Return-Path: X-Original-To: apmail-incubator-clerezza-dev-archive@minotaur.apache.org Delivered-To: apmail-incubator-clerezza-dev-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id F3108781E for ; Sun, 24 Jul 2011 10:03:27 +0000 (UTC) Received: (qmail 53152 invoked by uid 500); 24 Jul 2011 10:03:26 -0000 Delivered-To: apmail-incubator-clerezza-dev-archive@incubator.apache.org Received: (qmail 53085 invoked by uid 500); 24 Jul 2011 10:03:15 -0000 Mailing-List: contact clerezza-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: clerezza-dev@incubator.apache.org Delivered-To: mailing list clerezza-dev@incubator.apache.org Received: (qmail 53052 invoked by uid 99); 24 Jul 2011 10:03:09 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 24 Jul 2011 10:03:09 +0000 X-ASF-Spam-Status: No, hits=1.5 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of henry.story@gmail.com designates 74.125.82.43 as permitted sender) Received: from [74.125.82.43] (HELO mail-ww0-f43.google.com) (74.125.82.43) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 24 Jul 2011 10:03:02 +0000 Received: by wwi18 with SMTP id 18so3067700wwi.0 for ; Sun, 24 Jul 2011 03:02:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to:x-mailer; bh=GB9OqnIXI8tTkj2bzug6exF5PzI6ryEpJ+1XKxig6zw=; b=YF1XAZLwNhPhFdW3fiFzx1o8+6I9xxUvNvisL5JzFFuH/6y65sqvVhHVQ2uqcE4gC3 Yox8pzT1NcOX4H0usNFigOGTJVoXuZGscgMCR70nq5583ontiwmTzJ2jfKSFXDjP4SAO Ovv7AlMgdryFKZGIP6ebCGuCW+WOad65Fvoe8= Received: by 10.216.60.17 with SMTP id t17mr2896478wec.29.1311501760111; Sun, 24 Jul 2011 03:02:40 -0700 (PDT) Received: from bblfish.home (AAubervilliers-651-1-201-28.w83-114.abo.wanadoo.fr [83.114.32.28]) by mx.google.com with ESMTPS id h46sm2649371wed.38.2011.07.24.03.02.37 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 24 Jul 2011 03:02:38 -0700 (PDT) Subject: Re: [scala-user] Solution: taking context seriously was: A scala anti pattern -- looking for a name Mime-Version: 1.0 (Apple Message framework v1244.3) Content-Type: multipart/signed; boundary="Apple-Mail=_1F550B90-BDDF-499D-94A9-BA2FF1833FA4"; protocol="application/pkcs7-signature"; micalg=sha1 From: Henry Story In-Reply-To: Date: Sun, 24 Jul 2011 12:02:36 +0200 Cc: scala-user , Rex Kerr , =?iso-8859-1?Q?Reto_Bachmann-Gm=FCr?= , clerezza-dev@incubator.apache.org Message-Id: <4F13B437-8EE7-427A-A424-D72DAC26DA01@gmail.com> References: <4E26F65B.1090108@farewellutopia.com> <4E272720.1020709@farewellutopia.com> <4E27F0C4.3090602@farewellutopia.com> <06E9E2BC-1551-4249-975D-305D03DD49A2@gmail.com> To: Lex X-Mailer: Apple Mail (2.1244.3) X-Virus-Checked: Checked by ClamAV on apache.org --Apple-Mail=_1F550B90-BDDF-499D-94A9-BA2FF1833FA4 Content-Type: multipart/alternative; boundary="Apple-Mail=_824E50DA-F11D-4265-AE64-BDA1D06E8556" --Apple-Mail=_824E50DA-F11D-4265-AE64-BDA1D06E8556 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=iso-8859-1 Hi Lex,=20 thanks for your feedback. I think you must have missed a bit of the = discussion, and are lacking some of the context, which needs filling in = a little both to remove the sting present it is true in the discussion, = but also to allow us to see what the discussion has accomplished and why = it was a fruitful one for the scala-dev list. What brought me here was that I was asked by Reto to verify on the = scala-dev mailing list that=20 import ez1._ b_("reto") -- FOAF.homepage --> "http://bblfish.net/".uri import ez2._ b_("hjs") -- FOAF.homepage --> "http://bblfish.net/".uri was an anti-pattern [1]. We are two to be developing enthusiastically = with Scala in Clerezza, so the problem is that if we have a = disagreement of this kind it is very difficult to resolve it there. It = is true that I found it so evidently to be a problem, that I thought = that this was a bit disingenuous to ask me to come to this list = initially.=20 Anyway, so I came to the list, to ask the question, and the answer was = very clear: I don't think there was any support for the proposed way of = doing things from anyone here.=20 But was that therefore supporting some supposed way I had of doing = things? Was this an issue of my patch versus his patch? No, very clearly not. The solution I had developed a while ago [2] was = clearly over-engineered, and I am not suggesting to go back to that. The = discussion on this list helped me look very carefully at Reto's = arguments for his solution above. And you will see me taking those very = seriously in quite a few of the e-mails to this list [3]. In fact what I = took out of this was exactly why my original solution was problematic. = But as I will show, that part of the solution is still present within = the code that Reto proposed.=20 The problem with "my" original code, is to put it as simply as possible = is that you need the context to cover the whole of the DSL. Ie. in my = original solutions one would write ( graph.node a FOAF.Person -- name --> "Lex" -- knows --> ( graph.bnode("hjs") -- name --> "Henry = Story") -- knows --> ( reto -- knows -- graph.bnode("hjs")) ) =20 Notice that following the first -- knows --> arrow one MUST have a = reference back to the original graph object with the code graph.bnode("hjs") if one wants that to be used again in = the last statement of the DSL above - the one where it is claimed that Reto knows the same person you do.=20 It is in order to improve this that Reto rewrote the code I had written = and came up with the solution I have claimed is an anti-pattern. (It relies much too strongly on implicits.) Reto = solved the above very cleverly by using subclassing and an import statement [4] it works miracles so long as you have only = one graph. What you do is you import an implicit conversion from bnodes = or Uris to a GraphNode backed by a instance of a Graph. This then allows = you to write the above as val graph =3D new EzMGraph() import graph._ ( node a FOAF.Person -- name --> "Lex" -- knows --> ( bnode("hjs") -- name --> "Henry Story") -- knows --> ( reto -- knows -- bnode("hjs")) ) Which as you will see removes all the references back to the original = graph in the DSL. ( No more graph.xxx ) How this works I explained in detail in the bug report CLEREZZA-603 So I think I explained on this list very clearly why Reto's solution was = so attractive for him, and why to that extent it was an improvement on = the code I had written, and indeed this is why I did not oppose it = being introduced into the Clerezza subversion repository.=20 But of course the problem is that it makes use of this anti pattern that = we are discussing here, and that is visible when you start using = multiple graphs together, at which point that notation becomes very = confusing. (Now it took me some time to see spot this myself, btw.) Reto claims that we never need more than one graph - and I = fundamentally disagree. A very large part of the work I need to do in = creating distributed social networks, is going to be writing, comparing = and playing with multiple graphs. In fact if the semantic web brings one = thing to us it brings this ability to work with multiple points of view, = without needing to assert anyone as the only truth [5]. So this is a = very important tool that I wish to use, and I believe it will be more = and more important as Clerezza builds apps. So accepting the anti-pattern - or whatever you wish to call it - and = accepting that Reto's solution contains some interesting insights, you = will notice that I was not banging on my chest - as you say - trying to = get my own old solution back in, but rather I sought out a new solution = that could satisfy both the point that Reto had made without requiring = the anti-pattern. This is the solution I developed in the part of this = thread entitled "taking context seriously", and which I have been = developing on the github branch of clerezza I am working on at = https://github.com/bblfish/clerezza/ in the zz-issues branch, and soon = the bblfish branch. How does this end up looking?=20 Well with the proposed changes [6] one just makes the context clear by = writing new context {( =20 node a FOAF.Person -- name --> "Lex" -- knows --> ( bnode("hjs") -- name --> "Henry Story") -- knows --> ( reto -- knows -- bnode("hjs")) )} Here the DSL is protected as an inner class by the context, so that one = never moves out of one graph into another by mistake, which would have = many unclear consequences. I have been using this on my github branch, = and it does work very nicely on the whole. It also avoids subclassing a = graph object, which is dangerous as that tends to give code more access = to the internals of how a graph works that is relevant to the coder = writing such triples. Henry [1] Reto wrote on the clerezza mailing list=20 "I think it's important to identify anti-pattern. Post a link here if = you document the anti-pattern you think you've discovered on the scala = mailing list"=20 [2] see the older version 1141579 of EzMGraph=20 [3] My reply dated 21 July 2011 to Reto's 5 questions among others [4] version 1144633 of EzMGraph and version 1144633 of RichGraphNode [5] See my mail on blogs.sun.com Beatnik: change your mind [6] see the new context class I proposed on my branch in github Social Web Architect http://bblfish.net/ On 24 Jul 2011, at 06:58, Lex wrote on scala-dev: > Does this really belong on the scala list?=20 yes > So your patch was not accepted, not a big deal. I This was not about patches being accepted or not.=20 > f you feel a strong disagreement with the > author, just fork the project. I have a branch on github, where I have been developing this. > If you are unwilling to maintain the fork, then think about how much = effort it takes to start a project and > keep it going. Maybe that will make you more respectful and > professional about the subject. It is a lot of work, that is why I am trying to make sure that Clerezza = does the right thing. I would rather the right thing were done without my having to discuss = it, as I have a lot of more urgent things to do. But we are breaking new ground here, and we are = discovering the power of=20 Scala - which one has to be careful not to abuse. > Banging on the chest and pointing to your way of doing things as > superior, while calling the original "anti-pattern" wont get you > anywhere. I don't think I pointed to my way of doing things as being better = anywhere on this thread. I just asked whether or not the solution was an anti-pattern. It is = important to agree on that, because otherwise there is no reason to find a better solution. This discussion helped us find a solution, so I think it is all to the = good. --Apple-Mail=_824E50DA-F11D-4265-AE64-BDA1D06E8556 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=iso-8859-1 http://bblfish.net/".uri

  = import ez2._
  b_("hjs") -- FOAF.homepage --> = "http://bblfish.net/".uri

 was an = anti-pattern [1].  We are two to be developing = enthusiastically with Scala in  Clerezza, so the problem is that if = we have a disagreement of this kind it is very difficult to resolve it = there. It is true that I found it so evidently to be a problem, that I = thought that this was a bit disingenuous  to ask me to come to this = list initially. 

