From d067311cf799556d8f5076d077c056a576a65bbd Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Thu, 12 Jun 2014 02:14:06 -0500 Subject: [PATCH] Metafunctions now typeset their contracts as the first line This is a backwards incompatible change, but there is a keyword argument to render-metafunction and render-metafunctions that goes back to the old behavior --- .../redex-doc/redex/scribblings/ref.scrbl | 20 +- .../redex-lib/redex/private/judgment-form.rkt | 15 +- .../redex/private/reduction-semantics.rkt | 35 +- .../redex-pict-lib/redex/private/pict.rkt | 338 ++++++++++-------- .../redex-test/redex/tests/bitmap-test.rkt | 1 + .../bmps-macosx/metafunctions-multiple.png | Bin 15225 -> 15826 bytes 6 files changed, 242 insertions(+), 167 deletions(-) diff --git a/pkgs/redex-pkgs/redex-doc/redex/scribblings/ref.scrbl b/pkgs/redex-pkgs/redex-doc/redex/scribblings/ref.scrbl index 6ad4ccdc33..93ba3a2c5b 100644 --- a/pkgs/redex-pkgs/redex-doc/redex/scribblings/ref.scrbl +++ b/pkgs/redex-pkgs/redex-doc/redex/scribblings/ref.scrbl @@ -2952,18 +2952,22 @@ other tools that combine @racketmodname[pict]s together. } @deftogether[[ -@defform[(render-metafunction metafunction-name)]{} +@defform[(render-metafunction metafunction-name maybe-contract)]{} @defform/none[#:literals (render-metafunction) - (render-metafunction metafunction-name filename)]{} -@defform[(render-metafunctions metafunction-name ...)]{} -@defform/none[#:literals (render-metafunctions) - (render-metafunctions metafunction-name ... #:file filename)]{}]]{ + (render-metafunction metafunction-name filename maybe-contract)]{} +@defform[(render-metafunctions metafunction-name ... maybe-filename maybe-contract) + #:grammar ([maybe-filename (code:line) (code:line #:file filename)] + [maybe-contract? (code:line) (code:line #:contract? bool-expr)])]{}]]{ Like @racket[render-reduction-relation] but for metafunctions. Similarly, @racket[render-metafunctions] accepts multiple metafunctions and renders them together, lining up all of the clauses together. +If the metafunctions have contracts, they are typeset as the first +lines of the output, unless the expression following @racket[#:contract?] +evaluates to @racket[#f]. + This function sets @racket[dc-for-text-size]. See also @racket[metafunction->pict] and @racket[metafunctions->pict]. @@ -3146,10 +3150,10 @@ precede ellipses that represent argument sequences; when it is are rendered on two lines and which are rendered on one. If its value is a list, the length of the list must match - the number of cases and each boolean indicates if that - case has a linebreak or not. + the number of cases plus one if there is a contract. + Each boolean indicates if that case has a linebreak or not. - This influences the @racket['left/right] styles only. + This parameter's value influences the @racket['left/right] styles only. } @defparam[metafunction-cases diff --git a/pkgs/redex-pkgs/redex-lib/redex/private/judgment-form.rkt b/pkgs/redex-pkgs/redex-lib/redex/private/judgment-form.rkt index 48320333a6..bf88b8af0b 100644 --- a/pkgs/redex-pkgs/redex-lib/redex/private/judgment-form.rkt +++ b/pkgs/redex-pkgs/redex-lib/redex/private/judgment-form.rkt @@ -407,7 +407,7 @@ (begin (unless (identifier? #'lang) (raise-syntax-error #f "expected an identifier in the language position" stx #'lang)) - (define-values (contract-name dom-ctcs codom-contracts pats) + (define-values (contract-name dom-ctcs pre-condition codom-contracts pats) (split-out-contract stx (syntax-e #'def-form-id) #'body #t)) (with-syntax* ([((name trms ...) rest ...) (car pats)] [(mode-stx ...) #`(#:mode (name I))] @@ -416,7 +416,7 @@ #'())] [(clauses ...) pats] [new-body #`(mode-stx ... ctc-stx ... clauses ...)]) - (do-extended-judgment-form #'lang (syntax-e #'def-form-id) #'new-body #f stx #t)))])) + (do-extended-judgment-form #'lang (syntax-e #'def-form-id) #'new-body #f stx #t)))])) ;; if relation? is true, then the contract is a list of redex patterns ;; if relation? is false, then the contract is a single redex pattern @@ -425,7 +425,7 @@ ;; initial test determines if a contract is specified or not (cond [(pair? (syntax-e (car (syntax->list rest)))) - (values #f #f (list #'any) (check-clauses stx syn-error-name (syntax->list rest) relation?))] + (values #f #f #f (list #'any) (check-clauses stx syn-error-name (syntax->list rest) relation?))] [else (syntax-case rest () [(id separator more ...) @@ -438,7 +438,7 @@ (raise-syntax-error syn-error-name "expected clause definitions to follow domain contract" stx)) - (values #'id contract (list #'any) (check-clauses stx syn-error-name clauses #t)))] + (values #'id contract #f (list #'any) (check-clauses stx syn-error-name clauses #t)))] [else (unless (eq? ': (syntax-e #'separator)) (raise-syntax-error syn-error-name "expected a colon to follow the meta-function's name" stx #'separator)) @@ -481,10 +481,9 @@ #t)])])]))) (let ([doms (reverse dom-pats)] [clauses (check-clauses stx syn-error-name raw-clauses relation?)]) - (values #'id - (if relation? - doms - #`(side-condition #,doms (term #,pre-condition))) + (values #'id + doms + (if relation? #f pre-condition) (reverse rev-codomains) clauses))] [else diff --git a/pkgs/redex-pkgs/redex-lib/redex/private/reduction-semantics.rkt b/pkgs/redex-pkgs/redex-lib/redex/private/reduction-semantics.rkt index 4bcd7c2317..67b754d656 100644 --- a/pkgs/redex-pkgs/redex-lib/redex/private/reduction-semantics.rkt +++ b/pkgs/redex-pkgs/redex-lib/redex/private/reduction-semantics.rkt @@ -1187,7 +1187,7 @@ prev-metafunction (λ () (raise-syntax-error syn-error-name "expected a previously defined metafunction" orig-stx prev-metafunction)))) - (let*-values ([(contract-name dom-ctcs codom-contracts pats) + (let*-values ([(contract-name dom-ctcs pre-condition codom-contracts pats) (split-out-contract orig-stx syn-error-name #'rest #f)] [(name _) (defined-name (list contract-name) pats orig-stx)]) (when (and prev-metafunction (eq? (syntax-e #'name) (syntax-e prev-metafunction))) @@ -1208,6 +1208,7 @@ name name-predicate #,dom-ctcs + #,pre-condition #,codom-contracts #,pats #,syn-error-name)) @@ -1251,9 +1252,13 @@ (define-syntax (generate-metafunction stx) (syntax-case stx () - [(_ orig-stx lang prev-metafunction name name-predicate dom-ctcs codom-contracts pats syn-error-name) + [(_ orig-stx lang prev-metafunction + name name-predicate + dom-ctcs pre-condition + codom-contracts pats syn-error-name) (let ([prev-metafunction (and (syntax-e #'prev-metafunction) #'prev-metafunction)] [dom-ctcs (syntax-e #'dom-ctcs)] + [pre-condition (syntax-e #'pre-condition)] [codom-contracts (syntax-e #'codom-contracts)] [pats (syntax-e #'pats)] [syn-error-name (syntax-e #'syn-error-name)]) @@ -1323,7 +1328,7 @@ #'lang syn-error-name #f - dom-ctcs) + #`(side-condition #,dom-ctcs (term #,pre-condition))) #'((void) any () ()))] [((codom-syncheck-expr codom-side-conditions-rewritten codom-names codom-names/ellipses) ...) (map (λ (codom-contract) @@ -1369,7 +1374,6 @@ #,(if prev-metafunction #`(metafunc-proc-cases #,(term-fn-get-id (syntax-local-value prev-metafunction))) #'null)]) - (build-metafunction lang cases @@ -1378,12 +1382,23 @@ (make-metafunc-proc (let ([name (lambda (x) (f/dom x))]) name) '(clause-name ...) - (generate-lws #f - (lhs ...) - (lhs-for-lw ...) - ((stuff ...) ...) - (rhs ...) - #t) + (list + ;; mf contract + #,(if (and dom-ctcs codom-contracts) + #`(list + #,(with-syntax ([(dom-ctc ...) dom-ctcs]) + #`(list (to-lw dom-ctc) ...)) + #,(with-syntax ([(codom-ctc ...) codom-contracts]) + #`(list (to-lw codom-ctc) ...))) + #'#f) + + ;; body of mf + (generate-lws #f + (lhs ...) + (lhs-for-lw ...) + ((stuff ...) ...) + (rhs ...) + #t)) lang #t ;; multi-args? 'name diff --git a/pkgs/redex-pkgs/redex-pict-lib/redex/private/pict.rkt b/pkgs/redex-pkgs/redex-pict-lib/redex/private/pict.rkt index f9bb2a7656..f078e3bc95 100644 --- a/pkgs/redex-pkgs/redex-pict-lib/redex/private/pict.rkt +++ b/pkgs/redex-pkgs/redex-pict-lib/redex/private/pict.rkt @@ -5,7 +5,7 @@ racket/match racket/pretty racket/set - (only-in racket/list drop-right last partition) + (only-in racket/list drop-right last partition add-between) texpict/mrpict texpict/utils @@ -21,7 +21,8 @@ (prefix-in lw/rt: redex/private/loc-wrapper-rt)) (require (for-syntax racket/base - redex/private/term-fn)) + redex/private/term-fn + syntax/parse)) (provide render-term term->pict @@ -261,7 +262,6 @@ (apply vl-append (add-between - (blank 0 (reduction-relation-rule-separation)) (map (λ (rp) (side-condition-combiner (vl-append @@ -274,7 +274,8 @@ (rp->pict-label rp))) (rule-pict-rhs rp)) (rp->side-condition-pict rp +inf.0))) - rps)))))) + rps) + (blank 0 (reduction-relation-rule-separation))))))) (define compact-vertical-min-width (make-parameter 0)) @@ -352,14 +353,14 @@ (apply hbl-append (add-between - (basic-text ", " (default-style)) - fresh-vars)) + fresh-vars + (basic-text ", " (default-style)))) (basic-text " fresh" (default-style)))))] [lst (add-between - 'comma (append pattern-binds/sc - frsh))]) + frsh) + 'comma)]) (if (null? lst) (blank) (let ([where ((where-make-prefix-pict))]) @@ -414,14 +415,6 @@ label ((current-text) "]" (label-style) (label-font-size)))) -(define (add-between i l) - (cond - [(null? l) l] - [else - (cons (car l) - (apply append - (map (λ (x) (list i x)) (cdr l))))])) - (define (make-horiz-space picts) (blank (pict-width (apply cc-superimpose picts)) 0)) (define rule-pict-style (make-parameter 'vertical)) @@ -773,11 +766,11 @@ #'(metafunctions->pict name)])) (define-syntax (metafunctions->pict stx) - (syntax-case stx () - [(_ name1 name2 ...) - (and (identifier? #'name1) - (andmap identifier? (syntax->list #'(name2 ...)))) - #'(metafunctions->pict/proc (list (metafunction name1) (metafunction name2) ...) 'metafunctions->pict)])) + (syntax-parse stx + [(_ name1:id name2:id ... (~optional (~seq #:contract? contract-e:expr) #:defaults ([contract-e #'#t]))) + #'(metafunctions->pict/proc (list (metafunction name1) (metafunction name2) ...) + contract-e + 'metafunctions->pict)])) (define-syntax (relation->pict stx) (syntax-case stx () @@ -786,24 +779,39 @@ #'(inference-rules-pict/relation 'form (metafunction name1))])) (define-syntax (render-metafunctions stx) - (syntax-case stx () - [(_ name1 name2 ...) - (and (identifier? #'name) - (andmap identifier? (syntax->list #'(name2 ...)))) - #'(render-metafunction/proc (list (metafunction name1) (metafunction name2) ...) #f 'render-metafunctions)] - [(_ name1 name2 ... #:file filename) - (and (identifier? #'name1) - (andmap identifier? (syntax->list #'(name2 ...)))) - #'(render-metafunction/proc (list (metafunction name1) (metafunction name2) ...) filename 'render-metafunctions)])) + (syntax-parse stx + [(_ name1:id name2:id ... (~seq k:keyword e:expr) ...) + (define filename #'#f) + (define contract? #'#t) + (for ([kwd (in-list (syntax->list #'(k ...)))] + [e (in-list (syntax->list #'(e ...)))]) + (cond + [(equal? '#:filename (syntax-e kwd)) + (set! filename e)] + [(equal? '#:contract? (syntax-e kwd)) + (set! contract? e)] + [else + (raise-syntax-error #f "unexpected keyword" stx kwd)])) + #`(render-metafunction/proc + (list (metafunction name1) (metafunction name2) ...) + #,contract? + #,filename + 'render-metafunctions)])) (define-syntax (render-metafunction stx) - (syntax-case stx () - [(_ name) - (identifier? #'name) - #'(render-metafunction/proc (list (metafunction name)) #f 'render-metafunction)] - [(_ name file) - (identifier? #'name) - #'(render-metafunction/proc (list (metafunction name)) file 'render-metafunction)])) + (syntax-parse stx + [(_ name:id + (~optional file:expr #:defaults ([file #'#f])) + (~optional (~seq k:keyword e:expr))) + #`(render-metafunction/proc (list (metafunction name)) + #,(cond + [(not (attribute k)) #'#f] + [(and (equal? (syntax-e (attribute k)) '#:contract?)) + #'e] + [else + (raise-syntax-error #f "unknown keyword" stx #'k)]) + file + 'render-metafunction)])) (define-syntax (render-relation stx) (syntax-case stx () @@ -814,7 +822,7 @@ (define metafunction-pict-style (make-parameter 'left-right)) (define metafunction-cases (make-parameter #f)) -(define (select-mf-cases eqns case-labelss) +(define (select-mf-cases contracts eqns case-labelss) (define mf-cases (metafunction-cases)) (cond [mf-cases @@ -824,21 +832,29 @@ (apply append (for/list ([eqns (in-list eqns)] + [contract (in-list contracts)] [case-labels (in-list case-labelss)]) (filter values - (for/list ([eqn (in-list eqns)] - [case-label (in-list case-labels)]) - (begin0 - (cond - [(and (pair? sorted-cases) (= i (car sorted-cases))) - (set! sorted-cases (cdr sorted-cases)) - eqn] - [(set-member? named-cases case-label) - eqn] - [else #f]) - (set! i (+ i 1)))))))] - [else (apply append eqns)])) + (cons + contract + (for/list ([eqn (in-list eqns)] + [case-label (in-list case-labels)]) + (begin0 + (cond + [(and (pair? sorted-cases) (= i (car sorted-cases))) + (set! sorted-cases (cdr sorted-cases)) + eqn] + [(set-member? named-cases case-label) + eqn] + [else #f]) + (set! i (+ i 1))))))))] + [else (apply append + (for/list ([eqns (in-list eqns)] + [contract (in-list contracts)]) + (if contract + (cons contract eqns) + eqns)))])) (define judgment-form-cases (make-parameter #f)) (define (select-jf-cases eqns conclusions eqn-names) @@ -877,9 +893,9 @@ [else (cons (car l) (loop (cdr l)))]))) -(define (metafunctions->pict/proc mfs name) - (unless (andmap (λ (mf) (eq? (metafunc-proc-lang (metafunction-proc (car mfs))) - (metafunc-proc-lang (metafunction-proc mf)))) +(define (metafunctions->pict/proc mfs contract? name) + (unless (andmap (λ (mf) (equal? (metafunc-proc-lang (metafunction-proc (car mfs))) + (metafunc-proc-lang (metafunction-proc mf)))) mfs) (error name "expected metafunctions that are all drawn from the same language")) (define current-linebreaks (linebreaks)) @@ -887,22 +903,39 @@ (define sep 2) (define style (metafunction-pict-style)) (define (wrapper->pict lw) (lw->pict all-nts lw)) - (define all-eqns (map (λ (mf) (metafunc-proc-pict-info (metafunction-proc mf))) mfs)) + (define contracts (for/list ([mf (in-list mfs)]) + (define lws (list-ref (metafunc-proc-pict-info (metafunction-proc mf)) 0)) + (cond + [(and contract? lws) + (define doms (list-ref lws 0)) + (define rngs (list-ref lws 1)) + (render-metafunction-contract + (metafunc-proc-lang (metafunction-proc mf)) + (metafunc-proc-name (metafunction-proc mf)) + doms + rngs)] + [else #f]))) + (define all-eqns (map (λ (mf) (list-ref (metafunc-proc-pict-info (metafunction-proc mf)) 1)) mfs)) (define all-lhss - (map (λ (mf) - (map (lambda (eqn) - (wrapper->pict - (metafunction-call (metafunc-proc-name (metafunction-proc mf)) - (list-ref eqn 0)))) - (metafunc-proc-pict-info (metafunction-proc mf)))) - mfs)) + (for/list ([mf (in-list mfs)]) + (for/list ([eqn (in-list (list-ref (metafunc-proc-pict-info (metafunction-proc mf)) 1))]) + (wrapper->pict + (metafunction-call (metafunc-proc-name (metafunction-proc mf)) + (list-ref eqn 0)))))) (define case-labels (map (λ (mf) (metafunc-proc-clause-names (metafunction-proc mf))) mfs)) - (define eqns (select-mf-cases all-eqns case-labels)) - (define lhss (select-mf-cases all-lhss case-labels)) - (define rhss (map (lambda (eqn) (wrapper->pict (list-ref eqn 2))) eqns)) + (define eqns (select-mf-cases contracts all-eqns case-labels)) + (define lhs/contracts (select-mf-cases contracts all-lhss case-labels)) + (define rhss (for/list ([eqn/contract (in-list eqns)]) + (if (pict? eqn/contract) + 'contract + (wrapper->pict (list-ref eqn/contract 2))))) (unless (or (not current-linebreaks) (= (length current-linebreaks) (length eqns))) - (error 'metafunction->pict "expected the current-linebreaks parameter to be a list whose length matches the number of cases in the metafunction (~a), but got ~s" + (error 'metafunction->pict + (string-append + "expected the current-linebreaks parameter to be a list" + " whose length matches the number of cases in the metafunction" + " plus one if there is a contract (~a), but got ~s") (length eqns) current-linebreaks)) (define linebreak-list (or current-linebreaks @@ -923,45 +956,55 @@ left-right*/compact-side-conditions))) (define max-line-w/pre-sc (and compact-side-conditions? - (apply - max - (map (lambda (lhs rhs linebreak?) - (cond - [(eq? mode 'vertical) - (max (+ (pict-width lhs) (pict-width =-pict)) - (pict-width rhs))] - [linebreak? - (max (pict-width lhs) - (+ (pict-width rhs) sep (pict-width =-pict)))] - [else - (+ (pict-width lhs) (pict-width rhs) (pict-width =-pict) - (* 2 sep))])) - lhss rhss linebreak-list)))) + (for/fold ([biggest 0]) ([lhs/contract (in-list lhs/contracts)] + [rhs (in-list rhss)] + [linebreak? (in-list linebreak-list)]) + (cond + [(equal? rhs 'contract) + ;; this is a contract + (max biggest (pict-width lhs/contract))] + [(eq? mode 'vertical) + (max biggest + (+ (pict-width lhs/contract) (pict-width =-pict)) + (pict-width rhs))] + [linebreak? + (max biggest + (pict-width lhs/contract) + (+ (pict-width rhs) sep (pict-width =-pict)))] + [else + (max biggest + (+ (pict-width lhs/contract) (pict-width rhs) (pict-width =-pict) + (* 2 sep)))])))) (define scs (for/list ([eqn (in-list eqns)]) - (let ([scs (reverse (list-ref eqn 1))]) - (if (null? scs) - #f - (let-values ([(fresh where/sc) (partition metafunc-extra-fresh? scs)]) - (side-condition-pict (foldl (λ (clause picts) - (foldr (λ (l ps) (cons (wrapper->pict l) ps)) - picts (metafunc-extra-fresh-vars clause))) - '() fresh) - (map (match-lambda - [(struct metafunc-extra-where (lhs rhs)) - (where-pict (wrapper->pict lhs) (wrapper->pict rhs))] - [(struct metafunc-extra-side-cond (expr)) - (wrapper->pict expr)]) - where/sc) - (cond - [vertical-side-conditions? - ;; maximize line breaks: - 0] - [compact-side-conditions? - ;; maximize line break as needed: - max-line-w/pre-sc] - [else - ;; no line breaks: - +inf.0]))))))) + (cond + [(pict? eqn) #f] + [else + (define scs (reverse (list-ref eqn 1))) + (cond + [(null? scs) #f] + [else + (define-values (fresh where/sc) (partition metafunc-extra-fresh? scs)) + (side-condition-pict + (foldl (λ (clause picts) + (foldr (λ (l ps) (cons (wrapper->pict l) ps)) + picts (metafunc-extra-fresh-vars clause))) + '() fresh) + (map (match-lambda + [(struct metafunc-extra-where (lhs rhs)) + (where-pict (wrapper->pict lhs) (wrapper->pict rhs))] + [(struct metafunc-extra-side-cond (expr)) + (wrapper->pict expr)]) + where/sc) + (cond + [vertical-side-conditions? + ;; maximize line breaks: + 0] + [compact-side-conditions? + ;; maximize line break as needed: + max-line-w/pre-sc] + [else + ;; no line breaks: + +inf.0]))])]))) (case mode [(horizontal) (define (adjust-for-fills rows) @@ -1000,47 +1043,60 @@ (table 3 (adjust-for-fills (apply append - (map (lambda (lhs sc rhs linebreak?) - (append - (list - (cond - [linebreak? - (list lhs 'fill 'fill)] - [(and sc (eq? style 'left-right/beside-side-conditions)) - (list lhs =-pict (htl-append 10 rhs sc))] - [else - (list lhs =-pict rhs)])) - (if linebreak? - (list - (list (htl-append sep =-pict rhs) - 'fill - 'fill)) - null) - (if (or (not sc) - (and (not linebreak?) - (eq? style 'left-right/beside-side-conditions))) - null - (list - (list sc 'fill 'fill))))) - lhss - scs - rhss - linebreak-list))) + (for/list ([lhs/contract (in-list lhs/contracts)] + [sc (in-list scs)] + [rhs (in-list rhss)] + [linebreak? (in-list linebreak-list)]) + (append + (list + (cond + [(equal? rhs 'contract) ;; contract + (list lhs/contract 'fill 'fill)] + [linebreak? + (list lhs/contract 'fill 'fill)] + [(and sc (eq? style 'left-right/beside-side-conditions)) + (list lhs/contract =-pict (htl-append 10 rhs sc))] + [else + (list lhs/contract =-pict rhs)])) + (if linebreak? + (list + (list (htl-append sep =-pict rhs) + 'fill + 'fill)) + null) + (if (or (not sc) + (and (not linebreak?) + (eq? style 'left-right/beside-side-conditions))) + null + (list + (list sc 'fill 'fill))))))) ltl-superimpose ltl-superimpose sep sep)] [(vertical) (apply vl-append sep (apply append - (map (lambda (lhs sc rhs) - (cons - (vl-append (htl-append lhs =-pict) rhs) - (if (not sc) - null - (list sc)))) - lhss - scs - rhss)))])) + (for/list ([lhs/contract (in-list lhs/contracts)] + [sc (in-list scs)] + [rhs (in-list rhss)]) + (cond + [(equal? rhs 'contract) ;; contract + (list lhs/contract)] + [else + (cons + (vl-append (htl-append lhs/contract =-pict) rhs) + (if (not sc) + null + (list sc)))]))))])) + +(define (render-metafunction-contract lang name doms rngs) + (hbl-append (basic-text (format "~a" name) (metafunction-style)) + (basic-text " : " (default-style)) + (apply hbl-append (add-between (map (λ (x) (lw->pict lang x)) doms) + (basic-text " " (default-style)))) + (basic-text " → " (default-style)) + (apply hbl-append (add-between (map (λ (x) (lw->pict lang x)) rngs) + (basic-text " " (default-style)))))) (define (metafunction-call name an-lw) (struct-copy lw an-lw @@ -1122,14 +1178,14 @@ (basic-text "]" (default-style)))])] [else x])) -(define (render-metafunction/proc mfs filename name) +(define (render-metafunction/proc mfs contract? filename name) (cond [filename - (save-as-ps/pdf (λ () (metafunctions->pict/proc mfs name)) + (save-as-ps/pdf (λ () (metafunctions->pict/proc mfs contract? name)) filename)] [else (parameterize ([dc-for-text-size (make-object bitmap-dc% (make-object bitmap% 1 1))]) - (metafunctions->pict/proc mfs name))])) + (metafunctions->pict/proc mfs contract? name))])) (define (render-pict make-pict filename) (cond diff --git a/pkgs/redex-pkgs/redex-test/redex/tests/bitmap-test.rkt b/pkgs/redex-pkgs/redex-test/redex/tests/bitmap-test.rkt index ae04fa4bb9..471579655e 100644 --- a/pkgs/redex-pkgs/redex-test/redex/tests/bitmap-test.rkt +++ b/pkgs/redex-pkgs/redex-test/redex/tests/bitmap-test.rkt @@ -96,6 +96,7 @@ "red-with-where-name.png")) (define-metafunction lang + S : x v e -> e [(S x v e) e]) (btest (render-metafunction S) diff --git a/pkgs/redex-pkgs/redex-test/redex/tests/bmps-macosx/metafunctions-multiple.png b/pkgs/redex-pkgs/redex-test/redex/tests/bmps-macosx/metafunctions-multiple.png index 977fe249b779fa68460a2c59dcc748614f363d11..d3d3003993b61175e905d739bab4359b24a32985 100644 GIT binary patch literal 15826 zcma*OV{~lay6zii#xu5U+n%v)+nBL!+qUh@q{127w(aEPzxF!&u6FOf=iU$1tF@}$ zMjKVV^|z1bd46xWysS7JG!`@v5D=WiFA>G>_p0yL(+`O6(a){-90-U2NJ2zV*)8j$ z+uKcRA-&eSb7U~TIS?5q4b0x0Oj-!r{l|nv8lnFMgY+zXycw1xj3Yw65~s;3L90^& zF+!2uh3xH^Hz9>Ev!i*XHi@iMcFRatlq1(N1bCUZ;t@)FwO4@5e*UeWj&Yo15y1n` z5rWNl0`1G2l)=_g@%Y-Rm0flB!+G(;jaF|mF;PH>Sju&L`=npUkjONMDskn14RE%w z&aFFMpGR4q)PMg3FUdPD>8v*!u(~^?bHha&?1zQjXH^&iT0ns)B7~%*q`YeTL%vov zXfg+2EzL>p5Q%Vk8ZLk^E}s7gIXN*C31(D@+4KFqnfq|c7Ke)l!zaWd1+(AFRmyt) zm@0LC!u#vt_M3p?cl+El#*p~P1S!6LZt$2ex%t_#DFI4gS2K>6%yO^yL0F(6Z}k5D zzI_uh%Nb_QkNRI>zpQJV@)@(eg1VY{Hg#kD(Q@3Leb`RFk^tcCNl7VAWj8byy;tkw zGobr1>!@dTg)Id%c+=U09+_67qoX_1D@EHe4~_*DSy@?3s}MkjEUJg{nx0(Vbix}r z)fIVNT}fG4(33HDoKV^B0l~i)7(I%~{;VLgCM72;sVWLxoNV4?Ya7|dfhnBaxdSe$ z&?{Fc{D2HAp2h~D!Zv>LZ<@PAOdTcmT-T8p#9|0oUkD;1-gN#A7-ij+R`5;45RiuB zi}#ZPa(FEqKmrGx-Gq@J93<1lN}>EjiDYqqn?0N}5Ru10O3GV)2-{rb3qM;(qy6!g zF=*H#wRG(V?J)=&V3;`{-gz1gf_7sjjfn6wkoZ%8B`s?A9u7w2MvC=^`rt(kI{2XC z7TthSaA%gGGOQsBmXa=6BH_*U39T%qPxwX4vrp(6ttx21DBVCVc=QW+ziTFt;su^A z2sogIfZ|ai%e5|uHB8g51fWxm4%np2@kqp&O|lk@)d6Bux1Qa$OzsJXP}1uXsd*}* z*6}t37PLe043y&eRA8!Lv=a!pFjSTzv=Xj-_R`sXXam@)?((0+#H$39^-4rhC|*Go z_28c;_6X#*RYV)QZ~?#+H|D9}9wDHjI3mM_@oGINRDZAj1?OdJhW`20TidN$1-DmQ z0LCNh&{Fzlj2P}3jwyoaB_E($uW`;)5Vw@3MnHsgX^E65w0p#?;M?3zqSKCi&jI!` zaxV3@X9*9%(MdQpEUfMC%^e5NNnpuFMOe=&>uxERV3SnEg4fA|2cs%Cx$c-L303uD ze@BNdN}%ZaXB6j58u@-0>==v@?ENd0h@d!KWGX!|KchXju3?Z+9KV}BjSxkOxKGH< zhB`?Aon2M`76vFNp)(8&bB-C6h!ALy#;+aeEN!Dz321e==$F`%#n}<6CclOM99V!` z#as!AcAYekylW#0U>^Wj*5Uaou>%x&=!K&s$(>iS)>_$#Gg#8}J9MdO(PWIrh?nmf zJS=TCb)^^LizB*mb>w`rCQXs_Gj@1MWL8~D8x`;?9_JBxtx|5wk6wSSm|#3I!9s1U zw7I0!`*0`fc=6S{-XX4|))(8Hr;C5Ip?~n^sW6cfhgRKu> zq?&tTn90q{XCw-n7_kHKmR5|6mKQNI#UNxA<#{R-;U*pJ$0hElc)IG(4?uEZmD5m{ ze($2$3b7$4OsquxGFOHUKhL^NESwhJK@O2MN|C)?3@N4etsb%&Ba|zQ-IN)y4F?ys zuFZ@tUb+Hci{G7q?8gPF!V|-eEHvP57I2YwI5A)=O_z+JdCXQn&vQTASaVPHSBS*C zRta^H*Nh6l{&keY;BmkuCHOfBl*id#hEArGwrirFptg>tl3mI3ulsC0r|oc^EDmPt zL#0n>RcauZAq`c8>p!uvpuGpx4xb|QUyUx??vYE}*zK)IJuiK$3Ui@cIY#*Ub=m`K zSGD`;Wp!UYF4F4CDKR4&lH!#}O~tiH&$_RSc}FSWz;t?g!6S{3kP# zF#NqUQycQ~lRcO8L^+nnrTCx8IyL)_+q~zI2ZcUh2lGBgYwtD#Wu;|7r*bX!qL;Re zr2y~&rIsr_t)NzWO4hWpxFKQeQSf2{COy`U3Sf zCLT?ueILP^?W&BXViuHok=-lZ#?A;cOifK#GRB*&pqX(nz%Gv}QJ)lk1+ey zUQjm^reX>jdx2a^s|3`GtO++lYl@>>8N}-J(QIB{Kkb1y+_%hkY-0pmwwED+@jMjZ zXR(*ChfOT74&*-Xh(X4+HY9Z%QhZ&hgItnIFn2CoETHm}yKTjpd!GIN1BL(_-m;{M zQ}|#QhELOJIyjKf+7jSwx!%=`@bgjEct;pUJ*`W)H9Q*AnvWR_oyJp!ki(sL!+Z6n?umMCz^IlyTa)hG1-V8d>qS!TW>ArIAL+8 z^v65l8S}pri@Bh~bC`@0;i~6xPFc*IFNWg84Gu1Ek9x>Gc$S;GUft>Lt@8JEG-;R{Z;%^GTAy2OO69{~c*$C!aZ57X)K3+@;X(`^F+S8J@Yk2$l72lm*6 zPw)hw?te1=36A_C@2MUyER(ka(vdV*GG=LjmO-eDS2^Zd%Q*4oAJ|0L9%DVzP^8_z=CIge%-LY8a+{_k+IJjB?H#SKU6etJ<5r`B60kBa4L$SDpG&%lQ zS^8s|S+lTYjNVw$TW8{!F_VVo?Edl+UQ_8wOv-75vb=y>Ovuf#$q62} zyR{C$|J^3eYv)-_@$AJ=lIzhyRhImn+Mml6N4=?XnhX5=K2IMut!90swMj_-pS-jq1zP%5EY=2FD zUy(f2jiUS&V&gxTE)T+$g3(G-Si&lOUhJG{4Ax>>`!RC7dx2>->#;0CGzkjhh#r$8 zYb03&W_=mprT-3>TZ8=6V5$al7(xect2au?Y`xZi7)mZc_|tuS95EKMivDivQj1*? zD#e!+NOnsYQ^l}RoR3;f?lS*`-!nnH!s;3*6yG}ye5-8NUj|ve)FLV~$xr8_k8$50 zmXbU_c%sZo<;44j#G^Cx0#FYAp?$1bDm2r9JI~u0*wH>Y66)um0!3CCEK_L}{b0ZA zK%T1ih8L>CzRSa=TrtsJqhhqlOy|DSWNAR0txTsq;4TFk^TDlH36k;s6)X#Hm6$3c zeW)ob3sXF<)1mI`f%eh%?B1hXw3l7SWgFBF|+E6F!#OO0_I5s-;<7g*>x2ZHr_GQ?d4E-H`aE@h#XKj%V6Mo06DniA$VaOaZ_q}Pv&C!zdVZJ56*n!S&r@Fhf1FmKKJKvJWlZ`+urEV?ACrQNa+m3z&hTR z*T!|)z(|d^#CZ<$$##1)p5Q>Xo#}lBr*zmUd``Vld>#1~o!8^bbnIiL%lYxo9(rVD zb=sO)tmvRvYsgJ}z3ZI%@6cINEh*VQ>Cn)2W@ioiNEV)XCaGTT6@7uo``!4{N(^kI z);}V*-r2IjLh8EWK5fAbPxYiTj=pyGh>h>{N^3!vf?3a$WOKl7Q&Jdwj5Vw0SOUd{ zHblHpfY|mJ5qm_&H@ny60rAN3{4IdQzG>##ex{4@gdkWPojk~VkrL-7@~PP3>^nSw zJf4_12z095y>GH->cYxg`E{f6d2cb?cBr=`yh5I+(hBo@|JXa=bgReVG_Zy2eFHmt z&-`c0D{5}1p9P)sWf?7o-X~6A4s##CeE+d6Yk9@$#8s5D_sNSxUn|i5b;k3s^%Xv# zS9`cD>??I+V&nt2_m@1&<{ho%5($KU=#GHjH%65IUCWXuP*0AZb*-l_fc~Av2baD_ z+A|y>usKHj^CWk<{vCRoDTS6k;z`2i=YG?f!@Y~ta=oP&$nbJ!uPnEe@u~Lrr=3ar z``>Z^%P(h0($SGBVOD#H)>p;l_tGJGS}O98i5z1uj_cUbZYReIv63>JUCA;7L5}KM?y4dT`)raRbzJXX=dU zdk3)b3oz0H??k}cb4u;b;=8~IsK2_SwC#M1NP2RHabCB-W9RTXI($UItY}*?> z0@w9f2f#_uP2c}ea4vO`zA`$o7?E&D|}; z$IVHFncr*}*GH9=vPq+dj#?wS{T;^Xo8|xpr00n;;6?uEzy~m7RMm4B5blh@BThNZ!dt z(^ZVM^NFgW0ki%4Cuc#`&)zPaMu-2tt|YXpq~{L zG$v1WdaeautGQiJ~P4?JJ#V>$gYf^Q#!*oC>THuwDi;i~9cnmjy2~o=kZ8RX- zt8#XQR4L%=#ZE-%T0PLFx)piA$s}IKT8v`e@7o)d;Qfkh=)i*anc0}3l-}y?Ukj1K zigySdWy_Bynw!t)XkT|uB7T>tJ>x^ZoMS1S2-7#f0>G$?xi{ofo5GX0din41^l@6M zljQIp*xWUE6-9?%C#HN(kA#kR@6g2vKK@yqm%B5MUpTD%dz0jK9&7wNpNXjyZAQGs zvFC;N{SP!WZ)n{xwaQYX)NNO}y1Vhz+$*0Cv^1Lr#daI)7O$(cUJO;gJh~sWFnV6L zR&K|9qqybjuYo@Dfn^uYW2TV$NAJv5IW&GdDlVnvc(GwlaQwF2Uz4I)Cvl_#txjo^BA2$*nyc5k;%MIw$ zMo#<#6TQ46hdSaw$kpCkCNoly>P}O9584n}I>XORm$2Neb~|m5D2dUf)}0#ZklEx` zVnrK#UeSJtd()uv>kjCVF)a0OL*Y|J(A{ft+e9=y6=Cm9a25QsUvEGP*)f2Z;C-2f z8CFd`BYdzE7+n&zCk5!*F2lc;(<`}Nu}}OTPu7xjE}w4kpZ+lWsA#5bG4al9KEbT9 zUrc;b#>0}bDu;C!Q1)&hJU@?frWZ{1ALS5FI0l8hgZNg25lMOma#G>zcDL-vUN5Ro zYB`-lvO0YQD$n#*;!1+D8Ql$Nkcd$5a;YEEEarZY3)%4u`?D|BeNFOb$DB`MC{38{ zZ*1LoY$G&%orCquJlzC0S5jzloRI%`CeCNrx7+yn#g0aZqGT2>o%wu_m__l$lj{4n zFMm>z^EN-Xb#Ndoj(`0Aj(Et@CUnX z`k8f9*(|bjJ!{ig|Ve*9t-SfLa4eiFLT=)XM zdhM|@Y!O~VAdBmXkAX6cAvsW+Si2*?(O~N|&(Jzd!Pb-kS>$mw93leG!+A&>UAB&f zF($tG5R+O+Er8yni>zsqN$zG~csCC#{Mt;qu`JCV;h&R^ilAwBG%oB`t6J+UOINZf z652iC9yU$+Hk*aI5R0l*WR-&?6=g*Y)q>4j;K`h-!iIvV*)e429A3nyBHHTW(%wMf zz^8g*FcA*T6k*wg@*9)h()6)eMXCxaO6pO<(xQ+Yb^d4<)}+)Fd6!$7(%2z0kEEsS z>^7TTTgp}{`K=V6)3K^}ZT{A#I^Qw2S1Hd5Qx}RCm_|Yv;8p0h(JG^Qur0I)V&bWS*g= z!4}Z!@iiWWexmQlFZX<@9)(JU2C^Wo3D21op&N~L91}mrrgeMRis>$ay!T=Tmy+}_#{Zr5sAaf^QF8CrT!8uT)GL_ zd3${@cn9i$b_bT;ER< z9(OzTDaZ5c`RuzlHlmWAW#a2KrzD|wW3dkr&jlJM{yhx1{3v}nU&xpS(xSc_40 zD&l_Rl6OB;zHvm!1etP!`06>J?RJOp75f_-4h`Xn=ZWg~M}BH6zk%V~80TqzPLav` zp8(Q6?k;TLTf$pccD!vVwL{^e#M|P`o4o7kO#YJkJvuMQ*uvJ9hVq|8*|pbT&@p`o zob%6^u6BA*!MXcV(CfbArdgj9fj5{pE!U5WYhq2)TW8+5%Ok8W4E8NCsB7?k{gQ7_ zX9AR_wU9Vd>(TJnO+26>OkA-z0ok1zsktjHy?f@Y%F2y&3aqi$x-b}De2v#0s=w%L zyW#hOD!_C*iTu(Qa*0zpbz@!Jc0b|`nr(wO$-?o*^ed0U5g@=sNR};81yGuM$P;u_ zK;rA>v43_~>wIjHFL=021N2dUD|Nw#uTb{ucT&V*X#en-e=Tk&Ja}DS@K899d>tf+9bF``4ebajTchVI)yUJVE)fNo%)k&VlIbZvu8AV--ispJy==fc zG(Cocy^%0Hw`@`7p+DjLW@UCoV*Qm|pX++EBSFL0bjxHDfSL7pn{N zQiy}1zwVW{=mkE6kB%ov7I4)N#(1(5_PPhh7^r~QJ(Iur^ek*)FMTy~XpEuO*RqBJ z+^xK3eLK}@Cu60OAA@fe}OIO+!JSKxiITek+N65qx@7#(y~gyNNhYFY&YP$lBR zTH4ix7v>B8_1OEHYN(JquVphUuSXj(!zgC(6D?JgUeYB|L|lfQ`)`lQySZ_@iC0-? z^wz25vOLd?=d8BUP)efOo~w7N%($sK4|9giS6CA-OK!MAhs7aF4YJ_efTc0&ouj#` zFfnpQ{*5zYBm=|Gj=>bO2t+Il0+!gG!zxym9R5LbZcPc zvo_5hSo|sI^M8BDI?s74V55eMK0-Fb(k6#e$#Kl%`Z%H~W-4#CWzLFWTv-cR46yAFo^tdzNOJxD){|yWapKMAEWB1B5jE99) zvVf`$+840y&Y(uyti?tF4;nzo$Ao%e8HR9IZqy9iDteFhB+vEJvr^8h`i4;5%2R;k z6qWc_AUze4k4svE=DR^Ji#qI0{;xH+eoBpMDF>FO(ow05B04n@(&Hjb+93DjOwCD8NnNdq zHJa2a;;-IT)&bV`;%=*^PzFA|iA65$B@Xr|oQ!DKaHv7`E0tVbFzMM-m+*vXH+YDu zSK|tQ8!Lpefi~3}anXXEGLga=5esB=PuTEmaj8t{+%>8^Idj3iBgV4g2r3T<3+Mq(V!h5HPOHgzM zl*6okL_Ijw5@L{4r{ryz{sOCLogyZCC>=s$Zg;`($lw{Mb6Tqyb!3d>leh}i+; zd(dK5f>{J3@|7>173W(Wuj}O0D43y5&9jC(hXeGnRjU=vV2nFzP8XZpt(!3i_3yz0* zKFBAt@TCj3%1_k0=9Y@sW~LShVBh~hgbXbq#M!zf9|V-AHAr~^?}<}{V0ETka9irY zwW1WgY_sLI!d;EJl2mp6{atuAD#fpDl}`P@&UU&}j3$F7pfxge=)hEb8QJSoela z#b4pQC~d|In)#DrpAW_SbxlXZ#1k%N@xP7~`1GC_V{q5w9Rw3^nDlBaWYf>cO-rsj zZ9qKgJH!?h8l$+``<6PgceT9V3X2(9;kV zR$J2uNvD>+ybZkHhGx^5Zke%B=~TlR;xN|zOjZr$Jn_L&gb-a-dZe`IyoV6S6JKKR za!X77teXQ^zx;j8I5%X&M)rsh+yx~Sb8zn{+OUXzV?3@#`WauhM0i|1iy9@FS1A!i z;Bhu`Stcmc@5P9cW5t({nk(ny!{^@NwSeCu@DPgYL)%o_Ug$m_BQURo?csMe_#q562EfBuQT4F3LZAj$x3%)5^MSZ94U&~BXaXyTWw`3 zKFO_2BBg%AUSK?fhh}ecd5uqd=CfUHtVfqliCrjuz?$-OPJ2K>q!;m@o9`cxvo{!K zy#*snXKLiQ+4(7jQjKVIrK9!Do#6k4B_CriX!`W6q6Oo}3e=t@JrA1Jkt$w`ro5OO z*KnVkkD4XU<{z>j41%KyjsXI~jsAxPV9)BJxE8wS?vYpuS$i28dRyr{Kx_$)Rk(J7 zS=3tZY9Yioln0_2k!e)C4*f~14>^O{U^`cm&iT}5!B$njd)wN`1wbK-H5pIoZ+Lr- zC;v{9n6-bnT-WVD@r1xAt9~ZI^zz3db9`MNozSdJ_-_<5x3q|`<*EGZM_Dt0TWnqA zAI8+)nyYbZslXIm#@L2T@lSLjbXY4ye9D*|zOK@Hy-)0MTf;AXlb(-wW&g z`8)RTlvQE!wh3PqEm!X%)T2ZwtD5ZeoNa?sTdBXY3@M!>@j5_8y2~@*+W}cdtjtcwb!VPe@e=WBQI3U1=j?6QBnx-_wWx3-1(^7j` zXm}CYZmlA5xtCGKf9^I~1ci(2QVk?}KY)o%Zb}q4c$>W(~Zp$ScO);}> zHC?Mav>IX5qzii!XtGpPgmJd)QmNLU=M{IyK%I(^Ob5!Fo#jg|`6^tvPuK3h00`a} zBZjRZOX=d>K&f66+-T%3!+!iM;hh-CfrX@9iw$~0j1U`@(WJHkbGLF=og*j3P)jE8 zKs4w4`x{;$hd)Q})~%ypLrw zgcOI0Q-d1ohI&Fujq~c%vX-_Hy`014xLp2^s`Oo$uTiV-2#Dm6(mmfkNmKh z_ozRr(Ui_mh$oJPT|F?W=|c)4Rpgu)2>)1v^&fvRs_k)L!-4ZUW9uc-+bPe*zV?pS)D%*aVErL z_JCnmc~U70!O#D>px9RLh`qtiim=K0Z5^^agI0^;N!j7{r1xCn6apu584}Ge;;u}L zlZS%4Ac<3hyT}wF$qSyK(iJEONCS(*?N44F{dZV)Aew2_jdZF#Dg%0uCKiVxcr=oU ztu8ml+^Mun>@D)*g~&THlOf z*=vTp$v|R#@n3^1iE|oQbf<-M*aus2iOq+ z>2l?7(>q6WNou#9k}1O6W=kT^6E%IP7Qt&cdRe7s&H!!S;>pOudA?RlvcMT98n)%l z#~NP5onMzwL}X$mqC3i@IHhR{Bkk><(Nhy*(C#kWpml1;mtQo00SM0fy7A+G-i4qW zHv;O`Li|1ofb-nV4S1J+dT2ZdNvQ{obp z#6nB9bC@(+7o}&mq)%pPoAQP)eL||2=ndQ*;>lt&iB>-{DI;u4q!F&xeS;!oDv!9> zQ(-le^-GTJ_6!i*I<~U(9)D@XsFJ3c3Vn1Bx~mWj8QfFzBP$v-z3ln?gR_lZ|MeZYO$virL4>I+(T^{^1TV8plO!a zOABCb(5@B5aD&LmQB34ucb_{pHufIIiS`WHq0He{_uVsbVTT=KLHXhq?$H@7xrNCl%6Pn$CD_}>Dx3!@|s40?!isiB!eAm9h77U?CRD+I2Q+*)@uL zHp!rWV362q#GOz4L`^02shZKGrz_QgJ$2vkHdvr9(0nH%0&exd6J3`$>R*m?_@FP$ z*j(IBfXJlGF*E8ur8oHXOqFKiTFzF!w0&K4$asp1T%J33)KcOBEZ#ZDBJZEDwflspfic@=1V;mlzz~afDb8~qV!9{5sulPsexd9UIQGlz#Ic` zQJ`AZkbq5X;37oUM1dJQ6J(@9jw@mz%>(U5DErs+(FAZd?RWE?NYI+@q*zbj95N6Y#;3_4ODD=SE0O;G5S-o`e=X?$ij*IV+ICOY`#M$0>f^@cFK8(V$;iO6 zJpTekxPHCbl;V_n&i(@1evGa}x;jy{?Jo)47NzKUu~_6TUTOU``y;D9K_~t+F0hF!=>FYvws#~J0byEvNseB$WdjcP3 zQVF#|q?LY)L$6A~%Y3a_tqRukkLbR)TA(+6Fwi(# z{g-}4viYzL#PS1Ek2<*30>zK}Ct&*pROE{-b+Pn~z8)P<_p$|04{G0LrWb{<+sQM5 zlW1g~t6xo2{ZVlUINNg6F|#Xc11E*a*4#i4o|sGMc7ICxkk@+thPT*4cyO0jE)PwD zLO$y&oKi)*SEByy+l=nCI6o$x-x|%oooE8;ywnBlqcX|NSRL#zoUT@nRq!r7e^fCx z1n4CJ4>NuW<7Rh*-e>WKJB;(mTU%@KIvi!NYT=8-LYl!~JlU2~nAin9Y4)}8Ir$7t zBw6)i5o1`_9VgD+r#w~=C76ed+xb@Seu4dqC!mTeR&BtL`7iU6f zod`N$>_z9)FlHU`z@;Sdb(=h4lr0Bs~3SaC&=eV!pMxFxvgQ0MY$e%`(yBiyP#a6ZNjHw3GX!$l%wTC-CqS zG)3($YiO52VEAO3Lj!N#9iu1Gg=pd|3aydY@h+aXzIpKT?@}q9{uyKHbLtVI;~A^} z1Xlj*o<@X2rP+Tq81m(%uy}4(e-=vzOX;v$4WZtu7CEpv{HufQB$ecrE!FOgaw1bz zcFoL!^c$YYe?T(-@8bJift7wN{{RKe&`26OXDau*u&5y=HzWMb^RViCWR?;>v*DU> ztAG|Wm!>C8r5`C3o#sy(dDu$jL*tRrJC(@q=!lbc1mX*qETIZ@OR3-&dD@CIF8frr zI|~i(V}=mYJ{dODCh>oS3n)1`QJqD06&rs~w#sWM2+7*gaUQtbS2$pw@yeK3NND?N zXaY_)F@ikIc{HUoBq&)~Zz%Eq1s6<`)l(>;cU%0$DxVF=b;``pzc((dsXC2;9V>(Q^nY+tof`6LPuZeGkJgG`9QC zrHhsW@8VctizUHd009LX0xEU{p))U#d*44XH}DtnmtP{xGcV9Z7p8Yo@5?S5$Irp~ z+5ngD$Nr{;25OzvpEOcfJ9DTu`f}NUqIUGAM;Rbds^omRvD7uPvd*;0w(KQMu?OE& z5#`735Y`Id2d&^vbuM5~_f+rPcw#ta2h45PtVyNsDd1_BMwU+`dFn_vy$mwPjvHK^ z^KyA$Rvi`xe)?n@INyBMz`d{(SK|Mok|rAv)fE5Xk7jYp9H1B*W{R~Wf+zZJ-j?eA z*aO?;LL!SVx0zyNkadkZXUq7diLo7w zj}PfHu62S#MPx=PlhMlZ&Z^m}A~?j0br;>#4R+>w4kA#mQrBTl`=ojXjI6iLQ${>x z0z7@Y`F7*$(vAXT*NvTj{mLo;lL_~YmYnBzUQmF0kmKvA{Hj?kkE@*Q!=Sw&sF&ye z0R70SSefud;9}g_e_^)Cs^U)Pn&P!Xm2>BH>)u49k1dU)-%7}r{2A?tryj?xu?7>Z zLF&E0M&Sw|kg?<@Id6_MbRd6xofktm1{^*{tkq0f43kuQE8MUtle4FzI$8Gy10e zI}D78*Hh;xId;8oV%*K?3xw}S6sqrHM0v$ZrOLqj2Q;78{C>*&PTBr*sA;TD-+W>| z{{X7dZp-LUrgF4Hps_=&xQ2#0o8!rgk z==|M@0|xlLAxnCZ)`M=>im0UT|jCVl^pDhFZG#eQzyiTIy3naW2S|ogDpu#pDo!QH# zp$pIZ#iDHla`(`X(g|^A)$rFrCYg|Ktirqau6M87ySvf31E+%mkUT%?yE{w|-}hn{ zmWjvokks-gT%)tqW?0ED(?r=TDV){cFVzL z$*84`z-L1Qo>yBV@r{XEYGOuVmVNiM2J|8_6<=J0tGzG>aqlE<++XStCjF&OC9 zYAg?sx5+0z!@b}RUhA!%K;Erp1E7qlEvLNmB~#tL;VtaZ?Q#X7h< z$h})I4H7`E-wTT4n4%f~Cw+C8AeZcrT!#*_ zgKqu~_uj8I^|ZMrakqNXXpqHJ0mPGWSRWfEV{T*oVMg{8 zZ#4i}-eZ#arKM1PFK(&)0>gStOa;@z|1^ z$=olI4?18`%|!frdjT)L+62A}?w>N?bu=wXcNRm^qPA(h z-6I3Qj6JjA9(C%yb!-DK$aVAY=s4nB2eHnM(VoETFwuf)$}y_XN89SX$mc*9p)P9U zXvc~d-*Kjsy(To#G{qSt0)-7S6rtB9aD4$mJEbG`*a1P&o@h|$DH;)=w}T{niqPgm zf^oV5#cfyHZ(!(+`$K~g7u2!#TwN0c2hh}?L|H|_{FXa&1Cz*xpxG=r*0MBTe9>kl zclVUCzfB)ajxD%Foy2{IKJK7s^^c%-?xHa+%lD(NopU)w_6}{VeO{L^pSam=jUvyY zPd>LX3E!w9QmNV_{Ya(V(w7)1_s4taF1v{mJ&035!0$B-<0_Nu?jnAhbNYncBDthL zk8yD&g6Za8npTWSDof2n$FLzpqltN}l~K~Gh#yLpRauewmPge`s!#8YE2e!9E zczb%i?X$HLRZh=r3d$Nq4#(X>(dwA}dYg5lpubx_`-3||ni-VhFl@ih|WKgA1co2gn1jm)3lXFLCpr@a8 zQJ?;sOTe1tmE{J6eIOi1VE0#uqtx4C+s~WP`}5d!>%Gx7YrQfXr$hwpvJN?i zXbj8z!iF5B=Da4*Ja9p}zNqARSI>yeto&*!#K1g#30vLlfKDb}bC>1xf@9OM`@B}X ze8V}*h{(vHnLo4yqMnJK?(bLlkQ`ee$1p!aLBT+PLB24z#VV6eaU{N?nRBTFV71FFaO@4O zUA)M@?Ae%S6fj!A#mM0oH~*TR$8~gS$Ktqkgp7}9K1I3#*0lm2)89$p2kz@ST07t3 zGOu18pQ#{ke=ocnjB&0xBT2>T=j#P~T?H7{h0R%@GDs>_N}ac^}?PdI+l7Crd53Fd&GSs)q!VdlM{! zBAQFIqi5H;VzhJ=!YIy(j+TMpsqpQtQ+vV2$uWlDzknaNVFH;0& z88ff9Fn#DS2G%>z2(j?(pCTb!xK5AMVQihy%f?Fpuqo0U@y)AaJSB{8w4G@6&46MzezJ#LVtbX!Swpy_xky88$@htQ z-w>)L8jZyBRGb>ZJ-Xg-PJnngK#B%jv&4>^!sS>HqN$@Y+dNve?#N7b{%aNHgz<$x?LVD{{Vi2>`GKMI?m@pTj4h13re7}c zP%e&Rpx`i${zRAW3I5#(TXHb+U(1$@BCY+CI_q;F5N~{nwCB5|)~Zjo6E4~NiX=0~ zOq_#fPvKfRqU4*$SW@4saC{3mvNS*`9j5Q+v+JUR-Bnc47H$w}W<<4BLp3BO^$%nc zDW&(+()q{z2?VZ`OE{)H49QP+5=*`YSAx9>(5VptD&XQ@%}BsfRH#i8VEArD0|OX{ z^zjJI9=l+G0T_V`dtO3I7Bdux?w=sS4i6iv%%7=9kmIlaL+whqj|Hz%&@P9q;G4WP zoL56x0>2p$%nOS8=eS$|Q!N&=n@*xNJSog!u*VA|LF=Wtr217BsQ&p@rx_^%|8B)h z6Y3Mgz!*8DGmoY*Rs>#~)0UE*6uNXfZ9bWtqCqa~ydXI!tQsh0>`hbdLrcYC1eHQF z2`x1z`){E-g5)`mz?)cww69bEguY_B;hXmKk_ zYRcjgvYNbF%X5ibSGI7`M&17Vd?J^ke=`c3JQQdxu57t>%u1j=hb{S%|kY> zRTut2ymJ5I6UrAWE1v(+sScI6-2ghaMuqd*t^~e|x|_X!>C}**yn!uanbGeCzB0UW zV>b=v@RWfI4SLH@21e^5YWxBAsycUa`bWOL#s5uWyVkBnoYkx1HLHLc&_Vncj18NA z20Q`^v5L(J|BU|vnWf!#1#Esaaa{O5f!^BhPY~mcS~Xs&pI4otb21yEuQ5B_Sz`|B zd5S~h;mOFogreWXb@Sq-?cm~AFiMMG8?O_EkwM$_(3rL?^%0p}^|H*E1tj+#)dKyj zd##%V7!576++U|ge(1ZiDFvb)#`RRkiu4}<=ECJ7K#}31vAb^~rre*L!t8g)UF2QU zVB3`>YxU|9bNxSyQmdH%zoL}vUC!~vjo_>_+AHmUrhEgTU;ah;cH@7kp{q6YKG+8R zIa>mvwPsUx=x7YRY$-%J&i3+BA#ArS6{?}C!vB92qY{!oD#nLB{|6;12kXfyM*e?L zqTD+&mI;eJWp3CNiC8=k4zA#&r&dUXx~R;V*0aSGVROYYLsn{vXqEQqDy-dRr_n_{ zj}VNQyOzG){Uq?McISaChe?=9RsbSGp&g8u;9w(53~@PZV%vHy^ENC(l<`cpoMNoT rP%`@YZ;rG1I|<7N|MrJ&e1SJDMk}I%doI3vwSgo=WkqU)^aK7E&I(x= literal 15225 zcmbW8V{~QBx9($fY};nX>W*#Owr$(CZM&n6o$T1Qo!q?tbMCnq=bUlJ{jh3%*tKhq zxz?Ul^?T-1;c_yfa6hnr009BPiHiv-eBZ0SuRSP;?-rB)OCJb`5J+6;my%o7MYpe; z=3@5ImqUDgq6)l>ogQvqzBw1P^*#}6=1hVgE_q^;;C?oAF(|X-F`=m$&i;v1!=pe) zv*vAbCt^~5IqoVoLb!SPJbJsXNIHDWFJKGX;T2+6YTLSSEouZnG%T_Zv%*uO@9|iQ z)o8CT)%xu*{Or=LS>E%nxW*begY z>H=Y5ZrRBoP=p@cK4v(9%3jC=*6cry2hEtphc>xGTIk?oC)o4pOVgssnT`={zA|_) zx7Yxrj9cl7>GE-Lno)$9*1K>+z3^g*LzI4MTHeIOyDcZ++0wsBS}>6LO4Vo7$rueZ z59W4Agowd_`Cd#>;kv(?lg>9n)giB7!4f3)#WF5}`{vM=13m9s#)<<&&aIk&AgRmM zZd<*?d*fwmXo+<@V+3nQy^d@ZX!i*c$0n|k9F}j~Jb58B+;;Ol0Yz_Ml6MVM^i+Fx zd+G%!9O6yA(W|!#4Gj$(OISs%?I~4NwD7rbCA^2{EI*TsjOAwma01ii)C~>P$FQ>7 z0sS^H%E^i*oV8FIH|#% z=Jqjeeqw^t?&cmlE0cp0*(NGwSkL{uML@QT!~*M979vNkBi4Qp@gK|23BEbDV1(wX z3=%4;E!U88dEyX#F2V+*9y+MN;1x6W?i@7q(g5Zb2FdXN9@KM=m^VRY3~Q9MKAl7- z2-kXsgUkgCu$aCkM(SKhEFA+okgKU6T>p`k0qQ-dhVCg)eLwNA>m54Fj$T&=-fFYm zNIMC{>)i&@E9=T=-O?RuMB16{TrN!4gC8OFN=c}%0JAQy1lvsY0Xc4?8ks)8sX%m( zxu|Sni6==$HEXK0?T5kzG-PFks9dhvk>v|8FnnC&oSOp|ek?J`BEmhgAO=5DeC4=a zx#~G!x_wIF*mixAYmU1jaVU>Zec-8K=Nfp*-!ckS={q5AXs~F<3!)CY-nYv8bcP$h zUGR83y#|p$0JnWrdakHLeVFFvKSn>CuQi*z$`ZT&lyzSh`itL8gFJee(fnc#4-52k zy?EO>N-=TLp#fpDH9n<$8aG}=NQ``Hft;AL103k~v3QE>QCw1q>}FN(58)`78YWhy z^TWXPEqTx2LBG4$S?LDfVGV3z7drZV6MsB#Dnkn+%1OLAK{i{4V%Q?|o@~MWs8C|t zbvZJ|EeF=X*=6z;jep$?$U!w(ZW(vy>+E4C)-S{=rG`?7`&PR%YUfsTMMv>d62vu7 zMZD{Sn+OEbah4irPVa?-P!d{V;>$OK)&hag+-B9UObZAo~5@g%!#4rFX4eX-Xy=Hr>k!e%4r20$D;u6pl12PoDsz#Qv^u zLF!SRm?KtvBnHtH^^d!w_8xTnyrT=Cl}L=lj}b-;$S+$f%|yvxJ*z++NojU{6=k$w ze9T)|a`Nf07JU^)s2Ni&CLUX|jZdI$1{V-Z808NF$>0IOvmdqM1d?Z2;jJvHVR-R1 zOAt%}Y8uLD{Z_vz5#t013G>ASw9vc#bTYhvu|9n+ht|@`2Ors12CJY#sxB=0rpPn2 zs$I%z?;^wTLw9GVL|H$+dRO)FVw=7RvjWCysbx9U^;_69wT4x^2PINDfLgE1md zQMnSv8B*MOrNo<;yxvg_3A7CnmB%s6MM+#soG23KRLs)Atz+wq7x}i*{UVQxE9$q8 z3NE#i17`Ny4<71X%C9-WefYPVO0#s=ybugTeZ!@%C>QOzA}Ef+%ybLY5m z^H(Esi_A{C<{8qkTi5TV)|=u?a4DkOA&~9z#3go{ojXy_6I1CmIyUtU;_zutuMe&A z(xu^aa5Oohl}^+do{^v1@V^K=(;t>fX_dX5|jrd$lQLx)QaF z1(^Q!0AQinhH{syHKp7o!vP33lC{v}f&tWfc|Y2enIk6BSf1v3r(NOcd2K!>j;~Bk zIj48qF^W~5DMNqiq?O>d=YWHSm?kPyj!(Np#eCj`FJ1Iqlnk(xERH;STfy8HdPxtZyS zlNx*sw}BPYcWMY;hb*}}W1qPV25YV-FMF`MCg^H+<&^+K3({<6!Oq)hsP}7NnGd3e zNm6jDuaf~IV`F(Oh5nOEcngV!ztr?4MO`sIdF|vTgzHE#D-GHlTfeQ{nbcQSjFJ~; zD+jHco>cc$CkbYLD@araif8n4Or!E;|hMDPnwE?C)pUa;{u!JBJyWZSu^^kCSohHZdc zb(nBesta$+A?!M-=z23jwujf)@+(;z=rJ5_`#uH*Y1?~|Y%B3(&Ub=5feNzEb?Sqs zSJsej$t5;Th2w3Ko9>g8RK4X`-q)N_-WoWZhq=YAuCx}{K6c_ z1DodW7&U>6!%FkIBV-oGo5^aU72xrw2L9JmQt@?|j~ZP_t)||%jm~*@>;(;946xhr zGtIenFW!-1HIG3x#BW##0b6Iqo_eT&W#D?GFaJjo8K9of-hjZ!=XIcqE-d$;-Y!>2 zTv$DRxvAH62Z&XRl|*W5#2+J=fLCeWq)$e9=gfg4*H5(ABt9Sn0*c$+FQL1UEyenW zwJaB(*vUu(gu8u1P0spTsLztCcwemh-ksf=&Izx3j4i`Pw$SOV#@K1E4xl}_As*-6 zn7@#|VDy5X>aSfH9A2z{^7L!Y*ONnbL!3#B65D>m-g{w@FD zj2B$a(~oOp@Jh|>c_7J<>5&>uuAl3$6aIA`L;%LIaqr!-Kv%fI$>d*n7$MtOJH;sB z6x-^%Za6|7I?3Jhr?F#P-E&%=>(Rz!qs3vui<@ZDc>Vt9fWzm8yMSAz1Q%+i=AGfV z-huv}j4cK+KT0Ck_fFT)fd7HPrQy+V#2$#}#&LCQ=gq&(162;3^zLeHVdFuJ`%Vn)jaYc*CIo-^`qH*M&;IW@TG(H$`Z z|KHMC1oo%hyApM3O4=jiKF2zW#-bQ-u!@X@*_z7YGR0`?E+}&F}y#yYM@9V z(Sm(KB3>cP^JtN@5yn@{TXp{|_a<4n4wnar;Zzxcpvz-{dge(Qb1p$>rb_jpY;9*w zv+#0b%QZEd)fzBYc*k->W1WoPNwiX)?(sI9j|W|UyNw7f7nOgshN)$T;vYa`tUQC z6@p=Iw6dT^M)FMsvM9{Bpw^NVpLIZZ<`a^k~i zyqLnneb(hu@wuJ1>LPk<*LP3)+Bk^>KS|Ej|4N2@d7qcQ??TbrM$n1jeIbOzvYtk{ z@1A(=@l`pJk?l1O12k&I)$_5DT zGj*t}tHUd#>@EFQ z+3Tvb7h{2#NB2V}X3x#m%Inw_c~)tSZ>7Nt-rDnW^H-oZx9hF$q@CUw`R3dC64izw zm&*IegI}=e6^{AQmuJqqK1S?%1J^};jjub{$JUqdSi65?$x=i}AebPEV=+Ga1?A2l z(9c$D!_istM<0hN&qCQ^&YZ|H%ErBiRD|XVCzn8Jn##BT^~Gim*#lsrOs+ z9I7|uRNu3GyOWBn&ZFYMs`pl$a4$>GQ&0FDqO%x+xzqQ}G6;-`0u9N;O5*~BmC>T; z_}G_FNRDR_0x2TBW>wTE#g*Qu02-KKDJG`5BSlAd{9x4>-;itW-XrHP&$jMfl9}1j z4ChKJwIZP-V@^~p&RJ!jU9Au{CPa~l%hF%huJk=mXOXmD%eMBHGBmO1(R}r#6tU!Y zxutMjdSBqQTkoYw{XfzRLO&44Vcw>H+8?K8Yt>7QZ+jA4w`UtCY5iOwlwATGucob6zaUPlsyEtGX^1a8WECaDgj{5Dqog@DTYyi8dJ)P;!%peFl z#8I?5oXxfjew{_=FNukh0>4G_iPQ+qqDM9WJxspww2v1>s7t|}YHdh#-2lk^dg?1y z{(BVQRs5~dUx_Fy9A6=ljR7WjqPXNLRXkC;kCTR0Y+=nUpD}9bVO}N<`H+Rz^GXEK?jC@lV$jroqx! zkk24(GJo|EUXV~nouuRt{G&8f#hWy744yqmY=Kp9Yr`F?4an$HRcq_qP(e5O*=_S;JQAV>Ez^O(Gu4XURo8luQ zouE|W_n$}ME!&`E=kvKt`Ke}LpU*A)d=&>ghsy><%$8wjDOm!% z&=|fE>y#dcoNgl7XFSwj_=%pDN}E-J4VH*9u9m(AnFe9~P>ZkeC=@7uCU<<` zE4|H2EY#Nlafx`&s1W68jN_PqdfhSIuMlD6Bqb(Bsueu(ua^)K(n^LJh6txLf6Jf- zkJ?2->TT4h$b3!W1+K@s-#t$>`fbA$kcQon#LzJat8fuPcE2!^VmSBnS!j@kJZ`My zS(l0wZg_`4EO3;z+CQ!h8+Z5QE_@?T(FaUI10`UJOHkIvVxka~-KkdzK|r_H*Q9|7 zujII|nobQq{A>g^YbTx}?{$qx}w}w&9{%XY(^DJiGF+Jk%osem(Lw1sKDP0@jS^-G$v| zdtB9wXkC2emac8~Zab4dzupjMQ;=dtU1KE+VP{I!4TRU_E0$yZ8T|253;ZSbaNMKq zsDzHg3u*TT>#^zj@ljKxd1mXv8xJtJsDa6$IWmR^*{_%X0qLB_V9<+mKE3G=Vb{t7 z6QaNsiyyM#sa`966|iYvg*{fO&adXG>w}P#J(~`@tDkL zw(#+qs=vp#;mi8yWhxcsNcJkHV2F~5>_l%D1)%nBB!apxS}ygikKtgig9KlzM~E}w zmN}gnSp4D0MXy2rpx$2Fgv9=R*U=KBr2a_Lto!xQ9-eaof|PN%KK@9M!K-wFzcSjo z<-(t{Ks?Ox#*Bo1LqD-7U*))N%>^EHxWD(e3RUb9(*IWAhYNVdJ|b~o$X zJivSFixZvjNR)B{qMTc%cgd8V-~#*nm4mw~Lz$03`KeNw*ZNlpGH?~A%D~nPv2lvy ztypc4<^jEubwM?9(~O{$5h}bS)PMWg){X!mJa0 z0@uiz7vvIldVbp=uPl`z!}H`4YxO@G8Zhde%<)&$i}$#ejX*%NDX1pL$Zby)Zqbe9 zAEZXSOrihk3GM~|Zo7lDTK#~`x};ylLwDk6n}1f)_?n-{3q5Uibr2M!(Y_?7ez3d7 z$D`;x>Mfg;65InHObrk%RYL7)>18tMFw<-CkIE>p~G3B&%zB{gouF_Eb z{h(M+bie5;xQEO6W>l1a^V=Zs1xi;+4VIZ3a#yf8eXIZnfBQLbV4x|Zs}lI{s1A_h zVnU}er~x}6rU8j!d`$>|F_&58%vCv}X6|Pe{NU0lnysZ3)Y9A~M!4G`)ZBJ-SePtU zNfo;8UkbS75P+Ofv2>M5Awb8S%z2eHdl)}d_}-&1O?nt$7FDfH>|Je8&Kj;`nxayx zNehwfr-R)AF=$+is{NTxa>zZ1w1nQ<5WzA8 zrnCVowlD$+ggG4LK+`eWMQK#J3n_i2P9N@kQiSIH*n<%9F6$6}*Y{#V@0y5-3^J~0 zi_AFunMV|x#zei0Ag)>|cn()RdN*HE7Kw%g?S2X_wVS?ewk)-!_;-zZX>2TsB#uwk zGQ-nB+;drt{|~_Hr{$TL_TD?AhZ)-(89Ab1x9H0Qv0j2otm3^O_Ox3cb*~gzUG;^J zG3GLHPnZ}fYP=XJv(oC|ApU^CQT-hG+))G6aY$2M{T*hKf-n+qAS<{Kv5jSeAH@u{ z2co2<0O=exxnjfPf}V41&$iNar%-nN;uWV zS#km+V&;aPL)hOs!j3ttO0l*I=YV>monye+jGk>Wd8D|zU|7NutBwpOlRiIHkfiC8%yI4(i2e9}V*3YJ;4fVof*rR_K zu&|4f%TjJLuT&igel_C=9j+ZKS1ksTY~GhF?TviH1}p7p@7^`HXo0a?OIs|l9Rm|N zES4FjjFEaJTvVQfLVi?9v{8gahg^T#K2a|%TQ+x`>6 z2NJQrz$(8ODXW97*lBdg{<6tGdFwH&%6%kcy7v8M%JrQD&B(8)bST)coeY{ve1>#? zXf;?=>zR^ld7kj5JiP}wW>)cZG@88!n)urtG4&`tF~tz9{yafb6lsvVG}lSL(w(r{ zaa0F)GO&-SDK?=_-Q|@|k!%T4ZfBK$sH4UTK1JZh5E_65BQd*cE<9Qc4ZMdOFuQ{h zv!ua+Ls{IP+WbMCKKT1KG@I&h)0B-^yBf{__h%hqyhr-0=sl{v0VtV>eMe`}hJN@9(=qKXMts}|{W0wvT3A?b zrFaw}*ZA>eSzC!-KIV^Uc7oAGi&=~2eT$|Deyf~a1e`CQHr6Rh9I3-8)0VQLEWxdn zQ2oItLvv&AZi2#(1MjLii@&e|t^SF~zk=X!Zp*4F)-(fN&+c(EaVxPx`KHj(4zKHc7hO1N`f)hf=y>TrZ>43~e`0AWoj@f;9~>Mk=f=+O0;yi)nG)F#kI&5Gzh)O7 z5s_FfEG5X=e>^PTmCNdY_cbiC*Ogoseh+3MbJ=^OM92N)s%P#MaglhN z{llT5B8mjV#jc(32B8kgdIsI=IiyGTz5WEqXlsJ}6KhKEkx4gWT;E$^1ED?9%I zKgTOI=I5GBgu~9g;+Ef-pw$F}-);9mX_(85*ES`0kB8r_Gr?hlGEsf3Wy5D33RyO} zlU7nQ2vB+Mu~0eK;h1SlZTBy!khG_YDLv#)=28pV>Z)aR&iibgT8zfY#(AZQcNoM)e5}788_v`flVn{;rM!OD4_>5~{7=n4?27%$ zQsl9iv+P=))X7he^ta0&4fDdk+9Qq?eCA=$%Fx7t0^>+Mj&5<|9Rq@El{T!`nIjeM zikT9Yh@@`C@q3{z@f+?@fk)A}TbWf`UL79ihPm8IW91d0Z3Uxa!$C%~tvUrAbKx$+ z5r%<$d^gJ`5%ixFwRkHC@1U~Fi?hx~{Ce7Io2u>YW{!)???!5B-}xpS@-|UXB)T~8 zU7)gPO_30B1E9zN0pYOz;{{+M;yrJGF}?26{d~;JGJVGwTSoJGY1yI3kJ-j@? z7U`T7%rv|_Ua}PF!bxkuN}Z$NtIE`5-8318Gp>bv8-}$plORIfH~@BE7ZIPv=e>32 z=CR`BF^kEh7?V~mwCe(a6rQeK2z?iWlqT(DVJV+t@F?m9mS8{EM4xTvpDN zRwh1d^y0#L`W6ir6?FBX;sw5WHVY0Fy@8S)pQwVRH zs-_(WcAeFay008*T;9xn`Vkng=2XHd)Q7rXwm5Xh?ZyvwUp8AW_%oXB`8EXHu9pT| zuGN@+hb*D&E<)Jkz@@7 zoH!4|4*%e^+^>Io?9VTu8(pFto~B?-nh%3LhPmS@_gS!uD&;CU`pv7V+;k>`-80tn zF#oW_hfx$8afH9^TiC?}(XQhUl4Ufgm!WTP&*lFl{k{7Hi9U#YnLZKKl{Gv!zS+&$ z9cpg7Chl`%i6E*$cw3H9R_U2TLf7}0{&#UbpK3j(_W@TDuG#I&m_WE)z=ls)ID9co z>lUK`m1Q6e$$dxZp<%~gXA@rFao36u8II}MKjeI9g?8>RG1ng?;otZ7_6m1PO5}kR zp~|C_3-R>d$_t#@f7Jlg^I9*kj9Y%8@y-%PqYW7uC(q@}aHg?Y@Sj`FZb^;aRyXAh z9D1Z&EYleZ%llUxWs#rWWzzkyDN=&Oxa5?0IsAE-ohb>?EWxOG-+B{=v%XbiYcbr%LfUo20NOsVvC(Zq<6!>eVM6E&5SfUL08%)Zg|5se!G4vLu z4dGSOi!6iVjhDmN5;P%S{0U}X>K5aYNsbtbI%{IR3b7}A%984f zOc^)`iUs?PRVDTdnk1`^5w~;9G0kL32!FB{l9Cl18&Fu!ICdHBkH!Yf@0h3#ORso+!;X{U!hh7gAsjlc|AR*P1P)&n=P zvqr*1rAT#4r;WwgYGa(j%|l>w7yYuq4ScP-Ss#XazqKadU#9VV#>N9h%0zEj1)xle zo}^5e#5$os1`P)!{GXWmFgogV#J{P26d@agYfahg8dTcY46T&qCn_%`j=!@d4tW*wACj#o|1jr$N z`2xQxkhJL@u=o0)LE7c-jVvrJ$SEocMqlXKgVuh1ZWJ{J(Z5pwwc2R#-e;REs#I}7 z!T$cPiv!vCJb3VLrsjeg{!E4_v-QmOuVHD*+l$GJfO5r`WNxA1^-AG?|8(yAQ!PAT zXh-wa#F6qANkj;x)L^Z>&L}nB{JP-Usejb%7kK2$3*=_z26CUm5O0>x4AnN>M)5@{ zniqpPMdeS#;N5yftlNhEo5)XCt)f!>Hk~F>!IWVZgsVm;#cTozuLcIAYM>xck>MSu zy|zV<6@SNe)ADG0o?&LNGVhI<9o>(-Awr@N3!RP_^+)|q3P=Y+v)^Y8l4J-uHUL6E zHEG{Ab!wB%b&{>ZA9RYX=Y7^O3+VK#gX2a3UphA{?sSTPobS z?=ilH-|NUy9a{sa%hk>lIwJr+4neLhT@-=LbIWDjz>k+s9%NsnD+gpVlel25KJv7S#H+8yJ(>bvwvPLJ?2j*q0n)sOV{nsn70 zKKxwk92$LXz7*i%o&#NLAj5DccP#oP+Au0u!d?9Zl6C6~nK&WKoOi8~#e6FrO&(^_ zjRFaQhI!-VO^2bWwXJMqtVO%kPKsU0_=ufMOUEbJBh<4Sa_LsN6)cjTy61$g8;l0! zl}4Hiv-F8R^;np*0HteAgXjS)J8b1ejYf&IPaXbvE4pBC5)9**xvjH3;z;$5CZLP7 zV2!j*e1iP4kYbvMG;x$cvpND@UB5CDBw^v;`7#oCyEZo}gp*Tfyk72n8{EV6IpO!B zg#pJWY2CgWh^n!slPj}B(<#%H#xF`XSHIhDYZ+r{1)Ds-OWQA!WeIZzwa^0>< zhbdIxRgthg7v;+)T>OqwNtZ2&NzwIoSz~_;B!D%Q3jP2xK$aydDW&Qq@`}|EV5xl%%uF(FP?M7!kGbC%CtO98{_%`F=JH9YsGtv#p=DiO z=9Q2}R_z){jGY}rW>`vm&%dQ4xQdrr|AoPUQ}h2eI1HlRD@XH|&rgxfLd`EDmQP@f zk~9O?;~>JiK#$g`0V=8vPW}%SsFIf)*XAiwh{pgI8RD%-qqJ;Skk7m z3}dx28QJ|*?>#ia1cZR+8{B=?y607uELycF5Y`WLTx~PPj{fVK3&_F$|G9LJ0wKi; zjkg#^kB~fxsV0Z<^avqFViB`Dc9U?a(F5?n)$(A9dfw>)=n+4=Eu31k09y+a%zzAowZ(3zj+12E!gpN(+3B7c+ z3hKA1F_jVEyslggDz)B8Mn67D4r%88^a1ewxv~#z+l@m0)zK^fqY0~=b$OoOd4cK9 z1xcWrE!#3z9#;*uIwFBXfqh=;o0qHj)6@OQ2a+6@$G0Rp(U~H#6z-_zkSZ1@c7)}0 z&&BnoPujc!EFS8}KkK}_1FCF-s=TrVxc&rguBb`yH-6?Zjkcg?w?rYNlYz7Qps`{J zlwrbBPuO>@6$P6I!rlp-bk`cWPzH%5vudt*0$L`S4JlTdAk$)fhK!h4hGooZ>V!Sv zbromOC`?*+2}{brwKzw=qQNfhXR`_`E-7Y2!Q?c7>Hvq!DkW3oV%v^InjWhwZhzxg zaRfDk(kP`;^EZ#=Lsb1A&54y|$WeJ}p6SfH<=C4d& zs@gJSa?GW?$!@1ByUqG2B1~W~$woD2C^a(e>C!bD)S2*EqlAcVS6FLJTzsT(vC56C zh2_<}`}}_~47M<&!Ekze5^*}EJb3S@+_h+#pL=I zu^N>~l}a+z!h>(yo&dh8Su?CJ|IHj%g29{A!1#h^Y@_!E_0rY)2y`a!dMO76t_&v> zElzVbXA^HvVjwxi8{2TGZ=nh zd&S+DC?3yZGabn0@3&hBqG zas*RJXLQ712Q6J`TMC$8o?aEkFEeTH{o{ZSeJ#KP25|D1hp zW0v=zaq@>Es-GoHir^gUFyW;MB<6WgQMzF4qD2oo^PM$rbo}$rA@~2WLD)ylRVgVJSzXV7-^>E zQb`Rm?U*Kn)^;`{sq~25e@b8sZLe|=@qm$odK{FL+He%Pr9g=Xrf>?@^(So2EpsLI0xrlGtlDQMD16AqXx2#+Wb}O#W9vDl{bshp(wTCPHT@} zxr}yst;ISMv}EyMZ#QB;Xl{dL2aix^BrSIlc=s`Cmub8|^NCPz-awgSB0I-8CjO37 zF+(-s?r?`fwpVfUGPt&*Nphy=wbe1lj-$@Qx4y^ljXh#me;z}?DAN))0Ze8;=7Mi57Iz3S{G8r z2@9n8dP5+c>=*fk&qxWLm2(f%JVp*0b8UfJc|tds+HjHTByOq~{ z-Z)~QR&$WHoL1h!p#E4yvT`fU>9G`|8+d1CIW?UMt^7FW5)Y3C=B0IENtF;*I!#GI zO*$Z7e>KND!F0`A(A+cQjFOH%rkL9+Nw=9)g6li$@Jm>8LT@!zJuu=J9eg|&m3G0_ z2Lj=SEiwUg5t%Vl#NWjXg(}&8%9aq1a;0+_nryy!vDCC*GwFkyGlVUtfVq5#PEjEc zgLyavtNV7;W&CV$E4E0?-9Vfcz~|$0Lm_$O!m_4t?F6zqsSMSY zln}mArjPKFNknlM7^l_fyZG%exD?Rb{#Mjqlx1sH+t59c)yPmGS4&B&IUghOy+z`NTu6< z%+saL@Tj#+QxS-CiE3(o9Ry+x0~33S3LsF9p92w4+ZzEobIqv7DD=3)2@8XxnC%?K7j=*J@H}1-Kyqw>9N$6(zdwKYynme> zC8EPDcBa@7X$_L>jwss>IeGg9zCG0$UpPcm%EWi1(%ulq%V*kb32%n$j`TuFI{$R_ zJ{%L@__WGTscRJW#X)HIm$pSV-UB0O3S{YpYw+=wdPMV@hZE4b%&ika*iXLA7QMpZ zQau{g$hp*>T(r$C*p+A3tzHw|*zhbj^c${NW90FT*)AMVbp1PZNWFbLju$k(Ohse! z=3Wg>87w^hAH>ntY{4*6k+XjrOOMDs_fnInWdZi;wR>fmDj`_Rfr}1Y$lA;`w8ZFw zXV*4sj99uxqkREa4-r3ie7i7$El94J`26lYr$Nw2wWz5 zt|e%iAYu5&$G21IH1QyBF(!C+8#!Ir7l1%BYZq5$;^yJSYGT7(-l1C8o2v(wf{xDE zkd2N3OE;w{(GR6B@0N#=%MX?zOsgv&<`NYNfB%T6$D~@^1|f8E^%j>AZDW#iqnu{O*9}NQ+U}bQh2B zVbH!UxXhxKG?Xg)KFTA=8!!|kJ23y~97f0T|GCZ~2y^Moz9grC^yd3H+zohmbKh1Q zIp28HV(i`MOC`4vE`ao?2b>jaoRqOsicA_xJ|lC#lI&JR;aN5S#e9^#d4L4>q?n@a_`+Znq!)llwNAL?*Bs7+)o_RS?E$&RWo0c6}mU z^+c+P-hgZ(9K@t}y8h$w#W=VgxzZ~N;dRMah={iHECk}b@0i>4N`=KT1P<`mHQa@8s+F(&Z6n9>b8XMB$mNwL-DfFQyV={q`rx=Am+i-bg`1U38yV!yJ zMdaT?;8m)Rl#*;cI4B=F}1fGPCMr-@p?6yDoIt zusI1mRZbBl^HzQlkjQnRg&b|vwSOrn+|Wcw=mHu*L>?DbxmG=jIUd`zu9a3Ww; zt#i{d?3GV@@kzvA4q+=K zs#3W}_xi-f4E?X#on3!f?}kQR zFkJ|>jO*jfhD#Jrc3^Dn6ouxA(q9#mfT(0P8CHPomjHjM#pCVe2fP%=KS$;$&SVl$ z1KKOy$M%NzZlYe>Hne%{6f>xQk^XTfr113TkgAN5KCQ6+w?h3zT-*rxtHkn*PVL+= zaJHH@zCB#}Nk&mK1948sX%Iy0FI;WlaJS6CGR1`_@=7PFh9@O+lpDakcx5HW;#3_XV5*^I%EoF)Vp~XV)G<5p(TCMi=9^JP#{8dw3K}(}Blros>plw@$<%#hB5V rC*`7i2>&k^QJDqZzpqofU%+u4jnI=5ena0!YJtRsWrS*e>jnG|d6*99