var about = {
    init: function (loadPageFunc) {
        nav.setTitle('О сайте');
        loadPageFunc();
        validation('#contactForm', about.contact);

        brcrArray = [{name:"О нас"}];
        nav.setBreadcrumbs();
    },
    contact: function () {
        var text = e('message').value.trim();
        var email = e('email').value.trim();
        var name = e('name').value.trim();

        j.post(['about', 'contact'], function (data) {
            var frm = e('contactForm');
            empty(frm);
            // if (data.mgr.http_response_code == 200) e('alert', frm, 'div', 'alert alert-success').innerHTML = 'Спасибо! Ваше сообщение успешно отправлено.';
            if (data.result == 1) e('alert', frm, 'div', 'alert alert-success').innerHTML = 'Спасибо! Ваше сообщение успешно отправлено.';
            else e('alert', frm, 'div', 'alert alert-warning').innerHTML = 'К сожалению произошла ошибка, сообщите об этом по адресу - blago.web@outlook.com';
        }, {text: text, name: name, email: email, history: clk.debugPushedHistory});

    }
};var main = {
    tabs: {
        data: [],
        history: [],
        state: [],
        opened: 0
    },
    activeTabId: false,
    tabContentBox: e('tabContent'),
    isNewTab: false,
    init: function () {
        if (localStorage.darkTheme === 'true') main.actions.switchLight(false);
        if (localStorage.fontSize) {
            const r = document.querySelector(':root');
            r.style.setProperty('--fontSize', localStorage.fontSize);
        }

        if(!localStorage.bibleInitData){
            this.loadDBdata(main.buildPage);
        }
        else {
            bibleInitData = JSON.parse(localStorage.bibleInitData);
            this.buildPage();
        }

        $('#modalMsg').on('hidden.bs.modal', function (ev) {
            ev.currentTarget.querySelector('.modal-body').className = 'modal-body';
        });
        e('rightSidebar').ondragover = main.actions.sidebarSeparating;
    },
    loadDBdata: function (callback) {
        j.post(['main', 'init'], function (data) {
            localStorage.bibleInitData = JSON.stringify(data);
            bibleInitData = data;
            localStorage.DB_VERSION++;
            callback();
        }, {});
    },
    buildPage: function () {
        main.display.booksList(bibleInitData.booksList, bibleInitData.booksListOrderSeq);

        if (localStorage.openedTabs) {
            const openedTabs = JSON.parse(localStorage.openedTabs);
            main.tabs.state = openedTabs.state;
            main.tabs.data = openedTabs.data;

            for (let t in openedTabs.state) {
                if (openedTabs.state[t].bookId) {
                    main.isNewTab = true;
                    if (openedTabs.state[t].chapterId) main.display.chapter(openedTabs.data[t], openedTabs.state[t]);
                    else main.display.book(openedTabs.state[t].bookId);
                } else {
                    main.search.display(openedTabs.data[t], openedTabs.state[t], true);
                }
            }
            e('tab' + localStorage.activeTabId + '-tab').click();
            e('tab' + localStorage.activeTabId + '-tab').scrollIntoView({block: "center"});
            // console.log(localStorage.activeTabId);

            main.display.tabLinkScroll(true);
            localStorage.removeItem('openedTabs');
            localStorage.removeItem('activeTabId');
        }


        if (isDefined(path[2])) {
            event.ctrlKey = true;
            if (isDefined(path[3])) {
                // Открыть по стиху или главе
                const lang = Object.values(bibleInitData.langList).find(city => city.langCode == (path[0].toUpperCase()));
                if(lang) main.getChapter(path[2], path[3], path[4], lang.id, main.tabs.opened);
                else main.getChapter(path[2], path[3], path[4], false, main.tabs.opened);
            } else {
                // Открыть книгу
                main.activeTabId = false;
                main.display.book(path[2]);
            }
            history.replaceState(null, null, '/');
        }
    },
    display: {
        booksList: function (list,orderSeq) {
            let curPar;
            let order = Array();
            for (let o in orderSeq) order [orderSeq[o]] = o;

            e('oldTList').innerHTML = '';
            e('newTList').innerHTML = '';

            for (let o in order){
                if (order[o] < 40) curPar = e('oldTList');
                else curPar = e('newTList');
                e(null, e(null, curPar, 'li'), 'a', 'bookMenuLinks')
                    .a('onclick', 'main.display.book(this.dataset.bookId);')
                    .u('#')
                    .t(list[order[o]]).dataset.bookId = order[o];
            }
        },
        book: function (bookId, chapterRefId) {
            e('leftSidebar').classList.remove('opened');

            main.tabContentBox.scrollTo(0, 0);
            let curBook = bibleInitData.booksChapters[bookId];
            main.tab.changeContent(bibleInitData.booksList[bookId]);
            const langId =
                main.tabs.state[main.activeTabId] && main.tabs.state[main.activeTabId].langId && main.tabs.state[main.activeTabId].langId != 'all'
                    ? main.tabs.state[main.activeTabId].langId
                    : localStorage.langId;

            main.display.bookTools(main.activeTabId, langId, bookId);

            let titl = bibleInitData.booksList[bookId] + ' (' + bibleInitData.langList[langId]['langCode'] + ')';
            e('tab' + main.activeTabId + '-tab').innerText = titl;
            main.display.tabLinkScroll(true);
            main.tabs.history[main.activeTabId][main.tabs.history[main.activeTabId].length] = {
                title: titl,
                func: 'main.display.book(' + bookId + ',' + chapterRefId + ');'
            };

            let chapt, chBox, verBox;
            for (var t in curBook) {
                chapt = curBook[t];

                chBox = e(null, e('tab' + main.activeTabId), 'div', 'chaptBox');
                chBox.dataset.chapt = t;
                e(null, chBox, 'h6').innerText = 'Глава ' + t;
                for (var v in chapt) {
                    verBox = e(null, chBox, 'p', 'verseBox');
                    e(null, verBox, 'a').t(t + ':' + v + ' - ' + chapt[v])
                        .a('onclick', 'main.getChapter(' + bookId + ', ' + t + ', ' + v + ')')
                        .u('#');
                    // e(null, verBox, 'span').t(' - ' + chapt[v]);
                }
            }

            if (chapterRefId) {
                e('tab' + main.activeTabId).querySelector('[data-chapt="' + chapterRefId + '"]').scrollIntoView();
            }

            main.setState(bookId);
        },
        chapter: function (data, params) {
            const titl = bibleInitData.booksList[params.bookId] + ' ' + params.chapterId + ' (' + bibleInitData.langList[params.langId]['langCode'] + ')';
            main.tab.changeContent(titl);
            let tabIndx = /*isDefined(params) && isDefined(params.tabIndx) ? params.tabIndx :*/ main.activeTabId;
            main.display.bookTools(tabIndx, params.langId, params.bookId, params.chapterId, params.substrId);
            main.tabs.history[tabIndx][main.tabs.history[tabIndx].length] = {
                title: titl,
                func: 'main.getChapter(' + params.bookId + ', ' + params.chapterId + ', ' + params.verseNum + ', ' + params.langId + ');'
            };

            params.tabIndx = tabIndx;
            main.tabs.state[tabIndx] = params;
            main.tabs.data[tabIndx] = data;

            let curV, line;

            for (let v in data.verses) {
                curV = data.verses[v];
                line = e(null, e('tab' + tabIndx), 'div', 'row verseLine');
                line.oncopy = main.actions.verse.oncopy;
                line.onclick = main.actions.verse.selectVerse;
                line.dataset.verse = v;
                line.dataset.verseCode = curV.verseCode;
                e(null, line, 'div', 'col-12 col-lg-6 substrTransl').t(curV.subText);
                e(null, e(null, line, 'div', 'col-12 col-lg-6 d-flex'), 'div', 'translText my-auto').t(v + '. ' + curV.text);
                cloneTmpl(line, 'verseMenu');
            }
            if (params.verseNum) {
                const verLine = e('tab' + tabIndx).querySelector('[data-verse="' + params.verseNum + '"]');
                verLine.scrollIntoView({block: "center"});
                verLine.classList.add('activeLine');
                e('tab' + tabIndx).dataset.verse = params.verseNum;
            } else e('tabContent').scrollTop = 0;
        },
        verseInfo: function (verseCode) {
            document.querySelector('main').classList.add('versInfOpened');
            const data = main.tabs.data[main.activeTabId].wordList[verseCode];
            const verseInf = e('verseInfo');
            verseInf.querySelector('table').hidden = false;
            verseInf.dataset.verseCode = verseCode;
            const box = e('verseInfoBody');
            box.innerHTML = '';
            for (let k in data) {
                let line = e(null, box, 'tr', 'wordLine');
                line.dataset.id = data[k].id;
                line.dataset.strongid = data[k].strongId;
                line.dataset.substr = main.tabs.state[main.activeTabId].substrId;
                line.onclick = main.actions.wordInfo;

                e(null, line, 'td').t('<b>'+data[k].origWord + ' (' + data[k].strongId + ')</b><br>'+ data[k].meaning);

               /* e(null, line, 'td').t(data[k].origWord);
                e(null, line, 'td').t(data[k].translation);
                e(null, line, 'td').t(data[k].meaning);*/
            }
        },
        bookTools: function (tabIndx, langId, bookId, chapterId, substrId) {
            const chTools = cloneTmpl(e('tab' + tabIndx), 'bookTools', true);
            // if(chapterId) {
            chTools.querySelector('.btn-group').hidden = false;
            const chaptSelector = chTools.querySelector('select');
            for (let ch in bibleInitData.booksChapters[bookId]) {
                chaptSelector.options[chaptSelector.options.length] = new Option('Глава ' + ch, ch, chapterId == ch, chapterId == ch);
            }
            chTools.dataset.chapter = chapterId;
            // }
            chTools.dataset.book = bookId;
            chTools.dataset.booktype = bookId<40 ? 'old' : 'new';

            chTools.querySelector('.substrSelector').value = substrId;

            main.display.langList(tabIndx, langId);
        },
        tabLinkScroll: function (scrollToActive) {
            const scrollable = e('tabLinks').scrollWidth > e('tabLinks').offsetWidth;
            if (scrollable) {
                e('tabLinks').classList.add('scrollable');
                if (scrollToActive) e('tab' + main.activeTabId + '-tab').scrollIntoView({block: "center"});
            } else e('tabLinks').classList.remove('scrollable');
        },
        langList: function (tabIndx, langId) {
            const curSelector = e('tab' + tabIndx).querySelector('.langSelector');
            if (!isDefined(langId)) curSelector.options[0].disabled = false;
            const tList = Object.values(bibleInitData.langList).sort((l1, l2) => l1['ord'] > l2['ord'] ? 1 : -1);
            for (let ord in tList) {
                let lId = tList[ord]['id'];
                if (isDefined(langId) && langId == lId) curSelector.options[curSelector.options.length] = new Option(bibleInitData.langList[lId]['name'], lId, false, true);
                else curSelector.options[curSelector.options.length] = new Option(bibleInitData.langList[lId]['name'], lId);
            }
        }
    },
    tab: {
        changeContent: function (tabTitle, content) {
            if (main.activeTabId === false || main.isNewTab || event.ctrlKey) this.createNew(content, tabTitle);
            else {
                e('tab' + main.activeTabId + '-tab').t(tabTitle);
                e('tab' + main.activeTabId).t(content);
                return true;
            }
            main.isNewTab = false;
            main.display.tabLinkScroll(true);
        },
        createNew: function (content, tabTitle) {
            let tabCount = (main.tabs.opened++);
            main.tabs.history[tabCount] = [];
            if (document.querySelector('.nav-link.active')) {
                document.querySelector('.nav-link.active').classList.remove('active'); // remove active class for link
                document.querySelector('.tab-pane.active').classList.remove('active'); //
            }
            // create tab link
            const linkLi = e(null, e('tabLinks'), 'li', 'nav-item');
            e('tab' + tabCount + '-tab', linkLi, 'a', 'nav-link active')
                .a('data-toggle', 'tab')
                .a('href', '#tab' + tabCount)
                .a('role', 'tab')
                .a('aria-controls', 'tab' + tabCount)
                .a('aria-selected', 'true')
                .a('data-tabnum', tabCount)
                .t(tabTitle ? tabTitle : 'Новая вкладка');
            e(null, linkLi, 'b').a('onclick', 'main.tab.close(' + tabCount + ')').t('x')

            const hideSubstrCls = isMobile ? 'substrHide' : '';

            // create tab box
            e('tab' + tabCount, e('tabContent'), 'div', 'tab-pane fade show active '+hideSubstrCls)
                .a('role', 'tabpanel')
                .a('aria-labelledby', 'tab' + tabCount + '-tab')
                .t(content ? content : '');


            main.activeTabId = tabCount;

            main.actions.init();

            return true;
        },
        close: function (tabIdx) {
            delete main.tabs.state[tabIdx];
            delete main.tabs.history[tabIdx];
            delete main.tabs.data[tabIdx];
            e('tab' + tabIdx + '-tab').parentNode.remove();
            e('tab' + tabIdx).remove();
            let scrollToActive = false;

            if (tabIdx == main.activeTabId) {
                //display first tab
                let firstIdx = main.getFirstAvailableTabIdx();
                if (firstIdx) {
                    e('tab' + firstIdx + '-tab').click();
                } else main.activeTabId = false;
                scrollToActive = true;
            }
            main.display.tabLinkScroll(scrollToActive);

        },
        onscroll: function (ev) {
            if (isDefined(main.activeTabId)) {
                main.tabs.state[main.activeTabId].scrollTop = ev.scrollTop;
            }
        }
    },
    search: {
        init: function (mode) {
            // если нужно будет делать поиск по номеру стронга, то проверить сначала num>0
            // const num = e('bibleSW').value.replaceAll(/[\D]+/gu, '');
            const sw = e('bibleSW').value.replaceAll(/([^А-яёіїєъґA-zĂÂÎŞȘȚăâîşșțäöüßÄÖÜẞ\n])+/giu, ' ').replaceAll('/\s+/g', ' ');
            if (mode == 'full' && sw.length < 3) {
                alert('Для осуществления поиска введите три или больше БУКВЕННЫХ символа');
                return false;
            } else if (sw.length > 2) {
                if (isDefined(main.presearchTimeout)) clearTimeout(main.presearchTimeout);
                if (mode == 'full') main.search.start({sw: sw, mode: mode});
               // else main.presearchTimeout = setTimeout(main.search.start, 700, {sw: sw, mode: mode});
            }
            e('presearchList').innerHTML = '';
        },
        start: function (arg) {
            j.post(['main', 'search'], function (data, params) {
                if (params.mode == 'pre') main.search.presearchList(data.searchList);
                else main.search.display(data.searchList, params);
            }, arg);
        },
        refine: function () {
            const paramsBox = e('tab' + main.activeTabId).querySelector('.tabTools');
            const params = main.tabs.state[main.activeTabId];

            params.refine = 1;
            // params.caseSensitive = paramsBox.querySelector('.caseSensitive').checked ? 1 : 0;
            // params.exactMatch = paramsBox.querySelector('.exactMatch').checked ? 1 : 0;
            // params.searchStrong = 0; //paramsBox.querySelector('.searchStrong').checked?1:0;
            // params.searchHebrevStrong = 0; //paramsBox.querySelector('.searchHebrevStrong').checked?1:0;
            params.langId = paramsBox.querySelector('.langSelector').value;
            params.bookList = Array.from(paramsBox.querySelectorAll('.bookList option:checked')).map(el => el.value).join(' OR ');

            main.search.start(params);
        },
        presearchList: function (data) {
            e('presearchList').innerHTML = '';
            for (let k of data) {
                let a = e(null, e(null, e('presearchList'), 'li'), 'a')
                    .t('<span>' + k.text + '</span><br><span class="float-right">' + bibleInitData.booksList[k.bookId] + ' ' + k.chapter + ':' + k.verse + '</span>');
                a.dataset.bookId = k.bookId;
                a.dataset.chapterId = k.chapter;
                a.dataset.verseId = k.verse;
                a.dataset.langId = k.langId;
                a.onclick = function (ev) {
                    const link = ev.target.closest('a').dataset;
                    main.isNewTab = true;
                    main.getChapter(link.bookId, link.chapterId, link.verseId, link.langId);
                };
            }
        },
        display: function (dataRes, params, fromLocStorage) {
            e('mainHeader').classList.remove('searchOpened');
            let curCont;
            if (!params.refine || fromLocStorage) {
                main.isNewTab = true;
                const titl = 'Поиск - ' + params.sw.substr(0, 6) + (params.sw.substr(6, 1) ? '...' : '');
                main.tab.changeContent(titl);
                cloneTmpl(e('tab' + main.activeTabId), 'searchTools');
                e('tab' + main.activeTabId).querySelector('.searchFullTitle').innerHTML = "Поиск по запросу \"" + params.sw + "\"";
                main.display.langList(main.activeTabId);
                curCont = e(null, e('tab' + main.activeTabId), 'div', 'row curСontent');
            } else curCont = e('tab' + main.activeTabId).querySelector('.curСontent').t('');

            main.tabs.data[main.activeTabId] = dataRes;

            for (let s in dataRes) {
                let curV = dataRes[s];
                let line = e(null, curCont, 'div', 'searchLine')
                    .t('<span class="float-left">' + curV.text + '</span><br>' +
                        '<span class="float-right sourceText">' + bibleInitData.booksList[curV.bookId] + ' ' + curV.chapter + ':' + curV.verse
                        + ' (' + bibleInitData.langList[curV.langId]['langCode'] + ')</span>');
                line.a('onclick', 'main.isNewTab = true; main.getChapter(' + dataRes[s].bookId + ',' + dataRes[s].chapter + ',' + dataRes[s].verse + ',' + dataRes[s].langId + ')');
                line.dataset.verse = curV.verse;
            }

            this.initParams();
            main.setState(params);

            if (fromLocStorage && isDefined(params.refine)) this.setParams(params);
        },
        initParams: function () {
            for (let b in bibleInitData.booksList) {
                e(null, e('tab' + main.activeTabId).querySelector('.bookList'), 'option').t(bibleInitData.booksList[b]).value = 'bN.bookId = ' + b;
            }
        },
        setParams: function (params) {

            const paramsBox = e('tab' + main.activeTabId).querySelector('.tabTools');
            const bList = params.bookList.split(' OR ');
            e('tab' + main.activeTabId).querySelector('.bookList').value = '';

            for (let k in bList) e('tab' + main.activeTabId).querySelector('option[value="' + bList[k] + '"]').selected = true;
            /*paramsBox.querySelector('.caseSensitive').checked = params.caseSensitive;
            paramsBox.querySelector('.exactMatch').checked = params.exactMatch;
            paramsBox.querySelector('.searchStrong').checked = params.searchStrong;
            paramsBox.querySelector('.searchHebrevStrong').checked = params.searchHebrevStrong;*/
            paramsBox.querySelector('.langSelector').value = params.langId;
        }
    },
    actions: {
        init: function () {
            $('a[data-toggle="tab"]').off().on('shown.bs.tab', function (ev) {
                main.activeTabId = ev.target.dataset.tabnum;
                if (main.tabs.state[main.activeTabId].scrollTop) e('tabContent').scrollTop = main.tabs.state[main.activeTabId].scrollTop;
                else {
                    e('tabContent').scrollTop = 0;
                }
            }).on('mousedown', function (ev) {
                if (ev.which == 2) {
                    ev.preventDefault();
                    ev.stopImmediatePropagation();
                    main.tab.close(ev.target.dataset.tabnum);
                }
            });

            document.onclick = function (ev) {
                const hasOpened = document.querySelector('.moreBox.opened');
                if (hasOpened && !ev.target.closest('.moreBtn') && !ev.target.closest('.verseMenu')) {
                    hasOpened.classList.remove('opened');
                }
            }
        },
        prevChapter: function (ev) {
            let chapterId = ev.closest('.tab-pane').dataset.chapter;
            let bookId = ev.closest('.tab-pane').dataset.book;

            if (chapterId > 1) {
                chapterId--;
            } else if (bookId > 1) {
                bookId--;
                chapterId = Object.keys(bibleInitData.booksChapters[bookId]).length;
            } else {
                alert('Вы просматриваете первую главу Библии');
                return false;
            }
            main.getChapter(bookId, chapterId, 1);
        },
        nextChapter: function (ev) {
            let chapterId = ev.closest('.tab-pane').dataset.chapter;
            let bookId = ev.closest('.tab-pane').dataset.book;

            if (chapterId < Object.keys(bibleInitData.booksChapters[bookId]).length) {
                chapterId++;
            } else if (bookId < 66) {
                bookId++;
                chapterId = 1;
            } else {
                alert('Вы просматриваете последнюю главу Библии');
                return false;
            }
            main.getChapter(bookId, chapterId, 1);
        },
        langChange: function (ev) {
            if(ev.classList.contains('langSelector')){
                localStorage.langId = ev.value;
                main.tabs.state[main.activeTabId].langId = ev.value;
            }

            let chapterId = ev.closest('.tab-pane').dataset.chapter;
            let bookId = ev.closest('.tab-pane').dataset.book;
            let verseId = ev.closest('.tab-pane').dataset.verse;

            if (chapterId != 'undefined') main.getChapter(bookId, chapterId, verseId);
            else main.display.book(bookId);
        },
        verseOptions: function (ev) {
            const hasOpened = document.querySelector('.moreBox.opened');
            if (hasOpened) hasOpened.classList.toggle('opened');
            ev.closest('.moreBox').classList.toggle('opened');
        },
        openHistory: function () {
            console.log('history');
            const curHistory = main.tabs.history[main.activeTabId];
            e('modalMsg').querySelector('.modal-title').innerText = 'История вкладки';
            $('#modalMsg').modal('show');
            let htm = '<ul>';

            for (let k in curHistory) {
                let el = curHistory[k];
                htm += '<li><a href="#" onclick="$(\'#modalMsg\').modal(\'hide\');' + el.func + '">' + el.title + '</a></li>';
            }
            e('modalMsg').querySelector('.modal-body').innerHTML = htm + '</ul>';

        },
        duplicateTab: function () {
            const fromTabIndx = main.activeTabId;
            const toTabIndx = main.tabs.opened;

            main.tabs.state[toTabIndx] = main.tabs.state[fromTabIndx];
            main.tabs.data[toTabIndx] = main.tabs.data[fromTabIndx];

            main.tabs.state[toTabIndx].tabIndx = toTabIndx;

            main.isNewTab = true;
            const curState = main.tabs.state[toTabIndx];
            if (curState.chapterId) main.display.chapter(main.tabs.data[toTabIndx], main.tabs.state[toTabIndx]);
            else main.display.book(curState.bookId);
        },
        copyChapterTxt: function (fromVerse, toVerse) {
            fromVerse = fromVerse || 1;
            toVerse = toVerse || Object.keys(main.tabs.data[main.activeTabId].verses).length;

            let fullChapterTxt = '';
            for (let vers in main.tabs.data[main.activeTabId].verses) {
                if (fromVerse <= vers && vers <= toVerse)
                    fullChapterTxt += (fullChapterTxt==''?'':"\n") + vers + ". " +
                        main.decodeEntities(main.tabs.data[main.activeTabId].verses[vers]['text']).trim();
            }
            const curState = main.tabs.state[main.activeTabId];
            fullChapterTxt = bibleInitData.booksList[curState.bookId] + " " + curState.chapterId + ":" + fromVerse + (fromVerse != toVerse ? ("-" + toVerse) : '') + "\n\"" +
                fullChapterTxt.replace(/(<([^>]+)>)/ig, '') + "\"";
            // Clipboard.copy(fullChapterTxt);
            navigator.clipboard.writeText(fullChapterTxt);
        },
        switchLight: function (lightStatus) {
            localStorage.darkTheme = !lightStatus;
            if (lightStatus == 1) document.body.classList.remove('darkTheme');
            else document.body.classList.add('darkTheme');

            e('themeSwither').checked = lightStatus;
        },
        font: {
            decrease: function () {
                const r = document.querySelector(':root');
                let newFS = localStorage.fontSize ? --localStorage.fontSize : 15;
                newFS = newFS < 12 ? 12 : newFS;
                r.style.setProperty('--fontSize', newFS);
                localStorage.fontSize = newFS;
            },
            setDef: function () {
                const r = document.querySelector(':root');
                let newFS = 16;
                r.style.setProperty('--fontSize', newFS);
                localStorage.fontSize = newFS;
            },
            increase: function () {
                const r = document.querySelector(':root');
                let newFS = localStorage.fontSize ? ++localStorage.fontSize : 17;
                newFS = newFS > 30 ? 30 : newFS;
                r.style.setProperty('--fontSize', newFS);
                localStorage.fontSize = newFS;
            }
        },
        verse: {
            copyTxt: function (el) {
                const verse = el.closest('.verseLine');
                const verseNum = verse.dataset.verse;
                let txt = main.tabs.data[main.activeTabId].verses[verseNum].text;
                const curState = main.tabs.state[main.activeTabId];
                txt = bibleInitData.booksList[curState.bookId] + " " + curState.chapterId + ":" + verseNum + "\n\"" + txt.trim().replace(/(<([^>]+)>)/ig, '') + "\"";

                Clipboard.copy(txt);
            },
            /**
             * @param el - event
             * @param copy - copy? or return
             */
            link: function (el, copy) {
                let verseNum = false;
                if(el && el.closest('.verseLine')) verseNum = el.closest('.verseLine').dataset.verse;
                const curState = main.tabs.state[main.activeTabId];
                let link = 'https://rubible.org/';

                if(curState){
                    const curLangCode = bibleInitData.langList[curState.langId].langCode.toLowerCase();
                    link +=  curLangCode + "/" +
                        toUrl(bibleInitData.booksList[curState.bookId] + (curState.chapterId ? ' Глава ' + curState.chapterId : '')) + '/' +
                        curState.bookId + (curState.chapterId ? '/' + curState.chapterId : '') + (verseNum ? '/' + verseNum : '');
                }

                if(copy) Clipboard.copy(link);
                else return link;
            },
            getTranslations: function (el) {
                const curState = main.tabs.state[main.activeTabId];
                const verseNum = el.closest('.verseLine').dataset.verse;
                e('modalMsg').querySelector('.modal-title').innerText = 'Все переводы стиха';
                j.post(['main', 'getVerseTranslations'], function (data) {
                    e('modalMsg').querySelector('.modal-body').innerHTML = '';
                    for (let k in data.verses) {
                        e('modalMsg').querySelector('.modal-body').innerHTML += '<p>' + data.verses[k] + '</p>';
                    }

                    $('#modalMsg').modal('show');
                }, {verseCode: el.closest('.verseLine').dataset.verseCode});
            },
            selectVerse: function (ev) {
                // тут проверить айди стиха, если другой то обновить (если нет, то ничего не делать)
                const verLine = ev.target.closest('.verseLine');
                const tabIndx = main.activeTabId;
                const activeLines = e('tab' + tabIndx).querySelectorAll('.activeLine');
                // Если раскомментировать, будет работать множественное выделение стихов (ектив стилем).
                if(!ev.ctrlKey) activeLines.forEach(function (el) {
                    el.classList.remove('activeLine');
                });
                verLine.classList.add('activeLine');
                e('tab' + tabIndx).dataset.verse = verLine.dataset.verse;

                const verseCode = verLine.dataset.verseCode;
                main.display.verseInfo(verseCode);
            },
            oncopy: function (ev) {
                ev.preventDefault();
                ev.stopImmediatePropagation();

                const startVerse = parseInt(window.getSelection().getRangeAt(0).startContainer.parentElement.innerText);
                const endVerse = parseInt(window.getSelection().getRangeAt(0).endContainer.parentElement.innerText);

                main.actions.copyChapterTxt(startVerse, endVerse);

                // написать сообщение что стихи скопированы
            }
        },
        sidebarSeparating: function (ev) {
            const infBox = e('verseInfo');
            const d = (main.sidebarSepY > ev.screenY ? -1 : 1) * Math.abs(main.sidebarSepY - ev.screenY);
            const h1 = main.sidebarSepPos + d
            infBox.style.height = h1 + 'px';
            const wrdBox = e('wordInfo');
            wrdBox.style.height = e('rightSidebar').clientHeight - 6 -  h1 + 'px';
        },
        wordInfo: function () {
            let verseCode, vocabWordId, substrId, strongId;
            const clkTarget = event.target;
            if (clkTarget.closest('.verseLine')) { // если это клик из текста стиха
                verseCode = clkTarget.closest('.verseLine').dataset.verseCode;
                vocabWordId = clkTarget.dataset.id;
                strongId = main.tabs.data[main.activeTabId].wordList[verseCode][vocabWordId].strongId;
                substrId = clkTarget.dataset.substr;
            } else { // если это клик из таблицы в правой панели
                strongId = clkTarget.closest('.wordLine').dataset.strongid;
                vocabWordId = clkTarget.closest('.wordLine').dataset.id;
                substrId = clkTarget.closest('.wordLine').dataset.substr;
            }

            j.post(['main', 'getStrongWord'], function (data, params) {
                const wordTable = isMobile ? document.querySelector('#modalMsg .modal-body') : e('wordInfo');
                wordTable.innerHTML = '';
                wordTable.classList.add('wordInfoBox');
                if(data.strongInfo != null){
                    e(null,wordTable,'div').innerHTML = '<audio src="' + data.strongInfo.audio + '" controls></audio><br>' +
                        '<b>'+data.strongInfo.id+', '+data.strongInfo.originalWord+'</b>';
                    e(null,wordTable,'div').innerHTML = data.strongInfo.translation;
                    if(isDefined(data.strongInfo.mnemonika)) e(null,wordTable,'div').innerHTML = data.strongInfo.mnemonika;
                    e(null,wordTable,'div').innerHTML = data.strongInfo.definition;

                    let tmpTxt = '';
                    if(data.newTUsedList){
                        data.newTUsedList.forEach(function (val) {
                            tmpTxt += '<p class="wordFound"><a onmouseover="main.actions.versePopup(this);" onclick="main.getChapter('+val.book+', '+val.chapter+', '+val.verse+')" href="#">' +
                                bibleInitData.booksList[val.book]+ ` ${val.chapter}:${val.verse}` +
                                '</a><small><i>'+val.text+'</i><br>- Подстрочный перевод:<br><i>'+val.substrTxt+'</i></small></p> ';
                        });
                        let moreTxt = data.newTUsedList.length > 100 ? '<br>Показаны лишь первые 100 мест.' : '';
                        e(null,wordTable,'div').t("<b>Места где встречается данное слово</b> (НЗ):<br>"+tmpTxt+moreTxt);
                    }

                    tmpTxt = '';
                    if(data.oldTUsedList){
                        data.oldTUsedList.forEach(function (val) {
                            tmpTxt += '<p class="wordFound"><a onmouseover="main.actions.versePopup(this);" onclick="main.getChapter('+val.book+', '+val.chapter+', '+val.verse+')" href="#">' +
                                bibleInitData.booksList[val.book]+ ` ${val.chapter}:${val.verse}` +
                                '</a><small><i>'+val.text+'</i><br>- Подстрочный перевод:<br><i>'+val.substrTxt+'</i></small></p> ';
                        });
                        let moreTxt = data.oldTUsedList.length > 100 ? '<br>Показаны лишь первые 100 мест.' : '';
                        e(null,wordTable,'div').t("<b>Места где встречается данное слово</b> (ВЗ):<br>"+tmpTxt+moreTxt);
                    }

                    const activeLines = e('verseInfo').querySelectorAll('.activeLine');
                    activeLines.forEach(function (el) {
                        el.classList.remove('activeLine');
                    });

                    e('verseInfo').querySelector('tr[data-id="' + params.vocabWordId + '"]').classList.add('activeLine');
                    e('verseInfo').querySelector('tr[data-id="' + params.vocabWordId + '"]').scrollIntoView({block: "center"});
                }
                else e(null, wordTable, 'div').t('По этому слову в базе данные отсутствуют');

                if(isMobile) {
                    e('modalMsg').querySelector('.modal-title').innerText = 'Словарь';
                    $('#modalMsg').modal('show');
                }
            }, {
                strongId: strongId,
                vocabWordId: vocabWordId,
                substrId: substrId,
                langId: main.tabs.state[main.activeTabId].langId
            });
        },
        versePopup: function (ev) {
            const popupH = ev.nextElementSibling.offsetHeight;
            const topPos = event.layerY - 25;
            if(topPos > popupH) ev.nextElementSibling.style.marginTop = -popupH + 'px';
            else ev.nextElementSibling.style = '';
        },
        substrSwitcher: function () {
            e('tab' + main.activeTabId).classList.toggle('substrHide');
        }
    },
    decodeEntities: function (str) {
        let element = document.createElement('div');
        if (str && typeof str === 'string') {
            // strip script/html tags
            str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '');
            str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '');
            element.innerHTML = str;
            str = element.textContent;
            element.textContent = '';
        }

        return str;
    },
    getChapter: function (bookId, chapterId, verseNum, langId, tabIndx) {
        e('mainHeader').classList.remove('searchOpened');
        langId =
            main.tabs.state[main.activeTabId] && main.tabs.state[main.activeTabId].langId && main.tabs.state[main.activeTabId].langId != 'all'
                ? main.tabs.state[main.activeTabId].langId
                : localStorage.langId;
        let substrId = main.tabs.state[main.activeTabId] && main.tabs.state[main.activeTabId].substrId ? main.tabs.state[main.activeTabId].substrId : localStorage.substrId;
        main.isNewTab = main.isNewTab ? main.isNewTab : event.ctrlKey;

        if (chapterId) j.post(['main', 'getVerses'], main.display.chapter, {
            bookId: bookId,
            chapterId: chapterId,
            verseNum: verseNum,
            langId: langId,
            tabIndx: tabIndx,
            substrId: substrId
        });
        else main.display.book(bookId);
    },
    changeVerseLang: function (verseCode, langId, tabIndx) {
        let substrId = main.tabs.state[main.activeTabId] && main.tabs.state[main.activeTabId].substrId ? main.tabs.state[main.activeTabId].substrId : localStorage.substrId;

        j.post(['main', 'getVerses'], function (data, params) {
            params.bookId =
            params.chapterId =
            params.verseNum =
            main.display.chapter(data, params);
        }, {
            verseCode: verseCode,
            langId: langId,
            tabIndx: tabIndx,
            substrId: substrId
        });
    },
    setState: function (bookId, chapterId, verseId, langId) {
        if (!isDefined(main.tabs.state[main.activeTabId])) main.tabs.state[main.activeTabId] = {};
        if ((typeof bookId === "object") && (bookId !== null)) {
            main.tabs.state[main.activeTabId] = bookId;
        } else {
            main.tabs.state[main.activeTabId].bookId = isDefined(bookId) ? bookId : false;
            main.tabs.state[main.activeTabId].chapterId = isDefined(chapterId) ? chapterId : false;
            main.tabs.state[main.activeTabId].verseId = isDefined(verseId) ? verseId : false;
            main.tabs.state[main.activeTabId].langId =
                isDefined(langId) ? langId // если передан параметр
                    : main.tabs.state[main.activeTabId].langId ? main.tabs.state[main.activeTabId].langId // если уже установлено значение
                    : localStorage.langId; // по умолчанию
        }
    },
    getFirstAvailableTabIdx: function () {
        for (let tabsKey in main.tabs.state) {
            if (main.tabs.state[tabsKey]) return tabsKey;
        }
        return false;
    },
    bibleUrl: function (b, c, v) {
        let url = '/' + toUrl(bibleInitData.booksList[b].trim().replace(' ', '+'));

        if (isDefined(v)) url += '-Глава-' + c + '/' + b + '/' + c + '/' + v;
        else if (isDefined(c)) url += '-Глава-' + c + '/' + b + '/' + c + '/';
        else if (isDefined(b)) url += '/' + b + '/';

        return url;
    }
}