#!/bin/bash
#
# Welcome: the EndeavourOS greeter.
#
# Shows useful basic info about the EndeavourOS and its usage.
# Targeted for people new to EndeavourOS (but not new to Linux).
#
# TODO:
# - add icons to buttons once proper supported exists in yad

DebugBreak() { : ; }

export PROGNAME=eos-welcome
export PRETTY_PROGNAME="Welcome"

EOS_SCRIPTS_DIR=/usr/share/endeavouros/scripts
translations_dir=$EOS_SCRIPTS_DIR                 # used also by the translation.bash !!

source $translations_dir/translations.bash


#################################################################################
EOS_SCRIPTS_YAD=$EOS_SCRIPTS_DIR/eos-script-lib-yad
test -r  $EOS_SCRIPTS_YAD || {
    echo "ERROR: cannot find $EOS_SCRIPTS_YAD" >&2
    exit 1
}
source $EOS_SCRIPTS_YAD

unset EOS_SCRIPTS_YAD

export -f eos_yad
export -f eos_yad_terminal
export -f eos_yad_check_internet_connection
export -f eos_yad_GetArgVal
export -f eos_yad_RunCmdTermBash
export -f eos_yad_problem
export -f eos_yad_DIE
export -f eos_yad_WARN
export -f eos_yad__detectDE
export -f eos_yad_GetDesktopName
export -f eos_GetArch
export -f eos_select_browser
export -f eos_yad_nothing_todo
export -f eos_notification
#################################################################################

export PROG_PACKAGENAME="welcome"
export INSTALLER_PROGRAM=/usr/bin/calamares
export EOS_LIVEUSER=liveuser
export EOS_KEEP_PKGS
export PROG_VERSION="$(expac -Q %v $PROG_PACKAGENAME)"
export INSTALL_LOG_FILE=/home/$EOS_LIVEUSER/endeavour-install.log


AfterTranslations() {
    # Here we have definitions that require special treatment because of
    # yad running in other processes...

    export WH_BUTT_TITLE="$(ltr help_butt_title)"
    export WH_BUTT_TEXT="$(ltr help_butt_text)"

    export CAL_NOAVAIL="$(ltr cal_noavail)"
    export CAL_WARN="$(ltr cal_warn)"
    export CAL_INFO1="$(ltr cal_info1)"
    export CAL_INFO2="$(ltr cal_info2)"
    export CAL_INFO3="$(ltr cal_info3)"
    export CAL_INFO4="$(ltr cal_info4)"
    export CAL_CHOOSE="$(ltr cal_choose)"
    export CAL_METHOD="$(ltr cal_method)"
    export CAL_NOSUPPORT="$(ltr cal_nosupport)"
    export CAL_NOFILE="$(ltr cal_nofile)"
    export CAL_ISTARTED="$(ltr cal_istarted)"
    export CAL_ISTOPPED="$(ltr cal_istopped)"
    export ISSUES_TITLE="$(ltr issues_title)"
    export ISSUES_FRUB="$(ltr issues_grub)"
    export ISSUES_RUN="$(ltr issues_run)"
    export ISSUES_NO="$(ltr issues_no)"
    export SYSUP_NO="$(ltr sysup_no)"
    export SYSUP_CHECK="$(ltr sysup_check)"
    export INSTALL_INSTALLER="$(ltr install_installer)"
    export INSTALL_ALREADY="$(ltr install_already)"
    export INSTALL_ING="$(ltr install_ing)"
    export INSTALL_DONE="$(ltr install_done)"
    export DM_TITLE="$(ltr dm_title)"
    export DM_COL_NAME1="$(ltr dm_col_name1)"
    export DM_COL_NAME2="$(ltr dm_col_name2)"
    export DM_REBOOT_REQUIRED="$(ltr dm_reboot_required)"
    export DM_CHANGED="$(ltr dm_changed)"
    export DM_FAILED="$(ltr dm_failed)"
    export DM_WARNING_TITLE="$(ltr dm_warning_title)"
    export AFTER_INSTALL_US="$(ltr after_install_us)"
    export AFTER_INSTALL_US_FROM="$(ltr after_install_us_from)"
    export AFTER_INSTALL_US_EL="$(ltr after_install_us_el)"
    export AFTER_INSTALL_US_DONE="$(ltr after_install_us_done)"
    export AFTER_INSTALL_US_FAIL="$(ltr after_install_us_fail)"
    export UPDT_NOTHING_TODO="$(ltr updt_nothing_todo)"
    export UPDT_UPDATE_CHECK="$(ltr updt_update_check):"

    export INS_CUST_TEXT="$(ltr ins_cust_text)"
    export INS_CUST_TEXT2="$(ltr ins_cust_text2)"
    export INS_CUST_TEXT3="$(ltr ins_cust_text3)"

    export _COMMONPHRASE_ENABLED="$(ltr _commonphrase_enabled)"
    export _COMMONPHRASE_DISABLED="$(ltr _commonphrase_disabled)"
}

IsInstalled() { expac -Q %n "$1" >& /dev/null ; }
export -f IsInstalled

IsInstalling() {
    test "$show_installer" = "yes" && return 0
    test -x $INSTALLER_PROGRAM && test "$LOGNAME" = "$EOS_LIVEUSER"
}
export -f IsInstalling

Welog() {
    [ -d /home/$EOS_LIVEUSER ] && echo "$PROGNAME: " "$@" >> $INSTALL_LOG_FILE
}
export -f Welog

