#!/bin/bash


# Zerocat Hyperbola Setup --- Get the Hyperbola Operating System installed.
#
# Copyright (C) 2021, 2022  Kai Mertens <kmx@posteo.net>
#
# This file is part of Zerocat Hyperbola Setup.
#
# Zerocat Hyperbola Setup is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# Zerocat Hyperbola Setup is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Zerocat Hyperbola Setup.  If not, see <http://www.gnu.org/licenses/>.


# Thanks
# ======
#
# This script comes with special thanks to Hyperbola’s developers
# André (Emulatorman) and Tobias (Throgh), who helped to get started with
# essential configuration files.


# Usage
# =====
#
# This script will help you to install the Hyperbola GNU/Linux-libre
# System on a Corebooted Zerocat Machine with GRUB2 as a Payload:
#
# 1.  get the ISO-image
#
#     Website:   <https://wiki.hyperbola.info/doku.php?id=en:project:downloads&redirect=1>  
#     ISO file:  `https://repo.hyperbola.info/other/live_images/gnu-plus-linux-libre/hyperbola-milky-way-latest/hyperbola-milky-way-v0.4-dual.iso.torrent`  
#
# 2.  boot into the live session, adapt keymap and font, e.g.:
#
#     loadkeys de
#     setfont eurlatgr
#
# 3.  set up an internet connection, e.g.:
#
#     ip link set wlp2s0 up
#     wpa_supplicant -B -i wlp2s0 -c <(wpa_passphrase "SSID" "psk")
#     dhcpcd wlp2s0
#     ip a
#
# 4.  run this script from thumbdrive, e.g.:
#
#     mkdir thumbdrive
#     lsblk
#     mount /dev/sdc1 thumbdrive
#     ./thumbdrive/setup-hyperbola.sh
#
# 5.  reboot
#
#     halt
#     ...then power on again.
#
# This script is a reviewed and (hopefully) improved version of the
# original Parabola Installation CLI, checked out at:
#
# <git://git.parabola.nu/packages/parabolaiso.git>
#
#     tag name v46.1 (f29d8dafa7e2a3f2010909ffd96bb899f25ccacb)
#     tag date 2020-08-03 13:12:27 -0400
#     tagged by David P <megver83@parabola.nu>
#     commit 231f35c3c4ae7a1cf073e67f6ae091d1f1053a7c
#
# Within the parabolaiso repository, see AUTHORS.rst and LICENSE for
# proper authorship and license of the original sources, e.g.:
#
# <parabolaiso/configs/lxde-openrc/airootfs/root/.scriptsInstallation/language/en/install.sh>  
# <parabolaiso/configs/lxde-openrc/airootfs/root/.scriptsInstallation/language/en/systemConfig.sh>  
# <parabolaiso/configs/lxde-openrc/airootfs/root/.scriptsInstallation/language/en/userAccount.sh>  
# <parabolaiso/configs/lxde-openrc/airootfs/root/.scriptsInstallation/x11.sh>  


welcome() {

  $DIALOG ${FLAGS_DIALOG[@]} \
    --msgbox \
      "\
                                                                            \n\
# Welcome                                                                   \n\
                                                                            \n\
This is Zerocat’s install script for Hyperbola GNU/Linux-libre. \
It should be run on a fresh boot of the Hyperbola Live System. \
Please activate an internet connection, first.                              \n\
                                                                            \n\
# WWW Resources                                                             \n\
                                                                            \n\
* Website:  https://wiki.hyperbola.info/doku.php?id=en:project:downloads&redirect=1                                                                     \n\
* ISO:      https://repo.hyperbola.info/other/live_images/gnu-plus-linux-libre/hyperbola-milky-way-latest/hyperbola-milky-way-v0.4-dual.iso.torrent     \n\
                                                                            \n\
Good Luck! – www.zerocat.org                                                \n\
" \
      ${WIDGET_DIM};
}

fillscreen() {
  # Fill stdout with empty lines such that dialog and script output
  # won't overlap.

  echo "Fill screen ..."
  echo -e \
    "\n\n\n\n\n\n\n\n\n\n" \
    "\n\n\n\n\n\n\n\n\n\n" \
    "\n\n\n\n\n\n\n\n\n\n" \
    "\n\n\n\n\n\n\n\n\n\n" \
    "\n\n\n\n\n\n\n\n\n\n";
  echo "... done."
}

checkperm() {
  echo "Check priviledges ..."
  if [ "$EUID" -ne 0 ]; then
    echo "This script requires root priviledges."
    exit 1
  fi
  echo "... done."
}

notool() {
  # $1: tool name
  # let’s use builtin echo command here:
  echo "Tool $1 is missing."
  exit 1
}

hitenter() {

  # positional parameter

  # locals
  local key=''

  read \
    -p'Hit any key to continue, <ESC> to abort: ' \
    -N1 \
    -r \
    -s \
      key
  [ "$key" == $'\e' ] && {
    echo
    return 1
  }
  echo
  echo
  return 0
}

set_DISK_SYSTEM() {

  # positional parameter

  # local vars
  local i
  local -i n=1
  local -a list_of_disks=()
  local -a menulist_disk=()
  local feedback

  # collect available disks
  list_of_disks=( \
    $( \
      udevadm settle && \
      lsblk -n --nodeps -oPATH,TYPE | \
      egrep disk | \
      cut -f1 -d' ' - \
    ) \
  )

  # select a disk
  for i in "${list_of_disks[@]}"; do
    menulist_disk+=("${n}" "${i}")
    n+=1
  done
  feedback=$( \
    $DIALOG ${FLAGS_DIALOG[@]} \
      --cancel-label "Abort" \
      --menu "Select Disk" ${MENUWIDGET_DIM} "${menulist_disk[@]}" \
  )
  case $? in
    0)
      DISK_SYSTEM=${menulist_disk[$((feedback*2-1))]}
      FLAG_DISK='on'
      $DIALOG ${FLAGS_DIALOG[@]} \
        --msgbox "Selected Disk is: ${DISK_SYSTEM}" ${WIDGET_DIM}
      ;;
    *)
      echo; echo;
      abort
      ;;
  esac
}

unset_DISK_SYSTEM() {

  # positional parameter

  # locals

  DISK_SYSTEM=''
  FLAG_DISK=''
}

open_encryption() {

  # positional parameter

  # locals
  local -r -a crypto_LUKS=( \
    $( \
      lsblk -n -oPATH,FSTYPE | \
      egrep ${DISK_SYSTEM} | \
      egrep crypto_LUKS | \
      cut -f1 -d' ' - \
    ) \
  )
  local n

  for n in "${crypto_LUKS[@]}"; do
    cryptsetup luksOpen "${n}" "${n##*/}${CRYPT_SUFFIX}"
  done
}

assign_mountpoints() {

  # positional parameter

  # locals
  local i
  local -i n
  local -a list_of_vol
  local -a menulist_vol
  local feedback
  local partition
  local mountpoint

  # dismount
  dismount_mountpoints

  while [ true ]; do
    # update list of volumes
    list_of_vol=( \
      $(echo \
"$( \
  udevadm settle && \
  lsblk -n -oPATH,TYPE,PARTTYPENAME,FSTYPE,MOUNTPOINT,SIZE | \
  egrep "${DISK_SYSTEM##*/}" | \
  egrep -v Extended | \
  egrep -v crypto_LUKS | \
  egrep -e 'part|crypt' | \
  $SED -r -e 's/ /·/g;' - \
)" ) \
    )

    # set menu list
    n=1
    menulist_vol=()
    for i in "${list_of_vol[@]}"; do
      menulist_vol+=("${n}" "${i//·/ }")
      n+=1
    done

    feedback=$( \
      $DIALOG ${FLAGS_DIALOG[@]} \
        --ok-label "Select" \
        --extra-button --extra-label "Done" \
        --cancel-label "Abort" \
        --menu "Select a Partition of Disk \`$DISK_SYSTEM' and assign a mountpoint ...\nFirst select one intended for mountpoint “/mnt/”, then optionally assign subordinary mountpoints to other partitions.\nNote swap formatted partitions can be used for unencrypted [SWAP] only.\nPlease select your Swap carefully, the script does not yet provide a type check." ${MENUWIDGET_DIM} "${menulist_vol[@]}" \
    )
    case $? in
      0)
        partition="${menulist_vol[$((feedback*2-1))]%% *}"
        for i in ${partitions_processed[@]}; do
          [ "$i" == "$partition" ] && {
            $DIALOG ${FLAGS_DIALOG[@]} \
              --msgbox "Partition \`$i' is already used." ${WIDGET_DIM}
            continue 2
          }
        done
        feedback=$( \
          $DIALOG ${FLAGS_DIALOG[@]} \
            --menu "Assign a Mountpoint to Partition \`$partition'" ${MENUWIDGET_DIM} "${menulist_mountpoint[@]}" \
        )
        case $? in
          0)    # OK button
            mountpoint="${menulist_mountpoint[$((feedback*2-1))]}"
            for i in ${mountpoints_assigned[@]}; do
              [ "$i" == "$mountpoint" ] && {
                $DIALOG ${FLAGS_DIALOG[@]} \
                  --msgbox "Mountpoint \`$i' is already assigned." ${WIDGET_DIM}
                continue 2
              }
            done
            if [ "$mountpoint" == '/mnt/' -o -n "$FLAG_ROOT" ]; then
              case "$mountpoint" in
                '[SWAP]')
                  swapon $partition
                  ;;
                '/mnt/')
                  parted -s $DISK_SYSTEM -- set $(echo $partition | $SED -r -e 's/([a-zA-Z_/-]*)([0-9]+)(.*)/\2/;' -) boot on &> /dev/null
                  mount $partition /mnt &> /dev/null
                  FLAG_ROOT='on'
                  ;;
                '/mnt/usr'|'/mnt/usr/local')
                  mkdir -p ${mountpoint%/} &> /dev/null
                  mount $partition ${mountpoint%/}
                  FLAG_USR='on'
                  ;;
                '/mnt/boot')
                  parted -s $DISK_SYSTEM -- set $(echo $partition | $SED -r -e 's/([a-zA-Z_/-]*)([0-9]+)(.*)/\2/;' -) boot on &> /dev/null
                  mkdir -p ${mountpoint%/} &> /dev/null
                  mount $partition ${mountpoint%/}
                  cd ${mountpoint%/} && ln -sf . boot && cd - &> /dev/null
                  ;;
                *)
                  mkdir -p ${mountpoint%/} &> /dev/null
                  mount $partition ${mountpoint%/}
                  ;;
              esac
              partitions_processed+=("$partition")
              mountpoints_assigned+=("$mountpoint")
              if [ "${partition##*_}" == 'crypt' ]; then
                FLAG_CRYPT='on'
                FLAG_PLAIN=''
                if [ "$mountpoint" == '/mnt/' ]; then
                  echo; echo;
                  echo "Creating Swapfile ..."
                  dd if=/dev/zero of=/mnt/swapfile bs=1MiB count=2048 &> /dev/null
                  chmod 0600 /mnt/swapfile &> /dev/null
                  mkswap /mnt/swapfile &> /dev/null
                  swapon /mnt/swapfile &> /dev/null
                  echo "... Swapfile created."
                  hitenter || abort
                fi
              fi
            else
              $DIALOG ${FLAGS_DIALOG[@]} \
                --msgbox "You must assign a partition to the \`/mnt/' mountpoint, first." ${WIDGET_DIM}
            fi
            ;;
        esac
        ;;
      3)
        [ -n "$FLAG_ROOT" ] && {
          echo; echo;
          break
        }
        ;;
      *)
        echo; echo;
        abort
        ;;
    esac
  done
}

