Roblox/luau_corpus huggingface dataset:
--[=[
	Shares this observables state/computation with all down-stream observables. This can be useful
	when a very expensive computation was done and needs to be shared.

	Generally not needed.

	@param observable Observable<T>
	@return Observable<T>
]=]
function Blend.Shared(observable)
	return observable:Pipe({
		Rx.cache();
	})
end

function Blend.Dynamic(...)
	return Blend.Computed(...)
		:Pipe({
			-- This switch map is relatively expensive, so we don't do this for defaul computed
			-- and instead force the user to switch to another promise
			Rx.switchMap(function(promise, ...)
				if Promise.isPromise(promise) then
					return Rx.fromPromise(promise)
				elseif Observable.isObservable(promise) then
					return promise
				else
					return Rx.of(promise, ...)
				end
			end)
		})
end
--[[
	Handles client-side squash animations for the rooster NPCs around the market

	Note: Typically, using an actual AnimationTrack would be preferred because it gives more flexibility
	and is more performant than tweening properties. However, here we do the latter because this is a sample
	project, and use of animations is restricted to only the uploader. Therefore, if we used the Roblox animation system,
	the animations would not be available to anyone getting a standalone copy of this place.
--]]

local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local getInstance = require(ReplicatedStorage.Source.Utility.getInstance)

local SQUASH_FACTOR = 1.1
local ANIMATION_TIME = 0.6
local SQUASH_SCALAR = Vector3.new(SQUASH_FACTOR, 1 / SQUASH_FACTOR, SQUASH_FACTOR)

local random = Random.new()

local AnimatedRoosterNPC = {}
AnimatedRoosterNPC.__index = AnimatedRoosterNPC

export type ClassType = typeof(setmetatable(
	{} :: {
		_instance: Model,
		_loopedAnimationTween: Tween?,
	},
	AnimatedRoosterNPC
))

function AnimatedRoosterNPC.new(npcModel: Model): ClassType
	local self = {
		_instance = npcModel,
	}

	setmetatable(self, AnimatedRoosterNPC)

	-- Offset animations to add some variation across roosters
	task.delay(math.random() * ANIMATION_TIME, self._startAnimation, self)

	return self
end

function AnimatedRoosterNPC._startAnimation(self: ClassType)
	local mesh: MeshPart = getInstance(self._instance, "Mesh")
	local tweenInfo = TweenInfo.new(
		ANIMATION_TIME,
		Enum.EasingStyle.Back,
		Enum.EasingDirection.InOut,
		-1,
		true,
		random:NextNumber(1.5, 3)
	)
	local squashedMeshSize = mesh.Size * SQUASH_SCALAR

	local tween = TweenService:Create(mesh, tweenInfo, {
		Size = squashedMeshSize,
		CFrame = mesh.CFrame * CFrame.new(0, -(mesh.Size - squashedMeshSize).Y / 2, 0),
	})
	tween:Play()
	self._loopedAnimationTween = tween
end

function AnimatedRoosterNPC.destroy(self: ClassType)
	if self._loopedAnimationTween then
		self._loopedAnimationTween:Cancel()
	end
end

return AnimatedRoosterNPC
--- Same as indexing, but uses an incremented number as a key.
-- @param task An item to clean
-- @treturn number taskId
function Maid:GiveTask(task)
	assert(task)
	local taskId = #self._tasks+1
	self[taskId] = task
	return taskId
end

function Maid:GivePromise(promise)
	if not promise:IsPending() then
		return promise
	end

	local newPromise = promise.resolved(promise)
	local id = self:GiveTask(newPromise)

	-- Ensure GC
	newPromise:Finally(function()
		self[id] = nil
	end)

	return newPromise
end
--[[
	Provides an array of all item IDs in a specified parent, sorted by
	lowest purchase cost first, and alphabetical DisplayName second.

	This is used for items in the game meant to be displayed in a UI,
	such as pots and plants.
--]]

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Sift = require(ReplicatedStorage.Dependencies.Sift)
local Attribute = require(ReplicatedStorage.Source.SharedConstants.Attribute)
local ContainerByCategory = require(ReplicatedStorage.Source.SharedConstants.ContainerByCategory)
local ItemCategory = require(ReplicatedStorage.Source.SharedConstants.ItemCategory)