yad_Install() {
    # Install one or more given packages. Does not reinstall any packages.

    local yadcmd=(
        eos_yad --text-info --width=600 --height=500 --title="$INSTALL_INSTALLER" --wrap --tail --button=yad-quit:0 --fontname="Mono 10"
    )
    local pkg pkgs=()

    for pkg in "$@" ; do
        case "$pkg" in
            */*) pkgs+=("$pkg") ;;                                    # $repo/$pkg: force install
            *)   IsInstalled "$pkg" >& /dev/null || pkgs+=("$pkg") ;;
        esac
    done
    test -z "$pkgs" && {
        echo "$*: $INSTALL_ALREADY" | "${yadcmd[@]}"
        return
    }
    while true ; do
        echo "$INSTALL_ING ${pkgs[*]} ..."
        pkexec pacman -S --noconfirm "${pkgs[@]}"
        echo "$INSTALL_DONE"
        break
    done |& "${yadcmd[@]}"
}
export -f yad_Install

yad_GetCurrentDM() {
    local current=$(ls -l /etc/systemd/system/display-manager.service | awk '{print $NF}')
    current="$(basename $current .service)"
    echo "$current"
}
export -f yad_GetCurrentDM

yad_ChangeDisplayManager() {
    local cmd count
    local dmlist="" dm
    local dms=(gdm lightdm lxdm sddm)
    local current=$(yad_GetCurrentDM)

    count="${#dms[@]}"

    cmd=(eos_yad --list --radiolist --title="$DM_TITLE" --width=300 --height=200)
    cmd+=(--column="$DM_COL_NAME1":rd --column="$DM_COL_NAME2")

    for ((ix=0; ix<count; ix++)) ; do
        dm="${dms[$ix]}"
        case "$dm" in
            $current) cmd+=(true  "$dm") ;;
            *)        cmd+=(false "$dm") ;;
        esac
    done

    # selected new dm
    dm="$("${cmd[@]}" | cut -d '|' -f 2)"

    case "$dm" in
        "$current" | "") return ;;
    esac

    cmd=""
    IsInstalled "$dm" >& /dev/null || {
        case "$dm" in
            lightdm) cmd+="pacman -S ${dm}{,-gtk-greeter{,-settings}} --noconfirm >& /dev/null && ";;
            *)       cmd+="pacman -S $dm --noconfirm >& /dev/null && " ;;
        esac
    }
    cmd+="systemctl disable $current && systemctl enable $dm"
    pkexec bash -c "$cmd"

    if [ "$(yad_GetCurrentDM)" = "$dm" ] ; then
        echo "$DM_REBOOT_REQUIRED" | \
            eos_yad --text-info --title="$DM_CHANGED $dm" --wrap --width=300 --height=200 --button=yad-quit:0
    else
        echo "$DM_FAILED" | \
            eos_yad --text-info --title="$DM_WARNING_TITLE" --width=300 --height=200 --button=yad-quit:0
    fi
}
export -f yad_ChangeDisplayManager

WelcomeDevelConf() {
    # Supported config file variables, defaults, and supported values:
    #    local _show_change_reso=no      # yes or no
    #
    local varname="$1"
    local fallback="$2"

    test -n "$fallback" || {
        echo "Error: ${FUNCNAME[1]} calling ${FUNCNAME[0]}: must give two parameters!" >&2
        return 1
    }

    local devconf="$HOME/.config/welcome-devel.conf"
    local answer="$fallback"

    if [ -r "$devconf" ] ; then
        source "$devconf"
        answer="${!varname}"
        test -n "$answer" || answer="$fallback"
    fi
    echo "$answer"

}
export -f WelcomeDevelConf

AddField2() {    # Still experimental!
    [ $NewFieldHandling = yes ] || return 1
    local app="$1"
    shift
    if [ -z "$app" ] || which "$app" &>/dev/null ; then
        tabcontents+=(--field=" $@")
    fi
}

ShowChangeResoButton() {
    # Allow showing a button for changing the display resolution?

    [ -x /usr/bin/xrandr ] || return

    local show_reso_butt="$(WelcomeDevelConf _show_change_reso no)"

    if [ "$show_reso_butt" = "no" ] ; then
        case "$(device-info --vm)" in
            virtualbox | qemu | kvm | vmware)
                show_reso_butt=yes ;;                  # in a VM always show the button
        esac
    fi
    if [ -x $INSTALLER_PROGRAM ] || [ "$LOGNAME" = "$EOS_LIVEUSER" ] || [ "$show_installer" = "yes" ] ; then
        show_reso_butt=yes                  # show the button if installing
    fi

    if [ "$show_reso_butt" = "yes" ] ; then
        # AddField2 "" "$(ltr ins_reso)!$ICO_PREFERENCES_DISPLAY!$(ltr ins_resotip)":fbtn   ChangeDisplayResolution
        tabcontents+=(--field=" $(ltr ins_reso)!$ICO_PREFERENCES_DISPLAY!$(ltr ins_resotip)":fbtn   ChangeDisplayResolution)
    fi
}
export -f ShowChangeResoButton

RateMirrors_arch() {
    local tmpfile=$(mktemp -u)
    local delay="$RATE_MIRRORS_MAX_DELAY_ARCH"
    [ "$delay" ] || delay=3600
    chmod go-rwx $tmpfile
    local cmd="/usr/bin/rate-mirrors --save $tmpfile --disable-comments-in-file arch --max-delay=$delay"
          cmd+="; [ -e $tmpfile ] && sudo cp $tmpfile /etc/pacman.d/mirrorlist"
          cmd+="; sleep 1; rm -f $tmpfile"
    RunInTerminal "$cmd"
}
RateMirrors_eos() {
    local tmpfile=$(mktemp -u)
    chmod go-rwx $tmpfile
    local cmd="/usr/bin/rate-mirrors --save $tmpfile --disable-comments-in-file endeavouros"
          cmd+="; [ -e $tmpfile ] && sudo cp $tmpfile /etc/pacman.d/endeavouros-mirrorlist"
          cmd+="; sleep 1; rm -f $tmpfile"
    RunInTerminal "$cmd"
}

export -f RateMirrors_eos
export -f RateMirrors_arch

MirrorRankingButtons() {
    local has_ratemirrors=no
    [ -x /usr/bin/rate-mirrors ] && has_ratemirrors=yes

    if [ "$(eos_GetArch)" != "armv7h" ] ; then
        if [ -x /usr/bin/reflector-simple ] ; then
            tabcontents+=(
                --field=" $(ltr after_install_um) (Arch, reflector-simple)!$ICO_MIRROR_RANK!$(ltr after_install_umartip)":fbtn "reflector-simple"
            )
            # AddField2 reflector-simple "$(ltr after_install_um) (Arch, reflector-simple)!$ICO_MIRROR_RANK!$(ltr after_install_umartip)":fbtn "reflector-simple"
        fi
        if [ $has_ratemirrors = yes ] ; then
            tabcontents+=(
                --field=" $(ltr after_install_um) (Arch, rate-mirrors)!$ICO_MIRROR_RANK!$(ltr after_install_umartip)":fbtn "RateMirrors_arch"
            )
            # AddField2 rate-mirrors "$(ltr after_install_um) (Arch, rate-mirrors)!$ICO_MIRROR_RANK!$(ltr after_install_umartip)":fbtn "RateMirrors_arch"
        fi
        if [ -x /usr/bin/rami ] ; then
            if [ -z "$WELCOME_RAMI_OPTIONS" ] ; then
                WELCOME_RAMI_OPTIONS="--save --timeout-rank 10 --ranking-data --continent -cDE,US"
            fi
            tabcontents+=(
                --field=" $(ltr after_install_um) (Arch, rami)!$ICO_MIRROR_RANK!$(ltr after_install_umartip)":fbtn "RunInTerminal '/bin/rami $WELCOME_RAMI_OPTIONS'"
            )
            # AddField2 "" "$(ltr after_install_um) (Arch, rami)!$ICO_MIRROR_RANK!$(ltr after_install_umartip)":fbtn "RunInTerminal '/bin/rami $WELCOME_RAMI_OPTIONS'"
        fi
    fi
    if [ -x /usr/bin/eos-rankmirrors ] ; then
        tabcontents+=(
            --field=" $(ltr after_install_um) (EndeavourOS, eos-rankmirrors)!$ICO_MIRROR_RANK!$(ltr after_install_umentip)":fbtn "RunInTerminal 'LANG=C eos-rankmirrors'"
        )
    fi
    if [ $has_ratemirrors = yes ] ; then
        tabcontents+=(
            --field=" $(ltr after_install_um) (EndeavourOS, rate-mirrors)!$ICO_MIRROR_RANK!$(ltr after_install_umentip)":fbtn  "RateMirrors_eos"
        )
    fi
    # AddField2 eos-rankmirrors "$(ltr after_install_um) (EndeavourOS, eos-rankmirrors)!$ICO_MIRROR_RANK!$(ltr after_install_umentip)":fbtn "RunInTerminal 'LANG=C eos-rankmirrors'"
    # AddField2 rate-mirrors    "$(ltr after_install_um) (EndeavourOS, rate-mirrors)!$ICO_MIRROR_RANK!$(ltr after_install_umentip)":fbtn    "RateMirrors_eos"
}
export -f MirrorRankingButtons

ButtonsMayHide() {
  local -n _text_="$1"
  if [ "$has_a_connection" = "no" ] && [ $is_installing = yes ] ; then
      _text_+="\n$(ltr ins_no_connection)"
  fi
}

INSTALL() {
  local handle="$1"
  local tabnum="$2"
  local btdoc="$BLUETOOTH_INFO_PAGE"
  local INSTALLER_BROWSER=firefox
  local text="<b>$(ltr ins_text)</b>"

  ButtonsMayHide text

  local tabcontents=(
      eos_yad --align-buttons --use-interp
      --plug="$handle" --tabnum="$tabnum" --form  --columns=2
      --image=$ICO_CALAMARES                       # $WELCOME_ICON_INSTALL_TAB
      --text="$text"
      --text-align=left

      --field=" $(ltr ins_start)!$ICO_CALAMARES!$(ltr ins_starttip)":fbtn                   "eos-install-mode-run-calamares '$lang' '$install_mode'"
      # --field=" $(ltr install_community)!$ICO_INSTALL!$(ltr install_community_tip)":fbtn "eos-install-mode-run-calamares '$lang' community"
      # --field=" $(ltr ins_arm_start)!$ICO_INSTALL_ARM!$(ltr ins_arm_starttip)":fbtn    "arm-eos-welcome-installer"
  )
  [ "$has_a_connection" = "yes" ] && MirrorRankingButtons

  IsInstalled partitionmanager && tabcontents+=(--field=" $(ltr ins_pm) (partitionmanager)!$ICO_PARTITIONMANAGER!$(ltr ins_pmtip2)":fbtn 'partitionmanager')
  IsInstalled gparted          && tabcontents+=(--field=" $(ltr ins_pm) (gparted)!$ICO_GPARTED!$(ltr ins_pmtip)":fbtn 'gparted')

  ShowChangeResoButton
  if [ "$has_a_connection" = "yes" ] ; then
      tabcontents+=(
          --field=" $(ltr ins_blue_notes)!$ICO_BLUETOOTH!$(ltr ins_blue_notes_tip)":fbtn  "$INSTALLER_BROWSER '$btdoc'"
          --field=" $(ltr ins_rel)!$ICO_TIPS!$(ltr ins_reltip)":fbtn                      "$INSTALLER_BROWSER $EOS_NEWS_PAGE"
          --field=" $(ltr ins_tips)!$ICO_TIPS!$(ltr ins_tipstip)":fbtn                    "$INSTALLER_BROWSER $EOS_INSTALL_TIPS_PAGE"
          --field=" $(ltr ins_syslog)!$ICO_TIPS!$(ltr ins_syslogtip)":fbtn                "$INSTALLER_BROWSER $EOS_INCLUDE_LOGS_PAGE"
          --field=" $(ltr ins_custom)!$ICO_TIPS!$(ltr ins_custom_tip)":fbtn               "$INSTALLER_BROWSER $EOS_CUSTOMIZE_INSTALL_PAGE"
          --field=" $(ltr ins_customized)!$ICO_CUSTOM!$(ltr ins_cust_text)":fbtn          "AskUserCustomUrl"
      )
  fi
  TesterIsoFetching

  [ "$handle" != "calculate" ] && "${tabcontents[@]}" >& /dev/null &
}

AskUserCustomUrl() {
    local url=""
    local cmd=(
        eos_yad --entry
        --title="$INS_CUST_TEXT"
        --text="${INS_CUST_TEXT2}. $INS_CUST_TEXT3."
        --image=$ICO_QUESTION
    )

    url=$("${cmd[@]}")
    if [ $? -eq 0 ] ; then
        MagicId_new "$url"
    fi
}
export -f AskUserCustomUrl

GeneralInfo() {
  local handle="$1"
  local tabnum="$2"
  local text="<b>$(ltr general_info_text)</b>"

  ButtonsMayHide text

  local tabcontents=(
      eos_yad --align-buttons --use-interp
      --plug="$handle" --tabnum="$tabnum" --form --columns=2
      --image=$ICO_QUESTION
      --text="$text"
      --text-align=left
      --field=" $(ltr general_info_ws)!$ICO_TIPS!$EOS_MAIN_PAGE":fbtn                   "WelcomeBrowser $EOS_MAIN_PAGE"
      --field=" $(ltr general_info_wi)!$ICO_TIPS!$(ltr general_info_witip)":fbtn        "WelcomeBrowser $EOS_DISCOVERY_PAGE"
      --field=" $(ltr general_info_ne)!$ICO_TIPS!$(ltr general_info_netip)":fbtn        "WelcomeBrowser $EOS_NEWS_PAGE"
      --field=" $(ltr general_info_fo)!$ICO_TIPS!$(ltr general_info_fotip)":fbtn        "WelcomeBrowser $EOS_FORUM_PAGE"
      --field=" $(ltr general_info_do)!$ICO_TIPS!$(ltr general_info_dotip)":fbtn        "WelcomeBrowser $EOS_DONATE_PAGE"
      --field=" $(ltr general_info_ab)!$ICO_TIPS!$(ltr general_info_abtip)":fbtn        "WelcomeBrowser $EOS_WELCOME_PAGE"
  )

  [ "$handle" != "calculate" ] && "${tabcontents[@]}" >& /dev/null &
}

w_WARN() {
    local msg="$1"
    shift
    eos_yad_WARN "$PRETTY_PROGNAME: ${FUNCNAME[1]}: $msg" --height=200 --width=500 "$@"
}
export -f w_WARN

RunIfInstalled() {
    # Usage: $FUNCNAME -a="app" [-p="pkg"] [app-parameters]

    local app="" pkg=""
    local opt

    while [ -n "$1" ] ; do
        opt="$1"
        case "$opt" in
            -a=*) app="${opt#*=}" ; shift ;;
            -p=*) pkg="${opt#*=}" ; shift ;;
            -*) w_WARN "unsupported option '$opt'" --text="Option unsupported" ; return 1 ;;
            *) break ;;
        esac
    done

    if [ -z "$app" ] ; then
        w_WARN "app parameter (required) is empty" --text="Application name is empty"
        return 1
    fi
    if [ -z "$(which "$app" 2> /dev/null)" ] ; then
        if [ -n "$pkg" ] ; then
            w_WARN "app '$app' (from package '$pkg') not found" --text="Application not installed" --width=600
        else
            w_WARN "app '$app' not found" --text="Application not installed"
        fi
        return 1
    fi

    "$app" "$@"
}
export -f RunIfInstalled

UpdateWithEosAurHelper() {
    local command="$1"
    RunInTerminal "echo '==> $command' ; $command"
}
export -f UpdateWithEosAurHelper

AddEosAurHelpers() {
    # Add plain eos-update
    tabcontents+=(--field=" $(ltr after_install_usnat) (eos-update)!$ICO_UPDATE!$(ltr after_install_usnat_tip)":fbtn "UpdateWithEosAurHelper 'eos-update --faillock-check'")

    # Add eos-update --aur if a supported helper is installed
    if [ -x /bin/yay ] || [ -x /bin/paru ] ; then
        tabcontents+=(--field=" $(ltr after_install_usnataur) (eos-update --aur)!$ICO_UPDATE!$(ltr after_install_usnataur_tip)":fbtn "UpdateWithEosAurHelper 'eos-update --faillock-check --aur'")
    fi

    # Add simply the first existing AUR helper
    local helper=""
    for helper in "$EOS_AUR_HELPER" "$EOS_AUR_HELPER_OTHER" yay paru ; do
        helper="${helper##*/}"
        if [ "$helper" ] && [ -x "/bin/$helper" ] ; then
            tabcontents+=(
                --field=" $(ltr after_install_ushlp) ($helper)!$ICO_UPDATE!$(ltr after_install_ushlp_tip)":fbtn "UpdateWithEosAurHelper '$helper'"
            )
            break
        fi
    done
}
export -f AddEosAurHelpers

