build(precommit): add new hooks

This commit is contained in:
Nathaniel Landau
2022-10-23 11:49:22 -04:00
parent 54cb31ec71
commit 4f35ba24ae
5 changed files with 352 additions and 300 deletions

View File

@@ -1,27 +1,30 @@
--- ---
# Full documentation: https://ansible-lint.readthedocs.io/en/latest/index.html # Full documentation: https://ansible-lint.readthedocs.io/en/latest/index.html
exclude_paths: exclude_paths:
- ../../.cache/ - ../../.cache/
- .cache/ - .cache/
- .github/ - .github/
- .hooks/ - .hooks/
- .vscode/ - .vscode/
- archived_data/ - archived_data/
- galaxy-roles/ - galaxy-roles/
- .cz.yaml
- vault.yml
skip_list: skip_list:
- command-instead-of-shell - command-instead-of-shell
- name[template] - name[template]
- ignore-errors - ignore-errors
- meta-incorrect - meta-incorrect
- meta-no-info - meta-no-info
- package-latest - package-latest
- role-name - role-name
- unnamed-task - unnamed-task
- var-naming - var-naming
- name[casing] - name[casing]
- latest[git]
warn_list: warn_list:
- experimental - experimental
- risky-file-permissions - risky-file-permissions
- command-instead-of-module - command-instead-of-module

View File

@@ -1,68 +1,76 @@
--- ---
repos: repos:
- repo: https://github.com/commitizen-tools/commitizen - repo: "https://github.com/commitizen-tools/commitizen"
rev: v2.35.0 rev: v2.35.0
hooks: hooks:
- id: "commitizen" - id: "commitizen"
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0 - repo: "https://github.com/pre-commit/pre-commit-hooks"
hooks: rev: v4.3.0
- id: check-added-large-files hooks:
- id: check-ast - id: check-added-large-files
- id: check-builtin-literals - id: check-ast
- id: check-case-conflict - id: check-builtin-literals
- id: check-docstring-first - id: check-case-conflict
- id: check-json - id: check-docstring-first
exclude: ^files/certs - id: check-json
- id: check-merge-conflict exclude: ^files/certs
- id: check-shebang-scripts-are-executable - id: check-merge-conflict
- id: check-executables-have-shebangs - id: check-shebang-scripts-are-executable
- id: check-merge-conflict - id: check-executables-have-shebangs
- id: check-symlinks - id: check-merge-conflict
- id: check-toml - id: check-symlinks
- id: check-vcs-permalinks - id: check-toml
- id: check-xml - id: check-vcs-permalinks
- id: check-yaml - id: check-xml
- id: detect-private-key - id: check-yaml
- id: mixed-line-ending - id: detect-private-key
- id: trailing-whitespace - id: mixed-line-ending
types: [python] - id: trailing-whitespace
args: [--markdown-linebreak-ext=md] types: [python]
- repo: https://github.com/adrienverge/yamllint.git args: [--markdown-linebreak-ext=md]
rev: v1.28.0
hooks: - repo: "https://github.com/adrienverge/yamllint.git"
- id: yamllint rev: v1.28.0
exclude: vault\.yml|\.pre-commit-config.yaml hooks:
files: \.(yaml|yml)$ - id: yamllint
types: [file, yaml] files: \.(yaml|yml)$
entry: yamllint --strict --config-file .yamllint.yml exclude: |
- repo: local (?x)^(
hooks: \.cz|
- id: ansible-lint vault
name: running ansible-lint )\.(yaml|yml)$
language: system entry: yamllint --strict --config-file .yamllint.yml
exclude: |
(?x)^( - repo: local
(inventory|vault|variables|default_variables)\.ya?ml| hooks:
\..*\.ya?ml| - id: ansible-lint
galaxy-roles/.*\.ya?ml| name: running ansible-lint
templates/.*\.ya?ml| language: system
files/.*\.ya?ml files: \.(yaml|yml)$
)$ pass_filenames: false
files: \.ya?ml$ entry: ansible-lint --force-color --config-file .ansible-lint.yml
entry: ansible-lint --force-color --parseable --config-file .ansible-lint.yml
- id: lint-shellscript-templates - id: "lint-shellscript-templates"
name: lint shellscript templates name: lint shellscript templates
language: system language: system
files: \.sh\.j2$ files: \.sh\.j2$
entry: shellcheck -x --exclude=1009,1054,1056,1072,1073,1083,2001,2148 entry: shellcheck -x --exclude=1009,1054,1056,1072,1073,1083,2001,2148
- id: lint-shellscripts
name: lint shellscripts - id: "lint-shellscripts"
language: system name: lint shellscripts
files: \.sh$ language: system
entry: shellcheck -x --exclude=2001,2148 files: \.sh$
- id: run-shellscripts-bats-tests entry: shellcheck -x --exclude=2001,2148
name: run bats unit tests
language: system - id: "run-shellscripts-bats-tests"
files: \.bats$ name: run bats unit tests
entry: bats -t language: system
files: \.bats$
entry: bats -t
- id: "ansible-encryption-check"
name: Ansible Encryption Check
language: system
entry: scripts/ansible-vault-precommit.sh
files: vault\.ya?ml$

