Return-Path: X-Original-To: apmail-couchdb-user-archive@www.apache.org Delivered-To: apmail-couchdb-user-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id ED3EFD304 for ; Fri, 17 May 2013 16:29:34 +0000 (UTC) Received: (qmail 70983 invoked by uid 500); 17 May 2013 16:29:33 -0000 Delivered-To: apmail-couchdb-user-archive@couchdb.apache.org Received: (qmail 70950 invoked by uid 500); 17 May 2013 16:29:33 -0000 Mailing-List: contact user-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: user@couchdb.apache.org Delivered-To: mailing list user@couchdb.apache.org Received: (qmail 70942 invoked by uid 99); 17 May 2013 16:29:33 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 17 May 2013 16:29:33 +0000 X-ASF-Spam-Status: No, hits=2.2 required=5.0 tests=HTML_MESSAGE,RCVD_IN_DNSWL_NONE,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [128.18.84.132] (HELO brightmail-internal3.sri.com) (128.18.84.132) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 17 May 2013 16:29:28 +0000 X-AuditID: 80125484-b7f296d000001cbe-97-51965ad3c31b Received: from exchange-hub03.SRI.COM (Unknown_Domain [128.18.87.20]) (using TLS with cipher AES128-SHA (AES128-SHA/128 bits)) (Client did not present a certificate) by brightmail-internal3.sri.com (SRI Internal SMTP Gateway) with SMTP id 20.28.07358.3DA56915; Fri, 17 May 2013 09:29:08 -0700 (PDT) Received: from EXCHANGE-DB08.SRI.COM ([fe80::a11e:7c21:6886:9a20]) by exchange-hub03.SRI.COM ([fe80::8c0e:cf22:fef8:cb20%15]) with mapi id 14.02.0298.004; Fri, 17 May 2013 09:29:06 -0700 From: Jim Klo To: "" Subject: Re: tracking changes - how to check what was deleted? Thread-Topic: tracking changes - how to check what was deleted? Thread-Index: AQHOUis9seGK+4/2lU+F8E4pCcvHZ5kIbcoAgAB+ZACAAH4JAP///RjFgACCxwD//5ji7IAAd3QAgAAN4AA= Date: Fri, 17 May 2013 16:29:05 +0000 Message-ID: References: <20130516144732.0dda4bbf@svilendobrev.com> <70BAE84F-500B-4372-A81D-EABDD80B5A0B@sri.com> In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: yes X-MS-TNEF-Correlator: x-originating-ip: [192.12.16.226] Content-Type: multipart/signed; boundary="Apple-Mail=_F9F776AB-4D55-4CDB-86DB-C712C67FD5DC"; protocol="application/pkcs7-signature"; micalg=sha1 MIME-Version: 1.0 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrCIsWRmVeSWpSXmKPExsXSIBQuonslalqgwYzrvBade/ayOTB6bPxw nDGAMYrLJiU1J7MstUjfLoErY/um48wFC6YwVlycPJGpgfFQC2MXIyeHhICJxKpnbcwQtpjE hXvr2UBsIYENTBI39ydD2PsYJe7/kgCx2QTkJQ5vfwBWLyJgKXFrwUcWEFtYwE5iY9MFRoi4 vcSyL5OBbA4gO0liw60CkDCLgKpE36pPrCA2r4CVxJHpV4BsLqDxv5klOua9ZwJJcAoEStzo mgFWxAh0z/dTa8DizALiEreezGeCuFNE4uHF02wQtqjEy8f/WCFsRYl1TX/ZQYYyC0xhlJj2 5iwLxDZBiZMzn7BMYBSZhWTWLGR1s5DUQRQlSeyccpgRwtaWWLbwNTOErSmxv3s5C6a4hkTn t4msELapxOujH6F6rSVm/DrIBmErSkzpfsi+gJF7FaNMUlFmekZJbmJmji4sRo31iosy9ZLz czcxguM2pGUH44pdhocYBTgYlXh4P7lOCxRiTSwrrsw9xCjBwawkwnv849RAId6UxMqq1KL8 +KLSnNTiQ4zSHCxK4rxrVLoDhQTSE0tSs1NTC1KLYLJMHJxSDYwlq6bpJ127KCfGyxb0d99v J+e04AOGDxOyFaKCEw4E/PgSuI+p97N0g9Ox8xrqa38ZLq70kt6puSVt9pOH0mJB8pHX42/2 aFkd+lcWEZgslHJuuU9vxmnmGxf9tC5Ofio985L0Vblf9qs8lLO47mgHy9mv6y7mjG3ySXz4 P7op/8w0L9HbT5VYijMSDbWYi4oTAU98XbjXAgAA X-Virus-Checked: Checked by ClamAV on apache.org --Apple-Mail=_F9F776AB-4D55-4CDB-86DB-C712C67FD5DC Content-Type: multipart/alternative; boundary="Apple-Mail=_3E33FDD4-6610-4FA3-AF30-3AC59DF489BF" --Apple-Mail=_3E33FDD4-6610-4FA3-AF30-3AC59DF489BF Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 If there were a way to enable this sort of feature via a flag, like = local_seq that would be a good compromise IMO. :) I don't know what the = ramifications of this would be on performance, but would be a 'nice to = have'. Jim Klo Senior Software Engineer Center for Software Engineering SRI International t. @nsomnac On May 17, 2013, at 8:39 AM, Robert Newson wrote: > Aha, ok, that makes more sense. oldDoc will be null in that case to > match the behavior when there was never a document there, but it's > definitely a debatable nuance. I'm in favor of the existing behavior > but I do see your point. >=20 > B. >=20 > On 17 May 2013 16:31, Jim Klo wrote: >> No, I think I incorrectly described the condition where this happens. >>=20 >> If I first delete a doc with extra info like you illustrated, and = then re-insert the doc as new, the VDU does not get the existing delete = "stub" in my experience. If this has changed in 1.3, I'd welcome it. >>=20 >> It would be useful if the VDU got the existing "deleted" document in = certain use cases, like a document got removed for DCMA violation - I = don't want it to reappear by mistake. I'd like to have the right logic = in my VDU to check the notes in the existing deleted stub before = permitting the insert. There's ways around this which I use instead, but = think that if there's a stub that could be handed to VDU, it should. >>=20 >>=20 >> - JK >>=20 >> Sent from my iPhone >>=20 >> On May 17, 2013, at 7:41 AM, "Robert Newson" = wrote: >>=20 >>> VDU does receive the 'stub', which is always a document. The term >>> 'stub' can mislead people into thinking a deleted document is not an >>> actual document (it is). >>>=20 >>> Here I insist that deleted documents have a reason; >>>=20 >>> =E2=9E=9C ~ curl localhost:5984/db1/_design/foo -XPUT -d >>> '{"validate_doc_update":"function(newDoc) { if(newDoc._deleted && >>> !newDoc.reason) { throw({forbidden:\"must have a reason\"}); } = }"}' >>> = {"ok":true,"id":"_design/foo","rev":"1-ab8a8ecd8cf3de35ed7541facfb75029"} >>>=20 >>> An empty doc; >>>=20 >>> =E2=9E=9C ~ curl localhost:5984/db1/bar -XPUT -d {} >>> {"ok":true,"id":"bar","rev":"1-967a00dff5e02add41819138abb3284d"} >>>=20 >>> I try delete with DELETE method, which just does _id, _rev, = _deleted. >>>=20 >>> =E2=9E=9C ~ curl = 'localhost:5984/db1/bar?rev=3D1-967a00dff5e02add41819138abb3284d' >>> -XDELETE >>> {"error":"forbidden","reason":"must have a reason"} >>>=20 >>> Now I delete with a PUT and a reason; >>>=20 >>> =E2=9E=9C curl = 'localhost:5984/db1/bar?rev=3D1-967a00dff5e02add41819138abb3284d' >>> -XPUT -d '{"reason":"because I said so","_deleted":true}' >>> {"ok":true,"id":"bar","rev":"2-6e10b3cc9ea15f6a9d81aa72aaa6e098"} >>>=20 >>> And it's really deleted; >>>=20 >>> =E2=9E=9C ~ curl localhost:5984/db1/bar >>> {"error":"not_found","reason":"deleted"} >>>=20 >>> And my reason is recorded; >>>=20 >>> =E2=9E=9C ~ curl = 'localhost:5984/db1/bar?rev=3D2-6e10b3cc9ea15f6a9d81aa72aaa6e098' >>> = {"_id":"bar","_rev":"2-6e10b3cc9ea15f6a9d81aa72aaa6e098","reason":"because= >>> I said so","_deleted":true} >>>=20 >>> B. >>>=20 >>> On 17 May 2013 14:52, Jim Klo wrote: >>>> It's a great tip, my only complaint about it is that the deleted = stub doesn't get handed to the VDU function, unless that's changed in = 1.3 >>>>=20 >>>> - Jim >>>>=20 >>>>=20 >>>> On May 17, 2013, at 12:04 AM, "Dave Cottlehuber" = wrote: >>>>=20 >>>>> On 17 May 2013 01:32, Randall Leeds = wrote: >>>>>> Actually, it's even easier than this. It is acceptable to put a = body in the >>>>>> DELETE. You can store whatever fields you want accessible in your = deletion >>>>>> stubs. >>>>>=20 >>>>> **WIN** best tip of the month! --Apple-Mail=_3E33FDD4-6610-4FA3-AF30-3AC59DF489BF Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8 If = there were a way to enable this sort of feature via a flag, like = local_seq that would be a good compromise IMO. :)  I don't know = what the ramifications of this would be on performance, but would be a = 'nice to have'.

