• Hail, we're RedGuides. We want you to play six (yes, 6!) EverQuest characters at once. We have scripts and a friendly community to help, please join our playstyle and say hello! 👋
  • We've added LLM sections to our Terms & Rules and Resource Rules, for everyone's sanity & in-game safety.
    Read more
    a. Do not replace your voice with an LLM. This goes for your posts and your scripts. Drafting and editing with a tool is fine, but don't take you out of what you share.
    b. Do not replace your EQ character's voice with an LLM. We don't want scripts that speak over /ooc, /shout or other public channels. This has been an unwritten rule that's kept casino scripts off the site for decades, but we're now compelled to make it clear: keep automated communication private.

    Why Does RG Review Scripts?
    Nearly every LLM-written Lua script we see is making your character do impossible things, and rarely in a way that's beneficial to you. We've seen heavy server hammering, /target over impossible distances when /nav spawn would passively accomplish the same thing, a spawn search that fires 20+ times per second, and other pointless actions that are likely annoying GMs.

    You are welcome to use LLMs as a tool to structure, draft, and edit your work, but please read critically before hitting /lua run
Resource icon

Release Endless Mana for MQ2Mage Update 2.0

Maybe I described my wish in an uncomprehensively manner.
As the last version is written in Lua, it could do an infinitive loop, waiting for the mage to get l,ow on mana, and than start to recover the mana.
As far as I could unterstand, actually 1 call of MM will do 1 cycle of manarecovering and than end its service for this time.
To have it work all amgic, you need somethiong else to start it again, once you get low on mana.

As Lua it can run contemporary with all else running, so it could be extendet by a main-loop waiting for the mana to get low.
 
I set up a react for it a long time ago (I think it monitors mana level and combat state). But if you want to have it monitor mana and kick off the cycle at that point, feel free to have a go at the changes. I'm in the middle of another project and really don't have the time to tackle this. As hellfyre eludes to, some sort of config file will be necessary to keep track of the mana level. And probably also one for whether to do the mana recovery while in combat (maybe even taking into account if doing this in a raid/mission vs normal group grinding).
 
has anyone got this to work when using Hunter Tank mode on your mage? For me it will not trigger the macro. When Mage gets to the low mana threshold he just sits and meds. Is this because of how Hunter Tank works?
 
It works but the React doesn't for me. I made a /mac mm button so when I need mana I hit the button, it pauses my MQ2Mage and does what it is supposed to do.
 