Anyway, so I came to the = list, to ask the question, and the answer was very clear: I don't think = there was any support for the proposed way of doing things from anyone = here. 

But was that therefore supporting = some supposed way I had of doing things? Was this an issue of my patch = versus his patch?
No, very clearly not. The solution I had = developed a while ago [2] was clearly over-engineered, and I am not = suggesting to go back to that. The discussion on this list helped me = look very carefully at Reto's arguments for his solution above. And you = will see me taking those very seriously in quite a few of the e-mails to = this list [3]. In fact what I took out of this was exactly why my = original solution was problematic. But as I will show, that part of the = solution is still present within the code that Reto = proposed. 

The problem with "my" original = code, is to put it as simply as possible is that you need the context to = cover the whole of the DSL. Ie. in my original solutions one would = write

  (   graph.node a = FOAF.Person
              =  -- name --> "Lex"
          =      -- knows --> ( graph.bnode("hjs") -- name --> "Henry = Story")
              =  -- knows --> ( reto -- knows -- graph.bnode("hjs"))
  = )

  
Notice that following = the first  -- knows --> arrow one MUST have a reference back to = the original graph object
with the code graph.bnode("hjs") if = one wants that to be used again in the last statement of the DSL above = -
the one where it is claimed that Reto knows the same person = you do. 