disk_operations() {

  # positional parameter

  # locals (cryptsetup parameter)
  local -r   cipher='aes-xts-plain64'
  local -r  keysize='512'
  local -r hashtype='sha256'
  local -r itertime='500'
  local -r lukstype='luks1'

  # locals
  local feedback
  local -a menulist_operation=(
    1   "Wipe Disk with Zeros"
    2   "New Scheme: [MSDOS [2GB-SWAP] [xGB(ext4)]]"
    3   "New Scheme: [MSDOS [20GB(ext4)] [2GB-SWAP] [xGB(ext4)]]"
    4   "New Scheme: [MSDOS [20GB(ext4)] [10GB(ext4)] [2GB-SWAP] [xGB(ext4)]]"
    5   "New Scheme: [MSDOS [xGB(${lukstype^^}(ext4))]]"
    6   "Select Partitions, assign Mountpoints"
  )

  # disk operations
  while [ true ]; do
    feedback=$( \
      $DIALOG ${FLAGS_DIALOG[@]} \
        --cancel-label "Abort" \
        ${FLAG_ROOT:+--extra-button --extra-label "Done"} \
        ${FLAG_ROOT:+--default-button extra} \
        --menu "Disk Operations on Disk \`$DISK_SYSTEM'\nATTENTION! Your data is likely to be erased!" ${MENUWIDGET_DIM} "${menulist_operation[@]}"
    )
    case $? in
      0)
        case $feedback in
          1)
            $DIALOG ${FLAGS_DIALOG[@]} \
              --default-button no \
              --yesno "Disk Operation on Disk \`$DISK_SYSTEM': \`${menulist_operation[$((feedback*2-1))]}'\n\nThis will take some time, sure to proceed?" ${WIDGET_DIM}
            case $? in
              0)
                # Add space on screen
                echo; echo;
                echo "Starting job \`${menulist_operation[$((feedback*2-1))]}' ..."
                sleep $PROCESS_DELAY

                # Free up mountpoints
                dismount_mountpoints

                # Wipe disk
                echo "Wiping disk with zeros ..." && \
                dd if=/dev/zero of=$DISK_SYSTEM bs=1MiB status=progress || \
                  catch_error

                # Wait for user to acknowledge
                echo "... done with job \`${menulist_operation[$((feedback*2-1))]}'"
                hitenter || abort
                ;;
            esac
            ;;
          2)
            $DIALOG ${FLAGS_DIALOG[@]} \
              --default-button no \
              --yesno "Disk Operation on Disk \`$DISK_SYSTEM': \`${menulist_operation[$((feedback*2-1))]}'\n\nSure to proceed?" ${WIDGET_DIM}
            case $? in
              0)
                # Add space on screen
                echo; echo;
                echo "Starting job \`${menulist_operation[$((feedback*2-1))]}' ..."
                sleep $PROCESS_DELAY

                # Free up mountpoints
                dismount_mountpoints

                # Create msdos partition table
                # Create partitions, e.g.: [SWAP] + /
                # Format partitions
                echo "Wipe old partition headers ..." && \
                dd if=/dev/zero of=$DISK_SYSTEM bs=1MiB seek=1 count=${MiB_initial_wipe} && \
                dd if=/dev/zero of=$DISK_SYSTEM bs=1MiB seek=2000 count=${MiB_initial_wipe} && \
                echo "Write MSDOS partition table ..." && \
                parted -s $DISK_SYSTEM -- mklabel msdos && \
                echo "Create partitions ..." && \
                parted -s $DISK_SYSTEM -- mkpart primary 1MiB 2000MiB mkpart primary 2000MiB -1s && \
                echo "Make swap space ..." && \
                (echo t; echo 1; echo 82; echo w) | fdisk $DISK_SYSTEM && \
                mkswap ${DISK_SYSTEM}1 && \
                echo "Create filesystem ..." && \
                mkfs.ext4 ${DISK_SYSTEM}2 && \
                echo "Partitions are now ready to be mounted." || \
                  catch_error

                # Wait for user to acknowledge
                echo "... done with job \`${menulist_operation[$((feedback*2-1))]}'"
                hitenter || abort
                ;;
            esac
            ;;
          3)
            $DIALOG ${FLAGS_DIALOG[@]} \
              --default-button no \
              --yesno "Disk Operation on \`$DISK_SYSTEM': \`${menulist_operation[$((feedback*2-1))]}'\n\nSure to proceed?" ${WIDGET_DIM}
            case $? in
              0)
                # Add space on screen
                echo; echo;
                echo "Starting job \`${menulist_operation[$((feedback*2-1))]}' ..."
                sleep $PROCESS_DELAY

                # Free up mountpoints
                dismount_mountpoints

                # Create msdos partition table
                # Format Disk, e.g.: / + [SWAP] + /home
                # Format partitions
                echo "Wipe old partition headers ..." && \
                dd if=/dev/zero of=$DISK_SYSTEM bs=1MiB seek=1 count=${MiB_initial_wipe} && \
                dd if=/dev/zero of=$DISK_SYSTEM bs=1MiB seek=20000 count=${MiB_initial_wipe} && \
                dd if=/dev/zero of=$DISK_SYSTEM bs=1MiB seek=22000 count=${MiB_initial_wipe} && \
                echo "Write MSDOS partition table ..." && \
                parted -s $DISK_SYSTEM -- mklabel msdos && \
                echo "Create partitions ..." && \
                parted -s $DISK_SYSTEM -- mkpart primary 1MiB 20000MiB mkpart primary 20000MiB 22000MiB mkpart primary 22000MiB -1s && \
                echo "Create swap space ..." && \
                (echo t; echo 2; echo 82; echo w) | fdisk $DISK_SYSTEM && \
                mkswap ${DISK_SYSTEM}2 && \
                echo "Create filesystems ..." && \
                mkfs.ext4 ${DISK_SYSTEM}1 && \
                mkfs.ext4 ${DISK_SYSTEM}3 && \
                echo "Partitions are now ready to be mounted." || \
                  catch_error

                # Hit key
                echo "... done with job \`${menulist_operation[$((feedback*2-1))]}'"
                hitenter || abort
            esac
            ;;
          4)
            $DIALOG ${FLAGS_DIALOG[@]} \
              --default-button no \
              --yesno "Disk Operation on \`$DISK_SYSTEM': \`${menulist_operation[$((feedback*2-1))]}'\n\nSure to proceed?" ${WIDGET_DIM}
            case $? in
              0)
                # Add space on screen
                echo; echo;
                echo "Starting job \`${menulist_operation[$((feedback*2-1))]}' ..."
                sleep $PROCESS_DELAY

                # Free /mnt
                dismount_mountpoints

                # Create msdos partition table
                # Format Disk, e.g.: / + /tmp + [SWAP] + /home
                # Format partitions
                echo "Wipe old partition headers ..." && \
                dd if=/dev/zero of=$DISK_SYSTEM bs=1MiB seek=1 count=${MiB_initial_wipe} && \
                dd if=/dev/zero of=$DISK_SYSTEM bs=1MiB seek=20000 count=${MiB_initial_wipe} && \
                dd if=/dev/zero of=$DISK_SYSTEM bs=1MiB seek=30000 count=${MiB_initial_wipe} && \
                dd if=/dev/zero of=$DISK_SYSTEM bs=1MiB seek=32000 count=${MiB_initial_wipe} && \
                echo "Write MSDOS partition table ..." && \
                parted -s $DISK_SYSTEM -- mklabel msdos && \
                echo "Create partitions ..." && \
                parted -s $DISK_SYSTEM -- mkpart primary 1MiB 20000MiB mkpart primary 20000MiB 30000MiB mkpart primary 30000MiB 32000MiB mkpart primary 32000MiB -1s && \
                echo "Create swap space ..." && \
                (echo t; echo 3; echo 82; echo w) | fdisk $DISK_SYSTEM && \
                mkswap ${DISK_SYSTEM}3 && \
                echo "Create filesystems ..." && \
                mkfs.ext4 ${DISK_SYSTEM}1 && \
                mkfs.ext4 ${DISK_SYSTEM}2 && \
                mkfs.ext4 ${DISK_SYSTEM}4 && \
                echo "Partitions are now ready to be mounted." || \
                  catch_error

                # Hit key
                echo "... done with job \`${menulist_operation[$((feedback*2-1))]}'"
                hitenter || abort
            esac
            ;;
          5)
            $DIALOG ${FLAGS_DIALOG[@]} \
              --default-button no \
              --yesno "Disk Operation on \`$DISK_SYSTEM': \`${menulist_operation[$((feedback*2-1))]}'\n\nSure to proceed?" ${WIDGET_DIM}
            case $? in
              0)
                # Add space on screen
                echo; echo;
                echo "Starting job \`${menulist_operation[$((feedback*2-1))]}' ..."
                sleep $PROCESS_DELAY

                # Free /mnt
                dismount_mountpoints

                # Create msdos partition table
                # Format Disk, e.g.: /
                # Setup encryption
                # Open encryption
                # Format partition
                # Close encryption
                echo "Wipe old partition header ..." && \
                dd if=/dev/zero of=$DISK_SYSTEM bs=1MiB seek=1 count=${MiB_initial_wipe} && \
                echo "Write MSDOS partition table ..." && \
                parted -s $DISK_SYSTEM -- mklabel msdos && \
                echo "Create partition ..." && \
                parted -s $DISK_SYSTEM -- mkpart primary 1MiB -1s && \
                echo "Create LUKS header ..." && \
                cryptsetup -v \
                  --cipher ${cipher} \
                  --key-size ${keysize} \
                  --hash ${hashtype} \
                  --iter-time ${itertime} \
                  --use-random \
                  --type ${lukstype} \
                    luksFormat ${DISK_SYSTEM}1 && \
                echo "Open encryption ..." && \
                cryptsetup luksOpen ${DISK_SYSTEM}1 "${DISK_SYSTEM##*/}1${CRYPT_SUFFIX}" && \
                echo "Create filesystem ..." && \
                mkfs.ext4 /dev/mapper/"${DISK_SYSTEM##*/}1${CRYPT_SUFFIX}" && \
                echo "Store disk passphrase at a save place." && \
                sleep $PROCESS_DELAY && \
                cryptsetup luksClose "${DISK_SYSTEM##*/}1${CRYPT_SUFFIX}" || \
                  catch_error

                # Hit key
                echo "... done with job \`${menulist_operation[$((feedback*2-1))]}'"
                hitenter || abort
            esac
            ;;
          6)
            # Add space on screen
            echo; echo;
            echo "Starting job \`${menulist_operation[$((feedback*2-1))]}' ..."
            sleep $PROCESS_DELAY

            open_encryption
            assign_mountpoints

            # Hit key
            echo "... done with job \`${menulist_operation[$((feedback*2-1))]}'"
            hitenter || abort
            ;;
        esac
        ;;
      3)    # extra button
        [ -n "$FLAG_ROOT" ] && {
          echo; echo;
          break
        }
        ;;
      *)
        echo; echo;
        abort
        ;;
    esac
  done
}

