Почему когда я открыл окно кастомизации, то не могу его закрыть, в нем ничего нет, и оно странное, исправь все баги. Я имею возможность по коду добавить к UMP45 гологрофический прицел, но его нет в окне кастомизации.
```lua
-- cl_att.lua
if CLIENT then
	SWEP._attachments = SWEP._attachments or {}
	-- Очистка вложений при удалении оружия
	function SWEP:OnRemove()
		for _, attachment in pairs(self._attachments) do
			if IsValid(attachment.csEnt) then attachment.csEnt:Remove() end
		end
	end

	local color_white = Color(255, 255, 255)
	local color_black = Color(0, 0, 0)
	-- Функция отрисовки оптических вложений
	local function drawOpticAttach(csEnt, flags)
		local weap = csEnt.parent
		if not IsValid(weap) then return end
		local ply = csEnt:GetParent()
		if not IsValid(ply) then return end
		if ply:GetActiveWeapon() ~= weap then return end
		csEnt:DrawModel(flags)
		if not qwb.ironsighted then return end
		local scopeMat = csEnt.opticMat or weap.DefaultScopeMat
		if not scopeMat then return end
		local attID = weap:LookupAttachment("muzzle")
		if not attID or attID <= 0 then return end
		local att = weap:GetAttachment(attID)
		if not att then return end
		local pos, ang = LocalToWorld(csEnt.opticPos, csEnt.opticAng or Angle(-90, 0, 0), csEnt:GetPos(), att.Ang)
		local w, h = unpack(csEnt.opticSize or {512, 512})
		local radius = math.max(w, h)
		local semiRadius = radius * 0.5
		if not draw_Circle then -- Убедитесь, что функция draw_Circle доступна
			return
		end

		qwb.fullyClearStencil()
		render.SetStencilEnable(true)
		render.SetStencilCompareFunction(STENCIL_ALWAYS)
		render.SetStencilFailOperation(STENCIL_ZERO)
		render.SetStencilZFailOperation(STENCIL_ZERO)
		render.SetStencilPassOperation(STENCIL_REPLACE)
		render.SetStencilReferenceValue(1)
		cam.Start3D2D(pos, ang, 0.01)
		draw.NoTexture()
		surface.SetDrawColor(color_black)
		draw_Circle(semiRadius, semiRadius, semiRadius, 30)
		cam.End3D2D()
		render.SetStencilCompareFunction(STENCIL_EQUAL)
		cam.Start3D2D(pos, ang, 0.01)
		local mat = weap.mat
		if not mat then return end
		surface.SetDrawColor(color_white)
		surface.SetMaterial(mat)
		surface.DrawTexturedRect(0, 0, w, h)
		surface.SetDrawColor(color_white)
		surface.SetMaterial(scopeMat)
		surface.DrawTexturedRect(0, 0, w, h)
		cam.End3D2D()
		render.SetStencilEnable(false)
	end

	-- Обработка сетевого сообщения установки вложения
	net.Receive("qwb.setAttachment", function()
		local weap = net.ReadEntity()
		if not IsValid(weap) then return end
		local attachType, attachID = net.ReadString(), net.ReadString()
		if not attachType or not attachID then return end
		local attachmentData = weap.Attachments and weap.Attachments[attachType] and weap.Attachments[attachType][attachID]
		if not attachmentData then return end
		weap._attachments = weap._attachments or {}
		weap._attachments[attachType] = weap._attachments[attachType] or {}
		local attachment = weap._attachments[attachType]
		attachment.id = attachID
		if IsValid(attachment.csEnt) then attachment.csEnt:Remove() end
		local owner = weap:GetOwner()
		attachment.csEnt = ClientsideModel(attachmentData.mdl)
		if not IsValid(attachment.csEnt) then return end
		attachment.csEnt:SetParent(weap)
		attachment.csEnt:AddEffects(EF_BONEMERGE)
		attachment.csEnt:SetLocalPos(attachmentData.pos)
		attachment.csEnt:SetLocalAngles(attachmentData.ang)
		attachment.csEnt:SetModelScale(attachmentData.scale or 1)
		attachment.csEnt.parent = weap
		if attachmentData.opticPos and owner == LocalPlayer() then
			attachment.csEnt.opticPos = attachmentData.opticPos
			attachment.csEnt.opticAng = attachmentData.opticAng
			attachment.csEnt.opticSize = attachmentData.opticSize
			attachment.csEnt.opticMat = attachmentData.opticMat or weap.DefaultScopeMat
			attachment.csEnt.RenderOverride = drawOpticAttach
		end

		attachment.csEnt:Spawn()
	end)

	-- Обработка сетевого сообщения удаления вложения
	net.Receive("qwb.removeAttachment", function()
		local weap = net.ReadEntity()
		if not IsValid(weap) then return end
		if not weap._attachments then return end
		local attachType = net.ReadString()
		if not attachType then return end
		local attachment = weap._attachments[attachType]
		if not attachment then return end
		if IsValid(attachment.csEnt) then attachment.csEnt:Remove() end
		weap._attachments[attachType] = nil
	end)
end
```
```lua
-- cl_att_menu.lua
if CLIENT then
	local color_bg = Color(0, 0, 0, 190)
	-- Открытие меню вложений
	function SWEP:OpenAttMenu()
		if IsValid(self._attMenu) then return end
		self._attMenu = vgui.Create("DPanel")
		local pnl = self._attMenu
		pnl:SetSize(ScrW(), ScrH())
		pnl:Center()
		pnl:MakePopup()
		function pnl:Paint(w, h)
			surface.SetDrawColor(color_bg)
			surface.DrawRect(0, 0, w, h)
		end

		-- Здесь можно добавить дополнительные элементы интерфейса для управления вложениями
		-- Например, кнопки для выбора и установки вложений
		qwb.attMenuOpened = true
	end

	-- Закрытие меню вложений
	function SWEP:CloseAttMenu()
		if not IsValid(self._attMenu) then return end
		self._attMenu:Remove()
		self._attMenu = nil
		qwb.attMenuOpened = false
	end

	-- Переключение состояния меню вложений
	function SWEP:ToggleAttMenu()
		if IsValid(self._attMenu) then
			self:CloseAttMenu()
		else
			self:OpenAttMenu()
		end
	end

	-- Хук для открытия/закрытия меню по контекстному меню
	hook.Add("OnContextMenuOpen", "qwb.att.menu", function()
		local weap = LocalPlayer():GetActiveWeapon()
		if not IsValid(weap) then return end
		if not weap.IsQWB then return end
		weap:ToggleAttMenu()
	end)
	-- Альтернативный способ открытия меню через нажатие клавиши (например, "E")
	-- Для этого можно использовать пользовательские консольные команды или другие хуки
end
```
```lua
-- sh_att.lua
-- Получение информации о вложении
function SWEP:GetAttach(att)
	return self._attachments and self._attachments[att]
end
```
```lua
-- sv_att.lua
-- Проверка возможности установки вложения
function SWEP:CanAttach(attachType, attachID)
	-- Здесь можно добавить логику проверки допустимости вложения
	return true
end

-- Установка вложения
function SWEP:SetAttach(attachType, attachID)
	if not self.Attachments[attachType] or not self.Attachments[attachType][attachID] then return end
	self._attachments = self._attachments or {}
	self._attachments[attachType] = self._attachments[attachType] or {}
	if self._attachments[attachType].id == attachID then return end
	if not self:CanAttach(attachType, attachID) then return end
	self._attachments[attachType].id = attachID
	net.Start("qwb.setAttachment")
	net.WriteEntity(self)
	net.WriteString(attachType)
	net.WriteString(attachID)
	net.Broadcast()
end

-- Удаление вложения
function SWEP:RemoveAttach(attachType)
	if not self._attachments or not self._attachments[attachType] then return end
	self._attachments[attachType] = nil
	net.Start("qwb.removeAttachment")
	net.WriteEntity(self)
	net.WriteString(attachType)
	net.Broadcast()
end

if SERVER then
	-- Обработка сетевого сообщения установки вложения
	net.Receive("qwb.setAttachment", function(len, ply)
		local weap = ply:GetActiveWeapon()
		if not IsValid(weap) or not weap.IsQWB or not weap.SetAttach then return end
		local attachType, attachID = net.ReadString(), net.ReadString()
		if not attachType or not attachID then return end
		weap:SetAttach(attachType, attachID)
	end)

	-- Обработка сетевого сообщения удаления вложения
	net.Receive("qwb.removeAttachment", function(len, ply)
		local weap = ply:GetActiveWeapon()
		if not IsValid(weap) or not weap.IsQWB or not weap.RemoveAttach then return end
		local attachType = net.ReadString()
		if not attachType then return end
		weap:RemoveAttach(attachType)
	end)
end
```