From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp1.migadu.com ([2001:41d0:303:e224::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms13.migadu.com with LMTPS id uK0kNH5jy2ZZMgEA62LTzQ:P1 (envelope-from ) for ; Sun, 25 Aug 2024 17:01:50 +0000 Received: from aspmx1.migadu.com ([2001:41d0:303:e224::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp1.migadu.com with LMTPS id uK0kNH5jy2ZZMgEA62LTzQ (envelope-from ) for ; Sun, 25 Aug 2024 19:01:50 +0200 X-Envelope-To: larch@yhetil.org Authentication-Results: aspmx1.migadu.com; dkim=fail ("body hash did not verify") header.d=uni-muenster.de header.s=uniout header.b="UFUN/H4L"; dmarc=none; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1724605310; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=O0QOZvHqdG8Z0lJI4yN8Ey9+Jd0KvD1t1f53AJkZe5c=; b=GIo82dVb1R/dST26hI/At6d7RG5A3a1XiRHRfRShWDJjcAd8DwsmOr5WmUacND6oHSLSow 907nPlcW+Vl49JVYbpGx0pwDhTQzboMvK6SgI6FWOVnwhEYXuyYEAeyz+E6sz6JF9m+BGi Qv8eymPWW6pY925yM3mez7+sbHN3Bk/ULz/Lm9sYQRj/Qxfa82GDBbEPrOjoEhDOddiOq4 vameFzMueBxkEjiyzBvww1JQeMVOwPmnjWfwBE6IsDql+JIhWj1TcNey2qQ7g6LawDWg2U 9kdh+LtPq/HUKScGew/WUu4wJDFfslnKjg4Tz1jfQOEkxN0SfRFCy//ElvEHBw== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1724605310; a=rsa-sha256; cv=none; b=JWeaIublDq7bfBbhVM2rU9GzU+8CHTfNJakTXJ1leolCy/W7cj/ib1GNYEvz9FEhuEZXTz gmmYXrkM0oejZ7D4ryTWC3o7//qy9YxP2NqL35Ny8RDLVU59L48RsvOmYGxPPwkuaHht5F UAisjFsBtyvroz8v0Q6OztTFHpYfyUXxAXNhA1ejGIowPvA1SmE/7MHw3+doXgrXO22c7I QFgML4uk3s8WzFAUqhWBET3ZGOkdwGjbGjvfFGe8yJ7tKKsQPrHOHRa0DgE99RTWQd4UXJ 0DPUXibCX8UFSsOUEfu6dhLisnTeJMZuMQ5yN8dv+5ysqRGUaFYX4VTmwutoCg== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("body hash did not verify") header.d=uni-muenster.de header.s=uniout header.b="UFUN/H4L"; dmarc=none; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 66D6C139FB for ; Sun, 25 Aug 2024 19:01:50 +0200 (CEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1siGbr-00058H-58; Sun, 25 Aug 2024 13:00:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1siGbS-00055b-UB for emacs-orgmode@gnu.org; Sun, 25 Aug 2024 13:00:43 -0400 Received: from udcm-wwu2.uni-muenster.de ([128.176.118.28]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1siGbO-0003Sb-Pe; Sun, 25 Aug 2024 13:00:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uni-muenster.de; i=@uni-muenster.de; q=dns/txt; s=uniout; t=1724605230; x=1756141230; h=from:to:cc:subject:in-reply-to:references:date: message-id:mime-version; bh=Y/G0iyPhbB98jlBCN1OKySCCzf8oJLVas9vyFDknMd0=; b=UFUN/H4LnmBNqTYonfALup+MhMrN3BWfD5g84CZJifPv7PRwHQdlyYGN fTumfu7lHuxeBAh6T/d1KPB1exGeHhETPeqbcOPDv+PANuCQyv/AUcX4V 8hsm2n9Be4bEzVNoC52ujHQ8f0IOhdhK9dF87yAtl8H9p+GWInorlBK1b MuOJ8CN0CGRyBox7xgVO1+95xvh6XAda2vbk/qi+bRXEEHlIJos5nt88Y /aWCRCtzI9q6C1HsgD7e0LEvLohs8C5Ok1INMi0vQTgAmSmENwcUKUZIA eNrvZAR8W/3PUyYbWSkPeabEpvWEoav9BlvJkUoDJL0PbrbwzFMVECHtM w==; X-CSE-ConnectionGUID: DVbnrJW7QOmdMFVuEkSGSg== X-CSE-MsgGUID: WRgsv0dcQpyRHK+GVR+DqA== X-IronPort-AV: E=Sophos;i="6.10,175,1719871200"; d="p7s'346?scan'346,208,346,223";a="333922326" Received: from wiwi-ex-1.wiwi.uni-muenster.de (HELO mail.wiwi.uni-muenster.de) ([10.2.21.33]) by UDCM-RELAY2.UNI-MUENSTER.DE with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 25 Aug 2024 19:00:21 +0200 Received: from D-3170L03 (128.176.63.9) by WIWI-EX-1.WIWI.UNI-MUENSTER.DE (10.2.21.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Sun, 25 Aug 2024 19:00:21 +0200 From: Jens Lechtenboerger To: Ihor Radchenko CC: Eli Zaretskii , Subject: Re: Proposal: Change publication timestamps In-Reply-To: <87o75t1vy9.fsf@localhost> (Ihor Radchenko's message of "Thu, 15 Aug 2024 18:29:18 +0000") References: <86ed921oxu.fsf@gnu.org> <874j9vllbp.fsf@localhost> <87y177pqzm.fsf@wi.uni-muenster.de> <87a5jnk347.fsf@localhost> <87bk1yxjhw.fsf_-_@wi.uni-muenster.de> <87o75t1vy9.fsf@localhost> Mail-Followup-To: Ihor Radchenko , Eli Zaretskii , emacs-orgmode@gnu.org Date: Sun, 25 Aug 2024 19:00:15 +0200 Message-ID: <87le0kleqo.fsf@wi.uni-muenster.de> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: multipart/signed; boundary="==-=-="; micalg=sha384; protocol="application/pkcs7-signature" X-Originating-IP: [128.176.63.9] X-ClientProxiedBy: WIWI-EX-1.WIWI.UNI-MUENSTER.DE (10.2.21.33) To WIWI-EX-1.WIWI.UNI-MUENSTER.DE (10.2.21.33) Received-SPF: pass client-ip=128.176.118.28; envelope-from=Jens.Lechtenboerger@wi.uni-muenster.de; helo=UDCM-WWU2.UNI-MUENSTER.DE X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: emacs-orgmode-bounces+larch=yhetil.org@gnu.org X-Migadu-Flow: FLOW_IN X-Migadu-Country: US X-Migadu-Queue-Id: 66D6C139FB X-Migadu-Scanner: mx12.migadu.com X-Migadu-Spam-Score: -7.48 X-Spam-Score: -7.48 X-TUID: 7Qz09GquL1x1 --==-=-= Content-Type: multipart/mixed; boundary="=-=-=" --=-=-= Content-Type: text/plain On 2024-08-15, Ihor Radchenko wrote: > Jens Lechtenboerger writes: > >>> See "14.4 Triggering Publication" section of Org mode manual: >>> >>> Org uses timestamps to track when a file has changed. The above >>> functions normally only publish changed files. You can override this >>> [...] >> >> I propose to change caching and checking of timestamps as in the >> attached path. > > The patch looks reasonable. > Applied, onto main. > https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=38d1bc67b2 Great, thanks! > Ideally, it would be nice to have tests as well. I added test cases in the attached patch. Best wishes, Jens --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Add-test-case-for-publish-cache.patch Content-Transfer-Encoding: quoted-printable From=20bc20910287edad8b6740acdaa065e93100355405 Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Jens=3D20Lechtenb=3DC3=3DB6rger?=3D Date: Sun, 25 Aug 2024 18:52:59 +0200 Subject: [PATCH] Add test case for publish cache =2D-- testing/examples/pub-cache/config.org | 3 + testing/examples/pub-cache/source.org | 4 ++ testing/lisp/test-ox-publish.el | 98 +++++++++++++++++++++++++-- 3 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 testing/examples/pub-cache/config.org create mode 100644 testing/examples/pub-cache/source.org diff --git a/testing/examples/pub-cache/config.org b/testing/examples/pub-c= ache/config.org new file mode 100644 index 000000000..70628d3af =2D-- /dev/null +++ b/testing/examples/pub-cache/config.org @@ -0,0 +1,3 @@ +#+OPTIONS: author:nil + +This is included. diff --git a/testing/examples/pub-cache/source.org b/testing/examples/pub-c= ache/source.org new file mode 100644 index 000000000..7072f560e =2D-- /dev/null +++ b/testing/examples/pub-cache/source.org @@ -0,0 +1,4 @@ +#+TITLE: Test +#+INCLUDE: config.org + +Nothing special diff --git a/testing/lisp/test-ox-publish.el b/testing/lisp/test-ox-publish= .el index 6419b8f6c..a8127ccf2 100644 =2D-- a/testing/lisp/test-ox-publish.el +++ b/testing/lisp/test-ox-publish.el @@ -24,7 +24,9 @@ ;;; Helper functions =20 =2D(defun org-test-publish (properties handler &optional remove-prop) +(defun org-test-publish + (properties handler + &optional remove-prop timestamp-flag pubdir keep-pubdir-p) "Publish a project defined by PROPERTIES. Call HANDLER with the publishing directory as its sole argument. Unless set otherwise in PROPERTIES, `:base-directory' is set to @@ -33,12 +35,17 @@ Unless set otherwise in PROPERTIES, `:base-directory' i= s set to Because `org-publish-property' uses `plist-member' to check the existence of a property, a property with a value nil is different from a non-existing property. Properties in REMOVE-PROP will be =2Dremoved from the final plist." +removed from the final plist. +Assign optional TIMESTAMP-FLAG to `org-publish-use-timestamps-flag'. +Optional PUBDIR specifies the `:publishing-directory', which +overrides the default of a randomly generated temporary directory. +If optional KEEP-PUBDIR-P is non-nil, keep publishing directory, +including timestamp directory; otherwise, delete it." (declare (indent 1)) =2D (let* ((org-publish-use-timestamps-flag nil) + (let* ((org-publish-use-timestamps-flag timestamp-flag) (org-publish-cache nil) (base-dir (expand-file-name "examples/pub/" org-test-dir)) =2D (pub-dir (make-temp-file "org-test" t)) + (pub-dir (or pubdir (make-temp-file "org-test" t))) (org-publish-timestamp-directory (expand-file-name ".org-timestamps/" pub-dir)) (props (org-plist-delete-all @@ -54,8 +61,9 @@ removed from the final plist." (progn (org-publish-projects (list project)) (funcall handler pub-dir)) =2D ;; Clear published data. =2D (delete-directory pub-dir t) + (unless keep-pubdir-p + ;; Clear published data. + (delete-directory pub-dir t)) ;; Delete auto-generated site-map file, if applicable. (let ((site-map (and (plist-get properties :auto-sitemap) (expand-file-name @@ -69,7 +77,7 @@ removed from the final plist." ;;; Mandatory properties =20 (ert-deftest test-org-publish/base-extension () =2D "Test `:base-extension' specifications" + "Test `:base-extension' specifications." ;; Regular tests. (should (equal '("a.org" "b.org") @@ -114,6 +122,82 @@ removed from the final plist." (equal (org-test-publish nil func '(:publishing-function)) (org-test-publish '(:publishing-function org-html-publish-to-ht= ml) func))))) =20 + +;;; Publish cache + +(defun org-test-publish-touch (file) + "Change the modification time of FILE." + (let ((buf (get-file-buffer file))) + (when buf + (kill-buffer buf))) + (find-file file) + (set-buffer-modified-p t) + (save-buffer 0)) + +(ert-deftest test-org-publish/publish-cache () + "Test publish cache based on timestamps. +Publish a source file, which includes a config file, to HTML. +Test updates of source and config file." + (let* ((base (expand-file-name "examples/pub-cache/" org-test-dir)) + (source (expand-file-name "source.org" base)) + (config (expand-file-name "config.org" base)) + (pub-dir (make-temp-file "org-test" t)) + (html (expand-file-name "source.html" pub-dir)) + (plist `(:publishing-function org-html-publish-to-html + :base-extension nil + :base-directory ,base + :exclude "." + :include ("source.org"))) + (handler (lambda (dir) + (remove ".org-timestamps" + (cl-remove-if #'file-directory-p + (directory-files dir)))))) + (should + ;; Publish HTML from source.org for the first time. + (equal '("source.html") + (org-test-publish plist handler nil t pub-dir t))) + (let ((hmtime (org-publish-cache-mtime-of-src html))) + (sleep-for 0.1) + ;; Publish again, without source changes. + ;; Should not publish, but keep the HTML file unchanged. + (org-test-publish plist handler nil t pub-dir t) + (should + (equal hmtime + (org-publish-cache-mtime-of-src html))) + + ;; Pretend the source has changed. + ;; Publish again, with a new mtime. + (org-test-publish-touch source) + (org-test-publish plist handler nil t pub-dir t) + (let ((hmtime2 (org-publish-cache-mtime-of-src html))) + (should + (time-less-p hmtime hmtime2)) + + (sleep-for 0.1) + ;; Publish again, without source changes. + ;; Does not publish, but keeps the HTML file unchanged. + (org-test-publish plist handler nil t pub-dir t) + (should + (equal hmtime2 + (org-publish-cache-mtime-of-src html))) + + ;; Pretend file config.org has changed. + ;; Publish again, with a new mtime. + (org-test-publish-touch config) + (org-test-publish plist handler nil t pub-dir t) + (let ((hmtime3 (org-publish-cache-mtime-of-src html))) + (should + (time-less-p hmtime2 hmtime3)) + + (sleep-for 0.1) + ;; Publish again, without source changes. + ;; Should not publish, but keep the HTML file unchanged. + (org-test-publish plist handler nil t pub-dir t) + (should + (equal hmtime3 + (org-publish-cache-mtime-of-src html)))))) + (delete-directory pub-dir t))) + ;;; Site-map =20 =2D-=20 2.25.1 --=-=-=-- --==-=-= Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgIFADCABgkqhkiG9w0BBwEAAKCCFL0w ggWBMIIEaaADAgECAhA5ckQ6+SK3UdfTbBDdMTWVMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYT AkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNV BAoMEUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2VydmljZXMw HhcNMTkwMzEyMDAwMDAwWhcNMjgxMjMxMjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNU IE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2Hi qiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwW IJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2VN3I5xI6Ta5M irdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq/nROacdrjGCT3sTHDN/h Mq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303 p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugT ncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9Jnn V4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeEHg9j1uli utZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo4HyMIHvMB8GA1UdIwQYMBaAFKAR CiM+lvEH7OKvKe+CpX/QMKS0MB0GA1UdDgQWBBRTeb9aqitKz1SA4dibwJ3ysgNmyzAOBgNVHQ8B Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zARBgNVHSAECjAIMAYGBFUdIAAwQwYDVR0fBDwwOjA4 oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww NAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJ KoZIhvcNAQEMBQADggEBABiHUdx0IT2ciuAntzPQLszs8ObLXhHeIm+bdY6ecv7k1v6qH5yWLe8D Sn6u9I1vcjxDO8A/67jfXKqpxq7y/Njuo3tD9oY2fBTgzfT3P/7euLSK8JGW/v1DZH79zNIBoX19 +BkZyUIrE79Yi7qkomYEdoiRTgyJFM6iTckys7roFBq8cfFb8EELmAAKIgMQ5Qyx+c2SNxntO/Hk Orb5RRMmda+7qu8/e3c70sQCkT0ZANMXXDnbP3sYDUXNk4WWL13fWRZPP1G91UUYP+1KjugGYXQj FrUNUHMnREd/EF2JKmuFMRTE6KlqTIC8anjPuH+OdnKZDJ3+15EIFqGjX5UwggbmMIIEzqADAgEC AhAxAnDUNb6bJJr4VtDh4oVJMA0GCSqGSIb3DQEBDAUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UE CBMKTmV3IEplcnNleTEUMBIGA1UEBxMLSmVyc2V5IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJV U1QgTmV0d29yazEuMCwGA1UEAxMlVVNFUlRydXN0IFJTQSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 eTAeFw0yMDAyMTgwMDAwMDBaFw0zMzA1MDEyMzU5NTlaMEYxCzAJBgNVBAYTAk5MMRkwFwYDVQQK ExBHRUFOVCBWZXJlbmlnaW5nMRwwGgYDVQQDExNHRUFOVCBQZXJzb25hbCBDQSA0MIICIjANBgkq hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAs0riIl4nW+kEWxQENTIgFK600jFAxs1QwB6hRMqvnkph fy2Q3mKbM2otpELKlgE8/3AQPYBo7p7yeORuPMnAuA+oMGRb2wbeSaLcZbpwXgfCvnKxmq97/kQk OFX706F9O7/h0yehHhDjUdyMyT0zMs4AMBDRrAFn/b2vR3j0BSYgoQs16oSqadM3p+d0vvH/YrRM tOhkvGpLuzL8m+LTAQWvQJ92NwCyKiHspoP4mLPJvVpEpDMnpDbRUQdftSpZzVKTNORvPrGPRLnJ 0EEVCHR82LL6oz915WkrgeCY9ImuulBn4uVsd9ZpubCgM/EXvVBlViKqusChSsZEn7juIsGIiDya IhhLsd3amm8BS3bgK6AxdSMROND6hiHT182Lmf8C+gRHxQG9McvG35uUvRu8v7bPZiJRaT7ZC2f5 0P4lTlnbLvWpXv5yv7hheO8bMXltiyLweLB+VNvg+GnfL6TW3Aq1yF1yrZAZzR4MbpjTWdEdSLKv z8+0wCwscQ81nbDOwDt9vyZ+0eJXbRkWZiqScnwAg5/B1NUD4TrYlrI4n6zFp2pyYUOiuzP+as/A Znz63GvjFK69WODR2W/TK4D7VikEMhg18vhuRf4hxnWZOy0vhfDR/g3aJbdsGac+diahjEwzyB+U KJOCyzvecG8bZ/u/U8PsEMZg07iIPi8CAwEAAaOCAYswggGHMB8GA1UdIwQYMBaAFFN5v1qqK0rP VIDh2JvAnfKyA2bLMB0GA1UdDgQWBBRpAKHHIVj44MUbILAK3adRvxPZ5DAOBgNVHQ8BAf8EBAMC AYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwOAYD VR0gBDEwLzAtBgRVHSAAMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMFAG A1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0 aWZpY2F0aW9uQXV0aG9yaXR5LmNybDB2BggrBgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0dHA6 Ly9jcnQudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNydDAlBggrBgEFBQcw AYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEACgVOew2PHxM5 AP1v7GLGw+3tF6rjAcx43D9Hl110Q+BABABglkrPkES/VyMZsfuds8fcDGvGE3o5UfjSno4sij0x dKut8zMazv8/4VMKPCA3EUS0tDUoL01ugDdqwlyXuYizeXyH2ICAQfXMtS+raz7mf741CZvO50Ox MUMxqljeRfVPDJQJNHOYi2pxuxgjKDYx4hdZ9G2o+oLlHhu5+anMDkE8g0tffjRKn8I1D1BmrDdW R/IdbBOj6870abYvqys1qYlPotv5N5dm+XxQ8vlrvY7+kfQaAYeO3rP1DM8BGdpEqyFVa+I0rpJP haZkeWW7cImDQFerHW9bKzBrCC815a3WrEhNpxh72ZJZNs1HYJ+29NTB6uu4NJjaMxpk+g2puNSm 4b9uVjBbPO9V6sFSG+IBqE9ckX/1XjzJtY8Grqoo4SiRb6zcHhp3mxj3oqWi8SKNohAOKnUc7RIP 6ss1hqIFyv0xXZor4N9tnzD0Fo0JDIURjDPEgo5WTdti/MdGTmKFQNqxyZuT9uSI2Xvhz8p+4pCY kiZqpahZlHqMFxdw9XRZQgrP+cgtOkWEaiNkRBbvtvLdp7MCL2OsQhQEdEbUvDM9slzZXdI7NjJo kVBq3O4pls3VD2z3L/bHVBe0rBERjyM2C/HSIh84rfmAqBgklzIOqXhd+4RzadUwgghKMIIGMqAD AgECAhEAqkvi71CAEFxqZ4YPA1N9LTANBgkqhkiG9w0BAQwFADBGMQswCQYDVQQGEwJOTDEZMBcG A1UEChMQR0VBTlQgVmVyZW5pZ2luZzEcMBoGA1UEAxMTR0VBTlQgUGVyc29uYWwgQ0EgNDAeFw0y MjA1MTcwMDAwMDBaFw0yNTA1MTYyMzU5NTlaMIHwMQ4wDAYDVQQREwU0ODE0OTE1MDMGA1UEChMs V2VzdGZhZWxpc2NoZSBXaWxoZWxtcy1Vbml2ZXJzaXRhZXQgTXVlbnN0ZXIxFzAVBgNVBAkTDlNj aGxvc3NwbGF0eiAyMRwwGgYDVQQIExNOb3JkcmhlaW4tV2VzdGZhbGVuMREwDwYDVQQHDAhNw7xu c3RlcjELMAkGA1UEBhMCREUxHDAaBgNVBAMME0plbnMgTGVjaHRlbmLDtnJnZXIxMjAwBgkqhkiG 9w0BCQEWI2plbnMubGVjaHRlbmJvZXJnZXJAdW5pLW11ZW5zdGVyLmRlMIICIjANBgkqhkiG9w0B AQEFAAOCAg8AMIICCgKCAgEA4yLo33Fy6yODnDt0cuQvfxDd3lnsuNenB614hQB3kjb3cgHa1pA/ gNxGX4s1X4f9DeUbOuz0S0dHEYFcDByTpXDTOLsrA/I9vZ33GadnOwwFPevEn+ZegP92IT4vabIr fX9onRap8lcdV2MAMAnIUkvTykJmT31NFPzikecZAj8yRfSVdOYXYtqnBkCPsohTuo1R/xgo5hZA thHzENZ/0awwUocqydgxiiVr4bY47NzsHyB3s5aMAgmxszZ72Ya0SiyuQNomHvfqx/LccgcLRVeL bMniWy0zKUPfMsIHYLxKuz88og/hThCGylkZUxZ9ftDcI0yTuAKPgFgG1LME6SurW66XDOKUPOlZ 2qM7quHxDzfnhWyrXq4jK+KF54zWtVwrD4rqGvGP8RtoNaqGmUlJ9t1NycE2+w0UNTy60aOscthN s7nEMqU0MWJXymRxWB3svNOc3AfgCygNppmzMs+r/ZQVo9IvLlDZqmf+58IEDZgscVVWKvHqcsDR nZMdiURrOeEyFS0vUE04xZqlB8mCCd1bbwZ30JNJOZczRw7Uf142qbQvYtH/eIYcLeubNREzzvXc ZQrK1KcZdICk/w0MbUY94qcNEJFz46CRZapVRGyp0IW4G4t79Tcd+YEcqmVC2p9BDF+tpPBUTRAG TXh0VtCrRCMHAkZd6bArdd0CAwEAAaOCAoYwggKCMB8GA1UdIwQYMBaAFGkAocchWPjgxRsgsArd p1G/E9nkMB0GA1UdDgQWBBToJ4jbFf9An5mspQ0MDfjOqaWItjAOBgNVHQ8BAf8EBAMCBaAwDAYD VR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDBAYIKwYBBQUHAwIwPwYDVR0gBDgwNjA0Bgsr BgEEAbIxAQICTzAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3RpZ28uY29tL0NQUzBCBgNVHR8E OzA5MDegNaAzhjFodHRwOi8vR0VBTlQuY3JsLnNlY3RpZ28uY29tL0dFQU5UUGVyc29uYWxDQTQu Y3JsMHgGCCsGAQUFBwEBBGwwajA9BggrBgEFBQcwAoYxaHR0cDovL0dFQU5ULmNydC5zZWN0aWdv LmNvbS9HRUFOVFBlcnNvbmFsQ0E0LmNydDApBggrBgEFBQcwAYYdaHR0cDovL0dFQU5ULm9jc3Au c2VjdGlnby5jb20wggECBgNVHREEgfowgfeBGmxlY2h0ZW5Ad2kudW5pLW11ZW5zdGVyLmRlgQ5s ZWNodGVqQHd3dS5kZYEXbGVjaHRlakB1bmktbXVlbnN0ZXIuZGWBKWplbnMubGVjaHRlbmJvZXJn ZXJAZXJjaXMudW5pLW11ZW5zdGVyLmRlgRxsZWNodGVqK3tJRH1AdW5pLW11ZW5zdGVyLmRlgSZq ZW5zLmxlY2h0ZW5ib2VyZ2VyQHdpLnVuaS1tdWVuc3Rlci5kZYEaamVucy5sZWNodGVuYm9lcmdl ckB3d3UuZGWBI2plbnMubGVjaHRlbmJvZXJnZXJAdW5pLW11ZW5zdGVyLmRlMA0GCSqGSIb3DQEB DAUAA4ICAQAr3vuH36/HktCaRQa41rdgEEep3WbnlgjjN+Sl1CA/WGns2iwgTaS+WRKLTW9O3Y2N i4S9xFT5XezUAAkU7Z6GJjWyRiF2JS+Pb6XHmqXAjKxQqDpTT6/m3E+Vv8rBI0eEL5wiVSOQvZlt BU055MLEIYaWlDErzl5OCviWM2O+m88S4hIkRXIoUkyl2DSiDwihwLjZCX9Y4gRUPUuLiuJKStar wbknlvskOa2ugD3qKUxQh2QhpEKyEOSY7Tax30C6mXI+iINZVGETQNn8ZYZKEojOqzTvuWcD9XyA t/q9x/EiDlCaEdk4mwGcV/fW1bPfu7xFIz7GFrpS4fzVb3TSR91cyh0lEVK0mc5fNZN4wwaRP/hY PVywTRwOzWTCCVdjEZo33wbl6YXoCDsqudtbmqbhqrgYtKUnqSIooYMg8eX7NrSNi7NGi62Yt6gC 819l5Bw1rzWD0CkJ4mClaS3Byh7V9TaItJa5IEbx+l+z1esROAkkc0UD3Gqji3WPeSgUHr5aKlM7 fM46RSB8CD2ko3IdH3Lyu43sFyK2ujpx+814ASePaEIgqeyerMf+rPs5IhoOvzsrV8pvuvADWEZt pMRrfyQnQnUQlTGSNxQsZwTjpIPv/WewvujgWIwU0jC2yR7MQ4GtCtsjmzfBsGx/9L+C49R+U8Xq sP3AY0BXDzGCAywwggMoAgEBMFswRjELMAkGA1UEBhMCTkwxGTAXBgNVBAoTEEdFQU5UIFZlcmVu aWdpbmcxHDAaBgNVBAMTE0dFQU5UIFBlcnNvbmFsIENBIDQCEQCqS+LvUIAQXGpnhg8DU30tMA0G CWCGSAFlAwQCAgUAoIGjMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8X DTI0MDgyNTE3MDAxNVowKAYJKoZIhvcNAQkPMRswGTALBglghkgBZQMEAQIwCgYIKoZIhvcNAwcw PwYJKoZIhvcNAQkEMTIEMMzPV2YeKr9i848kuMP5iIBZ0QsS1+/+8tWTdHu5SOhlQa3QTQ16beeD s7ZONQ0a5jANBgkqhkiG9w0BAQEFAASCAgDNGmFBuf+YYxf5fWwfIRxuPL/jqg9AoMu8HBOUBeGl WHwE5KLRpjPzZToAgauMNMe+2pEpMDQiKRxQkj6AzLKEPtHsF1+6bXm7VHBag3R51k3CtnBNS5yk HdX3iYwijwb+g/wRVbHI6qx4lTR3W3o0dQQRdYgmTBitRG2Pggdh9mJDdImSkjJy5TG94r8LCQJZ qpan8c+VjrNXBLRvUOMBePL15oJASoD2Byv5QjUTViQaH/zOSq3cwfXrowbtvVf0nrxFfMpRsXll LBr7zz/dCzLqXfHN942MhosfBy0IJ1XdnuV2YbWvbiohDwwkYiDF51QwkhUnFFvQIaQ1Q1kdUz4G nybaSi8NR426CglYsctQnL05rhWYuddb6XKZsvw4PAnSO5aUuqA439P3jOi87JBnGJM3FImdACNe JLa9kK1iZjv2+xTyPMB/D1QIiWEQupjGIsUCP/m9ypfCpnTG4qpBD0uQoewD51ReUcAOFZAFVDhg yMa1CpLXIkvtumAEpBNHj4IZFrQsFYtk1g5jzL8C+1B+MCF6OzMXsVNJ8VEuWppqCE1cVSsxBdso hhPj6Y8jjTSnVEVEflsBKEmbrW86n67dHwtxQ3UIm+QL8fUeBi3fdjrEQT8hUJJpungettY/p/sW eqwju5c8KcwjmYE7Tz4SeKUGlkFMpUiQQAAAAAAAAA== --==-=-=--