Compare commits
39 Commits
Author | SHA1 | Date | |
---|---|---|---|
b412966f86 | |||
1119a8d04e | |||
9b3d294992 | |||
517337144c | |||
db89ad46b7 | |||
9fc1c53c3d | |||
cd61ab3e5b | |||
b319e89e41 | |||
b3d32c6fc4 | |||
91c2aef931 | |||
3ad0037fa9 | |||
f5d415ab4f | |||
b002db1148 | |||
393104f9fa | |||
b9f39e0d99 | |||
990397e1cb | |||
300713f5d5 | |||
9a17f19f7b | |||
3ff1bf473c | |||
50cd71b954 | |||
f81ebe6c3c | |||
1d85a61cc4 | |||
689de82139 | |||
5b9f35220f | |||
8fc4d7b4a5 | |||
cedf18ac7a | |||
164b6d7956 | |||
27e595cdf4 | |||
020560d341 | |||
cdef67986b | |||
dddcd0bfce | |||
a0784b7af1 | |||
4c4c9b2bfd | |||
5c34c051cb | |||
4fa44b0532 | |||
f167ce7d3b | |||
950b9e4289 | |||
264aeb7150 | |||
be7169c5df |
16
.github/workflows/setup.sh
vendored
@ -8,19 +8,17 @@ set -ex
|
||||
# install dependencies
|
||||
echo -e '[arcanisrepo]\nServer = https://repo.arcanis.me/$arch\nSigLevel = Never' | tee -a /etc/pacman.conf
|
||||
# refresh the image
|
||||
pacman -Syu --noconfirm
|
||||
pacman -Syyu --noconfirm
|
||||
# main dependencies
|
||||
pacman -Sy --noconfirm devtools git pyalpm python-cerberus python-inflection python-passlib python-pyelftools python-requests python-srcinfo python-systemd sudo
|
||||
pacman -S --noconfirm devtools git pyalpm python-inflection python-passlib python-pyelftools python-requests python-systemd sudo
|
||||
# make dependencies
|
||||
pacman -Sy --noconfirm --asdeps base-devel python-build python-flit python-installer python-tox python-wheel
|
||||
pacman -S --noconfirm --asdeps base-devel python-build python-flit python-installer python-tox python-wheel
|
||||
# optional dependencies
|
||||
if [[ -z $MINIMAL_INSTALL ]]; then
|
||||
# VCS support
|
||||
pacman -Sy --noconfirm breezy darcs mercurial subversion
|
||||
# web server
|
||||
pacman -Sy --noconfirm python-aioauth-client python-aiohttp python-aiohttp-apispec-git python-aiohttp-cors python-aiohttp-jinja2 python-aiohttp-security python-aiohttp-session python-cryptography python-jinja
|
||||
pacman -S --noconfirm python-aioauth-client python-aiohttp python-aiohttp-apispec-git python-aiohttp-cors python-aiohttp-jinja2 python-aiohttp-security python-aiohttp-session python-cryptography python-jinja
|
||||
# additional features
|
||||
pacman -Sy --noconfirm gnupg python-boto3 rsync
|
||||
pacman -S --noconfirm gnupg python-boto3 python-cerberus python-matplotlib rsync
|
||||
fi
|
||||
# FIXME since 1.0.4 devtools requires dbus to be run, which doesn't work now in container
|
||||
cp "docker/systemd-nspawn.sh" "/usr/local/bin/systemd-nspawn"
|
||||
@ -42,12 +40,12 @@ pacman -Qdtq | pacman -Rscn --noconfirm -
|
||||
# initial setup command as root
|
||||
[[ -z $MINIMAL_INSTALL ]] && WEB_ARGS=("--web-port" "8080")
|
||||
ahriman -a x86_64 -r "github" service-setup --packager "ahriman bot <ahriman@example.com>" "${WEB_ARGS[@]}"
|
||||
# validate configuration
|
||||
ahriman service-config-validate --exit-code
|
||||
# enable services
|
||||
systemctl enable ahriman-web
|
||||
systemctl enable ahriman@x86_64-github.timer
|
||||
if [[ -z $MINIMAL_INSTALL ]]; then
|
||||
# validate configuration
|
||||
ahriman service-config-validate --exit-code
|
||||
# run web service (detached)
|
||||
sudo -u ahriman -- ahriman web &
|
||||
WEB_PID=$!
|
||||
|
2
.github/workflows/tests.sh
vendored
@ -4,7 +4,7 @@
|
||||
set -ex
|
||||
|
||||
# install dependencies
|
||||
pacman --noconfirm -Syu base-devel python-tox
|
||||
pacman --noconfirm -Syyu base-devel python-tox
|
||||
|
||||
# run test and check targets
|
||||
tox
|
||||
|
@ -448,6 +448,7 @@ disable=raw-checker-failed,
|
||||
too-many-arguments,
|
||||
duplicate-code,
|
||||
cyclic-import,
|
||||
too-many-positional-arguments,
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
# either give multiple identifier separated by comma (,) or put this option
|
||||
|
@ -12,6 +12,7 @@ python:
|
||||
extra_requirements:
|
||||
- docs
|
||||
- s3
|
||||
- validator
|
||||
- web
|
||||
|
||||
formats:
|
||||
|
@ -36,6 +36,7 @@ Again, the most checks can be performed by `tox` command, though some additional
|
||||
|
||||
Notes:
|
||||
Very important note about this function
|
||||
Probably multi-line
|
||||
|
||||
Args:
|
||||
argument(str): an argument. This argument has
|
||||
@ -70,6 +71,7 @@ Again, the most checks can be performed by `tox` command, though some additional
|
||||
Attributes:
|
||||
CLAZZ_ATTRIBUTE(int): (class attribute) a brand-new class attribute
|
||||
instance_attribute(str): an instance attribute
|
||||
with the long description
|
||||
|
||||
Examples:
|
||||
Very informative class usage example, e.g.::
|
||||
@ -82,8 +84,6 @@ Again, the most checks can be performed by `tox` command, though some additional
|
||||
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
*args(Any): positional arguments
|
||||
**kwargs(Any): keyword arguments
|
||||
@ -91,8 +91,10 @@ Again, the most checks can be performed by `tox` command, though some additional
|
||||
self.instance_attribute = ""
|
||||
```
|
||||
|
||||
Note missing comment for the `__init__` method, which is the special case.
|
||||
|
||||
* Type annotations are the must, even for local functions. For the function argument `self` (for instance methods) and `cls` (for class methods) should not be annotated.
|
||||
* For collection types built-in classes must be used if possible (e.g. `dict` instead of `typing.Dict`, `tuple` instead of `typing.Tuple`). In case if built-in type is not available, but `collections.abc` provides interface, it must be used (e.g. `collections.abc.Awaitable` instead of `typing.Awaitable`, `collections.abc.Iterable` instead of `typing.Iterable`). For union classes, the bar operator (`|`) must be used (e.g. `float | int` instead of `typing.Union[float, int]`), which also includes `typinng.Optional` (e.g. `str | None` instead of `Optional[str]`).
|
||||
* For collection types built-in classes must be used if possible (e.g. `dict` instead of `typing.Dict`, `tuple` instead of `typing.Tuple`). In case if built-in type is not available, but `collections.abc` provides interface, it must be used (e.g. `collections.abc.Awaitable` instead of `typing.Awaitable`, `collections.abc.Iterable` instead of `typing.Iterable`). For union classes, the bar operator (`|`) must be used (e.g. `float | int` instead of `typing.Union[float, int]`), which also includes `typing.Optional` (e.g. `str | None` instead of `Optional[str]`).
|
||||
* `classmethod` should (almost) always return `Self`. In case of mypy warning (e.g. if there is a branch in which function doesn't return the instance of `cls`) consider using `staticmethod` instead.
|
||||
* Recommended order of function definitions in class:
|
||||
|
||||
|
43
Dockerfile
@ -25,18 +25,47 @@ RUN echo "[multilib]" >> "/etc/pacman.conf" && \
|
||||
echo "Include = /etc/pacman.d/mirrorlist" >> "/etc/pacman.conf"
|
||||
## refresh packages, install sudo and install packages for building
|
||||
RUN pacman -Syu --noconfirm sudo && \
|
||||
pacman -Sy --noconfirm --asdeps fakeroot python-tox
|
||||
pacman -S --noconfirm --asdeps fakeroot python-tox
|
||||
## create build user
|
||||
RUN useradd -m -d "/home/build" -s "/usr/bin/nologin" build && \
|
||||
echo "build ALL=(ALL) NOPASSWD: ALL" > "/etc/sudoers.d/build"
|
||||
COPY "docker/install-aur-package.sh" "/usr/local/bin/install-aur-package"
|
||||
## install package dependencies
|
||||
## darcs is not installed by reasons, because it requires a lot haskell packages which dramatically increase image size
|
||||
RUN pacman -Sy --noconfirm --asdeps devtools git pyalpm python-cerberus python-inflection python-passlib python-pyelftools python-requests python-srcinfo && \
|
||||
pacman -Sy --noconfirm --asdeps base-devel python-build python-flit python-installer python-wheel && \
|
||||
pacman -Sy --noconfirm --asdeps breezy git mercurial python-aiohttp python-boto3 python-cryptography python-jinja python-systemd rsync subversion && \
|
||||
runuser -u build -- install-aur-package python-aioauth-client python-webargs python-aiohttp-apispec-git python-aiohttp-cors \
|
||||
python-aiohttp-jinja2 python-aiohttp-session python-aiohttp-security python-requests-unixsocket2
|
||||
RUN pacman -S --noconfirm --asdeps \
|
||||
devtools \
|
||||
git \
|
||||
pyalpm \
|
||||
python-inflection \
|
||||
python-passlib \
|
||||
python-pyelftools \
|
||||
python-requests \
|
||||
&& \
|
||||
pacman -S --noconfirm --asdeps \
|
||||
base-devel \
|
||||
python-build \
|
||||
python-flit \
|
||||
python-installer \
|
||||
python-wheel \
|
||||
&& \
|
||||
pacman -S --noconfirm --asdeps \
|
||||
git \
|
||||
python-aiohttp \
|
||||
python-boto3 \
|
||||
python-cerberus \
|
||||
python-cryptography \
|
||||
python-jinja \
|
||||
python-systemd \
|
||||
rsync \
|
||||
&& \
|
||||
runuser -u build -- install-aur-package \
|
||||
python-aioauth-client \
|
||||
python-webargs \
|
||||
python-aiohttp-apispec-git \
|
||||
python-aiohttp-cors \
|
||||
python-aiohttp-jinja2 \
|
||||
python-aiohttp-session \
|
||||
python-aiohttp-security \
|
||||
python-requests-unixsocket2
|
||||
|
||||
## FIXME since 1.0.4 devtools requires dbus to be run, which doesn't work now in container
|
||||
COPY "docker/systemd-nspawn.sh" "/usr/local/bin/systemd-nspawn"
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
[](https://github.com/arcan1s/ahriman/actions/workflows/tests.yml)
|
||||
[](https://github.com/arcan1s/ahriman/actions/workflows/setup.yml)
|
||||
[](https://hub.docker.com/r/arcan1s/ahriman)
|
||||
[](https://hub.docker.com/r/arcan1s/ahriman)
|
||||
[](https://www.codefactor.io/repository/github/arcan1s/ahriman)
|
||||
[](https://ahriman.readthedocs.io)
|
||||
|
||||
|
@ -8,9 +8,6 @@ cat <<EOF > "/etc/ahriman.ini.d/00-docker.ini"
|
||||
[repository]
|
||||
root = $AHRIMAN_REPOSITORY_ROOT
|
||||
|
||||
[settings]
|
||||
database = $AHRIMAN_REPOSITORY_ROOT/ahriman.db
|
||||
|
||||
[web]
|
||||
host = $AHRIMAN_HOST
|
||||
|
||||
|
12051
docs/_static/architecture.svg
vendored
Normal file
After Width: | Height: | Size: 1.4 MiB |
721
docs/_static/logo.svg
vendored
Normal file
@ -0,0 +1,721 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="800"
|
||||
height="800"
|
||||
version="1.1"
|
||||
id="svg106"
|
||||
sodipodi:docname="logo.svg"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview106"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="1.8720703"
|
||||
inkscape:cx="511.73292"
|
||||
inkscape:cy="499.71414"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2160"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg106" />
|
||||
<path
|
||||
fill="#132b6d"
|
||||
d="m 387.66175,2.9352426 c 109.978,-0.5206001 203.504,31.4880054 285.824,108.1504174 159.376,148.42203 165.076,403.05807 17.164,561.4021 -72.884,78.02402 -172.364,120.98802 -278.558,124.58202 -105.508,0.092 -196.612,-29.306 -277.44,-100.25401 C -17.844855,562.95974 -40.874855,327.5097 78.894545,164.89367 155.84375,60.416853 261.60375,10.958044 387.66175,2.9352426 Z"
|
||||
id="path1"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs2">
|
||||
<linearGradient
|
||||
id="gradient_0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="361.42581"
|
||||
y1="223.77209"
|
||||
x2="195.62669"
|
||||
y2="358.78311"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#C29024"
|
||||
id="stop1" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#DCBB57"
|
||||
id="stop2" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_0)"
|
||||
d="M 351.39175,758.48578 C 168.77575,730.12777 41.748945,587.64375 38.358945,403.44571 34.725145,206.00568 197.09775,42.52665 394.25175,39.316449 c 199.908,-3.255 364.866,156.319231 367.572,354.681261 1.264,13.294 -0.766,28.52001 -2.266,41.84201 -22.772,202.34804 -192.312,343.02406 -397.788,324.19806 -2.656,-0.244 -8.104,-0.266 -10.378,-1.552 z"
|
||||
id="path2"
|
||||
style="fill:url(#gradient_0);stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 322.01375,466.26772 c -11.018,-19.004 -31.84,-33.106 -51.826,-41.634 -1.678,-0.714 -7.54,-2.124 -8.182,-3.564 l 0.732,-0.666 c 4,0.842 8.334,3.966 12.02,5.806 6.386,3.184 15.572,2.11 22.174,5.236 4.75,2.248 4.01,8.946 6.388,12.528 4.924,7.418 31.496,22.526 25.196,30.44801 -1.88,2.366 3.59,25.088 -6.502,27.406 9.19,-11.64 6.228,-23.022 0,-35.56001 z"
|
||||
id="path3"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1ead8"
|
||||
d="m 607.74175,596.82375 c 1.336,0.334 2.464,0.632 3.666,1.342 -20.054,9.052 -64.106,28.032 -86.62,22.686 4.1,-6.492 9.65,-12.676 16.658,-16.064 19.842,0.438 47.962,-0.334 66.296,-7.964 z"
|
||||
id="path4"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 501.15175,566.49574 c 6.586,7.622 13.706,16.72001 22.154,22.30601 4.128,2.764 8.214,4.434 12.892,6.05 9.566,1.388 23.592,3.746 32.986,1.972 14.562,-1.188 28.228,-3.904 42.224,-8.022 l -1.062,3.132 c -0.626,1.91 -1.408,3.284 -2.604,4.89 -18.334,7.63 -46.454,8.402 -66.296,7.964 -7.008,3.388 -12.558,9.572 -16.658,16.064 -9.11,-5.624 -25.204,-20.256 -33.116,-27.858 -0.438,-2.818 -1.834,-5.878 -2.786,-8.594 3.066,-7.94801 11.252,-13.00801 12.266,-17.90401 z"
|
||||
id="path5"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1ead8"
|
||||
d="m 279.36575,419.47772 c 17.368,-2.17 52.85,13.874 66.39,23.914 16.654,12.346 42.944,41.42201 46.084,62.86401 l -0.632,0.818 c -7.4,-0.814 -14.928,-3.078 -22.004,0 -15.638,-34.97 -32.316,-54.81001 -66.512,-75.00601 -7.612,-4.496 -15.806,-7.926 -23.326,-12.59 z"
|
||||
id="path6"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f2e8a9"
|
||||
d="m 358.50775,559.66374 c 12.018,13.204 20.532,31.28401 42.394,32.76001 26.828,1.808 75.452,-16.66001 100.25,-25.92801 -1.014,4.896 -9.2,9.956 -12.266,17.90401 0.952,2.716 2.348,5.776 2.786,8.594 -23.926,3.644 -42.772,14.97 -73.036,18.024 -31.48,3.176 -57.178,-20.208 -60.128,-51.35401 z"
|
||||
id="path7"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs8">
|
||||
<linearGradient
|
||||
id="gradient_1"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="251.38866"
|
||||
y1="364.7413"
|
||||
x2="250.98038"
|
||||
y2="386.04666"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#8B5E10"
|
||||
id="stop7" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#CF9A22"
|
||||
id="stop8" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_1)"
|
||||
d="m 310.19775,643.62576 c 2.576,-42.33201 43.824,-23.71801 68.946,-13.31801 29.856,12.36001 44.646,14.27401 76.866,17.40001 6.062,0.588 19.738,0.234 24.164,5.272 -4.906,4.506 -30.934,9.33 -37.886,8.6 -14.06,-1.944 -28.422,0.378 -42.516,0.02 -15.588,-0.394 -24.788,-3.174 -41.264,-0.02 -10.692,-0.35 -39.162,-6.928 -48.31,-12.01 l -0.164,-0.692 c -4.454,-4.498 -8.004,-10.198 -11.632,-15.38 h 1.106 c 3.348,3.464 6.672,7.448 10.69,10.128 z"
|
||||
id="path8"
|
||||
style="fill:url(#gradient_1);stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 533.18975,212.81168 3.008,1.8 c 104.752,81.45401 120.284,223.88804 39.258,327.17806 -4.874,6.214 -10.864,11.518 -15.55,17.874 -13.234,7.248 -22.01,22.26601 -36.562,27.66201 -3.272,-0.346 -14.796,-14.16001 -18.132,-17.28801 9.246,-9.45 22.016,-16.352 32.638,-26.984 75.99,-76.05602 84.014,-197.54404 14.068,-280.22005 -6.722,-7.946 -14.4,-14.688 -21.786,-21.97401 2.61,-8.98 1.014,-18.91 3.058,-28.048 z"
|
||||
id="path9"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs10">
|
||||
<linearGradient
|
||||
id="gradient_2"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="383.45288"
|
||||
y1="318.2124"
|
||||
x2="295.73892"
|
||||
y2="203.79875"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#BF9029"
|
||||
id="stop9" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#F5D354"
|
||||
id="stop10" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_2)"
|
||||
d="m 434.37375,137.51566 c 2.598,-0.164 5.328,-0.374 7.914,0 44.516,7.77801 92.47,33.43601 126.896,61.38602 7.438,7.668 16.4,14.876 22.864,23.372 2.62,2.794 5.176,5.692 8.21,8.044 5.566,3.826 22.78,23.15001 28.692,29.00401 l 0.008,0.522 c 0.052,5.284 2.926,14.418 2.624,16.914 1.07,8.98 6.816,17.276 9.974,25.644 32.534,86.22402 17.178,181.23004 -38.442,254.80205 -9.59,12.686 -20.71,25.49601 -33.178,35.41401 -3.856,3.068 -7.42,3.966 -0.752,4.206 -9.394,1.774 -23.42,-0.584 -32.986,-1.972 -4.678,-1.616 -8.764,-3.286 -12.892,-6.05 12.516,-9.682 25.068,-17.99401 36.6,-29.13801 4.686,-6.356 10.676,-11.66 15.55,-17.874 81.026,-103.29002 65.494,-245.72405 -39.258,-327.17806 l -3.008,-1.8 c -2.044,9.138 -0.448,19.068 -3.058,28.048 -20.19,-16.736 -57.964,-41.348 -84.916,-44.78 -4.862,6.39 -8.658,12.616 -14.43,18.532 -7.806,8.378 -15.312,17.27 -22.424,26.248 v -3.898 c -1.506,1.596 -4.512,4.54 -4.34,6.828 l 0.516,0.474 c -0.566,1.138 -1.052,2.3 -1.93,3.238 l -1.24,0.028 0.2,1.06001 c -4.05,-8.60801 1.232,-15.75801 3.436,-23.75601 26.818,-41.54401 24.194,-53.60601 -19.526,-73.22601 16.782,-3.452 30.824,-15.02601 48.896,-14.09201 z"
|
||||
id="path10"
|
||||
style="fill:url(#gradient_2);stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 592.04775,222.27368 c 2.62,2.794 5.176,5.692 8.21,8.044 8.066,13.52 19.78,29.05401 28.692,42.98401 -6.366,-3.072 -23.312,-30.26801 -30.038,-38.90201 -2.778,-3.566 -7.95,-7.296 -6.864,-12.126 z"
|
||||
id="path11"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#051053"
|
||||
d="m 600.25775,230.31768 c 5.566,3.826 22.78,23.15001 28.692,29.00401 l 0.008,0.522 c 0.052,5.284 2.926,14.418 2.624,16.914 -0.81,-1.204 -1.734,-2.318 -2.632,-3.456 -8.912,-13.93 -20.626,-29.46401 -28.692,-42.98401 z"
|
||||
id="path12"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#bf8a24"
|
||||
d="m 536.19775,214.61168 c -9.436,-16.308 -80.554,-44.98201 -95.5,-43.60601 -2.88,-2.338 -5.638,-6.154 -7.546,-9.334 13.846,-0.878 61.092,18.238 74.408,25.094 7.224,3.72 43.202,27.84801 43.214,27.84601 3.21,2.37 5.956,5.258 9.132,7.662 4.042,5.416 9.626,9.648 14.302,14.496 93.102,96.54202 79.466,249.74005 -15.778,339.83206 -3.328,3.14801 -18.614,17.85401 -22.232,18.25001 -4.678,-1.616 -8.764,-3.286 -12.892,-6.05 12.516,-9.682 25.068,-17.99401 36.6,-29.13801 4.686,-6.356 10.676,-11.66 15.55,-17.874 81.026,-103.29002 65.494,-245.72405 -39.258,-327.17806 z"
|
||||
id="path13"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 434.37375,137.51566 c 2.598,-0.164 5.328,-0.374 7.914,0 44.516,7.77801 92.47,33.43601 126.896,61.38602 2.568,7.928 14.072,10.708 15.774,18.372 l -0.474,0.94 -2.092,0.246 c -0.048,0.186 -10.608,12.996 -11.95,12.526 -3.166,-1.106 -7.656,-9.138 -10.536,-8.712 -3.176,-2.404 -5.922,-5.292 -9.132,-7.662 -0.012,0.002 -35.99,-24.12601 -43.214,-27.84601 -13.316,-6.856 -60.562,-25.972 -74.408,-25.094 1.908,3.18 4.666,6.996 7.546,9.334 14.946,-1.376 86.064,27.29801 95.5,43.60601 l -3.008,-1.8 c -2.044,9.138 -0.448,19.068 -3.058,28.048 -20.19,-16.736 -57.964,-41.348 -84.916,-44.78 -4.862,6.39 -8.658,12.616 -14.43,18.532 -7.806,8.378 -15.312,17.27 -22.424,26.248 v -3.898 c -1.506,1.596 -4.512,4.54 -4.34,6.828 l 0.516,0.474 c -0.566,1.138 -1.052,2.3 -1.93,3.238 l -1.24,0.028 0.2,1.06001 c -4.05,-8.60801 1.232,-15.75801 3.436,-23.75601 26.818,-41.54401 24.194,-53.60601 -19.526,-73.22601 16.782,-3.452 30.824,-15.02601 48.896,-14.09201 z"
|
||||
id="path14"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 412.09175,152.87167 c 12.74,-3.468 25.54,-4.784 38.71,-3.946 -6.848,2.32 -14.484,5.572 -20.016,10.326 8.062,3.682 21.354,5.528 30.612,8.39 19.908,6.152 75.712,30.48001 89.376,46.97001 -0.012,0.002 -35.99,-24.12601 -43.214,-27.84601 -13.316,-6.856 -60.562,-25.972 -74.408,-25.094 1.908,3.18 4.666,6.996 7.546,9.334 14.946,-1.376 86.064,27.29801 95.5,43.60601 l -3.008,-1.8 c -17.866,-18.572 -65.548,-36.19801 -90.902,-40.93001 3.608,7.782 6.348,15.752 2.928,24.19801 -4.862,6.39 -8.658,12.616 -14.43,18.532 -7.806,8.378 -15.312,17.27 -22.424,26.248 v -3.898 c 22.078,-32.98 57.308,-46.31801 3.73,-84.09001 z"
|
||||
id="path15"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1ead8"
|
||||
d="m 442.28775,171.88167 c 25.354,4.732 73.036,22.35801 90.902,40.93001 -2.044,9.138 -0.448,19.068 -3.058,28.048 -20.19,-16.736 -57.964,-41.348 -84.916,-44.78 3.42,-8.44601 0.68,-16.41601 -2.928,-24.19801 z"
|
||||
id="path16"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs17">
|
||||
<linearGradient
|
||||
id="gradient_3"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="259.85068"
|
||||
y1="248.27858"
|
||||
x2="350.85385"
|
||||
y2="408.95212"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#061757"
|
||||
id="stop16" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#1C4897"
|
||||
id="stop17" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_3)"
|
||||
d="m 628.94975,259.32169 c 35.888,36.25 71.52,72.79001 107.964,108.48002 6.736,6.598 18.816,21.616 24.91,26.196 1.264,13.294 -0.766,28.52001 -2.266,41.84201 -22.772,202.34804 -192.312,343.02406 -397.788,324.19806 -2.656,-0.244 -8.104,-0.266 -10.378,-1.552 -4.572,-6.652 -23.912,-22.76601 -31.626,-30.48801 l -117.162,-117.50802 c -11.006,-10.966 -46.288,-42.43401 -53.304,-54.48401 -4.57,-5.32 -10.27,-9.648 -14.854,-15.058 4.872,0.144 18.938,7.52 23.586,10.336 6.858,1.708 20.052,4.126 26.25,6.798 0.434,-1.258 0.146,-2.694 0,-3.998 0.138,-1.692 0.09,-3.306 0,-5 3.348,0.634 6.652,2.408 10.05,2.2 13.202,5.656 24.534,12.708 34.05,23.62 3.788,3.09 7.482,6.23801 11.126,9.49601 4.716,4.008 9.52,7.936 13.794,12.424 1.884,0.704 5.45,2.046 6.762,3.614 1.584,0.97 3.154,2.014 4.78,2.904 7.256,3.166 14.768,8.762 21.092,13.49 1.516,2.334 3.288,4.486 5.016,6.664 l 7.45,10.00201 c 3.628,5.182 7.178,10.882 11.632,15.38 l 0.164,0.692 c 9.148,5.082 37.618,11.66 48.31,12.01 16.476,-3.154 25.676,-0.374 41.264,0.02 14.094,0.358 28.456,-1.964 42.516,-0.02 6.952,0.73 32.98,-4.094 37.886,-8.6 7.398,7.31 18.44,8.658 28.374,7.392 40.55,-5.168 97.53,-34.27201 123.034,-67.37801 -2.714,-0.424 9.054,-10.22 9.25,-12.97 -7.204,1.354 -10.72,9.924 -18.264,10.996 -3.768,2.22 -7.816,4.312 -11.16,7.146 -1.202,-0.71 -2.33,-1.008 -3.666,-1.342 1.196,-1.606 1.978,-2.98 2.604,-4.89 l 1.062,-3.132 c -13.996,4.118 -27.662,6.834 -42.224,8.022 -6.668,-0.24 -3.104,-1.138 0.752,-4.206 12.468,-9.918 23.588,-22.72801 33.178,-35.41401 55.62,-73.57201 70.976,-168.57803 38.442,-254.80205 -3.158,-8.368 -8.904,-16.664 -9.974,-25.644 0.302,-2.496 -2.572,-11.63 -2.624,-16.914 z"
|
||||
id="path17"
|
||||
style="fill:url(#gradient_3);stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 637.21175,576.96974 c 4.14,-2.36 8.288,-4.69 12.494,-6.932 -5.274,7.16 -11.4,17.29401 -18.124,22.95601 -2.714,-0.424 9.054,-10.22 9.25,-12.97 -7.204,1.354 -10.72,9.924 -18.264,10.996 3.782,-3.136 14.3,-8.644 15.882,-12.846 z"
|
||||
id="path18"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f2e8a9"
|
||||
d="m 637.21175,576.96974 1.238,1.20401 c -1.582,4.202 -12.1,9.71 -15.882,12.846 -3.768,2.22 -7.816,4.312 -11.16,7.146 -1.202,-0.71 -2.33,-1.008 -3.666,-1.342 1.196,-1.606 1.978,-2.98 2.604,-4.89 l 1.062,-3.132 c 9.172,-3.09 17.482,-6.914 25.804,-11.83201 z"
|
||||
id="path19"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 358.50775,661.57976 c 16.476,-3.154 25.676,-0.374 41.264,0.02 14.094,0.358 28.456,-1.964 42.516,-0.02 -25.31,6.146 -58.224,4.784 -83.78,0 z"
|
||||
id="path20"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs21">
|
||||
<linearGradient
|
||||
id="gradient_4"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="178.9133"
|
||||
y1="342.13019"
|
||||
x2="155.9601"
|
||||
y2="362.37878"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#CC991E"
|
||||
id="stop20" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#F2B831"
|
||||
id="stop21" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_4)"
|
||||
d="m 134.44575,540.94774 c 4.872,0.144 18.938,7.52 23.586,10.336 6.858,1.708 20.052,4.126 26.25,6.798 0.434,-1.258 0.146,-2.694 0,-3.998 0.138,-1.692 0.09,-3.306 0,-5 3.348,0.634 6.652,2.408 10.05,2.2 13.202,5.656 24.534,12.708 34.05,23.62 3.788,3.09 7.482,6.23801 11.126,9.49601 4.716,4.008 9.52,7.936 13.794,12.424 1.884,0.704 5.45,2.046 6.762,3.614 1.584,0.97 3.154,2.014 4.78,2.904 7.256,3.166 14.768,8.762 21.092,13.49 1.516,2.334 3.288,4.486 5.016,6.664 l 7.45,10.00201 c 3.628,5.182 7.178,10.882 11.632,15.38 l 0.164,0.692 c -22.282,-4.896 -55.696,-23.88201 -74.236,-37.44601 -6.744,-4.934 -12.552,-11.388 -19.652,-15.766 -6.676,-4.12 -15.06,-5.966 -22.186,-9.388 -16.632,-7.988 -30.922,-18.98801 -44.824,-30.96401 -4.57,-5.32 -10.27,-9.648 -14.854,-15.058 z"
|
||||
id="path21"
|
||||
style="fill:url(#gradient_4);stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 158.03175,551.28374 c 6.858,1.708 20.052,4.126 26.25,6.798 1.448,0.596 2.168,1.102 2.948,2.48 l -0.558,0.666 c -3.77,-0.136 -27.166,-8.046 -28.64,-9.944 z"
|
||||
id="path22"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#bf8a24"
|
||||
d="m 242.85175,607.32775 c 7.25,0.168 31.11,8.666 40.444,11.75 -14.638,0.038 -27.2,-6.238 -40.444,-11.75 z"
|
||||
id="path23"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 232.69375,596.82375 c 6.662,0.62 22.044,5.462 27.37,3.614 1.584,0.97 3.154,2.014 4.78,2.904 -4.194,1.55 -18.89,-0.318 -26.814,1.446 z"
|
||||
id="path24"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 209.78375,574.90374 c -2.394,-0.948 -7.676,-3.032 -7.456,-6.196 5.142,-1.48 19.682,5.378 26.054,6.196 3.788,3.09 7.482,6.23801 11.126,9.49601 l -0.16,0.142 c -3.374,0.606 -25.568,-7.70801 -29.564,-9.63801 z"
|
||||
id="path25"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 209.78375,574.90374 c 3.996,1.93 26.19,10.24401 29.564,9.63801 l 0.16,-0.142 c 4.716,4.008 9.52,7.936 13.794,12.424 1.884,0.704 5.45,2.046 6.762,3.614 -5.326,1.848 -20.708,-2.994 -27.37,-3.614 -10.77,-1.75 -16.314,-4.876 -19.558,-16.004 -1.528,-1.78 -2.85,-3.59801 -3.352,-5.91601 z"
|
||||
id="path26"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#bf8a24"
|
||||
d="m 209.78375,574.90374 c 3.996,1.93 26.19,10.24401 29.564,9.63801 l 0.16,-0.142 c 4.716,4.008 9.52,7.936 13.794,12.424 v 0 c -11.244,-0.884 -22.286,-6.858 -31.866,-12.424 -2.804,-0.374 -5.434,-2.774 -8.3,-3.58 -1.528,-1.78 -2.85,-3.59801 -3.352,-5.91601 z"
|
||||
id="path27"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#ad7214"
|
||||
d="m 221.43575,584.39975 c 6.578,-0.56 30.096,8.298 31.866,12.424 -11.244,-0.884 -22.286,-6.858 -31.866,-12.424 z"
|
||||
id="path28"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#132b6d"
|
||||
d="m 266.41175,531.65974 c -4.998,-0.03 -11.098,-9.27801 -14.01,-12.81601 -78.2,-95.08401 -44.296,-239.09604 68.622,-289.88605 14.626,-6.58 87.39,-28.004 83.98,-12.018 0.29,5.32 -5.89,12.826 -5.742,19.654 l 0.8,-0.356 0.256,-0.984 c 0.838,-3.116 3.132,-7.658 4.686,-10.42 v 0 c -2.204,7.998 -7.486,15.148 -3.436,23.75601 l -0.2,-1.06001 1.24,-0.028 c 0.878,-0.938 1.364,-2.1 1.93,-3.238 l -0.516,-0.474 c -0.172,-2.288 2.834,-5.232 4.34,-6.828 v 3.898 c 7.112,-8.978 14.618,-17.87 22.424,-26.248 l 0.5,0.152 c 8.212,2.444 16.47,3.944 24.602,6.854 58.574,20.972 106.85,72.05001 120.456,133.45202 1.73,7.81001 2.632,15.79601 4.472,23.57201 0.174,4.016 1.316,11.12 -0.142,14.692 l -1.322,0.664 1.154,0.176 c 1.286,3.432 0.364,9.786 0.31,13.526 0.428,4.816 0.606,10.62001 0,15.40801 -1.662,4.574 -2.66,9.378 -3.582,14.148 -0.862,5.382 -1.694,10.842 -3.742,15.924 -1.502,3.656 -3.308,7.462 -4.308,11.294 -0.442,4.27201 -3.664,10.89601 -6.116,14.42401 -2.28,4.28 -4.82,10.524 -8.172,14.028 -2.766,4.198 -5.424,8.452 -8.062,12.73 l -10.636,13.256 c -0.812,1.354 -10.158,11.70601 -11.41,12.74801 -4.732,2.976 -7.86,5.02 -11.552,9.288 -4.794,2.344 -9.02,6.04 -13.816,8.136 -4.916,2.576 -9.95,5.226 -14.068,8.998 -5.336,1.804 -10.23,3.636 -15.1,6.486 -3,0.812 -11.478,3.87 -14.124,3.644 -5.37,1.882 -11.066,2.43 -16.396,4.486 l -14.888,2.206 c -3.228,-0.058 -14.524,1.172 -16.482,0 -2.668,0.884 -14.2,-1.2 -17.154,-2.206 -4.388,-1.97 -13.234,-3.4 -15.17,-4.486 -15.284,-4 -26.706,-61.61201 4.84,-58.55001 5.12,0.178 10.212,1.104 15.266,1.896 -0.322,-4.59 -1.47,-8.966 -2.758,-13.362 -31.792,-69.38401 -101.182,-95.30202 -174.692,-84.31001 28.904,2.816 52.742,14.29 77.006,28.634 14.684,13.388 42.828,39.46001 22.146,59.30801 -4.42,-5.66 -9.796,-10.928 -13.456,-17.124 l -1.134,0.23 0.924,-0.544 0.246,0.612 -1.168,-0.966 c -0.378,1.04 0.1,2.79 0.238,3.908 -0.494,8.656 -0.63,17.812 -1.922,26.378 -0.986,1.08 -1.914,2.264 -3.172,3.032 -4.348,3.636 -8.422,7.43801 -12.466,11.40401 -1.992,-3.07 -5.034,-6.59401 -6.57,-9.84601 -2.598,-1.562 -2.622,-4.334 -3.65,-6.816 l -0.892,0.308 c -0.248,2.022 1.28,3.668 1.268,5.77 l -0.744,0.738 c 2.36,3.862 7.746,10.52601 7.948,15.01601 -5.642,-0.656 -11.25,-1.548 -16.884,-2.268 z"
|
||||
id="path29"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 271.23775,505.65573 4.11,2.688 c 0.612,3.864 2.48,7.024 4.018,10.568 -2.598,-1.562 -2.622,-4.334 -3.65,-6.816 l -0.892,0.308 c -0.248,2.022 1.28,3.668 1.268,5.77 l -0.744,0.738 c -1.114,-4.514 -3.114,-8.68 -4.11,-13.256 z"
|
||||
id="path30"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#051053"
|
||||
d="m 397.67375,507.07373 c 2.356,4.01 4.79,7.942 7.33,11.838 -3.3,-1.106 -7.652,-4.4 -10.786,-4.59 l 1.848,-0.566 c 1.032,-1.614 0.804,-4.254 1.44,-6.188 z"
|
||||
id="path31"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#0f0e1a"
|
||||
d="m 393.38575,498.19573 c 3.194,2.542 2.828,5.462 4.288,8.878 l -0.168,0.494 c -0.636,1.934 -0.408,4.574 -1.44,6.188 l -1.848,0.566 c -4.74,-0.682 -9.642,-1.346 -13.34,-4.66 5.12,0.178 10.212,1.104 15.266,1.896 -0.322,-4.59 -1.47,-8.966 -2.758,-13.362 z"
|
||||
id="path32"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 405.00375,216.93968 c 0.29,5.32 -5.89,12.826 -5.742,19.654 l 0.8,-0.356 0.256,-0.984 c 0.838,-3.116 3.132,-7.658 4.686,-10.42 v 0 c -2.204,7.998 -7.486,15.148 -3.436,23.75601 l -0.2,-1.06001 1.24,-0.028 c 0.878,-0.938 1.364,-2.1 1.93,-3.238 l -0.516,-0.474 c -0.172,-2.288 2.834,-5.232 4.34,-6.828 v 3.898 c -5.74,7.47601 -10.278,15.97801 -14.976,24.13401 2.614,-16.47 4.536,-32.74201 11.618,-48.05401 z"
|
||||
id="path33"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 376.03775,568.21174 c 3.14,-7.134 6.892,-14.264 9.44,-21.616 2.51,8.576 3.87,17.374 5.73,26.102 -4.388,-1.97 -13.234,-3.4 -15.17,-4.486 z"
|
||||
id="path34"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 275.34775,508.34373 c 7.554,3.424 15.174,6.414 23.054,9.01 -4.348,3.636 -8.422,7.43801 -12.466,11.40401 -1.992,-3.07 -5.034,-6.59401 -6.57,-9.84601 -1.538,-3.544 -3.406,-6.704 -4.018,-10.568 z"
|
||||
id="path35"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 580.81575,378.64171 c 0.174,4.016 1.316,11.12 -0.142,14.692 l -1.322,0.664 c -8.51,-1.606 -16.614,-3.178 -25.25,-4.102 8.398,-6.016 16.886,-8.52 26.714,-11.254 z"
|
||||
id="path36"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 554.10175,411.69971 c 8.586,-2.24 17.924,-2.716 26.714,-4 0.428,4.816 0.606,10.62001 0,15.40801 -8.872,-2.66 -19.79,-5.044 -26.714,-11.40801 z"
|
||||
id="path37"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 413.80575,549.08374 c 5.198,7.878 7.314,17.22 11.038,25.82 -3.228,-0.058 -14.524,1.172 -16.482,0 1.018,-8.646 2.216,-17.686 5.444,-25.82 z"
|
||||
id="path38"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 526.91575,484.43773 c 9.316,1.67 19.154,5.096 27.98,8.488 -2.766,4.198 -5.424,8.452 -8.062,12.73 -7.26,-6.506 -15.232,-12.516 -19.918,-21.218 z"
|
||||
id="path39"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 549.10575,437.25572 c 9.318,-0.64 18.79,-0.084 28.128,0 -0.862,5.382 -1.694,10.842 -3.742,15.924 -8.43,-5.086 -16.78,-9.56 -24.386,-15.924 z"
|
||||
id="path40"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 439.73175,543.29174 1.36,1.452 c 6.326,6.73 9.89,15.802 15.036,23.468 -5.37,1.882 -11.066,2.43 -16.396,4.486 z"
|
||||
id="path41"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 539.67175,462.21972 c 9.972,-0.004 19.626,1.052 29.512,2.254 -0.442,4.27201 -3.664,10.89601 -6.116,14.42401 -8.166,-3.222 -17.172,-10.556 -23.396,-16.67801 z"
|
||||
id="path42"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 488.88575,521.69573 c 7.732,3.84201 19.168,12.47201 24.35,19.25201 -4.794,2.344 -9.02,6.04 -13.816,8.136 -4.688,-8.85 -7.936,-17.748 -10.534,-27.38801 z"
|
||||
id="path43"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 509.94175,505.65573 c 5.494,1.07 8.69,2.82 13.364,5.902 5.104,1.702 8.644,4.112 12.892,7.354 -0.812,1.354 -10.158,11.70601 -11.41,12.74801 -2.844,-4.58 -6.188,-9.33401 -8.274,-14.30601 -2.536,-3.532 -4.474,-7.872 -6.572,-11.698 z"
|
||||
id="path44"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 465.35375,533.92774 c 7.502,6.24 15.294,15.644 19.998,24.154 -5.336,1.804 -10.23,3.636 -15.1,6.486 -3.214,-9.588 -4.238,-20.568 -4.898,-30.64 z"
|
||||
id="path45"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#2356ae"
|
||||
d="M 351.39175,758.48578 C 168.77575,730.12777 41.748945,587.64375 38.358945,403.44571 34.725145,206.00568 197.09775,42.52665 394.25175,39.316449 c 199.908,-3.255 364.866,156.319231 367.572,354.681261 -6.094,-4.58 -18.174,-19.598 -24.91,-26.196 -36.444,-35.69001 -72.076,-72.23002 -107.964,-108.48002 -5.912,-5.854 -23.126,-25.17801 -28.692,-29.00401 -3.034,-2.352 -5.59,-5.25 -8.21,-8.044 -6.464,-8.496 -15.426,-15.704 -22.864,-23.372 -34.426,-27.95001 -82.38,-53.60801 -126.896,-61.38602 -2.586,-0.374 -5.316,-0.164 -7.914,0 -18.072,-0.934 -32.114,10.64001 -48.896,14.09201 43.72,19.62 46.344,31.682 19.526,73.22601 v 0 c -1.554,2.762 -3.848,7.304 -4.686,10.42 l -0.256,0.984 -0.8,0.356 c -0.148,-6.828 6.032,-14.334 5.742,-19.654 3.41,-15.986 -69.354,5.438 -83.98,12.018 -112.918,50.79001 -146.822,194.80204 -68.622,289.88605 2.912,3.538 9.012,12.78601 14.01,12.81601 5.634,0.72 11.242,1.612 16.884,2.268 -0.202,-4.49 -5.588,-11.15401 -7.948,-15.01601 l 0.744,-0.738 c 0.012,-2.102 -1.516,-3.748 -1.268,-5.77 l 0.892,-0.308 c 1.028,2.482 1.052,5.254 3.65,6.816 1.536,3.252 4.578,6.77601 6.57,9.84601 4.044,-3.966 8.118,-7.76801 12.466,-11.40401 1.258,-0.768 2.186,-1.952 3.172,-3.032 1.292,-8.566 1.428,-17.722 1.922,-26.378 -0.138,-1.118 -0.616,-2.868 -0.238,-3.908 l 1.168,0.966 -0.246,-0.612 -0.924,0.544 1.134,-0.23 c 3.66,6.196 9.036,11.464 13.456,17.124 20.682,-19.848 -7.462,-45.92001 -22.146,-59.30801 8.322,2.714 22.978,21.546 26.672,29.42201 2.368,5.048 2.81,14.832 4.236,17.488 3.938,-9.238 -6.242,-21.60201 -4.594,-23.16201 6.228,12.53801 9.19,23.92001 0,35.56001 -11.034,9.136 -29.284,21.156 -36.122,33.99601 -15.95,29.946 -3.004,58.48801 7.948,85.92401 1.766,3.338 5.028,8.098 5.668,11.75001 h -1.106 l -7.45,-10.00201 c -1.728,-2.178 -3.5,-4.33 -5.016,-6.664 -6.324,-4.728 -13.836,-10.324 -21.092,-13.49 -1.626,-0.89 -3.196,-1.934 -4.78,-2.904 -1.312,-1.568 -4.878,-2.91 -6.762,-3.614 -4.274,-4.488 -9.078,-8.416 -13.794,-12.424 -3.644,-3.258 -7.338,-6.40601 -11.126,-9.49601 -9.516,-10.912 -20.848,-17.964 -34.05,-23.62 -3.398,0.208 -6.702,-1.566 -10.05,-2.2 0.09,1.694 0.138,3.308 0,5 0.146,1.304 0.434,2.74 0,3.998 -6.198,-2.672 -19.392,-5.09 -26.25,-6.798 -4.648,-2.816 -18.714,-10.192 -23.586,-10.336 4.584,5.41 10.284,9.738 14.854,15.058 7.016,12.05 42.298,43.51801 53.304,54.48401 l 117.162,117.50802 c 7.714,7.722 27.054,23.83601 31.626,30.48801 z"
|
||||
id="path46"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#132b6d"
|
||||
d="m 179.65375,204.78568 0.312,-1.174 0.54,0.326 c 1.66,8.908 0.01,23.462 3.776,31.23 -0.946,2.464 -0.94,5.09 -2.088,7.614 -0.896,-7.214 -1.61,-14.446 -2.54,-21.656 -0.13,-5.46 -0.212,-10.878 0,-16.34 z"
|
||||
id="path47"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 125.81775,276.75769 c 2.17,11.74 9.116,22.444 12.934,33.79201 l -0.57,0.518 c -1.16,-3.654 -7.662,-20.46601 -9.84,-22.36001 l -0.976,0.068 c -1.38,1.692 -2.846,2.256 -4.866,3.024 -2.616,6.924 -1.898,24.47801 -3.168,33.15201 -0.472,-15.43 -0.356,-34.15801 6.486,-48.19401 z"
|
||||
id="path48"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#132b6d"
|
||||
d="m 274.23575,141.76967 c -2.074,7.182 -3.328,13.142 -2.998,20.634 -4.176,2.324 -7.592,4.762 -11.174,7.91 v -2.354 c 1.878,-6.262 2.766,-12.768 4.78,-19.034 3.524,-1.72 6.27,-4.824 9.392,-7.156 z"
|
||||
id="path49"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#132b6d"
|
||||
d="m 371.74975,108.36966 c -3.86,7.4 -7.354,14.524 -9.404,22.688 v 0 c -3.648,0.82 -7.228,1.122 -10.954,1.38 4.392,-6.38 5.642,-13.5 10.954,-19.87 l 1.312,1.376 c 2.71,-0.242 5.8,-4.024 8.092,-5.574 z"
|
||||
id="path50"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 268.33575,131.05766 c -1.042,5.972 -2.31,11.92001 -3.492,17.86801 -2.014,6.266 -2.902,12.772 -4.78,19.034 -1.326,-4.864 3.318,-9.734 1.244,-14.208 -22.57,-10.084 -17.62,14.712 -26.708,18.13 6.172,-15.816 20.434,-30.548 33.736,-40.82401 z"
|
||||
id="path51"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 179.65375,196.07968 c -0.244,2.936 -0.14,5.77 0,8.706 -0.212,5.462 -0.13,10.88 0,16.34 -2.87,1.676 -3.574,6.084 -4.174,9.192 -1.636,3.874 -3.642,7.834 -4.67,11.914 l -0.244,0.106 0.41,-0.728 -0.192,-0.106 c 2.75,-11.394 5.076,-8.03 -4.17,-11.186 -1.178,2.228 -4.1,9.672 -5.944,10.542 4.934,-15.602 12.448,-29.868 18.984,-44.78 z"
|
||||
id="path52"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#132b6d"
|
||||
d="m 456.12775,109.52166 c 3.564,1.658 10.414,-0.138 14.124,-1.152 -9.878,8.046 -21.92,17.846 -27.964,29.146 -2.586,-0.374 -5.316,-0.164 -7.914,0 l -6.334,-3.096 c 7.916,-6.85 14.976,-14.806 22.762,-21.852 1.752,-1.066 3.52,-2.074 5.326,-3.046 z"
|
||||
id="path53"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 100.50375,364.60771 c 8.122,7.8 22.772,25.956 30.762,31.252 0.936,5.038 2.374,10.71 2.462,15.774 -12.286,-9.396 -17.796,-19.394 -28.126,-27.642 0.096,1.026 0.082,1.858 -0.212,2.84 -2.522,-7.432 -3.886,-14.462 -4.886,-22.224 z"
|
||||
id="path54"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 96.515745,442.51972 c 8.566005,4.34 36.750005,23.486 42.236005,30.46001 l 0.276,0.808 c 6.398,2.844 8.096,8.69 8.058,15.766 l -0.588,-0.544 c -1.434,-1.32 -10.678,-7.62 -12.052,-7.594 -5.946,-3.566 -23.722,-21.69601 -29.056,-20.70801 -3.03,-6.03 -5.978005,-12.092 -8.874005,-18.188 z"
|
||||
id="path55"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 121.77975,525.87374 c 19.42,6.36 38.498,14.12 57.874,20.722 l 0.548,0.758 1.826,-0.056 c 1.258,1.488 1.388,4.868 2.254,6.786 0.146,1.304 0.434,2.74 0,3.998 -6.198,-2.672 -19.392,-5.09 -26.25,-6.798 -4.648,-2.816 -18.714,-10.192 -23.586,-10.336 -4.45,-4.812 -8.812,-9.764 -12.666,-15.074 z"
|
||||
id="path56"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 271.23775,162.40367 c 7.99,-6.254 18.884,-10.416 28.25,-14.234 16.76,-6.832 13.44,-7.376 25.658,-19.48401 10.768,-10.672 29.362,-23.208 44.058,-28.062 -2.508,3.886 -5.042,7.672 -6.858,11.944 -5.312,6.37 -6.562,13.49 -10.954,19.87 -0.974,1.678 -1.832,2.932 -3.262,4.254 l -0.532,-0.056 c 0.956,-3.102 4.54,-2.84 3.518,-6.662 l -2.128,-2.174 c -8.514,3.742 -77.504,34.61201 -77.75,34.60401 z"
|
||||
id="path57"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs58">
|
||||
<linearGradient
|
||||
id="gradient_5"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="145.13785"
|
||||
y1="328.17804"
|
||||
x2="117.22018"
|
||||
y2="280.89636"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#D79A18"
|
||||
id="stop57" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#F6C842"
|
||||
id="stop58" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_5)"
|
||||
d="m 105.38975,460.70772 c 5.334,-0.988 23.11,17.14201 29.056,20.70801 4.286,3.456 9.396,6.13 13.392,9.86 0.278,-2.39 0.424,-4.632 1.462,-6.838 l 0.504,-0.106 c 0.058,-0.954 -0.086,-7.128 0.79,-5.038 1.712,4.084 3.956,1.936 4.492,8.664 l 0.486,-0.014 c 2.38,7.206 8.172,8.99 13.068,13.884 l -0.348,0.398 c 2.612,0.138 4.874,0.24 7.188,1.558 0.816,0.698 1.66,1.344 2.532,1.97 l 0.462,1.048 c -1.04,0.308 -0.606,0.28 -1.274,0.272 3.704,0.932 3.808,4.058 4.994,7.248 v 0 c 2.772,3.696 5.17,7.268 6.946,11.55201 -1.732,-0.248 -24.262,-10.67601 -16.892,-1.472 2.482,3.098 5.226,7.084 8.34,9.526 2.636,1.906 4.292,5.756 7.29,7.02 h 1.262 l -1.262,2.344 c 0.818,1.872 1.938,2.472 3.716,3.304 l -0.66,0.048 c -2.968,0.184 -9.982,-2.572 -6.652,2.44 0.09,1.694 0.138,3.308 0,5 -0.866,-1.918 -0.996,-5.298 -2.254,-6.786 l -1.826,0.056 -0.548,-0.758 c -0.52,-3.778 -6.05,-8.072 -8.808,-10.5 -24.584,-13.75401 -54.27,-50.32801 -65.456,-75.38802 z"
|
||||
id="path58"
|
||||
style="fill:url(#gradient_5);stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 170.84575,536.09574 c 0.178,0.002 16.806,6.982 17.032,7.196 0.818,1.872 1.938,2.472 3.716,3.304 l -0.66,0.048 c -2.968,0.184 -9.982,-2.572 -6.652,2.44 0.09,1.694 0.138,3.308 0,5 -0.866,-1.918 -0.996,-5.298 -2.254,-6.786 l -1.826,0.056 -0.548,-0.758 c -0.52,-3.778 -6.05,-8.072 -8.808,-10.5 z"
|
||||
id="path59"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#bf8a24"
|
||||
d="m 182.19375,514.32173 c -5.22,-0.312 -16.074,-7.81 -20,-10.892 -0.398,-0.312 -4.628,-3.938 -2.568,-3.994 4.124,-0.114 11.04,6.52 14.26,8.908 0.87,-0.988 2.086,-1.036 3.314,-1.27 3.704,0.932 3.808,4.058 4.994,7.248 z"
|
||||
id="path60"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 177.19975,507.07373 c 3.704,0.932 3.808,4.058 4.994,7.248 -2.664,-2.118 -5.5,-4.052 -8.308,-5.978 0.87,-0.988 2.086,-1.036 3.314,-1.27 z"
|
||||
id="path61"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs62">
|
||||
<linearGradient
|
||||
id="gradient_6"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="238.76126"
|
||||
y1="143.77654"
|
||||
x2="270.52316"
|
||||
y2="95.432106"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#FAD84F"
|
||||
id="stop61" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#FFF5A9"
|
||||
id="stop62" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_6)"
|
||||
d="m 362.34575,131.05766 c 26.81,-3.184 19.722,-1.768 42.234,-13.04 19.684,-9.856 41.194,-16.094 63.324,-15.652 -4.056,2.182 -8.086,4.39 -11.776,7.156 -1.806,0.972 -3.574,1.98 -5.326,3.046 -7.786,7.046 -14.846,15.002 -22.762,21.852 l 6.334,3.096 c -18.072,-0.934 -32.114,10.64001 -48.896,14.09201 -3.1,0.442 -6.45,0.35 -9.44,1.264 -3.958,1.83 -9.35,-0.016 -13.526,1.328 l -0.166,0.49 c 4.412,1.276 9.87,1.98 13.692,4.562 -11.014,0.822 -21.384,-2.856 -32.396,-2.412 -0.74,-0.772 -5.22,0.294 -7.562,-0.282 l 0.286,-0.044 c -8.446,-2.598 -0.096,-4.918 2.406,-7.588 6.796,-3.554 22.95,-8.952 23.574,-17.86801 z"
|
||||
id="path62"
|
||||
style="fill:url(#gradient_6);stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 341.76375,151.60767 c 11.034,-5.176 26.9,-6.422 39.114,-7.498 -2.7,3.496 -6.968,3.658 -4.84,8.762 -3.958,1.83 -9.35,-0.016 -13.526,1.328 l -0.166,0.49 c -4.888,-1.222 -8.504,-1.066 -13.358,0 -2.746,0.4 -8.482,-0.994 -10.622,-2.552 l 0.184,-0.502 -0.088,0.422 0.506,-0.548 z"
|
||||
id="path63"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 424.84375,132.43766 c 9.142,-6.23 14.826,-16.674 25.958,-19.87 -7.786,7.046 -14.846,15.002 -22.762,21.852 l 6.334,3.096 c -18.072,-0.934 -32.114,10.64001 -48.896,14.09201 -3.1,0.442 -6.45,0.35 -9.44,1.264 -2.128,-5.104 2.14,-5.266 4.84,-8.762 8.736,-2.842 14.512,-8.95201 24.126,-9.69001 2.98,-2.124 16.504,-3.504 19.84,-1.982 z"
|
||||
id="path64"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 405.00375,134.41966 c 2.98,-2.124 16.504,-3.504 19.84,-1.982 -3.412,3.298 -15.364,2.648 -19.84,1.982 z"
|
||||
id="path65"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 348.98775,127.79966 2.128,2.174 c 1.022,3.822 -2.562,3.56 -3.518,6.662 l 0.532,0.056 c 1.43,-1.322 2.288,-2.576 3.262,-4.254 3.726,-0.258 7.306,-0.56 10.954,-1.38 -0.624,8.91601 -16.778,14.31401 -23.574,17.86801 -7.41,2.68 -9.978,8.094 -16.164,11.038 -3.652,1.74 -27.878,3.596 -21.164,11.206 l -1.672,0.284 6.764,0.428 c -13.404,2.41 -17.64,4.718 -29.284,7.922 6.38,1.602 10.798,-2.57 18.448,0.768 h 2.702 l -0.042,1.276 c -7.05,4.88 -18.516,5.498 -27.53,13.56001 -1.344,1.2 -2.83,2.678 -4.418,3.494 -4.23,1.326 -8.724,2.754 -13.11,3.378 -1.89,1.25 -12.68,4.234 -15.272,4.588 v 0 -2.082 l -2.28,-3.718 c -4.61,0.068 -7.042,12.34 -7.368,15.872 -8.018,0.742 -11.65,9.846 -16.818,14.858 -3.88,-1.22 -4.476,2.806 -6.472,5.164 -1.86,1.146 -4.982,3.384 -5.056,5.82 1.124,1.468 1.626,2.97 2.234,4.704 v 0 c -0.316,5.61801 1.456,4.99401 6.442,4.89801 -1.14,1.822 -2.366,3.564 -3.62,5.31 -1.95,2.246 -3.464,4.796 -5.056,7.3 -3.182,5.058 -6.5,9.462 -10.092,14.184 l -0.804,0.272 c -2.854,3.482 -4.438,8.244 -6.946,12.09 0.062,-2.884 0.094,-5.748 0,-8.632 -0.152,-5.29 -0.606,-10.77 0,-16.034 -4.278,6.658 -7.876,14.308 -9.904,21.966 l -0.172,-0.658 c -0.69,-2.716 -0.326,-5.508 -1.658,-8.056 -2.812,3.078 -0.546,7.956 -1.82,11.414 -2.326,1.824 -3.704,3.838 -4.96,6.498 0.362,13.11001 -0.04,26.34401 -0.64,39.44401 -2.058,-8.594 -3.944,-31.802 -5.008,-35.10001 -1.466,3.81001 -4.786,9.06401 -5.378,12.93801 -1.004,6.558 0.336,12.898 -1.634,19.682 l -0.152,-2.372 c -1.242,0.97 -0.692,3.5 -1.568,4.852 -0.888,5.956 -6.352,24.62201 -2.024,29.02001 l 1.026,-0.056 c 0.982,-1.328 1.022,-2.274 0.998,-3.888 2.54,11.112 6.984,15.086 6.272,27.338 -4.292,-5.588 -5.538,-12.7 -9.37,-18.494 -3.122,10.1 -3.688,19.896 -1.048,30.034 0.382,1.46 5.496,9.346 2.684,9.412 -1.922,-1.014 -3.814,-2.066 -5.696,-3.148 v 6.18601 l 5.696,5.592 -0.786,0.856 c 0.296,2.89 2.728,6.41 -0.85,8.024 -1.37,-0.752 -2.74,-1.49 -4.06,-2.326 1.508,3.706 4.194,6.776 5.696,10.326 -5.51,8.998 8.018,9.652 6.644,16.822 -2.168,-1.12 -4.022,-2.238 -6.51,-2.394 l -0.58,0.476 c 1.212,3.574 5.104,5.87 8.18,7.788 l 0.106,0.944 c 2.112,1.702 5.154,3.652 6.672,5.856 l -0.092,0.576 c -1.6,-0.072 -10.62,-4.306 -6.686,-0.158 3.098,4.66401 7.5,8.32001 11.042,12.63001 1.028,1.378 2.036,2.636 2.66,4.248 l -0.342,0.572 c -2.3,-0.9 -3.438,-2.91 -5.976,-3.28 2.058,3.032 5.576,4.756 7.89,7.506 -6.846,-3.492 -13.43,-7.156 -19.826,-11.44 1.408,2.746 2.824,5.372 4.552,7.934 -0.206,1.33 -0.332,2.17 0,3.506 l -0.486,0.014 c -0.536,-6.728 -2.78,-4.58 -4.492,-8.664 -0.876,-2.09 -0.732,4.084 -0.79,5.038 l -0.504,0.106 c -1.038,2.206 -1.184,4.448 -1.462,6.838 -3.996,-3.73 -9.106,-6.404 -13.392,-9.86 1.374,-0.026 10.618,6.274 12.052,7.594 l 0.588,0.544 c 0.038,-7.076 -1.66,-12.922 -8.058,-15.766 l -0.276,-0.808 c 1.184,0.176 3.7,2.69 4.754,3.524 -1.57,-16.19201 -6.668,-17.95401 -15.372,-31.30601 -8.38,-12.854 -23.376,-43.43601 -22.744,-58.36601 0.294,-0.982 0.308,-1.814 0.212,-2.84 10.33,8.248 15.84,18.246 28.126,27.642 -0.088,-5.064 -1.526,-10.736 -2.462,-15.774 0.614,-23.334 -11.684,-42.03401 -11.934,-70.90801 1.27,-8.674 0.552,-26.22801 3.168,-33.15201 2.02,-0.768 3.486,-1.332 4.866,-3.024 l 0.976,-0.068 c 2.178,1.894 8.68,18.70601 9.84,22.36001 l 0.57,-0.518 c 1.386,0.9 2.382,2.54 3.39,3.858 1.862,-13.02001 6.618,-19.94201 9.452,-31.46801 3.608,-14.66 3.426,-26.278 9.076,-42.08001 1.844,-0.87 4.766,-8.314 5.944,-10.542 9.246,3.156 6.92,-0.208 4.17,11.186 l 0.192,0.106 -0.41,0.728 0.244,-0.106 c 1.028,-4.08 3.034,-8.04 4.67,-11.914 0.6,-3.108 1.304,-7.516 4.174,-9.192 0.93,7.21 1.644,14.442 2.54,21.656 1.148,-2.524 1.142,-5.15 2.088,-7.614 8.798,-9.326 16.32,-19.906 24.89,-29.486 4.756,-5.318 10.938,-9.912 15.132,-15.63401 4.15,-5.656 5.632,-12.712 10.296,-18.166 9.088,-3.418 4.138,-28.214 26.708,-18.13 2.074,4.474 -2.57,9.344 -1.244,14.208 v 2.354 c 3.582,-3.148 6.998,-5.586 11.174,-7.91 v 0 c 0.246,0.008 69.236,-30.86201 77.75,-34.60401 z"
|
||||
id="path66"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 182.19375,266.87369 c 0.564,-0.782 2.61,-7.412 3.094,-3.452 0.322,2.642 1.102,21.51 -3.094,19.486 -0.152,-5.29 -0.606,-10.77 0,-16.034 z"
|
||||
id="path67"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 125.81775,310.5497 c 2.45,2.318 5.498,11.792 7.544,15.398 2.698,4.748 6.998,5.738 5.39,11.534 l -0.768,0.906 -0.92,-0.342 c -4.658,-6.078 -8.65,-19.842 -11.246,-27.496 z"
|
||||
id="path68"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 238.02975,204.78568 c 5.564,-5.62 15.092,-21.80401 23.426,-22.17401 -1.03,1.272 -5.95,6.208 -5.208,7.716 -1.792,1.966 -4.054,3.62801 -5.628,5.75201 -3.67,1.584 -4.516,5.316 -6.108,8.706 2.69,-0.91 5.97,-2.338 8.79,-2.506 -1.89,1.25 -12.68,4.234 -15.272,4.588 v 0 z"
|
||||
id="path69"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 295.69975,180.57167 h 2.702 c -8.5,7.116 -21.784,5.136 -31.99,7.612 -3.338,1.062 -6.97,1.058 -10.164,2.144 -0.742,-1.508 4.178,-6.444 5.208,-7.716 1.96,-1.942 7.53,-0.964 9.782,0 8.094,-2.064 16.232,-1.644 24.462,-2.04 z"
|
||||
id="path70"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 261.45575,182.61167 c 1.96,-1.942 7.53,-0.964 9.782,0 -9.012,0.558 -6.586,5.252 -4.826,5.572 -3.338,1.062 -6.97,1.058 -10.164,2.144 -0.742,-1.508 4.178,-6.444 5.208,-7.716 z"
|
||||
id="path71"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#bf8a24"
|
||||
d="m 200.03575,242.78168 c 1.124,1.468 1.626,2.97 2.234,4.704 v 0 c -0.316,5.61801 1.456,4.99401 6.442,4.89801 -1.14,1.822 -2.366,3.564 -3.62,5.31 -1.95,2.246 -3.464,4.796 -5.056,7.3 -3.182,5.058 -6.5,9.462 -10.092,14.184 l -0.804,0.272 c 0.992,-2.136 -0.112,-2.814 -0.734,-4.852 -1.902,-6.224 8.246,-26.224 11.63,-31.81601 z"
|
||||
id="path72"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 202.26975,247.48568 v 0 c -0.316,5.61801 1.456,4.99401 6.442,4.89801 -1.14,1.822 -2.366,3.564 -3.62,5.31 -1.95,2.246 -3.464,4.796 -5.056,7.3 -0.992,-6.32 1.244,-11.428 2.234,-17.50801 z"
|
||||
id="path73"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 298.40175,180.57167 -0.042,1.276 c -7.05,4.88 -18.516,5.498 -27.53,13.56001 -1.344,1.2 -2.83,2.678 -4.418,3.494 -4.23,1.326 -8.724,2.754 -13.11,3.378 -2.82,0.168 -6.1,1.596 -8.79,2.506 1.592,-3.39 2.438,-7.122 6.108,-8.706 1.574,-2.124 3.836,-3.78601 5.628,-5.75201 3.194,-1.086 6.826,-1.082 10.164,-2.144 10.206,-2.476 23.49,-0.496 31.99,-7.612 z"
|
||||
id="path74"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 271.23775,193.48968 c -1.194,1.158 -4.558,3.824 -4.826,5.412 -4.23,1.326 -8.724,2.754 -13.11,3.378 -2.82,0.168 -6.1,1.596 -8.79,2.506 1.592,-3.39 2.438,-7.122 6.108,-8.706 6.902,-0.504 13.82,-1.276 20.618,-2.59 z"
|
||||
id="path75"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 149.29975,466.26772 c -9.304,-9.342 -10.01,-43.218 -10.518,-57.68401 -0.538,-15.364 -1.234,-63.88401 4.522,-71.25001 l 0.256,0.428 -0.55,-0.498 c 0.858,0.034 1.536,1.384 3.084,1.57 -0.638,1.076 -2.192,1.04 -2.766,2.208 -3.374,6.87 -7.36,60.42401 -3.304,71.67401 l 1.144,0.50401 0.542,-0.48001 c -0.028,-1.786 0.016,-3.3 0.432,-5.04 v 6.18601 l 5.696,5.592 -0.786,0.856 c 0.296,2.89 2.728,6.41 -0.85,8.024 -1.37,-0.752 -2.74,-1.49 -4.06,-2.326 1.508,3.706 4.194,6.776 5.696,10.326 -5.51,8.998 8.018,9.652 6.644,16.822 -2.168,-1.12 -4.022,-2.238 -6.51,-2.394 l -0.58,0.476 c 1.212,3.574 5.104,5.87 8.18,7.788 l 0.106,0.944 c 2.112,1.702 5.154,3.652 6.672,5.856 l -0.092,0.576 c -1.6,-0.072 -10.62,-4.306 -6.686,-0.158 3.098,4.66401 7.5,8.32001 11.042,12.63001 1.028,1.378 2.036,2.636 2.66,4.248 l -0.342,0.572 c -2.3,-0.9 -3.438,-2.91 -5.976,-3.28 2.058,3.032 5.576,4.756 7.89,7.506 -6.846,-3.492 -13.43,-7.156 -19.826,-11.44 1.408,2.746 2.824,5.372 4.552,7.934 -0.206,1.33 -0.332,2.17 0,3.506 l -0.486,0.014 c -0.536,-6.728 -2.78,-4.58 -4.492,-8.664 -0.876,-2.09 -0.732,4.084 -0.79,5.038 l -0.504,0.106 c 0.334,-4.398 -0.07,-7.204 1.72,-11.458 -1.008,-2.202 -1.76,-4.234 -1.72,-6.71201 z"
|
||||
id="path76"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 149.29975,466.26772 c 2.55,1.562 4.34,4.17401 5.39,6.94401 l -0.242,0.898 c -1.33,0.158 -2.298,-0.53 -3.428,-1.13 -1.008,-2.202 -1.76,-4.234 -1.72,-6.71201 z"
|
||||
id="path77"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 234.59975,171.88167 c 9.088,-3.418 4.138,-28.214 26.708,-18.13 2.074,4.474 -2.57,9.344 -1.244,14.208 v 2.354 c -1.148,1.816 -5.864,3.458 -7.922,4.874 -14.14,9.736 -15.23,14.912 -24.894,26.40001 -6.982,8.3 -15.26,15.5 -22.134,23.932 -11.878,14.576 -27.774,39.38201 -41.434,51.23801 0.79,-11.36 12.096,-43.94801 11.8,-46.44001 0.6,-3.108 1.304,-7.516 4.174,-9.192 0.93,7.21 1.644,14.442 2.54,21.656 1.148,-2.524 1.142,-5.15 2.088,-7.614 8.798,-9.326 16.32,-19.906 24.89,-29.486 4.756,-5.318 10.938,-9.912 15.132,-15.63401 4.15,-5.656 5.632,-12.712 10.296,-18.166 z"
|
||||
id="path78"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#bf8a24"
|
||||
d="m 306.53575,171.88167 -6.764,-0.428 1.672,-0.284 c -6.714,-7.61 17.512,-9.466 21.164,-11.206 6.186,-2.944 8.754,-8.358 16.164,-11.038 -2.502,2.67 -10.852,4.99 -2.406,7.588 l -0.286,0.044 c 2.342,0.576 6.822,-0.49 7.562,0.282 11.012,-0.444 21.382,3.234 32.396,2.412 -3.822,-2.582 -9.28,-3.286 -13.692,-4.562 l 0.166,-0.49 c 4.176,-1.344 9.568,0.502 13.526,-1.328 2.99,-0.914 6.34,-0.822 9.44,-1.264 43.72,19.62 46.344,31.682 19.526,73.22601 v 0 c -1.554,2.762 -3.848,7.304 -4.686,10.42 l -0.256,0.984 -0.8,0.356 c -0.148,-6.828 6.032,-14.334 5.742,-19.654 3.41,-15.986 -69.354,5.438 -83.98,12.018 -112.918,50.79001 -146.822,194.80204 -68.622,289.88605 2.912,3.538 9.012,12.78601 14.01,12.81601 5.634,0.72 11.242,1.612 16.884,2.268 -0.202,-4.49 -5.588,-11.15401 -7.948,-15.01601 l 0.744,-0.738 c 0.012,-2.102 -1.516,-3.748 -1.268,-5.77 l 0.892,-0.308 c 1.028,2.482 1.052,5.254 3.65,6.816 1.536,3.252 4.578,6.77601 6.57,9.84601 4.044,-3.966 8.118,-7.76801 12.466,-11.40401 1.258,-0.768 2.186,-1.952 3.172,-3.032 1.292,-8.566 1.428,-17.722 1.922,-26.378 -0.138,-1.118 -0.616,-2.868 -0.238,-3.908 l 1.168,0.966 -0.246,-0.612 -0.924,0.544 1.134,-0.23 c 3.66,6.196 9.036,11.464 13.456,17.124 20.682,-19.848 -7.462,-45.92001 -22.146,-59.30801 8.322,2.714 22.978,21.546 26.672,29.42201 2.368,5.048 2.81,14.832 4.236,17.488 3.938,-9.238 -6.242,-21.60201 -4.594,-23.16201 6.228,12.53801 9.19,23.92001 0,35.56001 -11.034,9.136 -29.284,21.156 -36.122,33.99601 -15.95,29.946 -3.004,58.48801 7.948,85.92401 1.766,3.338 5.028,8.098 5.668,11.75001 h -1.106 l -7.45,-10.00201 c -1.728,-2.178 -3.5,-4.33 -5.016,-6.664 -6.324,-4.728 -13.836,-10.324 -21.092,-13.49 -1.626,-0.89 -3.196,-1.934 -4.78,-2.904 -1.312,-1.568 -4.878,-2.91 -6.762,-3.614 -4.274,-4.488 -9.078,-8.416 -13.794,-12.424 -3.644,-3.258 -7.338,-6.40601 -11.126,-9.49601 -9.516,-10.912 -20.848,-17.964 -34.05,-23.62 -3.398,0.208 -6.702,-1.566 -10.05,-2.2 -3.33,-5.012 3.684,-2.256 6.652,-2.44 l 0.66,-0.048 c -1.778,-0.832 -2.898,-1.432 -3.716,-3.304 l 1.262,-2.344 h -1.262 c -2.998,-1.264 -4.654,-5.114 -7.29,-7.02 -3.114,-2.442 -5.858,-6.428 -8.34,-9.526 -7.37,-9.20401 15.16,1.224 16.892,1.472 -1.776,-4.28401 -4.174,-7.85601 -6.946,-11.55201 v 0 c -1.186,-3.19 -1.29,-6.316 -4.994,-7.248 0.668,0.008 0.234,0.036 1.274,-0.272 l -0.462,-1.048 c -0.872,-0.626 -1.716,-1.272 -2.532,-1.97 -2.314,-1.318 -4.576,-1.42 -7.188,-1.558 l 0.348,-0.398 c -4.896,-4.894 -10.688,-6.678 -13.068,-13.884 -0.332,-1.336 -0.206,-2.176 0,-3.506 -1.728,-2.562 -3.144,-5.188 -4.552,-7.934 6.396,4.284 12.98,7.948 19.826,11.44 -2.314,-2.75 -5.832,-4.474 -7.89,-7.506 2.538,0.37 3.676,2.38 5.976,3.28 l 0.342,-0.572 c -0.624,-1.612 -1.632,-2.87 -2.66,-4.248 -3.542,-4.31 -7.944,-7.966 -11.042,-12.63001 -3.934,-4.148 5.086,0.086 6.686,0.158 l 0.092,-0.576 c -1.518,-2.204 -4.56,-4.154 -6.672,-5.856 l -0.106,-0.944 c -3.076,-1.918 -6.968,-4.214 -8.18,-7.788 l 0.58,-0.476 c 2.488,0.156 4.342,1.274 6.51,2.394 1.374,-7.17 -12.154,-7.824 -6.644,-16.822 -1.502,-3.55 -4.188,-6.62 -5.696,-10.326 1.32,0.836 2.69,1.574 4.06,2.326 3.578,-1.614 1.146,-5.134 0.85,-8.024 l 0.786,-0.856 -5.696,-5.592 v -6.18601 c 1.882,1.082 3.774,2.134 5.696,3.148 2.812,-0.066 -2.302,-7.952 -2.684,-9.412 -2.64,-10.138 -2.074,-19.934 1.048,-30.034 3.832,5.794 5.078,12.906 9.37,18.494 0.712,-12.252 -3.732,-16.226 -6.272,-27.338 0.024,1.614 -0.016,2.56 -0.998,3.888 l -1.026,0.056 c -4.328,-4.398 1.136,-23.06401 2.024,-29.02001 0.876,-1.352 0.326,-3.882 1.568,-4.852 l 0.152,2.372 c 1.97,-6.784 0.63,-13.124 1.634,-19.682 0.592,-3.874 3.912,-9.128 5.378,-12.93801 1.064,3.29801 2.95,26.50601 5.008,35.10001 0.6,-13.1 1.002,-26.334 0.64,-39.44401 1.256,-2.66 2.634,-4.674 4.96,-6.498 1.274,-3.458 -0.992,-8.336 1.82,-11.414 1.332,2.548 0.968,5.34 1.658,8.056 l 0.172,0.658 c 2.028,-7.658 5.626,-15.308 9.904,-21.966 -0.606,5.264 -0.152,10.744 0,16.034 0.094,2.884 0.062,5.748 0,8.632 2.508,-3.846 4.092,-8.608 6.946,-12.09 l 0.804,-0.272 c 3.592,-4.722 6.91,-9.126 10.092,-14.184 1.592,-2.504 3.106,-5.054 5.056,-7.3 1.254,-1.746 2.48,-3.488 3.62,-5.31 -4.986,0.096 -6.758,0.72 -6.442,-4.89801 v 0 c -0.608,-1.734 -1.11,-3.236 -2.234,-4.704 0.074,-2.436 3.196,-4.674 5.056,-5.82 1.996,-2.358 2.592,-6.384 6.472,-5.164 5.168,-5.012 8.8,-14.116 16.818,-14.858 0.326,-3.532 2.758,-15.804 7.368,-15.872 l 2.28,3.718 v 2.082 0 c 2.592,-0.354 13.382,-3.338 15.272,-4.588 4.386,-0.624 8.88,-2.052 13.11,-3.378 1.588,-0.816 3.074,-2.294 4.418,-3.494 9.014,-8.06201 20.48,-8.68001 27.53,-13.56001 l 0.042,-1.276 h -2.702 c -7.65,-3.338 -12.068,0.834 -18.448,-0.768 11.644,-3.204 15.88,-5.512 29.284,-7.922 z"
|
||||
id="path79"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 154.48175,356.6817 c 1.552,0.2 3.084,0.076 4.642,0 -0.404,2.63801 -0.692,5.29001 -1.092,7.92601 -1.188,-2.608 -2.544,-5.248 -3.55,-7.92601 z"
|
||||
id="path80"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 159.12375,442.51972 c 0.384,2.614 0.992,5.194 1.546,7.778 -3.03,-2.766 -6.444,-5.21 -9.65,-7.778 l 0.538,0.054 c 2.192,0.234 4.934,1.556 6.996,1.18 z"
|
||||
id="path81"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 175.47975,498.19573 c 0.814,1.764 4.086,6.738 0,5.588 -2.314,-1.318 -4.576,-1.42 -7.188,-1.558 l 0.348,-0.398 c 2.21,-2.024 4.874,-1.53 6.84,-3.632 z"
|
||||
id="path82"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#ad7214"
|
||||
d="m 155.57175,466.26772 c 9.084,-1.716 12.038,4.78201 11.562,12.49601 l -0.52,0.134 c -3.542,-4.31 -7.944,-7.966 -11.042,-12.63001 z"
|
||||
id="path83"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 155.57175,459.04972 c -3.076,-1.918 -6.968,-4.214 -8.18,-7.788 l 0.58,-0.476 c 2.488,0.156 4.342,1.274 6.51,2.394 2.566,1.4 4.326,3.672 6.188,5.87 1.02,1.764 1.71,3.5 2.37,5.424 -2.364,-1.688 -4.912,-4.152 -7.468,-5.424 z"
|
||||
id="path84"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 180.58775,533.92774 c -3.114,-2.442 -5.858,-6.428 -8.34,-9.526 -7.37,-9.20401 15.16,1.224 16.892,1.472 6.636,13.13 -9.994,0.33 -16.85,-2.24 3.11,3.16 6.322,6.268 8.298,10.294 z"
|
||||
id="path85"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 266.41175,531.65974 c 5.634,0.72 11.242,1.612 16.884,2.268 -0.584,3.624 -3.86,8.832 -5.208,12.668 -3.562,-5.308 -7.8,-9.892 -11.676,-14.936 z"
|
||||
id="path86"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 142.14175,426.03172 c 1.32,0.836 2.69,1.574 4.06,2.326 4.29,3.432 12.174,7.82 12.862,13.616 l 0.06,0.546 -0.57,1.234 c -2.062,0.376 -4.804,-0.946 -6.996,-1.18 l -0.538,-0.054 c -1,-2.096 -2.014,-4.15 -3.182,-6.162 -1.502,-3.55 -4.188,-6.62 -5.696,-10.326 z"
|
||||
id="path87"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 142.14175,407.69971 c 1.882,1.082 3.774,2.134 5.696,3.148 3.018,1.372 5.362,4.13001 7.734,6.39601 0.206,2.976 0.198,5.812 0,8.788 -2.638,-2.122 -5.196,-4.312 -7.734,-6.554 l -5.696,-5.592 z"
|
||||
id="path88"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 155.57175,484.43773 c 2.938,2.218 18.9,12.614 19.908,13.758 -1.966,2.102 -4.63,1.608 -6.84,3.632 -4.896,-4.894 -10.688,-6.678 -13.068,-13.884 -0.332,-1.336 -0.206,-2.176 0,-3.506 z"
|
||||
id="path89"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 303.49575,487.94373 c -0.138,-1.118 -0.616,-2.868 -0.238,-3.908 l 1.168,0.966 -0.246,-0.612 -0.924,0.544 1.134,-0.23 c 3.66,6.196 9.036,11.464 13.456,17.124 -2.234,2.422 -5.066,4.484 -7.648,6.516 -1.722,-5.352 -6.16,-14.438 -4.026,-19.786 l -0.84,-0.608 c -0.8,1.028 -0.922,2.05 -1.224,3.294 z"
|
||||
id="path90"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 343.64175,156.83967 c 11.012,-0.444 21.382,3.234 32.396,2.412 v 0 c 2.758,1.782 6.394,1.874 9.44,3.152 -10.682,1.228 -39.754,-2.68 -41.606,-1.904 0.806,1.616 2.88,2.336 4.224,3.502 l -1.41,0.542 0.34,0.15 -1.298,-0.124 c -4.908,-6.008 -9.214,-5.39 -10.248,-6.48 2.774,-0.232 5.512,-0.324 8.162,-1.25 z"
|
||||
id="path91"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 376.03775,152.87167 c 2.99,-0.914 6.34,-0.822 9.44,-1.264 43.72,19.62 46.344,31.682 19.526,73.22601 v 0 c 5.832,-22.874 34.842,-43.05801 -2.732,-64.07601 -11.18,-6.254 -18.164,-10.16 -31.452,-6.352 l -0.424,1.2 -0.404,-0.834 c 3.842,4.244 26.77,7.59 30.22,14.342 -1.308,0.37 -18.904,-9.996 -23.724,-10.5 l -0.45,0.638 v 0 c -3.822,-2.582 -9.28,-3.286 -13.692,-4.562 l 0.166,-0.49 c 4.176,-1.344 9.568,0.502 13.526,-1.328 z"
|
||||
id="path92"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 168.63975,291.53969 c 1.274,-3.458 -0.992,-8.336 1.82,-11.414 1.332,2.548 0.968,5.34 1.658,8.056 l 0.172,0.658 c 2.774,10.994 2.712,19.95201 -1.444,30.43201 -1.604,-9.654 -3.796,-17.92201 -2.206,-27.73201 z"
|
||||
id="path93"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 149.29975,337.4817 c 0.876,-1.352 0.326,-3.882 1.568,-4.852 l 0.152,2.372 c 1.894,5.472 9.814,16.574 8.104,21.68 -1.558,0.076 -3.09,0.2 -4.642,0 -1.126,-2.77 -2.134,-5.716 -3.462,-8.39 -1.878,5.094 -2.658,8.81 -1.72,14.26601 0.024,1.614 -0.016,2.56 -0.998,3.888 l -1.026,0.056 c -4.328,-4.398 1.136,-23.06401 2.024,-29.02001 z"
|
||||
id="path94"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 306.53575,171.88167 -6.764,-0.428 1.672,-0.284 c -6.714,-7.61 17.512,-9.466 21.164,-11.206 6.186,-2.944 8.754,-8.358 16.164,-11.038 -2.502,2.67 -10.852,4.99 -2.406,7.588 l -0.286,0.044 c 2.342,0.576 6.822,-0.49 7.562,0.282 -2.65,0.926 -5.388,1.018 -8.162,1.25 1.034,1.09 5.34,0.472 10.248,6.48 -3.348,-0.918 -27.976,0.078 -32.714,1.348 4.33,2.232 9.916,1.048 14.594,3.258 l 0.012,0.634 c -3.474,2.758 -16.412,2.3 -21.084,2.072 z"
|
||||
id="path95"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#ad7214"
|
||||
d="m 187.87775,540.94774 c 14.452,-1.578 18.17,9.438 25.354,17.744 17.95,20.75601 34.99,32.52001 57.314,46.64401 2.982,1.888 11.55,9.15 14.164,9.758 -0.954,-3.75 -7.964,-27.508 -9.222,-29.136 -2.72,-3.514 -11.288,-7.96801 -15.268,-11.09401 -12.18,-9.558 -46.938,-41.988 -52.316,-57.27201 l 0.808,-0.238 c 9.448,21.46801 48.068,54.83801 66.636,67.04602 1.412,2.178 10.994,29.386 10.588,32.432 -6.324,-4.728 -13.836,-10.324 -21.092,-13.49 -1.626,-0.89 -3.196,-1.934 -4.78,-2.904 -1.312,-1.568 -4.878,-2.91 -6.762,-3.614 -4.274,-4.488 -9.078,-8.416 -13.794,-12.424 -3.644,-3.258 -7.338,-6.40601 -11.126,-9.49601 -9.516,-10.912 -20.848,-17.964 -34.05,-23.62 -3.398,0.208 -6.702,-1.566 -10.05,-2.2 -3.33,-5.012 3.684,-2.256 6.652,-2.44 l 0.66,-0.048 c -1.778,-0.832 -2.898,-1.432 -3.716,-3.304 l 1.262,-2.344 z"
|
||||
id="path96"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 189.13975,540.94774 c 5.534,2.624 11.97,2.904 15.952,8.136 -3.688,-0.196 -7.236,-1.452 -10.76,-2.488 h -2.738 c -1.778,-0.832 -2.898,-1.432 -3.716,-3.304 z"
|
||||
id="path97"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 184.28175,549.08374 c -3.33,-5.012 3.684,-2.256 6.652,-2.44 l 0.66,-0.048 h 2.738 c 3.524,1.036 7.072,2.292 10.76,2.488 1.886,2.01 3.24,4.586 4.692,6.922 -3.318,-1.236 -12.546,-5.238 -15.452,-4.722 v 0 c -3.398,0.208 -6.702,-1.566 -10.05,-2.2 z"
|
||||
id="path98"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 184.28175,549.08374 c -3.33,-5.012 3.684,-2.256 6.652,-2.44 l 0.66,-0.048 h 2.738 c -4.344,0.788 -4.744,0.478 -1.17,2.97 l -0.606,-0.004 c -4.844,0.006 -0.282,1.608 1.776,1.722 v 0 c -3.398,0.208 -6.702,-1.566 -10.05,-2.2 z"
|
||||
id="path99"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 228.38175,216.93968 c 0.326,-3.532 2.758,-15.804 7.368,-15.872 l 2.28,3.718 v 2.082 0 c -6.518,12.316 13.27,-2.088 15.158,-2.352 -0.618,2.432 -27.42,25.384 -31.64,31.524 -3.73,5.426 -11.42,18.06801 -16.456,21.65401 1.254,-1.746 2.48,-3.488 3.62,-5.31 -4.986,0.096 -6.758,0.72 -6.442,-4.89801 v 0 c -0.608,-1.734 -1.11,-3.236 -2.234,-4.704 0.074,-2.436 3.196,-4.674 5.056,-5.82 1.996,-2.358 2.592,-6.384 6.472,-5.164 5.168,-5.012 8.8,-14.116 16.818,-14.858 z"
|
||||
id="path100"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 232.69375,222.27368 v 0 c -2.516,5.136 -7.8,8.384 -11.258,12.894 0.908,-3.178 1.606,-7.628 3.46,-10.334 2.71,0.164 5.344,-1.512 7.798,-2.56 z"
|
||||
id="path101"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 205.09175,236.96168 c 1.996,-2.358 2.592,-6.384 6.472,-5.164 -1.882,3.976 -3.154,7.958 -2.26,12.41 l 0.746,0.966 c 1.808,0.074 2.558,-0.808 4.2,-1.294 -0.568,2.526 -3.898,6.34801 -5.538,8.50401 -4.986,0.096 -6.758,0.72 -6.442,-4.89801 v 0 c -0.608,-1.734 -1.11,-3.236 -2.234,-4.704 0.074,-2.436 3.196,-4.674 5.056,-5.82 z"
|
||||
id="path102"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 200.03575,242.78168 c 0.074,-2.436 3.196,-4.674 5.056,-5.82 -1.032,3.436 -2.298,6.974 -2.822,10.524 v 0 c -0.608,-1.734 -1.11,-3.236 -2.234,-4.704 z"
|
||||
id="path103"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 228.38175,216.93968 c 0.326,-3.532 2.758,-15.804 7.368,-15.872 l 2.28,3.718 v 2.082 c -1.486,1.796 -3.142,3.526 -3.43,5.944 4.566,-0.902 8.72,-2.206 13.04,-3.914 -4.882,4.584 -9.786,9.102 -14.946,13.376 v 0 c -2.454,1.048 -5.088,2.724 -7.798,2.56 0.764,-2.614 2.36,-5.384 3.486,-7.894 z"
|
||||
id="path104"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 358.50775,173.44367 c 18.416,-4.38 53.464,-10.342 55.298,16.884 -24.86,0.57 -35.762,0.938 -60.484,4.82201 l -0.202,-0.514 c 1.278,-0.93 3.428,-0.886 4.184,-1.712 6.046,-6.58801 1.738,-6.33201 2.402,-12.86401 0.52,-5.102 6.456,-5.5 -0.302,-6.478 z"
|
||||
id="path105"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs106">
|
||||
<linearGradient
|
||||
id="gradient_7"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="141.16791"
|
||||
y1="268.56354"
|
||||
x2="265.50784"
|
||||
y2="226.48077"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#E1AF37"
|
||||
id="stop105" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#FCDE74"
|
||||
id="stop106" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_7)"
|
||||
d="m 208.71175,517.35373 c -86.018,-118.12402 -12.156,-301.82605 129.714,-339.49006 6.44,-1.71 13.438,-3.836 20.082,-4.42 l 0.896,0.138 c 6.758,0.978 0.822,1.376 0.302,6.478 -0.664,6.532 3.644,6.276 -2.402,12.86401 -0.756,0.826 -2.906,0.782 -4.184,1.712 l 0.202,0.514 c -12.89,3.57 -25.456,7.312 -37.754,12.642 -137.6,59.63401 -168.028,233.46204 -63.62,337.58006 7.44,7.418 16.184,13.6 23.4,21.124 0.094,5.944 0.338,11.96801 0,17.90401 -18.568,-12.20801 -57.188,-45.57801 -66.636,-67.04602 z"
|
||||
id="path106"
|
||||
style="fill:url(#gradient_7);stroke-width:2" />
|
||||
</svg>
|
After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 1.2 MiB |
@ -172,6 +172,14 @@ ahriman.application.handlers.sign module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.application.handlers.statistics module
|
||||
----------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.application.handlers.statistics
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.application.handlers.status module
|
||||
------------------------------------------
|
||||
|
||||
|
@ -28,6 +28,14 @@ ahriman.core.alpm.pacman\_database module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.alpm.pkgbuild\_parser module
|
||||
-----------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.alpm.pkgbuild_parser
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.alpm.repo module
|
||||
-----------------------------
|
||||
|
||||
|
@ -4,6 +4,14 @@ ahriman.core.build\_tools package
|
||||
Submodules
|
||||
----------
|
||||
|
||||
ahriman.core.build\_tools.package\_archive module
|
||||
-------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.build_tools.package_archive
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.build\_tools.sources module
|
||||
----------------------------------------
|
||||
|
||||
|
@ -28,6 +28,14 @@ ahriman.core.configuration.shell\_interpolator module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.configuration.shell\_template module
|
||||
-------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.configuration.shell_template
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.configuration.validator module
|
||||
-------------------------------------------
|
||||
|
||||
|
@ -116,6 +116,14 @@ ahriman.core.database.migrations.m013\_dependencies module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.database.migrations.m014\_auditlog module
|
||||
------------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.database.migrations.m014_auditlog
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
|
@ -36,6 +36,14 @@ ahriman.core.database.operations.dependencies\_operations module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.database.operations.event\_operations module
|
||||
---------------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.database.operations.event_operations
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.database.operations.logs\_operations module
|
||||
--------------------------------------------------------
|
||||
|
||||
|
@ -44,6 +44,14 @@ ahriman.core.formatters.configuration\_printer module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.formatters.event\_stats\_printer module
|
||||
----------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.formatters.event_stats_printer
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.formatters.package\_printer module
|
||||
-----------------------------------------------
|
||||
|
||||
@ -52,6 +60,14 @@ ahriman.core.formatters.package\_printer module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.formatters.package\_stats\_printer module
|
||||
------------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.formatters.package_stats_printer
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.formatters.patch\_printer module
|
||||
---------------------------------------------
|
||||
|
||||
|
@ -60,6 +60,14 @@ ahriman.core.report.report\_trigger module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.report.rss module
|
||||
------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.report.rss
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.report.telegram module
|
||||
-----------------------------------
|
||||
|
||||
|
@ -12,6 +12,14 @@ ahriman.core.repository.cleaner module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.repository.event\_logger module
|
||||
--------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.core.repository.event_logger
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.core.repository.executor module
|
||||
---------------------------------------
|
||||
|
||||
|
@ -68,6 +68,14 @@ ahriman.models.dependencies module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.models.event module
|
||||
---------------------------
|
||||
|
||||
.. automodule:: ahriman.models.event
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.models.filesystem\_package module
|
||||
-----------------------------------------
|
||||
|
||||
@ -100,6 +108,14 @@ ahriman.models.log\_record\_id module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.models.metrics\_timer module
|
||||
------------------------------------
|
||||
|
||||
.. automodule:: ahriman.models.metrics_timer
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.models.migration module
|
||||
-------------------------------
|
||||
|
||||
@ -124,14 +140,6 @@ ahriman.models.package module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.models.package\_archive module
|
||||
--------------------------------------
|
||||
|
||||
.. automodule:: ahriman.models.package_archive
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.models.package\_description module
|
||||
------------------------------------------
|
||||
|
||||
@ -164,6 +172,14 @@ ahriman.models.pacman\_synchronization module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.models.pkgbuild module
|
||||
------------------------------
|
||||
|
||||
.. automodule:: ahriman.models.pkgbuild
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.models.pkgbuild\_patch module
|
||||
-------------------------------------
|
||||
|
||||
|
@ -60,6 +60,22 @@ ahriman.web.schemas.error\_schema module
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.web.schemas.event\_schema module
|
||||
----------------------------------------
|
||||
|
||||
.. automodule:: ahriman.web.schemas.event_schema
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.web.schemas.event\_search\_schema module
|
||||
------------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.web.schemas.event_search_schema
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
ahriman.web.schemas.file\_schema module
|
||||
---------------------------------------
|
||||
|
||||
|
21
docs/ahriman.web.views.v1.auditlog.rst
Normal file
@ -0,0 +1,21 @@
|
||||
ahriman.web.views.v1.auditlog package
|
||||
=====================================
|
||||
|
||||
Submodules
|
||||
----------
|
||||
|
||||
ahriman.web.views.v1.auditlog.events module
|
||||
-------------------------------------------
|
||||
|
||||
.. automodule:: ahriman.web.views.v1.auditlog.events
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
.. automodule:: ahriman.web.views.v1.auditlog
|
||||
:members:
|
||||
:no-undoc-members:
|
||||
:show-inheritance:
|
@ -7,6 +7,7 @@ Subpackages
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
ahriman.web.views.v1.auditlog
|
||||
ahriman.web.views.v1.distributed
|
||||
ahriman.web.views.v1.packages
|
||||
ahriman.web.views.v1.service
|
||||
|
@ -12,8 +12,8 @@ Packages have strict rules of importing:
|
||||
|
||||
Full dependency diagram:
|
||||
|
||||
.. image:: ahriman-architecture.svg
|
||||
:target: _images/ahriman-architecture.svg
|
||||
.. image:: _static/architecture.svg
|
||||
:target: _static/architecture.svg
|
||||
:alt: architecture
|
||||
|
||||
``ahriman.application`` package
|
||||
@ -32,7 +32,7 @@ This package contains application (aka executable) related classes and everythin
|
||||
|
||||
This package contains everything required for the most of application actions and it is separated into several packages:
|
||||
|
||||
* ``ahriman.core.alpm`` package controls pacman related functions. It provides wrappers for ``pyalpm`` library and safe calls for repository tools (``repo-add`` and ``repo-remove``). Also this package contains ``ahriman.core.alpm.remote`` package which provides wrapper for remote sources (e.g. AUR RPC and official repositories RPC).
|
||||
* ``ahriman.core.alpm`` package controls pacman related functions. It provides wrappers for ``pyalpm`` library and safe calls for repository tools (``repo-add`` and ``repo-remove``). Also this package contains ``ahriman.core.alpm.remote`` package which provides wrapper for remote sources (e.g. AUR RPC and official repositories RPC) and some other helpers.
|
||||
* ``ahriman.core.auth`` package provides classes for authorization methods used by web mostly. Base class is ``ahriman.core.auth.Auth`` which must be instantiated by ``load`` method.
|
||||
* ``ahriman.core.build_tools`` is a package which provides wrapper for ``devtools`` commands.
|
||||
* ``ahriman.core.configuration`` contains extension for standard ``configparser`` library and some validation related classes.
|
||||
@ -375,6 +375,24 @@ There are several supported synchronization providers, currently they are ``rsyn
|
||||
|
||||
``github`` provider authenticates through basic auth, API key with repository write permissions is required. There will be created a release with the name of the architecture in case if it does not exist; files will be uploaded to the release assets. It also stores array of files and their MD5 checksums in release body in order to upload only changed ones. According to the GitHub API in case if there is already uploaded asset with the same name (e.g. database files), asset will be removed first.
|
||||
|
||||
PKGBUILD parsing
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
The application provides a house-made shell parser ``ahriman.core.alpm.pkgbuild_parser.PkgbuildParser`` to process PKGBUILDs and extract package data from them. It relies on the ``shlex.shlex`` parser with some configuration tweaks and adds some token post-processing.
|
||||
|
||||
#. During the parser process, firstly, it extract next token from the source file (basically, the word) and tries to match it to the variable assignment. If so, then just processes accordingly.
|
||||
#. If it is not an assignment, the parser checks if the token was quoted.
|
||||
#. If it wasn't then the parser tries to match the array starts (two consecutive tokens like ``array=`` and ``(``) or it is function (``function``, ``()`` and ``{``).
|
||||
#. The arrays are processed until the next closing bracket ``)``. After extraction, the parser tries to expand an array according to bash rules (``prefix{first,second}suffix`` constructions).
|
||||
#. The functions are just read until the closing bracket ``}`` and then reread whole text from the input string without a tokenization.
|
||||
|
||||
All extracted fields are packed as ``ahriman.models.pkgbuild_patch.PkgbuildPatch`` and then can be used as ``ahriman.models.pkgbuild.Pkgbuild`` instance.
|
||||
|
||||
The PKGBUILD class also provides some additional functions on top of that:
|
||||
|
||||
* Ability to extract fields defined inside ``package*()`` functions, which are in particular used for the multipackages.
|
||||
* Shell substitution, which supports constructions ``$var`` (including ``${var}``), ``${var#(#)pattern}``, ``${var%(%)pattern}`` and ``${var/(/)pattern/replacement}`` (including ``#pattern`` and ``%pattern``).
|
||||
|
||||
Additional features
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -72,7 +72,9 @@ html_theme = "sphinx_rtd_theme"
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = []
|
||||
html_static_path = ["_static"]
|
||||
|
||||
html_logo = "_static/logo.svg"
|
||||
|
||||
add_module_names = False
|
||||
|
||||
|
@ -17,14 +17,33 @@ There are two variable types which have been added to default ones, they are pat
|
||||
|
||||
Path values, except for casting to ``pathlib.Path`` type, will be also expanded to absolute paths relative to the configuration path. E.g. if path is set to ``ahriman.ini.d/logging.ini`` and root configuration path is ``/etc/ahriman.ini``, the value will be expanded to ``/etc/ahriman.ini.d/logging.ini``. In order to disable path expand, use the full path, e.g. ``/etc/ahriman.ini.d/logging.ini``.
|
||||
|
||||
Configuration allows string interpolation from environment variables, e.g.:
|
||||
Configuration allows string interpolation from the same configuration file, e.g.:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[section]
|
||||
key = ${anoher_key}
|
||||
another_key = value
|
||||
|
||||
will read value for the ``key`` option from ``another_key`` in the same section. In case if the cross-section reference is required, the ``${section:another_key}`` notation must be used. It also allows string interpolation from environment variables, e.g.:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[section]
|
||||
key = $SECRET
|
||||
|
||||
will try to read value from ``SECRET`` environment variable. In case if the required environment variable wasn't found, it will keep original value (i.e. ``$SECRET`` in the example). Dollar sign can be set as ``$$``.
|
||||
will try to read value from ``SECRET`` environment variable. In case if the required environment variable wasn't found, it will keep original value (i.e. ``$SECRET`` in the example). Dollar sign can be set as ``$$``. All those interpolations will be applied in succession and - expected to be - recursively, e.g. the following configuration:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[section1]
|
||||
key = ${section2:key}
|
||||
|
||||
[section2]
|
||||
key = ${home}
|
||||
home = $HOME
|
||||
|
||||
will eventually lead ``key`` option in section ``section1`` to be set to the value of ``HOME`` environment variable (if available).
|
||||
|
||||
There is also additional subcommand which will allow to validate configuration and print found errors. In order to do so, run ``service-config-validate`` subcommand, e.g.:
|
||||
|
||||
@ -81,14 +100,13 @@ Authorized users are stored inside internal database, if any of external provide
|
||||
|
||||
Build related configuration. Group name can refer to architecture, e.g. ``build:x86_64`` can be used for x86_64 architecture specific settings.
|
||||
|
||||
* ``allowed_scan_paths`` - paths to be used for implicit dependencies scan, scape separated list of paths, optional.
|
||||
* ``archbuild_flags`` - additional flags passed to ``archbuild`` command, space separated list of strings, optional.
|
||||
* ``blacklisted_scan_paths`` - paths to be excluded for implicit dependencies scan, scape separated list of paths, optional. Normally all elements of this option must be child paths of any of ``allowed_scan_paths`` element.
|
||||
* ``build_command`` - default build command, string, required.
|
||||
* ``ignore_packages`` - list packages to ignore during a regular update (manual update will still work), space separated list of strings, optional.
|
||||
* ``include_debug_packages`` - distribute debug packages, boolean, optional, default ``yes``.
|
||||
* ``makepkg_flags`` - additional flags passed to ``makepkg`` command, space separated list of strings, optional.
|
||||
* ``makechrootpkg_flags`` - additional flags passed to ``makechrootpkg`` command, space separated list of strings, optional.
|
||||
* ``scan_paths`` - paths to be used for implicit dependencies scan, space separated list of strings, optional. If any of those paths is matched against the path, it will be added to the allowed list.
|
||||
* ``triggers`` - list of ``ahriman.core.triggers.Trigger`` class implementation (e.g. ``ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger``) which will be loaded and run at the end of processing, space separated list of strings, optional. You can also specify triggers by their paths, e.g. ``/usr/lib/python3.10/site-packages/ahriman/core/report/report.py.ReportTrigger``. Triggers are run in the order of definition.
|
||||
* ``triggers_known`` - optional list of ``ahriman.core.triggers.Trigger`` class implementations which are not run automatically and used only for trigger discovery and configuration validation.
|
||||
* ``vcs_allowed_age`` - maximal age in seconds of the VCS packages before their version will be updated with its remote source, integer, optional, default is 7 days.
|
||||
@ -252,6 +270,7 @@ Section name must be either ``email`` (plus optional architecture name, e.g. ``e
|
||||
* ``password`` - SMTP password to authenticate, string, optional.
|
||||
* ``port`` - SMTP port for sending emails, integer, required.
|
||||
* ``receivers`` - SMTP receiver addresses, space separated list of strings, required.
|
||||
* ``rss_url`` - link to RSS feed, string, optional.
|
||||
* ``sender`` - SMTP sender address, string, required.
|
||||
* ``ssl`` - SSL mode for SMTP connection, one of ``ssl``, ``starttls``, ``disabled``, optional, default ``disabled``.
|
||||
* ``template`` - Jinja2 template name, string, required.
|
||||
@ -267,7 +286,8 @@ Section name must be either ``html`` (plus optional architecture name, e.g. ``ht
|
||||
* ``type`` - type of the report, string, optional, must be set to ``html`` if exists.
|
||||
* ``homepage`` - link to homepage, string, optional.
|
||||
* ``link_path`` - prefix for HTML links, string, required.
|
||||
* ``path`` - path to html report file, string, required.
|
||||
* ``path`` - path to HTML report file, string, required.
|
||||
* ``rss_url`` - link to RSS feed, string, optional.
|
||||
* ``template`` - Jinja2 template name, string, required.
|
||||
* ``templates`` - path to templates directories, space separated list of paths, required.
|
||||
|
||||
@ -282,6 +302,20 @@ Section name must be either ``remote-call`` (plus optional architecture name, e.
|
||||
* ``manual`` - update manually built packages, boolean, optional, default ``no``.
|
||||
* ``wait_timeout`` - maximum amount of time in seconds to be waited before remote process will be terminated, integer, optional, default ``-1``.
|
||||
|
||||
``rss`` type
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Section name must be either ``rss`` (plus optional architecture name, e.g. ``rss:x86_64``) or random name with ``type`` set.
|
||||
|
||||
* ``type`` - type of the report, string, optional, must be set to ``rss`` if exists.
|
||||
* ``homepage`` - link to homepage, string, optional.
|
||||
* ``link_path`` - prefix for HTML links, string, required.
|
||||
* ``max_entries`` - maximal amount of entries to be included to the report, negative means no limit, integer, optional, default ``-1``.
|
||||
* ``path`` - path to generated RSS file, string, required.
|
||||
* ``rss_url`` - link to RSS feed, string, optional.
|
||||
* ``template`` - Jinja2 template name, string, required.
|
||||
* ``templates`` - path to templates directories, space separated list of paths, required.
|
||||
|
||||
``telegram`` type
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
@ -292,6 +326,7 @@ Section name must be either ``telegram`` (plus optional architecture name, e.g.
|
||||
* ``chat_id`` - telegram chat id, either string with ``@`` or integer value, required.
|
||||
* ``homepage`` - link to homepage, string, optional.
|
||||
* ``link_path`` - prefix for HTML links, string, required.
|
||||
* ``rss_url`` - link to RSS feed, string, optional.
|
||||
* ``template`` - Jinja2 template name, string, required.
|
||||
* ``template_type`` - ``parse_mode`` to be passed to telegram API, one of ``MarkdownV2``, ``HTML``, ``Markdown``, string, optional, default ``HTML``.
|
||||
* ``templates`` - path to templates directories, space separated list of paths, required.
|
||||
@ -344,7 +379,7 @@ Requires ``rsync`` package to be installed. Do not forget to configure ssh for u
|
||||
|
||||
* ``type`` - type of the upload, string, optional, must be set to ``rsync`` if exists.
|
||||
* ``command`` - rsync command to run, space separated list of string, required.
|
||||
* ``remote`` - remote server to rsync (e.g. ``1.2.3.4:path/to/sync``), string, required.
|
||||
* ``remote`` - remote server to rsync (e.g. ``ahriman@10.0.0.1:/srv/repo``), string, required.
|
||||
|
||||
``s3`` type
|
||||
^^^^^^^^^^^
|
||||
|
@ -8,8 +8,8 @@ Remote synchronization and remote server call
|
||||
|
||||
This setup requires at least two instances of the service:
|
||||
|
||||
#. Web service (with opt-in authorization enabled), later will be referenced as ``master`` node.
|
||||
#. Application instances responsible for build, later will be referenced as ``worker`` nodes.
|
||||
#. Web service (with opt-in authorization enabled), later will be referenced as **master** node.
|
||||
#. Application instances responsible for build, later will be referenced as **worker** nodes.
|
||||
|
||||
In this example the following settings are assumed:
|
||||
|
||||
@ -70,7 +70,7 @@ Worker nodes configuration
|
||||
username = worker-user
|
||||
password = very-secure-password
|
||||
|
||||
As it has been mentioned above, ``status.address`` must be available for workers. In case if unix socket is used, it can be passed in the same option as usual. Optional ``status.username``/``status.password`` can be supplied in case if authentication was enabled on master node.
|
||||
As it has been mentioned above, ``${status:address}`` must be available for workers. In case if unix socket is used, it can be passed in the same option as usual. Optional ``${status:username}``/``${status:password}`` can be supplied in case if authentication was enabled on master node.
|
||||
|
||||
#.
|
||||
Each worker must call master node on success:
|
||||
@ -83,7 +83,7 @@ Worker nodes configuration
|
||||
[remote-call]
|
||||
manual = yes
|
||||
|
||||
After success synchronization (see above), the built packages will be put into directory, from which they will be read during manual update, thus ``remote-call.manual`` flag is required.
|
||||
After success synchronization (see above), the built packages will be put into directory, from which they will be read during manual update, thus ``${remote-call:manual}`` flag is required.
|
||||
|
||||
#.
|
||||
Change order of trigger runs. This step is required, because by default the report trigger is called before the upload trigger and we would like to achieve the opposite:
|
||||
@ -202,12 +202,12 @@ This action must be done in two steps:
|
||||
Delegate builds to remote workers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This setup heavily uses upload feature described above and, in addition, also delegates build process automatically to build machines. Same as above, there must be at least two instances available (``master`` and ``worker``), however, all ``worker`` nodes must be run in the web service mode.
|
||||
This setup heavily uses upload feature described above and, in addition, also delegates build process automatically to build machines. Same as above, there must be at least two instances available (**master** and **worker**), however, all **worker** nodes must be run in the web service mode.
|
||||
|
||||
Master node configuration
|
||||
"""""""""""""""""""""""""
|
||||
|
||||
In addition to the configuration above, the worker list must be defined in configuration file (``build.workers`` option), i.e.:
|
||||
In addition to the configuration above, the worker list must be defined in configuration file (``${build:workers}`` option), i.e.:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
@ -218,7 +218,7 @@ In addition to the configuration above, the worker list must be defined in confi
|
||||
enable_archive_upload = yes
|
||||
wait_timeout = 0
|
||||
|
||||
In the example above, ``https://worker1.example.com`` and ``https://worker2.example.com`` are remote ``worker`` node addresses available for ``master`` node.
|
||||
In the example above, ``https://worker1.example.com`` and ``https://worker2.example.com`` are remote **worker** node addresses available for **master** node.
|
||||
|
||||
In case if authentication is required (which is recommended way to setup it), it can be set by using ``status`` section as usual.
|
||||
|
||||
@ -229,7 +229,7 @@ It is required to point to the master node repository, otherwise internal depend
|
||||
|
||||
Also, in case if authentication is enabled, the same user with the same password must be created for all workers.
|
||||
|
||||
It is also recommended to set ``web.wait_timeout`` to infinite in case of multiple conflicting runs and ``service_only`` to ``yes`` in order to disable status endpoints.
|
||||
It is also recommended to set ``${web:wait_timeout}`` to infinite in case of multiple conflicting runs and ``${web:service_only}`` to ``yes`` in order to disable status endpoints.
|
||||
|
||||
Other settings are the same as mentioned above.
|
||||
|
||||
@ -292,24 +292,24 @@ Worker nodes (applicable for all workers) config (``worker.ini``) as:
|
||||
|
||||
Command to run worker nodes (considering there will be two workers, one is on ``8081`` port and other is on ``8082``):
|
||||
|
||||
.. code-block:: ini
|
||||
.. code-block:: shell
|
||||
|
||||
docker run --privileged -p 8081:8081 -e AHRIMAN_PORT=8081 -v worker.ini:/etc/ahriman.ini.d/overrides.ini arcan1s/ahriman:latest web
|
||||
docker run --privileged -p 8082:8082 -e AHRIMAN_PORT=8082 -v worker.ini:/etc/ahriman.ini.d/overrides.ini arcan1s/ahriman:latest web
|
||||
|
||||
Unlike the previous setup, it doesn't require to mount repository root for ``worker`` nodes, because they don't use it anyway.
|
||||
Unlike the previous setup, it doesn't require to mount repository root for **worker** nodes, because they don't use it anyway.
|
||||
|
||||
Check proof-of-concept setup `here <https://github.com/arcan1s/ahriman/tree/master/recipes/distributed>`__.
|
||||
|
||||
Addition of new package, package removal, repository update
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
In all scenarios, update process must be run only on ``master`` node. Unlike the manually distributed packages described above, automatic update must be enabled only for ``master`` node.
|
||||
In all scenarios, update process must be run only on **master** node. Unlike the manually distributed packages described above, automatic update must be enabled only for **master** node.
|
||||
|
||||
Automatic worker nodes discovery
|
||||
""""""""""""""""""""""""""""""""
|
||||
|
||||
Instead of setting ``build.workers`` option it is also possible to configure services to load worker list dynamically. To do so, the ``ahriman.core.distributed.WorkerLoaderTrigger`` and ``ahriman.core.distributed.WorkerTrigger`` must be used for ``master`` and ``worker`` nodes repsectively. See recipes for more details.
|
||||
Instead of setting ``${build:workers}`` option explicitly it is also possible to configure services to load worker list dynamically. To do so, the ``ahriman.core.distributed.WorkerLoaderTrigger`` and ``ahriman.core.distributed.WorkerTrigger`` must be used for **master** and **worker** nodes respectively. See recipes for more details.
|
||||
|
||||
Known limitations
|
||||
"""""""""""""""""
|
||||
@ -317,4 +317,4 @@ Known limitations
|
||||
* Workers don't support local packages. However, it is possible to build custom packages by providing sources by using ``ahriman.core.gitremote.RemotePullTrigger`` trigger.
|
||||
* No dynamic nodes discovery. In case if one of worker nodes is unavailable, the build process will fail.
|
||||
* No pkgrel bump on conflicts.
|
||||
* The identical user must be created for all workers. However, the ``master`` node user can be different from this one.
|
||||
* The identical user must be created for all workers. However, the **master** node user can be different from this one.
|
||||
|
@ -143,7 +143,7 @@ TL;DR
|
||||
|
||||
sudo -u ahriman ahriman package-add /path/to/local/directory/with/PKGBUILD --now
|
||||
|
||||
Before using this command you will need to create local directory, put ``PKGBUILD`` there and generate ``.SRCINFO`` by using ``makepkg --printsrcinfo > .SRCINFO`` command. These packages will be stored locally and *will be ignored* during automatic update; in order to update the package you will need to run ``package-add`` command again.
|
||||
Before using this command you will need to create local directory and put ``PKGBUILD`` there. These packages will be stored locally and *will be ignored* during automatic update; in order to update the package you will need to run ``package-add`` command again.
|
||||
|
||||
How to copy package from another repository
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -265,11 +265,7 @@ TL;DR
|
||||
How to update VCS packages
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Normally the service handles VCS packages correctly, however it requires additional dependencies:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
pacman -S breezy darcs mercurial subversion
|
||||
Normally the service handles VCS packages correctly. The version is updated in clean chroot, no additional actions are required.
|
||||
|
||||
How to review changes before build
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -379,7 +375,7 @@ After the success build the application extracts all linked libraries and used d
|
||||
|
||||
In order to disable this check completely, the ``--no-check-files`` flag can be used.
|
||||
|
||||
In addition, there is possibility to control paths which will be used for checking, by using options ``build.allowed_scan_paths`` and ``build.blacklisted_scan_paths``. Leaving ``build.allowed_scan_paths`` blank will effectively disable any check too.
|
||||
In addition, there is possibility to control paths which will be used for checking, by using option ``${build:scan_paths}``, which supports regular expressions. Leaving ``${build:scan_paths}`` blank will effectively disable any check too.
|
||||
|
||||
How to install built packages
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -14,7 +14,7 @@ The application provides special plugin which generates keyring package. This pl
|
||||
[keyring]
|
||||
target = keyring-generator
|
||||
|
||||
By default it will use ``sign.key`` as trusted key and all other keys as packagers ones. For all available options refer to :doc:`configuration </configuration>`.
|
||||
By default it will use ``${sign:key}`` as trusted key and all other keys as packagers ones. For all available options refer to :doc:`configuration </configuration>`.
|
||||
|
||||
#.
|
||||
Create package source files:
|
||||
@ -52,7 +52,7 @@ The application provides special plugin which generates mirrorlist package also.
|
||||
[mirrorlist-generator]
|
||||
servers = https://repo.example.com/$arch
|
||||
|
||||
The ``mirrorlist-generator.servers`` must contain list of available mirrors, the ``$arch`` and ``$repo`` variables are supported. For more options kindly refer to :doc:`configuration </configuration>`.
|
||||
The ``${mirrorlist-generator:servers}`` must contain list of available mirrors, the ``$arch`` and ``$repo`` variables are supported. For more options kindly refer to :doc:`configuration </configuration>`.
|
||||
|
||||
#.
|
||||
Create package source files:
|
||||
|
@ -28,8 +28,8 @@ How to report by email
|
||||
sender = me@example.com
|
||||
user = me@example.com
|
||||
|
||||
How to generate index page for S3
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
How to generate index page
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#.
|
||||
Install dependencies:
|
||||
@ -47,10 +47,30 @@ How to generate index page for S3
|
||||
target = html
|
||||
|
||||
[html]
|
||||
path = /var/lib/ahriman/repository/aur-clone/x86_64/index.html
|
||||
path = ${repository:root}/repository/aur-clone/x86_64/index.html
|
||||
link_path = http://example.com/aur-clone/x86_64
|
||||
|
||||
After these steps ``index.html`` file will be automatically synced to S3.
|
||||
Having this configuration, the generated ``index.html`` will be also automatically synced to remote services (e.g. S3).
|
||||
|
||||
How to generate RSS feed for index page
|
||||
"""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
In addition to previous steps, the following configuration is required:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[report]
|
||||
target = html rss
|
||||
|
||||
[html]
|
||||
rss_url = ${html:link_path}/rss.xml
|
||||
|
||||
[rss]
|
||||
link_path = ${html:link_path}
|
||||
path = ${repository:root}/repository/ahriman-demo/x86_64/rss.xml
|
||||
rss_url = ${html:link_path}/rss.xml
|
||||
|
||||
With the appended configuration, the service fill also generate ``rss.xml``, link it to generated ``index.html`` and put it together.
|
||||
|
||||
How to post build report to telegram
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -88,12 +108,12 @@ How to post build report to telegram
|
||||
chat_id = @ahriman
|
||||
link_path = http://example.com/aur-clone/x86_64
|
||||
|
||||
``api_key`` is the one sent by `@BotFather <https://t.me/botfather>`__, ``chat_id`` is the value retrieved from previous step.
|
||||
``${api_key}`` is the one sent by `@BotFather <https://t.me/botfather>`__, ``${chat_id}`` is the value retrieved from previous step.
|
||||
|
||||
If you did everything fine you should receive the message with the next update. Quick credentials check can be done by using the following command:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
curl 'https://api.telegram.org/bot{api_key}/sendMessage?chat_id={chat_id}&text=hello'
|
||||
curl 'https://api.telegram.org/bot${api_key}/sendMessage?chat_id=${chat_id}&text=hello'
|
||||
|
||||
(replace ``{chat_id}`` and ``{api_key}`` with the values from configuration).
|
||||
(replace ``${chat_id}`` and ``${api_key}`` with the values from configuration).
|
||||
|
@ -41,7 +41,7 @@ How to enable basic authorization
|
||||
target = configuration
|
||||
salt = somerandomstring
|
||||
|
||||
The ``salt`` parameter is optional, but recommended, and can be set to any (random) string.
|
||||
The ``${auth:salt}`` parameter is optional, but recommended, and can be set to any (random) string.
|
||||
|
||||
#.
|
||||
In order to provide access for reporting from application instances you can (the recommended way) use unix sockets by the following configuration (note, that it requires ``python-requests-unixsocket2`` package to be installed):
|
||||
@ -53,7 +53,7 @@ How to enable basic authorization
|
||||
|
||||
This socket path must be available for web service instance and must be available for all application instances (e.g. in case if you are using docker container - see above - you need to make sure that the socket is passed to the root filesystem).
|
||||
|
||||
By the way, unix socket variable will be automatically set in case if ``--web-unix-socket`` argument is supplied to the ``setup`` subcommand.
|
||||
By the way, unix socket variable will be automatically set in case if ``--web-unix-socket`` argument is supplied to the ``service-setup`` subcommand.
|
||||
|
||||
Alternatively, you need to create user for the service:
|
||||
|
||||
@ -96,7 +96,7 @@ How to enable OAuth authorization
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#.
|
||||
Create OAuth web application, download its ``client_id`` and ``client_secret``.
|
||||
Create OAuth web application, download its ``${auth:client_id}`` and ``${auth:client_secret}``.
|
||||
|
||||
#.
|
||||
Guess what? Install dependencies:
|
||||
@ -118,10 +118,10 @@ How to enable OAuth authorization
|
||||
[web]
|
||||
address = https://example.com
|
||||
|
||||
Configure ``oauth_provider`` and ``oauth_scopes`` in case if you would like to use different from Google provider. Scope must grant access to user email. ``web.address`` is required to make callback URL available from internet.
|
||||
Configure ``${auth:oauth_provider}`` and ``${auth:oauth_scopes}`` in case if you would like to use different from Google provider. Scope must grant access to user email. ``${web:address}`` is required to make callback URL available from internet.
|
||||
|
||||
#.
|
||||
If you are not going to use unix socket, you also need to create service user (remember to set ``auth.salt`` option before if required):
|
||||
If you are not going to use unix socket, you also need to create service user (remember to set ``${auth:salt}`` option before if required):
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
|
BIN
github-logo.png
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 76 KiB |
@ -1,18 +1,15 @@
|
||||
# Maintainer: Evgeniy Alekseev
|
||||
|
||||
pkgname='ahriman'
|
||||
pkgver=2.14.1
|
||||
pkgver=2.15.1
|
||||
pkgrel=1
|
||||
pkgdesc="ArcH linux ReposItory MANager"
|
||||
arch=('any')
|
||||
url="https://github.com/arcan1s/ahriman"
|
||||
license=('GPL3')
|
||||
depends=('devtools>=1:1.0.0' 'git' 'pyalpm' 'python-cerberus' 'python-inflection' 'python-passlib' 'python-pyelftools' 'python-requests' 'python-srcinfo')
|
||||
depends=('devtools>=1:1.0.0' 'git' 'pyalpm' 'python-inflection' 'python-passlib' 'python-pyelftools' 'python-requests')
|
||||
makedepends=('python-build' 'python-flit' 'python-installer' 'python-wheel')
|
||||
optdepends=('breezy: -bzr packages support'
|
||||
'darcs: -darcs packages support'
|
||||
'mercurial: -hg packages support'
|
||||
'python-aioauth-client: web server with OAuth2 authorization'
|
||||
optdepends=('python-aioauth-client: web server with OAuth2 authorization'
|
||||
'python-aiohttp: web server'
|
||||
'python-aiohttp-apispec>=3.0.0: web server'
|
||||
'python-aiohttp-cors: web server'
|
||||
@ -20,12 +17,13 @@ optdepends=('breezy: -bzr packages support'
|
||||
'python-aiohttp-security: web server with authorization'
|
||||
'python-aiohttp-session: web server with authorization'
|
||||
'python-boto3: sync to s3'
|
||||
'python-cerberus: configuration validator'
|
||||
'python-cryptography: web server with authorization'
|
||||
'python-matplotlib: usage statistics chart'
|
||||
'python-requests-unixsocket2: client report to web server by unix socket'
|
||||
'python-jinja: html report generation'
|
||||
'python-systemd: journal support'
|
||||
'rsync: sync by using rsync'
|
||||
'subversion: -svn packages support')
|
||||
'rsync: sync by using rsync')
|
||||
source=("https://github.com/arcan1s/ahriman/releases/download/$pkgver/$pkgname-$pkgver.tar.gz"
|
||||
'ahriman.sysusers'
|
||||
'ahriman.tmpfiles')
|
||||
|
@ -3,7 +3,7 @@ Description=ArcH linux ReposItory MANager (%i)
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/ahriman --repository-id "%I" repo-daemon --no-changes --refresh
|
||||
ExecStart=/usr/bin/ahriman --repository-id "%I" repo-daemon --refresh
|
||||
User=ahriman
|
||||
Group=ahriman
|
||||
|
||||
|
@ -2,6 +2,6 @@
|
||||
Description=ArcH linux ReposItory MANager (%i)
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/ahriman --repository-id "%I" repo-update --no-changes --refresh
|
||||
ExecStart=/usr/bin/ahriman --repository-id "%I" repo-update --refresh
|
||||
User=ahriman
|
||||
Group=ahriman
|
||||
|
@ -3,10 +3,10 @@
|
||||
include = ahriman.ini.d
|
||||
; Relative path to configuration used by logging package.
|
||||
logging = ahriman.ini.d/logging.ini
|
||||
; Perform database migrations on the application start. Do not touch this option unless you know what are you doing.
|
||||
; Perform database migrations on the application start. Do not touch this option unless you know what you are doing.
|
||||
;apply_migrations = yes
|
||||
; Path to the application SQLite database.
|
||||
database = /var/lib/ahriman/ahriman.db
|
||||
database = ${repository:root}/ahriman.db
|
||||
|
||||
[alpm]
|
||||
; Path to pacman system database cache.
|
||||
@ -17,14 +17,14 @@ mirror = https://geo.mirror.pkgbuild.com/$repo/os/$arch
|
||||
repositories = core extra multilib
|
||||
; Pacman's root directory. In the most cases it must point to the system root.
|
||||
root = /
|
||||
; Sync files databases too, which is required by deep dependencies check
|
||||
; Sync files databases too, which is required by deep dependencies check.
|
||||
sync_files_database = yes
|
||||
; Use local packages cache. If this option is enabled, the service will be able to synchronize databases (available
|
||||
; as additional option for some subcommands). If set to no, databases must be synchronized manually.
|
||||
use_ahriman_cache = yes
|
||||
|
||||
[auth]
|
||||
; Authentication provider, must be one of disabled, configuration, oauth.
|
||||
; Authentication provider, must be one of disabled, configuration, pam, oauth.
|
||||
target = disabled
|
||||
; Allow read-only endpoint to be called without authentication.
|
||||
allow_read_only = yes
|
||||
@ -34,7 +34,7 @@ allow_read_only = yes
|
||||
; Cookie secret key to be used for cookies encryption. Must be valid 32 bytes URL-safe base64-encoded string.
|
||||
; If not set, it will be generated automatically.
|
||||
;cookie_secret_key =
|
||||
; Name of the secondary group to be used as admin group in the service.
|
||||
; Name of the secondary group to be used as admin group in the service. Required if pam is used.
|
||||
;full_access_group = wheel
|
||||
; Authentication cookie expiration in seconds.
|
||||
;max_age = 604800
|
||||
@ -44,28 +44,26 @@ allow_read_only = yes
|
||||
;oauth_provider = GoogleClient
|
||||
; Scopes list for OAuth2 provider. Required if oauth is used.
|
||||
;oauth_scopes = https://www.googleapis.com/auth/userinfo.email
|
||||
; Allow login as root user (only if PAM is used).
|
||||
; Allow login as root user (only applicable if PAM is used).
|
||||
;permit_root_login = no
|
||||
; Optional password salt.
|
||||
;salt =
|
||||
|
||||
[build]
|
||||
; List of paths to be used for implicit dependency scan
|
||||
allowed_scan_paths = /usr/lib
|
||||
; List of additional flags passed to archbuild command.
|
||||
;archbuild_flags =
|
||||
; List of paths to be excluded for implicit dependency scan. Usually they should be subpaths of allowed_scan_paths
|
||||
blacklisted_scan_paths = /usr/lib/cmake
|
||||
; Path to build command
|
||||
; Path to build command.
|
||||
;build_command =
|
||||
; List of packages to be ignored during automatic updates.
|
||||
;ignore_packages =
|
||||
; Include debug packages
|
||||
; Include debug packages.
|
||||
;include_debug_packages = yes
|
||||
; List of additional flags passed to makechrootpkg command.
|
||||
;makechrootpkg_flags =
|
||||
; List of additional flags passed to makepkg command.
|
||||
makepkg_flags = --nocolor --ignorearch
|
||||
; List of paths to be used for implicit dependency scan. Regular expressions are supported.
|
||||
scan_paths = ^usr/lib(?!/cmake).*$
|
||||
; List of enabled triggers in the order of calls.
|
||||
triggers = ahriman.core.gitremote.RemotePullTrigger ahriman.core.report.ReportTrigger ahriman.core.upload.UploadTrigger ahriman.core.gitremote.RemotePushTrigger
|
||||
; List of well-known triggers. Used only for configuration purposes.
|
||||
@ -91,10 +89,10 @@ target =
|
||||
; Global switch to enable or disable status reporting.
|
||||
enabled = yes
|
||||
; Address of the remote service, e.g.:
|
||||
; address = http://1.0.0.1:8080
|
||||
; address = http://127.0.0.1:8080
|
||||
; In case if unix sockets are used, it might point to the valid socket with encoded path, e.g.:
|
||||
; address = http+unix://%2Fvar%2Flib%2Fahriman%2Fsocket
|
||||
;address =
|
||||
;address = http://${web:host}:${web:port}
|
||||
; Optional password for authentication (if enabled).
|
||||
;password =
|
||||
; Do not log HTTP errors if occurs.
|
||||
@ -106,24 +104,24 @@ suppress_http_log_errors = yes
|
||||
|
||||
[web]
|
||||
; External address of the web service. Will be used for some features like OAuth. If none set will be generated as
|
||||
; address = http://web.host:web.port
|
||||
;address =
|
||||
; address = http://${web:host}:${web:port}
|
||||
;address = http://${web:host}:${web:port}
|
||||
; Enable file upload endpoint used by some triggers.
|
||||
;enable_archive_upload = no
|
||||
; Address to bind the server.
|
||||
host = 127.0.0.1
|
||||
; Full URL to the repository index page used by templates.
|
||||
;index_url =
|
||||
; Max file size in bytes which can be uploaded to the server.
|
||||
; Max file size in bytes which can be uploaded to the server. Requires ${web:enable_archive_upload} to be enabled.
|
||||
;max_body_size =
|
||||
; Port to listen. Must be set, if the web service is enabled.
|
||||
;port =
|
||||
; Disable status (e.g. package status, logs, etc) endpoints. Useful for build only modes.
|
||||
;service_only = no
|
||||
; Path to directory with static files.
|
||||
static_path = /usr/share/ahriman/templates/static
|
||||
static_path = ${templates}/static
|
||||
; List of directories with templates.
|
||||
templates = /usr/share/ahriman/templates
|
||||
templates = ${prefix}/share/ahriman/templates
|
||||
; Path to unix socket. If none set, unix socket will be disabled.
|
||||
;unix_socket =
|
||||
; Allow unix socket to be world readable.
|
||||
@ -214,14 +212,14 @@ target = console
|
||||
|
||||
; Console reporting trigger configuration sample.
|
||||
[console]
|
||||
; Trigger type name
|
||||
; Trigger type name.
|
||||
;type = console
|
||||
; Use utf8 symbols in output.
|
||||
use_utf = yes
|
||||
|
||||
; Email reporting trigger configuration sample.
|
||||
[email]
|
||||
; Trigger type name
|
||||
; Trigger type name.
|
||||
;type = email
|
||||
; Optional URL to the repository homepage.
|
||||
;homepage=
|
||||
@ -237,6 +235,8 @@ use_utf = yes
|
||||
;port =
|
||||
; List of emails to receive the reports.
|
||||
;receivers =
|
||||
; Optional link to the RSS feed.
|
||||
;rss_url =
|
||||
; Sender email.
|
||||
;sender =
|
||||
; SMTP server SSL mode, one of ssl, starttls, disabled.
|
||||
@ -246,13 +246,13 @@ template = email-index.jinja2
|
||||
; Template name to be used for full packages list generation (same as HTML report).
|
||||
;template_full =
|
||||
; List of directories with templates.
|
||||
templates = /usr/share/ahriman/templates
|
||||
templates = ${prefix}/share/ahriman/templates
|
||||
; SMTP user.
|
||||
;user =
|
||||
|
||||
; HTML reporting trigger configuration sample.
|
||||
[html]
|
||||
; Trigger type name
|
||||
; Trigger type name.
|
||||
;type = html
|
||||
; Optional URL to the repository homepage.
|
||||
;homepage=
|
||||
@ -260,14 +260,16 @@ templates = /usr/share/ahriman/templates
|
||||
;link_path =
|
||||
; Output path for the HTML report.
|
||||
;path =
|
||||
; Optional link to the RSS feed.
|
||||
;rss_url =
|
||||
; Template name to be used.
|
||||
template = repo-index.jinja2
|
||||
; List of directories with templates.
|
||||
templates = /usr/share/ahriman/templates
|
||||
templates = ${prefix}/share/ahriman/templates
|
||||
|
||||
; Remote service callback trigger configuration sample.
|
||||
[remote-call]
|
||||
; Trigger type name
|
||||
; Trigger type name.
|
||||
;type = remote-call
|
||||
; Call for AUR packages update.
|
||||
;aur = no
|
||||
@ -278,9 +280,26 @@ templates = /usr/share/ahriman/templates
|
||||
; Wait until remote process will be terminated in seconds.
|
||||
;wait_timeout = -1
|
||||
|
||||
; RSS reporting trigger configuration sample.
|
||||
[rss]
|
||||
; Trigger type name.
|
||||
;type = rss
|
||||
; Optional URL to the repository homepage.
|
||||
;homepage=
|
||||
; Prefix for packages links. Link to a package will be formed as link_path / filename.
|
||||
;link_path =
|
||||
; Output path for the RSS report.
|
||||
;path =
|
||||
; Optional link to the RSS feed.
|
||||
;rss_url =
|
||||
; Template name to be used.
|
||||
template = rss.jinja2
|
||||
; List of directories with templates.
|
||||
templates = ${prefix}/share/ahriman/templates
|
||||
|
||||
; Telegram reporting trigger configuration sample.
|
||||
[telegram]
|
||||
; Trigger type name
|
||||
; Trigger type name.
|
||||
;type = telegram
|
||||
; Telegram bot API key.
|
||||
;api_key =
|
||||
@ -290,12 +309,14 @@ templates = /usr/share/ahriman/templates
|
||||
;homepage=
|
||||
; Prefix for packages links. Link to a package will be formed as link_path / filename.
|
||||
;link_path =
|
||||
; Optional link to the RSS feed.
|
||||
;rss_url =
|
||||
; Template name to be used.
|
||||
template = telegram-index.jinja2
|
||||
; Telegram specific template mode, one of MarkdownV2, HTML or Markdown.
|
||||
;template_type = HTML
|
||||
; List of directories with templates.
|
||||
templates = /usr/share/ahriman/templates
|
||||
templates = ${prefix}/share/ahriman/templates
|
||||
; HTTP request timeout in seconds.
|
||||
;timeout = 30
|
||||
|
||||
@ -306,7 +327,7 @@ target =
|
||||
|
||||
; GitHub upload trigger configuration sample.
|
||||
[github]
|
||||
; Trigger type name
|
||||
; Trigger type name.
|
||||
;type = github
|
||||
; GitHub repository owner username.
|
||||
;owner =
|
||||
@ -323,14 +344,14 @@ target =
|
||||
|
||||
; Remote instance upload trigger configuration sample.
|
||||
[remote-service]
|
||||
; Trigger type name
|
||||
; Trigger type name.
|
||||
;type = remote-service
|
||||
; HTTP request timeout in seconds.
|
||||
;timeout = 30
|
||||
|
||||
; rsync upload trigger configuration sample.
|
||||
[rsync]
|
||||
; Trigger type name
|
||||
; Trigger type name.
|
||||
;type = rsync
|
||||
; rsync command to run.
|
||||
command = rsync --archive --compress --partial --delete
|
||||
@ -340,7 +361,7 @@ command = rsync --archive --compress --partial --delete
|
||||
|
||||
; S3 upload trigger configuration sample.
|
||||
[s3]
|
||||
; Trigger type name
|
||||
; Trigger type name.
|
||||
;type = s3
|
||||
; AWS services access key.
|
||||
;access_key =
|
||||
|
@ -1,5 +1,5 @@
|
||||
[loggers]
|
||||
keys = root,http,stderr,boto3,botocore,nose,s3transfer
|
||||
keys = root,http,stderr,boto3,botocore,nose,s3transfer,sql
|
||||
|
||||
[handlers]
|
||||
keys = console_handler,journald_handler,syslog_handler
|
||||
@ -64,3 +64,8 @@ propagate = 0
|
||||
level = INFO
|
||||
qualname = s3transfer
|
||||
propagate = 0
|
||||
|
||||
[logger_sql]
|
||||
level = INFO
|
||||
qualname = sql
|
||||
propagate = 0
|
||||
|
@ -15,6 +15,7 @@
|
||||
apiDescriptionUrl="/api-docs/swagger.json"
|
||||
router="hash"
|
||||
layout="sidebar"
|
||||
logo="/static/logo.svg"
|
||||
/>
|
||||
|
||||
</body>
|
||||
|
@ -44,28 +44,28 @@
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<button id="package-add-button" class="btn dropdown-item" data-bs-toggle="modal" data-bs-target="#package-add-modal" hidden>
|
||||
<button id="package-add-button" class="btn dropdown-item" data-bs-toggle="modal" data-bs-target="#package-add-modal">
|
||||
<i class="bi bi-plus"></i> add
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button id="package-update-button" class="btn dropdown-item" onclick="packagesUpdate()" hidden>
|
||||
<button id="package-update-button" class="btn dropdown-item" onclick="packagesUpdate()">
|
||||
<i class="bi bi-play"></i> update
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button id="package-rebuild-button" class="btn dropdown-item" data-bs-toggle="modal" data-bs-target="#package-rebuild-modal" hidden>
|
||||
<button id="package-rebuild-button" class="btn dropdown-item" data-bs-toggle="modal" data-bs-target="#package-rebuild-modal">
|
||||
<i class="bi bi-arrow-clockwise"></i> rebuild
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button id="package-remove-button" class="btn dropdown-item" onclick="packagesRemove()" disabled hidden>
|
||||
<button id="package-remove-button" class="btn dropdown-item" onclick="packagesRemove()" disabled>
|
||||
<i class="bi bi-trash"></i> remove
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<button id="key-import-button" type="button" class="btn btn-info" data-bs-toggle="modal" data-bs-target="#key-import-modal" hidden>
|
||||
<button id="key-import-button" type="button" class="btn btn-info" data-bs-toggle="modal" data-bs-target="#key-import-modal">
|
||||
<i class="bi bi-key"></i><span class="d-none d-sm-inline"> import key</span>
|
||||
</button>
|
||||
{% endif %}
|
||||
|
@ -1,8 +1,12 @@
|
||||
<script>
|
||||
const alertPlaceholder = $("#alert-placeholder");
|
||||
const alertPlaceholder = document.getElementById("alert-placeholder");
|
||||
|
||||
function createAlert(title, message, clz, action, id) {
|
||||
id ??= md5(title + message); // MD5 id from the content
|
||||
if (alertPlaceholder.querySelector(`#alert-${id}`)) return; // check if there are duplicates
|
||||
|
||||
function createAlert(title, message, clz, action) {
|
||||
const wrapper = document.createElement("div");
|
||||
wrapper.id = `alert-${id}`;
|
||||
wrapper.classList.add("toast", clz);
|
||||
wrapper.role = "alert";
|
||||
wrapper.ariaLive = "assertive";
|
||||
@ -19,7 +23,7 @@
|
||||
body.innerText = message;
|
||||
wrapper.appendChild(body);
|
||||
|
||||
alertPlaceholder.append(wrapper);
|
||||
alertPlaceholder.appendChild(wrapper);
|
||||
const toast = new bootstrap.Toast(wrapper);
|
||||
wrapper.addEventListener("hidden.bs.toast", _ => {
|
||||
wrapper.remove(); // bootstrap doesn't remove elements
|
||||
@ -28,12 +32,12 @@
|
||||
toast.show();
|
||||
}
|
||||
|
||||
function showFailure(title, description, jqXHR, errorThrown) {
|
||||
function showFailure(title, description, error) {
|
||||
let details;
|
||||
try {
|
||||
details = $.parseJSON(jqXHR.responseText).error; // execution handler json error response
|
||||
details = JSON.parse(error.text).error; // execution handler json error response
|
||||
} catch (_) {
|
||||
details = errorThrown;
|
||||
details = error.text ?? error.message ?? error;
|
||||
}
|
||||
createAlert(title, description(details), "text-bg-danger");
|
||||
}
|
||||
|
@ -36,61 +36,69 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const keyImportModal = $("#key-import-modal");
|
||||
const keyImportForm = $("#key-import-form");
|
||||
const keyImportModal = document.getElementById("key-import-modal");
|
||||
const keyImportForm = document.getElementById("key-import-form");
|
||||
|
||||
const keyImportBodyInput = $("#key-import-body-input");
|
||||
const keyImportCopyButton = $("#key-import-copy-button");
|
||||
const keyImportBodyInput = document.getElementById("key-import-body-input");
|
||||
const keyImportCopyButton = document.getElementById("key-import-copy-button");
|
||||
|
||||
const keyImportFingerprintInput = $("#key-import-fingerprint-input");
|
||||
const keyImportServerInput = $("#key-import-server-input");
|
||||
const keyImportFingerprintInput = document.getElementById("key-import-fingerprint-input");
|
||||
const keyImportServerInput = document.getElementById("key-import-server-input");
|
||||
|
||||
async function copyPgpKey() {
|
||||
const logs = keyImportBodyInput.text();
|
||||
await copyToClipboard(logs, keyImportCopyButton);
|
||||
const key = keyImportBodyInput.textContent;
|
||||
await copyToClipboard(key, keyImportCopyButton);
|
||||
}
|
||||
|
||||
function fetchPgpKey() {
|
||||
const key = keyImportFingerprintInput.val();
|
||||
const server = keyImportServerInput.val();
|
||||
const key = keyImportFingerprintInput.value;
|
||||
const server = keyImportServerInput.value;
|
||||
|
||||
if (key && server) {
|
||||
$.ajax({
|
||||
url: "/api/v1/service/pgp",
|
||||
data: {"key": key, "server": server},
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
success: response => { keyImportBodyInput.text(response.key); },
|
||||
});
|
||||
makeRequest(
|
||||
"/api/v1/service/pgp",
|
||||
{
|
||||
query: {
|
||||
key: key,
|
||||
server: server,
|
||||
},
|
||||
convert: response => response.json(),
|
||||
},
|
||||
data => { keyImportBodyInput.textContent = data.key; },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function importPgpKey() {
|
||||
const key = keyImportFingerprintInput.val();
|
||||
const server = keyImportServerInput.val();
|
||||
const key = keyImportFingerprintInput.value;
|
||||
const server = keyImportServerInput.value;
|
||||
|
||||
if (key && server) {
|
||||
$.ajax({
|
||||
url: "/api/v1/service/pgp",
|
||||
data: JSON.stringify({key: key, server: server}),
|
||||
type: "POST",
|
||||
contentType: "application/json",
|
||||
success: _ => {
|
||||
keyImportModal.modal("hide");
|
||||
makeRequest(
|
||||
"/api/v1/service/pgp",
|
||||
{
|
||||
method: "POST",
|
||||
json: {
|
||||
key: key,
|
||||
server: server,
|
||||
},
|
||||
},
|
||||
_ => {
|
||||
bootstrap.Modal.getOrCreateInstance(keyImportModal).hide();
|
||||
showSuccess("Success", `Key ${key} has been imported`);
|
||||
},
|
||||
error: (jqXHR, _, errorThrown) => {
|
||||
error => {
|
||||
const message = _ => `Could not import key ${key} from ${server}`;
|
||||
showFailure("Action failed", message, jqXHR, errorThrown);
|
||||
showFailure("Action failed", message, error);
|
||||
},
|
||||
});
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$(_ => {
|
||||
keyImportModal.on("hidden.bs.modal", _ => {
|
||||
keyImportBodyInput.text("");
|
||||
keyImportForm.trigger("reset");
|
||||
ready(_ => {
|
||||
keyImportModal.addEventListener("hidden.bs.modal", _ => {
|
||||
keyImportBodyInput.textContent = "";
|
||||
keyImportForm.reset();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@ -34,53 +34,57 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const loginModal = $("#login-modal");
|
||||
const loginForm = $("#login-form");
|
||||
const loginModal = document.getElementById("login-modal");
|
||||
const loginForm = document.getElementById("login-form");
|
||||
|
||||
const loginPasswordInput = $("#login-password");
|
||||
const loginUsernameInput = $("#login-username");
|
||||
const showHidePasswordButton = $("#login-show-hide-password-button");
|
||||
const loginPasswordInput = document.getElementById("login-password");
|
||||
const loginUsernameInput = document.getElementById("login-username");
|
||||
const showHidePasswordButton = document.getElementById("login-show-hide-password-button");
|
||||
|
||||
function login() {
|
||||
const password = loginPasswordInput.val();
|
||||
const username = loginUsernameInput.val();
|
||||
const password = loginPasswordInput.value;
|
||||
const username = loginUsernameInput.value;
|
||||
|
||||
if (username && password) {
|
||||
$.ajax({
|
||||
url: "/api/v1/login",
|
||||
data: JSON.stringify({username: username, password: password}),
|
||||
type: "POST",
|
||||
contentType: "application/json",
|
||||
success: _ => {
|
||||
loginModal.modal("hide");
|
||||
makeRequest(
|
||||
"/api/v1/login",
|
||||
{
|
||||
method: "POST",
|
||||
json: {
|
||||
username: username,
|
||||
password: password,
|
||||
},
|
||||
},
|
||||
_ => {
|
||||
bootstrap.Modal.getOrCreateInstance(loginModal).hide();
|
||||
showSuccess("Logged in", `Successfully logged in as ${username}`, _ => location.href = "/");
|
||||
},
|
||||
error: (jqXHR, _, errorThrown) => {
|
||||
error => {
|
||||
const message = _ =>
|
||||
username === "admin" && password === "admin"
|
||||
? "You've entered a password for user \"root\", did you make a typo in username?"
|
||||
: `Could not login as ${username}`;
|
||||
showFailure("Login error", message, jqXHR, errorThrown);
|
||||
showFailure("Login error", message, error);
|
||||
},
|
||||
});
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function showPassword() {
|
||||
if (loginPasswordInput.attr("type") === "password") {
|
||||
loginPasswordInput.attr("type", "text");
|
||||
showHidePasswordButton.removeClass("bi-eye");
|
||||
showHidePasswordButton.addClass("bi-eye-slash");
|
||||
if (loginPasswordInput.getAttribute("type") === "password") {
|
||||
loginPasswordInput.setAttribute("type", "text");
|
||||
showHidePasswordButton.classList.remove("bi-eye");
|
||||
showHidePasswordButton.classList.add("bi-eye-slash");
|
||||
} else {
|
||||
loginPasswordInput.attr("type", "password");
|
||||
showHidePasswordButton.removeClass("bi-eye-slash");
|
||||
showHidePasswordButton.addClass("bi-eye");
|
||||
loginPasswordInput.setAttribute("type", "password");
|
||||
showHidePasswordButton.classList.remove("bi-eye-slash");
|
||||
showHidePasswordButton.classList.add("bi-eye");
|
||||
}
|
||||
}
|
||||
|
||||
$(_ => {
|
||||
loginModal.on("hidden.bs.modal", _ => {
|
||||
loginForm.trigger("reset");
|
||||
ready(_ => {
|
||||
loginModal.addEventListener("hidden.bs.modal", _ => {
|
||||
loginForm.reset();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@ -41,14 +41,14 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const packageAddModal = $("#package-add-modal");
|
||||
const packageAddForm = $("#package-add-form");
|
||||
const packageAddModal = document.getElementById("package-add-modal");
|
||||
const packageAddForm = document.getElementById("package-add-form");
|
||||
|
||||
const packageAddInput = $("#package-add-input");
|
||||
const packageAddRepositoryInput = $("#package-add-repository-input");
|
||||
const packageAddKnownPackagesList = $("#package-add-known-packages-dlist");
|
||||
const packageAddInput = document.getElementById("package-add-input");
|
||||
const packageAddRepositoryInput = document.getElementById("package-add-repository-input");
|
||||
const packageAddKnownPackagesList = document.getElementById("package-add-known-packages-dlist");
|
||||
|
||||
const packageAddVariablesDiv = $("#package-add-variables-div");
|
||||
const packageAddVariablesDiv = document.getElementById("package-add-variables-div");
|
||||
|
||||
function packageAddVariableInputCreate() {
|
||||
const variableInput = document.createElement("div");
|
||||
@ -78,7 +78,7 @@
|
||||
variableButtonRemove.classList.add("btn");
|
||||
variableButtonRemove.classList.add("btn-outline-danger");
|
||||
variableButtonRemove.innerHTML = "<i class=\"bi bi-trash\"></i>";
|
||||
variableButtonRemove.onclick = _ => { return variableInput.remove(); };
|
||||
variableButtonRemove.onclick = _ => { variableInput.remove(); };
|
||||
|
||||
// bring them together
|
||||
variableInput.appendChild(variableNameInput);
|
||||
@ -86,27 +86,26 @@
|
||||
variableInput.appendChild(variableValueInput);
|
||||
variableInput.appendChild(variableButtonRemove);
|
||||
|
||||
packageAddVariablesDiv.append(variableInput);
|
||||
packageAddVariablesDiv.appendChild(variableInput);
|
||||
}
|
||||
|
||||
function patchesParse() {
|
||||
const patches = packageAddVariablesDiv.find(".package-add-variable").map((_, element) => {
|
||||
const richElement = $(element);
|
||||
const patches = Array.from(packageAddVariablesDiv.getElementsByClassName("package-add-variable")).map(element => {
|
||||
return {
|
||||
key: richElement.find(".package-add-variable-name").val(),
|
||||
value: richElement.find(".package-add-variable-value").val(),
|
||||
key: element.querySelector(".package-add-variable-name").value,
|
||||
value: element.querySelector(".package-add-variable-value").value,
|
||||
};
|
||||
}).filter((_, patch) => patch.key).get();
|
||||
}).filter(patch => patch.key);
|
||||
return {patches: patches};
|
||||
}
|
||||
|
||||
function packagesAdd(packages, patches, repository) {
|
||||
packages = packages ?? packageAddInput.val();
|
||||
packages = packages ?? packageAddInput.value;
|
||||
patches = patches ?? patchesParse();
|
||||
repository = repository ?? getRepositorySelector(packageAddRepositoryInput);
|
||||
|
||||
if (packages) {
|
||||
packageAddModal.modal("hide");
|
||||
bootstrap.Modal.getOrCreateInstance(packageAddModal).hide();
|
||||
const onSuccess = update => `Packages ${update} have been added`;
|
||||
const onFailure = error => `Package addition failed: ${error}`;
|
||||
doPackageAction("/api/v1/service/add", [packages], repository, onSuccess, onFailure, patches);
|
||||
@ -114,50 +113,54 @@
|
||||
}
|
||||
|
||||
function packagesRequest(packages, patches) {
|
||||
packages = packages ?? packageAddInput.val();
|
||||
packages = packages ?? packageAddInput.value;
|
||||
patches = patches ?? patchesParse();
|
||||
const repository = getRepositorySelector(packageAddRepositoryInput);
|
||||
|
||||
if (packages) {
|
||||
packageAddModal.modal("hide");
|
||||
bootstrap.Modal.getOrCreateInstance(packageAddModal).hide();
|
||||
const onSuccess = update => `Packages ${update} have been requested`;
|
||||
const onFailure = error => `Package request failed: ${error}`;
|
||||
doPackageAction("/api/v1/service/request", [packages], repository, onSuccess, onFailure, patches);
|
||||
}
|
||||
}
|
||||
|
||||
$(_ => {
|
||||
packageAddModal.on("shown.bs.modal", _ => {
|
||||
$(`#package-add-repository-input option[value="${repository.architecture}-${repository.repository}"]`).prop("selected", true);
|
||||
ready(_ => {
|
||||
packageAddModal.addEventListener("shown.bs.modal", _ => {
|
||||
const option = packageAddRepositoryInput.querySelector(`option[value="${repository.architecture}-${repository.repository}"]`);
|
||||
option.selected = "selected";
|
||||
});
|
||||
packageAddModal.on("hidden.bs.modal", _ => {
|
||||
packageAddVariablesDiv.empty();
|
||||
packageAddForm.trigger("reset");
|
||||
packageAddModal.addEventListener("hidden.bs.modal", _ => {
|
||||
packageAddVariablesDiv.replaceChildren();
|
||||
packageAddForm.reset();
|
||||
});
|
||||
|
||||
packageAddInput.keyup(_ => {
|
||||
clearTimeout(packageAddInput.data("timeout"));
|
||||
packageAddInput.data("timeout", setTimeout($.proxy(_ => {
|
||||
const value = packageAddInput.val();
|
||||
packageAddInput.addEventListener("keyup", _ => {
|
||||
clearTimeout(packageAddInput.requestTimeout);
|
||||
packageAddInput.requestTimeout = setTimeout(_ => {
|
||||
const value = packageAddInput.value;
|
||||
|
||||
if (value.length >= 3) {
|
||||
$.ajax({
|
||||
url: "/api/v1/service/search",
|
||||
data: {"for": value},
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
success: response => {
|
||||
const options = response.map(pkg => {
|
||||
makeRequest(
|
||||
"/api/v1/service/search",
|
||||
{
|
||||
query: {
|
||||
for: value,
|
||||
},
|
||||
convert: response => response.json(),
|
||||
},
|
||||
data => {
|
||||
const options = data.map(pkg => {
|
||||
const option = document.createElement("option");
|
||||
option.value = pkg.package;
|
||||
option.innerText = `${pkg.package} (${pkg.description})`;
|
||||
return option;
|
||||
});
|
||||
packageAddKnownPackagesList.empty().append(options);
|
||||
packageAddKnownPackagesList.replaceChildren(...options);
|
||||
},
|
||||
});
|
||||
);
|
||||
}
|
||||
}, this), 500));
|
||||
}, 500);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@ -45,8 +45,9 @@
|
||||
|
||||
<nav>
|
||||
<div class="nav nav-tabs" role="tablist">
|
||||
<button id="package-info-logs-button" class="nav-link active" data-bs-toggle="tab" data-bs-target="#package-info-logs" type="button" role="tab" aria-controls="package-info-logs" aria-selected="true"><h3>Build logs</h3></button>
|
||||
<button id="package-info-changes-button" class="nav-link" data-bs-toggle="tab" data-bs-target="#package-info-changes" type="button" role="tab" aria-controls="package-info-changes" aria-selected="false"><h3>Changes</h3></button>
|
||||
<button id="package-info-logs-button" class="nav-link active" data-bs-toggle="tab" data-bs-target="#package-info-logs" type="button" role="tab" aria-controls="package-info-logs" aria-selected="true">Build logs</button>
|
||||
<button id="package-info-changes-button" class="nav-link" data-bs-toggle="tab" data-bs-target="#package-info-changes" type="button" role="tab" aria-controls="package-info-changes" aria-selected="false">Changes</button>
|
||||
<button id="package-info-events-button" class="nav-link" data-bs-toggle="tab" data-bs-target="#package-info-events" type="button" role="tab" aria-controls="package-info-events" aria-selected="false">Events</button>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="tab-content" id="nav-tabContent">
|
||||
@ -56,11 +57,30 @@
|
||||
<div id="package-info-changes" class="tab-pane fade" role="tabpanel" aria-labelledby="package-info-changes-button" tabindex="0">
|
||||
<pre class="language-diff"><code id="package-info-changes-input" class="pre-scrollable language-diff"></code><button id="package-info-changes-copy-button" type="button" class="btn language-diff" onclick="copyChanges()"><i class="bi bi-clipboard"></i> copy</button></pre>
|
||||
</div>
|
||||
<div id="package-info-events" class="tab-pane fade" role="tabpanel" aria-labelledby="package-info-events-button" tabindex="0">
|
||||
<canvas id="package-info-events-update-chart" hidden></canvas>
|
||||
<table id="package-info-events-table"
|
||||
data-classes="table table-hover"
|
||||
data-sortable="true"
|
||||
data-sort-name="timestamp"
|
||||
data-sort-order="desc"
|
||||
data-toggle="table">
|
||||
<thead class="table-primary">
|
||||
<tr>
|
||||
<th data-align="right" data-field="timestamp">date</th>
|
||||
<th data-field="event">event</th>
|
||||
<th data-field="message">description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="package-info-update-button" type="submit" class="btn btn-success" onclick="packageInfoUpdate()" data-bs-dismiss="modal" hidden><i class="bi bi-play"></i><span class="d-none d-sm-inline"> update</span></button>
|
||||
<button id="package-info-remove-button" type="submit" class="btn btn-danger" onclick="packageInfoRemove()" data-bs-dismiss="modal" hidden><i class="bi bi-trash"></i><span class="d-none d-sm-inline"> remove</span></button>
|
||||
{% if not auth.enabled or auth.username is not none %}
|
||||
<button id="package-info-update-button" type="submit" class="btn btn-success" onclick="packageInfoUpdate()" data-bs-dismiss="modal"><i class="bi bi-play"></i><span class="d-none d-sm-inline"> update</span></button>
|
||||
<button id="package-info-remove-button" type="submit" class="btn btn-danger" onclick="packageInfoRemove()" data-bs-dismiss="modal"><i class="bi bi-trash"></i><span class="d-none d-sm-inline"> remove</span></button>
|
||||
{% endif %}
|
||||
<button type="button" class="btn btn-secondary" onclick="showPackageInfo()"><i class="bi bi-arrow-clockwise"></i><span class="d-none d-sm-inline"> reload</span></button>
|
||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal"><i class="bi bi-x"></i><span class="d-none d-sm-inline"> close</span></button>
|
||||
</div>
|
||||
@ -69,41 +89,54 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const packageInfoModal = $("#package-info-modal");
|
||||
const packageInfoModalHeader = $("#package-info-modal-header");
|
||||
const packageInfo = $("#package-info");
|
||||
const packageInfoModal = document.getElementById("package-info-modal");
|
||||
const packageInfoModalHeader = document.getElementById("package-info-modal-header");
|
||||
const packageInfo = document.getElementById("package-info");
|
||||
|
||||
const packageInfoLogsInput = $("#package-info-logs-input");
|
||||
const packageInfoLogsCopyButton = $("#package-info-logs-copy-button");
|
||||
const packageInfoLogsInput = document.getElementById("package-info-logs-input");
|
||||
const packageInfoLogsCopyButton = document.getElementById("package-info-logs-copy-button");
|
||||
|
||||
const packageInfoChangesInput = $("#package-info-changes-input");
|
||||
const packageInfoChangesCopyButton = $("#package-info-changes-copy-button");
|
||||
const packageInfoChangesInput = document.getElementById("package-info-changes-input");
|
||||
const packageInfoChangesCopyButton = document.getElementById("package-info-changes-copy-button");
|
||||
|
||||
const packageInfoAurUrl = $("#package-info-aur-url");
|
||||
const packageInfoDepends = $("#package-info-depends");
|
||||
const packageInfoGroups = $("#package-info-groups");
|
||||
const packageInfoLicenses = $("#package-info-licenses");
|
||||
const packageInfoPackager = $("#package-info-packager");
|
||||
const packageInfoPackages = $("#package-info-packages");
|
||||
const packageInfoUpstreamUrl = $("#package-info-upstream-url");
|
||||
const packageInfoVersion = $("#package-info-version");
|
||||
// so far bootstrap-table only operates with jquery elements
|
||||
const packageInfoEventsTable = $(document.getElementById("package-info-events-table"));
|
||||
const packageInfoEventsUpdateChartCanvas = document.getElementById("package-info-events-update-chart");
|
||||
let packageInfoEventsUpdateChart = null;
|
||||
|
||||
const packageInfoVariablesBlock = $("#package-info-variables-block");
|
||||
const packageInfoVariablesDiv = $("#package-info-variables-div");
|
||||
const packageInfoAurUrl = document.getElementById("package-info-aur-url");
|
||||
const packageInfoDepends = document.getElementById("package-info-depends");
|
||||
const packageInfoGroups = document.getElementById("package-info-groups");
|
||||
const packageInfoLicenses = document.getElementById("package-info-licenses");
|
||||
const packageInfoPackager = document.getElementById("package-info-packager");
|
||||
const packageInfoPackages = document.getElementById("package-info-packages");
|
||||
const packageInfoUpstreamUrl = document.getElementById("package-info-upstream-url");
|
||||
const packageInfoVersion = document.getElementById("package-info-version");
|
||||
|
||||
const packageInfoVariablesBlock = document.getElementById("package-info-variables-block");
|
||||
const packageInfoVariablesDiv = document.getElementById("package-info-variables-div");
|
||||
|
||||
function clearChart() {
|
||||
packageInfoEventsUpdateChartCanvas.hidden = true;
|
||||
if (packageInfoEventsUpdateChart) {
|
||||
packageInfoEventsUpdateChart.data = {};
|
||||
packageInfoEventsUpdateChart.update();
|
||||
}
|
||||
}
|
||||
|
||||
async function copyChanges() {
|
||||
const changes = packageInfoChangesInput.text();
|
||||
const changes = packageInfoChangesInput.textContent;
|
||||
await copyToClipboard(changes, packageInfoChangesCopyButton);
|
||||
}
|
||||
|
||||
async function copyLogs() {
|
||||
const logs = packageInfoLogsInput.text();
|
||||
const logs = packageInfoLogsInput.textContent;
|
||||
await copyToClipboard(logs, packageInfoLogsCopyButton);
|
||||
}
|
||||
|
||||
function hideInfoControls(hidden) {
|
||||
packageInfoRemoveButton.attr("hidden", hidden);
|
||||
packageInfoUpdateButton.attr("hidden", hidden);
|
||||
function highlight(element) {
|
||||
delete element.dataset.highlighted;
|
||||
hljs.highlightElement(element);
|
||||
}
|
||||
|
||||
function insertVariable(packageBase, variable) {
|
||||
@ -130,12 +163,13 @@
|
||||
variableButtonRemove.classList.add("btn-outline-danger");
|
||||
variableButtonRemove.innerHTML = "<i class=\"bi bi-trash\"></i>";
|
||||
variableButtonRemove.onclick = _ => {
|
||||
$.ajax({
|
||||
url: `/api/v1/packages/${packageBase}/patches/${variable.key}`,
|
||||
type: "DELETE",
|
||||
dataType: "json",
|
||||
success: _ => variableInput.remove(),
|
||||
});
|
||||
makeRequest(
|
||||
`/api/v1/packages/${packageBase}/patches/${variable.key}`,
|
||||
{
|
||||
method: "DELETE",
|
||||
},
|
||||
_ => variableInput.remove(),
|
||||
);
|
||||
};
|
||||
|
||||
// bring them together
|
||||
@ -144,45 +178,93 @@
|
||||
variableInput.appendChild(variableValueInput);
|
||||
variableInput.appendChild(variableButtonRemove);
|
||||
|
||||
packageInfoVariablesDiv.append(variableInput);
|
||||
packageInfoVariablesDiv.appendChild(variableInput);
|
||||
}
|
||||
|
||||
function loadChanges(packageBase, onFailure) {
|
||||
$.ajax({
|
||||
url: `/api/v1/packages/${packageBase}/changes`,
|
||||
data: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
makeRequest(
|
||||
`/api/v1/packages/${packageBase}/changes`,
|
||||
{
|
||||
query: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
},
|
||||
convert: response => response.json(),
|
||||
},
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
success: response => {
|
||||
const changes = response.changes;
|
||||
packageInfoChangesInput.text(changes || "");
|
||||
packageInfoChangesInput.map((_, el) => hljs.highlightElement(el));
|
||||
data => {
|
||||
const changes = data.changes;
|
||||
packageInfoChangesInput.textContent = changes ?? "";
|
||||
highlight(packageInfoChangesInput);
|
||||
},
|
||||
error: onFailure,
|
||||
});
|
||||
onFailure,
|
||||
);
|
||||
}
|
||||
|
||||
function loadEvents(packageBase, onFailure) {
|
||||
packageInfoEventsTable.bootstrapTable("showLoading");
|
||||
clearChart();
|
||||
|
||||
makeRequest(
|
||||
"/api/v1/events",
|
||||
{
|
||||
query: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
object_id: packageBase,
|
||||
limit: 30,
|
||||
},
|
||||
convert: response => response.json(),
|
||||
},
|
||||
data => {
|
||||
const events = data.map(event => {
|
||||
return {
|
||||
timestamp: new Date(1000 * event.created).toISOStringShort(),
|
||||
event: event.event,
|
||||
message: event.message || "",
|
||||
};
|
||||
});
|
||||
const chart = data.filter(event => event.event === "package-updated");
|
||||
|
||||
packageInfoEventsTable.bootstrapTable("load", events);
|
||||
packageInfoEventsTable.bootstrapTable("hideLoading");
|
||||
|
||||
if (packageInfoEventsUpdateChart) {
|
||||
packageInfoEventsUpdateChart.config.data = {
|
||||
labels: chart.map(event => new Date(1000 * event.created).toISOStringShort()),
|
||||
datasets: [{
|
||||
label: "update duration, s",
|
||||
data: chart.map(event => event.data.took),
|
||||
cubicInterpolationMode: "monotone",
|
||||
tension: 0.4,
|
||||
}],
|
||||
};
|
||||
packageInfoEventsUpdateChart.update();
|
||||
}
|
||||
packageInfoEventsUpdateChartCanvas.hidden = !chart.length;
|
||||
},
|
||||
onFailure,
|
||||
);
|
||||
}
|
||||
|
||||
function loadLogs(packageBase, onFailure) {
|
||||
$.ajax({
|
||||
url: `/api/v2/packages/${packageBase}/logs`,
|
||||
data: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
makeRequest(
|
||||
`/api/v2/packages/${packageBase}/logs`,
|
||||
{
|
||||
query: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
},
|
||||
convert: response => response.json(),
|
||||
},
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
success: response => {
|
||||
const logs = response.map(log_record => {
|
||||
data => {
|
||||
const logs = data.map(log_record => {
|
||||
return `[${new Date(1000 * log_record.created).toISOString()}] ${log_record.message}`;
|
||||
});
|
||||
packageInfoLogsInput.text(logs.join("\n"));
|
||||
packageInfoLogsInput.map((_, el) => hljs.highlightElement(el));
|
||||
packageInfoLogsInput.textContent = logs.join("\n");
|
||||
highlight(packageInfoLogsInput);
|
||||
},
|
||||
error: onFailure,
|
||||
});
|
||||
onFailure,
|
||||
);
|
||||
}
|
||||
|
||||
function loadPackage(packageBase, onFailure) {
|
||||
@ -194,16 +276,17 @@
|
||||
return ["bg-secondary", "text-white"];
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url: `/api/v1/packages/${packageBase}`,
|
||||
data: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
makeRequest(
|
||||
`/api/v1/packages/${packageBase}`,
|
||||
{
|
||||
query: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
},
|
||||
convert: response => response.json(),
|
||||
},
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
success: response => {
|
||||
const description = response.find(Boolean);
|
||||
data => {
|
||||
const description = data.find(Boolean);
|
||||
const packages = Object.keys(description.package.packages);
|
||||
const aurUrl = description.package.remote.web_url;
|
||||
const upstreamUrls = Array.from(
|
||||
@ -213,103 +296,111 @@
|
||||
)
|
||||
).sort();
|
||||
|
||||
packageInfo.text(`${description.package.base} ${description.status.status} at ${new Date(1000 * description.status.timestamp).toISOStringShort()}`);
|
||||
packageInfo.textContent = `${description.package.base} ${description.status.status} at ${new Date(1000 * description.status.timestamp).toISOStringShort()}`;
|
||||
|
||||
packageInfoModalHeader.removeClass();
|
||||
packageInfoModalHeader.addClass("modal-header");
|
||||
headerClass(description.status.status).forEach(clz => packageInfoModalHeader.addClass(clz));
|
||||
packageInfoModalHeader.classList.remove(...packageInfoModalHeader.classList);
|
||||
packageInfoModalHeader.classList.add("modal-header");
|
||||
headerClass(description.status.status).forEach(clz => packageInfoModalHeader.classList.add(clz));
|
||||
|
||||
packageInfoAurUrl.html(aurUrl ? safeLink(aurUrl, aurUrl, "AUR link").outerHTML : "");
|
||||
packageInfoDepends.html(listToTable(
|
||||
packageInfoAurUrl.innerHTML = aurUrl ? safeLink(aurUrl, aurUrl, "AUR link").outerHTML : "";
|
||||
packageInfoDepends.innerHTML = listToTable(
|
||||
Object.values(description.package.packages)
|
||||
.reduce((accumulator, currentValue) => {
|
||||
return accumulator.concat(currentValue.depends.filter(v => packages.indexOf(v) === -1))
|
||||
.concat(currentValue.make_depends.filter(v => packages.indexOf(v) === -1).map(v => `${v} (make)`))
|
||||
.concat(currentValue.opt_depends.filter(v => packages.indexOf(v) === -1).map(v => `${v} (optional)`));
|
||||
}, [])
|
||||
));
|
||||
packageInfoGroups.html(listToTable(extractListProperties(description.package, "groups")));
|
||||
packageInfoLicenses.html(listToTable(extractListProperties(description.package, "licenses")));
|
||||
packageInfoPackager.text(description.package.packager);
|
||||
packageInfoPackages.html(listToTable(packages));
|
||||
packageInfoUpstreamUrl.html(upstreamUrls.map(url => safeLink(url, url, "upstream link").outerHTML).join("<br>"));
|
||||
packageInfoVersion.text(description.package.version);
|
||||
|
||||
hideInfoControls(false);
|
||||
);
|
||||
packageInfoGroups.innerHTML = listToTable(extractListProperties(description.package, "groups"));
|
||||
packageInfoLicenses.innerHTML = listToTable(extractListProperties(description.package, "licenses"));
|
||||
packageInfoPackager.textContent = description.package.packager;
|
||||
packageInfoPackages.innerHTML = listToTable(packages);
|
||||
packageInfoUpstreamUrl.innerHTML = upstreamUrls.map(url => safeLink(url, url, "upstream link").outerHTML).join("<br>");
|
||||
packageInfoVersion.textContent = description.package.version;
|
||||
},
|
||||
error: (jqXHR, _, errorThrown) => {
|
||||
hideInfoControls(true);
|
||||
onFailure(jqXHR, null, errorThrown);
|
||||
},
|
||||
});
|
||||
onFailure,
|
||||
);
|
||||
}
|
||||
|
||||
function loadPatches(packageBase, onFailure) {
|
||||
$.ajax({
|
||||
url: `/api/v1/packages/${packageBase}/patches`,
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
success: response => {
|
||||
packageInfoVariablesDiv.empty();
|
||||
response.map(patch => insertVariable(packageBase, patch));
|
||||
packageInfoVariablesBlock.attr("hidden", response.length === 0);
|
||||
makeRequest(
|
||||
`/api/v1/packages/${packageBase}/patches`,
|
||||
{
|
||||
convert: response => response.json(),
|
||||
},
|
||||
error: onFailure,
|
||||
});
|
||||
data => {
|
||||
packageInfoVariablesDiv.replaceChildren();
|
||||
data.map(patch => insertVariable(packageBase, patch));
|
||||
packageInfoVariablesBlock.hidden = !data.length;
|
||||
},
|
||||
onFailure,
|
||||
);
|
||||
}
|
||||
|
||||
function packageInfoRemove() {
|
||||
const packageBase = packageInfoModal.data("package");
|
||||
if (packageBase) return packagesRemove([packageBase]);
|
||||
const packageBase = packageInfoModal.package;
|
||||
packagesRemove([packageBase]);
|
||||
}
|
||||
|
||||
function packageInfoUpdate() {
|
||||
const packageBase = packageInfoModal.data("package");
|
||||
if (packageBase) return packagesAdd(packageBase, [], repository);
|
||||
const packageBase = packageInfoModal.package;
|
||||
packagesAdd(packageBase, [], repository);
|
||||
}
|
||||
|
||||
function showPackageInfo(packageBase) {
|
||||
const isPackageBaseSet = packageBase !== undefined;
|
||||
if (isPackageBaseSet)
|
||||
packageInfoModal.data("package", packageBase); // set package base as currently used
|
||||
else
|
||||
packageBase = packageInfoModal.data("package"); // read package base from the current window attribute
|
||||
if (isPackageBaseSet) {
|
||||
// set package base as currently used
|
||||
packageInfoModal.package = packageBase;
|
||||
} else {
|
||||
// read package base from the current window attribute
|
||||
packageBase = packageInfoModal.package;
|
||||
}
|
||||
|
||||
const onFailure = (jqXHR, _, errorThrown) => {
|
||||
const onFailure = error => {
|
||||
if (isPackageBaseSet) {
|
||||
const message = error => `Could not load package ${packageBase} info: ${error}`;
|
||||
showFailure("Load failure", message, jqXHR, errorThrown);
|
||||
const message = details => `Could not load package ${packageBase} info: ${details}`;
|
||||
showFailure("Load failure", message, error);
|
||||
}
|
||||
};
|
||||
|
||||
loadPackage(packageBase, onFailure);
|
||||
loadPatches(packageBase, onFailure);
|
||||
loadLogs(packageBase, onFailure);
|
||||
loadChanges(packageBase, onFailure)
|
||||
loadChanges(packageBase, onFailure);
|
||||
loadEvents(packageBase, onFailure);
|
||||
|
||||
if (isPackageBaseSet) packageInfoModal.modal("show");
|
||||
if (isPackageBaseSet) {
|
||||
bootstrap.Modal.getOrCreateInstance(packageInfoModal).show();
|
||||
}
|
||||
}
|
||||
|
||||
$(_ => {
|
||||
packageInfoModal.on("hidden.bs.modal", _ => {
|
||||
packageInfoAurUrl.empty();
|
||||
packageInfoDepends.empty();
|
||||
packageInfoGroups.empty();
|
||||
packageInfoLicenses.empty();
|
||||
packageInfoPackager.empty();
|
||||
packageInfoPackages.empty();
|
||||
packageInfoUpstreamUrl.empty();
|
||||
packageInfoVersion.empty();
|
||||
ready(_ => {
|
||||
packageInfoEventsUpdateChart = new Chart(packageInfoEventsUpdateChartCanvas, {
|
||||
type: "line",
|
||||
data: {},
|
||||
options: {
|
||||
responsive: true,
|
||||
},
|
||||
});
|
||||
|
||||
packageInfoVariablesBlock.attr("hidden", true);
|
||||
packageInfoVariablesDiv.empty();
|
||||
packageInfoModal.addEventListener("hidden.bs.modal", _ => {
|
||||
packageInfoAurUrl.textContent = "";
|
||||
packageInfoDepends.textContent = "";
|
||||
packageInfoGroups.textContent = "";
|
||||
packageInfoLicenses.textContent = "";
|
||||
packageInfoPackager.textContent = "";
|
||||
packageInfoPackages.textContent = "";
|
||||
packageInfoUpstreamUrl.textContent = "";
|
||||
packageInfoVersion.textContent = "";
|
||||
|
||||
packageInfoLogsInput.empty();
|
||||
packageInfoChangesInput.empty();
|
||||
packageInfoVariablesBlock.hidden = true;
|
||||
packageInfoVariablesDiv.replaceChildren();
|
||||
|
||||
packageInfoModal.trigger("reset");
|
||||
|
||||
hideInfoControls(true);
|
||||
packageInfoLogsInput.textContent = "";
|
||||
packageInfoChangesInput.textContent = "";
|
||||
packageInfoEventsTable.bootstrapTable("load", []);
|
||||
clearChart();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@ -33,28 +33,31 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const packageRebuildModal = $("#package-rebuild-modal");
|
||||
const packageRebuildForm = $("#package-rebuild-form");
|
||||
const packageRebuildModal = document.getElementById("package-rebuild-modal");
|
||||
const packageRebuildForm = document.getElementById("package-rebuild-form");
|
||||
|
||||
const packageRebuildDependencyInput = $("#package-rebuild-dependency-input");
|
||||
const packageRebuildRepositoryInput = $("#package-rebuild-repository-input");
|
||||
const packageRebuildDependencyInput = document.getElementById("package-rebuild-dependency-input");
|
||||
const packageRebuildRepositoryInput = document.getElementById("package-rebuild-repository-input");
|
||||
|
||||
function packagesRebuild() {
|
||||
const packages = packageRebuildDependencyInput.val();
|
||||
const packages = packageRebuildDependencyInput.value;
|
||||
const repository = getRepositorySelector(packageRebuildRepositoryInput);
|
||||
if (packages) {
|
||||
packageRebuildModal.modal("hide");
|
||||
bootstrap.Modal.getOrCreateInstance(packageRebuildModal).hide();
|
||||
const onSuccess = update => `Repository rebuild has been run for packages which depend on ${update}`;
|
||||
const onFailure = error => `Repository rebuild failed: ${error}`;
|
||||
doPackageAction("/api/v1/service/rebuild", [packages], repository, onSuccess, onFailure);
|
||||
}
|
||||
}
|
||||
|
||||
$(_ => {
|
||||
packageRebuildModal.on("shown.bs.modal", _ => {
|
||||
$(`#package-rebuild-repository-input option[value="${repository.architecture}-${repository.repository}"]`).prop("selected", true);
|
||||
ready(_ => {
|
||||
packageRebuildModal.addEventListener("shown.bs.modal", _ => {
|
||||
const option = packageRebuildRepositoryInput.querySelector(`option[value="${repository.architecture}-${repository.repository}"]`);
|
||||
option.selected = "selected";
|
||||
|
||||
});
|
||||
packageRebuildModal.on("hidden.bs.modal", _ => { packageRebuildForm.trigger("reset"); });
|
||||
packageRebuildModal.addEventListener("hidden.bs.modal", _ => {
|
||||
packageRebuildForm.reset();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@ -1,39 +1,34 @@
|
||||
<script>
|
||||
const keyImportButton = $("#key-import-button");
|
||||
const packageAddButton = $("#package-add-button");
|
||||
const packageRebuildButton = $("#package-rebuild-button");
|
||||
const packageRemoveButton = $("#package-remove-button");
|
||||
const packageUpdateButton = $("#package-update-button");
|
||||
|
||||
const packageInfoRemoveButton = $("#package-info-remove-button");
|
||||
const packageInfoUpdateButton = $("#package-info-update-button");
|
||||
const packageRemoveButton = document.getElementById("package-remove-button");
|
||||
const packageUpdateButton = document.getElementById("package-update-button");
|
||||
|
||||
let repository = null;
|
||||
|
||||
const table = $("#packages");
|
||||
// so far bootstrap-table only operates with jquery elements
|
||||
const table = $(document.getElementById("packages"));
|
||||
|
||||
const statusBadge = $("#badge-status");
|
||||
const versionBadge = $("#badge-version");
|
||||
const statusBadge = document.getElementById("badge-status");
|
||||
const versionBadge = document.getElementById("badge-version");
|
||||
|
||||
function doPackageAction(uri, packages, repository, successText, failureText, data) {
|
||||
const queryParams = $.param({
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
}); // it will never be empty btw
|
||||
|
||||
$.ajax({
|
||||
url: `${uri}?${queryParams}`,
|
||||
data: JSON.stringify(Object.assign({}, {packages: packages}, data || {})),
|
||||
type: "POST",
|
||||
contentType: "application/json",
|
||||
success: _ => {
|
||||
makeRequest(
|
||||
uri,
|
||||
{
|
||||
method: "POST",
|
||||
query: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
},
|
||||
json: Object.assign({}, {packages: packages}, data || {}),
|
||||
},
|
||||
_ => {
|
||||
const message = successText(packages.join(", "));
|
||||
showSuccess("Success", message);
|
||||
},
|
||||
error: (jqXHR, _, errorThrown) => {
|
||||
showFailure("Action failed", failureText, jqXHR, errorThrown);
|
||||
error => {
|
||||
showFailure("Action failed", failureText, error);
|
||||
},
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
function filterListGroups() {
|
||||
@ -49,10 +44,10 @@
|
||||
}
|
||||
|
||||
function getRepositorySelector(selector) {
|
||||
const selected = selector.find(":selected");
|
||||
const selected = selector.options[selector.selectedIndex];
|
||||
return {
|
||||
architecture: selected.data("architecture"),
|
||||
repository: selected.data("repository"),
|
||||
architecture: selected.getAttribute("data-architecture"),
|
||||
repository: selected.getAttribute("data-repository"),
|
||||
};
|
||||
}
|
||||
|
||||
@ -60,14 +55,6 @@
|
||||
return table.bootstrapTable("getSelections").map(row => row.id);
|
||||
}
|
||||
|
||||
function hideControls(hidden) {
|
||||
keyImportButton.attr("hidden", hidden);
|
||||
packageAddButton.attr("hidden", hidden);
|
||||
packageRebuildButton.attr("hidden", hidden);
|
||||
packageRemoveButton.attr("hidden", hidden);
|
||||
packageUpdateButton.attr("hidden", hidden);
|
||||
}
|
||||
|
||||
function packagesRemove(packages) {
|
||||
packages = packages ?? getSelection();
|
||||
const onSuccess = update => `Packages ${update} have been removed`;
|
||||
@ -97,16 +84,17 @@
|
||||
return "btn-outline-secondary";
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url: "/api/v1/packages",
|
||||
data: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
makeRequest(
|
||||
"/api/v1/packages",
|
||||
{
|
||||
query: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
},
|
||||
convert: response => response.json(),
|
||||
},
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
success: response => {
|
||||
const payload = response.map(description => {
|
||||
data => {
|
||||
const payload = data.map(description => {
|
||||
const package_base = description.package.base;
|
||||
const web_url = description.package.remote.web_url;
|
||||
return {
|
||||
@ -125,10 +113,9 @@
|
||||
table.bootstrapTable("load", payload);
|
||||
table.bootstrapTable("uncheckAll");
|
||||
table.bootstrapTable("hideLoading");
|
||||
hideControls(false);
|
||||
},
|
||||
error: (jqXHR, _, errorThrown) => {
|
||||
if ((jqXHR.status === 401) || (jqXHR.status === 403)) {
|
||||
error => {
|
||||
if ((error.status === 401) || (error.status === 403)) {
|
||||
// authorization error
|
||||
const text = "In order to see statuses you must login first.";
|
||||
table.find("tr.unauthorized").remove();
|
||||
@ -136,39 +123,39 @@
|
||||
table.bootstrapTable("hideLoading");
|
||||
} else {
|
||||
// other errors
|
||||
const message = error => `Could not load list of packages: ${error}`;
|
||||
showFailure("Load failure", message, jqXHR, errorThrown);
|
||||
const message = details => `Could not load list of packages: ${details}`;
|
||||
showFailure("Load failure", message, error);
|
||||
}
|
||||
hideControls(true);
|
||||
},
|
||||
});
|
||||
);
|
||||
|
||||
$.ajax({
|
||||
url: "/api/v1/status",
|
||||
data: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
makeRequest(
|
||||
"/api/v1/status",
|
||||
{
|
||||
query: {
|
||||
architecture: repository.architecture,
|
||||
repository: repository.repository,
|
||||
},
|
||||
convert: response => response.json(),
|
||||
},
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
success: response => {
|
||||
versionBadge.html(`<i class="bi bi-github"></i> ahriman ${safe(response.version)}`);
|
||||
data => {
|
||||
versionBadge.innerHTML = `<i class="bi bi-github"></i> ahriman ${safe(data.version)}`;
|
||||
|
||||
statusBadge
|
||||
.popover("dispose")
|
||||
.attr("data-bs-content", `${response.status.status} at ${new Date(1000 * response.status.timestamp).toISOStringShort()}`)
|
||||
.popover();
|
||||
statusBadge.removeClass();
|
||||
statusBadge.addClass("btn");
|
||||
statusBadge.addClass(badgeClass(response.status.status));
|
||||
statusBadge.classList.remove(...statusBadge.classList);
|
||||
statusBadge.classList.add("btn");
|
||||
statusBadge.classList.add(badgeClass(data.status.status));
|
||||
|
||||
const popover = bootstrap.Popover.getOrCreateInstance(statusBadge);
|
||||
popover.dispose();
|
||||
statusBadge.dataset.bsContent = `${data.status.status} at ${new Date(1000 * data.status.timestamp).toISOStringShort()}`;
|
||||
bootstrap.Popover.getOrCreateInstance(statusBadge);
|
||||
},
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
function selectRepository() {
|
||||
const fragment = window.location.hash.replace("#", "") || "{{ repositories[0].id }}";
|
||||
const element = $(`#${fragment}-link`);
|
||||
element.click();
|
||||
document.getElementById(`${fragment}-link`).click();
|
||||
}
|
||||
|
||||
function statusFormat(value) {
|
||||
@ -182,20 +169,25 @@
|
||||
return {classes: cellClass(value)};
|
||||
}
|
||||
|
||||
$(_ => {
|
||||
$("#repositories a").on("click", event => {
|
||||
const element = event.target;
|
||||
repository = {
|
||||
architecture: element.dataset.architecture,
|
||||
repository: element.dataset.repository,
|
||||
ready(_ => {
|
||||
document.querySelectorAll("#repositories a").forEach(element => {
|
||||
element.onclick = _ => {
|
||||
repository = {
|
||||
architecture: element.dataset.architecture,
|
||||
repository: element.dataset.repository,
|
||||
};
|
||||
if (packageUpdateButton) {
|
||||
packageUpdateButton.innerHTML = `<i class="bi bi-play"></i> update<span class="d-none d-sm-inline"> ${safe(repository.repository)} (${safe(repository.architecture)})</span>`;
|
||||
}
|
||||
bootstrap.Tab.getOrCreateInstance(document.getElementById(element.id)).show();
|
||||
reload();
|
||||
};
|
||||
packageUpdateButton.html(`<i class="bi bi-play"></i> update<span class="d-none d-sm-inline"> ${safe(repository.repository)} (${safe(repository.architecture)})</span>`);
|
||||
$(`#${element.id}`).tab("show");
|
||||
reload();
|
||||
});
|
||||
|
||||
table.on("check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table", _ => {
|
||||
packageRemoveButton.prop("disabled", !table.bootstrapTable("getSelections").length);
|
||||
if (packageRemoveButton) {
|
||||
packageRemoveButton.disabled = !table.bootstrapTable("getSelections").length;
|
||||
}
|
||||
});
|
||||
table.on("click-row.bs.table", (self, data, row, cell) => {
|
||||
if (0 === cell || "base" === cell) {
|
||||
@ -204,26 +196,38 @@
|
||||
} else showPackageInfo(data.id);
|
||||
});
|
||||
table.on("created-controls.bs.table", _ => {
|
||||
const pickerInput = $(".bootstrap-table-filter-control-timestamp");
|
||||
pickerInput.daterangepicker({
|
||||
autoUpdateInput: false,
|
||||
new easepick.create({
|
||||
element: document.querySelector(".bootstrap-table-filter-control-timestamp"),
|
||||
css: [
|
||||
"https://cdn.jsdelivr.net/npm/@easepick/bundle@1.2.1/dist/index.css",
|
||||
],
|
||||
grid: 2,
|
||||
calendars: 2,
|
||||
autoApply: false,
|
||||
locale: {
|
||||
cancelLabel: "Clear",
|
||||
cancel: "Clear",
|
||||
},
|
||||
RangePlugin: {
|
||||
tooltip: false,
|
||||
},
|
||||
plugins: [
|
||||
"RangePlugin",
|
||||
],
|
||||
setup: picker => {
|
||||
picker.on("select", _ => { table.bootstrapTable("triggerSearch"); });
|
||||
// replace "Cancel" behaviour to "Clear"
|
||||
picker.onClickCancelButton = element => {
|
||||
if (picker.isCancelButton(element)) {
|
||||
picker.clear();
|
||||
picker.hide();
|
||||
table.bootstrapTable("triggerSearch");
|
||||
}
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
pickerInput.on("apply.daterangepicker", (event, picker) => {
|
||||
pickerInput.val(`${picker.startDate.format("YYYY-MM-DD")} - ${picker.endDate.format("YYYY-MM-DD")}`);
|
||||
table.bootstrapTable("triggerSearch");
|
||||
});
|
||||
|
||||
pickerInput.on("cancel.daterangepicker", _ => {
|
||||
pickerInput.val("");
|
||||
table.bootstrapTable("triggerSearch");
|
||||
});
|
||||
});
|
||||
|
||||
statusBadge.popover();
|
||||
bootstrap.Popover.getOrCreateInstance(statusBadge);
|
||||
selectRepository();
|
||||
});
|
||||
</script>
|
||||
|
@ -7,6 +7,10 @@
|
||||
|
||||
{% include "utils/style.jinja2" %}
|
||||
{% include "user-style.jinja2" ignore missing %}
|
||||
|
||||
{% if rss_url is not none %}
|
||||
<link rel="alternate" href="{{ rss_url }}" type="application/rss+xml">
|
||||
{% endif %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -101,13 +105,13 @@ SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Pa
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const table = $("#packages");
|
||||
const table = $(document.getElementById("packages"));
|
||||
|
||||
const pacmanConf = $("#pacman-conf");
|
||||
const pacmanConfCopyButton = $("#copy-btn");
|
||||
const pacmanConf = document.getElementById("pacman-conf");
|
||||
const pacmanConfCopyButton = document.getElementById("copy-btn");
|
||||
|
||||
async function copyPacmanConf() {
|
||||
const conf = pacmanConf.text();
|
||||
const conf = pacmanConf.textContent;
|
||||
await copyToClipboard(conf, pacmanConfCopyButton);
|
||||
}
|
||||
|
||||
@ -123,24 +127,36 @@ SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Pa
|
||||
return extractDataList(table.bootstrapTable("getData"), "licenses");
|
||||
}
|
||||
|
||||
$(_ => {
|
||||
ready(_ => {
|
||||
table.on("created-controls.bs.table", _ => {
|
||||
const pickerInput = $(".bootstrap-table-filter-control-timestamp");
|
||||
pickerInput.daterangepicker({
|
||||
autoUpdateInput: false,
|
||||
new easepick.create({
|
||||
element: document.querySelector(".bootstrap-table-filter-control-timestamp"),
|
||||
css: [
|
||||
"https://cdn.jsdelivr.net/npm/@easepick/bundle@1.2.1/dist/index.css",
|
||||
],
|
||||
grid: 2,
|
||||
calendars: 2,
|
||||
autoApply: false,
|
||||
locale: {
|
||||
cancelLabel: "Clear",
|
||||
cancel: "Clear",
|
||||
},
|
||||
RangePlugin: {
|
||||
tooltip: false,
|
||||
},
|
||||
plugins: [
|
||||
"RangePlugin",
|
||||
],
|
||||
setup: picker => {
|
||||
picker.on("select", _ => { table.bootstrapTable("triggerSearch"); });
|
||||
// replace "Cancel" behaviour to "Clear"
|
||||
picker.onClickCancelButton = element => {
|
||||
if (picker.isCancelButton(element)) {
|
||||
picker.clear();
|
||||
picker.hide();
|
||||
table.bootstrapTable("triggerSearch");
|
||||
}
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
pickerInput.on("apply.daterangepicker", (event, picker) => {
|
||||
pickerInput.val(`${picker.startDate.format("YYYY-MM-DD")} - ${picker.endDate.format("YYYY-MM-DD")}`);
|
||||
table.bootstrapTable("triggerSearch");
|
||||
});
|
||||
|
||||
pickerInput.on("cancel.daterangepicker", _ => {
|
||||
pickerInput.val("");
|
||||
table.bootstrapTable("triggerSearch");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
27
package/share/ahriman/templates/rss.jinja2
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{ repository }}: Recent package updates</title>
|
||||
{% if homepage is not none %}
|
||||
<link>{{ homepage }}</link>
|
||||
{% endif %}
|
||||
<description>Recently updated packages in the {{ repository }}.</description>
|
||||
{% if rss_url is not none %}
|
||||
<atom:link href="{{ rss_url }}" rel="self"/>
|
||||
{% endif %}
|
||||
<language>en-us</language>
|
||||
<lastBuildDate>{{ last_update }}</lastBuildDate>
|
||||
|
||||
{% for package in packages %}
|
||||
<item>
|
||||
<title>{{ package.name }} {{ package.version }} {{ package.architecture }}</title>
|
||||
<link>{{ link_path }}/{{ package.filename }}</link>
|
||||
<description>{{ package.description }}</description>
|
||||
<pubDate>{{ package.build_date }}</pubDate>
|
||||
<guid isPermaLink="false">{{ package.tag }}</guid>
|
||||
<category>{{ repository }}</category>
|
||||
<category>{{ package.architecture }}</category>
|
||||
</item>
|
||||
{% endfor %}
|
||||
</channel>
|
||||
</rss>
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 181 KiB |
@ -1,70 +1,721 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="256.000000pt" height="256.000000pt" viewBox="0 0 256.000000 256.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,256.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M1019 2546 c-51 -18 -92 -49 -136 -103 -34 -41 -83 -73 -112 -73 -6
|
||||
0 4 22 20 49 17 27 30 54 28 59 -7 17 -153 -102 -176 -143 -13 -23 -30 -40
|
||||
-40 -40 -15 0 -18 9 -18 61 0 49 6 73 33 125 l33 64 -42 -40 c-50 -49 -82 -97
|
||||
-98 -150 -31 -102 -43 -125 -77 -146 -19 -11 -48 -42 -65 -67 -17 -26 -62 -76
|
||||
-100 -112 -69 -66 -69 -66 -69 -120 0 -30 5 -62 10 -70 5 -8 10 -10 10 -4 0 7
|
||||
21 35 46 63 69 77 154 95 154 33 0 -42 -27 -126 -50 -155 l-21 -26 25 -7 c34
|
||||
-8 63 10 86 56 27 53 74 105 127 142 42 29 44 32 38 68 -6 33 -3 40 22 60 25
|
||||
20 36 22 96 17 83 -7 121 5 137 43 7 16 19 31 28 34 10 3 -9 3 -40 1 -65 -6
|
||||
-84 8 -48 37 34 27 118 24 180 -7 57 -29 115 -32 150 -8 l24 17 -24 6 c-14 3
|
||||
-27 14 -28 24 -4 17 1 18 46 13 58 -7 118 -34 147 -67 38 -44 107 -80 149 -80
|
||||
36 1 38 2 21 12 -41 23 -115 108 -115 133 0 13 58 -27 94 -64 42 -43 86 -58
|
||||
133 -46 28 7 28 7 6 18 -13 5 -23 19 -23 29 0 14 6 19 23 16 17 -2 32 -23 62
|
||||
-85 48 -99 63 -115 123 -141 97 -41 101 -40 50 16 -54 60 -80 113 -76 149 l3
|
||||
26 58 -47 c61 -50 87 -89 87 -131 0 -43 27 -93 59 -109 38 -20 37 -21 36 11 0
|
||||
45 24 38 47 -14 19 -41 22 -63 20 -146 -2 -91 0 -103 25 -148 45 -83 54 -83
|
||||
47 2 -6 74 11 155 32 153 20 -2 47 -101 48 -179 1 -65 -3 -88 -22 -122 -24
|
||||
-46 -28 -98 -10 -138 14 -30 24 -32 31 -5 8 30 37 25 37 -6 0 -53 -23 -113
|
||||
-62 -160 -52 -63 -58 -81 -58 -167 l0 -72 35 65 c40 75 98 135 103 107 4 -19
|
||||
-37 -114 -69 -158 -11 -16 -49 -46 -85 -66 -64 -37 -94 -76 -94 -122 0 -20 1
|
||||
-21 24 -6 19 13 25 13 35 2 17 -21 -15 -43 -73 -51 -85 -11 -126 -26 -164 -61
|
||||
-35 -31 -80 -95 -67 -95 3 0 29 12 57 26 52 26 168 45 168 28 0 -12 -92 -91
|
||||
-123 -105 -20 -9 -34 -8 -71 6 -52 20 -104 14 -130 -14 -17 -19 -17 -20 6 -23
|
||||
12 -2 24 -11 26 -20 4 -22 -37 -23 -189 -7 -99 11 -104 10 -151 -12 -26 -13
|
||||
-48 -27 -48 -30 0 -3 25 -16 55 -28 30 -13 55 -26 55 -31 0 -8 -73 -20 -119
|
||||
-20 -44 0 -99 20 -130 46 -37 31 -87 46 -124 38 l-27 -6 22 -18 c16 -13 20
|
||||
-22 12 -29 -18 -19 -125 42 -174 100 -45 53 -95 82 -165 95 l-40 7 52 -41 c96
|
||||
-76 114 -128 31 -86 -105 52 -120 69 -147 172 -9 31 -21 48 -44 62 -41 25 -61
|
||||
26 -49 2 5 -9 7 -23 5 -29 -10 -27 -32 -11 -57 39 -21 43 -26 66 -26 132 0 71
|
||||
-4 87 -29 131 -32 55 -80 106 -67 71 21 -58 18 -206 -4 -206 -5 0 -30 43 -56
|
||||
95 l-48 96 17 47 c21 57 21 89 2 122 -14 25 -14 25 -15 3 0 -14 -6 -23 -16
|
||||
-23 -14 0 -16 8 -10 53 4 28 18 70 31 92 14 22 31 55 40 73 18 37 32 152 19
|
||||
152 -5 0 -17 -21 -28 -46 -18 -45 -61 -104 -75 -104 -4 0 -4 32 0 72 6 55 16
|
||||
83 40 122 24 37 34 66 37 108 6 75 -1 91 -22 51 -16 -32 -48 -44 -61 -23 -8
|
||||
12 22 69 40 76 19 8 41 43 65 105 l21 52 -29 -29 c-16 -16 -48 -40 -71 -54
|
||||
-23 -14 -56 -45 -72 -69 -28 -43 -29 -47 -29 -175 0 -186 -12 -220 -43 -122
|
||||
-10 29 -15 62 -11 72 4 14 -2 11 -20 -9 -31 -33 -33 -65 -7 -115 21 -40 38
|
||||
-112 27 -112 -16 0 -58 35 -71 59 l-14 26 -1 -37 c0 -24 13 -63 36 -108 39
|
||||
-76 51 -155 24 -155 -8 0 -20 16 -27 35 l-11 35 -7 -29 c-11 -40 11 -127 43
|
||||
-175 15 -22 56 -72 90 -111 70 -78 66 -86 -28 -51 -71 27 -60 7 30 -54 71 -48
|
||||
106 -93 86 -112 -4 -4 -46 12 -93 37 -110 58 -109 58 -87 20 29 -49 70 -81
|
||||
188 -145 114 -63 148 -94 126 -120 -13 -16 -52 -6 -82 22 -28 25 -21 0 11 -44
|
||||
45 -63 100 -83 259 -99 154 -15 221 -29 272 -54 l35 -18 -35 -6 c-56 -10 -164
|
||||
-26 -175 -26 -5 -1 15 -10 45 -21 62 -23 124 -27 255 -15 72 6 94 5 109 -7 28
|
||||
-21 11 -37 -42 -38 l-47 -1 40 -19 c63 -31 153 -22 244 25 80 41 166 66 224
|
||||
66 l38 0 -26 -35 c-15 -19 -48 -48 -73 -66 l-47 -31 72 4 c71 4 72 4 130 59
|
||||
66 64 104 86 160 95 27 4 42 2 50 -8 16 -19 4 -34 -43 -58 l-39 -19 54 -1 c71
|
||||
0 129 28 181 88 22 26 68 80 102 120 35 41 74 89 87 108 13 19 26 33 28 31 2
|
||||
-2 -3 -46 -12 -98 -20 -128 -20 -128 26 -73 52 63 64 91 83 196 18 108 39 150
|
||||
69 146 23 -3 27 -20 14 -70 -11 -42 18 -25 49 28 34 58 41 139 20 222 -21 84
|
||||
-21 83 19 172 19 43 38 99 41 125 l7 46 38 -68 39 -68 0 88 c0 80 -3 93 -35
|
||||
157 -41 80 -47 140 -15 140 11 0 26 -12 34 -27 15 -27 15 -27 16 35 0 54 -4
|
||||
70 -29 105 -16 23 -49 57 -74 76 -56 42 -111 153 -122 248 l-7 63 58 -26 c32
|
||||
-14 71 -35 86 -45 40 -29 35 -10 -18 60 -34 45 -65 72 -117 103 -118 69 -153
|
||||
102 -141 132 9 22 25 20 68 -9 42 -28 43 -26 14 26 -36 65 -136 119 -217 119
|
||||
-48 0 -233 88 -211 100 8 4 44 11 80 14 129 14 130 15 58 47 -62 29 -64 29
|
||||
-198 23 -121 -6 -138 -5 -153 11 -25 24 -6 43 46 47 l42 3 -35 20 c-25 13 -53
|
||||
19 -98 19 -54 0 -74 -6 -143 -42 -76 -39 -139 -54 -139 -33 0 6 45 32 100 60
|
||||
l99 50 -55 7 c-76 9 -111 2 -214 -46 -99 -46 -155 -51 -155 -15 0 14 12 24 44
|
||||
36 40 14 42 16 20 22 -37 10 -80 8 -120 -7z"/>
|
||||
</g>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="800"
|
||||
height="800"
|
||||
version="1.1"
|
||||
id="svg106"
|
||||
sodipodi:docname="logo.svg"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview106"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="1.8720703"
|
||||
inkscape:cx="511.73292"
|
||||
inkscape:cy="499.71414"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2160"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg106" />
|
||||
<path
|
||||
fill="#132b6d"
|
||||
d="m 387.66175,2.9352426 c 109.978,-0.5206001 203.504,31.4880054 285.824,108.1504174 159.376,148.42203 165.076,403.05807 17.164,561.4021 -72.884,78.02402 -172.364,120.98802 -278.558,124.58202 -105.508,0.092 -196.612,-29.306 -277.44,-100.25401 C -17.844855,562.95974 -40.874855,327.5097 78.894545,164.89367 155.84375,60.416853 261.60375,10.958044 387.66175,2.9352426 Z"
|
||||
id="path1"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs2">
|
||||
<linearGradient
|
||||
id="gradient_0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="361.42581"
|
||||
y1="223.77209"
|
||||
x2="195.62669"
|
||||
y2="358.78311"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#C29024"
|
||||
id="stop1" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#DCBB57"
|
||||
id="stop2" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_0)"
|
||||
d="M 351.39175,758.48578 C 168.77575,730.12777 41.748945,587.64375 38.358945,403.44571 34.725145,206.00568 197.09775,42.52665 394.25175,39.316449 c 199.908,-3.255 364.866,156.319231 367.572,354.681261 1.264,13.294 -0.766,28.52001 -2.266,41.84201 -22.772,202.34804 -192.312,343.02406 -397.788,324.19806 -2.656,-0.244 -8.104,-0.266 -10.378,-1.552 z"
|
||||
id="path2"
|
||||
style="fill:url(#gradient_0);stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 322.01375,466.26772 c -11.018,-19.004 -31.84,-33.106 -51.826,-41.634 -1.678,-0.714 -7.54,-2.124 -8.182,-3.564 l 0.732,-0.666 c 4,0.842 8.334,3.966 12.02,5.806 6.386,3.184 15.572,2.11 22.174,5.236 4.75,2.248 4.01,8.946 6.388,12.528 4.924,7.418 31.496,22.526 25.196,30.44801 -1.88,2.366 3.59,25.088 -6.502,27.406 9.19,-11.64 6.228,-23.022 0,-35.56001 z"
|
||||
id="path3"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1ead8"
|
||||
d="m 607.74175,596.82375 c 1.336,0.334 2.464,0.632 3.666,1.342 -20.054,9.052 -64.106,28.032 -86.62,22.686 4.1,-6.492 9.65,-12.676 16.658,-16.064 19.842,0.438 47.962,-0.334 66.296,-7.964 z"
|
||||
id="path4"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 501.15175,566.49574 c 6.586,7.622 13.706,16.72001 22.154,22.30601 4.128,2.764 8.214,4.434 12.892,6.05 9.566,1.388 23.592,3.746 32.986,1.972 14.562,-1.188 28.228,-3.904 42.224,-8.022 l -1.062,3.132 c -0.626,1.91 -1.408,3.284 -2.604,4.89 -18.334,7.63 -46.454,8.402 -66.296,7.964 -7.008,3.388 -12.558,9.572 -16.658,16.064 -9.11,-5.624 -25.204,-20.256 -33.116,-27.858 -0.438,-2.818 -1.834,-5.878 -2.786,-8.594 3.066,-7.94801 11.252,-13.00801 12.266,-17.90401 z"
|
||||
id="path5"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1ead8"
|
||||
d="m 279.36575,419.47772 c 17.368,-2.17 52.85,13.874 66.39,23.914 16.654,12.346 42.944,41.42201 46.084,62.86401 l -0.632,0.818 c -7.4,-0.814 -14.928,-3.078 -22.004,0 -15.638,-34.97 -32.316,-54.81001 -66.512,-75.00601 -7.612,-4.496 -15.806,-7.926 -23.326,-12.59 z"
|
||||
id="path6"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f2e8a9"
|
||||
d="m 358.50775,559.66374 c 12.018,13.204 20.532,31.28401 42.394,32.76001 26.828,1.808 75.452,-16.66001 100.25,-25.92801 -1.014,4.896 -9.2,9.956 -12.266,17.90401 0.952,2.716 2.348,5.776 2.786,8.594 -23.926,3.644 -42.772,14.97 -73.036,18.024 -31.48,3.176 -57.178,-20.208 -60.128,-51.35401 z"
|
||||
id="path7"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs8">
|
||||
<linearGradient
|
||||
id="gradient_1"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="251.38866"
|
||||
y1="364.7413"
|
||||
x2="250.98038"
|
||||
y2="386.04666"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#8B5E10"
|
||||
id="stop7" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#CF9A22"
|
||||
id="stop8" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_1)"
|
||||
d="m 310.19775,643.62576 c 2.576,-42.33201 43.824,-23.71801 68.946,-13.31801 29.856,12.36001 44.646,14.27401 76.866,17.40001 6.062,0.588 19.738,0.234 24.164,5.272 -4.906,4.506 -30.934,9.33 -37.886,8.6 -14.06,-1.944 -28.422,0.378 -42.516,0.02 -15.588,-0.394 -24.788,-3.174 -41.264,-0.02 -10.692,-0.35 -39.162,-6.928 -48.31,-12.01 l -0.164,-0.692 c -4.454,-4.498 -8.004,-10.198 -11.632,-15.38 h 1.106 c 3.348,3.464 6.672,7.448 10.69,10.128 z"
|
||||
id="path8"
|
||||
style="fill:url(#gradient_1);stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 533.18975,212.81168 3.008,1.8 c 104.752,81.45401 120.284,223.88804 39.258,327.17806 -4.874,6.214 -10.864,11.518 -15.55,17.874 -13.234,7.248 -22.01,22.26601 -36.562,27.66201 -3.272,-0.346 -14.796,-14.16001 -18.132,-17.28801 9.246,-9.45 22.016,-16.352 32.638,-26.984 75.99,-76.05602 84.014,-197.54404 14.068,-280.22005 -6.722,-7.946 -14.4,-14.688 -21.786,-21.97401 2.61,-8.98 1.014,-18.91 3.058,-28.048 z"
|
||||
id="path9"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs10">
|
||||
<linearGradient
|
||||
id="gradient_2"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="383.45288"
|
||||
y1="318.2124"
|
||||
x2="295.73892"
|
||||
y2="203.79875"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#BF9029"
|
||||
id="stop9" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#F5D354"
|
||||
id="stop10" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_2)"
|
||||
d="m 434.37375,137.51566 c 2.598,-0.164 5.328,-0.374 7.914,0 44.516,7.77801 92.47,33.43601 126.896,61.38602 7.438,7.668 16.4,14.876 22.864,23.372 2.62,2.794 5.176,5.692 8.21,8.044 5.566,3.826 22.78,23.15001 28.692,29.00401 l 0.008,0.522 c 0.052,5.284 2.926,14.418 2.624,16.914 1.07,8.98 6.816,17.276 9.974,25.644 32.534,86.22402 17.178,181.23004 -38.442,254.80205 -9.59,12.686 -20.71,25.49601 -33.178,35.41401 -3.856,3.068 -7.42,3.966 -0.752,4.206 -9.394,1.774 -23.42,-0.584 -32.986,-1.972 -4.678,-1.616 -8.764,-3.286 -12.892,-6.05 12.516,-9.682 25.068,-17.99401 36.6,-29.13801 4.686,-6.356 10.676,-11.66 15.55,-17.874 81.026,-103.29002 65.494,-245.72405 -39.258,-327.17806 l -3.008,-1.8 c -2.044,9.138 -0.448,19.068 -3.058,28.048 -20.19,-16.736 -57.964,-41.348 -84.916,-44.78 -4.862,6.39 -8.658,12.616 -14.43,18.532 -7.806,8.378 -15.312,17.27 -22.424,26.248 v -3.898 c -1.506,1.596 -4.512,4.54 -4.34,6.828 l 0.516,0.474 c -0.566,1.138 -1.052,2.3 -1.93,3.238 l -1.24,0.028 0.2,1.06001 c -4.05,-8.60801 1.232,-15.75801 3.436,-23.75601 26.818,-41.54401 24.194,-53.60601 -19.526,-73.22601 16.782,-3.452 30.824,-15.02601 48.896,-14.09201 z"
|
||||
id="path10"
|
||||
style="fill:url(#gradient_2);stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 592.04775,222.27368 c 2.62,2.794 5.176,5.692 8.21,8.044 8.066,13.52 19.78,29.05401 28.692,42.98401 -6.366,-3.072 -23.312,-30.26801 -30.038,-38.90201 -2.778,-3.566 -7.95,-7.296 -6.864,-12.126 z"
|
||||
id="path11"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#051053"
|
||||
d="m 600.25775,230.31768 c 5.566,3.826 22.78,23.15001 28.692,29.00401 l 0.008,0.522 c 0.052,5.284 2.926,14.418 2.624,16.914 -0.81,-1.204 -1.734,-2.318 -2.632,-3.456 -8.912,-13.93 -20.626,-29.46401 -28.692,-42.98401 z"
|
||||
id="path12"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#bf8a24"
|
||||
d="m 536.19775,214.61168 c -9.436,-16.308 -80.554,-44.98201 -95.5,-43.60601 -2.88,-2.338 -5.638,-6.154 -7.546,-9.334 13.846,-0.878 61.092,18.238 74.408,25.094 7.224,3.72 43.202,27.84801 43.214,27.84601 3.21,2.37 5.956,5.258 9.132,7.662 4.042,5.416 9.626,9.648 14.302,14.496 93.102,96.54202 79.466,249.74005 -15.778,339.83206 -3.328,3.14801 -18.614,17.85401 -22.232,18.25001 -4.678,-1.616 -8.764,-3.286 -12.892,-6.05 12.516,-9.682 25.068,-17.99401 36.6,-29.13801 4.686,-6.356 10.676,-11.66 15.55,-17.874 81.026,-103.29002 65.494,-245.72405 -39.258,-327.17806 z"
|
||||
id="path13"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 434.37375,137.51566 c 2.598,-0.164 5.328,-0.374 7.914,0 44.516,7.77801 92.47,33.43601 126.896,61.38602 2.568,7.928 14.072,10.708 15.774,18.372 l -0.474,0.94 -2.092,0.246 c -0.048,0.186 -10.608,12.996 -11.95,12.526 -3.166,-1.106 -7.656,-9.138 -10.536,-8.712 -3.176,-2.404 -5.922,-5.292 -9.132,-7.662 -0.012,0.002 -35.99,-24.12601 -43.214,-27.84601 -13.316,-6.856 -60.562,-25.972 -74.408,-25.094 1.908,3.18 4.666,6.996 7.546,9.334 14.946,-1.376 86.064,27.29801 95.5,43.60601 l -3.008,-1.8 c -2.044,9.138 -0.448,19.068 -3.058,28.048 -20.19,-16.736 -57.964,-41.348 -84.916,-44.78 -4.862,6.39 -8.658,12.616 -14.43,18.532 -7.806,8.378 -15.312,17.27 -22.424,26.248 v -3.898 c -1.506,1.596 -4.512,4.54 -4.34,6.828 l 0.516,0.474 c -0.566,1.138 -1.052,2.3 -1.93,3.238 l -1.24,0.028 0.2,1.06001 c -4.05,-8.60801 1.232,-15.75801 3.436,-23.75601 26.818,-41.54401 24.194,-53.60601 -19.526,-73.22601 16.782,-3.452 30.824,-15.02601 48.896,-14.09201 z"
|
||||
id="path14"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 412.09175,152.87167 c 12.74,-3.468 25.54,-4.784 38.71,-3.946 -6.848,2.32 -14.484,5.572 -20.016,10.326 8.062,3.682 21.354,5.528 30.612,8.39 19.908,6.152 75.712,30.48001 89.376,46.97001 -0.012,0.002 -35.99,-24.12601 -43.214,-27.84601 -13.316,-6.856 -60.562,-25.972 -74.408,-25.094 1.908,3.18 4.666,6.996 7.546,9.334 14.946,-1.376 86.064,27.29801 95.5,43.60601 l -3.008,-1.8 c -17.866,-18.572 -65.548,-36.19801 -90.902,-40.93001 3.608,7.782 6.348,15.752 2.928,24.19801 -4.862,6.39 -8.658,12.616 -14.43,18.532 -7.806,8.378 -15.312,17.27 -22.424,26.248 v -3.898 c 22.078,-32.98 57.308,-46.31801 3.73,-84.09001 z"
|
||||
id="path15"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1ead8"
|
||||
d="m 442.28775,171.88167 c 25.354,4.732 73.036,22.35801 90.902,40.93001 -2.044,9.138 -0.448,19.068 -3.058,28.048 -20.19,-16.736 -57.964,-41.348 -84.916,-44.78 3.42,-8.44601 0.68,-16.41601 -2.928,-24.19801 z"
|
||||
id="path16"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs17">
|
||||
<linearGradient
|
||||
id="gradient_3"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="259.85068"
|
||||
y1="248.27858"
|
||||
x2="350.85385"
|
||||
y2="408.95212"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#061757"
|
||||
id="stop16" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#1C4897"
|
||||
id="stop17" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_3)"
|
||||
d="m 628.94975,259.32169 c 35.888,36.25 71.52,72.79001 107.964,108.48002 6.736,6.598 18.816,21.616 24.91,26.196 1.264,13.294 -0.766,28.52001 -2.266,41.84201 -22.772,202.34804 -192.312,343.02406 -397.788,324.19806 -2.656,-0.244 -8.104,-0.266 -10.378,-1.552 -4.572,-6.652 -23.912,-22.76601 -31.626,-30.48801 l -117.162,-117.50802 c -11.006,-10.966 -46.288,-42.43401 -53.304,-54.48401 -4.57,-5.32 -10.27,-9.648 -14.854,-15.058 4.872,0.144 18.938,7.52 23.586,10.336 6.858,1.708 20.052,4.126 26.25,6.798 0.434,-1.258 0.146,-2.694 0,-3.998 0.138,-1.692 0.09,-3.306 0,-5 3.348,0.634 6.652,2.408 10.05,2.2 13.202,5.656 24.534,12.708 34.05,23.62 3.788,3.09 7.482,6.23801 11.126,9.49601 4.716,4.008 9.52,7.936 13.794,12.424 1.884,0.704 5.45,2.046 6.762,3.614 1.584,0.97 3.154,2.014 4.78,2.904 7.256,3.166 14.768,8.762 21.092,13.49 1.516,2.334 3.288,4.486 5.016,6.664 l 7.45,10.00201 c 3.628,5.182 7.178,10.882 11.632,15.38 l 0.164,0.692 c 9.148,5.082 37.618,11.66 48.31,12.01 16.476,-3.154 25.676,-0.374 41.264,0.02 14.094,0.358 28.456,-1.964 42.516,-0.02 6.952,0.73 32.98,-4.094 37.886,-8.6 7.398,7.31 18.44,8.658 28.374,7.392 40.55,-5.168 97.53,-34.27201 123.034,-67.37801 -2.714,-0.424 9.054,-10.22 9.25,-12.97 -7.204,1.354 -10.72,9.924 -18.264,10.996 -3.768,2.22 -7.816,4.312 -11.16,7.146 -1.202,-0.71 -2.33,-1.008 -3.666,-1.342 1.196,-1.606 1.978,-2.98 2.604,-4.89 l 1.062,-3.132 c -13.996,4.118 -27.662,6.834 -42.224,8.022 -6.668,-0.24 -3.104,-1.138 0.752,-4.206 12.468,-9.918 23.588,-22.72801 33.178,-35.41401 55.62,-73.57201 70.976,-168.57803 38.442,-254.80205 -3.158,-8.368 -8.904,-16.664 -9.974,-25.644 0.302,-2.496 -2.572,-11.63 -2.624,-16.914 z"
|
||||
id="path17"
|
||||
style="fill:url(#gradient_3);stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 637.21175,576.96974 c 4.14,-2.36 8.288,-4.69 12.494,-6.932 -5.274,7.16 -11.4,17.29401 -18.124,22.95601 -2.714,-0.424 9.054,-10.22 9.25,-12.97 -7.204,1.354 -10.72,9.924 -18.264,10.996 3.782,-3.136 14.3,-8.644 15.882,-12.846 z"
|
||||
id="path18"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f2e8a9"
|
||||
d="m 637.21175,576.96974 1.238,1.20401 c -1.582,4.202 -12.1,9.71 -15.882,12.846 -3.768,2.22 -7.816,4.312 -11.16,7.146 -1.202,-0.71 -2.33,-1.008 -3.666,-1.342 1.196,-1.606 1.978,-2.98 2.604,-4.89 l 1.062,-3.132 c 9.172,-3.09 17.482,-6.914 25.804,-11.83201 z"
|
||||
id="path19"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 358.50775,661.57976 c 16.476,-3.154 25.676,-0.374 41.264,0.02 14.094,0.358 28.456,-1.964 42.516,-0.02 -25.31,6.146 -58.224,4.784 -83.78,0 z"
|
||||
id="path20"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs21">
|
||||
<linearGradient
|
||||
id="gradient_4"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="178.9133"
|
||||
y1="342.13019"
|
||||
x2="155.9601"
|
||||
y2="362.37878"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#CC991E"
|
||||
id="stop20" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#F2B831"
|
||||
id="stop21" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_4)"
|
||||
d="m 134.44575,540.94774 c 4.872,0.144 18.938,7.52 23.586,10.336 6.858,1.708 20.052,4.126 26.25,6.798 0.434,-1.258 0.146,-2.694 0,-3.998 0.138,-1.692 0.09,-3.306 0,-5 3.348,0.634 6.652,2.408 10.05,2.2 13.202,5.656 24.534,12.708 34.05,23.62 3.788,3.09 7.482,6.23801 11.126,9.49601 4.716,4.008 9.52,7.936 13.794,12.424 1.884,0.704 5.45,2.046 6.762,3.614 1.584,0.97 3.154,2.014 4.78,2.904 7.256,3.166 14.768,8.762 21.092,13.49 1.516,2.334 3.288,4.486 5.016,6.664 l 7.45,10.00201 c 3.628,5.182 7.178,10.882 11.632,15.38 l 0.164,0.692 c -22.282,-4.896 -55.696,-23.88201 -74.236,-37.44601 -6.744,-4.934 -12.552,-11.388 -19.652,-15.766 -6.676,-4.12 -15.06,-5.966 -22.186,-9.388 -16.632,-7.988 -30.922,-18.98801 -44.824,-30.96401 -4.57,-5.32 -10.27,-9.648 -14.854,-15.058 z"
|
||||
id="path21"
|
||||
style="fill:url(#gradient_4);stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 158.03175,551.28374 c 6.858,1.708 20.052,4.126 26.25,6.798 1.448,0.596 2.168,1.102 2.948,2.48 l -0.558,0.666 c -3.77,-0.136 -27.166,-8.046 -28.64,-9.944 z"
|
||||
id="path22"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#bf8a24"
|
||||
d="m 242.85175,607.32775 c 7.25,0.168 31.11,8.666 40.444,11.75 -14.638,0.038 -27.2,-6.238 -40.444,-11.75 z"
|
||||
id="path23"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 232.69375,596.82375 c 6.662,0.62 22.044,5.462 27.37,3.614 1.584,0.97 3.154,2.014 4.78,2.904 -4.194,1.55 -18.89,-0.318 -26.814,1.446 z"
|
||||
id="path24"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 209.78375,574.90374 c -2.394,-0.948 -7.676,-3.032 -7.456,-6.196 5.142,-1.48 19.682,5.378 26.054,6.196 3.788,3.09 7.482,6.23801 11.126,9.49601 l -0.16,0.142 c -3.374,0.606 -25.568,-7.70801 -29.564,-9.63801 z"
|
||||
id="path25"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 209.78375,574.90374 c 3.996,1.93 26.19,10.24401 29.564,9.63801 l 0.16,-0.142 c 4.716,4.008 9.52,7.936 13.794,12.424 1.884,0.704 5.45,2.046 6.762,3.614 -5.326,1.848 -20.708,-2.994 -27.37,-3.614 -10.77,-1.75 -16.314,-4.876 -19.558,-16.004 -1.528,-1.78 -2.85,-3.59801 -3.352,-5.91601 z"
|
||||
id="path26"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#bf8a24"
|
||||
d="m 209.78375,574.90374 c 3.996,1.93 26.19,10.24401 29.564,9.63801 l 0.16,-0.142 c 4.716,4.008 9.52,7.936 13.794,12.424 v 0 c -11.244,-0.884 -22.286,-6.858 -31.866,-12.424 -2.804,-0.374 -5.434,-2.774 -8.3,-3.58 -1.528,-1.78 -2.85,-3.59801 -3.352,-5.91601 z"
|
||||
id="path27"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#ad7214"
|
||||
d="m 221.43575,584.39975 c 6.578,-0.56 30.096,8.298 31.866,12.424 -11.244,-0.884 -22.286,-6.858 -31.866,-12.424 z"
|
||||
id="path28"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#132b6d"
|
||||
d="m 266.41175,531.65974 c -4.998,-0.03 -11.098,-9.27801 -14.01,-12.81601 -78.2,-95.08401 -44.296,-239.09604 68.622,-289.88605 14.626,-6.58 87.39,-28.004 83.98,-12.018 0.29,5.32 -5.89,12.826 -5.742,19.654 l 0.8,-0.356 0.256,-0.984 c 0.838,-3.116 3.132,-7.658 4.686,-10.42 v 0 c -2.204,7.998 -7.486,15.148 -3.436,23.75601 l -0.2,-1.06001 1.24,-0.028 c 0.878,-0.938 1.364,-2.1 1.93,-3.238 l -0.516,-0.474 c -0.172,-2.288 2.834,-5.232 4.34,-6.828 v 3.898 c 7.112,-8.978 14.618,-17.87 22.424,-26.248 l 0.5,0.152 c 8.212,2.444 16.47,3.944 24.602,6.854 58.574,20.972 106.85,72.05001 120.456,133.45202 1.73,7.81001 2.632,15.79601 4.472,23.57201 0.174,4.016 1.316,11.12 -0.142,14.692 l -1.322,0.664 1.154,0.176 c 1.286,3.432 0.364,9.786 0.31,13.526 0.428,4.816 0.606,10.62001 0,15.40801 -1.662,4.574 -2.66,9.378 -3.582,14.148 -0.862,5.382 -1.694,10.842 -3.742,15.924 -1.502,3.656 -3.308,7.462 -4.308,11.294 -0.442,4.27201 -3.664,10.89601 -6.116,14.42401 -2.28,4.28 -4.82,10.524 -8.172,14.028 -2.766,4.198 -5.424,8.452 -8.062,12.73 l -10.636,13.256 c -0.812,1.354 -10.158,11.70601 -11.41,12.74801 -4.732,2.976 -7.86,5.02 -11.552,9.288 -4.794,2.344 -9.02,6.04 -13.816,8.136 -4.916,2.576 -9.95,5.226 -14.068,8.998 -5.336,1.804 -10.23,3.636 -15.1,6.486 -3,0.812 -11.478,3.87 -14.124,3.644 -5.37,1.882 -11.066,2.43 -16.396,4.486 l -14.888,2.206 c -3.228,-0.058 -14.524,1.172 -16.482,0 -2.668,0.884 -14.2,-1.2 -17.154,-2.206 -4.388,-1.97 -13.234,-3.4 -15.17,-4.486 -15.284,-4 -26.706,-61.61201 4.84,-58.55001 5.12,0.178 10.212,1.104 15.266,1.896 -0.322,-4.59 -1.47,-8.966 -2.758,-13.362 -31.792,-69.38401 -101.182,-95.30202 -174.692,-84.31001 28.904,2.816 52.742,14.29 77.006,28.634 14.684,13.388 42.828,39.46001 22.146,59.30801 -4.42,-5.66 -9.796,-10.928 -13.456,-17.124 l -1.134,0.23 0.924,-0.544 0.246,0.612 -1.168,-0.966 c -0.378,1.04 0.1,2.79 0.238,3.908 -0.494,8.656 -0.63,17.812 -1.922,26.378 -0.986,1.08 -1.914,2.264 -3.172,3.032 -4.348,3.636 -8.422,7.43801 -12.466,11.40401 -1.992,-3.07 -5.034,-6.59401 -6.57,-9.84601 -2.598,-1.562 -2.622,-4.334 -3.65,-6.816 l -0.892,0.308 c -0.248,2.022 1.28,3.668 1.268,5.77 l -0.744,0.738 c 2.36,3.862 7.746,10.52601 7.948,15.01601 -5.642,-0.656 -11.25,-1.548 -16.884,-2.268 z"
|
||||
id="path29"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 271.23775,505.65573 4.11,2.688 c 0.612,3.864 2.48,7.024 4.018,10.568 -2.598,-1.562 -2.622,-4.334 -3.65,-6.816 l -0.892,0.308 c -0.248,2.022 1.28,3.668 1.268,5.77 l -0.744,0.738 c -1.114,-4.514 -3.114,-8.68 -4.11,-13.256 z"
|
||||
id="path30"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#051053"
|
||||
d="m 397.67375,507.07373 c 2.356,4.01 4.79,7.942 7.33,11.838 -3.3,-1.106 -7.652,-4.4 -10.786,-4.59 l 1.848,-0.566 c 1.032,-1.614 0.804,-4.254 1.44,-6.188 z"
|
||||
id="path31"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#0f0e1a"
|
||||
d="m 393.38575,498.19573 c 3.194,2.542 2.828,5.462 4.288,8.878 l -0.168,0.494 c -0.636,1.934 -0.408,4.574 -1.44,6.188 l -1.848,0.566 c -4.74,-0.682 -9.642,-1.346 -13.34,-4.66 5.12,0.178 10.212,1.104 15.266,1.896 -0.322,-4.59 -1.47,-8.966 -2.758,-13.362 z"
|
||||
id="path32"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 405.00375,216.93968 c 0.29,5.32 -5.89,12.826 -5.742,19.654 l 0.8,-0.356 0.256,-0.984 c 0.838,-3.116 3.132,-7.658 4.686,-10.42 v 0 c -2.204,7.998 -7.486,15.148 -3.436,23.75601 l -0.2,-1.06001 1.24,-0.028 c 0.878,-0.938 1.364,-2.1 1.93,-3.238 l -0.516,-0.474 c -0.172,-2.288 2.834,-5.232 4.34,-6.828 v 3.898 c -5.74,7.47601 -10.278,15.97801 -14.976,24.13401 2.614,-16.47 4.536,-32.74201 11.618,-48.05401 z"
|
||||
id="path33"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 376.03775,568.21174 c 3.14,-7.134 6.892,-14.264 9.44,-21.616 2.51,8.576 3.87,17.374 5.73,26.102 -4.388,-1.97 -13.234,-3.4 -15.17,-4.486 z"
|
||||
id="path34"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 275.34775,508.34373 c 7.554,3.424 15.174,6.414 23.054,9.01 -4.348,3.636 -8.422,7.43801 -12.466,11.40401 -1.992,-3.07 -5.034,-6.59401 -6.57,-9.84601 -1.538,-3.544 -3.406,-6.704 -4.018,-10.568 z"
|
||||
id="path35"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 580.81575,378.64171 c 0.174,4.016 1.316,11.12 -0.142,14.692 l -1.322,0.664 c -8.51,-1.606 -16.614,-3.178 -25.25,-4.102 8.398,-6.016 16.886,-8.52 26.714,-11.254 z"
|
||||
id="path36"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 554.10175,411.69971 c 8.586,-2.24 17.924,-2.716 26.714,-4 0.428,4.816 0.606,10.62001 0,15.40801 -8.872,-2.66 -19.79,-5.044 -26.714,-11.40801 z"
|
||||
id="path37"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 413.80575,549.08374 c 5.198,7.878 7.314,17.22 11.038,25.82 -3.228,-0.058 -14.524,1.172 -16.482,0 1.018,-8.646 2.216,-17.686 5.444,-25.82 z"
|
||||
id="path38"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 526.91575,484.43773 c 9.316,1.67 19.154,5.096 27.98,8.488 -2.766,4.198 -5.424,8.452 -8.062,12.73 -7.26,-6.506 -15.232,-12.516 -19.918,-21.218 z"
|
||||
id="path39"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 549.10575,437.25572 c 9.318,-0.64 18.79,-0.084 28.128,0 -0.862,5.382 -1.694,10.842 -3.742,15.924 -8.43,-5.086 -16.78,-9.56 -24.386,-15.924 z"
|
||||
id="path40"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 439.73175,543.29174 1.36,1.452 c 6.326,6.73 9.89,15.802 15.036,23.468 -5.37,1.882 -11.066,2.43 -16.396,4.486 z"
|
||||
id="path41"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 539.67175,462.21972 c 9.972,-0.004 19.626,1.052 29.512,2.254 -0.442,4.27201 -3.664,10.89601 -6.116,14.42401 -8.166,-3.222 -17.172,-10.556 -23.396,-16.67801 z"
|
||||
id="path42"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 488.88575,521.69573 c 7.732,3.84201 19.168,12.47201 24.35,19.25201 -4.794,2.344 -9.02,6.04 -13.816,8.136 -4.688,-8.85 -7.936,-17.748 -10.534,-27.38801 z"
|
||||
id="path43"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 509.94175,505.65573 c 5.494,1.07 8.69,2.82 13.364,5.902 5.104,1.702 8.644,4.112 12.892,7.354 -0.812,1.354 -10.158,11.70601 -11.41,12.74801 -2.844,-4.58 -6.188,-9.33401 -8.274,-14.30601 -2.536,-3.532 -4.474,-7.872 -6.572,-11.698 z"
|
||||
id="path44"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 465.35375,533.92774 c 7.502,6.24 15.294,15.644 19.998,24.154 -5.336,1.804 -10.23,3.636 -15.1,6.486 -3.214,-9.588 -4.238,-20.568 -4.898,-30.64 z"
|
||||
id="path45"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#2356ae"
|
||||
d="M 351.39175,758.48578 C 168.77575,730.12777 41.748945,587.64375 38.358945,403.44571 34.725145,206.00568 197.09775,42.52665 394.25175,39.316449 c 199.908,-3.255 364.866,156.319231 367.572,354.681261 -6.094,-4.58 -18.174,-19.598 -24.91,-26.196 -36.444,-35.69001 -72.076,-72.23002 -107.964,-108.48002 -5.912,-5.854 -23.126,-25.17801 -28.692,-29.00401 -3.034,-2.352 -5.59,-5.25 -8.21,-8.044 -6.464,-8.496 -15.426,-15.704 -22.864,-23.372 -34.426,-27.95001 -82.38,-53.60801 -126.896,-61.38602 -2.586,-0.374 -5.316,-0.164 -7.914,0 -18.072,-0.934 -32.114,10.64001 -48.896,14.09201 43.72,19.62 46.344,31.682 19.526,73.22601 v 0 c -1.554,2.762 -3.848,7.304 -4.686,10.42 l -0.256,0.984 -0.8,0.356 c -0.148,-6.828 6.032,-14.334 5.742,-19.654 3.41,-15.986 -69.354,5.438 -83.98,12.018 -112.918,50.79001 -146.822,194.80204 -68.622,289.88605 2.912,3.538 9.012,12.78601 14.01,12.81601 5.634,0.72 11.242,1.612 16.884,2.268 -0.202,-4.49 -5.588,-11.15401 -7.948,-15.01601 l 0.744,-0.738 c 0.012,-2.102 -1.516,-3.748 -1.268,-5.77 l 0.892,-0.308 c 1.028,2.482 1.052,5.254 3.65,6.816 1.536,3.252 4.578,6.77601 6.57,9.84601 4.044,-3.966 8.118,-7.76801 12.466,-11.40401 1.258,-0.768 2.186,-1.952 3.172,-3.032 1.292,-8.566 1.428,-17.722 1.922,-26.378 -0.138,-1.118 -0.616,-2.868 -0.238,-3.908 l 1.168,0.966 -0.246,-0.612 -0.924,0.544 1.134,-0.23 c 3.66,6.196 9.036,11.464 13.456,17.124 20.682,-19.848 -7.462,-45.92001 -22.146,-59.30801 8.322,2.714 22.978,21.546 26.672,29.42201 2.368,5.048 2.81,14.832 4.236,17.488 3.938,-9.238 -6.242,-21.60201 -4.594,-23.16201 6.228,12.53801 9.19,23.92001 0,35.56001 -11.034,9.136 -29.284,21.156 -36.122,33.99601 -15.95,29.946 -3.004,58.48801 7.948,85.92401 1.766,3.338 5.028,8.098 5.668,11.75001 h -1.106 l -7.45,-10.00201 c -1.728,-2.178 -3.5,-4.33 -5.016,-6.664 -6.324,-4.728 -13.836,-10.324 -21.092,-13.49 -1.626,-0.89 -3.196,-1.934 -4.78,-2.904 -1.312,-1.568 -4.878,-2.91 -6.762,-3.614 -4.274,-4.488 -9.078,-8.416 -13.794,-12.424 -3.644,-3.258 -7.338,-6.40601 -11.126,-9.49601 -9.516,-10.912 -20.848,-17.964 -34.05,-23.62 -3.398,0.208 -6.702,-1.566 -10.05,-2.2 0.09,1.694 0.138,3.308 0,5 0.146,1.304 0.434,2.74 0,3.998 -6.198,-2.672 -19.392,-5.09 -26.25,-6.798 -4.648,-2.816 -18.714,-10.192 -23.586,-10.336 4.584,5.41 10.284,9.738 14.854,15.058 7.016,12.05 42.298,43.51801 53.304,54.48401 l 117.162,117.50802 c 7.714,7.722 27.054,23.83601 31.626,30.48801 z"
|
||||
id="path46"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#132b6d"
|
||||
d="m 179.65375,204.78568 0.312,-1.174 0.54,0.326 c 1.66,8.908 0.01,23.462 3.776,31.23 -0.946,2.464 -0.94,5.09 -2.088,7.614 -0.896,-7.214 -1.61,-14.446 -2.54,-21.656 -0.13,-5.46 -0.212,-10.878 0,-16.34 z"
|
||||
id="path47"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 125.81775,276.75769 c 2.17,11.74 9.116,22.444 12.934,33.79201 l -0.57,0.518 c -1.16,-3.654 -7.662,-20.46601 -9.84,-22.36001 l -0.976,0.068 c -1.38,1.692 -2.846,2.256 -4.866,3.024 -2.616,6.924 -1.898,24.47801 -3.168,33.15201 -0.472,-15.43 -0.356,-34.15801 6.486,-48.19401 z"
|
||||
id="path48"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#132b6d"
|
||||
d="m 274.23575,141.76967 c -2.074,7.182 -3.328,13.142 -2.998,20.634 -4.176,2.324 -7.592,4.762 -11.174,7.91 v -2.354 c 1.878,-6.262 2.766,-12.768 4.78,-19.034 3.524,-1.72 6.27,-4.824 9.392,-7.156 z"
|
||||
id="path49"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#132b6d"
|
||||
d="m 371.74975,108.36966 c -3.86,7.4 -7.354,14.524 -9.404,22.688 v 0 c -3.648,0.82 -7.228,1.122 -10.954,1.38 4.392,-6.38 5.642,-13.5 10.954,-19.87 l 1.312,1.376 c 2.71,-0.242 5.8,-4.024 8.092,-5.574 z"
|
||||
id="path50"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 268.33575,131.05766 c -1.042,5.972 -2.31,11.92001 -3.492,17.86801 -2.014,6.266 -2.902,12.772 -4.78,19.034 -1.326,-4.864 3.318,-9.734 1.244,-14.208 -22.57,-10.084 -17.62,14.712 -26.708,18.13 6.172,-15.816 20.434,-30.548 33.736,-40.82401 z"
|
||||
id="path51"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 179.65375,196.07968 c -0.244,2.936 -0.14,5.77 0,8.706 -0.212,5.462 -0.13,10.88 0,16.34 -2.87,1.676 -3.574,6.084 -4.174,9.192 -1.636,3.874 -3.642,7.834 -4.67,11.914 l -0.244,0.106 0.41,-0.728 -0.192,-0.106 c 2.75,-11.394 5.076,-8.03 -4.17,-11.186 -1.178,2.228 -4.1,9.672 -5.944,10.542 4.934,-15.602 12.448,-29.868 18.984,-44.78 z"
|
||||
id="path52"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#132b6d"
|
||||
d="m 456.12775,109.52166 c 3.564,1.658 10.414,-0.138 14.124,-1.152 -9.878,8.046 -21.92,17.846 -27.964,29.146 -2.586,-0.374 -5.316,-0.164 -7.914,0 l -6.334,-3.096 c 7.916,-6.85 14.976,-14.806 22.762,-21.852 1.752,-1.066 3.52,-2.074 5.326,-3.046 z"
|
||||
id="path53"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 100.50375,364.60771 c 8.122,7.8 22.772,25.956 30.762,31.252 0.936,5.038 2.374,10.71 2.462,15.774 -12.286,-9.396 -17.796,-19.394 -28.126,-27.642 0.096,1.026 0.082,1.858 -0.212,2.84 -2.522,-7.432 -3.886,-14.462 -4.886,-22.224 z"
|
||||
id="path54"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 96.515745,442.51972 c 8.566005,4.34 36.750005,23.486 42.236005,30.46001 l 0.276,0.808 c 6.398,2.844 8.096,8.69 8.058,15.766 l -0.588,-0.544 c -1.434,-1.32 -10.678,-7.62 -12.052,-7.594 -5.946,-3.566 -23.722,-21.69601 -29.056,-20.70801 -3.03,-6.03 -5.978005,-12.092 -8.874005,-18.188 z"
|
||||
id="path55"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 121.77975,525.87374 c 19.42,6.36 38.498,14.12 57.874,20.722 l 0.548,0.758 1.826,-0.056 c 1.258,1.488 1.388,4.868 2.254,6.786 0.146,1.304 0.434,2.74 0,3.998 -6.198,-2.672 -19.392,-5.09 -26.25,-6.798 -4.648,-2.816 -18.714,-10.192 -23.586,-10.336 -4.45,-4.812 -8.812,-9.764 -12.666,-15.074 z"
|
||||
id="path56"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 271.23775,162.40367 c 7.99,-6.254 18.884,-10.416 28.25,-14.234 16.76,-6.832 13.44,-7.376 25.658,-19.48401 10.768,-10.672 29.362,-23.208 44.058,-28.062 -2.508,3.886 -5.042,7.672 -6.858,11.944 -5.312,6.37 -6.562,13.49 -10.954,19.87 -0.974,1.678 -1.832,2.932 -3.262,4.254 l -0.532,-0.056 c 0.956,-3.102 4.54,-2.84 3.518,-6.662 l -2.128,-2.174 c -8.514,3.742 -77.504,34.61201 -77.75,34.60401 z"
|
||||
id="path57"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs58">
|
||||
<linearGradient
|
||||
id="gradient_5"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="145.13785"
|
||||
y1="328.17804"
|
||||
x2="117.22018"
|
||||
y2="280.89636"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#D79A18"
|
||||
id="stop57" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#F6C842"
|
||||
id="stop58" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_5)"
|
||||
d="m 105.38975,460.70772 c 5.334,-0.988 23.11,17.14201 29.056,20.70801 4.286,3.456 9.396,6.13 13.392,9.86 0.278,-2.39 0.424,-4.632 1.462,-6.838 l 0.504,-0.106 c 0.058,-0.954 -0.086,-7.128 0.79,-5.038 1.712,4.084 3.956,1.936 4.492,8.664 l 0.486,-0.014 c 2.38,7.206 8.172,8.99 13.068,13.884 l -0.348,0.398 c 2.612,0.138 4.874,0.24 7.188,1.558 0.816,0.698 1.66,1.344 2.532,1.97 l 0.462,1.048 c -1.04,0.308 -0.606,0.28 -1.274,0.272 3.704,0.932 3.808,4.058 4.994,7.248 v 0 c 2.772,3.696 5.17,7.268 6.946,11.55201 -1.732,-0.248 -24.262,-10.67601 -16.892,-1.472 2.482,3.098 5.226,7.084 8.34,9.526 2.636,1.906 4.292,5.756 7.29,7.02 h 1.262 l -1.262,2.344 c 0.818,1.872 1.938,2.472 3.716,3.304 l -0.66,0.048 c -2.968,0.184 -9.982,-2.572 -6.652,2.44 0.09,1.694 0.138,3.308 0,5 -0.866,-1.918 -0.996,-5.298 -2.254,-6.786 l -1.826,0.056 -0.548,-0.758 c -0.52,-3.778 -6.05,-8.072 -8.808,-10.5 -24.584,-13.75401 -54.27,-50.32801 -65.456,-75.38802 z"
|
||||
id="path58"
|
||||
style="fill:url(#gradient_5);stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 170.84575,536.09574 c 0.178,0.002 16.806,6.982 17.032,7.196 0.818,1.872 1.938,2.472 3.716,3.304 l -0.66,0.048 c -2.968,0.184 -9.982,-2.572 -6.652,2.44 0.09,1.694 0.138,3.308 0,5 -0.866,-1.918 -0.996,-5.298 -2.254,-6.786 l -1.826,0.056 -0.548,-0.758 c -0.52,-3.778 -6.05,-8.072 -8.808,-10.5 z"
|
||||
id="path59"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#bf8a24"
|
||||
d="m 182.19375,514.32173 c -5.22,-0.312 -16.074,-7.81 -20,-10.892 -0.398,-0.312 -4.628,-3.938 -2.568,-3.994 4.124,-0.114 11.04,6.52 14.26,8.908 0.87,-0.988 2.086,-1.036 3.314,-1.27 3.704,0.932 3.808,4.058 4.994,7.248 z"
|
||||
id="path60"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 177.19975,507.07373 c 3.704,0.932 3.808,4.058 4.994,7.248 -2.664,-2.118 -5.5,-4.052 -8.308,-5.978 0.87,-0.988 2.086,-1.036 3.314,-1.27 z"
|
||||
id="path61"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs62">
|
||||
<linearGradient
|
||||
id="gradient_6"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="238.76126"
|
||||
y1="143.77654"
|
||||
x2="270.52316"
|
||||
y2="95.432106"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#FAD84F"
|
||||
id="stop61" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#FFF5A9"
|
||||
id="stop62" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_6)"
|
||||
d="m 362.34575,131.05766 c 26.81,-3.184 19.722,-1.768 42.234,-13.04 19.684,-9.856 41.194,-16.094 63.324,-15.652 -4.056,2.182 -8.086,4.39 -11.776,7.156 -1.806,0.972 -3.574,1.98 -5.326,3.046 -7.786,7.046 -14.846,15.002 -22.762,21.852 l 6.334,3.096 c -18.072,-0.934 -32.114,10.64001 -48.896,14.09201 -3.1,0.442 -6.45,0.35 -9.44,1.264 -3.958,1.83 -9.35,-0.016 -13.526,1.328 l -0.166,0.49 c 4.412,1.276 9.87,1.98 13.692,4.562 -11.014,0.822 -21.384,-2.856 -32.396,-2.412 -0.74,-0.772 -5.22,0.294 -7.562,-0.282 l 0.286,-0.044 c -8.446,-2.598 -0.096,-4.918 2.406,-7.588 6.796,-3.554 22.95,-8.952 23.574,-17.86801 z"
|
||||
id="path62"
|
||||
style="fill:url(#gradient_6);stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 341.76375,151.60767 c 11.034,-5.176 26.9,-6.422 39.114,-7.498 -2.7,3.496 -6.968,3.658 -4.84,8.762 -3.958,1.83 -9.35,-0.016 -13.526,1.328 l -0.166,0.49 c -4.888,-1.222 -8.504,-1.066 -13.358,0 -2.746,0.4 -8.482,-0.994 -10.622,-2.552 l 0.184,-0.502 -0.088,0.422 0.506,-0.548 z"
|
||||
id="path63"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 424.84375,132.43766 c 9.142,-6.23 14.826,-16.674 25.958,-19.87 -7.786,7.046 -14.846,15.002 -22.762,21.852 l 6.334,3.096 c -18.072,-0.934 -32.114,10.64001 -48.896,14.09201 -3.1,0.442 -6.45,0.35 -9.44,1.264 -2.128,-5.104 2.14,-5.266 4.84,-8.762 8.736,-2.842 14.512,-8.95201 24.126,-9.69001 2.98,-2.124 16.504,-3.504 19.84,-1.982 z"
|
||||
id="path64"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 405.00375,134.41966 c 2.98,-2.124 16.504,-3.504 19.84,-1.982 -3.412,3.298 -15.364,2.648 -19.84,1.982 z"
|
||||
id="path65"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 348.98775,127.79966 2.128,2.174 c 1.022,3.822 -2.562,3.56 -3.518,6.662 l 0.532,0.056 c 1.43,-1.322 2.288,-2.576 3.262,-4.254 3.726,-0.258 7.306,-0.56 10.954,-1.38 -0.624,8.91601 -16.778,14.31401 -23.574,17.86801 -7.41,2.68 -9.978,8.094 -16.164,11.038 -3.652,1.74 -27.878,3.596 -21.164,11.206 l -1.672,0.284 6.764,0.428 c -13.404,2.41 -17.64,4.718 -29.284,7.922 6.38,1.602 10.798,-2.57 18.448,0.768 h 2.702 l -0.042,1.276 c -7.05,4.88 -18.516,5.498 -27.53,13.56001 -1.344,1.2 -2.83,2.678 -4.418,3.494 -4.23,1.326 -8.724,2.754 -13.11,3.378 -1.89,1.25 -12.68,4.234 -15.272,4.588 v 0 -2.082 l -2.28,-3.718 c -4.61,0.068 -7.042,12.34 -7.368,15.872 -8.018,0.742 -11.65,9.846 -16.818,14.858 -3.88,-1.22 -4.476,2.806 -6.472,5.164 -1.86,1.146 -4.982,3.384 -5.056,5.82 1.124,1.468 1.626,2.97 2.234,4.704 v 0 c -0.316,5.61801 1.456,4.99401 6.442,4.89801 -1.14,1.822 -2.366,3.564 -3.62,5.31 -1.95,2.246 -3.464,4.796 -5.056,7.3 -3.182,5.058 -6.5,9.462 -10.092,14.184 l -0.804,0.272 c -2.854,3.482 -4.438,8.244 -6.946,12.09 0.062,-2.884 0.094,-5.748 0,-8.632 -0.152,-5.29 -0.606,-10.77 0,-16.034 -4.278,6.658 -7.876,14.308 -9.904,21.966 l -0.172,-0.658 c -0.69,-2.716 -0.326,-5.508 -1.658,-8.056 -2.812,3.078 -0.546,7.956 -1.82,11.414 -2.326,1.824 -3.704,3.838 -4.96,6.498 0.362,13.11001 -0.04,26.34401 -0.64,39.44401 -2.058,-8.594 -3.944,-31.802 -5.008,-35.10001 -1.466,3.81001 -4.786,9.06401 -5.378,12.93801 -1.004,6.558 0.336,12.898 -1.634,19.682 l -0.152,-2.372 c -1.242,0.97 -0.692,3.5 -1.568,4.852 -0.888,5.956 -6.352,24.62201 -2.024,29.02001 l 1.026,-0.056 c 0.982,-1.328 1.022,-2.274 0.998,-3.888 2.54,11.112 6.984,15.086 6.272,27.338 -4.292,-5.588 -5.538,-12.7 -9.37,-18.494 -3.122,10.1 -3.688,19.896 -1.048,30.034 0.382,1.46 5.496,9.346 2.684,9.412 -1.922,-1.014 -3.814,-2.066 -5.696,-3.148 v 6.18601 l 5.696,5.592 -0.786,0.856 c 0.296,2.89 2.728,6.41 -0.85,8.024 -1.37,-0.752 -2.74,-1.49 -4.06,-2.326 1.508,3.706 4.194,6.776 5.696,10.326 -5.51,8.998 8.018,9.652 6.644,16.822 -2.168,-1.12 -4.022,-2.238 -6.51,-2.394 l -0.58,0.476 c 1.212,3.574 5.104,5.87 8.18,7.788 l 0.106,0.944 c 2.112,1.702 5.154,3.652 6.672,5.856 l -0.092,0.576 c -1.6,-0.072 -10.62,-4.306 -6.686,-0.158 3.098,4.66401 7.5,8.32001 11.042,12.63001 1.028,1.378 2.036,2.636 2.66,4.248 l -0.342,0.572 c -2.3,-0.9 -3.438,-2.91 -5.976,-3.28 2.058,3.032 5.576,4.756 7.89,7.506 -6.846,-3.492 -13.43,-7.156 -19.826,-11.44 1.408,2.746 2.824,5.372 4.552,7.934 -0.206,1.33 -0.332,2.17 0,3.506 l -0.486,0.014 c -0.536,-6.728 -2.78,-4.58 -4.492,-8.664 -0.876,-2.09 -0.732,4.084 -0.79,5.038 l -0.504,0.106 c -1.038,2.206 -1.184,4.448 -1.462,6.838 -3.996,-3.73 -9.106,-6.404 -13.392,-9.86 1.374,-0.026 10.618,6.274 12.052,7.594 l 0.588,0.544 c 0.038,-7.076 -1.66,-12.922 -8.058,-15.766 l -0.276,-0.808 c 1.184,0.176 3.7,2.69 4.754,3.524 -1.57,-16.19201 -6.668,-17.95401 -15.372,-31.30601 -8.38,-12.854 -23.376,-43.43601 -22.744,-58.36601 0.294,-0.982 0.308,-1.814 0.212,-2.84 10.33,8.248 15.84,18.246 28.126,27.642 -0.088,-5.064 -1.526,-10.736 -2.462,-15.774 0.614,-23.334 -11.684,-42.03401 -11.934,-70.90801 1.27,-8.674 0.552,-26.22801 3.168,-33.15201 2.02,-0.768 3.486,-1.332 4.866,-3.024 l 0.976,-0.068 c 2.178,1.894 8.68,18.70601 9.84,22.36001 l 0.57,-0.518 c 1.386,0.9 2.382,2.54 3.39,3.858 1.862,-13.02001 6.618,-19.94201 9.452,-31.46801 3.608,-14.66 3.426,-26.278 9.076,-42.08001 1.844,-0.87 4.766,-8.314 5.944,-10.542 9.246,3.156 6.92,-0.208 4.17,11.186 l 0.192,0.106 -0.41,0.728 0.244,-0.106 c 1.028,-4.08 3.034,-8.04 4.67,-11.914 0.6,-3.108 1.304,-7.516 4.174,-9.192 0.93,7.21 1.644,14.442 2.54,21.656 1.148,-2.524 1.142,-5.15 2.088,-7.614 8.798,-9.326 16.32,-19.906 24.89,-29.486 4.756,-5.318 10.938,-9.912 15.132,-15.63401 4.15,-5.656 5.632,-12.712 10.296,-18.166 9.088,-3.418 4.138,-28.214 26.708,-18.13 2.074,4.474 -2.57,9.344 -1.244,14.208 v 2.354 c 3.582,-3.148 6.998,-5.586 11.174,-7.91 v 0 c 0.246,0.008 69.236,-30.86201 77.75,-34.60401 z"
|
||||
id="path66"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 182.19375,266.87369 c 0.564,-0.782 2.61,-7.412 3.094,-3.452 0.322,2.642 1.102,21.51 -3.094,19.486 -0.152,-5.29 -0.606,-10.77 0,-16.034 z"
|
||||
id="path67"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 125.81775,310.5497 c 2.45,2.318 5.498,11.792 7.544,15.398 2.698,4.748 6.998,5.738 5.39,11.534 l -0.768,0.906 -0.92,-0.342 c -4.658,-6.078 -8.65,-19.842 -11.246,-27.496 z"
|
||||
id="path68"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 238.02975,204.78568 c 5.564,-5.62 15.092,-21.80401 23.426,-22.17401 -1.03,1.272 -5.95,6.208 -5.208,7.716 -1.792,1.966 -4.054,3.62801 -5.628,5.75201 -3.67,1.584 -4.516,5.316 -6.108,8.706 2.69,-0.91 5.97,-2.338 8.79,-2.506 -1.89,1.25 -12.68,4.234 -15.272,4.588 v 0 z"
|
||||
id="path69"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 295.69975,180.57167 h 2.702 c -8.5,7.116 -21.784,5.136 -31.99,7.612 -3.338,1.062 -6.97,1.058 -10.164,2.144 -0.742,-1.508 4.178,-6.444 5.208,-7.716 1.96,-1.942 7.53,-0.964 9.782,0 8.094,-2.064 16.232,-1.644 24.462,-2.04 z"
|
||||
id="path70"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 261.45575,182.61167 c 1.96,-1.942 7.53,-0.964 9.782,0 -9.012,0.558 -6.586,5.252 -4.826,5.572 -3.338,1.062 -6.97,1.058 -10.164,2.144 -0.742,-1.508 4.178,-6.444 5.208,-7.716 z"
|
||||
id="path71"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#bf8a24"
|
||||
d="m 200.03575,242.78168 c 1.124,1.468 1.626,2.97 2.234,4.704 v 0 c -0.316,5.61801 1.456,4.99401 6.442,4.89801 -1.14,1.822 -2.366,3.564 -3.62,5.31 -1.95,2.246 -3.464,4.796 -5.056,7.3 -3.182,5.058 -6.5,9.462 -10.092,14.184 l -0.804,0.272 c 0.992,-2.136 -0.112,-2.814 -0.734,-4.852 -1.902,-6.224 8.246,-26.224 11.63,-31.81601 z"
|
||||
id="path72"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 202.26975,247.48568 v 0 c -0.316,5.61801 1.456,4.99401 6.442,4.89801 -1.14,1.822 -2.366,3.564 -3.62,5.31 -1.95,2.246 -3.464,4.796 -5.056,7.3 -0.992,-6.32 1.244,-11.428 2.234,-17.50801 z"
|
||||
id="path73"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 298.40175,180.57167 -0.042,1.276 c -7.05,4.88 -18.516,5.498 -27.53,13.56001 -1.344,1.2 -2.83,2.678 -4.418,3.494 -4.23,1.326 -8.724,2.754 -13.11,3.378 -2.82,0.168 -6.1,1.596 -8.79,2.506 1.592,-3.39 2.438,-7.122 6.108,-8.706 1.574,-2.124 3.836,-3.78601 5.628,-5.75201 3.194,-1.086 6.826,-1.082 10.164,-2.144 10.206,-2.476 23.49,-0.496 31.99,-7.612 z"
|
||||
id="path74"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 271.23775,193.48968 c -1.194,1.158 -4.558,3.824 -4.826,5.412 -4.23,1.326 -8.724,2.754 -13.11,3.378 -2.82,0.168 -6.1,1.596 -8.79,2.506 1.592,-3.39 2.438,-7.122 6.108,-8.706 6.902,-0.504 13.82,-1.276 20.618,-2.59 z"
|
||||
id="path75"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 149.29975,466.26772 c -9.304,-9.342 -10.01,-43.218 -10.518,-57.68401 -0.538,-15.364 -1.234,-63.88401 4.522,-71.25001 l 0.256,0.428 -0.55,-0.498 c 0.858,0.034 1.536,1.384 3.084,1.57 -0.638,1.076 -2.192,1.04 -2.766,2.208 -3.374,6.87 -7.36,60.42401 -3.304,71.67401 l 1.144,0.50401 0.542,-0.48001 c -0.028,-1.786 0.016,-3.3 0.432,-5.04 v 6.18601 l 5.696,5.592 -0.786,0.856 c 0.296,2.89 2.728,6.41 -0.85,8.024 -1.37,-0.752 -2.74,-1.49 -4.06,-2.326 1.508,3.706 4.194,6.776 5.696,10.326 -5.51,8.998 8.018,9.652 6.644,16.822 -2.168,-1.12 -4.022,-2.238 -6.51,-2.394 l -0.58,0.476 c 1.212,3.574 5.104,5.87 8.18,7.788 l 0.106,0.944 c 2.112,1.702 5.154,3.652 6.672,5.856 l -0.092,0.576 c -1.6,-0.072 -10.62,-4.306 -6.686,-0.158 3.098,4.66401 7.5,8.32001 11.042,12.63001 1.028,1.378 2.036,2.636 2.66,4.248 l -0.342,0.572 c -2.3,-0.9 -3.438,-2.91 -5.976,-3.28 2.058,3.032 5.576,4.756 7.89,7.506 -6.846,-3.492 -13.43,-7.156 -19.826,-11.44 1.408,2.746 2.824,5.372 4.552,7.934 -0.206,1.33 -0.332,2.17 0,3.506 l -0.486,0.014 c -0.536,-6.728 -2.78,-4.58 -4.492,-8.664 -0.876,-2.09 -0.732,4.084 -0.79,5.038 l -0.504,0.106 c 0.334,-4.398 -0.07,-7.204 1.72,-11.458 -1.008,-2.202 -1.76,-4.234 -1.72,-6.71201 z"
|
||||
id="path76"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 149.29975,466.26772 c 2.55,1.562 4.34,4.17401 5.39,6.94401 l -0.242,0.898 c -1.33,0.158 -2.298,-0.53 -3.428,-1.13 -1.008,-2.202 -1.76,-4.234 -1.72,-6.71201 z"
|
||||
id="path77"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 234.59975,171.88167 c 9.088,-3.418 4.138,-28.214 26.708,-18.13 2.074,4.474 -2.57,9.344 -1.244,14.208 v 2.354 c -1.148,1.816 -5.864,3.458 -7.922,4.874 -14.14,9.736 -15.23,14.912 -24.894,26.40001 -6.982,8.3 -15.26,15.5 -22.134,23.932 -11.878,14.576 -27.774,39.38201 -41.434,51.23801 0.79,-11.36 12.096,-43.94801 11.8,-46.44001 0.6,-3.108 1.304,-7.516 4.174,-9.192 0.93,7.21 1.644,14.442 2.54,21.656 1.148,-2.524 1.142,-5.15 2.088,-7.614 8.798,-9.326 16.32,-19.906 24.89,-29.486 4.756,-5.318 10.938,-9.912 15.132,-15.63401 4.15,-5.656 5.632,-12.712 10.296,-18.166 z"
|
||||
id="path78"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#bf8a24"
|
||||
d="m 306.53575,171.88167 -6.764,-0.428 1.672,-0.284 c -6.714,-7.61 17.512,-9.466 21.164,-11.206 6.186,-2.944 8.754,-8.358 16.164,-11.038 -2.502,2.67 -10.852,4.99 -2.406,7.588 l -0.286,0.044 c 2.342,0.576 6.822,-0.49 7.562,0.282 11.012,-0.444 21.382,3.234 32.396,2.412 -3.822,-2.582 -9.28,-3.286 -13.692,-4.562 l 0.166,-0.49 c 4.176,-1.344 9.568,0.502 13.526,-1.328 2.99,-0.914 6.34,-0.822 9.44,-1.264 43.72,19.62 46.344,31.682 19.526,73.22601 v 0 c -1.554,2.762 -3.848,7.304 -4.686,10.42 l -0.256,0.984 -0.8,0.356 c -0.148,-6.828 6.032,-14.334 5.742,-19.654 3.41,-15.986 -69.354,5.438 -83.98,12.018 -112.918,50.79001 -146.822,194.80204 -68.622,289.88605 2.912,3.538 9.012,12.78601 14.01,12.81601 5.634,0.72 11.242,1.612 16.884,2.268 -0.202,-4.49 -5.588,-11.15401 -7.948,-15.01601 l 0.744,-0.738 c 0.012,-2.102 -1.516,-3.748 -1.268,-5.77 l 0.892,-0.308 c 1.028,2.482 1.052,5.254 3.65,6.816 1.536,3.252 4.578,6.77601 6.57,9.84601 4.044,-3.966 8.118,-7.76801 12.466,-11.40401 1.258,-0.768 2.186,-1.952 3.172,-3.032 1.292,-8.566 1.428,-17.722 1.922,-26.378 -0.138,-1.118 -0.616,-2.868 -0.238,-3.908 l 1.168,0.966 -0.246,-0.612 -0.924,0.544 1.134,-0.23 c 3.66,6.196 9.036,11.464 13.456,17.124 20.682,-19.848 -7.462,-45.92001 -22.146,-59.30801 8.322,2.714 22.978,21.546 26.672,29.42201 2.368,5.048 2.81,14.832 4.236,17.488 3.938,-9.238 -6.242,-21.60201 -4.594,-23.16201 6.228,12.53801 9.19,23.92001 0,35.56001 -11.034,9.136 -29.284,21.156 -36.122,33.99601 -15.95,29.946 -3.004,58.48801 7.948,85.92401 1.766,3.338 5.028,8.098 5.668,11.75001 h -1.106 l -7.45,-10.00201 c -1.728,-2.178 -3.5,-4.33 -5.016,-6.664 -6.324,-4.728 -13.836,-10.324 -21.092,-13.49 -1.626,-0.89 -3.196,-1.934 -4.78,-2.904 -1.312,-1.568 -4.878,-2.91 -6.762,-3.614 -4.274,-4.488 -9.078,-8.416 -13.794,-12.424 -3.644,-3.258 -7.338,-6.40601 -11.126,-9.49601 -9.516,-10.912 -20.848,-17.964 -34.05,-23.62 -3.398,0.208 -6.702,-1.566 -10.05,-2.2 -3.33,-5.012 3.684,-2.256 6.652,-2.44 l 0.66,-0.048 c -1.778,-0.832 -2.898,-1.432 -3.716,-3.304 l 1.262,-2.344 h -1.262 c -2.998,-1.264 -4.654,-5.114 -7.29,-7.02 -3.114,-2.442 -5.858,-6.428 -8.34,-9.526 -7.37,-9.20401 15.16,1.224 16.892,1.472 -1.776,-4.28401 -4.174,-7.85601 -6.946,-11.55201 v 0 c -1.186,-3.19 -1.29,-6.316 -4.994,-7.248 0.668,0.008 0.234,0.036 1.274,-0.272 l -0.462,-1.048 c -0.872,-0.626 -1.716,-1.272 -2.532,-1.97 -2.314,-1.318 -4.576,-1.42 -7.188,-1.558 l 0.348,-0.398 c -4.896,-4.894 -10.688,-6.678 -13.068,-13.884 -0.332,-1.336 -0.206,-2.176 0,-3.506 -1.728,-2.562 -3.144,-5.188 -4.552,-7.934 6.396,4.284 12.98,7.948 19.826,11.44 -2.314,-2.75 -5.832,-4.474 -7.89,-7.506 2.538,0.37 3.676,2.38 5.976,3.28 l 0.342,-0.572 c -0.624,-1.612 -1.632,-2.87 -2.66,-4.248 -3.542,-4.31 -7.944,-7.966 -11.042,-12.63001 -3.934,-4.148 5.086,0.086 6.686,0.158 l 0.092,-0.576 c -1.518,-2.204 -4.56,-4.154 -6.672,-5.856 l -0.106,-0.944 c -3.076,-1.918 -6.968,-4.214 -8.18,-7.788 l 0.58,-0.476 c 2.488,0.156 4.342,1.274 6.51,2.394 1.374,-7.17 -12.154,-7.824 -6.644,-16.822 -1.502,-3.55 -4.188,-6.62 -5.696,-10.326 1.32,0.836 2.69,1.574 4.06,2.326 3.578,-1.614 1.146,-5.134 0.85,-8.024 l 0.786,-0.856 -5.696,-5.592 v -6.18601 c 1.882,1.082 3.774,2.134 5.696,3.148 2.812,-0.066 -2.302,-7.952 -2.684,-9.412 -2.64,-10.138 -2.074,-19.934 1.048,-30.034 3.832,5.794 5.078,12.906 9.37,18.494 0.712,-12.252 -3.732,-16.226 -6.272,-27.338 0.024,1.614 -0.016,2.56 -0.998,3.888 l -1.026,0.056 c -4.328,-4.398 1.136,-23.06401 2.024,-29.02001 0.876,-1.352 0.326,-3.882 1.568,-4.852 l 0.152,2.372 c 1.97,-6.784 0.63,-13.124 1.634,-19.682 0.592,-3.874 3.912,-9.128 5.378,-12.93801 1.064,3.29801 2.95,26.50601 5.008,35.10001 0.6,-13.1 1.002,-26.334 0.64,-39.44401 1.256,-2.66 2.634,-4.674 4.96,-6.498 1.274,-3.458 -0.992,-8.336 1.82,-11.414 1.332,2.548 0.968,5.34 1.658,8.056 l 0.172,0.658 c 2.028,-7.658 5.626,-15.308 9.904,-21.966 -0.606,5.264 -0.152,10.744 0,16.034 0.094,2.884 0.062,5.748 0,8.632 2.508,-3.846 4.092,-8.608 6.946,-12.09 l 0.804,-0.272 c 3.592,-4.722 6.91,-9.126 10.092,-14.184 1.592,-2.504 3.106,-5.054 5.056,-7.3 1.254,-1.746 2.48,-3.488 3.62,-5.31 -4.986,0.096 -6.758,0.72 -6.442,-4.89801 v 0 c -0.608,-1.734 -1.11,-3.236 -2.234,-4.704 0.074,-2.436 3.196,-4.674 5.056,-5.82 1.996,-2.358 2.592,-6.384 6.472,-5.164 5.168,-5.012 8.8,-14.116 16.818,-14.858 0.326,-3.532 2.758,-15.804 7.368,-15.872 l 2.28,3.718 v 2.082 0 c 2.592,-0.354 13.382,-3.338 15.272,-4.588 4.386,-0.624 8.88,-2.052 13.11,-3.378 1.588,-0.816 3.074,-2.294 4.418,-3.494 9.014,-8.06201 20.48,-8.68001 27.53,-13.56001 l 0.042,-1.276 h -2.702 c -7.65,-3.338 -12.068,0.834 -18.448,-0.768 11.644,-3.204 15.88,-5.512 29.284,-7.922 z"
|
||||
id="path79"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 154.48175,356.6817 c 1.552,0.2 3.084,0.076 4.642,0 -0.404,2.63801 -0.692,5.29001 -1.092,7.92601 -1.188,-2.608 -2.544,-5.248 -3.55,-7.92601 z"
|
||||
id="path80"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 159.12375,442.51972 c 0.384,2.614 0.992,5.194 1.546,7.778 -3.03,-2.766 -6.444,-5.21 -9.65,-7.778 l 0.538,0.054 c 2.192,0.234 4.934,1.556 6.996,1.18 z"
|
||||
id="path81"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 175.47975,498.19573 c 0.814,1.764 4.086,6.738 0,5.588 -2.314,-1.318 -4.576,-1.42 -7.188,-1.558 l 0.348,-0.398 c 2.21,-2.024 4.874,-1.53 6.84,-3.632 z"
|
||||
id="path82"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#ad7214"
|
||||
d="m 155.57175,466.26772 c 9.084,-1.716 12.038,4.78201 11.562,12.49601 l -0.52,0.134 c -3.542,-4.31 -7.944,-7.966 -11.042,-12.63001 z"
|
||||
id="path83"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 155.57175,459.04972 c -3.076,-1.918 -6.968,-4.214 -8.18,-7.788 l 0.58,-0.476 c 2.488,0.156 4.342,1.274 6.51,2.394 2.566,1.4 4.326,3.672 6.188,5.87 1.02,1.764 1.71,3.5 2.37,5.424 -2.364,-1.688 -4.912,-4.152 -7.468,-5.424 z"
|
||||
id="path84"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 180.58775,533.92774 c -3.114,-2.442 -5.858,-6.428 -8.34,-9.526 -7.37,-9.20401 15.16,1.224 16.892,1.472 6.636,13.13 -9.994,0.33 -16.85,-2.24 3.11,3.16 6.322,6.268 8.298,10.294 z"
|
||||
id="path85"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 266.41175,531.65974 c 5.634,0.72 11.242,1.612 16.884,2.268 -0.584,3.624 -3.86,8.832 -5.208,12.668 -3.562,-5.308 -7.8,-9.892 -11.676,-14.936 z"
|
||||
id="path86"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 142.14175,426.03172 c 1.32,0.836 2.69,1.574 4.06,2.326 4.29,3.432 12.174,7.82 12.862,13.616 l 0.06,0.546 -0.57,1.234 c -2.062,0.376 -4.804,-0.946 -6.996,-1.18 l -0.538,-0.054 c -1,-2.096 -2.014,-4.15 -3.182,-6.162 -1.502,-3.55 -4.188,-6.62 -5.696,-10.326 z"
|
||||
id="path87"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 142.14175,407.69971 c 1.882,1.082 3.774,2.134 5.696,3.148 3.018,1.372 5.362,4.13001 7.734,6.39601 0.206,2.976 0.198,5.812 0,8.788 -2.638,-2.122 -5.196,-4.312 -7.734,-6.554 l -5.696,-5.592 z"
|
||||
id="path88"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 155.57175,484.43773 c 2.938,2.218 18.9,12.614 19.908,13.758 -1.966,2.102 -4.63,1.608 -6.84,3.632 -4.896,-4.894 -10.688,-6.678 -13.068,-13.884 -0.332,-1.336 -0.206,-2.176 0,-3.506 z"
|
||||
id="path89"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 303.49575,487.94373 c -0.138,-1.118 -0.616,-2.868 -0.238,-3.908 l 1.168,0.966 -0.246,-0.612 -0.924,0.544 1.134,-0.23 c 3.66,6.196 9.036,11.464 13.456,17.124 -2.234,2.422 -5.066,4.484 -7.648,6.516 -1.722,-5.352 -6.16,-14.438 -4.026,-19.786 l -0.84,-0.608 c -0.8,1.028 -0.922,2.05 -1.224,3.294 z"
|
||||
id="path90"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#f1be39"
|
||||
d="m 343.64175,156.83967 c 11.012,-0.444 21.382,3.234 32.396,2.412 v 0 c 2.758,1.782 6.394,1.874 9.44,3.152 -10.682,1.228 -39.754,-2.68 -41.606,-1.904 0.806,1.616 2.88,2.336 4.224,3.502 l -1.41,0.542 0.34,0.15 -1.298,-0.124 c -4.908,-6.008 -9.214,-5.39 -10.248,-6.48 2.774,-0.232 5.512,-0.324 8.162,-1.25 z"
|
||||
id="path91"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 376.03775,152.87167 c 2.99,-0.914 6.34,-0.822 9.44,-1.264 43.72,19.62 46.344,31.682 19.526,73.22601 v 0 c 5.832,-22.874 34.842,-43.05801 -2.732,-64.07601 -11.18,-6.254 -18.164,-10.16 -31.452,-6.352 l -0.424,1.2 -0.404,-0.834 c 3.842,4.244 26.77,7.59 30.22,14.342 -1.308,0.37 -18.904,-9.996 -23.724,-10.5 l -0.45,0.638 v 0 c -3.822,-2.582 -9.28,-3.286 -13.692,-4.562 l 0.166,-0.49 c 4.176,-1.344 9.568,0.502 13.526,-1.328 z"
|
||||
id="path92"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 168.63975,291.53969 c 1.274,-3.458 -0.992,-8.336 1.82,-11.414 1.332,2.548 0.968,5.34 1.658,8.056 l 0.172,0.658 c 2.774,10.994 2.712,19.95201 -1.444,30.43201 -1.604,-9.654 -3.796,-17.92201 -2.206,-27.73201 z"
|
||||
id="path93"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 149.29975,337.4817 c 0.876,-1.352 0.326,-3.882 1.568,-4.852 l 0.152,2.372 c 1.894,5.472 9.814,16.574 8.104,21.68 -1.558,0.076 -3.09,0.2 -4.642,0 -1.126,-2.77 -2.134,-5.716 -3.462,-8.39 -1.878,5.094 -2.658,8.81 -1.72,14.26601 0.024,1.614 -0.016,2.56 -0.998,3.888 l -1.026,0.056 c -4.328,-4.398 1.136,-23.06401 2.024,-29.02001 z"
|
||||
id="path94"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 306.53575,171.88167 -6.764,-0.428 1.672,-0.284 c -6.714,-7.61 17.512,-9.466 21.164,-11.206 6.186,-2.944 8.754,-8.358 16.164,-11.038 -2.502,2.67 -10.852,4.99 -2.406,7.588 l -0.286,0.044 c 2.342,0.576 6.822,-0.49 7.562,0.282 -2.65,0.926 -5.388,1.018 -8.162,1.25 1.034,1.09 5.34,0.472 10.248,6.48 -3.348,-0.918 -27.976,0.078 -32.714,1.348 4.33,2.232 9.916,1.048 14.594,3.258 l 0.012,0.634 c -3.474,2.758 -16.412,2.3 -21.084,2.072 z"
|
||||
id="path95"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#ad7214"
|
||||
d="m 187.87775,540.94774 c 14.452,-1.578 18.17,9.438 25.354,17.744 17.95,20.75601 34.99,32.52001 57.314,46.64401 2.982,1.888 11.55,9.15 14.164,9.758 -0.954,-3.75 -7.964,-27.508 -9.222,-29.136 -2.72,-3.514 -11.288,-7.96801 -15.268,-11.09401 -12.18,-9.558 -46.938,-41.988 -52.316,-57.27201 l 0.808,-0.238 c 9.448,21.46801 48.068,54.83801 66.636,67.04602 1.412,2.178 10.994,29.386 10.588,32.432 -6.324,-4.728 -13.836,-10.324 -21.092,-13.49 -1.626,-0.89 -3.196,-1.934 -4.78,-2.904 -1.312,-1.568 -4.878,-2.91 -6.762,-3.614 -4.274,-4.488 -9.078,-8.416 -13.794,-12.424 -3.644,-3.258 -7.338,-6.40601 -11.126,-9.49601 -9.516,-10.912 -20.848,-17.964 -34.05,-23.62 -3.398,0.208 -6.702,-1.566 -10.05,-2.2 -3.33,-5.012 3.684,-2.256 6.652,-2.44 l 0.66,-0.048 c -1.778,-0.832 -2.898,-1.432 -3.716,-3.304 l 1.262,-2.344 z"
|
||||
id="path96"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 189.13975,540.94774 c 5.534,2.624 11.97,2.904 15.952,8.136 -3.688,-0.196 -7.236,-1.452 -10.76,-2.488 h -2.738 c -1.778,-0.832 -2.898,-1.432 -3.716,-3.304 z"
|
||||
id="path97"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 184.28175,549.08374 c -3.33,-5.012 3.684,-2.256 6.652,-2.44 l 0.66,-0.048 h 2.738 c 3.524,1.036 7.072,2.292 10.76,2.488 1.886,2.01 3.24,4.586 4.692,6.922 -3.318,-1.236 -12.546,-5.238 -15.452,-4.722 v 0 c -3.398,0.208 -6.702,-1.566 -10.05,-2.2 z"
|
||||
id="path98"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e7aa1f"
|
||||
d="m 184.28175,549.08374 c -3.33,-5.012 3.684,-2.256 6.652,-2.44 l 0.66,-0.048 h 2.738 c -4.344,0.788 -4.744,0.478 -1.17,2.97 l -0.606,-0.004 c -4.844,0.006 -0.282,1.608 1.776,1.722 v 0 c -3.398,0.208 -6.702,-1.566 -10.05,-2.2 z"
|
||||
id="path99"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 228.38175,216.93968 c 0.326,-3.532 2.758,-15.804 7.368,-15.872 l 2.28,3.718 v 2.082 0 c -6.518,12.316 13.27,-2.088 15.158,-2.352 -0.618,2.432 -27.42,25.384 -31.64,31.524 -3.73,5.426 -11.42,18.06801 -16.456,21.65401 1.254,-1.746 2.48,-3.488 3.62,-5.31 -4.986,0.096 -6.758,0.72 -6.442,-4.89801 v 0 c -0.608,-1.734 -1.11,-3.236 -2.234,-4.704 0.074,-2.436 3.196,-4.674 5.056,-5.82 1.996,-2.358 2.592,-6.384 6.472,-5.164 5.168,-5.012 8.8,-14.116 16.818,-14.858 z"
|
||||
id="path100"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 232.69375,222.27368 v 0 c -2.516,5.136 -7.8,8.384 -11.258,12.894 0.908,-3.178 1.606,-7.628 3.46,-10.334 2.71,0.164 5.344,-1.512 7.798,-2.56 z"
|
||||
id="path101"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#e4c267"
|
||||
d="m 205.09175,236.96168 c 1.996,-2.358 2.592,-6.384 6.472,-5.164 -1.882,3.976 -3.154,7.958 -2.26,12.41 l 0.746,0.966 c 1.808,0.074 2.558,-0.808 4.2,-1.294 -0.568,2.526 -3.898,6.34801 -5.538,8.50401 -4.986,0.096 -6.758,0.72 -6.442,-4.89801 v 0 c -0.608,-1.734 -1.11,-3.236 -2.234,-4.704 0.074,-2.436 3.196,-4.674 5.056,-5.82 z"
|
||||
id="path102"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#d6991c"
|
||||
d="m 200.03575,242.78168 c 0.074,-2.436 3.196,-4.674 5.056,-5.82 -1.032,3.436 -2.298,6.974 -2.822,10.524 v 0 c -0.608,-1.734 -1.11,-3.236 -2.234,-4.704 z"
|
||||
id="path103"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 228.38175,216.93968 c 0.326,-3.532 2.758,-15.804 7.368,-15.872 l 2.28,3.718 v 2.082 c -1.486,1.796 -3.142,3.526 -3.43,5.944 4.566,-0.902 8.72,-2.206 13.04,-3.914 -4.882,4.584 -9.786,9.102 -14.946,13.376 v 0 c -2.454,1.048 -5.088,2.724 -7.798,2.56 0.764,-2.614 2.36,-5.384 3.486,-7.894 z"
|
||||
id="path104"
|
||||
style="stroke-width:2" />
|
||||
<path
|
||||
fill="#fade6b"
|
||||
d="m 358.50775,173.44367 c 18.416,-4.38 53.464,-10.342 55.298,16.884 -24.86,0.57 -35.762,0.938 -60.484,4.82201 l -0.202,-0.514 c 1.278,-0.93 3.428,-0.886 4.184,-1.712 6.046,-6.58801 1.738,-6.33201 2.402,-12.86401 0.52,-5.102 6.456,-5.5 -0.302,-6.478 z"
|
||||
id="path105"
|
||||
style="stroke-width:2" />
|
||||
<defs
|
||||
id="defs106">
|
||||
<linearGradient
|
||||
id="gradient_7"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="141.16791"
|
||||
y1="268.56354"
|
||||
x2="265.50784"
|
||||
y2="226.48077"
|
||||
gradientTransform="matrix(2,0,0,2.0000004,-111.74825,-110.67438)">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#E1AF37"
|
||||
id="stop105" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#FCDE74"
|
||||
id="stop106" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
fill="url(#gradient_7)"
|
||||
d="m 208.71175,517.35373 c -86.018,-118.12402 -12.156,-301.82605 129.714,-339.49006 6.44,-1.71 13.438,-3.836 20.082,-4.42 l 0.896,0.138 c 6.758,0.978 0.822,1.376 0.302,6.478 -0.664,6.532 3.644,6.276 -2.402,12.86401 -0.756,0.826 -2.906,0.782 -4.184,1.712 l 0.202,0.514 c -12.89,3.57 -25.456,7.312 -37.754,12.642 -137.6,59.63401 -168.028,233.46204 -63.62,337.58006 7.44,7.418 16.184,13.6 23.4,21.124 0.094,5.944 0.338,11.96801 0,17.90401 -18.568,-12.20801 -57.188,-45.57801 -66.636,-67.04602 z"
|
||||
id="path106"
|
||||
style="fill:url(#gradient_7);stroke-width:2" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 57 KiB |
@ -1,38 +1,30 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/js-md5@0.8.3/src/md5.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/moment@2.29.4/moment.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/daterangepicker@3.1.0/daterangepicker.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/tableexport.jquery.plugin@1.28.0/tableExport.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/tableexport.jquery.plugin@1.30.0/tableExport.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/bootstrap-table.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.23.2/dist/bootstrap-table.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/extensions/export/bootstrap-table-export.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/extensions/resizable/bootstrap-table-resizable.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/extensions/filter-control/bootstrap-table-filter-control.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.23.2/dist/extensions/export/bootstrap-table-export.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.23.2/dist/extensions/resizable/bootstrap-table-resizable.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.23.2/dist/extensions/filter-control/bootstrap-table-filter-control.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/highlight.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@easepick/bundle@1.2.1/dist/index.umd.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.10.0/build/highlight.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.4/dist/chart.umd.min.js" crossorigin="anonymous" type="application/javascript"></script>
|
||||
|
||||
<script>
|
||||
async function copyToClipboard(text, button) {
|
||||
if (navigator.clipboard === undefined) {
|
||||
const input = document.createElement("textarea");
|
||||
input.innerHTML = text;
|
||||
document.body.appendChild(input);
|
||||
input.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(input);
|
||||
} else {
|
||||
await navigator.clipboard.writeText(text);
|
||||
}
|
||||
|
||||
button.html("<i class=\"bi bi-clipboard-check\"></i> copied");
|
||||
setTimeout(()=> {
|
||||
button.html("<i class=\"bi bi-clipboard\"></i> copy");
|
||||
await navigator.clipboard.writeText(text);
|
||||
button.innerHTML = "<i class=\"bi bi-clipboard-check\"></i> copied";
|
||||
setTimeout(_ => {
|
||||
button.innerHTML = "<i class=\"bi bi-clipboard\"></i> copy";
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
@ -73,6 +65,47 @@
|
||||
.join("<br>");
|
||||
}
|
||||
|
||||
function makeRequest(url, params, onSuccess, onFailure) {
|
||||
const requestParams = {
|
||||
method: params.method,
|
||||
body: params.json ? JSON.stringify(params.json) : params.json,
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
};
|
||||
if (params.query) {
|
||||
const query = new URLSearchParams(params.query);
|
||||
url += `?${query.toString()}`;
|
||||
}
|
||||
const convert = params.convert ?? (response => response.text());
|
||||
|
||||
return fetch(url, requestParams)
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
return convert(response);
|
||||
} else {
|
||||
const error = new Error("Network request error");
|
||||
error.status = response.status;
|
||||
error.statusText = response.statusText;
|
||||
return response.text().then(text => {
|
||||
error.text = text;
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
})
|
||||
.then(data => onSuccess && onSuccess(data))
|
||||
.catch(error => onFailure && onFailure(error));
|
||||
}
|
||||
|
||||
function ready(fn) {
|
||||
if (document.readyState === "complete" || document.readyState === "interactive") {
|
||||
setTimeout(fn, 1);
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", fn);
|
||||
}
|
||||
}
|
||||
|
||||
function safe(string) {
|
||||
return String(string)
|
||||
.replace(/&/g, "&")
|
||||
@ -86,7 +119,9 @@
|
||||
const element = document.createElement("a");
|
||||
element.href = url;
|
||||
element.innerText = text;
|
||||
if (title) element.title = title;
|
||||
if (title) {
|
||||
element.title = title;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,15 @@
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" crossorigin="anonymous" type="text/css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" crossorigin="anonymous" type="text/css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css" crossorigin="anonymous" type="text/css">
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/bootstrap-table.min.css" crossorigin="anonymous" type="text/css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-table@1.23.2/dist/bootstrap-table.min.css" crossorigin="anonymous" type="text/css">
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery-resizable-columns@0.2.3/dist/jquery.resizableColumns.css" crossorigin="anonymous" type="text/css">
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-table@1.22.1/dist/extensions/filter-control/bootstrap-table-filter-control.css" crossorigin="anonymous" type="text/css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-table@1.23.2/dist/extensions/filter-control/bootstrap-table-filter-control.css" crossorigin="anonymous" type="text/css">
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootswatch@5.3.2/dist/cosmo/bootstrap.min.css" crossorigin="anonymous" type="text/css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootswatch@5.3.3/dist/cosmo/bootstrap.min.css" crossorigin="anonymous" type="text/css">
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/daterangepicker@3.1.0/daterangepicker.css" crossorigin="anonymous" type="text/css">
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/styles/github.min.css" crossorigin="anonymous" type="text/css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.10.0/build/styles/github.min.css" crossorigin="anonymous" type="text/css">
|
||||
|
||||
<style>
|
||||
.pre-scrollable {
|
||||
|
@ -1,6 +1,6 @@
|
||||
# AUTOMATICALLY GENERATED by `shtab`
|
||||
|
||||
_shtab_ahriman_subparsers=('aur-search' 'search' 'help-commands-unsafe' 'help' 'help-updates' 'help-version' 'version' 'package-add' 'add' 'package-update' 'package-changes' 'package-changes-remove' 'package-remove' 'remove' 'package-status' 'status' 'package-status-remove' 'package-status-update' 'status-update' 'patch-add' 'patch-list' 'patch-remove' 'patch-set-add' 'repo-backup' 'repo-check' 'check' 'repo-create-keyring' 'repo-create-mirrorlist' 'repo-daemon' 'daemon' 'repo-rebuild' 'rebuild' 'repo-remove-unknown' 'remove-unknown' 'repo-report' 'report' 'repo-restore' 'repo-sign' 'sign' 'repo-status-update' 'repo-sync' 'sync' 'repo-tree' 'repo-triggers' 'repo-update' 'update' 'service-clean' 'clean' 'repo-clean' 'service-config' 'config' 'repo-config' 'service-config-validate' 'config-validate' 'repo-config-validate' 'service-key-import' 'key-import' 'service-repositories' 'service-run' 'run' 'service-setup' 'init' 'repo-init' 'repo-setup' 'setup' 'service-shell' 'shell' 'service-tree-migrate' 'user-add' 'user-list' 'user-remove' 'web')
|
||||
_shtab_ahriman_subparsers=('aur-search' 'search' 'help-commands-unsafe' 'help' 'help-updates' 'help-version' 'version' 'package-add' 'add' 'package-update' 'package-changes' 'package-changes-remove' 'package-remove' 'remove' 'package-status' 'status' 'package-status-remove' 'package-status-update' 'status-update' 'patch-add' 'patch-list' 'patch-remove' 'patch-set-add' 'repo-backup' 'repo-check' 'check' 'repo-create-keyring' 'repo-create-mirrorlist' 'repo-daemon' 'daemon' 'repo-rebuild' 'rebuild' 'repo-remove-unknown' 'remove-unknown' 'repo-report' 'report' 'repo-restore' 'repo-sign' 'sign' 'repo-statistics' 'repo-status-update' 'repo-sync' 'sync' 'repo-tree' 'repo-triggers' 'repo-update' 'update' 'service-clean' 'clean' 'repo-clean' 'service-config' 'config' 'repo-config' 'service-config-validate' 'config-validate' 'repo-config-validate' 'service-key-import' 'key-import' 'service-repositories' 'service-run' 'run' 'service-setup' 'init' 'repo-init' 'repo-setup' 'setup' 'service-shell' 'shell' 'service-tree-migrate' 'user-add' 'user-list' 'user-remove' 'web')
|
||||
|
||||
_shtab_ahriman_option_strings=('-h' '--help' '-a' '--architecture' '-c' '--configuration' '--force' '-l' '--lock' '--log-handler' '-q' '--quiet' '--report' '--no-report' '-r' '--repository' '--unsafe' '-V' '--version' '--wait-timeout')
|
||||
_shtab_ahriman_aur_search_option_strings=('-h' '--help' '-e' '--exit-code' '--info' '--no-info' '--sort-by')
|
||||
@ -10,9 +10,9 @@ _shtab_ahriman_help_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_help_updates_option_strings=('-h' '--help' '-e' '--exit-code')
|
||||
_shtab_ahriman_help_version_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_version_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_package_add_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '--increment' '--no-increment' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username' '-v' '--variable')
|
||||
_shtab_ahriman_add_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '--increment' '--no-increment' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username' '-v' '--variable')
|
||||
_shtab_ahriman_package_update_option_strings=('-h' '--help' '--dependencies' '--no-dependencies' '-e' '--exit-code' '--increment' '--no-increment' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username' '-v' '--variable')
|
||||
_shtab_ahriman_package_add_option_strings=('-h' '--help' '--changes' '--no-changes' '--dependencies' '--no-dependencies' '-e' '--exit-code' '--increment' '--no-increment' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username' '-v' '--variable')
|
||||
_shtab_ahriman_add_option_strings=('-h' '--help' '--changes' '--no-changes' '--dependencies' '--no-dependencies' '-e' '--exit-code' '--increment' '--no-increment' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username' '-v' '--variable')
|
||||
_shtab_ahriman_package_update_option_strings=('-h' '--help' '--changes' '--no-changes' '--dependencies' '--no-dependencies' '-e' '--exit-code' '--increment' '--no-increment' '-n' '--now' '-y' '--refresh' '-s' '--source' '-u' '--username' '-v' '--variable')
|
||||
_shtab_ahriman_package_changes_option_strings=('-h' '--help' '-e' '--exit-code')
|
||||
_shtab_ahriman_package_changes_remove_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_package_remove_option_strings=('-h' '--help')
|
||||
@ -42,6 +42,7 @@ _shtab_ahriman_report_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_repo_restore_option_strings=('-h' '--help' '-o' '--output')
|
||||
_shtab_ahriman_repo_sign_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_sign_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_repo_statistics_option_strings=('-h' '--help' '--chart' '-e' '--event' '--from-date' '--limit' '--offset' '--to-date')
|
||||
_shtab_ahriman_repo_status_update_option_strings=('-h' '--help' '-s' '--status')
|
||||
_shtab_ahriman_repo_sync_option_strings=('-h' '--help')
|
||||
_shtab_ahriman_sync_option_strings=('-h' '--help')
|
||||
@ -78,7 +79,7 @@ _shtab_ahriman_web_option_strings=('-h' '--help')
|
||||
|
||||
|
||||
|
||||
_shtab_ahriman_pos_0_choices=('aur-search' 'search' 'help-commands-unsafe' 'help' 'help-updates' 'help-version' 'version' 'package-add' 'add' 'package-update' 'package-changes' 'package-changes-remove' 'package-remove' 'remove' 'package-status' 'status' 'package-status-remove' 'package-status-update' 'status-update' 'patch-add' 'patch-list' 'patch-remove' 'patch-set-add' 'repo-backup' 'repo-check' 'check' 'repo-create-keyring' 'repo-create-mirrorlist' 'repo-daemon' 'daemon' 'repo-rebuild' 'rebuild' 'repo-remove-unknown' 'remove-unknown' 'repo-report' 'report' 'repo-restore' 'repo-sign' 'sign' 'repo-status-update' 'repo-sync' 'sync' 'repo-tree' 'repo-triggers' 'repo-update' 'update' 'service-clean' 'clean' 'repo-clean' 'service-config' 'config' 'repo-config' 'service-config-validate' 'config-validate' 'repo-config-validate' 'service-key-import' 'key-import' 'service-repositories' 'service-run' 'run' 'service-setup' 'init' 'repo-init' 'repo-setup' 'setup' 'service-shell' 'shell' 'service-tree-migrate' 'user-add' 'user-list' 'user-remove' 'web')
|
||||
_shtab_ahriman_pos_0_choices=('aur-search' 'search' 'help-commands-unsafe' 'help' 'help-updates' 'help-version' 'version' 'package-add' 'add' 'package-update' 'package-changes' 'package-changes-remove' 'package-remove' 'remove' 'package-status' 'status' 'package-status-remove' 'package-status-update' 'status-update' 'patch-add' 'patch-list' 'patch-remove' 'patch-set-add' 'repo-backup' 'repo-check' 'check' 'repo-create-keyring' 'repo-create-mirrorlist' 'repo-daemon' 'daemon' 'repo-rebuild' 'rebuild' 'repo-remove-unknown' 'remove-unknown' 'repo-report' 'report' 'repo-restore' 'repo-sign' 'sign' 'repo-statistics' 'repo-status-update' 'repo-sync' 'sync' 'repo-tree' 'repo-triggers' 'repo-update' 'update' 'service-clean' 'clean' 'repo-clean' 'service-config' 'config' 'repo-config' 'service-config-validate' 'config-validate' 'repo-config-validate' 'service-key-import' 'key-import' 'service-repositories' 'service-run' 'run' 'service-setup' 'init' 'repo-init' 'repo-setup' 'setup' 'service-shell' 'shell' 'service-tree-migrate' 'user-add' 'user-list' 'user-remove' 'web')
|
||||
_shtab_ahriman___log_handler_choices=('console' 'syslog' 'journald')
|
||||
_shtab_ahriman_aur_search___sort_by_choices=('description' 'first_submitted' 'id' 'last_modified' 'maintainer' 'name' 'num_votes' 'out_of_date' 'package_base' 'package_base_id' 'popularity' 'repository' 'submitter' 'url' 'url_path' 'version')
|
||||
_shtab_ahriman_search___sort_by_choices=('description' 'first_submitted' 'id' 'last_modified' 'maintainer' 'name' 'num_votes' 'out_of_date' 'package_base' 'package_base_id' 'popularity' 'repository' 'submitter' 'url' 'url_path' 'version')
|
||||
@ -100,6 +101,8 @@ _shtab_ahriman_repo_rebuild__s_choices=('unknown' 'pending' 'building' 'failed'
|
||||
_shtab_ahriman_repo_rebuild___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||
_shtab_ahriman_rebuild__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||
_shtab_ahriman_rebuild___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||
_shtab_ahriman_repo_statistics__e_choices=('package-outdated' 'package-removed' 'package-update-failed' 'package-updated')
|
||||
_shtab_ahriman_repo_statistics___event_choices=('package-outdated' 'package-removed' 'package-update-failed' 'package-updated')
|
||||
_shtab_ahriman_repo_status_update__s_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||
_shtab_ahriman_repo_status_update___status_choices=('unknown' 'pending' 'building' 'failed' 'success')
|
||||
_shtab_ahriman_service_setup___sign_target_choices=('disabled' 'packages' 'repository')
|
||||
@ -153,6 +156,8 @@ _shtab_ahriman_version___help_nargs=0
|
||||
_shtab_ahriman_package_add_pos_0_nargs=+
|
||||
_shtab_ahriman_package_add__h_nargs=0
|
||||
_shtab_ahriman_package_add___help_nargs=0
|
||||
_shtab_ahriman_package_add___changes_nargs=0
|
||||
_shtab_ahriman_package_add___no_changes_nargs=0
|
||||
_shtab_ahriman_package_add___dependencies_nargs=0
|
||||
_shtab_ahriman_package_add___no_dependencies_nargs=0
|
||||
_shtab_ahriman_package_add__e_nargs=0
|
||||
@ -166,6 +171,8 @@ _shtab_ahriman_package_add___refresh_nargs=0
|
||||
_shtab_ahriman_add_pos_0_nargs=+
|
||||
_shtab_ahriman_add__h_nargs=0
|
||||
_shtab_ahriman_add___help_nargs=0
|
||||
_shtab_ahriman_add___changes_nargs=0
|
||||
_shtab_ahriman_add___no_changes_nargs=0
|
||||
_shtab_ahriman_add___dependencies_nargs=0
|
||||
_shtab_ahriman_add___no_dependencies_nargs=0
|
||||
_shtab_ahriman_add__e_nargs=0
|
||||
@ -179,6 +186,8 @@ _shtab_ahriman_add___refresh_nargs=0
|
||||
_shtab_ahriman_package_update_pos_0_nargs=+
|
||||
_shtab_ahriman_package_update__h_nargs=0
|
||||
_shtab_ahriman_package_update___help_nargs=0
|
||||
_shtab_ahriman_package_update___changes_nargs=0
|
||||
_shtab_ahriman_package_update___no_changes_nargs=0
|
||||
_shtab_ahriman_package_update___dependencies_nargs=0
|
||||
_shtab_ahriman_package_update___no_dependencies_nargs=0
|
||||
_shtab_ahriman_package_update__e_nargs=0
|
||||
@ -348,6 +357,8 @@ _shtab_ahriman_repo_sign___help_nargs=0
|
||||
_shtab_ahriman_sign_pos_0_nargs=*
|
||||
_shtab_ahriman_sign__h_nargs=0
|
||||
_shtab_ahriman_sign___help_nargs=0
|
||||
_shtab_ahriman_repo_statistics__h_nargs=0
|
||||
_shtab_ahriman_repo_statistics___help_nargs=0
|
||||
_shtab_ahriman_repo_status_update__h_nargs=0
|
||||
_shtab_ahriman_repo_status_update___help_nargs=0
|
||||
_shtab_ahriman_repo_sync__h_nargs=0
|
||||
|
@ -1,9 +1,9 @@
|
||||
.TH AHRIMAN "1" "2024\-09\-04" "ahriman" "Generated Python Manual"
|
||||
.TH AHRIMAN "1" "2024\-09\-24" "ahriman" "Generated Python Manual"
|
||||
.SH NAME
|
||||
ahriman
|
||||
.SH SYNOPSIS
|
||||
.B ahriman
|
||||
[-h] [-a ARCHITECTURE] [-c CONFIGURATION] [--force] [-l LOCK] [--log-handler {console,syslog,journald}] [-q] [--report | --no-report] [-r REPOSITORY] [--unsafe] [-V] [--wait-timeout WAIT_TIMEOUT] {aur-search,search,help-commands-unsafe,help,help-updates,help-version,version,package-add,add,package-update,package-changes,package-changes-remove,package-remove,remove,package-status,status,package-status-remove,package-status-update,status-update,patch-add,patch-list,patch-remove,patch-set-add,repo-backup,repo-check,check,repo-create-keyring,repo-create-mirrorlist,repo-daemon,daemon,repo-rebuild,rebuild,repo-remove-unknown,remove-unknown,repo-report,report,repo-restore,repo-sign,sign,repo-status-update,repo-sync,sync,repo-tree,repo-triggers,repo-update,update,service-clean,clean,repo-clean,service-config,config,repo-config,service-config-validate,config-validate,repo-config-validate,service-key-import,key-import,service-repositories,service-run,run,service-setup,init,repo-init,repo-setup,setup,service-shell,shell,service-tree-migrate,user-add,user-list,user-remove,web} ...
|
||||
[-h] [-a ARCHITECTURE] [-c CONFIGURATION] [--force] [-l LOCK] [--log-handler {console,syslog,journald}] [-q] [--report | --no-report] [-r REPOSITORY] [--unsafe] [-V] [--wait-timeout WAIT_TIMEOUT] {aur-search,search,help-commands-unsafe,help,help-updates,help-version,version,package-add,add,package-update,package-changes,package-changes-remove,package-remove,remove,package-status,status,package-status-remove,package-status-update,status-update,patch-add,patch-list,patch-remove,patch-set-add,repo-backup,repo-check,check,repo-create-keyring,repo-create-mirrorlist,repo-daemon,daemon,repo-rebuild,rebuild,repo-remove-unknown,remove-unknown,repo-report,report,repo-restore,repo-sign,sign,repo-statistics,repo-status-update,repo-sync,sync,repo-tree,repo-triggers,repo-update,update,service-clean,clean,repo-clean,service-config,config,repo-config,service-config-validate,config-validate,repo-config-validate,service-key-import,key-import,service-repositories,service-run,run,service-setup,init,repo-init,repo-setup,setup,service-shell,shell,service-tree-migrate,user-add,user-list,user-remove,web} ...
|
||||
.SH DESCRIPTION
|
||||
ArcH linux ReposItory MANager
|
||||
|
||||
@ -134,6 +134,9 @@ restore repository data
|
||||
\fBahriman\fR \fI\,repo\-sign\/\fR
|
||||
sign packages
|
||||
.TP
|
||||
\fBahriman\fR \fI\,repo\-statistics\/\fR
|
||||
repository statistics
|
||||
.TP
|
||||
\fBahriman\fR \fI\,repo\-status\-update\/\fR
|
||||
update repository status
|
||||
.TP
|
||||
@ -248,7 +251,8 @@ usage: ahriman help\-version [\-h]
|
||||
print application and its dependencies versions
|
||||
|
||||
.SH COMMAND \fI\,'ahriman package\-add'\/\fR
|
||||
usage: ahriman package\-add [\-h] [\-\-dependencies | \-\-no\-dependencies] [\-e] [\-\-increment | \-\-no\-increment] [\-n] [\-y]
|
||||
usage: ahriman package\-add [\-h] [\-\-changes | \-\-no\-changes] [\-\-dependencies | \-\-no\-dependencies] [\-e]
|
||||
[\-\-increment | \-\-no\-increment] [\-n] [\-y]
|
||||
[\-s {auto,archive,aur,directory,local,remote,repository}] [\-u USERNAME] [\-v VARIABLE]
|
||||
package [package ...]
|
||||
|
||||
@ -259,6 +263,10 @@ add existing or new package to the build queue
|
||||
package source (base name, path to local files, remote URL)
|
||||
|
||||
.SH OPTIONS \fI\,'ahriman package\-add'\/\fR
|
||||
.TP
|
||||
\fB\-\-changes\fR, \fB\-\-no\-changes\fR
|
||||
calculate changes from the latest known commit if available
|
||||
|
||||
.TP
|
||||
\fB\-\-dependencies\fR, \fB\-\-no\-dependencies\fR
|
||||
process missing package dependencies
|
||||
@ -460,7 +468,7 @@ filter check by package base
|
||||
.SH OPTIONS \fI\,'ahriman repo\-check'\/\fR
|
||||
.TP
|
||||
\fB\-\-changes\fR, \fB\-\-no\-changes\fR
|
||||
calculate changes from the latest known commit if available. Only applicable in dry run mode
|
||||
calculate changes from the latest known commit if available
|
||||
|
||||
.TP
|
||||
\fB\-\-check\-files\fR, \fB\-\-no\-check\-files\fR
|
||||
@ -624,6 +632,43 @@ usage: ahriman repo\-sign [\-h] [package ...]
|
||||
\fBpackage\fR
|
||||
sign only specified packages
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-statistics'\/\fR
|
||||
usage: ahriman repo\-statistics [\-h] [\-\-chart CHART]
|
||||
[\-e {package\-outdated,package\-removed,package\-update\-failed,package\-updated}]
|
||||
[\-\-from\-date FROM_DATE] [\-\-limit LIMIT] [\-\-offset OFFSET] [\-\-to\-date TO_DATE]
|
||||
[package]
|
||||
|
||||
fetch repository statistics
|
||||
|
||||
.TP
|
||||
\fBpackage\fR
|
||||
fetch only events for the specified package
|
||||
|
||||
.SH OPTIONS \fI\,'ahriman repo\-statistics'\/\fR
|
||||
.TP
|
||||
\fB\-\-chart\fR \fI\,CHART\/\fR
|
||||
create updates chart and save it to the specified path
|
||||
|
||||
.TP
|
||||
\fB\-e\fR \fI\,{package\-outdated,package\-removed,package\-update\-failed,package\-updated}\/\fR, \fB\-\-event\fR \fI\,{package\-outdated,package\-removed,package\-update\-failed,package\-updated}\/\fR
|
||||
event type filter
|
||||
|
||||
.TP
|
||||
\fB\-\-from\-date\fR \fI\,FROM_DATE\/\fR
|
||||
only fetch events which are newer than the date
|
||||
|
||||
.TP
|
||||
\fB\-\-limit\fR \fI\,LIMIT\/\fR
|
||||
limit response by specified amount of events
|
||||
|
||||
.TP
|
||||
\fB\-\-offset\fR \fI\,OFFSET\/\fR
|
||||
skip specified amount of events
|
||||
|
||||
.TP
|
||||
\fB\-\-to\-date\fR \fI\,TO_DATE\/\fR
|
||||
only fetch events which are older than the date
|
||||
|
||||
.SH COMMAND \fI\,'ahriman repo\-status\-update'\/\fR
|
||||
usage: ahriman repo\-status\-update [\-h] [\-s {unknown,pending,building,failed,success}]
|
||||
|
||||
|
@ -48,6 +48,7 @@ _shtab_ahriman_commands() {
|
||||
"repo-restore:restore settings and database"
|
||||
"repo-setup:create initial service configuration, requires root"
|
||||
"repo-sign:(re-)sign packages and repository database according to current settings"
|
||||
"repo-statistics:fetch repository statistics"
|
||||
"repo-status-update:update repository status on the status page"
|
||||
"repo-sync:sync repository files to remote server according to current settings"
|
||||
"repo-tree:dump repository tree based on packages dependencies"
|
||||
@ -98,6 +99,7 @@ _shtab_ahriman_options=(
|
||||
|
||||
_shtab_ahriman_add_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--changes,--no-changes}"[calculate changes from the latest known commit if available (default\: True)]:changes:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--increment,--no-increment}"[increment package release (pkgrel) version on duplicate (default\: True)]:increment:"
|
||||
@ -119,7 +121,7 @@ _shtab_ahriman_aur_search_options=(
|
||||
|
||||
_shtab_ahriman_check_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--changes,--no-changes}"[calculate changes from the latest known commit if available. Only applicable in dry run mode (default\: True)]:changes:"
|
||||
{--changes,--no-changes}"[calculate changes from the latest known commit if available (default\: True)]:changes:"
|
||||
{--check-files,--no-check-files}"[enable or disable checking of broken dependencies (e.g. dynamically linked libraries or modules directories) (default\: True)]:check_files:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages (default\: True)]:vcs:"
|
||||
@ -209,6 +211,7 @@ _shtab_ahriman_key_import_options=(
|
||||
|
||||
_shtab_ahriman_package_add_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--changes,--no-changes}"[calculate changes from the latest known commit if available (default\: True)]:changes:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--increment,--no-increment}"[increment package release (pkgrel) version on duplicate (default\: True)]:increment:"
|
||||
@ -258,6 +261,7 @@ _shtab_ahriman_package_status_update_options=(
|
||||
|
||||
_shtab_ahriman_package_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--changes,--no-changes}"[calculate changes from the latest known commit if available (default\: True)]:changes:"
|
||||
{--dependencies,--no-dependencies}"[process missing package dependencies (default\: True)]:dependencies:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--increment,--no-increment}"[increment package release (pkgrel) version on duplicate (default\: True)]:increment:"
|
||||
@ -323,7 +327,7 @@ _shtab_ahriman_repo_backup_options=(
|
||||
|
||||
_shtab_ahriman_repo_check_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{--changes,--no-changes}"[calculate changes from the latest known commit if available. Only applicable in dry run mode (default\: True)]:changes:"
|
||||
{--changes,--no-changes}"[calculate changes from the latest known commit if available (default\: True)]:changes:"
|
||||
{--check-files,--no-check-files}"[enable or disable checking of broken dependencies (e.g. dynamically linked libraries or modules directories) (default\: True)]:check_files:"
|
||||
{-e,--exit-code}"[return non-zero exit status if result is empty (default\: False)]"
|
||||
{--vcs,--no-vcs}"[fetch actual version of VCS packages (default\: True)]:vcs:"
|
||||
@ -441,6 +445,17 @@ _shtab_ahriman_repo_sign_options=(
|
||||
"(*)::sign only specified packages (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_statistics_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
"--chart[create updates chart and save it to the specified path (default\: None)]:chart:"
|
||||
{-e,--event}"[event type filter (default\: package-updated)]:event:(package-outdated package-removed package-update-failed package-updated)"
|
||||
"--from-date[only fetch events which are newer than the date (default\: None)]:from_date:"
|
||||
"--limit[limit response by specified amount of events (default\: -1)]:limit:"
|
||||
"--offset[skip specified amount of events (default\: 0)]:offset:"
|
||||
"--to-date[only fetch events which are older than the date (default\: None)]:to_date:"
|
||||
":fetch only events for the specified package (default\: None):"
|
||||
)
|
||||
|
||||
_shtab_ahriman_repo_status_update_options=(
|
||||
"(- : *)"{-h,--help}"[show this help message and exit]"
|
||||
{-s,--status}"[new status (default\: success)]:status:(unknown pending building failed success)"
|
||||
@ -706,6 +721,7 @@ _shtab_ahriman() {
|
||||
repo-restore) _arguments -C -s $_shtab_ahriman_repo_restore_options ;;
|
||||
repo-setup) _arguments -C -s $_shtab_ahriman_repo_setup_options ;;
|
||||
repo-sign) _arguments -C -s $_shtab_ahriman_repo_sign_options ;;
|
||||
repo-statistics) _arguments -C -s $_shtab_ahriman_repo_statistics_options ;;
|
||||
repo-status-update) _arguments -C -s $_shtab_ahriman_repo_status_update_options ;;
|
||||
repo-sync) _arguments -C -s $_shtab_ahriman_repo_sync_options ;;
|
||||
repo-tree) _arguments -C -s $_shtab_ahriman_repo_tree_options ;;
|
||||
|
@ -17,12 +17,10 @@ authors = [
|
||||
]
|
||||
|
||||
dependencies = [
|
||||
"cerberus",
|
||||
"inflection",
|
||||
"passlib",
|
||||
"pyelftools",
|
||||
"requests",
|
||||
"srcinfo",
|
||||
]
|
||||
|
||||
dynamic = ["version"]
|
||||
@ -62,6 +60,9 @@ pacman = [
|
||||
s3 = [
|
||||
"boto3",
|
||||
]
|
||||
stats = [
|
||||
"matplotlib",
|
||||
]
|
||||
tests = [
|
||||
"pytest",
|
||||
"pytest-aiohttp",
|
||||
@ -71,6 +72,9 @@ tests = [
|
||||
"pytest-resource-path",
|
||||
"pytest-spec",
|
||||
]
|
||||
validator = [
|
||||
"cerberus",
|
||||
]
|
||||
web = [
|
||||
"Jinja2",
|
||||
"aioauth-client",
|
||||
|
@ -1,6 +1,7 @@
|
||||
# Index
|
||||
|
||||
1. Setup repository named `ahriman-demo` with architecture `x86_64`.
|
||||
2. Generate index page.
|
||||
2. Generate index page and RSS feed.
|
||||
3. Repository is available at `http://localhost:8080/repo`.
|
||||
4. Index page is available at `http://localhost:8080/repo/ahriman-demo/x86_64/index.html`
|
||||
5. Index page is available at `http://localhost:8080/repo/ahriman-demo/x86_64/rss.xml`
|
||||
|
@ -1,6 +1,12 @@
|
||||
[report]
|
||||
target = html
|
||||
target = html rss
|
||||
|
||||
[html]
|
||||
path = /var/lib/ahriman/ahriman/repository/ahriman-demo/x86_64/index.html
|
||||
path = ${repository:root}/repository/ahriman-demo/x86_64/index.html
|
||||
link_path = http://localhost:8080/repo/ahriman-demo/x86_64
|
||||
rss_url = ${html:link_path}/rss.xml
|
||||
|
||||
[rss]
|
||||
link_path = ${html:link_path}
|
||||
path = ${repository:root}/repository/ahriman-demo/x86_64/rss.xml
|
||||
rss_url = ${html:link_path}/rss.xml
|
||||
|
@ -17,4 +17,4 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
__version__ = "2.14.1"
|
||||
__version__ = "2.15.1"
|
||||
|
@ -28,6 +28,7 @@ from ahriman.application import handlers
|
||||
from ahriman.core.utils import enum_values, extract_user
|
||||
from ahriman.models.action import Action
|
||||
from ahriman.models.build_status import BuildStatusEnum
|
||||
from ahriman.models.event import EventType
|
||||
from ahriman.models.log_handler import LogHandler
|
||||
from ahriman.models.package_source import PackageSource
|
||||
from ahriman.models.sign_settings import SignSettings
|
||||
@ -119,6 +120,7 @@ def _parser() -> argparse.ArgumentParser:
|
||||
_set_repo_report_parser(subparsers)
|
||||
_set_repo_restore_parser(subparsers)
|
||||
_set_repo_sign_parser(subparsers)
|
||||
_set_repo_statistics_parser(subparsers)
|
||||
_set_repo_status_update_parser(subparsers)
|
||||
_set_repo_sync_parser(subparsers)
|
||||
_set_repo_tree_parser(subparsers)
|
||||
@ -264,6 +266,8 @@ def _set_package_add_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
"5) and finally you can add package from AUR.",
|
||||
formatter_class=_formatter)
|
||||
parser.add_argument("package", help="package source (base name, path to local files, remote URL)", nargs="+")
|
||||
parser.add_argument("--changes", help="calculate changes from the latest known commit if available",
|
||||
action=argparse.BooleanOptionalAction, default=True)
|
||||
parser.add_argument("--dependencies", help="process missing package dependencies",
|
||||
action=argparse.BooleanOptionalAction, default=True)
|
||||
parser.add_argument("-e", "--exit-code", help="return non-zero exit status if result is empty", action="store_true")
|
||||
@ -532,8 +536,7 @@ def _set_repo_check_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
description="check for packages updates. Same as repo-update --dry-run --no-manual",
|
||||
formatter_class=_formatter)
|
||||
parser.add_argument("package", help="filter check by package base", nargs="*")
|
||||
parser.add_argument("--changes", help="calculate changes from the latest known commit if available. "
|
||||
"Only applicable in dry run mode",
|
||||
parser.add_argument("--changes", help="calculate changes from the latest known commit if available",
|
||||
action=argparse.BooleanOptionalAction, default=True)
|
||||
parser.add_argument("--check-files", help="enable or disable checking of broken dependencies "
|
||||
"(e.g. dynamically linked libraries or modules directories)",
|
||||
@ -735,6 +738,30 @@ def _set_repo_sign_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
return parser
|
||||
|
||||
|
||||
def _set_repo_statistics_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
"""
|
||||
add parser for repository statistics subcommand
|
||||
|
||||
Args:
|
||||
root(SubParserAction): subparsers for the commands
|
||||
|
||||
Returns:
|
||||
argparse.ArgumentParser: created argument parser
|
||||
"""
|
||||
parser = root.add_parser("repo-statistics", help="repository statistics",
|
||||
description="fetch repository statistics", formatter_class=_formatter)
|
||||
parser.add_argument("package", help="fetch only events for the specified package", nargs="?")
|
||||
parser.add_argument("--chart", help="create updates chart and save it to the specified path", type=Path)
|
||||
parser.add_argument("-e", "--event", help="event type filter",
|
||||
type=EventType, choices=enum_values(EventType), default=EventType.PackageUpdated)
|
||||
parser.add_argument("--from-date", help="only fetch events which are newer than the date")
|
||||
parser.add_argument("--limit", help="limit response by specified amount of events", type=int, default=-1)
|
||||
parser.add_argument("--offset", help="skip specified amount of events", type=int, default=0)
|
||||
parser.add_argument("--to-date", help="only fetch events which are older than the date")
|
||||
parser.set_defaults(handler=handlers.Statistics, lock=None, quiet=True, report=False, unsafe=True)
|
||||
return parser
|
||||
|
||||
|
||||
def _set_repo_status_update_parser(root: SubParserAction) -> argparse.ArgumentParser:
|
||||
"""
|
||||
add parser for repository status update subcommand
|
||||
|
@ -120,8 +120,7 @@ class Application(ApplicationPackages, ApplicationRepository):
|
||||
process_dependencies(bool): if no set, dependencies will not be processed
|
||||
|
||||
Returns:
|
||||
list[Package]: updated packages list. Packager for dependencies will be copied from
|
||||
original package
|
||||
list[Package]: updated packages list. Packager for dependencies will be copied from the original package
|
||||
|
||||
Examples:
|
||||
In the most cases, in order to avoid build failure, it is required to add missing packages, which can be
|
||||
|
@ -40,8 +40,6 @@ class ApplicationProperties(LazyLogging):
|
||||
def __init__(self, repository_id: RepositoryId, configuration: Configuration, *, report: bool,
|
||||
refresh_pacman_database: PacmanSynchronization = PacmanSynchronization.Disabled) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
repository_id(RepositoryId): repository unique identifier
|
||||
configuration(Configuration): configuration instance
|
||||
|
@ -49,8 +49,6 @@ class UpdatesIterator(Iterator[list[str] | None]):
|
||||
|
||||
def __init__(self, application: Application, interval: int) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
application(Application): application instance
|
||||
interval(int): predefined interval for updates
|
||||
|
@ -37,8 +37,6 @@ class LocalUpdater(Updater):
|
||||
|
||||
def __init__(self, repository: Repository) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
repository(Repository): repository instance
|
||||
"""
|
||||
|
@ -43,8 +43,6 @@ class RemoteUpdater(Updater):
|
||||
|
||||
def __init__(self, workers: list[Worker], repository_id: RepositoryId, configuration: Configuration) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
workers(list[Worker]): worker identifiers
|
||||
repository_id(RepositoryId): repository unique identifier
|
||||
|
@ -38,6 +38,7 @@ from ahriman.application.handlers.service_updates import ServiceUpdates
|
||||
from ahriman.application.handlers.setup import Setup
|
||||
from ahriman.application.handlers.shell import Shell
|
||||
from ahriman.application.handlers.sign import Sign
|
||||
from ahriman.application.handlers.statistics import Statistics
|
||||
from ahriman.application.handlers.status import Status
|
||||
from ahriman.application.handlers.status_update import StatusUpdate
|
||||
from ahriman.application.handlers.structure import Structure
|
||||
|
@ -57,9 +57,12 @@ class Add(Handler):
|
||||
return
|
||||
|
||||
packages = application.updates(args.package, aur=False, local=False, manual=True, vcs=False, check_files=False)
|
||||
if args.changes: # generate changes if requested
|
||||
application.changes(packages)
|
||||
|
||||
packages = application.with_dependencies(packages, process_dependencies=args.dependencies)
|
||||
packagers = Packagers(args.username, {package.base: package.packager for package in packages})
|
||||
|
||||
application.print_updates(packages, log_fn=application.logger.info)
|
||||
result = application.update(packages, packagers, bump_pkgrel=args.increment)
|
||||
Add.check_if_empty(args.exit_code, result.is_empty)
|
||||
Add.check_status(args.exit_code, not result.is_empty)
|
||||
|
@ -54,6 +54,6 @@ class Change(Handler):
|
||||
case Action.List:
|
||||
changes = client.package_changes_get(args.package)
|
||||
ChangesPrinter(changes)(verbose=True, separator="")
|
||||
Change.check_if_empty(args.exit_code, changes.is_empty)
|
||||
Change.check_status(args.exit_code, not changes.is_empty)
|
||||
case Action.Remove:
|
||||
client.package_changes_update(args.package, Changes())
|
||||
|
@ -20,7 +20,7 @@
|
||||
import argparse
|
||||
import logging
|
||||
|
||||
from collections.abc import Iterable
|
||||
from collections.abc import Callable, Iterable
|
||||
from multiprocessing import Pool
|
||||
|
||||
from ahriman.application.lock import Lock
|
||||
@ -59,7 +59,7 @@ class Handler:
|
||||
repository_id(RepositoryId): repository unique identifier
|
||||
|
||||
Returns:
|
||||
bool: True on success, False otherwise
|
||||
bool: ``True`` on success, ``False`` otherwise
|
||||
"""
|
||||
try:
|
||||
configuration = Configuration.from_path(args.configuration, repository_id)
|
||||
@ -124,19 +124,26 @@ class Handler:
|
||||
raise NotImplementedError
|
||||
|
||||
@staticmethod
|
||||
def check_if_empty(enabled: bool, predicate: bool) -> None:
|
||||
def check_status(enabled: bool, status: bool | Callable[[], bool]) -> None:
|
||||
"""
|
||||
check condition and flag and raise ExitCode exception in case if it is enabled and condition match
|
||||
|
||||
Args:
|
||||
enabled(bool): if False no check will be performed
|
||||
predicate(bool): indicates condition on which exception should be thrown
|
||||
enabled(bool): if ``False`` no check will be performed
|
||||
status(bool | Callable[[], bool]): return status or function to check. ``True`` means success and vice versa
|
||||
|
||||
Raises:
|
||||
ExitCode: if result is empty and check is enabled
|
||||
"""
|
||||
if enabled and predicate:
|
||||
raise ExitCode
|
||||
if not enabled:
|
||||
return
|
||||
|
||||
match status:
|
||||
case False:
|
||||
raise ExitCode
|
||||
# https://github.com/python/mypy/issues/14014
|
||||
case Callable() if not status(): # type: ignore[misc]
|
||||
raise ExitCode
|
||||
|
||||
@staticmethod
|
||||
def repositories_extract(args: argparse.Namespace) -> list[RepositoryId]:
|
||||
|
@ -136,7 +136,7 @@ class Patch(Handler):
|
||||
for patch in application.reporter.package_patches_get(package_base, None)
|
||||
if variables is None or patch.key in variables
|
||||
]
|
||||
Patch.check_if_empty(exit_code, not patches)
|
||||
Patch.check_status(exit_code, bool(patches))
|
||||
|
||||
PatchPrinter(package_base, patches)(verbose=True, separator=" = ")
|
||||
|
||||
|
@ -49,15 +49,15 @@ class Rebuild(Handler):
|
||||
application.on_start()
|
||||
|
||||
packages = Rebuild.extract_packages(application, args.status, from_database=args.from_database)
|
||||
updates = application.repository.packages_depend_on(packages, args.depends_on)
|
||||
packages = application.repository.packages_depend_on(packages, args.depends_on)
|
||||
|
||||
Rebuild.check_if_empty(args.exit_code, not updates)
|
||||
Rebuild.check_status(args.exit_code, bool(packages))
|
||||
if args.dry_run:
|
||||
application.print_updates(updates, log_fn=print)
|
||||
application.print_updates(packages, log_fn=print)
|
||||
return
|
||||
|
||||
result = application.update(updates, Packagers(args.username), bump_pkgrel=args.increment)
|
||||
Rebuild.check_if_empty(args.exit_code, result.is_empty)
|
||||
result = application.update(packages, Packagers(args.username), bump_pkgrel=args.increment)
|
||||
Rebuild.check_status(args.exit_code, not result.is_empty)
|
||||
|
||||
@staticmethod
|
||||
def extract_packages(application: Application, status: BuildStatusEnum | None, *,
|
||||
|
@ -47,7 +47,7 @@ class Run(Handler):
|
||||
parser = args.parser()
|
||||
for command in args.command:
|
||||
status = Run.run_command(shlex.split(command), parser)
|
||||
Run.check_if_empty(True, not status)
|
||||
Run.check_status(True, status)
|
||||
|
||||
@staticmethod
|
||||
def run_command(command: list[str], parser: argparse.ArgumentParser) -> bool:
|
||||
|
@ -60,7 +60,8 @@ class Search(Handler):
|
||||
"""
|
||||
official_packages_list = Official.multisearch(*args.search)
|
||||
aur_packages_list = AUR.multisearch(*args.search)
|
||||
Search.check_if_empty(args.exit_code, not official_packages_list and not aur_packages_list)
|
||||
non_empty = bool(official_packages_list or aur_packages_list)
|
||||
Search.check_status(args.exit_code, non_empty)
|
||||
|
||||
for packages_list in (official_packages_list, aur_packages_list):
|
||||
# keep sorting by packages source
|
||||
|
@ -47,7 +47,7 @@ class ServiceUpdates(Handler):
|
||||
report(bool): force enable or disable reporting
|
||||
"""
|
||||
remote = Package.from_aur("ahriman", None)
|
||||
_, release = remote.version.rsplit("-", 1) # we don't store pkgrel locally, so we just append it
|
||||
_, release = remote.version.rsplit("-", maxsplit=1) # we don't store pkgrel locally, so we just append it
|
||||
local_version = f"{__version__}-{release}"
|
||||
|
||||
# technically we would like to compare versions, but it is fine to raise an exception in case if locally
|
||||
@ -57,4 +57,4 @@ class ServiceUpdates(Handler):
|
||||
return
|
||||
|
||||
UpdatePrinter(remote, local_version)(verbose=True, separator=" -> ")
|
||||
ServiceUpdates.check_if_empty(args.exit_code, not same_version)
|
||||
ServiceUpdates.check_status(args.exit_code, same_version)
|
||||
|
170
src/ahriman/application/handlers/statistics.py
Normal file
@ -0,0 +1,170 @@
|
||||
#
|
||||
# Copyright (c) 2021-2024 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import argparse
|
||||
import datetime
|
||||
import itertools
|
||||
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.application.application import Application
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.formatters import EventStatsPrinter, PackageStatsPrinter
|
||||
from ahriman.core.utils import pretty_datetime
|
||||
from ahriman.models.event import Event
|
||||
from ahriman.models.repository_id import RepositoryId
|
||||
|
||||
|
||||
class Statistics(Handler):
|
||||
"""
|
||||
repository statistics handler
|
||||
"""
|
||||
|
||||
ALLOW_MULTI_ARCHITECTURE_RUN = False # conflicting io
|
||||
|
||||
@classmethod
|
||||
def run(cls, args: argparse.Namespace, repository_id: RepositoryId, configuration: Configuration, *,
|
||||
report: bool) -> None:
|
||||
"""
|
||||
callback for command line
|
||||
|
||||
Args:
|
||||
args(argparse.Namespace): command line args
|
||||
repository_id(RepositoryId): repository unique identifier
|
||||
configuration(Configuration): configuration instance
|
||||
report(bool): force enable or disable reporting
|
||||
"""
|
||||
application = Application(repository_id, configuration, report=True)
|
||||
|
||||
from_date = to_date = None
|
||||
if (value := args.from_date) is not None:
|
||||
from_date = datetime.datetime.fromisoformat(value).timestamp()
|
||||
if (value := args.to_date) is not None:
|
||||
to_date = datetime.datetime.fromisoformat(value).timestamp()
|
||||
|
||||
events = application.reporter.event_get(args.event, args.package, from_date, to_date, args.limit, args.offset)
|
||||
|
||||
match args.package:
|
||||
case None:
|
||||
Statistics.stats_per_package(args.event, events, args.chart)
|
||||
case _:
|
||||
Statistics.stats_for_package(args.event, events, args.chart)
|
||||
|
||||
@staticmethod
|
||||
def event_stats(event_type: str, events: list[Event]) -> None:
|
||||
"""
|
||||
calculate event stats
|
||||
|
||||
Args:
|
||||
event_type(str): event type
|
||||
events(list[Event]): list of events
|
||||
"""
|
||||
times = [event.get("took") for event in events if event.get("took") is not None]
|
||||
EventStatsPrinter(f"{event_type} duration, s", times)(verbose=True)
|
||||
|
||||
@staticmethod
|
||||
def plot_packages(event_type: str, events: dict[str, int], path: Path) -> None:
|
||||
"""
|
||||
plot packages frequency
|
||||
|
||||
Args:
|
||||
event_type(str): event type
|
||||
events(dict[str, int]): list of events
|
||||
path(Path): path to save plot
|
||||
"""
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
x, y = list(events.keys()), list(events.values())
|
||||
plt.bar(x, y)
|
||||
|
||||
plt.xlabel("Package base")
|
||||
plt.ylabel("Frequency")
|
||||
plt.title(f"Frequency of the {event_type} event per package")
|
||||
|
||||
plt.savefig(path)
|
||||
|
||||
@staticmethod
|
||||
def plot_times(event_type: str, events: list[Event], path: Path) -> None:
|
||||
"""
|
||||
plot events timeline
|
||||
|
||||
Args:
|
||||
event_type(str): event type
|
||||
events(list[Event]): list of events
|
||||
path(Path): path to save plot
|
||||
"""
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
figure = plt.figure()
|
||||
|
||||
x, y = zip(*[(pretty_datetime(event.created), event.get("took")) for event in events])
|
||||
plt.plot(x, y)
|
||||
|
||||
plt.xlabel("Event timestamp")
|
||||
plt.ylabel("Duration, s")
|
||||
plt.title(f"Duration of the {event_type} event")
|
||||
figure.autofmt_xdate()
|
||||
|
||||
plt.savefig(path)
|
||||
|
||||
@staticmethod
|
||||
def stats_for_package(event_type: str, events: list[Event], chart_path: Path | None) -> None:
|
||||
"""
|
||||
calculate statistics for a package
|
||||
|
||||
Args:
|
||||
event_type(str): event type
|
||||
events(list[Event]): list of events
|
||||
chart_path(Path): path to save plot if any
|
||||
"""
|
||||
# event statistics
|
||||
Statistics.event_stats(event_type, events)
|
||||
|
||||
# chart if enabled
|
||||
if chart_path is not None:
|
||||
Statistics.plot_times(event_type, events, chart_path)
|
||||
|
||||
@staticmethod
|
||||
def stats_per_package(event_type: str, events: list[Event], chart_path: Path | None) -> None:
|
||||
"""
|
||||
calculate overall statistics
|
||||
|
||||
Args:
|
||||
event_type(str): event type
|
||||
events(list[Event]): list of events
|
||||
chart_path(Path): path to save plot if any
|
||||
"""
|
||||
key: Callable[[Event], str] = lambda event: event.object_id
|
||||
by_object_id = {
|
||||
object_id: len(list(related))
|
||||
for object_id, related in itertools.groupby(sorted(events, key=key), key=key)
|
||||
}
|
||||
|
||||
# distribution per package
|
||||
PackageStatsPrinter(by_object_id)(verbose=True)
|
||||
EventStatsPrinter(f"{event_type} frequency", list(by_object_id.values()))(verbose=True)
|
||||
|
||||
# event statistics
|
||||
Statistics.event_stats(event_type, events)
|
||||
|
||||
# chart if enabled
|
||||
if chart_path is not None:
|
||||
Statistics.plot_packages(event_type, by_object_id, chart_path)
|
@ -61,7 +61,7 @@ class Status(Handler):
|
||||
else:
|
||||
packages = client.package_get(None)
|
||||
|
||||
Status.check_if_empty(args.exit_code, not packages)
|
||||
Status.check_status(args.exit_code, bool(packages))
|
||||
|
||||
comparator: Callable[[tuple[Package, BuildStatus]], str] = lambda item: item[0].base
|
||||
filter_fn: Callable[[tuple[Package, BuildStatus]], bool] =\
|
||||
|
@ -63,7 +63,7 @@ class UnsafeCommands(Handler):
|
||||
parser(argparse.ArgumentParser): generated argument parser
|
||||
"""
|
||||
args = parser.parse_args(command)
|
||||
UnsafeCommands.check_if_empty(True, args.command in unsafe_commands)
|
||||
UnsafeCommands.check_status(True, args.command not in unsafe_commands)
|
||||
|
||||
@staticmethod
|
||||
def get_unsafe_commands(parser: argparse.ArgumentParser) -> list[str]:
|
||||
|
@ -50,11 +50,11 @@ class Update(Handler):
|
||||
|
||||
packages = application.updates(args.package, aur=args.aur, local=args.local, manual=args.manual, vcs=args.vcs,
|
||||
check_files=args.check_files)
|
||||
if args.dry_run: # some check specific actions
|
||||
if args.changes: # generate changes if requested
|
||||
application.changes(packages)
|
||||
if args.changes: # generate changes if requested
|
||||
application.changes(packages)
|
||||
|
||||
Update.check_if_empty(args.exit_code, not packages) # status code check
|
||||
if args.dry_run: # exit from application if no build requested
|
||||
Update.check_status(args.exit_code, bool(packages)) # status code check
|
||||
return
|
||||
|
||||
packages = application.with_dependencies(packages, process_dependencies=args.dependencies)
|
||||
@ -62,7 +62,7 @@ class Update(Handler):
|
||||
|
||||
application.print_updates(packages, log_fn=application.logger.info)
|
||||
result = application.update(packages, packagers, bump_pkgrel=args.increment)
|
||||
Update.check_if_empty(args.exit_code, result.is_empty)
|
||||
Update.check_status(args.exit_code, not result.is_empty)
|
||||
|
||||
@staticmethod
|
||||
def log_fn(application: Application, dry_run: bool) -> Callable[[str], None]:
|
||||
|
@ -59,9 +59,9 @@ class Users(Handler):
|
||||
database.user_update(user.hash_password(salt))
|
||||
case Action.List:
|
||||
users = database.user_list(args.username, args.role)
|
||||
Users.check_if_empty(args.exit_code, not users)
|
||||
for user in users:
|
||||
UserPrinter(user)(verbose=True)
|
||||
Users.check_status(args.exit_code, bool(users))
|
||||
case Action.Remove:
|
||||
database.user_remove(args.username)
|
||||
|
||||
|
@ -25,7 +25,6 @@ from typing import Any
|
||||
from ahriman.application.handlers.handler import Handler
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.configuration.schema import CONFIGURATION_SCHEMA, ConfigurationSchema
|
||||
from ahriman.core.configuration.validator import Validator
|
||||
from ahriman.core.exceptions import ExtensionError
|
||||
from ahriman.core.formatters import ValidationPrinter
|
||||
from ahriman.core.triggers import TriggerLoader
|
||||
@ -51,6 +50,8 @@ class Validate(Handler):
|
||||
configuration(Configuration): configuration instance
|
||||
report(bool): force enable or disable reporting
|
||||
"""
|
||||
from ahriman.core.configuration.validator import Validator
|
||||
|
||||
schema = Validate.schema(repository_id, configuration)
|
||||
validator = Validator(configuration=configuration, schema=schema)
|
||||
|
||||
@ -60,7 +61,7 @@ class Validate(Handler):
|
||||
ValidationPrinter(node, errors)(verbose=True)
|
||||
|
||||
# as we reach this part it means that we always have errors
|
||||
Validate.check_if_empty(args.exit_code, True)
|
||||
Validate.check_status(args.exit_code, False)
|
||||
|
||||
@staticmethod
|
||||
def schema(repository_id: RepositoryId, configuration: Configuration) -> ConfigurationSchema:
|
||||
|
@ -59,15 +59,13 @@ class Lock(LazyLogging):
|
||||
>>> configuration = Configuration()
|
||||
>>> try:
|
||||
>>> with Lock(args, RepositoryId("x86_64", "aur-clone"), configuration):
|
||||
>>> perform_actions()
|
||||
>>> do_something()
|
||||
>>> except Exception as exception:
|
||||
>>> handle_exceptions(exception)
|
||||
"""
|
||||
|
||||
def __init__(self, args: argparse.Namespace, repository_id: RepositoryId, configuration: Configuration) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
args(argparse.Namespace): command line args
|
||||
repository_id(RepositoryId): repository unique identifier
|
||||
@ -99,7 +97,7 @@ class Lock(LazyLogging):
|
||||
fd(int): file descriptor:
|
||||
|
||||
Returns:
|
||||
bool: True in case if file is locked and False otherwise
|
||||
bool: ``True`` in case if file is locked and ``False`` otherwise
|
||||
"""
|
||||
try:
|
||||
fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
@ -121,7 +119,7 @@ class Lock(LazyLogging):
|
||||
watch until lock disappear
|
||||
|
||||
Returns:
|
||||
bool: True in case if file is locked and False otherwise
|
||||
bool: ``True`` in case if file is locked and ``False`` otherwise
|
||||
"""
|
||||
# there are reasons why we are not using inotify here. First of all, if we would use it, it would bring to
|
||||
# race conditions because multiple processes will be notified at the same time. Secondly, it is good library,
|
||||
@ -225,7 +223,7 @@ class Lock(LazyLogging):
|
||||
exc_tb(TracebackType): exception traceback if any
|
||||
|
||||
Returns:
|
||||
Literal[False]: always False (do not suppress any exception)
|
||||
Literal[False]: always ``False`` (do not suppress any exception)
|
||||
"""
|
||||
self.clear()
|
||||
status = BuildStatusEnum.Success if exc_val is None else BuildStatusEnum.Failed
|
||||
|
@ -33,9 +33,7 @@ class _Context:
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""
|
||||
default constructor. Must not be used directly
|
||||
"""
|
||||
""""""
|
||||
self._content: dict[str, Any] = {}
|
||||
|
||||
def get(self, key: ContextKey[T] | type[T]) -> T:
|
||||
|
@ -49,8 +49,6 @@ class Pacman(LazyLogging):
|
||||
def __init__(self, repository_id: RepositoryId, configuration: Configuration, *,
|
||||
refresh_database: PacmanSynchronization) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
repository_id(RepositoryId): repository unique identifier
|
||||
configuration(Configuration): configuration instance
|
||||
|
@ -45,8 +45,6 @@ class PacmanDatabase(SyncHttpClient):
|
||||
|
||||
def __init__(self, database: DB, configuration: Configuration) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
database(DB): pyalpm database object
|
||||
configuration(Configuration): configuration instance
|
||||
@ -102,7 +100,7 @@ class PacmanDatabase(SyncHttpClient):
|
||||
local_path(Path): path to locally stored file
|
||||
|
||||
Returns:
|
||||
bool: True in case if remote file is newer than local file
|
||||
bool: ``True`` in case if remote file is newer than local file
|
||||
|
||||
Raises:
|
||||
PacmanError: in case if no last-modified header was found
|
||||
|
325
src/ahriman/core/alpm/pkgbuild_parser.py
Normal file
@ -0,0 +1,325 @@
|
||||
#
|
||||
# Copyright (c) 2021-2024 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import itertools
|
||||
import re
|
||||
import shlex
|
||||
|
||||
from collections.abc import Generator
|
||||
from enum import StrEnum
|
||||
from typing import IO
|
||||
|
||||
from ahriman.core.exceptions import PkgbuildParserError
|
||||
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
||||
|
||||
|
||||
class PkgbuildToken(StrEnum):
|
||||
"""
|
||||
well-known tokens dictionary
|
||||
|
||||
Attributes:
|
||||
ArrayEnds(PkgbuildToken): (class attribute) array ends token
|
||||
ArrayStarts(PkgbuildToken): (class attribute) array starts token
|
||||
Comma(PkgbuildToken): (class attribute) comma token
|
||||
Comment(PkgbuildToken): (class attribute) comment token
|
||||
FunctionDeclaration(PkgbuildToken): (class attribute) function declaration token
|
||||
FunctionEnds(PkgbuildToken): (class attribute) function ends token
|
||||
FunctionStarts(PkgbuildToken): (class attribute) function starts token
|
||||
"""
|
||||
|
||||
ArrayStarts = "("
|
||||
ArrayEnds = ")"
|
||||
|
||||
Comma = ","
|
||||
|
||||
Comment = "#"
|
||||
|
||||
FunctionDeclaration = "()"
|
||||
FunctionStarts = "{"
|
||||
FunctionEnds = "}"
|
||||
|
||||
|
||||
class PkgbuildParser(shlex.shlex):
|
||||
"""
|
||||
simple pkgbuild reader implementation in pure python, because others suck.
|
||||
|
||||
What is it:
|
||||
|
||||
#. Simple PKGBUILD parser written in python.
|
||||
#. No shell execution, so it is free from random shell attacks.
|
||||
#. Able to parse simple constructions (assignments, comments, functions, arrays).
|
||||
|
||||
What it is not:
|
||||
|
||||
#. Fully functional shell parser.
|
||||
#. Shell executor.
|
||||
#. No parameter expansion.
|
||||
|
||||
For more details what does it support, please, consult with the test cases.
|
||||
|
||||
Examples:
|
||||
This class is heavily based on :mod:`shlex` parser, but instead of strings operates with the
|
||||
:class:`ahriman.models.pkgbuild_patch.PkgbuildPatch` objects. The main way to use it is to call :func:`parse()`
|
||||
function and collect parsed objects, e.g.::
|
||||
|
||||
>>> parser = PkgbuildParser(StringIO("input string"))
|
||||
>>> for patch in parser.parse():
|
||||
>>> print(f"{patch.key} = {patch.value}")
|
||||
|
||||
It doesn't store the state of the fields (but operates with the :mod:`shlex` parser state), so no shell
|
||||
post-processing is performed (e.g. variable substitution).
|
||||
"""
|
||||
|
||||
_ARRAY_ASSIGNMENT = re.compile(r"^(?P<key>\w+)=$")
|
||||
# in addition to usual assignment, functions can have dash
|
||||
_FUNCTION_DECLARATION = re.compile(r"^(?P<key>[\w-]+)$")
|
||||
_STRING_ASSIGNMENT = re.compile(r"^(?P<key>\w+)=(?P<value>.+)$")
|
||||
|
||||
def __init__(self, stream: IO[str]) -> None:
|
||||
"""
|
||||
Args:
|
||||
stream(IO[str]): input stream containing PKGBUILD content
|
||||
"""
|
||||
shlex.shlex.__init__(self, stream, posix=True, punctuation_chars=True)
|
||||
self._io = stream # direct access without type casting
|
||||
|
||||
# ignore substitution and extend bash symbols
|
||||
self.wordchars += "${}#:+-@!"
|
||||
# in case of default behaviour, it will ignore, for example, segment part of url outside of quotes
|
||||
self.commenters = ""
|
||||
|
||||
@staticmethod
|
||||
def _expand_array(array: list[str]) -> list[str]:
|
||||
"""
|
||||
bash array expansion simulator. It takes raw array and tries to expand constructions like
|
||||
``(first prefix-{mid1,mid2}-suffix last)`` into ``(first, prefix-mid1-suffix prefix-mid2-suffix last)``
|
||||
|
||||
Args:
|
||||
array(list[str]): input array
|
||||
|
||||
Returns:
|
||||
list[str]: either source array or expanded array if possible
|
||||
|
||||
Raises:
|
||||
PkgbuildParserError: if there are errors in parser
|
||||
"""
|
||||
# we are using comma as marker for expansion (if any)
|
||||
if PkgbuildToken.Comma not in array:
|
||||
return array
|
||||
# again sanity check, for expansion there are at least 3 elements (first, last and comma)
|
||||
if len(array) < 3:
|
||||
return array
|
||||
|
||||
result = []
|
||||
buffer, prefix = [], None
|
||||
|
||||
for index, (first, second) in enumerate(itertools.pairwise(array)):
|
||||
match (first, second):
|
||||
# in this case we check if expansion should be started
|
||||
# this condition matches "prefix{first", ","
|
||||
case (_, PkgbuildToken.Comma) if PkgbuildToken.FunctionStarts in first:
|
||||
prefix, part = first.rsplit(PkgbuildToken.FunctionStarts, maxsplit=1)
|
||||
buffer.append(f"{prefix}{part}")
|
||||
|
||||
# the last element case, it matches either ",", "last}" or ",", "last}suffix"
|
||||
# in case if there is suffix, it must be appended to all list elements
|
||||
case (PkgbuildToken.Comma, _) if prefix is not None and PkgbuildToken.FunctionEnds in second:
|
||||
part, suffix = second.rsplit(PkgbuildToken.FunctionEnds, maxsplit=1)
|
||||
buffer.append(f"{prefix}{part}")
|
||||
result.extend([f"{part}{suffix}" for part in buffer])
|
||||
# reset state
|
||||
buffer, prefix = [], None
|
||||
|
||||
# we have already prefix string, so we are in progress of expansion
|
||||
# we always operate the last element, so this matches ",", "next"
|
||||
case (PkgbuildToken.Comma, _) if prefix is not None:
|
||||
buffer.append(f"{prefix}{second}")
|
||||
|
||||
# exactly first element of the list
|
||||
case (_, _) if prefix is None and index == 0:
|
||||
result.append(first)
|
||||
|
||||
# any next normal element
|
||||
case (_, _) if prefix is None:
|
||||
result.append(second)
|
||||
|
||||
# small sanity check
|
||||
if prefix is not None:
|
||||
raise PkgbuildParserError("error in array expansion", array)
|
||||
|
||||
return result
|
||||
|
||||
def _is_escaped(self) -> bool:
|
||||
"""
|
||||
check if the last element was quoted. ``shlex.shlex`` parser doesn't provide information about was the token
|
||||
quoted or not, thus there is no difference between "'#'" (diez in quotes) and "#" (diez without quotes). This
|
||||
method simply rolls back to the last non-space character and check if it is a quotation mark
|
||||
|
||||
Returns:
|
||||
bool: ``True`` if the previous element of the stream is a quote or escaped and ``False`` otherwise
|
||||
"""
|
||||
current_position = self._io.tell()
|
||||
|
||||
last_char = penultimate_char = None
|
||||
for index in range(current_position - 1, -1, -1):
|
||||
self._io.seek(index)
|
||||
last_char = self._io.read(1)
|
||||
if last_char.isspace():
|
||||
continue
|
||||
|
||||
if index >= 0:
|
||||
self._io.seek(index - 1)
|
||||
penultimate_char = self._io.read(1)
|
||||
|
||||
break
|
||||
|
||||
self._io.seek(current_position) # reset position of the stream
|
||||
is_quoted = last_char is not None and last_char in self.quotes
|
||||
is_escaped = penultimate_char is not None and penultimate_char in self.escape
|
||||
|
||||
return is_quoted or is_escaped
|
||||
|
||||
def _parse_array(self) -> list[str]:
|
||||
"""
|
||||
parse array from the PKGBUILD. This method will extract tokens from parser until it matches closing array,
|
||||
modifying source parser state
|
||||
|
||||
Returns:
|
||||
list[str]: extracted arrays elements
|
||||
|
||||
Raises:
|
||||
PkgbuildParserError: if array is not closed
|
||||
"""
|
||||
def extract() -> Generator[str, None, None]:
|
||||
while token := self.get_token():
|
||||
match token:
|
||||
case _ if self._is_escaped():
|
||||
pass
|
||||
case PkgbuildToken.ArrayEnds:
|
||||
break
|
||||
case PkgbuildToken.Comment:
|
||||
self.instream.readline()
|
||||
continue
|
||||
yield token
|
||||
|
||||
if token != PkgbuildToken.ArrayEnds:
|
||||
raise PkgbuildParserError("no closing array bracket found")
|
||||
|
||||
return self._expand_array(list(extract()))
|
||||
|
||||
def _parse_function(self) -> str:
|
||||
"""
|
||||
parse function from the PKGBUILD. This method will extract tokens from parser until it matches closing function,
|
||||
modifying source parser state. Instead of trying to combine tokens together, it uses positions of the file
|
||||
and reads content again in this range
|
||||
|
||||
Returns:
|
||||
str: function body
|
||||
|
||||
Raises:
|
||||
PkgbuildParserError: if function body wasn't found or parser input stream doesn't support position reading
|
||||
"""
|
||||
# find start and end positions
|
||||
start_position = end_position = -1
|
||||
counter = 0 # simple processing of the inner "{" and "}"
|
||||
for token in self:
|
||||
match token:
|
||||
case _ if self._is_escaped():
|
||||
continue
|
||||
case PkgbuildToken.FunctionStarts:
|
||||
if counter == 0:
|
||||
start_position = self._io.tell() - 1
|
||||
counter += 1
|
||||
case PkgbuildToken.FunctionEnds:
|
||||
end_position = self._io.tell()
|
||||
counter -= 1
|
||||
if counter == 0:
|
||||
break
|
||||
|
||||
if not 0 < start_position < end_position:
|
||||
raise PkgbuildParserError("function body wasn't found")
|
||||
|
||||
# read the specified interval from source stream
|
||||
self._io.seek(start_position - 1) # start from the previous symbol
|
||||
content = self._io.read(end_position - start_position)
|
||||
|
||||
# special case of the end of file
|
||||
if self.state == self.eof: # type: ignore[attr-defined]
|
||||
content += self._io.read(1)
|
||||
|
||||
# reset position (because the last position was before the next token starts)
|
||||
self._io.seek(end_position)
|
||||
|
||||
return content
|
||||
|
||||
def _parse_token(self, token: str) -> Generator[PkgbuildPatch, None, None]:
|
||||
"""
|
||||
parse single token to the PKGBUILD field
|
||||
|
||||
Args:
|
||||
token(str): current token
|
||||
|
||||
Yields:
|
||||
PkgbuildPatch: extracted a PKGBUILD node
|
||||
"""
|
||||
# simple assignment rule
|
||||
if m := self._STRING_ASSIGNMENT.match(token):
|
||||
key = m.group("key")
|
||||
value = m.group("value")
|
||||
yield PkgbuildPatch(key, value)
|
||||
return
|
||||
|
||||
if token == PkgbuildToken.Comment:
|
||||
self.instream.readline()
|
||||
return
|
||||
|
||||
match self.get_token():
|
||||
# array processing. Arrays will be sent as "key=", "(", values, ")"
|
||||
case PkgbuildToken.ArrayStarts if m := self._ARRAY_ASSIGNMENT.match(token):
|
||||
key = m.group("key")
|
||||
value = self._parse_array()
|
||||
yield PkgbuildPatch(key, value)
|
||||
|
||||
# functions processing. Function will be sent as "name", "()", "{", body, "}"
|
||||
case PkgbuildToken.FunctionDeclaration if self._FUNCTION_DECLARATION.match(token):
|
||||
key = f"{token}{PkgbuildToken.FunctionDeclaration}"
|
||||
value = self._parse_function()
|
||||
yield PkgbuildPatch(key, value) # this is not mistake, assign to token without ()
|
||||
|
||||
# special function case, where "(" and ")" are separated tokens, e.g. "pkgver ( )"
|
||||
case PkgbuildToken.ArrayStarts if self._FUNCTION_DECLARATION.match(token):
|
||||
next_token = self.get_token()
|
||||
if next_token == PkgbuildToken.ArrayEnds: # replace closing bracket with "()"
|
||||
next_token = PkgbuildToken.FunctionDeclaration
|
||||
self.push_token(next_token) # type: ignore[arg-type]
|
||||
yield from self._parse_token(token)
|
||||
|
||||
# some random token received without continuation, lets guess it is empty assignment (i.e. key=)
|
||||
case other if other is not None:
|
||||
yield from self._parse_token(other)
|
||||
|
||||
def parse(self) -> Generator[PkgbuildPatch, None, None]:
|
||||
"""
|
||||
parse source stream and yield parsed entries
|
||||
|
||||
Yields:
|
||||
PkgbuildPatch: extracted a PKGBUILD node
|
||||
"""
|
||||
for token in self:
|
||||
yield from self._parse_token(token)
|
@ -38,8 +38,6 @@ class Repo(LazyLogging):
|
||||
|
||||
def __init__(self, name: str, paths: RepositoryPaths, sign_args: list[str]) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
name(str): repository name
|
||||
paths(RepositoryPaths): repository paths instance
|
||||
@ -68,7 +66,7 @@ class Repo(LazyLogging):
|
||||
path(Path): path to archive to add
|
||||
"""
|
||||
check_output(
|
||||
"repo-add", *self.sign_args, "--remove", str(self.repo_path), str(path),
|
||||
"repo-add", *self.sign_args, "-R", str(self.repo_path), str(path),
|
||||
exception=BuildError.from_process(path.name),
|
||||
cwd=self.paths.repository,
|
||||
logger=self.logger,
|
||||
@ -78,13 +76,8 @@ class Repo(LazyLogging):
|
||||
"""
|
||||
create empty repository database. It just calls add with empty arguments
|
||||
"""
|
||||
# since pacman-6.1.0 repo-add doesn't create empty database in case if no packages supplied
|
||||
# this code creates empty files instead
|
||||
if self.repo_path.exists():
|
||||
return # database is already created, skip this part
|
||||
|
||||
self.repo_path.touch(exist_ok=True)
|
||||
(self.paths.repository / f"{self.name}.db").symlink_to(self.repo_path)
|
||||
check_output("repo-add", *self.sign_args, str(self.repo_path),
|
||||
cwd=self.paths.repository, logger=self.logger, user=self.uid)
|
||||
|
||||
def remove(self, package: str, filename: Path) -> None:
|
||||
"""
|
||||
|
@ -38,8 +38,6 @@ class Auth(LazyLogging):
|
||||
|
||||
def __init__(self, configuration: Configuration, provider: AuthSettings = AuthSettings.Disabled) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration instance
|
||||
provider(AuthSettings, optional): authorization type definition (Default value = AuthSettings.Disabled)
|
||||
@ -96,7 +94,7 @@ class Auth(LazyLogging):
|
||||
password(str | None): entered password
|
||||
|
||||
Returns:
|
||||
bool: True in case if password matches, False otherwise
|
||||
bool: ``True`` in case if password matches, ``False`` otherwise
|
||||
"""
|
||||
del username, password
|
||||
return True
|
||||
@ -109,7 +107,7 @@ class Auth(LazyLogging):
|
||||
username(str): username
|
||||
|
||||
Returns:
|
||||
bool: True in case if user is known and can be authorized and False otherwise
|
||||
bool: ``True`` in case if user is known and can be authorized and ``False`` otherwise
|
||||
"""
|
||||
del username
|
||||
return True
|
||||
@ -124,7 +122,7 @@ class Auth(LazyLogging):
|
||||
context(str | None): URI request path
|
||||
|
||||
Returns:
|
||||
bool: True in case if user is allowed to do this request and False otherwise
|
||||
bool: ``True`` in case if user is allowed to do this request and ``False`` otherwise
|
||||
"""
|
||||
del username, required, context
|
||||
return True
|
||||
|
@ -38,7 +38,7 @@ async def authorized_userid(*args: Any, **kwargs: Any) -> Any:
|
||||
**kwargs(Any): named argument list as provided by authorized_userid function
|
||||
|
||||
Returns:
|
||||
Any: None in case if no aiohttp_security module found and function call otherwise
|
||||
Any: ``None`` in case if no aiohttp_security module found and function call otherwise
|
||||
"""
|
||||
if _has_aiohttp_security:
|
||||
return await aiohttp_security.authorized_userid(*args, **kwargs) # pylint: disable=no-value-for-parameter
|
||||
@ -54,7 +54,7 @@ async def check_authorized(*args: Any, **kwargs: Any) -> Any:
|
||||
**kwargs(Any): named argument list as provided by authorized_userid function
|
||||
|
||||
Returns:
|
||||
Any: None in case if no aiohttp_security module found and function call otherwise
|
||||
Any: ``None`` in case if no aiohttp_security module found and function call otherwise
|
||||
"""
|
||||
if _has_aiohttp_security:
|
||||
return await aiohttp_security.check_authorized(*args, **kwargs) # pylint: disable=no-value-for-parameter
|
||||
@ -70,7 +70,7 @@ async def forget(*args: Any, **kwargs: Any) -> Any:
|
||||
**kwargs(Any): named argument list as provided by authorized_userid function
|
||||
|
||||
Returns:
|
||||
Any: None in case if no aiohttp_security module found and function call otherwise
|
||||
Any: ``None`` in case if no aiohttp_security module found and function call otherwise
|
||||
"""
|
||||
if _has_aiohttp_security:
|
||||
return await aiohttp_security.forget(*args, **kwargs) # pylint: disable=no-value-for-parameter
|
||||
@ -86,7 +86,7 @@ async def remember(*args: Any, **kwargs: Any) -> Any:
|
||||
**kwargs(Any): named argument list as provided by authorized_userid function
|
||||
|
||||
Returns:
|
||||
Any: None in case if no aiohttp_security module found and function call otherwise
|
||||
Any: ``None`` in case if no aiohttp_security module found and function call otherwise
|
||||
"""
|
||||
if _has_aiohttp_security:
|
||||
return await aiohttp_security.remember(*args, **kwargs) # pylint: disable=no-value-for-parameter
|
||||
|
@ -37,8 +37,6 @@ class Mapping(Auth):
|
||||
def __init__(self, configuration: Configuration, database: SQLite,
|
||||
provider: AuthSettings = AuthSettings.Configuration) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration instance
|
||||
database(SQLite): database instance
|
||||
@ -57,7 +55,7 @@ class Mapping(Auth):
|
||||
password(str | None): entered password
|
||||
|
||||
Returns:
|
||||
bool: True in case if password matches, False otherwise
|
||||
bool: ``True`` in case if password matches, ``False`` otherwise
|
||||
"""
|
||||
if password is None:
|
||||
return False # invalid data supplied
|
||||
@ -72,7 +70,7 @@ class Mapping(Auth):
|
||||
username(str): username
|
||||
|
||||
Returns:
|
||||
User | None: user descriptor if username is known and None otherwise
|
||||
User | None: user descriptor if username is known and ``None`` otherwise
|
||||
"""
|
||||
return self.database.user_get(username)
|
||||
|
||||
@ -84,7 +82,7 @@ class Mapping(Auth):
|
||||
username(str): username
|
||||
|
||||
Returns:
|
||||
bool: True in case if user is known and can be authorized and False otherwise
|
||||
bool: ``True`` in case if user is known and can be authorized and ``False`` otherwise
|
||||
"""
|
||||
return username is not None and self.get_user(username) is not None
|
||||
|
||||
@ -98,7 +96,7 @@ class Mapping(Auth):
|
||||
context(str | None): URI request path
|
||||
|
||||
Returns:
|
||||
bool: True in case if user is allowed to do this request and False otherwise
|
||||
bool: ``True`` in case if user is allowed to do this request and ``False`` otherwise
|
||||
"""
|
||||
user = self.get_user(username)
|
||||
return user is not None and user.verify_access(required)
|
||||
|
@ -43,8 +43,6 @@ class OAuth(Mapping):
|
||||
def __init__(self, configuration: Configuration, database: SQLite,
|
||||
provider: AuthSettings = AuthSettings.OAuth) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration instance
|
||||
database(SQLite): database instance
|
||||
|
@ -41,8 +41,6 @@ class PAM(Mapping):
|
||||
def __init__(self, configuration: Configuration, database: SQLite,
|
||||
provider: AuthSettings = AuthSettings.PAM) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration instance
|
||||
database(SQLite): database instance
|
||||
@ -79,7 +77,7 @@ class PAM(Mapping):
|
||||
password(str | None): entered password
|
||||
|
||||
Returns:
|
||||
bool: True in case if password matches, False otherwise
|
||||
bool: ``True`` in case if password matches, ``False`` otherwise
|
||||
"""
|
||||
if password is None:
|
||||
return False # invalid data supplied
|
||||
@ -101,7 +99,7 @@ class PAM(Mapping):
|
||||
username(str): username
|
||||
|
||||
Returns:
|
||||
bool: True in case if user is known and can be authorized and False otherwise
|
||||
bool: ``True`` in case if user is known and can be authorized and ``False`` otherwise
|
||||
"""
|
||||
try:
|
||||
_ = getpwnam(username)
|
||||
@ -119,7 +117,7 @@ class PAM(Mapping):
|
||||
context(str | None): URI request path
|
||||
|
||||
Returns:
|
||||
bool: True in case if user is allowed to do this request and False otherwise
|
||||
bool: ``True`` in case if user is allowed to do this request and ``False`` otherwise
|
||||
"""
|
||||
# this method is basically inverted, first we check overrides in database and then fallback to the PAM logic
|
||||
if (user := self.get_user(username)) is not None:
|
||||
|
@ -17,7 +17,6 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from dataclasses import dataclass
|
||||
from elftools.elf.dynamic import DynamicSection
|
||||
from elftools.elf.elffile import ELFFile
|
||||
from pathlib import Path
|
||||
@ -33,7 +32,6 @@ from ahriman.models.package import Package
|
||||
from ahriman.models.scan_paths import ScanPaths
|
||||
|
||||
|
||||
@dataclass
|
||||
class PackageArchive:
|
||||
"""
|
||||
helper for package archives
|
||||
@ -45,10 +43,18 @@ class PackageArchive:
|
||||
scan_paths(ScanPaths): scan paths holder
|
||||
"""
|
||||
|
||||
root: Path
|
||||
package: Package
|
||||
pacman: Pacman
|
||||
scan_paths: ScanPaths
|
||||
def __init__(self, root: Path, package: Package, pacman: Pacman, scan_paths: ScanPaths) -> None:
|
||||
"""
|
||||
Args:
|
||||
root(Path): path to root filesystem
|
||||
package(Package): package descriptor
|
||||
pacman(Pacman): alpm wrapper instance
|
||||
scan_paths(ScanPaths): scan paths holder
|
||||
"""
|
||||
self.root = root
|
||||
self.package = package
|
||||
self.pacman = pacman
|
||||
self.scan_paths = scan_paths
|
||||
|
||||
@staticmethod
|
||||
def dynamic_needed(binary_path: Path) -> list[str]:
|
||||
@ -109,7 +115,7 @@ class PackageArchive:
|
||||
Returns:
|
||||
FilesystemPackage: generated pacman package model with empty paths
|
||||
"""
|
||||
package_name, *_ = path.parent.name.rsplit("-", 2)
|
||||
package_name, *_ = path.parent.name.rsplit("-", maxsplit=2)
|
||||
try:
|
||||
pacman_package = OfficialSyncdb.info(package_name, pacman=self.pacman)
|
||||
return FilesystemPackage(
|
||||
@ -163,7 +169,7 @@ class PackageArchive:
|
||||
|
||||
result: dict[Path, list[FilesystemPackage]] = {}
|
||||
# sort items from children directories to root
|
||||
for path, packages in reversed(sorted(source.items())):
|
||||
for path, packages in sorted(source.items(), reverse=True):
|
||||
# skip if this path belongs to the one of the base packages
|
||||
if any(package.package_name in base_packages for package in packages):
|
||||
continue
|
||||
@ -228,7 +234,7 @@ class PackageArchive:
|
||||
extract list of the installed packages and their content
|
||||
|
||||
Returns:
|
||||
dict[str, FilesystemPackage]; map of package name to list of directories and files contained
|
||||
dict[str, FilesystemPackage]: map of package name to list of directories and files contained
|
||||
by this package
|
||||
"""
|
||||
result = {}
|
@ -64,8 +64,9 @@ class Sources(LazyLogging):
|
||||
return None # no previous reference found
|
||||
|
||||
instance = Sources()
|
||||
instance.fetch_until(source_dir, commit_sha=last_commit_sha)
|
||||
return instance.diff(source_dir, last_commit_sha)
|
||||
if instance.fetch_until(source_dir, commit_sha=last_commit_sha) is not None:
|
||||
return instance.diff(source_dir, last_commit_sha)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def extend_architectures(sources_dir: Path, architecture: str) -> list[PkgbuildPatch]:
|
||||
@ -138,7 +139,7 @@ class Sources(LazyLogging):
|
||||
sources_dir(Path): local path to git repository
|
||||
|
||||
Returns:
|
||||
bool: True in case if there is any remote and false otherwise
|
||||
bool: ``True`` in case if there is any remote and false otherwise
|
||||
"""
|
||||
instance = Sources()
|
||||
remotes = check_output(*instance.git(), "remote", cwd=sources_dir, logger=instance.logger)
|
||||
@ -261,7 +262,7 @@ class Sources(LazyLogging):
|
||||
commit_author(tuple[str, str] | None, optional): optional commit author if any (Default value = None)
|
||||
|
||||
Returns:
|
||||
bool: True in case if changes have been committed and False otherwise
|
||||
bool: ``True`` in case if changes have been committed and ``False`` otherwise
|
||||
"""
|
||||
if not self.has_changes(sources_dir):
|
||||
return False # nothing to commit
|
||||
@ -298,7 +299,8 @@ class Sources(LazyLogging):
|
||||
args.append(sha)
|
||||
return check_output(*self.git(), "diff", *args, cwd=sources_dir, logger=self.logger)
|
||||
|
||||
def fetch_until(self, sources_dir: Path, *, branch: str | None = None, commit_sha: str | None = None) -> None:
|
||||
def fetch_until(self, sources_dir: Path, *, branch: str | None = None, commit_sha: str | None = None,
|
||||
max_depth: int = 10) -> str | None:
|
||||
"""
|
||||
fetch repository until commit sha
|
||||
|
||||
@ -307,11 +309,16 @@ class Sources(LazyLogging):
|
||||
branch(str | None, optional): use specified branch (Default value = None)
|
||||
commit_sha(str | None, optional): commit hash to fetch. If none set, only one will be fetched
|
||||
(Default value = None)
|
||||
max_depth(int, optional): maximal amount of commits to fetch if ``commit_sha`` is set (Default value = 10)
|
||||
|
||||
Returns:
|
||||
str | None: fetched ``commit_sha`` (if set) and ``None`` in case if commit wasn't found or
|
||||
``commit_sha`` is not set
|
||||
"""
|
||||
commit_sha = commit_sha or "HEAD" # if none set we just fetch the last commit
|
||||
|
||||
commits_count = 1
|
||||
while commit_sha is not None:
|
||||
while commits_count <= max_depth:
|
||||
command = self.git() + ["fetch", "--quiet", "--depth", str(commits_count)]
|
||||
if branch is not None:
|
||||
command += ["origin", branch]
|
||||
@ -320,10 +327,13 @@ class Sources(LazyLogging):
|
||||
try:
|
||||
# check if there is an object in current git directory
|
||||
check_output(*self.git(), "cat-file", "-e", commit_sha, cwd=sources_dir, logger=self.logger)
|
||||
commit_sha = None # reset search
|
||||
return commit_sha # found the required commit
|
||||
except CalledProcessError:
|
||||
commits_count += 1 # increase depth
|
||||
|
||||
# no commits found at the requested depth
|
||||
return None
|
||||
|
||||
def git(self, gitconfig: dict[str, str] | None = None) -> list[str]:
|
||||
"""
|
||||
git command prefix
|
||||
@ -351,7 +361,7 @@ class Sources(LazyLogging):
|
||||
sources_dir(Path): local path to git repository
|
||||
|
||||
Returns:
|
||||
bool: True if there are uncommitted changes and False otherwise
|
||||
bool: ``True`` if there are uncommitted changes and ``False`` otherwise
|
||||
"""
|
||||
# there is --exit-code argument to diff, however, there might be other process errors
|
||||
changes = check_output(*self.git(), "diff", "--cached", "--name-only", cwd=sources_dir, logger=self.logger)
|
||||
|
@ -17,13 +17,14 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from collections.abc import Generator
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.core.build_tools.sources import Sources
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.exceptions import BuildError
|
||||
from ahriman.core.log import LazyLogging
|
||||
from ahriman.core.utils import check_output
|
||||
from ahriman.core.utils import check_output, package_like
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
@ -48,8 +49,6 @@ class Task(LazyLogging):
|
||||
def __init__(self, package: Package, configuration: Configuration, architecture: str,
|
||||
paths: RepositoryPaths) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
package(Package): package definitions
|
||||
configuration(Configuration): configuration instance
|
||||
@ -67,12 +66,43 @@ class Task(LazyLogging):
|
||||
self.makepkg_flags = configuration.getlist("build", "makepkg_flags", fallback=[])
|
||||
self.makechrootpkg_flags = configuration.getlist("build", "makechrootpkg_flags", fallback=[])
|
||||
|
||||
def build(self, sources_dir: Path, **kwargs: str | None) -> list[Path]:
|
||||
def _package_archives(self, sources_dir: Path, source_files: list[Path]) -> list[Path]:
|
||||
"""
|
||||
extract package archives from the directory
|
||||
|
||||
Args:
|
||||
sources_dir(Path): path to where sources are
|
||||
source_files(list[Path]): list of files which were initially in the directory
|
||||
|
||||
Returns:
|
||||
list[Path]: list of file paths which looks like freshly generated archives
|
||||
"""
|
||||
def files() -> Generator[Path, None, None]:
|
||||
for filepath in sources_dir.iterdir():
|
||||
if filepath in source_files:
|
||||
continue # skip files which were already there
|
||||
if filepath.suffix == ".log":
|
||||
continue # skip log files
|
||||
if not package_like(filepath):
|
||||
continue # path doesn't look like a package
|
||||
yield filepath
|
||||
|
||||
# debug packages are always formed as package.base-debug
|
||||
# see /usr/share/makepkg/util/pkgbuild.sh for more details
|
||||
debug_package_prefix = f"{self.package.base}-debug-"
|
||||
return [
|
||||
package
|
||||
for package in files()
|
||||
if self.include_debug_packages or not package.name.startswith(debug_package_prefix)
|
||||
]
|
||||
|
||||
def build(self, sources_dir: Path, *, dry_run: bool = False, **kwargs: str | None) -> list[Path]:
|
||||
"""
|
||||
run package build
|
||||
|
||||
Args:
|
||||
sources_dir(Path): path to where sources are
|
||||
dry_run(bool, optional): do not perform build itself (Default value = False)
|
||||
**kwargs(str | None): environment variables to be passed to build processes
|
||||
|
||||
Returns:
|
||||
@ -82,6 +112,8 @@ class Task(LazyLogging):
|
||||
command.extend(self.archbuild_flags)
|
||||
command.extend(["--"] + self.makechrootpkg_flags)
|
||||
command.extend(["--"] + self.makepkg_flags)
|
||||
if dry_run:
|
||||
command.extend(["--nobuild"])
|
||||
self.logger.info("using %s for %s", command, self.package.base)
|
||||
|
||||
environment: dict[str, str] = {
|
||||
@ -91,6 +123,7 @@ class Task(LazyLogging):
|
||||
}
|
||||
self.logger.info("using environment variables %s", environment)
|
||||
|
||||
source_files = list(sources_dir.iterdir())
|
||||
check_output(
|
||||
*command,
|
||||
exception=BuildError.from_process(self.package.base),
|
||||
@ -100,20 +133,7 @@ class Task(LazyLogging):
|
||||
environment=environment,
|
||||
)
|
||||
|
||||
package_list_command = ["makepkg", "--packagelist"]
|
||||
if not self.include_debug_packages:
|
||||
package_list_command.append("OPTIONS=(!debug)") # disable debug flag manually
|
||||
packages = check_output(
|
||||
*package_list_command,
|
||||
exception=BuildError.from_process(self.package.base),
|
||||
cwd=sources_dir,
|
||||
logger=self.logger,
|
||||
environment=environment,
|
||||
).splitlines()
|
||||
# some dirty magic here
|
||||
# the filter is applied in order to make sure that result will only contain packages which were actually built
|
||||
# e.g. in some cases packagelist command produces debug packages which were not actually built
|
||||
return list(filter(lambda path: path.is_file(), map(Path, packages)))
|
||||
return self._package_archives(sources_dir, source_files)
|
||||
|
||||
def init(self, sources_dir: Path, patches: list[PkgbuildPatch], local_version: str | None) -> str | None:
|
||||
"""
|
||||
|
@ -46,7 +46,8 @@ class Configuration(configparser.RawConfigParser):
|
||||
Examples:
|
||||
Configuration class provides additional method in order to handle application configuration. Since this class is
|
||||
derived from built-in :class:`configparser.RawConfigParser` class, the same flow is applicable here.
|
||||
Nevertheless, it is recommended to use :func:`from_path` class method which also calls initialization methods::
|
||||
Nevertheless, it is recommended to use :func:`from_path()` class method which also calls initialization
|
||||
methods::
|
||||
|
||||
>>> from pathlib import Path
|
||||
>>>
|
||||
@ -57,7 +58,7 @@ class Configuration(configparser.RawConfigParser):
|
||||
The configuration instance loaded in this way will contain only sections which are defined for the specified
|
||||
architecture according to the merge rules. Moreover, the architecture names will be removed from section names.
|
||||
|
||||
In order to get current settings, the :func:`check_loaded` method can be used. This method will raise an
|
||||
In order to get current settings, the :func:`check_loaded()` method can be used. This method will raise an
|
||||
:exc:`ahriman.core.exceptions.InitializeError` in case if configuration was not yet loaded::
|
||||
|
||||
>>> path, repository_id = configuration.check_loaded()
|
||||
@ -70,8 +71,6 @@ class Configuration(configparser.RawConfigParser):
|
||||
|
||||
def __init__(self, allow_no_value: bool = False) -> None:
|
||||
"""
|
||||
default constructor. In the most cases must not be called directly
|
||||
|
||||
Args:
|
||||
allow_no_value(bool, optional): copies :class:`configparser.RawConfigParser` behaviour. In case if it is set
|
||||
to ``True``, the keys without values will be allowed (Default value = False)
|
||||
@ -344,7 +343,8 @@ class Configuration(configparser.RawConfigParser):
|
||||
|
||||
def set_option(self, section: str, option: str, value: str) -> None:
|
||||
"""
|
||||
set option. Unlike default :func:`configparser.RawConfigParser.set` it also creates section if it does not exist
|
||||
set option. Unlike default :func:`configparser.RawConfigParser.set()` it also creates section if
|
||||
it does not exist
|
||||
|
||||
Args:
|
||||
section(str): section name
|
||||
|
@ -169,14 +169,6 @@ CONFIGURATION_SCHEMA: ConfigurationSchema = {
|
||||
"build": {
|
||||
"type": "dict",
|
||||
"schema": {
|
||||
"allowed_scan_paths": {
|
||||
"type": "list",
|
||||
"coerce": "list",
|
||||
"schema": {
|
||||
"type": "path",
|
||||
"coerce": "absolute_path",
|
||||
},
|
||||
},
|
||||
"archbuild_flags": {
|
||||
"type": "list",
|
||||
"coerce": "list",
|
||||
@ -185,14 +177,6 @@ CONFIGURATION_SCHEMA: ConfigurationSchema = {
|
||||
"empty": False,
|
||||
},
|
||||
},
|
||||
"blacklisted_scan_paths": {
|
||||
"type": "list",
|
||||
"coerce": "list",
|
||||
"schema": {
|
||||
"type": "path",
|
||||
"coerce": "absolute_path",
|
||||
},
|
||||
},
|
||||
"build_command": {
|
||||
"type": "string",
|
||||
"required": True,
|
||||
@ -226,6 +210,14 @@ CONFIGURATION_SCHEMA: ConfigurationSchema = {
|
||||
"empty": False,
|
||||
},
|
||||
},
|
||||
"scan_paths": {
|
||||
"type": "list",
|
||||
"coerce": "list",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"empty": False,
|
||||
},
|
||||
},
|
||||
"triggers": {
|
||||
"type": "list",
|
||||
"coerce": "list",
|
||||
|
@ -19,21 +19,84 @@
|
||||
#
|
||||
import configparser
|
||||
import os
|
||||
import sys
|
||||
|
||||
from collections.abc import Mapping, MutableMapping
|
||||
from collections.abc import Generator, Mapping, MutableMapping
|
||||
from string import Template
|
||||
|
||||
from ahriman.core.configuration.shell_template import ShellTemplate
|
||||
|
||||
|
||||
class ShellInterpolator(configparser.Interpolation):
|
||||
"""
|
||||
custom string interpolator, because we cannot use defaults argument due to config validation
|
||||
"""
|
||||
|
||||
DATA_LINK_ESCAPE = "\x10"
|
||||
|
||||
@staticmethod
|
||||
def _extract_variables(parser: MutableMapping[str, Mapping[str, str]], value: str,
|
||||
defaults: Mapping[str, str]) -> Generator[tuple[str, str], None, None]:
|
||||
"""
|
||||
extract keys and values (if available) from the configuration. In case if a key is not available, it will be
|
||||
silently skipped from the result
|
||||
|
||||
Args:
|
||||
parser(MutableMapping[str, Mapping[str, str]]): option parser
|
||||
value(str): source (not-converted) value
|
||||
defaults(Mapping[str, str]): default values
|
||||
|
||||
Yields:
|
||||
tuple[str, str]: variable name used for substitution and its value
|
||||
"""
|
||||
def identifiers() -> Generator[tuple[str | None, str], None, None]:
|
||||
# extract all found identifiers and parse them
|
||||
for identifier in ShellTemplate(value).get_identifiers():
|
||||
match identifier.rsplit(":", maxsplit=1):
|
||||
case [lookup_option]: # single option from the same section
|
||||
yield None, lookup_option
|
||||
case [lookup_section, lookup_option]: # reference to another section
|
||||
yield lookup_section, lookup_option
|
||||
|
||||
for section, option in identifiers():
|
||||
# key to be substituted
|
||||
key = f"{section}:{option}" if section else option
|
||||
|
||||
if section is not None: # foreign section case
|
||||
if section not in parser:
|
||||
continue # section was not found, silently skip it
|
||||
values = parser[section]
|
||||
else: # same section
|
||||
values = defaults
|
||||
|
||||
if (raw := values.get(option)) is not None:
|
||||
yield key, raw
|
||||
|
||||
@staticmethod
|
||||
def environment() -> dict[str, str]:
|
||||
"""
|
||||
extract environment variables
|
||||
|
||||
Returns:
|
||||
dict[str, str]: environment variables and some custom variables
|
||||
"""
|
||||
return os.environ | {
|
||||
"prefix": sys.prefix,
|
||||
}
|
||||
|
||||
def before_get(self, parser: MutableMapping[str, Mapping[str, str]], section: str, option: str, value: str,
|
||||
defaults: Mapping[str, str]) -> str:
|
||||
"""
|
||||
interpolate option value
|
||||
|
||||
Notes:
|
||||
This method is using :class:`string.Template` class in order to render both cross-references and
|
||||
environment variables, because it seems that it is the most legit way to handle it. In addition,
|
||||
we are using shell-like variables in some cases (see :attr:`alpm.mirror` option), thus we would like
|
||||
to keep them alive.
|
||||
|
||||
First this method resolves substitution from the configuration and then renders environment variables
|
||||
|
||||
Args:
|
||||
parser(MutableMapping[str, Mapping[str, str]]): option parser
|
||||
section(str): section name
|
||||
@ -44,8 +107,15 @@ class ShellInterpolator(configparser.Interpolation):
|
||||
Returns:
|
||||
str: substituted value
|
||||
"""
|
||||
# At the moment it seems that it is the most legit way to handle environment variables
|
||||
# Template behaviour is literally the same as shell
|
||||
# In addition, we are using shell-like variables in some cases (see :attr:`alpm.mirror` option),
|
||||
# thus we would like to keep them alive
|
||||
return Template(value).safe_substitute(os.environ)
|
||||
# because any substitution effectively replace escaped $ ($$) in result, we have to escape it manually
|
||||
escaped = value.replace("$$", self.DATA_LINK_ESCAPE)
|
||||
|
||||
# resolve internal references
|
||||
variables = dict(self._extract_variables(parser, value, defaults))
|
||||
internal = ShellTemplate(escaped).safe_substitute(variables)
|
||||
|
||||
# resolve enriched environment variables by using default Template class
|
||||
environment = Template(internal).safe_substitute(self.environment())
|
||||
|
||||
# replace escaped values back
|
||||
return environment.replace(self.DATA_LINK_ESCAPE, "$")
|
||||
|
158
src/ahriman/core/configuration/shell_template.py
Normal file
@ -0,0 +1,158 @@
|
||||
#
|
||||
# Copyright (c) 2021-2024 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import fnmatch
|
||||
import re
|
||||
|
||||
from collections.abc import Generator, Mapping
|
||||
from string import Template
|
||||
|
||||
|
||||
class ShellTemplate(Template):
|
||||
"""
|
||||
extension to the default :class:`Template` class, which also adds additional tokens to braced regex and enables
|
||||
bash expansion
|
||||
|
||||
Attributes:
|
||||
braceidpattern(str): regular expression to match every character except for closing bracket
|
||||
"""
|
||||
|
||||
braceidpattern = r"(?a:[_a-z0-9][^}]*)"
|
||||
|
||||
_REMOVE_BACK = re.compile(r"^(?P<key>\w+)%(?P<pattern>.+)$")
|
||||
_REMOVE_FRONT = re.compile(r"^(?P<key>\w+)#(?P<pattern>.+)$")
|
||||
_REPLACE = re.compile(r"^(?P<key>\w+)/(?P<pattern>.+)/(?P<replacement>.+)$")
|
||||
|
||||
@staticmethod
|
||||
def _remove_back(source: str, pattern: str, *, greedy: bool) -> str:
|
||||
"""
|
||||
resolve "${var%(%)pattern}" constructions
|
||||
|
||||
Args:
|
||||
source(str): source string to match the pattern inside
|
||||
pattern(str): shell expression to match
|
||||
greedy(bool): match as much as possible or not
|
||||
|
||||
Returns:
|
||||
str: result after removal ``pattern`` from the end of the string
|
||||
"""
|
||||
regex = fnmatch.translate(pattern)
|
||||
compiled = re.compile(regex)
|
||||
|
||||
result = source
|
||||
start_pos = 0
|
||||
|
||||
while m := compiled.search(source, start_pos):
|
||||
result = source[:m.start()]
|
||||
start_pos += m.start() + 1
|
||||
if greedy:
|
||||
break
|
||||
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def _remove_front(source: str, pattern: str, *, greedy: bool) -> str:
|
||||
"""
|
||||
resolve "${var#(#)pattern}" constructions
|
||||
|
||||
Args:
|
||||
source(str): source string to match the pattern inside
|
||||
pattern(str): shell expression to match
|
||||
greedy(bool): match as much as possible or not
|
||||
|
||||
Returns:
|
||||
str: result after removal ``pattern`` from the start of the string
|
||||
"""
|
||||
regex = fnmatch.translate(pattern)[:-2] # remove \Z at the end of the regex
|
||||
if not greedy:
|
||||
regex = regex.replace("*", "*?")
|
||||
compiled = re.compile(regex)
|
||||
|
||||
m = compiled.match(source)
|
||||
if m is None:
|
||||
return source
|
||||
|
||||
return source[m.end():]
|
||||
|
||||
@staticmethod
|
||||
def _replace(source: str, pattern: str, replacement: str, *, greedy: bool) -> str:
|
||||
"""
|
||||
resolve "${var/(/)pattern/replacement}" constructions
|
||||
|
||||
Args:
|
||||
source(str): source string to match the pattern inside
|
||||
pattern(str): shell expression to match
|
||||
replacement(str): new substring
|
||||
greedy(bool): replace as much as possible or not
|
||||
|
||||
Returns:
|
||||
str: result after replacing ``pattern`` by ``replacement``
|
||||
"""
|
||||
match pattern:
|
||||
case from_back if from_back.startswith("%"):
|
||||
removed = ShellTemplate._remove_back(source, from_back[1:], greedy=False)
|
||||
return removed if removed == source else removed + replacement
|
||||
|
||||
case from_front if from_front.startswith("#"):
|
||||
removed = ShellTemplate._remove_front(source, from_front[1:], greedy=False)
|
||||
return removed if removed == source else replacement + removed
|
||||
|
||||
case regular:
|
||||
regex = fnmatch.translate(regular)[:-2] # remove \Z at the end of the regex
|
||||
compiled = re.compile(regex)
|
||||
return compiled.sub(replacement, source, count=not greedy)
|
||||
|
||||
def shell_substitute(self, mapping: Mapping[str, str], /, **kwargs: str) -> str:
|
||||
"""
|
||||
this method behaves the same as :func:`safe_substitute`, however also expands bash string operations
|
||||
|
||||
Args:
|
||||
mapping(Mapping[str, str]): key-value dictionary of variables
|
||||
**kwargs(str): key-value dictionary of variables passed as kwargs
|
||||
|
||||
Returns:
|
||||
str: string with replaced values
|
||||
"""
|
||||
substitutions = (
|
||||
(self._REMOVE_BACK, self._remove_back, "%"),
|
||||
(self._REMOVE_FRONT, self._remove_front, "#"),
|
||||
(self._REPLACE, self._replace, "/"),
|
||||
)
|
||||
|
||||
def generator(variables: dict[str, str]) -> Generator[tuple[str, str], None, None]:
|
||||
for identifier in self.get_identifiers():
|
||||
for regex, function, greediness in substitutions:
|
||||
if m := regex.match(identifier):
|
||||
source = variables.get(m.group("key"))
|
||||
if source is None:
|
||||
continue
|
||||
|
||||
# replace pattern with non-greedy
|
||||
pattern = m.group("pattern").removeprefix(greediness)
|
||||
greedy = m.group("pattern").startswith(greediness)
|
||||
# gather all additional args
|
||||
args = {key: value for key, value in m.groupdict().items() if key not in ("key", "pattern")}
|
||||
|
||||
yield identifier, function(source, pattern, **args, greedy=greedy)
|
||||
break
|
||||
|
||||
kwargs.update(mapping)
|
||||
substituted = dict(generator(kwargs))
|
||||
|
||||
return self.safe_substitute(kwargs | substituted)
|
@ -35,13 +35,12 @@ class Validator(RootValidator):
|
||||
configuration(Configuration): configuration instance
|
||||
"""
|
||||
|
||||
types_mapping = RootValidator.types_mapping.copy()
|
||||
types_mapping["path"] = TypeDefinition("path", (Path,), ())
|
||||
types_mapping = RootValidator.types_mapping | {
|
||||
"path": TypeDefinition("path", (Path,), ()),
|
||||
}
|
||||
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
"""
|
||||
default constructor
|
||||
|
||||
Args:
|
||||
configuration(Configuration): configuration instance used for extraction
|
||||
*args(Any): positional arguments to be passed to base validator
|
||||
@ -149,7 +148,7 @@ class Validator(RootValidator):
|
||||
check if paths exists
|
||||
|
||||
Args:
|
||||
constraint(bool): True in case if path must exist and False otherwise
|
||||
constraint(bool): ``True`` in case if path must exist and ``False`` otherwise
|
||||
field(str): field name to be checked
|
||||
value(Path): value to be checked
|
||||
|
||||
|