Generate a YGOPro Lua script for the following Yu-Gi-Oh card effect:
When this card is Normal Summoned: You can excavate the top 3 cards of your Deck, and if you do, you can banish 1 excavated monster to add 1 monster with its same name to your hand, from either your Deck or the other excavated cards, also shuffle the rest into the Deck. Once per turn, during the End Phase, if this card is in your GY because it was sent there this turn after being Normal Summoned/Set: You can excavate the top 3 cards of your Deck, and if you do, place them on top of the Deck in any order.
--ボティス
--Votis
--Scripted by Hatter
local s,id=GetID()
function s.initial_effect(c)
	--Add to hand
	local e1=Effect.CreateEffect(c)
	e1:SetDescription(aux.Stringid(id,0))
	e1:SetCategory(CATEGORY_REMOVE+CATEGORY_TOHAND+CATEGORY_SEARCH)
	e1:SetType(EFFECT_TYPE_SINGLE+EFFECT_TYPE_TRIGGER_O)
	e1:SetCode(EVENT_SUMMON_SUCCESS)
	e1:SetTarget(s.exctg)
	e1:SetOperation(s.thop)
	c:RegisterEffect(e1)
	--Excavate and sort cards
	local e2=Effect.CreateEffect(c)
	e2:SetDescription(aux.Stringid(id,1))
	e2:SetType(EFFECT_TYPE_FIELD+EFFECT_TYPE_TRIGGER_O)
	e2:SetCode(EVENT_PHASE+PHASE_END)
	e2:SetRange(LOCATION_GRAVE)
	e2:SetCountLimit(1)
	e2:SetCondition(s.sdcon)
	e2:SetTarget(s.exctg)
	e2:SetOperation(s.sdop)
	c:RegisterEffect(e2)
end
function s.exctg(e,tp,eg,ep,ev,re,r,rp,chk)
	if chk==0 then return Duel.GetFieldGroupCount(tp,LOCATION_DECK,0)>=3 end
	Duel.SetPossibleOperationInfo(0,CATEGORY_REMOVE,nil,1,tp,LOCATION_DECK)
	Duel.SetPossibleOperationInfo(0,CATEGORY_TOHAND,nil,1,tp,LOCATION_DECK)
end
function s.thfilter(c,code)
	return c:IsMonster() and c:IsCode(code) and c:IsAbleToHand() 
end
function s.rmfilter(c,tp)
	return c:IsMonster() and c:IsAbleToRemove() and Duel.IsExistingMatchingCard(s.thfilter,tp,LOCATION_DECK,0,1,c,c:GetCode())
end
function s.thop(e,tp,eg,ep,ev,re,r,rp)
	if Duel.GetFieldGroupCount(tp,LOCATION_DECK,0)<3 then return end
	Duel.ConfirmDecktop(tp,3)
	local dg=Duel.GetDecktopGroup(tp,3)
	if dg:IsExists(s.rmfilter,1,nil,tp) and Duel.SelectYesNo(tp,aux.Stringid(id,2)) then
		Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_REMOVE)
		local tc=dg:FilterSelect(tp,s.rmfilter,1,1,nil,tp):GetFirst()
		if tc and Duel.Remove(tc,POS_FACEUP,REASON_EFFECT)>0 and tc:IsLocation(LOCATION_REMOVED) then
			Duel.Hint(HINT_SELECTMSG,tp,HINTMSG_ATOHAND)
			local sg=Duel.SelectMatchingCard(tp,s.thfilter,tp,LOCATION_DECK,0,1,1,nil,tc:GetCode())
			if #sg>0 then
				Duel.SendtoHand(sg,nil,REASON_EFFECT)
				Duel.ConfirmCards(1-tp,sg)
			end
		end
	end
	Duel.ShuffleDeck(tp)
end
function s.sdcon(e,tp,eg,ep,ev,re,r,rp)
	local c=e:GetHandler()
	return c:GetTurnID()==Duel.GetTurnCount() and c:IsPreviousLocation(LOCATION_MZONE) and c:IsNormalSummoned()
end
function s.sdop(e,tp,eg,ep,ev,re,r,rp)
	if Duel.GetFieldGroupCount(tp,LOCATION_DECK,0)<3 then return end
	Duel.ConfirmDecktop(tp,3)
	Duel.SortDecktop(tp,tp,3)
end