Pinkstack/roblox-luau-corpus-text huggingface dataset:
---Exemplo De Uso | RagdollMD.RagDoll(workspace["Combat Test"],3)



function ActiveRagdoll(plr,Seconds)
	local character = plr
	local humanoid = character.Humanoid
	character.HumanoidRootPart.Massless = true
	humanoid:ChangeState(Enum.HumanoidStateType.Physics)
	for _, v in pairs(character:GetDescendants()) do
		if v:IsA("Motor6D") then
			local a0, a1 = Instance.new("Attachment"), Instance.new("Attachment")
			a0.CFrame = v.C0
			a1.CFrame = v.C1
			a0.Parent = v.Part0
			a1.Parent = v.Part1
			local b = Instance.new("BallSocketConstraint")
			b.Attachment0 = a0
			b.Attachment1 = a1
			b.Parent = v.Part0
			v.Enabled = false
		end
	end
	delay(Seconds,function()
		for _,v in pairs(character:GetDescendants()) do
			if v:IsA('Motor6D') then
				v.Enabled = true
			end
			if v.Name == 'BallSocketConstraint' then
				v:Destroy()
			end
			if v.Name == 'Attachment' then
				v:Destroy()
			end
			character.HumanoidRootPart.Massless = false
			humanoid.PlatformStand = false
			humanoid:ChangeState(Enum.HumanoidStateType.Ragdoll,false)
		end
	end)
end


module.RagDoll = function(plr,Seconds)
	spawn(function()
		ActiveRagdoll(plr,Seconds)
	end)
end


return module
--Horn Sound Code, Metrotren


m1=script.Parent.StartHorn
m2=script.Parent.HornSound
m3=script.Parent.EndHorn
m1:Stop() --Initial setup
m2:Stop()
m3:Stop()
m1.Volume = 0
m2.Volume = 0
m3.Volume = 0
m2.Looped = false
m2.Playing = false
script.Parent.Parent:WaitForChild("Drive").Locotrol.Event:connect(function(data)
	if data["Horn"] == true then
		m2.Volume = 0
		m2.Looped = false
		m2:Stop()
		m2.Playing = false
		m3.Volume = 0
		m3:stop()
		m1.Volume = 1
		m1:Play()
		--wait(m1.TimeLength) --disabled because it makes looping part stuck playing if stopped too soon.
		if m1.TimePosition < m1.TimeLength then
			m2.Looped = true
			m2.Volume = 1
			m2:Play()
		else
			m1.Volume = 0
			m1:Stop()
		end
	elseif data["Horn"] == false then
		m1.Volume = 0
		m1:Stop()
		--For 3 part option
		m2.Volume = 0
		m2:Stop()
		m2.Looped = false
		m2.Playing = false
		m3.Volume = 1
		m3:Play()
		
		--[[ -- For 2 part option
		if m2.IsPlaying == true then
			for i=1, 0, -.1 do
				m2.Volume = i*1
				wait(.1)
			end
		end
		m2.Volume = 0
		m2.Looped = false
		m2.Playing = false
		m2:Stop()
		--]]	
	end
end)
----------------------------------------------------------------------------------------------------
-----------------=[ RECOIL & PRECISAO ]=------------------------------------------------------------
----------------------------------------------------------------------------------------------------


	,VRecoil = {18,25}				--- Vertical Recoil
	,HRecoil = {10,15}				--- Horizontal Recoil
	,AimRecover = .65				---- Between 0 & 1
	
	,RecoilPunch = .25
	,VPunchBase = 3.75				--- Vertical Punch
	,HPunchBase = 1.5				--- Horizontal Punch
	,DPunchBase = 1 				--- Tilt Punch | useless
	
	,AimRecoilReduction = 5 		--- Recoil Reduction Factor While Aiming (Do not set to 0)
	,PunchRecover = 0.2
	,MinRecoilPower = .75
	,MaxRecoilPower = 3
	,RecoilPowerStepAmount = .25
	
	,MinSpread = 0.12				--- Min bullet spread value | Studs
	,MaxSpread = 47					--- Max bullet spread value | Studs
	,AimInaccuracyStepAmount = 1
	,WalkMultiplier = 0				--- Bullet spread based on player speed

	,SwayBase = 0.25				--- Weapon Base Sway | Studs
	,MaxSway =	2					--- Max sway value based on player stamina | Studs
