format
This commit is contained in:
66
flake.nix
66
flake.nix
@@ -63,9 +63,25 @@
|
|||||||
# inputs.nixpkgs.follows = "nixpkgs-unstable";
|
# inputs.nixpkgs.follows = "nixpkgs-unstable";
|
||||||
#};
|
#};
|
||||||
};
|
};
|
||||||
outputs = { self, nur, nixpkgs, nixos-hardware, nixos-wsl, nixpkgs-unstable
|
outputs =
|
||||||
, agenix, home-manager, home-manager-unstable, nix-colors, nixos-cosmic
|
{ self
|
||||||
, nixvim, nixos-generators, stylix, disko, flake-utils, ... }@inputs:
|
, nur
|
||||||
|
, nixpkgs
|
||||||
|
, nixos-hardware
|
||||||
|
, nixos-wsl
|
||||||
|
, nixpkgs-unstable
|
||||||
|
, agenix
|
||||||
|
, home-manager
|
||||||
|
, home-manager-unstable
|
||||||
|
, nix-colors
|
||||||
|
, nixos-cosmic
|
||||||
|
, nixvim
|
||||||
|
, nixos-generators
|
||||||
|
, stylix
|
||||||
|
, disko
|
||||||
|
, flake-utils
|
||||||
|
, ...
|
||||||
|
}@inputs:
|
||||||
let
|
let
|
||||||
inherit (self) outputs;
|
inherit (self) outputs;
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
@@ -82,30 +98,41 @@
|
|||||||
defaultModules = [ ./modules agenix.nixosModules.default overlays ];
|
defaultModules = [ ./modules agenix.nixosModules.default overlays ];
|
||||||
merge = list:
|
merge = list:
|
||||||
builtins.foldl' (acc: elem: nixpkgs.lib.recursiveUpdate acc elem) { }
|
builtins.foldl' (acc: elem: nixpkgs.lib.recursiveUpdate acc elem) { }
|
||||||
list;
|
list;
|
||||||
# helper function to create a machine
|
# helper function to create a machine
|
||||||
mkHost = { modules, specialArgs ? {
|
mkHost =
|
||||||
pkgsVersion = nixpkgs-unstable;
|
{ modules
|
||||||
home-manager-version = home-manager-unstable;
|
, specialArgs ? {
|
||||||
}, system ? "x86_64-linux", minimal ? false, graphical ? true }:
|
pkgsVersion = nixpkgs-unstable;
|
||||||
|
home-manager-version = home-manager-unstable;
|
||||||
|
}
|
||||||
|
, system ? "x86_64-linux"
|
||||||
|
, minimal ? false
|
||||||
|
, graphical ? true
|
||||||
|
}:
|
||||||
let lib = specialArgs.pkgsVersion.lib;
|
let lib = specialArgs.pkgsVersion.lib;
|
||||||
in specialArgs.pkgsVersion.lib.nixosSystem {
|
in specialArgs.pkgsVersion.lib.nixosSystem {
|
||||||
inherit system;
|
inherit system;
|
||||||
modules = modules ++ defaultModules ++ lib.lists.optionals (!minimal)
|
modules = modules ++ defaultModules ++ lib.lists.optionals (!minimal)
|
||||||
[ specialArgs.home-manager-version.nixosModules.home-manager ]
|
[ specialArgs.home-manager-version.nixosModules.home-manager ]
|
||||||
++ lib.lists.optionals (!minimal && graphical) [
|
++ lib.lists.optionals (!minimal && graphical) [
|
||||||
./modules/graphical
|
./modules/graphical
|
||||||
stylix.nixosModules.stylix
|
stylix.nixosModules.stylix
|
||||||
./modules/graphical/stylix.nix
|
./modules/graphical/stylix.nix
|
||||||
nixos-cosmic.nixosModules.default
|
nixos-cosmic.nixosModules.default
|
||||||
./modules/graphical/cosmic.nix
|
./modules/graphical/cosmic.nix
|
||||||
];
|
];
|
||||||
specialArgs = specialArgs // { inherit inputs outputs; };
|
specialArgs = specialArgs // { inherit inputs outputs; };
|
||||||
};
|
};
|
||||||
mkStableServer = { modules, specialArgs ? {
|
mkStableServer =
|
||||||
pkgsVersion = nixpkgs;
|
{ modules
|
||||||
home-manager-version = home-manager;
|
, specialArgs ? {
|
||||||
}, system ? "x86_64-linux", minimal ? false }:
|
pkgsVersion = nixpkgs;
|
||||||
|
home-manager-version = home-manager;
|
||||||
|
}
|
||||||
|
, system ? "x86_64-linux"
|
||||||
|
, minimal ? false
|
||||||
|
}:
|
||||||
let lib = specialArgs.pkgsVersion.lib;
|
let lib = specialArgs.pkgsVersion.lib;
|
||||||
in specialArgs.pkgsVersion.lib.nixosSystem {
|
in specialArgs.pkgsVersion.lib.nixosSystem {
|
||||||
inherit system;
|
inherit system;
|
||||||
@@ -141,7 +168,8 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
overlays = import ./overlays.nix { inherit inputs; };
|
overlays = import ./overlays.nix { inherit inputs; };
|
||||||
|
|
||||||
nixosConfigurations = {
|
nixosConfigurations = {
|
||||||
|
|||||||
@@ -1,22 +1,24 @@
|
|||||||
{ osConfig, config, pkgs, inputs, lib, ... }: {
|
{ osConfig, config, pkgs, inputs, lib, ... }: {
|
||||||
config = lib.mkIf osConfig.custom.graphical.code.enable rec {
|
config = lib.mkIf osConfig.custom.graphical.code.enable rec {
|
||||||
home.activation.makeVSCodeConfigWritable = let
|
home.activation.makeVSCodeConfigWritable =
|
||||||
configDirName = {
|
let
|
||||||
"vscode" = "Code";
|
configDirName = {
|
||||||
"vscode-insiders" = "Code - Insiders";
|
"vscode" = "Code";
|
||||||
"vscodium" = "VSCodium";
|
"vscode-insiders" = "Code - Insiders";
|
||||||
}.${programs.vscode.package.pname};
|
"vscodium" = "VSCodium";
|
||||||
configPath =
|
}.${programs.vscode.package.pname};
|
||||||
"${config.xdg.configHome}/${configDirName}/User/settings.json";
|
configPath =
|
||||||
in {
|
"${config.xdg.configHome}/${configDirName}/User/settings.json";
|
||||||
after = [ "writeBoundary" ];
|
in
|
||||||
before = [ ];
|
{
|
||||||
data = ''
|
after = [ "writeBoundary" ];
|
||||||
if [ -e "$(readlink ${configPath})" ]; then
|
before = [ ];
|
||||||
install -m 0640 "$(readlink ${configPath})" ${configPath}
|
data = ''
|
||||||
fi
|
if [ -e "$(readlink ${configPath})" ]; then
|
||||||
'';
|
install -m 0640 "$(readlink ${configPath})" ${configPath}
|
||||||
};
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
programs.vscode = {
|
programs.vscode = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.vscodium;
|
package = pkgs.vscodium;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{ config, pkgs, inputs, ...}:
|
{ config, pkgs, inputs, ... }:
|
||||||
{
|
{
|
||||||
programs.direnv = {
|
programs.direnv = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableZshIntegration = true;
|
enableZshIntegration = true;
|
||||||
nix-direnv.enable = true;
|
nix-direnv.enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,9 +122,9 @@
|
|||||||
"pdfjs.enableScripting" = true;
|
"pdfjs.enableScripting" = true;
|
||||||
|
|
||||||
# copied these from a blog
|
# copied these from a blog
|
||||||
"browser.newtabpage.activity-stream.feeds.telemetry" = false;
|
"browser.newtabpage.activity-stream.feeds.telemetry" = false;
|
||||||
"browser.newtabpage.activity-stream.feeds.asrouterfeed" = false;
|
"browser.newtabpage.activity-stream.feeds.asrouterfeed" = false;
|
||||||
"browser.newtabpage.activity-stream.telemetry" = false;
|
"browser.newtabpage.activity-stream.telemetry" = false;
|
||||||
"browser.ping-centre.telemetry" = false;
|
"browser.ping-centre.telemetry" = false;
|
||||||
"devtools.onboarding.telemetry.logged" = false;
|
"devtools.onboarding.telemetry.logged" = false;
|
||||||
"accessibility.force_disabled" = 1;
|
"accessibility.force_disabled" = 1;
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ let
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
stylix = lib.mkIf osConfig.custom.graphical.stylix.enable {
|
stylix = lib.mkIf osConfig.custom.graphical.stylix.enable {
|
||||||
targets.firefox = {
|
targets.firefox = {
|
||||||
profileNames = [ "default" ];
|
profileNames = [ "default" ];
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ let
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
programs.floorp = {
|
programs.floorp = {
|
||||||
enable = true;
|
enable = true;
|
||||||
policies = {
|
policies = {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ config, pkgs, inputs, ...}:
|
{ config, pkgs, inputs, ... }:
|
||||||
{
|
{
|
||||||
home.file.".gitconfig" = {
|
home.file.".gitconfig" = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ let
|
|||||||
'';
|
'';
|
||||||
monitor1 = if isPc then "DP-1" else if isLaptop then "eDP-1" else "eDP-1";
|
monitor1 = if isPc then "DP-1" else if isLaptop then "eDP-1" else "eDP-1";
|
||||||
monitor2 = "HDMI-A-1";
|
monitor2 = "HDMI-A-1";
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
||||||
home.file.".config/hypr/hyprshade.toml".source =
|
home.file.".config/hypr/hyprshade.toml".source =
|
||||||
@@ -29,21 +30,22 @@ in {
|
|||||||
#
|
#
|
||||||
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Monitors/
|
# See https://wiki.hyprland.org/Configuring/Monitors/
|
||||||
monitor = if isPc then [
|
monitor =
|
||||||
"${monitor2},1920x1080@60,0x0,1"
|
if isPc then [
|
||||||
"${monitor1},2560x1440@144,1920x0,1"
|
"${monitor2},1920x1080@60,0x0,1"
|
||||||
"Unknown-1,disable"
|
"${monitor1},2560x1440@144,1920x0,1"
|
||||||
] else if isLaptop then [
|
"Unknown-1,disable"
|
||||||
# laptop
|
] else if isLaptop then [
|
||||||
"eDP-1,1920x1080@60,0x0,1"
|
# laptop
|
||||||
#"DP-3,1920x1080@60,1920x0,1"
|
"eDP-1,1920x1080@60,0x0,1"
|
||||||
#",preferred,auto,1,mirror,eDP-1"
|
#"DP-3,1920x1080@60,1920x0,1"
|
||||||
",preferred,auto,auto"
|
#",preferred,auto,1,mirror,eDP-1"
|
||||||
] else
|
|
||||||
[
|
|
||||||
# Default
|
|
||||||
",preferred,auto,auto"
|
",preferred,auto,auto"
|
||||||
];
|
] else
|
||||||
|
[
|
||||||
|
# Default
|
||||||
|
",preferred,auto,auto"
|
||||||
|
];
|
||||||
|
|
||||||
workspace =
|
workspace =
|
||||||
lib.lists.optionals (osConfig.networking.hostName == "kop-pc") [
|
lib.lists.optionals (osConfig.networking.hostName == "kop-pc") [
|
||||||
@@ -181,90 +183,92 @@ in {
|
|||||||
"$mainMod" = "SUPER";
|
"$mainMod" = "SUPER";
|
||||||
|
|
||||||
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
|
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
|
||||||
bind = let
|
bind =
|
||||||
rofi = "${pkgs.rofi-wayland}/bin/rofi";
|
let
|
||||||
kitty = "${pkgs.kitty}/bin/kitty";
|
rofi = "${pkgs.rofi-wayland}/bin/rofi";
|
||||||
#dolphin = "${pkgs.dolphin}/bin/dolphin";
|
kitty = "${pkgs.kitty}/bin/kitty";
|
||||||
thunar = "${pkgs.xfce.thunar}/bin/thunar";
|
#dolphin = "${pkgs.dolphin}/bin/dolphin";
|
||||||
wl-copy = "${pkgs.wl-clipboard}/bin/wl-copy";
|
thunar = "${pkgs.xfce.thunar}/bin/thunar";
|
||||||
wl-paste = "${pkgs.wl-clipboard}/bin/wl-paste";
|
wl-copy = "${pkgs.wl-clipboard}/bin/wl-copy";
|
||||||
grim = "${pkgs.grim}/bin/grim";
|
wl-paste = "${pkgs.wl-clipboard}/bin/wl-paste";
|
||||||
slurp = "${pkgs.slurp}/bin/slurp";
|
grim = "${pkgs.grim}/bin/grim";
|
||||||
swww = "${pkgs.swww}/bin/swww";
|
slurp = "${pkgs.slurp}/bin/slurp";
|
||||||
pdfgrep = "${pkgs.pdfgrep}/bin/pdfgrep";
|
swww = "${pkgs.swww}/bin/swww";
|
||||||
brightnessctl = "${pkgs.brightnessctl}/bin/brightnessctl";
|
pdfgrep = "${pkgs.pdfgrep}/bin/pdfgrep";
|
||||||
#swaylock = "${pkgs.swaylock}/bin/swaylock";
|
brightnessctl = "${pkgs.brightnessctl}/bin/brightnessctl";
|
||||||
hyprlock = "${pkgs.hyprlock}/bin/hyprlock";
|
#swaylock = "${pkgs.swaylock}/bin/swaylock";
|
||||||
playerctl = "${pkgs.playerctl}/bin/playerctl";
|
hyprlock = "${pkgs.hyprlock}/bin/hyprlock";
|
||||||
in [
|
playerctl = "${pkgs.playerctl}/bin/playerctl";
|
||||||
"$mainMod, Q, exec, ${kitty}"
|
in
|
||||||
"$mainMod, C, killactive"
|
[
|
||||||
#"$mainMod, L, exec, ${swaylock} -f -c 000000"
|
"$mainMod, Q, exec, ${kitty}"
|
||||||
"$mainMod, L, exec, ${hyprlock}"
|
"$mainMod, C, killactive"
|
||||||
"$mainMod, M, exit,"
|
#"$mainMod, L, exec, ${swaylock} -f -c 000000"
|
||||||
"$mainMod, E, exec, ${thunar}"
|
"$mainMod, L, exec, ${hyprlock}"
|
||||||
"$mainMod, F, fullscreen"
|
"$mainMod, M, exit,"
|
||||||
"$mainMod, V, togglefloating"
|
"$mainMod, E, exec, ${thunar}"
|
||||||
"$mainMod, I, exec, ${rofi} -show drun -show-icons"
|
"$mainMod, F, fullscreen"
|
||||||
''
|
"$mainMod, V, togglefloating"
|
||||||
$mainMod, S, exec, cat ~/songs | shuf -n 1 | sed "s/^/b.p /g" | ${wl-copy}''
|
"$mainMod, I, exec, ${rofi} -show drun -show-icons"
|
||||||
"$mainMod, R, exec, ${swww} img $(ls -d /synced/default/dinge/Bg/* | shuf -n 1)"
|
''
|
||||||
"$mainMod, W, exec, ${swww} img ${config.stylix.image}"
|
$mainMod, S, exec, cat ~/songs | shuf -n 1 | sed "s/^/b.p /g" | ${wl-copy}''
|
||||||
" , Print, exec, ${grim} -g \"$(${slurp} -d)\" - | ${wl-copy}"
|
"$mainMod, R, exec, ${swww} img $(ls -d /synced/default/dinge/Bg/* | shuf -n 1)"
|
||||||
''
|
"$mainMod, W, exec, ${swww} img ${config.stylix.image}"
|
||||||
$mainMod, Print, exec, ${grim} -g "$(${slurp} -d)" /tmp/$(date +'%s_grim.png')''
|
" , Print, exec, ${grim} -g \"$(${slurp} -d)\" - | ${wl-copy}"
|
||||||
''
|
''
|
||||||
Shift_L, Print, exec, ${grim} -g "$(${slurp} -d)" ~/Pictures/$(date +'%s_grim.png')''
|
$mainMod, Print, exec, ${grim} -g "$(${slurp} -d)" /tmp/$(date +'%s_grim.png')''
|
||||||
"$mainMod, SPACE, exec, ${rofi} -modi drun -show drun -config ~/.config/rofi/rofidmenu.rasi"
|
''
|
||||||
" , XF86MonBrightnessUp, exec, ${brightnessctl} s +5%"
|
Shift_L, Print, exec, ${grim} -g "$(${slurp} -d)" ~/Pictures/$(date +'%s_grim.png')''
|
||||||
" , XF86MonBrightnessDown, exec, ${brightnessctl} s 5%-"
|
"$mainMod, SPACE, exec, ${rofi} -modi drun -show drun -config ~/.config/rofi/rofidmenu.rasi"
|
||||||
" , XF86AudioPlay, exec, ${playerctl} play-pause"
|
" , XF86MonBrightnessUp, exec, ${brightnessctl} s +5%"
|
||||||
" , XF86AudioNext, exec, ${playerctl} next"
|
" , XF86MonBrightnessDown, exec, ${brightnessctl} s 5%-"
|
||||||
" , XF86AudioPrev, exec, ${playerctl} previous"
|
" , XF86AudioPlay, exec, ${playerctl} play-pause"
|
||||||
"$mainMod, P, pseudo" # dwindle
|
" , XF86AudioNext, exec, ${playerctl} next"
|
||||||
"$mainMod, J, togglesplit" # dwindle
|
" , XF86AudioPrev, exec, ${playerctl} previous"
|
||||||
# Move focus with mainMod + arrow keys
|
"$mainMod, P, pseudo" # dwindle
|
||||||
"$mainMod, left, movefocus, l"
|
"$mainMod, J, togglesplit" # dwindle
|
||||||
"$mainMod, right, movefocus, r"
|
# Move focus with mainMod + arrow keys
|
||||||
"$mainMod, up, movefocus, u"
|
"$mainMod, left, movefocus, l"
|
||||||
"$mainMod, down, movefocus, d"
|
"$mainMod, right, movefocus, r"
|
||||||
"$mainMod SHIFT, left, resizeactive, -30 0"
|
"$mainMod, up, movefocus, u"
|
||||||
"$mainMod SHIFT, right, resizeactive, 30 0"
|
"$mainMod, down, movefocus, d"
|
||||||
"$mainMod SHIFT, up, resizeactive, 0 -30"
|
"$mainMod SHIFT, left, resizeactive, -30 0"
|
||||||
"$mainMod SHIFT, down, resizeactive, 0 30"
|
"$mainMod SHIFT, right, resizeactive, 30 0"
|
||||||
|
"$mainMod SHIFT, up, resizeactive, 0 -30"
|
||||||
|
"$mainMod SHIFT, down, resizeactive, 0 30"
|
||||||
|
|
||||||
|
|
||||||
# Switch workspaces with mainMod + [0-9]
|
# Switch workspaces with mainMod + [0-9]
|
||||||
"$mainMod, 1, workspace, 1"
|
"$mainMod, 1, workspace, 1"
|
||||||
"$mainMod, 2, workspace, 2"
|
"$mainMod, 2, workspace, 2"
|
||||||
"$mainMod, 3, workspace, 3"
|
"$mainMod, 3, workspace, 3"
|
||||||
"$mainMod, 4, workspace, 4"
|
"$mainMod, 4, workspace, 4"
|
||||||
"$mainMod, 5, workspace, 5"
|
"$mainMod, 5, workspace, 5"
|
||||||
"$mainMod, 6, workspace, 6"
|
"$mainMod, 6, workspace, 6"
|
||||||
"$mainMod, 7, workspace, 7"
|
"$mainMod, 7, workspace, 7"
|
||||||
"$mainMod, 8, workspace, 8"
|
"$mainMod, 8, workspace, 8"
|
||||||
"$mainMod, 9, workspace, 9"
|
"$mainMod, 9, workspace, 9"
|
||||||
"$mainMod, 0, workspace, 10"
|
"$mainMod, 0, workspace, 10"
|
||||||
|
|
||||||
# Move active window to a workspace with mainMod + SHIFT + [0-9]
|
# Move active window to a workspace with mainMod + SHIFT + [0-9]
|
||||||
"$mainMod SHIFT, 1, movetoworkspace, 1"
|
"$mainMod SHIFT, 1, movetoworkspace, 1"
|
||||||
"$mainMod SHIFT, 2, movetoworkspace, 2"
|
"$mainMod SHIFT, 2, movetoworkspace, 2"
|
||||||
"$mainMod SHIFT, 3, movetoworkspace, 3"
|
"$mainMod SHIFT, 3, movetoworkspace, 3"
|
||||||
"$mainMod SHIFT, 4, movetoworkspace, 4"
|
"$mainMod SHIFT, 4, movetoworkspace, 4"
|
||||||
"$mainMod SHIFT, 5, movetoworkspace, 5"
|
"$mainMod SHIFT, 5, movetoworkspace, 5"
|
||||||
"$mainMod SHIFT, 6, movetoworkspace, 6"
|
"$mainMod SHIFT, 6, movetoworkspace, 6"
|
||||||
"$mainMod SHIFT, 7, movetoworkspace, 7"
|
"$mainMod SHIFT, 7, movetoworkspace, 7"
|
||||||
"$mainMod SHIFT, 8, movetoworkspace, 8"
|
"$mainMod SHIFT, 8, movetoworkspace, 8"
|
||||||
"$mainMod SHIFT, 9, movetoworkspace, 9"
|
"$mainMod SHIFT, 9, movetoworkspace, 9"
|
||||||
"$mainMod SHIFT, 0, movetoworkspace, 10"
|
"$mainMod SHIFT, 0, movetoworkspace, 10"
|
||||||
|
|
||||||
# Scroll through existing workspaces with mainMod + scroll
|
# Scroll through existing workspaces with mainMod + scroll
|
||||||
"$mainMod, mouse_down, workspace, e+1"
|
"$mainMod, mouse_down, workspace, e+1"
|
||||||
"$mainMod, mouse_up, workspace, e-1"
|
"$mainMod, mouse_up, workspace, e-1"
|
||||||
|
|
||||||
# "ALT, Tab, cyclenext,"
|
# "ALT, Tab, cyclenext,"
|
||||||
# "ALT, Tab, bringactivetotop,"
|
# "ALT, Tab, bringactivetotop,"
|
||||||
];
|
];
|
||||||
|
|
||||||
bindm = [
|
bindm = [
|
||||||
# Move/resize windows with mainMod + LMB/RMB and dragging
|
# Move/resize windows with mainMod + LMB/RMB and dragging
|
||||||
@@ -318,44 +322,46 @@ in {
|
|||||||
"xrandr --monitor ${monitor1} --primary"
|
"xrandr --monitor ${monitor1} --primary"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
extraConfig = let
|
extraConfig =
|
||||||
wl-copy = "${pkgs.wl-clipboard}/bin/wl-copy";
|
let
|
||||||
wl-paste = "${pkgs.wl-clipboard}/bin/wl-paste";
|
wl-copy = "${pkgs.wl-clipboard}/bin/wl-copy";
|
||||||
dunstify = "${pkgs.dunst}/bin/dunstify";
|
wl-paste = "${pkgs.wl-clipboard}/bin/wl-paste";
|
||||||
dunstctl = "${pkgs.dunst}/bin/dunstctl";
|
dunstify = "${pkgs.dunst}/bin/dunstify";
|
||||||
pdfgrep = "${pkgs.pdfgrep}/bin/pdfgrep --cache";
|
dunstctl = "${pkgs.dunst}/bin/dunstctl";
|
||||||
path = "/synced/fh/os-hardening/**/slides";
|
pdfgrep = "${pkgs.pdfgrep}/bin/pdfgrep --cache";
|
||||||
in ''
|
path = "/synced/fh/os-hardening/**/slides";
|
||||||
bind = $mainMod, A, submap, notes
|
in
|
||||||
|
''
|
||||||
|
bind = $mainMod, A, submap, notes
|
||||||
|
|
||||||
submap = notes
|
submap = notes
|
||||||
# below
|
# below
|
||||||
bind = $mainMod, B, exec, ${wl-paste} | xargs -I {} ${pdfgrep} -B 15 -h -i "{}" ${path}/*.pdf | sed 's/[ \t]*$//' | ${wl-copy}
|
bind = $mainMod, B, exec, ${wl-paste} | xargs -I {} ${pdfgrep} -B 15 -h -i "{}" ${path}/*.pdf | sed 's/[ \t]*$//' | ${wl-copy}
|
||||||
# above
|
# above
|
||||||
bind = $mainMod, A, exec, ${wl-paste} | xargs -I {} ${pdfgrep} -A 15 -h -i "{}" ${path}/*.pdf | sed 's/[ \t]*$//' | ${wl-copy}
|
bind = $mainMod, A, exec, ${wl-paste} | xargs -I {} ${pdfgrep} -A 15 -h -i "{}" ${path}/*.pdf | sed 's/[ \t]*$//' | ${wl-copy}
|
||||||
# context
|
# context
|
||||||
bind = $mainMod, C, exec, ${wl-paste} | xargs -I {} ${pdfgrep} -C 15 -h -i "{}" ${path}/*.pdf | sed 's/[ \t]*$//' | ${wl-copy}
|
bind = $mainMod, C, exec, ${wl-paste} | xargs -I {} ${pdfgrep} -C 15 -h -i "{}" ${path}/*.pdf | sed 's/[ \t]*$//' | ${wl-copy}
|
||||||
# trim
|
# trim
|
||||||
bind = $mainMod, T, exec, ${wl-paste} | sed 's/[ \t]*$//' | sed 's/^[ \t]*//' | sed '/^[[:space:]]*$/d' | ${wl-copy}
|
bind = $mainMod, T, exec, ${wl-paste} | sed 's/[ \t]*$//' | sed 's/^[ \t]*//' | sed '/^[[:space:]]*$/d' | ${wl-copy}
|
||||||
bind = $mainMod, N, exec, ${dunstify} "$(${wl-paste})"
|
bind = $mainMod, N, exec, ${dunstify} "$(${wl-paste})"
|
||||||
bind = $mainMod, D, exec, ${dunstctl} close-all
|
bind = $mainMod, D, exec, ${dunstctl} close-all
|
||||||
# I win
|
# I win
|
||||||
bind = $mainMod, P, exec, ${wl-paste} | sgpt --model="gpt-4o" "Respond with the correct answer to the following question." | ${wl-copy}
|
bind = $mainMod, P, exec, ${wl-paste} | sgpt --model="gpt-4o" "Respond with the correct answer to the following question." | ${wl-copy}
|
||||||
# notes
|
# notes
|
||||||
|
|
||||||
bind = $mainMod, 2, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
bind = $mainMod, 2, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
||||||
bind = $mainMod, 3, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
bind = $mainMod, 3, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
||||||
bind = $mainMod, 4, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
bind = $mainMod, 4, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
||||||
bind = $mainMod, 5, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
bind = $mainMod, 5, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
||||||
bind = $mainMod, 6, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
bind = $mainMod, 6, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
||||||
bind = $mainMod, 7, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
bind = $mainMod, 7, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
||||||
bind = $mainMod, 8, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
bind = $mainMod, 8, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
||||||
bind = $mainMod, 0, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
bind = $mainMod, 0, exec, cat ~/Nextcloud/test.txt | ${wl-copy}
|
||||||
|
|
||||||
bind = , escape, submap, reset
|
bind = , escape, submap, reset
|
||||||
submap = reset
|
submap = reset
|
||||||
|
|
||||||
'';
|
'';
|
||||||
#experimental:explicit_sync = true
|
#experimental:explicit_sync = true
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
{ config, osConfig, pkgs, inputs, lib, ... }:
|
{ config, osConfig, pkgs, inputs, lib, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = osConfig.custom.graphical.hyprland.videobridge;
|
cfg = osConfig.custom.graphical.hyprland.videobridge;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
wayland.windowManager.hyprland.settings.windowrulev2 = [
|
wayland.windowManager.hyprland.settings.windowrulev2 = [
|
||||||
"opacity 0.0 override 0.0 override,class:^(xwaylandvideobridge)$"
|
"opacity 0.0 override 0.0 override,class:^(xwaylandvideobridge)$"
|
||||||
"noanim,class:^(xwaylandvideobridge)$"
|
"noanim,class:^(xwaylandvideobridge)$"
|
||||||
"noinitialfocus,class:^(xwaylandvideobridge)$"
|
"noinitialfocus,class:^(xwaylandvideobridge)$"
|
||||||
"maxsize 1 1,class:^(xwaylandvideobridge)$"
|
"maxsize 1 1,class:^(xwaylandvideobridge)$"
|
||||||
"noblur,class:^(xwaylandvideobridge)$"
|
"noblur,class:^(xwaylandvideobridge)$"
|
||||||
];
|
];
|
||||||
|
|
||||||
systemd.user.services.xwaylandvideobridge = {
|
systemd.user.services.xwaylandvideobridge = {
|
||||||
Unit.Description = "XWaylandVideoBridge";
|
Unit.Description = "XWaylandVideoBridge";
|
||||||
Service.ExecStart = lib.getExe pkgs.unstable.xwaylandvideobridge;
|
Service.ExecStart = lib.getExe pkgs.unstable.xwaylandvideobridge;
|
||||||
Install.WantedBy = ["graphical-session.target"];
|
Install.WantedBy = [ "graphical-session.target" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,239 +2,241 @@
|
|||||||
with lib;
|
with lib;
|
||||||
let cfg = osConfig.custom.graphical.hyprland;
|
let cfg = osConfig.custom.graphical.hyprland;
|
||||||
in {
|
in {
|
||||||
config = let
|
config =
|
||||||
# styles from https://github.com/khaneliman/khanelinix/blob/8375f8cfbe5bfd87565b4dc34c9d30630c17336d/modules/home/desktop/addons/waybar/default.nix
|
let
|
||||||
base16 = config.stylix.base16Scheme;
|
# styles from https://github.com/khaneliman/khanelinix/blob/8375f8cfbe5bfd87565b4dc34c9d30630c17336d/modules/home/desktop/addons/waybar/default.nix
|
||||||
readAndReplace = path: replace: builtins.readFile (pkgs.replaceVars path replace);
|
base16 = config.stylix.base16Scheme;
|
||||||
# base 1, 7, 0
|
readAndReplace = path: replace: builtins.readFile (pkgs.replaceVars path replace);
|
||||||
#theme = readAndReplace ./styles/theme.css { BASE="#5c4133"; BORDER="#fef1de"; TEXT="#dab353";};
|
# base 1, 7, 0
|
||||||
theme = builtins.readFile ./styles/theme.css;
|
#theme = readAndReplace ./styles/theme.css { BASE="#5c4133"; BORDER="#fef1de"; TEXT="#dab353";};
|
||||||
style = builtins.readFile ./styles/style.css;
|
theme = builtins.readFile ./styles/theme.css;
|
||||||
notificationsStyle = builtins.readFile ./styles/notifications.css;
|
style = builtins.readFile ./styles/style.css;
|
||||||
powerStyle = builtins.readFile ./styles/power.css;
|
notificationsStyle = builtins.readFile ./styles/notifications.css;
|
||||||
statsStyle = builtins.readFile ./styles/stats.css;
|
powerStyle = builtins.readFile ./styles/power.css;
|
||||||
workspacesStyle = builtins.readFile ./styles/workspaces.css;
|
statsStyle = builtins.readFile ./styles/stats.css;
|
||||||
in lib.mkIf cfg.enable {
|
workspacesStyle = builtins.readFile ./styles/workspaces.css;
|
||||||
|
in
|
||||||
|
lib.mkIf cfg.enable {
|
||||||
|
|
||||||
home.file.".config/waybar" = {
|
home.file.".config/waybar" = {
|
||||||
recursive = true;
|
recursive = true;
|
||||||
source = ../../.config/waybar;
|
source = ../../.config/waybar;
|
||||||
};
|
};
|
||||||
programs.waybar = {
|
programs.waybar = {
|
||||||
enable = true;
|
enable = true;
|
||||||
#systemd.enable = true;
|
#systemd.enable = true;
|
||||||
#systemd.target = "sway-session.target";
|
#systemd.target = "sway-session.target";
|
||||||
settings.main = {
|
settings.main = {
|
||||||
layer = "top";
|
layer = "top";
|
||||||
position = "bottom";
|
position = "bottom";
|
||||||
#output = lib.mapAttrsToList (n: v: v.monitor) outputs;
|
#output = lib.mapAttrsToList (n: v: v.monitor) outputs;
|
||||||
height = 25;
|
height = 25;
|
||||||
spacing = 4;
|
spacing = 4;
|
||||||
modules-left = [
|
modules-left = [
|
||||||
"hyprland/workspaces"
|
"hyprland/workspaces"
|
||||||
#"hyprland/window"
|
#"hyprland/window"
|
||||||
];
|
];
|
||||||
modules-center = [ ];
|
modules-center = [ ];
|
||||||
modules-right = [ "group/stats" "group/other" ];
|
modules-right = [ "group/stats" "group/other" ];
|
||||||
"group/stats" = {
|
"group/stats" = {
|
||||||
"orientation" = "horizontal";
|
"orientation" = "horizontal";
|
||||||
"modules" = [ "network" "cpu" "memory" "temperature" ]
|
"modules" = [ "network" "cpu" "memory" "temperature" ]
|
||||||
++ lib.optionals osConfig.custom.hardware.nvidia.enable [ "custom/nvidia" ]
|
++ lib.optionals osConfig.custom.hardware.nvidia.enable [ "custom/nvidia" ]
|
||||||
++ lib.optionals osConfig.custom.hardware.amd-gpu.enable [ "custom/amd-gpu" ];
|
++ lib.optionals osConfig.custom.hardware.amd-gpu.enable [ "custom/amd-gpu" ];
|
||||||
};
|
|
||||||
"group/other" = {
|
|
||||||
"orientation" = "horizontal";
|
|
||||||
"modules" =
|
|
||||||
[ "tray" "backlight" "pulseaudio" "mpris" "battery" "clock" ];
|
|
||||||
};
|
|
||||||
"cpu" = {
|
|
||||||
"format" = " {usage}%";
|
|
||||||
"tooltip" = true;
|
|
||||||
};
|
|
||||||
"disk" = { "format" = " {percentage_used}%"; };
|
|
||||||
"memory" = { "format" = " {}%"; };
|
|
||||||
|
|
||||||
"idle_inhibitor" = {
|
|
||||||
"format" = "{icon} ";
|
|
||||||
"format-icons" = {
|
|
||||||
"activated" = "";
|
|
||||||
"deactivated" = "";
|
|
||||||
};
|
};
|
||||||
};
|
"group/other" = {
|
||||||
|
"orientation" = "horizontal";
|
||||||
"keyboard-state" = {
|
"modules" =
|
||||||
"numlock" = true;
|
[ "tray" "backlight" "pulseaudio" "mpris" "battery" "clock" ];
|
||||||
"capslock" = true;
|
|
||||||
"format" = "{icon} {name}";
|
|
||||||
"format-icons" = {
|
|
||||||
"locked" = "";
|
|
||||||
"unlocked" = "";
|
|
||||||
};
|
};
|
||||||
};
|
"cpu" = {
|
||||||
|
"format" = " {usage}%";
|
||||||
"network" = {
|
"tooltip" = true;
|
||||||
"interval" = 2;
|
|
||||||
"format-wifi" = " {bandwidthDownBytes} {bandwidthUpBytes}";
|
|
||||||
"format-ethernet" = " {bandwidthDownBytes} {bandwidthUpBytes}";
|
|
||||||
"tooltip-format" = " {ifname} via {gwaddr}";
|
|
||||||
"format-linked" = " {ifname} (No IP)";
|
|
||||||
"format-disconnected" = " Disconnected";
|
|
||||||
"format-alt" = "{ifname}: {ipaddr}/{cidr}";
|
|
||||||
};
|
|
||||||
"pulseaudio" = {
|
|
||||||
"format" = "{volume}% {icon}";
|
|
||||||
"format-bluetooth" = "{volume}% {icon}";
|
|
||||||
"format-muted" = "";
|
|
||||||
"format-icons" = {
|
|
||||||
"headphone" = " ";
|
|
||||||
"hands-free" = " ";
|
|
||||||
"headset" = " ";
|
|
||||||
"phone" = "";
|
|
||||||
"portable" = "";
|
|
||||||
"car" = "";
|
|
||||||
"default" = [ "" "" ];
|
|
||||||
};
|
};
|
||||||
"scroll-step" = 1;
|
"disk" = { "format" = " {percentage_used}%"; };
|
||||||
"on-click" = "${pkgs.pavucontrol}/bin/pavucontrol";
|
"memory" = { "format" = " {}%"; };
|
||||||
"ignored-sinks" = [ "Easy Effects Sink" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
"pulseaudio/slider" = {
|
"idle_inhibitor" = {
|
||||||
"min" = 0;
|
"format" = "{icon} ";
|
||||||
"max" = 100;
|
"format-icons" = {
|
||||||
"orientation" = "horizontal";
|
"activated" = "";
|
||||||
};
|
"deactivated" = "";
|
||||||
"temperature".critical-threshold = 80;
|
};
|
||||||
"temperature".format = "{temperatureC}°C ";
|
};
|
||||||
"temperature".interval = 5;
|
|
||||||
"temperature".hwmon-path =
|
"keyboard-state" = {
|
||||||
lib.mkIf (osConfig.networking.hostName == "nix-laptop")
|
"numlock" = true;
|
||||||
"/sys/class/hwmon/hwmon6/temp1_input";
|
"capslock" = true;
|
||||||
"backlight".format = "{percent}% {icon}";
|
"format" = "{icon} {name}";
|
||||||
"backlight".states = [ 0 50 ];
|
"format-icons" = {
|
||||||
"backlight".format-icons = [ "" "" ];
|
"locked" = "";
|
||||||
"battery".states.good = 95;
|
"unlocked" = "";
|
||||||
"battery".interval = 5;
|
};
|
||||||
"battery".states.warning = 30;
|
};
|
||||||
"battery".states.critical = 15;
|
|
||||||
"battery".format = "{capacity}% / {power:.2}W {icon}";
|
"network" = {
|
||||||
"battery".format-icons = [ "" "" "" "" "" ];
|
"interval" = 2;
|
||||||
"clock" = {
|
"format-wifi" = " {bandwidthDownBytes} {bandwidthUpBytes}";
|
||||||
format = "{:%F %H:%M}";
|
"format-ethernet" = " {bandwidthDownBytes} {bandwidthUpBytes}";
|
||||||
tooltip-format = "<tt><small>{calendar}</small></tt>";
|
"tooltip-format" = " {ifname} via {gwaddr}";
|
||||||
"calendar" = {
|
"format-linked" = " {ifname} (No IP)";
|
||||||
"mode" = "year";
|
"format-disconnected" = " Disconnected";
|
||||||
"mode-mon-col" = 3;
|
"format-alt" = "{ifname}: {ipaddr}/{cidr}";
|
||||||
"weeks-pos" = "right";
|
};
|
||||||
"on-scroll" = 1;
|
"pulseaudio" = {
|
||||||
"format" = {
|
"format" = "{volume}% {icon}";
|
||||||
"months" = "<span color='#ffead3'><b>{}</b></span>";
|
"format-bluetooth" = "{volume}% {icon}";
|
||||||
"days" = "<span color='#ecc6d9'><b>{}</b></span>";
|
"format-muted" = "";
|
||||||
"weeks" = "<span color='#99ffdd'><b>W{}</b></span>";
|
"format-icons" = {
|
||||||
"weekdays" = "<span color='#ffcc66'><b>{}</b></span>";
|
"headphone" = " ";
|
||||||
"today" = "<span color='#ff6699'><b><u>{}</u></b></span>";
|
"hands-free" = " ";
|
||||||
|
"headset" = " ";
|
||||||
|
"phone" = "";
|
||||||
|
"portable" = "";
|
||||||
|
"car" = "";
|
||||||
|
"default" = [ "" "" ];
|
||||||
|
};
|
||||||
|
"scroll-step" = 1;
|
||||||
|
"on-click" = "${pkgs.pavucontrol}/bin/pavucontrol";
|
||||||
|
"ignored-sinks" = [ "Easy Effects Sink" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
"pulseaudio/slider" = {
|
||||||
|
"min" = 0;
|
||||||
|
"max" = 100;
|
||||||
|
"orientation" = "horizontal";
|
||||||
|
};
|
||||||
|
"temperature".critical-threshold = 80;
|
||||||
|
"temperature".format = "{temperatureC}°C ";
|
||||||
|
"temperature".interval = 5;
|
||||||
|
"temperature".hwmon-path =
|
||||||
|
lib.mkIf (osConfig.networking.hostName == "nix-laptop")
|
||||||
|
"/sys/class/hwmon/hwmon6/temp1_input";
|
||||||
|
"backlight".format = "{percent}% {icon}";
|
||||||
|
"backlight".states = [ 0 50 ];
|
||||||
|
"backlight".format-icons = [ "" "" ];
|
||||||
|
"battery".states.good = 95;
|
||||||
|
"battery".interval = 5;
|
||||||
|
"battery".states.warning = 30;
|
||||||
|
"battery".states.critical = 15;
|
||||||
|
"battery".format = "{capacity}% / {power:.2}W {icon}";
|
||||||
|
"battery".format-icons = [ "" "" "" "" "" ];
|
||||||
|
"clock" = {
|
||||||
|
format = "{:%F %H:%M}";
|
||||||
|
tooltip-format = "<tt><small>{calendar}</small></tt>";
|
||||||
|
"calendar" = {
|
||||||
|
"mode" = "year";
|
||||||
|
"mode-mon-col" = 3;
|
||||||
|
"weeks-pos" = "right";
|
||||||
|
"on-scroll" = 1;
|
||||||
|
"format" = {
|
||||||
|
"months" = "<span color='#ffead3'><b>{}</b></span>";
|
||||||
|
"days" = "<span color='#ecc6d9'><b>{}</b></span>";
|
||||||
|
"weeks" = "<span color='#99ffdd'><b>W{}</b></span>";
|
||||||
|
"weekdays" = "<span color='#ffcc66'><b>{}</b></span>";
|
||||||
|
"today" = "<span color='#ff6699'><b><u>{}</u></b></span>";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"mpris" = {
|
||||||
|
"format" = "{player_icon} {dynamic}";
|
||||||
|
"format-paused" = "{status_icon} <i>{dynamic}</i>";
|
||||||
|
"title-len" = 35;
|
||||||
|
"dynamic-len" = 35;
|
||||||
|
"player-icons" = {
|
||||||
|
"default" = "▶";
|
||||||
|
"mpv" = "🎵";
|
||||||
|
};
|
||||||
|
"status-icons" = { "paused" = "⏸"; };
|
||||||
|
};
|
||||||
|
"custom/nvidia" = {
|
||||||
|
"format" = "{}";
|
||||||
|
"interval" = 5;
|
||||||
|
"exec" = "~/.config/waybar/nvidia.sh";
|
||||||
|
"exec-if" = "nvidia-smi";
|
||||||
|
};
|
||||||
|
"custom/amd-gpu" = {
|
||||||
|
"format" = "{}";
|
||||||
|
"interval" = 5;
|
||||||
|
"exec" = "~/.config/waybar/amd-gpu.sh";
|
||||||
|
};
|
||||||
|
"tray".icon-size = 21;
|
||||||
|
"tray".spacing = 10;
|
||||||
|
"hyprland/window" = {
|
||||||
|
"format" = "{}";
|
||||||
|
"separate-outputs" = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
"hyprland/workspaces" = {
|
||||||
|
"disable-scroll" = true;
|
||||||
|
"all-outputs" = false;
|
||||||
|
"active-only" = false;
|
||||||
|
"on-click" = "activate";
|
||||||
|
"format" = "{icon} {windows}";
|
||||||
|
"format-icons" = {
|
||||||
|
"1" = "";
|
||||||
|
"2" = "";
|
||||||
|
"3" = "";
|
||||||
|
"4" = "";
|
||||||
|
"5" = "";
|
||||||
|
"6" = "";
|
||||||
|
"7" = "";
|
||||||
|
"8" = "";
|
||||||
|
"9" = "";
|
||||||
|
"10" = "";
|
||||||
|
"urgent" = "";
|
||||||
|
"default" = "";
|
||||||
|
"empty" = "";
|
||||||
|
};
|
||||||
|
# "format-window-separator" = "->";
|
||||||
|
"window-rewrite-default" = "";
|
||||||
|
"window-rewrite" = {
|
||||||
|
"class<org.keepassxc.KeePassXC>" = "";
|
||||||
|
"class<Caprine>" = "";
|
||||||
|
"class<Github Desktop>" = "";
|
||||||
|
"class<Godot>" = "";
|
||||||
|
"class<Mysql-workbench-bin>" = "";
|
||||||
|
"class<Slack>" = "";
|
||||||
|
"class<code>" = "";
|
||||||
|
"class<codium>" = "";
|
||||||
|
"code-url-handler" = "";
|
||||||
|
"class<discord>" = "";
|
||||||
|
"class<firefox>" = "";
|
||||||
|
"class<firefox-beta>" = "";
|
||||||
|
"class<firefox-developer-edition>" = "";
|
||||||
|
"class<firefox> title<.*github.*>" = "";
|
||||||
|
"class<firefox> title<.*twitch|youtube|plex|tntdrama|bally sports.*>" =
|
||||||
|
"";
|
||||||
|
"class<kitty>" = "";
|
||||||
|
"class<org.wezfurlong.wezterm>" = "";
|
||||||
|
"class<mediainfo-gui>" = "";
|
||||||
|
"class<org.kde.digikam>" = "";
|
||||||
|
"class<org.telegram.desktop>" = "";
|
||||||
|
"class<.pitivi-wrapped>" = "";
|
||||||
|
"class<steam>" = "";
|
||||||
|
"class<thunderbird>" = "";
|
||||||
|
"class<virt-manager>" = "";
|
||||||
|
"class<vlc>" = "";
|
||||||
|
"class<thunar>" = "";
|
||||||
|
"class<org.gnome.Nautilus>" = "";
|
||||||
|
"class<Spotify>" = "";
|
||||||
|
"title<Spotify Free>" = "";
|
||||||
|
"class<libreoffice-draw>" = "";
|
||||||
|
"class<libreoffice-writer>" = "";
|
||||||
|
"class<libreoffice-calc>" = "";
|
||||||
|
"class<libreoffice-impress>" = "";
|
||||||
|
"class<teams-for-linux>" = "";
|
||||||
|
"class<org.prismlauncher.PrismLauncher>" = "";
|
||||||
|
"class<minecraft-launcher>" = "";
|
||||||
|
"class<Postman>" = "";
|
||||||
|
"class<jetbrains-idea>" = "";
|
||||||
|
"class<Logseq>" = "";
|
||||||
|
"class<brave-browser>" = "";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"mpris" = {
|
style =
|
||||||
"format" = "{player_icon} {dynamic}";
|
"${theme}${style}${notificationsStyle}${powerStyle}${statsStyle}${workspacesStyle}";
|
||||||
"format-paused" = "{status_icon} <i>{dynamic}</i>";
|
|
||||||
"title-len" = 35;
|
|
||||||
"dynamic-len" = 35;
|
|
||||||
"player-icons" = {
|
|
||||||
"default" = "▶";
|
|
||||||
"mpv" = "🎵";
|
|
||||||
};
|
|
||||||
"status-icons" = { "paused" = "⏸"; };
|
|
||||||
};
|
|
||||||
"custom/nvidia" = {
|
|
||||||
"format" = "{}";
|
|
||||||
"interval" = 5;
|
|
||||||
"exec" = "~/.config/waybar/nvidia.sh";
|
|
||||||
"exec-if" = "nvidia-smi";
|
|
||||||
};
|
|
||||||
"custom/amd-gpu" = {
|
|
||||||
"format" = "{}";
|
|
||||||
"interval" = 5;
|
|
||||||
"exec" = "~/.config/waybar/amd-gpu.sh";
|
|
||||||
};
|
|
||||||
"tray".icon-size = 21;
|
|
||||||
"tray".spacing = 10;
|
|
||||||
"hyprland/window" = {
|
|
||||||
"format" = "{}";
|
|
||||||
"separate-outputs" = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
"hyprland/workspaces" = {
|
|
||||||
"disable-scroll" = true;
|
|
||||||
"all-outputs" = false;
|
|
||||||
"active-only" = false;
|
|
||||||
"on-click" = "activate";
|
|
||||||
"format" = "{icon} {windows}";
|
|
||||||
"format-icons" = {
|
|
||||||
"1" = "";
|
|
||||||
"2" = "";
|
|
||||||
"3" = "";
|
|
||||||
"4" = "";
|
|
||||||
"5" = "";
|
|
||||||
"6" = "";
|
|
||||||
"7" = "";
|
|
||||||
"8" = "";
|
|
||||||
"9" = "";
|
|
||||||
"10" = "";
|
|
||||||
"urgent" = "";
|
|
||||||
"default" = "";
|
|
||||||
"empty" = "";
|
|
||||||
};
|
|
||||||
# "format-window-separator" = "->";
|
|
||||||
"window-rewrite-default" = "";
|
|
||||||
"window-rewrite" = {
|
|
||||||
"class<org.keepassxc.KeePassXC>" = "";
|
|
||||||
"class<Caprine>" = "";
|
|
||||||
"class<Github Desktop>" = "";
|
|
||||||
"class<Godot>" = "";
|
|
||||||
"class<Mysql-workbench-bin>" = "";
|
|
||||||
"class<Slack>" = "";
|
|
||||||
"class<code>" = "";
|
|
||||||
"class<codium>" = "";
|
|
||||||
"code-url-handler" = "";
|
|
||||||
"class<discord>" = "";
|
|
||||||
"class<firefox>" = "";
|
|
||||||
"class<firefox-beta>" = "";
|
|
||||||
"class<firefox-developer-edition>" = "";
|
|
||||||
"class<firefox> title<.*github.*>" = "";
|
|
||||||
"class<firefox> title<.*twitch|youtube|plex|tntdrama|bally sports.*>" =
|
|
||||||
"";
|
|
||||||
"class<kitty>" = "";
|
|
||||||
"class<org.wezfurlong.wezterm>" = "";
|
|
||||||
"class<mediainfo-gui>" = "";
|
|
||||||
"class<org.kde.digikam>" = "";
|
|
||||||
"class<org.telegram.desktop>" = "";
|
|
||||||
"class<.pitivi-wrapped>" = "";
|
|
||||||
"class<steam>" = "";
|
|
||||||
"class<thunderbird>" = "";
|
|
||||||
"class<virt-manager>" = "";
|
|
||||||
"class<vlc>" = "";
|
|
||||||
"class<thunar>" = "";
|
|
||||||
"class<org.gnome.Nautilus>" = "";
|
|
||||||
"class<Spotify>" = "";
|
|
||||||
"title<Spotify Free>" = "";
|
|
||||||
"class<libreoffice-draw>" = "";
|
|
||||||
"class<libreoffice-writer>" = "";
|
|
||||||
"class<libreoffice-calc>" = "";
|
|
||||||
"class<libreoffice-impress>" = "";
|
|
||||||
"class<teams-for-linux>" = "";
|
|
||||||
"class<org.prismlauncher.PrismLauncher>" = "";
|
|
||||||
"class<minecraft-launcher>" = "";
|
|
||||||
"class<Postman>" = "";
|
|
||||||
"class<jetbrains-idea>" = "";
|
|
||||||
"class<Logseq>" = "";
|
|
||||||
"class<brave-browser>" = "";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
style =
|
|
||||||
"${theme}${style}${notificationsStyle}${powerStyle}${statsStyle}${workspacesStyle}";
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ in {
|
|||||||
modules-left = "i3 xwindow";
|
modules-left = "i3 xwindow";
|
||||||
modules-center = "";
|
modules-center = "";
|
||||||
modules-right = [ "music network memory cpu cpu-wattage cpu-temp" ]
|
modules-right = [ "music network memory cpu cpu-wattage cpu-temp" ]
|
||||||
++ lib.optionals osConfig.custom.hardware.nvidia.enable [ "nvidia-gpu" ]
|
++ lib.optionals osConfig.custom.hardware.nvidia.enable [ "nvidia-gpu" ]
|
||||||
++ lib.optionals osConfig.custom.hardware.amd-gpu.enable [ "amd-gpu" ]
|
++ lib.optionals osConfig.custom.hardware.amd-gpu.enable [ "amd-gpu" ]
|
||||||
++ [ "pulseaudio date tray" ];
|
++ [ "pulseaudio date tray" ];
|
||||||
cursor-click = "pointer";
|
cursor-click = "pointer";
|
||||||
cursor-scroll = "ns-resize";
|
cursor-scroll = "ns-resize";
|
||||||
@@ -68,33 +68,34 @@ in {
|
|||||||
# wm-restack = "i3";
|
# wm-restack = "i3";
|
||||||
# override-redirect = true;
|
# override-redirect = true;
|
||||||
};
|
};
|
||||||
"module/i3" = let padding = 2;
|
"module/i3" =
|
||||||
in {
|
let padding = 2;
|
||||||
type = "internal/i3";
|
in {
|
||||||
pin-workspaces = true;
|
type = "internal/i3";
|
||||||
show-urgent = true;
|
pin-workspaces = true;
|
||||||
strip-wsnumbers = true;
|
show-urgent = true;
|
||||||
index-sort = true;
|
strip-wsnumbers = true;
|
||||||
enable-click = true;
|
index-sort = true;
|
||||||
wrapping-scroll = true;
|
enable-click = true;
|
||||||
fuzzy-match = true;
|
wrapping-scroll = true;
|
||||||
format = "<label-state> <label-mode>";
|
fuzzy-match = true;
|
||||||
label-focused = "%name%";
|
format = "<label-state> <label-mode>";
|
||||||
label-focused-foreground = config.stylix.base16Scheme.base01;
|
label-focused = "%name%";
|
||||||
label-focused-background = config.stylix.base16Scheme.base05;
|
label-focused-foreground = config.stylix.base16Scheme.base01;
|
||||||
label-focused-underline = config.stylix.base16Scheme.base03;
|
label-focused-background = config.stylix.base16Scheme.base05;
|
||||||
label-focused-padding = padding;
|
label-focused-underline = config.stylix.base16Scheme.base03;
|
||||||
label-unfocused = "%name%";
|
label-focused-padding = padding;
|
||||||
label-unfocused-padding = padding;
|
label-unfocused = "%name%";
|
||||||
label-visible = "%name%";
|
label-unfocused-padding = padding;
|
||||||
label-visible-underline = config.stylix.base16Scheme.base01;
|
label-visible = "%name%";
|
||||||
label-visible-padding = padding;
|
label-visible-underline = config.stylix.base16Scheme.base01;
|
||||||
label-urgent = "%name%";
|
label-visible-padding = padding;
|
||||||
label-urgent-foreground = config.stylix.base16Scheme.base00;
|
label-urgent = "%name%";
|
||||||
label-urgent-background = config.stylix.base16Scheme.base08;
|
label-urgent-foreground = config.stylix.base16Scheme.base00;
|
||||||
label-urgent-underline = config.stylix.base16Scheme.base0F;
|
label-urgent-background = config.stylix.base16Scheme.base08;
|
||||||
label-urgent-padding = padding;
|
label-urgent-underline = config.stylix.base16Scheme.base0F;
|
||||||
};
|
label-urgent-padding = padding;
|
||||||
|
};
|
||||||
"module/xworkspaces" = {
|
"module/xworkspaces" = {
|
||||||
type = "internal/xworkspaces";
|
type = "internal/xworkspaces";
|
||||||
label-active = "%name%";
|
label-active = "%name%";
|
||||||
@@ -198,7 +199,7 @@ in {
|
|||||||
};
|
};
|
||||||
"module/amd-gpu" = {
|
"module/amd-gpu" = {
|
||||||
type = "custom/script";
|
type = "custom/script";
|
||||||
format-foreground = "ed1c24";
|
format-foreground = "ed1c24";
|
||||||
label = "%output:0:35:...%";
|
label = "%output:0:35:...%";
|
||||||
exec = "~/.config/polybar/amd-gpu.sh";
|
exec = "~/.config/polybar/amd-gpu.sh";
|
||||||
interval = 3;
|
interval = 3;
|
||||||
|
|||||||
@@ -1,47 +1,47 @@
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
{
|
{
|
||||||
home.file."path.sh" = {
|
home.file."path.sh" = {
|
||||||
enable = true;
|
enable = true;
|
||||||
recursive = true;
|
recursive = true;
|
||||||
executable = true;
|
executable = true;
|
||||||
text = ''
|
text = ''
|
||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
if [ "$XDG_SESSION_TYPE" = "wayland" ]; then
|
if [ "$XDG_SESSION_TYPE" = "wayland" ]; then
|
||||||
export MOZ_DBUS_REMOTE="1"
|
export MOZ_DBUS_REMOTE="1"
|
||||||
export KITTY_ENABLE_WAYLAND="1"
|
export KITTY_ENABLE_WAYLAND="1"
|
||||||
export _JAVA_AWT_WM_NONREPARENTING="1"
|
export _JAVA_AWT_WM_NONREPARENTING="1"
|
||||||
export MOZ_ENABLE_WAYLAND="1"
|
export MOZ_ENABLE_WAYLAND="1"
|
||||||
export WLR_NO_HARDWARE_CURSORS="1"
|
export WLR_NO_HARDWARE_CURSORS="1"
|
||||||
export NIXOS_OZONE_WL="1"
|
export NIXOS_OZONE_WL="1"
|
||||||
|
|
||||||
export LIBVA_DRIVER_NAME="nvidia"
|
export LIBVA_DRIVER_NAME="nvidia"
|
||||||
export __GLX_VENDOR_LIBRARY_NAME="nvidia"
|
export __GLX_VENDOR_LIBRARY_NAME="nvidia"
|
||||||
export GBM_BACKEND="nvidia-drm"
|
export GBM_BACKEND="nvidia-drm"
|
||||||
|
|
||||||
export XDG_SESSION_TYPE="wayland"
|
export XDG_SESSION_TYPE="wayland"
|
||||||
export QT_QPA_PLATFORM="wayland;xcb"
|
export QT_QPA_PLATFORM="wayland;xcb"
|
||||||
export ELECTRON_OZONE_PLATFORM_HINT="wayland"
|
export ELECTRON_OZONE_PLATFORM_HINT="wayland"
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
target = ".config/plasma-workspace/env/path.sh";
|
target = ".config/plasma-workspace/env/path.sh";
|
||||||
};
|
};
|
||||||
# home.file."path.desktop" = {
|
# home.file."path.desktop" = {
|
||||||
# enable = true;
|
# enable = true;
|
||||||
# recursive = true;
|
# recursive = true;
|
||||||
# executable = true;
|
# executable = true;
|
||||||
# text = ''
|
# text = ''
|
||||||
# [Desktop Entry]
|
# [Desktop Entry]
|
||||||
# Type=Application
|
# Type=Application
|
||||||
# Exec=${config.xdg.configHome}/autostart/path.sh
|
# Exec=${config.xdg.configHome}/autostart/path.sh
|
||||||
# Hidden=false
|
# Hidden=false
|
||||||
# NoDisplay=false
|
# NoDisplay=false
|
||||||
# X-GNOME-Autostart-enabled=true
|
# X-GNOME-Autostart-enabled=true
|
||||||
# Name[en_US]=Login Script
|
# Name[en_US]=Login Script
|
||||||
# Name=Login Script
|
# Name=Login Script
|
||||||
# Comment[en_US]=Launches login script and sets environment variables
|
# Comment[en_US]=Launches login script and sets environment variables
|
||||||
# Comment=Launches login script and sets environment variables
|
# Comment=Launches login script and sets environment variables
|
||||||
# '';
|
# '';
|
||||||
# target = ".config/autostart/path.desktop";
|
# target = ".config/autostart/path.desktop";
|
||||||
# };
|
# };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ config, pkgs, inputs, lib, ...}:
|
{ config, pkgs, inputs, lib, ... }:
|
||||||
{
|
{
|
||||||
programs.kitty = {
|
programs.kitty = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
{ config, pkgs, inputs, ...}:
|
{ config, pkgs, inputs, ... }:
|
||||||
{
|
{
|
||||||
programs.lf = {
|
programs.lf = {
|
||||||
enable = true;
|
enable = true;
|
||||||
previewer.source = pkgs.writeShellScript "pv.sh" ''
|
previewer.source = pkgs.writeShellScript "pv.sh" ''
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
case "$(${pkgs.file}/bin/file -Lb --mime-type -- "$1")" in
|
case "$(${pkgs.file}/bin/file -Lb --mime-type -- "$1")" in
|
||||||
#image/*|video/*) ${pkgs.chafa}/bin/chafa -f sixel -s "$2x$3" --animate false $1;;
|
#image/*|video/*) ${pkgs.chafa}/bin/chafa -f sixel -s "$2x$3" --animate false $1;;
|
||||||
application/x-tar) tar tf "$1";;
|
application/x-tar) tar tf "$1";;
|
||||||
application/vnd.rar) ${pkgs.p7zip}/bin/7z l "$1";;
|
application/vnd.rar) ${pkgs.p7zip}/bin/7z l "$1";;
|
||||||
application/x-7z-compressed) ${pkgs.p7zip}/bin/7z l "$1";;
|
application/x-7z-compressed) ${pkgs.p7zip}/bin/7z l "$1";;
|
||||||
*) ${pkgs.ctpv}/bin/ctpv "$1";;
|
*) ${pkgs.ctpv}/bin/ctpv "$1";;
|
||||||
esac
|
esac
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ config, pkgs, inputs, ...}:
|
{ config, pkgs, inputs, ... }:
|
||||||
{
|
{
|
||||||
programs.mpv = {
|
programs.mpv = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
plugins.nvim-autopairs = { enable = true; };
|
plugins.nvim-autopairs = { enable = true; };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{lib, pkgs, ...}:
|
{ lib, pkgs, ... }:
|
||||||
{
|
{
|
||||||
enable = true;
|
enable = true;
|
||||||
viAlias = true;
|
viAlias = true;
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ let
|
|||||||
];
|
];
|
||||||
merged =
|
merged =
|
||||||
builtins.foldl' (acc: elem: lib.recursiveUpdate acc elem) { } configs;
|
builtins.foldl' (acc: elem: lib.recursiveUpdate acc elem) { } configs;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
home.sessionVariables = { EDITOR = "nvim"; };
|
home.sessionVariables = { EDITOR = "nvim"; };
|
||||||
programs.nixvim = merged;
|
programs.nixvim = merged;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{pkgs, ...}:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
plugins = {
|
plugins = {
|
||||||
image.enable = true;
|
image.enable = true;
|
||||||
|
|||||||
@@ -1,19 +1,28 @@
|
|||||||
{pkgs, ...}:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
plugins = {
|
plugins = {
|
||||||
otter = { # provide lsp functionality for code embedded in other languages
|
otter = {
|
||||||
|
# provide lsp functionality for code embedded in other languages
|
||||||
enable = true;
|
enable = true;
|
||||||
settings.handle_leading_whitespace = true;
|
settings.handle_leading_whitespace = true;
|
||||||
};
|
};
|
||||||
lsp = {
|
lsp = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
inlayHints = true;
|
||||||
servers = {
|
servers = {
|
||||||
bashls.enable = true;
|
bashls.enable = true;
|
||||||
#ccls.enable = true;
|
#ccls.enable = true;
|
||||||
clangd.enable = true;
|
clangd.enable = true;
|
||||||
cssls.enable = true;
|
cssls.enable = true;
|
||||||
gopls.enable = true;
|
gopls.enable = true;
|
||||||
nixd.enable = true;
|
nixd = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
nixpkgs.expr = ''import <nixpkgs> { }'';
|
||||||
|
formatting.command = [ "nixpkgs-fmt" ];
|
||||||
|
options.nixos.expr = ''(builtins.getFlake ("/home/kopatz/projects/github/nix-config")).nixosConfigurations.kop-pc.options'';
|
||||||
|
};
|
||||||
|
};
|
||||||
html.enable = true;
|
html.enable = true;
|
||||||
dartls.enable = true;
|
dartls.enable = true;
|
||||||
ts_ls.enable = true;
|
ts_ls.enable = true;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
fantomas.enable = true;
|
fantomas.enable = true;
|
||||||
gofmt.enable = true;
|
gofmt.enable = true;
|
||||||
goimports.enable = true;
|
goimports.enable = true;
|
||||||
nixfmt.enable = true;
|
#nixfmt.enable = true;
|
||||||
markdownlint.enable = true;
|
markdownlint.enable = true;
|
||||||
shellharden.enable = true;
|
shellharden.enable = true;
|
||||||
shfmt.enable = true;
|
shfmt.enable = true;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
opts = {
|
opts = {
|
||||||
timeoutlen = 500;
|
timeoutlen = 500;
|
||||||
};
|
};
|
||||||
plugins.which-key = { enable = true; }; }
|
plugins.which-key = { enable = true; };
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
{ config, pkgs, inputs, ...}:
|
{ config, pkgs, inputs, ... }:
|
||||||
{
|
{
|
||||||
home.file.".config/nvim" = {
|
home.file.".config/nvim" = {
|
||||||
enable = true;
|
enable = true;
|
||||||
recursive = true;
|
recursive = true;
|
||||||
source = ../.config/nvim;
|
source = ../.config/nvim;
|
||||||
target = ".config/nvim";
|
target = ".config/nvim";
|
||||||
};
|
};
|
||||||
programs.neovim = {
|
programs.neovim = {
|
||||||
enable = true;
|
enable = true;
|
||||||
defaultEditor = true;
|
defaultEditor = true;
|
||||||
extraPackages = with pkgs; [
|
extraPackages = with pkgs; [
|
||||||
gcc
|
gcc
|
||||||
ripgrep
|
ripgrep
|
||||||
fd
|
fd
|
||||||
cmake
|
cmake
|
||||||
pyright
|
pyright
|
||||||
nodePackages.eslint
|
nodePackages.eslint
|
||||||
ccls
|
ccls
|
||||||
nodejs_22
|
nodejs_22
|
||||||
go
|
go
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ let
|
|||||||
r = c."${color}-rgb-r";
|
r = c."${color}-rgb-r";
|
||||||
g = c."${color}-rgb-g";
|
g = c."${color}-rgb-g";
|
||||||
b = c."${color}-rgb-b";
|
b = c."${color}-rgb-b";
|
||||||
in "rgba ( ${r}, ${g}, ${b}, ${opacity} % )";
|
in
|
||||||
|
"rgba ( ${r}, ${g}, ${b}, ${opacity} % )";
|
||||||
mkRgb = mkRgba "100";
|
mkRgb = mkRgba "100";
|
||||||
rofiOpacity =
|
rofiOpacity =
|
||||||
builtins.toString (builtins.ceil (config.stylix.opacity.popups * 100));
|
builtins.toString (builtins.ceil (config.stylix.opacity.popups * 100));
|
||||||
@@ -55,7 +56,8 @@ let
|
|||||||
alternate-active-text = mkRgb "base0D";
|
alternate-active-text = mkRgb "base0D";
|
||||||
alternate-urgent-text = mkRgb "base08";
|
alternate-urgent-text = mkRgb "base08";
|
||||||
};
|
};
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
home.file.".config/rofi" = {
|
home.file.".config/rofi" = {
|
||||||
enable = true;
|
enable = true;
|
||||||
recursive = true;
|
recursive = true;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
{ osConfig, pkgs, config, lib, ... }:
|
{ osConfig, pkgs, config, lib, ... }:
|
||||||
let cfg = osConfig.custom.graphical.stylix;
|
let
|
||||||
|
cfg = osConfig.custom.graphical.stylix;
|
||||||
base16 = config.stylix.base16Scheme;
|
base16 = config.stylix.base16Scheme;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
stylix = {
|
stylix = {
|
||||||
enable = true;
|
enable = true;
|
||||||
@@ -17,7 +19,7 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
wayland.windowManager.hyprland.settings = lib.mkIf osConfig.custom.graphical.hyprland.enable {
|
wayland.windowManager.hyprland.settings = lib.mkIf osConfig.custom.graphical.hyprland.enable {
|
||||||
env = ["GTK_THEME,adw-gtk3"];
|
env = [ "GTK_THEME,adw-gtk3" ];
|
||||||
general."col.active_border" = lib.mkForce "rgb(${base16.base07}) rgb(${base16.base04}) 45deg";
|
general."col.active_border" = lib.mkForce "rgb(${base16.base07}) rgb(${base16.base04}) 45deg";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ config, pkgs, inputs, ...}:
|
{ config, pkgs, inputs, ... }:
|
||||||
{
|
{
|
||||||
home = {
|
home = {
|
||||||
pointerCursor = {
|
pointerCursor = {
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
};
|
};
|
||||||
gtk = {
|
gtk = {
|
||||||
enable = true;
|
enable = true;
|
||||||
theme = {
|
theme = {
|
||||||
name = "Tokyonight-Dark-BL";
|
name = "Tokyonight-Dark-BL";
|
||||||
package = pkgs.tokyo-night-gtk;
|
package = pkgs.tokyo-night-gtk;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
{
|
{
|
||||||
slug = "yorha";
|
slug = "yorha";
|
||||||
name = "yorha";
|
name = "yorha";
|
||||||
author = "flick0 (https://github.com/flick0)";
|
author = "flick0 (https://github.com/flick0)";
|
||||||
palette = {
|
palette = {
|
||||||
base00 = "#1e1d1c";
|
base00 = "#1e1d1c";
|
||||||
base01 = "#A39D8F";
|
base01 = "#A39D8F";
|
||||||
base02 = "#AFA899";
|
base02 = "#AFA899";
|
||||||
base03 = "#BBB4A5";
|
base03 = "#BBB4A5";
|
||||||
base04 = "#C3BCAB";
|
base04 = "#C3BCAB";
|
||||||
base05 = "#D2CCB9";
|
base05 = "#D2CCB9";
|
||||||
base06 = "#DBD5C2";
|
base06 = "#DBD5C2";
|
||||||
base07 = "#e8e5da";
|
base07 = "#e8e5da";
|
||||||
base08 = "#a2a098";
|
base08 = "#a2a098";
|
||||||
base09 = "#A39D8F";
|
base09 = "#A39D8F";
|
||||||
base10 = "#AFA899";
|
base10 = "#AFA899";
|
||||||
base11 = "#BBB4A5";
|
base11 = "#BBB4A5";
|
||||||
base12 = "#C3BCAB";
|
base12 = "#C3BCAB";
|
||||||
base13 = "#D2CCB9";
|
base13 = "#D2CCB9";
|
||||||
base14 = "#DBD5C2";
|
base14 = "#DBD5C2";
|
||||||
base15 = "#e8e5da";
|
base15 = "#e8e5da";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
services.cron = {
|
services.cron = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +1,40 @@
|
|||||||
{
|
{
|
||||||
services.openssh.enable = true;
|
services.openssh.enable = true;
|
||||||
services.openssh.extraConfig = ''
|
services.openssh.extraConfig = ''
|
||||||
HostKeyAlgorithms +ssh-rsa
|
HostKeyAlgorithms +ssh-rsa
|
||||||
PubkeyAcceptedAlgorithms +ssh-rsa
|
PubkeyAcceptedAlgorithms +ssh-rsa
|
||||||
'';
|
'';
|
||||||
|
|
||||||
services.openssh.settings.Macs = [
|
services.openssh.settings.Macs = [
|
||||||
"hmac-md5"
|
"hmac-md5"
|
||||||
];
|
];
|
||||||
services.openssh.settings.Ciphers = [
|
services.openssh.settings.Ciphers = [
|
||||||
"3des-cbc"
|
"3des-cbc"
|
||||||
"aes128-cbc"
|
"aes128-cbc"
|
||||||
"aes192-cbc"
|
"aes192-cbc"
|
||||||
"aes256-cbc"
|
"aes256-cbc"
|
||||||
"aes128-ctr"
|
"aes128-ctr"
|
||||||
"aes192-ctr"
|
"aes192-ctr"
|
||||||
"aes256-ctr"
|
"aes256-ctr"
|
||||||
"aes128-gcm@openssh.com"
|
"aes128-gcm@openssh.com"
|
||||||
"aes256-gcm@openssh.com"
|
"aes256-gcm@openssh.com"
|
||||||
"chacha20-poly1305@openssh.com"
|
"chacha20-poly1305@openssh.com"
|
||||||
];
|
];
|
||||||
|
|
||||||
services.openssh.settings.KexAlgorithms = [
|
services.openssh.settings.KexAlgorithms = [
|
||||||
"diffie-hellman-group1-sha1"
|
"diffie-hellman-group1-sha1"
|
||||||
"diffie-hellman-group14-sha1"
|
"diffie-hellman-group14-sha1"
|
||||||
"diffie-hellman-group14-sha256"
|
"diffie-hellman-group14-sha256"
|
||||||
"diffie-hellman-group16-sha512"
|
"diffie-hellman-group16-sha512"
|
||||||
"diffie-hellman-group18-sha512"
|
"diffie-hellman-group18-sha512"
|
||||||
"diffie-hellman-group-exchange-sha1"
|
"diffie-hellman-group-exchange-sha1"
|
||||||
"diffie-hellman-group-exchange-sha256"
|
"diffie-hellman-group-exchange-sha256"
|
||||||
"ecdh-sha2-nistp256"
|
"ecdh-sha2-nistp256"
|
||||||
"ecdh-sha2-nistp384"
|
"ecdh-sha2-nistp384"
|
||||||
"ecdh-sha2-nistp521"
|
"ecdh-sha2-nistp521"
|
||||||
"curve25519-sha256"
|
"curve25519-sha256"
|
||||||
"curve25519-sha256@libssh.org"
|
"curve25519-sha256@libssh.org"
|
||||||
"sntrup761x25519-sha512@openssh.com"
|
"sntrup761x25519-sha512@openssh.com"
|
||||||
];
|
];
|
||||||
services.atftpd.enable = true;
|
services.atftpd.enable = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, config, ...}:
|
{ pkgs, config, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./fh
|
./fh
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, ...}:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
ecryptfs
|
ecryptfs
|
||||||
@@ -6,5 +6,5 @@
|
|||||||
security.pam.enableEcryptfs = true;
|
security.pam.enableEcryptfs = true;
|
||||||
|
|
||||||
programs.ecryptfs.enable = true;
|
programs.ecryptfs.enable = true;
|
||||||
boot.kernelModules = ["ecryptfs"];
|
boot.kernelModules = [ "ecryptfs" ];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, config, ...}:
|
{ pkgs, config, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
{ pkgs, ...} :
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
regripper
|
regripper
|
||||||
foremost
|
foremost
|
||||||
binwalk
|
binwalk
|
||||||
sleuthkit
|
sleuthkit
|
||||||
samdump2
|
samdump2
|
||||||
apktool
|
apktool
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
{ pkgs, ...} :
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
nmap
|
nmap
|
||||||
gobuster
|
gobuster
|
||||||
thc-hydra
|
thc-hydra
|
||||||
seclists
|
seclists
|
||||||
aircrack-ng
|
aircrack-ng
|
||||||
hashcat
|
hashcat
|
||||||
hashcat-utils
|
hashcat-utils
|
||||||
john
|
john
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{pkgs, ...}: {
|
{ pkgs, ... }: {
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
typst
|
typst
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
services.flatpak.enable = true;
|
services.flatpak.enable = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{pkgs, ...}:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
#services.pcscd.enable = true;
|
#services.pcscd.enable = true;
|
||||||
|
|
||||||
@@ -9,5 +9,5 @@
|
|||||||
};
|
};
|
||||||
#environment.systemPackages = with pkgs; [
|
#environment.systemPackages = with pkgs; [
|
||||||
# pinentry-curses
|
# pinentry-curses
|
||||||
# ];
|
# ];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{config, lib, pkgs, ...} :
|
{ config, lib, pkgs, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.graphical.audio;
|
cfg = config.custom.graphical.audio;
|
||||||
@@ -7,11 +7,11 @@ in
|
|||||||
options.custom.graphical.audio = {
|
options.custom.graphical.audio = {
|
||||||
enable = mkEnableOption "Enables audio";
|
enable = mkEnableOption "Enables audio";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
# Enable sound with pipewire.
|
# Enable sound with pipewire.
|
||||||
security.rtkit.enable = true;
|
security.rtkit.enable = true;
|
||||||
|
|
||||||
services.pulseaudio.enable = false;
|
services.pulseaudio.enable = false;
|
||||||
services.pipewire = {
|
services.pipewire = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ in
|
|||||||
options.custom.graphical.code = {
|
options.custom.graphical.code = {
|
||||||
enable = mkEnableOption "Enables code";
|
enable = mkEnableOption "Enables code";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
documentation.dev.enable = true;
|
documentation.dev.enable = true;
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
@@ -18,7 +18,7 @@ in
|
|||||||
insomnia
|
insomnia
|
||||||
nodejs_22 # needed for tabby extension
|
nodejs_22 # needed for tabby extension
|
||||||
];
|
];
|
||||||
|
|
||||||
#environment.sessionVariables = {
|
#environment.sessionVariables = {
|
||||||
# DOTNET_ROOT = "${pkgs.dotnet-sdk_7}";
|
# DOTNET_ROOT = "${pkgs.dotnet-sdk_7}";
|
||||||
#};
|
#};
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ in
|
|||||||
options.custom.graphical.cosmic = {
|
options.custom.graphical.cosmic = {
|
||||||
enable = lib.mkEnableOption "Enables cosmic";
|
enable = lib.mkEnableOption "Enables cosmic";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
nix.settings = {
|
nix.settings = {
|
||||||
substituters = [ "https://cosmic.cachix.org/" ];
|
substituters = [ "https://cosmic.cachix.org/" ];
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, config, lib, ...}:
|
{ pkgs, config, lib, ... }:
|
||||||
{
|
{
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{lib, config, pkgs, inputs, ... }:
|
{ lib, config, pkgs, inputs, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.graphical.emulators;
|
cfg = config.custom.graphical.emulators;
|
||||||
@@ -7,7 +7,7 @@ in
|
|||||||
options.custom.graphical.emulators = {
|
options.custom.graphical.emulators = {
|
||||||
enable = mkEnableOption "Enables emulators";
|
enable = mkEnableOption "Enables emulators";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
snes9x
|
snes9x
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ let
|
|||||||
# hash = "sha256-aWpTUAm9FBuZI2KwEvhSnLB7Mfp5nYgUwvvLF47FIfM=";
|
# hash = "sha256-aWpTUAm9FBuZI2KwEvhSnLB7Mfp5nYgUwvvLF47FIfM=";
|
||||||
# };
|
# };
|
||||||
#});
|
#});
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.custom.graphical.games = {
|
options.custom.graphical.games = {
|
||||||
enable = mkEnableOption "Enables games";
|
enable = mkEnableOption "Enables games";
|
||||||
enablePreinstalled = mkEnableOption "Enables preinstalled games";
|
enablePreinstalled = mkEnableOption "Enables preinstalled games";
|
||||||
@@ -42,16 +43,16 @@ in {
|
|||||||
];
|
];
|
||||||
environment.systemPackages = [ pkgs.mangohud ]
|
environment.systemPackages = [ pkgs.mangohud ]
|
||||||
++ optionals cfg.enablePreinstalled (with pkgs; [
|
++ optionals cfg.enablePreinstalled (with pkgs; [
|
||||||
#taisei
|
#taisei
|
||||||
#osu-lazer-bin
|
#osu-lazer-bin
|
||||||
wineWowPackages.unstableFull
|
wineWowPackages.unstableFull
|
||||||
winetricks
|
winetricks
|
||||||
lutris
|
lutris
|
||||||
prismlauncher
|
prismlauncher
|
||||||
steamtinkerlaunch
|
steamtinkerlaunch
|
||||||
tetrio-desktop
|
tetrio-desktop
|
||||||
#libs
|
#libs
|
||||||
]) ++ optionals cfg.enableVr (with pkgs; [ beatsabermodmanager ]);
|
]) ++ optionals cfg.enableVr (with pkgs; [ beatsabermodmanager ]);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{lib, config, pkgs, ...}:
|
{ lib, config, pkgs, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.graphical.lxqt;
|
cfg = config.custom.graphical.lxqt;
|
||||||
@@ -7,10 +7,10 @@ in
|
|||||||
options.custom.graphical.lxqt = {
|
options.custom.graphical.lxqt = {
|
||||||
enable = mkEnableOption "Enables lxqt";
|
enable = mkEnableOption "Enables lxqt";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
services.xserver = {
|
services.xserver = {
|
||||||
xkb.layout = config.mainUser.layout;
|
xkb.layout = config.mainUser.layout;
|
||||||
xkb.variant = config.mainUser.variant;
|
xkb.variant = config.mainUser.variant;
|
||||||
enable = true;
|
enable = true;
|
||||||
displayManager.sddm.enable = true;
|
displayManager.sddm.enable = true;
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
{config, pkgs, lib, ...}:
|
{ config, pkgs, lib, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.custom.graphical.noise-supression;
|
cfg = config.custom.graphical.noise-supression;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.custom.graphical.noise-supression = {
|
options.custom.graphical.noise-supression = {
|
||||||
enable = lib.mkEnableOption "Enables noise-supression";
|
enable = lib.mkEnableOption "Enables noise-supression";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
easyeffects
|
easyeffects
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{lib, config, pkgs, ...}:
|
{ lib, config, pkgs, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.graphical.obs;
|
cfg = config.custom.graphical.obs;
|
||||||
@@ -7,14 +7,14 @@ in
|
|||||||
options.custom.graphical.obs = {
|
options.custom.graphical.obs = {
|
||||||
enable = mkEnableOption "Enables obs";
|
enable = mkEnableOption "Enables obs";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
# borked in unstable branch
|
# borked in unstable branch
|
||||||
#boot = {
|
#boot = {
|
||||||
# kernelModules = ["v4l2loopback"]; # Autostart kernel modules on boot
|
# kernelModules = ["v4l2loopback"]; # Autostart kernel modules on boot
|
||||||
# extraModulePackages = with config.boot.kernelPackages; [v4l2loopback]; # loopback module to make OBS virtual camera work
|
# extraModulePackages = with config.boot.kernelPackages; [v4l2loopback]; # loopback module to make OBS virtual camera work
|
||||||
#};
|
#};
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
(wrapOBS {
|
(wrapOBS {
|
||||||
plugins = with obs-studio-plugins; [
|
plugins = with obs-studio-plugins; [
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{config, lib, pkgs, ...}:
|
{ config, lib, pkgs, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.graphical.openrgb;
|
cfg = config.custom.graphical.openrgb;
|
||||||
@@ -7,7 +7,7 @@ in
|
|||||||
options.custom.graphical.openrgb = {
|
options.custom.graphical.openrgb = {
|
||||||
enable = mkEnableOption "Enables openrgb";
|
enable = mkEnableOption "Enables openrgb";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
services.hardware.openrgb.enable = true;
|
services.hardware.openrgb.enable = true;
|
||||||
services.hardware.openrgb.package = pkgs.openrgb-with-all-plugins;
|
services.hardware.openrgb.package = pkgs.openrgb-with-all-plugins;
|
||||||
|
|||||||
@@ -6,68 +6,70 @@ in {
|
|||||||
enable = mkEnableOption "Enables shared";
|
enable = mkEnableOption "Enables shared";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = let
|
config =
|
||||||
screenshot = pkgs.writeShellScriptBin "screenshot" ''
|
let
|
||||||
${pkgs.scrot}/bin/scrot -fs - | ${pkgs.xclip}/bin/xclip -selection clipboard -t image/png -i
|
screenshot = pkgs.writeShellScriptBin "screenshot" ''
|
||||||
'';
|
${pkgs.scrot}/bin/scrot -fs - | ${pkgs.xclip}/bin/xclip -selection clipboard -t image/png -i
|
||||||
in mkIf cfg.enable {
|
'';
|
||||||
programs.dconf.enable = true;
|
in
|
||||||
|
mkIf cfg.enable {
|
||||||
|
programs.dconf.enable = true;
|
||||||
|
|
||||||
fonts.fontDir.enable = true;
|
fonts.fontDir.enable = true;
|
||||||
fonts.packages = with pkgs; [
|
fonts.packages = with pkgs; [
|
||||||
#uw-ttyp0
|
#uw-ttyp0
|
||||||
#corefonts
|
#corefonts
|
||||||
nerd-fonts.noto
|
nerd-fonts.noto
|
||||||
nerd-fonts.hack
|
nerd-fonts.hack
|
||||||
#noto-fonts
|
#noto-fonts
|
||||||
#noto-fonts-emoji
|
#noto-fonts-emoji
|
||||||
noto-fonts-cjk-sans
|
noto-fonts-cjk-sans
|
||||||
#font-awesome
|
#font-awesome
|
||||||
];
|
];
|
||||||
services.libinput = {
|
services.libinput = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
# disabling mouse acceleration
|
# disabling mouse acceleration
|
||||||
mouse = {
|
mouse = {
|
||||||
accelProfile = "flat";
|
accelProfile = "flat";
|
||||||
middleEmulation = false;
|
middleEmulation = false;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
programs.kdeconnect.enable = true;
|
||||||
programs.kdeconnect.enable = true;
|
networking.firewall = {
|
||||||
networking.firewall = {
|
enable = true;
|
||||||
enable = true;
|
allowedTCPPorts = [ 25565 53317 ]; # localsend
|
||||||
allowedTCPPorts = [ 25565 53317 ]; # localsend
|
allowedUDPPorts = [ 1194 53317 ]; # openvpn, localsend
|
||||||
allowedUDPPorts = [ 1194 53317 ]; # openvpn, localsend
|
allowedTCPPortRanges = [{
|
||||||
allowedTCPPortRanges = [{
|
from = 1714;
|
||||||
from = 1714;
|
to = 1764;
|
||||||
to = 1764;
|
} # KDE Connect
|
||||||
} # KDE Connect
|
|
||||||
];
|
];
|
||||||
allowedUDPPortRanges = [{
|
allowedUDPPortRanges = [{
|
||||||
from = 1714;
|
from = 1714;
|
||||||
to = 1764;
|
to = 1764;
|
||||||
} # KDE Connect
|
} # KDE Connect
|
||||||
];
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
#services.xserver.wacom.enable = true;
|
||||||
|
services.tumbler.enable = true; # for thumbnails
|
||||||
|
programs.file-roller.enable = true;
|
||||||
|
programs.thunar.enable = true;
|
||||||
|
programs.thunar.plugins = with pkgs.xfce; [
|
||||||
|
thunar-archive-plugin
|
||||||
|
thunar-volman
|
||||||
|
];
|
||||||
|
services.gvfs.enable = true; # for file manager, trash support, etc.
|
||||||
|
|
||||||
|
# List packages installed in system profile. To search, run:
|
||||||
|
# $ nix search wget
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
keepassxc
|
||||||
|
screenshot
|
||||||
|
wl-clipboard
|
||||||
|
xarchiver # archive tool
|
||||||
|
adwaita-icon-theme
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
#services.xserver.wacom.enable = true;
|
|
||||||
services.tumbler.enable = true; # for thumbnails
|
|
||||||
programs.file-roller.enable = true;
|
|
||||||
programs.thunar.enable = true;
|
|
||||||
programs.thunar.plugins = with pkgs.xfce; [
|
|
||||||
thunar-archive-plugin
|
|
||||||
thunar-volman
|
|
||||||
];
|
|
||||||
services.gvfs.enable = true; # for file manager, trash support, etc.
|
|
||||||
|
|
||||||
# List packages installed in system profile. To search, run:
|
|
||||||
# $ nix search wget
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
keepassxc
|
|
||||||
screenshot
|
|
||||||
wl-clipboard
|
|
||||||
xarchiver # archive tool
|
|
||||||
adwaita-icon-theme
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{lib, config, pkgs, ...}:
|
{ lib, config, pkgs, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.graphical.xfce;
|
cfg = config.custom.graphical.xfce;
|
||||||
@@ -7,10 +7,10 @@ in
|
|||||||
options.custom.graphical.xfce = {
|
options.custom.graphical.xfce = {
|
||||||
enable = mkEnableOption "Enables lxqt";
|
enable = mkEnableOption "Enables lxqt";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
services.xserver = {
|
services.xserver = {
|
||||||
xkb.layout = config.mainUser.layout;
|
xkb.layout = config.mainUser.layout;
|
||||||
xkb.variant = config.mainUser.variant;
|
xkb.variant = config.mainUser.variant;
|
||||||
enable = true;
|
enable = true;
|
||||||
desktopManager.xfce.enable = true;
|
desktopManager.xfce.enable = true;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{config, lib, ...}:
|
{ config, lib, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.hardware.firmware;
|
cfg = config.custom.hardware.firmware;
|
||||||
@@ -7,7 +7,7 @@ in
|
|||||||
options.custom.hardware.firmware = {
|
options.custom.hardware.firmware = {
|
||||||
enable = mkEnableOption "Enables firmware";
|
enable = mkEnableOption "Enables firmware";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
services.fwupd.enable = true;
|
services.fwupd.enable = true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,94 +28,97 @@ in {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = let
|
config =
|
||||||
# the option was renamed in unstable
|
let
|
||||||
nvidiaOption = if (pkgsVersion == inputs.nixpkgs-unstable) then {
|
# the option was renamed in unstable
|
||||||
hardware.graphics = {
|
nvidiaOption =
|
||||||
enable = true;
|
if (pkgsVersion == inputs.nixpkgs-unstable) then {
|
||||||
enable32Bit = true;
|
hardware.graphics = {
|
||||||
extraPackages = with pkgs; [ nvidia-vaapi-driver ];
|
enable = true;
|
||||||
};
|
enable32Bit = true;
|
||||||
} else {
|
extraPackages = with pkgs; [ nvidia-vaapi-driver ];
|
||||||
hardware.opengl = {
|
};
|
||||||
enable = true;
|
} else {
|
||||||
driSupport = true;
|
hardware.opengl = {
|
||||||
driSupport32Bit = true;
|
enable = true;
|
||||||
};
|
driSupport = true;
|
||||||
};
|
driSupport32Bit = true;
|
||||||
nvidia_oc = "${pkgs.nvidia_oc}/bin/nvidia_oc";
|
};
|
||||||
in lib.mkIf cfg.enable (lib.recursiveUpdate nvidiaOption {
|
};
|
||||||
boot.kernelParams =
|
nvidia_oc = "${pkgs.nvidia_oc}/bin/nvidia_oc";
|
||||||
[ "nvidia-drm.fbdev=1" "nvidia.NVreg_PreserveVideoMemoryAllocations=1" ];
|
in
|
||||||
services.xserver.videoDrivers = [ "nvidia" ];
|
lib.mkIf cfg.enable (lib.recursiveUpdate nvidiaOption {
|
||||||
services.xserver.deviceSection = ''
|
boot.kernelParams =
|
||||||
Option "Coolbits" "24"
|
[ "nvidia-drm.fbdev=1" "nvidia.NVreg_PreserveVideoMemoryAllocations=1" ];
|
||||||
'';
|
services.xserver.videoDrivers = [ "nvidia" ];
|
||||||
hardware.nvidia = {
|
services.xserver.deviceSection = ''
|
||||||
# Modesetting is required.
|
Option "Coolbits" "24"
|
||||||
modesetting.enable = true;
|
'';
|
||||||
# Open drivers with gsp stutters in VR - https://github.com/ValveSoftware/SteamVR-for-Linux/issues/631
|
hardware.nvidia = {
|
||||||
gsp.enable = config.hardware.nvidia.open;
|
# Modesetting is required.
|
||||||
# Nvidia power management. Experimental, and can cause sleep/suspend to fail.
|
modesetting.enable = true;
|
||||||
powerManagement.enable = false;
|
# Open drivers with gsp stutters in VR - https://github.com/ValveSoftware/SteamVR-for-Linux/issues/631
|
||||||
# Fine-grained power management. Turns off GPU when not in use.
|
gsp.enable = config.hardware.nvidia.open;
|
||||||
# Experimental and only works on modern Nvidia GPUs (Turing or newer).
|
# Nvidia power management. Experimental, and can cause sleep/suspend to fail.
|
||||||
powerManagement.finegrained = false;
|
powerManagement.enable = false;
|
||||||
# Use the NVidia open source kernel module (not to be confused with the
|
# Fine-grained power management. Turns off GPU when not in use.
|
||||||
# independent third-party "nouveau" open source driver).
|
# Experimental and only works on modern Nvidia GPUs (Turing or newer).
|
||||||
# Support is limited to the Turing and later architectures. Full list of
|
powerManagement.finegrained = false;
|
||||||
# supported GPUs is at:
|
# Use the NVidia open source kernel module (not to be confused with the
|
||||||
# https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus
|
# independent third-party "nouveau" open source driver).
|
||||||
# Only available from driver 515.43.04+
|
# Support is limited to the Turing and later architectures. Full list of
|
||||||
# GSP must be enabled for this to work.
|
# supported GPUs is at:
|
||||||
open = false;
|
# https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus
|
||||||
# Enable the Nvidia settings menu,
|
# Only available from driver 515.43.04+
|
||||||
# accessible via `nvidia-settings`.
|
# GSP must be enabled for this to work.
|
||||||
nvidiaSettings = true;
|
open = false;
|
||||||
# Optionally, you may need to select the appropriate driver version for your specific GPU.
|
# Enable the Nvidia settings menu,
|
||||||
|
# accessible via `nvidia-settings`.
|
||||||
|
nvidiaSettings = true;
|
||||||
|
# Optionally, you may need to select the appropriate driver version for your specific GPU.
|
||||||
#package = config.boot.kernelPackages.nvidiaPackages.beta;
|
#package = config.boot.kernelPackages.nvidiaPackages.beta;
|
||||||
package = config.boot.kernelPackages.nvidiaPackages.mkDriver {
|
package = config.boot.kernelPackages.nvidiaPackages.mkDriver {
|
||||||
version = "570.124.04";
|
version = "570.124.04";
|
||||||
sha256_64bit = "sha256-G3hqS3Ei18QhbFiuQAdoik93jBlsFI2RkWOBXuENU8Q=";
|
sha256_64bit = "sha256-G3hqS3Ei18QhbFiuQAdoik93jBlsFI2RkWOBXuENU8Q=";
|
||||||
sha256_aarch64 = "";
|
sha256_aarch64 = "";
|
||||||
openSha256 = "";
|
openSha256 = "";
|
||||||
settingsSha256 = "sha256-LNL0J/sYHD8vagkV1w8tb52gMtzj/F0QmJTV1cMaso8=";
|
settingsSha256 = "sha256-LNL0J/sYHD8vagkV1w8tb52gMtzj/F0QmJTV1cMaso8=";
|
||||||
persistencedSha256 = "";
|
persistencedSha256 = "";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
vaapiVdpau
|
vaapiVdpau
|
||||||
libvdpau-va-gl
|
libvdpau-va-gl
|
||||||
libva
|
libva
|
||||||
libva-utils
|
libva-utils
|
||||||
pkgs.nvidia_oc
|
pkgs.nvidia_oc
|
||||||
(gwe.override { nvidia_x11 = config.hardware.nvidia.package; })
|
(gwe.override { nvidia_x11 = config.hardware.nvidia.package; })
|
||||||
];
|
];
|
||||||
|
|
||||||
environment.sessionVariables = {
|
environment.sessionVariables = {
|
||||||
# for firefox, see https://github.com/elFarto/nvidia-vaapi-driver/#firefox
|
# for firefox, see https://github.com/elFarto/nvidia-vaapi-driver/#firefox
|
||||||
MOZ_DISABLE_RDD_SANDBOX = "1";
|
MOZ_DISABLE_RDD_SANDBOX = "1";
|
||||||
LIBVA_DRIVER_NAME = "nvidia";
|
LIBVA_DRIVER_NAME = "nvidia";
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.nvidiaSetPower = lib.mkIf cfg.powerLimit.enable {
|
systemd.services.nvidiaSetPower = lib.mkIf cfg.powerLimit.enable {
|
||||||
description =
|
description =
|
||||||
"Increase GPU power limit to ${toString cfg.powerLimit.wattage} watts";
|
"Increase GPU power limit to ${toString cfg.powerLimit.wattage} watts";
|
||||||
script = "/run/current-system/sw/bin/nvidia-smi -pl=${
|
script = "/run/current-system/sw/bin/nvidia-smi -pl=${
|
||||||
toString cfg.powerLimit.wattage
|
toString cfg.powerLimit.wattage
|
||||||
}";
|
}";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
};
|
};
|
||||||
systemd.services.nvidiaSetClocks = lib.mkIf cfg.clock.enable {
|
systemd.services.nvidiaSetClocks = lib.mkIf cfg.clock.enable {
|
||||||
description = "Set GPU clocks";
|
description = "Set GPU clocks";
|
||||||
script =
|
script =
|
||||||
"${nvidia_oc} set -i 0 --min-clock ${toString cfg.clock.min} --max-clock ${
|
"${nvidia_oc} set -i 0 --min-clock ${toString cfg.clock.min} --max-clock ${
|
||||||
toString cfg.clock.max
|
toString cfg.clock.max
|
||||||
} --freq-offset ${toString cfg.clock.offset}";
|
} --freq-offset ${toString cfg.clock.offset}";
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "network.target" ];
|
after = [ "network.target" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
{config, lib, ...}:
|
{ config, lib, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.hardware.scheduler;
|
cfg = config.custom.hardware.scheduler;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.custom.hardware.scheduler = {
|
options.custom.hardware.scheduler = {
|
||||||
enable = mkEnableOption "Enables scheduler";
|
enable = mkEnableOption "Enables scheduler";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
services.system76-scheduler = {
|
services.system76-scheduler = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
|
||||||
|
|
||||||
hardware.system76.enableAll = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
hardware.system76.enableAll = true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
{config, lib, ...}:
|
{ config, lib, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.hardware.ssd;
|
cfg = config.custom.hardware.ssd;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.custom.hardware.ssd = {
|
options.custom.hardware.ssd = {
|
||||||
enable = mkEnableOption "Enables fstrim";
|
enable = mkEnableOption "Enables fstrim";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
services.fstrim.enable = true;
|
services.fstrim.enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ in
|
|||||||
options.custom.hardware.vfio = {
|
options.custom.hardware.vfio = {
|
||||||
enable = mkEnableOption "Enables vfio";
|
enable = mkEnableOption "Enables vfio";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf (cfg.enable && config.virtualisation.libvirtd.enable) {
|
config = mkIf (cfg.enable && config.virtualisation.libvirtd.enable) {
|
||||||
boot.kernelParams = [ "amd_iommu=on" "iommu=pt" ];
|
boot.kernelParams = [ "amd_iommu=on" "iommu=pt" ];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,40 +1,42 @@
|
|||||||
{ config, pkgs, lib, ...}:
|
{ config, pkgs, lib, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.hardware.wooting;
|
cfg = config.custom.hardware.wooting;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.custom.hardware.wooting = {
|
options.custom.hardware.wooting = {
|
||||||
enable = mkEnableOption "Enable wooting hardware support";
|
enable = mkEnableOption "Enable wooting hardware support";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = let
|
config =
|
||||||
wooting-udev = pkgs.stdenv.mkDerivation rec {
|
let
|
||||||
pname = "wooting-udev-rules";
|
wooting-udev = pkgs.stdenv.mkDerivation rec {
|
||||||
version = "unstable-2023-03-31";
|
pname = "wooting-udev-rules";
|
||||||
|
version = "unstable-2023-03-31";
|
||||||
|
|
||||||
# Source: https://help.wooting.io/en/article/wootility-configuring-device-access-for-wootility-under-linux-udev-rules-r6lb2o/
|
# Source: https://help.wooting.io/en/article/wootility-configuring-device-access-for-wootility-under-linux-udev-rules-r6lb2o/
|
||||||
src = [ ./wooting.rules ];
|
src = [ ./wooting.rules ];
|
||||||
|
|
||||||
dontUnpack = true;
|
dontUnpack = true;
|
||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
install -Dpm644 $src $out/lib/udev/rules.d/70-wooting.rules
|
install -Dpm644 $src $out/lib/udev/rules.d/70-wooting.rules
|
||||||
'';
|
'';
|
||||||
|
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
homepage = "https://help.wooting.io/en/article/wootility-configuring-device-access-for-wootility-under-linux-udev-rules-r6lb2o/";
|
homepage = "https://help.wooting.io/en/article/wootility-configuring-device-access-for-wootility-under-linux-udev-rules-r6lb2o/";
|
||||||
description = "udev rules that give NixOS permission to communicate with Wooting keyboards";
|
description = "udev rules that give NixOS permission to communicate with Wooting keyboards";
|
||||||
platforms = platforms.linux;
|
platforms = platforms.linux;
|
||||||
license = "unknown";
|
license = "unknown";
|
||||||
maintainers = with maintainers; [ davidtwco ];
|
maintainers = with maintainers; [ davidtwco ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
in
|
||||||
in mkIf cfg.enable {
|
mkIf cfg.enable {
|
||||||
services.udev.packages = [ wooting-udev ];
|
services.udev.packages = [ wooting-udev ];
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
wootility
|
wootility
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{ pkgs, ...}:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
powerManagement.powerUpCommands = ''
|
powerManagement.powerUpCommands = ''
|
||||||
${pkgs.hdparm}/sbin/hdparm -B 127 /dev/sd[ab]
|
${pkgs.hdparm}/sbin/hdparm -B 127 /dev/sd[ab]
|
||||||
${pkgs.hdparm}/sbin/hdparm -S 120 /dev/sd[ab]
|
${pkgs.hdparm}/sbin/hdparm -S 120 /dev/sd[ab]
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,54 @@
|
|||||||
{ pkgs, config, ... }:
|
{ pkgs, config, ... }:
|
||||||
let
|
let
|
||||||
#amdgpu_module_pkg =
|
#amdgpu_module_pkg =
|
||||||
# { pkgs, lib, fetchurl, kernel ? pkgs.linuxPackages_latest.kernel, ... }:
|
# { pkgs, lib, fetchurl, kernel ? pkgs.linuxPackages_latest.kernel, ... }:
|
||||||
#
|
#
|
||||||
# pkgs.stdenv.mkDerivation {
|
# pkgs.stdenv.mkDerivation {
|
||||||
# pname = "amdgpu-kernel-module";
|
# pname = "amdgpu-kernel-module";
|
||||||
# inherit (kernel) version postPatch nativeBuildInputs;
|
# inherit (kernel) version postPatch nativeBuildInputs;
|
||||||
# src = fetchurl {
|
# src = fetchurl {
|
||||||
# url =
|
# url =
|
||||||
# "https://gitlab.freedesktop.org/agd5f/linux/-/archive/amd-drm-next-6.15-2025-03-14/linux-amd-drm-next-6.15-2025-03-14.tar.gz";
|
# "https://gitlab.freedesktop.org/agd5f/linux/-/archive/amd-drm-next-6.15-2025-03-14/linux-amd-drm-next-6.15-2025-03-14.tar.gz";
|
||||||
# # After the first build attempt, look for "hash mismatch" and then 2 lines below at the "got:" line.
|
# # After the first build attempt, look for "hash mismatch" and then 2 lines below at the "got:" line.
|
||||||
# # Use "sha256-....." value here.
|
# # Use "sha256-....." value here.
|
||||||
# hash = "sha256-/9EvJNBSKteXljrZzmaQkbZ7o4etCe0yFM3JJg/jD7o=";
|
# hash = "sha256-/9EvJNBSKteXljrZzmaQkbZ7o4etCe0yFM3JJg/jD7o=";
|
||||||
# };
|
# };
|
||||||
#
|
#
|
||||||
# kernel_dev = kernel.dev;
|
# kernel_dev = kernel.dev;
|
||||||
# kernelVersion = kernel.modDirVersion;
|
# kernelVersion = kernel.modDirVersion;
|
||||||
#
|
#
|
||||||
# modulePath = "drivers/gpu/drm/amd/amdgpu";
|
# modulePath = "drivers/gpu/drm/amd/amdgpu";
|
||||||
#
|
#
|
||||||
# buildPhase = ''
|
# buildPhase = ''
|
||||||
# BUILT_KERNEL=$kernel_dev/lib/modules/$kernelVersion/build
|
# BUILT_KERNEL=$kernel_dev/lib/modules/$kernelVersion/build
|
||||||
#
|
#
|
||||||
# cp $BUILT_KERNEL/Module.symvers .
|
# cp $BUILT_KERNEL/Module.symvers .
|
||||||
# cp $BUILT_KERNEL/.config .
|
# cp $BUILT_KERNEL/.config .
|
||||||
# cp $kernel_dev/vmlinux .
|
# cp $kernel_dev/vmlinux .
|
||||||
#
|
#
|
||||||
# make "-j$NIX_BUILD_CORES" modules_prepare
|
# make "-j$NIX_BUILD_CORES" modules_prepare
|
||||||
# make "-j$NIX_BUILD_CORES" M=$modulePath modules
|
# make "-j$NIX_BUILD_CORES" M=$modulePath modules
|
||||||
# '';
|
# '';
|
||||||
#
|
#
|
||||||
# installPhase = ''
|
# installPhase = ''
|
||||||
# make \
|
# make \
|
||||||
# INSTALL_MOD_PATH="$out" \
|
# INSTALL_MOD_PATH="$out" \
|
||||||
# XZ="xz -T$NIX_BUILD_CORES" \
|
# XZ="xz -T$NIX_BUILD_CORES" \
|
||||||
# M="$modulePath" \
|
# M="$modulePath" \
|
||||||
# modules_install
|
# modules_install
|
||||||
# '';
|
# '';
|
||||||
#
|
#
|
||||||
# meta = {
|
# meta = {
|
||||||
# description = "AMD GPU kernel module";
|
# description = "AMD GPU kernel module";
|
||||||
# license = lib.licenses.gpl3;
|
# license = lib.licenses.gpl3;
|
||||||
# };
|
# };
|
||||||
# };
|
# };
|
||||||
# amdgpu_module = pkgs.callPackage amdgpu_module_pkg {
|
# amdgpu_module = pkgs.callPackage amdgpu_module_pkg {
|
||||||
# kernel = config.boot.kernelPackages.kernel;
|
# kernel = config.boot.kernelPackages.kernel;
|
||||||
# };
|
# };
|
||||||
|
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
#boot.extraModulePackages = [ amdgpu_module ];
|
#boot.extraModulePackages = [ amdgpu_module ];
|
||||||
#boot.kernelPackages = pkgs.linuxPackages_latest;
|
#boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||||
#boot.kernelPackages = pkgs.linuxPackages_testing;
|
#boot.kernelPackages = pkgs.linuxPackages_testing;
|
||||||
@@ -62,24 +63,26 @@ in {
|
|||||||
# };
|
# };
|
||||||
#});
|
#});
|
||||||
|
|
||||||
boot.kernelPackages = let
|
boot.kernelPackages =
|
||||||
amd_drm_next_pkg = { fetchurl, buildLinux, ... }@args:
|
let
|
||||||
|
amd_drm_next_pkg = { fetchurl, buildLinux, ... }@args:
|
||||||
|
|
||||||
buildLinux (args // rec {
|
buildLinux (args // rec {
|
||||||
version = "6.14.0-rc4";
|
version = "6.14.0-rc4";
|
||||||
modDirVersion = version;
|
modDirVersion = version;
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url =
|
url =
|
||||||
"https://gitlab.freedesktop.org/agd5f/linux/-/archive/amd-drm-next-6.15-2025-03-14/linux-amd-drm-next-6.15-2025-03-14.tar.gz";
|
"https://gitlab.freedesktop.org/agd5f/linux/-/archive/amd-drm-next-6.15-2025-03-14/linux-amd-drm-next-6.15-2025-03-14.tar.gz";
|
||||||
# After the first build attempt, look for "hash mismatch" and then 2 lines below at the "got:" line.
|
# After the first build attempt, look for "hash mismatch" and then 2 lines below at the "got:" line.
|
||||||
# Use "sha256-....." value here.
|
# Use "sha256-....." value here.
|
||||||
hash = "sha256-/9EvJNBSKteXljrZzmaQkbZ7o4etCe0yFM3JJg/jD7o=";
|
hash = "sha256-/9EvJNBSKteXljrZzmaQkbZ7o4etCe0yFM3JJg/jD7o=";
|
||||||
};
|
};
|
||||||
kernelPatches = [ ];
|
kernelPatches = [ ];
|
||||||
|
|
||||||
extraMeta.branch = "6.14.0-rc4";
|
extraMeta.branch = "6.14.0-rc4";
|
||||||
} // (args.argsOverride or { }));
|
} // (args.argsOverride or { }));
|
||||||
linux_amd_drm_next = pkgs.callPackage amd_drm_next_pkg { };
|
linux_amd_drm_next = pkgs.callPackage amd_drm_next_pkg { };
|
||||||
in pkgs.recurseIntoAttrs (pkgs.linuxPackagesFor linux_amd_drm_next);
|
in
|
||||||
|
pkgs.recurseIntoAttrs (pkgs.linuxPackagesFor linux_amd_drm_next);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
services.journald.extraConfig = "SystemMaxUse=4G";
|
services.journald.extraConfig = "SystemMaxUse=4G";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,75 +4,77 @@ let
|
|||||||
cfg = config.custom.misc.backup;
|
cfg = config.custom.misc.backup;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.custom.misc.backup = {
|
options.custom.misc.backup = {
|
||||||
enable = mkEnableOption "Enables backup";
|
enable = mkEnableOption "Enables backup";
|
||||||
small = lib.mkOption {
|
small = lib.mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
description = "paths to include in the small backup";
|
description = "paths to include in the small backup";
|
||||||
};
|
};
|
||||||
medium = lib.mkOption {
|
medium = lib.mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = cfg.small;
|
default = cfg.small;
|
||||||
description = "paths to include in the medium backup";
|
description = "paths to include in the medium backup";
|
||||||
};
|
};
|
||||||
large = lib.mkOption {
|
large = lib.mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = cfg.small // cfg.medium;
|
default = cfg.small // cfg.medium;
|
||||||
description = "paths to include in the large backup";
|
description = "paths to include in the large backup";
|
||||||
};
|
};
|
||||||
excludePaths = lib.mkOption {
|
excludePaths = lib.mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [ "**/Cache" "**/.cache" "**/__pycache__" "**/node_modules" "**/venv" "*.o" "*.out"];
|
default = [ "**/Cache" "**/.cache" "**/__pycache__" "**/node_modules" "**/venv" "*.o" "*.out" ];
|
||||||
description = "paths to exclude from the backup";
|
description = "paths to exclude from the backup";
|
||||||
};
|
};
|
||||||
excludePathsRemote = lib.mkOption {
|
excludePathsRemote = lib.mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = cfg.excludePaths ++ [ "**/dont_remotebackup"];
|
default = cfg.excludePaths ++ [ "**/dont_remotebackup" ];
|
||||||
description = "paths to exclude from the remote backup";
|
description = "paths to exclude from the remote backup";
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = let
|
|
||||||
checkStorageSpace = pkgs.writeShellApplication {
|
|
||||||
name = "checkBackupStorageSpace";
|
|
||||||
text = ''
|
|
||||||
# Check how much space is used by the backup paths
|
|
||||||
echo "Checking storage space (small) with excluded paths..."
|
|
||||||
du -sch ${builtins.concatStringsSep " " (map (x: "--exclude=" + x) cfg.excludePaths)} ${builtins.concatStringsSep " " cfg.small}
|
|
||||||
echo "Checking storage space (small) with excluded paths (remote)..."
|
|
||||||
du -sch ${builtins.concatStringsSep " " (map (x: "--exclude=" + x) cfg.excludePathsRemote)} ${builtins.concatStringsSep " " cfg.small}
|
|
||||||
echo "Checking storage space (medium) with excluded paths..."
|
|
||||||
du -sch ${builtins.concatStringsSep " " (map (x: "--exclude=" + x) cfg.excludePaths)} ${builtins.concatStringsSep " " cfg.medium}
|
|
||||||
echo "Checking storage space (medium) with excluded paths (remote)..."
|
|
||||||
du -sch ${builtins.concatStringsSep " " (map (x: "--exclude=" + x) cfg.excludePathsRemote)} ${builtins.concatStringsSep " " cfg.medium}
|
|
||||||
echo "Checking storage space (full) with excluded paths..."
|
|
||||||
du -sch ${builtins.concatStringsSep " " (map (x: "--exclude=" + x) cfg.excludePaths)} ${builtins.concatStringsSep " " cfg.large}
|
|
||||||
echo "Checking storage space (full) with excluded paths (remote)..."
|
|
||||||
du -sch ${builtins.concatStringsSep " " (map (x: "--exclude=" + x) cfg.excludePathsRemote)} ${builtins.concatStringsSep " " cfg.large}
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
in mkIf cfg.enable {
|
|
||||||
environment.systemPackages = with pkgs; [ checkStorageSpace ];
|
|
||||||
age.secrets.restic-pw = {
|
|
||||||
file = ../../secrets/restic-pw.age;
|
|
||||||
};
|
};
|
||||||
age.secrets.restic-s3 = {
|
|
||||||
file = ../../secrets/restic-s3.age;
|
config =
|
||||||
};
|
let
|
||||||
age.secrets.restic-gdrive = {
|
checkStorageSpace = pkgs.writeShellApplication {
|
||||||
file = ../../secrets/restic-gdrive.age;
|
name = "checkBackupStorageSpace";
|
||||||
};
|
text = ''
|
||||||
services.restic = {
|
# Check how much space is used by the backup paths
|
||||||
backups = {
|
echo "Checking storage space (small) with excluded paths..."
|
||||||
#localbackup = {
|
du -sch ${builtins.concatStringsSep " " (map (x: "--exclude=" + x) cfg.excludePaths)} ${builtins.concatStringsSep " " cfg.small}
|
||||||
# initialize = true;
|
echo "Checking storage space (small) with excluded paths (remote)..."
|
||||||
# passwordFile = config.age.secrets.restic-pw.path;
|
du -sch ${builtins.concatStringsSep " " (map (x: "--exclude=" + x) cfg.excludePathsRemote)} ${builtins.concatStringsSep " " cfg.small}
|
||||||
# exclude = cfg.excludePaths;
|
echo "Checking storage space (medium) with excluded paths..."
|
||||||
# paths = cfg.large;
|
du -sch ${builtins.concatStringsSep " " (map (x: "--exclude=" + x) cfg.excludePaths)} ${builtins.concatStringsSep " " cfg.medium}
|
||||||
# pruneOpts = [ "--keep-daily 7" "--keep-weekly 3" "--keep-monthly 3" "--keep-yearly 3" ];
|
echo "Checking storage space (medium) with excluded paths (remote)..."
|
||||||
# repository = "/mnt/2tb/restic";
|
du -sch ${builtins.concatStringsSep " " (map (x: "--exclude=" + x) cfg.excludePathsRemote)} ${builtins.concatStringsSep " " cfg.medium}
|
||||||
#};
|
echo "Checking storage space (full) with excluded paths..."
|
||||||
localbackup-1tb-ssd = {
|
du -sch ${builtins.concatStringsSep " " (map (x: "--exclude=" + x) cfg.excludePaths)} ${builtins.concatStringsSep " " cfg.large}
|
||||||
|
echo "Checking storage space (full) with excluded paths (remote)..."
|
||||||
|
du -sch ${builtins.concatStringsSep " " (map (x: "--exclude=" + x) cfg.excludePathsRemote)} ${builtins.concatStringsSep " " cfg.large}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
mkIf cfg.enable {
|
||||||
|
environment.systemPackages = with pkgs; [ checkStorageSpace ];
|
||||||
|
age.secrets.restic-pw = {
|
||||||
|
file = ../../secrets/restic-pw.age;
|
||||||
|
};
|
||||||
|
age.secrets.restic-s3 = {
|
||||||
|
file = ../../secrets/restic-s3.age;
|
||||||
|
};
|
||||||
|
age.secrets.restic-gdrive = {
|
||||||
|
file = ../../secrets/restic-gdrive.age;
|
||||||
|
};
|
||||||
|
services.restic = {
|
||||||
|
backups = {
|
||||||
|
#localbackup = {
|
||||||
|
# initialize = true;
|
||||||
|
# passwordFile = config.age.secrets.restic-pw.path;
|
||||||
|
# exclude = cfg.excludePaths;
|
||||||
|
# paths = cfg.large;
|
||||||
|
# pruneOpts = [ "--keep-daily 7" "--keep-weekly 3" "--keep-monthly 3" "--keep-yearly 3" ];
|
||||||
|
# repository = "/mnt/2tb/restic";
|
||||||
|
#};
|
||||||
|
localbackup-1tb-ssd = {
|
||||||
initialize = true;
|
initialize = true;
|
||||||
passwordFile = config.age.secrets.restic-pw.path;
|
passwordFile = config.age.secrets.restic-pw.path;
|
||||||
exclude = cfg.excludePaths;
|
exclude = cfg.excludePaths;
|
||||||
@@ -83,33 +85,33 @@ in mkIf cfg.enable {
|
|||||||
};
|
};
|
||||||
pruneOpts = [ "--keep-daily 7" "--keep-weekly 3" "--keep-monthly 3" "--keep-yearly 3" ];
|
pruneOpts = [ "--keep-daily 7" "--keep-weekly 3" "--keep-monthly 3" "--keep-yearly 3" ];
|
||||||
repository = "/1tbssd/restic";
|
repository = "/1tbssd/restic";
|
||||||
};
|
};
|
||||||
#localbackup-1tb = {
|
#localbackup-1tb = {
|
||||||
# initialize = true;
|
# initialize = true;
|
||||||
# passwordFile = config.age.secrets.restic-pw.path;
|
# passwordFile = config.age.secrets.restic-pw.path;
|
||||||
# exclude = cfg.excludePaths;
|
# exclude = cfg.excludePaths;
|
||||||
# paths = cfg.large;
|
# paths = cfg.large;
|
||||||
# repository = "/mnt/1tb/restic";
|
# repository = "/mnt/1tb/restic";
|
||||||
# pruneOpts = [ "--keep-daily 5" "--keep-weekly 3" "--keep-monthly 3" "--keep-yearly 3" ];
|
# pruneOpts = [ "--keep-daily 5" "--keep-weekly 3" "--keep-monthly 3" "--keep-yearly 3" ];
|
||||||
# timerConfig = {
|
# timerConfig = {
|
||||||
# OnCalendar = "*-*-03,06,09,12,15,18,21,24,27,30 02:00:00";
|
# OnCalendar = "*-*-03,06,09,12,15,18,21,24,27,30 02:00:00";
|
||||||
# Persistent = true;
|
# Persistent = true;
|
||||||
# };
|
# };
|
||||||
#};
|
#};
|
||||||
remotebackup-gdrive = {
|
remotebackup-gdrive = {
|
||||||
initialize = true;
|
initialize = true;
|
||||||
passwordFile = config.age.secrets.restic-pw.path;
|
passwordFile = config.age.secrets.restic-pw.path;
|
||||||
exclude = cfg.excludePathsRemote;
|
exclude = cfg.excludePathsRemote;
|
||||||
paths = cfg.medium;
|
paths = cfg.medium;
|
||||||
rcloneConfigFile = config.age.secrets.restic-gdrive.path;
|
rcloneConfigFile = config.age.secrets.restic-gdrive.path;
|
||||||
repository = "rclone:it-experts:backup";
|
repository = "rclone:it-experts:backup";
|
||||||
pruneOpts = [ "--keep-daily 5" "--keep-weekly 3" "--keep-monthly 3" "--keep-yearly 3" ];
|
pruneOpts = [ "--keep-daily 5" "--keep-weekly 3" "--keep-monthly 3" "--keep-yearly 3" ];
|
||||||
timerConfig = {
|
timerConfig = {
|
||||||
OnCalendar = "*-*-03,06,09,12,15,18,21,24,27,30 02:00:00";
|
OnCalendar = "*-*-03,06,09,12,15,18,21,24,27,30 02:00:00";
|
||||||
Persistent = true;
|
Persistent = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
remotebackup = {
|
remotebackup = {
|
||||||
initialize = true;
|
initialize = true;
|
||||||
passwordFile = config.age.secrets.restic-pw.path;
|
passwordFile = config.age.secrets.restic-pw.path;
|
||||||
environmentFile = config.age.secrets.restic-s3.path;
|
environmentFile = config.age.secrets.restic-s3.path;
|
||||||
@@ -121,8 +123,8 @@ in mkIf cfg.enable {
|
|||||||
Persistent = true;
|
Persistent = true;
|
||||||
};
|
};
|
||||||
repository = "s3:s3.us-west-002.backblazeb2.com/kop-bucket";
|
repository = "s3:s3.us-west-002.backblazeb2.com/kop-bucket";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{config, lib, ...}:
|
{ config, lib, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.misc.btrfs;
|
cfg = config.custom.misc.btrfs;
|
||||||
@@ -7,7 +7,7 @@ in
|
|||||||
options.custom.misc.btrfs = {
|
options.custom.misc.btrfs = {
|
||||||
enable = mkEnableOption "Enables btrfs scrubbing";
|
enable = mkEnableOption "Enables btrfs scrubbing";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
services.btrfs.autoScrub.enable = true;
|
services.btrfs.autoScrub.enable = true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,83 +4,85 @@ let cfg = config.custom.cli-tools;
|
|||||||
in {
|
in {
|
||||||
options.custom.cli-tools = { enable = mkEnableOption "Enables cli-tools"; };
|
options.custom.cli-tools = { enable = mkEnableOption "Enables cli-tools"; };
|
||||||
|
|
||||||
config = let
|
config =
|
||||||
getTotalPowerUsed = pkgs.writeShellScriptBin "total-power" ''
|
let
|
||||||
echo "$(sudo cat /sys/class/powercap/*/energy_uj | awk 'BEGIN { sum = 0; } { sum += $1; } END { print sum; }' "$@") / 1000000" | bc | xargs -I _ echo "_ W"
|
getTotalPowerUsed = pkgs.writeShellScriptBin "total-power" ''
|
||||||
'';
|
echo "$(sudo cat /sys/class/powercap/*/energy_uj | awk 'BEGIN { sum = 0; } { sum += $1; } END { print sum; }' "$@") / 1000000" | bc | xargs -I _ echo "_ W"
|
||||||
watchCurrentPowerUsed = pkgs.writeShellScriptBin "watch-current-power" ''
|
'';
|
||||||
function getCurrentPowerUsed() {
|
watchCurrentPowerUsed = pkgs.writeShellScriptBin "watch-current-power" ''
|
||||||
local energy_uj=$(sudo cat $energy_path | awk 'BEGIN { sum = 0; } { sum += $1; } END { print sum; }' "$@")
|
function getCurrentPowerUsed() {
|
||||||
echo "scale=2; $energy_uj / 1000000" | bc
|
local energy_uj=$(sudo cat $energy_path | awk 'BEGIN { sum = 0; } { sum += $1; } END { print sum; }' "$@")
|
||||||
}
|
echo "scale=2; $energy_uj / 1000000" | bc
|
||||||
|
}
|
||||||
|
|
||||||
energy_path=$(grep package /sys/class/powercap/*/name | sed 's/name.*$/energy_uj/')
|
energy_path=$(grep package /sys/class/powercap/*/name | sed 's/name.*$/energy_uj/')
|
||||||
power_prev=0
|
power_prev=0
|
||||||
power_curr=$(getCurrentPowerUsed)
|
|
||||||
while true; do
|
|
||||||
power_prev=$power_curr
|
|
||||||
sleep 1
|
|
||||||
power_curr=$(getCurrentPowerUsed)
|
power_curr=$(getCurrentPowerUsed)
|
||||||
echo "scale=2; ($power_curr - $power_prev) / 1" | bc | xargs -I _ echo "_ W"
|
while true; do
|
||||||
done
|
power_prev=$power_curr
|
||||||
'';
|
sleep 1
|
||||||
in mkIf cfg.enable {
|
power_curr=$(getCurrentPowerUsed)
|
||||||
environment.systemPackages = with pkgs; [
|
echo "scale=2; ($power_curr - $power_prev) / 1" | bc | xargs -I _ echo "_ W"
|
||||||
getTotalPowerUsed
|
done
|
||||||
watchCurrentPowerUsed
|
'';
|
||||||
(if lib.versionOlder lib.version "25.05" then
|
in
|
||||||
|
mkIf cfg.enable {
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
getTotalPowerUsed
|
||||||
|
watchCurrentPowerUsed
|
||||||
|
(if lib.versionOlder lib.version "25.05" then
|
||||||
|
wget
|
||||||
|
else
|
||||||
|
powerjoular) # monitor power usage
|
||||||
|
fzf # fuzzy finder
|
||||||
|
bat # fancy cat
|
||||||
|
fd # nicer find
|
||||||
|
duf # nicer du
|
||||||
|
eza # nicer ls
|
||||||
|
ripgrep # faster grep
|
||||||
|
gdu
|
||||||
wget
|
wget
|
||||||
else
|
pciutils
|
||||||
powerjoular) # monitor power usage
|
rippkgs # faster nixpkgs search, init with `rippkgs-index nixpkgs && mv rippkgs-index.sqlite ~/.local/share/`;
|
||||||
fzf # fuzzy finder
|
nixos-option
|
||||||
bat # fancy cat
|
btop
|
||||||
fd # nicer find
|
git
|
||||||
duf # nicer du
|
gh # github
|
||||||
eza # nicer ls
|
killall
|
||||||
ripgrep # faster grep
|
xclip
|
||||||
gdu
|
usbutils
|
||||||
wget
|
inputs.agenix.packages."x86_64-linux".default
|
||||||
pciutils
|
fastfetch
|
||||||
rippkgs # faster nixpkgs search, init with `rippkgs-index nixpkgs && mv rippkgs-index.sqlite ~/.local/share/`;
|
pdfgrep
|
||||||
nixos-option
|
glxinfo
|
||||||
btop
|
vulkan-tools
|
||||||
git
|
ffmpeg
|
||||||
gh # github
|
nethogs
|
||||||
killall
|
dig
|
||||||
xclip
|
smartmontools
|
||||||
usbutils
|
bc
|
||||||
inputs.agenix.packages."x86_64-linux".default
|
xxd
|
||||||
fastfetch
|
tldr
|
||||||
pdfgrep
|
file
|
||||||
glxinfo
|
unzip
|
||||||
vulkan-tools
|
lsof
|
||||||
ffmpeg
|
lshw
|
||||||
nethogs
|
screen
|
||||||
dig
|
tmux
|
||||||
smartmontools
|
fatrace # monitor filesystem events
|
||||||
bc
|
nh
|
||||||
xxd
|
nix-output-monitor # nom
|
||||||
tldr
|
nvd # nix diff, example: nvd diff /nix/var/nix/profiles/system-389-link /nix/var/nix/profiles/system-390-link
|
||||||
file
|
compsize
|
||||||
unzip
|
trashy # move files to trash
|
||||||
lsof
|
shell-gpt
|
||||||
lshw
|
libheif # convert heic to jpg with `heif-convert something.heic something.jpg`
|
||||||
screen
|
imagemagick # convert images
|
||||||
tmux
|
tree
|
||||||
fatrace # monitor filesystem events
|
kop-newproject # creates a shell.nix and .envrc
|
||||||
nh
|
nix-tree # show nix derivations
|
||||||
nix-output-monitor # nom
|
binwalk # show what's inside a binary
|
||||||
nvd # nix diff, example: nvd diff /nix/var/nix/profiles/system-389-link /nix/var/nix/profiles/system-390-link
|
iotop
|
||||||
compsize
|
];
|
||||||
trashy # move files to trash
|
};
|
||||||
shell-gpt
|
|
||||||
libheif # convert heic to jpg with `heif-convert something.heic something.jpg`
|
|
||||||
imagemagick # convert images
|
|
||||||
tree
|
|
||||||
kop-newproject # creates a shell.nix and .envrc
|
|
||||||
nix-tree # show nix derivations
|
|
||||||
binwalk # show what's inside a binary
|
|
||||||
iotop
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, config, ...}:
|
{ pkgs, config, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./packages-list.nix
|
./packages-list.nix
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ in
|
|||||||
virtualisation.docker.enable = true;
|
virtualisation.docker.enable = true;
|
||||||
virtualisation.docker.daemon.settings = { ip = "127.0.0.1"; };
|
virtualisation.docker.daemon.settings = { ip = "127.0.0.1"; };
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
docker-compose
|
docker-compose
|
||||||
];
|
];
|
||||||
hardware.nvidia-container-toolkit.enable = lib.mkIf config.custom.hardware.nvidia.enable true;
|
hardware.nvidia-container-toolkit.enable = lib.mkIf config.custom.hardware.nvidia.enable true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ lib, pkgs, config, ... }: {
|
{ lib, pkgs, config, ... }: {
|
||||||
# before: Startup finished in 18.830s (firmware) + 5.844s (loader) + 4.422s (kernel) + 7.616s (userspace) = 36.713s
|
# before: Startup finished in 18.830s (firmware) + 5.844s (loader) + 4.422s (kernel) + 7.616s (userspace) = 36.713s
|
||||||
# after: Startup finished in 14.115s (firmware) + 789ms (loader) + 4.312s (kernel) + 5.777s (userspace) = 24.995s
|
# after: Startup finished in 14.115s (firmware) + 789ms (loader) + 4.312s (kernel) + 5.777s (userspace) = 24.995s
|
||||||
systemd = {
|
systemd = {
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
{config, lib, ...}:
|
{ config, lib, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.nftables;
|
cfg = config.custom.nftables;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.custom.nftables = {
|
options.custom.nftables = {
|
||||||
enable = mkEnableOption "Enables nftables";
|
enable = mkEnableOption "Enables nftables";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
networking.nftables.enable = true;
|
networking.nftables.enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
{ config, pkgs, ... }: {
|
{ config, pkgs, ... }: {
|
||||||
environment.etc."current-system-packages".text = let
|
environment.etc."current-system-packages".text =
|
||||||
packages = builtins.map (p: "${p.name}") config.environment.systemPackages;
|
let
|
||||||
sortedUnique =
|
packages = builtins.map (p: "${p.name}") config.environment.systemPackages;
|
||||||
builtins.sort builtins.lessThan (pkgs.lib.lists.unique packages);
|
sortedUnique =
|
||||||
formatted = builtins.concatStringsSep "\n" sortedUnique;
|
builtins.sort builtins.lessThan (pkgs.lib.lists.unique packages);
|
||||||
in formatted;
|
formatted = builtins.concatStringsSep "\n" sortedUnique;
|
||||||
|
in
|
||||||
|
formatted;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,27 +22,28 @@ in {
|
|||||||
description = "Default gateway";
|
description = "Default gateway";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = let fallback = "1.1.1.1";
|
config =
|
||||||
in mkIf cfg.enable {
|
let fallback = "1.1.1.1";
|
||||||
networking = {
|
in mkIf cfg.enable {
|
||||||
defaultGateway = cfg.gateway;
|
networking = {
|
||||||
useDHCP = false;
|
defaultGateway = cfg.gateway;
|
||||||
nameservers = [ cfg.dns ]
|
useDHCP = false;
|
||||||
++ lib.lists.optionals (!config.services.resolved.enable) [ fallback ];
|
nameservers = [ cfg.dns ]
|
||||||
interfaces = {
|
++ lib.lists.optionals (!config.services.resolved.enable) [ fallback ];
|
||||||
${cfg.interface} = {
|
interfaces = {
|
||||||
name = "eth0";
|
${cfg.interface} = {
|
||||||
ipv4.addresses = [{
|
name = "eth0";
|
||||||
address = cfg.ip;
|
ipv4.addresses = [{
|
||||||
prefixLength = 24;
|
address = cfg.ip;
|
||||||
}];
|
prefixLength = 24;
|
||||||
|
}];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
services.resolved = lib.mkIf config.services.resolved.enable {
|
services.resolved = lib.mkIf config.services.resolved.enable {
|
||||||
llmnr = "false";
|
llmnr = "false";
|
||||||
fallbackDns = [ "1.1.1.1" ];
|
fallbackDns = [ "1.1.1.1" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
{config, lib, ...}:
|
{ config, lib, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.tmpfs;
|
cfg = config.custom.tmpfs;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.custom.tmpfs = {
|
options.custom.tmpfs = {
|
||||||
enable = mkEnableOption "Enables tmpfs";
|
enable = mkEnableOption "Enables tmpfs";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
boot.tmp.useTmpfs = true;
|
boot.tmp.useTmpfs = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
{lib, config, pkgs, ... }:
|
{ lib, config, pkgs, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.wireshark;
|
cfg = config.custom.wireshark;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.custom.wireshark = {
|
options.custom.wireshark = {
|
||||||
enable = mkEnableOption "Enables wireshark";
|
enable = mkEnableOption "Enables wireshark";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
programs.wireshark.enable = true;
|
programs.wireshark.enable = true;
|
||||||
programs.wireshark.package = pkgs.wireshark;
|
programs.wireshark.package = pkgs.wireshark;
|
||||||
|
|
||||||
users.users.${config.mainUser.name}.extraGroups = [ "wireshark" ];
|
users.users.${config.mainUser.name}.extraGroups = [ "wireshark" ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,52 +1,52 @@
|
|||||||
{
|
{
|
||||||
users.motd = ''
|
users.motd = ''
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣴⣾⣿⣿⣿⣿⣿⠟⡅⠠⢀⢠⡾⠋⠀⣀⣠⣴⠶⠛⠋⠉⢀⣀⣠⡴⠋⠁⡆⢌⠉⠙⢦⠀⠀⠈⠉⠉⠉⠓⠫⢝⡓⠦⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣴⣾⣿⣿⣿⣿⣿⠟⡅⠠⢀⢠⡾⠋⠀⣀⣠⣴⠶⠛⠋⠉⢀⣀⣠⡴⠋⠁⡆⢌⠉⠙⢦⠀⠀⠈⠉⠉⠉⠓⠫⢝⡓⠦⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣠⣄⣤⣤⣤⣤⣤⣤⣤⣴⣾⣿⢿⣻⣿⣿⣿⡿⠟⣱⠃⡄⢣⣰⣿⣗⣾⡿⠟⠉⠀⣀⠤⠒⠉⠁⣼⠋⠀⠀⢸⠀⠈⣆⠀⠀⠳⣤⣀⠀⠀⠀⠀⠀⠀⠈⠀⣀⣙⣻⣶⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣠⣄⣤⣤⣤⣤⣤⣤⣤⣴⣾⣿⢿⣻⣿⣿⣿⡿⠟⣱⠃⡄⢣⣰⣿⣗⣾⡿⠟⠉⠀⣀⠤⠒⠉⠁⣼⠋⠀⠀⢸⠀⠈⣆⠀⠀⠳⣤⣀⠀⠀⠀⠀⠀⠀⠈⠀⣀⣙⣻⣶⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⢃⣤⣼⣦⣷⣮⣷⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⠉⣠⡾⢡⠚⡤⣷⡿⣻⠟⠉⣀⣤⠞⠋⠀⠀⠀⠀⣼⢻⠀⠀⠀⠈⠀⠀⢸⡄⠀⠀⢣⠀⠉⠒⠶⣶⣿⣍⣉⣭⣡⣤⠀⠉⠛⢿⣷⣦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⢃⣤⣼⣦⣷⣮⣷⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⠉⣠⡾⢡⠚⡤⣷⡿⣻⠟⠉⣀⣤⠞⠋⠀⠀⠀⠀⣼⢻⠀⠀⠀⠈⠀⠀⢸⡄⠀⠀⢣⠀⠉⠒⠶⣶⣿⣍⣉⣭⣡⣤⠀⠉⠛⢿⣷⣦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡿⢠⣿⣟⣿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠚⠁⠀⢀⣴⡟⡔⣣⢹⣼⣿⠞⢁⣠⡾⠋⠀⠀⠀⠀⢀⣤⢾⠃⡏⠀⠀⠀⠀⠀⠀⠀⡇⢀⠀⠘⣦⠀⠀⠀⢄⠙⠺⣿⢿⣿⣿⣧⠀⢀⠀⠙⢮⡳⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡿⢠⣿⣟⣿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠚⠁⠀⢀⣴⡟⡔⣣⢹⣼⣿⠞⢁⣠⡾⠋⠀⠀⠀⠀⢀⣤⢾⠃⡏⠀⠀⠀⠀⠀⠀⠀⡇⢀⠀⠘⣦⠀⠀⠀⢄⠙⠺⣿⢿⣿⣿⣧⠀⢀⠀⠙⢮⡳⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⣧⢣⣿⣿⢾⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡞⠛⠛⠛⠙⢻⠟⣀⣴⠟⠋⠀⠀⣠⡴⠊⣡⠞⠁⡟⢰⠁⠀⠀⠀⠀⠀⠀⠀⡇⢈⠆⠀⢿⡀⠀⠀⠀⠑⡀⠀⠙⠽⢿⣿⣧⠀⠣⠀⠀⠙⢶⡹⢷⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⣧⢣⣿⣿⢾⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡞⠛⠛⠛⠙⢻⠟⣀⣴⠟⠋⠀⠀⣠⡴⠊⣡⠞⠁⡟⢰⠁⠀⠀⠀⠀⠀⠀⠀⡇⢈⠆⠀⢿⡀⠀⠀⠀⠑⡀⠀⠙⠽⢿⣿⣧⠀⠣⠀⠀⠙⢶⡹⢷⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠊⠀⢹⣯⢿⣿⣻⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⡀⠀⠀⠀⠀⢧⡽⠋⠀⠀⡠⠊⠁⠀⡴⠃⠀⠀⡇⠸⠀⠀⠀⠀⠀⠀⠀⠀⡜⢸⢠⠀⡘⢷⡀⠀⠀⠠⡈⠆⠀⠀⠀⠘⢿⣧⠰⠁⠀⠀⠀⠙⢮⣳⢧⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠊⠀⢹⣯⢿⣿⣻⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⡀⠀⠀⠀⠀⢧⡽⠋⠀⠀⡠⠊⠁⠀⡴⠃⠀⠀⡇⠸⠀⠀⠀⠀⠀⠀⠀⠀⡜⢸⢠⠀⡘⢷⡀⠀⠀⠠⡈⠆⠀⠀⠀⠘⢿⣧⠰⠁⠀⠀⠀⠙⢮⣳⢧⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣶⣷⡀⠀⠀⠀⠸⡀⡀⡰⠊⠀⠀⢀⠞⠀⠀⠀⠈⡇⠘⠀⠀⠀⠀⠀⠀⠀⠀⡇⣼⠎⠀⡅⠈⢳⡀⠀⠀⠈⠻⣄⠀⠀⠀⠸⣿⡄⢣⠀⠀⠀⠀⠈⠻⣦⡈⠑⠒⢤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣶⣷⡀⠀⠀⠀⠸⡀⡀⡰⠊⠀⠀⢀⠞⠀⠀⠀⠈⡇⠘⠀⠀⠀⠀⠀⠀⠀⠀⡇⣼⠎⠀⡅⠈⢳⡀⠀⠀⠈⠻⣄⠀⠀⠀⠸⣿⡄⢣⠀⠀⠀⠀⠈⠻⣦⡈⠑⠒⢤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢄⠀⠀⣰⣿⣿⣿⣿⣿⠟⠀⠀⠀⠀⠀⠀⢀⣀⣴⣮⡿⣿⣿⣷⠀⠀⠀⠘⣿⠚⠀⠀⠀⢠⠋⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⣸⣷⡇⠀⢀⡇⠀⡀⢳⡀⠀⠀⠀⠈⠢⡀⠀⠀⣿⣧⠈⣧⠀⠀⠀⠀⠀⠙⢿⣦⡀⠀⠙⠗⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢄⠀⠀⣰⣿⣿⣿⣿⣿⠟⠀⠀⠀⠀⠀⠀⢀⣀⣴⣮⡿⣿⣿⣷⠀⠀⠀⠘⣿⠚⠀⠀⠀⢠⠋⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⣸⣷⡇⠀⢀⡇⠀⡀⢳⡀⠀⠀⠀⠈⠢⡀⠀⠀⣿⣧⠈⣧⠀⠀⠀⠀⠀⠙⢿⣦⡀⠀⠙⠗⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢦⣴⡿⣽⣿⣿⣿⡟⠀⠠⠤⠤⠤⣴⣶⣾⣿⡿⠟⣡⠿⣿⣿⣆⠀⠀⠀⢻⡆⠀⠀⠀⡜⢢⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⣠⡿⡻⠁⠀⣼⠃⠀⠱⡈⢇⠀⠀⠀⠀⠀⠳⡀⠀⢹⣿⠀⢻⡆⠀⠀⠀⠀⢀⠈⠻⣷⣄⠀⠀⠙⢅⠢⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢦⣴⡿⣽⣿⣿⣿⡟⠀⠠⠤⠤⠤⣴⣶⣾⣿⡿⠟⣡⠿⣿⣿⣆⠀⠀⠀⢻⡆⠀⠀⠀⡜⢢⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⣠⡿⡻⠁⠀⣼⠃⠀⠱⡈⢇⠀⠀⠀⠀⠀⠳⡀⠀⢹⣿⠀⢻⡆⠀⠀⠀⠀⢀⠈⠻⣷⣄⠀⠀⠙⢅⠢⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣽⣿⣿⣿⣿⣴⣶⣶⣾⣿⡿⢟⡹⣿⣯⣤⣾⣁⡀⡽⣿⣿⣄⠀⠀⠀⢿⡀⠀⡜⠀⠠⡙⠦⣄⡀⠀⣧⠀⠀⠀⠀⣀⠠⠞⢉⠜⠁⠀⢰⠏⡠⠀⠀⢱⠈⡄⠀⠀⠀⠀⠀⠘⢄⢸⣿⡀⠘⠻⡄⠀⠀⠀⠈⡄⠀⢻⣿⡻⢦⡀⠀⠑⢌⠢⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣽⣿⣿⣿⣿⣴⣶⣶⣾⣿⡿⢟⡹⣿⣯⣤⣾⣁⡀⡽⣿⣿⣄⠀⠀⠀⢿⡀⠀⡜⠀⠠⡙⠦⣄⡀⠀⣧⠀⠀⠀⠀⣀⠠⠞⢉⠜⠁⠀⢰⠏⡠⠀⠀⢱⠈⡄⠀⠀⠀⠀⠀⠘⢄⢸⣿⡀⠘⠻⡄⠀⠀⠀⠈⡄⠀⢻⣿⡻⢦⡀⠀⠑⢌⠢⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣟⣾⣿⣿⣿⠋⠈⣉⢭⡽⣟⡛⣬⠣⡗⢿⣿⡿⣿⣻⢿⣷⣿⣿⣿⣄⠀⠀⠸⣇⡸⠀⠀⠀⠈⠑⠬⣕⣢⣍⣉⠉⠉⠁⣀⣠⣴⠏⠀⠀⢠⡇⠀⠀⠀⠀⠸⣃⠸⡀⠀⠀⠀⠀⠀⠈⢚⣿⡇⠀⡀⠹⡀⠀⠀⠀⢱⠀⠀⢯⡻⣄⠈⠒⢄⡀⠱⡄⠑⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣟⣾⣿⣿⣿⠋⠈⣉⢭⡽⣟⡛⣬⠣⡗⢿⣿⡿⣿⣻⢿⣷⣿⣿⣿⣄⠀⠀⠸⣇⡸⠀⠀⠀⠈⠑⠬⣕⣢⣍⣉⠉⠉⠁⣀⣠⣴⠏⠀⠀⢠⡇⠀⠀⠀⠀⠸⣃⠸⡀⠀⠀⠀⠀⠀⠈⢚⣿⡇⠀⡀⠹⡀⠀⠀⠀⢱⠀⠀⢯⡻⣄⠈⠒⢄⡀⠱⡄⠑⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⢻⣾⣿⣿⠿⠁⠲⠟⡺⣍⠶⡡⢏⣴⣳⣽⣿⣿⣷⣭⣓⡏⡞⡽⣻⢿⣿⣦⣄⠀⢹⡁⠀⠀⠀⠀⠀⢠⠀⢩⠏⣯⠉⠛⠋⠉⡠⠊⠀⠀⣰⡟⠀⠀⠀⠀⠀⠀⠘⡀⢳⡀⠀⠀⠀⠀⠀⠀⣿⡇⠀⡇⠀⢡⡀⠀⠀⠸⡇⠀⠸⢿⣟⣦⠀⠀⠙⡆⢼⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⢻⣾⣿⣿⠿⠁⠲⠟⡺⣍⠶⡡⢏⣴⣳⣽⣿⣿⣷⣭⣓⡏⡞⡽⣻⢿⣿⣦⣄⠀⢹⡁⠀⠀⠀⠀⠀⢠⠀⢩⠏⣯⠉⠛⠋⠉⡠⠊⠀⠀⣰⡟⠀⠀⠀⠀⠀⠀⠘⡀⢳⡀⠀⠀⠀⠀⠀⠀⣿⡇⠀⡇⠀⢡⡀⠀⠀⠸⡇⠀⠸⢿⣟⣦⠀⠀⠙⡆⢼⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣫⠟⠋⠁⠀⠀⠀⠰⣉⣶⡼⠶⠛⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣽⣞⣿⣿⣿⣷⣌⣇⠀⠀⠀⠀⢠⡏⢀⡞⠀⠸⡆⠀⢀⠔⠁⠀⢠⣾⠋⠀⠀⠀⠀⠀⠀⠀⠀⠇⠘⣿⡄⠀⠀⠀⠀⠀⣿⢳⠀⠇⠈⢄⠱⡀⠀⠀⢿⠀⠀⠸⡜⢿⣷⡄⠀⠈⢆⠈⠳⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣫⠟⠋⠁⠀⠀⠀⠰⣉⣶⡼⠶⠛⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣽⣞⣿⣿⣿⣷⣌⣇⠀⠀⠀⠀⢠⡏⢀⡞⠀⠸⡆⠀⢀⠔⠁⠀⢠⣾⠋⠀⠀⠀⠀⠀⠀⠀⠀⠇⠘⣿⡄⠀⠀⠀⠀⠀⣿⢳⠀⠇⠈⢄⠱⡀⠀⠀⢿⠀⠀⠸⡜⢿⣷⡄⠀⠈⢆⠈⠳⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⠗⠁⠀⠀⠀⣀⡤⠖⠛⠉⠀⠀⢠⣾⣿⣿⡿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠋⠀⠀⠀⠀⡸⠀⣼⠒⢆⢀⡹⠔⠁⠀⣠⣶⠟⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⢇⠹⣄⠀⠀⠀⠀⣿⠈⠀⠀⠀⠈⢦⠈⢂⠀⢸⡇⠀⠀⢣⠘⣟⣷⡀⠀⠀⠡⡀⠈⠢⡀⠑⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⠗⠁⠀⠀⠀⣀⡤⠖⠛⠉⠀⠀⢠⣾⣿⣿⡿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠋⠀⠀⠀⠀⡸⠀⣼⠒⢆⢀⡹⠔⠁⠀⣠⣶⠟⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⢇⠹⣄⠀⠀⠀⠀⣿⠈⠀⠀⠀⠈⢦⠈⢂⠀⢸⡇⠀⠀⢣⠘⣟⣷⡀⠀⠀⠡⡀⠈⠢⡀⠑⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡾⠋⢀⡠⠤⠒⠉⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⠏⠀⢠⣿⡟⠀⠀⢸⠁⠀⠀⠀⠀⢀⠅⠀⡟⠀⠤⡀⠀⠀⠀⡇⣼⠃⡀⠜⠋⣀⣤⣴⠿⠋⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠸⡄⢸⠀⠹⣆⠀⠀⢠⡟⠐⠀⣆⠀⠀⠈⣷⢄⠑⢼⣗⠀⠀⠈⡄⠘⣟⣧⠀⠀⠀⠡⡀⠀⠐⠄⠘⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡾⠋⢀⡠⠤⠒⠉⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⠏⠀⢠⣿⡟⠀⠀⢸⠁⠀⠀⠀⠀⢀⠅⠀⡟⠀⠤⡀⠀⠀⠀⡇⣼⠃⡀⠜⠋⣀⣤⣴⠿⠋⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠸⡄⢸⠀⠹⣆⠀⠀⢠⡟⠐⠀⣆⠀⠀⠈⣷⢄⠑⢼⣗⠀⠀⠈⡄⠘⣟⣧⠀⠀⠀⠡⡀⠀⠐⠄⠘⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⡿⢋⠞⡏⢀⠴⠋⣼⠃⠀⠀⡎⠀⠀⠀⠀⠀⡜⠀⠀⡇⠠⣀⠀⠉⠐⣺⠟⡏⡻⣗⣉⣉⣀⠸⡙⡄⠀⠀⡀⢆⠈⢢⠀⠀⠀⠀⠀⠀⠀⢀⠇⠐⡀⠀⠘⡆⠀⢸⠇⠐⠀⠉⡄⠀⠀⢸⡄⠑⠤⡈⠢⢄⡀⠃⠀⠘⣿⣇⡀⠀⠀⠱⡀⠀⠈⢆⠈⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⡿⢋⠞⡏⢀⠴⠋⣼⠃⠀⠀⡎⠀⠀⠀⠀⠀⡜⠀⠀⡇⠠⣀⠀⠉⠐⣺⠟⡏⡻⣗⣉⣉⣀⠸⡙⡄⠀⠀⡀⢆⠈⢢⠀⠀⠀⠀⠀⠀⠀⢀⠇⠐⡀⠀⠘⡆⠀⢸⠇⠐⠀⠉⡄⠀⠀⢸⡄⠑⠤⡈⠢⢄⡀⠃⠀⠘⣿⣇⡀⠀⠀⠱⡀⠀⠈⢆⠈⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣻⢧⠏⣸⠔⠉⣠⠎⣾⠀⠀⠀⠇⠀⠀⠀⠀⣰⠁⠀⢸⠁⠀⠀⠉⠉⣸⣿⡷⠟⠛⠉⠉⠀⠈⢾⡇⠹⡄⠀⠱⠈⣦⠀⠑⡄⢀⠀⠀⠀⠀⠈⠉⠘⠗⠠⢀⣸⡄⣸⡀⠃⢠⠀⢰⠀⠀⠀⣧⠀⠀⣿⠑⠢⠬⢷⡲⠦⠼⣿⡅⠀⠀⠀⢱⠀⠀⠀⢣⢥⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣻⢧⠏⣸⠔⠉⣠⠎⣾⠀⠀⠀⠇⠀⠀⠀⠀⣰⠁⠀⢸⠁⠀⠀⠉⠉⣸⣿⡷⠟⠛⠉⠉⠀⠈⢾⡇⠹⡄⠀⠱⠈⣦⠀⠑⡄⢀⠀⠀⠀⠀⠈⠉⠘⠗⠠⢀⣸⡄⣸⡀⠃⢠⠀⢰⠀⠀⠀⣧⠀⠀⣿⠑⠢⠬⢷⡲⠦⠼⣿⡅⠀⠀⠀⢱⠀⠀⠀⢣⢥⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡾⢡⣏⠔⠁⠀⠴⠃⡜⢸⠀⠀⢈⠀⠀⠀⠀⢠⡟⠀⠀⢸⠀⣀⠄⠂⣁⡽⢸⡄⠀⠀⠀⠀⠀⠀⠘⣧⠀⢻⡄⠀⢣⠘⡳⣄⠀⠙⢆⠀⠀⠀⠀⠀⠀⠂⠀⠀⠈⣿⣷⠀⡀⡸⠀⠀⣆⠀⠀⢸⡀⠀⣿⠆⠀⠀⡀⠆⠀⠀⢿⣿⠀⠀⠀⠀⠆⠀⠀⠈⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡾⢡⣏⠔⠁⠀⠴⠃⡜⢸⠀⠀⢈⠀⠀⠀⠀⢠⡟⠀⠀⢸⠀⣀⠄⠂⣁⡽⢸⡄⠀⠀⠀⠀⠀⠀⠘⣧⠀⢻⡄⠀⢣⠘⡳⣄⠀⠙⢆⠀⠀⠀⠀⠀⠀⠂⠀⠀⠈⣿⣷⠀⡀⡸⠀⠀⣆⠀⠀⢸⡀⠀⣿⠆⠀⠀⡀⠆⠀⠀⢿⣿⠀⠀⠀⠀⠆⠀⠀⠈⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢾⣇⡾⠉⠀⣠⣤⠀⡸⠀⢸⡀⠀⠠⠀⠀⠀⢀⣾⠇⠀⠀⢸⡏⠀⠀⡰⢣⠟⢸⡇⠀⠀⠀⠀⠀⠀⠀⢹⡄⠈⣿⡄⠈⣆⠁⠈⢳⣤⡀⠑⠠⣀⢀⠀⠐⠀⠀⠀⠀⢈⣧⠀⢀⠇⠀⠀⢼⠀⠀⠈⡇⠀⣿⡅⠀⠀⢧⠸⠀⠀⠈⢿⡇⠀⠀⠀⢡⠀⠀⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢾⣇⡾⠉⠀⣠⣤⠀⡸⠀⢸⡀⠀⠠⠀⠀⠀⢀⣾⠇⠀⠀⢸⡏⠀⠀⡰⢣⠟⢸⡇⠀⠀⠀⠀⠀⠀⠀⢹⡄⠈⣿⡄⠈⣆⠁⠈⢳⣤⡀⠑⠠⣀⢀⠀⠐⠀⠀⠀⠀⢈⣧⠀⢀⠇⠀⠀⢼⠀⠀⠈⡇⠀⣿⡅⠀⠀⢧⠸⠀⠀⠈⢿⡇⠀⠀⠀⢡⠀⠀⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡜⢸⠋⠀⢀⣾⣿⠇⢠⠁⠀⢸⡀⠀⠐⠀⠀⢀⣾⣼⠁⠀⠀⢸⠅⢀⣼⡷⠋⠀⢸⣷⣃⣀⣀⣀⣀⠀⠀⢈⡇⠀⢳⢹⡄⠀⢃⠀⠀⢻⡛⠷⣤⣀⣉⠒⢤⣀⡀⠀⠀⡞⠸⡏⡈⢀⠤⠊⠈⡆⠀⠀⣿⠀⣿⠆⠀⠀⣾⡀⡇⢠⠀⠈⠏⢆⠀⠀⡐⠀⠀⣰⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡜⢸⠋⠀⢀⣾⣿⠇⢠⠁⠀⢸⡀⠀⠐⠀⠀⢀⣾⣼⠁⠀⠀⢸⠅⢀⣼⡷⠋⠀⢸⣷⣃⣀⣀⣀⣀⠀⠀⢈⡇⠀⢳⢹⡄⠀⢃⠀⠀⢻⡛⠷⣤⣀⣉⠒⢤⣀⡀⠀⠀⡞⠸⡏⡈⢀⠤⠊⠈⡆⠀⠀⣿⠀⣿⠆⠀⠀⣾⡀⡇⢠⠀⠈⠏⢆⠀⠀⡐⠀⠀⣰⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣃⠂⢀⠔⣻⣿⡏⠀⠀⠀⠀⢸⡇⠀⠈⠀⠀⣼⣿⣿⢀⠀⠀⢸⣴⣿⡟⠁⢀⣨⣽⣿⣿⣾⣧⣍⣙⠿⠂⠀⣧⠀⡜⠈⢿⡄⢸⠀⠀⠘⡷⡄⠈⢿⣿⡿⣷⣶⣻⢟⣾⠓⣶⣷⠋⠁⠀⠀⠀⢣⠀⠀⣿⡀⢹⠇⠀⢀⠿⣇⢁⠀⡆⠀⠈⠄⠢⡴⠥⡴⠞⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣃⠂⢀⠔⣻⣿⡏⠀⠀⠀⠀⢸⡇⠀⠈⠀⠀⣼⣿⣿⢀⠀⠀⢸⣴⣿⡟⠁⢀⣨⣽⣿⣿⣾⣧⣍⣙⠿⠂⠀⣧⠀⡜⠈⢿⡄⢸⠀⠀⠘⡷⡄⠈⢿⣿⡿⣷⣶⣻⢟⣾⠓⣶⣷⠋⠁⠀⠀⠀⢣⠀⠀⣿⡀⢹⠇⠀⢀⠿⣇⢁⠀⡆⠀⠈⠄⠢⡴⠥⡴⠞⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠃⢠⡎⢰⣿⣿⠀⠀⠀⠀⢠⠸⣧⠀⠀⡃⢰⣿⡿⢻⡎⠀⠀⢹⠻⠃⣬⣿⣿⣿⣿⣿⣿⣿⣿⠿⢿⣿⠀⠀⣾⠀⡆⠀⠈⣯⠽⡀⠀⠀⢱⠘⣤⣿⣟⠀⠙⣿⣯⣨⠏⢩⣿⢿⡀⠀⠀⠀⠀⠸⡀⠀⢹⣧⢸⠀⠀⢸⠀⣿⢈⠀⢡⠀⠀⠘⡄⠑⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠃⢠⡎⢰⣿⣿⠀⠀⠀⠀⢠⠸⣧⠀⠀⡃⢰⣿⡿⢻⡎⠀⠀⢹⠻⠃⣬⣿⣿⣿⣿⣿⣿⣿⣿⠿⢿⣿⠀⠀⣾⠀⡆⠀⠈⣯⠽⡀⠀⠀⢱⠘⣤⣿⣟⠀⠙⣿⣯⣨⠏⢩⣿⢿⡀⠀⠀⠀⠀⠸⡀⠀⢹⣧⢸⠀⠀⢸⠀⣿⢈⠀⢡⠀⠀⠘⡄⠑⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢠⣿⣆⣿⣿⡇⠀⠀⠀⠀⡘⠀⣿⢇⠀⢣⣾⣿⣿⢿⡄⠀⠀⢹⣦⣿⡿⠋⢻⣿⣿⣿⣿⣿⣿⣤⡤⠈⠀⠀⣿⣰⠁⠀⠀⣾⣷⠰⠀⢀⣸⡾⠟⣇⠘⣦⣀⠘⣿⣿⣤⠋⠁⢸⣧⣀⠀⠀⠀⠀⡇⠀⢸⣿⣿⠀⢀⡇⠀⢸⡄⡀⠸⡀⠀⠀⠈⢆⠈⢷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢠⣿⣆⣿⣿⡇⠀⠀⠀⠀⡘⠀⣿⢇⠀⢣⣾⣿⣿⢿⡄⠀⠀⢹⣦⣿⡿⠋⢻⣿⣿⣿⣿⣿⣿⣤⡤⠈⠀⠀⣿⣰⠁⠀⠀⣾⣷⠰⠀⢀⣸⡾⠟⣇⠘⣦⣀⠘⣿⣿⣤⠋⠁⢸⣧⣀⠀⠀⠀⠀⡇⠀⢸⣿⣿⠀⢀⡇⠀⢸⡄⡀⠸⡀⠀⠀⠈⢆⠈⢷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡏⠙⣿⣿⣿⠀⠀⠀⠀⠀⡇⠀⢹⡼⡄⠘⣿⣿⡏⣀⣻⠀⠘⢿⣿⡟⠀⣴⣿⣿⣿⡿⣭⣽⣿⣿⣿⠀⠀⢰⣿⡞⠀⠀⠀⣿⠋⡆⣇⠀⠀⡇⠈⣿⣷⣿⣿⣄⡈⣿⣿⣦⠀⠀⣿⣀⠉⠀⠀⢰⣷⠀⣿⣿⡇⠀⡞⠀⠀⠈⡇⠅⠀⡇⠀⠆⠀⠈⢳⣀⠙⢭⣒⢤⣀⡀⢀⣀⣀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡏⠙⣿⣿⣿⠀⠀⠀⠀⠀⡇⠀⢹⡼⡄⠘⣿⣿⡏⣀⣻⠀⠘⢿⣿⡟⠀⣴⣿⣿⣿⡿⣭⣽⣿⣿⣿⠀⠀⢰⣿⡞⠀⠀⠀⣿⠋⡆⣇⠀⠀⡇⠈⣿⣷⣿⣿⣄⡈⣿⣿⣦⠀⠀⣿⣀⠉⠀⠀⢰⣷⠀⣿⣿⡇⠀⡞⠀⠀⠈⡇⠅⠀⡇⠀⠆⠀⠈⢳⣀⠙⢭⣒⢤⣀⡀⢀⣀⣀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢣⢀⢿⣿⣿⠀⠀⠀⠀⢠⣗⠀⠘⣇⢷⠀⢻⣿⣷⠛⢿⡆⠀⠸⣿⠁⠀⣿⣿⣿⣿⣷⢯⣿⣿⣿⡏⠀⠀⢸⡿⠁⠀⠀⣰⡟⠀⣷⢹⠀⠀⡇⠀⣿⣿⣿⡿⣽⣷⣯⣿⣿⣄⠀⢹⣋⠀⠀⠀⢸⣿⡄⢿⣿⠁⡰⠁⢀⠀⠀⡇⡄⠀⢱⠀⠐⡀⠀⠈⠍⠢⢌⡙⠚⠭⠥⠾⠟⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠄⠀⠀
|
⠀⠀⠀⠀⠀⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢣⢀⢿⣿⣿⠀⠀⠀⠀⢠⣗⠀⠘⣇⢷⠀⢻⣿⣷⠛⢿⡆⠀⠸⣿⠁⠀⣿⣿⣿⣿⣷⢯⣿⣿⣿⡏⠀⠀⢸⡿⠁⠀⠀⣰⡟⠀⣷⢹⠀⠀⡇⠀⣿⣿⣿⡿⣽⣷⣯⣿⣿⣄⠀⢹⣋⠀⠀⠀⢸⣿⡄⢿⣿⠁⡰⠁⢀⠀⠀⡇⡄⠀⢱⠀⠐⡀⠀⠈⠍⠢⢌⡙⠚⠭⠥⠾⠟⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠄⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣹⢻⣿⣿⠀⠀⠀⠀⢠⡛⠀⠀⠹⣾⣧⡀⢿⣿⣇⠀⣿⡀⠀⠻⡃⠀⠸⠿⣿⣏⠋⠛⢫⣽⡿⠁⠀⣠⠟⠁⠀⠀⣠⠟⠀⠀⣿⣘⡇⠀⢡⠀⠈⣿⣎⠽⠇⣛⣻⣿⡿⠁⠑⡞⠀⠀⠀⠀⣞⣿⣧⣸⢃⡜⠀⠀⠀⠆⠀⡇⡄⠀⠘⡄⠀⠹⣄⠀⠈⢆⠀⠈⢋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠋⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣹⢻⣿⣿⠀⠀⠀⠀⢠⡛⠀⠀⠹⣾⣧⡀⢿⣿⣇⠀⣿⡀⠀⠻⡃⠀⠸⠿⣿⣏⠋⠛⢫⣽⡿⠁⠀⣠⠟⠁⠀⠀⣠⠟⠀⠀⣿⣘⡇⠀⢡⠀⠈⣿⣎⠽⠇⣛⣻⣿⡿⠁⠑⡞⠀⠀⠀⠀⣞⣿⣧⣸⢃⡜⠀⠀⠀⠆⠀⡇⡄⠀⠘⡄⠀⠹⣄⠀⠈⢆⠀⠈⢋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠋⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⣸⣿⣿⠀⠀⠀⠀⠠⣇⠀⠀⠀⢹⣿⣷⡌⢿⣿⣿⣻⣷⣀⠀⠙⡶⠤⣄⣿⡾⠥⠴⠚⠛⠒⢁⡤⠋⠀⠀⣠⠜⠁⠀⠀⠀⠟⢻⣇⠀⡼⠀⠈⠙⠛⠦⠦⠬⣷⣿⣤⠴⢺⡇⠀⠀⠀⢠⣿⣿⣿⣣⣾⡇⠀⠀⠀⢃⢀⡧⡇⠀⠀⢃⠀⠀⢻⡦⠀⠀⠢⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠁⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⣸⣿⣿⠀⠀⠀⠀⠠⣇⠀⠀⠀⢹⣿⣷⡌⢿⣿⣿⣻⣷⣀⠀⠙⡶⠤⣄⣿⡾⠥⠴⠚⠛⠒⢁⡤⠋⠀⠀⣠⠜⠁⠀⠀⠀⠟⢻⣇⠀⡼⠀⠈⠙⠛⠦⠦⠬⣷⣿⣤⠴⢺⡇⠀⠀⠀⢠⣿⣿⣿⣣⣾⡇⠀⠀⠀⢃⢀⡧⡇⠀⠀⢃⠀⠀⢻⡦⠀⠀⠢⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠁⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⠀⠀⠀⠀⠀⠀⠀⣾⡇⣼⣿⣿⠀⠀⠀⠀⠐⣧⠀⠀⠀⢸⣿⣿⣿⣶⣿⣿⣿⣿⣿⣷⣄⠈⠢⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⠻⠼⠶⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡿⠀⠀⢀⣾⣿⣿⣯⣿⣿⣿⡇⠀⢘⠀⢨⢸⢱⠃⠀⠀⠘⡀⠀⠈⡇⠡⡀⠀⢃⠀⠀⠁⠀⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⠀⠀⠀⠀⠀⠀⠀⣾⡇⣼⣿⣿⠀⠀⠀⠀⠐⣧⠀⠀⠀⢸⣿⣿⣿⣶⣿⣿⣿⣿⣿⣷⣄⠈⠢⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⠻⠼⠶⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡿⠀⠀⢀⣾⣿⣿⣯⣿⣿⣿⡇⠀⢘⠀⢨⢸⢱⠃⠀⠀⠘⡀⠀⠈⡇⠡⡀⠀⢃⠀⠀⠁⠀⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⢰⢫⡇⢹⡿⣿⣇⠀⠀⠀⠀⣿⡀⠀⠀⢸⣿⣿⣯⣿⣿⣿⣿⣿⣿⣿⡮⢿⣲⣬⣑⠢⠀⠀⠀⠀⠀⠀⢀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣟⠥⢶⣾⣿⣾⣿⣿⣿⣿⣿⣿⡇⠀⢸⠀⢸⣞⠎⠀⠀⠀⠀⡇⠀⠀⡅⠀⠱⡀⠈⢆⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠄⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⢰⢫⡇⢹⡿⣿⣇⠀⠀⠀⠀⣿⡀⠀⠀⢸⣿⣿⣯⣿⣿⣿⣿⣿⣿⣿⡮⢿⣲⣬⣑⠢⠀⠀⠀⠀⠀⠀⢀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣟⠥⢶⣾⣿⣾⣿⣿⣿⣿⣿⣿⡇⠀⢸⠀⢸⣞⠎⠀⠀⠀⠀⡇⠀⠀⡅⠀⠱⡀⠈⢆⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠄⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⠀⠀⠀⠀⠀⢸⡀⣷⣸⡇⢹⣿⡀⠀⠀⠀⠸⣧⡆⠀⠘⣿⣿⡿⣿⣾⣟⡿⣿⣿⣿⣷⠈⠒⠉⠉⠛⠛⠛⠒⠀⠀⠀⢯⠉⠑⠒⠒⠤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠤⠾⠭⠔⠂⣼⣿⣿⣿⣿⣿⣿⣿⡿⣽⠀⢀⡏⠀⣼⠋⠀⠀⠀⢀⠀⠰⠀⠀⠀⠀⠀⠑⡀⠈⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⠀⠀⠀⠀⠀⢸⡀⣷⣸⡇⢹⣿⡀⠀⠀⠀⠸⣧⡆⠀⠘⣿⣿⡿⣿⣾⣟⡿⣿⣿⣿⣷⠈⠒⠉⠉⠛⠛⠛⠒⠀⠀⠀⢯⠉⠑⠒⠒⠤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠤⠾⠭⠔⠂⣼⣿⣿⣿⣿⣿⣿⣿⡿⣽⠀⢀⡏⠀⣼⠋⠀⠀⠀⢀⠀⠰⠀⠀⠀⠀⠀⠑⡀⠈⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⢄⡀⠀⠘⡆⠀⠀⠀⠀⠀⢳⣯⣿⣽⠀⢿⣿⠀⠀⠀⠀⢿⣻⠀⠀⢹⣿⢿⣿⣻⣿⣿⣿⣿⢿⣿⣆⠙⠢⠤⠀⠀⠀⠀⠀⠀⠀⠈⠳⡀⠀⠀⠀⠈⠳⠤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣿⣿⣿⣿⡿⣿⣿⣼⠇⠀⣼⡇⠊⣸⠀⠀⠀⠀⠈⡄⠸⠀⠀⠀⠀⠀⠀⢠⠀⢱⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⢄⡀⠀⠘⡆⠀⠀⠀⠀⠀⢳⣯⣿⣽⠀⢿⣿⠀⠀⠀⠀⢿⣻⠀⠀⢹⣿⢿⣿⣻⣿⣿⣿⣿⢿⣿⣆⠙⠢⠤⠀⠀⠀⠀⠀⠀⠀⠈⠳⡀⠀⠀⠀⠈⠳⠤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣿⣿⣿⣿⡿⣿⣿⣼⠇⠀⣼⡇⠊⣸⠀⠀⠀⠀⠈⡄⠸⠀⠀⠀⠀⠀⠀⢠⠀⢱⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠢⡀⢡⠀⠀⠀⠀⠀⠀⠻⣾⣏⢇⠀⢙⣷⠘⡀⠀⠘⣿⣄⠄⠀⠹⣿⣿⣟⣷⣿⡾⣽⡻⣞⡿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢷⠀⠀⠀⠣⡀⠀⠈⢦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣟⣯⣿⣳⣿⢿⣿⣿⠏⢀⣼⣿⠁⠀⣿⠀⠀⠀⠀⠀⢡⠀⡆⠀⠀⠀⠀⠀⠀⢇⠀⣯⢀⠔⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠢⡀⢡⠀⠀⠀⠀⠀⠀⠻⣾⣏⢇⠀⢙⣷⠘⡀⠀⠘⣿⣄⠄⠀⠹⣿⣿⣟⣷⣿⡾⣽⡻⣞⡿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢷⠀⠀⠀⠣⡀⠀⠈⢦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣟⣯⣿⣳⣿⢿⣿⣿⠏⢀⣼⣿⠁⠀⣿⠀⠀⠀⠀⠀⢡⠀⡆⠀⠀⠀⠀⠀⠀⢇⠀⣯⢀⠔⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠳⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠺⡆⠀⠀⠀⠀⠀⠀⠘⣿⠈⢄⠐⣿⣧⡘⡄⠀⠘⣯⠿⣶⣄⣈⣳⣿⣾⢯⡻⣵⢻⣬⢷⣻⡽⣆⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣇⠀⠀⠀⠱⡀⠀⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣾⣟⡷⢯⣟⣾⣿⡿⣿⣿⣃⣴⢿⣿⡿⠀⢸⡗⠀⠀⠀⠀⠀⠈⠀⢡⡄⠀⠀⠀⠀⠀⢸⢠⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠞⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠳⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠺⡆⠀⠀⠀⠀⠀⠀⠘⣿⠈⢄⠐⣿⣧⡘⡄⠀⠘⣯⠿⣶⣄⣈⣳⣿⣾⢯⡻⣵⢻⣬⢷⣻⡽⣆⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣇⠀⠀⠀⠱⡀⠀⠀⢣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣾⣟⡷⢯⣟⣾⣿⡿⣿⣿⣃⣴⢿⣿⡿⠀⢸⡗⠀⠀⠀⠀⠀⠈⠀⢡⡄⠀⠀⠀⠀⠀⢸⢠⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠞⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠒⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠱⡀⠀⠀⠀⠀⠀⠀⠹⣧⠀⠣⠘⡌⢻⣜⣆⡀⠈⠻⣬⣉⠻⣬⣛⣿⢯⣓⢭⢻⣼⡧⣗⡯⣝⣻⣦⣄⣠⣤⣶⣶⣿⣿⣿⠿⢦⡀⠀⠀⠘⠀⠀⠀⢻⣿⣶⣶⣤⣄⣀⣀⣠⣶⡟⣯⠷⣞⡽⣻⣾⢻⡿⣿⡿⣟⣿⣽⣿⡿⠇⢠⣿⡅⠀⢀⠀⠀⠀⠀⡇⢸⠀⠀⠀⠀⠀⠀⣼⠎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠒⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠒⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠱⡀⠀⠀⠀⠀⠀⠀⠹⣧⠀⠣⠘⡌⢻⣜⣆⡀⠈⠻⣬⣉⠻⣬⣛⣿⢯⣓⢭⢻⣼⡧⣗⡯⣝⣻⣦⣄⣠⣤⣶⣶⣿⣿⣿⠿⢦⡀⠀⠀⠘⠀⠀⠀⢻⣿⣶⣶⣤⣄⣀⣀⣠⣶⡟⣯⠷⣞⡽⣻⣾⢻⡿⣿⡿⣟⣿⣽⣿⡿⠇⢠⣿⡅⠀⢀⠀⠀⠀⠀⡇⢸⠀⠀⠀⠀⠀⠀⣼⠎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠒⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⡄⠀⠀⠀⠀⠀⠀⠘⢧⡀⠀⠈⠢⡈⠻⣟⠶⣶⣶⡿⣍⣹⣾⣏⢧⡙⠆⢫⣷⣽⣷⣿⣿⡿⠿⠿⠛⠛⠋⠉⣁⣀⣤⣤⣤⣇⠀⠀⠀⠀⠀⠀⢸⠉⠉⠛⠛⠻⠿⠿⣿⣷⣿⣾⣿⣞⣋⠑⡡⠋⣼⣏⢷⣻⣿⡷⠋⠃⣰⡿⣳⠁⠀⡌⠀⠀⠀⠀⣧⠸⡀⠀⠀⠀⣀⣾⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⡄⠀⠀⠀⠀⠀⠀⠘⢧⡀⠀⠈⠢⡈⠻⣟⠶⣶⣶⡿⣍⣹⣾⣏⢧⡙⠆⢫⣷⣽⣷⣿⣿⡿⠿⠿⠛⠛⠋⠉⣁⣀⣤⣤⣤⣇⠀⠀⠀⠀⠀⠀⢸⠉⠉⠛⠛⠻⠿⠿⣿⣷⣿⣾⣿⣞⣋⠑⡡⠋⣼⣏⢷⣻⣿⡷⠋⠃⣰⡿⣳⠁⠀⡌⠀⠀⠀⠀⣧⠸⡀⠀⠀⠀⣀⣾⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠢⠬⣢⣀⠀⠀⠀⠀⠀⠀⠙⠢⠤⠀⠈⠢⣘⠿⡳⣷⡹⣿⣯⠻⣟⢮⣉⢿⣿⡿⣿⣟⣿⣶⣤⣤⣴⣶⣾⣿⣿⣿⣿⣿⣿⣿⡿⢇⠀⠀⠀⡀⠀⣼⣿⣿⣿⣶⣶⣤⣤⣀⡈⠉⠙⠛⠿⣿⣿⣷⣾⣳⣾⠟⣿⣋⣀⣠⣼⣟⣿⡟⠀⢠⠃⠀⠀⠀⠀⣿⢄⠈⠑⠒⢊⣽⠥⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠒⠤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠢⠬⣢⣀⠀⠀⠀⠀⠀⠀⠙⠢⠤⠀⠈⠢⣘⠿⡳⣷⡹⣿⣯⠻⣟⢮⣉⢿⣿⡿⣿⣟⣿⣶⣤⣤⣴⣶⣾⣿⣿⣿⣿⣿⣿⣿⡿⢇⠀⠀⠀⡀⠀⣼⣿⣿⣿⣶⣶⣤⣤⣀⡈⠉⠙⠛⠿⣿⣿⣷⣾⣳⣾⠟⣿⣋⣀⣠⣼⣟⣿⡟⠀⢠⠃⠀⠀⠀⠀⣿⢄⠈⠑⠒⢊⣽⠥⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠒⠤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠳⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠁⠋⠀⠉⠋⠘⠧⠛⠚⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣾⣿⣿⣿⣿⣿⡇⠀⠄⠀⠀⠁⠀⡽⣿⣯⣭⣝⣛⣛⠻⠿⢿⣿⣷⣾⣶⣤⣬⠇⠀⠈⠱⠋⠀⠀⠘⠁⢈⣈⠀⠀⠀⡞⠀⠀⠀⠀⣠⠟⢸⢀⣤⠞⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠳⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠁⠋⠀⠉⠋⠘⠧⠛⠚⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣾⣿⣿⣿⣿⣿⡇⠀⠄⠀⠀⠁⠀⡽⣿⣯⣭⣝⣛⣛⠻⠿⢿⣿⣷⣾⣶⣤⣬⠇⠀⠈⠱⠋⠀⠀⠘⠁⢈⣈⠀⠀⠀⡞⠀⠀⠀⠀⣠⠟⢸⢀⣤⠞⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠢⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢮⣑⠦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠈⠀⠈⠀⡸⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⣭⣝⣻⡟⠀⠀⠀⠀⠀⠀⠀⠀⡠⠊⣼⠋⢀⡞⠁⠀⠀⠀⣴⣯⢴⣼⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠜⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠢⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢮⣑⠦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠈⠀⠈⠀⡸⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⣭⣝⣻⡟⠀⠀⠀⠀⠀⠀⠀⠀⡠⠊⣼⠋⢀⡞⠁⠀⠀⠀⣴⣯⢴⣼⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠜⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠠⠒⢈⠇⠀⠙⠳⢦⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣉⠘⣌⡙⢳⠦⣤⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠔⠚⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠡⡀⠐⡄⠜⡡⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡗⠤⣀⠀⠀⠐⠒⠂⠉⠀⣰⠃⢠⠞⠁⠀⠀⢠⣞⡿⢡⣿⣏⡠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡴⠞⠉⠀⠀⡉⠒⠤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠠⠒⢈⠇⠀⠙⠳⢦⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣉⠘⣌⡙⢳⠦⣤⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠔⠚⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠡⡀⠐⡄⠜⡡⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡗⠤⣀⠀⠀⠐⠒⠂⠉⠀⣰⠃⢠⠞⠁⠀⠀⢠⣞⡿⢡⣿⣏⡠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡴⠞⠉⠀⠀⡉⠒⠤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠂⠀⠀⠀⠀⠀⡈⠙⠥⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠻⢾⣵⣚⠦⣝⢮⣛⡟⣶⣶⣶⠶⠦⠒⠊⠉⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⢂⠁⢠⠗⠊⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠈⠑⠒⠤⣤⣤⣴⡶⠃⡠⠃⠀⢀⣠⠞⣣⣿⠼⢻⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⢄⡀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠘⣄⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠂⠀⠀⠀⠀⠀⡈⠙⠥⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠻⢾⣵⣚⠦⣝⢮⣛⡟⣶⣶⣶⠶⠦⠒⠊⠉⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⢂⠁⢠⠗⠊⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠈⠑⠒⠤⣤⣤⣴⡶⠃⡠⠃⠀⢀⣠⠞⣣⣿⠼⢻⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⢄⡀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠘⣄⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠋⠀⠀⠀⠀⠀⡔⠁⠀⠀⠀⢀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠻⢶⣹⣎⡯⠷⠛⠉⠉⠀⠀⠀⡀⠀⠀⠀⠀⡈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠾⣄⠞⠀⣀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⠀⠀⠀⢀⣴⣿⡿⠟⣁⣴⣡⡤⣶⣾⣯⡶⠟⢉⣠⠞⠁⠀⠀⠀⠀⠀⠀⠤⣀⠀⠀⠈⠑⠠⡀⠀⠀⠀⠈⠢⡀⠀⠀⠀⠀⠙⡆⠀⠀⠠⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠋⠀⠀⠀⠀⠀⡔⠁⠀⠀⠀⢀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠻⢶⣹⣎⡯⠷⠛⠉⠉⠀⠀⠀⡀⠀⠀⠀⠀⡈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠾⣄⠞⠀⣀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⠀⠀⠀⢀⣴⣿⡿⠟⣁⣴⣡⡤⣶⣾⣯⡶⠟⢉⣠⠞⠁⠀⠀⠀⠀⠀⠀⠤⣀⠀⠀⠈⠑⠠⡀⠀⠀⠀⠈⠢⡀⠀⠀⠀⠀⠙⡆⠀⠀⠠⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠃⠀⠀⠀⠀⠄⣊⠄⠀⠀⠀⣀⠮⠤⠤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡤⢶⣾⠉⠀⡇⠀⠀⠀⠀⠀⠀⠀⠈⠓⠌⠲⠦⣄⢣⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠁⡀⠀⠈⠒⢾⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀⠀⠀⣠⣴⣿⣯⣽⣶⣾⠿⠛⡡⠔⢛⠀⢻⢹⠒⢦⣀⠀⠀⠀⣄⠀⠀⠀⠀⠀⠈⠙⠷⠶⠦⠤⠼⢀⠀⠀⠉⠢⣝⠢⢄⣀⡀⡀⠘⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠃⠀⠀⠀⠀⠄⣊⠄⠀⠀⠀⣀⠮⠤⠤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡤⢶⣾⠉⠀⡇⠀⠀⠀⠀⠀⠀⠀⠈⠓⠌⠲⠦⣄⢣⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠁⡀⠀⠈⠒⢾⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀⠀⠀⣠⣴⣿⣯⣽⣶⣾⠿⠛⡡⠔⢛⠀⢻⢹⠒⢦⣀⠀⠀⠀⣄⠀⠀⠀⠀⠀⠈⠙⠷⠶⠦⠤⠼⢀⠀⠀⠉⠢⣝⠢⢄⣀⡀⡀⠘⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠲⠤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠼⠁⠀⢤⠔⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⠴⡾⣿⠀⢸⠸⡀⠀⢱⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠲⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣏⣀⣠⣾⣿⣶⣄⠀⠀⠉⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠓⠒⠒⠒⠛⠛⠛⠛⠛⠋⠛⠉⠉⠁⠀⠀⡞⠀⡇⡜⠀⢸⠙⣿⠶⣄⣈⠙⠶⣤⣤⣀⣤⡠⠄⠀⠀⠀⠀⠀⠉⠒⡤⢄⡈⠦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠲⠤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠼⠁⠀⢤⠔⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⠴⡾⣿⠀⢸⠸⡀⠀⢱⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠲⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣏⣀⣠⣾⣿⣶⣄⠀⠀⠉⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠓⠒⠒⠒⠛⠛⠛⠛⠛⠋⠛⠉⠉⠁⠀⠀⡞⠀⡇⡜⠀⢸⠙⣿⠶⣄⣈⠙⠶⣤⣤⣀⣤⡠⠄⠀⠀⠀⠀⠀⠉⠒⡤⢄⡈⠦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠠⣀⠀⠀⠀⠀⠀⠈⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠄⠀⠀⠴⠚⠉⢠⠟⠀⢹⠀⠈⡆⡇⠀⠸⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⡴⠒⠒⠒⠓⠚⠛⠿⢿⣿⣿⣿⣿⣿⣿⡿⠛⠞⠻⠿⠿⣷⣷⡀⠀⠀⠀⠙⢻⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠂⠀⠀⠀⠀⣸⠁⢰⢡⠇⠀⢸⠀⣺⣯⡝⡭⢷⢶⣤⡀⠣⣄⡀⠀⠀⡀⠀⠀⠀⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀
|
⠠⣀⠀⠀⠀⠀⠀⠈⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠄⠀⠀⠴⠚⠉⢠⠟⠀⢹⠀⠈⡆⡇⠀⠸⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⡴⠒⠒⠒⠓⠚⠛⠿⢿⣿⣿⣿⣿⣿⣿⡿⠛⠞⠻⠿⠿⣷⣷⡀⠀⠀⠀⠙⢻⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠂⠀⠀⠀⠀⣸⠁⢰⢡⠇⠀⢸⠀⣺⣯⡝⡭⢷⢶⣤⡀⠣⣄⡀⠀⠀⡀⠀⠀⠀⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠑⠦⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠁⠀⠀⠀⠀⠠⠀⠀⠀⠀⠀⠀⠀⠀⡠⠞⠁⠀⡏⠀⡇⢸⠀⠀⢳⢸⠀⠀⢷⠀⠀⠀⠀⠀⠀⠀⠀⢠⣇⡀⠀⠀⠀⠀⠀⠀⠀⠈⠳⢯⣟⣿⣿⣃⠀⠀⠀⠀⠀⠀⠀⠉⠙⠲⠄⠀⠀⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠎⠀⠀⠀⠀⢠⡏⠀⡜⡜⠀⠀⡇⠀⡇⣿⣞⡱⣯⢷⣄⡀⠀⠘⢯⢓⠒⠚⠒⠦⣄⣀⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⣠⠤⠊
|
⠀⠀⠑⠦⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠁⠀⠀⠀⠀⠠⠀⠀⠀⠀⠀⠀⠀⠀⡠⠞⠁⠀⡏⠀⡇⢸⠀⠀⢳⢸⠀⠀⢷⠀⠀⠀⠀⠀⠀⠀⠀⢠⣇⡀⠀⠀⠀⠀⠀⠀⠀⠈⠳⢯⣟⣿⣿⣃⠀⠀⠀⠀⠀⠀⠀⠉⠙⠲⠄⠀⠀⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠎⠀⠀⠀⠀⢠⡏⠀⡜⡜⠀⠀⡇⠀⡇⣿⣞⡱⣯⢷⣄⡀⠀⠘⢯⢓⠒⠚⠒⠦⣄⣀⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⣠⠤⠊
|
||||||
⠀⠀⠀⠀⠀⠈⠉⠙⠒⠶⠤⢤⣄⣀⠀⡀⠀⢀⠀⠀⠄⠀⠈⠁⠀⠐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⢡⠈⡆⠀⠘⡆⡇⠀⠈⣇⠀⠀⠀⠀⠀⠀⠀⣸⠌⣷⡀⠀⠀⠄⠀⠠⠀⢀⠀⠀⢿⣿⣏⠀⠈⠉⠀⠀⠀⠀⠤⠠⠤⠀⠀⠀⠀⣿⡿⠛⠛⠛⠲⠤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⡼⠀⢠⢳⠃⠀⢠⠃⣸⠀⢸⣧⣏⢿⡌⢷⡹⣳⣄⠈⢯⠙⠦⣅⡐⠀⠀⠉⠉⠀⠈⠢⠤⠄⣀⠀⢀⢀⡀⡀⠠⠔⠒⠒⠀⠈⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠈⠉⠙⠒⠶⠤⢤⣄⣀⠀⡀⠀⢀⠀⠀⠄⠀⠈⠁⠀⠐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⢡⠈⡆⠀⠘⡆⡇⠀⠈⣇⠀⠀⠀⠀⠀⠀⠀⣸⠌⣷⡀⠀⠀⠄⠀⠠⠀⢀⠀⠀⢿⣿⣏⠀⠈⠉⠀⠀⠀⠀⠤⠠⠤⠀⠀⠀⠀⣿⡿⠛⠛⠛⠲⠤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⡼⠀⢠⢳⠃⠀⢠⠃⣸⠀⢸⣧⣏⢿⡌⢷⡹⣳⣄⠈⢯⠙⠦⣅⡐⠀⠀⠉⠉⠀⠈⠢⠤⠄⣀⠀⢀⢀⡀⡀⠠⠔⠒⠒⠀⠈⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⢃⠀⠘⢆⢣⠀⠀⠹⡸⡀⠀⠸⡄⠀⠀⠀⠀⠀⠀⣿⠄⡐⢻⠀⠀⠀⢀⠀⠠⠀⠀⠂⢘⣿⡿⠶⠒⠂⠉⠉⠉⠑⠒⠀⠐⣒⡶⠀⠀⢿⣳⣤⡀⠀⠀⠀⠀⠉⠑⠢⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠃⠀⡞⡏⠀⠀⡰⢰⡇⠀⢸⡏⢧⣋⢷⡈⢷⡈⠙⠛⠓⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⢃⠀⠘⢆⢣⠀⠀⠹⡸⡀⠀⠸⡄⠀⠀⠀⠀⠀⠀⣿⠄⡐⢻⠀⠀⠀⢀⠀⠠⠀⠀⠂⢘⣿⡿⠶⠒⠂⠉⠉⠉⠑⠒⠀⠐⣒⡶⠀⠀⢿⣳⣤⡀⠀⠀⠀⠀⠉⠑⠢⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠃⠀⡞⡏⠀⠀⡰⢰⡇⠀⢸⡏⢧⣋⢷⡈⢷⡈⠙⠛⠓⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠈⢿⡆⠀⠀⢣⢣⠀⠀⢱⡀⠀⠀⠀⠀⢀⣿⡇⣌⠃⠀⠀⠈⠀⠀⠀⠀⠁⠐⣾⡟⠀⢀⣤⣴⡶⠿⠿⠚⠒⠒⠊⠉⠀⠀⠀⢸⡄⠀⠙⠶⡀⠀⢀⠀⢀⠀⠀⠙⠲⢤⣀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⠁⠀⣠⣿⡿⠇⠀⣻⠀⠀⠀⠧⣹⢮⣳⡈⠲⠄⠀⠀⠀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠈⢿⡆⠀⠀⢣⢣⠀⠀⢱⡀⠀⠀⠀⠀⢀⣿⡇⣌⠃⠀⠀⠈⠀⠀⠀⠀⠁⠐⣾⡟⠀⢀⣤⣴⡶⠿⠿⠚⠒⠒⠊⠉⠀⠀⠀⢸⡄⠀⠙⠶⡀⠀⢀⠀⢀⠀⠀⠙⠲⢤⣀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⠁⠀⣠⣿⡿⠇⠀⣻⠀⠀⠀⠧⣹⢮⣳⡈⠲⠄⠀⠀⠀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{pkgs, lib, ...}:
|
{ pkgs, lib, ... }:
|
||||||
{
|
{
|
||||||
networking.networkmanager.enable = true;
|
networking.networkmanager.enable = true;
|
||||||
networking.networkmanager.plugins = lib.mkForce [ pkgs.networkmanager-openvpn ];
|
networking.networkmanager.plugins = lib.mkForce [ pkgs.networkmanager-openvpn ];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, config, ...}:
|
{ pkgs, config, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./index.nix
|
./index.nix
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.custom.nix.ld;
|
cfg = config.custom.nix.ld;
|
||||||
@@ -7,7 +7,7 @@ in
|
|||||||
options.custom.nix.ld = {
|
options.custom.nix.ld = {
|
||||||
enable = mkEnableOption "Enables nix ld";
|
enable = mkEnableOption "Enables nix ld";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
programs.nix-ld.enable = true;
|
programs.nix-ld.enable = true;
|
||||||
programs.nix-ld.libraries = with pkgs; [
|
programs.nix-ld.libraries = with pkgs; [
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ with lib;
|
|||||||
let
|
let
|
||||||
cfg = config.custom.nix.settings;
|
cfg = config.custom.nix.settings;
|
||||||
cache = "https://cache.nixos.org";
|
cache = "https://cache.nixos.org";
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
options.custom.nix.settings = {
|
options.custom.nix.settings = {
|
||||||
enable = mkEnableOption "Enables various nix settings";
|
enable = mkEnableOption "Enables various nix settings";
|
||||||
optimise = mkOption {
|
optimise = mkOption {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
services.logind.lidSwitchExternalPower = "ignore";
|
services.logind.lidSwitchExternalPower = "ignore";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
{ config, pkgs, lib, inputs, ... }:
|
{ config, pkgs, lib, inputs, ... }:
|
||||||
with lib;
|
with lib;
|
||||||
let cfg = config.custom.services.adam-site;
|
let cfg = config.custom.services.adam-site;
|
||||||
|
|||||||
@@ -19,157 +19,159 @@ in {
|
|||||||
description = "use https for the adguard instance";
|
description = "use https for the adguard instance";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = let
|
config =
|
||||||
ip = cfg.ip;
|
let
|
||||||
wireguardIp = config.custom.services.wireguard.ip;
|
ip = cfg.ip;
|
||||||
in lib.mkIf cfg.enable {
|
wireguardIp = config.custom.services.wireguard.ip;
|
||||||
networking.firewall.allowedTCPPorts = [ 53 ];
|
in
|
||||||
networking.firewall.allowedUDPPorts = [ 53 ];
|
lib.mkIf cfg.enable {
|
||||||
|
networking.firewall.allowedTCPPorts = [ 53 ];
|
||||||
|
networking.firewall.allowedUDPPorts = [ 53 ];
|
||||||
|
|
||||||
security.acme.certs."${cfg.fqdn}".server =
|
security.acme.certs."${cfg.fqdn}".server =
|
||||||
"https://127.0.0.1:8443/acme/kop-acme/directory";
|
"https://127.0.0.1:8443/acme/kop-acme/directory";
|
||||||
# nginx reverse proxy
|
# nginx reverse proxy
|
||||||
services.nginx.virtualHosts.${cfg.fqdn} = {
|
services.nginx.virtualHosts.${cfg.fqdn} = {
|
||||||
forceSSL = cfg.useHttps;
|
forceSSL = cfg.useHttps;
|
||||||
enableACME = cfg.useHttps;
|
enableACME = cfg.useHttps;
|
||||||
quic = cfg.useHttps;
|
quic = cfg.useHttps;
|
||||||
http3 = cfg.useHttps;
|
http3 = cfg.useHttps;
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxyPass =
|
proxyPass =
|
||||||
"http://127.0.0.1:${toString config.services.adguardhome.port}";
|
"http://127.0.0.1:${toString config.services.adguardhome.port}";
|
||||||
proxyWebsockets = true;
|
proxyWebsockets = true;
|
||||||
};
|
|
||||||
};
|
|
||||||
systemd.services.adguardhome = {
|
|
||||||
after = [ "nginx.service" "step-ca.service" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.adguardhome = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
schema_version = 28;
|
|
||||||
users = [{
|
|
||||||
name = "admin";
|
|
||||||
password =
|
|
||||||
"$2y$15$iPzjmUJPTwWUOsDp46GOPO/LYor/jDJjndwy2QlPddaKSD4QXvq9W";
|
|
||||||
}];
|
|
||||||
dns = {
|
|
||||||
bind_hosts = [ "127.0.0.1" ip ] ++ lib.lists.optionals config.custom.services.wireguard.enable [ wireguardIp ];
|
|
||||||
port = 53;
|
|
||||||
protection_enabled = true;
|
|
||||||
filtering_enabled = true;
|
|
||||||
upstream_dns = [
|
|
||||||
"https://dns10.quad9.net/dns-query"
|
|
||||||
"https://dns.adguard-dns.com/dns-query"
|
|
||||||
];
|
|
||||||
use_http3_upstreams = true;
|
|
||||||
};
|
};
|
||||||
querylog = { enabled = false; };
|
};
|
||||||
filters = [
|
systemd.services.adguardhome = {
|
||||||
{
|
after = [ "nginx.service" "step-ca.service" ];
|
||||||
enabled = true;
|
};
|
||||||
url =
|
|
||||||
"https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt";
|
services.adguardhome = {
|
||||||
name = "adguard dns list";
|
enable = true;
|
||||||
id = 1;
|
settings = {
|
||||||
}
|
schema_version = 28;
|
||||||
{
|
users = [{
|
||||||
enabled = true;
|
name = "admin";
|
||||||
url =
|
password =
|
||||||
"https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt";
|
"$2y$15$iPzjmUJPTwWUOsDp46GOPO/LYor/jDJjndwy2QlPddaKSD4QXvq9W";
|
||||||
name = "adguard block list";
|
}];
|
||||||
id = 2;
|
dns = {
|
||||||
}
|
bind_hosts = [ "127.0.0.1" ip ] ++ lib.lists.optionals config.custom.services.wireguard.enable [ wireguardIp ];
|
||||||
{
|
port = 53;
|
||||||
enabled = true;
|
protection_enabled = true;
|
||||||
url = "https://dbl.oisd.nl/";
|
filtering_enabled = true;
|
||||||
name = "big block list";
|
upstream_dns = [
|
||||||
id = 3;
|
"https://dns10.quad9.net/dns-query"
|
||||||
}
|
"https://dns.adguard-dns.com/dns-query"
|
||||||
];
|
];
|
||||||
dhcp = { enabled = false; };
|
use_http3_upstreams = true;
|
||||||
tls = { enabled = false; };
|
};
|
||||||
filtering = {
|
querylog = { enabled = false; };
|
||||||
rewrites = [
|
filters = [
|
||||||
{
|
{
|
||||||
"domain" = "kopatz.ddns.net";
|
enabled = true;
|
||||||
"answer" = ip;
|
url =
|
||||||
|
"https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt";
|
||||||
|
name = "adguard dns list";
|
||||||
|
id = 1;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
"domain" = "kop.oasch.net";
|
enabled = true;
|
||||||
"answer" = ip;
|
url =
|
||||||
|
"https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt";
|
||||||
|
name = "adguard block list";
|
||||||
|
id = 2;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
"domain" = "kavita-kopatz.duckdns.org";
|
enabled = true;
|
||||||
"answer" = ip;
|
url = "https://dbl.oisd.nl/";
|
||||||
|
name = "big block list";
|
||||||
|
id = 3;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
"domain" = "server.home";
|
|
||||||
"answer" = ip;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "server.home.arpa";
|
|
||||||
"answer" = ip;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "adguard.home.arpa";
|
|
||||||
"answer" = ip;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "nextcloud.home.arpa";
|
|
||||||
"answer" = ip;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "kavita.home.arpa";
|
|
||||||
"answer" = ip;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "grafana.home.arpa";
|
|
||||||
"answer" = ip;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "yt.home.arpa";
|
|
||||||
"answer" = ip;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "nextcloud.home.arpa";
|
|
||||||
"answer" = wireguardIp;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "kavita.home.arpa";
|
|
||||||
"answer" = wireguardIp;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "yt.home.arpa";
|
|
||||||
"answer" = wireguardIp;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "turnserver.home.arpa";
|
|
||||||
"answer" = wireguardIp;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "powerline.home.arpa";
|
|
||||||
"answer" = "192.168.0.2";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "3neo.home.arpa";
|
|
||||||
"answer" = "192.168.0.4";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "alcatel.home.arpa";
|
|
||||||
"answer" = "192.168.0.5";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "extender.home.arpa";
|
|
||||||
"answer" = "192.168.0.8";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
"domain" = "inverter.home.arpa";
|
|
||||||
"answer" = "192.168.0.9";
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
|
dhcp = { enabled = false; };
|
||||||
|
tls = { enabled = false; };
|
||||||
|
filtering = {
|
||||||
|
rewrites = [
|
||||||
|
{
|
||||||
|
"domain" = "kopatz.ddns.net";
|
||||||
|
"answer" = ip;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "kop.oasch.net";
|
||||||
|
"answer" = ip;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "kavita-kopatz.duckdns.org";
|
||||||
|
"answer" = ip;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "server.home";
|
||||||
|
"answer" = ip;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "server.home.arpa";
|
||||||
|
"answer" = ip;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "adguard.home.arpa";
|
||||||
|
"answer" = ip;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "nextcloud.home.arpa";
|
||||||
|
"answer" = ip;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "kavita.home.arpa";
|
||||||
|
"answer" = ip;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "grafana.home.arpa";
|
||||||
|
"answer" = ip;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "yt.home.arpa";
|
||||||
|
"answer" = ip;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "nextcloud.home.arpa";
|
||||||
|
"answer" = wireguardIp;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "kavita.home.arpa";
|
||||||
|
"answer" = wireguardIp;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "yt.home.arpa";
|
||||||
|
"answer" = wireguardIp;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "turnserver.home.arpa";
|
||||||
|
"answer" = wireguardIp;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "powerline.home.arpa";
|
||||||
|
"answer" = "192.168.0.2";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "3neo.home.arpa";
|
||||||
|
"answer" = "192.168.0.4";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "alcatel.home.arpa";
|
||||||
|
"answer" = "192.168.0.5";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "extender.home.arpa";
|
||||||
|
"answer" = "192.168.0.8";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"domain" = "inverter.home.arpa";
|
||||||
|
"answer" = "192.168.0.9";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,44 +28,47 @@ in {
|
|||||||
large = [ "/var/lib/radicale/" ];
|
large = [ "/var/lib/radicale/" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.kop-fhcalendar = let
|
systemd.services.kop-fhcalendar =
|
||||||
radicale = if lib.versionOlder lib.version "25.05" then
|
let
|
||||||
(builtins.elemAt
|
radicale =
|
||||||
config.services.radicale.settings.storage.filesystem_folder 0)
|
if lib.versionOlder lib.version "25.05" then
|
||||||
else
|
(builtins.elemAt
|
||||||
config.services.radicale.settings.storage.filesystem_folder;
|
config.services.radicale.settings.storage.filesystem_folder 0)
|
||||||
# not reproducible
|
else
|
||||||
working =
|
config.services.radicale.settings.storage.filesystem_folder;
|
||||||
"${radicale}/collection-root/kopatz/b6d2c446-8109-714a-397f-1f35d3136639";
|
# not reproducible
|
||||||
in {
|
working =
|
||||||
description = "Download fh calendar";
|
"${radicale}/collection-root/kopatz/b6d2c446-8109-714a-397f-1f35d3136639";
|
||||||
wants = [ "network-online.target" ];
|
in
|
||||||
after = [ "network.target" "network-online.target" ];
|
{
|
||||||
wantedBy = [ "multi-user.target" ];
|
description = "Download fh calendar";
|
||||||
startAt = "*-*-* 06:00:00";
|
wants = [ "network-online.target" ];
|
||||||
|
after = [ "network.target" "network-online.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
startAt = "*-*-* 06:00:00";
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
ExecStart = "${pkgs.kop-fhcalendar}/bin/kop-fhcalendar";
|
ExecStart = "${pkgs.kop-fhcalendar}/bin/kop-fhcalendar";
|
||||||
WorkingDirectory = working;
|
WorkingDirectory = working;
|
||||||
BindPaths = [ working ];
|
BindPaths = [ working ];
|
||||||
User = "radicale";
|
User = "radicale";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
RestartSec = "5s";
|
RestartSec = "5s";
|
||||||
PrivateMounts = lib.mkDefault true;
|
PrivateMounts = lib.mkDefault true;
|
||||||
PrivateTmp = lib.mkDefault true;
|
PrivateTmp = lib.mkDefault true;
|
||||||
PrivateUsers = lib.mkDefault true;
|
PrivateUsers = lib.mkDefault true;
|
||||||
ProtectClock = lib.mkDefault true;
|
ProtectClock = lib.mkDefault true;
|
||||||
ProtectControlGroups = lib.mkDefault true;
|
ProtectControlGroups = lib.mkDefault true;
|
||||||
ProtectHome = lib.mkDefault true;
|
ProtectHome = lib.mkDefault true;
|
||||||
ProtectHostname = lib.mkDefault true;
|
ProtectHostname = lib.mkDefault true;
|
||||||
ProtectKernelLogs = lib.mkDefault true;
|
ProtectKernelLogs = lib.mkDefault true;
|
||||||
ProtectKernelModules = lib.mkDefault true;
|
ProtectKernelModules = lib.mkDefault true;
|
||||||
ProtectKernelTunables = lib.mkDefault true;
|
ProtectKernelTunables = lib.mkDefault true;
|
||||||
ProtectSystem = lib.mkDefault "strict";
|
ProtectSystem = lib.mkDefault "strict";
|
||||||
# Needs network access
|
# Needs network access
|
||||||
PrivateNetwork = lib.mkDefault false;
|
PrivateNetwork = lib.mkDefault false;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
{ config, pkgs, lib, inputs, ... }:
|
{ config, pkgs, lib, inputs, ... }:
|
||||||
{
|
{
|
||||||
age.secrets.coturn-secret = {
|
age.secrets.coturn-secret = {
|
||||||
file = ../../secrets/coturn-secret.age;
|
file = ../../secrets/coturn-secret.age;
|
||||||
owner = "turnserver";
|
owner = "turnserver";
|
||||||
group = "turnserver";
|
group = "turnserver";
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall.allowedUDPPortRanges = [ { from = 49000; to=50000; } ];
|
networking.firewall.allowedUDPPortRanges = [{ from = 49000; to = 50000; }];
|
||||||
networking.firewall.allowedUDPPorts = [ 3478 ]; #5349 ];
|
networking.firewall.allowedUDPPorts = [ 3478 ]; #5349 ];
|
||||||
networking.firewall.allowedTCPPorts = [ 3478 ]; #5349 ];
|
networking.firewall.allowedTCPPorts = [ 3478 ]; #5349 ];
|
||||||
|
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
use-auth-secret = true;
|
use-auth-secret = true;
|
||||||
static-auth-secret-file = config.age.secrets.coturn-secret.path;
|
static-auth-secret-file = config.age.secrets.coturn-secret.path;
|
||||||
relay-ips = [
|
relay-ips = [
|
||||||
"192.168.2.1"
|
"192.168.2.1"
|
||||||
];
|
];
|
||||||
listening-ips = [
|
listening-ips = [
|
||||||
"192.168.2.1"
|
"192.168.2.1"
|
||||||
];
|
];
|
||||||
realm = "kopatz.ddns.net";
|
realm = "kopatz.ddns.net";
|
||||||
#cert = "${config.security.acme.certs."kopatz.ddns.net".directory}/full.pem";
|
#cert = "${config.security.acme.certs."kopatz.ddns.net".directory}/full.pem";
|
||||||
@@ -65,9 +65,9 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
#systemd.services.coturn = {
|
#systemd.services.coturn = {
|
||||||
# serviceConfig = {
|
# serviceConfig = {
|
||||||
# User = lib.mkForce "root";
|
# User = lib.mkForce "root";
|
||||||
# Group = lib.mkForce "root";
|
# Group = lib.mkForce "root";
|
||||||
# };
|
# };
|
||||||
# };
|
# };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, config, ...}:
|
{ pkgs, config, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./acme.nix
|
./acme.nix
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
{ config, pkgs, lib, inputs, ... }:
|
{ config, pkgs, lib, inputs, ... }:
|
||||||
{
|
{
|
||||||
age.secrets.duckdns = {
|
age.secrets.duckdns = {
|
||||||
file = ../../secrets/duckdns.age;
|
file = ../../secrets/duckdns.age;
|
||||||
};
|
};
|
||||||
services.ddclient = {
|
services.ddclient = {
|
||||||
enable = true;
|
enable = true;
|
||||||
protocol = "duckdns";
|
protocol = "duckdns";
|
||||||
passwordFile = config.age.secrets.duckdns.path;
|
passwordFile = config.age.secrets.duckdns.path;
|
||||||
domains = ["wachbirn.duckdns.org"];
|
domains = [ "wachbirn.duckdns.org" ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,17 +13,17 @@ in
|
|||||||
};
|
};
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
users.users.fileshelter = {
|
users.users.fileshelter = {
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
uid = cfg.uid;
|
uid = cfg.uid;
|
||||||
group = "fileshelter";
|
group = "fileshelter";
|
||||||
};
|
};
|
||||||
users.groups.fileshelter = {};
|
users.groups.fileshelter = { };
|
||||||
age.secrets.fileshelter-conf = {
|
age.secrets.fileshelter-conf = {
|
||||||
file = ../../secrets/fileshelter-conf.age;
|
file = ../../secrets/fileshelter-conf.age;
|
||||||
owner = "fileshelter";
|
owner = "fileshelter";
|
||||||
};
|
};
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d /data/fileshelter 0770 fileshelter fileshelter -"
|
"d /data/fileshelter 0770 fileshelter fileshelter -"
|
||||||
];
|
];
|
||||||
custom.misc.docker.enable = true;
|
custom.misc.docker.enable = true;
|
||||||
virtualisation.oci-containers.backend = "docker";
|
virtualisation.oci-containers.backend = "docker";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, config, ...}:
|
{ pkgs, config, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./terraria.nix
|
./terraria.nix
|
||||||
|
|||||||
@@ -1,59 +1,61 @@
|
|||||||
# valheim.nix
|
# valheim.nix
|
||||||
{config, pkgs, lib, ...}: let
|
{ config, pkgs, lib, ... }:
|
||||||
|
let
|
||||||
join = builtins.concatStringsSep " ";
|
join = builtins.concatStringsSep " ";
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
|
|
||||||
services.cron = {
|
services.cron = {
|
||||||
enable = true;
|
enable = true;
|
||||||
systemCronJobs = [
|
systemCronJobs = [
|
||||||
"0 6 * * * root systemctl restart palworld"
|
"0 6 * * * root systemctl restart palworld"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall.allowedUDPPorts = [ 8211 ]; #5349 ];
|
networking.firewall.allowedUDPPorts = [ 8211 ]; #5349 ];
|
||||||
users.users.palworld = {
|
users.users.palworld = {
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
# Valheim puts save data in the home directory.
|
# Valheim puts save data in the home directory.
|
||||||
home = "/var/lib/palworld";
|
home = "/var/lib/palworld";
|
||||||
createHome = true;
|
createHome = true;
|
||||||
homeMode = "750";
|
homeMode = "750";
|
||||||
group = "palworld";
|
group = "palworld";
|
||||||
};
|
};
|
||||||
|
|
||||||
users.groups.palworld = {};
|
users.groups.palworld = { };
|
||||||
|
|
||||||
systemd.services.palworld = {
|
systemd.services.palworld = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
wants = [ "network-online.target" ];
|
wants = [ "network-online.target" ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStartPre = join [
|
ExecStartPre = join [
|
||||||
"${pkgs.steamcmd}/bin/steamcmd"
|
"${pkgs.steamcmd}/bin/steamcmd"
|
||||||
"+force_install_dir /var/lib/palworld"
|
"+force_install_dir /var/lib/palworld"
|
||||||
"+login anonymous"
|
"+login anonymous"
|
||||||
"+app_update 2394010"
|
"+app_update 2394010"
|
||||||
"+quit"
|
"+quit"
|
||||||
"&& mkdir -p /var/lib/palworld/.steam/sdk64"
|
"&& mkdir -p /var/lib/palworld/.steam/sdk64"
|
||||||
"&& cp /var/lib/palworld/linux64/steamclient.so /var/lib/palworld/.steam/sdk64/."
|
"&& cp /var/lib/palworld/linux64/steamclient.so /var/lib/palworld/.steam/sdk64/."
|
||||||
];
|
];
|
||||||
ExecStart = join [
|
ExecStart = join [
|
||||||
"${pkgs.steam-run}/bin/steam-run /var/lib/palworld/Pal/Binaries/Linux/PalServer-Linux-Test Pal"
|
"${pkgs.steam-run}/bin/steam-run /var/lib/palworld/Pal/Binaries/Linux/PalServer-Linux-Test Pal"
|
||||||
"-useperfthreads"
|
"-useperfthreads"
|
||||||
"-NoAsyncLoadingThread"
|
"-NoAsyncLoadingThread"
|
||||||
"-UseMultithreadForDS"
|
"-UseMultithreadForDS"
|
||||||
];
|
];
|
||||||
Nice = "-5";
|
Nice = "-5";
|
||||||
PrivateTmp = true;
|
PrivateTmp = true;
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
User = "palworld";
|
User = "palworld";
|
||||||
WorkingDirectory = "~";
|
WorkingDirectory = "~";
|
||||||
};
|
};
|
||||||
environment = {
|
environment = {
|
||||||
# linux64 directory is required by Valheim.
|
# linux64 directory is required by Valheim.
|
||||||
LD_LIBRARY_PATH = "/var/lib/palworld/linux64:${pkgs.glibc}/lib";
|
LD_LIBRARY_PATH = "/var/lib/palworld/linux64:${pkgs.glibc}/lib";
|
||||||
SteamAppId = "2394010";
|
SteamAppId = "2394010";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{pkgs, config, lib, ...}:
|
{ pkgs, config, lib, ... }:
|
||||||
let
|
let
|
||||||
useHttps = config.services.step-ca.enable;
|
useHttps = config.services.step-ca.enable;
|
||||||
fqdn = "grafana.home.arpa";
|
fqdn = "grafana.home.arpa";
|
||||||
@@ -25,25 +25,25 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
provision.alerting.contactPoints.path = config.age.secrets.grafana-contact-points.path;
|
provision.alerting.contactPoints.path = config.age.secrets.grafana-contact-points.path;
|
||||||
provision.alerting.policies.path = ./grafana/notification-policies.yml;
|
provision.alerting.policies.path = ./grafana/notification-policies.yml;
|
||||||
provision.alerting.templates.path = ./grafana/alerts.yml;
|
provision.alerting.templates.path = ./grafana/alerts.yml;
|
||||||
provision.datasources.settings = {
|
provision.datasources.settings = {
|
||||||
datasources =
|
datasources =
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name = "DS_PROMETHEUS";
|
name = "DS_PROMETHEUS";
|
||||||
url = "http://127.0.0.1:${toString config.services.prometheus.port}";
|
url = "http://127.0.0.1:${toString config.services.prometheus.port}";
|
||||||
type = "prometheus";
|
type = "prometheus";
|
||||||
isDefault = true;
|
isDefault = true;
|
||||||
# This has to match the prometheus scrape interval, otherwise the $__rate_interval variable wont work.
|
# This has to match the prometheus scrape interval, otherwise the $__rate_interval variable wont work.
|
||||||
jsonData.timeInterval = "60s";
|
jsonData.timeInterval = "60s";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
name = "loki";
|
name = "loki";
|
||||||
url = "http://localhost:3100";
|
url = "http://localhost:3100";
|
||||||
type = "loki";
|
type = "loki";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
provision.dashboards.settings.providers = [{
|
provision.dashboards.settings.providers = [{
|
||||||
name = "provisioned-dashboards";
|
name = "provisioned-dashboards";
|
||||||
@@ -63,8 +63,8 @@ in
|
|||||||
quic = useHttps;
|
quic = useHttps;
|
||||||
http3 = useHttps;
|
http3 = useHttps;
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxyPass = "http://127.0.0.1:${toString config.services.grafana.settings.server.http_port}";
|
proxyPass = "http://127.0.0.1:${toString config.services.grafana.settings.server.http_port}";
|
||||||
proxyWebsockets = true;
|
proxyWebsockets = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ in
|
|||||||
settings.namespaces = [
|
settings.namespaces = [
|
||||||
{
|
{
|
||||||
name = "nginxlog";
|
name = "nginxlog";
|
||||||
source.files = ["/var/log/nginx/access.log"];
|
source.files = [ "/var/log/nginx/access.log" ];
|
||||||
format = "$remote_addr - $remote_user [$time_local] \"$request\" $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\"";
|
format = "$remote_addr - $remote_user [$time_local] \"$request\" $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\"";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@@ -101,18 +101,18 @@ in
|
|||||||
{
|
{
|
||||||
job_name = "scrapema";
|
job_name = "scrapema";
|
||||||
static_configs = [{
|
static_configs = [{
|
||||||
targets = [
|
targets = [
|
||||||
"127.0.0.1:${toString config.services.prometheus.exporters.node.port}"
|
"127.0.0.1:${toString config.services.prometheus.exporters.node.port}"
|
||||||
] ++
|
] ++
|
||||||
(lib.optional config.services.cadvisor.enable "${config.services.cadvisor.listenAddress}:${toString config.services.cadvisor.port}") ++
|
(lib.optional config.services.cadvisor.enable "${config.services.cadvisor.listenAddress}:${toString config.services.cadvisor.port}") ++
|
||||||
(lib.optional config.services.prometheus.exporters.nginx.enable "127.0.0.1:${toString config.services.prometheus.exporters.nginx.port}") ++
|
(lib.optional config.services.prometheus.exporters.nginx.enable "127.0.0.1:${toString config.services.prometheus.exporters.nginx.port}") ++
|
||||||
(lib.optional config.services.prometheus.exporters.nginxlog.enable "127.0.0.1:${toString config.services.prometheus.exporters.nginxlog.port}")
|
(lib.optional config.services.prometheus.exporters.nginxlog.enable "127.0.0.1:${toString config.services.prometheus.exporters.nginxlog.port}")
|
||||||
;
|
;
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.cadvisor = {
|
services.cadvisor = {
|
||||||
enable = true;
|
enable = true;
|
||||||
listenAddress = "127.0.0.1";
|
listenAddress = "127.0.0.1";
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
config = {
|
config = {
|
||||||
# Includes dependencies for a basic setup
|
# Includes dependencies for a basic setup
|
||||||
# https://www.home-assistant.io/integrations/default_config/
|
# https://www.home-assistant.io/integrations/default_config/
|
||||||
default_config = {};
|
default_config = { };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ config, vars, ...} :
|
{ config, vars, ... }:
|
||||||
let
|
let
|
||||||
fqdn = "yt.home.arpa";
|
fqdn = "yt.home.arpa";
|
||||||
useHttps = config.services.step-ca.enable;
|
useHttps = config.services.step-ca.enable;
|
||||||
|
|||||||
@@ -21,133 +21,138 @@ in {
|
|||||||
};
|
};
|
||||||
isTest = mkEnableOption "Is this a test vm?";
|
isTest = mkEnableOption "Is this a test vm?";
|
||||||
};
|
};
|
||||||
config = let
|
config =
|
||||||
fqdn = "kavita-kopatz.duckdns.org";
|
let
|
||||||
useStepCa = false; # config.services.step-ca.enable;
|
fqdn = "kavita-kopatz.duckdns.org";
|
||||||
useHttps = cfg.https;
|
useStepCa = false; # config.services.step-ca.enable;
|
||||||
baseDir = cfg.dir;
|
useHttps = cfg.https;
|
||||||
mangal = "${pkgs.mangal-patched}/bin/mangal";
|
baseDir = cfg.dir;
|
||||||
githubRunnerEnabled = config.services.github-runners ? oberprofis.enable;
|
mangal = "${pkgs.mangal-patched}/bin/mangal";
|
||||||
in lib.mkIf cfg.enable {
|
githubRunnerEnabled = config.services.github-runners ? oberprofis.enable;
|
||||||
networking.firewall.allowedTCPPorts = [ 5000 ];
|
in
|
||||||
systemd.tmpfiles.rules = [
|
lib.mkIf cfg.enable {
|
||||||
(if githubRunnerEnabled then
|
networking.firewall.allowedTCPPorts = [ 5000 ];
|
||||||
"d ${baseDir} 0750 kavita github-actions-runner -"
|
systemd.tmpfiles.rules = [
|
||||||
else
|
(if githubRunnerEnabled then
|
||||||
"d ${baseDir} 0770 kavita kavita -")
|
"d ${baseDir} 0750 kavita github-actions-runner -"
|
||||||
"d ${baseDir}/manga 0770 kavita kavita -"
|
else
|
||||||
] ++ lib.optional githubRunnerEnabled
|
"d ${baseDir} 0770 kavita kavita -")
|
||||||
"d ${baseDir}/github 0770 github-actions-runner kavita -";
|
"d ${baseDir}/manga 0770 kavita kavita -"
|
||||||
|
] ++ lib.optional githubRunnerEnabled
|
||||||
|
"d ${baseDir}/github 0770 github-actions-runner kavita -";
|
||||||
|
|
||||||
age.secrets.kavita = mkIf (!cfg.isTest) {
|
age.secrets.kavita = mkIf (!cfg.isTest) {
|
||||||
file = ../../secrets/kavita.age;
|
file = ../../secrets/kavita.age;
|
||||||
owner = "kavita";
|
owner = "kavita";
|
||||||
group = "kavita";
|
group = "kavita";
|
||||||
};
|
|
||||||
|
|
||||||
services.kavita = {
|
|
||||||
enable = true;
|
|
||||||
user = "kavita";
|
|
||||||
package = let
|
|
||||||
backend = pkgs.unstable.kavita.backend.overrideAttrs
|
|
||||||
(old: { patches = old.patches ++ [ ./kavita-patches-chapter-parsing.diff ./kavita-page-size.diff ]; });
|
|
||||||
kavitaPatched = pkgs.unstable.kavita.overrideAttrs (old: { backend = backend; });
|
|
||||||
in kavitaPatched;
|
|
||||||
settings = {
|
|
||||||
Port = 5000;
|
|
||||||
IpAddresses = "127.0.0.1";
|
|
||||||
BaseUrl = "/kavita";
|
|
||||||
};
|
};
|
||||||
dataDir = baseDir;
|
|
||||||
tokenKeyFile = if cfg.isTest then
|
|
||||||
(builtins.toFile "test"
|
|
||||||
"wWKNeGUslGILrUUp8Dnn4xyYnivZWBb8uqjKg3ALyCs7reV5v3CtE/E2b6i0Mwz1Xw1p9a0wcduRDNoa8Yh8kQ==")
|
|
||||||
else
|
|
||||||
config.age.secrets.kavita.path;
|
|
||||||
};
|
|
||||||
|
|
||||||
#todo: base url needs new kavita version
|
services.kavita = {
|
||||||
systemd.services = {
|
enable = true;
|
||||||
kavita = {
|
user = "kavita";
|
||||||
after = [ "nginx.service" ] ++ lib.optional useStepCa "step-ca.service";
|
package =
|
||||||
|
let
|
||||||
|
backend = pkgs.unstable.kavita.backend.overrideAttrs
|
||||||
|
(old: { patches = old.patches ++ [ ./kavita-patches-chapter-parsing.diff ./kavita-page-size.diff ]; });
|
||||||
|
kavitaPatched = pkgs.unstable.kavita.overrideAttrs (old: { backend = backend; });
|
||||||
|
in
|
||||||
|
kavitaPatched;
|
||||||
|
settings = {
|
||||||
|
Port = 5000;
|
||||||
|
IpAddresses = "127.0.0.1";
|
||||||
|
BaseUrl = "/kavita";
|
||||||
|
};
|
||||||
|
dataDir = baseDir;
|
||||||
|
tokenKeyFile =
|
||||||
|
if cfg.isTest then
|
||||||
|
(builtins.toFile "test"
|
||||||
|
"wWKNeGUslGILrUUp8Dnn4xyYnivZWBb8uqjKg3ALyCs7reV5v3CtE/E2b6i0Mwz1Xw1p9a0wcduRDNoa8Yh8kQ==")
|
||||||
|
else
|
||||||
|
config.age.secrets.kavita.path;
|
||||||
};
|
};
|
||||||
download-manga = mkIf cfg.autoDownload {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
|
|
||||||
wants = [ "network-online.target" ];
|
#todo: base url needs new kavita version
|
||||||
after = [ "network-online.target" ];
|
systemd.services = {
|
||||||
startAt = "*-*-* 19:00:00";
|
kavita = {
|
||||||
restartIfChanged = false;
|
after = [ "nginx.service" ] ++ lib.optional useStepCa "step-ca.service";
|
||||||
script = ''
|
};
|
||||||
${mangal} clear -q
|
download-manga = mkIf cfg.autoDownload {
|
||||||
${mangal} clear -c
|
wantedBy = [ "multi-user.target" ];
|
||||||
${mangal} inline -S Mangapill -q omniscient -m first -d
|
|
||||||
${mangal} inline -S Mangapill --query "oshi-no-ko" --manga first --download
|
wants = [ "network-online.target" ];
|
||||||
${mangal} inline -S Mangapill --query "Frieren" --manga first --download -f
|
after = [ "network-online.target" ];
|
||||||
${mangal} inline -S Mangapill --query "Chainsaw" --manga first --download
|
startAt = "*-*-* 19:00:00";
|
||||||
${mangal} inline -S Mangapill --query "Jujutsu%20Kaisen" --manga first --download
|
restartIfChanged = false;
|
||||||
${mangal} inline -S Mangapill --query "solo-leveling" --manga first --download
|
script = ''
|
||||||
${mangal} inline -S Mangapill --query "the-greatest-real-estate" --manga first --download
|
${mangal} clear -q
|
||||||
${mangal} inline -S Mangapill --query "66666_years" --manga first --download
|
${mangal} clear -c
|
||||||
${mangal} inline -S Mangapill --query "Return_of_the_blossoming" --manga first --download
|
${mangal} inline -S Mangapill -q omniscient -m first -d
|
||||||
${mangal} inline -S Mangapill --query "path_of_the_shaman" --manga first --download
|
${mangal} inline -S Mangapill --query "oshi-no-ko" --manga first --download
|
||||||
${mangal} inline -S Mangapill --query "pick_me_up" --manga first --download
|
${mangal} inline -S Mangapill --query "Frieren" --manga first --download -f
|
||||||
${mangal} inline -S Mangapill --query "revenge_of_the_iron_blooded" --manga first --download
|
${mangal} inline -S Mangapill --query "Chainsaw" --manga first --download
|
||||||
${mangal} inline -S Mangapill --query "northern_blade" --manga first --download
|
${mangal} inline -S Mangapill --query "Jujutsu%20Kaisen" --manga first --download
|
||||||
${mangal} inline -S Mangapill --query "Dungeon_reset" --manga first --download
|
${mangal} inline -S Mangapill --query "solo-leveling" --manga first --download
|
||||||
${mangal} inline -S Mangapill --query "iruma-kun" --manga first --download
|
${mangal} inline -S Mangapill --query "the-greatest-real-estate" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "grand_blue" --manga first --download
|
${mangal} inline -S Mangapill --query "66666_years" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "sss-class_suicide" --manga first --download
|
${mangal} inline -S Mangapill --query "Return_of_the_blossoming" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "cultivation_chat" --manga first --download
|
${mangal} inline -S Mangapill --query "path_of_the_shaman" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "gokushufudo" --manga first --download
|
${mangal} inline -S Mangapill --query "pick_me_up" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "slime" --manga first --download
|
${mangal} inline -S Mangapill --query "revenge_of_the_iron_blooded" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "nano_machine" --manga first --download
|
${mangal} inline -S Mangapill --query "northern_blade" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "kill_the_hero" --manga first --download
|
${mangal} inline -S Mangapill --query "Dungeon_reset" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "Seoul_Station_Necromancer" --manga first --download
|
${mangal} inline -S Mangapill --query "iruma-kun" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "grandmaster_of_demonic" --manga first --download
|
${mangal} inline -S Manganato --query "grand_blue" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "becoming_the_monarch" --manga first --download
|
${mangal} inline -S Manganato --query "sss-class_suicide" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "sleeping" --manga first --download
|
${mangal} inline -S Manganato --query "cultivation_chat" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "Terror_man" --manga first --download
|
${mangal} inline -S Manganato --query "gokushufudo" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "I_Stole_the_Number_One_Ranker" --manga first --download
|
${mangal} inline -S Manganato --query "slime" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "hidan_no_aria" --manga first --download
|
${mangal} inline -S Manganato --query "nano_machine" --manga first --download
|
||||||
${mangal} inline -S AsuraScans --query "the_max_level_hero" --manga first --download
|
${mangal} inline -S Manganato --query "kill_the_hero" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "Parallel_City" --manga first --download
|
${mangal} inline -S Manganato --query "Seoul_Station_Necromancer" --manga first --download
|
||||||
${mangal} inline -S Manganato --query "Existence" --manga first --download
|
${mangal} inline -S Manganato --query "grandmaster_of_demonic" --manga first --download
|
||||||
${mangal} inline -S Mangapill --query "Call_of_the_Night" --manga first --download
|
${mangal} inline -S Manganato --query "becoming_the_monarch" --manga first --download
|
||||||
'';
|
${mangal} inline -S Manganato --query "sleeping" --manga first --download
|
||||||
serviceConfig = {
|
${mangal} inline -S Manganato --query "Terror_man" --manga first --download
|
||||||
PrivateTmp = true;
|
${mangal} inline -S Manganato --query "I_Stole_the_Number_One_Ranker" --manga first --download
|
||||||
User = "kavita";
|
${mangal} inline -S Manganato --query "hidan_no_aria" --manga first --download
|
||||||
Group = "kavita";
|
${mangal} inline -S AsuraScans --query "the_max_level_hero" --manga first --download
|
||||||
Type = "oneshot";
|
${mangal} inline -S Manganato --query "Parallel_City" --manga first --download
|
||||||
WorkingDirectory = "${baseDir}/manga";
|
${mangal} inline -S Manganato --query "Existence" --manga first --download
|
||||||
|
${mangal} inline -S Mangapill --query "Call_of_the_Night" --manga first --download
|
||||||
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
PrivateTmp = true;
|
||||||
|
User = "kavita";
|
||||||
|
Group = "kavita";
|
||||||
|
Type = "oneshot";
|
||||||
|
WorkingDirectory = "${baseDir}/manga";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
# services.nginx.virtualHosts."kopatz.ddns.net".locations."/kavita" = {
|
# services.nginx.virtualHosts."kopatz.ddns.net".locations."/kavita" = {
|
||||||
# proxyPass = "http://127.0.0.1:5000";
|
# proxyPass = "http://127.0.0.1:5000";
|
||||||
# extraConfig = ''
|
# extraConfig = ''
|
||||||
# add_header Access-Control-Allow-Origin *;
|
# add_header Access-Control-Allow-Origin *;
|
||||||
# add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
|
# add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
|
||||||
# add_header Access-Control-Allow-Headers "Authorization, Origin, X-Requested-With, Content-Type, Accept";
|
# add_header Access-Control-Allow-Headers "Authorization, Origin, X-Requested-With, Content-Type, Accept";
|
||||||
# '';
|
# '';
|
||||||
# };
|
# };
|
||||||
security.acme.certs."${fqdn}" = lib.mkIf useStepCa {
|
security.acme.certs."${fqdn}" = lib.mkIf useStepCa {
|
||||||
server = "https://127.0.0.1:8443/acme/kop-acme/directory";
|
server = "https://127.0.0.1:8443/acme/kop-acme/directory";
|
||||||
|
};
|
||||||
|
services.nginx.virtualHosts."${fqdn}" = {
|
||||||
|
forceSSL = useHttps;
|
||||||
|
enableACME = useHttps;
|
||||||
|
quic = useHttps;
|
||||||
|
http3 = useHttps;
|
||||||
|
locations."/".proxyPass = "http://127.0.0.1:5000";
|
||||||
|
locations."/".extraConfig = ''
|
||||||
|
more_clear_headers 'x-frame-options';
|
||||||
|
add_header Access-Control-Allow-Origin *;
|
||||||
|
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
|
||||||
|
add_header Access-Control-Allow-Headers "Authorization, Origin, X-Requested-With, Content-Type, Accept";
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
services.nginx.virtualHosts."${fqdn}" = {
|
|
||||||
forceSSL = useHttps;
|
|
||||||
enableACME = useHttps;
|
|
||||||
quic = useHttps;
|
|
||||||
http3 = useHttps;
|
|
||||||
locations."/".proxyPass = "http://127.0.0.1:5000";
|
|
||||||
locations."/".extraConfig = ''
|
|
||||||
more_clear_headers 'x-frame-options';
|
|
||||||
add_header Access-Control-Allow-Origin *;
|
|
||||||
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
|
|
||||||
add_header Access-Control-Allow-Headers "Authorization, Origin, X-Requested-With, Content-Type, Accept";
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ pkgs, config, lib, ...}:
|
{ pkgs, config, lib, ... }:
|
||||||
# idk, dont need this
|
# idk, dont need this
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
@@ -6,38 +6,40 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.custom.services.kubernetes = {
|
options.custom.services.kubernetes = {
|
||||||
enable = mkEnableOption "Enables kubernetes";
|
enable = mkEnableOption "Enables kubernetes";
|
||||||
};
|
};
|
||||||
config = let
|
config =
|
||||||
kubeMasterIP = "localhost";
|
let
|
||||||
kubeMasterHostname = "localhost";
|
kubeMasterIP = "localhost";
|
||||||
in lib.mkIf cfg.enable {
|
kubeMasterHostname = "localhost";
|
||||||
|
in
|
||||||
|
lib.mkIf cfg.enable {
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [
|
networking.firewall.allowedTCPPorts = [
|
||||||
6443 # k3s: required so that pods can reach the API server (running on port 6443 by default)
|
6443 # k3s: required so that pods can reach the API server (running on port 6443 by default)
|
||||||
# 2379 # k3s, etcd clients: required if using a "High Availability Embedded etcd" configuration
|
# 2379 # k3s, etcd clients: required if using a "High Availability Embedded etcd" configuration
|
||||||
# 2380 # k3s, etcd peers: required if using a "High Availability Embedded etcd" configuration
|
# 2380 # k3s, etcd peers: required if using a "High Availability Embedded etcd" configuration
|
||||||
];
|
];
|
||||||
networking.firewall.allowedUDPPorts = [
|
networking.firewall.allowedUDPPorts = [
|
||||||
# 8472 # k3s, flannel: required if using multi-node for inter-node networking
|
# 8472 # k3s, flannel: required if using multi-node for inter-node networking
|
||||||
];
|
];
|
||||||
services.k3s.enable = true;
|
services.k3s.enable = true;
|
||||||
services.k3s.role = "server";
|
services.k3s.role = "server";
|
||||||
services.k3s.extraFlags = toString [
|
services.k3s.extraFlags = toString [
|
||||||
# "--kubelet-arg=v=4" # Optionally add additional args to k3s
|
# "--kubelet-arg=v=4" # Optionally add additional args to k3s
|
||||||
];
|
];
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
k3s
|
k3s
|
||||||
];
|
];
|
||||||
#services.kubernetes = {
|
#services.kubernetes = {
|
||||||
# roles = ["master" "node"];
|
# roles = ["master" "node"];
|
||||||
# masterAddress = "localhost";
|
# masterAddress = "localhost";
|
||||||
# apiserverAddress = "https://localhost:6443";
|
# apiserverAddress = "https://localhost:6443";
|
||||||
# apiserver = {
|
# apiserver = {
|
||||||
# advertiseAddress = "127.0.0.1";
|
# advertiseAddress = "127.0.0.1";
|
||||||
# securePort = 6443;
|
# securePort = 6443;
|
||||||
# allowPrivileged = true;
|
# allowPrivileged = true;
|
||||||
# };
|
# };
|
||||||
#};
|
#};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,66 +1,66 @@
|
|||||||
{ pkgs, ...}:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
services.minecraft-server = {
|
services.minecraft-server = {
|
||||||
enable = true;
|
enable = true;
|
||||||
eula = true;
|
eula = true;
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
package = pkgs.unstable.papermc;
|
package = pkgs.unstable.papermc;
|
||||||
declarative = true;
|
declarative = true;
|
||||||
whitelist = {
|
whitelist = {
|
||||||
coolBayram = "514afd03-8ca2-4f60-abe4-4c2a365d223b";
|
coolBayram = "514afd03-8ca2-4f60-abe4-4c2a365d223b";
|
||||||
filipus098 = "a09fb009-be78-4e26-9f33-1534186e2228";
|
filipus098 = "a09fb009-be78-4e26-9f33-1534186e2228";
|
||||||
};
|
|
||||||
serverProperties = {
|
|
||||||
allow-flight=true;
|
|
||||||
allow-nether=true;
|
|
||||||
broadcast-console-to-ops=true;
|
|
||||||
broadcast-rcon-to-ops=true;
|
|
||||||
debug=false;
|
|
||||||
difficulty="hard";
|
|
||||||
enable-command-block=false;
|
|
||||||
enable-jmx-monitoring=false;
|
|
||||||
enable-query=false;
|
|
||||||
enable-rcon=false;
|
|
||||||
enable-status=true;
|
|
||||||
enforce-secure-profile=true;
|
|
||||||
enforce-whitelist=false;
|
|
||||||
entity-broadcast-range-percentage=100;
|
|
||||||
force-gamemode=false;
|
|
||||||
function-permission-level=2;
|
|
||||||
gamemode="survival";
|
|
||||||
generate-structures=true;
|
|
||||||
hardcore=false;
|
|
||||||
hide-online-players=false;
|
|
||||||
initial-enabled-packs="vanilla";
|
|
||||||
level-name="budak";
|
|
||||||
level-type="minecraft\:normal";
|
|
||||||
log-ips=true;
|
|
||||||
max-chained-neighbor-updates=1000000;
|
|
||||||
max-players=5;
|
|
||||||
max-tick-time=60000;
|
|
||||||
max-world-size=29999984;
|
|
||||||
motd="A Minecraft Server";
|
|
||||||
network-compression-threshold=256;
|
|
||||||
online-mode=true;
|
|
||||||
op-permission-level=4;
|
|
||||||
player-idle-timeout=0;
|
|
||||||
prevent-proxy-connections=false;
|
|
||||||
pvp=true;
|
|
||||||
"query.port"=25565;
|
|
||||||
rate-limit=0;
|
|
||||||
"rcon.password"="123asdadsqwe123123";
|
|
||||||
"rcon.port"=25575;
|
|
||||||
require-resource-pack=false;
|
|
||||||
server-port=25565;
|
|
||||||
simulation-distance=10;
|
|
||||||
spawn-animals=true;
|
|
||||||
spawn-monsters=true;
|
|
||||||
spawn-npcs=true;
|
|
||||||
spawn-protection=16;
|
|
||||||
sync-chunk-writes=true;
|
|
||||||
use-native-transport=true;
|
|
||||||
view-distance=10;
|
|
||||||
white-list=true;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
serverProperties = {
|
||||||
|
allow-flight = true;
|
||||||
|
allow-nether = true;
|
||||||
|
broadcast-console-to-ops = true;
|
||||||
|
broadcast-rcon-to-ops = true;
|
||||||
|
debug = false;
|
||||||
|
difficulty = "hard";
|
||||||
|
enable-command-block = false;
|
||||||
|
enable-jmx-monitoring = false;
|
||||||
|
enable-query = false;
|
||||||
|
enable-rcon = false;
|
||||||
|
enable-status = true;
|
||||||
|
enforce-secure-profile = true;
|
||||||
|
enforce-whitelist = false;
|
||||||
|
entity-broadcast-range-percentage = 100;
|
||||||
|
force-gamemode = false;
|
||||||
|
function-permission-level = 2;
|
||||||
|
gamemode = "survival";
|
||||||
|
generate-structures = true;
|
||||||
|
hardcore = false;
|
||||||
|
hide-online-players = false;
|
||||||
|
initial-enabled-packs = "vanilla";
|
||||||
|
level-name = "budak";
|
||||||
|
level-type = "minecraft\:normal";
|
||||||
|
log-ips = true;
|
||||||
|
max-chained-neighbor-updates = 1000000;
|
||||||
|
max-players = 5;
|
||||||
|
max-tick-time = 60000;
|
||||||
|
max-world-size = 29999984;
|
||||||
|
motd = "A Minecraft Server";
|
||||||
|
network-compression-threshold = 256;
|
||||||
|
online-mode = true;
|
||||||
|
op-permission-level = 4;
|
||||||
|
player-idle-timeout = 0;
|
||||||
|
prevent-proxy-connections = false;
|
||||||
|
pvp = true;
|
||||||
|
"query.port" = 25565;
|
||||||
|
rate-limit = 0;
|
||||||
|
"rcon.password" = "123asdadsqwe123123";
|
||||||
|
"rcon.port" = 25575;
|
||||||
|
require-resource-pack = false;
|
||||||
|
server-port = 25565;
|
||||||
|
simulation-distance = 10;
|
||||||
|
spawn-animals = true;
|
||||||
|
spawn-monsters = true;
|
||||||
|
spawn-npcs = true;
|
||||||
|
spawn-protection = 16;
|
||||||
|
sync-chunk-writes = true;
|
||||||
|
use-native-transport = true;
|
||||||
|
view-distance = 10;
|
||||||
|
white-list = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{ vars, ... }:
|
{ vars, ... }:
|
||||||
let
|
let
|
||||||
ip = vars.ipv4;
|
ip = vars.ipv4;
|
||||||
wireguardIp = vars.wireguardIp;
|
wireguardIp = vars.wireguardIp;
|
||||||
in
|
in
|
||||||
@@ -54,6 +54,6 @@ in
|
|||||||
perf = no
|
perf = no
|
||||||
freeipmi = no
|
freeipmi = no
|
||||||
apps = yes
|
apps = yes
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,70 +5,70 @@ let
|
|||||||
useHttps = config.services.step-ca.enable;
|
useHttps = config.services.step-ca.enable;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./postgres.nix ];
|
imports = [ ./postgres.nix ];
|
||||||
security.acme.certs."${fqdn}".server = "https://127.0.0.1:8443/acme/kop-acme/directory";
|
security.acme.certs."${fqdn}".server = "https://127.0.0.1:8443/acme/kop-acme/directory";
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
# Use recommended settings
|
# Use recommended settings
|
||||||
recommendedGzipSettings = true;
|
recommendedGzipSettings = true;
|
||||||
recommendedOptimisation = true;
|
recommendedOptimisation = true;
|
||||||
recommendedProxySettings = true;
|
recommendedProxySettings = true;
|
||||||
recommendedTlsSettings = true;
|
recommendedTlsSettings = true;
|
||||||
|
|
||||||
# Only allow PFS-enabled ciphers with AES256
|
# Only allow PFS-enabled ciphers with AES256
|
||||||
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
|
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
|
||||||
|
|
||||||
# Setup Nextcloud virtual host to listen on ports
|
# Setup Nextcloud virtual host to listen on ports
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
"${fqdn}" = {
|
"${fqdn}" = {
|
||||||
serverAliases = [ wireguardIp ];
|
serverAliases = [ wireguardIp ];
|
||||||
## Force HTTP redirect to HTTPS
|
## Force HTTP redirect to HTTPS
|
||||||
forceSSL = useHttps;
|
forceSSL = useHttps;
|
||||||
enableACME = useHttps;
|
enableACME = useHttps;
|
||||||
locations."~ \\.php(?:$|/)".extraConfig = ''
|
locations."~ \\.php(?:$|/)".extraConfig = ''
|
||||||
client_max_body_size 20G;
|
client_max_body_size 20G;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
age.secrets.nextcloud-admin = {
|
||||||
|
file = ../../secrets/nextcloud-admin.age;
|
||||||
|
owner = "nextcloud";
|
||||||
|
group = "nextcloud";
|
||||||
|
};
|
||||||
|
services.nextcloud = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.nextcloud28;
|
||||||
|
https = true;
|
||||||
|
hostName = "nextcloud.home.arpa";
|
||||||
|
config.adminpassFile = config.age.secrets.nextcloud-admin.path;
|
||||||
|
config.dbtype = "pgsql";
|
||||||
|
database.createLocally = true;
|
||||||
|
settings.trusted_domains = [ wireguardIp "nextcloud.home.arpa" ];
|
||||||
|
home = "/mnt/250ssd/nextcloud";
|
||||||
|
extraApps = with config.services.nextcloud.package.packages.apps; {
|
||||||
|
inherit onlyoffice calendar mail;
|
||||||
};
|
};
|
||||||
|
|
||||||
age.secrets.nextcloud-admin = {
|
phpOptions = {
|
||||||
file = ../../secrets/nextcloud-admin.age;
|
upload_max_filesize = lib.mkForce "20G";
|
||||||
owner = "nextcloud";
|
post_max_size = lib.mkForce "20G";
|
||||||
group = "nextcloud";
|
|
||||||
};
|
|
||||||
services.nextcloud = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.nextcloud28;
|
|
||||||
https = true;
|
|
||||||
hostName = "nextcloud.home.arpa";
|
|
||||||
config.adminpassFile = config.age.secrets.nextcloud-admin.path;
|
|
||||||
config.dbtype = "pgsql";
|
|
||||||
database.createLocally = true;
|
|
||||||
settings.trusted_domains = [ wireguardIp "nextcloud.home.arpa" ];
|
|
||||||
home = "/mnt/250ssd/nextcloud";
|
|
||||||
extraApps = with config.services.nextcloud.package.packages.apps; {
|
|
||||||
inherit onlyoffice calendar mail;
|
|
||||||
};
|
|
||||||
|
|
||||||
phpOptions = {
|
|
||||||
upload_max_filesize = lib.mkForce "20G";
|
|
||||||
post_max_size = lib.mkForce "20G";
|
|
||||||
};
|
|
||||||
extraAppsEnable = true;
|
|
||||||
settings.enabledPreviewProviders = [
|
|
||||||
"OC\\Preview\\BMP"
|
|
||||||
"OC\\Preview\\GIF"
|
|
||||||
"OC\\Preview\\JPEG"
|
|
||||||
"OC\\Preview\\Krita"
|
|
||||||
"OC\\Preview\\MarkDown"
|
|
||||||
"OC\\Preview\\MP3"
|
|
||||||
"OC\\Preview\\OpenDocument"
|
|
||||||
"OC\\Preview\\PNG"
|
|
||||||
"OC\\Preview\\TXT"
|
|
||||||
"OC\\Preview\\XBitmap"
|
|
||||||
"OC\\Preview\\HEIC"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
extraAppsEnable = true;
|
||||||
|
settings.enabledPreviewProviders = [
|
||||||
|
"OC\\Preview\\BMP"
|
||||||
|
"OC\\Preview\\GIF"
|
||||||
|
"OC\\Preview\\JPEG"
|
||||||
|
"OC\\Preview\\Krita"
|
||||||
|
"OC\\Preview\\MarkDown"
|
||||||
|
"OC\\Preview\\MP3"
|
||||||
|
"OC\\Preview\\OpenDocument"
|
||||||
|
"OC\\Preview\\PNG"
|
||||||
|
"OC\\Preview\\TXT"
|
||||||
|
"OC\\Preview\\XBitmap"
|
||||||
|
"OC\\Preview\\HEIC"
|
||||||
|
];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,72 +45,74 @@ in {
|
|||||||
more_set_headers "Permissions-Policy: geolocation=(), microphone=()";
|
more_set_headers "Permissions-Policy: geolocation=(), microphone=()";
|
||||||
'';
|
'';
|
||||||
|
|
||||||
virtualHosts = let
|
virtualHosts =
|
||||||
kopConfig = {
|
let
|
||||||
root = pkgs.kop-website;
|
kopConfig = {
|
||||||
forceSSL = cfg.https;
|
root = pkgs.kop-website;
|
||||||
enableACME = cfg.https;
|
forceSSL = cfg.https;
|
||||||
quic = cfg.https;
|
enableACME = cfg.https;
|
||||||
http3 = cfg.https;
|
quic = cfg.https;
|
||||||
locations = {
|
http3 = cfg.https;
|
||||||
"~* \\.(jpg|png)$".extraConfig = ''
|
locations = {
|
||||||
add_header Access-Control-Allow-Origin *;
|
"~* \\.(jpg|png)$".extraConfig = ''
|
||||||
'';
|
add_header Access-Control-Allow-Origin *;
|
||||||
"/stash" = {
|
|
||||||
basicAuthFile = config.age.secrets.stash-auth.path;
|
|
||||||
extraConfig = ''
|
|
||||||
client_max_body_size 20000M;
|
|
||||||
proxy_redirect off;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header X-NginX-Proxy true;
|
|
||||||
proxy_pass http://localhost:7777;
|
|
||||||
'';
|
'';
|
||||||
};
|
"/stash" = {
|
||||||
"/tracker-site" = {
|
basicAuthFile = config.age.secrets.stash-auth.path;
|
||||||
tryFiles = "$uri $uri/ /tracker-site/index.html =404";
|
extraConfig = ''
|
||||||
};
|
client_max_body_size 20000M;
|
||||||
"/tracker-site/api" = {
|
proxy_redirect off;
|
||||||
extraConfig = ''
|
proxy_set_header Host $host;
|
||||||
rewrite /tracker-site/api/(.*) /$1 break;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
'';
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxyPass = "http://127.0.0.1:8080";
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
};
|
proxy_set_header X-NginX-Proxy true;
|
||||||
"/radicale/" = {
|
proxy_pass http://localhost:7777;
|
||||||
extraConfig = ''
|
'';
|
||||||
proxy_set_header X-Script-Name /radicale;
|
};
|
||||||
'';
|
"/tracker-site" = {
|
||||||
proxyPass = "http://localhost:5232/";
|
tryFiles = "$uri $uri/ /tracker-site/index.html =404";
|
||||||
};
|
};
|
||||||
"/socket.io" = { proxyPass = "http://localhost:9955"; proxyWebsockets = true; };
|
"/tracker-site/api" = {
|
||||||
"/comms/" = {
|
extraConfig = ''
|
||||||
extraConfig = ''
|
rewrite /tracker-site/api/(.*) /$1 break;
|
||||||
|
'';
|
||||||
|
proxyPass = "http://127.0.0.1:8080";
|
||||||
|
};
|
||||||
|
"/radicale/" = {
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_set_header X-Script-Name /radicale;
|
||||||
|
'';
|
||||||
|
proxyPass = "http://localhost:5232/";
|
||||||
|
};
|
||||||
|
"/socket.io" = { proxyPass = "http://localhost:9955"; proxyWebsockets = true; };
|
||||||
|
"/comms/" = {
|
||||||
|
extraConfig = ''
|
||||||
more_set_headers "Permissions-Policy: geolocation=(), microphone=(self), camera=(self)";
|
more_set_headers "Permissions-Policy: geolocation=(), microphone=(self), camera=(self)";
|
||||||
'';
|
'';
|
||||||
alias = "/comms/";
|
alias = "/comms/";
|
||||||
tryFiles = "$uri $uri/ /comms/index.html";
|
tryFiles = "$uri $uri/ /comms/index.html";
|
||||||
};
|
};
|
||||||
"/comms" = {
|
"/comms" = {
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
return 301 /comms/;
|
return 301 /comms/;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
"/kavita-client" = {
|
"/kavita-client" = {
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
return 301 /kavita-client/;
|
return 301 /kavita-client/;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
"/kavita-client/" = {
|
"/kavita-client/" = {
|
||||||
alias = "/kavita-client/";
|
alias = "/kavita-client/";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
"kopatz.ddns.net" = kopConfig;
|
||||||
|
"kop.oasch.net" = kopConfig;
|
||||||
};
|
};
|
||||||
in {
|
|
||||||
"kopatz.ddns.net" = kopConfig;
|
|
||||||
"kop.oasch.net" = kopConfig;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
{ config, pkgs, lib, inputs, vars, ... }:
|
{ config, pkgs, lib, inputs, vars, ... }:
|
||||||
let
|
let
|
||||||
ip = vars.ipv4;
|
ip = vars.ipv4;
|
||||||
wireguardIp = vars.wireguardIp;
|
wireguardIp = vars.wireguardIp;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
networking.firewall.allowedTCPPorts = [ 28981 ];
|
networking.firewall.allowedTCPPorts = [ 28981 ];
|
||||||
age.secrets.paperless = {
|
age.secrets.paperless = {
|
||||||
file = ../../secrets/paperless.age;
|
file = ../../secrets/paperless.age;
|
||||||
owner = "paperless";
|
owner = "paperless";
|
||||||
group = "paperless";
|
group = "paperless";
|
||||||
};
|
};
|
||||||
services.paperless = {
|
services.paperless = {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = 28981;
|
port = 28981;
|
||||||
passwordFile = config.age.secrets.paperless.path;
|
passwordFile = config.age.secrets.paperless.path;
|
||||||
address = wireguardIp;
|
address = wireguardIp;
|
||||||
mediaDir = "/mnt/250ssd/paperless";
|
mediaDir = "/mnt/250ssd/paperless";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
services.postgresql = {
|
services.postgresql = {
|
||||||
enable = true;
|
enable = true;
|
||||||
authentication = pkgs.lib.mkOverride 10 ''
|
authentication = pkgs.lib.mkOverride 10 ''
|
||||||
#type database DBuser auth-method optional_ident_map
|
#type database DBuser auth-method optional_ident_map
|
||||||
local sameuser all peer map=superuser_map
|
local sameuser all peer map=superuser_map
|
||||||
local all postgres peer
|
local all postgres peer
|
||||||
'';
|
'';
|
||||||
identMap = ''
|
identMap = ''
|
||||||
# ArbitraryMapName systemUser DBUser
|
# ArbitraryMapName systemUser DBUser
|
||||||
superuser_map root postgres
|
superuser_map root postgres
|
||||||
superuser_map postgres postgres
|
superuser_map postgres postgres
|
||||||
# Let other names login as themselves
|
# Let other names login as themselves
|
||||||
superuser_map /^(.*)$ \1
|
superuser_map /^(.*)$ \1
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
services.postgresqlBackup = {
|
services.postgresqlBackup = {
|
||||||
enable = true;
|
enable = true;
|
||||||
location = "/var/backup/postgresql";
|
location = "/var/backup/postgresql";
|
||||||
backupAll = true;
|
backupAll = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ let
|
|||||||
wm = vars.wm;
|
wm = vars.wm;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
services.xrdp.enable = true;
|
services.xrdp.enable = true;
|
||||||
services.xrdp.defaultWindowManager = wm;
|
services.xrdp.defaultWindowManager = wm;
|
||||||
services.xrdp.openFirewall = true;
|
services.xrdp.openFirewall = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,37 @@
|
|||||||
{
|
{
|
||||||
#services.samba-wsdd.enable = true; # make shares visible for windows 10 clients
|
#services.samba-wsdd.enable = true; # make shares visible for windows 10 clients
|
||||||
#networking.firewall.allowedTCPPorts = [
|
#networking.firewall.allowedTCPPorts = [
|
||||||
#5357 # wsdd
|
#5357 # wsdd
|
||||||
#];
|
#];
|
||||||
#networking.firewall.allowedUDPPorts = [
|
#networking.firewall.allowedUDPPorts = [
|
||||||
#3702 # wsdd
|
#3702 # wsdd
|
||||||
#];
|
#];
|
||||||
services.samba.openFirewall = true;
|
services.samba.openFirewall = true;
|
||||||
services.samba = {
|
services.samba = {
|
||||||
enable = true;
|
enable = true;
|
||||||
securityType = "user";
|
securityType = "user";
|
||||||
invalidUsers = [
|
invalidUsers = [
|
||||||
"root"
|
"root"
|
||||||
];
|
];
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
disable netbios = yes
|
disable netbios = yes
|
||||||
smb ports = 445
|
smb ports = 445
|
||||||
workgroup = WORKGROUP
|
workgroup = WORKGROUP
|
||||||
server string = smbnix
|
server string = smbnix
|
||||||
security = user
|
security = user
|
||||||
#use sendfile = yes
|
#use sendfile = yes
|
||||||
#max protocol = smb2
|
#max protocol = smb2
|
||||||
# note: localhost is the ipv6 localhost ::1
|
# note: localhost is the ipv6 localhost ::1
|
||||||
hosts allow = 192.168.0. 192.168.174.1 127.0.0.1 localhost
|
hosts allow = 192.168.0. 192.168.174.1 127.0.0.1 localhost
|
||||||
hosts deny = 0.0.0.0/0
|
hosts deny = 0.0.0.0/0
|
||||||
guest account = nobody
|
guest account = nobody
|
||||||
map to guest = bad user
|
map to guest = bad user
|
||||||
'';
|
'';
|
||||||
shares = {
|
shares = {
|
||||||
homes = {
|
homes = {
|
||||||
browseable = "no";
|
browseable = "no";
|
||||||
writable = "yes";
|
writable = "yes";
|
||||||
};
|
};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ let
|
|||||||
--data "$JSON"
|
--data "$JSON"
|
||||||
'';
|
'';
|
||||||
cfg = config.custom.services.smartd;
|
cfg = config.custom.services.smartd;
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
|
|
||||||
options.custom.services.smartd = {
|
options.custom.services.smartd = {
|
||||||
enable = lib.mkEnableOption "Enables smartd monitoring";
|
enable = lib.mkEnableOption "Enables smartd monitoring";
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
networking.firewall.allowedTCPPorts = [ 22 ];
|
networking.firewall.allowedTCPPorts = [ 22 ];
|
||||||
services.openssh = {
|
services.openssh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
allowSFTP = false;
|
allowSFTP = false;
|
||||||
settings.PasswordAuthentication = false;
|
settings.PasswordAuthentication = false;
|
||||||
settings.KbdInteractiveAuthentication = false;
|
settings.KbdInteractiveAuthentication = false;
|
||||||
settings.X11Forwarding = false;
|
settings.X11Forwarding = false;
|
||||||
settings.PermitRootLogin = "prohibit-password";
|
settings.PermitRootLogin = "prohibit-password";
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
AllowAgentForwarding no
|
AllowAgentForwarding no
|
||||||
AllowStreamLocalForwarding no
|
AllowStreamLocalForwarding no
|
||||||
AuthenticationMethods publickey
|
AuthenticationMethods publickey
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,33 +2,33 @@
|
|||||||
let
|
let
|
||||||
root_ca =
|
root_ca =
|
||||||
''
|
''
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIIBjTCCATKgAwIBAgIRAMVH2+JHZ3wm2fLUlKjTYDswCgYIKoZIzj0EAwIwJDEM
|
MIIBjTCCATKgAwIBAgIRAMVH2+JHZ3wm2fLUlKjTYDswCgYIKoZIzj0EAwIwJDEM
|
||||||
MAoGA1UEChMDS29wMRQwEgYDVQQDEwtLb3AgUm9vdCBDQTAeFw0yMzEyMDgxNDUx
|
MAoGA1UEChMDS29wMRQwEgYDVQQDEwtLb3AgUm9vdCBDQTAeFw0yMzEyMDgxNDUx
|
||||||
MTZaFw0zMzEyMDUxNDUxMTZaMCQxDDAKBgNVBAoTA0tvcDEUMBIGA1UEAxMLS29w
|
MTZaFw0zMzEyMDUxNDUxMTZaMCQxDDAKBgNVBAoTA0tvcDEUMBIGA1UEAxMLS29w
|
||||||
IFJvb3QgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATdZBOkNynShXipzhuX
|
IFJvb3QgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATdZBOkNynShXipzhuX
|
||||||
f6dUByD3chNupNWsagYC5AlPRJT9fAeHEIK/bxWkFwRtLBDopWvBu9lHahBgpHc7
|
f6dUByD3chNupNWsagYC5AlPRJT9fAeHEIK/bxWkFwRtLBDopWvBu9lHahBgpHc7
|
||||||
y7rTo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNV
|
y7rTo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNV
|
||||||
HQ4EFgQU9AVtwipW5HDBLfZRH1KZCnIKCfowCgYIKoZIzj0EAwIDSQAwRgIhAMHj
|
HQ4EFgQU9AVtwipW5HDBLfZRH1KZCnIKCfowCgYIKoZIzj0EAwIDSQAwRgIhAMHj
|
||||||
AipNdhQKIYPvMt/h1uW4xP3NTkitnmshM09+rIasAiEAlSalGddXDkqJBHhPD+Fr
|
AipNdhQKIYPvMt/h1uW4xP3NTkitnmshM09+rIasAiEAlSalGddXDkqJBHhPD+Fr
|
||||||
gpuVkfVkA8gQCXNs5F9TnxA=
|
gpuVkfVkA8gQCXNs5F9TnxA=
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
'';
|
'';
|
||||||
intermediate_ca =
|
intermediate_ca =
|
||||||
''
|
''
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIIBtDCCAVqgAwIBAgIQbEVEV7LgtjVWO+qBrrmgETAKBggqhkjOPQQDAjAkMQww
|
MIIBtDCCAVqgAwIBAgIQbEVEV7LgtjVWO+qBrrmgETAKBggqhkjOPQQDAjAkMQww
|
||||||
CgYDVQQKEwNLb3AxFDASBgNVBAMTC0tvcCBSb290IENBMB4XDTIzMTIwODE0NTEx
|
CgYDVQQKEwNLb3AxFDASBgNVBAMTC0tvcCBSb290IENBMB4XDTIzMTIwODE0NTEx
|
||||||
N1oXDTMzMTIwNTE0NTExN1owLDEMMAoGA1UEChMDS29wMRwwGgYDVQQDExNLb3Ag
|
N1oXDTMzMTIwNTE0NTExN1owLDEMMAoGA1UEChMDS29wMRwwGgYDVQQDExNLb3Ag
|
||||||
SW50ZXJtZWRpYXRlIENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmv7jg7Cs
|
SW50ZXJtZWRpYXRlIENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmv7jg7Cs
|
||||||
4L5v52+3yUmn79hZFS2vmm/5wwcUCL63dokEXQsHgbEjaRKsF/MW0yJDLTB6Sdhl
|
4L5v52+3yUmn79hZFS2vmm/5wwcUCL63dokEXQsHgbEjaRKsF/MW0yJDLTB6Sdhl
|
||||||
pCvoNJqITWuEN6NmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C
|
pCvoNJqITWuEN6NmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C
|
||||||
AQAwHQYDVR0OBBYEFDgVolMCmdrhDIXhuIs4q/KwRKNLMB8GA1UdIwQYMBaAFPQF
|
AQAwHQYDVR0OBBYEFDgVolMCmdrhDIXhuIs4q/KwRKNLMB8GA1UdIwQYMBaAFPQF
|
||||||
bcIqVuRwwS32UR9SmQpyCgn6MAoGCCqGSM49BAMCA0gAMEUCIQCQa01E+UvAJ8KR
|
bcIqVuRwwS32UR9SmQpyCgn6MAoGCCqGSM49BAMCA0gAMEUCIQCQa01E+UvAJ8KR
|
||||||
DFfDducZUpW4tZRN35lqoge7T9nM2QIgK4FFt1NqDqcjOSabAXPOQ68bvdxlHW0y
|
DFfDducZUpW4tZRN35lqoge7T9nM2QIgK4FFt1NqDqcjOSabAXPOQ68bvdxlHW0y
|
||||||
AgN9qNc3Jbo=
|
AgN9qNc3Jbo=
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
'';
|
'';
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@@ -82,9 +82,9 @@ in
|
|||||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"
|
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"
|
||||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
|
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
|
||||||
];
|
];
|
||||||
minVersion = 1.2;
|
minVersion = 1.2;
|
||||||
maxVersion = 1.3;
|
maxVersion = 1.3;
|
||||||
renegotiation = false;
|
renegotiation = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user