ghc-vis 0.6.1.1 → 0.7
raw patch · 15 files changed
+2429/−2026 lines, 15 filesdep −SDLdep ~ghc-heap-viewdep ~svgcairoPVP ok
version bump matches the API change (PVP)
Dependencies removed: SDL
Dependency ranges changed: ghc-heap-view, svgcairo
API changes (from Hackage documentation)
+ GHC.Vis: history :: (Int -> Int) -> IO ()
+ GHC.Vis: restore :: IO ()
+ GHC.Vis.Internal: instance Eq Box
+ GHC.Vis.Internal: parseClosure :: HeapGraphIndex -> PrintState [VisObject]
+ GHC.Vis.Internal: showClosureFields :: GenClosure t -> [String]
Files
- data/hover_collapse.svg +117/−0
- data/hover_evaluate.svg +118/−0
- data/icon_collapse.svg +117/−0
- data/icon_evaluate.svg +104/−0
- data/main.ui +56/−13
- data/welcome.svg +1308/−1474
- ghc-vis.cabal +15/−15
- ghci +3/−0
- src/GHC/Vis.hs +73/−33
- src/GHC/Vis/Internal.hs +148/−318
- src/GHC/Vis/Types.hs +18/−19
- src/GHC/Vis/View/Common.hs +78/−19
- src/GHC/Vis/View/Graph.hs +145/−49
- src/GHC/Vis/View/Graph/Parser.hs +108/−70
- src/GHC/Vis/View/List.hs +21/−16
+ data/hover_collapse.svg view
@@ -0,0 +1,117 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+ xmlns:dc="http://purl.org/dc/elements/1.1/"+ xmlns:cc="http://creativecommons.org/ns#"+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+ xmlns:svg="http://www.w3.org/2000/svg"+ xmlns="http://www.w3.org/2000/svg"+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+ version="1.1"+ width="35"+ height="17.5"+ id="svg3346"+ inkscape:version="0.48.4 r9939"+ sodipodi:docname="hover_collapse.svg">+ <sodipodi:namedview+ pagecolor="#ffffff"+ bordercolor="#666666"+ borderopacity="1"+ objecttolerance="10"+ gridtolerance="10"+ guidetolerance="10"+ inkscape:pageopacity="0"+ inkscape:pageshadow="2"+ inkscape:window-width="911"+ inkscape:window-height="817"+ id="namedview15"+ showgrid="false"+ inkscape:zoom="3.56"+ inkscape:cx="2.9494382"+ inkscape:cy="25"+ inkscape:window-x="737"+ inkscape:window-y="160"+ inkscape:window-maximized="0"+ inkscape:current-layer="layer1" />+ <defs+ id="defs3348">+ <marker+ refX="0"+ refY="0"+ orient="auto"+ id="Arrow2Send"+ style="overflow:visible">+ <path+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"+ transform="matrix(-0.3,0,0,-0.3,0.69,0)"+ id="path4223"+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"+ inkscape:connector-curvature="0" />+ </marker>+ <marker+ refX="0"+ refY="0"+ orient="auto"+ id="Arrow2Mend"+ style="overflow:visible">+ <path+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"+ transform="scale(-0.6,-0.6)"+ id="path4217"+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"+ inkscape:connector-curvature="0" />+ </marker>+ <marker+ refX="0"+ refY="0"+ orient="auto"+ id="Arrow1Lend"+ style="overflow:visible">+ <path+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"+ transform="matrix(-0.8,0,0,-0.8,-10,0)"+ id="path4193"+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"+ inkscape:connector-curvature="0" />+ </marker>+ <marker+ refX="0"+ refY="0"+ orient="auto"+ id="Arrow2Send-0"+ style="overflow:visible">+ <path+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"+ transform="matrix(-0.3,0,0,-0.3,0.69,0)"+ id="path4223-2"+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"+ inkscape:connector-curvature="0" />+ </marker>+ </defs>+ <metadata+ id="metadata3351">+ <rdf:RDF>+ <cc:Work+ rdf:about="">+ <dc:format>image/svg+xml</dc:format>+ <dc:type+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+ <dc:title />+ </cc:Work>+ </rdf:RDF>+ </metadata>+ <g+ transform="matrix(0.35,0,0,0.35,-9.8,-350.82674)"+ id="layer1">+ <rect+ width="93"+ height="43"+ ry="0"+ x="31.5"+ y="1005.8621"+ id="rect4164"+ style="color:#000000;fill:none;stroke:#ff0000;stroke-width:7.00000047999999975;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:7.00000047999999975, 14.00000095000000044;stroke-dashoffset:9.80000066999999930;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />+ </g>+</svg>
+ data/hover_evaluate.svg view
@@ -0,0 +1,118 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+ xmlns:dc="http://purl.org/dc/elements/1.1/"+ xmlns:cc="http://creativecommons.org/ns#"+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+ xmlns:svg="http://www.w3.org/2000/svg"+ xmlns="http://www.w3.org/2000/svg"+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+ version="1.1"+ width="35"+ height="17.5"+ id="svg5999"+ inkscape:version="0.48.4 r9939"+ sodipodi:docname="icon_evaluate.svg">+ <sodipodi:namedview+ pagecolor="#ffffff"+ bordercolor="#666666"+ borderopacity="1"+ objecttolerance="10"+ gridtolerance="10"+ guidetolerance="10"+ inkscape:pageopacity="0"+ inkscape:pageshadow="2"+ inkscape:window-width="1441"+ inkscape:window-height="1051"+ id="namedview2999"+ showgrid="false"+ inkscape:zoom="3.56"+ inkscape:cx="-80.842697"+ inkscape:cy="25"+ inkscape:window-x="0"+ inkscape:window-y="14"+ inkscape:window-maximized="0"+ inkscape:current-layer="layer1" />+ <defs+ id="defs6001">+ <marker+ style="overflow:visible"+ id="Arrow2Mend"+ orient="auto"+ refY="0"+ refX="0">+ <path+ inkscape:connector-curvature="0"+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"+ id="path4217"+ transform="scale(-0.6,-0.6)"+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" />+ </marker>+ <marker+ style="overflow:visible"+ id="Arrow2MendB"+ orient="auto"+ refY="0"+ refX="0"+ inkscape:stockid="Arrow2MendB">+ <path+ inkscape:connector-curvature="0"+ style="stroke-linejoin:round;stroke:#ff0000;stroke-width:0.625;fill:#ff0000;fill-rule:evenodd"+ id="path3019"+ transform="scale(-0.6,-0.6)"+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" />+ </marker>+ <marker+ style="overflow:visible"+ id="Arrow2MendBQ"+ orient="auto"+ refY="0"+ refX="0"+ inkscape:stockid="Arrow2MendBQ">+ <path+ inkscape:connector-curvature="0"+ style="stroke-linejoin:round;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;fill:#000000"+ id="path3820"+ transform="scale(-0.6,-0.6)"+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" />+ </marker>+ <marker+ style="overflow:visible"+ id="Arrow2MendBQO"+ orient="auto"+ refY="0"+ refX="0"+ inkscape:stockid="Arrow2MendBQO">+ <path+ inkscape:connector-curvature="0"+ style="stroke-linejoin:round;stroke:#ff0000;stroke-width:0.625;fill:#ff0000;fill-rule:evenodd"+ id="path3894"+ transform="scale(-0.6,-0.6)"+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" />+ </marker>+ </defs>+ <metadata+ id="metadata6004">+ <rdf:RDF>+ <cc:Work+ rdf:about="">+ <dc:format>image/svg+xml</dc:format>+ <dc:type+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+ <dc:title></dc:title>+ </cc:Work>+ </rdf:RDF>+ </metadata>+ <g+ style="stroke:#ff0000;stroke-opacity:1"+ id="layer1"+ transform="matrix(0.35,0,0,0.35,-84.109376,-19.205165)">+ <path+ inkscape:connector-curvature="0"+ style="stroke-linejoin:miter;marker-end:url(#Arrow2MendBQO);stroke-opacity:1;stroke:#ff0000;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-width:7.00000047999999975;fill:none"+ id="path4184-6"+ d="m 244.89904,79.939158 85.05631,0" />+ </g>+</svg>
+ data/icon_collapse.svg view
@@ -0,0 +1,117 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+ xmlns:dc="http://purl.org/dc/elements/1.1/"+ xmlns:cc="http://creativecommons.org/ns#"+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+ xmlns:svg="http://www.w3.org/2000/svg"+ xmlns="http://www.w3.org/2000/svg"+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+ version="1.1"+ width="35"+ height="17.5"+ id="svg3346"+ inkscape:version="0.48.4 r9939"+ sodipodi:docname="icon_collapse.svg">+ <sodipodi:namedview+ pagecolor="#ffffff"+ bordercolor="#666666"+ borderopacity="1"+ objecttolerance="10"+ gridtolerance="10"+ guidetolerance="10"+ inkscape:pageopacity="0"+ inkscape:pageshadow="2"+ inkscape:window-width="958"+ inkscape:window-height="1064"+ id="namedview15"+ showgrid="false"+ inkscape:zoom="3.56"+ inkscape:cx="2.9494382"+ inkscape:cy="25"+ inkscape:window-x="960"+ inkscape:window-y="14"+ inkscape:window-maximized="0"+ inkscape:current-layer="svg3346" />+ <defs+ id="defs3348">+ <marker+ refX="0"+ refY="0"+ orient="auto"+ id="Arrow2Send"+ style="overflow:visible">+ <path+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"+ transform="matrix(-0.3,0,0,-0.3,0.69,0)"+ id="path4223"+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"+ inkscape:connector-curvature="0" />+ </marker>+ <marker+ refX="0"+ refY="0"+ orient="auto"+ id="Arrow2Mend"+ style="overflow:visible">+ <path+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"+ transform="scale(-0.6,-0.6)"+ id="path4217"+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"+ inkscape:connector-curvature="0" />+ </marker>+ <marker+ refX="0"+ refY="0"+ orient="auto"+ id="Arrow1Lend"+ style="overflow:visible">+ <path+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"+ transform="matrix(-0.8,0,0,-0.8,-10,0)"+ id="path4193"+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"+ inkscape:connector-curvature="0" />+ </marker>+ <marker+ refX="0"+ refY="0"+ orient="auto"+ id="Arrow2Send-0"+ style="overflow:visible">+ <path+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"+ transform="matrix(-0.3,0,0,-0.3,0.69,0)"+ id="path4223-2"+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"+ inkscape:connector-curvature="0" />+ </marker>+ </defs>+ <metadata+ id="metadata3351">+ <rdf:RDF>+ <cc:Work+ rdf:about="">+ <dc:format>image/svg+xml</dc:format>+ <dc:type+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+ <dc:title />+ </cc:Work>+ </rdf:RDF>+ </metadata>+ <g+ transform="matrix(0.35,0,0,0.35,-9.8,-350.82674)"+ id="layer1">+ <rect+ width="93"+ height="43"+ ry="0"+ x="31.5"+ y="1005.8621"+ id="rect4164"+ style="color:#000000;fill:none;stroke:#000000;stroke-width:7.00000048;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:7.00000048, 14.00000095;stroke-dashoffset:9.80000067;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />+ </g>+</svg>
+ data/icon_evaluate.svg view
@@ -0,0 +1,104 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+ xmlns:dc="http://purl.org/dc/elements/1.1/"+ xmlns:cc="http://creativecommons.org/ns#"+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+ xmlns:svg="http://www.w3.org/2000/svg"+ xmlns="http://www.w3.org/2000/svg"+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+ version="1.1"+ width="35"+ height="17.5"+ id="svg5999"+ inkscape:version="0.48.4 r9939"+ sodipodi:docname="hover_evaluate.svg">+ <sodipodi:namedview+ pagecolor="#ffffff"+ bordercolor="#666666"+ borderopacity="1"+ objecttolerance="10"+ gridtolerance="10"+ guidetolerance="10"+ inkscape:pageopacity="0"+ inkscape:pageshadow="2"+ inkscape:window-width="1441"+ inkscape:window-height="1051"+ id="namedview2999"+ showgrid="false"+ inkscape:zoom="3.56"+ inkscape:cx="-80.842697"+ inkscape:cy="25"+ inkscape:window-x="0"+ inkscape:window-y="14"+ inkscape:window-maximized="0"+ inkscape:current-layer="svg5999" />+ <defs+ id="defs6001">+ <marker+ style="overflow:visible"+ id="Arrow2Mend"+ orient="auto"+ refY="0"+ refX="0">+ <path+ inkscape:connector-curvature="0"+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"+ id="path4217"+ transform="scale(-0.6,-0.6)"+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" />+ </marker>+ <marker+ style="overflow:visible"+ id="Arrow2MendB"+ orient="auto"+ refY="0"+ refX="0"+ inkscape:stockid="Arrow2MendB">+ <path+ inkscape:connector-curvature="0"+ style="stroke-linejoin:round;stroke:#ff0000;stroke-width:0.625;fill:#ff0000;fill-rule:evenodd"+ id="path3019"+ transform="scale(-0.6,-0.6)"+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" />+ </marker>+ <marker+ style="overflow:visible"+ id="Arrow2MendBQ"+ orient="auto"+ refY="0"+ refX="0"+ inkscape:stockid="Arrow2MendBQ">+ <path+ inkscape:connector-curvature="0"+ style="stroke-linejoin:round;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;fill:#000000"+ id="path3820"+ transform="scale(-0.6,-0.6)"+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" />+ </marker>+ </defs>+ <metadata+ id="metadata6004">+ <rdf:RDF>+ <cc:Work+ rdf:about="">+ <dc:format>image/svg+xml</dc:format>+ <dc:type+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+ <dc:title></dc:title>+ </cc:Work>+ </rdf:RDF>+ </metadata>+ <g+ style=""+ id="layer1"+ transform="matrix(0.35,0,0,0.35,-84.109376,-19.205165)">+ <path+ inkscape:connector-curvature="0"+ style="stroke-linejoin:miter;marker-end:url(#Arrow2MendBQ);stroke-opacity:1;stroke:#000000;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-width:7.00000047999999975;fill:none"+ id="path4184-6"+ d="m 244.89904,79.939158 85.05631,0" />+ </g>+</svg>
data/main.ui view
@@ -39,6 +39,11 @@ <property name="can_focus">False</property> <property name="stock">gtk-save</property> </object>+ <object class="GtkImage" id="image10">+ <property name="visible">True</property>+ <property name="can_focus">False</property>+ <property name="stock">gtk-undo</property>+ </object> <object class="GtkImage" id="image2"> <property name="visible">True</property> <property name="can_focus">False</property>@@ -69,6 +74,16 @@ <property name="can_focus">False</property> <property name="stock">gtk-justify-left</property> </object>+ <object class="GtkImage" id="image8">+ <property name="visible">True</property>+ <property name="can_focus">False</property>+ <property name="stock">gtk-media-rewind</property>+ </object>+ <object class="GtkImage" id="image9">+ <property name="visible">True</property>+ <property name="can_focus">False</property>+ <property name="stock">gtk-media-forward</property>+ </object> <object class="GtkWindow" id="legenddialog"> <property name="can_focus">False</property> <property name="title" translatable="yes">ghc-vis Legend</property>@@ -103,7 +118,6 @@ <child> <object class="GtkButton" id="cancelbutton"> <property name="label">gtk-cancel</property>- <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property>@@ -118,7 +132,6 @@ <child> <object class="GtkButton" id="savebutton"> <property name="label">gtk-save</property>- <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="has_focus">True</property>@@ -167,7 +180,6 @@ <property name="can_focus">False</property> <child> <object class="GtkMenuItem" id="menuitem1">- <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes">_File</property>@@ -179,7 +191,6 @@ <child> <object class="GtkImageMenuItem" id="clear"> <property name="label" translatable="yes">Clear (:clear, c)</property>- <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="image">image3</property>@@ -189,7 +200,6 @@ <child> <object class="GtkImageMenuItem" id="export"> <property name="label" translatable="yes">Export (:export)</property>- <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="image">image2</property>@@ -198,7 +208,6 @@ </child> <child> <object class="GtkSeparatorMenuItem" id="separatormenuitem1">- <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> </object>@@ -206,7 +215,6 @@ <child> <object class="GtkImageMenuItem" id="quit"> <property name="label">gtk-quit</property>- <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="use_underline">True</property>@@ -219,7 +227,6 @@ </child> <child> <object class="GtkMenuItem" id="menuitem3">- <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes">_View</property>@@ -229,9 +236,17 @@ <property name="visible">True</property> <property name="can_focus">False</property> <child>+ <object class="GtkImageMenuItem" id="restore">+ <property name="label" translatable="yes">Restore collapsed nodes (:restore, C)</property>+ <property name="visible">True</property>+ <property name="can_focus">False</property>+ <property name="image">image10</property>+ <property name="use_stock">False</property>+ </object>+ </child>+ <child> <object class="GtkImageMenuItem" id="switch"> <property name="label" translatable="yes">Switch (:switch, v)</property>- <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="image">image4</property>@@ -241,7 +256,6 @@ <child> <object class="GtkImageMenuItem" id="update"> <property name="label" translatable="yes">Update (:update, u)</property>- <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="image">image5</property>@@ -253,8 +267,39 @@ </object> </child> <child>+ <object class="GtkMenuItem" id="menuitem2">+ <property name="visible">True</property>+ <property name="can_focus">False</property>+ <property name="label" translatable="yes">_History</property>+ <property name="use_underline">True</property>+ <child type="submenu">+ <object class="GtkMenu" id="menu4">+ <property name="visible">True</property>+ <property name="can_focus">False</property>+ <child>+ <object class="GtkImageMenuItem" id="timeback">+ <property name="label" translatable="yes">Back (:timeback, ,)</property>+ <property name="visible">True</property>+ <property name="can_focus">False</property>+ <property name="image">image8</property>+ <property name="use_stock">False</property>+ </object>+ </child>+ <child>+ <object class="GtkImageMenuItem" id="timeforward">+ <property name="label" translatable="yes">Forward (:timeforward, .)</property>+ <property name="visible">True</property>+ <property name="can_focus">False</property>+ <property name="image">image9</property>+ <property name="use_stock">False</property>+ </object>+ </child>+ </object>+ </child>+ </object>+ </child>+ <child> <object class="GtkMenuItem" id="menuitem4">- <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes">_Help</property>@@ -266,7 +311,6 @@ <child> <object class="GtkImageMenuItem" id="legend"> <property name="label" translatable="yes">Legend</property>- <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="image">image7</property>@@ -276,7 +320,6 @@ <child> <object class="GtkImageMenuItem" id="about"> <property name="label">gtk-about</property>- <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="use_underline">True</property>
data/welcome.svg view
@@ -8,1480 +8,1314 @@ xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"- width="919.96094"- height="889.92102"- id="svg3450"- version="1.1"- inkscape:version="0.48.3.1 r9886"- sodipodi:docname="welcome.svg">- <defs- id="defs3452">- <g- id="g3824">- <symbol- id="glyph0-0"- overflow="visible"- style="overflow:visible">- <path- id="path3827"- d="m 1.4375,5.125 0,-25.578125 14.5,0 0,25.578125 z m 1.640625,-1.609375 11.25,0 0,-22.328125 -11.25,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-1"- overflow="visible"- style="overflow:visible">- <path- id="path3830"- d="m 2.734375,-22.03125 2.609375,0 0,22.03125 -2.609375,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-2"- overflow="visible"- style="overflow:visible">- <path- id="path3833"- d="m 3.40625,-3.59375 2.984375,0 0,3.59375 -2.984375,0 z m 0,-11.40625 2.984375,0 0,3.59375 -2.984375,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-3"- overflow="visible"- style="overflow:visible">- <path- id="path3836"- d=""- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-4"- overflow="visible"- style="overflow:visible">- <path- id="path3839"- d="m 8.984375,-22 c -1.261719,2.167969 -2.199219,4.3125 -2.8125,6.4375 C 5.554688,-13.4375 5.25,-11.285156 5.25,-9.109375 c 0,2.1875 0.304688,4.351563 0.921875,6.484375 0.625,2.136719 1.5625,4.285156 2.8125,6.453125 l -2.265625,0 C 5.3125,1.609375 4.253906,-0.570312 3.546875,-2.71875 2.847656,-4.863281 2.5,-6.992188 2.5,-9.109375 c 0,-2.101563 0.347656,-4.21875 1.046875,-6.34375 C 4.242188,-17.585938 5.300781,-19.769531 6.71875,-22 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-5"- overflow="visible"- style="overflow:visible">- <path- id="path3842"- d="m 15.515625,-20.453125 0,2.796875 c -1.085937,-0.519531 -2.109375,-0.90625 -3.078125,-1.15625 -0.960938,-0.257812 -1.886719,-0.390625 -2.78125,-0.390625 -1.554688,0 -2.757812,0.304687 -3.609375,0.90625 -0.84375,0.605469 -1.265625,1.464844 -1.265625,2.578125 0,0.9375 0.28125,1.648438 0.84375,2.125 0.5625,0.46875 1.628906,0.851562 3.203125,1.140625 l 1.71875,0.359375 c 2.132813,0.40625 3.707031,1.125 4.71875,2.15625 1.019531,1.023438 1.53125,2.390625 1.53125,4.109375 0,2.042969 -0.6875,3.59375 -2.0625,4.65625 -1.375,1.054687 -3.390625,1.578125 -6.046875,1.578125 -1,0 -2.0625,-0.117188 -3.1875,-0.34375 -1.125,-0.21875 -2.292969,-0.550781 -3.5,-1 L 2,-3.875 c 1.15625,0.648438 2.289062,1.136719 3.40625,1.46875 1.113281,0.335938 2.207031,0.5 3.28125,0.5 1.632812,0 2.894531,-0.320312 3.78125,-0.96875 0.894531,-0.644531 1.34375,-1.5625 1.34375,-2.75 0,-1.03125 -0.324219,-1.835938 -0.96875,-2.421875 -0.636719,-0.59375 -1.679688,-1.035156 -3.125,-1.328125 l -1.75,-0.34375 c -2.136719,-0.414062 -3.683594,-1.078125 -4.640625,-1.984375 -0.949219,-0.90625 -1.421875,-2.164063 -1.421875,-3.78125 0,-1.875 0.65625,-3.347656 1.96875,-4.421875 1.320312,-1.082031 3.140625,-1.625 5.453125,-1.625 0.988281,0 2,0.09375 3.03125,0.28125 1.03125,0.179688 2.082031,0.445312 3.15625,0.796875 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-6"- overflow="visible"- style="overflow:visible">- <path- id="path3845"- d="m 14.828125,-12.765625 -4.125,0 -1.1875,4.734375 4.15625,0 z m -2.125,-8.046875 -1.46875,5.875 4.125,0 1.484375,-5.875 2.265625,0 -1.453125,5.875 4.421875,0 0,2.171875 -4.96875,0 -1.171875,4.734375 4.515625,0 0,2.171875 -5.0625,0 L 13.921875,0 11.65625,0 l 1.453125,-5.859375 -4.140625,0 L 7.5,0 5.21875,0 l 1.484375,-5.859375 -4.46875,0 0,-2.171875 4.984375,0 1.1875,-4.734375 -4.546875,0 0,-2.171875 5.109375,0 1.4375,-5.875 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-7"- overflow="visible"- style="overflow:visible">- <path- id="path3848"- d="m 3.59375,-2.40625 4.671875,0 0,-16.125 -5.078125,1.015625 0,-2.609375 5.046875,-1.015625 2.875,0 0,18.734375 4.671875,0 0,2.40625 -12.1875,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-8"- overflow="visible"- style="overflow:visible">- <path- id="path3851"- d="m 2.328125,-22 2.265625,0 c 1.414062,2.230469 2.472656,4.414062 3.171875,6.546875 0.707031,2.125 1.0625,4.242187 1.0625,6.34375 0,2.117187 -0.355469,4.246094 -1.0625,6.390625 C 7.066406,-0.570312 6.007812,1.609375 4.59375,3.828125 l -2.265625,0 C 3.578125,1.660156 4.507812,-0.488281 5.125,-2.625 5.75,-4.757812 6.0625,-6.921875 6.0625,-9.109375 6.0625,-11.285156 5.75,-13.4375 5.125,-15.5625 4.507812,-17.6875 3.578125,-19.832031 2.328125,-22 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-9"- overflow="visible"- style="overflow:visible">- <path- id="path3854"- d="m 5.5625,-2.40625 9.984375,0 0,2.40625 L 2.125,0 l 0,-2.40625 c 1.082031,-1.125 2.5625,-2.628906 4.4375,-4.515625 1.875,-1.894531 3.050781,-3.117187 3.53125,-3.671875 0.914062,-1.03125 1.554688,-1.898438 1.921875,-2.609375 0.363281,-0.71875 0.546875,-1.421875 0.546875,-2.109375 0,-1.125 -0.398438,-2.035156 -1.1875,-2.734375 -0.78125,-0.707031 -1.808594,-1.0625 -3.078125,-1.0625 -0.898437,0 -1.84375,0.15625 -2.84375,0.46875 -0.992187,0.304687 -2.054687,0.773437 -3.1875,1.40625 l 0,-2.890625 C 3.421875,-20.582031 4.5,-20.929688 5.5,-21.171875 c 1,-0.238281 1.910156,-0.359375 2.734375,-0.359375 2.195313,0 3.945313,0.554688 5.25,1.65625 1.300781,1.09375 1.953125,2.558594 1.953125,4.390625 0,0.867187 -0.167969,1.6875 -0.5,2.46875 -0.324219,0.773437 -0.914062,1.6875 -1.765625,2.75 -0.242187,0.273437 -0.996094,1.0625 -2.265625,2.375 -1.261719,1.304687 -3.042969,3.132813 -5.34375,5.484375 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-10"- overflow="visible"- style="overflow:visible">- <path- id="path3857"- d="m 11.765625,-11.40625 c 1.375,0.304688 2.441406,0.917969 3.203125,1.84375 0.769531,0.917969 1.15625,2.058594 1.15625,3.421875 0,2.085937 -0.71875,3.699219 -2.15625,4.84375 -1.429688,1.136719 -3.464844,1.703125 -6.109375,1.703125 -0.886719,0 -1.804687,-0.089844 -2.75,-0.265625 -0.9375,-0.1640625 -1.90625,-0.425781 -2.90625,-0.78125 l 0,-2.765625 C 3.003906,-2.9375 3.875,-2.582031 4.8125,-2.34375 5.757812,-2.113281 6.75,-2 7.78125,-2 c 1.789062,0 3.15625,-0.351562 4.09375,-1.0625 0.9375,-0.707031 1.40625,-1.734375 1.40625,-3.078125 0,-1.25 -0.4375,-2.222656 -1.3125,-2.921875 -0.875,-0.707031 -2.089844,-1.0625 -3.640625,-1.0625 l -2.46875,0 0,-2.34375 2.578125,0 c 1.40625,0 2.476562,-0.28125 3.21875,-0.84375 0.75,-0.5625 1.125,-1.375 1.125,-2.4375 0,-1.082031 -0.386719,-1.910156 -1.15625,-2.484375 -0.761719,-0.582031 -1.859375,-0.875 -3.296875,-0.875 -0.78125,0 -1.625,0.08594 -2.53125,0.25 -0.898437,0.167969 -1.882813,0.433594 -2.953125,0.796875 l 0,-2.5625 c 1.082031,-0.300781 2.097656,-0.523438 3.046875,-0.671875 0.957031,-0.15625 1.851563,-0.234375 2.6875,-0.234375 2.175781,0 3.894531,0.496094 5.15625,1.484375 1.269531,0.992187 1.90625,2.324219 1.90625,4 0,1.179687 -0.339844,2.171875 -1.015625,2.984375 -0.667969,0.804688 -1.621094,1.355469 -2.859375,1.65625 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-11"- overflow="visible"- style="overflow:visible">- <path- id="path3860"- d="m 2.5,-22.03125 6,0 0,2.015625 -3.40625,0 0,21.8125 3.40625,0 0,2.03125 -6,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-12"- overflow="visible"- style="overflow:visible">- <path- id="path3863"- d="m 8.828125,-22.03125 0,25.859375 -6.015625,0 0,-2.03125 3.390625,0 0,-21.8125 -3.390625,0 0,-2.015625 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-13"- overflow="visible"- style="overflow:visible">- <path- id="path3866"- d="m 14.125,-7.921875 c 0,-1.914063 -0.398438,-3.414063 -1.1875,-4.5 -0.792969,-1.09375 -1.875,-1.640625 -3.25,-1.640625 -1.375,0 -2.460938,0.546875 -3.25,1.640625 -0.792969,1.085937 -1.1875,2.585937 -1.1875,4.5 0,1.917969 0.394531,3.421875 1.1875,4.515625 0.789062,1.09375 1.875,1.640625 3.25,1.640625 1.375,0 2.457031,-0.546875 3.25,-1.640625 C 13.726562,-4.5 14.125,-6.003906 14.125,-7.921875 z m -8.875,-5.53125 c 0.550781,-0.945313 1.242188,-1.644531 2.078125,-2.09375 0.832031,-0.457031 1.832031,-0.6875 3,-0.6875 1.925781,0 3.488281,0.765625 4.6875,2.296875 1.207031,1.523438 1.8125,3.527344 1.8125,6.015625 0,2.5 -0.605469,4.515625 -1.8125,6.046875 -1.199219,1.523438 -2.761719,2.28125 -4.6875,2.28125 -1.167969,0 -2.167969,-0.230469 -3,-0.6875 C 6.492188,-0.738281 5.800781,-1.4375 5.25,-2.375 l 0,2.375 -2.609375,0 0,-22.03125 2.609375,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-14"- overflow="visible"- style="overflow:visible">- <path- id="path3869"- d="m 9.21875,-19.265625 c -1.46875,0 -2.578125,0.730469 -3.328125,2.1875 -0.742187,1.449219 -1.109375,3.625 -1.109375,6.53125 0,2.898437 0.367188,5.070313 1.109375,6.515625 0.75,1.449219 1.859375,2.171875 3.328125,2.171875 1.476562,0 2.585938,-0.722656 3.328125,-2.171875 0.75,-1.445312 1.125,-3.617188 1.125,-6.515625 0,-2.90625 -0.375,-5.082031 -1.125,-6.53125 -0.742187,-1.457031 -1.851563,-2.1875 -3.328125,-2.1875 z m 0,-2.265625 c 2.363281,0 4.171875,0.9375 5.421875,2.8125 1.257813,1.875 1.890625,4.601562 1.890625,8.171875 0,3.554687 -0.632812,6.265625 -1.890625,8.140625 -1.25,1.875 -3.058594,2.8125 -5.421875,2.8125 -2.367188,0 -4.179688,-0.9375 -5.4375,-2.8125 -1.25,-1.875 -1.875,-4.585938 -1.875,-8.140625 0,-3.570313 0.625,-6.296875 1.875,-8.171875 1.257812,-1.875 3.070312,-2.8125 5.4375,-2.8125 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-15"- overflow="visible"- style="overflow:visible">- <path- id="path3872"- d="m 10.953125,-18.65625 -7.21875,11.296875 7.21875,0 z m -0.75,-2.484375 3.609375,0 0,13.78125 3.015625,0 0,2.375 -3.015625,0 0,4.984375 -2.859375,0 0,-4.984375 -9.53125,0 0,-2.765625 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-16"- overflow="visible"- style="overflow:visible">- <path- id="path3875"- d="M 15.921875,-15.859375 10.1875,-8.140625 16.21875,0 13.140625,0 8.53125,-6.234375 3.90625,0 0.828125,0 7,-8.296875 l -5.640625,-7.5625 3.078125,0 4.203125,5.65625 4.203125,-5.65625 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-17"- overflow="visible"- style="overflow:visible">- <path- id="path3878"- d="m 5.3125,-20.359375 0,4.5 5.359375,0 0,2.03125 -5.359375,0 0,8.609375 c 0,1.292969 0.175781,2.121094 0.53125,2.484375 C 6.195312,-2.367188 6.914062,-2.1875 8,-2.1875 l 2.671875,0 0,2.1875 L 8,0 C 5.988281,0 4.597656,-0.375 3.828125,-1.125 3.066406,-1.875 2.6875,-3.238281 2.6875,-5.21875 l 0,-8.609375 -1.90625,0 0,-2.03125 1.90625,0 0,-4.5 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-18"- overflow="visible"- style="overflow:visible">- <path- id="path3881"- d="m 3.40625,-3.59375 2.984375,0 0,2.4375 L 4.0625,3.375 l -1.828125,0 1.171875,-4.53125 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-19"- overflow="visible"- style="overflow:visible">- <path- id="path3884"- d="M 9.328125,1.46875 C 8.597656,3.363281 7.878906,4.597656 7.171875,5.171875 6.472656,5.742188 5.539062,6.03125 4.375,6.03125 l -2.078125,0 0,-2.171875 1.53125,0 C 4.546875,3.859375 5.101562,3.6875 5.5,3.34375 5.894531,3 6.332031,2.195312 6.8125,0.9375 L 7.28125,-0.25 0.859375,-15.859375 l 2.765625,0 4.953125,12.40625 4.953125,-12.40625 2.765625,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- </g>- <g- id="g4592">- <symbol- id="glyph0-0-3"- overflow="visible"- style="overflow:visible">- <path- id="path4595"- d="m 1.296875,4.59375 0,-22.921875 13,0 0,22.921875 z M 2.75,3.15625 l 10.09375,0 0,-20.03125 -10.09375,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph0-1-8"- overflow="visible"- style="overflow:visible">- <path- id="path4598"- d="m 3.046875,-3.21875 2.671875,0 0,3.21875 -2.671875,0 z m 0,-10.21875 2.671875,0 0,3.21875 -2.671875,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph1-0"- overflow="visible"- style="overflow:visible">- <path- id="path4601"- d="m 1.140625,4.0625 0,-20.28125 11.5,0 0,20.28125 z M 2.4375,2.78125 l 8.921875,0 0,-17.703125 -8.921875,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph1-1"- overflow="visible"- style="overflow:visible">- <path- id="path4604"- d="m 7.859375,-14.53125 -3.078125,8.34375 6.171875,0 z m -1.28125,-2.234375 2.578125,0 L 15.546875,0 13.1875,0 l -1.53125,-4.296875 -7.5625,0 L 2.578125,0 0.1875,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph1-2"- overflow="visible"- style="overflow:visible">- <path- id="path4607"- d="m 4.53125,-14.90625 0,6.296875 2.84375,0 c 1.0625,0 1.878906,-0.269531 2.453125,-0.8125 0.570313,-0.550781 0.859375,-1.332031 0.859375,-2.34375 0,-1 -0.289062,-1.769531 -0.859375,-2.3125 C 9.253906,-14.628906 8.4375,-14.90625 7.375,-14.90625 z M 2.25,-16.765625 l 5.125,0 c 1.882812,0 3.304688,0.429687 4.265625,1.28125 0.957031,0.84375 1.4375,2.085937 1.4375,3.71875 0,1.65625 -0.480469,2.914063 -1.4375,3.765625 -0.960937,0.84375 -2.382813,1.265625 -4.265625,1.265625 l -2.84375,0 L 4.53125,0 2.25,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph2-0"- overflow="visible"- style="overflow:visible">- <path- id="path4610"- d="m 1.140625,4.0625 0,-20.28125 11.5,0 0,20.28125 z M 2.4375,2.78125 l 8.921875,0 0,-17.703125 -8.921875,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph2-1"- overflow="visible"- style="overflow:visible">- <path- id="path4613"- d="m 12.3125,-16.21875 0,2.21875 c -0.867188,-0.414062 -1.683594,-0.722656 -2.453125,-0.921875 -0.761719,-0.207031 -1.496094,-0.3125 -2.203125,-0.3125 -1.230469,0 -2.183594,0.242187 -2.859375,0.71875 -0.667969,0.480469 -1,1.164063 -1,2.046875 0,0.742188 0.21875,1.304688 0.65625,1.6875 C 4.898438,-10.40625 5.75,-10.101562 7,-9.875 l 1.359375,0.28125 c 1.695313,0.324219 2.945313,0.890625 3.75,1.703125 0.800781,0.8125 1.203125,1.902344 1.203125,3.265625 0,1.625 -0.546875,2.859375 -1.640625,3.703125 -1.085937,0.8359375 -2.679687,1.25 -4.78125,1.25 -0.792969,0 -1.636719,-0.09375 -2.53125,-0.28125 -0.898437,-0.175781 -1.824219,-0.4375 -2.78125,-0.78125 l 0,-2.34375 c 0.925781,0.523437 1.828125,0.914063 2.703125,1.171875 0.882812,0.261719 1.753906,0.390625 2.609375,0.390625 1.300781,0 2.300781,-0.253906 3,-0.765625 0.707031,-0.507812 1.0625,-1.234375 1.0625,-2.171875 0,-0.820313 -0.257813,-1.46875 -0.765625,-1.9375 -0.5,-0.46875 -1.328125,-0.816406 -2.484375,-1.046875 l -1.375,-0.265625 C 4.628906,-8.035156 3.398438,-8.5625 2.640625,-9.28125 c -0.75,-0.71875 -1.125,-1.71875 -1.125,-3 0,-1.488281 0.519531,-2.660156 1.5625,-3.515625 1.050781,-0.851563 2.492187,-1.28125 4.328125,-1.28125 0.78125,0 1.578125,0.07422 2.390625,0.21875 0.820313,0.148437 1.660156,0.359375 2.515625,0.640625 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph2-2"- overflow="visible"- style="overflow:visible">- <path- id="path4616"- d="m 11.765625,-10.125 -3.28125,0 -0.9375,3.75 3.296875,0 z m -1.6875,-6.390625 -1.171875,4.671875 3.28125,0 1.171875,-4.671875 1.796875,0 L 14,-11.84375 l 3.515625,0 0,1.71875 -3.953125,0 -0.921875,3.75 3.578125,0 0,1.71875 -4.015625,0 L 11.046875,0 9.25,0 l 1.15625,-4.65625 -3.296875,0 L 5.953125,0 4.140625,0 5.3125,-4.65625 l -3.53125,0 0,-1.71875 3.953125,0 0.9375,-3.75 -3.609375,0 0,-1.71875 4.046875,0 L 8.25,-16.515625 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph2-3"- overflow="visible"- style="overflow:visible">- <path- id="path4619"- d=""- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph2-4"- overflow="visible"- style="overflow:visible">- <path- id="path4622"- d="m 2.859375,-1.90625 3.703125,0 0,-12.796875 -4.03125,0.8125 0,-2.0625 4,-0.8125 2.28125,0 0,14.859375 3.703125,0 0,1.90625 -9.65625,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph2-5"- overflow="visible"- style="overflow:visible">- <path- id="path4625"- d="m 4.40625,-1.90625 7.921875,0 0,1.90625 -10.640625,0 0,-1.90625 C 2.539062,-2.800781 3.710938,-4 5.203125,-5.5 6.691406,-7 7.625,-7.96875 8,-8.40625 c 0.726562,-0.8125 1.238281,-1.5 1.53125,-2.0625 0.289062,-0.570312 0.4375,-1.128906 0.4375,-1.671875 0,-0.894531 -0.3125,-1.617187 -0.9375,-2.171875 -0.625,-0.5625 -1.445312,-0.84375 -2.453125,-0.84375 -0.710937,0 -1.460937,0.125 -2.25,0.375 -0.792969,0.242188 -1.636719,0.609375 -2.53125,1.109375 l 0,-2.28125 c 0.914063,-0.375 1.769531,-0.65625 2.5625,-0.84375 0.789063,-0.1875 1.515625,-0.28125 2.171875,-0.28125 1.738281,0 3.125,0.4375 4.15625,1.3125 1.03125,0.867187 1.546875,2.027344 1.546875,3.484375 0,0.6875 -0.132813,1.339844 -0.390625,1.953125 -0.25,0.617187 -0.71875,1.34375 -1.40625,2.1875 -0.1875,0.21875 -0.78125,0.851563 -1.78125,1.890625 -1,1.03125 -2.417969,2.480469 -4.25,4.34375 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph2-6"- overflow="visible"- style="overflow:visible">- <path- id="path4628"- d="m 9.328125,-9.046875 c 1.09375,0.242187 1.941406,0.730469 2.546875,1.46875 0.613281,0.730469 0.921875,1.632813 0.921875,2.703125 0,1.65625 -0.574219,2.9375 -1.71875,3.84375 -1.136719,0.90625 -2.75,1.359375 -4.84375,1.359375 -0.710937,0 -1.4375,-0.074219 -2.1875,-0.21875 C 3.304688,-0.0234375 2.539062,-0.226562 1.75,-0.5 l 0,-2.203125 c 0.632812,0.375 1.320312,0.65625 2.0625,0.84375 0.75,0.1875 1.535156,0.28125 2.359375,0.28125 1.414063,0 2.492187,-0.28125 3.234375,-0.84375 0.75,-0.5625 1.125,-1.378906 1.125,-2.453125 0,-0.988281 -0.351562,-1.757812 -1.046875,-2.3125 -0.6875,-0.5625 -1.648437,-0.84375 -2.875,-0.84375 l -1.953125,0 0,-1.859375 2.03125,0 c 1.113281,0 1.96875,-0.222656 2.5625,-0.671875 0.59375,-0.445312 0.890625,-1.085938 0.890625,-1.921875 0,-0.863281 -0.308594,-1.523437 -0.921875,-1.984375 -0.605469,-0.457031 -1.476562,-0.6875 -2.609375,-0.6875 -0.625,0 -1.296875,0.07031 -2.015625,0.203125 -0.710938,0.136719 -1.492188,0.34375 -2.34375,0.625 l 0,-2.03125 c 0.863281,-0.238281 1.671875,-0.414063 2.421875,-0.53125 0.757813,-0.125 1.472656,-0.1875 2.140625,-0.1875 1.71875,0 3.078125,0.398437 4.078125,1.1875 1.007813,0.78125 1.515625,1.839844 1.515625,3.171875 0,0.929688 -0.273438,1.714844 -0.8125,2.359375 -0.53125,0.636719 -1.289062,1.074219 -2.265625,1.3125 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph2-7"- overflow="visible"- style="overflow:visible">- <path- id="path4631"- d="m 8.6875,-14.796875 -5.71875,8.953125 5.71875,0 z m -0.59375,-1.96875 2.859375,0 0,10.921875 2.390625,0 0,1.890625 -2.390625,0 0,3.953125 -2.265625,0 0,-3.953125 -7.5625,0 0,-2.1875 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph3-0"- overflow="visible"- style="overflow:visible">- <path- id="path4634"- d="m 1.203125,4.25 0,-21.171875 12,0 0,21.171875 z m 1.34375,-1.34375 9.3125,0 0,-18.484375 -9.3125,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph3-1"- overflow="visible"- style="overflow:visible">- <path- id="path4637"- d="m 2.0625,-18.234375 4.96875,0 0,1.671875 -2.8125,0 0,18.046875 2.8125,0 0,1.6875 -4.96875,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph3-2"- overflow="visible"- style="overflow:visible">- <path- id="path4640"- d="m 7.296875,-18.234375 0,21.40625 -4.96875,0 0,-1.6875 2.8125,0 0,-18.046875 -2.8125,0 0,-1.671875 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph3-3"- overflow="visible"- style="overflow:visible">- <path- id="path4643"- d="m 7.4375,-18.21875 c -1.042969,1.804688 -1.820312,3.585938 -2.328125,5.34375 -0.511719,1.75 -0.765625,3.53125 -0.765625,5.34375 0,1.804688 0.253906,3.589844 0.765625,5.359375 0.519531,1.773437 1.296875,3.550781 2.328125,5.34375 l -1.875,0 C 4.394531,1.328125 3.519531,-0.476562 2.9375,-2.25 2.351562,-4.019531 2.0625,-5.78125 2.0625,-7.53125 c 0,-1.75 0.285156,-3.503906 0.859375,-5.265625 C 3.503906,-14.566406 4.382812,-16.375 5.5625,-18.21875 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph3-4"- overflow="visible"- style="overflow:visible">- <path- id="path4646"- d="m 1.921875,-18.21875 1.875,0 c 1.175781,1.84375 2.050781,3.652344 2.625,5.421875 0.582031,1.761719 0.875,3.515625 0.875,5.265625 0,1.75 -0.292969,3.511719 -0.875,5.28125 -0.574219,1.773438 -1.449219,3.578125 -2.625,5.421875 l -1.875,0 C 2.960938,1.378906 3.738281,-0.398438 4.25,-2.171875 4.757812,-3.941406 5.015625,-5.726562 5.015625,-7.53125 5.015625,-9.34375 4.757812,-11.125 4.25,-12.875 3.738281,-14.632812 2.960938,-16.414062 1.921875,-18.21875 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph4-0"- overflow="visible"- style="overflow:visible">- <path- id="path4649"- d="m 1.140625,4.0625 0,-20.28125 11.5,0 0,20.28125 z M 2.4375,2.78125 l 8.921875,0 0,-17.703125 -8.921875,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph4-1"- overflow="visible"- style="overflow:visible">- <path- id="path4652"- d="m 4.53125,-8 0,6.140625 3.640625,0 c 1.21875,0 2.117187,-0.25 2.703125,-0.75 0.59375,-0.507813 0.890625,-1.285156 0.890625,-2.328125 0,-1.050781 -0.296875,-1.820312 -0.890625,-2.3125 C 10.289062,-7.75 9.390625,-8 8.171875,-8 z m 0,-6.90625 0,5.0625 3.359375,0 c 1.101563,0 1.925781,-0.207031 2.46875,-0.625 0.539063,-0.414062 0.8125,-1.050781 0.8125,-1.90625 0,-0.84375 -0.273437,-1.472656 -0.8125,-1.890625 -0.542969,-0.425781 -1.367187,-0.640625 -2.46875,-0.640625 z M 2.25,-16.765625 l 5.796875,0 c 1.726563,0 3.0625,0.359375 4,1.078125 0.9375,0.71875 1.40625,1.742188 1.40625,3.0625 0,1.03125 -0.242187,1.851562 -0.71875,2.453125 -0.480469,0.605469 -1.183594,0.980469 -2.109375,1.125 1.113281,0.242187 1.976562,0.742187 2.59375,1.5 0.625,0.761719 0.9375,1.714844 0.9375,2.859375 0,1.492188 -0.511719,2.648438 -1.53125,3.46875 C 11.601562,-0.40625 10.15625,0 8.28125,0 L 2.25,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph4-2"- overflow="visible"- style="overflow:visible">- <path- id="path4655"- d="m 14.8125,-15.46875 0,2.390625 c -0.761719,-0.71875 -1.574219,-1.25 -2.4375,-1.59375 -0.867188,-0.351563 -1.789062,-0.53125 -2.765625,-0.53125 -1.917969,0 -3.386719,0.589844 -4.40625,1.765625 -1.011719,1.167969 -1.515625,2.859375 -1.515625,5.078125 0,2.210937 0.503906,3.902344 1.515625,5.078125 1.019531,1.167969 2.488281,1.75 4.40625,1.75 0.976563,0 1.898437,-0.175781 2.765625,-0.53125 0.863281,-0.351562 1.675781,-0.882812 2.4375,-1.59375 l 0,2.359375 c -0.792969,0.542969 -1.632812,0.949219 -2.515625,1.21875 -0.886719,0.269531 -1.824219,0.40625 -2.8125,0.40625 -2.542969,0 -4.542969,-0.773437 -6,-2.328125 -1.460937,-1.550781 -2.1875,-3.671875 -2.1875,-6.359375 0,-2.695313 0.726563,-4.820313 2.1875,-6.375 1.457031,-1.5625 3.457031,-2.34375 6,-2.34375 1,0 1.941406,0.136719 2.828125,0.40625 0.882812,0.273437 1.71875,0.671875 2.5,1.203125 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph4-3"- overflow="visible"- style="overflow:visible">- <path- id="path4658"- d="m 9.0625,-15.234375 c -1.648438,0 -2.953125,0.617187 -3.921875,1.84375 -0.96875,1.230469 -1.453125,2.90625 -1.453125,5.03125 0,2.105469 0.484375,3.773437 1.453125,5 0.96875,1.230469 2.273437,1.84375 3.921875,1.84375 1.644531,0 2.945312,-0.613281 3.90625,-1.84375 0.96875,-1.226563 1.453125,-2.894531 1.453125,-5 0,-2.125 -0.484375,-3.800781 -1.453125,-5.03125 -0.960938,-1.226563 -2.261719,-1.84375 -3.90625,-1.84375 z m 0,-1.84375 c 2.351562,0 4.234375,0.792969 5.640625,2.375 1.40625,1.574219 2.109375,3.6875 2.109375,6.34375 0,2.636719 -0.703125,4.746094 -2.109375,6.328125 -1.40625,1.574219 -3.289063,2.359375 -5.640625,2.359375 -2.355469,0 -4.242188,-0.785156 -5.65625,-2.359375 C 2,-3.601562 1.296875,-5.710938 1.296875,-8.359375 c 0,-2.65625 0.703125,-4.769531 2.109375,-6.34375 1.414062,-1.582031 3.300781,-2.375 5.65625,-2.375 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph5-0"- overflow="visible"- style="overflow:visible">- <path- id="path4661"- d="m 1.25,4.421875 0,-22.046875 12.5,0 0,22.046875 z m 1.40625,-1.390625 9.703125,0 0,-19.25 -9.703125,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph5-1"- overflow="visible"- style="overflow:visible">- <path- id="path4664"- d="M 8.046875,1.265625 C 7.410156,2.898438 6.789062,3.960938 6.1875,4.453125 c -0.605469,0.5 -1.414062,0.75 -2.421875,0.75 l -1.78125,0 0,-1.875 1.3125,0 c 0.613281,0 1.09375,-0.152344 1.4375,-0.453125 C 5.078125,2.582031 5.457031,1.894531 5.875,0.8125 L 6.28125,-0.21875 0.75,-13.671875 l 2.375,0 4.265625,10.6875 4.28125,-10.6875 2.375,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph5-2"- overflow="visible"- style="overflow:visible">- <path- id="path4667"- d="M 13.71875,-13.671875 8.78125,-7.015625 13.984375,0 11.328125,0 7.34375,-5.375 3.375,0 0.71875,0 l 5.3125,-7.15625 -4.859375,-6.515625 2.65625,0 3.625,4.875 3.625,-4.875 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph6-0"- overflow="visible"- style="overflow:visible">- <path- id="path4670"- d="m 1.140625,4.0625 0,-20.28125 11.5,0 0,20.28125 z M 2.4375,2.78125 l 8.921875,0 0,-17.703125 -8.921875,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph6-1"- overflow="visible"- style="overflow:visible">- <path- id="path4673"- d="m 2.171875,-17.46875 2.0625,0 0,17.46875 -2.0625,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph6-2"- overflow="visible"- style="overflow:visible">- <path- id="path4676"- d="m 4.40625,-1.90625 7.921875,0 0,1.90625 -10.640625,0 0,-1.90625 C 2.539062,-2.800781 3.710938,-4 5.203125,-5.5 6.691406,-7 7.625,-7.96875 8,-8.40625 c 0.726562,-0.8125 1.238281,-1.5 1.53125,-2.0625 0.289062,-0.570312 0.4375,-1.128906 0.4375,-1.671875 0,-0.894531 -0.3125,-1.617187 -0.9375,-2.171875 -0.625,-0.5625 -1.445312,-0.84375 -2.453125,-0.84375 -0.710937,0 -1.460937,0.125 -2.25,0.375 -0.792969,0.242188 -1.636719,0.609375 -2.53125,1.109375 l 0,-2.28125 c 0.914063,-0.375 1.769531,-0.65625 2.5625,-0.84375 0.789063,-0.1875 1.515625,-0.28125 2.171875,-0.28125 1.738281,0 3.125,0.4375 4.15625,1.3125 1.03125,0.867187 1.546875,2.027344 1.546875,3.484375 0,0.6875 -0.132813,1.339844 -0.390625,1.953125 -0.25,0.617187 -0.71875,1.34375 -1.40625,2.1875 -0.1875,0.21875 -0.78125,0.851563 -1.78125,1.890625 -1,1.03125 -2.417969,2.480469 -4.25,4.34375 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph7-0"- overflow="visible"- style="overflow:visible">- <path- id="path4679"- d="m 1.203125,4.25 0,-21.171875 12,0 0,21.171875 z m 1.34375,-1.34375 9.3125,0 0,-18.484375 -9.3125,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- <symbol- id="glyph7-1"- overflow="visible"- style="overflow:visible">- <path- id="path4682"- d="m 2.265625,-18.234375 2.15625,0 0,18.234375 -2.15625,0 z"- style="stroke:none"- inkscape:connector-curvature="0" />- </symbol>- </g>- </defs>- <sodipodi:namedview- id="base"- pagecolor="#ffffff"- bordercolor="#666666"- borderopacity="1.0"- inkscape:pageopacity="0.0"- inkscape:pageshadow="2"- inkscape:zoom="0.35"- inkscape:cx="435.83443"- inkscape:cy="33.42821"- inkscape:document-units="px"- inkscape:current-layer="layer1"- showgrid="false"- inkscape:window-width="1278"- inkscape:window-height="1008"- inkscape:window-x="0"- inkscape:window-y="14"- inkscape:window-maximized="0"- fit-margin-top="20"- fit-margin-left="20"- fit-margin-right="20"- fit-margin-bottom="20" />- <metadata- id="metadata3455">- <rdf:RDF>- <cc:Work- rdf:about="">- <dc:format>image/svg+xml</dc:format>- <dc:type- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />- <dc:title />- </cc:Work>- </rdf:RDF>- </metadata>- <g- inkscape:label="Layer 1"- inkscape:groupmode="layer"- id="layer1"- transform="translate(53.377808,-160.09879)">- <text- xml:space="preserve"- style="font-size:144px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"- x="127.14285"- y="289.50504"- id="text3464"- sodipodi:linespacing="125%"><tspan- sodipodi:role="line"- id="tspan3466"- x="127.14285"- y="289.50504">ghc-vis</tspan></text>- <g- id="surface287"- transform="matrix(0.95750438,0,0,0.95750438,7.1095031,538.67303)">- <g- id="g3887"- style="fill:#000000;fill-opacity:1">- <use- id="use3889"- y="43.740131"- x="3.644531"- xlink:href="#glyph0-1"- width="1"- height="1" />- <use- id="use3891"- y="43.740131"- x="11.745329"- xlink:href="#glyph0-2"- width="1"- height="1" />- <use- id="use3893"- y="43.740131"- x="21.56879"- xlink:href="#glyph0-3"- width="1"- height="1" />- </g>- <path- id="path3895"- transform="matrix(1.457859,0,0,1.457859,53.03246,43.735763)"- d="m -8.30078e-4,-18.561456 0,46.560687 c 0,2.762506 2.237335078,4.999841 4.999841078,4.999841 l 233.242869,0 c 2.75982,0 4.99984,-2.237335 4.99984,-4.999841 l 0,-46.560687 c 0,-2.762506 -2.24002,-4.999842 -4.99984,-4.999842 l -233.242869,0 c -2.762506,0 -4.999841078,2.237336 -4.999841078,4.999842 z"- style="fill:#7fff7f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"- inkscape:connector-curvature="0" />- <path- id="path3897"- transform="matrix(1.457859,0,0,1.457859,53.03246,43.735763)"- d="m -8.30078e-4,4.717548 243.242550078,0"- style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"- inkscape:connector-curvature="0" />- <g- id="g3899"- style="fill:#000000;fill-opacity:1">- <use- id="use3901"- y="43.740131"- x="63.964844"- xlink:href="#glyph0-4"- width="1"- height="1" />- <use- id="use3903"- y="43.740131"- x="75.340126"- xlink:href="#glyph0-5"- width="1"- height="1" />- <use- id="use3905"- y="43.740131"- x="93.848099"- xlink:href="#glyph0-6"- width="1"- height="1" />- <use- id="use3907"- y="43.740131"- x="118.27863"- xlink:href="#glyph0-3"- width="1"- height="1" />- <use- id="use3909"- y="43.740131"- x="127.54684"- xlink:href="#glyph0-7"- width="1"- height="1" />- <use- id="use3911"- y="43.740131"- x="146.09753"- xlink:href="#glyph0-8"- width="1"- height="1" />- <use- id="use3913"- y="43.740131"- x="157.47281"- xlink:href="#glyph0-2"- width="1"- height="1" />- <use- id="use3915"- y="43.740131"- x="167.29628"- xlink:href="#glyph0-4"- width="1"- height="1" />- <use- id="use3917"- y="43.740131"- x="178.67157"- xlink:href="#glyph0-5"- width="1"- height="1" />- <use- id="use3919"- y="43.740131"- x="197.17953"- xlink:href="#glyph0-6"- width="1"- height="1" />- <use- id="use3921"- y="43.740131"- x="221.61006"- xlink:href="#glyph0-3"- width="1"- height="1" />- <use- id="use3923"- y="43.740131"- x="230.87828"- xlink:href="#glyph0-9"- width="1"- height="1" />- <use- id="use3925"- y="43.740131"- x="249.42897"- xlink:href="#glyph0-8"- width="1"- height="1" />- <use- id="use3927"- y="43.740131"- x="260.80426"- xlink:href="#glyph0-2"- width="1"- height="1" />- <use- id="use3929"- y="43.740131"- x="270.62772"- xlink:href="#glyph0-4"- width="1"- height="1" />- <use- id="use3931"- y="43.740131"- x="282.00299"- xlink:href="#glyph0-5"- width="1"- height="1" />- <use- id="use3933"- y="43.740131"- x="300.51096"- xlink:href="#glyph0-6"- width="1"- height="1" />- <use- id="use3935"- y="43.740131"- x="324.9415"- xlink:href="#glyph0-3"- width="1"- height="1" />- <use- id="use3937"- y="43.740131"- x="334.20972"- xlink:href="#glyph0-10"- width="1"- height="1" />- <use- id="use3939"- y="43.740131"- x="352.76041"- xlink:href="#glyph0-8"- width="1"- height="1" />- <use- id="use3941"- y="43.740131"- x="364.13568"- xlink:href="#glyph0-2"- width="1"- height="1" />- <use- id="use3943"- y="43.740131"- x="373.95914"- xlink:href="#glyph0-11"- width="1"- height="1" />- <use- id="use3945"- y="43.740131"- x="385.33444"- xlink:href="#glyph0-12"- width="1"- height="1" />- </g>- <g- id="g3947"- style="fill:#000000;fill-opacity:1">- <use- id="use3949"- y="81.322166"- x="211.80859"- xlink:href="#glyph0-13"- width="1"- height="1" />- <use- id="use3951"- y="81.322166"- x="230.31656"- xlink:href="#glyph0-14"- width="1"- height="1" />- </g>- <g- id="g3953"- style="fill:#000000;fill-opacity:1">- <use- id="use3955"- y="177.2245"- x="3.644531"- xlink:href="#glyph0-1"- width="1"- height="1" />- <use- id="use3957"- y="177.2245"- x="11.745329"- xlink:href="#glyph0-9"- width="1"- height="1" />- <use- id="use3959"- y="177.2245"- x="30.296013"- xlink:href="#glyph0-2"- width="1"- height="1" />- <use- id="use3961"- y="177.2245"- x="40.119473"- xlink:href="#glyph0-3"- width="1"- height="1" />- </g>- <path- id="path3963"- transform="matrix(1.457859,0,0,1.457859,53.03246,177.22096)"- d="m -8.30078e-4,-18.562018 0,56.563049 c 0,2.759827 2.237335078,4.999842 4.999841078,4.999842 l 111.298719,0 c 2.76251,0 4.99984,-2.240015 4.99984,-4.999842 l 0,-56.563049 c 0,-2.762506 -2.23733,-4.999841 -4.99984,-4.999841 l -111.298719,0 c -2.762506,0 -4.999841078,2.237335 -4.999841078,4.999841 z"- style="fill:#7fff7f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"- inkscape:connector-curvature="0" />- <path- id="path3965"- transform="matrix(1.457859,0,0,1.457859,53.03246,177.22096)"- d="m -8.30078e-4,14.719348 121.298400078,0"- style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"- inkscape:connector-curvature="0" />- <g- id="g3967"- style="fill:#000000;fill-opacity:1">- <use- id="use3969"- y="177.2245"- x="63.964844"- xlink:href="#glyph0-4"- width="1"- height="1" />- <use- id="use3971"- y="177.2245"- x="75.340126"- xlink:href="#glyph0-5"- width="1"- height="1" />- <use- id="use3973"- y="177.2245"- x="93.848099"- xlink:href="#glyph0-6"- width="1"- height="1" />- <use- id="use3975"- y="177.2245"- x="118.27863"- xlink:href="#glyph0-3"- width="1"- height="1" />- <use- id="use3977"- y="177.2245"- x="127.54684"- xlink:href="#glyph0-15"- width="1"- height="1" />- <use- id="use3979"- y="177.2245"- x="146.09753"- xlink:href="#glyph0-8"- width="1"- height="1" />- <use- id="use3981"- y="177.2245"- x="157.47281"- xlink:href="#glyph0-2"- width="1"- height="1" />- </g>- <path- id="path3983"- transform="matrix(1.457859,0,0,1.457859,53.03246,177.22096)"- d="m 80.878168,-18.562018 0,23.281684 c 0,2.759826 2.237335,4.999841 4.999841,4.999841 l 25.419881,0 c 2.7625,0 4.99984,-2.240015 4.99984,-4.999841 l 0,-23.281684 c 0,-2.762506 -2.23734,-4.999841 -4.99984,-4.999841 l -25.419881,0 c -2.762506,0 -4.999841,2.237335 -4.999841,4.999841 z"- style="fill:#7f7fff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"- inkscape:connector-curvature="0" />- <g- id="g3985"- style="fill:#000000;fill-opacity:1">- <use- id="use3987"- y="177.2245"- x="178.23047"- xlink:href="#glyph0-13"- width="1"- height="1" />- <use- id="use3989"- y="177.2245"- x="196.73843"- xlink:href="#glyph0-14"- width="1"- height="1" />- </g>- <g- id="g3991"- style="fill:#000000;fill-opacity:1">- <use- id="use3993"- y="229.38857"- x="122.92188"- xlink:href="#glyph0-13"- width="1"- height="1" />- <use- id="use3995"- y="229.38857"- x="141.42986"- xlink:href="#glyph0-7"- width="1"- height="1" />- </g>- <g- id="g3997"- style="fill:#000000;fill-opacity:1">- <use- id="use3999"- y="325.28702"- x="3.644531"- xlink:href="#glyph0-16"- width="1"- height="1" />- <use- id="use4001"- y="325.28702"- x="20.899656"- xlink:href="#glyph0-2"- width="1"- height="1" />- <use- id="use4003"- y="325.28702"- x="30.72312"- xlink:href="#glyph0-3"- width="1"- height="1" />- </g>- <path- id="path4005"- transform="matrix(1.457859,0,0,1.457859,53.03246,325.28474)"- d="m -8.30078e-4,-18.562897 0,23.281684 c 0,2.762506 2.237335078,4.999841 4.999841078,4.999841 l 20.567407,0 c 2.759827,0 4.999842,-2.237335 4.999842,-4.999841 l 0,-23.281684 c 0,-2.759826 -2.240015,-4.999841 -4.999842,-4.999841 l -20.567407,0 c -2.762506,0 -4.999841078,2.240015 -4.999841078,4.999841 z"- style="fill:#ff7f7f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"- inkscape:connector-curvature="0" />- <g- id="g4007"- style="fill:#000000;fill-opacity:1">- <use- id="use4009"- y="325.28702"- x="60.320312"- xlink:href="#glyph0-17"- width="1"- height="1" />- <use- id="use4011"- y="325.28702"- x="71.752548"- xlink:href="#glyph0-14"- width="1"- height="1" />- </g>- <g- id="g4013"- style="fill:#000000;fill-opacity:1">- <use- id="use4015"- y="325.28702"- x="101.23828"- xlink:href="#glyph0-4"- width="1"- height="1" />- </g>- <path- id="path4017"- transform="matrix(1.457859,0,0,1.457859,53.03246,325.28474)"- d="m 43.36864,-18.562897 0,23.281684 c 0,2.762506 2.237335,4.999841 4.999841,4.999841 l 25.41988,0 c 2.762506,0 4.999841,-2.237335 4.999841,-4.999841 l 0,-23.281684 c 0,-2.759826 -2.237335,-4.999841 -4.999841,-4.999841 l -25.41988,0 c -2.762506,0 -4.999841,2.240015 -4.999841,4.999841 z"- style="fill:#7f7fff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"- inkscape:connector-curvature="0" />- <g- id="g4019"- style="fill:#000000;fill-opacity:1">- <use- id="use4021"- y="325.28702"- x="123.54688"- xlink:href="#glyph0-13"- width="1"- height="1" />- <use- id="use4023"- y="325.28702"- x="142.05486"- xlink:href="#glyph0-7"- width="1"- height="1" />- </g>- <g- id="g4025"- style="fill:#000000;fill-opacity:1">- <use- id="use4027"- y="325.28702"- x="171.53906"- xlink:href="#glyph0-18"- width="1"- height="1" />- </g>- <path- id="path4029"- transform="matrix(1.457859,0,0,1.457859,53.03246,325.28474)"- d="m 90.146362,-18.562897 0,23.281684 c 0,2.762506 2.237336,4.999841 4.999842,4.999841 l 25.419876,0 c 2.76251,0 4.99984,-2.237335 4.99984,-4.999841 l 0,-23.281684 c 0,-2.759826 -2.23733,-4.999841 -4.99984,-4.999841 l -25.419876,0 c -2.762506,0 -4.999842,2.240015 -4.999842,4.999841 z"- style="fill:#7f7fff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"- inkscape:connector-curvature="0" />- <g- id="g4031"- style="fill:#000000;fill-opacity:1">- <use- id="use4033"- y="325.28702"- x="191.74219"- xlink:href="#glyph0-13"- width="1"- height="1" />- <use- id="use4035"- y="325.28702"- x="210.25015"- xlink:href="#glyph0-14"- width="1"- height="1" />- </g>- <g- id="g4037"- style="fill:#000000;fill-opacity:1">- <use- id="use4039"- y="325.28702"- x="239.73438"- xlink:href="#glyph0-8"- width="1"- height="1" />- </g>- <g- id="g4041"- style="fill:#000000;fill-opacity:1">- <use- id="use4043"- y="417.54092"- x="3.644531"- xlink:href="#glyph0-19"- width="1"- height="1" />- <use- id="use4045"- y="417.54092"- x="18.778358"- xlink:href="#glyph0-2"- width="1"- height="1" />- <use- id="use4047"- y="417.54092"- x="28.601822"- xlink:href="#glyph0-3"- width="1"- height="1" />- </g>- <path- id="path4049"- transform="matrix(1.457859,0,0,1.457859,53.03246,417.53986)"- d="m -8.30078e-4,-18.563733 0,56.563049 c 0,2.762507 2.237335078,4.999842 4.999841078,4.999842 l 62.763281,0 c 2.762507,0 4.999842,-2.237335 4.999842,-4.999842 l 0,-56.563049 c 0,-2.759827 -2.237335,-4.999841 -4.999842,-4.999841 l -62.763281,0 c -2.762506,0 -4.999841078,2.240014 -4.999841078,4.999841 z"- style="fill:#7fff7f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"- inkscape:connector-curvature="0" />- <path- id="path4051"- transform="matrix(1.457859,0,0,1.457859,53.03246,417.53986)"- d="m -8.30078e-4,14.717633 72.762964078,0"- style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"- inkscape:connector-curvature="0" />- <g- id="g4053"- style="fill:#000000;fill-opacity:1">- <use- id="use4055"- y="417.54092"- x="63.964844"- xlink:href="#glyph0-4"- width="1"- height="1" />- <use- id="use4057"- y="417.54092"- x="75.340126"- xlink:href="#glyph0-8"- width="1"- height="1" />- <use- id="use4059"- y="417.54092"- x="86.715416"- xlink:href="#glyph0-2"- width="1"- height="1" />- </g>- <path- id="path4061"- transform="matrix(1.457859,0,0,1.457859,53.03246,417.53986)"- d="m 32.342731,-18.563733 0,23.281683 c 0,2.762507 2.237335,4.999842 4.999841,4.999842 l 25.419879,0 c 2.762506,0 4.999841,-2.237335 4.999841,-4.999842 l 0,-23.281683 c 0,-2.759827 -2.237335,-4.999841 -4.999841,-4.999841 l -25.419879,0 c -2.762506,0 -4.999841,2.240014 -4.999841,4.999841 z"- style="fill:#7f7fff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1"- inkscape:connector-curvature="0" />- <g- id="g4063"- style="fill:#000000;fill-opacity:1">- <use- id="use4065"- y="417.54092"- x="107.47266"- xlink:href="#glyph0-13"- width="1"- height="1" />- <use- id="use4067"- y="417.54092"- x="125.98063"- xlink:href="#glyph0-9"- width="1"- height="1" />- </g>- <g- id="g4069"- style="fill:#000000;fill-opacity:1">- <use- id="use4071"- y="469.70499"- x="87.542969"- xlink:href="#glyph0-13"- width="1"- height="1" />- <use- id="use4073"- y="469.70499"- x="106.05094"- xlink:href="#glyph0-9"- width="1"- height="1" />- </g>- </g>- <text- xml:space="preserve"- style="font-size:72px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"- x="406.8136"- y="408.48969"- id="text3468-5"- sodipodi:linespacing="125%"><tspan- sodipodi:role="line"- x="406.8136"- y="408.48969"- id="tspan3472-8">Type :view x in GHCi</tspan><tspan- sodipodi:role="line"- x="406.8136"- y="498.48969"- id="tspan5130">to visualize expression x</tspan></text>- <g- transform="matrix(1.25,0,0,-1.25,439.73215,1037.3623)"- id="g4843">- <g- id="g4845"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 110.125,-23.82 c 0,9.644 -11.727,17.461 -26.191,17.461 -14.465,0 -26.188,-7.817 -26.188,-17.461 0,-9.645 11.723,-17.461 26.188,-17.461 14.464,0 26.191,7.816 26.191,17.461"- style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4847" />- </g>- <g- id="g4849"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 110.125,-130.52 c 0,13.93 -11.727,25.219 -26.191,25.219 -14.465,0 -26.188,-11.289 -26.188,-25.219 0,-13.929 11.723,-25.218 26.188,-25.218 14.464,0 26.191,11.289 26.191,25.218"- style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4851" />- </g>- <text- transform="matrix(1,0,0,-1,79.570312,287.62471)"- id="text4853">- <tspan- style="font-size:25.9445858px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans"- x="0"- y="0"- id="tspan4855">:</tspan>- </text>- <g- id="g4857"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 105.273,-217.82 c 0,13.929 -22.582,25.218 -50.437,25.218 -27.859,0 -50.441,-11.289 -50.441,-25.218 0,-13.93 22.582,-25.219 50.441,-25.219 27.855,0 50.437,11.289 50.437,25.219"- style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4859" />- </g>- <text- transform="matrix(1,0,0,-1,26.703125,200.02351)"- id="text4861">- <tspan- style="font-size:23.21299934px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans"- x="0 14.693829 34.099895 41.45842"- y="0"- sodipodi:role="line"- id="tspan4863">S# 1</tspan>- </text>- <g- id="g4865"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 175.113,-217.82 c 0,13.929 -11.722,25.218 -26.187,25.218 -14.465,0 -26.192,-11.289 -26.192,-25.218 0,-13.93 11.727,-25.219 26.192,-25.219 14.465,0 26.187,11.289 26.187,25.219"- style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4867" />- </g>- <text- transform="matrix(1,0,0,-1,144.55859,200.32393)"- id="text4869">- <tspan- style="font-size:25.9445858px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans"- x="0"- y="0"- id="tspan4871">:</tspan>- </text>- <g- id="g4873"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 170.266,-392.422 c 0,13.93 -22.582,25.223 -50.442,25.223 -27.855,0 -50.437,-11.293 -50.437,-25.223 0,-13.926 22.582,-25.219 50.437,-25.219 27.86,0 50.442,11.293 50.442,25.219"- style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4875" />- </g>- <text- transform="matrix(1,0,0,-1,91.695313,25.421945)"- id="text4877">- <tspan- style="font-size:23.21299934px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans"- x="0 14.693829 34.099895 41.45842"- y="0"- sodipodi:role="line"- id="tspan4879">S# 1</tspan>- </text>- <g- id="g4881"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 275.023,-305.121 c 0,13.93 -28.66,25.223 -64.019,25.223 -35.356,0 -64.02,-11.293 -64.02,-25.223 0,-13.926 28.664,-25.219 64.02,-25.219 35.359,0 64.019,11.293 64.019,25.219"- style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4883" />- </g>- <text- transform="matrix(1,0,0,-1,173.66016,112.83297)"- id="text4885">- <tspan- style="font-size:24.19260597px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans"- x="0 14.733297 30.023024 45.336945 60.626671"- y="0"- sodipodi:role="line"- id="tspan4887">Thunk</tspan>- </text>- <g- id="g4889"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 288.605,-392.422 c 0,13.93 -22.582,25.223 -50.441,25.223 -27.855,0 -50.437,-11.293 -50.437,-25.223 0,-13.926 22.582,-25.219 50.437,-25.219 27.859,0 50.441,11.293 50.441,25.219"- style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4891" />- </g>- <text- transform="matrix(1,0,0,-1,210.03516,25.421945)"- id="text4893">- <tspan- style="font-size:23.21299934px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans"- x="0 14.693829 34.099895 41.45842"- y="0"- sodipodi:role="line"- id="tspan4895">S# 0</tspan>- </text>- <g- id="g4897"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 83.934,-41.281 c 0,-14.547 0,-35.891 0,-54.321"- style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4899" />- </g>- <path- inkscape:connector-curvature="0"- d="m 87.816,328.398 -3.882,-9.699 -2.911,9.699 6.793,0 z"- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"- id="path4901" />- <g- id="g4903"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 87.816,-95.602 -3.882,-9.699 -2.911,9.699 6.793,0 z"- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4905" />- </g>- <text- transform="matrix(1,0,0,-1,84.421875,344.52158)"- id="text4907">- <tspan- style="font-size:22.93732834px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans"- x="0 8.9455585 23.510763 30.758959 45.324162 52.595295 59.866428"- y="0"- sodipodi:role="line"- id="tspan4909">[1,1..]</tspan>- </text>- <g- id="g4911"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 76.176,-154.77 c -2.91,-8.73 -6.789,-19.402 -9.699,-29.101"- style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4913" />- </g>- <path- inkscape:connector-curvature="0"- d="m 69.387,239.16 -5.821,-7.762 -0.972,9.704 6.793,-1.942 z"- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"- id="path4915" />- <g- id="g4917"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 69.387,-184.84 -5.821,-7.762 -0.972,9.704 6.793,-1.942 z"- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4919" />- </g>- <g- id="g4921"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 99.453,-150.891 c 8.731,-11.64 19.402,-26.187 28.133,-38.8"- style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4923" />- </g>- <path- inkscape:connector-curvature="0"- d="m 130.496,236.25 2.91,-9.699 -8.73,5.82 5.82,3.879 z"- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"- id="path4925" />- <g- id="g4927"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 130.496,-187.75 2.91,-9.699 -8.73,5.82 5.82,3.879 z"- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4929" />- </g>- <g- id="g4931"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 145.047,-243.039 c -2.91,-10.672 -4.852,-24.25 -6.793,-36.859 -3.879,-26.192 -8.731,-55.293 -12.609,-77.602"- style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4933" />- </g>- <path- inkscape:connector-curvature="0"- d="m 128.555,66.5 -4.852,-9.699 -1.937,10.668 6.789,-0.969 z"- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"- id="path4935" />- <g- id="g4937"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 128.555,-357.5 -4.852,-9.699 -1.937,10.668 6.789,-0.969 z"- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4939" />- </g>- <g- id="g4941"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 163.477,-239.16 c 7.757,-9.699 16.488,-22.309 24.25,-33.949"- style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4943" />- </g>- <path- inkscape:connector-curvature="0"- d="m 190.637,152.828 2.91,-9.699 -7.762,5.82 4.852,3.879 z"- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"- id="path4945" />- <g- id="g4947"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 190.637,-271.172 2.91,-9.699 -7.762,5.82 4.852,3.879 z"- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4949" />- </g>- <g- id="g4951"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 186.754,-328.398 c -11.641,-10.672 -24.25,-23.282 -35.891,-34.922"- style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4953" />- </g>- <path- inkscape:connector-curvature="0"- d="m 152.805,58.738 -9.7,-4.847 4.848,9.699 4.852,-4.852 z"- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"- id="path4955" />- <g- id="g4957"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 152.805,-365.262 -9.7,-4.847 4.848,9.699 4.852,-4.852 z"- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4959" />- </g>- <g- id="g4961"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 218.766,-330.34 c 2.91,-8.73 5.82,-18.43 8.73,-27.16"- style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4963" />- </g>- <path- inkscape:connector-curvature="0"- d="m 230.406,67.469 0,-10.668 -5.82,7.758 5.82,2.91 z"- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"- id="path4965" />- <g- id="g4967"- transform="translate(0,424)">- <path- inkscape:connector-curvature="0"- d="m 230.406,-356.531 0,-10.668 -5.82,7.758 5.82,2.91 z"- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"- id="path4969" />- </g>+ version="1.1"+ width="899.96094"+ height="768.12683"+ viewBox="0 0 719.96875 614.50146"+ id="svg2">+ <metadata+ id="metadata312">+ <rdf:RDF>+ <cc:Work+ rdf:about="">+ <dc:format>image/svg+xml</dc:format>+ <dc:type+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+ <dc:title></dc:title>+ </cc:Work>+ </rdf:RDF>+ </metadata>+ <defs+ id="defs4">+ <g+ id="g6">+ <symbol+ id="glyph0-0"+ style="overflow:visible">+ <path+ d="m 2,-15 1.890625,0 0,15 L 2,0 z m 0,0"+ id="path9"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-1"+ style="overflow:visible">+ <path+ d="m 2,-2.15625 1.890625,0 0,2.15625 L 2,0 z M 2,-10 l 1.890625,0 0,2.15625 -1.890625,0 z m 0,0"+ id="path12"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-2"+ style="overflow:visible">+ <path+ d=""+ id="path15"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-3"+ style="overflow:visible">+ <path+ d="m 6.46875,-15 c -0.875,1.523438 -1.527344,3.023438 -1.953125,4.5 -0.417969,1.480469 -0.625,2.976562 -0.625,4.484375 0,1.523437 0.210937,3.027344 0.640625,4.515625 0.425781,1.4921875 1.070312,2.988281 1.9375,4.5 L 4.90625,3 C 3.9375,1.445312 3.207031,-0.0703125 2.71875,-1.5625 2.238281,-3.050781 2,-4.535156 2,-6.015625 2,-7.472656 2.238281,-8.945312 2.71875,-10.4375 3.207031,-11.925781 3.9375,-13.445312 4.90625,-15 z m 0,0"+ id="path18"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-4"+ style="overflow:visible">+ <path+ d="m 10.203125,-13.3125 0,1.796875 C 9.460938,-11.847656 8.765625,-12.09375 8.109375,-12.25 7.460938,-12.414062 6.828125,-12.5 6.203125,-12.5 5.148438,-12.5 4.332031,-12.304688 3.75,-11.921875 3.175781,-11.546875 2.890625,-11 2.890625,-10.28125 c 0,0.605469 0.1875,1.058594 0.5625,1.359375 0.382813,0.304687 1.101563,0.546875 2.15625,0.734375 l 1.1875,0.21875 c 1.4375,0.25 2.492187,0.703125 3.171875,1.359375 0.6875,0.65625 1.03125,1.53125 1.03125,2.625 0,1.304687 -0.464844,2.292969 -1.390625,2.96875 C 8.679688,-0.335938 7.320312,0 5.53125,0 4.851562,0 4.128906,-0.0703125 3.359375,-0.21875 2.597656,-0.363281 1.8125,-0.582031 1,-0.875 L 1,-2.75 c 0.800781,0.417969 1.582031,0.730469 2.34375,0.9375 0.769531,0.210938 1.523438,0.3125 2.265625,0.3125 1.113281,0 1.972656,-0.203125 2.578125,-0.609375 0.613281,-0.40625 0.921875,-0.992187 0.921875,-1.765625 0,-0.65625 -0.21875,-1.164062 -0.65625,-1.53125 -0.429687,-0.375 -1.136719,-0.65625 -2.125,-0.84375 l -1.1875,-0.21875 c -1.449219,-0.269531 -2.5,-0.691406 -3.15625,-1.265625 C 1.328125,-8.316406 1,-9.117188 1,-10.140625 1,-11.335938 1.445312,-12.28125 2.34375,-12.96875 3.238281,-13.65625 4.460938,-14 6.015625,-14 c 0.675781,0 1.359375,0.05859 2.046875,0.171875 0.695312,0.117187 1.410156,0.289063 2.140625,0.515625 z m 0,0"+ id="path21"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-5"+ style="overflow:visible">+ <path+ d="m 10.9375,-8.671875 -2.984375,0 L 7.09375,-5.5 l 3,0 z M 9.40625,-14 l -1.078125,3.859375 3,0 L 12.40625,-14 l 1.625,0 -1.046875,3.859375 3.015625,0 0,1.46875 -3.421875,0 L 11.75,-5.5 l 3.25,0 0,1.5 -3.65625,0 -1.0625,4 -1.640625,0 1.0625,-4 -3,0 -1.0625,4 L 4,0 5.0625,-4 2,-4 l 0,-1.5 3.4375,0 0.859375,-3.171875 -3.296875,0 0,-1.46875 3.703125,0 L 7.734375,-14 z m 0,0"+ id="path24"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-6"+ style="overflow:visible">+ <path+ d="m 3,-1.625 3.109375,0 0,-10.65625 L 2.5,-11.609375 2.5,-13.328125 6.09375,-14 8,-14 l 0,12.375 3,0 L 11,0 3,0 z m 0,0"+ id="path27"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-7"+ style="overflow:visible">+ <path+ d="m 1.421875,-15 1.5625,0 c 0.96875,1.554688 1.691406,3.074219 2.171875,4.5625 0.488281,1.492188 0.734375,2.964844 0.734375,4.421875 0,1.480469 -0.246094,2.964844 -0.734375,4.453125 C 4.675781,-0.0703125 3.953125,1.445312 2.984375,3 l -1.5625,0 C 2.285156,1.488281 2.929688,-0.0078125 3.359375,-1.5 3.785156,-2.988281 4,-4.492188 4,-6.015625 4,-7.523438 3.785156,-9.019531 3.359375,-10.5 2.929688,-11.976562 2.285156,-13.476562 1.421875,-15 z m 0,0"+ id="path30"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-8"+ style="overflow:visible">+ <path+ d="M 3.34375,-1.5 10,-1.5 10,0 1,0 1,-1.5 c 0.738281,-0.738281 1.75,-1.726562 3.03125,-2.96875 1.28125,-1.25 2.082031,-2.054688 2.40625,-2.421875 0.625,-0.675781 1.054688,-1.25 1.296875,-1.71875 0.25,-0.476563 0.375,-0.941406 0.375,-1.390625 0,-0.738281 -0.273437,-1.335938 -0.8125,-1.796875 -0.542969,-0.46875 -1.25,-0.703125 -2.125,-0.703125 -0.625,0 -1.28125,0.105469 -1.96875,0.3125 C 2.515625,-11.988281 1.78125,-11.679688 1,-11.265625 L 1,-13.125 c 0.78125,-0.289062 1.515625,-0.507812 2.203125,-0.65625 C 3.890625,-13.925781 4.519531,-14 5.09375,-14 c 1.488281,0 2.675781,0.359375 3.5625,1.078125 0.894531,0.71875 1.34375,1.679687 1.34375,2.875 0,0.5625 -0.109375,1.101563 -0.328125,1.609375 -0.21875,0.5 -0.621094,1.101562 -1.203125,1.796875 C 8.3125,-6.460938 7.804688,-5.945312 6.953125,-5.09375 6.097656,-4.238281 4.894531,-3.039062 3.34375,-1.5 z m 0,0"+ id="path33"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-9"+ style="overflow:visible">+ <path+ d="m 8.28125,-7.8125 c 0.851562,0.199219 1.519531,0.605469 2,1.21875 C 10.757812,-5.988281 11,-5.234375 11,-4.328125 c 0,1.367187 -0.492188,2.429687 -1.46875,3.1875 C 8.550781,-0.378906 7.160156,0 5.359375,0 4.742188,0 4.113281,-0.0507812 3.46875,-0.15625 2.832031,-0.269531 2.175781,-0.4375 1.5,-0.65625 l 0,-1.796875 c 0.539062,0.324219 1.132812,0.5625 1.78125,0.71875 C 3.9375,-1.578125 4.613281,-1.5 5.3125,-1.5 c 1.238281,0 2.179688,-0.238281 2.828125,-0.71875 0.644531,-0.476562 0.96875,-1.171875 0.96875,-2.078125 0,-0.84375 -0.296875,-1.503906 -0.890625,-1.984375 C 7.632812,-6.757812 6.816406,-7 5.765625,-7 l -1.671875,0 0,-1.5 1.828125,0 c 1,0 1.757813,-0.164062 2.28125,-0.5 C 8.734375,-9.34375 9,-9.832031 9,-10.46875 9,-11.125 8.726562,-11.625 8.1875,-11.96875 7.644531,-12.320312 6.863281,-12.5 5.84375,-12.5 c -0.554688,0 -1.152344,0.05469 -1.796875,0.15625 -0.636719,0.105469 -1.335937,0.261719 -2.09375,0.46875 l 0,-1.5625 c 0.757813,-0.1875 1.46875,-0.328125 2.125,-0.421875 C 4.742188,-13.953125 5.375,-14 5.96875,-14 c 1.519531,0 2.71875,0.304688 3.59375,0.90625 0.882812,0.59375 1.328125,1.414062 1.328125,2.453125 0,0.710937 -0.230469,1.3125 -0.6875,1.8125 C 9.753906,-8.335938 9.113281,-8 8.28125,-7.8125 z m 0,0"+ id="path36"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-10"+ style="overflow:visible">+ <path+ d="m 2,-15 4.234375,0 0,1.5 -2.34375,0 0,14.5 2.34375,0 0,1.5 L 2,2.5 z m 0,0"+ id="path39"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-11"+ style="overflow:visible">+ <path+ d="m 5.890625,-15 0,17.5 -4.234375,0 0,-1.5 L 4,1 l 0,-14.5 -2.34375,0 0,-1.5 z m 0,0"+ id="path42"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-12"+ style="overflow:visible">+ <path+ d="M 10.984375,-11 7.015625,-5.640625 11.1875,0 9.0625,0 5.875,-4.328125 2.703125,0 l -2.125,0 4.25,-5.75 L 0.9375,-11 3.0625,-11 5.953125,-7.078125 8.859375,-11 z m 0,0"+ id="path45"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-13"+ style="overflow:visible">+ <path+ d="M 7,-12.375 2.078125,-5 7,-5 z M 6.484375,-14 l 2.40625,0 0,9 L 11,-5 l 0,1.609375 -2.109375,0 L 8.890625,0 7,0 l 0,-3.390625 -6.5,0 0,-1.859375 z m 0,0"+ id="path48"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-14"+ style="overflow:visible">+ <path+ d="m 4,-14 0,3 4,0 0,1.5 -4,0 0,5.9375 c 0,0.886719 0.128906,1.453125 0.390625,1.703125 0.269531,0.25 0.8125,0.375 1.625,0.375 L 8,-1.484375 8,0 6.03125,0 C 4.539062,0 3.515625,-0.253906 2.953125,-0.765625 c -0.5625,-0.519531 -0.84375,-1.457031 -0.84375,-2.8125 L 2.109375,-9.5 1,-9.5 1,-11 l 1.109375,0 0,-3 z m 0,0"+ id="path51"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-15"+ style="overflow:visible">+ <path+ d="m 3.890625,-7 0,5.5 3.125,0 c 1.050781,0 1.828125,-0.222656 2.328125,-0.671875 0.507812,-0.457031 0.765625,-1.148437 0.765625,-2.078125 0,-0.9375 -0.257813,-1.628906 -0.765625,-2.078125 C 8.84375,-6.773438 8.066406,-7 7.015625,-7 z m 0,-5.5 0,4 3.09375,0 C 7.992188,-8.5 8.75,-8.660156 9.25,-8.984375 9.75,-9.316406 10,-9.820312 10,-10.5 10,-11.175781 9.75,-11.675781 9.25,-12 8.75,-12.332031 7.992188,-12.5 6.984375,-12.5 z M 2,-14 l 5.109375,0 c 1.53125,0 2.707031,0.289062 3.53125,0.859375 0.832031,0.574219 1.25,1.386719 1.25,2.4375 0,0.8125 -0.203125,1.464844 -0.609375,1.953125 -0.398438,0.492188 -0.992188,0.792969 -1.78125,0.90625 0.789062,0.210938 1.40625,0.640625 1.84375,1.296875 C 11.78125,-5.890625 12,-5.066406 12,-4.078125 12,-2.773438 11.570312,-1.769531 10.71875,-1.0625 9.863281,-0.351562 8.644531,0 7.0625,0 L 2,0 z m 0,0"+ id="path54"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-16"+ style="overflow:visible">+ <path+ d="m 13,-12.71875 0,1.921875 c -0.6875,-0.570313 -1.429688,-1 -2.21875,-1.28125 C 10,-12.359375 9.164062,-12.5 8.28125,-12.5 c -1.742188,0 -3.074219,0.476562 -4,1.421875 C 3.351562,-10.140625 2.890625,-8.78125 2.890625,-7 c 0,1.78125 0.460937,3.148438 1.390625,4.09375 0.925781,0.9375 2.257812,1.40625 4,1.40625 0.882812,0 1.71875,-0.140625 2.5,-0.421875 0.789062,-0.289063 1.53125,-0.71875 2.21875,-1.28125 l 0,1.90625 C 12.300781,-0.859375 11.554688,-0.53125 10.765625,-0.3125 9.972656,-0.101562 9.144531,0 8.28125,0 6.019531,0 4.238281,-0.625 2.9375,-1.875 1.644531,-3.125 1,-4.832031 1,-7 1,-9.164062 1.644531,-10.875 2.9375,-12.125 4.238281,-13.375 6.019531,-14 8.28125,-14 c 0.875,0 1.707031,0.109375 2.5,0.328125 0.789062,0.210937 1.53125,0.527344 2.21875,0.953125 z m 0,0"+ id="path57"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-17"+ style="overflow:visible">+ <path+ d="m 7.4375,-12.5 c -1.386719,0 -2.492188,0.496094 -3.3125,1.484375 C 3.300781,-10.035156 2.890625,-8.695312 2.890625,-7 c 0,1.699219 0.410156,3.042969 1.234375,4.03125 C 4.945312,-1.988281 6.054688,-1.5 7.453125,-1.5 c 1.394531,0 2.5,-0.488281 3.3125,-1.46875 C 11.585938,-3.957031 12,-5.300781 12,-7 12,-8.695312 11.585938,-10.035156 10.765625,-11.015625 9.953125,-12.003906 8.84375,-12.5 7.4375,-12.5 z M 7.453125,-14 c 1.957031,0 3.519531,0.636719 4.6875,1.90625 1.164063,1.273438 1.75,2.96875 1.75,5.09375 0,2.125 -0.585937,3.824219 -1.75,5.09375 C 10.972656,-0.632812 9.40625,0 7.4375,0 5.488281,0 3.925781,-0.628906 2.75,-1.890625 1.582031,-3.160156 1,-4.863281 1,-7 1,-9.125 1.582031,-10.820312 2.75,-12.09375 3.925781,-13.363281 5.492188,-14 7.453125,-14 z m 0,0"+ id="path60"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-18"+ style="overflow:visible">+ <path+ d="m 2,-3 1.890625,0 0,1.75 L 2.421875,2 1.203125,2 2,-1.25 z m 0,0"+ id="path63"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-19"+ style="overflow:visible">+ <path+ d="m 8,-15 0,1.5 -1.5625,0 c -0.585938,0 -0.992188,0.121094 -1.21875,0.359375 C 5,-12.910156 4.890625,-12.488281 4.890625,-11.875 l 0,0.875 L 7,-11 l 0,1.5 -2.109375,0 0,9.5 L 3,0 l 0,-9.5 -2,0 0,-1.5 2,0 0,-0.71875 c 0,-1.144531 0.269531,-1.976562 0.8125,-2.5 C 4.351562,-14.738281 5.207031,-15 6.375,-15 z m 0,0"+ id="path66"+ style="stroke:none" />+ </symbol>+ <symbol+ id="glyph0-20"+ style="overflow:visible">+ <path+ d="M 6.859375,0.890625 C 6.347656,2.179688 5.851562,3.019531 5.375,3.40625 4.894531,3.800781 4.25,4 3.4375,4 L 2,4 2,2.53125 l 1.0625,0 c 0.488281,0 0.867188,-0.121094 1.140625,-0.359375 C 4.484375,1.941406 4.789062,1.394531 5.125,0.53125 L 5.4375,-0.296875 1.015625,-11 2.921875,-11 6.34375,-2.484375 9.765625,-11 l 1.890625,0 z m 0,0"+ id="path69"+ style="stroke:none" />+ </symbol>+ </g>+ </defs>+ <g+ transform="translate(33.958741,300.70406)"+ id="surface553">+ <g+ id="g72"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use74"+ x="2.5"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-0" />+ <use+ id="use76"+ x="8.0566406"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-1" />+ <use+ id="use78"+ x="14.794922"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-2" />+ </g>+ <path+ d="m -0.00195312,-18.5625 0,46.5625 c 0,2.761719 2.23828112,5 5.00000012,5 l 233.242183,0 c 2.76172,0 5,-2.238281 5,-5 l 0,-46.5625 c 0,-2.761719 -2.23828,-5 -5,-5 l -233.242183,0 c -2.761719,0 -5.00000012,2.238281 -5.00000012,5 z m 0,0"+ transform="translate(36.376953,30)"+ id="path80"+ style="fill:#7fff7f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" />+ <path+ d="m -0.00195312,4.71875 243.24218312,0"+ transform="translate(36.376953,30)"+ id="path82"+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" />+ <g+ id="g84"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use86"+ x="43.875"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-3" />+ <use+ id="use88"+ x="51.677734"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-4" />+ <use+ id="use90"+ x="64.373047"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-5" />+ <use+ id="use92"+ x="81.130859"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-2" />+ <use+ id="use94"+ x="87.488281"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-6" />+ <use+ id="use96"+ x="100.21289"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-7" />+ <use+ id="use98"+ x="108.01562"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-1" />+ <use+ id="use100"+ x="114.75391"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-3" />+ <use+ id="use102"+ x="122.55664"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-4" />+ <use+ id="use104"+ x="135.25195"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-5" />+ <use+ id="use106"+ x="152.00977"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-2" />+ <use+ id="use108"+ x="158.36719"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-8" />+ <use+ id="use110"+ x="171.0918"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-7" />+ <use+ id="use112"+ x="178.89453"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-1" />+ <use+ id="use114"+ x="185.63281"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-3" />+ <use+ id="use116"+ x="193.43555"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-4" />+ <use+ id="use118"+ x="206.13086"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-5" />+ <use+ id="use120"+ x="222.88867"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-2" />+ <use+ id="use122"+ x="229.24609"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-9" />+ <use+ id="use124"+ x="241.9707"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-7" />+ <use+ id="use126"+ x="249.77344"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-1" />+ <use+ id="use128"+ x="256.51172"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-10" />+ <use+ id="use130"+ x="264.31445"+ y="30.001953"+ width="289"+ height="309"+ xlink:href="#glyph0-11" />+ </g>+ <g+ id="g132"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use134"+ x="145.71484"+ y="55.783203"+ width="289"+ height="309"+ xlink:href="#glyph0-12" />+ <use+ id="use136"+ x="157.55078"+ y="55.783203"+ width="289"+ height="309"+ xlink:href="#glyph0-6" />+ </g>+ <g+ id="g138"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use140"+ x="2.5"+ y="121.56445"+ width="289"+ height="309"+ xlink:href="#glyph0-0" />+ <use+ id="use142"+ x="8.0566406"+ y="121.56445"+ width="289"+ height="309"+ xlink:href="#glyph0-8" />+ <use+ id="use144"+ x="20.78125"+ y="121.56445"+ width="289"+ height="309"+ xlink:href="#glyph0-1" />+ <use+ id="use146"+ x="27.519531"+ y="121.56445"+ width="289"+ height="309"+ xlink:href="#glyph0-2" />+ </g>+ <path+ d="m -0.00195312,-18.5625 0,56.5625 c 0,2.761719 2.23828112,5 5.00000012,5 l 110.437503,0 c 2.76172,0 5,-2.238281 5,-5 l 0,-56.5625 c 0,-2.761719 -2.23828,-5 -5,-5 l -110.437503,0 c -2.761719,0 -5.00000012,2.238281 -5.00000012,5 z m 0,0"+ transform="translate(36.376953,121.5625)"+ id="path148"+ style="fill:#7fff7f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" />+ <path+ d="m -0.00195312,14.71875 120.43750312,0"+ transform="translate(36.376953,121.5625)"+ id="path150"+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" />+ <g+ id="g152"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use154"+ x="43.875"+ y="121.56445"+ width="289"+ height="309"+ xlink:href="#glyph0-3" />+ <use+ id="use156"+ x="51.677734"+ y="121.56445"+ width="289"+ height="309"+ xlink:href="#glyph0-4" />+ <use+ id="use158"+ x="64.373047"+ y="121.56445"+ width="289"+ height="309"+ xlink:href="#glyph0-5" />+ <use+ id="use160"+ x="81.130859"+ y="121.56445"+ width="289"+ height="309"+ xlink:href="#glyph0-2" />+ <use+ id="use162"+ x="87.488281"+ y="121.56445"+ width="289"+ height="309"+ xlink:href="#glyph0-13" />+ <use+ id="use164"+ x="100.21289"+ y="121.56445"+ width="289"+ height="309"+ xlink:href="#glyph0-7" />+ <use+ id="use166"+ x="108.01562"+ y="121.56445"+ width="289"+ height="309"+ xlink:href="#glyph0-1" />+ </g>+ <path+ d="m 80.876953,-18.5625 0,23.28125 c 0,2.761719 2.238281,5 5,5 l 24.558597,0 c 2.76172,0 5,-2.238281 5,-5 l 0,-23.28125 c 0,-2.761719 -2.23828,-5 -5,-5 l -24.558597,0 c -2.761719,0 -5,2.238281 -5,5 z m 0,0"+ transform="translate(36.376953,121.5625)"+ id="path168"+ style="fill:#7f7fff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" />+ <g+ id="g170"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use172"+ x="122.25391"+ y="121.56445"+ width="289"+ height="309"+ xlink:href="#glyph0-12" />+ <use+ id="use174"+ x="134.08984"+ y="121.56445"+ width="289"+ height="309"+ xlink:href="#glyph0-6" />+ </g>+ <g+ id="g176"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use178"+ x="84.3125"+ y="157.3457"+ width="289"+ height="309"+ xlink:href="#glyph0-12" />+ <use+ id="use180"+ x="96.148438"+ y="157.3457"+ width="289"+ height="309"+ xlink:href="#glyph0-8" />+ </g>+ <g+ id="g182"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use184"+ x="2.5"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-12" />+ <use+ id="use186"+ x="14.335938"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-1" />+ <use+ id="use188"+ x="21.074219"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-2" />+ </g>+ <path+ d="m -0.00195312,-18.5625 0,23.28125 c 0,2.761719 2.23828112,5 5.00000012,5 l 20.566406,0 c 2.761719,0 5,-2.238281 5,-5 l 0,-23.28125 c 0,-2.761719 -2.238281,-5 -5,-5 l -20.566406,0 c -2.761719,0 -5.00000012,2.238281 -5.00000012,5 z m 0,0"+ transform="translate(36.376953,223.125)"+ id="path190"+ style="fill:#ff7f7f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" />+ <g+ id="g192"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use194"+ x="41.375"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-14" />+ <use+ id="use196"+ x="49.216797"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-6" />+ </g>+ <g+ id="g198"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use200"+ x="69.441406"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-15" />+ <use+ id="use202"+ x="82.818359"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-16" />+ <use+ id="use204"+ x="96.783203"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-17" />+ <use+ id="use206"+ x="112.52539"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-3" />+ </g>+ <path+ d="m 86.451172,-18.5625 0,23.28125 c 0,2.761719 2.238281,5 5,5 l 24.562498,0 c 2.75781,0 5,-2.238281 5,-5 l 0,-23.28125 c 0,-2.761719 -2.24219,-5 -5,-5 l -24.562498,0 c -2.761719,0 -5,2.238281 -5,5 z m 0,0"+ transform="translate(36.376953,223.125)"+ id="path208"+ style="fill:#7f7fff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" />+ <g+ id="g210"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use212"+ x="127.82812"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-12" />+ <use+ id="use214"+ x="139.66406"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-8" />+ </g>+ <g+ id="g216"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use218"+ x="159.89062"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-18" />+ </g>+ <path+ d="m 132.37305,-18.5625 0,23.28125 c 0,2.761719 2.23828,5 5,5 l 24.5625,0 c 2.75781,0 5,-2.238281 5,-5 l 0,-23.28125 c 0,-2.761719 -2.24219,-5 -5,-5 l -24.5625,0 c -2.76172,0 -5,2.238281 -5,5 z m 0,0"+ transform="translate(36.376953,223.125)"+ id="path220"+ style="fill:#7f7fff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" />+ <g+ id="g222"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use224"+ x="173.75"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-12" />+ <use+ id="use226"+ x="185.58594"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-6" />+ </g>+ <g+ id="g228"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use230"+ x="205.8125"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-18" />+ </g>+ <path+ d="m 178.29492,-18.5625 0,23.28125 c 0,2.761719 2.23828,5 5,5 l 19.76563,0 c 2.76172,0 5,-2.238281 5,-5 l 0,-23.28125 c 0,-2.761719 -2.23828,-5 -5,-5 l -19.76563,0 c -2.76172,0 -5,2.238281 -5,5 z m 0,0"+ transform="translate(36.376953,223.125)"+ id="path232"+ style="fill:#ffff7f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" />+ <g+ id="g234"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use236"+ x="219.67188"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-19" />+ <use+ id="use238"+ x="226.71289"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-6" />+ </g>+ <g+ id="g240"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use242"+ x="246.9375"+ y="223.12695"+ width="289"+ height="309"+ xlink:href="#glyph0-7" />+ </g>+ <g+ id="g244"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use246"+ x="2.5"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-20" />+ <use+ id="use248"+ x="12.898438"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-1" />+ <use+ id="use250"+ x="19.636719"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-2" />+ </g>+ <path+ d="m -0.00195312,-18.5625 0,23.28125 c 0,2.761719 2.23828112,5 5.00000012,5 l 20.566406,0 c 2.761719,0 5,-2.238281 5,-5 l 0,-23.28125 c 0,-2.761719 -2.238281,-5 -5,-5 l -20.566406,0 c -2.761719,0 -5.00000012,2.238281 -5.00000012,5 z m 0,0"+ transform="translate(36.376953,286.40625)"+ id="path252"+ style="fill:#ff7f7f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" />+ <g+ id="g254"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use256"+ x="41.375"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-14" />+ <use+ id="use258"+ x="49.216797"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-8" />+ </g>+ <g+ id="g260"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use262"+ x="69.441406"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-15" />+ <use+ id="use264"+ x="82.818359"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-16" />+ <use+ id="use266"+ x="96.783203"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-17" />+ <use+ id="use268"+ x="112.52539"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-3" />+ <use+ id="use270"+ x="120.32812"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-15" />+ <use+ id="use272"+ x="133.70508"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-16" />+ <use+ id="use274"+ x="147.66992"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-17" />+ <use+ id="use276"+ x="163.41211"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-3" />+ <use+ id="use278"+ x="171.21484"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-3" />+ <use+ id="use280"+ x="179.01758"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-7" />+ <use+ id="use282"+ x="186.82031"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-18" />+ </g>+ <path+ d="m 159.30273,-18.5625 0,23.28125 c 0,2.761719 2.23829,5 5,5 l 19.76563,0 c 2.76172,0 5,-2.238281 5,-5 l 0,-23.28125 c 0,-2.761719 -2.23828,-5 -5,-5 l -19.76563,0 c -2.76171,0 -5,2.238281 -5,5 z m 0,0"+ transform="translate(36.376953,286.40625)"+ id="path284"+ style="fill:#ffff7f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" />+ <g+ id="g286"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use288"+ x="200.67969"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-19" />+ <use+ id="use290"+ x="207.7207"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-8" />+ </g>+ <g+ id="g292"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use294"+ x="227.94531"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-18" />+ </g>+ <path+ d="m 200.42773,-18.5625 0,23.28125 c 0,2.761719 2.23829,5 5,5 l 19.76563,0 c 2.76172,0 5,-2.238281 5,-5 l 0,-23.28125 c 0,-2.761719 -2.23828,-5 -5,-5 l -19.76563,0 c -2.76171,0 -5,2.238281 -5,5 z m 0,0"+ transform="translate(36.376953,286.40625)"+ id="path296"+ style="fill:#ffff7f;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1" />+ <g+ id="g298"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use300"+ x="241.80469"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-19" />+ <use+ id="use302"+ x="248.8457"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-9" />+ </g>+ <g+ id="g304"+ style="fill:#000000;fill-opacity:1">+ <use+ id="use306"+ x="269.07031"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-7" />+ <use+ id="use308"+ x="276.87305"+ y="286.4082"+ width="289"+ height="309"+ xlink:href="#glyph0-7" />+ </g>+ </g>+ <text+ x="136.41679"+ y="95.524994"+ id="text3464"+ xml:space="preserve"+ style="font-size:115.19999695px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"><tspan+ x="136.41679"+ y="95.524994"+ id="tspan3466">ghc-vis</tspan></text>+ <text+ x="360.15311"+ y="190.71274"+ id="text3468-5"+ xml:space="preserve"+ style="font-size:57.59999847px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"><tspan+ x="360.15311"+ y="190.71274"+ id="tspan3472-8">Type :view x in GHCi</tspan><tspan+ x="360.15311"+ y="262.71274"+ id="tspan5130">to visualize expression x</tspan></text>+ <g+ transform="matrix(1,0,0,-1,356.03874,612.02846)"+ id="g3099">+ <g+ transform="translate(0,336)"+ id="g3101">+ <path+ d="m 26.078,-108.828 0,35.887 70.813,0 0,-35.887 -70.813,0 z"+ id="path3103"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <g+ transform="translate(0,336)"+ id="g3105">+ <path+ d="m 50.328,-108.828 0,35.887"+ id="path3107"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <g+ transform="translate(0,336)"+ id="g3109">+ <path+ d="m 73.609,-108.828 0,35.887"+ id="path3111"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <text+ transform="matrix(1,0,0,-1,33.355469,238.77705)"+ id="text3113">+ <tspan+ x="0"+ y="0"+ id="tspan3115"+ style="font-size:25.9445858px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans">:</tspan>+ </text>+ <g+ transform="translate(0,336)"+ id="g3117">+ <path+ d="m 3.77,-182.551 0,35.891 81.48,0 0,-35.891 -81.48,0 z"+ id="path3119"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <g+ transform="translate(0,336)"+ id="g3121">+ <path+ d="m 54.211,-182.551 0,35.891"+ id="path3123"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <text+ transform="matrix(1,0,0,-1,12.015625,164.73768)"+ id="text3125">+ <tspan+ x="0 14.634792"+ y="0"+ id="tspan3127"+ style="font-size:23.08326721px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans">S#</tspan>+ </text>+ <text+ transform="matrix(1,0,0,-1,61.96875,164.88647)"+ id="text3129">+ <tspan+ x="0"+ y="0"+ id="tspan3131"+ style="font-size:24.42534065px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans">1</tspan>+ </text>+ <g+ transform="translate(0,336)"+ id="g3133">+ <path+ d="m 101.738,-182.551 0,35.891 70.813,0 0,-35.891 -70.813,0 z"+ id="path3135"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <g+ transform="translate(0,336)"+ id="g3137">+ <path+ d="m 125.988,-182.551 0,35.891"+ id="path3139"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <g+ transform="translate(0,336)"+ id="g3141">+ <path+ d="m 149.27,-182.551 0,35.891"+ id="path3143"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <text+ transform="matrix(1,0,0,-1,109.01563,165.0544)"+ id="text3145">+ <tspan+ x="0"+ y="0"+ id="tspan3147"+ style="font-size:25.9445858px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans">:</tspan>+ </text>+ <g+ transform="translate(0,336)"+ id="g3149">+ <path+ d="m 107.559,-329.988 0,35.886 80.511,0 0,-35.886 -80.511,0 z"+ id="path3151"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <g+ transform="translate(0,336)"+ id="g3153">+ <path+ d="m 157.031,-329.988 0,35.886"+ id="path3155"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <text+ transform="matrix(1,0,0,-1,114.83594,17.300177)"+ id="text3157">+ <tspan+ x="0 14.634792"+ y="0"+ id="tspan3159"+ style="font-size:23.08326721px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans">S#</tspan>+ </text>+ <text+ transform="matrix(1,0,0,-1,164.78906,17.448968)"+ id="text3161">+ <tspan+ x="0"+ y="0"+ id="tspan3163"+ style="font-size:24.42534065px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans">1</tspan>+ </text>+ <g+ transform="translate(0,336)"+ id="g3165">+ <path+ d="m 146.359,-256.27 0,35.891 136.77,0 0,-35.891 -136.77,0 z"+ id="path3167"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <g+ transform="translate(0,336)"+ id="g3169">+ <path+ d="m 236.57,-256.27 0,35.891"+ id="path3171"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <g+ transform="translate(0,336)"+ id="g3173">+ <path+ d="m 259.852,-256.27 0,35.891"+ id="path3175"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <text+ transform="matrix(1,0,0,-1,153.63672,91.141559)"+ id="text3177">+ <tspan+ x="0 14.733297 30.023024 45.336945 60.626671"+ y="0"+ id="tspan3179"+ style="font-size:24.19260597px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans">Thunk</tspan>+ </text>+ <g+ transform="translate(0,336)"+ id="g3181">+ <path+ d="m 231.719,-329.988 0,35.886 80.511,0 0,-35.886 -80.511,0 z"+ id="path3183"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <g+ transform="translate(0,336)"+ id="g3185">+ <path+ d="m 281.191,-329.988 0,35.886"+ id="path3187"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <text+ transform="matrix(1,0,0,-1,238.99609,17.300177)"+ id="text3189">+ <tspan+ x="0 14.634792"+ y="0"+ id="tspan3191"+ style="font-size:23.08326721px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans">S#</tspan>+ </text>+ <text+ transform="matrix(1,0,0,-1,288.94922,17.448968)"+ id="text3193">+ <tspan+ x="0"+ y="0"+ id="tspan3195"+ style="font-size:24.42534065px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans">0</tspan>+ </text>+ <g+ transform="translate(0,336)"+ id="g3197">+ <path+ d="m 61,-8.922 c 0,-6.789 0,-32.976 0,-54.316"+ id="path3199"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <path+ d="M 64.879,272.762 61,263.059 l -2.91,9.703 6.789,0 z"+ id="path3201"+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />+ <g+ transform="translate(0,336)"+ id="g3203">+ <path+ d="M 64.879,-63.238 61,-72.941 l -2.91,9.703 6.789,0 z"+ id="path3205"+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <text+ transform="matrix(1,0,0,-1,61.484375,288.88095)"+ id="text3207">+ <tspan+ x="0 8.9455585 23.510763 30.758959 45.324162 52.595295 59.866428"+ y="0"+ id="tspan3209"+ style="font-size:22.93732834px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVuSans">[1,1..]</tspan>+ </text>+ <g+ transform="translate(0,336)"+ id="g3211">+ <path+ d="m 61.969,-109.801 c 0,-9.699 -1.938,-19.398 -4.848,-28.129"+ id="path3213"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <path+ d="m 60.031,197.102 -6.793,-7.762 0,9.699 6.793,-1.937 z"+ id="path3215"+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />+ <g+ transform="translate(0,336)"+ id="g3217">+ <path+ d="m 60.031,-138.898 -6.793,-7.762 0,9.699 6.793,-1.937 z"+ id="path3219"+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <g+ transform="translate(0,336)"+ id="g3221">+ <path+ d="m 85.25,-109.801 c 0,-11.64 6.789,-22.308 14.551,-30.07"+ id="path3223"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <path+ d="m 101.738,198.07 4.852,-8.73 -8.731,3.879 3.879,4.851 z"+ id="path3225"+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />+ <g+ transform="translate(0,336)"+ id="g3227">+ <path+ d="m 101.738,-137.93 4.852,-8.73 -8.731,3.879 3.879,4.851 z"+ id="path3229"+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <g+ transform="translate(0,336)"+ id="g3231">+ <path+ d="m 137.629,-183.52 c 0,-32.98 -2.91,-40.742 0,-73.718 0.973,-8.731 1.941,-18.434 3.883,-27.16"+ id="path3233"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <path+ d="m 144.422,51.602 -0.973,-9.704 -4.847,8.731 5.82,0.973 z"+ id="path3235"+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />+ <g+ transform="translate(0,336)"+ id="g3237">+ <path+ d="m 144.422,-284.398 -0.973,-9.704 -4.847,8.731 5.82,0.973 z"+ id="path3239"+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <g+ transform="translate(0,336)"+ id="g3241">+ <path+ d="m 160.91,-183.52 c 0,-11.64 6.789,-22.308 14.551,-31.039"+ id="path3243"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <path+ d="m 178.371,124.352 4.848,-8.731 -9.699,3.879 4.851,4.852 z"+ id="path3245"+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />+ <g+ transform="translate(0,336)"+ id="g3247">+ <path+ d="m 178.371,-211.648 4.848,-8.731 -9.699,3.879 4.851,4.852 z"+ id="path3249"+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <g+ transform="translate(0,336)"+ id="g3251">+ <path+ d="m 248.211,-257.238 c 0,-25.223 -25.223,-39.774 -50.441,-46.563"+ id="path3253"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <path+ d="m 197.77,28.32 -9.7,0.969 7.758,5.82 1.942,-6.789 z"+ id="path3255"+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />+ <g+ transform="translate(0,336)"+ id="g3257">+ <path+ d="m 197.77,-307.68 -9.7,0.969 7.758,5.82 1.942,-6.789 z"+ id="path3259"+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <g+ transform="translate(0,336)"+ id="g3261">+ <path+ d="m 271.488,-257.238 c 0,-8.731 0,-18.434 0,-27.16"+ id="path3263"+ style="fill:none;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" />+ </g>+ <path+ d="m 275.371,51.602 -3.883,-9.704 -2.91,9.704 6.793,0 z"+ id="path3265"+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />+ <g+ transform="translate(0,336)"+ id="g3267">+ <path+ d="m 275.371,-284.398 -3.883,-9.704 -2.91,9.704 6.793,0 z"+ id="path3269"+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.97000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /> </g> </g> </svg>
ghc-vis.cabal view
@@ -1,14 +1,14 @@ name: ghc-vis-version: 0.6.1.1+version: 0.7 license: BSD3 license-file: LICENSE category: GHC, Debug, Development cabal-version: >= 1.10 build-type: Custom-author: Dennis Felsing <dennis@felsin9.de>+author: Dennis Felsing, Joachim Breitner maintainer: Dennis Felsing <dennis@felsin9.de> homepage: http://felsin9.de/nnis/ghc-vis-copyright: Dennis Felsing 2012+copyright: Dennis Felsing 2012-2013 synopsis: Live visualization of data structures in GHCi description: Visualize live data structures in GHCi. Evaluation is not forced and you can interact with the visualized data@@ -20,8 +20,8 @@ how it can be used with GHCi's debugger: <http://felsin9.de/nnis/ghc-vis/#combined-debugger> -tested-with: GHC == 7.4.1, GHC == 7.4.2, GHC == 7.6.1-data-files: ghci data/main.ui data/welcome.svg data/legend_graph.svg data/legend_list.svg+tested-with: GHC == 7.4.1, GHC == 7.4.2, GHC == 7.6.1, GHC == 7.6.2, GHC == 7.6.3+data-files: ghci data/main.ui data/welcome.svg data/legend_graph.svg data/legend_list.svg data/icon_collapse.svg data/icon_evaluate.svg data/hover_collapse.svg data/hover_evaluate.svg Extra-source-files: nonghci-test.hs flag graph@@ -32,13 +32,13 @@ Default: True Description: "Full ghc-vis window: decorations, buttons, legend" -flag sdl- Default: False- Description: "SDL window"+--flag sdl+-- Default: False+-- Description: "SDL window" Library- Exposed-modules: GHC.Vis- Other-modules: GHC.Vis.Internal GHC.Vis.Types GHC.Vis.View.List GHC.Vis.View.Common Paths_ghc_vis+ Exposed-modules: GHC.Vis GHC.Vis.Internal + Other-modules: GHC.Vis.Types GHC.Vis.View.List GHC.Vis.View.Common Paths_ghc_vis Default-Language: Haskell2010 Build-depends: base >= 4.5 && < 4.7, mtl >= 2.0 && < 2.2,@@ -48,8 +48,9 @@ transformers == 0.3.*, containers >= 0.4 && < 0.6, gtk == 0.12.*,+ svgcairo == 0.12.*, cairo == 0.12.*,- ghc-heap-view == 0.4.*+ ghc-heap-view == 0.5.* Hs-source-dirs: src/ Ghc-options: -Wall -fno-warn-unused-do-bind @@ -60,12 +61,11 @@ Cpp-options: -DGRAPH_VIEW if flag(full)- Build-depends: svgcairo >= 0.12 Cpp-options: -DFULL_WINDOW - if flag(sdl)- Build-depends: SDL == 0.6.*- Cpp-options: -DSDL_WINDOW+ --if flag(sdl)+ -- Build-depends: SDL == 0.6.*+ -- Cpp-options: -DSDL_WINDOW source-repository head type: git
ghci view
@@ -6,6 +6,9 @@ :def switch \_ -> return $ "GHC.Vis.switch" :def update \_ -> return $ "GHC.Vis.update" :def clear \_ -> return $ "GHC.Vis.clear"+:def restore \_ -> return $ "GHC.Vis.restore"+:def timeBack \_ -> return $ "GHC.Vis.history (+1)"+:def timeForward \_ -> return $ "GHC.Vis.history (\\x -> x - 1)" :def export \x -> return $ "GHC.Vis.export " ++ show x -- Evaluate one step and update values in ghc-vis
src/GHC/Vis.hs view
@@ -44,6 +44,8 @@ switch, update, clear,+ restore,+ history, export ) where@@ -66,6 +68,8 @@ import Data.Char import Data.IORef +import qualified Data.IntMap as M+ import System.Timeout import System.Mem @@ -81,7 +85,7 @@ import qualified GHC.Vis.View.Graph as Graph #endif -import Graphics.Rendering.Cairo+import Graphics.Rendering.Cairo hiding (restore) #ifdef FULL_WINDOW import Graphics.Rendering.Cairo.SVG@@ -176,6 +180,14 @@ clear :: IO () clear = put ClearSignal +-- | Reset the hidden boxes+restore :: IO ()+restore = put RestoreSignal++-- | Change position in history+history :: (Int -> Int) -> IO ()+history = put . HistorySignal+ -- | Export the current visualization view to a file, format depends on the -- file ending. Currently supported: svg, png, pdf, ps export :: String -> IO ()@@ -396,9 +408,18 @@ when (E.eventKeyName e `elem` ["c"]) $ put ClearSignal + when (E.eventKeyName e `elem` ["C"]) $+ put RestoreSignal+ when (E.eventKeyName e `elem` ["u"]) $ put UpdateSignal + when (E.eventKeyName e `elem` ["comma", "bracketleft"]) $+ put $ HistorySignal (+1)++ when (E.eventKeyName e `elem` ["period", "bracketright"]) $+ put $ HistorySignal (\x -> x - 1)+ widgetQueueDraw canvas return True @@ -445,7 +466,7 @@ return ()) boxes <- readMVar visBoxes- performGC -- TODO: Else Blackholes appear. Do we want this?+ performGC -- Else Blackholes appear. Do we want this? -- Blackholes stop our current thread and only resume after -- they have been replaced with their result, thereby leading -- to an additional element in the HeapMap we don't want.@@ -463,7 +484,7 @@ #ifdef GRAPH_VIEW where doSwitch = isGraphvizInstalled >>= \gvi -> if gvi then modifyIORef visState (\s -> s {T.view = succN (T.view s), zoomRatio = 1, position = (0, 0)})- else putStrLn "Cannot switch view: Graphviz not installed"+ else putStrLn "Cannot switch view: The Graphviz binary (dot) is not installed" succN GraphView = ListView succN ListView = GraphView@@ -488,27 +509,46 @@ timeout signalTimeout (putMVar visSignal UpdateSignal) react canvas legendCanvas) Just signal -> do- case signal of- NewSignal x n -> modifyMVar_ visBoxes (- \y -> return $ if (x,n) `elem` y then y else y ++ [(x,n)])- ClearSignal -> modifyMVar_ visBoxes (\_ -> return [])- UpdateSignal -> return ()- SwitchSignal -> doSwitch- ExportSignal d f -> catch (runCorrect exportView >>= \e -> e d f)- (\e -> do let err = show (e :: IOException)- hPutStrLn stderr $ "Couldn't export to file \"" ++ f ++ "\": " ++ err- return ())+ doUpdate <- case signal of+ NewSignal x n -> do+ modifyMVar_ visBoxes (\y -> return $ if ([n], x) `elem` y then y else y ++ [([n], x)])+ return True+ ClearSignal -> do+ modifyMVar_ visBoxes $ const $ return []+ modifyMVar_ visHidden $ const $ return []+ modifyMVar_ visHeapHistory $ const $ return (0, [(HeapGraph M.empty, [])])+ return False+ RestoreSignal -> do+ modifyMVar_ visHidden $ const $ return []+ return False+ RedrawSignal -> return False+ UpdateSignal -> return True+ SwitchSignal -> doSwitch >> return False+ HistorySignal f -> do+ modifyMVar_ visHeapHistory (\(i,xs) -> return (max 0 (min (length xs - 1) (f i)), xs))+ return False+ ExportSignal d f -> do+ catch (runCorrect exportView >>= \e -> e d f)+ (\e -> do let err = show (e :: IOException)+ hPutStrLn stderr $ "Couldn't export to file \"" ++ f ++ "\": " ++ err+ return ())+ return False boxes <- readMVar visBoxes- performGC -- TODO: Else Blackholes appear. Do we want this?- -- Blackholes stop our current thread and only resume after- -- they have been replaced with their result, thereby leading- -- to an additional element in the HeapMap we don't want.- -- Example for bad behaviour that would happen then:- -- λ> let xs = [1..42] :: [Int]- -- λ> let x = 17 :: Int- -- λ> let ys = [ y | y <- xs, y >= x ] + when doUpdate $ do+ performGC -- Else Blackholes appear. Do we want this?+ -- Blackholes stop our current thread and only resume after+ -- they have been replaced with their result, thereby leading+ -- to an additional element in the HeapMap we don't want.+ -- Example for bad behaviour that would happen then:+ -- λ> let xs = [1..42] :: [Int]+ -- λ> let x = 17 :: Int+ -- λ> let ys = [ y | y <- xs, y >= x ]++ x <- multiBuildHeapGraph 10 boxes+ modifyMVar_ visHeapHistory (\(i,xs) -> return (i,x:xs))+ runCorrect updateObjects >>= \f -> f boxes postGUISync $ widgetQueueDraw canvas@@ -518,7 +558,7 @@ #ifdef GRAPH_VIEW where doSwitch = isGraphvizInstalled >>= \gvi -> if gvi then modifyIORef visState (\s -> s {T.view = succN (T.view s), zoomRatio = 1, position = (0, 0)})- else putStrLn "Cannot switch view: Graphviz not installed"+ else putStrLn "Cannot switch view: The Graphviz binary (dot) is not installed" succN GraphView = ListView succN ListView = GraphView@@ -533,8 +573,6 @@ zoomImage :: WidgetClass w1 => w1 -> State -> Double -> T.Point -> IO T.Point zoomImage _canvas s newZoomRatio _mousePos@(_x', _y') = do- -- TODO: Mouse must stay at same spot- --E.Rectangle _ _ rw' rh' <- widgetGetAllocation canvas --let (rw, rh) = (fromIntegral rw', fromIntegral rh') --let (x,y) = (x' - rw / 2, y' - rh / 2)@@ -550,9 +588,8 @@ visMainThread = do initGUI - mainUIFile <- My.getDataFileName "data/main.ui" builder <- builderNew- builderAddFromFile builder mainUIFile+ builderAddFromFile builder =<< My.getDataFileName "data/main.ui" let get :: forall cls . GObjectClass cls => (GObject -> cls)@@ -581,13 +618,16 @@ onDelete aboutDialog $ const $ widgetHide aboutDialog >> return True onDelete legendDialog $ const $ widgetHide legendDialog >> return True - get castToMenuItem "clear" >>= \item -> onActivateLeaf item clear- get castToMenuItem "switch" >>= \item -> onActivateLeaf item switch- get castToMenuItem "update" >>= \item -> onActivateLeaf item update- get castToMenuItem "export" >>= \item -> onActivateLeaf item $ widgetShow saveDialog- get castToMenuItem "quit" >>= \item -> onActivateLeaf item $ widgetDestroy window- get castToMenuItem "about" >>= \item -> onActivateLeaf item $ widgetShow aboutDialog- get castToMenuItem "legend" >>= \item -> onActivateLeaf item $ widgetShow legendDialog+ get castToMenuItem "clear" >>= \item -> onActivateLeaf item clear+ get castToMenuItem "switch" >>= \item -> onActivateLeaf item switch+ get castToMenuItem "restore" >>= \item -> onActivateLeaf item restore+ get castToMenuItem "update" >>= \item -> onActivateLeaf item update+ get castToMenuItem "export" >>= \item -> onActivateLeaf item $ widgetShow saveDialog+ get castToMenuItem "quit" >>= \item -> onActivateLeaf item $ widgetDestroy window+ get castToMenuItem "about" >>= \item -> onActivateLeaf item $ widgetShow aboutDialog+ get castToMenuItem "legend" >>= \item -> onActivateLeaf item $ widgetShow legendDialog+ get castToMenuItem "timeback" >>= \item -> onActivateLeaf item $ history (+1)+ get castToMenuItem "timeforward" >>= \item -> onActivateLeaf item $ history (\x -> x - 1) widgetModifyBg canvas StateNormal backgroundColor widgetModifyBg legendCanvas StateNormal backgroundColor
src/GHC/Vis/Internal.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP, MagicHash, DeriveDataTypeable, NoMonomorphismRestriction, RankNTypes #-}+{-# LANGUAGE CPP, MagicHash, DeriveDataTypeable, NoMonomorphismRestriction, RankNTypes, RecordWildCards #-} {- | Module : GHC.Vis.Internal@@ -8,11 +8,8 @@ -} module GHC.Vis.Internal (- walkHeap,- parseBoxes,- parseBoxesHeap,- pointersToFollow2,- showClosure+ parseClosure,+ showClosureFields ) where @@ -21,96 +18,80 @@ #endif import GHC.Vis.Types-import GHC.HeapView hiding (name, pkg, modl, fun, arrWords) +import GHC.HeapView hiding (pkg, modl, fun, arrWords)+ import Control.Monad import Control.Monad.State hiding (State, fix) import Data.Word import Data.Char import Data.List hiding (insert)+import qualified Data.IntMap as M import Text.Printf import Unsafe.Coerce -import Control.Monad.Trans.Maybe- import System.IO.Unsafe --- | Maximum depth which walkHeap recurses to. Prevents users from evaluating--- data structures which are too big and would take very long to visualize.-maxHeapWalkDepth :: Int-maxHeapWalkDepth = 100---- | Walk the heap for a list of objects to be visualized and their--- corresponding names.-parseBoxes :: [(Box, String)] -> IO [[VisObject]]-parseBoxes bs = do- r <- generalParseBoxes evalState bs- case r of- Just x -> return x- _ -> do- putStrLn "Failure, trying again"- parseBoxes bs+-- TODO: Remove+instance Eq Box where+ a == b = unsafePerformIO $ areBoxesEqual a b --- | Walk the heap for a list of objects to be visualized and their--- corresponding names. Also return the resulting 'HeapMap' and another--- 'HeapMap' that does not contain BCO pointers.-parseBoxesHeap :: [(Box, String)] -> IO ([[VisObject]], PState)-parseBoxesHeap bs = do- r <- generalParseBoxes runState bs- case r of- (Just x, y) -> return (x,y)- _ -> parseBoxesHeap bs+-- | Parse a closure to a list of VisObjects+parseClosure :: HeapGraphIndex -> PrintState [VisObject]+parseClosure i = do+ o <- correctObject i+ case o of+ Link n -> return [Link n] -- Don't build infinite heaps+ _ -> do HeapGraph m <- gets heapGraph+ l <- parseInternal i $ hgeClosure $ m M.! i+ return $ insertObjects o l -generalParseBoxes ::- (PrintState (Maybe [[VisObject]]) -> PState -> b)- -> [(Box, String)] -> IO b-generalParseBoxes f bs = do- h <- walkHeapSimply bs- h2 <- walkHeapWithBCO bs- return $ f (g bs) $ PState 0 0 0 h h2- where g bs' = runMaybeT $ go bs'- go ((b',_):b's) = do h <- lift $ gets heapMap'- (_,c) <- lookupT b' h- r <- parseClosure b' c- rs <- go b's- return $ simplify r : rs- go [] = return []+correctObject :: HeapGraphIndex -> PrintState VisObject+correctObject i = do+ name <- getName i+ bindings <- gets bindings -lookupT :: Eq a => a -> [(a,b)] -> MaybeT PrintState b-lookupT b' h = MaybeT $ return $ lookup b' h+ if null name+ then if i `elem` bindings then+ (do name' <- setName i+ return $ Named name' [])+ else return $ Unnamed ""+ else return $ Link name --- Pulls together multiple Unnamed objects to one-simplify :: [VisObject] -> [VisObject]-simplify [] = []-simplify [Named a bs] = [Named a $ simplify bs]-simplify [a] = [a]-simplify (Unnamed a : Unnamed b : xs) = simplify $ Unnamed (a ++ b) : xs-simplify (Named a bs : xs) = Named a (simplify bs) : simplify xs-simplify (a:xs) = a : simplify xs+setName :: HeapGraphIndex -> PrintState String+setName i = do+ n <- getName i+ if null n+ then do+ s@(PState ti fi xi _ (HeapGraph m)) <- get+ let Just hge@(HeapGraphEntry{hgeClosure = c}) = M.lookup i m+ let (name,newState) = case bindingLetter c of+ 't' -> ('t' : show ti, s{tCounter' = ti + 1})+ 'f' -> ('f' : show fi, s{fCounter' = fi + 1})+ 'x' -> ('x' : show xi, s{xCounter' = xi + 1})+ _ -> error "Invalid letter" -parseClosure :: Box -> Closure -> MaybeT PrintState [VisObject]-parseClosure b c = do- o <- correctObject b- case o of- Link n -> return [Link n] -- Don't build infinite heaps- _ -> do i <- parseInternal b c- return $ insertObjects o i+ let m' = M.insert i (hge{hgeData = name}) m+ put $ newState{heapGraph = HeapGraph m'}+ return name+ else return n -correctObject :: Box -> MaybeT PrintState VisObject-correctObject box = do- r <- lift $ countReferences box- n <- getName box+ where+ bindingLetter c = case c of+ ThunkClosure {..} -> 't'+ SelectorClosure {..} -> 't'+ APClosure {..} -> 't'+ PAPClosure {..} -> 'f'+ BCOClosure {..} -> 't'+ FunClosure {..} -> 'f'+ _ -> 'x' - case n of- Just name -> return $ Link name- Nothing -> if r > 1 then- (do setName box- mbName <- getName box- name <- MaybeT $ return mbName- return $ Named name [])- else return $ Unnamed ""+getName :: HeapGraphIndex -> PrintState String+getName i = do+ HeapGraph m <- gets heapGraph+ return $ hgeData $ m M.! i insertObjects :: VisObject -> [VisObject] -> [VisObject] insertObjects _ xs@(Function _ : _) = xs@@ -120,144 +101,7 @@ insertObjects (Unnamed _) xs = xs insertObjects _ _ = error "unexpected arguments" --- | Recursively walk down the heap objects and return the resulting map. This--- function recognizes loops and avoids them. Big data structures might still--- be very slow.-walkHeap :: [(Box, String)] -> IO HeapMap-walkHeap = walkHeapGeneral Just pointersToFollow---- | walkHeap, but without Top level names-walkHeapSimply :: [(Box, String)] -> IO HeapMap-walkHeapSimply = walkHeapGeneral (const Nothing) pointersToFollow--walkHeapWithBCO :: [(Box, String)] -> IO HeapMap-walkHeapWithBCO = walkHeapGeneral (const Nothing) pointersToFollow2--walkHeapGeneral :: (String -> Maybe String) -> (Closure -> IO [Box]) -> [(Box, String)] -> IO HeapMap-walkHeapGeneral topF p2fF bs = foldM (topNodes topF) [dummy] bs >>= \s -> foldM (startWalk p2fF) s bs- where topNodes hn l (b,n) = do -- Adds the top nodes without looking at their pointers- c' <- getBoxedClosureData b- return $ insert (b, (hn n, c')) l- startWalk p2f l (b,_) = do -- Ignores that the top nodes are already in the heap map- c' <- getBoxedClosureData b- p <- p2f c'- foldM (step maxHeapWalkDepth p2f) l p- step depth p2f l b = case lookup b l of- Just _ -> return l- Nothing -> do- c' <- getBoxedClosureData b- p <- p2f c'- if depth == 0 && not (null p)- then do- putStrLn "Warning: Maximum data structure depth reached, output is truncated"- return $ insert (b, (Nothing, maxDepthClosure)) l- else foldM (step (depth - 1) p2f) (insert (b, (Nothing, c')) l) p- dummy = (asBox (1 :: Integer),- (Nothing, ConsClosure (StgInfoTable 0 0 CONSTR 0) (map fst bs) [] "" "" ""))- maxDepthClosure = ConsClosure (StgInfoTable 0 0 CONSTR 0) [] [] "" "" "..."---- We're not inspecting the BCOs and instead later looks which of its recursive--- children are still in the heap. Only those should be visualized.-pointersToFollow :: Closure -> IO [Box]-pointersToFollow BCOClosure{} = return []--pointersToFollow (MutArrClosure _ _ _ bPtrs) =- do cPtrs <- mapM getBoxedClosureData bPtrs- return $ fix $ zip bPtrs cPtrs- where fix ((_,ConsClosure _ _ _ _ "ByteCodeInstr" "BreakInfo"):_:_:xs) = fix xs- fix ((_,ConsClosure _ _ _ _ "ByteCodeInstr" "BreakInfo"):_:xs) = fix xs- fix ((_,ConsClosure _ _ _ _ "ByteCodeInstr" "BreakInfo"):xs) = fix xs- fix ((x,_):xs) = x : fix xs- fix [] = []--pointersToFollow x = return $ allPtrs x---- | Follows 'GHC.HeapView.BCOClosure's, but not the debugging data structures--- (ByteCodeInstr.BreakInfo) of GHC.-pointersToFollow2 :: Closure -> IO [Box]-pointersToFollow2 (MutArrClosure _ _ _ bPtrs) =- do cPtrs <- mapM getBoxedClosureData bPtrs- return $ fix $ zip bPtrs cPtrs- where fix ((_,ConsClosure _ _ _ _ "ByteCodeInstr" "BreakInfo"):_:_:xs) = fix xs- fix ((_,ConsClosure _ _ _ _ "ByteCodeInstr" "BreakInfo"):_:xs) = fix xs- fix ((_,ConsClosure _ _ _ _ "ByteCodeInstr" "BreakInfo"):xs) = fix xs- fix ((x,_):xs) = x : fix xs- fix [] = []--pointersToFollow2 x = return $ allPtrs x---- walkHeap, but with a maximum depth---walkHeapDepth :: [(Box, String)] -> IO HeapMap---walkHeapDepth bs = foldM topNodes [dummy bs] bs >>= \s -> foldM goStart s bs--- where topNodes l (b,n) = do -- Adds the top nodes without looking at their pointers--- c' <- getBoxedClosureData b--- return $ insert (b, (Just n, c')) l--- goStart l (b,_) = do -- Ignores that the top nodes are already in the heap map--- c' <- getBoxedClosureData b--- p <- pointersToFollow c'--- foldM (\l b -> go l b 30) l p--- go l _ 0 = return l--- go l b x = case lookup b l of--- Just _ -> return l--- Nothing -> do--- c' <- getBoxedClosureData b--- p <- pointersToFollow c'--- foldM (\l b -> go l b (x-1)) (insert (b, (Nothing, c')) l) p---- Additional map operations-insert :: (Box, HeapEntry) -> HeapMap -> HeapMap-insert (b,x) xs = case find (\(c,_) -> c == b) xs of- Just _ -> xs- Nothing -> (b,x):xs--adjust :: (HeapEntry -> HeapEntry) -> Box -> HeapMap -> Maybe HeapMap-adjust f b h = do i <- findIndex (\(y,_) -> y == b) h- let (h1,(_,x):h2) = splitAt i h- return $ h1 ++ ((b,f x) : h2)--setName :: Box -> MaybeT PrintState ()-setName b = do PState ti fi bi h h2 <- lift get- (_,c) <- lookupT b h2- let (n, ti',fi',bi') = case c of- ThunkClosure{} -> ('t' : show ti, ti+1, fi, bi)- APClosure{} -> ('t' : show ti, ti+1, fi, bi)- FunClosure{} -> ('f' : show fi, ti, fi+1, bi)- PAPClosure{} -> ('f' : show fi, ti, fi+1, bi)- _ -> ('b' : show bi, ti, fi, bi+1)- set (Nothing, closure) = (Just n, closure)- set _ = error "unexpected pattern"- h' <- MaybeT $ return $ adjust set b h- h2' <- MaybeT $ return $ adjust set b h2- lift $ put $ PState ti' fi' bi' h' h2'--setVisited :: Box -> MaybeT PrintState ()-setVisited b = do PState ti fi bi h h2 <- lift get- let set (Nothing, closure) = (Just "visited", closure)- set _ = error "unexpected pattern"- h2' <- MaybeT $ return $ adjust set b h2- lift $ put $ PState ti fi bi h h2'--getName :: Box -> MaybeT PrintState (Maybe String)-getName b = do h <- lift $ gets heapMap'- (name,_) <- lookupT b h- return name--getSetName :: Box -> MaybeT PrintState String-getSetName b = do mn <- getName b- case mn of- Nothing -> do setName b- name <- getName b- MaybeT $ return name- Just name -> return name---- How often is a box referenced in the entire heap map-countReferences :: Box -> PrintState Int-countReferences b = do- h <- gets heapMap'- return $ sum $ map countR h- where countR (_,(_,c)) = length $ filter (== b) $ allPtrs c--parseInternal :: Box -> Closure -> MaybeT PrintState [VisObject]+parseInternal :: HeapGraphIndex -> GenClosure (Maybe HeapGraphIndex) -> PrintState [VisObject] parseInternal _ (ConsClosure _ [] [dataArg] _pkg modl name) = return [Unnamed $ case (modl, name) of k | k `elem` [ ("GHC.Word", "W#")@@ -284,8 +128,6 @@ _ -> printf "%s %d" (infixFix name) dataArg ] --- Empty ByteStrings point to a nullForeignPtr, evaluating it leads to an--- Prelude.undefined exception parseInternal _ (ConsClosure (StgInfoTable 1 3 _ _) _ [_,0,0] _ "Data.ByteString.Internal" "PS") = return [Unnamed "ByteString 0 0"] @@ -332,15 +174,15 @@ -- Reversed order of ptrs parseInternal b (ThunkClosure _ bPtrs args) = do- name <- getSetName b+ name <- setName b cPtrs <- mapM contParse $ reverse bPtrs let tPtrs = intercalate [Unnamed ","] cPtrs sPtrs = if null tPtrs then [Unnamed ""] else Unnamed "(" : tPtrs ++ [Unnamed ")"] sArgs = Unnamed $ if null args then "" else show args return $ Thunk (infixFix name) : sPtrs ++ [sArgs] -parseInternal b (FunClosure _ bPtrs args) = do- name <- getSetName b+parseInternal i (FunClosure _ bPtrs args) = do+ name <- setName i cPtrs <- mapM contParse $ reverse bPtrs let tPtrs = intercalate [Unnamed ","] cPtrs sPtrs = if null tPtrs then [Unnamed ""] else Unnamed "(" : tPtrs ++ [Unnamed ")"]@@ -349,7 +191,8 @@ -- bPtrs here can currently point to Nothing, because else we might get infinite heaps parseInternal _ (MutArrClosure _ _ _ bPtrs)- = do cPtrs <- mutArrContParse bPtrs+ -- = do cPtrs <- mutArrContParse2 bPtrs+ = do cPtrs <- mapM contParse bPtrs let tPtrs = intercalate [Unnamed ","] cPtrs return $ if null tPtrs then [Unnamed ""] else Unnamed "(" : tPtrs ++ [Unnamed ")"] @@ -357,45 +200,30 @@ = do c <- contParse b return $ Unnamed "MutVar " : c -parseInternal b (BCOClosure _ _ _ bPtr _ _ _)- = do cPtrs <- bcoContParse [bPtr]+parseInternal _ (BCOClosure _ _ _ bPtr _ _ _)+ -- = do cPtrs <- bcoContParse2 [bPtr]+ = do cPtrs <- mapM contParse [bPtr] let tPtrs = intercalate [Unnamed ","] cPtrs- r <- lift $ countReferences b- return $ if null tPtrs then if r > 1 then [Unnamed "BCO"] else [Unnamed ""] else (if r > 1 then Unnamed "BCO(" else Unnamed "(") : tPtrs ++ [Unnamed ")"]- -- = do case lookup b h of- -- Nothing -> c <- getBoxedClosureData bPtr- -- Just (_,c) -> p <- parseClosure bPtr c- -- = do vs <- contParse bPtr- -- let ls = filter isExternal $ filter isLink vs-- -- isLink (Link _) = True- -- isLink _ = False-- -- isExternal (Link n) = all (notHasName n) vs-- -- notHasName n (Named m _) = n /= m- -- notHasName n (Function m) = n /= m- -- notHasName _ _ = True- -- return vs+ return $ Unnamed "BCO" : tPtrs -parseInternal b (APClosure _ _ _ fun pl) = do- name <- getSetName b+parseInternal i (APClosure _ _ _ fun pl) = do+ name <- setName i fPtr <- contParse fun pPtrs <- mapM contParse $ reverse pl let tPtrs = intercalate [Unnamed ","] pPtrs sPtrs = if null tPtrs then [Unnamed ""] else Unnamed "[" : tPtrs ++ [Unnamed "]"] return $ Thunk (infixFix name) : fPtr ++ sPtrs -parseInternal b (PAPClosure _ _ _ fun pl) = do- name <- getSetName b+parseInternal i (PAPClosure _ _ _ fun pl) = do+ name <- setName i fPtr <- contParse fun pPtrs <- mapM contParse $ reverse pl let tPtrs = intercalate [Unnamed ","] pPtrs sPtrs = if null tPtrs then [Unnamed ""] else Unnamed "[" : tPtrs ++ [Unnamed "]"] return $ Function (infixFix name) : fPtr ++ sPtrs -parseInternal b (APStackClosure _ fun pl) = do- name <- getSetName b+parseInternal i (APStackClosure _ fun pl) = do+ name <- setName i fPtr <- contParse fun pPtrs <- mapM contParse $ reverse pl let tPtrs = intercalate [Unnamed ","] pPtrs@@ -408,10 +236,9 @@ cValue <- liftM mbParens $ contParse qValue return $ Unnamed "MVar#(" : cHead ++ [Unnamed ","] ++ cTail ++ [Unnamed ","] ++ cValue ++ [Unnamed ")"] -contParse :: Box -> MaybeT PrintState [VisObject]-contParse b = do h <- lift $ gets heapMap- (_,c) <- lookupT b h- parseClosure b c+contParse :: Maybe HeapGraphIndex -> PrintState [VisObject]+contParse Nothing = return []+contParse (Just i) = parseClosure i -- It turned out that bcoContParse actually does go into an infinite loop, for -- example for this:@@ -420,28 +247,28 @@ -- :view foldr' -- We fix this by giving visited closures a dummy name, so we recognize when we -- get into a loop.-bcoContParse :: [Box] -> MaybeT PrintState [[VisObject]]-bcoContParse [] = return []-bcoContParse (b:bs) = gets heapMap >>= \h -> case lookup b h of- Nothing -> do let ptf = unsafePerformIO $ getBoxedClosureData b >>= pointersToFollow2- r <- lift $ countReferences b- n <- getName b- case n of- Just _ -> bcoContParse bs- Nothing -> do- when (r > 1) $ setVisited b- bcoContParse $ ptf ++ bs- Just (_,c) -> do p <- parseClosure b c- ps <- bcoContParse bs- return $ p : ps+--bcoContParse :: [Box] -> MaybeT PrintState [[VisObject]]+--bcoContParse [] = return []+--bcoContParse (b:bs) = gets heapMap >>= \h -> case lookup b h of+-- Nothing -> do let ptf = unsafePerformIO $ getBoxedClosureData b >>= pointersToFollow2+-- r <- lift $ countReferences b+-- n <- getName b+-- case n of+-- Just _ -> bcoContParse bs+-- Nothing -> do+-- when (r > 1) $ setVisited b+-- bcoContParse $ ptf ++ bs+-- Just (_,c) -> do p <- parseClosure b c+-- ps <- bcoContParse bs+-- return $ p : ps -mutArrContParse :: [Box] -> MaybeT PrintState [[VisObject]]-mutArrContParse [] = return []-mutArrContParse (b:bs) = gets heapMap >>= \h -> case lookup b h of- Nothing -> mutArrContParse bs- Just (_,c) -> do p <- parseClosure b c- ps <- mutArrContParse bs- return $ p : ps+--mutArrContParse :: [Box] -> MaybeT PrintState [[VisObject]]+--mutArrContParse [] = return []+--mutArrContParse (b:bs) = gets heapMap >>= \h -> case lookup b h of+-- Nothing -> mutArrContParse bs+-- Just (_,c) -> do p <- parseClosure b c+-- ps <- mutArrContParse bs+-- return $ p : ps -- TODO: Doesn't work quite right, for example with (1,"fo") mbParens :: [VisObject] -> [VisObject]@@ -463,16 +290,19 @@ -- go (Named _ os) = any go os -- go _ = False +--showClosure :: Closure -> String+--showClosure = unwords . showClosureFields+ -- | Textual representation of Heap objects, used in the graph visualization.-showClosure :: Closure -> String-showClosure (ConsClosure _ _ [dataArg] _ modl name) =+showClosureFields :: GenClosure t -> [String]+showClosureFields (ConsClosure _ _ [dataArg] _ modl name) = case (modl, name) of k | k `elem` [ ("GHC.Word", "W#") , ("GHC.Word", "W8#") , ("GHC.Word", "W16#") , ("GHC.Word", "W32#") , ("GHC.Word", "W64#")- ] -> name ++ " " ++ show dataArg+ ] -> [name, show dataArg] k | k `elem` [ ("GHC.Integer.Type", "S#") , ("GHC.Types", "I#")@@ -480,80 +310,80 @@ , ("GHC.Int", "I16#") , ("GHC.Int", "I32#") , ("GHC.Int", "I64#")- ] -> name ++ " " ++ show ((fromIntegral :: Word -> Int) dataArg)+ ] -> [name, show ((fromIntegral :: Word -> Int) dataArg)] - ("GHC.Types", "C#") -> show . chr $ fromIntegral dataArg+ ("GHC.Types", "C#") -> ["C#", [chr $ fromIntegral dataArg]] - ("GHC.Types", "D#") -> printf "D# %0.5f" (unsafeCoerce dataArg :: Double)- ("GHC.Types", "F#") -> printf "F# %0.5f" (unsafeCoerce dataArg :: Double)+ ("GHC.Types", "D#") -> ["D#", printf "%0.5f" (unsafeCoerce dataArg :: Double)]+ ("GHC.Types", "F#") -> ["F#", printf "%0.5f" (unsafeCoerce dataArg :: Double)] -- :m +GHC.Arr -- let b = array ((1,1),(3,2)) [((1,1),42),((1,2),23),((2,1),999),((2,2),1000),((3,1),1001),((3,2),1002)] -- b -- :view b- _ -> printf "%s %d" name dataArg+ _ -> [name, show dataArg] -showClosure (ConsClosure (StgInfoTable 1 3 _ 0) _ [_,0,0] _ "Data.ByteString.Internal" "PS")- = "ByteString 0 0"+showClosureFields (ConsClosure (StgInfoTable 1 3 _ 0) _ [_,0,0] _ "Data.ByteString.Internal" "PS")+ = ["ByteString","0","0"] -showClosure (ConsClosure (StgInfoTable 1 3 _ 0) [_] [_,start,end] _ "Data.ByteString.Internal" "PS")- = printf "ByteString %d %d" start end+showClosureFields (ConsClosure (StgInfoTable 1 3 _ 0) [_] [_,start,end] _ "Data.ByteString.Internal" "PS")+ = ["ByteString",printf "%d" start,printf "%d" end] -showClosure (ConsClosure (StgInfoTable 2 3 _ 1) [_,_] [_,start,end] _ "Data.ByteString.Lazy.Internal" "Chunk")- = printf "Chunk %d %d" start end+showClosureFields (ConsClosure (StgInfoTable 2 3 _ 1) [_,_] [_,start,end] _ "Data.ByteString.Lazy.Internal" "Chunk")+ = ["Chunk",printf "%d" start,printf "%d" end] -showClosure (ConsClosure _ _ dArgs _ _ name)- = unwords $ name : map show dArgs+showClosureFields (ConsClosure _ _ dArgs _ _ name)+ = name : map show dArgs -- Reversed order of ptrs-showClosure ThunkClosure{}- = "Thunk"+showClosureFields ThunkClosure{}+ = ["Thunk"] -showClosure SelectorClosure{}- = "Selector"+showClosureFields SelectorClosure{}+ = ["Selector"] -- Probably should delete these from Graph-showClosure IndClosure{}- = "Ind"+showClosureFields IndClosure{}+ = ["Ind"] -showClosure BlackholeClosure{}- = "Blackhole"+showClosureFields BlackholeClosure{}+ = ["Blackhole"] -showClosure APClosure{}- = "AP"+showClosureFields APClosure{}+ = ["AP"] -showClosure PAPClosure{}- = "PAP"+showClosureFields PAPClosure{}+ = ["PAP"] -showClosure APStackClosure{}- = "APStack"+showClosureFields APStackClosure{}+ = ["APStack"] -showClosure BCOClosure{}- = "BCO"+showClosureFields BCOClosure{}+ = ["BCO"] -showClosure (ArrWordsClosure _ _ arrWords)- = intercalate ",\n" $ map (printf "0x%x") arrWords+showClosureFields (ArrWordsClosure _ _ arrWords)+ = map (printf "0x%x") arrWords -showClosure MutArrClosure{}- = "MutArr"+showClosureFields MutArrClosure{}+ = ["MutArr"] -showClosure MutVarClosure{}- = "MutVar"+showClosureFields MutVarClosure{}+ = ["MutVar"] -showClosure MVarClosure{}- = "MVar#"+showClosureFields MVarClosure{}+ = ["MVar#"] -showClosure FunClosure{}- = "Fun"+showClosureFields FunClosure{}+ = ["Fun"] -showClosure BlockingQueueClosure{}- = "BlockingQueue"+showClosureFields BlockingQueueClosure{}+ = ["BlockingQueue"] -showClosure (OtherClosure (StgInfoTable _ _ cTipe _) _ _)- = show cTipe+showClosureFields (OtherClosure (StgInfoTable _ _ cTipe _) _ _)+ = [show cTipe] -showClosure (UnsupportedClosure (StgInfoTable _ _ cTipe _))- = show cTipe+showClosureFields (UnsupportedClosure (StgInfoTable _ _ cTipe _))+ = [show cTipe] --showClosure c = "Missing pattern for " ++ show c
src/GHC/Vis/Types.hs view
@@ -13,8 +13,8 @@ View(..), ViewType(..), State(..),- HeapEntry,- HeapMap,+ Identifier,+ NamedBox, PState(..), PrintState, VisObject(..)@@ -36,9 +36,12 @@ -- | Signals that are sent to the GUI to signal changes data Signal = NewSignal Box String -- ^ Add a new Box to be visualized- | UpdateSignal -- ^ Redraw+ | UpdateSignal -- ^ Update the view+ | RedrawSignal -- ^ Redraw | ClearSignal -- ^ Remove all Boxes+ | RestoreSignal -- ^ Reset all hidden boxes | SwitchSignal -- ^ Switch to alternative view+ | HistorySignal (Int -> Int) -- ^ Change position in history | ExportSignal DrawFunction String -- ^ Export the view to a file -- | All functions a view has to provide@@ -46,7 +49,7 @@ { redraw :: WidgetClass w => w -> IO () , click :: IO () , move :: WidgetClass w => w -> IO ()- , updateObjects :: [(Box, String)] -> IO ()+ , updateObjects :: [NamedBox] -> IO () , exportView :: DrawFunction -> String -> IO () } @@ -65,23 +68,19 @@ , wasDragged :: Bool -- ^ Whether the mouse was actually dragged } --- | An entry in a 'HeapMap', consisting of an identifier and a parsed GHC heap entry-type HeapEntry =- ( Maybe String- , Closure- )--- | A map of heap objects.--- We're using a slow, eq-based list instead of a proper map because--- StableNames' hash values aren't stable enough-type HeapMap = [(Box, HeapEntry)]+-- | Identifier of a closure+type Identifier = [String] --- | The second HeapMap includes BCO pointers, needed for list visualization+-- | A box and its identifier+type NamedBox = (Identifier, Box)++-- | Internal state of the list view generator data PState = PState- { tCounter :: Integer- , fCounter :: Integer- , bCounter :: Integer- , heapMap :: HeapMap- , heapMap' :: HeapMap+ { tCounter' :: Integer+ , fCounter' :: Integer+ , xCounter' :: Integer+ , bindings :: [HeapGraphIndex]+ , heapGraph :: HeapGraph String } -- | The state of a printing operation
src/GHC/Vis/View/Common.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP, ScopedTypeVariables #-}+{-# LANGUAGE CPP, ScopedTypeVariables, RecordWildCards #-} {- | Module : GHC.Vis.View.Common Copyright : (c) Dennis Felsing@@ -11,6 +11,12 @@ visRunning, visState, visBoxes,+ visHidden,+ visHeapHistory,+ getHeapGraph,+ inHistoryMode,+ parseBoxes,+ parseBoxesHeap, evaluate ) where@@ -23,8 +29,15 @@ import Control.DeepSeq import Control.Exception hiding (evaluate) +import Control.Monad.State hiding (State, fix)++import qualified Data.IntMap as M+ import Data.IORef +import Data.Maybe (catMaybes)+import Data.List+ import System.IO.Unsafe import GHC.Vis.Internal@@ -44,29 +57,75 @@ visState = unsafePerformIO $ newIORef $ State (0, 0) ListView 1 (0, 0) False False -- | All the visualized boxes-visBoxes :: MVar [(Box, String)]-visBoxes = unsafePerformIO (newMVar [] :: IO (MVar [(Box, String)]))+visBoxes :: MVar [NamedBox]+visBoxes = unsafePerformIO (newMVar [] :: IO (MVar [NamedBox])) +-- | Hidden boxes+visHidden :: MVar [Box]+visHidden = unsafePerformIO (newMVar [] :: IO (MVar [Box]))++-- | All heap graphs since the last clear command+visHeapHistory :: MVar (Int, [(HeapGraph Identifier, [(Identifier, HeapGraphIndex)])])+visHeapHistory = unsafePerformIO (newMVar (0, [(HeapGraph M.empty, [])]) :: IO (MVar (Int, [(HeapGraph Identifier, [(Identifier, HeapGraphIndex)])])))++-- | Get the currently selected heap graph+getHeapGraph :: IO (HeapGraph Identifier, [(Identifier, HeapGraphIndex)])+getHeapGraph = do+ (pos, xs) <- readMVar visHeapHistory+ return $ xs !! pos++-- | Whether we're currently looking at an older heap graph or the most recent one+inHistoryMode :: IO Bool+inHistoryMode = liftM ((> 0) . fst) $ readMVar visHeapHistory+ -- | Evaluate an object identified by a String. evaluate :: String -> IO ()-evaluate identifier = do (_,hm) <- printAll- (show (map go hm) `deepseq` return ()) `catch`+evaluate identifier = do (_,HeapGraph m) <- printAll+ (show (M.map go m) `deepseq` return ()) `catch` \(e :: SomeException) -> putStrLn $ "Caught exception while evaluating: " ++ show e- where go (Box a,(Just n, y)) | n == identifier = seq a (Just n, y)- | otherwise = (Just n, y)- go (_,(x,y)) = (x,y)+ where go hge@(HeapGraphEntry (Box a) _ _ n) | n == identifier = seq a hge+ | otherwise = hge ---printOne :: a -> IO String---printOne a = do--- bs <- readMVar visBoxes--- case findIndex (\(b,_) -> asBox a == b) bs of--- Just pos -> do--- t <- parseBoxes bs--- return $ show (t !! pos)--- Nothing -> return "Add entry first"+-- | Walk the heap for a list of objects to be visualized and their+-- corresponding names.+parseBoxes :: IO [[VisObject]]+parseBoxes = generalParseBoxes evalState -printAll :: IO (String, HeapMap)+-- | Walk the heap for a list of objects to be visualized and their+-- corresponding names. Also return the resulting 'HeapMap' and another+-- 'HeapMap' that does not contain BCO pointers.+parseBoxesHeap :: IO ([[VisObject]], PState)+parseBoxesHeap = generalParseBoxes runState++--generalParseBoxes ::+-- (PrintState (Maybe [[VisObject]]) -> PState -> b)+-- -> [NamedBox] -> IO b+generalParseBoxes :: (PrintState [[VisObject]] -> PState -> b) -> IO b+generalParseBoxes f = do+ --(hg, starts) <- multiBuildHeapGraph 100 $ map (\(_,x) -> ("",x)) bs+ (hg@(HeapGraph m), starts) <- getHeapGraph+ let bindings = boundMultipleTimes hg $ map snd starts+ let g i = do+ r <- parseClosure i+ return $ simplify r+ return $ f (mapM (g . snd) starts) $ PState 1 1 1 bindings $ HeapGraph $ M.map (\hge -> hge{hgeData = ""}) m++-- | In the given HeapMap, list all indices that are used more than once. The+-- second parameter adds external references, commonly @[heapGraphRoot]@.+boundMultipleTimes :: HeapGraph a -> [HeapGraphIndex] -> [HeapGraphIndex]+boundMultipleTimes (HeapGraph m) roots = map head $ filter (not.null) $ map tail $ group $ sort $+ roots ++ concatMap (catMaybes . allPtrs . hgeClosure) (M.elems m)++-- Pulls together multiple Unnamed objects to one+simplify :: [VisObject] -> [VisObject]+simplify [] = []+simplify [Named a bs] = [Named a $ simplify bs]+simplify [a] = [a]+simplify (Unnamed a : Unnamed b : xs) = simplify $ Unnamed (a ++ b) : xs+simplify (Named a bs : xs) = Named a (simplify bs) : simplify xs+simplify (a:xs) = a : simplify xs++printAll :: IO (String, HeapGraph String) printAll = do- bs <- readMVar visBoxes- (t, PState{heapMap = h}) <- parseBoxesHeap bs+ (t, PState{heapGraph = h}) <- parseBoxesHeap return (show t, h)
src/GHC/Vis/View/Graph.hs view
@@ -27,6 +27,7 @@ import Control.Monad import Control.Exception +import Data.Maybe import Data.IORef import System.IO.Unsafe @@ -39,17 +40,44 @@ import Graphics.XDot.Viewer import Graphics.XDot.Types hiding (size, w, h) +import Graphics.Rendering.Cairo.SVG+import Paths_ghc_vis as My++hoverIconWidth :: Double+hoverIconWidth = 35++hoverIconHeight :: Double+hoverIconHeight = 17.5++hoverIconSpace :: Double+hoverIconSpace = 5++data Icon = EvaluateIcon+ | CollapseIcon+ deriving (Show, Eq)+ data State = State { boxes :: [Box] , operations :: [(Object Int, Operation)]- , totalSize :: (Double, Double, Double, Double)- , bounds :: [(Object Int, (Double, Double, Double, Double))]+ , totalSize :: Rectangle+ , bounds :: [(Object Int, Rectangle)]+ , hoverIconBounds :: [(Object Int, [(Icon, Rectangle)])] , hover :: Object Int+ , iconHover :: Maybe (Object Int, Icon) } state :: IORef State-state = unsafePerformIO $ newIORef $ State [] [] (0, 0, 1, 1) [] None+state = unsafePerformIO $ newIORef $ State [] [] (0, 0, 1, 1) [] [] None Nothing +iconEvaluateSVG :: SVG+iconEvaluateSVG = unsafePerformIO $ My.getDataFileName "data/icon_evaluate.svg" >>= svgNewFromFile+iconCollapseSVG :: SVG+iconCollapseSVG = unsafePerformIO $ My.getDataFileName "data/icon_collapse.svg" >>= svgNewFromFile+hoverEvaluateSVG :: SVG+hoverEvaluateSVG = unsafePerformIO $ My.getDataFileName "data/hover_evaluate.svg" >>= svgNewFromFile+hoverCollapseSVG :: SVG+hoverCollapseSVG = unsafePerformIO $ My.getDataFileName "data/hover_collapse.svg" >>= svgNewFromFile+ -- | Draw visualization to screen, called on every update or when it's -- requested from outside the program. redraw :: WidgetClass w => w -> IO ()@@ -57,9 +85,9 @@ s <- readIORef state Gtk.Rectangle _ _ rw2 rh2 <- widgetGetAllocation canvas - boundingBoxes <- render canvas (draw s rw2 rh2)+ (bbs, hibbs) <- render canvas (draw s rw2 rh2) - modifyIORef state (\s' -> s' {bounds = boundingBoxes})+ modifyIORef state (\s' -> s' {bounds = bbs, hoverIconBounds = hibbs}) -- | Export the visualization to an SVG file export :: DrawFunction -> String -> IO ()@@ -73,55 +101,98 @@ return () -draw :: State -> Int -> Int -> Render [(Object Int, Rectangle)]+draw :: State -> Int -> Int -> Render ([(Object Int, Rectangle)], [(Object Int, [(Icon, Rectangle)])]) draw s rw2 rh2 = do- vS <- liftIO $ readIORef visState+ if null $ boxes s then return ([], [])+ else do+ vS <- liftIO $ readIORef visState - -- Line widths don't count to size, let's add a bit- let rw = 0.97 * fromIntegral rw2- rh = 0.97 * fromIntegral rh2+ -- Line widths don't count to size, let's add a bit+ let rw = 0.97 * fromIntegral rw2+ rh = 0.97 * fromIntegral rh2 - ops = operations s- size@(_,_,sw,sh) = totalSize s+ ops = operations s+ size@(_,_,sw,sh) = totalSize s - -- Proportional scaling- (sx,sy) = (zoomRatio vS * min (rw / sw) (rh / sh), sx)- (ox1,oy1) = (0.5 * fromIntegral rw2, 0.5 * fromIntegral rh2)- (ox2,oy2) = position vS- (ox,oy) = (ox1 + ox2, oy1 + oy2)+ -- Proportional scaling+ (sx,sy) = (min 1000 $ zoomRatio vS * min (rw / sw) (rh / sh), sx)+ (ox1,oy1) = (0.5 * fromIntegral rw2, 0.5 * fromIntegral rh2)+ (ox2,oy2) = position vS+ (ox,oy) = (ox1 + ox2, oy1 + oy2) - translate ox oy- scale sx sy+ translate ox oy+ scale sx sy - result <- drawAll (hover s) size ops+ result <- drawAll (hover s) size ops - return $ map (\(o, (x,y,w,h)) -> (o,- ( x * sx + ox -- Transformations to correct scaling and offset- , y * sy + oy- , w * sx- , h * sy- ))) result+ case hover s of+ Node n -> do+ let Just (x,y,w,_h) = lookup (Node n) result + translate (x + w + hoverIconSpace) y+ drawHoverMenu $ iconHover s+ _ -> return True++ let trafo (o, (x,y,w,h)) = (o,+ ( x * sx + ox -- Transformations to correct scaling and offset+ , y * sy + oy+ , w * sx+ , h * sy+ ))++ let toHoverIconBounds (o, (x,y,w,_h)) = (o, map trafo+ [ (EvaluateIcon, (x+w, y, hoverIconWidth + hoverIconSpace, hoverIconHeight))+ , (CollapseIcon, (x+w, y+hoverIconHeight, hoverIconWidth + hoverIconSpace, hoverIconHeight))+ ])++ return (map trafo result, map toHoverIconBounds result)+ render :: WidgetClass w => w -> Render b -> IO b render canvas r = do win <- widgetGetDrawWindow canvas renderWithDrawable win r +drawHoverMenu :: Maybe (t, Icon) -> Render Bool+drawHoverMenu x = do+ svgRender $ case x of+ Just (_, EvaluateIcon) -> hoverEvaluateSVG+ _ -> iconEvaluateSVG++ translate 0 hoverIconHeight++ svgRender $ case x of+ Just (_, CollapseIcon) -> hoverCollapseSVG+ _ -> iconCollapseSVG+ -- | Handle a mouse click. If an object was clicked an 'UpdateSignal' is sent -- that causes the object to be evaluated and the screen to be updated. click :: IO () click = do s <- readIORef state - case hover s of- -- This might fail when a click occurs during an update- Node t -> unless (length (boxes s) <= t) $ do- evaluate2 $ boxes s !! t- -- Without forkIO it would hang indefinitely if some action is currently- -- executed- void $ forkIO $ putMVar visSignal UpdateSignal+ hm <- inHistoryMode+ when (not hm) $ case iconHover s of+ Nothing -> case hover s of+ -- This might fail when a click occurs during an update+ Node t -> evaluateClick s t+ _ -> return ()++ Just (Node t, EvaluateIcon) -> evaluateClick s t+ Just (Node t, CollapseIcon) -> collapseClick s t _ -> return () +evaluateClick :: State -> Int -> IO ()+evaluateClick s t = unless (length (boxes s) <= t) $ do+ evaluate2 $ boxes s !! t+ -- Without forkIO it would hang indefinitely if some action is currently+ -- executed+ void $ forkIO $ putMVar visSignal UpdateSignal++collapseClick :: State -> Int -> IO ()+collapseClick s t = unless (length (boxes s) <= t) $ do+ hide $ boxes s !! t+ void $ forkIO $ putMVar visSignal RedrawSignal+ evaluate2 :: Box -> IO () evaluate2 b@(Box a) = do c <- getBoxedClosureData b@@ -143,6 +214,9 @@ `catch` \(e :: SomeException) -> putStrLn $ "Caught exception while evaluating: " ++ show e +hide :: Box -> IO ()+hide b = modifyMVar_ visHidden (\hs -> return $ b : hs)+ -- | Handle a mouse move. Causes an 'UpdateSignal' if the mouse is hovering a -- different object now, so the object gets highlighted and the screen -- updated.@@ -152,23 +226,45 @@ oldS <- readIORef state let oldHover = hover oldS - modifyIORef state $ \s' -> (- let (mx, my) = mousePos vs- check (o, (x,y,w,h)) =- if x <= mx && mx <= x + w &&- y <= my && my <= y + h- then o else None+ (mx, my) = mousePos vs - validOne (None:xs) = validOne xs- validOne (x:_) = x- validOne _ = None- in s' {hover = validOne $ map check (bounds oldS)}- )- s <- readIORef state- unless (oldHover == hover s) $ widgetQueueDraw canvas+ check (o, (x,y,w,h)) =+ if x <= mx && mx <= x + w &&+ y <= my && my <= y + h+ then o else None + check2 (o, (x,y,w,h)) =+ if x <= mx && mx <= x + w &&+ y <= my && my <= y + h+ then Just o else Nothing++ validOne (None:xs) = validOne xs+ validOne (x:_) = x+ validOne _ = None++ validOne2 (Nothing:xs) = validOne2 xs+ validOne2 (Just x:_) = Just x+ validOne2 _ = Nothing++ let iconHov = case oldHover of+ Node n -> validOne2 $ map check2 $ fromJust $ lookup (Node n) $ hoverIconBounds oldS+ _ -> Nothing++ case iconHov of+ Just i -> do+ let ih = Just (oldHover, i)+ modifyIORef state $ \s' -> s' {iconHover = ih}+ unless (iconHover oldS == ih) $ widgetQueueDraw canvas++ Nothing -> do+ let h = validOne $ map check $ bounds oldS+ modifyIORef state $ \s' -> s' {hover = h, iconHover = Nothing}+ unless (oldHover == h && iconHover oldS == Nothing) $ widgetQueueDraw canvas+ -- | Something might have changed on the heap, update the view.-updateObjects :: [(Box, String)] -> IO ()-updateObjects bs = do- (ops, bs', size) <- xDotParse bs+updateObjects :: [NamedBox] -> IO ()+updateObjects _boxes = do+ hidden <- readMVar visHidden+ (ops, bs', _ , size) <- xDotParse $ hidden+ modifyIORef state (\s -> s {operations = ops, boxes = bs', totalSize = size, hover = None})
src/GHC/Vis/View/Graph/Parser.hs view
@@ -12,21 +12,24 @@ ) where -import Data.List+import Data.Monoid -import Control.Monad+import qualified Data.Foldable as F+import qualified Data.IntMap as M+import qualified Data.IntSet as S import qualified Data.Text.Lazy as B -import Data.Graph.Inductive hiding (nodes, edges)+import Data.Graph.Inductive hiding (edges, newNodes) -import Data.GraphViz hiding (Ellipse, Polygon, parse)+import Data.GraphViz hiding (toNode, Ellipse, Polygon, parse) import Data.GraphViz.Attributes.Complete import Data.GraphViz.Commands.IO import GHC.HeapView hiding (name)-import GHC.Vis.Internal+import GHC.Vis.Internal (showClosureFields) import GHC.Vis.Types+import GHC.Vis.View.Common import Graphics.XDot.Types hiding (name, h, Style, Color) import Graphics.XDot.Parser@@ -45,87 +48,122 @@ edgeFontSize :: Double edgeFontSize = 24 -foldlMaybe :: (a -> b -> Maybe a) -> a -> [b] -> Maybe a-foldlMaybe f a bs =- foldr (\b g x -> f x b >>= g) Just bs a+graphvizCommand :: GraphvizCommand+graphvizCommand = Dot --- | Take the objects to be visualized and run them through @dot@ and extract--- the drawing operations that have to be exectued to show the graph of the--- heap map.-xDotParse :: [(Box, String)] -> IO ([(Object Node, Operation)], [Box], Rectangle)-xDotParse as = do- hm <- walkHeap as+-- | A generic algorithm to restrict a graph to the subgraph reachable by certain nodes+reachableSubgraph :: DynGraph gr => [Node] => gr a b => gr a b+reachableSubgraph roots graph = flip delNodes graph $+ filter (`S.notMember` reachableNodes) $+ nodes graph+ where+ trGraph = trc graph+ reachableNodes = S.unions $ map (S.fromList . suc trGraph) roots - let nodes = zip [0..] $ map (\(_,(_,c)) -> c) rhm- edges = do- mbe <- foldM mbEdges [] nodes- return $ foldlMaybe toLEdge [] mbe- -- Reversing it fixes the ordering of nodes in the graph. Should run- -- through allPtrs and sort by order inside of all allPtrs lists.- --- -- When building the graph directly out of [Box] instead of going- -- through the HeapMap, then the order of nodes might not be right for- -- non-trivial graphs.- --- -- In some cases it's impossible to get the order right. Maybe there is- -- a way in graphviz to specify outgoing edge orientation after all?- rhm = reverse hm - toLEdge xs (0, Just t) = if length rhm <= t- then Nothing -- This might be able to happen, let's make sure it doesn't- else case rhm !! t of- (_,(Just name, _)) -> Just $ (0,t,name):xs- (_,(Nothing, _)) -> Just $ (0,t,""):xs- toLEdge xs (f, Just t) = Just $ (f,t,""):xs- toLEdge xs _ = Just xs+-- | Converts a 'HeapGraph' to a fgl 'Gr', taking into account special+-- representations for BCOs.+convertGraph :: HeapGraph Identifier -> Gr ([String], Int) (String, Int)+convertGraph hg = appEndo (removeGarbage <> addNames <> addEdges <> addNodes) empty+ where+ HeapGraph hgm = hg - mbEdges xs (p,BCOClosure _ _ _ bPtr _ _ _) = do- children <- bcoChildren [bPtr]- return $ map (\b -> (p, Just b)) children ++ xs- -- Using allPtrs and then filtering the closures not available in the- -- heap map out emulates pointersToFollow without being in IO- mbEdges xs (p,c) = return $ map (\b -> (p, boxPos b)) (allPtrs c) ++ xs+ -- Adds nodes for every closure in the map+ -- Special treatment for BCOs: Use the disassembler+ addNodes = mconcat [+ Endo (insNode (i, toNode hge))+ | (i,hge) <- M.toList hgm+ ] - boxPos :: Box -> Maybe Int- boxPos b = elemIndex b $ map fst rhm+ deref = fmap $ hgeClosure . (M.!) hgm - bcoChildren :: [Box] -> IO [Int]- bcoChildren [] = return []- bcoChildren (b:bs) = case boxPos b of- Nothing -> do c <- getBoxedClosureData b- ptf <- pointersToFollow2 c- bcoChildren (ptf ++ bs)- Just pos -> do children <- bcoChildren bs- return $ pos : children+ toNode hge | Just byteCode <- disassembleBCO deref (hgeClosure hge)+ -- Does not look nice this way, far too wide+ -- = (map show byteCode, 0)+ = (["BCO"], length (concatMap F.toList byteCode))+ | otherwise+ = (showClosureFields (hgeClosure hge), length $ allPtrs (hgeClosure hge)) - es' <- edges+ -- Adds edges between the closurs, treating BCOs specially+ addEdges = mconcat [+ Endo (insEdge (i, t, ("",n)))+ | (i, hge) <- M.toList hgm+ , (t,n) <- toEdges hge+ ]+ toEdges hge = [ (t, n) | (Just t, n) <- zip myPtrs [0..] ]+ where myPtrs | Just byteCode <- disassembleBCO deref (hgeClosure hge)+ = concatMap F.toList byteCode+ | otherwise+ = allPtrs (hgeClosure hge) - case es' of- Nothing -> xDotParse as- Just es -> do- -- Convert a heap map, our internal data structure, to a graph that can be- -- converted to a dot graph.- let buildGraph :: Gr Closure String- buildGraph = insEdges es $ insNodes nodes empty+ -- Adds the nodes and edges for the names+ -- addNameList = zip [-1,-2..] -- Displays from right to left+ addNameList = zip [-1,-2..] $ reverse+ [ (i,name)+ | (i, hge) <- M.toList hgm+ , name <- hgeData hge+ ]+ addNames = mconcat $ map addName addNameList+ addName (n,(i,name)) = Endo (insEdge (n, i, (name, 0))) <> Endo (insNode (n, ([""],0))) - xDot <- graphvizWithHandle Dot (defaultVis $ toViewableGraph buildGraph) XDot hGetDot- return (getOperations xDot, getBoxes hm, getSize xDot)+ -- Removes nodes not reachable by a named closure+ removeGarbage = Endo (reachableSubgraph (map fst addNameList)) -getBoxes :: HeapMap -> [Box]-getBoxes hm = map (\(b,(_,_)) -> b) $ reverse hm+removeOld :: Eq a => [a] -> Maybe a -> Maybe a+removeOld keys (Just x)+ | x `elem` keys = Just x+ | otherwise = Nothing+removeOld _ x = x --- Probably have to do some kind of fold over the graph to remove for example--- unwanted pointers-toViewableGraph :: Gr Closure String -> Gr String String-toViewableGraph cg = emap id $ nmap showClosure cg+-- | Take the objects to be visualized and run them through @dot@ and extract+-- the drawing operations that have to be exectued to show the graph of the+-- heap map.+xDotParse :: [Box] -> IO ([(Object Node, Operation)], [Box], [(Object Node, Rectangle)], Rectangle)+xDotParse hidden = do+ --(hg, _) <- multiBuildHeapGraph 100 as+ (HeapGraph hg'', _) <- getHeapGraph+ let hg' = M.filter (\(HeapGraphEntry b _ _ _) -> not $ b `elem` hidden) hg''+ let hg = HeapGraph $ M.map (\hge -> hge{hgeClosure = fmap (removeOld $ M.keys hg') (hgeClosure hge)}) hg'+ --let hg = HeapGraph $ traverse removeOld hg' -defaultVis :: (Graph gr) => gr String String -> DotGraph Node+ xDot <- graphvizWithHandle graphvizCommand (defaultVis $ convertGraph hg) XDot hGetDot++ return (getOperations xDot, getBoxes (HeapGraph hg''), getDimensions xDot, getSize xDot)++getBoxes :: HeapGraph a -> [Box]+getBoxes (HeapGraph hg) = map (\(HeapGraphEntry b _ _ _) -> b) $ M.elems hg++defaultVis :: (Graph gr) => gr ([String], Int) (String, Int) -> DotGraph Node defaultVis = graphToDot nonClusteredParams -- Somehow (X11Color Transparency) is white, use (RGBA 0 0 0 0) instead -- Ordering OutEdges is not strong enough to force edge ordering, might not look good anyway { globalAttributes = [GraphAttrs [BgColor [toWC $ RGBA 0 0 0 0], FontName fontName, FontSize graphFontSize]]- , fmtNode = \ (_,l) -> [toLabel l, FontName fontName, FontSize nodeFontSize]+ , fmtNode = \(x,(l,i)) -> if x >= 0 then [+ --xLabel (B.pack "foo"),+ nodeLabel l i,+ Shape Record, FontName fontName, FontSize nodeFontSize]+ -- x < 0: Invisible marker nodes+ else [Shape PointShape, Style [SItem Invisible []]] --, fmtNode = \ (_,l) -> [toLabel l, FontName fontName, FontSize nodeFontSize, Style [SItem Filled []], FillColor [RGBA 255 255 255 255], Color [RGBA 0 0 0 255]] --, fmtNode = \ (_,l) -> [toLabel l, FontName fontName, FontSize nodeFontSize, Shape PlainText]- , fmtEdge = \ (_,_,l) -> [toLabel l, FontName fontName, FontSize edgeFontSize]+ , fmtEdge = \ (_,_,(l,i)) -> [+ TailPort (LabelledPort (PN (B.pack (show i))) Nothing),+ toLabel l,+ FontName fontName, FontSize edgeFontSize] }+ where+ {-+ All pointer origins below the constructor:+ nodeLabel l 0 = Label $ RecordLabel [FieldLabel (B.pack l) | l <- ls]+ nodeLabel l i = Label $ RecordLabel [+ FlipFields [+ FlipFields [FieldLabel (B.pack l) | l <- ls] +++ FlipFields [PortName (PN (B.pack (show j))) | j <- [0..i-1]]+ ]]+ -}+ {-+ All pointer following the constructor on the right:+ -}+ nodeLabel ls i = Label $ RecordLabel $+ [FieldLabel (B.pack l) | l <- ls] +++ [ PortName (PN (B.pack (show j))) | j <- [0..i-1]]
src/GHC/Vis/View/List.hs view
@@ -29,9 +29,9 @@ import Control.Monad import Data.IORef+import Data.List import System.IO.Unsafe -import GHC.Vis.Internal import GHC.Vis.Types hiding (State, View(..)) import GHC.Vis.View.Common @@ -43,12 +43,13 @@ { objects :: [(Box, String, [VisObject])] , bounds :: [(String, Rectangle)] , hover :: Maybe String+ , totalSize :: Rectangle } type RGB = (Double, Double, Double) state :: IORef State-state = unsafePerformIO $ newIORef $ State [] [] Nothing+state = unsafePerformIO $ newIORef $ State [] [] Nothing (0, 0, 1, 1) layout' :: IORef (Maybe PangoLayout) layout' = unsafePerformIO $ newIORef Nothing@@ -96,8 +97,8 @@ s <- readIORef state Gtk.Rectangle _ _ rw2 rh2 <- widgetGetAllocation canvas - boundingBoxes <- render canvas (draw s rw2 rh2)- modifyIORef state (\s' -> s' {bounds = boundingBoxes})+ (size, boundingBoxes) <- render canvas (draw s rw2 rh2)+ modifyIORef state (\s' -> s' {totalSize = size, bounds = boundingBoxes}) #ifdef SDL_WINDOW getState :: IO State@@ -113,15 +114,14 @@ export drawFn file = do s <- readIORef state - drawFn file (fromIntegral xSize) (fromIntegral ySize)- (\surface -> renderWith surface (draw s xSize ySize))+ let (_, _, xSize, ySize) = totalSize s - return ()+ drawFn file xSize ySize+ (\surface -> renderWith surface (draw s 0 0)) - where xSize = 500 :: Int- ySize = 500 :: Int+ return () -draw :: State -> Int -> Int -> Render [(String, Rectangle)]+draw :: State -> Int -> Int -> Render (Rectangle, [(String, Rectangle)]) draw s rw2 rh2 = do let os = objects s objs = map (\(_,_,x) -> x) os@@ -151,12 +151,13 @@ (ox,oy) = (ox2 - (zoomRatio vS - 1) * rw / 2, oy2 - (zoomRatio vS - 1) * rh / 2) translate ox oy- scale sx sy+ unless (rw2 == 0 || rh2 == 0) $+ scale sx sy let rpos = scanl (\a b -> a + b + 30) 30 pos result <- mapM (drawEntry s maxNameWidth 0) (zip3 objs rpos names) - return $ map (\(o, (x,y,w,h)) -> (o, (x*sx+ox,y*sy+oy,w*sx,h*sy))) $ concat result+ return ((0, 0, sw, sh), map (\(o, (x,y,w,h)) -> (o, (x*sx+ox,y*sy+oy,w*sx,h*sy))) $ concat result) render :: WidgetClass w => w -> Render b -> IO b render canvas r = do@@ -169,7 +170,8 @@ click = do s <- readIORef state - case hover s of+ hm <- inHistoryMode+ when (not hm) $ case hover s of Just t -> do evaluate t -- Without forkIO it would hang indefinitely if some action is currently@@ -198,10 +200,13 @@ unless (oldHover == hover s) $ widgetQueueDraw canvas -- | Something might have changed on the heap, update the view.-updateObjects :: [(Box, String)] -> IO ()+updateObjects :: [NamedBox] -> IO () updateObjects boxes = do- os <- parseBoxes boxes- let objs = zipWith (\(x,y) z -> (x,y,z)) boxes os+ os <- parseBoxes+ --(h, is) <- multiBuildHeapGraph 100 $ map fst boxes+ -- This is wrong+ --let os = visHeapGraph (zipWith (\(b,i) (b',n) -> (i,n)) is boxes) h+ let objs = zipWith (\(y,x) z -> (x,intercalate ", " y,z)) boxes os modifyIORef state (\s -> s {objects = objs, hover = Nothing}) drawEntry :: State -> Double -> Double -> ([VisObject], Double, String) -> Render [(String, Rectangle)]