--print(ChosenNTID)


NightTheme.SoundId = "rbxassetid://" .. ChosenNTID
NightTheme.Ended:Connect(function()
UpdateNightThemeID()
end)
end

NightTheme:Play()
UpdateNightThemeID()

game:GetService("RunService").RenderStepped:Connect(function()
if Rake ~= nil and Rake:FindFirstChild("HumanoidRootPart") ~= nil then
if CharacterRoot ~= nil and ChracterHumanoid ~= nil then -- Check if The rake, Player character, Player character humanoid still exist
RangeMagnitude = (Rake.HumanoidRootPart.Position - CharacterRoot.Position).magnitude
if Rake.Stunning.Value == true then
StunDebounce = true
if RangeMagnitude < 70 then
ReplayDebounce = true
end
StopSound()
elseif Rake.Stunning.Value == false or ChracterHumanoid.Health > 0 then
StunDebounce = false
if ReplayDebounce == true and RangeMagnitude < 70 then
ReplayDebounce = false
StartSound()
end
end
if RangeMagnitude < 70 and Debounce1 == false and StunDebounce == false then
Debounce1 = true
StartSound()
Found:Play()
elseif RangeMagnitude > 70 and StunDebounce == false and Debounce1 == true then
Debounce1 = false
ReplayDebounce = false
StopSound()
end

if RakeTheme.IsPlaying then
if RangeMagnitude > 70 then
Debounce1 = false
ReplayDebounce = false
StopSound()
end
if Rake.NPC.Health <= 0 then
script.Parent:Destroy()
end
if ChracterHumanoid.Health <= 0 then
StopSound()
end
if RangeMagnitude < 70 and RangeMagnitude > 35 then
RakeTheme.PlaybackSpeed = 1
end
if RangeMagnitude < 35 and RangeMagnitude > 20 then
RakeTheme.PlaybackSpeed = 1
end
if RangeMagnitude < 20 then
RakeTheme.PlaybackSpeed = 1
end
if RangeMagnitude < 20 then
RakeTheme.PlaybackSpeed = 1
end
end
end
end
end)
-- Connect events


Humanoid.Died:Connect(onDied)
Humanoid.Running:Connect(onRunning)
Humanoid.Jumping:Connect(onJumping)
Humanoid.Climbing:Connect(onClimbing)
Humanoid.GettingUp:Connect(onGettingUp)
Humanoid.FreeFalling:Connect(onFreeFall)
Humanoid.FallingDown:Connect(onFallingDown)
Humanoid.Seated:Connect(onSeated)
Humanoid.PlatformStanding:Connect(onPlatformStanding)
Humanoid.Swimming:Connect(onSwimming)
-- ProximityPrompts


local Workspace = game:GetService("Workspace")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events = ReplicatedStorage:WaitForChild("Events")
local ClientTriggerGame = Events:WaitForChild("ClientTriggerGame")
local toggleRideHUD = Events:WaitForChild("ToggleRideHUD")

local starterGUI = script.Parent

local playNPC = game.Workspace.Lobby:WaitForChild("PlayNPC")
local proximityPlay = playNPC:WaitForChild("ProximityPrompt")
local playScreen = starterGUI:WaitForChild("PlayScreen")
local playGUI = playScreen:WaitForChild("PlayGUI")
local tutorialGUI = playScreen:WaitForChild("TutorialGUI")
--[[
	Clone the contents of StarterGui into the player's PlayerGui, placing them on top

	This is required as this game does not use characters, therefore StarterGui does not work
	out of the box.
]]


function UIController.extractStarterGui()
	local playerGui = Players.LocalPlayer:WaitForChild("PlayerGui")
	for _, child in pairs(StarterGui:GetChildren()) do
		child.DisplayOrder = 1
		child:Clone().Parent = playerGui
	end
