?45bodQHAgD_-BJ3S=+0=cqxyPg0Olpnb1A%L?g$R^~(B6``;)KBpSyt
zD<4YhxMD9==GfjLDX_3*?^_HLM&+#cjjI!TblYYX
zFiIaU_$zsWe3fZ`js1w}X2mqsLz2kQY9j!&S=c>AdYvpf&hK4+I(XB?pl?*%!~m}l
zjQfT*Lk!y359PY`tJ(pU@>4`}7|xX;86c<^b;%i`sP-D>(LCmH<_9rH6F()H*EbNvaP9o0FeNQHY}HBK
zx!?s55wGdA^1KdE0`a>lluHkk3yjFI!wNY5xP{1@dR*!VL4uLmg)
z0=vU(*bN&2!jA>udAaajO4*>9bmhFyM#an1he8uKQ-N4ka22(hFpJc9yK+0)?ycp|
zWu>$R7p`zgqupc(@L_o!ga#IZEkn25in*4az|#*`JIR|o;zdr;8`wTM`XOklzxTR_
z+<8za{Iv)j-z30{3uxDR?4OFLuw=7LzEAyWXs{6-VF4Wumx=}oOxzQUFyUb=
zJnJ1KqROydSn6=xT9TRVCv9&kuX{mwbO^2(TUCR_C@bOGkY+06zj?J6nvKMReGE0v
zs@6>2QZpLL`d+X1m+eHC72b+Ur~`G?N9Gca%{w|azr1fBU#DpNxcHEX4WRAZCr2g0
zP(3n%@YX+8j|cfy=wpj^)rg-Upzh|626h^s)P-xFU@$?k&?r?0bQ}Y4IkOzVl>j4ZU0{z-7P8
zoRDRm?#npc-s4+&pW)eMaQ|1u7vsN5s`;L!N}&=G8o=$=PzN^Zy;;1Sr4aH@
ze~5RJgB^&)B~3~+!->?q5lFR0$2Jc>sqHKZYq{Cd1{38Bps<8IOIa^){`$)!#CaB;
zlp*G5e)v*ps4gQt9!lF9Km4VkF^!wqdDhg(C!my^~LyA{jd*Vxx&mJZ;FHUjcL$6yEdv+7qZ|^mQrkaQ9ma
ziw<5(CAK6i-RC7wGCoU}13_;;8DS=%6InHQ@E7sc1D;^sxt>nch
z1Z%rOfkCV(C><+m)wDXv-ZNLHT>W~&Ikw6$k|XRV>tej%I*UMm4Ski_wqYR>!Mw$3
zBs4E5oy-lpv2j(+4?yRuO9=eTH@xV+H+9pGjKL5GW)?iLr*ef#M;51pFh1s9a(YBB
zi$1`6ZsXXoD4Smjd~;2%4NRjxP_|_`e^<9@Q2gn);~{jvqkcZ7pW6kbNgX2XN`uq^
zV{IKh<9_sJ!dNdD+_V!Q@CifzrS^(Bk|@VT5u*M1U5MEqUK{ovDOXT>m>zkd&Jsi~
zEo--P-LZ2kc(-A_Te`EeG3ZU2WV$`M6!&$8ilvUNd+0>Gp
zRUG1P%!c;quMG48r{^9y5PE_Gu70r|!%U0V7mB+|G%S5KdU=L1sr;BPU-9j`q$de9
zJS|m6EWZT!EBi9o2gGS?AGje~92%tbo;06CHtRC9%1Tx`$OD%H
zlaK>;y2fvE=u&xwdYu@Y=lRfFCQUFc`=8jV>!(t;wMnrgGOflH)A1^F(ypEm`0zgRW=&u4$fCIi9P=C
zs?S7U>Zo7dPlpMY0;aW6pEQ@i=8vBhYZK6q!CHqs1%Hmf(w72Fy6A0XLeIlZd{}`f
zzSyEwqKz&jx7xO4qoVG;aTLDMFe)3X{)fVnQe_K5TNR>0R*^nke63!TQ|do7VeFRl
z%sKt9R4o~yZMCT&wSX{EBF{h^yRS*51@2Y1T{DGvz9|-w02{XKkieP~@?MP_TT=Y;
z4_s&t*%OBT-wczDl(m^g&nE2gd*94zBVIJ-=?LA%r>G^5t2CUWYR;nBx{+tjpd2!hQ$Q+YxVa
zxHl&@?Gb(B^%oyoz3F{O;%;Ul5fn?cbx=CFl3{e?Oq*X2!f@L-6tORrwiiaYt4@&u
zah6_szQY&%J&-pnT72Fq@U`W>-4f;1N~lvSdUuc3(EBWJ!}4Fe!NlM!b}O~vOwf<3
z{K7wG)`oSMh1Ea{DT9Bah&tU
zYz1z>;vG=((gZk-peMSp
zsEiYoNvnQRzu^1XyZpsT45KiLe|`XUi&!UYnClAVN@7N)Qfw*wgUAm})()Ggp}RM7
z>M?TVF%-+Y+q^j!IE#P%6q*F9({2IomszpFQ!uOj!_e~}v
zsJ2FuD(#1;m7ewp%?-^j7??GhyysA|EFd=JaqkNu>TFF7#I#%RXK!vV9Jm6E6y48U
z1LjCvY0Rk_Cc|s9E!8pIAD~663@6d$)bL|W#YaAL`!srkaRJ1gdXi7aRD&g@qLmg%
zJV=C*mxMXCKIx*(6?3(-s0t7lpV?iYx6%cJp+U)lWKZhGT|7
zInLZS=lqAr^%QzIh9tEB!X|)o{1&~#4vJ5&+LSdiWRDy7nRQ`~0uTAjcp@b`67tq8
zEC)x*fq2gf5UJsu2eMYNRGx=hJf&4JZg5?uyx4Rpv}
z-0dcPz?N9T(rkwHCCiq?*D|z5HUoh8PXLiwTd2?+q)wkUXvEX!M`cO`zD6d#SlXs~
zcYjF2AZI^@L}$)hzr~y0Iw)}KR)vl-;ET1M;gS-Q8q}D&`02=stYB%`4{XYQsu_@4
z{(~{J5f<)~U`h&~Hs@Ob2M@??p)cNka!4-65kx~+M(oGVCVNLN6v6`M@jFA+-+4Q<
z#9v*gflX?mFGe7A-gMeLW{09L*XYMSl0ZI-8UUaeM#DdbD9tfTU{fZ&@59qTut~xp
zVg~BR-Fg{enNyO`{7*8UVr3Sn{<^ySYLoD=L>I_;P+=+_UW8Fa;$?&(H5er^p!|}I=I+IdP4vlH%&cKx4wQr(iWvZ`1kLE#P_zNs3PpSnpaVFe-5Gbd}X{to-2<8u_l>=tcgMA+#U!u_T>(%FhOW*NmEHupyzfg>`j#KhqVpP
zc2WkTCNBi3dkulwaV8R1rx!*DIgg%Wf}9)DRb0DiNCy_I$eJ3qhi-I|#^$$vG1Jrb3m-
z74ggPn`!`M1^Fl(2ZXQ)ZgfpU4N)f(fi6ETWQQ0M&rIYSheUF+aob{`@?l#rijfva
z^9|!WD=mRNwgyvJvEORxWf&$(f4r|ddrO@#e)sOnGA1pC7DMwb9fg%r*zj*--KJZ_
zo`XN|?K~c}UT*3@3x?~p57V!_+;CyO)_y5-F+Ki9Prl$(1R>a+(nWKIE^o4Y0|N1QTYQsH3UpJx
zU*Gh-@lkBJ4Lrr1*jLMf*-B8|LrAtsz
zsBZnqW;9aKk68p)ON)hM^HX&b7?Ga|l?4C6Ez%RhkWE)nQUi2?#kfdrbBeX>T%4{stV<9vG!JmXx5S9@7
zApHc`ib>hAAa$H52@~i{4TP;K5hxmpmi%x`#V=34e{{fXyzBHe@_#w0j}hSDp0Fio
z=9o2J1NBvVWB2Td7li`tL8L@6L|weyq&jR%jx;>G>6_u17$B5X2e8BGW_8u8zV;V*
z3p@2_--J+r9eA}!zKD5q^lD?Z_rQ2r?I|HCM2?01qh^_LCa>Y%Q-HxwgMq
z5RP(Pwk_VXw!MLKwY_r#UkqCGdl-))}Dw6slc}+XRi8rMR^xI>yANBeS#L-P#OQ&4MsSeAn0-s
zTE1I02@TG4@vJ{2i%>!h2ojRLkcbTM>}BDDjON5rqE7BP#IC?HZ)xQ8dLT!#5CPS`NR9t@2;qpm-%V%_D|Gl)FLe08)?>?ohI1Va>}}o
zTj9%i
z>`d36>+O1s3LMa`UT6MJg{E7tI|4RSlE#=eW;yUt^C8Be7{+z7Zjo4GH?;IPD7>su
z&Td!~9WE4_J!AXTg07|wqB(;g2+#PNEeohW18MqhE}Ewn>(IhYAI$^j>frCwuV^NH
z4&N%ZYAiOLp8%}_G3t@Q$ASU=s25Npx0IldMQyb%7tohe+b;a{OuuU6_a?919@&iqk%+=NZXvDf!S52m*kL-*01D%FN@MWzwy2OyNc_>3e3uBook?aU$mGEgwK#iYg!SNw%F47&;OUXwgl
zV_A0J``-E-mZ`lJZ24SJ*lLqFUivKtc4CaQzppg0l(^uBoShp%g1-QWx#Guoue+0m
zR)_>}IHa$?HA2f>r2Q1iKx_Ne-^ksr5D4xkOZ$BbkXIK9wU@vuR11AL`>aq-Mv8hv
zqaym4{g4a=5%YoYF-0q_hA0XxPF$VYkKD!YK0FqeQ4wW!6cN;;F1kupJPdI{0g_*u
zVJz^LK(F+?rS&={5NZ@af3<~mHT+w&$AeNS#IsC99q4%xej$}{f6aq^Q={qKY>PDY
zpcfE>vBm%Bt{)8$D_Jyho%S~Nz%HUl7bEvvssORNA1>OSpM}62{#Y^ru&8D>u%$xBUSA2
zl$_N>qslga#z=+8&pER+6%_4`Mcd)kP&jZs?#w0&|Gs?`>zwQgKe4A}1R*Mnn|jg>
z?3AeZGj$s`4_QL$qL$M5J3#}Sh6t5y-$KnrrwLIUH0
z{gI9?B(DFESxOvH%#P~G^JS8~iSYd}dHHe7IKoeG@(EuC#+GOtoUrYO8oXTv_>_->
zop?qXNdpxY8b(u`Z@xn%>rEt6mOeI;eH5qs9Q@W3GSBc^?f78148OxNv&awr9(yC!O
zPuH9Q3Zb}Vc3%N@-(~9FtIM-yL-lPav14DgN(#5?yO|izU1@Ki?N;zNd&ck^NC7^%
z5l=eVpk8x9D5^2Tw~TV>dftm6_64e6`J^1QU$``(ba<^INF0tUra;c%X#BE*{TpXE
zd8x1p?ZY82pGCZ4*iHeW6C$gH_G;-T>G@t_kTx#?BsjgHqT%M8S**5&1x6RAsJb5!-4@~?Vz&DQiQzYNono02
z8iRwgMNnl_T;xt*ZDT8~3X3bXvSA81f->d+7`1rLNtKuHQYgq*#@wHjOrp_-H
z7DQl|^H0L4LL@r~&31~S4W7U3uvH^uPK*^wD*mjL(DPA5sVDqa=dIWfK?Rou3DYjlZqogr+yv@{T^qY
zTyTdK!V<{F08$|l7b|IdLbJcbjzASv_zs@8rSV5K1k3#)Tow1Mm`u1a*I+=4encl_
z#kc!I0OghEpO?u2pF_F3Ybm*toI!LWp**e
zt+cUR{P|FU!_f5A`|Y2kzRIDvd+_d{%m@9m9!j6v9|xyhiX()O3tlWg22@5_;TwBi
z#)PchE;2hmrn+Cs7F9v9bXgLbP+>%LxjN)o`d<)_r#3|#G935Dfu_DQL*xNNlD
z+I8_NVQa9k6)LQPNSgpCfbo8QDSG$Cf6qf&7~6-`x#|z~v>_?1xg9K{V0vY3uyz
zs`bI~r$~XJcJFhe0Yw_`4peCU_dgr
zVrW+fK+F|`S3WL2=HB(UaGlT(wg#a(WhaB1>tEkQHK=qE^gkA@-HzKZ>|+g<2nayI
zxbNq^e{0c(xYPk+rsDuNlUgy1^TIh!ed&)uydzR1&nyi4ZyAQKj)Aq&YC+FuhaOr6
zqC-wmYGv_W&;!;lYpILt<13HT3l%32Pmq4KE!@kEDM_2XDV2lkh+l*o^4{BWo)9@jeuBR49q91~>
zf=kW`<*HXk=}cv55Vo%fS~$oZ$SMB{Q8=Ks#_94&4deZZwwlT)0w#(Y`XgX(km9
z@ast;GyJZGcs~m;ew_!iXw-e>I7V=8UIO=hn)N#NWGVE&v`Aj&!edMl=e01K3lTV1mwz3(1*w8^*c->%*tKM4;SNpQI8S2`*9GJ1`VgYfIeCCsjd
zYK221k;@{D55f8Wi?DBwkEH9?O(x02wrzWoOl(hV+qNgRZQGvMHYfJP#)N%4?|05U
z-?`^^@9jUjYp<%URcm)WYwz0Y38cAXIzohZ3qsGY{}4yI6xI<1u;r&)SR+dId#Mdj
z1S7G?{J0f27i5(*J&C6d^jfIuuZtY;hn83REA84EZv2pY(j&(S@@sh`{eU8QpZX&sDp%f%Wn}X1{C{CZsKsFXhlb|`N6&(G0QRcbB*yucWwn0V#
zDSFR!H$pC{lyzA@{yqPdE;?she#^x9t64$y2Pe1qBRS5t@On97OC2GB(+Dn~R1FQ4
zCV}?tSMS~xI$n)G**AGiU)!$&*Y)3JO15YGpsZ=pO8_o;6XY`>R*WR~=m)jC`wcJK
ziQmaW-I}X=<@UMwm3=JqX%I6n*u0^ay^t5n;IY%=Lz!UKn%VqJuCk$w)PB@V24Eg)
zG0R|b2*q#fqS^gfg3YN(#<9%<5RV4p5YbVtb9FpGH7x>m5DTDl=eT5G2;b@J!sYX-
z?{c78Jd_sggh)YFtN4XqH}*6X#N^n&w1Ecsw~{MSK+IPnwdV;UvFg9%!eW7rnraDn
zlBtx!Vr6|xVsb31JoQ7r`@MF6NHpTOD#MooV7&=>t)z!2)wF`uh3FyWDT6}sWxt!x
zk)<89r$qL!bc4&o=G^8lq^bcT(b@{jojx>P;LFxvDYV_~rCsc@kfmtw4?Xt;4b{NC
zzZ)QCR(Pvo%Ch=*86*BSkI3j>Ewy1J3HveW>UAsT}ruf~OKi0IeYyg`pPkftqAm8>6eR_&Zv>
zF#Q7)Up~uco*UAtnqUK)ya8ny2GU3Nc+M~LBHaC88HS*h4WsECwIy7Q%GX&i{mX|4
zA73lZ-Y;KaQ3WwYF5q8m#LqzT5mYfygxp-saqbW*jv8fq!bO7-C
z$);7`wAMYaKZ=0+%ik$^i2&+)=mTr8Bv>!Hg7{g;ieI`5_1EcqJ&3_4jAk-NIVqiM
zcN{cqI~jHQVR5eLveRZ}=gY1Tb9asVflubZ*lq&YY;iK`cx3D0Z>k@fJPZ|p$OXnQ
zKsMV^H^Cx3^dG>^;6{1u9=!38w_|S5g#J%&Nb1!;ttIdMU9I6Z>5zpH;=N{cgX(5?
z6*S@ph%&HhD*%LRbRz=!9<|i(^3qMSfL_i0B=3rFMcZ~^C^(%;iWMOrUgKZ%a9t|j
zTa^otG&=t-3P2=n%>Q8VoR#^BQKY}At+(;|$GV104r{^hMqBP@=rs}2*427P8Z>xc
zptcgA(nL1ZFhqQZK}ZSj*4-%h1@KjnBY&jY1*`{yAb)MBOxdQa{u
zk6Vj(7cnOc_w7(@F+k+P!QtIb&YmrKqTcaRw8KqPxE%1`Jt!+;#RrJK_N4aZp1&Z4m+YSQypjM&FA!EGQTwRRrp%I%#Ez
z*crFJv`}qtXYsNwv|ejDNWMRPEcix08}KJoxOk2d_fqx~mRymmM=pfnQ!Rv?B0~SF
zAGs9_7K4tkmO4Yjh_oSR7e!};+1?~F`}P!C2pOta5@~hjr;rc}d?%+?=W>z|Gvmc>
zRO$J`0YHUE{+l29{a+j`KZ>aSPk
zkNO_Ld4K0BOyA4jRfh4`oucE5er}7V#SGmt0Hv4F=DK+c5yW6J1B7P*BvqIk!bS22
zy*TZCcgBQOyf~fmGm@U4rep*oDIP<`mmk8{*s;nf<6&Z(7ghkeZA
zX!icC7$`Nxx%uD>)c|5L+F{pebeG++9)ub|Dh=AeooDh_`d4{fKOSz~@<5SsJPisN
z9}WA?b!9pfFOcY5e@ewpzL3ghSrY^ncLd6>6BQJP|*7(>eP;B*teWQXxqdk=5
z9_kW6`N3B&kP`i^Sm)!t0y`I-zZw~(f_6i|hNt~ldn@Dr`|wvFMJ*=c&GBBOyK1?t
zW)%{}H*V6eJp7zq1p_a{H~CcMyjj5-#s{VXrJjd9i%R$S%RAkLWx`BA>Z~G
z244g8NmMTRRS-+2cX<=|D)+DQJ#ld0$*=F(Wr(|GJ23vVr+zMj+HY$sDhAl~+yXRP
zWGzdm%Lg)(UR$uDikQKqKY~WiGeah2dOP`v;(FcAxa_Bg5bA
z0A8w{N6mT+Gb5cE)#{dQcNcv7az$c>q3cW5B}UeYq|_ZuHf@UwBsSQE3yL49knIgc
zIhTrQt4a*)89y5see6^%SI6($wy=*}5O8r4`}S$FkH2(ICC
zY)W?4UaCmA(nEibkJ?!=?Rv;g4CT6GZy{=>adg8mfQEWQ;hNwJ+-icIkM1LK2Hio{
z$@J&v^mGSszVQ*xsr~sr>Bx~dz%!6T?T1|njmI+1#Pi|)OH-9fx$$pH`0aP=Bi|<0
z8Zzm_ShrVL-P`0v8&PGHD~Gaq&p|#=dYMiqHP8Iaf_;0PcSI6=)e`-T^EDp8Nn6MV
zWeOx4JEw)OJxY$9%B2wSbrYZ@sV(65X+r0J&mWq^U3sCt|@cXtf7=n{eX
zH80xBeh|%!v~`F0er0K^`UriO_GO*v=m>o42>IY2=5D_+-?@%T;&9UPc7oINJb>|F
z7e-qeoxx`2Rx)_W4ap(efQxN|Tw%!K_j^Y^chUv=KW#Z5g|2{hEXEqVIV9{|0lgEo
zRpbH@W83@)sTo4*5jKer15fCM6Bmi+ecZj1osa{D<2d_-HI6u;D{J7c>vJf
z&aEt=Oxv=-sm=Ns>FFCGcbKe^Kt+=G62`?u;xO-d^g%(Y&IF(Maqq(H2Ou}-Zb8o;
z-fx3QWty$=|5EMN7VOrTV)^^0q8a>Dtr27Me2Ye|g=(LQsMA2QFJPFmoDsdg%nyWX
zt+ISGZq8u5qU7zx4sWx?bL)Un9D#t#_a(!Jv+vZV
z@1W^c5PWed$@qXT$p7)@L!2nJ-x*npiRiGvLr0#@*%ijovhtuuC2()r4YW^2616Ik
zd|i(;eRhu=-sExZS?{9hlRPp|8SK$$cOLDhV+Zf-*ftc|PF>-eMVcpW`6F-b@
zV=gSTMh%9)DU~NZz5%zH!H)2pXEl3iCh0Phg~W(TZ3GGPjc5Wvzn{TQBvyqxmbG~9
zEHkQgWSL}Y3AFj@-R>I3gtuyRR@s%E*)1q@za>z4q$)Z5`WW#6;X%#{@r@wOG<}wn
zlOw@v28#>ZFt#b9@~*W^`!G}dNhOwLSaoLX4WcazICKSA)FFAXUf^>}ufj^&qFw*g
z8&%dT#U+0v^o@W+$)_9>7J%|YEpFQ9ttw*L+UoIE1gI{JCsW1o%t``%pjZj5cgr+s
zdOeAK>-X6AtYZTR?pym)i|4d09jN}^%3f{=4X>I+gmN9I1pplmiXA+SQK<8|Hs*p~
z7g$L=M(0djE9rX>K>$jJ8+sDU@(Ozx25x4Aw_tV?uI!N7A5}D=1mhuxv;xA-Z*I;j
z<70t5%HohlOK}l9*;Q}_Yw^xP)5BvgfLr|jdd2t&1grJzgxjf`mww_*D3@3cLHi}eoC4Wf5nEo+-Vi~bN3v@CYYvN_azYzvtFN+@cd
zuVOC}3Dh;7&Am-gzJqe>UJX4pABDN6G=8xgaZ3y=5O||+EjL
z=!UQ$^FesogV{pCXd?QVjx`q=4QaLVHqd#j*caPW8O|}BX7*H@%irR=Mu}f}v}}*X
zlw*GfAZPIiJlj)#?;(Q;{kkJNLf4+L75q$oz*X&|^~=!eO5_fz*K^1G=Lvu48-hD<
z6^1_*-O4;5H))$PNuoW>OO_ZqXvt6`7*3Gv>%9n_
zO1w!pN^W9(JZISHah3aC6BDJFINvWP*E>dG9_24Zm7#UXRSYRCQGI!G~da0
zmy}+OR+i<-p0wJJC#=#kNR!hQyIfT~`PYy=O8`&@_j+oguO>=oR3|fY#rOO__P2#$
zh8Y~AIoakvko;W;uKhFk4`AzwzyN1bL>u7LeKTwaKUOR+B->p6&Ttt)cCI(LruR!h
zf_VyU1GJV7ZGK?^w{tX(JCS<&l{~a_o~4pqSd<-7Gc7ota1D!S?oPKr2(ZGizW-VH
zi!hmBm=HSA)SG<2eVuuW8{B}LN4-j>v?k!?+UT_7`KZlU~l@Q#W5#j)?
zHcI9X+aXq(lex=X0-!p0&{LDa4d&;XAI=`mIZYg!^{ri|?iD15rsys61gdfHKyZfCD`*|?O&+q}+Y&G>r?JLg~E|}iMK^FY7YkDw#
zVcvi?cvXN_vC)x5$b~(shsSK|LU-rAcaBZE?BylV16o;1=lWmM
zkFj;mz=&YT0uOpC=U9_OcxN#B{&Xt~emVkvvK*jtU!Fc1%Ov>4_p=d;0uiB)sqC1`
z(Hn}M7*1_wj45ZT+h`K~T+WI4w020oDFWyjhZTKgl#WBbL;&K6F!R%9@zE%8XSONJ
zJ>w%l{Y_j-ELnhk1jYmK(M1ni;-tx;Zcyo;9jt|WOj$BAr6-YG^ewk=}PP&nd&)IX@6Q*N#IJ*xLm#$_>~~P
zXlcmAOd%HRv9nn^Si6wWVJbv!A*LvN&w>>P;aO~F#Ma7iGR-;?#AcZbFL1Z-a+=ar
z0O=|6+zC#0GwsAw4cZ3E`_ZiZD!U%Vb_iAh6TQ$qq$@5^tw_gyQmMSxeA!%fZ*pxf
z9aX@!k7tbUr7d6Myc^IY@7fo6q(`_0Ufj_fC>3N|Ebow<$5b;Q4!TgLt4qU34avP&
zgq7)WdC*6W0Rs-ri-gYuNPKa_MX$FY-08*e&8lStvD#PFy^{U25_1-R3gN$PGc5Rl
zi+m23*M$Bt<%RLDB8@VsOF*kyL>fJD18Ma_lIv^-ci|H;$hbDNmb`rrZErATEHLs0
z$5+@kWLp;8@bq3WSCN10ZIJlQd4d9*VI6+$=oo7ihW8a_tXy~J)WMN)a96Zx&9LFQ
zYo6;ZA`x<|CFeW8x8$;8Og!QL!UBvUbYALJan!jyD$5R4>1^;WKbLwLs#m51UiUq#
z!tr_bbyMl|XGq4CjB3Lx5=jRGrWS!tL$RsHbjzKXB0PTLk0m26xw+!aUGr){yptwc
zaYj6{@gu4b@;O|&2HA#O}4x6rg#;f;kyL{&o|{NLITVC{zQE7%e6o#2hp
zdnaj*BA18dpNq`Spy;9HJa9hfb=;C=Ur^Fb-xGqi1D7A{8ZQEVa@9WUGKlI@G1LIc5sUilFwqzy$+O-Q6gkv%
z{th-u;TUwbx776G9CiWp&;(M?Yc=?C^xAEwJtz3RvuQJXDGGf9kRd33EsvIZx1N=v;)m*zW=6{?EJdqS+P@akp39Cpj|3l9(y%BAeVm%Y=F0PuBKP&36BqF|0vA
zs52|ev4o1@HVa^bc~tlQ%eSa8g5zRpq4feA7GkMq(*f?3%)I%VzpxpmRXDpQV#9L-
zMW(MtGkc8nR!Hi!)k;~GW7k)gT`%-5KOb;(T>8YAv--{M&A&xO3JvPP&63Qx=Q`p&
zbvyaextbH>fhJcz^DfNW5zWJB9{EJiabvpn6up2u?4EkolHK>B&(lP4iKz(*_(z;4
z1W@|5vQt1$fuDpOKYW3wQE4y7-hAp}9CoY@K6hCDxZ_IvW9r?@0p^?@RqTOA_W3EL_NY@DC*6r1a
z6`~$_ksHcz(Q0YyG~s6Z(TJd(f`isHZR>IX4-Wg!3=wFiI~4e@%zyY*td+5uWAgDm
zxAS&pJ9m*GV9*)#s(u87U3cd933khAX3f4rK>V4;)Xme+pErR)r$dToq*IFlu^A9M
zeiy#QC|m7(4HXuL|G4(6uEdxo#7V+09u~bu7)__8^Aj1z{L$h(j)|1>0`a%qZU+el
z>&>y`jSp7E_EByd5iSZO}q8Bl`
zt5}>#5iZTo*oN^o*By-Igei9R5EJI;FK*zi7z3)&mSYs>r7jG~z|e(QIl(g5xv1(_
z{TRUf$h!0w>=ophNU2(Pi2nq;y$k~e!jyOu%vfHdQdQKlB`-EVpqc1aAF=!Z{igx+
z<<#^<(%0m)R;X`RL^IpY5fm=QxO*gQAKsr0*e!`lT#P+S>+LB=i<%dzzeGP;MlMT^
zHF)eTa8Tv>C%7v8Nb&suw@86;O(VFJv5)7~oV5Qy-h+`Yejs#(e%NaDMeD#nff9?2
z8!s3Z
zp=R+d{`Gk&>5gg)n0ibjtmrOFa4wIMd8}uu0JgAC0Oej$il1UU$TvvrNcw|}G**(h
zoff!2Zl0$S7GNzX!z|nVPYB;O{^X(*z|8oe*vu25MCc^Hu~=R$nNPk;B9ZcYrY1R-
z@=tc=m*;&*x66$-hqLKy;1=gW0Vfge$R+ESna>`uO_5Wq&P5wXruIO_5uYVhISl?d
zp#`80S6E%)yx4WO8$Fuo;4W1uw;0z81@{lYqS0t~D!0=#XFg%^n%!}Yk)xRjrQIid
z-niePZe-xD*hE7L>4mo}P4pAR@_s_M{cR~icT?Gwz$d;I<;O?9nM*qOgkW*z(~IGw
zo>#11Cu;i6;@7*?%SF7W&(7PMaPL7p@=-Zjt7u^VvUWS6rAr?l`P(8#J46-^&XHEMBwCq>*g*);aTbq
zqjqGD6K)NangG>J#|X!C_P~rn=;6I?H>hA=zR5a#cJqFT=?6T<^8oIrUPp()c}2!Y
zOs*eWjiLP4RoYTdF%1~CDZW3ah99H^a91&YtY6=mU5x*&@bo`rI-pVMF#<69Y1BWA
zE}5|f;%5)?{`l+@lj8H&VuIm@om(Sv5vpziz#1X*ibknnY{lWS`O4eaxbILW9D|dP
zTrDRS9A9nM^H|oVTe-DIlJlKCWX=?%LnrxLvi?d8L_xuroE$w
z@WPG--N1)|FEE1~{p;GqY7Az0-T{;i7d7|l?N_}F6=CW?t8!+3quW-5yaY=I)bN*q
ztWDd`?zDYx4&rltb&5wrT#r;HI-Bg=v(oBB(Q9pvxTom^tXL+3;MiTJ@pd|G_S=k}q~-64J|`2hN~
zZMz14Jt7Wc<~>RxFuhH17+6
zkif@^Rp(s!QyI3^qfYb@FOiXlS!?v?=(H88R%s>OPn-%zq@dwKz_fBQd!?F-u4+Wk8x
zij0M=6_CP&hz%G%-_8-pyh5bK1kA&v1H-5YWKSW|;$$J>WM^Vv`^L%jjfjPXorsh3
z^Q0irC+*8W@%sghoGt8ZfkY`pj4FzfFrQyUROZgk_Dw*BzgHS1{bdXYU}@tQiX+!o$J2^?bp_bC2NKE&DEQWbpWvvRivy_*O%iz
z>>C4_uH1Ex1`kjCh7gxa*zhZ6>ykpH_>!Os-pIgjD2`E`#}@1`4|
z?e!^p!r|}9z1|1$`N0ff&)Nmxb^+1ts=Htl5zwCapgn*9V)3-_sPh56ALGYdH
z0$fA445E?~-j?g^2}2-8W8$a>JwS6GVaEbWabPEDx!`GMYGJ66#uVTocE8ge-oK(V`A*RYeJ&sSBRY{R*a?Q`lv3Ot*MtLCmS{(
z?nuZ#QjGZxm7ETd?3n57LYrLS+@lA@u&8bXLp#V5A#UVjbcUH*$QL`%;
zFEqHrq^zX0EH+l0(}6b3anR#Q(3qUOYjeUp3{0n=T}(5LHfSBcAee+vtz;2i2pHMs
zF@L@tITkGHGl?*U4uKK6^c#$_l7clt7-h!qga+?P83gOeVD9OP|0JCY5*58irDKWj
zveZ1toUwyQtj~qXshEN2U!PSm
zQ4I6%`RWH(L>lB@4R4al(UYPq-i+J5GItYO^rQ*(0StRDF
zpRoWhSuX$#|co!-%L3
zjB2l+bKFW8EsE=E_k%$ph6hyj1VZv@TEy7oAJ0V05y%Q7TJMp=K?v}w*{PRwrkkeQ
zL$O6IaEqx;{#bRj*Tv@-rF|3!-{2v~o3U`#DPCqN8UuYY@y$?w8OSjt8wPbySFeWh
z$Ux4iHD>;`&ynO#hVP5ZN+bTsfR&v|Yk#ddSqv+trk7lklHyp0@mTyIQvsL%>@Vis
zLl(W7wS+_&(ad=5>h&uw4*Oz4rQYVXdeVc>f*s}CX5?wUv8I4-@6amsmCsaMXye|p
zkq+w*XruM4F3@JP1$aX=$gSmGp((Jc2XDx&Q@p{j0}^AgG&R}d_4M+)FRcy4n+R!3
zvF3$~awzTt*cHsIoCsQ--&rCK-nKO1=402OAi4iQYa@X6)tN4-wYEX!x5+@0o@Uy~
zT`w)xot(nSkUXfAxA_qK=AI}*!ntlXk;ifmP5T+If94T`W2zGF94M%&8t#$eTUM`A
zx*%b`h>q_%>A)hI!dSK93$p}DUWj2IS(OIU6GSGt@uA9#*&zt69D7eJ{f)s&s#(j&
zP9iI#fkLMhX_;H$9!$K_b}r?koO`|E;P{>?G>|h(SbWVmt*`>B@eK3j1bmSSiQG&4
zyt)=vK~+VNp%%AtPHwZZN21(N2tU1US5(dp?(A3rWT{{g_1?avRTDh?09%L@s`+@1
z(=3H0s4(*&(o=nChbSm7cQlsri*r)ZP|H13DZ{Dcoy{pWt_wn3MJMvqpA_=8xVeP{
z55gT}gvRbH>d_iHXST`|&tnm2grTq%nibEA(`vB6eF(7k9yU4E$f9!%&hz$tcwyCu
zy5YKqAg>OS*c^q}jjV*?jHn7>apY?BfR?aE6}*K)W(q;;rBU`j4W4n9B5OapW7dqh
z)A7;UDW=Pgy(98?z%lw`_q~ywFN_#yTTKe~dtU4aMuDq9ncMT*rOcQdles
zVmH~Ywn(3(B!gQP5NK?xgybh2b^}teRn(p@46Mq`yRf&jcE8>2OsoR=7
zG0|tx^hwlO6cQ>kY!~w~9>R*>3Ni+doPfiR)~bJWy7y-f7Ra8%zqrMfVHQ0i9AVg2
z>b60To;l!IL!J57y>Cocq65MeNHdyP84T8|at1jSj#Bt?o-lfA<22ajH#q9L)k2|?
z=uayl7Jc4WE@gogiVTnO?9^q@t>GB2fq%JCiHf-4qnb!h>Qu!$j-qAgzkb
zvToL0-@7Li@-}LRrXQkzzi_k_Z}as6lwv1v7_V<`8qo=FMEfWqL?hET7jA@x1N
zXoqrc=}w)EAmi>FyE5xFCaq4o8W&N%{HVJ1zUx;z5GE~ZP1beVQ0t`9vQy*gDZYv`kWy>A{d?mM+QGuSWyBrOO1WB5KC6ybxu<@$L6xq$
zL>dY#F>Q
zrchJgH*sYtW>Zx$Dkj^uF65N5`Wpe=u^otXF4G{IDwC}=y7FPHuS#Kh%qz`Xz3q3K
zE9En_lSMhn$jNU&egh;QH>FgpMhDX*IR52@=yQ9db>vA+v%6A1pV$4@r>o1J*XN$?
zkN1aHzC)AfCsj{RQK0uG8Vf$SAxEXsFv$h@ld;X=>4OU)8y6*5eo
zHQuWW^Z}|=SQg#1m5LjSE=tRoWon{Av_DpDjsW?q!^hGN$G+^YVCD%w{bw-5J!<~n
zE_FC_^?TM5%F5bpQKl7%l4gGiMOe#U&S3oIJO6;^i0s3HBZbhW4?`+(m(;P#ulW68
znkZFEOCq?i77fEW5T?+F2s3SIekoA3ib2P63$>n3>6#kx)PyLELQz%2h-#WRue>U9
zRjWddDB{yGC~(1@?93Xj*_d5M$n%S|`>UKZv1B#O(lXtF>{SkDuG6GGcgm9^V+jY1
z3zB#T&S%cEy9kV$HqU9qCzpJJzA1jk!!DE@*DO?YW?;_vm=f;F*WeNB`$~yu%l!4I
zP#J!!EuNSO)u;KF1vhHT)0o|zOP$koC{`l*^Z0W-*XdM4xHMkTYku~~KW1oY|4;D}T*
zjU26?$1lLu@c}~`>|r{(`Y)?IQ_#S<*jr)rb1~V^y$RVUIQzvBk6&O(`E>nKT@kxn
zTtWHe=|bB%hE0Ur$QB`Wk>0)g)N$T5XOo{a?A#xzzvoDJ(Hgvs!JzlU`IquEBKhz2
zngxaKjOZ=%KgZGfT^g0e)s_dRSo6p2#n+O-THPxA-gUYRLbv?4qHlJ-J+JYp2asN0
zhXm1l0Vc0HyL5xbw;lYYn+yCNueDbnh(B^SWdElJ!t!6J{$K9GkAFxQ6@l@ZT^x-}
zoId>sATOkmk_ph+_=ggbQQ5@ZnTYWpwnm}<_!a(-UrC_rA?ofduH+2lTKvo^&Pw!2
z52*-rBmR@|@l&kMLG(!o`Hxu44#?98l!>tsv3<&b?hZQ<`@hb9W|K8BwlEN~bN`p;
z!_LJ)^o@<>)5ZC8m7IvQK7A-fU|JYh4v_NEiRjZ&0hXfV?C4_T{KLTUA0ZQv-twPA
zBIZvA>a*tmAUyjg{ofeRK2_lKS)dEBWk5blX$xauJ)fFV)cLo3|4y*^kEbPU;A~)R
zXZBeWuz>$r(ZA{XU;LBIL~Kl)9RDARN=`1efA^=R)cjA{`%;VD-+j*a+Lwe}YEV}br%da3BdHtzp5xf50*t}!VueSjE*H$#CU05I>vW_K
z?pQvM(aIXS1$*o-#eGkJA06JgIclY#9YhSGI43_AHn*OPF~a~3B&m`TaZTn%HI*XFsadxm4>)pe~v
z`l-gJ<$I)b{h4wbAMw&hmiGK77#}S!C#}IIGfMZ#(zd6xmb)+mMs>psF(rw`BduSl
zd)H(Vw$4;22eZ0Jd?VOt`EcfCrPQ)o9?zKjxhsE>wt|gOra-Aoq-m@yEccHdsWb}v
zrd1oHa09i4aUUdaM65#I?f997ymHV)7c;uEsu+;}9>CfVTG1{U?B|X%S<6az850bA
z@6$Ns$^J{aD^Y6y^uvs4JRy%WkCR0RW8~E&ChA+GuEt95Ix*&JVJN4+9>#z*e0%zz
zmkn`oo#NPIkmoW!RYYNY=_XV!x#Kp48k5*+F^iWZkud|SQE~TuHVxB0{lpMA4u1uF
z|2b}uLRk%o{qR3E
zITSZhIVk0pUEo{nUX~+mXmYrX4*iboj!NQz?r?ALZg;;#IcJ?w`n1MfvO?;Ep?bc1
z^r$-b2MZD(67y`wz#zN^E|0*W9-4p)s{
z_H48aR>P05X4e?FHBoh6&usEH%aLaO>kss~EefyXXoTvH8VqgMY50dHDInlkw@D`Ba4$#hP36+E)}^3Q0!j`N$I*#(F7Di%WXpefZsa=nx%F_?dV3
z`)F7*iZ81dC>Yvc>$W($FR9lEJPfa#>7Ik-9Ay4{Lb=Cm!g{f%P2a>rT{Qc;Hj5X&
zo@c!}uSqPFDVNH|&4kU#Y>04V$KXB$b}U5spchu>LAecjTILfq?@b?r$IJ__f;}w4
z;SJj?NKP2c!EAtP@DM?9XJQE96jNwY7vtAqsJd=oalJ6$+U2~DcPezCoPS7dXpsZz
z=Aj5?ERl_Eny@z{7G0IC84kakE5k~%UjId2^4E-QT#4$0xGIe9MIIH=b+03-Wxa(40;+V_&WEE%
z9WugsZtzRPw&xHc2Ur#i93~A@7r9%ce4?KaQ|Wh|!Xq2Y2L~7sIN8}7z8?)HY8*>Q
z>fa&M6%61cSF9Cvs2j(m4XnUlt+$%MUS7#u-~qxAk-8r+XGV7+p55-gx6+d{kPdK>
z##3r7^m@W5$xtkJ7(NAxitZ8sDoQuw??c|SdscR@U!3l6=SeS1f%}s$Pfss@^!y?ODHgT5B||&DM*cn&?>W*UnK=%qhZs&ccsa^32|
zcL>kPNo9?5$swPm?T;DrusPS#7{wn8(0v4P2HPyMk{967uuMnAC<`RNCi9we(=Wxj
zz42wwfrn46Csy&kA@(w%Xpl$o@?rz9k>!lCZn_1|?2-oS*FrvqL`IN!y#;LU?(JP)
z`d8wRQuFf4!mR2HeyjKtLIuC#Uh+?w8I7wr)WaCY(%2|n)9)R)
zEypN`XM&mJXhW8KKCyZl+KSC9n#rvOeOt-XtlO8DTkGwZ;ox=0&359{2_AY1&9;H8
z?2j^DT8j|+rT8rH0gtWW1fHvn1n$ivne@v#O#^jxlv|RYhhaNdw~eDvFta}@!vs+%
zmhaBDc>eZmm=U-zFTkiM)duW?|N39?s#G2N?s4`
zp?ra*A*smupAd%m-w3Gxg<(D+g@}ohk)wsZvz;UG`3g+S8Q1`cqXqx@(8>Y@P9~0y
z2F~)r
zr~eNq@(Fycck6$1YYR(?d|vsfp3nA6iYVKO
zONz)E*aLx^F|dyo&Om}zpjgSn3D`|ZTT{DFNTz6FW&vb}^&p}W1TuY_P{T0Ff6hT$
z*qRYh{bx3yP|3yK-r58>ckE2W^oiKiKB1Zx`!`M^P7V$oB3596la*D6h>e{{i-VI{
zhv*ydfR*K&4p1W;KoJug@QC>v5Xv!q%7B{E`o{Jt<6!&D`Kcr(B2HFzpoH_Y2-eT5
zfH+W#^BeGph2^t+HV$AB9IQG({feml(~SRwcb`!5KXm&4p0{TGcbKIUKVdn*ge3a(
z5}{ENxg)+`1Yrc_`bGC%aMRbHK3YkT9#%u+?-lI~7A8&H4%3sA8moeaTJs!1fg9)e
zSKj+Is?Y^@HUfikoXM{E^~q^eTU>_-;YYC5RpI2Rx7v*po&bFlc8Qn4&SC#GZC9xiPGA;2vw16h*&TgQJH!;oSCq02^sHj
z%1>nzu-u#Hv$4;t$G_Oqd}OTGObh*=Bk})YzW>__Kg|y~K>q)BD{2d*Y5z2{|81T0
z68||KjSYaq2WZPcNDkzt{}=XGwo|dS_+)km4zy3vzoGPhBcA_H(9O)o_Bo3GU)I3R
z!u;Qf;k7)JwN)|zmtM_vLB)9(%LNfIXhnJUrBS&lZ-%oa_Mk>q(b;
zb%}>vFkhz=?bdVIeUUl+ntKiwb_xpRTW)6bCj@GWAHVN0vyQhElJ>3efTw;V;Bbid
zy>Oqjzd#%`0Um@n^W|#?H&`yhhnq2a;EL>f_P%g~m^<{V5jGrH_B-x^3;Y!b)hsuI
zp}D=WvNu*kU6+3gBD@{msltXYYzn4<#xo4Eorl~bE8Q1lQ7BLtY38N?6h=SITdD7)
zDT9#I@`TXh*F6}ARCmc_ZzXOHs
zBIx^z-n4vCB4Iceqd5B4fEl6Ys4uv?M
z49y9D&Y*_UbMj7t;HbC=&52TQdQdcuRYOwMa7%8DSx57~x(wbb0xhHlb
z^cm~`bdr!X*5Kp22f>}%SY=v|_}0i9=`HdRLt-zAq*}pxJ*QMw^@ARs|EceUN0kfrv2)(>zj%vRUTYR)|x=N%NMaJ*`F?u7d{F
zWva~=>_LsQal`Anwf8i+oi}S(ln`XDKb~EwZ+?kkvB{G?be29PjEsK~q
ztOP+}QWQ=axg$AjSyQAObFLjx!2@p2J-I;OkrW29xE&27Hi2p90-as94)`vyJ>mK3
z86Lg>cuPR1bMgSl*#vF|-0TmXU*jMqZ8}&)mF4*vr?BR!SvR}(UC&cgw5G|2jpGd(
zCIk~KEi9t0r7pfZJqG%9gr1!6ZmxYV-BX*{vjIF3giUpwIfp8At&N@L`c?p@gN7S|
z=}Q;Lgi`1`)_7xZrft^E`XYaUHnRxZ5QWauJaCetEnjz0Nh^0`D*H$Ku4g?I
zW-LSWz@`s;v;Kg!afsb)L1yN|Y8sGkb>u^yS=Nt$Y>C&|VwI!jF4%8~S#L+YJ46e>
zTH*FFH`RhR%Z3(5c}H_h;_zu?vKQc;h3NC7d|%#q6X!~o_-fvt
z5$*m|ZN$q5zo*-Ve3N&mn8X%A`Zc}y>pkNkXT+PhKDIHDOCj2t5p9)t>opH
z8&Td=-BU8_aJejrzqgw2Ar)7013nBey7olv7}EIC0%KlD66{sVhAH2z`|cNWMZEq{
z$~}UWC*fuQF>c;~nw&S$HcO=KeZl(Qo?O9LZ87;fulN`VXH$+bmbeU``D(S`E#vzk
znS_yP;h{$J0rdH_w;XCug^yswUre$v=_L0!I)$_)3H$+HeP;h67Vx0SOWvPxo#gEm
zgeI{nwaG^)mAp^IzXKqerMJWPnyFB5U`$RL#7#p~!5f@2$9re|gFHLCBX|FHX
zzQZsa_5@J1Y3M({bnr$hW4`Z0w(A8iq
z(mqm?Z9gvY4ay7HMz;X|bVqw$D#a}2$d7~rOog;ys{%x_nOEPOTH6Yas9lL%jZPC!
zzPv}u)py)lX3V%UlkEltzg|YFW+0Q?`?qBuzddg?(h<&~ZPKr~`Dy_8iC5%M=o{%9
zm!o>rz0y1k#5Q)(CX;Wun+Yds>A53%Xlkt(-)^zMf8<7#b`@pC8D|S>A?z=V?0Jn+
zihQTZ5jlrQl9K*ocI*=K;>ee1I+I-f5?mGG&ow;%+j%XJfkc>{FHoM5nemtr_s8T*
zc2?hhXDde7z+r<-)gkT`jm6@L2VI!4%}9Do&hJ?KY7$28@n^bq(knG~B5pXRl
z)Hch_vk%-c>0BwN@a679b{hZcE>`POkQ=Zkskt{T({(Ni#o=`p>rhx*)KJkR2
zB3YFn*_p%2w8cAiIno(As5H;p#bSwA=Oq#018r6tRm-&2x2
zZu;8EdVMTMhmC1UkzbH1MedzIe9O{mk0^*bG@{^(Ad0?z;u|{lR8!qgV`)SPX)2m=FWxA;kTx
zug#Mmc@yWU%VsA3sd}KpOR?=$?#HURfvJ(++VQ(dZEkQ_j*4xlKLT8o#G#5Dd{F
z8l;RcPms>V{BS+m3&<%f0Ft;PjSUfidsHHyAZ2B>!On$|oWhpT&;BJ@Fa0LbKRGzJ
znv0?@Vxmlrr7}$Bs9;WU(T}>3Bk2XviuStuvb)viD
zsO#FHBxR$r*r=_85>k(rs#js)+a)_*X+a0W?aaL8B24gDN^vnFMI$-wNJh3fiv};^
z0GZDjf|XZHMJMZ@QXWR{g?e9~Q1>E>htm?qHeM^u+tUP+1U0m#YDPNO)ks+B2?9n?&E7WmWmTzx3
z5K;Vlf8Tj@C_wTNtXwfw~4>daHmo!^@QnD^K)C`wS#l`I}Xv@?1
z&CNXA)db4pR3t;0I?~@q{SQvOevA-ltJunS=-4!rS1H-Hz@v(;%OZ@(+T>zK=UQK0
zZNG)buP3$^msn1)BtmTiqqbY0GUX3pAJ1tw5k;TonzvXqkACqenyCKG#idlELN)t^
zD_NM%#Vx}K)%SqPip^}%*?G})HDvu(T#00X!xW7(jn$H8&5G4g94)1&b0~dyba|(>1CTsP|D()1NWmRjtzaoaGWrpHFF|
zL;K>`l$$KB*WZ?%owObz0osXr3fi+32r6#TAw3G+-}#1da_j1~{$jTOj!)6fv7VBY
zny5E1GsWDsK1X46+}|*O`d`JJc{o)28^F0mAxX5@Cs`uP%$ePqt*e`qY!ep|vS%xX
zr1#*o{wd-|H2*G1Y$TSs(V?2ke>
zg!0%3%j~w}8XD&&C#b)>R)NcS>RWxCD{C=HGxwzwY2ssaMqyzF-K9OCVX{j#iCw8Q
zBzc=S{Utr$X8OU=@-fBq1d^5Y)dUp@AGhslyIy%UHF(xFdet>}X5GzIL(!t1w9|d|
z*W{Swcv1Ik=@s@%jIAP@-Y9ygK}9q%H;^RXKZCIC>z~RiU1@S};(5lGa(-s-aALG9
zimtOD9z=*UP8x_mY$aD(WG-3%n}e@j+G2S_9nXQZs---_GDK}|OV>4>kGVCQnY`|)
z^XV=*osnHKR?8}re7tTh9}aj+i5oo8pv5MVhXThe@A=;`O#Gtr-g}UngtNUWSILl@PR|tS^d6IA6b1LAf`XywY_Dg#&AVjSv?chB
zD}?58qwwotJBA}NUR1Vy`1B%G>4@jaM@hqFNw^V;?Fa=oc2?L{*>hh1SfK6k0S!Ul
z7O6O5R!PZOd9~z8!dpq{w#Lb1?Usu#&$09`wssz{PFO>1O&DsUGU$VPqE_zWeC(wql`#qz$-CyO#V7
zvsc9)zb6Rv@-Xi>hNsSt8Qchs_*p$;@EK`zl%(&zZS+<@q;M^SG^Z!hY?YtWkl)U3
zuU~M!;#qc6bEiPGl=FZ`zlzkBi18SzZ~NwEm1AwAg_O);DPm4wyBpl=fh9#=)WUMB
zoQj>DPp9)`WQQWYL4<$zZUGUM)X59UJ?qUQ@vpOOM8zrbrO$mxuZN7>Ad%^b{uqmg
zujQExJ};_X=RnWKlzvBKU#ypUbzbDGb%!SMFp@5do_l6Sk9}iJjz6cSy}N6(^j`MB
zUW228Uy3(bM_E1Vnj*XGuW`;w;jhQG%sJZXDIOhkCBBaIAS;cY@G$jMg7wEAXGPms
zDOdU(ixbhVnN0FEFN@GURqT<@oZ0fS47P(Tc}=VOjN`f|5}^?$(@xq4Dk8#Xtl6NR
zPW3dN#h_I(n%&cauKHh|wkje2ZksO{NO`>rCrRxfG?Vv=cpQt*VQu(dE7Zd_!K@ra}6|3udXpo`oOi
zi#j=*o^;s6U{dqDs94!&;`xZI8mShkmEE+S9scl;Xo`r^P8XL2I`)N>SuDf5D3WvXJAs_FkGvNJl}|^sXwI
zgL+zN&YzKeKaD<@elNUy4Aii`U2e5iA}*6;?_`rg{`8wh)90hc*U&o6#(B{@<7W5v+&(lp;kIGXsg#ag
zs%|k5HXvHDNrtS-t}>jez5jVN{er74V%cMOI@gFqbeOkBK_7n>gzY$Z(ID_)ihkN;
zP=Q+O&xRiaZJr)F`N`*3iIQCm`BU{T%c01k{Y-R-xv#l#agrb@EL~EhczyuY^_GyQ
zu+fEm$>{lSnmE={p4ZgFBX1RM&$n9<+=_;~z2;67FZ<1~qDomiAD@z9-U(5NGWwK-
zdhxtep(w(e5XS!LM&9pf)`vbtJ`U=B&gu<+F3jT_oe&rJC2hOGWr0g{3o~Im1NwOF
z5jL8yDNrrd?opspO{<iPQy5^5uP9U~<+VJcLEg4X9R+=@}_
zYb^~n&o~4aSuSfuX*NCSU20ae-`F_?Uh!DE=6JOw^=fVI5SzAHKm57vsc9k+Rul%M6v^pI1NSXdVKuhXRw+B-&qENK^y)_A@M=Mxrdw^x!l%%>eJZ)df9
zY*%tXV?{Uu${n}z{k=PQaV%?pxHr$%1U0S&^#%n~o7JgQ1oqFg^?!pJ`m3M@NZgE*&>m67zPJMBB2$14u|2)
z24R3zBnp5P2+PTy!(kXWr;vs7`C}gj;1u9AM~K04hGBte3of&)gwG0jm%!2!rY
zA%J-lhr*zcKnn#2`Y6IN&`F1v~;v0Vs&$Hds0ijRjvESP0mQ0rrqMFcS_iHd{2DvmXa6aNLE!
zfnN=R{^1P_;9))AfuQ&XpWATJ$Qi8&N~%$W`cV-jeY&y>!W+%h;^I~`^5DWd$5CYh
z&QKG1`7)bzD9czKzmwTQZDobCO-+lf`J-B<=ZmOwtdIs%He?zX>$QCzy(w(olWO?z
zppK4DZl&~{Dao;!%QfK(Ebo&-Y>N$3bxYB7Yb*h4x{dvrsu7~oM`5(tj}=4G47|i>
zr}dX!RrTJE!em;S(D`>VZ(bHP&qW1?t0e7n;zloOz3rw=zdqSkvp1BLo-$^;JQ$Z6
zxy-hVEN&}b{va74AoGeSJ9))WkZc&mEp|wt{t`{Jcqfe~TNV;;-{g{Eu-`(?P-$I;
zYtE&d2b9fd{tFvbjpI#s+%!?V$!kcI)zeKqt1o9M?9QvaM?QP4UW|f}{>57Hwc*z#
z`PPhImyD8<6`Hw_1h)0ptfgaM`bxp+R8!
zK@W>tb*zv$I0#!m=;1H`VSkea`a1$>@6QjoxVd|X3+EK6A3kvcR0wiHCHUW3q2?=X
Za5@759sL7WP9_qM#Gv`*<&6&R{TJLMdWZl3
literal 0
HcmV?d00001
diff --git a/package-lock.json b/package-lock.json
index f4cf47807..39b1a1841 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3489,12 +3489,12 @@
}
},
"node_modules/@prisma/client": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.0.0.tgz",
- "integrity": "sha512-XlO5ELNAQ7rV4cXIDJUNBEgdLwX3pjtt9Q/RHqDpGf43szpNJx2hJnggfFs7TKNx0cOFsl6KJCSfqr5duEU/bQ==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.3.1.tgz",
+ "integrity": "sha512-ArOKjHwdFZIe1cGU56oIfy7wRuTn0FfZjGuU/AjgEBOQh+4rDkB6nF+AGHP8KaVpkBIiHGPQh3IpwQ3xDMdO0Q==",
"hasInstallScript": true,
"dependencies": {
- "@prisma/engines-version": "4.17.0-26.6b0aef69b7cdfc787f822ecd7cdc76d5f1991584"
+ "@prisma/engines-version": "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59"
},
"engines": {
"node": ">=16.13"
@@ -3509,15 +3509,15 @@
}
},
"node_modules/@prisma/engines": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.0.0.tgz",
- "integrity": "sha512-kyT/8fd0OpWmhAU5YnY7eP31brW1q1YrTGoblWrhQJDiN/1K+Z8S1kylcmtjqx5wsUGcP1HBWutayA/jtyt+sg==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.3.1.tgz",
+ "integrity": "sha512-6QkILNyfeeN67BNEPEtkgh3Xo2tm6D7V+UhrkBbRHqKw9CTaz/vvTP/ROwYSP/3JT2MtIutZm/EnhxUiuOPVDA==",
"hasInstallScript": true
},
"node_modules/@prisma/engines-version": {
- "version": "4.17.0-26.6b0aef69b7cdfc787f822ecd7cdc76d5f1991584",
- "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.17.0-26.6b0aef69b7cdfc787f822ecd7cdc76d5f1991584.tgz",
- "integrity": "sha512-HHiUF6NixsldsP3JROq07TYBLEjXFKr6PdH8H4gK/XAoTmIplOJBCgrIUMrsRAnEuGyRoRLXKXWUb943+PFoKQ=="
+ "version": "5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59",
+ "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.3.1-2.61e140623197a131c2a6189271ffee05a7aa9a59.tgz",
+ "integrity": "sha512-y5qbUi3ql2Xg7XraqcXEdMHh0MocBfnBzDn5GbV1xk23S3Mq8MGs+VjacTNiBh3dtEdUERCrUUG7Z3QaJ+h79w=="
},
"node_modules/@protobufjs/aspromise": {
"version": "1.1.2",
@@ -14820,12 +14820,12 @@
"integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew=="
},
"node_modules/prisma": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.0.0.tgz",
- "integrity": "sha512-KYWk83Fhi1FH59jSpavAYTt2eoMVW9YKgu8ci0kuUnt6Dup5Qy47pcB4/TLmiPAbhGrxxSz7gsSnJcCmkyPANA==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.3.1.tgz",
+ "integrity": "sha512-Wp2msQIlMPHe+5k5Od6xnsI/WNG7UJGgFUJgqv/ygc7kOECZapcSz/iU4NIEzISs3H1W9sFLjAPbg/gOqqtB7A==",
"hasInstallScript": true,
"dependencies": {
- "@prisma/engines": "5.0.0"
+ "@prisma/engines": "5.3.1"
},
"bin": {
"prisma": "build/index.js"
@@ -18417,8 +18417,12 @@
"version": "1.0.0",
"license": "MIT",
"dependencies": {
- "@prisma/client": "5.0.0",
- "prisma": "5.0.0"
+ "@prisma/client": "5.3.1",
+ "prisma": "5.3.1"
+ },
+ "devDependencies": {
+ "ts-node": "^10.9.1",
+ "typescript": "^5.1.6"
}
},
"packages/tailwind-config": {
diff --git a/packages/lib/server-only/document/send-document.tsx b/packages/lib/server-only/document/send-document.tsx
index 37ecc66b7..83a88f24a 100644
--- a/packages/lib/server-only/document/send-document.tsx
+++ b/packages/lib/server-only/document/send-document.tsx
@@ -48,8 +48,8 @@ export const sendDocument = async ({ documentId, userId }: SendDocumentOptions)
return;
}
- const assetBaseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000';
- const signDocumentLink = `${process.env.NEXT_PUBLIC_SITE_URL}/sign/${recipient.token}`;
+ const assetBaseUrl = process.env.NEXT_PUBLIC_WEBAPP_URL || 'http://localhost:3000';
+ const signDocumentLink = `${process.env.NEXT_PUBLIC_WEBAPP_URL}/sign/${recipient.token}`;
const template = createElement(DocumentInviteEmailTemplate, {
documentName: document.title,
diff --git a/packages/lib/universal/get-base-url.ts b/packages/lib/universal/get-base-url.ts
index aa8884088..2120c9f54 100644
--- a/packages/lib/universal/get-base-url.ts
+++ b/packages/lib/universal/get-base-url.ts
@@ -8,8 +8,8 @@ export const getBaseUrl = () => {
return `https://${process.env.VERCEL_URL}`;
}
- if (process.env.NEXT_PUBLIC_SITE_URL) {
- return `https://${process.env.NEXT_PUBLIC_SITE_URL}`;
+ if (process.env.NEXT_PUBLIC_WEBAPP_URL) {
+ return process.env.NEXT_PUBLIC_WEBAPP_URL;
}
return `http://localhost:${process.env.PORT ?? 3000}`;
diff --git a/packages/prisma/helper.ts b/packages/prisma/helper.ts
new file mode 100644
index 000000000..d436771d1
--- /dev/null
+++ b/packages/prisma/helper.ts
@@ -0,0 +1,52 @@
+///
+
+export const getDatabaseUrl = () => {
+ if (process.env.NEXT_PRIVATE_DATABASE_URL) {
+ return process.env.NEXT_PRIVATE_DATABASE_URL;
+ }
+
+ if (process.env.POSTGRES_URL) {
+ process.env.NEXT_PRIVATE_DATABASE_URL = process.env.POSTGRES_URL;
+ process.env.NEXT_PRIVATE_DIRECT_DATABASE_URL = process.env.POSTGRES_URL;
+ }
+
+ if (process.env.DATABASE_URL) {
+ process.env.NEXT_PRIVATE_DATABASE_URL = process.env.DATABASE_URL;
+ process.env.NEXT_PRIVATE_DIRECT_DATABASE_URL = process.env.DATABASE_URL;
+ }
+
+ if (process.env.POSTGRES_PRISMA_URL) {
+ process.env.NEXT_PRIVATE_DATABASE_URL = process.env.POSTGRES_PRISMA_URL;
+ }
+
+ if (process.env.POSTGRES_URL_NON_POOLING) {
+ process.env.NEXT_PRIVATE_DIRECT_DATABASE_URL = process.env.POSTGRES_URL_NON_POOLING;
+ }
+
+ // We change the protocol from `postgres:` to `https:` so we can construct a easily
+ // mofifiable URL.
+ const url = new URL(process.env.NEXT_PRIVATE_DATABASE_URL.replace('postgres://', 'https://'));
+
+ // If we're using a connection pool, we need to let Prisma know that
+ // we're using PgBouncer.
+ if (process.env.NEXT_PRIVATE_DATABASE_URL !== process.env.NEXT_PRIVATE_DIRECT_DATABASE_URL) {
+ url.searchParams.set('pgbouncer', 'true');
+
+ process.env.NEXT_PRIVATE_DATABASE_URL = url.toString().replace('https://', 'postgres://');
+ }
+
+ // Support for neon.tech (Neon Database)
+ if (url.hostname.endsWith('neon.tech')) {
+ const [projectId, ...rest] = url.hostname.split('.');
+
+ if (!projectId.endsWith('-bouncer')) {
+ url.hostname = `${projectId}-pooler.${rest.join('.')}`;
+ }
+
+ url.searchParams.set('pgbouncer', 'true');
+
+ process.env.NEXT_PRIVATE_DATABASE_URL = url.toString().replace('https://', 'postgres://');
+ }
+
+ return process.env.NEXT_PRIVATE_DATABASE_URL;
+};
diff --git a/packages/prisma/index.ts b/packages/prisma/index.ts
index 93a334caa..b9e290add 100644
--- a/packages/prisma/index.ts
+++ b/packages/prisma/index.ts
@@ -1,5 +1,7 @@
import { PrismaClient } from '@prisma/client';
+import { getDatabaseUrl } from './helper';
+
declare global {
// We need `var` to declare a global variable in TypeScript
// eslint-disable-next-line no-var
@@ -7,9 +9,13 @@ declare global {
}
if (!globalThis.prisma) {
- globalThis.prisma = new PrismaClient();
+ globalThis.prisma = new PrismaClient({ datasourceUrl: getDatabaseUrl() });
}
-export const prisma = globalThis.prisma || new PrismaClient();
+export const prisma =
+ globalThis.prisma ||
+ new PrismaClient({
+ datasourceUrl: getDatabaseUrl(),
+ });
export const getPrismaClient = () => prisma;
diff --git a/packages/prisma/package.json b/packages/prisma/package.json
index 3ef12787a..958bcde17 100644
--- a/packages/prisma/package.json
+++ b/packages/prisma/package.json
@@ -9,10 +9,18 @@
"format": "prisma format",
"prisma:generate": "prisma generate",
"prisma:migrate-dev": "prisma migrate dev",
- "prisma:migrate-deploy": "prisma migrate deploy"
+ "prisma:migrate-deploy": "prisma migrate deploy",
+ "prisma:seed": "prisma db seed"
+ },
+ "prisma": {
+ "seed": "ts-node --transpileOnly --skipProject ./seed-database.ts"
},
"dependencies": {
- "@prisma/client": "5.0.0",
- "prisma": "5.0.0"
+ "@prisma/client": "5.3.1",
+ "prisma": "5.3.1"
+ },
+ "devDependencies": {
+ "ts-node": "^10.9.1",
+ "typescript": "^5.1.6"
}
}
diff --git a/packages/prisma/seed-database.ts b/packages/prisma/seed-database.ts
new file mode 100644
index 000000000..65daa357e
--- /dev/null
+++ b/packages/prisma/seed-database.ts
@@ -0,0 +1,82 @@
+import { DocumentDataType, Role } from '@prisma/client';
+import fs from 'node:fs';
+import path from 'node:path';
+
+import { hashSync } from '@documenso/lib/server-only/auth/hash';
+
+import { prisma } from './index';
+
+const seedDatabase = async () => {
+ const examplePdf = fs
+ .readFileSync(path.join(__dirname, '../../assets/example.pdf'))
+ .toString('base64');
+
+ const exampleUser = await prisma.user.upsert({
+ where: {
+ email: 'example@documenso.com',
+ },
+ create: {
+ name: 'Example User',
+ email: 'example@documenso.com',
+ password: hashSync('password'),
+ roles: [Role.USER],
+ },
+ update: {},
+ });
+
+ const adminUser = await prisma.user.upsert({
+ where: {
+ email: 'admin@documenso.com',
+ },
+ create: {
+ name: 'Admin User',
+ email: 'admin@documenso.com',
+ password: hashSync('password'),
+ roles: [Role.USER, Role.ADMIN],
+ },
+ update: {},
+ });
+
+ const examplePdfData = await prisma.documentData.upsert({
+ where: {
+ id: 'clmn0kv5k0000pe04vcqg5zla',
+ },
+ create: {
+ id: 'clmn0kv5k0000pe04vcqg5zla',
+ type: DocumentDataType.BYTES_64,
+ data: examplePdf,
+ initialData: examplePdf,
+ },
+ update: {},
+ });
+
+ await prisma.document.upsert({
+ where: {
+ id: 1,
+ },
+ create: {
+ id: 1,
+ title: 'Example Document',
+ documentDataId: examplePdfData.id,
+ userId: exampleUser.id,
+ Recipient: {
+ create: {
+ name: String(adminUser.name),
+ email: adminUser.email,
+ token: Math.random().toString(36).slice(2, 9),
+ },
+ },
+ },
+ update: {},
+ });
+};
+
+seedDatabase()
+ .then(() => {
+ console.log('Database seeded');
+ process.exit(0);
+ })
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
diff --git a/packages/tsconfig/process-env.d.ts b/packages/tsconfig/process-env.d.ts
index b0852b4f4..d32b9984a 100644
--- a/packages/tsconfig/process-env.d.ts
+++ b/packages/tsconfig/process-env.d.ts
@@ -1,6 +1,7 @@
declare namespace NodeJS {
export interface ProcessEnv {
- NEXT_PUBLIC_SITE_URL?: string;
+ NEXT_PUBLIC_WEBAPP_URL?: string;
+ NEXT_PUBLIC_MARKETING_URL?: string;
NEXT_PRIVATE_GOOGLE_CLIENT_ID?: string;
NEXT_PRIVATE_GOOGLE_CLIENT_SECRET?: string;
@@ -40,5 +41,19 @@ declare namespace NodeJS {
NEXT_PRIVATE_SMTP_FROM_NAME?: string;
NEXT_PRIVATE_SMTP_FROM_ADDRESS?: string;
+
+ /**
+ * Vercel environment variables
+ */
+ VERCEL?: string;
+ VERCEL_ENV?: 'production' | 'development' | 'preview';
+ VERCEL_URL?: string;
+
+ DEPLOYMENT_TARGET?: 'webapp' | 'marketing';
+
+ POSTGRES_URL?: string;
+ DATABASE_URL?: string;
+ POSTGRES_PRISMA_URL?: string;
+ POSTGRES_URL_NON_POOLING?: string;
}
}
diff --git a/scripts/remap-vercel-env.cjs b/scripts/remap-vercel-env.cjs
new file mode 100644
index 000000000..95e60cde8
--- /dev/null
+++ b/scripts/remap-vercel-env.cjs
@@ -0,0 +1,45 @@
+/** @typedef {import('@documenso/tsconfig/process-env')} */
+
+/**
+ * Remap Vercel environment variables to our defined Next.js environment variables.
+ *
+ * @deprecated This is no longer needed because we can't inject runtime environment variables via next.config.js
+ *
+ * @returns {void}
+ */
+const remapVercelEnv = () => {
+ if (!process.env.VERCEL || !process.env.DEPLOYMENT_TARGET) {
+ return;
+ }
+
+ if (process.env.POSTGRES_URL) {
+ process.env.NEXT_PRIVATE_DATABASE_URL = process.env.POSTGRES_URL;
+ }
+
+ if (process.env.POSTGRES_URL_NON_POOLING) {
+ process.env.NEXT_PRIVATE_DIRECT_DATABASE_URL = process.env.POSTGRES_URL_NON_POOLING;
+ }
+
+ // If we're using a connection pool, we need to let Prisma know that
+ // we're using PgBouncer.
+ if (process.env.NEXT_PRIVATE_DATABASE_URL !== process.env.NEXT_PRIVATE_DIRECT_DATABASE_URL) {
+ const url = new URL(process.env.NEXT_PRIVATE_DATABASE_URL);
+
+ url.searchParams.set('pgbouncer', 'true');
+
+ process.env.NEXT_PRIVATE_DATABASE_URL = url.toString();
+ }
+
+ if (process.env.VERCEL_ENV !== 'production' && process.env.DEPLOYMENT_TARGET === 'webapp') {
+ process.env.NEXTAUTH_URL = `https://${process.env.VERCEL_URL}`;
+ process.env.NEXT_PUBLIC_WEBAPP_URL = `https://${process.env.VERCEL_URL}`;
+ }
+
+ if (process.env.VERCEL_ENV !== 'production' && process.env.DEPLOYMENT_TARGET === 'marketing') {
+ process.env.NEXT_PUBLIC_MARKETING_URL = `https://${process.env.VERCEL_URL}`;
+ }
+};
+
+module.exports = {
+ remapVercelEnv,
+};
diff --git a/scripts/vercel.sh b/scripts/vercel.sh
new file mode 100755
index 000000000..e4ab23622
--- /dev/null
+++ b/scripts/vercel.sh
@@ -0,0 +1,107 @@
+#!/usr/bin/env bash
+
+# Exit on error.
+set -eo pipefail
+
+# Get the directory of this script, regardless of where it is called from.
+SCRIPT_DIR="$(readlink -f "$(dirname "$0")")"
+
+
+function log() {
+ echo "[VercelBuild]: $1"
+}
+
+function build_webapp() {
+ log "Building webapp for $VERCEL_ENV"
+
+ remap_database_integration
+
+ npm run prisma:generate --workspace=@documenso/prisma
+ npm run prisma:migrate-deploy --workspace=@documenso/prisma
+
+ if [[ "$VERCEL_ENV" != "production" ]]; then
+ log "Seeding database for $VERCEL_ENV"
+
+ npm run prisma:seed --workspace=@documenso/prisma
+ fi
+
+ npm run build -- --filter @documenso/web
+}
+
+function remap_webapp_env() {
+ if [[ "$VERCEL_ENV" != "production" ]]; then
+ log "Remapping webapp environment variables for $VERCEL_ENV"
+
+ export NEXTAUTH_URL="https://$VERCEL_URL"
+ export NEXT_PUBLIC_WEBAPP_URL="https://$VERCEL_URL"
+ fi
+}
+
+function build_marketing() {
+ log "Building marketing for $VERCEL_ENV"
+
+ remap_database_integration
+
+ npm run prisma:generate --workspace=@documenso/prisma
+ npm run build -- --filter @documenso/marketing
+}
+
+function remap_marketing_env() {
+ if [[ "$VERCEL_ENV" != "production" ]]; then
+ log "Remapping marketing environment variables for $VERCEL_ENV"
+
+ export NEXT_PUBLIC_MARKETING_URL="https://$VERCEL_URL"
+ fi
+}
+
+function remap_database_integration() {
+ log "Remapping Supabase integration for $VERCEL_ENV"
+
+ if [[ ! -z "$POSTGRES_URL" ]]; then
+ export NEXT_PRIVATE_DATABASE_URL="$POSTGRES_URL"
+ export NEXT_PRIVATE_DIRECT_DATABASE_URL="$POSTGRES_URL"
+ fi
+
+ if [[ ! -z "$DATABASE_URL" ]]; then
+ export NEXT_PRIVATE_DATABASE_URL="$DATABASE_URL"
+ export NEXT_PRIVATE_DIRECT_DATABASE_URL="$DATABASE_URL"
+ fi
+
+ if [[ ! -z "$POSTGRES_URL_NON_POOLING" ]]; then
+ export NEXT_PRIVATE_DATABASE_URL="$POSTGRES_URL?pgbouncer=true"
+ export NEXT_PRIVATE_DIRECT_DATABASE_URL="$POSTGRES_URL_NON_POOLING"
+ fi
+
+
+ if [[ "$NEXT_PRIVATE_DATABASE_URL" == *"neon.tech"* ]]; then
+ log "Remapping for Neon integration"
+
+ PROJECT_ID="$(echo "$PGHOST" | cut -d'.' -f1)"
+ PGBOUNCER_HOST="$(echo "$PGHOST" | sed "s/${PROJECT_ID}/${PROJECT_ID}-pooler/")"
+
+ export NEXT_PRIVATE_DATABASE_URL="postgres://${PGUSER}:${PGPASSWORD}@${PGBOUNCER_HOST}/${PGDATABASE}?pgbouncer=true"
+ fi
+}
+
+# Navigate to the root of the project.
+cd "$SCRIPT_DIR/.."
+
+# Check if the script is running on Vercel.
+if [[ -z "$VERCEL" ]]; then
+ log "ERROR - This script must be run as part of the Vercel build process."
+ exit 1
+fi
+
+case "$DEPLOYMENT_TARGET" in
+ "webapp")
+ build_webapp
+ ;;
+ "marketing")
+ build_marketing
+ ;;
+ *)
+ log "ERROR - Missing or invalid DEPLOYMENT_TARGET environment variable."
+ log "ERROR - DEPLOYMENT_TARGET must be either 'webapp' or 'marketing'."
+ exit 1
+ ;;
+esac
diff --git a/turbo.json b/turbo.json
index a5b333c66..01b8bd487 100644
--- a/turbo.json
+++ b/turbo.json
@@ -2,8 +2,13 @@
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
- "dependsOn": ["^build"],
- "outputs": [".next/**", "!.next/cache/**"]
+ "dependsOn": [
+ "^build"
+ ],
+ "outputs": [
+ ".next/**",
+ "!.next/cache/**"
+ ]
},
"lint": {},
"dev": {
@@ -11,20 +16,22 @@
"persistent": true
}
},
- "globalDependencies": ["**/.env.*local"],
+ "globalDependencies": [
+ "**/.env.*local"
+ ],
"globalEnv": [
"APP_VERSION",
"NEXTAUTH_URL",
"NEXTAUTH_SECRET",
- "NEXT_PUBLIC_APP_URL",
- "NEXT_PUBLIC_SITE_URL",
+ "NEXT_PUBLIC_WEBAPP_URL",
+ "NEXT_PUBLIC_MARKETING_URL",
"NEXT_PUBLIC_POSTHOG_KEY",
"NEXT_PUBLIC_POSTHOG_HOST",
"NEXT_PUBLIC_FEATURE_BILLING_ENABLED",
"NEXT_PUBLIC_STRIPE_COMMUNITY_PLAN_YEARLY_PRICE_ID",
"NEXT_PUBLIC_STRIPE_COMMUNITY_PLAN_MONTHLY_PRICE_ID",
"NEXT_PRIVATE_DATABASE_URL",
- "NEXT_PRIVATE_NEXT_AUTH_SECRET",
+ "NEXT_PRIVATE_DIRECT_DATABASE_URL",
"NEXT_PRIVATE_GOOGLE_CLIENT_ID",
"NEXT_PRIVATE_GOOGLE_CLIENT_SECRET",
"NEXT_PUBLIC_UPLOAD_TRANSPORT",
@@ -48,6 +55,15 @@
"NEXT_PRIVATE_SMTP_SECURE",
"NEXT_PRIVATE_SMTP_FROM_NAME",
"NEXT_PRIVATE_SMTP_FROM_ADDRESS",
- "NEXT_PRIVATE_STRIPE_API_KEY"
+ "NEXT_PRIVATE_STRIPE_API_KEY",
+
+ "VERCEL",
+ "VERCEL_ENV",
+ "VERCEL_URL",
+ "DEPLOYMENT_TARGET",
+ "POSTGRES_URL",
+ "DATABASE_URL",
+ "POSTGRES_PRISMA_URL",
+ "POSTGRES_URL_NON_POOLING"
]
}