From 74a2e26f183df7976cd34a4721c821f82f415bea Mon Sep 17 00:00:00 2001 From: William Petit Date: Mon, 12 Mar 2018 21:20:13 +0100 Subject: [PATCH] Logomotion: React + Redux --- ...le-f8-diagram-with-client-action-1300w.png | Bin 0 -> 26132 bytes .../presentation/img/redux_flow.epgz | Bin 0 -> 20654 bytes .../presentation/img/redux_flow.png | Bin 0 -> 47311 bytes .../framework_web/presentation/slides.md | 1137 +++++++++++++++++ 4 files changed, 1137 insertions(+) create mode 100644 developpement/framework_web/presentation/img/flux-simple-f8-diagram-with-client-action-1300w.png create mode 100644 developpement/framework_web/presentation/img/redux_flow.epgz create mode 100644 developpement/framework_web/presentation/img/redux_flow.png create mode 100644 developpement/framework_web/presentation/slides.md diff --git a/developpement/framework_web/presentation/img/flux-simple-f8-diagram-with-client-action-1300w.png b/developpement/framework_web/presentation/img/flux-simple-f8-diagram-with-client-action-1300w.png new file mode 100644 index 0000000000000000000000000000000000000000..9286f70b05040406167af15587d08c282ad97c6c GIT binary patch literal 26132 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 literal 0 HcmV?d00001 diff --git a/developpement/framework_web/presentation/img/redux_flow.epgz b/developpement/framework_web/presentation/img/redux_flow.epgz new file mode 100644 index 0000000000000000000000000000000000000000..1820dbd95d7dde840ee63efbf1ddd9bea3029480 GIT binary patch literal 20654 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 Z_%Dvq{=pyo!5{oz;omS^fh+*#003GQCR+di literal 0 HcmV?d00001 diff --git a/developpement/framework_web/presentation/img/redux_flow.png b/developpement/framework_web/presentation/img/redux_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..0943c4a9308c57ee67859e38b2bc911f7a474272 GIT binary patch literal 47311 zcmd4&bx_ss7e9*9AV`aVbPGrc(k%*`?%JeuD-D}&B;80i(kF(~>#MzsV z-`~tRGw06Sf9_ldhI#vbVm+&$*IMszWkqRh%vYEQ2ng5!87Wl+1XKwG1f*gNG}!;V zXvuUyK)^irRM&P^HFl%^?C4-_Wot(5?D5%*+RWX`909?7Ha*G4k**p0@{VH2qPJ9X}wL8liH|g)% z;%blE3VkVJO1kSCL1rIzs%fLfKkTSOPJUgT)Fa$GKh&=sm8~MD5KVhNykY2@MsN4L z5P5#@aR(wSJk z``w}&Fa6$vT=^A!zz&vulY#5dKMgck+o^H(Ke+WUs1(sT>K9meBfR#GGDW09&!bj2 zLvJxK3Ie3`IBPjlb0Weg?30cp#OWQbs9lHH?Sa+^^J<;1!C$xrwjO;&ANPol^ha~Z zgU|?0I-BTw2!5M;zTohRVqU+uDrlh|Y|p~FXlw-`G$wMpNKWD!6Gq*#@T|zAXgUB`kYkoY*UW2 zGFf{^(B+j=0|YpBr!wLT`rDjRQ9D^-{-@7yyK3vqzrE}3=DLX=^<+cRkU3X57&-kJ zCHn%Vj^&8nxk`8^!ter3>0Whyl2oL>VonvykMH?I1rsUn-OcOXx{+EO&AXMHIy1MK z5zi3*GS3pMigpz~5Ij#)2XQ1$&7^A$B>%|u?wOqpnsXDXJ~hD|w6>!NV>0pNSlqL{ zaW5)KEZt&fcMq`?;+w%Q?39_XRrx}d!AIos!ZBa7nVd>Qqgm^gc~9QKf>45WLB4OCv;If?WNX2!2EM@6qNfEz8F7LqK z-?RCsR_iM7j_$wnXqIVMEEH_^B$ry$cp}CB_8hHa+)c8;fA1dM8YR0GT}}i@%J8ba zn>RSqDaag97%U!7AKN29Zy5YWG%S^QknfoL=XhaY-;B?bqxBP4Mwy0;jmdr-)5knD zlJFy*EAyA2NgpkD>GsBRm-T=ob;!$#R7(AeUw=q!g>WONiqeBmo&SiC(geHpvp^}6 zXNkv&<(3Dh%>4YmQF21a5k}r6PEAo3TUE=FWhMT`$PDZlAL9`ptN#t=UOw{}&^~MW z={l?OZFJ1?90?50)HSb4ZoM4KKf?SIN4cnm7wn1`O6XzJe966=W3hLsxv$qsSt&fH zbHL4Er*D)c)H=_HjqZG3NNYGleG~h&OIEKKA%3;=_wMN;M4 z*>u?7MW3%0s{#0PqS{EOX|U^*B3__Q2siLY;^ctk-i!%{;`n^2%9TE{r4y})2oRK_ zTsHe=z})cd5cy2i&Y&%=Qh#BG`L|GGz&p)Mt@rb$hk$ylWfayf3wJ_~tWsfUGHaqE zw(9T)vWY{kDbU`9#UU5FwRQ}fmXUZQY28r+Y6s;+iGLAqKAZW)97k13+W5Cut{H+jT^XV$~1SacM19teO`>z9t{f-%~umlp~o)A z(9T2cF2_U^_bPEd<4PFS7R>Ph8@}+|MeB%?SZs3n(K*6+E`EN9^5qDuttPfN{F_H^ z`_!rDqdo8HT1fN@-JNZ=5Dok+#0+ib1CF}ZAAs!i*JDwpI9e!S8rtp|1dO4I`L zxkitQ_;5?ESBR1Qimtpm5GY!*V#w5Df7JzkT6HuL2HEq3dIW&^vqN4}n{)O=Qr3u! zK!*CsN5=JE`Z(ID9?wU+BHQ#dX2jZ?-Ud*i4T)@i-+A`~Z|oNpSOVzv9&fl;B!I&? zZhMcfY^L`Y(?=P$ukDQ!(O8CtpUEh+@mur^okXH6(>YxIe;Q*>SuhpI>Hp1L;Rsdg zg5u^8;yB01YZ{9%KC2vgjaK)n%nBJ#!+hCTv|>uSG%&VtmB6^bd0N3j}2b zrDo?TNM&gA+?WEKEFTeP0~IG-=ncDGi}AwmF*wPm*e?UeA$|3E<(t(p;$Lz8 zwDKdV>n(-EJMj}X{3J&0RiFGl3F8su9?E_)3)(cwhu-4e(=btu#DwnG)*q(sDQLP| z_Gw8EZClUvXUqb--^kGI_&*C&!$b2BinSwj2)5|39O$}GHcx6oYq$QEE|*i5v3k2toR@Gaj8k)D z^uzZ4N=>Z^E`u$-@_Qb%uXvHpyA_T8R9LJKk832;U)f08o2ER88AV9u_* zGBqk1_PAwaX8B8v_RFS#+ir9>vZ&ggH8mD+yVE&@{lHkY@gufnoI)VpvCyv2mhLe= z{S{&{0W$ra6hI*((83dqB^8nL&2zmGg6EDtfl`d3;?^d+a@pRmbw~el(zpDSWhD7j zVM6mFU4Qte=QpOTUebrxuR4VJG{43WHY-!lS-uv)S>S&r8Mi~LZ2OAnQOQ4-;x>TL zQBSP$u}}2EZsIbns3YM>z=9mb`yewfl9H z7Ye1*KCk05xoxRmJ#9g?g?fXeKO~e($KPQid*LzTzNo4lus!v|XAg3gk2U0Me1BW2 zxYej`+r^1NutG~tpwplu^c~Gw=ApJnU-tvb3}SiBvt(PO$_~QpaZt_6AZpuOyf@{p zwjy;(4TB7rcw0`MEGBV33NX2d_Aqy=`2vrZKTkD}P|9Ply|kSAi{ociiJo*~9U!YF z%rj}h(|MSzKg6+GjDMhAfzKEAmBu~TmN<(wS8H1(4C{B_9bqv@)FAUQ#1O#dXfRu!~ zd)oejTbiCr>*LAv3@mj<%2kn+Lz0PWuzGD2k(HH2@Fr{;OpSP+qqXeWs&!xV%kj4( zbB-4CA_{95j}SvZ4i7*_@|pL000whzT+n{T5>+O5auqiaypX=Xe&Hp2$>r3ab|zwB zUOjW=)3(GR1EvT3|NLjNGXuiK z;B`emloVcv_067=xOkCyQ-CUmIR*=y-d%j`@v)y5E@|>9io>YsKvsou5BffZA-4H> zca66dC9|&q#R?%=@RQ}*k8?6m=q<%Sz;E9Hs)`}(3HdzVIIBJA5_M@<04%+D>hNI` z8ye{lgA855`}(U-&N$*2dn@1-|QS?UBNn0fQ35wQ8foA z5(#!B%B|f-I4=^GzlGoLj{MW+JS)M9Ms|U`lha%)RtPE=N|ac6vD-3RU*&N+KQhvZ{5Y!fiJR{_6Zl!Epfqde4iDp=2^!D z&b2NnaYcp?1++roOMgep^7daV@Uqez7)cfcP=tpluD{(=uWLF$LQAR3cqjqHPt8AE+JlS+-r~ zE&(HP8Of-~7GV7QMtf@CnBk+}MGPb`A>ps`QYd0*v_*`X*idDh=#&T(72=ygj;U#` zXGzl{OmXxY5%K@oZWX~;T!d!i;jL3H8=LT1p0DxBwCJx}RHswK*Wzd9Q(|6X3WoRm z5U-83T&vj&?ANXNJhgHy^pn*8gvE+&QSbvy&wThwv}zAhea7S94SVfFtdaz&Pyf)$~R6|C6KY(qL}qhV$!%w=`pN?Je#D zXHEXiFo0n5%O4`&jgic|!1wI!guAEhb?lE_kft_77#mrY+tvCw5x}_ykbf>lR+pcK zK)Gsyfw%P>iHumJ+RWn`q*U-&_`dE9?kgyxtElB*!bTKCWb`7+Pjh-|ca{Ornn6eh zS39t-9H~6mQ2y5Kp859hC+^zOoczFTEl&kd;oeW8EOm6gWy3?iJ-xXNADl}O@K3wq zQNH#dD}<^hg}W|zfP-%Ro0Y{rCu+`34Ywy^D~Yw3d34wqE@87FT%v8hs9|QK#1scl zKxZfn;5*hVc(}|&@Oa<+h)uzWR^=I`` zf6rFtY?XaQjBf@^zIz#j35wU>bDLct;q-vXeKmeR>iQY9N)Z?n8OLMjhE} z&09fvya{g#O81iq<-nd_|FPNHz~dG_g`J;5R~KPh=o3A zSzUm!!HQ#54rsXgm~7nA!%Y9p#N?M{H;3&T1ZS0#Pbr@*AiOa4FO>ds9tkhpo+IYP*Z~Q|JNjhW~jIny5r3h1ArD_g$uh zD*BB-1?_fYqdLmU%mXc)u;N~ED5VsS!a^0~pZ{{vUQ+@K!6HA0USg^LdB{OEEss8> zo!r#-QiqlEo)WOfq*Xk9QGo#CQ+O{LXH1J9M#+CsE(eu-8-8FBIg-DPWT=ZcJJy-! zR3STD_Aw4-(EkF&EXx{1-a(c?(Y|(tWH~IuLFrqlU-N){qvs`2-vp&y1bxx&KluR5 z^gg`Co6PD(2=uHIDP`z{pq=)X2;PMTOlY71uSX%f`$8 z|8IGVP8aD;uIR-)%D!e3+W}VJp5MuW^Ql0r=wHu$$YAjho4g|dJz)0dKY=z$b=5fA zdUp=eXJ^k})^N~+2=zClt1c$9$^3)6yQL#oLNariqlR4M?OTMcX8XBe_8at1Z{(t2 zq%jzKf;p>(C_<6YyT_fS>dHCjyQ*9U{NF6gzqFXkM0-jA&1jg%4<6V7{apXqrAx#Y zi~R9Dg5f-Q;v4%axT-a3F^+?_y2$S@z=0~Ds)m{OTX68H76+K}V9rKUe-goi<^y#DSbspmv;^4Q> z{DOWp`tc}O(VH=d!(2_Bq1su=yy@?PC$|ZA_y7A5LTc`k0}GbHQkMoLF-67jLz~>4 zT-)(wdO%N4u`{LA)w}ZRCHG z$_&4Y@JdwW9Gn#}D*!srXSC?G+^Tk-4jFF-%WROUxWr%y-|rJx;zj2-+98v*q?ut! zSBdA2rv2QOr5y+(K4lNA2DhcUQ~9Tfh;WO~T8VU4^`_uUIJjLT9;2g9{wuPjNaeRq z(;t#;)!)DQyuU-;9Xe~NWQ zXiw|IFC|eO>zZWIh|$|8n=e2Z4bA%rspf{?(#EQzoSea7JW$9=_H~#0glxcYa)#2HMc&PS@i|^3`(=>#Y5kgd4lL17;<7U>V}n z^cR!S{<6}h{ zmQnCC6%oVCF!$9o>=r2BsTH9aZ3<07ZL5x^o;4^upM5$t3*42xD=+8RVgyJGSr{%y zY1j=-&?#JEU9W00!ha%bZMPDxw578-6aEcs(O}ZkL)KE{g__?uo zS9BbdkBH40^~@}5)!i0{DJ*ryua9w;X^ixU=4hm|VK%zjm1+5EesZu)!MQBk=yxwkaJ?|yOPhvv9G~47xhcOR z8$(q@8>a7^A6q{Au&lXEoAonvE^o?}Nz`pJP1_OmSYy@cL}(Rsm&Z~kt%_YupboZH z?wZ+wg{rU3Au;>6XSN2_;QR`uwQyf=Pzgef^mjcqFue&G?7}o~^ail|yX`{|T|2su z-bS5ssQGf&%ybJ&y_wAg4GX3Nl45^?1+p)~1ClW6KB^b_HPbPNSu|H(gB_D; zulIXms`~l{{3I3g`&t+u9xrU2bQ{yJ=`KY(9yJ=-z}D~!ctKG6R*T{Z+Umj1%kB;3B4%paoO$hN@1fYfahX5F{A zExi0*Dhniv@2-flh)s@8E`>4^gCK-&tYsw@|HBWh$p+4WQ|f_ZozK4cf%DjfRWJda$5-h?_|qIl$8(F* z3QX2rg$4Kww9kN|>==$Ct6Ee-H+~vZh*4u-hwN zyF_!ya=Tk>$GJAYyaS#`^UCd--GzPtTdT;bBp&DbUZv$P{dv#7Ufj-o8X=bN6MIGh z%M9o7J5HqX)~^O^AL&(oU&h;duzbd?B-j2RpL@=%`?$!>3tFh1IrZompRr*~*l#92 zrpU3j*SLH~bxm2u`ch2Aab8w&@DfTmB4)F6Fr&3|gXoIdhBA--h7RdRaEC)!`QpYM zztEyIi|tbNavC(=b`STCY&7cLW7%x^%cuDstBzr_Xg(H@twSl~cZZN4SBJ0pUi82$ z7aQw|@qNmitx93kB2ASW(x+GQ9+cTRv#a}<#;hJeGnsIDA zV)LsvJ+Pt`bsF$T_p88vPyGE=9L3S}%xQK9#NVRYRTO;?<+9>)8)^5|w1m_}F}({j z(?@XbtMA<$Zou645&1H^Z{IJv%JPxd#=-7r>%?&rq^k@?AznP7mKYMXs);r!zbT|U zzGGCQXZTH#^qm!S;j$eu#4Ywlmre0f*Dfl*>N>?J+LDuEtvD+~NY)(jKJy9I*;8;OsP<8aH!%pgRjeyYRuI)Xvx`GNRlifqV z+~y{oXtvVnmjG5^k3`4PAIQW4if~-*9>vUbZ}^^p+Hq5&KcZBJt4FZY=DbFgaL{$T z+#yFX2z=CJV0i5AcOJJYUcEZ zRN{SLl~cMDN+cD-p|2Ky0)`$s-q9mr2ji;9y|OEXTD5C@lb_di`*(~ZX`})I|ATgd zD_^G7S#(n<4*la}*SxoA*!A=8sgZj?smka0Rg38qCX$yfj3?+{Z%`{pV<{ZiPJ9Mw zAN)>UaLISRrtS6-!cS_`a~yW*zUuA`gL1a&GfL_uCEFy>Z z|H0M~dTd>8*uu{YO}nz_^#cBCs({gBO*$njpTas}KF|>RWq(uXRCG0Rf_= ztXJJ7ov2eUUS=~W9C~X*Ydd7sN9l&JK4>v6S|QBBzPW?R$p1#6g2Z6;l3meLDbsK=!?Gs-=JN^(P5|BC%E zDBSN2AL!1BVa``FNC9tpmdH{6X9W!lE!GfC=N~G9$-3Y+dFO)=3{_%eU(_~Pb#xrl zxk#j!c)!js80H>iQ6fef?I)VQ;qtXhs?Wb{3io=qzV%1zyM2U;RPCvg)W+%806Uw$ zn7AfZl}X*#e8?NP{)XVkI|pi{C8n_0i&8sV6Z^XBOr%HPXUed?2+@Qxq3^5E^tpNu*}9s35I$* zao#LxQQFz`4o1G+Q#~d6>QH*zRPq|f!_l$&eu%zlCt+5`XTPhHdV6c;TNuV|4fV4@g^nrr0#EOY54Fsjg& zmRQx>`L&jD`A919L@k{CQ~*Tyi+Y`vcn*y9V>ZQhdnI72f`LV={}84DTn4FwR3 z-qQ6Crwda@`||JSMl-j4+L=z6_C#m2*uQhMBy>Ww^R8A`F!zK^=bs6jB{p%x%7BV@PyDhV~>vX zjqH%5+}vMH{+s^t8XSql@mbDOF@pytsPzEes$0pt_75>SssNu1FQ}N5dcCN;eAPsT zo^Pm`-M-r2bWcn4=$Q;L{DmS8TBM&5RTaeHIy1f!d-iL21~iNhH~MugtSaG9${f}U z>KxWbw4AXjI)Y_2DF&-N<)&)KwS?$gM@y|j)r(IS6f){IZHdutKRL)vYMmvs%hmt( z=FeY!R6KOj+TpH;9WMHhLPM=wDhQy;1iMSCvdR7rD~k%rvVEhYsG}3_3XAxs& zLX}4$ymhrNggN-gwVje(f_)94bO%~Fl3y@9DL#{qZrot6_wo$61ZU3puSv8CdCHMN zU(~giga|c*w;k^#XdBX`)W;P2+Uyw^Np*oM7kQe5E4!I~4tRt}6p|?Z?K$_cWXp3M zzNV1J=Xd^v%X$j)S8M(pE|nqzjaN6n_uUVYmmb&;`W4>rq!rR<0OWgW1Fj8+O1fK@ zO4eN(A(GOElXb6!m83=87Pz_%4nb|)8m-_7_WwZRxgT0py@(Wl>&pOcn2*mJ@>dOh zV?JhGnw%0vQPjQ#4WWnaLO|iWzr&^6)vZc@tCobZ|FToK)#7h6w|Kz&yXfsr+CU54 zeII!x5S)av>rVS!xPWkLKnKMuZrin;YILY&Oc_l8inL_`X-D#E9TW|<`v7#jvcczC zQB%66y?Iv8h=*t^UD{7cxOz6C?|aTB3@Jw)$aBnWKD3lRtk%)3WdqE0!ywNhv^*7+ z$`4g+6yQ2H2D;2VKw|VH1E4rVkNDWXnHj0$S+o+U<8$esK?P)J|^Qq_B9 z5ku8a>5y#_pBGC7{aNOB6dSOGg_*I%a&fESzJN$!i!7D5vEBSA^?+DiYab;s~preUpTgYjgxJ&3fihg^J7eW(LS&4Y|b!*wV$KT8( z>XP|Aq2kXiqtRZ6FKd26rutp(kM_5uz_X?du(UZR_qyVACuG&fTi&X43 zeuFn>_e6cUndmZEDw5EHtc-Q_K?K9EN0*}6-MGiJp*w7 zpPJ8hptoO)y1N~)H~oY2%_6Eh@iFvmMG?9v_FdF9-C3QhG(=x6FB?VF@VKS2HHPrl zoliH&8MjPdanRitxol}E`a$b6;!SvtBBR*%_t^{K#+1~D##*~_Et$%99tpX2=5Wqr z(dQLeHWuCa%vmpVU7eklP21n-dPCSg%uS2kL2?erG7i52Gf z+)O>`HBK3mst4<+3z?uOqSEkHxUvK7ai&=v6`0~|T1r`WS7Uj0|7NE9T`7wFp%hs; zjd|Nra$(Jz`+GZDu5kPg28KCDLe#d@)joUbfT}*CSuZZm^rWD|G+c|Am{_W0sBhRv zEiM=6*0i5^{yBY9^;Wbu>2H&iO%@mF#1?iwD;1H?l6`gF{!2(PW&_PC^OL^ZH`zq8 zG0m|U&uI>qL>cA?bLJiyIxcE5y0>4^(x)l*Zj^86*WfThXhO){S%8bpMnKFvPSAtZ zDUIoH-}lGTt;3x^Z?{+rg53=rw>|z)Ck}s&`+i^A-gvDUoQZIsabXVceNXsw!jReP7XM+qo<1a&Ns~H;Wmq=DxK2-g3Vl_QE^P?)G)rsm;SG zm>%R)O8i7ZFu-n*1U~$@hjq!J>~8mbs)4C3TgHH%3IZD2B2+1iTea2dS(VJ8VJ-La zP(KL1Ne`vWd}tu%<)hD~m&IzUKq>}+dLT+L~euOCQjW^WV-L_066x>CDj=4Ztuu)u>l)=7O#4 zDQ>Xt6C%Sm|H`Qw9E%MuVIBCG`uxx90ryv``0s~=@^BFsL{hy2OooE zE~F-bjbC``dk)u|UvMxY{jsB@kEy2`~A|CI`l>bXbX6`+xs|1z^$v!%=Xc`q z=<9)eZ&+IMH(y$WB<8-V&M35pzB)FP;@fllWwH_zsNoFJ4v?#^u=Y$I4sBw40l8iv z9jK}(`x&4aIOQxOJGU}@HlxKr_FBwijB&OdH&v)oDLXx!2GiVi^Y^b{WCGcAxWq`u6^3><5wPa%h7j%rLvVKlh&13a{!oG}KM3V4%e}sZ$;kf-| zO@e}+q%#&umG#JthOII&V2fDGAE~6uCZ2vWznvhi<~dzczhG%%9eQKRgmm%*sV1mtb*yCz++HpTyZiEWqKA@SE`58C(-@+u60yb z23GW%1fL#wJSKi0&SeD@vprI?98oec&gcN-qt6hy;x0`lZBlZ}c)ln7*=79n@ft^A zHXcjdX#mjqR|2H)s`m1?5Jif(>W5lh=@9xNsi#VU;U>c~y82S`56+9bQT7a*&O@*w z@RnY3WU-Ten0W^WYtgIR z4^h>CW9PfFb7dIu>hOk;18R7=ftQasG^CF)r^(U8Wp;vw%pV9GLW69+WPE3k!K3j5 zHW^UN9;ggRhr_)>u|1jeZux94T(D)Q#67z%bzp_)m^ua<*{S-^p76TrZVenkoliEr#hx@IILh~-5j3{WLD5g>Kud_=$N}pRh7^% z4Pe&*#z4>N+M%6TjVR*lN9CfPi=D55xfUzFp7eI{>zI!u)gl9ueLEfJAyzwon}YhD z$(QrkTT16KN5SfB_A81^BC59?D34S$b_L+@>U#k;t5Dt*#50^CU2~=V*_JFhNf_k^ z1D*XIuqEKNj`XB7#z-U?RYt^EPJZIpeCDX!QWP1&!@)}%YgkrQdi@=al2I#+%atL; zyFQ1}m#a7+IhZ_Y9}1ItO|33W%YR3svm9{#R|vL?Bi@v+pKHlI=!ZL_2?qJH8WAjU zR{KPCP!khM`e)60a!pn2B<~NkKx!)xpRpwD??Hn(q}&yY-YV6_0zuHYa|1Z{25^uh z0^PS4@zJlR)Q3qQR_zJZMr0`>fbkywII&0SCuw_(ywF9<0t@~t zztUgG!k_wK5_ozi2!HDO-xCY`>0c)U{lzQTQ(ega)+BWP|E9oN0^lXpr_-q_{A&Y&RT9Vl?E!OT|NlEQxBTSM z549skcIuH9=<5?xZwWo8TlJA&>RBU47si}N+HZ;K-L<~xe#efmsQ%kEEv|Oul%)=C z<={H3kSy@TyGtY-#7kBkvA4i>Y54pasxM-fvmqwrD0;Y&Xrj0+W2gtavd_Lmg(3tN z|Ba?Xj_|AYSb@wOK7$ReT8ISy*xBfdo}flPe$XUz^fTKt<}q zAu`!1KEk7$(CUN9vFGxLnux>*(i%V6o|e$?E?z)@#ggjc1wT9I7b6Ifg|6@4K4P{| zx}!AY_S<;~eQ|JQ*2zSgKKF9!_r$ptJQm3T-tlMU6+bPI%Tfu$m?si`lq~om!SGw% zFfQ%XlD{wiwjC+}+3A{o!zwN^@pH6rxog0yloW1njxCHxM}J>SEJuhh@ftXBeHQxs zG1;yFfe%3mnFATi9~9=bQ1hDkp`31Todm5B_G+AdzF?N=kRchJ?burKa3muA2fK$lVteNQcOZ6~`&# z{@LB{mh_A>J#(A zvu%vNYfaH!5jLbPcOgA7c!T2e-uWlTR`blsqQZQ=65*8{!@*L$!aCFb?G+3dgdO%t zn{%UYUgJw{NEZ7NAkLw}DiWL;!{4N`v|lM2NT6gD;AMXztmK+|+>`2X(f;+2TD3+l z9Vy`>^B_IbuJf##~!KEj)*jOde0!-kzY$pWdwKQu~ncy;9kePt+=tgbjRLkcAh3& z*_K~+r?s?0(ZsvD0Cp@fi|LG7e!3gp=^)8*bo}7jN=!gwa%ixhSOy7RLN^}>H63tS zUn*H)*b*Q~!u3KX!4*cGPqzb!;a5Fo$wQ<6M7v>dG47gmd)xPyHUCbpp)W)H;wHzo*^4dsoT9MY&EEmfVky{5TfAMuD96tVK2`3q)Y@j#3`Q))(cH zvFFPm^Zu>(GfttotIBF+^|?DH$XooyP}!QhsiR zbzUlU!sOcNWgy(+_m>=jV4@rk`3yzetG-^MdZ#W-cFd`E4ma zwpE>9nMI?k)Or$psSp*P&-@V<>qvm#5?$c(&XnS$Et(N&!P~zp+> z22D77ej@sQ{;3mkHXDAmfhy8<{=SehTMG%W!}5RM^DHu2fPE9yI<2O6z!y>|>Xou>-Ckq_BvcuCcKkAjrTRx(n#cp*wV4DN zAD+Ytq13UPX7V(p)O>yC%s8z2k%X7M^$T?_n)dK_i4=m~@M|MP6=RThUtK!^Q4Ycp zj2()!`|~n`+Yg_9)d{SZuqx%bm|0k~Bx0yJRriW%RoyeKv+{}=R&j}b#Pw|^5+OAI{PEtK8!J4L6kBMMf#Tw^0 z=ItI8hr5Bh1I`d->T8^AEN_2|XG&$2B5vuR#8NQZS{X0MIaBO~`#A%n`Y6ff z{uUf(v?h?G){GDm8Pu0Ad*p>Ty)=)>i!*|graAdgDE! z&yJaMSRW+P`CSin>ox@i>G*z*RqS`*@a(NbK3m#eW0+P(tBZFCk^q5 zf?31+$5*}|jV&h3uM2H7?YV`{gGMy-_Urp%mToL^nl3$PKQG7+l04?Ut=KEF=}Rvt zgQysD&P=|ada>A?&iT}CR)Y-hceyMZqC|&@CAN(JutbVKIhA~eb2+f%M#}BdCTwO< zuB+JJj+}eCr}Jyy5rO|~nbdYuEKbHQ5QIrt*3ws|iF zTCj%CUXPlI@Zpc|g(WY_wdQy3?fr?lx^}+gPxJcYL0X2a{3j-UhBTN^LIacdiiz=h zXWLZHuFr+0f@cS!vd+rJQC_K(w>JnwRrd<%7~KUiwx>Um&Bc}MmN`?t#>o}pp3#(E zZ@T9=T3v%*b;exb4cD`LLLe{h4c2Ykd?%W1<_css=EY8~{4;eF>4XzeKFJSqa z^^(iX8fC|pTpc!w&vV<|?h{dfe2_E#&F*i>BZkhwm;DfWpBKlYU>9#ctg0>8q7pt_ zH^*nW;OTR8b38FD$2H?a{VJt$ptsd^5*U|H47(-U6x!EKl7>epZdcMcvvw#oeWlu{ zGrs3fC|h@cb(e4#c@9Hh%N}%>8E9qhX?|Dt;!=kY`e8W3N)LQ-M>$KH!Jo5j{1|3D z*mEu*%i$e5GiP#w?t{Zgu_D7eAtvx%t1;IhF1TN+_BX_f4_cz{Z1pA3NI4q5Y$U&a zP61sTd!!2(jKP}>t;gf;!A0mnaDZGw73!Kje57C@+W!~Hj*~5 z0IvjcUVUcgdNvOAYm>@b%M4@b#qysfh+|@7l!SfjxAjT}rfgyz-cqqw>^aZ}{TZ$d zh9(eIV)~=t@-5DM+@-Kg4yC@E#!!>!wpynAHXFvwh}pZTE_Vl z=J&3H$&bu`ybAh72%msTX}-jzqvoxhC-RA?0FcsD7 z>$dfS04)i*9EzhajpRr~81-jzmFyIP_zFBiq1K3`u7d`eLuzWs6W^lP`>PRf%RXaG>h`0ih)dgC}OVoM}sOwJkw&BO|lc z%8k}&K?5MalFhj{g&MkMfV3f5W?%ZE4p^ih@2_vmPosr>U&HX>=` zP937l?=@Yi-XBIkIewVF6PgG_!qnpnc{MKoN9|Jq*Msg zS$9J>VC)>Pxs&t9_=Q7L{65uEL_$&DwRGc!Qr35bA7M7WINJJ~e=npMc9e5IIU$x= z)GldCIs_oB46ZqSJQ{P^(m z2+p8w*`=6us;SmlQ54P@Ev0(V}E&1lVG8T z)rzL4^iBMjkNC8_&*j;nBZo@1=Nqo%abNYnM>qQ=VC?Ui!ps&{my`IZe{c7E1faY2 zp#&y1_KYn0a8GCzx&{ONau?TyX$PUO9IWWlJF(FEp5~@68>UaN*YHmwb`>a5+CDnd zK!$89`b9rRl0iw1f3ws-H5?ZA7*fK%ff(Wo@AF=iN6BG1`ur*3X0ij_QiQh{zQh41 zIiWh(GiLtHDXvB>(d0Bz8k*N@;3BDep6Aev{eePcx?qgm^&lMXL+e;=99KHZd5Yeu zG4K$%xK?bDX6Hi_~~N3 zYX`qzs(u?o;OV7?-#=9y;9wM3HW!e`_HQB`{En(_dNPldUzfWx8DB>h1ozJWrn3Gw z$~v6JlH)T(O^*MZb=q-TtK4jSbJLnn8io*YVw5S!CAM{{DV60HSz(uG+7-Jx!6*_m zUF*Nl18r+HT#i&!uC9ETw2$`87M-*gcR2n{cC=M+C5qV5t|*ws(PpC;li|CNujOIe z$AX|cRwE5zgY|;5Wq^K7;IFmG>VxH(>qW36b%fn+cSII=UFL`Q_`Yn!V_id+3~h}j08PqvwzFKByIJf{*3TUoo>>cFMy3*&3g z57i|e8)7TMC`ZtinlFYRu;A!wl87)>>Q!kL;1Y}(LUx?3af z@wxX*0e+1UGtbPvv!4A4|2;3OI7)CTsa5lFW-WlURL>5@<`!4e)?CfDGzO0=rv6^< zt3M4D6CT)vwYVp7ro}1FW}3t-q$1=?sVw_NDQ5n`@lB)k-Kg zn_QD~--i0GG>VCKt4)iFFa1JxKZ_Al4c3%Rw_vao^0}**M!a4QLgsf_^+(Y2nf{^g zlcB|Hmw$4zq3@$-mk!PF=*vc@|G$WP%c!WnHw<)Wlr$*mpM;2nbcdjb2na~Gq#)f5 zQX(mx10oGFbT>$cbhj|{07DPV+%xF^-n;IHdq3U}XD!xn&OSTdc;5Hy_t}L(WZ#=d z22-N3?5DIt9hN*G)@1&e5!8a|^LCP9zBfCwb>%4oob06+O;9ki_?QNe)$-ZmEu$AD z+F9PQo*wO-g#}F?mr8nvbPoFxfCx&P!h!x3I)>*)mEW%-asumjOQt1`<#Vo9h2d2= z@3ZS&Ks^?&df|K=x}629ja8Rd`AMalqO}4%*6jq(bn3xK(Mev{R^#;3&CZK=pDm7UvSx$m}nIUP92+0T4oe2EzGGsc15T+xLP@AW`NJVgl%^!fym+@Y=F<;iB& zg500p`9+C3)3=;0h3!c?zsrZ|%0Z}CcD(4I7UvS}<)H^d^*xcR3)ZmBS`tnsMdQA6 z35_aPx7Vdt+BbKxuFh6h#NF0?)?Yad=X7qjs$E9I)f6@U2M^71ZnbG{o}rXeCJpZm|-ihg61xpL@b48%z0-^FP;{plfg^7}5x z_b8mT{(LD3RCl?#P9?-mUx3`V3%^`O`2=~v^gG6KskfF}!J|LiR=XaYLn|}IKO1+x z@nsp-?S@LY(RYTNuFqL75C5W&>@`agA3WZm23lWyn_h=V^nng)cjqPzLrWVCO#5Or zDY>&q@aUVUVP4CY!@^MetMl{LN+7FQH4WwsljA~Be^lrn^AjjXg_-E=!v~3++&^`T zKTB(liDaK1w>t!dL@#Fs=F<&f&?mn;tAms-wk@EL4@UGPlUznx-vWv>11}imyN2G` z^K3gXGlZ`#DnCcCw=x$(*1L2ibX_yMVN3n+TCu?|wX_`jyn`o;yqu*H_+dSEp$Lynvz;?$ka&eew)j=R{)Nv0pi8R5jF; z8$agP^BGxR$Q+XW{J*^b$Ss0FR6iaiPnlsTOxvQAdgU@{8f_}}#{5{3yCI0WV;BLb z0HW|U$_voJbhkzE9JW1icTf*a9c#EoDHLg8uy&B2$PEX2vA+;EV_l2!5`q}`OyNF4 zVrP7lH*~UG2%g?6r}jZi99_h!>ml0I^aK$f&6RxE=|y*pKn6Cp#!F5ETA7j76}Ice zgI=~&pyIo@2FQ-cbEnlzC`Q@HN&t=13b9CAPvNZr$!`18EgT)G)&P{U$%pG|YTvVfEzE|ngC4#Pn0Btww$*euxM+eXy7#6oB zq{#Gi4qbjAzhi~_y}2ib@kXoFm)C8%IjC|(qG`xy`Fiu-%K@&|rf(kbM4Ob?ANyiY zOSB)1q@}@|nOhEn5%q^1dlqXFSi+mh;@Y*gyp*k+x*40tE?Ml@Y zni*s`=O3`8?LpFnUNEUx7%Unl?>O9dhbbmb>ey3)&LiD>8VbLp>puUJF{0IJG2-0@ zTv8|nIs3WHQl`hno{Mpdx^Bl46sR|T&Z6QEtWxL_ zJRry`pa%*A3ir?riJfxkQ30 z(6Vs7jW&-9x!v-i)@1o{h6-*uGVnf_?#BAfwB6&!qH)A>&X0?2h;@^GT6A7-JoEj; z5(tqDj60~ynetNKCzQ4>_vqn7UKvygwW+hxt5u_l;-Xh?a;+~qsR`JcjNBs)Qb5eq zHAmHWdF3WJ4kU_DWtevdo180D*HA3V4YmHlK<7}{V)61B zh}{l_tL=5sqx-RMZs>Y|-oPAs;8;rOLg;4b%46e{?fJ$n34SBD^anXjZokpVOF4Q@ z8nr`r1E>du+aBk-A@ZE8RMdx55}}GAT#oVvXVyk=E#8PRQ`bJ<*pIG9Ml{?ces4J^ zib=S)2rU{Cb^j=Rr?u(Oy@h8FzkfX>TUqy=Dw+S1@93Qc`%O}w4}#Ajrs7Ew+>ssw zg7&}Ssl?82;6=2{tKii*{)w{Q`JdbAhEyi;7CmxvX4ln9m9um@})hEMlPKmnz zKu60JiN!^$&GzlOkH%S-*IU6ELwDq8`gc(hEUOaqK7RLFy?u$LL2iEgrY%l84(i_z z`W5Hv56`)d&(A|1Q@xg>$RBk_-IjH} z=Le&_4s%tpMWBNPM5KIOEXJDx0Pho!0aJP-;NB>^z9`_!<3#;H%J@8bQa zp@vH;@|%6}3elR)l2*U)B@1=be>E3j!c9B}jO60S68fR1##_X@-Vqj!aBojVnzw5!~BE6#7 zlAYmZBz7l_dXs?SqvtF@Bmx*w^;MQT>Br6)V1xg?RVZLbmY zB@0b~`Cq@*7i1YmTEjd&=+fK{%q=rZuQ!Xs#LrrMJ5=7HEQL{sZn*{C_0A%0d&7mJ zF}zRg96wNuwDqW6!`Jvqx@H!~jRQ)XnFJCReRCYwX9*tHBhyN_3=CHo*-iiD*iD~Z zd%s;H;e!(IbbjnP`7qaUe@UmRXqa)UWx>rXdZd;dvL-o9+aEnltMg+a4eXoA9aJs@ zzgV5UywihAI~6Pk5e{q@L}fssTqaW%)@(vzS0r`ri{uS%5x$}>yEE&>nD6}0epX&) zLL%47Q^IGPoCJ9#4BBxneRiEQYsEyV{q4Z+e9N@r+^bsAN;a44Wcdy!iqU2E8{I*z zk5kI&?zfbjLR&N@7R9gN*l2T?RPHE!G61 zHyf7~Jz35y2k24mkL2iY@Chhv{}kqbt>4O?;eF0~_VyVEE51>GeCkM7n(bF{RL|y7 zCq0We3eRPARBpuRaHSP~4IfD6x8}gX36t~(Dl1QB$~}2u$O{LM2(8PL#gNlNks9l9 z;!WgLCMcrra^Ma?sIfHjJ^gS1a(Ly2>HxqXYoMP!ONy{|5Et#U@rS}b$I&d2) zHem~rP-E~Sd5v|GZ>xFm%434cW~DW1vv(jGGM70ik`{Mx@pJ&3)|02KQF(}*rgWLk z1vUANkCTS{iKKmlBpFe90vX8a6j~p(zCf&`X#R+RCheT56c% z8dAApw<4i>2FWOoex8=3himF0H5Q!XbERavH3=2o<25=X;kC|- zez7CXgw_Ri_V(3QSf*_IhJ&utZqM7(7t2EOofvm?3wn^CEF(Q+LZ$q zz(iZXgV}xlNWfwIcs8!oZl|V7R==TYbHBF7ae$+;9tytvwA7TQX{g^`3@HUMu(KOY z6wpP`&L^>#3WY2zG$;pDI&YIpTrixyy-v~rhsn8SXJt|IT9j@CQ%FGWO0O#>zk{dL zSxvewdGnrKqii`wPyzZy{k}Vexj@pBi9d!}%_446Aio=C}GtI%gP z{gn#|6D;1*xf;V`}d^&NQ2`7B6eZI)W$HTQVAyCL16n%CND;jjI0Pw?e)X-!oM8Up3B@UFn-` zutl@ZFCz{XYSjCK^UVEfN_P-7!rI=CiXUq)bJ8Z)J99WGOy!ETIJr^Lm(KJ8GBm5B z^Ge$T$Bc|j9kuH5s)k9fZ&-E>d*c($?$ym$b~3 zUtS8+ht>CPgyA!tTM3PReuhkiY&g>P`uW#k!D(MvY!(o+R+js7W=^|5dz{7A7W4Ju6&6^)>=U0oN5Uxg>gVlo>X;+s3amWsAvY2jZS2z@Gk8S9^LhVfDt<{07 zuKY2qv+wCmB2KVbT5>lL6a zDA}2Mo;ZfGek`;%Xj1$_YoA``_d{R$T^x}TWz7m+-X{i)%&YF1!~5Hd^|YCGGu>Da zj+G=s;qN;$S2nrtl`OO~ae{ZOZ)(PhVCNG*subo6h>Y>6-Qvf@MIBcCIf*8^Z<=AH z`)Y=juDUMD6Kb}8R*;R7+1ME;m(kRrYxf;dF@86;#{M00=Yzh6y7T550W5VH7?5FK zbFoRf8re&H{uu37&YK(jp_?4*^&X>Q>{yV5;LWB0layOqKF8f*!HaK#rYc=-=wkKFN>VKY9@@iM~*Ss>Dw)yre!@5}Rn}kdM zzL%umP+~kn*G#-eG=fRMuw*7MPGcQ{@z{ulC9r)AHAamPke0~)?YA@LtCgtm! z`zdZWu=F0Wwfnoz-G?lJ59+WIL#L0+O8D9g_H`mCnKUbZtuE8>! zLZ#=uEU8`ZA(t_)ZEz2#Q2Jf%dGmj7Z}NIj^<4w~gDcdR>7tVkuUm_VM^G*Na&bV?-^Zx~!kMjZ z`{4c31hC=M%7T?2d&JxP*>@yFGD*VqV6A*o*UBA z4LM8}DxNk`QM>KE(G^|aovjM>T$?BLQxusWk2%kn&ug&gqfJVe4V`jn4K)-K46W96 z8)L8K;6=gNPqyCIF7NHhZ}@~Tep;$;oH}=2KP#wJIFM+8-Vks1Di3q5utF)yT%fjS zYYWR8f#%{cFPy!&*NLE0J#|xxB{n597BUNl2hbgQo?7)N`|?EC`8tUVB-;GQF{N(y zs$E{^&k*?~{y-2`I;T|QV6vBztb1?pDa6GpxbthaRFgAb;$lc7DN|i|jE8Wx`Dgsz!^dwG1V2H_A*KB_ z(}Qe9p6MZsjRN}x_pbBCp4K)b?Z~_7y-*6h(cR4zpheKWXjdN22S!urwX5{TK&SV5 zSuy`lF3!WnGt5vzm_jRrSXp6lD2357otv;8RUHh9kleQPb-QHq5<`7n79Ww^^zHV6 zaK6Tu_Hwlv_^LRsUG@RXBy@AK&UXDw_3N|^W33|lm8(tbG?={5*=9KvE#{|*w9mBa zzdf%`KOgNcSRY!|pBooo_3>NSZU9KW6*0(57kYb}WOf(w1j&D5uT*@K%OjN1v{^EM z7-Yo=EpLA&qZTSR+^K&fp+h#LFOb!P9GM>lLNwsL&s{C)D3%caDG#!3wog;k)R9)1 zY8Z=%YAVd(iHDL&#NXp?saY=vRZXqGfmmeTL?jtJ{qBSKWZUA=WiX=5|I9}@N?hO| zrOpV86|6PDd-MZ{vZNL>!?5tW#ZeTtrhj@HBvHWUAy4NaSm(;_h|z%`D(>9(jLD}} zEJ#U?Spp^66Jlj|Wy(*sL1sEJw*FijAu&0E9QG|=Rn#Nsr<+gWjRLSNm)f(c{n5f5BuIc$ukZU~IIyt?H+Hdw z-@_y{R?zhcmw`LiFXchw)j$aK=Yzn88=Fsz2G@s9gXF4=JIRHRJTJk%hnC)c7l>XCJLf1^3Qh)jM=e5Z7j?!fErtx~SR~o;2zztgU_fNt2Y3f- z*TZ2^z*A7U__3VrPJct*n2ez0&JM3p7Cg3w4eQArSxM-#*OymseZ@_%j23D_;HdN>aE^<|KTic zv6n@jPQ*vRb!%%@m2@MOp_gIbZ*ZUau~l>CsFl>WeCJD_`8KqA4+nuB7dM~veow^Cn$;Duz5@B znj6M!EjV4+Jl(zH;dNw1_vT*ujqR29<}+P6^H*)>O4M5UJm)I;k7S-J!GbRUg%$<1ZO%#rw7iPF1TNp^4cG?p33 z(>e8P`BBK)mQU>l2&L5l-uSn+70=KDh+O=Rlkfz#|bKUG}23FLa}&g|?Q_m`Lc zG_R$y4<;ONTI}q70Nvd=JXeby`vp2#v0smr*_wHtR#6c%`Xh5QjP)y3#;zwbV%gv8#cs8QoOK^}dtRWXRYz!=v3m*s$^9`N^ zh+2dUuK&vkNu+JBv%>f4Tg{v}ihJ_Wfy7eN znO&2|{<7AMfkWi_Ms6b;_)#<7;@zu>dOdX~A@8?+AvR*-fERd|WROM5@qzas=f~v+ z+$s5bN^XJ299vjBC4B}WigGyM_B~qo)Pm|wyWYQf`H*HQG9j%79!(-)0_6Lm4wk~w zxC-b}T~EGeSY~AO4KHq_pU*>uE_>;mKhA#@<)T%$zF|Gv9UcLk-lm1Q!$v&S+l=NQ zm74}Nje9)n>tt_rwJ_Vbx}$Pd4o^bO5su3)M~iCF>l?uXDI#8XEEbLkO^)GDgqqmr z-we3tyYq8#Mfh@GLCPNsbJ|{9yS2E}a1El;0qM3Mvr%?DXp=yv`rz=S=YE&Cbd8&D z4ZfTrn^Dy`e`@+xt4ur{uJ47$E{mp;)R?Xdyt>(uj}psyU?^6Er|Gw-_&*iJt zQ5DRbelfsWw|DVaIM0h!;M4LiwU-K)_P=oFHcgM9?8^Cy;&}{0g??_F)U%nbEwx`% zYQ_6fdd|#^Aj4IC!={s)v|_w4-bA~F;qSC_hwDzEQ@i5vIUyfFo`+kL#k9&29>f&- zC(2VLvwgu7Ew86be+r$=3_HV?LIC}UjkOs}txn7k{Q-_&zUWrDhWZgJJYkh=B^Z%x zjgX_$9;~r3tFlVyixebY4SGPl5kehuxE9WgHd|q=676P5w0+NeoIiAi=!>0Bs7hSh zW7z<~3RE&vDNW!MF>|>Hqw5*q;{uWX~PAh#n_#-{H%h~CQ zUnQI2ckH+fhUUXHHBTQ60Z~K>EMtHRoHo=9@$IEwDmVyE%SdUz47{@64esI1IR{fr zz1dLK1P=qweL-|x2AtU%0flP1&DsG5WBSz@bgH~(JbwU8Q5=)w%ncI1h@e{xCy~5< z+Il&JCw4aTA@SKPI!1phl<%_pc385N1a$?$5=LEjTF2kR$;jmOIuikVTCqukmXT-W zAX785!$Dr?ak$~&=8~7>9}>SWUM%Joz*j4uy3?t3DxMtVNEZXX`^hM8-EJu`2~fPZ z8Nl`(wRJG+G4ZOLWIuE*Tz86QHkOGN|J9-kTV`vWzdm&>d`F!Gp8HXGUIc()K6-Ypkx z)0bN$qonZTjIe1lQwzr>r)i$uO$#k_l<8CCspSo*13LZ4kJ-b3kIot&+DW{6Ehm07}O>Z|E$<; zwj6^}*Qi!Fh*Dvk?2iS=tZ)9Zyn9*?yGm?yguBj}T8uV2i8jdSd~h z7fs?krEz{MzA&yvB~}hjQkb^PZN|Yi-I9 z@8dp}snSLH`5J8+4^!5;+GUi*hupO_juO543;~;pt;I(DW(r4D+M)E6GOCE=Z6_Vo zaDnTat|pUM`T>92rqX2!wrEsxVwPZ2s{h0WM(U^F$q? zbZ($hgO~rK&u{QZfxTyMjPRfGgPlXOIDs%R)@p;)9laHIC;(l!^`;MWyKBwqmc!JF z8-%9oo=67@3u1Gyac{Y&Q>oGW*Wwup@GT}>2XAj5YriF|W!5s_`{<}eXYj3Q`QPui zbz_q;H0XLR;3Xo-Xui>$_@{yBdM@AxyvC9|fPqn7#GZpIm5(ZUp=$_D*_U(kLHYLo z=#HiSt0;@jG5^16x+?#1eg@+{@A%(d0AP!?Hn4jScply9l7G~u0QKk8|5^3LZ;ejd z-rkVPj~>VE-~aEg`2Vw6ZAGAp3f;*w1_B{$OT2hYYyS*IfMs_~x(9qak{m2W_7$BK z4kPw5nhWd;!Wm+3>;+tByCU2-09p6n(dJ;uE3f#h)V77Sv8*Vrd|YwK24~4(p@;`@ zaPyw5(-;xkzrd>9XDxT+rLNPHS4|bBxh1-GX7C`T#4f=s#Q; zcxOF3Nar;{i169ZcX#&_J-U5r7T9tLbk#X)i#VMEfdn>6FyUr()#PJpcGW~<4J(U4 zbNH%$5~+Zm%8TItT^&{Ub4vHH0ym~M(2DZ=k=%O1WI~#jP@cQ~Y;7Nms7DXsg1|=Q zDS4<;mzB|(s<=B9Y& z3>H_qFUwbT!(l{Q7FYn?4sSDK+eyWIi&bGV&(+m`qcrC6GhjC?WFNxpi6X}$!RkDB zl#I>ca};Vq3k5&DO#tr~@&}LPA1(y9{g+J_@6jfdy}A|{KqNnHh_@j9P?nQ5HN29- zUQFe;Fr5&A7L};vV~yp;awnkj$ea1>hI=Jn>gAX)>VBi|t52dW;y=ESOBE@;=6f$; zKyUOU=E3}d^23tuk=0oO_sAz=L;=wOk+QHM?Q+QYmyk705dl}pgr{CXEwr@|R+TRz zUo0(=&$89`@GzG_ElLk#kgg=>fWAKPx;-R76|O?XQ-gsdT)?4uG0_Oe&;Gti)@Ceg zY}v$HKrDrdeDY2#{7DxzuJ`MQhvE<2hT!GXqil1Iul8IRe+Q?^^a0g>T`hhBXICFf z==>W4>>m7lXs9U(^6auP#CCpsm!JJ6^$AE{+F26o3%SvbeAUeTw#l|ahiMvm_F~m& zt$N8w8@#sV4;w?Qci$?1Nf@O~rWAz|kMX`YjIE;hD}@u@LFLnLjo1!(jWidIpaGg6 zmRUm`1RvnID1%UnA0R^>ZOrAzBg}Wz*$1#FF{%`vLU^#7+0Q(6#*QBNpUHOqw)nMA zFIV-Sx9*BT_Uc9SgVSu9b|hqQDWSk(Z~r}BDe2<;e%t4nv!q>>&6GBZu%$}7`$Ped z_ev*A5^qj;FZ}k@ikamRzy4N+rsg+V&l*x4)84Ozh)%*im(&Ja;DyBO>{uNivRD7i zw)Htc%}Gy*^=0|&p0sVtZ>ZZ!D!aH797?E+jJMt+VuwjpJw?#AdCAIb=HDM$tmjf| z${?blV&_WeH>%PU?=PV_LkWZh*fvRa8;s<7*0nGdeiLH7ExF}a&YY<5)7|5j_(Dy7 ze&d=Q!<~>TOK?pXHh(T=&!@6=`9aS^|BGirDa)h#D4cAA^n~JO&5*2-+yaX`D!rFJ z*$KY> zCHXRTBIcjbm0mbU>4w6Sx_u-wEXhv#J)~>z4Sl;a36ItY$;!VMoW=Tp!~F!8U$bC2 zZllfcgP|eAPVgLgvTW7W)spG`;2KtpT-k83=2sKCE}~^=mczsF-BFeTUzE8T!v4bD zdRM!J>7(R7V=vI{gTg8bwVnRun$2+ZEZg2m#QyH6{q=|mbnr_vn0TQZ9NIBGX)Oy6 zF_5on@Y2_N@z6h{P1s@oYpnB_f2FV8lb z2vY`cpk>{4p{xv46VqueDilyJ z>=kIa(>YUIfgtNdOYggwszsKwhU!E(7bxoI#+-NpVq|7_n`s#G2*NcQ5Ar#GSIWeu z_;1!hZe0egau46LG?FI2edx{t@t4T7+(Ot}aejSYSOMK23Bw$OhJ7A!4=$hn5%yx@ zTXj{n;359#(^E!!&4qFvBe^}q#ERG^ zliC^%`JxdA1LQNV3qD$CxcoHl+pd$WJy*xY6ZosYy zf-8C-#ZyL_{HAJ4EmLc8(Vw}kHNVadaBu&Fg<(g<;Z?>$+=Fc zANUD2U=mj`Bp%=8gMaB5@XHgz%cd*jdceVbk~?$hArCFV0%Ic6CIa?|+8(qqwwcLF zTS!glo({-1^GAbxABy@htB_1ClMZQ%&AZD+6G+53UQ}>5Lb?8J}(h6#= z2Pn0X8ycN%1OZ`ZH#5kA)qa<11 z{iRy%%j&05KK#`qCWfcg1X}L~%3~~hufU&5%~0ekfz5i22~TH}1|061lb@omGVdXggCEK5{e2VqE-zE_FX@c^vl=6T51FDLZM&nMwzY6kEQx~Me zu`vHx1ZWE}cx$Ltb@n+xKk+-+*v*xTPV0ceE9Bo6;{|X52(&E);920+Y#adLfc#j% zU*ZDQK!9ohz?c6B4~Y8FfRxtq-+L*sfL=H={OcIQ-v|G49E|z?eURsGhY-JRAKa=K zQ{5RvjH{Laa1z6O_|p#g>mod$6^_2alx3?Ome+G~+jnkh2>89c2&6E0J{v6<;{>li zDg;)cbf68!c1MM;V;;{-yC-8I!}WdNXB`geen z^XUB$5Ma&}7m0x-XeiUI1wc)X&y>?lS09!1yWJfa8DpI0AZJtd^LgMu@y{v?sTqJ- z++L}6*@$4BI~O|r!hj!=Cqjo!XtQkMyfl?Cp80972DnB2@3d7J0>mc3d;>=>e4J$S z`(V3E_d_?SG_}045M7p^bMhP?y#PEEuTz<;Y1-mpuwJG40WEHh&;g}4+ft_ZMYz+}GhL#* zpI7Gl5I1e?fJpIB0#!5s82&v$^bS7G?zi@vfj3!y{^)B=AG+z}}-| zE5E*y7n0UB_Tr(6>FM{d*R4bkpf7+nw9+5EC$jYz%@OtzIna9tJirm?blYq&V?k;V zy*p66q=OrHD?8lS>T!4QLtXkaljkS)fuKdz6CgK<&B-&zFRFTyqE7i9U} z(GWvKxBDDcS#D0?bf2#W^vsA=HT+!h`1$ea3qmQ0q)4ck_TYL{t z(CXIAcR=t%UNv?IOI4Lwk-o*l&#EhlXARH8=B#@vU&PB=toa7-1t?W3DV!S}VK^Ey z$-5*-GSZ}`v{QE2e=_@B59#1emmw8XF=&r_NrLP2s3;Pci9T@Fn~!RvIg$IvtV=J= zV;qI9mN0+&TpAbH;7(7IH{g=3Ml|zj17jJ(c;cs*oHqM)7oUnAyWAkN9f^u!BF`os z>dz`$*(po*@7u^-Fe6csSA9Bsr$`4KuL?gSu|8?}v_+SdpfL!3uXQg(E%rS0e+#&E zg`T8bWn>+9?MkZs2XkTt%qJyxrN$ZXdkM0*c|)0Trh_=kfZ?@+v*vzmyo_Tx@6UWq zx_d9R6jU|#bv6#r34w1B43v22HJ2Z2x4htAt>ez&_HPnb>>zgyD6*{5+^Z(T);H;y z#>g$d88CtTA}vwYHz186cu1~C8%2V7*J6o&V#^e;?J4Q`@-Ab5Vq9VlDL=gzeJ4o{05cp97i@I@G&vl0ZRb=mMjvL+MX~NPUU{8wucudXh zLINB9nkpoOk$ONz$>|6X#92Vs&{9-oc$Xz;y^_Zx_Z27=%NWC6`wH{jmjoZ}lF~mW z81>pzgPh5vQObq{fGrXEYm>($s9jwy-o>=b@Drcla7N+8BSiL^C3Jr6G>B=q#WDnj zhUn8yeadGleEGNXn`u98bvh{80y_fYVD!+Q_;*XW?!#hux)yb;DL|#|t9apVA_(Z; z$zSU!e@ecqE-YYdL2NI;UBIRjZ%V47>u5zoCHm=wyTuRSY_^G<|J|v|%}A5EfW`NT zWEDrsAdZi%x~V|XST%Ygg0R#n3Mg*Y)++}{_ko~eay2)R89g@|ERZf3!Mu$9y-413 zXv>q}LlnbIYF%T=XXDaGT!6_D|4V1%5_>D((rf9d!m>{GbOpfS5H_Nrk7U+)u?+f9 z8p+ex096YAKS!mSVT!vdBQ0gyF+57@Y?FF6A@`e%GNX!%L9ntT7+4(U|ILMZdyu_1 zDYnc5*Qm9&R4iw^(f{50p;@Z9vz-PXSI{`{(QEGHpvkpB|Ah#e zQo9OV`Pi|4G(_)aZs;@rR)^P^tNyckgz-M<|$+;YKc!qm3Ja z<+0JHjwtYUA?q_Pi=hdGmguR3tM?T~&?vyFp&?*{M>q04$v`2gl1ou}Lp&gNGA)HF z0(UbfpGRI*?cWJExerOB0_uDT<@mg5$wX`6+a#Pu172LyLgb12=DMTQ&)7TzIbbca z%b60t4~c|62a(2e)8H-49+Cl8Ikt24)|m4D@nat(_{`v7>AoBSfx?%OUVtf_ZFxZZ z3apf762hEbdlrT_dw4t%Vkb2wjw8)Ip$>52U;gXEWQ_Lk*2R7q0Z|Ks>g*;_iO*Vl z(Y}BjvH9-@;eb8-NOKO={-fwAw0eEYbzN;t4I0Ii*T3&(X3naJ#UL-T^$#vv;jdH3 zV#d}ylHIOQ{x}JJUD0sH(A%Hab3q@MFkijnKF#G5xOd=FRO1FgHmy=)@E`o_ZdQmT z_8h)*8*vt~F$wyL{LXUe)Eu>4d5tT<18L~z-nc4KcU;2+yuwcBzm(P^%-6{zd>*~- zIy;1)gZ7EI#JdmF2a0N(lv|&Olbye@l1mmM^9Qhs#osL97{>Q(XVw82SI&nX0oP}# zJyR*;#ZfMeTl3Dsh_O8Dbf)dBfBC{9w%2-s;#}Yi zKvY6rMnXHaingMBl^sw}=6_ljr-ekMCA&E4Zl=$DyQHA|6{QTF6w1$bmg{h(42hf+ zlUL>acSv0kW03ICeEU@h>?1qHj@BiSnSutMk#6_-W`40S}MmBD6QeuJ^cW zh}+1s6WzTxx0z<3N|o(3&3(Fqpb&!_KDQGsN8;U{(%4_1Po6haoBHld`=JrpAI>>z zhSQZUrxewpZjW5(wCfii)se;KB)0ueHa_PFO9!q^K=-2~_Gqqdj#YR>T}$U`y{5Khn|sYa7frv<~! z-y7F+Y`_iJbwlxz&ghAwY=Vy>Yg4uv!3G$eRBBg9=z!ohr21(qQiniouhj zjEbV|CjyvQs@T)9%8m1+xoH{v*D6%O&rp*``@0!t!dRi(*+BNB*YM5FoCZRiJK_cXWN~$v^Tbo1{WvCFFN&-cv zwda&CA9Q>Nj0_`T4=#obZrg%0IR z{Mn>n{4WI3NikETe2+y#YkK$`k#$TTMU5QS(P!!bfmj0h89pEkZkOvF3xgVZa=jM} zUrw*y-gBSQe8xbVnjmf5K56_MBW^&Ue%EM^@#*%8=DlOtS8ZMW`}Qy4)Jn* zz^QdZ-)>|7Ntypw!1LhTH<*dPBpWYK*tmDBf8U5A2qtJ2{z&7(*I8M8o>5^x7-%Z) z)(7tV-vEzG@ZCl!b-p?Fv$?yUOUu`H3k>v3J@%?8Kj#DsKgGeQmje2^dclxozj@Oh z@6&Qez9^rR1@HYit{ELSrRAilq7`MX?D>7xuJ4Dj6MDBcZT}_O3z(BiU=u0|uZjP~ zJHbX=?NVlxci)HRJpSU#VEBela`CQ_=9r5LWV{bYQ&Z0nd{0ly+3=m-i0-!>&*GV1 z8B{;(=(e!Sm$K-kxU<8kYce}X?t2Abrag6auz0{P7aMO*9GV2IU*L6d$7l)$go(ra zVP8NQh>|2-rb??9c@kko#=f3jFj&S=^jI74#Judu8Ip|7ryt}$YVtA9Xx(E84ut#v zR2&E6mXm$f4r_e+;=mbcCU4bpi$knb&?qFKkG*_#Yw~I5$iUeAgQt}DChw8w2$9F6 zCA9B-zO#C9QY{txA6a7^uZQisrB5BW`;eTPP(}p{Nz#V`^14j&k++dETd=WaCBZD5Y>^;ltPEW-P_K>xS zPV%+`@Zjyi!EAkp)*U^(nBCJt++QsVJQ3ZtDkZ~CA8cO7-sAQKaO`^IA`n0fl;8#S z8NXKP7#1v~dP3LxReqA7%5o~O{SOOpNLAsz+hzI{c3MP}R>q4bL`^yIkmC){mjVuc z=v`U>j%|IWiybQx3oLKTyYN|c#-HX_^xAo>M^Vk+mp3C0_)uZAjmt?!kN*!{ma!K; z7w9-ON4{|5rOn+q&m418`wSq$dy}7y_`Fte-1VD#2B!%>UO+KzC+DGidAHSJygGNo zR!deL8*t2^m7cU3z~c&ppfP^xLL%&Onrr95`;2v8x>FENhVd^h{79L8{?^lIFGGuW zm3a!2Hnlju6PA%|1P^9D6hy;Ep zfCs*LQ>#saZ33M6cvqIatQG&$PY0%(n(iIn%FXXz?;fOj_;I&<14K&%bo&L7oE-?U z6xzCiGJJ%&H3A?I>3>2KkIM@q=?*2+Q(2dKen??N9$9Ir`mv<6HOBF^uU0$R8E_P0 z;w{f)wHB4I9zC{$kA#zdTv~}Rf~#;}T574RxU+-hV|Wg^8CrHK9F?#HCWS5}g8Z28 zJ{h0#*P?~xi!~Gi2zwagsXRv-BRUlR_Wy-T3s)cB*l{#cP^tjxJLWNQ!#j@b4 zXU`D!drXUptGnM@a$_Mgi1DQvhD}qWJ*xR6wPtSpx~Lu0h(=cw z7w%L~LP|ERaj)u&yZbk6@#v zv~0)EzEotd#X3G_4U$PKk&e|VnI*vvHp~5^9`yFEOk!R!nA`N@%if#{)njxHt#IbS z`;QL)OR;qLT$q(I$rG{v#nIL2$+*m|2<0hpxc#JSPuwsw%z{L~`=vOegl+Gj5#LI> zd+a0q(RicBDt0Fw*LPNbNBEaxL=a&fpXV=d=X?R;Z?d;;!^-kwOMiulm4POXyZ87@ zccI&Slbe?ChCo3UqT41)q;;U|55epVIL3XZX{GW3MXzX!PUPv}-a2oN zH|8EC`6_Q`a4dsxzG;Zr^NLdV;Y+#JzM}M7e(GxHz*8BQhhd2v#y$=pCek~Y(W+O1 z1E|nB<`#u=yrFDmxF1uMKt3_X&CR3t2``uGl2y4m6m=8H*1o#ec+ZV-5pmnq|1ga8u63#)nnPpBJG<>9NQ-JQAgtW!fI(d56bR$q6QDiOL zcn0>grZ5tqKJ4J8BP70QMUB+eY5|uo`GE<<4@=^$h(Nfd&^63|WJkqZGyCx5EQhCa zrUj>bpKJQZAa4K{CYh|b8buE+JDx2r9rG0-lK%7wIzfl%yVdEJcVa2zQM5D@+;DZlh0byl1s{`|dgL~O+-yqTEw(HK}Pv+ZO?(&o?TTO&dlo-v8gD7UIcphRK&3>A9I$ za#N1OiFJ;6AgA4NE%bujZZ(<64q{XYykI=i{dl;Pm3gz{^?q-GSPII^X+EyY#YDq3 zUzT@;I4z#Jn3Du;IgkAx?R|GtQ`z_LWi03jq9e*EO~)V|lqw)#Lkv=+C_)5u=!AgM zTL@!;8IWQSkQ!_h=`D1kgVLLH5+EWabfhIDA>^Iw{N8V^w|?vUe!utLT5r8S-dVC# za_+hN?6dc0@4NTTz8br&Hd{yOa(9!eX3c*!>%aF@y^!|jF)0@R+4FRk@I8qyKQH0- z?pSpzX&vhP61b=5-5=x;d3q3X5$$=MHkZ_#9|#L`+Fh)?8{*9|l3Y-t_Iw1(wr)~JAn z2)4xSpV`(2s$XJh^QvA`d+q$Ba_ZBITnLk+Yty{Id6CM`2?uk za4iPm&v?+u!sdADw}d$3V^{Q@NFpJI8|S1A8tK)89Mj;Kg`{HJ$zq7rbk3{^ow@1N7VOJZdC zM|*It1@F_`nzi@-^i+Iy`sew!38WJu`Nh{=5;N9QfBL8*^=_g*MdNVUHPg2HwzUbrs#jFQ)V zH!~M%eX)#Pp9T?j*Lz<~3HUwiT(Q7$<+OJ7V34+jp`o{u76>^z8HsH*uSM&n6I3sY z=ZpD^N{&AK({qS6{$eT_(TESxZjDo*2^cAhI!okGQtWH31`=}2fA@_1~)aUfin9-l%tqYjC`g@jhXD`jF(}N|5dj3RM>;+=Dn^(phvYoXyip?}lx!ZQ z6!gVtfNCt<54Uf2E6MQ|@_vtwnaU z_8hWZ_Uoe97W;RK8}q&yeBQ5UuVvKnEXzDNaz6C@-PJT zCmsT#A(b$vq#a`Fw=5fak^)4+r)SBA2l{&QG^`N@7?hVU-d8IoN*>8Hh))%OrcbBq z|8d635^D)T=Uw(+;t6|f);{_>1~nofa`#1>ObqY)XyljC>fC~k0eSDJ3T-L`LA<=M zHutzu@Oia`{3*fcJ3Tw|X2DiYbB`7xvr_thf}mZ0!o;{#bjS~88JcG|4f>$W*TagX z63ANfEDs2J5ckWYpCI0fnT03~$K*ugXhv3W=J~jatZdUvAS*)NZa4WMi0?droUfUc z^{143@5jGINUs>Q4OHYhd%nn%t?(-;WEn%y#V45%o=jW_ih2_EA3Gwr&$jMg46 z^SGc;g(U~2Ajn4&aC!FYD|A${V=_vUSYZ+^zOS}P(ID3RYkY^z1MEXRuF!749RlD^ zX4K3=i@G+sDfB^#$^M83PU(6n)0g5=)rcrENF=)*ENLCEhFll6NSaY;kBwZ=nI+_25_ z-7h!kRy+ebVvDPbH5g2?8$Uqu07t;wurU{A(8D1j(NM9y+(+Be9Vx+=9^YoM*<6Nu zb4A^f@DR0`EI_ZKJGUvxQz8vvL97z5=Yc+4dQ&pE2ON>lK=H%2a;xbML06eb!^MDx zVLZ5e(5>+$LefGfvDtzWj`)0dfH;7BKjBpJI%p>sf!4fG7NOaubi+KWb=CxehP7Zy zv@Q6>X@>Q6?ru_EdiciRx(7z&U7Z*j)TI{cXLPhR>muHn`(;YjFK$G>G{%5*nvQ-3= zO%ckGzr};tHV{6+njRDAB+dV z>47ny0?r(a95if3At$t395rN(0pI%OxEi`Rrr#NzXLD><0cKh2l&6u z5uik1_!{l|8UDLp6(}YcH;4Yy2`A7t(5CCZ^F|Lh1h4erV<(VuF#ZeF{of}4qGYon zre@-0u912_8V5llA@C;4wVd4g`1$pm)C7}9#6LRV7`$K?xj;5=63!T+WrE%821hM6 z{N;HD1q5ZPwaH8{I; z&&!f$HUkDU_GQ50i?`*f+?-HWU1I~x@t-f-NkbUf_G;Nc`ML~QUdn+4p)hM0?|P7)ysv%&40eML?4o-8(I-D&(0I)!;ZGE?W^}$U z0G^K+`kbTH!ilg98}?1p{+hi|*!aDFQ;h#0_nj%38-D@aAB_F!9wAMqcJSzjj|;ER zXkZgBQqKZk3XJ~+jr^A~A6=mk#!|U&Z9Zboh832ChIjY%tJA+C?0;8dt-Q@m7f!%r zpM+gOFmk;A%YgF#$^Xwp>|X-vKY01S#Qo^!5XAbBD6i-|*+eVDP-gg!EBzKBs;0)z z|Csf*s5@k43emd48Q%=t%p(( z2gEQ=xock&_=+uit@j3c{k>&+!VLwcL5yywbtQVHvsP1g>!Wk2L+h^UxvW^)WAQrT zwW9)ZdZtqy%2c}rC9sOU+O?mcVUt*$AoO4nP604$?RjiS5eiB{G=@iaXi=GShJ>9j zh*m74v$ZKYk6mj4d{?RC`wa*$&lcn^=3>DqeW6wWL_yWps3MiTrc95kx@~(D)qnrn z#JTOo@#M1;<i1U7wxU; z0>(YqforY7r9qp$hN<*%v2N1$zm=;e!UbkN3)!_)J(P5AiJJ%n4aSpoxv7C$6WkU_ zoz+QWw1)zUetm~Y$fkW38gl5#{HU?kV(Hitci5_ICRxsI$3-k?Hmh!0-g4?&6saed zpcm!QN!o4?F7;h#Kd!kEClWZdf24S#TFy2^|CnOKY4Fv-#=Cwaq%5gOHycvNx6kWJ z?!&K`MQeg6Z}aIK!oBE zigm?uLpF>Z_c4~&IBPK0vFRBJEpEj8u#4KluYNa$S8VH=Eoa`_Yq?t77_XvYvC~=| z%JF70yFI&WsT@YK=4Pc?B89Ov=25pQ;QetAE(6G39-r6+6=d(|cKu!dF;8danqKwh zAgSGxGf1tplxkC1)iKTu;}ea)QH#5DZ~Bz53T-PmV9N&&h*+9$nQn_@;ypao{Ye?*77^LXu> zM3SgGOK7jjXxvL00ViX({cR7d9=42{%IUZ9U7dePX2h4++x5|WUpS(ix_20SqCwY# zDO;=AQ}rvH>>rf3;(1F$nB7XD+tNt9#0{B0W>cx#+38s`>MANz&y*Fqq7(~TfpTZT zSUmQyS#_k`6&s`FVKB~U==PuI=9lTjHH+2C>M~o0ycuJ5bB7+?z80dh*^jOM`iRuB zM`)XAO9HQ_&ZfPN+Q~Afl)I7=)a&QgMzIV_Zz|SX$-aqN!J7`Fr&*#Stl5<$&XM%x z)Uy-);O(y~%mtE;e5?-3E|4`hL-)NK_1bKKh)InXOxE!Bs5~2N*YFRceujDubZIjh zkE<{Hf{qBJmUxr#)CzRcbOU>43j83D*P>4l%uVXg0z>jK&8N2-Yu4DGyD}#jw)}wX zx?*_cianW3oNkp|aTT}}!KZ;pRl~I4B?P9*`xF-asDU)>TNLU>yF9YAU7EQPG;~XY zmS%MvXf9BD0CJ2itfnS=@kX#aLCNvjasxZhinLRmZ@n1>V-XDau*Tr0>ehFPo7qjV zI4o>B5*4sg^77m-lTNp3Y07!cU+UOvu(F_Fi(~86i=@rO6Sk2V!ON?1)*FPt?bX`# zD7(@4XkkJ(Kw0l@?IBu5aA7yvE;!VwlXd%`mb-fq9k;z|9_%g-km8vb*8O&oM`v3C z$;A_(){S*4mm|RZ61$^$BWXv)Ic;^PZrRs!Yp+p~nZ68>y-lPpR4jzKrYSLo0{q&bfT)RFps}FqTIi0yp zqox5hczRsLdo|f?mFb^-Dl}&ZMdpbjRYhE99(w(8uK8=SORJ zjJCoCXeQdTPHwW9)WBg0+1-sV&Cd^i&~oYxqoyIoyqPgr_|qiVMFnnr)kCqN%G>*0 zH+DJAGK3z^pBLn=I~A9)Fh==-{YM`4O172Oy_1TJaFpxi(3*t=sVuxvXT@sRx&=*Fg#G}8|pMYrr9uA#34u6u8!!7 zoGWRji&Cu^*7W7zT~H?d32^v@C`#*b;a{=?>kzqEd#=;+FdDH7Z{^Qw274!6`(C)2GVT*vY+#C@$+P$Trfx! zg>H^nRehfs_3qwWIyE~HAs+9$aNFT?Bmp==%eVp3MlU(vb}VJ0QGfc+(`V>aB|Qyy zfQ=K&{#0Z;M&1c*uJuie+*vG(Qg-c4t~YC3Ui|ND<}GebN_=x7V&=6{@(YA?``m!} zo5d+Mw@O)rbGzn<_GO0X^&Ul`^XLcY%PY}7_3`QCoB(+lQl_L!MV3c z&+B*q85YOnS>1f1no6D_lO19N|G)P;J5T(bTISlvq7#Q2=$)`X0q=gBRm9b+3=Z9% zEShFhxfTaC91L~1%z>gi>lxPNvx9Z4fw3V*2tW-yqA@}|11O+@+5RiBn)9E)Z5+fx zzH8O;T@nxYDy*?sY`>N=R3{xBeTAMAgXN3^kF_A&TIj=g@`b!KC5&I-ba^}Fn99M< z1IQUcr1^7|qk8A+S;~&ho8Zyh)w9Sp$-#KCr|#_18gWmbQ<9}|#x3I!#|Y?yM>KFr z$G2y6k@yY*&VHsNIT^T-^Z*Qc!DRijqHP?8LY(Tk65A#`{=IgI7NhOwg>P$VY8EHe z_F+N)4@BkY+MH$DAgAA)LHmQZ;Y)4-a6v=28uRc7&E%`J zk$+rArC&Cnv&>$v{>)d*z8A?>f&-?6`m+`JClZZa-LLnRx3>?1pd8k_@Z4oVh~5R< zi;;Y*bwl9pQDIx?&E;@Y0NQlsm>yC3{Zo!Rx%^ank}g@tmkoQZ`Z{YIw?Nevrah8Y)5ztJ~o0d9$synN*pFv%~E%7!LNW^6rdD=pwO5Q*ujM{OQ_ z%m&TONlCoo+s4M{Cl=kQ4XOu@h3JyD9dAUwJ_TMB;>+IHIAU@^%Q=Io#hf!CCE&Iq z)MtE)g3++O+AAQIvAIBKf32t62HT$5SNgO^2XqF;oA*m@yD3zCRrFdYz$F2%-em3T zV`|rGvq^i6Z}$xBZ5E)^9T$h=*9!ePo1wTOt?>e&F|fI2E;@rZZ8$gR+BY|-f#;95 zZ6>v&##h!0tUj$CI@xB-$nYN*cUt|XReJ9uW9_M8okYB(-HXXsLSkpCogsQ*msQcOt&8NB(xaLLjwxxx}rCtm1OL@TFR9T@91`?R~=n zKQ!N-dFe6err}@uU_yeq8cRxnU77YoZ9Fhyb3S9h?|<26LOSmmOlj8IlZjLUPcFK@krKl@5bOX0G70;Lfj*1apMeShg2;g8am0d03b<3=E4TAU$kXJ8R zw9MA;h}Dv7D%Lz;%?Gqmz~s)lKug+m(olt+HvkpdF7Yb0H~Qj~x$)OhO2KrJ^LQOv z$#Z-FR-2{MD)A2AJ}Ixo_-_XSEvOH+8EOdi1TnRkX#Tx9ea=ZqiH<2`{m|vh8fRQd zzlUrxdfw*j;BHlGw#IOdCR*Yu&wNf9W7s9S%15eb`(V!bE8gG@t5;%glr9E@uokUv z^#&6?sfh!5sP%7Ac`$aum}lQ)I68UnL1#+#4*`dn3-;X_cdC)`o?9wc<~9&NQhfgw zfI6S180?aVx|B@25_<4LI>7(81sK$|XTPSui4E-(D~M-quNQz0|9U`jQyxwlFF)jE zjFR-?elcwGx)af>Oop6RoBKd}By|jRLquPKE?$1v%YQj4eDrMKZH;$ow_s{NWE_4(FKaDplYV@nH_)i_ zRBryq5%E;XXV1=fU&q_!S!u9~ZY=3N zN17`trn;Gd05}L(haV~zH*6>uxrM-yOA0Qiwzk-eJ~;Vn@{2xA^`or>WAM?yI>;P? z9EkAcp3s}3duo(LMDT*y1I3xPW@(AWwV#FbuBr019#xgy2Tuz+xqFFM&&#!Wa;+b6 z1#MyIdBPf-bg-sD7XB2(#mi%jfQ6o`Ip*^4+S2?S=JWA6%@aPoQ&!V2QjUUL9t7E_ z4Az7N4c&COmK|;%M2fA@-MN&p!`2;sgN|kP*iGj!LaO`^oIlgrn;!A_gpzja-{VU^ zE~H0;)sIRm8bqe^7tM2Yh&rU-P?idmH|R=I`76eOfLoeRGo{;a#NQobi~cx~@gtAu zuUf?wB#%03n(z~b*&KIjl?Ux(W|N55yj5+TU(1(fdMJ<0c&=2WbiAUxKAeE1hdRS# z7W+TR#Jcp*4Ogn>-89Zfv+iAayCm%I6#Y0>Bq^R0YO>;As&yrAh3Mqmm-#XIxq~tH z*pGnx*vPNB0tuq(R}FfnbB26G_LBopADMGu?d5 zp|gP60j?S|tno6Ayv7}Y={Xu3x%Rzb?uQi6V-A%I9JNvBJu#xrabGz5OZl&w7n*VNvdjcZMtd%|1To3|%0)ch zTS34rr`oj;ebGTd9ih@OvtD-v&4U_#f$3u<1%C1U`c{#e=tUtS5~81ni)g>%jGhx` z`M@We=fMI6yrbJ*YAV$9FEmo^nF^S_7jeqJlnW#{Ci=Mz536(dQhmI_NvwW8+-7e2 zPd%asaecL#qMlackXhseBULuS@NK9!~)v3(u#DN4K!bp4Y3ZQqsKb&b?Jc>UZB2W)sfdxYINM{L0lwEV zbhI&wm=+eZGJEMW|I&~+c2&Rc{QRFb+CR{HK1LPL^2O1p=XC{bfj;zBmgew%c#<4j zd4cUSxIJrEM(CCM|@s5rE;GEkhpDmq!rOG>6 zOKYX?q?D@bAG+e>gGfam-^8}961L4^*q?;Tn8|hy6fzBPr7Nza+41}H$skf=OroET zTzh$Why3C}0YJ=$FaR(1j$Yo+51yLEZy@*8T=~)ycmIfq!5R8}NgMe&>#H*xb~O0B zii5Kn870Kh_44mtdId6bS~gVI;MDX9Se$=757a9kHg8tTX=iQSk!`$aE7KL3|4;)0 za+zlUo;lVS3fR5S89A9t#TZZ9XwK3L;al9a2awo9l(3Yvs+_DE#=nT|hfz_dH&D<8 z?>pcR=c&VZuIwWVSkD|oQ`!_JzP?5Xqs>i{=rJ`7Ald;62Mz&Z`a`hivgP`Eb63ZG1O$0Y z2RBrHE`JBg7mWGe!y6B?MC@L2rU)yY7F9zU;MWS@-nB^$qF<}7F+&S2ykGeNqr32j z$_W*)7eTD|cDdt@^g`h~D{@_9-Hp9am1AGa3gr7x4Y$h&UnAff4<7->6|Q=)97$}~ zBpwyUuLbY&zUl(jM3ua{5sXqm!__va@8QY!y7yf|zpV+M8I8ew4oB#=e6T)UuG%V4 z!<&i0R5xj6!jnWm{#JFPr{Z%*X@|Thg`C|a@Wf_P=v}k)cjSyhRYTQl?g3cE!s;b= z7nJY7c+y0pftQ4aa!p#Nb~}@>j7@d zpKvV=g-F{*EYzfjoRuae7+f52-ebWIC~huWAXYfOSN&)5A+T;-Vv&$P2Hm~^Dj9~n zKPOuJ-J_9fcnf!dt*+_gy?MOy7J+#$7LCi2>nkm25v=_HtJZ@|H;{q#xy>(}4f{-n z&$C{)e2Sq($%89B3)G$=y)IAN2O3sjuA7ONVo>RCPk0=YeNQ78lx8(52j{$zD^qby zdA0)|+SiMcyG1kKPfVr(XUm9RukgB8K&((9GB|U@{N;!_MfT3n?V0&KLr0B*aX&0E z-v!_jJ~&V)n*!=P-hyfnfSB}Kx}fj_<5);0YQ*o(1j|DGM^0Z7fMBshrr=dz%k3(q z^ya#gpx&94Zf{VBCavTgj9M<8k%VV&8te-S%MDLB5U*kcJO@>m2Tm{a&PX6lor3Uh zTXIBsT&=Ps90$)Jt)>d+eG4d+;5D07KO9Anqz;1e!e4sB;V&@w9RAPBJfN@`u^Qsw oQJAQve^G(~-{=3qasCj8`@{><^u_qv!sH?KjIS16zW3 +pre { font-size: 0.5em !important; } +table { font-size: 0.6em !important; } + + +# React + Redux +## William Petit - S.C.O.P. Cadoles + +--- + +## Amorçage d'un projet + +--- + + + +## Méthode simplifiée: `create-react-app` + + +```bash +npm install -g create-react-app # Installation du générateur d'application +create-react-app my-app # Génération de l'application +cd my-app # Se placer dans le répertoire +npm start # Lancer le serveur de développement +``` + +https://github.com/facebook/create-react-app + +--- + +## Méthode manuelle + +### Installation des dépendances + +```bash +mkdir my-app # Création du répertoire de l'application +cd my-app # Se placer dans le répertoire +npm init # Initialiser le projet NPM + # Installation des dépendances NPM +npm install --save \ + react react-dom react-hot-loader \ + webpack webpack-dev-server \ + webpack-cli \ + babel-core babel-loader \ + babel-preset-env babel-preset-react \ + babel-preset-stage-2 \ + style-loader file-loader css-loader \ + html-webpack-plugin clean-webpack-plugin \ + uglifyjs-webpack-plugin webpack-merge + +``` + +--- + +### Configuration de Webpack + +```js +// my-app/webpack.common.js + +const webpack = require('webpack') +const HTMLPlugin = require('html-webpack-plugin') + +module.exports = { + entry: { + main: './src/index.js' + }, + module: { + rules: [ + { test: /\.(js|jsx)$/, exclude: /node_modules/, use: ['babel-loader'] }, + { test: /\.(scss|sass)$/, use: ['style-loader', 'css-loader'] }, + { test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)(\?.*$|$)/, use: ['file-loader'] } + ] + }, + resolve: { + extensions: ['*', '.js', '.jsx'] + }, + plugins: [ + new webpack.ProvidePlugin({ + 'React': 'react' + }), + new HTMLPlugin({ + title: 'MyApp', + hash: true, + template: 'src/index.html' + }) + ] +} +``` + +--- + +```js +// my-app/webpack.dev.js + +const webpack = require('webpack') +const common = require('./webpack.common.js') +const merge = require('webpack-merge') +const path = require('path') + +module.exports = merge(common, { + devtool: 'inline-source-map', + mode: 'development', + plugins: [ + new webpack.HotModuleReplacementPlugin() + ], + output: { + path: path.join(__dirname, 'public'), + publicPath: '/', + filename: '[name].[hash].js' + }, + devServer: { + contentBase: './public', + hot: true + } +}) +``` + +--- + +``` +// my-app/webpack.prod.js + +const common = require('./webpack.common.js') +const merge = require('webpack-merge') +const path = require('path') +const webpack = require('webpack') +const CleanWebpackPlugin = require('clean-webpack-plugin') +const UglifyJSPlugin = require('uglifyjs-webpack-plugin') + +module.exports = merge(common, { + mode: 'production', + output: { + path: path.join(__dirname, 'dist'), + publicPath: '/', + filename: '[name].[chunkhash].js' + }, + devtool: 'source-map', + plugins: [ + new CleanWebpackPlugin(['dist']), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify('production') + }), + new UglifyJSPlugin({ + sourceMap: true + }) + ] +}) +``` + +--- + +### Compléter le fichier `package.json` + +```js +// my-app/package.json + +{ + + "scripts": { + "start": "webpack-dev-server --progress --colors --config webpack.dev.js", + "build": "webpack --progress --colors --config webpack.prod.js" + }, + + // ... + + "babel": { + "presets": [ + "env", + "react", + "stage-2" + ], + "plugins": ["react-hot-loader/babel"] + } + +} +``` +--- + +### Création des fichiers source de base + +```html + + + + + + + MyApp + <% for (var css in htmlWebpackPlugin.files.css) { %> + + <% } %> + +
+ + +``` +https://github.com/jantimon/html-webpack-plugin + +--- + +```js +// my-app/src/index.js + +import ReactDOM from 'react-dom' +import App from './app' + +ReactDOM.render(, document.getElementById('app')) +``` + +```js +// my-app/src/app.js + +import { Component } from 'react' +import { hot } from 'react-hot-loader' + +class App extends Component { + render () { + return

Hello World !

+ } +} + +export default hot(module)(App) +``` + +--- + +### Lancer le serveur de développement + +```bash +npm start # Puis ouvrir http://localhost:8080 dans votre navigateur +``` + +### Générer une version pour la production + +```bash +npm run build # Les fichiers générés seront dans le répertoire my-app/dist +``` + +--- + +## Les composants + +--- + +## Différentes notations + +### Classe ES6 + +```jsx +// my-app/src/components/hello-world.js +import React from 'react' + +class HelloWorld extends React.Component { + + render() { + return ( +
+

