diff --git a/.config/autostart/org.keepassxc.KeePassXC.desktop b/.config/autostart/org.keepassxc.KeePassXC.desktop
index e3c8320..c6e4654 100644
--- a/.config/autostart/org.keepassxc.KeePassXC.desktop
+++ b/.config/autostart/org.keepassxc.KeePassXC.desktop
@@ -1,17 +1,17 @@
[Desktop Entry]
-Categories=Utility;Security;Qt;
-Comment=Community-driven port of the Windows application “KeePass Password Safe”
-Exec=keepassxc %f
-GenericName=Password Manager
-Icon=keepassxc
-Keywords=security;privacy;password-manager;yubikey;password;keepass;
-MimeType=application/x-keepass2;
Name=KeePassXC
-SingleMainWindow=true
-StartupNotify=true
-StartupWMClass=keepassxc
-Terminal=false
+GenericName=Password Manager
+Exec=keepassxc
TryExec=keepassxc
+Icon=keepassxc
+StartupWMClass=keepassxc
+StartupNotify=true
+Terminal=false
Type=Application
-Version=1.5
-X-GNOME-SingleWindow=true
+Version=1.0
+Categories=Utility;Security;Qt;
+MimeType=application/x-keepass2;
+X-GNOME-Autostart-enabled=true
+X-GNOME-Autostart-Delay=2
+X-KDE-autostart-after=panel
+X-LXQt-Need-Tray=true
diff --git a/.config/kdedefaults/kcminputrc b/.config/kdedefaults/kcminputrc
deleted file mode 100644
index 779b957..0000000
--- a/.config/kdedefaults/kcminputrc
+++ /dev/null
@@ -1,2 +0,0 @@
-[Mouse]
-cursorTheme=breeze_cursors
diff --git a/.config/kdedefaults/kdeglobals b/.config/kdedefaults/kdeglobals
deleted file mode 100644
index 5bdede9..0000000
--- a/.config/kdedefaults/kdeglobals
+++ /dev/null
@@ -1,8 +0,0 @@
-[General]
-ColorScheme=BreezeDark
-
-[Icons]
-Theme=breeze-dark
-
-[KDE]
-widgetStyle=Breeze
diff --git a/.config/kdedefaults/kscreenlockerrc b/.config/kdedefaults/kscreenlockerrc
deleted file mode 100644
index e6a2d2c..0000000
--- a/.config/kdedefaults/kscreenlockerrc
+++ /dev/null
@@ -1,2 +0,0 @@
-[Greeter]
-Theme=org.debian.desktop
diff --git a/.config/kdedefaults/ksplashrc b/.config/kdedefaults/ksplashrc
deleted file mode 100644
index 5e5998b..0000000
--- a/.config/kdedefaults/ksplashrc
+++ /dev/null
@@ -1,3 +0,0 @@
-[KSplash]
-Engine=KSplashQML
-Theme=org.debian.desktop
diff --git a/.config/kdedefaults/kwinrc b/.config/kdedefaults/kwinrc
deleted file mode 100644
index 883ff0f..0000000
--- a/.config/kdedefaults/kwinrc
+++ /dev/null
@@ -1,12 +0,0 @@
-[TabBox]
-DesktopLayout=org.kde.breeze.desktop
-DesktopListLayout=org.kde.breeze.desktop
-LayoutName=org.kde.breeze.desktop
-
-[Windows]
-Placement=Centered
-
-[org.kde.kdecoration2]
-NoPlugin=false
-library=org.kde.breeze
-theme=Breeze
diff --git a/.config/kdedefaults/package b/.config/kdedefaults/package
deleted file mode 100644
index c188391..0000000
--- a/.config/kdedefaults/package
+++ /dev/null
@@ -1 +0,0 @@
-org.kde.breezedark.desktop
\ No newline at end of file
diff --git a/.config/kdedefaults/plasmarc b/.config/kdedefaults/plasmarc
deleted file mode 100644
index 8b58863..0000000
--- a/.config/kdedefaults/plasmarc
+++ /dev/null
@@ -1,2 +0,0 @@
-[Theme]
-name=default
diff --git a/.config/konsave/conf.yaml b/.config/konsave/conf.yaml
new file mode 100644
index 0000000..c7db0a0
--- /dev/null
+++ b/.config/konsave/conf.yaml
@@ -0,0 +1,118 @@
+---
+# This is the configuration file for konsave.
+# This file is pre-configured for KDE Plasma users.
+# This will backup all the important files for your Plasma customizations.
+# Please make sure it follows the correct format for proper working of Konsave.
+# The format should be:
+# ---
+# save:
+# name:
+# location: "path/to/parent/directory"
+# entries:
+# # these are files which will be backed up.
+# # They should be present in the specified location.
+# - file1
+# - file2
+# export:
+# # This includes files which will be exported with your profile.
+# # They will not be saved but only be exported and imported.
+# # These may include files like complete icon packs and themes..
+# name:
+# location: "path/to/parent/directory"
+# entries:
+# - file1
+# - file2
+# ...
+# You can use these placeholders in the "location" of each item:
+# $HOME: the home directory
+# $CONFIG_DIR: refers to "$HOME/.config/"
+# $SHARE_DIR: refers to "$HOME/.local/share"
+# $BIN_DIR: refers to "$HOME/.local/bin"
+# ${ENDS_WITH="text"}: for folders with different names on different computers whose names end with the same thing.
+# The best example for this is the "*.default-release" folder of firefox.
+# ${BEGINS_WITH="text"}: for folders with different names on different computers whose names start with the same thing.
+
+save:
+ configs:
+ location: "$CONFIG_DIR"
+ entries:
+ - gtk-2.0
+ - gtk-3.0
+ - gtk-4.0
+ - kate
+ - Kvantum
+ - latte
+ - dolphinrc
+ - katerc
+ - konsolerc
+ - kcminputrc
+ - kdeglobals
+ - kglobalshortcutsrc
+ - klipperrc
+ - krunnerrc
+ - kscreenlockerrc
+ - ksmserverrc
+ - kwinrc
+ - kwinrulesrc
+ - plasma-org.kde.plasma.desktop-appletsrc
+ - plasmarc
+ - plasmashellrc
+ - gtkrc
+ - gtkrc-2.0
+ - lattedockrc
+ - breezerc
+ - oxygenrc
+ - lightlyrc
+ - ksplashrc
+ - khotkeysrc
+
+ app_layouts:
+ location: "$HOME/.local/share/kxmlgui5"
+ entries:
+ - dolphin
+ - konsole
+
+ # Here are a few examples of how you can add more stuff to back up.
+ # Uncomment these lines if you want.
+ # firefox:
+ # location: "$HOME/.mozilla/firefox/${ENDS_WITH='.default-release'}"
+ # entries:
+ # - chrome # for firefox customizations
+
+ # code oss:
+ # location: "$CONFIG_DIR/Code - OSS/User/"
+ # entries:
+ # - settings.json
+
+
+# The following files will only be used for exporting and importing.
+export:
+ share_folder:
+ location: "$SHARE_DIR"
+ entries:
+ - plasma
+ - kwin
+ - konsole
+ - fonts
+ - color-schemes
+ - aurorae
+ - icons
+ - wallpapers
+
+ home_folder:
+ location: "$HOME/"
+ entries:
+ - .fonts
+ - .themes
+ - .icons
+
+
+ # You can add more files to export like this
+ # name:
+ # location: "path/to/parent/directory"
+ # entries:
+ # - file1
+ # - file2
+ # - folder1
+ # - folder2
+...
diff --git a/.config/konsave/profiles/laptop-kde/conf.yaml b/.config/konsave/profiles/laptop-kde/conf.yaml
new file mode 100644
index 0000000..c7db0a0
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/conf.yaml
@@ -0,0 +1,118 @@
+---
+# This is the configuration file for konsave.
+# This file is pre-configured for KDE Plasma users.
+# This will backup all the important files for your Plasma customizations.
+# Please make sure it follows the correct format for proper working of Konsave.
+# The format should be:
+# ---
+# save:
+# name:
+# location: "path/to/parent/directory"
+# entries:
+# # these are files which will be backed up.
+# # They should be present in the specified location.
+# - file1
+# - file2
+# export:
+# # This includes files which will be exported with your profile.
+# # They will not be saved but only be exported and imported.
+# # These may include files like complete icon packs and themes..
+# name:
+# location: "path/to/parent/directory"
+# entries:
+# - file1
+# - file2
+# ...
+# You can use these placeholders in the "location" of each item:
+# $HOME: the home directory
+# $CONFIG_DIR: refers to "$HOME/.config/"
+# $SHARE_DIR: refers to "$HOME/.local/share"
+# $BIN_DIR: refers to "$HOME/.local/bin"
+# ${ENDS_WITH="text"}: for folders with different names on different computers whose names end with the same thing.
+# The best example for this is the "*.default-release" folder of firefox.
+# ${BEGINS_WITH="text"}: for folders with different names on different computers whose names start with the same thing.
+
+save:
+ configs:
+ location: "$CONFIG_DIR"
+ entries:
+ - gtk-2.0
+ - gtk-3.0
+ - gtk-4.0
+ - kate
+ - Kvantum
+ - latte
+ - dolphinrc
+ - katerc
+ - konsolerc
+ - kcminputrc
+ - kdeglobals
+ - kglobalshortcutsrc
+ - klipperrc
+ - krunnerrc
+ - kscreenlockerrc
+ - ksmserverrc
+ - kwinrc
+ - kwinrulesrc
+ - plasma-org.kde.plasma.desktop-appletsrc
+ - plasmarc
+ - plasmashellrc
+ - gtkrc
+ - gtkrc-2.0
+ - lattedockrc
+ - breezerc
+ - oxygenrc
+ - lightlyrc
+ - ksplashrc
+ - khotkeysrc
+
+ app_layouts:
+ location: "$HOME/.local/share/kxmlgui5"
+ entries:
+ - dolphin
+ - konsole
+
+ # Here are a few examples of how you can add more stuff to back up.
+ # Uncomment these lines if you want.
+ # firefox:
+ # location: "$HOME/.mozilla/firefox/${ENDS_WITH='.default-release'}"
+ # entries:
+ # - chrome # for firefox customizations
+
+ # code oss:
+ # location: "$CONFIG_DIR/Code - OSS/User/"
+ # entries:
+ # - settings.json
+
+
+# The following files will only be used for exporting and importing.
+export:
+ share_folder:
+ location: "$SHARE_DIR"
+ entries:
+ - plasma
+ - kwin
+ - konsole
+ - fonts
+ - color-schemes
+ - aurorae
+ - icons
+ - wallpapers
+
+ home_folder:
+ location: "$HOME/"
+ entries:
+ - .fonts
+ - .themes
+ - .icons
+
+
+ # You can add more files to export like this
+ # name:
+ # location: "path/to/parent/directory"
+ # entries:
+ # - file1
+ # - file2
+ # - folder1
+ # - folder2
+...
diff --git a/.config/konsave/profiles/laptop-kde/configs/dolphinrc b/.config/konsave/profiles/laptop-kde/configs/dolphinrc
new file mode 100644
index 0000000..ca14f5f
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/dolphinrc
@@ -0,0 +1,14 @@
+[$Version]
+update_info=dolphin_detailsmodesettings.upd:rename-leading-padding
+
+[General]
+Version=202
+ViewPropsTimestamp=2025,8,17,23,34,43.381
+
+[KFileDialog Settings]
+Places Icons Auto-resize=false
+Places Icons Static Size=22
+
+[MainWindow]
+MenuBar=Disabled
+ToolBarsMovable=Disabled
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-active.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-active.svg
new file mode 100644
index 0000000..2fd1e7a
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-active.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-backdrop-active.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-backdrop-active.svg
new file mode 100644
index 0000000..2fd1e7a
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-backdrop-active.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-backdrop-hover.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-backdrop-hover.svg
new file mode 100644
index 0000000..88176c0
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-backdrop-hover.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-backdrop-normal.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-backdrop-normal.svg
new file mode 100644
index 0000000..95f76de
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-backdrop-normal.svg
@@ -0,0 +1,27 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-hover.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-hover.svg
new file mode 100644
index 0000000..88176c0
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-hover.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-normal.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-normal.svg
new file mode 100644
index 0000000..59a4f23
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/close-normal.svg
@@ -0,0 +1,32 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-active.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-active.svg
new file mode 100644
index 0000000..5884cef
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-active.svg
@@ -0,0 +1,38 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-backdrop-active.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-backdrop-active.svg
new file mode 100644
index 0000000..5884cef
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-backdrop-active.svg
@@ -0,0 +1,38 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-backdrop-hover.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-backdrop-hover.svg
new file mode 100644
index 0000000..a79852c
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-backdrop-hover.svg
@@ -0,0 +1,38 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-backdrop-normal.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-backdrop-normal.svg
new file mode 100644
index 0000000..dd4e5ef
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-backdrop-normal.svg
@@ -0,0 +1,27 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-hover.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-hover.svg
new file mode 100644
index 0000000..a79852c
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-hover.svg
@@ -0,0 +1,38 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-normal.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-normal.svg
new file mode 100644
index 0000000..c56875b
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximize-normal.svg
@@ -0,0 +1,32 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-active.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-active.svg
new file mode 100644
index 0000000..7e1eaf9
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-active.svg
@@ -0,0 +1,37 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-backdrop-active.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-backdrop-active.svg
new file mode 100644
index 0000000..7e1eaf9
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-backdrop-active.svg
@@ -0,0 +1,37 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-backdrop-hover.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-backdrop-hover.svg
new file mode 100644
index 0000000..2c1afe0
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-backdrop-hover.svg
@@ -0,0 +1,37 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-backdrop-normal.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-backdrop-normal.svg
new file mode 100644
index 0000000..dd4e5ef
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-backdrop-normal.svg
@@ -0,0 +1,27 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-hover.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-hover.svg
new file mode 100644
index 0000000..2c1afe0
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-hover.svg
@@ -0,0 +1,37 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-normal.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-normal.svg
new file mode 100644
index 0000000..2e2b140
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/maximized-normal.svg
@@ -0,0 +1,31 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-active.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-active.svg
new file mode 100644
index 0000000..d458805
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-active.svg
@@ -0,0 +1,43 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-backdrop-active.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-backdrop-active.svg
new file mode 100644
index 0000000..d458805
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-backdrop-active.svg
@@ -0,0 +1,43 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-backdrop-hover.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-backdrop-hover.svg
new file mode 100644
index 0000000..19eef11
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-backdrop-hover.svg
@@ -0,0 +1,43 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-backdrop-normal.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-backdrop-normal.svg
new file mode 100644
index 0000000..7e6a20a
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-backdrop-normal.svg
@@ -0,0 +1,27 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-hover.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-hover.svg
new file mode 100644
index 0000000..19eef11
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-hover.svg
@@ -0,0 +1,43 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-normal.svg b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-normal.svg
new file mode 100644
index 0000000..9e95b18
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/assets/minimize-normal.svg
@@ -0,0 +1,31 @@
+
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/colors.css b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/colors.css
new file mode 100644
index 0000000..ea00f9a
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/colors.css
@@ -0,0 +1,84 @@
+@define-color borders_breeze #4a4c52;
+@define-color content_view_bg_breeze #101013;
+@define-color error_color_backdrop_breeze #ed254e;
+@define-color error_color_breeze #ed254e;
+@define-color error_color_insensitive_backdrop_breeze #591626;
+@define-color error_color_insensitive_breeze #591626;
+@define-color insensitive_base_color_breeze #0f0f12;
+@define-color insensitive_base_fg_color_breeze #505358;
+@define-color insensitive_bg_color_breeze #1b1b1f;
+@define-color insensitive_borders_breeze #2a2b30;
+@define-color insensitive_fg_color_breeze #585a60;
+@define-color insensitive_selected_bg_color_breeze #1b1b1f;
+@define-color insensitive_selected_fg_color_breeze #585a60;
+@define-color insensitive_unfocused_bg_color_breeze #1b1b1f;
+@define-color insensitive_unfocused_fg_color_breeze #585a60;
+@define-color insensitive_unfocused_selected_bg_color_breeze #1b1b1f;
+@define-color insensitive_unfocused_selected_fg_color_breeze #585a60;
+@define-color link_color_breeze #5294e2;
+@define-color link_visited_color_breeze #7cb7ff;
+@define-color success_color_backdrop_breeze #71f79f;
+@define-color success_color_breeze #71f79f;
+@define-color success_color_insensitive_backdrop_breeze #305c41;
+@define-color success_color_insensitive_breeze #305c41;
+@define-color theme_base_color_breeze #101013;
+@define-color theme_bg_color_breeze #1c1c21;
+@define-color theme_button_background_backdrop_breeze #31363d;
+@define-color theme_button_background_backdrop_insensitive_breeze #2f333a;
+@define-color theme_button_background_insensitive_breeze #2f333a;
+@define-color theme_button_background_normal_breeze #31363d;
+@define-color theme_button_decoration_focus_backdrop_breeze #0072ff;
+@define-color theme_button_decoration_focus_backdrop_insensitive_breeze #1e477b;
+@define-color theme_button_decoration_focus_breeze #0072ff;
+@define-color theme_button_decoration_focus_insensitive_breeze #1e477b;
+@define-color theme_button_decoration_hover_backdrop_breeze #0072ff;
+@define-color theme_button_decoration_hover_backdrop_insensitive_breeze #1e477b;
+@define-color theme_button_decoration_hover_breeze #0072ff;
+@define-color theme_button_decoration_hover_insensitive_breeze #1e477b;
+@define-color theme_button_foreground_active_backdrop_breeze #d3dae3;
+@define-color theme_button_foreground_active_backdrop_insensitive_breeze #585a60;
+@define-color theme_button_foreground_active_breeze #fefefe;
+@define-color theme_button_foreground_active_insensitive_breeze #585a60;
+@define-color theme_button_foreground_backdrop_breeze #c3c7d1;
+@define-color theme_button_foreground_backdrop_insensitive_breeze #5f646c;
+@define-color theme_button_foreground_insensitive_breeze #5f646c;
+@define-color theme_button_foreground_normal_breeze #c3c7d1;
+@define-color theme_fg_color_breeze #d3dae3;
+@define-color theme_header_background_backdrop_breeze #1c1c21;
+@define-color theme_header_background_breeze #1c1c21;
+@define-color theme_header_background_light_breeze #1c1c21;
+@define-color theme_header_foreground_backdrop_breeze #d3dae3;
+@define-color theme_header_foreground_breeze #d3dae3;
+@define-color theme_header_foreground_insensitive_backdrop_breeze #d3dae3;
+@define-color theme_header_foreground_insensitive_breeze #d3dae3;
+@define-color theme_hovering_selected_bg_color_breeze #0072ff;
+@define-color theme_selected_bg_color_breeze #0072ff;
+@define-color theme_selected_fg_color_breeze #fefefe;
+@define-color theme_text_color_breeze #d3dae3;
+@define-color theme_titlebar_background_backdrop_breeze #2f343f;
+@define-color theme_titlebar_background_breeze #2f343f;
+@define-color theme_titlebar_background_light_breeze #1c1c21;
+@define-color theme_titlebar_foreground_backdrop_breeze #666a73;
+@define-color theme_titlebar_foreground_breeze #d3dae3;
+@define-color theme_titlebar_foreground_insensitive_backdrop_breeze #666a73;
+@define-color theme_titlebar_foreground_insensitive_breeze #666a73;
+@define-color theme_unfocused_base_color_breeze #101013;
+@define-color theme_unfocused_bg_color_breeze #1c1c21;
+@define-color theme_unfocused_fg_color_breeze #d3dae3;
+@define-color theme_unfocused_selected_bg_color_alt_breeze #063065;
+@define-color theme_unfocused_selected_bg_color_breeze #063065;
+@define-color theme_unfocused_selected_fg_color_breeze #d3dae3;
+@define-color theme_unfocused_text_color_breeze #d3dae3;
+@define-color theme_unfocused_view_bg_color_breeze #0f0f12;
+@define-color theme_unfocused_view_text_color_breeze #505358;
+@define-color theme_view_active_decoration_color_breeze #0072ff;
+@define-color theme_view_hover_decoration_color_breeze #0072ff;
+@define-color tooltip_background_breeze #353945;
+@define-color tooltip_border_breeze #5d616d;
+@define-color tooltip_text_breeze #d3dae3;
+@define-color unfocused_borders_breeze #4a4c52;
+@define-color unfocused_insensitive_borders_breeze #2a2b30;
+@define-color warning_color_backdrop_breeze #ff6a00;
+@define-color warning_color_breeze #ff6a00;
+@define-color warning_color_insensitive_backdrop_breeze #5f2d0c;
+@define-color warning_color_insensitive_breeze #5f2d0c;
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/gtk.css b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/gtk.css
new file mode 100644
index 0000000..c9763f7
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/gtk.css
@@ -0,0 +1 @@
+@import 'colors.css';
\ No newline at end of file
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/settings.ini b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/settings.ini
new file mode 100644
index 0000000..857e588
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/settings.ini
@@ -0,0 +1,15 @@
+[Settings]
+gtk-application-prefer-dark-theme=true
+gtk-button-images=true
+gtk-cursor-theme-name=Sweet-cursors
+gtk-cursor-theme-size=24
+gtk-decoration-layout=icon:minimize,maximize,close
+gtk-enable-animations=true
+gtk-font-name=Noto Sans, 11
+gtk-icon-theme-name=candy-icons
+gtk-menu-images=true
+gtk-modules=colorreload-gtk-module:window-decorations-gtk-module
+gtk-primary-button-warps-slider=false
+gtk-theme-name=Breeze
+gtk-toolbar-style=3
+gtk-xft-dpi=98304
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/window_decorations.css b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/window_decorations.css
new file mode 100644
index 0000000..ca70a8a
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-3.0/window_decorations.css
@@ -0,0 +1,71 @@
+headerbar button.titlebutton.close, .titlebar button.titlebutton.close {
+ background-image: url("assets/close-normal.svg"); }
+
+headerbar button.titlebutton.close:hover, .titlebar button.titlebutton.close:hover {
+ background-image: url("assets/close-hover.svg"); }
+
+headerbar button.titlebutton.close:active, .titlebar button.titlebutton.close:active {
+ background-image: url("assets/close-active.svg"); }
+
+headerbar button.titlebutton.close:backdrop, .titlebar button.titlebutton.close:backdrop {
+ background-image: url("assets/close-backdrop-normal.svg"); }
+
+headerbar button.titlebutton.close:backdrop:hover, .titlebar button.titlebutton.close:backdrop:hover {
+ background-image: url("assets/close-backdrop-hover.svg"); }
+
+headerbar button.titlebutton.close:backdrop:active, .titlebar button.titlebutton.close:backdrop:active {
+ background-image: url("assets/close-backdrop-active.svg"); }
+
+headerbar button.titlebutton.maximize, .titlebar button.titlebutton.maximize {
+ background-image: url("assets/maximize-normal.svg"); }
+
+headerbar button.titlebutton.maximize:hover, .titlebar button.titlebutton.maximize:hover {
+ background-image: url("assets/maximize-hover.svg"); }
+
+headerbar button.titlebutton.maximize:active, .titlebar button.titlebutton.maximize:active {
+ background-image: url("assets/maximize-active.svg"); }
+
+headerbar button.titlebutton.maximize:backdrop, .titlebar button.titlebutton.maximize:backdrop {
+ background-image: url("assets/maximize-backdrop-normal.svg"); }
+
+headerbar button.titlebutton.maximize:backdrop:hover, .titlebar button.titlebutton.maximize:backdrop:hover {
+ background-image: url("assets/maximize-backdrop-hover.svg"); }
+
+headerbar button.titlebutton.maximize:backdrop:active, .titlebar button.titlebutton.maximize:backdrop:active {
+ background-image: url("assets/maximize-backdrop-active.svg"); }
+
+headerbar button.titlebutton.minimize, .titlebar button.titlebutton.minimize {
+ background-image: url("assets/minimize-normal.svg"); }
+
+headerbar button.titlebutton.minimize:hover, .titlebar button.titlebutton.minimize:hover {
+ background-image: url("assets/minimize-hover.svg"); }
+
+headerbar button.titlebutton.minimize:active, .titlebar button.titlebutton.minimize:active {
+ background-image: url("assets/minimize-active.svg"); }
+
+headerbar button.titlebutton.minimize:backdrop, .titlebar button.titlebutton.minimize:backdrop {
+ background-image: url("assets/minimize-backdrop-normal.svg"); }
+
+headerbar button.titlebutton.minimize:backdrop:hover, .titlebar button.titlebutton.minimize:backdrop:hover {
+ background-image: url("assets/minimize-backdrop-hover.svg"); }
+
+headerbar button.titlebutton.minimize:backdrop:active, .titlebar button.titlebutton.minimize:backdrop:active {
+ background-image: url("assets/minimize-backdrop-active.svg"); }
+
+.maximized headerbar button.titlebutton.maximize, .maximized .titlebar button.titlebutton.maximize {
+ background-image: url("assets/maximized-normal.svg"); }
+
+.maximized headerbar button.titlebutton.maximize:hover, .maximized .titlebar button.titlebutton.maximize:hover {
+ background-image: url("assets/maximized-hover.svg"); }
+
+.maximized headerbar button.titlebutton.maximize:active, .maximized .titlebar button.titlebutton.maximize:active {
+ background-image: url("assets/maximized-active.svg"); }
+
+.maximized headerbar button.titlebutton.maximize:backdrop, .maximized .titlebar button.titlebutton.maximize:backdrop {
+ background-image: url("assets/maximized-backdrop-normal.svg"); }
+
+.maximized headerbar button.titlebutton.maximize:backdrop:hover, .maximized .titlebar button.titlebutton.maximize:backdrop:hover {
+ background-image: url("assets/maximized-backdrop-hover.svg"); }
+
+.maximized headerbar button.titlebutton.maximize:backdrop:active, .maximized .titlebar button.titlebutton.maximize:backdrop:active {
+ background-image: url("assets/maximized-backdrop-active.svg"); }
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-4.0/colors.css b/.config/konsave/profiles/laptop-kde/configs/gtk-4.0/colors.css
new file mode 100644
index 0000000..ea00f9a
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-4.0/colors.css
@@ -0,0 +1,84 @@
+@define-color borders_breeze #4a4c52;
+@define-color content_view_bg_breeze #101013;
+@define-color error_color_backdrop_breeze #ed254e;
+@define-color error_color_breeze #ed254e;
+@define-color error_color_insensitive_backdrop_breeze #591626;
+@define-color error_color_insensitive_breeze #591626;
+@define-color insensitive_base_color_breeze #0f0f12;
+@define-color insensitive_base_fg_color_breeze #505358;
+@define-color insensitive_bg_color_breeze #1b1b1f;
+@define-color insensitive_borders_breeze #2a2b30;
+@define-color insensitive_fg_color_breeze #585a60;
+@define-color insensitive_selected_bg_color_breeze #1b1b1f;
+@define-color insensitive_selected_fg_color_breeze #585a60;
+@define-color insensitive_unfocused_bg_color_breeze #1b1b1f;
+@define-color insensitive_unfocused_fg_color_breeze #585a60;
+@define-color insensitive_unfocused_selected_bg_color_breeze #1b1b1f;
+@define-color insensitive_unfocused_selected_fg_color_breeze #585a60;
+@define-color link_color_breeze #5294e2;
+@define-color link_visited_color_breeze #7cb7ff;
+@define-color success_color_backdrop_breeze #71f79f;
+@define-color success_color_breeze #71f79f;
+@define-color success_color_insensitive_backdrop_breeze #305c41;
+@define-color success_color_insensitive_breeze #305c41;
+@define-color theme_base_color_breeze #101013;
+@define-color theme_bg_color_breeze #1c1c21;
+@define-color theme_button_background_backdrop_breeze #31363d;
+@define-color theme_button_background_backdrop_insensitive_breeze #2f333a;
+@define-color theme_button_background_insensitive_breeze #2f333a;
+@define-color theme_button_background_normal_breeze #31363d;
+@define-color theme_button_decoration_focus_backdrop_breeze #0072ff;
+@define-color theme_button_decoration_focus_backdrop_insensitive_breeze #1e477b;
+@define-color theme_button_decoration_focus_breeze #0072ff;
+@define-color theme_button_decoration_focus_insensitive_breeze #1e477b;
+@define-color theme_button_decoration_hover_backdrop_breeze #0072ff;
+@define-color theme_button_decoration_hover_backdrop_insensitive_breeze #1e477b;
+@define-color theme_button_decoration_hover_breeze #0072ff;
+@define-color theme_button_decoration_hover_insensitive_breeze #1e477b;
+@define-color theme_button_foreground_active_backdrop_breeze #d3dae3;
+@define-color theme_button_foreground_active_backdrop_insensitive_breeze #585a60;
+@define-color theme_button_foreground_active_breeze #fefefe;
+@define-color theme_button_foreground_active_insensitive_breeze #585a60;
+@define-color theme_button_foreground_backdrop_breeze #c3c7d1;
+@define-color theme_button_foreground_backdrop_insensitive_breeze #5f646c;
+@define-color theme_button_foreground_insensitive_breeze #5f646c;
+@define-color theme_button_foreground_normal_breeze #c3c7d1;
+@define-color theme_fg_color_breeze #d3dae3;
+@define-color theme_header_background_backdrop_breeze #1c1c21;
+@define-color theme_header_background_breeze #1c1c21;
+@define-color theme_header_background_light_breeze #1c1c21;
+@define-color theme_header_foreground_backdrop_breeze #d3dae3;
+@define-color theme_header_foreground_breeze #d3dae3;
+@define-color theme_header_foreground_insensitive_backdrop_breeze #d3dae3;
+@define-color theme_header_foreground_insensitive_breeze #d3dae3;
+@define-color theme_hovering_selected_bg_color_breeze #0072ff;
+@define-color theme_selected_bg_color_breeze #0072ff;
+@define-color theme_selected_fg_color_breeze #fefefe;
+@define-color theme_text_color_breeze #d3dae3;
+@define-color theme_titlebar_background_backdrop_breeze #2f343f;
+@define-color theme_titlebar_background_breeze #2f343f;
+@define-color theme_titlebar_background_light_breeze #1c1c21;
+@define-color theme_titlebar_foreground_backdrop_breeze #666a73;
+@define-color theme_titlebar_foreground_breeze #d3dae3;
+@define-color theme_titlebar_foreground_insensitive_backdrop_breeze #666a73;
+@define-color theme_titlebar_foreground_insensitive_breeze #666a73;
+@define-color theme_unfocused_base_color_breeze #101013;
+@define-color theme_unfocused_bg_color_breeze #1c1c21;
+@define-color theme_unfocused_fg_color_breeze #d3dae3;
+@define-color theme_unfocused_selected_bg_color_alt_breeze #063065;
+@define-color theme_unfocused_selected_bg_color_breeze #063065;
+@define-color theme_unfocused_selected_fg_color_breeze #d3dae3;
+@define-color theme_unfocused_text_color_breeze #d3dae3;
+@define-color theme_unfocused_view_bg_color_breeze #0f0f12;
+@define-color theme_unfocused_view_text_color_breeze #505358;
+@define-color theme_view_active_decoration_color_breeze #0072ff;
+@define-color theme_view_hover_decoration_color_breeze #0072ff;
+@define-color tooltip_background_breeze #353945;
+@define-color tooltip_border_breeze #5d616d;
+@define-color tooltip_text_breeze #d3dae3;
+@define-color unfocused_borders_breeze #4a4c52;
+@define-color unfocused_insensitive_borders_breeze #2a2b30;
+@define-color warning_color_backdrop_breeze #ff6a00;
+@define-color warning_color_breeze #ff6a00;
+@define-color warning_color_insensitive_backdrop_breeze #5f2d0c;
+@define-color warning_color_insensitive_breeze #5f2d0c;
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-4.0/gtk.css b/.config/konsave/profiles/laptop-kde/configs/gtk-4.0/gtk.css
new file mode 100644
index 0000000..c9763f7
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-4.0/gtk.css
@@ -0,0 +1 @@
+@import 'colors.css';
\ No newline at end of file
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-4.0/settings.ini b/.config/konsave/profiles/laptop-kde/configs/gtk-4.0/settings.ini
new file mode 100644
index 0000000..2c01403
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-4.0/settings.ini
@@ -0,0 +1,12 @@
+[Settings]
+gtk-application-prefer-dark-theme=true
+gtk-cursor-theme-name=Sweet-cursors
+gtk-cursor-theme-size=24
+gtk-decoration-layout=icon:minimize,maximize,close
+gtk-enable-animations=true
+gtk-font-name=Noto Sans, 11
+gtk-icon-theme-name=candy-icons
+gtk-modules=colorreload-gtk-module:window-decorations-gtk-module
+gtk-primary-button-warps-slider=false
+gtk-theme-name=Breeze
+gtk-xft-dpi=98304
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtk-4.0/window_decorations.css b/.config/konsave/profiles/laptop-kde/configs/gtk-4.0/window_decorations.css
new file mode 100644
index 0000000..ca70a8a
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtk-4.0/window_decorations.css
@@ -0,0 +1,71 @@
+headerbar button.titlebutton.close, .titlebar button.titlebutton.close {
+ background-image: url("assets/close-normal.svg"); }
+
+headerbar button.titlebutton.close:hover, .titlebar button.titlebutton.close:hover {
+ background-image: url("assets/close-hover.svg"); }
+
+headerbar button.titlebutton.close:active, .titlebar button.titlebutton.close:active {
+ background-image: url("assets/close-active.svg"); }
+
+headerbar button.titlebutton.close:backdrop, .titlebar button.titlebutton.close:backdrop {
+ background-image: url("assets/close-backdrop-normal.svg"); }
+
+headerbar button.titlebutton.close:backdrop:hover, .titlebar button.titlebutton.close:backdrop:hover {
+ background-image: url("assets/close-backdrop-hover.svg"); }
+
+headerbar button.titlebutton.close:backdrop:active, .titlebar button.titlebutton.close:backdrop:active {
+ background-image: url("assets/close-backdrop-active.svg"); }
+
+headerbar button.titlebutton.maximize, .titlebar button.titlebutton.maximize {
+ background-image: url("assets/maximize-normal.svg"); }
+
+headerbar button.titlebutton.maximize:hover, .titlebar button.titlebutton.maximize:hover {
+ background-image: url("assets/maximize-hover.svg"); }
+
+headerbar button.titlebutton.maximize:active, .titlebar button.titlebutton.maximize:active {
+ background-image: url("assets/maximize-active.svg"); }
+
+headerbar button.titlebutton.maximize:backdrop, .titlebar button.titlebutton.maximize:backdrop {
+ background-image: url("assets/maximize-backdrop-normal.svg"); }
+
+headerbar button.titlebutton.maximize:backdrop:hover, .titlebar button.titlebutton.maximize:backdrop:hover {
+ background-image: url("assets/maximize-backdrop-hover.svg"); }
+
+headerbar button.titlebutton.maximize:backdrop:active, .titlebar button.titlebutton.maximize:backdrop:active {
+ background-image: url("assets/maximize-backdrop-active.svg"); }
+
+headerbar button.titlebutton.minimize, .titlebar button.titlebutton.minimize {
+ background-image: url("assets/minimize-normal.svg"); }
+
+headerbar button.titlebutton.minimize:hover, .titlebar button.titlebutton.minimize:hover {
+ background-image: url("assets/minimize-hover.svg"); }
+
+headerbar button.titlebutton.minimize:active, .titlebar button.titlebutton.minimize:active {
+ background-image: url("assets/minimize-active.svg"); }
+
+headerbar button.titlebutton.minimize:backdrop, .titlebar button.titlebutton.minimize:backdrop {
+ background-image: url("assets/minimize-backdrop-normal.svg"); }
+
+headerbar button.titlebutton.minimize:backdrop:hover, .titlebar button.titlebutton.minimize:backdrop:hover {
+ background-image: url("assets/minimize-backdrop-hover.svg"); }
+
+headerbar button.titlebutton.minimize:backdrop:active, .titlebar button.titlebutton.minimize:backdrop:active {
+ background-image: url("assets/minimize-backdrop-active.svg"); }
+
+.maximized headerbar button.titlebutton.maximize, .maximized .titlebar button.titlebutton.maximize {
+ background-image: url("assets/maximized-normal.svg"); }
+
+.maximized headerbar button.titlebutton.maximize:hover, .maximized .titlebar button.titlebutton.maximize:hover {
+ background-image: url("assets/maximized-hover.svg"); }
+
+.maximized headerbar button.titlebutton.maximize:active, .maximized .titlebar button.titlebutton.maximize:active {
+ background-image: url("assets/maximized-active.svg"); }
+
+.maximized headerbar button.titlebutton.maximize:backdrop, .maximized .titlebar button.titlebutton.maximize:backdrop {
+ background-image: url("assets/maximized-backdrop-normal.svg"); }
+
+.maximized headerbar button.titlebutton.maximize:backdrop:hover, .maximized .titlebar button.titlebutton.maximize:backdrop:hover {
+ background-image: url("assets/maximized-backdrop-hover.svg"); }
+
+.maximized headerbar button.titlebutton.maximize:backdrop:active, .maximized .titlebar button.titlebutton.maximize:backdrop:active {
+ background-image: url("assets/maximized-backdrop-active.svg"); }
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtkrc b/.config/konsave/profiles/laptop-kde/configs/gtkrc
new file mode 100644
index 0000000..ae4050e
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtkrc
@@ -0,0 +1,2 @@
+# created by KDE Plasma, Wed Aug 20 15:01:07 2025
+#
diff --git a/.config/konsave/profiles/laptop-kde/configs/gtkrc-2.0 b/.config/konsave/profiles/laptop-kde/configs/gtkrc-2.0
new file mode 100644
index 0000000..62531ef
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/gtkrc-2.0
@@ -0,0 +1,5 @@
+# created by KDE Plasma, Wed Aug 20 15:01:07 2025
+#
+
+gtk-alternative-button-order = 1
+
diff --git a/.config/konsave/profiles/laptop-kde/configs/katerc b/.config/konsave/profiles/laptop-kde/configs/katerc
new file mode 100644
index 0000000..b1d7aed
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/katerc
@@ -0,0 +1,132 @@
+[General]
+Days Meta Infos=30
+Save Meta Infos=true
+Show Full Path in Title=false
+Show Menu Bar=true
+Show Status Bar=true
+Show Tab Bar=true
+Show Url Nav Bar=true
+
+[KTextEditor Document]
+Allow End of Line Detection=true
+Auto Detect Indent=true
+Auto Reload If State Is In Version Control=true
+Auto Save=false
+Auto Save Interval=0
+Auto Save On Focus Out=false
+BOM=false
+Backup Local=false
+Backup Prefix=
+Backup Remote=false
+Backup Suffix=~
+Camel Cursor=true
+Encoding=UTF-8
+End of Line=0
+Indent On Backspace=true
+Indent On Tab=true
+Indent On Text Paste=false
+Indentation Mode=normal
+Indentation Width=4
+Keep Extra Spaces=false
+Line Length Limit=10000
+Newline at End of File=true
+On-The-Fly Spellcheck=false
+Overwrite Mode=false
+PageUp/PageDown Moves Cursor=false
+Remove Spaces=1
+ReplaceTabsDyn=true
+Show Spaces=0
+Show Tabs=true
+Smart Home=true
+Swap Directory=
+Swap File Mode=1
+Swap Sync Interval=15
+Tab Handling=2
+Tab Width=4
+Trailing Marker Size=1
+Word Wrap=false
+Word Wrap Column=80
+
+[KTextEditor Editor]
+Encoding Prober Type=1
+Fallback Encoding=ISO 8859-15
+
+[KTextEditor Renderer]
+Animate Bracket Matching=false
+Auto Color Theme Selection=true
+Color Theme=Breeze Dark
+Font=Hack,10,-1,7,50,0,0,0,0,0
+Line Height Multiplier=1
+Show Indentation Lines=false
+Show Whole Bracket Expression=false
+Word Wrap Marker=false
+
+[KTextEditor View]
+Allow Mark Menu=true
+Auto Brackets=true
+Auto Center Lines=0
+Auto Completion=true
+Auto Completion Preselect First Entry=true
+Backspace Remove Composed Characters=false
+Bookmark Menu Sorting=0
+Bracket Match Preview=false
+Chars To Enclose Selection=<>(){}[]'"
+Default Mark Type=1
+Dynamic Word Wrap=true
+Dynamic Word Wrap Align Indent=80
+Dynamic Word Wrap At Static Marker=false
+Dynamic Word Wrap Indicators=1
+Dynamic Wrap not at word boundaries=false
+Enable Tab completion=false
+Fold First Line=false
+Folding Bar=true
+Folding Preview=true
+Icon Bar=false
+Input Mode=0
+Keyword Completion=true
+Line Modification=true
+Line Numbers=true
+Max Clipboard History Entries=20
+Maximum Search History Size=100
+Mouse Paste At Cursor Position=false
+Multiple Cursor Modifier=134217728
+Persistent Selection=false
+Scroll Bar Marks=false
+Scroll Bar Mini Map All=true
+Scroll Bar Mini Map Width=60
+Scroll Bar MiniMap=true
+Scroll Bar Preview=true
+Scroll Past End=false
+Search/Replace Flags=140
+Shoe Line Ending Type in Statusbar=false
+Show Documentation With Completion=true
+Show File Encoding=true
+Show Focus Frame Around Editor=true
+Show Folding Icons On Hover Only=true
+Show Line Count=false
+Show Scrollbars=0
+Show Statusbar Dictionary=true
+Show Statusbar Highlighting Mode=true
+Show Statusbar Input Mode=true
+Show Statusbar Line Column=true
+Show Statusbar Tab Settings=true
+Show Word Count=false
+Smart Copy Cut=true
+Statusbar Line Column Compact Mode=true
+Text Drag And Drop=true
+User Sets Of Chars To Enclose Selection=
+Vi Input Mode Steal Keys=false
+Vi Relative Line Numbers=false
+Word Completion=true
+Word Completion Minimal Word Length=3
+Word Completion Remove Tail=true
+
+[filetree]
+editShade=183,220,246
+listMode=false
+shadingEnabled=true
+showCloseButton=false
+showFullPathOnRoots=false
+showToolbar=true
+sortRole=0
+viewShade=211,190,222
diff --git a/.config/konsave/profiles/laptop-kde/configs/kcminputrc b/.config/konsave/profiles/laptop-kde/configs/kcminputrc
new file mode 100644
index 0000000..a39a1d4
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/kcminputrc
@@ -0,0 +1,16 @@
+[$Version]
+update_info=delete_cursor_old_default_size.upd:DeleteCursorOldDefaultSize,kcminputrc_fix_botched_5_21_0.upd:kcminputrc_fix_botched_5_21_0_pre,kcminputrc_fix_botched_5_21_0.upd:kcminputrc_fix_botched_5_21_0,kcminputrc_repeat.upd:kcminputrc_migrate_key_repeat
+
+[Keyboard]
+NumLock=0
+
+[Libinput][2362][569][PIXA3854:00 093A:0239 Touchpad]
+ClickMethod=2
+TapDragLock=true
+TapToClick=true
+
+[Mouse]
+X11LibInputXAccelProfileFlat=false
+
+[Tmp]
+update_info=delete_cursor_old_default_size.upd:DeleteCursorOldDefaultSize
diff --git a/.config/konsave/profiles/laptop-kde/configs/kdeglobals b/.config/konsave/profiles/laptop-kde/configs/kdeglobals
new file mode 100644
index 0000000..ae7606f
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/kdeglobals
@@ -0,0 +1,143 @@
+[$Version]
+update_info=filepicker.upd:filepicker-remove-old-previews-entry,fonts_global.upd:Fonts_Global,fonts_global_toolbar.upd:Fonts_Global_Toolbar,icons_remove_effects.upd:IconsRemoveEffects,kwin.upd:animation-speed,style_widgetstyle_default_breeze.upd:StyleWidgetStyleDefaultBreeze
+
+[ColorEffects:Disabled]
+ChangeSelectionColor=
+Color=56,56,56
+ColorAmount=0
+ColorEffect=0
+ContrastAmount=0.65
+ContrastEffect=1
+Enable=
+IntensityAmount=0.1
+IntensityEffect=2
+
+[ColorEffects:Inactive]
+ChangeSelectionColor=true
+Color=112,111,110
+ColorAmount=0.025000000000000001
+ColorEffect=2
+ContrastAmount=0.10000000000000001
+ContrastEffect=2
+Enable=false
+IntensityAmount=0
+IntensityEffect=0
+
+[Colors:Button]
+BackgroundAlternate=64,69,82
+BackgroundNormal=49,54,61
+DecorationFocus=0,114,255
+DecorationHover=0,114,255
+ForegroundActive=61,174,233
+ForegroundInactive=102,106,115
+ForegroundLink=41,128,185
+ForegroundNegative=237,37,78
+ForegroundNeutral=255,106,0
+ForegroundNormal=195,199,209
+ForegroundPositive=113,247,159
+ForegroundVisited=82,148,226
+
+[Colors:Selection]
+BackgroundAlternate=29,153,243
+BackgroundNormal=0,114,255
+DecorationFocus=0,114,255
+DecorationHover=0,114,255
+ForegroundActive=252,252,252
+ForegroundInactive=211,218,227
+ForegroundLink=253,188,75
+ForegroundNegative=237,37,78
+ForegroundNeutral=255,106,0
+ForegroundNormal=254,254,254
+ForegroundPositive=113,247,159
+ForegroundVisited=189,195,199
+
+[Colors:Tooltip]
+BackgroundAlternate=47,52,63
+BackgroundNormal=53,57,69
+DecorationFocus=0,114,255
+DecorationHover=0,114,255
+ForegroundActive=61,174,233
+ForegroundInactive=102,106,115
+ForegroundLink=41,128,185
+ForegroundNegative=237,37,78
+ForegroundNeutral=255,106,0
+ForegroundNormal=211,218,227
+ForegroundPositive=113,247,159
+ForegroundVisited=82,148,226
+
+[Colors:View]
+BackgroundAlternate=31,35,51
+BackgroundNormal=16,16,19
+DecorationFocus=0,114,255
+DecorationHover=0,114,255
+ForegroundActive=0,193,228
+ForegroundInactive=102,106,115
+ForegroundLink=82,148,226
+ForegroundNegative=237,37,78
+ForegroundNeutral=255,106,0
+ForegroundNormal=211,218,227
+ForegroundPositive=113,247,159
+ForegroundVisited=124,183,255
+
+[Colors:Window]
+BackgroundAlternate=47,52,63
+BackgroundNormal=28,28,33
+DecorationFocus=0,114,255
+DecorationHover=0,114,255
+ForegroundActive=61,174,233
+ForegroundInactive=102,106,115
+ForegroundLink=41,128,185
+ForegroundNegative=237,37,78
+ForegroundNeutral=255,106,0
+ForegroundNormal=211,218,227
+ForegroundPositive=113,247,159
+ForegroundVisited=179,13,191
+
+[DirSelect Dialog]
+DirSelectDialog Size=845,578
+
+[General]
+BrowserApplication=firefox-esr.desktop
+ColorScheme=SweetAmbarBlue
+ColorSchemeHash=f6df0e9f12a4783afd65d81532865d4d86848c5e
+TerminalApplication=alacritty
+TerminalService=alacritty-AM.desktop
+XftSubPixel=none
+fixed=Inconsolata,11,-1,5,57,0,0,0,0,0,Medium
+font=Noto Sans,11,-1,5,50,0,0,0,0,0
+menuFont=Noto Sans,11,-1,5,50,0,0,0,0,0
+smallestReadableFont=Noto Sans,9,-1,5,50,0,0,0,0,0
+toolBarFont=Noto Sans,11,-1,5,50,0,0,0,0,0
+
+[KDE]
+LookAndFeelPackage=Sweet-Ambar-Blue
+widgetStyle=Oxygen
+
+[KFileDialog Settings]
+Allow Expansion=false
+Automatically select filename extension=true
+Breadcrumb Navigation=true
+Decoration position=2
+LocationCombo Completionmode=5
+PathCombo Completionmode=5
+Show Bookmarks=false
+Show Full Path=false
+Show Inline Previews=true
+Show Preview=false
+Show Speedbar=true
+Show hidden files=true
+Sort by=Name
+Sort directories first=true
+Sort hidden files last=false
+Sort reversed=false
+Speedbar Width=154
+View Style=DetailTree
+
+[WM]
+activeBackground=47,52,63
+activeBlend=47,52,63
+activeFont=Noto Sans,11,-1,5,50,0,0,0,0,0
+activeForeground=211,218,227
+inactiveBackground=47,52,63
+inactiveBlend=47,52,63
+inactiveForeground=102,106,115
diff --git a/.config/konsave/profiles/laptop-kde/configs/kglobalshortcutsrc b/.config/konsave/profiles/laptop-kde/configs/kglobalshortcutsrc
new file mode 100644
index 0000000..8da55cc
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/kglobalshortcutsrc
@@ -0,0 +1,322 @@
+[ActivityManager]
+_k_friendly_name=Activity Manager
+switch-to-activity-09e50951-6a17-4dca-8490-891d4b1f1a7b=none,none,Switch to activity "Messaging"
+switch-to-activity-9763face-6a83-4162-9250-00df5eadcbe6=none,none,Switch to activity "Game"
+switch-to-activity-b8cde0cc-78c3-4951-962c-b2fc6e340ff6=none,none,Switch to activity "Default"
+
+[KDE Keyboard Layout Switcher]
+Switch to Next Keyboard Layout=Meta+Alt+K,Meta+Alt+K,Switch to Next Keyboard Layout
+_k_friendly_name=Keyboard Layout Switcher
+
+[alacritty-AM.desktop]
+New=Meta+Return,none,New Terminal
+_k_friendly_name=Alacritty
+_launch=none,none,Alacritty
+
+[kaccess]
+Toggle Screen Reader On and Off=Meta+Alt+S,Meta+Alt+S,Toggle Screen Reader On and Off
+_k_friendly_name=Accessibility
+
+[kcm_touchpad]
+Disable Touchpad=Touchpad Off,Touchpad Off,Disable Touchpad
+Enable Touchpad=Touchpad On,Touchpad On,Enable Touchpad
+Toggle Touchpad=Touchpad Toggle\tMeta+Ctrl+Zenkaku Hankaku,Touchpad Toggle,Toggle Touchpad
+_k_friendly_name=Touchpad
+
+[kded5]
+Show System Activity=Ctrl+Esc,Ctrl+Esc,Show System Activity
+_k_friendly_name=KDE Daemon
+display=Display\tMeta+P,Display\tMeta+P,Switch Display
+
+[khotkeys]
+_k_friendly_name=Custom Shortcuts Service
+{0fc0cfdf-b4f2-4dc0-b1af-c779fea9cace}=,none,New Action
+{1d2a0200-07fb-4a21-89cc-945241fdfbf9}=none,none,Rotate Down
+{605975d3-a3fa-41ce-8a30-655e6302cf87}=none,none,Rotate Left
+{9d07f6e6-e52c-45f0-860e-8743a1e30b7d}=,none,New Action
+{aaecd1c5-62e0-4900-9485-d0320b15291b}=none,none,Rotate Right
+{c01c9ab3-f2ea-43a2-8470-f0e987283b91}=none,none,Rotate Up
+{d03619b6-9b3c-48cc-9d9c-a2aadb485550}=none,none,Search
+
+[kmix]
+_k_friendly_name=Audio Volume
+decrease_microphone_volume=Microphone Volume Down,Microphone Volume Down,Decrease Microphone Volume
+decrease_volume=Volume Down,Volume Down,Decrease Volume
+increase_microphone_volume=Microphone Volume Up,Microphone Volume Up,Increase Microphone Volume
+increase_volume=Volume Up,Volume Up,Increase Volume
+mic_mute=Microphone Mute\tMeta+Volume Mute,Microphone Mute\tMeta+Volume Mute,Mute Microphone
+mute=Volume Mute,Volume Mute,Mute
+
+[kscreen-doctor-2.desktop]
+_k_friendly_name=kscreen-doctor output.eDP-1.rotation.normal
+_launch=Meta+Ctrl+Down,none,kscreen-doctor output.eDP-1.rotation.normal
+
+[kscreen-doctor-3.desktop]
+_k_friendly_name=kscreen-doctor output.eDP-1.rotation.left
+_launch=Meta+Ctrl+Left,none,kscreen-doctor output.eDP-1.rotation.left
+
+[kscreen-doctor-4.desktop]
+_k_friendly_name=kscreen-doctor output.eDP-1.rotation.inverted
+_launch=Meta+Ctrl+Up,none,kscreen-doctor output.eDP-1.rotation.inverted
+
+[kscreen-doctor.desktop]
+_k_friendly_name=kscreen-doctor output.eDP-1.rotation.right
+_launch=Meta+Ctrl+Right,none,kscreen-doctor output.eDP-1.rotation.right
+
+[ksmserver]
+Halt Without Confirmation=none,,Halt Without Confirmation
+Lock Session=Meta+L\tScreensaver,Meta+L\tScreensaver,Lock Session
+Log Out=Ctrl+Alt+Del,Ctrl+Alt+Del,Log Out
+Log Out Without Confirmation=none,,Log Out Without Confirmation
+Reboot Without Confirmation=none,,Reboot Without Confirmation
+_k_friendly_name=Session Management
+
+[kwin]
+Activate Window Demanding Attention=Meta+Ctrl+A,Meta+Ctrl+A,Activate Window Demanding Attention
+Decrease Opacity=none,,Decrease Opacity of Active Window by 5%
+Edit Tiles=Meta+T,Meta+T,Toggle Tiles Editor
+Expose=Ctrl+F9,Ctrl+F9,Toggle Present Windows (Current desktop)
+ExposeAll=Ctrl+F10\tLaunch (C),Ctrl+F10\tLaunch (C),Toggle Present Windows (All desktops)
+ExposeClass=Ctrl+F7,Ctrl+F7,Toggle Present Windows (Window class)
+ExposeClassCurrentDesktop=none,none,Toggle Present Windows (Window class on current desktop)
+Increase Opacity=none,,Increase Opacity of Active Window by 5%
+Kill Window=Meta+Ctrl+Esc,Meta+Ctrl+Esc,Kill Window
+Move Tablet to Next Output=none,none,Move the tablet to the next output
+MoveMouseToCenter=Meta+F6,Meta+F6,Move Mouse to Center
+MoveMouseToFocus=Meta+F5,Meta+F5,Move Mouse to Focus
+MoveZoomDown=none,none,Move Zoomed Area Downwards
+MoveZoomLeft=none,none,Move Zoomed Area to Left
+MoveZoomRight=none,none,Move Zoomed Area to Right
+MoveZoomUp=none,none,Move Zoomed Area Upwards
+Overview=Meta+W,Meta+W,Toggle Overview
+Setup Window Shortcut=none,,Setup Window Shortcut
+Show Desktop=Meta+D,Meta+D,Peek at Desktop
+ShowDesktopGrid=Meta+F8,Meta+F8,Show Desktop Grid
+Suspend Compositing=Alt+Shift+F12,Alt+Shift+F12,Suspend Compositing
+Switch One Desktop Down=none,Meta+Ctrl+Down,Switch One Desktop Down
+Switch One Desktop Up=none,Meta+Ctrl+Up,Switch One Desktop Up
+Switch One Desktop to the Left=none,Meta+Ctrl+Left,Switch One Desktop to the Left
+Switch One Desktop to the Right=none,Meta+Ctrl+Right,Switch One Desktop to the Right
+Switch Window Down=Meta+Alt+Down,Meta+Alt+Down,Switch to Window Below
+Switch Window Left=Meta+Alt+Left,Meta+Alt+Left,Switch to Window to the Left
+Switch Window Right=Meta+Alt+Right,Meta+Alt+Right,Switch to Window to the Right
+Switch Window Up=Meta+Alt+Up,Meta+Alt+Up,Switch to Window Above
+Switch to Desktop 1=Ctrl+F1,Ctrl+F1,Switch to Desktop 1
+Switch to Desktop 10=none,,Switch to Desktop 10
+Switch to Desktop 11=none,,Switch to Desktop 11
+Switch to Desktop 12=none,,Switch to Desktop 12
+Switch to Desktop 13=none,,Switch to Desktop 13
+Switch to Desktop 14=none,,Switch to Desktop 14
+Switch to Desktop 15=none,,Switch to Desktop 15
+Switch to Desktop 16=none,,Switch to Desktop 16
+Switch to Desktop 17=none,,Switch to Desktop 17
+Switch to Desktop 18=none,,Switch to Desktop 18
+Switch to Desktop 19=none,,Switch to Desktop 19
+Switch to Desktop 2=Ctrl+F2,Ctrl+F2,Switch to Desktop 2
+Switch to Desktop 20=none,,Switch to Desktop 20
+Switch to Desktop 3=Ctrl+F3,Ctrl+F3,Switch to Desktop 3
+Switch to Desktop 4=Ctrl+F4,Ctrl+F4,Switch to Desktop 4
+Switch to Desktop 5=none,,Switch to Desktop 5
+Switch to Desktop 6=none,,Switch to Desktop 6
+Switch to Desktop 7=none,,Switch to Desktop 7
+Switch to Desktop 8=none,,Switch to Desktop 8
+Switch to Desktop 9=none,,Switch to Desktop 9
+Switch to Next Desktop=none,,Switch to Next Desktop
+Switch to Next Screen=none,,Switch to Next Screen
+Switch to Previous Desktop=none,,Switch to Previous Desktop
+Switch to Previous Screen=none,,Switch to Previous Screen
+Switch to Screen 0=none,,Switch to Screen 0
+Switch to Screen 1=none,,Switch to Screen 1
+Switch to Screen 2=none,,Switch to Screen 2
+Switch to Screen 3=none,,Switch to Screen 3
+Switch to Screen 4=none,,Switch to Screen 4
+Switch to Screen 5=none,,Switch to Screen 5
+Switch to Screen 6=none,,Switch to Screen 6
+Switch to Screen 7=none,,Switch to Screen 7
+Switch to Screen Above=none,,Switch to Screen Above
+Switch to Screen Below=none,,Switch to Screen Below
+Switch to Screen to the Left=none,,Switch to Screen to the Left
+Switch to Screen to the Right=none,,Switch to Screen to the Right
+Toggle Night Color=none,none,Toggle Night Color
+Toggle Window Raise/Lower=none,,Toggle Window Raise/Lower
+Walk Through Desktop List=none,,Walk Through Desktop List
+Walk Through Desktop List (Reverse)=none,,Walk Through Desktop List (Reverse)
+Walk Through Desktops=none,,Walk Through Desktops
+Walk Through Desktops (Reverse)=none,,Walk Through Desktops (Reverse)
+Walk Through Windows=Alt+Tab,Alt+Tab,Walk Through Windows
+Walk Through Windows (Reverse)=Alt+Shift+Backtab,Alt+Shift+Backtab,Walk Through Windows (Reverse)
+Walk Through Windows Alternative=none,,Walk Through Windows Alternative
+Walk Through Windows Alternative (Reverse)=none,,Walk Through Windows Alternative (Reverse)
+Walk Through Windows of Current Application=Alt+`,Alt+`,Walk Through Windows of Current Application
+Walk Through Windows of Current Application (Reverse)=Alt+~,Alt+~,Walk Through Windows of Current Application (Reverse)
+Walk Through Windows of Current Application Alternative=none,,Walk Through Windows of Current Application Alternative
+Walk Through Windows of Current Application Alternative (Reverse)=none,,Walk Through Windows of Current Application Alternative (Reverse)
+Window Above Other Windows=none,,Keep Window Above Others
+Window Below Other Windows=none,,Keep Window Below Others
+Window Close=Alt+F4,Alt+F4,Close Window
+Window Fullscreen=none,,Make Window Fullscreen
+Window Grow Horizontal=none,,Expand Window Horizontally
+Window Grow Vertical=none,,Expand Window Vertically
+Window Lower=none,,Lower Window
+Window Maximize=Meta+PgUp,Meta+PgUp,Maximize Window
+Window Maximize Horizontal=none,,Maximize Window Horizontally
+Window Maximize Vertical=none,,Maximize Window Vertically
+Window Minimize=Meta+PgDown,Meta+PgDown,Minimize Window
+Window Move=none,,Move Window
+Window Move Center=none,,Move Window to the Center
+Window No Border=none,,Toggle Window Titlebar and Frame
+Window On All Desktops=none,,Keep Window on All Desktops
+Window One Desktop Down=Meta+Ctrl+Shift+Down,Meta+Ctrl+Shift+Down,Window One Desktop Down
+Window One Desktop Up=Meta+Ctrl+Shift+Up,Meta+Ctrl+Shift+Up,Window One Desktop Up
+Window One Desktop to the Left=Meta+Ctrl+Shift+Left,Meta+Ctrl+Shift+Left,Window One Desktop to the Left
+Window One Desktop to the Right=Meta+Ctrl+Shift+Right,Meta+Ctrl+Shift+Right,Window One Desktop to the Right
+Window One Screen Down=none,,Window One Screen Down
+Window One Screen Up=none,,Window One Screen Up
+Window One Screen to the Left=none,,Window One Screen to the Left
+Window One Screen to the Right=none,,Window One Screen to the Right
+Window Operations Menu=Alt+F3,Alt+F3,Window Operations Menu
+Window Pack Down=none,,Move Window Down
+Window Pack Left=none,,Move Window Left
+Window Pack Right=none,,Move Window Right
+Window Pack Up=none,,Move Window Up
+Window Quick Tile Bottom=Meta+Down,Meta+Down,Quick Tile Window to the Bottom
+Window Quick Tile Bottom Left=none,,Quick Tile Window to the Bottom Left
+Window Quick Tile Bottom Right=none,,Quick Tile Window to the Bottom Right
+Window Quick Tile Left=Meta+Left,Meta+Left,Quick Tile Window to the Left
+Window Quick Tile Right=Meta+Right,Meta+Right,Quick Tile Window to the Right
+Window Quick Tile Top=Meta+Up,Meta+Up,Quick Tile Window to the Top
+Window Quick Tile Top Left=none,,Quick Tile Window to the Top Left
+Window Quick Tile Top Right=none,,Quick Tile Window to the Top Right
+Window Raise=none,,Raise Window
+Window Resize=none,,Resize Window
+Window Shade=none,,Shade Window
+Window Shrink Horizontal=none,,Shrink Window Horizontally
+Window Shrink Vertical=none,,Shrink Window Vertically
+Window to Desktop 1=none,,Window to Desktop 1
+Window to Desktop 10=none,,Window to Desktop 10
+Window to Desktop 11=none,,Window to Desktop 11
+Window to Desktop 12=none,,Window to Desktop 12
+Window to Desktop 13=none,,Window to Desktop 13
+Window to Desktop 14=none,,Window to Desktop 14
+Window to Desktop 15=none,,Window to Desktop 15
+Window to Desktop 16=none,,Window to Desktop 16
+Window to Desktop 17=none,,Window to Desktop 17
+Window to Desktop 18=none,,Window to Desktop 18
+Window to Desktop 19=none,,Window to Desktop 19
+Window to Desktop 2=none,,Window to Desktop 2
+Window to Desktop 20=none,,Window to Desktop 20
+Window to Desktop 3=none,,Window to Desktop 3
+Window to Desktop 4=none,,Window to Desktop 4
+Window to Desktop 5=none,,Window to Desktop 5
+Window to Desktop 6=none,,Window to Desktop 6
+Window to Desktop 7=none,,Window to Desktop 7
+Window to Desktop 8=none,,Window to Desktop 8
+Window to Desktop 9=none,,Window to Desktop 9
+Window to Next Desktop=none,,Window to Next Desktop
+Window to Next Screen=Meta+Shift+Right,Meta+Shift+Right,Window to Next Screen
+Window to Previous Desktop=none,,Window to Previous Desktop
+Window to Previous Screen=Meta+Shift+Left,Meta+Shift+Left,Window to Previous Screen
+Window to Screen 0=none,,Window to Screen 0
+Window to Screen 1=none,,Window to Screen 1
+Window to Screen 2=none,,Window to Screen 2
+Window to Screen 3=none,,Window to Screen 3
+Window to Screen 4=none,,Window to Screen 4
+Window to Screen 5=none,,Window to Screen 5
+Window to Screen 6=none,,Window to Screen 6
+Window to Screen 7=none,,Window to Screen 7
+_k_friendly_name=KWin
+view_actual_size=Meta+0,Meta+0,Zoom to Actual Size
+view_zoom_in=Meta++\tMeta+=,Meta++,Zoom In
+view_zoom_out=Meta+-,Meta+-,Zoom Out
+
+[mediacontrol]
+_k_friendly_name=Media Controller
+mediavolumedown=none,none,Media volume down
+mediavolumeup=none,none,Media volume up
+nextmedia=Media Next,Media Next,Media playback next
+pausemedia=Media Pause,Media Pause,Pause media playback
+playmedia=none,none,Play media playback
+playpausemedia=Media Play,Media Play,Play/Pause media playback
+previousmedia=Media Previous,Media Previous,Media playback previous
+stopmedia=Media Stop,Media Stop,Stop media playback
+
+[org.kde.dolphin.desktop]
+_k_friendly_name=Dolphin
+_launch=Meta+E,Meta+E,Dolphin
+
+[org.kde.kcalc.desktop]
+_k_friendly_name=KCalc
+_launch=Launch (1),Launch (1),KCalc
+
+[org.kde.krunner.desktop]
+RunClipboard=Alt+Shift+F2,Alt+Shift+F2,Run command on clipboard contents
+_k_friendly_name=KRunner
+_launch=Alt+Space\tAlt+F2\tSearch,Alt+Space\tAlt+F2\tSearch,KRunner
+
+[org.kde.plasma.emojier.desktop]
+_k_friendly_name=Emoji Selector
+_launch=Meta+.\tMeta+Ctrl+Alt+Shift+Space,Meta+.\tMeta+Ctrl+Alt+Shift+Space,Emoji Selector
+
+[org.kde.spectacle.desktop]
+ActiveWindowScreenShot=Meta+Print,Meta+Print,Capture Active Window
+CurrentMonitorScreenShot=none,none,Capture Current Monitor
+FullScreenScreenShot=Shift+Print,Shift+Print,Capture Entire Desktop
+OpenWithoutScreenshot=none,none,Launch without taking a screenshot
+RectangularRegionScreenShot=Meta+Shift+Print,Meta+Shift+Print,Capture Rectangular Region
+WindowUnderCursorScreenShot=Meta+Ctrl+Print,Meta+Ctrl+Print,Capture Window Under Cursor
+_k_friendly_name=Spectacle
+_launch=Print,Print,Spectacle
+
+[org_kde_powerdevil]
+Decrease Keyboard Brightness=Keyboard Brightness Down,Keyboard Brightness Down,Decrease Keyboard Brightness
+Decrease Screen Brightness=Monitor Brightness Down,Monitor Brightness Down,Decrease Screen Brightness
+Hibernate=Hibernate,Hibernate,Hibernate
+Increase Keyboard Brightness=Keyboard Brightness Up,Keyboard Brightness Up,Increase Keyboard Brightness
+Increase Screen Brightness=Monitor Brightness Up,Monitor Brightness Up,Increase Screen Brightness
+PowerDown=Power Down,Power Down,Power Down
+PowerOff=Power Off,Power Off,Power Off
+Sleep=Sleep,Sleep,Suspend
+Toggle Keyboard Backlight=Keyboard Light On/Off,Keyboard Light On/Off,Toggle Keyboard Backlight
+Turn Off Screen=none,none,Turn Off Screen
+_k_friendly_name=Power Management
+
+[plasmashell]
+_k_friendly_name=Plasma
+activate task manager entry 1=Meta+1,Meta+1,Activate Task Manager Entry 1
+activate task manager entry 10=none,Meta+0,Activate Task Manager Entry 10
+activate task manager entry 2=Meta+2,Meta+2,Activate Task Manager Entry 2
+activate task manager entry 3=Meta+3,Meta+3,Activate Task Manager Entry 3
+activate task manager entry 4=Meta+4,Meta+4,Activate Task Manager Entry 4
+activate task manager entry 5=Meta+5,Meta+5,Activate Task Manager Entry 5
+activate task manager entry 6=Meta+6,Meta+6,Activate Task Manager Entry 6
+activate task manager entry 7=Meta+7,Meta+7,Activate Task Manager Entry 7
+activate task manager entry 8=Meta+8,Meta+8,Activate Task Manager Entry 8
+activate task manager entry 9=Meta+9,Meta+9,Activate Task Manager Entry 9
+activate widget 3=Alt+F1,none,Activate Application Launcher Widget
+activate widget 60=none,none,Activate Simple Application Launcher Widget
+clear-history=none,,Clear Clipboard History
+clipboard_action=Meta+Ctrl+X,Meta+Ctrl+X,Automatic Action Popup Menu
+cycle-panels=Meta+Alt+P,Meta+Alt+P,Move keyboard focus between panels
+cycleNextAction=none,,Next History Item
+cyclePrevAction=none,,Previous History Item
+edit_clipboard=none,,Edit Contents…
+manage activities=Meta+Q,Meta+Q,Show Activity Switcher
+next activity=Meta+Tab,Meta+Tab,Walk through activities
+previous activity=Meta+Shift+Tab,Meta+Shift+Tab,Walk through activities (Reverse)
+repeat_action=Meta+Ctrl+R,Meta+Ctrl+R,Manually Invoke Action on Current Clipboard
+show dashboard=Ctrl+F12,Ctrl+F12,Show Desktop
+show-barcode=none,,Show Barcode…
+show-on-mouse-pos=Meta+V,Meta+V,Show Items at Mouse Position
+stop current activity=Meta+S,Meta+S,Stop Current Activity
+switch to next activity=none,,Switch to Next Activity
+switch to previous activity=none,,Switch to Previous Activity
+toggle do not disturb=none,,Toggle do not disturb
+
+[systemsettings.desktop]
+_k_friendly_name=System Settings
+_launch=Tools,Tools,System Settings
+kcm-kscreen=none,none,Display Configuration
+kcm-lookandfeel=none,none,Global Theme
+kcm-users=none,none,Users
+powerdevilprofilesconfig=none,none,Energy Saving
+screenlocker=none,none,Screen Locking
diff --git a/.config/khotkeysrc b/.config/konsave/profiles/laptop-kde/configs/khotkeysrc
similarity index 99%
rename from .config/khotkeysrc
rename to .config/konsave/profiles/laptop-kde/configs/khotkeysrc
index f5ff6d0..9d634e7 100644
--- a/.config/khotkeysrc
+++ b/.config/konsave/profiles/laptop-kde/configs/khotkeysrc
@@ -1001,6 +1001,8 @@ History Items[$d]
BrowserApplication[$d]
ColorScheme[$d]
ColorSchemeHash[$d]
+TerminalApplication[$d]
+TerminalService[$d]
XftAntialias[$d]
XftHintStyle[$d]
XftSubPixel[$d]
diff --git a/.config/konsave/profiles/laptop-kde/configs/konsolerc b/.config/konsave/profiles/laptop-kde/configs/konsolerc
new file mode 100644
index 0000000..55a95f9
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/konsolerc
@@ -0,0 +1,18 @@
+[General]
+ConfigVersion=1
+
+[MainWindow]
+1280x800 screen: Height=554
+1280x800 screen: Width=911
+1280x800 screen: Window-Maximized=true
+1600x1000 screen: Window-Maximized=true
+1920x1200 screen: Height=554
+1920x1200 screen: Width=911
+1920x1200 screen: XPosition=550
+1920x1200 screen: YPosition=386
+State=AAAA/wAAAAD9AAAAAQAAAAAAAAAAAAAAAPwCAAAAAvsAAAAiAFEAdQBpAGMAawBDAG8AbQBtAGEAbgBkAHMARABvAGMAawAAAAAA/////wAAAX4BAAAF+wAAABwAUwBTAEgATQBhAG4AYQBnAGUAcgBEAG8AYwBrAAAAAAD/////AAABGwEAAAUAAAOPAAAB4gAAAAQAAAAEAAAACAAAAAj8AAAAAQAAAAIAAAACAAAAFgBtAGEAaQBuAFQAbwBvAGwAQgBhAHIBAAAAAP////8AAAAAAAAAAAAAABwAcwBlAHMAcwBpAG8AbgBUAG8AbwBsAGIAYQByAQAAAOz/////AAAAAAAAAAA=
+ToolBarsMovable=Disabled
+eDP-1=eDP-1
+
+[UiSettings]
+ColorScheme=
diff --git a/.config/konsave/profiles/laptop-kde/configs/krunnerrc b/.config/konsave/profiles/laptop-kde/configs/krunnerrc
new file mode 100644
index 0000000..c36d549
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/krunnerrc
@@ -0,0 +1,2 @@
+[PlasmaRunnerManager]
+migrated=true
diff --git a/.config/konsave/profiles/laptop-kde/configs/kscreenlockerrc b/.config/konsave/profiles/laptop-kde/configs/kscreenlockerrc
new file mode 100644
index 0000000..6a7ebfb
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/kscreenlockerrc
@@ -0,0 +1,5 @@
+[$Version]
+update_info=kscreenlocker.upd:0.1-autolock
+
+[Daemon]
+Autolock=false
diff --git a/.config/konsave/profiles/laptop-kde/configs/ksmserverrc b/.config/konsave/profiles/laptop-kde/configs/ksmserverrc
new file mode 100644
index 0000000..09d58cb
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/ksmserverrc
@@ -0,0 +1,53 @@
+[$Version]
+update_info=ksmserver_update_loginMode_value.upd:ksmserver_update_loginMode_value_default_enum
+
+[LegacySession: saved at previous logout]
+clientMachine1=localhost
+command1=syncthing-gtk
+count=1
+
+[Session: saved at previous logout]
+clientId1=10d9d3726d000175557677900000416870004
+clientId2=10d9d3726d000175557677900000416870008
+clientId3=10d9d3726d000175557678000000416870011
+clientId4=10d9d3726d000175557938000000416870028
+clientId5=10d9d3726d000175570185100000416870036
+clientId6=10d9d3726d000175570255400000416870037
+clientId7=10d9d3726d000175570573500000416870040
+clientId8=10d9d3726d000175570663600000416870042
+count=8
+discardCommand5[$e]=rm,$HOME/.config/session/dolphin_10d9d3726d000175570185100000416870036_1755710195_622051
+discardCommand6[$e]=rm,$HOME/.config/session/dolphin_10d9d3726d000175570255400000416870037_1755710195_621794
+discardCommand7[$e]=rm,$HOME/.config/session/dolphin_10d9d3726d000175570573500000416870040_1755710195_621972
+program1=/usr/bin/flameshot
+program2=/usr/bin/keepassxc
+program3=/usr/bin/kalendarac
+program4=firefox
+program5=/usr/bin/dolphin
+program6=/usr/bin/dolphin
+program7=dolphin
+program8=/usr/bin/kdeconnect-app
+restartCommand1=/usr/bin/flameshot,-session,10d9d3726d000175557677900000416870004_1755710195_621549
+restartCommand2=/usr/bin/keepassxc,-session,10d9d3726d000175557677900000416870008_1755710195_621559
+restartCommand3=/usr/bin/kalendarac,-session,10d9d3726d000175557678000000416870011_1755710195_621587
+restartCommand4=/usr/lib/firefox-esr/firefox-esr,--sm-client-id,10d9d3726d000175557938000000416870028
+restartCommand5=/usr/bin/dolphin,-session,10d9d3726d000175570185100000416870036_1755710195_622051
+restartCommand6=/usr/bin/dolphin,-session,10d9d3726d000175570255400000416870037_1755710195_621794
+restartCommand7=dolphin,-session,10d9d3726d000175570573500000416870040_1755710195_621972
+restartCommand8=/usr/bin/kdeconnect-app,-session,10d9d3726d000175570663600000416870042_1755710195_621791
+restartStyleHint1=0
+restartStyleHint2=0
+restartStyleHint3=0
+restartStyleHint4=0
+restartStyleHint5=0
+restartStyleHint6=0
+restartStyleHint7=0
+restartStyleHint8=0
+userId1=melissa
+userId2=melissa
+userId3=melissa
+userId4=melissa
+userId5=melissa
+userId6=melissa
+userId7=melissa
+userId8=melissa
diff --git a/.config/konsave/profiles/laptop-kde/configs/kwinrc b/.config/konsave/profiles/laptop-kde/configs/kwinrc
new file mode 100644
index 0000000..2ee5184
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/kwinrc
@@ -0,0 +1,23 @@
+[$Version]
+update_info=kwin.upd:replace-scalein-with-scale,kwin.upd:port-minimizeanimation-effect-to-js,kwin.upd:port-scale-effect-to-js,kwin.upd:port-dimscreen-effect-to-js,kwin.upd:auto-bordersize,kwin.upd:animation-speed,kwin.upd:desktop-grid-click-behavior,kwin.upd:no-swap-encourage,kwin.upd:make-translucency-effect-disabled-by-default,kwin.upd:remove-flip-switch-effect,kwin.upd:remove-cover-switch-effect,kwin.upd:remove-cubeslide-effect,kwin.upd:remove-xrender-backend,kwin.upd:enable-scale-effect-by-default,kwin.upd:overview-group-plugin-id,kwin.upd:animation-speed-cleanup,kwin.upd:replace-cascaded-zerocornered
+
+[Desktops]
+Id_1=c3fcb1e0-89f0-4cb5-b1dd-eb8917bc6a90
+Number=1
+Rows=1
+
+[Tiling]
+padding=4
+
+[Tiling][0705bead-31eb-53e0-b8c3-09b36b77be96]
+tiles={"layoutDirection":"horizontal","tiles":[{"width":0.5},{"width":0.5}]}
+
+[Tiling][99727b82-4770-57e2-8782-7bcade40496d]
+tiles={"layoutDirection":"horizontal","tiles":[{"width":0.25},{"width":0.5},{"width":0.25}]}
+
+[Wayland]
+InputMethod[$e]=/usr/share/applications/com.github.maliit.keyboard.desktop
+VirtualKeyboardEnabled=false
+
+[Xwayland]
+Scale=1.2
diff --git a/.config/konsave/profiles/laptop-kde/configs/kwinrulesrc b/.config/konsave/profiles/laptop-kde/configs/kwinrulesrc
new file mode 100644
index 0000000..a65d21f
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/kwinrulesrc
@@ -0,0 +1,2 @@
+[$Version]
+update_info=kwinrules.upd:replace-placement-string-to-enum,kwinrules.upd:use-virtual-desktop-ids
diff --git a/.config/konsave/profiles/laptop-kde/configs/plasma-org.kde.plasma.desktop-appletsrc b/.config/konsave/profiles/laptop-kde/configs/plasma-org.kde.plasma.desktop-appletsrc
new file mode 100644
index 0000000..43a0f4e
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/plasma-org.kde.plasma.desktop-appletsrc
@@ -0,0 +1,310 @@
+[ActionPlugins][0]
+MiddleButton;NoModifier=org.kde.paste
+RightButton;NoModifier=org.kde.contextmenu
+wheel:Vertical;NoModifier=org.kde.switchdesktop
+
+[ActionPlugins][1]
+RightButton;NoModifier=org.kde.contextmenu
+
+[Containments][31]
+activityId=
+formfactor=2
+immutability=1
+lastScreen=0
+location=4
+plugin=org.kde.panel
+wallpaperplugin=org.kde.image
+
+[Containments][31][Applets][34]
+immutability=1
+plugin=org.kde.plasma.panelspacer
+
+[Containments][31][Applets][34][Configuration]
+PreloadWeight=42
+immutability=1
+
+[Containments][31][Applets][34][Configuration][Configuration]
+PreloadWeight=0
+
+[Containments][31][Applets][34][Configuration][Configuration][General]
+length=1108
+
+[Containments][31][Applets][34][Configuration][General]
+length=1108
+
+[Containments][31][Applets][35]
+immutability=1
+plugin=org.kde.plasma.systemtray
+
+[Containments][31][Applets][35][Configuration]
+PreloadWeight=100
+SystrayContainmentId=36
+immutability=1
+
+[Containments][31][Applets][35][Configuration][Configuration]
+PreloadWeight=0
+
+[Containments][31][Applets][48]
+immutability=1
+plugin=org.kde.plasma.digitalclock
+
+[Containments][31][Applets][48][Configuration]
+PreloadWeight=70
+immutability=1
+popupHeight=550
+popupWidth=484
+
+[Containments][31][Applets][48][Configuration][Configuration]
+PreloadWeight=0
+
+[Containments][31][Applets][53]
+immutability=1
+plugin=org.kde.plasma.showActivityManager
+
+[Containments][31][Applets][53][Configuration][ConfigDialog]
+DialogHeight=660
+DialogWidth=880
+
+[Containments][31][Applets][53][Configuration][General]
+showActivityName=false
+
+[Containments][31][Applets][58]
+immutability=1
+plugin=org.kde.plasma.icontasks
+
+[Containments][31][Applets][58][Configuration][ConfigDialog]
+DialogHeight=660
+DialogWidth=880
+
+[Containments][31][Applets][58][Configuration][General]
+launchers=[b8cde0cc-78c3-4951-962c-b2fc6e340ff6]\napplications:firefox-esr.desktop,applications:systemsettings.desktop,[b8cde0cc-78c3-4951-962c-b2fc6e340ff6]\napplications:alacritty-AM.desktop,preferred://filemanager
+
+[Containments][31][Applets][60]
+immutability=1
+plugin=org.kde.plasma.simplekickoff
+
+[Containments][31][Applets][60][Configuration]
+PreloadWeight=100
+immutability=1
+popupHeight=570
+popupWidth=729
+
+[Containments][31][Applets][60][Configuration][ConfigDialog]
+DialogHeight=660
+DialogWidth=880
+
+[Containments][31][Applets][60][Configuration][Configuration]
+PreloadWeight=100
+
+[Containments][31][Applets][60][Configuration][Configuration][ConfigDialog]
+DialogHeight=480
+DialogWidth=640
+
+[Containments][31][Applets][60][Configuration][Configuration][General]
+favoritesPortedToKAstats=true
+icon=start-here
+
+[Containments][31][Applets][60][Configuration][General]
+favoritesPortedToKAstats=true
+icon=pop-cosmic-applications
+systemFavorites=suspend\\,hibernate\\,reboot\\,shutdown
+
+[Containments][31][Applets][60][Configuration][Shortcuts]
+global=Alt+F1
+
+[Containments][31][Applets][77]
+immutability=1
+plugin=org.kde.resourcesMonitor-fork
+
+[Containments][31][Applets][77][Configuration][Appearance]
+fontScale=30
+graphFillOpacity=100
+graphHeight=1
+graphWidth=1
+
+[Containments][31][Applets][77][Configuration][ConfigDialog]
+DialogHeight=660
+DialogWidth=880
+
+[Containments][31][Applets][77][Configuration][General]
+gpuMemoryInPercent=true
+memorySecondUnit=swap-percent
+memoryUnit=physical-percent
+networkUnit=kilobit
+showClock=false
+showCpuTemperature=true
+showDiskMonitor=true
+showGpuTemperature=true
+showNetMonitor=true
+
+[Containments][31][ConfigDialog]
+DialogHeight=93
+DialogWidth=1920
+
+[Containments][31][Configuration]
+PreloadWeight=0
+
+[Containments][31][General]
+AppletOrder=60;53;58;34;77;35;48
+
+[Containments][36]
+activityId=
+formfactor=2
+immutability=1
+lastScreen=0
+location=4
+plugin=org.kde.plasma.private.systemtray
+popupHeight=528
+popupWidth=528
+wallpaperplugin=org.kde.image
+
+[Containments][36][Applets][37]
+immutability=1
+plugin=org.kde.plasma.devicenotifier
+
+[Containments][36][Applets][37][Configuration]
+PreloadWeight=55
+
+[Containments][36][Applets][38]
+immutability=1
+plugin=org.kde.plasma.manage-inputmethod
+
+[Containments][36][Applets][39]
+immutability=1
+plugin=org.kde.plasma.keyboardlayout
+
+[Containments][36][Applets][40]
+immutability=1
+plugin=org.kde.kdeconnect
+
+[Containments][36][Applets][41]
+immutability=1
+plugin=org.kde.kscreen
+
+[Containments][36][Applets][41][Configuration]
+PreloadWeight=55
+
+[Containments][36][Applets][42]
+immutability=1
+plugin=org.kde.plasma.printmanager
+
+[Containments][36][Applets][43]
+immutability=1
+plugin=org.kde.plasma.volume
+
+[Containments][36][Applets][43][Configuration][General]
+migrated=true
+
+[Containments][36][Applets][44]
+immutability=1
+plugin=org.kde.plasma.keyboardindicator
+
+[Containments][36][Applets][45]
+immutability=1
+plugin=org.kde.plasma.clipboard
+
+[Containments][36][Applets][46]
+immutability=1
+plugin=org.kde.plasma.notifications
+
+[Containments][36][Applets][46][Configuration]
+PreloadWeight=60
+
+[Containments][36][Applets][47]
+immutability=1
+plugin=org.kde.plasma.vault
+
+[Containments][36][Applets][49]
+immutability=1
+plugin=org.kde.plasma.nightcolorcontrol
+
+[Containments][36][Applets][50]
+immutability=1
+plugin=org.kde.plasma.battery
+
+[Containments][36][Applets][50][Configuration]
+PreloadWeight=95
+
+[Containments][36][Applets][51]
+immutability=1
+plugin=org.kde.plasma.networkmanagement
+
+[Containments][36][Applets][51][Configuration]
+PreloadWeight=100
+
+[Containments][36][Applets][52]
+immutability=1
+plugin=org.kde.plasma.bluetooth
+
+[Containments][36][Applets][52][Configuration]
+PreloadWeight=65
+
+[Containments][36][Applets][79]
+immutability=1
+plugin=org.kde.plasma.mediacontroller
+
+[Containments][36][ConfigDialog]
+DialogHeight=660
+DialogWidth=880
+
+[Containments][36][General]
+extraItems=org.kde.plasma.battery,org.kde.plasma.devicenotifier,org.kde.plasma.manage-inputmethod,org.kde.plasma.nightcolorcontrol,org.kde.plasma.keyboardlayout,org.kde.kdeconnect,org.kde.kupapplet,org.kde.kscreen,org.kde.plasma.printmanager,org.kde.plasma.volume,org.kde.plasma.networkmanagement,org.kde.plasma.bluetooth,org.kde.plasma.keyboardindicator,org.kde.plasma.mediacontroller,org.kde.plasma.clipboard,org.kde.plasma.notifications,org.kde.plasma.vault
+knownItems=org.kde.plasma.battery,org.kde.plasma.devicenotifier,org.kde.plasma.manage-inputmethod,org.kde.plasma.nightcolorcontrol,org.kde.plasma.keyboardlayout,org.kde.kdeconnect,org.kde.kupapplet,org.kde.kscreen,org.kde.plasma.printmanager,org.kde.plasma.volume,org.kde.plasma.networkmanagement,org.kde.plasma.bluetooth,org.kde.plasma.keyboardindicator,org.kde.plasma.mediacontroller,org.kde.plasma.clipboard,org.kde.plasma.notifications,org.kde.plasma.vault
+
+[Containments][62]
+activityId=09e50951-6a17-4dca-8490-891d4b1f1a7b
+formfactor=0
+immutability=1
+lastScreen=0
+location=0
+plugin=org.kde.plasma.folder
+wallpaperplugin=org.kde.image
+
+[Containments][78]
+ItemGeometries-1920x1200=
+ItemGeometriesHorizontal=
+activityId=b8cde0cc-78c3-4951-962c-b2fc6e340ff6
+formfactor=0
+immutability=1
+lastScreen=0
+location=0
+plugin=org.kde.desktopcontainment
+wallpaperplugin=org.kde.plasma.citygrow
+
+[Containments][78][ConfigDialog]
+DialogHeight=660
+DialogWidth=880
+
+[Containments][78][General]
+ToolBoxButtonState=topcenter
+ToolBoxButtonX=508
+
+[Containments][78][Wallpaper][org.kde.image][General]
+Image=/home/melissa/.local/share/wallpapers/Sweet-Wallpapers/Sweet-space.png
+SlidePaths=/home/melissa/.local/share/wallpapers/,/usr/share/wallpapers/
+
+[Containments][80]
+ItemGeometries-0x0=
+ItemGeometriesVertical=
+activityId=9763face-6a83-4162-9250-00df5eadcbe6
+formfactor=0
+immutability=1
+lastScreen=0
+location=0
+plugin=org.kde.desktopcontainment
+wallpaperplugin=org.kde.plasma.citygrow
+
+[Containments][80][ConfigDialog]
+DialogHeight=660
+DialogWidth=880
+
+[Containments][80][Configuration]
+PreloadWeight=0
+
+[Containments][80][General]
+ToolBoxButtonState=topcenter
+ToolBoxButtonX=377
+
+[ScreenMapping]
+itemsOnDisabledScreens=0,b8cde0cc-78c3-4951-962c-b2fc6e340ff6,1,desktop:/steam.desktop
+screenMapping=
diff --git a/.config/konsave/profiles/laptop-kde/configs/plasmarc b/.config/konsave/profiles/laptop-kde/configs/plasmarc
new file mode 100644
index 0000000..5650146
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/plasmarc
@@ -0,0 +1,2 @@
+[Wallpapers]
+usersWallpapers=
diff --git a/.config/konsave/profiles/laptop-kde/configs/plasmashellrc b/.config/konsave/profiles/laptop-kde/configs/plasmashellrc
new file mode 100644
index 0000000..1c5e5f3
--- /dev/null
+++ b/.config/konsave/profiles/laptop-kde/configs/plasmashellrc
@@ -0,0 +1,26 @@
+[KPropertiesDialog]
+1920x1200 screen: Height=581
+1920x1200 screen: Width=496
+
+[PlasmaTransientsConfig]
+PreloadWeight=0
+
+[PlasmaViews][Panel 2][Defaults]
+thickness=44
+
+[PlasmaViews][Panel 31]
+alignment=132
+floating=0
+
+[PlasmaViews][Panel 31][Defaults]
+maxLength=1920
+minLength=1920
+offset=0
+thickness=40
+
+[PlasmaViews][Panel 31][Horizontal1920]
+maxLength=1920
+minLength=1920
+
+[Updates]
+performed=/usr/share/plasma/shells/org.kde.plasma.desktop/contents/updates/systemloadviewer_systemmonitor.js,/usr/share/plasma/shells/org.kde.plasma.desktop/contents/updates/containmentactions_middlebutton.js,/usr/share/plasma/shells/org.kde.plasma.desktop/contents/updates/digitalclock_rename_timezonedisplay_key.js,/usr/share/plasma/shells/org.kde.plasma.desktop/contents/updates/move_desktop_layout_config.js,/usr/share/plasma/shells/org.kde.plasma.desktop/contents/updates/klipper_clear_config.js,/usr/share/plasma/shells/org.kde.plasma.desktop/contents/updates/maintain_existing_desktop_icon_sizes.js,/usr/share/plasma/shells/org.kde.plasma.desktop/contents/updates/digitalclock_migrate_font_settings.js,/usr/share/plasma/shells/org.kde.plasma.desktop/contents/updates/mediaframe_migrate_useBackground_setting.js,/usr/share/plasma/shells/org.kde.plasma.desktop/contents/updates/keyboardlayout_remove_shortcut.js,/usr/share/plasma/shells/org.kde.plasma.desktop/contents/updates/no_middle_click_paste_on_panels.js,/usr/share/plasma/shells/org.kde.plasma.desktop/contents/updates/unlock_widgets.js,/usr/share/plasma/shells/org.kde.plasma.desktop/contents/updates/keyboardlayout_migrateiconsetting.js
diff --git a/.config/plasmarc b/.config/plasmarc
deleted file mode 100644
index e69de29..0000000
diff --git a/.config/xsettingsd/xsettingsd.conf b/.config/xsettingsd/xsettingsd.conf
deleted file mode 100644
index fdf10ef..0000000
--- a/.config/xsettingsd/xsettingsd.conf
+++ /dev/null
@@ -1,15 +0,0 @@
-Net/SoundThemeName "ocean"
-Net/ThemeName "Breeze-Dark"
-Gdk/UnscaledDPI 113049
-Gdk/WindowScalingFactor 1
-Gtk/EnableAnimations 1
-Gtk/DecorationLayout "icon:minimize,maximize,close"
-Gtk/PrimaryButtonWarpsSlider 1
-Gtk/ToolbarStyle 3
-Gtk/MenuImages 1
-Gtk/ButtonImages 1
-Gtk/CursorThemeSize 27
-Gtk/CursorThemeName "breeze_cursors"
-Net/IconThemeName "breeze-dark"
-Gtk/FontName "Noto Sans, 10"
-
diff --git a/.zshrc b/.zshrc
index 9e5fd91..2a73a3f 100644
--- a/.zshrc
+++ b/.zshrc
@@ -121,6 +121,7 @@ path+=("$HOME/scripts")
path+=("/var/lib/flatpak/exports/share/applications")
path+=("$HOME/go/bin")
path+=("$HOME/.config/emacs/bin") # for doom
+path+=("$HOME/.dotnet")
fpath+=~/.zfunc
diff --git a/scripts/AM-INSTALLER b/scripts/AM-INSTALLER
deleted file mode 100755
index c44bea2..0000000
--- a/scripts/AM-INSTALLER
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/bin/sh
-
-set -e
-
-# Colors
-RED='\033[0;31m'; LightBlue='\033[1;34m'; Green='\033[0;32m'
-
-# For developers
-AM_BRANCH="main"
-
-# Check dependencies for this script
-_check_dependency() {
- AMDEPENDENCES="chmod chown curl grep wget"
- for dependency in $AMDEPENDENCES; do
- if ! command -v "$dependency" >/dev/null 2>&1; then
- printf "\n %b💀 ERROR! MISSING ESSENTIAL COMMAND \033[0m: %b\n\n Install the above and try again! \n\n" "${RED}" "$dependency"
- exit 1
- fi
- done
-}
-
-_check_dependency
-
-# Function to check online connections (uses github.com by default, as the database and CLI itself are stored/hosted there)
-_online_check() {
- if ! wget -q --tries=3 --timeout=10 --spider https://github.com; then
- printf "\n Installer wouldn't work offline\n\n Please check your internet connection and try again\n\n"
- exit 1
- fi
-}
-
-_online_check
-
-# INSTALL "AM" SYSTEM-WIDE
-_install_am() {
- CACHEDIR="${XDG_CACHE_HOME:-$HOME/.cache}"
- mkdir -p "$CACHEDIR" || true
- rm -f "$CACHEDIR"/INSTALL-AM.sh || true
- wget -q "https://raw.githubusercontent.com/ivan-hc/AM/$AM_BRANCH/INSTALL" -O "$CACHEDIR"/INSTALL-AM.sh && chmod a+x "$CACHEDIR"/INSTALL-AM.sh
- #cp ./INSTALL "$CACHEDIR"/INSTALL-AM.sh && chmod a+x "$CACHEDIR"/INSTALL-AM.sh # for developers
- if command -v sudo >/dev/null 2>&1; then
- SUDOCMD="sudo"
- elif command -v doas >/dev/null 2>&1; then
- SUDOCMD="doas"
- else
- echo 'ERROR: No sudo or doas found'
- exit 1
- fi
- $SUDOCMD "$CACHEDIR"/INSTALL-AM.sh && rm -f "$CACHEDIR"/INSTALL-AM.sh
-}
-
-# INSTALL "AM" LOCALLY, AS "APPMAN"
-_install_appman() {
- ZSHRC="${ZDOTDIR:-$HOME}/.zshrc"
- BINDIR="${XDG_BIN_HOME:-$HOME/.local/bin}"
- mkdir -p "$BINDIR"
- if ! echo $PATH | grep "$BINDIR" >/dev/null 2>&1; then
- echo '--------------------------------------------------------------------------'
- echo " Adding $BINDIR to PATH, you might need to"
- echo " close and reopen the terminal for this to take effect."
- if [ -e ~/.bashrc ] && ! grep 'PATH="$PATH:$BINDIR"' ~/.bashrc >/dev/null 2>&1; then
- printf '\n%s\n' 'BINDIR="${XDG_BIN_HOME:-$HOME/.local/bin}"' >> ~/.bashrc
- printf '\n%s\n' 'if ! echo $PATH | grep "$BINDIR" >/dev/null 2>&1; then' >> ~/.bashrc
- printf ' export PATH="$PATH:$BINDIR"\nfi\n' >> ~/.bashrc
- fi
- if [ -e "$ZSHRC" ] && ! grep 'PATH="$PATH:$BINDIR"' "$ZSHRC" >/dev/null 2>&1; then
- printf '\n%s\n' 'BINDIR="${XDG_BIN_HOME:-$HOME/.local/bin}"' >> "$ZSHRC"
- printf '\n%s\n' 'if ! echo $PATH | grep "$BINDIR" >/dev/null 2>&1; then' >> "$ZSHRC"
- printf ' export PATH="$PATH:$BINDIR"\nfi\n' >> "$ZSHRC"
- fi
- fi
- wget -q "https://raw.githubusercontent.com/ivan-hc/AM/$AM_BRANCH/APP-MANAGER" -O "$BINDIR"/appman && chmod a+x "$BINDIR"/appman
-}
-
-# CHOOSE BETWEEN "AM" AND "APPMAN"
-printf " Choose how to install \"AM\" and all its managed applications.
-
- 1) As \"${RED}AM\033[0m\", command \"${Green}am\033[0m\", this is a system-wide installation:
- - the command is a symlink /usr/local/bin/am for /opt/am/APP-MANAGER
- - install and manage both system (default, require \"root\") and local apps
- - choose wherever you want to install local apps
- - you are the one with read-write permissions for \"AM\" and system programs
- - other users can only use programs you have installed, nothing else
- - other users can still use \"AppMan mode\" for their rootless configurations
-
- 2) As \"${LightBlue}AppMan\033[0m\", command \"${Green}appman\033[0m\", local installation:
- - the command is the script ~/.local/bin/appman
- - install and manage only local apps
- - choose wherever you want to install local apps
- - you can replicate your configurations on every system you want
- - more storage space required, if more users use \"AppMan\"
-
-"
-read -r -p "Choose between \"AM\" (type 1) and \"AppMan\" (2), or leave blank to exit: " response
-case "$response" in
- 1) _install_am || exit 1
- ;;
- 2) _install_appman || exit 1
- echo '--------------------------------------------------------------------------'
- printf " ${Green}\"AppMan\" has been successfully installed!\033[0m\n"
- printf " Please, run \"${LightBlue}appman -h\033[0m\" to see the list of the options.\n"
- echo '--------------------------------------------------------------------------'
- ;;
- ''|*) echo "Installation aborted, exiting." && exit 1
- ;;
-esac
diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh
index fbbea51..22ae2bf 100755
--- a/scripts/bootstrap.sh
+++ b/scripts/bootstrap.sh
@@ -24,7 +24,7 @@ echo "deb [signed-by=/usr/share/keyrings/mullvad-keyring.asc arch=$( dpkg --prin
sudo apt update && sudo apt upgrade -y
# apt
-sudo apt install -y autorandr i3 polybar lightdm-gtk-greeter lightdm flatpak yadm git python3 pipx alacritty i3lock-fancy network-manager-applet rofi dunst htop wget keepassxc-full net-tools vim mullvad-vpn flameshot caffeine pasystray tmux plasma-discover-backend-flatpak zsh autorandr kdeconnect fwupd numlockx neofetch
+sudo apt install -y autorandr i3 polybar lightdm-gtk-greeter lightdm flatpak yadm git python3 pipx alacritty i3lock-fancy nm-tray rofi dunst htop wget keepassxc net-tools vim mullvad-vpn flameshot caffeine pasystray tmux plasma-discover-backend-flatpak zsh autorandr kdeconnect fwupd numlockx neofetch vim emacs
# chsh
chsh melissa -s /bin/zsh
@@ -39,7 +39,7 @@ yadm submodule update --init --recursive
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
# flatpak installs
-flatpak install com.discordapp.Discord com.spotify.Client me.kozec.syncthingtk org.jitsi.jitsi-meet org.signal.Signal org.telegram.desktop us.zoom.Zoom
+flatpak install co.discordapp.Discord com.spotify.Client me.kozec.syncthingtk org.jitsi.jitsi-meet org.signal.Signal org.telegram.desktop us.zoom.Zoom
# am
wget -q https://raw.githubusercontent.com/ivan-hc/AM/main/AM-INSTALLER && chmod a+x ./AM-INSTALLER && ./AM-INSTALLER && rm ./AM-INSTALLER
@@ -50,6 +50,8 @@ wget -q https://raw.githubusercontent.com/ivan-hc/AM/main/AM-INSTALLER && chmod
# rustup default stable
# cargo install cargo-update
+# include dotnet
+
# pipx
pipx install topgrade termdown
diff --git a/scripts/dotnet-install.sh b/scripts/dotnet-install.sh
new file mode 100755
index 0000000..034d2df
--- /dev/null
+++ b/scripts/dotnet-install.sh
@@ -0,0 +1,1888 @@
+#!/usr/bin/env bash
+# Copyright (c) .NET Foundation and contributors. All rights reserved.
+# Licensed under the MIT license. See LICENSE file in the project root for full license information.
+#
+
+# Stop script on NZEC
+set -e
+# Stop script if unbound variable found (use ${var:-} if intentional)
+set -u
+# By default cmd1 | cmd2 returns exit code of cmd2 regardless of cmd1 success
+# This is causing it to fail
+set -o pipefail
+
+# Use in the the functions: eval $invocation
+invocation='say_verbose "Calling: ${yellow:-}${FUNCNAME[0]} ${green:-}$*${normal:-}"'
+
+# standard output may be used as a return value in the functions
+# we need a way to write text on the screen in the functions so that
+# it won't interfere with the return value.
+# Exposing stream 3 as a pipe to standard output of the script itself
+exec 3>&1
+
+# Setup some colors to use. These need to work in fairly limited shells, like the Ubuntu Docker container where there are only 8 colors.
+# See if stdout is a terminal
+if [ -t 1 ] && command -v tput > /dev/null; then
+ # see if it supports colors
+ ncolors=$(tput colors || echo 0)
+ if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
+ bold="$(tput bold || echo)"
+ normal="$(tput sgr0 || echo)"
+ black="$(tput setaf 0 || echo)"
+ red="$(tput setaf 1 || echo)"
+ green="$(tput setaf 2 || echo)"
+ yellow="$(tput setaf 3 || echo)"
+ blue="$(tput setaf 4 || echo)"
+ magenta="$(tput setaf 5 || echo)"
+ cyan="$(tput setaf 6 || echo)"
+ white="$(tput setaf 7 || echo)"
+ fi
+fi
+
+say_warning() {
+ printf "%b\n" "${yellow:-}dotnet_install: Warning: $1${normal:-}" >&3
+}
+
+say_err() {
+ printf "%b\n" "${red:-}dotnet_install: Error: $1${normal:-}" >&2
+}
+
+say() {
+ # using stream 3 (defined in the beginning) to not interfere with stdout of functions
+ # which may be used as return value
+ printf "%b\n" "${cyan:-}dotnet-install:${normal:-} $1" >&3
+}
+
+say_verbose() {
+ if [ "$verbose" = true ]; then
+ say "$1"
+ fi
+}
+
+# This platform list is finite - if the SDK/Runtime has supported Linux distribution-specific assets,
+# then and only then should the Linux distribution appear in this list.
+# Adding a Linux distribution to this list does not imply distribution-specific support.
+get_legacy_os_name_from_platform() {
+ eval $invocation
+
+ platform="$1"
+ case "$platform" in
+ "centos.7")
+ echo "centos"
+ return 0
+ ;;
+ "debian.8")
+ echo "debian"
+ return 0
+ ;;
+ "debian.9")
+ echo "debian.9"
+ return 0
+ ;;
+ "fedora.23")
+ echo "fedora.23"
+ return 0
+ ;;
+ "fedora.24")
+ echo "fedora.24"
+ return 0
+ ;;
+ "fedora.27")
+ echo "fedora.27"
+ return 0
+ ;;
+ "fedora.28")
+ echo "fedora.28"
+ return 0
+ ;;
+ "opensuse.13.2")
+ echo "opensuse.13.2"
+ return 0
+ ;;
+ "opensuse.42.1")
+ echo "opensuse.42.1"
+ return 0
+ ;;
+ "opensuse.42.3")
+ echo "opensuse.42.3"
+ return 0
+ ;;
+ "rhel.7"*)
+ echo "rhel"
+ return 0
+ ;;
+ "ubuntu.14.04")
+ echo "ubuntu"
+ return 0
+ ;;
+ "ubuntu.16.04")
+ echo "ubuntu.16.04"
+ return 0
+ ;;
+ "ubuntu.16.10")
+ echo "ubuntu.16.10"
+ return 0
+ ;;
+ "ubuntu.18.04")
+ echo "ubuntu.18.04"
+ return 0
+ ;;
+ "alpine.3.4.3")
+ echo "alpine"
+ return 0
+ ;;
+ esac
+ return 1
+}
+
+get_legacy_os_name() {
+ eval $invocation
+
+ local uname=$(uname)
+ if [ "$uname" = "Darwin" ]; then
+ echo "osx"
+ return 0
+ elif [ -n "$runtime_id" ]; then
+ echo $(get_legacy_os_name_from_platform "${runtime_id%-*}" || echo "${runtime_id%-*}")
+ return 0
+ else
+ if [ -e /etc/os-release ]; then
+ . /etc/os-release
+ os=$(get_legacy_os_name_from_platform "$ID${VERSION_ID:+.${VERSION_ID}}" || echo "")
+ if [ -n "$os" ]; then
+ echo "$os"
+ return 0
+ fi
+ fi
+ fi
+
+ say_verbose "Distribution specific OS name and version could not be detected: UName = $uname"
+ return 1
+}
+
+get_linux_platform_name() {
+ eval $invocation
+
+ if [ -n "$runtime_id" ]; then
+ echo "${runtime_id%-*}"
+ return 0
+ else
+ if [ -e /etc/os-release ]; then
+ . /etc/os-release
+ echo "$ID${VERSION_ID:+.${VERSION_ID}}"
+ return 0
+ elif [ -e /etc/redhat-release ]; then
+ local redhatRelease=$(&1 || true) | grep -q musl
+}
+
+get_current_os_name() {
+ eval $invocation
+
+ local uname=$(uname)
+ if [ "$uname" = "Darwin" ]; then
+ echo "osx"
+ return 0
+ elif [ "$uname" = "FreeBSD" ]; then
+ echo "freebsd"
+ return 0
+ elif [ "$uname" = "Linux" ]; then
+ local linux_platform_name=""
+ linux_platform_name="$(get_linux_platform_name)" || true
+
+ if [ "$linux_platform_name" = "rhel.6" ]; then
+ echo $linux_platform_name
+ return 0
+ elif is_musl_based_distro; then
+ echo "linux-musl"
+ return 0
+ elif [ "$linux_platform_name" = "linux-musl" ]; then
+ echo "linux-musl"
+ return 0
+ else
+ echo "linux"
+ return 0
+ fi
+ fi
+
+ say_err "OS name could not be detected: UName = $uname"
+ return 1
+}
+
+machine_has() {
+ eval $invocation
+
+ command -v "$1" > /dev/null 2>&1
+ return $?
+}
+
+check_min_reqs() {
+ local hasMinimum=false
+ if machine_has "curl"; then
+ hasMinimum=true
+ elif machine_has "wget"; then
+ hasMinimum=true
+ fi
+
+ if [ "$hasMinimum" = "false" ]; then
+ say_err "curl (recommended) or wget are required to download dotnet. Install missing prerequisite to proceed."
+ return 1
+ fi
+ return 0
+}
+
+# args:
+# input - $1
+to_lowercase() {
+ #eval $invocation
+
+ echo "$1" | tr '[:upper:]' '[:lower:]'
+ return 0
+}
+
+# args:
+# input - $1
+remove_trailing_slash() {
+ #eval $invocation
+
+ local input="${1:-}"
+ echo "${input%/}"
+ return 0
+}
+
+# args:
+# input - $1
+remove_beginning_slash() {
+ #eval $invocation
+
+ local input="${1:-}"
+ echo "${input#/}"
+ return 0
+}
+
+# args:
+# root_path - $1
+# child_path - $2 - this parameter can be empty
+combine_paths() {
+ eval $invocation
+
+ # TODO: Consider making it work with any number of paths. For now:
+ if [ ! -z "${3:-}" ]; then
+ say_err "combine_paths: Function takes two parameters."
+ return 1
+ fi
+
+ local root_path="$(remove_trailing_slash "$1")"
+ local child_path="$(remove_beginning_slash "${2:-}")"
+ say_verbose "combine_paths: root_path=$root_path"
+ say_verbose "combine_paths: child_path=$child_path"
+ echo "$root_path/$child_path"
+ return 0
+}
+
+get_machine_architecture() {
+ eval $invocation
+
+ if command -v uname > /dev/null; then
+ CPUName=$(uname -m)
+ case $CPUName in
+ armv1*|armv2*|armv3*|armv4*|armv5*|armv6*)
+ echo "armv6-or-below"
+ return 0
+ ;;
+ armv*l)
+ echo "arm"
+ return 0
+ ;;
+ aarch64|arm64)
+ if [ "$(getconf LONG_BIT)" -lt 64 ]; then
+ # This is 32-bit OS running on 64-bit CPU (for example Raspberry Pi OS)
+ echo "arm"
+ return 0
+ fi
+ echo "arm64"
+ return 0
+ ;;
+ s390x)
+ echo "s390x"
+ return 0
+ ;;
+ ppc64le)
+ echo "ppc64le"
+ return 0
+ ;;
+ loongarch64)
+ echo "loongarch64"
+ return 0
+ ;;
+ riscv64)
+ echo "riscv64"
+ return 0
+ ;;
+ powerpc|ppc)
+ echo "ppc"
+ return 0
+ ;;
+ esac
+ fi
+
+ # Always default to 'x64'
+ echo "x64"
+ return 0
+}
+
+# args:
+# architecture - $1
+get_normalized_architecture_from_architecture() {
+ eval $invocation
+
+ local architecture="$(to_lowercase "$1")"
+
+ if [[ $architecture == \ ]]; then
+ machine_architecture="$(get_machine_architecture)"
+ if [[ "$machine_architecture" == "armv6-or-below" ]]; then
+ say_err "Architecture \`$machine_architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues"
+ return 1
+ fi
+
+ echo $machine_architecture
+ return 0
+ fi
+
+ case "$architecture" in
+ amd64|x64)
+ echo "x64"
+ return 0
+ ;;
+ arm)
+ echo "arm"
+ return 0
+ ;;
+ arm64)
+ echo "arm64"
+ return 0
+ ;;
+ s390x)
+ echo "s390x"
+ return 0
+ ;;
+ ppc64le)
+ echo "ppc64le"
+ return 0
+ ;;
+ loongarch64)
+ echo "loongarch64"
+ return 0
+ ;;
+ esac
+
+ say_err "Architecture \`$architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues"
+ return 1
+}
+
+# args:
+# version - $1
+# channel - $2
+# architecture - $3
+get_normalized_architecture_for_specific_sdk_version() {
+ eval $invocation
+
+ local is_version_support_arm64="$(is_arm64_supported "$1")"
+ local is_channel_support_arm64="$(is_arm64_supported "$2")"
+ local architecture="$3";
+ local osname="$(get_current_os_name)"
+
+ if [ "$osname" == "osx" ] && [ "$architecture" == "arm64" ] && { [ "$is_version_support_arm64" = false ] || [ "$is_channel_support_arm64" = false ]; }; then
+ #check if rosetta is installed
+ if [ "$(/usr/bin/pgrep oahd >/dev/null 2>&1;echo $?)" -eq 0 ]; then
+ say_verbose "Changing user architecture from '$architecture' to 'x64' because .NET SDKs prior to version 6.0 do not support arm64."
+ echo "x64"
+ return 0;
+ else
+ say_err "Architecture \`$architecture\` is not supported for .NET SDK version \`$version\`. Please install Rosetta to allow emulation of the \`$architecture\` .NET SDK on this platform"
+ return 1
+ fi
+ fi
+
+ echo "$architecture"
+ return 0
+}
+
+# args:
+# version or channel - $1
+is_arm64_supported() {
+ # Extract the major version by splitting on the dot
+ major_version="${1%%.*}"
+
+ # Check if the major version is a valid number and less than 6
+ case "$major_version" in
+ [0-9]*)
+ if [ "$major_version" -lt 6 ]; then
+ echo false
+ return 0
+ fi
+ ;;
+ esac
+
+ echo true
+ return 0
+}
+
+# args:
+# user_defined_os - $1
+get_normalized_os() {
+ eval $invocation
+
+ local osname="$(to_lowercase "$1")"
+ if [ ! -z "$osname" ]; then
+ case "$osname" in
+ osx | freebsd | rhel.6 | linux-musl | linux)
+ echo "$osname"
+ return 0
+ ;;
+ macos)
+ osname='osx'
+ echo "$osname"
+ return 0
+ ;;
+ *)
+ say_err "'$user_defined_os' is not a supported value for --os option, supported values are: osx, macos, linux, linux-musl, freebsd, rhel.6. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues."
+ return 1
+ ;;
+ esac
+ else
+ osname="$(get_current_os_name)" || return 1
+ fi
+ echo "$osname"
+ return 0
+}
+
+# args:
+# quality - $1
+get_normalized_quality() {
+ eval $invocation
+
+ local quality="$(to_lowercase "$1")"
+ if [ ! -z "$quality" ]; then
+ case "$quality" in
+ daily | preview)
+ echo "$quality"
+ return 0
+ ;;
+ ga)
+ #ga quality is available without specifying quality, so normalizing it to empty
+ return 0
+ ;;
+ *)
+ say_err "'$quality' is not a supported value for --quality option. Supported values are: daily, preview, ga. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues."
+ return 1
+ ;;
+ esac
+ fi
+ return 0
+}
+
+# args:
+# channel - $1
+get_normalized_channel() {
+ eval $invocation
+
+ local channel="$(to_lowercase "$1")"
+
+ if [[ $channel == current ]]; then
+ say_warning 'Value "Current" is deprecated for -Channel option. Use "STS" instead.'
+ fi
+
+ if [[ $channel == release/* ]]; then
+ say_warning 'Using branch name with -Channel option is no longer supported with newer releases. Use -Quality option with a channel in X.Y format instead.';
+ fi
+
+ if [ ! -z "$channel" ]; then
+ case "$channel" in
+ lts)
+ echo "LTS"
+ return 0
+ ;;
+ sts)
+ echo "STS"
+ return 0
+ ;;
+ current)
+ echo "STS"
+ return 0
+ ;;
+ *)
+ echo "$channel"
+ return 0
+ ;;
+ esac
+ fi
+
+ return 0
+}
+
+# args:
+# runtime - $1
+get_normalized_product() {
+ eval $invocation
+
+ local product=""
+ local runtime="$(to_lowercase "$1")"
+ if [[ "$runtime" == "dotnet" ]]; then
+ product="dotnet-runtime"
+ elif [[ "$runtime" == "aspnetcore" ]]; then
+ product="aspnetcore-runtime"
+ elif [ -z "$runtime" ]; then
+ product="dotnet-sdk"
+ fi
+ echo "$product"
+ return 0
+}
+
+# The version text returned from the feeds is a 1-line or 2-line string:
+# For the SDK and the dotnet runtime (2 lines):
+# Line 1: # commit_hash
+# Line 2: # 4-part version
+# For the aspnetcore runtime (1 line):
+# Line 1: # 4-part version
+
+# args:
+# version_text - stdin
+get_version_from_latestversion_file_content() {
+ eval $invocation
+
+ cat | tail -n 1 | sed 's/\r$//'
+ return 0
+}
+
+# args:
+# install_root - $1
+# relative_path_to_package - $2
+# specific_version - $3
+is_dotnet_package_installed() {
+ eval $invocation
+
+ local install_root="$1"
+ local relative_path_to_package="$2"
+ local specific_version="${3//[$'\t\r\n']}"
+
+ local dotnet_package_path="$(combine_paths "$(combine_paths "$install_root" "$relative_path_to_package")" "$specific_version")"
+ say_verbose "is_dotnet_package_installed: dotnet_package_path=$dotnet_package_path"
+
+ if [ -d "$dotnet_package_path" ]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+# args:
+# downloaded file - $1
+# remote_file_size - $2
+validate_remote_local_file_sizes()
+{
+ eval $invocation
+
+ local downloaded_file="$1"
+ local remote_file_size="$2"
+ local file_size=''
+
+ if [[ "$OSTYPE" == "linux-gnu"* ]]; then
+ file_size="$(stat -c '%s' "$downloaded_file")"
+ elif [[ "$OSTYPE" == "darwin"* ]]; then
+ # hardcode in order to avoid conflicts with GNU stat
+ file_size="$(/usr/bin/stat -f '%z' "$downloaded_file")"
+ fi
+
+ if [ -n "$file_size" ]; then
+ say "Downloaded file size is $file_size bytes."
+
+ if [ -n "$remote_file_size" ] && [ -n "$file_size" ]; then
+ if [ "$remote_file_size" -ne "$file_size" ]; then
+ say "The remote and local file sizes are not equal. The remote file size is $remote_file_size bytes and the local size is $file_size bytes. The local package may be corrupted."
+ else
+ say "The remote and local file sizes are equal."
+ fi
+ fi
+
+ else
+ say "Either downloaded or local package size can not be measured. One of them may be corrupted."
+ fi
+}
+
+# args:
+# azure_feed - $1
+# channel - $2
+# normalized_architecture - $3
+get_version_from_latestversion_file() {
+ eval $invocation
+
+ local azure_feed="$1"
+ local channel="$2"
+ local normalized_architecture="$3"
+
+ local version_file_url=null
+ if [[ "$runtime" == "dotnet" ]]; then
+ version_file_url="$azure_feed/Runtime/$channel/latest.version"
+ elif [[ "$runtime" == "aspnetcore" ]]; then
+ version_file_url="$azure_feed/aspnetcore/Runtime/$channel/latest.version"
+ elif [ -z "$runtime" ]; then
+ version_file_url="$azure_feed/Sdk/$channel/latest.version"
+ else
+ say_err "Invalid value for \$runtime"
+ return 1
+ fi
+ say_verbose "get_version_from_latestversion_file: latest url: $version_file_url"
+
+ download "$version_file_url" || return $?
+ return 0
+}
+
+# args:
+# json_file - $1
+parse_globaljson_file_for_version() {
+ eval $invocation
+
+ local json_file="$1"
+ if [ ! -f "$json_file" ]; then
+ say_err "Unable to find \`$json_file\`"
+ return 1
+ fi
+
+ sdk_section=$(cat $json_file | tr -d "\r" | awk '/"sdk"/,/}/')
+ if [ -z "$sdk_section" ]; then
+ say_err "Unable to parse the SDK node in \`$json_file\`"
+ return 1
+ fi
+
+ sdk_list=$(echo $sdk_section | awk -F"[{}]" '{print $2}')
+ sdk_list=${sdk_list//[\" ]/}
+ sdk_list=${sdk_list//,/$'\n'}
+
+ local version_info=""
+ while read -r line; do
+ IFS=:
+ while read -r key value; do
+ if [[ "$key" == "version" ]]; then
+ version_info=$value
+ fi
+ done <<< "$line"
+ done <<< "$sdk_list"
+ if [ -z "$version_info" ]; then
+ say_err "Unable to find the SDK:version node in \`$json_file\`"
+ return 1
+ fi
+
+ unset IFS;
+ echo "$version_info"
+ return 0
+}
+
+# args:
+# azure_feed - $1
+# channel - $2
+# normalized_architecture - $3
+# version - $4
+# json_file - $5
+get_specific_version_from_version() {
+ eval $invocation
+
+ local azure_feed="$1"
+ local channel="$2"
+ local normalized_architecture="$3"
+ local version="$(to_lowercase "$4")"
+ local json_file="$5"
+
+ if [ -z "$json_file" ]; then
+ if [[ "$version" == "latest" ]]; then
+ local version_info
+ version_info="$(get_version_from_latestversion_file "$azure_feed" "$channel" "$normalized_architecture" false)" || return 1
+ say_verbose "get_specific_version_from_version: version_info=$version_info"
+ echo "$version_info" | get_version_from_latestversion_file_content
+ return 0
+ else
+ echo "$version"
+ return 0
+ fi
+ else
+ local version_info
+ version_info="$(parse_globaljson_file_for_version "$json_file")" || return 1
+ echo "$version_info"
+ return 0
+ fi
+}
+
+# args:
+# azure_feed - $1
+# channel - $2
+# normalized_architecture - $3
+# specific_version - $4
+# normalized_os - $5
+construct_download_link() {
+ eval $invocation
+
+ local azure_feed="$1"
+ local channel="$2"
+ local normalized_architecture="$3"
+ local specific_version="${4//[$'\t\r\n']}"
+ local specific_product_version="$(get_specific_product_version "$1" "$4")"
+ local osname="$5"
+
+ local download_link=null
+ if [[ "$runtime" == "dotnet" ]]; then
+ download_link="$azure_feed/Runtime/$specific_version/dotnet-runtime-$specific_product_version-$osname-$normalized_architecture.tar.gz"
+ elif [[ "$runtime" == "aspnetcore" ]]; then
+ download_link="$azure_feed/aspnetcore/Runtime/$specific_version/aspnetcore-runtime-$specific_product_version-$osname-$normalized_architecture.tar.gz"
+ elif [ -z "$runtime" ]; then
+ download_link="$azure_feed/Sdk/$specific_version/dotnet-sdk-$specific_product_version-$osname-$normalized_architecture.tar.gz"
+ else
+ return 1
+ fi
+
+ echo "$download_link"
+ return 0
+}
+
+# args:
+# azure_feed - $1
+# specific_version - $2
+# download link - $3 (optional)
+get_specific_product_version() {
+ # If we find a 'productVersion.txt' at the root of any folder, we'll use its contents
+ # to resolve the version of what's in the folder, superseding the specified version.
+ # if 'productVersion.txt' is missing but download link is already available, product version will be taken from download link
+ eval $invocation
+
+ local azure_feed="$1"
+ local specific_version="${2//[$'\t\r\n']}"
+ local package_download_link=""
+ if [ $# -gt 2 ]; then
+ local package_download_link="$3"
+ fi
+ local specific_product_version=null
+
+ # Try to get the version number, using the productVersion.txt file located next to the installer file.
+ local download_links=($(get_specific_product_version_url "$azure_feed" "$specific_version" true "$package_download_link")
+ $(get_specific_product_version_url "$azure_feed" "$specific_version" false "$package_download_link"))
+
+ for download_link in "${download_links[@]}"
+ do
+ say_verbose "Checking for the existence of $download_link"
+
+ if machine_has "curl"
+ then
+ if ! specific_product_version=$(curl -s --fail "${download_link}${feed_credential}" 2>&1); then
+ continue
+ else
+ echo "${specific_product_version//[$'\t\r\n']}"
+ return 0
+ fi
+
+ elif machine_has "wget"
+ then
+ specific_product_version=$(wget -qO- "${download_link}${feed_credential}" 2>&1)
+ if [ $? = 0 ]; then
+ echo "${specific_product_version//[$'\t\r\n']}"
+ return 0
+ fi
+ fi
+ done
+
+ # Getting the version number with productVersion.txt has failed. Try parsing the download link for a version number.
+ say_verbose "Failed to get the version using productVersion.txt file. Download link will be parsed instead."
+ specific_product_version="$(get_product_specific_version_from_download_link "$package_download_link" "$specific_version")"
+ echo "${specific_product_version//[$'\t\r\n']}"
+ return 0
+}
+
+# args:
+# azure_feed - $1
+# specific_version - $2
+# is_flattened - $3
+# download link - $4 (optional)
+get_specific_product_version_url() {
+ eval $invocation
+
+ local azure_feed="$1"
+ local specific_version="$2"
+ local is_flattened="$3"
+ local package_download_link=""
+ if [ $# -gt 3 ]; then
+ local package_download_link="$4"
+ fi
+
+ local pvFileName="productVersion.txt"
+ if [ "$is_flattened" = true ]; then
+ if [ -z "$runtime" ]; then
+ pvFileName="sdk-productVersion.txt"
+ elif [[ "$runtime" == "dotnet" ]]; then
+ pvFileName="runtime-productVersion.txt"
+ else
+ pvFileName="$runtime-productVersion.txt"
+ fi
+ fi
+
+ local download_link=null
+
+ if [ -z "$package_download_link" ]; then
+ if [[ "$runtime" == "dotnet" ]]; then
+ download_link="$azure_feed/Runtime/$specific_version/${pvFileName}"
+ elif [[ "$runtime" == "aspnetcore" ]]; then
+ download_link="$azure_feed/aspnetcore/Runtime/$specific_version/${pvFileName}"
+ elif [ -z "$runtime" ]; then
+ download_link="$azure_feed/Sdk/$specific_version/${pvFileName}"
+ else
+ return 1
+ fi
+ else
+ download_link="${package_download_link%/*}/${pvFileName}"
+ fi
+
+ say_verbose "Constructed productVersion link: $download_link"
+ echo "$download_link"
+ return 0
+}
+
+# args:
+# download link - $1
+# specific version - $2
+get_product_specific_version_from_download_link()
+{
+ eval $invocation
+
+ local download_link="$1"
+ local specific_version="$2"
+ local specific_product_version=""
+
+ if [ -z "$download_link" ]; then
+ echo "$specific_version"
+ return 0
+ fi
+
+ #get filename
+ filename="${download_link##*/}"
+
+ #product specific version follows the product name
+ #for filename 'dotnet-sdk-3.1.404-linux-x64.tar.gz': the product version is 3.1.404
+ IFS='-'
+ read -ra filename_elems <<< "$filename"
+ count=${#filename_elems[@]}
+ if [[ "$count" -gt 2 ]]; then
+ specific_product_version="${filename_elems[2]}"
+ else
+ specific_product_version=$specific_version
+ fi
+ unset IFS;
+ echo "$specific_product_version"
+ return 0
+}
+
+# args:
+# azure_feed - $1
+# channel - $2
+# normalized_architecture - $3
+# specific_version - $4
+construct_legacy_download_link() {
+ eval $invocation
+
+ local azure_feed="$1"
+ local channel="$2"
+ local normalized_architecture="$3"
+ local specific_version="${4//[$'\t\r\n']}"
+
+ local distro_specific_osname
+ distro_specific_osname="$(get_legacy_os_name)" || return 1
+
+ local legacy_download_link=null
+ if [[ "$runtime" == "dotnet" ]]; then
+ legacy_download_link="$azure_feed/Runtime/$specific_version/dotnet-$distro_specific_osname-$normalized_architecture.$specific_version.tar.gz"
+ elif [ -z "$runtime" ]; then
+ legacy_download_link="$azure_feed/Sdk/$specific_version/dotnet-dev-$distro_specific_osname-$normalized_architecture.$specific_version.tar.gz"
+ else
+ return 1
+ fi
+
+ echo "$legacy_download_link"
+ return 0
+}
+
+get_user_install_path() {
+ eval $invocation
+
+ if [ ! -z "${DOTNET_INSTALL_DIR:-}" ]; then
+ echo "$DOTNET_INSTALL_DIR"
+ else
+ echo "$HOME/.dotnet"
+ fi
+ return 0
+}
+
+# args:
+# install_dir - $1
+resolve_installation_path() {
+ eval $invocation
+
+ local install_dir=$1
+ if [ "$install_dir" = "" ]; then
+ local user_install_path="$(get_user_install_path)"
+ say_verbose "resolve_installation_path: user_install_path=$user_install_path"
+ echo "$user_install_path"
+ return 0
+ fi
+
+ echo "$install_dir"
+ return 0
+}
+
+# args:
+# relative_or_absolute_path - $1
+get_absolute_path() {
+ eval $invocation
+
+ local relative_or_absolute_path=$1
+ echo "$(cd "$(dirname "$1")" && pwd -P)/$(basename "$1")"
+ return 0
+}
+
+# args:
+# override - $1 (boolean, true or false)
+get_cp_options() {
+ eval $invocation
+
+ local override="$1"
+ local override_switch=""
+
+ if [ "$override" = false ]; then
+ override_switch="-n"
+
+ # create temporary files to check if 'cp -u' is supported
+ tmp_dir="$(mktemp -d)"
+ tmp_file="$tmp_dir/testfile"
+ tmp_file2="$tmp_dir/testfile2"
+
+ touch "$tmp_file"
+
+ # use -u instead of -n if it's available
+ if cp -u "$tmp_file" "$tmp_file2" 2>/dev/null; then
+ override_switch="-u"
+ fi
+
+ # clean up
+ rm -f "$tmp_file" "$tmp_file2"
+ rm -rf "$tmp_dir"
+ fi
+
+ echo "$override_switch"
+}
+
+# args:
+# input_files - stdin
+# root_path - $1
+# out_path - $2
+# override - $3
+copy_files_or_dirs_from_list() {
+ eval $invocation
+
+ local root_path="$(remove_trailing_slash "$1")"
+ local out_path="$(remove_trailing_slash "$2")"
+ local override="$3"
+ local override_switch="$(get_cp_options "$override")"
+
+ cat | uniq | while read -r file_path; do
+ local path="$(remove_beginning_slash "${file_path#$root_path}")"
+ local target="$out_path/$path"
+ if [ "$override" = true ] || (! ([ -d "$target" ] || [ -e "$target" ])); then
+ mkdir -p "$out_path/$(dirname "$path")"
+ if [ -d "$target" ]; then
+ rm -rf "$target"
+ fi
+ cp -R $override_switch "$root_path/$path" "$target"
+ fi
+ done
+}
+
+# args:
+# zip_uri - $1
+get_remote_file_size() {
+ local zip_uri="$1"
+
+ if machine_has "curl"; then
+ file_size=$(curl -sI "$zip_uri" | grep -i content-length | awk '{ num = $2 + 0; print num }')
+ elif machine_has "wget"; then
+ file_size=$(wget --spider --server-response -O /dev/null "$zip_uri" 2>&1 | grep -i 'Content-Length:' | awk '{ num = $2 + 0; print num }')
+ else
+ say "Neither curl nor wget is available on this system."
+ return
+ fi
+
+ if [ -n "$file_size" ]; then
+ say "Remote file $zip_uri size is $file_size bytes."
+ echo "$file_size"
+ else
+ say_verbose "Content-Length header was not extracted for $zip_uri."
+ echo ""
+ fi
+}
+
+# args:
+# zip_path - $1
+# out_path - $2
+# remote_file_size - $3
+extract_dotnet_package() {
+ eval $invocation
+
+ local zip_path="$1"
+ local out_path="$2"
+ local remote_file_size="$3"
+
+ local temp_out_path="$(mktemp -d "$temporary_file_template")"
+
+ local failed=false
+ tar -xzf "$zip_path" -C "$temp_out_path" > /dev/null || failed=true
+
+ local folders_with_version_regex='^.*/[0-9]+\.[0-9]+[^/]+/'
+ find "$temp_out_path" -type f | grep -Eo "$folders_with_version_regex" | sort | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" false
+ find "$temp_out_path" -type f | grep -Ev "$folders_with_version_regex" | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" "$override_non_versioned_files"
+
+ validate_remote_local_file_sizes "$zip_path" "$remote_file_size"
+
+ rm -rf "$temp_out_path"
+ if [ -z ${keep_zip+x} ]; then
+ rm -f "$zip_path" && say_verbose "Temporary archive file $zip_path was removed"
+ fi
+
+ if [ "$failed" = true ]; then
+ say_err "Extraction failed"
+ return 1
+ fi
+ return 0
+}
+
+# args:
+# remote_path - $1
+# disable_feed_credential - $2
+get_http_header()
+{
+ eval $invocation
+ local remote_path="$1"
+ local disable_feed_credential="$2"
+
+ local failed=false
+ local response
+ if machine_has "curl"; then
+ get_http_header_curl $remote_path $disable_feed_credential || failed=true
+ elif machine_has "wget"; then
+ get_http_header_wget $remote_path $disable_feed_credential || failed=true
+ else
+ failed=true
+ fi
+ if [ "$failed" = true ]; then
+ say_verbose "Failed to get HTTP header: '$remote_path'."
+ return 1
+ fi
+ return 0
+}
+
+# args:
+# remote_path - $1
+# disable_feed_credential - $2
+get_http_header_curl() {
+ eval $invocation
+ local remote_path="$1"
+ local disable_feed_credential="$2"
+
+ remote_path_with_credential="$remote_path"
+ if [ "$disable_feed_credential" = false ]; then
+ remote_path_with_credential+="$feed_credential"
+ fi
+
+ curl_options="-I -sSL --retry 5 --retry-delay 2 --connect-timeout 15 "
+ curl $curl_options "$remote_path_with_credential" 2>&1 || return 1
+ return 0
+}
+
+# args:
+# remote_path - $1
+# disable_feed_credential - $2
+get_http_header_wget() {
+ eval $invocation
+ local remote_path="$1"
+ local disable_feed_credential="$2"
+ local wget_options="-q -S --spider --tries 5 "
+
+ local wget_options_extra=''
+
+ # Test for options that aren't supported on all wget implementations.
+ if [[ $(wget -h 2>&1 | grep -E 'waitretry|connect-timeout') ]]; then
+ wget_options_extra="--waitretry 2 --connect-timeout 15 "
+ else
+ say "wget extra options are unavailable for this environment"
+ fi
+
+ remote_path_with_credential="$remote_path"
+ if [ "$disable_feed_credential" = false ]; then
+ remote_path_with_credential+="$feed_credential"
+ fi
+
+ wget $wget_options $wget_options_extra "$remote_path_with_credential" 2>&1
+
+ return $?
+}
+
+# args:
+# remote_path - $1
+# [out_path] - $2 - stdout if not provided
+download() {
+ eval $invocation
+
+ local remote_path="$1"
+ local out_path="${2:-}"
+
+ if [[ "$remote_path" != "http"* ]]; then
+ cp "$remote_path" "$out_path"
+ return $?
+ fi
+
+ local failed=false
+ local attempts=0
+ while [ $attempts -lt 3 ]; do
+ attempts=$((attempts+1))
+ failed=false
+ if machine_has "curl"; then
+ downloadcurl "$remote_path" "$out_path" || failed=true
+ elif machine_has "wget"; then
+ downloadwget "$remote_path" "$out_path" || failed=true
+ else
+ say_err "Missing dependency: neither curl nor wget was found."
+ exit 1
+ fi
+
+ if [ "$failed" = false ] || [ $attempts -ge 3 ] || { [ ! -z $http_code ] && [ $http_code = "404" ]; }; then
+ break
+ fi
+
+ say "Download attempt #$attempts has failed: $http_code $download_error_msg"
+ say "Attempt #$((attempts+1)) will start in $((attempts*10)) seconds."
+ sleep $((attempts*10))
+ done
+
+ if [ "$failed" = true ]; then
+ say_verbose "Download failed: $remote_path"
+ return 1
+ fi
+ return 0
+}
+
+# Updates global variables $http_code and $download_error_msg
+downloadcurl() {
+ eval $invocation
+ unset http_code
+ unset download_error_msg
+ local remote_path="$1"
+ local out_path="${2:-}"
+ # Append feed_credential as late as possible before calling curl to avoid logging feed_credential
+ # Avoid passing URI with credentials to functions: note, most of them echoing parameters of invocation in verbose output.
+ local remote_path_with_credential="${remote_path}${feed_credential}"
+ local curl_options="--retry 20 --retry-delay 2 --connect-timeout 15 -sSL -f --create-dirs "
+ local curl_exit_code=0;
+ if [ -z "$out_path" ]; then
+ curl_output=$(curl $curl_options "$remote_path_with_credential" 2>&1)
+ curl_exit_code=$?
+ echo "$curl_output"
+ else
+ curl_output=$(curl $curl_options -o "$out_path" "$remote_path_with_credential" 2>&1)
+ curl_exit_code=$?
+ fi
+
+ # Regression in curl causes curl with --retry to return a 0 exit code even when it fails to download a file - https://github.com/curl/curl/issues/17554
+ if [ $curl_exit_code -eq 0 ] && echo "$curl_output" | grep -q "^curl: ([0-9]*) "; then
+ curl_exit_code=$(echo "$curl_output" | sed 's/curl: (\([0-9]*\)).*/\1/')
+ fi
+
+ if [ $curl_exit_code -gt 0 ]; then
+ download_error_msg="Unable to download $remote_path."
+ # Check for curl timeout codes
+ if [[ $curl_exit_code == 7 || $curl_exit_code == 28 ]]; then
+ download_error_msg+=" Failed to reach the server: connection timeout."
+ else
+ local disable_feed_credential=false
+ local response=$(get_http_header_curl $remote_path $disable_feed_credential)
+ http_code=$( echo "$response" | awk '/^HTTP/{print $2}' | tail -1 )
+ if [[ ! -z $http_code && $http_code != 2* ]]; then
+ download_error_msg+=" Returned HTTP status code: $http_code."
+ fi
+ fi
+ say_verbose "$download_error_msg"
+ return 1
+ fi
+ return 0
+}
+
+
+# Updates global variables $http_code and $download_error_msg
+downloadwget() {
+ eval $invocation
+ unset http_code
+ unset download_error_msg
+ local remote_path="$1"
+ local out_path="${2:-}"
+ # Append feed_credential as late as possible before calling wget to avoid logging feed_credential
+ local remote_path_with_credential="${remote_path}${feed_credential}"
+ local wget_options="--tries 20 "
+
+ local wget_options_extra=''
+ local wget_result=''
+
+ # Test for options that aren't supported on all wget implementations.
+ if [[ $(wget -h 2>&1 | grep -E 'waitretry|connect-timeout') ]]; then
+ wget_options_extra="--waitretry 2 --connect-timeout 15 "
+ else
+ say "wget extra options are unavailable for this environment"
+ fi
+
+ if [ -z "$out_path" ]; then
+ wget -q $wget_options $wget_options_extra -O - "$remote_path_with_credential" 2>&1
+ wget_result=$?
+ else
+ wget $wget_options $wget_options_extra -O "$out_path" "$remote_path_with_credential" 2>&1
+ wget_result=$?
+ fi
+
+ if [[ $wget_result != 0 ]]; then
+ local disable_feed_credential=false
+ local response=$(get_http_header_wget $remote_path $disable_feed_credential)
+ http_code=$( echo "$response" | awk '/^ HTTP/{print $2}' | tail -1 )
+ download_error_msg="Unable to download $remote_path."
+ if [[ ! -z $http_code && $http_code != 2* ]]; then
+ download_error_msg+=" Returned HTTP status code: $http_code."
+ # wget exit code 4 stands for network-issue
+ elif [[ $wget_result == 4 ]]; then
+ download_error_msg+=" Failed to reach the server: connection timeout."
+ fi
+ say_verbose "$download_error_msg"
+ return 1
+ fi
+
+ return 0
+}
+
+get_download_link_from_aka_ms() {
+ eval $invocation
+
+ #quality is not supported for LTS or STS channel
+ #STS maps to current
+ if [[ ! -z "$normalized_quality" && ("$normalized_channel" == "LTS" || "$normalized_channel" == "STS") ]]; then
+ normalized_quality=""
+ say_warning "Specifying quality for STS or LTS channel is not supported, the quality will be ignored."
+ fi
+
+ say_verbose "Retrieving primary payload URL from aka.ms for channel: '$normalized_channel', quality: '$normalized_quality', product: '$normalized_product', os: '$normalized_os', architecture: '$normalized_architecture'."
+
+ #construct aka.ms link
+ aka_ms_link="https://aka.ms/dotnet"
+ if [ "$internal" = true ]; then
+ aka_ms_link="$aka_ms_link/internal"
+ fi
+ aka_ms_link="$aka_ms_link/$normalized_channel"
+ if [[ ! -z "$normalized_quality" ]]; then
+ aka_ms_link="$aka_ms_link/$normalized_quality"
+ fi
+ aka_ms_link="$aka_ms_link/$normalized_product-$normalized_os-$normalized_architecture.tar.gz"
+ say_verbose "Constructed aka.ms link: '$aka_ms_link'."
+
+ #get HTTP response
+ #do not pass credentials as a part of the $aka_ms_link and do not apply credentials in the get_http_header function
+ #otherwise the redirect link would have credentials as well
+ #it would result in applying credentials twice to the resulting link and thus breaking it, and in echoing credentials to the output as a part of redirect link
+ disable_feed_credential=true
+ response="$(get_http_header $aka_ms_link $disable_feed_credential)"
+
+ say_verbose "Received response: $response"
+ # Get results of all the redirects.
+ http_codes=$( echo "$response" | awk '$1 ~ /^HTTP/ {print $2}' )
+ # They all need to be 301, otherwise some links are broken (except for the last, which is not a redirect but 200 or 404).
+ broken_redirects=$( echo "$http_codes" | sed '$d' | grep -v '301' )
+ # The response may end without final code 2xx/4xx/5xx somehow, e.g. network restrictions on www.bing.com causes redirecting to bing.com fails with connection refused.
+ # In this case it should not exclude the last.
+ last_http_code=$( echo "$http_codes" | tail -n 1 )
+ if ! [[ $last_http_code =~ ^(2|4|5)[0-9][0-9]$ ]]; then
+ broken_redirects=$( echo "$http_codes" | grep -v '301' )
+ fi
+
+ # All HTTP codes are 301 (Moved Permanently), the redirect link exists.
+ if [[ -z "$broken_redirects" ]]; then
+ aka_ms_download_link=$( echo "$response" | awk '$1 ~ /^Location/{print $2}' | tail -1 | tr -d '\r')
+
+ if [[ -z "$aka_ms_download_link" ]]; then
+ say_verbose "The aka.ms link '$aka_ms_link' is not valid: failed to get redirect location."
+ return 1
+ fi
+
+ say_verbose "The redirect location retrieved: '$aka_ms_download_link'."
+ return 0
+ else
+ say_verbose "The aka.ms link '$aka_ms_link' is not valid: received HTTP code: $(echo "$broken_redirects" | paste -sd "," -)."
+ return 1
+ fi
+}
+
+get_feeds_to_use()
+{
+ feeds=(
+ "https://builds.dotnet.microsoft.com/dotnet"
+ "https://ci.dot.net/public"
+ )
+
+ if [[ -n "$azure_feed" ]]; then
+ feeds=("$azure_feed")
+ fi
+
+ if [[ -n "$uncached_feed" ]]; then
+ feeds=("$uncached_feed")
+ fi
+}
+
+# THIS FUNCTION MAY EXIT (if the determined version is already installed).
+generate_download_links() {
+
+ download_links=()
+ specific_versions=()
+ effective_versions=()
+ link_types=()
+
+ # If generate_akams_links returns false, no fallback to old links. Just terminate.
+ # This function may also 'exit' (if the determined version is already installed).
+ generate_akams_links || return
+
+ # Check other feeds only if we haven't been able to find an aka.ms link.
+ if [[ "${#download_links[@]}" -lt 1 ]]; then
+ for feed in ${feeds[@]}
+ do
+ # generate_regular_links may also 'exit' (if the determined version is already installed).
+ generate_regular_links $feed || return
+ done
+ fi
+
+ if [[ "${#download_links[@]}" -eq 0 ]]; then
+ say_err "Failed to resolve the exact version number."
+ return 1
+ fi
+
+ say_verbose "Generated ${#download_links[@]} links."
+ for link_index in ${!download_links[@]}
+ do
+ say_verbose "Link $link_index: ${link_types[$link_index]}, ${effective_versions[$link_index]}, ${download_links[$link_index]}"
+ done
+}
+
+# THIS FUNCTION MAY EXIT (if the determined version is already installed).
+generate_akams_links() {
+ local valid_aka_ms_link=true;
+
+ normalized_version="$(to_lowercase "$version")"
+ if [[ "$normalized_version" != "latest" ]] && [ -n "$normalized_quality" ]; then
+ say_err "Quality and Version options are not allowed to be specified simultaneously. See https://learn.microsoft.com/dotnet/core/tools/dotnet-install-script#options for details."
+ return 1
+ fi
+
+ if [[ -n "$json_file" || "$normalized_version" != "latest" ]]; then
+ # aka.ms links are not needed when exact version is specified via command or json file
+ return
+ fi
+
+ get_download_link_from_aka_ms || valid_aka_ms_link=false
+
+ if [[ "$valid_aka_ms_link" == true ]]; then
+ say_verbose "Retrieved primary payload URL from aka.ms link: '$aka_ms_download_link'."
+ say_verbose "Downloading using legacy url will not be attempted."
+
+ download_link=$aka_ms_download_link
+
+ #get version from the path
+ IFS='/'
+ read -ra pathElems <<< "$download_link"
+ count=${#pathElems[@]}
+ specific_version="${pathElems[count-2]}"
+ unset IFS;
+ say_verbose "Version: '$specific_version'."
+
+ #Retrieve effective version
+ effective_version="$(get_specific_product_version "$azure_feed" "$specific_version" "$download_link")"
+
+ # Add link info to arrays
+ download_links+=($download_link)
+ specific_versions+=($specific_version)
+ effective_versions+=($effective_version)
+ link_types+=("aka.ms")
+
+ # Check if the SDK version is already installed.
+ if [[ "$dry_run" != true ]] && is_dotnet_package_installed "$install_root" "$asset_relative_path" "$effective_version"; then
+ say "$asset_name with version '$effective_version' is already installed."
+ exit 0
+ fi
+
+ return 0
+ fi
+
+ # if quality is specified - exit with error - there is no fallback approach
+ if [ ! -z "$normalized_quality" ]; then
+ say_err "Failed to locate the latest version in the channel '$normalized_channel' with '$normalized_quality' quality for '$normalized_product', os: '$normalized_os', architecture: '$normalized_architecture'."
+ say_err "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support."
+ return 1
+ fi
+ say_verbose "Falling back to latest.version file approach."
+}
+
+# THIS FUNCTION MAY EXIT (if the determined version is already installed)
+# args:
+# feed - $1
+generate_regular_links() {
+ local feed="$1"
+ local valid_legacy_download_link=true
+
+ specific_version=$(get_specific_version_from_version "$feed" "$channel" "$normalized_architecture" "$version" "$json_file") || specific_version='0'
+
+ if [[ "$specific_version" == '0' ]]; then
+ say_verbose "Failed to resolve the specific version number using feed '$feed'"
+ return
+ fi
+
+ effective_version="$(get_specific_product_version "$feed" "$specific_version")"
+ say_verbose "specific_version=$specific_version"
+
+ download_link="$(construct_download_link "$feed" "$channel" "$normalized_architecture" "$specific_version" "$normalized_os")"
+ say_verbose "Constructed primary named payload URL: $download_link"
+
+ # Add link info to arrays
+ download_links+=($download_link)
+ specific_versions+=($specific_version)
+ effective_versions+=($effective_version)
+ link_types+=("primary")
+
+ legacy_download_link="$(construct_legacy_download_link "$feed" "$channel" "$normalized_architecture" "$specific_version")" || valid_legacy_download_link=false
+
+ if [ "$valid_legacy_download_link" = true ]; then
+ say_verbose "Constructed legacy named payload URL: $legacy_download_link"
+
+ download_links+=($legacy_download_link)
+ specific_versions+=($specific_version)
+ effective_versions+=($effective_version)
+ link_types+=("legacy")
+ else
+ legacy_download_link=""
+ say_verbose "Could not construct a legacy_download_link; omitting..."
+ fi
+
+ # Check if the SDK version is already installed.
+ if [[ "$dry_run" != true ]] && is_dotnet_package_installed "$install_root" "$asset_relative_path" "$effective_version"; then
+ say "$asset_name with version '$effective_version' is already installed."
+ exit 0
+ fi
+}
+
+print_dry_run() {
+
+ say "Payload URLs:"
+
+ for link_index in "${!download_links[@]}"
+ do
+ say "URL #$link_index - ${link_types[$link_index]}: ${download_links[$link_index]}"
+ done
+
+ resolved_version=${specific_versions[0]}
+ repeatable_command="./$script_name --version "\""$resolved_version"\"" --install-dir "\""$install_root"\"" --architecture "\""$normalized_architecture"\"" --os "\""$normalized_os"\"""
+
+ if [ ! -z "$normalized_quality" ]; then
+ repeatable_command+=" --quality "\""$normalized_quality"\"""
+ fi
+
+ if [[ "$runtime" == "dotnet" ]]; then
+ repeatable_command+=" --runtime "\""dotnet"\"""
+ elif [[ "$runtime" == "aspnetcore" ]]; then
+ repeatable_command+=" --runtime "\""aspnetcore"\"""
+ fi
+
+ repeatable_command+="$non_dynamic_parameters"
+
+ if [ -n "$feed_credential" ]; then
+ repeatable_command+=" --feed-credential "\"""\"""
+ fi
+
+ say "Repeatable invocation: $repeatable_command"
+}
+
+calculate_vars() {
+ eval $invocation
+
+ script_name=$(basename "$0")
+ normalized_architecture="$(get_normalized_architecture_from_architecture "$architecture")"
+ say_verbose "Normalized architecture: '$normalized_architecture'."
+ normalized_os="$(get_normalized_os "$user_defined_os")"
+ say_verbose "Normalized OS: '$normalized_os'."
+ normalized_quality="$(get_normalized_quality "$quality")"
+ say_verbose "Normalized quality: '$normalized_quality'."
+ normalized_channel="$(get_normalized_channel "$channel")"
+ say_verbose "Normalized channel: '$normalized_channel'."
+ normalized_product="$(get_normalized_product "$runtime")"
+ say_verbose "Normalized product: '$normalized_product'."
+ install_root="$(resolve_installation_path "$install_dir")"
+ say_verbose "InstallRoot: '$install_root'."
+
+ normalized_architecture="$(get_normalized_architecture_for_specific_sdk_version "$version" "$normalized_channel" "$normalized_architecture")"
+
+ if [[ "$runtime" == "dotnet" ]]; then
+ asset_relative_path="shared/Microsoft.NETCore.App"
+ asset_name=".NET Core Runtime"
+ elif [[ "$runtime" == "aspnetcore" ]]; then
+ asset_relative_path="shared/Microsoft.AspNetCore.App"
+ asset_name="ASP.NET Core Runtime"
+ elif [ -z "$runtime" ]; then
+ asset_relative_path="sdk"
+ asset_name=".NET Core SDK"
+ fi
+
+ get_feeds_to_use
+}
+
+install_dotnet() {
+ eval $invocation
+ local download_failed=false
+ local download_completed=false
+ local remote_file_size=0
+
+ mkdir -p "$install_root"
+ zip_path="${zip_path:-$(mktemp "$temporary_file_template")}"
+ say_verbose "Archive path: $zip_path"
+
+ for link_index in "${!download_links[@]}"
+ do
+ download_link="${download_links[$link_index]}"
+ specific_version="${specific_versions[$link_index]}"
+ effective_version="${effective_versions[$link_index]}"
+ link_type="${link_types[$link_index]}"
+
+ say "Attempting to download using $link_type link $download_link"
+
+ # The download function will set variables $http_code and $download_error_msg in case of failure.
+ download_failed=false
+ download "$download_link" "$zip_path" 2>&1 || download_failed=true
+
+ if [ "$download_failed" = true ]; then
+ case $http_code in
+ 404)
+ say "The resource at $link_type link '$download_link' is not available."
+ ;;
+ *)
+ say "Failed to download $link_type link '$download_link': $http_code $download_error_msg"
+ ;;
+ esac
+ rm -f "$zip_path" 2>&1 && say_verbose "Temporary archive file $zip_path was removed"
+ else
+ download_completed=true
+ break
+ fi
+ done
+
+ if [[ "$download_completed" == false ]]; then
+ say_err "Could not find \`$asset_name\` with version = $specific_version"
+ say_err "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support"
+ return 1
+ fi
+
+ remote_file_size="$(get_remote_file_size "$download_link")"
+
+ say "Extracting archive from $download_link"
+ extract_dotnet_package "$zip_path" "$install_root" "$remote_file_size" || return 1
+
+ # Check if the SDK version is installed; if not, fail the installation.
+ # if the version contains "RTM" or "servicing"; check if a 'release-type' SDK version is installed.
+ if [[ $specific_version == *"rtm"* || $specific_version == *"servicing"* ]]; then
+ IFS='-'
+ read -ra verArr <<< "$specific_version"
+ release_version="${verArr[0]}"
+ unset IFS;
+ say_verbose "Checking installation: version = $release_version"
+ if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$release_version"; then
+ say "Installed version is $effective_version"
+ return 0
+ fi
+ fi
+
+ # Check if the standard SDK version is installed.
+ say_verbose "Checking installation: version = $effective_version"
+ if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$effective_version"; then
+ say "Installed version is $effective_version"
+ return 0
+ fi
+
+ # Version verification failed. More likely something is wrong either with the downloaded content or with the verification algorithm.
+ say_err "Failed to verify the version of installed \`$asset_name\`.\nInstallation source: $download_link.\nInstallation location: $install_root.\nReport the bug at https://github.com/dotnet/install-scripts/issues."
+ say_err "\`$asset_name\` with version = $effective_version failed to install with an error."
+ return 1
+}
+
+args=("$@")
+
+local_version_file_relative_path="/.version"
+bin_folder_relative_path=""
+temporary_file_template="${TMPDIR:-/tmp}/dotnet.XXXXXXXXX"
+
+channel="LTS"
+version="Latest"
+json_file=""
+install_dir=""
+architecture=""
+dry_run=false
+no_path=false
+azure_feed=""
+uncached_feed=""
+feed_credential=""
+verbose=false
+runtime=""
+runtime_id=""
+quality=""
+internal=false
+override_non_versioned_files=true
+non_dynamic_parameters=""
+user_defined_os=""
+
+while [ $# -ne 0 ]
+do
+ name="$1"
+ case "$name" in
+ -c|--channel|-[Cc]hannel)
+ shift
+ channel="$1"
+ ;;
+ -v|--version|-[Vv]ersion)
+ shift
+ version="$1"
+ ;;
+ -q|--quality|-[Qq]uality)
+ shift
+ quality="$1"
+ ;;
+ --internal|-[Ii]nternal)
+ internal=true
+ non_dynamic_parameters+=" $name"
+ ;;
+ -i|--install-dir|-[Ii]nstall[Dd]ir)
+ shift
+ install_dir="$1"
+ ;;
+ --arch|--architecture|-[Aa]rch|-[Aa]rchitecture)
+ shift
+ architecture="$1"
+ ;;
+ --os|-[Oo][SS])
+ shift
+ user_defined_os="$1"
+ ;;
+ --shared-runtime|-[Ss]hared[Rr]untime)
+ say_warning "The --shared-runtime flag is obsolete and may be removed in a future version of this script. The recommended usage is to specify '--runtime dotnet'."
+ if [ -z "$runtime" ]; then
+ runtime="dotnet"
+ fi
+ ;;
+ --runtime|-[Rr]untime)
+ shift
+ runtime="$1"
+ if [[ "$runtime" != "dotnet" ]] && [[ "$runtime" != "aspnetcore" ]]; then
+ say_err "Unsupported value for --runtime: '$1'. Valid values are 'dotnet' and 'aspnetcore'."
+ if [[ "$runtime" == "windowsdesktop" ]]; then
+ say_err "WindowsDesktop archives are manufactured for Windows platforms only."
+ fi
+ exit 1
+ fi
+ ;;
+ --dry-run|-[Dd]ry[Rr]un)
+ dry_run=true
+ ;;
+ --no-path|-[Nn]o[Pp]ath)
+ no_path=true
+ non_dynamic_parameters+=" $name"
+ ;;
+ --verbose|-[Vv]erbose)
+ verbose=true
+ non_dynamic_parameters+=" $name"
+ ;;
+ --azure-feed|-[Aa]zure[Ff]eed)
+ shift
+ azure_feed="$1"
+ non_dynamic_parameters+=" $name "\""$1"\"""
+ ;;
+ --uncached-feed|-[Uu]ncached[Ff]eed)
+ shift
+ uncached_feed="$1"
+ non_dynamic_parameters+=" $name "\""$1"\"""
+ ;;
+ --feed-credential|-[Ff]eed[Cc]redential)
+ shift
+ feed_credential="$1"
+ #feed_credential should start with "?", for it to be added to the end of the link.
+ #adding "?" at the beginning of the feed_credential if needed.
+ [[ -z "$(echo $feed_credential)" ]] || [[ $feed_credential == \?* ]] || feed_credential="?$feed_credential"
+ ;;
+ --runtime-id|-[Rr]untime[Ii]d)
+ shift
+ runtime_id="$1"
+ non_dynamic_parameters+=" $name "\""$1"\"""
+ say_warning "Use of --runtime-id is obsolete and should be limited to the versions below 2.1. To override architecture, use --architecture option instead. To override OS, use --os option instead."
+ ;;
+ --jsonfile|-[Jj][Ss]on[Ff]ile)
+ shift
+ json_file="$1"
+ ;;
+ --skip-non-versioned-files|-[Ss]kip[Nn]on[Vv]ersioned[Ff]iles)
+ override_non_versioned_files=false
+ non_dynamic_parameters+=" $name"
+ ;;
+ --keep-zip|-[Kk]eep[Zz]ip)
+ keep_zip=true
+ non_dynamic_parameters+=" $name"
+ ;;
+ --zip-path|-[Zz]ip[Pp]ath)
+ shift
+ zip_path="$1"
+ ;;
+ -?|--?|-h|--help|-[Hh]elp)
+ script_name="dotnet-install.sh"
+ echo ".NET Tools Installer"
+ echo "Usage:"
+ echo " # Install a .NET SDK of a given Quality from a given Channel"
+ echo " $script_name [-c|--channel ] [-q|--quality ]"
+ echo " # Install a .NET SDK of a specific public version"
+ echo " $script_name [-v|--version ]"
+ echo " $script_name -h|-?|--help"
+ echo ""
+ echo "$script_name is a simple command line interface for obtaining dotnet cli."
+ echo " Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
+ echo " - The SDK needs to be installed without user interaction and without admin rights."
+ echo " - The SDK installation doesn't need to persist across multiple CI runs."
+ echo " To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer."
+ echo ""
+ echo "Options:"
+ echo " -c,--channel Download from the channel specified, Defaults to \`$channel\`."
+ echo " -Channel"
+ echo " Possible values:"
+ echo " - STS - the most recent Standard Term Support release"
+ echo " - LTS - the most recent Long Term Support release"
+ echo " - 2-part version in a format A.B - represents a specific release"
+ echo " examples: 2.0; 1.0"
+ echo " - 3-part version in a format A.B.Cxx - represents a specific SDK release"
+ echo " examples: 5.0.1xx, 5.0.2xx."
+ echo " Supported since 5.0 release"
+ echo " Warning: Value 'Current' is deprecated for the Channel parameter. Use 'STS' instead."
+ echo " Note: The version parameter overrides the channel parameter when any version other than 'latest' is used."
+ echo " -v,--version Use specific VERSION, Defaults to \`$version\`."
+ echo " -Version"
+ echo " Possible values:"
+ echo " - latest - the latest build on specific channel"
+ echo " - 3-part version in a format A.B.C - represents specific version of build"
+ echo " examples: 2.0.0-preview2-006120; 1.1.0"
+ echo " -q,--quality Download the latest build of specified quality in the channel."
+ echo " -Quality"
+ echo " The possible values are: daily, preview, GA."
+ echo " Works only in combination with channel. Not applicable for STS and LTS channels and will be ignored if those channels are used."
+ echo " For SDK use channel in A.B.Cxx format. Using quality for SDK together with channel in A.B format is not supported."
+ echo " Supported since 5.0 release."
+ echo " Note: The version parameter overrides the channel parameter when any version other than 'latest' is used, and therefore overrides the quality."
+ echo " --internal,-Internal Download internal builds. Requires providing credentials via --feed-credential parameter."
+ echo " --feed-credential Token to access Azure feed. Used as a query string to append to the Azure feed."
+ echo " -FeedCredential This parameter typically is not specified."
+ echo " -i,--install-dir Install under specified location (see Install Location below)"
+ echo " -InstallDir"
+ echo " --architecture Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`."
+ echo " --arch,-Architecture,-Arch"
+ echo " Possible values: x64, arm, arm64, s390x, ppc64le and loongarch64"
+ echo " --os Specifies operating system to be used when selecting the installer."
+ echo " Overrides the OS determination approach used by the script. Supported values: osx, linux, linux-musl, freebsd, rhel.6."
+ echo " In case any other value is provided, the platform will be determined by the script based on machine configuration."
+ echo " Not supported for legacy links. Use --runtime-id to specify platform for legacy links."
+ echo " Refer to: https://aka.ms/dotnet-os-lifecycle for more information."
+ echo " --runtime Installs a shared runtime only, without the SDK."
+ echo " -Runtime"
+ echo " Possible values:"
+ echo " - dotnet - the Microsoft.NETCore.App shared runtime"
+ echo " - aspnetcore - the Microsoft.AspNetCore.App shared runtime"
+ echo " --dry-run,-DryRun Do not perform installation. Display download link."
+ echo " --no-path, -NoPath Do not set PATH for the current process."
+ echo " --verbose,-Verbose Display diagnostics information."
+ echo " --azure-feed,-AzureFeed For internal use only."
+ echo " Allows using a different storage to download SDK archives from."
+ echo " --uncached-feed,-UncachedFeed For internal use only."
+ echo " Allows using a different storage to download SDK archives from."
+ echo " --skip-non-versioned-files Skips non-versioned files if they already exist, such as the dotnet executable."
+ echo " -SkipNonVersionedFiles"
+ echo " --jsonfile Determines the SDK version from a user specified global.json file."
+ echo " Note: global.json must have a value for 'SDK:Version'"
+ echo " --keep-zip,-KeepZip If set, downloaded file is kept."
+ echo " --zip-path, -ZipPath If set, downloaded file is stored at the specified path."
+ echo " -?,--?,-h,--help,-Help Shows this help message"
+ echo ""
+ echo "Install Location:"
+ echo " Location is chosen in following order:"
+ echo " - --install-dir option"
+ echo " - Environmental variable DOTNET_INSTALL_DIR"
+ echo " - $HOME/.dotnet"
+ exit 0
+ ;;
+ *)
+ say_err "Unknown argument \`$name\`"
+ exit 1
+ ;;
+ esac
+
+ shift
+done
+
+say_verbose "Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
+say_verbose "- The SDK needs to be installed without user interaction and without admin rights."
+say_verbose "- The SDK installation doesn't need to persist across multiple CI runs."
+say_verbose "To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.\n"
+
+if [ "$internal" = true ] && [ -z "$(echo $feed_credential)" ]; then
+ message="Provide credentials via --feed-credential parameter."
+ if [ "$dry_run" = true ]; then
+ say_warning "$message"
+ else
+ say_err "$message"
+ exit 1
+ fi
+fi
+
+check_min_reqs
+calculate_vars
+# generate_regular_links call below will 'exit' if the determined version is already installed.
+generate_download_links
+
+if [[ "$dry_run" = true ]]; then
+ print_dry_run
+ exit 0
+fi
+
+install_dotnet
+
+bin_path="$(get_absolute_path "$(combine_paths "$install_root" "$bin_folder_relative_path")")"
+if [ "$no_path" = false ]; then
+ say "Adding to current process PATH: \`$bin_path\`. Note: This change will be visible only when sourcing script."
+ export PATH="$bin_path":"$PATH"
+else
+ say "Binaries of dotnet can be found in $bin_path"
+fi
+
+say "Note that the script does not resolve dependencies during installation."
+say "To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the \"Dependencies\" section."
+say "Installation finished successfully."