chore: migrate foxtrot nixosConfiguration package
Some checks failed
/ check (push) Failing after 50s
Some checks failed
/ check (push) Failing after 50s
This commit is contained in:
parent
4a9196dd33
commit
a68ee40b01
7 changed files with 101 additions and 374 deletions
|
@ -1,4 +1,4 @@
|
||||||
{ self, ... }:
|
{ self, ... }@inputs:
|
||||||
let
|
let
|
||||||
forSelfOverlay =
|
forSelfOverlay =
|
||||||
if builtins.hasAttr "overlays" self && builtins.hasAttr "forSelf" self.overlays then
|
if builtins.hasAttr "overlays" self && builtins.hasAttr "forSelf" self.overlays then
|
||||||
|
@ -17,4 +17,6 @@ rec {
|
||||||
forSystems = nixpkgs: nixpkgs.lib.genAttrs systems;
|
forSystems = nixpkgs: nixpkgs.lib.genAttrs systems;
|
||||||
pkgsFor = nixpkgs: system: (import nixpkgs { inherit system; }).extend forSelfOverlay;
|
pkgsFor = nixpkgs: system: (import nixpkgs { inherit system; }).extend forSelfOverlay;
|
||||||
genPkgs = nixpkgs: func: (forSystems nixpkgs (system: func (pkgsFor nixpkgs system)));
|
genPkgs = nixpkgs: func: (forSystems nixpkgs (system: func (pkgsFor nixpkgs system)));
|
||||||
|
|
||||||
|
inherit (import ./host.nix inputs) host stableHost;
|
||||||
}
|
}
|
||||||
|
|
36
lib/host.nix
Normal file
36
lib/host.nix
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
inputs:
|
||||||
|
let
|
||||||
|
baseHost =
|
||||||
|
{
|
||||||
|
nixpkgs,
|
||||||
|
home-manager,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
(
|
||||||
|
path:
|
||||||
|
(
|
||||||
|
{
|
||||||
|
system ? "x86_64-linux",
|
||||||
|
}:
|
||||||
|
(nixpkgs.lib.nixosSystem {
|
||||||
|
inherit system;
|
||||||
|
specialArgs = {
|
||||||
|
inherit home-manager;
|
||||||
|
hardware = inputs.hardware.outputs.nixosModules;
|
||||||
|
diskoConfigurations = inputs.self.outputs.diskoConfigurations;
|
||||||
|
};
|
||||||
|
modules = [
|
||||||
|
inputs.self.outputs.nixosModules.default
|
||||||
|
(import path)
|
||||||
|
];
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
stableHost = baseHost { inherit (inputs) nixpkgs home-manager; };
|
||||||
|
host = baseHost {
|
||||||
|
nixpkgs = inputs.nixpkgs-unstable;
|
||||||
|
home-manager = inputs.home-manager-unstable;
|
||||||
|
};
|
||||||
|
}
|
|
@ -52,9 +52,9 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = mkIf cfg.enable {
|
||||||
systemd.timers.deno-netlify-ddns-client = {
|
systemd.timers.deno-netlify-ddns-client = {
|
||||||
enable = mkIf cfg.enable true;
|
enable = true;
|
||||||
after = [ "network.target" ];
|
after = [ "network.target" ];
|
||||||
wantedBy = [ "timers.target" ];
|
wantedBy = [ "timers.target" ];
|
||||||
timerConfig = {
|
timerConfig = {
|
||||||
|
@ -65,7 +65,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.deno-netlify-ddns-client = {
|
systemd.services.deno-netlify-ddns-client = {
|
||||||
enable = mkIf cfg.enable true;
|
enable = true;
|
||||||
after = [ "network.target" ];
|
after = [ "network.target" ];
|
||||||
script = ''
|
script = ''
|
||||||
set -eu
|
set -eu
|
||||||
|
|
|
@ -1,39 +1,10 @@
|
||||||
inputs:
|
inputs:
|
||||||
let
|
let
|
||||||
baseHost =
|
inherit (inputs.self.flakeLib) host stableHost;
|
||||||
{
|
|
||||||
nixpkgs,
|
|
||||||
home-manager,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
(
|
|
||||||
path:
|
|
||||||
(
|
|
||||||
{
|
|
||||||
system ? "x86_64-linux",
|
|
||||||
}:
|
|
||||||
(nixpkgs.lib.nixosSystem {
|
|
||||||
inherit system;
|
|
||||||
specialArgs = {
|
|
||||||
inherit home-manager;
|
|
||||||
hardware = inputs.hardware.outputs.nixosModules;
|
|
||||||
diskoConfigurations = inputs.self.outputs.diskoConfigurations;
|
|
||||||
};
|
|
||||||
modules = [
|
|
||||||
inputs.self.outputs.nixosModules.default
|
|
||||||
(import path)
|
|
||||||
];
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
stableHost = baseHost { inherit (inputs) nixpkgs home-manager; };
|
|
||||||
host = baseHost {
|
|
||||||
nixpkgs = inputs.nixpkgs-unstable;
|
|
||||||
home-manager = inputs.home-manager-unstable;
|
|
||||||
};
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
beefcake = stableHost ./beefcake.nix { };
|
beefcake = stableHost ./beefcake.nix { };
|
||||||
dragon = host ./dragon.nix { };
|
dragon = host ./dragon.nix { };
|
||||||
|
foxtrot = host ./foxtrot.nix { };
|
||||||
# arm-dragon = host ./dragon.nix { system = "aarch64-linux"; };
|
# arm-dragon = host ./dragon.nix { system = "aarch64-linux"; };
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,8 @@
|
||||||
lyte.desktop.enable = true;
|
lyte.desktop.enable = true;
|
||||||
|
|
||||||
home-manager.users.daniel = {
|
home-manager.users.daniel = {
|
||||||
|
lyte.shell.enable = true;
|
||||||
|
lyte.desktop.enable = true;
|
||||||
slippi-launcher = {
|
slippi-launcher = {
|
||||||
enable = true;
|
enable = true;
|
||||||
isoPath = "${config.users.users.daniel.home}/../games/roms/dolphin/melee.iso";
|
isoPath = "${config.users.users.daniel.home}/../games/roms/dolphin/melee.iso";
|
||||||
|
|
|
@ -1,211 +1,24 @@
|
||||||
{ pkgs, ... }:
|
|
||||||
{
|
{
|
||||||
imports = [
|
pkgs,
|
||||||
{
|
hardware,
|
||||||
|
diskoConfigurations,
|
||||||
|
# homeConfigurations,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
system.stateVersion = "24.11";
|
system.stateVersion = "24.11";
|
||||||
home-manager.users.daniel.home.stateVersion = "24.11";
|
|
||||||
networking.hostName = "foxtrot";
|
networking.hostName = "foxtrot";
|
||||||
}
|
|
||||||
{
|
|
||||||
swapDevices = [
|
|
||||||
# TODO: move this to disko?
|
|
||||||
# NOTE(oninstall):
|
|
||||||
/*
|
|
||||||
sudo btrfs subvolume create /swap
|
|
||||||
sudo btrfs filesystem mkswapfile --size 32g --uuid clear /swap/swapfile
|
|
||||||
sudo swapon /swap/swapfile
|
|
||||||
*/
|
|
||||||
];
|
|
||||||
# findmnt -no UUID -T /swap/swapfile
|
|
||||||
# boot.resumeDevice = "/dev/disk/by-uuid/81c3354a-f629-4b6b-a249-7705aeb9f0d5";
|
|
||||||
# systemd.sleep.extraConfig = "HibernateDelaySec=180m";
|
|
||||||
services.fwupd.enable = true;
|
|
||||||
services.fwupd.extraRemotes = [ "lvfs-testing" ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
environment = {
|
|
||||||
systemPackages = with pkgs; [
|
|
||||||
easyeffects
|
|
||||||
godot_4
|
|
||||||
fractal
|
|
||||||
prismlauncher
|
|
||||||
upower
|
|
||||||
acpi
|
|
||||||
prismlauncher
|
|
||||||
radeontop
|
|
||||||
sops
|
|
||||||
xh
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
home-manager.users.daniel = {
|
|
||||||
home = {
|
|
||||||
pointerCursor = {
|
|
||||||
size = 40;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.easyeffects = {
|
|
||||||
enable = true;
|
|
||||||
preset = "philonmetal";
|
|
||||||
# clone from https://github.com/ceiphr/ee-framework-presets
|
|
||||||
# then `cp *.json ~/.config/easyeffects/output`
|
|
||||||
# TODO: nixify this
|
|
||||||
};
|
|
||||||
|
|
||||||
programs.hyprlock.settings = {
|
|
||||||
label = [
|
|
||||||
{
|
|
||||||
monitor = "";
|
|
||||||
font_size = 32;
|
|
||||||
|
|
||||||
halign = "center";
|
|
||||||
valign = "center";
|
|
||||||
text_align = "center";
|
|
||||||
color = "rgba(255, 255, 255, 0.5)";
|
|
||||||
|
|
||||||
position = "0 -500";
|
|
||||||
font_family = "IosevkaLyteTerm";
|
|
||||||
text = "cmd[update:30000] acpi";
|
|
||||||
|
|
||||||
shadow_passes = 3;
|
|
||||||
shadow_size = 1;
|
|
||||||
shadow_color = "rgba(0, 0, 0, 1.0)";
|
|
||||||
shadow_boost = 1.0;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
services.hypridle =
|
|
||||||
let
|
|
||||||
secondsPerMinute = 60;
|
|
||||||
lockSeconds = 10 * secondsPerMinute;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
settings = {
|
|
||||||
listener = [
|
|
||||||
{
|
|
||||||
timeout = lockSeconds + 55;
|
|
||||||
on-timeout = ''systemctl suspend'';
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
wayland.windowManager.hyprland = {
|
|
||||||
settings = {
|
|
||||||
exec-once = [
|
|
||||||
"eww open bar0"
|
|
||||||
];
|
|
||||||
# See https://wiki.hyprland.org/Configuring/Keywords/ for more
|
|
||||||
monitor = [
|
|
||||||
"eDP-1,2880x1920@120Hz,0x0,1.5"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
wayland.windowManager.sway = {
|
|
||||||
config = {
|
|
||||||
output = {
|
|
||||||
"BOE NE135A1M-NY1 Unknown" = {
|
|
||||||
mode = "2880x1920@120Hz";
|
|
||||||
position = "1092,2160";
|
|
||||||
scale = toString (5 / 3);
|
|
||||||
};
|
|
||||||
|
|
||||||
"Dell Inc. DELL U2720Q CWTM623" = {
|
|
||||||
mode = "3840x2160@60Hz";
|
|
||||||
position = "0,0";
|
|
||||||
scale = toString 1.25;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
"BOE 0x0BCA Unknown" = {
|
|
||||||
mode = "2256x1504@60Hz";
|
|
||||||
position = "0,0";
|
|
||||||
scale = toString scale;
|
|
||||||
};
|
|
||||||
|
|
||||||
"Dell Inc. DELL U2720Q D3TM623" = {
|
|
||||||
# desktop left vertical monitor
|
|
||||||
mode = "1920x1080@60Hz";
|
|
||||||
# transform = "90";
|
|
||||||
# scale = "1.5";
|
|
||||||
position = "${toString (builtins.floor (2256 / scale))},0";
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
hardware.graphics.extraPackages = [
|
|
||||||
# pkgs.rocmPackages.clr.icd
|
|
||||||
pkgs.amdvlk
|
|
||||||
|
|
||||||
# encoding/decoding acceleration
|
|
||||||
pkgs.libvdpau-va-gl
|
|
||||||
pkgs.vaapiVdpau
|
|
||||||
];
|
|
||||||
|
|
||||||
hardware.amdgpu = {
|
|
||||||
amdvlk = {
|
|
||||||
enable = true;
|
|
||||||
support32Bit = {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.networkmanager.wifi.powersave = false;
|
|
||||||
|
|
||||||
hardware.framework.amd-7040.preventWakeOnAC = true;
|
|
||||||
|
|
||||||
boot = {
|
boot = {
|
||||||
# kernelPackages = pkgs.linuxPackages_latest;
|
|
||||||
|
|
||||||
# https://github.com/void-linux/void-packages/issues/50417#issuecomment-2131802836 fix framework 13 not shutting down
|
|
||||||
/*
|
|
||||||
kernelPatches = [
|
|
||||||
{
|
|
||||||
name = "framework13shutdownfix";
|
|
||||||
patch = builtins.fetchurl {
|
|
||||||
url = "https://github.com/void-linux/void-packages/files/15445612/0001-Add-hopefully-a-solution-for-shutdown-regression.PATCH";
|
|
||||||
sha256 = "sha256:10zcnzy5hkam2cnxx441b978gzhvnqlcc49k7bpz9dc28xyjik50";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
*/
|
|
||||||
|
|
||||||
loader = {
|
loader = {
|
||||||
efi.canTouchEfiVariables = true;
|
efi.canTouchEfiVariables = true;
|
||||||
systemd-boot = {
|
systemd-boot.enable = true;
|
||||||
enable = true;
|
|
||||||
extraEntries = {
|
|
||||||
"arch.conf" = ''
|
|
||||||
title Arch
|
|
||||||
efi /efi/Arch/grubx64.efi
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# NOTE(oninstall):
|
|
||||||
/*
|
|
||||||
sudo filefrag -v /swap/swapfile | awk '$1=="0:" {print substr($4, 1, length($4)-2)}'
|
|
||||||
the above won't work for btrfs, instead you need btrfs inspect-internal map-swapfile -r /swap/swapfile
|
|
||||||
https://wiki.archlinux.org/title/Power_management/Suspend_and_hibernate#Hibernation_into_swap_file
|
|
||||||
many of these come from https://wiki.archlinux.org/title/Framework_Laptop_13#Suspend
|
|
||||||
*/
|
|
||||||
kernelParams = [
|
kernelParams = [
|
||||||
"rtc_cmos.use_acpi_alarm=1"
|
"rtc_cmos.use_acpi_alarm=1"
|
||||||
"amdgpu.sg_display=0"
|
"amdgpu.sg_display=0"
|
||||||
"boot.shell_on_fail=1"
|
"boot.shell_on_fail=1"
|
||||||
"acpi_osi=\"!Windows 2020\""
|
"acpi_osi=\"!Windows 2020\""
|
||||||
|
|
||||||
# "nvme.noacpi=1" # maybe causing crashes upon waking?
|
|
||||||
|
|
||||||
# NOTE(oninstall):
|
|
||||||
"resume_offset=3421665"
|
"resume_offset=3421665"
|
||||||
];
|
];
|
||||||
initrd.availableKernelModules = [
|
initrd.availableKernelModules = [
|
||||||
|
@ -215,12 +28,17 @@
|
||||||
];
|
];
|
||||||
kernelModules = [ "kvm-amd" ];
|
kernelModules = [ "kvm-amd" ];
|
||||||
};
|
};
|
||||||
hardware.bluetooth = {
|
|
||||||
enable = true;
|
|
||||||
# TODO: when resuming from hibernation, it would be nice if this would
|
|
||||||
# simply resume the power state at the time of hibernation
|
|
||||||
powerOnBoot = false;
|
|
||||||
|
|
||||||
|
imports = with hardware; [
|
||||||
|
diskoConfigurations.foxtrot
|
||||||
|
framework-13-7040-amd
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.networkmanager.wifi.powersave = false;
|
||||||
|
hardware = {
|
||||||
|
framework.amd-7040.preventWakeOnAC = true;
|
||||||
|
bluetooth = {
|
||||||
|
enable = true;
|
||||||
package = pkgs.bluez.overrideAttrs (
|
package = pkgs.bluez.overrideAttrs (
|
||||||
finalAttrs: previousAttrs: rec {
|
finalAttrs: previousAttrs: rec {
|
||||||
version = "5.78";
|
version = "5.78";
|
||||||
|
@ -235,67 +53,30 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
};
|
||||||
powerManagement.cpuFreqGovernor = "ondemand";
|
powerManagement.cpuFreqGovernor = "ondemand";
|
||||||
/*
|
services = {
|
||||||
powerManagement.resumeCommands = ''
|
fwupd.extraRemotes = [ "lvfs-testing" ];
|
||||||
modprobe -rv mt7921e
|
power-profiles-daemon = {
|
||||||
modprobe -v mt7921e
|
|
||||||
'';
|
|
||||||
*/
|
|
||||||
|
|
||||||
services.power-profiles-daemon = {
|
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
fprintd = {
|
||||||
services.fprintd = {
|
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.fprintd.overrideAttrs {
|
|
||||||
# Source: https://github.com/NixOS/nixpkgs/commit/87ca2dc071581aea0e691c730d6844f1beb07c9f
|
|
||||||
# mesonCheckFlags = [
|
|
||||||
# PAM related checks are timing out
|
|
||||||
# "--no-suite"
|
|
||||||
# "fprintd:TestPamFprintd"
|
|
||||||
# ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
networking.wifi.enable = true;
|
||||||
services.tlp = {
|
lyte.desktop.enable = true;
|
||||||
|
|
||||||
|
home-manager.users.daniel = {
|
||||||
|
lyte.shell.enable = true;
|
||||||
|
lyte.desktop.enable = true;
|
||||||
|
services.easyeffects = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
preset = "philonmetal";
|
||||||
CPU_ENERGY_PERF_POLICY_ON_BAT = "power";
|
# clone from https://github.com/ceiphr/ee-framework-presets
|
||||||
CPU_SCALING_GOVERNOR_ON_BAT = "ondemand";
|
# then `cp *.json ~/.config/easyeffects/output`
|
||||||
CPU_MIN_PERF_ON_BAT = 0;
|
# TODO: nixify this
|
||||||
CPU_MAX_PERF_ON_BAT = 80;
|
|
||||||
|
|
||||||
CPU_SCALING_GOVERNOR_ON_AC = "performance";
|
|
||||||
CPU_ENERGY_PERF_POLICY_ON_AC = "performance";
|
|
||||||
CPU_MIN_PERF_ON_AC = 0;
|
|
||||||
CPU_MAX_PERF_ON_AC = 100;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts =
|
|
||||||
let
|
|
||||||
stardewValley = 24642;
|
|
||||||
factorio = 34197;
|
|
||||||
in
|
|
||||||
[
|
|
||||||
8000 # dev stuff
|
|
||||||
factorio
|
|
||||||
stardewValley
|
|
||||||
7777
|
|
||||||
];
|
|
||||||
networking.firewall.allowedUDPPorts =
|
|
||||||
let
|
|
||||||
stardewValley = 24642;
|
|
||||||
factorio = 34197;
|
|
||||||
in
|
|
||||||
[
|
|
||||||
8000 # dev stuff
|
|
||||||
factorio
|
|
||||||
stardewValley
|
|
||||||
7777
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,71 +101,6 @@ in
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
foxtrot = nixpkgs-unstable.lib.nixosSystem {
|
|
||||||
system = "x86_64-linux";
|
|
||||||
modules = with nixosModules; [
|
|
||||||
home-manager-unstable-defaults
|
|
||||||
|
|
||||||
outputs.diskoConfigurations.foxtrot
|
|
||||||
hardware.nixosModules.framework-13-7040-amd
|
|
||||||
|
|
||||||
common
|
|
||||||
kde-connect
|
|
||||||
password-manager
|
|
||||||
graphical-workstation
|
|
||||||
# plasma6
|
|
||||||
# virtual-machines
|
|
||||||
# virtual-machines-gui
|
|
||||||
laptop
|
|
||||||
gaming
|
|
||||||
cross-compiler
|
|
||||||
|
|
||||||
./nixos/foxtrot.nix
|
|
||||||
|
|
||||||
(
|
|
||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
home-manager.users.daniel = {
|
|
||||||
imports = with homeManagerModules; [
|
|
||||||
senpai
|
|
||||||
iex
|
|
||||||
niri
|
|
||||||
cargo
|
|
||||||
linux-desktop-environment-config
|
|
||||||
];
|
|
||||||
};
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
fw-ectool
|
|
||||||
(writeShellApplication {
|
|
||||||
name = "reset-wifi-module";
|
|
||||||
runtimeInputs = with pkgs; [ kmod ];
|
|
||||||
text = ''
|
|
||||||
modprobe -rv mt7921e
|
|
||||||
modprobe -v mt7921e
|
|
||||||
'';
|
|
||||||
})
|
|
||||||
(writeShellApplication {
|
|
||||||
name = "perfmode";
|
|
||||||
# we use command -v $cmd here because we only want to invoke these calls _if_ the related package is installed on the system
|
|
||||||
# otherwise, they will likely have no effect anyways
|
|
||||||
text = ''
|
|
||||||
command -v powerprofilesctl &>/dev/null && bash -x -c 'powerprofilesctl set balanced'
|
|
||||||
command -v swaymsg &>/dev/null && bash -x -c 'swaymsg output eDP-1 mode 2880x1920@120Hz'
|
|
||||||
'';
|
|
||||||
})
|
|
||||||
(writeShellApplication {
|
|
||||||
name = "battmode";
|
|
||||||
text = ''
|
|
||||||
command -v powerprofilesctl &>/dev/null && bash -x -c 'powerprofilesctl set power-saver'
|
|
||||||
command -v swaymsg &>/dev/null && bash -x -c 'swaymsg output eDP-1 mode 2880x1920@60Hz'
|
|
||||||
'';
|
|
||||||
})
|
|
||||||
];
|
|
||||||
}
|
|
||||||
)
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
thablet = nixpkgs-unstable.lib.nixosSystem {
|
thablet = nixpkgs-unstable.lib.nixosSystem {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
modules = with nixosModules; [
|
modules = with nixosModules; [
|
||||||
|
|
Loading…
Add table
Reference in a new issue