Greasy Fork is available in English.

Eternity Tower Old Recipe Hider

Hides old recipes you no longer need automatically

Verze ze dne 07. 08. 2018. Zobrazit nejnovější verzi.

// ==UserScript==
// @name          Eternity Tower Old Recipe Hider
// @icon          https://www.eternitytower.net/favicon.png
// @namespace     http://mean.cloud/
// @version       1.03
// @description   Hides old recipes you no longer need automatically
// @match         http*://*.eternitytower.net/*
// @author        psouza4@gmail.com
// @copyright     2018, MeanCloud
// @run-at        document-end
// @grant         GM_getValue
// @grant         GM_setValue
// @grant         GM_addStyle
// ==/UserScript==

// Note: temp version to toy with inventory layout

////////////////////////////////////////////////////////////////
////////////// ** SCRIPT GLOBAL INITIALIZATION ** //////////////
function startup() { ET_RecipeHiderMod(); }
////////////////////////////////////////////////////////////////

ET_RecipeHiderMod = function()
{
    //ET.MCMF.WantDebug = true;

    ET.MCMF.Loaded(function()
    {
        ET.MCMF.PETRecipeHider = [];
        
        //Blaze._getTemplate("craftingList").onCreated(PETRecipeHider_main);
        
        Package.meteor.Meteor.call('crafting.fetchRecipes', function(err, res)
        {
            //console.log(JSON.stringify(jQ.makeArray(res)));
            
            ET.MCMF.PETRecipeHider.AllRecipes = res;
            
            PETRecipeHider_main();
        });
        
    }, "ETREcipeHider");
};

document.ET_Util_Log = function(msg)
{
    try
    {
        var now_time = new Date();
        var timestamp = (now_time.getMonth() + 1).toString() + "/" + now_time.getDate().toString() + "/" + (now_time.getYear() + 1900).toString() + " " + ((now_time.getHours() === 0) ? (12) : ((now_time.getHours() > 12) ? (now_time.getHours() - 12) : (now_time.getHours()))).toString() + ":" + now_time.getMinutes().toString().padStart(2, "0") + ":" + now_time.getSeconds().toString().padStart(2, "0") + ((now_time.getHours() < 12) ? ("am") : ("pm")) + " :: ";
        //alert(timestamp.toString() + msg);
        //jQ("body").append("<div>" + timestamp.toString() + msg + "<br /></div>\r\n");
        unsafeWindow.console.log(timestamp.toString() + msg);
    }
    catch (err) { }
};

document.ET_Util_Time = function() // returns time in milliseconds (not seconds!)
{
    return document.CInt((new Date()).getTime());
};

document.ET_LocalFriendlyNumber = function(num)
{
    if (num < 1000) return num.toString();
    if (num < 10000) return ((Math.floor(num / 100) / 10.0).toString() + "k");
    if (num < 100000) return ((Math.floor(num / 1000)).toString() + "k");
    if (num < 1000000) return ((Math.floor(num / 1000)).toString() + "k");
    if (num < 10000000) return ((Math.floor(num / 100000) / 10.0).toString() + "m");
    if (num < 100000000) return ((Math.floor(num / 1000000)).toString() + "m");
    if (num < 1000000000) return ((Math.floor(num / 10000000)).toString() + "m");    
    if (num < 10000000000) return ((Math.floor(num / 100000000) / 10.0).toString() + "b");
    if (num < 100000000000) return ((Math.floor(num / 1000000000)).toString() + "b");
    if (num < 1000000000000) return ((Math.floor(num / 10000000000)).toString() + "b");    
    return num.toString();
};

PETRecipeHider_MatchRecipe = function(recipe_name)
{
    ET.MCMF.PETRecipeHider.RecipeResult = undefined;
    
    try
    {
        ET.MCMF.PETRecipeHider.RecipeSearch = recipe_name.trim().toLowerCase();
        
        if (ET.MCMF.PETRecipeHider.AllRecipes !== undefined)
        {
            jQ.makeArray(ET.MCMF.PETRecipeHider.AllRecipes).forEach(function(currentRecipe, index, array)
            {
                if (ET.MCMF.PETRecipeHider.RecipeResult !== undefined) return;
                if (currentRecipe.name.trim().toLowerCase() === ET.MCMF.PETRecipeHider.RecipeSearch)
                    ET.MCMF.PETRecipeHider.RecipeResult = currentRecipe;
            });
        }
    }
    catch (err) { }
    
    return ET.MCMF.PETRecipeHider.RecipeResult;
};

PETRecipeHider_GetItem = function(item_name_or_id)
{
    var oFoundItem = undefined;
    
    jQuery.each(Package.meteor.global.Accounts.connection._stores.items._getCollection()._collection._docs._map, function()
    {
        if (oFoundItem !== undefined) return;
        if ((this.itemId.trim().toLowerCase() === item_name_or_id) || (this.name.trim().toLowerCase() === item_name_or_id))
            oFoundItem = this;
    });
    
    return oFoundItem;
};

PETRecipeHider_GetSkill = function(skill_name)
{
    var oFoundSkill = undefined;
    
    jQuery.each(window.ET.MCMF.GetSkills(), function()
    {
        if (oFoundSkill !== undefined) return;
        if (this.type.trim().toLowerCase() === skill_name.trim().toLowerCase())
            oFoundSkill = this;
    });
    
    return oFoundSkill;
};

PETRecipeHider_LowestWoodcuttingLevel = function(skill_name)
{
    var iLevel = 9999;
    
    var oWoodcuttingData = Object.keys(Package.meteor.global.Accounts.connection._stores.woodcutting._getCollection()._collection._docs._map).map(key => Package.meteor.global.Accounts.connection._stores.woodcutting._getCollection()._collection._docs._map[key])[0]
    
    for (var i = 0; i < 5; i++)
    {
        try
        {
            if (oWoodcuttingData.woodcutters[i].quality >= 80)
                if (iLevel > oWoodcuttingData.woodcutters[i].stats.attack)
                    iLevel = oWoodcuttingData.woodcutters[i].stats.attack;
        }
        catch (err) { }
    }

    return ((iLevel === 9999) ? 0 : iLevel);
};

