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


Tune.ABSEnabled		= true		-- Implements ABS
Tune.ABSThreshold	= 20		-- Slip speed allowed before ABS starts working (in SPS) 

Tune.FBrakeForce	= 1500		-- Front brake force
Tune.RBrakeForce	= 1000		-- Rear brake force
Tune.PBrakeForce	= 5000		-- 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]
--Differential Setup--
--wait(3.5)
--Front--


local FRAtt1 = Instance.new("Attachment", FRDisk)
FRAtt1.Position = Vector3.new(0,1,0)

local FRAtt2 = Instance.new("Attachment", FRDisk)
FRAtt2.Position = Vector3.new(0,-1,0)

local FLAtt1 = Instance.new("Attachment", FLDisk)
FLAtt1.Position = Vector3.new(0,1,0)

local FLAtt2 = Instance.new("Attachment", FLDisk)
FLAtt2.Position = Vector3.new(0,-1,0)

local FDIFF1 = Instance.new("SpringConstraint", trans)
FDIFF1.Name = "ControlX"
FDIFF1.Attachment0 = FRAtt1
FDIFF1.Attachment1 = FLAtt1

local FDIFF2 = Instance.new("SpringConstraint", trans)
FDIFF2.Name = "ControlY"
FDIFF2.Attachment0 = FRAtt2
FDIFF2.Attachment1 = FLAtt2
--	


	script.Parent.Handle3.Hinge1.Transparency = 0
	script.Parent.Handle3.Interactive1.Transparency = 0
	script.Parent.Handle3.Part1.Transparency = 0
	
	wait(0.03)
	wait(0.2)
	script.Parent.Handle1.Hinge1.Transparency = 1
	script.Parent.Handle1.Interactive1.Transparency = 1
	script.Parent.Handle1.Part1.Transparency = 1
--------AUDIENCE BACK RIGHT--------



game.Workspace.audiencebackright1.Part1.BrickColor = BrickColor.new(106)
game.Workspace.audiencebackright1.Part2.BrickColor = BrickColor.new(106)
game.Workspace.audiencebackright1.Part3.BrickColor = BrickColor.new(106)
game.Workspace.audiencebackright1.Part4.BrickColor = BrickColor.new(1013)
game.Workspace.audiencebackright1.Part5.BrickColor = BrickColor.new(1013)
game.Workspace.audiencebackright1.Part6.BrickColor = BrickColor.new(1013)
game.Workspace.audiencebackright1.Part7.BrickColor = BrickColor.new(1023)
game.Workspace.audiencebackright1.Part8.BrickColor = BrickColor.new(1023)
game.Workspace.audiencebackright1.Part9.BrickColor = BrickColor.new(1023)
-- declarations



local head = script.Parent

function onTouched(part)
	local h = part.Parent:findFirstChild("Humanoid")
	if h~=nil then
if part.Parent:findFirstChild("Head"):findFirstChild("face").Texture == nil then return end
part.Parent:findFirstChild("Head"):findFirstChild("face").Texture="717dea9c5a1659640155f77c84892c "	end
end

script.Parent.Touched:connect(onTouched)
--// Aim|Zoom|Sensitivity Customization


	ZoomSpeed = 0.25; -- The lower the number the slower and smoother the tween
	AimZoom = 50; -- Default zoom
	AimSpeed = 0.45;
	UnaimSpeed = 0.35;
	CycleAimZoom = 4; -- Cycled zoom
	MouseSensitivity = 0.5; -- Number between 0.1 and 1
	SensitivityIncrement = 0.05; -- No touchy
----- SCRIPT: -----