So I ended up using the Lua from rouneq
I've expanded this to account for Mages leveling 115 -> 120. Since neither MS XIV nor Gather Vigor are available until 120, those mages below still need MS XIII and Gather Potency. I've also encountered issues getting the MS spell to load (sometimes it won't and I have to do it manually). Lastly, I've also added all the elemental staffs and it'll use the first one it finds in inventory. There's a few other changes, but those should be seen as more of a cleanup. Sharing in case anyone else is interested. And num1 can take them to use going forward. Much of the additions are taken from other macros I use, so I can't claim credit for the basic ideas behind them. Just the tweaks for this particular usage.
and a simple LEM to trigger it. Caveat, though, it gets weird when you are recovering from a death since (in my case) CWTN kicks in and wants to do Mage stuff and the MM Lua also wants to do it's thing. Here I the LEM code

Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENnb3RMUzFBY21WMGRYSnVJR0p2YjJ4bFlXNGdRRkpsZEhWeWJuTWdkSEoxWlNCcFppQjBhR1VnWVdOMGFXOXVJSE5vYjNWc1pDQm1hWEpsTENCdmRHaGxjbmRwYzJVZ1ptRnNjMlV1Q214dlkyRnNJR1oxYm1OMGFXOXVJR052Ym1ScGRHbHZiaWdwQ2lBZ0lDQnNiMk5oYkNCdGVWOWpiR0Z6Y3lBOUlHMXhMbFJNVHk1TlpTNURiR0Z6Y3k1VGFHOXlkRTVoYldVb0tRb2dJQ0FnYkc5allXd2diWGxmYldGdVlTQTlJRzF4TGxSTVR5NU5aUzVRWTNSTllXNWhLQ2tLSUNBZ0lHeHZZMkZzSUcxdFgzTjBZWFIxY3lBOUlHMXhMbFJNVHk1TWRXRXVVMk55YVhCMEtDZHRiU2NwTGxOMFlYUjFjeWdwQ2lBZ0lDQnlaWFIxY200Z2JYbGZZMnhoYzNNZ1BUMGdKMDFCUnljZ1lXNWtJRzE1WDIxaGJtRWdQQ0F4TlNCaGJtUWdiVzFmYzNSaGRIVnpJSDQ5SUNkU1ZVNU9TVTVISndwbGJtUUtDbXh2WTJGc0lHWjFibU4wYVc5dUlHRmpkR2x2YmlncENpQWdJQ0J0Y1M1amJXUW9KeTlzZFdFZ2NuVnVJRzF0SnlrS1pXNWtDZ3B5WlhSMWNtNGdlMk52Ym1SbWRXNWpQV052Ym1ScGRHbHZiaXdnWVdOMGFXOXVablZ1WXoxaFkzUnBiMjU5IiwKIGNhdGVnb3J5ID0gIiIsCiB0eXBlID0gImNvbmRpdGlvbnMiLAogbmFtZSA9ICJNYWdlTWFuYSIsCn0=
 
So I ended up using the LUA from rouneq

and a simple LEM to trigger it. Caveat, though, it gets weird when you are recovering from a death since (in my case) CWTN kicks in and wants to do Mage stuff and the MM Lua also wants to do it's thing. Here I the LEM code

Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENnb3RMUzFBY21WMGRYSnVJR0p2YjJ4bFlXNGdRRkpsZEhWeWJuTWdkSEoxWlNCcFppQjBhR1VnWVdOMGFXOXVJSE5vYjNWc1pDQm1hWEpsTENCdmRHaGxjbmRwYzJVZ1ptRnNjMlV1Q214dlkyRnNJR1oxYm1OMGFXOXVJR052Ym1ScGRHbHZiaWdwQ2lBZ0lDQnNiMk5oYkNCdGVWOWpiR0Z6Y3lBOUlHMXhMbFJNVHk1TlpTNURiR0Z6Y3k1VGFHOXlkRTVoYldVb0tRb2dJQ0FnYkc5allXd2diWGxmYldGdVlTQTlJRzF4TGxSTVR5NU5aUzVRWTNSTllXNWhLQ2tLSUNBZ0lHeHZZMkZzSUcxdFgzTjBZWFIxY3lBOUlHMXhMbFJNVHk1TWRXRXVVMk55YVhCMEtDZHRiU2NwTGxOMFlYUjFjeWdwQ2lBZ0lDQnlaWFIxY200Z2JYbGZZMnhoYzNNZ1BUMGdKMDFCUnljZ1lXNWtJRzE1WDIxaGJtRWdQQ0F4TlNCaGJtUWdiVzFmYzNSaGRIVnpJSDQ5SUNkU1ZVNU9TVTVISndwbGJtUUtDbXh2WTJGc0lHWjFibU4wYVc5dUlHRmpkR2x2YmlncENpQWdJQ0J0Y1M1amJXUW9KeTlzZFdFZ2NuVnVJRzF0SnlrS1pXNWtDZ3B5WlhSMWNtNGdlMk52Ym1SbWRXNWpQV052Ym1ScGRHbHZiaXdnWVdOMGFXOXVablZ1WXoxaFkzUnBiMjU5IiwKIGNhdGVnb3J5ID0gIiIsCiB0eXBlID0gImNvbmRpdGlvbnMiLAogbmFtZSA9ICJNYWdlTWFuYSIsCn0=
Do you use MQ2Boxr? One of the first things the script does after verifying the operating environment is workable (i.e., initialization logic) is to use /squelch /docommand /boxr pause. Later followed by a /boxr unpause before ending. This should stop any macro/plugin activity while MM is doing the work.
 
So I ended up using the LUA from rouneq

and a simple LEM to trigger it. Caveat, though, it gets weird when you are recovering from a death since (in my case) CWTN kicks in and wants to do Mage stuff and the MM Lua also wants to do it's thing. Here I the LEM code

Code:
cmV0dXJuIHsKIGxvYWQgPSB7CiAgYWx3YXlzID0gZmFsc2UsCiAgY2xhc3MgPSAiIiwKICB6b25lID0gIiIsCiB9LAogY29kZSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENnb3RMUzFBY21WMGRYSnVJR0p2YjJ4bFlXNGdRRkpsZEhWeWJuTWdkSEoxWlNCcFppQjBhR1VnWVdOMGFXOXVJSE5vYjNWc1pDQm1hWEpsTENCdmRHaGxjbmRwYzJVZ1ptRnNjMlV1Q214dlkyRnNJR1oxYm1OMGFXOXVJR052Ym1ScGRHbHZiaWdwQ2lBZ0lDQnNiMk5oYkNCdGVWOWpiR0Z6Y3lBOUlHMXhMbFJNVHk1TlpTNURiR0Z6Y3k1VGFHOXlkRTVoYldVb0tRb2dJQ0FnYkc5allXd2diWGxmYldGdVlTQTlJRzF4TGxSTVR5NU5aUzVRWTNSTllXNWhLQ2tLSUNBZ0lHeHZZMkZzSUcxdFgzTjBZWFIxY3lBOUlHMXhMbFJNVHk1TWRXRXVVMk55YVhCMEtDZHRiU2NwTGxOMFlYUjFjeWdwQ2lBZ0lDQnlaWFIxY200Z2JYbGZZMnhoYzNNZ1BUMGdKMDFCUnljZ1lXNWtJRzE1WDIxaGJtRWdQQ0F4TlNCaGJtUWdiVzFmYzNSaGRIVnpJSDQ5SUNkU1ZVNU9TVTVISndwbGJtUUtDbXh2WTJGc0lHWjFibU4wYVc5dUlHRmpkR2x2YmlncENpQWdJQ0J0Y1M1amJXUW9KeTlzZFdFZ2NuVnVJRzF0SnlrS1pXNWtDZ3B5WlhSMWNtNGdlMk52Ym1SbWRXNWpQV052Ym1ScGRHbHZiaXdnWVdOMGFXOXVablZ1WXoxaFkzUnBiMjU5IiwKIGNhdGVnb3J5ID0gIiIsCiB0eXBlID0gImNvbmRpdGlvbnMiLAogbmFtZSA9ICJNYWdlTWFuYSIsCn0=
I can't seem to get the Lua from rouneq to work. Did you need to do any changes to that?
 
My Lua version. There is an issue if the "Gather" spell isn't available. Put in your lua folder. Extract into that folder (a couple files are put into lib).
I made some small changes on it, here is my version based on the Lua by @rouneq

MM Brute Force
Lua:
--- @type Mq
local mq = require('mq')
local Note = require('lib.Note')

Note.prefix = 'MonsterMana'
Note.loglevel = 'info'

local workingStates = { Active=true, Cooldown=true, Resting=true, }
local MonsterSummoning
local MonsterSummoningSpell
local GatherMana
local GatherManaSpell
local ReclaimSet
local ReclaimItem
local RetryCount = 5
local MiscSpellGem = 7
local IsMemorizing = false

--[[ local function delay(timeout, condition)
    if ((not timeout and not condition) or type(timeout) ~= "number") then
        return
    end

    if (not condition) then
        mq.delay(timeout)

        return
    end

    local function predicate()
        mq.doevents()

        return condition()
    end

    mq.delay(timeout, predicate)
end ]]

local function CheckPlugin(plugin)
    if (not mq.TLO.Plugin(plugin)()) then
        mq.cmdf('/squelch /plugin %s noauto', plugin)
        Note.Debug('\aw%s\ar not detected! \awThis script requires it! Loading ...', plugin)
    end
end

local function ChooseAbility(set)
    -- Create New spell holder as Outer if it doesn't already exist
    local chosenSpell
    local highestSpellLevel = 0

    -- Iterate throught the spell set
    for _, value in ipairs(set) do
        Note.Debug('spell: %s', value)
        local spellLevel = mq.TLO.Spell(value).Level()
        Note.Debug('spellLevel: %s', spellLevel)
        local spellRank = mq.TLO.Spell(value).RankName()
        Note.Debug('spellRank: %s', spellRank)

        -- Detect mispelled spells
        if (not spellRank) then
            Note.Info('\arSPELL NOT AVAILABLE: \ax%s', value)
        -- If we can cast the spell and its in our book, see if we should use it
        elseif (mq.TLO.Me.Book(spellRank)()) then
            -- If it's higher than the spell we've already set, use it.
            if (spellLevel > highestSpellLevel) then
                -- This is the value we use for casting and buff checking so must be BaseName. RankName is only
                -- for memorization and Me.Book checking.
                if (mq.TLO.Me.SpellRankCap() > 1) then
                    chosenSpell = mq.TLO.Spell(spellRank).RankName()
                else
                    chosenSpell = mq.TLO.Spell(spellRank).BaseName()
                end

                highestSpellLevel = spellLevel
            end
        end
    end

    Note.Debug('selected spell: %s', chosenSpell)

    return chosenSpell
end

local function ChooseItem(set)
    local reclaimItem

    -- Iterate throught the staff set
    for _, value in ipairs(set) do
        if (mq.TLO.FindItemCount(value)()>0) then
            reclaimItem = value

            break
        end
    end

    Note.Debug('reclaim item: %s', reclaimItem)

    return reclaimItem
end

local function Init()
    CheckPlugin('MQ2XAssist')
    CheckPlugin('MQ2AdvPath')
    CheckPlugin('MQ2MoveUtils')
    CheckPlugin('MQ2Boxr')

    MonsterSummoning = {
        "Monster Summoning XV",
        "Monster Summoning XIV",
        "Monster Summoning XIII",
    }

    MonsterSummoningSpell = ChooseAbility(MonsterSummoning)

    if (not MonsterSummoningSpell) then
        Note.Info('A monster summoning spell is not available')

        return false
    end

    GatherMana = {
        "Gather Vigor",
        "Gather Potency",
    }

    GatherManaSpell = ChooseAbility(GatherMana)

    if (not GatherManaSpell) then
        Note.Info('A gather mana spell is not available')

        return false
    end

    -- There are multiple instant cast "Reclaim Energy" items, if yours is different, add to the set below.
    ReclaimSet = {
        "Staff of Elemental Mastery: Earth",
        "Staff of Elemental Mastery: Fire",
        "Staff of Elemental Mastery: Air",
        "Staff of Elemental Mastery: Water",
        "Broom of Trilon",
        "Ancient Torch of Alna",
        "Gemmed Gloves of Guile",
        "Gloves of Dark Summoning",
        "Shovel of Ponz",
        "Stein of Ulissa",
        "Torch of Alna"
    }

    ReclaimItem = ChooseItem(ReclaimSet)

    if (not ReclaimItem) then
        Note.Info('An item to reclaim energy is not present in inventory')

        return false
    end

    return true
end

local function Event_BeginMemorizing(_, spellName)
    IsMemorizing = true
end

local Event_EndMemorizing = function(_, spellName)
    IsMemorizing = false
end

mq.event('BeginMemorizing', "#*#Beginning to memorize #1#...#*#", Event_BeginMemorizing)
mq.event('FinishMemorizing', "#*#You have finished memorizing #1##*#", Event_EndMemorizing)
mq.event('AbortMemorizing', "#*#Aborting memorization of spell.#*#", Event_EndMemorizing)

local function LoadSpellGem(spellToMem, requestedMemGem)
    if (mq.TLO.Me.Gem(spellToMem)()) then
        Note.Debug('Requested spell "%s" is already in a gem slot. Returning that gem slot number instead', spellToMem)

        return mq.TLO.Me.Gem(spellToMem)()
    end

    -- We want to pop out quickly if we're in combat or moving
    if ( mq.TLO.AdvPath.Following() or
        mq.TLO.MoveTo.Moving() or
        mq.TLO.Me.Moving() or
        -- mq.TLO.XAssist.XTFullHaterCount() > 0 or
        mq.TLO.Navigation.Active()) then
        Note.Info('Cannot mem a spell while moving')

        return
    end

    -- Need to use RankName with Me.Book and /memspell
    spellToMem = mq.TLO.Spell(spellToMem).RankName()

    if (spellToMem == nil or spellToMem == '') then
        Note.Info('Invalid spellToMem "%s"', spellToMem)

        return
    end

    if (not mq.TLO.Me.Book(spellToMem)()) then
        Note.Info('\awCould Not find the spell "%s" in the spell book.', spellToMem)

        return
    end

    if (not mq.TLO.Me.Gem(requestedMemGem)() and requestedMemGem ~= MiscSpellGem) then
        Note.Info('Requested gem slot, %s, is not available. Using default misc spell gem, %s, instead', requestedMemGem, MiscSpellGem)

        requestedMemGem = MiscSpellGem
    end

    Note.Info('\agMeming \aw"%s" in \agslot %s', spellToMem, requestedMemGem)
    mq.cmdf('/memspell %s "%s"', requestedMemGem, spellToMem)

    -- Client settle delay to avoid getting stuck in loading spell gems.
    mq.delay(2000, function()
        --return mq.TLO.Window('SpellBookWnd').Open() and IsMemorizing
        return IsMemorizing
    end)

    mq.delay(10000, function()
        return mq.TLO.Me.Gem(requestedMemGem).Name() == spellToMem or not IsMemorizing
    end)

    if (mq.TLO.Me.Gem(requestedMemGem).Name() ~= spellToMem) then
        --[[ if (mq.TLO.XAssist.XTFullHaterCount() > 0) then
            Note.Info('I was interruped by combat while waiting to memorize ${spellToMem}.')

            return
        end ]]

        if (not mq.TLO.Window('SpellBookWnd').Open()) then
            Note.Info('My Spellbook Window closed while I tried to memorize a spell.')

            return
        end
    end

    return requestedMemGem
end

local function ReclaimMana()
    Note.Info('Mana Loop Started')
    mq.cmd('/squelch /beepontells off')
    while (mq.TLO.Me.PctMana() < 90) do
        if (mq.TLO.Cursor.ID()) then
            mq.cmd('/autoinventory')
            mq.delay(2000)
            mq.cmd('/autoinventory')
        end
       
        -- move to MA

        if mq.TLO.Group.MainAssist() and mq.TLO.Group.MainAssist.Distance() > 40 then
            mq.cmdf('/squelch /nav id %s',mq.TLO.Group.MainAssist.ID())
            Note.Info('Catching up with MA')
            while mq.TLO.Navigation.Active() do mq.delay(100) end
            mq.delay(500)
        end

        -- Checking if mana is under 8%
        if (mq.TLO.Me.PctMana() < 8 and mq.TLO.Me.SpellReady(GatherManaSpell)()) then
            mq.cmdf('/cast "%s"', GatherManaSpell)
            mq.delay(20000, function() return mq.TLO.Me.Casting.ID() == nil end)
        elseif (mq.TLO.Me.CurrentMana() < mq.TLO.Spell(MonsterSummoningSpell).Mana()) then
            -- Sitting
            if (mq.TLO.Me.Standing() and not mq.TLO.Me.Casting.ID()) then
                mq.TLO.Me.Sit()
            end

            mq.delay(6050)
        else
            if (mq.TLO.Me.Sitting()) then
                mq.TLO.Me.Stand()
            end

            mq.delay(1000)

            Note.Debug('Request load spell "%s" to gem %s', MonsterSummoningSpell, MiscSpellGem)
            local actualSpellGem = LoadSpellGem(MonsterSummoningSpell, MiscSpellGem)

            if (not actualSpellGem) then
                Note.Info('Requested spell load failed...exting')

                return
            end
           
            mq.delay(500)

            if (mq.TLO.Me.SpellReady(MonsterSummoningSpell)()) then
                mq.cmdf('/cast %s', actualSpellGem)
            end
           
            mq.delay(7000, function() return not mq.TLO.Me.Casting.ID() end)
            mq.delay(500)
            if (mq.TLO.Me.Pet.ID() > 0) then
                mq.cmdf('/useitem %s', ReclaimItem)
            end

            mq.delay(500)
        end
        mq.delay(50)
    end
   
    mq.delay(1000)
    Note.Info('Mana Loop Ended')
    local counter = 0
    while (mq.TLO.Me.Pet.ID() > 0 and counter < RetryCount) do
        mq.cmdf('/useitem %s', ReclaimItem)
        mq.delay(500)
        counter = counter + 1
    end
end

local function Main()
    if (mq.TLO.Me.Class.ShortName() ~= 'MAG') then
        Note.Info('MonsterMana only works for Mage characters')

        return false
    end

    if (mq.TLO.Me.PctMana() > 95) then
        Note.Info('Mana is nearly full; nothing to do')

        return false
    end

    -- Sets up the operational domain including which version of monster to summon, basic mana recovery spell to use (if low on mana), and reclaim item to use from inventory
    if (not Init()) then
        Note.Info('Macro initialization unsuccessful')

        return false
    end

    mq.cmd('/squelch /docommand /boxr pause')
    mq.delay(300)
    mq.cmd('/squelch /attack off')
    -- added auto inventory
    local counter = 0
    while (mq.TLO.Cursor.ID() and counter < RetryCount) do
        mq.cmd('/autoinventory')
        mq.delay(500)
        mq.cmd('/autoinventory')
        counter = counter + 1
    end

    mq.delay(500)

    -- Section for if you already have a main pet summoned.
    if (mq.TLO.Me.Pet.ID() and mq.TLO.Me.Pet.ID() > 0) then
        Note.Info('Primary mana method started (with pet)!')

        -- Stores main pet using Suspend Companion to keep items/buffs on pet.
        Note.Info('Storing Pet')
        local counter = 0
        while (mq.TLO.Me.Pet.ID() > 0 and counter < RetryCount) do
            mq.cmd('/pet hold')
            mq.delay(300)
            mq.cmd('/pet back off')
            mq.delay(300)
            mq.cmd('/alt act 1215') --summon companion
            mq.delay(500)
            if (mq.TLO.Me.Pet.ID()> 0) then mq.cmd('/alt act 176') end -- suspend pet
            mq.delay(500)
            mq.delay(8000, function() return not mq.TLO.Me.Casting.ID() end)
            counter = counter + 1
        end

        ReclaimMana()

        -- Returns main pet from Suspend Companion
        Note.Info('Restoring Main Pet')
        local counter = 0
        while (mq.TLO.Me.Pet.ID() == 0 and counter < RetryCount) do
            Note.Info('resummon pet')
            mq.delay(300)
            mq.cmd('/alt act 176')
            mq.delay(300)
            mq.delay(6000, function() return not mq.TLO.Me.Casting.ID() end)
            mq.delay(300)
            counter = counter + 1
        end
    -- Secondary method for if you reciently died, have 0 mana and no main pet.
    else
        Note.Info('Primary mana method started (no pet)!')
        mq.delay(300)

        while (mq.TLO.Me.PctMana() < 8) do
            if (mq.TLO.Me.SpellReady(mq.TLO.Spell(GatherManaSpell).RankName())) then
                mq.cmdf('/cast "%s"', mq.TLO.Spell(GatherManaSpell).RankName())
                mq.delay(20000, function() return not mq.TLO.Me.Casting.ID() end)
            elseif (workingStates[mq.TLO.Me.CombatState()]) then
                -- Sitting
                if (mq.TLO.Me.Standing() and not mq.TLO.Me.Casting.ID()) then
                    mq.TLO.Me.Sit()
                end

                mq.delay(6050)
            end
            mq.delay(200)
        end

        ReclaimMana()
    end

    mq.delay(300)
    mq.cmd('/pet hold')
    mq.delay(300)
    mq.cmd('/squelch /docommand /boxr unpause')
    mq.delay(300)
    Note.Info('Mana Macro Ending')
    Note.Info('Mage Mana now: \ag%s', mq.TLO.Me.PctMana())
    mq.cmd('/squelch /beepontells on')
end

Main()

Also here is a LEM to trigger it:

cmV0dXJuIHsKIFsibmFtZSJdID0gIk1hZ2VNYW5hQnJ1dGVmb3JjZSIsCiBbImxvYWQiXSA9IHsKICBbInpvbmUiXSA9ICIiLAogIFsiY2xhc3MiXSA9ICIiLAogIFsiYWx3YXlzIl0gPSBmYWxzZSwKIH0sCiBbInR5cGUiXSA9ICJjb25kaXRpb25zIiwKIFsiY29kZSJdID0gImJHOWpZV3dnYlhFZ1BTQnlaWEYxYVhKbEtDZHRjU2NwQ2dvdExTMUFjbVYwZFhKdUlHSnZiMnhsWVc0Z1FGSmxkSFZ5Ym5NZ2RISjFaU0JwWmlCMGFHVWdZV04wYVc5dUlITm9iM1ZzWkNCbWFYSmxMQ0J2ZEdobGNuZHBjMlVnWm1Gc2MyVXVDbXh2WTJGc0lHWjFibU4wYVc5dUlHTnZibVJwZEdsdmJpZ3BDaUFnSUNCc2IyTmhiQ0J0ZVY5amJHRnpjeUE5SUcxeExsUk1UeTVOWlM1RGJHRnpjeTVUYUc5eWRFNWhiV1VvS1FvZ0lDQWdiRzlqWVd3Z2JYbGZiV0Z1WVNBOUlHMXhMbFJNVHk1TlpTNVFZM1JOWVc1aEtDa0tJQ0FnSUd4dlkyRnNJR05vWldOclgzQmhkWE5sWkNBOUlHMXhMbFJNVHk1RFYxUk9MbEJoZFhObFpDZ3BDaUFnSUNCc2IyTmhiQ0J0YlY5emRHRjBkWE1nUFNCdGNTNVVURTh1VEhWaExsTmpjbWx3ZENnblRVMWljblYwWlNjcExsTjBZWFIxY3lncENpQWdJQ0J5WlhSMWNtNGdiWGxmWTJ4aGMzTWdQVDBnSjAxQlJ5Y2dZVzVrSUcxNVgyMWhibUVnUENBeU1DQmhibVFnYlcxZmMzUmhkSFZ6SUg0OUlDZFNWVTVPU1U1SEp5QmhibVFnWTJobFkydGZjR0YxYzJWa0lEMDlJR1poYkhObENtVnVaQW9LYkc5allXd2dablZ1WTNScGIyNGdZV04wYVc5dUtDa0tJQ0FnSUcxeExtTnRaQ2duTDJ4MVlTQnlkVzRnVFUxaWNuVjBaU2NwQ21WdVpBb0tjbVYwZFhKdUlIdGpiMjVrWm5WdVl6MWpiMjVrYVhScGIyNHNJR0ZqZEdsdmJtWjFibU05WVdOMGFXOXVmUT09IiwKIFsiY2F0ZWdvcnkiXSA9ICJncmluZCIsCn0=
 

Attachments

I may have to just do I don't feel left out. My Druid doesn't even have mana problems. My FTP Druid. I'm serious.
Then they are underperforming what they are capable of or you are pulling 1 mob and have downtime between mobs. There's no way if those toons are pushing they are staying at 80%+ mana indeffinently.
 
Then they are underperforming what they are capable of or you are pulling 1 mob and have downtime between mobs. There's no way if those toons are pushing they are staying at 80%+ mana indeffinently.
I can't make the mobs come any faster in the missions. I'm killing as fast as I can. Maybe my ridiculous overcompensating for Mana Regen has something to do with it. I know you'll say it doesn't. But if you took my toons for a spin you would be surprised at how well they retain Mana.
 
I can't make the mobs come any faster in the missions. I'm killing as fast as I can. Maybe my ridiculous overcompensating for Mana Regen has something to do with it. I know you'll say it doesn't. But if you took my toons for a spin you would be surprised at how well they retain Mana.
Are you talking going through one mission and then dropping and medding or are you talking grind?
 
I can't make the mobs come any faster in the missions. I'm killing as fast as I can. Maybe my ridiculous overcompensating for Mana Regen has something to do with it. I know you'll say it doesn't. But if you took my toons for a spin you would be surprised at how well they retain Mana.
@RobRenfro my mages ftp or normal are usually tapped for mana no matter what…you need to nuke, pet swarm, and of many spell line constantly. You also need to learn to pull swarms (3+) mobs per pull so theres always something waiting to be hit and to fully utilize your enc or bard fully and to reduce downtime.

Rgmerc chain pull with ranger ranged is amazing if your tank plugin isn’t handling swarm pulls well. Give it a go you’ll see…this routine/Lua is amazing at reducing downtime and increasing dps output
 
I don't have 3 rezzers in my primary group because I under pull and at least 2 in every other group.
What do rezzers have to do with anything? Modern tanks even with auto as long as they are geared/aad for the content you are in can handle 3+ no mez
 
I have 3 rezzers because I pull hard Louis Roberts hard. I'll sink your battleship then I'm going after the kayaker and your uncle's fishing canoe pulling. So I have 3 toons to save my bacon if I slide off the razor's edge.
 
I've been away for awhile however I recently started playing again. Rather then having external Lua's and macros I integrated things into a LEM alone. I also added in where it will CotH ourselves to wipe agro as for some reason if we are in combat even after summoning pet it was not suspending. This is an early release of the LEM but any feedback is welcome.

Here is code:
Endless Mana LEM
Lua:
local mq = require('mq')

---@return boolean @Returns true if the action should fire, otherwise false.
local function condition()
    local my_class = mq.TLO.Me.Class.ShortName()
    local my_mana = mq.TLO.Me.PctMana()
    local check_paused = mq.TLO.CWTN.Paused()
    local mm_status = mq.TLO.Lua.Script('MMbrute').Status()
    return my_class == 'MAG' and my_mana < 20 and mm_status ~= 'RUNNING' and check_paused == false
end

-----------------------------------------------------------------------
-- Everything below runs inside LEM's action() when the condition is met
-----------------------------------------------------------------------

-- Lightweight logger (self-contained)
local Note = { prefix = 'MonsterMana', loglevel = 'info' }
function Note.Info(fmt, ...) print(('\ag[%s]\ax '..fmt):format(Note.prefix, ...)) end

-- State / config
local workingStates = { Active=true, Cooldown=true, Resting=true }
local MonsterSummoning, MonsterSummoningSpell
local GatherMana, GatherManaSpell
local ReclaimSet, ReclaimItem
local MiscSpellGem = 8 -- using gem 8
local IsMemorizing = false

-- -----------------------------
-- Helpers
-- -----------------------------
local function CheckPlugin(plugin)
    if not mq.TLO.Plugin(plugin)() then
        mq.cmdf('/squelch /plugin %s noauto', plugin)
        Note.Info('\aw%s\ax not detected. Loading…', plugin)
    end
end

-- Simple movement check: only your avatar’s motion.
local function IsMoving()
    return mq.TLO.Me.Moving() or ((mq.TLO.Me.Speed() or 0) > 0)
end

-- Wait until we’ve been NOT moving for a continuous window (ms). No attempt limit.
local function WaitStill(min_ms)
    min_ms = min_ms or 400
    local stillStart = nil
    while true do
        if IsMoving() then
            stillStart = nil
        else
            stillStart = stillStart or mq.gettime()
            if (mq.gettime() - stillStart) >= min_ms then return true end
        end
        mq.delay(50)
    end
end

-- Robust “am I in combat?” check
local function InCombat()
    local cs = tostring(mq.TLO.Me.CombatState() or '')
    if cs ~= '' and cs:upper() == 'COMBAT' then return true end
    if mq.TLO.Me.Combat and mq.TLO.Me.Combat() then return true end
    return false
end

local function ChooseAbility(set)
    local chosenSpell, highestLevel = nil, 0
    for _, name in ipairs(set) do
        local s = mq.TLO.Spell(name)
        local lvl, rank = s.Level(), s.RankName()
        if rank and mq.TLO.Me.Book(rank)() and lvl > highestLevel then
            chosenSpell = (mq.TLO.Me.SpellRankCap() > 1) and s.RankName() or s.BaseName()
            highestLevel = lvl
        end
    end
    return chosenSpell
end

local function ChooseItem(set)
    for _, name in ipairs(set) do
        if mq.TLO.FindItemCount(name)() > 0 then return name end
    end
end

-- Spellbook events (registered inside action())
local function Event_BeginMemorizing(_, _) IsMemorizing = true end
local function Event_EndMemorizing(_, _) IsMemorizing = false end

-- Ensure spell is in a specific gem (blocking, no attempt limit). Only starts when stationary.
local function EnsureSpellInGem(spellToMem, gem)
    gem = gem or MiscSpellGem
    while true do
        if mq.TLO.Me.Gem(spellToMem)() == gem then return gem end
        local rn = mq.TLO.Spell(spellToMem).RankName()
        if not rn or not mq.TLO.Me.Book(rn)() then
            Note.Info('Cannot memorize (not in book): %s', tostring(spellToMem))
            return
        end
        if not mq.TLO.Me.Gem(gem)() and gem ~= MiscSpellGem then gem = MiscSpellGem end
        WaitStill(600)
        Note.Info('\agMemming\ax "%s" into gem %d', rn, gem)
        mq.cmdf('/memspell %d "%s"', gem, rn)
        mq.delay(2000, function() return IsMemorizing or mq.TLO.Me.Gem(gem).Name() == rn end)
        mq.delay(10000, function() return mq.TLO.Me.Gem(gem).Name() == rn or not IsMemorizing end)
        if mq.TLO.Me.Gem(gem).Name() == rn then return gem end
    end
end

-- Pet proximity helpers (with optional timeout to prevent hangs)
local function PetNear(maxDist) return (mq.TLO.Me.Pet.Distance() or 9999) <= (maxDist or 12) end
local function WaitPetNear(maxDist, timeout_ms)
    maxDist = maxDist or 12
    local start = mq.gettime()
    while true do
        if (mq.TLO.Me.Pet.ID() or 0) == 0 then return false end
        if PetNear(maxDist) then return true end
        if timeout_ms and (mq.gettime() - start) >= timeout_ms then return PetNear(maxDist) end
        mq.delay(50)
    end
end

-- Suspend pet with full sequence every pass.
-- Now: only use CoTH AA (7050) if we are IN COMBAT.
local function SuspendPrimaryPet_Blocking()
    local origID = mq.TLO.Me.Pet.ID() or 0
    if origID == 0 then return true end
    Note.Info('Storing Pet (ID %s)', tostring(origID))

    while (mq.TLO.Me.Pet.ID() or 0) > 0 do
        -- Full sequence: ghold -> spellhold -> hold/back -> Summon Companion (1215) -> (CoTH if IN COMBAT) -> suspend
        WaitStill(400)
        mq.cmd('/pet ghold on')    ; mq.delay(300)
        mq.cmd('/pet spellhold on'); mq.delay(300)
        mq.cmd('/pet back')        ; mq.delay(300)

        -- Summon Companion RIGHT BEFORE suspending, if ready (don’t block for CD)
        if mq.TLO.Me.AltAbilityReady(1215)() or mq.TLO.Me.AltAbilityReady('Summon Companion')() then
            WaitStill(300)
            mq.cmd('/alt act 1215')
            mq.delay(3500, function() return not mq.TLO.Me.Casting.ID() end)
            WaitPetNear(12, 3000)
        end

        -- NEW: Only do CoTH if we are actually in combat
        if InCombat() and mq.TLO.Me.AltAbilityReady(7050)() then
            WaitStill(300)
            mq.cmdf('/target id %d', mq.TLO.Me.ID() or 0)
            mq.delay(200)
            Note.Info('Using CoTH AA to wipe personal aggro (in combat).')
            mq.cmd('/alt act 7050')
            mq.delay(3500, function() return not mq.TLO.Me.Casting.ID() end)
        end

        -- Attempt to suspend
        WaitStill(400)
        if mq.TLO.Me.AltAbilityReady(176)() or mq.TLO.Me.AltAbilityReady('Suspend Minion')() then
            Note.Info('Suspending Minion…')
            mq.cmd('/alt act 176')
            mq.delay(500)
            mq.delay(3000, function() return not mq.TLO.Me.Casting.ID() end)
        end

        -- Success?
        if (mq.TLO.Me.Pet.ID() or 0) == 0 then
            Note.Info('Pet suspended.')
            return true
        end

        -- Redo the entire sequence until success.
        mq.delay(200)
    end

    return true
end

-- Core mana loop: summon monster pet (gem 8) & reclaim until 95% mana.
local function ReclaimMana()
    Note.Info('Mana Loop Started')
    mq.cmd('/squelch /beepontells off')

    while (mq.TLO.Me.PctMana() or 100) < 95 do
        if mq.TLO.Cursor.ID() then
            mq.cmd('/autoinventory')
            mq.delay(2000)
            mq.cmd('/autoinventory')
        end

        if (mq.TLO.Me.PctMana() or 100) < 8 and mq.TLO.Me.SpellReady(GatherManaSpell)() then
            WaitStill(400)
            mq.cmdf('/cast "%s"', GatherManaSpell)
            mq.delay(20000, function() return mq.TLO.Me.Casting.ID() == nil end)

        elseif (mq.TLO.Me.CurrentMana() or 0) < (mq.TLO.Spell(MonsterSummoningSpell).Mana() or 0) then
            if mq.TLO.Me.Standing() and not mq.TLO.Me.Casting.ID() then mq.TLO.Me.Sit() end
            mq.delay(6050)

        else
            if mq.TLO.Me.Sitting() then mq.TLO.Me.Stand() end
            mq.delay(250)

            -- Ensure spell in gem 8
            local actualGem = EnsureSpellInGem(MonsterSummoningSpell, MiscSpellGem)
            if not actualGem then
                Note.Info('Could not load Monster Summoning into gem %d; exiting mana loop.', MiscSpellGem)
                break
            end

            -- Cast Monster Summoning
            WaitStill(400)
            if mq.TLO.Me.SpellReady(MonsterSummoningSpell)() then
                mq.cmdf('/cast %d', actualGem)
            end
            mq.delay(7000, function() return not mq.TLO.Me.Casting.ID() end)
            mq.delay(300)

            -- Reclaim immediately if a pet is up
            if (mq.TLO.Me.Pet.ID() or 0) > 0 and ReclaimItem then
                WaitStill(200)
                mq.cmdf('/useitem %s', ReclaimItem)
                mq.delay(500)
            end
        end

        mq.delay(50)
    end

    Note.Info('Mana Loop Ended')
    -- final cleanup: if temp pet still up, reclaim until gone
    while (mq.TLO.Me.Pet.ID() or 0) > 0 do
        mq.cmdf('/useitem %s', ReclaimItem)
        mq.delay(500)
    end
end

-- Init spells/items
local function Init()
    CheckPlugin('MQ2XAssist')
    CheckPlugin('MQ2AdvPath')
    CheckPlugin('MQ2MoveUtils')
    CheckPlugin('MQ2Boxr')

    MonsterSummoning = {
        "Monster Summoning XV",
        "Monster Summoning XIV",
        "Monster Summoning XIII",
    }
    MonsterSummoningSpell = ChooseAbility(MonsterSummoning)
    if not MonsterSummoningSpell then
        Note.Info('A monster summoning spell is not available')
        return false
    end

    -- Updated Gather line (includes level 125)
    GatherMana = {
        "Gather Zeal",
        "Gather Vigor",
        "Gather Potency",
    }
    GatherManaSpell = ChooseAbility(GatherMana)
    if not GatherManaSpell then
        Note.Info('A gather mana spell is not available')
        return false
    end

    ReclaimSet = {
        "Staff of Elemental Mastery: Earth",
        "Staff of Elemental Mastery: Fire",
        "Staff of Elemental Mastery: Air",
        "Staff of Elemental Mastery: Water",
        "Broom of Trilon",
        "Ancient Torch of Alna",
        "Gemmed Gloves of Guile",
        "Gloves of Dark Summoning",
        "Shovel of Ponz",
        "Stein of Ulissa",
        "Torch of Alna",
    }
    ReclaimItem = ChooseItem(ReclaimSet)
    if not ReclaimItem then
        Note.Info('No reclaim item found in inventory')
        return false
    end

    return true
end

-- Main routine (merged into LEM action)
local function RunMonsterMana()
    if mq.TLO.Me.Class.ShortName() ~= 'MAG' then
        Note.Info('MonsterMana only works for Mage characters')
        return false
    end
    if (mq.TLO.Me.PctMana() or 100) > 95 then
        Note.Info('Mana is nearly full; nothing to do')
        return false
    end
    if not Init() then
        Note.Info('Initialization unsuccessful')
        return false
    end

    mq.cmd('/squelch /docommand /boxr pause')
    mq.delay(300)
    mq.cmd('/squelch /attack off')

    -- clear cursor
    while mq.TLO.Cursor.ID() do
        mq.cmd('/autoinventory')
        mq.delay(500)
    end

    -- If we already have a main pet, suspend it FIRST (blocking)
    if (mq.TLO.Me.Pet.ID() or 0) > 0 then
        Note.Info('Primary mana method (with pet)')
        if not SuspendPrimaryPet_Blocking() then
            Note.Info('Unable to suspend pet safely; aborting.')
            mq.cmd('/squelch /docommand /boxr unpause')
            return false
        end
    else
        -- No-pet fallback: build to 8% with Gather or sitting
        Note.Info('Primary mana method (no pet)')
        while (mq.TLO.Me.PctMana() or 0) < 8 do
            local rankName = mq.TLO.Spell(GatherManaSpell).RankName()
            if mq.TLO.Me.SpellReady(rankName)() then
                WaitStill(400)
                mq.cmdf('/cast "%s"', rankName)
                mq.delay(20000, function() return not mq.TLO.Me.Casting.ID() end)
            elseif workingStates[mq.TLO.Me.CombatState() or ''] then
                if mq.TLO.Me.Standing() and not mq.TLO.Me.Casting.ID() then mq.TLO.Me.Sit() end
                mq.delay(6050)
            end
            mq.delay(150)
        end
    end

    -- Run mana loop (summon/reclaim)
    ReclaimMana()

    -- Try to restore main pet (unsuspend). Loop until a non-Warrior pet (i.e., your real elemental) returns.
    Note.Info('Restoring main pet (unsuspending)')
    while (mq.TLO.Me.Pet.ID() or 0) == 0 do
        WaitStill(400)
        mq.cmd('/alt act 176')
        mq.delay(6500, function() return not mq.TLO.Me.Casting.ID() end)
        mq.delay(300)
    end
    -- If a Monster Summoning warrior pet popped instead, reclaim and try again.
    while (mq.TLO.Me.Pet.Class.Name() or '') == 'Warrior' do
        if ReclaimItem then
            mq.cmdf('/useitem %s', ReclaimItem)
            mq.delay(500)
        else
            break
        end
        while (mq.TLO.Me.Pet.ID() or 0) == 0 do
            WaitStill(400)
            mq.cmd('/alt act 176')
            mq.delay(6500, function() return not mq.TLO.Me.Casting.ID() end)
            mq.delay(300)
        end
    end

    mq.delay(300)
    mq.cmd('/pet hold')
    mq.delay(300)
    mq.cmd('/squelch /docommand /boxr unpause')
    mq.delay(300)
    Note.Info('Mana routine complete. Mage mana now: \ag%s', tostring(mq.TLO.Me.PctMana()))
    mq.cmd('/squelch /beepontells on')
    return true
end

local function action()
    -- Register spellbook events (LEM-safe)
    mq.event('BeginMemorizing', "#*#Beginning to memorize #1#...#*#", Event_BeginMemorizing)
    mq.event('FinishMemorizing', "#*#You have finished memorizing #1##*#", Event_EndMemorizing)
    mq.event('AbortMemorizing', "#*#Aborting memorization of spell.#*#", Event_EndMemorizing)

    local ok, err = pcall(RunMonsterMana)
    if not ok then Note.Info('\arError:\ax %s', tostring(err)) end
end

return {condfunc=condition, actionfunc=action}

LEM import code:
cmV0dXJuIHsKIFsibmFtZSJdID0gIk1hZ2UgLSBFbmRsZXNzIE1hbmEiLAogWyJsb2FkIl0gPSB7CiAgWyJhbHdheXMiXSA9IGZhbHNlLAogIFsiem9uZSJdID0gIiIsCiAgWyJjbGFzcyJdID0gIiIsCiB9LAogWyJjb2RlIl0gPSAiYkc5allXd2diWEVnUFNCeVpYRjFhWEpsS0NkdGNTY3BDZ290TFMxQWNtVjBkWEp1SUdKdmIyeGxZVzRnUUZKbGRIVnlibk1nZEhKMVpTQnBaaUIwYUdVZ1lXTjBhVzl1SUhOb2IzVnNaQ0JtYVhKbExDQnZkR2hsY25kcGMyVWdabUZzYzJVdUNteHZZMkZzSUdaMWJtTjBhVzl1SUdOdmJtUnBkR2x2YmlncENpQWdJQ0JzYjJOaGJDQnRlVjlqYkdGemN5QTlJRzF4TGxSTVR5NU5aUzVEYkdGemN5NVRhRzl5ZEU1aGJXVW9LUW9nSUNBZ2JHOWpZV3dnYlhsZmJXRnVZU0E5SUcxeExsUk1UeTVOWlM1UVkzUk5ZVzVoS0NrS0lDQWdJR3h2WTJGc0lHTm9aV05yWDNCaGRYTmxaQ0E5SUcxeExsUk1UeTVEVjFST0xsQmhkWE5sWkNncENpQWdJQ0JzYjJOaGJDQnRiVjl6ZEdGMGRYTWdQU0J0Y1M1VVRFOHVUSFZoTGxOamNtbHdkQ2duVFUxaWNuVjBaU2NwTGxOMFlYUjFjeWdwQ2lBZ0lDQnlaWFIxY200Z2JYbGZZMnhoYzNNZ1BUMGdKMDFCUnljZ1lXNWtJRzE1WDIxaGJtRWdQQ0F5TUNCaGJtUWdiVzFmYzNSaGRIVnpJSDQ5SUNkU1ZVNU9TVTVISnlCaGJtUWdZMmhsWTJ0ZmNHRjFjMlZrSUQwOUlHWmhiSE5sQ21WdVpBb0tMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMEtMUzBnUlhabGNubDBhR2x1WnlCaVpXeHZkeUJ5ZFc1eklHbHVjMmxrWlNCTVJVMG5jeUJoWTNScGIyNG9LU0IzYUdWdUlIUm9aU0JqYjI1a2FYUnBiMjRnYVhNZ2JXVjBDaTB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRDZ290TFNCTWFXZG9kSGRsYVdkb2RDQnNiMmRuWlhJZ0tITmxiR1l0WTI5dWRHRnBibVZrS1Fwc2IyTmhiQ0JPYjNSbElEMGdleUJ3Y21WbWFYZ2dQU0FuVFc5dWMzUmxjazFoYm1FbkxDQnNiMmRzWlhabGJDQTlJQ2RwYm1adkp5QjlDbVoxYm1OMGFXOXVJRTV2ZEdVdVNXNW1ieWhtYlhRc0lDNHVMaWtnY0hKcGJuUW9LQ2RjWVdkYkpYTmRYR0Y0SUNjdUxtWnRkQ2s2Wm05eWJXRjBLRTV2ZEdVdWNISmxabWw0TENBdUxpNHBLU0JsYm1RS0NpMHRJRk4wWVhSbElDOGdZMjl1Wm1sbkNteHZZMkZzSUhkdmNtdHBibWRUZEdGMFpYTWdQU0I3SUVGamRHbDJaVDEwY25WbExDQkRiMjlzWkc5M2JqMTBjblZsTENCU1pYTjBhVzVuUFhSeWRXVWdmUXBzYjJOaGJDQk5iMjV6ZEdWeVUzVnRiVzl1YVc1bkxDQk5iMjV6ZEdWeVUzVnRiVzl1YVc1blUzQmxiR3dLYkc5allXd2dSMkYwYUdWeVRXRnVZU3dnUjJGMGFHVnlUV0Z1WVZOd1pXeHNDbXh2WTJGc0lGSmxZMnhoYVcxVFpYUXNJRkpsWTJ4aGFXMUpkR1Z0Q214dlkyRnNJRTFwYzJOVGNHVnNiRWRsYlNBOUlEZ2dMUzBnZFhOcGJtY2daMlZ0SURnS2JHOWpZV3dnU1hOTlpXMXZjbWw2YVc1bklEMGdabUZzYzJVS0NpMHRJQzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0Q2kwdElFaGxiSEJsY25NS0xTMGdMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzBLYkc5allXd2dablZ1WTNScGIyNGdRMmhsWTJ0UWJIVm5hVzRvY0d4MVoybHVLUW9nSUNBZ2FXWWdibTkwSUcxeExsUk1UeTVRYkhWbmFXNG9jR3gxWjJsdUtTZ3BJSFJvWlc0S0lDQWdJQ0FnSUNCdGNTNWpiV1JtS0NjdmMzRjFaV3hqYUNBdmNHeDFaMmx1SUNWeklHNXZZWFYwYnljc0lIQnNkV2RwYmlrS0lDQWdJQ0FnSUNCT2IzUmxMa2x1Wm04b0oxeGhkeVZ6WEdGNElHNXZkQ0JrWlhSbFkzUmxaQzRnVEc5aFpHbHVaK0tBcGljc0lIQnNkV2RwYmlrS0lDQWdJR1Z1WkFwbGJtUUtDaTB0SUZOcGJYQnNaU0J0YjNabGJXVnVkQ0JqYUdWamF6b2diMjVzZVNCNWIzVnlJR0YyWVhSaGN1S0FtWE1nYlc5MGFXOXVMZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQkpjMDF2ZG1sdVp5Z3BDaUFnSUNCeVpYUjFjbTRnYlhFdVZFeFBMazFsTGsxdmRtbHVaeWdwSUc5eUlDZ29iWEV1VkV4UExrMWxMbE53WldWa0tDa2diM0lnTUNrZ1BpQXdLUXBsYm1RS0NpMHRJRmRoYVhRZ2RXNTBhV3dnZDJYaWdKbDJaU0JpWldWdUlFNVBWQ0J0YjNacGJtY2dabTl5SUdFZ1kyOXVkR2x1ZFc5MWN5QjNhVzVrYjNjZ0tHMXpLUzRnVG04Z1lYUjBaVzF3ZENCc2FXMXBkQzRLYkc5allXd2dablZ1WTNScGIyNGdWMkZwZEZOMGFXeHNLRzFwYmw5dGN5a0tJQ0FnSUcxcGJsOXRjeUE5SUcxcGJsOXRjeUJ2Y2lBME1EQUtJQ0FnSUd4dlkyRnNJSE4wYVd4c1UzUmhjblFnUFNCdWFXd0tJQ0FnSUhkb2FXeGxJSFJ5ZFdVZ1pHOEtJQ0FnSUNBZ0lDQnBaaUJKYzAxdmRtbHVaeWdwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnYzNScGJHeFRkR0Z5ZENBOUlHNXBiQW9nSUNBZ0lDQWdJR1ZzYzJVS0lDQWdJQ0FnSUNBZ0lDQWdjM1JwYkd4VGRHRnlkQ0E5SUhOMGFXeHNVM1JoY25RZ2IzSWdiWEV1WjJWMGRHbHRaU2dwQ2lBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2h0Y1M1blpYUjBhVzFsS0NrZ0xTQnpkR2xzYkZOMFlYSjBLU0ErUFNCdGFXNWZiWE1nZEdobGJpQnlaWFIxY200Z2RISjFaU0JsYm1RS0lDQWdJQ0FnSUNCbGJtUUtJQ0FnSUNBZ0lDQnRjUzVrWld4aGVTZzFNQ2tLSUNBZ0lHVnVaQXBsYm1RS0NpMHRJRkp2WW5WemRDRGlnSnhoYlNCSklHbHVJR052YldKaGREL2lnSjBnWTJobFkyc0tiRzlqWVd3Z1puVnVZM1JwYjI0Z1NXNURiMjFpWVhRb0tRb2dJQ0FnYkc5allXd2dZM01nUFNCMGIzTjBjbWx1WnlodGNTNVVURTh1VFdVdVEyOXRZbUYwVTNSaGRHVW9LU0J2Y2lBbkp5a0tJQ0FnSUdsbUlHTnpJSDQ5SUNjbklHRnVaQ0JqY3pwMWNIQmxjaWdwSUQwOUlDZERUMDFDUVZRbklIUm9aVzRnY21WMGRYSnVJSFJ5ZFdVZ1pXNWtDaUFnSUNCcFppQnRjUzVVVEU4dVRXVXVRMjl0WW1GMElHRnVaQ0J0Y1M1VVRFOHVUV1V1UTI5dFltRjBLQ2tnZEdobGJpQnlaWFIxY200Z2RISjFaU0JsYm1RS0lDQWdJSEpsZEhWeWJpQm1ZV3h6WlFwbGJtUUtDbXh2WTJGc0lHWjFibU4wYVc5dUlFTm9iMjl6WlVGaWFXeHBkSGtvYzJWMEtRb2dJQ0FnYkc5allXd2dZMmh2YzJWdVUzQmxiR3dzSUdocFoyaGxjM1JNWlhabGJDQTlJRzVwYkN3Z01Bb2dJQ0FnWm05eUlGOHNJRzVoYldVZ2FXNGdhWEJoYVhKektITmxkQ2tnWkc4S0lDQWdJQ0FnSUNCc2IyTmhiQ0J6SUQwZ2JYRXVWRXhQTGxOd1pXeHNLRzVoYldVcENpQWdJQ0FnSUNBZ2JHOWpZV3dnYkhac0xDQnlZVzVySUQwZ2N5NU1aWFpsYkNncExDQnpMbEpoYm10T1lXMWxLQ2tLSUNBZ0lDQWdJQ0JwWmlCeVlXNXJJR0Z1WkNCdGNTNVVURTh1VFdVdVFtOXZheWh5WVc1cktTZ3BJR0Z1WkNCc2Rtd2dQaUJvYVdkb1pYTjBUR1YyWld3Z2RHaGxiZ29nSUNBZ0lDQWdJQ0FnSUNCamFHOXpaVzVUY0dWc2JDQTlJQ2h0Y1M1VVRFOHVUV1V1VTNCbGJHeFNZVzVyUTJGd0tDa2dQaUF4S1NCaGJtUWdjeTVTWVc1clRtRnRaU2dwSUc5eUlITXVRbUZ6WlU1aGJXVW9LUW9nSUNBZ0lDQWdJQ0FnSUNCb2FXZG9aWE4wVEdWMlpXd2dQU0JzZG13S0lDQWdJQ0FnSUNCbGJtUUtJQ0FnSUdWdVpBb2dJQ0FnY21WMGRYSnVJR05vYjNObGJsTndaV3hzQ21WdVpBb0tiRzlqWVd3Z1puVnVZM1JwYjI0Z1EyaHZiM05sU1hSbGJTaHpaWFFwQ2lBZ0lDQm1iM0lnWHl3Z2JtRnRaU0JwYmlCcGNHRnBjbk1vYzJWMEtTQmtid29nSUNBZ0lDQWdJR2xtSUcxeExsUk1UeTVHYVc1a1NYUmxiVU52ZFc1MEtHNWhiV1VwS0NrZ1BpQXdJSFJvWlc0Z2NtVjBkWEp1SUc1aGJXVWdaVzVrQ2lBZ0lDQmxibVFLWlc1a0Nnb3RMU0JUY0dWc2JHSnZiMnNnWlhabGJuUnpJQ2h5WldkcGMzUmxjbVZrSUdsdWMybGtaU0JoWTNScGIyNG9LU2tLYkc5allXd2dablZ1WTNScGIyNGdSWFpsYm5SZlFtVm5hVzVOWlcxdmNtbDZhVzVuS0Y4c0lGOHBJRWx6VFdWdGIzSnBlbWx1WnlBOUlIUnlkV1VnWlc1a0NteHZZMkZzSUdaMWJtTjBhVzl1SUVWMlpXNTBYMFZ1WkUxbGJXOXlhWHBwYm1jb1h5d2dYeWtnU1hOTlpXMXZjbWw2YVc1bklEMGdabUZzYzJVZ1pXNWtDZ290TFNCRmJuTjFjbVVnYzNCbGJHd2dhWE1nYVc0Z1lTQnpjR1ZqYVdacFl5Qm5aVzBnS0dKc2IyTnJhVzVuTENCdWJ5QmhkSFJsYlhCMElHeHBiV2wwS1M0Z1QyNXNlU0J6ZEdGeWRITWdkMmhsYmlCemRHRjBhVzl1WVhKNUxncHNiMk5oYkNCbWRXNWpkR2x2YmlCRmJuTjFjbVZUY0dWc2JFbHVSMlZ0S0hOd1pXeHNWRzlOWlcwc0lHZGxiU2tLSUNBZ0lHZGxiU0E5SUdkbGJTQnZjaUJOYVhOalUzQmxiR3hIWlcwS0lDQWdJSGRvYVd4bElIUnlkV1VnWkc4S0lDQWdJQ0FnSUNCcFppQnRjUzVVVEU4dVRXVXVSMlZ0S0hOd1pXeHNWRzlOWlcwcEtDa2dQVDBnWjJWdElIUm9aVzRnY21WMGRYSnVJR2RsYlNCbGJtUUtJQ0FnSUNBZ0lDQnNiMk5oYkNCeWJpQTlJRzF4TGxSTVR5NVRjR1ZzYkNoemNHVnNiRlJ2VFdWdEtTNVNZVzVyVG1GdFpTZ3BDaUFnSUNBZ0lDQWdhV1lnYm05MElISnVJRzl5SUc1dmRDQnRjUzVVVEU4dVRXVXVRbTl2YXloeWJpa29LU0IwYUdWdUNpQWdJQ0FnSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduUTJGdWJtOTBJRzFsYlc5eWFYcGxJQ2h1YjNRZ2FXNGdZbTl2YXlrNklDVnpKeXdnZEc5emRISnBibWNvYzNCbGJHeFViMDFsYlNrcENpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJnb2dJQ0FnSUNBZ0lHVnVaQW9nSUNBZ0lDQWdJR2xtSUc1dmRDQnRjUzVVVEU4dVRXVXVSMlZ0S0dkbGJTa29LU0JoYm1RZ1oyVnRJSDQ5SUUxcGMyTlRjR1ZzYkVkbGJTQjBhR1Z1SUdkbGJTQTlJRTFwYzJOVGNHVnNiRWRsYlNCbGJtUUtJQ0FnSUNBZ0lDQlhZV2wwVTNScGJHd29OakF3S1FvZ0lDQWdJQ0FnSUU1dmRHVXVTVzVtYnlnblhHRm5UV1Z0YldsdVoxeGhlQ0FpSlhNaUlHbHVkRzhnWjJWdElDVmtKeXdnY200c0lHZGxiU2tLSUNBZ0lDQWdJQ0J0Y1M1amJXUm1LQ2N2YldWdGMzQmxiR3dnSldRZ0lpVnpJaWNzSUdkbGJTd2djbTRwQ2lBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTWpBd01Dd2dablZ1WTNScGIyNG9LU0J5WlhSMWNtNGdTWE5OWlcxdmNtbDZhVzVuSUc5eUlHMXhMbFJNVHk1TlpTNUhaVzBvWjJWdEtTNU9ZVzFsS0NrZ1BUMGdjbTRnWlc1a0tRb2dJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtERXdNREF3TENCbWRXNWpkR2x2YmlncElISmxkSFZ5YmlCdGNTNVVURTh1VFdVdVIyVnRLR2RsYlNrdVRtRnRaU2dwSUQwOUlISnVJRzl5SUc1dmRDQkpjMDFsYlc5eWFYcHBibWNnWlc1a0tRb2dJQ0FnSUNBZ0lHbG1JRzF4TGxSTVR5NU5aUzVIWlcwb1oyVnRLUzVPWVcxbEtDa2dQVDBnY200Z2RHaGxiaUJ5WlhSMWNtNGdaMlZ0SUdWdVpBb2dJQ0FnWlc1a0NtVnVaQW9LTFMwZ1VHVjBJSEJ5YjNocGJXbDBlU0JvWld4d1pYSnpJQ2gzYVhSb0lHOXdkR2x2Ym1Gc0lIUnBiV1Z2ZFhRZ2RHOGdjSEpsZG1WdWRDQm9ZVzVuY3lrS2JHOWpZV3dnWm5WdVkzUnBiMjRnVUdWMFRtVmhjaWh0WVhoRWFYTjBLU0J5WlhSMWNtNGdLRzF4TGxSTVR5NU5aUzVRWlhRdVJHbHpkR0Z1WTJVb0tTQnZjaUE1T1RrNUtTQThQU0FvYldGNFJHbHpkQ0J2Y2lBeE1pa2daVzVrQ214dlkyRnNJR1oxYm1OMGFXOXVJRmRoYVhSUVpYUk9aV0Z5S0cxaGVFUnBjM1FzSUhScGJXVnZkWFJmYlhNcENpQWdJQ0J0WVhoRWFYTjBJRDBnYldGNFJHbHpkQ0J2Y2lBeE1nb2dJQ0FnYkc5allXd2djM1JoY25RZ1BTQnRjUzVuWlhSMGFXMWxLQ2tLSUNBZ0lIZG9hV3hsSUhSeWRXVWdaRzhLSUNBZ0lDQWdJQ0JwWmlBb2JYRXVWRXhQTGsxbExsQmxkQzVKUkNncElHOXlJREFwSUQwOUlEQWdkR2hsYmlCeVpYUjFjbTRnWm1Gc2MyVWdaVzVrQ2lBZ0lDQWdJQ0FnYVdZZ1VHVjBUbVZoY2lodFlYaEVhWE4wS1NCMGFHVnVJSEpsZEhWeWJpQjBjblZsSUdWdVpBb2dJQ0FnSUNBZ0lHbG1JSFJwYldWdmRYUmZiWE1nWVc1a0lDaHRjUzVuWlhSMGFXMWxLQ2tnTFNCemRHRnlkQ2tnUGowZ2RHbHRaVzkxZEY5dGN5QjBhR1Z1SUhKbGRIVnliaUJRWlhST1pXRnlLRzFoZUVScGMzUXBJR1Z1WkFvZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RVd0tRb2dJQ0FnWlc1a0NtVnVaQW9LTFMwZ1UzVnpjR1Z1WkNCd1pYUWdkMmwwYUNCbWRXeHNJSE5sY1hWbGJtTmxJR1YyWlhKNUlIQmhjM011Q2kwdElFNXZkem9nYjI1c2VTQjFjMlVnUTI5VVNDQkJRU0FvTnpBMU1Da2dhV1lnZDJVZ1lYSmxJRWxPSUVOUFRVSkJWQzRLYkc5allXd2dablZ1WTNScGIyNGdVM1Z6Y0dWdVpGQnlhVzFoY25sUVpYUmZRbXh2WTJ0cGJtY29LUW9nSUNBZ2JHOWpZV3dnYjNKcFowbEVJRDBnYlhFdVZFeFBMazFsTGxCbGRDNUpSQ2dwSUc5eUlEQUtJQ0FnSUdsbUlHOXlhV2RKUkNBOVBTQXdJSFJvWlc0Z2NtVjBkWEp1SUhSeWRXVWdaVzVrQ2lBZ0lDQk9iM1JsTGtsdVptOG9KMU4wYjNKcGJtY2dVR1YwSUNoSlJDQWxjeWtuTENCMGIzTjBjbWx1WnlodmNtbG5TVVFwS1FvS0lDQWdJSGRvYVd4bElDaHRjUzVVVEU4dVRXVXVVR1YwTGtsRUtDa2diM0lnTUNrZ1BpQXdJR1J2Q2lBZ0lDQWdJQ0FnTFMwZ1JuVnNiQ0J6WlhGMVpXNWpaVG9nWjJodmJHUWdMVDRnYzNCbGJHeG9iMnhrSUMwK0lHaHZiR1F2WW1GamF5QXRQaUJUZFcxdGIyNGdRMjl0Y0dGdWFXOXVJQ2d4TWpFMUtTQXRQaUFvUTI5VVNDQnBaaUJKVGlCRFQwMUNRVlFwSUMwK0lITjFjM0JsYm1RS0lDQWdJQ0FnSUNCWFlXbDBVM1JwYkd3b05EQXdLUW9nSUNBZ0lDQWdJRzF4TG1OdFpDZ25MM0JsZENCbmFHOXNaQ0J2YmljcElDQWdJRHNnYlhFdVpHVnNZWGtvTXpBd0tRb2dJQ0FnSUNBZ0lHMXhMbU50WkNnbkwzQmxkQ0J6Y0dWc2JHaHZiR1FnYjI0bktUc2diWEV1WkdWc1lYa29NekF3S1FvZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDNCbGRDQmlZV05ySnlrZ0lDQWdJQ0FnSURzZ2JYRXVaR1ZzWVhrb016QXdLUW9LSUNBZ0lDQWdJQ0F0TFNCVGRXMXRiMjRnUTI5dGNHRnVhVzl1SUZKSlIwaFVJRUpGUms5U1JTQnpkWE53Wlc1a2FXNW5MQ0JwWmlCeVpXRmtlU0FvWkc5dTRvQ1pkQ0JpYkc5amF5Qm1iM0lnUTBRcENpQWdJQ0FnSUNBZ2FXWWdiWEV1VkV4UExrMWxMa0ZzZEVGaWFXeHBkSGxTWldGa2VTZ3hNakUxS1NncElHOXlJRzF4TGxSTVR5NU5aUzVCYkhSQlltbHNhWFI1VW1WaFpIa29KMU4xYlcxdmJpQkRiMjF3WVc1cGIyNG5LU2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnVjJGcGRGTjBhV3hzS0RNd01Da0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVkyMWtLQ2N2WVd4MElHRmpkQ0F4TWpFMUp5a0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTXpVd01Dd2dablZ1WTNScGIyNG9LU0J5WlhSMWNtNGdibTkwSUcxeExsUk1UeTVOWlM1RFlYTjBhVzVuTGtsRUtDa2daVzVrS1FvZ0lDQWdJQ0FnSUNBZ0lDQlhZV2wwVUdWMFRtVmhjaWd4TWl3Z016QXdNQ2tLSUNBZ0lDQWdJQ0JsYm1RS0NpQWdJQ0FnSUNBZ0xTMGdUa1ZYT2lCUGJteDVJR1J2SUVOdlZFZ2dhV1lnZDJVZ1lYSmxJR0ZqZEhWaGJHeDVJR2x1SUdOdmJXSmhkQW9nSUNBZ0lDQWdJR2xtSUVsdVEyOXRZbUYwS0NrZ1lXNWtJRzF4TGxSTVR5NU5aUzVCYkhSQlltbHNhWFI1VW1WaFpIa29OekExTUNrb0tTQjBhR1Z1Q2lBZ0lDQWdJQ0FnSUNBZ0lGZGhhWFJUZEdsc2JDZ3pNREFwQ2lBZ0lDQWdJQ0FnSUNBZ0lHMXhMbU50WkdZb0p5OTBZWEpuWlhRZ2FXUWdKV1FuTENCdGNTNVVURTh1VFdVdVNVUW9LU0J2Y2lBd0tRb2dJQ0FnSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2d5TURBcENpQWdJQ0FnSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduVlhOcGJtY2dRMjlVU0NCQlFTQjBieUIzYVhCbElIQmxjbk52Ym1Gc0lHRm5aM0p2SUNocGJpQmpiMjFpWVhRcExpY3BDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDJGc2RDQmhZM1FnTnpBMU1DY3BDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RNMU1EQXNJR1oxYm1OMGFXOXVLQ2tnY21WMGRYSnVJRzV2ZENCdGNTNVVURTh1VFdVdVEyRnpkR2x1Wnk1SlJDZ3BJR1Z1WkNrS0lDQWdJQ0FnSUNCbGJtUUtDaUFnSUNBZ0lDQWdMUzBnUVhSMFpXMXdkQ0IwYnlCemRYTndaVzVrQ2lBZ0lDQWdJQ0FnVjJGcGRGTjBhV3hzS0RRd01Da0tJQ0FnSUNBZ0lDQnBaaUJ0Y1M1VVRFOHVUV1V1UVd4MFFXSnBiR2wwZVZKbFlXUjVLREUzTmlrb0tTQnZjaUJ0Y1M1VVRFOHVUV1V1UVd4MFFXSnBiR2wwZVZKbFlXUjVLQ2RUZFhOd1pXNWtJRTFwYm1sdmJpY3BLQ2tnZEdobGJnb2dJQ0FnSUNBZ0lDQWdJQ0JPYjNSbExrbHVabThvSjFOMWMzQmxibVJwYm1jZ1RXbHVhVzl1NG9DbUp5a0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVkyMWtLQ2N2WVd4MElHRmpkQ0F4TnpZbktRb2dJQ0FnSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2cxTURBcENpQWdJQ0FnSUNBZ0lDQWdJRzF4TG1SbGJHRjVLRE13TURBc0lHWjFibU4wYVc5dUtDa2djbVYwZFhKdUlHNXZkQ0J0Y1M1VVRFOHVUV1V1UTJGemRHbHVaeTVKUkNncElHVnVaQ2tLSUNBZ0lDQWdJQ0JsYm1RS0NpQWdJQ0FnSUNBZ0xTMGdVM1ZqWTJWemN6OEtJQ0FnSUNBZ0lDQnBaaUFvYlhFdVZFeFBMazFsTGxCbGRDNUpSQ2dwSUc5eUlEQXBJRDA5SURBZ2RHaGxiZ29nSUNBZ0lDQWdJQ0FnSUNCT2IzUmxMa2x1Wm04b0oxQmxkQ0J6ZFhOd1pXNWtaV1F1SnlrS0lDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdUlIUnlkV1VLSUNBZ0lDQWdJQ0JsYm1RS0NpQWdJQ0FnSUNBZ0xTMGdVbVZrYnlCMGFHVWdaVzUwYVhKbElITmxjWFZsYm1ObElIVnVkR2xzSUhOMVkyTmxjM011Q2lBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTWpBd0tRb2dJQ0FnWlc1a0Nnb2dJQ0FnY21WMGRYSnVJSFJ5ZFdVS1pXNWtDZ290TFNCRGIzSmxJRzFoYm1FZ2JHOXZjRG9nYzNWdGJXOXVJRzF2Ym5OMFpYSWdjR1YwSUNoblpXMGdPQ2tnSmlCeVpXTnNZV2x0SUhWdWRHbHNJRGsxSlNCdFlXNWhMZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQlNaV05zWVdsdFRXRnVZU2dwQ2lBZ0lDQk9iM1JsTGtsdVptOG9KMDFoYm1FZ1RHOXZjQ0JUZEdGeWRHVmtKeWtLSUNBZ0lHMXhMbU50WkNnbkwzTnhkV1ZzWTJnZ0wySmxaWEJ2Ym5SbGJHeHpJRzltWmljcENnb2dJQ0FnZDJocGJHVWdLRzF4TGxSTVR5NU5aUzVRWTNSTllXNWhLQ2tnYjNJZ01UQXdLU0E4SURrMUlHUnZDaUFnSUNBZ0lDQWdhV1lnYlhFdVZFeFBMa04xY25OdmNpNUpSQ2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVkyMWtLQ2N2WVhWMGIybHVkbVZ1ZEc5eWVTY3BDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RJd01EQXBDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDJGMWRHOXBiblpsYm5SdmNua25LUW9nSUNBZ0lDQWdJR1Z1WkFvS0lDQWdJQ0FnSUNCcFppQW9iWEV1VkV4UExrMWxMbEJqZEUxaGJtRW9LU0J2Y2lBeE1EQXBJRHdnT0NCaGJtUWdiWEV1VkV4UExrMWxMbE53Wld4c1VtVmhaSGtvUjJGMGFHVnlUV0Z1WVZOd1pXeHNLU2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnVjJGcGRGTjBhV3hzS0RRd01Da0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVkyMWtaaWduTDJOaGMzUWdJaVZ6SWljc0lFZGhkR2hsY2sxaGJtRlRjR1ZzYkNrS0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WkdWc1lYa29NakF3TURBc0lHWjFibU4wYVc5dUtDa2djbVYwZFhKdUlHMXhMbFJNVHk1TlpTNURZWE4wYVc1bkxrbEVLQ2tnUFQwZ2JtbHNJR1Z1WkNrS0NpQWdJQ0FnSUNBZ1pXeHpaV2xtSUNodGNTNVVURTh1VFdVdVEzVnljbVZ1ZEUxaGJtRW9LU0J2Y2lBd0tTQThJQ2h0Y1M1VVRFOHVVM0JsYkd3b1RXOXVjM1JsY2xOMWJXMXZibWx1WjFOd1pXeHNLUzVOWVc1aEtDa2diM0lnTUNrZ2RHaGxiZ29nSUNBZ0lDQWdJQ0FnSUNCcFppQnRjUzVVVEU4dVRXVXVVM1JoYm1ScGJtY29LU0JoYm1RZ2JtOTBJRzF4TGxSTVR5NU5aUzVEWVhOMGFXNW5Ma2xFS0NrZ2RHaGxiaUJ0Y1M1VVRFOHVUV1V1VTJsMEtDa2daVzVrQ2lBZ0lDQWdJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEWXdOVEFwQ2dvZ0lDQWdJQ0FnSUdWc2MyVUtJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ2JYRXVWRXhQTGsxbExsTnBkSFJwYm1jb0tTQjBhR1Z1SUcxeExsUk1UeTVOWlM1VGRHRnVaQ2dwSUdWdVpBb2dJQ0FnSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2d5TlRBcENnb2dJQ0FnSUNBZ0lDQWdJQ0F0TFNCRmJuTjFjbVVnYzNCbGJHd2dhVzRnWjJWdElEZ0tJQ0FnSUNBZ0lDQWdJQ0FnYkc5allXd2dZV04wZFdGc1IyVnRJRDBnUlc1emRYSmxVM0JsYkd4SmJrZGxiU2hOYjI1emRHVnlVM1Z0Ylc5dWFXNW5VM0JsYkd3c0lFMXBjMk5UY0dWc2JFZGxiU2tLSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdibTkwSUdGamRIVmhiRWRsYlNCMGFHVnVDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQk9iM1JsTGtsdVptOG9KME52ZFd4a0lHNXZkQ0JzYjJGa0lFMXZibk4wWlhJZ1UzVnRiVzl1YVc1bklHbHVkRzhnWjJWdElDVmtPeUJsZUdsMGFXNW5JRzFoYm1FZ2JHOXZjQzRuTENCTmFYTmpVM0JsYkd4SFpXMHBDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmljbVZoYXdvZ0lDQWdJQ0FnSUNBZ0lDQmxibVFLQ2lBZ0lDQWdJQ0FnSUNBZ0lDMHRJRU5oYzNRZ1RXOXVjM1JsY2lCVGRXMXRiMjVwYm1jS0lDQWdJQ0FnSUNBZ0lDQWdWMkZwZEZOMGFXeHNLRFF3TUNrS0lDQWdJQ0FnSUNBZ0lDQWdhV1lnYlhFdVZFeFBMazFsTGxOd1pXeHNVbVZoWkhrb1RXOXVjM1JsY2xOMWJXMXZibWx1WjFOd1pXeHNLU2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHMXhMbU50WkdZb0p5OWpZWE4wSUNWa0p5d2dZV04wZFdGc1IyVnRLUW9nSUNBZ0lDQWdJQ0FnSUNCbGJtUUtJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTnpBd01Dd2dablZ1WTNScGIyNG9LU0J5WlhSMWNtNGdibTkwSUcxeExsUk1UeTVOWlM1RFlYTjBhVzVuTGtsRUtDa2daVzVrS1FvZ0lDQWdJQ0FnSUNBZ0lDQnRjUzVrWld4aGVTZ3pNREFwQ2dvZ0lDQWdJQ0FnSUNBZ0lDQXRMU0JTWldOc1lXbHRJR2x0YldWa2FXRjBaV3g1SUdsbUlHRWdjR1YwSUdseklIVndDaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaHRjUzVVVEU4dVRXVXVVR1YwTGtsRUtDa2diM0lnTUNrZ1BpQXdJR0Z1WkNCU1pXTnNZV2x0U1hSbGJTQjBhR1Z1Q2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JYWVdsMFUzUnBiR3dvTWpBd0tRb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2JYRXVZMjFrWmlnbkwzVnpaV2wwWlcwZ0pYTW5MQ0JTWldOc1lXbHRTWFJsYlNrS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RVd01Da0tJQ0FnSUNBZ0lDQWdJQ0FnWlc1a0NpQWdJQ0FnSUNBZ1pXNWtDZ29nSUNBZ0lDQWdJRzF4TG1SbGJHRjVLRFV3S1FvZ0lDQWdaVzVrQ2dvZ0lDQWdUbTkwWlM1SmJtWnZLQ2ROWVc1aElFeHZiM0FnUlc1a1pXUW5LUW9nSUNBZ0xTMGdabWx1WVd3Z1kyeGxZVzUxY0RvZ2FXWWdkR1Z0Y0NCd1pYUWdjM1JwYkd3Z2RYQXNJSEpsWTJ4aGFXMGdkVzUwYVd3Z1oyOXVaUW9nSUNBZ2QyaHBiR1VnS0cxeExsUk1UeTVOWlM1UVpYUXVTVVFvS1NCdmNpQXdLU0ErSURBZ1pHOEtJQ0FnSUNBZ0lDQnRjUzVqYldSbUtDY3ZkWE5sYVhSbGJTQWxjeWNzSUZKbFkyeGhhVzFKZEdWdEtRb2dJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEVXdNQ2tLSUNBZ0lHVnVaQXBsYm1RS0NpMHRJRWx1YVhRZ2MzQmxiR3h6TDJsMFpXMXpDbXh2WTJGc0lHWjFibU4wYVc5dUlFbHVhWFFvS1FvZ0lDQWdRMmhsWTJ0UWJIVm5hVzRvSjAxUk1saEJjM05wYzNRbktRb2dJQ0FnUTJobFkydFFiSFZuYVc0b0owMVJNa0ZrZGxCaGRHZ25LUW9nSUNBZ1EyaGxZMnRRYkhWbmFXNG9KMDFSTWsxdmRtVlZkR2xzY3ljcENpQWdJQ0JEYUdWamExQnNkV2RwYmlnblRWRXlRbTk0Y2ljcENnb2dJQ0FnVFc5dWMzUmxjbE4xYlcxdmJtbHVaeUE5SUhzS0lDQWdJQ0FnSUNBaVRXOXVjM1JsY2lCVGRXMXRiMjVwYm1jZ1dGWWlMQW9nSUNBZ0lDQWdJQ0pOYjI1emRHVnlJRk4xYlcxdmJtbHVaeUJZU1ZZaUxBb2dJQ0FnSUNBZ0lDSk5iMjV6ZEdWeUlGTjFiVzF2Ym1sdVp5QllTVWxKSWl3S0lDQWdJSDBLSUNBZ0lFMXZibk4wWlhKVGRXMXRiMjVwYm1kVGNHVnNiQ0E5SUVOb2IyOXpaVUZpYVd4cGRIa29UVzl1YzNSbGNsTjFiVzF2Ym1sdVp5a0tJQ0FnSUdsbUlHNXZkQ0JOYjI1emRHVnlVM1Z0Ylc5dWFXNW5VM0JsYkd3Z2RHaGxiZ29nSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduUVNCdGIyNXpkR1Z5SUhOMWJXMXZibWx1WnlCemNHVnNiQ0JwY3lCdWIzUWdZWFpoYVd4aFlteGxKeWtLSUNBZ0lDQWdJQ0J5WlhSMWNtNGdabUZzYzJVS0lDQWdJR1Z1WkFvS0lDQWdJQzB0SUZWd1pHRjBaV1FnUjJGMGFHVnlJR3hwYm1VZ0tHbHVZMngxWkdWeklHeGxkbVZzSURFeU5Ta0tJQ0FnSUVkaGRHaGxjazFoYm1FZ1BTQjdDaUFnSUNBZ0lDQWdJa2RoZEdobGNpQmFaV0ZzSWl3S0lDQWdJQ0FnSUNBaVIyRjBhR1Z5SUZacFoyOXlJaXdLSUNBZ0lDQWdJQ0FpUjJGMGFHVnlJRkJ2ZEdWdVkza2lMQW9nSUNBZ2ZRb2dJQ0FnUjJGMGFHVnlUV0Z1WVZOd1pXeHNJRDBnUTJodmIzTmxRV0pwYkdsMGVTaEhZWFJvWlhKTllXNWhLUW9nSUNBZ2FXWWdibTkwSUVkaGRHaGxjazFoYm1GVGNHVnNiQ0IwYUdWdUNpQWdJQ0FnSUNBZ1RtOTBaUzVKYm1adktDZEJJR2RoZEdobGNpQnRZVzVoSUhOd1pXeHNJR2x6SUc1dmRDQmhkbUZwYkdGaWJHVW5LUW9nSUNBZ0lDQWdJSEpsZEhWeWJpQm1ZV3h6WlFvZ0lDQWdaVzVrQ2dvZ0lDQWdVbVZqYkdGcGJWTmxkQ0E5SUhzS0lDQWdJQ0FnSUNBaVUzUmhabVlnYjJZZ1JXeGxiV1Z1ZEdGc0lFMWhjM1JsY25rNklFVmhjblJvSWl3S0lDQWdJQ0FnSUNBaVUzUmhabVlnYjJZZ1JXeGxiV1Z1ZEdGc0lFMWhjM1JsY25rNklFWnBjbVVpTEFvZ0lDQWdJQ0FnSUNKVGRHRm1aaUJ2WmlCRmJHVnRaVzUwWVd3Z1RXRnpkR1Z5ZVRvZ1FXbHlJaXdLSUNBZ0lDQWdJQ0FpVTNSaFptWWdiMllnUld4bGJXVnVkR0ZzSUUxaGMzUmxjbms2SUZkaGRHVnlJaXdLSUNBZ0lDQWdJQ0FpUW5KdmIyMGdiMllnVkhKcGJHOXVJaXdLSUNBZ0lDQWdJQ0FpUVc1amFXVnVkQ0JVYjNKamFDQnZaaUJCYkc1aElpd0tJQ0FnSUNBZ0lDQWlSMlZ0YldWa0lFZHNiM1psY3lCdlppQkhkV2xzWlNJc0NpQWdJQ0FnSUNBZ0lrZHNiM1psY3lCdlppQkVZWEpySUZOMWJXMXZibWx1WnlJc0NpQWdJQ0FnSUNBZ0lsTm9iM1psYkNCdlppQlFiMjU2SWl3S0lDQWdJQ0FnSUNBaVUzUmxhVzRnYjJZZ1ZXeHBjM05oSWl3S0lDQWdJQ0FnSUNBaVZHOXlZMmdnYjJZZ1FXeHVZU0lzQ2lBZ0lDQjlDaUFnSUNCU1pXTnNZV2x0U1hSbGJTQTlJRU5vYjI5elpVbDBaVzBvVW1WamJHRnBiVk5sZENrS0lDQWdJR2xtSUc1dmRDQlNaV05zWVdsdFNYUmxiU0IwYUdWdUNpQWdJQ0FnSUNBZ1RtOTBaUzVKYm1adktDZE9ieUJ5WldOc1lXbHRJR2wwWlcwZ1ptOTFibVFnYVc0Z2FXNTJaVzUwYjNKNUp5a0tJQ0FnSUNBZ0lDQnlaWFIxY200Z1ptRnNjMlVLSUNBZ0lHVnVaQW9LSUNBZ0lISmxkSFZ5YmlCMGNuVmxDbVZ1WkFvS0xTMGdUV0ZwYmlCeWIzVjBhVzVsSUNodFpYSm5aV1FnYVc1MGJ5Qk1SVTBnWVdOMGFXOXVLUXBzYjJOaGJDQm1kVzVqZEdsdmJpQlNkVzVOYjI1emRHVnlUV0Z1WVNncENpQWdJQ0JwWmlCdGNTNVVURTh1VFdVdVEyeGhjM011VTJodmNuUk9ZVzFsS0NrZ2ZqMGdKMDFCUnljZ2RHaGxiZ29nSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduVFc5dWMzUmxjazFoYm1FZ2IyNXNlU0IzYjNKcmN5Qm1iM0lnVFdGblpTQmphR0Z5WVdOMFpYSnpKeWtLSUNBZ0lDQWdJQ0J5WlhSMWNtNGdabUZzYzJVS0lDQWdJR1Z1WkFvZ0lDQWdhV1lnS0cxeExsUk1UeTVOWlM1UVkzUk5ZVzVoS0NrZ2IzSWdNVEF3S1NBK0lEazFJSFJvWlc0S0lDQWdJQ0FnSUNCT2IzUmxMa2x1Wm04b0owMWhibUVnYVhNZ2JtVmhjbXg1SUdaMWJHdzdJRzV2ZEdocGJtY2dkRzhnWkc4bktRb2dJQ0FnSUNBZ0lISmxkSFZ5YmlCbVlXeHpaUW9nSUNBZ1pXNWtDaUFnSUNCcFppQnViM1FnU1c1cGRDZ3BJSFJvWlc0S0lDQWdJQ0FnSUNCT2IzUmxMa2x1Wm04b0owbHVhWFJwWVd4cGVtRjBhVzl1SUhWdWMzVmpZMlZ6YzJaMWJDY3BDaUFnSUNBZ0lDQWdjbVYwZFhKdUlHWmhiSE5sQ2lBZ0lDQmxibVFLQ2lBZ0lDQnRjUzVqYldRb0p5OXpjWFZsYkdOb0lDOWtiMk52YlcxaGJtUWdMMkp2ZUhJZ2NHRjFjMlVuS1FvZ0lDQWdiWEV1WkdWc1lYa29NekF3S1FvZ0lDQWdiWEV1WTIxa0tDY3ZjM0YxWld4amFDQXZZWFIwWVdOcklHOW1aaWNwQ2dvZ0lDQWdMUzBnWTJ4bFlYSWdZM1Z5YzI5eUNpQWdJQ0IzYUdsc1pTQnRjUzVVVEU4dVEzVnljMjl5TGtsRUtDa2daRzhLSUNBZ0lDQWdJQ0J0Y1M1amJXUW9KeTloZFhSdmFXNTJaVzUwYjNKNUp5a0tJQ0FnSUNBZ0lDQnRjUzVrWld4aGVTZzFNREFwQ2lBZ0lDQmxibVFLQ2lBZ0lDQXRMU0JKWmlCM1pTQmhiSEpsWVdSNUlHaGhkbVVnWVNCdFlXbHVJSEJsZEN3Z2MzVnpjR1Z1WkNCcGRDQkdTVkpUVkNBb1lteHZZMnRwYm1jcENpQWdJQ0JwWmlBb2JYRXVWRXhQTGsxbExsQmxkQzVKUkNncElHOXlJREFwSUQ0Z01DQjBhR1Z1Q2lBZ0lDQWdJQ0FnVG05MFpTNUpibVp2S0NkUWNtbHRZWEo1SUcxaGJtRWdiV1YwYUc5a0lDaDNhWFJvSUhCbGRDa25LUW9nSUNBZ0lDQWdJR2xtSUc1dmRDQlRkWE53Wlc1a1VISnBiV0Z5ZVZCbGRGOUNiRzlqYTJsdVp5Z3BJSFJvWlc0S0lDQWdJQ0FnSUNBZ0lDQWdUbTkwWlM1SmJtWnZLQ2RWYm1GaWJHVWdkRzhnYzNWemNHVnVaQ0J3WlhRZ2MyRm1aV3g1T3lCaFltOXlkR2x1Wnk0bktRb2dJQ0FnSUNBZ0lDQWdJQ0J0Y1M1amJXUW9KeTl6Y1hWbGJHTm9JQzlrYjJOdmJXMWhibVFnTDJKdmVISWdkVzV3WVhWelpTY3BDaUFnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJtWVd4elpRb2dJQ0FnSUNBZ0lHVnVaQW9nSUNBZ1pXeHpaUW9nSUNBZ0lDQWdJQzB0SUU1dkxYQmxkQ0JtWVd4c1ltRmphem9nWW5WcGJHUWdkRzhnT0NVZ2QybDBhQ0JIWVhSb1pYSWdiM0lnYzJsMGRHbHVad29nSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduVUhKcGJXRnllU0J0WVc1aElHMWxkR2h2WkNBb2JtOGdjR1YwS1NjcENpQWdJQ0FnSUNBZ2QyaHBiR1VnS0cxeExsUk1UeTVOWlM1UVkzUk5ZVzVoS0NrZ2IzSWdNQ2tnUENBNElHUnZDaUFnSUNBZ0lDQWdJQ0FnSUd4dlkyRnNJSEpoYm10T1lXMWxJRDBnYlhFdVZFeFBMbE53Wld4c0tFZGhkR2hsY2sxaGJtRlRjR1ZzYkNrdVVtRnVhMDVoYldVb0tRb2dJQ0FnSUNBZ0lDQWdJQ0JwWmlCdGNTNVVURTh1VFdVdVUzQmxiR3hTWldGa2VTaHlZVzVyVG1GdFpTa29LU0IwYUdWdUNpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCWFlXbDBVM1JwYkd3b05EQXdLUW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WTIxa1ppZ25MMk5oYzNRZ0lpVnpJaWNzSUhKaGJtdE9ZVzFsS1FvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTWpBd01EQXNJR1oxYm1OMGFXOXVLQ2tnY21WMGRYSnVJRzV2ZENCdGNTNVVURTh1VFdVdVEyRnpkR2x1Wnk1SlJDZ3BJR1Z1WkNrS0lDQWdJQ0FnSUNBZ0lDQWdaV3h6WldsbUlIZHZjbXRwYm1kVGRHRjBaWE5iYlhFdVZFeFBMazFsTGtOdmJXSmhkRk4wWVhSbEtDa2diM0lnSnlkZElIUm9aVzRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR2xtSUcxeExsUk1UeTVOWlM1VGRHRnVaR2x1WnlncElHRnVaQ0J1YjNRZ2JYRXVWRXhQTGsxbExrTmhjM1JwYm1jdVNVUW9LU0IwYUdWdUlHMXhMbFJNVHk1TlpTNVRhWFFvS1NCbGJtUUtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEWXdOVEFwQ2lBZ0lDQWdJQ0FnSUNBZ0lHVnVaQW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWtaV3hoZVNneE5UQXBDaUFnSUNBZ0lDQWdaVzVrQ2lBZ0lDQmxibVFLQ2lBZ0lDQXRMU0JTZFc0Z2JXRnVZU0JzYjI5d0lDaHpkVzF0YjI0dmNtVmpiR0ZwYlNrS0lDQWdJRkpsWTJ4aGFXMU5ZVzVoS0NrS0NpQWdJQ0F0TFNCVWNua2dkRzhnY21WemRHOXlaU0J0WVdsdUlIQmxkQ0FvZFc1emRYTndaVzVrS1M0Z1RHOXZjQ0IxYm5ScGJDQmhJRzV2YmkxWFlYSnlhVzl5SUhCbGRDQW9hUzVsTGl3Z2VXOTFjaUJ5WldGc0lHVnNaVzFsYm5SaGJDa2djbVYwZFhKdWN5NEtJQ0FnSUU1dmRHVXVTVzVtYnlnblVtVnpkRzl5YVc1bklHMWhhVzRnY0dWMElDaDFibk4xYzNCbGJtUnBibWNwSnlrS0lDQWdJSGRvYVd4bElDaHRjUzVVVEU4dVRXVXVVR1YwTGtsRUtDa2diM0lnTUNrZ1BUMGdNQ0JrYndvZ0lDQWdJQ0FnSUZkaGFYUlRkR2xzYkNnME1EQXBDaUFnSUNBZ0lDQWdiWEV1WTIxa0tDY3ZZV3gwSUdGamRDQXhOelluS1FvZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RZMU1EQXNJR1oxYm1OMGFXOXVLQ2tnY21WMGRYSnVJRzV2ZENCdGNTNVVURTh1VFdVdVEyRnpkR2x1Wnk1SlJDZ3BJR1Z1WkNrS0lDQWdJQ0FnSUNCdGNTNWtaV3hoZVNnek1EQXBDaUFnSUNCbGJtUUtJQ0FnSUMwdElFbG1JR0VnVFc5dWMzUmxjaUJUZFcxdGIyNXBibWNnZDJGeWNtbHZjaUJ3WlhRZ2NHOXdjR1ZrSUdsdWMzUmxZV1FzSUhKbFkyeGhhVzBnWVc1a0lIUnllU0JoWjJGcGJpNEtJQ0FnSUhkb2FXeGxJQ2h0Y1M1VVRFOHVUV1V1VUdWMExrTnNZWE56TGs1aGJXVW9LU0J2Y2lBbkp5a2dQVDBnSjFkaGNuSnBiM0luSUdSdkNpQWdJQ0FnSUNBZ2FXWWdVbVZqYkdGcGJVbDBaVzBnZEdobGJnb2dJQ0FnSUNBZ0lDQWdJQ0J0Y1M1amJXUm1LQ2N2ZFhObGFYUmxiU0FsY3ljc0lGSmxZMnhoYVcxSmRHVnRLUW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWtaV3hoZVNnMU1EQXBDaUFnSUNBZ0lDQWdaV3h6WlFvZ0lDQWdJQ0FnSUNBZ0lDQmljbVZoYXdvZ0lDQWdJQ0FnSUdWdVpBb2dJQ0FnSUNBZ0lIZG9hV3hsSUNodGNTNVVURTh1VFdVdVVHVjBMa2xFS0NrZ2IzSWdNQ2tnUFQwZ01DQmtid29nSUNBZ0lDQWdJQ0FnSUNCWFlXbDBVM1JwYkd3b05EQXdLUW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWpiV1FvSnk5aGJIUWdZV04wSURFM05pY3BDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RZMU1EQXNJR1oxYm1OMGFXOXVLQ2tnY21WMGRYSnVJRzV2ZENCdGNTNVVURTh1VFdVdVEyRnpkR2x1Wnk1SlJDZ3BJR1Z1WkNrS0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WkdWc1lYa29NekF3S1FvZ0lDQWdJQ0FnSUdWdVpBb2dJQ0FnWlc1a0Nnb2dJQ0FnYlhFdVpHVnNZWGtvTXpBd0tRb2dJQ0FnYlhFdVkyMWtLQ2N2Y0dWMElHaHZiR1FuS1FvZ0lDQWdiWEV1WkdWc1lYa29NekF3S1FvZ0lDQWdiWEV1WTIxa0tDY3ZjM0YxWld4amFDQXZaRzlqYjIxdFlXNWtJQzlpYjNoeUlIVnVjR0YxYzJVbktRb2dJQ0FnYlhFdVpHVnNZWGtvTXpBd0tRb2dJQ0FnVG05MFpTNUpibVp2S0NkTllXNWhJSEp2ZFhScGJtVWdZMjl0Y0d4bGRHVXVJRTFoWjJVZ2JXRnVZU0J1YjNjNklGeGhaeVZ6Snl3Z2RHOXpkSEpwYm1jb2JYRXVWRXhQTGsxbExsQmpkRTFoYm1Fb0tTa3BDaUFnSUNCdGNTNWpiV1FvSnk5emNYVmxiR05vSUM5aVpXVndiMjUwWld4c2N5QnZiaWNwQ2lBZ0lDQnlaWFIxY200Z2RISjFaUXBsYm1RS0NteHZZMkZzSUdaMWJtTjBhVzl1SUdGamRHbHZiaWdwQ2lBZ0lDQXRMU0JTWldkcGMzUmxjaUJ6Y0dWc2JHSnZiMnNnWlhabGJuUnpJQ2hNUlUwdGMyRm1aU2tLSUNBZ0lHMXhMbVYyWlc1MEtDZENaV2RwYmsxbGJXOXlhWHBwYm1jbkxDQWlJeW9qUW1WbmFXNXVhVzVuSUhSdklHMWxiVzl5YVhwbElDTXhJeTR1TGlNcUl5SXNJRVYyWlc1MFgwSmxaMmx1VFdWdGIzSnBlbWx1WnlrS0lDQWdJRzF4TG1WMlpXNTBLQ2RHYVc1cGMyaE5aVzF2Y21sNmFXNW5KeXdnSWlNcUkxbHZkU0JvWVhabElHWnBibWx6YUdWa0lHMWxiVzl5YVhwcGJtY2dJekVqSXlvaklpd2dSWFpsYm5SZlJXNWtUV1Z0YjNKcGVtbHVaeWtLSUNBZ0lHMXhMbVYyWlc1MEtDZEJZbTl5ZEUxbGJXOXlhWHBwYm1jbkxDQWlJeW9qUVdKdmNuUnBibWNnYldWdGIzSnBlbUYwYVc5dUlHOW1JSE53Wld4c0xpTXFJeUlzSUVWMlpXNTBYMFZ1WkUxbGJXOXlhWHBwYm1jcENnb2dJQ0FnYkc5allXd2diMnNzSUdWeWNpQTlJSEJqWVd4c0tGSjFiazF2Ym5OMFpYSk5ZVzVoS1FvZ0lDQWdhV1lnYm05MElHOXJJSFJvWlc0Z1RtOTBaUzVKYm1adktDZGNZWEpGY25KdmNqcGNZWGdnSlhNbkxDQjBiM04wY21sdVp5aGxjbklwS1NCbGJtUUtaVzVrQ2dweVpYUjFjbTRnZTJOdmJtUm1kVzVqUFdOdmJtUnBkR2x2Yml3Z1lXTjBhVzl1Wm5WdVl6MWhZM1JwYjI1OUNnPT0iLAogWyJ0eXBlIl0gPSAiY29uZGl0aW9ucyIsCiBbImNhdGVnb3J5Il0gPSAiR2VuZXJhbCIsCn0=
 
Updated LEM Version that fixed some bugs:

Import String:
Import String
Code:
cmV0dXJuIHsKIFsibG9hZCJdID0gewogIFsiYWx3YXlzIl0gPSBmYWxzZSwKICBbInpvbmUiXSA9ICIiLAogIFsiY2xhc3MiXSA9ICIiLAogfSwKIFsidHlwZSJdID0gImNvbmRpdGlvbnMiLAogWyJuYW1lIl0gPSAiTWFnZSAtIEVuZGxlc3MgTWFuYSIsCiBbImNhdGVnb3J5Il0gPSAiR2VuZXJhbCIsCiBbImNvZGUiXSA9ICJiRzlqWVd3Z2JYRWdQU0J5WlhGMWFYSmxLQ2R0Y1NjcENnb3RMUzFBY21WMGRYSnVJR0p2YjJ4bFlXNGdRRkpsZEhWeWJuTWdkSEoxWlNCcFppQjBhR1VnWVdOMGFXOXVJSE5vYjNWc1pDQm1hWEpsTENCdmRHaGxjbmRwYzJVZ1ptRnNjMlV1Q214dlkyRnNJR1oxYm1OMGFXOXVJR052Ym1ScGRHbHZiaWdwQ2lBZ0lDQnNiMk5oYkNCdGVWOWpiR0Z6Y3lBOUlHMXhMbFJNVHk1TlpTNURiR0Z6Y3k1VGFHOXlkRTVoYldVb0tRb2dJQ0FnYkc5allXd2diWGxmYldGdVlTQTlJRzF4TGxSTVR5NU5aUzVRWTNSTllXNWhLQ2tLSUNBZ0lHeHZZMkZzSUdOb1pXTnJYM0JoZFhObFpDQTlJRzF4TGxSTVR5NURWMVJPTGxCaGRYTmxaQ2dwQ2lBZ0lDQnNiMk5oYkNCdGJWOXpkR0YwZFhNZ1BTQnRjUzVVVEU4dVRIVmhMbE5qY21sd2RDZ25UVTFpY25WMFpTY3BMbE4wWVhSMWN5Z3BDaUFnSUNCeVpYUjFjbTRnYlhsZlkyeGhjM01nUFQwZ0owMUJSeWNnWVc1a0lHMTVYMjFoYm1FZ1BDQXlNQ0JoYm1RZ2JXMWZjM1JoZEhWeklINDlJQ2RTVlU1T1NVNUhKeUJoYm1RZ1kyaGxZMnRmY0dGMWMyVmtJRDA5SUdaaGJITmxDbVZ1WkFvS0xTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwS0xTMGdSWFpsY25sMGFHbHVaeUJpWld4dmR5QnlkVzV6SUdsdWMybGtaU0JNUlUwbmN5QmhZM1JwYjI0b0tTQjNhR1Z1SUhSb1pTQmpiMjVrYVhScGIyNGdhWE1nYldWMENpMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdENnb3RMU0JNYVdkb2RIZGxhV2RvZENCc2IyZG5aWElnS0hObGJHWXRZMjl1ZEdGcGJtVmtLUXBzYjJOaGJDQk9iM1JsSUQwZ2V5QndjbVZtYVhnZ1BTQW5UVzl1YzNSbGNrMWhibUVuTENCc2IyZHNaWFpsYkNBOUlDZHBibVp2SnlCOUNtWjFibU4wYVc5dUlFNXZkR1V1U1c1bWJ5aG1iWFFzSUM0dUxpa2djSEpwYm5Rb0tDZGNZV2RiSlhOZFhHRjRJQ2N1TG1adGRDazZabTl5YldGMEtFNXZkR1V1Y0hKbFptbDRMQ0F1TGk0cEtTQmxibVFLQ2kwdElGTjBZWFJsSUM4Z1kyOXVabWxuQ214dlkyRnNJSGR2Y210cGJtZFRkR0YwWlhNZ1BTQjdJRUZqZEdsMlpUMTBjblZsTENCRGIyOXNaRzkzYmoxMGNuVmxMQ0JTWlhOMGFXNW5QWFJ5ZFdVZ2ZRcHNiMk5oYkNCTmIyNXpkR1Z5VTNWdGJXOXVhVzVuTENCTmIyNXpkR1Z5VTNWdGJXOXVhVzVuVTNCbGJHd0tiRzlqWVd3Z1IyRjBhR1Z5VFdGdVlTd2dSMkYwYUdWeVRXRnVZVk53Wld4c0NteHZZMkZzSUZKbFkyeGhhVzFUWlhRc0lGSmxZMnhoYVcxSmRHVnRDbXh2WTJGc0lFMXBjMk5UY0dWc2JFZGxiU0E5SURnZ0xTMGdkWE5wYm1jZ1oyVnRJRGdLYkc5allXd2dTWE5OWlcxdmNtbDZhVzVuSUQwZ1ptRnNjMlVLYkc5allXd2daR2xrVTNWemNHVnVaRTFoYVc1UVpYUWdQU0JtWVd4elpTQXRMU0JPUlZjNklIUnlZV05ySUhkb1pYUm9aWElnZDJVZ1lXTjBkV0ZzYkhrZ2MzVnpjR1Z1WkdWa0lHRWdiV0ZwYmlCd1pYUWdkR2hwY3lCeWRXNEtDaTB0SUMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdENpMHRJRWhsYkhCbGNuTUtMUzBnTFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwdExTMHRMUzB0TFMwS2JHOWpZV3dnWm5WdVkzUnBiMjRnUTJobFkydFFiSFZuYVc0b2NHeDFaMmx1S1FvZ0lDQWdhV1lnYm05MElHMXhMbFJNVHk1UWJIVm5hVzRvY0d4MVoybHVLU2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQnRjUzVqYldSbUtDY3ZjM0YxWld4amFDQXZjR3gxWjJsdUlDVnpJRzV2WVhWMGJ5Y3NJSEJzZFdkcGJpa0tJQ0FnSUNBZ0lDQk9iM1JsTGtsdVptOG9KMXhoZHlWelhHRjRJRzV2ZENCa1pYUmxZM1JsWkM0Z1RHOWhaR2x1WitLQXBpY3NJSEJzZFdkcGJpa0tJQ0FnSUdWdVpBcGxibVFLQ2kwdElGTnBiWEJzWlNCdGIzWmxiV1Z1ZENCamFHVmphem9nYjI1c2VTQjViM1Z5SUdGMllYUmhjdUtBbVhNZ2JXOTBhVzl1TGdwc2IyTmhiQ0JtZFc1amRHbHZiaUJKYzAxdmRtbHVaeWdwQ2lBZ0lDQnlaWFIxY200Z2JYRXVWRXhQTGsxbExrMXZkbWx1WnlncElHOXlJQ2dvYlhFdVZFeFBMazFsTGxOd1pXVmtLQ2tnYjNJZ01Da2dQaUF3S1FwbGJtUUtDaTB0SUZkaGFYUWdkVzUwYVd3Z2QyWGlnSmwyWlNCaVpXVnVJRTVQVkNCdGIzWnBibWNnWm05eUlHRWdZMjl1ZEdsdWRXOTFjeUIzYVc1a2IzY2dLRzF6S1M0Z1RtOGdZWFIwWlcxd2RDQnNhVzFwZEM0S2JHOWpZV3dnWm5WdVkzUnBiMjRnVjJGcGRGTjBhV3hzS0cxcGJsOXRjeWtLSUNBZ0lHMXBibDl0Y3lBOUlHMXBibDl0Y3lCdmNpQTBNREFLSUNBZ0lHeHZZMkZzSUhOMGFXeHNVM1JoY25RZ1BTQnVhV3dLSUNBZ0lIZG9hV3hsSUhSeWRXVWdaRzhLSUNBZ0lDQWdJQ0JwWmlCSmMwMXZkbWx1WnlncElIUm9aVzRLSUNBZ0lDQWdJQ0FnSUNBZ2MzUnBiR3hUZEdGeWRDQTlJRzVwYkFvZ0lDQWdJQ0FnSUdWc2MyVUtJQ0FnSUNBZ0lDQWdJQ0FnYzNScGJHeFRkR0Z5ZENBOUlITjBhV3hzVTNSaGNuUWdiM0lnYlhFdVoyVjBkR2x0WlNncENpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNodGNTNW5aWFIwYVcxbEtDa2dMU0J6ZEdsc2JGTjBZWEowS1NBK1BTQnRhVzVmYlhNZ2RHaGxiaUJ5WlhSMWNtNGdkSEoxWlNCbGJtUUtJQ0FnSUNBZ0lDQmxibVFLSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2cxTUNrS0lDQWdJR1Z1WkFwbGJtUUtDaTB0SUZKdlluVnpkQ0RpZ0p4aGJTQkpJR2x1SUdOdmJXSmhkRC9pZ0owZ1kyaGxZMnNLYkc5allXd2dablZ1WTNScGIyNGdTVzVEYjIxaVlYUW9LUW9nSUNBZ2JHOWpZV3dnWTNNZ1BTQjBiM04wY21sdVp5aHRjUzVVVEU4dVRXVXVRMjl0WW1GMFUzUmhkR1VvS1NCdmNpQW5KeWtLSUNBZ0lHbG1JR056SUg0OUlDY25JR0Z1WkNCamN6cDFjSEJsY2lncElEMDlJQ2REVDAxQ1FWUW5JSFJvWlc0Z2NtVjBkWEp1SUhSeWRXVWdaVzVrQ2lBZ0lDQnBaaUJ0Y1M1VVRFOHVUV1V1UTI5dFltRjBJR0Z1WkNCdGNTNVVURTh1VFdVdVEyOXRZbUYwS0NrZ2RHaGxiaUJ5WlhSMWNtNGdkSEoxWlNCbGJtUUtJQ0FnSUhKbGRIVnliaUJtWVd4elpRcGxibVFLQ214dlkyRnNJR1oxYm1OMGFXOXVJRU5vYjI5elpVRmlhV3hwZEhrb2MyVjBLUW9nSUNBZ2JHOWpZV3dnWTJodmMyVnVVM0JsYkd3c0lHaHBaMmhsYzNSTVpYWmxiQ0E5SUc1cGJDd2dNQW9nSUNBZ1ptOXlJRjhzSUc1aGJXVWdhVzRnYVhCaGFYSnpLSE5sZENrZ1pHOEtJQ0FnSUNBZ0lDQnNiMk5oYkNCeklEMGdiWEV1VkV4UExsTndaV3hzS0c1aGJXVXBDaUFnSUNBZ0lDQWdiRzlqWVd3Z2JIWnNMQ0J5WVc1cklEMGdjeTVNWlhabGJDZ3BMQ0J6TGxKaGJtdE9ZVzFsS0NrS0lDQWdJQ0FnSUNCcFppQnlZVzVySUdGdVpDQnRjUzVVVEU4dVRXVXVRbTl2YXloeVlXNXJLU2dwSUdGdVpDQnNkbXdnUGlCb2FXZG9aWE4wVEdWMlpXd2dkR2hsYmdvZ0lDQWdJQ0FnSUNBZ0lDQmphRzl6Wlc1VGNHVnNiQ0E5SUNodGNTNVVURTh1VFdVdVUzQmxiR3hTWVc1clEyRndLQ2tnUGlBeEtTQmhibVFnY3k1U1lXNXJUbUZ0WlNncElHOXlJSE11UW1GelpVNWhiV1VvS1FvZ0lDQWdJQ0FnSUNBZ0lDQm9hV2RvWlhOMFRHVjJaV3dnUFNCc2Rtd0tJQ0FnSUNBZ0lDQmxibVFLSUNBZ0lHVnVaQW9nSUNBZ2NtVjBkWEp1SUdOb2IzTmxibE53Wld4c0NtVnVaQW9LYkc5allXd2dablZ1WTNScGIyNGdRMmh2YjNObFNYUmxiU2h6WlhRcENpQWdJQ0JtYjNJZ1h5d2dibUZ0WlNCcGJpQnBjR0ZwY25Nb2MyVjBLU0JrYndvZ0lDQWdJQ0FnSUdsbUlHMXhMbFJNVHk1R2FXNWtTWFJsYlVOdmRXNTBLRzVoYldVcEtDa2dQaUF3SUhSb1pXNGdjbVYwZFhKdUlHNWhiV1VnWlc1a0NpQWdJQ0JsYm1RS1pXNWtDZ290TFNCVGNHVnNiR0p2YjJzZ1pYWmxiblJ6SUNoeVpXZHBjM1JsY21Wa0lHbHVjMmxrWlNCaFkzUnBiMjRvS1NrS2JHOWpZV3dnWm5WdVkzUnBiMjRnUlhabGJuUmZRbVZuYVc1TlpXMXZjbWw2YVc1bktGOHNJRjhwSUVselRXVnRiM0pwZW1sdVp5QTlJSFJ5ZFdVZ1pXNWtDbXh2WTJGc0lHWjFibU4wYVc5dUlFVjJaVzUwWDBWdVpFMWxiVzl5YVhwcGJtY29YeXdnWHlrZ1NYTk5aVzF2Y21sNmFXNW5JRDBnWm1Gc2MyVWdaVzVrQ2dvdExTQkZibk4xY21VZ2MzQmxiR3dnYVhNZ2FXNGdZU0J6Y0dWamFXWnBZeUJuWlcwZ0tHSnNiMk5yYVc1bkxDQnVieUJoZEhSbGJYQjBJR3hwYldsMEtTNGdUMjVzZVNCemRHRnlkSE1nZDJobGJpQnpkR0YwYVc5dVlYSjVMZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQkZibk4xY21WVGNHVnNiRWx1UjJWdEtITndaV3hzVkc5TlpXMHNJR2RsYlNrS0lDQWdJR2RsYlNBOUlHZGxiU0J2Y2lCTmFYTmpVM0JsYkd4SFpXMEtJQ0FnSUhkb2FXeGxJSFJ5ZFdVZ1pHOEtJQ0FnSUNBZ0lDQnBaaUJ0Y1M1VVRFOHVUV1V1UjJWdEtITndaV3hzVkc5TlpXMHBLQ2tnUFQwZ1oyVnRJSFJvWlc0Z2NtVjBkWEp1SUdkbGJTQmxibVFLSUNBZ0lDQWdJQ0JzYjJOaGJDQnliaUE5SUcxeExsUk1UeTVUY0dWc2JDaHpjR1ZzYkZSdlRXVnRLUzVTWVc1clRtRnRaU2dwQ2lBZ0lDQWdJQ0FnYVdZZ2JtOTBJSEp1SUc5eUlHNXZkQ0J0Y1M1VVRFOHVUV1V1UW05dmF5aHliaWtvS1NCMGFHVnVDaUFnSUNBZ0lDQWdJQ0FnSUU1dmRHVXVTVzVtYnlnblEyRnVibTkwSUcxbGJXOXlhWHBsSUNodWIzUWdhVzRnWW05dmF5azZJQ1Z6Snl3Z2RHOXpkSEpwYm1jb2MzQmxiR3hVYjAxbGJTa3BDaUFnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliZ29nSUNBZ0lDQWdJR1Z1WkFvZ0lDQWdJQ0FnSUdsbUlHNXZkQ0J0Y1M1VVRFOHVUV1V1UjJWdEtHZGxiU2tvS1NCaGJtUWdaMlZ0SUg0OUlFMXBjMk5UY0dWc2JFZGxiU0IwYUdWdUlHZGxiU0E5SUUxcGMyTlRjR1ZzYkVkbGJTQmxibVFLSUNBZ0lDQWdJQ0JYWVdsMFUzUnBiR3dvTmpBd0tRb2dJQ0FnSUNBZ0lFNXZkR1V1U1c1bWJ5Z25YR0ZuVFdWdGJXbHVaMXhoZUNBaUpYTWlJR2x1ZEc4Z1oyVnRJQ1ZrSnl3Z2NtNHNJR2RsYlNrS0lDQWdJQ0FnSUNCdGNTNWpiV1JtS0NjdmJXVnRjM0JsYkd3Z0pXUWdJaVZ6SWljc0lHZGxiU3dnY200cENpQWdJQ0FnSUNBZ2JYRXVaR1ZzWVhrb01qQXdNQ3dnWm5WdVkzUnBiMjRvS1NCeVpYUjFjbTRnU1hOTlpXMXZjbWw2YVc1bklHOXlJRzF4TGxSTVR5NU5aUzVIWlcwb1oyVnRLUzVPWVcxbEtDa2dQVDBnY200Z1pXNWtLUW9nSUNBZ0lDQWdJRzF4TG1SbGJHRjVLREV3TURBd0xDQm1kVzVqZEdsdmJpZ3BJSEpsZEhWeWJpQnRjUzVVVEU4dVRXVXVSMlZ0S0dkbGJTa3VUbUZ0WlNncElEMDlJSEp1SUc5eUlHNXZkQ0JKYzAxbGJXOXlhWHBwYm1jZ1pXNWtLUW9nSUNBZ0lDQWdJR2xtSUcxeExsUk1UeTVOWlM1SFpXMG9aMlZ0S1M1T1lXMWxLQ2tnUFQwZ2NtNGdkR2hsYmlCeVpYUjFjbTRnWjJWdElHVnVaQW9nSUNBZ1pXNWtDbVZ1WkFvS0xTMGdVR1YwSUhCeWIzaHBiV2wwZVNCb1pXeHdaWEp6SUNoM2FYUm9JRzl3ZEdsdmJtRnNJSFJwYldWdmRYUWdkRzhnY0hKbGRtVnVkQ0JvWVc1bmN5a0tiRzlqWVd3Z1puVnVZM1JwYjI0Z1VHVjBUbVZoY2lodFlYaEVhWE4wS1NCeVpYUjFjbTRnS0cxeExsUk1UeTVOWlM1UVpYUXVSR2x6ZEdGdVkyVW9LU0J2Y2lBNU9UazVLU0E4UFNBb2JXRjRSR2x6ZENCdmNpQXhNaWtnWlc1a0NteHZZMkZzSUdaMWJtTjBhVzl1SUZkaGFYUlFaWFJPWldGeUtHMWhlRVJwYzNRc0lIUnBiV1Z2ZFhSZmJYTXBDaUFnSUNCdFlYaEVhWE4wSUQwZ2JXRjRSR2x6ZENCdmNpQXhNZ29nSUNBZ2JHOWpZV3dnYzNSaGNuUWdQU0J0Y1M1blpYUjBhVzFsS0NrS0lDQWdJSGRvYVd4bElIUnlkV1VnWkc4S0lDQWdJQ0FnSUNCcFppQW9iWEV1VkV4UExrMWxMbEJsZEM1SlJDZ3BJRzl5SURBcElEMDlJREFnZEdobGJpQnlaWFIxY200Z1ptRnNjMlVnWlc1a0NpQWdJQ0FnSUNBZ2FXWWdVR1YwVG1WaGNpaHRZWGhFYVhOMEtTQjBhR1Z1SUhKbGRIVnliaUIwY25WbElHVnVaQW9nSUNBZ0lDQWdJR2xtSUhScGJXVnZkWFJmYlhNZ1lXNWtJQ2h0Y1M1blpYUjBhVzFsS0NrZ0xTQnpkR0Z5ZENrZ1BqMGdkR2x0Wlc5MWRGOXRjeUIwYUdWdUlISmxkSFZ5YmlCUVpYUk9aV0Z5S0cxaGVFUnBjM1FwSUdWdVpBb2dJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEVXdLUW9nSUNBZ1pXNWtDbVZ1WkFvS0xTMGdVM1Z6Y0dWdVpDQndaWFFnZDJsMGFDQm1kV3hzSUhObGNYVmxibU5sSUdWMlpYSjVJSEJoYzNNdUNpMHRJRTl1YkhrZ2RYTmxJRU52VkVnZ1FVRWdLRGN3TlRBcElHbG1JSGRsSUdGeVpTQkpUaUJEVDAxQ1FWUXVDaTB0SUZKbGRIVnlibk1nVkZKVlJTQnZibXg1SUdsbUlIUm9aU0J3WlhRZ1pXNWtjeUIxY0NCemRYTndaVzVrWldRZ0tFbEVJRDA5SURBcExncHNiMk5oYkNCbWRXNWpkR2x2YmlCVGRYTndaVzVrVUhKcGJXRnllVkJsZEY5Q2JHOWphMmx1WnlncENpQWdJQ0JzYjJOaGJDQnZjbWxuU1VRZ1BTQnRjUzVVVEU4dVRXVXVVR1YwTGtsRUtDa2diM0lnTUFvZ0lDQWdhV1lnYjNKcFowbEVJRDA5SURBZ2RHaGxiaUJ5WlhSMWNtNGdabUZzYzJVZ1pXNWtJQzB0SUc1dmRHaHBibWNnZEc4Z2MzVnpjR1Z1WkFvS0lDQWdJRTV2ZEdVdVNXNW1ieWduVTNSdmNtbHVaeUJRWlhRZ0tFbEVJQ1Z6S1Njc0lIUnZjM1J5YVc1bktHOXlhV2RKUkNrcENnb2dJQ0FnZDJocGJHVWdLRzF4TGxSTVR5NU5aUzVRWlhRdVNVUW9LU0J2Y2lBd0tTQStJREFnWkc4S0lDQWdJQ0FnSUNBdExTQkdkV3hzSUhObGNYVmxibU5sT2lCbmFHOXNaQ0F0UGlCemNHVnNiR2h2YkdRZ0xUNGdZbUZqYXlBdFBpQlRkVzF0YjI0Z1EyOXRjR0Z1YVc5dUlDZ3hNakUxS1NBdFBpQW9RMjlVU0NCcFppQkpUaUJEVDAxQ1FWUXBJQzArSUhOMWMzQmxibVFLSUNBZ0lDQWdJQ0JYWVdsMFUzUnBiR3dvTkRBd0tRb2dJQ0FnSUNBZ0lHMXhMbU50WkNnbkwzQmxkQ0JuYUc5c1pDQnZiaWNwSUNBZ0lEc2diWEV1WkdWc1lYa29NekF3S1FvZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDNCbGRDQnpjR1ZzYkdodmJHUWdiMjRuS1RzZ2JYRXVaR1ZzWVhrb016QXdLUW9nSUNBZ0lDQWdJRzF4TG1OdFpDZ25MM0JsZENCaVlXTnJKeWtnSUNBZ0lDQWdJRHNnYlhFdVpHVnNZWGtvTXpBd0tRb0tJQ0FnSUNBZ0lDQXRMU0JUZFcxdGIyNGdRMjl0Y0dGdWFXOXVJRkpKUjBoVUlFSkZSazlTUlNCemRYTndaVzVrYVc1bkxDQnBaaUJ5WldGa2VTQW9aRzl1NG9DWmRDQmliRzlqYXlCbWIzSWdRMFFwQ2lBZ0lDQWdJQ0FnYVdZZ2JYRXVWRXhQTGsxbExrRnNkRUZpYVd4cGRIbFNaV0ZrZVNneE1qRTFLU2dwSUc5eUlHMXhMbFJNVHk1TlpTNUJiSFJCWW1sc2FYUjVVbVZoWkhrb0oxTjFiVzF2YmlCRGIyMXdZVzVwYjI0bktTZ3BJSFJvWlc0S0lDQWdJQ0FnSUNBZ0lDQWdWMkZwZEZOMGFXeHNLRE13TUNrS0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WTIxa0tDY3ZZV3gwSUdGamRDQXhNakUxSnlrS0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WkdWc1lYa29NelV3TUN3Z1puVnVZM1JwYjI0b0tTQnlaWFIxY200Z2JtOTBJRzF4TGxSTVR5NU5aUzVEWVhOMGFXNW5Ma2xFS0NrZ1pXNWtLUW9nSUNBZ0lDQWdJQ0FnSUNCWFlXbDBVR1YwVG1WaGNpZ3hNaXdnTXpBd01Da0tJQ0FnSUNBZ0lDQmxibVFLQ2lBZ0lDQWdJQ0FnTFMwZ1QyNXNlU0JrYnlCRGIxUklJR2xtSUhkbElHRnlaU0JoWTNSMVlXeHNlU0JwYmlCamIyMWlZWFFLSUNBZ0lDQWdJQ0JwWmlCSmJrTnZiV0poZENncElHRnVaQ0J0Y1M1VVRFOHVUV1V1UVd4MFFXSnBiR2wwZVZKbFlXUjVLRGN3TlRBcEtDa2dkR2hsYmdvZ0lDQWdJQ0FnSUNBZ0lDQlhZV2wwVTNScGJHd29NekF3S1FvZ0lDQWdJQ0FnSUNBZ0lDQnRjUzVqYldSbUtDY3ZkR0Z5WjJWMElHbGtJQ1ZrSnl3Z2JYRXVWRXhQTGsxbExrbEVLQ2tnYjNJZ01Da0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTWpBd0tRb2dJQ0FnSUNBZ0lDQWdJQ0JPYjNSbExrbHVabThvSjFWemFXNW5JRU52VkVnZ1FVRWdkRzhnZDJsd1pTQndaWEp6YjI1aGJDQmhaMmR5YnlBb2FXNGdZMjl0WW1GMEtTNG5LUW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWpiV1FvSnk5aGJIUWdZV04wSURjd05UQW5LUW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWtaV3hoZVNnek5UQXdMQ0JtZFc1amRHbHZiaWdwSUhKbGRIVnliaUJ1YjNRZ2JYRXVWRXhQTGsxbExrTmhjM1JwYm1jdVNVUW9LU0JsYm1RcENpQWdJQ0FnSUNBZ1pXNWtDZ29nSUNBZ0lDQWdJQzB0SUVGMGRHVnRjSFFnZEc4Z2MzVnpjR1Z1WkFvZ0lDQWdJQ0FnSUZkaGFYUlRkR2xzYkNnME1EQXBDaUFnSUNBZ0lDQWdhV1lnYlhFdVZFeFBMazFsTGtGc2RFRmlhV3hwZEhsU1pXRmtlU2d4TnpZcEtDa2diM0lnYlhFdVZFeFBMazFsTGtGc2RFRmlhV3hwZEhsU1pXRmtlU2duVTNWemNHVnVaQ0JOYVc1cGIyNG5LU2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnVG05MFpTNUpibVp2S0NkVGRYTndaVzVrYVc1bklFMXBibWx2YnVLQXBpY3BDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDJGc2RDQmhZM1FnTVRjMkp5a0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTlRBd0tRb2dJQ0FnSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2d6TURBd0xDQm1kVzVqZEdsdmJpZ3BJSEpsZEhWeWJpQnViM1FnYlhFdVZFeFBMazFsTGtOaGMzUnBibWN1U1VRb0tTQmxibVFwQ2lBZ0lDQWdJQ0FnWlc1a0Nnb2dJQ0FnSUNBZ0lHbG1JQ2h0Y1M1VVRFOHVUV1V1VUdWMExrbEVLQ2tnYjNJZ01Da2dQVDBnTUNCMGFHVnVDaUFnSUNBZ0lDQWdJQ0FnSUU1dmRHVXVTVzVtYnlnblVHVjBJSE4xYzNCbGJtUmxaQzRuS1FvZ0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2RISjFaUW9nSUNBZ0lDQWdJR1Z1WkFvS0lDQWdJQ0FnSUNBdExTQlNaV1J2SUhSb1pTQmxiblJwY21VZ2MyVnhkV1Z1WTJVZ2RXNTBhV3dnYzNWalkyVnpjeTRLSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2d5TURBcENpQWdJQ0JsYm1RS0NpQWdJQ0J5WlhSMWNtNGdLQ2h0Y1M1VVRFOHVUV1V1VUdWMExrbEVLQ2tnYjNJZ01Da2dQVDBnTUNrS1pXNWtDZ290TFNCRGIzSmxJRzFoYm1FZ2JHOXZjRG9nYzNWdGJXOXVJRzF2Ym5OMFpYSWdjR1YwSUNoblpXMGdPQ2tnSmlCeVpXTnNZV2x0SUhWdWRHbHNJRGsxSlNCdFlXNWhMZ3BzYjJOaGJDQm1kVzVqZEdsdmJpQlNaV05zWVdsdFRXRnVZU2dwQ2lBZ0lDQk9iM1JsTGtsdVptOG9KMDFoYm1FZ1RHOXZjQ0JUZEdGeWRHVmtKeWtLSUNBZ0lHMXhMbU50WkNnbkwzTnhkV1ZzWTJnZ0wySmxaWEJ2Ym5SbGJHeHpJRzltWmljcENnb2dJQ0FnZDJocGJHVWdLRzF4TGxSTVR5NU5aUzVRWTNSTllXNWhLQ2tnYjNJZ01UQXdLU0E4SURrMUlHUnZDaUFnSUNBZ0lDQWdhV1lnYlhFdVZFeFBMa04xY25OdmNpNUpSQ2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVkyMWtLQ2N2WVhWMGIybHVkbVZ1ZEc5eWVTY3BDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RJd01EQXBDaUFnSUNBZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDJGMWRHOXBiblpsYm5SdmNua25LUW9nSUNBZ0lDQWdJR1Z1WkFvS0lDQWdJQ0FnSUNCcFppQW9iWEV1VkV4UExrMWxMbEJqZEUxaGJtRW9LU0J2Y2lBeE1EQXBJRHdnT0NCaGJtUWdiWEV1VkV4UExrMWxMbE53Wld4c1VtVmhaSGtvUjJGMGFHVnlUV0Z1WVZOd1pXeHNLU2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnVjJGcGRGTjBhV3hzS0RRd01Da0tJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVkyMWtaaWduTDJOaGMzUWdJaVZ6SWljc0lFZGhkR2hsY2sxaGJtRlRjR1ZzYkNrS0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WkdWc1lYa29NakF3TURBc0lHWjFibU4wYVc5dUtDa2djbVYwZFhKdUlHMXhMbFJNVHk1TlpTNURZWE4wYVc1bkxrbEVLQ2tnUFQwZ2JtbHNJR1Z1WkNrS0NpQWdJQ0FnSUNBZ1pXeHpaV2xtSUNodGNTNVVURTh1VFdVdVEzVnljbVZ1ZEUxaGJtRW9LU0J2Y2lBd0tTQThJQ2h0Y1M1VVRFOHVVM0JsYkd3b1RXOXVjM1JsY2xOMWJXMXZibWx1WjFOd1pXeHNLUzVOWVc1aEtDa2diM0lnTUNrZ2RHaGxiZ29nSUNBZ0lDQWdJQ0FnSUNCcFppQnRjUzVVVEU4dVRXVXVVM1JoYm1ScGJtY29LU0JoYm1RZ2JtOTBJRzF4TGxSTVR5NU5aUzVEWVhOMGFXNW5Ma2xFS0NrZ2RHaGxiaUJ0Y1M1VVRFOHVUV1V1VTJsMEtDa2daVzVrQ2lBZ0lDQWdJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEWXdOVEFwQ2dvZ0lDQWdJQ0FnSUdWc2MyVUtJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ2JYRXVWRXhQTGsxbExsTnBkSFJwYm1jb0tTQjBhR1Z1SUcxeExsUk1UeTVOWlM1VGRHRnVaQ2dwSUdWdVpBb2dJQ0FnSUNBZ0lDQWdJQ0J0Y1M1a1pXeGhlU2d5TlRBcENnb2dJQ0FnSUNBZ0lDQWdJQ0F0TFNCRmJuTjFjbVVnYzNCbGJHd2dhVzRnWjJWdElEZ0tJQ0FnSUNBZ0lDQWdJQ0FnYkc5allXd2dZV04wZFdGc1IyVnRJRDBnUlc1emRYSmxVM0JsYkd4SmJrZGxiU2hOYjI1emRHVnlVM1Z0Ylc5dWFXNW5VM0JsYkd3c0lFMXBjMk5UY0dWc2JFZGxiU2tLSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdibTkwSUdGamRIVmhiRWRsYlNCMGFHVnVDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQk9iM1JsTGtsdVptOG9KME52ZFd4a0lHNXZkQ0JzYjJGa0lFMXZibk4wWlhJZ1UzVnRiVzl1YVc1bklHbHVkRzhnWjJWdElDVmtPeUJsZUdsMGFXNW5JRzFoYm1FZ2JHOXZjQzRuTENCTmFYTmpVM0JsYkd4SFpXMHBDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmljbVZoYXdvZ0lDQWdJQ0FnSUNBZ0lDQmxibVFLQ2lBZ0lDQWdJQ0FnSUNBZ0lDMHRJRU5oYzNRZ1RXOXVjM1JsY2lCVGRXMXRiMjVwYm1jS0lDQWdJQ0FnSUNBZ0lDQWdWMkZwZEZOMGFXeHNLRFF3TUNrS0lDQWdJQ0FnSUNBZ0lDQWdhV1lnYlhFdVZFeFBMazFsTGxOd1pXeHNVbVZoWkhrb1RXOXVjM1JsY2xOMWJXMXZibWx1WjFOd1pXeHNLU2dwSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHMXhMbU50WkdZb0p5OWpZWE4wSUNWa0p5d2dZV04wZFdGc1IyVnRLUW9nSUNBZ0lDQWdJQ0FnSUNCbGJtUUtJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTnpBd01Dd2dablZ1WTNScGIyNG9LU0J5WlhSMWNtNGdibTkwSUcxeExsUk1UeTVOWlM1RFlYTjBhVzVuTGtsRUtDa2daVzVrS1FvZ0lDQWdJQ0FnSUNBZ0lDQnRjUzVrWld4aGVTZ3pNREFwQ2dvZ0lDQWdJQ0FnSUNBZ0lDQXRMU0JTWldOc1lXbHRJR2x0YldWa2FXRjBaV3g1SUdsbUlHRWdjR1YwSUdseklIVndDaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaHRjUzVVVEU4dVRXVXVVR1YwTGtsRUtDa2diM0lnTUNrZ1BpQXdJR0Z1WkNCU1pXTnNZV2x0U1hSbGJTQjBhR1Z1Q2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JYWVdsMFUzUnBiR3dvTWpBd0tRb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2JYRXVZMjFrWmlnbkwzVnpaV2wwWlcwZ0pYTW5MQ0JTWldOc1lXbHRTWFJsYlNrS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUcxeExtUmxiR0Y1S0RVd01Da0tJQ0FnSUNBZ0lDQWdJQ0FnWlc1a0NpQWdJQ0FnSUNBZ1pXNWtDZ29nSUNBZ0lDQWdJRzF4TG1SbGJHRjVLRFV3S1FvZ0lDQWdaVzVrQ2dvZ0lDQWdUbTkwWlM1SmJtWnZLQ2ROWVc1aElFeHZiM0FnUlc1a1pXUW5LUW9nSUNBZ0xTMGdabWx1WVd3Z1kyeGxZVzUxY0RvZ2FXWWdkR1Z0Y0NCd1pYUWdjM1JwYkd3Z2RYQXNJSEpsWTJ4aGFXMGdkVzUwYVd3Z1oyOXVaUW9nSUNBZ2QyaHBiR1VnS0cxeExsUk1UeTVOWlM1UVpYUXVTVVFvS1NCdmNpQXdLU0ErSURBZ1pHOEtJQ0FnSUNBZ0lDQnRjUzVqYldSbUtDY3ZkWE5sYVhSbGJTQWxjeWNzSUZKbFkyeGhhVzFKZEdWdEtRb2dJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEVXdNQ2tLSUNBZ0lHVnVaQXBsYm1RS0NpMHRJRWx1YVhRZ2MzQmxiR3h6TDJsMFpXMXpDbXh2WTJGc0lHWjFibU4wYVc5dUlFbHVhWFFvS1FvZ0lDQWdRMmhsWTJ0UWJIVm5hVzRvSjAxUk1saEJjM05wYzNRbktRb2dJQ0FnUTJobFkydFFiSFZuYVc0b0owMVJNa0ZrZGxCaGRHZ25LUW9nSUNBZ1EyaGxZMnRRYkhWbmFXNG9KMDFSTWsxdmRtVlZkR2xzY3ljcENpQWdJQ0JEYUdWamExQnNkV2RwYmlnblRWRXlRbTk0Y2ljcENnb2dJQ0FnVFc5dWMzUmxjbE4xYlcxdmJtbHVaeUE5SUhzS0lDQWdJQ0FnSUNBaVRXOXVjM1JsY2lCVGRXMXRiMjVwYm1jZ1dGWWlMQW9nSUNBZ0lDQWdJQ0pOYjI1emRHVnlJRk4xYlcxdmJtbHVaeUJZU1ZZaUxBb2dJQ0FnSUNBZ0lDSk5iMjV6ZEdWeUlGTjFiVzF2Ym1sdVp5QllTVWxKSWl3S0lDQWdJSDBLSUNBZ0lFMXZibk4wWlhKVGRXMXRiMjVwYm1kVGNHVnNiQ0E5SUVOb2IyOXpaVUZpYVd4cGRIa29UVzl1YzNSbGNsTjFiVzF2Ym1sdVp5a0tJQ0FnSUdsbUlHNXZkQ0JOYjI1emRHVnlVM1Z0Ylc5dWFXNW5VM0JsYkd3Z2RHaGxiZ29nSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduUVNCdGIyNXpkR1Z5SUhOMWJXMXZibWx1WnlCemNHVnNiQ0JwY3lCdWIzUWdZWFpoYVd4aFlteGxKeWtLSUNBZ0lDQWdJQ0J5WlhSMWNtNGdabUZzYzJVS0lDQWdJR1Z1WkFvS0lDQWdJQzB0SUZWd1pHRjBaV1FnUjJGMGFHVnlJR3hwYm1VZ0tHbHVZMngxWkdWeklHeGxkbVZzSURFeU5Ta0tJQ0FnSUVkaGRHaGxjazFoYm1FZ1BTQjdDaUFnSUNBZ0lDQWdJa2RoZEdobGNpQmFaV0ZzSWl3S0lDQWdJQ0FnSUNBaVIyRjBhR1Z5SUZacFoyOXlJaXdLSUNBZ0lDQWdJQ0FpUjJGMGFHVnlJRkJ2ZEdWdVkza2lMQW9nSUNBZ2ZRb2dJQ0FnUjJGMGFHVnlUV0Z1WVZOd1pXeHNJRDBnUTJodmIzTmxRV0pwYkdsMGVTaEhZWFJvWlhKTllXNWhLUW9nSUNBZ2FXWWdibTkwSUVkaGRHaGxjazFoYm1GVGNHVnNiQ0IwYUdWdUNpQWdJQ0FnSUNBZ1RtOTBaUzVKYm1adktDZEJJR2RoZEdobGNpQnRZVzVoSUhOd1pXeHNJR2x6SUc1dmRDQmhkbUZwYkdGaWJHVW5LUW9nSUNBZ0lDQWdJSEpsZEhWeWJpQm1ZV3h6WlFvZ0lDQWdaVzVrQ2dvZ0lDQWdVbVZqYkdGcGJWTmxkQ0E5SUhzS0lDQWdJQ0FnSUNBaVUzUmhabVlnYjJZZ1JXeGxiV1Z1ZEdGc0lFMWhjM1JsY25rNklFVmhjblJvSWl3S0lDQWdJQ0FnSUNBaVUzUmhabVlnYjJZZ1JXeGxiV1Z1ZEdGc0lFMWhjM1JsY25rNklFWnBjbVVpTEFvZ0lDQWdJQ0FnSUNKVGRHRm1aaUJ2WmlCRmJHVnRaVzUwWVd3Z1RXRnpkR1Z5ZVRvZ1FXbHlJaXdLSUNBZ0lDQWdJQ0FpVTNSaFptWWdiMllnUld4bGJXVnVkR0ZzSUUxaGMzUmxjbms2SUZkaGRHVnlJaXdLSUNBZ0lDQWdJQ0FpUW5KdmIyMGdiMllnVkhKcGJHOXVJaXdLSUNBZ0lDQWdJQ0FpUVc1amFXVnVkQ0JVYjNKamFDQnZaaUJCYkc1aElpd0tJQ0FnSUNBZ0lDQWlSMlZ0YldWa0lFZHNiM1psY3lCdlppQkhkV2xzWlNJc0NpQWdJQ0FnSUNBZ0lrZHNiM1psY3lCdlppQkVZWEpySUZOMWJXMXZibWx1WnlJc0NpQWdJQ0FnSUNBZ0lsTm9iM1psYkNCdlppQlFiMjU2SWl3S0lDQWdJQ0FnSUNBaVUzUmxhVzRnYjJZZ1ZXeHBjM05oSWl3S0lDQWdJQ0FnSUNBaVZHOXlZMmdnYjJZZ1FXeHVZU0lzQ2lBZ0lDQjlDaUFnSUNCU1pXTnNZV2x0U1hSbGJTQTlJRU5vYjI5elpVbDBaVzBvVW1WamJHRnBiVk5sZENrS0lDQWdJR2xtSUc1dmRDQlNaV05zWVdsdFNYUmxiU0IwYUdWdUNpQWdJQ0FnSUNBZ1RtOTBaUzVKYm1adktDZE9ieUJ5WldOc1lXbHRJR2wwWlcwZ1ptOTFibVFnYVc0Z2FXNTJaVzUwYjNKNUp5a0tJQ0FnSUNBZ0lDQnlaWFIxY200Z1ptRnNjMlVLSUNBZ0lHVnVaQW9LSUNBZ0lISmxkSFZ5YmlCMGNuVmxDbVZ1WkFvS0xTMGdUV0ZwYmlCeWIzVjBhVzVsSUNodFpYSm5aV1FnYVc1MGJ5Qk1SVTBnWVdOMGFXOXVLUXBzYjJOaGJDQm1kVzVqZEdsdmJpQlNkVzVOYjI1emRHVnlUV0Z1WVNncENpQWdJQ0JwWmlCdGNTNVVURTh1VFdVdVEyeGhjM011VTJodmNuUk9ZVzFsS0NrZ2ZqMGdKMDFCUnljZ2RHaGxiZ29nSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduVFc5dWMzUmxjazFoYm1FZ2IyNXNlU0IzYjNKcmN5Qm1iM0lnVFdGblpTQmphR0Z5WVdOMFpYSnpKeWtLSUNBZ0lDQWdJQ0J5WlhSMWNtNGdabUZzYzJVS0lDQWdJR1Z1WkFvZ0lDQWdhV1lnS0cxeExsUk1UeTVOWlM1UVkzUk5ZVzVoS0NrZ2IzSWdNVEF3S1NBK0lEazFJSFJvWlc0S0lDQWdJQ0FnSUNCT2IzUmxMa2x1Wm04b0owMWhibUVnYVhNZ2JtVmhjbXg1SUdaMWJHdzdJRzV2ZEdocGJtY2dkRzhnWkc4bktRb2dJQ0FnSUNBZ0lISmxkSFZ5YmlCbVlXeHpaUW9nSUNBZ1pXNWtDaUFnSUNCcFppQnViM1FnU1c1cGRDZ3BJSFJvWlc0S0lDQWdJQ0FnSUNCT2IzUmxMa2x1Wm04b0owbHVhWFJwWVd4cGVtRjBhVzl1SUhWdWMzVmpZMlZ6YzJaMWJDY3BDaUFnSUNBZ0lDQWdjbVYwZFhKdUlHWmhiSE5sQ2lBZ0lDQmxibVFLQ2lBZ0lDQnRjUzVqYldRb0p5OXpjWFZsYkdOb0lDOWtiMk52YlcxaGJtUWdMMkp2ZUhJZ2NHRjFjMlVuS1FvZ0lDQWdiWEV1WkdWc1lYa29NekF3S1FvZ0lDQWdiWEV1WTIxa0tDY3ZjM0YxWld4amFDQXZZWFIwWVdOcklHOW1aaWNwQ2dvZ0lDQWdMUzBnWTJ4bFlYSWdZM1Z5YzI5eUNpQWdJQ0IzYUdsc1pTQnRjUzVVVEU4dVEzVnljMjl5TGtsRUtDa2daRzhLSUNBZ0lDQWdJQ0J0Y1M1amJXUW9KeTloZFhSdmFXNTJaVzUwYjNKNUp5a0tJQ0FnSUNBZ0lDQnRjUzVrWld4aGVTZzFNREFwQ2lBZ0lDQmxibVFLQ2lBZ0lDQXRMU0JKWmlCM1pTQmhiSEpsWVdSNUlHaGhkbVVnWVNCdFlXbHVJSEJsZEN3Z2MzVnpjR1Z1WkNCcGRDQkdTVkpUVkNBb1lteHZZMnRwYm1jcElHRnVaQ0J5WlcxbGJXSmxjaUIwYUdGMElIZGxJR1JwWkM0S0lDQWdJR2xtSUNodGNTNVVURTh1VFdVdVVHVjBMa2xFS0NrZ2IzSWdNQ2tnUGlBd0lIUm9aVzRLSUNBZ0lDQWdJQ0JPYjNSbExrbHVabThvSjFCeWFXMWhjbmtnYldGdVlTQnRaWFJvYjJRZ0tIZHBkR2dnY0dWMEtTY3BDaUFnSUNBZ0lDQWdiRzlqWVd3Z2MzVnpjR1Z1WkdWa1Qwc2dQU0JUZFhOd1pXNWtVSEpwYldGeWVWQmxkRjlDYkc5amEybHVaeWdwQ2lBZ0lDQWdJQ0FnYVdZZ2JtOTBJSE4xYzNCbGJtUmxaRTlMSUhSb1pXNEtJQ0FnSUNBZ0lDQWdJQ0FnVG05MFpTNUpibVp2S0NkVmJtRmliR1VnZEc4Z2MzVnpjR1Z1WkNCd1pYUWdjMkZtWld4NU95QmhZbTl5ZEdsdVp5NG5LUW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWpiV1FvSnk5emNYVmxiR05vSUM5a2IyTnZiVzFoYm1RZ0wySnZlSElnZFc1d1lYVnpaU2NwQ2lBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCbVlXeHpaUW9nSUNBZ0lDQWdJR1Z1WkFvZ0lDQWdJQ0FnSUdScFpGTjFjM0JsYm1STllXbHVVR1YwSUQwZ2RISjFaUW9nSUNBZ1pXeHpaUW9nSUNBZ0lDQWdJQzB0SUU1dkxYQmxkQ0JtWVd4c1ltRmphem9nWW5WcGJHUWdkRzhnT0NVZ2QybDBhQ0JIWVhSb1pYSWdiM0lnYzJsMGRHbHVad29nSUNBZ0lDQWdJRTV2ZEdVdVNXNW1ieWduVUhKcGJXRnllU0J0WVc1aElHMWxkR2h2WkNBb2JtOGdjR1YwS1NjcENpQWdJQ0FnSUNBZ2QyaHBiR1VnS0cxeExsUk1UeTVOWlM1UVkzUk5ZVzVoS0NrZ2IzSWdNQ2tnUENBNElHUnZDaUFnSUNBZ0lDQWdJQ0FnSUd4dlkyRnNJSEpoYm10T1lXMWxJRDBnYlhFdVZFeFBMbE53Wld4c0tFZGhkR2hsY2sxaGJtRlRjR1ZzYkNrdVVtRnVhMDVoYldVb0tRb2dJQ0FnSUNBZ0lDQWdJQ0JwWmlCdGNTNVVURTh1VFdVdVUzQmxiR3hTWldGa2VTaHlZVzVyVG1GdFpTa29LU0IwYUdWdUNpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCWFlXbDBVM1JwYkd3b05EQXdLUW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WTIxa1ppZ25MMk5oYzNRZ0lpVnpJaWNzSUhKaGJtdE9ZVzFsS1FvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYlhFdVpHVnNZWGtvTWpBd01EQXNJR1oxYm1OMGFXOXVLQ2tnY21WMGRYSnVJRzV2ZENCdGNTNVVURTh1VFdVdVEyRnpkR2x1Wnk1SlJDZ3BJR1Z1WkNrS0lDQWdJQ0FnSUNBZ0lDQWdaV3h6WldsbUlIZHZjbXRwYm1kVGRHRjBaWE5iYlhFdVZFeFBMazFsTGtOdmJXSmhkRk4wWVhSbEtDa2diM0lnSnlkZElIUm9aVzRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR2xtSUcxeExsUk1UeTVOWlM1VGRHRnVaR2x1WnlncElHRnVaQ0J1YjNRZ2JYRXVWRXhQTGsxbExrTmhjM1JwYm1jdVNVUW9LU0IwYUdWdUlHMXhMbFJNVHk1TlpTNVRhWFFvS1NCbGJtUUtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEWXdOVEFwQ2lBZ0lDQWdJQ0FnSUNBZ0lHVnVaQW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWtaV3hoZVNneE5UQXBDaUFnSUNBZ0lDQWdaVzVrQ2lBZ0lDQmxibVFLQ2lBZ0lDQXRMU0JTZFc0Z2JXRnVZU0JzYjI5d0lDaHpkVzF0YjI0dmNtVmpiR0ZwYlNrS0lDQWdJRkpsWTJ4aGFXMU5ZVzVoS0NrS0NpQWdJQ0F0TFNCU1pYTjBiM0psSUcxaGFXNGdjR1YwSUU5T1RGa2dhV1lnZDJVZ2NISmxkbWx2ZFhOc2VTQnpkWE53Wlc1a1pXUWdhWFFnZEdocGN5QnlkVzRnS0hCeVpYWmxiblJ6SUdsdVptbHVhWFJsSUd4dmIzQWdZV1owWlhJZ1pHVmhkR2dwTGdvZ0lDQWdhV1lnWkdsa1UzVnpjR1Z1WkUxaGFXNVFaWFFnZEdobGJnb2dJQ0FnSUNBZ0lFNXZkR1V1U1c1bWJ5Z25VbVZ6ZEc5eWFXNW5JRzFoYVc0Z2NHVjBJQ2gxYm5OMWMzQmxibVJwYm1jcEp5a0tJQ0FnSUNBZ0lDQjNhR2xzWlNBb2JYRXVWRXhQTGsxbExsQmxkQzVKUkNncElHOXlJREFwSUQwOUlEQWdaRzhLSUNBZ0lDQWdJQ0FnSUNBZ1YyRnBkRk4wYVd4c0tEUXdNQ2tLSUNBZ0lDQWdJQ0FnSUNBZ2JYRXVZMjFrS0NjdllXeDBJR0ZqZENBeE56WW5LUW9nSUNBZ0lDQWdJQ0FnSUNCdGNTNWtaV3hoZVNnMk5UQXdMQ0JtZFc1amRHbHZiaWdwSUhKbGRIVnliaUJ1YjNRZ2JYRXVWRXhQTGsxbExrTmhjM1JwYm1jdVNVUW9LU0JsYm1RcENpQWdJQ0FnSUNBZ0lDQWdJRzF4TG1SbGJHRjVLRE13TUNrS0lDQWdJQ0FnSUNCbGJtUUtJQ0FnSUNBZ0lDQXRMU0JKWmlCaElFMXZibk4wWlhJZ1UzVnRiVzl1YVc1bklIZGhjbkpwYjNJZ2NHVjBJSEJ2Y0hCbFpDQnBibk4wWldGa0xDQnlaV05zWVdsdElHRnVaQ0IwY25rZ1lXZGhhVzR1Q2lBZ0lDQWdJQ0FnZDJocGJHVWdLRzF4TGxSTVR5NU5aUzVRWlhRdVEyeGhjM011VG1GdFpTZ3BJRzl5SUNjbktTQTlQU0FuVjJGeWNtbHZjaWNnWkc4S0lDQWdJQ0FnSUNBZ0lDQWdhV1lnVW1WamJHRnBiVWwwWlcwZ2RHaGxiZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdiWEV1WTIxa1ppZ25MM1Z6WldsMFpXMGdKWE1uTENCU1pXTnNZV2x0U1hSbGJTa0tJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEVXdNQ2tLSUNBZ0lDQWdJQ0FnSUNBZ1pXeHpaUW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdZbkpsWVdzS0lDQWdJQ0FnSUNBZ0lDQWdaVzVrQ2lBZ0lDQWdJQ0FnSUNBZ0lIZG9hV3hsSUNodGNTNVVURTh1VFdVdVVHVjBMa2xFS0NrZ2IzSWdNQ2tnUFQwZ01DQmtid29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdWMkZwZEZOMGFXeHNLRFF3TUNrS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUcxeExtTnRaQ2duTDJGc2RDQmhZM1FnTVRjMkp5a0tJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtEWTFNREFzSUdaMWJtTjBhVzl1S0NrZ2NtVjBkWEp1SUc1dmRDQnRjUzVVVEU4dVRXVXVRMkZ6ZEdsdVp5NUpSQ2dwSUdWdVpDa0tJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHMXhMbVJsYkdGNUtETXdNQ2tLSUNBZ0lDQWdJQ0FnSUNBZ1pXNWtDaUFnSUNBZ0lDQWdaVzVrQ2lBZ0lDQmxiSE5sQ2lBZ0lDQWdJQ0FnVG05MFpTNUpibVp2S0NkT2J5QnpkWE53Wlc1a1pXUWdiV0ZwYmlCd1pYUWdkRzhnY21WemRHOXlaU0FvYkdsclpXeDVJSE4wWVhKMFpXUWdkMmwwYUNCdWJ5QndaWFFwTGljcENpQWdJQ0JsYm1RS0NpQWdJQ0J0Y1M1a1pXeGhlU2d6TURBcENpQWdJQ0J0Y1M1amJXUW9KeTl3WlhRZ2FHOXNaQ2NwQ2lBZ0lDQnRjUzVrWld4aGVTZ3pNREFwQ2lBZ0lDQnRjUzVqYldRb0p5OXpjWFZsYkdOb0lDOWtiMk52YlcxaGJtUWdMMkp2ZUhJZ2RXNXdZWFZ6WlNjcENpQWdJQ0J0Y1M1a1pXeGhlU2d6TURBcENpQWdJQ0JPYjNSbExrbHVabThvSjAxaGJtRWdjbTkxZEdsdVpTQmpiMjF3YkdWMFpTNGdUV0ZuWlNCdFlXNWhJRzV2ZHpvZ1hHRm5KWE1uTENCMGIzTjBjbWx1WnlodGNTNVVURTh1VFdVdVVHTjBUV0Z1WVNncEtTa0tJQ0FnSUcxeExtTnRaQ2duTDNOeGRXVnNZMmdnTDJKbFpYQnZiblJsYkd4eklHOXVKeWtLSUNBZ0lISmxkSFZ5YmlCMGNuVmxDbVZ1WkFvS2JHOWpZV3dnWm5WdVkzUnBiMjRnWVdOMGFXOXVLQ2tLSUNBZ0lDMHRJRkpsWjJsemRHVnlJSE53Wld4c1ltOXZheUJsZG1WdWRITWdLRXhGVFMxellXWmxLUW9nSUNBZ2JYRXVaWFpsYm5Rb0owSmxaMmx1VFdWdGIzSnBlbWx1Wnljc0lDSWpLaU5DWldkcGJtNXBibWNnZEc4Z2JXVnRiM0pwZW1VZ0l6RWpMaTR1SXlvaklpd2dSWFpsYm5SZlFtVm5hVzVOWlcxdmNtbDZhVzVuS1FvZ0lDQWdiWEV1WlhabGJuUW9KMFpwYm1semFFMWxiVzl5YVhwcGJtY25MQ0FpSXlvaldXOTFJR2hoZG1VZ1ptbHVhWE5vWldRZ2JXVnRiM0pwZW1sdVp5QWpNU01qS2lNaUxDQkZkbVZ1ZEY5RmJtUk5aVzF2Y21sNmFXNW5LUW9nSUNBZ2JYRXVaWFpsYm5Rb0owRmliM0owVFdWdGIzSnBlbWx1Wnljc0lDSWpLaU5CWW05eWRHbHVaeUJ0WlcxdmNtbDZZWFJwYjI0Z2IyWWdjM0JsYkd3dUl5b2pJaXdnUlhabGJuUmZSVzVrVFdWdGIzSnBlbWx1WnlrS0NpQWdJQ0JzYjJOaGJDQnZheXdnWlhKeUlEMGdjR05oYkd3b1VuVnVUVzl1YzNSbGNrMWhibUVwQ2lBZ0lDQnBaaUJ1YjNRZ2Iyc2dkR2hsYmlCT2IzUmxMa2x1Wm04b0oxeGhja1Z5Y205eU9seGhlQ0FsY3ljc0lIUnZjM1J5YVc1bktHVnljaWtwSUdWdVpBcGxibVFLQ25KbGRIVnliaUI3WTI5dVpHWjFibU05WTI5dVpHbDBhVzl1TENCaFkzUnBiMjVtZFc1alBXRmpkR2x2Ym4wSyIsCn0=

LEM Endless Mana
Lua:
local mq = require('mq')

---@return boolean @Returns true if the action should fire, otherwise false.
local function condition()
    local my_class = mq.TLO.Me.Class.ShortName()
    local my_mana = mq.TLO.Me.PctMana()
    local check_paused = mq.TLO.CWTN.Paused()
    local mm_status = mq.TLO.Lua.Script('MMbrute').Status()
    return my_class == 'MAG' and my_mana < 20 and mm_status ~= 'RUNNING' and check_paused == false
end

-----------------------------------------------------------------------
-- Everything below runs inside LEM's action() when the condition is met
-----------------------------------------------------------------------

-- Lightweight logger (self-contained)
local Note = { prefix = 'MonsterMana', loglevel = 'info' }
function Note.Info(fmt, ...) print(('\ag[%s]\ax '..fmt):format(Note.prefix, ...)) end

-- State / config
local workingStates = { Active=true, Cooldown=true, Resting=true }
local MonsterSummoning, MonsterSummoningSpell
local GatherMana, GatherManaSpell
local ReclaimSet, ReclaimItem
local MiscSpellGem = 8 -- using gem 8
local IsMemorizing = false
local didSuspendMainPet = false -- NEW: track whether we actually suspended a main pet this run

-- -----------------------------
-- Helpers
-- -----------------------------
local function CheckPlugin(plugin)
    if not mq.TLO.Plugin(plugin)() then
        mq.cmdf('/squelch /plugin %s noauto', plugin)
        Note.Info('\aw%s\ax not detected. Loading…', plugin)
    end
end

-- Simple movement check: only your avatar’s motion.
local function IsMoving()
    return mq.TLO.Me.Moving() or ((mq.TLO.Me.Speed() or 0) > 0)
end

-- Wait until we’ve been NOT moving for a continuous window (ms). No attempt limit.
local function WaitStill(min_ms)
    min_ms = min_ms or 400
    local stillStart = nil
    while true do
        if IsMoving() then
            stillStart = nil
        else
            stillStart = stillStart or mq.gettime()
            if (mq.gettime() - stillStart) >= min_ms then return true end
        end
        mq.delay(50)
    end
end

-- Robust “am I in combat?” check
local function InCombat()
    local cs = tostring(mq.TLO.Me.CombatState() or '')
    if cs ~= '' and cs:upper() == 'COMBAT' then return true end
    if mq.TLO.Me.Combat and mq.TLO.Me.Combat() then return true end
    return false
end

local function ChooseAbility(set)
    local chosenSpell, highestLevel = nil, 0
    for _, name in ipairs(set) do
        local s = mq.TLO.Spell(name)
        local lvl, rank = s.Level(), s.RankName()
        if rank and mq.TLO.Me.Book(rank)() and lvl > highestLevel then
            chosenSpell = (mq.TLO.Me.SpellRankCap() > 1) and s.RankName() or s.BaseName()
            highestLevel = lvl
        end
    end
    return chosenSpell
end

local function ChooseItem(set)
    for _, name in ipairs(set) do
        if mq.TLO.FindItemCount(name)() > 0 then return name end
    end
end

-- Spellbook events (registered inside action())
local function Event_BeginMemorizing(_, _) IsMemorizing = true end
local function Event_EndMemorizing(_, _) IsMemorizing = false end

-- Ensure spell is in a specific gem (blocking, no attempt limit). Only starts when stationary.
local function EnsureSpellInGem(spellToMem, gem)
    gem = gem or MiscSpellGem
    while true do
        if mq.TLO.Me.Gem(spellToMem)() == gem then return gem end
        local rn = mq.TLO.Spell(spellToMem).RankName()
        if not rn or not mq.TLO.Me.Book(rn)() then
            Note.Info('Cannot memorize (not in book): %s', tostring(spellToMem))
            return
        end
        if not mq.TLO.Me.Gem(gem)() and gem ~= MiscSpellGem then gem = MiscSpellGem end
        WaitStill(600)
        Note.Info('\agMemming\ax "%s" into gem %d', rn, gem)
        mq.cmdf('/memspell %d "%s"', gem, rn)
        mq.delay(2000, function() return IsMemorizing or mq.TLO.Me.Gem(gem).Name() == rn end)
        mq.delay(10000, function() return mq.TLO.Me.Gem(gem).Name() == rn or not IsMemorizing end)
        if mq.TLO.Me.Gem(gem).Name() == rn then return gem end
    end
end

-- Pet proximity helpers (with optional timeout to prevent hangs)
local function PetNear(maxDist) return (mq.TLO.Me.Pet.Distance() or 9999) <= (maxDist or 12) end
local function WaitPetNear(maxDist, timeout_ms)
    maxDist = maxDist or 12
    local start = mq.gettime()
    while true do
        if (mq.TLO.Me.Pet.ID() or 0) == 0 then return false end
        if PetNear(maxDist) then return true end
        if timeout_ms and (mq.gettime() - start) >= timeout_ms then return PetNear(maxDist) end
        mq.delay(50)
    end
end

-- Suspend pet with full sequence every pass.
-- Only use CoTH AA (7050) if we are IN COMBAT.
-- Returns TRUE only if the pet ends up suspended (ID == 0).
local function SuspendPrimaryPet_Blocking()
    local origID = mq.TLO.Me.Pet.ID() or 0
    if origID == 0 then return false end -- nothing to suspend

    Note.Info('Storing Pet (ID %s)', tostring(origID))

    while (mq.TLO.Me.Pet.ID() or 0) > 0 do
        -- Full sequence: ghold -> spellhold -> back -> Summon Companion (1215) -> (CoTH if IN COMBAT) -> suspend
        WaitStill(400)
        mq.cmd('/pet ghold on')    ; mq.delay(300)
        mq.cmd('/pet spellhold on'); mq.delay(300)
        mq.cmd('/pet back')        ; mq.delay(300)

        -- Summon Companion RIGHT BEFORE suspending, if ready (don’t block for CD)
        if mq.TLO.Me.AltAbilityReady(1215)() or mq.TLO.Me.AltAbilityReady('Summon Companion')() then
            WaitStill(300)
            mq.cmd('/alt act 1215')
            mq.delay(3500, function() return not mq.TLO.Me.Casting.ID() end)
            WaitPetNear(12, 3000)
        end

        -- Only do CoTH if we are actually in combat
        if InCombat() and mq.TLO.Me.AltAbilityReady(7050)() then
            WaitStill(300)
            mq.cmdf('/target id %d', mq.TLO.Me.ID() or 0)
            mq.delay(200)
            Note.Info('Using CoTH AA to wipe personal aggro (in combat).')
            mq.cmd('/alt act 7050')
            mq.delay(3500, function() return not mq.TLO.Me.Casting.ID() end)
        end

        -- Attempt to suspend
        WaitStill(400)
        if mq.TLO.Me.AltAbilityReady(176)() or mq.TLO.Me.AltAbilityReady('Suspend Minion')() then
            Note.Info('Suspending Minion…')
            mq.cmd('/alt act 176')
            mq.delay(500)
            mq.delay(3000, function() return not mq.TLO.Me.Casting.ID() end)
        end

        if (mq.TLO.Me.Pet.ID() or 0) == 0 then
            Note.Info('Pet suspended.')
            return true
        end

        -- Redo the entire sequence until success.
        mq.delay(200)
    end

    return ((mq.TLO.Me.Pet.ID() or 0) == 0)
end

-- Core mana loop: summon monster pet (gem 8) & reclaim until 95% mana.
local function ReclaimMana()
    Note.Info('Mana Loop Started')
    mq.cmd('/squelch /beepontells off')

    while (mq.TLO.Me.PctMana() or 100) < 95 do
        if mq.TLO.Cursor.ID() then
            mq.cmd('/autoinventory')
            mq.delay(2000)
            mq.cmd('/autoinventory')
        end

        if (mq.TLO.Me.PctMana() or 100) < 8 and mq.TLO.Me.SpellReady(GatherManaSpell)() then
            WaitStill(400)
            mq.cmdf('/cast "%s"', GatherManaSpell)
            mq.delay(20000, function() return mq.TLO.Me.Casting.ID() == nil end)

        elseif (mq.TLO.Me.CurrentMana() or 0) < (mq.TLO.Spell(MonsterSummoningSpell).Mana() or 0) then
            if mq.TLO.Me.Standing() and not mq.TLO.Me.Casting.ID() then mq.TLO.Me.Sit() end
            mq.delay(6050)

        else
            if mq.TLO.Me.Sitting() then mq.TLO.Me.Stand() end
            mq.delay(250)

            -- Ensure spell in gem 8
            local actualGem = EnsureSpellInGem(MonsterSummoningSpell, MiscSpellGem)
            if not actualGem then
                Note.Info('Could not load Monster Summoning into gem %d; exiting mana loop.', MiscSpellGem)
                break
            end

            -- Cast Monster Summoning
            WaitStill(400)
            if mq.TLO.Me.SpellReady(MonsterSummoningSpell)() then
                mq.cmdf('/cast %d', actualGem)
            end
            mq.delay(7000, function() return not mq.TLO.Me.Casting.ID() end)
            mq.delay(300)

            -- Reclaim immediately if a pet is up
            if (mq.TLO.Me.Pet.ID() or 0) > 0 and ReclaimItem then
                WaitStill(200)
                mq.cmdf('/useitem %s', ReclaimItem)
                mq.delay(500)
            end
        end

        mq.delay(50)
    end

    Note.Info('Mana Loop Ended')
    -- final cleanup: if temp pet still up, reclaim until gone
    while (mq.TLO.Me.Pet.ID() or 0) > 0 do
        mq.cmdf('/useitem %s', ReclaimItem)
        mq.delay(500)
    end
end

-- Init spells/items
local function Init()
    CheckPlugin('MQ2XAssist')
    CheckPlugin('MQ2AdvPath')
    CheckPlugin('MQ2MoveUtils')
    CheckPlugin('MQ2Boxr')

    MonsterSummoning = {
        "Monster Summoning XV",
        "Monster Summoning XIV",
        "Monster Summoning XIII",
    }
    MonsterSummoningSpell = ChooseAbility(MonsterSummoning)
    if not MonsterSummoningSpell then
        Note.Info('A monster summoning spell is not available')
        return false
    end

    -- Updated Gather line (includes level 125)
    GatherMana = {
        "Gather Zeal",
        "Gather Vigor",
        "Gather Potency",
    }
    GatherManaSpell = ChooseAbility(GatherMana)
    if not GatherManaSpell then
        Note.Info('A gather mana spell is not available')
        return false
    end

    ReclaimSet = {
        "Staff of Elemental Mastery: Earth",
        "Staff of Elemental Mastery: Fire",
        "Staff of Elemental Mastery: Air",
        "Staff of Elemental Mastery: Water",
        "Broom of Trilon",
        "Ancient Torch of Alna",
        "Gemmed Gloves of Guile",
        "Gloves of Dark Summoning",
        "Shovel of Ponz",
        "Stein of Ulissa",
        "Torch of Alna",
    }
    ReclaimItem = ChooseItem(ReclaimSet)
    if not ReclaimItem then
        Note.Info('No reclaim item found in inventory')
        return false
    end

    return true
end

-- Main routine (merged into LEM action)
local function RunMonsterMana()
    if mq.TLO.Me.Class.ShortName() ~= 'MAG' then
        Note.Info('MonsterMana only works for Mage characters')
        return false
    end
    if (mq.TLO.Me.PctMana() or 100) > 95 then
        Note.Info('Mana is nearly full; nothing to do')
        return false
    end
    if not Init() then
        Note.Info('Initialization unsuccessful')
        return false
    end

    mq.cmd('/squelch /docommand /boxr pause')
    mq.delay(300)
    mq.cmd('/squelch /attack off')

    -- clear cursor
    while mq.TLO.Cursor.ID() do
        mq.cmd('/autoinventory')
        mq.delay(500)
    end

    -- If we already have a main pet, suspend it FIRST (blocking) and remember that we did.
    if (mq.TLO.Me.Pet.ID() or 0) > 0 then
        Note.Info('Primary mana method (with pet)')
        local suspendedOK = SuspendPrimaryPet_Blocking()
        if not suspendedOK then
            Note.Info('Unable to suspend pet safely; aborting.')
            mq.cmd('/squelch /docommand /boxr unpause')
            return false
        end
        didSuspendMainPet = true
    else
        -- No-pet fallback: build to 8% with Gather or sitting
        Note.Info('Primary mana method (no pet)')
        while (mq.TLO.Me.PctMana() or 0) < 8 do
            local rankName = mq.TLO.Spell(GatherManaSpell).RankName()
            if mq.TLO.Me.SpellReady(rankName)() then
                WaitStill(400)
                mq.cmdf('/cast "%s"', rankName)
                mq.delay(20000, function() return not mq.TLO.Me.Casting.ID() end)
            elseif workingStates[mq.TLO.Me.CombatState() or ''] then
                if mq.TLO.Me.Standing() and not mq.TLO.Me.Casting.ID() then mq.TLO.Me.Sit() end
                mq.delay(6050)
            end
            mq.delay(150)
        end
    end

    -- Run mana loop (summon/reclaim)
    ReclaimMana()

    -- Restore main pet ONLY if we previously suspended it this run (prevents infinite loop after death).
    if didSuspendMainPet then
        Note.Info('Restoring main pet (unsuspending)')
        while (mq.TLO.Me.Pet.ID() or 0) == 0 do
            WaitStill(400)
            mq.cmd('/alt act 176')
            mq.delay(6500, function() return not mq.TLO.Me.Casting.ID() end)
            mq.delay(300)
        end
        -- If a Monster Summoning warrior pet popped instead, reclaim and try again.
        while (mq.TLO.Me.Pet.Class.Name() or '') == 'Warrior' do
            if ReclaimItem then
                mq.cmdf('/useitem %s', ReclaimItem)
                mq.delay(500)
            else
                break
            end
            while (mq.TLO.Me.Pet.ID() or 0) == 0 do
                WaitStill(400)
                mq.cmd('/alt act 176')
                mq.delay(6500, function() return not mq.TLO.Me.Casting.ID() end)
                mq.delay(300)
            end
        end
    else
        Note.Info('No suspended main pet to restore (likely started with no pet).')
    end

    mq.delay(300)
    mq.cmd('/pet hold')
    mq.delay(300)
    mq.cmd('/squelch /docommand /boxr unpause')
    mq.delay(300)
    Note.Info('Mana routine complete. Mage mana now: \ag%s', tostring(mq.TLO.Me.PctMana()))
    mq.cmd('/squelch /beepontells on')
    return true
end

local function action()
    -- Register spellbook events (LEM-safe)
    mq.event('BeginMemorizing', "#*#Beginning to memorize #1#...#*#", Event_BeginMemorizing)
    mq.event('FinishMemorizing', "#*#You have finished memorizing #1##*#", Event_EndMemorizing)
    mq.event('AbortMemorizing', "#*#Aborting memorization of spell.#*#", Event_EndMemorizing)

    local ok, err = pcall(RunMonsterMana)
    if not ok then Note.Info('\arError:\ax %s', tostring(err)) end
end

return {condfunc=condition, actionfunc=action}
 
Release Endless Mana for MQ2Mage

Users who are viewing this thread

Back
Top
Cart