PETRecipeHider_should_hide = function(recipe_name)
{
    try
    {
        // Map recipe
        var oRecipe           = PETRecipeHider_MatchRecipe(recipe_name);
        
        // Map some skills
        var oCraftingSkill    = PETRecipeHider_GetSkill("crafting");
        var oAttackSkill      = CInt(PETRecipeHider_GetSkill("attack").level);
        var oDefenseSkill     = CInt(PETRecipeHider_GetSkill("defense").level);
        var oMagicSkill       = CInt(PETRecipeHider_GetSkill("magic").level);
        var oMiningSkill      = PETRecipeHider_GetSkill("mining");
        var oWoodcuttingSkill = PETRecipeHider_GetSkill("woodcutting");
        
        //document.ET_Util_Log("Recipe name: " + oRecipe.name + " (" + recipe_name + ")");
        //document.ET_Util_Log("Mining data: " + JSON.stringify(oMiningData));
        //document.ET_Util_Log("Mining skill: " + JSON.stringify(oMiningSkill));
        //document.ET_Util_Log("Crafting skill: " + JSON.stringify(oCraftingSkill));
        //document.ET_Util_Log(JSON.stringify(oRecipe));        
        
        if (oRecipe.category === "mining")
        {
            var oMiningData = Object.keys(Package.meteor.global.Accounts.connection._stores.mining._getCollection()._collection._docs._map).map(key => Package.meteor.global.Accounts.connection._stores.mining._getCollection()._collection._docs._map[key])[0];
        
            if ((oMiningSkill.level >= oRecipe.requiredCraftingLevel + 10) && (oCraftingSkill.level >= oRecipe.requiredCraftingLevel + 10))
            {
                if ((oRecipe.name === "primitive pickaxe")     && (oMiningData.miners[ 0].amount >= 3)) return true;
                
                if ((oRecipe.name === "copper pickaxe")        && (oMiningData.miners[ 1].amount >= 3)) return true;
                if ((oRecipe.name === "copper mining anvil")   && (oMiningData.miners[ 1].amount >= 3)) return true;
                
                if ((oRecipe.name === "tin pickaxe")           && (oMiningData.miners[ 2].amount >= 3)) return true;
                if ((oRecipe.name === "tin mining anvil")      && (oMiningData.miners[ 2].amount >= 3)) return true;
                if ((oRecipe.name === "pine idol")                                                    ) return true;
                
                if ((oRecipe.name === "bronze pickaxe")        && (oMiningData.miners[ 3].amount >= 3)) return true;
                if ((oRecipe.name === "bronze mining anvil")   && (oMiningData.miners[ 3].amount >= 3)) return true;
                
                if ((oRecipe.name === "iron pickaxe")          && (oMiningData.miners[ 4].amount >= 3)) return true;
                if ((oRecipe.name === "iron mining anvil")     && (oMiningData.miners[ 4].amount >= 3)) return true;
                if ((oRecipe.name === "ash idol")                                                     ) return true;
                
                if ((oRecipe.name === "silver pickaxe")        && (oMiningData.miners[ 5].amount >= 3)) return true;
                if ((oRecipe.name === "silver mining anvil")   && (oMiningData.miners[ 5].amount >= 3)) return true;
                
                if ((oRecipe.name === "gold pickaxe")          && (oMiningData.miners[ 6].amount >= 3)) return true;
                if ((oRecipe.name === "gold mining anvil")     && (oMiningData.miners[ 6].amount >= 3)) return true;
                if ((oRecipe.name === "maple idol")                                                   ) return true;
                
                if ((oRecipe.name === "carbon pickaxe")        && (oMiningData.miners[ 7].amount >= 3)) return true;
                if ((oRecipe.name === "carbon mining anvil")   && (oMiningData.miners[ 7].amount >= 3)) return true;
                
                if ((oRecipe.name === "steel pickaxe")         && (oMiningData.miners[ 8].amount >= 3)) return true;
                if ((oRecipe.name === "steel mining anvil")    && (oMiningData.miners[ 8].amount >= 3)) return true;
                if ((oRecipe.name === "cherry idol")                                                  ) return true;
                
                if ((oRecipe.name === "platinum pickaxe")      && (oMiningData.miners[ 9].amount >= 3)) return true;
                if ((oRecipe.name === "platinum mining anvil") && (oMiningData.miners[ 9].amount >= 3)) return true;
                
                if ((oRecipe.name === "titanium pickaxe")      && (oMiningData.miners[10].amount >= 3)) return true;
                if ((oRecipe.name === "titanium mining anvil") && (oMiningData.miners[10].amount >= 3)) return true;
                if ((oRecipe.name === "elm idol")                                                     ) return true;
                
                if ((oRecipe.name === "tungsten pickaxe")      && (oMiningData.miners[11].amount >= 3)) return true;
                if ((oRecipe.name === "tungsten mining anvil") && (oMiningData.miners[11].amount >= 3)) return true;
                
                if ((oRecipe.name === "obsidian pickaxe")      && (oMiningData.miners[12].amount >= 3)) return true;
                if ((oRecipe.name === "obsidian mining anvil") && (oMiningData.miners[12].amount >= 3)) return true;
                if ((oRecipe.name === "blue gum idol")                                                ) return true;
                
                if ((oRecipe.name === "cobalt pickaxe")        && (oMiningData.miners[13].amount >= 3)) return true;
                if ((oRecipe.name === "cobalt mining anvil")   && (oMiningData.miners[13].amount >= 3)) return true;
                
                if ((oRecipe.name === "mithril pickaxe")       && (oMiningData.miners[14].amount >= 3)) return true;
                if ((oRecipe.name === "mithril mining anvil")  && (oMiningData.miners[14].amount >= 3)) return true;
                if ((oRecipe.name === "denya idol")                                                   ) return true;
                
                if ((oRecipe.name === "adamantium pickaxe")    && (oMiningData.miners[15].amount >= 3)) return true;
                if ((oRecipe.name === "adamantium mining anvil") && (oMiningData.miners[15].amount >= 3)) return true;
                
                if ((oRecipe.name === "orichalcum pickaxe")    && (oMiningData.miners[16].amount >= 3)) return true;
                if ((oRecipe.name === "orichalcum mining anvil") && (oMiningData.miners[16].amount >= 3)) return true;
                if ((oRecipe.name === "hickory idol")                                                 ) return true;
                
                if ((oRecipe.name === "meteorite pickaxe")     && (oMiningData.miners[17].amount >= 3)) return true;
                if ((oRecipe.name === "meteorite mining anvil") && (oMiningData.miners[17].amount >= 3)) return true;
                
                if ((oRecipe.name === "fairy steel pickaxe")   && (oMiningData.miners[18].amount >= 3)) return true;
                if ((oRecipe.name === "fairy steel mining anvil") && (oMiningData.miners[18].amount >= 3)) return true;
                if ((oRecipe.name === "poplar idol")                                                  ) return true;
                
                if ((oRecipe.name === "elven steel pickaxe")   && (oMiningData.miners[19].amount >= 3)) return true;
                if ((oRecipe.name === "elven steel mining anvil") && (oMiningData.miners[19].amount >= 3)) return true;
                
                if ((oRecipe.name === "cursed pickaxe")        && (oMiningData.miners[20].amount >= 3)) return true;
                if ((oRecipe.name === "cursed mining anvil")   && (oMiningData.miners[20].amount >= 3)) return true;
                if ((oRecipe.name === "willow idol")                                                  ) return true;
                
                if ((oRecipe.name === "darksteel pickaxe")     && (oMiningData.miners[21].amount >= 3)) return true;
                if ((oRecipe.name === "darksteel mining anvil") && (oMiningData.miners[21].amount >= 3)) return true;
                
                if ((oRecipe.name === "radiant pickaxe")       && (oMiningData.miners[22].amount >= 3)) return true;
                if ((oRecipe.name === "radiant mining anvil")  && (oMiningData.miners[22].amount >= 3)) return true;
                
                if ((oRecipe.name === "astral pickaxe")        && (oMiningData.miners[23].amount >= 3)) return true;
                if ((oRecipe.name === "astral mining anvil")   && (oMiningData.miners[23].amount >= 3)) return true;
            }
        }
        
        if (oRecipe.category === "woodcutting")
        {
            var iLowestWoodcuttingLevel = PETRecipeHider_LowestWoodcuttingLevel();
            if (oRecipe.baseStats.attack < iLowestWoodcuttingLevel)
                return true;
        }

        if (endsWith(oRecipe.name, " furnace"))
        {
            var iBestFurnaceTier = 0;
            jQuery.each(Package.meteor.global.Accounts.connection._stores.items._getCollection()._collection._docs._map, function()
            {
                if (endsWith(this.itemId, "_furnace"))
                    if (iBestFurnaceTier < CInt(this.tier))
                        iBestFurnaceTier = CInt(this.tier);
            });
            
            if ((oRecipe.name === "stone furnace")       && (iBestFurnaceTier >=  1)) return true;
            if ((oRecipe.name === "copper furnace")      && (iBestFurnaceTier >=  2)) return true;
            if ((oRecipe.name === "tin furnace")         && (iBestFurnaceTier >=  3)) return true;
            if ((oRecipe.name === "bronze furnace")      && (iBestFurnaceTier >=  4)) return true;
            if ((oRecipe.name === "iron furnace")        && (iBestFurnaceTier >=  5)) return true;
            if ((oRecipe.name === "silver furnace")      && (iBestFurnaceTier >=  6)) return true;
            if ((oRecipe.name === "gold furnace")        && (iBestFurnaceTier >=  7)) return true;
            if ((oRecipe.name === "carbon furnace")      && (iBestFurnaceTier >=  8)) return true;
            if ((oRecipe.name === "steel furnace")       && (iBestFurnaceTier >=  9)) return true;
            if ((oRecipe.name === "platinum furnace")    && (iBestFurnaceTier >= 10)) return true;
            if ((oRecipe.name === "titanium furnace")    && (iBestFurnaceTier >= 11)) return true;
            if ((oRecipe.name === "tungsten furnace")    && (iBestFurnaceTier >= 12)) return true;
            if ((oRecipe.name === "obsidian furnace")    && (iBestFurnaceTier >= 13)) return true;
            if ((oRecipe.name === "cobalt furnace")      && (iBestFurnaceTier >= 14)) return true;
            if ((oRecipe.name === "mithril furnace")     && (iBestFurnaceTier >= 15)) return true;
            if ((oRecipe.name === "adamantium furnace")  && (iBestFurnaceTier >= 16)) return true;
            if ((oRecipe.name === "orichalcum furnace")  && (iBestFurnaceTier >= 17)) return true;
            if ((oRecipe.name === "meteorite furnace")   && (iBestFurnaceTier >= 18)) return true;
            if ((oRecipe.name === "fairy steel furnace") && (iBestFurnaceTier >= 19)) return true;
            if ((oRecipe.name === "elven steel furnace") && (iBestFurnaceTier >= 20)) return true;
            if ((oRecipe.name === "cursed furnace")      && (iBestFurnaceTier >= 21)) return true;
            if ((oRecipe.name === "darksteel furnace")   && (iBestFurnaceTier >= 22)) return true;
            if ((oRecipe.name === "radiant furnace")     && (iBestFurnaceTier >= 23)) return true;
            if ((oRecipe.name === "astral furnace")      && (iBestFurnaceTier >= 24)) return true;
        }
        
        if (endsWith(oRecipe.id, "_bar")) {
            var bars = PETRecipeHider_GetItem(oRecipe.name); if ((CInt(bars.amount) > 100) && (oCraftingSkill.level >= oRecipe.requiredCraftingLevel + 15)) return true; }
        
        if ((oRecipe.category === "combat") && (!endsWith(oRecipe.name, " amulet")))
        {
            if ((startsWith(oRecipe.name, "copper "))      && (oCraftingSkill.level >=  10)) return true;
            if ((startsWith(oRecipe.name, "tin "))         && (oCraftingSkill.level >=  15)) return true;
            if ((startsWith(oRecipe.name, "bronze "))      && (oCraftingSkill.level >=  20)) return true;
            if ((startsWith(oRecipe.name, "iron "))        && (oCraftingSkill.level >=  25)) return true;
            if ((startsWith(oRecipe.name, "silver "))      && (oCraftingSkill.level >=  30)) return true;
            if ((startsWith(oRecipe.name, "gold "))        && (oCraftingSkill.level >=  35)) return true;
            if ((startsWith(oRecipe.name, "carbon "))      && (oCraftingSkill.level >=  40)) return true;
            if ((startsWith(oRecipe.name, "steel "))       && (oCraftingSkill.level >=  45)) return true;
            if ((startsWith(oRecipe.name, "platinum "))    && (oCraftingSkill.level >=  50)) return true;
            if ((startsWith(oRecipe.name, "titanium "))    && (oCraftingSkill.level >=  55)) return true;
            if ((startsWith(oRecipe.name, "tungsten "))    && (oCraftingSkill.level >=  60)) return true;
            if ((startsWith(oRecipe.name, "obsidian "))    && (oCraftingSkill.level >=  65)) return true;
            if ((startsWith(oRecipe.name, "cobalt "))      && (oCraftingSkill.level >=  70)) return true;
            if ((startsWith(oRecipe.name, "mithril "))     && (oCraftingSkill.level >=  75)) return true;
            if ((startsWith(oRecipe.name, "adamantium "))  && (oCraftingSkill.level >=  80)) return true;
            if ((startsWith(oRecipe.name, "orichalcum "))  && (oCraftingSkill.level >=  85)) return true;
            if ((startsWith(oRecipe.name, "meteorite "))   && (oCraftingSkill.level >=  90)) return true;
            if ((startsWith(oRecipe.name, "fairy steel ")) && (oCraftingSkill.level >=  95)) return true;
            if ((startsWith(oRecipe.name, "elven steel ")) && (oCraftingSkill.level >= 100)) return true;
            // never hide these tiers
            /*
            if ((startsWith(oRecipe.name, "cursed "))      && (oCraftingSkill.level >= 105)) return true;
            if ((startsWith(oRecipe.name, "darksteel "))   && (oCraftingSkill.level >= 110)) return true;
            if ((startsWith(oRecipe.name, "radiant "))     && (oCraftingSkill.level >= 115)) return true;
            if ((startsWith(oRecipe.name, "astral "))      && (oCraftingSkill.level >= 120)) return true;
            */
        }
        
        if (endsWith(oRecipe.name, " staff"))
        {
            if ((oRecipe.name === "beech staff")    && (oCraftingSkill.level >= 10)) return true; // next is walnut
            if ((oRecipe.name === "oak staff")      && (oCraftingSkill.level >= 30)) return true; // next is mahogany
            if ((oRecipe.name === "walnut staff")   && (oCraftingSkill.level >= 40)) return true; // next is black
            if ((oRecipe.name === "mahogany staff") && (oCraftingSkill.level >= 45)) return true; // next is blue gum
            if ((oRecipe.name === "black staff")    && (oCraftingSkill.level >= 50)) return true; // next is cedar
            if ((oRecipe.name === "blue gum staff") && (oCraftingSkill.level >= 55)) return true; // next is denya
            if ((oRecipe.name === "cedar staff")    && (oCraftingSkill.level >= 60)) return true; // next is gombe
            if ((oRecipe.name === "denya staff")    && (oCraftingSkill.level >= 65)) return true; // next is hickory
            if ((oRecipe.name === "gombe staff")    && (oCraftingSkill.level >= 70)) return true; // next is larch
            if ((oRecipe.name === "hickory staff")  && (oCraftingSkill.level >= 75)) return true; // next is poplar
            if ((oRecipe.name === "larch staff")    && (oCraftingSkill.level >= 80)) return true; // next is tali
            if ((oRecipe.name === "poplar staff")   && (oCraftingSkill.level >= 85)) return true; // next is willow
            if ((oRecipe.name === "tali staff")     && (oCraftingSkill.level >= 90)) return true; // next is teak
            // willow and teak have no upgrades
        }
        
        if (endsWith(recipe_name, " amulet"))
        {
            if ((oRecipe.name === "primitive amulet") && (oCraftingSkill.level >= 10)) return true; // anything, even copper, is better than primitive
            
            var amu = PETRecipeHider_GetItem("jade amulet"); if ((amu !== undefined) && (recipe_name === "jade amulet")) return true;
            var amu = PETRecipeHider_GetItem("lapis lazuli amulet"); if ((amu !== undefined) && (recipe_name === "lapis lazuli amulet")) return true;
            var amu = PETRecipeHider_GetItem("sapphire amulet"); if ((amu !== undefined) && (recipe_name === "sapphire amulet")) return true;
            var amu = PETRecipeHider_GetItem("emerald amulet"); if ((amu !== undefined) && (recipe_name === "emerald amulet")) return true;
            var amu = PETRecipeHider_GetItem("ruby amulet"); if ((amu !== undefined) && (recipe_name === "ruby amulet")) return true;
            var amu = PETRecipeHider_GetItem("tanzanite amulet"); if ((amu !== undefined) && (recipe_name === "tanzanite amulet")) return true;
            
            // EMERALD               = health
            // JADE                  = accuracy
            // LAPIS, copper, gold   = defense + health
            // SAPPHIRE, tin, carbon = magic power + magic armor
            // RUBY, bronze, steel   = damage + accuracy
            // TANZANITE, silver     = health + defense + accuracy + magic power ('everything')
            var amu_Defense = PETRecipeHider_GetItem("lapis lazuli amulet");
            if (amu_Defense === undefined) amu_Defense = PETRecipeHider_GetItem("fairy steel amulet");
            if (amu_Defense === undefined) amu_Defense = PETRecipeHider_GetItem("mithril amulet");
            if (amu_Defense === undefined) amu_Defense = PETRecipeHider_GetItem("titanium amulet");
            if (amu_Defense === undefined) amu_Defense = PETRecipeHider_GetItem("gold amulet");
            if (amu_Defense === undefined) amu_Defense = PETRecipeHider_GetItem("copper amulet");
            var amu_Magic = PETRecipeHider_GetItem("sapphire amulet");
            if (amu_Magic === undefined) amu_Magic = PETRecipeHider_GetItem("elven steel amulet");
            if (amu_Magic === undefined) amu_Magic = PETRecipeHider_GetItem("adamantium amulet");
            if (amu_Magic === undefined) amu_Magic = PETRecipeHider_GetItem("tungsten amulet");
            if (amu_Magic === undefined) amu_Magic = PETRecipeHider_GetItem("carbon amulet");
            if (amu_Magic === undefined) amu_Magic = PETRecipeHider_GetItem("tin amulet");
            var amu_Damage  = PETRecipeHider_GetItem("ruby amulet");
            if (amu_Damage === undefined) amu_Damage = PETRecipeHider_GetItem("cursed amulet");
            if (amu_Damage === undefined) amu_Damage = PETRecipeHider_GetItem("orichalcum amulet");
            if (amu_Damage === undefined) amu_Damage = PETRecipeHider_GetItem("obsidian amulet");
            if (amu_Damage === undefined) amu_Damage = PETRecipeHider_GetItem("steel amulet");
            if (amu_Damage === undefined) amu_Damage = PETRecipeHider_GetItem("bronze amulet");
            var amu_General = PETRecipeHider_GetItem("tanzanite amulet");
            if (amu_General === undefined) amu_General = PETRecipeHider_GetItem("meteorite amulet");
            if (amu_General === undefined) amu_General = PETRecipeHider_GetItem("cobalt amulet");
            if (amu_General === undefined) amu_General = PETRecipeHider_GetItem("platinum amulet");
            if (amu_General === undefined) amu_General = PETRecipeHider_GetItem("silver amulet");
            
            if ((oRecipe.name === "copper amulet") && ((amu_Defense !== undefined) || (oCraftingSkill.level >= 32))) return true;
            if ((oRecipe.name === "tin amulet") && ((amu_Magic !== undefined) || (oCraftingSkill.level >= 35))) return true;
            if ((oRecipe.name === "bronze amulet") && ((amu_Damage !== undefined) || (oCraftingSkill.level >= 40))) return true;
            if ((oRecipe.name === "silver amulet") && ((amu_General !== undefined) || (oCraftingSkill.level >= 45))) return true;
            
            if ((oRecipe.name === "gold amulet") && ((amu_Defense !== undefined) || (oCraftingSkill.level >= 50))) return true;
            if ((oRecipe.name === "carbon amulet") && ((amu_Magic !== undefined) || (oCraftingSkill.level >= 55))) return true;
            if ((oRecipe.name === "steel amulet") && ((amu_Damage !== undefined) || (oCraftingSkill.level >= 60))) return true;
            if ((oRecipe.name === "platinum amulet") && ((amu_General !== undefined) || (oCraftingSkill.level >= 65))) return true;
            
            if ((oRecipe.name === "titanium amulet") && ((amu_Defense !== undefined) || (oCraftingSkill.level >= 70))) return true;
            if ((oRecipe.name === "tungsten amulet") && ((amu_Magic !== undefined) || (oCraftingSkill.level >= 75))) return true;
            if ((oRecipe.name === "obsidian amulet") && ((amu_Damage !== undefined) || (oCraftingSkill.level >= 80))) return true;
            if ((oRecipe.name === "cobalt amulet") && ((amu_General !== undefined) || (oCraftingSkill.level >= 85))) return true;
            
            if ((oRecipe.name === "mithril amulet") && ((amu_Defense !== undefined) || (oCraftingSkill.level >= 90))) return true;
            if ((oRecipe.name === "adamantium amulet") && ((amu_Magic !== undefined) || (oCraftingSkill.level >= 95))) return true;
            if ((oRecipe.name === "orichalcum amulet") && ((amu_Damage !== undefined) || (oCraftingSkill.level >= 100))) return true;
            if ((oRecipe.name === "meteorite amulet") && ((amu_General !== undefined) || (oCraftingSkill.level >= 105))) return true;
            
            if ((oRecipe.name === "fairy steel amulet") && ((amu_Defense !== undefined) || (oCraftingSkill.level >= 110))) return true;
            if ((oRecipe.name === "elven steel amulet") && ((amu_Magic !== undefined) || (oCraftingSkill.level >= 115))) return true;
            if ((oRecipe.name === "cursed amulet") && ((amu_Damage !== undefined) || (oCraftingSkill.level >= 120))) return true;
        }
    }
    catch (err) { document.ET_Util_Log("Error evaluating this recipe: " + err); }
        
    return false;
}

