From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp0.migadu.com ([2001:41d0:303:5f26::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms8.migadu.com with LMTPS id MOUWFe8pjWVj1wAAkFu2QA (envelope-from ) for ; Thu, 28 Dec 2023 08:55:27 +0100 Received: from aspmx1.migadu.com ([2001:41d0:403:58f0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp0.migadu.com with LMTPS id MLCxDu8pjWXxhQEAqHPOHw (envelope-from ) for ; Thu, 28 Dec 2023 08:55:27 +0100 X-Envelope-To: larch@yhetil.org Authentication-Results: aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=gmail.com header.s=20230601 header.b=dh+5zuAe; spf=pass (aspmx1.migadu.com: domain of "guix-devel-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-devel-bounces+larch=yhetil.org@gnu.org"; dmarc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1703750127; 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=vBTA6fTZsr0v9GER1H9JZCgI42ZKbhcZJRNsfQoK03A=; b=JrdEZTrWhSM/K38hluyZ1pvtJVo+WCmX2IpY/fFpjJoRGMcQMi5JmsyGQXJ4S8eNyYf73R 98E5tn9Bwmk1NVjN5gU/5VkqPz31EdxuJVWynkRg5r2ZJ740LCXSyyATGigsEx8qRA1lRR r0H1UD7JprxIfuoNb6Oaxc+QozL9ubdfryiGD0dsSKcQW2JcVYMcViJOtr7qg0Y+Vkxq99 Aq3TEDrqOagVxNuMYgOnpFLCAJSUrX5+ok/Zs6Dt/pVrI0Y1PoRw4gwCohejVU+sP5zXqf BgzxNyJliihZX/5dH4XFFecVy+5mcb+Xh0F8oaLD5R432mscxkq1IOskwQFYhw== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1703750127; a=rsa-sha256; cv=none; b=AY7PyskVTKUj49CtGNzux3whcsnwooeYUcQWk0L1nnbdEO+aKLX5Ra2R+iWhxiK0uZUNWL NoSnqUPkgP2GWUEZVxrJhs8qdC3/qxMAEYPCdU1zMIBU0VK6hB4aVYRJt9+bVGBugojVsJ dtSCaqKUYPyW54DggKFM1uRiprvnqSfAn1i6v/Rw0Pc3VgOaYJHy4a4vGV9vvTpQsPrfCr 7zssZsvdyrov6EycAM6YVrzc+aOCV6wHGHrIMOaUhWtbxZ1cKA1mpXBblE2QzRaxUhHVQQ 5SFKhgAtyhqU7cuf5/JE38eO0hMvKBEs95Mxn6zn+gH3H33/m2tAdmiDgUcjxw== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=gmail.com header.s=20230601 header.b=dh+5zuAe; spf=pass (aspmx1.migadu.com: domain of "guix-devel-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-devel-bounces+larch=yhetil.org@gnu.org"; dmarc=none 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 CF42743F7D for ; Thu, 28 Dec 2023 08:55:26 +0100 (CET) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rIlDy-0002DL-Ub; Thu, 28 Dec 2023 02:54:40 -0500 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 1rIlDr-0002D0-61 for guix-devel@gnu.org; Thu, 28 Dec 2023 02:54:31 -0500 Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rIlDn-0006k4-Nh for guix-devel@gnu.org; Thu, 28 Dec 2023 02:54:30 -0500 Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-40d5aefcc2fso18183135e9.0 for ; Wed, 27 Dec 2023 23:54:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1703750066; x=1704354866; darn=gnu.org; h=in-reply-to:content-disposition:mime-version:references :mail-followup-to:message-id:subject:cc:to:from:date:sender:from:to :cc:subject:date:message-id:reply-to; bh=vBTA6fTZsr0v9GER1H9JZCgI42ZKbhcZJRNsfQoK03A=; b=dh+5zuAe5CJTn1VUQkwht6KN4AgVL0re/0qYiWHjOAEdxwRAvpQhI1U1KgtdY7IHPI DiZuc+hzaoh+4UP63qO/Bhe2CK7Waegr+I2dw+vFdIsn3UVDiGl7rP3K2P3h/nAvEVVC OsgdJNPsY216lqNlNNafXWhcXDyc4CdifgP5IZkuoWUS+Lrl9InOpIAvOsQMO+Dj22wO EM31eD4x6ffgDt9TQ65qax9w0SQAYvGxv+YFW6gPiNKzYMzBFQ2CDfxmmmsb1pH/6uJ2 Xv0R+ElRhYXE9XMq85zD/COknIlwmJUlP0VaIJIy5vWmWcFTejOhe3fFhj/Y8sQqlQAg KaOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1703750066; x=1704354866; h=in-reply-to:content-disposition:mime-version:references :mail-followup-to:message-id:subject:cc:to:from:date:sender :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=vBTA6fTZsr0v9GER1H9JZCgI42ZKbhcZJRNsfQoK03A=; b=ex6E1+xYCuNFydkjkfvAVvdZq67JS/OrWIoxvfYzbJ2LXQtOP1RdAAe9WEYaIK3oAK 0uzT4lhY5CIqLBD/b0VNmpDDt+n7YzGH6Oo1O6yoOSpP/5Z3XJGU7Vbqy+5JPMZQbXEi 2i9WTXXiodhHG6ivL7Rh6njwm1YrMSg+6+7PMNcumzsoX0phgw1Par6Hw5GagbOHE4Il FZTxUurl/yucZM0M+8EGLSfQQO/im72AUJVYUFr11P0i9AvMrdNqP5wqPSmWYoDu16pL fhHRbQ08IEhSMDR9co8bSfBZ8CgoMEnMxjoyhSffafFbHNLcEh0in8mNeLzVAFBTxPQL ESEA== X-Gm-Message-State: AOJu0Yxe+62BscvY5PZFWuSwT/WKT8U5g5ehgekZOY50yS5ySv/ndJtq qrT2wj857XKKTosXFizSR1Q= X-Google-Smtp-Source: AGHT+IF0mzmzboRzRDXIO/m8NFouVApYRsb9FJAktx/iGksfXZAFzUyp56jzUsKIFTBg42PnA0/8tA== X-Received: by 2002:a05:600c:5409:b0:40b:5e21:ec34 with SMTP id he9-20020a05600c540900b0040b5e21ec34mr5810081wmb.102.1703750065698; Wed, 27 Dec 2023 23:54:25 -0800 (PST) Received: from localhost ([141.226.15.142]) by smtp.gmail.com with ESMTPSA id n33-20020a05600c502100b004030e8ff964sm34707864wmr.34.2023.12.27.23.54.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Dec 2023 23:54:24 -0800 (PST) Date: Thu, 28 Dec 2023 09:54:22 +0200 From: Efraim Flashner To: jgart Cc: guix-devel@gnu.org Subject: Re: Rust <3 Guix Message-ID: Mail-Followup-To: jgart , guix-devel@gnu.org References: <4428a8245ae40646a1c23d0c33bdd756fea33425@dismail.de> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="QF/Erp3BOlBlhtnx" Content-Disposition: inline In-Reply-To: X-PGP-Key-ID: 0x41AAE7DCCA3D8351 X-PGP-Key: https://flashner.co.il/~efraim/efraim_flashner.asc X-PGP-Fingerprint: A28B F40C 3E55 1372 662D 14F7 41AA E7DC CA3D 8351 Received-SPF: pass client-ip=2a00:1450:4864:20::332; envelope-from=efraim.flashner@gmail.com; helo=mail-wm1-x332.google.com X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.249, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.249, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: guix-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+larch=yhetil.org@gnu.org Sender: guix-devel-bounces+larch=yhetil.org@gnu.org X-Migadu-Flow: FLOW_IN X-Migadu-Country: US X-Migadu-Spam-Score: -6.83 X-Spam-Score: -6.83 X-Migadu-Queue-Id: CF42743F7D X-Migadu-Scanner: mx11.migadu.com X-TUID: x+28lM0yttpX --QF/Erp3BOlBlhtnx Content-Type: multipart/mixed; boundary="Zag7j/HgOsJpRDPq" Content-Disposition: inline --Zag7j/HgOsJpRDPq Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Dec 25, 2023 at 07:25:26AM +0000, jgart wrote: > > Do you need both nss-certs and curl? >=20 > Hi Efraim, yes, I need both, oddly enough. If I remove one of them the bu= ild fails with the error message in the README that I provided. >=20 > > I saw in a later commit you said it's working. >=20 > I'm able to build main.rs with the guix installed tools but I'm not able = to use guix-installed crate dependencies. >=20 > I ended up installing the crates with cargo by fetching them from crates.= io with the following invocations: >=20 > cargo fetch > cargo update > cargo build >=20 > Not sure at the moment how to get cargo to defer to guix for managing the= crates when doing development... WDYT It's not pretty currently using guix's crates. The first part, getting the necessary crates, involves manually adding them (with their dependencies!) to your environment. The second part involves adjusting your config.toml to include the following: [source.crates-io] local-registry =3D '/gnu/store/3nfgfhxlciblr360jyrgxl275sf78a6f-profile/sha= re/cargo/registry' HOWEVER, instead of /gnu/store/...-profile you need to adjust the path to the value of your GUIX_ENVIRONMENT, and there's no way that I've figured out to use $GUIX_ENVIRONMENT in a toml file. Actually, it looks like I have the cargo registry patches sitting unapplied on my machine, so I'm not even sure if it'll work the way I wrote above. I'll see about getting them into a state I'm happy with for the rust-team branch. --=20 Efraim Flashner =D7=A8=D7=A0=D7=A9=D7=9C=D7=A4 = =D7=9D=D7=99=D7=A8=D7=A4=D7=90 GPG key =3D A28B F40C 3E55 1372 662D 14F7 41AA E7DC CA3D 8351 Confidentiality cannot be guaranteed on emails sent or received unencrypted --Zag7j/HgOsJpRDPq Content-Type: text/plain; charset=utf-8 Content-Disposition: attachment; filename="0001-build-cargo-build-system-Produce-registry-index-file.patch" Content-Transfer-Encoding: quoted-printable =46rom 84d2f06e9facec9a1646afd53adcbf2b95da4da0 Mon Sep 17 00:00:00 2001 Message-ID: <84d2f06e9facec9a1646afd53adcbf2b95da4da0.1702565894.git.efraim= @flashner.co.il> In-Reply-To: References: =46rom: Efraim Flashner Date: Thu, 14 Dec 2023 16:49:58 +0200 Subject: [PATCH 1/2] build: cargo-build-system: Produce registry index file= s. * guix/build/cargo-build-system.scm (rewrite-deps): New procedure. (package): Obtain output from 'cargo manifest' of the current package when the package will be installed. (install): Don't install cargo crates and source. (install-source): New phase. Install cargo crates. Generate cargo registry index files and install them in a known location. (%standard-phases): Add 'install-source phase after 'install. Change-Id: I6ce6c5b33fe3eb7667f86964daef798320724a25 --- guix/build/cargo-build-system.scm | 102 +++++++++++++++++++++++++----- 1 file changed, 87 insertions(+), 15 deletions(-) diff --git a/guix/build/cargo-build-system.scm b/guix/build/cargo-build-sys= tem.scm index ffb2ec898e..f1e35a5c65 100644 --- a/guix/build/cargo-build-system.scm +++ b/guix/build/cargo-build-system.scm @@ -73,6 +73,21 @@ (define (crate-src? path) " | cut -d/ -f2" " | grep -q '^Cargo.toml$'")))= )) =20 +(define (rewrite-deps cargo-deps) + (map (lambda (dependency) + `(@ ("name" . ,(assoc-ref dependency "name")) + ("req" . ,(assoc-ref dependency "req")) + ("features" . ,(assoc-ref dependency "features")) + ("optional" . ,(assoc-ref dependency "optional")) + ("default_features" . ,(assoc-ref dependency + "uses_default_features")) + ("target" . ,(assoc-ref dependency "target")) + ("kind" . ,(match (assoc-ref dependency "kind") + (null? "normal") + (kind kind))) + ("registry" . ,(assoc-ref dependency "registry")))) + cargo-deps)) + (define* (unpack-rust-crates #:key inputs vendor-dir #:allow-other-keys) (define (inputs->rust-inputs inputs) "Filter using the label part from INPUTS." @@ -271,7 +286,8 @@ (define* (package #:key install-source? (cargo-package-flags '("--no-metadata" "--no-verify")) #:allow-other-keys) - "Run 'cargo-package' for a given Cargo package." + "Run 'cargo-package' for a given Cargo package. Also generate metadata = so we can +create a package index for the crates." (if install-source? (if skip-build? (begin @@ -322,19 +338,24 @@ (define* (package #:key (delete-file-recursively dir))) (find-files "." "\\.crate$"))))) (format #t "Not installing cargo sources, skipping `cargo package`.~%"= )) - #t) + + (when install-source? + ;; First generate the metadata so we can create the index file. + ;; https://doc.rust-lang.org/cargo/commands/cargo-metadata.html#json-f= ormat + (with-output-to-file "cargo-metadata.json" + (lambda _ + (invoke "cargo" "metadata" + "--manifest-path" "Cargo.toml" + "--format-version" "1" + "--no-deps"))))) =20 (define* (install #:key - inputs outputs skip-build? - install-source? features #:allow-other-keys) "Install a given Cargo package." - (let* ((out (assoc-ref outputs "out")) - (registry (string-append out "/share/cargo/registry")) - (sources (string-append out "/share/cargo/src"))) + (let ((out (assoc-ref outputs "out"))) (mkdir-p out) =20 ;; Make cargo reuse all the artifacts we just built instead @@ -346,21 +367,71 @@ (define* (install #:key (or skip-build? (not (has-executable-target?)) (invoke "cargo" "install" "--no-track" "--path" "." "--root" out - "--features" (string-join features))) + "--features" (string-join features))))) + +(define* (install-sources #:key + name + outputs + install-source? + #:allow-other-keys) + "Install a given Cargo package." + (let* ((out (assoc-ref outputs "out")) + (registry (string-append out "/share/cargo/registry/")) + (name+ver (if (string-prefix? "rust-" name) + (string-drop name 5) + name)) + ;; Strip the version if it exists. + (pkgname (if (char-set-every + (lambda (item) + (char-set-contains? + (list->char-set (list #\- #\.) char-set:digit= ) item)) + (string->char-set + (string-drop name+ver (string-index-right name+= ver #\-)))) + (string-take name+ver (string-index-right name+ver #\= -)) + name+ver))) =20 (when install-source? ;; Install crate tarballs and unpacked sources for later use. - ;; TODO: Is there a better format/directory for these files? - (mkdir-p sources) (for-each (lambda (crate) (install-file crate registry)) (find-files "target/package" "\\.crate$")) =20 - (for-each (lambda (crate) - (invoke "tar" "xzf" crate "-C" sources)) - (find-files registry "\\.crate$"))) + (let ((path (match (string-length pkgname) + (1 "1") + (2 "2") + (3 (string-append "3/" (string-take pkgname 1))) + (else (string-append (substring pkgname 0 2) "/" + (substring pkgname 2 4))))) + (cargo-metadata (match (call-with-input-file + "cargo-metadata.json" read-json) + (('@ . alist) alist))) + (sha256sum (read-delimited + " " + (open-pipe* OPEN_READ + "sha256sum" "--" + (first (find-files registry pkgname))= )))) =20 - #t)) + ;; Now it's time to generate the actual index file: + ;; https://doc.rust-lang.org/cargo/reference/registry-index.html#j= son-schema + (call-with-output-file pkgname + (lambda (out) + (write-json + `(@ ("name" . ,(assoc-ref + (first (assoc-ref cargo-metadata "packages"= )) + "name")) + ("vers" . ,(assoc-ref + (first (assoc-ref cargo-metadata "packages"= )) + "version")) + ("deps" . ,(rewrite-deps (assoc-ref + (first (assoc-ref cargo-metadata "packages"= )) + "dependencies"))) + ("cksum" . ,sha256sum) + ("features" . ,(assoc-ref + (first (assoc-ref cargo-metadata "packa= ges")) + "features")) + ("yanked" . #f)) + out))) + (install-file pkgname (string-append registry "/index/" path)))))) =20 (define %standard-phases (modify-phases gnu:%standard-phases @@ -372,7 +443,8 @@ (define %standard-phases (add-after 'build 'package package) (add-after 'unpack 'check-for-pregenerated-files check-for-pregenerate= d-files) (add-after 'check-for-pregenerated-files 'unpack-rust-crates unpack-ru= st-crates) - (add-after 'patch-generated-file-shebangs 'patch-cargo-checksums patch= -cargo-checksums))) + (add-after 'patch-generated-file-shebangs 'patch-cargo-checksums patch= -cargo-checksums) + (add-after 'install 'install-sources install-sources))) =20 (define* (cargo-build #:key inputs (phases %standard-phases) #:allow-other-keys #:rest args) --=20 Efraim Flashner =D7=A8=D7=A0=D7=A9=D7=9C=D7=A4 = =D7=9D=D7=99=D7=A8=D7=A4=D7=90 GPG key =3D A28B F40C 3E55 1372 662D 14F7 41AA E7DC CA3D 8351 Confidentiality cannot be guaranteed on emails sent or received unencrypted --Zag7j/HgOsJpRDPq Content-Type: text/plain; charset=utf-8 Content-Disposition: attachment; filename="0002-guix-profiles-Add-cargo-registry-profile-hook.patch" Content-Transfer-Encoding: quoted-printable =46rom 1dca2772f81df7d9a66f7a97668c3f9acca141a8 Mon Sep 17 00:00:00 2001 Message-ID: <1dca2772f81df7d9a66f7a97668c3f9acca141a8.1702565894.git.efraim= @flashner.co.il> In-Reply-To: References: =46rom: Efraim Flashner Date: Thu, 14 Dec 2023 16:54:11 +0200 Subject: [PATCH 2/2] guix: profiles: Add cargo-registry profile hook. * guix/profiles.scm (cargo-registry): New profile-hook. (%default-profile-hooks): Add cargo-registry. Change-Id: I8642e116e7ff7df2ae2dde77c98d5cfeed85f99d --- guix/profiles.scm | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/guix/profiles.scm b/guix/profiles.scm index ce2f8337bf..129448b2b1 100644 --- a/guix/profiles.scm +++ b/guix/profiles.scm @@ -13,6 +13,7 @@ ;;; Copyright =C2=A9 2020 Danny Milosavljevic ;;; Copyright =C2=A9 2014 David Thompson ;;; Copyright =C2=A9 2022 Arun Isaac +;;; Copyright =C2=A9 2023 Efraim Flashner ;;; ;;; This file is part of GNU Guix. ;;; @@ -1193,6 +1194,29 @@ (define* (ca-certificate-bundle manifest #:optional = system) `((type . profile-hook) (hook . ca-certificate-bundle)))) =20 +(define* (cargo-registry manifest #:optional system) + (define build + (with-imported-modules '((guix build utils)) + #~(begin + (use-modules (guix build utils)) + (let ((registry (string-append #$output "/share/cargo/registry")= )) + (mkdir-p registry) + ;; https://doc.rust-lang.org/cargo/reference/registry-index.ht= ml#index-configuration + (with-output-to-file (string-append registry "/config.json") + (lambda _ + (format #t "{~@ + \"dl\": \"~a/{crate}-{version}.crate\",~@ + }~%" + registry))))))) + + (gexp->derivation "cargo-registry" build + #:system system + #:local-build? #t + #:substitutable? #f + #:properties + `((type . profile-hook) + (hook . cargo-registry)))) + (define* (emacs-subdirs manifest #:optional system) (define build (with-imported-modules (source-module-closure @@ -1932,6 +1956,7 @@ (define %default-profile-hooks fonts-dir-file ghc-package-cache-file ca-certificate-bundle + cargo-registry emacs-subdirs gdk-pixbuf-loaders-cache-file glib-schemas --=20 Efraim Flashner =D7=A8=D7=A0=D7=A9=D7=9C=D7=A4 = =D7=9D=D7=99=D7=A8=D7=A4=D7=90 GPG key =3D A28B F40C 3E55 1372 662D 14F7 41AA E7DC CA3D 8351 Confidentiality cannot be guaranteed on emails sent or received unencrypted --Zag7j/HgOsJpRDPq-- --QF/Erp3BOlBlhtnx Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEoov0DD5VE3JmLRT3Qarn3Mo9g1EFAmWNKa4ACgkQQarn3Mo9 g1GZKA/+KYzuBDnYxm2zoLSuINjx6t1g8egNS1ET9gebYUmueb6TOQg3q+IBRypL PlFy81HwQb0rB+PjBLEPIzzULcUYVCY9+gTgvplAWRihvq/3Ec2M9R/5xdD3HNFO Duqtmkstg1u+Zaujl8/CYGgW1KBcBD3G/PBW5BgF+b0QpldTeJ82dpeheKY1ItjK dW8QbfOuH3j6VLrZKfJv7MSyFlQsTbtgCYcVyRvkZcc9hrgVbaSvYiuZx7IcGrjx XPr3SyCP0+Sz3RegoSC/ZT5gLpH3LfOeyNXMt2l1TiuHvVV5EKbgrU/u08Wh+dbf AH9++JfrGhb06HmiZye7ldhuk4bFCnAOllG2UkrnuaBluwqDLtrcIPMXYx7x/77x s+iUp3Ad1AK+4nJUcGuDeSFBArU1hwxO1Ocgols2ZXA83/gq8iH2MMHTKaLCktoy 0T9KCik7LUxHyT3aAVoagA5ZBLG/wuj3bdaD99NDirzX/w5mI/SdmXDxo6+HZEoS O1hoFlWRp8eEyQiRtwp+THYswZaT7a0wzpvLEbpgaNdAPItejW5zPRIsYDurIZKG IrtwZG4pIgmTuHg/KP0shxMvJdxalu+1wVt9k0cJ/zlI3vu4BOWY192dm/XEMjIj mQ9UQcKS8M4tToMh5FeriiUnCOvwMAfOsGDTKlQUG8nyQY0KINM= =0R2r -----END PGP SIGNATURE----- --QF/Erp3BOlBlhtnx--