From 1714dff877af18922a23847e931915e3bcf407e3 Mon Sep 17 00:00:00 2001 From: Nathaniel Landau Date: Thu, 28 Dec 2023 15:47:10 -0500 Subject: [PATCH] feat: add gitea --- .pre-commit-config.yaml | 2 +- README.md | 3 +- default_variables.yml | 4 +- poetry.lock | 228 ++++++------- templates/nomad_jobs/gitea.hcl | 353 ++++++++++++++++++++ templates/nomad_jobs/reverse-proxy.hcl | 11 +- templates/scripts/service_backups.sh.j2 | 3 +- vault.yml | 422 ++++++++++++------------ 8 files changed, 697 insertions(+), 329 deletions(-) create mode 100644 templates/nomad_jobs/gitea.hcl diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c67f8be..a463c94 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -44,7 +44,7 @@ repos: entry: yamllint --strict --config-file .yamllint.yml - repo: "https://github.com/crate-ci/typos" - rev: v1.16.25 + rev: v1.16.26 hooks: - id: typos diff --git a/README.md b/README.md index 5377265..33925bf 100644 --- a/README.md +++ b/README.md @@ -41,14 +41,13 @@ This playbook adds storage, services, applications, and configurations to a prev - Custom shell scripts for backups and house keeping * **Syncs Nomad and Docker Compose job files** to servers: - - [ASN-to-IP](https://hub.docker.com/r/ddimick/asn-to-ip) - Used by Opnsense to build firewall aliases - [Authelia](https://www.authelia.com/) - Open-source full-featured authentication server - [Changedetection.io](https://github.com/dgtlmoon/changedetection.io) - Website change detection monitoring and notification service - [Diun](https://crazymax.dev/diun/) - Docker Image Update Notifier is a CLI application - [FreshRSS](https://freshrss.org/) - A containerized RSS reader + - [Gitea](https://about.gitea.com/) - Slef-hodted Git service - [Grafana](https://grafana.com/) - Operational dashboards - [Grafana Loki](https://grafana.com/oss/loki/) - Log aggregation system - - [Headless Trunk](https://github.com/alpeware/chrome-headless-trunk) - Headless Chromium - [iCloud Drive Docker](https://github.com/mandarons/icloud-drive-docker) - Backup files and photos from Apple iCloud - [InfluxDB](https://www.influxdata.com/) - Time series database - [Lidarr](https://lidarr.audio/) - Music collection manager diff --git a/default_variables.yml b/default_variables.yml index a6080cc..ffea5ea 100644 --- a/default_variables.yml +++ b/default_variables.yml @@ -1,7 +1,9 @@ --- # ---------------------------------- SOFTWARE VERSIONS authelia_version: 4.37.5 +backup_mongodb_version: 1.1.0 consul_version: 1.16.1 +gitea_version: 1.21.3 influxdb_version: 1.11.1 nomad_version: 1.7.1 prometheus_verssion: 2.46.0 @@ -11,7 +13,6 @@ tdarr_installer_version: 2.00.13 telegraf_version: 1.28.4 traefik_version: 2.10.7 valentina_version: 2.1.0 -backup_mongodb_version: 1.1.0 # ---------------------------------- SERVICE STATIC PORT MAPPINGS influxdb_port: "8086" @@ -22,6 +23,7 @@ tdarr_webui_port: "8265" # ---------------------------------- DIRECTORIES FOR SERVICE LOCAL STORAGE # These folders must be created, even if empty, to allow mounting nomad local storage end-points service_localfs_dirs: + - gitea - influxdb - lidarr - prowlarr diff --git a/poetry.lock b/poetry.lock index c8be031..3691863 100644 --- a/poetry.lock +++ b/poetry.lock @@ -490,13 +490,13 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- [[package]] name = "jsonschema-specifications" -version = "2023.11.2" +version = "2023.12.1" description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" optional = false python-versions = ">=3.8" files = [ - {file = "jsonschema_specifications-2023.11.2-py3-none-any.whl", hash = "sha256:e74ba7c0a65e8cb49dc26837d6cfe576557084a8b423ed16a420984228104f93"}, - {file = "jsonschema_specifications-2023.11.2.tar.gz", hash = "sha256:9472fc4fea474cd74bea4a2b190daeccb5a9e4db2ea80efcf7a1b582fc9a81b8"}, + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, ] [package.dependencies] @@ -884,110 +884,110 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "rpds-py" -version = "0.15.2" +version = "0.16.1" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.8" files = [ - {file = "rpds_py-0.15.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:337a8653fb11d2fbe7157c961cc78cb3c161d98cf44410ace9a3dc2db4fad882"}, - {file = "rpds_py-0.15.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:813a65f95bfcb7c8f2a70dd6add9b51e9accc3bdb3e03d0ff7a9e6a2d3e174bf"}, - {file = "rpds_py-0.15.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:082e0e55d73690ffb4da4352d1b5bbe1b5c6034eb9dc8c91aa2a3ee15f70d3e2"}, - {file = "rpds_py-0.15.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5595c80dd03d7e6c6afb73f3594bf3379a7d79fa57164b591d012d4b71d6ac4c"}, - {file = "rpds_py-0.15.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fb10bb720348fe1647a94eb605accb9ef6a9b1875d8845f9e763d9d71a706387"}, - {file = "rpds_py-0.15.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:53304cc14b1d94487d70086e1cb0cb4c29ec6da994d58ae84a4d7e78c6a6d04d"}, - {file = "rpds_py-0.15.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d64a657de7aae8db2da60dc0c9e4638a0c3893b4d60101fd564a3362b2bfeb34"}, - {file = "rpds_py-0.15.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ee40206d1d6e95eaa2b7b919195e3689a5cf6ded730632de7f187f35a1b6052c"}, - {file = "rpds_py-0.15.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1607cda6129f815493a3c184492acb5ae4aa6ed61d3a1b3663aa9824ed26f7ac"}, - {file = "rpds_py-0.15.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3e6e2e502c4043c52a99316d89dc49f416acda5b0c6886e0dd8ea7bb35859e8"}, - {file = "rpds_py-0.15.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:044f6f46d62444800402851afa3c3ae50141f12013060c1a3a0677e013310d6d"}, - {file = "rpds_py-0.15.2-cp310-none-win32.whl", hash = "sha256:c827a931c6b57f50f1bb5de400dcfb00bad8117e3753e80b96adb72d9d811514"}, - {file = "rpds_py-0.15.2-cp310-none-win_amd64.whl", hash = "sha256:3bbc89ce2a219662ea142f0abcf8d43f04a41d5b1880be17a794c39f0d609cb0"}, - {file = "rpds_py-0.15.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:1fd0f0b1ccd7d537b858a56355a250108df692102e08aa2036e1a094fd78b2dc"}, - {file = "rpds_py-0.15.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b414ef79f1f06fb90b5165db8aef77512c1a5e3ed1b4807da8476b7e2c853283"}, - {file = "rpds_py-0.15.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c31272c674f725dfe0f343d73b0abe8c878c646967ec1c6106122faae1efc15b"}, - {file = "rpds_py-0.15.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a6945c2d61c42bb7e818677f43638675b8c1c43e858b67a96df3eb2426a86c9d"}, - {file = "rpds_py-0.15.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02744236ac1895d7be837878e707a5c35fb8edc5137602f253b63623d7ad5c8c"}, - {file = "rpds_py-0.15.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2181e86d4e1cdf49a7320cb72a36c45efcb7670d0a88f09fd2d3a7967c0540fd"}, - {file = "rpds_py-0.15.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a8ff8e809da81363bffca2b965cb6e4bf6056b495fc3f078467d1f8266fe27f"}, - {file = "rpds_py-0.15.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:97532802f14d383f37d603a56e226909f825a83ff298dc1b6697de00d2243999"}, - {file = "rpds_py-0.15.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:13716e53627ad97babf72ac9e01cf9a7d4af2f75dd5ed7b323a7a9520e948282"}, - {file = "rpds_py-0.15.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2f1f295a5c28cfa74a7d48c95acc1c8a7acd49d7d9072040d4b694fe11cd7166"}, - {file = "rpds_py-0.15.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8ec464f20fe803ae00419bd1610934e3bda963aeba1e6181dfc9033dc7e8940c"}, - {file = "rpds_py-0.15.2-cp311-none-win32.whl", hash = "sha256:b61d5096e75fd71018b25da50b82dd70ec39b5e15bb2134daf7eb7bbbc103644"}, - {file = "rpds_py-0.15.2-cp311-none-win_amd64.whl", hash = "sha256:9d41ebb471a6f064c0d1c873c4f7dded733d16ca5db7d551fb04ff3805d87802"}, - {file = "rpds_py-0.15.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:13ff62d3561a23c17341b4afc78e8fcfd799ab67c0b1ca32091d71383a98ba4b"}, - {file = "rpds_py-0.15.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b70b45a40ad0798b69748b34d508259ef2bdc84fb2aad4048bc7c9cafb68ddb3"}, - {file = "rpds_py-0.15.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4ecbba7efd82bd2a4bb88aab7f984eb5470991c1347bdd1f35fb34ea28dba6e"}, - {file = "rpds_py-0.15.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9d38494a8d21c246c535b41ecdb2d562c4b933cf3d68de03e8bc43a0d41be652"}, - {file = "rpds_py-0.15.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:13152dfe7d7c27c40df8b99ac6aab12b978b546716e99f67e8a67a1d441acbc3"}, - {file = "rpds_py-0.15.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:164fcee32f15d04d61568c9cb0d919e37ff3195919cd604039ff3053ada0461b"}, - {file = "rpds_py-0.15.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a5122b17a4faf5d7a6d91fa67b479736c0cacc7afe791ddebb7163a8550b799"}, - {file = "rpds_py-0.15.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:46b4f3d47d1033db569173be62365fbf7808c2bd3fb742314d251f130d90d44c"}, - {file = "rpds_py-0.15.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c61e42b4ceb9759727045765e87d51c1bb9f89987aca1fcc8a040232138cad1c"}, - {file = "rpds_py-0.15.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d2aa3ca9552f83b0b4fa6ca8c6ce08da6580f37e3e0ab7afac73a1cfdc230c0e"}, - {file = "rpds_py-0.15.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ec19e823b4ccd87bd69e990879acbce9e961fc7aebe150156b8f4418d4b27b7f"}, - {file = "rpds_py-0.15.2-cp312-none-win32.whl", hash = "sha256:afeabb382c1256a7477b739820bce7fe782bb807d82927102cee73e79b41b38b"}, - {file = "rpds_py-0.15.2-cp312-none-win_amd64.whl", hash = "sha256:422b0901878a31ef167435c5ad46560362891816a76cc0d150683f3868a6f0d1"}, - {file = "rpds_py-0.15.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:baf744e5f9d5ee6531deea443be78b36ed1cd36c65a0b95ea4e8d69fa0102268"}, - {file = "rpds_py-0.15.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7e072f5da38d6428ba1fc1115d3cc0dae895df671cb04c70c019985e8c7606be"}, - {file = "rpds_py-0.15.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f138f550b83554f5b344d6be35d3ed59348510edc3cb96f75309db6e9bfe8210"}, - {file = "rpds_py-0.15.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b2a4cd924d0e2f4b1a68034abe4cadc73d69ad5f4cf02db6481c0d4d749f548f"}, - {file = "rpds_py-0.15.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5eb05b654a41e0f81ab27a7c3e88b6590425eb3e934e1d533ecec5dc88a6ffff"}, - {file = "rpds_py-0.15.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2ee066a64f0d2ba45391cac15b3a70dcb549e968a117bd0500634754cfe0e5fc"}, - {file = "rpds_py-0.15.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c51a899792ee2c696072791e56b2020caff58b275abecbc9ae0cb71af0645c95"}, - {file = "rpds_py-0.15.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac2ac84a4950d627d84b61f082eba61314373cfab4b3c264b62efab02ababe83"}, - {file = "rpds_py-0.15.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:62b292fff4739c6be89e6a0240c02bda5a9066a339d90ab191cf66e9fdbdc193"}, - {file = "rpds_py-0.15.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:98ee201a52a7f65608e5494518932e1473fd43535f12cade0a1b4ab32737fe28"}, - {file = "rpds_py-0.15.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3d40fb3ca22e3d40f494d577441b263026a3bd8c97ae6ce89b2d3c4b39ac9581"}, - {file = "rpds_py-0.15.2-cp38-none-win32.whl", hash = "sha256:30479a9f1fce47df56b07460b520f49fa2115ec2926d3b1303c85c81f8401ed1"}, - {file = "rpds_py-0.15.2-cp38-none-win_amd64.whl", hash = "sha256:2df3d07a16a3bef0917b28cd564778fbb31f3ffa5b5e33584470e2d1b0f248f0"}, - {file = "rpds_py-0.15.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:56b51ba29a18e5f5810224bcf00747ad931c0716e3c09a76b4a1edd3d4aba71f"}, - {file = "rpds_py-0.15.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3c11bc5814554b018f6c5d6ae0969e43766f81e995000b53a5d8c8057055e886"}, - {file = "rpds_py-0.15.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2faa97212b0dc465afeedf49045cdd077f97be1188285e646a9f689cb5dfff9e"}, - {file = "rpds_py-0.15.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:86c01299942b0f4b5b5f28c8701689181ad2eab852e65417172dbdd6c5b3ccc8"}, - {file = "rpds_py-0.15.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd7d3608589072f63078b4063a6c536af832e76b0b3885f1bfe9e892abe6c207"}, - {file = "rpds_py-0.15.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:938518a11780b39998179d07f31a4a468888123f9b00463842cd40f98191f4d3"}, - {file = "rpds_py-0.15.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2dccc623725d0b298f557d869a68496a2fd2a9e9c41107f234fa5f7a37d278ac"}, - {file = "rpds_py-0.15.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d46ee458452727a147d7897bb33886981ae1235775e05decae5d5d07f537695a"}, - {file = "rpds_py-0.15.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d9d7ebcd11ea76ba0feaae98485cd8e31467c3d7985210fab46983278214736b"}, - {file = "rpds_py-0.15.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:8a5f574b92b3ee7d254e56d56e37ec0e1416acb1ae357c4956d76a1788dc58fb"}, - {file = "rpds_py-0.15.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3db0c998c92b909d7c90b66c965590d4f3cd86157176a6cf14aa1f867b77b889"}, - {file = "rpds_py-0.15.2-cp39-none-win32.whl", hash = "sha256:bbc7421cbd28b4316d1d017db338039a7943f945c6f2bb15e1439b14b5682d28"}, - {file = "rpds_py-0.15.2-cp39-none-win_amd64.whl", hash = "sha256:1c24e30d720c0009b6fb2e1905b025da56103c70a8b31b99138e4ed1c2a6c5b0"}, - {file = "rpds_py-0.15.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1e6fcd0a0f62f2997107f758bb372397b8d5fd5f39cc6dcb86f7cb98a2172d6c"}, - {file = "rpds_py-0.15.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d800a8e2ac62db1b9ea5d6d1724f1a93c53907ca061de4d05ed94e8dfa79050c"}, - {file = "rpds_py-0.15.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e09d017e3f4d9bd7d17a30d3f59e4d6d9ba2d2ced280eec2425e84112cf623f"}, - {file = "rpds_py-0.15.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b88c3ab98556bc351b36d6208a6089de8c8db14a7f6e1f57f82a334bd2c18f0b"}, - {file = "rpds_py-0.15.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f333bfe782a2d05a67cfaa0cc9cd68b36b39ee6acfe099f980541ed973a7093"}, - {file = "rpds_py-0.15.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b629db53fe17e6ce478a969d30bd1d0e8b53238c46e3a9c9db39e8b65a9ef973"}, - {file = "rpds_py-0.15.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:485fbdd23becb822804ed05622907ee5c8e8a5f43f6f43894a45f463b2217045"}, - {file = "rpds_py-0.15.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:893e38d0f4319dfa70c0f36381a37cc418985c87b11d9784365b1fff4fa6973b"}, - {file = "rpds_py-0.15.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:8ffdeb7dbd0160d4e391e1f857477e4762d00aa2199c294eb95dfb9451aa1d9f"}, - {file = "rpds_py-0.15.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:fc33267d58dfbb2361baed52668c5d8c15d24bc0372cecbb79fed77339b55e0d"}, - {file = "rpds_py-0.15.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:2e7e5633577b3bd56bf3af2ef6ae3778bbafb83743989d57f0e7edbf6c0980e4"}, - {file = "rpds_py-0.15.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:8b9650f92251fdef843e74fc252cdfd6e3c700157ad686eeb0c6d7fdb2d11652"}, - {file = "rpds_py-0.15.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:07a2e1d78d382f7181789713cdf0c16edbad4fe14fe1d115526cb6f0eef0daa3"}, - {file = "rpds_py-0.15.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03f9c5875515820633bd7709a25c3e60c1ea9ad1c5d4030ce8a8c203309c36fd"}, - {file = "rpds_py-0.15.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:580182fa5b269c2981e9ce9764367cb4edc81982ce289208d4607c203f44ffde"}, - {file = "rpds_py-0.15.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa1e626c524d2c7972c0f3a8a575d654a3a9c008370dc2a97e46abd0eaa749b9"}, - {file = "rpds_py-0.15.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae9d83a81b09ce3a817e2cbb23aabc07f86a3abc664c613cd283ce7a03541e95"}, - {file = "rpds_py-0.15.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9235be95662559141934fced8197de6fee8c58870f36756b0584424b6d708393"}, - {file = "rpds_py-0.15.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a72e00826a2b032dda3eb25aa3e3579c6d6773d22d8446089a57a123481cc46c"}, - {file = "rpds_py-0.15.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:ab095edf1d840a6a6a4307e1a5b907a299a94e7b90e75436ee770b8c35d22a25"}, - {file = "rpds_py-0.15.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:3b79c63d29101cbaa53a517683557bb550462394fb91044cc5998dd2acff7340"}, - {file = "rpds_py-0.15.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:911e600e798374c0d86235e7ef19109cf865d1336942d398ff313375a25a93ba"}, - {file = "rpds_py-0.15.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3cd61e759c4075510052d1eca5cddbd297fe1164efec14ef1fce3f09b974dfe4"}, - {file = "rpds_py-0.15.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:9d2ae79f31da5143e020a8d4fc74e1f0cbcb8011bdf97453c140aa616db51406"}, - {file = "rpds_py-0.15.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e99d6510c8557510c220b865d966b105464740dcbebf9b79ecd4fbab30a13d9"}, - {file = "rpds_py-0.15.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c43e1b89099279cc03eb1c725c5de12af6edcd2f78e2f8a022569efa639ada3"}, - {file = "rpds_py-0.15.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7187bee72384b9cfedf09a29a3b2b6e8815cc64c095cdc8b5e6aec81e9fd5f"}, - {file = "rpds_py-0.15.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3423007fc0661827e06f8a185a3792c73dda41f30f3421562f210cf0c9e49569"}, - {file = "rpds_py-0.15.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2974e6dff38afafd5ccf8f41cb8fc94600b3f4fd9b0a98f6ece6e2219e3158d5"}, - {file = "rpds_py-0.15.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:93c18a1696a8e0388ed84b024fe1a188a26ba999b61d1d9a371318cb89885a8c"}, - {file = "rpds_py-0.15.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:c7cd0841a586b7105513a7c8c3d5c276f3adc762a072d81ef7fae80632afad1e"}, - {file = "rpds_py-0.15.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:709dc11af2f74ba89c68b1592368c6edcbccdb0a06ba77eb28c8fe08bb6997da"}, - {file = "rpds_py-0.15.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:fc066395e6332da1e7525d605b4c96055669f8336600bef8ac569d5226a7c76f"}, - {file = "rpds_py-0.15.2.tar.gz", hash = "sha256:373b76eeb79e8c14f6d82cb1d4d5293f9e4059baec6c1b16dca7ad13b6131b39"}, + {file = "rpds_py-0.16.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:792f138f63483f99ef7c19b3df64e53e4554f6240baa2d8c64ce98ee3b9e4e82"}, + {file = "rpds_py-0.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fdeee48341011c17f06584b175e36536944eb45131068677d0195da16567a15b"}, + {file = "rpds_py-0.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a2b7de57a1722b1cd1e9929e951b5e40c678fd46512e8f2be819c102611b845"}, + {file = "rpds_py-0.16.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5babe9d51d7b4fccd6c010e73dff0aa4e390cf7fe9c20d58f537c5095871917e"}, + {file = "rpds_py-0.16.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fdd2add869c6db24e1fff50979c05621f03947862d4c7acf7a59cd2a44027db5"}, + {file = "rpds_py-0.16.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3516725341fe27785907e52c9c37fbe4f3b64ad9a31be6007f4148d3657e4257"}, + {file = "rpds_py-0.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:201493fac02b039fab728dd2e3f5b37b96d52c5d329fd2d4a8c5225cd7e5072b"}, + {file = "rpds_py-0.16.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:df12cbf2e54700069993240a2b4d6a1c18124ec385cde7d8001114c4690e7728"}, + {file = "rpds_py-0.16.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ae090b430d3acc1f6e1779144ec6350d14ad8425fd5dee6caf4d062294be523a"}, + {file = "rpds_py-0.16.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:820cec9605fe49c2fa5f5f4a4373ea0c841e08372553135b71b84b18ea10e770"}, + {file = "rpds_py-0.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bda6636c95cf5c39c7dd8b68e61fd9c528e95230945f426bce8e1c7a43875969"}, + {file = "rpds_py-0.16.1-cp310-none-win32.whl", hash = "sha256:63cc52aa1ded5c886fc5d479069081ad3586dae59b39d2dfb724a66e8e08bef5"}, + {file = "rpds_py-0.16.1-cp310-none-win_amd64.whl", hash = "sha256:510d6cc8a5784688e658998510396bf18fd1d85fdacbdcea969144b9750fca94"}, + {file = "rpds_py-0.16.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:30aa74da7b76d93ca7a1c9eff42b4c650ee98ceb88fd8160fa83e6af430f0ecd"}, + {file = "rpds_py-0.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:20d83968639bda065ca2fb7e815c90751a782d31a4c1eac028746a2ea23efa29"}, + {file = "rpds_py-0.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c1a305ee915be646ae5fe0cf0c775c2c286b52bbd32e8ddc7830741d8956715"}, + {file = "rpds_py-0.16.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:98a6a3e55b7815d518ca997fd0e2df16d558eadc4211de26644639b9bfe9380a"}, + {file = "rpds_py-0.16.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ee6551d46516188e532a6eb3323065ee49d518dbe4701b68d7c78d33f9de340"}, + {file = "rpds_py-0.16.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eec4c366f8b425ab4c0991547dfb828f4b18c5bff8a83d27e145accbb5e566db"}, + {file = "rpds_py-0.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9cc14b9271fef5ddddd6cd040661cfbd962b2468eafd3228c1886b231d54e88d"}, + {file = "rpds_py-0.16.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6b6500b49ef4945b8e3e8da18cc8de10b92a8e7ce0b04eeaa42e0c471181bfae"}, + {file = "rpds_py-0.16.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cf0b7e52a8f63001d590d4409bc5707f04666fb560932e83fc42cf17f27dce3e"}, + {file = "rpds_py-0.16.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e99e67dede119b93ef15baf8ecdd6823709fd7be137db9e9367c90dff0f33cdf"}, + {file = "rpds_py-0.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:40b946e611bc58d6bcf669c7a53584d00419bdd2c7686e7eed358c6baddd6e37"}, + {file = "rpds_py-0.16.1-cp311-none-win32.whl", hash = "sha256:23e2bbcb2a0476082816d8fb772f6a9543ff56838289ca2c35887f458cb1ee72"}, + {file = "rpds_py-0.16.1-cp311-none-win_amd64.whl", hash = "sha256:b5708db83ab76562222ae370378e7015215f119065e80b6340221545abd5cd55"}, + {file = "rpds_py-0.16.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:8bd5512a13b5453d32654ac2526de57b6eb49a9448f671f1a641b8fb96de8c55"}, + {file = "rpds_py-0.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:69ec027b386866d8f4cd7d376215cb4b0b20651936ee896609b5f70e8f1253a1"}, + {file = "rpds_py-0.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12355871f989ff4f203cfe4e29f5ab9e39963209f0d9d0d532f8c857183c796f"}, + {file = "rpds_py-0.16.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a2ae2f423ca5f17f48d1eb31668ff76985eb6d856abb85356ce30bbf5b94359c"}, + {file = "rpds_py-0.16.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62918097d5b35786286ba097cc69fede032317440fa4aad2bef5f3c45184401b"}, + {file = "rpds_py-0.16.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:435044c335d5031115a397c6640b7bb43b7410d8be6112706a9bf091f428a783"}, + {file = "rpds_py-0.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce8994443b937460cee239f75bbae7caa5b74bbfcc55d8201307b538683411e"}, + {file = "rpds_py-0.16.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e209d3c700953e97dff23edee1d12f5f2e13e1110d5746413f83dfe58a342fd1"}, + {file = "rpds_py-0.16.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:24a97715c25169724398bf8b9cd6717cf8d0f7a56c0da9033c31728ab3c05cb3"}, + {file = "rpds_py-0.16.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e99077a6639ca9cd9326806da2db109b1fee1fed8a11715fdb5a21820eb8f122"}, + {file = "rpds_py-0.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4248aa22af2de482eeee762e2e51a470a72472a96facb4a59c286443f2696b06"}, + {file = "rpds_py-0.16.1-cp312-none-win32.whl", hash = "sha256:c0220dad4238cb78252faea9146691d545e25fd3aedca59ace138cd1275ff6b0"}, + {file = "rpds_py-0.16.1-cp312-none-win_amd64.whl", hash = "sha256:e00f9da9b0887002460e1cd39e44b6abc6828cc29a29b08d1459e31c3afad02a"}, + {file = "rpds_py-0.16.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4e3598aad6539a7c31c69e9d93117bdf7e6946c39487c0a0d0c86c63a12112d8"}, + {file = "rpds_py-0.16.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bb59a4bf53133ce6b2d918dc9b2f7a5547386d3de75432e712aa331504af9ffe"}, + {file = "rpds_py-0.16.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5278f126efc81860a62d861a7b08ce36eef57d0a97684e2e4c8929cfda1f566"}, + {file = "rpds_py-0.16.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d90e9be6b7cc84219c8bbd64d6ab4c3cc17b9ca1c7152fb1a4f50dc51f1dffef"}, + {file = "rpds_py-0.16.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dffeeb88610a5fb56a7e2d68ae3c14fc5cb585c0552825f20119a6c6879bb08b"}, + {file = "rpds_py-0.16.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:727144c480ad38372e4761130d144e362b999e934c698d22cd51fa0c33f6f2f7"}, + {file = "rpds_py-0.16.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:587205e703db5751cb632e7132c31cf3216dc5f376be6ad93c393056e8b991ee"}, + {file = "rpds_py-0.16.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:448e6df9772885e9f57116d3d5f7ea8521ec6145cd39c3dbeab7aad4836b05d4"}, + {file = "rpds_py-0.16.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:3c4c9a0ad3deb59f60bdb221f2fad30843799f98b03a89c3887eb016365241df"}, + {file = "rpds_py-0.16.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:82ced65af53435b1d2f435e7b079f1066137cb98dc0729ef7f86bb464e95481f"}, + {file = "rpds_py-0.16.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:50a269dbf1922d28826f87cd04721c8fa8f4ef40879ada27a1902a06cffb6b06"}, + {file = "rpds_py-0.16.1-cp38-none-win32.whl", hash = "sha256:774ade8a1c29d9f999c130896a67e6b290a86909e42ebed5ff0191a19efee3d8"}, + {file = "rpds_py-0.16.1-cp38-none-win_amd64.whl", hash = "sha256:7b0b6509f654f84db53063e2e3691b4f2d1411f2f1014309022431321e3e2ce0"}, + {file = "rpds_py-0.16.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c6abe54b71f38e9d2f7c2c233741576adec3e48449ebc4dcce8c5957e7758439"}, + {file = "rpds_py-0.16.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:acdc3510ba49681bbf7a33fbed59fa14a6e328bb25d0f37e3256683c8b6dbd34"}, + {file = "rpds_py-0.16.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7efbe86bffbfcbde93a4e22a71670d8bd35973c851390a94e7c28ade561b4aa"}, + {file = "rpds_py-0.16.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5ba7eac8523cc81452c5cfa6b141ad15df848245d94faaf8c8fb6b95256d3af6"}, + {file = "rpds_py-0.16.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:da803b01bbf7c2d1632d198f80086da152ff30b07dc8c2073a527c056852a8f2"}, + {file = "rpds_py-0.16.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bca0e3439a004e4d9b2cc8d46d4a57b299ceceb8c18730129f539e27f54a1fe3"}, + {file = "rpds_py-0.16.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6956bbda072ca7d591a048b86cce8c59be8a5da5b782aa12b72d189c3a007a5e"}, + {file = "rpds_py-0.16.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:309f9817ecea8e7ef02339cfd74a31ec630f6fb53f3559990c85120b3c7832c8"}, + {file = "rpds_py-0.16.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f780d89470faf8bfb632ce0ec6d042784717c688487b70929ee61fc1badca158"}, + {file = "rpds_py-0.16.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4ea9dc952180bc4bba4f7f9963ea921548b1c0a254bf7566e8433fec78ed086b"}, + {file = "rpds_py-0.16.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9f439574a55efe129022320a40e53a5001fe589c0ce21659e46079c4cc1b23e9"}, + {file = "rpds_py-0.16.1-cp39-none-win32.whl", hash = "sha256:fa33a96e2063a79e579fff90addcc45e74f86df76700fd2986550e9b6535cb71"}, + {file = "rpds_py-0.16.1-cp39-none-win_amd64.whl", hash = "sha256:0b6ad2b11596e1086cd2c7769fd2929d6ec304cfbcfb5be9abf20df3e0ccc8e1"}, + {file = "rpds_py-0.16.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:afd57d572fb85aba549f9f257afe3edfbda60d5d30370ca6e832d4595c1ce56d"}, + {file = "rpds_py-0.16.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b979a45800a341aa29e443988b7c68c1c3b0992b4a723e802bf24e82dfa4e83d"}, + {file = "rpds_py-0.16.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13e370110e57d261b7ddc2a89223f4d06e6a0cdc67db4c93708c2a114577058b"}, + {file = "rpds_py-0.16.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:150322f3ccb4e1a8140cfd0cc7e6c1588ddeac040afd655e84d0a225cbf86a39"}, + {file = "rpds_py-0.16.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c6c0f15faef597236a774cc321bbf520d86a7350f2a598a47f8bd61265c2aca"}, + {file = "rpds_py-0.16.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ffbd6258184445bb6cdfff8da5c004186e6dce1c06d9dce16a1a69b3c47e718"}, + {file = "rpds_py-0.16.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f9fc0875092ac51be790b665cfc4d296d893119b267e9c17863bc01a447e8e8"}, + {file = "rpds_py-0.16.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5c748805634d3aa3e211ab5c1fa789d2812c7a673e19e9bbf010d8f4952ca520"}, + {file = "rpds_py-0.16.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2b69aa0587d2e4c0e0dc7a1d7e355d9433250e71c163d52543aedeb6788288dc"}, + {file = "rpds_py-0.16.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:be46dc8b799490b34ac27bab16530bd977a90c3b5b32c470fa5deef987859a93"}, + {file = "rpds_py-0.16.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:4e976091322592e20a34fd4bc5daf0d0a9fb7a691fd631b988af56893ce4d9bb"}, + {file = "rpds_py-0.16.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dafd8b1d4f2de983c740b746d4dfb207bc0802918b83ad847c94ebfd714fc81f"}, + {file = "rpds_py-0.16.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:0f4967dc38ba502ae6268c5dced87b931cb6362e4d259fa2aeb7fcd280e340de"}, + {file = "rpds_py-0.16.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebcf6cdd51f7b0d0f67c4a001bc52c11c87027b8c5c02747a1c9420a75636cbe"}, + {file = "rpds_py-0.16.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:215949e29dd068e5b221593b2a93d55136d10ebce3ac24b7ec11fbe035092102"}, + {file = "rpds_py-0.16.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ddcc05a8e7127860e3b6a9f09214c6284812cb120707af22abbac67b7487981"}, + {file = "rpds_py-0.16.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fcf49525de3a03516af823aa97214bbbf9fa015b27b4f50470e60da6a0c904"}, + {file = "rpds_py-0.16.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83bd274ec1334c24fdb4b4529ba730e31970e572e2ce58e7e710567c7d7f2945"}, + {file = "rpds_py-0.16.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4c7cf4f3d84e1c88d817566c4af086208cebcd80f1cfad5d2623c097b01a07fd"}, + {file = "rpds_py-0.16.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:e268f0113a08765b28f87a317ae7b99b5adbccd332da0e034bfe9f7bd8e0df0f"}, + {file = "rpds_py-0.16.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:6f26307b0b200aa71418eb13f02d7f9e511bc76d0236aaba1635b8f22bc9081d"}, + {file = "rpds_py-0.16.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:b271bcdbcb4a8aae1ffc972df3c848c71f0b1e7f1c664c23cdd51daae95b4c6d"}, + {file = "rpds_py-0.16.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6942dc9f157fdb83e3903e7879250767089650b455d01ba22e1eecfd0f56ebb6"}, + {file = "rpds_py-0.16.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e75e433e02db93c20e6d19a7a68e0b46406ffc563025f12144b2f9222283af57"}, + {file = "rpds_py-0.16.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a34328fe4cb588ddbcebe173ec8fe10cbfb937c3eee6202d57bd2c4bfe19d80f"}, + {file = "rpds_py-0.16.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c274f1602b4ef6359f478bfaf26d0d4e981e5830d2b96312fc8a008d56ef92d5"}, + {file = "rpds_py-0.16.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97818e1b51cc503680983d4b5a0952c827e21e7193220608bfc3a74928787407"}, + {file = "rpds_py-0.16.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c8ee023ba89b3de03031a5acfe85050dc6861ddc9ef1ec30c9b5cbdf8118475"}, + {file = "rpds_py-0.16.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:452dd2187bd49825f2676caa9cef74b6dd2ee0d47aa927bb1f1102318ac49223"}, + {file = "rpds_py-0.16.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:948ee3a5dc00404c79595c35b3f8226546899b1e8fec6f10cf97014872c672bb"}, + {file = "rpds_py-0.16.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:6fbe5327fc74c339f2adbee634508396ed6fecc53255f37c98c989f796015e33"}, + {file = "rpds_py-0.16.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:b0227f3426bd5497ce718d6b0a63a36fd35ab2adf77491118061ef43d785babd"}, + {file = "rpds_py-0.16.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:de310a7189f02d75b4a363e2b9d027fad7d2e620ddf742407d4aa679165f0382"}, + {file = "rpds_py-0.16.1.tar.gz", hash = "sha256:bc77ba15c1c9a3ec3fdba044a1135b0669ca9a6c4c8ca262a74dc263343eb159"}, ] [[package]] @@ -1143,21 +1143,21 @@ files = [ [[package]] name = "typos" -version = "1.16.25" +version = "1.16.26" description = "Source Code Spelling Correction" optional = false python-versions = ">=3.7" files = [ - {file = "typos-1.16.25-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:6e901cc9fe54bf46b20dd663b262792c4a4879906fc7352047b05edba8b81b27"}, - {file = "typos-1.16.25-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2abf3ded3c94b4c991c437449f00ab190807627f9cd7928cab7f46141e3be3c9"}, - {file = "typos-1.16.25-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eeda6f7df73c10505978f24f547dccd2f4497b11a080996a3b045e3882a77c4b"}, - {file = "typos-1.16.25-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8ef110f6e988ac2af80f90d6a5db41150e69fbeff066db2d17722a297b85e22"}, - {file = "typos-1.16.25-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81f0e77f79b94a22f211eab3facc7a2fb88afa5b63c55b1c167c516fce924022"}, - {file = "typos-1.16.25-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ee9219d68a0014aa858f59cf03ee065881bac596cb042b29ff71ec7524e4ee53"}, - {file = "typos-1.16.25-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:9e9c66ea088c8b8982525035c02b58bb89e79309110fb234d8a79475e6789b97"}, - {file = "typos-1.16.25-py3-none-win32.whl", hash = "sha256:4e188af4b36c242b7c584c747800910b028438354b6af2f7aa9aad3e3da315ce"}, - {file = "typos-1.16.25-py3-none-win_amd64.whl", hash = "sha256:173c81439ed0877d887aae32a8cf69ee9a19783a3f50d16add2a20b738d14d20"}, - {file = "typos-1.16.25.tar.gz", hash = "sha256:46dc1c9ec6364279d7dc89154d311b4bcb51cda396cfc033e2fc59de7fb26e35"}, + {file = "typos-1.16.26-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7c0c7a36f2af868f5906337e39a4580a52c27bea55703a41accd0b78f1d9409f"}, + {file = "typos-1.16.26-py3-none-macosx_11_0_arm64.whl", hash = "sha256:52c6df947589d6986fe2da945b20ccec987a29666f19bfae8adc8c98b5c67ba4"}, + {file = "typos-1.16.26-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8216b04b705ee55a9c325b7aacfb64d26265c8a39ca119da9ce626798f3d2fa1"}, + {file = "typos-1.16.26-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:39465b6cc1aa183920851845263c469d4cd5faa331ea1b7802a921168ad7bf08"}, + {file = "typos-1.16.26-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a37fcf005f35bdf4d35b027f39c021dfd31304d05cd16656c3b43fc8d9d78f90"}, + {file = "typos-1.16.26-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:39c313d93bb8819e4a4ddca6d8bd89c02a62a785a6fc22a48d71238b3b0a7ee9"}, + {file = "typos-1.16.26-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:af1acb2eb99801e6aa47055a49fb4afa8b148529cc0dec2e18764b3e736967b1"}, + {file = "typos-1.16.26-py3-none-win32.whl", hash = "sha256:d5dc4a34021a5bcfa9fff7dd2da317ad29195093d5d98c6ea03f3ef9a69fc302"}, + {file = "typos-1.16.26-py3-none-win_amd64.whl", hash = "sha256:ef9fd2d2acbb0f69708986700c6c2b000f6f81d1ba29c0de97a1ca3652ded4a0"}, + {file = "typos-1.16.26.tar.gz", hash = "sha256:51ac53a284aa69f25707ba268c20568814219243c64da0e9862168fa2e177298"}, ] [[package]] diff --git a/templates/nomad_jobs/gitea.hcl b/templates/nomad_jobs/gitea.hcl new file mode 100644 index 0000000..92f34b3 --- /dev/null +++ b/templates/nomad_jobs/gitea.hcl @@ -0,0 +1,353 @@ +job "gitea" { + region = "global" + datacenters = ["{{ datacenter_name }}"] + type = "service" + + update { + max_parallel = 1 + health_check = "checks" + min_healthy_time = "10s" + healthy_deadline = "5m" + progress_deadline = "10m" + auto_revert = true + canary = 0 + stagger = "30s" + } + + constraint { + distinct_hosts = true + } + + group "gitea" { + + // constraint { + // attribute = "${node.unique.name}" + // operator = "regexp" + // value = "rpi" + // } + + count = 1 + + restart { + attempts = 0 + delay = "30s" + } + + network { + port "webui" { + to = "3000" + } + port "ssh" { + to = "22" + } + } + + task "create_filesystem" { + // Copy the most recent backup into place on the local computer. sonarr will not work with + // its database in an NFS share + + driver = "raw_exec" + config { + # When running a binary that exists on the host, the path must be absolute + command = "${meta.restoreCommand}" + args = [ + "${meta.restoreCommand1}", + "${meta.restoreCommand2}", + "${NOMAD_JOB_NAME}", + "${meta.restoreCommand3}" + ] + } + + lifecycle { + hook = "prestart" + sidecar = false + } + + } // /task create_filesystem + + + task "gitea" { + + env { + GITEA__mailer__ENABLED = true + GITEA__mailer__FROM = "gitea@{{ homelab_domain_name }}" + GITEA__mailer__PASSWD = "{{ gitea_smtp_password }}" + GITEA__mailer__PROTOCOL = "smtp+starttls" + GITEA__mailer__SMTP_ADDR = "{{ email_smtp_host }}" + GITEA__mailer__SMTP_PORT = "{{ email_smtp_port_starttls }}" + GITEA__mailer__SUBJECT_PREFIX = "[Gitea]" + GITEA__mailer__USER = "{{ email_smtp_account }}" + GITEA__repository__DEFAULT_REPO_UNITS = "repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects,repo.packages,repo.actions" + GITEA__server__DOMAIN = "{{ homelab_domain_name }}" + GITEA__server__ROOT_URL = "https://${NOMAD_JOB_NAME}.{{ homelab_domain_name }}" + GITEA__server__SSH_DOMAIN = "${NOMAD_JOB_NAME}.{{ homelab_domain_name }}" + GITEA__server__SSH_PORT = "2222" # Traefik gitea-ssh entrypoint + GITEA__server__START_SSH_SERVER = false + GITEA__service__ENABLE_NOTIFY_MAIL = true + GITEA__time__DEFAULT_UI_LOCATION = "America/New_York" + TZ = "America/New_York" + USER_GID = "${meta.PGID}" + USER_UID = "${meta.PUID}" + } + + driver = "docker" + config { + image = "gitea/gitea:{{ gitea_version }}" + image_pull_timeout = "10m" + hostname = "${NOMAD_TASK_NAME}" + volumes = [ + "${meta.localStorageRoot}/${NOMAD_JOB_NAME}:/data", + "/etc/timezone:/etc/timezone:ro", + "/etc/localtime:/etc/localtime:ro" + ] + ports = ["webui", "ssh"] + } // docker config + + service { + port = "webui" + name = "${NOMAD_TASK_NAME}" + provider = "nomad" + tags = [ + "traefik.enable=true", + "traefik.http.routers.${NOMAD_TASK_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)", + "traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure", + "traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}", + "traefik.http.routers.${NOMAD_TASK_NAME}.tls=true", + "traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare" + ] + + check { + type = "tcp" + port = "webui" + interval = "30s" + timeout = "4s" + } + + check_restart { + limit = 0 + grace = "1m" + } + + } // service + + service { + port = "ssh" + name = "gitea-ssh-svc" + provider = "nomad" + tags = [ + "traefik.enable=true", + "traefik.tcp.routers.gitea-ssh.rule=HostSNI(`*`)", + "traefik.tcp.routers.gitea-ssh.entrypoints=gitea-ssh", + "traefik.tcp.routers.gitea-ssh.service=gitea-ssh-svc" + ] + } // service + + // resources { + // cpu = 100 # MHz + // memory = 300 # MB + // } // resources + + } // task gitea + + task "save_configuration" { + driver = "raw_exec" + config { + # When running a binary that exists on the host, the path must be absolute + command = "${meta.backupCommand}" + args = [ + "${meta.backupAllocArg1}", + "${meta.backupAllocArg2}", + "${meta.backupAllocArg3}", + "${meta.backupAllocArg4}", + "${meta.backupAllocArg5}", + "${NOMAD_JOB_NAME}", + "${meta.backupAllocArg6}" + ] + } + lifecycle { + hook = "poststop" + sidecar = false + } + } // /task save_configuration + + } // group + + + group "action-runners" { + + // constraint { + // attribute = "${node.unique.name}" + // operator = "regexp" + // value = "rpi2" + // } + + constraint { + distinct_hosts = true + } + + count = 3 + + restart { + attempts = 0 + delay = "30s" + } + + network { + port "cache" { + to = "8088" + } + } + + task "gitea-action-runner" { + + env { + CONFIG_FILE = "/local/config.yml" + GITEA_INSTANCE_URL = "https://${NOMAD_JOB_NAME}.{{ homelab_domain_name }}" + GITEA_RUNNER_NAME = "${node.unique.name}-action-runner" + GITEA_RUNNER_REGISTRATION_TOKEN = "{{ gitea_runner_registration_token }}" + PGID = "${meta.PGID}" + PUID = "${meta.PUID}" + TZ = "America/New_York" + } + + driver = "docker" + config { + image = "gitea/act_runner:latest" + image_pull_timeout = "10m" + hostname = "${NOMAD_TASK_NAME}" + volumes = [ + "/var/run/docker.sock:/var/run/docker.sock" + ] + ports = ["cache"] + } // docker config + + template { + destination = "local/config.yml" + env = false + change_mode = "noop" + data = <<-EOH + log: + # The level of logging, can be trace, debug, info, warn, error, fatal + level: info + + runner: + # Where to store the registration result. + file: .runner + # Execute how many tasks concurrently at the same time. + capacity: 1 + # Extra environment variables to run jobs. + envs: + A_TEST_ENV_NAME_1: a_test_env_value_1 + A_TEST_ENV_NAME_2: a_test_env_value_2 + # Extra environment variables to run jobs from a file. + # It will be ignored if it's empty or the file doesn't exist. + env_file: .env + # The timeout for a job to be finished. + # Please note that the Gitea instance also has a timeout (3h by default) for the job. + # So the job could be stopped by the Gitea instance if it's timeout is shorter than this. + timeout: 3h + # Whether skip verifying the TLS certificate of the Gitea instance. + insecure: false + # The timeout for fetching the job from the Gitea instance. + fetch_timeout: 5s + # The interval for fetching the job from the Gitea instance. + fetch_interval: 2s + # The labels of a runner are used to determine which jobs the runner can run, and how to run them. + # Like: ["macos-arm64:host", "ubuntu-latest:docker://node:16-bullseye", "ubuntu-22.04:docker://node:16-bullseye"] + # If it's empty when registering, it will ask for inputting labels. + # If it's empty when execute `daemon`, will use labels in `.runner` file. + labels: [] + + cache: + # Enable cache server to use actions/cache. + enabled: false + # The directory to store the cache data. + # If it's empty, the cache data will be stored in $HOME/.cache/actcache. + dir: "" + # The host of the cache server. + # It's not for the address to listen, but the address to connect from job containers. + # So 0.0.0.0 is a bad choice, leave it empty to detect automatically. + {% raw %}host: "{{ env "NOMAD_IP_cache" }}"{% endraw +%} + # The port of the cache server. + {% raw %}port: {{ env "NOMAD_HOST_PORT_cache" }}{% endraw +%} + # The external cache server URL. Valid only when enable is true. + # If it's specified, act_runner will use this URL as the ACTIONS_CACHE_URL rather than start a server by itself. + # The URL should generally end with "/". + external_server: "" + + container: + # Specifies the network to which the container will connect. + # Could be host, bridge or the name of a custom network. + # If it's empty, act_runner will create a network automatically. + network: "" + # Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker). + privileged: false + # And other options to be used when the container is started (eg, --add-host=my.gitea.url:host-gateway). + options: + # The parent directory of a job's working directory. + # If it's empty, /workspace will be used. + workdir_parent: + # Volumes (including bind mounts) can be mounted to containers. Glob syntax is supported, see https://github.com/gobwas/glob + # You can specify multiple volumes. If the sequence is empty, no volumes can be mounted. + # For example, if you only allow containers to mount the `data` volume and all the json files in `/src`, you should change the config to: + # valid_volumes: + # - data + # - /src/*.json + # If you want to allow any volume, please use the following configuration: + # valid_volumes: + # - '**' + valid_volumes: + - '**' + # overrides the docker client host with the specified one. + # If it's empty, act_runner will find an available docker host automatically. + # If it's "-", act_runner will find an available docker host automatically, but the docker host won't be mounted to the job containers and service containers. + # If it's not empty or "-", the specified docker host will be used. An error will be returned if it doesn't work. + docker_host: "" + # Pull docker image(s) even if already present + force_pull: false + + host: + # The parent directory of a job's working directory. + # If it's empty, $HOME/.cache/act/ will be used. + workdir_parent: + EOH + } + + // service { + // port = "cache" + // name = "${NOMAD_TASK_NAME}" + // provider = "nomad" + // tags = [ + // "traefik.enable=true", + // "traefik.http.routers.${NOMAD_TASK_NAME}.rule=Host(`${NOMAD_JOB_NAME}.{{ homelab_domain_name }}`)", + // "traefik.http.routers.${NOMAD_TASK_NAME}.entryPoints=web,websecure", + // "traefik.http.routers.${NOMAD_TASK_NAME}.service=${NOMAD_TASK_NAME}", + // "traefik.http.routers.${NOMAD_TASK_NAME}.tls=true", + // "traefik.http.routers.${NOMAD_TASK_NAME}.tls.certresolver=cloudflare", + // "traefik.http.routers.${NOMAD_TASK_NAME}.middlewares=authelia@file" + // ] + + // check { + // type = "tcp" + // port = "cache" + // interval = "30s" + // timeout = "4s" + // } + + // check_restart { + // limit = 0 + // grace = "1m" + // } + + // } // service + + // resources { + // cpu = 100 # MHz + // memory = 300 # MB + // } // resources + + } // task gitea-action-runner + + } // group action-runners + +} // job diff --git a/templates/nomad_jobs/reverse-proxy.hcl b/templates/nomad_jobs/reverse-proxy.hcl index 325e830..07957f2 100644 --- a/templates/nomad_jobs/reverse-proxy.hcl +++ b/templates/nomad_jobs/reverse-proxy.hcl @@ -248,6 +248,10 @@ job "reverse-proxy" { static = 4430 to = 4430 } + port "ssh" { # Used for gitea + static = 2222 + to = 2222 + } } task "whoami" { @@ -305,12 +309,13 @@ job "reverse-proxy" { config { image = "traefik:v{{ traefik_version }}" hostname = "traefik" - ports = ["dashboard", "web", "websecure","externalwebsecure"] + ports = ["dashboard", "web", "websecure","externalwebsecure", "ssh"] volumes = [ "${meta.nfsStorageRoot}/pi-cluster/traefik/acme:/acme" ] image_pull_timeout = "10m" args = [ "--global.sendAnonymousUsage=false", "--global.checkNewVersion=false", + "--entryPoints.gitea-ssh.address=:2222", "--entryPoints.web.address=:80", "--entryPoints.websecure.address=:443", "--entryPoints.externalwebsecure.address=:4430", @@ -449,8 +454,8 @@ job "reverse-proxy" { } // service resources { - //cpu = 40 # MHz - memory = 64 # MB + cpu = 140 # MHz + memory = 100 # MB } // resources } // task traefik diff --git a/templates/scripts/service_backups.sh.j2 b/templates/scripts/service_backups.sh.j2 index c897dee..5189dba 100755 --- a/templates/scripts/service_backups.sh.j2 +++ b/templates/scripts/service_backups.sh.j2 @@ -20,6 +20,7 @@ _mainScript_() { readarr sonarr uptimekuma + gitea ) fi @@ -131,7 +132,7 @@ _mainScript_() { BACKUP_RETENTION_HOURLY=2 BACKUP_RETENTION_DAILY=6 BACKUP_RETENTION_WEEKLY=3 - BACKUP_RETENTION_MONTHLY=2 + BACKUP_RETENTION_MONTHLY=4 ;; esac diff --git a/vault.yml b/vault.yml index 01bc2ac..befca99 100644 --- a/vault.yml +++ b/vault.yml @@ -1,208 +1,216 @@ $ANSIBLE_VAULT;1.1;AES256 -35623038633764373461616362396466626463363165643435306131303963653738646362313863 -6533636431623330323134613339303362373632666136610a303862613363323738346438666563 -33353231343231313636313961383165666538653932663463306366373061303436636438393837 -6461343430386562320a623836653637306536353137623661373836653735393632613134636539 -32623663303365663361306634396166323461356636626365353965336630303139396666653439 -34373265376132323338396137376137656530373339316339393935353633323165643262346135 -35363639633733343264346330353636626165313839623239343130366332666262613134383136 -38653366363264383134623534646433343963623366616638306666323562363238346361613031 -33333839366663303861386133323264336161623939336262663166383165323031393663633339 -33633765356331653939663732653436623164386634323064356463313038303833653865303635 -31386538653138623063393831636366313330366230666337333762623536333362343466663964 -31343163303035393339303466336137303338353334336237643733346462333261653730396665 -61313534623533363263626536373137383037333739613830623938663432616464333631383331 -62636136373830343636613931656262383066636130653862316136363365386166663934356665 -63313134633261346561323138373734393364396662656333333263343665623766623633393565 -33353533363764323334663562653563326431663563366438636634333166386330633234303235 -30323966333764376566613164343538656566616132663735326436333735363033393465656233 -64323739393538323837366132303731393463363137333935373866353832383135353063633365 -39626531643038353161346637623061316662383432643133396131343536333436616664343234 -38663864393365343465656265633032373032383134663265643661386532613734366532623065 -34333436383562343565313931336637646666363838303661326466333661303737613563666463 -63333334373665656538663139383639333435643764363730303833393634373930613033636132 -35656166323437393430323430633139353962666562623630356166643234323264333430343837 -30313831333930653164313463393534303733613336346237343933376238653638366265396531 -31356461346266633631363839373834366337313534626530643133373031613837386562376562 -30633061663966613838383232393235323231316335646431663261313230303938663433656266 -35623231346432343835643233313238353832623763343735373661316131313232383732333062 -34326538666462376164366566626230393666643563633532336430326339306330663238653261 -38393931653964656365333236656166353138643934353230303163643331346438363166333263 -39666531343738316665383765323566363237393234653663306231383239346266653935663063 -36646439356662633237346362393335343730626464656532373032376231613431373166363761 -33353239643361323434666432623165316638616530646430623866313063356635363831643235 -31666265653436616464326364303961313666333837393033326561323931616435376165306562 -38373763636430326233636138373361373639633766343761653966336662663833613732306336 -32323733393434356465623436323665633862643236383162353239333534336165326665356564 -32303966353330623431346332633332346463316435363835346366333065346136633533333464 -31316566666535623166313265333561626335663238393439396237636261623730363261353364 -33643430333961393663643135313030623036356538323538373032643430623234326330623334 -32636663336339336262376338346431613535383235313039336564303033646132633463323461 -61613133383032636233306135383536383433363736363964336431313462376266306336646633 -34623730643531623138373736643232333562316239323863646439386132313736613432663437 -32396262656333623561643239373737333438383036323536353036366563373536636230326562 -65363864626361336235653936366666306663663230663637393332633762386338636637353930 -36653364616433653436663565646266663166346630313566366262626534616130343730393062 -66336132633531376438356162313063616532393735313935386633386137643736373038333531 -65323536313962626566356330303063356534373063366565663633623836616363383436326339 -38333064363065623464353238613765346161393362376132613462376661373030636338643365 -33373431396533626632366232383161653037333235633138323439613330633734376366636464 -62383563343538313232653763303536613166366666303763313331366238386161626533333763 -38383132326236393136356230333138646365623062343638643733323866373031316532663336 -64303738623637613535376366363762386466366664353862333066643933666431663265666635 -62636564323230303263343832373938626235363439393434313039366338633464613566653565 -63356362393465316137393138353365393866303363333439623635336364616134623733353161 -34633537653533336164323065366133306232643931316366626664383963313461646133303535 -37383835656535616339613061323466356437626665343363326262316661663033316236666465 -64313331623430333262313532383931333138646265333662376262626139346134346662616663 -61656539366165626463356138373965396634313135346133653532666334646631613062343064 -31393765343539363435666462356634343939313330623130393535383363613139303763623333 -36386330333463346632396139666233323462616537326134373463373636373439383163393530 -39303935396166663165386134336430653337343632633439663665363539363764633733633565 -64663637393664313564633839346334626438643736333161653733383136313366326639313762 -38643265373664386438313033353664323732373466303432373339633238343766663630643535 -39316634336362326263626532663061316636333735656361353662646464636634333662366264 -33393863313237313534316361306263386664326337366231393330366230646138386565633565 -61363536363936303136393137306434336534346431633332613431646537316631623031663739 -35346634396636343761366232333732646433666263313066656237343435653733323566336261 -37636464626461346466623835613439353836623338346165633837653364363834333732303065 -63363630656233346330363763363564306561346566326330636361643135343836616630336635 -65383734626136626337333736346635313636346364393030326362333833643566356135623737 -62343765386564383230343931363134376663393634313130633462346664306263623836316435 -64656465303666323764643261333362356165613261333738623834613733316230313631313762 -62363930366234653963633164366463613132333631653837356235366436653836346132303934 -35343537613734373737653636313261306435383232303935396264353430333739383235346434 -30663839626333616463663633323066323864383833313739363532306330393266633464313430 -30653061316531366636353064316466643734363232353638386365326634333931636537666435 -65383631376339646665623638613132653161663335663838386331343336646338323965333432 -65303531636564336130333530343361386232316464653563303163316561316133623433643264 -37663635386264336462353061376630336634353737323234386334386630633864306466323535 -37313030383463636561623566663934656363393661613730386439373762363165386334326161 -65666234656137383834653738336263323939633363323837643539326335643766663035386365 -64343030303764343631306466323638303163326633346665343165376261376565313032363262 -39663765343031353837666232306338326665343936333034316331366439663966663238336430 -32366330336661323735623236303763633835383230363862623538393633653465623330393234 -31323630353838313838613666373231613936343938643233373636326664313237623266343036 -32366336343430363161343561626165396433643530323465346137633330383137613336386434 -35353461336237376134373762323236633432366534646462626366356663346364646531313838 -33366632336165356231643132366463313037373630326437356634303530393930656331373562 -61376661313433616162373839393964623438626664626535343136323734333434623632393262 -65393536636365643633336130373162626636373638363731313835323136333930666235616230 -31633863643763616266343135663263313665363934396334623661643039633566653765363136 -32306563343236376564353233366666636137626234656366323862356465393930393431353437 -65366233653837343561666435643631623964663334346439376632303961306233323338616433 -63343162663466626436613262393265313834396239303230626635393162653862363836303630 -31653264653735363430393234306639346165623561326266653562333963383164613034666564 -39356666343563343837333633646266353565366335306635613231363238623131636561323135 -36656464343761653837653233313139386138303762613662343334666164636237306337653538 -33623236663631353238343238633232356661323064623139333366313534656531343262393734 -62663066356435633166393439353936376437306133383432353863306163663330643034626265 -33393331313739643934626139343565333834366439346635636566323563616436323235643663 -32353330616639343135306434343733383062633866326434303464623633376264313763633737 -30373666663664333465376337383239333537643536313338373861393233643135363830343961 -38343036363965656163366363353361306438303131656239313436666466343734393435333565 -33363034346665333761396635313737323065636331323138303238663138666162616333613536 -37623234626431326163663962383361343836396431353039653537333538663133346430653733 -31373862663835643236393234653036393331313731326431313633636566396364663163373634 -65373163666531643164333161653366353037343934313666613962326330376336386264626165 -31656131323461626530383130396162656333653536383766666236386334343265346262633263 -38393863333738366566316565653163386435303330323662383434633937636463313261373331 -34363138393337306131363132396165323534613362306261303635366238646166616230323530 -66353237363835653163656333303165336565303839363736633932343566396633306534663939 -65623632636637383631353461323037313531366232333464376466323336313166353263373166 -63313138623836653738663164373139663834636661636365376336386565623362393639343036 -34666530613066336130376338346438366432393437663834386664623530643137626635343065 -66336439363262386532373661623664653737643338666562656639303636353531363862643738 -36333931626439643033353935353434623030613762376135303538306132313331333365356363 -64383339643732323764303839363335313338343965353532396661303164303861353963316532 -38646331633561366538336165346430396161633862396331393934323431636238646665643966 -39323332653035663630373236633434316431383134333661653634376662623830626332326464 -62643438613761303538303035396232316665653865313839346637636462386663343838643831 -32366432323535613930376233643037666631316434643164643666323534636234666636336532 -39366437656632616237393436643336643636633863356666643131666535636136373436383636 -34393061383935373734346164313462353164613132613334303230336436326433656462653831 -38353335653266383837633738393331353963373734643961366231393331366135303138373933 -32303935306261363562633565383566346462663662656163366533333733356230306334363637 -61646661646136303838346136326362363539643236316331306363333766386436393362663832 -31383032616564663062343665636235306233303834366161356333666334323934633562333164 -32623861393463383966313131396332666462386662303439313965343566313561376634623930 -37346239373233376238623531656633303765313633623564623562346535626365393263316233 -62646239653861326262306465643764326363626436343230616138383863636137303439656430 -63623965313361393630373633396566653062613665656331323937666430616666636536623461 -37316138353762376439316236663435303531386265386365633036333030636466306430643138 -65613964633332373237633934633932323938633436663464343038626433663130343937623864 -65613565663031303333306264386363366431313837346530656239633833326563666231636634 -35626133616330346537636664376439316535663733323666633333343062663439636234303863 -34336137333961336461333935653761343662393064343134646631383134383065383836316464 -62356561303135633732306361333735353135633536613133616466636364316335383431303631 -63356635353236656565656230366336353638323430373434613638636637626135636134386463 -62393236363464363365306166306139306662376562636631353736336236306433633237636164 -31356235346239323666616463626263313238326364663935663732613237643830626362393161 -31336266323933646339343234356463653864666334376662383837666262633963333861326533 -63306430363361313362366530393566393063346662383730666631643030646237623339643439 -36663332343065643063346136353230626136663163366333303238376533386435356437616134 -39663036353630383663643136333333316561613061366264393132323939393435313663613338 -39643138343161383435363638643034383734396537363736383564396138363435396531633830 -33623964653034383735316165373766633661623932303037616335356463633866373230323130 -61396432363337626130633936363562333130363165336464346635646630363763623337343162 -33373661303164363534386164326364363133346635636664373833336437373335373231663934 -38383837646633333631376163616131353965346532323666623531396637393436646131336632 -31376435323737323733613939316662326533356364346135336334353831383238616666653933 -62363934663839623134316366646433626466326665613437396430353738343134333136626366 -33376264303937643732306534666666353130326435306433653132656237313336346462353535 -30343062663866636464643234663637373138636561663538363033343438646665616130626461 -33653466613633313265396338376339393039666631353537326532623964316537646463383632 -61343337313965366564383764303761393630666631613866386437323163366433636263356265 -63643063646633663934363739366539303731626537666236343138323065656139626239343863 -34663939306234326638626239303232396562663264363162623430653163363637373765346439 -38326137623936633630623765623763653138646166356566383966353031343166316136633761 -33363437663133623335623765656561663266613461613562386638623232613738613563633333 -30323734306664356266343235316238663131383639383365663538666161646139633663613162 -61366336303465363334656432633131363534666135346537373138393338363965383332636562 -37666538363639613538373036346338376661636137613533343931333462636238393538383464 -62666264376439626530633462343261623766346263396234316638396538353539326265343334 -35373036303135663239386238626634353139373132353338383735626161376334396132333035 -64343465666338343164323737643137623664633463353631306237613136653935663530643637 -36313831633333396163353665316636343461653933653361653665396338376663326439653865 -35343232393330343635653265383963313434653636626662626161366430316438653933623232 -38363966313762393163303763616331366337366138383630393230343536623461306133363035 -37646464346338346166373234306162613231663935663434636533333865626439663733363631 -63623539393139396663383031323933633132656338323661343639366537396138666265356337 -63396334323236386466646238366165343562326265396565643630623963383730656464333663 -37643965336266643766626363616563333234633261363833386430376331613862646564326565 -37343363333732633735376563346265623031666461653533366538313662643238363030356163 -38393762373439633162663164303461623833376434396637323665323638373736303331353531 -38303666326235343232623437636337616631373938636638303835336134366235383637653530 -61383961626166356264393365343930633332386532613136343861333731326135616234326632 -37313336303764383236333138643730316637303832666164383666383830313933323439373937 -35366561646235613231313262373538343436613034663232386231333365663832343062306532 -32373538626633356665363031363732393962333732653834343066383761636633616132636537 -37386561393265636665303561663065333434373466643736306139653364306562373436313065 -63626434613838323933626336346138656330653264613531323338653462663230343065363639 -37633633336334316230613437356338613362383962663434303739376161326134353261616235 -34373565343235613030356164353338656266616162386466646636643731363662626232323335 -31663437333031356361653030636632656135306463626431663265383266333539653831393361 -34343234663133373139383631353638636639383530386264386636316137613836343066383264 -35616632326632333231316437333633346336646330386363353734636331653735326135613239 -32333162313735383366333237356430303166353866306537356166356264346535653635613838 -35376236393734383264653839626434333565663532366565386535633233363466336138373235 -33326137303435376566666239356232376564373962653061633138653363633135323239656461 -39336562326664333131323434336161306662646164643964363963343733363234646132316266 -66343437633238333734333133333364386565396264623463376231623865343631363363663865 -31663963396261396264333331383964616139343435353031363439306262303761386633613962 -34383133623935316439326139363434353464343066643138333035376262376638353163396536 -64303065303637346166303031303162313935303035613538623536663931316430316666303462 -34306265376166633862343239616132623935396135356130316464613637663339616633623839 -35363838316137336537383135396638656133336631623265353635613464393663326330653036 -66373735396663646663336634613561393135616361366239376536643834656134356533383937 -65343665636364393033656566303737333963323766323039636636316138633863326531646161 -32303566376562303163353362373736633665396364613435346231373263313962343936383234 -33373030633938343139613563646635373762623236396663343663336337626562666536643833 -62663938636239376535663433303432303838396630363336663663386330666430653533366637 -34366437383961646333316335663266383133663638663965366565303966663063613031643262 -36366334663333306434373832313562656639323461626262386632623535316263386261373565 -61353135636230386238353461666637353638333365323331313934346365623233346639323662 -30636532326137313531633131626231336630373930306666343066356632636262363838316131 -33633139396638313131333738333762316336306563663236303330356165306637373662636239 -38313530376131366334613039636166346231663664396639666630643066333431613962633364 -303335396436643665366330303565343464 +62396563613031656439666537383564633031376439653235303834623532333435393666383238 +3666663262633462633732643164636635306336353834610a313664366434613561633835366137 +34303561396435626466316432643135353739326261636335346261626536616132333466663365 +6331373264396164330a653837393237633837613466353235396531653932363436636236373939 +66373031343362643237626531303231616261333737316237663965633065306666663235393063 +33663862303366343736373235383162336633653736393162373161636363633238633431396230 +65633638356262363439663530643763373863366465613539356131393337336666633332636635 +65666265393837633938656435653631356331313238373763393530363062396637623430383632 +38363662663564316136653431346464303761386639363436633466626137663966346333333031 +33643433643765366237373237653938656635643737633931656666313335626265613239623531 +31343033336132656638353533663934366464343430353734326439653235313232356631356261 +62356537323766356262323931366266386362386565323765313933346435363534646434343365 +65666462313461326464623531356438323933646537363034303638646563636432393061326439 +62663061666238623335643038326135383631653331653936336535666331626539313665656438 +35653936653237333832343438336130336632636335613264366335316363343539353161643231 +33653536326335633164633563353139386532333130386438313966353238353631363531393537 +38663839373534613232393463663439356264613930336530646464353635333566613033313235 +64333664326638616439643439313734323163366435616265333033343636633934666630653637 +65373237343764353833366663323737653239363936346461303739656234343531373864316238 +35616430346263353061313330333865366638343732643362623264636538323538363930306665 +62653565633366363930333437633137616532393633313631656561653236383736353861333737 +31646431306334313038653833633566353434616363333039663661656631313565313465303865 +38353232643132366636356466373038343262353332393730623831633266643638626433613335 +65366566633332623161633330643762323165616561353635316366323235303135326139643939 +65323234626466633962376465373732356536386631346539373437303166376434393761376338 +61383038316136656536313661353538366235383861653433313530383837306130643762383661 +64336235353066333833333834326463653430346231346462336162333432326164633330653432 +37343936316565333233303833346262366339386561373066353839383866653634376530343035 +35653232306262393032623630316332626539613730386133666463346536303239623532383939 +64393365643435623363323838353764346465306465306130346430303939363566303663336536 +30663863393563336431396164336538653263386436383533376634383965383166323766656135 +62326635653465313536343230633435346639346638393631613337626130363739636234613431 +30396161366433313836386635346430313930326638616134666433666361323439643539643730 +66626365373866616335613134653566313637373535333966666332346537393364343432333035 +36346262303631636631376338313339616139613336346638373865366466643534393334356365 +38303637343539343830633833356430656563303932386163326266386435356330626663633363 +33363661333830323831353836646436306661616230643939323033653232663237613163383138 +63616138616232306563353465326639346363353135393365323833383365363966613231643262 +61343463353232303138343231636237333833333134623634343939366538313136633661333231 +30653431666161646363633834633633656561366232363362633539356161366531353639353734 +36396335333462306331653135633736663030373163663235323161303665613366336630326634 +30373765653135316134656665656331366362383533623530363564353232323630643765626138 +39396664366631353765616430616639646565653436356665633633383132626635653832653662 +30643262353531626565303431316664356665343031373932663561303565376430383039646564 +36623162336239663034633866326537383761623638653434313761336336643866666365363431 +63663535326532383233346466613431313438393632313664336230326531353039333566636662 +64373961386263643632663430353661316137633830323735366163616564333931303266643064 +63333530653331333436353666343533613365373130613634386136316639363331636635656334 +33373938343662306164653330636461653761366638643166616239373931343637306531373933 +63363533623066343261353366373562623061343635353533616236666337303366653662323632 +31326637323534323865663738393765393333313738313436323338373265356336383861356431 +36376236323937653561336337636266636165643762343431383061306661353734336437366337 +31366366346263373533313431353161316439613933366638623235396231353634323465663737 +62353334323361363134343762343235636263663664356336363264323962373832666366366263 +38643231656237386561636533383062356433383335643636623331343731313032383537623037 +62323863303830363961623664303632383466393564343762623638303632613264346130396534 +38383363316337646635616261653232313332343832386633343837393530373964323631666130 +32313562366631356538373737316231303039366562326664363863363637353564393832376139 +61316565653635653238326261343632653966646166326234356161333763363462663562386333 +30326362363836613666303964343039313461306139343262303334623034653039363634616439 +39666536333263616231383532343236646634383835316433386638386537383065666664323336 +39303566633535613834316231663530373238663730663331326262363039356130343832323365 +38303865396330393866623964623335373533656334306134336461313730663533313161333532 +32396236386534353737646539643835393164633433303462353266623066333037343766653865 +34623761396239313063643232313736386431643030663831623262373736363163336135626161 +64373631613137646637653466653335353736303032343432636230303131616364653063663432 +35313636653461623334376332666661353465623865623164316230626238346639643139373033 +31326666636431343462363231373161663239636635333566353861383532326165663936376337 +38356566373662306265376530333063656431373332373530336262636138323763313435323535 +38366165383365653563343461386564373430623737623938666230313662333235383261336263 +38303165333136376165303636383630613231623239363032373539356531633535393734303863 +30376631653136313762623934616532616662646336393464316162353731653461333132386132 +37666665396132336464353637326431313537366132663238396361613235626466636366396435 +34643237316665313639353336633865373335386535393232343038343237363565346639653733 +62643034306336336639333535383437363635316665383338636461393038633263333037353638 +36316533323833353037613332363165633662623031353666346261613065383665633266336434 +63343638383533653864396261306635363637306265623234353939393262636233303861313437 +31323665663432363164613065663636323165666464633833346232633262656534313663333766 +32633561353361323732656139613933343664336439616534346132643832626566376665656463 +31343130663131323062336133633162623863333732353331343165653638636165653861383363 +66373238303036633034666163353663666461666335393930373436323362656430383330383237 +66353130636265333434643434383865643536326237366366396132626533646665366261633361 +61623466323536336237333564663236653063646262633561393331363931303565623365386133 +33636430643436343663396563326532303438613337663737303434346131303661366439643233 +36363530313730646534643930376235356133653362363333343432323937336430666266363565 +62373963646630303134613563623563353961313263366332663662656166613631393865643235 +64623832376634306233333130366334343961323266303835353666326562346539323534316162 +63393766373333613733303265363862346636376561633931313031653539663138313335623033 +33396161336534383835333764323736383461373332353137666462376233306463316663393331 +32336535366434333837316433363133643139643366376339623165383237373563366130656532 +33626635646639373232623631383234613332613361663734383764643964616133333462623034 +31393630316661623066316361373965656637653263623637376262656566353339356630643466 +62376531303939363165623635656634313639343036633730643565663634626166393862366564 +63393038633366633332623064353062323738663065306637303039386363653932336266333965 +65363863643538393461303664373830613263313133633337666139656630616464323666613466 +35383466303063373438656664306666356664366134373432386239623533353433346430323637 +32613666396538653563643662666461636139623934626536373362623936333035343435616435 +38343238333862643837653037653566313738653938396163313662346466363966363736383838 +61396663616361626239646332393631653963663566346138393464323335353930343231343238 +32333838376265363538303939346564383735393664333430616165313364393836313730396466 +61623165356665373634363331323234646634613361326436366334656261356435653864343330 +61313139396235623831383630313261636334333334636163653033316537623964333335326365 +30333732393162613237336166323166666636633138353562383338366362363833366130616465 +31313932623236383935346537626130623837396161323066623763663466303865353537653733 +61666539303632666664333935326666363263626134653766383130646439306231653739316235 +62613732616336633964303264616239386636643266373262386361303030653037366631323563 +31326236663838326566336233323133393239663232663039323636313731333033316230313266 +32333330643638376638353266613430383066326464633337353337663736323730316262323165 +32623663373736326164616264623066313930623332376238393037343931303338303262323965 +34386632353435643064623534616436396366343930336334666335666563373432373538373362 +63363338363130363364346466656632363837323263656562656362383064396139323837343632 +36353937303934363133346338633563363761303866333863646666633736393061653064653162 +64396462346462323439323531313035373364383137383764343164393536393365663466626161 +30653633643232633063313665313636653237366566616530656338623939353765663264353432 +39316633396662366137373762636236316131353531616236653938613530386632356434643933 +66306135356631366438353932653131333138383036653163653230366132396562643733346561 +65613332636636656266333566363131336436363539643034313862353239393736393631353036 +63353134386539656261383432306431386537656530303639383464616162383236386666393235 +66343463336238363361393861613231343138653631623030323031353430653233623435646534 +30646164643939376139333664323136323030376434326266336335393336333766653961313665 +33346639323231663835373332636637613439303164393566323833383565393534636361623736 +37363664393066663535616463333336373035623036316263363031363266373630633632353237 +37333961313430663632646633613737353732663938376262363732376262633337616130326463 +62376266396334353034383434623030633435646135323830336466303030396337396263386131 +35616237353937383731663961656365356334313665383162303930623765396338353533613930 +62306630336662386435636539366462623965343763303732396332633863663934356337386263 +32356234643230626530643337353237323165353235343137666335653364353034646634373961 +33393363616563306434366631663234343532616638396165393939323661653163636265663534 +62623036366333633566376136653938623234626238363138636261383031336631313735636661 +34613432333935653138626334633431336633343737303438626234306330373130386566613066 +36316636373733323161636162386635653534623263616431623064656531626661613039343861 +36623537626333643936313238343733353038623836323234353531636337613163393062376666 +38636333626365363231623663323834396262616536303362356230303664346163663162646663 +62306331616336666462333966333739336337313164316266353264353334353837393163346132 +33333765353139376132663633616332383138396361383831616631376237376332396530643937 +32373936643133343538356561333235363132616462633862623066386266616535626634616635 +36373766646332646361373264626363613935396633323263633237633433333864623238653536 +30663430646236303063323865326363316161393064383666633432643861376164333961613031 +32663738336266356366353162353031386330623163626564666561653630616230376634396634 +65363935666436646361633837326636636134383236643132343739306331356534316565333264 +64646464636263323036356437336461633636353039616664323565333866393833363930613431 +36653764646261363931376332646636343830653036653331386263356132373433313338366239 +34626632616336373334643138343137663030653762646230353132623637613137633336313539 +39343830383462653031396162633730656631383438323133363335663363646465653831333337 +39343732663462343933316264353437613735353764623665666263663563663137373361383464 +33373136623666613065326563613732366430313561643966313832653165613565393761663835 +39386531356233623161626263646261643634643330623730383235303766636131393630353361 +61636661323330663963643534383634623466376363633437613364616634326133613363353038 +62383336303638373039613034386230636639623165626666666235386230343566386636386261 +35376465623737383165633065666439626638666538656230613265636261376163613064383630 +33656137636464613932653531643333333532396439613861373033306637656363663834336534 +34396332313230613962653539333635323663333862326235396263393332363835663833643733 +62613233323361363532383961333565326432333033383361303332323065336165633365663361 +38643837666136393465333936303933386636373035646532633665333137393036643830396132 +36646231393361313531376463623238643431303935393436303438633837643863636263353637 +32663032346662623861616538633535396230653933646336353338383161636538313334393565 +35633636343366323334623631386534666232666436303435323534303335326665636138306263 +65646362313937373837383132306133666435633161643936363532383135663362393866356662 +37343930323362663261386130356236333736613138326531646439373538323831363966333034 +65643836356366616636303331316638646164633639363735386633393865646364666434373838 +63313235313165313230623331373738646437663565613865623666353138343937346531626436 +65656365383432363931303238646431383064356330383239616533396534636135653266613631 +65386261656531663561313661396139373263633834323131666634663338656564393232303163 +35653862643634326362353134663130303839616435376537303763343339366463383532616563 +64636638303635333964373336663037303837653137663036393966326636303435646133393465 +33616565613765353165313230633461303730363231623530623538646662333434303534363266 +66616265356634663064616536643864633638383536363866323137636365303264613839623337 +38346431396437313239366266346331306430386137376339366535626335653066663364373762 +37636462316238666138323235643833643839346632343038393766393862636366353261646534 +38316130663465313433643265623561346532666565323030643537623465366336326435363763 +62663531623365386335666636383531306264303062636435373138393535623033643964333438 +31633034636535666133653830646339646464386232326162386565333563343466326265386539 +32643039373833343933313666653963643034303039656365396639383465616661616436613437 +38343764303335313063636266346463343439346235353763636662303564313265666533666263 +37336632633836316463356333643238393030643433613133643835376138353166336138303165 +37373837623562366436373730356666316233656135353662346262393539353136316265346464 +35393831336261316230343264316134353965303032306536326439383739666634623663623563 +66643363376132643737353862313536353933353132303931333066396330646139363563653534 +64653234613461303637663330333766333637643862336261373765326261646263633136336538 +33303161373336643737323235336632393137653935306337626436336161386263636339663933 +36396162313861663333656463663863323264333163343631333039653332633535623934653963 +65303038326536373339656635303635626136633031643138646137653865643830376362366436 +30366336366363643365373364643937363664613436376665616432363333653932326130343235 +36613131623730316462633834643131356337356164656339346539323933653461316435343039 +61386438636330326461633632666631363538656230343035656633353730626231373834323964 +38363762353736616566323831346164303630383662333162613639663637363533383734356665 +62393164343265386132356530303337626366623830373434376565336133393230346635623330 +36326463303665306136373165643764633339313638366532376336353432636632663434646566 +33333434643665356331633666356633623433363036393765356234613635363363663436623064 +62646534393336343961383137633339376661396264333265623831383033653938373130396164 +33396264363237313633383562333637376165316261313166356631636162346563386163393739 +63333031633166613966343339353234613965343234616537336666306564613031636137636261 +63386336653430373939306466653064633636623136306138663731386232303564313762643035 +30376634393961326636336135353036643935643431343666326331316338376639616138386435 +64666531353139653563303932353832306438663337383761663463613165323132343664393630 +39333862343264356266643439653639623434663235666136616234303735613636333630393032 +38643334383534636232303238356238353135343664303034323565366335653064333038376631 +32646661373331383664623337663831626563613964663039623333366363323032336330313130 +39303162356637626564313335386630656234323734656332663364643732643261386662643436 +31666333326537336362643062646165356164386630653464396335376562636432666532616536 +62353466383635356238396132336133633332366336636663303333656235636265396238323430 +32383431656162663964323862626631636361316364316563353138636138313263373566646261 +38626634663932346139383363346132353462353462323265363838323531303061633562386130 +35643465633266663463613365396139616130646635636439623633346332636333623166313936 +39313131613461623636366462613337316664623161393635383661656361633836646664633364 +30323361623866306532386136303562636130313464346138306637656431376136303062636236 +62623535633663656365633462366630343034366533346230336566313531646363396135373565 +63303433656131636666363032363161376534303966353730386139366437356262366334393431 +62343033353463646537656130353339336138633962323136353737373365366435353933313439 +39653532386263336333393062303436393361363735306561366663643639393838353338653366 +34643836303363363466613932653666303130356330303932353737346236323035633533393766 +34326630303863393138386261643163353963316232393232653438396233386661616263326430 +33393733353535303030653062326238393537316436323262643763376434663561323363613831 +34303932643236363835373463306630663461383636346561353237393233313163616363373138 +336232363362326263343834666337396137