local getAttribute = require(ReplicatedStorage.Source.Utility.getAttribute)

local function getSortedIdsInCategory(itemCategory: ItemCategory.EnumType)
	local models = ContainerByCategory[itemCategory]:GetChildren()
	local sortedModels: { Instance } = Sift.Array.sort(models, function(itemA: Instance, itemB: Instance)
		-- Coin bundles don't have Display Names or Purchase Costs
		if itemCategory == ItemCategory.CoinBundles then
			local itemAValue: number = getAttribute(itemA, Attribute.CoinBundleSize)
			local itemBValue: number = getAttribute(itemB, Attribute.CoinBundleSize)

			return itemAValue < itemBValue
		else
			local itemAName: number = getAttribute(itemA, Attribute.DisplayName)
			local itemBName: number = getAttribute(itemB, Attribute.DisplayName)

			local itemAValue: number = getAttribute(itemA, Attribute.PurchaseCost)
			local itemBValue: number = getAttribute(itemB, Attribute.PurchaseCost)

			-- Sort by cost first, alphabetical display name second
			if itemAValue == itemBValue then
				return itemAName < itemBName
			else
				return itemAValue < itemBValue
			end
		end
	end)

	-- Convert the array of models to an array of item IDs
	local sortedItemIds: { string } = Sift.Array.map(sortedModels, function(itemModel: Instance)
		return itemModel.Name
	end)

	return sortedItemIds
end

return getSortedIdsInCategory
--[[

= Sonic Onset Adventure Client =

Source: ControlScript/Player/Input/TouchButton.lua
Purpose: Mobile Touch Button class
Author(s): Regan "CD/TheGreenDeveloper" Green
 (badia modded 🤑)
--]]

local touch_button = {}

local gui_service = game:GetService("GuiService")
local uis = game:GetService("UserInputService")
-- Electric Engine
Tune.Electric		= false

Tune.E_Redline	= 1600
Tune.E_Trans1	= 4000
Tune.E_Trans2	= 9000
--http://robloxdev.com/code-sample/Weld-Code-Sample-1
local function Weld(part0, part1, parent)
	local weld = Instance.new("WeldConstraint")
	weld.Part0 = part0
	weld.Part1 = part1
	weld.Parent = parent or part0
	
	return weld
end

local function WeldParts(parts, main, unanchor)
	for i,v in pairs(parts) do
		Weld(main, v)
	end
	
	if not unanchor then
		for i = 1, #parts do
			parts[i].Anchored = false
		end
		main.Anchored = false
	end
end
-- Function to check whether the player can send an invite
local function canSendGameInvite(sendingPlayer)
	local success, canSend = pcall(function()
		return SocialService:CanSendGameInviteAsync(sendingPlayer)
	end)
	return success and canSend
end

button.Activated:Connect(function()
	local canInvite = canSendGameInvite(player)
	if canInvite then
		local success, errorMessage = pcall(function()
			SocialService:PromptGameInvite(player)
		end)
	end
end)
-----------------
--| Functions |--
-----------------

function DamageTag(parent,damage)
	DmgTag = script.DamageTag:clone()
	DmgTag.Damage.Value = damage
	DmgTag.creator.Value = game.Players.LocalPlayer
	DmgTag.Disabled = false
	DmgTag.Parent = parent
end
-- find player's head pos

	local vCharacter = Tool.Parent
	local vPlayer = game.Players:playerFromCharacter(vCharacter)

	local head = vCharacter:findFirstChild("Head")
	if head == nil then return end


	local launch = head.Position + 10 * v

		

	local missile = pie:clone()
        		



	missile.CFrame = CFrame.new(launch,  launch + v)
	missile.Velocity = v * 50





	local force = Instance.new("BodyForce")
	force.force = Vector3.new(0,240,0)
	force.Parent = missile

	if (turbo) then
		missile.Velocity = v * 100
		force.force = Vector3.new(0,45,0)
	end

	local ps = script.Parent.PieScript:Clone()
	ps.Parent = missile
	missile.PieScript.Disabled = false

	

	local creator_tag = Instance.new("ObjectValue")
	creator_tag.Value = vCharacter
	creator_tag.Name = "creator"
	creator_tag.Parent = missile
	
	missile.Parent = game.Workspace