AfterInstall() {
  local handle="$1"
  local tabnum="$2"
  local text="<b>$(ltr after_install_text)</b>"

  ButtonsMayHide text

  local _exclamation='&#33;'   # '!'
  local _and='&#38;'           # '&'
  local _question='&#63;'      # '?'

  local tabcontents=(
      eos_yad --align-buttons
      --use-interp  # don't need explicit 'bash -c' construct when calling functions
      --plug="$handle" --tabnum="$tabnum" --form --image=$ICO_SYSTOOLS
      --text="$text" --columns=2
  )
  MirrorRankingButtons

  if [ -x /bin/eos-manual-intervention ] ; then
      if [ $(eos-manual-intervention --count) -gt 0 ] ; then
          tabcontents+=(--field=" $(ltr after_install_mani)!$ICO_UPDATE!$(ltr after_install_manitip)":fbtn "RunInTerminal eos-manual-intervention")
      fi
  fi

  AddEosAurHelpers
  tabcontents+=(
      #--field=" $(ltr after_install_us) ($EOS_AUR_HELPER)!$ICO_UPDATE!$(ltr after_install_ustip)":fbtn "UpdateWithEosAurHelper"     # "RunInTerminal UpdateInTerminal --lang=$lang"
      --field=" $(ltr after_install_pclean)!$ICO_SYSTOOLS!$(ltr after_install_pcleantip)":fbtn 'paccache-service-manager'
  )

  # if [ -x /usr/bin/eos-update-notifier-configure ] ; then
  #     tabcontents+=(--field=" $(ltr after_install_conf) eos-update-notifier!$ICO_UPDATE!$(ltr after_install_conf) eos-update-notifier":fbtn "eos-update-notifier-configure")
  # fi

  if [ "$(eos_GetArch)" != "armv7h" ] ; then
      tabcontents+=(--field=" $(ltr after_install_cdm)!$ICO_SYSTOOLS!$(ltr after_install_cdmtip)":fbtn 'yad_ChangeDisplayManager')
  fi

  ShowChangeResoButton

  tabcontents+=(
      --field=" $(ltr after_install_ew)!$ICO_WALL!$(ltr after_install_ewtip)":fbtn    'eos-wallpaper-set DEFAULT'
      --field=" $(ltr after_install_ew2)!$ICO_WALL!$(ltr after_install_ewtip2)":fbtn  'eos-wallpaper-set'
      --field=" $(ltr after_install_more_wall)!$ICO_WALL_DOWNLOAD!$(ltr after_install_more_wall_tip)":fbtn  'RunInTerminal eos-download-wallpapers'
  )
  if [ "$do_r8168_check" = yes ] && IsR8168Card ; then
      tabcontents+=(
          --field=" $(ltr after_install_r8168)!$ICO_SYSTOOLS!$(ltr after_install_r8168_tip)":fbtn "ethernet_toggle_r8168_r8169"
      )
  fi
  tabcontents+=(--field=" $(ltr ins_logtool)!$ICO_LOG!$(ltr ins_logtooltip)":fbtn  "eos-log-tool" )
  VboxGuestEnable

  case "$CurrentDesktop" in
      xfce) AddXfceThemingButtons ;;
  esac

  tabcontents+=(--field=" $(ltr after_install_itab)!$ICO_PREFERENCES_DISPLAY!$(ltr after_install_itab_tip)":fbtn "bash -c WelcomeInitialTab")

  [ "$handle" != "calculate" ] && "${tabcontents[@]}" >& /dev/null &
}

AddXfceThemingButtons() {
    XfceTheming() {
        local -r new_theme="$1"
        local -r date_time=$(date +%Y%m%d-%H:%M.%S)
        local -r conf="$HOME/.config"
        local -r conf2='~/.config'
        local -r bak=xfce-theme-bak
        local dir
        local msg=""
        local dirs=(xfce4)
        expac -Q %n endeavouros-skel-xfce4 >/dev/null && dirs+=(Thunar)                        # compatibility for old installs
        local -r dirs_list=$(echo "${dirs[*]}" | tr ' ' ',')
        
        msg+="About to change the Xfce theme to '$new_theme'.\n"
        msg+="The current theme will be saved under folder $conf2/$bak/$date_time\n"
        msg+="The new theme will be in folders $conf2/{$dirs_list}\n\n"
        msg+="Accept theme change and reboot now?"

        eos_yad --form --title="Change Xfce theme to $new_theme" --text="$msg" --image=$ICO_THEME \
                --button='yad-cancel!!Do nothing':1 --button='yad-ok!!Accept theme change and reboot now':0

        case "$?" in
            0)
                mkdir -p "$conf/$bak/$date_time"
                for dir in "${dirs[@]}" ; do
                    mv "$conf/$dir" "$conf/$bak/$date_time/$dir" || return 1                   # save current theme
                    case "$new_theme" in
                        EOS) cp -r "/etc/skel/.config/$dir" "$conf/" || return 1 ;;            # apply EOS theme
                        vanilla) ;;                                                            # will apply vanilla theme after reboot
                    esac
                done
                sleep 1
                reboot
                ;;
        esac
    }
    export -f XfceTheming
    tabcontents+=(
        --field=" $(ltr after_install_themevan)!$ICO_THEME!$(ltr after_install_themevantip)":fbtn "XfceTheming vanilla"
        --field=" $(ltr after_install_themedef)!$ICO_THEME!$(ltr after_install_themedeftip)":fbtn "XfceTheming EOS"
    )
}


PacdiffIcon() {
    # see /etc/eos-script-lib-yad.conf for differs

    for differ in "${EOS_WELCOME_PACDIFFERS[@]}" ; do
        if [ -x /usr/bin/$differ ] ; then
            case "$differ" in
                kompare)      differ_icon=$ICO_KOMPARE ;;
                meld)         differ_icon=$ICO_MELD ;;
                vim)          differ_icon=$ICO_VIM ;;
                *)            differ_icon=$ICO_COMPARE ;;                    # kdiff3 diffuse
            esac
            break
        fi
    done
}

TesterIsoFetching() {
    # for the ISO testers
    if [ $IsIsoTesting = yes ] || pacman -Q fetch-iso &>/dev/null ; then
        IsIsoTesting=yes
        tabcontents+=(
            --field=" Fetch a tester ISO!$ICO_INFO_WEB!For ISO testers only":fbtn   "RunInTerminal fetch-iso"
        )
    fi
}