View File

@@ -1,6 +1,6 @@
--- ---
# ---------------------------------- SOFTWARE VERSIONS # ---------------------------------- SOFTWARE VERSIONS
authelia_version: 4.36.9 authelia_version: 4.37.0
consul_version: 1.13.2 consul_version: 1.13.2
influxdb_version: 1.8.10 influxdb_version: 1.8.10
nomad_version: 1.4.1 nomad_version: 1.4.1
@@ -20,24 +20,24 @@ tdarr_webui_port: "8265"
# ---------------------------------- DIRECTORIES FOR SERVICE LOCAL STORAGE # ---------------------------------- DIRECTORIES FOR SERVICE LOCAL STORAGE
# These folders must be created, even if empty, to allow mounting nomad local storage end-points # These folders must be created, even if empty, to allow mounting nomad local storage end-points
service_localfs_dirs: service_localfs_dirs:
- influxdb - influxdb
- lidarr - lidarr
- prowlarr - prowlarr
- radarr - radarr
- sonarr - sonarr
- uptimekuma - uptimekuma
# ---------------------------------- SHARED FILE STORAGE # ---------------------------------- SHARED FILE STORAGE
rpi_usb_drive_mount_point: /mnt/usbDrive rpi_usb_drive_mount_point: /mnt/usbDrive
rpi_localfs_service_storage: "{{ rpi_usb_drive_mount_point }}/docker" rpi_localfs_service_storage: "{{ rpi_usb_drive_mount_point }}/docker"
rpi_nfs_mount_point: /mnt rpi_nfs_mount_point: /mnt
rpi_nfs_mounts_list: rpi_nfs_mounts_list:
- { local: "{{ rpi_nfs_mount_point }}/pi-cluster", src: "10.0.30.6:/volume1/pi-cluster" } - { local: "{{ rpi_nfs_mount_point }}/pi-cluster", src: "10.0.30.6:/volume1/pi-cluster" }
- { local: "{{ rpi_nfs_mount_point }}/syncthing", src: "10.0.30.6:/volume1/syncthing" } - { local: "{{ rpi_nfs_mount_point }}/syncthing", src: "10.0.30.6:/volume1/syncthing" }
- { local: "{{ rpi_nfs_mount_point }}/media", src: "10.0.30.6:/volume1/media" } - { local: "{{ rpi_nfs_mount_point }}/media", src: "10.0.30.6:/volume1/media" }
- { local: "{{ rpi_nfs_mount_point }}/nate", src: "10.0.30.6:/volume1/nate" } - { local: "{{ rpi_nfs_mount_point }}/nate", src: "10.0.30.6:/volume1/nate" }
rpi_nfs_mounts_remove: rpi_nfs_mounts_remove:
- { local: "{{ rpi_nfs_mount_point }}/downloads", src: "10.0.30.6:/volume1/downloads" } - { local: "{{ rpi_nfs_mount_point }}/downloads", src: "10.0.30.6:/volume1/downloads" }
# mac_autofs_type is one of 'smb,nfs,afp' # mac_autofs_type is one of 'smb,nfs,afp'
mac_autofs_type: smb mac_autofs_type: smb
@@ -45,23 +45,23 @@ mac_localfs_service_storage: "/Users/{{ ansible_user }}/Library/docker"
mac_storage_mount_point: /System/Volumes/Data/mnt mac_storage_mount_point: /System/Volumes/Data/mnt
mac_keep_alive_file: "{{ mac_storage_mount_point }}/pi-cluster/keepalive.txt" mac_keep_alive_file: "{{ mac_storage_mount_point }}/pi-cluster/keepalive.txt"
mac_nfs_mounts_list: mac_nfs_mounts_list:
- { local: "{{ mac_storage_mount_point }}/pi-cluster", src: "10.0.0.6:/volume1/pi-cluster" } - { local: "{{ mac_storage_mount_point }}/pi-cluster", src: "10.0.0.6:/volume1/pi-cluster" }
- { local: "{{ mac_storage_mount_point }}/syncthing", src: "10.0.0.6:/volume1/syncthing" } - { local: "{{ mac_storage_mount_point }}/syncthing", src: "10.0.0.6:/volume1/syncthing" }
- { local: "{{ mac_storage_mount_point }}/media", src: "10.0.0.6:/volume1/media" } - { local: "{{ mac_storage_mount_point }}/media", src: "10.0.0.6:/volume1/media" }
- { local: "{{ mac_storage_mount_point }}/nate", src: "10.0.0.6:/volume1/nate" } - { local: "{{ mac_storage_mount_point }}/nate", src: "10.0.0.6:/volume1/nate" }
# Add mounts to remove from auto_nfs to the dict below if needed # Add mounts to remove from auto_nfs to the dict below if needed
mac_nfs_mounts_remove: mac_nfs_mounts_remove:
# - { local: "{{ mac_storage_mount_point }}/pi-cluster", src: "10.0.0.6:/volume1/pi-cluster" } # - { local: "{{ mac_storage_mount_point }}/pi-cluster", src: "10.0.0.6:/volume1/pi-cluster" }
mac_afp_or_smb_mounts_list: mac_afp_or_smb_mounts_list:
- { local: "{{ mac_storage_mount_point }}/pi-cluster", src: "10.0.0.6:/pi-cluster" } - { local: "{{ mac_storage_mount_point }}/pi-cluster", src: "10.0.0.6:/pi-cluster" }
- { local: "{{ mac_storage_mount_point }}/syncthing", src: "10.0.0.6:/syncthing" } - { local: "{{ mac_storage_mount_point }}/syncthing", src: "10.0.0.6:/syncthing" }
- { local: "{{ mac_storage_mount_point }}/media", src: "10.0.0.6:/media" } - { local: "{{ mac_storage_mount_point }}/media", src: "10.0.0.6:/media" }
- { local: "{{ mac_storage_mount_point }}/nate", src: "10.0.0.6:/nate" } - { local: "{{ mac_storage_mount_point }}/nate", src: "10.0.0.6:/nate" }
mac_afp_or_smb_mounts_remove: mac_afp_or_smb_mounts_remove:
# - { local: "{{ mac_storage_mount_point }}/pi-cluster", src: "10.0.0.6:/pi-cluster" } # - { local: "{{ mac_storage_mount_point }}/pi-cluster", src: "10.0.0.6:/pi-cluster" }
# ---------------------------------- SERVICE CONFIGURATION VARIABLES # ---------------------------------- SERVICE CONFIGURATION VARIABLES
@@ -81,83 +81,83 @@ mac_tdarr_file_location: "/Users/{{ ansible_user }}/Library/tdarr"
# ---------------------------------- PACKAGES # ---------------------------------- PACKAGES
apt_packages_list: apt_packages_list:
- bc - bc
- coreutils - coreutils
- curl - curl
- dnsutils - dnsutils
- exa - exa
- fzf - fzf
- git - git
- git-extras - git-extras
- htop - htop
- iftop - iftop
- iotop - iotop
- iperf - iperf
- jq - jq
- less - less
- lnav - lnav
- logrotate - logrotate
- lsof - lsof
- nano - nano
- net-tools - net-tools
- nmap - nmap
- openssh-server - openssh-server
- p7zip-full - p7zip-full
- python3-pip - python3-pip
- rsync - rsync
- shellcheck - shellcheck
- unzip - unzip
- wget - wget
- yamllint - yamllint
- zsh - zsh
homebrew_package_list: homebrew_package_list:
- ansible - ansible
- ansible-lint - ansible-lint
- bash - bash
- bash-completion - bash-completion
- bashdb - bashdb
- bat - bat
- bats-core - bats-core
- coreutils - coreutils
- diff-so-fancy - diff-so-fancy
- exa - exa
- ffmpeg - ffmpeg
- findutils - findutils
- fping - fping
- fzf - fzf
- gawk - gawk
- git - git
- git-extras - git-extras
- git-flow - git-flow
- gnu-sed - gnu-sed
- gnu-tar - gnu-tar
- gnutls - gnutls
- gpg - gpg
- grep - grep
- handbrake - handbrake
- htop - htop
- httpie - httpie
- iperf - iperf
- jq - jq
- nano - nano
- ncurses - ncurses
- nmap - nmap
- openssl - openssl
- pandoc - pandoc
- prettier - prettier
- readline - readline
- shellcheck - shellcheck
- shfmt - shfmt
- source-highlight - source-highlight
- sqlite - sqlite
- ssh-copy-id - ssh-copy-id
- tealdeer - tealdeer
- tree - tree
- wget - wget
- yamllint - yamllint
- zsh - zsh
homebrew_cask_install_dir: /Applications homebrew_cask_install_dir: /Applications
homebrew_casks_list: homebrew_casks_list:
- lingon-x - lingon-x