PETRecipeHider_main = function()
{
    if (window.location.href.indexOf("/crafting") !== -1)
    {
        jQ("div.recipe-container").each(function()
        {
            try
            {
				var sTextThisRecipe = jQ(this).find("div div span.text-capitalize").text().trim().toLowerCase();

                if (PETRecipeHider_should_hide(sTextThisRecipe))
                    jQ(this).remove(); // do this so the Search mod won't re-add it
            }
            catch (err) { }
        });
    }

	setTimeout(PETRecipeHider_main, 5000);
};

PETPQ_LookupItem = function(sID)
{
	var res = null;

    // ET.MCMF.ItemManager._collection._docs._map
	jQ.each(Package.meteor.global.Accounts.connection._stores.items._getCollection()._collection._docs._map, function()
	{
		if (this._id.toLowerCase().trim() == sID.toLowerCase().trim())
		{
			res = this;
		}
	});

	return res;
};


////////////////////////////////////////////////////////////////
/////////////// ** common.js -- DO NOT MODIFY ** ///////////////
time_val = function()
{
    return CDbl(Math.floor(Date.now() / 1000));
};

IsValid = function(oObject)
{
    if (oObject === undefined) return false;
    if (oObject === null) return false;
    return true;
};

Random = function(iMin, iMax)
{
    return parseInt(iMin + Math.floor(Math.random() * iMax));
};

