!k l      !"#$%&'()*+,-./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 { | } ~                                                                                                                                          !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`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${$|$}$~$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&&&&&&&&&&&&&&&&&&''''''''''''''''''''''''((((((())))))))))))))))) ) * * * ******************* *!*"*#*$*%*&*'*(*)***+*,*-*.*/*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/{/|/}/~///////////////////////00011111111111111111111111111111222333333333333333333333333333333333333334444444445555555555555555555566666666666666 6 6 6 6 6666677777777777777 7!7"7#7$7%7&7'7(7)7*7+7,7-7.7/707172737475767778797:7;7<7=7>8?8@8A8B8C8D8E8F8G8H8I8J8K8L8M8N8O8P8Q8R8S8T8U8V8W8X8Y8Z8[8\8]8^8_8`8a8b8c8d8e8f8g8h8i8j8k8l8m8n8o8p8q8r8s8t8u8v8w8x8y8z8{8|8}8~888888888999999999999999999999::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;;;;;;;;<<<<=== = = = = =================== =!="=#=$=%=&='=(=)=*=+=,=-=.=/=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={=|=}=~=======================================================================>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> > > > > > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? !? "@ #@ $@ %@ &@ '@ (@ )@ *@ +@ ,@ -@ .@ /@ 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@ PA QA RA SA TA UA VA WA XA YA ZA [A \A ]A ^A _A `B aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB pB qB rB sB tB uB vB wB xB yB zB {B |B }B ~B B B B B B B C D E E E E E E E E E E E E E E E E F F F F F F G G G H H H H H H H H H H H H H H H H H H H H H H H H H H H I I I I I J J K K K L L L L L L M M M M M M M M M M M M M M M M M M M M M M M M M M M M N N N N O O P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q !Q "Q #Q $R %R &R 'R (R )R *R +R ,R -R .R /R 0R 1R 2R 3R 4R 5R 6R 7R 8R 9R :R ;R <R =R >R ?R @R AR BR CR DR ER FR GR HR IR JR KR LR MR NR OS PS QS RS ST TT UT VT WU XV YV ZV [V \V ]W ^W _W `W aW bW cW dW eW fW gW hW iW jW kWZNone%&'+,-0123456;<=>?FKNQSTV]et* hgeometry#Runs a computation at a given time. !"#$%&'()*+,-./0#$%& !"'()*+,-./0None%&'+,-0123456;<=>?FKNQSTV]e: hgeometry7Given a list xs, generate all unique (unordered) pairs.< hgeometryAll unieuqe unordered triplets.6789:;<89:;67<None%&'+,-0123456;<=>?FKNQSTV]e>D hgeometry;A State monad that can store earlier versions of the state.E hgeometryWCreate a snapshot of the current state and add it to the list of states that we store.F hgeometryrun a persistentStateT, returns a triplet with the value, the last state and a list of all states (including the last one) in chronological orderCDEFGDCEFGNone"#%&'+,-0123456;<=>?FKNQSTV]eqO hgeometryResult of splititng a treeQ hgeometrySplitting and extractingCA pair that is strict in its first argument and lazy in the second.] hgeometryA balanced binary search treea hgeometry!Describes how to search in a treeg hgeometryCreates an empty BSTh hgeometry O(n\log n)j hgeometryCheck if the tree is emptyk hgeometry'Test if an element occurs in the BST.  O(\log n)l hgeometry O(\log n)m hgeometrySearch for the Predecessor  O(\log n)n hgeometryInsert an element in the BST. O(\log n)o hgeometry'Delete (one occurance of) an element.  O(\log n)p hgeometry#Extract the minimum from the tree  O(\log n)r hgeometry#Extract the maximum from the tree  O(\log n)t hgeometryPJoins two BSTs. Assumes that the ranges are disjoint. It takes the left Tree nav O(\log n)u hgeometry.Joins two BSTs' with a specific Tree Navigator O(\log n)w hgeometry0Extract a prefix from the tree, i.e. a repeated p O(\log n +k), where k" is the size of the extracted partx hgeometry0Extract a suffix from the tree, i.e. a repeated p O(\log n +k), where k" is the size of the extracted party hgeometrydSplits the tree at x. Note that if x occurs more often, no guarantees are given which one is found. O(\log n)z hgeometry$split based on a monotonic predicate O(\log n){ hgeometryfSplits at a given monotone predicate p, and then selects everything that satisfies the predicate sel.~ hgeometry:Get the minimum in the tree. Errors when the tree is empty O(\log n) hgeometry:Get the maximum in the tree. Errors when the tree is empty O(\log n) hgeometry Extract all elements in the treeO(n) hgeometry Extract all elements in the treeO(n) hgeometryrebalance the tree<LNMOPQRTSUWXVYZ\[]^_`abdcefghijklmnopqrstuvwxyz{|}~<abdcef]^_`Z\[YUWXVghijklmnopqrstuQRTSvwxOPyz{LNM|}~None%&'+,-0123456;<=>?AFKNQSTV]e hgeometrysmart constructor hgeometry.Create a balanced tree, i.e. a tree of height  O(\log n)" with the elements in the leaves.O(n) time. hgeometryGiven a function to combine internal nodes into b's and leafs into b's, traverse the tree bottom up, and combine everything into one b. hgeometry?Traverses the tree bottom up, recomputing the assocated values. hgeometryfTakes two trees, that have the same structure, and uses the provided functions to "zip" them together hgeometry0Get the element stored at the root, if it exists hgeometryCreate a balanced binary treeO(n)None%&'+,-0123456;<=>?FKNQSTV]e:  hgeometryFocus on the root hgeometryGo to the left child hgeometryGo to the right child hgeometryMove to the parent hgeometryNavigate to the root hgeometry@Returns a list of zippers; one focussed on each node in the tree hgeometry(Get the value stored at the current node hgeometry=Returns all subtrees; i.e. every node with all its decendents hgeometry:Splits the tree here, returns a pair (innerTree,outerTree) None%&'+,-0123456;<=>?FKNQSTV]ed  hgeometryGiven a circular list, whose elements are in increasing order, insert the new element into the Circular list in its sorted order.insertOrd 1 C.empty fromList [1]insertOrd 1 $ C.fromList [2]fromList [2,1]insertOrd 2 $ C.fromList [1,3]fromList [1,2,3]insertOrd 31 ordList fromList [5,6,10,20,30,31,1,2,3]insertOrd 1 ordListfromList [5,6,10,20,30,1,1,2,3]insertOrd 4 ordListfromList [5,6,10,20,30,1,2,3,4]insertOrd 11 ordList fromList [5,6,10,11,20,30,1,2,3]  hgeometry_Insert an element into an increasingly ordered circular list, with specified compare operator.  hgeometryList version of insertOrdBy; i.e. the list contains the elements in cirulcar order. Again produces a list that has the items in circular order. hgeometry}Test if the circular list is a cyclic shift of the second list. Running time: O(n), where n is the size of the smallest list       None%&'+,-0123456;<=>?FKNQSTV]e  hgeometryNonempty circular sequence hgeometry.Gets the focus of the CSeq running time: O(1) hgeometryGAccess the i^th item (w.r.t the focus) in the CSeq (indices modulo n).running time: O(\log (i \mod n))index (fromList [0..5]) 11index (fromList [0..5]) 22index (fromList [0..5]) 55index (fromList [0..5]) 104index (fromList [0..5]) 60index (fromList [0..5]) (-1)5index (fromList [0..5]) (-6)0 hgeometry4Adjusts the i^th element w.r.t the focus in the CSeqrunning time: O(\log (i \mod n))'adjust (const 1000) 2 (fromList [0..5])CSeq [0,1,1000,3,4,5] hgeometry:Access te ith item in the CSeq (w.r.t the focus) as a lens hgeometry5smart constructor that automatically balances the seq l hgeometry4Builds a balanced seq with the element as the focus. hgeometryrotates one to the rightrunning time: O(1) (amortized)rotateR $ fromList [3,4,5,1,2]CSeq [4,5,1,2,3] hgeometryrotates the focus to the leftrunning time: O(1) (amortized)rotateL $ fromList [3,4,5,1,2]CSeq [2,3,4,5,1]8mapM_ print . take 5 $ iterate rotateL $ fromList [1..5]CSeq [1,2,3,4,5]CSeq [5,1,2,3,4]CSeq [4,5,1,2,3]CSeq [3,4,5,1,2]CSeq [2,3,4,5,1] hgeometry1Convert to a single Seq, starting with the focus. hgeometry9All elements, starting with the focus, going to the right hgeometry8All elements, starting with the focus, going to the left#leftElements $ fromList [3,4,5,1,2]fromList [3,2,1,5,4] hgeometry builds a CSeq hgeometry Rotates i elements to the right.pre: 0 <= i < nrunning time:  O(\log i) amortizedrotateNR 0 $ fromList [1..5]CSeq [1,2,3,4,5]rotateNR 1 $ fromList [1..5]CSeq [2,3,4,5,1]rotateNR 4 $ fromList [1..5]CSeq [5,1,2,3,4]  hgeometryRotates i elements to the left.pre: 0 <= i < nrunning time:  O(\log i) amoritzedrotateNL 0 $ fromList [1..5]CSeq [1,2,3,4,5]rotateNL 1 $ fromList [1..5]CSeq [5,1,2,3,4]rotateNL 2 $ fromList [1..5]CSeq [4,5,1,2,3]rotateNL 3 $ fromList [1..5]CSeq [3,4,5,1,2]rotateNL 4 $ fromList [1..5]CSeq [2,3,4,5,1]! hgeometry#Reversres the direction of the CSeqrunning time: O(n)"reverseDirection $ fromList [1..5]CSeq [1,5,4,3,2]" hgeometryFinds an element in the CSeq%findRotateTo (== 3) $ fromList [1..5]Just (CSeq [3,4,5,1,2])%findRotateTo (== 7) $ fromList [1..5]Nothing$ hgeometry+All rotations, the input CSeq is the focus.,mapM_ print . allRotations $ fromList [1..5]CSeq [1,2,3,4,5]CSeq [2,3,4,5,1]CSeq [3,4,5,1,2]CSeq [4,5,1,2,3]CSeq [5,1,2,3,4]% hgeometry"Left zip": zip the two CLists, pairing up every element in the *left* list with its corresponding element in the right list. If there are more items in the right clist they are discarded.& hgeometry see 'zipLWith' hgeometry%same as zipLWith but with three items( hgeometryGiven a circular seq, whose elements are in increasing order, insert the new element into the Circular seq in its sorted order.insertOrd 1 $ fromList [2] CSeq [2,1]insertOrd 2 $ fromList [1,3] CSeq [1,2,3]insertOrd 31 ordListCSeq [5,6,10,20,30,31,1,2,3]insertOrd 1 ordListCSeq [5,6,10,20,30,1,1,2,3]insertOrd 4 ordListCSeq [5,6,10,20,30,1,2,3,4]insertOrd 11 ordListCSeq [5,6,10,11,20,30,1,2,3]running time: O(n)) hgeometry_Insert an element into an increasingly ordered circular list, with specified compare operator.running time: O(n) m hgeometryList version of insertOrdBy; i.e. the list contains the elements in cirulcar order. Again produces a list that has the items in circular order.* hgeometry}Test if the circular list is a cyclic shift of the second list. Running time: O(n), where n is the size of the smallest list !"#$%&'()* !$"#%&'()* %A pair-like data type to represent a 7) type that has extra information as well.(c) Frank StaalsSee LICENCE fileNone%&'+,-01234568;<=>?FKNQSTV]e83 hgeometry]Our Ext type that represents the core datatype core extended with extra information of type 8.345678934567893141 None#%&'+,-0123456;<=>?BFKNQSTV]e%a hgeometrylAttr implements the mapping from labels to types as specified by the (symbol representing) the type family f hgeometryGive pref. to the *RIGHT* hgeometry Possible values for an ipe arrow hgeometry>IpeOpacity, IpeTyling, and IpeGradient are all symbolic values hgeometryAllowed Fill types hgeometryPath AttributesPossible attributes for a path data PathAttributeUniverse = Stroke | Fill | Dash | Pen | LineCap | LineJoin | FillRule | Arrow | RArrow | Opacity | Tiling | Gradient deriving (Show,Eq)Possible values for Dash hgeometryTODOSymbol AttributesThe optional Attributes for a symbol data SymbolAttributeUniverse = SymbolStroke | SymbolFill | SymbolPen | Size deriving (Show,Eq)BMany types either consist of a symbolc value, or a value of type v hgeometry"Possible values for Transformation hgeometryCommon AttributesPossible values for Pin hgeometry.gets and removes the attribute from Attributes hgeometryunsets/Removes an attribute hgeometryIFunction that states that all elements in xs satisfy a given constraint c hgeometrydFor the types representing attribute values we can get the name/key to use when serializing to ipe. hgeometryWriting Attribute namesw n o p q r s t u v w x y z { | } ~  K]\[ZYWVUTRQPONLMSXabcdefghijklmnopqrstuvwxyz{|}dK]\[ZYWVUTRQPONLMSX}|{zyxwvutsrqponmlkjihgfedabc None%&'+,-0123456;<=>?FKNQSTV]e*XNone%&'+,-0123456;<=>?FKNQSTV]e2  hgeometry%reexporting some standard combinators  hgeometryparses an integer with a prefix of zeros. Returns the total length of the string parced (i.e. number of digits) and the resulting antural number.  hgeometryinfix variant of notfollowed by  hgeometryRunning parsers in reverse;Runs parser q ``in reverse'' on the end of the input stream  hgeometry1run the parsers in reverse order, first q, then p  hgeometry"the variants with missing brackets  1 1 2 2 2[Defines some generic geometric properties e.g. Dimensions, NumType, and Intersection types.(c) Frank StaalsSee LICENCE fileNone!%&'+,-01234567;<=>?BFKNQRSTV]eD  hgeometryTWhen using IntersectionOf we may need some constraints that are always true anyway. hgeometryg  h  =* The intersection of g and h is non-empty.The default implementation computes the intersection of g and h, and uses nonEmptyIntersection to determine if the intersection is non-empty.  hgeometryHelper to implement .  hgeometryQThe type family specifying the list of possible result types of an intersection.  hgeometry6The result of interesecting two geometries is a CoRec,  hgeometry=A simple data type expressing that there are no intersections hgeometry=A type family for types that have an associated numeric type. hgeometryA type family for types that are associated with a dimension. The dimension is the dimension of the geometry they are embedded in. hgeometryHelper to produce a corec hgeometry5Returns True iff the result is *not* a NoIntersection          None%&'+,-0123456;<=>?FKNQSTV]eT hgeometrysDatatype representing d dimensional vectors. Our implementation wraps the implementation provided by fixed-vector. hgeometry.A proxy which can be used for the coordinates. hgeometry-Pattern synonym for two and three dim vectors hgeometryLens into the i th element  hgeometry Similar to x above. Except that we don't have a static guarantee that the index is in bounds. Hence, we can only return a Traversal# hgeometry!Get the head and tail of a vector$ hgeometry.Cross product of two three-dimensional vectors% hgeometryVonversion to a Linear.V2& hgeometryConversion to a Linear.V3' hgeometryConversion from a Linear.V3( hgeometry(Add an element at the back of the vector) hgeometry)Get a vector of the first d - 1 elements.+ hgeometry&Get a prefix of i elements of a vector, hgeometry Construct a 2 dimensional vector- hgeometry Construct a 3 dimensional vector. hgeometry#Destruct a 2 dim vector into a pair !"#$%&'()*+,-./ !"#$%&'()*+,-./None%&'+,-0123456;<=>?FKNQSTV]e[D hgeometryGMapping between the implementation type, and the actual implementation.E hgeometryDatatype representing d dimensional vectors. The default implementation is based n VectorFixed. However, for small vectors we automatically select a more efficient representation.] hgeometry!Get the head and tail of a vectorCDEFGHIJKLMNOPQRSTUVWXYZ[\]^RQPONMJKLHIEFGDSCTUVWXYZ[\]^None%&'+,-0123456;<=>?FKNQSTV]efq hgeometryDatatype representing d dimensional vectors. The default implementation is based n VectorFixed. However, for small vectors we automatically select a more efficient representation.} hgeometryLens into the i th element~ hgeometry Similar to }x above. Except that we don't have a static guarantee that the index is in bounds. Hence, we can only return a Traversal hgeometry(Add an element at the back of the vector hgeometry)Get a vector of the first d - 1 elements. hgeometry&Get a prefix of i elements of a vector hgeometry.Cross product of two three-dimensional vectorspqrstuvwxyz{|}~qrsypxwvutz{|}~None%&'+,-0123456;<=>?FKNQSTV]eq hgeometry$Test if v is a scalar multiple of u..Vector2 1 1 `isScalarMultipleOf` Vector2 10 10True-Vector2 1 1 `isScalarMultipleOf` Vector2 10 1False2Vector2 1 1 `isScalarMultipleOf` Vector2 11.1 11.1True2Vector2 1 1 `isScalarMultipleOf` Vector2 11.1 11.2False2Vector2 2 1 `isScalarMultipleOf` Vector2 11.1 11.2False,Vector2 2 1 `isScalarMultipleOf` Vector2 4 2True,Vector2 2 1 `isScalarMultipleOf` Vector2 4 0False hgeometry8Get the scalar labmda s.t. v = lambda * u (if it exists)  hgeometry'Actual implementation of scalarMultiple8 pqrstuvwxyz{|}~ d-dimensional points(c) Frank StaalsSee LICENCE fileNone%&'+,-0123456;<=>?FKNQSTV]ek hgeometry1Quadrants of two dimensional points. in CCW order hgeometryPTypes that we can transform by mapping a function on each point in the structure hgeometryA d-dimensional point. hgeometrySimilarly, we can write::{ let& g :: Point 3 r -> r g (Point3 x y z) = z in g myPoint:}3 hgeometryaWe provide pattern synonyms Point2 and Point3 for 2 and 3 dimensional points. i.e. we can write::{ let$ f :: Point 2 r -> r f (Point2 x y) = x in f (point2 1 2):}1 if we want. hgeometry-Point representing the origin in d dimensionsorigin :: Point 4 IntPoint4 [0,0,0,0] hgeometry6Lens to access the vector corresponding to this point.(point3 1 2 3) ^. vectorVector3 [1,2,3] origin & vector .~ Vector3 1 2 3Point3 [1,2,3] hgeometry{Get the coordinate in a given dimension. This operation is unsafe in the sense that no bounds are checked. Consider using  instead.point3 1 2 3 ^. unsafeCoord 22 hgeometry'Get the coordinate in a given dimension point3 1 2 3 ^. coord (C :: C 2)2%point3 1 2 3 & coord (C :: C 1) .~ 10Point3 [10,2,3]'point3 1 2 3 & coord (C :: C 3) %~ (+1)Point3 [1,2,4] hgeometry-Constructs a point from a list of coordinates,pointFromList [1,2,3] :: Maybe (Point 3 Int)Just Point3 [1,2,3] hgeometry,Project a point down into a lower dimension. hgeometryConstruct a 2 dimensional point point2 1 2 Point2 [1,2] hgeometryDestruct a 2 dimensional point_point2 $ point2 1 2(1,2) hgeometryConstruct a 3 dimensional point point3 1 2 3Point3 [1,2,3] hgeometryDestruct a 3 dimensional point_point3 $ point3 1 2 3(1,2,3) hgeometry,Shorthand to access the first coordinate C 1point3 1 2 3 ^. xCoord1point2 1 2 & xCoord .~ 10 Point2 [10,2] hgeometry-Shorthand to access the second coordinate C 2point2 1 2 ^. yCoord2point3 1 2 3 & yCoord %~ (+1)Point3 [1,3,3] hgeometry,Shorthand to access the third coordinate C 3point3 1 2 3 ^. zCoord3point3 1 2 3 & zCoord %~ (+1)Point3 [1,2,4] hgeometryTGiven three points p q and r determine the orientation when going from p to r via q. hgeometryTGiven three points p q and r determine the orientation when going from p to r via q. hgeometrySort the points arround the given point p in counter clockwise order with respect to the rightward horizontal ray starting from p. If two points q and r are colinear with p, the closest one to p is reported first. running time: O(n log n) hgeometryQuadrants around point c; quadrants are closed on their "previous" boundary (i..e the boundary with the previous quadrant in the CCW order), open on next boundary. The origin itself is assigned the topRight quadrant hgeometry$Quadrants with respect to the origin hgeometrygGiven a center point c, and a set of points, partition the points into quadrants around c (based on their x and y coordinates). The quadrants are reported in the order topLeft, topRight, bottomLeft, bottomRight. The points are in the same order as they were in the original input lists. Points with the same x-or y coordinate as p, are "rounded" to above. hgeometryCounter clockwise ordering of the points around c. Points are ordered with respect to the positive x-axis. Points nearer to the center come before points further away. hgeometryClockwise ordering of the points around c. Points are ordered with respect to the positive x-axis. Points nearer to the center come before points further away. hgeometryGiven a center c, a new point p, and a list of points ps, sorted in counter clockwise order around c. Insert p into the cyclic order. The focus of the returned cyclic list is the new point p.running time: O(n) hgeometry-Squared Euclidean distance between two points hgeometry%Euclidean distance between two points((None%&'+,-0123456;<=>?FKNQSTV]e hgeometryIA class representing types that can be transformed using a transformation hgeometry>A type representing a Transformation for d dimensional objects hgeometry?a matrix of n rows, each of m columns, storing values of type r hgeometry'Compose transformations (right to left) hgeometrycCreates a row with zeroes everywhere, except at position i, where the value is the supplied value. hgeometryRow in a translation matrix transRow :: forall n r. ( Arity n, Arity (n- 1), ((n - 1) + 1) ~ n , Num r) => Int -> r -> Vector n r transRow i x = set (V.element (Proxy :: Proxy (n-1))) x $ mkRow i 1None%&'+,-0123456;<=>?FKNQSTV]e hgeometry`Result of a query that asks if something is Inside a g, *on* the boundary of the g, or outside. hgeometry#The boundary of a geometric object.None"%&'+,-01234568;<=>?FKNQSTV]e hgeometryJA line is given by an anchor point and a vector indicating the direction.  hgeometryResult of a side test hgeometry`Types for which we can compute a supporting line, i.e. a line that contains the thing of type t. hgeometry*A line may be constructed from two points. hgeometry]Given a line l with anchor point p, get the line perpendicular to l that also goes through p. hgeometrymTest if two lines are identical, meaning; if they have exactly the same anchor point and directional vector. hgeometry#Test if the two lines are parallel.TlineThrough origin (point2 1 0) `isParallelTo` lineThrough (point2 1 1) (point2 2 1)TrueTlineThrough origin (point2 1 0) `isParallelTo` lineThrough (point2 1 1) (point2 2 2)False hgeometryTest if point p lies on line l/origin `onLine` lineThrough origin (point2 1 0)True5point2 10 10 `onLine` lineThrough origin (point2 2 2)True4point2 10 5 `onLine` lineThrough origin (point2 2 2)False hgeometry8Specific 2d version of testing if apoint lies on a line. hgeometry'Squared distance from point p to line l hgeometrybThe squared distance between the point p and the line l, and the point m realizing this distance. hgeometry-Create a line from the linear function ax + b hgeometrygget values a,b s.t. the input line is described by y = ax + b. returns Nothing if the line is vertical hgeometryGiven a point q and a line l, compute to which side of l q lies. For vertical lines the left side of the line is interpeted as below.8point2 10 10 `onSide` (lineThrough origin $ point2 10 5)Above;point2 10 10 `onSide` (lineThrough origin $ point2 (-10) 5)Above%point2 5 5 `onSide` (verticalLine 10)Below;point2 5 5 `onSide` (lineThrough origin $ point2 (-3) (-3))On hgeometry6Test if the query point q lies (strictly) above line l  hgeometry#Get the bisector between two points! hgeometryVCompares the lines on slope. Vertical lines are considered larger than anything else.B(Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 3 3))LTE(Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 (-3) 3))GTB(Line origin (Vector2 5 1)) `cmpSlope` (Line origin (Vector2 0 1))LT     !     !None%&'+,-0123456;<=>?FKNQSTV]e- : hgeometryInsert into a monotone OrdSeq.*pre: the comparator maintains monotonicity O(\log n); hgeometryInsert into a sorted OrdSeq O(\log n)= hgeometry O(\log n)> hgeometryGiven a monotonic function f that maps a to b, split the sequence s depending on the b values. I.e. the result (l,m,r) is such that * all (< x) . fmap f $ l * all (== x) . fmap f $ m * all (> x) . fmap f $ r"splitOn id 3 $ fromAscList' [1..5](OrdSeq {_asFingerTree = fromList [Elem 1,Elem 2]},OrdSeq {_asFingerTree = fromList [Elem 3]},OrdSeq {_asFingerTree = fromList [Elem 4,Elem 5]})NsplitOn fst 2 $ fromAscList' [(0,"-"),(1,"A"),(2,"B"),(2,"C"),(3,"D"),(4,"E")](OrdSeq {_asFingerTree = fromList [Elem (0,"-"),Elem (1,"A")]},OrdSeq {_asFingerTree = fromList [Elem (2,"B"),Elem (2,"C")]},OrdSeq {_asFingerTree = fromList [Elem (3,"D"),Elem (4,"E")]}) O(\log n)? hgeometrywGiven a monotonic predicate p, splits the sequence s into two sequences (as,bs) such that all (not p) as and all p bs O(\log n)A hgeometry inserts all eleements in order  O(n\log n)B hgeometry inserts all eleements in order  O(n\log n)C hgeometryO(n)D hgeometry O(\log n)F hgeometry-Fmap, assumes the order does not change O(n)G hgeometry*Gets the first element from the sequence O(1)./0123456789:;<=>?@ABCDEFGHIJKL56789234/01.:;<=>?@ABCDEFGHIJKLNone%&'+,-0123456;<=>?FKNQSTV]e< ^ hgeometry'Cyclic representation of a permutation.a hgeometryNidxes (fromEnum a) = (i,j) implies that a is the j^th item in the i^th orbitb hgeometry*Orbits (Cycles) are represented by vectorsi hgeometry!The cycle containing a given itemj hgeometry!Next item in a cyclic permutationk hgeometry%Previous item in a cyclic permutationl hgeometrycLookup the indices of an element, i.e. in which orbit the item is, and the index within the orbit.runnign time: O(1)m hgeometryCApply the permutation, i.e. consider the permutation as a function.n hgeometry7Find the cycle in the permutation starting at element sp hgeometryjGiven the size n, and a list of Cycles, turns the cycles into a cyclic representation of the Permutation.r hgeometrylens indexing into a vector^_a`befghijklmnopqrb^_a`feghijklmnopqrNone!%&'+,-0123456;<=>?FKNQSTV]ex;v hgeometryA dart represents a bi-directed edge. I.e. a dart has a direction, however the dart of the oposite direction is always present in the planar graph as well.} hgeometrygAn Arc is a directed edge in a planar graph. The type s is used to tie this arc to a particular graph. hgeometryReverse the direcion hgeometry Edge Oracle:main idea: store adjacency lists in such a way that we store an edge (u,v) either in u's adjacency list or in v's. This can be done s.t. all adjacency lists have length at most 6.Pnote: Every edge is stored exactly once (i.e. either at u or at v, but not both) hgeometryA face hgeometry)get the data associated with the value i.running time: O(1) to read the data, O(n) to write it. hgeometryA *connected* Planar graph with bidirected edges. I.e. the edges (darts) are directed, however, for every directed edge, the edge in the oposite direction is also in the graph.vThe types v, e, and f are the are the types of the data associated with the vertices, edges, and faces, respectively.The orbits in the embedding are assumed to be in counterclockwise order. Therefore, every dart directly bounds the face to its right. hgeometry~A vertex in a planar graph. A vertex is tied to a particular planar graph by the phantom type s, and to a particular world w. hgeometry"The world in which the graph lives hgeometry Get the twin of this dart (edge)twin (dart 0 "+1")Dart (Arc 0) -1twin (dart 0 "-1")Dart (Arc 0) +1 hgeometrytest if a dart is Positive hgeometry4Enumerates all darts such that allDarts !! i = d  = i == fromEnum d hgeometry1Helper function to build the graph from JSON datarunning time: O(n) hgeometrylens to access the Dart Data hgeometryedgeData is just an alias for   hgeometryHelper function to update the data in a planar graph. Takes care to update both the data in the original graph as well as in the dual.  hgeometry+The function that does the actual work for   hgeometry?Reorders the edge data to be in the right order to set edgeData hgeometryConstruct a planar graphrunning time: O(n). hgeometryNConstruct a planar graph, given the darts in cyclic order around each vertex.running time: O(n). hgeometry}Construct a planar graph from a adjacency matrix. For every vertex, all vertices should be given in counter clockwise order.&pre: No self-loops, and no multi-edgesrunning time: O(n). hgeometryProduces the adjacencylists for all vertices in the graph. For every vertex, the adjacent vertices are given in counter clockwise order.Note that in case a vertex u as a self loop, we have that this vertexId occurs twice in the list of neighbours, i.e.: u : [...,u,..,u,...]. Similarly, if there are multiple darts between a pair of edges they occur multiple times.running time: O(n) hgeometryGet the number of verticesnumVertices myGraph4 hgeometryGet the number of DartsnumDarts myGraph12 hgeometryGet the number of EdgesnumEdges myGraph6 hgeometryGet the number of facesnumFaces myGraph4 hgeometryEnumerate all verticesvertices' myGraph-[VertexId 0,VertexId 1,VertexId 2,VertexId 3] hgeometry7Enumerate all vertices, together with their vertex data hgeometryEnumerate all darts hgeometry&Get all darts together with their datamapM_ print $ darts myGraph (Dart (Arc 0) -1,"a-")(Dart (Arc 2) +1,"c+")(Dart (Arc 1) +1,"b+")(Dart (Arc 0) +1,"a+")(Dart (Arc 4) -1,"e-")(Dart (Arc 1) -1,"b-")(Dart (Arc 3) -1,"d-")(Dart (Arc 5) +1,"g+")(Dart (Arc 4) +1,"e+")(Dart (Arc 3) +1,"d+")(Dart (Arc 2) -1,"c-")(Dart (Arc 5) -1,"g-") hgeometry6Enumerate all edges. We report only the Positive darts hgeometryMEnumerate all edges with their edge data. We report only the Positive darts.mapM_ print $ edges myGraph(Dart (Arc 2) +1,"c+")(Dart (Arc 1) +1,"b+")(Dart (Arc 0) +1,"a+")(Dart (Arc 5) +1,"g+")(Dart (Arc 4) +1,"e+")(Dart (Arc 3) +1,"d+") hgeometry=The tail of a dart, i.e. the vertex this dart is leaving fromrunning time: O(1) hgeometry%The vertex this dart is heading in torunning time: O(1) hgeometry(endPoints d g = (tailOf d g, headOf d g)running time: O(1) hgeometryCAll edges incident to vertex v, in counterclockwise order around v.running time: O(k), where k is the output size hgeometryLAll incoming edges incident to vertex v, in counterclockwise order around v. hgeometryLAll outgoing edges incident to vertex v, in counterclockwise order around v. hgeometryYGets the neighbours of a particular vertex, in counterclockwise order around the vertex.running time: O(k), where k is the output size hgeometrybGiven a dart d that points into some vertex v, report the next dart in the cyclic order around v.running time: O(1) hgeometrybGiven a dart d that points into some vertex v, report the next dart in the cyclic order around v.running time: O(1) hgeometry/Data corresponding to the endpoints of the dart hgeometry/Data corresponding to the endpoints of the dartrunning time: O(1)  hgeometryThe dual of this graph:{  let fromList = V.fromList/ answer = fromList [ fromList [dart 0 "-1"]S , fromList [dart 2 "+1",dart 4 "+1",dart 1 "-1",dart 0 "+1"]G , fromList [dart 1 "+1",dart 3 "-1",dart 2 "-1"]S , fromList [dart 4 "-1",dart 3 "+1",dart 5 "+1",dart 5 "-1"] ]5 in (computeDual myGraph)^.embedding.orbits == answer:}Truerunning time: O(n).  hgeometry"Does the actual work for dualGraph hgeometry'Enumerate all faces in the planar graph hgeometryAll faces with their face data. hgeometry The face to the left of the dartleftFace (dart 1 "+1") myGraphFaceId 1leftFace (dart 1 "-1") myGraphFaceId 2leftFace (dart 2 "+1") myGraphFaceId 2leftFace (dart 0 "+1") myGraphFaceId 0running time: O(1). hgeometry!The face to the right of the dartrightFace (dart 1 "+1") myGraphFaceId 2rightFace (dart 1 "-1") myGraphFaceId 1rightFace (dart 2 "+1") myGraphFaceId 1rightFace (dart 0 "+1") myGraphFaceId 1running time: O(1). hgeometry Get the next edge along the facerunning time: O(1). hgeometry$Get the previous edge along the facerunning time: O(1). hgeometrytThe darts bounding this face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size. hgeometryEGenerates the darts incident to a face, starting with the given dart.O(k), where k is the number of darts reported hgeometrywThe vertices bounding this face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size. hgeometryGiven a planar graph, construct an edge oracle. Given a pair of vertices this allows us to efficiently find the dart representing this edge in the graph.(pre: No self-loops and no multi-edges!!!running time: O(n) hgeometryeBuilds an edge oracle that can be used to efficiently test if two vertices are connected by an edge.running time: O(n) hgeometry)Test if u and v are connected by an edge.running time: O(1) hgeometryEFind the edge data corresponding to edge (u,v) if such an edge existsrunning time: O(1) hgeometryhGiven a pair of vertices (u,v) returns the dart, oriented from u to v, corresponding to these vertices.running time: O(1)Pvwyxz|{}~P}~z|{vwyxNone%&'+,-0123456;<=>?FKNQSTV]eB hgeometrycAdjacency list representation of a graph: for each vertex we simply list all connected neighbours. hgeometryDFS on a planar graph.Running time: O(n)wNote that since our planar graphs are always connected there is no need need for dfs to take a list of start vertices. hgeometry+Transform into adjacencylist representation hgeometryFDFS, from a given vertex, on a graph in AdjacencyLists representation.Running time: O(n)None%&'+,-0123456;<=>?FKNQSTV]e  hgeometry Union find DS hgeometryMinimum spanning tree of the edges. The result is a rooted tree, in which the nodes are the vertices in the planar graph together with the edge weight of the edge to their parent. The root's weight is zero. The algorithm used is Kruskal's.running time:  O(n \log n) hgeometry6Computes the set of edges in the Minimum spanning treerunning time:  O(n \log n) hgeometry_Given an underlying planar graph, and a set of edges that form a tree, create the actual tree..pre: the planar graph has at least one vertex.  hgeometry~Union the components containing x and y. Returns weather or not the two components were already in the same component or not.  hgeometryGet the representative of the component containing x find :: (Enum a, Eq a) => UF s a -> a -> ST s a find uf = fmap fst . find' ufCget the representative (and its rank) of the component containing xGeneric Ranges (Intervals)(c) Frank StaalsSee LICENCE fileNone %&'+,-01234568;<=>?FKNQSTV]e  hgeometry"Data type for representing ranges. hgeometry2Endpoints of a range may either be open or closed. hgeometryBA range from l to u, ignoring/forgetting the type of the endpoints hgeometry Test if a value lies in a range.1 `inRange` (OpenRange 0 2)True1 `inRange` (OpenRange 0 1)False1 `inRange` (ClosedRange 0 1)True1 `inRange` (ClosedRange 1 1)True10 `inRange` (OpenRange 1 10)False10 `inRange` (ClosedRange 0 1)False hgeometryGet the width of the intervalwidth $ ClosedRange 1 109width $ OpenRange 5 105 hgeometrytClip the interval from below. I.e. intersect with the interval {l,infty), where { is either open, (, orr closed, [. hgeometryhClip the interval from above. I.e. intersect with (-infty, u}, where } is either open, ), or closed, ], hgeometry>Wether or not the first range completely covers the second one hgeometryCheck if the range is valid and nonEmpty, i.e. if the lower endpoint is indeed smaller than the right endpoint. Note that we treat empty open-ranges as invalid as well.  hgeometry!Compare end points, Closed < Open  hgeometry%Compare the end points, Open < Closed hgeometry!Shift a range x units to the left-prettyShow $ shiftLeft 10 (ClosedRange 10 20) "[0, 10]"+prettyShow $ shiftLeft 10 (OpenRange 15 25) "(5, 15)" hgeometryShifts the range to the right.prettyShow $ shiftRight 10 (ClosedRange 10 20) "[20, 30]",prettyShow $ shiftRight 10 (OpenRange 15 25) "(25, 35)"None%&'+,-0123456;<=>?FKNQSTV]e hgeometry,Open on left endpoint; so Closed before open& hgeometry.Order on right endpoint; so Open before Closed !&'()0 !)&'(0None%&'+,-0123456;<=>?FKNQSTV]e|1 hgeometryAn Interval is essentially a YZ but with possible payloadA hgeometryTest if a value lies in an interval. Note that the difference between inInterval and inRange is that the extra value is *not* used in the comparison with inInterval, whereas it is in inRange.)1236789:;<=>?@AB123@?>:;<=6789ABNone %&'+,-01234568;<=>?FKNQSTV]e L hgeometry1Information stored in a node of the Interval TreeV hgeometry.IntervalTree type, storing intervals of type i` hgeometry$Anything that looks like an intervalc hgeometry8Given an ordered list of points, create an interval treeO(n)d hgeometryBuild an interval tree O(n \log n)e hgeometry@Lists the intervals. We don't guarantee anything about the orderrunning time: O(n).f hgeometryFind all intervals that stab x O(\log n + k), where k is the output sizeg hgeometryFind all intervals that stab x O(\log n + k), where k is the output sizeh hgeometry@Insert : pre: the interval intersects some midpoint in the tree O(\log n)i hgeometry Delete an interval from the Tree O(\log n)) (under some general position assumption)LMNOPVWXYZ[`abcdefghiLMNOP[YZVWXb`acdhigfeNone%&'+,-0123456;<=>?FKNQSTV]e l hgeometryOInternal nodes store a split point, the range, and an associated data structureu hgeometryCLeaf nodes store an atomic range, and an associated data structure.  hgeometry.We store atomic ranges a bit more efficiently. hgeometry(Segment tree on a Fixed set of endpoints hgeometryInterval hgeometry%Class for associcated data structures hgeometryNGiven a sorted list of endpoints, without duplicates, construct a segment treeO(n) time  hgeometryInterleaves the two lists8interleave (NonEmpty.fromList ["0","1","2"]) ["01","12"]"0" :| ["01","1","12","2"] hgeometryBuild a SegmentTree O(n \log n)  hgeometrylists all intervals hgeometry'Search for all intervals intersecting x O(\log n + k) where k is the output size hgeometryBReturns the associated values of the nodes on the search path to x O(\log n)  hgeometry(Gets the range associated with this node hgeometryNPre: the interval should have one of the endpoints on which the tree is built. hgeometry Delete an interval from the tree pre: The segment is in the tree!"lmnopuvwxyz{"lmnop{zyuvwx[None%&'+,-0123456;<=>?FKNQSTV]eI"lmnopuvwxyz{ None"%&'+,-.0123456;<=>?FKNQSTV]e  hgeometryCoordinate wize minimum hgeometryCoordinate wize maximum hgeometrybGiven the point with the lowest coordinates and the point with highest coordinates, create a box. hgeometry)Build a d dimensional Box given d ranges. hgeometryNGiven a center point and a vector specifying the box width's, construct a box. hgeometryCenter of the box hgeometryCheck if a point lies a boxQorigin `inBox` (boundingBoxList' [point3 1 2 3, point3 10 20 30] :: Box 3 () Int)FalseZorigin `inBox` (boundingBoxList' [point3 (-1) (-2) (-3), point3 10 20 30] :: Box 3 () Int)True hgeometryGet a vector with the extent of the box in each dimension. Note that the resulting vector is 0 indexed whereas one would normally count dimensions starting at zero.Iextent (boundingBoxList' [point3 1 2 3, point3 10 20 30] :: Box 3 () Int)`Vector3 [Range (Closed 1) (Closed 10),Range (Closed 2) (Closed 20),Range (Closed 3) (Closed 30)] hgeometryGet the size of the box (in all dimensions). Note that the resulting vector is 0 indexed whereas one would normally count dimensions starting at zero.>size (boundingBoxList' [origin, point3 1 2 3] :: Box 3 () Int)Vector3 [1,2,3] hgeometryXGiven a dimension, get the width of the box in that dimension. Dimensions are 1 indexed.LwidthIn (C :: C 1) (boundingBoxList' [origin, point3 1 2 3] :: Box 3 () Int)1LwidthIn (C :: C 3) (boundingBoxList' [origin, point3 1 2 3] :: Box 3 () Int)3 hgeometrySame as 6 but with a runtime int instead of a static dimension.DwidthIn' 1 (boundingBoxList' [origin, point3 1 2 3] :: Box 3 () Int)Just 1DwidthIn' 3 (boundingBoxList' [origin, point3 1 2 3] :: Box 3 () Int)Just 3EwidthIn' 10 (boundingBoxList' [origin, point3 1 2 3] :: Box 3 () Int)Nothing hgeometryGet the corners of a rectangle, the order is: (TopLeft, TopRight, BottomRight, BottomLeft). The extra values in the Top points are taken from the Top point, the extra values in the Bottom points are taken from the Bottom point hgeometryOUnsafe version of boundingBoxList, that does not check if the list is non-empty!!!None%&'+,-0123456;<=>?FKNQSTV]e hgeometry;LSeq n a certifies that the sequence has *at least* n items  hgeometryJPromises that the length of this LSeq is actually n. This is not checked.This function should be a noop hgeometry[get the element with index i, counting from the left and starting at 0. O(log(min(i,n-i)))          555555 5 5"None%&'+,-0123456;<=>?FKNQSTV]e2 hgeometry^A view of the right end of the sequence, with the guarantee that it has at least one element.4 hgeometry Right viewsYA view of the right end of the seq, with the guarantee that it has at least two elements6 hgeometryAt least one element8 hgeometry Left views: hgeometry]Basically Data.Sequence but with the guarantee that the list contains at least two elements.= hgeometry[get the element with index i, counting from the left and starting at 0. O(log(min(i,n-i)))B hgeometry-Concatenate two sequences. O(log(min(n1,n2)))C hgeometry,pre: the list contains at least two elementsD hgeometryfmap but with an indexH hgeometryLConvert a Seq into a Seq2. It is not checked that the length is at least twoM hgeometryO(1) get a left viewP hgeometryO(1) get a right viewW hgeometryTWe throw away information here; namely that the combined list contains two elements.d hgeometryAt least two elements 23456789:;<=>?@ABCDEFGHIJKLMNOPQ :;<=>?@ABCDEFGH8967IJKLMNO4523PQ#None%&'+,-0123456;<=>?FKNQSTV]e#t hgeometryGiven a monotonic predicate, Get the index h such that everything strictly smaller than h has: p i = False, and all i >= h, we have p h = True)returns Nothing if no element satisfies prunning time: O(\log^2 n + T*\log n), where T' is the time to execute the predicate.u hgeometryGiven a monotonic predicate, get the index h such that everything strictly smaller than h has: p i = False, and all i >= h, we have p h = True)returns Nothing if no element satisfies prunning time:  O(T*\log n), where T' is the time to execute the predicate.v hgeometryGPartition the seq s given a monotone predicate p into (xs,ys) such thathall elements in xs do *not* satisfy the predicate p all elements in ys do satisfy the predicate p+all elements in s occur in either xs or ys.running time: O(\log^2 n + T*\log n), where T' is the time to execute the predicate.w hgeometryoGiven a monotonic predicate p, a lower bound l, and an upper bound u, with: p l = False p u = True l < u.rGet the index h such that everything strictly smaller than h has: p i = False, and all i >= h, we have p h = Truerunning time: O(\log(u - l))tuvwtuvw$None%&'+,-0123456;<=>?FKNQSTV]e7  hgeometryInsert into a monotone OrdSeq.*pre: the comparator maintains monotonicity O(\log^2 n) hgeometryInsert into a sorted OrdSeq O(\log^2 n) hgeometry O(\log^2 n) hgeometryGiven a monotonic function f that maps a to b, split the sequence s depending on the b values. I.e. the result (l,m,r) is such that * all (< x) . fmap f $ l * all (== x) . fmap f $ m * all (> x) . fmap f $ r"splitOn id 3 $ fromAscList' [1..5]{(OrdSeq {_asSeq = fromList [Elem 1,Elem 2]},OrdSeq {_asSeq = fromList [Elem 3]},OrdSeq {_asSeq = fromList [Elem 4,Elem 5]})NsplitOn fst 2 $ fromAscList' [(0,"-"),(1,"A"),(2,"B"),(2,"C"),(3,"D"),(4,"E")](OrdSeq {_asSeq = fromList [Elem (0,"-"),Elem (1,"A")]},OrdSeq {_asSeq = fromList [Elem (2,"B"),Elem (2,"C")]},OrdSeq {_asSeq = fromList [Elem (3,"D"),Elem (4,"E")]}) O(\log^2 n) hgeometrywGiven a monotonic predicate p, splits the sequence s into two sequences (as,bs) such that all (not p) as and all p bs O(\log^2 n) hgeometry inserts all eleements in order  O(n\log n) hgeometry inserts all eleements in order  O(n\log n) hgeometryO(n) hgeometry O(\log^2 n) hgeometry)Fmap, assumes the order does not change O(n) hgeometry*Gets the first element from the sequence O(1)xyz{|}~|}~yz{x%None%&'+,-0123456;<=>?FKNQSTV]eB hgeometry?`UnBounded a` represents the type a, together with an element / larger than any other element, and an element ", smaller than any other element. hgeometry2`Bottom a` represents the type a, together with a p element, i.e. an element that is smaller than any other element. We can think of `Bottom a` being defined as:data Bottom a = Bottom | ValB a hgeometry/`Top a` represents the type a, together with a l element, i.e. an element that is greater than any other element. We can think of `Top a` being defined as:data Top a = ValT a | Top&None %&'+,-0123456;<=>?FKNQSTV]eO  hgeometryrPart of a line. The interval is ranged based on the vector of the line l, and s.t.t zero is the anchorPoint of l. hgeometryGet the point at the given position along line, where 0 corresponds to the anchorPoint of the line, and 1 to the point anchorPoint .+^ directionVector hgeometry3Annotate the subRange with the actual ending points hgeometryNgiven point p on line (Line q v), Get the scalar lambda s.t. p = q + lambda v hgeometrytgiven point p, and a Subline l r such that p lies on line l, test if it lies on the subline, i.e. in the interval r hgeometrytgiven point p, and a Subline l r such that p lies on line l, test if it lies on the subline, i.e. in the interval r  '@Line segment data type and some basic functions on line segments(c) Frank StaalsSee LICENCE fileNone %&'+,-0123456;<=>?FKNQSTV]esi  hgeometryLine segments. LineSegments have a start and end point, both of which may contain additional data of type p. We can think of a Line-Segment being defined as\data LineSegment d p r = LineSegment (EndPoint (Point d r :+ p)) (EndPoint (Point d r :+ p)) hgeometryHGets the start and end point, but forgetting if they are open or closed. hgeometry6Pattern that essentially models the line segment as a:\data LineSegment d p r = LineSegment (EndPoint (Point d r :+ p)) (EndPoint (Point d r :+ p)) hgeometry,Directly convert a line into a line segment. hgeometry'Test if a point lies on a line segment.N(point2 1 0) `onSegment` (ClosedLineSegment (origin :+ ()) (point2 2 0 :+ ()))TrueN(point2 1 1) `onSegment` (ClosedLineSegment (origin :+ ()) (point2 2 0 :+ ()))FalseN(point2 5 0) `onSegment` (ClosedLineSegment (origin :+ ()) (point2 2 0 :+ ()))FalseQ(point2 (-1) 0) `onSegment` (ClosedLineSegment (origin :+ ()) (point2 2 0 :+ ()))FalseN(point2 1 1) `onSegment` (ClosedLineSegment (origin :+ ()) (point2 3 3 :+ ()))TrueVNote that the segments are assumed to be closed. So the end points lie on the segment.N(point2 2 0) `onSegment` (ClosedLineSegment (origin :+ ()) (point2 2 0 :+ ()))TrueHorigin `onSegment` (ClosedLineSegment (origin :+ ()) (point2 2 0 :+ ()))True,This function works for arbitrary dimensons.R(point3 1 1 1) `onSegment` (ClosedLineSegment (origin :+ ()) (point3 3 3 3 :+ ()))TrueR(point3 1 2 1) `onSegment` (ClosedLineSegment (origin :+ ()) (point3 3 3 3 :+ ()))False hgeometryNThe left and right end point (or left below right if they have equal x-coords) hgeometryLength of the line segment hgeometryNSquared distance from the point to the Segment s. The same remark as for the  applies here. hgeometryESquared distance from the point to the Segment s, and the point on s realizing it. Note that if the segment is *open*, the closest point returned may be one of the (open) end points, even though technically the end point does not lie on the segment. (The true closest point then lies arbitrarily close to the end point). hgeometry,flips the start and end point of the segment31236789:;<=>?@AB31236789:;<=>?@AB( Orthogonal d%-dimensiontal boxes (e.g. rectangles)(c) Frank StaalsSee LICENCE fileNone"%&'+,-01234568;<=>?FKNQSTV]e hgeometryOriented from *left to right* hgeometry-The right side, oriented from *bottom* to top hgeometryThe sides of the rectangle, in order (Top, Right, Bottom, Left). The sides themselves are also oriented in clockwise order. If, you want them in the same order as the functions , , , and , use  instead. hgeometryYThe sides of the rectangle. The order of the segments is (Top, Right, Bottom, Left). Note that the segments themselves, are oriented as described by the functions topSide, bottomSide, leftSide, rightSide (basically: from left to right, and from bottom to top). If you want the segments oriented along the boundary of the rectangle, use the  function instead.')None %&'+,-0123456;<=>?FKNQSTV]e! hgeometryA Poly line in R^d hgeometry0pre: The input list contains at least two points hgeometry`pre: The input list contains at least two points. All extra vields are initialized with mempty. hgeometry'We consider the line-segment as closed. hgeometry@Convert to a closed line segment by taking the first two points. hgeometry\Stricter version of asLineSegment that fails if the Polyline contains more than two points.  *None %&'+,-0123456;<=>?FKNQSTV]e]  hgeometry$Data that we store in the split tree    #$'&%()*+,-.345    -,.+()*#$'&%543+None%&'+,-0123456;<=>?FKNQSTV]er6 hgeometryCST monad with access to the vector storign the level of the points.7 hgeometryConstruct a split treerunning time:  O(n \log n)8 hgeometry5Given a split tree, generate the Well separated pairsrunning time: O(s^d n)9 hgeometryKGiven the points, sorted in every dimension, recursively build a split treeThe algorithm works in rounds. Each round takes O(n) time, and halves the number of points. Thus, the total running time is O(n log n).The algorithm essentially builds a path in the split tree; at every node on the path that we construct, we split the point set into two sets (L,R) according to the longest side of the bounding box.The smaller set is "assigned" to the current node and set asside. We continue to build the path with the larger set until the total number of items remaining is less than n/2.`To start the next round, each node on the path needs to have the points assigned to that node, sorted in each dimension (i.e. the Vector (PointSeq))'s. Since we have the level assignment, we can compute these lists by traversing each original input list (i.e. one for every dimension) once, and partition the points based on their level assignment.: hgeometry2Assign the points to their the correct class. The  $ class is considered the last class< hgeometry2Assign the points to their the correct class. The  $ class is considered the last class= hgeometryGiven a sequence of points, whose index is increasing in the first dimension, i.e. if idx p < idx q, then p[0] < q[0]. Reindex the points so that they again have an index in the range [0,..,n'], where n' is the new number of points.Xrunning time: O(n' * d) (more or less; we are actually using an intmap for the lookups)alternatively: I can unsafe freeze and thaw an existing vector to pass it along to use as mapping. Except then I would have to force the evaluation order, i.e. we cannot be in =( for two of the nodes at the same time.0so, basically, run reIndex points in ST as well.> hgeometryAssigns the points to a level. Returns the list of levels used. The first level in the list is the level assigned to the rest of the nodes. Their level is actually still set to Nothing in the underlying array.? hgeometry9Remove already assigned pts from the ends of all vectors.@ hgeometryAssign level l to point pA hgeometryGet the level of a pointB hgeometry5Test if the point already has a level assigned to it.C hgeometry1Remove allready assigned points from the sequencepre: there are points remainingD hgeometryGiven the points, ordered by their j^th coordinate, split the point set into a "left" and a "right" half, i.e. the points whose j^th coordinate is at most the given mid point m, and the points whose j^th coordinate is larger than m.,We return a pair (Largest set, Smallest set)fi ndAndCompact works by simultaneously traversing the points from left to right, and from right to left. As soon as we find a point crossing the mid point we stop and return. Thus, in principle this takes only O(|Smallest set|) time.running time: O(|Smallest set|) + R, where R is the number of *old* points (i.e. points that should have been removed) in the list.E hgeometry*Find the widest dimension of the point set3pre: points are sorted according to their dimensionG hgeometry]get the extends of the set of points in every dimension, i.e. the left and right boundaries.3pre: points are sorted according to their dimensionI hgeometry4Test if the two sets are well separated with param sJ hgeometry1Test if the two boxes are sufficiently far appartM hgeometry)Computes the maximum width of a splitTreeN hgeometryComputes! the bounding box of a split treeQ hgeometryTurn a traversal into lens< hgeometrynumber of classes hgeometrylevel assignment hgeometry input points> hgeometry"Number of items we need to collect hgeometry#Number of items we collected so far hgeometrynext level to use hgeometryLevels used so farD hgeometryWthe dimension we are in, i.e. so that we know which coordinate of the point to compare hgeometry the mid pointI hgeometryseparation factor6789:;<=>?@ABCDEFGHIJKLMNOPQR789:;<=6>?@ABCDEFGHIJKLMNOPQR,None%&'+,-0123456;<=>?FKNQSTV]eیS hgeometryLine simplification with the well-known Douglas Peucker alogrithm. Given a distance value eps adn a polyline pl, constructs a simplification of pl (i.e. with vertices from pl) s.t. all other vertices are within dist eps to the original polyline.5Running time: O(n^2) worst case, O(n log n) expected.T hgeometry;Concatenate the two polylines, dropping their shared vertexU hgeometryJSplit the polyline at the given vertex. Both polylines contain this vertexV hgeometryGiven a sequence of points, find the index of the point that has the Furthest distance to the LineSegment. The result is the index of the point and this distance.STUVSTUV-None%&'+,-0123456;<=>?FKNQSTV]eސm hgeometry]reports true if there is at least one segment for which this intersection point is interior.O(1)WXZY[\]_^`abcdklma`\]_^bcd[WXZYlkm.None%&'+,-0123456;<=>?FKNQSTV]en hgeometry#Compute all intersections (naively)O(n^2)o hgeometryHTest if the two segments intersect, and if so add the segment to the mapp hgeometry"Add s and s' to the map with key pq hgeometry(figure out which map to add the point tonopqrsnopqrs/None%&'+,-0123456;<=>?FKNQSTV]ev hgeometry1The actual event consists of a point and its typez hgeometryType of segment~ hgeometryCompute all intersectionsO((n+k)\log n), where k is the number of intersections. hgeometry`Computes all intersection points p s.t. p lies in the interior of at least one of the segments.O((n+k)\log n), where k is the number of intersections. hgeometry2Computes the event points for a given line segment hgeometry/Group the segments with the intersection points hgeometry\Group the startpoints such that segments with the same start point correspond to one event. hgeometry4An ordering that is decreasing on y, increasing on x hgeometry4Get the segments that start at the given event point hgeometryYCompare based on the x-coordinate of the intersection with the horizontal line through y hgeometryGiven a y coord and a line segment that intersects the horizontal line through y, compute the x-coordinate of this intersection point.Lnote that we will pretend that the line segment is closed, even if it is not hgeometry!Run the sweep handling all events hgeometryHandle an event point hgeometryjsplit the status structure, extracting the segments that contain p. the result is (before,contains,after) hgeometry`Given a point and the linesegements that contain it. Create a piece of status structure for it. hgeometry#Get the right endpoint of a segment hgeometryTest if a segment ends at p hgeometryFind all eventstuvwyxz}|{~~z}|{vwyxut0None %&'+,-0123456;<=>?BFKNQSTV]e hgeometry*Lines are transformable, via line segments     !1None %&'+,-0123456;<=>?FKNQSTV]ej hgeometryMThe two bounding lines of the slab, first the lower one, then the higher one: hgeometry0Smart consturctor for creating a horizontal slab hgeometry.Smart consturctor for creating a vertical slab  2None%&'+,-0123456;<=>?FKNQSTV]e2 hgeometry1Maps a line point (px,py) to a line (y=px*x - py) hgeometryZReturns Nothing if the input line is vertical Maps a line l: y = ax + b to a point (a,-b) hgeometry#Pre: the input line is not vertical3d-dimensional Balls and Spheres(c) Frank StaalsSee LICENCE fileNone %&'+,-0123456;<=>?FKNQSTV]e`  hgeometryA d-dimensional ball. hgeometry%Spheres, i.e. the boundary of a ball. hgeometry&A lens to get/set the radius of a Ball hgeometry?Given two points on the diameter of the ball, construct a ball. hgeometryFConstruct a ball given the center point and a point p on the boundary. hgeometry1A d dimensional unit ball centered at the origin. hgeometry+Test if a point lies strictly inside a ball&(point2 0.5 0.0) `insideBall` unitBallTrue"(point2 1 0) `insideBall` unitBallFalse"(point2 2 0) `insideBall` unitBallFalse hgeometry&Test if a point lies in or on the ball hgeometry/Test if a point lies on the boundary of a ball.(point2 1 0) `onBall` unitBallTrue (point3 1 1 0) `onBall` unitBallFalse hgeometrytGiven three points, get the disk through the three points. If the three input points are colinear we return Nothing1disk (point2 0 10) (point2 10 0) (point2 (-10) 0)FJust (Ball {_center = Point2 [0.0,0.0] :+ (), _squaredRadius = 100.0}) hgeometry2Creates a circle from three points on the boundary4None%&'+,-0123456;<=>?FKNQSTV]eL hgeometryCompute the area of a triangle hgeometry2*the area of a triangle. hgeometryhget the inscribed disk. Returns Nothing if the triangle is degenerate, i.e. if the points are colinear.5None!%&'+,-01234568;<=>?FKNQSTV]e$ hgeometryd-dimensional Half-Lines hgeometry#Test if a point lies on a half-line hgeometryTransform a LineSegment into a half-line, by forgetting the second endpoint. Note that this also forgets about if the starting point was open or closed.  6None%&'+,-0123456;<=>?FKNQSTV]e't hgeometry$Strict pair with both items the same hgeometry Strict pair hgeometry strict triple7CA Polygon data type and some basic functions to interact with them.(c) Frank StaalsSee LICENCE fileNone%&'+,-0123456;<=>?FKNQSTV]elO hgeometryEither a simple or multipolygon hgeometryOWe distinguish between simple polygons (without holes) and Polygons with holes. hgeometry,Access the i^th vertex on the outer boundary  hgeometryGet all holes in a polygon! hgeometryXThe vertices in the polygon. No guarantees are given on the order in which they appear!" hgeometry9Creates a simple polygon from the given list of vertices.3pre: the input list constains no repeated vertices.# hgeometryKThe edges along the outer boundary of the polygon. The edges are half open.running time: O(n)$ hgeometryLists all edges. The edges on the outer boundary are given before the ones on the holes. However, no other guarantees are given on the order.running time: O(n)% hgeometryvPairs every vertex with its incident edges. The first one is its predecessor edge, the second one its successor edge.<mapM_ print . polygonVertices $ withIncidentEdges simplePolyPoint2 [0 % 1,0 % 1] :+ SP LineSegment (Closed (Point2 [1 % 1,11 % 1] :+ ())) (Closed (Point2 [0 % 1,0 % 1] :+ ())) LineSegment (Closed (Point2 [0 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,0 % 1] :+ ()))Point2 [10 % 1,0 % 1] :+ SP LineSegment (Closed (Point2 [0 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,0 % 1] :+ ())) LineSegment (Closed (Point2 [10 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,10 % 1] :+ ()))Point2 [10 % 1,10 % 1] :+ SP LineSegment (Closed (Point2 [10 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,10 % 1] :+ ())) LineSegment (Closed (Point2 [10 % 1,10 % 1] :+ ())) (Closed (Point2 [5 % 1,15 % 1] :+ ()))Point2 [5 % 1,15 % 1] :+ SP LineSegment (Closed (Point2 [10 % 1,10 % 1] :+ ())) (Closed (Point2 [5 % 1,15 % 1] :+ ())) LineSegment (Closed (Point2 [5 % 1,15 % 1] :+ ())) (Closed (Point2 [1 % 1,11 % 1] :+ ()))Point2 [1 % 1,11 % 1] :+ SP LineSegment (Closed (Point2 [5 % 1,15 % 1] :+ ())) (Closed (Point2 [1 % 1,11 % 1] :+ ())) LineSegment (Closed (Point2 [1 % 1,11 % 1] :+ ())) (Closed (Point2 [0 % 1,0 % 1] :+ ()))& hgeometryUGiven the vertices of the polygon. Produce a list of edges. The edges are half-open.' hgeometryATest if q lies on the boundary of the polygon. Running time: O(n)"point2 1 1 `onBoundary` simplePolyFalse"point2 0 0 `onBoundary` simplePolyTrue#point2 10 0 `onBoundary` simplePolyTrue#point2 5 13 `onBoundary` simplePolyFalse#point2 5 10 `onBoundary` simplePolyFalse#point2 10 5 `onBoundary` simplePolyTrue#point2 20 5 `onBoundary` simplePolyFalseTODO: testcases multipolygon( hgeometryhCheck if a point lies inside a polygon, on the boundary, or outside of the polygon. Running time: O(n).!point2 1 1 `inPolygon` simplePolyInside!point2 0 0 `inPolygon` simplePoly OnBoundary"point2 10 0 `inPolygon` simplePoly OnBoundary"point2 5 13 `inPolygon` simplePolyInside"point2 5 10 `inPolygon` simplePolyInside"point2 10 5 `inPolygon` simplePoly OnBoundary"point2 20 5 `inPolygon` simplePolyOutsideUTODO: Add some testcases with multiPolygons TODO: Add some more onBoundary testcases) hgeometry1Test if a point lies strictly inside the polgyon.* hgeometryCompute the area of a polygon+ hgeometryCompute the signed area of a simple polygon. The the vertices are in clockwise order, the signed area will be negative, if the verices are given in counter clockwise order, the area will be positive., hgeometry)Compute the centroid of a simple polygon.- hgeometryVTest if the outer boundary of the polygon is in clockwise or counter clockwise order.running time: O(n). hgeometry,Orient the outer boundary to clockwise order/ hgeometry4Orient the outer boundary to counter clockwise order1 hgeometryDConvert a Polygon to a simple polygon by forgetting about any holes.2 hgeometry(Comparison that compares which point is larger) in the direction given by the vector u.3 hgeometryCFinds the extreme points, minimum and maximum, in a given directionrunning time: O(n)4 hgeometryassigns unique integer numbers to all vertices. Numbers start from 0, and are increasing along the outer boundary. The vertices of holes will be numbered last, in the same order.numberVertices simplePolySimplePolygon CSeq [Point2 [0 % 1,0 % 1] :+ SP 0 (),Point2 [10 % 1,0 % 1] :+ SP 1 (),Point2 [10 % 1,10 % 1] :+ SP 2 (),Point2 [5 % 1,15 % 1] :+ SP 3 (),Point2 [1 % 1,11 % 1] :+ SP 4 ()]# !"#$%&'()*+,-./01234# !"#$%&'()*+,-./012348None!%&'+,-0123456;<=>?FKNQSTV]ej/> hgeometry&Note that the functor instance is in vF hgeometry#Embedded, *connected*, planar graphS hgeometryrConstruct a plane graph from a simple polygon. It is assumed that the polygon is given in counterclockwise order..the interior of the polygon will have faceId 0Ipre: the input polygon is given in counterclockwise order running time: O(n).  hgeometry+Constructs a planar from the given verticesT hgeometry"Constructs a connected plane graph3pre: The segments form a single connected componentrunning time:  O(n\log n)U hgeometryGet the number of verticesnumVertices myGraph4V hgeometryGet the number of DartsnumDarts myGraph12W hgeometryGet the number of EdgesnumEdges myGraph6X hgeometryGet the number of facesnumFaces myGraph4Y hgeometryEnumerate all verticesvertices' myGraph-[VertexId 0,VertexId 1,VertexId 2,VertexId 3]Z hgeometry7Enumerate all vertices, together with their vertex data[ hgeometryEnumerate all darts\ hgeometry6Enumerate all edges. We report only the Positive darts] hgeometry6Lens to access the raw dart data, use at your own risk^ hgeometrylens to access the Dart Data_ hgeometryLens to access face dataa hgeometryMEnumerate all edges with their edge data. We report only the Positive darts.mapM_ print $ edges myGraph(Dart (Arc 2) +1,"c+")(Dart (Arc 1) +1,"b+")(Dart (Arc 0) +1,"a+")(Dart (Arc 5) +1,"g+")(Dart (Arc 4) +1,"e+")(Dart (Arc 3) +1,"d+")b hgeometry&Enumerate all faces in the plane graphc hgeometryAll faces with their face data.d hgeometryHReports the outerface and all internal faces separately. running time: O(n)e hgeometry+Reports all internal faces. running time: O(n)f hgeometry=The tail of a dart, i.e. the vertex this dart is leaving fromrunning time: O(1)g hgeometry%The vertex this dart is heading in torunning time: O(1)h hgeometry(endPoints d g = (tailOf d g, headOf d g)running time: O(1)i hgeometryCAll edges incident to vertex v, in counterclockwise order around v.running time: O(k), where k is the output sizej hgeometryLAll incoming edges incident to vertex v, in counterclockwise order around v.k hgeometryLAll outgoing edges incident to vertex v, in counterclockwise order around v.l hgeometryYGets the neighbours of a particular vertex, in counterclockwise order around the vertex.running time: O(k), where k is the output sizem hgeometrybGiven a dart d that points into some vertex v, report the next dart in the cyclic order around v.running time: O(1)n hgeometrybGiven a dart d that points into some vertex v, report the next dart in the cyclic order around v.running time: O(1)o hgeometry The face to the left of the dartleftFace (dart 1 "+1") myGraphFaceId 1leftFace (dart 1 "-1") myGraphFaceId 2leftFace (dart 2 "+1") myGraphFaceId 2leftFace (dart 0 "+1") myGraphFaceId 0running time: O(1).p hgeometry!The face to the right of the dartrightFace (dart 1 "+1") myGraphFaceId 2rightFace (dart 1 "-1") myGraphFaceId 1rightFace (dart 2 "+1") myGraphFaceId 1rightFace (dart 0 "+1") myGraphFaceId 1running time: O(1).q hgeometry Get the next edge along the facerunning time: O(1).r hgeometry$Get the previous edge along the facerunning time: O(1).s hgeometrytThe darts bounding this face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size.t hgeometryEGenerates the darts incident to a face, starting with the given dart.O(k), where k is the number of darts reportedu hgeometrywThe vertices bounding this face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size.x hgeometry.Getter for the data at the endpoints of a dartrunning time: O(1)y hgeometry/Data corresponding to the endpoints of the dartrunning time: O(1)z hgeometrygets the id of the outer facerunning time: O(n){ hgeometry[gets a dart incident to the outer face (in particular, that has the outerface on its left)running time: O(n)| hgeometry"Reports all edges as line segments} hgeometryLGiven a dart and the graph constructs the line segment representing the dartO(1)~ hgeometryThe polygon describing the face runningtime: O(k), where k is the size of the face. hgeometryAlias for rawFace Boundary runningtime: O(k), where k is the size of the face. hgeometry#Lists all faces of the plane graph. hgeometry_Labels the edges of a plane graph with their distances, as specified by the distance function.S hgeometry data inside hgeometrydata outside the polygonJv>?FGHIJRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~JFGR>?IHJSTUWXVYZ\abced[gfhijklmnopqrstuz{vwxy`_^]}|~v9Convex Polygons(c) Frank StaalsSee LICENCE fileNone %&'+,-0123456;<=>?FKNQSTV]e_  hgeometryCFinds the extreme points, minimum and maximum, in a given direction*pre: The input polygon is strictly convex.running time:  O(\log n) hgeometryBFinds the extreme maximum point in the given direction. Based on /http://geomalgorithms.com/a14-_extreme_pts.html*pre: The input polygon is strictly convex.running time:  O(\log^2 n) hgeometryRotating Right  - rotate clockwise-Merging two convex hulls, based on the paper:Two Algorithms for Constructing a Delaunay Triangulation Lee and Schachter International Journal of Computer and Information Sciences, Vol 9, No. 3, 1980O: (combined hull, lower tangent that was added, upper tangent thtat was added) hgeometry-Compute the lower tangent of the two polgyonspre: - polygons lp and rp have at least 1 vertex - lp and rp are disjoint, and there is a vertical line separating the two polygons. - The vertices of the polygons are given in clockwise orderRRunning time: O(n+m), where n and m are the sizes of the two polygons respectively hgeometry-Compute the upper tangent of the two polgyonspre: - polygons lp and rp have at least 1 vertex - lp and rp are disjoint, and there is a vertical line separating the two polygons. - The vertices of the polygons are given in clockwise orderRRunning time: O(n+m), where n and m are the sizes of the two polygons respectively hgeometry]Computes the Minkowski sum of the two input polygons with $n$ and $m$ vertices respectively.%pre: input polygons are in CCW order.running time: O(n+m).  hgeometryERotate to the rightmost point (rightmost and topmost in case of ties)  hgeometry=Rotate to the leftmost point (and bottommost in case of ties) hgeometry=Rotate to the bottommost point (and leftmost in case of ties)  hgeometry.Helper to get the vertices of a convex polygon:None"%&'+,-0123456;<=>?FKNQSTV]ef) hgeometry=The Face data consists of the data itself and a list of holes hgeometryA planarsubdivision is essentially a bunch of plane-graphs; one for every connected component. These graphs store the global ID's (darts, vertexId's, faceId's) in their data values. This essentially gives us a mapping between the two.note that a face may actually occur in multiple graphs, hence when we store the edges to the the holes, we store the global edgeId's rather than the local edgeId (dart)'s.%invariant: the outerface has faceId 0 hgeometryA connected component.For every face f, and every hole in this face, the facedata points to a dart d on the hole s.t. this dart has the face f on its left. i.e. leftFace d = f hgeometryNData type that expresses whether or not we are inside or outside the polygon. hgeometry0Constructs a planarsubdivision from a PlaneGraph runningTime: O(n) hgeometrynGiven a (connected) PlaneGraph and a dart that has the outerface on its left | Constructs a planarsubdivision runningTime: O(n) hgeometry4Construct a planar subdivision from a simple polygonrunning time: O(n). hgeometry*Constructs a connected planar subdivision.Cpre: the segments form a single connected component running time:  O(n\log n) hgeometryGet the number of verticesnumVertices myGraph4 hgeometryGet the number of DartsnumDarts myGraph12 hgeometryGet the number of EdgesnumEdges myGraph6 hgeometryGet the number of facesnumFaces myGraph4 hgeometryEnumerate all verticesvertices' myGraph-[VertexId 0,VertexId 1,VertexId 2,VertexId 3] hgeometry7Enumerate all vertices, together with their vertex data hgeometryEnumerate all darts hgeometry6Enumerate all edges. We report only the Positive darts hgeometryMEnumerate all edges with their edge data. We report only the Positive darts.mapM_ print $ edges myGraph(Dart (Arc 2) +1,"c+")(Dart (Arc 1) +1,"b+")(Dart (Arc 0) +1,"a+")(Dart (Arc 5) +1,"g+")(Dart (Arc 4) +1,"e+")(Dart (Arc 3) +1,"d+") hgeometryDEnumerates all faces with their face data exlcluding the outer face hgeometry=The tail of a dart, i.e. the vertex this dart is leaving fromrunning time: O(1) hgeometry%The vertex this dart is heading in torunning time: O(1) hgeometry(endPoints d g = (tailOf d g, headOf d g)running time: O(1) hgeometryCAll edges incident to vertex v, in counterclockwise order around v.running time: O(k), where k! is the number of edges reported. hgeometrydGiven a dart d that points into some vertex v, report the next dart e in the cyclic order around v.running time: O(1) hgeometryLAll incoming edges incident to vertex v, in counterclockwise order around v. hgeometryLAll outgoing edges incident to vertex v, in counterclockwise order around v. hgeometryYGets the neighbours of a particular vertex, in counterclockwise order around the vertex.running time: O(k), where k is the output size hgeometry The face to the left of the dartrunning time: O(1). hgeometry!The face to the right of the dartrunning time: O(1). hgeometryThe darts on the outer boundary of the face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size. hgeometryThe vertices of the outer boundary of the face, for internal faces in clockwise order, for the outer face in counter clockwise order.running time: O(k), where k is the output size. hgeometryZLists the holes in this face, given as a list of darts to arbitrary darts on those faces.running time: O(k), where k! is the number of darts returned.  hgeometryENote that using the setting part of this lens may be very expensive!! hgeometry.Getter for the data at the endpoints of a dartrunning time: O(1) hgeometry/data corresponding to the endpoints of the dartrunning time: O(1) hgeometrygets the id of the outer facerunning time: O(1) hgeometry"Reports all edges as line segments hgeometryLGiven a dart and the subdivision constructs the line segment representing itO(1) hgeometryEGenerates the darts incident to a face, starting with the given dart.O(k), where k is the number of darts reported hgeometry)Constructs the outer boundary of the faceO(k), where k4 is the complexity of the outer boundary of the face hgeometry)Constructs the boundary of the given faceO(k), where k is the complexity of the face hgeometry*Lists all faces of the planar subdivision. hgeometry data inside hgeometrydata outside the polygonVv>?FHIV>?IHFv;None%&'+,-0123456;<=>?FKNQSTV]e)y hgeometryUGiven a list of original edges and a list of diagonals, creates a planar-subdivisionrunning time:  O(n\log n) hgeometryUGiven a list of original edges and a list of diagonals, creates a planar-subdivisionrunning time:  O(n\log n) hgeometry3A counter-clockwise edge along the outer boundary hgeometryremaining original edges hgeometry diagonals hgeometry3A counter-clockwise edge along the outer boundary hgeometryremaining original edges hgeometry diagonals<None!%&'+,-0123456;<=>?FKNQSTV]ef4 hgeometryConstruct a planar subdivision from a polygon. Since our PlanarSubdivision models only connected planar subdivisions, this may add dummy/invisible edges.running time: O(n) for a simple polygon,  O(n\log n) for a polygon with holes. hgeometryGiven a list of *disjoint* polygons, construct a planarsubdivsion representing them. This may create dummy vertices which have no vertex data, hence the 'Maybe p' data type for the vertices.running time:  O(n\log n)  hgeometrygrows the box by x on all sides hgeometry data inside hgeometrydata outside the polygon hgeometrydata outside the polygonsXv>?FHI=None#%&'+,-0123456;<=>?FKNQSTV]eO hgeometry Image Objects hgeometryIpe Symbols, i.e. PointsA symbol (point) in ipe hgeometry Text Objects, hgeometryGExample of an IpeSymbol. I.e. A symbol that expresses that the size is larger sizeSymbol :: Attributes (AttrMapSym1 r) (SymbolAttributes r) sizeSymbol = attr SSize (IpeSize $ Named "large")PathsIPaths consist of Path Segments. PathSegments come in the following forms:: hgeometry/A path is a non-empty sequence of PathSegments.H hgeometry#type that represents a path in ipe.V hgeometryzThe mapping between the labels of the the attributes and the types of the attributes with these labels. For example, the = label/attribute should have a value of type 'Matrix 3 3 r'.g hgeometryBAn IpeObject' is essentially the oject ogether with its attributesi hgeometry,Attributes' :: * -> [AttributeUniverse] -> *k hgeometryGroups and ObjectsGroup Attributes,A group is essentially a list of IpeObjects. hgeometry;The definition of a view make active layer into an index ? hgeometrycollect all non-group objects hgeometry#for now we pretty much ignore these hgeometry The maybe string is the encoding hgeometryWAn IpePage is essentially a Group, together with a list of layers and a list of views. hgeometryA complete ipe file hgeometry$Creates a simple page with no views. hgeometryJConvenience function to construct an ipe file consisting of a single page. hgeometry7Create a single page ipe file from a list of IpeObjects hgeometry8Takes and applies the ipe Matrix attribute of this item. hgeometry2Applies the matrix to an ipe object if it has one.    ,43210/.-56:;<=>?@ABCDHQPONMLKJIRVWXYZ[\]^_`fedcbaghijklmnopqrs{|}~ć    65,43210/.-DCBA@?>=:;<RHQPONMLKJI_^]\[ZYXWVrpqnoklmjihgs`fedcba~}|{>None %&'+,-0123456;<=>?FKNQSTV]ee  hgeometryTypes that correspond to an XML Element. All instances should produce an Element. If the type should produce a Node with the Text constructor, use the  typeclass instead. hgeometry'For types that can produce a text value hgeometryGiven a prism to convert something of type g into an ipe file, a file path, and a g. Convert the geometry and write it to file.Write an IpeFiele to file. hgeometry2Creates a single page ipe file with the given page hgeometryConvert the input to ipeXml, and prints it to standard out in such a way that the copied text can be pasted into ipe as a geometry object. hgeometry$Convert input into an ipe selection. hgeometryConvert to Ipe xml hgeometry2Convert to ipe XML and write the output to a file. hgeometry(Functon to write all attributes in a Rec hgeometryWriting the attribute values hgeometryAdd attributes to a node hgeometrySame as  but then for a Maybe node hgeometryCThis instance converts the ratio to a Pico, and then displays that.?None%&'+,-01234567;<=>?FKNQSTV]ej,  hgeometryORepresent stuff that can be used as a coordinate in ipe. (similar to show/read)  hgeometryRunning the parsers  hgeometryThe parsers themselves  hgeometry/Generate a matrix from a list of 6 coordinates.                                  @None %&'+,-0123456;<=>?FKNQSTV]e " hgeometryOBasically IpeReadText for attributes. This class is not really meant to be implemented directly. Just define an IpeReadText instance for the type (Apply f at), then the generic instance below takes care of looking up the name of the attribute, and calling the right ipeReadText value. This class is just so that reifyConstraint in  /7 can select the right typeclass when building the rec. $ hgeometryReading an ipe lement from Xml & hgeometry'Reading an ipe elemtn from a Text value ) hgeometry,Given a file path, tries to read an ipe file * hgeometry]Given a file path, tries to read an ipe file. This function applies all matrices to objects. + hgeometrywSince most Ipe file contain only one page, we provide a shortcut for that as well. This function applies all matrices. , hgeometryqGiven a Bytestring, try to parse the bytestring into anything that is IpeReadable, i.e. any of the Ipe elements. - hgeometry3Reads the data from a Bytestring into a proper Node  hgeometry&Combination of zipRecWith and traverse / hgeometryReading the Attributes into a Rec (Attr f), all based on the types of f (the type family mapping labels to types), and a list of labels (ats). 0 hgeometryReader for records. Given a proxy of some ipe type i, and a proxy of an coordinate type r, read the IpeAttributes for i from the xml node. 1 hgeometryIf we can ipeRead an ipe element, and we can ipeReadAttrs its attributes we can properly read an ipe object using ipeReadObject  hgeometry{Given a list of Nodes, try to parse all of them as a big text. If we encounter anything else then text, the parsing fails.  hgeometry:try reading everything as an a. Throw away whatever fails. N hgeometryIpe read instances " # $ % & ' ( ) * + , - . / 0 1 ) * + ( , - & ' $ % " # . 1 0 / ANone%&'+,-0123456;<=>?FKNQSTV]ea S hgeometry|Try to convert a path into a line segment, fails if the path is not a line segment or a polyline with more than two points. T hgeometry5Convert to a polyline. Ignores all non-polyline partstestPath ^? _asPolyLinepJust (PolyLine {_points = Seq2 (Point2 [0,0] :+ ()) (fromList [Point2 [10,10] :+ ()]) (Point2 [200,100] :+ ())}) U hgeometryConvert to a simple polygon V hgeometryConvert to a multipolygon Y hgeometryuse the first prism to select the ipe object to depicle with, and the second how to select the geometry object from there on. Then we can select the geometry object, directly with its attributes here.-testObject ^? _withAttrs _IpePath _asPolyLine]Just (PolyLine {_points = Seq2 (Point2 [0,0] :+ ()) (fromList [Point2 [10,10] :+ ()]) (Point2 [200,100] :+ ())} :+ Attrs {_unAttrs = {GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Just (IpeColor (Named "red"))}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}, GAttr {_getAttr = Nothing}}}) Z hgeometry#Read all g's from some ipe page(s). [ hgeometryConvenience function from reading all g's from an ipe file. If there is an error reading or parsing the file the error is "thrown away". P R Q S T U V W X Y Z [ S T U V W X Y P R Q Z [BNone%&'+,-0123456;<=>?FKNQSTV]eA ` hgeometryUClass that specifies a default conversion from a geometry type g into an ipe object. c hgeometryJAn IpeOut is essentially a funciton to convert a geometry object of type g into an ipe object of type i. f hgeometryGiven an geometry object, and a record with its attributes, construct an ipe Object representing it using the default conversion. g hgeometrykasIpeObject with its arguments flipped. Convenient if you don't want to map asIpeObject over a list or so. i hgeometry,Create an ipe group without group attributes j hgeometryCreates a group out of ipe k hgeometryeHelper to construct an IpeOut g IpeObject , if we already know how to construct a specific Ipe type. l hgeometry/Construct an ipe object from the core of an Ext q hgeometryDefault size of the cliping rectangle used to clip lines. This is Rectangle is large enough to cover the normal page size in ipe. r hgeometryVAn ipe out to draw a line, by clipping it to stay within a rectangle of default size. s hgeometryGAn ipe out to draw a line, by clipping it to stay within the rectangle.pre: intersection of the line and the rectangle is a line segment (otherwise it arbitrarily inserts the bottom of the rectangle as the path) { hgeometryUHelper to construct a IpeOut g Path, for when we already have an IpeOut g PathSegment ` b a c d e f g h i j k l m n o p q r s t u v w x y z { | c d e f g h i j k l ` b a m n o p q r s t u v w x y z { |\>Reexports the functionality for reading and writing Ipe files.(c) Frank StaalsSee LICENCE fileNone%&'+,-0123456;<=>?FKNQSTV]eM n o  ~ } | { z y x w v u t s r q pKXSMLNOPQRTUVWYZ[\]abcdefghijklmnopqrstuvwxyz{|}    ,-./0123456:;<=>?@ABCDHIJKLMNOPQRVWXYZ[\]^_`abcdefghijklmnopqrs{|}~ " # $ % & ' ( ) * + , - . / 0 1 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 { |CNone%&'+,-0123456;<=>?FKNQSTV]e!  DNone%&'+,-0123456;<=>?FKNQSTV]eG  Basic Geometry types(c) Frank StaalsSee LICENCE fileNone%&'+,-0123456;<=>?FKNQSTV]eA      pqrstuvwxyz{|}~     !1236789:;<=>?@AB !#$%&'()*+,-./01234a pqrstuvwxyz{|}~ !#$%&'()*+,-./01234ENone%&'+,-0123456;<=>?FKNQSTV]eK  hgeometryeThe result of a smallest enclosing disk computation: The smallest ball and the points defining it  hgeometryList of two or three elements FNone%&'+,-0123456;<=>?FKNQSTV]e  hgeometryHorrible O(n^4) implementation that simply tries all disks, checks if they enclose all points, and takes the largest one. Basically, this is only useful to check correctness of the other algorithm(s)  hgeometryBGiven a list of canidate enclosing disks, report the smallest one.  hgeometry#check if a disk encloses all points  GNone%&'+,-0123456;<=>?FKNQSTV]e  hgeometryBComputes the Euclidean diametral pair by naively trying all pairs.running time: O(n^2)  hgeometrymGiven a distance function and a list of points pts, computes the diametral pair by naively trying all pairs.running time: O(n^2)  HNone %&'+,-0123456;<=>?FKNQSTV]e  hgeometryeNeighbours are stored in clockwise order: i.e. rotating right moves to the next clockwise neighbour.  hgeometryRotating Right  - rotate clockwise  hgeometry*ST' is a strict triple (m,a,x) containing:fm: a Map, mapping edges, represented by a pair of vertexId's (u,v) with u < v, to arcId's."a: the next available unused arcID0x: the data value we are interested in computing  hgeometry2convert the triangulation into a planarsubdivisionrunning time: O(n).  hgeometry,convert the triangulation into a plane graphrunning time: O(n).  INone%&'+,-0123456;<=>?FKNQSTV]e  hgeometryNaive O(n^4) time implementation of the delaunay triangulation. Simply tries each triple (p,q,r) and tests if it is delaunay, i.e. if there are no other points in the circle defined by p, q, and r.pre: the input is a *SET*, i.e. contains no duplicate points. (If the input does contain duplicate points, the implementation throws them away)  hgeometrypGiven a list of edges, as vertexId pairs, construct a vector with the adjacency lists, each in CW sorted order.  hgeometryGiven a particular point u and a list of points vs, sort the points vs in CW order around u. running time: O(m log m), where m=|vs| is the number of vertices to sort.  hgeometry0Given a list of faces, construct a list of edges  hgeometryaTest if the given three points form a triangle in the delaunay triangulation. running time: O(n)  JNone%&'+,-0123456;<=>?FKNQSTV]e  hgeometry O(n \log n)  hgeometry O(n \log n)  KNone%&'+,-0123456;<=>?FKNQSTV]e  hgeometry O(n \log n)W time ConvexHull using Graham-Scan. The resulting polygon is given in clockwise order.  hgeometrygHelper function so that that can compute both the upper or the lower hull, depending on the function f  hgeometry0Precondition: The list of input points is sorted  LNone%&'+,-0123456;<=>?FKNQSTV]e  hgeometryOGiven a list of non-vertical lines, computes the lower envelope using duality. O(n\log n)  hgeometryGiven a list of non-vertical lines, computes the lower envelope by computing the upper convex hull. It uses the given algorithm to do so@running time: O(time required by the given upper hull algorithm)  hgeometry=Computes the vertices of the envelope, in left to right order  hgeometryrGiven two non-parallel lines, compute the intersection point and return the pair of a's associated with the lines  MNone%&'+,-0123456;<=>?FKNQSTV]e"  hgeometry7Computes the delaunay triangulation of a set of points.Running time:  O(n \log n)C (note: We use an IntMap in the implementation. So maybe actually  O(n \log^2 n))pre: the input is a *SET*, i.e. contains no duplicate points. (If the input does contain duplicate points, the implementation throws them away)  hgeometryMapping that says for each vtx in the convex hull what the first entry in the adj. list should be. The input polygon is given in Clockwise order  hgeometryXGiven a polygon; construct the adjacency list representation pre: at least two elements  hgeometry&Merge the two delaunay triangulations.running time: O(n), (although we cheat a bit by using a IntMap)  hgeometry'Merges the two delaunay traingulations.  hgeometry'rotates'= around r and removes all neighbours of r that violate the delaunay condition. Returns the first vertex (as a Neighbour of r) that should remain in the Delaunay Triangulation, as well as a boolean A that helps deciding if we merge up by rotating left or rotating right (See description in the paper for more info)  hgeometry&The code that does the actual rotating  hgeometrySymmetric to rotateR  hgeometry=The code that does the actual rotating. Symmetric to rotateR'  hgeometryereturns True if the forth point (vertex) does not lie in the disk defined by the first three points.  hgeometry(Inserts an edge into the right position.  hgeometryNmake sure that the first vtx in the adj list of v is its predecessor on the CH  hgeometryhInserts an edge (and makes sure that the vertex is inserted in the correct. pos in the adjacency lists)  hgeometryDeletes an edge  hgeometry!Lifted version of Convex.IsLeftOf  hgeometry"Lifted version of Convex.IsRightOf  hgeometryan unsafeO version of rotateTo that assumes the element to rotate to occurs in the list.  hgeometryIAdjacency lists are stored in clockwise order, so pred means rotate right  hgeometryKAdjacency lists are stored in clockwise order, so pred and succ rotate left  hgeometry%Removes duplicates from a sorted list  hgeometry lower tangent hgeometry upper tangent  NNone%&'+,-0123456;<=>?FKNQSTV]e*O  hgeometryComputes the Euclidean Minimum Spanning Tree. We compute the Delaunay Triangulation (DT), and then extract the EMST. Hence, the same restrictions apply as for the DT:pre: the input is a *SET*, i.e. contains no duplicate points. (If the input does contain duplicate points, the implementation throws them away)running time:  O(n \log n)  ONone%&'+,-0123456;<=>?FKNQSTV]e-j  hgeometry O(n \log n)` time ConvexHull using divide and conqueror. The resulting polygon is given in clockwise order.  PNone%&'+,-0123456;<=>?FKNQSTV]e1  hgeometry1Expects the input to be a set, i.e. no duplicatesrunning time:  O(n \log n)  hgeometryNub by sorting first  hgeometrySearches in a KDTreerunning time: O(n^{(d-1)/d} + k)  hgeometryrunning time: O(n)              QNone%&'+,-0123456;<=>?FKNQSTV]e@=  hgeometryTriangulates a polygon of n verticesrunning time:  O(n \log n)  hgeometryTriangulates a polygon of n verticesrunning time:  O(n \log n)  hgeometryoGiven a y-monotone polygon in counter clockwise order computes the diagonals to add to triangulate the polygon-pre: the input polygon is y-monotone and has n \geq 3 verticesrunning time: O(n)  hgeometry5test if m does not block the line segment from v to u  hgeometry8given a comparison function, merge the two ordered lists  hgeometrykWhen the polygon is in counter clockwise order we return (leftChain,rightChain) ordered from the top-down.if there are multiple points with the maximum yCoord we pick the rightmost one, if there are multiple point with the minimum yCoord we pick the leftmost one.running time: O(n)                !                !RNone %&'+,-0123456;<=>?FKNQSTV]eO ' hgeometry*for every e_i, the id of the helper vertex / hgeometry$assigns a vertex type to each vertex&pre: the polygon is given in CCW orderrunning time: O(n). 0 hgeometry$assigns a vertex type to each vertex&pre: the polygon is given in CCW orderrunning time: O(n). 1 hgeometryp  q = p.y < q.y || p.y == q.y && p.x q.y ; hgeometrymGiven a polygon, find a set of non-intersecting diagonals that partition the polygon into y-monotone pieces.running time:  O(n\log n) < hgeometryPComputes a set of diagionals that decompose the polygon into y-monotone pieces.running time:  O(n\log n) F hgeometry1Adds edge (i,j) if e_j's helper is a merge vertex G hgeometry-Get the helper of edge i, and its vertex type K hgeometry`finds the edge j to the left of v_i, and connect v_i to it if the helper of j is a merge vertex L hgeometryBreturns True if v the interior of the polygon is to the right of v' $ % ' & ( ) . + - , * / 0 1 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N' ) . + - , * / 0 1 ( $ % ' & 9 8 : ; < 7 6 = > ? @ A B C D E F G H I J K L M NSNone%&'+,-0123456;<=>?FKNQSTV]eZ/ O hgeometryTriangulates a polygon of n verticesrunning time:  O(n \log n) P hgeometryTriangulates a polygon of n verticesrunning time:  O(n \log n) Q hgeometryMComputes a set of diagaonals that together triangulate the input polygon of n vertices.running time:  O(n \log n) R hgeometryMComputes a set of diagaonals that together triangulate the input polygon of ns vertices. Returns a copy of the input polygon, whose boundaries are oriented in counter clockwise order, as well.running time:  O(n \log n) O P Q R O P Q RTNone%&'+,-0123456;<=>?FKNQSTV]e] S hgeometryWrite the output to yaml T hgeometryPrints the yaml U hgeometry-alias for decodeEither' from the Yaml Package V hgeometryalias for reading a yaml file S T U V S T U VUNone%&'+,-0123456;<=>?FKNQSTV]eb%  hgeometry Strict pair W hgeometry2Fisher Yates shuffle, which shuffles in O(n) time.  hgeometry`Generate a list of indices in decreasing order, coupled with a random value in the range [0,i]. W WVNone%&'+,-0123456;<=>?FKNQSTV]ei X hgeometryO(n) expected time algorithm to compute the smallest enclosing disk of a set of points. we need at least two points. implemented using randomized incremental construction Y hgeometrySmallest enclosing disk. Z hgeometry6Smallest enclosing disk, given that p should be on it. [ hgeometry;Smallest enclosing disk, given that p and q should be on it \ hgeometryConstructs the initial   from two points X Y Z [ \ X Y Z [ \WNone%&'+,-0123456;<=>?FKNQSTV]ek ]^_]^`abcabdabeabfabgabhabiajkajlajmanoanpanqanransantanuanvanwanxanyanzanzan{an|an}an~ananan      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^ _ ` 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 _ ` c { | } ~                                                                                                                                      i                                     ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H IJKLMNOPQRSTTUVWXYZ[\]]^__`abcdefghijklmnopqrstuvwxyz{|}~efghm]^`ab]cfghdemnopiu}wvyxz{|      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHHIJKLKMNOPQRSTUVWXYZ[\]^_)`abcde+,/.-fghhijklmnopqrstuvwxyz{|}~!*ZZ     FF !"#$GG%&'()*+,-./0123456789:.;<=>?@ABCDEFGHHIJKLMNOPQQRSTUVWXYZ[\]^_`abHHIcdLMeOffghijUPklmnopqrsttuvwxyz{|}}~]^_`~                                             q                 !!!!!!!!!!!!!!!!!q!g!h!!!!!!!!p![!\!!!!!!!!!!!!!!!!!!!!!!!!""""""" "" " " "g"h"""""""""" " "q"""["""\""""""""""""""" "!"""#"$"%"&"'"(")"*"+","-"."/"0"1"2"3"4#5#6##7$G$H$H$8$K$L$K$M$N$O$$P$Q$R$S$$T$U$V$W$X$Y$Z$[$\$$$$$]$^$`$a$b$c$d$e$f$g%9%:%%;%<%=%>%E%?%@%=%E%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'n'q'r's't'u'v'w'x'y'z'{'|'}'~''''''((((((())))))))))))))))))*H*H*******M*L***********e***********F*G***********+++++++++++++++++++++++++++ +{+,,,,-----------------------....../////////S//////////// / / / / ////////00011111111111 1!1"1#1$1%1&1'1(1)1*1+1,1-1.1/10111223242536363738393:3:3;3<3=3;3<3=3>3?3@3A3B3C3D3E3F3G3H3I3J3K3L3M33N3O3P3Q3R3S3T3U4V4V4W4X4Y4Z4[4\4]5^5^5_5`5a5b5c5d5e5f5g5h5i5j5k5l5m5n5o5p6666q6q666r6s6t6u6v6w6x6y6z6{6|6}6666~7777777777777777777777777W77777777777777777778888888888888888888888888888888888888888888888888888888888888888888888888999999999999999999999::::::::::::::::::::::::::::::::::::::::::::::: : : ::::::::::::::::::::::::: :: ::::::::::::::::::;;;;;;;;<<< <!="="=#=$=%=%=&='=(=)=*=+=,=-=.=/=0=1=2=3=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=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={=|=}=~=============================================================================================>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> > > > > >>>>>>>>>??????????? ?!?"?#?$?%?&?'?(?)?*?+?,?-?.?/?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`AaAbAcAdAeAfAgAhAiAjAkAlAmAnAoBpBqBrBsBsBtBuBvBwBxByBzB{B|B}B~BBB_BBBBBBBBBBBBBBBBBBCDEEEEEEEEEEEEEEEEFFFFFFGGGHHHHHHHHHHHHHHHHHrHHHHHHHHHHIIIIIJJKKKLLLLLLMMMMMMMMMkMMlMMMMMMMMMMMvMMMMMMNNN NOOPPPPPPPPPPPPPPPPPPPPPPPPPPRPPPPPPPPPPQQ Q QFQGQ Q Q Q Q Q Q Q Q Q Q Q Q Q R RR R RR RRRRR R R R R R R R R R R R R{R R R !R "R #R $R R %R &R 'R (R )R *RR +R ,R -R .R /R 0S S S S 1T 2T 3T 4T 5U 6VVV 7V 8V 9W :W ;W <W =W >W ?W @W AW BW CW DW EW FW GW H I a J K L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  [  \  ]  ^X _X `X aX bX cX d e f g e h iX jX kX lX mX nX oX pX qX rX sX tX uX vX w x y z { | } ~K       8 9 9 9 :< @ @ @jK K UU (hgeometry-0.7.0.0-3y7zA7ljCTE9s6EHvXHItMData.Geometry.Vector Data.GeometryAlgorithms.Geometry.SweepAlgorithms.UtilControl.Monad.State.Persistent Data.BalBSTData.BinaryTreeData.BinaryTree.ZipperData.CircularList.UtilData.CircularSeqData.ExtData.Geometry.Ipe.AttributesData.Geometry.Ipe.LiteralData.Geometry.Properties Data.Geometry.Vector.VectorFixed&Data.Geometry.Vector.VectorFamilyPeano!Data.Geometry.Vector.VectorFamilyData.Geometry.PointData.Geometry.TransformationData.Geometry.BoundaryData.Geometry.Line.Internal Data.OrdSeqData.PermutationData.PlanarGraphAlgorithms.Graph.DFSAlgorithms.Graph.MST Data.RangeData.Geometry.Interval.UtilData.Geometry.IntervalData.Geometry.IntervalTree!Data.Geometry.SegmentTree.GenericData.Geometry.Box.InternalData.Seq Data.Seq2Data.Sequence.Util Data.SlowSeqData.UnBoundedData.Geometry.SubLineData.Geometry.LineSegmentData.Geometry.BoxData.Geometry.PolyLine8Algorithms.Geometry.WellSeparatedPairDecomposition.Types7Algorithms.Geometry.WellSeparatedPairDecomposition.WSPD9Algorithms.Geometry.PolyLineSimplification.DouglasPeucker1Algorithms.Geometry.LineSegmentIntersection.Types1Algorithms.Geometry.LineSegmentIntersection.Naive:Algorithms.Geometry.LineSegmentIntersection.BentleyOttmannData.Geometry.LineData.Geometry.SlabData.Geometry.DualityData.Geometry.BallData.Geometry.TriangleData.Geometry.HalfLine Data.UtilData.Geometry.PolygonData.PlaneGraphData.Geometry.Polygon.Convex%Data.Geometry.PlanarSubdivision.Basic.Algorithms.Geometry.PolygonTriangulation.TypesData.Geometry.PlanarSubdivisionData.Geometry.Ipe.TypesData.Geometry.Ipe.WriterData.Geometry.Ipe.PathParserData.Geometry.Ipe.ReaderData.Geometry.Ipe.FromIpeData.Geometry.Ipe.IpeOutData.PlaneGraph.Draw$Data.Geometry.PlanarSubdivision.Draw/Algorithms.Geometry.SmallestEnclosingBall.Types/Algorithms.Geometry.SmallestEnclosingBall.NaiveAlgorithms.Geometry.Diameter/Algorithms.Geometry.DelaunayTriangulation.Types/Algorithms.Geometry.DelaunayTriangulation.Naive+Algorithms.Geometry.LineSegmentIntersection)Algorithms.Geometry.ConvexHull.GrahamScan(Algorithms.Geometry.LowerEnvelope.DualCHViewL:<LSeqtoSeq:|>EmptyL:<<:<|<||>><evalpromise partition mapWithIndextakedropunstableSortByfromSeq $fIxedLSeq $fMonoidLSeq$fSemigroupLSeq $fOrdViewL $fEqViewL$fTraversableViewL$fFoldableViewL$fFunctorViewL$fSemigroupViewL $fOrdViewR $fEqViewR$fTraversableViewR$fFoldableViewR$fFunctorViewR$fSemigroupViewR $fShowLSeq $fReadLSeq$fEqLSeq $fOrdLSeq$fFoldableLSeq $fFunctorLSeq$fTraversableLSeq $fShowViewR $fShowViewLViewR1ViewR2:>>ViewL1ViewL2Seq2duo fromSeqUnsafeheadL1viewL1FromNonEmpty viewL1FromSeq l1Singleton viewL1toR1 r1Singleton $fIxedSeq2$fSemigroupSeq2$fFoldableSeq2 $fFunctorSeq2$fTraversableSeq2$fSemigroupViewL1$fFoldableViewL1$fFunctorViewL1$fTraversableViewL1 $fShowViewL1$fFoldableViewR2$fFunctorViewR2$fTraversableViewR2$fFoldableViewR1$fFunctorViewR1$fTraversableViewR1$fFoldableViewL2$fFunctorViewL2$fTraversableViewL2$fEqSeq2 $fOrdSeq2 $fShowSeq2 $fEqViewL1 $fOrdViewL1 $fShowViewR2 $fEqViewR2 $fOrdViewR2 $fShowViewR1 $fReadViewR1 $fEqViewR1 $fOrdViewR1 $fShowViewL2 $fEqViewL2 $fOrdViewL2binarySearchSeqbinarySearchVec binarySearch_asSeq UnBounded MinInfinity MaxInfinity _unUnBoundedBottom bottomToMaybe topToMaybeValBValT $fShowTop$fOrdTop $fShowBottom$fEqTop $fFunctorTop $fFoldableTop$fTraversableTop$fApplicativeTop $fMonadTop $fEqBottom $fOrdBottom$fFunctorBottom$fFoldableBottom$fTraversableBottom$fApplicativeBottom $fMonadBottom $fEqUnBounded$fOrdUnBounded$fFunctorUnBounded$fFoldableUnBounded$fTraversableUnBounded unUnBoundedunBoundedToMaybe$fFractionalUnBounded$fNumUnBounded$fShowUnBoundedSubLine_line _subRangelinesubRangepointAt fixEndPointstoOffset onSubLine onSubLine2fromLine#$fIsIntersectableWithSubLineSubLine$fBifunctorSubLine$fTraversableSubLine$fFoldableSubLine$fFunctorSubLine $fEqSubLine $fShowSubLine LineSegmentClosedLineSegment LineSegment'_SubLine toLineSegment onSegmentorderedEndPoints segmentLengthsqDistanceToSegsqDistanceToSegArg flipSegment$$fIsIntersectableWithLineSegmentLine+$fIsIntersectableWithLineSegmentLineSegment$fBifunctorLineSegment$fIsTransformableLineSegment$fIsBoxableLineSegment$fPointFunctorLineSegment$fShowLineSegment$fHasSupportingLineLineSegment$fHasEndLineSegment$fHasStartLineSegment$fFunctorLineSegment$fEqLineSegmenttopSide bottomSideleftSide rightSidesidessides' $fNFDataBoxPolyLine_pointspoints fromPoints fromPoints'fromLineSegment asLineSegmentasLineSegment'$fBifunctorPolyLine$fPointFunctorPolyLine$fIsTransformablePolyLine$fIsBoxablePolyLine$fSemigroupPolyLine$fFunctorPolyLine $fOrdPolyLine $fEqPolyLine$fShowPolyLine _splitDim_bBox _nodeDataWSPPointSet SplitTreeLevel_unLevel _widestDimPointSeqbBoxnodeDatasplitDim$fTraversableNodeData$fFoldableNodeData$fMeasuredvNodeData $fShowLevel $fEqLevel $fOrdLevelFindAndCompactFAC _leftPart _rightPart _shortSide ShortSideIdxunLevel widestDim nextLevel$fShowShortSide $fEqShortSide$fEqFindAndCompact$fShowFindAndCompactleftPart rightPart shortSideRST fairSplitTreewellSeparatedPairsfairSplitTree'distributePoints transposedistributePoints' reIndexPoints assignLevels compactEnds assignLevellevelOfhasLevel compactEnds'findAndCompactwidestDimensionwidthsextends findPairsareWellSeparatedboxBoxareWellSeparated'boxBox1maxWidthbbOf children'dropIdxdouglasPeuckermergemaxDistIntersectionPoint_intersectionPoint_associatedSegs Intersections Associated _endPointOf _interiorToSet' endPoints' associated endPointOf interiorTo$fMonoidAssociated$fSemigroupAssociated$fEqAssociated$fShowAssociated$fShowIntersectionPoint$fEqIntersectionPointassociatedSegsintersectionPointisEndPointIntersection intersections handlePointaddTo isEndPointOfpairsStatusStructure EventQueueEvent eventPoint eventType EventTypeStartEndinteriorIntersections asEventPts groupStarts ordPoints startSegsordAtxCoordAtsweep isClosedStarthandleextractContainstoStatusStruct rightEndpointendsAt findNewEvent$fOrdEventType $fEqEventType $fOrdEvent$fShowEventType $fShowEvent $fEqEvent$fIsIntersectableWithLineBox!$fIsIntersectableWithLineBoundary$fIsTransformableLineSlab_unSlab Orthogonal$fShowOrthogonal$fEqOrthogonal$fReadOrthogonal $fShowSlab$fEqSlabHasBoundingLines boundingLinesinSlabunSlabhorizontalSlab verticalSlabtest$fIsIntersectableWithSlabSlab$fIsIntersectableWithSlabSlab0$fBifunctorSlab$fTraversableSlab$fFoldableSlab $fFunctorSlab$$fIsIntersectableWithLineSegmentSlab $fIsIntersectableWithSubLineSlab$fIsIntersectableWithLineSlab$fHasBoundingLinesVertical$fHasBoundingLinesHorizontaldualLine dualPoint dualPoint'Ball_center_squaredRadius $fGenericBallTouchingCircleDiskSpherecenter squaredRadiusradius fromDiameterfromCenterAndPointunitBallinBall insideBall inClosedBallonBalldisk from3Points$fBifunctorBall $fFunctorBall $fNFDataBall($fIsIntersectableWithLineSegmentBoundary$fShowTouching $fEqTouching $fOrdTouching$fFunctorTouching$fFoldableTouching$fTraversableTouching$fEqBall $fShowBallTrianglearea doubleArea inscribedDisk$fIsTransformableTriangle$fPointFunctorTriangle$fFunctorTriangle$fShowTriangleHalfLine _startPoint_halfLineDirection$fGenericHalfLinehalfLineDirection startPointhalfLineToSubLine fromSubLine onHalfLine toHalfLine$fIsTransformableHalfLine$fHasSupportingLineHalfLine$fHasStartHalfLine$fTraversableHalfLine$fFoldableHalfLine$fFunctorHalfLine$fNFDataHalfLine $fEqHalfLine$fShowHalfLineSTRtrd'$fField3STRSTRcd$fField2STRSTRbd$fField1STRSTRad $fBifunctorSP$fField2SPSPbc$fField1SPSPac $fSemigroupSP $fShowSTR$fEqSTR$fOrdSTR $fFunctorSTR $fFunctorSP SomePolygon MultiPolygon SimplePolygonPolygon PolygonTypeSimpleMultibitraverseVertices outerBoundary polygonHoles outerVertexouterBoundaryEdgeholeListpolygonVerticesouterBoundaryEdges listEdgeswithIncidentEdgestoEdges onBoundary inPolygon insidePolygon signedAreacentroidisCounterClockwisetoClockwiseOrdertoCounterClockWiseOrderreverseOuterBoundaryasSimplePolygon cmpExtremeextremesLinearnumberVertices$fIsBoxablePolygon$fIsTransformablePolygon$fPointFunctorPolygon $fEqPolygon $fShowPolygon$fNFDataPolygon$fBitraversablePolygon$fBifoldablePolygon$fBifunctorPolygon VertexData$fShowVertexData$fEqVertexData$fOrdVertexData$fFunctorVertexData$fFoldableVertexData$fTraversableVertexData PlaneGraphlocationvData vtxDataToExt$fToJSONVertexData$fFromJSONVertexData$fBifunctorVertexData$fShowPlaneGraph$fEqPlaneGraph$fToJSONPlaneGraph$fFromJSONPlaneGraphgraphfromSimplePolygonfromConnectedSegmentsfaces'' internalFaces vertexDataOf locationOf endPointsOf outerFaceId outerFaceDart edgeSegments edgeSegmentrawFaceBoundaryrawFacePolygonrawFacePolygonswithEdgeDistances$fHasDataOfPlaneGraphFaceId$fHasDataOfPlaneGraphDart$fHasDataOfPlaneGraphVertexId$fIsBoxablePlaneGraph$fFunctorPlaneGraph ConvexPolygon_simplePolygon$fShowConvexPolygon$fEqConvexPolygon$fNFDataConvexPolygon simplePolygonextremesmaxInDirection leftTangent rightTangent lowerTangent upperTangent isRightOfisLeftOf minkowskiSum bottomMost$fIsBoxableConvexPolygon$fIsTransformableConvexPolygon$fPointFunctorConvexPolygonFaceData$fShowFaceData $fEqFaceData $fOrdFaceData$fFunctorFaceData$fFoldableFaceData$fTraversableFaceData$fGenericFaceDataRaw_compId_idxVal_dataVal ComponentIdWrapfDataholes$fToJSONFaceData$fFromJSONFaceData$fBifunctorFaceData$fShowComponentId$fEqComponentId$fOrdComponentId$fGenericComponentId$fBoundedComponentId$fEnumComponentId$fEqRaw $fShowRaw $fFunctorRaw $fFoldableRaw$fTraversableRawPlanarSubdivision ComponentdataVal$fShowPlanarSubdivision$fEqPlanarSubdivision$fFunctorPlanarSubdivisionPolygonFaceData components rawFaceData rawVertexData componentfromPlaneGraphfromPlaneGraph'outerBoundaryDartsholesOf dartMapping"$fHasDataOfPlanarSubdivisionFaceId $fHasDataOfPlanarSubdivisionDart$$fHasDataOfPlanarSubdivisionVertexId$fIsBoxablePlanarSubdivision$fShowPolygonFaceData$fReadPolygonFaceData$fEqPolygonFaceDataPolygonEdgeTypeOriginalDiagonalconstructSubdivisionconstructGraph$fShowPolygonEdgeType$fReadPolygonEdgeType$fEqPolygonEdgeType fromPolygon fromPolygons$fShowHoleData $fEqHoleDataImage _imageData_rect LayerName _layerName$fShowLayerName$fReadLayerName $fEqLayerName$fOrdLayerName$fIsStringLayerName $fShowImage $fEqImage $fOrdImage IpeSymbolSymbol _symbolPoint _symbolNameMiniPage TextLabelLabel imageDatarect$fIsTransformableImage$fIsTransformableTextLabel$fIsTransformableMiniPage$fShowTextLabel $fEqTextLabel$fOrdTextLabel$fShowMiniPage $fEqMiniPage $fOrdMiniPage$fShowIpeSymbol $fEqIpeSymbol$fOrdIpeSymbol PathSegmentPolyLineSegment PolygonPathCubicBezierSegmentQuadraticBezierSegmentEllipseSegment ArcSegment SplineSegmentClosedSplineSegment symbolName symbolPoint$fIsTransformableIpeSymbol$fShowPathSegment$fEqPathSegmentPath _pathSegments_PolyLineSegment _PolygonPath_CubicBezierSegment_QuadraticBezierSegment_EllipseSegment _ArcSegment_SplineSegment_ClosedSplineSegment$fIsTransformablePathSegment $fShowPath$fEqPath OperationMoveToLineToCurveToQCurveToEllipseArcToSpline ClosedSpline ClosePath pathSegments$fIsTransformablePath $fEqOperation$fShowOperationAttrMap_MoveTo_LineTo_CurveTo _QCurveTo_Ellipse_ArcTo_Spline _ClosedSpline _ClosePath IpeObjectIpeGroupIpeImage IpeTextLabel IpeMiniPageIpeUseIpePath IpeObject' IpeAttributes Attributes' AttributesOfGroup _groupItems AttrMapSym0AttrMapSym0KindInference AttrMapSym1AttrMapSym1KindInference AttrMapSym2 attributes'$fSuppressUnusedWarnings(->)AttrMapSym1'$fSuppressUnusedWarnings(->)AttrMapSym0$fIsTransformableGroup $fShowGroup $fEqGroup $fEqIpeObject$fShowIpeObject _IpeGroup _IpeImage _IpeTextLabel _IpeMiniPage_IpeUse_IpePathView _layerNames _activeLayerToObject ipeObject' groupItemscommonAttributes flattenGroups$fIsTransformableIpeObject$fToObjectPath$fToObjectIpeSymbol$fToObjectMiniPage$fToObjectTextLabel$fToObjectImage$fToObjectGroup$fEqView $fOrdView $fShowViewIpeStyle _styleName _styleData activeLayer layerNames $fEqIpeStyle$fShowIpeStyle IpePreamble _encoding _preambleData styleData styleName basicIpeStyle$fEqIpePreamble$fReadIpePreamble$fShowIpePreamble$fOrdIpePreambleIpePage_layers_views_content IpeBitmapencoding preambleData $fEqIpePage $fShowIpePageIpeFile _preamble_styles_pagescontentlayersviews fromContent $fEqIpeFile $fShowIpeFilepagespreamblestylessinglePageFilesinglePageFromContent applyMatrix' applyMatrix applyMatricesapplyMatricesPageIpeWriteipeWrite IpeWriteText ipeWriteText writeIpeFile writeIpePageprintAsIpeSelectiontoIpeSelectionXMLtoIpeXML writeIpeFile' ipeWriteAttrswriteAttrValuesaddAttsmAddAtts writeByShowunwords'unlines' ipeWriteRec fromPolyLinecombine$fIpeWriteText()$fIpeWriteTextPathSegment$fIpeWriteTextPolygon$fIpeWriteTextPolyLine$fIpeWriteTextOperation$fIpeWriteTextMatrix$fIpeWriteTextPath$fIpeWriteTextIpeArrow$fIpeWriteTextFillType$fIpeWriteTextIpeDash$fIpeWriteTextRGB$fIpeWriteTextPinType!$fIpeWriteTextTransformationTypes$fIpeWriteTextIpeValue$fIpeWriteTextPoint$fIpeWriteTextRatio$fIpeWriteTextFixed$fIpeWriteTextInteger$fIpeWriteTextInt$fIpeWriteTextDouble$fIpeWriteTextText$fIpeWriteTextEither$fIpeWriteTextAttr $fIpeWrite()$fIpeWriteLineSegment$fIpeWritePolyLine$fIpeWriteIpeFile$fIpeWriteIpePreamble$fIpeWriteIpeStyle$fIpeWriteIpePage$fIpeWriteView$fIpeWriteLayerName$fIpeWriteIpeObject$fIpeWriteTextLabel$fIpeWriteImage$fIpeWriteMiniPage $fIpeWrite:+$fIpeWriteGroup$fIpeWritePath$fIpeWriteIpeSymbol$fIpeWriteEither$fIpeWriteTextLayerName$fIpeWriteTextIpeColor$fIpeWriteTextIpePen$fIpeWriteTextIpeSizeEither'Left'Right' CoordinatedefaultFromSeqreadCoordinate readPoint runParsereither'readPathOperations errorText combineErrorssplitKeepDelims readMatrix readRectangle pOperationpPoint pCoordinate pRectanglepMatrixmkMatrix$fCoordinateRatio$fCoordinateDouble$fMonoidEither'$fSemigroupEither' $fShowEither' $fEqEither' IpeReadAttr ipeReadAttrIpeReadipeRead IpeReadText ipeReadTextConversionErrorreadRawIpeFile readIpeFilereadSinglePageFile fromIpeXMLreadXMLipeReadTextWith ipeReadRec ipeReadAttrs ipeReadObject$fIpeReadTextPath$fIpeReadTextNonEmpty$fIpeReadText[]$fIpeReadTextIpeSize$fIpeReadTextIpePen$fIpeReadTextIpeColor$fIpeReadTextRGB$fIpeReadTextBox$fIpeReadTextIpeDash$fIpeReadTextIpeArrow$fIpeReadTextFillType $fIpeReadTextTransformationTypes$fIpeReadTextPinType$fIpeReadTextLayerName$fIpeReadTextMatrix$fIpeReadTextPoint$fIpeReadTextInt$fIpeReadTextText$fIpeReadIpeFile$fIpeReadIpePage $fIpeReadView$fIpeReadLayerName$fIpeReadGroup$fIpeReadIpeObject$fIpeReadImage$fIpeReadMiniPage$fIpeReadTextLabel $fIpeReadPath$fIpeReadIpeSymbol$fIpeReadAttrAttrHasDefaultFromIpeDefaultFromIpedefaultFromIpe_asLineSegment _asPolyLine_asSimplePolygon_asMultiPolygon polygonToPath pathToPolygon _withAttrsreadAll readAllFrom$fHasDefaultFromIpePolygon$fHasDefaultFromIpePolygon0$fHasDefaultFromIpePolyLine$fHasDefaultFromIpeLineSegmentHasDefaultIpeOut DefaultIpeOut defaultIpeOutIpeOutasIpe asIpeObject asIpeObject'asIpeObjectWith asIpeGroup asIpeGroup' ipeObjectcoreOutipeMark ipeDiskMarknoAttrs addAttributesdefaultClipRectanglelineWithipeLineSegmentipeLineSegment' ipePolyLine ipePolyLine'ipeDisk ipeCircle ipeCircle'fromPathSegment ipePolygon$fHasDefaultIpeOutConvexPolygon$fHasDefaultIpeOutEither$fHasDefaultIpeOutPolygon$fHasDefaultIpeOutPolyLine$fHasDefaultIpeOutBall$fHasDefaultIpeOutLineSegment$fHasDefaultIpeOutPoint$fFunctorIpeOutdrawPlaneGraphdrawPlanarSubdivision DiskResult_enclosingDisk_definingPoints TwoOrThree$fFoldableTwoOrThree$fShowTwoOrThree$fReadTwoOrThree$fEqTwoOrThree$fOrdTwoOrThree$fFunctorTwoOrThreedefiningPoints enclosingDisksmallestEnclosingDisktripletsdisk'smallestEnclosingDisk' enclosesAll diameterNaivediametralPairNaivediametralPairWithNaive Triangulation _vertexIds _positions _neighboursAdjVertexVertexID$fShowTriangulation$fEqTriangulationST'ArcIDMapping neighbours positions vertexIdsshowDTtriangulationEdgestEdgesdrawTriangulationtoPlanarSubdivision toPlaneGraphdelaunayTriangulation toAdjLists sortAround' extractEdges isDelaunayhasInteriorIntersectionshasSelfIntersections convexHull upperHull lowerHullUpperHullAlgorithmEnvelope lowerEnvelopelowerEnvelopeWith intersect'FirstsMergedelaunayTriangulation'firstsfromHullmoveUprotateR'rotateL'qTest rotateToFirstinsert'lookup'size'pred'succ'focus'nub'withIDlookup''MSTW euclideanMST treeEdges$fSemigroupMergeKDTreeKDTree'KDTunKDTSplit'CoordunCoordtoMaybe buildKDTree buildKDTree'ordNub toPointSet compareOnbuild reportSubTree searchKDTree searchKDTree'boxOf containedIn asSingleton $fEnumCoord $fShowCoord $fEqCoord $fEqKDTree $fShowKDTree $fEqKDTree' $fShowKDTree'StackPLRMonotonePolygon triangulate triangulate'computeDiagonalschainOftoVtxsegprocessisInsidemergeBy splitPolygon testPoly5$fShowLR$fEqLR StatusStruct _statusStruct_helper VertexTypeRegularclassifyVerticesclassifyVertices'cmpSweep$fShowVertexType$fReadVertexType$fEqVertexType$fShowStatusStruct VertexInfoSweephelper statusStruct makeMonotonetell'getIdx getVertexType getEventTypeinsertAtdeleteAt handleStart handleEnd tellIfMerge getHelper handleSplit handleMerge connectToLeft isLeftVertexhandleRegularLhandleRegularRcomputeDiagonals' encodeYaml printYaml decodeYamldecodeYamlFileshufflesmallestEnclosingDiskWithPointsmallestEnclosingDiskWithPointsinitial$fArbitraryLineSegment$fArbitrarySubLine$fArbitraryInterval $fArbitrary:+$fArbitraryRange$fArbitraryEndPoint$fArbitraryBox$fArbitraryLine$fArbitraryPoint$fArbitraryVector$fArbitraryLSeq$fArbitraryBinLeafTree$fArbitraryBinaryTree$fArbitrarySeq2$fArbitraryOrdSeq withFocus'singletons-2.4.1-If1LsNMQ5ia49oz6JFd4AGData.Singletons.InternalSingSLayerSClip SGradientSTilingSOpacitySRArrowSArrow SFillRule SLineJoinSLineCapSDashSSizeSPenSFillSStrokeSTransformationsSPinSMatrixpManypPaddedNaturalpNotFollowedBy<*><><***>***>parsec-3.1.13.0Text.Parsec.TextParserText.Parsec.Error ParseErrorrunP'runPpMany1pChoicepNaturalpIntegerpCharpSpace pWhiteSpacepMaybepCountpSepBy<*><<***scalarMultiple' updateData updateData'reorderEdgeData computeDual computeDual'UFfind'cmpLowercmpUpper AtomicRange interleavegetRangebaseGHC.BaseNothing fromVertices rightMostleftMost getVerticesgrowzipTraverseWithallTexthullhull'rands