View File

@@ -0,0 +1,41 @@
#!/usr/bin/env bash
if ! GITROOT=$(git rev-parse --show-toplevel 2>/dev/null); then
error "We do not seem to be running in a git repository"
_safeExit_ 1
fi
FILES_PATTERN='.*vault.*\.ya?ml$'
REQUIRED='ANSIBLE_VAULT'
EXIT_STATUS=0
wipe="\033[1m\033[0m"
yellow='\033[1;33m'
# carriage return hack. Leave it on 2 lines.
cr='
'
for f in $(git diff --cached --name-only | grep -E "${FILES_PATTERN}"); do
# test for the presence of the required bit.
MATCH="$(head -n1 "${GITROOT}/${f}" | grep --no-messages "${REQUIRED}")"
echo "$MATCH"
if [ ! "${MATCH}" ]; then
# Build the list of unencrypted files if any
UNENCRYPTED_FILES="${f}${cr}${UNENCRYPTED_FILES}"
EXIT_STATUS=1
fi
done
if [ ! $EXIT_STATUS = 0 ]; then
echo '# COMMIT REJECTED'
echo '# Looks like unencrypted ansible-vault files are part of the commit:'
echo '#'
while read -r line; do
if [ -n "${line}" ]; then
echo -e "#\t${yellow}unencrypted: ${line}${wipe}"
fi
done <<<"${UNENCRYPTED_FILES}"
echo '#'
echo "# Please encrypt them with 'ansible-vault encrypt <file>'"
echo "# (or force the commit with '--no-verify')."
exit $EXIT_STATUS
fi
exit $EXIT_STATUS