ShiftClick = function(oEl)
{
    if (oEl === undefined)
    {
        var shiftclick = jQ.Event("click");
        shiftclick.shiftKey = true;

        var shiftclickOrig = jQ.Event("click");
        shiftclickOrig.shiftKey = true;

        shiftclick.originalEvent = shiftclick;
        return shiftclick;
    }

    jQ(oEl).trigger(ShiftClick());
};

if (!String.prototype.replaceAll)
    String.prototype.replaceAll = function(search, replace) { return ((replace === undefined) ? this.toString() : this.replace(new RegExp('[' + search + ']', 'g'), replace)); };

if (!String.prototype.startsWith)
    String.prototype.startsWith = function(search, pos) { return this.substr(((!pos) || (pos < 0)) ? 0 : +pos, search.length) === search; };

CInt = function(v)
{
	try
	{
		if (!isNaN(v)) return Math.floor(v);
		if (typeof v === 'undefined') return parseInt(0);
		if (v === null) return parseInt(0);
		var t = parseInt(v);
		if (isNaN(t)) return parseInt(0);
		return Math.floor(t);
	}
	catch (err) { }

	return parseInt(0);
};

CDbl = function(v)
{
	try
	{
		if (!isNaN(v)) return parseFloat(v);
		if (typeof v === 'undefined') return parseFloat(0.0);
		if (v === null) return parseFloat(0.0);
		var t = parseFloat(v);
		if (isNaN(t)) return parseFloat(0.0);
		return t;
	}
	catch (err) { }

	return parseFloat(0.0);
};

