From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Panicz Maciej Godek Newsgroups: gmane.lisp.guile.devel Subject: Re: I wrote fluid advection code: How to make this more elegant? Date: Sat, 23 Jan 2016 12:33:32 +0100 Message-ID: References: <87io2kpqdq.fsf@web.de> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=001a1148e42c9f3d5d0529feb404 X-Trace: ger.gmane.org 1453548822 23378 80.91.229.3 (23 Jan 2016 11:33:42 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 23 Jan 2016 11:33:42 +0000 (UTC) Cc: guile-devel To: Arne Babenhauserheide Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sat Jan 23 12:33:41 2016 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1aMwRn-0004ih-Pg for guile-devel@m.gmane.org; Sat, 23 Jan 2016 12:33:40 +0100 Original-Received: from localhost ([::1]:56896 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aMwRn-0001G0-0Q for guile-devel@m.gmane.org; Sat, 23 Jan 2016 06:33:39 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:34243) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aMwRj-0001F4-Ij for guile-devel@gnu.org; Sat, 23 Jan 2016 06:33:37 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aMwRh-0004F6-NI for guile-devel@gnu.org; Sat, 23 Jan 2016 06:33:35 -0500 Original-Received: from mail-wm0-x230.google.com ([2a00:1450:400c:c09::230]:35005) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aMwRh-0004EM-9u for guile-devel@gnu.org; Sat, 23 Jan 2016 06:33:33 -0500 Original-Received: by mail-wm0-x230.google.com with SMTP id r129so13354034wmr.0 for ; Sat, 23 Jan 2016 03:33:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=kdw1L0mb2/GWqAHbhdKez/tqu2Gx2hrNmo66rNnfxbk=; b=Z4fyaqoCisEKHe87wZIlfBTUc/o3pEd0NjhPFn0mFfqWK4Lt2dRF7jmuZjFhtdKuug NC0yX7dxQW3I1YFZ/f8LqPW44ZHxE/PpZvW8vB7ggaYI/hnPHLjTNnuH/rYkljxBXNqa YB9TIAUZnIXHczkIXw4lej7w5+9CrdcGGxCpvRHdKk7VGeiEpb/RjEGfw+qRSGzZlsRm 6pF6CqrlLFAkPRmeGAiWIxK/qPeDfymQpoi+flCf0jLQnT2dQwt+V3giBBmGHj4c3iNb 2772wOVixk19BF6DdTzwSO7lxTbalMNnXaIxDg0s8qXoizLFqHpuQrXJYlvOvMJqpk5m 5viA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=kdw1L0mb2/GWqAHbhdKez/tqu2Gx2hrNmo66rNnfxbk=; b=SUrxwENrIEnAkN8J73IQgh9iMB+HI1WajAjKknkGjkxf4Nygfua9sPlfcnK7Afg5Ae HLFqKlBBrASjDP84fwNZ8XgJcgOXT1JGjCH93+YgyI8zlKuzQKytOh+wyi4BpMaaM7NU sB/1MbHAHKG+ue7YNCzGw+Q+quRUUCigopvbCPMpjsB11x0kkIndykuFolI3CHws1HPt /2ANaRB3xvMUs/QRvcbgBwpz0QfzFGfRGe4HwUGxidICcvDGrADm7Zc4y3GAv3ptIsPD fNcf5x4/v4AwHDNkGd3JD5ueXyjjmTIj1oke0tuRrkGqMCvOvEAQ9CpVD6gLOGS2Blsp p5Lg== X-Gm-Message-State: AG10YOQfXeQvQAfcbBZEMF/5leXRT78c1TliHSJnnosuYNGB81BXoNFOVa5IpFNA6WMvv9U7jmyl8HnW49imKg== X-Received: by 10.28.59.136 with SMTP id i130mr8825101wma.12.1453548812317; Sat, 23 Jan 2016 03:33:32 -0800 (PST) Original-Received: by 10.195.11.201 with HTTP; Sat, 23 Jan 2016 03:33:32 -0800 (PST) In-Reply-To: <87io2kpqdq.fsf@web.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::230 X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:18128 Archived-At: --001a1148e42c9f3d5d0529feb404 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi, although I cannot be of immediate help with the topic, because I don't know anything about advection, I think that the main problem with your code is that it is imperative. While Python's stylistics handles the imperative code quite nicely, it looks rather strange in Scheme. >From my experience, the proper Scheme solution should resemble the mathematical formulation of a problem (except that it should be more descriptive), rather than a list of steps for solving it. Also, it should be more readable to use patern matching instead of list indexing, so most likely your expression (let ((newvalue (+ (- (psir i) (* c1 (- (psir (+ i 1)) (psir (- i 1))))) (* c2 (+ (- (psir (+ i 1)) (* 2 (psir i))) (psir (- i 1))))))) (array-set! psinew newvalue i)) should look like this (map (lambda (prev this next) (- this (* c1 (- next prev)) (* (- c2) (+ next (* -2 this) prev)))) `(0 ,@(drop psir 1)) psir `(,@(drop-right psir 1) 0)) While this may also look slightly difficult to read (and write), this isn't solely because of the expression's structure, but because the factors of the expression have no name, and therefore the source code doesn't explain their role (this is the problem of the Python code either, but Python doesn't prompt to fix that) HTH PS I think that this subject fits better to guile-user 2016-01-23 11:00 GMT+01:00 Arne Babenhauserheide : > Hi, > > I just recreated a fluid advection exercise in Guile Scheme and I=E2=80= =99m not > quite happy with its readability. Can you help me improve it? > > My main gripe is that the math does not look instantly accessible. > > The original version was in Python: > > psi[i] - c1*(psi[i+1] - psi[i-1]) + c2*(psi[i+1] - 2.0*psi[i] + > psi[i-1]) > > My port to Scheme looks like this: > > (let ((newvalue (+ (- (psir i) > (* c1 (- (psir (+ i 1)) (psir (- i 1))))) > (* c2 (+ (- (psir (+ i 1)) (* 2 (psir i))) > (psir (- i 1))))))) > (array-set! psinew newvalue i)) > > > Liebe Gr=C3=BC=C3=9Fe, > Arne > > Here=E2=80=99s the full code: > > #!/bin/sh > # -*- scheme -*- > exec guile -e '(@@ (advection) main)' -s "$0" "$@" > !# > > ; Copyright (c) 2015 John Burkardt (original Python), 2016 Corinna > ; Hoose (adaption) and 2016 Arne Babenhauserheide (pep8 + Scheme > ; version). > > ; License: LGPL, built on the Python version from 2015 John Burkardt > ; and Corinna Hoose. License LGPL. > > (define-module (advection) > #:use-module (ice-9 optargs) ; define* > #:use-module (srfi srfi-1) ; iota > #:use-module (ice-9 format) > #:use-module (ice-9 popen)) > > > (define* (fd1d-advection-lax-wendroff #:key (nx 101) (nt 1000) (c 1)) > (let* ((dx (/ 1 (- nx 1))) > (x (iota nx 0 (/ 1 nx))) > (dt (/ 1 nt)) > (c1 (* #e0.5 (* c (/ dt dx)))) > (c2 (* 0.5 (expt (* c (/ dt dx)) 2)))) > (format #t "CFL condition: dt (~g) =E2=89=A4 (~g) dx/c\n" dt (/ dx c)= ) > (let ((psi (make-array 0 nx)) > (X (make-array 0 nx (+ nt 1))) > (Y (make-array 0 nx (+ nt 1))) > (Z (make-array 0 nx (+ nt 1)))) > (let ((psinew (let ((pn (make-array 0 nx))) > (let loop ((i 0)) > (cond ((=3D i nx) > pn) > (else > (let ((xi (list-ref x i))) > (when (and (<=3D 0.4 xi) (<=3D xi 0.6)) > (array-set! pn > (* (expt (- (* 10 xi) 4) 2= ) > (expt (- 6 (* 10 xi)) 2= )) > i)) > (loop (+ 1 i))))))))) > (define (psir i) (array-ref psi i)) > (let loop ((j 0)) > (cond > ((> j nt) #t) ; done > (else > (let ((t (/ j nt))) > (when (>=3D j 1) > (let ((newvalue (+ (- (psir 0) > (* c1 (- (psir 1) > (psir (- nx 1))))) > (* c2 (+ (- (psir 1) > (* 2 (psir 0))) > (psir (- nx 1))))))) > (array-set! psinew newvalue 0)) > (let loop ((i 1)) > (when (< i (- nx 1)) > (let ((newvalue (+ (- (psir i) > (* c1 (- (psir (+ i 1)) (psir (= - > i 1))))) > (* c2 (+ (- (psir (+ i 1)) (* 2 > (psir i))) > (psir (- i 1))))))) > (array-set! psinew newvalue i)) > (loop (+ i 1)))) > (let ((newvalue (+ (- (psir (- nx 1)) > (* c1 (- (psir 0) (psir (- nx 2))))= ) > (* c2 (+ (- (psir 0) (* 2 (psir (- nx > 1)))) > (psir (- nx 2))))))) > (array-set! psinew newvalue (- nx 1)))) > (let loop ((i 0)) > (when (< i nx) > (array-set! psi (array-ref psinew i) i) > (array-set! X (list-ref x i) i j) > (array-set! Y t i j) > (array-set! Z (psir i) i j) > (loop (+ i 1))))) > (loop (+ j 1))))) > (list X Y Z))))) > > (define (main args) > (display "Hello World!\n") > (let ((res (fd1d-advection-lax-wendroff))) > (let ((X (list-ref res 0)) > (Y (list-ref res 1)) > (Z (list-ref res 2))) > ; (display Z) > (let ((port (open-output-pipe "python"))) > (format port "import pylab as pl\n") > (format port "y =3D [[float(j) for j in i] for i in > eval('~A'[2:].replace(' ',', '))]\n" Z) > (format port "pl.imshow(y)\n") > (format port "pl.colorbar()\n") > (format port "pl.show()\n") > (close-pipe port)))) > (newline)) > > > -- > Unpolitisch sein > hei=C3=9Ft politisch sein > ohne es zu merken > --001a1148e42c9f3d5d0529feb404 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+PGRpdj48ZGl2PkhpLDxicj48L2Rpdj5hbHRob3VnaCBJIGNhbm5vdCBi ZSBvZiBpbW1lZGlhdGUgaGVscCB3aXRoIHRoZSB0b3BpYywgYmVjYXVzZSBJIGRvbiYjMzk7dCBr bm93IGFueXRoaW5nIGFib3V0IGFkdmVjdGlvbiwgSSB0aGluayB0aGF0IHRoZSBtYWluIHByb2Js ZW0gd2l0aCB5b3VyIGNvZGUgaXMgdGhhdCBpdCBpcyBpbXBlcmF0aXZlLiBXaGlsZSBQeXRob24m IzM5O3Mgc3R5bGlzdGljcyBoYW5kbGVzIHRoZSBpbXBlcmF0aXZlIGNvZGUgcXVpdGUgbmljZWx5 LCBpdCBsb29rcyByYXRoZXIgc3RyYW5nZSBpbiBTY2hlbWUuPGJyPjxicj48L2Rpdj5Gcm9tIG15 IGV4cGVyaWVuY2UsIHRoZSBwcm9wZXIgU2NoZW1lIHNvbHV0aW9uIHNob3VsZCByZXNlbWJsZSB0 aGUgbWF0aGVtYXRpY2FsIGZvcm11bGF0aW9uIG9mIGEgcHJvYmxlbSAoZXhjZXB0IHRoYXQgaXQg c2hvdWxkIGJlIG1vcmUgZGVzY3JpcHRpdmUpLCByYXRoZXIgdGhhbiBhIGxpc3Qgb2Ygc3RlcHMg Zm9yIHNvbHZpbmcgaXQuPGJyPjxkaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5BbHNvLCBpdCBzaG91 bGQgYmUgbW9yZSByZWFkYWJsZSB0byB1c2UgcGF0ZXJuIG1hdGNoaW5nIGluc3RlYWQgb2YgbGlz dCBpbmRleGluZywgc28gbW9zdCBsaWtlbHkgeW91ciBleHByZXNzaW9uPGJyPjxicj4obGV0ICgo bmV3dmFsdWUgKCsgKC0gKHBzaXIgaSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCAoKiBjMSAoLSAocHNpciAoKyBpIDEpKSAocHNpciAoLSBpIDEpKSkpKTxicj4N CsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKCogYzIgKCsgKC0gKHBzaXIgKCsg aSAxKSkgKCogMiAocHNpciBpKSkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgKHBzaXIgKC0gaSAxKSkpKSkpKTxicj4NCsKgIMKgIMKgIChhcnJh eS1zZXQhIHBzaW5ldyBuZXd2YWx1ZSBpKSk8YnI+PGJyPjwvZGl2PjxkaXY+c2hvdWxkIGxvb2sg bGlrZSB0aGlzPGJyPjwvZGl2PjxkaXY+PGJyPihtYXAgKGxhbWJkYSAocHJldiB0aGlzIG5leHQp PGJyPjwvZGl2PjxkaXY+wqDCoMKgwqDCoMKgwqDCoMKgICgtIHRoaXM8YnI+wqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgICgqIGMxICgtIG5leHQgcHJldikpPGJyPjwvZGl2PjxkaXY+wqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgICgqICgtIGMyKSAoKyBuZXh0ICgqIC0yIHRoaXMpIHByZXYpKSkpPGJy PjwvZGl2PjxkaXY+wqDCoMKgwqDCoMKgIGAoMCAsQChkcm9wIHBzaXIgMSkpPGJyPjwvZGl2Pjxk aXY+wqDCoMKgwqDCoMKgIHBzaXI8YnI+PC9kaXY+PGRpdj7CoMKgwqDCoMKgwqAgYCgsQChkcm9w LXJpZ2h0IHBzaXIgMSkgMCkpPGJyPjxicj48L2Rpdj48ZGl2PldoaWxlIHRoaXMgbWF5IGFsc28g bG9vayBzbGlnaHRseSBkaWZmaWN1bHQgdG8gcmVhZCAoYW5kIHdyaXRlKSwgdGhpcyBpc24mIzM5 O3Qgc29sZWx5IGJlY2F1c2Ugb2YgdGhlIGV4cHJlc3Npb24mIzM5O3Mgc3RydWN0dXJlLCBidXQg YmVjYXVzZSB0aGUgZmFjdG9ycyBvZiB0aGUgZXhwcmVzc2lvbiBoYXZlIG5vIG5hbWUsIGFuZCB0 aGVyZWZvcmUgdGhlIHNvdXJjZSBjb2RlIGRvZXNuJiMzOTt0IGV4cGxhaW4gdGhlaXIgcm9sZSAo dGhpcyBpcyB0aGUgcHJvYmxlbSBvZiB0aGUgUHl0aG9uIGNvZGUgZWl0aGVyLCBidXQgUHl0aG9u IGRvZXNuJiMzOTt0IHByb21wdCB0byBmaXggdGhhdCk8YnI+PC9kaXY+PGRpdj48YnI+PC9kaXY+ PGRpdj5IVEg8YnI+PGJyPjwvZGl2PjxkaXY+UFMgSSB0aGluayB0aGF0IHRoaXMgc3ViamVjdCBm aXRzIGJldHRlciB0byBndWlsZS11c2VyPGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2PjwvZGl2Pjwv ZGl2PjxkaXYgY2xhc3M9ImdtYWlsX2V4dHJhIj48YnI+PGRpdiBjbGFzcz0iZ21haWxfcXVvdGUi PjIwMTYtMDEtMjMgMTE6MDAgR01UKzAxOjAwIEFybmUgQmFiZW5oYXVzZXJoZWlkZSA8c3BhbiBk aXI9Imx0ciI+Jmx0OzxhIGhyZWY9Im1haWx0bzphcm5lX2JhYkB3ZWIuZGUiIHRhcmdldD0iX2Js YW5rIj5hcm5lX2JhYkB3ZWIuZGU8L2E+Jmd0Ozwvc3Bhbj46PGJyPjxibG9ja3F1b3RlIGNsYXNz PSJnbWFpbF9xdW90ZSIgc3R5bGU9Im1hcmdpbjowIDAgMCAuOGV4O2JvcmRlci1sZWZ0OjFweCAj Y2NjIHNvbGlkO3BhZGRpbmctbGVmdDoxZXgiPkhpLDxicj4NCjxicj4NCkkganVzdCByZWNyZWF0 ZWQgYSBmbHVpZCBhZHZlY3Rpb24gZXhlcmNpc2UgaW4gR3VpbGUgU2NoZW1lIGFuZCBJ4oCZbSBu b3Q8YnI+DQpxdWl0ZSBoYXBweSB3aXRoIGl0cyByZWFkYWJpbGl0eS4gQ2FuIHlvdSBoZWxwIG1l IGltcHJvdmUgaXQ/PGJyPg0KPGJyPg0KTXkgbWFpbiBncmlwZSBpcyB0aGF0IHRoZSBtYXRoIGRv ZXMgbm90IGxvb2sgaW5zdGFudGx5IGFjY2Vzc2libGUuPGJyPg0KPGJyPg0KVGhlIG9yaWdpbmFs IHZlcnNpb24gd2FzIGluIFB5dGhvbjo8YnI+DQo8YnI+DQrCoCDCoCBwc2lbaV0gLSBjMSoocHNp W2krMV0gLSBwc2lbaS0xXSkgKyBjMioocHNpW2krMV0gLSAyLjAqcHNpW2ldICsgcHNpW2ktMV0p PGJyPg0KPGJyPg0KTXkgcG9ydCB0byBTY2hlbWUgbG9va3MgbGlrZSB0aGlzOjxicj4NCjxicj4N CsKgIMKgIChsZXQgKChuZXd2YWx1ZSAoKyAoLSAocHNpciBpKTxicj4NCsKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICgqIGMxICgtIChwc2lyICgrIGkgMSkpIChwc2lyICgt IGkgMSkpKSkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAoKiBjMiAo KyAoLSAocHNpciAoKyBpIDEpKSAoKiAyIChwc2lyIGkpKSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAocHNpciAoLSBpIDEpKSkpKSkpPGJyPg0K wqAgwqAgwqAgKGFycmF5LXNldCEgcHNpbmV3IG5ld3ZhbHVlIGkpKTxicj4NCjxicj4NCjxicj4N CkxpZWJlIEdyw7zDn2UsPGJyPg0KQXJuZTxicj4NCjxicj4NCkhlcmXigJlzIHRoZSBmdWxsIGNv ZGU6PGJyPg0KPGJyPg0KIyEvYmluL3NoPGJyPg0KIyAtKi0gc2NoZW1lIC0qLTxicj4NCmV4ZWMg Z3VpbGUgLWUgJiMzOTsoQEAgKGFkdmVjdGlvbikgbWFpbikmIzM5OyAtcyAmcXVvdDskMCZxdW90 OyAmcXVvdDskQCZxdW90Ozxicj4NCiEjPGJyPg0KPGJyPg0KOyBDb3B5cmlnaHQgKGMpIDIwMTUg Sm9obiBCdXJrYXJkdCAob3JpZ2luYWwgUHl0aG9uKSwgMjAxNiBDb3Jpbm5hPGJyPg0KOyBIb29z ZSAoYWRhcHRpb24pIGFuZCAyMDE2IEFybmUgQmFiZW5oYXVzZXJoZWlkZSAocGVwOCArIFNjaGVt ZTxicj4NCjsgdmVyc2lvbikuPGJyPg0KPGJyPg0KOyBMaWNlbnNlOiBMR1BMLCBidWlsdCBvbiB0 aGUgUHl0aG9uIHZlcnNpb24gZnJvbSAyMDE1IEpvaG4gQnVya2FyZHQ8YnI+DQo7IGFuZCBDb3Jp bm5hIEhvb3NlLiBMaWNlbnNlIExHUEwuPGJyPg0KPGJyPg0KKGRlZmluZS1tb2R1bGUgKGFkdmVj dGlvbik8YnI+DQrCoCAjOnVzZS1tb2R1bGUgKGljZS05IG9wdGFyZ3MpIDsgZGVmaW5lKjxicj4N CsKgICM6dXNlLW1vZHVsZSAoc3JmaSBzcmZpLTEpIDsgaW90YTxicj4NCsKgICM6dXNlLW1vZHVs ZSAoaWNlLTkgZm9ybWF0KTxicj4NCsKgICM6dXNlLW1vZHVsZSAoaWNlLTkgcG9wZW4pKTxicj4N Cjxicj4NCjxicj4NCihkZWZpbmUqIChmZDFkLWFkdmVjdGlvbi1sYXgtd2VuZHJvZmYgIzprZXkg KG54IDEwMSkgKG50IDEwMDApIChjIDEpKTxicj4NCsKgIChsZXQqICgoZHggKC8gMSAoLSBueCAx KSkpPGJyPg0KwqAgwqAgwqAgwqAgwqAoeCAoaW90YSBueCAwICgvIDEgbngpKSk8YnI+DQrCoCDC oCDCoCDCoCDCoChkdCAoLyAxIG50KSk8YnI+DQrCoCDCoCDCoCDCoCDCoChjMSAoKiAjZTAuNSAo KiBjICgvIGR0IGR4KSkpKTxicj4NCsKgIMKgIMKgIMKgIMKgKGMyICgqIDAuNSAoZXhwdCAoKiBj ICgvIGR0IGR4KSkgMikpKSk8YnI+DQrCoCDCoCAoZm9ybWF0ICN0ICZxdW90O0NGTCBjb25kaXRp b246IGR0ICh+Zykg4omkICh+ZykgZHgvY1xuJnF1b3Q7IGR0ICgvIGR4IGMpKTxicj4NCsKgIMKg IChsZXQgKChwc2kgKG1ha2UtYXJyYXkgMCBueCkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgKFggKG1h a2UtYXJyYXkgMCBueCAoKyBudCAxKSkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgKFkgKG1ha2UtYXJy YXkgMCBueCAoKyBudCAxKSkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgKFogKG1ha2UtYXJyYXkgMCBu eCAoKyBudCAxKSkpKTxicj4NCsKgIMKgIMKgIChsZXQgKChwc2luZXcgKGxldCAoKHBuIChtYWtl LWFycmF5IDAgbngpKSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAobGV0 IGxvb3AgKChpIDApKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIChj b25kICgoPSBpIG54KTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgcG4pPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgKGVsc2U8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoChsZXQgKCh4aSAobGlzdC1yZWYgeCBpKSkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAod2hlbiAoYW5kICgmbHQ7PSAwLjQgeGkp ICgmbHQ7PSB4aSAwLjYpKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgKGFycmF5LXNldCEgcG48YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCgqIChl eHB0ICgtICgqIDEwIHhpKSA0KSAyKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIChleHB0ICgtIDYg KCogMTAgeGkpKSAyKSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGkpKTxicj4NCsKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKGxvb3AgKCsgMSBpKSkpKSkpKSkp PGJyPg0KwqAgwqAgwqAgwqAgKGRlZmluZSAocHNpciBpKSAoYXJyYXktcmVmIHBzaSBpKSk8YnI+ DQrCoCDCoCDCoCDCoCAobGV0IGxvb3AgKChqIDApKTxicj4NCsKgIMKgIMKgIMKgIMKgIChjb25k PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAoKCZndDsgaiBudCkgI3QpIDsgZG9uZTxicj4NCsKgIMKg IMKgIMKgIMKgIMKgKGVsc2U8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCAobGV0ICgodCAoLyBqIG50 KSkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgKHdoZW4gKCZndDs9IGogMSk8YnI+DQrCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCAobGV0ICgobmV3dmFsdWUgKCsgKC0gKHBzaXIgMCk8YnI+DQrC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAo KiBjMSAoLSAocHNpciAxKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKHBzaXIgKC0gbnggMSkpKSkpPGJy Pg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAo KiBjMiAoKyAoLSAocHNpciAxKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgKCogMiAocHNpciAwKSkpPGJy Pg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgKHBzaXIgKC0gbnggMSkpKSkpKSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCAoYXJyYXktc2V0ISBwc2luZXcgbmV3dmFsdWUgMCkpPGJyPg0KwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgKGxldCBsb29wICgoaSAxKSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCAod2hlbiAoJmx0OyBpICgtIG54IDEpKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IMKgIMKgIChsZXQgKChuZXd2YWx1ZSAoKyAoLSAocHNpciBpKTxicj4NCsKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICgqIGMxICgt IChwc2lyICgrIGkgMSkpIChwc2lyICgtIGkgMSkpKSkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAoKiBjMiAoKyAoLSAocHNp ciAoKyBpIDEpKSAoKiAyIChwc2lyIGkpKSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAocHNpciAoLSBp IDEpKSkpKSkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKGFycmF5LXNl dCEgcHNpbmV3IG5ld3ZhbHVlIGkpKTxicj4NCsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg IChsb29wICgrIGkgMSkpKSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAobGV0ICgobmV3 dmFsdWUgKCsgKC0gKHBzaXIgKC0gbnggMSkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKCogYzEgKC0gKHBzaXIgMCkgKHBzaXIg KC0gbnggMikpKSkpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAoKiBjMiAoKyAoLSAocHNpciAwKSAoKiAyIChwc2lyICgtIG54IDEpKSkp PGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgKHBzaXIgKC0gbnggMikpKSkpKSk8YnI+DQrCoCDCoCDCoCDCoCDCoCDC oCDCoCDCoCDCoCAoYXJyYXktc2V0ISBwc2luZXcgbmV3dmFsdWUgKC0gbnggMSkpKSk8YnI+DQrC oCDCoCDCoCDCoCDCoCDCoCDCoCAobGV0IGxvb3AgKChpIDApKTxicj4NCsKgIMKgIMKgIMKgIMKg IMKgIMKgIMKgICh3aGVuICgmbHQ7IGkgbngpPGJyPg0KwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg wqAgKGFycmF5LXNldCEgcHNpIChhcnJheS1yZWYgcHNpbmV3IGkpIGkpPGJyPg0KwqAgwqAgwqAg wqAgwqAgwqAgwqAgwqAgwqAgKGFycmF5LXNldCEgWCAobGlzdC1yZWYgeCBpKSBpIGopPGJyPg0K wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgKGFycmF5LXNldCEgWSB0IGkgaik8YnI+DQrCoCDC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAoYXJyYXktc2V0ISBaIChwc2lyIGkpIGkgaik8YnI+DQrC oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAobG9vcCAoKyBpIDEpKSkpKTxicj4NCsKgIMKgIMKg IMKgIMKgIMKgIChsb29wICgrIGogMSkpKSkpPGJyPg0KwqAgwqAgwqAgKGxpc3QgWCBZIFopKSkp KTxicj4NCjxicj4NCihkZWZpbmUgKG1haW4gYXJncyk8YnI+DQrCoCAoZGlzcGxheSAmcXVvdDtI ZWxsbyBXb3JsZCFcbiZxdW90Oyk8YnI+DQrCoCAobGV0ICgocmVzIChmZDFkLWFkdmVjdGlvbi1s YXgtd2VuZHJvZmYpKSk8YnI+DQrCoCDCoCAobGV0ICgoWCAobGlzdC1yZWYgcmVzIDApKTxicj4N CsKgIMKgIMKgIMKgIMKgIChZIChsaXN0LXJlZiByZXMgMSkpPGJyPg0KwqAgwqAgwqAgwqAgwqAg KFogKGxpc3QtcmVmIHJlcyAyKSkpPGJyPg0KwqAgwqAgwqAgOyAoZGlzcGxheSBaKTxicj4NCsKg IMKgIMKgIChsZXQgKChwb3J0IChvcGVuLW91dHB1dC1waXBlICZxdW90O3B5dGhvbiZxdW90Oykp KTxicj4NCsKgIMKgIMKgIMKgIChmb3JtYXQgcG9ydCAmcXVvdDtpbXBvcnQgcHlsYWIgYXMgcGxc biZxdW90Oyk8YnI+DQrCoCDCoCDCoCDCoCAoZm9ybWF0IHBvcnQgJnF1b3Q7eSA9IFtbZmxvYXQo aikgZm9yIGogaW4gaV0gZm9yIGkgaW4gZXZhbCgmIzM5O35BJiMzOTtbMjpdLnJlcGxhY2UoJiMz OTsgJiMzOTssJiMzOTssICYjMzk7KSldXG4mcXVvdDsgWik8YnI+DQrCoCDCoCDCoCDCoCAoZm9y bWF0IHBvcnQgJnF1b3Q7cGwuaW1zaG93KHkpXG4mcXVvdDspPGJyPg0KwqAgwqAgwqAgwqAgKGZv cm1hdCBwb3J0ICZxdW90O3BsLmNvbG9yYmFyKClcbiZxdW90Oyk8YnI+DQrCoCDCoCDCoCDCoCAo Zm9ybWF0IHBvcnQgJnF1b3Q7cGwuc2hvdygpXG4mcXVvdDspPGJyPg0KwqAgwqAgwqAgwqAgKGNs b3NlLXBpcGUgcG9ydCkpKSk8YnI+DQrCoCAobmV3bGluZSkpPGJyPg0KPHNwYW4gY2xhc3M9IkhP RW5aYiI+PGZvbnQgY29sb3I9IiM4ODg4ODgiPjxicj4NCjxicj4NCi0tPGJyPg0KVW5wb2xpdGlz Y2ggc2Vpbjxicj4NCmhlacOfdCBwb2xpdGlzY2ggc2Vpbjxicj4NCm9obmUgZXMgenUgbWVya2Vu PGJyPg0KPC9mb250Pjwvc3Bhbj48L2Jsb2NrcXVvdGU+PC9kaXY+PGJyPjwvZGl2Pg0K --001a1148e42c9f3d5d0529feb404--