Greasy Fork

Greasy Fork is available in English.

HWHNewCharacterExt

Extension for HeroWarsHelper script

当前为 2025-10-27 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name             HWHNewCharacterExt
// @name:en          HWHNewCharacterExt
// @name:ru          HWHNewCharacterExt
// @namespace        HWHNewCharacterExt
// @version          1.40
// @description      Extension for HeroWarsHelper script
// @description:en   Extension for HeroWarsHelper script
// @description:ru   Расширение для скрипта HeroWarsHelper
// @author           ZingerY, Green
// @license          Copyright Green
// @match            https://www.hero-wars.com/*
// @match            https://apps-1701433570146040.apps.fbsbx.com/*
// @run-at           document-start
// ==/UserScript==

(function () {
    if (!this.HWHClasses) {
        console.log('%cObject for extension not found', 'color: red');
        return;
    }

    console.log('%cStart Extension ' + GM_info.script.name + ', v' + GM_info.script.version + ' by ' + GM_info.script.author, 'color: red');
    const { addExtentionName } = HWHFuncs;
    addExtentionName(GM_info.script.name, GM_info.script.version, GM_info.script.author);

    const { buttons } = HWHData;
    const {
        popup,
        confShow,
        getInput,
        setProgress,
        hideProgress,
        I18N,
        send,
        getTimer,
        countdownTimer,
        getUserInfo,
        getSaveVal,
        setSaveVal,
        setIsCancalBattle,
        random,
        EventEmitterMixin,
    } = HWHFuncs;

    const { i18nLangData } = HWHData;

    const { WinFixBattle } = HWHClasses;

    const i18nLangDataEn = {

        NEWCHARACTER: 'New Character',
        NEWCHARACTER_TITLE: 'Complete quests for a new hero or titan',
        NEWCHARACTER_NOEVENT: 'The event is not active',
        NEWHERO: '<span style="color: green;"> New Hero Event </span> <br>',
        NEWTITAN: '<span style="color: green;"> New Titan Event </span> <br>',
        NEWHERO_COMPLETETASKS: 'Complete the tasks',
        NEWHERO_COMPLETETASKS_TITLE: 'Complete the event tasks',
        NEWHERO_COMPLETECAPTERS:'Complete chapters',
        NEWHERO_COMPLETECAPTERS_TITLE:'Complete chapters',
        NEWHERO_SELECTACTION:'Select an action',
        NEWTITAN_GETTITANS: 'Сollect the Titans',
        NEWTITAN_GETTITANS_TITLE: 'Сollecting the Titans of the maximum rank by purchasing fragments in the store',
        NEWTITAN_GETHEROES: 'Сollect the Heroes',
        NEWTITAN_GETHEROES_TITLE: 'Сollecting the Heroes of the maximum rank by purchasing fragments in the store',
        NEWTITAN_GETINFLUENCESKILL: 'Сollect totem skills',
        NEWTITAN_GETINFLUENCESKILL_TITLE: 'Get the influence skill of the maximum rank by purchasing fragments in the store',
        NEWTITAN_GETTITANSPROGRESS: '<span style="color: green;"> {counter} </span> titans left to collect',
        NEWTITAN_GETTITANSCOLLECTED: 'All titans have been collected',
        NEWTITAN_GETINFLUENCESKILLCOLLECTED: 'All influence skills have been collected',
        NEWTITAN_GETINFLUENCESKILLPROGRESS: '<span style="color: green;"> {counter} </span> influence skills left to collect <br> Collecting...',
        NEWTITAN_CHAPTERNOTAVAILABLE: 'Chapter unavailable. Complete Chapter 1',
        NEWTITAN_GETHEROCOLLECTED: 'All heroes have been collected',
        NEWTITAN_GETHEROCOLLECTEDPROGRESS: '<span style="color: green;"> {counter} </span> heroes left to collect <br> Collecting...',
        NEWCHARACTER_SOMETHINGWENTWRONG:'<span style="color: red;"> Something went wrong </span> <br> Please try again',
        NEWTITAN_COLLECTEVERYTHING:'Collect everything',
        NEWTITAN_COLLECTEVERYTHING_TITLE:'Collect heroes, titans, totems, pets',
        NEWTITAN_BOSSWASKILLED:'<span style="color: green;"> The boss was killed </span>',
    };

    i18nLangData['en'] = Object.assign(i18nLangData['en'], i18nLangDataEn);

    const i18nLangDataRu = {
        NEWCHARACTER: 'Новый персонаж',
        NEWCHARACTER_TITLE: 'Выполнять задания для нового героя или титана',
        NEWCHARACTER_NOEVENT: 'Ивент не активен',
        NEWHERO: '<span style="color: green;"> Событие Нового Героя </span> <br>',
        NEWTITAN: '<span style="color: green;"> Событие Нового Титана </span> <br>',
        NEWHERO_COMPLETETASKS: 'Выполнить задания',
        NEWHERO_COMPLETETASKS_TITLE: 'Выполнить заданий ивента',
        NEWHERO_COMPLETECAPTERS:'Проходить главы',
        NEWHERO_COMPLETECAPTERS_TITLE:'Проходить главы',
        NEWHERO_SELECTACTION:'Выберите действие',
        NEWTITAN_GETTITANS: 'Собрать титанов',
        NEWTITAN_GETTITANS_TITLE: 'Собрать титанов максимального ранга, покупая фрагменты в магазине',
        NEWTITAN_GETHEROES: 'Собрать героев',
        NEWTITAN_GETHEROES_TITLE: 'Собрать героев максимального ранга, покупая фрагменты в магазине',
        NEWTITAN_GETINFLUENCESKILL: 'Собрать тотемы',
        NEWTITAN_GETINFLUENCESKILL_TITLE: 'Собрать навыки тотемов максимального ранга, покупая фрагменты в магазине',
        NEWTITAN_GETTITANSPROGRESS: 'Осталось собрать титанов: <span style="color: green;"> {counter} </span> шт.',
        NEWTITAN_GETTITANSCOLLECTED: 'Все титаны собраны',
        NEWTITAN_GETINFLUENCESKILLCOLLECTED: 'Все навыки влияния собраны',
        NEWTITAN_GETINFLUENCESKILLPROGRESS: 'Осталось собрать навыков тотемов: <span style="color: green;"> {counter} </span> шт. <br> Собираем...',
        NEWTITAN_CHAPTERNOTAVAILABLE: 'Глава не доступна. Завершите первую главу',
        NEWTITAN_GETHEROCOLLECTED: 'Все герои собраны',
        NEWTITAN_GETHEROCOLLECTEDPROGRESS: 'Осталось собрать героев: <span style="color: green;"> {counter} </span> шт. <br> Собираем...',
        NEWCHARACTER_SOMETHINGWENTWRONG:'<span style="color: red;"> Что то пошло не так </span> <br> Попробуйте заново',
        NEWTITAN_COLLECTEVERYTHING:'Собрать все',
        NEWTITAN_COLLECTEVERYTHING_TITLE:'Собрать героев, титанов, тотемы, питомцев',
        NEWTITAN_BOSSWASKILLED:'<span style="color: green;"> Убили босса </span>',
    };

    i18nLangData['ru'] = Object.assign(i18nLangData['ru'], i18nLangDataRu);

    ///////////////////////////////////////////////////////////////////////////////////////////////


    // Добавление кнопоки в окно Разное
    const { othersPopupButtons } = HWHData;
    othersPopupButtons.push({
        get msg() { return I18N('NEWCHARACTER'); },
        get title() { return I18N('NEWCHARACTER_TITLE'); },
        result: async function () {
            let invasionInfo = await Caller.send('invasion_getInfo');
            let invasionInfoId = invasionInfo.id;

            if(invasionInfo){
                let chapters = Object.values(lib.data.invasion.chapter).filter(e => e.invasionId === invasionInfoId)
                let chapterId = chapters[0].id
                let titanShopId = await getShopId(chapters, "titan");
                try {
                    if (titanShopId){
                        await onClickNewTitanButton();
                    }else{
                        await onClickNewHeroButton();
                    }
                } catch (e) {
                    confShow(`${I18N('NEWCHARACTER_SOMETHINGWENTWRONG')}`);
                }
            }else{
                confShow(`${I18N('NEWCHARACTER_NOEVENT')}`);
            }

        },
    });

    async function onClickNewHeroButton() {
        const popupButtons = [
            {
                get msg() { return I18N('NEWHERO_COMPLETETASKS'); },
                get title() { return I18N('NEWHERO_COMPLETETASKS_TITLE'); },
                result:async function () {
                    confShow('Нажата кнопка');
                },
            },
            {
                get msg() { return I18N('NEWHERO_COMPLETECAPTERS'); },
                get title() { return I18N('NEWHERO_COMPLETECAPTERS_TITLE'); },
                result: () => {
                    confShow('Нажата кнопка 2');
                },
            },
        ];
        popupButtons.push({ result: false, isClose: true });
        const answer = await popup.confirm(`${I18N('NEWHERO')} ${I18N('NEWHERO_SELECTACTION')}`, popupButtons);
        if (typeof answer === 'function') {
            answer();
        }
    }

    async function onClickNewTitanButton() {
        const popupButtons = [
            {
                get msg() { return I18N('NEWTITAN_GETTITANS'); },
                get title() { return I18N('NEWTITAN_GETTITANS_TITLE'); },
                result:async function () {
                    await newTitanGetTitans();
                },
            },
            {
                get msg() { return I18N('NEWTITAN_GETINFLUENCESKILL'); },
                get title() { return I18N('NEWTITAN_GETINFLUENCESKILL_TITLE'); },
                result:async function () {
                    await newTitanGetInvasionFragmentSkill();
                },
            },
            {
                get msg() { return I18N('NEWTITAN_GETHEROES'); },
                get title() { return I18N('NEWTITAN_GETHEROES_TITLE'); },
                result:async function () {
                    let farmedChapters = await Caller.send('invasion_getInfo').then(e => e.farmedChapters);
                    if(farmedChapters.length >= 1){
                        await newTitanGetHeroes();
                    }else{
                        confShow(`${I18N('NEWTITAN_CHAPTERNOTAVAILABLE')}`);
                    }
                },
            },
            {
                get msg() { return I18N('NEWTITAN_COLLECTEVERYTHING'); },
                get title() { return I18N('NEWTITAN_COLLECTEVERYTHING_TITLE'); },
                result:async function () {
                    await newTitanGetTitans();
                    await newTitanGetInvasionFragmentSkill();
                    let farmedChapters = await Caller.send('invasion_getInfo').then(e => e.farmedChapters);
                    if(farmedChapters.length >= 1){
                        await newTitanGetHeroes();
                    }else{
                        confShow(`${I18N('NEWTITAN_CHAPTERNOTAVAILABLE')}`);
                    }
                },
                color: 'pink',
            },

        ];
        popupButtons.push({ result: false, isClose: true });
        const answer = await popup.confirm(`${I18N('NEWTITAN')} ${I18N('NEWHERO_SELECTACTION')}`, popupButtons);
        if (typeof answer === 'function') {
            answer();
        }
    }


    async function newTitanGetTitans(){
        //Получить состояние на карте
        let invasionInfo = await Caller.send('invasion_getInfo');
        let invasionInfoId = invasionInfo.id;
        let farmedChapters = invasionInfo.farmedChapters;
        console.log("invasionInfoId " + invasionInfoId);
        console.log("farmedChapters ", JSON.stringify(farmedChapters));

        //Сброс главы
        await Caller.send('invasion_resetChapter')

        //Получить id первой главый
        let chapters = Object.values(lib.data.invasion.chapter).filter(e => e.invasionId === invasionInfoId)
        let chapterId = await getChapterId(chapters, 'titan');
        console.log("chapterId " + chapterId);

        //Получить id магазина
        let titanShopId = await getShopId(chapters, "titan"); //1073; // Магазин титанов
        console.log("Id магазина титанов " + titanShopId);


        let cycle = true;
        while( cycle ){
            //Получить титанов, которых нужно собрать
            let allTitanIdsToBuy = await getTitanIdsToBuy();
            if (allTitanIdsToBuy.length == 0){
                setProgress("", true);
                //await new Promise((e) => setTimeout(e, 4000));
                confShow(I18N('NEWTITAN_GETTITANSCOLLECTED'));
                cycle = false;
                return;
            }

            //Активировать главу
            let chapterInfo = await Caller.send({name: 'invasion_setActiveChapter',args: {chapterId: chapterId}});
            let haveTitanFragments = chapterInfo.invasion.fragments;

            //Id миссии
            let firstMissionId = chapterInfo.invasion.actions[0].payload.id;
            let missionId = firstMissionId;

            //Жизни
            let lives = chapterInfo.invasion.lives;
            console.log("firstMissionId "+ firstMissionId);
            console.log("missionId "+ missionId);
            console.log("lives "+ lives);


            //Id титанов, что необходимо собрать
            let titanIds = [0, 0];
            if (allTitanIdsToBuy.length >= 2){
                titanIds = [allTitanIdsToBuy[0], allTitanIdsToBuy[1]];
            }else{
                titanIds[0] = allTitanIdsToBuy[0]
                if (titanIds[0] != Number(Object.keys(haveTitanFragments)[0])){
                    titanIds[1] = Number(Object.keys(haveTitanFragments)[0]);
                }else{
                    titanIds[1] = Number(Object.keys(haveTitanFragments)[1]);
                }
             }
            //Фрагменты титанов
            let titanFragments = [0, 0];
            if (haveTitanFragments[titanIds[0]]){
                titanFragments[0] = haveTitanFragments[titanIds[0]];
            }
            if (haveTitanFragments[titanIds[1]]){
                titanFragments[1] = haveTitanFragments[titanIds[1]];
            }

            console.log("titanShopId "+ titanShopId);
            console.log(titanIds);
            console.log(titanFragments);

            //Навыки тотемов, что необходимо собрать
            let titanSkilsIds = await getTitanSkillIdsToBuy()

            //Фрагменты навыков тотемов
            let titanSkilFragments = [0, 0];
            if (titanSkilsIds.length <= 1){
                titanSkilFragments = [0];
            }

            setProgress(I18N('NEWTITAN_GETTITANSPROGRESS', {counter:allTitanIdsToBuy.length}) + "<br>" + I18N('NEWTITAN_GETINFLUENCESKILLPROGRESS', {counter:titanSkilsIds.length}), false);

            while( lives > 0 && missionId <= (firstMissionId+7)){
                //Купить титанов
                let result = await buyTitanInTheStore(titanShopId, titanIds, titanFragments, titanSkilsIds, titanSkilFragments);
                //Выйти, если босс побежден и полностью собрали двух титанов.
                if (result && farmedChapters.includes(chapterId)){
                    break;
                }
                //Текущая миссия босс или нет
                let boss = false;

                //Произвести атаку босса, если его ни разу не убили
                if(!farmedChapters.includes(chapterId)){
                    if (missionId == (firstMissionId+7)){
                        boss = true;
                        console.log("%cАтакуем босса ", "color: green; font-weight: bold;")
                    }
                }else{
                    //Не атаковать босса, если его уже убили
                    if (missionId == (firstMissionId+7)){
                        break;
                    }
                }

                //Получить атакующую команду
                let heroes = [];
                haveTitanFragments = await Caller.send('invasion_getInfo').then(e => e.fragments);
                for (let f in haveTitanFragments){
                    //Исключаем фрагменты тотемов
                    if(Number(f) < 4400){
                        heroes.push(Number(f));
                    }
                    if(heroes.length == 5){
                        break;
                    }
                }
                let firstSpiritSkills = {};

                //Проходим миссию
                await attackTitanMission(missionId, chapterId, heroes, firstSpiritSkills, boss);


                //Результат атаки
                let invasionInfo = await Caller.send('invasion_getInfo');
                farmedChapters = invasionInfo.farmedChapters;
                let missions = Object.values(invasionInfo.actions);
                for(let mission of missions){
                    if (mission.payload.wins == 0){
                        missionId = mission.payload.id;
                        break;
                    }
                }
                lives = invasionInfo.lives;
                console.log("missionId "+ missionId);
                console.log("lives "+ lives);
            }
        }
    }
    async function newTitanGetInvasionFragmentSkill() {
        //Получить состояние на карте
        let invasionInfo = await Caller.send('invasion_getInfo');
        let invasionInfoId = invasionInfo.id;
        let farmedChapters = invasionInfo.farmedChapters;
        console.log("invasionInfoId " + invasionInfoId);
        console.log("farmedChapters ", JSON.stringify(farmedChapters));

        //Сброс главы
        await Caller.send('invasion_resetChapter')

        //Получить id первой главый
        let chapters = Object.values(lib.data.invasion.chapter).filter(e => e.invasionId === invasionInfoId)
        let chapterId = await getChapterId(chapters, 'titan');
        console.log("chapterId " + chapterId);

        //Получить id магазина
        let titanShopId = await getShopId(chapters, 'titan'); //1073; // Магазин титанов
        console.log("Id магазина титанов " + titanShopId);

        let cycle = true;
        while( cycle ){
            //Получить навыки тотемов, которые нужно собрать
            let titanSkilsIds = await getTitanSkillIdsToBuy()
            if (titanSkilsIds.length == 0){
                setProgress("", true);
                //await new Promise((e) => setTimeout(e, 4000));
                confShow(I18N('NEWTITAN_GETINFLUENCESKILLCOLLECTED'));
                cycle = false;
                return;
            }
            console.log(titanSkilsIds);
            setProgress(I18N('NEWTITAN_GETINFLUENCESKILLPROGRESS', {counter:titanSkilsIds.length}), false);

            //Фрагменты навыков тотемов
            let titanSkilFragments = [0, 0];
            if (titanSkilsIds.length == 1){
                titanSkilFragments = [0];
            }

            //Активировать главу
            let chapterInfo = await Caller.send({name: 'invasion_setActiveChapter',args: {chapterId: chapterId}});
            let haveTitanFragments = chapterInfo.invasion.fragments;

            //Id миссии
            let firstMissionId = chapterInfo.invasion.actions[0].payload.id;
            let missionId = firstMissionId;

            //Жизни
            let lives = chapterInfo.invasion.lives;
            console.log("firstMissionId "+ firstMissionId);
            console.log("missionId "+ missionId);
            console.log("lives "+ lives);

            //Id титанов, что необходимо купить
            //Ияри и Солярис
            let titanIds = [4042, 4043];

            //Фрагменты титанов
            let titanFragments = [0, 0];
            if (haveTitanFragments[titanIds[0]]){
                titanFragments[0] = haveTitanFragments[titanIds[0]];
            }
            if (haveTitanFragments[titanIds[1]]){
                titanFragments[1] = haveTitanFragments[titanIds[1]];
            }

            console.log("titanShopId "+ titanShopId);
            console.log(titanIds);
            console.log(titanFragments);


            while( lives > 0 && missionId <= (firstMissionId+7)){
                //Купить титанов и навыки тотемов
                let result = await buyTotemSkilsInTheStore(titanShopId, titanIds, titanFragments, titanSkilsIds, titanSkilFragments);
                //Выйти, если босс побежден и полностью собрали два навыка тотема
                if (result && farmedChapters.includes(chapterId)){
                    break;
                }

                //Текущая миссия босс или нет
                let boss = false;

                //Произвести атаку босса, если его ни разу не убили
                if(!farmedChapters.includes(chapterId)){
                    if (missionId == (firstMissionId+7)){
                        boss = true;
                        console.log("%cАтакуем босса ", "color: green; font-weight: bold;")
                    }
                }else{
                    //Не атаковать босса, если его уже убили
                    if (missionId == (firstMissionId+7)){
                        break;
                    }
                }

                //Получить атакующую команду
                let heroes = [];
                haveTitanFragments = await Caller.send('invasion_getInfo').then(e => e.fragments);
                for (let f in haveTitanFragments){
                    //Исключаем фрагменты тотемов
                    if(Number(f) < 4400){
                        heroes.push(Number(f));
                    }
                    if(heroes.length == 5){
                        break;
                    }
                }
                console.log(heroes)

                let firstSpiritSkills = {};

                //Проходим миссию
                await attackTitanMission(missionId, chapterId, heroes, firstSpiritSkills);

                //Результат атаки
                let invasionInfo = await Caller.send('invasion_getInfo');
                farmedChapters = invasionInfo.farmedChapters;
                let missions = Object.values(invasionInfo.actions);
                for(let mission of missions){
                    if (mission.payload.wins == 0){
                        missionId = mission.payload.id;
                        break;
                    }
                }
                lives = invasionInfo.lives;
                console.log("missionId "+ missionId);
                console.log("lives "+ lives);
            }
        }
    }

    async function newTitanGetHeroes() {
        //Получить состояние на карте
        let invasionInfo = await Caller.send('invasion_getInfo');
        let invasionInfoId = invasionInfo.id;
        let farmedChapters = invasionInfo.farmedChapters;
        console.log("invasionInfoId " + invasionInfoId);
        console.log("farmedChapters ", JSON.stringify(farmedChapters));

        //Сброс главы
        await Caller.send('invasion_resetChapter')

        //Получить id главый
        let chapters = Object.values(lib.data.invasion.chapter).filter(e => e.invasionId === invasionInfoId)
        let chapterId = await getChapterId(chapters, 'hero');
        console.log("chapterId " + chapterId);

        //Получить id магазина
        let heroShopId = await getShopId(chapters, 'hero'); //1074; // Магазин героев
        console.log("Id магазина героев " + heroShopId);

        //Счетчик купленных питомцев
        let petCounter = [0];

        let cycle = true;
        while( cycle ){
            //Получить героев, которых нужно собрать
            let heroIdsToBuy = await getHeroIdsToBuy()
            if (heroIdsToBuy.length == 0){
                setProgress("", true);
                //await new Promise((e) => setTimeout(e, 4000));
                confShow(I18N('NEWTITAN_GETHEROCOLLECTED'));
                cycle = false;
                return;
            }
            console.log(heroIdsToBuy);
            setProgress(I18N('NEWTITAN_GETHEROCOLLECTEDPROGRESS', {counter:heroIdsToBuy.length}), false);

            //Активировать главу
            let chapterInfo = await Caller.send({name: 'invasion_setActiveChapter',args: {chapterId: chapterId}});
            let haveHeroFragments = chapterInfo.invasion.fragments;

            //Id миссии
            let firstMissionId = chapterInfo.invasion.actions[0].payload.id;
            let missionId = firstMissionId;

            //Жизни
            let lives = chapterInfo.invasion.lives;
            console.log("firstMissionId "+ firstMissionId);
            console.log("missionId "+ missionId);
            console.log("lives "+ lives);

            //Id героев, что необходимо купить
            let heroIds = [0, 0, 0];

            if (heroIdsToBuy.length >= 3){
                heroIds = [heroIdsToBuy[0], heroIdsToBuy[1], heroIdsToBuy[2]];
            }
            //Резервные герои, для добавления в покупки: Галахад, Тристан, Лирия
            let reserveHeroes = [2, 54, 67]
            if (heroIdsToBuy.length == 2){
                heroIds[0] = heroIdsToBuy[0];
                heroIds[1] = heroIdsToBuy[1];
                for(let r of reserveHeroes){
                    if (r != heroIds[0] && r != heroIds[1]){
                        heroIds[2] = r;
                        break;
                    }
                }
            }

            if (heroIdsToBuy.length == 1){
                if (farmedChapters.includes(heroIds[0])){
                    heroIds = reserveHeroes;
                }else{
                    heroIds[0] = heroIdsToBuy[0];
                    heroIds[1] = reserveHeroes[0];
                    heroIds[2] = reserveHeroes[1];
                }
            }

            //Фрагменты героев
            let heroFragments = [0, 0, 0];
            if (haveHeroFragments[heroIds[0]]){
                heroFragments[0] = haveHeroFragments[heroIds[0]];
            }
            if (haveHeroFragments[heroIds[1]]){
                heroFragments[1] = haveHeroFragments[heroIds[1]];
            }
            if (haveHeroFragments[heroIds[2]]){
                heroFragments[2] = haveHeroFragments[heroIds[2]];
            }
            console.log(heroIds);
            console.log(heroFragments);

            while( lives > 0 && missionId <= (firstMissionId+7)){
                //Купить героев и питомцев
                let result = await buyHeroInTheStore(heroShopId, heroIds, heroFragments, petCounter);

                //Выйти, если босс побежден и полностью собрали три героя
                if (result && farmedChapters.includes(chapterId)){
                    break;
                }

                //Текущая миссия босс или нет
                let boss = false;

                //Произвести атаку босса, если его ни разу не убили
                if(!farmedChapters.includes(chapterId)){
                    if (missionId == (firstMissionId+7)){
                        boss = true;
                        console.log("%cАтакуем босса ", "color: green; font-weight: bold;")
                    }
                }else{
                    //Не атаковать босса, если его уже убили
                    if (missionId == (firstMissionId+7)){
                        break;
                    }
                }

                //Получить атакующую команду
                let heroes = [];
                haveHeroFragments = await Caller.send('invasion_getInfo').then(e => e.fragments);
                for (let f in haveHeroFragments){
                    //Исключаем питомцев
                    if(Number(f) < 6000){
                        heroes.push(Number(f));
                    }
                    if(heroes.length == 5){
                        break;
                    }
                }
                console.log("Атакующие герои " + heroes);

                let pet;

                //Проходим миссию
                await attackTitanMission(missionId, chapterId, heroes, pet, boss);

                //Результат атаки
                let invasionInfo = await Caller.send('invasion_getInfo');
                farmedChapters = invasionInfo.farmedChapters;
                let missions = Object.values(invasionInfo.actions);
                for(let mission of missions){
                    if (mission.payload.wins == 0){
                        missionId = mission.payload.id;
                        break;
                    }
                }
                lives = invasionInfo.lives;
                console.log("missionId "+ missionId);
                console.log("lives "+ lives);
            }
        }
    }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    async function getHeroIdsToBuy() {
        const quest = await Caller.send('questGetAll');
        const heroIds = quest.filter(e => e.state == 1 && lib.data.quest.special[e.id]?.translationMethod === "invasionStallHeroFragments").map(e => lib.data.quest.special[e.id].farmCondition.eventFunc.args.fragmentId);
        return heroIds;
    }

    async function getTitanIdsToBuy() {
        const quest = await Caller.send('questGetAll');
        const titanIds = quest.filter(e => e.state == 1 && lib.data.quest.special[e.id]?.translationMethod === "invasionStallFragmentsTitans").map(e => lib.data.quest.special[e.id].farmCondition.eventFunc.args.fragmentId);
        return titanIds;
    }

    async function getTitanSkillIdsToBuy() {
        const quest = await Caller.send('questGetAll');
        const titanSkillIds = quest.filter(e => e.state == 1 && lib.data.quest.special[e.id]?.translationMethod === "invasionStallFragmentsTitanSkills").map(e => lib.data.quest.special[e.id].farmCondition.eventFunc.args.fragmentId);
        return titanSkillIds;
    }

    async function getShopId(chapters, titanOrHero){
        for (let chapter of chapters){
            if(chapter.settings.unitType === titanOrHero){
                return chapter.settings.stallShopId;
            }
        }
        return false;
    }
    async function getChapterId(chapters, titanOrHero){
        for (let chapter of chapters){
            if(chapter.settings.unitType === titanOrHero){
                return chapter.id;
            }
        }
        return false;
    }

    async function buyTitanInTheStore(titanShopId, titanIds, titanFragments, titanSkilsIds, titanSkilFragments) {
        console.log("Зашли в магазин");
        console.log("titanIds ", JSON.stringify(titanIds));
        console.log("titanFragments ", JSON.stringify(titanFragments));
        console.log("titanSkilsIds ", JSON.stringify(titanSkilsIds));
        console.log("titanSkilFragments ", JSON.stringify(titanSkilFragments));

        let coins = await Caller.send('inventoryGet').then(e => e.coin[1080]);
        console.log("Монеты: " + coins);

        while( coins >= 9){
            //Получить состояние магазина
            let result = await Caller.send([{name:'shopGet',args:{shopId: titanShopId}}]).then(e => e.slots);
            let slots = Object.values(result)
            for (let slot of slots){
                //Пропустить скрытые лоты
                if (slot.reward.invasionFragmentTitanRand || slot.reward.invasionFragmentSkillRand){
                    continue;
                }
                //Купить первого титана
                if (slot.reward.invasionFragmentTitan?.[titanIds[0]] && titanFragments[0] < 7){
                    if (coins >= slot.cost.coin[1080]){
                        let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: titanShopId, slot: slot.id}});
                        if(shopBuy.error){
                            await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                            coins = 0;
                            continue;
                        }
                        console.log("%cКуплен титан ", "color: green; font-weight: bold;")
                        coins -= slot.cost.coin[1080];
                        titanFragments[0] += slot.reward.invasionFragmentTitan?.[titanIds[0]];

                        //Если c первым титаном есть второй
                        if(slot.reward.invasionFragmentTitan?.[titanIds[1]]){
                            console.log("%cВторой титан в комплекте ", "color: green; font-weight: bold;")
                            titanFragments[1] += slot.reward.invasionFragmentTitan?.[titanIds[1]];
                        }
                    }else{
                        await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                    }
                    continue;
                }

                //Купить второго титана
                if (slot.reward.invasionFragmentTitan?.[titanIds[1]] && titanFragments[1] < 7){
                    if (coins >= slot.cost.coin[1080]){
                        let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: titanShopId, slot: slot.id}});
                        if(shopBuy.error){
                            await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                            coins = 0;
                            continue;
                        }
                        console.log("%cКуплен титан ", "color: green; font-weight: bold;")
                        coins -= slot.cost.coin[1080];
                        titanFragments[1] += slot.reward.invasionFragmentTitan?.[titanIds[1]];
                    }
                    else{
                        await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                    }
                    continue;
                }

                //Купить первый навык тотема
                if (slot.reward.invasionFragmentSkill?.[titanSkilsIds[0]] && titanSkilFragments[0] < 7){
                    if (coins >= slot.cost.coin[1080]){
                        let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: titanShopId, slot: slot.id}});
                        if(shopBuy.error){
                            await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                            coins = 0;
                            continue;
                        }
                        console.log("%cКуплена часть навыка тотема ", "color: green; font-weight: bold;")
                        coins -= slot.cost.coin[1080];
                        titanSkilFragments[0] += slot.reward.invasionFragmentSkill?.[titanSkilsIds[0]];
                    }else{
                        await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                    }
                    continue;
                }

                //Купить второй навык тотема
                if (titanSkilsIds.length >= 2 && slot.reward.invasionFragmentSkill?.[titanSkilsIds[1]] && titanSkilFragments[1] < 7){
                    if (coins >= slot.cost.coin[1080]){
                        let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: titanShopId, slot: slot.id}});
                        if(shopBuy.error){
                            await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                            coins = 0;
                            continue;
                        }
                        console.log("%cКуплена часть навыка тотема ", "color: green; font-weight: bold;")
                        coins -= slot.cost.coin[1080];
                        titanSkilFragments[1] += slot.reward.invasionFragmentSkill?.[titanSkilsIds[1]];
                    }else{
                        await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                    }
                    continue;
                }
                //Если ТИТАНЫ собраны
                if(titanFragments[0] >= 7 && titanFragments[1] >= 7 ){
                    //Обновляем навыки
                    if (titanSkilsIds.length >= 2 && titanSkilFragments[0] >= 7 && titanSkilFragments[1] >= 7){
                        console.log("%cМеняем навыки навыки тотемов", "color: green; font-weight: bold;")
                        titanSkilsIds = await getTitanSkillIdsToBuy();
                        titanSkilFragments = [0, 0];
                        if (titanSkilsIds.length == 1){
                            titanSkilFragments = [0];
                        }
                    }
                    if ((titanSkilsIds.length == 1 && titanSkilFragments[0] >= 7) || titanSkilsIds.length == 0){
                        console.log("%cВсе навыки тотемов куплены, переходим к покупке следующих титанов", "color: green; font-weight: bold;")
                        return true;
                    }
                }
            }
            //Обновить магазин
            if (coins >= 12){
                let shopRefresh = await Caller.send({name: 'shopRefresh', args: {shopId: titanShopId}});
                coins -= 3;
                console.log("Обновили магазин. Осталось монет: " + coins);
                if(shopRefresh.error){
                    coins = 0;
                }
            }else{
                break;
            }
        }
        return false;
    }

    async function buyTotemSkilsInTheStore(titanShopId, titanIds, titanFragments, titanSkilsIds, titanSkilFragments) {
        console.log("Зашли в магазин");
        console.log("titanIds ", JSON.stringify(titanIds));
        console.log("titanFragments ", JSON.stringify(titanFragments));
        console.log("titanSkilsIds ", JSON.stringify(titanSkilsIds));
        console.log("titanSkilFragments ", JSON.stringify(titanSkilFragments));

        let coins = await Caller.send('inventoryGet').then(e => e.coin[1080]);
        console.log("Монеты: " + coins);

        while( coins >= 9){
            //Получить состояние магазина
            let result = await Caller.send([{name:'shopGet',args:{shopId: titanShopId}}]).then(e => e.slots);
            let slots = Object.values(result)
            for (let slot of slots){
                //Пропустить скрытые лоты
                if (slot.reward.invasionFragmentTitanRand || slot.reward.invasionFragmentSkillRand){
                    continue;
                }
                //Купить первый навык тотема
                if (slot.reward.invasionFragmentSkill?.[titanSkilsIds[0]] && titanSkilFragments[0] < 7){
                    if (coins >= slot.cost.coin[1080]){
                        let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: titanShopId, slot: slot.id}});
                        if(shopBuy.error){
                            await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                            coins = 0;
                            continue;
                        }
                        console.log("%cКуплена часть навыка тотема ", "color: green; font-weight: bold;")
                        coins -= slot.cost.coin[1080];
                        titanSkilFragments[0] += slot.reward.invasionFragmentSkill?.[titanSkilsIds[0]];
                    }else{
                        await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                    }
                    continue;
                }

                //Купить второй навык тотема
                if (titanSkilsIds.length >= 2 && slot.reward.invasionFragmentSkill?.[titanSkilsIds[1]] && titanSkilFragments[1] < 7){
                    if (coins >= slot.cost.coin[1080]){
                        let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: titanShopId, slot: slot.id}});
                        if(shopBuy.error){
                            await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                            coins = 0;
                            continue;
                        }
                        console.log("%cКуплена часть навыка тотема ", "color: green; font-weight: bold;")
                        coins -= slot.cost.coin[1080];
                        titanSkilFragments[1] += slot.reward.invasionFragmentSkill?.[titanSkilsIds[1]];
                    }else{
                        await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                    }
                    continue;
                }
                //Если навыки собраны, обновляем навыки
                if (titanSkilsIds.length >= 2 && titanSkilFragments[0] >= 7 && titanSkilFragments[1] >= 7){
                    titanSkilsIds = await getTitanSkillIdsToBuy();
                    titanSkilFragments = [0, 0];
                    if (titanSkilsIds.length == 1){
                        titanSkilFragments = [0];
                    }
                }

                if ((titanSkilsIds.length == 1 && titanSkilFragments[0] >= 7) || titanSkilsIds.length == 0){
                    //Тратим оставшиеся монеты (пусть будет, вдруг пригодиццо)
                    /*if (coins >= slot.cost.coin[1080]){
                        let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: titanShopId, slot: slot.id}});
                        coins -= slot.cost.coin[1080];
                        if(shopBuy.error){
                            coins = 0;
                            continue;
                        }
                    }*/
                    //Купили все навыки, идем на выход
                    return true;
                }

                //Купить первого титана
                if (slot.reward.invasionFragmentTitan?.[titanIds[0]] && titanFragments[0] < 7){
                    if (coins >= slot.cost.coin[1080]){
                        let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: titanShopId, slot: slot.id}});
                        if(shopBuy.error){
                            await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                            coins = 0;
                            continue;
                        }
                        console.log("%cКуплен титан ", "color: green; font-weight: bold;")
                        coins -= slot.cost.coin[1080];
                        titanFragments[0] += slot.reward.invasionFragmentTitan?.[titanIds[0]];

                        //Если c первым титаном есть второй
                        if(slot.reward.invasionFragmentTitan?.[titanIds[1]]){
                            console.log("%cВторой титан в комплекте ", "color: green; font-weight: bold;")
                            titanFragments[1] += slot.reward.invasionFragmentTitan?.[titanIds[1]];
                        }
                    }else{
                        await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                    }
                    continue;
                }

                //Купить второго титана
                if (slot.reward.invasionFragmentTitan?.[titanIds[1]] && titanFragments[1] < 7){
                    if (coins >= slot.cost.coin[1080]){
                        let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: titanShopId, slot: slot.id}});
                        if(shopBuy.error){
                            await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                            coins = 0;
                            continue;
                        }
                        console.log("%cКуплен титан ", "color: green; font-weight: bold;")
                        coins -= slot.cost.coin[1080];
                        titanFragments[1] += slot.reward.invasionFragmentTitan?.[titanIds[1]];
                    }
                    else{
                        await Caller.send({name: 'shop_pinSlot', args: {shopId: titanShopId, slotId: slot.id}});
                    }
                    continue;
                }

            }
            //Обновить магазин
            if (coins >= 12){
                let shopRefresh = await Caller.send({name: 'shopRefresh', args: {shopId: titanShopId}});
                coins -= 3;
                console.log("Обновили магазин. Осталось монет " + coins);
                if(shopRefresh.error){
                    coins = 0;
                }
            }else{
                break;
            }
        }
        return false;
    }

    async function buyHeroInTheStore(heroShopId, heroIds, heroFragments, petCounter) {
        console.log("Зашли в магазин");
        console.log("heroShopId " + heroShopId);
        console.log("petCounter " + petCounter[0]);
        console.log("heroIds ", JSON.stringify(heroIds));
        console.log("heroFragments ", JSON.stringify(heroFragments));

        let coins = await Caller.send('inventoryGet').then(e => e.coin[1080]);
        console.log("Монеты: " + coins);

        while( coins >= 9){
            //Получить состояние магазина
            let result = await Caller.send([{name:'shopGet',args:{shopId: heroShopId}}]).then(e => e.slots);
            let slots = Object.values(result)
            for (let slot of slots){
                //Пропустить скрытые лоты
                if (slot.reward.invasionFragmentHeroRand){
                    continue;
                }
                //console.log(slot);
                //Купить первого титана
                if (slot.reward.invasionFragmentHero?.[heroIds[0]] && heroFragments[0] < 7){
                    if (coins >= slot.cost.coin[1080]){
                        let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: heroShopId, slot: slot.id}});
                        if(shopBuy.error){
                            await Caller.send({name: 'shop_pinSlot', args: {shopId: heroShopId, slotId: slot.id}});
                            coins = 0;
                            continue;
                        }
                        console.log("%cКуплен герой ", "color: green; font-weight: bold;")
                        coins -= slot.cost.coin[1080];
                        heroFragments[0] += slot.reward.invasionFragmentHero?.[heroIds[0]];

                        //Если c первым титаном есть второй
                        if(slot.reward.invasionFragmentHero?.[heroIds[1]]){
                            console.log("%cВторой герой в комплекте ", "color: green; font-weight: bold;")
                            heroFragments[1] += slot.reward.invasionFragmentHero?.[heroIds[1]];
                        }
                        //Если c первым титаном есть третий
                        if(slot.reward.invasionFragmentHero?.[heroIds[2]]){
                            console.log("%cТретий герой в комплекте ", "color: green; font-weight: bold;")
                            heroFragments[2] += slot.reward.invasionFragmentHero?.[heroIds[2]];
                        }
                    }else{
                        await Caller.send({name: 'shop_pinSlot', args: {shopId: heroShopId, slotId: slot.id}});
                    }
                    continue;
                }

                //Купить второго титана
                if (slot.reward.invasionFragmentHero?.[heroIds[1]] && heroFragments[1] < 7){
                    if (coins >= slot.cost.coin[1080]){
                        let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: heroShopId, slot: slot.id}});
                        if(shopBuy.error){
                            await Caller.send({name: 'shop_pinSlot', args: {shopId: heroShopId, slotId: slot.id}});
                            coins = 0;
                            continue;
                        }
                        console.log("%cКуплен герой ", "color: green; font-weight: bold;")
                        coins -= slot.cost.coin[1080];
                        heroFragments[1] += slot.reward.invasionFragmentHero?.[heroIds[1]];
                        //Если cо вторым титаном есть третий
                        if(slot.reward.invasionFragmentHero?.[heroIds[2]]){
                            console.log("%cТретий герой в комплекте ", "color: green; font-weight: bold;")
                            heroFragments[2] += slot.reward.invasionFragmentHero?.[heroIds[2]];
                        }
                    }
                    else{
                        await Caller.send({name: 'shop_pinSlot', args: {shopId: heroShopId, slotId: slot.id}});
                    }
                    continue;
                }
                //Купить третьего титана
                if (slot.reward.invasionFragmentHero?.[heroIds[2]] && heroFragments[2] < 7){
                    if (coins >= slot.cost.coin[1080]){
                        let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: heroShopId, slot: slot.id}});
                        if(shopBuy.error){
                            await Caller.send({name: 'shop_pinSlot', args: {shopId: heroShopId, slotId: slot.id}});
                            coins = 0;
                            continue;
                        }
                        console.log("%cКуплен герой ", "color: green; font-weight: bold;")
                        coins -= slot.cost.coin[1080];
                        heroFragments[2] += slot.reward.invasionFragmentHero?.[heroIds[2]];
                    }
                    else{
                        await Caller.send({name: 'shop_pinSlot', args: {shopId: heroShopId, slotId: slot.id}});
                    }
                    continue;
                }
                //Потратить оставшиеся монеты, если герои уже куплены
                if (heroFragments[0] >= 7 && heroFragments[1] >= 7 && heroFragments[2] >= 7){
                    console.log("Тратим монеты");
                    if (slot.reward.invasionFragmentPet && petCounter[0] < 10){
                        if(coins >= slot.cost.coin[1080]){
                            let shopBuy = await Caller.send({name: 'shopBuy', args: {cost: {}, reward: {}, shopId: heroShopId, slot: slot.id}});
                            coins -= slot.cost.coin[1080];
                            petCounter[0]++;
                            console.log("%cКуплен питомец ", "color: green; font-weight: bold;");
                        }else{
                            await Caller.send({name: 'shop_pinSlot', args: {shopId: heroShopId, slotId: slot.id}});
                        }
                    }
                    if (petCounter[0] >= 10 ){
                        console.log("%cВсе питомци куплены, переходим к покупке следующих героев", "color: green; font-weight: bold;")
                        return true;
                    }
                }
            }
            //Обновить магазин
            if (coins >= 15){
                let shopRefresh = await Caller.send({name: 'shopRefresh', args: {shopId: heroShopId}});
                coins -= 3;
                console.log("Обновили магазин. Осталось монет " + coins);
                if(shopRefresh.error){
                    coins = 0;
                }
            }else{
                break;
            }
        }
        return false;
    }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    async function attackTitanMission(missionId, chapterId, heroes, firstSpiritSkills, boss = false) {
        const startBattle = await Caller.send({
            name: 'invasion_bossStart',
            args: {
                id: missionId,
                chapterId:chapterId,
                heroes: heroes,
                //firstSpiritElement: "earth",
                firstSpiritSkills:firstSpiritSkills,
                favor: {},
            },
        });
        const calcBattle = await Calc(startBattle);

        if (!calcBattle.result.win) {
            const cloneBattle = structuredClone(startBattle);
            const bFix = new WinFixBattle(cloneBattle);
            let result = await bFix.start(cloneBattle.endTime, Infinity);
            if (result.result?.win) {
                calcBattle.result = result.result;
                calcBattle.progress = result.progress;
            }
        }

        if (!calcBattle.result.win && boss == true) {
            //Босса не убили
            console.log("%cБосса не убили ", "color: red; font-weight: bold;")
            return;
        }
        if(boss == true){
            let timer = calcBattle.battleTimer + 10;
            console.log("%cУбили босса", "color: green; font-weight: bold;")
            await countdownTimer(timer,`${I18N('NEWTITAN_BOSSWASKILLED')}`)
        }

        const endBattle = await Caller.send({
            name: 'invasion_bossEnd',
            args: {
                id: missionId,
                result: calcBattle.result,
                progress: calcBattle.progress,
            },
        });
    }

    async function attackHeroMission(missionId, chapterId, heroes, pet, boss = false) {
        const startBattle = await Caller.send({
            name: 'invasion_bossStart',
            args: {
                id: missionId,
                chapterId:chapterId,
                heroes: heroes,
                pet: pet,
                favor: {},
            },
        });
        const calcBattle = await Calc(startBattle);

        if (!calcBattle.result.win) {
            const cloneBattle = structuredClone(startBattle);
            const bFix = new WinFixBattle(cloneBattle);
            let result = await bFix.start(cloneBattle.endTime, Infinity);
            if (result.result?.win) {
                calcBattle.result = result.result;
                calcBattle.progress = result.progress;
            }
        }

        if (!calcBattle.result.win && boss == true) {
            //Босса не убили
            console.log("%cБосса не убили ", "color: red; font-weight: bold;")
            return;
        }
        if(boss == true){
            let timer = calcBattle.battleTimer + 10;
            console.log("%cУбили босса", "color: green; font-weight: bold;")
            await countdownTimer(timer,`${I18N('NEWTITAN_BOSSWASKILLED')}`)
        }

        const endBattle = await Caller.send({
            name: 'invasion_bossEnd',
            args: {
                id: missionId,
                result: calcBattle.result,
                progress: calcBattle.progress,
            },
        });
    }

})();