end



function rndDir()
	return Vector3.new(math.random() - .5, math.random() - .5, math.random() - .5).unit
end

Tool.Enabled = true
function onActivated()
	if not Tool.Enabled then
		return
	end

	Tool.Enabled = false

	local character = Tool.Parent;
	local humanoid = character.Humanoid
	if humanoid == nil then
		print("Humanoid not found")
		return 
	end
if loaded==true then
	loaded=false

	local targetPos = humanoid.TargetPoint
	local lookAt = (targetPos - character.Head.Position).unit

	fire(lookAt, isTurbo(character) )

	if (isTurbo(character) == true) then
		wait(.1)
		Tool.Parent.Torso["Right Shoulder"].MaxVelocity = 0.6
		Tool.Parent.Torso["Right Shoulder"].DesiredAngle = -3.6
		wait(.1)
		fire(lookAt * .9 + rndDir() * .1, isTurbo(character) )
		Tool.Parent.Torso["Right Shoulder"].MaxVelocity = 0.6
		Tool.Parent.Torso["Right Shoulder"].DesiredAngle = -3.6
		wait(.1)
		fire(lookAt * .8 + rndDir() * .2, isTurbo(character) )
		wait(.1)
	else
		wait(.3)
	end

	Tool.Enabled = true
elseif loaded==false then
Tool.Parent.Torso["Right Shoulder"].MaxVelocity = 0.6
Tool.Parent.Torso["Right Shoulder"].DesiredAngle = -3.6
	wait(.1)
Tool.Handle.Transparency=0
wait(.1)
	loaded=true
	end
	Tool.Enabled = true
end

script.Parent.Activated:connect(onActivated)
-- Replica destruction:
rev_ReplicaDestroy.OnClientEvent:Connect(function(replica_id) -- (replica_id)
	local replica = Replicas[replica_id]
	DestroyReplicaAndDescendantsRecursive(replica)
end)