DailyAssistant() {
  local handle="$1"
  local tabnum="$2"
  local text="<b>$(ltr daily_assistant_text)</b>"

  ButtonsMayHide text

  local _exclamation='&#33;'   # '!'
  local _and='&#38;'           # '&'

  local differ=""                   # PacdiffIcon may change
  local differ_icon=$ICO_COMPARE    # PacdiffIcon may change

  PacdiffIcon

  local tabcontents=(
      eos_yad --align-buttons --use-interp  # don't need explicit 'bash -c' construct when calling functions
      --plug="$handle" --tabnum="$tabnum" --form --image=$ICO_SYSTOOLS
      --text="$text" --columns=2
      # --field=" $(ltr after_install_us) ($EOS_AUR_HELPER)!$ICO_UPDATE!$(ltr after_install_ustip)":fbtn "UpdateWithEosAurHelper"    # "RunInTerminal UpdateInTerminal --lang=$lang"
      # --field=" $(ltr after_install_us) (UpdateInTerminal)!$ICO_UPDATE!$(ltr after_install_ustip)":fbtn "RunInTerminal UpdateInTerminal --lang=$lang"
  )
  AddEosAurHelpers
  MirrorRankingButtons
  tabcontents+=(--field=" Pacdiff $_and $differ!$differ_icon!$(ltr after_install_pacdiff_tip) $differ":fbtn "eos-pacdiff --nt")
  tabcontents+=(
      --field=" $(ltr ins_logtool)!$ICO_LOG!$(ltr ins_logtooltip)":fbtn  "eos-log-tool"
      --field=" $(ltr daily_assist_anews)!$ICO_INFO_WEB!$(ltr daily_assist_anewstip)":fbtn "WelcomeBrowser $ARCH_NEWS_PAGE"
  )

  # General app browsing buttons:
  if [ "$(eos_GetArch)" = "armv7h" ] ; then
      tabcontents+=(
          --field=" $(ltr add_more_apps_arch)!$ICO_INFO_WEB!$(ltr add_more_apps_done2_tip1)":fbtn "WelcomeBrowser $ARM_PACKAGES_PAGE"
      )
  else
      tabcontents+=(
          --field=" $(ltr add_more_apps_arch)!$ICO_INFO_WEB!$(ltr add_more_apps_done2_tip1)":fbtn "WelcomeBrowser $ARCH_PACKAGES_PAGE"
      )
  fi
  tabcontents+=(
      --field=" $(ltr add_more_apps_aur)!$ICO_INFO_WEB!$( ltr add_more_apps_done2_tip2)":fbtn "WelcomeBrowser $AUR_PACKAGES_PAGE"
      --field=" $(ltr daily_assist_apps)!$ICO_INFO_WEB!$(ltr daily_assist_apps_tip)":fbtn "WelcomeBrowser $ARCH_LIST_OF_APPS_PAGE"
  )

  if [ -n "$CurrentDesktop" ] ; then
      local dname
      case "$CurrentDesktop" in
          kde|mate|lxde|gnome)  dname=${CurrentDesktop^^} ;; # KDE_Plasma?
          xfce|cinnamon|budgie) dname=${CurrentDesktop^} ;;  # Xfce ;;
          lxqt)                 dname=LXQt ;;
          *)                    dname="$CurrentDesktop" ;;
      esac
      tabcontents+=(
          --field=" $dname: $(ltr daily_assist_DEinfo)!$ICO_INFO_WEB!$CurrentDesktop: $(ltr daily_assist_DEinfo_tip)":fbtn   "WelcomeBrowser https://wiki.archlinux.org/title/$dname"
      )
  fi
  TesterIsoFetching

  [ "$handle" != "calculate" ] && "${tabcontents[@]}" >& /dev/null &
}

WelcomeInitialTab() {
    ## Welcome tabs are numbered starting from 1.
    ## Note1: This setting is not used while installing.
    ## Note2: This overrides the related setting 'activate_own_commands_tab'
    ##        or the first parameter in call to personal_commands_init()
    ##        in file ~/.config/welcome-own-cmds.conf.

    if [ ! -r "$welcome_configurator" ] ; then
        echo "EOS_WELCOME_ACTIVE_TAB_NUMBER=2  # default: 2 (=After Install)" > $welcome_configurator
    fi
    source "$welcome_configurator"
    [ -z "$EOS_WELCOME_ACTIVE_TAB_NUMBER" ] && export EOS_WELCOME_ACTIVE_TAB_NUMBER=2

    local count="$_NOTEBOOK_TABS_COUNT"
    local txt=""
    txt+="Welcome tabs are numbered from 1 to $count.\n"
    txt+="For example, the <b>After Install</b> tab is number 2.\n"
    txt+="Select the number of the Welcome tab to show initially.\n"
    txt+="After selecting the initial tab, Welcome will be restarted.\n"
    local cmd=(
        eos_yad --form --align-buttons --use-interp --title="Welcome initial tab"
        --text="$txt" --image=$ICO_PREFERENCES_SYSTEM
        --field="Initial tab number\t\t":num "$EOS_WELCOME_ACTIVE_TAB_NUMBER!$ICO_PREFERENCES_DISPLAY!1"
    )
    local result="$("${cmd[@]}" | cut -d '|' -f1)"
    [ -z "$result" ] && return
    sed -i $welcome_configurator -e "s|^EOS_WELCOME_ACTIVE_TAB_NUMBER=[0-9]*|EOS_WELCOME_ACTIVE_TAB_NUMBER=$result|"

    RestartWelcome
}
export -f WelcomeInitialTab

RestartWelcome() {
    local tmpfile=$(mktemp $HOME/.cache/.greeter_restart.XXXXX)
    cat <<EOF > $tmpfile
pkill -f "/usr/bin/yad --window-icon=$EOS_WICON"
sleep 0.2
eos-welcome $WELCOME_ARGS $* &
sleep 0.5
rm -f $tmpfile
EOF
    chmod +x $tmpfile
    $tmpfile
}
export -f RestartWelcome

Github2Gitlab() {
    eos-github2gitlab "$@"
}
export -f Github2Gitlab

Reisub() {
    local file=/etc/sysctl.d/99-reisub.conf
    local time=5000

    case "$1" in
        --enable)    [ -e $file ] || echo 'kernel.sysrq=1' | pkexec tee $file > /dev/null ;;
        --disable)   [ -e $file ] && pkexec rm -f $file ;;
    esac
    if [ -e $file ] ; then
        eos_notification $ICO_INFO normal $time REISUB "REISUB $_COMMONPHRASE_ENABLED" ""
    else
        eos_notification $ICO_INFO normal $time REISUB "REISUB $_COMMONPHRASE_DISABLED" ""
    fi
}
export -f Reisub

UsefulTips() {
  local handle="$1"
  local tabnum="$2"
  local _and='&#38;'           # '&'
  local text="<b>$(ltr useful_tips_text)</b>"
  local -r REISUB_PAGE="https://forum.endeavouros.com/t/tip-enable-magic-sysrq-key-reisub"

  ButtonsMayHide text

  local tabcontents+=(
      eos_yad --align-buttons --use-interp
      --plug="$handle" --tabnum="$tabnum" --form --columns=2
      --image=$ICO_TIPS
      --text="$text"
  )
  AddWelcomeTipPages

  [ "$handle" != "calculate" ] && "${tabcontents[@]}" >& /dev/null &
}

AddWelcomeTipPages() {
    local WELCOME_TIP_PAGES=()
    local -r file=/usr/share/endeavouros/scripts/welcome-tip-pages   # contains the WELCOME_TIP_PAGES array
    source $file || return 1
    local button tip url_or_command ico
    local item                                       # button name | description or tip | url
    for item in "${WELCOME_TIP_PAGES[@]}" ; do
        ico=""
        button="${item%%|*}"                                             ; item=${item#*|}
        [ "$button" = "$item" ]         || tip="${item%%|*}"             ; item=${item#*|}
        [ "$tip" = "$item" ]            || url_or_command="${item%%|*}"  ; item=${item#*|}
        [ "$url_or_command" = "$item" ] || ico="${item%%|*}"             # ; item=${item#*|}

        [ "$ico" ] || ico="$ICO_INFO_WEB"    # not all definitions include icon field

        case "$ico" in
            "$ICO_INFO_WEB") tabcontents+=(--field=" $button!$ico!$tip":fbtn  "WelcomeBrowser '$url_or_command'") ;;
            *)               tabcontents+=(--field=" $button!$ico!$tip":fbtn  "$url_or_command")
        esac
    done
}

AddMoreApps() {
  local handle="$1"
  local tabnum="$2"
  local text=""

  local tabcontents=(
      eos_yad --align-buttons --use-interp
      --plug="$handle" --tabnum="$tabnum" --form --text-align=left --columns=2
      --image=$ICO_INSTALL
  )
  local shown_app_buttons=0

  ((shown_app_buttons++))
  tabcontents+=(--field=" $(ltr add_more_apps_qs)!$ICO_SYSTOOLS!$(ltr add_more_apps_qstip)":fbtn "eos-quickstart")

  tabcontents+=(--field=" $(ltr daily_assist_apps)!$ICO_INFO_WEB!$(ltr daily_assist_apps_tip)":fbtn "WelcomeBrowser $ARCH_LIST_OF_APPS_PAGE")
  tabcontents+=(--field=" $(ltr add_more_apps_aur)!$ICO_INFO_WEB!$( ltr add_more_apps_done2_tip2)":fbtn "WelcomeBrowser $AUR_PACKAGES_PAGE")

  # General app browsing buttons:
  if [ "$(eos_GetArch)" = "armv7h" ] ; then
      tabcontents+=(--field=" $(ltr add_more_apps_arch)!$ICO_INFO_WEB!$(ltr add_more_apps_done2_tip1)":fbtn "WelcomeBrowser $ARM_PACKAGES_PAGE")
  else
      tabcontents+=(--field=" $(ltr add_more_apps_arch)!$ICO_INFO_WEB!$(ltr add_more_apps_done2_tip1)":fbtn "WelcomeBrowser $ARCH_PACKAGES_PAGE")
  fi

  # Now we know if we have any apps in the install list.

  if [ $shown_app_buttons -eq 0 ] ; then
      text="<b>$(ltr add_more_apps_done1_text)$(ltr add_more_apps_done2_text)</b>"
  else
      text="<b>$(ltr add_more_apps_text) $(ltr add_more_apps_done2_text)</b>"
  fi
  ButtonsMayHide text
  tabcontents+=(--text="$text")

  [ "$handle" != "calculate" ] && "${tabcontents[@]}" >& /dev/null &
}

#### Support for personal commands:

personal_commands_add() {   # add one personal command
    [ "$is_installing" = "yes" ] && return
    local commandline="$1"
    local name="$2"
    local icon="$3"
    local description="$4"
    local cmd="$5"

    [ -n "$description" ] || description="$commandline"
    [ -n "$cmd" ] || cmd="$(echo "$commandline" | /usr/bin/awk '{print $1}')"

    if (/usr/bin/which $cmd &> /dev/null) ; then
        welcome_own_commands+=(--field=" $name!$icon!$description":fbtn "$commandline")
    else
        printf "%s: %s\n    %s\n" "$(/usr/bin/date "+%x %X")" "$FUNCNAME:" "warning: command '$cmd' not found" >> /tmp/welcome-personal-commands.log
        echo "$FUNCNAME: warning: command '$cmd' not found" >&2
    fi
}

personal_commands_init() {  # initialize user settings for personal commands
    [ "$is_installing" = "yes" ] && return
    [ -n "$1" ] && activate_own_commands_tab="$1"
    [ -n "$2" ] && columns_for_own_commands="$2"
    [ -n "$3" ] && show_predefined_buttons_at_own_commands="$3"
}

_align_buttons_on_tab() {
    # handles old _align() marking in ~/.config/welcome-own-cmds.conf

    local -n arr="$1"
    local handle="$2"
    local ix xx

    # just remove possible legacy "_align(...) construct"
    ix=0
    for xx in "${arr[@]}" ; do
        case "$xx" in
            --field=*)
                if [ "$xx" != "${xx/*_align(/}" ] ; then
                    arr[$ix]="$(echo "$xx" | sed 's|_align(\(.*\))!| \1!|')"
                fi
                ;;
        esac
        ((ix++))
    done
}