// dup of String.prototype.startsWith, but uses indexOf() instead of substr()
startsWith = function (haystack, needle) { return (needle === "") || (haystack.indexOf(needle) === 0); };
endsWith   = function (haystack, needle) { return (needle === "") || (haystack.substring(haystack.length - needle.length) === needle); };

ChopperBlank = function (sText, sSearch, sEnd)
{
	var sIntermediate = "";

	if (sSearch === "")
		sIntermediate = sText.substring(0, sText.length);
	else
	{
		var iIndexStart = sText.indexOf(sSearch);
		if (iIndexStart === -1)
			return "";

		sIntermediate = sText.substring(iIndexStart + sSearch.length);
	}

	if (sEnd === "")
		return sIntermediate;

	var iIndexEnd = sIntermediate.indexOf(sEnd);

	return (iIndexEnd === -1) ? sIntermediate : sIntermediate.substring(0, iIndexEnd);
};

CondenseSpacing = function(text)
{
	while (text.indexOf("  ") !== -1)
		text = text.replace("  ", " ");
	return text;
};

pad = function(sText, iWidth, sChar)
{
    sChar = ((sChar !== undefined) ? sChar : ('0'));
    sText = sText.toString();
    return ((sText.length >= iWidth) ? (sText) : (new Array(iWidth - sText.length + 1).join(sChar) + sText));
};

is_visible = (function () {
    var x = window.pageXOffset ? window.pageXOffset + window.innerWidth - 1 : 0,
        y = window.pageYOffset ? window.pageYOffset + window.innerHeight - 1 : 0,
        relative = !!((!x && !y) || !elementFromPoint(x, y));
        function inside(child, parent) {
            while(child){
                if (child === parent) return true;
                child = child.parentNode;
            }
        return false;
    };
    return function (elem) {
        if (
            hidden ||
            elem.offsetWidth==0 ||
            elem.offsetHeight==0 ||
            elem.style.visibility=='hidden' ||
            elem.style.display=='none' ||
            elem.style.opacity===0
        ) return false;
        var rect = elem.getBoundingClientRect();
        if (relative) {
            if (!inside(elementFromPoint(rect.left + elem.offsetWidth/2, rect.top + elem.offsetHeight/2),elem)) return false;
        } else if (
            !inside(elementFromPoint(rect.left + elem.offsetWidth/2 + window.pageXOffset, rect.top + elem.offsetHeight/2 + window.pageYOffset), elem) ||
            (
                rect.top + elem.offsetHeight/2 < 0 ||
                rect.left + elem.offsetWidth/2 < 0 ||
                rect.bottom - elem.offsetHeight/2 > (window.innerHeight || documentElement.clientHeight) ||
                rect.right - elem.offsetWidth/2 > (window.innerWidth || documentElement.clientWidth)
            )
        ) return false;
        if (window.getComputedStyle || elem.currentStyle) {
            var el = elem,
                comp = null;
            while (el) {
                if (el === document) {break;} else if(!el.parentNode) return false;
                comp = window.getComputedStyle ? window.getComputedStyle(el, null) : el.currentStyle;
                if (comp && (comp.visibility=='hidden' || comp.display == 'none' || (typeof comp.opacity !=='undefined' && comp.opacity != 1))) return false;
                el = el.parentNode;
            }
        }
        return true;
    };
})();
////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////
////////////// ** common_ET.js -- DO NOT MODIFY ** /////////////