return ReplicaController
------------------------------------------------------------------------	
	ltime = math.random(100,2000)
	print (ltime)
	for i=1,ltime do
	wait()
	local bewl = script.Parent:FindFirstChild("Bool")
	if bewl then
	local ignoreList = {}
	local ray = Ray.new(script.Parent.Part8.Position, missile.CFrame.lookVector * 999)
	local hit game.Workspace:FindPartOnRayWithIgnoreList(ray, ignoreList, false)
	local pos = script.Parent.Bool.Position
	local line = Instance.new("Part")
		line.Name = "Line"
		line.FormFactor = "Symmetric"
		line.Size = Vector3.new(1, 1, 1)
		line.BrickColor = BrickColor.new("White")
		line.Transparency = 0
		line.CanCollide = false
		line.Anchored = true
		line.Locked = true
		line.TopSurface, line.BottomSurface = 0, 0
		line.CFrame = CFrame.new(script.Parent.Part8.Position:lerp(pos, 0.5), pos)
		local mesh = Instance.new("BlockMesh", line)
		mesh.Scale = Vector3.new(0.03, 0.03, (script.Parent.Part8.Position - pos).magnitude)
		game.Debris:AddItem(line,0.08)
		line.Parent = script.Parent
		wait(0.001)

	else 
	print("No bool")
	break 
	end
	


	end
	
	local bewl = script.Parent:FindFirstChild("Bool")
	if bewl then
	bewl:Destroy()
	
	local character = script.Parent.Parent
	local player = game.Players:GetPlayerFromCharacter(character)
 	if player then
	script.Parent.Handle.Sound:Play()
	local ItemDirectory = game.ServerStorage.Assets.MobDrops.Fishing
	local FRAP = ItemDirectory:GetChildren()[math.random(1,#ItemDirectory:GetChildren())]:clone()
	FRAP.Parent = player.Backpack
	FRAP.Handle.CFrame =script.Parent.Handle.CFrame + Vector3.new(math.random(-5, 5), 3, math.random(-5, 5))
	end
	end
-- Decompiled with the Synapse X Luau decompiler.

local function u1(p1, p2, p3)
	local v1 = p3.X * p3.Y;
	local l__ImageRectSize__2 = p1.ImageRectSize;
	p2 = math.clamp(p2, 1, v1);
	local v3 = math.ceil(p2 / v1 * p3.Y);
	p1.ImageRectOffset = Vector2.new(l__ImageRectSize__2.X * (-1 + (p2 - p3.X * (v3 - 1))), l__ImageRectSize__2.Y * (-1 + v3));
end;
local l__RunService__2 = game:GetService("RunService");
return function(p4, p5, p6, p7, p8, p9)
	local v4 = Vector2.new(p5, p6);
	local v5 = tick();
	u1(p4, p5 * p6, v4);
	p4.Visible = true;
	local u3 = v5;
	local u4 = p7 and 60;
	local u5 = 0;
	local u6 = v4.X * v4.Y;
	local u7 = p8;
	task.defer(function()
		while p4 and p4.Parent do
			if 1 / u4 <= tick() - u3 then
				u3 = tick();
				u5 = u5 + 1;
				if u6 < u5 then
					u5 = 0;
					if not u7 then
						if p9 then
							p9();
							return;
						else
							break;
						end;
					end;
				end;
				u1(p4, u5, v4);
			end;
			l__RunService__2.RenderStepped:Wait();		
		end;
	end);
	return function()
		u7 = false;
	end;
end;
-- Another tip click Terrain then Decoration makesure to check it and turn it on!!! (MORE GRASS DETAIL)

script.Parent:Destory()
--------------------------------------------------------
function DeleteIdlePlane() --This deletes any planes that aren't currently being used
	for _,v in pairs(Planekit:GetChildren()) do
		if v.Name == "Plane" then
			v:Destroy()
		end
	end
end

function RegenMain() --This function regens the plane
	local PlaneClone2 = PlaneClone:clone()
	PlaneClone2.Parent = Planekit
	PlaneClone2.Origin.Value = Planekit
	PlaneClone2:MakeJoints()
	return PlaneClone2
end

function RegeneratePlane(Part) --This is the main regenerating function
	local Player = game.Players:GetPlayerFromCharacter(Part.Parent) --This gets the player that touched it
	if Player then
		if Active then
			Active = false
			DeleteIdlePlane() --This activates the "DeleteIdlePlane" function
			for i = 0,1,0.2 do --This makes the button transparent
				Main.Transparency = i
				wait()
			end
			if RegenTime >= 1 then
				RegenGui.Parent = Player.PlayerGui --The regengui will be put into the player if the regentime is more than 1
			end
			wait(RegenTime)
			RegenGui.Parent = script --This puts the gui back in the script
			local PlaneClone2 = RegenMain()
			if EnterOnSpawn.Value then --If the EnterOnSpawn value is true...
				coroutine.resume(coroutine.create(function()
					repeat wait() until PlaneClone2.Welded.Value
					onPlaneWelded(Player,PlaneClone2) --This activates the "onPlaneWelded" function whenever the welded value changes
				end))
			end
			wait(WaitTime)
			for i = 1,0,-0.2 do --This makes the button visible
				Main.Transparency = i
				wait()
			end
			Active = true
		end
	end
end

function onPlaneWelded(Player,Plane) --This function put you into the plane seat the moment the plane is welded
	if Plane and Player then --This checks to make sure there is a plane and a player
		if Player.Character:findFirstChild("Torso") then
			Player.Character.Torso.CFrame = Plane.MainParts.Seat.CFrame
		end
	end
end

Main.Touched:connect(RegeneratePlane) --This activates the "RegeneratePlane" function when the Main brick is touched
--[[	wait(3)

	tween:Play()
	wait(1)
	frame.Visible = false]]
end)
-- << FUNCTIONS >>
function module:GetData(dataStore, datastoreRetries, key)
	return module:DataStoreRetry(datastoreRetries, function()
		return dataStore:GetAsync(key)
	end)
end

function module:DataStoreRetry(datastoreRetries, dataStoreFunction)
	local tries = 0	
	local success = true
	local data = nil
	local errorMsg = ""
	repeat
		tries = tries + 1
		success, errorMsg = pcall(function() data = dataStoreFunction() end)
		if not success then wait(1) end
	until tries == datastoreRetries or success
	if not success then
		--warn("HD Admin | Could not access DataStore | ".. tostring(errorMsg))
		-- Cannot access DataStore
	end
	return success, data
end



return module
-- Decompiled with the Synapse X Luau decompiler.

local u1 = nil;
coroutine.wrap(function()
	u1 = require(game.ReplicatedStorage:WaitForChild("Framework"):WaitForChild("Library"));
end)();
return function(p1, p2)
	return u1.Functions.RadDeltaUnsafe(u1.Functions.RadNorm(p1), u1.Functions.RadNorm(p2));
end;
--Jitler is Pogi

local Sound = script.Parent.Sound
local Tada = Sound.Tada
local StarterGui = game:GetService("StarterGui")
StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.All, true)
local Frame = script.Parent.MainFrame

