return {
	["Noob Attack: Periastron"] = "Noob Attack - Periastron";
	["Noob Attack꞉ Periastron"] = "Noob Attack - Periastron";
}


local foo = bar -- trailing comment

-- leading comment
local bar = baz
local baz = foo

do
	local foo = bar
	-- comment
	local bar = baz
end


local negativeLiteral = -3
local negativeVariable = -x
local notLiteral = not true
local notVariable = not x
local length = #x


local x = 1
local y = 2

x += 5
x -= 5
x *= 5
x /= 5
x //= 5
x %= 5
x ^= 5

x += y
x -= y
x *= y
x /= y
x //= y
x %= y
x ^= y

local str1 = "Hello, "
local str2 = "world!"

str1 ..= "world!"
str1 ..= str2


-- Very important loop here
while true do
	continue
end

continue()
local continue = 4


--!strict
function _foo<x, y>()
end

local function _bar<x>()
end

export type Foo0 = {
	bar: <T>(
		a: T,
		b: nil | number | boolean
	) -> T,
}
local _baz
export type Foo1 = {
	bar: <T>(
		a: T,
		b: nil | number | boolean
	) -> ((arg0: T) -> ())?,
}

_baz = function<T>(a: T, b: number | boolean | nil): nil | T
    return nil
end


local x = if foo then foo.x else 5
local y = (if x then x.indices else create()):update(if shouldUpdate then information else defaults)
local z = (if bar then foo.y else 5) :: number

local a = if foo then foo.x elseif bar then bar.x else 5
local b = if foo then if bar then bar else foo else 5
local c = if foo then (foo.x :: number) elseif bar then bar.x()() else 5
local d = if foo then 5 else baz :: number

if if foo then bar else baz then
end


type MyCallbackType = (cost: number, name: string) -> string

local cb: (amount: number) -> number
local function foo(cb: (name: string) -> ())
end

local function bar(x: (number)?): (baz: string) -> string
end

local function bar(x: (number)?): (baz: string) -> ((names: Array<string>) -> ...any)
end


local function assertEq(left, right)
	assert(typeof(left) == "string", "left is a " .. typeof(left))
	assert(typeof(right) == "string", "right is a " .. typeof(right))

	if left ~= right then
		error(string.format("%q ~= %q", left, right))
	end
end

assertEq(`hello {"world"}`, "hello world")
assertEq(`Welcome {"to"} {"Luau"}!`, "Welcome to Luau!")

assertEq(`2 + 2 = {2 + 2}`, "2 + 2 = 4")

assertEq(`{1} {2} {3} {4} {5} {6} {7}`, "1 2 3 4 5 6 7")

local combo = {5, 2, 8, 9}
assertEq(`The lock combinations are: {table.concat(combo, ", ")}`, "The lock combinations are: 5, 2, 8, 9")

assertEq(`true = {true}`, "true = true")

local name = "Luau"
assertEq(`Welcome to {
	name
}!`, "Welcome to Luau!")

local nameNotConstantEvaluated = (function() return "Luau" end)()
assertEq(`Welcome to {nameNotConstantEvaluated}!`, "Welcome to Luau!")

assertEq(`This {localName} does not exist`, "This nil does not exist")

assertEq(`Welcome to \
{name}!`, "Welcome to \nLuau!")

assertEq(`empty`, "empty")

assertEq(`Escaped brace: \{}`, "Escaped brace: {}")
assertEq(`Escaped brace \{} with {"expression"}`, "Escaped brace {} with expression")
assertEq(`Backslash \ that escapes the space is not a part of the string...`, "Backslash  that escapes the space is not a part of the string...")
assertEq(`Escaped backslash \\`, "Escaped backslash \\")
assertEq(`Escaped backtick: \``, "Escaped backtick: `")

assertEq(`Hello {`from inside {"a nested string"}`}`, "Hello from inside a nested string")

assertEq(`1 {`2 {`3 {4}`}`}`, "1 2 3 4")

local health = 50
assert(`You have {health}% health` == "You have 50% health")

local function shadowsString(string)
	return `Value is {string}`
end

assertEq(shadowsString("hello"), "Value is hello")
assertEq(shadowsString(1), "Value is 1")

assertEq(`\u{0041}\t`, "A\t")

return "OK"


--!strict
local _fn3
type Identity<T> = T
type Array<T> = { [number]: T }
type Map<K, V> = { [K]: V }
type Function<T> = (...any) -> ...T
type Object = { x: number, y: number }
type Typeof = typeof(2 + 2 + _fn3())
type FetchResult = "alice" | "mallet"
type Element = { ["$$typeof"]: number }

type Callback1 = (string) -> number
type Callback2 = (string, string) -> number
type Callback3 = (string, string) -> (string, nil)
type Callback3a = (string, "error" | "success") -> (string, "weasel" | "basilisk")
type Callback4 = (string) -> (string) -> ()
type NetworkError = { message: string? } & { handled: true }

type Foo = {
	bar: number,
	baz: number,
}

local foo0: number = 3
local _foo1: number?
local _foo2: Array<string>
local _foo3: Map<number, "allow" | "deny">
local _bar0 = foo0 :: number
local _foo4: string, _bar1: string

local _union: number | string
local _multiUnion: number | string | nil

local _intersection: number & string
local _multiIntersection: number & string & nil

function _fn0(param: string): string
	return param
end

function _fn2(a: string, b: string, ...) end

local _fn3 = function(): number | nil
	return 3
end

local function _concat<T, S>(source: Array<T>, ...: Array<S> | S): Array<T> & Array<S>
    return (source :: any) :: Array<S> & Array<T>
end


type Config = {
    option1: string??, -- you probably need it once in a while
    option2: string???, -- once a year
    option3: string?????? -- once in your life!
}


--!strict
type Foo<T..., U...> = (U...) -> T...
type Bar<U, T...> = nil
type Function<Args... = ...any, Return... = ()> = (Args...) -> Return...
type Baz<U = string, T... = (string, number)> = nil
type Indexed<T...> = module.Indexed<T...>


local x: module.Foo = nil
local x: module.Array<string> = { "bar" }
local x: module.Foo | string = "bar"
local x: module.Foo? = nil
local x: module.Foo<...string> = nil


--!strict
function _foo<T...>(param: () -> T...)
end

type Foo<T...> = () -> T...

function _bar<T...>(...: T...)
end

type A<Z, P...> = {}
type C<S...> = A<number, S...> -- with a generic type pack
type B = A<number, ...string> -- with a variadic type pack
type D = A<number, ()> -- with an empty type pack

type Function<Args..., Return...> = (Args...) -> Return...

type AnyFunction = Function<...any, ...any>

local _g: Function<(number, string, ...string), (string, number)>? = nil


--!strict
type GField<_crack, __fuzzing> = {}
local TypeInfo = {}
function TypeInfo.new(
	getFieldDefFn: (() -> GField<any, any>?)?
)
end

export type Thunk<T> = (() -> T) | T

export type PromiseLike<T> = {
    andThen: (
                ((T) -> T)? | (PromiseLike<T>)?, -- resolve
                ((any) -> () | PromiseLike<T>)? -- reject
        ) -> PromiseLike<T>
}

local GError = {}
type GError = typeof(GError)
type Error = { message: string?, stacktrace: string? }
function GError.new(
	originalError: (Error & { extensions: any? }) -- new syntax
): GError?
  return nil
end

type IProperties = {
	RemoveOnCollision: (string | (IProperties, BasePart, Vector3, Vector3, Enum.Material, number) -> boolean)?,
}


--!strict
type Foo = (...number) -> ()
type Baz = (string, ...Foo) -> ...Foo
type Bar = (...number) -> (string, ...number) -> ...any
type Boom = (..."hit" | "miss") -> (string, ...("critical" | "weak" | "normal")) -> ...("dead" | "alive")

function _bar(...: number): ...number | string end

local f: Boom = function(...)
	return function(x, ...)
		return "alive", "dead"
	end
end

f("hit")

local Boo = {}
function Boo:f(name: string, ...: number): () -> (string, ...Foo) -> ()
	return function()
		return function(_x: string, ...: Foo) end
	end
end

type Fn<U...> = any
type T = Fn<...'ok'>


local function returnsComplexType()
	return {} :: { [string]: { number } }
end

-- Key and [1] both have incorrect highlighting
type Inner = typeof(returnsComplexType().Key[1])

-- This has correct highlighting
local inner = returnsComplexType().Key[1]


type Foo =
    | string
    | number

export type Bar =
    string
    | number
    | boolean

type WithComments =
    -- leading comment
    | string
    -- middle comment
    | number

type SingleLine = string | number

type Qualified =
    Foo.Bar
    | Baz.Qux

type WithTable =
    | { field: string }
    | number

type BeforeAssignment =
    | string
    | number
y = 1

type BeforeMethodCall =
    | string
x:method()

type BeforeIndex =
    | string
x[1] = 2

type BeforeDottedAssignment =
    | string
x.foo = 1

type BeforeFunction =
    | string
    | number
function foo() end

type BeforeLocal =
    | string
local z = 1


local function before()
    return true
end

--[[
```lua
pcall(function()
end
```
]]

local function after()
    return true
end


export type A = {
    LOL: "yes",
}

local a: xd.Something<{
    transparency: typeof(React.createBinding(0))
}> = function()

end

local c: xd.Something<{
    transparency: typeof(React.createBinding(0)), -- this comma is the reason why it diess!!
}> = function() -- it dies
    local a = "hello world"
end


local x: any
x.foo = 20

local function func(header: typeof(Instance.new("Humanoid"))) end

local y: any
y.foo = 10


--[[
```luau
local abc: number = 1
print(abc)
```
]]

--[[
```lua
local abc: number = 1
print(abc)
```
]]


-- Positive: nested type declarations
if true then
    type Foo = string
end

do
    export type Bar = number
end

while true do
    type Callback = (string) -> number
end

-- Positive: top-level (must not regress)
type TopLevel = boolean

-- Positive: nested type function
do
    export type function Identity(t)
    end
end

-- Regression: type as function call (NOT a type declaration)
local x = type(something)
if type(value) == "string" then end

-- Regression: type as property access (NOT a type declaration)
print(x.type)


local test_nil: nil
local test_string: string
local test_number: number
local test_boolean: boolean
local test_thread: thread
local test_vector: vector
local test_buffer: buffer
local test_unknown: unknown
local test_never: never
local test_any: any

local function test(
    test_nil: nil,
    test_string: string,
    test_number: number,
    test_boolean: boolean,
    test_thread: thread,
    test_vector: vector,
    test_buffer: buffer,
    test_unknown: unknown,
    test_never: never,
    test_any: any
)
    return
end

type Test = {
    test_nil: nil,
    test_string: string,
    test_number: number,
    test_boolean: boolean,
    test_thread: thread,
    test_vector: vector,
    test_buffer: buffer,
    test_unknown: unknown,
    test_never: never,
    test_any: any
}


type Test = {
    read readonly_property: string,
    write writeonly_property: string,
    property: string,
}


local baz = foo(bar);
(foo and x or y)(bar)

function foobar()
	local baz = foo(bar);
	(baz and x or y)(bar)
end


local foo = function(bar, baz) print(foo) end
call(function(x,y) local x = test end)


