9^z      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                  ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D EFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                        ! !!!!!!!!!!!!!!!!!!! !!!"!#!$!%!&!'"(")"*"+","-"."/#0#1#2#3#4#5#6#7#8#9#:$;$<%=%>&?&@&A&B&C'D'E'F'G'H'I'J'K'L'M'N'O'P'Q(R(S(T(U(V(W(X(Y(Z([(\(](^(_(`(a(b(c(d(e(f(g(h(i(j(k(l(m(n(o(p(q(r(s(t)u)v)w)x)y)z*{*|*}*~*****************,GHCunstablestephen.tetley@gmail.comVersion number  (0,17,0) !'Convert a join list to a regular list. 'Build a join list from a regular list.  This builds a tall skinny list. )WARNING - throws an error on empty list. Create an empty join list. Create a singleton join list. /Cons an element to the front of the join list. .Snoc an element to the tail of the join list. =Extract the first element of a join list - i.e. the leftmost ? element of the left spine. An error is thrown if the list is  empty. <This function performs a traversal down the left spine, so  unlike head2 on regular lists this function is not performed  in constant time. 8This function throws a runtime error on the empty list. &Right-associative fold of a JoinList. %Left-associative fold of a JoinList. #Access the left end of a sequence. <Unlike the corresponing operation on Data.Sequence this is = not a cheap operation, the joinlist must be traversed down + the left spine to find the leftmost node. :Also the traversal may involve changing the shape of the  underlying binary tree. $Access the right end of a sequence. <Unlike the corresponing operation on Data.Sequence this is = not a cheap operation, the joinlist must be traversed down + the left spine to find the leftmost node. :Also the traversal may involve changing the shape of the  underlying binary tree.     GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>9 Doc is a Join List ... !'Create an empty, zero length document. ")Create a document from a ShowS function. #6Horizontally concatenate two documents with no space  between them. $<Horizontally concatenate two documents with a single space  between them. %6Vertical concatenate two documents with a line break. &'2Horizontally concatenate a list of documents with (<>). (2Horizontally concatenate a list of documents with (<+>). )9Vertically concatenate a list of documents, with a line  break between each doc. *)Create a document from a literal string. <The string should not contain newlines (though this is not  enforced). +,Create a document from a literal character. *The char should not be a tab or newline. ,Show the Int as a Doc.  int = text . show -Show the Integer as a Doc. .Show an "integral value" as a Doc via . /Show the Float as a Doc. 0Show the Double as a Doc. 18Show the Int as hexadecimal, padding up to 4 digits if  necessary. 9No trucation occurs if the value has more than 4 digits. 22Create a Doc containing a single space character. 3!Create a Doc containing a comma, ",". 4&Create a Doc containing a semi colon, ";". 5!Create a Doc containing newline, "\n". 6:Fill a doc to the supplied length, padding the right-hand  side with spaces. >Note - this function is expensive - it unrolls the functional  representation of the String. /Also it should only be used for single line Doc's. 7String version of 6. This is more efficient than 6 as the input is a string " so its length is more accesible. 6Padding is the space character appended to the right. 8Left-padding version of 7. 9=Punctuate the Doc list with the separator, producing a Doc. :,Enclose the final Doc within the first two. +There are no spaces between the documents:  enclose l r d = l <> d <> r ;&Enclose the Doc within single quotes. <&Enclose the Doc within double quotes. =Enclose the Doc within parens (). >'Enclose the Doc within square brackets []. ?$Enclose the Doc within curly braces {}. @&Enclose the Doc within angle brackets <>. A&Create a Doc containing a left paren, '('. B'Create a Doc containing a right paren, ')'. C/Create a Doc containing a left square bracket, '['. D0Create a Doc containing a right square bracket, ']'. E,Create a Doc containing a left curly brace, '{'. F-Create a Doc containing a right curly brace, '}'. G.Create a Doc containing a left angle bracket, '<'. H/Create a Doc containing a right angle bracket, '>'. I;Comma separate the list of documents and enclose in square  brackets. J<Comma separate the list of documents and enclose in parens. K9Separate the list with a semicolon and enclose in curly  braces. LHorizontally indent a Doc. &Note - this space-prefixes the Doc on the current line. It = does not indent subsequent lines if the Doc spans multiple  lines. MWrite a Doc to file. 1 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM1 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM1 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMGHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>>NOPQRSTUVWXYZ[This one is from Chris Okasaki's "Even Higher-Order  Functions for Parsing". \;Peek tries the supplied parse, but does not consume input  ** even when the parse succeeds **. ]^_`abcdeApplicative cons. fghijklmnoo" an alias for Control.Applicative . pqrstuvwxyz{|}~5NOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~5QRTSPONUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~5NOPQRTSSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>;Opaque type representing a parser that consumes arbitrary  space.  Unlike Parsec'1s lexeme parser, this can be customized so that 0 e.g. newlines are not consumed as white space. #Build a lexeme parser that handles space. Space' is zero or more elements matching the isSpace  predicate from  Data.Char. -Build a lexeme parser that handles arbitrary space. space5 is parametric, for instance this can manufacture a : lexeme parser that consumes space and tab chars but not  newline. ;Build a lexeme parser that handles start-and-end delimited  comments and arbitrary space. ;Build a lexeme parser that handles line spanning comments  an arbitrary space. ;Build a lexeme parser that handles start-and-end delimited ' comments, line comments and arbitrary space. <Wrap a CharParser with a lexeme parser, the CharParser will : consume trailing space according to the strategy of the  LexemeParser. GHCunstablestephen.tetley@gmail.com 6velo consumes the list as per map, but builds it back , as a Hughes list - so items can be dropped  replaced, repeated, etc... GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>!Anchors in the center of a side. ;Sides are addressable by index. Following TikZ, side 1 is @ expected to be the top of the shape. If the shape has an apex A instead of a side then side 1 is expected to be the first side  left of the apex. >Implementations are also expected to modulo the side number, + rather than throw an out-of-bounds error. 9Anchors at the bottom left and right corners of a shape. 6Anchors at the top left and right corners of a shape. >For some shapes (Rectangle) the TikZ convention appears to be 5 have cardinals as the corner anchors, but this doesn't seem @ to be uniform. Wumpus will need to reconsider anchors at some  point... 6Anchor on a border that can be addressed by an angle. ?The angle is counter-clockwise from the right-horizontal, i.e.  0 is east. =Secondary group of cardinal (compass) positions on an object  for the diagonal positions. =It seems possible that for some objects defining the primary = compass points (north, south,...) will be straight-forward 7 whereas defining the secondary compass points may be ; problematic, hence the compass points are split into two  classes. ,Cardinal (compass) positions on an object. @Cardinal anchors should be at their equivalent radial position. ? However, some shapes may not be able to easily define radial A positions or may be able to provide more efficient definitions B for the cardinal anchors. Hence the redundancy seems justified. Apex of an object. Center of an object. !Note an Anchor is just a Point2.  : ' extract_func * dist * object -> Point  <Derive a anchor by projecting a line from the center of an : object through the intermediate anchor (produced by the ? extraction function). The final answer point is located along - the projected line at the supplied distance dist. <E.g. take the north of a rectangle and project it 10 units  further on:   projectAnchor north 10 my_rect ?If the distance is zero the answer with be whatever point the # the extraction function produces. :If the distance is negative the answer will be along the B projection line, between the center and the intermediate anchor. @If the distance is positive the anchor will be extend outwards  from the intermediate anchor.  : + object_a * object_b -> (Point_a, Point_b)  .Find the radial connectors points for objects a and b along ! the line joining their centers. GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>). is a Hughes list of Strings, so it supports  efficient append.  - type synonym for String. :A map between a font name and the respective FontMetrics. 0 store a subset of the properties available in ? a font file - enough to calculate accurate bounding boxes and  positions for text.  3 Bounding box representing the maximum glyph area. # Width vectors for each character.  Cap height  Descender depth. <Because Wumpus always needs font metrics respective to the : current point size, the actual fields are all functions. %A lookup function from code point to  width vector. >The unit is always stored as a Double representing PostScript  points. ?Note - in PostScript terminology a width vector is not obliged 9 to be left-to-right (writing direction 0). It could be & top-to-bottom (writing direction 1). 7A family group of FontDefs (regular, bold, italic and  bold-italic). ?It is convenient for some higher-level text objects in Wumpus  (particularly Doc, in Wumpus-Drawing) to treat a font and its 2 standard weights as the same entity. This allows Doc API to  provide a bold, operation to simply change to the the bold > weight of the current family, rather than use the primitive  set_font2 operation to change to an explicitly named font. FontDef wraps FontFace! from Wumpus-Core with file name # information for the font loaders. A Unicode code-point. Extract the regular weight  from a . Extract the bold weight  from a . ANote - this falls back to the regular weight if the font family / has no bold weight. To get the bold weight or Nothing if it ( is not present use the record selector ff_bold.  Extract the italic weight  from a . ANote - this falls back to the regular weight if the font family 3 has no italic weight. To get the italic weight or Nothing if + it is not present use the record selector  ff_italic.  Extract the  bold-italic weight  from a  . ANote - this falls back to the regular weight if the font family > has no bold-italic weight. To get the bold-italic weight or  Nothing/ if it is not present use the record selector  ff_bold_italic. !Print the loader errors from the  to std-out.  : ( name * font_table -> Maybe FontMetrics  !Lookup a font in the font_table.  : / name * font_metrics * font_table -> FontTable  )Insert a named font into the font_table. 8This ignores the Char code lookup and just returns the  default advance vector. %%% GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>5The metrics read from a font file by a font loader. "NOTE - FontProps is parametric on cu - Character Unit and  not on the usual u. A typical character unit is , < the unit of measurement for AFM files (1000th of a point). =The is the initial representation used by Wumpus-Basic as an ' syntax tree when loading font files. 9Monospace defaults are used if the font loader fails to  extract the necessary fields. =The values are taken from the font correpsonding to Courier  in the distributed font files. >Wumpus needs a very small subset of AFM files, common to both  version 2.0 and version 4.1. >Note - Bounding Box is mandatory for AFM versions 3.0 and 4.1 ?Cap Height is optional in AFM versions 3.0 and 4.1. As Wumpus ? uses cap height in calculations, glyph metrics must be build / with an arbitrary value if it is not present. *Encoding Scheme is optional in AFM files. Afm files index glyphs by PostScript character code. This & is not the same as Unicode, ASCII... #It is expected to be determined by EncodingScheme in the " Global Font Information Section. 9Build a MetricsOps function table, from a character unit 2 scaling function and FontProps read from a file.  GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>;Strictly speaking a fontBBox is measured in integer units.                      GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com> GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com> GHC highly unstablestephen.tetley@gmail.com-9Advance vectors provide an idiom for drawing consecutive > graphics. PostScript uses them to draw left-to-right text - 9 each character has an advance vector for the width and > as characters are drawn they successively displace the start 9 point for the next character with their advance vector. Type alias for Vec2. 8An enumeratied type representing the compass positions.  !":Vertical alignment - align to the left, center or bottom. #$%&;Horizontal alignment - align to the top, center or bottom. '()*+,-./0The empty data type - i.e. () - wrapped with a phantom unit  parameter. 12A Bifunctor class. >Again, it would be nice if there was a Bifunctor class in the  Haskell Base libraries... 3456A Semigroup class. ?The perhaps unusual name is the TeX name for the circled plus ? glyph. It would be nice if there was a semigroup class in the  Haskell Base libraries... 78;Type family to access the unit parameter of a TraceDrawing * or a promoted TraceDrawingT transformer. 99 :  list_head * [rest] -> Ans  Semigroup version of mconcat from the module  Data.Monoid. *As a semigroup cannot build a zero value, concat cannot # handle the empty list. So to make 9 a safe function : the input list is already destructured by one cons cell. 9Effectively this means that client code must handle the ! empty list case, before calling 9. :: :  alternative * [list] -> Ans : uses 7' to create a summary value from a list  of values. When supplied the empty list : returns the supplied   alternative2 value. If the list is inhabited, the alternative  value is discarded. This contrasts to 9$ where the single value represents + the head of an already destructured list. ;<=,1 an object that gives access to its unit at the  functor position. >+1 an object that gives access to its unit at the  functor position. ?1Convert a scalar value from one unit to another. @<Unit convert an object that gives access to its unit at the  Functor position. In practive this will be *all* Image answers. ABC7Extract the horizontal component of an advance vector. ;For left-to-right latin text, the vertical component of an 8 advance vector is expected to be 0. Ingoring it seems  permissible when drawing text. D6Extract the verticall component of an advance vector. - !"#$%&'()*+,-./0123456789:;<=>?@ABCD-8679:2345;<01-./*+,=>?@AB&)('"%$#! CD-!  !"%$##$%&)(''()*+,+,-././011234534567789:;<=>?@ABCDGHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>E#Wrapped Double representing an En. F$Wrapped Double representing an Em. GWrapped Double Pica unit type. Pica is 12 Points. H(Wrapped Double representing Centimeter. I5Cast a value in Centimeters to some Fractional type. ;Note - this casting should only be used for non-contextual  units such as Double. JConvert Double to Centimer. K.Cast a value in Pica to some Fractional type. ;Note - this casting should only be used for non-contextual  units such as Double. LConvert a Double to a Pica. EFGHIJKLHIJGKLFEEFGHIJKLGHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>/MM is equivalent to the to the  MonadReader - class, but the environment type is fixed to ba. To avoid name clashes with mtl this scheme is used:   askDC = ask  asksDC = asks  localize = local $Note, because the derived operation query (aka asks) is 3 expected to be used more often than queryCtx (aka ask) it  gets the more convenient name. NOPQ5ConnectorProps control the drawing of connectors in  Wumpus-Drawing.   conn_src_space :: Em  conn_dst_space :: Em @Source and destination spacers - these add spacing between the B respective connector points and the tips of the drawn connector.   conn_src_offset :: Em  conn_dst_offset :: Em =Source and destination offsets - these offset the drawing of > the connector perpendicular to the direction of line formed B between the connector points (a positive offset is drawn above, > a negative offset below). The main use of offsets is to draw  parallel line connectors.   conn_arc_ang :: Radian  Control the bend of an arc connector.   conn_src_arm :: Em  conn_dst_arm :: Em  Control the arm/ length of a jointed connector - arms are the % initial segments of the connector.   conn_loop_size :: Em  Control the height of a loop connector.   conn_box_halfsize :: Em :Control the size of a connector box. Connector boxes are @ drawn with the exterior lines projected out from the connector $ points a halfsize above and below. RSTUVWXYZ[\The text margin is measured in F so it is relative to the  current font size. The default value is 0.5. ]^_`2Type synonym for DrawingContext update functions. aba - the "graphics state" of Wumpus-Basic. B DrawingContext is operated on within a Reader monad rather than  a State monad so "updates" are delineated within a local  operation (called localize# in Wumpus), rather than permanent  until overridden as per set of a State monad. =Note - in contrast to most other drawing objects in Wumpus, ; none of the types of measurement values are parameteric ) (usually notated with the type variable u in Wumpus). Types  are either + representing PostScript points or Em - a ? contextual size that is interpreted according to the current  font size. :It is easier to specialize all the measurement types and  within the ba and add parametricity to the  getters and setters instead. bcdefghijklmnopp :  font_size -> DrawingContext   Create a ba. Note -  font_size) is used for sizing more than just text > labels. Arrowheads, plot marks and other elements have their % metrics derived from the font size. (No real font metrics are present in the ba  created by p. Static, hard-coded fallback  metrics derived from the Courier font are available but 7 these metrics might not accurately correspond to the  Courier3 available to the the final renderer (GhostScript,  an SVG viewer, etc.). =Use this constructor for drawings that make primitive use of  text.   font_metrics_table: empty  font_load_log: empty ( fallback_metrics: monospace_metrics  font_face: Courier + font_size: @supplied_font_size@ L stroke_props: line_width 1, no dash_pattern, cap-butt, join-miter.  stroke_colour: black ! fill_colour: light_gray  text_colour: black  line_spacing_factor: 0.2  round_corner_factor: 0 ( text_margin: (0.5 em, 0.5 em)  conn_src_sep: 0  conn_dst_sep: 0  conn_src_offset: 0  conn_dst_offset: 0  conn_arc_ang: pi / 12  conn_src_arm: 1  conn_dst_arm: 1  conn_loop_size: 2 qq : , font_size * font_metrics -> DrawingContext   Create a ba$ with font metrics loaded from the  file system. Note -  font_size) is used for sizing more than just text > labels. Arrowheads, plot marks and other elements have their % metrics derived from the font size. =Use this constructor for drawings that make use of the text  objects provided by Wumpus-Drawing (DocText and RotText). rr : ) font_load_result -> DrawinContextUpdate  >Add the font metrics from the FontLoadResult, if a font with $ the same name alreay exists in the ba it will be - replaced. Error and warning messages in the font_load_result  will be appended to the  font_load_log. ss :  DrawingContextF  $Reset the drawing properties in the ba to their 4 default values. This changes the following fields: L stroke_props: line_width 1, no dash_pattern, cap-butt, join-miter.  stroke_colour: black ! fill_colour: light_gray  text_colour: black  line_spacing_factor: 0.2  round_corner_factor: 0 ( text_margin: (0.5 em, 0.5 em) tt :  DrawingContextF  !Reset the drawing metrics in the ba to their 3 default values. This is a more limited version of  s# and changes the following fields: L stroke_props: line_width 1, no dash_pattern, cap-butt, join-miter.  line_spacing_factor: 0.2  round_corner_factor: 0 ( text_margin: (0.5 em, 0.5 em) Courier u)MNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstu)abcdefghijklmno`\]^_QRSTUVWXYZ[pqrstMNOPu)MNOPNOPQ RSTUVWXYZ[RSTUVWXYZ[\]^_]^_`abcdefghijklmnobcdefghijklmnopqrstuGHC highly unstablestephen.tetley@gmail.comv Alias for w*. Wumpus considers Context functions that  don't produce graphics to be queries.   Query :: DrawingContext -> a v has no unit type parameter. w:Most drawing operations in Wumpus-Basic have an implicit  graphics state the ba, so the most primitive ? building block is a function from the DrawingContext to some  polymorphic answer. @This functional type is represented concretely as the initials  CF for contextual function.  CF :: DrawingContext -> a xRun a CF' (context function) with the supplied  DrawingContext. yConstruction function. z{|}~:Apply the value transformer to the answer of the context  function. Figuratively  push it right so it works on the  answer.  pushR0 = fmap :Apply the value transformer to the answer of the context  function. Figuratively  push it right so it works on the  answer.  pushR1 = fmap . fmap :Apply the value transformer to the answer of the context  function. Figuratively  push it right so it works on the  answer.  pushR2 = fmap . fmap . fmap +Extract the drawing context from a CtxFun.  (ctx -> ctx) vwxyz{|}~wvxyz{|}~vwxyz{|}~GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>&;Get the Point corresponding the grid coordinates scaled by  the snap-grid scaling factors. <Scale a vector coordinate by the snap-grid scaling factors. Absolute units. "Get the (x,y) margin around text. >Note - not all text operations in Wumpus are drawn with text  margin. The mark4 height is the height of a lowercase letter in the ) Courier font at the current point size. =Arrowheads, dots etc. should generally be drawn at the mark  height. 7Vertical distance between descender of a line and the  cap-height of the line below. =Get the font bounding box - this is the maximum boundary of @ the glyphs in the font. The span of the height is expected to 5 be bigger than the cap_height plus descender depth. Height of a capital letter. -Note - descender is expected to be negative. 3This is the distance from cap_height to descender. 6Note the CharWidthLookup is not parameteric on units.  CharWidth2 is always Double representing PostScript points. 2 Client code must convert this value accordingly. $$$GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>= : $ x_unit * y_unit -> DrawingContextF  Set the snap grid factors" - a snap grid is an alternative 5 coordinate space, it can be convenient for drawing  " box and arrow" diagrams. set_line_width : $ width_in_points -> DrawingContextF  /Set the line_width to the supplied point size. !Initially the line width is 1.0. Constant+ variations of the function maybe be more  convenient: 7 line_default, line_thin, line_thick, line_ultra_thick Set the line_width to default - 1.0. Set the line_width to thin - 0.5. Set the line_width to thick - 2.0. Set the line_width to  ultra_thick - 4.0. )Set the line_cap to the default which is butt. This is a synonym for . Set the line_cap to butt. -Butt squares of the stroke at the end point. This is the default. Set the line_cap to round. 8This rounds the end of the stroke and the visually the 3 rounding slightly extends the length of the line. Set the line_cap to square. <This squares off the end of the stroke, visually extending $ the stroke by half the line width. *Set the line_join to the default which is miter. This is a synonym for . Set the line_join to miter. >This extends the joining line segments to form a sharp miter. This is the default. Set the line_join to round. 8This rounds off the corner of the joined line segments. Set the line_join to round. ?This bevels off the corner of the joined line segments with a  notch. Set the dash pattern. Initially the dash pattern is . Set the dash_pattern to solid - i.e. no dash pattern. This is the default. ,Set the dash pattern to draw a dotted line. ?A dot is actually a square - side length is equal to the line  width. 3The spacing between dots is 2 times the dot width. ;Set the dash pattern to draw a tightly packed dotted line. ?A dot is actually a square - side length is equal to the line  width. 4The spacing between dots is equal to the dot width. 4Set the dash pattern to draw a loosely dotted line. ?A dot is actually a square - side length is equal to the line  width. 3The spacing between dots is 4 times the dot width. ,Set the dash pattern to draw a dashed line. <The dash length is 3 times the line width, the spacing is 2  times the line width. <Set the dash pattern to draw a tightly packed, dashed line. ;The dash length is 3 times the line width, the spacing is  equal to the line width. 4Set the dash pattern to draw a loosely dashed line. <The dash length is 3 times the line width, the spacing is 4  times the line width. 3Set the font attributes, point size and font face. Set the font face. Set the point size. (This controls the drawing size of both 3 text labels and marks (e.g. dots and arrowheads). 4Scale the current point size by the supplied ratio. :Note - as fonts can only be drawn at integral sizes this > operation is not exact - for instance scaling 15pt by (1%2)  results in 7pt. ?Set the point size (font and mark size) to double the current  size. <Set the point size to half the current size, note the point 7 size also controls the size of dots, arrowsheads etc. :Note - as fonts can only be drawn at integral sizes this 9 operation is not exact - half size of 15pt type is 7pt.  : " x_sep * y_sep -> DrawingContextF  <NOTE - ideally this would use Em or En rather thn Double... Set the text margin to (0,0). ?This produces a tight box around the text vertically measured A to the cap-height and descender. Therefore some characters may 9 extend outside the margin (e.g. accented capitals like  A-grave). +Set the text margin to (0.25 em, 0.25 em). )Set the text margin to (0.5 em, 0.5 em). )Set the text margin to (1.0 em, 1.0 em). Set the stroke colour. Set the fill colour. Set the text colour. :Set the stroke, fill and text colours to a single colour. )Swap the stroke colour and fill colours. 6Set the fill colour to use the current stroke colour. 6Set the stroke colour to use the current fill colour. 4Set the fill colour to use the current text colour. 6Set the stroke colour to use the current fill colour. 6Set the text colour to use the current stroke colour. 4Set the text colour to use the current fill colour. Normalize to zero if negative. "Set the connector source spacing. ;The spacing is used as a projection along the line formed 0 between connector points making the connection looser if  required. >The default value is 0. Negative values are not allowed, they  are normalized to 0. 'Set the connector destination spacing. ;The spacing is used as a projection along the line formed 0 between connector points making the connection looser if  required. >The default value is 0. Negative values are not allowed, they  are normalized to 0. :Set the connector source and destination spacings to the  same length. !Set the connector source offset. ,The offset is used to shift the start point upwards 8 perpendicular to its true origin (negative values are < downwards). This can be used to draw a connector with two  parallel lines, for example. ?Upwards and downwards in this description are dependent on the A direction of the line, of course. Generally the documentations = consider lines are left-to-right unless specifically noted. &Set the connector destination offset. See  for an explanation. Set the connector arc angle. %Set the connector source arm length. *Set the connector destination arm length. ;Set the connector source and destination arms to the same  length. Set the connector loop size.  Set the connector box halfsize. 777GHC highly unstablestephen.tetley@gmail.com =Graphics objects, even simple ones (line, arrow, dot) might = need more than one primitive (path or text label) for their ? construction. Hence, the primary representation that all the $ others are built upon must support  concatenation of  primitives. 8Wumpus-Core has a type Picture - made from one or more ? Primitives - but Pictures include support for affine frames. > For drawing many simple graphics (dots, connector lines...) ? that do not need individual affine transformations this is a ; penalty. A list of Primitives is therefore more suitable 2 representation, and a Hughes list which supports " efficient concatenation is wise. *NOTE - currently HPrim has a phantom unit u, this is so > trace drawings can have a unit type, but this may change as  perhaps trace drawings don't benefit from having units. 3CatPrim could probably manage happily just being a . Primitive, but it is wrapped as a newtype... GHC highly unstablestephen.tetley@gmail.com-Map the answer produced by a graphic object. ;Note - the new answer must share the same unit type as the < initial answer, although it does not need to have the same  wrapper type. 1Replace the answer produced by a graphic object. ;Note - the new answer must share the same unit type as the < initial answer, although it does not need to have the same  wrapper type. 4Turn an imageAns into a GraphicAns by ignoring the  result. 3Usually this function will be used with one of the push  family of combinators. , LocImage-to-LocGraphic = pushR1 ignoreAns +Extractor for the answer part of an image. 4Note - maybe this requires an arity family instead? Clip a graphic object. 4Note - maybe this requires an arity family instead?  Downcast a LocCF* function by applying it to the supplied 0 point, making an arity-zero Context Function.  Remember a LocCF function is a CF1 context function where  the static argument" is specialized to a start point.  Downcast a ! function by applying it to the : supplied angle, making an arity-one Context Function (a  LocCF). 9Downcast a LocThetaQuery function by applying it to the B supplied point and angle, making an arity-zero Context Function  (a CF).  Downcast a ! function by applying it to the = start and end point, making an arity-zero Context Function  (a w). Replace the ans - arity 0. Replace the ans - arity 1. Replace the ans - arity 2. .Decorate an Image by superimposing a Graphic. ;Note - this function has a very general type signature and ! supports various graphic types: .Decorate an Image by superimposing a Graphic. ;Note - this function has a very general type signature and ! supports various graphic types: .Decorate an Image by superimposing a Graphic. ;Note - this function has a very general type signature and ! supports various graphic types: GHC highly unstablestephen.tetley@gmail.com     Concatenation with movement - the second object is moved  next to the first.  / hconcat is equivalent to @(<>)@ in WL-PPrint.  (infixr 6) 0 vconcat is equivalent to @(<$>)@ in WL_PPrint.  (infixr 5) Minimal defintion is ,  is usually   flip superior.   `superior` (infixr 6)  `anterior` (infixr 6) ,Horizontally concatenate a list of objects.  Note - the first argument is an  alternative - this is drawn 2 if the list is empty, otherwise it is not drawn. *Vertically concatenate a list of objects.  Note - the first argument is an  alternative - this is drawn 2 if the list is empty, otherwise it is not drawn.                       GHC highly unstablestephen.tetley@gmail.com-!!# is a type representing functions  from Radian * Point to Point. <It is useful for building arrowheads which are constructed @ with an implicit angle representing the direction of the line  at the arrow tip. ""# is a type representing functions  from Radian to Radian. ?It is especially useful for building composite graphics where @ one part of the graphic is drawn from a different start point  to the other part. ### is a type representing functions  from Point to Point. ?It is especially useful for building composite graphics where @ one part of the graphic is drawn from a different start point  to the other part. $Move the start-point of a  with the supplied  displacement function. %Move the start-point of a  with the supplied  displacement function. &Move the start-point of a  LocThetaCF with the supplied  displacement function. 'Change the inclination of a  LocThetaCF with the supplied  displacement function. (( :  x -> y -> PointDisplace  Build a combinator to move Points by the supplied x and  y distances. )+ :  (V2 x y) -> PointDisplace   Version of (' where the displacement is supplied as & a vector rather than two parameters. ** :  x -> PointDisplace  Build a combinator to move Points by horizontally the  supplied x distance. ++ :  y -> PointDisplace  Build a combinator to move Points vertically by the supplied  y distance. ,-./0123456789:;<< :  dist -> ThetaPointDisplace  Build a combinator to move Points in parallel to the ; direction of the implicit angle by the supplied distance  dist. =< :  dist -> ThetaPointDisplace  Build a combinator to move Points perpendicular to the < inclnation of the implicit angle by the supplied distance  dist. >> :  vec -> ThetaPointDisplace  This is a combination of displaceParallel and  displacePerpendicular%, with the x component of the vector 5 displaced in parallel and the y component displaced  perpendicular. ?@ABCDEFGAbsolute units. HValue is 1 snap unit right. 8This function should be considered obsolete, pending a  re-think. IValue is 1 snap move left. 8This function should be considered obsolete, pending a  re-think. J,Value is 1 snap move up, 1 snap move right. 8This function should be considered obsolete, pending a  re-think. K/Value is 1 snap move below, 1 snap move right. 8This function should be considered obsolete, pending a  re-think. L+Value is 1 snap move up, 1 snap move left. 8This function should be considered obsolete, pending a  re-think. M-Value is 1 snap move down, 1 snap move left. 8This function should be considered obsolete, pending a  re-think. -!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLM-#"!$%&'()*+,-./0123456789:;<=>?@ABCDEFGIHLJMK-!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMGHC highly unstablestephen.tetley@gmail.comNType specialized version of P. OType specialized version of Q. P9Graphic - function from the DrawingContext to a graphic   primitive. Q;Image - function from the DrawingContext to a polymorphic  answer and a graphic  primitive. (The answer is expected to be a Functor. RR :  query * graphic -> Image   Build an Q from a context function (w) that generates  the answer and a P that draws the Q. SDowncast an Q to a P. =This means forgetting the answer of the Image, replacing it  with (). TUse this to convert P or Q with Functor answer. UNOPQRSTUPQONRSTUNOPQRSTUGHC highly unstablestephen.tetley@gmail.comVType specialized version of X. WType specialized version of Y. X>LocGraphic - function from DrawingContext and start point to  a graphic  primitive. Y=Graphic - function from DrawingContext and start point to a  polymorphic answer and a graphic  primitive. (The answer is expected to be a Functor. ZZ : % loc_query * loc_graphic -> LocImage  Loc version of  intoImage. The Y0 is built as a function from an implicit start  point to the answer. [Downcast an Y to a X. @This means forgetting the answer of the LocImage, replacing it  with (). \\ :  LocGraphic  Build an empty X (i.e. a function  from Point to Graphic&). This is a path with a start point  but no path segments. The \ is treated as a null primitive by   Wumpus-Core0 and is not drawn, although it does generate a 3 minimum bounding box at the implicit start point. ]Use this to convert X or Y with Functor  answer. ^Use this to convert Y with unit-less answer. _`abThis is analogue to  replicate in the Prelude. cdVWXYZ[\]^_`abcdXYWVZ[\]^_`abcdVWXYZ[\]^_`abcdGHC highly unstablestephen.tetley@gmail.comefghAdvance vector& graphic - this partially models the  PostScript show command which moves the  current point by the 4 advance (width) vector as each character is drawn. ii : - loc_context_function * graphic -> AdvObject   Build an h from a context function (w) that 0 generates the answer displacement vector and a X  that draws the h. jemptyAdvObjectAU :  AdvObject  Build an empty h. The j is treated as a null primitive by   Wumpus-Core2 and is not drawn, the answer vector generated is  the zero vector (V2 0 0). klPrimitive combination. <Move second object by the advance vector of the first. Sum  both advance vecots. m8Draw the first AdvObject and use the advance vector to  displace the second AdvObject. 5The final answer is the sum of both advance vectors. n(Concatenate the list of AdvObjects with m. o7Combine the AdvObjects using the answer vector of the A first object plus the separator to move the start of the second  object. pList version of  nextSpace. qRepeat the AdvObject n times, moving each time with  m. r:Concatenate the list of AdvObjects, going next and adding  the separator at each step. s;Render the supplied AdvObject, but swap the result advance @ for the supplied vector. This function has behaviour analogue  to fill in the  wl-pprint library. efghijklmnopqrshgfeijklmnopqrsefghijklmnopqrsGHC highly unstablestephen.tetley@gmail.comtuChain algorithm. Linear simply iterates points. Prefix runs the left chain n times then runs the right - chain from the end point of the left chain. -Note the tail of of result list is infinite. :As any prefixes will be generated fully. This potentially  produces a  space bubble where a long prefix has to be > generated without the streaming of lazy evaluation. However, < chains that are long enough to cause this problem will be / problematic for a PostScript or SVG renderer. In short - don't make long chains. :Take n elements - also return the last of element in the 9 tuple so it can be accessed without a second traversal. Note (n > 0) vReturns the end point... wReturns no answer, just a X. xyz{|}~Outer and inner steppers.  tuvwxyz{|}~ utvwxyz{|}~ tuvwxyz{|}~GHC highly unstablestephen.tetley@gmail.com Type specialized version of . Type specialized version of . ?ConnectorGraphic - function from DrawingContext and start and  end points to a graphic  primitive. =ConnectorImage - function from DrawingContext and start and  end points to a polymorphic answer and a graphic  primitive.  : ' conn_query * conn_graphic -> LocImage   Connector version of  intoImage. The * is built as a function from an implicit % start and end points to the answer. Downcast an  to a . =This means forgetting the answer of the Image, replacing it  with ().  :  ConnectorGraphic  Build an empty . The  is treated as a null primitive by   Wumpus-Core0 and is not drawn, although it does generate a @ bounding box around the rectangular hull of the start and end  points. Use this to convert  or   with Functor answer. Use this to convert  with unit-less answer.   GHC highly unstablestephen.tetley@gmail.com Type specialized version of . Type specialized version of . =LocThetaGraphic - function from DrawingContext, start point  and inclination to a graphic  primitive (GraphicAns). . - function from DrawingContext, start point " and inclination to a polymorphic answer and a graphic   primitive (ImageAns). (The answer is expected to be a Functor.  : 6 loc_theta_query * loc_theta_graphic -> LocThetaImage  LocTheta version of  intoImage. The * is built as a function from an implicit 5 start point and angle of inclination to the answer. Downcast an  to a . =This means forgetting the answer of the Image, replacing it  with ().  :  LocThetaGraphic  Build an empty  (i.e. a function  %from Point and Inclination to Graphic). The  is treated as a null primitive by   Wumpus-Core0 and is not drawn, although it does generate a 3 minimum bounding box at the implicit start point. Use this to convert  or   with Functor answer. Use this to convert  with unit-less answer.   GHC highly unstablestephen.tetley@gmail.com.9Unit parametric version of KerningChar from Wumpus-Core.  :  [next_vector] -> LocQuery PrimPath  Create a path  - i.e. a functional type  from Point to PrimPath. This is the analogue to  vectorPath in  Wumpus-Core , but the  result is produced within the DrawingContext.  :  (Point ~> PrimPath)  Create an empty path  - i.e. a functional type  from Point to PrimPath. This is the analogue to  emptyPath in  Wumpus-Core , but the  result is produced within the DrawingContext.  :  (Point ~> PrimPath)  >Create a PrimPath made of straight line segments joining the  supplied points. This is the analogue to  in  Wumpus-Core, but  it is polymorphic on unit.  :  (Point ~> PrimPath)  2Create a path made of curve segments joining the  supplied points. This is the analogue to  in  Wumpus-Core, but  it is polymorphic on unit.  :  path -> Graphic  This is the analogue to  in  Wumpus-core , but the ? drawing properties (colour, line width, etc.) are taken from  the implicit DrawingContext.  :  path -> Graphic  This is the analogue to  in  Wumpus-core , but the ? drawing properties (colour, line width, etc.) are taken from  the implicit DrawingContext.  :  path -> Graphic  This is the analogue to  in  Wumpus-core , but the ( fill colour is taken from the implicit DrawingContext.  :  path -> Graphic  This is the analogue to  in  Wumpus-core , but the > drawing properties (fill colour, border colour, line width, # etc.) are taken from the implicit DrawingContext.  :  string -> LocGraphic  Create a text X - i.e. a functional type  from Point to Graphic. ;The implicit point of the LocGraphic is the baseline left. This is the analogue to  in  Wumpus-core , but the A text properties (font family, font size, colour) are taken from  the implicit DrawingContext.  :  string -> LocThetaGraphic  Create a text  - i.e. a functional type  from Point and Angle to Graphic. ?The implicit point of the LocGraphic is the baseline left, the 0 implicit angle is rotation factor of the text. @Note - rotated text often does not render well in PostScript or - SVG. Rotated text should be used sparingly. This is the analogue to  in  Wumpus-core.  escTextline :  escaped_text -> LocGraphic  Create a text X - i.e. a functional type  from Point to Graphic. ;The implicit point of the LocGraphic is the baseline left. This is the analogue to  in  Wumpus-core, but A the text properties (font family, font size, colour) are taken  from the implicit DrawingContext.  : ! escaped_text -> LocThetaGraphic  Create a text  - i.e. a functional type  from Point and Angle to Graphic. ?The implicit point of the LocGraphic is the baseline left, the 0 implicit angle is rotation factor of the text. @Note - rotated text often does not render well in PostScript or - SVG. Rotated text should be used sparingly. This is the analogue to  in  Wumpus-core, but A the text properties (font family, font size, colour) are taken  from the implicit DrawingContext.  :  [kern_char] -> LocGraphic  "Create a horizontally kerned text X - i.e. a  functional type from Point to Graphic. ;The implicit point of the LocGraphic is the baseline left. This is the analogue to  in  Wumpus-core, but A the text properties (font family, font size, colour) are taken  from the implicit DrawingContext.  :  [kern_char] -> LocGraphic   Create a vertically kerned text X - i.e. a  functional type from Point to Graphic. ;The implicit point of the LocGraphic is the baseline left. This is the analogue to  in  Wumpus-core, but A the text properties (font family, font size, colour) are taken  from the implicit DrawingContext.  : ' start_point * end_point -> LocGraphic  Create a straight line P, the start and end point  are supplied explicitly. =The line properties (colour, pen thickness, etc.) are taken  from the implicit DrawingContext.  :  vec_to -> LocGraphic  Create a stright line X - i.e. a functional type  from Point to Graphic. >The implicit point of the LocGraphic is the start point, the A end point is calculated by displacing the start point with the  supplied vector. =The line properties (colour, pen thickness, etc.) are taken  from the implicit DrawingContext.  curveLine : ! start_point * control_point1 * . control_point2 * end_point -> Graphic  Create a Bezier curve P, all control points are  supplied explicitly. =The line properties (colour, pen thickness, etc.) are taken  from the implicit DrawingContext.  : & start_point * end_point -> Connector  Create a straight line P, the start and end point  are supplied implicitly. =The line properties (colour, pen thickness, etc.) are taken  from the implicit DrawingContext. Helper for circle drawing.  :  radius -> LocGraphic  Create a stroked circle X - the implicit point is 7 center. The circle is drawn with four Bezier curves. =The line properties (colour, pen thickness, etc.) are taken  from the implicit DrawingContext.  :  radius -> LocGraphic  Create a filled circle X - the implicit point is 7 center. The circle is drawn with four Bezier curves. +The fill colour is taken from the implicit DrawingContext.  :  radius -> LocGraphic  Create a bordered circle X - the implicit point is 7 center. The circle is drawn with four Bezier curves. >The background fill colour and the outline stroke properties  are taken from the implicit DrawingContext. Helper for ellipse drawing. Helper for ellipse drawing.  : # x_radius * y_radius -> LocGraphic  Create a stroked ellipse X - the implicit point is 8 center. The ellipse is drawn with four Bezier curves. =The line properties (colour, pen thickness, etc.) are taken  from the implicit DrawingContext.  : ( x_radius * y_radius -> LocThetaGraphic  Create a stroked ellipse  - the implicit point < is center and the angle is rotation about the center. The , ellipse is drawn with four Bezier curves. =The line properties (colour, pen thickness, etc.) are taken  from the implicit DrawingContext.  : # x_radius * y_radius -> LocGraphic  Create a filled ellipse X - the implicit point is 8 center. The ellipse is drawn with four Bezier curves. +The fill colour is taken from the implicit DrawingContext.  : # x_radius * y_radius -> LocGraphic  Create a filled ellipse  - the implicit point < is center and the angle is rotation about the center. The - ellipse is drawn with four Bezier curves. +The fill colour is taken from the implicit DrawingContext.  : # x_radius * y_radius -> LocGraphic  Create a bordered ellipse X - the implicit point is 8 center. The ellipse is drawn with four Bezier curves. >The background fill colour and the outline stroke properties  are taken from the implicit DrawingContext.  : # x_radius * y_radius -> LocGraphic  Create a bordered ellipse  - the implicit point < is center and the angle is rotation about the center. The - ellipse is drawn with four Bezier curves. >The background fill colour and the outline stroke properties  are taken from the implicit DrawingContext. Supplied point is  bottom-left.  :  width * height -> LocGraphic  Create a stroked rectangle X - the implicit point is  bottom-left. =The line properties (colour, pen thickness, etc.) are taken  from the implicit DrawingContext.  :  width * height -> LocGraphic  Create a filled rectangle X - the implicit point is  the bottom-left. +The fill colour is taken from the implicit DrawingContext.  :  width * height -> LocGraphic  Create a bordered rectangle X - the implicit point is  bottom-left. >The background fill colour and the outline stroke properties  are taken from the implicit DrawingContext.  :  radius -> LocGraphic  Create a stroked circle X - the implicit point is  the center. 5This is a efficient representation of circles using  PostScript's arc or SVG's circle in the generated : output. However, stroked-circles do not draw well after ; non-uniform scaling - the pen width is scaled as well as  the shape. 8For stroked circles that can be adequately scaled, use   instead. =The line properties (colour, pen thickness, etc.) are taken  from the implicit DrawingContext.  :  radius -> LocGraphic  Create a filled circle X - the implicit point is  the center. 5This is a efficient representation of circles using  PostScript's arc or SVG's circle in the generated ; output. As the circle is filled rather than drawn with a  "pen" a  filledDisk can be scaled. +The fill colour is taken from the implicit DrawingContext.  :  radius -> LocGraphic  Create a bordered circle X - the implicit point is  the center. 5This is a efficient representation of circles using  PostScript's arc or SVG's circle in the generated = output. However, bordereded circles do not draw well after B non-uniform scaling - the pen width of the outline is scaled as  well as the shape. 9For bordered circles that can be adequately scaled, use   instead. >The background fill colour and the outline stroke properties  are taken from the implicit DrawingContext.  : # x_radius * y_radius -> LocGraphic  Create a stroked ellipse X - the implicit point is  the center. 5This is a efficient representation of circles using  PostScript's arc or SVG's ellipse in the generated ; output. However, stroked ellipses do not draw well after ; non-uniform scaling - the pen width is scaled as well as  the shape. 9For stroked ellipses that can be adequately scaled, use   instead. =The line properties (colour, pen thickness, etc.) are taken  from the implicit DrawingContext.  : # x_radius * y_radius -> LocGraphic  Create a filled ellipse X - the implicit point is  the center. 6This is a efficient representation of ellipses using  PostScript's arc or SVG's ellipse in the generated < output. As the ellipse is filled rather than drawn with a  "pen" a filledEllipseDisk can be scaled. +The fill colour is taken from the implicit DrawingContext.  : # x_radius * y_radius -> LocGraphic  Create a bordered ellipse X - the implicit point is  the center. 6This is a efficient representation of ellipses using  PostScript's arc or SVG's ellipse in the generated > output. However, bordereded ellipses do not draw well after B non-uniform scaling - the pen width of the outline is scaled as  well as the shape. :For bordered ellipses that can be adequately scaled, use   instead. >The background fill colour and the outline stroke properties  are taken from the implicit DrawingContext. %%%GHC highly unstablestephen.tetley@gmail.com %LocThetaGraphic with a bounding box. &Note the size of bounding box for the "same" shape will vary 6 according to the rotation. A bounding box is always ' orthonormal (?) to the x- and y-axes.  LocGraphic with a bounding box. Graphic with a bounding box.  :  theta * bbox -> BBox  Rotate a bounding box by theta about its center. Take the  new bounding box. @Remember that bounding boxes are always orthonormal rectangles, > so the dimensions as well as the positions may change under  rotation.  :  BoundedLocGraphic  Build an empty . The  is treated as a null primitive  by  Wumpus-Core- and is not drawn, although it does generate 9 the minimum bounding box with both the bottom-left and 2 upper-right corners at the implicit start point.  :  BoundedLocThetaGraphic  Build an empty . The  is treated as a null primitive  by  Wumpus-Core- and is not drawn, although it does generate 9 the minimum bounding box with both the bottom-left and @ upper-right corners at the implicit start point (the implicit  inclination can be ignored). 6Draw a BoundedGraphic, illustrating the bounding box. 9Draw a BoundedLocGraphic, illustrating the bounding box. >Draw a BoundedLocThetaGraphic, illustrating the bounding box.    GHC highly unstablestephen.tetley@gmail.com64Utility datatype representing orientation within a  rectangular frame*. RectPos is useful for graphics such as > text where the start point is not necessarily at the center  (or bottom left).  E x_minor is the horizontal distance from the left to the start point  F x_major is the horizontal distance from the start point to the right  E y_minor is the vertical distance from the bottom to the start point  B y_major is the vertical distance from the start point to the top "Values should be not be negative! ?Datatype enumerating the addressable positions of a rectangle  that can be derived for a  PosObject. >Concatenation here essentially turns both Orientation objects  into  center-form# then finds the maximum rectangle. 7Find the half-width and half-height of an Orientation. Essentially this is  center-form of an Orientation, but  in  center-form there is duplication:   xminor == xmajor  yminor == ymajor ,So instead, the result type is just a pair. The vector from a  to the start point. 2Calculate the bounding box formed by locating the   at the supplied point. Second Orientation is moved  to the right of the first along  the spine i.e the baseline. Second Orientation is moved below the first along the spine @ i.e. the vertical point between the left minor and right major * (not the same as the horizontal center). xmin and xmaj same as left. xmin same as left. xmin and ymaj same as left. 5Align second below - xmin and ymaj are same as left. (Align second below - ymaj same as left. 5Align second below - xmaj and ymaj are same as left. Move second right. Move second below. 000  GHC highly unstablestephen.tetley@gmail.com!>Version of PosObject specialized to Double for the unit type. A positionable "Object" that is drawn as a  . *Helper for PosObject - a LocImage that is  pre-applied to  the DrawingContext. ?This is somewhat contrived, but the orientation and the result ? graphic from a PosImage have to be generated within the same  DrawingContext.  : % object_pos * loc_image -> PosObject   Create a  from an  describing how it / is orientated within a border rectangle and a Y that  draws it.  This is the primary) constructor for PosObjects. Because the > PosObject type is considered as a specialized object it does ? not have the range of functions of LocImage or LocThetaImage. 6This is a bit of a hack to overcome that the newtype 8 wrapper around PosObject stops monadic bind operating  with the internal CF function.  :  PosObject  Build an empty PosGraphicObject. %Run a PosObject forming an Image (an  arity zero answer).  Version of  runPosObject that produces a  . The / is run with only rect-address as an explicit B argument (start-point is implicit). The corresponding answer is  an  arity one2 Graphic that needs drawing with the start-point.  Version of  runPosObject that produces a  . The 2 is run with no explicit arguments (rect-address 3 or start-point) so the corresponding answer is an  arity two 6 Graphic that needs drawing with the start-point and  rect-address. %Run a DrawingContext update within a . decorate -like functionality. ante-eloborate  : 2 bounded_loc_rect * rect_pos -> BoundedlocGraphic  Downcast a  to a   by supplying it with a  (start address on the  rectangle frame).  : , bounded_loc_rect * start_point * rect_pos  -> BoundedGraphic  Downcast a  to a  by * supplying it with an initial point and a  (start " address on the rectangle frame). Extend the orientation.      Illustrate a  by super-imposing its . This turns the  into a Y drawn at the locus  of the PosObject.              !GHC unstablestephen.tetley@gmail.com!  9Collect elementary graphics as part of a larger drawing. 'TraceM works much like a writer monad. <Run the drawing returning only the output it produces, drop * any answer from the monadic computation. =Run the drawing ignoring the output it produces, return the & answer from the monadic computation. >Note - this useful for testing, generally one would want the : opposite behaviour (return the drawing, ignore than the  answer). Unsafe promotion of HPrim to Picture. 3If the HPrim is empty, a run-time error is thrown. Safe promotion of HPrim to (Maybe Picture). If the HPrim is empty, then Nothing is returned. Unsafe promotion of (Maybe Picture) to Picture. This is equivalent to:  ! fromMaybe (error "empty") $ pic ;This function is solely a convenience, using it saves one  import and a few characters. If the supplied value is Nothing a run-time error is thrown. 2Draw a Graphic taking the drawing style from the  drawing context. This function is the  forgetful version of .  Commonly, it is used to draw P objects which  have no answer. 1Draw an Image taking the drawing style from the  drawing context. ?The graphic representation of the Image is drawn in the Trace $ monad, and the result is returned. ;Draw a LocImage at the supplied Anchor taking the drawing  style from the drawing context. This function is the  forgetful version of  .  Commonly, it is used to draw X objects which  have no answer.  :Draw a LocImage at the supplied Point taking the drawing  style from the drawing context. ?The graphic representation of the Image is drawn in the Trace $ monad, and the result is returned. !>Draw a ConnectorGraphic with the supplied Anchors taking the  drawing style from the drawing context. This function is the  forgetful version of ".  Commonly, it is used to draw  objects which  have no answer. ";Draw a ConnectorImage with the supplied Points taking the  drawing style from the drawing context. ?The graphic representation of the Image is drawn in the Trace $ monad, and the result is returned. #8Draw the object with the supplied grid coordinate. The - actual position is scaled according to the  snap_grid_factors in the drawing context. This function is the  forgetful version of $.  Commonly, it is used to draw X objects which  have no answer. $8Draw the object with the supplied grid coordinate. The - actual position is scaled according to the  snap_grid_factors in the drawing context. %<Draw a connector between two objects. The projection of the ? connector line is drawn on the line from center to center of @ the objects, the actual start and end points of the drawn line > are the radial points on the objects borders that cross the  projected line. This function is the  forgetful version of &.  Commonly, it is used to draw X objects which  have no answer. &<Draw a connector between two objects. The projection of the ? connector line is drawn on the line from center to center of @ the objects, the actual start and end points of the drawn line > are the radial points on the objects borders that cross the  projected line.    !"#$%&   !"#$%&   !"#$%&"GHC unstablestephen.tetley@gmail.com'A  Contextual Picture.  . CtxPicture = DrawingContext -> Maybe Picture This type corresponds to the  type in Wumpus-Core, but  it is embedded with a ba (for font properties, @ fill colour etc.). The DrawingContext is embedded so that font  metrics - loaded in IO& can be passed into the pure world of  .  Internally a context picture is a function from  ba to (Maybe Picture). The Maybe represents > that it is possible to construct empty Pictures, even though   Wumpus-Core0 cannot render them. Just as the DrawingContext > pushes font-metrics from the IO to the pure world, the Maybe ? lifts the problem of unrenderable Pictures into the API where , client code must deal with it explicitly. ?(In practice, it is very unlikely a program will create empty  pictures and runCtxPictureU can be used without worry). &Note - pictures are fixed to the unit Double (representing A PostScript points). Pictures are intentionally unsophisticated, ? any fine grained control of units should be delegated to the A elements that build the picture (Graphics, LocGraphics, etc.). (( : , drawing_ctx * ctx_picture -> Maybe Picture  Run a ' with the supplied ba  producing a . 8The resulting Picture may be empty. Wumpus-Core cannot ? generate empty pictures as they have no bounding box, so the A result is wrapped within a Maybe. This delegates reponsibility - for handling empty pictures to client code. )) : & drawing_ctx * ctx_picture -> Picture  Unsafe version of (. ;This function throws a runtime error when supplied with an  empty CtxPicture. ** :  trace_drawing -> CtxPicture   Transform a  into a '. ++ : 2 scalar_unit_value * trace_drawing -> CtxPicture   Variant of *& with a phantom first argument - the ) phantom identifies the unit type of the  . It is % not scurtinized at the value level. ,, : # trafo * ctx_picture -> CtxPicture  /Apply a picture transformation function to the   warpped in a '. -Draw a, move b) so its center is at the same center as  a, b) is drawn over underneath in the zorder.  a `cxpUniteCenter` b   a `cxpRight` b *Horizontal composition - position picture b to the right of  picture a.   a `cxpBelow` b (Vertical composition - position picture b down from picture  a. .*Center the picture at the supplied point.   cxpRightSep n a b Horizontal composition - move b, placing it to the right  of a with a horizontal gap of n separating the pictures.    cxpDownSep n a b Vertical composition - move b, placing it below a with a  vertical gap of n separating the pictures. !  cxpAlignH align a b Horizontal composition - move b, placing it to the right  of a0 and align it with the top, center or bottom of a. "  cxpAlignV align a b Vertical composition - move b, placing it below a 0 and align it with the left, center or right of a. #  cxpAlignSpaceH align sep a b Spacing version of ! - move b to the right of a  separated by sep units, align b according to align. $  cxpAlignSpaceV align sep a b !Spacing version of alignV - move b below a  separated by sep units, align b according to align. %  a `oplus` b Place 'drawing' a over b. The idea of over here is in = terms z-ordering, nither picture a or b are actually moved. '()*+,-.'()*+,-.'()*+,-.+GHC highly unstablestephen.tetley@gmail.comW !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-.#GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>/&'01234 Promote an IO action into the the  FontLoadIO monad. This function is equivalent to liftIO. 567The standard monadic sequence would finish on first fail = for the FontLoadIO monad. As we want to be able to sequence 9 the loading of a list of fonts, this is not really the B behaviour we want for Wumpus. Instead we prefer to use fallback @ metrics and produce an inaccurate drawing on a font load error * rather than fail and produce no drawing. (88Afm files do not have a default advance vec so use the  monospace default. Afm files hopefully have  CapHeight and FontBBox properties < in the header. Use the monospace default only if they are  missing. )*+9 /0123456789 /0123456789 /0123456789$GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>:: :   path_to_afm_fonts * [font_name] -> IO FontLoadResult  "Load the supplied list of fonts. <Note - if a font fails to load a message is written to the  log and monospaced fallback metrics are used. ;; :  3 path_to_afm_fonts * font_def -> IO FontLoadResult  Load a single AFM font. >Note - if the font fails to load a message is written to the  log and monospaced fallback metrics are used. ,->These are values extracted from Courier in the core 14 fonts. :;:;:;%GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com><< :   path_to_gs_fonts * [font_name] -> IO FontLoadResult  "Load the supplied list of fonts. <Note - if a font fails to load a message is written to the  log and monospaced fallback metrics are used. == :  3 path_to_gs_fonts * font_name -> IO FontLoadResult  !Load a single GhostScript font. >Note - if the font fails to load a message is written to the  log and monospaced fallback metrics are used. ./)These are values extracted from the file  n022003l.afm  which is the font NimbusMonL-Regu , GhostScript' s eqivalent $ font for the core 14 font Courier. <=<=<=&GHC highly unstablestephen.tetley@gmail.com >4A FontLoader is an action from a list of fonts to a   returned in IO.  Fonts are supplied in a list of Either FontDef FontFamily, > this is a little cumbersome but it allows the loader to load  individual fonts and /' or a whole families with a single API  call. 06Environment variable pointing to the GhostScript font  directory.  WUMPUS_GS_FONT_DIR 1:Environment variable pointing to the diretory containing  the Adobe Font Metrics files.  WUMPUS_AFM_FONT_DIR ?@A/Tries to find the GhostScript metrics first... 2Runs the IO action on the loader if it finds one. ,Either of one of the environment variables  WUMPUS_AFM_FONT_DIR or WUMPUS_GS_FONT_DIR must be defined + and point to their respective directory. 23B>?@AB>?@AB>?@AB'GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>CDEFGHH :  ang -> Quadrant  Get the quadrant of an angle. II :  ang -> Radian  8Modulo an angle so it lies in quadrant I (north east),  i.e. modulo into the range 0..(pi/2). 456JJ : ' half_width * half_height * ang -> Vec  @Find where a radial line extended from (0,0) with the elevation  ang; intersects with an enclosing rectangle. The rectangle is  centered at (0,0). ?Internally the calculation is made in quadrant I (north east), > symmetry is used to translate result to the other quadrants. KK :  width * height * ang -> Vec  *Find where a line from (0,0) in direction ang intersects the ; top or right side of a rectangle in QI (left side is the " y-axis, bottom is the x-axis). / ang must be in the @range 0 < ang <= 90 deg@.  $ width and height must be positive. LL : ' half_width * half_height * ang -> Vec  @Find where a radial line extended from (0,0) with the elevation  ang7 intersects with an enclosing diamond. The diamond is  centered at (0,0). ?Internally the calculation is made in quadrant I (north east), > symmetry is used to translate result to the other quadrants. MM : # half_base_width * height_minor * " height_minor * ang -> Vec  @Find where a radial line extended from (0,0) with the elevation  ang: intersects with an enclosing triangle. The triangle has @ the centroid at (0,0), so solutions in quadrants I and II are > intersections with a simple line. Intersections in quadrants = III and IV can intersect either the respective side or the  base. NN :  width * height * ang -> Vec  ,Find where a line from (0,0) with elevation ang intersects B the hypotenuse a right triangle in QI (the legs of the triangle  take the x and y-axes). + ang must be in the @range 0 < ang <= 90@.  $ width and height must be positive. OO : + top_width * height * top_right_ang -> Vec  ,Find where a line from (0,0) with elevation ang intersects > the either the lines A_B or B_D in a right trapezoid in QI. @The right trapezoid has a variable right side. Left side is the = y-axis (C_A), bottom side is the x-axis (C_D), top side is  parallel to the x-axis (A_B).   A B  -----  | \  | \  -------  C D   A B  -------  | /  | /  -----  C D ) ang must be in the range 0 < ang <= 90.  ( top_width and height must be positive. 7traingleLeftSide : - base_width * left_ang * right_ang -> Length     C  /\  / \  / \  / \  /________\  A B  < Calculate A_C given side A_B, angle C/A\B and angle A/B\C. PP : . top_width * height * top_right_ang -> Length  !Find the length of the line C_D:   A B  -----  | \  | \  -------  C D  A B  -------  | /  | /  -----  C D CDEFGHIJKLMNOPCGFEDHIJKLMNOPCGFEDDEFGHIJKLMNOP(GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>(QRA Strict cubic Bezier curve. STUVWXLine in equational form, i.e. Ax + By + C = 0. YZ[\]^02x2 matrix, considered to be in row-major form.  (M2'2 a b  c d) _`ab8c#Construct the identity 2x2 matrix:  (M2'2 1 0  0 1 ) dDeterminant of a 2x2 matrix. eTranspose a 2x2 matrix. ff : ! point1 * point2 -> LineEquation  <Construct a line in equational form bisecting the supplied  points. gg :  x * line_equation -> Point  1Calculate the point on the line for the supplied x value. hh :  y * line_equation -> Point  1Calculate the point on the line for the supplied y value. ii :  point -> line -> Distance  <Find the distance from a point to a line in equational form  using this formula:   P(u,v)  L: Ax + By + C = 0   (A*u) + (B*v) + C  -----------------  sqrt $ (A^2) +(B^2) <A positive distance indicates the point is above the line,  negative indicates below. jj : ) half_width * half_height -> [LineSegment]  *Compute the line segments of a rectangle. kk :  [point] -> [LineSegment]  5Build the line segments of a polygon fome a list of  its vertices. ll : ( start_point * control_1 * control_2 *  end_point -> Length  5Find the length of a Bezier curve. The result is an  approximation, with the  tolerance is 0.1 of a point. This A seems good enough for drawing (potentially the tolerance could  be larger still). 9The result is found through repeated subdivision so the $ calculation is potentially costly. 9 Jens Gravesen'$s bezier arc-length approximation. =Note this implementation is parametrized on error tolerance. :6Length of the tree lines spanning the control points. ;/Length of the cord - start point to end point. m"Curve subdivision via de Casteljau' s algorithm. n2subdivide with an affine weight along the line... <oo : 2 apex_angle * radius * rotation * center -> [Point]   . ang should be in the range 0 < ang < 360deg. & if 0 < ang <= 90 returns 4 points & if 90 < ang <= 180 returns 7 points ' if 180 < ang <= 270 returns 10 points ' if 270 < ang < 360 returns 13 points pp : 8 apex_angle * radius * rotation * center -> BezierCurve  . ang should be in the range 0 < ang <= 90deg. qAffine combination... rr : % start_point * end_point -> Midpoint  >Mid-point on the line formed between the two supplied points. ss : " start_point * end_point -> Angle  ?Calculate the counter-clockwise angle between the line formed - by the two points and the horizontal plane. #QRSTUVWXYZ[\]^_`abcdefghijklmnopqrs#`ab^_]cdeXYZ[\WfghiUVTjkRSQlmnopqrs#QRSSTUVVWXYZ[\YZ[\]^__`abcdefghijklmnopqrs)GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com> tt :  line1 * line2 -> Maybe Point  6Find the intersection of two lines, if there is one. <Lines are infinite they are represented by points on them,  they are not line segments.  An answer of Nothing( may indicate wither the lines coincide  or the are parallel. uu : . line_segment1 * line_segment2 -> Maybe Point  >Find the intersection of two line segments, if there is one.  An answer of Nothing# indicates that the line segments - coincide, or that there is no intersection. vv : $ line_segment * line -> Maybe Point  >Find the intersection of a line and a line segment, if there  is one.  An answer of Nothing& indicates that the the line and line 5 segment coincide, or that there is no intersection. =>Check the point is "within" the span of the line. #Note - this function is to be used *after* an intersection ) has been found. Hence it is not export. ?@wAIs the curve cut by the line? ?The curve might cut at the start or end points - which is good @ as it saves performing a subdivision. But make the return type  a bit involved. xx :: & radial_origin * theta * [line_segment] -> Maybe Point  .Find the first intersection of a line through  radial_origin  at angle theta+ and the supplied line segments, if there  is one. B9The tolerance on Radian equality should be acceptable... yy :  point * ang -> Line  Make an infinite line /% plane passing through the supplied  with elevation ang. tuvwxytuvwxytuvwxy*GHChighly unstable)Stephen Tetley <stephen.tetley@gmail.com>zA functional type from  initial point to point list. { A vector chain building a path. 4The vectors are relative to the predecessor, so the  rendering of a { iterates the start point. :A polygon PathAlg should have steps for all sides of the : polygon with the end point generated by the last vector # coinciding with thet start point. CDEFGH|}~<Note this creates a path very the first vector represents a  moveto), then the subsequence vectors represent linetos. Supplied point is center, the genearated points are ' counter-clockwise so [ bl, br, tr, tl ] . Supplied point is  bottom-left, subsequent points are ' counter-clockwise so [ bl, br, tr, tl ] .  : % half_width * half_height -> PathAlg   :  num_points * radius -> PathAlg  I1Helper - generate four vectors building a minor (< 90 deg)  arc. @The first vec is from center - for cumulative arcs this should  only taken once. JHelper - diff 7Note diff relies on the pointlist cycling the endpoint   [p0, ..., p0] 2This is how Wumpus-Core generates Bezier circles. K6Helper - divide an arc into quadrants plus remainder. Relative unit version of coordinatePrimPathAU. Supplied point is  bottom-left, subsequenct points are ' counter-clockwise so [ bl, br, tr, tl ] .  diamondPath : 5 half_width * half_height * center_point -> PrimPath   : ' num_points * radius * center -> [point]   isocelesTriangle bw h pt<Supplied point is the centriod of the triangle. This has a . nicer visual balance than using half-height.  isocelesTriangle bw h pt<Supplied point is the centriod of the triangle. This has a . nicer visual balance than using half-height.   side_length * ctr -> [Points]z{|}~{|}~zz{|}~,GHC highly unstablestephen.tetley@gmail.comLCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~L-./0123456789:;<=>?@ABCDEFGHIJKLM<NOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~W^Y\                                     ! " # $ % & ' ( ) * + , - . / 0 1 Y X \ 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L L M N O P Q R S T U V W X Y Z [ \ ] ^ _`abcdefghijkllmnopqrstuvvwxyzz{|}~      !"#$%&'()*+Q,-./SUT0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~e                       !!! !!!"!#!$!%!&!'!(!)!*!+!,!-!.!/!0!1!2!3!4!5!6!7!8"9":";"<"=">"?"@#A#B#C#D#E#F#G#H#I#J#K$L$M%N%O&P&Q&R&S&T'U'V'W'X'Y'Z'['\']'^'_'`'a'b(c(d(d(e(f(f(g(h(h(i(j(k(l(m(n(o(p(q(r(s(t(u(v(w(x(y(z({(|(}(~(((())))))*********************}         `abc|b              ! !!!!!!"9"""" "!"""#"$"%"&"'"(")"*"+",#A#-#>#.#/#0$1$2%3%4&5&6&7&8'9':';'<(=(>(?(@(A)B)C)D)E)F)G**H*I*J*K*L*M*N*OPwumpus-basic-0.17.0Wumpus.Basic.VersionNumberWumpus.Basic.Utils.JoinList$Wumpus.Basic.Utils.FormatCombinators$Wumpus.Basic.Utils.ParserCombinatorsWumpus.Basic.Utils.TokenParsersWumpus.Basic.Utils.HList#Wumpus.Basic.Kernel.Objects.Anchors$Wumpus.Basic.Kernel.Base.FontSupport(Wumpus.Basic.System.FontLoader.Datatypes,Wumpus.Basic.System.FontLoader.AfmParserBase.Wumpus.Basic.System.FontLoader.AfmV4Dot1Parser*Wumpus.Basic.System.FontLoader.AfmV2Parser!Wumpus.Basic.Kernel.Base.BaseDefsWumpus.Basic.Kernel.Base.Units'Wumpus.Basic.Kernel.Base.DrawingContext#Wumpus.Basic.Kernel.Base.ContextFun Wumpus.Basic.Kernel.Base.QueryDC!Wumpus.Basic.Kernel.Base.UpdateDC)Wumpus.Basic.Kernel.Base.WrappedPrimitive!Wumpus.Basic.Kernel.Objects.Basis"Wumpus.Basic.Kernel.Objects.Concat(Wumpus.Basic.Kernel.Objects.Displacement!Wumpus.Basic.Kernel.Objects.Image$Wumpus.Basic.Kernel.Objects.LocImage%Wumpus.Basic.Kernel.Objects.AdvObject!Wumpus.Basic.Kernel.Objects.Chain%Wumpus.Basic.Kernel.Objects.Connector)Wumpus.Basic.Kernel.Objects.LocThetaImage-Wumpus.Basic.Kernel.Objects.DrawingPrimitives#Wumpus.Basic.Kernel.Objects.Bounded'Wumpus.Basic.Kernel.Objects.Orientation%Wumpus.Basic.Kernel.Objects.PosObject(Wumpus.Basic.Kernel.Objects.TraceDrawing&Wumpus.Basic.Kernel.Objects.CtxPicture,Wumpus.Basic.System.FontLoader.FontLoadMonad*Wumpus.Basic.System.FontLoader.AfmTopLevel)Wumpus.Basic.System.FontLoader.GSTopLevelWumpus.Basic.System.FontLoaderWumpus.Basic.Geometry.QuadrantWumpus.Basic.Geometry.Base"Wumpus.Basic.Geometry.IntersectionWumpus.Basic.Geometry.PathsWumpus.Basic.KernelWumpus.Basic.Geometrywumpus_basic_versionViewR:>EmptyRViewL:<EmptyLJoinListtoListfromList fromListFtoListFtoListMzipWithIntoListnullemptyoneconssnocjoinheadtakeLlength takeWhileL accumMapLviewlviewrunViewLunViewRFormatformatDocSDocshowsDoc<><+>vconcatseparatehcathsepvcattextcharintintegerintegralfloatdoublehex4spacecomma semicolonlinefill fillStringR fillStringL punctuateenclosesquotesdquotesparensbracketsbracesangleslparenrparenlbracketrbracketlbracerbracelangleranglelisttupled semiBracesindentwriteDoc ParseError CharResult CharParserParserResultOkayFail runParserrunParserEitherapplyfailure throwError lookaheadpeekeofequalssatisfyoneOfnoneOfchainl1chainr1chainlchainrchoicecountbetweenoption optionMaybe optionUnitskipOneskipMany skipMany1many1sepBysepBy1sepEndBy sepEndBy1manyTill manyTill1stringanyCharupperlowerletteralphaNumdigithexDigitoctDigitnewlinetab LexemeParserspaceLexemeParserspaceCharLexemeParsercommentLexemeParsercommentLineLexemeParsercommentMultiLexemeParserlexeme whiteSpaceoctBaseoctHaskhexBasenaturalHemptyHwrapHconsHsnocHappendHunfoldrHveloHconcatHtoListH prefixListH fromListHSideMidpointAnchor sideMidpointBottomCornerAnchorbottomLeftCornerbottomRightCornerTopCornerAnchor topLeftCornertopRightCorner RadialAnchor radialAnchorCardinalAnchor2 northeast southeast southwest northwestCardinalAnchornorthsoutheastwest ApexAnchorapex CenterAnchorcenterAnchor projectAnchorradialConnectorPointsFontLoadResultloaded_font_table loader_errors FontLoadLog FontLoadMsg FontTable FontMetricsget_bounding_box get_cw_tableget_cap_height get_descenderCharWidthLookup FontFamily ff_regularff_bold ff_italicff_bold_italicFontDef font_def_face gs_file_name afm_file_name CodePointFontName regularWeight boldWeight italicWeightboldItalicWeightemptyFontTable fontLoadMsgprintLoadErrors lookupFont insertFontmonospace_metrics FontPropsfp_bounding_boxfp_default_adv_vec fp_adv_vecs fp_cap_height fp_descenderMonospaceDefaultsdefault_letter_bboxdefault_cap_heightdefault_descenderdefault_char_widthAfmGlyphMetrics afm_char_codeafm_width_vector afm_char_nameAfmFile afm_encodingafm_letter_bboxafm_cap_height afm_descenderafm_glyph_metrics GlobalInfoAfmKeyAfmBoundingBoxPSEncodingScheme PSCharCodebuildMetricsOps afmFileParserrunQuery textQuery getFontBBoxgetEncodingScheme getCapHeightcharBBoxmetric keyStringPair versionNumberstartCharMetricskeyName newlineOrEOF uptoNewlinenamename1seminumbercinthexIntoctIntsymbolafmV4Dot1Parser afmV2Parser AdvanceVecCardinal NORTH_WESTWEST SOUTH_WESTSOUTH SOUTH_EASTEAST NORTH_EASTNORTHVAlignVRightVCenterVLeftHAlignHBottomHCenterHTop InterpretUnit normalizedinterp ScalarUnit fromPsPoint toPsPointUNilBimapbimapbimapLbimapROPlusoplusMonUnitoconcat altconcatreplaceLreplaceRdinterpF normalizeF uconvert1 uconvertF intraMapPointintraMapFunctoradvanceHadvanceVEnEmPica Centimetercmdcmpicadpica DrawingCtxMaskDCasksDClocalizeConnectorPropsdc_conn_src_spacedc_conn_dst_spacedc_conn_src_offsetdc_conn_dst_offsetdc_conn_arc_angdc_conn_src_armdc_conn_dst_armdc_conn_loop_sizedc_conn_box_halfsize TextMargin text_margin_x text_margin_yDrawingContextFDrawingContextdc_font_metrics_tabledc_font_load_logdc_fallback_metrics dc_font_face dc_font_sizedc_snap_grid_factorsdc_stroke_propsdc_stroke_colourdc_fill_colourdc_text_colourdc_line_spacing_factordc_text_margindc_connector_propsstandardContextmetricsContext addFontTablesreset_drawing_propertiesreset_drawing_metricswithFontMetricsQueryCFrunCFconsCFdomMap1domMap2 promoteR1 promoteR2pushR0pushR1pushR2apply1R1apply1R2apply2R2lift0R1lift0R2lift1R2uconvR0uconvR1uconvR2a uconvR2ab drawingCtx normalizeCtx normalizeCtxF dinterpCtx dinterpCtxF uconvertCtx1 uconvertCtxF pointSize strokeAttrfillAttr borderedAttrtextAttrpositionsnapmove textMargin getLineWidth getFontAttr getFontSize getFontFace getTextColour markHeightmarkHalfHeight textlineSpaceglyphBoundingBox capHeight descender verticalSpan cwLookupTableconnectorSrcSpaceconnectorDstSpaceconnectorSrcOffsetconnectorDstOffsetconnectorArcAngleconnectorSrcArmconnectorDstArmconnectorLoopSizeconnectorBoxHalfSizesnap_grid_factorsset_line_width line_default line_thin line_thickline_ultra_thick cap_defaultcap_butt cap_round cap_square join_default join_miter join_round join_bevelset_dash_pattern solid_line dotted_line packed_dotted loose_dotted dashed_line packed_dashed loose_dashed font_attrset_font set_font_sizescale_point_sizedouble_point_sizehalf_point_size text_margintext_margin_nonetext_margin_tighttext_margin_defaulttext_margin_loose stroke_colour fill_colour text_colour single_colour swap_coloursfill_use_stroke_colourstroke_use_fill_colourfill_use_text_colourstroke_use_text_colourtext_use_stroke_colourtext_use_fill_colour source_space dest_spaceuniform_conn_space source_offset dest_offsetconn_arc_anglesource_arm_len dest_arm_lenuniform_arm_lenconn_loop_sizeconn_box_halfsizeHPrimCatPrimprim1cpmap hprimToListsingleH GraphicAnsImageAnsAnsConnectorQuery LocThetaQueryLocQuerymapAns replaceAns ignoreAns graphicAnsanswer hyperlink clipObject szconvAnsF szconvAnsZatincline atInclineconnect replaceAnsR0 replaceAnsR1 replaceAnsR2 decorateR0 decorateR1 decorateR2 elaborateR0 elaborateR1 elaborateR2 AlignSpace halignSpace valignSpaceAlignhalignvalignCatSpacehspacevspaceConcathconcatZConcatanteriorsuperiorcatvsepalignRow alignColumn alignRowSepalignColumnSepThetaPointDisplace ThetaDisplace PointDisplace moveStartmoveStartThetamoveStartThetaPointmoveStartThetaIncldisplace displaceVec displaceH displaceVdisp_up disp_down disp_left disp_right disp_up_left disp_up_rightdisp_down_leftdisp_down_right disp_north disp_south disp_east disp_westdisp_northeastdisp_northwestdisp_southeastdisp_southwestdisplaceParalleldisplacePerpendicular displaceOrtho adisp_north adisp_south adisp_east adisp_westadisp_northeastadisp_northwestadisp_southeastadisp_southwestcenterRelativeright_ofleft_ofabove_right_ofbelow_right_of above_left_of below_left_ofDGraphicDImageGraphicImage intoImagegraphic_ uconvImageF uconvImageZ DLocGraphic DLocImage LocGraphicLocImage intoLocImage locGraphic_emptyLocGraphicuconvLocImageFuconvLocImageZdistribdistribHdistribV duplicate duplicateH duplicateV DAdvGraphic AdvGraphic DAdvObject AdvObject makeAdvObjectemptyAdvObjectrunAdvObjectR0runAdvObjectR1advanceadvancesadvspace evenspace advrepeatadvfillIterationSchemeChainAlgchainchain_linearprefixiterationScheme chainIteratechainHchainV tableRight tableDown radialChainDConnectorGraphicDConnectorImageConnectorGraphicConnectorImageintoConnectorImageconnectorGraphic_emptyConnectorGraphicuconvConnectorImageFuconvConnectorImageZDLocThetaGraphicDLocThetaImageLocThetaGraphic LocThetaImageintoLocThetaImagelocThetaGraphic_emptyLocThetaGraphicuconvLocThetaImageFuconvLocThetaImageZKernCharlocPP emptyLocPPvertexPPcurvePP openStroke closedStroke filledPath borderedPath plainTextLinerplainTextLine escTextLine rescTextLine hkernLine vkernLine straightLinelocStraightLine curvedLinestraightConnector strokedCircle filledCircleborderedCirclestrokedEllipserstrokedEllipse filledEllipserfilledEllipseborderedEllipserborderedEllipsestrokedRectanglefilledRectangleborderedRectangle strokedDisk filledDisk borderedDiskstrokedEllipseDiskfilledEllipseDiskborderedEllipseDiskDBoundedLocThetaGraphicBoundedLocThetaGraphicDBoundedLocGraphicBoundedLocGraphicDBoundedGraphicBoundedGraphiccenterOrthoBBoxemptyBoundedLocGraphicemptyBoundedLocThetaGraphicillustrateBoundedGraphicillustrateBoundedLocGraphic illustrateBoundedLocThetaGraphic bbrectangle Orientation or_x_minor or_x_major or_y_minor or_y_major RectAddressBLRBLCBLLSWSENWNEWWEESSNNCENTERorientationStartorientationBoundsextendOrientation extendOLeft extendORight extendODown extendOUppadHEven padXMinor padXMajorpadVEven padYMinor padYMajor spineRight spineBelow halignBottomO halignCenterO halignTopO valignLeftO valignCenterO valignRightO spinemoveH spinemoveVbinmoveHBottombinmoveHCenter binmoveHTop binmoveVLeftbinmoveVCenter binmoveVRightBoundedLocRectGraphic LocRectQuery DPosObject PosObject makePosObjectmakeBindPosObjectemptyPosObjectrunPosObjectR0runPosObjectR1runPosObjectR2 localizePO elaboratePO aelaboratePO startAddr atStartAddrextendPosObjectpadHorizontalPO padLeftPO padRightPO padVerticalPOpadUpPO padDownPOillustratePosObjectDTraceDrawingT DTraceDrawing TraceDrawingT TraceDrawingTraceMtrace fontDeltarunTraceDrawingexecTraceDrawingevalTraceDrawingrunTraceDrawingTexecTraceDrawingTevalTraceDrawingTliftToPictureUliftToPictureMb mbPictureU evalQuerydrawdrawidrawldrawlidrawcdrawcinodenodeidrawrcdrawrci CtxPicture runCtxPicturerunCtxPictureU drawTracing udrawTracing mapCtxPicture uniteCenter centeredAt FontLoadIO runFontLoadIOevalFontLoadIO loadError tellLoadMsg promoteIO promoteEither runParserFLIO sequenceAllbuildAfmFontProps checkFontPathloadAfmFontMetrics loadAfmFont1loadGSFontMetrics loadGSFont1 FontLoaderafmLoaderByEnv gsLoaderByEnvsimpleFontLoaderdefault_font_loader_helpQuadrantQUAD_SEQUAD_SWQUAD_NWQUAD_NEquadrantqiModulorectRadialVector rectangleQIdiamondRadialVectortriangleRadialVector triangleQIrightTrapezoidQIrightTrapeziumBaseWidth DBezierCurve BezierCurve DLineSegment LineSegment DLineEquation LineEquation line_eqn_A line_eqn_B line_eqn_C DMatrix2'2 Matrix2'2M2'2 quarter_pihalf_pitwo_pi identity2'2det2'2 transpose2'2 lineEquation pointViaX pointViaYpointLineDistancerectangleLineSegmentspolygonLineSegments bezierLength subdivide subdividetbezierArcPointsbezierMinorArc affineCombmidpoint lineAngle interLineLineinterLinesegLineseginterLinesegLineinterCurveLine findIntersect makePlane LocCoordPathPathAlgrunPathAlgPoint runPathAlgVecpathStartIsStartpathStartIsLocuspathIterateLocusrectanglePathAlgblRectanglePathAlgdiamondPathAlgpolygonPathAlg arcPathAlg circlePathAlgcoordinatePrimPathrectangleCoordPathdiamondCoordPathpolygonCoordPathisoscelesTriangleCoordPathisoscelesTrianglePointsequilateralTriangleCoordPathequilateralTrianglePointsJoinOneEmpty joinfoldr joinfoldlIndentLineDoc1unDocindentSrunDocbaseGHC.Real fromIntegralpadr getParserFKSKyieldalt eagerMany eagerSome<:>Control.ApplicativesomegetLexemeParser lineComment spanCommentendLinegetFontLoadLog getFontTablewumpus-core-0.50.0Wumpus.Core.FontSizeAfmUnit globalInfo getDescenderfontBBoxlpcharMetricsV4Dot1 widthVector characterCode charMetricsV2getEngetEmgetPica getCentimeterghc-prim GHC.TypesDoubledefault_text_margindefault_connector_propsdefault_line_spacing wumpus_blackwumpus_light_graywumpus_couriergetCF glyphQuery connectorAsksupdateStrokeProps withFontSize setLineCap setLineJoinWumpus.Core.GraphicPropsSolid connectorUpdnormZerogetHPrimCat1CZero getAdvObjectAdvDrawadvpluslistcatScheme scheme_start scheme_stepPXL1interpChainAlgrunInf takeAndLast scHorizontal scVertical scStepper scCircularnorm2 makeGraphicmakeLocGraphicmakeLocThetaGraphicWumpus.Core.PicturevertexPrimPathcurvedPrimPathostrokecstroke fillStroke textlabel rtextlabel escapedlabel rescapedlabel uconvKernChar hkernlabel vkernlabel circlePath ellipsePath rellipsePath rectanglePathconcatOrientation halfDistsupDowndownUp leftRight rightLeft getPosObjectPosDrawpozeropoconcatgenPadillustrateOrientation genMoveAlign genMoveSepH genMoveSepVgetTraceDrawingTgetTraceDrawing fontDeltaMonfontDeltaTransWumpus.Core.PictureInternalPicture getCtxPictureleftEdge rightEdge bottomEdgetopEdge combineP2moveSndcxpRightcxpBelow cxpRightSep cxpDownSep cxpAlignH cxpAlignVcxpAlignSpaceHcxpAlignSpaceV$fOPlusCtxPicture getFontLoadIOextractCapHeightextractDescenderextractFontBBoxafmLoadFontMetricsafm_mono_defaults_4_1gsLoadFontMetricsghostscript_mono_defaults_8_54wumpus_gs_font_dirwumpus_afm_font_dir envLookupfontListnegateXnegateYnegateXYtriangleLeftSidelift2Matrix2'2gravesenLengthctrlPolyLength cordLengthkappambCheck withinPointspvenvecut quadrantCheckpath_alg_schemepath_alg_steps PathAlgSchemeSTART_IS_LOCUSSTART_IS_STARTminorArcQuadVecdiffarcdiv