local hit = false
game.Workspace.Map.Pad.Touched:connect(function(part)
	wait(.3)
	if part.Parent.Name == game.Players.LocalPlayer.Name then
		
		if not hit then
			hit = true
			part.Parent.Humanoid.WalkSpeed = 0
			script.Parent.ImageLabel:TweenPosition(UDim2.new(0.5, 0, 0, 0), "Out", "Quint", 1)
			script.Parent.ImageLabel2:TweenPosition(UDim2.new(0, 0, 0, 0), "Out", "Quint", 1)
			wait(0.7)
			StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.All, false)
			spawn(function()
				wait(.3)
				Frame.Visible = true
			end)
			wait(1.5)
			script.Parent.ImageLabel:TweenPosition(UDim2.new(0.5, 1000, 0, 0), "In", "Quint", 1)
			script.Parent.ImageLabel2:TweenPosition(UDim2.new(0, -1000, 0, 0), "In", "Quint", 1)
			spawn(function()
				wait(.2)
				Tada:Play()
			end)
			wait(1)
			script.Parent.ImageLabel.Visible = false
			script.Parent.ImageLabel2.Visible = false
		end
	end
end)
--	first reset scrollingFrame to zero position
	scrollingFrame.CanvasPosition = Vector2.new(0, 0)
	local width = scrollingFrame.AbsoluteSize.X
	local height = scrollingFrame.AbsoluteSize.Y

	local isBottom = false
	local instance
	local threshold = 2
	while not isBottom do
		wait(0.1)
		--if find the element then return
		instance = absPath:getFirstInstance()
		if instance then return instance end
		--scroll
		local oldPosition = scrollingFrame.CanvasPosition
		scrollingFrame.CanvasPosition = scrollingFrame.CanvasPosition +
			Vector2.new(math.min(width, 300), math.min(height, 300))
		--wait for content to refresh
		local delta = scrollingFrame.CanvasPosition - oldPosition
		isBottom = delta.Magnitude < threshold
		--if it is the bottom, then return not found
	end
	return nil
end

function Element:centralizeWithInfiniteScrolling()
	local instances, lastSeenIndex = self.path:getInstances()
	if #instances > 0 then self:centralizeInstance() end

	local lastSeenPath = self.path:copy()
	while #lastSeenPath.data > lastSeenIndex do
		table.remove(lastSeenPath.data)
	end

	local lastSeenInstance = lastSeenPath:getFirstInstance()
	local lastScrollingFrame = nil
	while true do
		if lastSeenInstance.ClassName == "ScrollingFrame" then
			lastScrollingFrame = lastSeenInstance
			break
		end
		lastSeenInstance = lastSeenInstance.Parent
		if lastSeenInstance == game then break end
	end
	if lastScrollingFrame == nil then return end
	if self:_scrollToFindInstance(lastScrollingFrame, self.path) == nil then return end
	self:_centralizeInScrollingFrame(self:getRbxInstance())
end