It is in order to improve this = that Reto rewrote the code I had written and came up with the solution I = have claimed
is an anti-pattern. (It relies much too strongly = on implicits.) Reto solved the above very cleverly by using = subclassing
and an import statement [4] it works miracles so = long as you have only one graph. What you do is you import an implicit = conversion from bnodes or Uris to a GraphNode backed by a instance of a = Graph. This then allows you to write the above = as

  val graph =3D new = EzMGraph()
  import graph._
  (   = node a FOAF.Person
              =  -- name --> "Lex"
            =    -- knows --> ( bnode("hjs") -- name --> "Henry = Story")
               -- = knows --> ( reto -- knows -- bnode("hjs"))
  = )

Which as you will see removes all the = references back to the original graph in the DSL. ( No more graph.xxx = )
How this works I explained in detail in the bug report =  CLEREZZA-603





Well with = the proposed changes [6] one just makes the context clear by = writing

 new context {( =   
     node a FOAF.Person
  =              -- name --> = "Lex"
               -- knows = --> ( bnode("hjs") -- name --> "Henry Story")
    =            -- knows --> ( reto -- knows = -- bnode("hjs"))
  )}

Here the DSL is = protected as an inner class by the context, so that one never moves out = of one graph into another by mistake, which would have many unclear = consequences. I have been using this on my github branch, and it does = work very nicely on the whole. It also avoids subclassing a graph = object, which is dangerous as that tends to give code more access to the = internals of how a graph works that is relevant to the coder writing = such = triples.

