Compare commits

..

4 Commits

Author SHA1 Message Date
7a2ebf6872 nixos: Add ADB stuff
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h3m46s
2025-01-26 18:33:04 +00:00
72b8bd089c nixos/uk: Add WireGuard VPN for access
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h15m33s
2025-01-22 19:19:03 +00:00
cff229f487 nixos: Add britway
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 1h3m58s
2025-01-19 23:58:51 +00:00
f3ac3cd67f nixos/middleman: Add pubkey and HTTP access to p.nul.ie
All checks were successful
CI / Check, build and cache nixfiles (push) Successful in 51m34s
2025-01-16 15:20:57 +00:00
11 changed files with 1438 additions and 83 deletions

View File

@ -126,6 +126,7 @@
nixos/boxes/home/palace nixos/boxes/home/palace
nixos/boxes/home/castle nixos/boxes/home/castle
nixos/boxes/britway nixos/boxes/britway
nixos/boxes/britnet.nix
nixos/boxes/kelder nixos/boxes/kelder
# Homes # Homes

View File

@ -22,6 +22,7 @@ rec {
kea = 404; kea = 404;
keepalived_script = 405; keepalived_script = 405;
photoprism = 406; photoprism = 406;
adbusers = 407;
}; };
}; };
@ -334,6 +335,20 @@ rec {
assignedV6 = "2001:19f0:7402:128b:5400:04ff:feac:6e06"; assignedV6 = "2001:19f0:7402:128b:5400:04ff:feac:6e06";
}; };
britnet = {
domain = "bhx1.int.${pubDomain}";
pubV4 = "77.74.199.67";
vpn = {
port = 51820;
};
prefixes = with lib.my.net.cidr; rec {
vpn = {
v4 = "10.200.0.0/24";
v6 = "fdfb:5ebf:6e84::/64";
};
};
};
tailscale = { tailscale = {
prefix = { prefix = {
v4 = "100.64.0.0/10"; v4 = "100.64.0.0/10";

191
nixos/boxes/britnet.nix Normal file
View File

@ -0,0 +1,191 @@
{ lib, ... }:
let
inherit (lib.my) net;
inherit (lib.my.c) pubDomain;
inherit (lib.my.c.britnet) domain pubV4 prefixes;
in
{
nixos.systems.britnet = {
system = "x86_64-linux";
nixpkgs = "mine";
assignments = {
allhost = {
inherit domain;
ipv4 = {
address = pubV4;
mask = 24;
gateway = "77.74.199.1";
};
ipv6 = {
address = "2a12:ab46:5344:99::a";
gateway = "2a12:ab46:5344::1";
};
};
vpn = {
ipv4 = {
address = net.cidr.host 1 prefixes.vpn.v4;
gateway = null;
};
ipv6.address = net.cidr.host 1 prefixes.vpn.v6;
};
};
configuration = { lib, pkgs, modulesPath, config, assignments, allAssignments, ... }:
let
inherit (lib) mkMerge mkForce;
inherit (lib.my) networkdAssignment;
in
{
imports = [
"${modulesPath}/profiles/qemu-guest.nix"
];
config = mkMerge [
{
boot = {
initrd.availableKernelModules = [
"ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "ahci" "sr_mod" "virtio_blk"
];
loader = {
systemd-boot.enable = false;
grub = {
enable = true;
device = "/dev/vda";
};
};
};
fileSystems = {
"/boot" = {
device = "/dev/disk/by-uuid/457444a1-81dd-4934-960c-650ad16c92b5";
fsType = "ext4";
};
"/nix" = {
device = "/dev/disk/by-uuid/992c0c79-5be6-45b6-bc30-dc82e3ec082a";
fsType = "ext4";
};
"/persist" = {
device = "/dev/disk/by-uuid/f020a955-54d5-4098-98ba-d3615781d96a";
fsType = "ext4";
neededForBoot = true;
};
};
environment = {
systemPackages = with pkgs; [
wireguard-tools
];
};
services = {
iperf3 = {
enable = true;
openFirewall = true;
};
tailscale = {
enable = true;
authKeyFile = config.age.secrets."tailscale-auth.key".path;
openFirewall = true;
interfaceName = "tailscale0";
extraUpFlags = [
"--operator=${config.my.user.config.name}"
"--login-server=https://hs.nul.ie"
"--netfilter-mode=off"
"--advertise-exit-node"
"--accept-routes=false"
];
};
};
networking = { inherit domain; };
systemd.network = {
netdevs = {
"30-wg0" = {
netdevConfig = {
Name = "wg0";
Kind = "wireguard";
};
wireguardConfig = {
PrivateKeyFile = config.age.secrets."britnet/wg.key".path;
ListenPort = lib.my.c.britnet.vpn.port;
};
wireguardPeers = [
{
PublicKey = "EfPwREfZ/q3ogHXBIqFZh4k/1NRJRyq4gBkBXtegNkE=";
AllowedIPs = [
(net.cidr.host 10 prefixes.vpn.v4)
(net.cidr.host 10 prefixes.vpn.v6)
];
}
];
};
};
links = {
"10-veth0" = {
matchConfig.PermanentMACAddress = "00:db:d9:62:68:1a";
linkConfig.Name = "veth0";
};
};
networks = {
"20-veth0" = mkMerge [
(networkdAssignment "veth0" assignments.allhost)
{
dns = [ "1.1.1.1" "1.0.0.1" ];
routes = [
{
# Gateway is on a different network for some reason...
Destination = "2a12:ab46:5344::1";
Scope = "link";
}
];
}
];
"30-wg0" = mkMerge [
(networkdAssignment "wg0" assignments.vpn)
{
networkConfig.IPv6AcceptRA = mkForce false;
}
];
};
};
my = {
server.enable = true;
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJIEx+1EC/lN6WKIaOB+O5LJgVHRK962YpZEPQg/m78O";
files = {
"tailscale-auth.key" = {};
"britnet/wg.key" = {
owner = "systemd-network";
};
};
};
firewall = {
udp.allowed = [ lib.my.c.britnet.vpn.port ];
trustedInterfaces = [ "tailscale0" ];
extraRules = ''
table inet filter {
chain forward {
iifname wg0 oifname veth0 accept
}
}
table inet nat {
chain postrouting {
iifname { tailscale0, wg0 } oifname veth0 snat ip to ${assignments.allhost.ipv4.address}
iifname { tailscale0, wg0 } oifname veth0 snat ip6 to ${assignments.allhost.ipv6.address}
}
}
'';
};
};
}
];
};
};
}

View File

@ -79,6 +79,10 @@ in
sha256 = "018wh6ps19n7323fi44njzj9yd4wqslc90dykbwfyscv7bgxhlar"; sha256 = "018wh6ps19n7323fi44njzj9yd4wqslc90dykbwfyscv7bgxhlar";
}; };
} }
{
name = "ssh.pub";
path = lib.my.c.sshKeyFiles.me;
}
]; ];
} }
wellKnown wellKnown
@ -343,6 +347,8 @@ in
useACMEHost = pubDomain; useACMEHost = pubDomain;
}; };
"public.${pubDomain}" = { "public.${pubDomain}" = {
onlySSL = false;
addSSL = true;
serverAliases = [ "p.${pubDomain}" ]; serverAliases = [ "p.${pubDomain}" ];
locations."/" = { locations."/" = {
root = "/mnt/media/public"; root = "/mnt/media/public";

View File

@ -150,6 +150,7 @@ in
mstflint mstflint
qperf qperf
ethtool ethtool
android-tools
]; ];
nix = { nix = {

View File

@ -14,7 +14,7 @@
network = ./network.nix; network = ./network.nix;
pdns = ./pdns.nix; pdns = ./pdns.nix;
nginx-sso = ./nginx-sso.nix; nginx-sso = ./nginx-sso.nix;
gui = ./gui.nix; gui = ./gui;
l2mesh = ./l2mesh.nix; l2mesh = ./l2mesh.nix;
borgthin = ./borgthin.nix; borgthin = ./borgthin.nix;
nvme = ./nvme; nvme = ./nvme;

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,12 @@ let
inherit (lib.my) mkBoolOpt'; inherit (lib.my) mkBoolOpt';
cfg = config.my.gui; cfg = config.my.gui;
androidUdevRules = pkgs.runCommand "udev-rules-android" {
rulesFile = ./android-udev.rules;
} ''
install -D "$rulesFile" "$out"/lib/udev/rules.d/51-android.rules
'';
in in
{ {
options.my.gui = with lib.types; { options.my.gui = with lib.types; {
@ -26,6 +32,12 @@ in
pam.services.swaylock-plugin = {}; pam.services.swaylock-plugin = {};
}; };
users = {
groups = {
adbusers.gid = lib.my.c.ids.gids.adbusers;
};
};
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
# for pw-jack # for pw-jack
pipewire.jack pipewire.jack
@ -46,6 +58,9 @@ in
}; };
udev = { udev = {
packages = [
androidUdevRules
];
extraRules = '' extraRules = ''
# Nvidia # Nvidia
SUBSYSTEM=="usb", ATTR{idVendor}=="0955", MODE="0664", GROUP="wheel" SUBSYSTEM=="usb", ATTR{idVendor}=="0955", MODE="0664", GROUP="wheel"
@ -88,5 +103,13 @@ in
]; ];
}; };
}; };
my = {
user = {
config = {
extraGroups = [ "adbusers" ];
};
};
};
}; };
} }