OwnCommands() {
  local handle="$1"
  local tabnum="$2"
  local cols="$columns_for_own_commands"
  local show_buttons="$show_predefined_buttons_at_own_commands"

  case "$show_buttons" in
      no) ;;
      *) show_buttons=yes ;;
  esac

  while true ; do
      if [ -z "$cols" ] ; then
          cols=2
      elif [ -n "$(echo "$cols" | tr -d '0-9')" ] ; then
          cols=2
          echo "Warning: value '$columns_for_own_commands' for variable 'columns_for_own_commands' is unsupported, using $cols." >&2
      elif [ $cols -lt 1 ] || [ $cols -gt 20 ] ; then
          cols=2
          echo "Warning: value '$columns_for_own_commands' for variable 'columns_for_own_commands' is unsupported, using $cols." >&2
      fi
      break
  done

  local tabcontents=(
      eos_yad --align-buttons --use-interp
      --plug="$handle" --tabnum="$tabnum" --form --columns=$cols
      --image=$ICO_OWN_COMMANDS
      --text="<b>$(ltr nb_tab_owncmds_text)</b>"
  )
  if [ "$show_buttons" = "yes" ] ; then
      tabcontents+=(
          --field=" $(ltr butt_owncmds_help)!$ICO_INFO_WEB!$(ltr nb_tab_owncmdstip)":fbtn   "WelcomeBrowser $adding_own_commands"
          --field=" $(ltr butt_owncmds_dnd)!$ICO_SYSTOOLS!$(ltr butt_owncmds_dnd_help)":fbtn  "welcome-dnd"
      )
  fi
  tabcontents+=("${welcome_own_commands[@]}")

  _align_buttons_on_tab tabcontents "$handle"

  [ "$handle" != "calculate" ] && "${tabcontents[@]}" >& /dev/null &
}


# Fields explanation:
# --field="ButtonName!!Tooltip":fbtn "Command"

### These variables are required:

CreateNotebookCommands() {
    if IsInstalling ; then
        _NOTEBOOK_TABS=(                             # names of functions above
            INSTALL
            GeneralInfo
        )
    else
        _NOTEBOOK_TABS=(                             # names of functions above
            GeneralInfo
            AfterInstall
            DailyAssistant
            UsefulTips
            AddMoreApps
        )
    fi
    if [ "$is_installing" = "no" ] ; then
        if [ -n "$welcome_own_commands" ] ; then
            _NOTEBOOK_TABS+=(OwnCommands)
        fi
    fi
    export _NOTEBOOK_TABS_COUNT=${#_NOTEBOOK_TABS[@]}
}

####################### DO NOT CHANGE ANYTHING AFTER THIS LINE! ######################################################

DIE() {
    local title="Error"
    while true ; do
        echo "Error: $1."
        Usage
        break
    done | eos_yad_problem "$title" --fontname="Mono 10" --height=700 "$@"
    exit 1
}

WelcomeHelp_opt() {
    Usage | eos_yad --text-info --title="$WH_BUTT_TITLE" --width=700 --height=500 \
                    --fontname="Mono 10" \
                    --text="<b>$WH_BUTT_TEXT</b>" \
                    --text-align=left \
                    --image=$ICO_HELP --button=yad-ok:0
    [ "$1" ] && exit $1
}
WelcomeHelp() {
    WelcomeBrowser "$EOS_WELCOME_PAGE"
}
export -f WelcomeHelp

WelcomeBrowser() {
    $_WELCOME_BROWSER "$1" &>/dev/null
}
export -f WelcomeBrowser

WelcomeChangelog() {
    WelcomeBrowser "$(Github2Gitlab $WELCOME_CHANGELOG_PAGE)"
}
export -f WelcomeChangelog

ImportantNews() {
    WelcomeBrowser "$(Github2Gitlab $WELCOME_NEWS_PAGE)"
}
export -f ImportantNews

SetBrowser() {
    [ -n "$_WELCOME_BROWSER" ] && return
    case "$is_installing" in
        yes) export _WELCOME_BROWSER=firefox ;;
        *)   export _WELCOME_BROWSER="$(eos_select_browser)" ;;
    esac
}
export -f SetBrowser

PrepareTabs() {
    local handle="$1"
    local xx ix

    ix=1
    for xx in "${_NOTEBOOK_TABS[@]}" ; do
        $xx "$handle" "$((ix++))" "$xx"
    done
}

SeparateWordsWithSpaces() { # add a space before a capital letter inside a word
    local tabname="$1"

    if [ "$(echo "$tabname" | tr -d '[a-z]')" = "$tabname" ] ; then
        echo "$tabname"           # all capital letters ==> don't change
    else
        echo "$tabname" | sed -e 's|\([A-Z]\)| \1|g' -e 's|^ ||'  # add space before capital letters
    fi
}


WelcomeSettings() {
    local value="$1"   # enable, disable, check
    declare -A defaults
    local xx

    defaults[Greeter]="Greeter=enable"
    defaults[LastCheck]="LastCheck=0"
    defaults[OnceDaily]="OnceDaily=no"

    # Make sure we have sensible initial values in the config file.
    if [ ! -r "$WELCOME_CONFIG" ] ; then
        cat <<EOF > "$WELCOME_CONFIG"
## Configuration file for $PROGNAME.
# Note: using bash syntax.
#
# 'Greeter'   values: enable or disable.
# 'OnceDaily' values: no or yes; yes means $PROGNAME is shown only once a day.
# 'LastCheck' values: automatically filled by $PROGNAME.

EOF
    fi

    for xx in Greeter OnceDaily LastCheck ; do
        if [ -z "$(grep "^${xx}=" "$WELCOME_CONFIG" 2>/dev/null)" ] ; then
            echo "${defaults[$xx]}" >> "$WELCOME_CONFIG"
        fi
    done

    # Now the initial values are in order.

    case "$value" in
        enable | disable)
            sed -i "$WELCOME_CONFIG" -e 's|^Greeter=.*$|Greeter='"$value"'|'
            ;;
    esac

    case "$value" in
        disable)
            eos_yad --form --image=$ICO_INFO --text="$(ltr settings_dis_contents)" \
                    --title="$(ltr settings_dis_title)" \
                    --button=" $(ltr settings_dis_butt)!$ICO_EXIT!$(ltr settings_dis_buttip)":11
            ;;
        check)
            grep "^Greeter=" "$WELCOME_CONFIG" 2>/dev/null | cut -d '=' -f 2
            ;;
        continue)
            if [ "$(grep "^OnceDaily=" "$WELCOME_CONFIG" 2>/dev/null | cut -d '=' -f 2)" = "no" ] ; then
                echo yes
                return
            fi
            local date="$(date +%Y%m%d)"
            if [ "$(grep "^LastCheck=" "$WELCOME_CONFIG" 2>/dev/null | cut -d '=' -f 2)" = "$date" ] ; then
                echo "Info: Stopping because of setting OnceDaily=yes in file $WELCOME_CONFIG." >&2
                echo no
            else
                echo yes
            fi
            sed -i "$WELCOME_CONFIG" -e 's|^LastCheck=.*$|LastCheck='"$date"'|'
            ;;
    esac
}

IsR8168Card() {
    # Return 0 if ethernet card is realtek 8168.

    if [ 0 -eq 1 ] && [ "$testing" = "yes" ] ; then   # this is only for testing
        return 0
    fi

    if [ -n "$(/usr/bin/lspci | /usr/bin/grep -w "Ethernet controller" | /usr/bin/grep -w 8168)" ] ; then   # have the card?
        if [ -n "$(lsmod | grep -Pw 'r8169|r8168')" ] ; then                                                # driver is in use?
            return 0
        fi
    fi
    return 1
}
export -f IsR8168Card

ethernet_toggle_r8168_r8169() {
    local cmds=":"
    local prompt=""
    if (! IsInstalled r8168) ; then
        prompt="echo 'r8169 ==> r8168'"
        if (eos-connection-checker) ; then
            cmds+="; pacman -Syu --noconfirm r8168"
        else
            local pkg="$(/usr/bin/ls -1 /opt/extra-drivers/r8168-*-x86_64.pkg.tar.zst 2>/dev/null)"  # may find it in /opt/extra-drivers !
            if [ -n "$pkg" ] ; then
                cmds="; pacman -U --noconfirm $pkg"
            else
                w_WARN "sorry, cannot install r8168 because there's no internet connection."
                return 1
            fi
        fi
        cmds+="; modprobe -r r8169 2>/dev/null"
        cmds+="; modprobe r8168 2>/dev/null"
    else
        prompt="echo 'r8168 ==> r8169'"
        cmds+="; pacman -Rsn --noconfirm r8168"
        cmds+="; modprobe -r r8168 2>/dev/null"
        cmds+="; modprobe r8169 2>/dev/null"
    fi
    cmds+="; systemctl restart NetworkManager"
    RunInTerminal "$prompt ; $EOS_ROOTER '$cmds'"
}
export -f ethernet_toggle_r8168_r8169

