mirror of
https://github.com/EQMacEmu/quests
synced 2026-08-21 00:23:04 -04:00
505 lines
14 KiB
Lua
505 lines
14 KiB
Lua
local INSTANCE_CONTROLLER_TYPE = 223077; -- _
|
|
local EVENTS_CONTROLLER_TYPE = 223078; -- _
|
|
local CAZIC_TYPE = 223004;
|
|
local BERTOX_TYPE = 223005;
|
|
local RZ_TYPE = 223006;
|
|
local INNO_TYPE = 223007;
|
|
|
|
local CRYPT_TYPE = 223147; -- Guardian_of_the_Crypt
|
|
local PRESTILENCE_TYPE = 223145; -- Guardian_Knight_of_Pestilence
|
|
local CASTER_TYPE = 223146; -- A_Firebone_Caster
|
|
local AMYGDALAN_TYPE = 223149; -- Amygdalan_knight
|
|
local PHOBO_TYPE = 223148; -- phoboplasm
|
|
local ABHORRENT_TYPE = 223153; -- an_abhorrent
|
|
local CLERIC_TYPE = 223152; -- Cleric_of_Innoruuk
|
|
local BRAWLER_TYPE = 223151; -- Decorin_Brawler
|
|
local FIERCE_TYPE = 223150; -- A_Fierce_War_Boar
|
|
|
|
local BOAR_TYPE = 223155; -- a_summoned_boar
|
|
local MINION_TYPE = 223154; -- a_summoned_minion
|
|
|
|
local GUARDIAN_TYPE = 223156; -- guardian_of_the_dark_prince
|
|
local HATEBRINGER_TYPE = 223157; -- a_hatebringer_of_Innoruuk
|
|
|
|
local BOSS_NUMS = { CAZIC_TYPE, BERTOX_TYPE, RZ_TYPE, INNO_TYPE }; -- table index is the number
|
|
|
|
local BOSS_LOCS = {
|
|
[CAZIC_TYPE] = { x = -255, y = 248, z = 27.501, h = 93 },
|
|
[BERTOX_TYPE] = { x = -303, y = -301, z = 35.626, h = 17 },
|
|
[RZ_TYPE] = { x = 274, y = -279, z = 18.751, h = 217 },
|
|
[INNO_TYPE] = { x = 302, y = 309, z = 25, h = 158 },
|
|
};
|
|
local BOSS_BOX = { [CAZIC_TYPE] = 120, [BERTOX_TYPE] = 120, [RZ_TYPE] = 100, [INNO_TYPE] = 130 };
|
|
|
|
local BERTOX_STATE = {
|
|
{ mr = 450, fr = 375, cr = 375, pr = 360, dr = 360, accuracy = -50, ac = 200, min_hit = 935, max_hit = 1600 },
|
|
{ mr = 350, fr = 300, cr = 300, pr = 275, dr = 275, accuracy = 50, ac = 300, min_hit = 1040, max_hit = 1800 },
|
|
{ mr = 250, fr = 200, cr = 200, pr = 180, dr = 180, accuracy = 170, ac = 500, min_hit = 1145, max_hit = 2000 },
|
|
{ mr = 150, fr = 150, cr = 150, pr = 130, dr = 130, accuracy = 320, ac = 600, min_hit = 1250, max_hit = 2200 },
|
|
{ mr = 200, fr = 175, cr = 175, pr = 160, dr = 160, accuracy = 275, ac = 650, min_hit = 1145, max_hit = 2000 },
|
|
{ mr = 250, fr = 200, cr = 200, pr = 180, dr = 180, accuracy = 200, ac = 600, min_hit = 1040, max_hit = 1800 },
|
|
{ mr = 300, fr = 250, cr = 250, pr = 230, dr = 230, accuracy = 65, ac = 500, min_hit = 940, max_hit = 1700 },
|
|
};
|
|
|
|
local INNO_ADD_LOCS = {
|
|
{ x = 211, y = 303 }, -- guardian
|
|
{ x = 207, y = 232 }, -- guardian
|
|
{ x = 324, y = 210 }, -- harbinger
|
|
{ x = 325, y = 268 }, -- harbinger
|
|
};
|
|
|
|
local TRASH_LOCS = {
|
|
[PHOBO_TYPE] = {
|
|
-139, 207, 5.625,
|
|
-122, 207, 5.625,
|
|
-139, 194, 5.625,
|
|
-122, 194, 5.625,
|
|
-139, 179, 5.625,
|
|
-122, 179, 5.625,
|
|
},
|
|
[AMYGDALAN_TYPE] = {
|
|
-122, 166, 8.75,
|
|
-139, 166, 8.75,
|
|
-122, 152, 8.75,
|
|
-139, 152, 8.75,
|
|
-157, 194, 8.75,
|
|
-157, 166, 8.75,
|
|
},
|
|
[CRYPT_TYPE] = {
|
|
-103, -133, 9.375,
|
|
-132, -151, 9.375,
|
|
},
|
|
[PRESTILENCE_TYPE] = {
|
|
-103, -151, 10,
|
|
-120, -115, 10,
|
|
-118, -133, 10,
|
|
-116, -151, 10,
|
|
-132, -133, 10,
|
|
},
|
|
[CASTER_TYPE] = {
|
|
-146, -115, 10,
|
|
-146, -133, 10,
|
|
-146, -151, 10,
|
|
-161, -133, 10,
|
|
-161, -151, 10,
|
|
},
|
|
[FIERCE_TYPE] = {
|
|
80, -135, 6.25,
|
|
100, -135, 6.25,
|
|
80, -150, 6.25,
|
|
100, -150, 6.25,
|
|
120, -150, 6.25,
|
|
80, -163, 6.25,
|
|
},
|
|
[BRAWLER_TYPE] = {
|
|
100, -163, 7.5,
|
|
80, -175, 7.5,
|
|
100, -175, 7.5,
|
|
120, -175, 7.5,
|
|
80, -186, 7.5,
|
|
100, -186, 7.5,
|
|
},
|
|
[CLERIC_TYPE] = {
|
|
120, 83, 4.375,
|
|
120, 103, 4.375,
|
|
139, 83, 4.375,
|
|
139, 103, 4.375,
|
|
139, 121, 4.375,
|
|
158, 83, 4.375,
|
|
},
|
|
[ABHORRENT_TYPE] = {
|
|
158, 103, 4.375,
|
|
177, 83, 4.375,
|
|
177, 103, 4.375,
|
|
177, 121, 4.375,
|
|
195, 83, 4.375,
|
|
195, 103, 4.375,
|
|
},
|
|
};
|
|
|
|
local TRASH_MASTERS = {
|
|
[PHOBO_TYPE] = 1,
|
|
[AMYGDALAN_TYPE] = 1,
|
|
[CRYPT_TYPE] = 2,
|
|
[PRESTILENCE_TYPE] = 2,
|
|
[CASTER_TYPE] = 2,
|
|
[FIERCE_TYPE] = 3,
|
|
[BRAWLER_TYPE] = 3,
|
|
[CLERIC_TYPE] = 4,
|
|
[ABHORRENT_TYPE] = 4,
|
|
};
|
|
local ADD_MASTERS = {
|
|
[BOAR_TYPE] = 3,
|
|
[MINION_TYPE] = 3,
|
|
[GUARDIAN_TYPE] = 4,
|
|
[HATEBRINGER_TYPE] = 4,
|
|
};
|
|
|
|
local RZ_ADDS_LOC = { x = 262, y = -272, z = 6.25 };
|
|
|
|
local rzState, bertoxState = 1, 1;
|
|
local bossState = {};
|
|
|
|
function Unpacket(s, numberize, returnTable)
|
|
local t = {};
|
|
for w in s:gmatch("([^;]+)") do
|
|
if ( numberize ) then
|
|
w = tonumber(w);
|
|
end
|
|
table.insert(t, w);
|
|
end
|
|
if ( returnTable ) then
|
|
return t;
|
|
else
|
|
return unpack(t);
|
|
end
|
|
end
|
|
|
|
function SpawnPhase()
|
|
local loc, mob;
|
|
|
|
rzState, bertoxState = 1, 1;
|
|
for i = 1, 4 do
|
|
if ( bosses[i] == 0 ) then
|
|
loc = BOSS_LOCS[BOSS_NUMS[i]];
|
|
mob = eq.spawn2(BOSS_NUMS[i], 0, 0, loc.x, loc.y, loc.z, loc.h);
|
|
bossState[i] = 1;
|
|
|
|
for typ, num in pairs(TRASH_MASTERS) do
|
|
if ( num == i ) then
|
|
|
|
for j = 1, #TRASH_LOCS[typ], 3 do
|
|
eq.spawn2(typ, 0, 0, TRASH_LOCS[typ][j], TRASH_LOCS[typ][j+1], TRASH_LOCS[typ][j+2], 0);
|
|
end
|
|
end
|
|
end
|
|
else
|
|
bossState[i] = 0;
|
|
end
|
|
end
|
|
end
|
|
|
|
function Phase5Signal(e)
|
|
|
|
if ( e.signal == 501 ) then
|
|
bosses = Unpacket(e.data, true, true);
|
|
SpawnPhase();
|
|
end
|
|
end
|
|
|
|
function BossTimer(e)
|
|
if ( e.timer == "leash" ) then
|
|
local typ = e.self:GetNPCTypeID();
|
|
if ( typ == CAZIC_TYPE or typ == BERTOX_TYPE ) then
|
|
return;
|
|
end
|
|
local box = BOSS_BOX[typ];
|
|
local sx, sy, sz, sh = e.self:GetSpawnPointX(), e.self:GetSpawnPointY(), e.self:GetSpawnPointZ(), e.self:GetSpawnPointH();
|
|
local xDiff, yDiff = (e.self:GetX() - sx), (e.self:GetY() - sy);
|
|
|
|
if ( xDiff > box or xDiff < -box or yDiff > box or yDiff < -box ) then
|
|
e.self:GMMove(sx, sy, sz, sh);
|
|
e.self:WipeHateList();
|
|
e.self:CastSpell(3230, e.self:GetID()); -- Balance of the Nameless
|
|
end
|
|
|
|
elseif ( e.timer == "check_hp" ) then
|
|
|
|
if ( e.self:GetHPRatio() > 98 ) then
|
|
|
|
local typ = e.self:GetNPCTypeID();
|
|
if ( typ == BERTOX_TYPE ) then
|
|
bertoxState = 1;
|
|
SetBertoxStats(e.self);
|
|
|
|
elseif ( typ == RZ_TYPE ) then
|
|
eq.depop_all(BOAR_TYPE);
|
|
eq.depop_all(MINION_TYPE);
|
|
rzState = 1;
|
|
SetRallosStats(e.self);
|
|
|
|
elseif ( typ == INNO_TYPE ) then
|
|
eq.depop_all(GUARDIAN_TYPE);
|
|
eq.depop_all(HATEBRINGER_TYPE);
|
|
end
|
|
eq.stop_timer(e.timer);
|
|
end
|
|
end
|
|
end
|
|
|
|
function BossCombat(e)
|
|
if ( e.joined ) then
|
|
eq.set_timer("leash", 3000);
|
|
eq.stop_timer("check_hp");
|
|
|
|
if ( e.self:GetHPRatio() > 92 ) then
|
|
eq.set_next_hp_event(91);
|
|
end
|
|
else
|
|
eq.stop_timer("leash");
|
|
eq.set_timer("check_hp", 3000);
|
|
end
|
|
end
|
|
|
|
|
|
function BertoxHP(e)
|
|
if ( e.hp_event == 91 ) then
|
|
eq.set_next_hp_event(71);
|
|
bertoxState = 2;
|
|
|
|
elseif ( e.hp_event == 71 ) then
|
|
eq.set_next_hp_event(56);
|
|
bertoxState = 3;
|
|
|
|
elseif ( e.hp_event == 56 ) then
|
|
eq.set_next_hp_event(46);
|
|
bertoxState = 4;
|
|
|
|
elseif ( e.hp_event == 46 ) then
|
|
eq.set_next_hp_event(31);
|
|
bertoxState = 5;
|
|
|
|
elseif ( e.hp_event == 31 ) then
|
|
eq.set_next_hp_event(11);
|
|
bertoxState = 6;
|
|
|
|
elseif ( e.hp_event == 11 ) then
|
|
bertoxState = 7;
|
|
end
|
|
|
|
if ( bertoxState < 5 ) then
|
|
eq.get_entity_list():MessageClose(e.self, true, 200, 0, "Blisters and festering sores covering Bertoxxulous's hide burst. A noxious ooze bleeds down his scarred flesh, strengthening his physical body.");
|
|
else
|
|
e.self:Emote("falters, nearly imperceptibly.");
|
|
end
|
|
SetBertoxStats(e.self);
|
|
end
|
|
|
|
function SetBertoxStats(npc)
|
|
for stat, value in pairs(BERTOX_STATE[bertoxState]) do
|
|
npc:ModifyNPCStat(stat, tostring(value));
|
|
end
|
|
end
|
|
|
|
function SpawnRallosAdd(boss, typ)
|
|
local x, y, z = RZ_ADDS_LOC.x, RZ_ADDS_LOC.y, RZ_ADDS_LOC.z;
|
|
local mob = eq.spawn2(typ, 0, 0, x, y, z, 0);
|
|
eq.set_timer("leash", 3000, mob);
|
|
--mob:CastToNPC():MoveTo(boss:GetX(), boss:GetY(), boss:GetZ(), -1, true);
|
|
end
|
|
|
|
function RallosHP(e)
|
|
if ( e.hp_event == 91 ) then
|
|
eq.set_next_hp_event(76);
|
|
rzState = 2;
|
|
for i = 1, 4 do
|
|
SpawnRallosAdd(e.self, eq.ChooseRandom(BOAR_TYPE, MINION_TYPE));
|
|
end
|
|
|
|
elseif ( e.hp_event == 76 ) then
|
|
eq.set_next_hp_event(51);
|
|
rzState = 3;
|
|
for i = 1, 4 do
|
|
SpawnRallosAdd(e.self, eq.ChooseRandom(BOAR_TYPE, MINION_TYPE));
|
|
end
|
|
|
|
elseif ( e.hp_event == 51 ) then
|
|
eq.set_next_hp_event(26);
|
|
rzState = 4;
|
|
for i = 1, 4 do
|
|
SpawnRallosAdd(e.self, eq.ChooseRandom(BOAR_TYPE, MINION_TYPE));
|
|
end
|
|
|
|
elseif ( e.hp_event == 26 ) then
|
|
rzState = 5;
|
|
for i = 1, 6 do
|
|
SpawnRallosAdd(e.self, eq.ChooseRandom(BOAR_TYPE, MINION_TYPE));
|
|
end
|
|
end
|
|
|
|
eq.get_entity_list():MessageClose(e.self, true, 200, 0, "Rallos Zek roars a mighty war cry and swings his axe with a vengeance.");
|
|
SetRallosStats(e.self);
|
|
end
|
|
|
|
function SetRallosStats(npc)
|
|
if ( rzState == 1 ) then
|
|
npc:ModifyNPCStat("special_abilities", "5,0,0"); -- disable flurry
|
|
npc:ModifyNPCStat("special_abilities", "4,0,0"); -- disable wild rampage
|
|
npc:ModifyNPCStat("special_abilities", "3,1,5,200"); -- rampage 5%
|
|
npc:ModifyNPCStat("mr", "250");
|
|
npc:ModifyNPCStat("fr", "170");
|
|
npc:ModifyNPCStat("cr", "170");
|
|
npc:ModifyNPCStat("pr", "155");
|
|
npc:ModifyNPCStat("dr", "155");
|
|
npc:ModifyNPCStat("atk", "-100");
|
|
npc:ModifyNPCStat("ac", "350");
|
|
|
|
elseif ( rzState == 2 ) then
|
|
npc:ModifyNPCStat("special_abilities", "5,0,0"); -- disable flurry
|
|
npc:ModifyNPCStat("special_abilities", "4,0,0"); -- disable wild rampage
|
|
npc:ModifyNPCStat("special_abilities", "3,1,5,200"); -- rampage 5%
|
|
npc:ModifyNPCStat("mr", "250");
|
|
npc:ModifyNPCStat("fr", "190");
|
|
npc:ModifyNPCStat("cr", "190");
|
|
npc:ModifyNPCStat("pr", "180");
|
|
npc:ModifyNPCStat("dr", "180");
|
|
npc:ModifyNPCStat("atk", "200");
|
|
npc:ModifyNPCStat("ac", "450");
|
|
|
|
elseif ( rzState == 3 ) then
|
|
npc:ModifyNPCStat("special_abilities", "5,0,0"); -- disable flurry
|
|
npc:ModifyNPCStat("special_abilities", "4,1,1"); -- wild rampage 1%
|
|
npc:ModifyNPCStat("special_abilities", "3,1,5,200"); -- rampage 5%
|
|
npc:ModifyNPCStat("mr", "300");
|
|
npc:ModifyNPCStat("fr", "225");
|
|
npc:ModifyNPCStat("cr", "225");
|
|
npc:ModifyNPCStat("pr", "200");
|
|
npc:ModifyNPCStat("dr", "200");
|
|
npc:ModifyNPCStat("atk", "400");
|
|
npc:ModifyNPCStat("ac", "550");
|
|
|
|
elseif ( rzState == 4 ) then
|
|
npc:ModifyNPCStat("special_abilities", "5,1,5"); -- flurry 5%
|
|
npc:ModifyNPCStat("special_abilities", "4,1,1"); -- wild rampage 1%
|
|
npc:ModifyNPCStat("special_abilities", "3,0,0"); -- disable rampage
|
|
npc:ModifyNPCStat("mr", "350");
|
|
npc:ModifyNPCStat("fr", "250");
|
|
npc:ModifyNPCStat("cr", "250");
|
|
npc:ModifyNPCStat("pr", "230");
|
|
npc:ModifyNPCStat("dr", "230");
|
|
npc:ModifyNPCStat("atk", "600");
|
|
npc:ModifyNPCStat("ac", "650");
|
|
|
|
elseif ( rzState == 5 ) then
|
|
npc:ModifyNPCStat("special_abilities", "5,1,5"); -- flurry 5%
|
|
npc:ModifyNPCStat("special_abilities", "4,1,1"); -- wild rampage 1%
|
|
npc:ModifyNPCStat("special_abilities", "3,0,0"); -- disable rampage
|
|
npc:ModifyNPCStat("mr", "550");
|
|
npc:ModifyNPCStat("fr", "275");
|
|
npc:ModifyNPCStat("cr", "275");
|
|
npc:ModifyNPCStat("pr", "250");
|
|
npc:ModifyNPCStat("dr", "250");
|
|
npc:ModifyNPCStat("atk", "800");
|
|
npc:ModifyNPCStat("ac", "750");
|
|
end
|
|
end
|
|
|
|
function InnoHP(e)
|
|
if ( e.hp_event == 91 ) then
|
|
eq.set_next_hp_event(81);
|
|
|
|
elseif ( e.hp_event == 81 ) then
|
|
eq.set_next_hp_event(21);
|
|
SpawnInnoAdd(1, GUARDIAN_TYPE);
|
|
SpawnInnoAdd(2, GUARDIAN_TYPE);
|
|
SpawnInnoAdd(3, HATEBRINGER_TYPE);
|
|
|
|
elseif ( e.hp_event == 21 ) then
|
|
SpawnInnoAdd(1, GUARDIAN_TYPE);
|
|
SpawnInnoAdd(2, GUARDIAN_TYPE);
|
|
SpawnInnoAdd(3, HATEBRINGER_TYPE);
|
|
SpawnInnoAdd(4, HATEBRINGER_TYPE);
|
|
end
|
|
end
|
|
|
|
function SpawnInnoAdd(locNum, typ)
|
|
local mob = eq.spawn2(typ, 0, 0, INNO_ADD_LOCS[locNum].x, INNO_ADD_LOCS[locNum].y, 7.5, 128);
|
|
eq.set_timer("leash", 6000, mob);
|
|
local boss = eq.get_entity_list():GetMobByNpcTypeID(INNO_TYPE);
|
|
mob:CastToNPC():MoveTo(boss:GetX(), boss:GetY(), boss:GetZ(), 0, true);
|
|
end
|
|
|
|
function AddTimer(e)
|
|
if ( e.timer == "leash" ) then
|
|
local masterType = BOSS_NUMS[ADD_MASTERS[e.self:GetNPCTypeID()]];
|
|
local x, y, z, h = BOSS_LOCS[masterType].x, BOSS_LOCS[masterType].y, BOSS_LOCS[masterType].z, BOSS_LOCS[masterType].h;
|
|
local xDiff, yDiff = (e.self:GetX() - x), (e.self:GetY() - y);
|
|
|
|
if ( xDiff > 200 or xDiff < -200 or yDiff > 200 or yDiff < -200 ) then
|
|
e.self:GMMove(x, y, z-10, h);
|
|
e.self:WipeHateList();
|
|
e.self:CastSpell(3230, e.self:GetID()); -- Balance of the Nameless
|
|
local boss = eq.get_entity_list():GetMobByNpcTypeID(masterType);
|
|
e.self:MoveTo(boss:GetX(), boss:GetY(), boss:GetZ(), 0, true);
|
|
end
|
|
end
|
|
end
|
|
|
|
function TrashDeathComplete(e)
|
|
local killType = e.self:GetNPCTypeID();
|
|
local master = TRASH_MASTERS[killType];
|
|
|
|
if ( bossState[master] == 1 ) then
|
|
local elist = eq.get_entity_list();
|
|
|
|
for typ, mast in pairs(TRASH_MASTERS) do
|
|
if ( mast == master ) then
|
|
if ( elist:IsMobSpawnedByNpcTypeID(typ) ) then
|
|
return;
|
|
end
|
|
end
|
|
end
|
|
|
|
bossState[master] = 2;
|
|
boss = elist:GetNPCByNPCTypeID(BOSS_NUMS[master]);
|
|
boss:SetSpecialAbility(24, 0); -- Will Not Aggro off
|
|
boss:SetSpecialAbility(35, 0); -- No Harm from Players off
|
|
if ( BOSS_NUMS[master] == RZ_TYPE ) then
|
|
boss:SetBodyType(19, false); -- Zek
|
|
else
|
|
boss:SetBodyType(1, false); -- humanoid
|
|
end
|
|
eq.debug(boss:GetCleanName().." now active");
|
|
end
|
|
end
|
|
|
|
function BossDeath(e)
|
|
local corpseType = e.self:GetNPCTypeID();
|
|
|
|
for i, typ in ipairs(BOSS_NUMS) do
|
|
if ( typ == corpseType ) then
|
|
|
|
if ( corpseType == RZ_TYPE and (rzState ~= 5 or e.self:GetAC() ~= 750) ) then
|
|
eq.debug("Error: Rallos Zek did not power up correctly. Depoping corpse.");
|
|
e.self:ClearItemList();
|
|
e.self:Depop();
|
|
eq.depop_all(corpseType);
|
|
return;
|
|
end
|
|
|
|
if ( corpseType == BERTOX_TYPE and (bertoxState ~= 7 or e.self:GetAC() ~= 500) ) then
|
|
eq.debug("Error: Bertoxxulous did not power up correctly. Depoping corpse.");
|
|
e.self:ClearItemList();
|
|
e.self:Depop();
|
|
eq.depop_all(corpseType);
|
|
return;
|
|
end
|
|
|
|
eq.signal(INSTANCE_CONTROLLER_TYPE, 6, 0, "5;"..i);
|
|
return;
|
|
end
|
|
end
|
|
end
|
|
|
|
function event_encounter_load(e)
|
|
eq.register_npc_event("Phase5", Event.signal, EVENTS_CONTROLLER_TYPE, Phase5Signal);
|
|
|
|
for _, typ in pairs(BOSS_NUMS) do
|
|
eq.register_npc_event("Phase5", Event.death, typ, BossDeath);
|
|
eq.register_npc_event("Phase5", Event.combat, typ, BossCombat);
|
|
eq.register_npc_event("Phase5", Event.timer, typ, BossTimer);
|
|
end
|
|
|
|
for typ in pairs(TRASH_LOCS) do
|
|
eq.register_npc_event("Phase5", Event.death_complete, typ, TrashDeathComplete);
|
|
end
|
|
|
|
eq.register_npc_event("Phase5", Event.hp, BERTOX_TYPE, BertoxHP);
|
|
eq.register_npc_event("Phase5", Event.hp, RZ_TYPE, RallosHP);
|
|
eq.register_npc_event("Phase5", Event.hp, INNO_TYPE, InnoHP);
|
|
|
|
eq.register_npc_event("Phase5", Event.timer, BOAR_TYPE, AddTimer);
|
|
eq.register_npc_event("Phase5", Event.timer, MINION_TYPE, AddTimer);
|
|
eq.register_npc_event("Phase5", Event.timer, GUARDIAN_TYPE, AddTimer);
|
|
eq.register_npc_event("Phase5", Event.timer, HATEBRINGER_TYPE, AddTimer);
|
|
end
|