write_touchpad_config() {

  # Write synaptic touchpad configuration file
  echo "Section \"InputClass\""                                      > /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  Identifier      \"laplet touchpad\""                      >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  MatchIsTouchpad \"yes\""                                  >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  Driver          \"synaptics\""                            >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  Option          \"ClickPad\"              \"yes\""        >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  Option          \"HorizEdgeScroll\"       \"yes\""        >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  Option          \"LockedDrags\"           \"no\""         >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  Option          \"PalmDetect\"            \"yes\""        >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  Option          \"PalmMinWidth\"          \"8\""          >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  Option          \"PalmMinZ\"              \"100\""        >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  Option          \"Protocol\"              \"auto-dev\""   >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  Option          \"TapButton1\"            \"1\""          >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  Option          \"TapButton2\"            \"3\""          >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  Option          \"TapButton3\"            \"2\""          >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  Option          \"TouchpadOff\"           \"0\""          >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "  Option          \"VertEdgeScroll\"        \"yes\""        >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf
  echo "EndSection" >> /mnt/etc/X11/xorg.conf.d/00-touchpad.conf

}

enable_services_OpenRC() {

  # Precondition: Folder /mnt must refer to a mounted partition.

  # locals
  local tmpfile=/mnt/servicesOpenRC.sh

  # Enable services with OpenRC
  echo "#!/bin/bash                                                               " >  "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "notool() {                                                                " >> "$tmpfile"
  echo "  local -r tool=\"\$1\"                                                   " >> "$tmpfile"
  echo "  echo \"Missing tool in chroot environment: \$tool\"                     " >> "$tmpfile"
  echo "  exit 1                                                                  " >> "$tmpfile"
  echo "}                                                                         " >> "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "# tool check                                                              " >> "$tmpfile"
  echo "[ -z \"\$(command -v rc-update)\" ] && notool 'rc-update'                 " >> "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "rc-update add dhcpcd default                                              " >> "$tmpfile"
  chroot_exec "$tmpfile" || catch_error
}

chroot_exec() {

  # Precondition: Folder /mnt must refer to a mounted partition.

  # positional parameter
  local -r scriptfile="$1"

  # locals
  local errstat

  chmod u+x "${scriptfile}"
  arch-chroot /mnt "/${scriptfile##*/}"
  errstat=$?
  rm -f "${scriptfile}"

  return $errstat
}

set_password() {

  # positional parameter
  local -r algo="$1"
  local -r user="$2"
  local -r priviledged="$3"

  # locals
  local -r tmpfile="/mnt/setPassword.sh"
  local feedback1
  local feedback2

  while [ true ]; do
    feedback1=$( \
      $DIALOG ${FLAGS_DIALOG[@]} \
        --cancel-label "Disable" \
        --quoted --passwordbox "Enter Password for User \`${user}'. Characters will not be displayed." ${WIDGET_DIM} \
    )
    case $? in
      0)
        feedback2=$( \
          $DIALOG ${FLAGS_DIALOG[@]} \
            --quoted --passwordbox "Repeat Password for User \`${user}'. Characters will not be displayed." ${WIDGET_DIM} \
        )
        case $? in
          0)
            if [ -z "${feedback1}" -o "${feedback1}" != "${feedback2}" ]; then
              $DIALOG ${FLAGS_DIALOG[@]} \
                --msgbox "Password not valid, try again!" ${WIDGET_DIM}
            else
              echo; echo;
              echo "#!/bin/bash                                                               " >  "$tmpfile"
              echo "                                                                          " >> "$tmpfile"
              echo "notool() {                                                                " >> "$tmpfile"
              echo "  local -r tool=\"\$1\"                                                   " >> "$tmpfile"
              echo "  echo \"Missing tool in chroot environment: \$tool\"                     " >> "$tmpfile"
              echo "  exit 1                                                                  " >> "$tmpfile"
              echo "}                                                                         " >> "$tmpfile"
              echo "                                                                          " >> "$tmpfile"
              echo "# tool check                                                              " >> "$tmpfile"
              echo "[ -z \"\$(command -v usermod)\" ] && notool 'usermod'                     " >> "$tmpfile"
              echo "                                                                          " >> "$tmpfile"
              echo "usermod                                                                 \\" >> "$tmpfile"
              echo "  -p \$(openssl passwd ${algo} \"${feedback1}\")                        \\" >> "$tmpfile"
              echo "    ${user}                                                               " >> "$tmpfile"
              chroot_exec "$tmpfile" || abort
              [ "$user" == "$user_root" -o -n "$priviledged" ] && FLAG_ADMIN='on'
              break
            fi
            ;;
          *)
            $DIALOG ${FLAGS_DIALOG[@]} \
              --msgbox "Try again!" ${WIDGET_DIM}
            ;;
        esac
        ;;
      *)
        [ "$user" == "$user_root" ]
          continue;

        $DIALOG ${FLAGS_DIALOG[@]} \
          --msgbox "Password disabled." ${WIDGET_DIM}
        echo; echo;
        break
        ;;
    esac
  done
}

