"use strict";

if (typeof window.workers !== "function") {
  // Not initialized

  // Initialize of the class in global namespace
  window.workers = class workers {
    /**
     * Заблокировать функцию закрытия всплывающего окна?
     */
    static freeze = false;

    /**
     * Тело всплывающего окна (массив)
     */
    static body = {};

    /**
     * Инициализирован класс?
     */
    static initialized = false;

    /**
     * Управление кнопками (escape, enter...)
     *
     * Содержит функцию инициализирующую обработчики событий keydown для document
     * функция деинициализируется с document при закрытии окна
     */
    static buttons;

    /**
     * Ожидание зависимости: ядро
     *
     * @param {function} execute Функция, которая будет встроена в демпфер
     * @param {mixed} args Аргументы встраиваемой функции
     *
     * @return {void}
     */
    static core(execute, ...args) {
      if (typeof execute === "function") {
        // Получена функция

        // Инициализация интервала для ожидания загрузки зависимостей
        const interval = setInterval(() => {
          if (typeof core === "function") {
            // Инициализировано ядро

            // Деинициализация интервала для ожидания загрузки зависимостей
            clearInterval(interval);

            // Запуск выполнения
            return execute(...args);
          }
        }, 100);

        // Инициализация деинициализации интервала для ожидания загрузки зависимостей спустя большой срок времени
        setTimeout(() => clearInterval(interval), 3000);
      }
    }

    /**
     * Ожидание зависимости: демпфер
     *
     * @param {function} execute Функция, которая будет встроена в демпфер
     * @param {number} timer Количество миллисекунд для демпфера
     * @param {mixed} args Аргументы встраиваемой функции
     *
     * @return {void}
     */
    static damper(execute, timer = 3000, ...args) {
      if (typeof execute === "function") {
        // Получена функция

        // Инициализация интервала для ожидания загрузки зависимостей
        const interval = setInterval(() => {
          if (typeof damper === "function") {
            // Инициализирован демпфер

            // Деинициализация интервала для ожидания загрузки записимостей
            clearInterval(interval);

            // Запуск выполнения
            return damper(() => execute(...args), timer);
          }
        }, 100);

        // Инициализация деинициализации интервала для ожидания загрузки зависимостей спустя большой срок времени
        setTimeout(() => clearInterval(interval), 3000);
      }
    }

    /**
     * Авторизация
     *
     * @param {function} execute Функция, которая будет встроена в демпфер
     * @param {mixed} args Аргументы встраиваемой функции
     *
     * @return {void}
     */
    static authorization(execute, ...args) {
      if (typeof execute === "function") {
        // Получена функция

        if (core.page === this.page) {
          // Пройдена проверка на страницу

          // Запуск выполнения
          return execute(...args);
        }
      }
    }

    /**
     * Создать аккаунт и сотрудника (вызов демпфера)
     *
     * @param {HTMLElement} button Кнопка <button>
     * @param {HTMLElement} worker_name_first Имя сотрудника <input>
     * @param {HTMLElement} worker_name_second Фамилия сотрудника <input>
     * @param {HTMLElement} worker_name_last Отчество сотрудника <input>
     * @param {HTMLElement} worker_number SIM-номер сотрудника <input>
     * @param {HTMLElement} worker_mail Почта сотрудника <input>
     * @param {HTMLElement} worker_id Идентификатор сотрудника <input>
     * @param {HTMLElement} worker_birth Дата рождения сотрудника <input>
     * @param {HTMLElement} worker_passport Номер паспорта сотрудника <input>
     * @param {HTMLElement} worker_issued Дата выдачи паспорта сотрудника <input>
     * @param {HTMLElement} worker_department_number Номер отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_department_address Адрес отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_requisites Реквизиты: "0000 0000 0000 0000 Банк Иванов И." <input>
     * @param {HTMLElement} worker_payment Форма оплаты сотруднику <input>
     * @param {HTMLElement} worker_tax Индивидуальный налоговый номер сотрудника <input>
     * @param {HTMLElement} worker_city Город проживания сотрудника <select>
     * @param {HTMLElement} worker_district Регион проживания сотрудника <input>
     * @param {HTMLElement} worker_address Адрес проживания сотрудника <input>
     * @param {HTMLElement} worker_work Тип работы сотрудника <select>
     * @param {HTMLElement} worker_hiring Дата найма сотрудника <input>
     * @param {HTMLElement} account_name_first Имя аккаунта сотрудника <input>
     * @param {HTMLElement} account_name_second Фамилия аккаунта сотрудника <input>
     * @param {HTMLElement} account_name_last Отчество/Матчество аккаунта сотрудника <input>
     * @param {HTMLElement} account_number SIM-номер аккаунта сотрудника <input>
     * @param {HTMLElement} account_mail Почта аккаунта сотрудника <input>
     * @param {HTMLElement} account_password Пароль аккаунта <input>
     * @param {HTMLElement} account_commentary Комментарий аккаунта <textarea>
     *
     * @return {void}
     */
    static _create(
      button,
      worker_name_first,
      worker_name_second,
      worker_name_last,
      worker_number,
      worker_mail,
      worker_id,
      worker_birth,
      worker_passport,
      worker_issued,
      worker_department_number,
      worker_department_address,
      worker_requisites,
      worker_payment,
      worker_tax,
      worker_city,
      worker_district,
      worker_address,
      worker_work,
      worker_hiring,
      account_name_first,
      account_name_second,
      account_name_last,
      account_number,
      account_mail,
      account_password,
      account_commentary,
    ) {
      // Блокировка полей ввода
      worker_name_first.setAttribute("readonly", true);
      worker_name_second.setAttribute("readonly", true);
      worker_name_last.setAttribute("readonly", true);
      worker_number.setAttribute("readonly", true);
      worker_mail.setAttribute("readonly", true);
      worker_id.setAttribute("readonly", true);
      worker_birth.setAttribute("readonly", true);
      worker_passport.setAttribute("readonly", true);
      worker_issued.setAttribute("readonly", true);
      worker_department_number.setAttribute("readonly", true);
      worker_department_address.setAttribute("readonly", true);
      worker_requisites.setAttribute("readonly", true);
      worker_payment.setAttribute("readonly", true);
      worker_tax.setAttribute("readonly", true);
      worker_city.setAttribute("readonly", true);
      worker_district.setAttribute("readonly", true);
      worker_address.setAttribute("readonly", true);
      worker_work.setAttribute("readonly", true);
      worker_hiring.setAttribute("readonly", true);
      account_name_first.setAttribute("readonly", true);
      account_name_second.setAttribute("readonly", true);
      account_name_last.setAttribute("readonly", true);
      account_number.setAttribute("readonly", true);
      account_mail.setAttribute("readonly", true);
      account_password.setAttribute("readonly", true);
      account_commentary.setAttribute("readonly", true);

      // Блокировка кнопки
      button.setAttribute("disabled", true);

      // Запуск выполнения
      this.__create(
        button,
        worker_name_first,
        worker_name_second,
        worker_name_last,
        worker_number,
        worker_mail,
        worker_id,
        worker_birth,
        worker_passport,
        worker_issued,
        worker_department_number,
        worker_department_address,
        worker_requisites,
        worker_payment,
        worker_tax,
        worker_city,
        worker_district,
        worker_address,
        worker_work,
        worker_hiring,
        account_name_first,
        account_name_second,
        account_name_last,
        account_number,
        account_mail,
        account_password,
        account_commentary,
      );
    }

    /**
     * Создать аккаунт и сотрудника (демпфер)
     *
     * @param {HTMLElement} button Кнопка <button>
     * @param {HTMLElement} worker_name_first Имя сотрудника <input>
     * @param {HTMLElement} worker_name_second Фамилия сотрудника <input>
     * @param {HTMLElement} worker_name_last Отчество сотрудника <input>
     * @param {HTMLElement} worker_number SIM-номер сотрудника <input>
     * @param {HTMLElement} worker_mail Почта сотрудника <input>
     * @param {HTMLElement} worker_id Идентификатор сотрудника <input>
     * @param {HTMLElement} worker_birth Дата рождения сотрудника <input>
     * @param {HTMLElement} worker_passport Номер паспорта сотрудника <input>
     * @param {HTMLElement} worker_issued Дата выдачи паспорта сотрудника <input>
     * @param {HTMLElement} worker_department_number Номер отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_department_address Адрес отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_requisites Реквизиты: "0000 0000 0000 0000 Банк Иванов И." <input>
     * @param {HTMLElement} worker_payment Форма оплаты сотруднику <input>
     * @param {HTMLElement} worker_tax Индивидуальный налоговый номер сотрудника <input>
     * @param {HTMLElement} worker_city Город проживания сотрудника <select>
     * @param {HTMLElement} worker_district Регион проживания сотрудника <input>
     * @param {HTMLElement} worker_address Адрес проживания сотрудника <input>
     * @param {HTMLElement} worker_work Тип работы сотрудника <select>
     * @param {HTMLElement} worker_hiring Дата найма сотрудника <input>
     * @param {HTMLElement} account_name_first Имя аккаунта сотрудника <input>
     * @param {HTMLElement} account_name_second Фамилия аккаунта сотрудника <input>
     * @param {HTMLElement} account_name_last Отчество/Матчество аккаунта сотрудника <input>
     * @param {HTMLElement} account_number SIM-номер аккаунта сотрудника <input>
     * @param {HTMLElement} account_mail Почта аккаунта сотрудника <input>
     * @param {HTMLElement} account_password Пароль аккаунта <input>
     * @param {HTMLElement} account_commentary Комментарий аккаунта <textarea>
     *
     * @return {void}
     */
    static __create = damper(
      async (
        button,
        worker_name_first,
        worker_name_second,
        worker_name_last,
        worker_number,
        worker_mail,
        worker_id,
        worker_birth,
        worker_passport,
        worker_issued,
        worker_department_number,
        worker_department_address,
        worker_requisites,
        worker_payment,
        worker_tax,
        worker_city,
        worker_district,
        worker_address,
        worker_work,
        worker_hiring,
        account_name_first,
        account_name_second,
        account_name_last,
        account_number,
        account_mail,
        account_password,
        account_commentary,
      ) => {
        // Инициализация функции разблокировки
        function unblock() {
          // Разблокировка полей ввода
          worker_name_first.removeAttribute("readonly");
          worker_name_second.removeAttribute("readonly");
          worker_name_last.removeAttribute("readonly");
          worker_number.removeAttribute("readonly");
          worker_mail.removeAttribute("readonly");
          worker_id.removeAttribute("readonly");
          worker_birth.removeAttribute("readonly");
          worker_passport.removeAttribute("readonly");
          worker_issued.removeAttribute("readonly");
          worker_department_number.removeAttribute("readonly");
          worker_department_address.removeAttribute("readonly");
          worker_requisites.removeAttribute("readonly");
          worker_payment.removeAttribute("readonly");
          worker_tax.removeAttribute("readonly");
          worker_city.removeAttribute("readonly");
          worker_district.removeAttribute("readonly");
          worker_address.removeAttribute("readonly");
          worker_work.removeAttribute("readonly");
          worker_hiring.removeAttribute("readonly");
          account_name_first.removeAttribute("readonly");
          account_name_second.removeAttribute("readonly");
          account_name_last.removeAttribute("readonly");
          account_number.removeAttribute("readonly");
          account_mail.removeAttribute("readonly");
          account_password.removeAttribute("readonly");
          account_commentary.removeAttribute("readonly");

          // Разблокировка кнопки
          button.removeAttribute("disabled");
        }

        // Запуск отсрочки разблокировки на случай, если сервер не отвечает
        const timeout = setTimeout(() => {
          this.errors(["Сервер не отвечает"]);
          unblock();
        }, 5000);

        // Запрос к серверу
        return await fetch("/workers/create", {
          method: "POST",
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
          body:
            `worker_name_first=${worker_name_first.value}&worker_name_second=${worker_name_second.value}&worker_name_last=${worker_name_last.value}&worker_number=${worker_number.mask.unmaskedValue}&worker_mail=${worker_mail.value}&worker_id=${worker_id.value}&worker_birth=${worker_birth.value}&worker_birth=${worker_birth.value}&worker_passport=${worker_passport.value}&worker_issued=${worker_issued.value}&worker_department_number=${worker_department_number.value}&worker_department_address=${worker_department_address.value}&worker_requisites=${worker_requisites.value}&worker_payment=${worker_payment.value}&worker_tax=${worker_tax.value}&worker_city=${worker_city.value}&worker_district=${worker_district.value}&worker_address=${worker_address.value}&worker_work=${worker_work.value}&worker_hiring=${worker_hiring.value}&account_name_first=${account_name_first.value}&account_name_second=${account_name_second.value}&account_name_last=${account_name_last.value}&account_number=${account_number.mask.unmaskedValue}&account_mail=${account_mail.value}&account_password=${account_password.value}&account_commentary=${account_commentary.value}`,
        })
          .then((response) => response.json())
          .then((data) => {
            // Удаление отсрочки разблокировки
            clearTimeout(timeout);

            if (this.errors(data.errors)) {
              // Сгенерированы ошибки

              // Разблокировка полей ввода и кнопок
              unblock();
            } else {
              // Не сгенерированы ошибки (подразумевается их отсутствие)

              if (data.clipboard.length > 0) {
                // Получены данные для записи в буфер обмена

                // Запись в буфер обмена (подразумеваются данные созданного аккаунта)
                navigator.clipboard.writeText(data.clipboard);
              }

              if (this.body.wrap instanceof HTMLElement) {
                // Найдено активное окно

                // Деинициализация быстрых действий по кнопкам
                document.removeEventListener("keydown", this.buttons);

                // Сброс блокировки
                this.freeze = false;

                // Деинициализация активного окна
                this.body.wrap.remove();
              }

              // Реинициализация строк
              this.reinit();
            }
          });
      },
      300,
    );

    /**
     * Сгенерировать окно с формой создания аккаунта и сотрудника
     *
     * @param {HTMLElement} row Строка
     *
     * @return {void}
     */
    static create = damper(() => {
      // Инициализация оболочки всплывающего окна
      this.body.wrap = document.createElement("div");
      this.body.wrap.setAttribute("id", "popup");

      // Инициализация оболочки всплывающего окна
      const popup = document.createElement("section");
      popup.classList.add("list", "extensive");

      // Инициализация заголовка всплывающего окна
      const title = document.createElement("h3");
      title.classList.add("unselectable");
      title.innerText = "Создание сотрудника";

      // Инициализация оболочки с основной информацией
      const main = document.createElement("section");
      main.classList.add("main");

      // Инициализация колонки
      const worker = document.createElement("div");
      worker.classList.add("column");
      worker.setAttribute("data-column", "worker");
      worker.style.setProperty("width", "450px");

      // Инициализация строки
      const worker_name_first = document.createElement("div");
      worker_name_first.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const worker_name_first_label = document.createElement("label");
      worker_name_first_label.setAttribute("id", "worker_first");

      // Инициализация заголовка для поля ввода
      const worker_name_first_title = document.createElement("b");
      worker_name_first_title.classList.add(
        "separated",
        "right",
        "unselectable",
      );
      worker_name_first_title.innerText = "Имя:";

      // Инициализация поля ввода
      const worker_name_first_input = document.createElement("input");
      worker_name_first_input.classList.add("large");
      worker_name_first_input.setAttribute("type", "text");
      worker_name_first_input.setAttribute("name", "first");
      worker_name_first_input.setAttribute("autocomplete", "given-name");
      worker_name_first_input.setAttribute("minlength", "0");
      worker_name_first_input.setAttribute("maxlength", "100");
      worker_name_first_input.setAttribute(
        "oninput",
        `this.parentElement.parentElement.parentElement.parentElement.children[1].querySelector('[name="first"]').value = this.value`,
      );
      worker_name_first_input.setAttribute("title", "Имя сотрудника");
      worker_name_first_input.setAttribute("placeholder", "Иван");

      // Инициализация строки
      const worker_name_second = document.createElement("div");
      worker_name_second.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const worker_name_second_label = document.createElement("label");
      worker_name_second_label.setAttribute("id", "worker_second");

      // Инициализация заголовка для поля ввода
      const worker_name_second_title = document.createElement("b");
      worker_name_second_title.classList.add(
        "separated",
        "right",
        "unselectable",
      );
      worker_name_second_title.innerText = "Фамилия:";

      // Инициализация поля ввода
      const worker_name_second_input = document.createElement("input");
      worker_name_second_input.classList.add("large");
      worker_name_second_input.setAttribute("autocomplete", "family-name");
      worker_name_second_input.setAttribute("name", "second");
      worker_name_second_input.setAttribute("type", "text");
      worker_name_second_input.setAttribute("minlength", "0");
      worker_name_second_input.setAttribute("maxlength", "100");
      worker_name_second_input.setAttribute(
        "oninput",
        `this.parentElement.parentElement.parentElement.parentElement.children[1].querySelector('[name="second"]').value = this.value`,
      );
      worker_name_second_input.setAttribute("title", "Фамилия сотрудника");
      worker_name_second_input.setAttribute("placeholder", "Иванов");

      // Инициализация строки
      const worker_name_last = document.createElement("div");
      worker_name_last.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const worker_name_last_label = document.createElement("label");
      worker_name_last_label.setAttribute("id", "worker_last");

      // Инициализация заголовка для поля ввода
      const worker_name_last_title = document.createElement("b");
      worker_name_last_title.classList.add(
        "separated",
        "right",
        "unselectable",
      );
      worker_name_last_title.innerText = "Отчество:";

      // Инициализация поля ввода
      const worker_name_last_input = document.createElement("input");
      worker_name_last_input.classList.add("large");
      worker_name_last_input.setAttribute("name", "last");
      worker_name_last_input.setAttribute("autocomplete", "additional-name");
      worker_name_last_input.setAttribute("type", "text");
      worker_name_last_input.setAttribute("minlength", "0");
      worker_name_last_input.setAttribute("maxlength", "100");
      worker_name_last_input.setAttribute(
        "oninput",
        `this.parentElement.parentElement.parentElement.parentElement.children[1].querySelector('[name="last"]').value = this.value`,
      );
      worker_name_last_input.setAttribute(
        "title",
        "Отчество/Матчество сотрудника",
      );
      worker_name_last_input.setAttribute("placeholder", "Иванович");

      // Инициализация строки
      const worker_number = document.createElement("div");
      worker_number.classList.add("row", "merged", "divided");

      // Инициализация оболочки для строки
      const worker_number_label = document.createElement("label");
      worker_number_label.setAttribute("id", "worker_number");

      // Инициализация заголовка для поля ввода
      const worker_number_title = document.createElement("b");
      worker_number_title.classList.add("separated", "right", "unselectable");
      worker_number_title.innerText = "SIM-номер:";

      // Инициализация поля ввода
      const worker_number_input = document.createElement("input");
      worker_number_input.classList.add("large");
      worker_number_input.setAttribute("name", "sim-number");
      worker_number_input.setAttribute("autocomplete", "tel");
      worker_number_input.setAttribute("type", "text");
      worker_number_input.setAttribute("minlength", "18");
      worker_number_input.setAttribute("maxlength", "18");
      worker_number_input.setAttribute(
        "onkeyup",
        `this.parentElement.parentElement.parentElement.parentElement.children[1].querySelector('[name="sim-number"]').mask.unmaskedValue = this.mask.unmaskedValue`,
      );
      worker_number_input.setAttribute("title", "SIM-номер сотрудника");
      worker_number_input.setAttribute("placeholder", "+7 (000) 000-00-00");
      worker_number_input.setAttribute("required", "true");

      // Инициализация строки
      const worker_mail = document.createElement("div");
      worker_mail.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const worker_mail_label = document.createElement("label");
      worker_mail_label.setAttribute("id", "worker_mail");

      // Инициализация заголовка для поля ввода
      const worker_mail_title = document.createElement("b");
      worker_mail_title.classList.add("separated", "right", "unselectable");
      worker_mail_title.innerText = "Почта:";

      // Инициализация поля ввода
      const worker_mail_input = document.createElement("input");
      worker_mail_input.classList.add("large");
      worker_mail_input.setAttribute("name", "mail");
      worker_mail_input.setAttribute("autocomplete", "email");
      worker_mail_input.setAttribute("type", "text");
      worker_mail_input.setAttribute("minlength", "3");
      worker_mail_input.setAttribute("maxlength", "300");
      worker_mail_input.setAttribute(
        "oninput",
        `this.parentElement.parentElement.parentElement.parentElement.children[1].querySelector('[name="mail"]').value = this.value`,
      );
      worker_mail_input.setAttribute("title", "Почта сотрудника");
      worker_mail_input.setAttribute("placeholder", "name@server");

      // Инициализация строки
      const worker_id = document.createElement("div");
      worker_id.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const worker_id_label = document.createElement("label");
      worker_id_label.setAttribute("id", "worker_id");

      // Инициализация заголовка для поля ввода
      const worker_id_title = document.createElement("b");
      worker_id_title.classList.add("separated", "right", "unselectable");
      worker_id_title.innerText = "Идентификатор:";

      // Инициализация поля ввода
      const worker_id_input = document.createElement("input");
      worker_id_input.classList.add("large");
      worker_id_input.setAttribute("name", "id");
      worker_id_input.setAttribute("type", "text");
      worker_id_input.setAttribute("minlength", "1");
      worker_id_input.setAttribute("maxlength", "6");
      worker_id_input.setAttribute("title", "Идентификатор сотрудника");
      worker_id_input.setAttribute("placeholder", "000000");

      // Инициализация строки
      const worker_birth = document.createElement("div");
      worker_birth.classList.add("row", "divided");

      // Инициализация оболочки для строки
      const worker_birth_label = document.createElement("label");
      worker_birth_label.setAttribute("id", "worker_birth");

      // Инициализация заголовка для поля ввода
      const worker_birth_title = document.createElement("b");
      worker_birth_title.classList.add("separated", "right");
      worker_birth_title.innerText = "Дата рождения:";

      // Инициализация поля ввода
      const worker_birth_input = document.createElement("input");
      worker_birth_input.classList.add("large");
      worker_birth_input.setAttribute("autocomplete", "bday");
      worker_birth_input.setAttribute("name", "birth");
      worker_birth_input.setAttribute("type", "date");
      worker_birth_input.setAttribute("title", "Дата рождения сотрудника");

      // Инициализация строки
      const worker_passport = document.createElement("div");
      worker_passport.classList.add("row", "merged", "divided");

      // Инициализация оболочки для строки
      const worker_passport_label = document.createElement("label");
      worker_passport_label.setAttribute("id", "worker_passport");

      // Инициализация заголовка для поля ввода
      const worker_passport_title = document.createElement("b");
      worker_passport_title.classList.add("separated", "right");
      worker_passport_title.innerText = "Паспорт:";

      // Инициализация поля ввода
      const worker_passport_input = document.createElement("input");
      worker_passport_input.classList.add("large");
      worker_passport_input.setAttribute("autocomplete", "on");
      worker_passport_input.setAttribute("name", "passport");
      worker_passport_input.setAttribute("type", "text");
      worker_passport_input.setAttribute("minlength", "0");
      worker_passport_input.setAttribute("maxlength", "11");
      worker_passport_input.setAttribute("title", "Номер паспорта сотрудника");
      worker_passport_input.setAttribute("placeholder", "0000 000000");

      // Инициализация строки
      const worker_issued = document.createElement("div");
      worker_issued.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const worker_issued_label = document.createElement("label");
      worker_issued_label.setAttribute("id", "worker_issued");

      // Инициализация заголовка для поля ввода
      const worker_issued_title = document.createElement("b");
      worker_issued_title.classList.add("separated", "right");
      worker_issued_title.innerText = "Дата выдачи:";

      // Инициализация поля ввода
      const worker_issued_input = document.createElement("input");
      worker_issued_input.classList.add("large");
      worker_issued_input.setAttribute("autocomplete", "on");
      worker_issued_input.setAttribute("name", "issued");
      worker_issued_input.setAttribute("type", "date");
      worker_issued_input.setAttribute(
        "title",
        "Дата выдачи паспорта сотрудника",
      );

      // Инициализация строки
      const worker_department_number = document.createElement("div");
      worker_department_number.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const worker_department_number_label = document.createElement("label");
      worker_department_number_label.setAttribute(
        "id",
        "worker_department_number",
      );

      // Инициализация заголовка для поля ввода
      const worker_department_number_title = document.createElement("b");
      worker_department_number_title.classList.add("separated", "right");
      worker_department_number_title.innerText = "Отделение:";

      // Инициализация поля ввода
      const worker_department_number_input = document.createElement("input");
      worker_department_number_input.classList.add("large");
      worker_department_number_input.setAttribute("autocomplete", "on");
      worker_department_number_input.setAttribute("name", "department");
      worker_department_number_input.setAttribute("type", "text");
      worker_department_number_input.setAttribute("minlength", "0");
      worker_department_number_input.setAttribute("maxlength", "7");
      worker_department_number_input.setAttribute(
        "title",
        "Номер отделения выдавшего паспорт сотруднику",
      );
      worker_department_number_input.setAttribute("placeholder", "000-000");

      // Инициализация строки
      const worker_department_address = document.createElement("div");
      worker_department_address.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const worker_department_address_label = document.createElement("label");
      worker_department_address_label.setAttribute(
        "id",
        "worker_department_address",
      );

      // Инициализация заголовка для поля ввода
      const worker_department_address_title = document.createElement("b");
      worker_department_address_title.classList.add("separated", "right");
      worker_department_address_title.innerText = "Адрес отделения:";

      // Инициализация поля ввода
      const worker_department_address_input = document.createElement("input");
      worker_department_address_input.classList.add("large");
      worker_department_address_input.setAttribute("autocomplete", "on");
      worker_department_address_input.setAttribute("name", "department_2");
      worker_department_address_input.setAttribute("type", "text");
      worker_department_address_input.setAttribute("minlength", "0");
      worker_department_address_input.setAttribute("maxlength", "150");
      worker_department_address_input.setAttribute(
        "title",
        "Адрес отделения выдавшего паспорт сотруднику",
      );
      worker_department_address_input.setAttribute(
        "placeholder",
        "ОФМС России по ...",
      );

      // Инициализация строки
      const worker_requisites = document.createElement("div");
      worker_requisites.classList.add("row", "merged", "divided");

      // Инициализация оболочки для строки
      const worker_requisites_label = document.createElement("label");
      worker_requisites_label.setAttribute("id", "worker_requisites");

      // Инициализация заголовка для поля ввода
      const worker_requisites_title = document.createElement("b");
      worker_requisites_title.classList.add("separated", "right");
      worker_requisites_title.innerText = "Реквизиты:";

      // Инициализация поля ввода
      const worker_requisites_input = document.createElement("input");
      worker_requisites_input.classList.add("large");
      worker_requisites_input.setAttribute("autocomplete", "cc-number");
      worker_requisites_input.setAttribute("name", "requisites");
      worker_requisites_input.setAttribute("type", "text");
      worker_requisites_input.setAttribute("minlength", "0");
      worker_requisites_input.setAttribute("maxlength", "250");
      worker_requisites_input.setAttribute(
        "title",
        "0000 0000 0000 0000 Банк Иванов И.",
      );
      worker_requisites_input.setAttribute(
        "placeholder",
        "0000 0000 0000 0000 Банк Иванов И.",
      );

      // Инициализация строки
      const worker_payment = document.createElement("div");
      worker_payment.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const worker_payment_label = document.createElement("label");
      worker_payment_label.setAttribute("id", "worker_payment");

      // Инициализация заголовка для поля ввода
      const worker_payment_title = document.createElement("b");
      worker_payment_title.classList.add("separated", "right");
      worker_payment_title.innerText = "Форма оплаты:";

      // Инициализация поля ввода
      const worker_payment_input = document.createElement("input");
      worker_payment_input.classList.add("large");
      worker_payment_input.setAttribute("autocomplete", "off");
      worker_payment_input.setAttribute("name", "payment");
      worker_payment_input.setAttribute("type", "text");
      worker_payment_input.setAttribute("minlength", "0");
      worker_payment_input.setAttribute("maxlength", "80");
      worker_payment_input.setAttribute("title", "Форма оплаты сотруднику");
      worker_payment_input.setAttribute("placeholder", "Перевод на карту");
      worker_payment_input.setAttribute("value", "Перевод на карту");

      // Инициализация строки
      const worker_tax = document.createElement("div");
      worker_tax.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const worker_tax_label = document.createElement("label");
      worker_tax_label.setAttribute("id", "worker_tax");

      // Инициализация заголовка для поля ввода
      const worker_tax_title = document.createElement("b");
      worker_tax_title.classList.add("separated", "right");
      worker_tax_title.innerText = "ИНН:";

      // Инициализация поля ввода
      const worker_tax_input = document.createElement("input");
      worker_tax_input.classList.add("large");
      worker_tax_input.setAttribute("autocomplete", "on");
      worker_tax_input.setAttribute("name", "tax");
      worker_tax_input.setAttribute("type", "text");
      worker_tax_input.setAttribute("minlength", "0");
      worker_tax_input.setAttribute("maxlength", "12");
      worker_tax_input.setAttribute(
        "title",
        "Индивидуальный налоговый номер сотрудника",
      );
      worker_tax_input.setAttribute("placeholder", "000000000000");

      // Инициализация строки
      const worker_city = document.createElement("div");
      worker_city.classList.add("row", "merged", "divided");

      // Инициализация оболочки для выпадающего списка
      const worker_city_label = document.createElement("label");
      worker_city_label.setAttribute("id", "worker_city");

      // Инициализация заголовка для выпадающего списка
      const worker_city_title = document.createElement("b");
      worker_city_title.classList.add("separated", "right");
      worker_city_title.innerText = "Город:";

      // Инициализация выпадающего списка
      const worker_city_select = document.createElement("select");
      worker_city_select.classList.add("large");
      worker_city_select.setAttribute("autocomplete", "address-level2");
      worker_city_select.setAttribute("name", "city");
      worker_city_select.setAttribute("title", "Город проживания сотрудника");

      // Инициализация варианта для выбора
      const worker_city_option_1 = document.createElement("option");
      worker_city_option_1.setAttribute("value", "Красноярск");
      worker_city_option_1.innerText = "Красноярск";

      // Инициализация варианта для выбора
      const worker_city_option_2 = document.createElement("option");
      worker_city_option_2.setAttribute("value", "Железногорск");
      worker_city_option_2.innerText = "Железногорск";
      /*
      // Инициализация варианта для выбора
      const worker_city_option_3 = document.createElement("option");
      worker_city_option_3.classList.add("value", "");
			worker_city_option_3.innerText = "";

      // Инициализация варианта для выбора
      const worker_city_option_4 = document.createElement("option");
      worker_city_option_4.classList.add("value", "");
			worker_city_option_4.innerText = "";

      // Инициализация варианта для выбора
      const worker_city_option_5 = document.createElement("option");
      worker_city_option_5.classList.add("value", "");
			worker_city_option_5.innerText = "";

      // Инициализация варианта для выбора
      const worker_city_option_ = document.createElement("option");
      worker_city_option_.classList.add("value", "");
			worker_city_option_.innerText = ""; */

      // Инициализация строки
      const worker_district = document.createElement("div");
      worker_district.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const worker_district_label = document.createElement("label");
      worker_district_label.setAttribute("id", "worker_district");

      // Инициализация заголовка для поля ввода
      const worker_district_title = document.createElement("b");
      worker_district_title.classList.add("separated", "right");
      worker_district_title.innerText = "Регион:";

      // Инициализация поля ввода
      const worker_district_input = document.createElement("input");
      worker_district_input.classList.add("large");
      worker_district_input.setAttribute("autocomplete", "address-level3");
      worker_district_input.setAttribute("name", "district");
      worker_district_input.setAttribute("type", "text");
      worker_district_input.setAttribute("minlength", "0");
      worker_district_input.setAttribute("maxlength", "80");
      worker_district_input.setAttribute(
        "title",
        "Регион проживания сотрудника",
      );
      worker_district_input.setAttribute("placeholder", "Центральный");

      // Инициализация строки
      const worker_address = document.createElement("div");
      worker_address.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const worker_address_label = document.createElement("label");
      worker_address_label.setAttribute("id", "worker_address");

      // Инициализация заголовка для поля ввода
      const worker_address_title = document.createElement("b");
      worker_address_title.classList.add("separated", "right");
      worker_address_title.innerText = "Адрес:";

      // Инициализация поля ввода
      const worker_address_input = document.createElement("input");
      worker_address_input.classList.add("large");
      worker_address_input.setAttribute("autocomplete", "street-address");
      worker_address_input.setAttribute("name", "address");
      worker_address_input.setAttribute("type", "text");
      worker_address_input.setAttribute("minlength", "0");
      worker_address_input.setAttribute("maxlength", "150");
      worker_address_input.setAttribute("title", "Адрес проживания сотрудника");
      worker_address_input.setAttribute("placeholder", "ул. Пушкина 7");

      // Инициализация строки
      const worker_work = document.createElement("div");
      worker_work.classList.add("row", "merged", "divided");

      // Инициализация оболочки для строки
      const worker_work_label = document.createElement("label");
      worker_work_label.setAttribute("id", "worker_address");

      // Инициализация заголовка для поля ввода
      const worker_work_title = document.createElement("b");
      worker_work_title.classList.add("separated", "right");
      worker_work_title.innerText = "Тип работы:";

      // Инициализация поля ввода
      const worker_work_select = document.createElement("select");
      worker_work_select.classList.add("large");
      worker_work_select.setAttribute("title", "Тип работы сотрудника");
      this.works().then((html) => (worker_work_select.innerHTML = html));

      // Инициализация строки
      const worker_hiring = document.createElement("div");
      worker_hiring.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const worker_hiring_label = document.createElement("label");
      worker_hiring_label.setAttribute("id", "worker_hiring");

      // Инициализация заголовка для поля ввода
      const worker_hiring_title = document.createElement("b");
      worker_hiring_title.classList.add("separated", "right");
      worker_hiring_title.innerText = "Дата найма:";

      // Инициализация поля ввода
      const worker_hiring_input = document.createElement("input");
      worker_hiring_input.classList.add("large");
      worker_address_input.setAttribute("autocomplete", "off");
      worker_address_input.setAttribute("name", "hiring");
      worker_hiring_input.setAttribute("type", "date");
      worker_hiring_input.setAttribute("title", "Дата найма");
      worker_hiring_input.valueAsDate = new Date();

      // Инициализация колонки
      const account = document.createElement("div");
      account.classList.add("column");
      account.setAttribute("data-column", "account");
      account.style.setProperty("width", "300px");

      // Инициализация строки
      const account_name_first = document.createElement("div");
      account_name_first.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const account_name_first_label = document.createElement("label");
      account_name_first_label.setAttribute("id", "account_first");

      // Инициализация заголовка для поля ввода
      const account_name_first_title = document.createElement("b");
      account_name_first_title.classList.add(
        "separated",
        "right",
        "unselectable",
      );
      account_name_first_title.innerText = "Имя:";

      // Инициализация поля ввода
      const account_name_first_input = document.createElement("input");
      account_name_first_input.classList.add("medium");
      account_name_first_input.setAttribute("type", "text");
      account_name_first_input.setAttribute("name", "first");
      account_name_first_input.setAttribute("autocomplete", "given-name");
      account_name_first_input.setAttribute("minlength", "0");
      account_name_first_input.setAttribute("maxlength", "100");
      account_name_first_input.setAttribute(
        "onclick",
        "this.parentElement.parentElement.parentElement.parentElement.children[0].querySelector('[name=\"first\"]').focus()",
      );
      account_name_first_input.setAttribute("title", "Имя аккаунта сотрудника");
      account_name_first_input.setAttribute("placeholder", "Иван");
      account_name_first_input.setAttribute("readonly", "true");

      // Инициализация строки
      const account_name_second = document.createElement("div");
      account_name_second.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const account_name_second_label = document.createElement("label");
      account_name_second_label.setAttribute("id", "account_second");

      // Инициализация заголовка для поля ввода
      const account_name_second_title = document.createElement("b");
      account_name_second_title.classList.add(
        "separated",
        "right",
        "unselectable",
      );
      account_name_second_title.innerText = "Фамилия:";

      // Инициализация поля ввода
      const account_name_second_input = document.createElement("input");
      account_name_second_input.classList.add("medium");
      account_name_second_input.setAttribute("autocomplete", "family-name");
      account_name_second_input.setAttribute("name", "second");
      account_name_second_input.setAttribute("type", "text");
      account_name_second_input.setAttribute("minlength", "0");
      account_name_second_input.setAttribute("maxlength", "100");
      account_name_second_input.setAttribute(
        "onclick",
        "this.parentElement.parentElement.parentElement.parentElement.children[0].querySelector('[name=\"second\"]').focus()",
      );
      account_name_second_input.setAttribute(
        "title",
        "Фамилия аккаунта сотрудника",
      );
      account_name_second_input.setAttribute("placeholder", "Иванов");
      account_name_second_input.setAttribute("readonly", "true");

      // Инициализация строки
      const account_name_last = document.createElement("div");
      account_name_last.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const account_name_last_label = document.createElement("label");
      account_name_last_label.setAttribute("id", "account_last");

      // Инициализация заголовка для поля ввода
      const account_name_last_title = document.createElement("b");
      account_name_last_title.classList.add(
        "separated",
        "right",
        "unselectable",
      );
      account_name_last_title.innerText = "Отчество:";

      // Инициализация поля ввода
      const account_name_last_input = document.createElement("input");
      account_name_last_input.classList.add("medium");
      account_name_last_input.setAttribute("name", "last");
      account_name_last_input.setAttribute("autocomplete", "additional-name");
      account_name_last_input.setAttribute("type", "text");
      account_name_last_input.setAttribute("minlength", "0");
      account_name_last_input.setAttribute("maxlength", "100");
      account_name_last_input.setAttribute(
        "onclick",
        "this.parentElement.parentElement.parentElement.parentElement.children[0].querySelector('[name=\"last\"]').focus()",
      );
      account_name_last_input.setAttribute(
        "title",
        "Отчество/Матчество аккаунта сотрудника",
      );
      account_name_last_input.setAttribute("placeholder", "Иванович");
      account_name_last_input.setAttribute("readonly", "true");

      // Инициализация строки
      const account_number = document.createElement("div");
      account_number.classList.add("row", "merged", "divided");

      // Инициализация оболочки для строки
      const account_number_label = document.createElement("label");
      account_number_label.setAttribute("id", "account_number");

      // Инициализация заголовка для поля ввода
      const account_number_title = document.createElement("b");
      account_number_title.classList.add("separated", "right", "unselectable");
      account_number_title.innerText = "SIM-номер:";

      // Инициализация поля ввода
      const account_number_input = document.createElement("input");
      account_number_input.classList.add("medium");
      account_number_input.setAttribute("name", "sim-number");
      account_number_input.setAttribute("autocomplete", "tel");
      account_number_input.setAttribute("type", "text");
      account_number_input.setAttribute("minlength", "18");
      account_number_input.setAttribute("maxlength", "18");
      account_number_input.setAttribute(
        "onclick",
        "this.parentElement.parentElement.parentElement.parentElement.children[0].querySelector('[name=\"sim-number\"]').focus()",
      );
      account_number_input.setAttribute(
        "title",
        "SIM-номер аккаунта сотрудника",
      );
      account_number_input.setAttribute("placeholder", "+7 (000) 000-00-00");
      account_number_input.setAttribute("required", "true");
      account_number_input.setAttribute("readonly", "true");

      // Инициализация строки
      const account_mail = document.createElement("div");
      account_mail.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const account_mail_label = document.createElement("label");
      account_mail_label.setAttribute("id", "account_mail");

      // Инициализация заголовка для поля ввода
      const account_mail_title = document.createElement("b");
      account_mail_title.classList.add("separated", "right", "unselectable");
      account_mail_title.innerText = "Почта:";

      // Инициализация поля ввода
      const account_mail_input = document.createElement("input");
      account_mail_input.classList.add("medium");
      account_mail_input.setAttribute("name", "mail");
      account_mail_input.setAttribute("autocomplete", "email");
      account_mail_input.setAttribute("type", "text");
      account_mail_input.setAttribute("minlength", "3");
      account_mail_input.setAttribute("maxlength", "300");
      account_mail_input.setAttribute(
        "onclick",
        "this.parentElement.parentElement.parentElement.parentElement.children[0].querySelector('[name=\"mail\"]').focus()",
      );
      account_mail_input.setAttribute("title", "Почта аккаунта сотрудника");
      account_mail_input.setAttribute("placeholder", "name@server");
      account_mail_input.setAttribute("readonly", "true");

      // Инициализация строки
      const account_password = document.createElement("div");
      account_password.classList.add("row", "merged");

      // Инициализация оболочки для строки
      const account_password_label = document.createElement("label");
      account_password_label.setAttribute("id", "account_password");

      // Инициализация заголовка для поля ввода
      const account_password_title = document.createElement("b");
      account_password_title.classList.add(
        "separated",
        "right",
        "unselectable",
      );
      account_password_title.innerText = "Пароль:";

      // Инициализация поля ввода
      const account_password_input = document.createElement("input");
      account_password_input.classList.add("medium");
      account_password_input.setAttribute("name", "password");
      account_password_input.setAttribute("required", "true");
      account_password_input.setAttribute("autocomplete", "new-password");
      account_password_input.setAttribute("type", "password");
      account_password_input.setAttribute("minlength", "6");
      account_password_input.setAttribute("maxlength", "100");
      account_password_input.setAttribute(
        "title",
        "Пароль аккаунта сотрудника",
      );
      account_password_input.setAttribute("placeholder", "*********");

      // Инициализация строки
      const account_commentary = document.createElement("div");
      account_commentary.classList.add("row", "endless");

      // Инициализация оболочки для строки
      const account_commentary_label = document.createElement("label");
      account_commentary_label.setAttribute("id", "account_commentary");

      // Инициализация поля ввода
      const account_commentary_textarea = document.createElement("textarea");
      account_commentary_textarea.classList.add("snow");
      account_commentary_textarea.setAttribute("maxlength", "800");
      account_commentary_textarea.setAttribute(
        "title",
        "Комментарий аккаунта сотрудника",
      );
      account_commentary_textarea.setAttribute(
        "placeholder",
        "Дополнительная информация для администраторов и операторов",
      );

      // Инициализация строки
      const account_buttons = document.createElement("div");
      account_buttons.classList.add("row", "divided", "buttons");

      // Инициализация оболочки для кнопок
      const account_buttons_label = document.createElement("label");

      // Инициализация кнопки подтверждения даты
      const account_create_button = document.createElement("button");
      account_create_button.classList.add("grass", "stretched");
      account_create_button.innerText = "Создать";
      account_create_button.setAttribute(
        "onclick",
        `workers._create(this, ...this.parentElement.parentElement.parentElement.parentElement.querySelectorAll(':is(select, input, textarea)'))`,
      );

      // Инициализация окна с ошибками
      this.body.errors = document.createElement("section");
      this.body.errors.classList.add(
        "errors",
        "window",
        "list",
        "calculated",
        "hidden",
      );
      this.body.errors.setAttribute("data-errors", true);

      // Инициализация элемента-тела (оболочки) окна с ошибками
      const errors = document.createElement("section");
      errors.classList.add("body");

      // Инициализация элемента-списка ошибок
      const dl = document.createElement("dl");

      // Инициализация активного всплывающего окна
      const old = document.getElementById("popup");

      if (old instanceof HTMLElement) {
        // Найдено активное окно

        // Деинициализация быстрых действий по кнопкам
        document.removeEventListener("keydown", this.buttons);

        // Сброс блокировки
        this.freeze = false;

        // Удаление активного окна
        old.remove();
      }

      // Запись в документ
      popup.appendChild(title);

      worker_name_first_label.appendChild(worker_name_first_title);
      worker_name_first_label.appendChild(worker_name_first_input);
      worker_name_first.appendChild(worker_name_first_label);
      worker.appendChild(worker_name_first);

      worker_name_second_label.appendChild(worker_name_second_title);
      worker_name_second_label.appendChild(worker_name_second_input);
      worker_name_second.appendChild(worker_name_second_label);
      worker.appendChild(worker_name_second);

      worker_name_last_label.appendChild(worker_name_last_title);
      worker_name_last_label.appendChild(worker_name_last_input);
      worker_name_last.appendChild(worker_name_last_label);
      worker.appendChild(worker_name_last);

      worker_number_label.appendChild(worker_number_title);
      worker_number_label.appendChild(worker_number_input);
      worker_number.appendChild(worker_number_label);
      worker.appendChild(worker_number);

      worker_mail_label.appendChild(worker_mail_title);
      worker_mail_label.appendChild(worker_mail_input);
      worker_mail.appendChild(worker_mail_label);
      worker.appendChild(worker_mail);

      worker_id_label.appendChild(worker_id_title);
      worker_id_label.appendChild(worker_id_input);
      worker_id.appendChild(worker_id_label);
      worker.appendChild(worker_id);

      worker_birth_label.appendChild(worker_birth_title);
      worker_birth_label.appendChild(worker_birth_input);
      worker_birth.appendChild(worker_birth_label);
      worker.appendChild(worker_birth);

      worker_passport_label.appendChild(worker_passport_title);
      worker_passport_label.appendChild(worker_passport_input);
      worker_passport.appendChild(worker_passport_label);
      worker.appendChild(worker_passport);

      worker_issued_label.appendChild(worker_issued_title);
      worker_issued_label.appendChild(worker_issued_input);
      worker_issued.appendChild(worker_issued_label);
      worker.appendChild(worker_issued);

      worker_department_number_label.appendChild(
        worker_department_number_title,
      );
      worker_department_number_label.appendChild(
        worker_department_number_input,
      );
      worker_department_number.appendChild(worker_department_number_label);
      worker.appendChild(worker_department_number);

      worker_department_address_label.appendChild(
        worker_department_address_title,
      );
      worker_department_address_label.appendChild(
        worker_department_address_input,
      );
      worker_department_address.appendChild(worker_department_address_label);
      worker.appendChild(worker_department_address);

      worker_requisites_label.appendChild(worker_requisites_title);
      worker_requisites_label.appendChild(worker_requisites_input);
      worker_requisites.appendChild(worker_requisites_label);
      worker.appendChild(worker_requisites);

      worker_payment_label.appendChild(worker_payment_title);
      worker_payment_label.appendChild(worker_payment_input);
      worker_payment.appendChild(worker_payment_label);
      worker.appendChild(worker_payment);

      worker_tax_label.appendChild(worker_tax_title);
      worker_tax_label.appendChild(worker_tax_input);
      worker_tax.appendChild(worker_tax_label);
      worker.appendChild(worker_tax);

      worker_city_label.appendChild(worker_city_title);
      worker_city_select.appendChild(worker_city_option_1);
      worker_city_select.appendChild(worker_city_option_2);
      worker_city_label.appendChild(worker_city_select);
      worker_city.appendChild(worker_city_label);
      worker.appendChild(worker_city);

      worker_district_label.appendChild(worker_district_title);
      worker_district_label.appendChild(worker_district_input);
      worker_district.appendChild(worker_district_label);
      worker.appendChild(worker_district);

      worker_address_label.appendChild(worker_address_title);
      worker_address_label.appendChild(worker_address_input);
      worker_address.appendChild(worker_address_label);
      worker.appendChild(worker_address);

      worker_work_label.appendChild(worker_work_title);
      worker_work_label.appendChild(worker_work_select);
      worker_work.appendChild(worker_work_label);
      worker.appendChild(worker_work);

      worker_hiring_label.appendChild(worker_hiring_title);
      worker_hiring_label.appendChild(worker_hiring_input);
      worker_hiring.appendChild(worker_hiring_label);
      worker.appendChild(worker_hiring);

      main.appendChild(worker);

      account_name_first_label.appendChild(account_name_first_title);
      account_name_first_label.appendChild(account_name_first_input);
      account_name_first.appendChild(account_name_first_label);
      account.appendChild(account_name_first);

      account_name_second_label.appendChild(account_name_second_title);
      account_name_second_label.appendChild(account_name_second_input);
      account_name_second.appendChild(account_name_second_label);
      account.appendChild(account_name_second);

      account_name_last_label.appendChild(account_name_last_title);
      account_name_last_label.appendChild(account_name_last_input);
      account_name_last.appendChild(account_name_last_label);
      account.appendChild(account_name_last);

      account_number_label.appendChild(account_number_title);
      account_number_label.appendChild(account_number_input);
      account_number.appendChild(account_number_label);
      account.appendChild(account_number);

      account_mail_label.appendChild(account_mail_title);
      account_mail_label.appendChild(account_mail_input);
      account_mail.appendChild(account_mail_label);
      account.appendChild(account_mail);

      account_password_label.appendChild(account_password_title);
      account_password_label.appendChild(account_password_input);
      account_password.appendChild(account_password_label);
      account.appendChild(account_password);

      account_commentary_label.appendChild(account_commentary_textarea);
      account_commentary.appendChild(account_commentary_label);
      account.appendChild(account_commentary);

      account_buttons_label.appendChild(account_create_button);
      account_buttons.appendChild(account_buttons_label);
      account.appendChild(account_buttons);

      main.appendChild(account);

      popup.appendChild(main);
      this.body.wrap.appendChild(popup);

      errors.appendChild(dl);
      this.body.errors.appendChild(errors);
      this.body.wrap.appendChild(this.body.errors);

      document.body.appendChild(this.body.wrap);

      // Инициализация ширины окна с ошибками
      this.body.errors.style.setProperty(
        "--calculated-width",
        popup.offsetWidth + "px",
      );

      // Инициалиация масок
      account_number_input.mask = IMask(account_number_input, {
        mask: "+{7} (000) 000-00-00",
      });
      worker_number_input.mask = IMask(worker_number_input, {
        mask: "+{7} (000) 000-00-00",
      });
      worker_passport_input.mask = IMask(worker_passport_input, {
        mask: "0000 000000",
      });
      worker_department_number_input.mask = IMask(
        worker_department_number_input,
        {
          mask: "000-000",
        },
      );
      worker_requisites_input.mask = IMask(worker_requisites_input, {
        mask: "0000 0000 0000 0000 bank second first",
        blocks: {
          bank: {
            mask: /^[А-яA-z\d]+$/,
            prepareChar: (str, masked) =>
              masked.value.length === 0 ? str.toUpperCase() : str,
          },
          second: {
            mask: /^[А-яA-z\d]+$/,
            prepareChar: (str, masked) =>
              masked.value.length === 0 ? str.toUpperCase() : str,
          },
          first: {
            mask: "a.",
            prepareChar: (str) => str.toUpperCase(),
          },
        },
      });
      worker_tax_input.mask = IMask(worker_tax_input, { mask: "000000000000" });

      // Инициализация переменных для окна с ошибками (12 - это значение gap из div#popup)
      function top(errors) {
        errors.style.setProperty("transition", "0s");
        errors.style.setProperty(
          "--top",
          popup.offsetTop + popup.offsetHeight + 12 + "px",
        );
        setTimeout(() => errors.style.removeProperty("transition"), 100);
      }
      top(this.body.errors);
      const resize = new ResizeObserver(() => top(this.body.errors));
      resize.observe(this.body.wrap);

      // Инициализация функции блокировки кнопки
      const block = (e) => {
        // Игнорировать нажатие кнопки "enter"
        if (e instanceof Event && e.keyCode === 13) return;

        // Проверка заполнения обязательных полей
        if (
          account_password_input.value.length > 6 &&
          account_number_input.value.length === 18 &&
          worker_number_input.value.length === 18
        ) {
          account_create_button.removeAttribute("disabled");
        } else account_create_button.setAttribute("disabled", "true");
      };

      // Добавление функции блокировки кнопки по событиям
      account_password_input.addEventListener("keyup", block);
      account_number_input.addEventListener("keyup", block);
      worker_number_input.addEventListener("keyup", block);

      // Первичная активация функции блокировки кнопки
      block();

      // Инициализация функции генерации пароля и записи в поле ввода и буфер обмена
      const generate = (e) => {
        // Блокировка выполнения при нажатии на поле для ввода
        if (e.target.tagName === "INPUT") return;

        // Инициализация поля ввода пароля
        const input = e.currentTarget.getElementsByTagName("input")[0];

        if (input instanceof HTMLElement) {
          // Найдено поле для ввода пароля

          // Инициализация буфера генерации пароля
          let password = "";

          // Инициализация используемых символов для генерируемого пароля
          const symbols =
            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789------";

          // Генерация пароля
          for (let i = 0; i < Math.random() * 14 + 8; i++) {
            password += symbols.charAt(
              Math.floor(Math.random() * symbols.length),
            );
          }

          // Запись пароля в поле для ввода пароля
          input.value = password;

          // Вызов функции инициализации генератора пароля
          input.dispatchEvent(new KeyboardEvent("keyup"));

          // Запиcь пароля в буфер обмена
          navigator.clipboard.writeText(password);

          // Фокусировка на поле для ввода пароля
          input.focus();
        }
      };

      // Инициализация функции инициализации генератора пароля
      const generator = (e) => {
        // Инициализация строки с полем для ввода пароля
        const row = e.currentTarget.parentElement.parentElement;

        if (row instanceof HTMLElement) {
          // Найдено поле для ввода пароля

          if (e.target.value.length === 0) {
            // Не введён пароль

            row.setAttribute("title", "Сгенерировать пароль");
            row.setAttribute("data-interactive", "true");
            row.addEventListener("click", generate);
          } else {
            // Введён пароль

            row.removeAttribute("title");
            row.removeAttribute("data-interactive");
            row.removeEventListener("click", generate);
          }
        }
      };

      // Инициализация вызова функции инициализации генератора пароля по события нажатия клавиши
      account_password_input.addEventListener("keyup", generator);

      // Вызов функции инициализации генератора пароля (первичный)
      account_password_input.dispatchEvent(new KeyboardEvent("keyup"));

      // Инициализация функции закрытия всплывающего окна
      const click = () => {
        // Блокировка
        if (this.freeze) return;

        // Удаление всплывающего окна
        this.body.wrap.remove();

        // Удаление статуса активной строки
        row.removeAttribute("data-selected");

        // Деинициализация быстрых действий по кнопкам
        document.removeEventListener("keydown", this.buttons);

        // Сброс блокировки
        this.freeze = false;
      };

      // Инициализация функции добавления функции закрытия всплывающего окна
      const enable = () => this.body.wrap.addEventListener("click", click);

      // Инициализация функции удаления функции закрытия всплывающего окна
      const disable = () => this.body.wrap.removeEventListener("click", click);

      // Первичная активация функции удаления всплывающего окна
      enable();

      // Инициализация блокировки удаления окна при взаимодействии с select-элементом
      for (const select of popup.getElementsByTagName("select")) {
        // Перебор всех select-элементов

        // Инициализация функции блокировки удаления окна по событию
        select.addEventListener("click", () => {
          // Блокировка удаления окна
          this.freeze = true;

          // Разблокировка удаления окна
          setTimeout(() => (this.freeze = false), 100);
        });

        for (const option of select.getElementsByTagName("option")) {
          // Перебор всех option-элементов

          // Инициализация функции блокировки удаления окна по событию
          option.addEventListener("click", () => {
            // Блокировка удаления окна
            this.freeze = true;

            // Разблокировка удаления окна
            setTimeout(() => (this.freeze = false), 100);
          });
        }
      }

      // Инициализация блокировки удаления окна при взаимодействии с textarea-элементом
      for (const textarea of popup.getElementsByTagName("textarea")) {
        // Перебор всех textarea-элементов

        // Обновлять позицию окна с ошибками при изменении размера textarea (там position: absolute)
        new MutationObserver(() => top(this.body.errors)).observe(textarea, {
          attributes: true,
          attributeFilter: ["style"],
        });

        // Инициализация функции игнорирования блокировки для выбранных кнопок
        textarea.addEventListener("keydown", (e) => {
          if (e.keyCode === 27) {
            // Нажата кнопка: "escape"

            // Вызов глобальной функции управления кнопками
            this.buttons(e, true);
          } else if (e.ctrlKey && e.keyCode === 13) {
            // Нажаты кнопки: "control", "enter"

            // Вызов глобальной функции управления кнопками
            this.buttons(e, true);
          }
        });

        // Добавление функции блокировки удаления окна и клавиш по событиям
        textarea.addEventListener("focus", () => (this.freeze = true));
        textarea.addEventListener("focusout", () => (this.freeze = false));
      }

      // Инициализация функции управления кнопками
      this.buttons = (e, force = false) => {
        // Блокировка
        if (!force && this.freeze) return;

        if (e.keyCode === 27) {
          // Нажата кнопка: "escape"

          // Удаление окна
          click();
        } else if (event.keyCode === 13) {
          // Нажата кнопка: "enter"

          // Инициализация буфера с текущим статусом блокировки закрытия окна
          const freeze = this.freeze;

          // Блокировка закрытия окна (чтобы не вызвался click() через событие onclick)
          this.freeze = true;

          // Активация виртуальной кнопки "создать"
          account_create_button.click();

          // Возвращение статуса блокировки закрытия окна
          this.freeze = freeze;
        }
      };

      // Инициализация быстрых действий по кнопкам
      document.addEventListener("keydown", this.buttons);

      // Добавление функции удаления всплывающего окна по событиям
      popup.addEventListener("mouseenter", disable);
      popup.addEventListener("mouseleave", enable);

      // Фокусировка
      worker_name_first_input.focus();
    }, 300);

    /**
     * Переключить фильтр
     *
     * @param {string} name Название
     * @param {string|number|null} value Значение
     * @param {HTMLElement|null} button Кнопка
     *
     * @return {void}
     */
    static filter = damper(async (name, value, button) => {
      if (typeof name === "string") {
        // Получено название

        // Инициализация сериализованного пути к директории
        const path = `workers_filter_${name}`;

        if (typeof value === "string" || typeof value === "number") {
          // Получено значение

          // Запись нового значения
          buffer.write(path, value);
        } else {
          // Не получено значение

          // Чтение текущего значения
          value = +(await buffer.read(path));

          // Инициализация значения по умолчанию
          if (isNaN(value)) value = 0;

          // Запись нового значения (инвертирование)
          buffer.write(path, ++value < 3 ? value : 0);

          if (button instanceof HTMLElement) {
            // Получена кнопка

            // Деинициализация классов статуса фильтра
            button.classList.remove("earth", "sand", "river");

            // Инициализация классов статуса фильтра
            if (value === 1) button.classList.add("sand");
            else if (value === 2) button.classList.add("river");
            else button.classList.add("earth");
          }
        }
      }
    }, 300);

    /**
     * Записать фильтр поиска
     *
     * @param {HTMLElement} input Строка поиска
     * @param {HTMLElement} button Кнопка отправки
     *
     * @return {void}
     */
    static search = (input, button) => {
      input.setAttribute("readonly", true);
      button.setAttribute("disabled", true);

      this._search(input, button);
    };

    /**
     * Записать фильтр поиска (системное)
     *
     * Используется как оболочка для большей временной задержки
     *
     * @param {HTMLElement} input Строка поиска
     * @param {HTMLElement} button Кнопка отправки
     *
     * @return {void}
     */
    static _search = damper((input, button) => {
      this.filter("search", input.value);
      this.reinit(() => {
        input.removeAttribute("readonly");
        button.removeAttribute("disabled");
      });
    }, 1000);

    /**
     * Инициализация страниц
     *
     * @param {number} amount Количество страниц для генерации
     * @param {number} iteration Номер итерации (системное)
     *
     * @return {void}
     */
    static async init(amount = 3, iteration = 0) {
      if (
        typeof amount === "number" &&
        typeof iteration === "number" &&
        this.initialized === false
      ) {
        // Получены количество страниц и номер итерации

        // Инициализация страницы (написал workers потому, что оптимизатор выдаёт ошибку, что this.read не найдено, хотя всё работает)
        await workers.read(++iteration);

        // Проверка условий и отложенный запуск следующей итерации
        if (iteration < amount) setTimeout(this.init, 1500, amount, iteration);
        else this.initialized = true;
      }
    }

    /**
     * Реинициализация страниц
     *
     * @param {function} postprocessing Функция которая будет исполнена после реинициализации
     * @param {number} amount Количество страниц для генерации при инициализации
     *
     * @return {void}
     */
    static reinit = damper((postprocessing, amount = 3) => {
      if (typeof amount === "number") {
        // Получены количество страниц

        // Деинициализация cookie с номером страницы
        Cookies.remove("workers_page", { path: "/" });

        // Инициализация оболочки
        const workers = document.getElementById("workers");

        if (workers instanceof HTMLElement) {
          // Найдена оболочка

          // Инициализация буфера активного элемента
          const active = document.activeElement;

          // Инициализация буфера элементов
          const buffer = document.createElement("div");

          // Перенос элементов в буфер
          buffer.replaceChildren(...workers.children);

          // Удаление комментариев с индексами страниц
          workers.innerHTML = workers.innerHTML.replace(
            /<!--(?!>)[\S\s]*?-->/g,
            "",
          );

          // Перенос элементов из буфера
          workers.replaceChildren(...buffer.children);

          // Деинициализация страниц
          for (
            const element of workers.querySelectorAll(
              ':scope > div[data-row="worker"]',
            )
          ) {
            element.remove();
          }

          // Сброс статуса инициализированности
          this.initialized = false;

          // Инициализация страниц
          this.init(amount);

          // Возвращение фокуса на активный элемент
          active.focus();

          // Постобработка
          if (typeof postprocessing === "function") postprocessing();
        }
      }
    }, 2000);

    /**
     * Прочитать
     *
     * Читает список сотрудников и модифицирует документ (записывает в общий список)
     *
     * @param {number} page Страница
     *
     * @return {object} {(bool) exist, (array) errors}
     */
    static read = damper(async (page) => {
      if (typeof core === "function" && typeof page !== "number") {
        // Не получена страница

        // Инициализация страницы (если не получена, то брать из cookie и прибавлять 1)
        page = Cookies.get(`workers_page`) ?? 0;

        // Запись идентификатора следующей страницы
        ++page;
      }

      // Запрос к серверу
      return await fetch("/workers/read", {
        method: "POST",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
        body: `page=${page}`,
      })
        .then((response) => response.text())
        .then((data) => {
          // Инициализация буфера для записи в документ
          const element = document.createElement("div");

          // Запись пустого элемента из буфера в документ
          document.getElementById("workers").appendChild(element);

          // Запись в документ HTML-данных через буфер
          element.outerHTML = data;

          // Возврат (успех)
          return data;
        });
    }, 50);

    /**
     * Сгенерировать список
     *
     * @return {array|null} Массив HTML-элементов <option>
     */
    static async list() {
      // Запрос к серверу
      return await fetch(`/workers/list`, {
        method: "POST",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
      })
        .then((response) => response.text())
        .then((data) => {
          if (data.length > 0) {
            // Получены данные

            return data;
          }

          return null;
        });
    }

    /**
     * Обновить сотрудника (вызов демпфера)
     *
     * @param {HTMLElement} row Строка <div>
     * @param {HTMLElement} button Кнопка <button>
     * @param {HTMLElement} worker_name_first Имя сотрудника <input>
     * @param {HTMLElement} worker_name_second Фамилия сотрудника <input>
     * @param {HTMLElement} worker_name_last Отчество сотрудника <input>
     * @param {HTMLElement} worker_number SIM-номер сотрудника <input>
     * @param {HTMLElement} worker_mail Почта сотрудника <input>
     * @param {HTMLElement} worker_birth Дата рождения сотрудника <input>
     * @param {HTMLElement} worker_passport Номер паспорта сотрудника <input>
     * @param {HTMLElement} worker_issued Дата выдачи паспорта сотрудника <input>
     * @param {HTMLElement} worker_department_number Номер отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_department_address Адрес отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_requisites Реквизиты: "0000 0000 0000 0000 Банк Иванов И." <input>
     * @param {HTMLElement} worker_payment Форма оплаты сотруднику <input>
     * @param {HTMLElement} worker_tax Индивидуальный налоговый номер сотрудника <input>
     * @param {HTMLElement} worker_city Город проживания сотрудника <select>
     * @param {HTMLElement} worker_district Регион проживания сотрудника <input>
     * @param {HTMLElement} worker_address Адрес проживания сотрудника <input>
     * @param {HTMLElement} worker_work Тип работы сотрудника <select>
     * @param {HTMLElement} worker_hiring Дата найма сотрудника <input>
     *
     * @return {void}
     */
    static _update(
      row,
      button,
      worker_name_first,
      worker_name_second,
      worker_name_last,
      worker_number,
      worker_mail,
      worker_birth,
      worker_passport,
      worker_issued,
      worker_department_number,
      worker_department_address,
      worker_requisites,
      worker_payment,
      worker_tax,
      worker_city,
      worker_district,
      worker_address,
      worker_work,
      worker_hiring,
    ) {
      // Блокировка полей ввода
      worker_name_first.setAttribute("readonly", true);
      worker_name_second.setAttribute("readonly", true);
      worker_name_last.setAttribute("readonly", true);
      worker_number.setAttribute("readonly", true);
      worker_mail.setAttribute("readonly", true);
      worker_birth.setAttribute("readonly", true);
      worker_passport.setAttribute("readonly", true);
      worker_issued.setAttribute("readonly", true);
      worker_department_number.setAttribute("readonly", true);
      worker_department_address.setAttribute("readonly", true);
      worker_requisites.setAttribute("readonly", true);
      worker_payment.setAttribute("readonly", true);
      worker_tax.setAttribute("readonly", true);
      worker_city.setAttribute("readonly", true);
      worker_district.setAttribute("readonly", true);
      worker_address.setAttribute("readonly", true);
      worker_work.setAttribute("readonly", true);
      worker_hiring.setAttribute("readonly", true);

      // Блокировка кнопки
      button.setAttribute("disabled", true);

      // Запуск выполнения
      this.__update(
        row,
        button,
        worker_name_first,
        worker_name_second,
        worker_name_last,
        worker_number,
        worker_mail,
        worker_birth,
        worker_passport,
        worker_issued,
        worker_department_number,
        worker_department_address,
        worker_requisites,
        worker_payment,
        worker_tax,
        worker_city,
        worker_district,
        worker_address,
        worker_work,
        worker_hiring,
      );
    }

    /**
     * Обновить сотрудника (демпфер)
     *
     * @param {HTMLElement} row Строка <div>
     * @param {HTMLElement} worker_name_first Имя сотрудника <input>
     * @param {HTMLElement} worker_name_second Фамилия сотрудника <input>
     * @param {HTMLElement} worker_name_last Отчество сотрудника <input>
     * @param {HTMLElement} worker_number SIM-номер сотрудника <input>
     * @param {HTMLElement} worker_mail Почта сотрудника <input>
     * @param {HTMLElement} worker_birth Дата рождения сотрудника <input>
     * @param {HTMLElement} worker_passport Номер паспорта сотрудника <input>
     * @param {HTMLElement} worker_issued Дата выдачи паспорта сотрудника <input>
     * @param {HTMLElement} worker_department_number Номер отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_department_address Адрес отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_requisites Реквизиты: "0000 0000 0000 0000 Банк Иванов И." <input>
     * @param {HTMLElement} worker_payment Форма оплаты сотруднику <input>
     * @param {HTMLElement} worker_tax Индивидуальный налоговый номер сотрудника <input>
     * @param {HTMLElement} worker_city Город проживания сотрудника <select>
     * @param {HTMLElement} worker_district Регион проживания сотрудника <input>
     * @param {HTMLElement} worker_address Адрес проживания сотрудника <input>
     * @param {HTMLElement} worker_work Тип работы сотрудника <select>
     * @param {HTMLElement} worker_hiring Дата найма сотрудника <input>
     *
     * @return {void}
     */
    static __update = damper(
      async (
        row,
        button,
        worker_name_first,
        worker_name_second,
        worker_name_last,
        worker_number,
        worker_mail,
        worker_birth,
        worker_passport,
        worker_issued,
        worker_department_number,
        worker_department_address,
        worker_requisites,
        worker_payment,
        worker_tax,
        worker_city,
        worker_district,
        worker_address,
        worker_work,
        worker_hiring,
      ) => {
        // Инициализация функции разблокировки
        function unblock() {
          // Разблокировка полей ввода
          worker_name_first.removeAttribute("readonly");
          worker_name_second.removeAttribute("readonly");
          worker_name_last.removeAttribute("readonly");
          worker_number.removeAttribute("readonly");
          worker_mail.removeAttribute("readonly");
          worker_birth.removeAttribute("readonly");
          worker_passport.removeAttribute("readonly");
          worker_issued.removeAttribute("readonly");
          worker_department_number.removeAttribute("readonly");
          worker_department_address.removeAttribute("readonly");
          worker_requisites.removeAttribute("readonly");
          worker_payment.removeAttribute("readonly");
          worker_tax.removeAttribute("readonly");
          worker_city.removeAttribute("readonly");
          worker_district.removeAttribute("readonly");
          worker_address.removeAttribute("readonly");
          worker_work.removeAttribute("readonly");
          worker_hiring.removeAttribute("readonly");

          // Разблокировка кнопки
          button.removeAttribute("disabled");
        }

        // Инициализация идентификатора сотрудника
        const id = row.querySelector(['span[data-column="worker"]']).innerText;

        // Запуск отсрочки разблокировки на случай, если сервер не отвечает
        const timeout = setTimeout(() => {
          this.errors(["Сервер не отвечает"]);
          unblock();
        }, 5000);

        // Запрос к серверу
        return await fetch(`/worker/${id}/update`, {
          method: "POST",
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
          body:
            `name_first=${worker_name_first.value}&name_second=${worker_name_second.value}&name_last=${worker_name_last.value}&number=${worker_number.mask.unmaskedValue}&mail=${worker_mail.value}&birth=${worker_birth.value}&passport=${worker_passport.value}&issued=${worker_issued.value}&department_number=${worker_department_number.value}&department_address=${worker_department_address.value}&requisites=${worker_requisites.value}&payment=${worker_payment.value}&tax=${worker_tax.value}&city=${worker_city.value}&district=${worker_district.value}&address=${worker_address.value}&work=${worker_work.value}&hiring=${worker_hiring.value}`,
        })
          .then((response) => response.json())
          .then((data) => {
            // Удаление отсрочки разблокировки
            clearTimeout(timeout);

            if (this.errors(data.errors)) {
              // Сгенерированы ошибки

              // Разблокировка полей ввода и кнопок
              unblock();
            } else {
              // Не сгенерированы ошибки (подразумевается их отсутствие)

              if (data.updated === true) {
                // Записаны данные

                // Инициализация буфера списка классов
                // const buffer = [...row.classList];

                // Инициализация статуса активной строки
                const selected = row.getAttribute("data-selected");

                // Реинициализация строки
                row.outerHTML = data.row;

                // Реинициализация строки (выражение странное, но правильное)
                row = document.getElementById(row.getAttribute("id"));

                // Копирование классов из буфера классов удалённой строки
                // row.classList.add(...buffer);

                // Копирование статуса активной строки
                if (
                  typeof selected === "string" &&
                  selected === "true" &&
                  document.body.contains(document.getElementById("popup")) &&
                  !document.body.contains(
                    document.querySelector('[data-selected="true"]'),
                  )
                ) {
                  row.setAttribute("data-selected", "true");
                }
              }

              if (this.body.wrap instanceof HTMLElement) {
                // Найдено активное окно

                // Деинициализация быстрых действий по кнопкам
                document.removeEventListener("keydown", this.buttons);

                // Сброс блокировки
                this.freeze = false;

                // Деинициализация активного окна
                this.body.wrap.remove();

                // Удаление статуса активной строки
                row.removeAttribute("data-selected");
              }
            }
          });
      },
      300,
    );

    /**
     * Сгенерировать окно для редактирования сотрудника
     *
     * @param {HTMLElement} row Строка
     *
     * @return {void}
     */
    static update = damper(async (row) => {
      if (row instanceof HTMLElement) {
        // Получена строка

        // Инициализация идентификатора сотрудника
        const id = row.querySelector(['span[data-column="worker"]']).innerText;

        // Запрос к серверу
        return await fetch(`/worker/${id}/fields`, {
          method: "POST",
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
        })
          .then((response) => response.json())
          .then((data) => {
            // Инициализация буфера выбранных строк
            const buffer = [
              ...document.querySelectorAll('div[data-selected="true"]'),
            ];

            // Удаление статуса активной строки у остальных строк
            for (const element of buffer) {
              element.removeAttribute("data-selected");
            }

            // Инициализация статуса активной строки (обрабатываемой в данный момент)
            row.setAttribute("data-selected", "true");

            // Инициализация оболочки всплывающего окна
            this.body.wrap = document.createElement("div");
            this.body.wrap.setAttribute("id", "popup");

            // Инициализация оболочки всплывающего окна
            const popup = document.createElement("section");
            popup.classList.add("list", "extensive");

            // Инициализация заголовка всплывающего окна
            const title = document.createElement("h3");
            title.innerText = id;

            // Инициализация оболочки с основной информацией
            const main = document.createElement("section");
            main.classList.add("main");

            // Инициализация колонки
            const worker = document.createElement("div");
            worker.classList.add("column");
            worker.setAttribute("data-column", "worker");
            worker.style.setProperty("width", "450px");

            // Инициализация строки
            const worker_name_first = document.createElement("div");
            worker_name_first.classList.add("row", "merged");

            // Инициализация оболочки для строки
            const worker_name_first_label = document.createElement("label");
            worker_name_first_label.setAttribute("id", "worker_first");

            // Инициализация заголовка для поля ввода
            const worker_name_first_title = document.createElement("b");
            worker_name_first_title.classList.add(
              "separated",
              "right",
              "unselectable",
            );
            worker_name_first_title.innerText = "Имя:";

            // Инициализация поля ввода
            const worker_name_first_input = document.createElement("input");
            worker_name_first_input.classList.add("large");
            worker_name_first_input.setAttribute("type", "text");
            worker_name_first_input.setAttribute("name", "first");
            worker_name_first_input.setAttribute("autocomplete", "given-name");
            worker_name_first_input.setAttribute("minlength", "0");
            worker_name_first_input.setAttribute("maxlength", "100");
            worker_name_first_input.setAttribute("title", "Имя сотрудника");
            worker_name_first_input.setAttribute("placeholder", "Иван");
            worker_name_first_input.value = data.name.first ?? "";

            // Инициализация строки
            const worker_name_second = document.createElement("div");
            worker_name_second.classList.add("row", "merged");

            // Инициализация оболочки для строки
            const worker_name_second_label = document.createElement("label");
            worker_name_second_label.setAttribute("id", "worker_second");

            // Инициализация заголовка для поля ввода
            const worker_name_second_title = document.createElement("b");
            worker_name_second_title.classList.add(
              "separated",
              "right",
              "unselectable",
            );
            worker_name_second_title.innerText = "Фамилия:";

            // Инициализация поля ввода
            const worker_name_second_input = document.createElement("input");
            worker_name_second_input.classList.add("large");
            worker_name_second_input.setAttribute(
              "autocomplete",
              "family-name",
            );
            worker_name_second_input.setAttribute("name", "second");
            worker_name_second_input.setAttribute("type", "text");
            worker_name_second_input.setAttribute("minlength", "0");
            worker_name_second_input.setAttribute("maxlength", "100");
            worker_name_second_input.setAttribute(
              "title",
              "Фамилия сотрудника",
            );
            worker_name_second_input.setAttribute("placeholder", "Иванов");
            worker_name_second_input.value = data.name.second ?? "";

            // Инициализация строки
            const worker_name_last = document.createElement("div");
            worker_name_last.classList.add("row", "merged");

            // Инициализация оболочки для строки
            const worker_name_last_label = document.createElement("label");
            worker_name_last_label.setAttribute("id", "worker_last");

            // Инициализация заголовка для поля ввода
            const worker_name_last_title = document.createElement("b");
            worker_name_last_title.classList.add(
              "separated",
              "right",
              "unselectable",
            );
            worker_name_last_title.innerText = "Отчество:";

            // Инициализация поля ввода
            const worker_name_last_input = document.createElement("input");
            worker_name_last_input.classList.add("large");
            worker_name_last_input.setAttribute("name", "last");
            worker_name_last_input.setAttribute(
              "autocomplete",
              "additional-name",
            );
            worker_name_last_input.setAttribute("type", "text");
            worker_name_last_input.setAttribute("minlength", "0");
            worker_name_last_input.setAttribute("maxlength", "100");
            worker_name_last_input.setAttribute(
              "title",
              "Отчество/Матчество сотрудника",
            );
            worker_name_last_input.setAttribute("placeholder", "Иванович");
            worker_name_last_input.value = data.name.last ?? "";

            // Инициализация строки
            const worker_number = document.createElement("div");
            worker_number.classList.add("row", "merged", "divided");

            // Инициализация оболочки для строки
            const worker_number_label = document.createElement("label");
            worker_number_label.setAttribute("id", "worker_number");

            // Инициализация заголовка для поля ввода
            const worker_number_title = document.createElement("b");
            worker_number_title.classList.add(
              "separated",
              "right",
              "unselectable",
            );
            worker_number_title.innerText = "SIM-номер:";

            // Инициализация поля ввода
            const worker_number_input = document.createElement("input");
            worker_number_input.classList.add("large");
            worker_number_input.setAttribute("name", "sim-number");
            worker_number_input.setAttribute("autocomplete", "tel");
            worker_number_input.setAttribute("type", "text");
            worker_number_input.setAttribute("minlength", "18");
            worker_number_input.setAttribute("maxlength", "18");
            worker_number_input.setAttribute("title", "SIM-номер сотрудника");
            worker_number_input.setAttribute(
              "placeholder",
              "+7 (000) 000-00-00",
            );
            worker_number_input.setAttribute("required", "true");
            worker_number_input.value = data.number ?? "";

            // Инициализация строки
            const worker_mail = document.createElement("div");
            worker_mail.classList.add("row", "merged");

            // Инициализация оболочки для строки
            const worker_mail_label = document.createElement("label");
            worker_mail_label.setAttribute("id", "worker_mail");

            // Инициализация заголовка для поля ввода
            const worker_mail_title = document.createElement("b");
            worker_mail_title.classList.add(
              "separated",
              "right",
              "unselectable",
            );
            worker_mail_title.innerText = "Почта:";

            // Инициализация поля ввода
            const worker_mail_input = document.createElement("input");
            worker_mail_input.classList.add("large");
            worker_mail_input.setAttribute("name", "mail");
            worker_mail_input.setAttribute("autocomplete", "email");
            worker_mail_input.setAttribute("type", "text");
            worker_mail_input.setAttribute("minlength", "3");
            worker_mail_input.setAttribute("maxlength", "300");
            worker_mail_input.setAttribute("title", "Почта сотрудника");
            worker_mail_input.setAttribute("placeholder", "name@server");
            worker_mail_input.value = data.mail ?? "";

            // Инициализация строки
            const worker_birth = document.createElement("div");
            worker_birth.classList.add("row", "divided");

            // Инициализация оболочки для строки
            const worker_birth_label = document.createElement("label");
            worker_birth_label.setAttribute("id", "worker_birth");

            // Инициализация заголовка для поля ввода
            const worker_birth_title = document.createElement("b");
            worker_birth_title.classList.add("separated", "right");
            worker_birth_title.innerText = "Дата рождения:";

            // Инициализация поля ввода
            const worker_birth_input = document.createElement("input");
            worker_birth_input.classList.add("large");
            worker_birth_input.setAttribute("autocomplete", "bday");
            worker_birth_input.setAttribute("name", "birth");
            worker_birth_input.setAttribute("type", "date");
            worker_birth_input.setAttribute(
              "title",
              "Дата рождения сотрудника",
            );
            if (typeof data.birth === "number") {
              worker_birth_input.valueAsDate = new Date(data.birth * 1000);
            }

            // Инициализация строки
            const worker_passport = document.createElement("div");
            worker_passport.classList.add("row", "merged", "divided");

            // Инициализация оболочки для строки
            const worker_passport_label = document.createElement("label");
            worker_passport_label.setAttribute("id", "worker_passport");

            // Инициализация заголовка для поля ввода
            const worker_passport_title = document.createElement("b");
            worker_passport_title.classList.add("separated", "right");
            worker_passport_title.innerText = "Паспорт:";

            // Инициализация поля ввода
            const worker_passport_input = document.createElement("input");
            worker_passport_input.classList.add("large");
            worker_passport_input.setAttribute("autocomplete", "on");
            worker_passport_input.setAttribute("name", "passport");
            worker_passport_input.setAttribute("type", "text");
            worker_passport_input.setAttribute("minlength", "0");
            worker_passport_input.setAttribute("maxlength", "11");
            worker_passport_input.setAttribute(
              "title",
              "Номер паспорта сотрудника",
            );
            worker_passport_input.setAttribute("placeholder", "0000 000000");
            worker_passport_input.value = data.passport ?? "";

            // Инициализация строки
            const worker_issued = document.createElement("div");
            worker_issued.classList.add("row", "merged");

            // Инициализация оболочки для строки
            const worker_issued_label = document.createElement("label");
            worker_issued_label.setAttribute("id", "worker_issued");

            // Инициализация заголовка для поля ввода
            const worker_issued_title = document.createElement("b");
            worker_issued_title.classList.add("separated", "right");
            worker_issued_title.innerText = "Дата выдачи:";

            // Инициализация поля ввода
            const worker_issued_input = document.createElement("input");
            worker_issued_input.classList.add("large");
            worker_issued_input.setAttribute("autocomplete", "on");
            worker_issued_input.setAttribute("name", "issued");
            worker_issued_input.setAttribute("type", "date");
            worker_issued_input.setAttribute(
              "title",
              "Дата выдачи паспорта сотрудника",
            );
            if (typeof data.issued === "number") {
              worker_issued_input.valueAsDate = new Date(data.issued * 1000);
            }

            // Инициализация строки
            const worker_department_number = document.createElement("div");
            worker_department_number.classList.add("row", "merged");

            // Инициализация оболочки для строки
            const worker_department_number_label = document.createElement(
              "label",
            );
            worker_department_number_label.setAttribute(
              "id",
              "worker_department_number",
            );

            // Инициализация заголовка для поля ввода
            const worker_department_number_title = document.createElement("b");
            worker_department_number_title.classList.add("separated", "right");
            worker_department_number_title.innerText = "Отделение:";

            // Инициализация поля ввода
            const worker_department_number_input = document.createElement(
              "input",
            );
            worker_department_number_input.classList.add("large");
            worker_department_number_input.setAttribute("autocomplete", "on");
            worker_department_number_input.setAttribute("name", "department");
            worker_department_number_input.setAttribute("type", "text");
            worker_department_number_input.setAttribute("minlength", "0");
            worker_department_number_input.setAttribute("maxlength", "7");
            worker_department_number_input.setAttribute(
              "title",
              "Номер отделения выдавшего паспорт сотруднику",
            );
            worker_department_number_input.setAttribute(
              "placeholder",
              "000-000",
            );
            worker_department_number_input.value = data.department.number ?? "";

            // Инициализация строки
            const worker_department_address = document.createElement("div");
            worker_department_address.classList.add("row", "merged");

            // Инициализация оболочки для строки
            const worker_department_address_label = document.createElement(
              "label",
            );
            worker_department_address_label.setAttribute(
              "id",
              "worker_department_address",
            );

            // Инициализация заголовка для поля ввода
            const worker_department_address_title = document.createElement("b");
            worker_department_address_title.classList.add("separated", "right");
            worker_department_address_title.innerText = "Адрес отделения:";

            // Инициализация поля ввода
            const worker_department_address_input = document.createElement(
              "input",
            );
            worker_department_address_input.classList.add("large");
            worker_department_address_input.setAttribute("autocomplete", "on");
            worker_department_address_input.setAttribute(
              "name",
              "department_2",
            );
            worker_department_address_input.setAttribute("type", "text");
            worker_department_address_input.setAttribute("minlength", "0");
            worker_department_address_input.setAttribute("maxlength", "150");
            worker_department_address_input.setAttribute(
              "title",
              "Адрес отделения выдавшего паспорт сотруднику",
            );
            worker_department_address_input.setAttribute(
              "placeholder",
              "ОФМС России по ...",
            );
            worker_department_address_input.value = data.department.address ??
              "";

            // Инициализация строки
            const worker_requisites = document.createElement("div");
            worker_requisites.classList.add("row", "merged", "divided");

            // Инициализация оболочки для строки
            const worker_requisites_label = document.createElement("label");
            worker_requisites_label.setAttribute("id", "worker_requisites");

            // Инициализация заголовка для поля ввода
            const worker_requisites_title = document.createElement("b");
            worker_requisites_title.classList.add("separated", "right");
            worker_requisites_title.innerText = "Реквизиты:";

            // Инициализация поля ввода
            const worker_requisites_input = document.createElement("input");
            worker_requisites_input.classList.add("large");
            worker_requisites_input.setAttribute("autocomplete", "cc-number");
            worker_requisites_input.setAttribute("name", "requisites");
            worker_requisites_input.setAttribute("type", "text");
            worker_requisites_input.setAttribute("minlength", "0");
            worker_requisites_input.setAttribute("maxlength", "250");
            worker_requisites_input.setAttribute(
              "title",
              "0000 0000 0000 0000 Банк Иванов И.",
            );
            worker_requisites_input.setAttribute(
              "placeholder",
              "0000 0000 0000 0000 Банк Иванов И.",
            );
            worker_requisites_input.value = data.requisites ?? "";

            // Инициализация строки
            const worker_payment = document.createElement("div");
            worker_payment.classList.add("row", "merged");

            // Инициализация оболочки для строки
            const worker_payment_label = document.createElement("label");
            worker_payment_label.setAttribute("id", "worker_payment");

            // Инициализация заголовка для поля ввода
            const worker_payment_title = document.createElement("b");
            worker_payment_title.classList.add("separated", "right");
            worker_payment_title.innerText = "Форма оплаты:";

            // Инициализация поля ввода
            const worker_payment_input = document.createElement("input");
            worker_payment_input.classList.add("large");
            worker_payment_input.setAttribute("autocomplete", "off");
            worker_payment_input.setAttribute("name", "payment");
            worker_payment_input.setAttribute("type", "text");
            worker_payment_input.setAttribute("minlength", "0");
            worker_payment_input.setAttribute("maxlength", "80");
            worker_payment_input.setAttribute(
              "title",
              "Форма оплаты сотруднику",
            );
            worker_payment_input.setAttribute(
              "placeholder",
              "Перевод на карту",
            );
            worker_payment_input.setAttribute("value", "Перевод на карту");
            worker_payment_input.value = data.payment ?? "";

            // Инициализация строки
            const worker_tax = document.createElement("div");
            worker_tax.classList.add("row", "merged");

            // Инициализация оболочки для строки
            const worker_tax_label = document.createElement("label");
            worker_tax_label.setAttribute("id", "worker_tax");

            // Инициализация заголовка для поля ввода
            const worker_tax_title = document.createElement("b");
            worker_tax_title.classList.add("separated", "right");
            worker_tax_title.innerText = "ИНН:";

            // Инициализация поля ввода
            const worker_tax_input = document.createElement("input");
            worker_tax_input.classList.add("large");
            worker_tax_input.setAttribute("autocomplete", "on");
            worker_tax_input.setAttribute("name", "tax");
            worker_tax_input.setAttribute("type", "text");
            worker_tax_input.setAttribute("minlength", "0");
            worker_tax_input.setAttribute("maxlength", "12");
            worker_tax_input.setAttribute(
              "title",
              "Индивидуальный налоговый номер сотрудника",
            );
            worker_tax_input.setAttribute("placeholder", "000000000000");
            worker_tax_input.value = data.tax ?? "";

            // Инициализация строки
            const worker_city = document.createElement("div");
            worker_city.classList.add("row", "merged", "divided");

            // Инициализация оболочки для выпадающего списка
            const worker_city_label = document.createElement("label");
            worker_city_label.setAttribute("id", "worker_city");

            // Инициализация заголовка для выпадающего списка
            const worker_city_title = document.createElement("b");
            worker_city_title.classList.add("separated", "right");
            worker_city_title.innerText = "Город:";

            // Инициализация выпадающего списка
            const worker_city_select = document.createElement("select");
            worker_city_select.classList.add("large");
            worker_city_select.setAttribute("autocomplete", "address-level2");
            worker_city_select.setAttribute("name", "city");
            worker_city_select.setAttribute(
              "title",
              "Город проживания сотрудника",
            );
            worker_city_select.value = data.city ?? "";

            // Инициализация варианта для выбора
            const worker_city_option_1 = document.createElement("option");
            worker_city_option_1.setAttribute("value", "Красноярск");
            worker_city_option_1.innerText = "Красноярск";

            // Инициализация варианта для выбора
            const worker_city_option_2 = document.createElement("option");
            worker_city_option_2.setAttribute("value", "Железногорск");
            worker_city_option_2.innerText = "Железногорск";

            /*
						// Инициализация варианта для выбора
						const worker_city_option_3 = document.createElement("option");
						worker_city_option_3.classList.add("value", "");
						worker_city_option_3.innerText = "";

						// Инициализация варианта для выбора
						const worker_city_option_4 = document.createElement("option");
						worker_city_option_4.classList.add("value", "");
						worker_city_option_4.innerText = "";

						// Инициализация варианта для выбора
						const worker_city_option_5 = document.createElement("option");
						worker_city_option_5.classList.add("value", "");
						worker_city_option_5.innerText = "";

						// Инициализация варианта для выбора
						const worker_city_option_ = document.createElement("option");
						worker_city_option_.classList.add("value", "");
						worker_city_option_.innerText = ""; */

            // Инициализация строки
            const worker_district = document.createElement("div");
            worker_district.classList.add("row", "merged");

            // Инициализация оболочки для строки
            const worker_district_label = document.createElement("label");
            worker_district_label.setAttribute("id", "worker_district");

            // Инициализация заголовка для поля ввода
            const worker_district_title = document.createElement("b");
            worker_district_title.classList.add("separated", "right");
            worker_district_title.innerText = "Регион:";

            // Инициализация поля ввода
            const worker_district_input = document.createElement("input");
            worker_district_input.classList.add("large");
            worker_district_input.setAttribute(
              "autocomplete",
              "address-level3",
            );
            worker_district_input.setAttribute("name", "district");
            worker_district_input.setAttribute("type", "text");
            worker_district_input.setAttribute("minlength", "0");
            worker_district_input.setAttribute("maxlength", "80");
            worker_district_input.setAttribute(
              "title",
              "Регион проживания сотрудника",
            );
            worker_district_input.setAttribute("placeholder", "Центральный");
            worker_district_input.value = data.district ?? "";

            // Инициализация строки
            const worker_address = document.createElement("div");
            worker_address.classList.add("row", "merged");

            // Инициализация оболочки для строки
            const worker_address_label = document.createElement("label");
            worker_address_label.setAttribute("id", "worker_address");

            // Инициализация заголовка для поля ввода
            const worker_address_title = document.createElement("b");
            worker_address_title.classList.add("separated", "right");
            worker_address_title.innerText = "Адрес:";

            // Инициализация поля ввода
            const worker_address_input = document.createElement("input");
            worker_address_input.classList.add("large");
            worker_address_input.setAttribute("autocomplete", "street-address");
            worker_address_input.setAttribute("name", "address");
            worker_address_input.setAttribute("type", "text");
            worker_address_input.setAttribute("minlength", "0");
            worker_address_input.setAttribute("maxlength", "150");
            worker_address_input.setAttribute(
              "title",
              "Адрес проживания сотрудника",
            );
            worker_address_input.setAttribute("placeholder", "ул. Пушкина 7");
            worker_address_input.value = data.address ?? "";

            // Инициализация строки
            const worker_work = document.createElement("div");
            worker_work.classList.add("row", "merged", "divided");

            // Инициализация оболочки для строки
            const worker_work_label = document.createElement("label");
            worker_work_label.setAttribute("id", "worker_address");

            // Инициализация заголовка для поля ввода
            const worker_work_title = document.createElement("b");
            worker_work_title.classList.add("separated", "right");
            worker_work_title.innerText = "Тип работы:";

            // Инициализация поля ввода
            const worker_work_select = document.createElement("select");
            worker_work_select.classList.add("large");
            worker_work_select.setAttribute("title", "Тип работы сотрудника");
            this.works(id).then(
              (html) => (worker_work_select.innerHTML = html),
            );

            // Инициализация строки
            const worker_hiring = document.createElement("div");
            worker_hiring.classList.add("row", "merged");

            // Инициализация оболочки для строки
            const worker_hiring_label = document.createElement("label");
            worker_hiring_label.setAttribute("id", "worker_hiring");

            // Инициализация заголовка для поля ввода
            const worker_hiring_title = document.createElement("b");
            worker_hiring_title.classList.add("separated", "right");
            worker_hiring_title.innerText = "Дата найма:";

            // Инициализация поля ввода
            const worker_hiring_input = document.createElement("input");
            worker_hiring_input.classList.add("large");
            worker_hiring_input.setAttribute("autocomplete", "off");
            worker_hiring_input.setAttribute("name", "hiring");
            worker_hiring_input.setAttribute("type", "date");
            worker_hiring_input.setAttribute("onkeypress", ``);
            worker_hiring_input.setAttribute("title", "Дата найма");
            if (typeof data.hiring === "number") {
              worker_hiring_input.valueAsDate = new Date(data.hiring * 1000);
            }

            // Инициализация строки
            const worker_buttons = document.createElement("div");
            worker_buttons.classList.add("row", "divided", "buttons");

            // Инициализация кнопки подтверждения даты
            const worker_update_button = document.createElement("button");
            worker_update_button.classList.add("grass", "stretched");
            worker_update_button.innerText = "Сохранить";
            worker_update_button.setAttribute(
              "onclick",
              `workers._update(document.getElementById(${
                row.getAttribute("id") ?? ""
              }), this, ...this.parentElement.parentElement.parentElement.parentElement.querySelectorAll(':is(select, input, textarea)'))`,
            );

            // Инициализация кнопки увольнения
            const worker_fire_button = document.createElement("button");
            if (row.classList.contains("fired")) {
              // Уволен

              worker_fire_button.classList.add("grass");
              worker_fire_button.innerText = "Нанять";
              worker_fire_button.setAttribute(
                "onclick",
                `workers._hire(document.getElementById(${
                  row.getAttribute("id") ?? ""
                }), this, ...this.parentElement.parentElement.parentElement.parentElement.querySelectorAll(':is(select, input, textarea)'))`,
              );
            } else {
              // Не уволен

              worker_fire_button.classList.add("clay");
              worker_fire_button.innerText = "Уволить";
              worker_fire_button.setAttribute(
                "onclick",
                `workers._fire(document.getElementById(${
                  row.getAttribute("id") ?? ""
                }), this, ...this.parentElement.parentElement.parentElement.parentElement.querySelectorAll(':is(select, input, textarea)'))`,
              );
            }

            // Инициализация окна с ошибками
            this.body.errors = document.createElement("section");
            this.body.errors.classList.add(
              "errors",
              "window",
              "list",
              "calculated",
              "hidden",
            );
            this.body.errors.setAttribute("data-errors", true);

            // Инициализация элемента-тела (оболочки) окна с ошибками
            const errors = document.createElement("section");
            errors.classList.add("body");

            // Инициализация элемента-списка ошибок
            const dl = document.createElement("dl");

            // Инициализация активного всплывающего окна
            const old = document.getElementById("popup");

            if (old instanceof HTMLElement) {
              // Найдено активное окно

              // Деинициализация быстрых действий по кнопкам
              document.removeEventListener("keydown", this.buttons);

              // Сброс блокировки
              this.freeze = false;

              // Удаление активного окна
              old.remove();
            }

            // Запись в документ
            popup.appendChild(title);

            worker_name_first_label.appendChild(worker_name_first_title);
            worker_name_first_label.appendChild(worker_name_first_input);
            worker_name_first.appendChild(worker_name_first_label);
            worker.appendChild(worker_name_first);

            worker_name_second_label.appendChild(worker_name_second_title);
            worker_name_second_label.appendChild(worker_name_second_input);
            worker_name_second.appendChild(worker_name_second_label);
            worker.appendChild(worker_name_second);

            worker_name_last_label.appendChild(worker_name_last_title);
            worker_name_last_label.appendChild(worker_name_last_input);
            worker_name_last.appendChild(worker_name_last_label);
            worker.appendChild(worker_name_last);

            worker_number_label.appendChild(worker_number_title);
            worker_number_label.appendChild(worker_number_input);
            worker_number.appendChild(worker_number_label);
            worker.appendChild(worker_number);

            worker_mail_label.appendChild(worker_mail_title);
            worker_mail_label.appendChild(worker_mail_input);
            worker_mail.appendChild(worker_mail_label);
            worker.appendChild(worker_mail);

            worker_birth_label.appendChild(worker_birth_title);
            worker_birth_label.appendChild(worker_birth_input);
            worker_birth.appendChild(worker_birth_label);
            worker.appendChild(worker_birth);

            worker_passport_label.appendChild(worker_passport_title);
            worker_passport_label.appendChild(worker_passport_input);
            worker_passport.appendChild(worker_passport_label);
            worker.appendChild(worker_passport);

            worker_issued_label.appendChild(worker_issued_title);
            worker_issued_label.appendChild(worker_issued_input);
            worker_issued.appendChild(worker_issued_label);
            worker.appendChild(worker_issued);

            worker_department_number_label.appendChild(
              worker_department_number_title,
            );
            worker_department_number_label.appendChild(
              worker_department_number_input,
            );
            worker_department_number.appendChild(
              worker_department_number_label,
            );
            worker.appendChild(worker_department_number);

            worker_department_address_label.appendChild(
              worker_department_address_title,
            );
            worker_department_address_label.appendChild(
              worker_department_address_input,
            );
            worker_department_address.appendChild(
              worker_department_address_label,
            );
            worker.appendChild(worker_department_address);

            worker_requisites_label.appendChild(worker_requisites_title);
            worker_requisites_label.appendChild(worker_requisites_input);
            worker_requisites.appendChild(worker_requisites_label);
            worker.appendChild(worker_requisites);

            worker_payment_label.appendChild(worker_payment_title);
            worker_payment_label.appendChild(worker_payment_input);
            worker_payment.appendChild(worker_payment_label);
            worker.appendChild(worker_payment);

            worker_tax_label.appendChild(worker_tax_title);
            worker_tax_label.appendChild(worker_tax_input);
            worker_tax.appendChild(worker_tax_label);
            worker.appendChild(worker_tax);

            worker_city_label.appendChild(worker_city_title);
            worker_city_select.appendChild(worker_city_option_1);
            worker_city_select.appendChild(worker_city_option_2);
            worker_city_label.appendChild(worker_city_select);
            worker_city.appendChild(worker_city_label);
            worker.appendChild(worker_city);

            worker_district_label.appendChild(worker_district_title);
            worker_district_label.appendChild(worker_district_input);
            worker_district.appendChild(worker_district_label);
            worker.appendChild(worker_district);

            worker_address_label.appendChild(worker_address_title);
            worker_address_label.appendChild(worker_address_input);
            worker_address.appendChild(worker_address_label);
            worker.appendChild(worker_address);

            worker_work_label.appendChild(worker_work_title);
            worker_work_label.appendChild(worker_work_select);
            worker_work.appendChild(worker_work_label);
            worker.appendChild(worker_work);

            worker_hiring_label.appendChild(worker_hiring_title);
            worker_hiring_label.appendChild(worker_hiring_input);
            worker_hiring.appendChild(worker_hiring_label);
            worker.appendChild(worker_hiring);

            worker_buttons.appendChild(worker_update_button);
            worker_buttons.appendChild(worker_fire_button);
            worker.appendChild(worker_buttons);

            main.appendChild(worker);

            popup.appendChild(main);
            this.body.wrap.appendChild(popup);

            errors.appendChild(dl);
            this.body.errors.appendChild(errors);
            this.body.wrap.appendChild(this.body.errors);

            document.body.appendChild(this.body.wrap);

            // Инициализация ширины окна с ошибками
            this.body.errors.style.setProperty(
              "--calculated-width",
              popup.offsetWidth + "px",
            );

            // Инициалиация масок
            worker_number_input.mask = IMask(worker_number_input, {
              mask: "+{7} (000) 000-00-00",
            });
            worker_passport_input.mask = IMask(worker_passport_input, {
              mask: "0000 000000",
            });
            worker_department_number_input.mask = IMask(
              worker_department_number_input,
              {
                mask: "000-000",
              },
            );
            worker_requisites_input.mask = IMask(worker_requisites_input, {
              mask: "0000 0000 0000 0000 bank second first",
              blocks: {
                bank: {
                  mask: /^[А-яA-z\d]+$/,
                  prepareChar: (str, masked) =>
                    masked.value.length === 0 ? str.toUpperCase() : str,
                },
                second: {
                  mask: /^[А-яA-z\d]+$/,
                  prepareChar: (str, masked) =>
                    masked.value.length === 0 ? str.toUpperCase() : str,
                },
                first: {
                  mask: "a.",
                  prepareChar: (str) => str.toUpperCase(),
                },
              },
            });
            worker_tax_input.mask = IMask(worker_tax_input, {
              mask: "000000000000",
            });

            // Инициализация переменных для окна с ошибками (12 - это значение gap из div#popup)
            function top(errors) {
              errors.style.setProperty("transition", "0s");
              errors.style.setProperty(
                "--top",
                popup.offsetTop + popup.offsetHeight + 12 + "px",
              );
              setTimeout(() => errors.style.removeProperty("transition"), 100);
            }
            top(this.body.errors);
            const resize = new ResizeObserver(() => top(this.body.errors));
            resize.observe(this.body.wrap);

            // Инициализация функции блокировки кнопки
            const block = (e) => {
              // Игнорировать нажатие кнопки "enter"
              if (e instanceof Event && e.keyCode === 13) return;

              if (worker_number_input.value.length === 18) {
                worker_number_input.removeAttribute("disabled");
              } else worker_number_input.setAttribute("disabled", "true");
            };

            // Добавление функции блокировки кнопки по событиям
            worker_number_input.addEventListener("keyup", block);

            // Первичная активация функции блокировки кнопки
            block();

            // Инициализация функции закрытия всплывающего окна
            const click = () => {
              // Блокировка
              if (this.freeze) return;

              // Удаление всплывающего окна
              this.body.wrap.remove();

              // Инициализация буфера выбранных строк
              const buffer = [
                ...document.querySelectorAll('div[data-selected="true"]'),
              ];

              // Удаление статуса активной строки у остальных строк
              for (const element of buffer) {
                element.removeAttribute("data-selected");
              }

              // Деинициализация быстрых действий по кнопкам
              document.removeEventListener("keydown", this.buttons);

              // Сброс блокировки
              this.freeze = false;
            };

            // Инициализация функции добавления функции закрытия всплывающего окна
            const enable = () =>
              this.body.wrap.addEventListener("click", click);

            // Инициализация функции удаления функции закрытия всплывающего окна
            const disable = () =>
              this.body.wrap.removeEventListener("click", click);

            // Первичная активация функции удаления всплывающего окна
            enable();

            // Инициализация блокировки удаления окна при взаимодействии с select-элементом
            for (const select of popup.getElementsByTagName("select")) {
              // Перебор всех select-элементов

              // Инициализация функции блокировки удаления окна по событию
              select.addEventListener("click", () => {
                // Блокировка удаления окна
                this.freeze = true;

                // Разблокировка удаления окна
                setTimeout(() => (this.freeze = false), 100);
              });

              for (const option of select.getElementsByTagName("option")) {
                // Перебор всех option-элементов

                // Инициализация функции блокировки удаления окна по событию
                option.addEventListener("click", () => {
                  // Блокировка удаления окна
                  this.freeze = true;

                  // Разблокировка удаления окна
                  setTimeout(() => (this.freeze = false), 100);
                });
              }
            }

            // Инициализация блокировки удаления окна при взаимодействии с textarea-элементом
            for (const textarea of popup.getElementsByTagName("textarea")) {
              // Перебор всех textarea-элементов

              // Обновлять позицию окна с ошибками при изменении размера textarea (там position: absolute)
              new MutationObserver(() => top(this.body.errors)).observe(
                textarea,
                {
                  attributes: true,
                  attributeFilter: ["style"],
                },
              );

              // Инициализация функции игнорирования блокировки для выбранных кнопок
              textarea.addEventListener("keydown", (e) => {
                if (e.keyCode === 27) {
                  // Нажата кнопка: "escape"

                  // Вызов глобальной функции управления кнопками
                  this.buttons(e, true);
                } else if (e.ctrlKey && e.keyCode === 13) {
                  // Нажаты кнопки: "control", "enter"

                  // Вызов глобальной функции управления кнопками
                  this.buttons(e, true);
                }
              });

              // Добавление функции блокировки удаления окна и клавиш по событиям
              textarea.addEventListener("focus", () => (this.freeze = true));
              textarea.addEventListener(
                "focusout",
                () => (this.freeze = false),
              );
            }

            // Инициализация функции управления кнопками
            this.buttons = (e, force = false) => {
              // Блокировка
              if (!force && this.freeze) return;

              if (e.keyCode === 27) {
                // Нажата кнопка: "escape"

                // Удаление окна
                click();
              } else if (event.keyCode === 13) {
                // Нажата кнопка: "enter"

                // Инициализация буфера с текущим статусом блокировки закрытия окна
                const freeze = this.freeze;

                // Блокировка закрытия окна (чтобы не вызвался click() через событие onclick)
                this.freeze = true;

                // Активация виртуальной кнопки "сохранить"
                worker_update_button.click();

                // Возвращение статуса блокировки закрытия окна
                this.freeze = freeze;
              }
            };

            // Инициализация быстрых действий по кнопкам
            document.addEventListener("keydown", this.buttons);

            // Инициализация функции удаления всплывающего окна по событиям
            popup.addEventListener("mouseenter", disable);
            popup.addEventListener("mouseleave", enable);

            // Фокусировка
            worker_name_first_input.focus();
          });
      }
    }, 300);

    /**
     * Уволить сотрудника (вызов демпфера)
     *
     * @param {HTMLElement} row Строка <div>
     * @param {HTMLElement} button Кнопка <button>
     * @param {HTMLElement} worker_name_first Имя сотрудника <input>
     * @param {HTMLElement} worker_name_second Фамилия сотрудника <input>
     * @param {HTMLElement} worker_name_last Отчество сотрудника <input>
     * @param {HTMLElement} worker_number SIM-номер сотрудника <input>
     * @param {HTMLElement} worker_mail Почта сотрудника <input>
     * @param {HTMLElement} worker_birth Дата рождения сотрудника <input>
     * @param {HTMLElement} worker_passport Номер паспорта сотрудника <input>
     * @param {HTMLElement} worker_issued Дата выдачи паспорта сотрудника <input>
     * @param {HTMLElement} worker_department_number Номер отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_department_address Адрес отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_requisites Реквизиты: "0000 0000 0000 0000 Банк Иванов И." <input>
     * @param {HTMLElement} worker_payment Форма оплаты сотруднику <input>
     * @param {HTMLElement} worker_tax Индивидуальный налоговый номер сотрудника <input>
     * @param {HTMLElement} worker_city Город проживания сотрудника <select>
     * @param {HTMLElement} worker_district Регион проживания сотрудника <input>
     * @param {HTMLElement} worker_address Адрес проживания сотрудника <input>
     * @param {HTMLElement} worker_work Тип работы сотрудника <select>
     * @param {HTMLElement} worker_hiring Дата найма сотрудника <input>
     *
     * @return {void}
     */
    static _fire(
      row,
      button,
      worker_name_first,
      worker_name_second,
      worker_name_last,
      worker_number,
      worker_mail,
      worker_birth,
      worker_passport,
      worker_issued,
      worker_department_number,
      worker_department_address,
      worker_requisites,
      worker_payment,
      worker_tax,
      worker_city,
      worker_district,
      worker_address,
      worker_work,
      worker_hiring,
    ) {
      // Блокировка полей ввода
      worker_name_first.setAttribute("readonly", true);
      worker_name_second.setAttribute("readonly", true);
      worker_name_last.setAttribute("readonly", true);
      worker_number.setAttribute("readonly", true);
      worker_mail.setAttribute("readonly", true);
      worker_birth.setAttribute("readonly", true);
      worker_passport.setAttribute("readonly", true);
      worker_issued.setAttribute("readonly", true);
      worker_department_number.setAttribute("readonly", true);
      worker_department_address.setAttribute("readonly", true);
      worker_requisites.setAttribute("readonly", true);
      worker_payment.setAttribute("readonly", true);
      worker_tax.setAttribute("readonly", true);
      worker_city.setAttribute("readonly", true);
      worker_district.setAttribute("readonly", true);
      worker_address.setAttribute("readonly", true);
      worker_work.setAttribute("readonly", true);
      worker_hiring.setAttribute("readonly", true);

      // Блокировка кнопки
      button.setAttribute("disabled", true);

      // Запуск выполнения
      this.__fire(
        row,
        button,
        worker_name_first,
        worker_name_second,
        worker_name_last,
        worker_number,
        worker_mail,
        worker_birth,
        worker_passport,
        worker_issued,
        worker_department_number,
        worker_department_address,
        worker_requisites,
        worker_payment,
        worker_tax,
        worker_city,
        worker_district,
        worker_address,
        worker_work,
        worker_hiring,
      );
    }

    /**
     * Уволить сотрудника (демпфер)
     *
     * @param {HTMLElement} row Строка <div>
     * @param {HTMLElement} worker_name_first Имя сотрудника <input>
     * @param {HTMLElement} worker_name_second Фамилия сотрудника <input>
     * @param {HTMLElement} worker_name_last Отчество сотрудника <input>
     * @param {HTMLElement} worker_number SIM-номер сотрудника <input>
     * @param {HTMLElement} worker_mail Почта сотрудника <input>
     * @param {HTMLElement} worker_birth Дата рождения сотрудника <input>
     * @param {HTMLElement} worker_passport Номер паспорта сотрудника <input>
     * @param {HTMLElement} worker_issued Дата выдачи паспорта сотрудника <input>
     * @param {HTMLElement} worker_department_number Номер отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_department_address Адрес отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_requisites Реквизиты: "0000 0000 0000 0000 Банк Иванов И." <input>
     * @param {HTMLElement} worker_payment Форма оплаты сотруднику <input>
     * @param {HTMLElement} worker_tax Индивидуальный налоговый номер сотрудника <input>
     * @param {HTMLElement} worker_city Город проживания сотрудника <select>
     * @param {HTMLElement} worker_district Регион проживания сотрудника <input>
     * @param {HTMLElement} worker_address Адрес проживания сотрудника <input>
     * @param {HTMLElement} worker_work Тип работы сотрудника <select>
     * @param {HTMLElement} worker_hiring Дата найма сотрудника <input>
     *
     * @return {void}
     */
    static __fire = damper(
      async (
        row,
        button,
        worker_name_first,
        worker_name_second,
        worker_name_last,
        worker_number,
        worker_mail,
        worker_birth,
        worker_passport,
        worker_issued,
        worker_department_number,
        worker_department_address,
        worker_requisites,
        worker_payment,
        worker_tax,
        worker_city,
        worker_district,
        worker_address,
        worker_work,
        worker_hiring,
      ) => {
        // Инициализация функции разблокировки
        function unblock() {
          // Разблокировка полей ввода
          worker_name_first.removeAttribute("readonly");
          worker_name_second.removeAttribute("readonly");
          worker_name_last.removeAttribute("readonly");
          worker_number.removeAttribute("readonly");
          worker_mail.removeAttribute("readonly");
          worker_birth.removeAttribute("readonly");
          worker_passport.removeAttribute("readonly");
          worker_issued.removeAttribute("readonly");
          worker_department_number.removeAttribute("readonly");
          worker_department_address.removeAttribute("readonly");
          worker_requisites.removeAttribute("readonly");
          worker_payment.removeAttribute("readonly");
          worker_tax.removeAttribute("readonly");
          worker_city.removeAttribute("readonly");
          worker_district.removeAttribute("readonly");
          worker_address.removeAttribute("readonly");
          worker_work.removeAttribute("readonly");
          worker_hiring.removeAttribute("readonly");

          // Разблокировка кнопки
          button.removeAttribute("disabled");
        }

        // Инициализация идентификатора сотрудника
        const id = row.querySelector(['span[data-column="worker"]']).innerText;

        // Запуск отсрочки разблокировки на случай, если сервер не отвечает
        const timeout = setTimeout(() => {
          this.errors(["Сервер не отвечает"]);
          unblock();
        }, 5000);

        // Запрос к серверу
        return await fetch(`/worker/${id}/fire`, {
          method: "POST",
        })
          .then((response) => response.json())
          .then((data) => {
            // Удаление отсрочки разблокировки
            clearTimeout(timeout);

            if (this.errors(data.errors)) {
              // Сгенерированы ошибки

              // Разблокировка полей ввода и кнопок
              unblock();
            } else {
              // Не сгенерированы ошибки (подразумевается их отсутствие)

              if (data.fired === true) {
                // Уволен сотрудник

                // Инициализация индикатора строки
                row.classList.add("fired");
              }

              if (this.body.wrap instanceof HTMLElement) {
                // Найдено активное окно

                // Деинициализация быстрых действий по кнопкам
                document.removeEventListener("keydown", this.buttons);

                // Сброс блокировки
                this.freeze = false;

                // Деинициализация активного окна
                this.body.wrap.remove();

                // Удаление статуса активной строки
                row.removeAttribute("data-selected");
              }
            }
          });
      },
      300,
    );

    /**
     * Нанять сотрудника (вызов демпфера)
     *
     * @param {HTMLElement} row Строка <div>
     * @param {HTMLElement} button Кнопка <button>
     * @param {HTMLElement} worker_name_first Имя сотрудника <input>
     * @param {HTMLElement} worker_name_second Фамилия сотрудника <input>
     * @param {HTMLElement} worker_name_last Отчество сотрудника <input>
     * @param {HTMLElement} worker_number SIM-номер сотрудника <input>
     * @param {HTMLElement} worker_mail Почта сотрудника <input>
     * @param {HTMLElement} worker_birth Дата рождения сотрудника <input>
     * @param {HTMLElement} worker_passport Номер паспорта сотрудника <input>
     * @param {HTMLElement} worker_issued Дата выдачи паспорта сотрудника <input>
     * @param {HTMLElement} worker_department_number Номер отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_department_address Адрес отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_requisites Реквизиты: "0000 0000 0000 0000 Банк Иванов И." <input>
     * @param {HTMLElement} worker_payment Форма оплаты сотруднику <input>
     * @param {HTMLElement} worker_tax Индивидуальный налоговый номер сотрудника <input>
     * @param {HTMLElement} worker_city Город проживания сотрудника <select>
     * @param {HTMLElement} worker_district Регион проживания сотрудника <input>
     * @param {HTMLElement} worker_address Адрес проживания сотрудника <input>
     * @param {HTMLElement} worker_work Тип работы сотрудника <select>
     * @param {HTMLElement} worker_hiring Дата найма сотрудника <input>
     *
     * @return {void}
     */
    static _hire(
      row,
      button,
      worker_name_first,
      worker_name_second,
      worker_name_last,
      worker_number,
      worker_mail,
      worker_birth,
      worker_passport,
      worker_issued,
      worker_department_number,
      worker_department_address,
      worker_requisites,
      worker_payment,
      worker_tax,
      worker_city,
      worker_district,
      worker_address,
      worker_work,
      worker_hiring,
    ) {
      // Блокировка полей ввода
      worker_name_first.setAttribute("readonly", true);
      worker_name_second.setAttribute("readonly", true);
      worker_name_last.setAttribute("readonly", true);
      worker_number.setAttribute("readonly", true);
      worker_mail.setAttribute("readonly", true);
      worker_birth.setAttribute("readonly", true);
      worker_passport.setAttribute("readonly", true);
      worker_issued.setAttribute("readonly", true);
      worker_department_number.setAttribute("readonly", true);
      worker_department_address.setAttribute("readonly", true);
      worker_requisites.setAttribute("readonly", true);
      worker_payment.setAttribute("readonly", true);
      worker_tax.setAttribute("readonly", true);
      worker_city.setAttribute("readonly", true);
      worker_district.setAttribute("readonly", true);
      worker_address.setAttribute("readonly", true);
      worker_work.setAttribute("readonly", true);
      worker_hiring.setAttribute("readonly", true);

      // Блокировка кнопки
      button.setAttribute("disabled", true);

      // Запуск выполнения
      this.__hire(
        row,
        button,
        worker_name_first,
        worker_name_second,
        worker_name_last,
        worker_number,
        worker_mail,
        worker_birth,
        worker_passport,
        worker_issued,
        worker_department_number,
        worker_department_address,
        worker_requisites,
        worker_payment,
        worker_tax,
        worker_city,
        worker_district,
        worker_address,
        worker_work,
        worker_hiring,
      );
    }

    /**
     * Нанять сотрудника (демпфер)
     *
     * @param {HTMLElement} row Строка <div>
     * @param {HTMLElement} worker_name_first Имя сотрудника <input>
     * @param {HTMLElement} worker_name_second Фамилия сотрудника <input>
     * @param {HTMLElement} worker_name_last Отчество сотрудника <input>
     * @param {HTMLElement} worker_number SIM-номер сотрудника <input>
     * @param {HTMLElement} worker_mail Почта сотрудника <input>
     * @param {HTMLElement} worker_birth Дата рождения сотрудника <input>
     * @param {HTMLElement} worker_passport Номер паспорта сотрудника <input>
     * @param {HTMLElement} worker_issued Дата выдачи паспорта сотрудника <input>
     * @param {HTMLElement} worker_department_number Номер отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_department_address Адрес отделения выдавшего паспорт сотруднику <input>
     * @param {HTMLElement} worker_requisites Реквизиты: "0000 0000 0000 0000 Банк Иванов И." <input>
     * @param {HTMLElement} worker_payment Форма оплаты сотруднику <input>
     * @param {HTMLElement} worker_tax Индивидуальный налоговый номер сотрудника <input>
     * @param {HTMLElement} worker_city Город проживания сотрудника <select>
     * @param {HTMLElement} worker_district Регион проживания сотрудника <input>
     * @param {HTMLElement} worker_address Адрес проживания сотрудника <input>
     * @param {HTMLElement} worker_work Тип работы сотрудника <select>
     * @param {HTMLElement} worker_hiring Дата найма сотрудника <input>
     *
     * @return {void}
     */
    static __hire = damper(
      async (
        row,
        button,
        worker_name_first,
        worker_name_second,
        worker_name_last,
        worker_number,
        worker_mail,
        worker_birth,
        worker_passport,
        worker_issued,
        worker_department_number,
        worker_department_address,
        worker_requisites,
        worker_payment,
        worker_tax,
        worker_city,
        worker_district,
        worker_address,
        worker_work,
        worker_hiring,
      ) => {
        // Инициализация функции разблокировки
        function unblock() {
          // Разблокировка полей ввода
          worker_name_first.removeAttribute("readonly");
          worker_name_second.removeAttribute("readonly");
          worker_name_last.removeAttribute("readonly");
          worker_number.removeAttribute("readonly");
          worker_mail.removeAttribute("readonly");
          worker_birth.removeAttribute("readonly");
          worker_passport.removeAttribute("readonly");
          worker_issued.removeAttribute("readonly");
          worker_department_number.removeAttribute("readonly");
          worker_department_address.removeAttribute("readonly");
          worker_requisites.removeAttribute("readonly");
          worker_payment.removeAttribute("readonly");
          worker_tax.removeAttribute("readonly");
          worker_city.removeAttribute("readonly");
          worker_district.removeAttribute("readonly");
          worker_address.removeAttribute("readonly");
          worker_work.removeAttribute("readonly");
          worker_hiring.removeAttribute("readonly");

          // Разблокировка кнопки
          button.removeAttribute("disabled");
        }

        // Инициализация идентификатора сотрудника
        const id = row.querySelector(['span[data-column="worker"]']).innerText;

        // Запуск отсрочки разблокировки на случай, если сервер не отвечает
        const timeout = setTimeout(() => {
          this.errors(["Сервер не отвечает"]);
          unblock();
        }, 5000);

        // Запрос к серверу
        return await fetch(`/worker/${id}/hire`, {
          method: "POST",
        })
          .then((response) => response.json())
          .then((data) => {
            // Удаление отсрочки разблокировки
            clearTimeout(timeout);

            if (this.errors(data.errors)) {
              // Сгенерированы ошибки

              // Разблокировка полей ввода и кнопок
              unblock();
            } else {
              // Не сгенерированы ошибки (подразумевается их отсутствие)

              if (data.hired === true) {
                // Нанят сотрудник

                // Инициализация индикатора строки
                row.classList.remove("fired");
              }

              if (this.body.wrap instanceof HTMLElement) {
                // Найдено активное окно

                // Деинициализация быстрых действий по кнопкам
                document.removeEventListener("keydown", this.buttons);

                // Сброс блокировки
                this.freeze = false;

                // Деинициализация активного окна
                this.body.wrap.remove();

                // Удаление статуса активной строки
                row.removeAttribute("data-selected");
              }
            }
          });
      },
      300,
    );


    static account = class {
      /**
       * Ядро (родительский класс)
       */
      static core;

      /**
       * Обновить аккаунт (вызов демпфера)
       *
       * @param {HTMLElement} row Строка <div>
       * @param {HTMLElement} button Кнопка <button>
       * @param {HTMLElement} account_name_first Имя аккаунта <input>
       * @param {HTMLElement} account_name_second Фамилия аккаунта <input>
       * @param {HTMLElement} account_name_last Отчество аккаунта <input>
       * @param {HTMLElement} account_number SIM-номер аккаунта <input>
       * @param {HTMLElement} account_mail Почта аккаунта<input>
       * @param {HTMLElement} account_password Пароль аккаунта <input>
       * @param {HTMLElement} account_commentary Комментарий аккаунта <textarea>
       *
       * @return {void}
       */
      static _update(
        row,
        button,
        account_name_first,
        account_name_second,
        account_name_last,
        account_number,
        account_mail,
        account_password,
        account_commentary,
      ) {
        // Блокировка полей ввода
        account_name_first.setAttribute("readonly", true);
        account_name_second.setAttribute("readonly", true);
        account_name_last.setAttribute("readonly", true);
        account_number.setAttribute("readonly", true);
        account_mail.setAttribute("readonly", true);
        account_password.setAttribute("readonly", true);
        account_commentary.setAttribute("readonly", true);

        // Блокировка кнопки
        button.setAttribute("disabled", true);

        // Запуск выполнения
        this.__update(
          row,
          button,
          account_name_first,
          account_name_second,
          account_name_last,
          account_number,
          account_mail,
          account_password,
          account_commentary,
        );
      }

      /**
       * Обновить аккаунт (демпфер)
       *
       * @param {HTMLElement} row Строка <div>
       * @param {HTMLElement} button Кнопка <button>
       * @param {HTMLElement} account_name_first Имя аккаунта <input>
       * @param {HTMLElement} account_name_second Фамилия аккаунта <input>
       * @param {HTMLElement} account_name_last Отчество аккаунта <input>
       * @param {HTMLElement} account_number SIM-номер аккаунта <input>
       * @param {HTMLElement} account_mail Почта аккаунта<input>
       * @param {HTMLElement} account_password Пароль аккаунта <input>
       * @param {HTMLElement} account_commentary Комментарий аккаунта <textarea>
       *
       * @return {void}
       */
      static __update = damper(
        async (
          row,
          button,
          account_name_first,
          account_name_second,
          account_name_last,
          account_number,
          account_mail,
          account_password,
          account_commentary,
        ) => {
          // Инициализация функции разблокировки
          function unblock() {
            // Разблокировка полей ввода
            account_name_first.removeAttribute("readonly");
            account_name_second.removeAttribute("readonly");
            account_name_last.removeAttribute("readonly");
            account_number.removeAttribute("readonly");
            account_mail.removeAttribute("readonly");
            account_password.removeAttribute("readonly");
            account_commentary.removeAttribute("readonly");

            // Разблокировка кнопки
            button.removeAttribute("disabled");
          }

          // Инициализация идентификатора
          const id = row.getAttribute("id");

          // Запуск отсрочки разблокировки на случай, если сервер не отвечает
          const timeout = setTimeout(() => {
            this.core.errors(["Сервер не отвечает"]);
            unblock();
          }, 5000);

          // Запрос к серверу
          return await fetch(`/${id}/update`, {
            method: "POST",
            headers: {
              "Content-Type": "application/x-www-form-urlencoded",
            },
            body:
              `name_first=${account_name_first.value}&name_second=${account_name_second.value}&name_last=${account_name_last.value}&number=${account_number.mask.unmaskedValue}&mail=${account_mail.value}&password=${account_password.value}&commentary=${account_commentary.value}`,
          })
            .then((response) => response.json())
            .then((data) => {
              // Удаление отсрочки разблокировки
              clearTimeout(timeout);

              if (this.core.errors(data.errors)) {
                // Сгенерированы ошибки

                // Разблокировка полей ввода и кнопок
                unblock();
              } else {
                // Не сгенерированы ошибки (подразумевается их отсутствие)

                if (data.updated === true) {
                  // Записаны данные

                  // Инициализация буфера списка классов
                  // const buffer = [...row.classList];

                  // Инициализация статуса активной строки
                  const selected = row.getAttribute("data-selected");

                  // Реинициализация строки
                  row.outerHTML = data.row;

                  // Реинициализация строки (выражение странное, но правильное)
                  row = document.getElementById(id);

                  // Копирование классов из буфера классов удалённой строки
                  // row.classList.add(...buffer);

                  // Копирование статуса активной строки
                  if (
                    typeof selected === "string" &&
                    selected === "true" &&
                    document.body.contains(document.getElementById("popup")) &&
                    !document.body.contains(
                      document.querySelector('[data-selected="true"]'),
                    )
                  ) {
                    row.setAttribute("data-selected", "true");
                  }
                }

                if (
                  typeof data.clipboard !== "undefined" &&
                  data.clipboard.length > 0
                ) {
                  // Получены данные для записи в буфер обмена

                  // Запись в буфер обмена (подразумеваются данные созданного аккаунта)
                  navigator.clipboard.writeText(data.clipboard);
                }

                if (this.core.body.wrap instanceof HTMLElement) {
                  // Найдено активное окно

                  // Деинициализация быстрых действий по кнопкам
                  document.removeEventListener("keydown", this.core.buttons);

                  // Сброс блокировки
                  this.core.freeze = false;

                  // Деинициализация активного окна
                  this.core.body.wrap.remove();

                  // Удаление статуса активной строки
                  row.removeAttribute("data-selected");
                }
              }
            });
        },
        300,
      );

      /**
       * Сгенерировать окно для редактированием аккаунта
       *
       * @param {HTMLElement} row Строка
       *
       * @return {void}
       */
      static update = damper(async (row) => {
        if (row instanceof HTMLElement) {
          // Получена строка

          // Инициализация идентификатора аккаунта
          const id = row.getAttribute("id");

          // Запрос к серверу
          return await fetch(`/${id}/fields`, {
            method: "POST",
            headers: {
              "Content-Type": "application/x-www-form-urlencoded",
            },
          })
            .then((response) => response.json())
            .then((data) => {
              // Инициализация буфера выбранных строк
              const buffer = [
                ...document.querySelectorAll('div[data-selected="true"]'),
              ];

              // Удаление статуса активной строки у остальных строк
              for (const element of buffer) {
                element.removeAttribute("data-selected");
              }

              // Инициализация статуса активной строки (обрабатываемой в данный момент)
              row.setAttribute("data-selected", "true");

              // Инициализация оболочки всплывающего окна
              this.core.body.wrap = document.createElement("div");
              this.core.body.wrap.setAttribute("id", "popup");

              // Инициализация оболочки всплывающего окна
              const popup = document.createElement("section");
              popup.classList.add("list", "small");

              // Инициализация заголовка всплывающего окна
              const title = document.createElement("h3");
              title.innerText = id;

              // Инициализация оболочки с основной информацией
              const main = document.createElement("section");
              main.classList.add("main");

              // Инициализация колонки
              const account = document.createElement("div");
              account.classList.add("column");

              // Инициализация строки
              const account_name_first = document.createElement("div");
              account_name_first.classList.add("row", "merged");

              // Инициализация оболочки для строки
              const account_name_first_label = document.createElement("label");
              account_name_first_label.setAttribute("id", "account_first");

              // Инициализация заголовка для поля ввода
              const account_name_first_title = document.createElement("b");
              account_name_first_title.classList.add(
                "separated",
                "right",
                "unselectable",
              );
              account_name_first_title.innerText = "Имя:";

              // Инициализация поля ввода
              const account_name_first_input = document.createElement("input");
              account_name_first_input.classList.add("medium");
              account_name_first_input.setAttribute("type", "text");
              account_name_first_input.setAttribute("name", "first");
              account_name_first_input.setAttribute(
                "autocomplete",
                "given-name",
              );
              account_name_first_input.setAttribute("minlength", "0");
              account_name_first_input.setAttribute("maxlength", "100");
              account_name_first_input.setAttribute("title", "Имя аккаунта");
              account_name_first_input.setAttribute("placeholder", "Иван");
              account_name_first_input.value = data.name.first ?? "";

              // Инициализация строки
              const account_name_second = document.createElement("div");
              account_name_second.classList.add("row", "merged");

              // Инициализация оболочки для строки
              const account_name_second_label = document.createElement("label");
              account_name_second_label.setAttribute("id", "account_second");

              // Инициализация заголовка для поля ввода
              const account_name_second_title = document.createElement("b");
              account_name_second_title.classList.add(
                "separated",
                "right",
                "unselectable",
              );
              account_name_second_title.innerText = "Фамилия:";

              // Инициализация поля ввода
              const account_name_second_input = document.createElement("input");
              account_name_second_input.classList.add("medium");
              account_name_second_input.setAttribute(
                "autocomplete",
                "family-name",
              );
              account_name_second_input.setAttribute("name", "second");
              account_name_second_input.setAttribute("type", "text");
              account_name_second_input.setAttribute("minlength", "0");
              account_name_second_input.setAttribute("maxlength", "100");
              account_name_second_input.setAttribute(
                "title",
                "Фамилия аккаунта",
              );
              account_name_second_input.setAttribute("placeholder", "Иванов");
              account_name_second_input.value = data.name.second ?? "";

              // Инициализация строки
              const account_name_last = document.createElement("div");
              account_name_last.classList.add("row", "merged");

              // Инициализация оболочки для строки
              const account_name_last_label = document.createElement("label");
              account_name_last_label.setAttribute("id", "account_last");

              // Инициализация заголовка для поля ввода
              const account_name_last_title = document.createElement("b");
              account_name_last_title.classList.add(
                "separated",
                "right",
                "unselectable",
              );
              account_name_last_title.innerText = "Отчество:";

              // Инициализация поля ввода
              const account_name_last_input = document.createElement("input");
              account_name_last_input.classList.add("medium");
              account_name_last_input.setAttribute("name", "last");
              account_name_last_input.setAttribute(
                "autocomplete",
                "additional-name",
              );
              account_name_last_input.setAttribute("type", "text");
              account_name_last_input.setAttribute("minlength", "0");
              account_name_last_input.setAttribute("maxlength", "100");
              account_name_last_input.setAttribute(
                "title",
                "Отчество/Матчество аккаунта",
              );
              account_name_last_input.setAttribute("placeholder", "Иванович");
              account_name_last_input.value = data.name.last ?? "";

              // Инициализация строки
              const account_number = document.createElement("div");
              account_number.classList.add("row", "merged", "divided");

              // Инициализация оболочки для строки
              const account_number_label = document.createElement("label");
              account_number_label.setAttribute("id", "account_number");

              // Инициализация заголовка для поля ввода
              const account_number_title = document.createElement("b");
              account_number_title.classList.add(
                "separated",
                "right",
                "unselectable",
              );
              account_number_title.innerText = "SIM-номер:";

              // Инициализация поля ввода
              const account_number_input = document.createElement("input");
              account_number_input.classList.add("medium");
              account_number_input.setAttribute("name", "sim-number");
              account_number_input.setAttribute("autocomplete", "tel");
              account_number_input.setAttribute("type", "text");
              account_number_input.setAttribute("minlength", "18");
              account_number_input.setAttribute("maxlength", "18");
              account_number_input.setAttribute("title", "SIM-номер аккаунта");
              account_number_input.setAttribute(
                "placeholder",
                "+7 (000) 000-00-00",
              );
              account_number_input.value = data.number ?? "";

              // Инициализация строки
              const account_mail = document.createElement("div");
              account_mail.classList.add("row", "merged");

              // Инициализация оболочки для строки
              const account_mail_label = document.createElement("label");
              account_mail_label.setAttribute("id", "account_mail");

              // Инициализация заголовка для поля ввода
              const account_mail_title = document.createElement("b");
              account_mail_title.classList.add(
                "separated",
                "right",
                "unselectable",
              );
              account_mail_title.innerText = "Почта:";

              // Инициализация поля ввода
              const account_mail_input = document.createElement("input");
              account_mail_input.classList.add("medium");
              account_mail_input.setAttribute("name", "mail");
              account_mail_input.setAttribute("autocomplete", "email");
              account_mail_input.setAttribute("type", "text");
              account_mail_input.setAttribute("minlength", "3");
              account_mail_input.setAttribute("maxlength", "300");
              account_mail_input.setAttribute("title", "Почта аккаунта");
              account_mail_input.setAttribute("placeholder", "name@server");
              account_mail_input.value = data.mail ?? "";

              // Инициализация строки
              const account_password = document.createElement("div");
              account_password.classList.add("row", "merged");

              // Инициализация оболочки для строки
              const account_password_label = document.createElement("label");
              account_password_label.setAttribute("id", "account_password");

              // Инициализация заголовка для поля ввода
              const account_password_title = document.createElement("b");
              account_password_title.classList.add(
                "separated",
                "right",
                "unselectable",
              );
              account_password_title.innerText = "Пароль:";

              // Инициализация поля ввода
              const account_password_input = document.createElement("input");
              account_password_input.classList.add("medium");
              account_password_input.setAttribute("name", "password");
              account_password_input.setAttribute("required", "true");
              account_password_input.setAttribute(
                "title",
                "Не менее 8 символов",
              );
              account_password_input.setAttribute(
                "autocomplete",
                "new-password",
              );
              account_password_input.setAttribute("type", "password");
              account_password_input.setAttribute("minlength", "8");
              account_password_input.setAttribute("maxlength", "100");
              account_password_input.setAttribute("title", "Пароль аккаунта");
              account_password_input.setAttribute("placeholder", "*********");

              // Инициализация строки
              const account_commentary = document.createElement("div");
              account_commentary.classList.add("row", "endless");

              // Инициализация оболочки для строки
              const account_commentary_label = document.createElement("label");
              account_commentary_label.setAttribute("id", "account_commentary");

              // Инициализация поля ввода
              const account_commentary_textarea = document.createElement(
                "textarea",
              );
              account_commentary_textarea.setAttribute("maxlength", "800");
              account_commentary_textarea.setAttribute(
                "title",
                "Комментарий аккаунта",
              );
              account_commentary_textarea.setAttribute(
                "placeholder",
                "Дополнительная информация для администраторов",
              );
              account_commentary_textarea.value = data.commentary ?? "";

              // Инициализация строки
              const account_buttons = document.createElement("div");
              account_buttons.classList.add(
                "row",
                "divided",
                "merged",
                "buttons",
              );

              // Инициализация кнопки обновления
              const account_update_button = document.createElement("button");
              account_update_button.classList.add("grass", "stretched");
              account_update_button.innerText = "Сохранить";
              account_update_button.setAttribute(
                "onclick",
                `workers.account._update(document.getElementById(${id}), this, ...this.parentElement.parentElement.parentElement.querySelectorAll(':is(input, textarea)'))`,
              );

              // Инициализация кнопки удаления
              const account_ban_button = document.createElement("button");
              if (row.classList.contains("banned")) {
                // Заблокирован

                account_ban_button.classList.add("grass");
                account_ban_button.innerText = "Разблокировать";
                account_ban_button.setAttribute(
                  "onclick",
                  `workers.account._unban(document.getElementById(${id}), this, ...this.parentElement.parentElement.parentElement.querySelectorAll(':is(input, textarea)'))`,
                );
              } else {
                // Не заблокирован

                account_ban_button.classList.add("clay");
                account_ban_button.innerText = "Заблокировать";
                account_ban_button.setAttribute(
                  "onclick",
                  `workers.account._ban(document.getElementById(${id}), this, ...this.parentElement.parentElement.parentElement.querySelectorAll(':is(input, textarea)'))`,
                );
              }

              // Инициализация строки
              const account_buttons_2 = document.createElement("div");
              account_buttons_2.classList.add("row", "merged", "buttons");

              // Инициализация кнопки удаления
              const account_delete_button = document.createElement("button");
              account_delete_button.classList.add("clay", "stretched");
              account_delete_button.innerText = "Удалить";
              account_delete_button.setAttribute(
                "onclick",
                `workers.account._delete(document.getElementById(${id}), this, ...this.parentElement.parentElement.parentElement.querySelectorAll(':is(input, textarea)'))`,
              );

              // Инициализация окна с ошибками
              this.core.body.errors = document.createElement("section");
              this.core.body.errors.classList.add(
                "errors",
                "window",
                "list",
                "small",
                "hidden",
              );
              this.core.body.errors.setAttribute("data-errors", true);

              // Инициализация элемента-оболочки с ошибками для всплывающего окна
              const errors = document.createElement("section");
              errors.classList.add("body");

              // Инициализация элемента-списка ошибок
              const dl = document.createElement("dl");

              // Инициализация активного всплывающего окна
              const old = document.getElementById("popup");

              if (old instanceof HTMLElement) {
                // Найдено активное окно

                // Деинициализация быстрых действий по кнопкам
                document.removeEventListener("keydown", this.core.buttons);

                // Сброс блокировки
                this.core.freeze = false;

                // Удаление активного окна
                old.remove();
              }

              // Запись в документ
              popup.appendChild(title);

              account_name_first_label.appendChild(account_name_first_title);
              account_name_first_label.appendChild(account_name_first_input);
              account_name_first.appendChild(account_name_first_label);
              account.appendChild(account_name_first);

              account_name_second_label.appendChild(account_name_second_title);
              account_name_second_label.appendChild(account_name_second_input);
              account_name_second.appendChild(account_name_second_label);
              account.appendChild(account_name_second);

              account_name_last_label.appendChild(account_name_last_title);
              account_name_last_label.appendChild(account_name_last_input);
              account_name_last.appendChild(account_name_last_label);
              account.appendChild(account_name_last);

              account_number_label.appendChild(account_number_title);
              account_number_label.appendChild(account_number_input);
              account_number.appendChild(account_number_label);
              account.appendChild(account_number);

              account_mail_label.appendChild(account_mail_title);
              account_mail_label.appendChild(account_mail_input);
              account_mail.appendChild(account_mail_label);
              account.appendChild(account_mail);

              account_password_label.appendChild(account_password_title);
              account_password_label.appendChild(account_password_input);
              account_password.appendChild(account_password_label);
              account.appendChild(account_password);

              account_commentary_label.appendChild(account_commentary_textarea);
              account_commentary.appendChild(account_commentary_label);
              account.appendChild(account_commentary);

              account_buttons.appendChild(account_update_button);
              account_buttons.appendChild(account_ban_button);
              account.appendChild(account_buttons);

              account_buttons_2.appendChild(account_delete_button);
              account.appendChild(account_buttons_2);

              main.appendChild(account);
              popup.appendChild(main);
              this.core.body.wrap.appendChild(popup);

              errors.appendChild(dl);
              this.core.body.errors.appendChild(errors);
              this.core.body.wrap.appendChild(this.core.body.errors);

              document.body.appendChild(this.core.body.wrap);

              // Инициалиация масок
              account_number_input.mask = IMask(account_number_input, {
                mask: "+{7} (000) 000-00-00",
              });

              // Инициализация переменных для окна с ошибками (12 - это значение gap из div#popup)
              function top(errors) {
                errors.style.setProperty("transition", "0s");
                errors.style.setProperty(
                  "--top",
                  popup.offsetTop + popup.offsetHeight + 12 + "px",
                );
                setTimeout(
                  () => errors.style.removeProperty("transition"),
                  100,
                );
              }
              top(this.core.body.errors);
              const resize = new ResizeObserver(() =>
                top(this.core.body.errors)
              );
              resize.observe(this.core.body.wrap);

              // Инициализация функции генерации пароля и записи в поле ввода и буфер обмена
              const generate = (e) => {
                // Блокировка выполнения при нажатии на поле для ввода
                if (e.target.tagName === "INPUT") return;

                // Инициализация поля ввода пароля
                const input = e.currentTarget.getElementsByTagName("input")[0];

                if (input instanceof HTMLElement) {
                  // Найдено поле для ввода пароля

                  // Инициализация буфера генерации пароля
                  let password = "";

                  // Инициализация используемых символов для генерируемого пароля
                  const symbols =
                    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789------";

                  // Генерация пароля
                  for (let i = 0; i < Math.random() * 14 + 8; i++) {
                    password += symbols.charAt(
                      Math.floor(Math.random() * symbols.length),
                    );
                  }

                  // Запись пароля в поле для ввода пароля
                  input.value = password;

                  // Вызов функции инициализации генератора пароля
                  input.dispatchEvent(new KeyboardEvent("keyup"));

                  // Запиcь пароля в буфер обмена
                  navigator.clipboard.writeText(password);

                  // Фокусировка на поле для ввода пароля
                  input.focus();
                }
              };

              // Инициализация функции инициализации генератора пароля
              const generator = (e) => {
                // Инициализация строки с полем для ввода пароля
                const row = e.currentTarget.parentElement.parentElement;

                if (row instanceof HTMLElement) {
                  // Найдено поле для ввода пароля

                  if (e.target.value.length === 0) {
                    // Не введён пароль

                    row.setAttribute("title", "Сгенерировать пароль");
                    row.setAttribute("data-interactive", "true");
                    row.addEventListener("click", generate);
                  } else {
                    // Введён пароль

                    row.removeAttribute("title");
                    row.removeAttribute("data-interactive");
                    row.removeEventListener("click", generate);
                  }
                }
              };

              // Инициализация вызова функции инициализации генератора пароля по события нажатия клавиши
              account_password_input.addEventListener("keyup", generator);

              // Вызов функции инициализации генератора пароля (первичный)
              account_password_input.dispatchEvent(new KeyboardEvent("keyup"));

              // Инициализация функции закрытия всплывающего окна
              const click = () => {
                // Блокировка
                if (this.core.freeze) return;

                // Удаление всплывающего окна
                this.core.body.wrap.remove();

                // Инициализация буфера выбранных строк
                const buffer = [
                  ...document.querySelectorAll('div[data-selected="true"]'),
                ];

                // Удаление статуса активной строки у остальных строк
                for (const element of buffer) {
                  element.removeAttribute("data-selected");
                }

                // Деинициализация быстрых действий по кнопкам
                document.removeEventListener("keydown", this.core.buttons);

                // Сброс блокировки
                this.core.freeze = false;
              };

              // Инициализация функции добавления функции закрытия всплывающего окна
              const enable = () =>
                this.core.body.wrap.addEventListener("click", click);

              // Инициализация функции удаления функции закрытия всплывающего окна
              const disable = () =>
                this.core.body.wrap.removeEventListener("click", click);

              // Первичная активация функции удаления всплывающего окна
              enable();

              // Инициализация блокировки удаления окна при взаимодействии с select-элементом
              for (const select of popup.getElementsByTagName("select")) {
                // Перебор всех select-элементов

                // Инициализация функции блокировки удаления окна по событию
                select.addEventListener("click", () => {
                  // Блокировка удаления окна
                  this.core.freeze = true;

                  // Разблокировка удаления окна
                  setTimeout(() => (this.core.freeze = false), 100);
                });

                for (const option of select.getElementsByTagName("option")) {
                  // Перебор всех option-элементов

                  // Инициализация функции блокировки удаления окна по событию
                  option.addEventListener("click", () => {
                    // Блокировка удаления окна
                    this.core.freeze = true;

                    // Разблокировка удаления окна
                    setTimeout(() => (this.core.freeze = false), 100);
                  });
                }
              }

              // Инициализация блокировки удаления окна при взаимодействии с textarea-элементом
              for (const textarea of popup.getElementsByTagName("textarea")) {
                // Перебор всех textarea-элементов

                // Обновлять позицию окна с ошибками при изменении размера textarea (там position: absolute)
                new MutationObserver(() => top(this.core.body.errors)).observe(
                  textarea,
                  {
                    attributes: true,
                    attributeFilter: ["style"],
                  },
                );

                // Инициализация функции игнорирования блокировки для выбранных кнопок
                textarea.addEventListener("keydown", (e) => {
                  if (e.keyCode === 27) {
                    // Нажата кнопка: "escape"

                    // Вызов глобальной функции управления кнопками
                    this.core.buttons(e, true);
                  } else if (e.ctrlKey && e.keyCode === 13) {
                    // Нажаты кнопки: "control", "enter"

                    // Вызов глобальной функции управления кнопками
                    this.core.buttons(e, true);
                  }
                });

                // Добавление функции блокировки удаления окна и клавиш по событиям
                textarea.addEventListener(
                  "focus",
                  () => (this.core.freeze = true),
                );
                textarea.addEventListener(
                  "focusout",
                  () => (this.core.freeze = false),
                );
              }

              // Инициализация функции управления кнопками
              this.core.buttons = (e, force = false) => {
                // Блокировка
                if (!force && this.core.freeze) return;

                if (e.keyCode === 27) {
                  // Нажата кнопка: "escape"

                  // Удаление окна
                  click();
                } else if (event.keyCode === 13) {
                  // Нажата кнопка: "enter"

                  // Инициализация буфера с текущим статусом блокировки закрытия окна
                  const freeze = this.core.freeze;

                  // Блокировка закрытия окна (чтобы не вызвался click() через событие onclick)
                  this.core.freeze = true;

                  // Активация виртуальной кнопки "сохранить"
                  account_update_button.click();

                  // Возвращение статуса блокировки закрытия окна
                  this.core.freeze = freeze;
                }
              };

              // Инициализация быстрых действий по кнопкам
              document.addEventListener("keydown", this.core.buttons);

              // Добавление функции удаления всплывающего окна по событиям
              popup.addEventListener("mouseenter", disable);
              popup.addEventListener("mouseleave", enable);

              // Фокусировка
              account_name_first_input.focus();
            });
        }
      }, 300);

      /**
       * Удалить аккаунт (вызов демпфера)
       *
       * @param {HTMLElement} row Строка <div>
       * @param {HTMLElement} button Кнопка <button>
       * @param {HTMLElement} account_name_first Имя аккаунта <input>
       * @param {HTMLElement} account_name_second Фамилия аккаунта <input>
       * @param {HTMLElement} account_name_last Отчество аккаунта <input>
       * @param {HTMLElement} account_number SIM-номер аккаунта <input>
       * @param {HTMLElement} account_mail Почта аккаунта<input>
       * @param {HTMLElement} account_password Пароль аккаунта <input>
       * @param {HTMLElement} account_commentary Комментарий аккаунта <textarea>
       *
       * @return {void}
       */
      static _delete(
        row,
        button,
        account_name_first,
        account_name_second,
        account_name_last,
        account_number,
        account_mail,
        account_password,
        account_commentary,
      ) {
        // Блокировка полей ввода
        account_name_first.setAttribute("readonly", true);
        account_name_second.setAttribute("readonly", true);
        account_name_last.setAttribute("readonly", true);
        account_number.setAttribute("readonly", true);
        account_mail.setAttribute("readonly", true);
        account_password.setAttribute("readonly", true);
        account_commentary.setAttribute("readonly", true);

        // Блокировка кнопки
        button.setAttribute("disabled", true);

        // Запуск выполнения
        this.__delete(
          row,
          button,
          account_name_first,
          account_name_second,
          account_name_last,
          account_number,
          account_mail,
          account_password,
          account_commentary,
        );
      }

      /**
       * Удалить аккаунт (демпфер)
       *
       * @param {HTMLElement} row Строка <div>
       * @param {HTMLElement} button Кнопка <button>
       * @param {HTMLElement} account_name_first Имя аккаунта <input>
       * @param {HTMLElement} account_name_second Фамилия аккаунта <input>
       * @param {HTMLElement} account_name_last Отчество аккаунта <input>
       * @param {HTMLElement} account_number SIM-номер аккаунта <input>
       * @param {HTMLElement} account_mail Почта аккаунта<input>
       * @param {HTMLElement} account_password Пароль аккаунта <input>
       * @param {HTMLElement} account_commentary Комментарий аккаунта <textarea>
       *
       * @return {void}
       */
      static __delete = damper(
        async (
          row,
          button,
          account_name_first,
          account_name_second,
          account_name_last,
          account_number,
          account_mail,
          account_password,
          account_commentary,
        ) => {
          // Инициализация функции разблокировки
          function unblock() {
            // Разблокировка полей ввода
            account_name_first.removeAttribute("readonly");
            account_name_second.removeAttribute("readonly");
            account_name_last.removeAttribute("readonly");
            account_number.removeAttribute("readonly");
            account_mail.removeAttribute("readonly");
            account_password.removeAttribute("readonly");
            account_commentary.removeAttribute("readonly");

            // Разблокировка кнопки
            button.removeAttribute("disabled");
          }

          // Инициализация идентификатора
          const id = row.getAttribute("id");

          // Запуск отсрочки разблокировки на случай, если сервер не отвечает
          const timeout = setTimeout(() => {
            this.core.errors(["Сервер не отвечает"]);
            unblock();
          }, 5000);

          // Запрос к серверу
          return await fetch(`/${id}/delete`, {
            method: "POST",
            headers: {
              "Content-Type": "application/x-www-form-urlencoded",
            },
          })
            .then((response) => response.json())
            .then((data) => {
              // Удаление отсрочки разблокировки
              clearTimeout(timeout);

              if (this.core.errors(data.errors)) {
                // Сгенерированы ошибки

                // Разблокировка полей ввода и кнопок
                unblock();
              } else {
                // Не сгенерированы ошибки (подразумевается их отсутствие)

                if (data.deleted === true) {
                  // Удалены данные

                  // Удаление строки
                  row.remove();
                }

                if (this.core.body.wrap instanceof HTMLElement) {
                  // Найдено активное окно

                  // Деинициализация быстрых действий по кнопкам
                  document.removeEventListener("keydown", this.core.buttons);

                  // Сброс блокировки
                  this.core.freeze = false;

                  // Деинициализация активного окна
                  this.core.body.wrap.remove();

                  // Удаление статуса активной строки
                  row.removeAttribute("data-selected");
                }
              }
            });
        },
        300,
      );

      /**
       * Заблокировать аккаунт (вызов демпфера)
       *
       * @param {HTMLElement} row Строка <div>
       * @param {HTMLElement} button Кнопка <button>
       * @param {HTMLElement} account_name_first Имя аккаунта <input>
       * @param {HTMLElement} account_name_second Фамилия аккаунта <input>
       * @param {HTMLElement} account_name_last Отчество аккаунта <input>
       * @param {HTMLElement} account_number SIM-номер аккаунта <input>
       * @param {HTMLElement} account_mail Почта аккаунта<input>
       * @param {HTMLElement} account_password Пароль аккаунта <input>
       * @param {HTMLElement} account_commentary Комментарий аккаунта <textarea>
       *
       * @return {void}
       */
      static _ban(
        row,
        button,
        account_name_first,
        account_name_second,
        account_name_last,
        account_number,
        account_mail,
        account_password,
        account_commentary,
      ) {
        // Блокировка полей ввода
        account_name_first.setAttribute("readonly", true);
        account_name_second.setAttribute("readonly", true);
        account_name_last.setAttribute("readonly", true);
        account_number.setAttribute("readonly", true);
        account_mail.setAttribute("readonly", true);
        account_password.setAttribute("readonly", true);
        account_commentary.setAttribute("readonly", true);

        // Блокировка кнопки
        button.setAttribute("disabled", true);

        // Запуск выполнения
        this.__ban(
          row,
          button,
          account_name_first,
          account_name_second,
          account_name_last,
          account_number,
          account_mail,
          account_password,
          account_commentary,
        );
      }

      /**
       * Заблокировать аккаунт (демпфер)
       *
       * @param {HTMLElement} row Строка <div>
       * @param {HTMLElement} button Кнопка <button>
       * @param {HTMLElement} account_name_first Имя аккаунта <input>
       * @param {HTMLElement} account_name_second Фамилия аккаунта <input>
       * @param {HTMLElement} account_name_last Отчество аккаунта <input>
       * @param {HTMLElement} account_number SIM-номер аккаунта <input>
       * @param {HTMLElement} account_mail Почта аккаунта<input>
       * @param {HTMLElement} account_password Пароль аккаунта <input>
       * @param {HTMLElement} account_commentary Комментарий аккаунта <textarea>
       *
       * @return {void}
       */
      static __ban = damper(
        async (
          row,
          button,
          account_name_first,
          account_name_second,
          account_name_last,
          account_number,
          account_mail,
          account_password,
          account_commentary,
        ) => {
          // Инициализация функции разблокировки
          function unblock() {
            // Разблокировка полей ввода
            account_name_first.removeAttribute("readonly");
            account_name_second.removeAttribute("readonly");
            account_name_last.removeAttribute("readonly");
            account_number.removeAttribute("readonly");
            account_mail.removeAttribute("readonly");
            account_password.removeAttribute("readonly");
            account_commentary.removeAttribute("readonly");

            // Разблокировка кнопки
            button.removeAttribute("disabled");
          }

          // Инициализация идентификатора
          const id = row.getAttribute("id");

          // Запуск отсрочки разблокировки на случай, если сервер не отвечает
          const timeout = setTimeout(() => {
            this.core.errors(["Сервер не отвечает"]);
            unblock();
          }, 5000);

          // Запрос к серверу
          return await fetch(`/${id}/ban`, {
            method: "POST",
            headers: {
              "Content-Type": "application/x-www-form-urlencoded",
            },
          })
            .then((response) => response.json())
            .then((data) => {
              // Удаление отсрочки разблокировки
              clearTimeout(timeout);

              if (this.core.errors(data.errors)) {
                // Сгенерированы ошибки

                // Разблокировка полей ввода и кнопок
                unblock();
              } else {
                // Не сгенерированы ошибки (подразумевается их отсутствие)

                if (data.banned === true) {
                  // Заблокирован аккаунт

                  // Инициализация индикации строки
                  row.classList.add("banned");
                }

                if (this.core.body.wrap instanceof HTMLElement) {
                  // Найдено активное окно

                  // Деинициализация быстрых действий по кнопкам
                  document.removeEventListener("keydown", this.core.buttons);

                  // Сброс блокировки
                  this.core.freeze = false;

                  // Деинициализация активного окна
                  this.core.body.wrap.remove();

                  // Удаление статуса активной строки
                  row.removeAttribute("data-selected");
                }
              }
            });
        },
        300,
      );
 
			/**
       * Разблокировать аккаунт (вызов демпфера)
       *
       * @param {HTMLElement} row Строка <div>
       * @param {HTMLElement} button Кнопка <button>
       * @param {HTMLElement} account_name_first Имя аккаунта <input>
       * @param {HTMLElement} account_name_second Фамилия аккаунта <input>
       * @param {HTMLElement} account_name_last Отчество аккаунта <input>
       * @param {HTMLElement} account_number SIM-номер аккаунта <input>
       * @param {HTMLElement} account_mail Почта аккаунта<input>
       * @param {HTMLElement} account_password Пароль аккаунта <input>
       * @param {HTMLElement} account_commentary Комментарий аккаунта <textarea>
       *
       * @return {void}
       */
      static _unban(
        row,
        button,
        account_name_first,
        account_name_second,
        account_name_last,
        account_number,
        account_mail,
        account_password,
        account_commentary,
      ) {
        // Блокировка полей ввода
        account_name_first.setAttribute("readonly", true);
        account_name_second.setAttribute("readonly", true);
        account_name_last.setAttribute("readonly", true);
        account_number.setAttribute("readonly", true);
        account_mail.setAttribute("readonly", true);
        account_password.setAttribute("readonly", true);
        account_commentary.setAttribute("readonly", true);

        // Блокировка кнопки
        button.setAttribute("disabled", true);

        // Запуск выполнения
        this.__unban(
          row,
          button,
          account_name_first,
          account_name_second,
          account_name_last,
          account_number,
          account_mail,
          account_password,
          account_commentary,
        );
      }

      /**
       * Разблокировать аккаунт (демпфер)
       *
       * @param {HTMLElement} row Строка <div>
       * @param {HTMLElement} button Кнопка <button>
       * @param {HTMLElement} account_name_first Имя аккаунта <input>
       * @param {HTMLElement} account_name_second Фамилия аккаунта <input>
       * @param {HTMLElement} account_name_last Отчество аккаунта <input>
       * @param {HTMLElement} account_number SIM-номер аккаунта <input>
       * @param {HTMLElement} account_mail Почта аккаунта<input>
       * @param {HTMLElement} account_password Пароль аккаунта <input>
       * @param {HTMLElement} account_commentary Комментарий аккаунта <textarea>
       *
       * @return {void}
       */
      static __unban = damper(
        async (
          row,
          button,
          account_name_first,
          account_name_second,
          account_name_last,
          account_number,
          account_mail,
          account_password,
          account_commentary,
        ) => {
          // Инициализация функции разблокировки
          function unblock() {
            // Разблокировка полей ввода
            account_name_first.removeAttribute("readonly");
            account_name_second.removeAttribute("readonly");
            account_name_last.removeAttribute("readonly");
            account_number.removeAttribute("readonly");
            account_mail.removeAttribute("readonly");
            account_password.removeAttribute("readonly");
            account_commentary.removeAttribute("readonly");

            // Разблокировка кнопки
            button.removeAttribute("disabled");
          }

          // Инициализация идентификатора
          const id = row.getAttribute("id");

          // Запуск отсрочки разблокировки на случай, если сервер не отвечает
          const timeout = setTimeout(() => {
            this.core.errors(["Сервер не отвечает"]);
            unblock();
          }, 5000);

          // Запрос к серверу
          return await fetch(`/${id}/unban`, {
            method: "POST",
            headers: {
              "Content-Type": "application/x-www-form-urlencoded",
            },
          })
            .then((response) => response.json())
            .then((data) => {
              // Удаление отсрочки разблокировки
              clearTimeout(timeout);

              if (this.core.errors(data.errors)) {
                // Сгенерированы ошибки

                // Разблокировка полей ввода и кнопок
                unblock();
              } else {
                // Не сгенерированы ошибки (подразумевается их отсутствие)

                if (data.unbanned === true) {
                  // Разблокирован аккаунт

                  // Инициализация индикации строки
                  row.classList.remove("banned");
                }

                if (this.core.body.wrap instanceof HTMLElement) {
                  // Найдено активное окно

                  // Деинициализация быстрых действий по кнопкам
                  document.removeEventListener("keydown", this.core.buttons);

                  // Сброс блокировки
                  this.core.freeze = false;

                  // Деинициализация активного окна
                  this.core.body.wrap.remove();

                  // Удаление статуса активной строки
                  row.removeAttribute("data-selected");
                }
              }
            });
        },
        300,
      );
    };

    /**
     * Сгенерировать список работ
     *
     * @return {array|null} Массив HTML-элементов <option>
     */
    static async works(id) {
      // Запрос к серверу
      return await fetch(`/tasks/works`, {
        method: "POST",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
      })
        .then((response) => response.json())
        .then((data) => {
          if (this.errors(data.errors)) {
            // Сгенерированы ошибки
          } else {
            // Не сгенерированы ошибки (подразумевается их отсутствие)

            return data.works;
          }
        });
    }

    /**
     * Сгенерировать HTML-элемент со списком ошибок
     *
     * @param {object} registry Реестр ошибок
     * @param {bool} render Отобразить в окне с ошибками?
     * @param {bool} clean Очистить окно с ошибками перед добавлением?
     *
     * @return {bool} Сгенерированы ошибки?
     */
    static errors(registry, render = true, clean = true) {
      // Инициализация ссылки на HTML-элемент с ошибками
      const wrap = document.body.contains(this.body.errors)
        ? this.body.errors
        : document.querySelector('[data-errors="true"]');

      if (wrap instanceof HTMLElement && document.body.contains(wrap)) {
        // Найден HTML-элемент с ошибками

        // Перерасчёт высоты элемента
        function height() {
          wrap.classList.remove("hidden");
          wrap.classList.remove("animation");
          // Реинициализация переменной с данными о высоте HTML-элемента (16 - это padding-top + padding-bottom у div#popup > section.errors)
          wrap.style.setProperty("--height", wrap.offsetHeight - 16 + "px");
          wrap.classList.add("animation");
          wrap.classList.add("hidden");
        }

        // Инициализация элемента-списка ошибок
        const list = wrap.getElementsByTagName("dl")[0];

        // Удаление ошибок из прошлой генерации
        if (clean) list.innerHTML = null;

        for (const error in registry) {
          // Генерация HTML-элементов с текстами ошибок

          // Инициализация HTML-элемента текста ошибки
          const samp = document.createElement("samp");

          if (typeof registry[error] === "object") {
            // Категория ошибок

            // Проверка наличия ошибок
            if (registry[error].length === 0) continue;

            // Инициализация HTML-элемента-оболочки
            const wrap = document.createElement("dt");

            // Запись текста категории
            samp.innerText = error;

            // Запись HTML-элементов в список
            wrap.appendChild(samp);
            list.appendChild(wrap);

            // Реинициализация высоты
            height();

            // Обработка вложенных ошибок (вход в рекурсию)
            this.errors(registry[error], false);
          } else {
            // Текст ошибки (подразумевается)

            // Инициализация HTML-элемента
            const wrap = document.createElement("dd");

            // Запись текста ошибки
            samp.innerText = registry[error];

            // Запись HTML-элемента в список
            wrap.appendChild(samp);
            list.appendChild(wrap);

            // Реинициализация высоты
            height();
          }
        }

        if (render) {
          // Запрошена отрисовка

          if (list.childElementCount !== 0) {
            // Найдены ошибки

            // Сброс анимации
            // УЛОВКА: таким образом не запускается анимация до взаимодействия с элементом (исправлял это в CSS, но не помню как)
            wrap.classList.add("animation");

            // Отображение
            wrap.classList.remove("hidden");
          } else {
            // Не найдены ошибки

            // Скрытие
            wrap.classList.add("hidden");
          }
        }

        return list.childElementCount === 0 ? false : true;
      }

      return false;
    }
  };

  // Инициализация ядра
  window.workers.account.core = window.workers;
}

// Вызов события: "инициализировано"
document.dispatchEvent(
  new CustomEvent("workers.initialized", {
    detail: { workers: window.workers },
  }),
);
