Handle term theming with theme.sh

main
sloane ess 2024-07-21 00:25:16 -04:00
parent 6cf8344ed9
commit b0fb268d77
12 changed files with 212 additions and 443 deletions

View File

@ -1,20 +1,5 @@
{ {
"nodes": { "nodes": {
"cl-nix-lite": {
"locked": {
"lastModified": 1717972076,
"narHash": "sha256-hnZEsDInTcsVSL5LBGDAZegAxVLBus/wiJh+sNM15zU=",
"owner": "hraban",
"repo": "cl-nix-lite",
"rev": "cc920bfb0a6402d3871f470c98d65266126973e4",
"type": "github"
},
"original": {
"owner": "hraban",
"repo": "cl-nix-lite",
"type": "github"
}
},
"crane": { "crane": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -153,23 +138,6 @@
} }
}, },
"flake-compat": { "flake-compat": {
"flake": false,
"locked": {
"lastModified": 1697816753,
"narHash": "sha256-40to80AEIyKCQI0xMKCeF5ePoIKTYgjVVCZeu4CnTxM=",
"owner": "hraban",
"repo": "flake-compat",
"rev": "6025bade1336a36014639bc3f67eacc853dab78f",
"type": "github"
},
"original": {
"owner": "hraban",
"ref": "fixed-output",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_2": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1696426674, "lastModified": 1696426674,
@ -266,23 +234,6 @@
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github" "type": "github"
}, },
"original": {
"id": "flake-utils",
"type": "indirect"
}
},
"flake-utils_3": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": { "original": {
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
@ -399,32 +350,9 @@
"type": "github" "type": "github"
} }
}, },
"mac-app-util": {
"inputs": {
"cl-nix-lite": "cl-nix-lite",
"flake-compat": "flake-compat",
"flake-utils": "flake-utils_2",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1719942949,
"narHash": "sha256-srSQac7dhXtisqu4XwPGrK8qcmT2rflJJ1mRIV9j0Qk=",
"owner": "hraban",
"repo": "mac-app-util",
"rev": "63f269f737cafb2219ba38780c1ecb1dc24bc4a2",
"type": "github"
},
"original": {
"owner": "hraban",
"repo": "mac-app-util",
"type": "github"
}
},
"nil": { "nil": {
"inputs": { "inputs": {
"flake-utils": "flake-utils_3", "flake-utils": "flake-utils_2",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
@ -566,7 +494,7 @@
}, },
"pre-commit": { "pre-commit": {
"inputs": { "inputs": {
"flake-compat": "flake-compat_2", "flake-compat": "flake-compat",
"gitignore": "gitignore", "gitignore": "gitignore",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
@ -602,7 +530,6 @@
"home-manager": "home-manager", "home-manager": "home-manager",
"homebrew-enabled": "homebrew-enabled", "homebrew-enabled": "homebrew-enabled",
"ia-writer-family-src": "ia-writer-family-src", "ia-writer-family-src": "ia-writer-family-src",
"mac-app-util": "mac-app-util",
"nil": "nil", "nil": "nil",
"nix-darwin": "nix-darwin", "nix-darwin": "nix-darwin",
"nixd": "nixd", "nixd": "nixd",
@ -709,21 +636,6 @@
"type": "github" "type": "github"
} }
}, },
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"terminal-themes": { "terminal-themes": {
"flake": false, "flake": false,
"locked": { "locked": {

View File

@ -15,8 +15,6 @@
disko.url = "github:nix-community/disko"; disko.url = "github:nix-community/disko";
disko.inputs.nixpkgs.follows = "nixpkgs"; disko.inputs.nixpkgs.follows = "nixpkgs";
ghostty.url = "github:clo4/ghostty-hm-module"; ghostty.url = "github:clo4/ghostty-hm-module";
mac-app-util.url = "github:hraban/mac-app-util";
mac-app-util.inputs.nixpkgs.follows = "nixpkgs";
# "flag" for toggling homebrew operations # "flag" for toggling homebrew operations
# https://www.mat.services/posts/command-line-flake-arguments/ # https://www.mat.services/posts/command-line-flake-arguments/
@ -36,7 +34,6 @@
ia-writer-family-src.url = "github:iaolo/iA-Fonts"; ia-writer-family-src.url = "github:iaolo/iA-Fonts";
ia-writer-family-src.flake = false; ia-writer-family-src.flake = false;
# standard kitty terminal themes
terminal-themes.url = "github:mbadolato/iTerm2-Color-Schemes"; terminal-themes.url = "github:mbadolato/iTerm2-Color-Schemes";
terminal-themes.flake = false; terminal-themes.flake = false;

View File

@ -14,7 +14,6 @@
./ghostty.nix ./ghostty.nix
./git.nix ./git.nix
./helix.nix ./helix.nix
./kitty.nix
./pijul.nix ./pijul.nix
./ssh.nix ./ssh.nix
./starship.nix ./starship.nix

View File

@ -0,0 +1,114 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.fish;
in
{
options.programs.fish = {
autoTheme = {
enable = lib.mkEnableOption "Automatically change terminal and shell themes with night mode";
light = lib.mkOption {
type = lib.types.str;
description = "Light mode theme";
};
dark = lib.mkOption {
type = lib.types.str;
description = "Dark mode theme";
};
};
};
config = lib.mkIf (cfg.enable && cfg.autoTheme.enable) {
programs.fish = {
shellInit = ''
set -g theme_dark "${config.programs.fish.autoTheme.dark}"
set -g theme_light "${config.programs.fish.autoTheme.light}"
set-background-to-system
'';
interactiveShellInit = ''
set-shell-colors
set-term-colors
'';
functions =
{
# toggles `$term_background` between "light" and "dark". other Fish functions trigger when this
# variable changes. we use a universal variable so that all instances of Fish have the same
# value for the variable.
toggle-background.body = ''
if test "$term_background" = light
set -U term_background dark
else
set -U term_background light
end
'';
# set `$term_background` based on whether macOS is light or dark mode
set-background-to-system.body = ''
if is-dark-mode
set -U term_background dark
else
set -U term_background light
end
'';
# set `$term_background` based on an env var
set-background-to-env = {
argumentNames = [ "env_var" ];
body = ''
switch $$env_var
case 1
echo "Setting dark mode"
set -U term_background dark
case 0
echo "Setting light mode"
set -U term_background light
end
'';
};
# sets shell utilities to light or dark colorscheme based on `$term_background`.
set-shell-colors = {
body = ''
# Use correct theme for `btm` and `bat`
if test "$term_background" = light
alias btm "btm --color nord-light"
set -xg BAT_THEME OneHalfLight
else
alias btm "btm --color nord"
set -xg BAT_THEME OneHalfDark
end
# Set LS_COLORS
set -xg LS_COLORS (${pkgs.vivid}/bin/vivid generate one-$term_background)
'';
onVariable = "term_background";
};
# use theme.sh to update terminal colors
set-term-colors = {
body = ''
set -l theme theme_$term_background
theme.sh $$theme
'';
onVariable = "term_background";
};
# do i need to implement for linux?
is-dark-mode = abort "is-dark-mode is not defined on ${pkgs.stdenv.system} yet.}";
}
// lib.optionalAttrs pkgs.stdenv.isDarwin {
# determine if dark mode is active
is-dark-mode.body = ''
defaults read -g AppleInterfaceStyle &>/dev/null
'';
};
shellAbbrs = {
tb = "toggle-background";
sb = "set-background-to-system";
};
};
};
}

View File

@ -1,86 +0,0 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.programs.kitty;
# helper scripts for changing kitty colors
term-background = pkgs.writeShellScriptBin "term-background" ''
# Accepts the name of a theme file in color-pkg
# If shell is running in a Kitty window set the colors.
if [ -n "$KITTY_WINDOW_ID" ]; then
kitty @ --to $KITTY_LISTEN_ON set-colors --all --configured \
${cfg.colors.colors-path}/"$1".conf &
fi
'';
term-light = pkgs.writeShellScriptBin "term-light" ''
${term-background}/bin/term-background ${cfg.colors.light-name}
'';
term-dark = pkgs.writeShellScriptBin "term-dark" ''
${term-background}/bin/term-background ${cfg.colors.dark-name}
'';
in
{
options.programs.kitty = {
colors = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
When enabled, commands <command>term-dark</command> and <command>term-light</command>
will toggle between your dark and a light colors.
There is also <command>term-background</command> which accepts one argument, the name
of the theme.
(Note that the Kitty setting <literal>allow_remote_control = true</literal> is set to
enable this functionality.)
'';
};
colors-path = lib.mkOption {
type = lib.types.path;
default = "${pkgs.terminal-themes}/kitty";
description = "Path from which to load kitty colors.";
};
color-pkg-path = lib.mkOption {
type = lib.types.optional lib.types.path;
default = null;
description = ''
Path to kitty colors within <literal>color-pkgs</literal>.
'';
};
light-name = lib.mkOption {
type = lib.types.str;
default = "light";
description = "The name to use for the light colorscheme.";
};
dark-name = lib.mkOption {
type = lib.types.str;
default = "dark";
description = "The name to use for the dark colorscheme.";
};
};
};
config = lib.mkIf (cfg.enable && cfg.colors.enable) {
home.packages = [
term-light
term-dark
term-background
];
programs.kitty.settings = {
allow_remote_control = "yes";
listen_on = "unix:/tmp/mykitty";
};
xdg.configFile."kitty/macos-launch-services-cmdline".text = lib.mkIf pkgs.stdenv.isDarwin "--listen-on unix:/tmp/mykitty";
};
}

View File

@ -1,27 +0,0 @@
{ config, lib, ... }:
let
cfg = config.programs.kitty;
in
{
options.programs.kitty = {
useSymbolsFromNerdFont = lib.mkOption {
type = lib.types.str;
default = "";
example = "JetBrainsMono Nerd Font";
description = ''
NerdFont patched fonts frequently suffer from rendering issues in terminals. To mitigate
this, we can use a non-NerdFont with Kitty and use the <literal>symbol_map</literal> setting
to tell Kitty to only use a NerdFont for NerdFont symbols.
Set this option the name of an installed NerdFont (the same name you'd use in the
<literal>font_family</literal> setting), to enable this feature.
'';
};
};
config = lib.mkIf (cfg.enable && cfg.useSymbolsFromNerdFont != "") {
programs.kitty.settings = {
# https://github.com/ryanoasis/nerd-fonts/wiki/Glyph-Sets-and-Code-Points
symbol_map = "U+E5FA-U+E62B,U+E700-U+E7C5,U+F000-U+F2E0,U+E200-U+E2A9,U+F500-U+FD46,U+E300-U+E3EB,U+F400-U+F4A8,U+2665,U+26a1,U+F27C,U+E0A3,U+E0B4-U+E0C8,U+E0CA,U+E0CC-U+E0D2,U+E0D4,U+23FB-U+23FE,U+2B58,U+F300-U+F313,U+E000-U+E00D ${cfg.useSymbolsFromNerdFont}";
};
};
}

View File

@ -1,167 +1,109 @@
{ pkgs, lib, ... }: { pkgs, ... }:
let let
nixConfigDirectory = "~/dotfiles.nix"; nixConfigDirectory = "~/dotfiles.nix";
in in
{ {
imports = [ ./extras/fish/auto-theme.nix ];
programs.fish = { programs.fish = {
enable = true; enable = true;
autoTheme = {
enable = true;
light = "rose-pine-dawn";
dark = "rose-pine";
};
# see flake.nix and pkgs/default.nix # see flake.nix and pkgs/default.nix
plugins = pkgs.fishPlugins.flakePlugins; plugins = pkgs.fishPlugins.flakePlugins;
functions = functions = {
{ # user functions
# user functions mkdcd = {
mkdcd = { argumentNames = [ "target" ];
argumentNames = [ "target" ]; body = ''
body = '' if test -z "$target"
if test -z "$target" echo "mkdcd requires an argument" 1>&2
echo "mkdcd requires an argument" 1>&2 return 1
return 1
end
mkdir -p $target
cd $target
'';
};
from-dir = {
argumentNames = [ "dir" ];
body = ''
pushd $dir
set -e argv[1]
$argv
popd
'';
};
darwin-rebuild-edit-with = {
argumentNames = [
"editor"
"file"
];
body = ''
if test -z "$file"
set file flake.nix
end
from-nix $editor $file
'';
};
# TODO: use these to implement !! and .. abbreviations
# blocked on additional support for abbr in home-manager
# https://github.com/nix-community/home-manager/issues/3706
#
# taken from
# https://fishshell.com/docs/current/relnotes.html#fish-3-6-0-released-january-7-2023
# last-history-item.body = ''
# echo $history[1]
# '';
# multi-cd.body = ''
# echo cd (string repeat -n (math (string length -- $argv[1]) - 1) ../)
# '';
}
// lib.optionalAttrs pkgs.stdenv.isDarwin {
# light/dark mode helpers
# determine if dark mode is active
is-dark-mode.body = ''
defaults read -g AppleInterfaceStyle &>/dev/null
'';
# toggles `$term_background` between "light" and "dark". other Fish functions trigger when this
# variable changes. we use a universal variable so that all instances of Fish have the same
# value for the variable.
toggle-background.body = ''
if test "$term_background" = light
set -U term_background dark
else
set -U term_background light
end end
mkdir -p $target
cd $target
''; '';
# set `$term_background` based on whether macOS is light or dark mode
set-background-to-macOS.body = ''
if is-dark-mode
set -U term_background dark
else
set -U term_background light
end
'';
# set `$term_background` based on an env var
set-background-to-env = {
argumentNames = [ "env_var" ];
body = ''
switch $$env_var
case 1
echo "Setting dark mode"
set -U term_background dark
case 0
echo "Setting light mode"
set -U term_background light
end
'';
};
# sets shell utilities to light or dark colorscheme based on `$term_background`.
set-shell-colors = {
body = ''
# Use correct theme for `btm` and `bat`
if test "$term_background" = light
alias btm "btm --color nord-light"
set -xg BAT_THEME OneHalfLight
else
alias btm "btm --color nord"
set -xg BAT_THEME OneHalfDark
end
# Set LS_COLORS
set -xg LS_COLORS (${pkgs.vivid}/bin/vivid generate one-$term_background)
'';
onVariable = "term_background";
};
}; };
shellAbbrs = from-dir = {
{ argumentNames = [ "dir" ];
".." = "cd .."; body = ''
pushd $dir
# darwin-rebuild build set -e argv[1]
drb = "from-nix darwin-rebuild build --flake ."; $argv
# darwin-rebuild switch full popd
drsf = "from-nix darwin-rebuild switch --flake ."; '';
# darwin-rebuild switch (no homebrew)
drs = "from-nix darwin-rebuild switch --flake . --override-input homebrew-enabled github:boolean-option/false";
# edit darwin-rebuild config in helix
drh = "darwin-rebuild-edit-with hx";
# edit darwin-rebuild config in zed
drz = "zed ${nixConfigDirectory}";
nb = "nix build";
nd = "nix develop";
nf = "nix flake";
nfc = "nix flake check";
nfi = "nix flake init";
nfs = "nix flake show";
nfu = "nix flake update";
nr = "nix run";
ns = "nix search nixpkgs";
nsh = "nix shell";
nrp = "nix repl --expr '{ pkgs = (import <nixpkgs> { }); }'";
g = "git";
ga = "git add";
gc = "git commit";
gd = "git diff";
gl = "git log";
gp = "git push";
stage = "git add .";
commit = "git commit";
push = "git push";
pull = "git pull";
}
// lib.optionalAttrs pkgs.stdenv.isDarwin {
tb = "toggle-background";
sb = "set-background-to-macOS";
}; };
darwin-rebuild-edit-with = {
argumentNames = [
"editor"
"file"
];
body = ''
if test -z "$file"
set file flake.nix
end
from-nix $editor $file
'';
};
# TODO: use these to implement !! and .. abbreviations
# blocked on additional support for abbr in home-manager
# https://github.com/nix-community/home-manager/issues/3706
#
# taken from
# https://fishshell.com/docs/current/relnotes.html#fish-3-6-0-released-january-7-2023
# last-history-item.body = ''
# echo $history[1]
# '';
# multi-cd.body = ''
# echo cd (string repeat -n (math (string length -- $argv[1]) - 1) ../)
# '';
};
shellAbbrs = {
".." = "cd ..";
# darwin-rebuild build
drb = "from-nix darwin-rebuild build --flake .";
# darwin-rebuild switch full
drsf = "from-nix darwin-rebuild switch --flake .";
# darwin-rebuild switch (no homebrew)
drs = "from-nix darwin-rebuild switch --flake . --override-input homebrew-enabled github:boolean-option/false";
# edit darwin-rebuild config in helix
drh = "darwin-rebuild-edit-with hx";
# edit darwin-rebuild config in zed
drz = "zed ${nixConfigDirectory}";
nb = "nix build";
nd = "nix develop";
nf = "nix flake";
nfc = "nix flake check";
nfi = "nix flake init";
nfs = "nix flake show";
nfu = "nix flake update";
nr = "nix run";
ns = "nix search nixpkgs";
nsh = "nix shell";
nrp = "nix repl --expr '{ pkgs = (import <nixpkgs> { }); }'";
g = "git";
ga = "git add";
gc = "git commit";
gd = "git diff";
gl = "git log";
gp = "git push";
stage = "git add .";
commit = "git commit";
push = "git push";
pull = "git pull";
};
shellAliases = { shellAliases = {
# nix related # nix related
from-nix = "from-dir ${nixConfigDirectory}"; from-nix = "from-dir ${nixConfigDirectory}";
@ -180,13 +122,11 @@ in
# configuration that should be above `loginShellInit` and `interactiveShellInit`. # configuration that should be above `loginShellInit` and `interactiveShellInit`.
shellInit = '' shellInit = ''
set -U fish_term24bit 1 set -U fish_term24bit 1
${lib.optionalString pkgs.stdenv.isDarwin "set-background-to-macOS"}
''; '';
interactiveShellInit = '' interactiveShellInit = ''
set -g fish_greeting (set_color red)"( ³)"(set_color yellow)" hello "(set_color blue)"( ³)"(set_color normal) set -g fish_greeting (set_color red)"( ³)"(set_color yellow)" hello "(set_color blue)"( ³)"(set_color normal)
fish_vi_key_bindings fish_vi_key_bindings
${lib.optionalString pkgs.stdenv.isDarwin "set-shell-colors"}
''; '';
}; };
home.sessionVariables.VIRTUAL_ENV_DISABLE_PROMPT = "true"; home.sessionVariables.VIRTUAL_ENV_DISABLE_PROMPT = "true";

View File

@ -16,9 +16,8 @@
font = "RecMonoDuotone Nerd Font"; font = "RecMonoDuotone Nerd Font";
in in
{ {
# TODO: auto-theme
config-file = [ "${pkgs.terminal-themes}/ghostty/rose-pine-dawn" ];
font-family = font; font-family = font;
theme = "rose-pine";
# font-family-bold = "${font} Bold"; # font-family-bold = "${font} Bold";
# font-family-italic = "${font} Italic"; # font-family-italic = "${font} Italic";
# font-family-bold-italic = "${font} Bold Italic"; # font-family-bold-italic = "${font} Bold Italic";
@ -35,8 +34,8 @@
} }
// lib.optionalAttrs pkgs.stdenv.isDarwin { // lib.optionalAttrs pkgs.stdenv.isDarwin {
copy-on-select = "clipboard"; copy-on-select = "clipboard";
background-blur-radius = 20; background-blur-radius = 80;
macos-non-native-fullscreen = "visible-menu"; macos-non-native-fullscreen = false;
macos-option-as-alt = true; macos-option-as-alt = true;
}; };
}; };