add_user_account() {

  # positional parameter
  local -r algo="$1"

  # locals
  local feedback
  local tmpfile=/mnt/newUserAccount.sh
  local priviledged=''
  local -a list_of_new_users=()

  while [ true ]; do
    $DIALOG ${FLAGS_DIALOG[@]} \
      --extra-button \
      --extra-label "Standard" \
      --ok-label "Priviledged" \
      --cancel-label "No" \
      --yesno "Current List of New Users:\n\`${list_of_new_users[*]}'\n\nCreate a new User Account?" ${WIDGET_DIM}
    case $? in
      0)
        priviledged='on'
        ;&
      3)
        feedback=$(\
          $DIALOG ${FLAGS_DIALOG[@]} \
            --inputbox "Enter Username\nAllowed characters are: lower case letters, numbers, underscore, hyphen, a final dolar sign" ${WIDGET_DIM} \
        )
        case $? in
          0)
            echo; echo;
            if [  -z "${feedback}" -o \
                  -n "`echo ${feedback} | $SED -r -e '/.{33,}/!d;' -`" -o \
                  -n "`echo ${feedback} | $SED -r -e '/^[a-z_][0-9a-z_-]*[$]?$/d;' -`" \
            ]; then
              $DIALOG ${FLAGS_DIALOG[@]} \
                --msgbox "Not a valid username!" ${WIDGET_DIM}
            else
              ( \
                echo "#!/bin/bash                                                                   " >  "$tmpfile"
                echo "                                                                              " >> "$tmpfile"
                echo "notool() {                                                                    " >> "$tmpfile"
                echo "  local -r tool=\"\$1\"                                                       " >> "$tmpfile"
                echo "  echo \"Missing tool in chroot environment: \$tool\"                         " >> "$tmpfile"
                echo "  exit 1                                                                      " >> "$tmpfile"
                echo "}                                                                             " >> "$tmpfile"
                echo "                                                                              " >> "$tmpfile"
                echo "# tool check                                                                  " >> "$tmpfile"
                echo "[ -z \"\$(command -v useradd)\" ] && notool 'useradd'                         " >> "$tmpfile"
                echo "                                                                              " >> "$tmpfile"
                echo "useradd                                                                     \\" >> "$tmpfile"
                echo "  --comment ${feedback^}                                                    \\" >> "$tmpfile"
                echo "  --create-home                                                             \\" >> "$tmpfile"
                echo "  --no-user-group                                                           \\" >> "$tmpfile"
                echo "  -g users                                                                  \\" >> "$tmpfile"
                echo "  -G ${priviledged:+wheel,}video,audio,sys,storage,optical,power,network    \\" >> "$tmpfile"
                echo "    ${feedback};                                                              " >> "$tmpfile"
              ) && \
              chroot_exec "$tmpfile" && \
              list_of_new_users+=("${feedback}") && \
              $DIALOG ${FLAGS_DIALOG[@]} \
                --msgbox "User \`${feedback}'${priviledged:+, priviledged,} successfully created." ${WIDGET_DIM} && \
              set_password "${openssl_passwd_algo}" "${feedback}" "${priviledged}" || \
                catch_error
            fi
            priviledged=''
            ;;
          *)
            ;;
        esac
        ;;
      *)
        [ -n "$FLAG_ADMIN" ] && {
          echo; echo;
          break
        }
        $DIALOG ${FLAGS_DIALOG[@]} \
          --msgbox "At least one new, priviledged user must be set up." ${WIDGET_DIM}
        ;;
    esac
  done
}

set_hostname_OpenRC() {

  # positional parameter
  local -r new_hostname="$1"

  # edit /etc/hostname
  $SED -r -i \
    -e "s|hyperbola|${new_hostname}|;" \
      /mnt/etc/hostname;

  # edit /etc/hosts
  $SED -r -i \
    -e "s/localhost$/& ${new_hostname}/;" \
      /mnt/etc/hosts;
}

set_localtime() {

  # positional parameter
  local -r new_timezone="$1"

  ln \
    -sf \
      /mnt/usr/share/zoneinfo/"${new_timezone}" /mnt/etc/localtime
}