function Element:setPluginWindow()
	local window = self.rbxInstance:FindFirstAncestorOfClass("DockWidgetPluginGui")
	VirtualInput.setCurrentWindow(window)
end

function Element:click(repeatCount)
	self:centralize()
	self:setPluginWindow()

	repeatCount = repeatCount or 1
	VirtualInput.Mouse.multiClick(self:getAnchor(), repeatCount)
end

function Element:rightClick()
	self:centralize()
	self:setPluginWindow()

	VirtualInput.Mouse.rightClick(self:getAnchor())
end

function Element:mouseWheel(num)
	self:centralize()
	VirtualInput.Mouse.mouseWheel(self:getAnchor(), num)
end

function Element:mouseDrag(xOffset, yOffset, duration)
	self:centralize()
	local posTo = self:getAnchor() + Vector2.new(xOffset, yOffset)
	VirtualInput.Mouse.mouseDrag(self:getAnchor(), posTo, duration, true)
end

function Element:mouseDragTo(posTo, duration)
	self:centralize()
	VirtualInput.Mouse.mouseDrag(self:getAnchor(), posTo, duration, true)
end

function Element:sendKey(key)
	self:setPluginWindow()
	VirtualInput.Keyboard.hitKey(key)
end

function Element:sendText(str)
	self:click()
	wait(0)
	VirtualInput.Text.sendText(str)
end

function Element:tap()
	self:centralize()
	VirtualInput.Touch.tap(self:getAnchor())
end

function Element:touchScroll(xOffset, yOffset, duration, multitouchId)
	self:centralize()
	VirtualInput.Touch.touchScroll(self:getAnchor(), xOffset, yOffset, duration, true, multitouchId)
end

return Element
--Serverside logic
Event.OnServerEvent:Connect(function(player,ExhaustParticle,FireBool)
	
	print("ExhaustParticle")
	
	if FireBool then
		
		local RanNum = tostring(math.random(1,3))
		ExhaustPart["Backfire"..RanNum]:Play()
        ExhaustPart2["Backfire"..RanNum]:Play()
		ExhaustPart.PointLight.Enabled = true
        ExhaustPart2.PointLight.Enabled = true
		ExhaustPart[ExhaustParticle].Enabled = true
        ExhaustPart2[ExhaustParticle].Enabled = true
		
		if ExhaustParticle == "FlamesSmall" then 
			
			ExhaustPart.PointLight.Range = 6
            ExhaustPart2.PointLight.Range = 6
			ExhaustPart.PointLight.Brightness = 5
            ExhaustPart2.PointLight.Brightness = 5
			ExhaustPart.Sparks.Enabled = false
            ExhaustPart2.Sparks.Enabled = false
			
		else 
			
			ExhaustPart.PointLight.Range = 8
            ExhaustPart2.PointLight.Range = 8
			ExhaustPart.PointLight.Brightness = 12
            ExhaustPart2.PointLight.Brightness = 12
			ExhaustPart.Sparks.Enabled = true
            ExhaustPart2.Sparks.Enabled = true
			
		end	
		
	else
		
		ExhaustPart[ExhaustParticle].Enabled = false
        ExhaustPart2[ExhaustParticle].Enabled = false
		ExhaustPart.PointLight.Enabled = false
        ExhaustPart2.PointLight.Enabled = false
		
	end	
	
end)
--[[ Local Functions ]]--
function MouseLockController:OnMouseLockToggled()
	self.isMouseLocked = not self.isMouseLocked

	if self.isMouseLocked then
		local cursorImageValueObj: StringValue? = script:FindFirstChild("CursorImage") :: StringValue?
		if cursorImageValueObj and cursorImageValueObj:IsA("StringValue") and cursorImageValueObj.Value then
			CameraUtils.setMouseIconOverride(cursorImageValueObj.Value)
		else
			if cursorImageValueObj then
				cursorImageValueObj:Destroy()
			end
			cursorImageValueObj = Instance.new("StringValue")
			assert(cursorImageValueObj, "")
			cursorImageValueObj.Name = "CursorImage"
			cursorImageValueObj.Value = DEFAULT_MOUSE_LOCK_CURSOR
			cursorImageValueObj.Parent = script
			CameraUtils.setMouseIconOverride(DEFAULT_MOUSE_LOCK_CURSOR)
		end
	else
		CameraUtils.restoreMouseIcon()
	end

	self.mouseLockToggledEvent:Fire()