View File

@ -1,4 +1,3 @@
{ pkgs, lib, ... }:
{ {
imports = [ ./extras/helix/auto-theme.nix ]; imports = [ ./extras/helix/auto-theme.nix ];
programs.helix = { programs.helix = {
@ -31,7 +30,7 @@
# }; # };
# }]; # }];
autoTheme = lib.mkIf pkgs.stdenv.isDarwin { autoTheme = {
enable = true; enable = true;
light = "rose_pine_dawn"; light = "rose_pine_dawn";
dark = "rose_pine"; dark = "rose_pine";

View File

@ -1,73 +0,0 @@
{ pkgs, lib, ... }:
let
font = "Rec Mono Duotone";
in
{
imports = [
./extras/kitty/auto-theme.nix
./extras/kitty/nerd-font.nix
];
programs.kitty = {
enable = true;
# using kitty from homebrew
package = pkgs.emptyDirectory;
settings = {
font_family = font;
bold_font = "${font} Bold";
italic_font = "${font} Italic";
bold_italic_font = "${font} Bold Italic";
font_size = "15.0";
adjust_line_height = "120%";
disable_ligatures = "cursor"; # disable ligatures when cursor is on them
hide_window_decorations = "titlebar-only";
window_padding_width = "10";
tab_bar_edge = "top";
tab_bar_style = "powerline";
tab_powerline_style = "angled";
tab_title_template = "{index}: {title}";
active_tab_font_style = "bold";
inactive_tab_font_style = "normal";
tab_activity_symbol = "💬";
# shell integration is manually enabled for fish
shell_integration = "disabled";
} // lib.optionalAttrs pkgs.stdenv.isDarwin { macos_option_as_alt = "both"; };
useSymbolsFromNerdFont = "CaskaydiaCove Nerd Font";
colors = {
enable = true;
dark-name = "rose-pine";
light-name = "rose-pine-dawn";
};
};
programs.fish = {
interactiveShellInit = ''
# Manually enable shell integration
if set -q KITTY_INSTALLATION_DIR
set --global KITTY_SHELL_INTEGRATION enabled
source "$KITTY_INSTALLATION_DIR/shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish"
set --prepend fish_complete_path "$KITTY_INSTALLATION_DIR/shell-integration/fish/vendor_completions.d"
end
set-term-colors
'';
shellAliases = {
s = "kitty +kitten ssh";
e = "edit-in-kitty";
};
functions.set-term-colors = {
body = ''
if test "$term_background" = light
term-light
else
term-dark
end
'';
onVariable = "term_background";
};
};
}

View File

@ -37,6 +37,8 @@
tarsnap tarsnap
# terminal color support testing # terminal color support testing
terminal-colors terminal-colors
# terminal color editing utility
theme-sh
# (La)TeX alternative # (La)TeX alternative
typst typst
# extract RAR archives # extract RAR archives

View File

@ -14,12 +14,5 @@ inputs: self: super: {
ia-writer-family = self.callPackage ./ia-writer-family.nix { ia-writer-family = self.callPackage ./ia-writer-family.nix {
inherit (inputs) ia-writer-family-src; inherit (inputs) ia-writer-family-src;
}; };
mac-app-util = inputs.mac-app-util.packages.${super.stdenv.system}.default.overrideAttrs (old: {
postInstall =
old.postInstall
+ ''
wrapProgram "$out/bin/mac-app-util" --suffix PATH : "${super.jq}/bin"
'';
});
recursive-patched = self.callPackage ./recursive-patched.nix { }; recursive-patched = self.callPackage ./recursive-patched.nix { };
} }