install_packages() {

  # positional parameter
  local -r set_of_packages="$1"

  # locals
  local tmpfile=/mnt/installPackages.sh

  echo "#!/bin/bash                                                               " >  "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "notool() {                                                                " >> "$tmpfile"
  echo "  local -r tool=\"\$1\"                                                   " >> "$tmpfile"
  echo "  echo \"Missing tool in chroot environment: \$tool\"                     " >> "$tmpfile"
  echo "  exit 1                                                                  " >> "$tmpfile"
  echo "}                                                                         " >> "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "# tool check                                                              " >> "$tmpfile"
  echo "[ -z \"\$(command -v pacman)\" ] && notool 'pacman'                       " >> "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "pacman -S ${set_of_packages}                                            \\" >> "$tmpfile"
  echo "  --confirm                                                               " >> "$tmpfile"
  chroot_exec "$tmpfile" || catch_error
}

make_initramfs() {

  # locals
  local tmpfile=/mnt/makeInitramfs.sh

  echo "#!/bin/bash                                                               " >  "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "notool() {                                                                " >> "$tmpfile"
  echo "  local -r tool=\"\$1\"                                                   " >> "$tmpfile"
  echo "  echo \"Missing tool in chroot environment: \$tool\"                     " >> "$tmpfile"
  echo "  exit 1                                                                  " >> "$tmpfile"
  echo "}                                                                         " >> "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "# tool check                                                              " >> "$tmpfile"
  echo "[ -z \"\$(command -v mkinitcpio)\" ] && notool 'mkinitcpio'               " >> "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "mkinitcpio                                                              \\" >> "$tmpfile"
  echo "  -p linux-libre-lts                                                          " >> "$tmpfile"
  chroot_exec "$tmpfile" || abort
}

gen_locales() {

  # positional parameter
  local -r -a default_locales=("$@")

  # locals
  local aux
  local i
  local -a checklist_locale=()
  local feedback
  local -a record=()
  local cfgfile=/mnt/etc/locale.gen
  local tmpfile=/mnt/genLocales.sh
  local bakfile="${cfgfile}.bak"

  cp "$cfgfile" "$bakfile"

  for i in $($SED -r -e '/^#[ ]|^#$/d;s/^#//;s/[ \t]*$//;s/ /#/g;' $cfgfile); do
    checklist_locale+=("${i//\#/ }" "${i//\#/ }" "off")
  done

  feedback=$( \
    $DIALOG ${FLAGS_DIALOG[@]} \
      --cancel-label "Abort" \
      --checklist \
        "Select Locales\nDefaulting to: \`${default_locales[*]/%/ }'" \
        ${MENUWIDGET_DIM} \
        "${checklist_locale[@]}" \
  )
  case $? in
    0)
      if [ -z "$feedback" ]; then
        $DIALOG ${FLAGS_DIALOG[@]} \
          --msgbox "Locales defaulting to: \`${default_locales[*]/%/ }'" ${WIDGET_DIM}
        record=("${default_locales[@]}")
      else
        record=("${feedback}")
      fi
      echo; echo;
      ;;
    *)
      echo; echo;
      abort
      ;;
  esac

  for i in "${record[@]}"; do
    $SED -r -i \
      -e "/^.$i/s/^#//;" \
        "$cfgfile"
  done

  echo "#!/bin/bash                                                               " >  "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "notool() {                                                                " >> "$tmpfile"
  echo "  local -r tool=\"\$1\"                                                   " >> "$tmpfile"
  echo "  echo \"Missing tool in chroot environment: \$tool\"                     " >> "$tmpfile"
  echo "  exit 1                                                                  " >> "$tmpfile"
  echo "}                                                                         " >> "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "# tool check                                                              " >> "$tmpfile"
  echo "[ -z \"\$(command -v locale-gen)\" ] && notool 'locale-gen'               " >> "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "locale-gen                                                                " >> "$tmpfile"
  chroot_exec "$tmpfile" || abort
}

set_language() {

  # positional parameter
  local -r default_language="$1"

  # locals
  local tmpfile=/mnt/setLanguage.sh

  echo "#!/bin/bash                                                               " >  "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "notool() {                                                                " >> "$tmpfile"
  echo "  local -r tool=\"\$1\"                                                   " >> "$tmpfile"
  echo "  echo \"Missing tool in chroot environment: \$tool\"                     " >> "$tmpfile"
  echo "  exit 1                                                                  " >> "$tmpfile"
  echo "}                                                                         " >> "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "# tool check                                                              " >> "$tmpfile"
  echo "[ -z \"\$(command -v locale)\" ] && notool 'locale'                       " >> "$tmpfile"
  echo "[ -z \"\$(command -v dialog)\" ] && notool 'dialog'                       " >> "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "declare i                                                                 " >> "$tmpfile"
  echo "declare -a radiolist_language=()                                          " >> "$tmpfile"
  echo "declare feedback                                                          " >> "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "# collect available languages                                             " >> "$tmpfile"
  echo "for i in \$(locale --all-locales); do                                     " >> "$tmpfile"
  echo "  radiolist_language+=(\"\$i\" \"\$i\" \"off\")                           " >> "$tmpfile"
  echo "done                                                                      " >> "$tmpfile"
  echo "                                                                          " >> "$tmpfile"
  echo "# set language                                                            " >> "$tmpfile"
  echo "feedback=\$(                                                            \\" >> "$tmpfile"
  echo "  dialog ${FLAGS_DIALOG[@]}                                             \\" >> "$tmpfile"
  echo "    --radiolist                                                         \\" >> "$tmpfile"
  echo "      \"Select your Language\\nDefaulting to: $default_language\"       \\" >> "$tmpfile"
  echo "      ${MENUWIDGET_DIM}                                                 \\" >> "$tmpfile"
  echo "      \${radiolist_language[@]};                                        \\" >> "$tmpfile"
  echo ")                                                                         " >> "$tmpfile"
  echo "[ \$? -ne 0 -o -z \"\$feedback\" ] && {                                   " >> "$tmpfile"
  echo "  dialog ${FLAGS_DIALOG[@]}                                             \\" >> "$tmpfile"
  echo "    --msgbox \"Language defaulting to: $default_language\" ${WIDGET_DIM}  " >> "$tmpfile"
  echo "  feedback=\"$default_language\"                                          " >> "$tmpfile"
  echo "}                                                                         " >> "$tmpfile"
  echo "echo \"LANG=\$feedback\" > /etc/locale.conf                               " >> "$tmpfile"
  chroot_exec "$tmpfile" || abort
}

dismount_mountpoints() {

  # dismount
  swapoff \
    -a \
      &> /dev/null
  umount \
    -R /mnt \
      &> /dev/null

  # reset records
  mountpoints_assigned=()
  partitions_processed=()

  # clear flags
  FLAG_USR=''
  FLAG_LVM2=''
  FLAG_ROOT=''
  FLAG_CRYPT=''
  FLAG_PLAIN='on'

  # Wait for Update
  udevadm settle
}

close_encryption() {

  # positional parameter

  # locals
  local -r -a type_crypt=( \
    $( \
      lsblk -n -oPATH,TYPE | \
      egrep ${DISK_SYSTEM##*/} | \
      egrep crypt | \
      cut -f1 -d' ' - \
    ) \
  )
  local n

  for n in "${type_crypt[@]}"; do
    cryptsetup luksClose "${n}"
  done
}

catch_error() {

  # positional parameter

  echo "Oops, an error occured. Proceed anyway?"
  hitenter || abort
}

abort() {

  # positional parameter

  echo "Aborting ..."
  echo "Mountpoints are NOT dismounted."
  echo "Encryption is NOT closed."
  exit 1
}

get_device() {

  # positional parameter
  local -r mountpoint="$1"
  local -n parray1="$2"
  local -n parray2="$3"
  local -n presult="$4"

  # locals
  local i
  local -i n=0

  for i in "${parray1[@]}"; do
    [ "$i" == "$mountpoint" ] && {
      presult="${parray2[$n]##*\/}"
      return 0
    }
    n+=1
  done
  return 1
}

main() {

  # positional parameter

  # script wide variables
  declare -r WIDGET_DIM='-1 -1'
  declare -r MENUWIDGET_DIM='-1 -1 22'
  declare -r PROCESS_DELAY=3
  declare -r CRYPT_SUFFIX='_crypt'
  declare DISK_SYSTEM=''
  declare FLAG_INTELGPU='on'
  declare FLAG_NVIDIAGPU=''
  declare FLAG_DISK=''
  declare FLAG_ROOT=''
  declare FLAG_USR=''
  declare FLAG_LVM2=''
  declare FLAG_CRYPT=''
  declare FLAG_PLAIN='on'
  declare FLAG_ADMIN=''
  declare -a partitions_processed=()
  declare -a mountpoints_assigned=()
  declare -r openssl_passwd_algo='-1'   # see `openssl passwd -help`
  declare -a -r config_pacman_keyserver=(
    'hkp://keys.openpgp.org'
    'hkp://pgpkeys.eu'
    'hkp://pgp.surf.nl'
    'hkp://pgp.circ.lu'
    'hkp://pgp.surfnet.nl'
    'hkp://sks.pgpkeys.eu'
    'hkp://sks.pyro.eu.org'
    'hkp://pgp.uni-mainz.de'
    'hkp://keyserver.computer42.org'
    'hkp://keyserver.spline.inf.fu-berlin.de'
  )
  declare -r user_root='root'
  declare -r MiB_initial_wipe=32

  # ISO Live Console Settings
  local   default_ISO_consolefont="eurlatgr"
  local default_ISO_consolekeymap="de"

  # default settings, customizable
  local -r   default_consolefont="eurlatgr"
  local -r default_consolekeymap="de"
  local -r -a    default_locales=( \
    "en_US.UTF-8 UTF-8" \
    "en_GB.UTF-8 UTF-8" \
    "es_ES.UTF-8 UTF-8" \
    "it_IT.UTF-8 UTF-8" \
    "fr_FR.UTF-8 UTF-8" \
    "pt_PT.UTF-8 UTF-8" \
    "pl_PL.UTF-8 UTF-8" \
    "de_DE.UTF-8 UTF-8" \
    "sv_SE.UTF-8 UTF-8" \
  )
  local -r      default_language="de_DE.utf8"
  local -r      default_timezone="Europe/Berlin"
  local -r      default_hostname="zerocat-hyperbola-machine"

  # X Server keymap settings
  declare -r   xkbmap_rules='evdev'
  declare -r   xkbmap_model='pc105'
  declare     xkbmap_layout='de'      # set by radiolist
  declare    xkbmap_variant=''        # set by radiolist

  # local constants
  local -r           config_pacman="/etc/pacman.conf"
  local -r config_pacman_alternate="/etc/alt-pacman.conf"
  local -r       config_pacman_gpg="/etc/pacman.d/gnupg/gpg.conf"
  local -r       config_mkinitcpio="/mnt/etc/mkinitcpio.conf"
  local -r -a checklist_mkinitcpio=(
    1 "Write Configuration File"                      on
    2 "Refine Configuration File with GNU Nano"       off
    3 "Generate Initial Ramdisk"                      on
  )
  local -r -a menulist_mountpoint=(
    1 "/mnt/"
    2 "/mnt/boot"
    3 "/mnt/usr"
    4 "/mnt/usr/local"
    5 "/mnt/var"
    6 "/mnt/tmp"
    7 "/mnt/home"
    8 "[SWAP]"
  )
  local -r -a checklist_tweak=(
    1   "Restrict Access to important Directories"              on
  )
  local -r -a radiolist_DE=(
    1   "ICEWM"                                                 on
  )
  local -r -a checklist_X=(
    1   "Install X Server"                                      on
    2   "Pick X Keymap Layout and Variant"                      on
    3   "Write Configuration Files for X"                       on
    4   "Add Your Window Manager"                               on
    5   "Add Services"                                          on
  )
  local -r -a checklist_main=(
    1   "Live System: Which keymap to use for this script?"                                   on
    2   "Live System: Select Drive, open Encryption, mount Partitions"                        on
    3   "Install GNU/Linux-libre System + Initial Ramdisk Image + User \`$user_root'"         on
    4   "Configure GNU System, set Password for User \`$user_root'"                           on
    5   "Apply extra Security Tweaks ..."                                                     on
    6   "Install X Server, Window Manager, Services ..."                                      on
    7   "Install Applications"                                                                on
    8   "Create User Accounts"                                                                on
    9   "Configure Kernel Console"                                                            on
    10  "Reconfigure & Remake Initial Ramdisk Image ..."                                      on
    11  "GRUB Bootloader Options ..."                                                         on
    12  "Live System: Dismount Partitions, close Encryption, deselect Drive"                  on
  )
  local -r -a packages_Base_OpenRC=(
    "base"                    # comes with kernel linux-libre
    "base-devel"              # provides doas
    "xenocara-setxkbmap"      # provides setxkbmap
    "wpa_supplicant"
    "cryptsetup"              # provides encrypt hook
    "dialog"                  # required by install script
  )
  local -r -a packages_GRUB=(
    "grub"
  )
  local -r -a packages_X=(
    "xenocara-server"
    "xorg-input-evdev"
    "xenocara-input-synaptics"
    "xenocara-video-ati"
    "xenocara-video-dummy"
    "xorg-video-fbdev"
    "xenocara-video-intel"
    "xorg-video-nouveau"
    "xenocara-video-openchrome"
    "xorg-video-sisusb"
    "xenocara-video-vesa"
    "xenocara-video-vmware"
    "xenocara-xinit"
    "xlockmore"
    "xterm"
  )
  local -r -a packages_ICEWM=(
    "icewm"
    "tilda"
    "spacefm"
    "dhcpcd-ui"
    "volumeicon"
  )
  local -r -a packages_User=(
    "libmtp"
    "gphoto2"
    "alsa-utils"
    "gparted"
    "abiword"
    "smplayer"
    "gnumeric"
    "iceweasel-uxp"
    "claws-mail"
    "qtox"
  )

  # locals
  local init_modules='i915 nouveau '
  local hooks_standard='base udev autodetect keyboard keymap consolefont modconf block encrypt lvm2 filesystems fsck usr shutdown '
  local option
  local feedback
  local feedback2
  local swapvol
  local cryptdev
  local uuid
  local i
  local x
  local -i n
  local -a radiolist_timezone=()
  local -a radiolist_consolefont=()
  local -a radiolist_consolekeymaps=()
  local -a radiolist_xkeymaplayouts=()
  local -a radiolist_xkeymapvariants=()
  local -a checklist_grub=()
  local -a radiolist_GRUB=()

  # set console font and keymap, default value
  setfont ${default_ISO_consolefont}
  loadkeys ${default_ISO_consolekeymap}

  # welcome
  welcome

  # reset init system
  cp "$config_pacman" "$config_pacman_alternate";

  # start main checklist
  option=$( \
    $DIALOG ${FLAGS_DIALOG[@]} \
      --cancel-label "Abort" \
      --checklist \
        "Hyperbola Installation Checklist" \
        ${MENUWIDGET_DIM} \
        "${checklist_main[@]}"; \
  )
  case $? in
    0)
      echo; echo;
      [ -n "$option" ] && {
        # process main checklist
        echo "Process Main Checklist ..."
        sleep $PROCESS_DELAY
        echo
        for i in $option; do
          echo "Starting job $i: “${checklist_main[$((i*3-2))]}” ..."
          sleep $PROCESS_DELAY
          case $i in
            1)    # Live System: select console keymap
                # collect available console keymaps
                radiolist_consolekeymaps=( \
                  $( \
                    find /usr/share/kbd/keymaps -name '*.map.gz' -print | \
                    sed -r -e 's/(^.*\/)(.*)(\.map\.gz)/\2 \2 off/;' - | \
                    sort - \
                  ) \
                )

                # set ISO console keymap
                feedback=$( \
                  $DIALOG ${FLAGS_DIALOG[@]} \
                    --cancel-label "Abort" \
                    --radiolist \
                      "Pick your Keymap for the Live System’s Console\nDefaulting to: \`$default_ISO_consolekeymap'" \
                      ${MENUWIDGET_DIM} \
                      ${radiolist_consolekeymaps[@]:-"${default_ISO_consolekeymap}" "default ISO console keymap" "on"} \
                )
                case $? in
                  0)
                    [ -z "$feedback" ] && {
                      $DIALOG ${FLAGS_DIALOG[@]} \
                        --msgbox "Live System’s Console keymap defaulting to: \`$default_ISO_consolekeymap'" ${WIDGET_DIM}
                      feedback="$default_ISO_consolekeymap"
                    }
                    loadkeys "$feedback"
                    echo; echo;
                    ;;
                  *)
                    echo; echo;
                    abort
                    ;;
                esac
              ;;
            2)    # Live System: select drive, format, mount partitions
              set_DISK_SYSTEM
              dismount_mountpoints
              close_encryption
              disk_operations
              ;;
            3)    # install GNU system with user root
              [ -n "$FLAG_DISK" -a -n "$FLAG_ROOT" ] && {
                # Install base system
                pacstrap \
                  -C "$config_pacman_alternate" \
                    /mnt ${packages_Base_OpenRC[@]} || \
                      catch_error
              }
              ;;
            4)    # configure GNU system, set password for user root
              [ -n "$FLAG_DISK" -a -n "$FLAG_ROOT" ] && {

                # generate fstab, set swapvol variable for GRUB
                genfstab \
                  -U \
                  -p /mnt \
                | sed -r -e 's/\/mnt//;' - \
                    >> /mnt/etc/fstab
                n=0; uuid=''; swapvol='';
                while [ ${n} -lt ${#partitions_processed[@]} ]; do
                  x="${partitions_processed[$n]##*/}"
                  case "${mountpoints_assigned[$n]}" in
                    '[SWAP]')
                      x="/dev/${x%${CRYPT_SUFFIX}}"
                      swapvol="${x}"
                      ;;
                  esac
                  n+=1
                done

                # set hostname
                while [ true ]; do
                  feedback=$( \
                    $DIALOG ${FLAGS_DIALOG[@]} \
                      --cancel-label "Abort" \
                      --inputbox \
                        "Enter Hostname" \
                        ${WIDGET_DIM} \
                        "$default_hostname"
                  )
                  case $? in
                    0)
                      if [  -z "$feedback" -o \
                            -n "`echo $feedback | $SED -r -e '/.{254,}/!d;' -`" -o \
                            -n "`echo $feedback | $SED -r -e '/^[.-]|[.][-]|[-][.]|[.-]$|[^a-zA-Z0-9.-]/!d;' -`" \
                      ]; then
                        $DIALOG ${FLAGS_DIALOG[@]} \
                          --msgbox "Not a valid hostname!" ${WIDGET_DIM}
                      else
                        set_hostname_OpenRC "$feedback"
                        break 1
                      fi
                      ;;
                    *)
                      echo; echo;
                      abort
                      ;;
                  esac
                done

                # collect available timezones
                radiolist_timezone=( \
                  $( \
                    find /mnt/usr/share/ -wholename '*zoneinfo/[^posixright/]*/[^/]*' -print | \
                    sed -r -e 's/(^.*\/)(.*\/)(.*)/\2\3 \3 off/;' - | \
                    sort - \
                  ) \
                )

                # set local time
                feedback=$( \
                  $DIALOG ${FLAGS_DIALOG[@]} \
                    --cancel-label "Abort" \
                    --radiolist \
                      "Select your Timezone\nDefaulting to: $default_timezone" \
                      ${MENUWIDGET_DIM}  \
                      "${radiolist_timezone[@]}" \
                )
                case $? in
                  0)
                    [ -z "$feedback" ] && {
                      $DIALOG ${FLAGS_DIALOG[@]} \
                        --msgbox "Timezone defaulting to: \`$default_timezone'" ${WIDGET_DIM}
                      feedback="$default_timezone"
                    }
                    set_localtime "$feedback"
                    ;;
                  *)
                    echo; echo;
                    abort
                    ;;
                esac

                # set hardware clock type
                echo "#!/bin/bash               " > /mnt/setHWClock.sh
                echo "hwclock --systohc --utc   " >> /mnt/setHWClock.sh
                chroot_exec "/mnt/setHWClock.sh" || catch_error

                # select locales and generate
                gen_locales "${default_locales[@]}"

                # select and set language
                set_language "$default_language"

                # set password for user root
                set_password "$openssl_passwd_algo" "$user_root"
              }
              ;;
            5)    # apply extra security tweaks
              [ -n "$FLAG_DISK" -a -n "$FLAG_ROOT" ] && {
                feedback=$( \
                  $DIALOG ${FLAGS_DIALOG[@]} \
                    --checklist "Select Security Tweaks" ${MENUWIDGET_DIM} "${checklist_tweak[@]}"
                )
                case $? in
                  0)
                    echo; echo;
                    [ -n "$feedback" ] && {
                      echo "Process Security Tweak checklist ..."
                      sleep $PROCESS_DELAY
                      echo
                      for x in $feedback; do
                        echo "Starting job $x: “${checklist_tweak[$((x*3-2))]}” ...";
                        sleep $PROCESS_DELAY
                        case $x in
                          1)    # restrict access
                            chmod 700 \
                              /boot \
                              /etc/{iptables,arptables} \
                                &> /dev/null
                            ;;
                        esac
                        echo "... done with job $x: “${checklist_tweak[$((x*3-2))]}”"
                        hitenter || abort
                      done
                      echo "... Security Tweak Checklist processed."
                      hitenter || abort
                    }
                    ;;
                  *)
                    echo; echo;
                    abort
                    ;;
                esac
              }
              ;;
            6)    # X Server Checklist
              [ -n "$FLAG_DISK" -a -n "$FLAG_ROOT" ] && {
                feedback=$( \
                  $DIALOG ${FLAGS_DIALOG[@]} \
                    --checklist "Select X Server Options" ${MENUWIDGET_DIM} "${checklist_X[@]}"
                )
                case $? in
                  0)
                    echo; echo;
                    [ -n "$feedback" ] && {
                      echo "Process X Server Checklist ..."
                      sleep $PROCESS_DELAY
                      echo
                      for x in $feedback; do
                        echo "Starting job $x: “${checklist_X[$((x*3-2))]}” ...";
                        sleep $PROCESS_DELAY
                        case $x in
                          1)      # Install X Server

                            # install X packages
                            install_packages "${packages_X[*]}"

                            ;;
                          2)      # Set X keymap layout and variant

                            # collect available X keymap layouts
                            radiolist_xkeymaplayouts=( \
                              $( \
                                cat /mnt/usr/share/X11/xkb/rules/base.lst | \
                                sed -r -e '/^\! layout/,/^$/!d;/^\! layout/d;/^$/d;' - | \
                                sed -r -e 's/ /\*/g;' - | \
                                sed -r -e 's/([\*]*)([^\*]*)([\*]*)(.*)/\2 \4 off/;' - | \
                                sort - \
                              ) \
                            )

                            # set X keymap layout
                            feedback=$( \
                              $DIALOG ${FLAGS_DIALOG[@]} \
                                --cancel-label "Abort" \
                                --radiolist \
                                  "Pick your Keymap Layout for the X Server\nDefaulting to: \`$xkbmap_layout'" \
                                  ${MENUWIDGET_DIM} \
                                  "${radiolist_xkeymaplayouts[@]}" \
                            )
                            case $? in
                              0)
                                [ -z "$feedback" ] && {
                                  $DIALOG ${FLAGS_DIALOG[@]} \
                                    --msgbox "X keymap layout defaulting to: \`$xkbmap_layout'" ${WIDGET_DIM}
                                  feedback="$xkbmap_layout"
                                }
                                xkbmap_layout="$feedback"
                                echo; echo;
                                ;;
                              *)
                                echo; echo;
                                abort
                                ;;
                            esac

                            # collect available X keymap variants
                            radiolist_xkeymapvariants=( \
                              $( \
                                cat /mnt/usr/share/X11/xkb/rules/base.lst | \
                                sed -r -e '/^\! variant/,/^$/!d;/^\! variant/d;/^$/d;' - | \
                                sed -r -e "/${xkbmap_layout}\:/!d;" - | \
                                sed -r -e 's/ /\*/g;' - | \
                                sed -r -e 's/([\*]*)([^\*]*)([\*]*)(.*)/\2 \4 off/;' - | \
                                sort - \
                              ) \
                            )

                            # set X keymap variant
                            feedback=$( \
                              $DIALOG ${FLAGS_DIALOG[@]} \
                                --cancel-label "Abort" \
                                --radiolist \
                                  "Pick your Keymap Variant for Layout \`${xkbmap_layout}' for the X Server\nDefaulting to: \`$xkbmap_variant'" \
                                  ${MENUWIDGET_DIM} \
                                  "" "no variant" "off" \
                                  "${radiolist_xkeymapvariants[@]}" \
                            )
                            case $? in
                              0)
                                [ -z "$feedback" ] && {
                                  $DIALOG ${FLAGS_DIALOG[@]} \
                                    --msgbox "X keymap variant defaulting to: \`$xkbmap_variant'" ${WIDGET_DIM}
                                  feedback="$xkbmap_variant"
                                }
                                xkbmap_variant="$feedback"
                                echo; echo;
                                ;;
                              *)
                                echo; echo;
                                abort
                                ;;
                            esac

                            ;;
                          3)      # Write configuration files for X

                            # write touchpad configuration
                            write_touchpad_config

                            # Copy live system’s skel folder into the new system
                            cp -a /etc/skel/ /mnt/etc/

                            # write /etc/skel/.xinitrc
                            echo "setxkbmap -rules \"${xkbmap_rules}\" -model \"${xkbmap_model}\" -layout \"${xkbmap_layout}\" -variant \"${xkbmap_variant}\"" > /mnt/etc/skel/.xinitrc
                            chmod +x /mnt/etc/skel/.xinitrc

                            # Adjust default .bash_profile to start X automatically
                            echo "startx" >> /mnt/etc/skel/.bash_profile

                            ;;
                          4)      # Select Window Manager or Desktop Environment

                            # retrieve user input
                            feedback=$( \
                              $DIALOG ${FLAGS_DIALOG[@]} \
                                --cancel-label "Abort" \
                                --radiolist "Select your Window Manager" ${MENUWIDGET_DIM} "${radiolist_DE[@]}"
                            )
                            case $? in
                              0)
                                echo; echo;
                                case $feedback in
                                  1)    # ICEWM

                                    # install packages
                                    install_packages "${packages_ICEWM[*]}"

                                    # Set up icewm configuration files
                                    mkdir -p /mnt/etc/skel/.icewm

                                    echo "Theme=\"icedesert/default.theme\"" > /mnt/etc/skel/.icewm/theme

                                    echo "#!/bin/bash" > /mnt/etc/skel/.icewm/startup
                                    echo "sleep 1 && volumeicon &" >> /mnt/etc/skel/.icewm/startup
                                    echo "sleep 1 && dhcpcd-gtk &" >> /mnt/etc/skel/.icewm/startup
                                    chmod +x /mnt/etc/skel/.icewm/startup

                                    echo "exec icewm-session      " >> /mnt/etc/skel/.xinitrc

                                    # adjust dhcpcd-gtk configuration
                                    echo "update_config=1" >> /mnt/etc/wpa_supplicant/wpa_supplicant.conf

                                    ;;
                                esac

                                ;;
                              *)
                                echo; echo;
                                abort
                                ;;
                            esac

                            ;;
                          5)      # Add Services

                            # enable services
                            enable_services_OpenRC

                            ;;
                        esac
                        echo "... done with job $x: “${checklist_X[$((x*3-2))]}”"
                        hitenter || abort
                      done
                      echo "... X Server Checklist processed."
                      hitenter || abort
                    }
                    ;;
                  *)
                    echo; echo;
                    abort
                    ;;
                esac
              }
              ;;
            7)    # install extra User Applications
              [ -n "$FLAG_DISK" -a -n "$FLAG_ROOT" ] && {
                # Install packages
                install_packages "${packages_User[*]}"
              }
              ;;
            8)    # create user accounts
              [ -n "$FLAG_DISK" -a -n "$FLAG_ROOT" ] && {
                # Add new users
                add_user_account "$openssl_passwd_algo"
              }
              ;;
            9)    # configure kernel console
              [ -n "$FLAG_DISK" -a -n "$FLAG_ROOT" ] && {
                # collect available console fonts
                radiolist_consolefont=( \
                  $( \
                    find /mnt/usr/share/kbd/consolefonts -name '*.psf*.gz' -print | \
                    sed -r -e 's/(^.*\/)(.*)(\..*)(\..*$)/\2 \2 off/;' - | \
                    sort - \
                  ) \
                )

                # set console font
                feedback=$( \
                  $DIALOG ${FLAGS_DIALOG[@]} \
                    --cancel-label "Abort" \
                    --radiolist \
                      "Pick your Font for the Kernel Console\nDefaulting to: \`$default_consolefont'" \
                      ${MENUWIDGET_DIM} \
                      ${radiolist_consolefont[@]:-"${default_consolefont}" "default console font" "on"} \
                )
                case $? in
                  0)
                    [ -z "$feedback" ] && {
                      $DIALOG ${FLAGS_DIALOG[@]} \
                        --msgbox "Console font defaulting to: \`$default_consolefont'" ${WIDGET_DIM}
                      feedback="$default_consolefont"
                    }
                    echo "consolefont=\"$feedback\"" >> "/mnt/etc/conf.d/consolefont"
                    ;;
                  *)
                    echo; echo;
                    abort
                    ;;
                esac

                # collect available console keymaps
                radiolist_consolekeymaps=( \
                  $( \
                    find /mnt/usr/share/kbd/keymaps -name '*.map.gz' -print | \
                    sed -r -e 's/(^.*\/)(.*)(\.map\.gz)/\2 \2 off/;' - | \
                    sort - \
                  ) \
                )

                # set console keymap
                feedback=$( \
                  $DIALOG ${FLAGS_DIALOG[@]} \
                    --cancel-label "Abort" \
                    --radiolist \
                      "Pick your Keymap for the Kernel Console\nDefaulting to: \`$default_consolekeymap'" \
                      ${MENUWIDGET_DIM} \
                      ${radiolist_consolekeymaps[@]:-"${default_consolekeymap}" "default console keymap" "on"} \
                )
                case $? in
                  0)
                    [ -z "$feedback" ] && {
                      $DIALOG ${FLAGS_DIALOG[@]} \
                        --msgbox "Console keymap defaulting to: \`$default_consolekeymap'" ${WIDGET_DIM}
                      feedback="$default_consolekeymap"
                    }
                    echo "keymap=\"$feedback\"" >> "/mnt/etc/conf.d/keymaps"
                    echo; echo;
                    ;;
                  *)
                    echo; echo;
                    abort
                    ;;
                esac
              }
              ;;
            10)   # reconfigure and remake initial ramdisk image
              [ -n "$FLAG_DISK" -a -n "$FLAG_ROOT" ] && {
                feedback=$( \
                  $DIALOG ${FLAGS_DIALOG[@]} \
                    --cancel-label "Abort" \
                    --checklist "Mkinitcpio Configuration Options" ${MENUWIDGET_DIM} "${checklist_mkinitcpio[@]}" \
                )
                case $? in
                  0)
                    echo; echo;
                    [ -n "$feedback" ] && {
                      echo "Process Mkinitcpio Configuration Checklist ..."
                      sleep $PROCESS_DELAY
                      echo
                      for x in $feedback; do
                        echo "Starting job $x: “${checklist_mkinitcpio[$((x*3-2))]}” ...";
                        sleep $PROCESS_DELAY
                        case $x in
                          1)
                            [ -z "$FLAG_INTELGPU" ] && {
                              init_modules="${init_modules/i915 /}"
                            }
                            [ -z "$FLAG_NVIDEAGPU" ] && {
                              init_modules="${init_modules/nouveau /}"
                            }
                            sed -r -i \
                              -e "/^MODULES=/s/^/#/;" \
                              -e "/^# BINARIES$/i# Modules suggested by install script – select and refine as required.\nMODULES=\"${init_modules}\"\n" \
                                "$config_mkinitcpio"
                            [ -z "$FLAG_USR" ] && {
                              hooks_standard="${hooks_standard/usr /}"
                            }
                            [ -z "$FLAG_LVM2" ] && {
                              hooks_standard="${hooks_standard/lvm2 /}"
                            }
                            [ -z "$FLAG_CRYPT" ] && {
                              hooks_standard="${hooks_standard/encrypt /}"
                            }
                            [ -z "$FLAG_CRYPT" -a -z "FLAG_USR" ] && {
                              hooks_standard="${hooks_standard/shutdown /}"
                            }
                            sed -r -i \
                              -e "/^HOOKS=/s/^/#/;" \
                              -e "/^# COMPRESSION$/i# Hooks suggested by install script – select and refine as required.\nHOOKS=\"${hooks_standard}\"\n" \
                                "$config_mkinitcpio"
                            ;;
                          2)
                            $DIALOG ${FLAGS_DIALOG[@]} \
                              --msgbox "\
Now edit the Initial Ramdisk Configuration File ...\n\
\n\
e.g. remove modules if not required:\n\
· i915        – Intel Graphics\n\
· nouveau     – nVIDEA Graphics\n\
\n\
e.g. remove hooks if not required:\n\
· keymap      – add console keymap to ramdisk image\n\
· consolefont – add console font to ramdisk image\n\
· encrypt     – support encrypted root device\n\
· usr         – support /usr and /usr/local on separate partitions\n\
· shutdown    – add dismount capabilities for usr and encrypt hook\n" ${WIDGET_DIM};
                            echo; echo;

                            # customize /mnt/etc/mkinitcpio.conf
                            #   e.g.: adjust MODULES and HOOKS as described in libreboot how-to:
                            #   https://libreboot.org/docs/gnulinux/encrypted_parabola.html#install-the-base-system
                            cp --backup=numbered "$config_mkinitcpio" "$config_mkinitcpio".bak
                            nano "$config_mkinitcpio"
                            ;;
                          3)
                            # make initramfs
                            make_initramfs
                            ;;
                        esac
                        echo "... done with job $x: “${checklist_mkinitcpio[$((x*3-2))]}”"
                        hitenter || abort
                      done
                      echo "... Mkinitcpio Configuration Checklist processed."
                      hitenter || abort
                    }
                    ;;
                  *)
                    echo; echo;
                    abort
                    ;;
                esac
              }
              ;;
            11)   # GRUB bootloader options
              [ -n "$FLAG_DISK" -a -n "$FLAG_ROOT" ] && {
                checklist_grub=(
                  1 "Install GRUB Package"                                      on
                  2 "Install GRUB Bootloader${DISK_SYSTEM:+ on $DISK_SYSTEM}"   off
                  3 "Generate GRUB Configuration File ..."                      on
                )
                feedback=$( \
                  $DIALOG ${FLAGS_DIALOG[@]} \
                    --cancel-label "Abort" \
                    --checklist \
                      "GRUB Bootloader Options" \
                      ${MENUWIDGET_DIM} \
                      "${checklist_grub[@]}"; \
                )
                case $? in
                  0)
                    echo; echo;
                    [ -n "$feedback" ] && {
                      echo "Process GRUB Checklist ..."
                      sleep $PROCESS_DELAY
                      echo
                      for x in $feedback; do
                        echo "Starting job $x: “${checklist_grub[$((x*3-2))]}” ...";
                        sleep $PROCESS_DELAY
                        case $x in
                          1)
                            install_packages "${packages_GRUB[*]}"
                            ;;
                          2)
                            echo "#!/bin/bash                                                               " >  /mnt/grubInstall.sh
                            echo "                                                                          " >> /mnt/grubInstall.sh
                            echo "notool() {                                                                " >> /mnt/grubInstall.sh
                            echo "  local -r tool=\"\$1\"                                                   " >> /mnt/grubInstall.sh
                            echo "  echo \"Missing tool in chroot environment: \$tool\"                     " >> /mnt/grubInstall.sh
                            echo "  exit 1                                                                  " >> /mnt/grubInstall.sh
                            echo "}                                                                         " >> /mnt/grubInstall.sh
                            echo "                                                                          " >> /mnt/grubInstall.sh
                            echo "# tool check                                                              " >> /mnt/grubInstall.sh
                            echo "[ -z \"\$(command -v grub-install)\" ] && notool 'grub-install'           " >> /mnt/grubInstall.sh
                            echo "                                                                          " >> /mnt/grubInstall.sh
                            echo "grub-install ${DISK_SYSTEM}                                               " >> /mnt/grubInstall.sh
                            chroot_exec "/mnt/grubInstall.sh" || abort
                            ;;
                          3)
                            radiolist_GRUB=(
                              1 "Generate GRUB Standard Configuration"           "${FLAG_PLAIN:-off}"
                              2 "Generate GRUB Configuration, Encrypted Disks"   "${FLAG_CRYPT:-off}"
                            )
                            feedback2=$( \
                              $DIALOG ${FLAGS_DIALOG[@]} \
                                --cancel-label "Abort" \
                                --radiolist "Type of GRUB Configuration File" ${MENUWIDGET_DIM} "${radiolist_GRUB[@]}"
                            )
                            case $? in
                              0)
                                echo; echo;
                                case $feedback2 in
                                  1)
                                    echo "#!/bin/bash                                                                                 " >  /mnt/grubConfig.sh
                                    echo "                                                                                            " >> /mnt/grubConfig.sh
                                    echo "notool() {                                                                                  " >> /mnt/grubConfig.sh
                                    echo "  local -r tool=\"\$1\"                                                                     " >> /mnt/grubConfig.sh
                                    echo "  echo \"Missing tool in chroot environment: \$tool\"                                       " >> /mnt/grubConfig.sh
                                    echo "  exit 1                                                                                    " >> /mnt/grubConfig.sh
                                    echo "}                                                                                           " >> /mnt/grubConfig.sh
                                    echo "                                                                                            " >> /mnt/grubConfig.sh
                                    echo "# tool check                                                                                " >> /mnt/grubConfig.sh
                                    echo "[ -z \"\$(command -v cp)\" ] && notool 'cp'                                                 " >> /mnt/grubConfig.sh
                                    echo "[ -z \"\$(command -v mv)\" ] && notool 'mv'                                                 " >> /mnt/grubConfig.sh
                                    echo "[ -z \"\$(command -v sed)\" ] && notool 'sed'                                               " >> /mnt/grubConfig.sh
                                    echo "[ -z \"\$(command -v mkdir)\" ] && notool 'mkdir'                                           " >> /mnt/grubConfig.sh
                                    echo "[ -z \"\$(command -v grub-mkconfig)\" ] && notool 'grub-mkconfig'                           " >> /mnt/grubConfig.sh
                                    echo "                                                                                            " >> /mnt/grubConfig.sh
                                    echo "cp /etc/default/grub /etc/default/grub.bak                                                  " >> /mnt/grubConfig.sh
                                    echo "mkdir -p /boot/grub                                                                         " >> /mnt/grubConfig.sh
                                    echo "sed -r -i                                                                                 \\" >> /mnt/grubConfig.sh
                                    echo "  -e \"/GRUB_CMDLINE_LINUX=/cGRUB_CMDLINE_LINUX=\\\"${swapvol:+resume=${swapvol}}\\\"\"   \\" >> /mnt/grubConfig.sh
                                    echo "    /etc/default/grub                                                                       " >> /mnt/grubConfig.sh
                                    echo "sed -r -i                                                                                 \\" >> /mnt/grubConfig.sh
                                    echo "  -e \"/GRUB_ENABLE_CRYPTODISK/s/^/#/;\"                                                  \\" >> /mnt/grubConfig.sh
                                    echo "    /etc/default/grub                                                                       " >> /mnt/grubConfig.sh
                                    echo "grub-mkconfig -o /boot/grub/grub.cfg                                                        " >> /mnt/grubConfig.sh
                                    echo "mv /etc/default/grub.bak /etc/default/grub                                                  " >> /mnt/grubConfig.sh
                                    chroot_exec "/mnt/grubConfig.sh" || abort
                                    ;;
                                  2)
                                    get_device '/mnt/' mountpoints_assigned partitions_processed cryptdev
                                    echo "#!/bin/bash                                                                                                                         " >  /mnt/grubConfig.sh
                                    echo "                                                                                                                                    " >> /mnt/grubConfig.sh
                                    echo "notool() {                                                                                                                          " >> /mnt/grubConfig.sh
                                    echo "  local -r tool=\"\$1\"                                                                                                             " >> /mnt/grubConfig.sh
                                    echo "  echo \"Missing tool in chroot environment: \$tool\"                                                                               " >> /mnt/grubConfig.sh
                                    echo "  exit 1                                                                                                                            " >> /mnt/grubConfig.sh
                                    echo "}                                                                                                                                   " >> /mnt/grubConfig.sh
                                    echo "                                                                                                                                    " >> /mnt/grubConfig.sh
                                    echo "# tool check                                                                                                                        " >> /mnt/grubConfig.sh
                                    echo "[ -z \"\$(command -v cp)\" ] && notool 'cp'                                                                                         " >> /mnt/grubConfig.sh
                                    echo "[ -z \"\$(command -v mv)\" ] && notool 'mv'                                                                                         " >> /mnt/grubConfig.sh
                                    echo "[ -z \"\$(command -v sed)\" ] && notool 'sed'                                                                                       " >> /mnt/grubConfig.sh
                                    echo "[ -z \"\$(command -v mkdir)\" ] && notool 'mkdir'                                                                                   " >> /mnt/grubConfig.sh
                                    echo "[ -z \"\$(command -v grub-mkconfig)\" ] && notool 'grub-mkconfig'                                                                   " >> /mnt/grubConfig.sh
                                    echo "                                                                                                                                    " >> /mnt/grubConfig.sh
                                    echo "cp /etc/default/grub /etc/default/grub.bak                                                                                          " >> /mnt/grubConfig.sh
                                    echo "mkdir -p /boot/grub                                                                                                                 " >> /mnt/grubConfig.sh
                                    echo "sed -r -i                                                                                                                         \\" >> /mnt/grubConfig.sh
                                    echo "  -e \"/GRUB_CMDLINE_LINUX=/cGRUB_CMDLINE_LINUX=\\\"cryptdevice=/dev/${cryptdev%${CRYPT_SUFFIX}}\:${cryptdev} hibernate=no\\\"\"  \\" >> /mnt/grubConfig.sh
                                    echo "    /etc/default/grub                                                                                                               " >> /mnt/grubConfig.sh
                                    echo "sed -r -i -e \"/GRUB_ENABLE_CRYPTODISK/s/^#//;\" /etc/default/grub                                                                  " >> /mnt/grubConfig.sh
                                    echo "grub-mkconfig -o /boot/grub/grub.cfg                                                                                                " >> /mnt/grubConfig.sh
                                    echo "mv /etc/default/grub.bak /etc/default/grub                                                                                          " >> /mnt/grubConfig.sh
                                    chroot_exec "/mnt/grubConfig.sh" || abort
                                    ;;
                                esac
                                ;;
                              *)
                                echo; echo;
                                abort
                                ;;
                            esac
                            ;;
                        esac
                        echo "... done with job $x: “${checklist_grub[$((x*3-2))]}”"
                        hitenter || abort
                      done
                      echo "... GRUB Checklist processed."
                      hitenter || abort
                    }
                    ;;
                  *)
                    echo; echo;
                    abort
                    ;;
                esac
              }
              ;;
            12)   # Live System: dismount partitions, close encryption
              dismount_mountpoints
              close_encryption
              unset_DISK_SYSTEM
              ;;
          esac
          echo "... done with job $i: “${checklist_main[$((i*3-2))]}”"
          hitenter || abort
        done
        echo "... Main Checklist processed."
        echo "Good Luck!"
        echo
      }
      ;;
    *)
      echo; echo;
      abort
      ;;
  esac
}

# check tools
declare -r SED=$(command -v sed);        [ -z "$SED" ] && notool 'sed';
declare -r DIALOG=$(command -v dialog);  [ -z "$DIALOG" ] && notool 'dialog';

# globals
declare -r -a FLAGS_DIALOG=("--stdout" "--no-shadow" "--title Hyperbola-Setup")

# start
fillscreen
checkperm
main "$@"