R8168check_at_install() {
    local card8168="$(lspci -vnn | grep -w Ethernet | grep -w Realtek | grep -w 8168 )"
    if [ -n "$card8168" ] ; then
        # we have 8618 card
        local cardid="$(echo "$card8168" | sed 's|.*\[\([^]]*\)\].*|\1|')"    # e.g. "10ec:8168"
        case "$cardid" in
            # 10ec:8168) ;;                # card id is known to work with kernel's r8169 module
            *)
                # Package r8168 is available in /opt/extra-drivers.
                local txt=""
                txt+="Your Ethernet card is set to use the kernel driver r8169 by default.\n"
                txt+="In some rare cases the r8168 driver works better.\n"
                txt+="If your Ethernet connection has problems with r8169, you can use the r8168 driver.\n"
                local cmd=(
                    eos_yad
                    --form
                    --image=$ICO_QUESTION
                    --title="Select the driver for the Realtek 8168 Ethernet card"
                    --text="$txt"
                    --button="r8168":1
                    --button="r8169 (default)":3
                )
                "${cmd[@]}"
                case "$?" in
                    1)
                        # use r8168 which is stored at /opt/extra-drivers
                        local pkg="$(/usr/bin/ls -1 /opt/extra-drivers/r8168-*-x86_64.pkg.tar.zst 2>/dev/null)"
                        if [ -n "$pkg" ] ; then
                            sudo pacman -U --noconfirm $pkg
                            sudo modprobe -r r8169 2>/dev/null
                            sudo modprobe r8168 2>/dev/null
                            sudo systemctl restart NetworkManager
                        fi
                        ;;
                esac
                ;;
        esac
    fi
}

MagicId_new() {
    # special support for user_commands.bash

    if (! IsInstalling) ; then
        echo "Option '--ni' is only an install time feature." >&2
        return 1
    fi

    local id="$1"     # URL or special id
    local url=""

    case "$id" in
        "")
            echo "Option --ni: URL or special id is missing'." >&2
            return 1
            ;;
        https://* | http://*)
            url="$id"
            ;;
        *)
            # use special id
            url=https://raw.githubusercontent.com/endeavouros-team/sandbox/master/pkg/list  # currently not in gitlab!
            local data=$(curl -Lsm 10 -o- $url)
            [ -n "$data" ] || { echo "Option --ni: failed to fetch data." >&2 ; return 1 ; }
            url=$(echo "$data" | grep "^$id"= | cut -d'=' -f2)
            [ -n "$url" ] || { echo "Option --ni: URL not found." >&2 ; return 1 ; }
            ;;
    esac

    if [ ! -r /home/$EOS_LIVEUSER/user_commands.bash.bak ] ; then
        cp /home/$EOS_LIVEUSER/user_commands.bash /home/$EOS_LIVEUSER/user_commands.bash.bak
    fi
    if ! curl --fail -Lsm 10 -o/home/$EOS_LIVEUSER/user_commands.bash "$url" ; then
        echo "Sorry, cannot find URL $url" >&2
        return 1
    fi
    return 0
}
export -f MagicId_new

MagicId() {
    local ENDEAVOUROS_TEAM=https://raw.githubusercontent.com/endeavouros-team
    if (! IsInstalling) ; then
        echo "Sorry, option --id is only an install feature." >&2
        return 1
    fi
    local id="$1"
    if [ -z "$id" ] ; then
        echo "Id value missing." >&2
        return 1
    fi
    local target=$HOME/user_pkglist.txt
    local time
    local data="$(curl -s $ENDEAVOUROS_TEAM/sandbox/master/pkg/list)"
    if [ -z "$data" ] ; then
        echo "Error: list not found." >&2
        return 1
    fi
    local url="$(echo "$data" | grep "^$id=" | sed "s|^$id=||")"
    if [ -z "$url" ] ; then
        echo "Id '$id' not found." >&2
        return 1
    fi
    if [ -r $target ] ; then
        time=$(date +%Y%m%d-%H%M-%S)
        echo "Moving existing $target to $target.$time" >&2
        mv $target $target.$time
    fi
    if (! Wget2Curl -q -O $target "$url") ; then
        echo "Sorry, URL '$url' not found. " >&2
        [ -r $target.$time ] && mv $target.$time $target
        return 1
    fi
    case "$id" in
        ma) if (! Wget2Curl -q -O pkglist_install.sh "$ENDEAVOUROS_TEAM/sandbox/master/pkg/pkglist_install.sh") ; then
                echo "Warning: cannot fetch pkglist_install.sh from sandbox" >&2
                return 1
            fi
            sudo cp pkglist_install.sh /usr/lib/calamares/modules/user_pkglist/
            ;;
    esac
    echo "$target: OK" >&2
}

VboxGuestEnable() {
    case "$(device-info --vm)" in
        virtualbox)
            if [ -n "$(systemctl status vboxservice 2>/dev/null | grep "inactive (dead)")" ] ; then
                local label="$(ltr after_install_vbox1)"
                local msg1="$(ltr after_install_vbox2)"
                local cmd="systemctl enable --now vboxservice.service"
                local msgvb="$msg1\n<b>$label</b>"
                local icon=$ICO_TIPS
                eos_yad --form --title="Info" --text="$msgvb" --image=$ICO_TIPS --button=yad-quit:0 &
                tabcontents+=(--field=" $label!$ICO_ENABLE!$cmd":fbtn "RunInTerminal $cmd")
            fi
            ;;
    esac
}

KillExtraYad() {
    sleep 0.2
    eos-kill-yad-zombies
}

Usage() {
    cat <<EOF
===== $PROG_PACKAGENAME $PROG_VERSION =====

Usage: $PROGNAME [options]

Options:
--startdelay=X    Wait before actually starting this app.
                  X value syntax is the same as in 'sleep'.
--enable | -f     Enable this $PRETTY_PROGNAME app.
--disable         Disable this $PRETTY_PROGNAME app.
--once | -1       Run $PRETTY_PROGNAME once, even if it is disabled.
--version         Show the version of this app.
--lang=X          Use language X on the user interface.

To have $PRETTY_PROGNAME app started when you log in, make sure
- $PRETTY_PROGNAME app is selected in the Autostart feature of the DE
    OR
- "Hidden=false" is set in file /etc/xdg/autostart/welcome.desktop

On DEs that do not work well with Autostart:
You may also disable the $PRETTY_PROGNAME app from the app itself
- with the --disable option
- with a button in the app (some DEs only)

To re-enable the app, use the terminal command
    $PROGNAME --enable

Note: check also settings in the configuration file $WELCOME_CONFIG2.

Option --lang=X is currently experimental and supports only a very small set
of languages. The value X should consist of two lowercase letters
(like 'en' for English or 'de' for German).
If option --lang is not given, the value is extracted from
the first two letters of the environment variable LANG (now: ${LANG::2}).
EOF
}
export -f Usage


#Experimental options:
#--genlang=X       Generate language X support for the user interface of the Welcome app.
#                  X is a shorthand of two lowercase letters, like de, en, or fr.
#                  Note: requires package 'translate-shell' to be already installed.
#                  Try command 'trans -R' to see a list of available languages.

#--changelog       Show the changelog of this package.

# --tr-prefer=X     Prefer either 'manual' or 'generated' language on the user interface.
#                   Note: value 'generated' is meaningful only after option --genlang has
#                   been used at least once.

#Install time options:
#--pkglist=URL     User can give an URL to a file that contains a list of additional packages
#                  to install. Package names are listed as one package name per line.
#                  Empty lines and comments (lines starting with character #) are allowed.

GetIsoVersion() {
    if [ -z "$ISO_VERSION" ] ; then
        local file=/usr/lib/endeavouros-release
        if [ -r $file ] ; then
            ISO_VERSION="$(grep "^VERSION=" $file | sed -E 's|^VERSION=([0-9\.]+).*|\1|')"
        fi
    fi
}

GetIsoDateStr() {
    echo "ISO: $ISO_VERSION"
}

SetCalamaresVersionInfo() {
    if [ -n "$ISO_VERSION" ] ; then
        local file=/etc/calamares/branding/endeavouros/branding.desc
        if [ -f $file ] ; then
            local str

            for str in "version:" "shortVersion:" ; do
                if [ "$(grep -w "$str" $file | awk '{print $2}')" != "$ISO_VERSION" ] ; then
                    sudo sed -i $file -E "s|^([ ]+$str[ ]+).*|\1$ISO_VERSION|"
                fi
            done
        fi
    fi
}

VerboseLog() {
    if [ "$WELCOME_VERBOSE_LOG" = "yes" ] ; then
        echo "$@" >> /tmp/welcome-verbose.log
    fi
}

AssignIconVariables() {
    # button icons, see
    #   https://specifications.freedesktop.org/icon-naming-spec/latest/ar01s04.html
    #   https://specifications.freedesktop.org/icon-naming-spec/latest/ar01s02.html

    AssignIconVariables_in_eos_bash_shared

    VerboseLog "ICO_INFO_WEB = $ICO_INFO_WEB"

    export ICO_BOOKMARK=$(eos_icon_path places bookmarks)
    export ICO_EXIT=$(eos_icon_path apps preferences-desktop-user)
    export ICO_CUSTOM=$(eos_icon_path apps preferences-desktop-tweaks)
    export ICO_PREFERENCES_DISPLAY=$(eos_icon_path apps preferences-desktop-display)
    # export ICO_GPARTED=$(eos_icon_path devices drive-harddisk)
    export ICO_GPARTED=$(eos_icon_path apps gparted)
    export ICO_PARTITIONMANAGER=$(eos_icon_path apps partitionmanager)
    export ICO_WALL=$(eos_icon_path apps preferences-desktop-wallpaper)
    export ICO_WALL_DOWNLOAD=$(eos_icon_path mimetypes application-x-partial-download)
    export ICO_THEME=$(eos_icon_path apps preferences-desktop-theme)
    export ICO_ENABLE=$(eos_icon_path apps system-run)
    export ICO_OWN_COMMANDS=$(eos_icon_path apps applications-featured)

    export ICO_SAD=$ICO_EXIT
    #export ICO_ANGEL=face-angel

    ## Alternatives for ICO_INSTALL_ARM:
    # export ICO_INSTALL_ARM=$(eos_icon_path devices media-flash)
    # export ICO_INSTALL_ARM=$(eos_icon_path devices drive-removable-media)
    export ICO_INSTALL_ARM=$(eos_icon_path apps usb-creator)
    export ICO_MELD=/usr/share/icons/Qogir/scalable/apps/meld.svg
    export ICO_VIM=/usr/share/icons/Qogir/scalable/apps/vim.svg
    export ICO_KOMPARE=/usr/share/icons/Qogir/scalable/apps/kompare.svg
    export ICO_COMPARE=/usr/share/icons/Qogir/scalable/apps/bcompare.svg
}