Hello World

+

Welcome to React

+
+ ) + } + +} + +export default HelloWorld +``` +--- + +## Notation fonctionnelle + +```jsx +// my-app/src/components/hello-world.js + +const HelloWorld = () => { + return ( +
+

Hello World

+

Welcome to React

+
+ ) +} + +export default HelloWorld +``` +--- + +## La syntaxe JSX + +Une représentation proche du XML d'une arborescence de composants. Il ne faut pas faire d'amalgame, **ce n'est pas du HTML**. + +La définition des attributs propres au DOM se fait via le nom de la propriété Javascript, pas de l'attribut HTML. **Par exemple l'attribut`class` en HTML devient `className` en JSX**. + +Il en est de même pour la **définition des styles**. + +--- + +## `props` + +Elle permettent de passer des données aux composants. + +```jsx +// my-app/src/components/props-example.js + +import React from 'react' + +class PropsExample extends React.Component { + + render() { + return ( + { this.props.text } + ) + } + +} + +export default PropsExample + +// Exemple d'utilisation + +// + +``` +--- + +### `props.children` + +La propriété `children` permet de récupérer les composants 'enfants' qui pourraient être passés au composant lors de son rendu. + +```jsx +// my-app/src/components/my-list.js + +import React from 'react' + +class MyList extends React.Component { + + render() { + return ( +
    + { this.props.children } +