end
-- Ps2maniac9 Technology




script.Ps2maniac9Credits.Parent = Game.Workspace
wait(0.1)
credit = script.Parent.Ps2maniac9ScreenGui
MakeHintsAll = false

if Game.Workspace.Ps2maniac9Credits.Value < 1 then
	Game.Workspace.Ps2maniac9Credits.Value = 1
	if not game:FindFirstChild("NetworkServer") then
		if MakeHintsAll then 
			credit.Parent = Game.StarterGui
		end
	else
		credit.Parent = Game.StarterGui
	end
end
--[[**
	ensures value is an enum of the correct type

	@param enum The enum to check

	@returns A function that will return true iff the condition is passed
**--]]


function t.enum(enum)
	assert(t.Enum(enum))
	return function(value)
		local enumItemSuccess, enumItemErrMsg = t.EnumItem(value)
		if not enumItemSuccess then
			return false, enumItemErrMsg
		end

		if value.EnumType == enum then
			return true
		else
			return false, string.format("enum of %s expected, got enum of %s", tostring(enum), tostring(value.EnumType))
		end
	end
end

do
	local checkWrap = t.tuple(t.callback, t.callback)

	--[[**
		wraps a callback in an assert with checkArgs

		@param callback The function to wrap
		@param checkArgs The functon to use to check arguments in the assert

		@returns A function that first asserts using checkArgs and then calls callback
	**--]]
	function t.wrap(callback, checkArgs)
		assert(checkWrap(callback, checkArgs))
		return function(...)
			assert(checkArgs(...))
			return callback(...)
		end
	end
end
--[put in StarterGui]



wait(0) --dont delete, the script can crash if you delete this line
local plr = game.Players.LocalPlayer --local player
local players = game.Players --players

local message = "you lost" --message when die (kick message), change if you want

players.RespawnTime = 0

