прив, у меня есть такой код, я хочу его универсализировать, как мне это сделать? local сanvases = {
	speedometer = {
		maxSpeed 	= 160,
		width 		= 200,
		height 		= 70,
		posX 		= 1200,
		posY 		= 730,
		borderWidth = 1.1,
		bars		= {
				speedBar = {
					allign 		= 'center', 
					padding 	= 20,
					--width 		= 160,
					height 		= 25,
					offsetX 	= speedometer.width/2,
					offsetY 	= 10,
					ticks = {
					main = {
						milesPerTick  = 20,
						milesOffset   = 0,
						allign        = 'end',
						height        = 5,
						width         = 1,
						text          = true,
						textOffset	  = 8
					},
					secondary = {
						milesPerTick  = 20,
						milesOffset   = 10,
						allign        = 'end',
						height        = 3,
						width         = 1,
						text          = false,
						textOffset	  = false
					}
				}
			}
		}
	}
}

local labels = {
    labelOffsetY = 62
}

function main()
    repeat wait(0) until isSampAvailable()

	local theme = colors.tmpTheme1

    while true do wait(0)
        if isCharInAnyCar(playerPed) then
            local car = storeCarCharIsInNoSave(playerPed)
            local speedUnits = math.floor(getCarSpeed(car) * 2)
            local speedStart = speedUnits > speedometer.maxSpeed and speedometer.maxSpeed * math.floor(speedUnits / speedometer.maxSpeed) or 0
			renderSetRenderState(161 --[[D3DRS_MULTISAMPLEANTIALIAS]], 1)

			
			for _, canvas in pairs(сanvases) do
			
				-- отрисовка фона спидометра
				renderDrawBox(speedometer.posX, speedometer.posY, speedometer.width, speedometer.height, theme.background)
			
			
				for _, bar in pairs(canvas.bars) do
					
					-- отрисовка спидбара
					local width = speedometer.width - (bar.padding * 2)
					local offsetX = (bar.allign == 'start' and bar.offsetX) or 
									(bar.allign == 'center' and bar.offsetX - width/2) or 
									(bar.allign == 'end' and bar.offsetX - width)
					local speed = (speedUnits - speedStart) / speedometer.maxSpeed * width
					renderDrawBox(speedometer.posX + offsetX, speedometer.posY + bar.offsetY,speed, bar.height, theme.speed1)
					
					
					-- отрисовка делений и чисел под ними
					for _, tick in pairs(bar.ticks) do
						local startX = speedometer.posX + bar.padding
						local startY = ((tick.allign == 'start' and 0) or 
									   (tick.allign == 'center' and bar.height / 2) or 
									   (tick.allign == 'end' and bar.height)) + speedometer.posY + bar.offsetY
						local endY = startY + tick.height
						local speedBarWidth = (speedometer.width - (bar.padding * 2))
						local pixelsPerMile = speedBarWidth / (speedometer.maxSpeed) -- деление ширины спидбара на максимальную на нем скорость
						local pixelsOffset = tick.milesOffset * pixelsPerMile -- смещение от начала в пикселях
						local ticksSpacing = tick.milesPerTick * pixelsPerMile -- расстояние между делениями
						local numTicks = math.floor((speedBarWidth-pixelsOffset) / ticksSpacing) -- деление ширины спидбара на ширину тика
						if tick.milesPerTick then
							for i = 0, numTicks  do
								local x = startX + ticksSpacing * i + pixelsOffset
								renderDrawLine(x, startY, x, endY, tick.width, theme.text)
								if tick.text then -- отрисовка текста под(над) черточкой скорости
									local speed = tick.milesPerTick * i + tick.milesOffset + speedStart
									local textY = endY + tick.textOffset
									
									renderFontDrawTextEx(fonts.small, tostring(speed), x, textY, theme.text, _, 'center', 'center') -- !! НАПИСАТЬЬ ВЫРАВНИЕ ПО ЦЕНТРУ ПО ОБЕИМ(?) ОСЯМ ЧЕРЕЗ КАСТОМНУЮ ФУНКЦИЮ РЕНДЕРА !!
								end
							end
						end
					end
						
						
					-- отрисовка текущей скорости			
					renderFontDrawTextEx(				fonts.large,				tostring(speedUnits),				speedometer.posX + bar.offsetX,				speedometer.posY + ((bar.height / 2)+bar.offsetY),				theme.text,				_, 'center', 'center'
					)
					
					
					-- отрисовка границ спидбара
					renderDrawLine(speedometer.posX + offsetX, speedometer.posY + bar.offsetY, speedometer.posX + offsetX + width, speedometer.posY + bar.offsetY, speedometer.borderWidth, theme.border)
					renderDrawLine(speedometer.posX + offsetX, speedometer.posY + bar.offsetY + bar.height, speedometer.posX + offsetX + width, speedometer.posY + bar.offsetY + bar.height, speedometer.borderWidth, theme.border)
					renderDrawLine(speedometer.posX + offsetX, speedometer.posY + bar.offsetY, speedometer.posX + offsetX, speedometer.posY + bar.offsetY + bar.height, speedometer.borderWidth, theme.border)
					renderDrawLine(speedometer.posX + offsetX + width, speedometer.posY + bar.offsetY, speedometer.posX + offsetX + width, speedometer.posY + bar.offsetY + bar.height, speedometer.borderWidth, theme.border)


					-- отрисовка надписи "Speed(MPH)"
					renderFontDrawTextEx(				fonts.medium,				'Speed(MPH)',				speedometer.posX + speedometer.width / 2,				speedometer.posY + labels.labelOffsetY,				theme.text,				_, 'center', 'center')
				
				end
			end
		end
	end
end

--      'start'      'center'      'end'

-- 1 значение - одинаковый отступ со всех сторон
-- 2 значения - первое для верха и низа, второе для левой и правой сторон
-- 3 значения - первое для верха, второе для правой и левой, третье для низа
-- 4 значения - отступы по часовой стрелке: верх, правая, низ, левая

function renderFontDrawTextEx(font, text, posX, posY, color, ignoreColorTags, allignX, allignY)
    local length = renderGetFontDrawTextLength(font, text)
    local height = renderGetFontDrawHeight(font)

    if allignX == "center" then
        posX = posX - length / 2
    elseif allignX == "end" then
        posX = posX - length
    end

    if allignY == "center" then
        posY = posY - height / 2
    elseif allignY == "end" then
        posY = posY - height
    end

    return renderFontDrawText(font, text, posX, posY, color, ignoreColorTags)
end


-- примеры вызова drawStar:
-- drawStar(100, 100, 100, 5, 0xFFDD0000, 0xFFFFFFFF, 55)
-- drawStar(50, 230, 45, 7, 0xFFDD0000, 0xFFFFFFFF, 65)
-- drawStar(230, 200, 100, 4, 0xFFCC0000, 0xAAFF00FF, 65)