From 6cd8d3b14b49f747f5e5befb9fba9bb4f742dace Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Tue, 29 Jul 2025 12:58:01 +0300 Subject: [PATCH] Netdata: add monitoring for postgresql databases --- files/authelia/docker-compose.yml.j2 | 4 +- files/caddyproxy/docker-compose.yml.j2 | 4 +- files/gitea/docker-compose.yml.j2 | 4 +- files/gramps/docker-compose.yml.j2 | 9 +- files/homepage/docker-compose.yml.j2 | 4 +- files/miniflux/docker-compose.yml.j2 | 7 +- files/netdata/docker-compose.yml.j2 | 9 +- files/netdata/go.d/fail2ban.conf | 2 +- files/netdata/go.d/postgres.conf | 9 + files/netdata/go.d/prometheus.conf | 3 +- files/outline/docker-compose.yml.j2 | 9 +- files/rssbridge/docker-compose.yml.j2 | 4 +- files/wakapi/docker-compose.yml.j2 | 4 +- playbook-docker.yml | 7 +- playbook-netdata.yml | 35 ++- vars/secrets.yml | 291 +++++++++++++------------ 16 files changed, 226 insertions(+), 179 deletions(-) create mode 100644 files/netdata/go.d/postgres.conf diff --git a/files/authelia/docker-compose.yml.j2 b/files/authelia/docker-compose.yml.j2 index 8fe13e2..757426d 100644 --- a/files/authelia/docker-compose.yml.j2 +++ b/files/authelia/docker-compose.yml.j2 @@ -6,10 +6,10 @@ services: user: '{{ user_create_result.uid }}:{{ user_create_result.group }}' restart: 'unless-stopped' networks: - - "{{ web_proxy_network }}" + - "web_proxy_network" volumes: - "{{ config_dir }}:/config" networks: - {{ web_proxy_network }}: + web_proxy_network: external: true diff --git a/files/caddyproxy/docker-compose.yml.j2 b/files/caddyproxy/docker-compose.yml.j2 index 07f3c8d..9ce4533 100644 --- a/files/caddyproxy/docker-compose.yml.j2 +++ b/files/caddyproxy/docker-compose.yml.j2 @@ -15,8 +15,8 @@ services: - {{ data_dir }}:/data - {{ config_dir }}:/config networks: - - "{{ web_proxy_network }}" + - "web_proxy_network" networks: - {{ web_proxy_network }}: + web_proxy_network: external: true diff --git a/files/gitea/docker-compose.yml.j2 b/files/gitea/docker-compose.yml.j2 index ba9c0fb..e72694b 100644 --- a/files/gitea/docker-compose.yml.j2 +++ b/files/gitea/docker-compose.yml.j2 @@ -13,7 +13,7 @@ services: - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro networks: - - "{{ web_proxy_network }}" + - "web_proxy_network" environment: - "USER_UID=${USER_UID}" - "USER_GID=${USER_GID}" @@ -29,5 +29,5 @@ services: - "GITEA__mailer__FROM=gitea@vakhrushev.me" networks: - {{ web_proxy_network }}: + web_proxy_network: external: true diff --git a/files/gramps/docker-compose.yml.j2 b/files/gramps/docker-compose.yml.j2 index 342dd3e..61dda44 100644 --- a/files/gramps/docker-compose.yml.j2 +++ b/files/gramps/docker-compose.yml.j2 @@ -3,14 +3,14 @@ services: gramps_app: &gramps_app - image: ghcr.io/gramps-project/grampsweb:25.7.2 + image: ghcr.io/gramps-project/grampsweb:25.7.3 container_name: gramps_app depends_on: - gramps_redis restart: unless-stopped networks: - "gramps_network" - - "{{ web_proxy_network }}" + - "web_proxy_network" volumes: - "{{ (data_dir, 'gramps_db') | path_join }}:/root/.gramps/grampsdb" # persist Gramps database - "{{ (data_dir, 'gramps_users') | path_join }}:/app/users" # persist user database @@ -61,9 +61,12 @@ services: restart: unless-stopped networks: - "gramps_network" + - "monitoring_network" networks: gramps_network: driver: bridge - {{ web_proxy_network }}: + web_proxy_network: + external: true + monitoring_network: external: true diff --git a/files/homepage/docker-compose.yml.j2 b/files/homepage/docker-compose.yml.j2 index 7184015..46fa6e8 100644 --- a/files/homepage/docker-compose.yml.j2 +++ b/files/homepage/docker-compose.yml.j2 @@ -6,9 +6,9 @@ services: ports: - "127.0.0.1:{{ homepage_port }}:80" networks: - - "{{ web_proxy_network }}" + - "web_proxy_network" networks: - {{ web_proxy_network }}: + web_proxy_network: external: true diff --git a/files/miniflux/docker-compose.yml.j2 b/files/miniflux/docker-compose.yml.j2 index 159e089..caa7fc5 100644 --- a/files/miniflux/docker-compose.yml.j2 +++ b/files/miniflux/docker-compose.yml.j2 @@ -10,7 +10,7 @@ services: condition: service_healthy networks: - "miniflux_network" - - "{{ web_proxy_network }}" + - "web_proxy_network" environment: - DATABASE_URL=postgres://{{ miniflux_postgres_user }}:{{ miniflux_postgres_password }}@miniflux_postgres/{{ miniflux_postgres_database }}?sslmode=disable - RUN_MIGRATIONS=1 @@ -38,6 +38,7 @@ services: - POSTGRES_DB={{ miniflux_postgres_database }} networks: - "miniflux_network" + - "monitoring_network" volumes: - {{ postgres_data_dir }}:/var/lib/postgresql/data healthcheck: @@ -48,5 +49,7 @@ services: networks: miniflux_network: driver: bridge - {{ web_proxy_network }}: + web_proxy_network: + external: true + monitoring_network: external: true diff --git a/files/netdata/docker-compose.yml.j2 b/files/netdata/docker-compose.yml.j2 index 8b3a03f..3a6ba81 100644 --- a/files/netdata/docker-compose.yml.j2 +++ b/files/netdata/docker-compose.yml.j2 @@ -2,7 +2,7 @@ services: netdata: - image: netdata/netdata:v2.6.0 + image: netdata/netdata:v2.6.1 container_name: netdata restart: unless-stopped cap_add: @@ -11,7 +11,8 @@ services: security_opt: - apparmor:unconfined networks: - - "{{ web_proxy_network }}" + - "web_proxy_network" + - "monitoring_network" volumes: - "{{ config_dir }}:/etc/netdata" - "{{ (data_dir, 'lib') | path_join }}:/var/lib/netdata" @@ -33,5 +34,7 @@ services: NETDATA_EXTRA_DEB_PACKAGES: "fail2ban" networks: - {{ web_proxy_network }}: + web_proxy_network: + external: true + monitoring_network: external: true diff --git a/files/netdata/go.d/fail2ban.conf b/files/netdata/go.d/fail2ban.conf index ddb5179..c78d740 100644 --- a/files/netdata/go.d/fail2ban.conf +++ b/files/netdata/go.d/fail2ban.conf @@ -1,3 +1,3 @@ jobs: - name: fail2ban - update_every: 5 # Collect Fail2Ban jails statistics every 5 seconds + update_every: 15 # Collect Fail2Ban jails statistics every 15 seconds diff --git a/files/netdata/go.d/postgres.conf b/files/netdata/go.d/postgres.conf new file mode 100644 index 0000000..86c50dd --- /dev/null +++ b/files/netdata/go.d/postgres.conf @@ -0,0 +1,9 @@ +update_every: 15 + +jobs: + + - name: outline_db + dsn: 'postgresql://netdata:{{ netdata_postgres_password }}@outline_postgres:5432/outline' + + - name: miniflux_db + dsn: 'postgresql://netdata:{{ netdata_postgres_password }}@miniflux_postgres:5432/miniflux' diff --git a/files/netdata/go.d/prometheus.conf b/files/netdata/go.d/prometheus.conf index 4b27ac8..b44022d 100644 --- a/files/netdata/go.d/prometheus.conf +++ b/files/netdata/go.d/prometheus.conf @@ -1,5 +1,4 @@ -update_every: 5 -autodetection_retry: 0 +update_every: 15 jobs: diff --git a/files/outline/docker-compose.yml.j2 b/files/outline/docker-compose.yml.j2 index 06117f8..9d5f286 100644 --- a/files/outline/docker-compose.yml.j2 +++ b/files/outline/docker-compose.yml.j2 @@ -13,7 +13,7 @@ services: - "127.0.0.1:{{ outline_port }}:3000" networks: - "outline_network" - - "{{ web_proxy_network }}" + - "web_proxy_network" environment: NODE_ENV: 'production' URL: 'https://outline.vakhrushev.me' @@ -59,7 +59,7 @@ services: restart: unless-stopped networks: - "outline_network" - + - "monitoring_network" outline_postgres: image: postgres:16.3-bookworm @@ -69,6 +69,7 @@ services: - {{ postgres_data_dir }}:/var/lib/postgresql/data networks: - "outline_network" + - "monitoring_network" environment: POSTGRES_USER: '{{ outline_postgres_user }}' POSTGRES_PASSWORD: '{{ outline_postgres_password }}' @@ -77,5 +78,7 @@ services: networks: outline_network: driver: bridge - {{ web_proxy_network }}: + web_proxy_network: + external: true + monitoring_network: external: true diff --git a/files/rssbridge/docker-compose.yml.j2 b/files/rssbridge/docker-compose.yml.j2 index 83ef1bf..59bc771 100644 --- a/files/rssbridge/docker-compose.yml.j2 +++ b/files/rssbridge/docker-compose.yml.j2 @@ -5,8 +5,8 @@ services: container_name: rssbridge_app restart: unless-stopped networks: - - "{{ web_proxy_network }}" + - "web_proxy_network" networks: - {{ web_proxy_network }}: + web_proxy_network: external: true diff --git a/files/wakapi/docker-compose.yml.j2 b/files/wakapi/docker-compose.yml.j2 index 2a9f041..4391ae0 100644 --- a/files/wakapi/docker-compose.yml.j2 +++ b/files/wakapi/docker-compose.yml.j2 @@ -8,7 +8,7 @@ services: restart: unless-stopped user: '{{ user_create_result.uid }}:{{ user_create_result.group }}' networks: - - "{{ web_proxy_network }}" + - "web_proxy_network" volumes: - "{{ data_dir }}:/data" environment: @@ -28,5 +28,5 @@ services: networks: - {{ web_proxy_network }}: + web_proxy_network: external: true diff --git a/playbook-docker.yml b/playbook-docker.yml index 61ad82e..b9a2a18 100644 --- a/playbook-docker.yml +++ b/playbook-docker.yml @@ -29,5 +29,10 @@ - name: Create a network for web proxy community.docker.docker_network: - name: "{{ web_proxy_network }}" + name: "web_proxy_network" + driver: "bridge" + + - name: Create a network for monitoring + community.docker.docker_network: + name: "monitoring_network" driver: "bridge" diff --git a/playbook-netdata.yml b/playbook-netdata.yml index c84fb1b..1d20aef 100644 --- a/playbook-netdata.yml +++ b/playbook-netdata.yml @@ -42,21 +42,34 @@ group: "{{ app_user }}" mode: "0640" - - name: "Copy prometheus plugin config file" - ansible.builtin.copy: - src: "files/{{ app_name }}/go.d/prometheus.conf" - dest: "{{ config_go_d_dir }}/prometheus.conf" - owner: "{{ app_user }}" - group: "{{ app_user }}" - mode: "0640" + - name: "Find all go.d plugin config files" + ansible.builtin.find: + paths: "files/{{ app_name }}/go.d" + file_type: file + delegate_to: localhost + register: go_d_source_files - - name: "Copy fail2ban plugin config file" - ansible.builtin.copy: - src: "files/{{ app_name }}/go.d/fail2ban.conf" - dest: "{{ config_go_d_dir }}/fail2ban.conf" + - name: "Template all go.d plugin config files" + ansible.builtin.template: + src: "{{ item.path }}" + dest: "{{ config_go_d_dir }}/{{ item.path | basename }}" owner: "{{ app_user }}" group: "{{ app_user }}" mode: "0640" + loop: "{{ go_d_source_files.files }}" + + - name: "Find existing go.d config files on server" + ansible.builtin.find: + paths: "{{ config_go_d_dir }}" + file_type: file + register: go_d_existing_files + + - name: "Remove go.d config files that don't exist in source" + ansible.builtin.file: + path: "{{ item.path }}" + state: absent + loop: "{{ go_d_existing_files.files }}" + when: (item.path | basename) not in (go_d_source_files.files | map(attribute='path') | map('basename') | list) - name: "Grab docker group id." ansible.builtin.shell: diff --git a/vars/secrets.yml b/vars/secrets.yml index 1116bf4..ec54a68 100644 --- a/vars/secrets.yml +++ b/vars/secrets.yml @@ -1,142 +1,151 @@ $ANSIBLE_VAULT;1.1;AES256 -62653431636461623338643536653736633166303934626565363963373637396534303130373035 -6565376162653735313737333439633862643366336264650a633265316463323062653032363861 -32626536343138663837633334316537373662653262366163633334623764633938323363363962 -6230333564643665320a613862653632363363616266336338346539323964383736366235306437 -33306363353163383663643062656330313134353836666232616532316264303564336235356661 -30653262363866653139646436333036393837383262643537313933613939326433313565393465 -31373036353133663337613935343038616164316132303833363338623863633234656537653039 -62626436346238636234393939366139363034306432326538656264343733356537393332633836 -38636639626665666238656338363633383566616638353235383465623232646537616230626630 -63303130316438353934656636393366306566346362356564393661643064323630636463383061 -37636461386432323136393739633862313337333261306664323361393835323034643134383461 -31313762616538336666656137373631336132383364646163633732323431613239333563653332 -65616664333839363834333362626238633833666430653738613636333432333430333861356339 -61323865663661383534343964346238383134613532616637346235616139383434623564333361 -31636165653261363830623162623738333937316664633434346431626630393837366666643434 -61643734653834326434353431393732376266626266313264376235323838313539306463653864 -36393461366230643234376161623330326365616539323965633431633238386262373562383161 -39323634633166643038356434616461613864303334393932663730303839373530643933323839 -66353337326336656635636362356531613634623633303461336565363564393964663430393666 -64326439346233346132653230343234653430653239636362616561636166343030303863373337 -36363633646432613138313062346164663730313061363432396138323561366430316439343036 -32353931393064666231323863656165363066313236613332356161363139616636333963386130 -37363030383765613132353161613766633635363033656561343038633839313933646264383730 -64336339646264383332373639326164373163383966626363653762643037353636376336626136 -33346533303036326531316332306461646361376435316438376161663162336335353938366565 -30633133653431393066393961313138383337313731653031323432633766356338316366373432 -32373937663961623739633439636661336461346132376533373961666432353937373066643165 -61663063363661633938373365393665356665636562646265313834373962336566393835633339 -34396666396162613162326331313037303933366564623837386338363063636564656339336639 -66346465366233663534373465313930323134313835316464363263383866313563396263616535 -63383265623865636162346635613863356266336664343434393437656134353639353535383332 -62623934643930313939646466663336633034343534396137333264623263663866663339663266 -30343234356536663262616363376663646264353331646164376331376639363135373137396437 -37363166386233356434656237373535326162303437346233623263663534383032363638376134 -61653939306433393437656465343066613530396265396262373433383637656266303064623234 -64333062353435373863636439663561393763333538303836303631666262326430623835656138 -37653562353562373935333235316430613737653862303933333062643663333364333966643461 -33323335346566363337643161303835356336306232653763346639323265373432376239363566 -64373562653238333865326335613133636335373739396335633631313431363061616139303463 -37333364393438666532396131343637373833353766396234383739306565646439366438653032 -33656330343061636338643465653664326338663233316631303465666632653436633135643664 -64616132366632666431653262393035393163343664303961396431666236303864303865343634 -35616634613165373637653235323164323666343436646339646637646234306163333462393063 -32346534636165656436353036316232303266616135303663343631303565623562616237306365 -65303938646239393564333461343238636335336533633265383066653734613332656563666434 -31316665613630336263613934316361383332363164323266373565323239343033666663396534 -39323739313636616232663535386439363065333766623837336230303334656466656262613363 -37386664336436376530373436353235616437333834646563353830626162336261333135383866 -64383930316531373366646335306131633166353161336463376530353066356530393665393063 -31613636386532623035373866373065633233633135343439616662616232366337313764646436 -64626262643532613136373238316561616361393433323066326333663663353236393662396539 -31653036303031303462643231333965653536666136313638613832393361666131363435633932 -31663864326563663230626237643763333737613239373134626433636564386231383961316162 -39383165336433626466393935383363396333636131643733663866356434366664613766396263 -34313934626133653361633665323131613736306331373732323434323535346136393964356231 -62346136356331393238346333393266613365633563626238353530333931613330663765393936 -32333261353634646366323238353238643837633735636662356630373464343330626630656130 -36356565356430643133386461313335343436316263303064366139316638663161356332386362 -37376431393661386231313763303266313630323362363664336366633035353562303439373630 -33343265633630343065363461363064653933303932613761303538393734373962613633386539 -66636534333537313135356665633966326430373062346136326532666638303334653263646431 -38393131653338316663313265653861663334326635353137623739396636333637343137636339 -32303836373535326363396434326233623532633931653039643763326263616232333462616631 -36666564623030396134346665386661386433366266363739626161653062323963313365353161 -35643530343439326133613939353737653165326538666530366530323963363839373032326462 -34666235376263616364656130633637346334353934396132353263313237316366303137386430 -64653563333963313361303239666361336136356363306266633833366262326431616161613238 -38653538613032386238623839663332613064333031303939363733396635373238666562386536 -32316566666435376239386637396334643861643634316338613063656465373164646530363865 -34373130636435326130633437303539646535336131393339613139383636333763336530636534 -34636666666265373636326666333130623863316465663333653466353063313134386262333739 -62626264393362353663303531313061643538663532333164336662343732373463623166396539 -39396531376338616538633633343733343765306237656466666232623163303738643431633763 -61656335616430653936303831393664653365363764333362373337323364323039363163353461 -61336536316466396636306266353830316665343739613033346538333830306263386134613737 -64316339613462346438656362346664303762643766373364343931626530626439336634666537 -31633964386564663531343764326666666261643464353438353035333665363434646661646663 -38636239373331623061343730376632393963303732393533396464633131633435373161303163 -66383461343861326665623463636262336562633936623563373136613063356362383862663232 -37333331373431393137363735613366656434323065346661366433663464666363343231393863 -64633530316230653065356165366135396531663731323866376162306238343962376362633234 -61626563306431623336623737353931316236623333623337383366613262346631646330313637 -39366239396330303461303666396431663062626533336136643039353034633230353765353334 -38613362653963336162326163356662356661386630353664333265373032316531656131376665 -37376262363130336161613230333863653662623436666361396561613935323432663665643138 -38616564636634613164313666393532396265396135326538336665373232316461326635306131 -34343632636637653835653131613161316237346239363830386536363933643532333533373333 -39643364306163666366376535653333323435383332633961343930633635383030356463333964 -39626130666166313234386439383833616265316265363430343134633730336261383435356138 -62373063346238613061363033343366623633373034346531303538396335653938646664303962 -31336634623135616237323837623831306535316463613266326262663934303938373132343735 -37656335333263326531646162393738653632376164323165393563656138613830633936396433 -61353332343134636564333233393863643837353366386234376237623435663765343366363033 -63326233383962633266303962613361643464613764303531333930363736323535386632393766 -61353666303134663466333330383031333933666137346364656364313965656164303065303530 -34616130653061613934393831373130333566363736626261316330303966656162326638333130 -66373133613536623566303432356666346535636237616561323063643439616436393666376536 -32613830343636393031333737376332396230313034393062663437613838363263333233613439 -30623039336339373234326261306435366332656164613439376139346333616331326561383963 -30643133376632656564616536323863373237623263366266396264633464373765316164346165 -37636233633661643362636630356333333766613036663335613264333439323239633861363034 -34663937376530653837653236303839336631313863363239626632646436653638366638366566 -39306538353231623434373537313862386335393262633062313432646232623863383731313031 -30656366363837366666393933346238363336363030373836386230343062363661306263633163 -33626562623935643665626239386133636531393536336661613430343630333961303233343430 -63656666346138643163393663316134666336323961626163376461663635633834333337393062 -61656163613234633965356133666335343065626137633137333266613561633936386136643134 -37383562663031393133326662623136386539633066323336306262346236613161613637626162 -36636133666334333636653535623732343233396430653566393165353431303739656239373738 -33323939633264303139323162613964306237376461383261646635343036313639626539373238 -32336537373436373338386432646139303831383138326564333739353761616336346461356532 -38303138656533386231303336336564656135346162376662663962663763353830663237323138 -33373331656637363139626132393231313136303936633161636261643264313230356261366165 -39666331306262643566663830626663656530303831343231323336306266363735393966613062 -63353938386263376166316335656164633233633465303065663565373764343031663866653135 -64663766386436653665356265333565323336636539656237303334383636353161643366656637 -66356532373130323236313936623964663433333965326662333833316437326461326165376661 -66396537653032346666363965313339323331303864616230646361386335663138613433326261 -35613430363864336635343434333761656639633863323534653862383936653762646134356664 -38326463326239636162333435656561343739366364313738663535636136323439373462643832 -62633661663337343538393466613734633531666532353161616231323161646237653736346561 -64323063656366373931396639393261643333393333626539663561636661393936316539633263 -63343331313464623636353031343232613534663565303538333164306531303438616539386364 -30376233333630336431336364663834633734636261353364343564333639623737363538313462 -61616233663335303062336635376435643965373039336231346234363436356238356162613138 -65326532663461616263626238346535623136633039613939353132313836373962646463333535 -65313562346631633435616232366166373763346337303561326130333936346130363431383036 -62356435616630396539303633343166646461393030336462366463636138316333633363643636 -65376131333731356566333237363266656466376539326438313930376363386231616138336335 -65333735653830373035656265336331346562353233663465343935383235303930633831613137 -64303130666532303733633133386334613733383562613661643931636136386264396438316366 -61653964643135646332343764666134336666336232376465353462356632346533633961636534 -32643234396636303135663562656435376561336235303837643932366334616265383639343733 -65633833653763643366646232343765306131313465326263623636386131376463356139623334 -39343163366439643334646663393434353333316234623530393431643539346435616263303734 -61633066653838363933646230623238653431393061646430383537343363643562653831336362 -37626630633161653763386663373630306564663339393265663732623434643231326335376562 -37663234643466366535326461396631633430613431346134316635653032663033623465346338 -61353331393631343365663233376330333730366161353362626166646232313666336333386265 -33373761313536326165343339346263316636363362393365663034353964373164643763383037 -3666 +61616633663963366535666638653235303963336131326665646631313731393761316238633533 +6562346633333230343363313062303266393231633636660a643962396261373463383439303230 +65316538666265356439373735343835646637626663666434393038326435363734383462663832 +6265323264356165340a633133343964343833373134363564353738356561303564306539666634 +37373736663031343834313361393739333731326164313562316132353766313066316635643265 +32353831626362373864313065383833643666353066383436643665316631313231653231316337 +33386537636461356164386163343133393364336234623564353134396637613431386334616331 +32376663646137353462633436623962346536616165303563316534356362353663326233623131 +66386461613362653063336332623261666664363633323934316437343165386538383261643262 +30656537383230303238306432633630303766353531643238333239343966363732373832623363 +62356539376434663564663761396230313539623838346463613234343036623433313864343761 +30353339363033633034646465633732336637326433343031653262613734376533643466333939 +39366234616361313433626331646333666561613131373562353862373962343034346439363737 +39383130306262643832306237633838643630316365616637303637613432383366653532333736 +61353261363436383839633538336662663238353137653962633437313233653139386566386262 +61323634393634356134653133656431646331383665613661396262363862666636396330643630 +33343330663430336662666263316161363562303461653930373734393462356430653733663565 +65616238356532323633313730316263396237306435383638366265663137623031613735393862 +66626161666366633738616161613933376534656461363439613237663263373237333961303765 +31373834356164323862396666623638306562633431313830326138646134363362393765393262 +66633065346132346363316337653263383334363837316539353830366465633764343739383737 +61303965313365633163333865663933646466323539626139306161663563386630323338336134 +62633766326132363063623930383935626233383534356236333232303262313138313062373937 +39386630656438373366396465383539313861323465333161363537323233643764356534643731 +34633362343938303265346237396466383038326435393338623464393035656365323662643736 +64363061383035393963306538316335326561613934653434613831616564626331346532353761 +61333030316636303038326564323261343237393436343433653563373736386238666461326663 +65343033343334316138333263393663356364623130303534343334303837393135353833393166 +66626161343962343239343639393537313836666561353665333266336330633832353764333230 +38313266353236346536323237373839616334323931623237366133313464653936663237323031 +65626461666334626462633531306339353439616364646239323738633365633539616430653061 +34623364326135323362396561323737363431383730306365303135383766346665653636323539 +66623138383661393738633266306233316437643630626465646363313736373837386266653062 +64643838353432656439643262636363633239646137663164353261663638333562636161633233 +63343237376661336162626237313632303332303062333861383135623062303031633130343964 +34386135376664366135353034376166653537386462383163613730353437666132333066396561 +37303633323063356433613933313038616436646562373031306535383332396633663731663135 +37336565353265316232643966326633376335623761313530363165306235646236653534666231 +38336438313362616234363635363565343632626662643462646466396666613034666136656361 +35306330613232386263623361373831353930393166666134616635323764313634353631346235 +30396336663737623765646466343232366232343739373964373230646632393732316234646165 +36623539303238346531666537386331326134323463383933323031383665323939313634356434 +61383330346637366530636432653035633234333865396561613432373963303030653261393431 +35303233393138356461306365383831353461306332626135373434383734356631386363616136 +34663233323031323162323563316562666462353663303366336536653837656266396435316539 +35326634316362643263393266643032373937346565623739353762356139653238383436643236 +34623564633162363338653963666539363063646164353164663039326437646537343936303936 +37626234663238373935633966626337356136363139626139373535633365383330393661393431 +32623339363539623263373934613539663037623738373264633162656364393033343265663931 +34643634633265643439666138383164366630306530373932393562613566666563396234613636 +35316166383036383335643562653230323561383931613033353061346539353538306637386564 +33393963376362313761636436623237653731343263373539633439323062366365643036336562 +35313433356236306138396131656334666336303135636364383861313934636633656666386139 +38636366383162626231646561363334306430366266316161353464396439313030613139613131 +38313130653737346137353239396162636364643431343436396131613161333132393462616263 +39656462313838353365363764616364643564666434623562366366346161643834306432643062 +31633732643466663439633530383734363366323938333661356436363861366634623336643664 +62353165393234313838366261623530653939373065376636356262303230386231663737343739 +33396533653065383734363430376662633965383465666365643234616331616366353532376330 +39633637303330633261356235623130303533633431366666616639326232626465633231666166 +63316161373539363533373338663433653334653135663534306539333563373164623639623762 +63346666616132613463633662306431356339313662323561626165356239326130643161346330 +34386166316339396165396337626634393237316163376336633730373635666237373563656531 +38663363666535323632353835373833333963346539613835653365396663316164313561366537 +64396330633939653535306633366165633463616635646566646235363062623434633466653732 +62316539343336396265376135346138336361346263303433636565623061633762623563366535 +30663562663131386532376631663838376238646137366163313134663565346335663535623035 +65333832363465613938626333636664626332386461616438393563346531306331666535666334 +34616430333234343833313636333561363863373564386630663361633032373730323566393636 +63353430646233323834383931643839643336653766343263666639656632326237666364636138 +39663939393533623439653534636635313166623962616633333136353331363963306238616466 +34626330653035376364333333313533383833356638633164383466613632363336613765636334 +37363365393934336666386336393031633532386163383463343032333139616630393166383466 +61336664343538346463376663656137316637666539353363373463346238313539383732643232 +37353865376530303737643635396633323938616133366463373732623032366334393566303561 +34613835303939616264653861643134306162373264383737323930303361373336326535346561 +33333764353234616332383939643837396331363137663835326264343935323763353764323337 +61333263313230353631383362643936363435623734353035353532643466333730383762333936 +36323666303962623038666634623962653634356330373236393931363363326564653835353064 +31333931626130353539613765346264653666363164373839383836313066353937356235636465 +32306230306337343036326139336466633564636530666337326462366337656565343130303739 +32313136376431633230616134346534313064333533313934393635383832326635626439643431 +39653836343336653366633434656364353563616436653931356435663638393030623162623732 +63343264313531393036633735383432643963343862386330623739333838656561663464303338 +66386233336563303563373835396566636366656634356130303130393539366131376631343834 +63663761326463326462643738636266393036626261373530656463373233363936613661303161 +65613537363831306631373662633035663732356130383230643933313738356531306237646531 +66373161343935613431646630396634393830393662393438333463366365376630306534363135 +33386563353932643862323432633332376639626563353936623762613163356364333231316565 +66396166396135633233373537366331353939393964316534616466396162383934323165393464 +34323464613639656333383334306637306264613534636365663338363262313134356130353932 +64373664626563613864653565613365636137303361343432613835663465363935303366633630 +30303332383166636233653164656230653331646662623838356132613933313266626330633034 +35303733616265316565626338346162666232343865636230663165646435633439393365643633 +63613332393965623232353562313430386161326265323937303333623531316334633039333437 +32376561313136366136666331396231633837613364396335326666313931383534383666386433 +66326261373262623666623731373538343530386166303032663933396163643032343231316632 +61386639393565326533646639373165343435653433333866323063333734613831343263363534 +32653332393862303632663534373932363731323861393032623138316366303332373538333634 +63653034653431313038363663313739656164393965666461303465363239343534306464303532 +33363636376163363339333336366234626163636563356164653132633033316435386230323939 +61396563303234613136663431373632643264303163353938346635643230303637323961363462 +37363434383933386130353861663636376162343736663166383136663662623334363537363135 +33396633653831623334343137646639373235333864666433306538303462353833643038303934 +61323663663930353339323565643366396336326136326631396461326566313330356430366330 +36383939373333353732393261353061663337313032643939396561613032303663636265313938 +62313633666532366339323031653661353961356566363335343964353531313638656438613864 +30646161303739356532633866313631313763623339633036646439666337636265343963303432 +64356232623236383138366163626361313333373038333931623566343130303761303462653239 +35653132636235383263363836313963343662623063376130666535653333353831623366326430 +38663565316337623432373830326363326562616330376433366436643139363663653632626537 +64333462353237646564313939623664313636366262366335656537626334376563386366643963 +31636531356135663061316163623037626262313437336462326535346330356161663335613433 +32623264666663383064333462646231666230393238643163396138616330663964313130306134 +34633439336239303766333039303961373563616233646232626635653137393864393661353830 +61353061386438333937646334303331303838303339323932653462653532373937393262616438 +36636431633764363932353333333464383162356131346161646638626262303633353732303238 +65353539393533353963393737303236323633393533346435333664303136383363363235363962 +38653738333732393231353061336334363263626136663065303130323739323562636639623934 +30616437626336363237353433306236633963343636396361653639323137393133343236336333 +34356265316461353966316261623538316332626536323030636433636636386337643631303265 +34363432373932643765343732616564393637383466343665313439363032393365313563663265 +30313863666236366539613930623130616533313930336330623230313638386135373732363862 +39333830623064396533626462363530636534306162363863656432636538623139653839623061 +63303465383136336562666265623333333034333732346137376265326166633833663335383539 +35376231393839383238303238656664303433373063313330373638393466383334306563363361 +35626638343730663332623835333337633262383330633134326132393732623432613235306332 +34356161363937356536393839313636326364333661303734653361323463616639613732313335 +63656134666461326636386337613833376562666137636634343932393430323565333736396332 +66333466333937316461373033663032326531643230383133353066306465333038643834303335 +37336261363161306338326461313534343738343364303431363166316565356666636338636432 +62633833396461626632386137636638376435643836376436636439313464636465363161326264 +62326264383865633133633438656463396138616136393961363834303034663764343430666263 +33343930323431653565346438633432666438346565373131356564643164663566666531646361 +66336536363664346332313136343934393963653535353533383764376334666666343932626361 +35313433356265353435656538633633313933326266303933373531633036356335393961666464 +35636230333564343131636532303930383032363462393638313939333532646336383463373063 +38306364303539623662393664656535643936663434636638363062666439376263376361313632 +34346238323639343863303136366464313061303332373239666135666337653961356633396138 +38623664323062353930363034326232326531663561613565386663366261626139633438393865 +65653261636536636137656635613361363064343838646435646338333335636539373235626134 +36656563373338376462353135363432396163313566316262313165343838646462626237383033 +35666136656361323166626335613465393131313464656462653063633466303538643836313562 +32623739313831636638313836646361663335613366336236666134666365303836396566313231 +35383038643662613539643665393039613562613962333663656261643636636663613738376431 +36653161666130626635313331373166393435323366326462623865643634353330646262333266 +35333232623065613635346534653133333766633634626438303932643338366566373437633161 +35323135393537653265626133376466623137343638656161353938623234376665613936373736 +32663161323864363031306439666561333438373536623162346438323139653032383038666339 +3037666133376562613632306463663031356431623563663864