initial commit

This commit is contained in:
Robert Perce 2025-08-15 16:41:33 -05:00
commit 726218542a
7 changed files with 537 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
result

88
Taskfile Executable file
View file

@ -0,0 +1,88 @@
#!/usr/bin/env bash
set -euo pipefail
TMPDIR=$(pwd)/tmp
export TMPDIR
help() { declare -F | awk -v ORS=" " '{ print $3 }'; echo; }
build() {
nix build .#"$1"
}
dump() {
build "$@"
sudo cp -f result/vzdump* /mnt/share/proxmox/dump/
}
get-ip() {
file="$1"
if [[ "$file" = "proxmox" ]]; then
echo 192.168.0.3
return
elif [[ "$file" != *.nix ]]; then
file="vm-$1.nix"
fi
grep ip4 "$file" | grep -Po "[0-9]+(\.[0-9]+){3}"
}
deploy() {
ip=$(get-ip "$1")
nix-shell -p '(nixos{}).nixos-rebuild' --run \
'nixos-rebuild switch --flake .#'"$1"' --target-host admin@"'"$ip"'" --use-remote-sudo'
}
ssh() {
command "${2:-mosh}" admin@"$(get-ip "$1")"
}
_modrinth() {
slug="$1"
mcversion=$(grep fabricServers vm-majcraft.nix | grep -Po "[0-9_]+" | head -n1)
mcversion=${mcversion//_/.}
curl -sSL "https://api.modrinth.com/v2/project/${slug}/version?loaders=fabric&game_versions=$mcversion"
}
majcraft-update() {
mcversion=$(grep fabricServers vm-majcraft.nix | grep -Po "[0-9_]+" | head -n1)
mcversion=${mcversion//_/.}
versionWithoutPatch=${mcversion%.[0-9]}
mods=(
Jrmoreqs AdvancedBackups
r0v8vy1s Alternate_Current
sml2FMaA AntiXray
lhGA9TYQ Architectury_API
MBAkmtvl Balm
Y8o1j1Sf Better_Fabric_Console
e0M1UDsY Collective
P7dR8mSH Fabric_API
uXXizFIs FerriteCore
nvQzSEkH Jade
jzTUm9hE Just_Mob_Heads
YdVBZMNR Just_Player_Heads
7uh75ruZ KleeSlabs
fQEb0iXm Krypton
gvQqBUqZ Lithium
nmDcB62a ModernFix
qQyHxfxd No_Chat_Reports
34T8oVNY Pl3xMap
zQhsx8KF Servux
G9rHXWug Sessility
9eGKb6K1 Simple_Voice_Chat
doqSKB0e Styled_Chat
DQIfKUHf Styled_Player_List
nxrXbh5K View_Distance_Fix
)
for (( i=0; i<${#mods[*]}; i+=2 )); do
slug="${mods[$i]}"
name="${mods[$i+1]}"
uri="https://api.modrinth.com/v2/project/${slug}/version?loaders=fabric&game_versions=$mcversion"
hash=$(curl -sSL "$uri" \
| jq -r '.[] | select(.loaders[] | contains("fabric"))' \
| jq -r 'select(.game_versions[] | . == ("'"$mcversion"'", "'"$versionWithoutPatch"'"))' \
| jq -r --slurp 'first | .id')
>&2 echo "$name ($mcversion $versionWithoutPatch) $uri $hash"
echo "$name = pkgs.$(nix run github:Infinidoge/nix-minecraft#nix-modrinth-prefetch -- "$hash");"
done
}
"$@"

113
flake.lock generated Normal file
View file

@ -0,0 +1,113 @@
{
"nodes": {
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1733328505,
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nix-minecraft": {
"inputs": {
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1748051893,
"narHash": "sha256-KV6bgVHPzb9ymVk9WDRX1lkkeoZETMbS/MyPpIOUWVo=",
"owner": "Infinidoge",
"repo": "nix-minecraft",
"rev": "a600d058c19e1668db6ba759ecc4cfd154079ab5",
"type": "github"
},
"original": {
"owner": "Infinidoge",
"repo": "nix-minecraft",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1742889210,
"narHash": "sha256-hw63HnwnqU3ZQfsMclLhMvOezpM7RSB0dMAtD5/sOiw=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "698214a32beb4f4c8e3942372c694f40848b360d",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1747862697,
"narHash": "sha256-U4HaNZ1W26cbOVm0Eb5OdGSnfQVWQKbLSPrSSa78KC0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2baa12ff69913392faf0ace833bc54bba297ea95",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.11",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nix-minecraft": "nix-minecraft",
"nixpkgs": "nixpkgs_2"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

30
flake.nix Normal file
View file

@ -0,0 +1,30 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
nix-minecraft.url = "github:Infinidoge/nix-minecraft";
};
outputs = { self, nixpkgs, ... }@inputs:
let
system = "x86_64-linux";
nixos = path: nixpkgs.lib.nixosSystem {
specialArgs = { inherit system inputs; };
modules = [
"${nixpkgs}/nixos/modules/virtualisation/proxmox-image.nix"
{ nixpkgs.hostPlatform = "${system}"; }
path
];
};
image = name: self.nixosConfigurations.${name}.config.system.build.VMA;
in {
nixosConfigurations = {
majcraft = nixos ./vm-majcraft.nix;
homelab = nixos ./vm-homelab.nix;
};
packages.${system} = {
majcraft = image "majcraft";
homelab = image "homelab";
};
};
}

130
vm-base.nix Normal file
View file

@ -0,0 +1,130 @@
{ config, pkgs, modulesPath, lib, ... }:
{
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
(modulesPath + "/virtualisation/proxmox-image.nix")
];
options.my.vm = {
name = lib.mkOption {
type = lib.types.nonEmptyStr;
example = "hello01";
description = "Used for vm name and hostname";
};
iface = lib.mkOption {
type = lib.types.nonEmptyStr;
default = "ens18";
example = "ens18";
description = "Interface on which static IP is bound";
};
ip4 = lib.mkOption {
type = lib.types.nonEmptyStr;
example = "192.168.0.42";
description = "Static IP for this VM";
};
};
config = let cfg = config.my.vm; in {
proxmox.qemuConf.name = cfg.name;
# virtualisation.diskSize = 10240; # MiB
proxmox.qemuConf.diskSize = "auto";
# Enable QEMU Guest for Proxmox
services.qemuGuest.enable = lib.mkDefault true;
# Use the boot drive for grub
boot.loader.grub.enable = lib.mkDefault true;
boot.loader.grub.devices = [ "nodev" ];
boot.growPartition = lib.mkDefault true;
# Allow remote updates with flakes and non-root users
nix.settings.trusted-users = [ "root" "@wheel" ];
nix.settings.experimental-features = [ "nix-command" "flakes" ];
# Enable mDNS for `hostname.local` addresses
services.avahi.enable = true;
services.avahi.nssmdns4 = true;
services.avahi.publish = {
enable = true;
addresses = true;
};
# Some sane packages we need on every system
environment.systemPackages = with pkgs; [
vim
git # for pulling nix flakes
];
# doing it here opens udp port _and_ installs package
programs.mosh.enable = true;
# Don't ask for passwords
security.sudo.wheelNeedsPassword = false;
# Don't use cloud-init
services.cloud-init.network.enable = lib.mkForce false;
networking = {
hostName = cfg.name;
nameservers = ["192.168.0.1"];
interfaces.${cfg.iface} = {
ipv4.addresses = [{
address = cfg.ip4;
prefixLength = 24;
}];
};
defaultGateway = {
address = "192.168.0.1";
interface = "${cfg.iface}";
};
defaultGateway6 = {
address = "fe80::1";
interface = "${cfg.iface}";
};
};
# Enable ssh
services.openssh = {
enable = true;
settings.PasswordAuthentication = false;
settings.KbdInteractiveAuthentication = false;
};
programs.ssh.startAgent = true;
# Enable prometheus metrics export
networking.firewall.allowedTCPPorts = [ 9100 ];
services.prometheus.exporters.node = {
enable = true;
port = 9100;
enabledCollectors = ["systemd"];
};
# Add an admin user
users.users.admin = {
isNormalUser = true;
description = "Robert Perce";
extraGroups = [ "wheel" ];
};
users.users.admin.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFTDd1G3ufe8lCEWMbMN+q83WrrS92+qrI2tOaMtit+q robert@aether"
];
# Default filesystem
fileSystems."/" = lib.mkDefault {
device = "/dev/disk/by-label/nixos";
autoResize = true;
fsType = "ext4";
};
fileSystems."/mnt/nfs" = lib.mkDefault {
device = "192.168.0.3:/";
fsType = "nfs";
};
system.stateVersion = lib.mkDefault "24.11";
};
}

83
vm-homelab.nix Normal file
View file

@ -0,0 +1,83 @@
{ inputs, pkgs, ... }:
{
imports = [
./vm-base.nix
];
config = {
my.vm = {
name = "lab01";
ip4 = "192.168.0.5";
};
# environment.systemPackages = with pkgs; [
# ];
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.caddy = {
enable = true;
virtualHosts = {
"feed.rperce.net".extraConfig = ''
reverse_proxy http://192.168.0.5:8080
'';
"barkeep.dukeceph.xyz".extraConfig = ''
reverse_proxy http://192.168.0.2:8000
'';
"barkeep.rperce.net".extraConfig = ''
reverse_proxy http://192.168.0.2:8000
'';
"minecraft.dukeceph.xyz".extraConfig = ''
reverse_proxy http://192.168.0.4:8080
'';
"immich.rperce.net".extraConfig = ''
reverse_proxy http://192.168.0.2:2283
'';
"metrics.rperce.net".extraConfig = ''
reverse_proxy http://192.168.0.2:3000
'';
"jellyfin.rperce.net".extraConfig = ''
reverse_proxy http://192.168.0.2:8096
'';
"forge.rperce.net".extraConfig = ''
reverse_proxy http://192.168.0.5:3333
'';
};
};
services.miniflux = {
enable = true;
adminCredentialsFile = "/mnt/nfs/miniflux/admin-credentials";
config = {
LISTEN_ADDR = "0.0.0.0:8080";
};
};
services.immich = {
enable = true;
host = "0.0.0.0";
port = 2293;
};
services.forgejo = {
enable = true;
database.type = "postgres";
lfs.enable = true;
settings = {
server = {
DOMAIN = "forge.rperce.net";
ROOT_URL = "https://forge.rperce.net/";
HTTP_PORT = 3333;
};
service.DISABLE_REGISTRATION = true;
actions = {
ENABLED = true;
DEFAULT_ACTIONS_URL = "github";
};
mailer.ENABLED = false;
};
};
};
}

92
vm-majcraft.nix Normal file
View file

@ -0,0 +1,92 @@
{ inputs, pkgs, ... }:
{
imports = [
./vm-base.nix
inputs.nix-minecraft.nixosModules.minecraft-servers
];
config = {
my.vm = {
name = "craft01";
ip4 = "192.168.0.4";
};
environment.systemPackages = with pkgs; [
tmux # interactive session management
# ferium # interactive mod updates
];
nixpkgs.config.allowUnfree = true;
nixpkgs.overlays = [ inputs.nix-minecraft.overlay ];
users.users.admin = {
extraGroups = [ "minecraft" ];
};
services.minecraft-servers = {
enable = true;
eula = true;
dataDir = "/mnt/nfs/minecraft";
};
# for dynmap
networking.firewall.allowedTCPPorts = [ 8080 ];
services.minecraft-servers.servers.majcraft = {
managementSystem = {
tmux.enable = false;
systemd-socket.enable = true;
};
enable = true;
package = pkgs.fabricServers.fabric-1_21_4.override { loaderVersion = "0.16.14"; };
autoStart = true;
openFirewall = true;
restart = "no";
enableReload = true;
whitelist = {
DukeCephalopod = "86743f88-3af8-4b52-bc77-23a43266c2ab";
MordeeKaaKh = "4eb901ec-db3c-416f-93de-ead48f34c803";
Cirichan = "9022affa-6498-483a-83c8-fba8fb2bc0d6";
};
serverProperties = {
allow-flight=true;
difficulty="hard";
level-seed="2786386421968123439";
max-players="5";
motd=":happywiggle:";
enforce-whitelist=true;
white-list=true;
};
symlinks = {
mods = pkgs.linkFarmFromDrvs "mods" (builtins.attrValues {
AdvancedBackups = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/Jrmoreqs/versions/g1B8uoKN/AdvancedBackups-fabric-1.21.2-3.7.1.jar"; sha512 = "31f4106ca36c0512857351ce1d025e0ca60aad4af274e83a8f286121d56a010cb9cd3a35f72983cfa8b54476bd62d16076f250f257283294053bd74bea6b17c4"; };
Alternate_Current = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/r0v8vy1s/versions/DwfiGUVU/alternate-current-mc1.21.2-1.9.1.jar"; sha512 = "8ed44291a8aed3e1c9750cfce85e0de679daeff7c3b1bc8f6329b41ba4570442750b8039d2d5c79c32655fc9372ea35843c60805438d33888b30e28731c39137"; };
AntiXray = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/sml2FMaA/versions/jihdVQXH/antixray-fabric-1.4.10%2B1.21.4.jar"; sha512 = "d61a5790a65b45cf65b062ea57812e1137595184a6426f9bb9377b91e73a1f7a0798b84be1e2c30230fbb74e1fdb6f35850b3c54b09c94bfa37799b4fc67d7f6"; };
Architectury_API = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/lhGA9TYQ/versions/73nlw3WM/architectury-15.0.3-fabric.jar"; sha512 = "6acc7cfccfc6e93fd8c1895fb2c489cbabd27265f38f7cbad98ddaab2cb2e6d1601633bd12cf26fc0bb100a87949ee06b872f333cf7b8490cccc0082ac586dcb"; };
Balm = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/MBAkmtvl/versions/urF0zb9k/balm-fabric-1.21.4-21.4.33.jar"; sha512 = "55f4bfc262b2f9b96fd14a21393531c1ea9ef8a954e5dd6acd7ce200b6918d0f49e96ce7c4fd2cf05ff65a57c06275f75a7f5606e5516995a5054f995f5518db"; };
Better_Fabric_Console = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/Y8o1j1Sf/versions/3d1g5aTY/better-fabric-console-mc1.21.4-1.2.2.jar"; sha512 = "aa7ea5e6fad06927462655331985e58d270bf2f6ac31a9c685830e8d4249c6a3de51f2a2e63ddef150432040448926c3238d3bab4722a26733c5e7db64359563"; };
Collective = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/e0M1UDsY/versions/I5jY2gQ2/collective-1.21.4-8.3.jar"; sha512 = "95c18b55a631bfdcbc501c17238f36c1f284d90a866f498dbf2b77ce7b9dcb0260cba0143a16dcbf254660710ea8fdbd8948cac94139e660bf25581b49fa2337"; };
Fabric_API = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/P7dR8mSH/versions/bQZpGIz0/fabric-api-0.119.2%2B1.21.4.jar"; sha512 = "bb8de90d5d1165ecc17a620ec24ce6946f578e1d834ddc49f85c2816a0c3ba954ec37e64f625a2f496d35ac1db85b495f978a402a62bbfcc561795de3098b5c9"; };
FerriteCore = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/uXXizFIs/versions/IPM0JlHd/ferritecore-7.1.1-fabric.jar"; sha512 = "f41dc9e8b28327a1e29b14667cb42ae5e7e17bcfa4495260f6f851a80d4b08d98a30d5c52b110007ee325f02dac7431e3fad4560c6840af0bf347afad48c5aac"; };
Jade = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/nvQzSEkH/versions/sSHUBFoq/Jade-1.21.4-Fabric-17.2.2.jar"; sha512 = "dbe2ce335170c7a7079595c6341188ef07f54704faab7e3919a7c24130d3b25f321425c5f28107ea706f8d7e47e1d49147882ab05c35cbe6af7ac9d371ca68e7"; };
Just_Mob_Heads = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/jzTUm9hE/versions/aQhtp5W0/justmobheads-1.21.4-8.5.jar"; sha512 = "8b6a0660d5ea9a38b87aa65a9e66a6bd1a0dbf74293d7fd3980d1c882dcf14a1378f9df98cba34f25ae7dccb89d7b389501ae82ce0e79814d2ce90c74963efeb"; };
Just_Player_Heads = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/YdVBZMNR/versions/c9yLWM9w/justplayerheads-1.21.4-4.2.jar"; sha512 = "9c1a6163e12d348de067c1a254d0460ef56f63150407b826e5cf4cc656c9e59f03e29f15e5caf53e7d7354a06afe6e6d2894f402b89c032e4d239fa184232ecf"; };
KleeSlabs = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/7uh75ruZ/versions/kmg19jRW/kleeslabs-fabric-1.21.4-21.4.5.jar"; sha512 = "8799eb50e850c7587c235c03ad685423666e7a1659f11b3e1f5a5d52bf4809d486b9f9565c742dac2bf0a9dff53ac2ed90d92e62b92860629e4635b97f40299b"; };
Krypton = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/fQEb0iXm/versions/Acz3ttTp/krypton-0.2.8.jar"; sha512 = "5f8cf96c79bfd4d893f1d70da582e62026bed36af49a7fa7b1e00fb6efb28d9ad6a1eec147020496b4fe38693d33fe6bfcd1eebbd93475612ee44290c2483784"; };
Lithium = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/gvQqBUqZ/versions/u8pHPXJl/lithium-fabric-0.15.3%2Bmc1.21.4.jar"; sha512 = "b8b541c0e968571c8972872b342e34b92573bc9210d455dc1349589f30a67a90d930dbfd99b176ab9b110350ceb53e11118378dc13a35e83a9090826627bdac0"; };
ModernFix = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/nmDcB62a/versions/ZGxQddYr/modernfix-fabric-5.20.3%2Bmc1.21.4.jar"; sha512 = "ae49114c92a048c9ce79e197fc4df028e186cf13546e710f72247382fa8076f0b70d6aa3224951f4a36c886ca236f099a011f20b021a2b0d1a75c631da4d7d52"; };
No_Chat_Reports = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/qQyHxfxd/versions/9xt05630/NoChatReports-FABRIC-1.21.4-v2.11.0.jar"; sha512 = "d343b05c8e50f1de15791ff622ad44eeca6cdcb21e960a267a17d71506c61ca79b1c824167779e44d778ca18dcbdebe594ff234fbe355b68d25cdb5b6afd6e4f"; };
Pl3xMap = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/34T8oVNY/versions/Mml961m8/Pl3xMap-1.21.4-526.jar"; sha512 = "20242fd540b1fff6780267e5765ef4518e47b13a967ec93fa0628168ef92329939a3d650eeaf86d5c523d42fb2048df8c8754a5f050db29ad3dad235dae7ce80"; };
Servux = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/zQhsx8KF/versions/QRj9tmeQ/servux-fabric-1.21.4-0.5.3.jar"; sha512 = "7f4170b3cecf05551a15a5aeb8bd7693201d3322775559afb270cb9756261f237ba87aec889fc8a8c74f9b76971deba9fc14b9c3e9c3201bf819a188cdd6e252"; };
Sessility = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/G9rHXWug/versions/t6DOfM7s/sessility-fabric-mod-0.7.jar"; sha512 = "173f060e10486d4cba3190569595c310304a8a535293448ff8ce026a1577912dddbdffd6192a66839b27562e2e8cf249abeb1a7335250c52b40e2b461a294826"; };
Simple_Voice_Chat = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/9eGKb6K1/versions/JRSB7SDd/voicechat-fabric-1.21.4-2.5.30.jar"; sha512 = "384f42959068da76128a02afe4ca754f47a85e248a3d1a2f0f5df38920110d9f577f98ef979f3866b36ad5038c4d42e2e5ff2391aa3d5c40a196456df951d084"; };
Styled_Chat = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/doqSKB0e/versions/AQ0JW3y8/styled-chat-2.7.2%2B1.21.3.jar"; sha512 = "bf4c4f1996d6f4fc4f74a2d2648fd2ecaf7048d627fe352c0bcd7f389460702503722c043f0dabfca4d5501516647dba921739bbc4fb37fa0bc1fa4c228fc476"; };
Styled_Player_List = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/DQIfKUHf/versions/gyvLcVPF/styledplayerlist-3.6.0%2B1.21.2.jar"; sha512 = "aa3c18646d0b34f56ae0a3ee24bfbb6026f0c6ce99217586cea02a5218946fc467d7ddd38960dd24e7b392ad0511f30b85cbeee57c00fe4e8bb8850f3d5658dc"; };
View_Distance_Fix = pkgs.fetchurl { url = "https://cdn.modrinth.com/data/nxrXbh5K/versions/JHg6ZYop/viewdistancefix-fabric-1.21.4-1.0.2.jar"; sha512 = "803b4d83b4c09c231b66c3f5fd068b4f55491c743207455fda8eb175a70ab51b5c6f09185d589555829906b44da1843e8ac722ea39919c4cc2a15dc4d5493b13"; };
});
};
};
};
}