plr.CharacterRemoving:Connect(function(e) --detects if the player died.
	plr:Kick(message) --kick the player with the message
end)
--[[
		___      _______                _     
	   / _ |____/ ___/ /  ___ ____ ___ (_)__ 
	  / __ /___/ /__/ _ \/ _ `(_-<(_-</ (_-<
	 /_/ |_|   \___/_//_/\_,_/___/___/_/___/
 						SecondLogic @ Inspare
]]




local autoscaling	= false					--Estimates top speed

local UNITS	= {								--Click on speed to change units
											--First unit is default	
	{
		units			= "MPH"				,
		scaling			= (10/12) * (60/88)	, -- 1 stud : 10 inches | ft/s to MPH
		maxSpeed		= 200				,
		spInc			= 20				, -- Increment between labelled notches
	},
	
	{
		units			= "KM/H"			,
		scaling			= (10/12) * 1.09728	, -- 1 stud : 10 inches | ft/s to KP/H
		maxSpeed		= 320				,
		spInc			= 20				, -- Increment between labelled notches
	},
	
	{
		units			= "SPS"				,
		scaling			= 1					, -- Roblox standard
		maxSpeed		= 400				,
		spInc			= 50				, -- Increment between labelled notches
	}
}
--------RIGHT DOOR --------



game.Workspace.doorright.l12.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorright.l22.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorright.l32.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorright.l42.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorright.l52.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorright.l62.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorright.l72.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
-- Get the players set settings


local plr
local wasEquipped = false
if script.Parent.Parent.ClassName == "Backpack" then
	plr = script.Parent.Parent.Parent
else
	wasEquipped = true
	plr = game.Players:GetPlayerFromCharacter(script.Parent.Parent)
end
local setSkin = game.ReplicatedStorage.KnifeSkins:FindFirstChild(plr.Settings.SetKnifeSkin.Value)
local setEffect = plr.Settings.SetEffect.Value
----- Script -----



local function DisableGui (Gift,Daily,Rebirth,Store,Vip,Inventory,CaseStore)
	GiftFrame.Visible = Gift
	DailyRewardFrame.Visible = Daily
	RebirthFrame.Visible = Rebirth
	StoreFrame.Visible = Store
	VipFrame.Visible = Vip
	InventoryFrame.Visible = Inventory
	CaseStoreFrame.Visible = CaseStore
end

GiftFrame.Changed:Connect(function()
	if GiftFrame.Visible == true then
		DisableGui(true,false,false,false,false,false,false)
	end
end)

DailyRewardFrame.Changed:Connect(function()
	if DailyRewardFrame.Visible == true then
		DisableGui(false,true,false,false,false,false,false)
		end
end)

RebirthFrame.Changed:Connect(function()
	if RebirthFrame.Visible == true then
		DisableGui(false,false,true,false,false,false,false)
	end
end)

StoreFrame.Changed:Connect(function()
	if StoreFrame.Visible == true then
		DisableGui(false,false,false,true,false,false,false)
	end
end)

VipFrame.Changed:Connect(function()
	if VipFrame.Visible == true then
		DisableGui(false,false,false,false,true,false,false)
	end
end)

InventoryFrame.Changed:Connect(function()
	if InventoryFrame.Visible == true then
		DisableGui(false,false,false,false,false,true,false)
	end
end)

CaseStoreFrame.Changed:Connect(function()
	if CaseStoreFrame.Visible == true then
		DisableGui(false,false,false,false,false,false,true)
	end
end)
-- Insert inside the tool


local tool = script.Parent
local anim = Instance.new("Animation")
local anim1 = Instance.new("Animation")
anim.Name = "IdleAnim"
anim.AnimationId = "rbxassetid://YourOwnID" -- Idle Animaton ID
anim1.Name = "EquipAnim"
anim1.AnimationId = "rbxassetid://YourOwnID"-- Equip Tool Animaton ID
local track
local track1
--edit the function below to return true when you want this response/prompt to be valid
--player is the player speaking to the dialogue, and dialogueFolder is the object containing the dialogue data


return function(player, dialogueFolder)
	local plrData = require(game.ReplicatedStorage.Source.Modules.Util):GetPlayerData(player)
	if plrData.Character.Injuries.Trauma.Value == true then
		return true
	end
	return false
end
--script.Parent.RemoteEvent.OnServerEvent:Connect(function()
--	if debounce == false then
--		char["Right Arm"].Touched:Connect(function(part)
--			if debounce == false then
--				debounce = true
--				script.Debounce.Value = true
--			if part.Parent.ClassName == "Model" then
--				target = part.Parent
--			elseif part.Parent.ClassName == "Model" then
--				target = part.Parent
--			else
--				return nil
--			end
--
--			if target:FindFirstChild("Humanoid") ~= nil then
--				target.Humanoid.Health = target.Humanoid.Health - script.Parent.Damage.Value
--				return
--			end
--			end
--			wait(script.Parent.Cooldown.Value)
--			debounce = false
--			script.Debounce.Value = false
--		end)
--	end
--end)
-- METHODS


function CollectiveWorldModel:_getCombinedResults(methodName, ...)
	local results = workspace[methodName](workspace, ...)
	if worldModel then
		local additionalResults = worldModel[methodName](worldModel, ...)
		for _, result in pairs(additionalResults) do
			table.insert(results, result)
		end
	end
	return results
end

function CollectiveWorldModel:GetPartBoundsInBox(cframe, size, overlapParams)
	return self:_getCombinedResults("GetPartBoundsInBox", cframe, size, overlapParams)
end

function CollectiveWorldModel:GetPartBoundsInRadius(position, radius, overlapParams)
	return self:_getCombinedResults("GetPartBoundsInRadius", position, radius, overlapParams)
end

function CollectiveWorldModel:GetPartsInPart(part, overlapParams)
	return self:_getCombinedResults("GetPartsInPart", part, overlapParams)
end



return CollectiveWorldModel
--	fallService:GetFallSignalFor(player, true):Connect(function()
--		if player.Character then
--			if player.Character:FindFirstChild("Immune") then return end
--			miscModule.Ragdoll(player.Character, 1.25)
--			DefaultGroup:Disable(player.Character)
--			task.delay(1.25, function()
--				DefaultGroup:Enable(player.Character)
--			end)
--		end
--	end)
--end)
-- Trim empty datastores and scopes from an entire datastore type:


local function prepareDataStoresForExport(origin)
	local dataPrepared = {}

	for name, scopes in pairs(origin) do
		local exportScopes = {}
		for scope, data in pairs(scopes) do
			local exportData = {}
			for key, value in pairs(data) do
				exportData[key] = value
			end
			if next(exportData) ~= nil then -- Only export datastore when non-empty
				exportScopes[scope] = exportData
			end
		end
		if next(exportScopes) ~= nil then -- Only export scope list when non-empty
			dataPrepared[name] = exportScopes
		end
	end

	if next(dataPrepared) ~= nil then -- Only return datastore type when non-empty
		return dataPrepared
	end
end

local function preprocessKey(key)
	if type(key) == "number" then
		if key ~= key then
			return "NAN"
		elseif key >= math.huge then
			return "INF"
		elseif key <= -math.huge then
			return "-INF"
		end
		return tostring(key)
	end
	return key
end

local function accurateWait(dt)
	dt = math.max(0, dt)
	local left = dt

	while left > 0 do
		left = left - RunService.Heartbeat:Wait()
	end

	return dt - left
end

local function simulateYield()
	if Constants.YIELD_TIME_MAX > 0 then
		accurateWait(rand:NextNumber(Constants.YIELD_TIME_MIN, Constants.YIELD_TIME_MAX))
	end
end

local function simulateErrorCheck(method)
	if Constants.SIMULATE_ERROR_RATE > 0 and rand:NextNumber() <= Constants.SIMULATE_ERROR_RATE then
		simulateYield()
		error(method .. " rejected with error (simulated error)", 3)
	end
end
--[[Drivetrain]]

	
	Tune.Config			= "RWD"		--"FWD" , "RWD" , "AWD"
	
	--Differential Settings	
	Tune.FDiffSlipThres	= 50		-- 1 - 100%				(Max threshold of applying full lock determined by deviation from avg speed)
	Tune.FDiffLockThres	= 50		-- 0 - 100%				(0 - Bias toward slower wheel, 100 - Bias toward faster wheel)
	Tune.RDiffSlipThres	= 80		-- 1 - 100%
	Tune.RDiffLockThres	= 20		-- 0 - 100%
	Tune.CDiffSlipThres	= 50		-- 1 - 100%				[AWD Only]
	Tune.CDiffLockThres	= 50		-- 0 - 100%				[AWD Only]
	
	--Traction Control Settings
	Tune.TCSEnabled		= True		-- Implements TCS
	Tune.TCSThreshold	= 20		-- Slip speed allowed before TCS starts working (in SPS)
	Tune.TCSGradient	= 20		-- Slip speed gradient between 0 to max reduction (in SPS)
	Tune.TCSLimit		= 10		-- Minimum amount of torque at max reduction (in percent)
-- tweens a given object in the path made by the Bezier (position only)
-- works for any object that has the properties given by the property table


function Bezier:CreateVector3Tween(object: Instance | {[any]: any}, propertyTable: {any}, bezierTweenInfo: TweenInfo, RelativeToLength: boolean?): Tween
	
	-- check if there are enough points to calculate a position within the Bezier
	if #self.Points == 0 then
		error("Bezier:CreateVector3Tween() only works if there is at least 1 BezierPoint in the Bezier!")
	end
	
	-- check if the object given is a valid object
	if typeof(object) ~= "Instance" and typeof(object) ~= "table" then
		error("Bezier:CreateVector3Tween() requires an Instance or a table as the first argument!")
	end
	
	-- check if the bezierTweenInfo given is a TweenInfo object
	if not (typeof(bezierTweenInfo) == "TweenInfo") then
		error("Bezier:CreateVector3Tween() requires a TweenInfo object as the third argument!")
	end
	
	-- check if the object given has the vector3 properties given
	local success, foundProperties = pcall(function()
		local foundProperties = true
		for _, propertyName in pairs(propertyTable) do
			if typeof(object[propertyName]) ~= "Vector3" and typeof(object[propertyName]) ~= "nil" then
				foundProperties = false
				break
			end
		end
		return foundProperties
	end)
	
	-- check if the properties were found
	if success and foundProperties then
		local tweenService = game:GetService("TweenService")
		local numValue = Instance.new("NumberValue")
		local tween = tweenService:Create(numValue, bezierTweenInfo, {Value = 1})
		local numValueChangedConnection
		tween.Changed:Connect(function(prop)
			if prop == "PlaybackState" then
				local playbackState = tween.PlaybackState
				if playbackState == Enum.PlaybackState.Playing then
					numValueChangedConnection = numValue.Changed:Connect(function(t)
						for _, propName in pairs(propertyTable) do
							object[propName] = RelativeToLength and self:CalculatePositionRelativeToLength(t) or self:CalculatePositionAt(t)
						end
					end)
				else
					if numValueChangedConnection then
						numValueChangedConnection:Disconnect()
						numValueChangedConnection = nil
					end
				end
			end
		end)
		return tween
	else
		error("Bezier:CreateVector3Tween() requires a matching property table with Vector3 or nil property names for the object as the second argument!")
	end
end
--[=[
	Schedules a sustained shake to stop. This works by setting the
	`Sustain` field to `false` and letting the shake effect fade out
	based on the `FadeOutTime` field.
]=]


function Shake:StopSustain()
	local now = self.TimeFunction()
	self.Sustain = false
	self.SustainTime = (now - self._startTime) - self.FadeInTime
end
--!strict


local events = require(script.events)
local install = require(script.install)

local DevModuleInstaller: { [string]: any } = {
	verboseLogging = false,
	pruneDevelopmentFiles = true,

	started = events.started.Event,
	finished = events.finished.Event,
}

function DevModuleInstaller.install(devModule: Folder)
	return install(devModule, {
		verboseLogging = DevModuleInstaller.verboseLogging,
		pruneDevelopmentFiles = DevModuleInstaller.pruneDevelopmentFiles,
	})
end

return DevModuleInstaller
--Change the color of the brush when the text box is used


brushSettings.ColorBox.FocusLost:Connect(function(entered)
	
	if entered then
		
		local color = brushSettings.ColorBox.Text
		color = string.gsub(color, " ", "")
		color = string.split(color, ",")
		
		if tonumber(color[1]) and tonumber(color[2]) and tonumber(color[3]) then
			
			currentColor = Color3.fromRGB(color[1], color[2], color[3])
		end
		
		brushSettings.ColorBox.Text = math.floor(currentColor.R * 255 + 0.5) .. ", " .. math.floor(currentColor.G * 255 + 0.5) .. ", " .. math.floor(currentColor.B * 255 + 0.5)

		brushSettings.PaintImage.ImageColor3 = currentColor
	end
end)
--Audio


local soundBank =  game.ServerStorage.Sounds.NPC.Banto:GetChildren()
banto.Health.Changed:connect(function()
    local hitSound = soundBank[math.random(1,#soundBank)]:Clone()
    hitSound.Parent = banto.PrimaryPart
    hitSound.PlayOnRemove = true
    wait()
    hitSound:Destroy()
end)

while true do
    bp.Parent = banto.PrimaryPart
    local goal
    repeat 
    local ray = Ray.new(Vector3.new(origin.p.x+math.random(-tether,tether), banto.PrimaryPart.Position.Y+100, origin.p.z+math.random(-tether,tether)),Vector3.new(0,-130,0))
    local part,pos,norm,mat = workspace:FindPartOnRay(ray,banto)
    if part == workspace.Terrain and mat ~= Enum.Material.Water then
        goal = pos+Vector3.new(0,2.25,0)
    end
    wait()
    until goal
    --Set new goal for banto to MoveTo :)
    walk:Play()
    local pos = banto.PrimaryPart.Position
    local cf = CFrame.new(Vector3.new(pos.X, 0, pos.Z), Vector3.new(goal.X, 0, goal.Z))
    bg.CFrame = cf
    bp.Position = (cf*CFrame.new(0,0,-100)).p
    
    local start = tick()
    repeat task.wait(.5)
    local ray = Ray.new(banto.PrimaryPart.Position, Vector3.new(0,-140,0))
    
    until (banto.PrimaryPart.Position-goal).magnitude < 10 or tick()-start >10
    walk:Stop()
    bp.Parent = nil
    wait(math.random(3,8))
end
-- ROBLOX deviation: currently no way – type the __call metamethod
-- {
--   __call: (any, any, any?) -> ExpectationResult,
-- -- ROBLOX deviation: [INTERNAL_MATCHER_FLAG]: boolean?
--   [Symbol]: boolean?
-- }



export type ThrowingMatcherFn = (any) -> ()
export type PromiseMatcherFn = (any) -> Promise<nil>

export type Tester = (any, any) -> boolean?

export type MatcherState = {
	assertionCalls: number,
	currentTestName: string?,
	dontThrow: (() -> ())?,
	error: Error?,
	equals: (any, any, Array<Tester>?, boolean?) -> boolean,
	expand: boolean?,
	expectedAssertionsNumber: number?,
	expectedAssertionsNumberError: Error?,
	isExpectingAssertions: boolean?,
	isExpectingAssertionsError: Error?,
	isNot: boolean,
	promise: string,
	suppressedErrors: Array<Error>,
	testPath: any, -- ROBLOX TODO: Config.Path?,
	utils: Object, -- ROBLOX deviation: no easy way to port to Lua: typeof jestMatcherUtils & {
	--   iterableEquality: Tester;
	--   subsetEquality: Tester;
	-- }
}

export type AsymmetricMatcher = {
	asymmetricMatch: (self: AsymmetricMatcher, other: unknown) -> boolean,
	toString: (self: AsymmetricMatcher) -> string,
	getExpectedType: ((self: AsymmetricMatcher) -> string)?,
	toAsymmetricMatcher: ((self: AsymmetricMatcher) -> string)?,
}
--[[

	VectorUtil.ClampMagnitude(vector, maxMagnitude)
	VectorUtil.AngleBetween(vector1, vector2)
	VectorUtil.AngleBetweenSigned(vector1, vector2, axisVector)


	EXAMPLES:

		ClampMagnitude:

			Clamps the magnitude of a vector so it is only a certain length.

			ClampMagnitude(Vector3.new(100, 0, 0), 15) == Vector3.new(15, 0, 0)
			ClampMagnitude(Vector3.new(10, 0, 0), 20)  == Vector3.new(10, 0, 0)

		
		AngleBetween:

			Finds the angle (in radians) between two vectors.

			v1 = Vector3.new(10, 0, 0)
			v2 = Vector3.new(0, 10, 0)
			AngleBetween(v1, v2) == math.rad(90)

		
		AngleBetweenSigned:

			Same as AngleBetween, but returns a signed value.

			v1 = Vector3.new(10, 0, 0)
			v2 = Vector3.new(0, 0, -10)
			axis = Vector3.new(0, 1, 0)
			AngleBetweenSigned(v1, v2, axis) == math.rad(90)

--]]




local VectorUtil = {}


function VectorUtil.ClampMagnitude(vector, maxMagnitude)
	return (vector.Magnitude > maxMagnitude and (vector.Unit * maxMagnitude) or vector)
end


function VectorUtil.AngleBetween(vector1, vector2)
	return math.acos(math.clamp(vector1.Unit:Dot(vector2.Unit), -1, 1))
end


function VectorUtil.AngleBetweenSigned(vector1, vector2, axisVector)
	local angle = VectorUtil.AngleBetween(vector1, vector2)
	return angle * math.sign(axisVector:Dot(vector1:Cross(vector2)))
end


return VectorUtil