Jim Klo
Senior Software Engineer
Center for Software Engineering
SRI = International
t. = @nsomnac

On May 17, 2013, at 8:39 AM, Robert Newson <rnewson@apache.org>
&n= bsp;wrote:

Aha, ok, that makes more sense. oldDoc will be null in = that case to
match the behavior when there was never a document = there, but it's
definitely a debatable nuance. I'm in favor of the = existing behavior
but I do see your point.

B.

On 17 May = 2013 16:31, Jim Klo <jim.klo@sri.com> = wrote:
No, I think I incorrectly described = the condition where this happens.

If I first delete a doc with = extra info like you illustrated, and then re-insert the doc as new, the = VDU does not get the existing delete "stub" in my experience. If this = has changed in 1.3, I'd welcome it.

It would be useful if the VDU = got the existing "deleted" document in certain use cases, like a = document got removed for DCMA violation - I don't want it to reappear by = mistake. I'd like to have the right logic in my VDU to check the notes = in the existing deleted stub before permitting the insert. There's ways = around this which I use instead, but think that if there's a stub that = could be handed to VDU, it should.


- JK

Sent from my = iPhone

On May 17, 2013, at 7:41 AM, "Robert Newson" <rnewson@apache.org> = wrote:

VDU does receive the 'stub', = which is always a document. The term
'stub' can mislead people into = thinking a deleted document is not an
actual document (it = is).

