<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        color:black;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.MsoPlainText, li.MsoPlainText, div.MsoPlainText
        {mso-style-priority:99;
        mso-style-link:"Plain Text Char";
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:10.5pt;
        font-family:Consolas;
        color:black;}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML Preformatted Char";
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";
        color:black;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0cm;
        margin-right:0cm;
        margin-bottom:0cm;
        margin-left:36.0pt;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        color:black;}
p.Code, li.Code, div.Code
        {mso-style-name:Code;
        mso-style-link:"Code Char";
        margin-top:0cm;
        margin-right:0cm;
        margin-bottom:0cm;
        margin-left:36.0pt;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Courier New";
        color:black;}
span.CodeChar
        {mso-style-name:"Code Char";
        mso-style-link:Code;
        font-family:"Courier New";}
span.PlainTextChar
        {mso-style-name:"Plain Text Char";
        mso-style-priority:99;
        mso-style-link:"Plain Text";
        font-family:Consolas;}
p.msonormal0, li.msonormal0, div.msonormal0
        {mso-style-name:msonormal;
        mso-margin-top-alt:auto;
        margin-right:0cm;
        mso-margin-bottom-alt:auto;
        margin-left:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        color:black;}
span.HTMLPreformattedChar
        {mso-style-name:"HTML Preformatted Char";
        mso-style-priority:99;
        mso-style-link:"HTML Preformatted";
        font-family:Consolas;
        color:black;}
span.EmailStyle25
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:1066874942;
        mso-list-type:hybrid;
        mso-list-template-ids:599311370 134807553 134807555 134807557 134807553 134807555 134807557 134807553 134807555 134807557;}
@list l0:level1
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l0:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level3
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l0:level4
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l0:level5
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level6
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
@list l0:level7
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Symbol;}
@list l0:level8
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:"Courier New";}
@list l0:level9
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;
        font-family:Wingdings;}
ol
        {margin-bottom:0cm;}