LangChoose() {
    local cmd=(
        eos_yad --list
        --title="Select language variation for 'Welcome'"
        --column="Language" --column=""
        --width=400 --height=600

        "English"                               en_US
        "Catalan (català)"                      ca_AD
        "German (Deutsch)"                      de_DE
        "Spanish (Español・Española)"           es_ES
        "Persian (فارسی)"                       fa_IR
        "Finnish (Suomi)"                       fi_FI
        "French (Francés・Francesa)"            fr_FR
        "India (हिंदी-भारत)"                        hi_IN
        "Croatian (Hrvatski)"                   hr_HR
        "Icelandic (Íoslainnis)"                is_IS
        "Italian (Italiano・Italiana)"          it_IT
        "Japanese (日本語)"                     ja_JP
	"Dutch (Nederlands)"                    nl_NL
        "Polish (Polski)"                       pl_PL
        "Portuguese (Português)"                pt_PT
        "Portuguese-Brazil (Português-Brasil)"  pt_BR
        "Romanian (Română)"                     ro_RO
        "Russian (Русский)"                     ru_RU
        # "Serbian (Srpski)" sr_?        # translation file incorrectly named as translation-rs.bash; rs should be: sr !!
        "Slovak (slovenský)"                    sk_SK
        "Sweden (Svenska)"                      sv_SE
        "Thai (แบบไทย)"                         th_TH
        "Ukrainian (українська)"                uk_UA
        "Chinese-China (中文-中国)"             zh_CN
        "Chinese-HongKong (中文-香港)"          zh_HK
        "Chinese-Singapore (中文-新加坡)"       zh_SG
        "Chinese-Taiwan (中文-台灣)"            zh_TW
    )
    if [ -z "$lang" ] ; then
        local out
        out=$("${cmd[@]}")
        [ -n "$out" ] || return                                    # defaults to English
        lang=$(echo "$out" | cut -d'|' -f2)
    fi
    if [ "$is_installing" = "yes" ] ; then
        # change locale only when installing
        if [ -z "$(grep "^$lang.UTF-8 UTF-8$" /etc/locale.gen)" ] ; then
            cp /etc/locale.gen /tmp/locale.gen.tmp
            echo "$lang.UTF-8 UTF-8" >> /tmp/locale.gen.tmp
            sudo cp /tmp/locale.gen.tmp /etc/locale.gen
            sudo locale-gen
        fi
        export LANG="$lang.UTF-8"
    fi
}
export -f LangChoose

LangImplConvert() {
    # convert user given language spec to support translation files in package eos-translations
    lang=${lang%%.*}                           # skip stuff after the dot, e.g. 'nl_NL.UTF-8' to 'nl_NL'
    case "$lang" in
	pt_BR | zh_?? | uk_UA | nl_NL) ;;
        *) lang=${lang%%_*} ;;                 # for the rest we have only support for 'xx' from 'xx_YY'
    esac
}
export -f LangImplConvert

LanguageSelection() {
    # $lang must match the '*' in the translation file names, i.e.
    # /usr/share/endeavouros/scripts/translation-*.bash.

    local lang=""

    LangChoose ALL
    LangImplConvert

    RestartWelcome --lang=$lang
}
export -f LanguageSelection

LanguageSelectionButton() {
    [ "$is_installing" = "no" ] && return
    lang=""
    local ico=/usr/share/icons/Qogir/scalable/apps/applications-languages.svg
    notebook+=(--button=" Change Language!$ico!Select another supported language for Welcome":"LanguageSelection")
}

IncludesOption() {
    local option="$1"
    shift
    printf "%s\n" "$@" | grep "^$option$" >/dev/null
}

HandleOptions1() {
    local opts
    opts="$(/usr/bin/getopt -o="$SOPTS" --longoptions "$LOPTS" --name "$PROGNAME" -- "$@")" || WelcomeHelp_opt 1
    eval set -- "$opts"

    while true ; do
        case "$1" in
            --)                    shift; break ;;
            --changelog)           WelcomeChangelog; exit ;;
            --lang | -l)           lang="$2"; shift ;;
            --tr-engine)           tr_engine="$2"; shift ;;
            --tr-prefer)           tr_prefer="$2"; shift ;;
            --id)                  MagicId "$2" && shift || exit 0 ;;
            --ni)                  MagicId_new "$2" && shift || exit 0 ;;
            --genlang)             lang="$2"
                                   shift
                                   LangImplConvert
                                   _init_translations --tr-engine="$tr_engine" --generate "$lang"
                                   exit $?
                                   ;;
        esac
        shift
    done
}
HandleOptions2() {
    local opts
    opts="$(/usr/bin/getopt -o="$SOPTS" --longoptions "$LOPTS" --name "$PROGNAME" -- "$@")" || WelcomeHelp_opt 1
    eval set -- "$opts"

    while true ; do
        case "$1" in
            --)             shift; break ;;
            --disable)      WelcomeSettings disable ; exit ;;
            --enable|-f)    WelcomeSettings enable ;;
            --help|-h)      WelcomeHelp_opt 0 ;;
            --once | -1)    allow_run_if_disabled=yes ;;
            --startdelay)   start_delay="$2"; shift ;;
            --testing)      testing=yes ;;
            --version)      echo "$PROG_VERSION" >&2 ; exit ;;

            --changelog | --genlang | --installer | --verboselog) ;;            # already handled
            --id | --lang | -l | --ni | --tr-engine | --tr-prefer) shift ;;     # already handled
        esac
        shift
    done
    [ "$1" ] && DIE "unsupported parameter '$1'"
}