Henry



 "I think it's = important to identify anti-pattern. Post a link here if you = document the anti-pattern you think you've discovered on the = scala mailing list" 
[6] see the new context class I proposed on my = branch in github

Social Web Architect
http://bblfish.net/

On 24 Jul 2011, at 06:58, Lex wrote on = scala-dev:

Does this really belong on the scala = list? 

yes

So your patch was not accepted, not a big deal. = I

This was not about patches being = accepted or not. 

f you = feel a strong disagreement with the
author, just fork the project. =

I have a branch on github, where = I have been developing this.


If you are unwilling to maintain the fork, then = think about how much effort it takes to start a project and
keep it = going. Maybe that will make you more respectful and
professional = about the subject.

It is a lot = of work, that is why I am trying to make sure that Clerezza does the = right thing.
I would rather the right thing were done without = my having to discuss it, as I have a lot of more
urgent things = to do. But we are breaking new ground here, and we are discovering the = power of 
Scala - which one has to be careful not to = abuse.

Banging on the = chest and pointing to your way of doing things as
superior, while = calling the original "anti-pattern" wont get = you
anywhere.

I don't think I = pointed to my way of doing things as being better anywhere on this = thread.
I just asked whether or not the solution was an = anti-pattern. It is important to agree on that,
because = otherwise there is no reason to find a better = solution.

This discussion helped us find a = solution, so I think it is all to the = good.




