function clamp(value, mi, ma)
	if value < mi then value = mi end
	if value > ma then value = ma end
	return value
end


function trim(s)
   return (s:gsub("^%s*(.-)%s*$", "%1"))
end


function startsWith(str, start)
	return string.sub(str, 1, string.len(start)) == start
end

function splitString(str, delimiter)
	local result = {}
	for word in string.gmatch(str, '([^'..delimiter..']+)') do
		result[#result+1] = trim(word)
	end
	return result
end


function hasWord(str, word)
	local words = splitString(str, " ")
	for i=1,#words do
		if string.lower(words[i]) == string.lower(word) then
			return true
		end
	end
	return false
end

function smoothstep(edge0, edge1, x)
	x = math.clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0)
	return x * x * (3 - 2 * x)
end


function progressBar(w, h, t)
	UiPush()
		UiAlign("left top")
		UiColor(0, 0, 0, 0.5)
		UiImageBox("ui/common/box-solid-10.png", w, h, 6, 6)
		if t > 0 then
			UiTranslate(2, 2)
			w = (w-4)*t
			if w < 12 then w = 12 end
			h = h-4
			UiColor(1,1,1,1)
			UiImageBox("ui/common/box-solid-6.png", w, h, 6, 6)
		end
	UiPop()
end

function rnd(mi, ma)
	return mi+(ma-mi)*math.random()
end


function rndVec(s)
	return VecScale(VecNormalize(Vec(math.random()-0.5, math.random()-0.5, math.random()-0.5)), s)
end


function getPlayerTeam(player)
	return 1 + ((player-1)%2)
end

function queryRaycastLocation(startloc, direction, distance)
	local hit, dist, normal, shape = QueryRaycast(startloc, direction, distance)
	local hitlocation = VecAdd(startloc, VecScale(direction, dist))
	return hit, dist, normal, shape, hitlocation
end