local      foo    =      'bar'
local   bar       ,       baz     = 1   ,   2


function foo()

	local x = 1

	return true

end

function bar()

	return

end

do

	-- comment
	local x = 1

	local foo = bar

	-- comment

end


local foo_result = foo( --a comment
	"oof"
)

local expr_result = 1 + 2 + 3 + 4 + 5 --a comment
	+ 6 + 6 + 8

print"text" --a comment
foo{bar = baz} -- comment

for foo, -- test
bar in
next, -- comment
value
do
	print("test", -- comment
		"foo"
	)
end

if code == 9 -- \t
or code == 32 -- <space>
   then
    print(code)
end

return foo, -- a comment
bar


foo( -- comment
baz
)

foo(
baz, -- comment
bar
)

foo (
	baz,
	-- comment
	bar
)

foo(baz,
bar -- comment
)

foo(baz, bar) -- comment

foo(
	-- comment
	baz,
	bar
)


function sayHello(
	name,    -- YourName
	foo,--baz
	greeting -- Message
)
	return greeting .. ", " .. name
end


function foo()
    local x = 1
    local y = 1

    -- comment
end

if foo then
    local x = 1
    -- comment
end


if
	this -- foobar
then
elseif
	foobar or code == 10 -- \n
then
	pos = 1
	lexer.line = 1
	lexer.lineStart = pos - 1
end

local function coerceToMap(mapLike)
	return instanceOf(mapLike, Map) and mapLike -- ROBLOX: order is preservered
		or Map.new(Object.entries(mapLike)) -- ROBLOX: order is not preserved
end

if -- comment
	foo
then
end

if
	foo
	-- comment
then
end

while -- commend
	foo
do
end

while
	foo
	-- comment
do
end

do
	return foo -- comment
		or bar, -- comment
		baz and foo
end

local x = foo -- comment
		or bar, -- comment
		baz and foo


local val = 1 + 2+ 1 -- add
foo = bar or #baz -- test
local foo = bar or (baz and foo) -- test

-- Stop Movement
if
	-- Moved for at least 0.1 seconds
	((tick() - Player.PlayerDataLocal.IsRunningTimeStamp.Value) > 0.1) and     -- Speed is less than threshold
	(Utility.Vec3XZLengthSquared(Player.Character.PrimaryPart.Velocity) <= RunThresholdSpeedSqr)
then --0.01
	Player.PlayerDataLocal.IsRunning.Value = false
end


--[[Testing this]]
local function foo(bar, baz) print(bar,baz) end --this is a nice function
local test = {}--this comment should stay

local y = foo
-- comment line 1
-- comment line 2, should not be split from above comment
local x = test


React.createElement("span", { key = id }, React.createElement(Consumer, nil, function()
	return React.createElement("span", nil, "inner")
end), React.createElement("span", nil, "outer"))


local instance = someReallyLongConditionExtremelyLongSoLongYourMindWillMelt
	and someReallyLongCondition
	and someOtherReallyLongCondition
	or somethingElse


if (foo) then
	print("true")
elseif (bar) then
	print("false")
end

while (foo) do
	print("true")
end

repeat
	print("yes")
until (foo)


do
	local region = Region3.new(part.Position - (0.5 * part.Size), part.Position + (0.5 * part.Size))

	do
		do
			return function(...)
				callback(LOG_FORMAT:format(os.date("%H:%M:%S"), key, level, fmt.fmt(...)))
			end
		end
	end

	self.digits = math.ceil(math.log10(math.max(math.abs(self.props.maxValue), math.abs(self.props.minValue))))
end

local gamemodes, keysById, idsByKey = createDataIndex(script.AllGamemodes, validateGamemodeSchema)

HealthRegen.ValidateInstance = t.intersection(ComponentUtil.HasComponentValidator("Health"), ComponentUtil.HasComponentValidator("Target"))


local x = -(-foo)
local y = - -foo

local z1 = -(-foo) -- bar
local z2 = - -foo -- baz


local function noop() -- comment
end

function noop()
	-- comment
end

call(function()
	-- comment

end)


local x
something((x))

