From 37fb8c5f7e5f9a5230335186cea5a441cb08921d Mon Sep 17 00:00:00 2001 From: <> Date: Sat, 27 Jan 2024 02:48:41 +0000 Subject: [PATCH] Deployed 03adabb with MkDocs version: 1.5.3 --- .nojekyll | 0 404.html | 1699 +++++ CNAME | 1 + aperture/about/index.html | 2034 +++++ aperture/ansible/index.html | 2131 ++++++ aperture/bastion-vm/index.html | 1830 +++++ aperture/consul/index.html | 1755 +++++ aperture/firewall/index.html | 2016 +++++ aperture/icecast/index.html | 1988 +++++ aperture/images/index.html | 1869 +++++ aperture/index.html | 1808 +++++ aperture/nomad/index.html | 1893 +++++ aperture/socs/index.html | 1756 +++++ aperture/vpn/index.html | 1894 +++++ assets/favicon.png | Bin 0 -> 3823 bytes assets/images/favicon.png | Bin 0 -> 1870 bytes assets/ingress-topology.png | Bin 0 -> 258981 bytes assets/javascripts/bundle.c18c5fb9.min.js | 29 + assets/javascripts/bundle.c18c5fb9.min.js.map | 7 + assets/javascripts/lunr/min/lunr.ar.min.js | 1 + assets/javascripts/lunr/min/lunr.da.min.js | 18 + assets/javascripts/lunr/min/lunr.de.min.js | 18 + assets/javascripts/lunr/min/lunr.du.min.js | 18 + assets/javascripts/lunr/min/lunr.el.min.js | 1 + assets/javascripts/lunr/min/lunr.es.min.js | 18 + assets/javascripts/lunr/min/lunr.fi.min.js | 18 + assets/javascripts/lunr/min/lunr.fr.min.js | 18 + assets/javascripts/lunr/min/lunr.he.min.js | 1 + assets/javascripts/lunr/min/lunr.hi.min.js | 1 + assets/javascripts/lunr/min/lunr.hu.min.js | 18 + assets/javascripts/lunr/min/lunr.hy.min.js | 1 + assets/javascripts/lunr/min/lunr.it.min.js | 18 + assets/javascripts/lunr/min/lunr.ja.min.js | 1 + assets/javascripts/lunr/min/lunr.jp.min.js | 1 + assets/javascripts/lunr/min/lunr.kn.min.js | 1 + assets/javascripts/lunr/min/lunr.ko.min.js | 1 + assets/javascripts/lunr/min/lunr.multi.min.js | 1 + assets/javascripts/lunr/min/lunr.nl.min.js | 18 + assets/javascripts/lunr/min/lunr.no.min.js | 18 + assets/javascripts/lunr/min/lunr.pt.min.js | 18 + assets/javascripts/lunr/min/lunr.ro.min.js | 18 + assets/javascripts/lunr/min/lunr.ru.min.js | 18 + assets/javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + assets/javascripts/lunr/min/lunr.sv.min.js | 18 + assets/javascripts/lunr/min/lunr.ta.min.js | 1 + assets/javascripts/lunr/min/lunr.te.min.js | 1 + assets/javascripts/lunr/min/lunr.th.min.js | 1 + assets/javascripts/lunr/min/lunr.tr.min.js | 18 + assets/javascripts/lunr/min/lunr.vi.min.js | 1 + assets/javascripts/lunr/min/lunr.zh.min.js | 1 + assets/javascripts/lunr/tinyseg.js | 206 + assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.b8dbb3d2.min.js | 42 + .../workers/search.b8dbb3d2.min.js.map | 7 + assets/logo.png | Bin 0 -> 155059 bytes assets/network-divorce.png | Bin 0 -> 68072 bytes assets/stylesheets/main.50c56a3b.min.css | 1 + assets/stylesheets/main.50c56a3b.min.css.map | 1 + assets/stylesheets/palette.06af60db.min.css | 1 + .../stylesheets/palette.06af60db.min.css.map | 1 + contact/index.html | 1767 +++++ css/timeago.css | 15 + hardware/index.html | 1800 +++++ hosts/aperture/chell/index.html | 1863 +++++ hosts/aperture/glados/index.html | 1863 +++++ hosts/aperture/johnson/index.html | 1885 +++++ hosts/aperture/wheatley/index.html | 1863 +++++ hosts/azazel/index.html | 1885 +++++ hosts/index.html | 1808 +++++ hosts/nix/hardcase/index.html | 1891 +++++ hosts/nix/icarus/index.html | 1890 +++++ hosts/nix/motherlode/index.html | 1876 +++++ hosts/paphos/index.html | 1892 +++++ hosts/pygmalion/index.html | 1883 +++++ hosts/zeus/index.html | 1885 +++++ index.html | 1869 +++++ js/timeago.min.js | 2 + js/timeago_mkdocs_material.js | 18 + procedures/handover/index.html | 1846 +++++ procedures/index.html | 1834 +++++ procedures/irc-ops/index.html | 1967 +++++ procedures/new-admins/index.html | 1900 +++++ procedures/nixos/index.html | 1909 +++++ procedures/policies/index.html | 2038 +++++ procedures/post-powercut/index.html | 1779 +++++ procedures/update-wp-domain/index.html | 1857 +++++ search/search_index.json | 1 + services/api/index.html | 1992 +++++ services/bind/index.html | 1860 +++++ services/cheatsheet/index.html | 2009 +++++ services/codimd/index.html | 1770 +++++ services/exposed/index.html | 1941 +++++ services/gitea/index.html | 1882 +++++ services/index.html | 1799 +++++ services/irc/index.html | 1980 +++++ services/nfs/index.html | 2098 ++++++ services/roadmap/index.html | 2070 +++++ services/servers/index.html | 2181 ++++++ services/traefik/index.html | 1765 +++++ services/znapzend/index.html | 1927 +++++ sitemap.xml | 238 + sitemap.xml.gz | Bin 0 -> 526 bytes 103 files changed, 98562 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 CNAME create mode 100644 aperture/about/index.html create mode 100644 aperture/ansible/index.html create mode 100644 aperture/bastion-vm/index.html create mode 100644 aperture/consul/index.html create mode 100644 aperture/firewall/index.html create mode 100644 aperture/icecast/index.html create mode 100644 aperture/images/index.html create mode 100644 aperture/index.html create mode 100644 aperture/nomad/index.html create mode 100644 aperture/socs/index.html create mode 100644 aperture/vpn/index.html create mode 100644 assets/favicon.png create mode 100644 assets/images/favicon.png create mode 100644 assets/ingress-topology.png create mode 100644 assets/javascripts/bundle.c18c5fb9.min.js create mode 100644 assets/javascripts/bundle.c18c5fb9.min.js.map create mode 100644 assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 assets/javascripts/lunr/min/lunr.el.min.js create mode 100644 assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.he.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 assets/javascripts/lunr/tinyseg.js create mode 100644 assets/javascripts/lunr/wordcut.js create mode 100644 assets/javascripts/workers/search.b8dbb3d2.min.js create mode 100644 assets/javascripts/workers/search.b8dbb3d2.min.js.map create mode 100644 assets/logo.png create mode 100644 assets/network-divorce.png create mode 100644 assets/stylesheets/main.50c56a3b.min.css create mode 100644 assets/stylesheets/main.50c56a3b.min.css.map create mode 100644 assets/stylesheets/palette.06af60db.min.css create mode 100644 assets/stylesheets/palette.06af60db.min.css.map create mode 100644 contact/index.html create mode 100644 css/timeago.css create mode 100644 hardware/index.html create mode 100644 hosts/aperture/chell/index.html create mode 100644 hosts/aperture/glados/index.html create mode 100644 hosts/aperture/johnson/index.html create mode 100644 hosts/aperture/wheatley/index.html create mode 100644 hosts/azazel/index.html create mode 100644 hosts/index.html create mode 100644 hosts/nix/hardcase/index.html create mode 100644 hosts/nix/icarus/index.html create mode 100644 hosts/nix/motherlode/index.html create mode 100644 hosts/paphos/index.html create mode 100644 hosts/pygmalion/index.html create mode 100644 hosts/zeus/index.html create mode 100644 index.html create mode 100644 js/timeago.min.js create mode 100644 js/timeago_mkdocs_material.js create mode 100644 procedures/handover/index.html create mode 100644 procedures/index.html create mode 100644 procedures/irc-ops/index.html create mode 100644 procedures/new-admins/index.html create mode 100644 procedures/nixos/index.html create mode 100644 procedures/policies/index.html create mode 100644 procedures/post-powercut/index.html create mode 100644 procedures/update-wp-domain/index.html create mode 100644 search/search_index.json create mode 100644 services/api/index.html create mode 100644 services/bind/index.html create mode 100644 services/cheatsheet/index.html create mode 100644 services/codimd/index.html create mode 100644 services/exposed/index.html create mode 100644 services/gitea/index.html create mode 100644 services/index.html create mode 100644 services/irc/index.html create mode 100644 services/nfs/index.html create mode 100644 services/roadmap/index.html create mode 100644 services/servers/index.html create mode 100644 services/traefik/index.html create mode 100644 services/znapzend/index.html create mode 100644 sitemap.xml create mode 100644 sitemap.xml.gz diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..d63e303d --- /dev/null +++ b/404.html @@ -0,0 +1,1699 @@ + + + +
+ + + + + + + + + + + + + + +Aperture is Redbrick's fleet of hardware that was installed in May 2022 by distro
, pints
, skins
, cawnj
, ymacomp
+and arkues
.
It consists of:
+3x Dell R6515
+CPU | +RAM | +Storage | +
---|---|---|
AMD 7302P 3GHz, 16C/32T, 128M, 155W, 3200 | +2x 16GB RDIMM, 3200MT/s Dual Rank | +4x 2TB SATA HDDs (hardware RAID) | +
2x Ubiquiti USW Pro
+The three servers are named glados
, wheatley
and chell
.
The firewall is called mordor
, and the two 24-port switches are called rivendell
and isengard
.
The IP address range for the aperture
subnet is 10.10.0.0/24
, with 10.10.0.0/16
being used for user VMs.
Hostname | +Internal Address | +External Address | +Purpose | +
---|---|---|---|
mordor |
+10.10.0.1 | +N/A | +Firewall | +
rivendell |
+10.10.0.2 | +N/A | +Switch | +
isengard |
+10.10.0.3 | +N/A | +Switch | +
glados |
+10.10.0.4 | +136.206.16.4 | +Server | +
wheatley |
+10.10.0.5 | +136.206.16.5 | +Server | +
chell |
+10.10.0.6 | +136.206.16.6 | +Server | +
Note
+Blue cables are used for production network.
+nexus
is the name of the KVM switch. It's internal IP address is 10.10.0.10
.
glados
is connected on port 1, wheatley
on port 2, and chell
on port 3.
Note
+Yellow cables are used for KVM network.
+The new servers are all equipped with IDRACs. These still need to be configured.
+Note
+Red cables are used for IDRAC network.
+We have two address ranges that come in on a single redundant link, so we're exchanging that redundant link for two
+separate links, each taking responsibility for an address range (136.26.15.0/24
and 136.206.16.0/24
). So we're surrendering
+redundancy to gain uptime/connectivity during the switchover only. Once the new servers are production ready, we can
+recombine the link to regain the redundancy.
Redbrick uses ansible to manage its infrastructure. This document describes the procedures and some tips to get the most
+out of it.
Ansible is a python package, so you'll need to install python first. On Debian/Ubuntu, you can do this with:
+pip install ansible
+
Ansible uses ssh to connect to the remote hosts. You'll need to set up your ssh key so that you can connect to the hosts
+without constant prompts for passwords.
This is used a phonebook of sorts for ansible. It tells ansible which hosts to connect to, and what user to use.
+[aperture]
+glados
+wheatley
+chell
+
+[aperture:vars]
+ansible_user= <your username>
+
++Contact @distro for a fully populated file.
+
ansible all -m ping
+
This should connect to all the hosts in the aperture
group, and run the ping
module. If it works, you're good to go!
Ansible playbooks are a set of instructions for ansible to run. They're written in YAML, and are usually stored in a file
+called playbook.yml
.
Ansible playbooks are written in YAML. The basic structure is:
+- hosts: <group name>
+ tasks:
+ - name: <task name>
+ <module name>:
+ <module options>
+
- hosts: aperture
+ tasks:
+ - name: Install curl
+ apt:
+ name: curl
+ state: present
+
This playbook will connect to all the hosts in the aperture
group, and run the apt
module with the name
and state
+options.
ansible-playbook playbook.yml -i hosts
+
Redbrick's ansible configuration is stored in the ansible repository. There's
+some more documentation there on each playbook.
Ansible's documentation is available here.
+Sometimes, when running a playbook, you'll get an error like this:
+TASK [apt : apt update packages to their latest version and autoclean] ***************************************************************************************************
+fatal: [wheatley]: FAILED! => {"changed": false, "msg": "Failed to update apt cache: unknown reason"}
+fatal: [chell]: FAILED! => {"changed": false, "msg": "Failed to update apt cache: unknown reason"}
+fatal: [glados]: FAILED! => {"changed": false, "msg": "Failed to update apt cache: unknown reason"}
+
This is because the Hashicorp apt key has expired. To fix this, uncomment the hashicorp-apt
task in the playbook.
This VM is an ephemeral machine that can be placed on any nomad client that has the qemu driver enabled.
+It acts as the point of ingress for Aperture, with ISS and our firewall allowing traffic to reach it's IP address externally. The VM is configured as a Nomad client itself, in the ingress
node pool to ensure that only ingress-type allocations are placed there (like traefik). Those services can proxy requests from the Bastion VM to internal services using consul's service DNS resolution, it's service mesh, or by plain IP and port.
cloud-init
is given a static address during the initialisation phase to configure the interface. This ensures that, even if it is replanned, it will be able to accept traffic.
The base image that the VM uses is a Debian 12 qcow file. After all configuration was done, the size of the image is ~3.2GB
. The image can be used to create replicas of the ingress on other external IP addresses, creating more availability if needed.
You'll need to ensure the hosts have a bridge device configured to ensure that the networking aspect of the VM can function. See theredbrick/nomad
repo for more information about the steps needed for that.
You'll need a webserver to serve the cloud-init
configs. There may be another solution to this in the near future, but for now, wheatley:/home/mojito/tmp/serve
contains the configurations.
Plan the Nomad job and wait for the allocation to be created. If you used the correct image (for example a backup of the qcow file) the virtual machine should be configured and should connect as normal to the Consul and Nomad clusters and become eligible for allocations. If you started from scratch, then use the ansible/redbrick-ansible.yml
playbook in the redbrick/nomad
repo and ensure that the hosts
file is up to date.
For security's sake, there is no root login and no user accounts on the bastion VM. This is an attempt to make the node more secure. If you need to make changes, you should change the base image and apply that. The less vulnerabilities that are discovered on the bastion VM, the happier we can keep ISS and the safer Redbrick will be.
+ + + + + + + + + + + + + + + + + + + + +The firewall is set up using the personal setup type, using the elected-admins@redbrick.dcu.ie account (stored in pwsafe
+2FA is stored on the same device as the Github 2FA code.
The UDM Pro is not set up for automatic updates for reliability reasons.
+We have a 10 GB/s link to DCU's core.
+The current elected admins should all have access to the rbadmin account on the firewall. Rootholders should not have
+access to the firewall unless they are explicity granted access.
The owner account of the unifi equipment is rbadmins
(email: elected-admins@redbrick.dcu.ie) with the password stored
+in pwsafe under unifi
.
There is a "super admin" account that can be used for local access only, details are stored in pwsafe under
+udmpro-super-admin
.
The UDM Pro should be kept up to date at all times using the web interface. Please ensure there are no breaking changes before
+updating.
Error
+This is to prevent a bad update from breaking the UDM Pro and thus the entire network.
+If you are confident that Unifi can produce stable updates, you may turn it on, however please let the next admins
+know that you have done this (and update these docs with a comment!).
SSH is enabled to allow for rollbacks in case of a bad update (I warned you!).
+Remote access is disabled as it should not be needed, the admin vpn should provide enough access for you.
+If it is enabled in future, please update these docs with your reasons.
Backups are configured to run every week at 1am on a Sunday. 20 backups are stored at a time, therefore storing 20 weeks
+of configuration. This should be plenty of time to recover from a bad configuration change.
Mordor
is natted when it accesses the Internet. This is because the link address between it and DCU is on a private address.
+This natting is used only for the UDM pro device itself, not for the 136.206.16.0/24 network, and is to allow the UDM
+box itself to access the Internet.
The 136.206.16.0/24 network is routed down to the UDM pro box, within the DCU network. Essentially there is a route in
+DCU's network that says "if you want to access 136.206.16.0/24 go to mordor".
Icecast is a streaming server that we currently host on aperture.
+We stream DCUFm's Broadcasts to their apps via a stream presented on dcufm.redbrick.dcu.ie
.
The configuration file for icecast is located in the nomad config repo.
+It should just be a case of running nomad job plan clubs-socs/dcufm.hcl
to plan and run the job.
Note
+The job may bind to either the internal or external address. Ensure that if you make a change to the config, you
+inform DCUfm that they may need to switch which server they use.
DCUfm use butt on a desktop in their studio to stream to Icecast.
+The desktop must be connected to the VPN to ensure the stream stays up, and traefik doesn't reset the connection every
+10 seconds. The current icecast configuration for the server is 10.10.0.5:2333 or 136.206.16.5:2333 (see above note).
+Read more about it in this issue.
A shortcut to the VPN is available on the desktop (change a shortcut to the binary to include --connect profile.ovpn
.
+See here).
This is a cheat sheet for DCUfm to help them stream to icecast.
+You'll need to connect to the Redbrick VPN to stream to icecast. You can do this by double clicking the shortcut on the desktop.
+You'll then need to go to bottom right corner of the screen and right click this icon:
+
A popup will appear, click connect. This will connect you to the VPN. It may take a second, but a window will pop up with
+a lot of text. The VPN will connect and then it'll close.
+
You should end up with an icon like this:
+
You're now connected to the VPN.
+You'll need to connect to icecast to stream to it. BUTT is the software we use to stream to icecast. You'll also find this
+on the desktop. Once its open, (and you're connected to the VPN), press the small "play" button in the top left corner. This
+will start your stream to the server.
The username and password should already be configured in the software. If not, ask a redbrick sysadmin
+for the login details.
Warning
+If you find that butt is not connecting, then you may need to switch which server you're connecting to. To do this,
+go to settings, and then the "Main" tab. In the dropdown, select either DCUfm 1 or DCUfm 2 (try both,
+one will definitely work).
Your stream will be saved automatically onto the desktop into a folder called Recordings YYYY
(where YYYY
is the
+current year), with the date and time of the recording, and the format .mp3
. Take this file with you (via a USB or similar)
+if you want to keep it for later, it will not be kept on the desktop for long!
If you have any questions, please ask a redbrick sysadmin.
+ + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
It's nothing to do with cameras. See about for more information on the hardware.
+If you're a new admin, this is a cheat sheet for you. In order to get broadly up to speed and understand the content of
+these pages, I suggest you read the following:
So, you've hit a problem. Here's some quicklinks to some common problems:
+ + + + + + + + + + + + + + + + + + + + + +distro
, wizzdom
++Adapted from the redbrick/nomad repo's README
+
Good question!
+++Nomad is a simple and flexible scheduler and orchestrator to deploy and manage
+
+containers and non-containerized applications
+- Nomad Docs
All Nomad job related configurations are stored in the nomad
directory.
The terminology used here is explained here. This is required reading.
+All of the job files are stored in the nomad
directory. To deploy a Nomad job manually, connect to a host and run
nomad job plan path/to/job/file.hcl
+
This will plan the allocations and ensure that what is deployed is the correct version.
+If you are happy with the deployment, run
+nomad job run -check-index [id from last command] path/to/job/file.hcl
+
This will deploy the planned allocations, and will error if the file changed on disk between the plan and the run.
+You can shorten this command to just
+nomad job plan path/to/file.hcl | grep path/to/file.hcl | bash
+
This will plan and run the job file without the need for you to copy and paste the check index id. Only use this once you are comfortable with how Nomad places allocations.
+nomad job stop -purge name-of-running-job
+
nomad system gc
+
nomad system reconcile summaries
+
nomad system gc # (yes, again)
+
nomad job plan path/to/job/file.hcl
+
DCUfm - Icecast
+ + + + + + + + + + + + + + + + + + + + +The admin VPN is set up to allow admins to access the network from outside of DCU, giving them an IP address on the
+internal network for troubleshooting, testing and integrating.
If you just want to create a new client configuration, go here: adding a new client
+Installed OpenVPN using this script on Glados.
+To add a new client, run the following command (as root) on Glados:
+bash /root/ovpn/openvpn-install.sh
+
You will be prompted to add a new client, enter a name for the client and then the script will generate a new client.
+It will be saved in /root/[client name].ovpn
.
To revoke a client, run the following command (as root) on Glados:
+bash /root/ovpn/openvpn-install.sh
+
You will be prompted to revoke a client, enter the name of the client you want to revoke.
+To connect to the VPN, you will need to download the client configuration file from glados and then import it into your
+OpenVPN client.
kXKoO!y`PYbgR1j70~a>P-& zO2NCkAE5T#{_YbQ7Y^K2S#X`0jF|c$Tmj{bptGNY^_uQwgrixVN5IGy(nim2#g+q5 zCeYSVnRhx5?x=*v#U$tFbH55O;3pu0vq@}PR;O0Qkel<}AwD+Na#mw3%K#ykOiA#z zZ1P9SYrI*;g<~8zr%`jyLG|PR$#$~@4}!^7=KEZLdf^5EBy3`6`IPw?(eWF3mvl}PFVGvk#;{e@hD4v*o8RhQYW*AcjoJ&)*ETBg3P_H z `}|8!k)p>&tJ|9s|?a<6T*a47l7qS+j>Aswm43X1SnW6R|`)>LC-oSEx?S5G4! zk(Yo9+^CUU5ZquaYg?ej43HX<9>py{iAUu>N<6Tj*nJSY&iBhU9P%c!GO?|uUnn8Y zX(~|WMk_;_$D+q#h%+&D$$O%rx!iu ^9f5#Jje$>zRx*k=?-=UPNSobYRLgeh4nE V4f-#Gno>3=TyjWnE8#ou|#tN5g&Ql$i&dgu(pD=GV_#KR?;N zB+vr!`{T9ijr;-^F%=@WdcF1j>LxL4-cMuJA8%%wzd5C$0C5snsj$KCOU-AxsY^Q4 zgU6wG2f9F3+~;dZhq-^->EXs~$Ad;t|A=I<_%bN4kp{&sUF%qP*v*_4dJGHnk_tQ{ z-@7eF2f{UCaKS`+(iz>DaJTau>->93U%q@19BzO9Az))bNUN!FRTP|?;i$N!M@XX9i zO8HO39|EH}hQ#8~H_q0r!1~J%`ntBeuAyvlyiS4mhD3m3*!qtv-gV_e?;gn4HoG0$ zw3@}0r20+QV(z2?=Tw(m;S=TAy7FiuWs+F_cpTumu;*L{uZ|z5wAb5|4x9#F$~L?6 zu>?04r=ar4ZJn2yh4TYa%C(#*(S)uVAmwN^u&+=b1n8VJI89$Fw7#6Y#s1rT0)IYW78xnKbgN@DQOE38ZRWtV`9 #RK=~Ke36RD&>7qbd%>9;Z zntS<7MB$4H2e=7Ia2x6TedpD@r879^c>V~UC|^;PgaZHfBX;MRu(%uaW`{&%%%_mq zmncuX8RMml@b=W(Bxxr>MgLRcWVrj_fx-!!!pF*UZOk#0X%&hU>UwS)7+ZSjVfYkY z473Ox{@YW|la{M9WCOy7Y%PxrB=2~K>NyKapwR@64xMoz%UnU%8XI0eTnSVwAINDa zxB1>=*@1+5Bth6$qWkC mKgr!}OF+`UR)VYgf-fEc$&;u`#-$0VpT{#FG6*M=XhPuI@ zKlh{7L_eC=#AQIPs|`-0y6QwmAoMM55LwSSHwmT+^3Z!`zy$}y4o<${ofnx0;_h-i zRP|;)TPZ(W42|tYg$sR!(TkW6%2RbMMQM-(UZ`yaLr^(bIDVoqaBX!k#kO&y<(|bT zz!$~F*#Pb=RKVYBx-%$7IKty^rspNIRR}%w#6(C1+v@x_jIG)hz@8w<(88Us=CBaN ztq%bqkCbCtH!%S1BkLDljt8^ Nvr>3S$V+ zj!#a;JUpymEwY96WFa(_iYMj$J>O}*a3 HDt+k8h%_m<)gV6r;NQijZ?(v z5!P9BlVjI-=lF7i9U2`<&XnJF{y=|^z)_rHHd7JQE3^pVWCn4pmxpMC#g*t;2&Vox zx&X!WWdWZM{!~^AI2ehkAO`FxI2bEEQ5j_wX|p`nSVnYx4Y2;c5RpJC`uDP*T29W< zU4=&2>$tltUn4f~=_=vi?q~;@UOtustdN%N7}9V4bb)IZL!8Yd9z@{9mx$8aFH!gDq7a5-y}xMqEaYCY?p|w1JL(s;tI#=^D)9r=-_Kv` zjGmfTXI3(p*yZr76P4CWmAiE)V>*=}s_^(wI^74xfErV}Zv~BV5=S_DKx}MV*ZCp& z$QAF@stv@UNiS)okq;Zr1Z}`RrOX#nTu`;>WA~yj1k5zXDjoCB#0QNx=ZM)oNejJ6 zDV}MK1|PchBW4UTB7#DmGoGFLaL-h;ojd7<%0h?AVL)+0LHehOQWc4mQR0G*+t@cv z@r*tcZ;u%8i^|Tw<(=D;LHS^R_Qe;yJCXs+-C-_fb AA1DSu{6MV8D0siR<0Jlr=!_u~{BB I5cCu^)Udr^{IKijt5^B? zN{Y6RX7e@#hCz_Evyzi|{Pdk@bKxgX sUchXW_NwPtm`bzXPO9ujI-EVT3NJ8{N*=nZ9WVUXg&b%&!tj#BOVKgKuD zI^;EX%w` l$CuqI8UdCX%{qSE#(rb&_iHq`iS1LnAyrvTRFO tFe+)x z5Gg~HKu?NT3NOd8!}sTt_Y>Kt=h%}Hjv8f;z7Z%DtuX(VD1TSXC4ASD2&UrtM1gLK z5c6xVJ>IIQyG;|&1iVo6;l>jIeUmk}{rX>MJG|*+Pjc0`Uv%1hOMd?uX~p)=51djC zZwjgm(o8`CY+P#V{;jhSlEPyI$28HKuif5nYS#UyJEt%4AZ5I8p++xa7PVkz=5 wN zp^aB-qyHIVK}Ue%k?R5bLIeohh6;X%Ac-Ry|BYd *?a!l&QOvqrYlp9uH)rHmH!6xh_3pPV>CS3YU2o7+{q5RhnlS1oZRP zz4+U<-){Ta&s-zIo8)W{sf=z{(LcRSv_L}Cc|=-jV&Bi?f7sa99MpCgnSSmkC6*GL z(y$?rSjr>rlVp(>Fxu(SeyRzCpCq*bUq6i~srsTI^%0>H_eBf%#GU>BDs_-mdm42$ z)N)suW@KTNM!?i_QK@wtPd@GPF*U)9{;hGYFUG4kW}j#8QIAgpDwbDN?$msR Yty=tRV&?$wqfqAuL<1tzMVo#N)Z zdi$ItW_7Y_W{;Z1upZh4 RCS{_
RNy1;jH(=GFpl!ca5 zZ#7^?O`HNohvX-3Ne_tA*N=8SYG5w8RIu^n9D2x0XsvHS!2+t4&O`O=61bA-qj`hk z+76>e*{W_H1-Huo3XIO$^{R1~F?aW9$of)A@qHRcvoD?b81v!I7M~W6zv~}%>?@^= zs4QrH?A-g$vx+Y=BPB@khhUlWhtgMRN)8XzqC#3u33_$AcnNQse^$ko iU*81yq1 {H}6vpXk_73im#>W#I}4-ttUFS9EV1KJ6lw)WCFyhd(?xBB)v zL9DrP^W{K@s6qNLn|kw+V@ol{tT5Io z{8(C{SeO-u(t^RS+cqkJwi(P1wPwrP2I8C+%zMT=Ch@&M7$!GQV&JJgi%<0JrOgE9 zM 7L0Kp%oV_J@+ZCT&T8cu z@cpWqt?23JQO8qy+wW_qnAKiF^bw+l(7o6lhP}`2`nPL5-T)4y^OGT7^jD|#1)b|W zrKa~JbCg&)L|qs>JhpML<34G(ZJIZ<-KCKs{CESnHr1%;=ksQ-OdYJ;qkR1xN*t~; zmC_gad8}SfG#_O8DZj3mrz}v6zL-;p)eOR0QFSd*Ofsfof~_e+JYP!S(8hVQ9(i+X z_ve>PuQ!XqdcExoo{Gt8+}d8?ku(-{C9mv7;U~kLVks21D`6bdzjj YW0T#9W1a3}?$_P5wBM+d zOt8UDvbPn#7d9K}y!urmRPYDa(6vsnB(^%{jx3W`Eq)RJl>se8b?A&)-k Fv?vtOKvBMq Kw5;eKq4npt6{^lBmy^Vo5^W0 z=g}i`7ft;A#OeZP`i3YALzSX2p+|mM!~9(-vvb`l<`W*uYDNzI3292-IN^4PS0u(t ztUp=DCHbPt;PkFHD#rEU0&U^0VK>WBvJ%u7E};A^(bY3B_szC~mRpfmqUMFwggfJi zn!4fvs{ P}_Pp?S!@+&;2 &m-G!7{fEXs-H;cI zW$%moq2DvUnLjNy#jIzFyTN48dE=f!dAY lSz5mX`aZ&K>bCx#H6E z`A#*pk@=Hp`4tZ758$^Zhi}^-%?8{QAuwfV9miI7Ym$8QaFiA)Fx0PK#bNHY<=N~_ z_XO7*8&te^&Mwc~;8Fk|(c`Ry9Qzd&$x9}Hu~ _0m_*SB-=|ABq_{ zF6Hvx4({%y@W14)?v?$eRpyZD^eW_4yPcmr=am-G^^YanO@7Sn@@Sub-l*LJHgV24 zYSJ(3qmXi`fg8oQ#yER&GRu~|d;ddc?s%u>BOhY^nLc@4%#t@gjn_zF0eJ=l%ZeNd zDyC1~|4Nh)RyGdG#U?{ukS6}v@nwVy;JaM`8o6QvD(@Q%f6NtD%tp0rh;;#q(5;0o zEn=Bhfxeq|zeYkuQBg~l%wKz|vm!ThrnZ+>e~Y6t((YJ(`#>fNw{6S}Um ?>?|yKF0SYJdS7aY? z`bdX)Og5jZZ0q0-|C3*zZzMaE@B~R^|9J4a_bJnGbzNr0)5Uon3j9qkFA^9AoOhtl zPj6%=w4ZU?Lv82^Jf{S$4RyP2uT(deNg2fa^gu_JeE!V)@6^nniytba{-3<{_+@|< z0%~zr(N~=~y84q#Odd%92dMs^t6q>NA^tdd@Y=O&b;C`-0YPIrXt%h4bl=AP^52Jp zesTHy*^=)oj7rrj)W(aR`-B*E17!O-=I55$HAKXq?iRZv4^&03f0;u+fDZ<}XK28L zq=@j`26`k55;m2)Nb#!vt=f(HxEKwASE&khsf|uowQ1^ci^aFTgiKKAp}q$w-1$PU z0zBU1@Wu;>@2|_0r8-WpGbt&_?wklx(Ew+A0cmN9ckP20@Zdp-(c1(Z6upZJZ(s%t zsHeI7*Z4T-S4p0k)n!`w$@%?!Vl%tPzN#a=LC;7DuMVi~K<%=awh!15-H~j6ZMu>E z@2%z(hb=%2+HKx17#Ev6;f)}~cte-;fzfVgNt{=LEvSaR9AGNMum!b;hh6? XKo?7DK=2LTR@=@gF)8 zR0%-x`qdsipoLm>7F4XtxY>Qg&%6K2qs63NAS7Q8E~HXrd$N4cwak0v$9>?H(aWd? zJj3u{4^&+<($cC_#btlXN4fmS&(wV?fL%qsn~Rcq0{tM;f=;hZ!n*?h5)+InuIod$ zSr#8P8p!^a SPV$Ep!I