commit 81e15c1535fa7855aa0d59e217e1c6ddfdb3f839 parent 11887c029fd9712ec4bdb904e81f6d203d02e224 Author: Florian Dold <florian@dold.me> Date: Wed, 27 May 2026 00:56:59 +0200 use same vault structure for rusty as for spec Diffstat:
| D | inventories/host_vars/rusty/.gitignore | | | 1 | - |
| D | inventories/host_vars/rusty/test-public.yml | | | 86 | ------------------------------------------------------------------------------- |
| D | inventories/host_vars/rusty/test-secrets.yml.gpg | | | 0 | |
| A | inventories/host_vars/rusty/vars.yml | | | 127 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | inventories/host_vars/rusty/vault.yml | | | 91 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5 files changed, 218 insertions(+), 87 deletions(-)
diff --git a/inventories/host_vars/rusty/.gitignore b/inventories/host_vars/rusty/.gitignore @@ -1 +0,0 @@ -test-secrets.yml diff --git a/inventories/host_vars/rusty/test-public.yml b/inventories/host_vars/rusty/test-public.yml @@ -1,86 +0,0 @@ -# What environment are we deploying? -DEPLOYMENT_KIND: "tops" -# Public variables for a "test" deployment -# Deploy challenger? -deploy_challenger: true -# Disable restore from backup? MUST be set to "false" once in production! -# This forces a backup to be provided *if* there is no database on the -# target system already. If such a database exists, we will NOT restore -# any backup even if this is 'false'. If no database exists on the target -# system and this option is 'false', then a backup must have been provided -# at the originating host (you get get it using the 'restore.sh' script). -DISABLE_RESTORE_BACKUP: true -# Main domain name. -domain_name: "stage.taler-ops.ch" -exchange_domain: "exchange.{{ domain_name }}" -# Our internal hostname -TARGET_HOST_NAME: "rusty.taler-ops.ch" -# Suite for taler packages. -taler_repo_suites: trixie-testing -# Deploy EBICS configuration (true/false). -use_ebics: false -# Our currency. -CURRENCY: CHF -# Smallest unit of the currency for wire transfers. -CURRENCY_ROUND_UNIT: "CHF:0.01" -# Sanction list to use, comment out to disable -SANCTION_LIST: sanctions-swiss.json -# Base URL of the exchange REST API -EXCHANGE_BASE_URL: "https://exchange.{{ domain_name }}/" -# Base URL of the auditor REST API -AUDITOR_BASE_URL: "https://auditor.{{ domain_name }}/" -# Exchange offline master public key. -EXCHANGE_MASTER_PUB: GT1ZRF6DT4RAETDEGW3KTWRH15RAKH9T0TK6ZJEYFGRX18B54AK0 -# Auditor offline public key. -AUDITOR_PUB: P6B7ZS7Y1Y12S0VP0PAJ1GQGSHW8RE4NSBTP8PR254J18SK24MH0 -# URL with merchants accepting this exchange. -EXCHANGE_SHOPPING_URL: "https://shops.taler-ops.ch/" -# Name of Terms of service resource file -EXCHANGE_TERMS_ETAG: "exchange-tos-v0" -# Name of Privacy policy resource file -EXCHANGE_PP_ETAG: "exchange-pp-v0" -# Full BIC of exchange account -EXCHANGE_BANK_ACCOUNT_BIC: "MAEBCHZZ" -# Full Payto URI of exchange account (for credit and debit) -EXCHANGE_BANK_ACCOUNT_IBAN: "CH6808573105529100001" -# Full Payto URI of exchange account (for credit and debit) -EXCHANGE_BANK_ACCOUNT_PAYTO: "payto://iban/{{ EXCHANGE_BANK_ACCOUNT_IBAN }}?receiver-name=Taler+Operations+AG" -# Port to be used by libeufin-nexus for the taler-exchange-wire-gateway -LIBEUFIN_PORT: 8082 -# Name of the exchange account at libeufin-nexus -LIBEUFIN_EXCHANGE_ACCOUNT: "exchange" -# Name of the bank dialect -LIBEUFIN_NEXUS_BANK_DIALECT: "maerki_baumann" -# SPA dialect (tops, gls, magnet, ...) -EXCHANGE_SPA_DIALECT: "tops" -# Business name of the exchange operator -EXCHANGE_OPERATOR_LEGAL_NAME: "Taler Operations AG" -# Where to send people after they passed KYC. -KYC_THANK_YOU_URL: https://taler-ops.ch/thank-you-kyc -# Template to use for identification of individuals with KYCAID -KYCAID_TEMPLATE_INDIVIDUAL: tmpl_xxx -# Template to use for identification of businesses with KYCAID -KYCAID_TEMPLATE_BUSINESS: tmpl_xxx -# Regex specifying allowed phone numbers for the SMS check -EXCHANGE_AML_PROGRAM_TOPS_SMS_HINT: "Swiss number required" -EXCHANGE_AML_PROGRAM_TOPS_SMS_EXAMPLE: "+41948224521" -EXCHANGE_AML_PROGRAM_TOPS_SMS_REGEX: "\\\\+41[0-9]+" -# Regex specifying allowed country names for the postal address check -EXCHANGE_AML_PROGRAM_TOPS_POSTAL_COUNTRY_HINT: "Swiss address required" -EXCHANGE_AML_PROGRAM_TOPS_POSTAL_EXAMPLE: "Max Mustermann\\nBahnhofsplatz 1\\n4201 Biel/Bienne" -EXCHANGE_AML_PROGRAM_TOPS_POSTAL_COUNTRY_REGEX: "CH|Ch|ch" -# Tool to use for sanction list checking -EXCHANGE_SANCTION_HELPER: taler-exchange-helper-sanctions-dummy - -# If set to true, set up an additional user to allow faking wire transfers and -# inspecting challenger auth codes. -# This setting MUST NOT be enabled in production -# deployments under any circumstance. -dangerously_enable_devtesting: true - -devtesting_ssh_keys: - - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINHSjJ/zPwQnqBrKp0qK+OdsZYfQ8DHY2dyJakNozBi7 fdold-work@sapota" - - "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAoXKfSbPriOPoFRR+lMAJszH0/7jaPZOxdg85/URlRbe0ljm8fxbVmup1EjGPuKKJkyYqJIqGQCRHPNYeBt05APXYEO+4d5WAuPY6QOiTFGxB5RueWHAjFM5LVKtBH9Ozln+ngjeXlID48ueuBY2LO24hRuZtRmHYKN1AwQNA2XKtjteKINx99ljm3uwVV9IDYAJkRWKllolLrSFfqK6CHDS/IqlMNp3qNNhNXEW+/Vm5kMUPzKvhPXH/OsFr2KyKaO/+zVXptwje9imtaYaD5iEuRbEfP+6OsCKKpIlp6kyfOUPLuxK+RQfDRY3pyHeCKGriv3DGUpCYqtFVZlmsww== stibane@feh.com" - - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPzMFKrnSNsRwS6eBInPx4WrJipQvsxFKNN48TGwXewb avalos@thinkpad" - - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDftpehk0olHW7h0z8u401gjEZwAw4gKjfy/WXfr1xP4aUlAmHlEybrwCA1TmLzYiuJ1GiEZC1a8s/pk4EFXDd1/YH/mMKnqb7FkFM78lsmpyF+uj9lWzGE/Ov0y8ypdS/V+54CGymPvpnZ2v9x/bvADrQip8qnDPu49ERbrr0/3xm4zT+s2uWh8878crJpzjcOnR5WxwTSyl/H1/uSC/8sGhK49sscwgyvemVL13tpqy5svVB6/7Epno8Gti/ydmy9bd3gl9CtBZvRqZ/0gMefWFaKrkyqtu7mwn7xpsth4izKCaJ5QKOVFo/7ZpqyuderUT7UEC0Opm72q8GR8bvS9aFXjMf3XlE4yrQ6NtHR8h7GpvqWkFsmKuSC5JdpPCMu2a8QtQ9RfCxoCv7JG2En2zJwg8ugek8Q9mKxC0RXl0IeOokm4SnoZWQ6smgJezTx8w3Jv2zOPkWX0jAwtGpPHnPlOleqLcdIqkYpbre/91K5527Sz2HvzZiyjScY13Q++YEiHBZ6xEhzSvbQ6FmV0k6zPhijayx8OyqHDp+PjFVGGOYRoRrN1vQTAJAgXxKrL/7QzdGb+920aeYdrxcVS1fp9xvnwUSM6nf9QobjYDcyFdbKRGo/Yn9KKpWR86ksGAy8m1dImvzv/mG7JP02cS1KqLmBSonzBh9KLUHs/Q== hernani+clementine@vecirex.net" - - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCeYL0JLzvDQXyUqzEn+QlOsxyVPmSedSK1SZxUzM/mBgGBJLRA6kN9Go9X9YeVLsPRJZjCOeLaZqZE3CbSUtw9m7/QYSHZslm+9ALlCJwqGeurFXeqWZ4HTo6/IqD79D+RJezYfnNI8QlKe/ChoIGSf+OHpuc5I5FkNRlKTWfTr+pq8/VFqziRqTTT/LkrtBhflvRYsLnz7X/7nMRrIHi+16SeOFxmT0kwTkl6cYnoGPtaV/FmZaWDYbE+QV4wxnWYbkBNu9CZei2b6t9ZITAJeB9S3VvHF3cvzes1mwz4lwItckmesQ/IY4E7KGu1QN5l3r1Ug0JC/BoZe8qnVQw5 stefan-kuegel" diff --git a/inventories/host_vars/rusty/test-secrets.yml.gpg b/inventories/host_vars/rusty/test-secrets.yml.gpg Binary files differ. diff --git a/inventories/host_vars/rusty/vars.yml b/inventories/host_vars/rusty/vars.yml @@ -0,0 +1,127 @@ +# What environment are we deploying? +DEPLOYMENT_KIND: "tops" +# Public variables for a "test" deployment +# Deploy challenger? +deploy_challenger: true +# Disable restore from backup? MUST be set to "false" once in production! +# This forces a backup to be provided *if* there is no database on the +# target system already. If such a database exists, we will NOT restore +# any backup even if this is 'false'. If no database exists on the target +# system and this option is 'false', then a backup must have been provided +# at the originating host (you get get it using the 'restore.sh' script). +DISABLE_RESTORE_BACKUP: true +# Main domain name. +domain_name: "stage.taler-ops.ch" +exchange_domain: "exchange.{{ domain_name }}" +# Our internal hostname +TARGET_HOST_NAME: "rusty.taler-ops.ch" +# Suite for taler packages. +taler_repo_suites: trixie-testing +# Deploy EBICS configuration (true/false). +use_ebics: false +# Our currency. +CURRENCY: CHF +# Smallest unit of the currency for wire transfers. +CURRENCY_ROUND_UNIT: "CHF:0.01" +# Sanction list to use, comment out to disable +SANCTION_LIST: sanctions-swiss.json +# Base URL of the exchange REST API +EXCHANGE_BASE_URL: "https://exchange.{{ domain_name }}/" +# Base URL of the auditor REST API +AUDITOR_BASE_URL: "https://auditor.{{ domain_name }}/" +# Exchange offline master public key. +EXCHANGE_MASTER_PUB: GT1ZRF6DT4RAETDEGW3KTWRH15RAKH9T0TK6ZJEYFGRX18B54AK0 +# Auditor offline public key. +AUDITOR_PUB: P6B7ZS7Y1Y12S0VP0PAJ1GQGSHW8RE4NSBTP8PR254J18SK24MH0 +# URL with merchants accepting this exchange. +EXCHANGE_SHOPPING_URL: "https://shops.taler-ops.ch/" +# Name of Terms of service resource file +EXCHANGE_TERMS_ETAG: "exchange-tos-v0" +# Name of Privacy policy resource file +EXCHANGE_PP_ETAG: "exchange-pp-v0" +# Full BIC of exchange account +EXCHANGE_BANK_ACCOUNT_BIC: "MAEBCHZZ" +# Full Payto URI of exchange account (for credit and debit) +EXCHANGE_BANK_ACCOUNT_IBAN: "CH6808573105529100001" +# Full Payto URI of exchange account (for credit and debit) +EXCHANGE_BANK_ACCOUNT_PAYTO: "payto://iban/{{ EXCHANGE_BANK_ACCOUNT_IBAN }}?receiver-name=Taler+Operations+AG" +# Port to be used by libeufin-nexus for the taler-exchange-wire-gateway +LIBEUFIN_PORT: 8082 +# Name of the exchange account at libeufin-nexus +LIBEUFIN_EXCHANGE_ACCOUNT: "exchange" +# Name of the bank dialect +LIBEUFIN_NEXUS_BANK_DIALECT: "maerki_baumann" +# SPA dialect (tops, gls, magnet, ...) +EXCHANGE_SPA_DIALECT: "tops" +# Business name of the exchange operator +EXCHANGE_OPERATOR_LEGAL_NAME: "Taler Operations AG" +# Where to send people after they passed KYC. +KYC_THANK_YOU_URL: https://taler-ops.ch/thank-you-kyc +# Template to use for identification of individuals with KYCAID +KYCAID_TEMPLATE_INDIVIDUAL: tmpl_xxx +# Template to use for identification of businesses with KYCAID +KYCAID_TEMPLATE_BUSINESS: tmpl_xxx +# Regex specifying allowed phone numbers for the SMS check +EXCHANGE_AML_PROGRAM_TOPS_SMS_HINT: "Swiss number required" +EXCHANGE_AML_PROGRAM_TOPS_SMS_EXAMPLE: "+41948224521" +EXCHANGE_AML_PROGRAM_TOPS_SMS_REGEX: "\\\\+41[0-9]+" +# Regex specifying allowed country names for the postal address check +EXCHANGE_AML_PROGRAM_TOPS_POSTAL_COUNTRY_HINT: "Swiss address required" +EXCHANGE_AML_PROGRAM_TOPS_POSTAL_EXAMPLE: "Max Mustermann\\nBahnhofsplatz 1\\n4201 Biel/Bienne" +EXCHANGE_AML_PROGRAM_TOPS_POSTAL_COUNTRY_REGEX: "CH|Ch|ch" +# Tool to use for sanction list checking +EXCHANGE_SANCTION_HELPER: taler-exchange-helper-sanctions-dummy + +# If set to true, set up an additional user to allow faking wire transfers and +# inspecting challenger auth codes. +# This setting MUST NOT be enabled in production +# deployments under any circumstance. +dangerously_enable_devtesting: true + +devtesting_ssh_keys: + - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINHSjJ/zPwQnqBrKp0qK+OdsZYfQ8DHY2dyJakNozBi7 fdold-work@sapota" + - "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAoXKfSbPriOPoFRR+lMAJszH0/7jaPZOxdg85/URlRbe0ljm8fxbVmup1EjGPuKKJkyYqJIqGQCRHPNYeBt05APXYEO+4d5WAuPY6QOiTFGxB5RueWHAjFM5LVKtBH9Ozln+ngjeXlID48ueuBY2LO24hRuZtRmHYKN1AwQNA2XKtjteKINx99ljm3uwVV9IDYAJkRWKllolLrSFfqK6CHDS/IqlMNp3qNNhNXEW+/Vm5kMUPzKvhPXH/OsFr2KyKaO/+zVXptwje9imtaYaD5iEuRbEfP+6OsCKKpIlp6kyfOUPLuxK+RQfDRY3pyHeCKGriv3DGUpCYqtFVZlmsww== stibane@feh.com" + - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPzMFKrnSNsRwS6eBInPx4WrJipQvsxFKNN48TGwXewb avalos@thinkpad" + - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDftpehk0olHW7h0z8u401gjEZwAw4gKjfy/WXfr1xP4aUlAmHlEybrwCA1TmLzYiuJ1GiEZC1a8s/pk4EFXDd1/YH/mMKnqb7FkFM78lsmpyF+uj9lWzGE/Ov0y8ypdS/V+54CGymPvpnZ2v9x/bvADrQip8qnDPu49ERbrr0/3xm4zT+s2uWh8878crJpzjcOnR5WxwTSyl/H1/uSC/8sGhK49sscwgyvemVL13tpqy5svVB6/7Epno8Gti/ydmy9bd3gl9CtBZvRqZ/0gMefWFaKrkyqtu7mwn7xpsth4izKCaJ5QKOVFo/7ZpqyuderUT7UEC0Opm72q8GR8bvS9aFXjMf3XlE4yrQ6NtHR8h7GpvqWkFsmKuSC5JdpPCMu2a8QtQ9RfCxoCv7JG2En2zJwg8ugek8Q9mKxC0RXl0IeOokm4SnoZWQ6smgJezTx8w3Jv2zOPkWX0jAwtGpPHnPlOleqLcdIqkYpbre/91K5527Sz2HvzZiyjScY13Q++YEiHBZ6xEhzSvbQ6FmV0k6zPhijayx8OyqHDp+PjFVGGOYRoRrN1vQTAJAgXxKrL/7QzdGb+920aeYdrxcVS1fp9xvnwUSM6nf9QobjYDcyFdbKRGo/Yn9KKpWR86ksGAy8m1dImvzv/mG7JP02cS1KqLmBSonzBh9KLUHs/Q== hernani+clementine@vecirex.net" + - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCeYL0JLzvDQXyUqzEn+QlOsxyVPmSedSK1SZxUzM/mBgGBJLRA6kN9Go9X9YeVLsPRJZjCOeLaZqZE3CbSUtw9m7/QYSHZslm+9ALlCJwqGeurFXeqWZ4HTo6/IqD79D+RJezYfnNI8QlKe/ChoIGSf+OHpuc5I5FkNRlKTWfTr+pq8/VFqziRqTTT/LkrtBhflvRYsLnz7X/7nMRrIHi+16SeOFxmT0kwTkl6cYnoGPtaV/FmZaWDYbE+QV4wxnWYbkBNu9CZei2b6t9ZITAJeB9S3VvHF3cvzes1mwz4lwItckmesQ/IY4E7KGu1QN5l3r1Ug0JC/BoZe8qnVQw5 stefan-kuegel" + +# Secrets are taken from the vault file and substituted via +# the vault_* variables. +# +# YOU MAY ONLY edit the vault.yml file via +# $ ansible-vault edit inventories/host_vars/rusty/vault.yml +# to decrease the likelihood of unencrypted secrets ending up in git. +HAVE_SECRETS: true + +# Symmetric encryption secret for KYC attribute encryption. +EXCHANGE_ATTRIBUTE_ENCRYPTION_KEY: "{{ vault_exchange_attribute_encryption_key }}" +# EBICS access details +LIBEUFIN_NEXUS_EBICS_HOST_BASE_URL: https://ebics.postfinance.ch/ebics/ebics.aspx +LIBEUFIN_NEXUS_EBICS_HOST_ID: PFEBICS +LIBEUFIN_NEXUS_EBICS_USER_ID: "{{ vault_libeufin_nexus_ebics_user_id }}" +LIBEUFIN_NEXUS_EBICS_PARTNER_ID: "{{ vault_libeufin_nexus_ebics_partner_id }}" +LIBEUFIN_NEXUS_EBICS_SYSTEM_ID: "{{ vault_libeufin_nexus_ebics_system_id }}" + +# Authorization token for the telesign SMS service +# "Basic" is pre-pended by the shell script +SMS_CHALLENGER_TELESIGN_AUTH_TOKEN: "{{ vault_sms_challenger_telesign_auth_token }}" + +sms_challenger_clicksend_username: "{{ vault_sms_challenger_clicksend_username }}" +vault_sms_challenger_clicksend_api_key: "{{ vault_sms_challenger_clicksend_api_key }}" + +# Authorization data for the pingen postal service +POSTAL_CHALLENGER_PINGEN_CLIENT_ID: "{{ vault_postal_challenger_pingen_client_id }}" +POSTAL_CHALLENGER_PINGEN_CLIENT_SECRET: "{{ vault_postal_challenger_pingen_client_secret }}" +POSTAL_CHALLENGER_PINGEN_ORG_ID: "{{ vault_postal_challenger_pingen_org_id }}" + +# KYCaid access token +EXCHANGE_KYCAID_ACCESS_TOKEN: "{{ vault_exchange_kycaid_access_token }}" + +# Bearer access token for the auditor SPA (set via browser extension to set Authorization HTTP header on auditor.$DOMAIN!) +AUDITOR_ACCESS_TOKEN: "{{ vault_auditor_access_token }}" + +# Bearer access token for monitoring.$DOMAIN (must be given to grafana) +PROMETHEUS_ACCESS_TOKEN: "{{ vault_prometheus_access_token }}" + +# Bearer access token for loki.taler-systems.com (see that nginx config) +LOKI_ACCESS_TOKEN: "{{ vault_loki_access_token }}" diff --git a/inventories/host_vars/rusty/vault.yml b/inventories/host_vars/rusty/vault.yml @@ -0,0 +1,91 @@ +$ANSIBLE_VAULT;1.1;AES256 +63366237626463656364633362336261316162313233356362656461653738366438633337663238 +3861366130643532653438363761323337353166643439360a613533623839613263623362653366 +65376563393031373763613038383438343632326630623835643064373965303761343335393164 +6533333864383463630a313834386163643139346637653631336365393739366262313262353365 +36303165393265626139303235663537643036323339366431383135313039396165623364663566 +33346239663431306461396364613032613135656133656462366166633138393765383865333939 +37343961633231343136633134633434646565346163353134356264336563346337323162653662 +30626463346332643232626366373932623365653330363464636438623866313736396431326533 +65336430366566623962373835666333336338633462353535646336346233613662316239633032 +32366535626338316338663062323261653331353731376436343833356162343339356163393666 +34323039336361623637616361346661393130363437383137613335653161396563323565346164 +39306262393639353863386265373738626235633937636662393330343639666536353363306166 +63313134336531663561396532323665393362623861643734666564376162323533646266343366 +31323937383563663833386632396531326431646235383238396666346530646233306464656632 +66323132336239376439616363363436353364653136663966306461663231636263623261646230 +38346339643931313261666439643562373639346630393663316364646264313461323032366230 +30326564376534623637633062336436323934353636346636643864616365376535396664396264 +32663664396565643430303131396133363830643535653264323163303234643237613666323666 +62653239396531643965663765366334613562633235326637336364326639383531626264356332 +62623238656538303137303065656339653630396337376263376138643534316233656662353836 +66336434336233313430343437363639653464376363636465386536613063643237343631383662 +30383134343735333366656239386133393435633137636433363462353338663633343238336230 +37303733363336383661363130316232363762623466333033643738366465656334353663336634 +63623865316365376437613066366163616138333036376462356365383837343563323531373730 +30366463646635336665396261396635343536323062313966633562353039623031343437333638 +63336138363035356261643565343731373636366266623765633564343365343062633938383836 +62386630623731333332343631653532616263613130346537306166323534343333323539313130 +62633665356338356637323264613336626236353338393264306431633433636166623436663663 +66386165326462666535313665656264316265336164393230613664643466336433636163393539 +62336666353264333833323134343964393132373631343361613139613935333439366133376533 +66306664656361346464326239353538613433626339663739383662623334636335383661366633 +34376161366433633437323733666239623537316339306538613736633366383333323230636536 +64653133373961303664386464393538346537353338343033663565373262393663623764613966 +63373331313239653332313534323761633534653339666466373462646238643032376330616238 +62306336656361343062613832336666346331373663646335356565323865656164633835313632 +39386263666166616633383130613365633933386332653764646233373865346438623966393062 +39633831393961646164306331383733366530353464616564383461366235666234343434626362 +62336135373232623233663164626231333664313939623836613864336336326136333766623334 +36653337366334303562666132343762633934643431343465393066636439303130616234653264 +63613633306539616135383439353634633133363538396261353636626438646638626337666263 +62346532613066343035303465333835396164313566383936636434386463653962333065353162 +30343364336630633636656539663530666433396535663664363436383064646664343366383562 +34373135376331326439623430663437353933653665353937643364616231613337386339616566 +30343465343465333538663562623363383137616432393032356532303961646136636133313939 +39373963336630613962363561356661623261346661393365616464383061353332623962633237 +66363030383538386533373034333339613834346364383632626465383439326539613730333330 +62383937393635363633393834376633356334336637383065613465326433363337643630663362 +63636535613061366565393732353134663562653832336165336133653232313665656261393461 +63663866333132333064373165313430383435333665663864373139626166643236386539656138 +62343761333236393864393039623132363238326435363666356239616638313866386261613434 +31303031373231643738386236633730396164313265643033353234306266646266366233356136 +61313338396335663863343437353537363564656334643063383239663732353362393035653563 +62623430376234323361346463353439313061633463373934323432353665613366653166336566 +38376162356266366335323366306532373661363931623031326164363735376261383430373065 +65353265383562353035333535303031306339383233323562343136396562356235316562346566 +38376430326266613563346437303461386133636339613866353039666334343234393362633837 +62366661393734373863646539636663623239333031666430656239383961636462663434313234 +66623562316364373437366333323031663039383164646365636238616137323466656231393865 +65326337353830376536623833623531336237313337663631613634363566363265356332636265 +62633561303335653733326664306635366535616534663136343961633139666465636238306232 +62316566613131333062346131366264366336346533653036616264633961623935306166323134 +30303538653438323438636532623635376235356466306462643938653962613437306164323633 +31666463383162333663343234303833363035333265366537343830383965663034626263336165 +38306561663735313338363131643032646537316264623366393434636635623036363662626230 +33386539613463613732326662393431326531363538346438313161306263346530303165356663 +33343630636161613665386634666266323465663066633131323132633336343462306434646634 +38626335353739306334363639373332363736303932666466663333613230323231656163333666 +39336139616364343731303033616639333563313666343962613965633635346362653166636262 +64303965613435373064316263643339663334623433666465646436616133393566646435396131 +34616163313636346264326535363130333632386533383733343561616530346439656633353837 +61356234326435623464383663373462633735646264363938396632366261663461613561626666 +34346233393466323336333061366165643335313434633933393364643838346436383431346438 +36626530306135653163653333313731383163303939633135663139313336353631316337363137 +66396664653663666336353037636533343436376135623365333539343266333334323437346165 +36396162393265663235666161333063613634383364656462623538303830333266343830363638 +35656231353636306437353330666339356634633233386539653764316338633939343764336431 +37333462373033643062323738313734373064646661656235393433646330396262646532363864 +35323966666661303737633230653939666230616463326532356265356133383530666462366134 +64346266393461653430373232376163383535336238303435383838346666346162386530356562 +32346662393263633136646563643233336536306361313733346134396539396232386231623231 +36636131323934306139373432363435643633306336316332323133396332306163643233613564 +37306535636163343335383366613930366530666539353865616131656665623866303662373735 +66653931336163343363633733363536303365303134303639303961333730663332643266326437 +64373533633334393061393962653463333139303739633238313262643636653433386431343936 +34643064626564363037346333633332366432626665303264656537336430303130323166353535 +31353930353435633262346338323464393839633935336135346133303063363839626233363461 +66373436336361623466366437333339333965306235386136643330393033623865653662316433 +38313130656166656336303838613830306563373863333862623439333064366134343762666264 +63653132303161323631356533316366383439626364626634613765366336326132396662656363 +3461326636386138303561303339336663643937316566643432