local x = (1 + 2) * 3
local y = ((1) * 3)
local z = (...) == nil and foo or bar
local foo = not (bar and baz)
local bar = (#bar) and baz
local cond = condition and (not object or object.Value == y)
local baz = (-4 + 3) * 2

({}):foo();
("hello"):format()

function x()
	return 1, 2
end

print(x())
print((x()))
print(((x())))

path = (function()
  return true
end)()

-- The following should have parentheses removed, but if they were a Prefix, they wouldn't be removed
local x = ({})
local y = ("hello")
local z = (function()
	return true
end)


local App = Roact.createElement("Frame", {
	Size = UDim2.new(0,0,0,0),
	Position = UDim2.new(0,0,0,0)
}, {
	Child1 = Roact.createElement("TextLabel", {
		Text = "foo",
		AnchorPoint = Vector2.new(0, 0), -- comment
		foo = bar
	}),

	Child2 = Roact.createElement("TextLabel", {
		Text = "foo",
		AnchorPoint = Vector2.new(0, 0),
		foo = bar
	}),
})

doSomething({
	aLongKey = aLongValue,
	anotherLongKey = anotherLongValue
}, notATableLiteral, {
	aLongKey = anotherLongValue,
	anotherLongKey = aLongValue
})

table.sort(recommendedDeveloperProducts, function(a, b)
	return a.amount < b.amount
end)


setmetatable({
	_words = words,
	_morewords = words,
	_evenmorewords = words,
	_words = words,
	_morewords = words,
	_evenmorewords = words,
}, Class)

foo({
	foo = bar,
}, baz, {
	bar = baz,
})

Roact.createElement("Frame", {
	foo = bar, bar = baz,
}, self.props[Roact.Children])


Roact.createElement("ImageLabel", {
	Size = UDim2.new(
		0,
		TextService:GetTextSize(self.props.PhysicalTool.Name, 16, Enum.Font.SourceSansBold, Vector2.new(100000, 100000)).X
			+ 10,
		0,
		20
	),
})


-- hug table braces with parentheses

print({ foo_variable = "some long value", foo_variable = "some long value", foo_variable = "some long value", foo_variable = "some long value", })

print({ foo_variable = "somenge", foo_variable = "malue", foo_variable = "alueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" })

-- but not if there is a comment present

foo( -- test
   { bar })

foo( -- test
	{
	   bar
	}
)


function_call(("hello" .. "darkness" .. "my" .. "old" .. "friend" .. "hello" .. "darkness" .. "my" .. "old" .. "friend" .. "!!!!!!!!!!!!"):call())


local AppRodux = RoactRodux.connect(
	function(state, props)
		return {

		}
	end
	-- function(dispatch)
	--   return {
	--     setCrossSize = function(crossSize)
	--       dispatch({
	--         type = "SetCrossSize",
	--         crossSize = crossSize
	--       })
	--     end
	--   }
	-- end
)(AppComponent)


function func(
	param_a -- description of a
	, param_b -- description of b
) end


function foo(foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo, barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr) end

function foo(foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo, barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)
end

function foobar(fooooo, barrrrrrrrrr, bazzzzzzzzzzzzzzz, fooooooooooo, bazzzzzzzzzzzzzzzzzzz, barrrrrrrrrrrrrrrrrrrrrrrr)
	print("test")
end

do
	function foo(fooooo, barr -- test
	)
		print("test")
	end
end

do
	function bar(foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo, barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr)
	end
end

local x = {
	func = function (fooooo, bar --test
	)
		print("test")
	end,
}


local function system(world)
	for id, model, lasering, transform in world:query(Components.Model, Components.Lasering, Components.Transform, Components.Mothership) do
	end
end

local function system(world)
	for id, model, lasering, transform, id, model, lasering, transform, id, model, lasering, transform, id, model, lasering, transform in world:query(Components.Model, Components.Lasering, Components.Transform, Components.Mothership) do
	end
end

local function system(world)
	for id, model, lasering, transform, id, model, lasering, transform, id, model, lasering, transform, id, model, lasering, transform in world:query(Components.Model, Components.Lasering, Components.Transform, Components.Mothership, Components.Mothership) do
	end
end


local function logTiger(tiger, depth)
	log(
	string.rep("  ", depth) ..
	"- " ..
	-- need to explicitly coerce to a string
	tiger.type and (tiger.type.name or tostring(tiger.type)) or "[r00t]",
	"[" ..
	tiger.commonExtraTentacles ..
	(tiger.pendingPartyHats and "*" or "") ..
	"]"
	)
	end

local function logTiger(tiger, depth)
	log(
	string.rep("  ", depth) ..
	-- need to explicitly coerce to a string
	"- " ..
	tiger.type and (tiger.type.name or tostring(tiger.type)) or "[r00t]",
	"[" ..
	tiger.commonExtraTentacles ..
	(tiger.pendingPartyHats and "*" or "") ..
	"]"
	)
	end


function foo(defaultExport)
	if defaultExport == nil then
		print(
			"lazy: Expected the result of a dynamic import() call. "
				.. "Instead received: %s\n\nYour code should look like: \n  "
				-- Break up imports to avoid accidentally parsing them as dependencies.
				-- ROBLOX deviation: Lua syntax in message
				.. "local MyComponent = lazy(function() => req"
				.. "quire('script.Parent.MyComponent') end)",
			moduleObject
		)
	end
end

function bar(defaultExport)
	if defaultExport == nil then
		print(
			"lazy: Expected the result of a dynamic import() call. " ..
				"Instead received: %s\n\nYour code should look like: \n  " ..
				-- Break up imports to avoid accidentally parsing them as dependencies.
				-- ROBLOX deviation: Lua syntax in message
	      "local MyComponent = lazy(function() => req" ..
				"quire('script.Parent.MyComponent') end)",
			moduleObject
		)
	end
end


local function findMoney()
	for _, existingObject in pairs(workspace:GetChildren()) do
		if
			existingObject:GetAttribute("MoneyID") == targetCash.id
			and existingObject.Name == targetName .. ".money"
		then
			break
		end
	end
end

do
	do
		do
			do
				do
					do
						do
							function Venue:inspectElectrics(inspectElectricParams)
								local id, pedal, fendererID =
									inspectElectricParams.id,
									inspectElectricParams.pedal,
									inspectElectricParams.rendererID
								local fenderer = self._fendererInterfaces[fendererID]

								if fenderer == nil then
									logger.warn(('Invalid fenderer id "%s" for Electric "%s"'):format(fendererID, id))
								else
									self._chorus:send("inspectedElectric", renderer.inspectElectric(id, pedal))

									-- When rocker selects an Electric, stop trying to frobnikate the pyramids,
									-- and instead recall the present songs for the next venue.
									if
										self._nexusstedSelectionBatch == nil or self._nexusstedSelectionBatch.id
											~= id
									then
									end
							  end
							end
						end
					end
				end
			end
		end
	end
end


local foo = x ^ -- comment
	y % -- comment
	z - -- comment
	a <= -- comment
	b < -- comment
	c >= -- comment
	d


local output = Job
    :new({
    command = "stylua",
    args = { "-" },
    writer = api.nvim_buf_get_lines(bufnr, 0, -1, false),
  })
    :sync()


Promise.new():andThen(callThis):andThen(function() print("test") end):andThen()

Promise.new():andThen(callThis):andThen({
    true
  }):andThen()

this.is.a.large.start:andThen():andThen(function()
	print("test")
end):andThen()

local f = this:andThen(callThis):andThen({
	true
}).X.Y.Z

this:andThen(callThis):andThen({
	true
}).X.Y.Z:andThen():andThen()

function foo()
	Promise.new():andThen(callThis):andThen(function() print("test") end):andThen()
end

local x = {
	promise = Promise.new():andThen(callThis):andThen(function() print("test") end):andThen()
}


assert(StringToHex(HexToString("05 e0 81 91 24 cb b2 2c 49 e2 0f 2e 8b 9a" .. " 47 56 9f fb fe ec d2 ff 1f")) == "05 e0 81 91 24 cb b2 2c 49 e2 0f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f")


do
	do
		local CreatedDirection = (
			DirectionalCF * CFrame.fromOrientation(0, 0, RNG:NextNumber(0, TAU)) * CFrame.fromOrientation(
				math.rad(RNG:NextNumber(
					GunMainConfiguration.BulletMinSpreadAngle or GlobalConfiguration.DEFAULT_MIN_SPREAD_ANGLE,
					GunMainConfiguration.BulletMaxSpreadAngle or GlobalConfiguration.DEFAULT_MAX_SPREAD_ANGLE
				)),
				0,
				0
			)
		).LookVector
	end
end


("foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" .. "barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr"):format()

do
	("foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" .. "barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr"):format()
end

print(("foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo" .. "barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr"):format())


if true then
else
end

if true then

	-- this is a comment

-- but this is another comment
	-- and another one - we should hence indent the comments overall
else
end


function foo()
    function bar()
        function baz()
            --[[
                comment
            ]]
            local x = 1
        end
    end
end


local x = foo[
	index -- test
]

foo[
	var -- string
] = baz

local x = foo[
	x -- string
][y][z][p
-- string
]

local x = foo[index --[[comment]]]


do
	local HitPart, HitPoint, HitNormal, HitMaterial = nil, Ray.Origin + Ray.Direction, Vector3.new(0, 1, 0), Enum.Material.Air
end


local something = fooooooooooooooo == barrrrrrrrrrrr and func(arggggggggggggggggggggggggggggggggggggggggg1, argggggggggg2) or somethingeeeeeeeeeeee


do
	do
		local FrontDistanceX, FrontDistanceY =
			self.settings.FWsBoneLen * math.cos(math.rad(self.settings.FWsBoneAngle)),
			self.settings.FWsBoneLen * math.sin(math.rad(self.settings.FWsBoneAngle))
	end
end


local LoadAddOn, UnitName, GetRealmName, UnitRace, UnitFactionGroup, IsInRaid = LoadAddOn, UnitName, GetRealmName, UnitRace, UnitFactionGroup, IsInRaid

LoadAddOn, UnitName, GetRealmName, UnitRace, UnitFactionGroup, IsInRaid = LoadAddOn, UnitName, GetRealmName, UnitRace, UnitFactionGroup, IsInRaid

do
	local LoadAddOn, UnitName, GetRealmName, UnitRace, UnitFactionGroup, IsInRaid = LoadAddOn, UnitName, GetRealmName, UnitRace, UnitFactionGroup, IsInRaid
end

do
	local XOffset, YOffset, ZOffset = CFrame.new(GlobalConfiguration.TPS_CAMERA_OFFSET.X, 0, 0), CFrame.new(0, GlobalConfiguration.TPS_CAMERA_OFFSET.Y, 0), CFrame.new(0, 0, GlobalConfiguration.TPS_CAMERA_OFFSET.Z)
end


checkVisitorFnArgs(
	expect,
	ast,
	{ ... },
	true --[[ isEdited ]]
)

local test   --[[foo]] = true

   --[[test]]
local x = true


if not (one and two and three and not (four and five) and six and not (seven and eight and nine and ten and eleven and twelve and thirteen and fourteen and fifteen and sixteen and seventeen)) then
	print("foo")
end

local longString = foo(
	"We are wrapping this %s " .. "onto multiple lines " .. "for ease of editing and %d readability" .. "and I continue to extend this string" .. "so it can wrap even further",
	myStringVar,
	myNumberVar
)

return node.kind == Kind.VARIABLE
  or node.kind == Kind.INT
  or node.kind == Kind.FLOAT
  or node.kind == Kind.STRING
  or node.kind == Kind.BOOLEAN
  or node.kind == Kind.NULL
  or node.kind == Kind.ENUM
  or node.kind == Kind.LIST
  or node.kind == Kind.OBJECT


do
	do
		do
			do
				local text = "Players: " .. #Server_Container.ARandomVariableWhichIsVeryLongSoThatThisGetsOverTheColumnLimit.Players_F:GetChildren() - 1 .. "/20"
				local ratio = (minAxis - minAxisSize) / delta * (self.props.maxScaleRatio - self.props.minScaleRatio) + self.props.minScaleRatio
				local ratio2 = (minAxis - minAxisSize) / delta * (self.props.maxScaleRatio - self.props.minScaleRatio) * self.props.aRandomVariableWhichIsVeryLong + self.props.minScaleRatio
			end
		end
	end
end


function SetCallsign(Player, Callsign)
	if Settings.PolicingSetup.Radio or (table.find(Settings.PolicingSetup.CallsignPrefix, string.sub(Callsign, 1, 2)) and tonumber(string.sub(Callsign, 3, 4))) then
		Player:SetAttribute("Callsign", Callsign)
	end
end


if someReallyLongCondition and someOtherReallyLongCondition and somethingElse and someReallyLongCondition and someOtherReallyLongCondition and somethingElse then
    print("foo")
end

foo = someReallyLongCondition * someOtherReallyLongCondition * somethingElse * someReallyLongCondition * someOtherReallyLongCondition * somethingElse

local foo = someReallyLongCondition and someOtherReallyLongCondition == foo and somethingElse and someReallyLongCondition and someOtherReallyLongCondition and somethingElse

repeat print("foo") until someReallyLongCondition and someOtherReallyLongCondition and somethingElse and someReallyLongCondition and someOtherReallyLongCondition and somethingElse

while someReallyLongCondition and someOtherReallyLongCondition and somethingElse and someReallyLongCondition and someOtherReallyLongCondition and somethingElse do
    print("foo")
end

if foo(aVeryLongValue, anotherVeryLongValue, someEvenMoreLongValues, evenMoreLongValues, whenWillTheseLongValuesEverEnd) and someOtherReallyLongCondition and somethingElse and someReallyLongCondition and someOtherReallyLongCondition and somethingElse then
    print("foo")
end

baz(first_arg___ooooooooooooooooooooooooooooooooooooooooooo, second_arg___qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq, function() if
			multiline_if___aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
			and multiline_if___bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
	then
			foo()
		end
	end
)


local a = 0.5
local b = .5
local c = 100
local d = 5e-5
local e = -.5
local f = .2e-5
local g = -.1e+5
local h = 0x12


local function foo(bar)
	local count = 0

	repeat
		count = count + 1
	until count == 10
end


return cframe
	-- Clamp & transform into world space
	* Vector3.new(
		math.clamp(transform.X, -halfSize.X, halfSize.X),
		math.clamp(transform.Y, -halfSize.Y, halfSize.Y),
		math.clamp(transform.Z, -halfSize.Z, halfSize.Z)
	), cframe.Position


function foo()
	return (
		long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
	), (
		long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
	)
end

function foo()
	return foo and bar or baz, (
		long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
	)
end

function foo()
	return not (
		long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
		+ long_variable_name
	)
end


function foo()
	return fooooooooooooooooooo(barrr) or foooooooooooooooooooooooooooooooooooooooooooooooooooooopppo(barrrrrrrrrrrrrr)(hello) or bazzzzzzzzzzzzzzzzzz
  end


local x = 1; -- comment
do
	return; -- bad
end; -- comment

local y; -- comment
z = 5; -- comment

repeat x = x + 1 until x > 5; -- comment

for x,y in pairs(z) do
	break; -- comment
end; -- comment

if x then end; -- comment

function foo()
end; -- comment

local function bar()
end; -- comment

for i = 1, 10 do
end; -- comment

while true do
end; -- comment

call("hello"); -- comment
call"hello"; -- comment
call { foo = bar }; -- comment

return x; -- comment


local foo = a <= b --[[ some block comment ]]; -- inline comment
fn() --[[ some block comment 2 ]]; -- inline comment 2


do
	do
		do
			do
				do
					do
						jestExpect(ReactIs.typeOf(React.createElement(React.Profiler, { id = "foo", onRender = jest.fn() }))).toBe(ReactIs.Profiler)
					end
				end
			end
		end
	end
end


-- standard escapes
local a = "foo \a \b \f \n \r \t \v \\ \" \'"

-- decimal escapes
local b = "\000 \001 \189 \254 \255"
local b2 = "\1 \2 \71\9"

-- lua 5.2: hex escapes
local c = "hello \x77\x6f\x72\x6c\x64\x99"

-- lua 5.2: \z
local d = "hello \z  test"

-- lua 5.3: utf8
local e = "\u{123} \u{255}"

-- wrong:
local f = "\q \p \e"


local foo = 'this \'string\' has \'escaped\' single quotes with "double quotes"'
local bar = "test \'foo\' \"bar\""
local baz = '\\"""'


local foo = {"bar", "baz", "foo", "bar", "baz", "foo", "bar", "baz", "foo", "bar", "baz", "foo", "bar", "baz", "foo", "bar", "baz"}

local foo = {"bar", "baz", "foo", "bar", "baz", "foo",
	"bar", "baz", "foo", "bar", "baz", "foo", "bar",
	"baz", "foo", "bar", "baz", "foo", "bar", "baz"}

local foo = {

}


local foo = {  "aaaa", "aaaa", "aaaa", "aaaa", "aaaa", "aaaa", "aaaa", "aaaa", "aaaa", "aaaa", "aaaa", "aaaa", "aaaa", "aaaa"  }


local foooooooooooooo = { "barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr" .. "bazzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"}

local barrrrrrrrrrrrr = { foooooooooooooooooo = "barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr" .. "bazzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"}

local bazzzzzzzzzzzzzz = { [foo()] = "barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr" .. "bazzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"}


local thisisathing = {this_is_one = "one", this_is_two = "two", this_is_three = "three", this_is_four = "four", f = "b"}


a = {
	key1 = string.format("test", "test", "test", "test", "test", "test", "test", "test", "test", "test", variable_names),
	key2 = string.format("test", "test", "test", "test", "test", "test", "test", "test", "test", "test", variable_names),
}


local x = {
	"foo", -- comment
	"bar", -- test
	"baz" -- test
}

local foo = {
	MinSize = call(0, 0),
	MaxSize = call(math.huge, 500) -- TODO: Set this up
}

local x = { -- comment
    hello = "world",
    foo = "bar",
}

local foo = { -- bar
}

local bar = { baz -- bar
}

local baz = {
	-- foo
}

local foobar = {
	"string"
} -- trailing comment

local tbl = Roact.createElement({
	-- comment
	a = test
	-- comment
})


local obj = { method1 = function(self) end, method2 = function(self, name) end }

local obj = { method1 = function(self) print(true) end, method2 = function(self, name) end }

local obj = { method1 = function(self) end, method2 = function(self, name) end, method3 = function(self) end, method4 = function(self, name) end, ["some-method"] = function(self) end, ["another-method"] = function(self, name) end, ["some-another-method"] = function(self) end, ["yet-another-method"] = function(self, name) end }


local foo = {
    {"foobarbazfoobarbaz", "foobarbazfoobarbaz"},
    {"foobarbazfoobarbaz", "foobarbazfoobarbaz"},
    {"foobarbazfoobarbaz", "foobarbazfoobarbaz"},
    {"foobarbazfoobarbaz", "foobarbazfoobarbaz"}
}


function foo()
	while NextFreq.Access ~= true and not Llama.List.find(NextFreq.Access, Players.LocalPlayer.Team.Name) and NextIndex > #Constants.RADIO_CHANNEL_ORDER do
		print("test")
	end
end


local Object = {ClassName = "Object"}
Object.__tostring = function(self) return self.ClassName end

Object.__tostring = function(self): string
    return self.ClassName
end


do
	for _, foo in
		applyFoooooo(
			aaaaaaaaaaaaaaaaaaaa, --[[:: Array<aaaaaaaaaaaaaaaaa>]]
			bbbbbbbbbbbbbbbbbb --[[:: Array<bbbbbbbbbbbbbbb>]]
		) :: Array<aaaaaaaaaaaaaaaaa | bbbbbbbbbbbbbbb>
	do
	end
end


local function foo(bar: Instance, baz: Instance, qux: Instance, quux: Instance, corge: Instance, grault: Instance, garply: Instance, waldo: Instance, fred: Instance, plugh: Instance, xyzzy: Instance, thud: Instance)
end


function foo(args: {
	id: string,
	fenderer: SubBassGuitar,
	fendererInterface: BasGuitarInterface,
})
	print("foo")
end

function foo(args: {
	id: string,
	fenderer: SubBassGuitar,
	fendererInterface: BasGuitarInterface,
}, type: string)
	print("foo")
end

local subs = {
	amps.sub("fenderer-nations", function(
		args: {
		id: string,
		fenderer: SubBassGuitar,
		fendererInterface: BasGuitarInterface,
	}
	)
		print("test")
	end),
}


for _id: number, transform: Components.Transform, angularControls: Components.AngularControls, characterModel: Components.CharacterModel in world:query(Transform, AngularControls, CharacterModel) do
    -- ...
end


cache:writeQuery({
	data = {
		items = Array.concat({}, (function()
			local ref = if Boing.toXYZBoxinf(data) and data ~= nil
					then  data.items
					else data
			return Boing.toXYZBoxinf(ref) and ref
		end)() or {}, { item }),
	},
})

local error_ = if errors and #(errors :: Array<any>) > 0
	then ApolloError.new({ graphQLErrors = errors })
	else nil

local function useMutation<TData, TVariables, TContext, TCache>(
	mutation: DocumentNode | TypedDocumentNode<TData, TContext>,
	options: MutationHookOptions_<TData, TVariables, TContext>?
): MutationTuple<TData, TVariables, TContext, TCache>
	local context = useContext(getApolloContext())
	local result, setResult = useState({ called = false, loading = false })
	local updatedOptions = if options
		then Object.assign({}, options, { mutation = mutation })
		else { mutation = mutation }
end


local options = if useDisposableConcast
	-- Disposable Concast fetches receive a shallow copy of this.options
    -- (merged with newOptions), leaving this.options unmodified.
	then compact(self.options, newOptions)
	else Object.assign(self.options, compact(newOptions))

do
    local state: S = if hook ~= nil
        then hook.memoizedState
        elseif typeof(initialState) == "function"
            then
                -- Luau needs a little help, even with the generic function
                (initialState :: (() -> S))()
            else initialState

	local state: S = if hook ~= nil then hook.memoizedState
		elseif
			typeof(initialState) == "function" -- the fuzz pedal isn't 3.3V
			or _G.__DEV__                      -- in DEV mode, undervolt anyway
		then
			-- Luau needs a little help, even with the generic function
			(initialState :: (() -> S))()
		else initialState
end

local foo = if true then
	-- comment here
	bar
else baz

local x = if true
	then -- comment
		bar
	else -- comment
		baz

local p = if true then bar
else
	-- comment
	baz


local scale = if someReallyLongFlagName() or someOtherReallyLongFlagName() then foo else bar

local scale = if someReallyLongFlagName() or someOtherReallyLongFlagName() then foooooooooooooBarrrrrrrrr else barrrrrrrrrBazzzzzz

local scale = if someReallyLongFlagName() or someOtherReallyLongFlagName() then Vector2.new(1, 1) + someVectorOffset + someOtherVector else Vector2.new(1, 1) + someNewVectorOffset + someNewOtherVector

local scale = if someReallyReallyLongFunctionNameThatForcesTheConditionToSpanMultipleLines() and someOtherReallyLongFunctionNameThatForcesTheConditionToSpanMultipleLines() then 1 else 2

local thing = makeSomething("Foo", {
	OneChild = if someFlag() then
		makeSomething("Bar", {
			scale = 1,
		})
	else
		makeSomething("Bar", {
			scale = 2,
		}),
	TwoChild = makeSomething("Baz"),
})

local thing = makeSomething("Foo", {
	OneChild = if someFlag() then makeSomething("Bar", {
		scale = 1,
	}) else makeSomething("Bar", {
		scale = 2,
	}),
	TwoChild = makeSomething("Baz"),
})

local state = if hook ~= nil then hook.memoizedState elseif typeof(initialState) == "function" then (initialState :: (() -> S))() else initialState

local scale = if someFlag() then 1 elseif someOtherFlag() then 0.5 else 2

local thing = makeSomething("Foo", {
	OneChild = if someFlag()
		then makeSomething("Bar", {
			scale = 1,
		})
		elseif someOtherFlag() then makeSomething("Bar", {
			scale = 0.5,
		})
		else makeSomething("Bar", {
			scale = 2,
		}),
	TwoChild = makeSomething("Baz"),
})
do
	do
	  do
		do
		  console.error(
			"guitarFuzz design functions accept exactly two parameters: guiter and fuzz. %s",
			if argumentCount == 1 then "Did you forget to use the fuzz parameter?" else "Any additional parameter will be undefined."
		  )
		end
	  end
  end
end


--!strict

type Array<T> = { [number]: T }
type Dictionary<T> = { [string]: T }

local RunService = game:GetService("RunService")

local INVALID_DUMP_VERSION = "API dump is an invalid version `%i` (expected version 1)"
local MODULE_NOT_READY_MESSAGE = "API has not been fetched yet; try using API.isReady() before calling API functions"
local CLASS_NOT_REAL_MESSAGE = "Class `%s` is not a valid Roblox class"
local API_REQUEST_FAILED_MESSAGE = "Could not get API dump: `%s`. Retrying in %i seconds."

local ApiTypes = require(script.ApiTypes)
local FetchApi = require(script.FetchApi)
local Filters = require(script.Filters)
local Util = require(script.Util)

local ReadyBindable = Instance.new("BindableEvent")

local classMap: Dictionary<ApiTypes.Class> = {}
local superClassMap: Dictionary<Array<ApiTypes.Class>> = {}

local dump: ApiTypes.API

local filterSecurity = Util.filterSecurity
local filterTags = Util.filterTags
local lookupify = Util.lookupify
local cloneMember = Util.cloneMember

local function tryAPI(): ()
	if dump then return end

	dump = FetchApi()

	if dump.Version ~= 1 then
		error(string.format(INVALID_DUMP_VERSION, dump.Version), 2)
	end

	for _, class in ipairs(dump.Classes) do
		classMap[class.Name] = class
	end

	for className in pairs(classMap) do
		local classTables = {}
		local root = className
		while classMap[root] do
			table.insert(classTables, 1, classMap[root])
			root = classMap[root].Superclass
		end
		superClassMap[className] = classTables
	end
end

local API = {}

API.readyEvent = ReadyBindable.Event
API.filters = Filters

function API.isReady()
	return not not dump
end

function API.getMembers(class: string, tagFilter: Array<string>?, securityFilter: Array<string>?): Dictionary<ApiTypes.Member>
	if not dump then
		error(MODULE_NOT_READY_MESSAGE, 2)
	end

	local superClasses: Array<ApiTypes.Class> = superClassMap[class]
	if not superClasses then
		error(string.format(CLASS_NOT_REAL_MESSAGE, class), 2)
	end

	local tagLookup: Dictionary<boolean> = lookupify(tagFilter)
	local securityLookup: Dictionary<boolean> = lookupify(securityFilter)

	local memberList: Dictionary<ApiTypes.Member> = {}
	for _, class in ipairs(superClasses) do
		for _, v in ipairs(class.Members) do
			if filterSecurity(v.Security, securityLookup) then continue end
			if filterTags(v.Tags, tagLookup) then continue end

			memberList[v.Name] = cloneMember(v)
		end
	end

	return memberList
end

function API.getProperties(class: string, tagFilter: Array<string>?, securityFilter: Array<string>?): Dictionary<ApiTypes.Property>
	if not dump then
		error(MODULE_NOT_READY_MESSAGE, 2)
	end

	local superClasses: Array<ApiTypes.Class> = superClassMap[class]
	if not superClasses then
		error(string.format(CLASS_NOT_REAL_MESSAGE, class), 2)
	end

	local tagLookup: Dictionary<boolean> = lookupify(tagFilter)
	local securityLookup: Dictionary<boolean> = lookupify(securityFilter)

	local memberList: Dictionary<ApiTypes.Property> = {}
	for _, class in ipairs(superClasses) do
		for _, v in ipairs(class.Members) do
			if v.MemberType ~= "Property" then continue end
			if filterSecurity(v.Security, securityLookup) then continue end
			if filterTags(v.Tags, tagLookup) then continue end

			memberList[v.Name] = cloneMember(v)
		end
	end

	return memberList
end

function API.getFunctions(class: string, tagFilter: Array<string>?, securityFilter: Array<string>?): Dictionary<ApiTypes.Function>
	if not dump then
		error(MODULE_NOT_READY_MESSAGE, 2)
	end

	local superClasses: Array<ApiTypes.Class> = superClassMap[class]
	if not superClasses then
		error(string.format(CLASS_NOT_REAL_MESSAGE, class), 2)
	end

	local tagLookup: Dictionary<boolean> = lookupify(tagFilter)
	local securityLookup: Dictionary<boolean> = lookupify(securityFilter)

	local memberList: Dictionary<ApiTypes.Function> = {}
	for _, class in ipairs(superClasses) do
		for _, v in ipairs(class.Members) do
			if v.MemberType ~= "Function" then continue end
			if filterSecurity(v.Security, securityLookup) then continue end
			if filterTags(v.Tags, tagLookup) then continue end

			memberList[v.Name] = cloneMember(v)
		end
	end

	return memberList
end

function API.getEvents(class: string, tagFilter: Array<string>?, securityFilter: Array<string>?): Dictionary<ApiTypes.Event>
	if not dump then
		error(MODULE_NOT_READY_MESSAGE, 2)
	end

	local superClasses: Array<ApiTypes.Class> = superClassMap[class]
	if not superClasses then
		error(string.format(CLASS_NOT_REAL_MESSAGE, class), 2)
	end

	local tagLookup: Dictionary<boolean> = lookupify(tagFilter)
	local securityLookup: Dictionary<boolean> = lookupify(securityFilter)

	local memberList: Dictionary<ApiTypes.Event> = {}
	for _, class in ipairs(superClasses) do
		for _, v in ipairs(class.Members) do
			if v.MemberType ~= "Event" then continue end
			if filterSecurity(v.Security, securityLookup) then continue end
			if filterTags(v.Tags, tagLookup) then continue end

			memberList[v.Name] = cloneMember(v)
		end
	end

	return memberList
end

function API.getCallbacks(class: string, tagFilter: Array<string>?, securityFilter: Array<string>?): Dictionary<ApiTypes.Callback>
	if not dump then
		error(MODULE_NOT_READY_MESSAGE, 2)
	end

	local superClasses: Array<ApiTypes.Class> = superClassMap[class]
	if not superClasses then
		error(string.format(CLASS_NOT_REAL_MESSAGE, class), 2)
	end

	local tagLookup: Dictionary<boolean> = lookupify(tagFilter)
	local securityLookup: Dictionary<boolean> = lookupify(securityFilter)

	local memberList: Dictionary<ApiTypes.Callback> = {}
	for _, class in ipairs(superClasses) do
		for _, v in ipairs(class.Members) do
			if v.MemberType ~= "Callback" then continue end
			if filterSecurity(v.Security, securityLookup) then continue end
			if filterTags(v.Tags, tagLookup) then continue end

			memberList[v.Name] = cloneMember(v)
		end
	end

	return memberList
end

function API.getSuperclasses(class: string): Array<string>
	if not dump then
		error(MODULE_NOT_READY_MESSAGE, 2)
	end

	local superClasses: Array<ApiTypes.Class> = superClassMap[class]
	if not superClasses then
		error(string.format(CLASS_NOT_REAL_MESSAGE, class), 2)
	end

	local list = {}
	for i, class in ipairs(superClasses) do
		list[i] = class.Name
	end

	return list
end

function API.isDeprecated(class: string, member: string?): boolean
	if not dump then
		error(MODULE_NOT_READY_MESSAGE, 2)
	end

	local classTable: ApiTypes.Class = classMap[class]
	if not classTable then
		error(string.format(CLASS_NOT_REAL_MESSAGE, class), 2)
	end

	if member then
		local members = API.getMembers(class, {"Deprecated"})
		if members[member] then
			return true
		else
			return false
		end
	else
		local tags: typeof(classTable.Tags) = classTable.Tags
		if tags then
			if table.find(tags, "Deprecated") then
				return true
			end
		end
	end
	return false
end

function API.isService(class: string): boolean
	if not dump then
		error(MODULE_NOT_READY_MESSAGE, 2)
	end

	local classTable: ApiTypes.Class = classMap[class]
	if not classTable then
		error(string.format(CLASS_NOT_REAL_MESSAGE, class), 2)
	end

	local tags: typeof(classTable.Tags) = classTable.Tags
	if tags then
		if table.find(tags, "Service") then
			return true
		end
	end
	return false
end

function API.getClasses(filter: Array<string>?): Array<string>
	if not dump then
		error(MODULE_NOT_READY_MESSAGE, 2)
	end
	local classList: Array<string> = {}

	local tagLookup: Dictionary<boolean> = lookupify(filter)

	local classCount = 1

	for _, v in ipairs(dump.Classes) do
		if filterTags(v.Tags, tagLookup) then continue end

		classList[classCount] = v.Name
		classCount += 1
	end

	return classList
end

function API.getEnums(filter: Array<string>?): Array<string>
	if not dump then
		error(MODULE_NOT_READY_MESSAGE, 2)
	end
	local enumList: Array<string> = {}

	local tagLookup: Dictionary<boolean> = lookupify(filter)

	local enumCount = 1

	for _, v in ipairs(dump.Enums) do
		if filterTags(v.Tags, tagLookup) then continue end

		enumList[enumCount] = v.Name
		enumCount += 1
	end

	return enumList
end

export type Member = ApiTypes.Member
export type Property = ApiTypes.Property
export type Function = ApiTypes.Function
export type Event = ApiTypes.Event
export type Callback = ApiTypes.Callback

return API


local foo = {
	[ [[test]] :: test ] = true,
}

foo[ [[test]] :: test ] = false


export type ObservableQueryFields<TData, TVariables> = ObservableQueryPick<TData, TVariables> & {
    fetchMore: ((
        _self: any,
        fetchMoreOptions: FetchMoreQueryOptions<TVariables, TData> & FetchMoreOptions<TData, TVariables>
    ) -> Promise<ApolloQueryResult<TData>>) & ((<TData2, TVariables2>(
        _self: any,
        fetchMoreOptions: { query: (DocumentNode | TypedDocumentNode<TData, TVariables>)? } & FetchMoreQueryOptions<TVariables2, TData> & FetchMoreOptions<TData2, TVariables2>
    ) -> Promise<ApolloQueryResult<TData2>>)),
}

export type ObservableQueryFields<TData, TVariables> = ObservableQueryPick<TData, TVariables> & {
	fetchMore: ((
		_self: any,
		FetchMoreQueryOptions<TVariables, TData> & FetchMoreOptions<TData, TVariables>
	) -> Promise<ApolloQueryResult<TData>>) & ((
		-- ROBLOX deviation: dont have function generics
		{ query: (DocumentNode | TypedDocumentNode<TData, TVariables>)? } & FetchMoreQueryOptions<any, TData> & FetchMoreOptions<any, any>
	) -> Promise<ApolloQueryResult<any>>),
}

type Foo = (
	a: X & -- test
	Y
) -> string

type Foo = () -> X & -- test
Y


export type XYZ = {
	onSubmitTigerFoot: (
		FendererID,
		Object,
		-- Added in v96.1 to support Prelifer priority lamerz
		number?,
		-- Added in v96.9 to support Star Refresh
		boolean?
	) -> (),
}


export type Thenable<R, U> = {
	andTheeeeeeeeeeeeeeen: (any, (R) -> () | Thenable<R, U> | U, (any) -> () | Thenable<R, U> | U) -> () | Thenable<R, U>,
}


local function mergeDeep<T...>(...: T...) -- : TupleToIntersection<...T>
	return mergeDeepArray({ ... })
end


export type GraphQLInputType =
	GraphQLScalarType
	| GraphQLEnumType
	| GraphQLInputObjectType
	| GraphQLList<GraphQLScalarType | GraphQLEnumType | GraphQLInputObjectType | GraphQLList<any> | GraphQLNonNull<GraphQLScalarType | GraphQLEnumType | GraphQLInputObjectType | GraphQLList<GraphQLScalarType | GraphQLEnumType | GraphQLInputObjectType | GraphQLList<any> | GraphQLNonNull<GraphQLScalarType | GraphQLEnumType | GraphQLInputObjectType>>>>
	| GraphQLNonNull<GraphQLScalarType | GraphQLEnumType | GraphQLInputObjectType | GraphQLList<GraphQLScalarType | GraphQLEnumType | GraphQLInputObjectType | GraphQLList<any> | GraphQLNonNull<GraphQLScalarType | GraphQLEnumType | GraphQLInputObjectType>>>


export type Cache_WriteOptions<TResult = any, TVariables = any> = Omit_id_from_DataProxy_Query<TVariables, TResult> & Omit_data_from_DataProxy_WriteOptions<TResult> & { dataId: string?, result: TResult }


export type CoverageReporterWithOptions<K> =
	Array<string | Object> --[[ [K, Partial<ReportOptions[K]>] ]]
	| nil

export type CoverageReporterWithOptions<K> =
	Array<string | Object> --[[ [K, Partial<ReportOptions[K]>] ]]
	& nil


export type IntrospectionType = IntrospectionScalarType | IntrospectionObjectType | IntrospectionInterfaceType | IntrospectionUnionType | IntrospectionEnumType | IntrospectionInputObjectType

export type IntrospectionOutputType = IntrospectionScalarType | IntrospectionObjectType | IntrospectionInterfaceType | IntrospectionUnionType | IntrospectionEnumType

export type IntrospectionInputType = IntrospectionScalarType | IntrospectionEnumType | IntrospectionInputObjectType


-- Shouldn't hang since multiline comments arent an issue

export type GraphQLEnumType =  --[[ <T> ]]{
	name: string,
	description: string?,
	extensions: ReadOnlyObjMap<any>?,
	astNode: EnumTypeDefinitionNode?,
	extensionASTNodes: Array<EnumTypeExtensionNode>?,

	_values: Array<GraphQLEnumValue --[[ <T> ]]>,
	_valueLookup: Map<any --[[ T ]], GraphQLEnumValue>,
	_nameLookup: ObjMap<GraphQLEnumValue>,
	-- ROBLOX deviation: add self parameter for all ':' operator methods
	getValues: (self: GraphQLEnumType) -> Array<GraphQLEnumValue --[[ <T> ]]>,
	getValue: (self: GraphQLEnumType, string) -> GraphQLEnumValue?,
	serialize: (
		self: GraphQLEnumType,
		any --[[ T ]]
	) -> string?,
	parseValue: (self: GraphQLEnumType, any) -> any?, --[[ T ]]
	parseLiteral: (self: GraphQLEnumType, ValueNode, ObjMap<any>?) -> any?, --[[ T ]]
	toConfig: (self: GraphQLEnumType) -> GraphQLEnumTypeNormalizedConfig,
}


function foo(): (
	nil -- Some comment
)
	return nil
end

type X = (
	string,
	number -- testing
) -> (
	number,
	string -- testing
)


type PseudoEnumItemConstructor = (((GuiThemeTypeEnum, string) -> GuiThemeType) & ((GuiBrandTypeEnum, string) -> GuiBrandType) & ((GuiStateModifierEnum, string) -> GuiStateModifier) & ((GuiBrandTypeEnum, string) -> GuiBrandType) & ((GuiStateModifierEnum, string) -> GuiStateModifier) & ((GuiDensityModifierEnum, string) -> GuiDensityModifier) & ((GuiColorPaletteEnum, string) -> GuiColorPalette) & ((GuiTypographyEnum, string) -> GuiTypography) & ((GuiColorTypeEnum, string) -> GuiColorType) & ((ValidityFailTypeEnum, string) -> ValidityFailType) & ((VehicleClassEnum, string) -> VehicleClass) & ((VehiclePurposeEnum, string) -> VehiclePurpose) & ((FuelTypeEnum, string) -> FuelType) & ((LaneTypeEnum, string) -> LaneType) & ((InfrastructureTypeEnum, string) -> InfrastructureType) & ((FoundationTypeEnum, string) -> FoundationType) & ((BiomeTypeEnum, string) -> BiomeType) & ((BuildStateEnum, string) -> BuildState) & ((BuildMethodTypeEnum, string) -> BuildMethodType) & ((CurvePartTypeEnum, string) -> CurvePartType))


function foo(
	bar: number,
	baz: number -- test
): number
	print("test")
end


type PromptSettings = {
    object: string,
    action: string,
    holdDuration: number,
    keyboardKey: KeyCode,
    gamepadKey: KeyCode,
    distance: number,
    lineOfSight: boolean,
    offset: Vector2,
}

export type Sprite = {
	Image: string, ImageRectOffset: Vector2, ImageRectSize: Vector2 }


type SubscribeToMoreOptions<TData, TSubscriptionVariables, TSubscriptionData> =
	watchQueryOptionsModule.SubscribeToMoreOptions<TData, TSubscriptionVariables, TSubscriptionData>


type X = {
	useMemo: <T...>(nextCreate: () -> T..., deps: Array<any> | nil) -> T...,
}


export type IntrospectionNamedTypeRef<
  T, -- TODO: add generic constraints and default types: IntrospectionType = IntrospectionType,
  P
> = {
  kind: any, -- deviation: add this type spec later: $PropertyType<T, 'kind'>,
  name: string,
  ofType: T -- TODO: this field is missing
}

export type ReactScopeQuery = (
	string, -- type
	{ [any]: any }, -- props
	any -- instance
) -> boolean

export type Thenable<R> = {
	andThen: <U>(
		self: Thenable<R>,
		onFulfill: (R) -> () | _Thenable<U> | U,
		onReject: (error: any) -> () | _Thenable<U> | U
	-- note: need union type packs to parse () | Thenable<U>
	) -> nil | _Thenable<U>,
}


local srcWorkspace = script.Parent.Parent
local PromiseModule = require(srcWorkspace.luaUtils.Promise)
type Promise<T> = PromiseModule.Promise<T>
type Resolver<T, U> = any
type Result = any

export type SubscriptionArgs = {
    rootValue: any?,
    contextValue: any?,
    variableValues: { [string]: any },
    operationName: string?,
    fieldResolver: Resolver<any, any>?,
    subscribeFieldResolver: Resolver<any, any>?
}

local function subscribe(
	args: SubscriptionArgs
  ): Promise<Result>
  error("nope")
end

local function createEventStream(
	rootValue: any?,
	contextValue: any?,
	variableValues: { [string]: any }?,
	operationName: string?,
	fieldResolver: Resolver<any, any>?
  ): Promise<Result>
  error("nope")
end

return {
	subscribe = subscribe,
	createEventStream = createEventStream
}


type function UserDefinedTypeFunction(Foo: type, Bar: type, Qux: type): type
    return types.intersectionof(Foo, Bar, Qux)
end

export type function ExportUserDefinedTypeFunction(Foo: type, Bar: type, Qux: type): type
    return types.unionof(Foo, Bar, Qux)
end


--!native
--!optimize 2
--!strict

local gate = require("gate")
local qb = require("qb")
local preset = require("preset")

type complex = {r: number, i: number}
type qubit = {complex}
type qubits = {qubit}
type matrix = {{complex}}
type matrix_sz = {r: number, c: number}

local algo = {}

function algo.shor(n: number): number
	local function period(a: number, n: number): number
		local q = 2^math.ceil(math.log(n^2, 2))
		local qs = qb.new_ex(q)
		qs = gate.apply_ex(qs, preset.hadamard)
		for i = 0, q - 1 do
			qs = gate.apply_ex(qs, gate.controlled_modular_exponentiation(a, n, i))
		end
		return qb.mmeasure(qb.qft(qs))
	end
	local function gcd(a: number, b: number): number
		while b ~= 0 do
			a, b = b, a % b
		end
		return a
	end
	if n % 2 == 0 then return 2 end
	local a = math.random(2, n - 1)
	local g = gcd(a, n)
	if g > 1 then return g end
	local r = period(a, n)
	if r % 2 ~= 0 then return algo.shor(n) end
	local factor = gcd(a^(r//2) + 1, n)
	if factor == 1 or factor == n then return algo.shor(n) end
	return factor
end

function algo.grover(f: (qubits) -> qubits, n: number): number
	local qs = qb.new_ex(n)
	qs = gate.apply_ex(qs, preset.hadamard)
	local iterations = math.floor(math.pi/4 * math.sqrt(2^n))
	for _ = 1, iterations do
		qs = f(qs)
		qs = gate.diffusion(qs)
	end
	return qb.mmeasure(qs)
end

function algo.qft(qs: qubits): qubits
	local n = #qs
	for i = 1, n do
		qs = gate.apply_ex(qs, preset.hadamard)
		for j = i + 1, n do
			local angle = 2 * math.pi / (2^(j - i + 1))
			qs = gate.apply_ex(qs, gate.controlled_phase(angle))
		end
	end
	for i = 1, n // 2 do
		qs = gate.apply_ex(qs, preset.swap)
	end
	return qs
end

function algo.vqe(hamiltonian: matrix, depth: number): number
	local n = #hamiltonian
	local function ansatz(params: {number}): qubits
		local qs = qb.new_ex(n)
		local param_idx = 1
		for _ = 1, depth do
			for i = 1, n do
				qs = gate.apply_ex(qs, gate.rx(params[param_idx]))
				param_idx = param_idx + 1
				qs = gate.apply_ex(qs, gate.ry(params[param_idx]))
				param_idx = param_idx + 1
			end
			for i = 1, n - 1 do
				qs = gate.apply_ex(qs, preset.cnot)
			end
		end
		return qs
	end

	local function objective(params: {number}): number
		local qs = ansatz(params)
		return qb.expectation(qs, hamiltonian)
	end

	local params = table.create(2 * n * depth, 0)
	for i = 1, #params do
		params[i] = math.random() * 2 * math.pi
	end

	local iterations = 100
	local learning_rate = 0.1
	for _ = 1, iterations do
		local grad = table.create(#params, 0)
		for i = 1, #params do
			local params_plus = table.clone(params)
			local params_minus = table.clone(params)
			params_plus[i] = params_plus[i] + 0.01
			params_minus[i] = params_minus[i] - 0.01
			grad[i] = (objective(params_plus) - objective(params_minus)) / 0.02
		end
		for i = 1, #params do
			params[i] = params[i] - learning_rate * grad[i]
		end
	end

	return objective(params)
end

function algo.qaoa(qubits: qubits, p: number, gammas: {number}, betas: {number}): qubits
	for k = 1, p do
		qubits = gate.cost_hamiltonian(qubits, gammas[k])
		qubits = gate.mixer_hamiltonian(qubits, betas[k])
	end
	return qubits
end

function algo.qpe(qs: qubits, unitary: matrix, precision: number): qubits
	for i = 1, precision do
		qs = gate.apply_ex(qs, preset.hadamard)
	end
	for i = 1, precision do
		local control_qubit = i
		local exponent = 2^(precision - i)
		qs = gate.apply_ex(qs, gate.controlled_unitary(unitary, control_qubit, precision + 1, exponent))
	end

	qs = (function(qs: qubits, n: number): qubits
		for i = n, 1, -1 do
			for j = i + 1, n do
				local angle = -2 * math.pi / (2^(j - i + 1))
				qs = gate.apply_ex(qs, gate.controlled_phase(angle))
			end
			qs = gate.apply_ex(qs, preset.hadamard)
		end
		return qs
	end)(qs, precision)

	return qs
end

return algo


--!native
--!optimize 2
--!strict

type complex = {r: number, i: number}
type qubit = {complex}
type qubits = {qubit}
type gate = {{complex}}
type matrix = {{complex}}
type hamiltonian = {{number}}

local cpx = require("cpx")
local gate = require("gate")
local mtx = require("mtx")
local qb = require("qb")
local preset = require("preset")

local anneal = {}

local BOLTZMANN = 1.380649e-23 -- Boltzmann constant
local PLANCK = 6.62607015e-34 -- Planck constant

-- helper fucntion because it's not compatible..
local function hamiltoniantomatrix(h: hamiltonian): matrix
	local m: matrix = {}
	for i, row in ipairs(h) do
		m[i] = {}
		for j, value in ipairs(row) do
			m[i][j] = cpx.new(value, 0)
		end
	end
	return m
end

-- Unused functions 🥰
-- local function randompair()
-- 	return math.random(), math.random()
-- end

-- local function sigmoid(x) -- Sigmoid.
-- 	return 1 / (1 + math.exp(-x))
-- end

function anneal.quantumanneal(hamiltonian: hamiltonian, initialstate: {number}, temperature: number, steps: number, coolingrate: number): ({number}, number)
	local currentstate = initialstate
	local bestenergy = anneal.evaluateenergy(currentstate, hamiltonian)
	local beststate = currentstate

	for step = 1, steps do
		local newstate = anneal.perturb(currentstate)
		local newenergy = anneal.evaluateenergy(newstate, hamiltonian)

		local energydifference = newenergy - bestenergy

		if energydifference < 0 or math.exp(-energydifference / (BOLTZMANN * temperature)) > math.random() then
			currentstate = newstate
			bestenergy = newenergy

			if newenergy < bestenergy then
				beststate = newstate
				bestenergy = newenergy
			end
		end

		temperature = temperature * coolingrate
	end

	return beststate, bestenergy
end

function anneal.evaluateenergy(state: {number}, hamiltonian: hamiltonian): number
	local energy = 0
	for i = 1, #state do
		for j = 1, #state do
			energy = energy + hamiltonian[i][j] * state[i] * state[j]
		end
	end
	return energy
end

function anneal.perturb(state: {number}): {number}
	local newstate = table.create(#state)
	for i = 1, #state do
		newstate[i] = state[i]
	end

	local index = math.random(1, #state)
	newstate[index] = -newstate[index] -- Flip the spin!

	return newstate
end

function anneal.preparequbits(n: number): qubits
	local qubits: qubits = {}
	for i = 1, n do
		qubits[i] = qb.new(cpx.new(1 / math.sqrt(2), 0), cpx.new(1 / math.sqrt(2), 0))
	end
	return qubits
end

function anneal.applyquantumfluctuation(qubits: qubits, strength: number): qubits
	local hadamardgate = preset.hadamard
	for i = 1, #qubits do
		qubits[i] = gate.apply(qubits[i], mtx.scalar_mul(cpx.new(strength, 0), hadamardgate))
	end
	return qubits
end

function anneal.measurestate(qubits: qubits): {number}
	local state: {number} = {}
	for i = 1, #qubits do
		state[i] = qb.measure(qubits[i]) * 2 - 1 -- Convert to {-1, 1}
	end
	return state
end

function anneal.quantumfluctuationstrength(t: number, tmax: number): number
	return (1 - t / tmax) ^ 2
end

function anneal.classicalfluctuationstrength(t: number, tmax: number): number
	return (t / tmax) ^ 2
end

function anneal.metropolisacceptance(energydiff: number, temperature: number): number
	return math.exp(-energydiff / temperature)
end

function anneal.simulatedquantumannealing(hamiltonian: hamiltonian, nqubits: number, steps: number, initialtemp: number, finaltemp: number): ({number}, number)
	local qubits = anneal.preparequbits(nqubits)
	local currentenergy = anneal.evaluateenergy(anneal.measurestate(qubits), hamiltonian)
	local bestenergy = currentenergy
	local beststate = anneal.measurestate(qubits)

	for step = 1, steps do
		local t = step / steps
		local temperature = initialtemp + (finaltemp - initialtemp) * t

		local qstrength = anneal.quantumfluctuationstrength(step, steps)
		local cstrength = anneal.classicalfluctuationstrength(step, steps)

		qubits = anneal.applyquantumfluctuation(qubits, qstrength)

		local newstate = anneal.measurestate(qubits)
		local newenergy = anneal.evaluateenergy(newstate, hamiltonian)

		local energydiff = newenergy - currentenergy

		if energydiff < 0 or math.random() < anneal.metropolisacceptance(energydiff, temperature) then
			currentenergy = newenergy
			if newenergy < bestenergy then
				bestenergy = newenergy
				beststate = newstate
			end
		else
			qubits = anneal.preparequbits(nqubits)
		end

		if cstrength > 0 then
			newstate = anneal.perturb(newstate)
			newenergy = anneal.evaluateenergy(newstate, hamiltonian)
			energydiff = newenergy - currentenergy

			if energydiff < 0 or math.random() < anneal.metropolisacceptance(energydiff, temperature) then
				currentenergy = newenergy
				if newenergy < bestenergy then
					bestenergy = newenergy
					beststate = newstate
				end
				qubits = anneal.statetoqubits(newstate)
			end
		end
	end

	return beststate, bestenergy
end

function anneal.statetoqubits(state: {number}): qubits
	local qubits: qubits = {}
	for i = 1, #state do
		local angle = state[i] == 1 and 0 or math.pi
		qubits[i] = qb.new(cpx.new(math.cos(angle/2), 0), cpx.new(math.sin(angle/2), 0))
	end
	return qubits
end

function anneal.quantumtunneling(currentstate: {number}, hamiltonian: hamiltonian, temperature: number): {number}
	local n = #currentstate
	local tunneledstate = table.create(n)

	for i = 1, n do
		tunneledstate[i] = currentstate[i]
	end

	local i, j = math.random(1, n), math.random(1, n)
	while i == j do
		j = math.random(1, n)
	end

	tunneledstate[i], tunneledstate[j] = -tunneledstate[i], -tunneledstate[j]

	local energydiff = anneal.evaluateenergy(tunneledstate, hamiltonian) - anneal.evaluateenergy(currentstate, hamiltonian)
	local tunnelingprob = math.exp(-energydiff / temperature)

	if math.random() < tunnelingprob then
		return tunneledstate
	else
		return currentstate
	end
end

function anneal.quantumoperator(qubits: qubits, hamiltonian: hamiltonian): qubits
	local n = #qubits
	local result: qubits = table.create(n)
	local matrixH = hamiltoniantomatrix(hamiltonian)

	for i = 1, n do
		result[i] = qb.new(cpx.new(0, 0), cpx.new(0, 0))
		for j = 1, n do
			local term = gate.apply(qubits[j], mtx.scalar_mul(matrixH[i][j], preset.pauliz))
			result[i] = {cpx.add(result[i][1], term[1]), cpx.add(result[i][2], term[2])}
		end
	end

	return result
end

function anneal.trotter(qubits: qubits, hamiltonian: hamiltonian, timestep: number, trottersteps: number): qubits
	for _ = 1, trottersteps do
		local evolved = anneal.quantumoperator(qubits, hamiltonian)
		for i = 1, #qubits do
			local phase = cpx.mul(cpx.new(0, -timestep / trottersteps), evolved[i][1])
			qubits[i] = {cpx.mul(qubits[i][1], cpx.exp(phase)), cpx.mul(qubits[i][2], cpx.exp(phase))}
		end
	end
	return qubits
end

function anneal.quantummontecarloanneal(hamiltonian: hamiltonian, nqubits: number, steps: number, initialtemp: number, finaltemp: number, trottersteps: number): ({number}, number)
	local qubits = anneal.preparequbits(nqubits)
	local currentenergy = qb.expectation(qubits, hamiltoniantomatrix(hamiltonian))
	local bestenergy = currentenergy
	local beststate = anneal.measurestate(qubits)

	for step = 1, steps do
		local temperature = initialtemp + (finaltemp - initialtemp) * (step / steps)
		local timestep = PLANCK / (BOLTZMANN * temperature)

		qubits = anneal.trotter(qubits, hamiltonian, timestep, trottersteps)

		local newenergy = qb.expectation(qubits, hamiltoniantomatrix(hamiltonian))
		local energydiff = newenergy - currentenergy

		if energydiff < 0 or math.random() < math.exp(-energydiff / temperature) then
			currentenergy = newenergy
			if newenergy < bestenergy then
				bestenergy = newenergy
				beststate = anneal.measurestate(qubits)
			end
		else
			qubits = anneal.preparequbits(nqubits)
		end

		if step % 10 == 0 then
			local measuredState = anneal.measurestate(qubits)
			qubits = anneal.statetoqubits(anneal.quantumtunneling(measuredState, hamiltonian, temperature))
		end
	end

	return beststate, bestenergy
end

return anneal


--!native
--!optimize 2
--!strict

local cpx = require("cpx")
local mtx = require("mtx")
local qb = require("qb")

type complex = {r: number, i: number}
type matrix = {{complex}}
type qubit = {complex}
type qubits = {qubit}

local anyon = {}

local function braidgenerator(n: number, i: number): matrix
	local dim = 2^n
	local result = mtx.identity(dim)
	local root5 = cpx.new(math.sqrt(5), 0)
	local tau = cpx.div(cpx.add(cpx.new(1, 0), root5), cpx.new(2, 0))
	local phase = cpx.exp(cpx.mul(cpx.new(0, 2 * math.pi / 5), tau))

	result[i][i] = phase
	result[i+1][i+1] = cpx.conj(phase)

	return result
end

function anyon.fibonaccichain(n: number): qubits
	local qubits: qubits = {}
	for i = 1, n do
		qubits[i] = qb.new(cpx.new(1, 0), cpx.new(0, 0))
	end
	return qubits
end

function anyon.applybraid(qubits: qubits, i: number): qubits
	local n = #qubits
	if i < 1 or i >= n then
		error("Invalid braid index")
	end

	local braidmatrix = braidgenerator(n, i)
	local state = qb.tensorproduct(qubits)
	state = mtx.mul_mv(braidmatrix, state)

	local newqubits: qubits = {}
	for j = 1, n do
		newqubits[j] = {state[2*j-1], state[2*j]}
	end

	return newqubits
end

function anyon.measurecharge(qubits: qubits): string
	local state = qb.tensorproduct(qubits)
	local prob1 = cpx.abs(state[1])^2

	if math.random() < prob1 then
		return "trivial"
	else
		return "nontrivial"
	end
end

function anyon.topologicalqubit(): qubits
	local qubits = anyon.fibonaccichain(4)
	return anyon.applybraid(anyon.applybraid(qubits, 2), 1)
end

function anyon.topologicalnot(qubits: qubits): qubits
	assert(#qubits == 4, "Topological qubit must consist of 4 anyons")

	return anyon.applybraid(anyon.applybraid(anyon.applybraid(qubits, 2), 1), 2)
end

function anyon.topologicalhadamard(qubits: qubits): qubits
	assert(#qubits == 4, "Topological qubit must consist of 4 anyons")

	local rotated = anyon.applybraid(qubits, 1)
	rotated = anyon.applybraid(rotated, 2)
	rotated = anyon.applybraid(rotated, 1)
	return anyon.applybraid(rotated, 2)
end

function anyon.topologicalcnot(control: qubits, target: qubits): (qubits, qubits)
	assert(#control == 4 and #target == 4, "Both control and target must be topological qubits consisting of 4 anyons each")

	local combined = {}
	for i = 1, 4 do
		combined[i] = control[i]
		combined[i+4] = target[i]
	end

	combined = anyon.applybraid(combined, 4)
	combined = anyon.applybraid(combined, 5)
	combined = anyon.applybraid(combined, 4)
	combined = anyon.applybraid(combined, 3)
	combined = anyon.applybraid(combined, 4)
	combined = anyon.applybraid(combined, 5)
	combined = anyon.applybraid(combined, 4)

	local newcontrol: qubits = {}
	local newtarget: qubits = {}

	for i = 1, 4 do
		newcontrol[i] = combined[i]
		newtarget[i] = combined[i+4]
	end

	return newcontrol, newtarget
end

local function fusionchannel(a: string, b: string): {string}
	if a == "1" and b == "1" then
		return {"1"}
	elseif (a == "1" and b == "τ") or (a == "τ" and b == "1") then
		return {"τ"}
	elseif a == "τ" and b == "τ" then
		return {"1", "τ"}
	else
		error("Invalid anyon types for fusion")
	end
end

function anyon.fuse(a: string, b: string): string
	local channels = fusionchannel(a, b)
	if #channels == 1 then
		return channels[1]
	else
		return channels[math.random(#channels)]
	end
end

function anyon.topologicalspin(anyontype: string): complex
	if anyontype == "1" then
		return cpx.new(1, 0)
	elseif anyontype == "τ" then
		return cpx.exp(cpx.new(0, 2 * math.pi / 5))
	else
		error("Invalid anyon type")
	end
end

function anyon.braidingphase(a: string, b: string): complex
	local spina = anyon.topologicalspin(a)
	local spinb = anyon.topologicalspin(b)
	local spinab = anyon.topologicalspin(anyon.fuse(a, b))
	return cpx.mul(cpx.mul(spinab, cpx.conj(spina)), cpx.conj(spinb))
end

return anyon


--!native
--!optimize 2
--!strict

local circuitvis = {}

export type gate = string
export type qubit = {gate}
export type circuit = {qubit}
export type grid = {{string}}

local function creategrid(rows: number, cols: number): grid
	local grid = table.create(rows)
	for i = 1, rows do
		grid[i] = table.create(cols, " ")
	end
	return grid
end

local function drawwire(grid: grid, row: number, startcol: number, endcol: number)
	for col = startcol, endcol do
		grid[row][col] = "─"
	end
end

local function drawgate(grid: grid, row: number, col: number, gatetype: gate)
	local gatesymbols = {
		h = "H", x = "X", y = "Y", z = "Z",
		s = "S", t = "T", cx = "●", cz = "○"
	}
	grid[row][col] = gatesymbols[string.lower(gatetype)] or gatetype
end

local function drawcontrol(grid: grid, startrow: number, endrow: number, col: number)
	for row = startrow, endrow do
		if grid[row][col] == " " then
			grid[row][col] = "│"
		end
	end
	grid[startrow][col] = "●"
	grid[endrow][col] = "X"
end

function circuitvis.visualize(circuit: circuit): string
	assert(type(circuit) == "table" and #circuit > 0, "invalid circuit")

	local numqubits = #circuit
	local numsteps = 0
	for i = 1, numqubits do
		assert(type(circuit[i]) == "table", "invalid qubit at index " .. i)
		numsteps = math.max(numsteps, #circuit[i])
	end

	local grid = creategrid(numqubits * 2 - 1, numsteps * 4 + 2)

	for qubit = 1, numqubits do
		local row = (qubit - 1) * 2 + 1
		grid[row][1] = tostring(qubit - 1) .. ":"
		drawwire(grid, row, 3, numsteps * 4 + 2)

		for step = 1, #circuit[qubit] do
			local col = (step - 1) * 4 + 4
			local gate = circuit[qubit][step]
			assert(type(gate) == "string", "invalid gate at qubit " .. qubit .. ", step " .. step)

			if gate:sub(1, 1) == "c" and #gate > 1 then
				local targetqubit = tonumber(gate:sub(2))
				assert(targetqubit and targetqubit <= numqubits, "invalid controlled gate target")
				local targetrow = (targetqubit - 1) * 2 + 1
				drawcontrol(grid, math.min(row, targetrow), math.max(row, targetrow), col)
			else
				drawgate(grid, row, col, gate)
			end
		end
	end

	local visualcircuit = ""
	for i = 1, #grid do
		visualcircuit = visualcircuit .. table.concat(grid[i]) .. "\n"
	end

	return visualcircuit
end

function circuitvis.printcircuit(circuit: circuit)
	print(circuitvis.visualize(circuit))
end

return circuitvis


--!native
--!optimize 2
--!strict

-- feel free to advance this further i'm too lazy
-- dude?? it's literally like basic stuff

local EPSILON = 1e-10
local MAX_QUBITS = 10

type complex = {r: number, i: number}
type qubit = {complex}
type qubits = {qubit}
type gate = {{complex}}
type operation = {gate: string, target: number, control: number?, params: {number}?}

local gate = require("gate")
local preset = require("preset")
local noise = require("noise")

local compiler = {}

local function _isclose(a: number, b: number): boolean
	return math.abs(a - b) < EPSILON
end

local function matrixmultiply(a: gate, b: gate): gate
	local result: gate = table.create(#a)
	local colsb = #b[1]

	for i = 1, #a do
		result[i] = table.create(colsb)
		for j = 1, colsb do
			local sum = { r = 0, i = 0 }
			for k = 1, #a[1] do
				sum.r += a[i][k].r * b[k][j].r - a[i][k].i * b[k][j].i
				sum.i += a[i][k].r * b[k][j].i + a[i][k].i * b[k][j].r
			end
			result[i][j] = sum
		end
	end

	return result
end

function compiler.parse(algorithm: { operation }): { operation }
	local parsed = table.create(#algorithm)

	for _, op in ipairs(algorithm) do
		if type(op) == "table" and op.gate and op.target then
			table.insert(parsed, op)
		else
			warn("Invalid operation skipped:", op)
		end
	end

	return parsed
end

function compiler.optimize(circuit: { operation }): { operation }
	local optimized = table.create(#circuit)
	local i = 1

	while i <= #circuit do
		local current = circuit[i]
		local next = circuit[i + 1]

		if next and current.gate == next.gate and current.target == next.target then
			if current.gate == "paulix" or current.gate == "pauliy" or current.gate == "pauliz" then
				i += 2  -- Cancel out consecutive Pauli gates
			elseif current.gate == "rotation" and current.params and next.params then
				-- Combine consecutive rotations
				current.params[1] += next.params[1]
				table.insert(optimized, current)
				i += 2
			else
				table.insert(optimized, current)
				i += 1
			end
		else
			table.insert(optimized, current)
			i += 1
		end
	end

	return optimized
end

function compiler.compile(circuit: { operation }): { gate }
	local instructions = table.create(#circuit)

	for _, op in ipairs(circuit) do
		local gatematrix: gate

		if op.gate == "hadamard" then
			gatematrix = preset.hadamard
		elseif op.gate == "cnot" then
			assert(op.control, "Control qubit not specified for CNOT gate")
			gatematrix = gate.cnot(op.control, op.target)
		elseif op.gate == "paulix" then
			gatematrix = preset.paulix
		elseif op.gate == "pauliy" then
			gatematrix = preset.pauliy
		elseif op.gate == "pauliz" then
			gatematrix = preset.pauliz
		elseif op.gate == "rotation" then
			assert(op.params and #op.params == 3, "Rotation gate requires 3 parameters")
			gatematrix = gate.rx(op.params[1])
			gatematrix = matrixmultiply(gate.ry(op.params[2]), gatematrix)
			gatematrix = matrixmultiply(gate.rz(op.params[3]), gatematrix)
		elseif op.gate == "phase" then
			assert(op.params and #op.params == 1, "Phase gate requires 1 parameter")
			gatematrix = gate.rz(op.params[1])
		elseif op.gate == "toffoli" then
			assert(op.control, "Control qubit not specified for Toffoli gate")
			gatematrix = gate.toffoli() -- AXTRCT. i hope that your gate is good enough to handle toffoli,
		else                            -- it should probably take parameters to specify the control and target qubits
			error("Unknown gate: " .. op.gate) -- and im not checking this at all. if it isn't good enough, code breaks.
		end

		table.insert(instructions, gatematrix)
	end

	return instructions
end

function compiler.applynoise(circuit: { gate }, noisemodel: noise.noise_meta): { gate }
	local noisycircuit = table.create(#circuit)

	for _, gatematrix in ipairs(circuit) do
		local noisygate = noisemodel:apply_all(gatematrix)
		table.insert(noisycircuit, noisygate)
	end

	return noisycircuit
end

function compiler.compresscircuit(circuit: { gate }): { gate }
	local compressed = {}
	local currentgate: gate = circuit[1]

	for i = 2, #circuit do
		local nextgate = circuit[i]
		local combined = matrixmultiply(nextgate, currentgate)

		if #combined <= MAX_QUBITS then
			currentgate = combined
		else
			table.insert(compressed, currentgate)
			currentgate = nextgate
		end
	end

	table.insert(compressed, currentgate)
	return compressed
end

function compiler.compilealgorithm(algorithm: { operation }, noisemodel: noise.noise_meta?): { gate }
	local parsedcircuit = compiler.parse(algorithm)
	local optimizedcircuit = compiler.optimize(parsedcircuit)
	local machineinstructions = compiler.compile(optimizedcircuit)
	local compressedcircuit = compiler.compresscircuit(machineinstructions)

	if noisemodel then
		return compiler.applynoise(compressedcircuit, noisemodel)
	else
		return compressedcircuit
	end
end

function compiler.simulate(compiledcircuit: { gate }, initialstate: qubits): qubits
	local state = initialstate

	for _, gatematrix in ipairs(compiledcircuit) do
		state = gate.apply_ex(state, gatematrix)
	end

	return state
end

function compiler.measure(state: qubits): { number }
	local probabilities = table.create(#state)
	local totalprobability = 0

	for i, amplitude in ipairs(state) do
		local probability = amplitude[1].r * amplitude[1].r + amplitude[1].i * amplitude[1].i
		probabilities[i] = probability
		totalprobability += probability
	end

	-- Normalize probabilities
	for i, prob in ipairs(probabilities) do
		probabilities[i] = prob / totalprobability
	end

	local result = {}
	local random = math.random()
	local cumulative = 0

	for i, prob in ipairs(probabilities) do
		cumulative += prob
		if random <= cumulative then
			result[1] = i - 1  -- convert to 0-based index
			break
		end
	end

	-- convert result to binary representation
	local binary = table.create(math.log(#state, 2))
	local value = result[1]
	for i = 1, #binary do
		binary[i] = value % 2
		value = math.floor(value / 2)
	end

	return binary
end

return compiler


--!native
--!optimize 2
--!strict

type complex = {r: number, i: number}

local cpx = {}

function cpx.new(real: number?, imaginary: number?): complex
    return {r = real or 0, i = imaginary or 0}
end

function cpx.add(c1: complex, c2: complex)
	return cpx.new(c1.r + c2.r, c1.i + c2.i)
end

function cpx.sub(c1: complex, c2: complex)
	return cpx.new(c1.r - c2.r, c1.i - c2.i)
end

function cpx.mul(c1: complex, c2: complex)
	return cpx.new(c1.r * c2.r - c1.i * c2.i, c1.r * c2.i + c1.i * c2.r)
end

function cpx.div(c1: complex, c2: complex)
	local d = c2.r * c2.r + c2.i * c2.i
	return cpx.new((c1.r * c2.r + c1.i * c2.i) / d, (c1.i * c2.r - c1.r * c2.i) / d)
end

function cpx.abs(c: complex): number
    return math.sqrt(c.r * c.r + c.i * c.i)
end

function cpx.conj(c: complex)
	return cpx.new(c.r, -c.i)
end

function cpx.exp(c: complex)
	local e = math.exp(c.r)
	return cpx.new(e * math.cos(c.i), e * math.sin(c.i))
end

function cpx.pow(c: complex, n: number)  -- Becuase you still suck :heart:
	local r = cpx.abs(c)
	local theta = math.atan2(c.i, c.r)
	local rn = r ^ n
	local ntheta = n * theta
	return cpx.new(rn * math.cos(ntheta), rn * math.sin(ntheta))
end

function cpx.sqrt(c: complex) -- sqrt
	local r = cpx.abs(c)
	local x = math.sqrt((r + c.r) / 2)
	local y = math.sqrt((r - c.r) / 2)
	if c.i < 0 then y = -y end
	return cpx.new(x, y)
end

function cpx.log(c: complex): complex
	return cpx.new(math.log(math.sqrt(c.r * c.r + c.i * c.i)), math.atan2(c.i, c.r))
end

function cpx.tostring(c: complex): string
	return c.r .. (if c.i > 0 then "+" else "") .. c.i
end

-- https://hewgill.com/picomath/lua/gamma.lua.html

function cpx.gamma(c: complex): complex
	local gamma_const = 0.577215664901532860606512090

	if c.r < 0.001 then
		local term = {r = c.r * (1.0 + gamma_const * c.r), i = c.i}
		return {r = 1.0 / term.r, i = -term.i / (term.r * term.r)}
	end

	if c.r < 12.0 then
		local y = c.r
		local n = 0
		local arg_was_less_than_one = (y < 1.0)

		if arg_was_less_than_one then
			y = y + 1.0
		else
			n = math.floor(y) - 1
			y = y - n
		end

		local p = {
			-1.71618513886549492533811E+0,
			 2.47656508055759199108314E+1,
			-3.79804256470945635097577E+2,
			 6.29331155312818442661052E+2,
			 8.66966202790413211295064E+2,
			-3.14512729688483675254357E+4,
			-3.61444134186911729807069E+4,
			 6.64561438202405440627855E+4
		}
		local q = {
			-3.08402300119738975254353E+1,
			 3.15350626979604161529144E+2,
			-1.01515636749021914166146E+3,
			-3.10777167157231109440444E+3,
			 2.25381184209801510330112E+4,
			 4.75584627752788110767815E+3,
			-1.34659959864969306392456E+5,
			-1.15132259675553483497211E+5
		}

		local num = {r = 0.0, i = 0.0}
		local den = {r = 1.0, i = 0.0}

		local z = y - 1
		for i = 1, 8 do
			local term = cpx.mul({r = p[i], i = 0}, {r = z, i = 0})
			num = cpx.add(num, term)
			term = cpx.mul({r = q[i], i = 0}, {r = z, i = 0})
			den = cpx.add(den, term)
		end

		local result = cpx.div(num, den)
		result = cpx.add(result, {r = 1.0, i = 0.0})

		if arg_was_less_than_one then
			local term = {r = y - 1.0, i = 0.0}
			result = cpx.div(result, term)
		else
			for i = 1, n do
				result = cpx.mul(result, {r = y, i = 0.0})
				y = y + 1
			end
		end

		return result
	end

	if c.r > 171.624 then
		return {r = 1.0 / 0, i = 0}
	end

	local log_gamma = cpx.log(cpx.gamma(c))
	return cpx.exp(log_gamma)
end

return cpx