Here I insist that deleted documents have a = reason;

=E2=9E=9C  ~  curl = localhost:5984/db1/_design/foo -XPUT = -d
'{"validate_doc_update":"function(newDoc) { if(newDoc._deleted = &&
!newDoc.reason) { throw({forbidden:\"must have a = reason\"});  } =  }"}'
{"ok":true,"id":"_design/foo","rev":"1-ab8a8ecd8cf3de35ed754= 1facfb75029"}

An empty doc;

=E2=9E=9C  ~  curl = localhost:5984/db1/bar -XPUT -d = {}
{"ok":true,"id":"bar","rev":"1-967a00dff5e02add41819138abb3284d"}
I try delete with DELETE method, which just does _id, _rev, = _deleted.

=E2=9E=9C  ~  curl = 'localhost:5984/db1/bar?rev=3D1-967a00dff5e02add41819138abb3284d'
-XDEL= ETE
{"error":"forbidden","reason":"must have a reason"}

Now I = delete with a PUT and a reason;

=E2=9E=9C curl = 'localhost:5984/db1/bar?rev=3D1-967a00dff5e02add41819138abb3284d'
-XPUT= -d '{"reason":"because I said = so","_deleted":true}'
{"ok":true,"id":"bar","rev":"2-6e10b3cc9ea15f6a9d= 81aa72aaa6e098"}

And it's really deleted;

=E2=9E=9C =  ~  curl = localhost:5984/db1/bar
{"error":"not_found","reason":"deleted"}

= And my reason is recorded;

=E2=9E=9C  ~ curl = 'localhost:5984/db1/bar?rev=3D2-6e10b3cc9ea15f6a9d81aa72aaa6e098'
{"_id= ":"bar","_rev":"2-6e10b3cc9ea15f6a9d81aa72aaa6e098","reason":"because
I= said so","_deleted":true}

B.

On 17 May 2013 14:52, Jim = Klo <jim.klo@sri.com> = wrote:
It's a great tip, my only complaint = about it is that the deleted stub doesn't get handed to the VDU = function, unless that's changed in 1.3

- Jim


On May = 17, 2013, at 12:04 AM, "Dave Cottlehuber" <dch@jsonified.com> = wrote:

On 17 May 2013 01:32, Randall = Leeds <randall.leeds@gmail.com> = wrote:
Actually, it's even easier than = this. It is acceptable to put a body in the
DELETE. You can store = whatever fields you want accessible in your = deletion
stubs.

**WIN** best tip of the = month!

= --Apple-Mail=_3E33FDD4-6610-4FA3-AF30-3AC59DF489BF-- --Apple-Mail=_F9F776AB-4D55-4CDB-86DB-C712C67FD5DC Content-Disposition: attachment; filename="smime.p7s" Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJ/zCCBO0w ggRWoAMCAQICEDJaYyWeLlo372z82sws71YwDQYJKoZIhvcNAQEFBQAwgdgxCzAJBgNVBAYTAlVT MRowGAYDVQQKExFTUkkgSW50ZXJuYXRpb25hbDEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0 d29yazE7MDkGA1UECxMyVGVybXMgb2YgdXNlIGF0IGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9y cGEgKGMpMDIxMDAuBgNVBAsTJ0NsYXNzIDIgT25TaXRlIEluZGl2aWR1YWwgU3Vic2NyaWJlciBD QTEdMBsGA1UEAxMUU1JJIEludGVybmF0aW9uYWwgQ0EwHhcNMTIxMjIyMDAwMDAwWhcNMTMwNjIw MjM1OTU5WjCBwjEaMBgGA1UEChQRU1JJIEludGVybmF0aW9uYWwxKDAmBgNVBAsUH0luZm9ybWF0 aW9uIFRlY2hub2xvZ3kgU2VydmljZXMxRjBEBgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3Np dG9yeS9DUFMgSW5jb3JwLiBieSBSZWYuLExJQUIuTFREKGMpOTkxEjAQBgNVBAMTCUphbWVzIEts bzEeMBwGCSqGSIb3DQEJARYPamltLmtsb0BzcmkuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEArcAbsKPrj0OY8eP+7cwOoUFxQcaL/voNDjR7tLexnZxcS97AyPjJokX5B4ayC7Mh oqvbgdFXf74mZIwKtoMIpf3SDopp68M2sTbhII4weZzn1yYLnVB8p1dH3h2hZDS+AHDY3qAchch0 C5aGQ/ahgJDAhgEiJ/NCbyFAboIhrDsyRS3XxyIlegbrYh9JYRaWdgoxZ21cdJG2xDUPyv/cLVam XKexUqXFLIKH7KKFFwAmVBj6BhZsjjgbMlC1AF3yV2TppULrSS1tDQdHWh5dL+Mw+QXS1O49W0hZ 7V1xFEXvqVj8SdGOaCAphVIU6RPAg7AEiAMynx/sdF5UMZsJuQIDAQABo4IBRjCCAUIwCQYDVR0T BAIwADCBrAYDVR0gBIGkMIGhMIGeBgtghkgBhvhFAQcXAjCBjjAoBggrBgEFBQcCARYcaHR0cHM6 Ly93d3cudmVyaXNpZ24uY29tL0NQUzBiBggrBgEFBQcCAjBWMBUWDlZlcmlTaWduLCBJbmMuMAMC AQEaPVZlcmlTaWduJ3MgQ1BTIGluY29ycC4gYnkgcmVmZXJlbmNlIGxpYWIuIGx0ZC4gKGMpOTcg VmVyaVNpZ24wCwYDVR0PBAQDAgWgMBEGCWCGSAGG+EIBAQQEAwIHgDBmBgNVHR8EXzBdMFugWaBX hlVodHRwOi8vb25zaXRlY3JsLnZlcmlzaWduLmNvbS9TUklJbnRlcm5hdGlvbmFsSW5mb3JtYXRp b25UZWNobm9sb2d5U2VydmljZXMvTGF0ZXN0Q1JMMA0GCSqGSIb3DQEBBQUAA4GBAMShtqQuVGbd YU5ZlqbBxf9ejMIfFgBIn7wubcTIyCAN2nIiDaAqmgS6eE8QiV6A2AchRz87CTQXDH+lkHaSgMiI MtW+n78v+kOLauCqau5iQ2vOwmBx+ypTVu1yV1JQ8GhwQl8hbHaKsVULtlBnPlbCMCgtf4XDBHOL CDLxEJN5MIIFCjCCBHOgAwIBAgIQFnwAoITZjkQu1m3KBG96NzANBgkqhkiG9w0BAQUFADCBwTEL MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTwwOgYDVQQLEzNDbGFzcyAyIFB1 YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIxOjA4BgNVBAsTMShjKSAx OTk4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAsTFlZl cmlTaWduIFRydXN0IE5ldHdvcmswHhcNMDIwOTIzMDAwMDAwWhcNMTMxMjMxMjM1OTU5WjCB2DEL MAkGA1UEBhMCVVMxGjAYBgNVBAoTEVNSSSBJbnRlcm5hdGlvbmFsMR8wHQYDVQQLExZWZXJpU2ln biBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQgaHR0cHM6Ly93d3cudmVy aXNpZ24uY29tL3JwYSAoYykwMjEwMC4GA1UECxMnQ2xhc3MgMiBPblNpdGUgSW5kaXZpZHVhbCBT dWJzY3JpYmVyIENBMR0wGwYDVQQDExRTUkkgSW50ZXJuYXRpb25hbCBDQTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAzvnUwmuZmBSSAFVb0qoC0hhUL1a6f+AIHw5UpxW5oRTjsDtUzsCa+6Yg GvKUlisrnI/tPZFrupvHVNQjRj05fhHiABFinwlnCA7J80x3gZlBMwHrgoKYribJ1GTVmc1R0FmA B4KYzBeZjJZiNpqLEsEb0ORdzJYb2/UZazjL/fkCAwEAAaOCAegwggHkMBIGA1UdEwEB/wQIMAYB Af8CAQAwRAYDVR0gBD0wOzA5BgtghkgBhvhFAQcXAjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3 dy52ZXJpc2lnbi5jb20vcnBhMDQGA1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwudmVyaXNpZ24u Y29tL3BjYTItZzIuY3JsMAsGA1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAQYwKAYDVR0RBCEw H6QdMBsxGTAXBgNVBAMTEFByaXZhdGVMYWJlbDItODIwHQYDVR0OBBYEFC1OfgnwbUVBEaxx2j87 9iZKf2RkMIHoBgNVHSMEgeAwgd2hgcekgcQwgcExCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJp U2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9u IEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBh dXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrghEAuS9g zIifoXpGCbhbcGyKrzANBgkqhkiG9w0BAQUFAAOBgQBocPsx9foGtLlCL8coGlfjYx8GhbDYbdQ3 8w0P/BIw4D49KhAocMcivLESZiV8YYYFFx+ozAPtg0j0knx+tcdeDvWmSefavP+aKlRhpAWk5Z+n c34jLXdw9/+6WveM/OQQbPbd8asD6BsLcFlRm68KZY8kk7SjlsP1S6rQBiCX8jGCBHswggR3AgEB MIHtMIHYMQswCQYDVQQGEwJVUzEaMBgGA1UEChMRU1JJIEludGVybmF0aW9uYWwxHzAdBgNVBAsT FlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczov L3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTAyMTAwLgYDVQQLEydDbGFzcyAyIE9uU2l0ZSBJbmRp dmlkdWFsIFN1YnNjcmliZXIgQ0ExHTAbBgNVBAMTFFNSSSBJbnRlcm5hdGlvbmFsIENBAhAyWmMl ni5aN+9s/NrMLO9WMAkGBSsOAwIaBQCgggJiMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJ KoZIhvcNAQkFMQ8XDTEzMDUxNzE2MjkwN1owIwYJKoZIhvcNAQkEMRYEFLSliwCD94hoWMY+ops1 u2BUeERRMIH+BgkrBgEEAYI3EAQxgfAwge0wgdgxCzAJBgNVBAYTAlVTMRowGAYDVQQKExFTUkkg SW50ZXJuYXRpb25hbDEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazE7MDkGA1UECxMy VGVybXMgb2YgdXNlIGF0IGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9ycGEgKGMpMDIxMDAuBgNV BAsTJ0NsYXNzIDIgT25TaXRlIEluZGl2aWR1YWwgU3Vic2NyaWJlciBDQTEdMBsGA1UEAxMUU1JJ IEludGVybmF0aW9uYWwgQ0ECEDJaYyWeLlo372z82sws71YwggEABgsqhkiG9w0BCRACCzGB8KCB 7TCB2DELMAkGA1UEBhMCVVMxGjAYBgNVBAoTEVNSSSBJbnRlcm5hdGlvbmFsMR8wHQYDVQQLExZW ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQgaHR0cHM6Ly93 d3cudmVyaXNpZ24uY29tL3JwYSAoYykwMjEwMC4GA1UECxMnQ2xhc3MgMiBPblNpdGUgSW5kaXZp ZHVhbCBTdWJzY3JpYmVyIENBMR0wGwYDVQQDExRTUkkgSW50ZXJuYXRpb25hbCBDQQIQMlpjJZ4u WjfvbPzazCzvVjANBgkqhkiG9w0BAQEFAASCAQBPvoEcfGEy30ctFEK32KE6Ckyl5wr8GCak26sa O3UCw0ktxUr7ynSNNtNOkWRYLmR3MkRvmsm0C6hY64O1xNW2rhrBGaaZ9QLQsvGhhAlbYcLSzJtj 7oV5L4Ilh8vHlw7VQPRfKZd6KsqzJqlC/FXOnEmjksN7iv3v+req0OEQvsueGQ7byG0BYm5o1rK0 +R1302FXdgK1OlDciI+BWz59A6J7sW0Mpv4RBAKA01yE45rYP58q85yIgx1HBfcEX/pR2/eqr4BB Mux841UHFfkZyQeXpNM+qzBi1WsYbhDS0S8CazVslgXMLV73b4BlfO8c+DcNNf5AVoTHyIo5aN6o AAAAAAAA --Apple-Mail=_F9F776AB-4D55-4CDB-86DB-C712C67FD5DC--