= --Apple-Mail=_824E50DA-F11D-4265-AE64-BDA1D06E8556-- --Apple-Mail=_1F550B90-BDDF-499D-94A9-BA2FF1833FA4 Content-Disposition: attachment; filename=smime.p7s Content-Type: application/pkcs7-signature; name=smime.p7s Content-Transfer-Encoding: base64 MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIOWzCCBnEw ggVZoAMCAQICAwJiDzANBgkqhkiG9w0BAQUFADCBjDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0 YXJ0Q29tIEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcx ODA2BgNVBAMTL1N0YXJ0Q29tIENsYXNzIDEgUHJpbWFyeSBJbnRlcm1lZGlhdGUgQ2xpZW50IENB MB4XDTExMDQwMzIzNDY1N1oXDTEyMDQwNTAwMDUwN1owgZMxIDAeBgNVBA0TFzM5NjU3MC1qSjVz czBIVHUwMlQwSHVwMR4wHAYDVQQKExVQZXJzb25hIE5vdCBWYWxpZGF0ZWQxKTAnBgNVBAMTIFN0 YXJ0Q29tIEZyZWUgQ2VydGlmaWNhdGUgTWVtYmVyMSQwIgYJKoZIhvcNAQkBFhVoZW5yeS5zdG9y eUBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCicB403P/cSHReHjbL 3dcz3rcjJom+veLQj/eaNVXE8o5YCSteFZ8mKNx3CMebWDWokxru0lD523MAHaPN8MSIUQV3Rd29 tJAnV3JWMK7olkIgzFfggS7v0vEBjS8LbLnrjqnGHpvLrh4eAaUvSLl6GcqURTGS5EYkmZBjFHLj +BiIkRrXPe9xtt5//yzB3oizfOpYRYJM0lvIqwAkvz43qF9czBGM8IhOG9YG91QT6QfSQpXia6lI R4I70gbaqP9qrget0l8KfwCZwD77LWkjTyyOZiqTNlNOYIBBEtmrExc11H2RFI8ZxOWbdI7yFIFt Zz/0PibZaV3Ap+PhvGVbAgMBAAGjggLRMIICzTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNV HSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwHQYDVR0OBBYEFCbo2HM76etf592IqCQT2IaBGmvI MB8GA1UdIwQYMBaAFFNy7ZKc4NrLAVx8fpY1TvLUuFGCMCAGA1UdEQQZMBeBFWhlbnJ5LnN0b3J5 QGdtYWlsLmNvbTCCAUIGA1UdIASCATkwggE1MIIBMQYLKwYBBAGBtTcBAgIwggEgMC4GCCsGAQUF BwIBFiJodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS9wb2xpY3kucGRmMDQGCCsGAQUFBwIBFihodHRw Oi8vd3d3LnN0YXJ0c3NsLmNvbS9pbnRlcm1lZGlhdGUucGRmMIG3BggrBgEFBQcCAjCBqjAUFg1T dGFydENvbSBMdGQuMAMCAQEagZFMaW1pdGVkIExpYWJpbGl0eSwgc2VlIHNlY3Rpb24gKkxlZ2Fs IExpbWl0YXRpb25zKiBvZiB0aGUgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUG9s aWN5IGF2YWlsYWJsZSBhdCBodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS9wb2xpY3kucGRmMDYGA1Ud HwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwuc3RhcnRzc2wuY29tL2NydHUxLWNybC5jcmwwgY4GCCsG AQUFBwEBBIGBMH8wOQYIKwYBBQUHMAGGLWh0dHA6Ly9vY3NwLnN0YXJ0c3NsLmNvbS9zdWIvY2xh c3MxL2NsaWVudC9jYTBCBggrBgEFBQcwAoY2aHR0cDovL2FpYS5zdGFydHNzbC5jb20vY2VydHMv c3ViLmNsYXNzMS5jbGllbnQuY2EuY3J0MCMGA1UdEgQcMBqGGGh0dHA6Ly93d3cuc3RhcnRzc2wu Y29tLzANBgkqhkiG9w0BAQUFAAOCAQEADMZOKh5RXKZze/+8r6Jrgnv8bBSDQ3W2plhF2cvtVol9 V4lmu0DcXsho+2kDugkZnS1piYMm3OqD2hv6uwj0aLd6KCzKPesyR79CsOLuCCPQV9sDTV0T9scT T+vmzLq4V8StHHnVBbqh71SyVUpyRzUH16Aqtk2+fsJEcHArhEeLrgl4RUI3m+j/FPLf1wk2NpZI vLd5aYYQ1s0xB/FvNZHI/9L6J1HSZG5hzBysaaab76Xlfg0sEn9aKsqxorA7IiZcQKBoZ6xW2lvu 3P0dB+lzQZrNkPbDabD5wVPegG1GrEnbMWt8vcdiFEkTroT4xtgh2hJ7g4Ct4IZTRuDPkzCCB+Iw ggXKoAMCAQICAQ0wDQYJKoZIhvcNAQEFBQAwfTELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0 Q29tIEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxKTAn BgNVBAMTIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA3MTAyNDIxMDE1NFoX DTEyMTAyMjIxMDE1NFowgYwxCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSsw KQYDVQQLEyJTZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWduaW5nMTgwNgYDVQQDEy9TdGFy dENvbSBDbGFzcyAxIFByaW1hcnkgSW50ZXJtZWRpYXRlIENsaWVudCBDQTCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBAMcJg8zOLdgasSmkLhOrlr6KMoOMpohBllVHrdRvEg/q6r8jR+EK 75xCGhR8ToREoqe7zM9/UnC6TS2y9UKTpT1v7RSMzR0t6ndl0TWBuUr/UXBhPk+Kmy7bI4yW4urC +y7P3/1/X7U8ocb8VpH/Clt+4iq7nirMcNh6qJR+xjOhV+VHzQMALuGYn5KZmc1NbJQYclsGkDxD z2UbFqE2+6vIZoL+jb9x4Pa5gNf1TwSDkOkikZB1xtB4ZqtXThaABSONdfmv/Z1pua3FYxnCFmdr /+N2JLKutIxMYqQOJebr/f/h5t95m4JgrM3Y/w7YX9d7YAL9jvN4SydHsU6n65cCAwEAAaOCA1sw ggNXMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgGmMB0GA1UdDgQWBBRTcu2SnODaywFcfH6WNU7y 1LhRgjCBqAYDVR0jBIGgMIGdgBROC+8apEBbpRdphzDKNGhD0EGu8qGBgaR/MH0xCzAJBgNVBAYT AklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSswKQYDVQQLEyJTZWN1cmUgRGlnaXRhbCBDZXJ0 aWZpY2F0ZSBTaWduaW5nMSkwJwYDVQQDEyBTdGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 eYIBATAJBgNVHRIEAjAAMD0GCCsGAQUFBwEBBDEwLzAtBggrBgEFBQcwAoYhaHR0cDovL3d3dy5z dGFydHNzbC5jb20vc2ZzY2EuY3J0MGAGA1UdHwRZMFcwLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0 Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0c3NsLmNvbS9zZnNj YS5jcmwwggFdBgNVHSAEggFUMIIBUDCCAUwGCysGAQQBgbU3AQEEMIIBOzAvBggrBgEFBQcCARYj aHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwNQYIKwYBBQUHAgEWKWh0dHA6Ly9j ZXJ0LnN0YXJ0Y29tLm9yZy9pbnRlcm1lZGlhdGUucGRmMIHQBggrBgEFBQcCAjCBwzAnFiBTdGFy dCBDb21tZXJjaWFsIChTdGFydENvbSkgTHRkLjADAgEBGoGXTGltaXRlZCBMaWFiaWxpdHksIHJl YWQgdGhlIHNlY3Rpb24gKkxlZ2FsIExpbWl0YXRpb25zKiBvZiB0aGUgU3RhcnRDb20gQ2VydGlm aWNhdGlvbiBBdXRob3JpdHkgUG9saWN5IGF2YWlsYWJsZSBhdCBodHRwOi8vY2VydC5zdGFydGNv bS5vcmcvcG9saWN5LnBkZjARBglghkgBhvhCAQEEBAMCAAcwUAYJYIZIAYb4QgENBEMWQVN0YXJ0 Q29tIENsYXNzIDEgUHJpbWFyeSBJbnRlcm1lZGlhdGUgRnJlZSBTU0wgRW1haWwgQ2VydGlmaWNh dGVzMA0GCSqGSIb3DQEBBQUAA4ICAQCqmuHgW4zOHRv8HcYsMCCgt5Mm/fECts0RKL8p/8cwz/+B /wXPBRQ04KCUfp19i4tBD91O07IxvgmiIvdPvGJUoQA6ZD635v/Es4xrSbXzOhGpbiToaXKjK9zs syt2mBiT+USHmery0930Gg2bCKKF5emEhUf9B6VOBSQ3NMLshWmZhWwq406fETWMkVk01+plkr/k 62jsLo98663XUqYFBItlqsDPRv+aOCF0Gxh8e6F07y+s68PSDmDt0DimQ4BTYR3ilIKjAFIi3IP/ loXBnvmOLpirsYIbcGmLIA/2y3yH6KdzQv7uSasAwloswCa7oZmzleCxvOfTBQm9sP2HmOecwz1R pkNzGXa4sHTiq4ZRYzo2IoZptvFBzrzQ9ht5CtC757oni6o0DHOhrlHGQEDlr/eqVuAX24kF6QKo mzDHm9D2SEmuzxRMxogXNsQLlUZDOJAff/oongNQ/zk4kScLH+q5KFYDrDfXwsOdtrczprlX4qg0 uGxWL9NLF/3RRsGrB1FH9w7C4aQ0mHXo2++Eio7bqiwyDrgJtmwNWsQOvu5IxXjSJ4ElOjj0jK3v sQI6HP+nKGjBrYRQ/popq/4v/BfMA8Hcs2rO6MZHQrWlvIVYq/JiZ26eAm3JJZQzD5HkOqkDZsUg 4Tnql9Y8sdnE4v7z6vv08sVf7LZXoTGCA28wggNrAgEBMIGUMIGMMQswCQYDVQQGEwJJTDEWMBQG A1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUg U2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3MgMSBQcmltYXJ5IEludGVybWVkaWF0ZSBD bGllbnQgQ0ECAwJiDzAJBgUrDgMCGgUAoIIBrzAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwG CSqGSIb3DQEJBTEPFw0xMTA3MjQxMDAyMzZaMCMGCSqGSIb3DQEJBDEWBBRE94NdNYP92TprUOut iMJOQ5Ar5jCBpQYJKwYBBAGCNxAEMYGXMIGUMIGMMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3Rh cnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4 MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3MgMSBQcmltYXJ5IEludGVybWVkaWF0ZSBDbGllbnQgQ0EC AwJiDzCBpwYLKoZIhvcNAQkQAgsxgZeggZQwgYwxCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFy dENvbSBMdGQuMSswKQYDVQQLEyJTZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWduaW5nMTgw NgYDVQQDEy9TdGFydENvbSBDbGFzcyAxIFByaW1hcnkgSW50ZXJtZWRpYXRlIENsaWVudCBDQQID AmIPMA0GCSqGSIb3DQEBAQUABIIBAJRmjZPCWq4Q6JsIS46M2wwSTKGUCxZVMmdgCu38dGFGrCwx jooW1Nn5kb4D8tLMWT4S7M4qjPColM88h/q7v2sAB30zAWB4SkwG+qn94yLEbW+zpN10lWfzYpp1 aBNIENjrxpXqhm74WvDYphv79bXrnJTRnjlItWsBgxkDG4U97V9C3WAUqaIUWc9r7nG8pLUVby7c U0NmBk1qk+TNBjJFMo6Qb+zX32TRBN11tbSYuEcTy1nUXi8LSZ+xeC99KGAeu3Oc2dObl9kFip8n vdkaixuX9PskMz7Ml2XH2JP3nCpyPcVDZedk75XvnrXA6/tvSqQJaVblhMa5C1YhXfAAAAAAAAA= --Apple-Mail=_1F550B90-BDDF-499D-94A9-BA2FF1833FA4--