From 79cc152ddfa7fdd2265782732bcbfdb42b07391e Mon Sep 17 00:00:00 2001 From: sunag Date: Wed, 1 Nov 2023 03:40:27 -0300 Subject: [PATCH] ViewportNode revision (#27096) * ViewportNode revision * remove depth * Revert "remove depth" This reverts commit d20b0f7f643352eeef0fbc4cfc62ee79f49e5017. * revision shadowmap * fix screenshot --- examples/jsm/nodes/accessors/TextureNode.js | 13 +++++++++-- examples/jsm/nodes/display/ViewportNode.js | 13 +++++------ .../jsm/nodes/lighting/AnalyticLightNode.js | 21 +++++++----------- .../renderers/webgpu/nodes/WGSLNodeBuilder.js | 2 +- examples/screenshots/webgpu_depth_texture.jpg | Bin 11693 -> 11541 bytes 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/examples/jsm/nodes/accessors/TextureNode.js b/examples/jsm/nodes/accessors/TextureNode.js index bd9c1529ec6f48..ac9ebd473379c7 100644 --- a/examples/jsm/nodes/accessors/TextureNode.js +++ b/examples/jsm/nodes/accessors/TextureNode.js @@ -117,7 +117,10 @@ class TextureNode extends UniformNode { generate( builder, output ) { - const { uvNode, levelNode } = builder.getNodeProperties( this ); + const properties = builder.getNodeProperties( this ); + + let { uvNode } = properties; + const { levelNode } = properties; const compareNode = this.compareNode; const texture = this.value; @@ -128,6 +131,12 @@ class TextureNode extends UniformNode { } + if ( builder.isFlipY() && ( texture.isFramebufferTexture === true || texture.isDepthTexture === true ) ) { + + uvNode = uvNode.setY( uvNode.y.fract().oneMinus() ); + + } + const textureProperty = super.generate( builder, 'property' ); if ( output === 'sampler' ) { @@ -212,7 +221,7 @@ class TextureNode extends UniformNode { textureNode.levelNode = levelNode; return context( textureNode, { - getMIPLevelAlgorithmNode: ( textureNode, levelNode ) => levelNode + getMIPLevelAlgorithmNode: ( reqTextureNode, levelNode ) => levelNode } ); } diff --git a/examples/jsm/nodes/display/ViewportNode.js b/examples/jsm/nodes/display/ViewportNode.js index 80931752f05e55..ead56148da6cb9 100644 --- a/examples/jsm/nodes/display/ViewportNode.js +++ b/examples/jsm/nodes/display/ViewportNode.js @@ -21,7 +21,7 @@ class ViewportNode extends Node { getNodeType() { - return this.scope === ViewportNode.COORDINATE || this.scope === ViewportNode.VIEWPORT ? 'vec4' : 'vec2'; + return this.scope === ViewportNode.VIEWPORT ? 'vec4' : 'vec2'; } @@ -55,7 +55,7 @@ class ViewportNode extends Node { } - setup( builder ) { + setup( /*builder*/ ) { const scope = this.scope; @@ -73,10 +73,7 @@ class ViewportNode extends Node { } else { - const coordinateNode = vec2( new ViewportNode( ViewportNode.COORDINATE ) ); - const resolutionNode = new ViewportNode( ViewportNode.RESOLUTION ); - - output = coordinateNode.div( resolutionNode ); + output = viewportCoordinate.div( viewportResolution ); let outX = output.x; let outY = output.y; @@ -102,9 +99,9 @@ class ViewportNode extends Node { // follow webgpu standards - const resolution = viewportResolution.build( builder ); + const resolution = builder.getNodeProperties( viewportResolution ).outputNode.build( builder ); - coord = `${ builder.getType( 'vec2' ) }( ${ coord }.x, ${ resolution}.y - ${ coord }.y )`; + coord = `${ builder.getType( 'vec2' ) }( ${ coord }.x, ${ resolution }.y - ${ coord }.y )`; } diff --git a/examples/jsm/nodes/lighting/AnalyticLightNode.js b/examples/jsm/nodes/lighting/AnalyticLightNode.js index 1a18989d8a8ba6..a29250958b575a 100644 --- a/examples/jsm/nodes/lighting/AnalyticLightNode.js +++ b/examples/jsm/nodes/lighting/AnalyticLightNode.js @@ -74,25 +74,20 @@ class AnalyticLightNode extends LightingNode { .and( shadowCoord.y.lessThanEqual( 1 ) ) .and( shadowCoord.z.lessThanEqual( 1 ) ); + let coordZ = shadowCoord.z.add( bias ); if ( builder.renderer.coordinateSystem === WebGPUCoordinateSystem ) { - shadowCoord = vec3( - shadowCoord.x, - shadowCoord.y.oneMinus(), // WebGPU: Flip Y - shadowCoord.z.add( bias ).mul( 2 ).sub( 1 ) // WebGPU: Convertion [ 0, 1 ] to [ - 1, 1 ] - ); - - } else { - - shadowCoord = vec3( - shadowCoord.x, - shadowCoord.y, - shadowCoord.z.add( bias ) - ); + coordZ = coordZ.mul( 2 ).sub( 1 ); // WebGPU: Convertion [ 0, 1 ] to [ - 1, 1 ] } + shadowCoord = vec3( + shadowCoord.x, + shadowCoord.y.oneMinus(), // follow webgpu standards + coordZ + ); + const textureCompare = ( depthTexture, shadowCoord, compare ) => texture( depthTexture, shadowCoord ).compare( compare ); //const textureCompare = ( depthTexture, shadowCoord, compare ) => compare.step( texture( depthTexture, shadowCoord ) ); diff --git a/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js b/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js index da67617e230c11..d8e703572ef399 100644 --- a/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +++ b/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js @@ -484,7 +484,7 @@ ${ flowData.code } getFragCoord() { - return this.getBuiltin( 'position', 'fragCoord', 'vec4', 'fragment' ); + return this.getBuiltin( 'position', 'fragCoord', 'vec4', 'fragment' ) + '.xy'; } diff --git a/examples/screenshots/webgpu_depth_texture.jpg b/examples/screenshots/webgpu_depth_texture.jpg index 338ef4c8ac5bc517125d13f36632fe5fe639a530..835ad94e4422e3aec678a99c9512037688a90646 100644 GIT binary patch literal 11541 zcmbVy2|QHq+xLBD#*AGe`%;!no3bRkBUvIDDU~H$GDA6RP#!GM6QAM0nr`avSDpP5J`B8kjICjWU*SeVHa77Cfn%*M>Zx_-b{>};&; z>u>(PjKD-BGO<#~ls_N;Kb_Xf0XH*PM52iZHz05$L~dlQ3b_x*$nEr*xL0YPvWlwC0bM*^c7 zHhpVuY5m^T)7#fSFgP?kGCDOqGduTd{`bNn0*HT`1JD1%9%wj1Sob+)-5!K+2|kG2 zB&IELIWb5&Tl}}2sM|x`Aq(2t@-x(D2|7FpC z8uXv`thE7lA_6Cj$PKi>3Qr)NF!$mtFOrjCIT5fYk`LSa^;r+fQ@uhZG--IE{NqT? z)hxnz{tNBxA9!v%s2ouf0>8KrpDyuDCol6W8@<0X|Cqw5RjO5isR{uqzzG=ZKRgkI zt1M$pHD-S9XHBU$4k%FEbad%w= zi_0&Hr?0}dD2vq1jfyY!9HSY@4Ko3c#o7qjhtZW8s}pkN(NTBH7DkqbiE>x8pFVv< zZ+i5}^V$~4=@C?Tk^k29FP1JQPI)~JM35F>2s&~0-Jz->-xaqOnpYlf9b1-+TcPx! zVi$ItEd%?9l4(SdzA&J>RDo%PR4T0jhsp79VWpUJVgnjCX(nSypbTXKSN2^H^P`ay z(&#hFH06n_RHAFw-Uy}5z1YrLl+TtIabju!=PVB#L$oYF3PliSThx1S>0wvxRR;xq zDf}A@Jw_k59*&ellGTzhmWayq{8{K_x~c z>BW3dvyY24@k9xn3Mkjn&s#AuAW9_|9qeiwkkP5%qlh%CE6p3Q$Lt7F?kLM5rcNX0%qEKo@k5@F*A4Q*Z7<^~OVK+6@1IdQ3&n zbr2IQPMt+;zZ6B3y~8=9D&I&<{~B2gPTOtJFO!+~3uiY8RZVN(Z6B#rkE$2E8}&>3 z994m->{Dlu^y89%-O4D4{X~BCI`TW0yt3)Qq`r zDW-nS>DQbhl6Qgiz-v1z1m&}{X~bl1(g{seI?>4Fg`=4BGtrP7aEfINmI~q`dDboKjNae2Bxre3~ zh_;q2D~o?*P*i=BK0h%md^;-ccR^(i=XCAuX#X^6prW^# zK_q|q%8L})^$Pnut-8eg?m-k$WTG5rw|sI}c0z2>F2OSn(oFWUEJAm&ew42moI3@JD-xMc zcu+x?`3Rtka=3q@6K%@P$xGGdPRF-M&2SZdiCGLp#h$Il4>HZ}{MR(j(q{>f}_i^ahdY)BZCTmsV3EDSeUg$hY4uJ-I2p zZ0_z4D>oH%oMzhM{U8f4ZT2b`5w9FZ2Kkd*np3=f9WNZ*W_Mmyi$+HRHH?A5tqun1 z3%d|#nd~aMoNkjb@Fbc2^37CHziX&iww)jO!CBF{myRkl`JsiYbb`e{;Y8Y0pq6v6 zUDVF*p)O2L_!`RRwGdG{CZ8qEyjk216*l{wcOalRU+uH;ICQYlhwR*;bC1ry6m#1{ zB~a{=i74TNM7XQ+tRk4ZYeESFsV%4P+Q(|tKV_5kU7}Hp9iDtY#VsVK_amZq0OiXf z%G9WOo*MDL;(Q027+Ka>1L@0DVz_%XkjDf%jREVAknQd$@7%%gm%xt|Jn~J;fzBr@ zG-GPw!REq0W#^P^=G;RWOL1|_Aw#HW=la^Ey#G>jl}Z?hi1^k&=5p@*^!p(e5rdOa z49evZ2*|Vm5A*u)+6&-VWgU21N(4&UIz&mC^J z(zBvJfQnijsa7{ql&9zmnwv%I0#!`CZ~w|Y^&Pf4W4;9qGh99B7MD%#9X}vZ4 zGwL+TgWrC7QTrSFo*xkmY1k3fYuB=@#R^{k>u&!$;?t(2Gu!fu90ci+Q?)~jG|Ddc zP5QYuhfkUOcU{eHR1!L=M7@@Z=%}P=+rNI)mcv<2D7$ZYZa}EbY$k50a7a7?*q5FU z$pA|0^NWl{Gl7eX+hX#w*vq`#XU7+9F&;}J{;yI(L9S6E>@%sY^EfA8Z%4YC_KsAp z46t8Ylul529&<|B`ZNf6XOx!Vf?dIa( zZzMivzXtffw#?w1i*OQFH-6?`1B_EPA8EwHB@#WQG^<_}VL5LT0Mh z*)wrcDeY@iBc`PIGxXK5ujk(cj@PM+{IvPV4%6gomy0fb%*FXBQaWE^UQh{!|9~9- z4cM7Ur^Bx`34#8C6qWq3=5Vf`zj$x1X*YX}lAUSr{5;MYOxU9ftZr4zSbyKuA&-4z;eMOhj8Qx3^S|sD ze&vGI&GK5RAXq=DM-fSXILv?Plhkc?cjAYAX0teF3b&-Ti1T$*jB*AQ@ZVD+-TRV) z?JH`*SM!nJde0b?BeJ~f&~sgG*>Q}L1NPOZvRkmb-S1k6kW(>EEEgDhmW^||*Ybi2 zL_iTV+`x98)J~8WtAwzI3H2p2h;-tYQl4zh%%0&><{eW!JZV;5D{`oqAIf}~tPA$} z`7#J08r8t!>t4T=?HBS-SmnEPa0dHD&LSN?cGZQ8(<`YLPvoMX%6;5Bq9$>Uu)m$V z<(}#DB9}Ppnw*i>Nx=I*wNQ?;MxBehb%NfLLo2iJb;fAjahzuV#T>byltQ9>(c zY0YW~MAL+l{Dd~gAp7n0mw6Gf&t@nm&SW(d1`0Ay)CG7w--?co4^xR*2Tm~bZvE{m zHk2iA--XtFzI{m$aj3-PDMRsbP5l$^#B+ed27L=~?{KlD(QvNK#Dky?@1LmPsXfgB zg$0f&2zL!Zj|=~~5Qhr<*h5FcQ>p=BpIttui6QusW?a&k_T!RUe2km5NpS->&__`O zjq-9RJJpXyv73BjGVAwVX{AN)(^c&?zzX_*i93P)A&r>inLW9!n>teJg0c zS78?zrke^z{onSWf)F^FZgCv`Y2wyAy<9TD)v1Vl8A(bON*1%fvS(@7WHW?xaPprB z^^U(r5|YAPicJ!)ww$_;$;mD&WTBp%(l*DsVLmv%q_n)p>?~CVpZ=_fIDM{cnWyX) zk1uOG{PvCo=y?A8nn_4q@WrK%zIiyy@PEuBQL@_mdT-?p>D(2cqBH893tx@8j5CIy5O66`t@ zTqx5+b2wYfZ==eX+;5E!Bv7L5nD#de)nY6#mHVvwaP1o6jONYhPG%m z*!3@3E-8OM!5eTsOaj*nc1SDF)ONGrOqNUglzF0RqlQo(Vyf=HzWP6iJW(b{EzyES z?^q27@JPCzoWQ?}^dP;vFKZ5GS1XjQD#`&zFKVcT0XtdWFmT7@tL$F2s=WODpCwQG za(RxUq92Qr^aJw~e+0_@ey_Xq$uDn~7kNLnDp}GZyZTMhDe$!V^ldt`qF2u8LBa*Z4e~ChR zEHeGZM-dDtD->umUSD_drDCYFkXJ!FtGL-KzQ zMt9bi995=Wr4ucto7LLS7RI|(PHRK}_uL5K#8!_?GPX&z7u%O_?b^o1R8-=~9vm2$ zN+s?WJ#JF0X7|c!ai91nZ0DbnN&nKtP03r&nJ^%2uYA>%`ReK?pC4+hAoNh@6v`uo zPj=8qzvj&>mF!&AvWMx!!_5KqDDQKD42jN`u*jL%} zvO|HbXsTk$KqKqyDW!tZvh)k2$;ZPMunt~ zv%>vX<8jX1rM}{(=%(A#ZgivxhN&Yaeb@l!yi?Bo&iSJ3OTVq}dym9SeUO`7Y~UZYyCUx$IabJlvgZ7q@7 zFw@Defv1W<#sVa9_F_^vTatI4yZt-CTeY1BM`m%3R++HgEsC;&C*UY#bM5j2Gvg;! zxy(jTk(F=#cj5#c&Zm}p5im)diPacrVlv@!p(-M01#y-wce|sF1pEE-k!QS56rHzw zoq-A9AC!X4Z@;=+6exWiTt^%@(?p}FWdC*=tPam+txvgh-)k|l2}$kaMR;H_`Khdk zo*1oZHAyGLUn7dmB5d%V;d8Lu4#Om6WE7E|cXr8qZN!8)_2>v4vW93cUPPT+@dY!( z<1iEOQc4(ec749>lWLmT7`l-L5E%j{MI`b9aIhR_p@`5(9=R46x84_YW4ZEH=nwKw z!4XtQb?c*Dg7@QN!{u?9TgQAuU%QJO_+iR`yj7Q?g0rL_>kzF$HMo4i_u}Fr7rCU) zquEw2#7A_Zj4gwFnyfl!r**_DGW5{3apN7(jTM~w&Zl``CpD-+9ckH?Q9!k)O&w=9nf|v9=R$i zMVorQc~$}wmaZ<<8au1I1}W~lzjzVz8NII;UYsqku6^>1GCPLy zI!vBQ9Z#HaFdcTI6Oe8LBmWsw>8qp@kf)^OUQs$jNqKPCx_se&9Ptuk4d^T|C|fQ$ zyE|{YG03NHcEemi0^70Y9nKv3t{Uk1^g_z%;e}JO>TniNR}GAW_|79~hTyI92JA|w z2@DzjoC`wgQXxCW;LGDf114hmV6IJ-Mqm(bNMK@|D!d@>{dB$k75lkz;sTARI!Pta z>x0`PwfhG#esy~x-~bM~wnks2BNO`|3ySgB9|oesMQ9+mp4oh}*n?(FEYS%>N2@Ui zWD?Y5PM&&apWA4kSM!Y*XufqbsUsl69&}`KEZ5{`Iw{~~HLwZl-4VLndQb9g0kE~P zF8KB?PDZdI$_eD`{HUp`WrlLo2#+qgqdcNV2EVXsZ#z<%Ok>)5yYrS@oyI{$WLHkd zuZBU(`g*@^m;|YNKXl7mTYkT@OeJ&(%^Fu%>B2eE1=crug@gYhrHAC<6vn^lJf_W8 zG#)v}oG-&%Yd>rj--C0?RB3`Yjq}FHjKpV7ipjIgg+WZE{nkm`<;7O65p+|h->Mg2 zuqg8)n*{`L%KctUrl=t4d}5yzS7~cEtgmPJMnGR2EXm`+O755d?v-ehy&$4gnzK=PEC<3#jgXLnWA7g@H4h zFXG_f%M3t`PK^iSzXc&HJ*c9%zFv62oOM1TW%hyGC*0=&@8<3D*aF+37VFDE1f-u+ z3AA)NA;00SKxz#pIRjykepG$}XX#PC;>#fZ)rj#4-*ibfV!v)Mt3fATIMfuosxHF9 z|C73Ei|zUY?*EZS?SH?lBI@L|bADAX;lB2X;tey>s=4fUyX3hBa6F-l-_>jyXWd@h z%?fE*ks^{|cV9uG<1fAgXKtI$C;BdNc`ne%foBFnxd}CIFY>ytffh|j)`IL?_i@G} ze0^gm>$6q{DHJ*k<_ZqB8=`8E2StuEo@V*D#)FQ&44|oEsO*7v4^hg1iAHDsvscXF zcH&-z0T$qN?3N}5LGfOsIVOyp@Uk2$YBKqNsJGyC@VCkk}s~Hcb-Rp2x z&$Q&FBoK+o6liS`9HtY#1^;?({q&9wRiW4pI@WS2W!vPh!`(yi4tQ$W6tJ0#A3zuBN&;HgYE(ZvKhJZ4Z9hUcm*xGTF zKmVTB(vc5RPCY7Zm77z)!}#7Nb=j&;lF!!TAWj0Q@rdYObzBV{aFOQDjH9eiIe>-@ zjPNI?muTeF*i|ns*V>8X9AH>~bX)@42*H7hnEj*?hY8jBwh~e?+P@UR_-YU)5+Wt; z3u58t_Bmm|sc@nRQAfPtRCtIa0WbAcUN9o;#2{&0hS+XkFADPs$8g({{uy)wjl>9- zX~rnf0R@ao;uyLiE)ZTK&#`(JXR(?I1Lu?lak8ssJ|dm5oUo5g^|mzU{ya$Ub}3XP zs0MPYOh44Bs13Rr0qFl)mZVGP&6~}SXmjV0yn8YAdhOaqOv1f}PDseimcGAWps+>6 zcNb9MN%I9SS*B}6XiUK+?(bA!8rbqCQu^bq1+jd@uy?ZKU~w|Spb>SryD%{>cXT6x zO9$oD`>`%p)?FI2Fkf2x3He-HJ6IVWMSabfo?}^g)c> z+ZT;ZWfKRaH; z5EJD|Y=?PYe(GaXTq`RGf(mtiVi34=NfFfX-WbFrijBVveN6(7SG3k~_3(?!VO;*R z;I$Dal~7jo=Hzs(1<19Za{@=>uibV6os3e`y~UP(ji)q$>#$Z9&Usr@T3hP8;0gN; zFeCo$KV)#R?AE!q@a98udGEy!*G}W?W9_$J7M)8zD}q4v;9hacfTvVMtcfC0`a)N{ zE81@cWo>C5`*L%U6*xO_>T#p<4M2bJj>=BY3Fv`^KeQ6MPanFGlao%+RS%*PO%4c~ z_G^5Cd=TSi?7^9nluk7POvx997QiW#@^`$TTe}|u2&bOPJDidYAIk50F_M4?gXwi* z_l)KH9?$78aJ?n3n?ay%ry?_-ruR!;=uyF0fAovkVj}C*;f3e5ag@DHVZ9LbUKuNR z1*5eMJW=-(cxKm#ZNVve?UrLG&l7Nc2}*P?3{KwsEH#62ClIr7CUe1FY*%{_RG);} zWJ{EiuiPa6KKQ9?3{uJ1u0giq;O1$vS;wE@5-^p&#OODAktglxyEjyoU$U{OT!3wb zhGi4arKZADm7Z6Pft|r$8GugFSio5}g^r+H<`Yx`>Y;#cBz9raCS@?X^bLUz#F$u3 zD8m&V2|dm2(ti=MlIH$MNPllBYe21RBe^e97f>Sv&I&BjkbbV8LO^{zQ3}ujGg?l@ z_?^YV0=5HRoh?Hyz{JIQ(BSdmgUSR<*15StI5>u%wJtESDj){sr4sDVXD!m0e&?rq z+Da|G5IdR%tL*fh^5ugnv>;Wu>I4OFW|0jY3;>C|h@LLk5)laJq>*_HWj+DH?^J0R zIG=ZuUv!Daq_2}K#ymVfXUSJ;@9*dq@%VX8L=ag(m|Tq)-XEOZkYrtQ(bZw6+gYRLZkXUc|9cz1UHN z6%?;8UR{~VByd-iM#_^TU|UI%@gTj{7nYy1f9R|)q&(^4sF1I89RHHlt?8(e)S+ff z)``#Ps;jLOdGx8D5U5CKrb|r^?te&QO3^Y&7(H}*`?V+B%UQ(p0N)-ClzBnjI9@D} zw5N3h<*t3yT3g?~Z4LOP4M7RIjB1$XREV-h-9<-Xo)p4FB3c>5c^Iftg@w-F4*(An zD=!E;eCbY$S84>`Yc#rTz#v`IENDyYHIzr?SJmmHD}7qZu;h7&BHV(Kzuat!8r~H@FEi1 zY9Np6lfg9ek?oIE8Ki93>7yf~5Z{PjUW->?vTg65i81!*TY$uks*s($e2=r4ioR#Y zS&p8z#iXH^fq@F7JPWTb;T*fv(94Vu-i8ECT~Yr>*j7#9p@GuA)si(ZH%#!eW^Lw5 zGM5+krwpL{C^!w14%jTl{9kp4!kj4Ujv&XvihUP@UFtrO@&&#a9 zcnsbSVwQm-ScD!iJ1}Lv8hzmKAx6MwB@NAxB3M?xHTw4SqL1bm2U)ZyK75mAFpZM7 z?ABPCqWATrZZAFDRewId-#=s)=Tf`7=)_Bvg#@(=1s?=DhWg(_b?z{< z4F2H1mu-ZE?5FQC{eN&w$IK%mP`@xrF<u~afjRiQ? z9}dY-kJ8*2%C=snBYPv}np50lpAJ&{iYGLnUiI?k=8?a&0C- zto;&K4W^!Jj#G5yjxZ~0gyJ053RRc*s-!>Jn|Qv*IkIxQ%Wi!tir({clnP|;W1yS? z8j1=45;%gguIHGeuCN7u#^nnEzJyVibKm)R(ow%H+rQ*}(5t-GhV7l$Yt1@XJI+Rb zbFS}04YTG$Se{0IJkg&7TNg>n^U07IG3Z5W;9SU$Y3?_2wXYaVqw7v&U(u=JYYwgk zGg6{%K2WK5=x}~@``sEiMf26Kg-_UymE5safAQ5tMMO$9XPG20krr9~LQ4`AQqq*} zIB+R%#oh+0wMwswP6Q7+wE8OfGMKh4>#&LzPTrY^h3pRFUZZNWLTZh#8|)~`Ka5HF z7^|}L@Ije4l$lwBisbrKg9Ej@P(rp{AS(1b|0+?=GAmYw^&>?_W06e5+}4+ZcZL;Eo+2}->ai#ED&O%;0@yz%o$ z5qlcbYirq2zq4<+SI0H{R;WlmqH(?5!dmKkxA?u0E=+Y@MHWBRY<;4&tx&EiQY#u~ z_x)Eu$EqZP@Y)M!MxYKr;(6N;*oH~qED~05HOO+h2ZjM`T~@e4jHMICgKrLeaFIOY z5Cwj*!=Sh)l^m@`BavWT%HspMz?(CDnZ6)sb z)CnIjfLTS)3X;Af#u&egbnC+44K7A?=?68=pMwRb!KQxAI^lf zK&18WYC9HgRcbHUFUkF`)`~`)&w)~a>NZv-I`K(ksm`OW{ksO*iAY4aTPD=Sg!-Q< zlp1zl_drC3pw^oUwYkT6(ofSJRkljk!FpE1V*ZDc@g6O?1v5zG5@lrK8h|RbKS`U{ z@MK~)f(maj$T}1Q@kDkHEZd_? zV`}I~i$duA1umIKR6>j`9f|a#5$S{z_6BFp*((DElkn@I64yji294?L>CRz-j5>p8 zgrID^ukATt+0>`xf7(ADVTW1&#v||XWjf(n894Cya}GG`WPdj@;1!h+{I(gBF#ka( z9B{3{r1Zv79zEDS^absc9fL=jpLQU{XQ5U-tu&}S(uN6tjX}B0Vv<0DdNTCEstDt3 zb8a(<$@b9Y7rtCmiU{NPjU{6~=LaVbgiDsQtLjIY_<|w(h?wWPfEg}ERZJ{I0+ZHL zhK$}dXXh;;_5@`}>eQI+HdH)+c7R6dK?PQKq;c>PpYIHaUd>0sOAC#mYE;0XW^$?I zm4}T$#8LYt$fHWs?Oe5*zN>jIAENwbkgpED)O@gY$JMd`Av&Dtd#?fJ5Csbty3sFRNp{_hbP1aK9`KHR5LMsXslBW*8f-H~Jq-93LbMP44u_YZ^b_UZDMQaZ zZvO5Q2XM-1kLrc3=Mxj(iv2Z)2~}siFxhj>7z2`od*Tj?C8dl!TqhxH4&J zkpY;Ylmy%hvJm^PyU!HyJAN;HG~5kq{$`w+ihNmwHC2!=Y{-A{xpctqij8%yu=s18 z_6`QQ8hEDeO4TZQ{N#qjW&t9jAEq|%_#*RV1(YRu76*`;kg$13L;4*dIMRX{#PafW z*-IH_$4wn2FmDxg;>>l#9I&^4!GsqfCPOYk2RQ3|><{Y)**NQ=);<0&lj?Lj)YzT?TBvo|P|(Ygz*wz{^{X`Sek- zyPAX8&P*#B>1H#gG%L=Lej zBJ!`V8Q}OD2;OHTKHU|tGy*A;>`8i(%eBkVmK>E2RO-Yb_b);P-bhYue#vphcHz#0 z;#IB-&mh}5*V%9TsVdgvpavbGB1e;_P_7yuC>fDpk3Yr$Mm?a``VV44aF@@n5hY2} zR~r;Iygn!e_s7Waf}}UMx8B`;u@VAKZT>MaL(gSa*` zNXC`xTMZN8em_MTLFSMcOLLWd2@NrDI(e@pi((-9*&!n zs~Mtf8@99JGR{V@@kF^!!l0bEtztAB`NMyba5c&TjOXM$ieGTs|0&?rt+WAD$XtxC zSvIP{WnkOtHlNy_X4u$x#@0GgWh6I~LD`b%rWu4O4*#nir%=`Q`Ip197^458>GT?S z0U3X+R9viwF^rnWPls3`lkU+SxVIIP-L(d8XS_+3BzgrFA?;shAUYhu#JNE~gLsPv zWj27F{N|V^qDp=Kh+a>P8r-(_D~G9UHSyD@Jv_cznSwayv04?JR98bq>dJBQr-#dH zAO)BwK`9@2LM?o5tHDkqPG;)|UD%#vD5gZTKgY=oV!Do0;MHN`VYcjDHBC!z;=!Hh z+N)xd{_g7nF)C=LH&rNVAep5IDq#Z^XH814$n0C85;b*TKT5)Jf=-b4tizcz3EJiT zG}xm7_&JvuzG~4+Xhh`vUjtJVW{NQ)I7N3|m$)n|_RnjV^6k)LF9399f}3Fyn`60-~*c;JFM+irDD&0{7b2uXQk02;By%; z8+(V7f+X05Wz|$({UCm!QitYXq~iKj!3du2|lw17|oc* zx(E-s<{!dNc$2dRHa|&QoDWzbF(_P+M_<%rKPF_h$23l^uJ#lYI6mcEl42+8J^ra< zDhbs5x$Njt6JonTE}2H+PxD__I`rq^Ry&mciu%p1k8etlnJj}8U;#SUdgl5Rui@L$ zGt*g6Z*n6&M8ZJ!<(5?<)GpVBJ|<(!727qq*@ag;vkzs5zrCw^4T!Dtd3LFxXTBhz rDLIu+a02yZ$4;gk1xPn5`1oyg6!vbDpbsRQ;A#7x4TNi8?fd@%+vPR= literal 11693 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 H%bouLsh3>v