StartHere() {
    eos_assert_deps $PROGNAME yad || return 1
    DebugBreak

    local -r LOPTS="changelog,lang:,tr-engine:,tr-prefer:,id:,ni:,verboselog,genlang:,help,enable,disable,once,startdelay:,version,testing,installer"
    local -r SOPTS="1fhl:"

    local arg lang=""
    local yad_zombie_log=/tmp/yad-zombies.log
    local tr_engine=bing
    local tr_prefer=manual
    local pb_percent=0
    local testing=no
    local allow_run_if_disabled=no            # yes = allow run even if disabled

    local welcome_own_commands=()
    local activate_own_commands_tab="no"
    local columns_for_own_commands="2"
    local show_predefined_buttons_at_own_commands="yes"
    local has_a_connection=no
    local ISO_VERSION=""                      # only for the installer
    local CurrentDesktop=""
    local IsIsoTesting=no

    export NewFieldHandling=yes

    source /etc/welcome-installer.conf || DIE "file /etc/welcome-installer.conf not found"

    IncludesOption --verboselog "$@" && export WELCOME_VERBOSE_LOG=yes

    GetCurrentDesktop CurrentDesktop
    AssignIconVariables

    export show_installer=no    # explicitly show the installer, for testing only

    IncludesOption --installer "$@" && export show_installer=yes

    local install_mode=""
    local is_installing=no

    IsInstalling && is_installing=yes

    if [ "$is_installing" = "yes" ] && [ -z "$lang" ] ; then
        lang="$LANG"
        LangImplConvert
        _init_translations --tr-prefer="$tr_prefer" "$lang" || { echo "language fail" >&2 ; exit 1 ; }
        AfterTranslations
    fi


    if eos-connection-checker ; then
        has_a_connection=yes
    else
        if [ $is_installing = yes ] ; then
            if type systemsettings >& /dev/null ; then
                local -r ICO_NETWORKMANAGER=/usr/share/icons/Qogir/scalable/apps/networkmanager.svg
                eos_yad --form \
                        --title="$(ltr ins_conn_issue_title)" \
                        --image=$ICO_QUESTION \
                        --text="$(ltr ins_conn_issue_text)" \
                        --button="$(ltr ins_conn_issue_nm1)!$ICO_NETWORKMANAGER!$(ltr ins_conn_issue_nm2)":1 \
                        --button="$(ltr ins_conn_issue_oi1)!$ICO_INSTALL!$(ltr ins_conn_issue_oi2)":3 \
                        --button="$(ltr ins_conn_issue_ex1)!$ICO_EXIT!$(ltr ins_conn_issue_ex2)":5
                case "$?" in
                    1) systemsettings kcm_networkmanagement
                       eos-connection-checker && has_a_connection=yes
                       ;;
                    3) install_mode=offline ;;
                    5) return ;;
                    *) return 1 ;;
                esac
            else
                local sleeptime=1
                local rounds=10
                while true ; do
                    eos_yad --form \
                            --title="What next?" \
                            --image=$ICO_QUESTION \
                            --text="Internet connection not found.\nDo you want to quit, wait for a connection, or continue without a connection?" \
                            --button="Quit!Quit this program":1 \
                            --button="Wait $((sleeptime * rounds))s and ask!Wait a few seconds for a connection":3 \
                            --button="Wait indefinitely!!Wait indefinitely for a connection":7 \
                            --button="Continue!Continue without connection":5
                    case "$?" in
                        1) return ;;
                        3) for round in $(seq $rounds) ; do
                               sleep $sleeptime
                               if eos-connection-checker ; then
                                   has_a_connection=yes
                                   eos_yad --form --title="Connection OK" --text="Connection established, will continue." \
                                           --button=yad-ok --timeout=3 --no-focus --width=200
                                   break 2
                               fi
                           done
                           ;;
                        5) break ;;
                        7) while true ; do
                               sleep $sleeptime
                               if eos-connection-checker ; then
                                   has_a_connection=yes
                                   eos_yad --form --title="Connection OK" --text="Connection established, will continue." \
                                           --button=yad-ok --timeout=3 --no-focus --width=200
                                   break 2
                               fi
                           done
                           ;;
                    esac
                done
            fi
        fi
    fi

    [ -z "$EOS_FILESERVER_SITE" ] && EOS_FILESERVER_SITE="gitlab"
    if [ "$is_installing" = "yes" ] ; then

        EOS_FILESERVER_SITE="$(eos-select-file-server)"        # do this first at install !!!

        if [ "$has_a_connection" = "yes" ] ; then
            local timezone="$(show-location-info timezone)"
            if [ -n "$timezone" ] ; then
                local preprelogfile="$(eos-select-file-server --logfilename)"
                echo "==> $PROGNAME: info: setting timezone to '$timezone'" >> "$preprelogfile"
                timedatectl set-timezone "$timezone"
                sleep 0.1
            fi
        fi

        GetIsoVersion
        # SetCalamaresVersionInfo
    fi
    export EOS_FILESERVER_SITE
    export EOS_AUR_HELPER
    [ -n "$EOS_AUR_HELPER_OTHER" ] && export EOS_AUR_HELPER_OTHER
    export WELCOME_ARGS="$*"

    SetBrowser

    HandleOptions1 "$@"

    if [ "$is_installing" = "no" ] && [ -z "$lang" ] ; then
        lang="$LANG"
    fi
    LangImplConvert

    DebugBreak

    _init_translations --tr-prefer="$tr_prefer" "$lang" || { echo "language fail" >&2 ; exit 1 ; }

    AfterTranslations

    KillExtraYad > /tmp/yad-zombies.log

    local -r WELCOME_CONFIG="$HOME/.config/EOS-greeter.conf"      # "Welcome" used to be "Greeter" ...
    local -r WELCOME_CONFIG2='$HOME/.config/EOS-greeter.conf'
    export welcome_configurator="$HOME/.config/welcome.conf"      # another welcome config... should combine these

    if [ -r "$welcome_configurator" ] ; then
        if [ -n "$(grep "^local ConfVersion" "$welcome_configurator")" ] || [ -n "$(grep "^local MaxButtonNameLength" "$welcome_configurator")" ] ; then
            # this is an old config file, just delete the file
            rm -f "$welcome_configurator"
        fi
    fi

    [ -r "$welcome_configurator" ] && source "$welcome_configurator"

    [ "$EOS_WELCOME_ACTIVE_TAB_NUMBER" ] || EOS_WELCOME_ACTIVE_TAB_NUMBER=2

    export EOS_WELCOME_ACTIVE_TAB_NUMBER

    export user_pkglist_url=""
    local start_delay=0
    local _NOTEBOOK_TITLE="$PRETTY_PROGNAME v$PROG_VERSION"        # main window title

    if [ "$is_installing" = "yes" ] ; then
        [ -n "$ISO_VERSION" ] && _NOTEBOOK_TITLE+="  [$(GetIsoDateStr)]"
    fi

    HandleOptions2 "$@"

    export WELCOME_LANG="$lang"

    [ "$(WelcomeSettings continue)" = "no" ] && return

    local adding_own_commands=$(Github2Gitlab $WELCOME_ADD_COMMANDS_INFO)
    local own_commands_conf="$HOME/.config/welcome-own-cmds.conf"

    [ -r    "$own_commands_conf" ] && source "$own_commands_conf"

    CreateNotebookCommands

    if [ "$(WelcomeSettings check)" != "enable" ] && [ "$allow_run_if_disabled" = "no" ]; then
        ltr2 welcome_disabled
        return
    fi

    local do_r8168_check=no     # yes or no

    if [ "$do_r8168_check" = yes ] && [ "$is_installing" = "yes" ] ; then
        R8168check_at_install
    fi

    [ "$start_delay" != "0" ] && sleep "$start_delay"

    if [ "$is_installing" = "no" ] ; then
        local verbosity
        if [ "$EOS_WELCOME_CONNECTION_WARNING" = "yes" ] ; then
            verbosity=verbose
        else
            verbosity=none
        fi

        eos_yad_check_internet_connection $verbosity 2 "3s" "Welcome" || return 1

        if [ -n "$TERMINAL_AT_START" ] ; then
            arg="$(echo "$TERMINAL_AT_START" | awk '{print $1}')"
            which "$arg" 2>/dev/null && {
                $TERMINAL_AT_START &
            } || {
                echo "Warning: terminal '$arg' (setting TERMINAL_AT_START) in file /etc/eos-script-lib-yad.conf is not supported." >&2
            }
        fi
    else
        [ "$has_a_connection" = "yes" ] && eos-kbd-set

        if [ -x /usr/bin/numlockx ] ; then
            # some laptops have number pad inside the normal keyboard, so set NumLock off
            numlockx on  # show we are adjusting numlock...
            sleep 1
            numlockx off
        fi
        if [ ! -r /tmp/mirrorlist.bu ] ; then
            if [ -r /etc/pacman.d/mirrorlist ] ; then
                cp /etc/pacman.d/mirrorlist /tmp/mirrorlist.bu  # to be checked by update-mirrorlist
            else
                Welog "Warning: cannot make a backup of mirrorlist!"
            fi
        fi
        if [ ! -r /tmp/endeavouros-mirrorlist.bu ] ; then
            if [ -r /etc/pacman.d/endeavouros-mirrorlist ] ; then
                cp /etc/pacman.d/endeavouros-mirrorlist /tmp/endeavouros-mirrorlist.bu  # to be checked by update-mirrorlist
            else
                Welog "Warning: cannot make a backup of endeavouros-mirrorlist!"
            fi
        fi
    fi

    local handle="$(shuf -i 700000-999999 -n 1)"
    local tab tabname
    local notebook   # contains the main yad command

    PrepareTabs "$handle" || DIE "PrepareTabs failed"

    # Create the yad command gradually into an array 'notebook':

    notebook=(eos_yad --notebook --key="$handle" --center --title="$_NOTEBOOK_TITLE")
    notebook+=(--use-interp)
    notebook+=(--expand)

    DebugBreak

    if [ "$is_installing" = "no" ] ; then
        # Try to give a critical notification.
        #
        # File 'do_notify' can contain one or more date defs, one per line. Ignored lines:
        #   - comment lines (first non-white char is #)
        #   - empty lines (contain only white spaces)
        #
        local news_date_url="$(Github2Gitlab https://raw.githubusercontent.com/endeavouros-team/Important-news/main/do_notify)"
        local news_date=""
        news_date="$(curl --fail -Lsm 10 -o- $news_date_url | grep -Pv "^[ \t]*#|^[ \t]*$")"
        if [ "$news_date" ] ; then
            notebook+=(--text="$(ltr nb_notify_user1)\n$news_date\n$(ltr nb_notify_user2) <b>$(ltr butt_softnews)</b> $(ltr nb_notify_user3)\n")
        fi
    fi

    for tab in "${_NOTEBOOK_TABS[@]}" ; do
        tabname="$(ltr nb_tab_$tab)"
        #tabname="$(SeparateWordsWithSpaces "$tabname")"
        notebook+=(--tab="$tabname")
    done

    # Set the active tab number.
    local active_tab_nr=2                             # 2 = the After Install tab
    if [ "$is_installing" = "yes" ] ; then
        active_tab_nr=1
    elif [ -n "$EOS_WELCOME_ACTIVE_TAB_NUMBER" ] ; then
        active_tab_nr=$EOS_WELCOME_ACTIVE_TAB_NUMBER
    else
        if [ -n "$welcome_own_commands" ] ; then
            # 'activate_own_commands_tab' may have been set
            # in the "$own_commands_conf" file
            case "$activate_own_commands_tab" in
                [Yy][Ee][Ss])
                    active_tab_nr=6                       # 6 = the Personal Commands tab
                    ;;
            esac
        fi
    fi
    notebook+=(--active-tab=$active_tab_nr)

    [ "$is_installing" = "yes" ] && LanguageSelectionButton

    notebook+=(--button=" $(ltr butt_softnews)!$ICO_NEWS!$(ltr butt_softnews_tip)":"ImportantNews")
    notebook+=(--button=" $(ltr butt_changelog)!$ICO_CHANGES!$(ltr butt_changelogtip)":"WelcomeChangelog")
    case "$EOS_WELCOME_HAS_SEE_YOU_LATER_BUTTON" in
        yes)
            notebook+=(--button=" $(ltr butt_help)!$ICO_HELP!":"WelcomeHelp")
            if [ "$is_installing" = "no" ] ; then
                notebook+=(--button=" $(ltr butt_noshow)!$ICO_SAD!$(ltr butt_noshow)":5)
            fi
            notebook+=(--button=" $(ltr butt_later)!$ICO_ANGEL!$(ltr butt_latertip)":0)
            ;;
        no|*)
            [ "$is_installing" = "no" ] && notebook+=(--button=" $(ltr butt_noshow)!$ICO_SAD!$(ltr butt_noshow)":5)
            notebook+=(--button=" $(ltr butt_help)!$ICO_HELP!":"WelcomeHelp")
            ;;
    esac

    local error_log=/tmp/$PROGNAME.log
    local comment=""

    "${notebook[@]}" 2>/dev/null

    local result=$?

    case "$result" in
        5) WelcomeSettings disable ;;
        0) sleep 0.5 ; WelcomeSettings enable ;;
        252) ;;
        *)
            case "$result" in
                143) comment="   # likely caused by restarting the Welcome app" ;;
            esac
            echo "$(/usr/bin/date "+%x %X"): welcome exit code was: $result$comment" >> $error_log
            ;;
    esac
}

trap "sleep 0.2 ; eos-kill-yad-zombies --silent" EXIT

StartHere "$@"

exit 0