ul
        {margin-bottom:0cm;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body bgcolor="white" lang="EN-GB" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="color:windowtext;mso-fareast-language:EN-US">The underlying think I don’t understand is this:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:windowtext;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<ul style="margin-top:0cm" type="disc">
<li class="MsoListParagraph" style="color:windowtext;margin-left:0cm;mso-list:l0 level1 lfo1">
<span style="mso-fareast-language:EN-US">I assume that the shared cloud cache (SCC) maps input files + command line to outputs.<o:p></o:p></span></li></ul>
<p class="MsoListParagraph"><span style="color:windowtext;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<ul style="margin-top:0cm" type="disc">
<li class="MsoListParagraph" style="color:windowtext;margin-left:0cm;mso-list:l0 level1 lfo1">
<span style="mso-fareast-language:EN-US">To have a SCC we really have to list <b>
all</b> the input files that a compilation step consults – and that may be many more than the direct imports of the module.   If we compile M which imports A, we will read A.hi; but then we may now have to read B.hi and so on.  Let’s say that M has a
<b>deep dependency</b> on B.hi.<o:p></o:p></span></li></ul>
<p class="MsoListParagraph"><span style="color:windowtext;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoListParagraph"><span style="color:windowtext;mso-fareast-language:EN-US">Listing
<b>all</b> the inputs is a soundness issue: if the SCC is simply a cached map from those inputs to outputs, then missing out an input would be fatal (i.e. unsound).  It’s sound to list too many inputs, but doing will reduce the usefulness of the cache.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:windowtext;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<ul style="margin-top:0cm" type="disc">
<li class="MsoListParagraph" style="color:windowtext;margin-left:0cm;mso-list:l0 level1 lfo1">
<span style="mso-fareast-language:EN-US">In contrast, to get a correct Hadrian build, it suffices to list all the
<b>direct imports</b> (= shallow depdendencies) of the thing being compiled.  We’ll bring those up to date and, by implication, all the things it depends on will now also be up to date.<o:p></o:p></span></li></ul>
<p class="MsoNormal"><span style="color:windowtext;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="color:windowtext;mso-fareast-language:EN-US">Listing only the direct imports is much less onerous; that’s what ghc -M does.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:windowtext;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<ul style="margin-top:0cm" type="disc">
<li class="MsoListParagraph" style="color:windowtext;margin-left:0cm;mso-list:l0 level1 lfo1">
<span style="mso-fareast-language:EN-US">Early cutoff has something in common with the SCC.   E.g. if we compile A and produce an
<b>identical</b> A.hi, we still need to recompile M because B.hi has changed.   GHC already accommodated this by putting B.hi’s fingerprint in A.hi, so if B.hi changes then so will A.hi.
<o:p></o:p></span></li></ul>
<p class="MsoNormal"><span style="color:windowtext;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="color:windowtext;mso-fareast-language:EN-US">So maybe we
<b>don’t</b> need to record those transitive dependencies in the SCC?<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="color:windowtext;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:windowtext;mso-fareast-language:EN-US">It would be extremely onerous to write Hadrian code to make all deep dependencies explicit.  Do we really need to?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:windowtext;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:windowtext;mso-fareast-language:EN-US">Simon<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:windowtext;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span lang="EN-US" style="color:windowtext">From:</span></b><span lang="EN-US" style="color:windowtext"> ghc-devs <ghc-devs-bounces@haskell.org>
<b>On Behalf Of </b>David Eichmann<br>
<b>Sent:</b> 27 March 2019 11:54<br>
<b>To:</b> Neil Mitchell <ndmitchell@gmail.com>; Andrey Mokhov <andrey.mokhov@newcastle.ac.uk>; GHC developers <ghc-devs@haskell.org><br>
<b>Subject:</b> Hadrian Transitive Dependencies<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p>Hello Shake/Hadrian contributors and the like,<o:p></o:p></p>
<p>Recently I've been putting Hadrian's fsatrace linting feature to good use, tracking down missing dependencies in Hadrian. Ultimately, we want to use shake's cloud build / shared cache feature and ensure it works across CI builds. Unfortunately the feature
 isn't working smoothly with Hadrian: see <a href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.haskell.org%2Fghc%2Fghc%2Fissues%2F16295&data=02%7C01%7Csimonpj%40microsoft.com%7C1638b8b55cbf4ae2862a08d6b2aaeba1%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636892844511642155&sdata=RPU0zZ4fLhvEp4yrBuGVO7ZGtTASGL80qctso%2BcBrgU%3D&reserved=0">
#16295</a>. This is very desirable to improve CI build times. It is my understanding that in order to get caching to work:<o:p></o:p></p>
<p class="MsoNormal">1. All accessed files must declared with `need` AND<br>
2. All created files must be declared with `produces` (or be the target of the build rule)
<o:p></o:p></p>
<p>Is my understanding correct? Or is there a weaker condition (perhaps only 2 is necessary)?<o:p></o:p></p>
<p>If I'm correct, this amounts to fixing all fsatrace lint errors. See <a href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.haskell.org%2Fghc%2Fghc%2Fissues%2F16400%23note_188901&data=02%7C01%7Csimonpj%40microsoft.com%7C1638b8b55cbf4ae2862a08d6b2aaeba1%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636892844511652163&sdata=G8kxo%2F7D%2Fx2TQHHfzZqcMmh2GyJVmqe%2FQ8kNY8YNHI8%3D&reserved=0">
here</a> for a breakdown of lint errors / missing dependencies. A large portion of these are Haskell interface files (i.e. *.hi files). Before building a Haskell object file, dependencies are discovered via `ghc` using the `-M  -include-pkg-deps` options. Unfortunately,
 shake's fsatrace linting complains about other *.hi files being accessed! For example when building `stage1/libraries/mtl/build/Control/Monad/RWS/Class.o` we get the following dependencies from ghc:<o:p></o:p></p>
<pre>_build/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o : libraries/mtl/Control/Monad/RWS/Class.hs<o:p></o:p></pre>
<pre>_build/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o : _build/stage1/lib/../lib/x86_64-linux-ghc-8.9.20190325/base-4.13.0.0/Prelude.hi<o:p></o:p></pre>
<pre>_build/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o : _build/stage1/lib/../lib/x86_64-linux-ghc-8.9.20190325/base-4.13.0.0/Data/Monoid.hi<o:p></o:p></pre>
<pre>_build/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o : _build/stage1/lib/../lib/x86_64-linux-ghc-8.9.20190325/transformers-0.5.5.0/Control/Monad/Trans/RWS/Strict.hi<o:p></o:p></pre>
<pre>_build/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o : _build/stage1/lib/../lib/x86_64-linux-ghc-8.9.20190325/transformers-0.5.5.0/Control/Monad/Trans/RWS/Lazy.hi<o:p></o:p></pre>
<pre>_build/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o : _build/stage1/lib/../lib/x86_64-linux-ghc-8.9.20190325/transformers-0.5.5.0/Control/Monad/Trans/Identity.hi<o:p></o:p></pre>
<pre>_build/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o : _build/stage1/lib/../lib/x86_64-linux-ghc-8.9.20190325/transformers-0.5.5.0/Control/Monad/Trans/Maybe.hi<o:p></o:p></pre>
<pre>_build/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o : _build/stage1/lib/../lib/x86_64-linux-ghc-8.9.20190325/transformers-0.5.5.0/Control/Monad/Trans/Except.hi<o:p></o:p></pre>
<pre>_build/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o : _build/stage1/lib/../lib/x86_64-linux-ghc-8.9.20190325/transformers-0.5.5.0/Control/Monad/Trans/Error.hi<o:p></o:p></pre>
<pre>_build/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o : _build/stage1/lib/../lib/x86_64-linux-ghc-8.9.20190325/transformers-0.5.5.0/Control/Monad/Trans/Class.hi<o:p></o:p></pre>
<pre>_build/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o : _build/stage1/libraries/mtl/build/Control/Monad/Writer/Class.hi<o:p></o:p></pre>
<pre>_build/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o : _build/stage1/libraries/mtl/build/Control/Monad/State/Class.hi<o:p></o:p></pre>
<pre>_build/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o : _build/stage1/libraries/mtl/build/Control/Monad/Reader/Class.hi<o:p></o:p></pre>
<p>And shake complains of the following missing deps:<o:p></o:p></p>
<pre>_build/stage0/bin/ghc -Wall -hisuf hi -osuf o -hcsuf hc -static -hide-all-packages -no-user-package-db '-package-db _build/stage1/lib/package.conf.d' '-this-unit-id mtl-2.2.2' '-package-id base-4.13.0.0' '-package-id transformers-0.5.5.0' -i -i_build/stage1/libraries/mtl/build -i_build/stage1/libraries/mtl/build/autogen -ilibraries/mtl/. -Iincludes -I_build/generated -I_build/stage1/libraries/mtl/build -I/home/david/ghc/_build/stage1/lib/x86_64-linux-ghc-8.9.20190325/base-4.13.0.0/include -I/home/david/ghc/_build/stage1/lib/x86_64-linux-ghc-8.9.20190325/integer-gmp-1.0.2.0/include -I/home/david/ghc/_build/stage1/lib/x86_64-linux-ghc-8.9.20190325/rts-1.0/include -I_build/generated -optc-I_build/generated -optP-include -optP_build/stage1/libraries/mtl/build/autogen/cabal_macros.h -outputdir _build/stage1/libraries/mtl/build -Wnoncanonical-monad-instances -optc-Werror=unused-but-set-variable -optc-Wno-error=inline -c libraries/mtl/Control/Monad/RWS/Class.hs -o _build/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o -O2 -H32m -Wall -fno-warn-unused-imports -fno-warn-warnings-deprecations -Wcompat -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -XHaskell2010 -XSafe -ghcversion-file=/home/david/MEGA/File_Dump/Well-Typed/GHC/_nosync_git/ghc/_build/generated/ghcversion.h -Wno-deprecated-flags<o:p></o:p></pre>
<pre>Lint checking error - _build/HEAD_default/stage1/libraries/mtl/build/Control/Monad/RWS/Class.o - 22 values were used but not depended upon:<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage0/lib/settings<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage0/lib/platformConstants<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage0/lib/llvm-targets<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage0/lib/llvm-passes<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage0/lib/package.conf.d/package.cache<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/package.conf.d/package.cache<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/base-4.13.0.0/GHC/Float.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/base-4.13.0.0/GHC/Base.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/ghc-prim-0.5.3/GHC/Types.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/base-4.13.0.0/GHC/Maybe.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/transformers-0.5.5.0/Control/Monad/Trans/Writer/Lazy.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/transformers-0.5.5.0/Control/Monad/Trans/Writer/Strict.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/transformers-0.5.5.0/Control/Monad/Trans/State/Lazy.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/transformers-0.5.5.0/Control/Monad/Trans/State/Strict.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/transformers-0.5.5.0/Control/Monad/Trans/Reader.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/transformers-0.5.5.0/Control/Monad/Trans/List.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/transformers-0.5.5.0/Control/Monad/Trans/Cont.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/ghc-prim-0.5.3/GHC/Tuple.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/base-4.13.0.0/GHC/IO/Exception.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/integer-gmp-1.0.2.0/GHC/Integer/Type.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/base-4.13.0.0/Data/Either.hi<o:p></o:p></pre>
<pre>  Used:  _build/HEAD_default/stage1/lib/x86_64-linux-ghc-8.9.20190325/base-4.13.0.0/GHC/Natural.hi<o:p></o:p></pre>
<p>GHC is reading *.hi files that are not reported as dependencies by `ghc -M  -include-pkg-deps`. This is because they are not direct, but
<i>transitive</i> dependencies! How do we fix these lint errors (again with the goal of using shakes shared cache feature)? Some ideas:<o:p></o:p></p>
<p class="MsoNormal">* Wildly over approximate dependencies. This may be easier to implement but cause unneeded recompilation (when a false dependency changes). Either:<br>
    * `need` all dependent packages' interface files recursively as well as transitive dependencies reported by `ghc -M  -include-pkg-deps` within the current package. OR<br>
    * OR `need` all transitive dependencies reported by `ghc -M  -include-pkg-deps`. This will likely result in fewer dependencies but requires a bit more work in recovering dependent packages' dependency graphs.<br>
* Perhaps transitive dependencies are not important for shared caching to work. Change shakes linting feature to allow (untracked?) transitive dependencies to be accessed.
<o:p></o:p></p>
<p>Feed back would be greatly appreciated.<o:p></o:p></p>
<p>David Eichmann<o:p></o:p></p>
<p><o:p> </o:p></p>
<pre>-- <o:p></o:p></pre>
<pre>David Eichmann, Haskell Consultant<o:p></o:p></pre>
<pre>Well-Typed LLP, <a href="https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.well-typed.com&data=02%7C01%7Csimonpj%40microsoft.com%7C1638b8b55cbf4ae2862a08d6b2aaeba1%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636892844511662172&sdata=BIQVoE%2FaLNjUWBH4bYcNpvFxEESb56bsJ2d8dBDt0rk%3D&reserved=0">http://www.well-typed.com</a><o:p></o:p></pre>
<pre><o:p> </o:p></pre>
<pre>Registered in England & Wales, OC335890<o:p></o:p></pre>
<pre>118 Wymering Mansions, Wymering Road, London W9 2NF, England <o:p></o:p></pre>
</div>
</div>
</body>
</html>