#!/usr/bin/env bash
#
#   Script name: ubinstall
#   Description: Script for configure UBLinux (ublinux.ini)
#   GitLab: https://gitlab.ublinux.ru/
#   Author: Dmitry Razumov asmeron@ublinux.ru
#   Contributors: support@ublinux.ru
#
#   Copyright (c) 2021-2024 UBLinux <support@ublinux.ru>
#   License GPLv2+: GNU GPL version 2 or later <http://ublinux.ru>"
#
#   This program 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 2 of the License, or
#   (at your option) any later version.
#
#   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.

VERSION_SCRIPT=2.63

# Exit Immediately if a command fails
#set -o errexit

# Extended pattern matching: https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching
shopt -s extglob

#################################
###   :::   C O L O R S   :::   #
#################################
set_color(){
#http://abload.de/img/bash-color-chartmxjbp.png
    export BBC=$'\e[1;34m'
    export RBC=$'\e[1;31m'
    export WBC=$'\e[1m'
    export EC=$'\e[0m'

    export txtblk='\033[0;30m' # Black - Regular
    export txtred='\033[0;31m' # Red			# prompt: error color
    export txtgrn='\033[0;32m' # Green			# prompt: success color
    export txtylw='\033[0;33m' # Yellow			# prompt: waring color
    export txtblu='\033[0;34m' # Blue			
    export txtpur='\033[0;35m' # Purple
    export txtcyn='\033[0;36m' # Cyan			# prompt: info color
    export txtwht='\033[0;37m' # White
    export bldblk='\033[1;30m' # Black - Bold
    export bldred='\033[1;31m' # Red			# prompt: bold error color
    export bldgrn='\033[1;32m' # Green			# prompt: bold success color
    export bldylw="\033[1;33m" # Yellow                 # prompt: bold warning color
    export bldblu='\033[1;34m' # Blue				
    export bldpur='\033[1;35m' # Purple
    export bldcyn="\033[1;36m" # Cyan                   # prompt: bold info color
    export bldwht="\033[1;37m" # White			# prompt: bold default color

    export undblk='\033[4;30m' # Black - Underline
    export undred='\033[4;31m' # Red

    export bakblk='\033[40m'   # Black - Background
    export bakred='\033[41m'   # Red
    export badgrn='\033[42m'   # Green

    export txtrst='\033[0m'    # Text Reset		# prompt: default color
}

#######################################
###   :::   F U N C T I O N S   :::   #
#######################################

check_root(){
    [[ ${DEBUG} == @(yes|y|1) ]] && return 0
    if [[ ${EUID:-$(id -u)} > 0 ]]; then
	case ${1} in
	    -w  | --warning)	  shift; prompt -w "Please run as root! ${@}" && return 1 ;;
	    -wq | --warning-quit) shift; prompt -wq "Please run as root!" ;;
    	    *) 			  prompt -wq "Please run as root!" ;;
        esac
    fi
}

# Check command availability
has_command(){ command -v $1 &> /dev/null; }

i18n() {
    local key="$1"; shift
    printf "$(gettext -s "${key}")" "$@"
}

ere_quote_grep() {
    # Что экранировать
    sed 's/[][\.|$(){}?+*^]/\\&/g' <<< "$*"
    # Что не экранировать
    #sed 's/[^a-zA-Z0-9=",;/_@#%&<> -]/\\&/g' <<< "$*"
}

ere_quote_sed() {
    # Что экранировать
    sed 's/[][\.|$(){}?+*^;/]/\\&/g' <<< "$*"
    # Что не экранировать
    #sed 's/[^a-zA-Z0-9=",_@#%&<> -]/\\&/g' <<< "$*"
}

# echo like ... with flag type and display message colors
prompt(){
    local PROGRESS=
	case ${1} in
	    -s  | --success)		# print success message
		shift; [[ $1 =~ ^[[:digit:]]+"%"$ ]] && PROGRESS="($1) " && shift && echo -e "${PROGRESS}$(i18n "${@}")" >&5
		echo -e "${txtgrn}${PROGRESS}$(i18n "${@}")${txtrst}"
	    ;;
	    -sq | --success-quit)	# print success message
		shift; [[ $1 =~ ^[[:digit:]]+"%"$ ]] && PROGRESS="($1) " && shift && echo -e "${PROGRESS}$(i18n "${@}")" >&5
		echo -e "${txtgrn}${PROGRESS}$(i18n "${@}")${txtrst}"; echo -e "${txtgrn}[S:0]${txtrst}"; exit 1
	    ;;
	    -e  | --error)   	 	# print error message
		shift; [[ $1 =~ ^[[:digit:]]+"%"$ ]] && PROGRESS="($1) " && shift && echo -e "${PROGRESS}$(i18n "${@}")" >&5
		echo -e "${txtred}${PROGRESS}$(i18n "ERROR:")$(i18n "${@}")${txtrst}"
	    ;;
	    -eq | --error-quit)		# print error message
		shift; [[ $1 =~ ^[[:digit:]]+"%"$ ]] && PROGRESS="($1) " && shift && echo -e "${PROGRESS}$(i18n "${@}")" >&5
		echo -e "${txtred}${PROGRESS}$(i18n "ERROR:")$(i18n "${@}")${txtrst}"; echo -e "${txtred}[E:1]${txtrst}"; exit 1
	    ;;
	    -w  | --warning) 	  	# print warning message
		shift; [[ $1 =~ ^[[:digit:]]+"%"$ ]] && PROGRESS="($1) " && shift && echo -e "${PROGRESS}$(i18n "${@}")" >&5
		echo -e "${txtylw}${PROGRESS}$(i18n "WARNING:")${bldwht}$(i18n "${@}")${txtrst}"
	    ;;
	    -wq | --warning-quit) 	# print warning message
		shift; [[ $1 =~ ^[[:digit:]]+"%"$ ]] && PROGRESS="($1) " && shift && echo -e "${PROGRESS}$(i18n "${@}")" >&5
		echo -e "${txtylw}${PROGRESS}$(i18n "WARNING:")${bldwht}$(i18n "${@}")${txtrst}"; echo -e "${txtylw}[W:1]${txtrst}"; exit 1
	    ;;
	    -i  | --info)    	  	# print info message
		shift; [[ $1 =~ ^[[:digit:]]+"%"$ ]] && PROGRESS="($1) " && shift && echo -e "${PROGRESS}$(i18n "${@}")" >&5
		echo -e "${txtcyn}${PROGRESS}$(i18n "INFO:")${txtcyn}$(i18n "${@}")${txtrst}"
	    ;;
	    -iq | --info-quit)    	# print info message
		shift; [[ $1 =~ ^[[:digit:]]+"%"$ ]] && PROGRESS="($1) " && shift && echo -e "${PROGRESS}$(i18n "${@}")" >&5
		echo -e "${txtcyn}${PROGRESS}$(i18n "INFO:")${txtcyn}$(i18n "${@}")${txtrst}"; echo -e "${txtcyn}[I:0]${txtrst}"; exit 1
	    ;;
	    -q | --quit)    		# print all message
		shift; [[ $1 =~ ^[[:digit:]]+"%"$ ]] && PROGRESS="($1) " && shift && echo -e "${PROGRESS}$(i18n "${@}")" >&5
		echo -e "${PROGRESS}$(i18n "${@}")"; echo -e "[E:1]"; exit 1
	    ;;
	    *)    		  	# print all message
		[[ $1 =~ ^[[:digit:]]+"%"$ ]] && PROGRESS="($1) " && shift && echo -e "${PROGRESS}$(i18n "${@}")" >&5
		echo -e "${PROGRESS}$(i18n "${@}")"
	    ;;
	esac
}

usage_version(){
    printf "%s  %s\n" "${0##*/}" "version: ${VERSION_SCRIPT}"
}

usage(){
    cat <<EOF
UBLinux installer
Author: Dmitry Razumov asmeron@ublinux.ru

Usage:  ${0##*/} [OPTIONS...]

Command:
  autoinstall		Автоустановка системы по заданным параметрам из конфигурации
  autoconfig		Провести только настройку установленной системы на заданные параметры
  install_modules_extra	Установить только дополнительные модули параметра --modules_extra

Meta Commands:
  help          Show this help

Options:
      --installer_lang=*russian|english
    			Язык установщика
  -s, --source=auto|<device_n>,<path_n>,<file_iso_n>,...
			Источник установки
       *auto       	Источником выступает текущая загруженная система
        <device>   	Раздел с образом системы, может быть cdrom или флешка, пример: /dev/sdb3
        <path>     	Каталог к образу системы, пример: /home/superadmin/distrib
        <file_iso> 	Путь до файла ISO с образом системы
  -c, --config=<FILE>	Использовать пользовательский файл конфигурации
	<FILE>		Файл конфигурации формата ublinux.ini
  -t, --install_type=<TYPE>
			Тип установки
	fast		Быстрая типовая установка на выбранное устройство
	                Обязательные дополнительные параметры: AUTOINSTALL[device]
        next		Установка рядом с другой системой на выбранное устройство в отдельный раздел
    			Обязательные дополнительные параметры: AUTOINSTALL[device] AUTOINSTALL[part]
        part		Установка рядом с другой системой на выбранное устройство в раздел другой системы
                	Обязательные дополнительные параметры: AUTOINSTALL[device] AUTOINSTALL[part]
        grub_install	Переустановить GRUB, на выбранный на выбранное устройство и раздел
                    	Обязательные дополнительные параметры: AUTOINSTALL[device] AUTOINSTALL[part]
        grub_update	Обновить GRUB, на выбранное устройство и раздел
                        Обязательные дополнительные параметры: AUTOINSTALL[device] AUTOINSTALL[part]
        system_only	Установить/перезаписать только базовые модули с источника (source)/ublinux/base на
    			выбранное устройство и раздел
	                Обязательные дополнительные параметры: AUTOINSTALL[device] AUTOINSTALL[part]
        data_only	Установить/перезаписать только дополнительные модули с источника (source)/ublinux/modules на
    			выбранное устройство и раздел, с полной очисткой (part)/ublinux-data
                    	Обязательные дополнительные параметры: AUTOINSTALL[device] AUTOINSTALL[part]
        custom		Выборачная установка с возможностью использовать все параметры
                    	Обязательные дополнительные параметры: AUTOINSTALL[device]
  --device=<DEVICE>	Устройство на которое будет установлена система. Если установлена опция AUTOINSTALL[device_typevfs], то
			возможно пречислять через запятую (,) несколько устройств
        <DEVICE>	Путь устройства, пример: /dev/sda
  --device_typevfs=*none|raid0|raid1|raid4|raid5|raid6|raid10|lvm|lvm_dynamic
    			Тип  виртуального устройств из выбранных физических, используется для рейда MDADM или LVM и другие
  --part=sda2		Раздел на который будет установлена система (part)/ublinux (part)/ublinux-data
			Если указан второй раздел через запятую (,) то установка разделяется на (part1)/ublinux (part2)/ublinux-data
  --part_size=256G 	Размер раздела для установки. Если указано два раздела в AUTOINSTALL[parts], то
			возможно указать два размера через запятую (,) для первого и второго раздела
  --part_label=*ublinux Метка раздела. Если указано два раздела в AUTOINSTALL[parts], то
			возможно указать два типа опций через запятую (,) для первого и второго раздела
  --part_fs_type=*ext4|ext3|ext2|exfat|fat|fat12|fat16|fat32|msdos|vfat|bfs|btrfs|f2fs|riserfs|jfs|minix|nilfs2|ntfs|udf|xfs|-zfs
			Тип файловой системы для раздела. Если указано два раздела в AUTOINSTALL[parts], то
			возможно указать два типа опций через запятую (,) для первого и второго раздела
  --part_fs_label=*ublinux
			Метка файловой системы
  --part_format=*no|yes	Форматировать устройство
  --part_crypt=luks1|luks2:password
			Зашифрованный раздел dm-crypt + LUKS. Если указано два раздела в AUTOINSTALL[parts], то
			возможно указать два типа опций через запятую (,) для первого и второго раздела
  --swap=*auto|yes|no	Создать раздел для SWAP
        *auto       	Не создавать отдельный раздел для SWAP, если существует, то использовать существующий
    			Включить SWAP в динамический сжатый файл
	 yes        	Создать раздел для SWAP, если существует, то использовать существующий
	 no         	Без SWAP
  --swap_size=*ram|<number>MG
       *ram        	Размер SWAP по размеру ОЗУ
        <number>MG 	Размер SWAP в M(мегабайт) G(гигабайт)
  --locale=*en_US.UTF-8,*ru_RU.UTF-8,...
			Поддерживаемые локали системой, перечисляются через запятую
  --lang=*ru_RU.UTF-8	Основная локаль системы
  --zone=*Europe/Moscow	Часовой пояс * =UTC
  --user_name=*superadmin
  --user_gecos=*Администратор
  --user_password=*ublinux
  --root_password=*ublinux
  --autologin=*no|yes|<username>
  --xkbmodel=*pc105
  --xkblayout=*"us,ru"
  --xkbvariant=*ru
  --xkboptions=*"grp:lalt_lshift_toggle,grp_led:scroll,compose:rwin"
  --hostname=<hostname>|auto
	<hostname>  	Имя хоста
       *auto        	Динамически сгенерированное имя с суфиксом "ublinux-<nnnn>", где "nnnn" четыре цифры
  --ubconfig="<section_value_1>;<section_value_n>"
	<section_value_n>   Наименование секции и переменной, разделитель точка с запятой(;)
			    Пример: "[boot] GRUB_TIMEOUT=3;[boot] GRUB_SUPERUSERS=superadmin"
  --modules=*auto|<list_modules>
			Модули для установки из источника
	auto            Все модули источника установки из каталога (source)/ublinux/base (source)/ublinux/modules
	<list_modules>  Выбранные модули источника установки из каталога (source)/ublinux/ (source)/ublinux/modules
  --modules_extra=<list_modules>
			Модули для установки из архива модулей дистрибутива через интернет
        <list_modules>  Выбранные модули из архива модулей дистрибутива
  --log=*yes|no|save	Использовать лог установки
       *yes		Использовать лог файл установки (/var/log/ubinstall.log)
	no         	Не использовать лог файл установки
	save       	Использовать лог файл установки и сохранить в установленную систему по адресу (source)/ublinux-data/ubinstall.log
  --debug		Выводить подробный результат выполнения
  --test		Тестировать выбранные параметры и лог, без фактической установки
  --nocolor	   	Disable color
  -q, --quiet	   	Quiet mode
  -h, --help	   	Show this help
  -V, --version	   	Show package version

Examples:
${0##*/} --device /dev/sda --install_type fast
EOF
}

help(){
    usage_version
    [[ -n $1 ]] || usage
    exit 0
}

arguments(){
# Pre-process options to:
# - expand -xyz into -x -y -z
# - expand --longopt=arg into --longopt arg
    local ARGV=()
    local END_OF_OPT=
    while [[ $# -gt 0 ]]; do
	arg="$1"; shift
	case "${END_OF_OPT}${arg}" in
	    get|GET|set|SET|remove|REMOVE|update|UPDATE) ARGV+=("${arg}"); END_OF_OPT=1 ;;
	    --)		ARGV+=("${arg}"); END_OF_OPT=1 ;;
	    --*=*)	ARGV+=("${arg%%=*}" "${arg#*=}") ;;
	    --*)	ARGV+=("${arg}") ;;
	    -*) 	for i in $(seq 2 ${#arg}); do ARGV+=("-${arg:i-1:1}"); done ;;
	    *)		ARGV+=("${arg}") ;;
	esac
    done
    # Apply pre-processed options
    set -- "${ARGV[@]}"
    # Parse options
    local END_OF_OPT=
    local POSITIONAL_ARGS=()
    [[ -z $@ ]] && usage && exit 0
    while [[ $# -gt 0 ]]; do
	case "${END_OF_OPT}${1}" in
	    autoconfig)  	ARG_AUTOCONFIG=yes ;;
	    autoinstall)	ARG_AUTOINSTALL=yes ;;
	    install_modules_extra) ARG_INSTALL_MODULES_EXTRA=yes ;;
	    -c | --config)	shift; ARG_CONFIG="$1" ;;
            --installer_lang)	shift; ARG_INSTALLER_LANG="$1" ;;
	    -s | --source)	shift; ARG_SOURCE="$1" ;;
	    -t | --install_type) shift; ARG_INSTALL_TYPE="$1" ;;
            -d | --device)	shift; ARG_DEVICE="$1" ;;
            --device_typevfs)	shift; ARG_DEVICE_TYPEVFS="$1" ;;
            -p | --part)	shift; ARG_PART="$1" ;;
            --part_size)	shift; ARG_PART_SIZE="$1" ;;
            --part_label)	shift; ARG_PART_LABEL="$1" ;;
            --part_fs_type)	shift; ARG_PART_FS_TYPE="$1" ;;
            --part_fs_label)	shift; ARG_PART_FS_LABEL="$1" ;;
            --part_format)	shift; ARG_PART_FORMAT="$1" ;;
            --part_crypt)	shift; ARG_PART_CRYPT="$1" ;;
            --swap)		shift; ARG_SWAP="$1" ;;
            --swap_size)	shift; ARG_SWAP_SIZE="$1" ;;
            --locale)		shift; ARG_LOCALE="$1" ;;
            --lang)		shift; ARG_LANG="$1" ;;
            --zone)		shift; ARG_ZONE="$1" ;;
            --user_name)	shift; ARG_USER_NAME="$1" ;;
            --user_gecos)	shift; ARG_USER_GECOS="$1" ;;
            --user_password)	shift; ARG_USER_PASSWORD="$1" ;;
            --root_password)	shift; ARG_ROOT_PASSWORD="$1" ;;
            --autologin)	shift; ARG_AUTOLOGIN="$1" ;;
            --xkbmodel)		shift; ARG_XKBMODEL="$1" ;;
            --xkblayout)	shift; ARG_XKBLAYOUT="$1" ;;
            --xkbvariant)	shift; ARG_XKBVARIANT="$1" ;;
            --xkboptions)	shift; ARG_XKBOPTIONS="$1" ;;
            --hostname)		shift; ARG_HOSTNAME="$1" ;;
            --ubconfig)		shift; ARG_UBCONFIG="$1" ;;
            --modules)		shift; ARG_MODULES="$1" ;;
            --modules_extra)	shift; ARG_MODULES_EXTRA="$1" ;;
            --log)		shift; ARG_LOG="$1" ;;
            --debug)		ARG_DEBUG=yes ;;
            --test)		ARG_TEST=yes ;;
	    -h | --help | help)	   shift; help $1;;
	    -q | --quiet)     	   QUIET="--quiet"; QUIET_SYSTEMCTL="--quiet"; QUIET_ARG="-q" ;;
	         --nocolor)    	   NOCOLOR="--nocolor" ;;
	         --debug)	   DEBUG=1 ;;
	    -V | --version)	   usage_version; exit 0 ;;
	    --stdin)        	   READ_STDIN=1 ;;
	    --)             	   END_OF_OPT=1 ;;
	    -*|--*)         	   prompt -w "Unrecognized argument, skiped: $1" >&2  ;;
	    *)              	   POSITIONAL_ARGS+=("$1") ;;
	esac
	shift
    done
    # Restore positional parameters
    set -- "${POSITIONAL_ARGS[@]}"
    REQUEST_ARGS=("${POSITIONAL_ARGS[@]}")

    RANDOM_NUMBER=$(shuf -i 1-10000 -n 1)
    DEFAULT_SOURCE="auto"
    DEFAULT_DEVICE_TYPEVFS="none"
    DEFAULT_PART_SIZE="16G"
    DEFAULT_PART_LABEL="ublinux-${RANDOM_NUMBER}"
    DEFAULT_PART_LABEL_DATA="ublinux-data-${RANDOM_NUMBER}"
    DEFAULT_PART_FS_TYPE="ext4"
    DEFAULT_PART_FS_LABEL="ublinux-${RANDOM_NUMBER}"
    DEFAULT_PART_FS_LABEL_DATA="ublinux-data-${RANDOM_NUMBER}"
    #DEFAULT_PART_FORMAT=
    #DEFAULT_PART_CRYPT=
    #DEFAULT_SWAP="auto"
    #DEFAULT_SWAP_SIZE="ram"
    #DEFAULT_LOCALE="en_US.UTF-8,ru_RU.UTF-8"
    #DEFAULT_LANG="ru_RU.UTF-8"
    #DEFAULT_ZONE="Europe/Moscow"
    DEFAULT_USER_NAME="superadmin"
    DEFAULT_USER_GECOS="Administrator"
    DEFAULT_USER_PASSWORD="ublinux"
    DEFAULT_ROOT_PASSWORD="ublinux"
    #DEFAULT_AUTOLOGIN=
    #DEFAULT_XKBMODEL="pc105"
    #DEFAULT_XKBLAYOUT="us,ru"
    #DEFAULT_XKBVARIANT="ru"
    #DEFAULT_XKBOPTIONS="grp:lalt_lshift_toggle,grp_led:scroll,compose:rwin"
    DEFAULT_HOSTNAME="ublinux-$(shuf -i 1-100000 -n 1)"
    #DEFAULT_MODULES="auto"
    #DEFAULT_MODULES_EXTRA=
    #DEFAULT_ARG_DEBUG=
    #DEFAULT_ARG_TEST=
    DEFAULT_LOG=yes
    default_arguments
}

