From 4308c5a769ab76a45adc5a1fa365ba566dfd7ef1 Mon Sep 17 00:00:00 2001 From: Mike Thompson Date: Sun, 11 Dec 2016 23:46:55 +1100 Subject: [PATCH] Docs WIP --- CHANGES.md | 4 +-- docs/ApplicationState.md | 15 +++++++---- docs/CodeWalkthrough.md | 44 +++++++++++++++----------------- docs/MentalModelOmnibus.md | 11 +++++--- images/mental-model-omnibus.jpg | Bin 0 -> 14416 bytes 5 files changed, 40 insertions(+), 34 deletions(-) create mode 100644 images/mental-model-omnibus.jpg diff --git a/CHANGES.md b/CHANGES.md index a2a1a61..60779fa 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,8 +2,8 @@ #### Headline - - Docs: a rewritten README and a new "Introduction" section in `/docs` - - [#218](https://github.com/Day8/re-frame/issues/218) Make it okay to use `subscribe` in Form-1 components + - The README and `/docs` have been substantially reworked. + - [#218](https://github.com/Day8/re-frame/issues/218) Make it okay to use `subscribe` in Form-1 components. This is a big deal. #### Breaking diff --git a/docs/ApplicationState.md b/docs/ApplicationState.md index d1be34b..2d812cb 100644 --- a/docs/ApplicationState.md +++ b/docs/ApplicationState.md @@ -115,13 +115,18 @@ source of data is elsewhere. ### Get You A Leveragable Schema -You really do need a schema for `app-db`. Yes, it is optional, and I breezed past this -earlier, but now I'm thumping the table and my face is red with intensity. You need one. +You really need a schema for `app-db`. -The [todomvc example](https://github.com/Day8/re-frame/tree/master/examples/todomvc) (in this repo) shows how to check `app-db` against your schema -after every single event has been processed. +Of course, that means you'll have to learn [spec](http://clojure.org/about/spec) and there's +some overhead in that, so maybe, just maybe, in your initial experiments, you can +get away without one. But not for long. Promise me you'll write a `spec`. Good. -This is good:
+The [todomvc example](https://github.com/Day8/re-frame/tree/master/examples/todomvc) +shows how to use a spec. Look in `src/db.cljs` for the spec itself, and then in `src/events.cljs` for +how to write code which checks `app-db` against this spec after every single event has been +processed. + +Specs are leveragable. Watch how:
https://www.youtube.com/watch?v=VNTQ-M_uSo8 *** diff --git a/docs/CodeWalkthrough.md b/docs/CodeWalkthrough.md index 23b2585..cf258e7 100644 --- a/docs/CodeWalkthrough.md +++ b/docs/CodeWalkthrough.md @@ -2,12 +2,16 @@ ## Initial Code Walk-through -At this point in your reading, you are armed with: +At this point, you are about 50% of the way to understanding re-frame. You are armed with: - a high level understanding of the 6 domino process (from re-frame's README) - an understanding of application state (from the previous tutorial) +By the end of this tutorial, you'll be at 70%, which is good +enough to start coding by yourself. + In this tutorial, **we'll look at re-frame code**. + ## Table Of Contents @@ -35,42 +39,34 @@ In this tutorial, **we'll look at re-frame code**. ## What Code? This repo contains an example application called ["simple"](https://github.com/Day8/re-frame/tree/develop/examples/simple), -which has around 70 lines of code. We'll look at every line of the [file](https://github.com/Day8/re-frame/blob/develop/examples/simple/src/simple/core.cljs). - -You are currently about 50% the way to understanding re-frame. By the -end of this tutorial, you'll be at 70%, which is good -enough to start coding by yourself. - -## What Does It Do? +which has around 70 lines of code. We'll look at every line of [the file](https://github.com/Day8/re-frame/blob/develop/examples/simple/src/simple/core.cljs). This app: - displays the current time in a nice big, colourful font - - provides a text input field into which you can type a hex colour code, - like "#CCC", for the time display + - provides a single text input field, into which you can type a hex colour code, + like "#CCC", used for the time display - +Here's what it looks like: ![Example App image](../images/example_app.png) -To run the code: - * Install Java 8 (http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) +To run the code: + * Install Java 8 * Install leiningen (http://leiningen.org/#install) Then: -1. `git clone https://github.com/Day8/re-frame.git` -2. `cd re-frame/examples/simple` -3. `lein do clean, figwheel` -4. open http://localhost:3449/example.html - - -The source file we'll be reviewing is: -https://github.com/Day8/re-frame/blob/master/examples/simple/src/simpleexample/core.cljs + 1. `git clone https://github.com/Day8/re-frame.git` + 2. `cd re-frame/examples/simple` + 3. `lein do clean, figwheel` + 4. open http://localhost:3449/example.html ## Namespace -Because this example is so small, the code is in a single namespace. -Within it, we'll need access to both `reagent` and `re-frame`. -So, we start like this: +Because this example is tiny, the code is in a single namespace which you can find here: +https://github.com/Day8/re-frame/blob/master/examples/simple/src/simpleexample/core.cljs + +Within this namespace, we'll need access to both `reagent` and `re-frame`. +So, at the top, we start like this: ```clj (ns simple.core (:require [reagent.core :as reagent] diff --git a/docs/MentalModelOmnibus.md b/docs/MentalModelOmnibus.md index 5faf168..1baf5f8 100644 --- a/docs/MentalModelOmnibus.md +++ b/docs/MentalModelOmnibus.md @@ -8,6 +8,9 @@ patterns of thought that produced that government are left intact, then those patterns will repeat themselves.
> -- Robert Pirsig, Zen and the Art of Motorcycle Maintenance + + + The tutorials initially focus on the **domino narrative**. The goal is to efficiently explain the mechanics of re-frame, and get you reading and writing code ASAP. @@ -16,9 +19,9 @@ and get you reading and writing code ASAP. which will deepen your understanding of its design, and help you to get the best from it. -This tutorial is a tour -of these ideas, justifications and insights. It is a little rambling, but -I'm hoping you'll have had at least one "Aaaah, I see" moment before the end. +This tutorial is a tour of these ideas, justifications and insights. +It is a little rambling, but I'm hoping it will deliver for you +at least one "Aaaah, I see" moment before the end. @@ -94,6 +97,7 @@ wrong places and you'll end up with a tire fire of an Architecture. ## It does Event Sourcing + How did that error happen, you puzzle, shaking your head ruefully? What did the user do immediately prior? What state was the app in that this event was so problematic? @@ -124,6 +128,7 @@ Here's Martin Fowler's [description of Event Sourcing](http://martinfowler.com/e ## It does a reduce + Here's an interesting way of thinking about the re-frame data flow ... diff --git a/images/mental-model-omnibus.jpg b/images/mental-model-omnibus.jpg new file mode 100644 index 0000000000000000000000000000000000000000..abd45b8232ca5b2096ab76e802ff24ff2c1fc9c5 GIT binary patch literal 14416 zcmb`ubzBtR_dh;_ASx}L(jiMpN~v@T2nf3i5=-aOODZVR4bsvL(j}mDigbf?gLK1p z@#U-DpZELs*Y7NknRD-)bLO7sId|sXJD2OR>p6f_%EinW0OaJ@fZM>|biE1SOF9}_ zxB@5uIFt?fbjMm7d8kfDtgr;ENVCpU{PmY@fkQ&14a9m^woFg(1SiP{@c*T#Q!4McBp4)(YmJ zPwQf3X>Bj;B1-qmxG<8xsph1k{UzdHAxih;=B~6am7dc+vw_2C`9NG8hFttywEWy4 zZr(=%0s;?ddAPW_IJtN@xp_Fa1%!Edgt@qAe-j<@Zg3-GVKqtV-}ge6MCpDzHoAK39~nZo7p;;*;v!wSkyPLadZ%+ zL$>q}7p!dmGW%b#`iG#B(*L)pmDLRZzs%Y@sKNej?|(IH|H9Q4#;FFgw{e6U!jR(h zH_Eoc&)_h92OIbc8ym|%QG9M{<6vWNYGX_LOr4Kb%goxy#@YUtw33proVC4!zO^At zPEwQ(sSh$UGZKC#Eh)t%B_#cni-((=TZ&JRS5oMS6fYMKFaMKA+>(-i>Pp%eI$FW3 z9sblc`b+l-*ZEku==KiuRYo!e;-wEt3D!-fvx_|JfEHssE|V ziEIq#O<4aC=0B^DxpTw*m9)shUuh4sM&>#knbg-?fb8G!@`AVk!KZRc=rf;Es?&w@k-;O(m(Cm4+W^k5qz8L$oxc6y)R-q%<@POsq@{G~C>LeB9hm{!J+O zxVQxO35W>^iHY#<;}ek+k&qCPGn123k&`p?(9p!{v z0^r|9Swm$z%ad85+CKp7#iv=q~SmAgo28XhO~tKL{;C8j)(AdYRRqe zxuY1G~)p8@N;ZbH- zj0)J&qfnmQv`*-?pqS2D{#IRYATF^8f?@!Ec%`yH51(Z(!|81_ZF{k`D+e}FA!E7* zFdCAXzqi3^}_2RPvjY`9i;9+;& zWD714`~g7?o_B1=;@X}N@Z}W_2hw%Mkqfbbup2MXbLBbYIdY{o$UxZQ&uCFLmb!5^ z6)EfuS!Tl_Q~M9vbeh_4%|CmSf-~b;*4s$^qH~R9QfE-X0`c__zA$!)>t8Isy_J8Y zc?~2ykeL!nX;D42MCTS{NxJ{0|hz6 zOH;&KFk^GKtsY|wxfx3@xlab$m1wEW?K~AeluIr+vf=bfTZ9H@&QLOqC>M4Y-976V z6OZPp*SdTzrjB+zWiv5)7=9>bb9oI|UK}6(aKCExadKLaG!L}RQ!O1olIHe+co@&} zY=?DC&#`%&eVPc;Gs?&u=4}3gn?8FK?~K*&q_IImNTxJ#Dlj~lrt}jMnlj})CA@1= zX*tBUo0Vu;t1uJqP949yFw@6tH_hw(7_paKp!HR4?)F)Dqy**rC;JR&i*SciO7B-( zn8ZlfBQ`u~%w+#SfqZX|t?Dku2Z7PhyYvPYm6}3@qCtZ`mgeL3jKb*-R0q<}lkrZJvFL<;L7%~IuiF32J7)k^RnR@GOYr45vR}E@W{~+|AyOVmI>USL~4vRdo!Qg zDc2DkCzr0RdqBX4uNPEHv|iV4l`m=E-EM$8t5vtLagT_cG%(F_%~{vQEZw8j&Gfso zz-qBQOgy;&x&~C|EeVqnt~g@kzQGgVQOSi3arP#;E7;vUWD2NtR4&^UtkNQs2{!W{ zQ^0saIh#nuLrX}ozI=3Lr|Iy3iZ+M(k04#}EdQoxLyzLPgWEvFF(hh%uhmwu{cYo@ zU&(kCTTd!N=wdR=D&ZX%Xn>tf^A;_NgRdK&yC zfM1%Ln1Oe9g~dqAJ=IXfR~@R+X!E(ASvkIJu#A|kprtlDnC4xtV9ns#j^8;WX^j|q zCRuw++VG$wq&B@MH+!6=fiOJZo z9@UFA*riCUd0JhB5B(nGO2@;|u#su3V7-zJj_CiXV<%y|0tyM%dxogqXx6>NEvh=D zrYQ?O_3PjrZ}jjP%bj2?*8CVfqVO(WAz$_**A|(^-1Z9?xY+MSLahAo1&6Khi~y^3 zTrulNK9mjrU2Q}3%=yWOFhCR~7zklll|{uux^~+=L^*{%>>dU%KkGN42E9p!zdZ&V zvA)%?jxu9`)B?>eau!i|;8BSgQyC|fCzaNdUd~gEZ@rc^Up*|^FxQl>amY99H@L`I zPY#{%9;IR}64bt6spM`*(BBbG3iOTG3OrLi?QAccgS91AHgrZKAu#;Cv4W&1u)>xewN{oz5qySVw8kNqcKR~rN(ULSDi!KuHWRO?h^`VSD0EVlRWGCJOO zS&WQTtRR@t0@Mzk7_SoN-_ zK3H>qRcm3d;`^~q&>ponVaHv3A~iH2RF|(hPH_7~ewG-A*Ri@6l+3~0{G`kS*?C?l z37%-p*TWwK$KGXFnm=^-R@I%IDaN{v$qw(<(RfP~NG5upMM+s{PuWJhdx_b(W;&rD za};JcRBS^S>mxAM2;uw#^YipO+($4b*4{FBLT5Ph4>OJ(h2Hu|Ttasq@*e2OWF(sN{ z3`H(yq|h{3XS>waG)?AYv#pmqPCI~0LE?AefuWiy6GQ3n^LF;55f5Wyw7Q2$mCBPe zFE%5iQrsek6WixQ3q5(T0{e?~&~`4yYnQhif6V%c#j?I`oN$`iiT3uzke%_03f zXG+|+vtLSD&$+ObSY8EJ(4ZeGo%fxWBvy@i$l;jwH>M&vj&JP)bW4nYAI1 z1?14ZMWZiLITyqX+mOu1Yar;99!l#?R@L4-iT;sVge}Sb2Zs&~Ne=6S@9HOBcdnlr?p$#8d1=bTwj5lP z9AA;FH0IOtSc|(Xc~0~d^t2^)?@%^QY9GcSALuw23L=bJ>Oa$_(y={;nR_!lNW!i1 z>PJ?``7mLkd|3zUv1$nVW&eXBY&%8V{O)}s1$g(Qa{zs8Roj|0fyHdD#rRBYm+5|t zCLe_cg%uy)U13JWflKnYUXh^v1rwo3A>~dXWeAM9wQ9{|X!}?_ZgKOmKI3EVq~~Qa z1s@M=%_U4{S2Is#Fpkl;eOXk?R9u;<+0_?Pp)vgVfeCV*IfZ(Pt_@V}<2&lX$?`2x zE`=<5bZaKTi?fZZ7u{kx)TCmOP7|pK%XPLacI}!{a(pz73eD^Dv2G$B?dIPmIezZ5 z*^d4wvGctK_$3T~BlpKZ*smipwg)S~DyLO|=|IlT>I{3sIz&vQv`kM+azSrAmD4NF ztkWez?@mABQd%AkO3xhx`71fpaQbs@Hdu_A6>lqC0|EILbwGcWo+tEJgES+CV>c^c zRMD`&Rm!>H2)5eVa%rQi`Sfa?^MK21GU8-5O+=I#tlYq)^)vSJ8NniEy0y~yW4?h} zsFKl0T8%V&bIR>jTiKwgbMxuq&aZXZ`Lg-+t#S^neC<9u=_G+BzH4figb@j$CTcp& zd%WHpjr8e+hQ`geKn^#^Y(^ST30cJ{}RH==8v{93Bb zKGIca{t{78tdWjEiCSAWi>G#M%Us?lqm-3T2LH=k2ss;C9SZ^*2dvrzKK5fWxZhUU zZTQUigJvvUE0~c;<1v}0uqZUUsW#uqJv&QGeI%}NyOgAv(}u}JgCOtmSm=^b9frfC zuoaYFbIPbLp8pgcOLdHWtaPbO{mw{y$TmHN=o%mjiFUQ9R6Qeh@5whPEL?OUkt)aGk-P>j}D#|f1ut+oL+jGTmw1% z^*f=Mb}__D?~5mjf)KF5cBtqU-yDaSdeh#F#<-_xK06&$b8=o@C6?OnEA_~Eg9yhr zm&YM&ofF%>5cSZ{$;tbH?xfT>$K_j53(w#aa1n@t$@g`47$n|C$@K_s@*XicLOd?X z)-_Q|Rb9i8t#FbT<+28vnHlW-qqm^FLY`5u34pg>CiSLbksxZFI+4cTQCnLZKG-N$ z{>-=Y9cQhh(oX;^H;$#jq1muG62U&N?0tJUf}GMjOaf3em}J6(FPpwaP{uWvklEeo zU;tz@n7=0?cgyQ8iYywG(*sR>ym+0|D z&JFX_xm)a$SIppiY#0X{j@TngiD3KLJ8by`DXS^BolHA^Xt7W*qUK5_YTs3jP-RWThWjhdL&3Z=K~|;*w_+r7 zD(}m72n)G4zyCk;OthSK&8PFGS@kX@I68JXdHEIlkD5^N9zDHPa&NTm!$=@KTJ@Jo zzQ}-_ieVNi2c9LgqBqdI6wa_acSMdeCln&EM=Fy!$L+>fg(DSxvpse{|^P{%hc3Xh^5(cxhsC7Xp=$h5@xH| zWhl9M)Dj5Wd=Rm3!YN?#<+7Wmy~4{)>>2={hEuj21Qoph5SO5+wS4MUQc$cyj6-Gd z@{p+lx}i>0Zq`bDw3HHA-K#*KEo;$FTKH&muxCG8o2=66i0UjlE*M13A3si`0BxvfIsJrL zQ@`o*p?Y_!aw^&ryY#v0sPaNYMWr8KEvPCKJ_(Rg@6f{EYSQ3>Y z{gX{=OZyO|+JwA1ys-D(2L16CBHWun3K8Tedkj7?|2fS>nYJ5F$baWgFDBxWVBs&^ zloSJoxR5kq;`yiHgWem}N0OTAd{i_5lM=o+u1G{C4RKE7fd3q1T;&~ICM4>|8H^;) zq9oR>ej!s#hD$1oY&$xpyJ%dfyS`pNlMwudJqkx(@bgNXK{SlF_|vrD{cn`F6+xLZ z9?@~2d|j4<6*Rsu_6nVf=_Pq#9&D|_iJ)3j4X$CrFu?BnAJ`+07+;Ww8^Xi*EC;_m+Z6P8}K#INwZ^rpf+Oj>|6I#O&cXX zL~=51yuyOAN-s`>b$3K2GP+vZuwM*Afg>qY^8_!@qKJMz?c8`;P%<&IP14lii9uH4 zt;~)yvE~(9t+nt2=sS;T{cM@Zvue{k*_vJUhzA6<`pKq!27F3nn^MCu7R?X)BNi>= zViuH0E1SH(!15sfu>^?)>0lE1GX8XcsVh7tdOO|9;eGcbXnU;Zno)wPyC?=E$R8}wlKwQ`GH!LaSjvD` zREOHCcO(DtyE#iY?bs)&IBUn?aXph_>GjMeccq`D#D%X84`_H>;g1ZLzU6`#Hp-@z z4rFw8Ih|}-6P0&M_1#_1r*pRL9?m0Jf?DQZnxKh>2`DqU(Q28RA_Eo11=S5YEbv34 z8eR{u!j9kmf)&vprulbtfU#e(LB-@E0K#d#$<2HDB(gH|hemIQmCuRV#cAJ;xA2GB zJsKtC+ng-Qe?YLB{(-JV)odxRqD6$G>C~|z_bt;&nX)rQNi`+&vAh~NN-l%+ z69!BjTQ5kxNxu_~sL$EbhM3={zPf@(rsrNSh%7zP#^7L0 zGLUf|x0M>{y^3dHz`xdjaZ-C0KkTE|-|@U}SeYh78hmo&Zxm?YjXWPUAoB?7Hss9U*^K7rrRwv~YconX4u0{DDq>MgLQHbF z2KaMI;PY!r5Z&{70%M)JM0$Oe{##qDena+`%7Qxm(yA|m+7VS_=02c&;tsPw5vs3d z_J_%v+Kbi|Yla>d%A4n^{elhD2nJs{g;&V5K_%mgRUEvxh?~|_)tc#?o{t}BR;K58 zlM-FGjN4fd6H6TmeK@hr}Z0u3^vqR!D?NE?nf|{q9iO_vt+CFX$xR zzmo7DD~?o}^$Tw%!aJRW%SWooEu`?I<9m)RhOvp#PVRqcz_8%&H(+=@rdhIIGh6Ig z>Z_M>cD%tNU3>73;&K2_0X!MNQIkTa~gu8WA)sUw(>3yUz06R5`=^mNUnLEf&67 z%X){ePP;bYML~D+`#T-G>n}RqR%+(6W{s}3xOI02F>}5H>1K?B5+a6285;Rgp4>L; zsN{z6F1nM`xAdK-aIRtwjr&V&C|Cs5bJ(4#JZ9HN2+b?#T}?HZ5fq2Z&3i_1&g*_2 zT@RgJUg(pf@6VHo9TeWQEd}w03N~O<fc2pc*#Z=B4uwQgAfkj`GG4#z4l7flFXZ z_Ft+)->q^cryE3-pg4GEd><`}{U(q|<=Qs0cIF#Oxh%{UJ)b?!~90 zH+npG;{Oa7#UFutrjOSti?#?=p^Jg4Fu)Oyb&*Lv0(+fT#y9C${-yR79>_nr*Fi@P zJv!@j>Q|aKK0e$TG2t7{;MUuY`Xs^d9zOFK--sikG3ZFP6wWhAuf*0~ z+O^cWe)~!N-52NrV-(22kCWXJ^?oEbWltSZT%sgQN2#8K*eoAcm-iI={z4mNEcL$R zE0cyD`HJ=3lHMAvI|Dk5Uy0i=?Ot2HGD+YY386>r__EFYSoHzFHW56{DV&vxvg@T$ z-(=3W;#nwv=C)2v@v|M7z7x&)snvQj#>uf!!~uk1nr30?l!HF3Ee#rio9rhv-H(Dx}eW2Q;BKy+jEGO4}6we^9T|2&WCl>j&eWQ zSQDF#6jdbO04RO0F%lKczWJ5sRZGWEUlhHXp0P1Q~>h>p(tfobYA{6VVvZm;-aci_l72Tx;K)iOQ$TK zIrpo(G?|rwgkAO)@L|mT@)O}aw+RR)N{H$a$e|WGtT3J7_MI7q$7OjG?f}i9^4IagCKP!FV%e_r6%Q?pNU|Vk!tEt z|4QTfvXRE-_N!)Tj%obXYalikEB*m*UtY5!lT~4|(&{u;th6zUVl5%8Vna4dE#K^MWc>F>*}oGtWn=!75RMI%ElH-Ri=u&TG7(@gd&?^T>_Bot!xlU$92WS4_R%ZD+3WH8r>U#v4yq51UOOh|1azHiA9>^tAZA)To&_8>_yxm5e9X=96!J==y5oQy7HiKnJ# zSzSskIm1{}Gh@-DR7O26xifk~hgHL=PqK$Mrl4|z58-q_YC>m?)EB^E`W?SN$BVZi zLP>Z)1Qx0x2U!{cPg0W(<%cefME*9Z@bDPkhe2Id8i#cdW2Y>by0AKXd{JQeiBAjf zVMtk0$d%M~v%g|y&r(m6D%se!I(yVNMxNX;Z5`IicKbNV&CxePQIkRs-!~`F@%xc51CID$Hn=~AAb&z~_zdtJF4 ze=rdanlM5Gqd~QfcojK@_6bc(NdzMT*(-Ps4b3@%{gUnuf`T)Ufheqa`K`9ce6Yd{ zv}9kHT^P1$>}=LuzGEL==$@s)jt?nhOY+B0cvw_r9~U#}hEEJFMt{DP3+Xyjza2Ro zhC=l5#=l?m*M}4U5B&|F1kO)?&t?Ch$4yyR@92K(hRvzWPXPNK?M-teC_D1D2}VEXc2qI@ z8e9sKG4eL=txY!UQh!E1l}4`t?Mj<@i@1%KTh~Cr!ih60k-P~{93(>(ZLmP%Ej1dy@67LTQ6pb3Le7{!E(*A1; zGY)V+$STgN=Zw#*;!=tj3@g?aqYC`Ah&Egg9&Q)`(1ymH{jH9K3rAj7in}^}y?Wtk zzcDAMeR~`dHOE+BRGk&thx^Q8hR12mp?JWsYUjl)r=p%A=Wtz>|7z=!OSo52B6vh} z*7ROAIEKmHvAsmdgKZY8SU+c&kZ=ILx20V$-_Q5qAPjK)!k<=~ai9=rB-h3bk5mnq zU!3u$UlH))YC|mO+l3BP?0Llp99afPdw4u>4o#c1!5^r%vM~jxr066Tmg+G7l&L7{ z#h+WUCebS}JQF^T71%I#?Q%lyM1V&wk7Fj?U$zpNaE<-0+?U0wmlgf~eQ3lZassS; z0PMS8t9bpcYA8*7U%;>G9AyETnhk`kKfM&`zKj`jEGS0Qx5+=EJsMhy#Fc?0D!!es48&R(A=HzYYbUPx{%C(_h-sB zb4blG6~N$){s!wWVI+h03i+Wy;3L89A#;?n2=I_Ma6?fcmWk{-y{qWa;K(~CoCuHZ z72e6{$AZtML+4;vDAO^@qXjed-Jcebvgp4wejobZzKyPiJtHK*=`L_5F@TmvZp!NG z8?7uh|Eub_tjz9nU7%>TS$vsTYnCVCjPpYHy!FO0U4iT5 z3h~!II87P!-#edaJ6gF{pnaKb(YX*DR=rmIJth0h{?R54+-CNZ-$Hnb;Vdy~GO?vt ze}&P{2EX=fy=+{SgJsMxT(H~N%+y?Tpm_O~tBBnm3ANW#&&b~k`oG#PhYTg~Ft|9X zLG2Sp)S%8slb}Rb;0t`FKLfZ!MAzn#SP_8ud6Mz8rBc9gGnf|Y0My89#0a7d5S zEUY;6_K_5dM@_iy7DR8!iHwm|8LEc(bfYct+r;k^^)+zTMm${6P6)GFUV0)j)d`Ag z*V|5=zI?2L4v1d*Z7ZE0;a$K*&}PRx7iJsvaog#?ppA?RRJ_T4n}A!sr7gmly1O>I z);xGA^nrKIPZ##-YpIq&u4h0e2Zg@`a+~NsNtQMY03N>$5jja4W@P*t*Qu19hbF-u zTpw|&ASwX>zpmdX@RcD2k%TG_>U!(B>9OVsfFgqohndrMj1}xDj?I5GvX`ehDYxHb zK?xqZJ)(j0Gg3w3cS8SC{_Eg@(R@sOd4Ahdh(_#&XZp?mCGa;Baf39;F*7zt#lNav^?0sATRB{0bC+l7ZZ4fyn`0tnsFE8ihC}4AwZsZTBcl=LcRC z_36hbtHr)ZusZt0QN`wD8(N36)O*$?hrG`p`#b->;h!At$1zXjH`E(|S9-_5nIBwS ztHX+TLLBZhGtHE!TCE4s{wezJvn(wNEx;&Oq*%$H{q-k|7MnJWUtTNBosWij@Z>-bf%Dc+yAtFfH2_W`hoMQW&~VtS^4P+N^f?`XCbu8bP$ zN2n*0w3uQEhmSU%Iq2?;hnieQ`AW~&(Zde68sdco?JJ_uCVmbtHW7r!N7s+TaaG2z zy4abhxJxXc;pUFLpfP3PEEsUtv(I@vMo(pxDw!arQAN4%(IGjvQ$bIjXFt&$yNb2l z?L>1Qi}=9U)=e}#(YySLV}p;^9AO$dBb|oh6c7^kwED$*zhr=de>(rMW2M87k%H3d z!%iWVH7bWQne=M_b{cx6;q}??@bw(pRBWV3>;1*u7=PsFFFBk(vlO&$x3;CA(od_J z>P+()E2O)D{XZ>{(Cl2sE{mUPT|7?bOOgnChOuM-OXan7QS6hC*WqYj8+srvs@;DbxT$pq7#FX~$ zr)8AH1e-U?;mn#+lZwusbM|=cLR^RKuiQZX?*)K`P5{6WMXyjSIYxaO)S9`uBLj!sy-hK>OL^uxkEu|S z?UO>a>$Pu`{`I6rmNBNoIS&(YXs!V%FKyD`NzPeP@fNMaFtXBtb6pwS9m}(x>FVmj z1d~yz?M1J6gYL`iYha>pgLkaTzUS*Wf6jt3mwNEFP7~pL!PV4DYTOrY{cEuDBkU@f z;hXFX&A zGYT#!t4L8S$!pZ>fkZ+R8WMK5qFtXyYccP%wG35kt@IpLZGzzfh2I=A7DCdkY8ynU z_}cxv$jD4*j^!;h*e`U_ziK!bIy^djnSn_<-d}9f^`$~+)LC&=A=>%Lg}bW-mHPJ% z#Bc$0Bq*4BE-)$dMRCyD2;bzLgN>kkL{7I%p6Q+&aFBUXK_zrqskfNcdsb(8&ZHsN zXMHaEygkaL35Q#kfjZ@0?V*iYRsP--iKo5Z6@&Wxwwstn_2D!dM-i02jbMc1OpAFB zMVeaUgR2Hi6_mgh5n)jQvh#fB-%}b0->#y@$$OZX3AIr&BojrrI8zYs-d#+unI8-X zpA`5Kkz~%2ji!x`1f6G*jPY)@sO>($NU~pC!pamBSnGd1GG4c0C7`@XmZNQiU|1sJ zbcVXAeBQI(uiidbQW3UG$g&L*Hb_m2u-X$B5Zky0ti_%BE;GF}UN2ee+Rogs|ky>1nr`FsE98h(BbRKV&f?0RDk#O!NRwj1b8L4p!Q!2{Df-+Md zBp^`sh)(-@%-R%q3x9gx5LIx>+&)UtT9LZ@xdM9JD)T@-_lZ-R{mFcNe6oj_+r-e1 zr3$w6yb(KFYxa6j6m(@%Zu)I#jg~{EB8>Dz_&g;8@=)P3Hdt?uveB<@x94J65ABd9 zeRFMcQR~j=izJeaSW(9mw0*xe%EwxOxb(ito`bjmGGAGLSY6r8ZuPddCw+I+wsP!r zu~W(Hl-fN+zEBhRio3XqJU0*8LsBMm%o|aD)@jXr&}-2+oX4DX?L$oQ2iP(D2sUXc z+oimCai}U+Wa6{bJNwvaUzuurP`$Kv%NJshR*L{{isD|jU(TW(#dy4M(UrS0YP*;e zOGg{tZyT>(wni>+2U;EG-G`)-Fr>VwCUM2J?rZAmiP7bYl6L$mHBLgM6FK@!FYaPE zp>$<5FjPtNsUtf@Sw0k!(GUo2ZP483H$L^0(k9YU%i@lLdO#2f$Un4s_wI|Y)t=*5 z46c6J%X-V$%}0H^^gaLR^MCew07$MmKD+&&LyBLLDB0E>??9gXO7XR8m4wNOy5WfW zdtdHy#+RO3hBgazDd?{8_X@c>LaTllKGP#4=FjJYh|7sp3~q9V0pp%fCo2~uqOI+v zYrPfC3J_rjuZygwz+tJt2d~1}>V8~88v3cy1ma{yHD7%}1!YLU41cTrMz(Oz%f@Y+ zEKR{P;dO+1 zIFV6Z#o+X+)~}!!Ux*=OUBB!*%OPz(Vc12zjMKm8>!M;mWN^ipf2Ci~5t#`u7)h zHnOQy_ZVK2+YWyB&|O>hs1xtDMeeK#fjm$fZgp@R&T2T;`gkgV+3#x73m;E^2#KE_ zvyW9<8!W03v$E(FTNp=fqX|!Uo}>?G7%WyZ4|U6L46V!knSru>n$R;ivvMcTCmSbr zn6z_)we#nCOroglo^8=PF>5i&!_}-YWgYtg0yTvDTL3p}-}%E&fxMDbKMKM$c+`b# z&d&%rvviY$rQUWLi|MuAPBlj@vRoEWu3NvE?J)IAw8?$VUH{M4M2qvRd2?!oCxMxV zta3*JGvFnT=mu}?Cx2q?UPvc1FtDG6fBZUC& Oe