end

function MouseLockController:DoMouseLockSwitch(name, state, input)
	if state == Enum.UserInputState.Begin then
		self:OnMouseLockToggled()
		return Enum.ContextActionResult.Sink
	end
	return Enum.ContextActionResult.Pass
end

function MouseLockController:BindContextActions()
	ContextActionService:BindActionAtPriority(CONTEXT_ACTION_NAME, function(name, state, input)
		return self:DoMouseLockSwitch(name, state, input)
	end, false, MOUSELOCK_ACTION_PRIORITY, unpack(self.boundKeys))
end

function MouseLockController:UnbindContextActions()
	ContextActionService:UnbindAction(CONTEXT_ACTION_NAME)
end

function MouseLockController:IsMouseLocked(): boolean
	return self.enabled and self.isMouseLocked
end

function MouseLockController:EnableMouseLock(enable: boolean)
	if enable ~= self.enabled then

		self.enabled = enable

		if self.enabled then
			-- Enabling the mode
			self:BindContextActions()
		else
			-- Disabling
			-- Restore mouse cursor
			CameraUtils.restoreMouseIcon()

			self:UnbindContextActions()

			-- If the mode is disabled while being used, fire the event to toggle it off
			if self.isMouseLocked then
				self.mouseLockToggledEvent:Fire()
			end

			self.isMouseLocked = false
		end

	end
end

return MouseLockController
--[[Transmission]]
	Tune.TransModes		= {"Auto", "Semi", "Manual"}								--[[
	[Modes]
		"Auto"		: Automatic shifting
		"Semi"		: Clutchless manual shifting, dual clutch transmission
		"Manual"	: Manual shifting with clutch
		
		>Include within brackets
			eg: {"Semi"} or {"Auto", "Manual"}								
		>First mode is default mode													]]
	
	--Automatic Settings
	Tune.AutoShiftMode	= "Speed"												--[[
	[Modes]
		"Speed"		: Shifts based on wheel speed
		"RPM"		: Shifts based on RPM											]]	
	Tune.AutoUpThresh	= -200		--Automatic upshift point 	(relative to peak RPM, positive = Over-rev)
	Tune.AutoDownThresh = 1400		--Automatic downshift point (relative to peak RPM, positive = Under-rev)
	
	--Gear Ratios
	Tune.FinalDrive		= 4.06			-- Gearing determines top speed and wheel torque
	Tune.Ratios			= {				-- Higher ratio = more torque, Lower ratio = higher top speed
		--[[Reverse]]	3.70		,	-- Copy and paste a ratio to add a gear
		--[[Neutral]]	0			,	-- Ratios can also be deleted
		--[[ 1 ]]		3.53		,	-- Reverse, Neutral, and 1st gear are required
		--[[ 2 ]]		2.04		,
		--[[ 3 ]]		1.38		,
		--[[ 4 ]]		1.03		,
		--[[ 5 ]]		0.81		,
		--[[ 6 ]]		0.64		,
		--[[ 7 ]]		0.49		,
		--[[ 8 ]]		0.40		,
	}
	Tune.FDMult			= 1.5			-- Ratio multiplier (Change this value instead of FinalDrive if car is struggling with torque ; Default = 1)
--[[Brakes]]
	Tune.ABSEnabled		= false		-- Implements ABS
	Tune.ABSThreshold	= 20		-- Slip speed allowed before ABS starts working (in SPS) 

	Tune.FBrakeForce	= 1200		-- Front brake force
	Tune.RBrakeForce	= 1600		-- Rear brake force
	Tune.PBrakeForce	= 6000		-- Handbrake force
	
	Tune.FLgcyBForce	= 15000		-- Front brake force [PGS OFF]
	Tune.RLgcyBForce	= 10000		-- Rear brake force [PGS OFF]
	Tune.LgcyPBForce	= 25000		-- Handbrake force [PGS OFF]