Pinkstack/roblox-luau-corpus-text huggingface dataset:
--[[Engine]]


	--Torque Curve
	Tune.Horsepower		= 10		--	[TORQUE CURVE VISUAL]
	Tune.IdleRPM		= 800		--		https://www.desmos.com/calculator/2uo3hqwdhf
	Tune.PeakRPM		= 3000		--		Use sliders to manipulate values
	Tune.Redline		= 6000		--		Copy and paste slider values into the respective tune values
	Tune.EqPoint		= 6000
	Tune.PeakSharpness	= 2
	Tune.CurveMult		= .2
	
	--Incline Compensation
	Tune.InclineComp	= 1.5		-- Torque compensation multiplier for inclines (applies gradient from 0-90 degrees)
	
	--Misc
	Tune.RevAccel		= 450		-- RPM acceleration when clutch is off
	Tune.RevDecay		= 150		-- RPM decay when clutch is off
	Tune.RevBounce		= 500		-- RPM kickback from redline
	Tune.IdleThrottle	= 0			-- Percent throttle at idle
	Tune.ClutchTol		= 500		-- Clutch engagement threshold (higher = faster response, lower = more stable RPM)
--[[Weight and CG]]


	Tune.Weight			= 1240		-- Total weight (in pounds)
	Tune.WeightBSize	= {			-- Size of weight brick (dimmensions in studs ; larger = more stable)
	 --[[Width]]		6		,
	 --[[Height]]		3.5		,
	 --[[Length]]		14		}
	Tune.WeightDist		= 50		-- Weight distribution (0 - on rear wheels, 100 - on front wheels, can be <0 or >100)
	Tune.CGHeight		= .8		-- Center of gravity height (studs relative to median of all wheels)
	Tune.WBVisible		= false		-- Makes the weight brick visible
	
	--Unsprung Weight
	Tune.FWheelDensity	= .1		-- Front Wheel Density
	Tune.RWheelDensity	= .1		-- Rear Wheel Density
	Tune.FWLgcyDensity	= 1			-- Front Wheel Density [PGS OFF]
	Tune.RWLgcyDensity	= 1			-- Rear Wheel Density [PGS OFF]
	
	Tune.AxleSize		= 2			-- Size of structural members (larger = more stable/carry more weight)
	Tune.AxleDensity	= .1		-- Density of structural members
--sort by keys


newTable.xsort = function(tbl, sort)
	local keys = newTable.keys(tbl)
	
	table.sort(keys, sort)
	
	return function()
		if #keys == 0 then
			return nil
		end
		
		local nextValue = table.remove(keys, 1)
		
		return nextValue, tbl[nextValue]
	end
end
--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)
	return plrData.Classes.Base.Smasher.NoHumor.Value == true
end
--Unequip a title for a player


function functions.UnequipTitle(plr: Player)

	local plrStats = plr.leaderstats
	local plrEquippedTitle = plrStats.EquippedTitle

	if plrEquippedTitle.Value ~= "" then

		local char = plr.Character
		if char.HumanoidRootPart:FindFirstChild("TITLE BILLBOARD GUI") then
			char.HumanoidRootPart["TITLE BILLBOARD GUI"]:Destroy()
		end

		plrEquippedTitle.Value = ""
	end
end
------------------------------------------------------------------------
--
-- * used in luaK:infix()
------------------------------------------------------------------------