if (window.ET === undefined) window.ET = { };
if ((window.ET.MCMF === undefined) || (CDbl(window.ET.MCMF.version < 1.01)) // MeanCloud mod framework
{
    window.ET.MCMF =
    {
        version: 1.01,
        
        TryingToLoad: false,
        WantDebug: false,
        WantFasterAbilityCDs: false,

        InBattle: false,
        FinishedLoading: false,
        Initialized: false,
        AbilitiesReady: false,
        InitialAbilityCheck: true,
        TimeLeftOnCD: 9999,
        TimeLastFight: 0,

        CombatID: undefined,
        BattleID: undefined,

        ToastMessageSuccess: function(msg)
        {
            toastr.success(msg);
        },

        ToastMessageWarning: function(msg)
        {
            toastr.warning(msg);
        },

        EventSubscribe: function(sEventName, fnCallback, sNote)
        {
            if (window.ET.MCMF.EventSubscribe_events === undefined)
                window.ET.MCMF.EventSubscribe_events = [];

            var newEvtData = {};
                newEvtData.name = ((!sEventName.startsWith("ET:")) ? ("ET:" + sEventName) : (sEventName));
                newEvtData.callback = fnCallback;
                newEvtData.note = sNote;

            window.ET.MCMF.EventSubscribe_events.push(newEvtData);

            /*
            jQ("div#ET_meancloud_bootstrap").off("ET:" + sEventName.trim()).on("ET:" + sEventName.trim(), function()
            {
                window.ET.MCMF.EventSubscribe_events.forEach(function(oThisEvent, index, array)
                {
                    if (sEventName === oThisEvent.name)
                    {
                        if (window.ET.MCMF.WantDebug) console.log("FIRING '" + oThisEvent.name + "'!" + ((oThisEvent.note === undefined) ? "" : " (" + oThisEvent.note + ")"));
                        oThisEvent.callback();
                    }
                });
            });
            */

            if (window.ET.MCMF.WantDebug) console.log("Added event subscription '" + sEventName + "'!" + ((sNote === undefined) ? "" : " (" + sNote + ")"));
        },

        EventTrigger: function(sEventName)
        {
            //jQ("div#ET_meancloud_bootstrap").trigger(sEventName);

            if (window.ET.MCMF.EventSubscribe_events === undefined) return;

            window.ET.MCMF.EventSubscribe_events.forEach(function(oThisEvent, index, array)
            {
                if (sEventName === oThisEvent.name)
                {
                    if (window.ET.MCMF.WantDebug) console.log("FIRING '" + oThisEvent.name + "'!" + ((oThisEvent.note === undefined) ? "" : " (" + oThisEvent.note + ")"));
                    try { oThisEvent.callback(); } catch (err) { if (window.ET.MCMF.WantDebug) console.log("Exception: " + err); }
                }
            });
        },

        MeteorCall: function(sMethod, oParam1, oParam2, sMsgSuccess, sMsgFailure)
        {
            Package.meteor.Meteor.call("crafting.craftItem", sRecipeID, iBatchAmt, function(errResp)
            {
                if (errResp)
                    window.ET.MCMF.ToastMessageWarning(sMsgFailure);
                else
                    window.ET.MCMF.ToastMessageSuccess(sMsgSuccess);
            });
        },

        FasterAbilityUpdates: function()
        {
            try
            {
                if ((window.ET.MCMF.WantFasterAbilityCDs) && (window.ET.MCMF.FinishedLoading) && (!window.ET.MCMF.InBattle) && (!window.ET.MCMF.AbilitiesReady))
                    Meteor.call("abilities.gameUpdate", function(e, t) { });
            }
            catch (err) { }

            setTimeout(window.ET.MCMF.FasterAbilityUpdates, 2000);
        },

        AbilityCDTrigger: function()
        {
            try
            {
                bStillInCombat = window.ET.MCMF.InBattle || ((time_val() - window.ET.MCMF.TimeLastFight) < 3);

                if ((window.ET.MCMF.FinishedLoading) && (!bStillInCombat))
                {
                    iTotalCD = 0;
                    iTotalCDTest = 0;
                    iHighestCD = 0;

                    window.ET.MCMF.GetAbilities().forEach(function(oThisAbility, index, array)
                    {
                        if (oThisAbility.equipped)
                        {
                            if (parseInt(oThisAbility.currentCooldown) > 0)
                            {
                                iTotalCD += parseInt(oThisAbility.currentCooldown);
                                if (iHighestCD < parseInt(oThisAbility.currentCooldown))
                                    iHighestCD = parseInt(oThisAbility.currentCooldown);
                            }
                        }

                        iTotalCDTest += parseInt(oThisAbility.cooldown);
                    });

                    if ((iTotalCDTest > 0) && (iTotalCD === 0))
                    {
                        if (!window.ET.MCMF.AbilitiesReady)
                        {
                            if (!window.ET.MCMF.InitialAbilityCheck)
                            {
                                if (window.ET.MCMF.WantDebug) console.log("<-- triggering ET:abilitiesReady -->");
                                window.ET.MCMF.EventTrigger("ET:abilitiesReady");
                                //jQ("div#ET_meancloud_bootstrap").trigger("ET:abilitiesReady");
                            }
                        }

                        window.ET.MCMF.AbilitiesReady = true;
                        window.ET.MCMF.TimeLeftOnCD = 0;
                    }
                    else
                    {
                        window.ET.MCMF.AbilitiesReady = false;
                        window.ET.MCMF.TimeLeftOnCD = iHighestCD;
                    }

                    window.ET.MCMF.InitialAbilityCheck = false;
                }
                else
                {
                    window.ET.MCMF.AbilitiesReady = false;
                    window.ET.MCMF.TimeLeftOnCD = 9999;
                }
            }
            catch (err) { }

            setTimeout(window.ET.MCMF.AbilityCDTrigger, 500);
        },

        InitMeteorTriggers: function()
        {
            if ((Package.meteor.Meteor === undefined) || (Package.meteor.Meteor.connection === undefined) || (Package.meteor.Meteor.connection._stream === undefined))
            {
                setTimeout(window.ET.MCMF.InitMeteorTriggers, 100);
                return;
            }

            Package.meteor.Meteor.connection._stream.on('message', function(sMeteorRawData)
            {
                if (window.ET.MCMF.CombatID === undefined)
                {
                    window.ET.MCMF.GetPlayerCombatData();
                    
                    /*
                    try
                    {
                        oDataTemp = Package.meteor.global.Accounts.connection._stores.combat._getCollection()._collection._docs._map;
                        window.ET.MCMF.CombatID = oDataTemp[Object.keys(oDataTemp)[0]]._id;
                    }
                    catch (err) { }
                    */
                }

                try
                {
                    oMeteorData = JSON.parse(sMeteorRawData);

                    /////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //
                    //  BACKUP TO RETRIEVE USER AND COMBAT IDS
                    //
                    if (oMeteorData.collection === "users")
                        if ((window.ET.MCMF.UserID === undefined) || (window.ET.MCMF.UserID.length !== 17))
                            window.ET.MCMF.UserID = oMeteorData.id;

                    if (oMeteorData.collection === "combat")
                        if ((window.ET.MCMF.CombatID === undefined) || (window.ET.MCMF.CombatID.length !== 17))
                            if (oMeteorData.fields.owner === window.ET.MCMF.UserID)
                                window.ET.MCMF.CombatID = oMeteorData.id;
                    //
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////

                    if (window.ET.MCMF.FinishedLoading)
                    {
                        if (oMeteorData.collection === "battlesList")
                        {
                            window.ET.MCMF.IsDemon = false;
                            window.ET.MCMF.AbilitiesReady = false;

                            if ((oMeteorData.msg === "added") || (oMeteorData.msg === "removed"))
                            {
                                window.ET.MCMF.InBattle = (oMeteorData.msg === "added");
                                if (window.ET.MCMF.WantDebug) console.log("<-- triggering ET:combat" + (((oMeteorData.msg === "added")) ? ("Start") : ("End")) + " -->");
                                window.ET.MCMF.EventTrigger("ET:combat" + (((oMeteorData.msg === "added")) ? ("Start") : ("End")));
                                //jQ("div#ET_meancloud_bootstrap").trigger("ET:combat" + (((oMeteorData.msg === "added")) ? ("Start") : ("End")));
                            }
                        }

                        if ((oMeteorData.collection === "battles") && (oMeteorData.msg === "added"))
                        {
                            if (oMeteorData.fields.finished)
                            {
                                window.ET.MCMF.WonLast = oMeteorData.fields.win;
                                window.ET.MCMF.TimeLastFight = time_val();

                                if (!oMeteorData.fields.win)
                                    window.ET.MCMF.HP = 0;

                                if (window.ET.MCMF.WantDebug) console.log("<-- triggering ET:combat" + ((oMeteorData.fields.win) ? ("Won") : ("Lost")) + " -->");
                                window.ET.MCMF.EventTrigger("ET:combat" + ((oMeteorData.fields.win) ? ("Won") : ("Lost")));
                                //jQ("div#ET_meancloud_bootstrap").trigger("ET:combat" + ((oMeteorData.fields.win) ? ("Won") : ("Lost")));
                            }
                        }
                    }

                    try
                    {
                        if (window.ET.MCMF.FinishedLoading)
                        {
                            if (oMeteorData.id)
                            {
                                if (oMeteorData.id.startsWith("battles-"))
                                {
                                    if (oMeteorData.msg !== "removed")
                                    {
                                        battleID = oMeteorData.id;
                                        battleData = JSON.parse(oMeteorData.fields.value);

                                        jQ.makeArray(battleData.units).forEach(function(currentPlayer, index, array)
                                        {
                                            try
                                            {
                                                if (currentPlayer.name === window.ET.MCMF.UserName)
                                                {
                                                    jQ.makeArray(currentPlayer.buffs).forEach(function(currentBuff, index2, array2)
                                                     {
                                                        try
                                                        {
                                                            if (currentBuff.id === "demons_heart")
                                                            {
                                                                if (currentBuff.data.active)
                                                                {
                                                                    if (!window.ET.MCMF.IsDemon)
                                                                    {
                                                                        window.ET.MCMF.IsDemon = true;

                                                                        if (window.ET.MCMF.WantDebug) console.log("<-- triggering ET:combat:buffDemon -->");
                                                                        window.ET.MCMF.EventTrigger("ET:combat:buffDemon");
                                                                        //jQ("div#ET_meancloud_bootstrap").trigger("ET:combat:buffDemon");
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        catch (err) { }
                                                    });

                                                    return true; // break out of forEach()
                                                }
                                            }
                                            catch (err) { }
                                        });
                                    }
                                }
                            }
                        }
                    }
                    catch (err) { }
                }
                catch (err) { }

                try
                {
                    //todo: use life data from Meteor vs captured meteor response data
                    oMeteorData = JSON.parse(sMeteorRawData);

                    if (oMeteorData.collection === "combat")
                    {
                        if ((oMeteorData.fields.owner === window.ET.MCMF.UserID) || (oMeteorData.id === window.ET.MCMF.CombatID))
                        {
                            window.ET.MCMF.HP  = oMeteorData.fields.stats.health;
                            window.ET.MCMF.NRG = oMeteorData.fields.stats.energy;
                        }
                    }
                }
                catch (err) { }
            });
        },

        AbilityCDCalc: function()
        {
            iTotalCD = 0;
            iTotalCDTest = 0;
            iHighestCD = 0;

            window.ET.MCMF.GetAbilities().forEach(function(oThisAbility, index, array)
            {
                if (oThisAbility.equipped)
                {
                    if (parseInt(oThisAbility.currentCooldown) > 0)
                    {
                        iTotalCD += parseInt(oThisAbility.currentCooldown);
                        if (iHighestCD < parseInt(oThisAbility.currentCooldown))
                            iHighestCD = parseInt(oThisAbility.currentCooldown);
                    }
                }

                iTotalCDTest += parseInt(oThisAbility.cooldown);
            });

            if ((iTotalCDTest > 0) && (iTotalCD === 0))
            {
                if (!window.ET.MCMF.AbilitiesReady)
                {
                    if (!window.ET.MCMF.InitialAbilityCheck)
                    {
                        if (window.ET.MCMF.WantDebug) console.log("<-- triggering ET:abilitiesReady -->");
                        window.ET.MCMF.EventTrigger("ET:abilitiesReady");
                        //jQ("div#ET_meancloud_bootstrap").trigger("ET:abilitiesReady");
                    }
                }

                window.ET.MCMF.AbilitiesReady = true;
                window.ET.MCMF.TimeLeftOnCD = 0;
            }
            else
            {
                window.ET.MCMF.AbilitiesReady = false;
                window.ET.MCMF.TimeLeftOnCD = iHighestCD;
            }

            window.ET.MCMF.InitialAbilityCheck = false;
        },

        GetPlayerCombatData: function()
        {
            var oCombatPlayerData = undefined;
            
            try
            {        
                window.ET.MCMF.CombatID = undefined;
            
                jQuery.each(Package.meteor.global.Accounts.connection._stores.combat._getCollection()._collection._docs._map, function()
                {
                    if (this.owner === window.ET.MCMF.UserID)
                    {
                        oCombatPlayerData = this;
                        
                        window.ET.MCMF.CombatID === oCombatPlayerData._id;
                    }
                });        
            }
            catch (err) { }
            
            return oCombatPlayerData;
        },
        
        GetAbilities: function()
        {
            return Object.keys(window.ET.MCMF.AbilityManager._collection._docs._map).map(key => window.ET.MCMF.AbilityManager._collection._docs._map[key])[0].learntAbilities;
        },

        GetAdventures: function()
        {
            return Object.keys(window.ET.MCMF.AdventureManager._collection._docs._map).map(key => window.ET.MCMF.AdventureManager._collection._docs._map[key])[0].adventures;
        },

        GetChats: function()
        {
            return Object.keys(window.ET.MCMF.ChatManager._collection._docs._map).map(key => window.ET.MCMF.ChatManager._collection._docs._map[key]);
        },

        GetItems: function()
        {
            return Object.keys(window.ET.MCMF.ItemManager._collection._docs._map).map(key => window.ET.MCMF.ItemManager._collection._docs._map[key]);
        },
        
        GetSkills: function()
        {
            return Object.keys(window.ET.MCMF.SkillManager._collection._docs._map).map(key => window.ET.MCMF.SkillManager._collection._docs._map[key]);
        },

        // need a better way to check if the game has loaded basic data, but this is fine for now
        Setup: function()
        {
            if ((!window.ET.MCMF.TryingToLoad) && (!window.ET.MCMF.FinishedLoading))
            {
                // use whatever version of jQuery available to us
                $("body").append("<div id=\"ET_meancloud_bootstrap\" style=\"visibility: hidden; display: none;\"></div>");
                window.ET.MCMF.TryingToLoad = true;
                window.ET.MCMF.Setup_Initializer();
            }
        },

        Setup_Initializer: function()
        {
            // wait for Meteor availability
            if ((Package === undefined) || (Package.meteor === undefined) || (Package.meteor.Meteor === undefined) || (Package.meteor.Meteor.connection === undefined) || (Package.meteor.Meteor.connection._stream === undefined))
            {
                setTimeout(window.ET.MCMF.Setup_Initializer, 10);
                return;
            }

            if (!window.ET.MCMF.Initialized)
            {
                window.ET.MCMF.Initialized = true;
                window.ET.MCMF.Setup_SendDelayedInitializer();
                window.ET.MCMF.InitMeteorTriggers();
                window.ET.MCMF.Setup_remaining();
            }
        },

        Setup_SendDelayedInitializer: function()
        {
            try
            {
                jQ("div#ET_meancloud_bootstrap").trigger("ET:initialized");
                window.ET.MCMF.EventTrigger("ET:initialized");
                //if (window.ET.MCMF.WantDebug) console.log("<-- triggering ET:initialized -->");
            }
            catch (err)
            {
                setTimeout(window.ET.MCMF.Setup_SendDelayedInitializer, 100);
            }
        },

        Setup_remaining: function()
        {
            try
            {
                window.ET.MCMF.UserID = Package.meteor.global.Accounts.connection._userId;
                window.ET.MCMF.UserName = Package.meteor.global.Accounts.connection._stores.users._getCollection()._collection._docs._map[Package.meteor.global.Accounts.connection._userId].username;
                window.ET.MCMF.GetPlayerCombatData();

                window.ET.MCMF.AbilityManager = Package.meteor.global.Accounts.connection._stores.abilities._getCollection();
                window.ET.MCMF.AdventureManager = Package.meteor.global.Accounts.connection._stores.adventures._getCollection();
                window.ET.MCMF.ChatManager = Package.meteor.global.Accounts.connection._stores.simpleChats._getCollection();
                window.ET.MCMF.ItemManager = Package.meteor.global.Accounts.connection._stores.items._getCollection();
                window.ET.MCMF.SkillManager = Package.meteor.global.Accounts.connection._stores.skills._getCollection();

                if (window.ET.MCMF.GetAbilities().length < 0) throw "Not loaded yet: no abilities";
                if (window.ET.MCMF.GetItems().length < 0) throw "Not loaded yet: no items";
                if (window.ET.MCMF.GetChats().length < 0) throw "Not loaded yet: no chats";
                if (window.ET.MCMF.GetSkills().length < 0) throw "Not loaded yet: no skills";

                //console.log(JSON.stringify(window.ET.MCMF.GetSkills()));
                
                // if the above is all good, then this should be no problem:

                window.ET.MCMF.AbilityCDTrigger();     // set up ability CD trigger
                window.ET.MCMF.AbilityCDCalc();
                window.ET.MCMF.FasterAbilityUpdates(); // set up faster ability updates (do not disable, this is controlled via configurable setting)

                // trigger finished-loading event
                if (!window.ET.MCMF.FinishedLoading)
                {
                    if (window.ET.MCMF.WantDebug) console.log("<-- triggering ET:loaded -->");
                    window.ET.MCMF.EventTrigger("ET:loaded");
                    //jQ("div#ET_meancloud_bootstrap").trigger("ET:loaded");
                    window.ET.MCMF.FinishedLoading = true;
                }
            }
            catch (err)
            {
                // any errors and we retry setup
                //console.log("ET MCMF Framework Setup Error: " + JSON.stringify(err));
                setTimeout(window.ET.MCMF.Setup_remaining, 500);
            }
        },

        Loaded: function(fnCallback, sNote)
        {
            if (!window.ET.MCMF.FinishedLoading)
                window.ET.MCMF.EventSubscribe("loaded", fnCallback, sNote);
            else
                fnCallback();
        },

        Ready: function(fnCallback, sNote)
        {
            if (!window.ET.MCMF.Initialized)
                window.ET.MCMF.EventSubscribe("initialized", fnCallback, sNote);
            else
                fnCallback();
        }
    };

    window.ET.MCMF.Setup();
}
////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////
////////// ** CORE SCRIPT STARTUP -- DO NOT MODIFY ** //////////
function LoadJQ(callback) {
    if (window.jQ === undefined) { var script=document.createElement("script");script.setAttribute("src","//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js");script.addEventListener('load',function() {
        var subscript=document.createElement("script");subscript.textContent="window.jQ=jQuery.noConflict(true);("+callback.toString()+")();";document.body.appendChild(subscript); },
    !1);document.body.appendChild(script); } else callback(); } LoadJQ(startup);
////////////////////////////////////////////////////////////////