View File

@ -0,0 +1,13 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IHNqUFR5ZyBVVkI0
dE5YN1pJWExzLzltcmhna2tJUmdRNjZ1Y1hwbzdtRE0wa2hReTNBCk4ydmNFK0FF
b0RUdVl3a3d4amhKSEVhZWZPeHZDenBiTXpkVVFiNXFXNGsKLT4gWDI1NTE5IG9i
K0ZrNEc5SVlyWU1EbXdlbWppRG1DdjFRbTBCREY2OUxrMmVqNHhSazQKVnRaVmVn
MFBRL1dWeFNOaEwyU2szb1lOVzF1enQwdmVZZWRJcHd5MHdFbwotPiB2Wy1gUV8/
LWdyZWFzZSBdSDFebHsgKkBkVzl+KnggJTEKdlhrdzVpMHYxUUliQnhaYXNaVWNR
S3NxbjhFMEFGamZkRU1RNURhcmwzOGxFbGxXelhOdDBWTHBSY1hBcGFtUwpkampi
WnhzMDcxTk1seWZ6VURZb1l1QU1GdwotLS0gRFNpcXpDUFZLTXFJN3Z0bEJQd280
WGROWUVvdSt3ZUdBbmRNcGFhRE9BWQoDDlPEY/t2eapa4Xbv8FcW6gdLzQn7Y2cH
5UwD+0CTF3JdUpxWUIx9RWFleHekkt8j1+2/oO+m7+24yCg5mdqTJ3ZIwu9uk1eI
0As8IA==
-----END AGE ENCRYPTED FILE-----