default_arguments(){
    if [[ -n ${ARG_CONFIG} ]]; then
	eval $(grep -i "^AUTOINSTALL" ${ARG_CONFIG})
    else
	# Если подгружать как источник ${SYSCONF}/autoinstall то переменная AUTOINSTALL очистится от значений по умолчанию
	[[ -n ${ARG_AUTOINSTALL} || -n ${ARG_AUTOCONFIG} ]] && [[ -f ${SYSCONF}/autoinstall ]] && eval $(grep -i "^AUTOINSTALL" ${SYSCONF}/autoinstall)
    fi
    : ${ARG_INSTALLER_LANG:=${AUTOINSTALL[installer_lang]}}
    : ${ARG_SOURCE:=${AUTOINSTALL[source]:-${DEFAULT_SOURCE}}}
    : ${ARG_INSTALL_TYPE:=${AUTOINSTALL[install_type]}} #-
    : ${ARG_DEVICE:=${AUTOINSTALL[device]}} #-
    : ${ARG_DEVICE_TYPEVFS:=${AUTOINSTALL[device_typevfs]:-${DEFAULT_DEVICE_TYPEVFS}}}
    : ${ARG_PART:=${AUTOINSTALL[part]}} #-
    : ${ARG_PART_SIZE:=${AUTOINSTALL[part_size]:-${DEFAULT_PART_SIZE}}}
    : ${ARG_PART_LABEL:=${AUTOINSTALL[part_label]:-${DEFAULT_PART_LABEL}}}
    : ${ARG_PART_FS_TYPE:=${AUTOINSTALL[part_fs_type]:-${DEFAULT_PART_FS_TYPE}}}
    : ${ARG_PART_FS_LABEL:=${AUTOINSTALL[part_fs_label]:-${DEFAULT_PART_FS_LABEL}}}
    : ${ARG_PART_FORMAT:=${AUTOINSTALL[part_format]:-${DEFAULT_PART_FORMAT}}}
    : ${ARG_PART_CRYPT:=${AUTOINSTALL[part_crypt]}} #-
    : ${ARG_SWAP:=${AUTOINSTALL[swap]:-${DEFAULT_SWAP}}}
    : ${ARG_SWAP_SIZE:=${AUTOINSTALL[swap_size]:-${DEFAULT_SWAP_SIZE}}}
    [[ ${ARG_SWAP,,} != "yes" ]] && ARG_SWAP_SIZE=0
    [[ ${ARG_SWAP_SIZE,,} == "ram" ]] && ARG_SWAP_SIZE="$(grep MemTotal /proc/meminfo | awk '{printf("%.0f \n",$2*1024)}')" # байт'
    ARG_SWAP_SIZE=$(numfmt --from=iec ${ARG_SWAP_SIZE:-0})  # Новый размер в байтах
    : ${ARG_LOCALE:=${AUTOINSTALL[locale]:-${DEFAULT_LOCALE}}}
    : ${ARG_LANG:=${AUTOINSTALL[lang]:-${DEFAULT_LANG}}}
    : ${ARG_ZONE:=${AUTOINSTALL[zone]:-${DEFAULT_ZONE}}}

    : ${ARG_USER_NAME:=${AUTOINSTALL[user_name]:-${DEFAULT_USER_NAME}}}
    : ${ARG_USER_GECOS:=${AUTOINSTALL[user_gecos]:-${DEFAULT_USER_GECOS}}}
# TODO: Подключить переводчик i18n
    [[ ${ARG_USER_GECOS,,} == "administrator" && ${LANG,,} =~ "ru_ru" ]] && ARG_USER_GECOS="Администратор"
    : ${ARG_USER_PASSWORD:=${AUTOINSTALL[user_password]}} #-
    [[ ${ARG_USER_PASSWORD} == @("${DEFAULT_USER_PASSWORD}"|"${DEFAULTPASSWD}") ]] && unset ARG_USER_PASSWORD
    : ${ARG_ROOT_PASSWORD:=${AUTOINSTALL[root_password]}} #-
    [[ ${ARG_ROOT_PASSWORD} == @("${DEFAULT_ROOT_PASSWORD}"|"${DEFAULTROOTPASSWD}") ]] && unset ARG_ROOT_PASSWORD
    : ${ARG_AUTOLOGIN:=${AUTOINSTALL[autologin]:-${DEFAULT_AUTOLOGIN}}}
    : ${ARG_XKBMODEL:=${AUTOINSTALL[xkbmodel]:-${DEFAULT_XKBMODEL}}}
    : ${ARG_XKBLAYOUT:=${AUTOINSTALL[xkblayout]:-${DEFAULT_XKBLAYOUT}}}
    : ${ARG_XKBVARIANT:=${AUTOINSTALL[xkbvariant]:-${DEFAULT_XKBVARIANT}}}
    : ${ARG_XKBOPTIONS:=${AUTOINSTALL[xkboptions]:-${DEFAULT_XKBOPTIONS}}}
    : ${ARG_HOSTNAME:=${AUTOINSTALL[hostname]}}
    [[ ${ARG_HOSTNAME,,} == "auto" || ${AUTOINSTALL[hostname],,} == "auto" ]] && ARG_HOSTNAME="${DEFAULT_HOSTNAME}"

    : ${ARG_MODULES:=${AUTOINSTALL[modules]:-${DEFAULT_MODULES}}}
    : ${ARG_MODULES_EXTRA:=${AUTOINSTALL[modules_extra]:-${DEFAULT_MODULES_EXTRA}}}
    : ${ARG_LOG:=${AUTOINSTALL[log]:-${DEFAULT_LOG}}}

    [[ -n ${ARG_INSTALL_TYPE} ]] || prompt -eq "Missing required parameter %s" "--install_type"
    [[ ${ARG_INSTALL_TYPE} == @(fast|next|part|grub_install|grub_update|system_only|data_only|custom) ]] || prompt -eq "Не верный тип установки %s" "--install_type ${ARG_INSTALL_TYPE}"
    [[ ${ARG_INSTALL_TYPE} == fast && -z ${ARG_DEVICE} ]] && prompt -eq "Пропущен обязательный параметр %s" "--device"
    [[ ${ARG_INSTALL_TYPE} == @(next|part|grub_install|grub_update|system_only|data_only) && -z ${ARG_PART} ]] && prompt -eq "Пропущен обязательный параметр %s" "--part\n[E:1]"

    # Если короткие имена, то находим полный путь до устройства
    if [[ -n ${ARG_DEVICE} ]]; then
	local DEVICE_FILTER=
	while IFS= read LINE_DEVICE; do
	    DEVICE_FILTER+="$(lsblk -o path | grep "${LINE_DEVICE}$"),"
	done <<< ${ARG_DEVICE//@(,|;|\|)/$'\n'}
	ARG_DEVICE=${DEVICE_FILTER%,*}
    fi
    # Если короткие имена, то находим полный путь до устройства
    if [[ -n ${ARG_PART} ]]; then
	local PART_FILTER=
	while IFS= read LINE_PART; do
	    PART_FILTER+="$(lsblk -o path | grep "${LINE_PART}$"),"
	done <<< ${ARG_PART//@(,|;|\|)/$'\n'}
	ARG_PART=${PART_FILTER%,*}
    fi
    # Если указан разделы и не указаны устройства, то получить устройства от разделов
    if [[ -z ${ARG_DEVICE} && -n ${ARG_PART} ]]; then
	local DEVICE_FILTER= SELECT_DEVICE_FILTER=
	while IFS= read LINE_PART; do
	    SELECT_DEVICE_FILTER=$(lsblk --list --noheadings --paths --output PKNAME ${LINE_PART} | head -1)
	    [[ ${SELECT_DEVICE_FILTER} == "" || ${DEVICE_FILTER} =~ ${SELECT_DEVICE_FILTER} ]] || DEVICE_FILTER+="${SELECT_DEVICE_FILTER},"
	done <<< ${ARG_PART//@(,|;|\|)/$'\n'}
	ARG_DEVICE=${DEVICE_FILTER%,*}
    fi

    # Применить параметры из командной строки
    [[ -n ${ARG_UBCONFIG} ]] && while IFS= read LINE_ARG_UBCONFIG; do
	LINE_ARG_UBCONFIG_NAME=${LINE_ARG_UBCONFIG%%=*}
	LINE_ARG_UBCONFIG_VALUE=${LINE_ARG_UBCONFIG#*=}
	#echo "ubconfig --target system set [autoinstall] AUTOINSTALL[\"ubconfig set ${LINE_ARG_UBCONFIG_NAME}\"]=${LINE_ARG_UBCONFIG_VALUE}"
	AUTOINSTALL["ubconfig set ${LINE_ARG_UBCONFIG_NAME}"]="${LINE_ARG_UBCONFIG_VALUE}"
    done <<< ${ARG_UBCONFIG//@(;|\|)/$'\n'}
}

show_conf_install(){
    prompt "Настройки установки:"
    prompt "$(sed '/^[[:space:]]*$/d' <<< "    ${ARG_TEST:+TEST=${ARG_TEST}}
    ${ARG_DEBUG:+DEBUG=${ARG_DEBUG}}
    ${ARG_LOG:+LOG=${ARG_LOG}}
    ${ARG_INSTALLER_LANG:+AUTOINSTALL[installer_lang]=${ARG_INSTALLER_LANG}}
    ${ARG_SOURCE:+AUTOINSTALL[source]=${ARG_SOURCE}}
    ${ARG_INSTALL_TYPE:+AUTOINSTALL[install_type]=${ARG_INSTALL_TYPE}}
    ${ARG_DEVICE:+AUTOINSTALL[device]=${ARG_DEVICE}}
    ${ARG_DEVICE_TYPEVFS:+AUTOINSTALL[device_typevfs]=${ARG_DEVICE_TYPEVFS}}
    ${ARG_PART:+AUTOINSTALL[part]=${ARG_PART}}
    ${ARG_PART_SIZE:+AUTOINSTALL[part_size]=${ARG_PART_SIZE}}
    ${ARG_PART_LABEL:+AUTOINSTALL[part_label]=${ARG_PART_LABEL}}
    ${ARG_PART_FS_TYPE:+AUTOINSTALL[part_fs_type]=${ARG_PART_FS_TYPE}}
    ${ARG_PART_FS_LABEL:+AUTOINSTALL[part_fs_label]=${ARG_PART_FS_LABEL}}
    ${ARG_PART_FORMAT:+AUTOINSTALL[part_format]=${ARG_PART_FORMAT}}
    ${ARG_PART_CRYPT:+AUTOINSTALL[part_crypt]=${ARG_PART_CRYPT}}
    ${ARG_SWAP:+AUTOINSTALL[swap]=${ARG_SWAP}}
    ${ARG_SWAP_SIZE:+AUTOINSTALL[swap_size]=${ARG_SWAP_SIZE}}
    ${ARG_MODULES:+AUTOINSTALL[modules]=${ARG_MODULES}}
    ")"
}
show_conf_settings(){
    prompt "Настройки системы после установки:"
    prompt "$(sed '/^[[:space:]]*$/d' <<< "	${ARG_LOCALE:+AUTOINSTALL[locale]=${ARG_LOCALE}}
    ${ARG_LANG:+AUTOINSTALL[lang]=${ARG_LANG}}
    ${ARG_ZONE:+AUTOINSTALL[zone]=${ARG_ZONE}}
    ${ARG_USER_NAME:+AUTOINSTALL[user_name]=${ARG_USER_NAME}}
    ${ARG_USER_GECOS:+AUTOINSTALL[user_gecos]=${ARG_USER_GECOS}}
    ${ARG_USER_PASSWORD:+AUTOINSTALL[user_password]=${ARG_USER_PASSWORD}}
    ${ARG_ROOT_PASSWORD:+AUTOINSTALL[root_password]=${ARG_ROOT_PASSWORD}}
    ${ARG_AUTOLOGIN:+AUTOINSTALL[autologin]=${ARG_AUTOLOGIN}}
    ${ARG_XKBMODEL:+AUTOINSTALL[xkbmodel]=${ARG_XKBMODEL}}
    ${ARG_XKBLAYOUT:+AUTOINSTALL[xkblayout]=${ARG_XKBLAYOUT}}
    ${ARG_XKBVARIANT:+AUTOINSTALL[xkbvariant]=${ARG_XKBVARIANT}}
    ${ARG_XKBOPTIONS:+AUTOINSTALL[xkboptions]=${ARG_XKBOPTIONS}}
    ${ARG_HOSTNAME:+AUTOINSTALL[hostname]=${ARG_HOSTNAME}}
    ${ARG_MODULES_EXTRA:+AUTOINSTALL[modules_extra]=${ARG_MODULES_EXTRA}}
$(for ARG_ITEM in "${!AUTOINSTALL[@]}"; do [[ ${ARG_ITEM} =~ ^"ubconfig "(.*) ]] && echo "    AUTOINSTALL[\"${ARG_ITEM}\"]=\"${AUTOINSTALL[${ARG_ITEM}]}\""; done)
    ")"
}
show_extra_settings(){
    prompt "Настройки системы после установки:"
    prompt "$(sed '/^[[:space:]]*$/d' <<< "	${ARG_MODULES_EXTRA:+AUTOINSTALL[modules_extra]=${ARG_MODULES_EXTRA}}
    ")"
}

get_all_block_device(){
    lsblk -rbo maj:min,name,path,type,parttypename,fstype,label,size,fsavail,fsuse%,mountpoint,tran,vendor,model,ro | sed 's/:/\ /' | sort -nk1 -nk2 | sed 's/\ /|/'| awk '{if ($4 == "disk" || $4 == "part") print $0;}' | sed 's/\ /:/g;s/::/:-:/g;s/::/:-:/g;s/:$/:-/'

    # Только устройства
    #lsblk --noheadings --nodeps -o PATH,SIZE,MODEL,VENDOR,SERIAL --exclude 7,253
    # Устройства с разделами
    #lsblk --noheadings -o TYPE,PATH,SIZE,FSTYPE,LABEL,PARTLABEL,MOUNTPOINT,FSUSED,FSUSE% --exclude 7,253
}

drive_info(){
    local DEVICE=$1
    while IFS= read -r SELECT_DEVICE; do
	partprobe ${SELECT_DEVICE} 1>&3 2>&3 	# Информируем ядро об изменении разделов
	prompt "################################################################"
	prompt "Drive info: %s" "fdisk -l ${SELECT_DEVICE}"
	fdisk -l ${SELECT_DEVICE} 1>&3 2>&3
	prompt "################################################################"
	prompt "Drive info: %s" "gdisk -l ${SELECT_DEVICE}"
	gdisk -l ${SELECT_DEVICE} 1>&3 2>&3
	prompt "################################################################"
	prompt "Drive info: %s" "sgdisk -O ${SELECT_DEVICE}"
	sgdisk -O ${SELECT_DEVICE} 1>&3 2>&3
	prompt "################################################################"
	prompt "Device %s detected record:" "${SELECT_DEVICE}"
    done <<<${DEVICE//@(,|;|\|)/$'\n'}
}

# Если MBR и Win, то отключить у ntfs режим hibernation и удалить старый bootmgr
fix_ntfs_windows_os(){
    local DEVICE=$1
    [[ -z ${ARG_TEST} ]] && while IFS= read -r SELECT_DEVICE; do
	local FIND_BOOTMGR=
	local FIND_PART_NTFS_DOS=$(lsblk --noheadings --paths --output PATH,FSTYPE,PTTYPE ${SELECT_DEVICE} | grep "ntfs" | cut -d' ' -f1)
	[[ -n ${FIND_PART_NTFS_DOS} ]] && while IFS= read -r SELECT_PART; do
	    ntfsfix ${SELECT_PART}
	    ntfsfix -b ${SELECT_PART}
	    mount --mkdir -o remove_hiberfile ${SELECT_PART} /mnt${SELECT_PART}
	    if [[ -f /mnt/${SELECT_PART}/bootmgr && -z ${FIND_BOOTMGR} ]]; then
		FIND_BOOTMGR=yes
	    elif [[ -f /mnt/${SELECT_PART}/bootmgr ]]; then
		rm -f /mnt/${SELECT_PART}/bootmgr
		prompt -w "Remove /bootmgr on partition: %s" "${SELECT_PART}"
	    fi
	done <<<${FIND_PART_NTFS_DOS}
    done <<< ${DEVICE//@(,|;|\|)/$'\n'}
    sleep 0.5
}

drive_umount_allparts(){
    local DEVICE=$1
    sync; sync
    sleep 1
    swapoff -a 1>&3 2>&3
    [[ -z ${ARG_TEST} ]] && while IFS= read -r SELECT_DEVICE; do
#	has_command "fuser" && find /dev/ -iname "${DEVICE##*/}*" -exec fuser -cuk {} 1>&3 2>/dev/null \;
	find /dev/ -name "${DEVICE##*/}*" -exec umount -A --recursive {} \; 1>&3 2>/dev/null
##    	umount -Rl ${DEVICE}* 1>&3 2>&3
	FINDMNT=$(find /dev/ -iname "${DEVICE##*/}*" -exec findmnt --source {} \;)
	[[ -n ${FINDMNT} ]] && prompt -w "Failed to unmount device: %s" "${DEVICE}" && return 1
    done <<< ${DEVICE//@(,|;|\|)/$'\n'}
    # Для zfs, только пул нужно указать
    #zpool export -a ${POOLNAME}
    sync; sync
    sleep 1
}

install_fast_drive_partitioning(){
    local DEVICE=$1
    local PART_LABEL=$2
    [[ -b ${DEVICE} ]] || prompt -eq "Device '%s' is not block!" "${DEVICE}"
#### Destroy MBR or GPT or other
	prompt "02%" "Destroy MBR or GPT on drive: %s" "${DEVICE}"
    [[ -z ${ARG_TEST} ]] && { dd if=/dev/zero of=${DEVICE} bs=446 count=1 conv=notrunc 1>&3 2>&3; }	# replace X with the target drive letter.    
    [[ -z ${ARG_TEST} ]] && { wipefs -a -f ${DEVICE} 1>&3 2>&3 || return 1; }			# zap GPT and MBR - core/util-linux
    [[ -z ${ARG_TEST} ]] && { sgdisk -Z ${DEVICE} 1>&3 2>&3 || return 1; }			# zap GPT and MBR, create GPT - extra/gptfdisk
	prompt "03%" "Clear partition table on drive: %s" "${DEVICE}"
    [[ -z ${ARG_TEST} ]] && { sgdisk -o ${DEVICE} 1>&3 2>&3 || return 1; }			# clear partition table
    [[ -z ${ARG_TEST} ]] && { sgdisk -a=2048 ${DEVICE} 1>&3 2>&3 || return 1; }			# aligment
	prompt "04%" "Create partition 2M: '%s' on drive: %s" "bios_boot" "${DEVICE}"
    [[ -z ${ARG_TEST} ]] && { sgdisk -a=2048 -n 0:0:+2M -c 0:"bios_boot" -t 0:ef02 ${DEVICE} 1>&3 2>&3 || return 1; }	# create partition
	prompt "05%" "Create partition 320M: '%s' on drive: %s" "efi" "${DEVICE}"
    [[ -z ${ARG_TEST} ]] && { sgdisk -a=2048 -n 0:0:+320M -c 0:"efi" -t 0:ef00 ${DEVICE} 1>&3 2>&3 || return 1; }	# create partition
    DEVICE_FREE_SPACE=$(LC_ALL=C parted ${DEVICE} unit B print free | awk '/Free Space/{c++; sum += $3} END{if(c == 0) print "0"; else print sum}') #'
    [[ -z ${ARG_TEST} && ${ARG_SWAP,,} == "yes" ]] && { [[ ${ARG_SWAP_SIZE:-0} -le ${DEVICE_FREE_SPACE:-0} ]] || prompt -eq "No free space to create a new partition!"; }
	prompt "06%" "Create partition: '%s' on drive: %s" ${PART_LABEL:-ublinux} "${DEVICE}"
    #[[ -n ${ARG_PART_SIZE} ]] && ARG_PART_SIZE="+${ARG_PART_SIZE%%@(,|;|\|)*}"
    [[ -z ${ARG_TEST} ]] && { sgdisk -a=2048 -n 0:0:-$(numfmt --to=iec ${ARG_SWAP_SIZE:-0}) -c 0:${PART_LABEL:-ublinux} -t 0:8300 ${DEVICE} 1>&3 2>&3 || return 1; }	# create partition
    partprobe ${DEVICE} 1>&3 2>&3
    sleep 1
    ARG_PART="$(lsblk --list --noheadings --paths --output PATH,PARTTYPENAME,PARTLABEL,LABEL ${DEVICE} | cut -d' ' -f1 | tail -1)"
    if [[ ${ARG_SWAP,,} == "yes" && ${ARG_SWAP_SIZE:-0} -gt 10485760 ]]; then	# Минимум 10М на свап, иначе не создавать
	prompt "06%" "Create swap partition: '%s' on drive: %s" "swap" "${DEVICE}"
	[[ -z ${ARG_TEST} ]] && { sgdisk -a=2048 -n 0:0:0 -c 0:swap -t 0:8200 ${DEVICE} 1>&3 2>&3 || return 1; }	# create swap partition
    fi
	prompt "07%" "Create hybrid MBR: '%s' on drive: %s" "1:2" "${DEVICE}"
    [[ -z ${ARG_TEST} ]] && { sgdisk -h 2:3 ${DEVICE} 1>&3 2>&3 || return 1; }			# create hybrid MBR partnum[:partnum...][:EE]
	prompt "08%" "Set boot atribute partition: '%s' on drive: %s" "1" "${DEVICE}"
    [[ -z ${ARG_TEST} ]] && { sgdisk -A 1:set:2 ${DEVICE} 1>&3 2>&3 || return 1; }		# set boot atribute
    partprobe ${DEVICE} 1>&3 2>&3
    sync; sleep 1
    echo 3 > /proc/sys/vm/drop_caches
    sleep 1
}

make_fs_efi(){
    local DEVICE=$1
    local PART_EFI=$(lsblk --list --noheadings --paths --output PATH,PARTTYPENAME ${DEVICE} | grep -iE "EFI System|EFI \(FAT-12/16/32\)" | cut -d' ' -f1 | head -1) #"
    if [[ -b ${PART_EFI} ]]; then
	prompt "10%" "Make fat32 on partition '%s': %s" "efi" "${PART_EFI}"
	[[ -z ${ARG_TEST} ]] && { eval mkfs.fat -F32 -n EFI ${PART_EFI} 1>&3 2>&3 || return 1; }
	partprobe ${DEVICE} 1>&3 2>&3
	sync; sleep 1
	echo 3 > /proc/sys/vm/drop_caches
    fi
    sleep 0.5
}

make_fs(){
    local PART=$1
    local PART_FS_TYPE=$2
    local PART_FS_LABEL=$3
    if [[ -b ${PART} && -n ${PART_FS_TYPE} ]]; then
	local DEVICE=$(lsblk --list --noheadings --paths --output PKNAME,PATH,PARTLABEL,LABEL ${PART} | cut -d' ' -f1 | head -1)
	if [[ -b ${DEVICE} ]]; then
	    prompt "11%" "Make fs '%s' label '%s' on partition '%s'" "${PART_FS_TYPE}" "${PART_FS_LABEL}" "${PART}"
	    [[ -z ${ARG_TEST} ]] && case "${PART_FS_TYPE,,}" in
	        bfs)
	            prompt "mkfs.${PART_FS_TYPE,,} -v -f ${PART_FS_LABEL:+--vname ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} -v -f ${PART_FS_LABEL:+--vname ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        btrfs)
	            prompt "mkfs.${PART_FS_TYPE,,} -v -f ${PART_FS_LABEL:+-L ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} -v -f ${PART_FS_LABEL:+-L ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        exfat)
	            prompt "mkfs.${PART_FS_TYPE,,} -v -f ${PART_FS_LABEL:+-L ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} -v -f ${PART_FS_LABEL:+-L ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        ext2|ext3|ext4)
	            prompt "mkfs.${PART_FS_TYPE,,} -v -F ${PART_FS_LABEL:+-L ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} -v -F ${PART_FS_LABEL:+-L ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        f2fs)
	            prompt "mkfs.${PART_FS_TYPE,,} -f ${PART_FS_LABEL:+-l ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} -f ${PART_FS_LABEL:+-l ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        fat|msdos|vat)
	            prompt "mkfs.${PART_FS_TYPE,,} -v ${PART_FS_LABEL:+-n ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} -v ${PART_FS_LABEL:+-n ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        fat12|msdos12|vat12)
	            prompt "mkfs.${PART_FS_TYPE,,} -v ${PART_FS_LABEL:+-n ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} -v -F 12 ${PART_FS_LABEL:+-n ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        fat16|msdos16|vat16)
	            prompt "mkfs.${PART_FS_TYPE,,} -v ${PART_FS_LABEL:+-n ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} -v -F 16 ${PART_FS_LABEL:+-n ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        fat32|msdos32|vat32)
	            prompt "mkfs.${PART_FS_TYPE,,} -v ${PART_FS_LABEL:+-n ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} -v -F 32 ${PART_FS_LABEL:+-n ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        jfs)
	            prompt "mkfs.${PART_FS_TYPE,,} -f -c ${PART_FS_LABEL:+-L ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} -f -c ${PART_FS_LABEL:+-L ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        minix)
	            prompt "mkfs.${PART_FS_TYPE,,} -c -3 ${PART}"
	            mkfs.${PART_FS_TYPE,,} -c -3 ${PART} 1>&3 2>&3 || return 1
	        ;;
	        nilfs2)
	            prompt "mkfs.${PART_FS_TYPE,,} -v -f -c ${PART_FS_LABEL:+-L ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} -v -f -c ${PART_FS_LABEL:+-L ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        ntfs)
	            prompt "mkfs.${PART_FS_TYPE,,} -v -F ${PART_FS_LABEL:+-L ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} -v -F ${PART_FS_LABEL:+-L ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        reiserfs)
	            prompt "mkfs.${PART_FS_TYPE,,} -d -ff ${PART_FS_LABEL:+-l ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} -d -ff ${PART_FS_LABEL:+-l ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        udf)
	            prompt "mkfs.${PART_FS_TYPE,,} ${PART_FS_LABEL:+-l ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} ${PART_FS_LABEL:+-l ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        xfs)
	            prompt "mkfs.${PART_FS_TYPE,,} -f ${PART_FS_LABEL:+-L ${PART_FS_LABEL}} ${PART}"
	            mkfs.${PART_FS_TYPE,,} -f ${PART_FS_LABEL:+-L ${PART_FS_LABEL}} ${PART} 1>&3 2>&3 || return 1
	        ;;
	        zfs)
                # TODO: Доделать, т.к. сейчас создайтся пул с точкой монтирования в ${PART_FS_LABEL}
                # TODO: https://habr.com/ru/companies/selectel/articles/926806/
	            #prompt "zpool create -f ${PART_FS_LABEL} ${PART}"
	            #zpool create ${PART_FS_LABEL} -f ${PART} 1>&3 2>&3 || return 1
	            # Без сжатия, raidz или шифрования:
	            prompt "zpool create -o ashift=12 -o autotrim=on -O normalization=formD -O acltype=posixacl -O xattr=sa -O dnodesize=auto -O canmount=off -O mountpoint=none -R /mnt ${PART_FS_LABEL} ${PART}"
	            zpool create -o ashift=12 -o autotrim=on -O normalization=formD -O acltype=posixacl -O xattr=sa -O dnodesize=auto -O canmount=off -O mountpoint=none -R /mnt ${PART_FS_LABEL} ${PART}
	            # Дедупликация жрёт много ОЗУ, но экномит место на диске
	            #prompt "zfs set dedup=on ${PART_FS_LABEL}"
	            #zfs set dedup=on ${PART_FS_LABEL} 1>&3 2>&3 || return 1

	            prompt "zpool status -P ${PART_FS_LABEL}"
	            zpool status -P ${PART_FS_LABEL} 1>&3 2>&3 || return 1
	            prompt "zfs list ${PART_FS_LABEL}"
	            zfs list ${PART_FS_LABEL} 1>&3 2>&3 || return 1
	            prompt "zpool get all ${PART_FS_LABEL}"
	            zpool get all ${PART_FS_LABEL} 1>&3 2>&3 || return 1
	        ;;
	        *)
	            prompt "mkfs.${PART_FS_TYPE,,} ${PART_FS_LABEL} ${PART}"
	            mkfs.${PART_FS_TYPE,,} ${PART_FS_LABEL} ${PART} 1>&3 2>&3 || return 1
	        ;;
	    esac
	    [[ -b ${DEVICE} ]] && partprobe ${DEVICE} 1>&3 2>&3
	    sync; sleep 1
	    echo 3 > /proc/sys/vm/drop_caches
	else
	    prompt -eq "Device '%s' is not block!" "${PART}"
	fi
	sleep 0.5
    else
	prompt -eq "File system type:'%s' or partition label:'%s' on partition '%s' not set !" "${PART_FS_TYPE}" "${PART_FS_LABEL}" "${PART}"
    fi
}

make_fs_swap(){
    local DEVICE=$1
    local PART_SWAP=$(lsblk --list --noheadings --paths --output PATH,PARTTYPENAME ${DEVICE} | grep -iE "Linux swap|swap" | cut -d' ' -f1 | head -1) #"
    if [[ -b ${PART_SWAP} ]]; then
	prompt "10%" "Make swap on partition '%s': %s" "swap" "${PART_SWAP}"
	[[ -z ${ARG_TEST} ]] && { mkswap -L swap ${PART_SWAP} 1>&3 2>&3 || return 1; }
	partprobe ${DEVICE} 1>&3 2>&3
	sync; sleep 1
	echo 3 > /proc/sys/vm/drop_caches
    fi
    sleep 0.5
}

drive_mount(){
    local DEVICE=${1//@(;|\|)/,}	# Если указано два устройства, то на втором подразумевается ublinux-data
    local PART_LABEL=${2//@(;|\|)/,}	# Можно указать метку фс или раздела или имя раздела /dev/sda3
					# Если указано две метки, то на второй подразумевается ublinux-data
    local DEVICE_MEDIA= DEVICE_DATA=
    IFS=',' read DEVICE_MEDIA DEVICE_DATA NULL <<< ${DEVICE}
    [[ -z ${DEVICE_DATA} ]] && DEVICE_DATA=${DEVICE_MEDIA}
    local PART_MEDIA_LABEL= PART_DATA_LABEL=
    IFS=',' read PART_MEDIA_LABEL PART_DATA_LABEL NULL <<< ${PART_LABEL}
    [[ -z ${PART_DATA_LABEL} ]] && PART_DATA_LABEL=${PART_MEDIA_LABEL}
    
    if [[ -n ${DEVICE_MEDIA} ]]; then
	# Если указано два устройства, то найти раздел efi вначале на media, если не найден, то на data
	local PART_EFI="$(lsblk --list --noheadings --paths --output PATH,PARTLABEL,LABEL,PARTTYPENAME ${DEVICE_MEDIA} | grep -i "EFI System" | head -1 | cut -d' ' -f1)"
	[[ -n ${PART_EFI} ]] || PART_EFI="$(lsblk --list --noheadings --paths --output PATH,PARTLABEL,LABEL ${DEVICE_DATA} | grep efi | head -1 | cut -d' ' -f1)"
	if [[ -n ${PART_EFI} ]]; then
	    prompt "12%" "Make EFI directory: %s" "/mnt${DEVICE_MEDIA}/efi"
	    mkdir -p /mnt${DEVICE_MEDIA}/efi 1>&3 2>&3
	    prompt "12%" "Mount EFI directory device: %s to path: %s" "${PART_EFI}" "/mnt${DEVICE_MEDIA}/efi"
	    mount ${PART_EFI} /mnt${DEVICE_MEDIA}/efi 1>&3 2>&3
	    findmnt -P --source ${PART_EFI} &>/dev/null && PATH_MOUNT_EFI="/mnt${DEVICE_MEDIA}/efi" && DEVICE_MOUNT_EFI=${PART_EFI}
	else
	    prompt -w "Partition EFI on device '%s' and label '%s' not found !" "${DEVICE_MEDIA}" "efi"
	fi
    fi
    if [[ -n ${DEVICE_MEDIA} && -n ${PART_MEDIA_LABEL} ]]; then
	local LINE_PART_DEVICE="$(lsblk --pairs --noheadings --paths --output PATH,PARTLABEL,LABEL,FSTYPE ${DEVICE_MEDIA} | grep ${PART_MEDIA_LABEL} | tail -1)"
	local PATH_LSBLK= PARTLABEL_LSBLK= LABEL_LSBLK= FSTYPE_LSBLK=
	LINE_PART_DEVICE=${LINE_PART_DEVICE//=/_LSBLK=}; LINE_PART_DEVICE=${LINE_PART_DEVICE//\" /\"; }
	eval ${LINE_PART_DEVICE}
	SELECT_PATH=${PATH_LSBLK}; SELECT_PARTLABEL=${PARTLABEL_LSBLK}; SELECT_LABEL=${LABEL_LSBLK}; SELECT_FSTYPE=${FSTYPE_LSBLK};
	if [[ -n ${SELECT_PATH} && -n ${SELECT_FSTYPE} ]]; then
	    prompt "13%" "Make MEDIA directory: %s" "/mnt${DEVICE_MEDIA}/media"
	    mkdir -p /mnt${DEVICE_MEDIA}/media 1>&3 2>&3
	    prompt "13%" "Mount MEDIA directory device: %s to path: %s" "${SELECT_PATH}" "/mnt${DEVICE_MEDIA}/media"
	    mount ${SELECT_PATH} /mnt${DEVICE_MEDIA}/media 1>&3 2>&3
	    findmnt -P --source ${SELECT_PATH} &>/dev/null && PATH_MOUNT_MEDIA="/mnt${DEVICE_MEDIA}/media" && DEVICE_MOUNT_MEDIA=${SELECT_PATH}
	else
	    prompt -wq "Partition MEDIA on device '%s' and label/part '%s' with file system not found !" "${DEVICE_MEDIA}" "${PART_MEDIA_LABEL}"
	fi
    fi
    if [[ -n ${DEVICE_DATA} && -n ${PART_DATA_LABEL} ]]; then
	local LINE_PART_DEVICE="$(lsblk --pairs --noheadings --paths --output PATH,PARTLABEL,LABEL,FSTYPE ${DEVICE_MEDIA} | grep ${PART_DATA_LABEL} | tail -1)"
	local PATH_LSBLK= PARTLABEL_LSBLK= LABEL_LSBLK= FSTYPE_LSBLK=
	LINE_PART_DEVICE=${LINE_PART_DEVICE//=/_LSBLK=}; LINE_PART_DEVICE=${LINE_PART_DEVICE//\" /\"; }
	eval ${LINE_PART_DEVICE}
	SELECT_PATH=${PATH_LSBLK}; SELECT_PARTLABEL=${PARTLABEL_LSBLK}; SELECT_LABEL=${LABEL_LSBLK}; SELECT_FSTYPE=${FSTYPE_LSBLK};
	# Если ФС ntfs и раздел MEDIA=DATA, то повторно для DATA смонтировать нельзя, для этого указываем раздел DATA == MEDIA
	if [[ -n ${SELECT_PATH} && -n ${SELECT_FSTYPE} && ${PART_MEDIA_LABEL} == ${PART_DATA_LABEL} && ${SELECT_FSTYPE} == 'ntfs' ]]; then
	    prompt "13%" "Make DATA directory: %s" "/mnt${DEVICE_DATA}/data"
	    mkdir -p /mnt${DEVICE_MEDIA}/data 1>&3 2>&3
	    prompt "13%" "Set DATA directory device: %s to path: %s" "${SELECT_PATH}" "/mnt${DEVICE_DATA}/data"
	    findmnt -P --source ${SELECT_PATH} &>/dev/null && PATH_MOUNT_DATA="/mnt${DEVICE_MEDIA}/media" && DEVICE_MOUNT_DATA=${SELECT_PATH}
	elif [[ -n ${SELECT_PATH} && -n ${SELECT_FSTYPE} ]]; then
	    prompt "13%" "Make DATA directory: %s" "/mnt${DEVICE_DATA}/data"
	    mkdir -p /mnt${DEVICE_MEDIA}/data 1>&3 2>&3
	    prompt "13%" "Mount DATA directory device: %s to path: %s" "${SELECT_PATH}" "/mnt${DEVICE_DATA}/data"
	    mount ${SELECT_PATH} /mnt${DEVICE_DATA}/data 1>&3 2>&3
	    findmnt -P --source ${SELECT_PATH} &>/dev/null && PATH_MOUNT_DATA="/mnt${DEVICE_MEDIA}/data" && DEVICE_MOUNT_DATA=${SELECT_PATH}
	else
	    prompt -wq "Partition DATA on device '%s' and label/part '%s' with file system not found !" "${DEVICE_DATA}" "${PART_DATA_LABEL}"
	fi
    fi
    if [[ -n ${DEVICE_MEDIA} || -n ${DEVICE_DATA} ]]; then
	# Проверим если на устройствах имеется каталог boot то его выбираем для переменной
	prompt "13%" "Make BOOT directory"
	if [[ -n ${PATH_MOUNT_MEDIA} && -e ${PATH_MOUNT_MEDIA}/boot/grub/grub.cfg ]]; then
	    DEVICE_MOUNT_BOOT=${DEVICE_MOUNT_MEDIA}
	    PATH_MOUNT_BOOT=${PATH_MOUNT_MEDIA}
	elif [[ ${PATH_MOUNT_DATA} && -e ${PATH_MOUNT_DATA}/boot/grub/grub.cfg ]]; then
	    DEVICE_MOUNT_BOOT=${DEVICE_MOUNT_DATA}
	    PATH_MOUNT_BOOT=${PATH_MOUNT_DATA}
	else
	    # Перебрать все партиции на устройстве, для поиска установленного grub
	    local EXIT_WHILE=
	    while IFS= read -r LINE_PART_DEVICE; do
		[[ -n ${EXIT_WHILE} ]] && continue
		[[ ${LINE_PART_DEVICE} == "" ]] && continue
		local PKNAME_LSBLK= PATH_LSBLK= FSTYPE_LSBLK=
		LINE_PART_DEVICE=${LINE_PART_DEVICE//=/_LSBLK=}; LINE_PART_DEVICE=${LINE_PART_DEVICE//\" /\"; }
		eval ${LINE_PART_DEVICE}
		SELECT_PKNAME=${PKNAME_LSBLK}; SELECT_PATH=${PATH_LSBLK}; SELECT_FSTYPE=${FSTYPE_LSBLK};
		
		# Если устройство не раздел, то пропускаем
		[[ ${SELECT_PKNAME} == "" || ${SELECT_FSTYPE} == "" ]] && continue
		local PATH_SELECT_PATH="/mnt${SELECT_PATH}"
		prompt "13%" "Probing BOOT directory device: %s to path: %s" "${SELECT_PATH}" "${PATH_SELECT_PATH}"
		mkdir -p ${PATH_SELECT_PATH}
		mount --mkdir ${SELECT_PATH} "${PATH_SELECT_PATH}" 2>/dev/null \
		&& if [[ -e ${PATH_SELECT_PATH}/boot/grub/grub.cfg ]]; then
		#&& if [[ -e ${PATH_SELECT_PATH}/boot/grub/grub.cfg || -e ${PATH_SELECT_PATH}/grub/grub.cfg ]]; then
		    DEVICE_MOUNT_BOOT=${SELECT_PATH}
		    PATH_MOUNT_BOOT=${PATH_SELECT_PATH}
		    EXIT_WHILE=yes	# Break не использую, что-бы не ломало lsblk
		else
		    #umount --recursive ${PATH_SELECT_PATH} 1>&3 2>&3 && rm -rdf ${PATH_SELECT_PATH}
		    umount ${PATH_SELECT_PATH} 1>&3 2>&3 && rm -rdf ${PATH_SELECT_PATH}
		fi		
	    done < <(lsblk --pairs --noheadings --paths --output PKNAME,PATH,FSTYPE ${DEVICE_MEDIA} ${DEVICE_DATA})
	    if [[ -z ${DEVICE_MOUNT_BOOT} && -z ${PATH_MOUNT_BOOT} ]]; then
	    # Определяем новую установку
		DEVICE_MOUNT_BOOT=${DEVICE_MOUNT_MEDIA}
		PATH_MOUNT_BOOT=${PATH_MOUNT_MEDIA}
	    fi
	fi
	if [[ -n ${DEVICE_MOUNT_BOOT} && -n ${PATH_MOUNT_BOOT} ]]; then
	    prompt "13%" "Mount BOOT directory device: %s to path: %s" "${DEVICE_MOUNT_BOOT}" "${PATH_MOUNT_BOOT}"
	else
	    prompt -wq "Partition BOOT not found !" "${DEVICE_DATA}" "${PART_DATA_LABEL}"
	fi
    fi
    sleep 0.5
#    echo "PATH_MOUNT_EFI=${PATH_MOUNT_EFI}	DEVICE_MOUNT_EFI=${DEVICE_MOUNT_EFI}"
#    echo "PATH_MOUNT_MEDIA=${PATH_MOUNT_MEDIA}	DEVICE_MOUNT_MEDIA=${DEVICE_MOUNT_MEDIA}"
#    echo "PATH_MOUNT_DATA=${PATH_MOUNT_DATA}	DEVICE_MOUNT_DATA=${DEVICE_MOUNT_DATA}"
#    echo "PATH_MOUNT_BOOT=${PATH_MOUNT_BOOT}	DEVICE_MOUNT_BOOT=${DEVICE_MOUNT_BOOT}"
}

install_grub(){
    local DEVICE_MEDIA="${1%%@(,|;|\|)*}"
    local ARCH=$2	# x86_64-efi,i386-efi,i386-pc
    prompt "16%" "Install GRUB achitecture: %s " "${ARCH}"
    [[ -z ${PATH_MOUNT_EFI} ]] && prompt -w "For grub installation, the EFI path is not set!"
    [[ -z ${PATH_MOUNT_BOOT} ]] && prompt -wq "For grub installation, the BOOT path is not set!"
    
    [[ -z ${ARG_TEST} ]] && { mkdir -p ${PATH_MOUNT_BOOT}/boot || return 1; }
    if [[ ${ARCH} =~ "x86_64-efi" && -n ${PATH_MOUNT_EFI} ]]; then
	prompt "17%" "Install %s" "GRUB target=x86_64-efi"
	[[ -z ${ARG_TEST} ]] && grub-install --target=x86_64-efi --efi-directory=${PATH_MOUNT_EFI} --boot-directory=${PATH_MOUNT_BOOT}/boot --removable --recheck 1>&3 2>&3 \
	&& find ${PATH_MOUNT_EFI} -ipath "*/efi/boot/*" -iname "bootx64.efi" -exec install -D -t ${PATH_MOUNT_EFI}/EFI/UBLINUX {} +
    fi
    if [[ ${ARCH} =~ "i386-efi" && -n ${PATH_MOUNT_EFI} ]]; then
	prompt "18%" "Install %s" "GRUB target=i386-efi"
	[[ -z ${ARG_TEST} ]] && grub-install --target=i386-efi --efi-directory=${PATH_MOUNT_EFI} --boot-directory=${PATH_MOUNT_BOOT}/boot --removable --recheck 1>&3 2>&3 \
	&& find ${PATH_MOUNT_EFI} -ipath "*/efi/boot/*" -iname "bootia32.efi" -exec install -D -t ${PATH_MOUNT_EFI}/EFI/UBLINUX {} +
    fi
    if [[ ${ARCH} =~ "i386-pc" && -n ${DEVICE_MOUNT_BOOT} ]]; then
	prompt "19%" "Install %s" "GRUB target=i386-pc"
	[[ -z ${ARG_TEST} && -n ${DEVICE_MOUNT_BOOT} && -b ${DEVICE_MEDIA} ]] && grub-install --target=i386-pc --boot-directory=${PATH_MOUNT_BOOT}/boot --recheck ${DEVICE_MEDIA} 1>&3 2>&3
    fi
    sync; sleep 1
    echo 3 > /proc/sys/vm/drop_caches
    sleep 1
}

install_uefi_menu(){
    local DEVICE_MEDIA=$1
    command -v efibootmgr &>/dev/null || return 0
    efibootmgr 1>&3 2>&3 || return 0
    prompt "17%" "Install UEFI entry: %s" "/EFI/Boot/bootx64.efi"
    # Найти и удалить имеющуюся запись
    FIND_RECORD_EFI=$(efibootmgr -- | grep 'UBLinux' | sed -Ern 's/Boot([[:digit:]]+). .*/\1/p') #'
    [[ -z ${FIND_RECORD_EFI} ]] || efibootmgr -b ${FIND_RECORD_EFI} -B 1>&3 2>&3

    if [[ -n ${PATH_MOUNT_EFI} && -n ${DEVICE_MOUNT_EFI} ]] && mountpoint --quiet ${PATH_MOUNT_EFI}; then
    # После устанновки GRUB раздел EFI примонтирован, получить устройство от примонтированного раздела
	true
    elif [[ -n ${DEVICE_MEDIA} ]]; then
    # Найти первый раздел с меткой EFI
        local DEVICE_MOUNT_EFI=$(blkid --output device --match-token LABEL="EFI" -c /dev/null ${DEVICE_MEDIA}*)
        [[ -n ${DEVICE_MOUNT_EFI} ]] || DEVICE_MOUNT_EFI=$(blkid --output device --match-token PARTLABEL="efi" -c /dev/null ${DEVICE_MEDIA}*)
        if [[ -n ${DEVICE_MOUNT_EFI} ]]; then
            local PATH_MOUNT_EFI="/mnt${DEVICE_MEDIA}/efi"
            mkdir -p ${PATH_MOUNT_EFI}
            mount ${DEVICE_MOUNT_EFI} ${PATH_MOUNT_EFI}
        fi
    else
	return 1
    fi
    local DEVICE_EFI= NUM_PART_EFI= FIND_LOADER=
    if [[ -n ${PATH_MOUNT_EFI} && -n ${DEVICE_MOUNT_EFI} ]]; then
	# Получить имя самого устройства из имени партиции
        DEVICE_EFI="$(lsblk --list --noheadings --paths --output PKNAME ${DEVICE_MOUNT_EFI} | head -1)"
        # Получить порядковый номер партиции из имени партиции
        NUM_PART_EFI="$(partx -rgo NR ${DEVICE_MOUNT_EFI})"
        # Найти созданный .efi и добавить в меню
        [[ -z ${FIND_LOADER} ]] && FIND_LOADER=$(find ${PATH_MOUNT_EFI} -ipath "*/efi/ublinux/*" -type f -iname "bootx64.efi" 2>/dev/null | sed "s|${PATH_MOUNT_EFI}||g" | tr '/' '\\')
        [[ -z ${FIND_LOADER} ]] && FIND_LOADER=$(find ${PATH_MOUNT_EFI} -ipath "*/efi/ublinux/*" -type f -iname "grubx64.efi" 2>/dev/null | sed "s|${PATH_MOUNT_EFI}||g" | tr '/' '\\')
        [[ -z ${FIND_LOADER} ]] && FIND_LOADER=$(find ${PATH_MOUNT_EFI} -ipath "*/efi/boot/*" -type f -iname "bootx64.efi" 2>/dev/null | sed "s|${PATH_MOUNT_EFI}||g" | tr '/' '\\')
        [[ -z ${FIND_LOADER} ]] && FIND_LOADER=$(find ${PATH_MOUNT_EFI} -ipath "*/efi/boot/*" -type f -iname "grubx64.efi" 2>/dev/null | sed "s|${PATH_MOUNT_EFI}||g" | tr '/' '\\')
        [[ -z ${FIND_LOADER} ]] && FIND_LOADER=$(find ${PATH_MOUNT_EFI} -type f -iname "bootx64.efi" 2>/dev/null | sed "s|${PATH_MOUNT_EFI}||g" | tr '/' '\\')
        [[ -z ${FIND_LOADER} ]] && FIND_LOADER=$(find ${PATH_MOUNT_EFI} -type f -iname "grubx64.efi" 2>/dev/null | sed "s|${PATH_MOUNT_EFI}||g" | tr '/' '\\')
        [[ -z ${ARG_TEST} && -n ${DEVICE_EFI} && -n ${NUM_PART_EFI} && -n ${FIND_LOADER} ]] \
        && efibootmgr --create --disk ${DEVICE_EFI} --part ${NUM_PART_EFI} --label "UBLinux" --loader "${FIND_LOADER}" 1>&3 2>&3
    fi
    sleep 0.5
}

create_skeleton(){
    local MODE=$1
    local PATH_MOUNT_MEDIA=$2
    local PATH_MOUNT_BOOT=$3
    local PATH_MOUNT_DATA=$4
    prompt "19%" "Creating skeletons"
    [[ -z ${ARG_TEST} ]] || return 0
    if [[ ${MODE,,} =~ "media" && ${PATH_MOUNT_MEDIA} != @(""|"-") ]]; then
	prompt "19%" "Creating skeleton /ublinux/"
	/usr/lib/ubboot/ubboot-skel create --skel-ublinux --path-media "${PATH_MOUNT_MEDIA}" 1>&3 2>&3
    fi
    if [[ ${MODE,,} =~ "data" && ${PATH_MOUNT_DATA} != @(""|"-") ]]; then 
        prompt "19%" "Creating skeleton /ublinux-data/"
	/usr/lib/ubboot/ubboot-skel create --skel-data --path-media "${PATH_MOUNT_DATA}" 1>&3 2>&3
    fi
    if [[ ${MODE,,} =~ "boot" ]] && [[ ${PATH_MOUNT_MEDIA} != @(""|"-") || ${PATH_MOUNT_BOOT} != @(""|"-") ]]; then
	prompt "19%" "Creating skeleton /boot/grub/ublinux"
	[[ ${PATH_MOUNT_BOOT} == @(""|"-") ]] && PATH_MOUNT_BOOT=${PATH_MOUNT_MEDIA}
	#rm -rdf ${PATH_MOUNT_BOOT}/boot/grub/themes
	/usr/lib/ubboot/ubboot-skel create --skel-grub --grub-theme --path-media "${PATH_MOUNT_MEDIA}" --path-boot "${PATH_MOUNT_BOOT}" 1>&3 2>&3
#	[[ -n ${DETECT_MBR_WINDOWS} ]] && cat <<'EOF' >> "${PATH_MOUNT_BOOT}/boot/grub/ublinux/grub_local.cfg"
#	menuentry "Загрузка Windows 7-12 BIOS MBR (bootmgr)" --unrestricted {
#	    savedefault
#	    set BOOTFILE=/bootmgr
#    	    search --no-floppy --set=root --file ${BOOTFILE}
#    	    ntldr ${BOOTFILE}
#	}
#	menuentry "Загрузка Windows 2000-XP BIOS MBR (ntldr)" --unrestricted {
#	    savedefault
#	    set BOOTFILE=/ntldr
#    	    search --no-floppy --set=root --file ${BOOTFILE}
#    	    ntldr ${BOOTFILE}
#	}
#	menuentry "Загрузка Windows BIOS MBR" --unrestricted {
#	    savedefault
#	    set BOOTFILE=/ntldr
#    	    search --no-floppy --set=root --file ${BOOTFILE}
#    	    chainloader +1
#	}
#EOF
    fi
    sleep 0.5
}

update_skeleton(){
    local MODE=$1
    local PATH_MOUNT_MEDIA=$2
    local PATH_MOUNT_BOOT=$3
    local PATH_MOUNT_DATA=$4
    prompt "19%" "Updating skeletons"
    [[ -z ${ARG_TEST} ]] || return 0
    if [[ ${MODE,,} =~ "media" && ${PATH_MOUNT_MEDIA} != @(""|"-") ]]; then
	prompt "19%" "Updating skeleton /ublinux/"
	/usr/lib/ubboot/ubboot-skel update --skel-ublinux --path-media "${PATH_MOUNT_MEDIA}" 1>&3 2>&3
    fi
    if [[ ${MODE,,} =~ "data" && ${PATH_MOUNT_DATA} != @(""|"-") ]]; then 
        prompt "19%" "Updating skeleton /ublinux-data/"
	/usr/lib/ubboot/ubboot-skel update --skel-data --path-media "${PATH_MOUNT_DATA}" 1>&3 2>&3
    fi
    if [[ ${MODE,,} =~ "boot" ]] && [[ ${PATH_MOUNT_MEDIA} != @(""|"-") || ${PATH_MOUNT_BOOT} != @(""|"-") ]]; then
	prompt "19%" "Updating skeleton /boot/grub/ublinux"
	[[ ${PATH_MOUNT_BOOT} == @(""|"-") ]] && PATH_MOUNT_BOOT=${PATH_MOUNT_MEDIA}
	#rm -rdf ${PATH_MOUNT_BOOT}/boot/grub/themes
	/usr/lib/ubboot/ubboot-skel update --skel-grub --grub-theme --path-media "${PATH_MOUNT_MEDIA}" --path-boot "${PATH_MOUNT_BOOT}" 1>&3 2>&3
#	[[ -n ${DETECT_MBR_WINDOWS} ]] && cat <<'EOF' >> "${PATH_MOUNT_BOOT}/boot/grub/ublinux/grub_local.cfg"
#	menuentry "Загрузка Windows 7-12 BIOS MBR (bootmgr)" --unrestricted {
#	    savedefault
#	    set BOOTFILE=/bootmgr
#    	    search --no-floppy --set=root --file ${BOOTFILE}
#    	    ntldr ${BOOTFILE}
#	}
#	menuentry "Загрузка Windows 2000-XP BIOS MBR (ntldr)" --unrestricted {
#	    savedefault
#	    set BOOTFILE=/ntldr
#    	    search --no-floppy --set=root --file ${BOOTFILE}
#    	    ntldr ${BOOTFILE}
#	}
#	menuentry "Загрузка Windows BIOS MBR" --unrestricted {
#	    savedefault
#	    set BOOTFILE=/bootmgr
#    	    search --no-floppy --set=root --file ${BOOTFILE}
#    	    chainloader +1
#	}
#EOF
    fi
    sleep 0.5
}

copy_ublinux(){
    local SOURCES=$1
    local PATH_COPY_SRC=
    [[ -z ${ARG_TEST} ]] && { [[ -d ${PATH_MOUNT_MEDIA} ]] || return 1; }
    [[ -n ${SOURCES} ]] && while IFS= read -r SOURCE; do
	if [[ ${SOURCE} == @(""|"auto") ]]; then
	    PATH_COPY_SRC=$(find "/memory/data/from" -maxdepth 2 -type d -ipath "*/[[:digit:]]*/*" -iname "ublinux" | head -1)
	elif [[ -d ${SOURCE} ]]; then
	    PATH_COPY_SRC=$(find "${SOURCE}" -maxdepth 1 -type d -iname "ublinux" | head -1)
	elif [[ -b ${SOURCE} ]]; then
	    mkdir -p /mnt/source/${SOURCE##*/}
	    mount ${SOURCE} "/mnt/source/${SOURCE##*/}" 1>&3 2>&3 || return 1
	    PATH_COPY_SRC=$(find "/mnt/source/${SOURCE##*/}" -maxdepth 1 -type d -iname "ublinux" | head -1)
	elif [[ ${SOURCE} =~ ".iso"$ ]]; then
	    file -s ${SOURCE} | grep -iq "iso 9660" || return 1
	    mkdir -p /mnt/source/${SOURCE##*/}
	    mount ${SOURCE} "/mnt/source/${SOURCE##*/}" 1>&3 2>&3 || return 1
	    PATH_COPY_SRC=$(find "/mnt/source/${SOURCE##*/}" -maxdepth 1 -type d -iname "ublinux" | head -1)
	fi
	[[ -n ${PATH_COPY_SRC} ]] || continue
	prompt "20%" "Copying file system"
	# Если выбраны шаблоны конкретных модулей, то только их копировать
	if [[ ${ARG_MODULES} != @(""|"auto") ]]; then
	    INAME_FIND=$(while IFS= read -r LINE_MODULE; do printf " -iname '%s' -o" "${LINE_MODULE}"; done <<<${ARG_MODULES//,/$'\n'})
	    RSYNC_INCLUDE=$(eval find "${PATH_COPY_SRC%/*}/" ${INAME_FIND%*-o} | while IFS= read -r LINE_INCLUDE; do printf " --include '%s' " "${LINE_INCLUDE##*/}"; done)
	    RSYNC_EXCLUDE="--exclude='*/*.ubm'"
	else
	    RSYNC_INCLUDE=
	    RSYNC_EXCLUDE=
	fi	
	LINE_FILE=; LINE_FILE_NUM=1; LINE_FILE_SUM=0/0
	[[ -z ${ARG_TEST} ]] && eval rsync -akhHEAX --ignore-times --no-i-r  --progress ${RSYNC_INCLUDE} --exclude='ublinux-*.sgn' ${RSYNC_EXCLUDE} "${PATH_COPY_SRC}" "${PATH_MOUNT_MEDIA}/" | stdbuf -oL tr '\r' '\n' | while IFS= read -r LINE; do
	    LINE_SHOW=
	    if [[ -f ${PATH_COPY_SRC%/*}/${LINE} ]]; then
    		LINE_FILE="${LINE##*/}"
	    elif [[ ${LINE} =~ ^[[:blank:]]+([^[:blank:]]+)[[:blank:]]+([^[:blank:]]+)[[:blank:]]+([^[:blank:]]+)[[:blank:]]+([^[:blank:]]+)[[:blank:]]+[[:blank:]]*$ ]]; then
		LINE_SIZE=${BASH_REMATCH[1]}; LINE_PERC=${BASH_REMATCH[2]}; LINE_SPEED=${BASH_REMATCH[3]}; LINE_TIME=${BASH_REMATCH[4]}; LINE_SHOW=yes
	    elif [[ ${LINE} =~ ^[[:blank:]]+([^[:blank:]]+)[[:blank:]]+([^[:blank:]]+)[[:blank:]]+([^[:blank:]]+)[[:blank:]]+([^[:blank:]]+)[[:blank:]]+"(xfr#"([^,]+)", to-chk="([^\)]+)")"[[:blank:]]*$ ]]; then
		LINE_SIZE=${BASH_REMATCH[1]}; LINE_PERC=${BASH_REMATCH[2]}; LINE_SPEED=${BASH_REMATCH[3]}; LINE_TIME=${BASH_REMATCH[4]}; LINE_SHOW=yes
		LINE_FILE_NUM=${BASH_REMATCH[5]}; LINE_FILE_SUM=${BASH_REMATCH[6]}
	    fi
	    [[ -n ${LINE_SHOW} ]] \
	    && i18n "Copy file: %s %s %s %s %s %s %s\n" "${LINE_FILE}" "${LINE_SIZE}" "${LINE_PERC}" "${LINE_SPEED}" "${LINE_TIME}" "${LINE_FILE_NUM}" "${LINE_FILE_SUM}" 1>&3 2>&3 \
    	    && printf "(#pb) %s %s %s %s %s %s %s\n" "${LINE_FILE}" "${LINE_SIZE}" "${LINE_PERC}" "${LINE_SPEED}" "${LINE_TIME}" "${LINE_FILE_NUM}" "${LINE_FILE_SUM}" 1>&5 2>/dev/null
	done || 
	prompt "90%" "Extract file %s" "$(find ${PATH_COPY_SRC} -maxdepth 1 -type f -iname "ublinux-data.tar.*" -print)"
	[[ -z ${ARG_TEST} ]] && find ${PATH_COPY_SRC} -maxdepth 1 -type f -iname "ublinux-data.tar.*" -exec  tar xJf {} -C ${PATH_MOUNT_DATA}/ --exclude='ublinux-*.sgn' 1>&3 2>&3 \;
    done <<< ${SOURCES//@(,|;)/$'\n'}
    echo 3 > /proc/sys/vm/drop_caches
    sync; sleep 1
}

update_sign(){
    prompt "90%" "Update signature"
    [[ -n ${PATH_MOUNT_BOOT} || -n ${PATH_MOUNT_MEDIA} || -n ${PATH_MOUNT_DATA} ]] || return 1
    local ARG_UBBOOT_SKEL_BOOT= ARG_UBBOOT_SKEL_MEDIA= ARG_UBBOOT_SKEL_DATA=
    [[ -n ${PATH_MOUNT_BOOT} ]] && ARG_UBBOOT_SKEL_BOOT="--path-boot ${PATH_MOUNT_BOOT}"
    [[ -n ${PATH_MOUNT_MEDIA} ]] && ARG_UBBOOT_SKEL_MEDIA="--path-media ${PATH_MOUNT_MEDIA}"
    [[ -n ${PATH_MOUNT_DATA} ]] && ARG_UBBOOT_SKEL_DATA="--path-data ${PATH_MOUNT_DATA}"
    [[ -z ${ARG_TEST} ]] && eval /usr/lib/ubboot/ubboot-skel update  --sign ${ARG_UBBOOT_SKEL_BOOT} ${ARG_UBBOOT_SKEL_MEDIA} ${ARG_UBBOOT_SKEL_DATA} 1>&3 2>&3
    echo 3 > /proc/sys/vm/drop_caches
    sync; sleep 0.5
}

post_install_general(){
    local PATH_MOUNT_MEDIA="${PATH_MOUNT_MEDIA}/ublinux"
    if [[ -d ${PATH_MOUNT_MEDIA} ]]; then
	prompt "91%" "Setting attributes for new directories"
	[[ -z ${ARG_TEST} ]] && find ${PATH_MOUNT_MEDIA} -type d -exec chmod -R 644 {} \; -exec chmod 755 {} \; -exec chown -R root:root {} \; 1>&3 2>&3
	prompt "91%" "Setting attributes for new directories"
	[[ -z ${ARG_TEST} ]] && find ${PATH_MOUNT_MEDIA} -maxdepth 1 -type f -exec chmod -R 400 {} + 1>&3 2>&3
    fi
    local PATH_MOUNT_DATA="${PATH_MOUNT_DATA}/ublinux-data"
    if [[ -d ${PATH_MOUNT_DATA} && -z ${ARG_TEST} ]]; then
	prompt "91%" "Configuring System Settings"
	ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" set [system] FIRSTSTART=yes 1>&3 2>&3
	prompt "91%" "Finishing install"
	# Сохранить лог на диске
	[[ ${ARG_LOG,,} == "save" && -e ${FILE_UBINSTALL_LOG} ]] && cp -a ${FILE_UBINSTALL_LOG} "${PATH_MOUNT_DATA}/"
    fi
    echo 3 > /proc/sys/vm/drop_caches
    sync; sleep 0.5
}

post_install_config(){
    local PATH_MOUNT_DATA="${PATH_MOUNT_DATA}/ublinux-data"
    if [[ -d ${PATH_MOUNT_DATA} && -z ${ARG_TEST} ]]; then
	prompt "91%" "Configuring System Settings"
	# Повторно загружаем значения параметров из конфига, т.к. в процессе установки значения могли измениться, через ГУЙ
	default_arguments
	show_conf_settings
	[[ -z ${ARG_LOCALE} ]] 		|| ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" set [locale] LOCALE="${ARG_LOCALE}" 1>&3 2>&3
	[[ -z ${ARG_LANG} ]] 		|| ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" set [locale] LANG="${ARG_LANG}" 1>&3 2>&3
	[[ -z ${ARG_ZONE} ]] 		|| ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" set [clock] ZONE="${ARG_ZONE}" 1>&3 2>&3
	if [[ -n ${ARG_USER_NAME} ]]; then
	    if [[ ${ARG_USER_NAME} == "root" ]]; then
		ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" set [users] USERADD[${ARG_USER_NAME}]=":0:x:x:--home-dir /root:x" 1>&3 2>&3
	    else
		ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" set [users] USERADD[${ARG_USER_NAME}]="${ARG_USER_GECOS}:1000:x:x:x:${ARG_USER_PASSWORD}" 1>&3 2>&3
	    fi
	fi
	[[ -z ${ARG_USER_PASSWORD} ]]	|| ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" set [users] DEFAULTPASSWD="${ARG_USER_PASSWORD}" 1>&3 2>&3
	[[ -z ${ARG_ROOT_PASSWORD} ]]	|| ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" set [users] DEFAULTROOTPASSWD="${ARG_ROOT_PASSWORD}" 1>&3 2>&3
	[[ -z ${ARG_AUTOLOGIN} ]] 	|| ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" set [desktop] AUTOLOGINUSER="${ARG_AUTOLOGIN}" 1>&3 2>&3
	[[ -z ${ARG_XKBMODEL} ]] 	|| ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" set [keyboard] XKBMODEL="${ARG_XKBMODEL}" 1>&3 2>&3
	[[ -z ${ARG_XKBLAYOUT} ]] 	|| ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" set [keyboard] XKBLAYOUT="${ARG_XKBLAYOUT}" 1>&3 2>&3
	[[ -z ${ARG_XKBVARIANT} ]] 	|| ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" set [keyboard] XKBVARIANT="${ARG_XKBVARIANT}" 1>&3 2>&3
	[[ -z ${ARG_XKBOPTIONS} ]] 	|| ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" set [keyboard] XKBOPTIONS="${ARG_XKBOPTIONS}" 1>&3 2>&3
	[[ -z ${ARG_HOSTNAME} ]] 	|| ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" set [system] HOSTNAME="${ARG_HOSTNAME}" 1>&3 2>&3
	for ARG_ITEM in "${!AUTOINSTALL[@]}"; do
	    [[ ${ARG_ITEM} =~ ^"ubconfig "(.*) ]] && ubconfig --target "${PATH_MOUNT_DATA}/ublinux.ini" ${BASH_REMATCH[1]}="${AUTOINSTALL[${ARG_ITEM}]}"
	done
    elif [[ -z ${ARG_TEST} ]]; then
	prompt -eq "Data path 'ublinux-data' not found!"
    fi
    # Восстановить дефолтный EFI по умолчанию, т.к. возможно другая ОС по нему загружается
    if [[ -z ${ARG_TEST} && -n ${PATH_MOUNT_EFI} ]]; then
	prompt "91%" "Detect EFI file other OS, restore EFI file"
	find ${PATH_MOUNT_EFI} -ipath "*/efi/boot/*" -type f -name "grubx64.efi" -exec cp -af "{}" "${PATH_MOUNT_EFI}/EFI/BOOT/BOOTX64.EFI" \;
    fi

    echo 3 > /proc/sys/vm/drop_caches
    sync; sleep 0.5
}

post_install_modules_extra(){
    prompt "91%" "Download extra modules"
    show_extra_settings
    #TODO: Скачать модули указанные в параметрах
    #${ARG_MODULES_EXTRA:+AUTOINSTALL[modules_extra]=${ARG_MODULES_EXTRA}}
    echo 3 > /proc/sys/vm/drop_caches
    sync; sleep 0.5
}

check_part_after_install(){
    local DEVICE=$1
    while IFS= read LINE_DEVICE; do 
        local SELECT_PATH= SELECT_FSTYPE= SELECT_MOUNTPOINT=
        while IFS= read LINE_PART_DEVICE; do
    	    [[ ${LINE_PART_DEVICE} =~ ^([^[:blank:]]+)[[:blank:]]+([^[:blank:]]+)[[:blank:]]*([^[:blank:]]*) ]] \
	    && { SELECT_PATH=${BASH_REMATCH[1]}; SELECT_FSTYPE=${BASH_REMATCH[2]}; SELECT_MOUNTPOINT=${BASH_REMATCH[3]}; }
	    [[ -z ${SELECT_FSTYPE} || -n ${SELECT_MOUNTPOINT} ]] && continue
	    prompt "99%" "Checking file system '%s'  on partition '%s' for errors" "${SELECT_FSTYPE}" "${SELECT_PATH}"
    	    [[ ${SELECT_FSTYPE} == @(ext2|ext3|ext4) ]] && { e2fsck -vfy ${SELECT_PATH} 1>&3 2>&3; }
    	    [[ ${SELECT_FSTYPE} == @(vfat|fat) ]] && { fsck.fat -a -n -l -v ${SELECT_PATH} 1>&3 2>&3; }
	done < <(lsblk --list --noheadings --paths --output PATH,FSTYPE,MOUNTPOINT ${LINE_DEVICE})
    done <<< ${DEVICE//@(,|;|\|)/$'\n'}
    sleep 0.5
}

# Метки получить от устройства и установить соответствующую глобальные переменные меток
# ARG_PART_LABEL	ARG_PART_FS_LABEL
# Можно в тесте применять
get_media_data_label(){
    local PART_LABEL_FILTER= 
    while IFS= read LINE_DEVICE; do 
        local SELECT_PKNAME= SELECT_PATH= SELECT_PARTLABEL=
        while IFS= read -ru 10 LINE_PART_DEVICE; do
	    local PKNAME_LSBLK= PATH_LSBLK= PARTLABEL_LSBLK= LABEL_LSBLK=
	    LINE_PART_DEVICE=${LINE_PART_DEVICE//=/_LSBLK=}; LINE_PART_DEVICE=${LINE_PART_DEVICE//\" /\"; }
	    eval ${LINE_PART_DEVICE}
	    SELECT_PKNAME=${PKNAME_LSBLK}; SELECT_PATH=${PATH_LSBLK}; SELECT_PARTLABEL=${PARTLABEL_LSBLK}; SELECT_LABEL=${LABEL_LSBLK};
	    [[ ${SELECT_PKNAME} == "" || ${SELECT_PARTLABEL} == @(""|bios_boot|efi|EFI) || ${PART_LABEL_FILTER} =~ (^"${SELECT_PARTLABEL},"|"${SELECT_PARTLABEL},"$) ]] || PART_LABEL_FILTER+="${SELECT_PARTLABEL},"
	    [[ ${SELECT_PKNAME} == "" || ${SELECT_LABEL} == @(""|bios_boot|efi|EFI) || ${PART_FS_LABEL_FILTER} =~ (^"${SELECT_LABEL},"|"${SELECT_LABEL},"$) ]] || PART_FS_LABEL_FILTER+="${SELECT_LABEL},"
	done 10< <(lsblk --pairs  --noheadings --paths --output PKNAME,PATH,PARTLABEL,LABEL ${LINE_DEVICE})
    done <<< ${ARG_DEVICE//@(,|;|\|)/$'\n'}
    ARG_PART_LABEL=${PART_LABEL_FILTER%,*}
    ARG_PART_FS_LABEL=${PART_FS_LABEL_FILTER%,*}
    #ARG_PART_LABEL=$(lsblk -no partlabel,path ${ARG_DEVICE//,/ } | grep ublinux | cut -d' ' -f1 | xargs | tr ' ' ',')
    #ARG_PART_FS_LABEL=$(lsblk -no label,path ${ARG_PART//,/ } | grep ublinux | cut -d' ' -f1| xargs | tr ' ' ',')
}

# Просмотреть все разделы устройства, и если найдены ключевые файлы, установить соответствующую глобальные переменные меток
# ARG_PART_LABEL	ARG_PART_FS_LABEL
find_media_data_part(){
    local DEVICE=$1
    if [[ -n ${DEVICE} ]]; then
	while IFS= read -ru 10 SELECT_PART; do
	    local PKNAME_LSBLK= PATH_LSBLK= PARTN_LSBLK= FSTYPE_LSBLK= PARTLABEL_LSBLK= LABEL_LSBLK=
	    SELECT_PART=${SELECT_PART//=/_LSBLK=}
	    SELECT_PART=${SELECT_PART//\" /\"; }
	    eval ${SELECT_PART}
	    SELECT_PKNAME=${PKNAME_LSBLK}; SELECT_PATH=${PATH_LSBLK}; SELECT_PARTN=${PARTN_LSBLK}; SELECT_FSTYPE=${FSTYPE_LSBLK}; SELECT_PARTLABEL=${PARTLABEL_LSBLK}; SELECT_LABEL=${LABEL_LSBLK};
	    # Если устройство не раздел, то пропускаем
	    [[ ${SELECT_PKNAME} == "" || ${SELECT_FSTYPE} == "" ]] && continue
	    local PATH_SELECT_PART="/mnt/findpart${SELECT_PATH}"
	    if mount --mkdir ${SELECT_PATH} ${PATH_SELECT_PART} 2>/dev/null; then
		if [[ -n $(find ${PATH_SELECT_PART}/ublinux -maxdepth 1 -name "ublinux*.sgn") ]]; then
		    ARG_PART=${SELECT_PATH}
		fi  
		if [[ -n $(find ${PATH_SELECT_PART}/ublinux-data -maxdepth 1 -name "ublinux-data*.sgn") ]]; then
		    ARG_PART+=",${SELECT_PATH}"
		fi
	    fi
	    umount ${PATH_SELECT_PART} 1>&3 2>/dev/null && rm -rdf ${PATH_SELECT_PART}
	done 10< <(lsblk --pairs --noheadings --paths --output PKNAME,PATH,PARTN,FSTYPE,PARTLABEL,LABEL ${DEVICE//,/ })
    else
        prompt -wq "Device %s not found!" "${DEVICE}"
    fi
}

detect_other_os(){
    # Найти файл grub.cfg определить какая возможно система и перенести в дочерний каталог конфигурацию
    local PATH_MOUNT_BOOT=$1
    # Если каталог grub находится в корне партиции, то скопировать его в /boot/
    if [[ -d ${PATH_MOUNT_BOOT}/grub ]]; then
	mkdir -p ${PATH_MOUNT_BOOT}/boot
	cp -af -t ${PATH_MOUNT_BOOT}/boot ${PATH_MOUNT_BOOT}/grub
#	rm -rdf ${PATH_MOUNT_BOOT}/grub
    fi
    local TYPE_OS=(astra rosa alt redos atlant archlinux manjaro debian ubuntu mint)
    if [[ -e ${PATH_MOUNT_BOOT}/boot/grub/grub.cfg ]]; then
	prompt "16%" "Finding a GRUB configuration file for another OS"
	local DETECT_OS_COPY=
	for SELECT_TYPE_OS in ${TYPE_OS[@]}; do
	    if grep -qi "${SELECT_TYPE_OS}" ${PATH_MOUNT_BOOT}/boot/grub/grub.cfg 2>/dev/null; then
		prompt "Detect '%s' OS and copy to /boot/grub/%s/grub.cfg" "${SELECT_TYPE_OS}" "${SELECT_TYPE_OS}"
		[[ -z ${ARG_TEST} ]] && install -Dm644 ${PATH_MOUNT_BOOT}/boot/grub/grub.cfg ${PATH_MOUNT_BOOT}/boot/grub/${SELECT_TYPE_OS}/grub.cfg
		DETECT_OS_COPY=yes
	    fi
	done
	if [[ ${DETECT_OS_COPY} != "yes" ]]; then
	    prompt "Detect '%s' OS and copy to /boot/grub/%s/grub.cfg" "other" "other"
	    [[ -z ${ARG_TEST} ]] && install -Dm644 ${PATH_MOUNT_BOOT}/boot/grub/grub.cfg ${PATH_MOUNT_BOOT}/boot/grub/other/grub.cfg
	fi
    else
	return 1
    fi
    true
}

autoconfig_only(){
    config_device(){
	if [[ -b ${ARG_DEVICE} ]]; then
		prompt "01%" "Unmounting parts"
	    drive_umount_allparts ${ARG_DEVICE} || return 1
		prompt "02%" "Search lebel parts"
	    find_media_data_part ${ARG_DEVICE}
		prompt "12%" "Mount file system"
	    drive_mount ${ARG_DEVICE} ${ARG_PART} || return 1
		prompt "91%" "Finishing install"
    	    post_install_config || return 1
		prompt "99%" "Unmounting parts"
    	    drive_umount_allparts ${ARG_DEVICE} || return 1
    		prompt "100%" "Configuration is complete!"
    		prompt "################################################################"
    		prompt "CONGRATULATIONS! EVERYTHING IS FINE!"
    		prompt -s "CONFIGURATION IS COMPLETE!"
	else
    	    prompt -wq "Device %s is not block!" "${ARG_DEVICE}"
	fi
    }
    # Метки получатся не упорядоченные
    #ARG_PART_LABEL=$(lsblk -no partlabel,path ${ARG_PART//,/ } | cut -d' ' -f1 | xargs | tr ' ' ',')
    #ARG_PART_FS_LABEL=$(lsblk -no label,path ${ARG_PART//,/ } | cut -d' ' -f1| xargs | tr ' ' ',')
    prompt "################################################################"
    prompt "STARTING CONFIGURATION"
    prompt "################################################################"
    if [[ ${ARG_INSTALL_TYPE} == "fast" ]]; then
	config_device
    elif [[ ${ARG_INSTALL_TYPE} == "next" ]]; then
	config_device
    elif [[ ${ARG_INSTALL_TYPE} == "part" ]]; then
	config_device
    elif [[ ${ARG_INSTALL_TYPE} == "grub_install" ]]; then
	config_device
    elif [[ ${ARG_INSTALL_TYPE} == "grub_update" ]]; then
	config_device
    elif [[ ${ARG_INSTALL_TYPE} == "system_only" ]]; then 
	config_device
    elif [[ ${ARG_INSTALL_TYPE} == "data_only" ]]; then
	config_device
    elif [[ ${ARG_INSTALL_TYPE} == "custom" ]]; then
	config_device
    fi
}

install_modules_extra_only(){
    config_device(){
	local DEVICE=$1
	if [[ -b ${DEVICE} ]]; then
		prompt "01%" "Unmounting parts"
	    drive_umount_allparts ${DEVICE} || return 1
		prompt "02%" "Search lebel parts"
	    find_media_data_part ${DEVICE}
		prompt "12%" "Mount file system"
	    drive_mount ${DEVICE} ${ARG_PART_LABEL} || return 1
		prompt "91%" "Finishing install"
    	    post_install_modules_extra || return 1
		prompt "99%" "Unmounting parts"
    	    drive_umount_allparts ${DEVICE} || return 1
    		prompt "100%" "Configuration is complete!"
    		prompt "################################################################"
    		prompt "CONGRATULATIONS! EVERYTHING IS FINE!"
    		prompt -s "CONFIGURATION IS COMPLETE!"
	else
    	    prompt -wq "Device %s is not block!" "${DEVICE}"
	fi
    }
    # Метки получатся не упорядоченные
    #ARG_PART_LABEL=$(lsblk -no partlabel,path ${ARG_PART//,/ } | cut -d' ' -f1 | xargs | tr ' ' ',')
    #ARG_PART_FS_LABEL=$(lsblk -no label,path ${ARG_PART//,/ } | cut -d' ' -f1| xargs | tr ' ' ',')
    prompt "################################################################"
    prompt "STARTING INSTALLATION EXTRA MODULES"
    prompt "################################################################"
    if [[ ${ARG_INSTALL_TYPE} == "fast" ]]; then
	config_device ${ARG_DEVICE}
    elif [[ ${ARG_INSTALL_TYPE} == "next" ]]; then
	config_device ${ARG_DEVICE}
    elif [[ ${ARG_INSTALL_TYPE} == "part" ]]; then
	config_device ${ARG_DEVICE}
    elif [[ ${ARG_INSTALL_TYPE} == "grub_install" ]]; then
	config_device ${ARG_DEVICE}
    elif [[ ${ARG_INSTALL_TYPE} == "grub_update" ]]; then
	config_device ${ARG_DEVICE}
    elif [[ ${ARG_INSTALL_TYPE} == "system_only" ]]; then 
	config_device ${ARG_DEVICE}
    elif [[ ${ARG_INSTALL_TYPE} == "data_only" ]]; then
	config_device ${ARG_DEVICE}
    elif [[ ${ARG_INSTALL_TYPE} == "custom" ]]; then
	config_device ${ARG_DEVICE}
    fi
}

install_fast(){
    # Выбираем только первое устройство из списка
    ARG_DEVICE="${ARG_DEVICE%%@(,|;|\|)*}"
    [[ -b ${ARG_DEVICE} ]] || ARG_DEVICE=$(find /dev/ -type b -iname "${ARG_DEVICE##*/}")
    ARG_PART="${ARG_PART%%@(,|;)*}"
    [[ -b ${ARG_PART} ]] || ARG_PART=$(find /dev/ -type b -iname "${ARG_PART##*/}")

    ARG_PART_LABEL="${ARG_PART_LABEL%%@(,|;|\|)*}"
    ARG_PART_FS_LABEL="${ARG_PART_FS_LABEL%%@(,|;|\|)*}"

    # Если тестируем, то метки получаем от устройства
    [[ -n ${ARG_TEST} ]] && get_media_data_label
    
    prompt "################################################################"
    prompt "STARTING INSTALLATION"
    show_conf_install
    prompt "################################################################"
    prompt "STARTING FAST INSTALLATION (%s)" "$(date)"
    if [[ -b ${ARG_DEVICE} ]]; then
	drive_info ${ARG_DEVICE} || return 1
	    prompt "02%" "Unmounting parts"
	drive_umount_allparts ${ARG_DEVICE} || return 1
	    prompt "02%" "Partition drive"
	install_fast_drive_partitioning ${ARG_DEVICE} "${ARG_PART_LABEL}" || return 1
	    prompt "09%" "Make file system"
	make_fs_efi ${ARG_DEVICE} || return 1
	make_fs "${ARG_PART}" "${ARG_PART_FS_TYPE}" "${ARG_PART_FS_LABEL}" || return 1
	make_fs_swap ${ARG_DEVICE} || return 1
	    prompt "12%" "Mount file system"
	drive_mount ${ARG_DEVICE} ${ARG_PART_FS_LABEL} || return 1
	    prompt "16%" "Install grub"
	install_grub "${ARG_DEVICE}" "x86_64-efi,i386-efi,i386-pc" || return 1
	    prompt "17%" "Install UEFI entry"
	install_uefi_menu ${ARG_DEVICE} || return 1
	    prompt "19%" "Creating skeleton"
	create_skeleton "media,data,boot" "${PATH_MOUNT_MEDIA}" "${PATH_MOUNT_BOOT}" "${PATH_MOUNT_DATA}" || return 1
	    prompt "20%" "Copying file system"
	copy_ublinux ${ARG_SOURCE} || return 1
	    prompt "90%" "Update signature"
	update_sign || return 1
	    prompt "91%" "Finishing install"
	post_install_general || return 1
	post_install_config || return 1
	post_install_modules_extra || return 1
	    prompt "99%" "Unmounting parts"
	drive_umount_allparts ${ARG_DEVICE} || return 1
	    prompt "99%" "Checking the disk for errors"
	check_part_after_install ${ARG_DEVICE} || return 1
	    prompt "100%" "Installation is complete!"
	    prompt "################################################################" 
	    prompt "CONGRATULATIONS! EVERYTHING IS FINE!"
	    prompt -s "FAST INSTALLATION IS COMPLETE!"
    else
	prompt -wq "Device %s is not block!" "${ARG_DEVICE}"
    fi
}

install_part(){
    # Выбираем только первое устройство из списка
    ARG_DEVICE="${ARG_DEVICE%%@(,|;|\|)*}"
    [[ -b ${ARG_DEVICE} ]] || ARG_DEVICE=$(find /dev/ -type b -iname "${ARG_DEVICE##*/}")
    ARG_PART="${ARG_PART%%@(,|;)*}"
    [[ -b ${ARG_PART} ]] || ARG_PART=$(find /dev/ -type b -iname "${ARG_PART##*/}")

    # Метки получатся не упорядоченные, переделать в цикле
    ARG_PART_LABEL=$(lsblk -no partlabel,path ${ARG_PART//,/ } | cut -d' ' -f1 | xargs | tr ' ' ',')
    ARG_PART_FS_LABEL=$(lsblk -no label,path ${ARG_PART//,/ } | cut -d' ' -f1| xargs | tr ' ' ',')

    prompt "################################################################"
    prompt "STARTING INSTALLATION"
    show_conf_install
    prompt "################################################################"
    prompt "STARTING INSTALLATION IN EXISTING PART (%s)" "$(date)"
    if [[ -b ${ARG_PART} ]]; then
	drive_info ${ARG_DEVICE} || return 1
	    prompt "01%" "Unmounting parts"
	drive_umount_allparts ${ARG_DEVICE} || return 1
	    prompt "02%" "Search MBR Windows partition and fix hibernation and remove old bootmgr"
	# Если ntfs и Win, то отключить у ntfs режим hibernation и удалить старый bootmgr
	fix_ntfs_windows_os ${ARG_DEVICE}
	    prompt "02%" "Unmounting parts"
	drive_umount_allparts ${ARG_DEVICE} || return 1
	    prompt "09%" "Make file system"
	#make_fs_efi ${ARG_DEVICE} || return 1
	[[ ${ARG_PART_FORMAT} == @(yes|y) ]] && { make_fs "${ARG_PART}" "${ARG_PART_FS_TYPE}" "${ARG_PART_FS_LABEL}" || return 1; }
	    prompt "12%" "Mount file system"
	drive_mount ${ARG_DEVICE} ${ARG_PART} || return 1
	    prompt "16%" "Install grub"
	detect_other_os ${PATH_MOUNT_BOOT}
	install_grub "${ARG_DEVICE}" "x86_64-efi,i386-efi,i386-pc" || return 1
	    prompt "17%" "Install UEFI entry"
	install_uefi_menu ${ARG_DEVICE} || return 1
	    prompt "19%" "Creating skeleton"
	create_skeleton "media,data,boot" "${PATH_MOUNT_MEDIA}" "${PATH_MOUNT_BOOT}" "${PATH_MOUNT_DATA}" || return 1
	    prompt "20%" "Copying file system"
	copy_ublinux ${ARG_SOURCE} || return 1
	    prompt "90%" "Update signature"
	update_sign || return 1
	    prompt "91%" "Finishing install"
	post_install_general || return 1
	post_install_config || return 1
	post_install_modules_extra || return 1
	    prompt "99%" "Unmounting parts"
        drive_umount_allparts ${ARG_DEVICE} || return 1
    	    prompt "99%" "Checking the disk for errors"
        check_part_after_install ${ARG_DEVICE} || return 1
    	    prompt "100%" "Installation is complete!"
    	    prompt "################################################################"
    	    prompt "CONGRATULATIONS! EVERYTHING IS FINE!"
    	    prompt -s "INSTALLATION IN EXISTING PART IS COMPLETE!"
    else
        prompt -wq "Device %s is not block!" "${ARG_PART}"
    fi
}

install_next_drive_resize(){
    local PART_SOURCE=$1
    local PART_NEW_SIZE=$2
    local PART_NEW_LABEL=$3
    findmnt ${PART_SOURCE} && return 1
    [[ -z ${ARG_TEST} ]] || return 0
    # т.к. не всегда возвращаются дданные от ядра, первый тестовый запрос
    sync; partprobe ${PART_SOURCE} 1>&3 2>&3
    sleep 2
    lsblk --paths --output PKNAME,PATH,PARTN,PTTYPE,START,LOG-SEC,PARTLABEL,FSTYPE,LABEL ${PART_SOURCE} 1>&3 2>&3
    PART_SOURCE_INFO=$(lsblk --pairs --noheadings --paths --output PKNAME,PATH,PARTN,PTTYPE,START,LOG-SEC,PARTLABEL,FSTYPE,LABEL ${PART_SOURCE})
    local PKNAME_LSBLK= PATH_LSBLK= PARTN_LSBLK= PTTYPE_LSBLK= START_LSBLK= LOGSEC_LSBLK= PARTLABEL_LSBLK= FSTYPE_LSBLK= LABEL_LSBLK=
    PART_SOURCE_INFO=${PART_SOURCE_INFO//=/_LSBLK=}
    PART_SOURCE_INFO=${PART_SOURCE_INFO//LOG-SEC/LOGSEC}
    PART_SOURCE_INFO=${PART_SOURCE_INFO//\" /\"; }
    eval ${PART_SOURCE_INFO}
    SELECT_PKNAME=${PKNAME_LSBLK}; SELECT_PATH=${PATH_LSBLK}; SELECT_PARTN=${PARTN_LSBLK}; SELECT_PTTYPE=${PTTYPE_LSBLK}; SELECT_START=${START_LSBLK}; SELECT_LOGSEC=${LOGSEC_LSBLK}; 
    SELECT_PARTLABEL=${PARTLABEL_LSBLK}; SELECT_FSTYPE=${FSTYPE_LSBLK}; SELECT_LABEL=${LABEL_LSBLK};

    prompt "03%" "Detect device '%s' on partition: '%s' ,  number: '%s' , partlabel: '%s' , fstype: '%s' , fslabel '%s'" "${SELECT_PKNAME}" "${SELECT_PATH}" "${SELECT_PARTN}" "${SELECT_PARTLABEL}" "${SELECT_FSTYPE}" "${SELECT_LABEL}"
    if [[ ${SELECT_FSTYPE,,} == @(ext2|ext3|ext4) ]]; then
	PART_SOURCE_SIZE_BYTE=$(blockdev --getsize64 ${SELECT_PATH})	# Исходный размер партиции в байтах
	PART_SOURCE_FS_SIZE_BYTE=$(dumpe2fs -h ${SELECT_PATH} |& awk -F: '/Block count/{count=$2} /Block size/{size=$2} END{print count*size}') # Исходный размер ФС в байтах
	PART_NEW_FS_SIZE_BYTE=$(numfmt --from=iec ${PART_NEW_SIZE:-0})	# Новый размер новой партиции в байтах
	PART_SOURCE_NEW_SIZE_BYTE=$((${PART_SOURCE_SIZE_BYTE}-${PART_NEW_FS_SIZE_BYTE})) # Новый размер старой партиции в байтах
	PART_SOURCE_FS_NEW_SIZE_BYTE=$((${PART_SOURCE_FS_SIZE_BYTE}-${PART_NEW_FS_SIZE_BYTE})) # Новый размер старой ФС в байтах

	PART_SOURCE_FS_BLOCK_SIZE=$(tune2fs -l ${SELECT_PATH} | grep "^Block size:" | tr -d ' ' | cut -d':' -f2)	# Размер блока ФС
	PART_SOURCE_FS_MINBLOCK_SIZE=$(resize2fs -P ${SELECT_PATH} | tr -d ' ' | cut -d: -f2)	# Минимально возможный размер ФС в блоках
	PART_SOURCE_FS_MIN_SIZE=$((${PART_SOURCE_FS_BLOCK_SIZE}*${PART_SOURCE_FS_MINBLOCK_SIZE})) # Минимально возможный размер ФС в байтах
	PART_SOURCE_END_SECTOR=$((${PART_SOURCE_NEW_SIZE_BYTE}/${SELECT_LOGSEC}+${SELECT_START}+6)) # Последний сектор старой партиции в байтах
	
	[[ ${PART_SOURCE_FS_MIN_SIZE} -gt ${PART_SOURCE_FS_NEW_SIZE_BYTE} ]] \
	&& prompt -eq "04%" "The new size '%s' of the file system '%s' of the '%s' partition is less than the allowable size '%s'" "$(numfmt --to=iec --format "%.4f" ${PART_SOURCE_FS_NEW_SIZE_BYTE:-0})" "${SELECT_FSTYPE}" "${SELECT_PATH}" "$(numfmt --to=iec --format "%.4f" ${PART_SOURCE_FS_MIN_SIZE:-0})"
	    prompt "04%" "Checking the disk '%s' for errors" "${SELECT_PATH}"
	e2fsck -f -y -v -C 0 ${SELECT_PATH} 1>&3 2>&3 || return 1	# Проверить на ошибки
	    prompt "05%" "Resize filesystem '%s' to '%s'" "${SELECT_PATH}" "$(numfmt --to=iec --format "%.4f" ${PART_SOURCE_NEW_SIZE_BYTE:-0})"
	resize2fs -p ${SELECT_PATH} "$((${PART_SOURCE_FS_NEW_SIZE_BYTE}/${PART_SOURCE_FS_BLOCK_SIZE}))" 1>&3 2>&3 || return 1	# Уменьшить размер до указанных байт
	#resize2fs ${SELECT_PATH} -M	# Уменьшить размер до минимально возможных байт
	#RESIZEMIN_PART_SOURCE_FS_SIZE_BYTE=$(dumpe2fs -h ${PART_SOURCE} |& awk -F: '/Block count/{count=$2} /Block size/{size=$2} END{print count*size}') # Получить размер уменьшенной файловой системы
	    #prompt "06%" "Modify number '%s' partition '%s'" "${SELECT_PARTN}" "${SELECT_PKNAME}"
	#sgdisk -d ${SELECT_PARTN} ${SELECT_PKNAME}
	    prompt "07%" "Modify number '%s' partition '%s' to '%s' size and '%s' part label " "${SELECT_PARTN}" "${SELECT_PKNAME}" "$(numfmt --to=iec --format "%.4f" ${PART_SOURCE_FS_NEW_SIZE_BYTE:-0})" "${SELECT_PARTLABEL}"
	printf "Yes\n" | parted ---pretend-input-tty --align optimal --fix ${SELECT_PKNAME} unit s resizepart ${SELECT_PARTN} ${PART_SOURCE_END_SECTOR} 1>&3 2>&3 || return 1
	#sgdisk -a=2048 -n ${SELECT_PARTN}:0:+"$((${PART_SOURCE_NEW_SIZE_BYTE}/512+6))s" -c 0:${SELECT_PARTLABEL} -t 0:8300 ${SELECT_PKNAME}
	#sgdisk -a=2048 -n ${SELECT_PARTN}:0:-"$(numfmt --to=iec --format "%.2f" ${PART_NEW_FS_SIZE_BYTE:-0})" -c 0:${SELECT_PARTLABEL} -t 0:8300 ${SELECT_PKNAME}
	    prompt "07%" "Expand file system '%s'" "${SELECT_PATH}"
	resize2fs -p ${SELECT_PATH} 1>&3 2>&3 || return 1
	    prompt "08%" "Create new partition on drive '%s' with new label '%s'" "${SELECT_PKNAME}" "${PART_NEW_LABEL}"
	#sgdisk -a=2048 -n 0:0:0 -c 0:${PART_NEW_LABEL} -t 0:8300 ${SELECT_PKNAME}
	sgdisk -a=2048 -n 0:$((${PART_SOURCE_END_SECTOR}+1)):0 -c 0:${PART_NEW_LABEL} -t 0:8300 ${SELECT_PKNAME} 1>&3 2>&3 || return 1
	sync; partprobe ${SELECT_PKNAME} 1>&3 2>&3
	sleep 2
	lsblk --list --paths --output PATH,PARTLABEL,LABEL ${SELECT_PKNAME} 1>&3 2>&3
	ARG_PART="$(lsblk --list --noheadings --paths --output PATH,PARTLABEL,LABEL ${SELECT_PKNAME} | grep ${PART_NEW_LABEL} | cut -d' ' -f1 | tail -1)"
	    prompt "08%" "1 Checking the disk for errors: '%s'" "${PART_SOURCE}"
	e2fsck -f -y -v -C 0 ${PART_SOURCE}
    elif [[ ${SELECT_FSTYPE,,} == @(vfat|fat) ]]; then
	true
    elif [[ ${SELECT_FSTYPE,,} == ntfs ]]; then
	    prompt "04%" "Checking the disk '%s' for errors" "${SELECT_PATH}"
	    prompt "05%" "Resize filesystem '%s' to '%s'" "${SELECT_PATH}" "${PART_NEW_SIZE}"
	PART_NEW_FS_SIZE_BYTE="$(numfmt --from=iec ${PART_NEW_SIZE:-0})"	# Новый размер новой партиции в байтах
	ntfsresize -i -f -v ${SELECT_PATH} 1>&3 2>&3 || return 1
	PART_SOURCE_FS_INFO="$(ntfsresize -i -f -v ${SELECT_PATH})"
	[[ ${PART_SOURCE_FS_INFO} =~ (^|$'\n')"Current volume size"[[:blank:]]*':'[[:blank:]]*([[:digit:]]*)" bytes" ]] && PART_SOURCE_FS_CURRENT_SIZE=${BASH_REMATCH[2]} # Текущий размер ФС в байтах
	[[ ${PART_SOURCE_FS_INFO} =~ (^|$'\n')"You might resize at "([[:digit:]]*)" bytes" ]] && PART_SOURCE_FS_MIN_SIZE=${BASH_REMATCH[2]} # Минимально возможный размер ФС в байтах
	PART_SOURCE_FS_NEW_SIZE_BYTE=$((${PART_SOURCE_FS_CURRENT_SIZE}-${PART_NEW_FS_SIZE_BYTE})) # Новый размер старой ФС в байтах, расчётный
	# Расчёт фактического, выравненного размера файловой системы
	PART_SOURCE_FS_CALC=$(ntfsresize --force --force --size ${PART_SOURCE_FS_NEW_SIZE_BYTE} --no-action ${SELECT_PATH})
	[[ ${PART_SOURCE_FS_CALC} =~ (^|$'\n')"New volume size"[[:blank:]]*':'[[:blank:]]*([[:digit:]]+)" bytes" ]] && PART_SOURCE_FS_NEW_SIZE_BYTE=${BASH_REMATCH[2]} # Новый фактический размер ФС
	[[ ${PART_SOURCE_FS_NEW_SIZE_BYTE} -gt ${PART_SOURCE_FS_MIN_SIZE} ]] \
	  || prompt -eq "04%" "The new size '%s' of the file system '%s' of the '%s' partition is less than the allowable size '%s'" "$(numfmt --to=iec --format "%.4f" ${PART_SOURCE_FS_NEW_SIZE_BYTE:-0})" "${SELECT_FSTYPE}" "${SELECT_PATH}" "$(numfmt --to=iec --format "%.4f" ${PART_SOURCE_FS_MIN_SIZE:-0})"
	PART_SOURCE_END_SECTOR=$((${PART_SOURCE_FS_NEW_SIZE_BYTE}/${SELECT_LOGSEC}+${SELECT_START}+8)) 
	    prompt "05%" "Resize filesystem '%s' to '%s'" "${SELECT_PATH}" "$(numfmt --to=iec --format "%.4f" ${PART_SOURCE_FS_NEW_SIZE_BYTE:-0})"
	ntfsresize --force --force --size ${PART_SOURCE_FS_NEW_SIZE_BYTE} ${SELECT_PATH}  1>&3 2>&3 || return 1
	    prompt "05%" "Resize partition '%s' to '%s'" "${SELECT_PATH}" "$(numfmt --to=iec --format "%.4f" ${PART_SOURCE_END_SECTOR:-0})"
	printf "Yes\n" | parted ---pretend-input-tty --align optimal --fix ${SELECT_PKNAME} unit s resizepart ${SELECT_PARTN} ${PART_SOURCE_END_SECTOR} 1>&3 2>&3 || return 1
	#PART_SOURCE_SIZE_BYTE=$(blockdev --getsize64 ${SELECT_PATH})	# Исходный размер партиции в байтах
	#PART_SOURCE_FS_SIZE_BYTE=$(ntfsinfo --mft ${SELECT_PATH} | awk -F: '/Volume Size in Clusters/{count=$2} /Cluster Size/{size=$2} END{print count*size}') # Исходный размер ФС в байтах
	#PART_NEW_FS_SIZE_BYTE="$(numfmt --from=iec ${PART_NEW_SIZE:-0})"	# Новый размер новой партиции в байтах
	#PART_SOURCE_NEW_SIZE_BYTE=$((${PART_SOURCE_SIZE_BYTE}-${PART_NEW_FS_SIZE_BYTE})) # Новый размер старой партиции в байтах
	#PART_SOURCE_FS_NEW_SIZE_BYTE=$((${PART_SOURCE_FS_SIZE_BYTE}-${PART_NEW_FS_SIZE_BYTE})) # Новый размер старой ФС в байтах
	#[[ $(ntfsresize --info ${SELECT_PATH} | grep "^You might resize at ") =~ ^"You might resize at "([[:digit:]]*)" bytes".* ]] && PART_SOURCE_FS_MIN_SIZE=${BASH_REMATCH[1]} # Минимально возможный размер ФС в байтах
	#[[ ${PART_SOURCE_FS_MIN_SIZE} -gt ${PART_SOURCE_FS_NEW_SIZE_BYTE} ]] \
	#&& prompt -eq "04%" "The new size '%s' of the file system '%s' of the '%s' partition is less than the allowable size '%s'" "$(numfmt --to=iec --format "%.4f" ${PART_SOURCE_FS_NEW_SIZE_BYTE:-0})" "${SELECT_FSTYPE}" "${SELECT_PATH}" "$(numfmt --to=iec --format "%.4f" ${PART_SOURCE_FS_MIN_SIZE:-0})"
	#ntfsresize -i -f -v ${SELECT_PATH}
	#ntfsresize --force --force --no-action ${SELECT_PATH}
	#ntfsresize --force --force ${SELECT_PATH}
#	    prompt "05%" "Resize filesystem '%s' to '%s'" "${SELECT_PATH}" "$(numfmt --to=iec --format "%.4f" ${PART_SOURCE_NEW_SIZE_BYTE:-0})"
	#ntfsresize --force --force --size ${PART_SOURCE_FS_NEW_SIZE_BYTE} --no-action ${SELECT_PATH}
	#ntfsresize --force --force --size ${PART_SOURCE_FS_NEW_SIZE_BYTE} ${SELECT_PATH}
	#ntfsresize --info --force ${SELECT_PATH}
#	    prompt "06%" "Modify number '%s' partition '%s'" "${SELECT_PARTN}" "${SELECT_PKNAME}"
	#sgdisk -d ${SELECT_PARTN} ${SELECT_PKNAME}
#	    prompt "07%" "Modify number '%s' partition '%s' to '%s' size and '%s' part label " "${SELECT_PARTN}" "${SELECT_PKNAME}" "$(numfmt --to=iec --format "%.4f" ${PART_SOURCE_FS_NEW_SIZE_BYTE:-0})" "${SELECT_PARTLABEL}"
	#sgdisk -a=2048 -n ${SELECT_PARTN}:0:+"$((${PART_SOURCE_NEW_SIZE_BYTE}/512))s" -c 0:"${SELECT_PARTLABEL}" -t 0:8300 ${SELECT_PKNAME}
	#sgdisk -a=2048 -n ${SELECT_PARTN}:0:-"$(numfmt --to=iec --format "%.2f" ${PART_NEW_FS_SIZE_BYTE:-0})" -c 0:${SELECT_PARTLABEL} -t 0:8300 ${SELECT_PKNAME}
#	    prompt "07%" "Expand file system '%s'" "${SELECT_PATH}"
	#ntfsresize --force --verbose ${SELECT_PATH}
	#ntfsresize --info --force ${SELECT_PATH}
	#ntfsresize --check ${SELECT_PATH}
	#prompt "08%" "Set msftdata atribute partition: '%s' on drive: %s" "${SELECT_PARTN}" "${SELECT_PKNAME}"
	#[[ -z ${ARG_TEST} ]] && parted --fix ${SELECT_PKNAME} set ${SELECT_PARTN} msftdata on 1>&3 2>&3	# set msftdata flag
	    prompt "08%" "Create new partition on drive '%s' with new label '%s'" "${SELECT_PKNAME}" "${PART_NEW_LABEL}"
	sync; partprobe ${SELECT_PKNAME} 1>&3 2>&3
	sleep 2
	echo 3 > /proc/sys/vm/drop_caches
	sleep 1
        if [[ ${SELECT_PTTYPE} == "gpt" ]]; then
	    sgdisk -a=2048 -n 0:$((${PART_SOURCE_END_SECTOR}+1)):0 -c 0:${PART_NEW_LABEL} -t 0:8300 ${SELECT_PKNAME} 1>&3 2>&3 || return 1
	    partprobe ${SELECT_PKNAME} 1>&3 2>&3
	    sleep 2
	    lsblk --list --paths --output PATH,PARTLABEL ${SELECT_PKNAME} 1>&3 2>&3
	    ARG_PART="$(lsblk --list --noheadings --paths --output PATH,PARTLABEL ${SELECT_PKNAME} | grep ${PART_NEW_LABEL} | cut -d' ' -f1 | tail -1)"
	elif [[ ${SELECT_PTTYPE} == "dos" ]]; then
	    # Проверяем наличие раздела "BIOS Boot" EF02
	    # gdisk -l /dev/nvme0n1 | grep "EF02"
	    # Создаём Extended раздел
	    printf "n\n e\n \n \n \n w\n" | fdisk ${SELECT_PKNAME} 1>&3 2>&3
	    sleep 4
	    partprobe ${SELECT_PKNAME} 1>&3 2>&3
	    sleep 4
	    lsblk --paths --output PARTTYPENAME ${SELECT_PKNAME} 1>&3 2>&3
	    if ! lsblk --noheadings --paths --output PARTTYPENAME ${SELECT_PKNAME} | grep -qi "bios boot"; then
		printf "n\n \n +2M\n  t\n \n 04\n  a\n \n w\n" | fdisk ${SELECT_PKNAME} 1>&3 2>&3
		# Создаём boot раздел
		#printf "n\n \n +2M\n w\n" | fdisk ${SELECT_PKNAME} 1>&3 2>&3
		#sleep 1
		#partprobe ${SELECT_PKNAME} 1>&3 2>&3
		#sleep 1
		# Устанавливаем тип 04 для применения в установке grub 
		#printf "t\n \n 04\n w\n" | fdisk ${SELECT_PKNAME} 1>&3 2>&3
		#sleep 1
		#partprobe ${SELECT_PKNAME} 1>&3 2>&3
		#sleep 1
		# Устанавливаем boot аттрибут
		#printf "a\n \n w\n" | fdisk ${SELECT_PKNAME} 1>&3 2>&3
		sleep 4
		partprobe ${SELECT_PKNAME} 1>&3 2>&3
		sleep 4
	    fi
	    # Создаём раздел для данных
	    local PART_NEW_PARTN_TXT=$(printf "n\n \n \n w\n" | LC_ALL=C fdisk ${SELECT_PKNAME})
	    echo "${PART_NEW_PARTN_TXT}" 1>&3 2>&3
	    [[ ${PART_NEW_PARTN_TXT} =~ "Created a new partition "([[:digit:]]*)" of type" ]] && PART_NEW_PARTN=${BASH_REMATCH[1]}
	    partprobe ${SELECT_PKNAME} 1>&3 2>&3
	    sleep 4
	    lsblk --list --paths --output PATH,PARTN ${SELECT_PKNAME} 1>&3 2>&3
	    ARG_PART="$(lsblk --list --noheadings --paths --output PATH,PARTN ${SELECT_PKNAME} | grep ${PART_NEW_PARTN} | cut -d' ' -f1 | tail -1)"
	    DETECT_MBR_WINDOWS=yes
	fi
	ntfsfix ${SELECT_PATH} 1>&3 2>&3 || return 1
	[[ ${ARG_PART} != ${SELECT_PATH} && -b ${ARG_PART} ]] || return 1
	    prompt "08%" "2 Checking the disk for errors: '%s'" "${PART_SOURCE}"
        # Пример получения блока и размеров
        ## start=$(cat /sys/block/mmcblk0/mmcblk0p3/start)
	## end=$(($start+$(cat /sys/block/mmcblk0/mmcblk0p3/size)))
	## newend=$(($(cat /sys/block/mmcblk0/size)-8))
	## if [ "$newend" -gt "$end" ]; then
	##     parted -s /dev/mmcblk0 unit s resize 3 $start $newend
	## fi
    elif [[ ${SELECT_FSTYPE,,} == btrfs ]]; then
	true
    elif [[ ${SELECT_FSTYPE,,} == xfs ]]; then
	true
    elif [[ ${SELECT_FSTYPE,,} == zfs ]]; then
	true
    elif [[ ${SELECT_FSTYPE,,} == ufs ]]; then
	true
    else
	 prompt -eq "Type file system not detected!"
    fi
    prompt "New partition: %s" "${ARG_PART}"
    [[ -n ${ARG_PART} ]] || return 1
    partprobe ${SELECT_PKNAME} 1>&3 2>&3
    sleep 1
    sync; sleep 1
    echo 3 > /proc/sys/vm/drop_caches
    [[ ${ARG_PART} == ${PART_SOURCE} ]] && prompt -eq "New partition not created!"
    sleep 0.5
#    echo "Move data from right" 1>&3
#    echo -e "04 Prepare disk for install: move data in end"
#    [[ -z ${ARG_TEST} ]] && e2image -ra -p -O $2 "/dev/${part_name}"
}

install_next(){
    # Выбираем только первое устройство из списка
    ARG_DEVICE="${ARG_DEVICE%%@(,|;|\|)*}"
    [[ -b ${ARG_DEVICE} ]] || ARG_DEVICE=$(find /dev/ -type b -iname "${ARG_DEVICE##*/}")
    ARG_PART="${ARG_PART%%@(,|;)*}"
    [[ -b ${ARG_PART} ]] || ARG_PART=$(find /dev/ -type b -iname "${ARG_PART##*/}")
    ARG_PART_SOURCE=${ARG_PART}
    
    ARG_PART_LABEL="${ARG_PART_LABEL%%@(,|;|\|)*}"
    ARG_PART_FS_LABEL="${ARG_PART_FS_LABEL%%@(,|;|\|)*}"
    ARG_PART_SIZE="${ARG_PART_SIZE%%@(,|;|\|)*}"
    
    prompt "################################################################"
    prompt "STARTING INSTALLATION"
    show_conf_install
    prompt "################################################################"
    prompt "STARTING NEXT INSTALLATION (%s)" "$(date)"
    if [[ -b ${ARG_DEVICE} ]]; then
	drive_info ${ARG_DEVICE} || return 1
	    prompt "02%" "Unmounting parts"
	drive_umount_allparts ${ARG_DEVICE} || return 1
	    prompt "02%" "Search MBR Windows partition and fix hibernation and remove old bootmgr"
	# Если ntfs и Win, то отключить у ntfs режим hibernation и удалить старый bootmgr
	fix_ntfs_windows_os ${ARG_DEVICE}
	    prompt "02%" "Unmounting parts"
	drive_umount_allparts ${ARG_DEVICE} || return 1
	    prompt "02%" "Partition drive"
	# Уменьшить сущестующий раздел
	install_next_drive_resize ${ARG_PART} ${ARG_PART_SIZE} "${ARG_PART_LABEL}" || return 1
	[[ ${ARG_PART} == ${ARG_PART_SOURCE} ]] && prompt -eq "New partition not created!"
	    prompt "09%" "Make file system"
	#make_fs_efi ${ARG_DEVICE} || return 1
	make_fs "${ARG_PART}" "${ARG_PART_FS_TYPE}" "${ARG_PART_FS_LABEL}" || return 1
	    prompt "12%" "Mount file system"
	drive_mount ${ARG_DEVICE} ${ARG_PART_FS_LABEL} || return 1
	    prompt "16%" "Install grub"
	detect_other_os ${PATH_MOUNT_BOOT}
	install_grub "${ARG_DEVICE}" "x86_64-efi,i386-efi,i386-pc" || return 1
	    prompt "17%" "Install UEFI entry"
	install_uefi_menu ${ARG_DEVICE} || return 1
	    prompt "19%" "Creating skeleton"
	create_skeleton "media,data,boot" "${PATH_MOUNT_MEDIA}" "${PATH_MOUNT_BOOT}" "${PATH_MOUNT_DATA}" || return 1
	    prompt "20%" "Copying file system"
	copy_ublinux ${ARG_SOURCE} || return 1
	    prompt "90%" "Update signature"
	update_sign || return 1
	    prompt "93%" "Finishing install"
	post_install_general || return 1
	post_install_config || return 1
	post_install_modules_extra || return 1
	    prompt "99%" "Unmounting parts"
	drive_umount_allparts ${ARG_DEVICE} || return 1
	    prompt "99%" "Checking the disk for errors"
	check_part_after_install ${ARG_DEVICE} || return 1
	    prompt "100%" "Installation is complete!"
	    prompt "################################################################" 
	    prompt "CONGRATULATIONS! EVERYTHING IS FINE!"
	    prompt -s "NEXT INSTALLATION IS COMPLETE!"
    else
	prompt -wq "Device %s is not block!" "${ARG_DEVICE}"
    fi
}

install_only_grub(){
    # Выбираем только первое устройство из списка
    ARG_DEVICE="${ARG_DEVICE%%@(,|;|\|)*}"
    [[ -b ${ARG_DEVICE} ]] || ARG_DEVICE=$(find /dev/ -type b -iname "${ARG_DEVICE##*/}")
    ARG_PART="${ARG_PART%%@(,|;)*}"
    [[ -b ${ARG_PART} ]] || ARG_PART=$(find /dev/ -type b -iname "${ARG_PART##*/}")

    prompt "################################################################"
    prompt "STARTING INSTALLATION"
    show_conf_install
    prompt "################################################################"
    prompt "STARTING GRUB INSTALLATION (%s)" "$(date)"
    if [[ -b ${ARG_DEVICE} ]]; then
	drive_info ${ARG_DEVICE} || return 1
	    prompt "02%" "Unmounting parts"
	drive_umount_allparts ${ARG_DEVICE} || return 1
	    prompt "12%" "Mount file system"

	drive_mount ${ARG_DEVICE} ${ARG_PART} || return 1
	    prompt "16%" "Install grub"
	detect_other_os ${PATH_MOUNT_BOOT}
	install_grub "${ARG_DEVICE}" "x86_64-efi,i386-efi,i386-pc" || return 1
	    prompt "17%" "Install UEFI entry"
	install_uefi_menu ${ARG_DEVICE} || return 1
	    prompt "19%" "Creating skeleton"
	create_skeleton "boot" "${PATH_MOUNT_MEDIA}" "${PATH_MOUNT_BOOT}" || return 1
	    prompt "99%" "Unmounting parts"
	drive_umount_allparts ${ARG_DEVICE} || return 1
	    prompt "99%" "Checking the disk for errors"
	check_part_after_install ${ARG_DEVICE} || return 1
	    prompt "100%" "Installation is complete!"
	    prompt "################################################################" 
	    prompt "CONGRATULATIONS! EVERYTHING IS FINE!"
	    prompt -s "GRUB INSTALLATION IS COMPLETE!"
    else
	prompt -wq "Device %s is not block!" "${ARG_DEVICE}"
    fi
}

update_only_grub(){
    echo -e "################################################################" 1>&3
    echo -e "#### $(i18n "STARTING UPDATE GRUB CONFIGURATION %s" "$(date)") ####" 1>&3
    echo -e "05|$(i18n "Configure grub")" >&5
    echo -e "19|$(i18n "Copying file system")" >&5
    echo -e "90|$(i18n "Finishing install")" >&5
    echo -e "1.00|$(i18n "Installation is complete!")" >&5
    echo -e "################################################################" 1>&3
    echo -e "#### $(i18n "CONGRATULATIONS! EVERYTHING IS FINE!") ####" 1>&3
    echo -e "#### $(i18n "UPDATE GRUB CONFIGURATION IS COMPLETE!") ####" 1>&3
}

install_media_only(){
    echo -e "################################################################" 1>&3
    echo -e "#### $(i18n "STARTING OS ONLY INSTALLATION  %s" "$(date)") ####" 1>&3
    echo -e "01|$(i18n "Start installation")" >&5
    echo -e "1.00|$(i18n "Installation is complete!")" >&5
    echo -e "################################################################" 1>&3
    echo -e "#### $(i18n "CONGRATULATIONS! EVERYTHING IS FINE!") ####" 1>&3
    echo -e "#### $(i18n "OS ONLY INSTALLATION IS COMPLETE!") ####" 1>&3
}


install_data_only(){
    echo -e "################################################################" 1>&3
    echo -e "#### $(i18n "STARTING USER ONLY INSTALLATION  %s" "$(date)") ####" 1>&3
    echo -e "01|$(i18n "Start installation")" >&5
    echo -e "1.00|$(i18n "Installation is complete!")" >&5
    echo -e "################################################################" 1>&3
    echo -e "#### $(i18n "CONGRATULATIONS! EVERYTHING IS FINE!") ####" 1>&3
    echo -e "#### $(i18n "USER ONLY INSTALLATION IS COMPLETE!") ####" 1>&3
}

install_custom(){
    echo -e "################################################################" 1>&3
    echo -e "#### $(i18n "STARTING HYBRID INSTALLATION  %s" "$(date)") ####" 1>&3
    echo -e "01|$(i18n "Start installation")" >&5
    echo -e "1.00|$(i18n "Installation is complete!")" >&5
    echo -e "################################################################" 1>&3
    echo -e "#### $(i18n "CONGRATULATIONS! EVERYTHING IS FINE!") ####" 1>&3
    echo -e "#### $(i18n "HYBRID INSTALLATION IS COMPLETE!") ####" 1>&3
}


    ##########################
  ########   MAIN   ########
##########################

    PKGNAME=${0##*/}
    PATH_WORK=${PWD}

    # Define exit codes
    ERR_C=-1	# Error code
    OK_C=0 	# OK button is pressed
    CANCEL_C=1 	# Cancel button is pressed
    HELP_C=2	# Help code
    EXTRA_C=3 	# Extra button is pressed
    ESC_C=255 	# ESC button is pressed

    declare -A AUTOINSTALL
    unset ROOTFS; [[ -d /usr/lib/ublinux ]] || ROOTFS=.
    SOURCE=${ROOTFS}/usr/lib/ublinux/default; [[ -f ${SOURCE} ]] && . ${SOURCE} #2>/dev/null
    [[ -n ${SYSCONF} ]] || SYSCONF="/etc/ublinux"
    SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null


    [[ -n ${NOCOLOR} ]] || set_color
    
    export TEXTDOMAIN=${PKGNAME}
    export TEXTDOMAINDIR="${ROOTFS}/usr/share/locale"

    REQUEST_ARGS=()
    arguments "$@"
    set -- "${REQUEST_ARGS[@]}"

    FILE_UBINSTALL_TMP="/tmp/ubinstall"
    [[ -d ${FILE_UBINSTALL_TMP} ]] || install -d ${FILE_UBINSTALL_TMP}
    FILE_UBINSTALL_LOG="${ROOTFS}/var/log/ubinstall.log"
    FILE_UBINSTALL_PROGRESS="${ROOTFS}/var/log/ubinstall_progress.log"
    true > ${FILE_UBINSTALL_LOG}
    true > ${FILE_UBINSTALL_PROGRESS}
    PATH_UBBOOT_LIB="${ROOTFS}/usr/lib/ubboot"
    PATH_UBBOOT_TEMPLATE="${ROOTFS}/usr/share/ubboot"

    if has_command "mkpasswd"; then
	CMD_PASSWD="mkpasswd -m gost-yescrypt"
    elif has_command "mkpasswd2"; then
	CMD_PASSWD="mkpasswd2 -m gost-yescrypt"
    elif has_command "openssl"; then
	CMD_PASSWD="openssl passwd -6"
    fi

    [[ -f ${FILE_UBINSTALL_LOG} ]] || ARG_LOG="no"
    [[ -n ${QUIET} ]] && STDOUT_NULL="/dev/null"  || STDOUT_NULL="/dev/stdout"

    # ARG_LOG=yes	# Включить вывод в лог файл
    # ARG_LOG=save	# Включить вывод в лог файл который после устновки будет сохранён в установленной системе
    # ARG_DEBUG=yes 	# Включает в вывод STDERR
    # STDOUT> STDERR> в консоль и файл лога, 5> в файл прогресса
    [[ ${ARG_LOG} == @("yes"|"save") ]] && [[ -n ${ARG_DEBUG} ]] && exec 5>${FILE_UBINSTALL_PROGRESS} 1>${STDOUT_NULL} &> >(tee -i >(sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' > ${FILE_UBINSTALL_LOG})) 3>&1
    # STDOUT> в консоль и файл лога, STDERR> /dev/null , 5> в файл прогресса
    [[ ${ARG_LOG} == @("yes"|"save") ]] && [[ -z ${ARG_DEBUG} ]] && exec 5>${FILE_UBINSTALL_PROGRESS} 1>${STDOUT_NULL} 2>/dev/null 1> >(tee -i >(sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g' > ${FILE_UBINSTALL_LOG})) 3>&1
    # STDOUT> STDERR> в консоль, 5> в файл прогресса
    [[ ${ARG_LOG} == @(""|"no") ]]      && [[ -n ${ARG_DEBUG} ]] && exec 5>${FILE_UBINSTALL_PROGRESS} 1>${STDOUT_NULL} 3>&1 
    # STDOUT> в консоль, STDERR> /dev/null , 5> в файл прогресса
    [[ ${ARG_LOG} == @(""|"no") ]]      && [[ -z ${ARG_DEBUG} ]] && exec 5>${FILE_UBINSTALL_PROGRESS} 1>${STDOUT_NULL} 2>/dev/null

### EXCUTE
    [[ -n ${arg_get_list_block} ]] && get_all_block_device && exit 0
    check_root -wq

    DEVICE_MOUNT_EFI=;   PATH_MOUNT_EFI=
    DEVICE_MOUNT_MEDIA=; PATH_MOUNT_MEDIA=
    DEVICE_MOUNT_DATA=;  PATH_MOUNT_DATA=
    DEVICE_MOUNT_BOOT=;  PATH_MOUNT_BOOT=
    
    DETECT_MBR_WINDOWS=
    
    if [[ -n ${ARG_AUTOCONFIG} ]]; then
	autoconfig_only || prompt -eq "SOMETHING WENT WRONG!\n#### CONFIGURATION IS NOT COMPLETE! ####"
    elif [[ -n ${ARG_INSTALL_MODULES_EXTRA} ]]; then
	install_modules_extra_only || prompt -eq "SOMETHING WENT WRONG!\n#### CONFIGURATION IS NOT COMPLETE! ####"
    else
	if [[ ${ARG_INSTALL_TYPE} == "fast" ]]; then
	    install_fast || prompt -eq "SOMETHING WENT WRONG!\n#### INSTALLATION IS NOT COMPLETE! ####"
	elif [[ ${ARG_INSTALL_TYPE} == "next" ]]; then
	    install_next || prompt -eq "SOMETHING WENT WRONG!\n#### INSTALLATION IS NOT COMPLETE! ####"
	elif [[ ${ARG_INSTALL_TYPE} == "part" ]]; then
	    install_part || prompt -eq "SOMETHING WENT WRONG!\n#### INSTALLATION IS NOT COMPLETE! ####"
	elif [[ ${ARG_INSTALL_TYPE} == "grub_install" ]]; then
	    install_only_grub || prompt -eq "SOMETHING WENT WRONG!\n#### INSTALL GRUB IS NOT COMPLETE! ####"
	elif [[ ${ARG_INSTALL_TYPE} == "grub_update" ]]; then
	    update_only_grub || prompt -eq "SOMETHING WENT WRONG!\n#### UPDATE GRUB CONFIGURATION IS NOT COMPLETE! ####"
	elif [[ ${ARG_INSTALL_TYPE} == "system_only" ]]; then
	    install_media_only || prompt -eq "SOMETHING WENT WRONG!\n#### INSTALLATION IS NOT COMPLETE! ####"
	elif [[ ${ARG_INSTALL_TYPE} == "data_only" ]]; then
	    install_data_only || prompt -eq "SOMETHING WENT WRONG!\n#### INSTALLATION IS NOT COMPLETE! ####"
	elif [[ ${ARG_INSTALL_TYPE} == "custom" ]]; then
	    install_custom || prompt -eq "SOMETHING WENT WRONG!\n#### INSTALLATION IS NOT COMPLETE! ####"
	else
	    true
	fi
    fi