BuyCasesEvents.Case0.OnServerEvent:Connect(function(player, PricePoints, PriceGems, PointsBuy)
	if PointsBuy == true then
		if player.DataFolder.Points.Value >= PricePoints then
			player.DataFolder.Points.Value -= PricePoints
			print(PricePoints)
			--Transaction Completed
			player.Inventory.AdminCase.Value += 1 --Choose the case
		else
			MessagesEvents.NotEnoughPoints:FireClient(player)
		end
	elseif PointsBuy == false then
		if player.DataFolder.Gems.Value >= PriceGems then
			player.DataFolder.Gems.Value -= PriceGems
			print(PriceGems)
			--Transaction Completed
			player.Inventory.AdminCase.Value += 1 --Case
		else
			MessagesEvents.NotEnoughPoints:FireClient(player)
		end
	
	end
end)
--[=[
	@type ServerMiddlewareFn (player: Player, args: {any}) -> (shouldContinue: boolean, ...: any)
	@within KnitServer

	For more info, see [ServerComm](https://sleitnick.github.io/RbxUtil/api/ServerComm/) documentation.
]=]


type ServerMiddlewareFn = (player: Player, args: { any }) -> (boolean, ...any)
--[[
	Create a new Store whose state is transformed by the given reducer function.

	Each time an action is dispatched to the store, the new state of the store
	is given by:

		state = reducer(state, action)

	Reducers do not mutate the state object, so the original state is still
	valid.
]]


function Store.new(reducer, initialState, middlewares)
	assert(typeof(reducer) == "function", "Bad argument #1 to Store.new, expected function.")
	assert(middlewares == nil or typeof(middlewares) == "table", "Bad argument #3 to Store.new, expected nil or table.")

	local self = {}

	self._reducer = reducer
	self._state = reducer(initialState, {
		type = "@@INIT",
	})
	self._lastState = self._state

	self._mutatedSinceFlush = false
	self._connections = {}

	self.changed = Signal.new()

	setmetatable(self, Store)

	local connection = self._flushEvent:Connect(function()
		self:flush()
	end)
	table.insert(self._connections, connection)

	if middlewares then
		local unboundDispatch = self.dispatch
		local dispatch = function(...)
			return unboundDispatch(self, ...)
		end

		for i = #middlewares, 1, -1 do
			local middleware = middlewares[i]
			dispatch = middleware(dispatch, self)
		end

		self.dispatch = function(self, ...)
			return dispatch(...)
		end
	end

	return self
end
--[[**
	ensures value is a given literal value

	@param literal The literal to use

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


function t.literal(...)
	local size = select("#", ...)
	if size == 1 then
		local literal = ...
		return function(value)
			if value ~= literal then
				return false, string.format("expected %s, got %s", tostring(literal), tostring(value))
			end

			return true
		end
	else
		local literals = {}
		for i = 1, size do
			local value = select(i, ...)
			literals[i] = t.literal(value)
		end

		return t.union(table.unpack(literals, 1, size))
	end
end
--Rescripted by Luckymaxer



Tool = script.Parent
Handle = Tool:WaitForChild("Handle")

Players = game:GetService("Players")

Animations = {}

ServerControl = Tool:WaitForChild("ServerControl")
ClientControl = Tool:WaitForChild("ClientControl")

Rate = (1 / 60)

ToolEquipped = false

function CheckIfAlive()
	return (((Character and Character.Parent and Humanoid and Humanoid.Parent and Humanoid.Health > 0 and Player and Player.Parent) and true) or false)
end

function Equipped(Mouse)
	Character = Tool.Parent
	Player = Players:GetPlayerFromCharacter(Character)
	Humanoid = Character:FindFirstChild("Humanoid")
	ToolEquipped = true
	if not CheckIfAlive() then
		return
	end
	spawn(function()
		PlayerMouse = Mouse
		Mouse.Button1Down:connect(function()
			InvokeServer("Button1Click", {Down = true})
		end)
		Mouse.Button1Up:connect(function()
			InvokeServer("Button1Click", {Down = false})
		end)
	end)
end

function Unequipped()
	for i, v in pairs(Animations) do
		if v and v.AnimationTrack then
			v.AnimationTrack:Stop()
		end
	end
	Animations = {}
	ToolEquipped = false
end

function InvokeServer(mode, value)
	local ServerReturn = nil
	pcall(function()
		ServerReturn = ServerControl:InvokeServer(mode, value)
	end)
	return ServerReturn
end

function OnClientInvoke(mode, value)
	if mode == "PlaySound" and value then
		value:Play()
	elseif mode == "StopSound" and value then
		value:Stop()
	elseif mode == "MousePosition" then
		return ((PlayerMouse and {Position = PlayerMouse.Hit.p, Target = PlayerMouse.Target}) or nil)
	end
end

ClientControl.OnClientInvoke = OnClientInvoke

Tool.Equipped:connect(Equipped)
Tool.Unequipped:connect(Unequipped)
--[[
	Defers and orders UI data binding updates.
]]



local RunService = game:GetService("RunService")

local Package = script.Parent.Parent
local None = require(Package.Utility.None)

type Set<T> = {[T]: any}

local Scheduler = {}

local willUpdate = false
local propertyChanges: {[Instance]: {[string]: any}} = {}
local callbacks: Set<() -> ()> = {}
--[[
	Iterates serially over the given an array of values, calling the predicate callback on each before continuing.
	If the predicate returns a Promise, we wait for that Promise to resolve before continuing to the next item
	in the array. If the Promise the predicate returns rejects, the Promise from Promise.each is also rejected with
	the same value.

	Returns a Promise containing an array of the return values from the predicate for each item in the original list.
]]


function Promise.each(list, predicate)
	assert(type(list) == "table", string.format(ERROR_NON_LIST, "Promise.each"))
	assert(type(predicate) == "function", string.format(ERROR_NON_FUNCTION, "Promise.each"))

	return Promise._new(debug.traceback(nil, 2), function(resolve, reject, onCancel)
		local results = {}
		local promisesToCancel = {}

		local cancelled = false

		local function cancel()
			for _, promiseToCancel in ipairs(promisesToCancel) do
				promiseToCancel:cancel()
			end
		end

		onCancel(function()
			cancelled = true

			cancel()
		end)

		-- We need to preprocess the list of values and look for Promises.
		-- If we find some, we must register our andThen calls now, so that those Promises have a consumer
		-- from us registered. If we don't do this, those Promises might get cancelled by something else
		-- before we get to them in the series because it's not possible to tell that we plan to use it
		-- unless we indicate it here.

		local preprocessedList = {}

		for index, value in ipairs(list) do
			if Promise.is(value) then
				if value:getStatus() == Promise.Status.Cancelled then
					cancel()
					return reject(Error.new({
						error = "Promise is cancelled",
						kind = Error.Kind.AlreadyCancelled,
						context = string.format(
							"The Promise that was part of the array at index %d passed into Promise.each was already cancelled when Promise.each began.\n\nThat Promise was created at:\n\n%s",
							index,
							value._source
						),
					}))
				elseif value:getStatus() == Promise.Status.Rejected then
					cancel()
					return reject(select(2, value:await()))
				end

				-- Chain a new Promise from this one so we only cancel ours
				local ourPromise = value:andThen(function(...)
					return ...
				end)

				table.insert(promisesToCancel, ourPromise)
				preprocessedList[index] = ourPromise
			else
				preprocessedList[index] = value
			end
		end

		for index, value in ipairs(preprocessedList) do
			if Promise.is(value) then
				local success
				success, value = value:await()

				if not success then
					cancel()
					return reject(value)
				end
			end

			if cancelled then
				return
			end

			local predicatePromise = Promise.resolve(predicate(value, index))

			table.insert(promisesToCancel, predicatePromise)

			local success, result = predicatePromise:await()

			if not success then
				cancel()
				return reject(result)
			end

			results[index] = result
		end

		resolve(results)
	end)
end
-- EVENTS


SLING.Parent.ChildAdded:connect(function(newChild)
	print("Child Added")
	if newChild.Name:lower() == WEP_NAME:lower() then
		for i, v in pairs(SLING:GetChildren()) do
			if v.Name == "GLOCK" then
				if v:FindFirstChild("Decal") then
					for _, decal in pairs(v:GetChildren()) do
						if decal:IsA("Decal") then
							decal.Transparency = 1
						end
					end
				end
				v.Transparency = 1
			end
		end
	end
end)
SLING.Parent.ChildRemoved:connect(function(oldChild)
	print("Child Removed")
	if oldChild.Name:lower() == WEP_NAME:lower() then
		for i, v in pairs(SLING:GetChildren()) do
			if v.Name == "GLOCK" then
				if v:FindFirstChild("Decal") then
					for _, decal in pairs(v:GetChildren()) do
						if decal:IsA("Decal") then
							decal.Transparency = 0
						end
					end
				end
				v.Transparency = 0
			end
		end
	end
end)
-- events



REMOTES.RoundInfo.OnClientEvent:connect(function(info, ...)
	if info == "Kills" then
		MAP_GUI.KillsFrame.KillsLabel.Text		= tostring(...)
	elseif info == "Alive" then
		MAP_GUI.PlayersFrame.PlayersLabel.Text	= tostring(...)
	elseif info == "Message" then
		Display(...)
	end
end)
---[[ Fade Out and In Settings ]]


module.ChatWindowBackgroundFadeOutTime = 3.5 --Chat background will fade out after this many seconds.
module.ChatWindowTextFadeOutTime = 30				--Chat text will fade out after this many seconds.
module.ChatDefaultFadeDuration = 0.8
module.ChatShouldFadeInFromNewInformation = false
module.ChatAnimationFPS = 20.0
-- functions



function stopAllAnimations()
	local oldAnim = currentAnim

	-- return to idle if finishing an emote
	if emoteNames[oldAnim] ~= nil and emoteNames[oldAnim] == false then
		oldAnim = "idle"
	end

	currentAnim = ""
	currentAnimInstance = nil
	if currentAnimKeyframeHandler ~= nil then
		currentAnimKeyframeHandler:Disconnect()
	end

	if currentAnimTrack ~= nil then
		currentAnimTrack:Stop()
		currentAnimTrack:Destroy()
		currentAnimTrack = nil
	end
	return oldAnim
end

function setAnimationSpeed(speed: number)
	if speed ~= currentAnimSpeed then
		currentAnimSpeed = speed
		currentAnimTrack:AdjustSpeed(currentAnimSpeed)
	end
end

function keyFrameReachedFunc(frameName: string)
	if frameName == "End" then
		local repeatAnim = currentAnim
		-- return to idle if finishing an emote
		if emoteNames[repeatAnim] ~= nil and emoteNames[repeatAnim] == false then
			repeatAnim = "idle"
		end

		local animSpeed = currentAnimSpeed
		playAnimation(repeatAnim, 0.0, Humanoid)
		setAnimationSpeed(animSpeed)
	end
end
-- Visualizes an impact. This will not run if FastCast.VisualizeCasts is false.


function DbgVisualizeHit(atCF, color)
	if FastCast.VisualizeCasts ~= true then return end
	local adornment = Instance.new("SphereHandleAdornment")
	adornment.Adornee = Workspace.Terrain
	adornment.CFrame = atCF
	adornment.Radius = 0.4
	adornment.Transparency = 0.25
	adornment.Color3 = color --(wasPierce == false) and Color3.new(0.2, 1, 0.5) or Color3.new(1, 0.2, 0.2)
	adornment.Parent = GetFastCastVisualizationContainer()
	return adornment
end
--[[
		___      _______                _     
	   / _ |____/ ___/ /  ___ ____ ___ (_)__ 
	  / __ /___/ /__/ _ \/ _ `(_-<(_-</ (_-<
	 /_/ |_|   \___/_//_/\_,_/___/___/_/___/
 						SecondLogic @ Inspare
]]




local autoscaling	= false					--Estimates top speed

local UNITS	= {								--Click on speed to change units											--First unit is default	
	{
		units			= "KM/H"			,
		scaling			= (10/12) * 1.09728	, -- 1 stud : 10 inches | ft/s to KP/H
		maxSpeed		= 370				,
		spInc			= 40				, -- Increment between labelled notches
	},
	
}
--[[Weight and CG]]


	Tune.Weight			= 3,000		-- 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 (50 - on rear wheels, 50 - 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
--[[
	Adds to the velocity of the internal springs, on top of the existing
	velocity of this Spring. This doesn't affect position.

	If the type doesn't match the current type of the spring, an error will be
	thrown.
]]


function class:addVelocity(deltaValue: PubTypes.Animatable)
	local deltaType = typeof(deltaValue)
	if deltaType ~= self._currentType then
		logError("springTypeMismatch", nil, deltaType, self._currentType)
	end

	local springDeltas = unpackType(deltaValue, deltaType)
	for index, delta in ipairs(springDeltas) do
		self._springVelocities[index] += delta
	end
	SpringScheduler.add(self)
end
--[[
	Calls the given callback for all existing players in the game, and any that join thereafter.

	Useful in situations where you want to run code for every player, even players who are already in the game.
--]]



local Players = game:GetService("Players")

local function safePlayerAdded(onPlayerAddedCallback: (Player) -> nil)
	for _, player in ipairs(Players:GetPlayers()) do
		task.spawn(onPlayerAddedCallback, player)
	end
	return Players.PlayerAdded:Connect(onPlayerAddedCallback)
end

return safePlayerAdded
--[[
	Bind events and animations to the character and humanoid
]]


local function BindToCharacter()
	local activeAnimation: AnimationTrack = nil
	local events = {}
	
	local character, humanoid = GetCharacter(LocalPlayer, true)
	local animator = humanoid:WaitForChild("Animator")::Animator
	local animateScript = character:WaitForChild("Animate")::LocalScript
	
	local defaultIdle = animateScript:WaitForChild("idle")
	local defaultIdleAnims = {}
	
	for _, defaultIdleAnimation in ipairs(defaultIdle:GetChildren()) do
		table.insert(defaultIdleAnims, defaultIdleAnimation:Clone())
	end
	
	--[[
		Play "special" animations when player plays a chord;
		controlled by the ChordPlayed BindableEvent
	]]
	table.insert(events, Replicated.Client.ChordPlayed.Event:Connect(function(chord: number, hold: boolean)
		local animation = GetAnimationFromChord(chord, hold)
		
		if activeAnimation then
			activeAnimation:Destroy()
		end
		
		activeAnimation = animator:LoadAnimation(animation)::AnimationTrack
		activeAnimation.Looped = false
		activeAnimation:Play()
	end))
	
	--[[
		Switch out idle animation for generic dance animation while player
		is on the dance floor; replace default idle animations when the
		player leaves a dance floor
		
		-- TODO: Revert to default idle animations when the music is stopped
	]]
	local wasOnDanceFloor = false
	table.insert(events, humanoid.Running:Connect(function(speed: number)
		local isOnDanceFloor = DanceFloorTracker.IsOnDanceFloor()
		
		if wasOnDanceFloor == isOnDanceFloor then
			return
		end
		
		wasOnDanceFloor = isOnDanceFloor
		defaultIdle:ClearAllChildren()
		
		if isOnDanceFloor then
			AnimationsDB.Generic:Clone().Parent = defaultIdle
		else
			for _, animation in ipairs(defaultIdleAnims) do
				animation:Clone().Parent = defaultIdle
			end
		end
	end))
	
	--[[
		If the player dies, disconnect all events and destroy the active animation,
		and re-bind events to the new humanoid/character instances
	]]
	table.insert(events, humanoid.Died:Connect(function()
		for _, event in ipairs(events) do
			event:Disconnect()
		end
		
		if activeAnimation then
			activeAnimation:Destroy()
		end
		
		BindToCharacter()
	end))
end

BindToCharacter()
--[[	
	Main RenderStep Update. The camera controller and occlusion module both have opportunities
	to set and modify (respectively) the CFrame and Focus before it is set once on CurrentCamera.
	The camera and occlusion modules should only return CFrames, not set the CFrame property of
	CurrentCamera directly.	
--]]




function CameraModule:Update(dt)
	if self.activeCameraController then
		
		if script.Parent.Parent.shiftLock.Value == true and script.Parent.Parent.shiftLock.camLock.Value == false then
			self.activeCameraController:SetIsMouseLocked(true)
			
		elseif script.Parent.Parent.shiftLock.Value == true and script.Parent.Parent.shiftLock.camLock.Value == true  then
			self.activeCameraController:SetIsMouseLocked(true)
		else
			self.activeCameraController:SetIsMouseLocked(false)
		end
		local newCameraCFrame, newCameraFocus = self.activeCameraController:Update(dt)
		self.activeCameraController:ApplyVRTransform()
		if self.activeOcclusionModule then
			newCameraCFrame, newCameraFocus = self.activeOcclusionModule:Update(dt, newCameraCFrame, newCameraFocus)
		end
		
		-- Here is where the new CFrame and Focus are set for this render frame
		game.Workspace.CurrentCamera.CFrame = newCameraCFrame
		game.Workspace.CurrentCamera.Focus = newCameraFocus
		
		-- Update to character local transparency as needed based on camera-to-subject distance
		if self.activeTransparencyController then
			self.activeTransparencyController:Update()
		end
	end
end
--------------------)


i = true
script.Parent[ZoneModelName]:MoveTo(Vector3.new(0,10000,0))
script.Parent[ZoneModelName]:Clone().Parent = game.ServerStorage
script.Parent.RemoteEvent.OnServerEvent:Connect(function(plr,X,Y,Z)
	if i then i = false
		local zone = game.ServerStorage:WaitForChild(ZoneModelName):Clone()
		zone.Parent = game.Workspace
		zone.PrimaryPart = zone.Main
		zone:SetPrimaryPartCFrame(CFrame.new(Vector3.new(X,Y+0.5,Z)))
		zone.Main.Touched:Connect(function(hit)
			if hit.Parent:FindFirstChild(MobHumanoidName) then
				hit.Parent[MobHumanoidName].Health = hit.Parent[MobHumanoidName].Health-Damage
			end
		end) 
		wait(Cooldown)
		i = true
	end
end)
-- Replica creation:


rev_ReplicaCreate.OnClientEvent:Connect(function(param1, param2) -- (top_replica_id, {replica_data}) OR (top_replica_id, {creation_data}) or ({replica_package})
	--[[
	param1 description:
		top_replica_id = replica_id
		OR
		replica_package = {{replica_id, creation_data}, ...}
	param2 description:
		replica_data = {replica_class, replica_tags, data_table, parent_id / 0, write_lib_module / nil}
		OR
		creation_data = {["replica_id"] = replica_data, ...}
	--]]
	local created_replicas = {}
	-- Unpacking replica data:
	if type(param1) == "table" then -- Replica package
		table.sort(param1, function(a, b) -- Sorting top level replicas by their id
			return a[1] < b[1]
		end)
		for _, replica_branch_entry in ipairs(param1) do
			CreateReplicaBranch(replica_branch_entry[2], created_replicas)
		end
	elseif param2[1] ~= nil then -- One replica data
		CreateReplicaBranch({[tostring(param1)] = param2}, created_replicas)
	else -- Creation data table
		CreateReplicaBranch(param2, created_replicas)
	end
	-- Broadcasting replica creation:
	table.sort(created_replicas, function(a, b)
		return a.Id < b.Id
	end)
	-- 1) Child added:
	for _, replica in ipairs(created_replicas) do
		local parent_replica = replica.Parent
		if parent_replica ~= nil then
			local child_listener_table = ChildListeners[parent_replica.Id]
			if child_listener_table ~= nil then
				for i = 1, #child_listener_table do
					child_listener_table[i](replica)
				end
			end
		end
	end
	-- 2) New Replica and Replica of class created:
	for _, replica in ipairs(created_replicas) do
		NewReplicaSignal:Fire(replica)
		local class_listener_signal = ClassListeners[replica.Class]
		if class_listener_signal ~= nil then
			class_listener_signal:Fire(replica)
		end
	end
end)
--[=[
	@prop Util Folder
	@within KnitClient
	@readonly
	References the Util folder. Should only be accessed when using Knit as
	a standalone module. If using Knit from Wally, modules should just be
	pulled in via Wally instead of relying on Knit's Util folder, as this
	folder only contains what is necessary for Knit to run in Wally mode.
]=]


KnitClient.Util = script.Parent.Parent

local Promise = require(KnitClient.Util.Promise)
local Comm = require(KnitClient.Util.Comm)
local ClientComm = Comm.ClientComm

local controllers: { [string]: Controller } = {}
local services: { [string]: Service } = {}
local servicesFolder = nil

local started = false
local startedComplete = false
local onStartedComplete = Instance.new("BindableEvent")

local function DoesControllerExist(controllerName: string): boolean
	local controller: Controller? = controllers[controllerName]
	return controller ~= nil
end

local function GetServicesFolder()
	if not servicesFolder then
		servicesFolder = script.Parent:WaitForChild("Services")
	end
	return servicesFolder
end

local function GetMiddlewareForService(serviceName: string)
	local knitMiddleware = if selectedOptions.Middleware ~= nil then selectedOptions.Middleware else {}
	local serviceMiddleware = selectedOptions.PerServiceMiddleware[serviceName]
	return if serviceMiddleware ~= nil then serviceMiddleware else knitMiddleware
end

local function BuildService(serviceName: string)
	local folder = GetServicesFolder()
	local middleware = GetMiddlewareForService(serviceName)
	local clientComm = ClientComm.new(folder, selectedOptions.ServicePromises, serviceName)
	local service = clientComm:BuildObject(middleware.Inbound, middleware.Outbound)
	services[serviceName] = service
	return service
end