View File

@ -1,14 +1,18 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyByYlJn YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IHNqUFR5ZyArUnBS
aERLcEhadS9jVUlyUmgxWEk5K0U2cE9WUlhCc0ZXbzhDRnZLTERvCmo2Vy9XeFhq MCtjZERmK2IwTm16eGcrZFF5QlpYZU9VbUNzbHZ2VDBoZkJkam0wCndDdmhHc2pu
NTcwdG5PZjlDb1JIM3BYWEVzMlBFWHFmRWt2dkF2OEQ2TDQKLT4gc3NoLWVkMjU1 TFFiT3MzcU13YklrdFpiRW1ZSU4zUGFQbXF3ellUU3U3bUkKLT4gc3NoLWVkMjU1
MTkgT0VxTXNnIHROaUlGUExERTZFaU5QL3dBcFpQVWNobGQwSEZ1YTU3NXJkekRi MTkgRExNZUZnIE9EbUtYRFg0Z0xuVGNRM2pad3FFVGRDVTA3ZE50SHlvT1ZrU1NW
c0RUMGsKUHg4V0hIdFJ0aGxwOTFhaVB6MUdVWE0wUFgrMjI2am5uZlhWL09ObjhB b3VYREkKL0dPV3RGMHYyUW9jSlJhTU5yTnR3L0pHVjZTNWpoaGJiSmlPVWlDYlFv
VQotPiBYMjU1MTkgTWwyQjZjcUFYQ01KUHpoajRrVkpZd0czSzVrMTZxdjVHaHRh RQotPiBzc2gtZWQyNTUxOSBPRXFNc2cgRkwrZEY4RjAxYzhpbEE2eU0ya2N4emE5
bERCSjBqSQpYOXJibDZPM2Z6bkNCSGpMRExZT21UTzU0N0RiT2FNM0l3N1pnRkl6 T0NlUnJwUi8vdVlJWlVOWEZESQo0OFdldUdML0hoR0NENHp2UktCTFhOYkxUZyti
WUJBCi0+IE0qLWdyZWFzZSB6TDVwIGRiQm0gajFFIEVqUXcKU3pEOFBqRVQ0dDZi OGlhS3V1RnFUdHhVT0JvCi0+IFgyNTUxOSBOcnEzanBFWnltMUwwd3VBd3Jablk1
REszS1h0T2FnOFF6cHBrN2xtOHdEQkIrCi0tLSBTM3EwNHhDaEo1eldDOTN5dzQz Z3hDU283RVJxSlkzKy9JQW1adVVVCmtnSjVTTSsxblpsczMzR2NldlFlTFk0S210
Q3Rpeno1K25KRU15L01wU21tczNmdlVJCqHBdFLovtLJGH9IY86pvc3xhpoLnfI/ T1AxV1RQRjhDSU1CQ2p6M1UKLT4gVnNOLWdyZWFzZSB1fDAgYy1xRSBESjoyIDJz
OVAF5RdpR9T2oNCr3oAiVURkPocYXLHnbjZhLKoj3uDoSZAE52VN9l05jhyX1wwY CkdRcWxTa1NHVkJDcUVmeDlIVEZTcW13N0I4ek5jTjliQ2t6Zk9nRkloQmhSY3hG
/Vfnp48kP8xfbQ== TUdJekhXdlRzUGJ6WU8zRXgKZXFGUGgrTndSQmVyMFcyL2J0bEdKY09paTkzRHd0
R1ZWVVVuaDljWE4zK00rdllOdGRVTzVZTnFtT1p0WlZOYgpGdwotLS0gd3dvU08x
SzJkdjAvQys5Mnp0dDZQUWp1dzZ3U2tuYUpqR09xeTJnSzVDTQooXx8cndfMYlmf
7eCLssPnHKj7KKgUfiihj91X8pokJR/++wQSarMdRtFB0S0MpDs/khwgG0HkmrKp
XB1jureGwJs7gmJ6gafKCKSkBv9Jkaw=
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----