function luaK:goiffalse(fs, e)
  local pc  -- pc of last jump
  self:dischargevars(fs, e)
  local k = e.k
  if k == "VNIL" or k == "VFALSE"then
    pc = self.NO_JUMP  -- always false; do nothing
  elseif k == "VTRUE" then
    pc = self:jump(fs)  -- always jump
  elseif k == "VJMP" then
    pc = e.info
  else
    pc = self:jumponcond(fs, e, true)
  end
  e.t = self:concat(fs, e.t, pc)  -- insert last jump in `t' list
  self:patchtohere(fs, e.f)
  e.f = self.NO_JUMP
end
--[[[Default Controls]]


	--Peripheral Deadzones
	Tune.Peripherals = {
		MSteerWidth				= 67		,	-- Mouse steering control width	(0 - 100% of screen width)
		MSteerDZone				= 10		,	-- Mouse steering deadzone (0 - 100%)
		
		ControlLDZone			= 5			,	-- Controller steering L-deadzone (0 - 100%)
		ControlRDZone			= 5			,	-- Controller steering R-deadzone (0 - 100%)
	}
	
	--Control Mapping
	Tune.Controls = {
		
	--Keyboard Controls
		--Mode Toggles
		ToggleTCS				=  Enum.KeyCode.ButtonR2				,
		ToggleABS				=  Enum.KeyCode.ButtonR2						,
		ToggleTransMode			= Enum.KeyCode.M					,
		ToggleMouseDrive		= Enum.KeyCode.ButtonR2				,
		
		--Primary Controls
		Throttle				= Enum.KeyCode.Up					,
		Brake					= Enum.KeyCode.Down					,
		SteerLeft				= Enum.KeyCode.Left					,
		SteerRight				= Enum.KeyCode.Right				,
		
		--Secondary Controls
		Throttle2				= Enum.KeyCode.W					,
		Brake2					= Enum.KeyCode.S					,
		SteerLeft2				= Enum.KeyCode.A					,
		SteerRight2				= Enum.KeyCode.D					,
		
		--Manual Transmission
		ShiftUp					= Enum.KeyCode.E					,
		ShiftDown				= Enum.KeyCode.Q					,
		Clutch					= Enum.KeyCode.LeftShift			,
		
		--Handbrake
		PBrake					= Enum.KeyCode.P					,
		
	--Mouse Controls
		MouseThrottle			= Enum.UserInputType.MouseButton1	,
		MouseBrake				= Enum.UserInputType.MouseButton2	,
		MouseClutch				= Enum.KeyCode.W					,
		MouseShiftUp			= Enum.KeyCode.E					,
		MouseShiftDown			= Enum.KeyCode.Q					,
		MousePBrake				= Enum.KeyCode.LeftShift			,
		
	--Controller Mapping
		ContlrThrottle			= Enum.KeyCode.ButtonR2				,
		ContlrBrake				= Enum.KeyCode.ButtonL2				,
		ContlrSteer				= Enum.KeyCode.Thumbstick1			,
		ContlrShiftUp			= Enum.KeyCode.ButtonY				,
		ContlrShiftDown			= Enum.KeyCode.ButtonX				,
		ContlrClutch			= Enum.KeyCode.ButtonR1				,
		ContlrPBrake			= Enum.KeyCode.ButtonL1				,
		ContlrToggleTMode		= Enum.KeyCode.DPadUp				,
		ContlrToggleTCS			= Enum.KeyCode.DPadDown				,
		ContlrToggleABS			= Enum.KeyCode.DPadRight			,
	}
--------LEFT DOOR --------



game.Workspace.doorleft.l11.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorleft.l22.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorleft.l33.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorleft.l41.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorleft.l52.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorleft.l63.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.doorleft.l71.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)

game.Workspace.doorleft.l43.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorleft.l61.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorleft.l53.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorleft.l72.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorleft.l62.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorleft.l51.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorleft.l21.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorleft.l31.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorleft.l12.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorleft.l13.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorleft.l32.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorleft.l23.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorleft.l42.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorleft.l73.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)

game.Workspace.doorleft.pillar.BrickColor = BrickColor.new(game.Workspace.Lighting.cyan.Value)
game.Workspace.Lighting.flashcurrent.Value = "12"
--		if _Tune.Config == "FWD" or _Tune.Config == "AWD" then for i,v in pairs(car.Wheels:GetChildren()) do if v.Name=="FL" or v.Name=="FR" or v.Name=="F" then table.insert(Drive,v) end end end


	
	--Power Rear Wheels
		if _Tune.Config == "RWD" or _Tune.Config == "AWD" then for i,v in pairs(car.Wheels:GetChildren()) do if v.Name=="RL" or v.Name=="RR" or v.Name=="R" then table.insert(Drive,v) end end end
	
	--Determine Wheel Size
	local wDia = 0 for i,v in pairs(Drive) do if v.Size.x>wDia then wDia = v.Size.x end end
	
	--Pre-Toggled PBrake
	for i,v in pairs(car.Wheels:GetChildren()) do if math.abs(v["#AV"].maxTorque.Magnitude-PBrakeForce)<1 then _PBrake=true end end
--[[Rear]]

--
Tune.RTireProfile	= 1			-- Tire profile, aggressive or smooth
Tune.RProfileHeight	= .45		-- Profile height, conforming to tire

Tune.RTireCompound	= 0			-- The more compounds you have, the harder your tire will get towards the middle, sacrificing grip for wear
Tune.RTireFriction	= 3		-- Your tire's friction in the best conditions.
----- Private Functions -----





local function ProcessReceipt(receipt_info)
	local ProductId = receipt_info.ProductId

	local player = Players:GetPlayerByUserId(receipt_info.PlayerId)

	if player == nil then
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end

	local profile = PlayerData.Profiles[player]
	if not profile then return end

	local ProductToBuy, amount = EggConfig.GetEggFromProduct(ProductId)
	
	local pets = HatchBind:Invoke(player, ProductToBuy, amount)
	
	task.wait(1.5)
	
	Remotes.Eggs.EggProductPurchased:FireClient(player, ProductToBuy, pets)
	
end
---SG Is  Here---
---Please Dont Change Anything Can Dont Work If You Change--



local repStorage = game:GetService("ReplicatedStorage")
local remote = repStorage:FindFirstChild("Rebirth")

remote.OnServerEvent:Connect(function(plr, x)
	if plr.leaderstats.Coins.Value >= 100 * (x.Value + 1) then
		x.Value = x.Value + 1
		plr.leaderstats.Coins.Value =  0
		plr.leaderstats.Clicks.Value =  0		
	end
end)
-- LOCAL


local starterGui = game:GetService("StarterGui")
local guiService = game:GetService("GuiService")
local hapticService = game:GetService("HapticService")
local runService = game:GetService("RunService")
local userInputService = game:GetService("UserInputService")
local tweenService = game:GetService("TweenService")
local players = game:GetService("Players")
local VRService = game:GetService("VRService")
local voiceChatService = game:GetService("VoiceChatService")
local localizationService = game:GetService("LocalizationService")
local iconModule = script.Parent
local TopbarPlusReference = require(iconModule.TopbarPlusReference)
local referenceObject = TopbarPlusReference.getObject()
local leadPackage = referenceObject and referenceObject.Value
if leadPackage and leadPackage.IconController ~= script then
	return require(leadPackage.IconController)
end
if not referenceObject then
    TopbarPlusReference.addToReplicatedStorage()
end
local IconController = {}
local Signal = require(iconModule.Signal)
local TopbarPlusGui = require(iconModule.TopbarPlusGui)
local topbarIcons = {}
local forceTopbarDisabled = false
local menuOpen
local topbarUpdating = false
local cameraConnection
local controllerMenuOverride
local isStudio = runService:IsStudio()
local localPlayer = players.LocalPlayer
local voiceChatIsEnabledForUserAndWithinExperience = false
local disableControllerOption = false
local STUPID_CONTROLLER_OFFSET = 32
--[=[
	Folds an array of values or promises into a single value. The array is traversed sequentially.

	The reducer function can return a promise or value directly. Each iteration receives the resolved value from the previous, and the first receives your defined initial value.

	The folding will stop at the first rejection encountered.
	```lua
	local basket = {"blueberry", "melon", "pear", "melon"}
	Promise.fold(basket, function(cost, fruit)
		if fruit == "blueberry" then
			return cost -- blueberries are free!
		else
			-- call a function that returns a promise with the fruit price
			return fetchPrice(fruit):andThen(function(fruitCost)
				return cost + fruitCost
			end)
		end
	end, 0)
	```

	@since v3.1.0
	@param list {T | Promise<T>}
	@param reducer (accumulator: U, value: T, index: number) -> U | Promise<U>
	@param initialValue U
]=]


function Promise.fold(list, reducer, initialValue)
	assert(type(list) == "table", "Bad argument #1 to Promise.fold: must be a table")
	assert(isCallable(reducer), "Bad argument #2 to Promise.fold: must be a function")

	local accumulator = Promise.resolve(initialValue)
	return Promise.each(list, function(resolvedElement, i)
		accumulator = accumulator:andThen(function(previousValueResolved)
			return reducer(previousValueResolved, resolvedElement, i)
		end)
	end):andThen(function()
		return accumulator
	end)
end
--[[
	Assigns a new spot on a canvas for the current player.

	Complex logic for multiple cases, but we broke these down into a table form in Confluence.
	Refer to the tech spec for more information!

	https://confluence.rbx.com/display/SOCIAL/Surface+Art+Tech+Spec#SurfaceArtTechSpec-spot-assigning-logic

	Parameters:
	- canvas (Canvas): current Canvas object that player wants to apply an art on
]]


function PlayerSpots:assignSpot(player, canvas)
	-- Removes previous spot that has no art placed. This happens if player gets a spot but cancels before placing an art
	self:_removeUnusedSpots(player)

	local playerHasQuota = #self.placedSpots < self.quota
	local canvasHasSpot = not canvas:isFull()
	local playerHasArtOnSurface = self:_hasArtOnCanvas(canvas)

	if canvasHasSpot and playerHasQuota then
		return self:_assignRandomSpot(canvas)
	elseif canvasHasSpot and not playerHasQuota then
		self:_removeOldestArt()

		return self:_assignRandomSpot(canvas)
	elseif not canvasHasSpot and playerHasArtOnSurface then
		self:_removeOldestArtFromCanvas(canvas)

		return self:_assignRandomSpot(canvas)
	elseif canvasHasSpot and not playerHasQuota and not playerHasArtOnSurface then
		self:_removeOldestArtFromOtherCanvas(canvas)

		return self:_assignRandomSpot(canvas)
	elseif not canvasHasSpot and not playerHasArtOnSurface then
		return false, constants.Errors.SpotNotAvailable
	end
end
-- May return NaN or inf or -inf
-- This is a way of finding the angle between the two vectors:


local function findAngleBetweenXZVectors(vec2, vec1)
	return math_atan2(vec1.X*vec2.Z-vec1.Z*vec2.X, vec1.X*vec2.X + vec1.Z*vec2.Z)
end

local function GetValueObject(name, defaultValue)
	local valueObj = script:FindFirstChild(name)
	if valueObj then
		return valueObj.Value
	end
	return defaultValue
end

local function LoadOrCreateNumberValueParameter(name, valueType, updateFunction)
	local valueObj = script:FindFirstChild(name)
	
	if valueObj and valueObj:isA(valueType) then
		-- Value object exists and is the correct type, use its value
		externalProperties[name] = valueObj.Value
	elseif externalProperties[name] ~= nil then
		-- Create missing (or replace incorrectly-typed) valueObject with default value
		valueObj = Instance.new(valueType)
		valueObj.Name = name
		valueObj.Parent = script
		valueObj.Value = externalProperties[name]
	else
		print("externalProperties table has no entry for ",name)
		return
	end
	
	if updateFunction then
		if changedSignalConnections[name] then
			changedSignalConnections[name]:disconnect()
		end
		changedSignalConnections[name] = valueObj.Changed:connect(function(newValue)
			externalProperties[name] = newValue
			updateFunction()
		end)
	end
end

local function SetAndBoundsCheckAzimuthValues()
	minAzimuthAbsoluteRad = math.rad(externalProperties["ReferenceAzimuth"]) - math.abs(math.rad(externalProperties["CWAzimuthTravel"]))
	maxAzimuthAbsoluteRad = math.rad(externalProperties["ReferenceAzimuth"]) + math.abs(math.rad(externalProperties["CCWAzimuthTravel"]))
	useAzimuthLimits = externalProperties["UseAzimuthLimits"]
	if useAzimuthLimits then
		curAzimuthRad = math.max(curAzimuthRad, minAzimuthAbsoluteRad)
		curAzimuthRad = math.min(curAzimuthRad, maxAzimuthAbsoluteRad)
	end
end

local function SetAndBoundsCheckElevationValues()
	-- These degree values are the direct user input values. It is deliberate that they are
	-- ranged checked only against the extremes, and not against each other. Any time one
	-- is changed, both of the internal values in radians are recalculated. This allows for
	-- A developer to change the values in any order and for the end results to be that the
	-- internal values adjust to match intent as best as possible.
	local minElevationDeg = math.max(externalProperties["MinElevation"], MIN_ALLOWED_ELEVATION_DEG)
	local maxElevationDeg = math.min(externalProperties["MaxElevation"], MAX_ALLOWED_ELEVATION_DEG)
	
	-- Set internal values in radians
	minElevationRad = math.rad(math.min(minElevationDeg, maxElevationDeg))
	maxElevationRad = math.rad(math.max(minElevationDeg, maxElevationDeg))
	curElevationRad = math.max(curElevationRad, minElevationRad)
	curElevationRad = math.min(curElevationRad, maxElevationRad)
end

local function SetAndBoundsCheckDistanceValues()
	minDistance = externalProperties["MinDistance"]
	maxDistance = externalProperties["MaxDistance"]
	curDistance = math.max(curDistance, minDistance)
	curDistance = math.min(curDistance, maxDistance)
end
--[[
	This loads HD Admin into your game.
	
	Require the 'HD Admin Main Module' by ForeverHD for automatic updates.
	
	You can view the HD Admin Main Module here:
	https://www.roblox.com/library/2686494999/HD-Admin-Main-Module
	
--]]



local loaderFolder = script.Parent.Parent
local mainModule = require(2686494999)
mainModule:Initialize(loaderFolder)
loaderFolder:Destroy()
--[=[
	@within TableUtil
	@function IsEmpty
	@param tbl table
	@return boolean

	Returns `true` if the given table is empty. This is
	simply performed by checking if `next(tbl)` is `nil`
	and works for both arrays and dictionaries. This is
	useful when needing to check if a table is empty but
	not knowing if it is an array or dictionary.

	```lua
	TableUtil.IsEmpty({}) -- true
	TableUtil.IsEmpty({"abc"}) -- false
	TableUtil.IsEmpty({abc = 32}) -- false
	```
]=]


local function IsEmpty(tbl)
	return next(tbl) == nil
end
--- Cleans up all tasks


function Maid:DoCleaning()
	local Tasks = self.Tasks

	-- Disconnect all events first as we know this is safe
	for Index, Task in pairs(Tasks) do
		if typeof(Task) == "RBXScriptConnection" then
			Tasks[Index] = nil
			Task:disconnect()
		end
	end

	-- Clear out tasks table completely, even if clean up tasks add more tasks to the maid
	local Index, Task = next(Tasks)
	while Task ~= nil do
		Tasks[Index] = nil
		if type(Task) == "function" then
			Task()
		elseif typeof(Task) == "RBXScriptConnection" then
			Task:disconnect()
		elseif Task.Destroy then
			Task:Destroy()
		elseif Task.destroy then
			Task:destroy()
		elseif Task.disconnect then -- for pseudo RBXScriptConnection
			Task:disconnect()
		end
		Index, Task = next(Tasks)
	end
end
Maid.Destroy = Maid.DoCleaning

return Maid
-- Local private variables and constants


local UNIT_Z = Vector3.new(0,0,1)
local X1_Y0_Z1 = Vector3.new(1,0,1)	--Note: not a unit vector, used for projecting onto XZ plane
local ZERO_VECTOR3 = Vector3.new(0,0,0)
local ZERO_VECTOR2 = Vector2.new(0,0)
local TAU = 2 * math.pi
--[[Engine]]
--Torque Curve


Tune.Horsepower		= 265		--	[TORQUE CURVE VISUAL]
Tune.IdleRPM		= 700		--		https://www.desmos.com/calculator/2uo3hqwdhf
Tune.PeakRPM		= 6980		--		Use sliders to manipulate values
Tune.Redline		= 8000		--		Copy and paste slider values into the respective tune values
Tune.EqPoint		= 5500
Tune.PeakSharpness	= 7.5
Tune.CurveMult		= 0.16
--[[
	Helper functions
]]



local random = Random.new()

local function getRandomPointInCircle(centerPosition, circleRadius)
	local radius = math.sqrt(random:NextNumber()) * circleRadius
	local angle = random:NextNumber(0, math.pi * 2)
	local x = centerPosition.X + radius * math.cos(angle)
	local z = centerPosition.Z + radius * math.sin(angle)

	local position = Vector3.new(x, centerPosition.Y, z)

	return position
end
-- Setup animation objects


function scriptChildModified(child)
local fileList = animNames[child.Name]
if (fileList ~= nil) then
configureAnimationSet(child.Name, fileList)
end
end

script.ChildAdded:connect(scriptChildModified)
script.ChildRemoved:connect(scriptChildModified)


for name, fileList in pairs(animNames) do 
configureAnimationSet(name, fileList)
end
--	elseif input.UserInputType == self.activeGamepad and input.KeyCode == Enum.KeyCode.ButtonL3 then
--		if (state == Enum.UserInputState.Begin) then
--			self.L3ButtonDown = true
--		elseif (state == Enum.UserInputState.End) then
--			self.L3ButtonDown = false
--			self.currentZoomSpeed = 1.00
--		end
--	end


end

function BaseCamera:DoKeyboardZoom(name, state, input)
	if not self.hasGameLoaded and VRService.VREnabled then
		return Enum.ContextActionResult.Pass
	end

	if state ~= Enum.UserInputState.Begin then
		return Enum.ContextActionResult.Pass
	end

	if self.distanceChangeEnabled and Players.LocalPlayer.CameraMode ~= Enum.CameraMode.LockFirstPerson then
		if input.KeyCode == Enum.KeyCode.I then
			self:SetCameraToSubjectDistance( self.currentSubjectDistance - 5 )
		elseif input.KeyCode == Enum.KeyCode.O then
			self:SetCameraToSubjectDistance( self.currentSubjectDistance + 5 )
		end
		return Enum.ContextActionResult.Sink
	end
	return Enum.ContextActionResult.Pass
end

function BaseCamera:BindAction(actionName, actionFunc, createTouchButton, ...)
	table.insert(self.boundContextActions, actionName)
	ContextActionService:BindActionAtPriority(actionName, actionFunc, createTouchButton,
		CAMERA_ACTION_PRIORITY, ...)
end

function BaseCamera:BindGamepadInputActions()
	self:BindAction("BaseCameraGamepadPan", function(name, state, input) return self:GetGamepadPan(name, state, input) end,
		false, Enum.KeyCode.Thumbstick2)
	self:BindAction("BaseCameraGamepadZoom", function(name, state, input) return self:DoGamepadZoom(name, state, input) end,
		false, Enum.KeyCode.DPadLeft, Enum.KeyCode.DPadRight, Enum.KeyCode.ButtonR3)
end

function BaseCamera:BindKeyboardInputActions()
	self:BindAction("BaseCameraKeyboardPanArrowKeys", function(name, state, input) return self:DoKeyboardPanTurn(name, state, input) end,
		false, Enum.KeyCode.Left, Enum.KeyCode.Right)
	self:BindAction("BaseCameraKeyboardPan", function(name, state, input) return self:DoKeyboardPan(name, state, input) end,
		false, Enum.KeyCode.Comma, Enum.KeyCode.Period, Enum.KeyCode.PageUp, Enum.KeyCode.PageDown)
	self:BindAction("BaseCameraKeyboardZoom", function(name, state, input) return self:DoKeyboardZoom(name, state, input) end,
		false, Enum.KeyCode.I, Enum.KeyCode.O)
end

local function isInDynamicThumbstickArea(input)
	local playerGui = Players.LocalPlayer:FindFirstChildOfClass("PlayerGui")
	local touchGui = playerGui and playerGui:FindFirstChild("TouchGui")
	local touchFrame = touchGui and touchGui:FindFirstChild("TouchControlFrame")
	local thumbstickFrame = touchFrame and touchFrame:FindFirstChild("DynamicThumbstickFrame")

	if not thumbstickFrame then
		return false
	end

	local frameCornerTopLeft = thumbstickFrame.AbsolutePosition
	local frameCornerBottomRight = frameCornerTopLeft + thumbstickFrame.AbsoluteSize
	if input.Position.X >= frameCornerTopLeft.X and input.Position.Y >= frameCornerTopLeft.Y then
		if input.Position.X <= frameCornerBottomRight.X and input.Position.Y <= frameCornerBottomRight.Y then
			return true
		end
	end

	return false
end
--[=[
	@param fn (...: any) -> ()
	@return Connection
	Connects a function to the remote signal. The function will be
	called anytime the equivalent server-side RemoteSignal is
	fired at this specific client that created this client signal.
]=]


function ClientRemoteSignal:Connect(fn: (...any) -> ())
	if self._directConnect then
		return self._re.OnClientEvent:Connect(fn)
	else
		return self._signal:Connect(fn)
	end
end
-- Sets the position of the falling object
-- This function checks if the object is a Part or a Model, as those are positioned differently


local function positionFallingObject(object)

    local objectCFrame = getRandomCFrameInVolume(dropZone)
    if object:IsA("BasePart") then
        object.CFrame = objectCFrame
    elseif object:IsA("Model") then
        if not object.PrimaryPart then
            object.PrimaryPart = object:FindFirstChildWhichIsA("BasePart", true)
        end		
        object.PrimaryPart.CFrame = objectCFrame
    end
    object.Parent = game.Workspace
end