+ ) + } + +} + +export default PropsExample + + +// Exemple d'utilisation + + +
  • Item 1
  • +
  • Item 2
  • +
    + +``` + +--- + +## `state` + +La propriété `state` d'un composant représente l'état (au sens données) de celui ci. + +```jsx +// my-app/src/components/clock.js + +import React from 'react' + +export default class Clock extends React.Component { + + constructor(props) { + super(props) + // Initialisation du "state" du composant + this.state = { + time: new Date() + } + // On appelle la méthode tick() du composant + // toutes les secondes + setInterval(this.tick.bind(this), 1000); + } + + // Méthode de rendu du composant + render() { + return ( +
    Time: { this.state.time.toString() }
    + ) + } + + // La méthode tick() met à jour le state du composant avec + // la date courante + tick() { + this.setState({ time: new Date() }); + } + +} +``` +--- + +## Évènements du DOM + +Les évènements du DOM sont interceptés par le passage de "callbacks" sur les propriétés `on` des composants. + +```jsx +// my-app/src/components/counter.js + +import React from 'react' + +export default class Counter extends React.Component { + constructor(props) { + super(props) + // Initialisation du "state" du composant + this.state = { + count: 0 + } + // On "lie" les méthodes de la classe à l'instance + this.increment = this.increment.bind(this) + this.decrement = this.decrement.bind(this) + } + // Méthode de rendu du composant + render() { + return ( +
    + Count: { this.state.count }  + + +
    + ) + } + // La méthode increment() incrémente la valeur du compteur de 1 + increment() { + this.setState(prevState => ({ count: prevState.count+1 })) + } + // La méthode decrement() incrémente la valeur du compteur de 1 + decrement() { + this.setState(prevState => ({ count: prevState.count-1 })) + } +} +``` + +--- + +## Gestion des styles + +Différentes méthodologies existes pour gérer les styles des composants. + +La méthode classique CSS (avec ou sans préprocesseur SCSS/SASS) est tout à fait viable. + +Les styles des composants sont également souvent déclarés en Javascript et utilisés via les `props` des composants. + +D'autres solutions plus avancées comme [styled-components](https://www.styled-components.com/) ou [CSS Modules](https://github.com/css-modules/css-modules) existent également. Elles mettent l'accent sur la modularité et la réutilisation des règles de style entre les composants. + +--- + +### Déclaration des styles en Javascript + +```jsx +// my-app/src/components/my-styled-component.styles.js + +export default { + self: { + backgroundColor: 'red', + border: '1px solid black', + padding: '10px' + }, + content: { + backgroundColor: 'blue', + border: '1px dotted white' + } +} +``` + +```jsx +// my-app/src/components/my-styled-component.js + +import React from 'react' +import styles from './my-styled-component.styles.js' + +export default class MyStyledComponent extends React.Component { + + render() { + return ( +
    +
    + Isnt it pretty ? +
    +
    + ) + } + +} +``` +--- +## Composition des styles en Javascript + +En utilisant l'opérateur de décomposition `...`, il est possible +de composer les styles. + +```jsx +// my-app/src/components/my-styled-component.js + +import React from 'react' +import styles from './my-styled-component.styles.js' + +export default class MyStyledComponent extends React.Component { + + render() { + return ( +
    +
    + Isnt it pretty ? +
    +
    + ) + } + +} + +// Exemple d'utilisation + + + +``` +--- + +## Cycle de vie et méthodes + +https://reactjs.org/docs/react-component.html + +--- + +### Séquence de montage + +1. `constructor(props)` +2. `componentWillMount()` +3. `render()` +4. `componentDidMount()` + +--- + +### Séquence de mise à jour + +1. `componentWillReceiveProps(nextProps)` +2. `shouldComponentUpdate(nextProps, nextState)` +3. `componentWillUpdate(nextProps, nextState)` +4. `render()` +5. `componentDidUpdate(prevProps, prevState)` + +--- + +### Séquence de démontage + +1. `componentWillUnmount()` + +--- + +### Gestion des erreurs + +`componentDidCatch(error, info)` + +Permet d'intercepter les erreurs qui pourraient être émises dans l'arbre des sous composants. + +--- + +## Composants "contrôlés" (formulaires) + +```jsx +// my-app/src/components/my-form.js +import React from 'react' + +export default class MyForm extends React.Component { + + constructor(props) { + super(props); + this.state = {name: ''}; + this.handleChange = this.handleChange.bind(this); + this.handleSubmit = this.handleSubmit.bind(this); + } + + handleChange(evt) { + this.setState({value: evt.target.value}); + } + + handleSubmit(evt) { + console.log(`Votre nom est ${this.state.name}`); + evt.preventDefault(); + } + + render() { + return ( +
    + + +
    + ); + } +} +``` +--- + +## Intégrer React avec d'autres librairies + +https://reactjs.org/docs/integrating-with-other-libraries.html + +--- + +## Tester ses composants + +https://facebook.github.io/jest/docs/en/tutorial-react.html + +### Installer Jest + +```bash +npm install --save-dev jest react-test-renderer babel-jest +``` + +### Configurer le script NPM + +```js +// package.json +{ + // ... + "scripts" : { + "test": "jest" + } + //... +} +``` +--- + +## Créer un script de test + +``` +// my-app/src/components/my-styled-component.test.js + +/* globals test, expect */ +import MyStyledComponent from './my-styled-component' +import renderer from 'react-test-renderer' + +test('Navbar snapshot', () => { + const component = renderer.create() + + let tree = component.toJSON() + + // Vérifier que le composant n'a pas changé depuis le dernier + // snapshot. + // Voir https://facebook.github.io/jest/docs/en/snapshot-testing.html + // pour plus d'informations + expect(tree).toMatchSnapshot() + + // L'API expect() de Jest est disponible à l'adresse + // https://facebook.github.io/jest/docs/en/expect.html + + // Il est possible d'effectuer des vérifications plus avancées + // grâce au projet Enzyme (vérification du DOM, etc) + // Voir http://airbnb.io/enzyme/ et + // https://facebook.github.io/jest/docs/en/tutorial-react.html#dom-testing + +}) +``` + +--- + +### Lancer les tests + +```bash +npm test +``` + +--- + +## Gestion des routes + +https://reacttraining.com/react-router/web/ + +### Installation du module + +```bash +npm install --save react-router react-router-dom +``` + +--- + +### Déclaration basique des routes + +``` +// my-app/src/app.js + +import React from 'react' +import { HashRouter } from 'react-router-dom' // ou BrowserRouter +import { Route, Switch, Redirect } from 'react-router' +import { Clock, MyStyledComponent, My404Page } from './components' + +export default class App extends React.Component { + + render() { + + + + + + + + + + + + + } + +} +``` + +--- + +## Liens de navigation + +``` +// my-app/src/components/my-linked-component.js + +import React from 'react' +import { Link } from 'react-router' + +export default class App extends React.Component { + render() { + return ( +
    + +
    + ) + } +} +``` +--- + +## Paramètres de route + +``` +// my-app/src/app.js + +import React from 'react' +import { HashRouter } from 'react-router-dom' // ou BrowserRouter +import { Route } from 'react-router' +import { MyRouteParameter } from './components' + +export default class App extends React.Component { + render() { + + + + } +} +``` +``` +// my-app/src/components/my-route-parameter.js + +import React from 'react' +import { HashRouter } from 'react-router-dom' // ou BrowserRouter +import { Route } from 'react-router' +import { MyRouteParameter } from './components' + +export default class App extends React.Component { + render() { + const { match } = this.props + Paramètre: { match.params.myParam } + } +} +``` + +--- + +### Sous routes + +``` +// my-app/src/app.js + +import React from 'react' +import { HashRouter } from 'react-router-dom' +import { Route, Switch } from 'react-router' +import { ProductPage } from './components' + +export default class App extends React.Component { + render() { + + + + + + } +} +``` +``` +// my-app/src/component/product.js + +import React from 'react' +import { Route, Switch } from 'react-router' +import ProductView from './product-view' +import ProductEdit from './product-edit' + +export default class ProductPage extends React.Component { + render() { + const { match } = this.props + return ( + + + + + ) + } +} +``` +--- + +## Et plus encore... + +- [Transitions](https://reacttraining.com/react-router/web/example/animated-transitions) +- [Liens personnalisés](https://reacttraining.com/react-router/web/example/custom-link) +- [Chemins récursifs...](https://reacttraining.com/react-router/web/example/recursive-paths) + +--- + +## État de l'application + +--- + +## Architecture Flux + +![center 100%](img/flux-simple-f8-diagram-with-client-action-1300w.png) + +--- + +## Redux + +https://redux.js.org/ + +--- + +## Flot des données + +![center 100%](./img/redux_flow.png?1) + +--- + +## `store`, `actions` et `reducers` + +### Générateurs d'actions + +```js +// actions.js + +export const ADD_PRODUCT = 'ADD_PRODUCT' + +export function addProduct (name, price) { + return {type: ADD_PRODUCT, product: {name, price}} +} + +export const REMOVE_PRODUCT = 'REMOVE_PRODUCT' + +export function removeProduct (name) { + return {type: REMOVE_PRODUCT, productName: name} +} +``` + +--- + +### "Reducer" racine + +```js +// reducer.js + +export default const rootReducer = (state, action) => { + + console.log(`Action: ${JSON.stringify(action)}`) + + switch (action.type) { + + case ADD_PRODUCT: + // L'action est de type ADD_PRODUCT + // On ajoute le produit dans la liste et + // on retourne un nouvel état modifié + return { + products: [...state.products, action.product] + } + + + case REMOVE_PRODUCT: + // L'action est de type REMOVE_PRODUCT + // On filtre la liste des produits et on + // retourne un nouvel état modifié + return { + products: state.products.filter(p => p.name !== action.productName) + } + } + + // Si l'action n'est pas gérée, on retoure l'état + // sans le modifier + return state + +} +``` + +--- + +## Création du `store` +``` +// store.js + +import { createStore } from 'redux' +import rootReducer from './reducer' + +export function configureStore(initialState = { products: [] }) { + return createStore( + rootReducer, + initialState + ) +} +``` +--- +## Tester + +``` +// store.test.js + +/* globals test, expect, jest */ +import { addProduct, removeProduct } from './actions' +import { configureStore } from './store' + +test('Ajout/suppression des produits', () => { + // On créait une instance de notre store + // avec le state par défaut + const store = configureStore() + + // On créait un "faux" subscriber + // pour vérifier que l'état du store + // à bien été modifié le nombre de fois voulu + const subscriber = jest.fn() + + // On attache notre faux subscriber + // au store + store.subscribe(subscriber) + + // On "dispatch" nos actions + store.dispatch(addProduct('pomme', 5)) + store.dispatch(addProduct('orange', 7)) + store.dispatch(removeProduct('pomme')) + + // On s'assure que notre subscriber a bien été + // appelé + expect(subscriber).toHaveBeenCalledTimes(3) + + const state = store.getState() + + // On s'assure que l'état du store correspond + // à ce qu'on attend + expect(state).toMatchObject({ + products: [ + {name: 'orange', price: 7} + ] + }) + +}) +``` + +--- + +## Actions asynchrones + +https://github.com/gaearon/redux-thunk + +```bash +npm install --save redux-thunk +``` +--- + +### Ajout du middleware au `store` + +``` +// store.js + +import { createStore, applyMiddleware } from 'redux' +import thunk from 'redux-thunk' +import rootReducer from './reducer' + +export function configureStore(initialState = { products: [] }) { + return createStore( + rootReducer, + initialState, + applyMiddleware(thunk) // On ajoute le middleware 'thunk' + ) +} +``` +--- + +## Générateur d'actions asynchrones + +``` +// actions.js + +export const SAVE_PRODUCT = 'SAVE_PRODUCT' +export const SAVE_PRODUCT_SUCCESS = 'SAVE_PRODUCT_SUCCESS' +export const SAVE_PRODUCT_FAILURE = 'SAVE_PRODUCT_FAILURE' + +export function saveProduct (product) { + return (dispatch, getState) => { + + dispatch({type: SAVE_PRODUCT, product}) + + return fetch('http://my-api/products', { + method: 'POST', + body: JSON.stringify(product) + }) + .then(res => res.json()) + .then(res => dispatch({ type: SAVE_PRODUCT_SUCCESS, product: res.data })) + .catch(error => dispatch({ type: SAVE_PRODUCT_FAILURE, error })) + } +} +``` + +--- + +## Utilisation avec React + +### Installer les dépendances +```bash +npm install --save react-redux +``` + +--- + +### Déclaration de l'usage du `store` dans l'application + +``` +// my-app/src/index.js + +import ReactDOM from 'react-dom' +import { Provider } from 'react-redux' +import App from './app' +import { configureStore } from './store' + +const store = configureStore() + +ReactDOM.render( + + + , + document.getElementById('app') +) + +``` +--- +``` +// my-app/src/app.js + +import React from 'react' +import { addProduct } from './actions' +import { connect } from 'react-redux' + +class App extends React.Component { + + componentDidMount() { + // Toutes les 2 secondes, on "dispatch" une nouvelle + // action qui va ajouter un produit dans le store + setInterval(() => { + this.props.dispatch(addProduct(`My product #${Date.now()}`, Math.random()*10|0)) + }, 2000) + } + + render() { + // On créait une liste à partir des éléments présents + // dans le tableaux de produits + const items = this.props.products.map((p, i) => { + return
  • {p.name}
  • + }) + return ( +
      + {items} +
    + ) + } + +} + +// Cette fonction permet de "sélectionner" les éléments +// qui nous intéressent dans le state et de les exposer +// en tant que "props" sur notre composant +const mapStateToProps = state => { + return { + products: state.products + } +} + +// On "emballe" notre composant dans un "higher order component" (ou H.O.C.) +// ce qui nous permet de récupérer les données à partir du store +export default connect(mapStateToProps)(App) +``` + +--- + +## Mise en application + +--- + +### Contexte + +Implémenter une application de type "catalogue" comprenant les fonctionnalités suivantes: + +- Créer/modifier/supprimer des fiches "produit" +- Trouver des produits via un système de recherche multicritères +- Un mécanisme d'authentification par mot de passe +- Un système de rôles basiques: + - Un rôle "administrateur" pouvant effectuer toutes les actions + - Un rôle "éditeur" pouvant créer/modifier/supprimer des fiches existantes + - Un rôle "consultant" permettant de lire/rechercher des fiches existantes + +--- + +### Contraintes + +Vous pouvez sélectionner n'importe quel type de produit à implémenter (album de musique, collection de pins, bestiaire de jeu de rôle...). Voici cependant les différents types d'attributs qui devront être présents sur une fiche produit: + +- Un attribut de type numérique +- Un attribut de type "liste de mots clés" +- Un attribut de type "texte libre" +- Un attribut de type "fichier" + +La partie "backend" est laissée à votre libre choix. + +--- + +# Licence + +## CC BY-NC-SA 3.0 FR + +[Creative Commons - Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 3.0 France](https://creativecommons.org/licenses/by-nc-sa/3.0/fr/) \ No newline at end of file