234
vault.yml
View File

@@ -1,118 +1,118 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
64663833313761613465336531333331376533306663343739643561356662393831386562646261 30623635333734313065373830313834623163353536653638363735383739616430646139333663
6663623065373237633664376664623166383839353237350a323139343936303539626436643131 6164633533343764316539376636343435363037633838650a643166646263633162616132626238
33633735323264363833626331306464313862643932303330316166623666333530333430343565 66663531616238373931663931333161633332643037303338323861396136306165313437316238
3063313964633161630a326637373363376464326330303936643563373038323337643533623562 6134653233656639640a653738393230666438396631303039393134393064353862306537363232
34636134646434356664653465663335616432343232343561383761343161663033623937643231 33333634303163343838376633393635386532313230323938366561366464313135376135343636
30396137646630666134333432383632333535313735386434386161643835383032343965346436 32613733663261653238633831316661326530346663313231386433323961613835666563346538
31613965396435376466656566313739306335346665656566303133626437353438316563663961 36643433353436393435636135326637356261636263333435653561653037356238313230653030
61653838366463656134396365373832303834323037383332363233376332303735363738396362 61613635393261363333306336316437333031356561356532396163396631643431373234373263
37306136633336386637633336333136323739666634356264383562383333643236373238323962 38396464613133396262653032356662343537613136626133656234636232643139623366303664
61323231373036616137616138366465376530623565323939333835386361323335396434666131 61626334306637323562663832643065636635396334386338393966343732623634386266373863
30316530393366376262363363353730393065306366313339313236313364303836376661313566 35333330626137633439623434393662396463643363333965393933623663326432346166613638
31653837656530313632333331323461316666346431656235316436626631383762666166346463 65663237616665333262656231613765326537396536386266396431623464376135643031616537
63333561326633663636623461663965376231313539353530633161613434363039363030663261 37623239396431316461326163313165663638306437623265353761666361616233333836643131
61613062396135343939393965386637313234633935313462336366616530333134383334333739 34363065373437303231343236633839323465363461313236303566363235356264633435613564
30353638646630353838663733306437663661386238376365373134343065316666336663393061 33326665623161623062316435646334356164333265376131636162326131613962393036666533
62383539373035323933326161653836343437643932663263646634343333303765646631643836 32613964393239353730656431383831366333323637353936373936616639616465643563653465
61306234663132313032343231386566346532386437343838653766306262613437653463313862 30376665393136653738376534663534316236666434643437646635383634356132666361623762
33623339643539383737353830633561316634313633313634323634663335326363653162363330 62306364363961303030383236616666623561376233636632373638306464323632323766303964
38653761636531643236313534643032633831666566376561313965663664626232326137373763 64373232333661316339616135383038656135643365306435643437303136336430393237373236
64653135326230313034663832373534306664366433623039306630333735633263356263646530 62383830653162623030353034623665313562366661633430313662353539323766373834333966
32346437353839633363646334316665643737353233333864663234363537343939383064383233 66336137613161386537653038623664643333336534663231396363633132386136373835613539
31343763626561346631363135363762323135626630653630306134333030383836333164383431 33386130366264633333373262393038356636653535303036313565336339316430333236333836
62623138333732303431303962323662356136323835623636386361333636636165333037636530 31313264666534613138656564396436346632636163613162323338393834373434623238306235
61323738303536666566306566616535316338393561303532393965303439663238393330303332 62386330316530333335646532623832653131323134646265613833393435333365326538633937
38303432313963393131393733333330353337616462363566666434616239343131613562393230 66313630656662613234363962636136653132656361633437613932353234663463643339613866
66376437653461316664346436663164643066633137343830366565323131646235623631306638 64333233396337343531666261613937306138373638356162666362643934383762663061623462
30393438626439333762323733623463623030353261653763396437396539316234363834666162 61616338343137666531343663373862316239363839353734623432653438613265613532353334
66326437326666396333326564663730396565643436623037313737343134333337356630656464 30333533653836333762316431383765333438313633663234656263343935313638363939386661
31663237663564376663633963393539383939303932353362333561653533313261656662623734 36636532623562393265316665393534343965303565383631626465613931353436393737646538
34336166613135353930613635616330326664656566333635386436663035646539633738373036 66626439363730666233626161353336623164323236386431643436396132363736646430336236
33313363333262396537613565393634336161386133386336343637633566303463643961616164 30343736316234656330353766326236633465393236323938383964323430323539383039363631
61303563336538313563323431636636653634393232316132366562336438306336306530366462 35366661373836316163363030626533373734633638316238656261396364646438336330653361
34393162633032633765613963393466643361643162393833383363396563663331313535643437 66613166663238653338316430306638663231393662343933383136383632343062613032333066
64366434613364393564633236343363663137653532313566343163633765633264376165333135 37613235313466306230316133333961666231666163323735326561343337306431363237643761
37363436646633383636316232336663363764366230363430643637663233313232386334303061 30623162653865356238303835386362643062326236366162326237373661653436343663643736
63333662613365386437363466326538626463373966343737633563373832616332386364376632 61306331656333333633353663393861633130336262346438626365646330646432663833623132
61346437343635653434656337333135653163373961666639643236616234336435393838653964 65383465376131386266616566306564323334303862306531623032353163633038303838633634
33393533316164656437333866313636363762663366343136343732323435393731623731653438 66396165633930363764663865333032346633393763646535356364303163343539323935363934
35616232376131353832326363363931366631376133303632353235393162613038386534326639 61376637656562643836653835326236303838393738303833366663626264346464343332646163
61636336366464633365386462656135356138393630313864616566386336326538333765363162 38386164666632623136313831643931623639633564356164633230346533376632363234346539
31616335666432336231663939303732346364313930623765656631323737623566383334363930 63393564346536353837626265373962316332326530613833663135373932393665336430306363
63353633356230643139326233313333646239313361303263323537623437363663356234343166 35333030373462653930393430623735376634636666633563643739313465643239313464343339
62363163646562336364373832643333333261323339653136306163383661316430663732333233 39646134366461303661306631616666376434323238363337346163386662343034356365656433
61333035323131623765663163643931663533653439306139363436326566653435383837383738 65653430393964623632336637366138353931633033366332666332643138616535353834323163
34636231326366626535663062393133643363663133663433303135303339323238616639666230 66353037376435613237643337633632306238623838616166343766323065336263323530633130
32633331653633633763383131633836646333356161323262383763343263633935306134333038 62366332333964346162366366616334313466383331326234626662343237353765633661333165
65363134306635363236396461316261363431353533356437363130313235633762613732346262 33633735653661643636306262613137326334643663616436326437313039396635623434633636
62363663373738373831356432663232623133646538643962323736656638636661333834623166 32373732333130376261663139643732313934373863633139376335313537353735343366653166
66363037373637303532373665613232313563373631366265386266366133373136626665626635 37333039333932336537633831313531336663623965653637613532376165383336646336386438
31663737356232346537646462336138333530336637623961613961346365656338343537376334 39613038376234356131396530613066323463386365313232336464636530653839636565396433
37356461636530343963313564393864383437636566393232626539336531636432613964636564 64636435383630313037643432656539643437663532333165356436323234653732396265623033
66333833616662626233623031353531343236303935316565353939316634656561323234623563 31326264663565383437613632306134303832363733333134303661633237316130346261306436
64336436336165336666653533336233623965373438336365323738666330656666613033613364 33353965613830313766363830363865363137353238663832626337343135333732343733343564
37346138336239316438383739343239656332376236366639656431383031626463323936373539 61613835623538356262653832613538313233346262633464386232643362643265663738633237
35383839656561333536623633336233316265343932326539323161363064646239373934656264 62663132333737376432323232663436343232326365343638636666376530353234313064616365
30653032653864303231336630343039343734343263373465656339313162373861633339616338 33633361363362653731306165666636353666613766343339623261633939656533613131363030
37393230313231313563323961353233383337616432353164366139333064306535353333666438 62336233393566313737356533613936333863393833636464313266646265663331303766326361
65363933333231306661396639313635366531323936333534343139626637663936303734383666 35303461383964363965313439613436323064663163336538636464353361643931326438393462
66373862666437646235616430636330663633626438633234346239666566336464643037353661 61656638313236666465653162633831363964313365333764616231376137326333346534656138
65646333343434613637636663623765306361303735633137376666393465376132616435646664 31663034303332383262373035323662373565336230633931316338333561366335336530653630
36666337626339313265613239663365333961366131613533313062643034343930343661643031 34633265653665643936646365643166303535356266623732343234373465323637313539303938
35306337313366363136396534653035383864666533336639353865653131376161346436313834 33653261306433643166336434623563333136386333303366633761613264333738613330633836
38333033313233643739653966633166306231396639356331643031393864616464376537393436 39303538366161363831396635303265316566363035366562316439616339333163306234663365
32313363643132666665396437313463373837623937346230653965626631363639646537316631 64346638366361383134663933643134613566616235356537353561363061393736313266623938
36396536333266323738366535393866313139636439663066373239636564663064306463393265 30613462343065666437326333613861393538313534333238373432353832613465663230616431
38313832356638323034303133316431356531376261616261373930303065306435386466393432 62343164613361323635353536353138313061303537353266313138666339613562386536346139
32303862316166323938363739336161313666363935646632396136633833616330323462363035 64356266656232633836616161363731303761396635646262643635383766336661346530373834
36393963653137323737383635343366383735383635623931333532343534646435656431383034 37386465633965346130643131663631373462316136333336383864616365306633643036393538
61663937336534653438353662336632326465636262623530346333323630316435323739373531 64623662383337663961383039376365366139653662633165313063386562636266666365386336
31626630343537393333383537326330383834666262633261356565646134643565666639616163 65383738633933663966626461613062346636303536333564623336613333656264306661613664
39343237323933663866373539356435613962636663323533386362363236333236386139623536 66616635363166643334653064386537656530663631633465656234646161636138393531373830
33303964313037353330323566626536663634343863366362666262666638393633333762343466 65633130393136333430336630366433376262396232613736313238663139353637316131376632
63396264366537316637373231643338393431316138653430386366656433306537656236666635 63643636373532343730326662396465356339616163363035663564363766303134646462663639
63643337623263363637646432396363616138623264393435306339323531613835623262356338 62333833303361373337613231373863316363643931373034633666656362363464313561363465
63353564353666363734643563666231363338623138366232393963303139363464666265626236 39343066353333353466323030633761336636383334666264356662376338646561386263366533
66643533366563303137373032636236353535356432653334363561626663633738303266666237 35646363313337393938643565653236353930336163356330363033373365346138343164393234
36336465386537353732666533386131656663633962663966313064636130393565363639616332 36373963373463373538393835636234333964623361356238626132613338616538633465396635
66633933623434323836666665656135393863333032323665363634313764333038323366663462 34356438386231376665373439646235626130646636653731366133373436373735373566356362
62356561613462613439643333386533646234613432343430336231663430386339343830613839 63343663626337326631386564363336343162333039643363363630393039616165346535383332
33666230373962386536336530646165396437303838613132303032303538366530633964636135 34306463326336656461383336373063356564353363656130356230303564346565656532653435
31323264376230626438623635396339346666363134343965626336326530343531666261616136 33666664376638663838613061643938356230663565336130316635353131633862643363333361
39323532643532633662373537346366636636633133623563656330383330343361616464363031 39383537323063666534626436383262393631656261326530643137323165616236373236653734
31313263303764666339613639353830646231633161633733653233356330353466333734346233 32633161646139626166643134313662356230336366356165393734333130653663333437346230
33666231386562333538623965363130396434316539316536333733636431656637663965303963 32613237333032353733383362643938363632376132323936396538643766353036306464613134
61623962643236386266396539653934323935623361323535396238636163366639303261656362 32616531653963363338383132353334356662613236303262653934613932376431616263663861
37646239333539303831636335636432393964363165306139633932343663373264313839336662 63346338323735313563303662623734396361323935613861303331313061326363616364386263
37383464643332313733393734326264663732396538666464346261316261653931353161646133 31656132303835343866343962633866346330333765653430613633376361353966396532366639
34343763396566666139376463656633646436343033333431386461376431303634333864313961 62373239363738633831326263653434656263326531323435386437356537636464333937316231
33323837613537613762376464643161313964646661613135323235356633366534383566336430 31623361343966323133666633663137633565396464633266643263663430386237663464346461
33373536656231623332383934383835353833626432626133633938376430383965633536656239 37366336383365353665666564663236633439343333386536306665343965616433333666313862
32636632326661363135376661633165313065333433663832333866623130613666663865343965 39653866303932663533333431316636333665396266343065323636376139333739613337663539
37623232363134303662653335613935376332353163356630653430336531643538303862623530 31306533396665376636353236363165613834366338653961666638643664383433636261363433
35623531376339663136356231643130353130316137383764656438663862306132353364316163 35356330353239653962616436373430303735333837643032613738633561633132323538393538
64313534636562613365656134396461636233666363396533353865323566663163383736633434 31376630376130323561656334306161373263373030636363633465663162613763613162353336
31356635306636316262396537353433393038633635653230396437663337323831396631393739 38346264636130353437383333303766306337313631626562323666343338353961663439366132
64333432303639396436326330613137383332386534356666616335313835383466623561633261 31356135666438633434383832396435353263316662313963303965386334646633646239313566
65356130646230376232633938393066303362653231643435613261363638633232616630363365 62653538663566363164326361306133313536363265643636646235333461633566396535373865
64626463353766366561666262366232303463383332363831343131336131633461346139333661 38663033623030653932386531653465653336383732346266353033306564353134646536363563
32613562373233393564636466373430333734656565343534393765326434646531363864326334 65333839343764656662366330393562383264613864323837633265616463363964313935353231
35366230326465633339323236383762316665656138663432336339343935353431316530666536 64633765613662303961396237316330323763663666386235326363643633336233613665353163
30626334376535326137663831623462333030633561333439303230303966626337383861366564 36326331643139643935343461643737353463643133353066323133373139663564333063313164
33626266366539356533626166313330303535396239656162366635633634656134393463356564 36353864396438363135323638393762343466666636633639343830303331343061666164386565
64633535333933313036316336666430373864393134366664633139343532386264373438303234 65363866303233343163633432653433633333393065373863393061643930633233643762316665
37653033396632646132616331393832393566373566363334343337626362646462636135383039 65383033623063333730656164623230373836313935353237306134616235396161393136616566
36613135386538383735346637643764356431366261363933653861633262373163333834633533 36626535633962636661366137316337623233326631396663616163623765643131386235653962
30363836616666643163633638373732336462396336303430363439336134313634393533373164 36643633663634626135653531303331313330333965383036373933396331633737343438613637
32396362353433373439666538393132623938356434363061383931633035336461643131323935 33303933346533636134633364336533383862323961323262646261326264393931313836313538
36386562373230663132326232653936653565303934333762383262316464633261363132323733 34656530343530386461366534396332646564373430333736396661353038623364646266366466
61303234386361386434363936393063626633636138333837356232373732643932313962313530 38626436333936313834336132333834383566376664613161643664366164633636336566303665
64396361333930303734363335353861313034643261313834343763333061623739653166666433 62663830666238623964646566346338383963306637393766346337653938616637636138633637
38353330633936623731303638326464306665393030643834633835393031313463616430336263 61363064323463306637643733316166303066356165383236333066623936626433376438613035
33336532666665343839363166386336643235386431373334326433303238306363613961393233 64363261343065633538656166353731646338346361333735376666643462363566393933656432
30323964363730396133646363613930636238303233386130353936353934323931356332363262 66303132386435653665343535323862336132323830313063636337316536613238343331326337
64336135383835643261383430343636633833386166626437333762656365336164636331326564 37393037383262393362396163343963326262366437336633366336646466313431656561636661
37303765623736643430653934633935363231376330393130313538353235646232343035636664 36333066333536646165626632343464323365353233383638326639666432323039623730383934
66356362616264393637323264353962306333613937363537326331633864663432376265326262 62656338636535306262353330653739363239623633616132373030383039386562663131343636
6338 6463