h&c6w       !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                                                                                     ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % % % % % % % % % % % & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ) ) ) ) ) * * * * *++ Safe-Inferred*5689:;=""  Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred*5689:;=% swarm5A context is a mapping from variable names to things.swarmWe use   values to represent variables.swarmThe empty context.swarmA singleton context.swarm Look up a variable in a context.swarm!Delete a variable from a context.swarm6Get the list of key-value associations from a context. swarmAdd a key-value binding to a context (overwriting the old one if the key is already present). swarmRight-biased union of contexts. swarm6Locally extend the context with an additional binding. swarmLocally extend the context with an additional context of bindings.swarm(The semigroup operation for contexts is right-biased union.    Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred*5689:;=9Q%swarmIn several cases we have two versions of something: a "normal" version, and a U. version with unification variables in it (e.g. * vs ), $ vs #, ( vs '). This class abstracts over the process of converting back and forth between them.In particular,  t# represents the fact that the type t also has a U counterpart, with a way to convert back and forth. Note, however, that converting back may be "unsafe" in the sense that it requires an extra burden of proof to guarantee that it is used only on inputs that are safe.swarmThe associated "U-version" of the type t.swarm Convert from t to its associated "U-version". This direction is always safe (we simply have no unification variables even though the type allows it).swarmConvert from the associated "U-version" back to t. Generally, this direction requires somehow knowing that there are no longer any unification variables in the value being converted.swarmA  represents the type of an expression at some intermediate stage during the type inference process. We get a ) (not a #) for the expression, which may contain some free unification or type variables, as well as a context of #s for any defined variables.swarmA  is the final result of the type inference process on an expression: we get a polytype for the expression, and a context of polytypes for the defined variables.swarmA module generally represents the result of performing type inference on a top-level expression, which in particular can contain definitions (,). A module contains the overall type of the expression, as well as the context giving the types of any defined variables.#swarm&A polytype with unification variables.$swarm)A polytype without unification variables.%swarmA Poly t is a universally quantified t5. The variables in the list are bound inside the t. For example, the type forall a. a -> a would be represented as Forall ["a"] (TyFun "a" "a").'swarmA UCtx is a mapping from variables to polytypes with unification variables. We generally have one of these while we are in the midst of the type inference process.(swarmA TCtx is a mapping from variables to polytypes. We generally get one of these at the end of the type inference process.)swarm) s are like */s, but also contain unification variables. ) is defined via  3, which is also a kind of fixed point (in fact, ) is the  free monad over +). Just as with *=, we provide a bunch of pattern synonyms for working with ) as if it were defined directly.*swarmType& is now defined as the fixed point of +?. It would be annoying to manually apply and match against   constructors everywhere, so we provide pattern synonyms that allow us to work with *3 as if it were defined in a directly recursive way.+swarmA "structure functor" encoding the shape of type expressions. Actual types are then represented by taking a fixed point of this functor. We represent types in this way, via a "two-level type", so that we can work with the unification-fd package (see  https://byorgey.wordpress.com/2021/09/08/implementing-hindley-milner-with-the-unification-fd-library/).,swarm A base type.-swarmA type variable..swarmCommands, with return type. Note that commands form a monad./swarmType of delayed computations.0swarm Sum type.1swarm Product type.2swarmFunction type.3swarm Base types.4swarm#The void type, with no inhabitants.5swarm(The unit type, with a single inhabitant.6swarm Signed, arbitrary-size integers.7swarmUnicode strings.8swarm Directions.9swarm Booleans.:swarmRobots.Xswarm*Get all the type variables contained in a *.Yswarm A generic fold for things defined via   (including, in particular, )$). This probably belongs in the unification-fd package, but since it doesn't provide one, we define it here.Zswarm(A quick-and-dirty method for turning an   (used internally as a unification variable) into a unique variable name, by appending a number to the given name.[swarmThe trivial module for a given s, with the empty context.\swarm!For convenience, so we can write e.g. "a" instead of  TyVar "a".^swarmA  instance can be lifted through any functor (including, in particular,  and %)._swarm* is an instance of , with associated type ). !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[3456789:+,-./012*XWVUTSRQPONMLKJ)IHGFEDCBA@?>= indicates whether the definition is known to be recursive.swarm)A monadic bind for commands, of the form c1 ; c2 or  x <- c1; c2.swarm$Delay evaluation of a term, written {...}>. Swarm is an eager language, but in some cases (e.g. for if statements and recursive bindings) we need to delay evaluation. The counterpart to {...} is force, where  force {t} = t. Note that  is just a constant, whereas  has to be a special syntactic form so its argument can get special treatment during evaluation.swarmCOMPLETE pragma tells GHC using this set of pattern is complete for Term4Different runtime behaviors for delayed expressions.swarm1A simple delay, implemented via a (non-memoized) VDelay# holding the delayed expression.swarmA memoized delay, implemented by allocating a mutable cell with the delayed expression and returning a reference to it. When the  Maybe Var is Just, a recursive binding of the variable with a reference to the delayed expression will be provided while evaluating the delayed expression itself. Note that there is no surface syntax for binding a variable within a recursive delayed expression; the only way we can get Just here is when we automatically generate a delayed expression while interpreting a recursive let or def.swarm#The surface syntax for the language swarmThe length of a tangible command. Short commands take exactly one tick to execute. Long commands may require multiple ticks. swarmWhether a command is tangible or not. Tangible commands have some kind of effect on the external world; at most one tangible command can be executed per tick. Intangible commands are things like sensing commands, or commands that solely modify a robot's internal state; multiple intangible commands may be executed per tick. In addition, tangible commands can have a   (either   or  ) indicating whether they require only one, or possibly more than one, tick to execute. Long commands are excluded from atomic# blocks to avoid freezing the game.swarm;The meta type representing associativity of unary operator.swarmPrefix unary operator (see -.)swarmSuffix unary operator (see -/)swarmNote: This is used for documentation purposes and complements  and 2 in that exactly one will accept a given constant.swarmWhether the constant is a tangible command, that has an external effect on the world. At most one tangible command may be executed per tick.swarmWhether the constant is a long command, that is, a tangible command which could require multiple ticks to execute. Such commands cannot be allowed in atomic blocks.swarmInformation about constants used in parsing and pretty printing.It would be more compact to represent the information by testing whether the constants are in certain sets, but using pattern matching gives us warning if we add more constants.swarmAlso used to color messages, so water is special and excluded.swarmThe default robot attribute.swarm3Some defined attribute names used in the Swarm TUI.swarm3Some defined attribute names used in the Swarm TUI.swarm3Some defined attribute names used in the Swarm TUI.swarm3Some defined attribute names used in the Swarm TUI.swarm3Some defined attribute names used in the Swarm TUI.swarm3Some defined attribute names used in the Swarm TUI.swarmSome basic colors used in TUI.swarmSome basic colors used in TUI.swarmSome basic colors used in TUI.swarmSome basic colors used in TUI.swarmSome basic colors used in TUI.  Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred*5689:;=swarmLabels for a rectangular border, with optional left, middle, and right labels on the top and bottom.swarmLabels for a horizontal border, with optional left, middle, and right labels.swarm)A plain horizontal border with no labels.swarm*A plain rectangular border with no labels.swarmDraw a horizontal border with three optional labels. The left label (if present) will be placed two units away from the left end of the border, and the right label will be placed two units away from the right end. The center label, if present, will always be centered in the border overall, regardless of the width of the left and right labels. This ensures that when the labels change width, they do not cause the other labels to wiggle.swarmPut a rectangular border around the specified widget with the specified label widgets placed around the border.    Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred*5689:;= swarmA  is a pair of a  and a .swarmShould we include or exclude the current location in the search?swarmWhich direction to search: forward or backward from the current location.swarmHandle a list event, taking an extra predicate to identify which list elements are separators; separators will be skipped if possible.swarm%Some convenient synonyms for various  values.swarm%Some convenient synonyms for various  values.swarm%Some convenient synonyms for various  values.swarm%Some convenient synonyms for various  values.swarmStarting from the currently selected element, attempt to find and select the next element matching the predicate. How the search proceeds depends on the : the  says whether to search forward or backward from the selected element, and the  says whether the currently selected element should be included in the search or not.swarmIs this element a separator?  Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred*5689:;=swarmCreate a panel.swarm2Border attribute to use when the panel is focused.swarm'Focus ring the panel should be part of.swarm&The name of the panel. Must be unique.swarm$The labels to use around the border.swarmThe content of the panel.  Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred"*5689:;=swarm&A convenient infix flipped version of : Just a ? b = a, and Nothing ? b = b . It can also be chained, as in x ? y ? z ? def), which takes the value inside the first Just, defaulting to def as a last resort.swarmFind the maximum of two values, comparing them according to a custom projection function.swarmFind the maximum of a list of numbers, defaulting to 0 if the list is empty.swarmTake the successor of an 2 type, wrapping around when it reaches the end.swarm7Drop repeated elements that are adjacent to each other.uniq [][] uniq [1..5] [1,2,3,4,5]uniq (replicate 10 'a')"a"uniq "abbbccd""abcd"swarm+Manhattan distance between world locations.swarm:Get elements that are in manhattan distance from location.v2s i = [(v, manhattan (V2 0 0) v) | x <- [-i..i], y <- [-i..i], let v = V2 x y]v2s 0 [(V2 0 0,0)]map (\i -> length (getElemsInArea (V2 0 0) i (M.fromList $ v2s i))) [0..8][1,5,13,25,41,61,85,113,145]:The last test is the sequence "Centered square numbers": https://oeis.org/A001844swarmSafely attempt to read a file.swarm,Safely attempt to (efficiently) read a file.swarm Turns any IO error into Nothing.swarmGet path to swarm data, optionally creating necessary directories.swarmGet path to swarm saves, optionally creating necessary directories.swarmGet path to swarm history, optionally creating necessary directories. This could fail if user has bad permissions on his own $HOME or $XDG_DATA_HOME which is unlikely.swarm/Read all the .txt files in the data/ directory.swarmPredicate to test for characters which can be part of a valid identifier: alphanumeric, underscore, or single quote.5isIdentChar 'A' && isIdentChar 'b' && isIdentChar '9'True#isIdentChar '_' && isIdentChar '\''True5isIdentChar '$' || isIdentChar '.' || isIdentChar ' 'FalseswarmreplaceLast r t replaces the last word of t with r.:set -XOverloadedStrings replaceLast "foo" "bar baz quux" "bar baz foo"replaceLast "move" "(make""(move"swarm;Reflow text by removing newlines and condensing whitespace.swarmPrepend a noun with the proper indefinite article ("a" or "an").swarmPrepend a noun with the proper indefinite article, and surround the noun in single quotes.swarmCombine the subject word with the simple present tense of the verb.Only some irregular verbs are handled, but it should be enough to scrap some error message boilerplate and have fun!:set -XOverloadedStringssingularSubjectVerb "I" "be""I am"singularSubjectVerb "he" "can""he can"+singularSubjectVerb "The target robot" "do""The target robot does"swarmPluralize a noun.swarmEither pluralize a noun or not, depending on the value of the number.swarm$Surround some text in single quotes.swarm$Surround some text in double quotes.swarm5Make a list of things with commas and the word "and".swarm Require that a Boolean value is True, or throw an exception.swarmRequire that a  value is , or throw an exception.swarmRequire that an  value is 5, or throw an exception based on the value in the .swarmRequire that a  value is 5, or throw an exception based on the value in the .swarmGiven a list of nonempty sets, find a hitting set, that is, a set which has at least one element in common with each set in the list. It is not guaranteed to be the smallest possible such set, because that is NP-hard. Instead, we use a greedy algorithm that will give us a reasonably small hitting set: first, choose all elements in singleton sets, since those must necessarily be chosen. Now take any sets which are still not hit, and find an element which occurs in the largest possible number of remaining sets. Add this element to the set of chosen elements, and filter out all the sets it hits. Repeat, choosing a new element to hit the largest number of unhit sets at each step, until all sets are hit. This algorithm produces a hitting set which might be larger than optimal by a factor of lg(m), where m is the number of sets in the input.import qualified Data.Set as S&shs = smallHittingSet . map S.fromList shs ["a"] fromList "a"shs ["ab", "b"] fromList "b"shs ["ab", "bc"] fromList "b"shs ["acd", "c", "aef", "a"] fromList "ac" shs ["abc", "abd", "acd", "bcd"] fromList "cd")Here is an example of an input for which smallHittingSet does not produce a minimal hitting set. "bc" is also a hitting set and is smaller. b, c, and d all occur in exactly two sets, but d is unluckily chosen first, leaving "be" and "ac" unhit and necessitating choosing one more element from each.shs ["bd", "be", "ac", "cd"]fromList "cde"''144444 Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred*5689:;=7swarmA quasiquoter for Swarm polytypes, so we can conveniently write them down using concrete syntax and have them parsed into abstract syntax at compile time. This is used, for example, in writing down the concrete types of constants (see Swarm.Language.Typecheck). Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred"*5689:;=Դ'swarmVarious reasons the body of an atomic might be invalid.swarm,The arugment has too many tangible commands.swarm.The argument uses some way to duplicate code: def, let , or lambda.swarm;The argument referred to a variable with a non-simple type.swarmThe argument had a nested atomicswarm%The argument contained a long commandswarmErrors that can occur during type checking. The idea is that each error carries information that can be used to help explain what went wrong (though the amount of information carried can and should be very much improved in the future); errors can then separately be pretty-printed to display them to the user.swarm&An undefined variable was encountered.swarm,A Skolem variable escaped its local context.swarmThe given term was expected to have a certain type, but has a different type instead.swarm2A definition was encountered not at the top level.swarmA term was encountered which we cannot infer the type of. This should never happen.swarm$An invalid argument was provided to atomic.swarmunification-fd provides a function  which fully substitutes for any bound unification variables (for efficiency, it does not perform such substitution as it goes along). The  class is for anything which has unification variables in it and to which we can usefully apply .swarm>A class for getting the free unification variables of a thing.swarm-The concrete monad used for type inference. + is a monad transformer provided by the unification-fd library which supports various operations such as generating fresh variables and unifying things.swarm=Run a top-level inference computation, returning either a  or a fully resolved .swarmLook up a variable in the ambient type context, either throwing an 8 error if it is not found, or opening its associated #) with fresh unification variables via .swarm&Generate a fresh unification variable.swarmPerform a substitution over a ), substituting for both type and unification variables. Note that since )s do not have any binding constructs, we don't have to worry about ignoring bound variables; all variables in a ) are free.swarm Constrain two types to be equal.swarmTo  a #, we generate a fresh unification variable for each variable bound by the &2, and then substitute them throughout the type.swarm is like  , except we substitute fresh type variables instead of unification variables. Such variables cannot unify with anything other than themselves. This is used when checking something with a polytype explicitly specified by the user.swarm is the opposite of : add a &> which closes over all free type and unification variables.swarmTop-level type inference function: given a context of definition types and a top-level term, either return a type error or its type as a .swarmInfer the signature of a top-level expression which might contain definitions.swarmPretty-print a thing, with a context precedence level of zero.swarm(Pretty-print something and render it as Text.swarm*Pretty-print something and render it as a String.swarmOptionally surround a document with parentheses depending on the Bool argument.   Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred)*5689:;=swarm:An environment is a mapping from variable names to values.swarmA value is a term that cannot (or does not) take any more evaluation steps on its own.swarmThe unit value.swarm An integer.swarm Literal text.swarm A direction.swarm A boolean.swarmA reference to a robot.swarm:An injection into a sum type. False = left, True = right.swarmA pair.swarmA closure, representing a lambda term along with an environment containing bindings for any free variables in the body of the lambda.swarmAn application of a constant to some value arguments, potentially waiting for more arguments. If a constant application is fully saturated (as defined by its ), whether it is a value or not depends on whether or not it represents a command (as defined by ). If a command (e.g.  ), it is a value, and awaits an 6; frame which will cause it to execute. Otherwise (e.g. 5), it is not a value, and will immediately reduce.swarmA definition, which does not take effect until executed. The Bool/ indicates whether the definition is recursive.swarmThe result of a command, consisting of the result of the command as well as an environment of bindings from  commands.swarmAn unevaluated bind expression, waiting to be executed, of the form i.e. c1 ; c2 or  x <- c1; c2. We also store an ' in which to interpret the commands.swarmA (non-recursive) delayed term, along with its environment. If a term would otherwise be evaluated but we don't want it to be (e.g.# as in the case of arguments to an 'if'-, or a recursive binding), we can stick a  on it, which turns it into a value. Delayed terms won't be evaluated until  is applied to them.swarm*A reference to a memory cell in the store.swarmPretty-print a value.swarm Inject a value back into a term. Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred"*5689:;=swarmA record containing the results of the language processing pipeline. Put a  in, and get one of these out.swarmGiven a  $ value representing a Swarm program, Parse it (see Swarm.Language.Parse)Typecheck it (see Swarm.Language.Typecheck)Elaborate it (see Swarm.Language.Elaborate))Check what capabilities it requires (see Swarm.Language.Capability)!Return either the end result (or Nothing if the input was only whitespace) or a pretty-printed error message.swarmLike ., but use a term that has already been parsed.swarmLike %, but use explicit starting contexts.swarmLike ., but use a term that has already been parsed.swarmThe elaborated termswarm6The type of the term (and of any embedded definitions)swarmRequirements of the termswarm;Capability context for any definitions embedded in the term Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred*5689:;=swarmA quasiquoter for Swarm language terms, so we can conveniently write them down using concrete syntax and have them parsed into abstract syntax at compile time. The quasiquoter actually runs the entire pipeline on them (parsing, typechecking, elaborating), so a quasiquoted Swarm program with a parse error or a type error will fail at Haskell compile time. This is useful for creating system robot programs (for example, see #7). Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred"*5689:;= Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred*5689:;=[swarmA  consists of a  that specifies the initial world, a cache of loaded square tiles to make lookups faster, and a map storing locations whose entities have changed from their initial values.Right now the  simply holds on to all the tiles it has ever loaded. Ideally it would use some kind of LRU caching scheme to keep memory usage bounded, but it would be a bit tricky, and in any case it's probably not going to matter much for a while. Once tile loads can trigger robots to spawn, it would also make for some difficult decisions in terms of how to handle respawning.swarmAn entity tile is an array of possible entity values. Note it cannot be an unboxed array since entities are complex records which have to be boxed.swarm5A terrain tile is an unboxed array of terrain values.swarmA  represents an offset from the upper-left corner of some tile to a cell in its interior.swarm&If we think of the world as a grid of tiles, we can assign each tile some coordinates in the same way we would if each tile was a single cell. These are the tile coordinates.swarmA  WorldFun t e, represents a 2D world with terrain of type t. (exactly one per cell) and entities of type e (at most one per cell).swarmWorld coordinates use (row,column) format, with the row increasing as we move down the screen. This format plays nicely with drawing the screen.swarmConvert an (x,y) location to a  value.swarmConvert  to an (x,y) location.swarmCreate a world function from a finite array of specified cells plus a single default cell to use everywhere else.swarmThe number of bits we need in each coordinate to represent all the locations in a tile. In other words, each tile has a size of 2^tileBits x 2^tileBits. Currently,  is set to 6, giving us 64x64 tiles, with 4096 cells in each tile. That seems intuitively like a good size, but I don't have a good sense for the tradeoffs here, and I don't know how much the choice of tile size matters.swarmThe number consisting of  many 1 bits. We can use this to mask out the tile offset of a coordinate.swarmConvert from a cell's coordinates to the coordinates of its tile, simply by shifting out  many bits.swarm8Find the coordinates of the upper-left corner of a tile.swarmThe offsets of the upper-left and lower-right corners of a tile: (0,0) to (, ).swarm9Compute the offset of a given coordinate within its tile.swarmAdd a tile offset to the coordinates of the tile's upper left corner. NOTE that for efficiency, this function only works when the first argument is in fact the coordinates of a tile's upper-left corner (i.e. it is an output of ). In that case the coordinates will end with all 0 bits, and we can add the tile offset just by doing a coordinatewise .swarm Create a new  from a .swarmCreate a new empty 0 consisting of nothing but the given terrain.swarmLook up the terrain value at certain coordinates: try looking it up in the tile cache first, and fall back to running the  otherwise.This function does not ensure that the tile containing the given coordinates is loaded. For that, see .swarmA stateful variant of , which first loads the tile containing the given coordinates if it is not already loaded, then looks up the terrain value.swarmLook up the entity at certain coordinates: first, see if it is in the map of locations with changed entities; then try looking it up in the tile cache first; and finally fall back to running the .This function does not ensure that the tile containing the given coordinates is loaded. For that, see .swarmA stateful variant of , which first loads the tile containing the given coordinates if it is not already loaded, then looks up the terrain value.swarmUpdate the entity (or absence thereof) at a certain location, returning an updated  . See also .swarmA stateful variant of , which also ensures the tile containing the given coordinates is loaded.swarm)Load the tile containing a specific cell.swarmLoad all the tiles which overlap the given rectangular region (specified as an upper-left and lower-right corner). Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred*5689:;<=?swarm governs values that can be parsed from a YAML (or JSON) file, but which also have access to an extra, read-only environment value.For things that don't care about the environment, the default implementation of  simply calls  from a  instance.swarmA  is a YAML 5 that can also depend on knowing an value of type e. The E used to stand for  EntityMap?, but now that it is generalized, it stands for Environment.swarmA generic wrapper for computations which also depend on knowing a value of type e.swarmLift a computation that does not care about the environment value.swarmLocally modify an environment.swarmLocally merge an environment with the current one for given action.swarmGet the current environment.swarmRead a value from a YAML file, providing the needed extra environment.swarm A variant of  for : project out a field of an &, passing along the extra environment.swarm A variant of  for ): project out an optional field of an &, passing along the extra environment.swarm A variant of  for any functor.swarm name f value applies f to the   when value is a String and fails otherwise.swarm name f value applies f to the  when value is an  and fails otherwise.swarm name f value applies f to the  when value is an  and fails otherwise. Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred"*5689:;=fswarm8A record explaining how to display an entity in the TUI.swarmDisplay priority. Entities with higher priority will be drawn on top of entities with lower priority.swarmThe display caches the current orientation of the entity, so we know which character to use from the orientation map.swarm)The default character to use for display.swarm!The attribute to use for display.swarmThis entity's display priority. Higher priorities are drawn on top of lower.swarm*Whether the entity is currently invisible.swarmFor robots or other entities that have an orientation, this map optionally associates different display characters with different orientations. If an orientation is not in the map, the  will be used.swarm8Look up the character that should be used for a display.swarm Render a display as a UI widget.swarmModify a display to use a ?3 character for entities that are hidden/unknown.swarmThe default way to display some terrain using the given character and attribute, with priority 0.swarmConstruct a default display for an entity that uses only a single display character, the default entity attribute, and priority 1.swarmConstruct a default robot display for a given orientation, with display characters "X^>v<"2, the default robot attribute, and priority 10.Note that the  is used for direction 0 and is overriden for the special base robot. Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred*5689:;= swarmThe different possible types of terrain. Unlike entities and robots, these are hard-coded into the game.swarmA map containing a  record for each different . Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred"*5689:;=-2swarmAn inventory is really just a bag/multiset of entities. That is, it contains some entities, along with the number of times each occurs. Entities can be looked up directly, or by name.swarm*A convenient synonym to remind us when an  is supposed to represent how many of something we have.swarmAn  is a data structure containing all the loaded entities, allowing them to be looked up either by name or by what capabilities they provide (if any).swarm-A record to hold information about an entity.The constructor for  is intentionally not exported. To construct one manually, use the  function.>There are two main constraints on the way entities are stored: We want to be able to easily modify an entity in one particular cell of the world (for example, painting one tree red).In an inventory, we want to store identical entities only once, along with a count.We could get (2) nicely by storing only names of entities, and having a global lookup table from names to entity records. However, storing names instead of actual entity records in the world makes (1) more complex: every time we modify an entity we would have to generate a fresh name for the modified entity and add it to the global entity table. This approach is also annoying because it means we can't just uses lenses to drill down into the properties of an entity in the world or in an inventory, but have to do an intermediate lookup in the global (mutable!) entity table.On the other hand, if we just store entity records everywhere, checking them for equality becomes expensive. Having an inventory be a map with entities themselves as keys sounds awful.)The solution we adopt here is that every Entity record carries along a hash value of all the other fields. We just assume that these hashes are unique (a collision is of course possible but extremely unlikely). Entities can be efficiently compared just by looking at their hashes; they can be stored in a map using hash values as keys; and we provide lenses which automatically recompute the hash value when modifying a field of an entity record. Note also that world storage is still efficient, too: thanks to referential transparency, in practice most of the entities stored in the world that are the same will literally just be stored as pointers to the same shared record.swarm+A hash value computed from the other fieldsswarm9The way this entity should be displayed on the world map.swarmThe name of the entity, used e.g. in an inventory display.swarmThe plural of the entity name, in case it is irregular. If this field is Nothing8, default pluralization heuristics will be used (see ).swarm A longer-form description. Each   value is one paragraph.swarmThe entity's orientation (if it has one). For example, when a robot moves, it moves in the direction of its orientation.swarm,If this entity grows, how long does it take?swarmThe name of a different entity obtained when this entity is grabbed.swarmProperties of the entity.swarm%Capabilities provided by this entity.swarm0Inventory of other entities held by this entity.swarmHow long an entity takes to regrow. This represents the minimum and maximum amount of time taken by one growth stage (there are two stages). The actual time for each stage will be chosen uniformly at random between these two values.swarmVarious properties that an entity can have, which affect how robots can interact with it.swarm5Robots can't move onto a cell containing this entity.swarmRobots can pick this up (via 8 or 9).swarm*Regrows from a seed after it is harvested.swarm1Regenerates infinitely when grabbed or harvested.swarm1Robots drown if they walk on this without a boat.swarmRobots automatically know what this is without having to scan it.swarm!Recompute an entity's hash value.swarmCreate an entity with no orientation, an empty inventory, providing no capabilities (automatically filling in the hash value).swarm#Find an entity with the given name.swarmFind all entities which are devices that provide the given capability.swarm Build an  from a list of entities. The idea is that this will be called once at startup, when loading the entities from a file; see .swarm&Load entities from a data file called  entities.yaml, producing either an ! or a pretty-printed parse error.swarm>Make a lens for Entity that recomputes the hash after setting.swarmGet the hash of an entity. Note that this is a getter, not a lens; the Swarm.Game.Entity module carefully maintains some internal invariants ensuring that hashes work properly, and by golly, no one else is going to mess that up.swarmThe 9 explaining how to draw this entity in the world display.swarmThe name of the entity.swarmThe irregular plural version of the entity's name, if there is one.swarmGet a version of the entity's name appropriate to the number---the singular name for 1, and a plural name for any other number. The plural name is obtained either by looking it up if irregular, or by applying standard heuristics otherwise.swarm5A longer, free-form description of the entity. Each  ! value represents a paragraph.swarm4The direction this entity is facing (if it has one).swarm2How long this entity takes to grow, if it regrows.swarmThe name of a different entity yielded when this entity is grabbed, if any.swarm&The properties enjoyed by this entity.swarm.Test whether an entity has a certain property.swarm5The capabilities this entity provides when installed.swarm7The inventory of other entities carried by this entity.swarmLook up an entity in an inventory, returning the number of copies contained.swarmLook up an entity by name in an inventory, returning a list of matching entities. Note, if this returns some entities, it does *not* mean we necessarily have any in our inventory! It just means we *know about* them. If you want to know whether you have any, use  and see whether the resulting  is positive, or just use  in the first place.swarmLook up an entity by name and see how many there are in the inventory. If there are multiple entities with the same name, it just picks the first one returned from .swarmThe empty inventory.swarm*Create an inventory containing one entity.swarmInsert an entity into an inventory. If the inventory already contains this entity, then only its count will be incremented.swarm,Create an inventory from a list of entities.swarm=Create an inventory from a list of entities and their counts.swarmInsert a certain number of copies of an entity into an inventory. If the inventory already contains this entity, then only its count will be incremented.swarmCheck whether an inventory contains at least one of a given entity.swarmCheck whether an inventory has an entry for entity (used by robots).swarmCheck if the first inventory is a subset of the second. Note that entities with a count of 0 are ignored.swarmCheck whether an inventory is empty, meaning that it contains 0 total entities (although it may still  know about some entities, that is, have them as keys with a count of 0).swarmCompute the set of capabilities provided by the devices in an inventory.swarm;Delete a single copy of a certain entity from an inventory.swarmDelete a specified number of copies of an entity from an inventory.swarm8Delete all copies of a certain entity from an inventory.swarm=Get the entities in an inventory and their associated counts.swarmUnion two inventories.swarm-Subtract the second inventory from the first.swarm0Inventories are compared by hash for efficiency.swarm-Entities are compared by hash for efficiency.swarm-Entities are compared by hash for efficiency.swarmThe Hashable instance for Entity ignores the cached hash value and simply combines the other fields.swarmIf we have access to an !, we can parse the name of an ' as a string and look it up in the map.swarmDisplayswarm Entity nameswarmEntity descriptionswarm Propertiesswarm Capabilities77 Safe-Inferred"*5689:;=/*swarmAll non-alphabetic sort criteria perform alphabetic tie-breaking. "Reverse ordering" only applies to the *primary* sort criteria; the secondary alphabetic sort is always in ascending order. Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred"*5689:;=3 swarm>A simple test world used for a while during early development.swarm2A list of entities available in the initial world.swarmLook up an entity name in an entity map, when we know the entity must exist. This is only used for entities which are named in .swarmThe main world of the classic game, for historical reasons named 8. If new entities are added, you SHOULD ALSO UPDATE testWorld2Entities.swarmCreate a world function from a finite array of specified cells plus a seed to randomly generate the rest.swarm$Offset a world by a multiple of the skip8 in such a way that it satisfies the given predicate.swarmOffset the world so the base starts in a 32x32 patch containing at least one of each of a list of required entities.swarmOffset the world so the base starts on empty spot next to tree and grass.swarmOffset the world so the base starts in a good patch (near necessary items), next to a tree. Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred"*5689:;==swarmA recipe is just a list of input entities and a list of output entities (both with multiplicity). The idea is that it represents some kind of process where the inputs are transformed into the outputs.swarmAn ingredient list is a list of entities with multiplicity. It is polymorphic in the entity type so that we can use either entity names when serializing, or actual entity objects while the game is running.swarmThe inputs to a recipe.swarmThe outputs from a recipe.swarmOther entities which the recipe requires you to have, but which are not consumed by the recipe (e.g. a furnace).swarm%The time required to finish a recipe.swarmHow this recipe is weighted against other recipes. Any time there are multiple valid recipes that fit certain criteria, one of the recipes will be randomly chosen with probability proportional to its weight.swarm Given an $, turn a list of recipes containing names9 of entities into a list of recipes containing actual  records; or.swarmGiven an already loaded 6, try to load a list of recipes from the data file  recipes.yaml.swarm3Build a map of recipes either by inputs or outputs.swarm5Build a map of recipes indexed by output ingredients.swarm4Build a map of recipes indexed by input ingredients.swarm/Build a map of recipes indexed by requirements.swarmGet a list of all the recipes for the given entity. Look up an entity in either an  or  depending on whether you want to know recipes that consume or produce the given entity, respectively.swarmFigure out which ingredients (if any) are lacking from an inventory to be able to carry out the recipe. Requirements are not consumed and so can use installed.swarmFigure out if a recipe is available, but it can be lacking items.swarmTry to make a recipe, deleting the recipe's inputs from the inventory. Return either a description of which items are lacking, if the inventory does not contain sufficient inputs, or an inventory without inputs and function adding outputs if it was successful.swarm/Try to make a recipe, but do not insert it yet. Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred"*5689:;=F swarm.)A  saves the original  and  that are being evaluated; if Ctrl-C is used to cancel a computation while we are in the middle of evaluating a cell, the  can be reset to .swarm0Once evaluation is complete, we cache the final  in the , so that subsequent lookups can just use it without recomputing anything.swarm3 represents a store, indexing integer locations to s.swarm)A continuation is just a stack of frames.swarmA frame is a single component of a continuation stack, explaining what to do next after we finish evaluating the currently focused term.swarmWe were evaluating the first component of a pair; next, we should evaluate the second component which was saved in this frame (and push a 1 frame on the stack to save the first component).swarmWe were evaluating the second component of a pair; when done, we should combine it with the value of the first component saved in this frame to construct a fully evaluated pair.swarmFArg t e says that we were evaluating the left-hand side of an application, so the next thing we should do is evaluate the term t (the right-hand side, i.e.. argument of the application) in environment e. We will also push an  frame on the stack.swarmFApp v says that we were evaluating the right-hand side of an application; once we are done, we should pass the resulting value as an argument to v.swarm FLet x t2 e% says that we were evaluating a term t1 in an expression of the form let x = t1 in t21, that is, we were evaluating the definition of x+; the next thing we should do is evaluate t2 in the environment e extended with a binding for x.swarmWe are executing inside a  block. If an exception is raised, we will execute the stored term (the "catch" block).swarmWe were executing a command; next we should take any environment it returned and union it with this one to produce the result of a bind expression.swarmWe were executing a command that might have definitions; next we should take the resulting  and add it to the robot's :&, along with adding this accompanying  and  to the robot's ;.swarmWe were executing a definition; next we should take the resulting value and return a context binding the variable to the value.swarmAn FExec frame means the focused value is a command, which we should now execute.swarmWe are in the process of executing the first component of a bind; once done, we should also execute the second component in the given environment (extended by binding the variable, if there is one, to the output of the first command).swarm6Apply specific updates to the world and current robot.swarmUpdate the memory cell at a certain location with the computed value.swarm3Signal that we are done with an atomic computation.swarmAllocate a new memory cell containing an unevaluated expression with the current environment. Return the index of the allocated cell.swarm"Look up the cell at a given index.swarmSet the cell at a given index.swarmIs the CESK machine in a final (finished) state? If so, extract the final value and store.swarmInitialize a machine state with a starting term along with its type; the term will be executed or just evaluated depending on whether it has a command type or not.swarmLike 2, but also take an explicit starting continuation.swarm)Cancel the currently running computation.swarm Reset any  s in the . We need to use this any time a running computation is interrupted, either by an exception or by a Ctrl+C.swarmVery poor pretty-printing of CESK machine states, really just for debugging. At some point we should make a nicer version.swarm&Poor pretty-printing of continuations.swarmPoor pretty-printing of frames.-- Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred#"(*15689:;=5swarmA record that stores the information for all defintions stored in a  swarm$Map definition names to their types.swarmMap defintion names to the capabilities required to evaluate/execute them.swarmMap defintion names to their values. Note that since definitions are delayed, the values will just consist of s pointing into the store.swarmA store containing memory cells allocated to hold definitions.swarmAn entry in a robot's log.swarmThe time at which the entry was created. Note that this is the first field we sort on.swarm(Whether this log records a said message.swarm/The name of the robot that generated the entry.swarm-The ID of the robot that generated the entry.swarm,Location of the robot at log entry creation.swarmThe text of the log entry.swarmA value of type ? is a record representing the state of a single robot. The f parameter is for tracking whether or not the robot has been assigned a unique ID.swarmA cached view of the capabilities this robot has. Automatically generated from .swarm:Robot templates have no ID; concrete robots definitely do.swarmWith a robot template, we may or may not have a location. With a concrete robot we must have a location.swarm(The phase of a robot description record.swarmThe robot record has just been read in from a scenario description; it represents a template that may later be instantiated as one or more concrete robots.swarm:The robot record represents a concrete robot in the world.swarm A unique identifier for a robot. swarmA concrete robot, with a unique ID number and a specific location. swarmA template robot, i.e. a template robot record without a unique ID number, and possibly without a location. swarm&The robot's current CEK machine state. swarmThe robot's context swarmThe creation date of the robot. swarmRobots are not entities, but they have almost all the characteristics of one (or perhaps we could think of robots as very special sorts of entities), so for convenience each robot carries an  record to store all the information it has in common with any .Note there are various lenses provided for convenience that directly reference fields inside this record; for example, one can use   instead of writing   . . swarm?Is this robot extra heavy (thus requiring tank treads to move)? swarmThe (unique) ID number of the robot. This is only a Getter since the robot ID is immutable. swarmThe robot's current location, represented as (x,y). This is only a getter, since when changing a robot's location we must remember to update the robotsByLocation" map as well. You can use the updateRobotLocation function for this purpose. swarmHas the  3 been updated since the last time it was viewed? swarmThe ID number of the robot's parent, that is, the robot that built (or most recently reprogrammed) this robot, if there is one. swarm/Is the robot currently running an atomic block? swarm&Does this robot wish to self destruct? swarmIs this robot a "system robot"? System robots are generated by the system (as opposed to created by the user) and are not subject to the usual capability restrictions. swarm The need for   is a bit technical, and I hope I can eventually find a different, better way to accomplish it. Ideally, we would want each robot to execute a single command at every game tick, so that e.g. two robots executing move;move;move and  repeat 3 move$ (given a suitable definition of repeat) will move in lockstep. However, the second robot actually has to do more computation than the first (it has to look up the definition of repeat, reduce its application to the number 3, etc.), so its CESK machine will take more steps. It won't do to simply let each robot run until executing a command---because robot programs can involve arbitrary recursion, it is very easy to write a program that evaluates forever without ever executing a command, which in this scenario would completely freeze the UI. (It also wouldn't help to ensure all programs are terminating---it would still be possible to effectively do the same thing by making a program that takes a very, very long time to terminate.) So instead, we allocate each robot a certain maximum number of computation steps per tick (defined in #<), and it suspends computation when it either executes a command or reaches the maximum number of steps, whichever comes first.It seems like this really isn't something the robot should be keeping track of itself, but that seemed the most technically convenient way to do it at the time. The robot needs some way to signal when it has executed a command, which it currently does by setting tickSteps to zero. However, that has the disadvantage that when tickSteps becomes zero, we can't tell whether that happened because the robot ran out of steps, or because it executed a command and set it to zero manually.Perhaps instead, each robot should keep a counter saying how many commands it has executed. The loop stepping the robot can tell when the counter increments. swarmThe name of a robot. swarmThe name of a robot template. swarmThe  of a robot. This is a special lens that automatically sets the 8 to the orientation of the robot every time you do a get operation. Technically this does not satisfy the lens laws---in particular, the get/put law does not hold. But we should think of the  as being simply a cache of the displayed entity's direction. swarmSet a robot's location. This is unsafe and should never be called directly except by the updateRobotLocation: function. The reason is that we need to make sure the robotsByLocation map stays in sync. swarm%A template robot's location. Unlike  , this is a lens, since when dealing with robot templates there is as yet no robotsByLocation map to keep up-to-date. swarm(Which way the robot is currently facing. swarmThe robot's inventory. swarmInstantiate a robot template to make it into a concrete robot, by providing a robot ID. Concrete robots also require a location; if the robot template didn't have a location already, just set the location to (0,0) by default. If you want a different location, set it via   before calling  . swarmA separate inventory for "installed devices", which provide the robot with certain capabilities.Note that every time the inventory of installed devices is modified, this lens recomputes a cached set of the capabilities the installed devices provide, to speed up subsequent lookups to see whether the robot has a certain capability (see  ) swarmThe robot's own private message log, most recent message last. Messages can be added both by explicit use of the Log6 command, and by uncaught exceptions. Stored as a  Data.Sequence so that we can efficiently add to the end and also process from beginning to end. Note that updating via this lens will also set the  . swarmA hash of a robot's entity record and installed devices, to facilitate quickly deciding whether we need to redraw the robot info panel. swarm+Does a robot know of an entity's existence? swarmGet the set of capabilities this robot possesses. This is only a getter, not a lens, because it is automatically generated from the  . The only way to change a robot's capabilities is to modify its  . swarm'A general function for creating robots. swarm5Is the robot actively in the middle of a computation? swarm2The time until which the robot is waiting, if any. swarm >     Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred""%&*5689:;<=? swarmAn objective is a condition to be achieved by a player in a scenario. swarmA  8 contains all the information to describe a scenario. swarm1A description of a world parsed from a YAML file.swarm#A world palette maps characters to   values. swarmA single cell in a world map, which contains a terrain value, and optionally an entity and robot.swarmA map from names to robots, used to look up robots in scenario descriptions. swarmA robot template paired with its definition's index within the Scenario file swarmA winning condition for the objective, expressed as a program of type cmd bool. By default, this program will be run to completion every tick (the usual limits on the number of CESK steps per tick do not apply). swarmAn explanation of the goal of the objective, shown to the player during play. It is represented as a list of paragraphs.swarm Create a  from a list of robot templates.swarmLook up a thing by name, throwing a parse error if it is not found.swarm Look up an entity by name in an /, throwing a parse error if it is not found.swarmLook up a robot by name in a /, throwing a parse error if it is not found.swarmPaint a world map using a 8, turning it from a raw string into a nested list of   values by looking up each character in the palette, failing if any character in the raw map is not contained in the palette. swarmParse a tuple such as [grass, rock, base] into a  . The entity and robot, if present, are immediately looked up and converted into  and  : values. If they are not found, a parse error results. swarmThe author of the scenario. swarm3Whether the scenario should start in creative mode. swarm0A high-level description of the scenario, shown e.g. in the menu. swarm+Any custom entities used for this scenario. swarmList of entities that should be considered "known", so robots do not have to scan them. swarmThe name of the scenario. swarm3A sequence of objectives for the scenario (if any). swarm)Any custom recipes used in this scenario. swarmThe starting robots for the scenario. Note this should include the base. swarm3The seed used for the random number generator. If Nothing6, use a random seed / prompt the user for the seed. swarmAn optional solution of the scenario, expressed as a program of type cmd a?. This is useful for automated testing of the win condition. swarmOptionally, specify the maximum number of steps each robot may take during a single tick. swarmThe version number of the scenario schema. Currently, this should always be 1, but it is ignored. In the future, this may be used to convert older formats to newer ones, or simply to print a nice error message when we can't read an older format. swarm$The starting world for the scenario. swarmLoad a scenario with a given name from disk, given an entity map to use. This function is used if a specific scenario is requested on the command line. swarmLoad a scenario from a file." " ! Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred*5689:;=  swarmA  ScenarioInfo record stores metadata about a scenario: its canonical path, most recent status, and best-ever status. swarmA ScenarioStatus stores the status of a scenario along with appropriate metadata: not started, in progress, or complete. Note that "in progress" is currently a bit of a misnomer since games cannot be saved; at the moment it really means more like "you played this scenario before but didn't win". swarm7Time when the scenario was started including time zone. swarm)Time elapsed until quitting the scenario. swarm*Ticks elapsed until quitting the scenario. swarmA scenario collection is a tree of scenarios, keyed by name, together with an optional order. Invariant: every item in the scOrder exists as a key in the scMap. swarmA scenario item is either a specific scenario, or a collection of scenarios (*e.g.* the scenarios contained in a subdirectory). swarm8The best status of the scenario, measured in game ticks. swarm=The best status of the scenario, measured in real world time. swarm&The path of the scenario, relative to data/scenarios. swarmThe status of the scenario. swarmUpdate the current  ScenarioInfo record when quitting a game.Note that when comparing "best" times, shorter is not always better! As long as the scenario is not completed (e.g. some do not have win condition) we consider having fun _longer_ to be better. swarm%Retrieve the name of a scenario item. swarmAccess and modify ScenarioItems in collection based on their path. swarm?Canonicalize a scenario path, making it usable as a unique key. swarm:Convert a scenario collection to a list of scenario items. swarm9Load all the scenarios from the scenarios data directory.swarmThe name of the special file which indicates the order of scenarios in a folder.swarmRecursively load all scenarios from a particular directory, and also load the 00-ORDER file (if any) giving the order for the scenarios.swarm,How to transform scenario path to save path. swarm>Load saved info about played scenario from XDG data directory. swarm6Save info about played scenario to XDG data directory.swarmLoad a scenario item (either a scenario, or a subdirectory containing a collection of scenarios) from a particular path. % " Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred "%&(*5689:;= swarmThe   specifies how to determine the center of the world viewport. swarm4The view should be centered on an absolute position. swarm/The view should be centered on a certain robot. swarmThere is no winning condition. swarmThere are one or more objectives remaining that the player has not yet accomplished. swarmThe player has won. The boolean indicates whether they have already been congratulated. swarm8A data type to represent the current status of the REPL. swarmThe REPL is not doing anything actively at the moment. We persist the last value and its type though. swarm>A command entered at the REPL is currently being run. The $ represents the type of the expression that was entered. The  Maybe Value starts out as Nothing and gets filled in with a result once the command completes. swarmSequence of REPL inputs and outputs, oldest entry is leftmost.swarm9The index of the first entry since loading saved history.?It will be set on load and reset on save (happens during exit). swarm>Create new REPL history (i.e. from loaded history file lines). swarm=Point the start of REPL history after current last line. See . swarmCurrent number lines of the REPL history - (ab)used as index of input buffer. swarmAdd new REPL input - the index must have been pointing one past the last element already, so we increment it to keep it that way. swarmGet the latest N items in history, starting with the oldest one.This is used to show previous REPL lines in UI, so we need the items sorted in the order they were entered and will be drawn top to bottom. swarmGiven some text, removes the REPLEntry within REPLHistory which is equal to that. This is used when the user enters in search mode and want to traverse the history. If a command has been used many times, the history will be populated with it causing the effect that search command always finds the same command. swarm=Get the last REPLEntry in REPLHistory matching the given text swarmHistory of things the user has typed at the REPL, interleaved with outputs the system has generated. swarmThe last thing the user has typed which isn't part of the history. This is used to restore the repl form after the user visited the history. swarm5The prompt where the user can type input at the REPL. swarmThe way we interpret text typed by the player in the REPL prompt. swarmThe type of the current REPL input which should be displayed to the user (if any). swarm#Whether the prompt text is a valid Term. swarmConvinience lens to get text from editor and replace it with new one that has the provided text. swarmAn entry in the inventory list displayed in the info panel. We can either have an entity with a count in the robot's inventory, an entity installed on the robot, or a labelled separator. The purpose of the separators is to show a clear distinction between the robot's  inventory and its installed devices. swarmCreate a brick  of scenario items from a  . swarmGiven a   and a  which is the canonical path to some folder or scenario, construct a  1 stack focused on the given item, if possible. swarmThe main record holding the UI state. For access to the fields, see the lenses below. swarm:The amount of accumulated real time. Every time we get a   event, we accumulate the amount of real time that happened since the last frame, then attempt to take an appropriate number of ticks to "catch up", based on the target tick rate.See  1https://gafferongames.com/post/fix_your_timestep/ . swarmFree-form data loaded from the data directory, for things like the logo, about page, tutorial story, etc. swarmA counter used to track how many frames have been rendered since the last time we updated the ticks/frame statistics. swarmA counter used to track how many ticks have happened in the current frame, so we can stop when we get to the tick cap. swarmThe time of the last   event. swarm'The time of the last info widget update swarmThe currently active Scenario description, useful for starting over. swarmA counter used to track how many ticks have happened since the last time we updated the ticks/frame statistics. swarmCheat mode, i.e. are we allowed to turn creative mode on and off? swarm When this is Just, it represents a popup box containing an error message that is shown on top of the rest of the UI. swarm!Computed frames per milli seconds swarmThe focus ring is the set of UI panels we can cycle among using the Tab key. swarmStatus of the scenario goal: whether there is one, and whether it has been displayed to the user initially. swarmHide robots on the world map. swarmThe hash value of the focused robot entity (so we can tell if its inventory changed) along with a list of the items in the focused robot's inventory. swarm,Whether the Inventory ui panel should update swarm2The order and direction of sorting inventory list. swarmThe current menu state. swarm When this is Just, it represents a modal to be displayed on top of the UI, e.g. for the Help screen. swarmDoes the info panel contain more content past the bottom of the panel? swarmDoes the info panel contain more content past the top of the panel? swarmAre we currently playing the game? True = we are playing, and should thus display a world, REPL, etc.; False = we should display the current menu. swarmThe state of REPL panel. swarmA flag telling the UI to scroll the info panel to the very end (used when a new log message is appended). swarm%A toggle to show the FPS by pressing f swarmA toggle to show or hide inventory items with count 0 by pressing `0` swarm Computed ticks per milli seconds swarm,The last clicked position on the world view. swarm0Whether to show or hide robots on the world map. swarmThe base-2 logarithm of the current game speed in ticks/second. Note that we cap this value to the range of +/- log2 INTMAX. swarmThe  ' just stores together the other states.This is so you can use a smaller state when e.g. writing some game logic or updating the UI. Also consider that GameState can change when loading a new scenario - if the state should persist games, use RuntimeState. swarmA log of runtime events.This logging is separate from the logging done during game-play. If some error happens before a game is even selected, this is the place to log it. swarmThe upstream release version. swarm4The port on which the HTTP debug service is running. swarm$Simply log to the runtime event log. swarm-Command-line options for configuring the app. swarm!Explicit seed chosen by the user. swarm Scenario the user wants to play. swarmCode to be run on base. swarm;Automatically run the solution defined in the scenario file swarmShould cheat mode be enabled? swarm)Explicit port on which to run the web API swarm>Information about the Git repository (not present in release). swarmThe   record. swarmThe   record swarmThe   record. swarmGet the currently focused  ' from the robot info panel (if any). swarmGet the currently focused entity from the robot info panel (if any). This is just like   but forgets the distinction between plain inventory items and installed devices. swarm$The initial state of the focus ring. swarmThe initial tick speed. swarmInitialize the UI state. This needs to be in the IO monad since it involves reading a REPL history file, getting the current time, and loading text files from the data directory. The Bool parameter indicates whether we should start off by showing the main menu. swarmGiven the focused robot, populate the UI inventory list in the info panel with information about its inventory. swarmInitialize the  . swarmLoad a Scenario and start playing the game. swarmRe-initialize the game from the stored reference to the current scenario.Note that "restarting" is intended only for "scenarios"; with some scenarios, it may be possible to get stuck so that it is either impossible or very annoying to win, so being offered an option to restart is more user-friendly.Since scenarios are stored as a Maybe in the UI state, we handle the Nothing case upstream so that the Scenario passed to this function definitely exists.swarmLoad a Scenario and start playing the game, with the possibility for the user to override the seed. swarmExtract the scenario which would come next in the menu from the currently selected scenario (if any). Can return Nothing if either we are not in the  NewGameMenu<, or the current scenario is the last among its siblings. swarmContext for the REPL commands to execute in. Contains the base robot context plus the it variable that refer to the previously computed values. (Note that `it{n}` variables are set in the base robot context; we only set it here because it's so transient) swarm Modify the  , appropriately when starting a new scenario.swarm?Modify the UI state appropriately when starting a new scenario.   ' Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred"*5689:;=#% swarmThe main entry point for drawing the entire UI. Figures out which menu screen we should show (if any), or just the game itself.swarmDraw the main game UI. Generates a list of widgets, where each represents a layer. Right now we just generate two layers: the main layer and a layer for a floating dialog that can be on top.swarmFormat the clock display to be shown in the upper right of the world panel.swarmCheck whether the currently focused robot (if any) has a clock device installed.swarm,Format a ticks count as a hexadecimal clock.swarmReturn a possible time display, if the currently focused robot has a clock device installed. The first argument is the number of ticks (e.g. 943 = 0x3af), and the second argument indicates whether the time should be shown down to single-tick resolution (e.g. 0:00:3a.f) or not (e.g. 0:00:3a).swarmRender the type of the current REPL input to be shown to the user. swarm7Draw info about the current number of ticks per second.swarmThe height of the REPL box. Perhaps in the future this should be configurable. swarm#Hide the cursor when a modal is setswarm-Width cap for modal and error message windowsswarm9Render the error dialog window with a given error message swarmDraw the error dialog window, if it should be displayed right now.swarmMake a widget scrolling if it is bigger than the available vertical space. Thanks to jtdaugherty for this code.swarm.Draw one of the various types of modal dialog. swarm4Generate a fresh modal window of the requested type.swarm*Get the name of the current New Game menu.swarmGenerate a pop-up widget to display the description of an entity.swarm1Draw a widget with messages to the current robot. swarmDraw the F-key modal menu. This is displayed in the top left world corner. swarmDraw a menu explaining what key commands are available for the current panel. This menu is displayed as a single line in between the world panel and the REPL.8This excludes the F-key modals that are shown elsewhere. swarm&Draw a single key command in the menu. swarmDraw the current world view.swarm Render the  for a specific location.swarmGet the . for a specific location, by combining the 6s for the terrain, entity, and robots at the location. swarmDraw info about the currently focused robot, such as its name, position, orientation, and inventory. swarmDraw an inventory entry. swarmDraw the name of an entity, labelled with its visual representation as a cell in the world. swarmDraw the info panel in the bottom-left corner, which shows info about the currently focused inventory item. swarmDisplay info about the currently focused inventory entity, such as its description and relevant recipes.swarm/Return all recipes that involve a given entity.swarmDraw an ASCII art representation of a recipe. For now, the weight is not shown.swarm=Ad-hoc entity to represent time - only used in recipe drawingswarm5Draw one log entry with an optional robot name first.swarm2Turn the repl prompt into a decorator for the form swarmDraw the REPL.swarmDisplay a list of text-wrapped paragraphs with one blank line after each. swarm3The index of the currently selected inventory entryswarm%The index of the entry we are drawingswarmWhether this entry is selected; we can ignore this because it will automatically have a special attribute applied to it.swarmThe entry to draw.  ( Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred"*5689:;=1 swarm0Pattern synonyms to simplify brick event handler swarm(The top-level event handler for the TUI.swarm$The event handler for the main menu.swarmIf we are in a New Game menu, advance the menu to the next item in order.swarmThe top-level event handler while we are running the game itself.swarmSet the game to Running if it was (auto) paused otherwise to paused.Also resets the last frame time to now. If we are pausing, it doesn't matter; if we are unpausing, this is critical to ensure the next frame doesn't think it has to catch up from whenever the game was paused!swarm2Only unpause the game if leaving autopaused modal.Note that the game could have been paused before opening the modal, in that case, leave the game paused.swarm-The running modals do not autopause the game.swarm Write the  ScenarioInfo! out to disk when exiting a game. swarm Quit a game.)writes out the updated REPL history to a .swarm_history file4saves current scenario status (InProgress/Completed)returns to the previous menu swarmRun the game for a single frame (i.e. screen redraw), then update the UI. Depending on how long it is taking to draw each frame, and how many ticks per second we are trying to achieve, this may involve stepping the game any number of ticks (including zero). swarm9Run the game for a single frame, without updating the UI. swarmDo zero or more ticks, with each tick notionally taking the given timestep, until we have used up all available accumulated time, OR until we have hit the cap on ticks per frame, whichever comes first. swarm2Run the game for a single tick, and update the UI.swarm:Modifies the game state using a fused-effect state action. swarm Run the game for a single tick (without updating the UI). Every robot is given a certain amount of maximum computation to perform a single world action (like moving, turning, grabbing, etc.). swarmUpdate the UI. This function is used after running the game for some number of ticks.swarmMake sure all tiles covering the visible part of the world are loaded.swarmStrips top-level cmd from type (in case of REPL evaluation), and returns a boolean to indicate if it happenedswarmSet the REPLForm to the given value, resetting type error checks to Nothing and removing uiError. swarm'Handle a user input event for the REPL.swarmTry to complete the last word in a partially-entered REPL prompt using reserved words and names in scope (in the case of function names) or entity names (in the case of string literals). swarmValidate the REPL input when it changes: see if it parses and typechecks, and set the color accordingly. swarm0Update our current position in the REPL history. swarm2Handle a user input event in the world view panel. swarmManually scroll the world view. swarm+Convert a directional key into a direction. swarm"Adjust the ticks per second speed.swarm,Handle user input events in the robot panel.swarmAttempt to make an entity selected from the inventory, if the base is not currently busy.swarm9Display a modal window with the description of an entity. swarm6Handle user events in the info panel (just scrolling).  ) Safe-Inferred*15689:;=4 swarmAttempt to start a web thread on the requested port, or a default one if none is requested (or don't start a web thread if the requested port is 0). If an explicit port was requested, fail if startup doesn't work. Otherwise, ignore the failure. In any case, return a  Maybe Port value representing whether a web server is actually running, and if so, what port it is on.  * Brent Yorgey BSD-3-Clausebyorgey@gmail.com Safe-Inferred"*5689:;=6_ swarm&The definition of the app used by the brick library. swarm The main IO computation which initializes the state, sets up some communication channels, and runs the UI. swarmA demo program to run the web service directly, without the terminal application. This is useful to live update the code using `ghcid -W --test "Swarm.App.demoWeb"` swarmIf available for the terminal emulator, enable bracketed paste mode.  >>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~89,B                                                                                            C3CABDG6                                                                           ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #7# # # # # # # # # # # # # # # # # # # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % % % % % % % % % % % & & & & & & & & & & & & & & & & & & & && & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ) ) ) ) ) * * * * * + + + + + + + +                              !!!!""$$$$$$&&&''''''''''''''''''''''(((((=((((((((((($swarm-0.2.0.0-D1mAmWsUEjoFqpCaq9DHG0Swarm.Language.ContextSwarm.Language.TypesSwarm.Language.SyntaxSwarm.Language.ElaborateSwarm.Language.CapabilitySwarm.Language.RequirementSwarm.Language.TypedSwarm.Language.ParseSwarm.TUI.AttrSwarm.TUI.BorderSwarm.TUI.ListSwarm.TUI.Panel Swarm.UtilSwarm.Language.Parse.QQSwarm.Language.TypecheckSwarm.Language.PrettySwarm.Game.ValueSwarm.Language.PipelineSwarm.Language.Pipeline.QQSwarm.Language.LSPSwarm.Game.WorldSwarm.Util.YamlSwarm.Game.DisplaySwarm.Game.TerrainSwarm.Game.EntitySwarm.TUI.Inventory.SortingSwarm.Game.WorldGenSwarm.Game.RecipeSwarm.Game.ExceptionSwarm.Game.CESKSwarm.Game.RobotSwarm.Game.ScenarioSwarm.Game.ScenarioInfoSwarm.Game.StateSwarm.Game.Step Swarm.DocGen Swarm.VersionSwarm.TUI.ModelSwarm.TUI.ViewSwarm.TUI.Controller Swarm.Web Swarm.App Paths_swarmTDefControl.Monad.Combinators.ExprPrefixSuffixInfixLInfixNInfixRVCApp Data.Set.LenssetOfFExec seedProgramGrabHarvestrobotEnvrobotCtxevalStepsPerTicksafeTogglePauseCtxunCtxVarempty singletonlookupdeleteassocs addBindingunion withBinding withBindings $fAsEmptyCtx $fMonoidCtx$fSemigroupCtx$fEqCtx $fShowCtx $fFunctorCtx $fFoldableCtx$fTraversableCtx $fDataCtx $fGenericCtx $fFromJSONCtx $fToJSONCtxWithUUtoUfromUUModuleTModuleModulemoduleTy moduleCtx UPolytypePolytypePolyForallUCtxTCtxUTypeTypeTypeFTyBaseFTyVarFTyCmdFTyDelayFTySumFTyProdFTyFunFBaseTyBVoidBUnitBIntBTextBDirBBoolBRobotPolyUnitUTyDelayUTyCmdUTyFunUTyProdUTySumUTyRobotUTyBoolUTyDirUTyTextUTyIntUTyUnitUTyVoidUTyVarUTyBaseTyDelayTyCmd:->::*::+:TyRobotTyBoolTyDirTyTextTyIntTyUnitTyVoidTyVarTyBasetyVarsucata mkVarNametrivMod $fIsStringFix$fIsStringUTerm$fWithUf $fWithUFix $fShowModule $fEqModule$fFunctorModule $fDataModule$fGenericModule$fFromJSONModule$fToJSONModule $fShowPoly$fEqPoly $fFunctorPoly $fDataPoly $fGenericPoly$fFromJSONPoly $fToJSONPoly $fShowTypeF $fEqTypeF$fFunctorTypeF$fFoldableTypeF$fTraversableTypeF$fGenericTypeF$fGeneric1TYPETypeF$fUnifiableTypeF $fDataTypeF$fFromJSONTypeF $fToJSONTypeF $fEqBaseTy $fOrdBaseTy $fShowBaseTy $fDataBaseTy$fGenericBaseTy$fFromJSONBaseTy$fToJSONBaseTy $fFromJSONFix $fToJSONFix $fGenericFix $fDataIntVar $fDataUTerm $fDataFixTermTUnitTConstTDirTIntTAntiIntTText TAntiTextTBoolTRobotTRefTRequireDeviceTRequireTVarSPairSLamSAppSLetSDefSBindSDelay DelayType SimpleDelay MemoizedDelayLocationNoLocSyntaxsLocsTermMUnAssocPS MBinAssocLNR ConstMeta ConstMFunc ConstMUnOp ConstMBinOpConstDocbriefDoclongDoc ConstInfosyntaxfixity constMetaconstDoc tangibilityConstNoopWait SelfdestructMoveTurnPlaceGiveInstallMakeHas InstalledCountDrillBuildSalvage ReprogramSayListenLogViewAppearCreateTimeWhereamiBlockedScanUploadIshereSelfParentBaseWhoamiSetnameRandomRunIfInlInrCaseFstSndForceReturnTry UndefinedFailNotNegEqNeqLtGtLeqGeqOrAndAddSubMulDivExpFormatConcatCharsSplitAppFSwapAtomicTeleportAs RobotNamed RobotNumberedKnowsDirInfo dirSyntaxdirAbs dirApplyTurn DirectionDLeftDRightDBackDForwardDNorthDSouthDEastDWestDDownTDelayTBindTLet:$:TAppTLamTPairSTermallDirsdirInfo isCardinalnorthsoutheastwest applyTurn toDirection fromDirectionallConstarityisCmd isUserFunc isOperatorisBuiltinFunction isTangibleisLong constInfomkOp'mkOpnoLocfvTfvmapFree1$fFromJSONKeyDirection$fToJSONKeyDirection$fIsStringConstDoc$fMonoidLocation$fSemigroupLocation $fPlatedTerm$fEqTerm $fShowTerm $fDataTerm $fGenericTerm$fFromJSONTerm $fToJSONTerm $fEqSyntax $fShowSyntax $fDataSyntax$fGenericSyntax$fFromJSONSyntax$fToJSONSyntax $fEqDelayType$fShowDelayType$fDataDelayType$fGenericDelayType$fFromJSONDelayType$fToJSONDelayType $fEqLocation$fShowLocation$fDataLocation$fGenericLocation$fFromJSONLocation$fToJSONLocation $fEqConstInfo$fOrdConstInfo$fShowConstInfo$fEqTangibility$fOrdTangibility$fShowTangibility$fReadTangibility $fEqLength $fOrdLength $fShowLength $fReadLength$fBoundedLength $fEnumLength $fEqConstMeta$fOrdConstMeta$fShowConstMeta $fEqMUnAssoc $fOrdMUnAssoc$fShowMUnAssoc $fEqMBinAssoc$fOrdMBinAssoc$fShowMBinAssoc $fEqConstDoc $fOrdConstDoc$fShowConstDoc $fEqConst $fOrdConst $fEnumConst$fBoundedConst $fDataConst $fShowConst$fGenericConst$fFromJSONConst $fToJSONConst $fEqDirection$fOrdDirection$fShowDirection$fReadDirection$fGenericDirection$fDataDirection$fHashableDirection$fToJSONDirection$fFromJSONDirection$fEnumDirection$fBoundedDirection elaborate wrapForce CapabilityCPowerCMove CMoveheavyCTurn CSelfdestructCGrabCHarvestCPlaceCGiveCInstallCMakeCCountCBuildCSalvageCDrill CSenseloc CSensefront CSensehereCScanCRandomCAppearCCreateCListenCLogCTextCFloatCCond CNegationCCompareCOrientCArithCEnvCLambda CRecursion CReprogramCWhoamiCSetname CTeleportCAtomicCSwapCTimeCTryCSumCProdCGodcapabilityName constCaps$fFromJSONCapability$fToJSONCapability$fEqCapability$fOrdCapability$fShowCapability$fReadCapability$fEnumCapability$fBoundedCapability$fGenericCapability$fHashableCapability$fDataCapability$fFromJSONKeyCapability$fToJSONKeyCapabilityReqCtx RequirementscapReqsdevReqsinvReqs RequirementReqCapReqDevReqInv singletonCap singletonDev singletonInvinsert requirements$fMonoidRequirements$fSemigroupRequirements$fEqRequirements$fOrdRequirements$fShowRequirements$fDataRequirements$fGenericRequirements$fFromJSONRequirements$fToJSONRequirements$fEqRequirement$fOrdRequirement$fShowRequirement$fReadRequirement$fGenericRequirement$fHashableRequirement$fDataRequirement$fFromJSONRequirement$fToJSONRequirementTyped_value _polytype _requires $fShowTyped $fEqTyped$fGenericTyped$fFromJSONTyped $fToJSONTypedpolytyperequiresvalueParser reservedWords parsePolytype parseType parseTermbinOpsunOps runParser runParserTHreadTerm readTerm'showShortError showErrorPos getLocRange $fShowStmt$fEqAntiquoting$fOrdAntiquoting$fShowAntiquoting swarmAttrMap entityAttr worldPrefixworldAttributes robotAttrdirtAttr grassAttr stoneAttriceAttr waterAttrrockAttr plantAttr highlightAttr notifAttrinfoAttrboldAttrdimAttrdefAttrredAttr greenAttrblueAttr yellowAttrcyanAttr$fFromJSONAttrName$fToJSONAttrName BorderLabels HBorderLabels plainHBorder plainBorder centerLabel leftLabel rightLabel bottomLabels topLabelshBorderWithLabelsborderWithLabelshandleListEventWithSeparators $fEqFindStart$fOrdFindStart$fShowFindStart$fEnumFindStart $fEqFindDir $fOrdFindDir $fShowFindDir $fEnumFindDirpanel $fNamedPaneln?maxOnmaximum0 cycleEnumuniq manhattangetElemsInArea readFileMay readFileMayTgetDataDirSafegetDataFileNameSafe dataNotFoundgetSwarmDataPathgetSwarmSavePathgetSwarmHistoryPath readAppData isIdentChar replaceLastreflow indefinite indefiniteQsingularSubjectVerbpluralnumbersquotequote commaListholdsOrisJustOr isRightOr isSuccessOrliftText<+=<%=%%=<<.=<>= _NonEmptysmallHittingSet$fToJSONTimeSpec$fFromJSONTimeSpec $fToJSONKeyV2$fFromJSONKeyV2 $fFromJSONV2 $fToJSONV2tyQInvalidAtomicReason TooManyTicksAtomicDupingThingNonSimpleVarType NestedAtomic LongConstTypeErr UnboundVar EscapedSkolemInfiniteMismatchDefNotTopLevel CantInfer InvalidAtomic HasBindings applyBindingsInferrunInferfreshsubstU=:= instantiate skolemize generalizegetTypeErrLocationinferTop inferModuleinferdecomposeCmdTydecomposeFunTy inferConstcheck isSimpleUType$fFallibleTypeFIntVarTypeErr$fHasBindingsModule$fHasBindingsCtx$fHasBindingsPoly$fHasBindingsUTerm $fFreeVarsCtx$fFreeVarsPoly$fFreeVarsUTerm $fShowTypeErr$fShowInvalidAtomicReason $fOrdIntVar PrettyPrec prettyPrecppr prettyText prettyStringpparens prettyTuple prettyPrecAppappliedTermPrec$fPrettyPrecInvalidAtomicReason$fPrettyPrecTypeErr$fPrettyPrecTerm$fPrettyPrecConst$fPrettyPrecCapability$fPrettyPrecDirection$fPrettyPrecCtx$fPrettyPrecPoly$fPrettyPrecPoly0$fPrettyPrecTypeF$fPrettyPrecUTerm$fPrettyPrecFix$fPrettyPrecIntVar$fPrettyPrecBaseTyEnvValueVUnitVIntVTextVDirVBoolVRobotVInjVPairVCloVDefVResultVBindVDelayVRef prettyValue valueToTerm $fEqValue $fShowValue$fGenericValue$fFromJSONValue $fToJSONValue ProcessedTerm processTermprocessParsedTerm processTerm'showTypeErrorPosprocessParsedTerm'$fToJSONProcessedTerm$fFromJSONProcessedTerm$fDataProcessedTerm$fShowProcessedTerm$fEqProcessedTerm$fGenericProcessedTermtmQlspMaindebugvalidateSwarmCodehandlersWorldWorldFunWFrunWFCoordsunCoords locToCoords coordsToLocworldFunFromArraynewWorld emptyWorld lookupTerrainlookupTerrainM lookupEntity lookupEntityMupdateupdateMloadCell loadRegion$fWrappedCoords$fRewrappedCoordst$fBifunctorWorldFun$fWrappedTileCoords$fRewrappedTileCoordst$fWrappedTileOffset$fRewrappedTileOffsett$fEqTileOffset$fOrdTileOffset$fShowTileOffset$fIxTileOffset$fGenericTileOffset$fEqTileCoords$fOrdTileCoords$fShowTileCoords$fIxTileCoords$fGenericTileCoords $fEqCoords $fOrdCoords $fShowCoords $fIxCoords$fGenericCoords FromJSONE parseJSONE parseJSONE'ParserEWithErunEliftElocalEwithEgetEdecodeFileEitherE..:..:?..!= withTextE withObjectE withArrayE$fFromJSONEe(,)$fFromJSONEe[]$fFromJSONEeInt $fFunctorWith$fApplicativeWith $fMonadWith$fMonadFailWithDisplayPriority$fHashableAttrName$fSemigroupDisplay $fEqDisplay $fOrdDisplay $fShowDisplay$fGenericDisplay$fHashableDisplaycurOrientation defaultChar displayAttrdisplayPriority invisibleorientationMap displayChar renderDisplayhiddendefaultTerrainDisplaydefaultEntityDisplaydefaultRobotDisplay$fMonoidDisplay$fToJSONDisplay$fFromJSONEDisplayDisplay$fFromJSONDisplay TerrainTypeStoneTDirtTGrassTIceTBlankT terrainMap$fFromJSONTerrainType$fEqTerrainType$fOrdTerrainType$fShowTerrainType$fReadTerrainType$fBoundedTerrainType$fEnumTerrainType Inventory EntityMapentitiesByName entitiesByCapEntity GrowthTimeEntityProperty UnwalkablePortableGrowableLiquidKnowndefaultGrowthTimemkEntitylookupEntityName deviceForCapbuildEntityMap loadEntities entityHash entityDisplay entityName entityPlural entityNameForentityDescriptionentityOrientation entityGrowth entityYieldsentityProperties hasPropertyentityCapabilitiesentityInventory lookupByName countByNamefromList fromElems insertCountcontains contains0plus isSubsetOfisEmptyinventoryCapabilities deleteCount deleteAllelems difference$fFromJSONEntityProperty$fToJSONEntityProperty $fEqInventory$fHashableInventory$fToJSONEntity$fFromJSONEntity $fOrdEntity $fEqEntity$fHashableEntity$fFromJSONEEntityMapEntity$fMonoidEntityMap$fSemigroupEntityMap $fEqEntityMap$fShowEntityMap$fGenericEntityMap$fFromJSONEntityMap$fToJSONEntityMap$fShowInventory$fGenericInventory$fFromJSONInventory$fToJSONInventory $fShowEntity$fGenericEntity$fEqGrowthTime$fOrdGrowthTime$fShowGrowthTime$fReadGrowthTime$fGenericGrowthTime$fHashableGrowthTime$fFromJSONGrowthTime$fToJSONGrowthTime$fEqEntityProperty$fOrdEntityProperty$fShowEntityProperty$fReadEntityProperty$fEnumEntityProperty$fBoundedEntityProperty$fGenericEntityProperty$fHashableEntityPropertyInventorySortOptionsInventorySortOrderByNaturalAlphabetic ByQuantityByTypeInventorySortDirection Ascending DescendingdefaultSortOptionsrenderSortMethodcycleSortOrdercycleSortDirection sortInventory$fEnumInventorySortOrder$fBoundedInventorySortOrder$fEqInventorySortOrder$fEnumInventorySortDirection$fBoundedInventorySortDirection$fEqInventorySortDirectionSeedOriginNatural ArtificialHardnessSoftHardSizeSmallBig testWorld1testWorld2Entites readEntity testWorld2testWorld2FromArray findOffset findPatchWithfindTreeOffsetfindGoodOrigin $fEqOrigin $fOrdOrigin $fShowOrigin $fReadOrigin $fEqHardness $fOrdHardness$fShowHardness$fReadHardness$fEqSize $fOrdSize $fShowSize $fReadSizeRecipe _recipeInputs_recipeOutputs_recipeRequirements _recipeTime _recipeWeightIngredientList $fEqRecipe $fOrdRecipe $fShowRecipe$fFunctorRecipe$fFoldableRecipe$fTraversableRecipe$fGenericRecipe$fFromJSONRecipe$fToJSONRecipe MissingType MissingInputMissingCatalystMissingIngredient recipeInputs recipeOutputsrecipeRequirements recipeTime recipeWeight loadRecipes outRecipeMap inRecipeMap reqRecipeMap recipesForknowsIngredientsFormakemake'$fFromJSONEEntityMapRecipe$fFromJSONRecipe0$fToJSONRecipe0$fShowMissingIngredient$fEqMissingIngredient$fShowMissingType$fEqMissingTypeExnFatal InfiniteLoop Incapable CmdFailedUser IncapableFix FixByInstall FixByObtain formatExnformatIncapableFixformatIncapable$fEqExn $fShowExn $fGenericExn $fFromJSONExn $fToJSONExn$fEqIncapableFix$fShowIncapableFix$fGenericIncapableFix$fFromJSONIncapableFix$fToJSONIncapableFix RobotUpdaterobotUpdateInventory WorldUpdate worldUpdateCESKInOutUpWaitingCell BlackholeVStoreLocContFrameFSndFFstFArgFAppFLetFTry FUnionEnvFLoadEnvFDefFBind FImmediateFUpdate FFinishAtomic emptyStoreallocate lookupCellsetCell finalValue initMachine initMachine'cancelresetBlackholes prettyCESK prettyCont prettyFrame$fToJSONWorldUpdate$fFromJSONWorldUpdate$fEqWorldUpdate$fShowWorldUpdate$fToJSONRobotUpdate$fFromJSONRobotUpdate$fEqRobotUpdate$fShowRobotUpdate$fEqCESK $fShowCESK $fGenericCESK$fFromJSONCESK $fToJSONCESK $fEqFrame $fShowFrame$fGenericFrame$fFromJSONFrame $fToJSONFrame $fShowStore $fEqStore$fGenericStore$fFromJSONStore $fToJSONStore $fShowCell$fEqCell $fGenericCell$fFromJSONCell $fToJSONCell RobotContext$fEqRobotContext$fShowRobotContext$fGenericRobotContext$fFromJSONRobotContext$fToJSONRobotContextLogEntry_leTime_leSaid _leRobotName _leRobotID _leLocation_leText LogSourceSaidLogged ErrorTracedefReqsdefStoredefTypesdefValsemptyRobotContext$fAtRobotContext$fIxedRobotContext$fShowLogEntry $fEqLogEntry $fOrdLogEntry$fGenericLogEntry$fFromJSONLogEntry$fToJSONLogEntry$fShowLogSource $fEqLogSource$fOrdLogSource$fGenericLogSource$fFromJSONLogSource$fToJSONLogSourceRobotR RobotPhase TemplateRobot ConcreteRobotRID leLocation leRobotID leRobotNameleSaidleTextleTime$fGenericRobotR$fToJSONRobotR $fEqRobotR $fShowRobotRRobotmachine robotContextrobotCreatedAt robotEntity robotHeavyrobotID robotLocationrobotLogUpdated robotParentID runningAtomic selfDestruct systemRobot tickSteps robotName trobotName robotDisplayunsafeSetRobotLocationtrobotLocationrobotOrientationrobotInventoryinstantiateRobotinstalledDevicesrobotLog inventoryHash robotKnowsrobotCapabilitiesmkRobotisActive waitingUntil getResulthearingDistance$fFromJSONEEntityMapRobotR Objective $fEqObjective$fShowObjective$fGenericObjective$fToJSONObjectiveScenarioWorldDescriptiondefaultTerrain offsetOriginpaletteularea cellTerrain cellEntity cellRobots IndexedTRobotobjectiveCondition objectiveGoal$fFromJSONObjective$fFromJSONE(,)Cell$fFromJSONE(,)WorldPalette$fFromJSONE(,)WorldDescription $fEqScenario$fShowScenario$fEqWorldDescription$fShowWorldDescription$fEqWorldPalette$fShowWorldPalettescenarioAuthorscenarioCreativescenarioDescriptionscenarioEntities scenarioKnown scenarioNamescenarioObjectivesscenarioRecipesscenarioRobots scenarioSeedscenarioSolutionscenarioStepsPerTickscenarioVersion scenarioWorldgetScenarioPath loadScenarioloadScenarioFile$fFromJSONEEntityMapScenarioScenarioInfoPair ScenarioInfo _scenarioPath_scenarioStatus_scenarioBestTime_scenarioBestTicksScenarioStatus NotStarted InProgressComplete_scenarioStarted_scenarioElapsed_scenarioElapsedTicks$fOrdZonedTime $fEqZonedTime$fToJSONScenarioStatus$fFromJSONScenarioStatus$fToJSONScenarioInfo$fFromJSONScenarioInfo$fEqScenarioInfo$fOrdScenarioInfo$fShowScenarioInfo$fReadScenarioInfo$fGenericScenarioInfo$fEqScenarioStatus$fOrdScenarioStatus$fShowScenarioStatus$fReadScenarioStatus$fGenericScenarioStatusScenarioCollectionSCscOrderscMap ScenarioItemSISingle SICollectionscenarioBestTicksscenarioBestTime scenarioPathscenarioStatusupdateScenarioInfoOnQuitscenarioItemNamescenarioItemByPathnormalizeScenarioPathscenarioCollectionToList loadScenariosloadScenarioInfosaveScenarioInfo$fEqScenarioCollection$fShowScenarioCollection$fEqScenarioItem$fShowScenarioItem _SISingle _NotStarted _InProgress _CompleteViewCenterRule VCLocationVCRobot CodeToRunSuggestedSolution ScriptPath$fEqViewCenterRule$fOrdViewCenterRule$fShowViewCenterRule$fGenericViewCenterRule$fFromJSONViewCenterRule$fToJSONViewCenterRule WinConditionNoWinCondition WinConditionsWon REPLStatusREPLDone REPLWorking$fShowWinCondition$fGenericWinCondition$fFromJSONWinCondition$fToJSONWinCondition$fEqREPLStatus$fShowREPLStatus$fGenericREPLStatus$fFromJSONREPLStatus$fToJSONREPLStatus Notifications_notificationsCount_notificationsContent RunStatusRunning ManualPause AutoPause_NoWinCondition_WinConditions_WontoggleRunStatus$fMonoidNotifications$fSemigroupNotifications$fEqNotifications$fShowNotifications$fGenericNotifications$fFromJSONNotifications$fToJSONNotifications $fEqRunStatus$fShowRunStatus$fGenericRunStatus$fFromJSONRunStatus$fToJSONRunStatus GameStatenotificationsContentnotificationsCountallDiscoveredEntitiesavailableCommandsavailableRecipes creativeModecurrentScenarioPath entityMapgensym knownEntitieslastSeenMessageTime messageQueue needsRedrawrandGen recipesIn recipesOut recipesReqreplNextValueIndex replStatusrobotMaprobotStepsPerTickrobotsByLocation runStatus scenariosseedticks winCondition winSolutionworldpausedrobotsAtLocation robotsInArea baseRobot activeRobots waitingRobotsadjListnameList viewCenterfocusedRobotIDviewCenterRule replWorkingreplActiveTypemessageNotificationsmessageIsRecentmessageIsFromNearbyapplyViewCenterRulerecalcViewCentermodifyViewCenter viewingRegion focusedRobotclearFocusedRobotLogUpdated addTRobotaddRobot emitMessage sleepUntil sleepForever activateRobotwakeUpRobotsDoneSleeping deleteRobot initGameStatescenarioToGameStateinitGameStateForScenario classicGame0 GrabbingCmdGrab'Harvest'Swap' MoveFailure failIfBlocked failIfDrown RobotFailureThrowExnDestroy IgnoreFailHasRobotStepStategameTickevalPTgetNowhypotheticalRobot evaluateCESKrunCESK flagRedraw zoomWorldentityAtupdateEntityAt robotWithID robotWithNameuniformweightedChoice randomNamecreateLogEntrytraceLog traceLogShow constCapsForensureCanExecute hasCapabilityhasCapabilityForcmdExnraisewithExceptions tickRobot tickRobotRec stepRobotstepCESK evalConst addSeedBot execConstverbGrabbingCmdverbedGrabbingCmdprovisionChildupdateRobotLocationonTargetevalCmp compareValues incompatCmp incomparable evalArithsafeDivsafeExpupdateDiscoveredEntitiesupdateAvailableRecipesupdateAvailableCommands$fEqGrabbingCmd$fShowGrabbingCmd PageAddress entityAddresscommandsAddresscapabilityAddressrecipesAddress SheetTypeEntitiesCommands CapabilitiesRecipes EditorTypeEmacsVSCode GenerateDocs RecipeGraphEditorKeywords CheatSheetnoPageAddresses generateDocsbuiltinFunctionList editorListkeywordsCommandskeywordsDirections operatorNames commandsPagecapabilityPage$fEqGenerateDocs$fShowGenerateDocs$fEqPageAddress$fShowPageAddress $fEqSheetType$fShowSheetType$fEnumSheetType$fBoundedSheetType$fEqEditorType$fShowEditorType$fEnumEditorType$fBoundedEditorTypeNewReleaseFailureFailedReleaseQueryNoMainUpstreamReleaseOnDevelopmentBranchOldUpstreamReleaseisSwarmReleaseTagversionupstreamReleaseVersion tagToVersiongetNewerReleaseVersion$fShowNewReleaseFailure REPLHistory REPLHistItem REPLEntry REPLOutputName REPLPanel WorldPanel RobotPanel InfoPanel REPLInput WorldCache WorldExtent InventoryListInventoryListItemMenuList ScenarioList InfoViewport ModalViewportAppEventUpstreamVersion infoScroll modalScroll getREPLEntry isREPLEntry replItemText$fEqREPLHistItem$fOrdREPLHistItem$fShowREPLHistItem$fReadREPLHistItem$fEqName $fOrdName $fShowName $fReadName$fShowAppEvent REPLState REPLPrompt CmdPrompt SearchPromptTimeDirNewerOlder replIndexreplSeqnewREPLHistoryrestartREPLHistory replLength addREPLItemgetLatestREPLHistoryItemsmoveReplHistIndexgetCurrentItemTextreplIndexIsAtInput removeEntry lastEntry defaultPrompt newREPLEditor initREPLState $fEqTimeDir $fOrdTimeDir $fShowTimeDirModal _modalType _modalDialogButtonSelection CancelButtonKeepPlayingButtonStartOverButton QuitButton NextButton ModalType HelpModal RecipesModal CommandsModal MessagesModal RobotsModalWinModal QuitModalKeepPlayingModalDescriptionModal GoalModal replHistoryreplLastreplPromptEditorreplPromptTypereplType replValidreplPromptText $fEqModalType$fShowModalTypeMenuNoMenuMainMenu NewGameMenu MessagesMenu AboutMenu MainMenuEntryNewGameTutorialMessagesAboutQuit modalDialog modalTypemainMenu$fEqMainMenuEntry$fOrdMainMenuEntry$fShowMainMenuEntry$fReadMainMenuEntry$fBoundedMainMenuEntry$fEnumMainMenuEntryInventoryListEntry SeparatorInventoryEntryInstalledEntry _NewGameMenumkScenarioList mkNewGameMenu$fEqInventoryListEntryUIState _Separator_InventoryEntry_InstalledEntry RuntimeStateaccumulatedTimeappData frameCountframeTickCount lastFrameTime lastInfoTime scenarioRef tickCount uiCheatModeuiErroruiFPS uiFocusRinguiGoaluiHideRobotsUntil uiInventoryuiInventoryShouldUpdateuiInventorySortuiMenuuiModal uiMoreInfoBot uiMoreInfoTop uiPlayinguiREPL uiScrollToEnd uiShowFPS uiShowZerouiTPF uiWorldCursor uiShowRobotslgTicksPerSecondinitRuntimeStateAppStateeventLogupstreamReleasewebPortlogEventAppOptsuserSeed userScenario scriptToRunautoPlay cheatMode userWebPort repoGitInfo gameState runtimeStateuiState focusedItem focusedEntity initFocusRinginitLgTicksPerSecond initUIStatepopulateInventoryList initAppState startGame restartGame nextScenario topContextscenarioToAppStatedrawUIdrawTPS chooseCursor drawDialog generateModal drawModalMenu drawKeyMenu drawKeyCmd drawWorlddrawRobotPaneldrawItemdrawLabelledEntityName drawInfoPanelexplainFocusedItemdrawREPL handleEventquitGame runFrameUIrunFrame runFrameTicks runGameTickUI runGameTickupdateUIhandleREPLEventvalidateREPLFormadjReplHistIndexhandleWorldEvent scrollViewkeyToDir adjustTPShandleInfoPanelEvent$fEqCompletionTypeSwarmApimkAppwebMain defaultPortstartWebThread EventHandlerappappMaindemoWebenablePasteModegetDataFileName getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDir text-1.2.5.0Data.Text.InternalText,unification-fd-0.11.2-10nGBFM9NSRCQtHAyha5T3Control.Unification.TypesUTermData.Functor.FixedpointFixControl.Unification.IntVarIntVarLength TangibilityShortLongdown cardinalDirsshortlong requirements' Antiquotingsclexemesymbolreserved identifier textLiteralinteger parseConst parseLocGparseLocsLetsDeffixDefMissingSemisbaseControl.Monad.Fail MonadFailfully fullyMaybe FindStrategyFindDir FindStart fwdInclusive fwdExclusive bwdInclusive bwdExclusivelistFindByStrategy Data.Maybe fromMaybeGHC.EnumEnumcatchIO GHC.MaybeMaybeJust Data.EitherEitherRightLeft#either-5.0.2-5NI3p1cUuFSG7dJvrEIzZoData.Either.Validation ValidationSuccessFailureControl.UnificationFreeVars IntBindingT validAtomic analyzeAtomicisSimpleUPolytypeghc-prim GHC.ClassesOrdcontainers-0.6.5.1Data.Set.InternalSet EntityTile TerrainTile TileOffset TileCoordstileBitstileMask tileCoords tileOrigin tileBounds tileOffset plusOffsetGHC.Bitsxor#aeson-2.1.1.0-3oVJQ6k21EwIYMuCcSPLyData.Aeson.Types.FromJSON parseJSONFromJSONData.Aeson.Types.Internal.:.:?.!= GHC.TypesInt _entityHash_entityDisplay _entityName _entityPlural_entityDescription_entityOrientation _entityGrowth _entityYields_entityProperties_entityCapabilities_entityInventory rehashEntity hashedLensgetSortCompartorresolveRecipesbuildRecipeMapmissingIngredientsFor unlinesExText _defTypes_defReqs_defVals _defStore_robotCapabilities_installedDevicesRobotID RobotLocation WorldPaletteRobotMap buildRobotMapgetThing getEntitygetRobotpaintMap orderFileNameloadScenarioDirscenarioPathToSavePathloadScenarioItemdefaultRobotStepsPerTicklens-5.2-5ddEOJ9614q3muyA6i6qJYControl.Lens.TypeGetter buildWorld+fused-effects-1.1.2.1-72OYyMRlDoNP5cqc2wIXnControl.Effect.Throw.InternalThrowControl.Effect.Catch.InternalCatchControl.Effect.Error.InternalErrorOrdering recipeLevelsclassicScenarioignoredEntites hiddenNode.~>.---<> replStart brick-1.3-Co5IVQuoJrFA35glvCiZ1TBrick.Widgets.ListListGHC.IOFilePathstartGameWithSeedscenarioToUIState drawGameUIdrawClockDisplayclockInstalleddrawTime maybeDrawTimedrawType replHeightmaxModalWindowWidthrenderErrorDialog maybeScroll drawModal curMenuNamedescriptionWidgetmessagesWidgetdrawLoc displayLoc recipesWith drawRecipetimeE drawLogEntryreplPromptAsWidgetdisplayParagraphsKeyhandleMainMenuEvent advanceMenuhandleMainEventsafeAutoUnpauseisRunningModalsaveScenarioInfoOnQuit zoomGameStateloadVisibleRegionstripCmd resetREPL tabCompletehandleRobotPanelEvent makeEntitydescriptionModal