View File

@ -1,72 +1,72 @@
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IERMTWVGZyBVUDR4 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IHNqUFR5ZyBaOU1F
Um1XS00yUDFIRnYyZzg2KzYzanBIMWFNTmV1MVF6ei8rZDBiTXowCnBBRFEyQU14 ckpVQWNGejNoQUQzaERobUNmRFMyWVFzc0Eydkh6SEVZNHU2SHhRCmc0NUJMa0lG
ZU5MdSt0NnRJdUMyMyt6dVlOWHBqUnkvRWNmMjNRUENKeTgKLT4gc3NoLWVkMjU1 SnRuZHR3dmNKem1oYXA5bHVsNWcwY0xzMTlqQUlsQWJiSFUKLT4gc3NoLWVkMjU1
MTkgM2JCM1pnIHFyc2laWnBTQU0rcThOamJTcEtlUGNsSW8reTc2eTJjbVBkZlJu MTkgRExNZUZnIG9Ca2M0ZHJwS2I5VWJiY1ptUWJtNTdVakVGQXlteGdCRHg4c3JO
cXEzbUUKcmFrTEVjaXY2a0lJNEtCWXNjTUsxNENkSWZmZUJhRm5ydWZ6WlJ1aDdR cXpaSGMKTHlidkxRZ01mWVRLRVRZdWRyNTZWZDhmR0Vicy9hYmF2elg5M1FXNGF6
RQotPiBzc2gtZWQyNTUxOSBxKzBYY3cgRVBuOEJ4K0NRVjdLdFhIU2Y3ZGQwL3F4 UQotPiBzc2gtZWQyNTUxOSAzYkIzWmcgZE03MlRsVDQzdlF3R3F0TWppdU4yV2J3
clFjMVNsOWNvTU8wVlRoNG5CZwpycFRlMzFjZ0drN0t5QXpoMkJ4aERMYkxVSFhU N21xS0djYnQzLytKK3JBenFoawp4bk1pWDlmZ2dmOFU3djBHVlN1alJETENGMGhM
STJTdUNzeWtkUmFMTHVBCi0+IHNzaC1lZDI1NTE5IFpCM2U2USBBRUhnNlNzbDVX eWhGSFNGUW5OenpNMFRvCi0+IHNzaC1lZDI1NTE5IHErMFhjdyA3am5WUzQ4a0xM
Q1ArRENrZzBrNkhhSUd5dEZnM2oxRUtmYWx2L1NtbG53ClZIalNsaUNBUUtKWGpT OEpvdTVGVjNVV2tMNnRHQ2IraGdZbjd2VjcrTnJzSjA0CmoyRjI3U1R5bElhb0NL
dTM3VExldm0xRXJoSWZ0SU4vdWk5SDlZTEFPczQKLT4gc3NoLWVkMjU1MTkgajY3 UU4wRG1VZVV2MlpFdFkrUGdNNVNsOTJjN1pmZ0kKLT4gc3NoLWVkMjU1MTkgWkIz
RlhRIGR0VkhtNWxCK2xSYUNlS2hhdzRldEVZRDQwNmVnN0dtRTdOamFSM1Jqek0K ZTZRIFByVVhNbzRFQ0grb29hd2x0OU9iUU5sbjU2Zld0RXExM0RHT0M1VTZ6U0kK
YS9uWGMyY3JzeUZCWkhLTzk4d1dxT0NkbEQ3UnlWOStCdUh0bkg3K2N3TQotPiBz a2lVNzZiNWkwMy9XT2lIVnQrNG52cWx1b3lNQk41WFhHenlsVDdlR1FjZwotPiBz
c2gtZWQyNTUxOSBjMFROYVEgYXJhZUdOeEphOGxkMTZmamJxdmMrTElkYkFScVA3 c2gtZWQyNTUxOSBqNjdGWFEgVzZURHE4ZHZ0YWNYZ1hkbWQvdDhQbzJ0R1NMNjRv
alExSC9TVTJzeUFqNApsZXo1cC9wdnp3Zml4bG52ekFHMEUyU29acFFJeU1VN3Mr QkVWdkNPWFN4blNGawo2ZndJeEhsbkoxYjBXbk96bjZsMXVqeE4yMDFRaDR1K0Rq
ZlorWC9VWDZzCi0+IHNzaC1lZDI1NTE5IG44Q3BVdyBTenhVdjNncGxudDJ2Y3lw eExHNDFBNlpnCi0+IHNzaC1lZDI1NTE5IGMwVE5hUSBjQXhrenI5cTZhNkR2VnNG
K0JIOFJDd2VVQzFkWGc1STROdFZqbnUrYlJnCk5MTWxRYVRPcUFjMmdySEJ5Rndy VitKUzQ5QThOcFJCZytTUXRrQzFZWi9VREZ3CnZFTU5QNm84NjVGYmp4RTZTM0Js
TzdnNGErNnBRa1dTSFVFekxQUitOYTAKLT4gc3NoLWVkMjU1MTkgakk4UkFnIGtL cTR0WUMwd1RWS0RJNHo0dDBkS1A0NE0KLT4gc3NoLWVkMjU1MTkgbjhDcFV3IHVz
c1psRWRRN1hNZUNiVHFmR3JGVm1jUWJtdm91ZVR6M01zNmhGdW9pRTAKNGpwek8w Q0FiOTBIYUY5SFBLK0Zia3YxaHd4dVN4bDhjbjZYaFVKNHp6VkFOMmMKeXAzcndh
QkRnSkZXUjhEMEpPaUdkeGwxZDRGbTRSMjg1Z1pMdEVSaTJEdwotPiBzc2gtZWQy M2hLWUFSNlJTUXFhNnlZZGZCYnBvM1AzMVg0QWFvK05rS3ZlOAotPiBzc2gtZWQy
NTUxOSBoTWE0bncgYmRqR1FRaDdQQ09ZZHQwWmQxVUJ2QWdLYjdoRlNLU09GYUNi NTUxOSBqSThSQWcgS0NRY0pKaEd2UmVXcTU5bDFYSkx6cS9KNnVXbXc1ZVpxelIy
ajJhMWx5QQo3ZWFNWjMvTzNxSXJjeTY5cTNMWmk0K0IzZ053Mmd6T1hhaVFTVVBj U2E0T2VSRQo1cTZzQWk3cDRPSjVOdFQrOWNvWDVhZlE1VTRmRjBHZ0JjTVdheFdX
NHBrCi0+IHNzaC1lZDI1NTE5IGV5cTNkZyBXbUdJKzdMZDF1NW1pTi94aUtjNGpo bVB3Ci0+IHNzaC1lZDI1NTE5IGhNYTRudyBPUW11MkNuQUsyelNiejl1UEhvMFJT
aGVLbno0RzE1MXlURTJJQ3hRb1dVClg5K2FwRHBvcXIwVUl1U21GSnJsSmJmMGZN bUxmQU5MaW1Qcy9JeUZoVzdUSzBVCmVZWHoxTFVQWmJQbDlzYXZhVkxYRSszOGdm
cmdBcmRiRERzcjJmZzV4Q2sKLT4gc3NoLWVkMjU1MTkgN1dROVBBIEIrays1YUJN MktPS3ZNV1BpZFJkM25wcGsKLT4gc3NoLWVkMjU1MTkgZXlxM2RnIDZLMzQxNFMr
TkRMS01oVzQyZEJuSjFPTTV4YkZSMDdTV0UvZE4rZ1U3SFEKWEZSL0g0dmFnelJC azlybFZLK05xY21DU3BOZnduOWt4Z2lDNzl4KzVtYitrbUkKcGR1OWtkVTB1czdE
S3VGZDlaTHhJQ3NaaEc2aUsvRmdKdjRNZ1VXMExmQQotPiBzc2gtZWQyNTUxOSBn dWdhd0U3cC82Ry8zTStkQ256N3RMQlZCbjU5bWJVbwotPiBzc2gtZWQyNTUxOSA3
U3hQMFEgODNUUEg4M0hLL3RSUXk4M3dGV0tZNjJXQWxabmxLanF0Slc0WWMyUkNo V1E5UEEgb2IyVVNmM1AwNTVnZExDTEp1NWw4S0xWK0lnWG5DQ1dQTnh3RmNuZ2x5
bwpCMGlaZDdodk4zeDROczVFc0FxM25qMFdicWZZSVpjb2tiT081bUVUTGFzCi0+ NApNaXhzL0wxUWtHNHpWSWplRS8wSzk0cEs4S21VUnp3azlRajJNdlJ6ZEprCi0+
IHNzaC1lZDI1NTE5IFZGY3c1ZyBKanVnSDI0bUhvS3RVbzdSc0s2TmQzSVdEczRF IHNzaC1lZDI1NTE5IGdTeFAwUSBLWXV1VW1Pb2w0ZkpOUlNEa3dLamFGSDFJMWRq
eU1CazZPM094eEt1ZGp3Cm1HWGluLzhoRUtNRDZOcVJDVUR1R3dneHNHa1M1VGpH NzVMZDRXUWY0UmVuaUhjCkNlWFUvRHByUVBEenFXTXBMZ3k5d2l2L1BaUHprYVN5
YWF3TDQ5cS9saFUKLT4gc3NoLWVkMjU1MTkgaGtidHZnIHJLN2dJQnA4eGo5SnU3 ZHZmdVAvQk1lY3cKLT4gc3NoLWVkMjU1MTkgVkZjdzVnIG1IUngvcVNSM2RrSDF0
SkttSlM2YXNERXJOYjc1Tlo4NnhFakdYT0dqUWMKQllrZm83NHJrYmtWaytCc1VI dkZMSlAySmxWL3VqLzJYWWs3SUZTRWpvUkQ0R0EKalMzNW5rSXJES1M5Y2tVeDRW
aVhESUtYeHpoT0JmdStSRURMZ0JldlQwYwotPiBzc2gtZWQyNTUxOSBldDJ6cFEg bFQ2eG9zeGxSZDBZMDV0TVV2SDVManI4QQotPiBzc2gtZWQyNTUxOSBoa2J0dmcg
d3NnSXpMRzU0QjBBL0c4SGw5Znl6d3hRdWxvbHdXZCtIeVdnU1F6MFVVQQpiQjVX WmkxUSs4MGI4Y1BrZjdSSDRQMEtGbC9LNWlDdDBKbFI4NXdjN21BS2lIRQpUZVhL
TSsycGZqMVNWajZHcFkyN2JwY2RqcGRlNitRWXgxWnN5TzlpU1lRCi0+IHNzaC1l c0orRXNvbGFUbE1UZlBGc3h5N01Fekh2Q3B2WjI0WXpkRWpqM1hnCi0+IHNzaC1l
ZDI1NTE5IFpiTEpXQSB3VmFwR2ZqR2p4OXlpSnQrbExqTktkaEJ4emxLM2ZZbGdx ZDI1NTE5IGV0MnpwUSA0TWlIWW1oRzgrYzJUK29XbXVyd2JETHpLUFVLeG4rRUY1
U0drOWtxUGprClgyYnd1M1NQem1rZkxwUk5tVXBLNGVDMFVjNjc5Lys4N0RsajZN bmV1bUZPaDBNCnI0cllLZmRFMEZDWTFRV2QxL25uV1RtOHBMZVhrOXFyR0NGbjk4
eG9LeEEKLT4gc3NoLWVkMjU1MTkgWk5xSW9nIFl3QUlPNnVHNXNwQ2sxRUEycFda QWwvbDgKLT4gc3NoLWVkMjU1MTkgWmJMSldBIGNiK2hGRkhZRlU3SFpURWNLY3lL
TkJsUmx0dCtRdnRVRVAzY3pPbm1LM0EKbVZDMHBSOFBiMFVQbkxHOGpkQjhrbDRJ VisrSW01V1lXQU8yUGN5MENNaEZwVU0KbnNGd2Y4TDZKdmFIQ21NWlZZVGQ1ZEFw
YUN0M2JPOW1PbjVtQURaUnVFbwotPiBzc2gtZWQyNTUxOSBxTGpxeVEgUXc5TUxn MyszQ0VLOWxiSkdrWFdGWUlkOAotPiBzc2gtZWQyNTUxOSBaTnFJb2cgZ2dnRHkr
YXk2ai9EbHdVeFVsUk96bHZIRFdlcDFqYkxLQ3FJaFBQVG93bwpTSFJ5dmJiN2tt UEs5S3FJRkpBLzZLRyt6RmdBeUcvTjJGTmhoci8xNXord3F5OAplZXRUQTF5MUtT
TVlLUlBhb3VmSG8zVHNYdC9HVjcwN3JUVVVWN3BFUkhvCi0+IHNzaC1lZDI1NTE5 RG1uVmZOOENzVVZqWUFsdDFXRm93dy9OYmtVSDZTUDV3Ci0+IHNzaC1lZDI1NTE5
IEJhUWxSZyAxYkNsekljV0s1ZWR2eVZnSk9Oc2QvWjE2a2dMaldDYzJRU0FWUVE0 IHFManF5USA5SUF1MW85T2dZNXY2cFBwOC9Wb1R6MSs5VGVOOTExUnNaM3pwci9l
Z0FvCnk5UlhrT0ZaK3FXTThVY0RKZlE0d0FTajJLRCtSNWdvWjd5V3hZNEg4dUkK N2pRCk1tYWRnSlAwbUNiMWdmRU0wZk5VOHZmVU5uZDlRSlJJM1pHR3VxTTNHN0kK
LT4gc3NoLWVkMjU1MTkgcytxUmZnIHA5cGpXWlMvTlVreDNremhCa1FDUlFVYk45 LT4gc3NoLWVkMjU1MTkgQmFRbFJnIExWTm0xU0djWW9XL3ova003ZVBMTTFIS1FR
OHhjaUhYTWZVa3dySzNLeW8KNXZnZzFPNC8zMExuMG4yUTJFMDgxTFdGdDZ6VVl1 S0xYckNMRFJhZGVXM1haeDAKeTVoSC92bnhRdG93RnV4akxVRHRuVEc4Y2N3cmta
WEFGUC9zNVgrd2RRdwotPiBzc2gtZWQyNTUxOSA2MkpjY0EgMG51elJWRWRDNzRM UFJrTHZtU3A5RjFGdwotPiBzc2gtZWQyNTUxOSBzK3FSZmcgaGJNcUc4bFZHK3Bl
SERza2RiNFBoOHc1eCt0SWtmUy90dGl0VEd6QTJENApodnNBM1FkUlZ2ZjB6b1Np cnVZV0dPWkFOTndSMU1zNlAweXZsUkZtSk1XQUoxdwpWak02bTJVWjNNMXZoenJq
QWNXdjVoNFlsa0NOQWp6TUw2TVQrU3VNRlVZCi0+IHNzaC1lZDI1NTE5IC9oeC9k RFN0UzRvdk0xT2VzazFKcysvYk9HejYrLzRvCi0+IHNzaC1lZDI1NTE5IDYySmNj
QSBxdlhXM3Rqb3J4YjVDUzdhUUVYQlFvSTJjZXA5MHBYY0NXWVR0VzllR2hzCkU2 QSA4KzVSYkxEUW5jaithdUNvSVpjdDJGZm90Q1IyWnBtbTZnTWNsY01pUkQwCkRa
K2xCY2tGeEJjK1dMYkhCZ29pR3EzYndWUXF4bWorNC83d1E3U3luMFUKLT4gc3No NHRHenFIS050dXVWcWdzaElkemU4enEyUmkwU0tSMENJWHFYMlg0L0UKLT4gc3No
LWVkMjU1MTkgV3pMR0hBIGg1MjIydFM3YlM3aWVFR0h4TytwRWxYWTVkTXN4VkdW LWVkMjU1MTkgL2h4L2RBIDVhY2hCcitGVjFueUsrTHpNNmEzeDFTUFdYeGZ2d1ox
TnJ0bXQ0WTduQUEKemtad2lsTTlPUEtUaVpFLzNPVFhqd3VpeWJWbDFyayt2VVhy czE2TUFIS0NzVFkKU0lFcGJiQmQrMU1iYlhtNWVFZ2VZM09jOTBwUWRDdlNOKzc4
Q0FSb01rRQotPiBzc2gtZWQyNTUxOSBISi9KN0EgTkdKZUx2U1NTODZzTlpJb2xT VHVEeC8wdwotPiBzc2gtZWQyNTUxOSBXekxHSEEgNlhBMHVJTTFuZHgxN3RqYkV0
VFptQ3hWOS9BMCsyZXdsM3ErMXhtaHlFQQoyUnp3RW81VUh6OVRQcGhJOXYxNXRR SzB2elhYcm9BWmszNjRIUzhCbEpiWktFawpka1ZpK0pCMnAxTUE4UzhHeXhxcjRi
NHNGT3ZIU2ZQb2c5aEg0UmhRcG13Ci0+IHNzaC1lZDI1NTE5IE9FcU1zZyBLMi9r djNRdUxVeW90SUFENjh0UVJyeDBnCi0+IHNzaC1lZDI1NTE5IEhKL0o3QSBhNno1
bmFyTnBCU1lsdUpDWTJsd3ltRzAxZmw5eDNqVUtjMkR0OGF1dVRjCndrNmVHcmYy QmZWMFJ1OEdmZVRzd05qWktUM3BXaWtvV3FpckllV29hM0VWalJZClN0NVFMTDlu
c0lQOFM5SjBjN1ZqZXk1Vkk3RzA0b3JtaWZrdDBmdmFrYXcKLT4gc3NoLWVkMjU1 Z01TaVp3ZDRURGRqSk5FazBBVXJuTzlzdFI4bWE3cUowYmsKLT4gc3NoLWVkMjU1
MTkgL0VKWHZnIEV6eVNrNEZvVWhPMXppeFpmSEt1Y2NqcmtUOXAxQ1lOWVdtcnlm MTkgT0VxTXNnIHBBaHl2U2hKMVJpc1FDdDRMVnRacHZ6SUh4TGwxYm9Sejh5S3FL
R3B3VFEKVXJJRWlmOFVHZ3hyWWhLZE03VlNlM0M4ejFDYjM1b1c0YWhMMVcrRXlH RVBheUUKQUNRZDZtN1dBcUI1TFVpenI3R0M5TC9zY3B4OEFBMXhLQjMyYmVseWEv
bwotPiBYMjU1MTkgUkRPY2JrSGZYeGNVWldVbTAzbkdtbHdUS1hoZXg2R2JEOGtC bwotPiBzc2gtZWQyNTUxOSAvRUpYdmcgZ0M3ZVdBZVlOOFNEbmFwYVcvMGtETTdy
ckZSOWV3TQpGejNQOUlxb05oWE9hRWdjbzI2a0NKVkpHMG1PMWlMWVZpYkVQNlpx QXZmSy9qZFVKQkROdFRVak4xSQpRREliRFFjMTl6ak45ckdEdnpReEJPS3RSbXB4
c2xRCi0+ICwlLDsrbWYtZ3JlYXNlIE8mcz1jaywgeiJbOE9FeyAjXFl4Ugo1c2VM R0JxdUUxZ2wxSkUwQk5NCi0+IFgyNTUxOSBqYW5sdkVBcUJiUHltVy9mT0hYbzJ4
THdsOFlhODVMV3JsYzY3QU5Hb1BJTHBWNFEvalRHN3lXQlBBZFVvQXRIdXpXYVpU bW11dmwvUGFlVkV1WlpFQ2Y1UHpNCm1OQ09yOVRSNnIxeXY0N2ltOEt3OVVYRTM2
b0NLRG40WWhMQ2hDCnZyS1d6SGxGekIzWUs2Uk5XSFRscTIrTTEwNzJKMExGcG5m bHV4dkJOaUFrUFhydmdTSFEKLT4gZ296LWdyZWFzZSBbcyA6IUVJKiBSYi04ClB1
UWR0MWtBNnk4bDBYYStVQzFwZDlWRzRDNXJVZm0KajVrCi0tLSBkQ044Z3A5R0dt QjgzNTBMM3o1cER5RWhQa1F4YmFEOXNzQUZyOTU2SXRzYmtTODdKd1djZ3NUagot
S0htaUZaSzdPOTNCcXZrSWFVVHlTZk0zejBuT21yQzFBCo6rc9fznstf3eXBRUA8 LS0gRGN4Y2ZyV1g4YnFaM0JTazNZSFNOQVlzQWViU1R1ZUVpdjB0ZmNUeThvRQrn
73MZAYqSnJ5wVMrYrwGfT9lXvKbHCOvkgjUI6Ieo0nuw+aZpXoV3t9HfZv62UEll KRRdOMs11eAfh0452NX5E0nDyNXe/Bn3kStg7jBDKRo+JxFw4xTwgT9XeyMwzonH
ZZVu+ieRCZqOOqZKKZ3TCP24vdXun8Tu+3YK8fyn88QSRH/0ZMnqI9FXbtsUhsF8 bci/yoXC0hSJNiGvMCu9qbnEZakb7nzQfn8KJY9+4ptjRI5zxnGRWUEDrHjNXA22
2o7m7Fn48B0nVKy16HZyBsksknAuZCkfS/JOkgI= UGpm6PGdBRpktySXA4wFTJL1nWxtIIRvZ/j3Njc3O78ggjhW3QtBc0VJ
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----