summary refs log tree commit diff
path: root/nixos/modules/services/x11/desktop-managers/gnome.nix
diff options
context:
space:
mode:
authorJan Tojnar <jtojnar@gmail.com>2021-05-07 23:18:14 +0200
committerJan Tojnar <jtojnar@gmail.com>2021-05-08 09:47:42 +0200
commit468cb5980b56d348979488a74a9b5de638400160 (patch)
tree1426485105b897074e82af80efdd545462edb211 /nixos/modules/services/x11/desktop-managers/gnome.nix
parentd03a5eb09720fd6ad670df12d8eafbbfcd7ff494 (diff)
downloadnixpkgs-468cb5980b56d348979488a74a9b5de638400160.tar
nixpkgs-468cb5980b56d348979488a74a9b5de638400160.tar.gz
nixpkgs-468cb5980b56d348979488a74a9b5de638400160.tar.bz2
nixpkgs-468cb5980b56d348979488a74a9b5de638400160.tar.lz
nixpkgs-468cb5980b56d348979488a74a9b5de638400160.tar.xz
nixpkgs-468cb5980b56d348979488a74a9b5de638400160.tar.zst
nixpkgs-468cb5980b56d348979488a74a9b5de638400160.zip
gnome: rename from gnome3
Since GNOME version is now 40, it no longer makes sense to use the old attribute name.
Diffstat (limited to 'nixos/modules/services/x11/desktop-managers/gnome.nix')
-rw-r--r--nixos/modules/services/x11/desktop-managers/gnome.nix560
1 files changed, 560 insertions, 0 deletions
diff --git a/nixos/modules/services/x11/desktop-managers/gnome.nix b/nixos/modules/services/x11/desktop-managers/gnome.nix
new file mode 100644
index 00000000000..d61d6ce50da
--- /dev/null
+++ b/nixos/modules/services/x11/desktop-managers/gnome.nix
@@ -0,0 +1,560 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.xserver.desktopManager.gnome;
+  serviceCfg = config.services.gnome;
+
+  # Prioritize nautilus by default when opening directories
+  mimeAppsList = pkgs.writeTextFile {
+    name = "gnome-mimeapps";
+    destination = "/share/applications/mimeapps.list";
+    text = ''
+      [Default Applications]
+      inode/directory=nautilus.desktop;org.gnome.Nautilus.desktop
+    '';
+  };
+
+  defaultFavoriteAppsOverride = ''
+    [org.gnome.shell]
+    favorite-apps=[ 'org.gnome.Epiphany.desktop', 'org.gnome.Geary.desktop', 'org.gnome.Calendar.desktop', 'org.gnome.Music.desktop', 'org.gnome.Photos.desktop', 'org.gnome.Nautilus.desktop' ]
+  '';
+
+  nixos-gsettings-desktop-schemas = let
+    defaultPackages = with pkgs; [ gsettings-desktop-schemas gnome.gnome-shell ];
+  in
+  pkgs.runCommand "nixos-gsettings-desktop-schemas" { preferLocalBuild = true; }
+    ''
+     mkdir -p $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
+
+     ${concatMapStrings
+        (pkg: "cp -rf ${pkg}/share/gsettings-schemas/*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas\n")
+        (defaultPackages ++ cfg.extraGSettingsOverridePackages)}
+
+     cp -f ${pkgs.gnome.gnome-shell}/share/gsettings-schemas/*/glib-2.0/schemas/*.gschema.override $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
+
+     ${optionalString flashbackEnabled ''
+       cp -f ${pkgs.gnome.gnome-flashback}/share/gsettings-schemas/*/glib-2.0/schemas/*.gschema.override $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
+     ''}
+
+     chmod -R a+w $out/share/gsettings-schemas/nixos-gsettings-overrides
+     cat - > $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas/nixos-defaults.gschema.override <<- EOF
+       [org.gnome.desktop.background]
+       picture-uri='file://${pkgs.nixos-artwork.wallpapers.simple-dark-gray.gnomeFilePath}'
+
+       [org.gnome.desktop.screensaver]
+       picture-uri='file://${pkgs.nixos-artwork.wallpapers.simple-dark-gray-bottom.gnomeFilePath}'
+
+       ${cfg.favoriteAppsOverride}
+
+       ${cfg.extraGSettingsOverrides}
+     EOF
+
+     ${pkgs.glib.dev}/bin/glib-compile-schemas $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas/
+    '';
+
+  flashbackEnabled = cfg.flashback.enableMetacity || length cfg.flashback.customSessions > 0;
+
+  notExcluded = pkg: mkDefault (!(lib.elem pkg config.environment.gnome.excludePackages));
+
+in
+
+{
+
+  meta = {
+    maintainers = teams.gnome.members;
+  };
+
+  imports = [
+    # Added 2021-05-07
+    (mkRenamedOptionModule
+      [ "services" "gnome3" "core-os-services" "enable" ]
+      [ "services" "gnome" "core-os-services" "enable" ]
+    )
+    (mkRenamedOptionModule
+      [ "services" "gnome3" "core-shell" "enable" ]
+      [ "services" "gnome" "core-shell" "enable" ]
+    )
+    (mkRenamedOptionModule
+      [ "services" "gnome3" "core-utilities" "enable" ]
+      [ "services" "gnome" "core-utilities" "enable" ]
+    )
+    (mkRenamedOptionModule
+      [ "services" "gnome3" "core-developer-tools" "enable" ]
+      [ "services" "gnome" "core-developer-tools" "enable" ]
+    )
+    (mkRenamedOptionModule
+      [ "services" "gnome3" "games" "enable" ]
+      [ "services" "gnome" "games" "enable" ]
+    )
+    (mkRenamedOptionModule
+      [ "services" "gnome3" "experimental-features" "realtime-scheduling" ]
+      [ "services" "gnome" "experimental-features" "realtime-scheduling" ]
+    )
+    (mkRenamedOptionModule
+      [ "services" "xserver" "desktopManager" "gnome3" "enable" ]
+      [ "services" "xserver" "desktopManager" "gnome" "enable" ]
+    )
+    (mkRenamedOptionModule
+      [ "services" "xserver" "desktopManager" "gnome3" "sessionPath" ]
+      [ "services" "xserver" "desktopManager" "gnome" "sessionPath" ]
+    )
+    (mkRenamedOptionModule
+      [ "services" "xserver" "desktopManager" "gnome3" "favoriteAppsOverride" ]
+      [ "services" "xserver" "desktopManager" "gnome" "favoriteAppsOverride" ]
+    )
+    (mkRenamedOptionModule
+      [ "services" "xserver" "desktopManager" "gnome3" "extraGSettingsOverrides" ]
+      [ "services" "xserver" "desktopManager" "gnome" "extraGSettingsOverrides" ]
+    )
+    (mkRenamedOptionModule
+      [ "services" "xserver" "desktopManager" "gnome3" "extraGSettingsOverridePackages" ]
+      [ "services" "xserver" "desktopManager" "gnome" "extraGSettingsOverridePackages" ]
+    )
+    (mkRenamedOptionModule
+      [ "services" "xserver" "desktopManager" "gnome3" "debug" ]
+      [ "services" "xserver" "desktopManager" "gnome" "debug" ]
+    )
+    (mkRenamedOptionModule
+      [ "services" "xserver" "desktopManager" "gnome3" "flashback" ]
+      [ "services" "xserver" "desktopManager" "gnome" "flashback" ]
+    )
+    (mkRenamedOptionModule
+      [ "environment" "gnome3" "excludePackages" ]
+      [ "environment" "gnome" "excludePackages" ]
+    )
+  ];
+
+  options = {
+
+    services.gnome = {
+      core-os-services.enable = mkEnableOption "essential services for GNOME3";
+      core-shell.enable = mkEnableOption "GNOME Shell services";
+      core-utilities.enable = mkEnableOption "GNOME core utilities";
+      core-developer-tools.enable = mkEnableOption "GNOME core developer tools";
+      games.enable = mkEnableOption "GNOME games";
+
+      experimental-features = {
+        realtime-scheduling = mkOption {
+          type = types.bool;
+          default = false;
+          description = ''
+            Makes mutter (which propagates to gnome-shell) request a low priority real-time
+            scheduling which is only available on the wayland session.
+            To enable this experimental feature it requires a restart of the compositor.
+            Note that enabling this option only enables the <emphasis>capability</emphasis>
+            for realtime-scheduling to be used. It doesn't automatically set the gsetting
+            so that mutter actually uses realtime-scheduling. This would require adding <literal>
+            rt-scheduler</literal> to <literal>/org/gnome/mutter/experimental-features</literal>
+            with dconf-editor. You cannot use extraGSettingsOverrides because that will only
+            change the default value of the setting.
+
+            Please be aware of these known issues with the feature in nixos:
+            <itemizedlist>
+             <listitem>
+              <para>
+               <link xlink:href="https://github.com/NixOS/nixpkgs/issues/90201">NixOS/nixpkgs#90201</link>
+              </para>
+             </listitem>
+             <listitem>
+              <para>
+               <link xlink:href="https://github.com/NixOS/nixpkgs/issues/86730">NixOS/nixpkgs#86730</link>
+              </para>
+            </listitem>
+            </itemizedlist>
+          '';
+        };
+      };
+    };
+
+    services.xserver.desktopManager.gnome = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Enable Gnome 3 desktop manager.";
+      };
+
+      sessionPath = mkOption {
+        default = [];
+        type = types.listOf types.package;
+        example = literalExample "[ pkgs.gnome.gpaste ]";
+        description = ''
+          Additional list of packages to be added to the session search path.
+          Useful for GNOME Shell extensions or GSettings-conditional autostart.
+
+          Note that this should be a last resort; patching the package is preferred (see GPaste).
+        '';
+        apply = list: list ++ [ pkgs.gnome.gnome-shell pkgs.gnome.gnome-shell-extensions ];
+      };
+
+      favoriteAppsOverride = mkOption {
+        internal = true; # this is messy
+        default = defaultFavoriteAppsOverride;
+        type = types.lines;
+        example = literalExample ''
+          [org.gnome.shell]
+          favorite-apps=[ 'firefox.desktop', 'org.gnome.Calendar.desktop' ]
+        '';
+        description = "List of desktop files to put as favorite apps into gnome-shell. These need to be installed somehow globally.";
+      };
+
+      extraGSettingsOverrides = mkOption {
+        default = "";
+        type = types.lines;
+        description = "Additional gsettings overrides.";
+      };
+
+      extraGSettingsOverridePackages = mkOption {
+        default = [];
+        type = types.listOf types.path;
+        description = "List of packages for which gsettings are overridden.";
+      };
+
+      debug = mkEnableOption "gnome-session debug messages";
+
+      flashback = {
+        enableMetacity = mkEnableOption "the standard GNOME Flashback session with Metacity";
+
+        customSessions = mkOption {
+          type = types.listOf (types.submodule {
+            options = {
+              wmName = mkOption {
+                type = types.str;
+                description = "The filename-compatible name of the window manager to use.";
+                example = "xmonad";
+              };
+
+              wmLabel = mkOption {
+                type = types.str;
+                description = "The pretty name of the window manager to use.";
+                example = "XMonad";
+              };
+
+              wmCommand = mkOption {
+                type = types.str;
+                description = "The executable of the window manager to use.";
+                example = "\${pkgs.haskellPackages.xmonad}/bin/xmonad";
+              };
+            };
+          });
+          default = [];
+          description = "Other GNOME Flashback sessions to enable.";
+        };
+      };
+    };
+
+    environment.gnome.excludePackages = mkOption {
+      default = [];
+      example = literalExample "[ pkgs.gnome.totem ]";
+      type = types.listOf types.package;
+      description = "Which packages gnome should exclude from the default environment";
+    };
+
+  };
+
+  config = mkMerge [
+    (mkIf (cfg.enable || flashbackEnabled) {
+      # Seed our configuration into nixos-generate-config
+      system.nixos-generate-config.desktopConfiguration = [''
+        # Enable the GNOME 3 Desktop Environment.
+        services.xserver.displayManager.gdm.enable = true;
+        services.xserver.desktopManager.gnome.enable = true;
+      ''];
+
+      services.gnome.core-os-services.enable = true;
+      services.gnome.core-shell.enable = true;
+      services.gnome.core-utilities.enable = mkDefault true;
+
+      services.xserver.displayManager.sessionPackages = [ pkgs.gnome.gnome-session.sessions ];
+
+      environment.extraInit = ''
+        ${concatMapStrings (p: ''
+          if [ -d "${p}/share/gsettings-schemas/${p.name}" ]; then
+            export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${p}/share/gsettings-schemas/${p.name}
+          fi
+
+          if [ -d "${p}/lib/girepository-1.0" ]; then
+            export GI_TYPELIB_PATH=$GI_TYPELIB_PATH''${GI_TYPELIB_PATH:+:}${p}/lib/girepository-1.0
+            export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}${p}/lib
+          fi
+        '') cfg.sessionPath}
+      '';
+
+      environment.systemPackages = cfg.sessionPath;
+
+      environment.sessionVariables.GNOME_SESSION_DEBUG = mkIf cfg.debug "1";
+
+      # Override GSettings schemas
+      environment.sessionVariables.NIX_GSETTINGS_OVERRIDES_DIR = "${nixos-gsettings-desktop-schemas}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas";
+
+       # If gnome is installed, build vim for gtk3 too.
+      nixpkgs.config.vim.gui = "gtk3";
+
+      # Install gnome-software if flatpak is enabled
+      services.flatpak.guiPackages = [
+        pkgs.gnome.gnome-software
+      ];
+    })
+
+    (mkIf flashbackEnabled {
+      services.xserver.displayManager.sessionPackages =  map
+        (wm: pkgs.gnome.gnome-flashback.mkSessionForWm {
+          inherit (wm) wmName wmLabel wmCommand;
+        }) (optional cfg.flashback.enableMetacity {
+              wmName = "metacity";
+              wmLabel = "Metacity";
+              wmCommand = "${pkgs.gnome.metacity}/bin/metacity";
+            } ++ cfg.flashback.customSessions);
+
+      security.pam.services.gnome-flashback = {
+        enableGnomeKeyring = true;
+      };
+
+      systemd.packages = with pkgs.gnome; [
+        gnome-flashback
+      ] ++ (map
+        (wm: gnome-flashback.mkSystemdTargetForWm {
+          inherit (wm) wmName;
+        }) cfg.flashback.customSessions);
+
+        # gnome-panel needs these for menu applet
+        environment.sessionVariables.XDG_DATA_DIRS = [ "${pkgs.gnome.gnome-flashback}/share" ];
+        # TODO: switch to sessionVariables (resolve conflict)
+        environment.variables.XDG_CONFIG_DIRS = [ "${pkgs.gnome.gnome-flashback}/etc/xdg" ];
+    })
+
+    (mkIf serviceCfg.core-os-services.enable {
+      hardware.bluetooth.enable = mkDefault true;
+      hardware.pulseaudio.enable = mkDefault true;
+      programs.dconf.enable = true;
+      security.polkit.enable = true;
+      services.accounts-daemon.enable = true;
+      services.dleyna-renderer.enable = mkDefault true;
+      services.dleyna-server.enable = mkDefault true;
+      services.power-profiles-daemon.enable = mkDefault true;
+      services.gnome.at-spi2-core.enable = true;
+      services.gnome.evolution-data-server.enable = true;
+      services.gnome.gnome-keyring.enable = true;
+      services.gnome.gnome-online-accounts.enable = mkDefault true;
+      services.gnome.gnome-online-miners.enable = true;
+      services.gnome.tracker-miners.enable = mkDefault true;
+      services.gnome.tracker.enable = mkDefault true;
+      services.hardware.bolt.enable = mkDefault true;
+      services.packagekit.enable = mkDefault true;
+      services.udisks2.enable = true;
+      services.upower.enable = config.powerManagement.enable;
+      services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center
+
+      xdg.portal.enable = true;
+      xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
+
+      networking.networkmanager.enable = mkDefault true;
+
+      services.xserver.updateDbusEnvironment = true;
+
+      # gnome has a custom alert theme but it still
+      # inherits from the freedesktop theme.
+      environment.systemPackages = with pkgs; [
+        sound-theme-freedesktop
+      ];
+
+      # Needed for themes and backgrounds
+      environment.pathsToLink = [
+        "/share" # TODO: https://github.com/NixOS/nixpkgs/issues/47173
+      ];
+    })
+
+    (mkIf serviceCfg.core-shell.enable {
+      services.colord.enable = mkDefault true;
+      services.gnome.chrome-gnome-shell.enable = mkDefault true;
+      services.gnome.glib-networking.enable = true;
+      services.gnome.gnome-initial-setup.enable = mkDefault true;
+      services.gnome.gnome-remote-desktop.enable = mkDefault true;
+      services.gnome.gnome-settings-daemon.enable = true;
+      services.gnome.gnome-user-share.enable = mkDefault true;
+      services.gnome.rygel.enable = mkDefault true;
+      services.gvfs.enable = true;
+      services.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true));
+      services.telepathy.enable = mkDefault true;
+
+      systemd.packages = with pkgs.gnome; [
+        gnome-session
+        gnome-shell
+      ];
+
+      services.udev.packages = with pkgs.gnome; [
+        # Force enable KMS modifiers for devices that require them.
+        # https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1443
+        mutter
+      ];
+
+      services.avahi.enable = mkDefault true;
+
+      xdg.portal.extraPortals = [
+        pkgs.gnome.gnome-shell
+      ];
+
+      services.geoclue2.enable = mkDefault true;
+      services.geoclue2.enableDemoAgent = false; # GNOME has its own geoclue agent
+
+      services.geoclue2.appConfig.gnome-datetime-panel = {
+        isAllowed = true;
+        isSystem = true;
+      };
+      services.geoclue2.appConfig.gnome-color-panel = {
+        isAllowed = true;
+        isSystem = true;
+      };
+      services.geoclue2.appConfig."org.gnome.Shell" = {
+        isAllowed = true;
+        isSystem = true;
+      };
+
+      fonts.fonts = with pkgs; [
+        cantarell-fonts
+        dejavu_fonts
+        source-code-pro # Default monospace font in 3.32
+        source-sans-pro
+      ];
+
+      # Adapt from https://gitlab.gnome.org/GNOME/gnome-build-meta/blob/gnome-3-38/elements/core/meta-gnome-core-shell.bst
+      environment.systemPackages = with pkgs.gnome; [
+        adwaita-icon-theme
+        gnome-backgrounds
+        gnome-bluetooth
+        gnome-color-manager
+        gnome-control-center
+        gnome-shell
+        gnome-shell-extensions
+        gnome-themes-extra
+        pkgs.gnome-tour # GNOME Shell detects the .desktop file on first log-in.
+        pkgs.nixos-artwork.wallpapers.simple-dark-gray
+        pkgs.nixos-artwork.wallpapers.simple-dark-gray-bottom
+        pkgs.gnome-user-docs
+        pkgs.orca
+        pkgs.glib # for gsettings
+        pkgs.gnome-menus
+        pkgs.gtk3.out # for gtk-launch
+        pkgs.hicolor-icon-theme
+        pkgs.shared-mime-info # for update-mime-database
+        pkgs.xdg-user-dirs # Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
+      ];
+    })
+
+    # Enable soft realtime scheduling, only supported on wayland
+    (mkIf serviceCfg.experimental-features.realtime-scheduling {
+      security.wrappers.".gnome-shell-wrapped" = {
+        source = "${pkgs.gnome.gnome-shell}/bin/.gnome-shell-wrapped";
+        capabilities = "cap_sys_nice=ep";
+      };
+
+      systemd.user.services.gnome-shell-wayland = let
+        gnomeShellRT = with pkgs.gnome; pkgs.runCommand "gnome-shell-rt" {} ''
+          mkdir -p $out/bin/
+          cp ${gnome-shell}/bin/gnome-shell $out/bin
+          sed -i "s@${gnome-shell}/bin/@${config.security.wrapperDir}/@" $out/bin/gnome-shell
+        '';
+      in {
+        # Note we need to clear ExecStart before overriding it
+        serviceConfig.ExecStart = ["" "${gnomeShellRT}/bin/gnome-shell"];
+        # Do not use the default environment, it provides a broken PATH
+        environment = mkForce {};
+      };
+    })
+
+    # Adapt from https://gitlab.gnome.org/GNOME/gnome-build-meta/blob/gnome-3-38/elements/core/meta-gnome-core-utilities.bst
+    (mkIf serviceCfg.core-utilities.enable {
+      environment.systemPackages = (with pkgs.gnome; removePackagesByName [
+        baobab
+        cheese
+        eog
+        epiphany
+        gedit
+        gnome-calculator
+        gnome-calendar
+        gnome-characters
+        gnome-clocks
+        gnome-contacts
+        gnome-font-viewer
+        gnome-logs
+        gnome-maps
+        gnome-music
+        pkgs.gnome-photos
+        gnome-screenshot
+        gnome-system-monitor
+        gnome-weather
+        nautilus
+        pkgs.gnome-connections
+        simple-scan
+        totem
+        yelp
+      ] config.environment.gnome.excludePackages);
+
+      # Enable default program modules
+      # Since some of these have a corresponding package, we only
+      # enable that program module if the package hasn't been excluded
+      # through `environment.gnome.excludePackages`
+      programs.evince.enable = notExcluded pkgs.gnome.evince;
+      programs.file-roller.enable = notExcluded pkgs.gnome.file-roller;
+      programs.geary.enable = notExcluded pkgs.gnome.geary;
+      programs.gnome-disks.enable = notExcluded pkgs.gnome.gnome-disk-utility;
+      programs.gnome-terminal.enable = notExcluded pkgs.gnome.gnome-terminal;
+      programs.seahorse.enable = notExcluded pkgs.gnome.seahorse;
+      services.gnome.sushi.enable = notExcluded pkgs.gnome.sushi;
+
+      # Let nautilus find extensions
+      # TODO: Create nautilus-with-extensions package
+      environment.sessionVariables.NAUTILUS_EXTENSION_DIR = "${config.system.path}/lib/nautilus/extensions-3.0";
+
+      # Override default mimeapps for nautilus
+      environment.sessionVariables.XDG_DATA_DIRS = [ "${mimeAppsList}/share" ];
+
+      environment.pathsToLink = [
+        "/share/nautilus-python/extensions"
+      ];
+    })
+
+    (mkIf serviceCfg.games.enable {
+      environment.systemPackages = (with pkgs.gnome; removePackagesByName [
+        aisleriot
+        atomix
+        five-or-more
+        four-in-a-row
+        gnome-chess
+        gnome-klotski
+        gnome-mahjongg
+        gnome-mines
+        gnome-nibbles
+        gnome-robots
+        gnome-sudoku
+        gnome-taquin
+        gnome-tetravex
+        hitori
+        iagno
+        lightsoff
+        quadrapassel
+        swell-foop
+        tali
+      ] config.environment.gnome.excludePackages);
+    })
+
+    # Adapt from https://gitlab.gnome.org/GNOME/gnome-build-meta/-/blob/3.38.0/elements/core/meta-gnome-core-developer-tools.bst
+    (mkIf serviceCfg.core-developer-tools.enable {
+      environment.systemPackages = (with pkgs.gnome; removePackagesByName [
+        dconf-editor
+        devhelp
+        pkgs.gnome-builder
+        # boxes would make sense in this option, however
+        # it doesn't function well enough to be included
+        # in default configurations.
+        # https://github.com/NixOS/nixpkgs/issues/60908
+        /* gnome-boxes */
+      ] config.environment.gnome.excludePackages);
+
+      services.sysprof.enable = true;
+    })
+  ];
+
+}