From 63c7cc5c5b58d08741f455958bf80ca62392459b Mon Sep 17 00:00:00 2001 From: Alessandro Autiero Date: Fri, 24 Feb 2023 15:24:24 +0100 Subject: [PATCH] checkpoint --- assets/binaries/antivirus.bat | 1 + assets/binaries/kill_lawin_port.bat | 1 + assets/binaries/kill_matchmaker_port.bat | 1 + assets/binaries/port.bat | 1 - assets/binaries/release.bat | 2 - assets/binaries/service.bat | 1 - assets/binaries/winnat.bat | 2 + assets/config/DefaultEngine.ini | 7 +- assets/config/DefaultGame.ini | 7 +- assets/config/DefaultRuntimeOptions.ini | 5 +- assets/images/auties.png | Bin 0 -> 6923 bytes assets/images/tutorial_else_1.png | Bin 5153 -> 3037 bytes assets/images/tutorial_else_2.png | Bin 2388 -> 5080 bytes assets/images/tutorial_else_3.png | Bin 3037 -> 2741 bytes assets/images/tutorial_else_4.png | Bin 2741 -> 3080 bytes assets/images/tutorial_else_5.png | Bin 3080 -> 1595 bytes assets/images/tutorial_else_6.png | Bin 1595 -> 1034 bytes assets/images/tutorial_else_7.png | Bin 1034 -> 35726 bytes assets/images/tutorial_else_8.png | Bin 35726 -> 0 bytes assets/images/tutorial_own_1.png | Bin 5153 -> 3037 bytes assets/images/tutorial_own_10.png | Bin 1595 -> 1034 bytes assets/images/tutorial_own_11.png | Bin 1034 -> 35726 bytes assets/images/tutorial_own_12.png | Bin 35726 -> 0 bytes assets/images/tutorial_own_3.png | Bin 3037 -> 2741 bytes assets/images/tutorial_own_4.png | Bin 2741 -> 3080 bytes assets/images/tutorial_own_5.png | Bin 3080 -> 1909 bytes assets/images/tutorial_own_6.png | Bin 1909 -> 1034 bytes assets/images/tutorial_own_7.png | Bin 1034 -> 2270 bytes assets/images/tutorial_own_8.png | Bin 2270 -> 9108 bytes assets/images/tutorial_own_9.png | Bin 9108 -> 1595 bytes lib/cli.dart | 2 +- lib/main.dart | 3 +- lib/src/cli/compatibility.dart | 2 +- lib/src/cli/game.dart | 23 +- lib/src/cli/reboot.dart | 2 +- lib/src/controller/game_controller.dart | 9 +- lib/src/controller/server_controller.dart | 9 +- lib/src/controller/settings_controller.dart | 23 +- lib/src/dialog/dialog.dart | 22 +- lib/src/dialog/game_dialogs.dart | 59 ++++- lib/src/dialog/server_dialogs.dart | 162 +++++++----- lib/src/dialog/snackbar.dart | 1 + lib/src/embedded/auth.dart | 2 +- lib/src/embedded/error.dart | 35 ++- lib/src/embedded/server.dart | 48 ++-- lib/src/embedded/storage.dart | 41 +-- lib/src/model/game_instance.dart | 4 +- lib/src/model/reboot_download.dart | 11 + lib/src/page/home_page.dart | 130 ++++++---- lib/src/page/info_page.dart | 20 +- lib/src/page/launcher_page.dart | 194 ++++++++++---- lib/src/page/server_page.dart | 17 +- lib/src/page/settings_page.dart | 176 +++++++------ lib/src/util/build.dart | 13 +- lib/src/util/checks.dart | 8 + lib/src/util/error.dart | 1 + lib/src/util/os.dart | 69 ++++- lib/src/util/process.dart | 34 +++ lib/src/util/reboot.dart | 82 +++--- lib/src/util/server.dart | 65 +++-- lib/src/widget/home/game_type_selector.dart | 55 ++-- lib/src/widget/home/launch_button.dart | 268 ++++++++++++-------- lib/src/widget/home/version_selector.dart | 88 ++++--- lib/src/widget/server/port_input.dart | 2 +- lib/src/widget/server/server_button.dart | 5 +- lib/src/widget/setting/url_updater.dart | 66 +++++ lib/src/widget/shared/file_selector.dart | 2 +- pubspec.yaml | 8 +- windows/runner/main.cpp | 3 + 69 files changed, 1148 insertions(+), 644 deletions(-) create mode 100644 assets/binaries/antivirus.bat create mode 100644 assets/binaries/kill_lawin_port.bat create mode 100644 assets/binaries/kill_matchmaker_port.bat delete mode 100644 assets/binaries/port.bat delete mode 100644 assets/binaries/release.bat delete mode 100644 assets/binaries/service.bat create mode 100644 assets/binaries/winnat.bat create mode 100644 assets/images/auties.png delete mode 100644 assets/images/tutorial_else_8.png delete mode 100644 assets/images/tutorial_own_12.png create mode 100644 lib/src/model/reboot_download.dart create mode 100644 lib/src/util/process.dart create mode 100644 lib/src/widget/setting/url_updater.dart diff --git a/assets/binaries/antivirus.bat b/assets/binaries/antivirus.bat new file mode 100644 index 0000000..8ef7edf --- /dev/null +++ b/assets/binaries/antivirus.bat @@ -0,0 +1 @@ +powershell -inputformat none -outputformat none -NonInteractive -Command Add-MpPreference -ExclusionPath "%UserProfile%/.reboot_launcher" \ No newline at end of file diff --git a/assets/binaries/kill_lawin_port.bat b/assets/binaries/kill_lawin_port.bat new file mode 100644 index 0000000..6e68e6e --- /dev/null +++ b/assets/binaries/kill_lawin_port.bat @@ -0,0 +1 @@ +for /f "tokens=5" %%a in ('netstat -aon ^| find ":3551" ^| find "LISTENING"') do taskkill /f /pid %%a \ No newline at end of file diff --git a/assets/binaries/kill_matchmaker_port.bat b/assets/binaries/kill_matchmaker_port.bat new file mode 100644 index 0000000..44b34dd --- /dev/null +++ b/assets/binaries/kill_matchmaker_port.bat @@ -0,0 +1 @@ +for /f "tokens=5" %%a in ('netstat -aon ^| find ":8080" ^| find "LISTENING"') do taskkill /f /pid %%a \ No newline at end of file diff --git a/assets/binaries/port.bat b/assets/binaries/port.bat deleted file mode 100644 index c77488b..0000000 --- a/assets/binaries/port.bat +++ /dev/null @@ -1 +0,0 @@ -netstat -ano|find ":3551" \ No newline at end of file diff --git a/assets/binaries/release.bat b/assets/binaries/release.bat deleted file mode 100644 index 63d5a3a..0000000 --- a/assets/binaries/release.bat +++ /dev/null @@ -1,2 +0,0 @@ -for /f "tokens=5" %%a in ('netstat -aon ^| find ":3551" ^| find "LISTENING"') do taskkill /f /pid %%a -for /f "tokens=5" %%a in ('netstat -aon ^| find ":8080" ^| find "LISTENING"') do taskkill /f /pid %%a \ No newline at end of file diff --git a/assets/binaries/service.bat b/assets/binaries/service.bat deleted file mode 100644 index 4a4122c..0000000 --- a/assets/binaries/service.bat +++ /dev/null @@ -1 +0,0 @@ -sc query "MongoDB" | findstr /i "STATE" \ No newline at end of file diff --git a/assets/binaries/winnat.bat b/assets/binaries/winnat.bat new file mode 100644 index 0000000..b425498 --- /dev/null +++ b/assets/binaries/winnat.bat @@ -0,0 +1,2 @@ +net stop winnat +net start winnat \ No newline at end of file diff --git a/assets/config/DefaultEngine.ini b/assets/config/DefaultEngine.ini index b578f40..5ffac6b 100644 --- a/assets/config/DefaultEngine.ini +++ b/assets/config/DefaultEngine.ini @@ -10,8 +10,5 @@ bCheckOSSForUpdate=false [XMPP] bEnableWebsockets=false -# Do not remove/change, this redirects epicgames xmpp to lawinserver xmpp -[OnlineSubsystemMcp.Xmpp Prod] -bUseSSL=false -ServerAddr="ws://127.0.0.1" -ServerPort=80 \ No newline at end of file +[/Script/Engine.InputSettings] +ConsoleKey=F8 \ No newline at end of file diff --git a/assets/config/DefaultGame.ini b/assets/config/DefaultGame.ini index 0d61b80..e6585e5 100644 --- a/assets/config/DefaultGame.ini +++ b/assets/config/DefaultGame.ini @@ -9,12 +9,12 @@ bUploadAthenaStats=false bUploadAthenaStatsV2=false [/Script/FortniteGame.FortMatchmakingV2] -bCustomKeyEnabled=false +bCustomKeyEnabled=true [/Script/FortniteGame.FortChatManager] bShouldRequestGeneralChatRooms=false bShouldJoinGlobalChat=false -bShouldJoinFounderChat=false +bShouldJoinFoaunderChat=false bIsAthenaGlobalChatEnabled=false [/Script/FortniteGame.FortGameInstance] @@ -26,3 +26,6 @@ bBattleRoyaleMatchmakingEnabled=true +FrontEndPlaylistData=(PlaylistName=Playlist_DefaultSquad, PlaylistAccess=(bEnabled=true, bIsDefaultPlaylist=true, bVisibleWhenDisabled=false, bDisplayAsNew=false, CategoryIndex=0, bDisplayAsLimitedTime=false, DisplayPriority=6)) +FrontEndPlaylistData=(PlaylistName=Playlist_PlaygroundV2, PlaylistAccess=(bEnabled=true, bIsDefaultPlaylist=false, bVisibleWhenDisabled=false, bDisplayAsNew=false, CategoryIndex=2, bDisplayAsLimitedTime=false, DisplayPriority=16)) +FrontEndPlaylistData=(PlaylistName=Playlist_Campaign, PlaylistAccess=(bEnabled=true, bInvisibleWhenEnabled=true)) + +[/Script/Engine.InputSettings] +ConsoleKey=F8 \ No newline at end of file diff --git a/assets/config/DefaultRuntimeOptions.ini b/assets/config/DefaultRuntimeOptions.ini index 168cfc9..fe7a055 100644 --- a/assets/config/DefaultRuntimeOptions.ini +++ b/assets/config/DefaultRuntimeOptions.ini @@ -15,4 +15,7 @@ bIsOutOfSeasonMode=true +DisabledTabsForOutOfSeason=(TabName="CareerScreen",TabState=EFortRuntimeOptionTabState::Hidden) +DisabledTabsForOutOfSeason=(TabName="AthenaDirectAcquisition",TabState=EFortRuntimeOptionTabState::Hidden) +DisabledTabsForOutOfSeason=(TabName="BattlePass",TabState=EFortRuntimeOptionTabState::Hidden) -+DisabledTabsForOutOfSeason=(TabName="AthenaCustomize",TabState=EFortRuntimeOptionTabState::Hidden) \ No newline at end of file ++DisabledTabsForOutOfSeason=(TabName="AthenaCustomize",TabState=EFortRuntimeOptionTabState::Hidden) + +[/Script/Engine.InputSettings] +ConsoleKey=F8 \ No newline at end of file diff --git a/assets/images/auties.png b/assets/images/auties.png new file mode 100644 index 0000000000000000000000000000000000000000..b5fbf159de42d79c5604fec2e2a2cb699fdaee74 GIT binary patch literal 6923 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

DtbocRFcs4FdEnxxHrRSebZ1be2Q<+X-`Zo zG8#O29Az@jsQDf!1B|*bd0DL}G1ZEx9Y&`nY3_a0;*6Rf6xGcrrJ<(pwSK{yYE4Y7 zFe(E5Xb3d4IHQ5_aIc%uj;%Fxx)oWYr$bg474z}-2Kpe8QN!V0E2DPT(CJoejhLcJhnCE!(M_Oc5AQ6T zRJ$XWYisCqOUG1bl!h{meaXcb{hix!5TzwE8W`TZ_ia<2CG-%2#ze3(ZFm+ zDP^S7qKix%`e2m={6T$BH%cMX=^fPd%L|#TiYJK$ZR=7_jPloTT7B0hYP>X!+Picq(Z(=pv=b^KTsm&n-Io{90Qz|2KCu`T82#kE8$fyc*bzae zcb{CS{sa5&zwi^pZi@b3F($kYkBj?E2ggg$uZ%9I(8e$d>z_Mq+LcPdn?96JE`*R{ z;anrO150~C#pE%qtK^b_ zI8x)RFr#++p+b2~>!|$wO;Ib%XdqWR#h>A9Lmtz5sc2Ivv@(psM7Xyd@p~TAT1hmO zN?A!p2e;N-i17=U#DR$4^O(A= zq8*|!tHdbUXpThup2yTxi70<-EsjnRtHfyFzyN7f9#hx!aNK&jJXV#_fOd;;BQfoH zOr28Z&JOua0i#GY++nomF?B{e2lfRIw&S!EHx-OJmYDWDrVglj8XB4!Mg#L3MvRlk z)S|@1k>!hVM9P{nMgyzMo)YCTwIZ~W61QV6Z7LZJ9BV)IJf`NQsGSrw#f*yflN&?% zp**H0Rk6E1(Nr@kC+|6xnD#uTrc`K^QhrmHm}y}&kgG~OrtOgc zG<}oXil&QE*x=e#k7*kOK#ML>Dr6cNh2gv9F>SU4pz69p6HPCpf$ZD&m^M`c(53V7 zDpzgV84Wz94V3{8N@jx5zz6-t$rzx4F-8O5(r=J-HTx*H-^;) zOyNF7|9si~L3Nv>jFLH$p*9)QsY$rca$A5KGp891Xy9~y#=1joB&PJh@DdMEFl??f zN+u>u%^tQ(YLhS(8!H!oPLeIF2cu-e&~LBR-vms<;O<`AD9!4`sIUjyVjq5cq}CWy zNv9Yqu`ze4iq(x#X}HT`|1(RZ)(=xj=k~E9?x&uKR!c_7ERtFqOlwXjS&bPb6QsVe zh~|{xNAEd~DOyF;Ctqti$!gE&(2%FfO?pi(L~#*QIa{6v+-sM2rdd-M9hvB*I&;EU z0^km&geHQCzI~T$S<@IL6A8fbMPMr2s%BU%V=8BPir)CM3k?YCiPlU;LmS*$qij_x ztQIhpXb$_5TpeduWesO^Xipx;VO5>8n!%LDhiHM3Sma)xe)uZZ4n`w}fGE;{`5EM_ zYI)U#>8Kfm-$g)&*K7xxp|y_DU3;*N`WB;BbJM&2wOT%)22%+og>w7}mnpg|n$k!w zVJ&7fYTy;g0Q~Ej69QK0V#|5i!kA7?MxlhZo_|jC9NoCqW-g=V8BH=Ed*}9G^@{Ma zr)GOJ+j<1hA9FdczNqMTB=N%^E0;VGBSdnnV)Gn&tk0us2l*3ei%@C8*M zSPaIVIUzVkf;%@Y1Wf0qK_1WqtPuPn4nQgi?gdRa= z1(~o4vb;fwp)@VZ?YhAqz;~?rU!{~Wp9uy_dUpZ+mPn^@2GAj=^=h6m6lV~gwtc`5 zimQ^fuqZNs;`VlR1xeIb09)fE%K9z;Qz@pD-}@98)p38Y#I~6i@dt|_1h!l`!ymAuT=JBELNJ&^a32m1zte%KBkqf#I}_zRcdH8Rp{R(qJ2UzBSgcEs+zz ze=Da$n5i>604w>RgV_+U=06@N7k97B3>I@C)^g6w<;h+yCw;4FG@vJufare^G5#h& zV6P;*o*B9BL~_^^bLoBeO#|Z$pie`lf8*wZgvL5vKhz5|5yQ82Ut+guni0;H08 zJKmbidulfey6XcID(X)!k~Yz0n;vQ4F31Hu3RtO};9sjKg&es9vP)TuCPvU-jtni# zGA4-r+jr4#>hP#3v3<}Glgzm-PxBu7I0{({<83IN9`0eJ`rOfPQ>oWUZ_oz}>UGW$ zf%5_Q+_W1Tj+^7wOJ+W`#V6Bk1uv%jU%EtTMq5rK@#pFG=4!(TEq4$TExLB~WXHGT z9- zC*leDK1(T`1lT}6t0(hLyg#YZ_ulwW^{M8@PT^Bt#8d>7;NC_wHA7Z48VmJ=^{-)L z7=mLXHQbiQepy?V{IsQN&ufvQX0jVhAmq(K%z;%FgZ7@c-o*4iIIMR9$ai__BRcGW zB$uS@3ln~B3Ki(fFHE-SFm^oYpn*&x_1U7P+yt8M!}!36K7P;mxv|HoW35Sx!5$`% zQguoY*p7Qb)FGHD7DO3ykF_9%Rj5&f7+~nJaih>Z)h4O?q4%6?zqRL8{B}QXfF5)2 zFQ@(g)^mNa^d*imO=G5T2OpNYYM7pVwtGArd?6UCrS?ibm-bEvBVN{t41a&D)}x$U z#B4`dVzk^cDnaQ`IK(FEYddvRw9vNreqO%#X7kSZ%O){5pM-?B(TMEXxn>H;Zp@}6 z&zz`5p-sC|9{^c5-m${8v>!n*>JT%9lM~j^h6{zZpGKdl^>5}P!=5Oy8z+b(4XG$H ze+TDP!rX{hb$Btc=;66wlwspO9{YwmbFnn(>z?L8w+_EoCU13LfuCLcFrCP(oXQsh^k7DXKHppHw^u)>x(`4s-Iry+oArt1XB77 ztuS2tW4b7WoN1s)OE|$;A87~-&8Q_bRJvDkyK>VG z6^1i|+gHEdXs9pnI``amOY0b0wEThFRhs!^)6>3AM;%?;r~R4FNK7ymF?!P@R$Nt? z_v0Dg(L!oI4j)xF*n{I>jn3{Z8PzDP^oEmF)_!m7#CtTWeQrilE=TXqM&;twfU*1c z&YhOdnAdYFm>{Niz_V=Ja&KXnDECWyVP~Xeq^k- zf|87Mc8(8+vjYqaZohuoNpnawS+P;A@wN_n?Xk7B9!Ev^=Hsm9f)A`sbxqZPD$8Y2 zDBEZQp?ebQ7<0tqcU>iTjehxLOO!eGZLqk~R9m6b?z?3TTP-04GS}s(f)y3k%E#Za zxi)4s^9||QC+5e%$Cc#zshTMsPjn2eL)x|(F*Mv^_ocWhj$#XsJ#ZFfQZiw%%q#ECfiq4*@N(5mX6Mn@Ig8-rFc+LJ4Bv^XX<7N*8xFH*3hm7kKi_Fj>~Fag z98i1o-C4QBn%uqBw%_KD?kVLY^!g86h};|7-U`3#b;cX=`sh8U^mkTVKR2x(d{ejJ z@T(cYV|K#B4hZG31>R^#l*2xSsn9B|6$Lwt8%wI*b;@8hLw$$aciQSKuf<4_;ru0X zsaFRxfL`Z~rhvAzZx<2YMgE;)e@}E%%?zfvR9hluU42; z&U|seVzmFzs>YVzW{DSX?vAh9#{kM9(lZH9tada`zRI^WWuGrv`+5S`XF5};8Ald* z2_`%;c8el&vFX|FHCkd2a9=-E;b30Q;ee9>O03jvE5Cei8~3!W(r%fw z;mSnK5*wNIxBlB>`;nBgQq7u2qgO+yojtx9ZUg!<;qClsJGD88#mUq$s}5oX@T*qxBZN#j*hU`8wS$}w|X)z^5%J|D!7_)xf6ePW5m1>cda zVCYa~R@aU8w6@cwFbM_Y9gQ%m1IX$!@6Jy!mzG zne~}`(C9{-Ox~ySFaYWb13y0w&%i0N9M9pZP*%isPVyBC zegvte3}R@n+CZg5sHT(&o?)e?ajrIIx2se%5r{2`+hpV s;2)-ubQ#Sccyg`;@_m7r8*M!Dx2LebAwuDX%5<`QepK(-=6^otKN|)6WdHyG literal 5153 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 literal 2388 zcmbuBX;@Ro9>#}75pk;v$o|+0h>BbZ!cAEsn}8sx#*H1Sf*K&m5|#)-Tda616pf&O zNmT?F2uLJIfCNQFmJn=^Ko*cKVM_u8f+QsL*!#6l?}z*0EOVa!ne)DLW`6JF{1D*1 zey!130Kj@*AJ1a|Xih`-$JeZe&i$4@GNFq`;xTV`K<+Y`fEwD-Zb#ezc#)^K9JvZ= z>&E*8CIYabI-lzcV{SWY83@gHZ?fO9M$=%( zee1*PyKX$m-sD;NGuF*Gc+B#=!OO#%ud_ED${&8V=7#2@6On7YynOflJl$L7j=%gq zO?uyHvBX(~t)kE2%(hD!VWLJ@v_vSQi<}apsF=ab#~J`Uv!^7A0u=@Z{1lgj=L4t?tCrP7bBmG%6(x%%;TwoM80^^bW1ubxY>6G22_#@jtWnmiKr7jTW3^bE5*;e)+s&}mUhk; zp_*Z2DCOB1X&I|Gcr1m$qvVLC(c6OF#|b5<@_<^^C}m#RHcO4=QR7RbbS1edV8v3Y zjCAtrdSI&(2Iu}EecfvDu%M~pY3TeG3l#5c# zicn=}G9SInP%EY^S|vI&35|AV%u@!^L~lMnz`J@F{+pm0qZDLrewJsB7$AGgqko&j z)G)NgHKQg9JD>5z;@1J>U~+f}E$KpAv^d-YfH+r_j(l9_ZD<4bfEAJ$!}&#Fu|v1W z*dbcqJm@xQu+msm$%><%Bg0cQO+)5z8|k z4Rr1`m5_D^UHsaoS5{A;1HfNCxwUUg_m&aNxn*^*44X=ZpH8=SSY(6mYq1 z{wYx`l+m%S*j*H^b@W8x$BJt!b|1#4HtzeDV*{J=qQ`y^wL9vKtpL!>yx?`kMZ?9- zg(9>@8d?n5C-dGtDesuqQk)9U_$24p9tjjTn^>p#w)q>L{k7N&c|WBq`myL=6%-`m z`8R!RDKwnCT5@J^_X=X3=?wdW}yh`;b@KZh5=Q$D)|p z%xS;z&d!v{9+)z8K*n?&OsWcVfd^>f;D_Q4np#n2;H`HE1*P^Dk@Y54mwjL^5o>SHiqY$f!UXYrsiJcyW&i7+nZsus>+9T{J5V9&l?2>C1>@C+$Tj%Wm z`e5aV-NMVopJ=$P5a9laSuqd8zZcMw(K4l!ky6=K0#7XKZ^ET;Xp$Q zWkjG4z-gDd!AzX2!kK z3)x77IOs^?=!g8M)?Cw2^wV`_cGtH%`T&q+9C<jEG3$St@P4m z-&NYWgm^F|xJN)h(Wx;|__*+t#V{6LMow+>P_Nn0i7`xJTaR~H|3Bpfnh-L)(7 ziN(cPGO0cvq?|@k^11Mfqonl7r&yP;)S>Kb+EOM7Qu%yJzYn&DD0*DJvy4HAH|0@d zjo~QQq%Si=+4MR7{7Y}&o0rp$pDDPMEc;r1K=~L2Kt#Q<+OHg11(V^jbL0} zN`S#&>{{p#-0>+3pc3DEUU5N)7;yp`8OrJk&;QPI#ZYN~f4{uY3ug2M!aA)I>bo?q zeyqUZ6v;Is{aK(KS{t2A<^d<{^m&I^ZjTvc`mVoalWoYW?h>aI@;wqsN)3n_{+jn8 nc;aTQ|2y{oevfdHy}WTNlQnkzoc>2>Cj@-G0zAp?5m)~NC`6-} diff --git a/assets/images/tutorial_else_3.png b/assets/images/tutorial_else_3.png index 7b8d8e889435b6151fa7b6c77049bb2fd0d5d2f7..b025c32b4ad1abc58dc1beb716c6c75b1de1da5f 100644 GIT binary patch literal 2741 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 diff --git a/assets/images/tutorial_else_4.png b/assets/images/tutorial_else_4.png index b025c32b4ad1abc58dc1beb716c6c75b1de1da5f..3162ea35d1fbcb477046baae025a86feed3a6c3d 100644 GIT binary patch literal 3080 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 F{{`tq7!d#f literal 2741 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 literal 3080 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 F{{`tq7!d#f diff --git a/assets/images/tutorial_else_6.png b/assets/images/tutorial_else_6.png index cc315692698870a5248a3921c98a73c114d3cae0..1ff494fd94a192b623e2b508bec8b24fae9f4ccc 100644 GIT binary patch literal 1034 zcmeAS@N?(olHy`uVBq!ia0y~yV0r{(TX3)e$sIT6#sewF;vjb?hIQv;UIIBR>5jgR z3=A9lx&I`x0{NT;9+AZi419+{nDKc2iWCM0=J}p3jv*CsZ|~T8sdzIS_&Dpix|P-n zj%93oatdfJvdtpQLG7*)HW*mcM&9 z#iq_aW7(?R>32T(=Z8+$n(Czsw9@yh|1TB>hFKmR%nS}}PBIJ(Mgl-bPiPciXK3JQ zv0z|GQ8>cLpunui$G{-TQOLk>!hwL&=AflPE0=!cep+O?W$V_Zk_-$V0?W(G7e=jJ zcJp-{@5g`t{uR{M%V%v3mzHH-J>~c-`GR?cl+K^_O>CxO!Do zPEPI;PlJ78e!hN5Sy|iNyLU^})&s4+aQpV}+<&$V|HD7pKDvJWdgixD>d0Z>kXAU; zBW9OSzs0)f$VkrY?Ci{M8gcP4F*?US78e(9-m(7Q-}v|QXU(eGCDvc@zWDt5qt%QV za*BKtF5bBlbK~AUzQ>OrA1$n`yeV+{y`-F+p55c}>C>hidhsITMdANk1nYdsqqTi5v?*3X|mKl;NoJv}}1%ZeDi<$?@nfzfT$mAz;2FQJJN zkL!bMPci@qcl%!-f2?+D$3vqyX-P@V zYc2I5G1YR{8?Wz|@0a+_P{Y5}YiW@8W2Zm)XKvrVZNkjJuy57gy?@XCwVH=J-CYoP zwDnf^^cBDa9seaR+Pvk*)vKW&XNfW}Jb0ZHe0*D-_u=Xzi~IWeF5JB<3pC#fXlzYL zjgXx3pJ&h1=4O7$0-DWGKmF`1l9K*~62(6(k`tMfGiql86C?wJr>mdKI;Vst03nsF A*8l(j literal 1595 zcma)6X)qgT82(&!w2IZOHiWJo*j_BFCY3EkHMXI;7IiN>&Y~Gtl6AMH!Zc}jr_`-l zl$5MeDT(Nm3e`%m8bxR+62zIfDzcy5Kl`uy9@O^e38A4FVvDr}ppLS8>lY|W z6ZiP^nnRu{a;}%Cx63p&6~D3c!aPxwWoepi;K?ytmfP1X3;tLu%JtDX!7vZezC9pX zoWpQBJ3ABQ0m$MOl*oZpd6ifIj5BSNL2CLJVS^M~M$tz*wY9Yoo^b~UJrM>5oZ|qL zsv>38vaYVK*tL0ntaMYtQ~Ee+$etY z&uF%v^>`fBibSIg_$vcI_4P>8$Dz^amVlAT#gA=a;o&pWKAZD=Mt{MX=)T6t;cE7( zXqXzRp|$Qv)~lKtoEU1mrO{vhV{UZ>0DtDkp~siUUu8GMO!qLI!q{Y_P}pBdxL55- z(WE)tj2>#JA|?sA55#lt>r2f1TRA4EouIrleOF`xp7gj@fg!P%POvE(10}Cif1Azh z{_r7Sh)IZH!9i2|pZ;(JQTfSi=xGS2SUfX8WquB^v$KN{TnLg0`xgC_Dua1V1@I!A z{=|lIH|K!&`{%fz{QLJi8Ryzn3FxO^aq4Ov0|Kp&1#@BNGjfs)#Dgho^S-F$E&M2E z0O=jresroYDE4SOi76JD*0SFK#cxeX@sk5DX8yvJ%HEc|Y}qTW58+H9Vc)g8 z5xA;{BXd@;-4CfYl)UBVD^73jQpn^fUjPD{a?s;&)D|IE51#_Srd|=2yU)H<0od50 z@@*GHBCJ#@t*WdvT7Znq&MPT#F*i34i;6n6a3ZSL#-ASL>&1wV+*}oTOW<@s5lLab zx%^zpc45MB#M$xhOieEr6?1xevLKN?%R&XA!qAz}S?30IF^k0#OFyqMVen=xEHaW$ zYD|lo(gPsBH_V%ny~B%t)A&zD|AFpDxD@2soMT2tI@W=wN19@c_)J1QF=_JkJtZEj z>sf>~_b`jy(a|?R_2?G}LM53z<-K~H3+t`jxu-pN3uCP%3C#)HTN~o_r3sits;uII z0@|>Ny!=i;=1un$bwkz~57+uKlAV*b-sYKyRFm#he2)+;-DvN0s+@7X?~YURqr7Uj zx^yymU0FllO?J7}kJ181U741aHpbcuK+ep@%Cr#DFGch^b4A<8`4NdkV)hqaP)Ne# zt*}_^gtmo@FNq|$7ZuV ztb6Pprfn}zb~hv}j558NiT33ZoLJDC_%#6ANG+k+>y|#8K0;l*p3OE%C`_hjY1}xq zYBH#MCd!SI-9jr`zhex*lbfOZd*l`F`W|8-o=&c6pLm(E8_5sGjj@sjstB{Zj%!3C z!^NOuXjX@>4*=`5nS%!p=5c5#+AI9}`g#J~hOtx{jn*7D5t!Aq!;M2w9;L?ekl<>D zJMhpyu+Ne^JuM^N(18R{MMcgwrs>l?ed>d;P#b`sSurnOos3jKCrh?RMttHp9mU1P zOz14u5P|YS<)en0wIfqpU2Ev{Gm^EnY`FD2(+@=C<>gh$xBP@ug34IrT-Sll|L-#V e(zXnIBtAz9+T)ZkVsR9T2VfkW?Q72mr2h>hP2L&+ diff --git a/assets/images/tutorial_else_7.png b/assets/images/tutorial_else_7.png index 1ff494fd94a192b623e2b508bec8b24fae9f4ccc..0e96942fc735f04c7b2193de32c4a932c001178b 100644 GIT binary patch literal 35726 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 literal 1034 zcmeAS@N?(olHy`uVBq!ia0y~yV0r{(TX3)e$sIT6#sewF;vjb?hIQv;UIIBR>5jgR z3=A9lx&I`x0{NT;9+AZi419+{nDKc2iWCM0=J}p3jv*CsZ|~T8sdzIS_&Dpix|P-n zj%93oatdfJvdtpQLG7*)HW*mcM&9 z#iq_aW7(?R>32T(=Z8+$n(Czsw9@yh|1TB>hFKmR%nS}}PBIJ(Mgl-bPiPciXK3JQ zv0z|GQ8>cLpunui$G{-TQOLk>!hwL&=AflPE0=!cep+O?W$V_Zk_-$V0?W(G7e=jJ zcJp-{@5g`t{uR{M%V%v3mzHH-J>~c-`GR?cl+K^_O>CxO!Do zPEPI;PlJ78e!hN5Sy|iNyLU^})&s4+aQpV}+<&$V|HD7pKDvJWdgixD>d0Z>kXAU; zBW9OSzs0)f$VkrY?Ci{M8gcP4F*?US78e(9-m(7Q-}v|QXU(eGCDvc@zWDt5qt%QV za*BKtF5bBlbK~AUzQ>OrA1$n`yeV+{y`-F+p55c}>C>hidhsITMdANk1nYdsqqTi5v?*3X|mKl;NoJv}}1%ZeDi<$?@nfzfT$mAz;2FQJJN zkL!bMPci@qcl%!-f2?+D$3vqyX-P@V zYc2I5G1YR{8?Wz|@0a+_P{Y5}YiW@8W2Zm)XKvrVZNkjJuy57gy?@XCwVH=J-CYoP zwDnf^^cBDa9seaR+Pvk*)vKW&XNfW}Jb0ZHe0*D-_u=Xzi~IWeF5JB<3pC#fXlzYL zjgXx3pJ&h1=4O7$0-DWGKmF`1l9K*~62(6(k`tMfGiql86C?wJr>mdKI;Vst03nsF A*8l(j diff --git a/assets/images/tutorial_else_8.png b/assets/images/tutorial_else_8.png deleted file mode 100644 index 0e96942fc735f04c7b2193de32c4a932c001178b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35726 zcmV)gK%~EkP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>Diz7)yK~#8N?Y#$} zY)5q^TKC?U_4J;krEuoxI@;K4q5R!YH;g68ToX5x%7Gt;zDiYX<{#rL+BVmeIoJrbAuLH-7mLTa_Ijv1mRODPqSb#bb>8WXD<3s;KXm9Ib&2Zs~QD;bF~o zr*#DV@$Uj>#nfh3$d7r^ z$jla`48ICF5UA5n8Jek0)N+gtg`1v_^fBXced~#U5c58c1tK z97%k9_<=?(|1@vttm0nWvY$lWp#7dYfd zCohC8el`fX!3RXF$s!LEmqlBw`%>z_K_L+?#F7WiR98e>4XNvNpY6;xbR3(B(cYG- z*$JM&p3XQL!}0_ZAEg8=F4=6bsGj;l89>^|)glw%)EOtP-%grwm0GMuT26;36H+kM5kiw}V?tdev;@37 z4Kt|7tEg@cT7R7+DbKJv7UFOws-21{VGX$kmlb9EZQO%c#^zg_TGBFXA9Od8b)QRG zUXGbJ{?Z>xb2N|b(n-d)&Z6$XC#8c800}m*0LhMni<_Bk1B|$0vrBbUW>nja$y(@4 zB>|^6h5cc$yxP7Pgkp#3u61zxSq=P^Ky=qya~# zB_)&73B%~}B2;dPRw22rMn~mI+O1*8v6R!Gp4m_fLEL)XHhDxBY^Rk+KHr(qn_wTe zrIvkkmZ@gfVmQ`pgwa*63wnj)NxP)5(^X2+XJ=7aS-I+go_y?PwP~U7F%vD>`rtgX zC6>VXj7-(ip|(d#jr^AV*#Oc8rY2Y=HvkyZ4BfPL)f(gib!s*nu*4VJ>Pt)%ok7wm z3R5snXup+|S!1@!ZwG9!)7N%G^X)wiA>H@-2TPLj>D?6rk zrz6dJ+oB+^7hoQX))IW+dE2(7!il0Q7Rqupi2 zQkSx44p3*SOI~Dq1CR9SHr?KTWX_BcEtq2WKcYvB7S>!|{~FwI@&8dP2VddX6$Ve@ zIzXF{Tx$S$S;!w;<2xHTPR0zauPLkf$R3{CkXm4w1F5g1a@JD^kwJ#F)ktV#KWeoi zt75@U)G7%3r&_J)nNW+iaR7!?Ytx6qx7|fUE!IUtn{H^+_XGwm$5!c)Ts1~@VM|*B z+*2mqJ$L@z*n`kT$dZ=}{*cH{Y3!PY@Cc&1GO6QfK*AZUMgv8zxy?);DXFN1YINqZ zkY?GKWquUeSQVASP^;-#6~QH=*64C@04mk|KF?T7r&%?}Ym?Bo-9?&Bk{{6!6h7I< zOMOpp00yQlKX}2`J9!R8Sx<BgLUtPB>Bx{cp(ey0kke7 z9mWPK0XghNz+9CISK(C`DP>PZEmZQ6LT%X@X;!ikXx4JuX1z_faZjPPET!Ka zDrI~uqPCsO&84E&rtuMlE>zAB>2aopwpDWG=YHjnVKS1j7>>B$2hEU zOSq@jvY`Jc5?Yh`YsZY<)b@nVs{O0*=s^$Q9zTw5A9U`Hp(|pIOtRwN&c|UIEZebb zwt&HA8XSM_v(*yZ@TvExm19;*2967puR^*IGnGBiw1L?T@J{e-K@9tsa4pEf4W|xE zD{1pW%pfw&ZQUF=CJE-jNR~6~l}E}4#IYE|;>2X8Ndj3gBZt5!=|m#m0n@{wd0n(N zWFo0Xn$=kdjhfD*Sr>IyW#>dG-?r2(*yFGTVVPabQ`XyKanjq;}jF?O(0?u`&BTaF;5~EqI<0+HD{4|yM14y$t__UB_Lare&k4dwf zUG+WHqS+*jm9n;$!pT5e^(aiuweI4hf!ccXu@e(l7=WUU;mwzs6~>cPiY&a0D4RCU z)yWFP@<59)?C1+^rS{q^RY0dx{ltENnJpV6k(^Kvuipr znI7QnO`7G@wP=H7NP4|Z&$79^zGqAQRHMo`#X6)e ziN39V(xM~TU1s|B6KOU9YwNvK(k!vQk`qu+i_{oV3r<2s;r5`OS?&^K86OSIW^3TN zTySkRHl8>fNUpI^XvXat8=w=@rZTshFDTPWMzBCLZaBr+b52?dh3PJq>0GF;T5g(< zL@k&Ch@P>?^Vp#lGqTjoE#VV9Cq$zOn&s=$N3BD3YoLrGzeZcGv||La*dW&0e`H9r zWoKY(vbUnX43KB7+@mU#FyVNL3TO4yph|%@hbp)Pfno zacZTAg8~E)SMpRrtmtw}woSF%Uh<-PNzErls6YwzwvC)3OtqBGbBXnKhA?a9JDb^l zGP;S9jHyzSK5ue1o1{fg1*=*m&0^c04YUT9fR^@jQGVN1T2@$_CHv5JjAs1-T!_?K z9;A1YRzv1ZE+-o8)2u<#W!_{hKZYYjh!Z7M8K=}lY(|}w=U_1|GKcb`sdEun7gL~u z&yO*(^7ZsFf{!taH~@|5^5WzGXDKX^#WN?PtVOcp}6qUQdv`M`R&Z>3`bcLO&PO5<}8&C{)wF$5fMZUGgM0`r1Zi6)A zZMDWhhB=e43n^!Ifkv8~H24s)4!*s(UKMIv40CI&iXE&itIpztiH#IcS?VZt;y^|z zvfMUus>~zt@FZ2{;-q>>m-SCEK_1Isxg5)bT+7EI%V6t>NaELegpG5 zC21BJ^>T_i>7W;`vxu4>+heM%S*@_VNUa}hf{!eC>9!t9nk8oIW^6-OY%=iTQ5Kv# z@lviVw7wqgYK`A6 zsI8l4wnLK0C|rf)H}!s0k4O}&Q9%)Ee1*N+Eg(^zcPCbnx}zy7S3teWbUU*L%hBYf zBaT%|aQ_Y8P%FpWX-|31TX-}oxapWQ;9z&%bMtlLw4&Il9s4*7^&E?y@Pwe&Dh>88 z!)2IB`$!OtR&WM(Y6TLDGe)!uBV`aW2d)!}m>|oj<|Ik2&YUTbRqk%7GujaxvVNV% zn}TSgN}82g9kQ<*xfRhr=N@e~)~`S{g=Y!k_CKSV$m?Xyb~G15h0)Z#SrsEHQUS{7 zZlWENBp3U3saWRbGBgLAuhYD_u`@sR#^0~5$CIA(Qc6#uZ+_03Y4+RB0GQT ztRplGMFaiqxr`;OS7Rr#(A>3ADU7BLbPp0m%|;yP%V|{Mo+qIZ_h=1v)?)N#6bZ@g zZ`-5Hp7=N#1}xU6JmIK=!jXsWAJ(m19roF<7jd1IdxedAuM7Y2KfgWP_rMm-PMBot z`p@m<0WT-b8i;CPWZCLu8l$Ngx_=T;g0-9|u~A&(I47A|MoUf?C`%rXDtgbINlq?c zf(<(1+~=qzxb~C(o6GVFbLK~W>i3G(5clNodKs67Z+`k?Y7tx;$s|i288W{TH$=TH zp#|OPEzyojDb!Q9_25aM8fLK)FOrL4CW|MtDHgQ|)ryQ}F2M~p)wl-|id`htduz6$ zUVV`}?Wdl0e0ajq2Zv4j?H%^tcki&@#`R&x&Rt>imTlq2Tkj5Ex$?&Fxi4QGcI}$i zdhOV-_u6po=_iDMXPmBn6L0zRcZY9Xe|y$0 z@X{Ba7Y;jkzc4p98&=HCg%vAi$)-|${JXB<@80>*aQ#hpsV7*wW>t9Mv(5^nXd`=n!W!!37*E9h8!7RO@ueBLHIeZSMFa7lT7^6G;PiDli)uU3jkW|3FT=>lc7 zH?b@zPMt>{ZiCte9Kdh)%qw31JJnS_^}AoLmf*@u(|}VR=*(3oTS#=osK=V<2(@Ey zrRKUYrdntP#a`_iL;!K?Ik`%n6N(xRL-Pb}pDTIz6ue@8(X-DCCmweg``^6w*6^<% zzbrhk`C;}4AzwuYQDzjf{_cyy72mv3l_t(R^Mvr@ zFMBq3%w52T-5ftUZ;%dZaq>;0b&-}hZ-hgZD# z0*yBD*Z=r$;gTvo#9_T z`o-|Ui!Kj4cF=ZK&VNX=v$Nra&padi&2qIH3{i2sU$T=xjW~LfLa8a|~5+i5Rve5t`mL;CRgLURVsC^Gbi$ zLrK1q4W;?c7W(h?c-!UJ#D2=9M+EF4%uq`(W)Lx-NTFGc5^S=T%Zw@3aukHl)Fnd_ zkm=hHsONOB0S;)Axnfpf>3#4y2OY36{N|fp8lLyG)A(&85H_@f_TNXd>flu~s+Isn z_6B~j{3l=e-0;KSd%>W=1~`CTasR^WUL4Lm`B-g9Ni*=-=bsXO=Et7jJJ$`ykL8{nV= z_ThnU(UaPm1Z!5W3NL@r`QcA~?NxkSu^t(rA- z&TC)t%&GGJ%W%hur>J{c4#8}VL9n3N$rSPG)wgBt1PE1p4ab&By{JdoGu_Nl+J!SbktRO{a$Or@y8q@e-&E* z8e+&vtJ}RUw%!bNR;^kQe(?EE6>SP&u)*7XzV(;9;JmP6#T?s{;swt0i44d zH>|5}yWzpjTRE@q3TOX)H_$On=MCx{OasUyKtAdjxh*{Dro_G**N6Y>$6mlk%+_fo zU3KAerD?&(;#p^9+e!~64vpBPVd7XK%~Fm|a3r5Y3`rG5Y@x(Nvt%||Lz2_Pj1HEN zPbn6uNRrRigcQtZi=Ub_i`&)5HuS{{NP613ysB3+-Dg zPv-T-%?e$3K(BCWcc6J3xM@RtF4=RW@9oGExEjF*%DI%I_yU&W{5AAOew_Rnk)(|%!+qZNK=$@I*8=6 ziv+-jCgpNs;`UQQZ>m8P(_3mZT7dRBjvTy1x$Jko5(n5nX;PVTg`&q8*1^ZwPdQ9c zv7VAsP(u^LsxoPomTA7mI%ufH+8B{J-H25&A}fG9y>Md#@YFMo=dum&`oO2d zpZ(Vls8`2nPdbXv5nKgy0o#r|+_ANLzWt6le8z$EfX_R6LV$;00I2{uHQ=fXw^&%ojUd;Ydj_uBQWxi(6f$O&TK;4<_48 z$w?8R)H5PasTq^QYPv=|9V*f=OjC(F>5>V#=g>&^0`BXHfdmcXLwkHCgAcK>c*&gM z^W%e`xSYKj5W`!u+y?n*XWtFDMOWHk==PW!p~8msYsF{*Zs)!2&ile=F1t#VIyUXI zHEshlLe%_11Ugg#j1mBVM3Av}L=hP2jDnRV(MR zf#Q$@_tj{Qu7MSG;&T9P^_*Z|`s#JzxBv2=!q#m&RA~Zl)g5)%{@m8a^)hI;0e7L@ za>u=V$6Xh2qXn&^66=^4tz2fv7Lk)_I`=Yc>;u>eZci0nE?X!y&jdx>kLnxX8fnx%opd?}NSm@&m;43oy_ zA!SC*;XGNe7EJbyre$!dnq__)2V>$2%LwVCW2amSxmSTta7i-k3_47@U%p z96`>?p3hqDx&I+9`)0&bzkxr`HU z=dN9<)`2$Ve3$1I-ukQI+8ggss|g-(c+yj|=lsM?4-akG8b0>vuc}f9zH5Wc=sOm7 z-}fLd^MMEZkA;WsA_WX_l0}F{Q218gSB$0-m-*Gtvv!`qfQ&6_a$K8-Qp9B%exJ0cgz3)(JTr z(74i!m=8u-Ch-(0m{U;;c{b1)?1A;LeA%E(A~8o*_30eUg?!SK5_uI_6*8ZE{9)ne zf8s^_HV8T=5H_@vPB@$sF_2(TDsc*FHlRHD_`}1Sf8u+>VF$T($cFZ0v}4eHAZsdk zVDnbB>ez=nuNl5d=mO4z{pgi--)+@9cg^!Tv}MaSRq8l!|Bb!N+(`qMoR2i%?A)zt z9r!$q&vBYy;|r8EbPYI%@)Zs(5A7(sAh&pjaMP{#s8Yuhk3E#;{Wm}0OS8yZ*)tHg ztyZolr6x73WZ z=i)%(Q`v`}29MlM^-S}z6gMsDLa#g8L=FgG?#aj;b1^kS301L)&Nh|<=xbwtYfkEb zfx4>j!3Jrj9lD=Vf&;lP|DN;ts=(hEVE!v82Hbk*{d~)7323+8aUU&iM%p3Y=b8V* zFTQ|tuxb%xvqsYc4|TskV-IF%;0JEKv;A#4051-J`+KfjE;#E% zzWZ-A4VZWvu?_s?*|uj;|7y1&oj}pzb7&}Z!9B|#x_ZcCMx#|=*44yGQEQ{d2C5<; z>zJW6w*ciK)f0#V4&M}@gwILtL?%g1JehRxz+`qxby_W6#z@m;F||#xt&ZdXF~&jF zJZTnVpv)LvHp*-`viif%>|sEA8ENLJfi#&S>_m~wO|qFLd|q=nUCp!so!fqtgSVdU zr>hWjg18$CgbfWuJ4YPS-Hv?0k(Np;V(Y>n<2D-5x`6MDyy2DK6+ZNd%fpYo`LDxk zf9Y?+8~)RO;SaBW`49hR_^rSEr|_qL|ABDx?f3Q$IJnUPSNQ<0bh@yK+FH4)XTagB z8aYRIawppk{t_jh%Zq%a(gwVRcz?^4#^DEV;?mB^KHv+gcxK_30J?yEi~$j!&vfB{ zO&h`+f9wU}10VfTc=;RuH2lb${v!Oue|%f`ncw*P@Qc6qKf-VR*}K9Y|G)3!V^Kpq z?u_KIl?Bzwiz252if1W(`7Ic-Z#^3M)dsp-MRXDlMYUc-FyL${LXDiNR2Aj_aEQ3F z;j0@RbZiM)5c7e89x_-&BE#p1ZaHOL(X?Jhi3!DM>R5HsFmVi44){#YZ^jKVNA1Cw z^2A*du*{4!bCk}zLN{gLHXO@%4b&d;{^^6C4ZrvYZx6rl`$E{zI6M$3l`LLY(Y}85 zE#cmt+luiMHNXE$Kg@6KVW7YV^yoy+rk&WdL92}n7rlF4nN4WT}2qsR^JuQ z?%neC95Cn#NA0#71^^q>Yrvgt_?@+(Coq49i1P56RUZ!Av@v|;8#nOp#B~8*3jL#B z|FLk&iAV7j-sUY^!`=684maI)Pq^}$Tf^tSat(iOjTl$rs z`u_0CZ}?umtBTvhgvPkR8UA3t3%howj<&vVqd48ekO*laP%## z61a123k{t2J|H(rl)x2>uZv^a1$>rTTd@Y4iC-l^1TR->G@F&0iDkf~)aDWewxt)LgOlv#u`oL#6hZz^HzL?>o zmwq+earXmUrw^ynE9>9;#aHm#YTm{hzrQ?5(vn;0`sPUjwc-aQ*>( zzg&&qF|(7j?JYI@L=IBAuK3W|4+RD&?3f`}I2dqnEIxSAWqcd@5S)I}(c!JX`YQg- zy1n;W%f~>Dr~noZ1QHORHFgPl?8IbB0Ye<|0nx-(u;esJQ6F=SWV#{6*+Lv-WpZ#E zpth4Y8ifhDRN&k+_Mnl1-nBrb8Eaj#bIKJCozb2c3=qeOp3$m#jb_&Q=K}_)gNY4d z#JG%#o$9!DRr5I#FPBfYUpJn_wxATEtCJz>4whEP74)186kd+gCBn|XNSgI98?eAi zGuPa32md^O34HhEnj7yxGyL;4Z+h(u_zJ@S`%SNXVL0LFL#UmZaP zx`4r}Hi&xQF9Zz!hKWA3UE$bWV)wON;Q&V*LRWVR-K(v@6%LU8N}(M*AX54^Iu^hG zH~-vvl~n@A;u%jpDg42Id}X}(0853g2S)tD(4!x+=zG}fg^c{yB~Gk}hhKu@}9P7|#< z6$imTJCv_``Lp>|YKc>ycx2dX-D+<86)!rEU&-V108ePI_@48qoj|#(xK4>Po_uup z$sc|W=U{nhf-kg=1OGGgyMO(EssmRW@RKpW{D$x2&s(S&c}3p=e^t{v;LzaJcV&RP z=L~%Vj@>rBnmYEjTcYi=oBJMUA9#;AR0ka1cVf1|?mnE;fu{>HILWcO{jU4Num90I z`7@oNz-{Dsi;Zs(aVy4_G|e-f%qL1A26Xu5B%i>N)Q7_{B?nn^I%I~AXo*?StGE!cS(g$i<|M4$Qmh$9X0;LTnHJ8@lu}2)h zzm8nPgIl(S2OrwTKVIptY)T-84rVjuqD~EG(x7wf5eLe0;|l0H^CTK#=y3n!?>`X! z-*58lkxWbYB z&~=5gN%oieUBC+i zMqAhxX;j*@_N7n->xhEI(uWJ*ayiUCJ5V_;dIW1NF@@OLCaEzX zx7x7*zW3|_5|w;~gAQ7V!AHrN4kW}5xFB95iY*u~Qg^`NpAc?2W|nl|TWkw0 zf;Ir5zAFZRo4}JZ-{=I2Nhe7;MC2RAa2ksteCG12!>`gS?2A78bv|Z&IRC5@!iM$h z^!p#}z;}6c5iBb6-z)vlCEq>PfgO5<({)R<{mnt!U1|UZc?=}jW867* zz&^w28w>#qIM_LIGzeN;{P`=xn|}Kr!oOc~#h_zx;n^q3&lR~5cS?O*t=xGtb$#jhRUv!E{E z3yTa|aNiwmTet5B_uk*$@dNn%HrWyy%zA!zjekmqw!7`~8vt$KUsdK1cHL*u?9KTe#P+TND1}BVXXZ%I^D#Ash?; z%M|G7c|CPqxyWoC1XzKqHqCIFh=&~UEocLWPui>*F0`PesPMPDV2afE%q;t^WMi+Nnj9t=$D#8OT^-gerLHK3z9 z>tuPm?OnJ7t#StzG~9s(oOSZCt)F4oG4)J*Zj~k`QJlv1HkY8!YlauHuwPg z4}bYb!drj!NBMvG|KM-_x%cywefQam28iw}5?s~bR%T3nS2*}#&U^0f{!Yq%_`y&; z0BxVk81A~~K~C+u!oh#h{K>DsI=toQ^1pm9fh$Joh;-pCz^?)zqwl9^@PZKg4u7Eb zN5A%}@TdRj)#1;7<2B(ge)F~AFW>Ux;jez{$HQO$_D}HJoWJ>J@9ur;a^IGH!E3AQ zYyt&7j|sJCNoOhxcVaZ^Ow&jK z={1Fz=nBWKZiG0|{MAQ4Wq^`8IpY8pW0gUK^V}e!%a%N~DaJXbt5)VGO*>E4#g-WC zVj!|Oc8U3z$Vk4$R3{%ZAIF?02ntxyQ$uRINX1>;8zp?47U4jXdiHJ_nmdphjx4>HWYH>K+8UL;J5jxGsR~sUBDM;v3~w1j%wJx zb2s0<{;AJjsY)I4%Mz2pwubwE*m&3mk`c!QE&L#3A<+wm<9>4Cl2vifup%{>P*J@^ z)J<)tPtP3XGQo9ke!!uwFxqy7W2w@SHYuHbB)6edEgv9|FLl!3V7k{*yV15bsm$BN zt1*p1bEUU^DdeqEjqIqKFIw7m><@S@mnRVs*OVAHz+z7g^QAVZP}eCFqr0vyKrzX3 z(8>SXC%;T}7Q?H5@ag>BmlDuk{XmqU&PaA(iJj~l~1lm&FZiw zc4HvQVxl33HCJYJc^fRIS2-LLU1-~ye5qH-!T!^kP5jUpV09!>bhgYOvhM{JrCzEF z_QCRGUFwt1QZ$4*@Ex3o=#~AEhi(dI=v!+w;4ZhLCHEVm{*N1a?yTV zfGwS&kby@GKQUrV>5$}s6WVVjwUe=uGibv42s8MAvXts5vzCKBs2o(f!kMRzmpbi8 z_;`OF*@@Nx)`?Evy@lpUZKh72O0_wkm*;h~AvU*VF=8yOzK@lfmT|dRse=uCUs~O$ z(N;U39!fEyj=keztZ+;;0EN|qr&$7(nJRfelQ`PUNi#=Fo{$cA(G>%JnHXQp^t|q- zJHr>RxQ<`3KjEl@x>}%I?*@l+v6Hm=TV(wAk5SCPU zY3A4qUYkPES`0t*lW$U6@THG_P%Xf9m<8H4jCGpHPNPy2)l0q_veQx$+g+L~+2RtW z)etS_m<^MQR41;3&MZ%Clu?OwfY=Uu1Ts=MwGa3lS2&2m^JcIGZAV4X6ZY_nwEY3` zc^94uw@L9EX-mbg{n0z<#fQ92$7fSK zrO1#+JkPjP4Nsaz45gbT8_1u324@m-k1Dw1S5jj~t``AR6qje;nu84$`>)K2)+g0jgayrdZ4CF~;niGk1iOPih4$>@D?BWFQ z)v%2qp6qR%wugPjf@8(U%T0O9$@Hs#)pfUr%>%#W*#=y#-AGqb0Dj*8Q=k6^+cm6P zySj6*!Bv{Q#bn*k2S0upm($?=ANvyT7a(4lRDf^yf8Xog8h+sQe-vKw(|;2F_Xp(; zz&6O+YD?=TvET4Jc!n#lzNPmT^gi5q&x87zkQ`ymWfnb#*<6|&^Xg?Q+-~UIBb9`u z?ZwG}Wz|?kB{7+45~T&HLX#82AHf7@Mus}G3pBti%%g**(lJ%giFyPhce3bod9cbU zZ<9Il00CFu<)e%*z)X9tZyyTxh{5iBTHQw`~&++kOP@Dh!;m;5Lr2-F} z&u{ymABk<*bMjMPxH5csf}eRY;5$qo`IP<*Hw_M5|38GkSHSaRo?Z;%zjgY)?-Fku zm=gG%xWD>`4~6ac!Y4qRyo;9ozutGL_*3Ft@4qxYx6meLa?D}FWsiL;Q(;a~Mzr{) zoS`$gH2BWD#tAUEY9&eBasVolYA91%(y<5iC|2N(fl-Uu1v;VPKm%LJCjpa9A_fQ{ zC6my+3NmJ$6rQMTyFsUqd~!B5-}%>UF12pd%rEqE8TEWxbziTj!*p6&hV6W308XobYRdw`=gZ#gm?JxGHtvPq%P$00wDB&nni!*!N%l z`VBmYAA96My+0EJpd)|#doK>}|L7NG*?#flnfVao+t$e%P*nl5O#h;boa~-_(gtxTd<0o`*HyqYiFvH(% z!mlv50iQ)(_Vw$-i=K6+D*eC!jGw6ai~s&X{Z~$TJsd#}js^bE4#(p7qYobRvpD$8 zxqtYlPlW$NSC;lX0=R8m058cFM(38q?De?BP|6@GWqiv}V{Aq##axjR9GVJHR?N{N zKjOf8)Yyt5C~jws1pgeWK2rtzA91W&l6CKOUn{c3n>qBfABuYHYN>eTn|?K`@P!Y* zUoEe;A#Ds>(bZFeW+Lfa#q7l4M-;>^wCGVqb!Em6b|_>e&zsAN@jOo-ETA+QGvu%d zPwPP_HJ(>=z+$ct___ly>6bT`0<8aYFE}MU_rg* zIp>^uTzK*cNAS|MIEt`M>%9J{&&&>91;Y{zZvw(Mcy99-e*vDLnY#7Y6VfZMdq! z|Hypub6@AHHTzzY>whP}3=Q;$@y!Ztz}434e&uiZOQ5HmcqD(|kEqP7p-#Q%A-cC8!> zeAaWrEqBo%c~iLbi{In{kn3ri9!bidiz3-`jAvY08?1{HV{9f#=IR5^RP@C?@?4MZ zdXEk|Ppu*-ZbuCbb>^x3#Pgq%Wqj+S?-YYXUw`J{Q@-ElslFIq`E$R{uHo|^exF)H zkPbz(*wE91W}>?jNeZ))UDMc>lILcNqqdX~P0rer2hA)VTaI;86W;gjxsv8FpJyr0 z6|s#tFX9QQy&U=BS_-Pocfj@oUa@x8)opL>SgmpvcY{I=6l}&tDVM{p6TL4s9_mZM z#v5P#f`GqEt^pnO&;QOp$RD9mu2u7GRdOhn@>DlJlIo)kN3N&sEeEkKC2M)MPH{b8caiFFTVz+M?dJ9PbZ{){ zR4KVMmq~SqkeP)qHd`tHqWt?M?SG|=ANj2PPmn;nn3kTVCPRyzYZZ9}9)2+aR}uK0 z%(m@2_=*W{iDCckrsuBx`t)GP4q>ws15yTo+Tp{Y4)1k#$P$r{SB!JG%+V6ERuUhX zDaLUwWa5C5ia9LVKOj4_Ry$*vgK2fh#B zJ66e`Tes;6Z;@6~5S`tr=RXs*BW}Isn`&vh6*QhaD#WK%Oz?hs(y^tQ!PkvylHxpv z)39v?XbYv(P)vzJoGHl8Ty4Q*E@5HcK`3>zqe(N&wU(Gn*f48wX;ZTg)%=Fg4_~E? zlOgTfHb^`rMN4(>i!Fxf_>AYNryt+=m212`^hba9KK`<14doe_otG$xWljVJ9Y^>= z#Ds8%B0Yx^qU#z;n#{5)K8bl~#}U7neL|J0iMnOWIN*Na@W{ z*h=(ZSe8SjT~q8lofug~_dGB}p&k>hh!pxJ_Zbdw*ELsgi54-YXj+(CO9PG#G}7A% zPon`xa~OWWX`uRDPrL>?D@f(&q(Zz0nBPClLQuxUP#_rE!w&^_bS$ZTa7sL9A$vdNwqstG(>7Q~jaChP6j7A<><4Oh@S zm&0v$-XG35>FDsc@Ayb~=ld>g{+1Z;pc2JrTIw{;LlUMsHzxqMpJt3`Iiu9_=cLIs zZE|$hi|x`HXkvNgVr9%FflD^cVi|L`0T)t;kjX`ktF0xW$T2iz7Fv=OozY7D?$(AQ zJ8RhyCF*L#=Lt~J&xzf3yS1l?O}bF23~PTo@EMiNiIAph|}+!l?9 zN9V55otLStCyLlorNzcv9)(TtZDoNhR0nTVv1PnJ6lC%amxl^s0cK)nMwq6#F(xh> zJi$>y<`9tNPR2?DS#5&>!>AU`IG*GNdcqXw+xe3rE~j;Y2HBqsmn)_US&UPy}~I^+(IEY`R#*_%wp8X zFqcQP)sngTK-RvNfVaDVU6DYZ6XYPMUk^S?N6TbSht^O-m>#Xov;;(U!G=k5)m(@i+5Z{xos{YiK<#{kX3R0H&4j##%wwl~ z{>dzAYD6U~lB3q1L2O^wLKl_>8;i0Nb4+zlbBC(fB3ny}ma2yAdbTIG9#*voHga3~ zuLdmGaq7en8!0il?wlthdj@!)Z8fxjwf~WNg`@KA-@07-GNs)>Ab&CK0!FE+wX4v$ zPh}UAxMDaTP+v^4)RAS1D~tE-&|Ds(AjUq*x-V%i&dsRp^)~9=SYn%=?$QEfCz6Iy z+}*upcVO|CY5C4B$!8rl=Sn^CMYlV)czMX-x|7rDmgKlCqaZI|*QF6F{K!hKkwUrF zkxP#rN*Gr{NtzMkDI?bqNXvBuVyQdAW2;vMrUWzi@uep#dED( zzWAzA(Y}6&cutA9I?a7Ag_hz-79SUAC>=Rd>Uh%3<+2-T2FJ?wBJ+IKT5}WSxs&QL zZQ_^^f#f3xl2vdqo+KVo2<9?rmbJrE(qo(67bo-EDBDNoyo{`1@j<=hzBsv_Q3PC9fTljOMw7A8qLHMTm1<7w_|iIzQ7gA2wX^;Y3@@oaN3| z^5EfiymsOii|<`R=K~|;K}RW_d&-ecUE6heF<#J?+e%#~FV~SZjc1zd0=4T*xt>-p z)rAw|ZXXNt+(}8Z7FMN_tCE6P4!+35E={h&ivIFi(08@gf@lTj8czT zOc9rT(L~6Odln~1ies7IBr3(J5>KqRY0v*AHNW!C0_zRUNU?mabV8l3dTm6%QfNHA zWmH^E(>96(2yVeGgx~>!GdLl5a2ecnuz|sy;2zxF-QC^Y-Q6KLfiw5}ob|0W|MuS9 zHQiO!)mK@)BaQ4c(s0yjK!|i13?cy<$9~pqQx7ZGw9`!-?^80z-@M+D5~;2cGdNLB zSGu3O=$u6?DMwZ&DJwWWi94Dp5$xTsY#7h!nPi_ylg_rL4(< zZ`k;mHmh0no7%*~xr^uc9l5b!KaCL*e4%`19Xv8r1$EHYF(*7R8Gnj*P5wic+YitT zF1G99r`(yg4xmx@V;UCCr0-Q=&b3YcL{S45$NqhMl2>tbt3IN%OkDSmuMyo~G_0R_ ztA>sk3ddwS%DOSrKA^f8WmKC|ti+A4S^O{MSAi(bAyyS^ipV9YQS~|#&z}nt7MovF zR@N$;1Z7sYVZ}GaZ~f%n<*(S*=%drg_KSabnQ8mPvwcM^a;dvfqY@jgiBLwUikM&n zsNRSzk~)^hCyCaDSj+#)FCcSu#j258cf2Pxi?HWpIrxI9*>+-wG&6l-e8jk-^$s?3(=@6ZX3^q)C6kBFk}|i-SIS zHoMdQe3@@Jsz0Yg=h_%37>x+gPN@KKh*StA0yNncGUCSh*S9<=w# zx|#GtPDb>P`38nPehu*xBvMbl6@rjTPpNV}yA(98A0UR6BrBh7MzWL1vjJbLuI}@o zfe&V8wBq*q*W;lYZKz}+>Q6X-)L9JAMi8Hq@=|E_=q5iXg?-qgryhNZR1C=6Mm!>6+d_8Dcjy*7{7kjf)sEAuH^tWp!k7sC$I z@sX>P#DmRkxGT|EOxyMD_ZR!~2xot-iza!h^Cipk6Y!2*P(Ut*kdHUD>-dT4s}SQO zRSk(vGoQ!lidJv$J?Aut)LW71? z7uWFx-G+fZtPdOueR`CIqTdzU|mF{5bmcf z9VoiJp+;o(tF?yB-K$A)F{VU)tKHD54fBMxd^K@^7IujenOa|2X7Tb7?ABxOiU;=2fljtD9iB)w(YpH>~049V^L$rlN zYRhq8fce(<+@l{}*=j%ZXMQM(DM{wm5OoPyLQEsjIakfpv!+WehJu|hH_yJDCp#bL z)N-rU;^+N2;#66w#u2{@EP_qBXossER5fIH$I}l&2y-HN8E@@7mA3VKXVkcow8f*%6u(n?5r{HBitqpv(R-2N#2?w^bZyb?b<=pbT=j7DC9;5j4auF zp=t2cmG`n9ob_Y(VGGnRM&@i>G1Uu~#GPzMT%{?DcRic!!({HOA`R?U$GS1D5G~8? zDs|B2^f+zN>h;9r&jW1ac+X(oV!2-um zu>mWRP$%72EM6t_TYi_Zj{$cGvaW-SNzG(`rQ@l8LnN)fhHx(>RC=C@(^R;jX;~<+ zk@dA0Qsg7dC&XUKjy&9Tr`mP~8FA0duel4oHiHk>EnFWPr=#@T#G3X{pXKx1VQSt0 z>Qc1=p`iEg^i?UdO4(-aCLpzA>hW-zk>evxYRdiMk(9+^=H5Ym9nU|vbCvVg*Wqpc zq30a)tY$mgdi+LP**JNyL5RO&`13n5rD}(Gq<&%fVdI<86DKFb&dUTFlguKF9*C>*fVdf47KR&vVC`_WgY8& z!0WZ`q=2svJ4MoWfxWF8-WJd>YUbTdMtEo%Ah7A`3|Bd~572_*`rIskz;o4g5Y)@} zzHj)}e<1I1f4c3bLLunT%RV6xGC}r_r&S&ERWE$IOgR$ubfN6v(z{qa!Y{b6p& z>lJ}>g8&IMN$b1XbN^KgVq14fnU&D#pwH>5ntMG2s}%?NZ9T>?Qx>%RA=8+Rx-1sC zj5XF~avag|3le7jyrPy&#+cfVt=~q?X|7LkEALK(aV1VKeLUf&v;fy(uNq*mR;@1@0 zd04Ym3?i!!HLv`&As6OkP8F-Jwv)({NqPEY`Az6^e;d|p9IU4~v>2-#S%!lHDZ}I< zVds%-k#SI0Zbj%Of9uZtlD7z$+mmt}WnJ$pYGm8L-Q$2JQdu=D1zm7r8)Y=&F);F! zSa*Fva5P_F+gh5QruvCcoTsc2LyN>SV$22cARz~%hER^O?WF?87wx~O*HV)Z#(l+3 zA!`34TVO$6Xh7~r5nIH|MEprH7A*>$sc(z$ms%eICcB-=$f`j%2hywxx7$`cK=%&j zQOnp%=9gU`BK&YKh)_xIkYPzM=7@s8FyeA0CFqq3cj5g)Yfek}i`>=95ba!L#-5+t zYbY)xC5Iwo5IL3N%K#~?H6tFC!%c>$?jsR!>RG|kpXf8wCYoUPi6!vJS$1*EMWGoS zR;<6`#|122){B>8-D@VEA#v|Am*Oj!G^5H?d689wrZD=Jru>&SqwRc~ezv>Twdzt2 z0UaMk=%+YkxD6n0TgU_GsW$A>5Zhie&e`2l9LuRTAIuw#0~drNmj>x#qp4yIC3em6 z*ae2qi@rJ>u%Iu6iQDEC2iH$6ZXKG=-83z`fP-UEWv#;qr8oUlQ{tyx0{o(Bl`eH| ztJZCv{z~Tj*hw&II3mB2VM|jeMQZwlU>(EToY8A&ZMV!hFuY}HS{B-8&Wk<#lSw_^ zwE}f61OaYGhBDS70bY#yb`BVTV@+hg6VeOmb5Z&eodc>i?U*4B$Fe3s=RLV5vr3V5 zY6;O_jr`l~iGB}2_2B}kH`_;!%Fn7|*a*U4EY-2{A2;1mpt41)qGJnDG*&|r>^SghxNLf;iA`U<=R{VyPQV!%!azhNp-Lyl3pW&$1_%D{tK}oyr~2b&5>xsv`<@%D%<}Yce@Oo z&F*t@e9h1B-ut}dXoO_eUktxyOvf4O&9An(KD@c?GI4HY2Q>zPEn1*l~qavZhprDxK5(lnEP!fH?V6t}AjWp9X?60)`Uslvj#C|Gt)*Jk{^% zsteSKV4AcS^JCo-H=}1G%Wl_pxHqzWn_P0G`xYfD8`<&0)2|VIp2xOM^!UY^wstL% z&{8ta53K-JGA2TMn00`SDE7qFhv?LYSw)oU0s$}m_|Ihvf22BOQIqfP9!;$=FS~$x zujHVaJ-Cwj>(OUdr<;#IcO^c}MF$dz=q~jR= z3Sl9;INuPzbxzxsNe_%5StwS8B`ZQdRem)9R{E1Ij&^!^F8zSV^yx<1yiVRcMKDQU-<%x7&t?QA7t;DpS zGDP#}|FPy0_#|z|XHDIhXRtnymcg;6{9!EfHR52@P^*ws1*19F(%YG7n5nrGnwrx@mMl%cG=8_|Z0iToCzbBPiP|&Op+?+v%pZalUD)NvntAlLTP;1CP5p>)HI?Lz9h1iQR$#l0z>4!MOv`Mb2!m@fD)-&UNW zleo(3-^vl~pI!Mszo#AIU9x@v;*w-P>d{s*pYBD!>!z+6{$utDC5%)+9 zQjkyZ_rJaK``cY;p-OKVQr;mX?A07|WpMKu`SZXt|Y=Q>% zu5}c;j{0_u!#8e3c8B!*HI(TI7bitVxh3BxXzykC#9zi56cuv0imQNz`$G}_ zb5SuC_dfTotND0EPc)Z*bG3?*c>&J9MdXoP7+RlS_2Ipn<|hWWEH15jRR0L;3F!* z;h;j!nKJ5M)8@G~{^t#W^V&THw@AA}6Z)pN?7k%0=LCWuJX3omSlWMkKYuY`U3=f^ z-S#)aG_gHTQQaPPptj$Feev(b*oZBSJm@)= z7YsC7Z8+bu{b%&=EN{?W-mNG4W+#;S6d*n;+qj8)(c;Wr?`wU0*!^;e8_E9{rXsBI zFSxalDL1Og{USUza-Mq9pRuCN*A`T?|NF&Sd$RMq;bFsGj7#D)qVWs&?PaE-JEKKv zvA_q`^Tx}K?WSA|j6n*B4H zm-C8|u%-?c>q+0qh=^}nqOlQD>_}=ZEMma^$iGrFUi8znrBPG=e3XY;dkS4Q9OUSJ z$X^B&;&Nt$e<{Yni@A@})U=q0`dF4>4-B{$O+v;(d0IL6j*@WuuqoHB<|m^={?T)g zO#&Js9-HYqdbYuaq6+ryZgkP6`T~+sf=Zece|DSKu1?uMH82kxE2iP^tvHIpz5bY& zi7Beq0#)6TUN7m(peg0+XVT*HP(ESR!N@`V$IjXUzPy6oi}Re^8`v8Umzj&L^Bl=O zG&U{g7gv`Y!Aq4N^kD$cSMaV?A|WE^T`c$>d&+tkjXOcYBz#NfcROEueD3Q@ZB$sg zLB@F+Bmfb`u*R5MR%bd-BoFyx6KLWY;+m`qkmj{v4K>pd|6QDv_><}iA_kwi&|Ao7 zEL$OBJ4eD>ZG_Q><}F>z*$5)$bhH|Wbcha}pU*5TF4k_7EPdbAkG#pjxF19wSpn+S zG|jT=F$YDdqJ2D1ZApycqC0&8@DFvk#*tl~(Ow)vJ~Dek1dW3$km}Y_ov5G2Hp8zRXV5TECW|qVLu$x=Xtcq1R}8ULO6Ccq5S=4D zT_AHbG3%0IVoqnWkAXJ%tMI3W*;296Fhl+l7*bv$P03}?@It9PM;~Q5Gt2)aj3{s~ z?kEyNq~j&!B{4owyLdi&HarYB|1YT2_kIY=+hHEc?P>%;flhR|858adf_+tJ%|~-Ls3At2pz-q^EC%r#Ys#<)afrYXY={E z92r_(S-H=Z$x)>Q(SSa=8JCHUIjo|nuXgDy#J`HSJsVtfMVVqQna_kd1$KO~l4#k+ zNj2=RnGc57$4zj2u<=8wTJzyM8w$;oa^IP^87? zGyJ?#ourrx_$3CX-ZVim;-O)RCvA^M6Fj75k2h?<7>2hs;{Nemo(h4fwdL{0UY&s^ z;!49Azv9>cZc$d84$nmsOpva=SF4j$QuK-_GaOr>pV&FXl zpo1b4!bFPt{5ka?aYwT_`9KL`^@0jT-wJm0Y6mvcWT%{-JwR4UMwcS6oYWkY@^}^^ z`$@txqB?VVSV2|c*?&fUDt%9%w%wO$R=sd{I2IArbg-T4>9G;D_O8dtWs~*5E_8-N zBK>NsN7)(gz*S%tp(wMzEJwcNM{J!^M|d8Ph(NfRH$J!+TTOxqBKGB{XxW}q4rBR0 z549yo5&RIHhG^=Ba6?Z&7k3tj`eX4fN+C?1L^y|~xug9F%)*H{uYtkOmJ2^QMpMjG9>WKx*ni}yq;7sjn9C-H_jRi>>6$L`kGw6!=AcL1dN4zhjoUzcks+o@yajEBtt;;QE7J{gFEf zvzB4liVbd`;dJqD!c$?$A|8r%LLb<4t~MkJ2|-(qcSBkzzFJUDxiBK#+Mr!)K?kmR zqK;Q7>Y&D(Ct+5!HU+TIr=add!dMhIk1Y`P-DREuFK3Q}6qNEgqxd4OJfr;^7nOpv z9Na`^of1O2?9y#2OqdjVoBKd34XxY<1~QT#j3g1%UaN*(C?M(P=H4#%I)Ea)iTkgL zX!BcLg_O$8h*$q2IJ009x^QG-3Cav&`puW*anqSx&DvP4&;4k_dR*UO)c={ z7o64(_k1um)bgw+O7Qzz1W4_2a_E;+gndyjSjH8-*J#FcjZ8+Yf%G~gojoUg_tq8D zc&!Mzm1${7w;DdRYR#(`nWNX>=xH(x*Wa8AMA8-C$QnMf zacvxJcO7(m`u!Hi>atc9`&O%wPw-<-ai^;G!nlr)EqzNghOAS5-w+DBg|9S>3gym` zMKbuV3HM4rnVFV~iOVYUwHSu2*3FL?oWpIB`BTA0#Biao5V#)e~wqaV7Z{(4rbi73T^ngM+6LQ=; z2#DH%7Liua4P2UJU6{(Vq|axFKTeZVDf6vet*#(sN|{fBKlLmQhufDwlzRM$mz~dK zo}+%AQ&oDpeH_11*}=1@YCUEdi)A1^KFgh+F$SIyw$YLKhp9ntiP z@Uqffm~KwlVmVIKJ!Zg191O!wMMA%ZiZXv%5_ zHbluGpk`H%67gkXvM?OtRn21jh9GS)h&S<7I3O)qqLzU(LqGJek#!BU&=_Uvo`$C~ zlM*Al!-DR1BPQb;`%Bi>O*;=asa$P*)p#4tROS$0THH2r$)|SdlU^yVgXgm_-}iG- zyRAdwbIXE7+#P^&{=B1gUCo#^v<6Ham&NbGIWS*oj%~K5{jpelTBznw5>-^6NmU{h zs0|LUNLze$<|W%qN%xbN3c}uw_Ad}N#mBi4RwAFYQ$?U~#3Wqe=xxtK73@GvpEeph z^!k94^v%s<^3+?b9BzD$I;*uhpBZ!l$?dAKxv8s)SFecBPSiR<=br>Y9Am2mmBFDb2)n=z2I(-~jd1W+JjsC2!qRD5? zDswB^%nPc!jT9hD4SS0t5M@T$G#K1%ngL3})11RoRF!Q@DZm#Z8bkW&mj;`Xf;c=3 za^uckqQ6fItYTkc(O?>R4rE#JMxk{cc`GlbccdVOBnzb(jZhdS0g~ zca=5eyTDUPnn7~>MAN$y46(S@=!c9H-#AJ8`QjY!Qd~)0r160!ociK!LKTDGYP1?I5*7Sm2}pO!5-MX6?l^7X&r+n* z#AeMdk#vvE@HOz6_v;n}9cVPPDwdpoVwO&dae>sMmTI7e`LSeT4=;zzuh!EW^+%F~ z4G0MVoP;goqs~3@VGW$|oU?biJsu7`G{MF4T6*@sa6E|gU>x_ZL~kF(l*hP9Fy#z| zMk4^wXhE;8z(8-r`lPt;-x7%+vXF*_09Z^KQ#y5QziwBIvwfvwoD^w9^i`bJsmyAJ zznRAsxQsEeG6}qb`O|=by1A$RACU0{EYTl%io@9GnlFljqzxa-q|8d~8rm}ts|HQT zfs|iB7_#{YWam|djQXck4F`%A0DM!%h3c3?kPHz7kG*i#CszA2wOpu`Xvy6y3hm!- zLp@P_wV!*K#>Ngpfzz4QX)ZsVr2{L@ z#drP;&ysNf6gM{DM52|c`~`dH(Lqo^hN3y~4e zl2Bu<>+?SUX9M2<(AsfD)@tZxVHtR&^tEa?#=ot@T0InrLt15mmm^>}W~k>j4jVO1 zFDg*YV4~3g{X^#Lo-L!Q*H&X;2=O~rTgauCZPg*WtHB#vbh>IG*vg*{=Tm~`)#c0` z2MiBcU(e+yKP~_k>j}61B(21-00NWEy%hd5EvELxM=hNLLQ-}UMAa0f$Fe9>kJm&3 z^0?VPd~N(m&Upoxw>Q*~01m{;s8RLviom9_(#o4|%AA!5OP=R(l}BExh{dMx7lA+K zE8Z0~^MZ0e6-6X{{9s1Qn)3xPms?g4z(#z!C7odjN5CfIsuaAg1jk+|6an=J(h9o= z5DqJadN`hz&&@mi6$)5`G{Q4m05am^#|hg^;`eDSLgPnE(26L4bd}A;ffV=-%^qs5 zwr%D32PE@;Ftcw*LvO?)t&wzJaY)+wP@GRATTU0eeJUwYpwD+XqGD)_&6Yda@SE5{ zqr!8>s70kp?o)t6UknvIYM7zuZqlvdGbxvbZ$C8U4mOksT_q20JiMsSq@;kEMIJ#a z+GkmDS3Hv)x98;yT7a`e8J|4gU@#%=So5W!Y5-{Vi9HCX$EpLzR;3QC2 z8yxwRz2`Is%iAm9sFi)1N`OnL<=seZRl*{MqKQPRc;Kq%zRORO-niIAh3{*)!emA* z3r-_L`go5TL5P%aQ_f`wnYwlyUf?QLAYn8djiNcQf)5y#Tt>+GCN8s(i+CQXDbEnC z^Jk1-)nA)x)A5@|I7HQeuX_>#GNIe_^%Cpw^t(SZJ! z!k#XHlBrq{nHIAMy4tsc-}`Re(B>B!rmKI8ss`XACAqXvQqX_qTf)XNJ5SXH#xS^^ zt8%i{ol|#nxd`(ugYNbqF2bp!u+IEJq#XmA0Lo-B{O0Bzwq+F|#<60Dr5kWVf(A3H zVyv%-xm}glT~40w;9zWeBZ22HaFb`oD%A-h>S?%Q6VXo_WDF4v$C<+u;kpc|ulpq* z<9`J@ZVA_=br(F-$65g~C0$L(*sj2=Lgtc51?ngoz|>!6tx0u1xJb(Eh9NK^((%0h$ zO#^v;gD_dFkzpJ1uMS8XhBBINFS0vj#h8?qe9RPxLCXpO0p@&?noK#>Ty-C0T#t^Y zx<24(DH|24iBJzXo$M=(QHK=6;W5WqZ8n4!i`G~DHMi3j9>z>DL>BdA&MqO_JwR0# z9ftKXu6pERN~=;tfYrR z-bmx?`nmA4V?@h3py9T&oqzMhtcHEi7Xo)*39Q0;rCPr9;>nSMXY}DuZ^AG?nf>=n zJUj`8piRFtoQ`)XNfv%Wrhi~;8~Rku@_$bWBT;p)zK`!)b8yGP7Lr=|jIs!-l>cv1 zLmp<2ZBgEdqb&F>ltYL19_+8T&`*K?`;?#Ik1n6n#y2o6bN&)4h(!UGFTR(4UCX;qh)eLia#ovwo~@) zugTtbrsE=isWmXQ32;Lu=r|JD;3Bi%L7esR>r8S|xV({x#5aQe(~m>Wxz&TD=gUOvmkcUeSmr|Ni8WH&f_Ungy44%kub9s7pPGx!hg z8#XDk$Miq9@SWwp4m6&4Kj$av!4gjB>ht~$+09g6qr#b{v>Ya5Sv?9L-eGf`7+#13 zoMx5xHn3gh-9{2q>ng^Q@qxZn5(s^mCS)~q8>`^wwc>d;IoWTz5_>ptrJ+qtw`VWZ zQ_$X~WA5DJsTU7l65WzZMsFyO1J0US7XIp3c7?WVsBILi>%Av)@OTmRsJ^p~+R{@T zeVLn4%tiNta!F2CX#HWpU66oIJ1KN6$US$4Y6mk!$>1lhK@pGlaAeG0`UOFeG7b%N zV)E&19-AUsg;s*R`)#!od`C5L!1?QP%=5DR+y&sg?+y$;(|_DYZlvCR-EVLXOIw<_ z+e5IPFYk3x{DpTziBF__@Z-)vY&O?j(n;>_U4!F5UJ(mfZU59$0fr{8*=bYx9B^Sp z_6UmZ0KHr*A?@d!2WLm0-WuKJxhGY9A<^5YjwPaLqM{y zCq>TIz3wgxcC8qE?s_W@$62j>prtoFPU*F4gLKY%6GHdn|3+HMT{^AG#9&;wDAbKa z)pOx<>=ly;hn47fEQTfMe2s~nOCd#VZ3qmqc{aNHPm&D#jL_XFo@5N1_BHS9wXb@# z`i2J5`oD*L*_cD@O#;N)86>Xt@cf@(k%uLrvO`LX%c5Yz4Xb=fyk(dM4V%t(l;<)? z`N-QStvV0SPa^&s6RM9)O)=3)B3+rjVWVhY{U&h?9-d~~+PXw8pa3_lL&TPvpZxyc zy9a6+I13clU+z+P-Vqi{#lTc!V?^?$Xgqn^PS?dJzaoQdUyPU9|K0w-FVrsX{#IRN z6_zaaJxzAXG5MjfKSyPbvmVySr&lcOxf~Td_y??W7jgfOa2fUX$*`W3e=C>9g6~g@ zQ*D5Xu{0@oIc41*AJGWwj_pgh_nf2u(+@6V2Isykn57HQ%g;D;>=MA*A7S{3QB<8Z z7SEGk%(VSGuN75K1@98=|ECtN)q9^s^+*oXY*i{lZaZF5LHoU^0bK!3^ zl|&@z6XDj_$#=f6?gE@JE4a+{u{3D1F4W=H@fcD&pMu6m-b8cO^e+1UR>kxH<0Eu4 zQSMH7E?xChW%M_PlL4p6LfRBy<`kQ*Wv2&%-ijch(*K{5Zw5AZAqJJA8Kt^phXR)< z567}KrW0NVjHU1s1kAh=<-=E3))dIMe4Y8w6NX*TZg}D<PLoJZ$i#$acQ1Z>%g^*lXG5yWBrI)$5jgIz zQGy!f&F*A??R_|rcxPM_(ZFq!1ct?UzrQBiJ_TN&v^oVVuzk3!%h^*YjioZYl|-*RleDlc^o5_&CVGWge$T;+8BD=8JV&DPW+(DOT=%**eO z=x@aiXu7YjoSN=^!K93fnFI?Lo1P-}7q`qn#=)`WNe~fO@aKX$yUVg`gUcUOi!?2ah|{lnf&{M=%9 z#VVIbnV(1_n3WA#h+%C0t#p+8om{xmv+~$%b`UmLQ`unl^;h9>oog-~P>8@UA;??5 zb-wa#)>5@?6HusCQrLQqwp={}qu?ikdDSjoUaQ=8apy{R*A8_G@Vg_vUl;hsaNx`S zdR<=J=`pQ2_sflrGGj(`@G31hC~vI%=>3>@yS<0n7zk{$ac?@&jA0zTPD|F1GHGv* zsjVFnbSWJsHmkqL4v#_8E*o7z25GF{7{U0 z-xtCd$O5s6L`;(=5pA-5`PFnDnQyyU|0ohE{jznN5fIs_TRCuQn^M{U8FxIQJ8_gI zw|hJRud&`aiAR1g1C|v+0?wEXv*-~?vUX8uDdq#gcHD0t%gITe9(Q-XIchT&E9=tO zr0QXNy)lJta|-dv`zd%PL*m`6)5J6^j6PO&hGbBQxzAp;q^@RKPP%iU2gmbTw;e|| ze;3-cIy^}&D%)FpTr(@rIrOfLh^C6DWxS%`xl_-PAa>nTUM9B8Rl_8368HrH+3!hy z5e&)5XN=rGcsT+cLdjSJjGIi9rVH` zksk|K$5g$Gj*_1k8w+U0a}V@>xlg`|e3&r|HL1vhElkj(vLAgGb?s&1Xi{BCi(6FY ztH1B&EH&+|WzO=gR;r93{OC#2I0eJesW8dZ47$^H8EBrpjE#=+oEY0?$zPpZ{`r~0 z3TBN^icB>2PQ0bL>Qsbbh#U|T+-Q1mP}I97`WhjWjE*Ug#uAH^CT$bJSQLBbNV|>B z%`(}rE)1lozmJ%7f4(}0t?WUEt9YyD-r+iOvl)iS=}|U@v_4ZwxJ^{7shq#0T48X( zR74jkJP){jN)1PCy{tT;qA1*hMIt-M*zVOj>=AlX?ij;^a?0#tY8>}Q3;(LqY&qn$ z0ccIM1z}FJ0swE(;Xc>d4muSng{W4oZSUiX!NsnQ@G1 zZifxpuP@FM0q1-(Y`~rKY-!zyM?I&`j@T=4Vmgqu+(>%sL66SELLw}=>(Vcm9lPF# z-Ffc4Rfl!iyEfuXS3%xTkEj1pUs%Gefh34rvIp#!V`lz_b={kO_c%02Rh*kfHoz{Q zjQswP`h({!$*nEoLFhYyptI`<-4jY-3@}$)Bkpu<(wff{T3k_qR>xxYHVgj5ZTQso zLO1GAmq)oAxLeP$b!ELP{Z>{S1GLXXuidVTEeb8=vo{`Ij&}#%IUSfcGZAOk7;+O3 zI4Oy6*%XsP_l7ZTdAV7H|DtFas!jr~D&L#BDvvAy)~_>okEA~n0NmVd7hfvCbsJyX zju#9@dCsN&ekebpw%wbwI~j$`bnLEj>MCD7=pl2?Z&}>bo@8`=TYfB~)w>vqrZxkf zsh+>5a=4^!T8-jbGu#O>pAE<-%^6WqRQ?>~4`&3<6iYfTl&2!wdYl__7DhlT35PcQ z(%zo42c_Mk9E!Jqit2$kpUA-{tn%6ca|uTLhkvo|S4wpo2TCgw8|NErGqbyq;H3p7 zZ+}BhM#%we(Yik;wnvBR)up2HxGTVW4Aj(U`#mhibbcc*Ps+lUitu z<}fAu^N;b2*WImi>8WH3!+y$`JRSkFldNVXnQt#7|k;t%mLSauKyXA~M z7Xi;T;qpSx*_w?5mRGqsDoD;n^E=d&LhjKsr=w(m8J^z8pRoeLcz?nZU6`Xx#XBB} zCJ@kgT%o)8kcWXz!GZDF`K{tYkmSnCR-kcU98>CFbMy9Hfv3#*!75N?^_D*vaSX4H z8OiEIFEik28GLKKZd*#`rtndoKl0u@-%ARO!zBz`=s+VZk^l0W=1-I4{}UF{XEM?@ zA1ezg0{*s*K`eX%a)-B}=+7G)!~-?Z*^cp4sVgH=8zo6z7qqE$cY8j;W7vdroRYWU zsoKs4GjiGMXU@Y8(lK_Uh}B{ZQY=RiVpt2Ub-K zTjUwXn_z03)mOGC-Sd4>=G~`o=&HJFz8`plJtR7u0G=+m%-`9!Ix-!EFcwl_kk}Fu zE>AAw#d;wHnO`Oqhnc1Qi2r!|(#+H8hf*UE`8RJC)!T^Q|LE0YJ*WYr64hq!-TzCf z5WB^I!d7Dy~z#f$`{&enQgkD(;in07IUc6$vu$=bk|SVjk9ntOPRcpFJD_ z|FOiFbym*1_2$p0JeFA>_Kok~YbI876gi)H9~Va|_3CR!aY1cPVY9EIF6*-YGIvR<-VLEAf{Rx9#=zITQW6G<$g|zC(Cl|V zDy!5hsB%g254(Ms^++3_&wOO!B$f>PBTiZ@y3e=K+K@6kFq_F=DKod4!wBHqVd5<1 zHeRWQaIHCBR!xHM2Zcpv-~RHK_gl8XHnL(SK~r6}ol70Bi_P->amnq@agJ9kHBMhT z*RYxUy0GLT#C`V<3;VmI6cypIR(n6vGO&JIyM3#ti|6%(d5=NhNlf9gcq?6@M*)re zI*T0b)dJPG5fjjO$jI7+R5b24bC=H&LpRFte!YqC;1U1Q3!~W%rtf~?M1G_e+D5RG z2oN6Yi4-(ZS<-^WjsA^!D%R7kZPvs%_VLbV1!vguYSN^>aU3+22`t|Mb9L2pn zzyFx+iK!lXqQ-7;blDcFuFwxR{&Kln#kMi z?M8>McamOl28Sb|y^|S2%_Ha;3MwM(Ce%b2BL~Fj@ z_E?m+%=en~`bmt0uu9kENN`{F(|mnfzS<-U;P?S-L;lDJ|8kkA2hfKeCGpViI?dos z_+A@<_{RB@bF^(hVSXbebi?=1HXI4x$kM`}ifYk-JgwZoyJ#wr_YyaN>&*4-wqvE$ z+c8Cj8|aBs&Q0s@6k{3_)P@;k(IIR0g>Ain^lgL-b1g$Zu|+{i>5+8+B%`#sN;W2db)bBT_?p5Alz)HPmoC4VT zc~9epg$BFjVbY(!mT=4Ma)49%FN>g}pL$4Myv5#eSqPRvZzmqV9)9SMEO+`gW{bXh z`E&`rYDe!nzuSvGPKjC0oeq}7hk4w=K@G(V@J2FUud>`G(Ly=X1fsKi2GV@HJd zFa%4^`=+AGX53J{K2&lvkxgN+Z7357c9Pdy;;{#)7Vv(9@yh>_F&OmL+1eX;*W2*K zX}iIq?I|GmKomGDw}SU}@NfaN?F;rQTYl$!Ui{E|oksDPMM&sPx+4o8AonM_BrJ?$ zYYvJTh(4{l+dkYgs&dw=ApX<2 zVZlK_>WwAz+P6HAygc0D2fr{O@EwE4r!vOfk@7G$I_zp?&Ze@iHdm=lM6=<+TPca%x9R8hsDE%8{dDdJ?;z^CO6&@jdqXkoj5O~WB!4o42(6CN!ZJ5~K3R*jQ&PPp=-b)R zE>nrmb-#0q(k?4p>;N}q;B__P&za*N)+gJaKie#|dhxNJ#=mmyRAL3fG=djT8Wk(R zPyjK|0?Gg*Fn$C8-YY`-mEUfn1N{MHGfP9!OnZ%U3~nUXC#?nYKX?mEpOsuD|MkAP zpsz^+**VF80M7P^CeD_E#I(Qcq_5LDvJ`-t5y0z_ZteRe)rNSOU$~|1GgK35{f-t$ z+be(tFIKqm#ZKAuYs+oO0C_mu#hZI9Di#OOaWQxr(O*a)x%{J$OR4_k}#G-2Ocd18p!WA2)*LNLX{=Ye{-nWGmIo*j~3vh4S!) z;UhlTbiuA=-G+F3C2KmKc^u6ec)bwJldu~8BoKUBuHSBaBXxd7>%|Vbz<7TwbS_!M zKsyn7F7ShDs;Ev6$m28xAyOLlza$;IU+V3bVe_eIEUxH?q+|+fO);1}K8P=fX=IqM zmg-BM>26Ro`KagqoPFDOyw+er?|l3K=<%pjpv^R_rRQErTZq(pWO$O{ewc?|CuW^R zR$K0=9lZ_0t)4HvDSQpa<{T>*WGq{G@wlVu9rb$cg*Hc9`cbIo>%wffXK}dG^9b)l zC63mg!Wp)`1%KGIG)2-9W8N{DvVo>CvjXIusQ$9qU*?&59b zVj!T(;4+|Uu|*7u>r5uVO0JM0rDBV+vhP=-`MeTEzMKVyXyw^Ga|UbVM@vepYj>Hr zQghkw4MkIR?gIF@*P*i3A@X^H$A@p>Zw2Rn>H({%DOfM9pRvl#}}10C~nK2jZSXeZo+8DJmmK0rq=F@iI>s7)j`C8J}bqIlnJ;mu+B0 zaP^fNNBs|}|B`S+MmmMbw!9^(C{F6|jPv?4{8)GC zDay6*nXFd6<6&@_rMl|0qUtu=`Tqym?+Kek8(RAnCSo`xn6XXjt_g^hLTUEH6Ap6Y z_?MKp{w;rR#px8DK+Qy{e1D4i{{puONcL1~HwGMl1|k}8enPz*^E<8%yS9Eny%8fu zjQDngb#>N3OWEwCsdGgK&30avdh&_vOPMqs2;y>3>awYnb)ofQn_lU|Hlo92Soxig zH_(6s*rwSaQyp-y-Jg2ze^4jKuC1S^LFZESMvNHo*a3P6>kO@<)XtMTRqAxv$E#qq z{VV6_OXr+?lte0PucpOEiDjam*}5Llb{)0)3Em#@Xyd2eEWZ|QM`h{(XXloG3yZtH zsosbYBjjmCj2$F8Q!TB7rA|1$<>5+xl6UbB;ySI)4}5nI{!Y8p0NUDpvK_8@-x z&2oiPo@yNf&g<04v2*kP42$!3sW)Q8w4jqLc7E1Lg05pFHeN|nN1Qt36pL?hSf?F* zE2%?{zAlUN%too}q60_%Y8tR|#E21H_?chO0jEI6fb)~;cr1n;54?>^yHjn%BMr=k%0a!U=#E8cOe&!b|f51lQ z7;s*%PQv2i&am^rzgF)%3D)6BhnRPu*0Gvh>y(LHN6PrBo3&cUJ>=CiNbACO*-3+d zl_N%s81bEhpZUdqQ!7Wufb#}*5*Ft-hn-t+OEfx3>!kC}IKI76bkyx1AR^DVhq(CG zIX7NSvo9U<*inxdF=E8G7vA`bA5tqvKH#{1x;Eg97%^hRh!K5wW9J6tF9W zkt0Wr9653dnrTp52AmiyGe(XaIdbI4NvSAYcZK6rhGmW%IdbI4k(00v9dK$1WdkEe zjvP61K0p8D!pk@-W%B&OZ89qXGbj{Gxr)7C9u;&Js&1XYY)X1Alo>}RD zr;`B&Z1Ig^G)@pIeH&c5d0r$Z^9iv%mxGxWQBF=j{lp8%7z?5K$`mk-S}|hszLI8m zWLji7kwyiT1$D8QH`)LtL^cRtYNQ;vqML>k^ChM^@YzfnXNn_nNrA_DENNyXI+>)o zI9`x=KeF_#4YGB@g9}$`Boc_{I|MkI$H&+G7fOx&=+2U8oNIF2zvf$p>4caPa~$lr#^c*|a){1#%Y_oe zqNS6;gu=G05r{yXU?WlF4CTp_!eq%qYy)e_PwlC}g=Um71KfdZN;=VkJ$Xe6jp^&A zG^Pc_xBOyKU6UlgGFe>mIW3YAW5|{S&QoH>6G|44;(UIXt#QO8AUel6!ljRy&n0|m zAlj0{Nt$O&vE+-E{`5+G82C0DCT^Zfu`?i*4V>piT-{vN=SlIri7(!=usT!1)?Es* z-^?@qn|@b@-d$#n8e~ z@)KS~v!e!JrPxO)E*p{1tPS;TE)RvX*i=8}Bp)*^6e$CBxg5x3bi>#2lm%8uQQa#! zY35QQS!0tXa*PsCpC`#Ny&1FiMCTlhiiU&~w;axjzSJw=5I1)=lxh>8~ zw&|?-$#RUUQGoz!01DG3H)%}HBCt_?hh2e4`J53cwIr_>~-6&}vm zN`*8NMuVt9g}G7kg3?!mZEZE0^D&(YnF+;?r9pBmi8I(1*KAlCMcp89eqL!ua}B&#qULQfZChD(0U(76 z6q(J03|V$1cUcDO;&o%l3z(>^E#l zKKW|7NpoM9Cxs@NE`mU-z>>HL@_?$Ew^2%*Z3#B>7-F-BQc^@`Nn;F+vu1JijWNfO zYl;m+G&lm*J@kBc&wv4-yh`dcLropJ#=5S4{Vfm`mzZlwjXJF4Fno;H-fx<_k})j~ zKx%8P1Q!Qnf6G#w$?(3(F6=<6C1(lZi$vS0F`OG7ejN;r^Pq^QcDo@tnyJMe8*l)$ z;n@jI=*?@uD*Bpa$M(c%?nIzCAv`GLpCmJK1~tGEW<*=0_tIOa>eI zwlc^NKTRw{*Q6LH!Ioh@1TMVKmDFc5w~-xfejskLYFr0CB(YiJi6!wXq**FC8x`jvERqxdK|pdxJa|i zRz(bICi)Dw1h;&%rNA6pga7~l07*qoM6N<$g7i+3ZU6uP diff --git a/assets/images/tutorial_own_1.png b/assets/images/tutorial_own_1.png index b12929cfd8dcdb8b9bef4f32f6861785250a22a4..7b8d8e889435b6151fa7b6c77049bb2fd0d5d2f7 100644 GIT binary patch literal 3037 zcmb7Gc~lbW5+`#nHB+gdRa= z1(~o4vb;fwp)@VZ?YhAqz;~?rU!{~Wp9uy_dUpZ+mPn^@2GAj=^=h6m6lV~gwtc`5 zimQ^fuqZNs;`VlR1xeIb09)fE%K9z;Qz@pD-}@98)p38Y#I~6i@dt|_1h!l`!ymAuT=JBELNJ&^a32m1zte%KBkqf#I}_zRcdH8Rp{R(qJ2UzBSgcEs+zz ze=Da$n5i>604w>RgV_+U=06@N7k97B3>I@C)^g6w<;h+yCw;4FG@vJufare^G5#h& zV6P;*o*B9BL~_^^bLoBeO#|Z$pie`lf8*wZgvL5vKhz5|5yQ82Ut+guni0;H08 zJKmbidulfey6XcID(X)!k~Yz0n;vQ4F31Hu3RtO};9sjKg&es9vP)TuCPvU-jtni# zGA4-r+jr4#>hP#3v3<}Glgzm-PxBu7I0{({<83IN9`0eJ`rOfPQ>oWUZ_oz}>UGW$ zf%5_Q+_W1Tj+^7wOJ+W`#V6Bk1uv%jU%EtTMq5rK@#pFG=4!(TEq4$TExLB~WXHGT z9- zC*leDK1(T`1lT}6t0(hLyg#YZ_ulwW^{M8@PT^Bt#8d>7;NC_wHA7Z48VmJ=^{-)L z7=mLXHQbiQepy?V{IsQN&ufvQX0jVhAmq(K%z;%FgZ7@c-o*4iIIMR9$ai__BRcGW zB$uS@3ln~B3Ki(fFHE-SFm^oYpn*&x_1U7P+yt8M!}!36K7P;mxv|HoW35Sx!5$`% zQguoY*p7Qb)FGHD7DO3ykF_9%Rj5&f7+~nJaih>Z)h4O?q4%6?zqRL8{B}QXfF5)2 zFQ@(g)^mNa^d*imO=G5T2OpNYYM7pVwtGArd?6UCrS?ibm-bEvBVN{t41a&D)}x$U z#B4`dVzk^cDnaQ`IK(FEYddvRw9vNreqO%#X7kSZ%O){5pM-?B(TMEXxn>H;Zp@}6 z&zz`5p-sC|9{^c5-m${8v>!n*>JT%9lM~j^h6{zZpGKdl^>5}P!=5Oy8z+b(4XG$H ze+TDP!rX{hb$Btc=;66wlwspO9{YwmbFnn(>z?L8w+_EoCU13LfuCLcFrCP(oXQsh^k7DXKHppHw^u)>x(`4s-Iry+oArt1XB77 ztuS2tW4b7WoN1s)OE|$;A87~-&8Q_bRJvDkyK>VG z6^1i|+gHEdXs9pnI``amOY0b0wEThFRhs!^)6>3AM;%?;r~R4FNK7ymF?!P@R$Nt? z_v0Dg(L!oI4j)xF*n{I>jn3{Z8PzDP^oEmF)_!m7#CtTWeQrilE=TXqM&;twfU*1c z&YhOdnAdYFm>{Niz_V=Ja&KXnDECWyVP~Xeq^k- zf|87Mc8(8+vjYqaZohuoNpnawS+P;A@wN_n?Xk7B9!Ev^=Hsm9f)A`sbxqZPD$8Y2 zDBEZQp?ebQ7<0tqcU>iTjehxLOO!eGZLqk~R9m6b?z?3TTP-04GS}s(f)y3k%E#Za zxi)4s^9||QC+5e%$Cc#zshTMsPjn2eL)x|(F*Mv^_ocWhj$#XsJ#ZFfQZiw%%q#ECfiq4*@N(5mX6Mn@Ig8-rFc+LJ4Bv^XX<7N*8xFH*3hm7kKi_Fj>~Fag z98i1o-C4QBn%uqBw%_KD?kVLY^!g86h};|7-U`3#b;cX=`sh8U^mkTVKR2x(d{ejJ z@T(cYV|K#B4hZG31>R^#l*2xSsn9B|6$Lwt8%wI*b;@8hLw$$aciQSKuf<4_;ru0X zsaFRxfL`Z~rhvAzZx<2YMgE;)e@}E%%?zfvR9hluU42; z&U|seVzmFzs>YVzW{DSX?vAh9#{kM9(lZH9tada`zRI^WWuGrv`+5S`XF5};8Ald* z2_`%;c8el&vFX|FHCkd2a9=-E;b30Q;ee9>O03jvE5Cei8~3!W(r%fw z;mSnK5*wNIxBlB>`;nBgQq7u2qgO+yojtx9ZUg!<;qClsJGD88#mUq$s}5oX@T*qxBZN#j*hU`8wS$}w|X)z^5%J|D!7_)xf6ePW5m1>cda zVCYa~R@aU8w6@cwFbM_Y9gQ%m1IX$!@6Jy!mzG zne~}`(C9{-Ox~ySFaYWb13y0w&%i0N9M9pZP*%isPVyBC zegvte3}R@n+CZg5sHT(&o?)e?ajrIIx2se%5r{2`+hpV s;2)-ubQ#Sccyg`;@_m7r8*M!Dx2LebAwuDX%5<`QepK(-=6^otKN|)6WdHyG literal 5153 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 A*8l(j literal 1595 zcma)6X)qgT82(&!w2IZOHiWJo*j_BFCY3EkHMXI;7IiN>&Y~Gtl6AMH!Zc}jr_`-l zl$5MeDT(Nm3e`%m8bxR+62zIfDzcy5Kl`uy9@O^e38A4FVvDr}ppLS8>lY|W z6ZiP^nnRu{a;}%Cx63p&6~D3c!aPxwWoepi;K?ytmfP1X3;tLu%JtDX!7vZezC9pX zoWpQBJ3ABQ0m$MOl*oZpd6ifIj5BSNL2CLJVS^M~M$tz*wY9Yoo^b~UJrM>5oZ|qL zsv>38vaYVK*tL0ntaMYtQ~Ee+$etY z&uF%v^>`fBibSIg_$vcI_4P>8$Dz^amVlAT#gA=a;o&pWKAZD=Mt{MX=)T6t;cE7( zXqXzRp|$Qv)~lKtoEU1mrO{vhV{UZ>0DtDkp~siUUu8GMO!qLI!q{Y_P}pBdxL55- z(WE)tj2>#JA|?sA55#lt>r2f1TRA4EouIrleOF`xp7gj@fg!P%POvE(10}Cif1Azh z{_r7Sh)IZH!9i2|pZ;(JQTfSi=xGS2SUfX8WquB^v$KN{TnLg0`xgC_Dua1V1@I!A z{=|lIH|K!&`{%fz{QLJi8Ryzn3FxO^aq4Ov0|Kp&1#@BNGjfs)#Dgho^S-F$E&M2E z0O=jresroYDE4SOi76JD*0SFK#cxeX@sk5DX8yvJ%HEc|Y}qTW58+H9Vc)g8 z5xA;{BXd@;-4CfYl)UBVD^73jQpn^fUjPD{a?s;&)D|IE51#_Srd|=2yU)H<0od50 z@@*GHBCJ#@t*WdvT7Znq&MPT#F*i34i;6n6a3ZSL#-ASL>&1wV+*}oTOW<@s5lLab zx%^zpc45MB#M$xhOieEr6?1xevLKN?%R&XA!qAz}S?30IF^k0#OFyqMVen=xEHaW$ zYD|lo(gPsBH_V%ny~B%t)A&zD|AFpDxD@2soMT2tI@W=wN19@c_)J1QF=_JkJtZEj z>sf>~_b`jy(a|?R_2?G}LM53z<-K~H3+t`jxu-pN3uCP%3C#)HTN~o_r3sits;uII z0@|>Ny!=i;=1un$bwkz~57+uKlAV*b-sYKyRFm#he2)+;-DvN0s+@7X?~YURqr7Uj zx^yymU0FllO?J7}kJ181U741aHpbcuK+ep@%Cr#DFGch^b4A<8`4NdkV)hqaP)Ne# zt*}_^gtmo@FNq|$7ZuV ztb6Pprfn}zb~hv}j558NiT33ZoLJDC_%#6ANG+k+>y|#8K0;l*p3OE%C`_hjY1}xq zYBH#MCd!SI-9jr`zhex*lbfOZd*l`F`W|8-o=&c6pLm(E8_5sGjj@sjstB{Zj%!3C z!^NOuXjX@>4*=`5nS%!p=5c5#+AI9}`g#J~hOtx{jn*7D5t!Aq!;M2w9;L?ekl<>D zJMhpyu+Ne^JuM^N(18R{MMcgwrs>l?ed>d;P#b`sSurnOos3jKCrh?RMttHp9mU1P zOz14u5P|YS<)en0wIfqpU2Ev{Gm^EnY`FD2(+@=C<>gh$xBP@ug34IrT-Sll|L-#V e(zXnIBtAz9+T)ZkVsR9T2VfkW?Q72mr2h>hP2L&+ diff --git a/assets/images/tutorial_own_11.png b/assets/images/tutorial_own_11.png index 1ff494fd94a192b623e2b508bec8b24fae9f4ccc..0e96942fc735f04c7b2193de32c4a932c001178b 100644 GIT binary patch literal 35726 zcmV)gK%~EkP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>Diz7)yK~#8N?Y#$} zY)5q^TKC?U_4J;krEuoxI@;K4q5R!YH;g68ToX5x%7Gt;zDiYX<{#rL+BVmeIoJrbAuLH-7mLTa_Ijv1mRODPqSb#bb>8WXD<3s;KXm9Ib&2Zs~QD;bF~o zr*#DV@$Uj>#nfh3$d7r^ z$jla`48ICF5UA5n8Jek0)N+gtg`1v_^fBXced~#U5c58c1tK z97%k9_<=?(|1@vttm0nWvY$lWp#7dYfd zCohC8el`fX!3RXF$s!LEmqlBw`%>z_K_L+?#F7WiR98e>4XNvNpY6;xbR3(B(cYG- z*$JM&p3XQL!}0_ZAEg8=F4=6bsGj;l89>^|)glw%)EOtP-%grwm0GMuT26;36H+kM5kiw}V?tdev;@37 z4Kt|7tEg@cT7R7+DbKJv7UFOws-21{VGX$kmlb9EZQO%c#^zg_TGBFXA9Od8b)QRG zUXGbJ{?Z>xb2N|b(n-d)&Z6$XC#8c800}m*0LhMni<_Bk1B|$0vrBbUW>nja$y(@4 zB>|^6h5cc$yxP7Pgkp#3u61zxSq=P^Ky=qya~# zB_)&73B%~}B2;dPRw22rMn~mI+O1*8v6R!Gp4m_fLEL)XHhDxBY^Rk+KHr(qn_wTe zrIvkkmZ@gfVmQ`pgwa*63wnj)NxP)5(^X2+XJ=7aS-I+go_y?PwP~U7F%vD>`rtgX zC6>VXj7-(ip|(d#jr^AV*#Oc8rY2Y=HvkyZ4BfPL)f(gib!s*nu*4VJ>Pt)%ok7wm z3R5snXup+|S!1@!ZwG9!)7N%G^X)wiA>H@-2TPLj>D?6rk zrz6dJ+oB+^7hoQX))IW+dE2(7!il0Q7Rqupi2 zQkSx44p3*SOI~Dq1CR9SHr?KTWX_BcEtq2WKcYvB7S>!|{~FwI@&8dP2VddX6$Ve@ zIzXF{Tx$S$S;!w;<2xHTPR0zauPLkf$R3{CkXm4w1F5g1a@JD^kwJ#F)ktV#KWeoi zt75@U)G7%3r&_J)nNW+iaR7!?Ytx6qx7|fUE!IUtn{H^+_XGwm$5!c)Ts1~@VM|*B z+*2mqJ$L@z*n`kT$dZ=}{*cH{Y3!PY@Cc&1GO6QfK*AZUMgv8zxy?);DXFN1YINqZ zkY?GKWquUeSQVASP^;-#6~QH=*64C@04mk|KF?T7r&%?}Ym?Bo-9?&Bk{{6!6h7I< zOMOpp00yQlKX}2`J9!R8Sx<BgLUtPB>Bx{cp(ey0kke7 z9mWPK0XghNz+9CISK(C`DP>PZEmZQ6LT%X@X;!ikXx4JuX1z_faZjPPET!Ka zDrI~uqPCsO&84E&rtuMlE>zAB>2aopwpDWG=YHjnVKS1j7>>B$2hEU zOSq@jvY`Jc5?Yh`YsZY<)b@nVs{O0*=s^$Q9zTw5A9U`Hp(|pIOtRwN&c|UIEZebb zwt&HA8XSM_v(*yZ@TvExm19;*2967puR^*IGnGBiw1L?T@J{e-K@9tsa4pEf4W|xE zD{1pW%pfw&ZQUF=CJE-jNR~6~l}E}4#IYE|;>2X8Ndj3gBZt5!=|m#m0n@{wd0n(N zWFo0Xn$=kdjhfD*Sr>IyW#>dG-?r2(*yFGTVVPabQ`XyKanjq;}jF?O(0?u`&BTaF;5~EqI<0+HD{4|yM14y$t__UB_Lare&k4dwf zUG+WHqS+*jm9n;$!pT5e^(aiuweI4hf!ccXu@e(l7=WUU;mwzs6~>cPiY&a0D4RCU z)yWFP@<59)?C1+^rS{q^RY0dx{ltENnJpV6k(^Kvuipr znI7QnO`7G@wP=H7NP4|Z&$79^zGqAQRHMo`#X6)e ziN39V(xM~TU1s|B6KOU9YwNvK(k!vQk`qu+i_{oV3r<2s;r5`OS?&^K86OSIW^3TN zTySkRHl8>fNUpI^XvXat8=w=@rZTshFDTPWMzBCLZaBr+b52?dh3PJq>0GF;T5g(< zL@k&Ch@P>?^Vp#lGqTjoE#VV9Cq$zOn&s=$N3BD3YoLrGzeZcGv||La*dW&0e`H9r zWoKY(vbUnX43KB7+@mU#FyVNL3TO4yph|%@hbp)Pfno zacZTAg8~E)SMpRrtmtw}woSF%Uh<-PNzErls6YwzwvC)3OtqBGbBXnKhA?a9JDb^l zGP;S9jHyzSK5ue1o1{fg1*=*m&0^c04YUT9fR^@jQGVN1T2@$_CHv5JjAs1-T!_?K z9;A1YRzv1ZE+-o8)2u<#W!_{hKZYYjh!Z7M8K=}lY(|}w=U_1|GKcb`sdEun7gL~u z&yO*(^7ZsFf{!taH~@|5^5WzGXDKX^#WN?PtVOcp}6qUQdv`M`R&Z>3`bcLO&PO5<}8&C{)wF$5fMZUGgM0`r1Zi6)A zZMDWhhB=e43n^!Ifkv8~H24s)4!*s(UKMIv40CI&iXE&itIpztiH#IcS?VZt;y^|z zvfMUus>~zt@FZ2{;-q>>m-SCEK_1Isxg5)bT+7EI%V6t>NaELegpG5 zC21BJ^>T_i>7W;`vxu4>+heM%S*@_VNUa}hf{!eC>9!t9nk8oIW^6-OY%=iTQ5Kv# z@lviVw7wqgYK`A6 zsI8l4wnLK0C|rf)H}!s0k4O}&Q9%)Ee1*N+Eg(^zcPCbnx}zy7S3teWbUU*L%hBYf zBaT%|aQ_Y8P%FpWX-|31TX-}oxapWQ;9z&%bMtlLw4&Il9s4*7^&E?y@Pwe&Dh>88 z!)2IB`$!OtR&WM(Y6TLDGe)!uBV`aW2d)!}m>|oj<|Ik2&YUTbRqk%7GujaxvVNV% zn}TSgN}82g9kQ<*xfRhr=N@e~)~`S{g=Y!k_CKSV$m?Xyb~G15h0)Z#SrsEHQUS{7 zZlWENBp3U3saWRbGBgLAuhYD_u`@sR#^0~5$CIA(Qc6#uZ+_03Y4+RB0GQT ztRplGMFaiqxr`;OS7Rr#(A>3ADU7BLbPp0m%|;yP%V|{Mo+qIZ_h=1v)?)N#6bZ@g zZ`-5Hp7=N#1}xU6JmIK=!jXsWAJ(m19roF<7jd1IdxedAuM7Y2KfgWP_rMm-PMBot z`p@m<0WT-b8i;CPWZCLu8l$Ngx_=T;g0-9|u~A&(I47A|MoUf?C`%rXDtgbINlq?c zf(<(1+~=qzxb~C(o6GVFbLK~W>i3G(5clNodKs67Z+`k?Y7tx;$s|i288W{TH$=TH zp#|OPEzyojDb!Q9_25aM8fLK)FOrL4CW|MtDHgQ|)ryQ}F2M~p)wl-|id`htduz6$ zUVV`}?Wdl0e0ajq2Zv4j?H%^tcki&@#`R&x&Rt>imTlq2Tkj5Ex$?&Fxi4QGcI}$i zdhOV-_u6po=_iDMXPmBn6L0zRcZY9Xe|y$0 z@X{Ba7Y;jkzc4p98&=HCg%vAi$)-|${JXB<@80>*aQ#hpsV7*wW>t9Mv(5^nXd`=n!W!!37*E9h8!7RO@ueBLHIeZSMFa7lT7^6G;PiDli)uU3jkW|3FT=>lc7 zH?b@zPMt>{ZiCte9Kdh)%qw31JJnS_^}AoLmf*@u(|}VR=*(3oTS#=osK=V<2(@Ey zrRKUYrdntP#a`_iL;!K?Ik`%n6N(xRL-Pb}pDTIz6ue@8(X-DCCmweg``^6w*6^<% zzbrhk`C;}4AzwuYQDzjf{_cyy72mv3l_t(R^Mvr@ zFMBq3%w52T-5ftUZ;%dZaq>;0b&-}hZ-hgZD# z0*yBD*Z=r$;gTvo#9_T z`o-|Ui!Kj4cF=ZK&VNX=v$Nra&padi&2qIH3{i2sU$T=xjW~LfLa8a|~5+i5Rve5t`mL;CRgLURVsC^Gbi$ zLrK1q4W;?c7W(h?c-!UJ#D2=9M+EF4%uq`(W)Lx-NTFGc5^S=T%Zw@3aukHl)Fnd_ zkm=hHsONOB0S;)Axnfpf>3#4y2OY36{N|fp8lLyG)A(&85H_@f_TNXd>flu~s+Isn z_6B~j{3l=e-0;KSd%>W=1~`CTasR^WUL4Lm`B-g9Ni*=-=bsXO=Et7jJJ$`ykL8{nV= z_ThnU(UaPm1Z!5W3NL@r`QcA~?NxkSu^t(rA- z&TC)t%&GGJ%W%hur>J{c4#8}VL9n3N$rSPG)wgBt1PE1p4ab&By{JdoGu_Nl+J!SbktRO{a$Or@y8q@e-&E* z8e+&vtJ}RUw%!bNR;^kQe(?EE6>SP&u)*7XzV(;9;JmP6#T?s{;swt0i44d zH>|5}yWzpjTRE@q3TOX)H_$On=MCx{OasUyKtAdjxh*{Dro_G**N6Y>$6mlk%+_fo zU3KAerD?&(;#p^9+e!~64vpBPVd7XK%~Fm|a3r5Y3`rG5Y@x(Nvt%||Lz2_Pj1HEN zPbn6uNRrRigcQtZi=Ub_i`&)5HuS{{NP613ysB3+-Dg zPv-T-%?e$3K(BCWcc6J3xM@RtF4=RW@9oGExEjF*%DI%I_yU&W{5AAOew_Rnk)(|%!+qZNK=$@I*8=6 ziv+-jCgpNs;`UQQZ>m8P(_3mZT7dRBjvTy1x$Jko5(n5nX;PVTg`&q8*1^ZwPdQ9c zv7VAsP(u^LsxoPomTA7mI%ufH+8B{J-H25&A}fG9y>Md#@YFMo=dum&`oO2d zpZ(Vls8`2nPdbXv5nKgy0o#r|+_ANLzWt6le8z$EfX_R6LV$;00I2{uHQ=fXw^&%ojUd;Ydj_uBQWxi(6f$O&TK;4<_48 z$w?8R)H5PasTq^QYPv=|9V*f=OjC(F>5>V#=g>&^0`BXHfdmcXLwkHCgAcK>c*&gM z^W%e`xSYKj5W`!u+y?n*XWtFDMOWHk==PW!p~8msYsF{*Zs)!2&ile=F1t#VIyUXI zHEshlLe%_11Ugg#j1mBVM3Av}L=hP2jDnRV(MR zf#Q$@_tj{Qu7MSG;&T9P^_*Z|`s#JzxBv2=!q#m&RA~Zl)g5)%{@m8a^)hI;0e7L@ za>u=V$6Xh2qXn&^66=^4tz2fv7Lk)_I`=Yc>;u>eZci0nE?X!y&jdx>kLnxX8fnx%opd?}NSm@&m;43oy_ zA!SC*;XGNe7EJbyre$!dnq__)2V>$2%LwVCW2amSxmSTta7i-k3_47@U%p z96`>?p3hqDx&I+9`)0&bzkxr`HU z=dN9<)`2$Ve3$1I-ukQI+8ggss|g-(c+yj|=lsM?4-akG8b0>vuc}f9zH5Wc=sOm7 z-}fLd^MMEZkA;WsA_WX_l0}F{Q218gSB$0-m-*Gtvv!`qfQ&6_a$K8-Qp9B%exJ0cgz3)(JTr z(74i!m=8u-Ch-(0m{U;;c{b1)?1A;LeA%E(A~8o*_30eUg?!SK5_uI_6*8ZE{9)ne zf8s^_HV8T=5H_@vPB@$sF_2(TDsc*FHlRHD_`}1Sf8u+>VF$T($cFZ0v}4eHAZsdk zVDnbB>ez=nuNl5d=mO4z{pgi--)+@9cg^!Tv}MaSRq8l!|Bb!N+(`qMoR2i%?A)zt z9r!$q&vBYy;|r8EbPYI%@)Zs(5A7(sAh&pjaMP{#s8Yuhk3E#;{Wm}0OS8yZ*)tHg ztyZolr6x73WZ z=i)%(Q`v`}29MlM^-S}z6gMsDLa#g8L=FgG?#aj;b1^kS301L)&Nh|<=xbwtYfkEb zfx4>j!3Jrj9lD=Vf&;lP|DN;ts=(hEVE!v82Hbk*{d~)7323+8aUU&iM%p3Y=b8V* zFTQ|tuxb%xvqsYc4|TskV-IF%;0JEKv;A#4051-J`+KfjE;#E% zzWZ-A4VZWvu?_s?*|uj;|7y1&oj}pzb7&}Z!9B|#x_ZcCMx#|=*44yGQEQ{d2C5<; z>zJW6w*ciK)f0#V4&M}@gwILtL?%g1JehRxz+`qxby_W6#z@m;F||#xt&ZdXF~&jF zJZTnVpv)LvHp*-`viif%>|sEA8ENLJfi#&S>_m~wO|qFLd|q=nUCp!so!fqtgSVdU zr>hWjg18$CgbfWuJ4YPS-Hv?0k(Np;V(Y>n<2D-5x`6MDyy2DK6+ZNd%fpYo`LDxk zf9Y?+8~)RO;SaBW`49hR_^rSEr|_qL|ABDx?f3Q$IJnUPSNQ<0bh@yK+FH4)XTagB z8aYRIawppk{t_jh%Zq%a(gwVRcz?^4#^DEV;?mB^KHv+gcxK_30J?yEi~$j!&vfB{ zO&h`+f9wU}10VfTc=;RuH2lb${v!Oue|%f`ncw*P@Qc6qKf-VR*}K9Y|G)3!V^Kpq z?u_KIl?Bzwiz252if1W(`7Ic-Z#^3M)dsp-MRXDlMYUc-FyL${LXDiNR2Aj_aEQ3F z;j0@RbZiM)5c7e89x_-&BE#p1ZaHOL(X?Jhi3!DM>R5HsFmVi44){#YZ^jKVNA1Cw z^2A*du*{4!bCk}zLN{gLHXO@%4b&d;{^^6C4ZrvYZx6rl`$E{zI6M$3l`LLY(Y}85 zE#cmt+luiMHNXE$Kg@6KVW7YV^yoy+rk&WdL92}n7rlF4nN4WT}2qsR^JuQ z?%neC95Cn#NA0#71^^q>Yrvgt_?@+(Coq49i1P56RUZ!Av@v|;8#nOp#B~8*3jL#B z|FLk&iAV7j-sUY^!`=684maI)Pq^}$Tf^tSat(iOjTl$rs z`u_0CZ}?umtBTvhgvPkR8UA3t3%howj<&vVqd48ekO*laP%## z61a123k{t2J|H(rl)x2>uZv^a1$>rTTd@Y4iC-l^1TR->G@F&0iDkf~)aDWewxt)LgOlv#u`oL#6hZz^HzL?>o zmwq+earXmUrw^ynE9>9;#aHm#YTm{hzrQ?5(vn;0`sPUjwc-aQ*>( zzg&&qF|(7j?JYI@L=IBAuK3W|4+RD&?3f`}I2dqnEIxSAWqcd@5S)I}(c!JX`YQg- zy1n;W%f~>Dr~noZ1QHORHFgPl?8IbB0Ye<|0nx-(u;esJQ6F=SWV#{6*+Lv-WpZ#E zpth4Y8ifhDRN&k+_Mnl1-nBrb8Eaj#bIKJCozb2c3=qeOp3$m#jb_&Q=K}_)gNY4d z#JG%#o$9!DRr5I#FPBfYUpJn_wxATEtCJz>4whEP74)186kd+gCBn|XNSgI98?eAi zGuPa32md^O34HhEnj7yxGyL;4Z+h(u_zJ@S`%SNXVL0LFL#UmZaP zx`4r}Hi&xQF9Zz!hKWA3UE$bWV)wON;Q&V*LRWVR-K(v@6%LU8N}(M*AX54^Iu^hG zH~-vvl~n@A;u%jpDg42Id}X}(0853g2S)tD(4!x+=zG}fg^c{yB~Gk}hhKu@}9P7|#< z6$imTJCv_``Lp>|YKc>ycx2dX-D+<86)!rEU&-V108ePI_@48qoj|#(xK4>Po_uup z$sc|W=U{nhf-kg=1OGGgyMO(EssmRW@RKpW{D$x2&s(S&c}3p=e^t{v;LzaJcV&RP z=L~%Vj@>rBnmYEjTcYi=oBJMUA9#;AR0ka1cVf1|?mnE;fu{>HILWcO{jU4Num90I z`7@oNz-{Dsi;Zs(aVy4_G|e-f%qL1A26Xu5B%i>N)Q7_{B?nn^I%I~AXo*?StGE!cS(g$i<|M4$Qmh$9X0;LTnHJ8@lu}2)h zzm8nPgIl(S2OrwTKVIptY)T-84rVjuqD~EG(x7wf5eLe0;|l0H^CTK#=y3n!?>`X! z-*58lkxWbYB z&~=5gN%oieUBC+i zMqAhxX;j*@_N7n->xhEI(uWJ*ayiUCJ5V_;dIW1NF@@OLCaEzX zx7x7*zW3|_5|w;~gAQ7V!AHrN4kW}5xFB95iY*u~Qg^`NpAc?2W|nl|TWkw0 zf;Ir5zAFZRo4}JZ-{=I2Nhe7;MC2RAa2ksteCG12!>`gS?2A78bv|Z&IRC5@!iM$h z^!p#}z;}6c5iBb6-z)vlCEq>PfgO5<({)R<{mnt!U1|UZc?=}jW867* zz&^w28w>#qIM_LIGzeN;{P`=xn|}Kr!oOc~#h_zx;n^q3&lR~5cS?O*t=xGtb$#jhRUv!E{E z3yTa|aNiwmTet5B_uk*$@dNn%HrWyy%zA!zjekmqw!7`~8vt$KUsdK1cHL*u?9KTe#P+TND1}BVXXZ%I^D#Ash?; z%M|G7c|CPqxyWoC1XzKqHqCIFh=&~UEocLWPui>*F0`PesPMPDV2afE%q;t^WMi+Nnj9t=$D#8OT^-gerLHK3z9 z>tuPm?OnJ7t#StzG~9s(oOSZCt)F4oG4)J*Zj~k`QJlv1HkY8!YlauHuwPg z4}bYb!drj!NBMvG|KM-_x%cywefQam28iw}5?s~bR%T3nS2*}#&U^0f{!Yq%_`y&; z0BxVk81A~~K~C+u!oh#h{K>DsI=toQ^1pm9fh$Joh;-pCz^?)zqwl9^@PZKg4u7Eb zN5A%}@TdRj)#1;7<2B(ge)F~AFW>Ux;jez{$HQO$_D}HJoWJ>J@9ur;a^IGH!E3AQ zYyt&7j|sJCNoOhxcVaZ^Ow&jK z={1Fz=nBWKZiG0|{MAQ4Wq^`8IpY8pW0gUK^V}e!%a%N~DaJXbt5)VGO*>E4#g-WC zVj!|Oc8U3z$Vk4$R3{%ZAIF?02ntxyQ$uRINX1>;8zp?47U4jXdiHJ_nmdphjx4>HWYH>K+8UL;J5jxGsR~sUBDM;v3~w1j%wJx zb2s0<{;AJjsY)I4%Mz2pwubwE*m&3mk`c!QE&L#3A<+wm<9>4Cl2vifup%{>P*J@^ z)J<)tPtP3XGQo9ke!!uwFxqy7W2w@SHYuHbB)6edEgv9|FLl!3V7k{*yV15bsm$BN zt1*p1bEUU^DdeqEjqIqKFIw7m><@S@mnRVs*OVAHz+z7g^QAVZP}eCFqr0vyKrzX3 z(8>SXC%;T}7Q?H5@ag>BmlDuk{XmqU&PaA(iJj~l~1lm&FZiw zc4HvQVxl33HCJYJc^fRIS2-LLU1-~ye5qH-!T!^kP5jUpV09!>bhgYOvhM{JrCzEF z_QCRGUFwt1QZ$4*@Ex3o=#~AEhi(dI=v!+w;4ZhLCHEVm{*N1a?yTV zfGwS&kby@GKQUrV>5$}s6WVVjwUe=uGibv42s8MAvXts5vzCKBs2o(f!kMRzmpbi8 z_;`OF*@@Nx)`?Evy@lpUZKh72O0_wkm*;h~AvU*VF=8yOzK@lfmT|dRse=uCUs~O$ z(N;U39!fEyj=keztZ+;;0EN|qr&$7(nJRfelQ`PUNi#=Fo{$cA(G>%JnHXQp^t|q- zJHr>RxQ<`3KjEl@x>}%I?*@l+v6Hm=TV(wAk5SCPU zY3A4qUYkPES`0t*lW$U6@THG_P%Xf9m<8H4jCGpHPNPy2)l0q_veQx$+g+L~+2RtW z)etS_m<^MQR41;3&MZ%Clu?OwfY=Uu1Ts=MwGa3lS2&2m^JcIGZAV4X6ZY_nwEY3` zc^94uw@L9EX-mbg{n0z<#fQ92$7fSK zrO1#+JkPjP4Nsaz45gbT8_1u324@m-k1Dw1S5jj~t``AR6qje;nu84$`>)K2)+g0jgayrdZ4CF~;niGk1iOPih4$>@D?BWFQ z)v%2qp6qR%wugPjf@8(U%T0O9$@Hs#)pfUr%>%#W*#=y#-AGqb0Dj*8Q=k6^+cm6P zySj6*!Bv{Q#bn*k2S0upm($?=ANvyT7a(4lRDf^yf8Xog8h+sQe-vKw(|;2F_Xp(; zz&6O+YD?=TvET4Jc!n#lzNPmT^gi5q&x87zkQ`ymWfnb#*<6|&^Xg?Q+-~UIBb9`u z?ZwG}Wz|?kB{7+45~T&HLX#82AHf7@Mus}G3pBti%%g**(lJ%giFyPhce3bod9cbU zZ<9Il00CFu<)e%*z)X9tZyyTxh{5iBTHQw`~&++kOP@Dh!;m;5Lr2-F} z&u{ymABk<*bMjMPxH5csf}eRY;5$qo`IP<*Hw_M5|38GkSHSaRo?Z;%zjgY)?-Fku zm=gG%xWD>`4~6ac!Y4qRyo;9ozutGL_*3Ft@4qxYx6meLa?D}FWsiL;Q(;a~Mzr{) zoS`$gH2BWD#tAUEY9&eBasVolYA91%(y<5iC|2N(fl-Uu1v;VPKm%LJCjpa9A_fQ{ zC6my+3NmJ$6rQMTyFsUqd~!B5-}%>UF12pd%rEqE8TEWxbziTj!*p6&hV6W308XobYRdw`=gZ#gm?JxGHtvPq%P$00wDB&nni!*!N%l z`VBmYAA96My+0EJpd)|#doK>}|L7NG*?#flnfVao+t$e%P*nl5O#h;boa~-_(gtxTd<0o`*HyqYiFvH(% z!mlv50iQ)(_Vw$-i=K6+D*eC!jGw6ai~s&X{Z~$TJsd#}js^bE4#(p7qYobRvpD$8 zxqtYlPlW$NSC;lX0=R8m058cFM(38q?De?BP|6@GWqiv}V{Aq##axjR9GVJHR?N{N zKjOf8)Yyt5C~jws1pgeWK2rtzA91W&l6CKOUn{c3n>qBfABuYHYN>eTn|?K`@P!Y* zUoEe;A#Ds>(bZFeW+Lfa#q7l4M-;>^wCGVqb!Em6b|_>e&zsAN@jOo-ETA+QGvu%d zPwPP_HJ(>=z+$ct___ly>6bT`0<8aYFE}MU_rg* zIp>^uTzK*cNAS|MIEt`M>%9J{&&&>91;Y{zZvw(Mcy99-e*vDLnY#7Y6VfZMdq! z|Hypub6@AHHTzzY>whP}3=Q;$@y!Ztz}434e&uiZOQ5HmcqD(|kEqP7p-#Q%A-cC8!> zeAaWrEqBo%c~iLbi{In{kn3ri9!bidiz3-`jAvY08?1{HV{9f#=IR5^RP@C?@?4MZ zdXEk|Ppu*-ZbuCbb>^x3#Pgq%Wqj+S?-YYXUw`J{Q@-ElslFIq`E$R{uHo|^exF)H zkPbz(*wE91W}>?jNeZ))UDMc>lILcNqqdX~P0rer2hA)VTaI;86W;gjxsv8FpJyr0 z6|s#tFX9QQy&U=BS_-Pocfj@oUa@x8)opL>SgmpvcY{I=6l}&tDVM{p6TL4s9_mZM z#v5P#f`GqEt^pnO&;QOp$RD9mu2u7GRdOhn@>DlJlIo)kN3N&sEeEkKC2M)MPH{b8caiFFTVz+M?dJ9PbZ{){ zR4KVMmq~SqkeP)qHd`tHqWt?M?SG|=ANj2PPmn;nn3kTVCPRyzYZZ9}9)2+aR}uK0 z%(m@2_=*W{iDCckrsuBx`t)GP4q>ws15yTo+Tp{Y4)1k#$P$r{SB!JG%+V6ERuUhX zDaLUwWa5C5ia9LVKOj4_Ry$*vgK2fh#B zJ66e`Tes;6Z;@6~5S`tr=RXs*BW}Isn`&vh6*QhaD#WK%Oz?hs(y^tQ!PkvylHxpv z)39v?XbYv(P)vzJoGHl8Ty4Q*E@5HcK`3>zqe(N&wU(Gn*f48wX;ZTg)%=Fg4_~E? zlOgTfHb^`rMN4(>i!Fxf_>AYNryt+=m212`^hba9KK`<14doe_otG$xWljVJ9Y^>= z#Ds8%B0Yx^qU#z;n#{5)K8bl~#}U7neL|J0iMnOWIN*Na@W{ z*h=(ZSe8SjT~q8lofug~_dGB}p&k>hh!pxJ_Zbdw*ELsgi54-YXj+(CO9PG#G}7A% zPon`xa~OWWX`uRDPrL>?D@f(&q(Zz0nBPClLQuxUP#_rE!w&^_bS$ZTa7sL9A$vdNwqstG(>7Q~jaChP6j7A<><4Oh@S zm&0v$-XG35>FDsc@Ayb~=ld>g{+1Z;pc2JrTIw{;LlUMsHzxqMpJt3`Iiu9_=cLIs zZE|$hi|x`HXkvNgVr9%FflD^cVi|L`0T)t;kjX`ktF0xW$T2iz7Fv=OozY7D?$(AQ zJ8RhyCF*L#=Lt~J&xzf3yS1l?O}bF23~PTo@EMiNiIAph|}+!l?9 zN9V55otLStCyLlorNzcv9)(TtZDoNhR0nTVv1PnJ6lC%amxl^s0cK)nMwq6#F(xh> zJi$>y<`9tNPR2?DS#5&>!>AU`IG*GNdcqXw+xe3rE~j;Y2HBqsmn)_US&UPy}~I^+(IEY`R#*_%wp8X zFqcQP)sngTK-RvNfVaDVU6DYZ6XYPMUk^S?N6TbSht^O-m>#Xov;;(U!G=k5)m(@i+5Z{xos{YiK<#{kX3R0H&4j##%wwl~ z{>dzAYD6U~lB3q1L2O^wLKl_>8;i0Nb4+zlbBC(fB3ny}ma2yAdbTIG9#*voHga3~ zuLdmGaq7en8!0il?wlthdj@!)Z8fxjwf~WNg`@KA-@07-GNs)>Ab&CK0!FE+wX4v$ zPh}UAxMDaTP+v^4)RAS1D~tE-&|Ds(AjUq*x-V%i&dsRp^)~9=SYn%=?$QEfCz6Iy z+}*upcVO|CY5C4B$!8rl=Sn^CMYlV)czMX-x|7rDmgKlCqaZI|*QF6F{K!hKkwUrF zkxP#rN*Gr{NtzMkDI?bqNXvBuVyQdAW2;vMrUWzi@uep#dED( zzWAzA(Y}6&cutA9I?a7Ag_hz-79SUAC>=Rd>Uh%3<+2-T2FJ?wBJ+IKT5}WSxs&QL zZQ_^^f#f3xl2vdqo+KVo2<9?rmbJrE(qo(67bo-EDBDNoyo{`1@j<=hzBsv_Q3PC9fTljOMw7A8qLHMTm1<7w_|iIzQ7gA2wX^;Y3@@oaN3| z^5EfiymsOii|<`R=K~|;K}RW_d&-ecUE6heF<#J?+e%#~FV~SZjc1zd0=4T*xt>-p z)rAw|ZXXNt+(}8Z7FMN_tCE6P4!+35E={h&ivIFi(08@gf@lTj8czT zOc9rT(L~6Odln~1ies7IBr3(J5>KqRY0v*AHNW!C0_zRUNU?mabV8l3dTm6%QfNHA zWmH^E(>96(2yVeGgx~>!GdLl5a2ecnuz|sy;2zxF-QC^Y-Q6KLfiw5}ob|0W|MuS9 zHQiO!)mK@)BaQ4c(s0yjK!|i13?cy<$9~pqQx7ZGw9`!-?^80z-@M+D5~;2cGdNLB zSGu3O=$u6?DMwZ&DJwWWi94Dp5$xTsY#7h!nPi_ylg_rL4(< zZ`k;mHmh0no7%*~xr^uc9l5b!KaCL*e4%`19Xv8r1$EHYF(*7R8Gnj*P5wic+YitT zF1G99r`(yg4xmx@V;UCCr0-Q=&b3YcL{S45$NqhMl2>tbt3IN%OkDSmuMyo~G_0R_ ztA>sk3ddwS%DOSrKA^f8WmKC|ti+A4S^O{MSAi(bAyyS^ipV9YQS~|#&z}nt7MovF zR@N$;1Z7sYVZ}GaZ~f%n<*(S*=%drg_KSabnQ8mPvwcM^a;dvfqY@jgiBLwUikM&n zsNRSzk~)^hCyCaDSj+#)FCcSu#j258cf2Pxi?HWpIrxI9*>+-wG&6l-e8jk-^$s?3(=@6ZX3^q)C6kBFk}|i-SIS zHoMdQe3@@Jsz0Yg=h_%37>x+gPN@KKh*StA0yNncGUCSh*S9<=w# zx|#GtPDb>P`38nPehu*xBvMbl6@rjTPpNV}yA(98A0UR6BrBh7MzWL1vjJbLuI}@o zfe&V8wBq*q*W;lYZKz}+>Q6X-)L9JAMi8Hq@=|E_=q5iXg?-qgryhNZR1C=6Mm!>6+d_8Dcjy*7{7kjf)sEAuH^tWp!k7sC$I z@sX>P#DmRkxGT|EOxyMD_ZR!~2xot-iza!h^Cipk6Y!2*P(Ut*kdHUD>-dT4s}SQO zRSk(vGoQ!lidJv$J?Aut)LW71? z7uWFx-G+fZtPdOueR`CIqTdzU|mF{5bmcf z9VoiJp+;o(tF?yB-K$A)F{VU)tKHD54fBMxd^K@^7IujenOa|2X7Tb7?ABxOiU;=2fljtD9iB)w(YpH>~049V^L$rlN zYRhq8fce(<+@l{}*=j%ZXMQM(DM{wm5OoPyLQEsjIakfpv!+WehJu|hH_yJDCp#bL z)N-rU;^+N2;#66w#u2{@EP_qBXossER5fIH$I}l&2y-HN8E@@7mA3VKXVkcow8f*%6u(n?5r{HBitqpv(R-2N#2?w^bZyb?b<=pbT=j7DC9;5j4auF zp=t2cmG`n9ob_Y(VGGnRM&@i>G1Uu~#GPzMT%{?DcRic!!({HOA`R?U$GS1D5G~8? zDs|B2^f+zN>h;9r&jW1ac+X(oV!2-um zu>mWRP$%72EM6t_TYi_Zj{$cGvaW-SNzG(`rQ@l8LnN)fhHx(>RC=C@(^R;jX;~<+ zk@dA0Qsg7dC&XUKjy&9Tr`mP~8FA0duel4oHiHk>EnFWPr=#@T#G3X{pXKx1VQSt0 z>Qc1=p`iEg^i?UdO4(-aCLpzA>hW-zk>evxYRdiMk(9+^=H5Ym9nU|vbCvVg*Wqpc zq30a)tY$mgdi+LP**JNyL5RO&`13n5rD}(Gq<&%fVdI<86DKFb&dUTFlguKF9*C>*fVdf47KR&vVC`_WgY8& z!0WZ`q=2svJ4MoWfxWF8-WJd>YUbTdMtEo%Ah7A`3|Bd~572_*`rIskz;o4g5Y)@} zzHj)}e<1I1f4c3bLLunT%RV6xGC}r_r&S&ERWE$IOgR$ubfN6v(z{qa!Y{b6p& z>lJ}>g8&IMN$b1XbN^KgVq14fnU&D#pwH>5ntMG2s}%?NZ9T>?Qx>%RA=8+Rx-1sC zj5XF~avag|3le7jyrPy&#+cfVt=~q?X|7LkEALK(aV1VKeLUf&v;fy(uNq*mR;@1@0 zd04Ym3?i!!HLv`&As6OkP8F-Jwv)({NqPEY`Az6^e;d|p9IU4~v>2-#S%!lHDZ}I< zVds%-k#SI0Zbj%Of9uZtlD7z$+mmt}WnJ$pYGm8L-Q$2JQdu=D1zm7r8)Y=&F);F! zSa*Fva5P_F+gh5QruvCcoTsc2LyN>SV$22cARz~%hER^O?WF?87wx~O*HV)Z#(l+3 zA!`34TVO$6Xh7~r5nIH|MEprH7A*>$sc(z$ms%eICcB-=$f`j%2hywxx7$`cK=%&j zQOnp%=9gU`BK&YKh)_xIkYPzM=7@s8FyeA0CFqq3cj5g)Yfek}i`>=95ba!L#-5+t zYbY)xC5Iwo5IL3N%K#~?H6tFC!%c>$?jsR!>RG|kpXf8wCYoUPi6!vJS$1*EMWGoS zR;<6`#|122){B>8-D@VEA#v|Am*Oj!G^5H?d689wrZD=Jru>&SqwRc~ezv>Twdzt2 z0UaMk=%+YkxD6n0TgU_GsW$A>5Zhie&e`2l9LuRTAIuw#0~drNmj>x#qp4yIC3em6 z*ae2qi@rJ>u%Iu6iQDEC2iH$6ZXKG=-83z`fP-UEWv#;qr8oUlQ{tyx0{o(Bl`eH| ztJZCv{z~Tj*hw&II3mB2VM|jeMQZwlU>(EToY8A&ZMV!hFuY}HS{B-8&Wk<#lSw_^ zwE}f61OaYGhBDS70bY#yb`BVTV@+hg6VeOmb5Z&eodc>i?U*4B$Fe3s=RLV5vr3V5 zY6;O_jr`l~iGB}2_2B}kH`_;!%Fn7|*a*U4EY-2{A2;1mpt41)qGJnDG*&|r>^SghxNLf;iA`U<=R{VyPQV!%!azhNp-Lyl3pW&$1_%D{tK}oyr~2b&5>xsv`<@%D%<}Yce@Oo z&F*t@e9h1B-ut}dXoO_eUktxyOvf4O&9An(KD@c?GI4HY2Q>zPEn1*l~qavZhprDxK5(lnEP!fH?V6t}AjWp9X?60)`Uslvj#C|Gt)*Jk{^% zsteSKV4AcS^JCo-H=}1G%Wl_pxHqzWn_P0G`xYfD8`<&0)2|VIp2xOM^!UY^wstL% z&{8ta53K-JGA2TMn00`SDE7qFhv?LYSw)oU0s$}m_|Ihvf22BOQIqfP9!;$=FS~$x zujHVaJ-Cwj>(OUdr<;#IcO^c}MF$dz=q~jR= z3Sl9;INuPzbxzxsNe_%5StwS8B`ZQdRem)9R{E1Ij&^!^F8zSV^yx<1yiVRcMKDQU-<%x7&t?QA7t;DpS zGDP#}|FPy0_#|z|XHDIhXRtnymcg;6{9!EfHR52@P^*ws1*19F(%YG7n5nrGnwrx@mMl%cG=8_|Z0iToCzbBPiP|&Op+?+v%pZalUD)NvntAlLTP;1CP5p>)HI?Lz9h1iQR$#l0z>4!MOv`Mb2!m@fD)-&UNW zleo(3-^vl~pI!Mszo#AIU9x@v;*w-P>d{s*pYBD!>!z+6{$utDC5%)+9 zQjkyZ_rJaK``cY;p-OKVQr;mX?A07|WpMKu`SZXt|Y=Q>% zu5}c;j{0_u!#8e3c8B!*HI(TI7bitVxh3BxXzykC#9zi56cuv0imQNz`$G}_ zb5SuC_dfTotND0EPc)Z*bG3?*c>&J9MdXoP7+RlS_2Ipn<|hWWEH15jRR0L;3F!* z;h;j!nKJ5M)8@G~{^t#W^V&THw@AA}6Z)pN?7k%0=LCWuJX3omSlWMkKYuY`U3=f^ z-S#)aG_gHTQQaPPptj$Feev(b*oZBSJm@)= z7YsC7Z8+bu{b%&=EN{?W-mNG4W+#;S6d*n;+qj8)(c;Wr?`wU0*!^;e8_E9{rXsBI zFSxalDL1Og{USUza-Mq9pRuCN*A`T?|NF&Sd$RMq;bFsGj7#D)qVWs&?PaE-JEKKv zvA_q`^Tx}K?WSA|j6n*B4H zm-C8|u%-?c>q+0qh=^}nqOlQD>_}=ZEMma^$iGrFUi8znrBPG=e3XY;dkS4Q9OUSJ z$X^B&;&Nt$e<{Yni@A@})U=q0`dF4>4-B{$O+v;(d0IL6j*@WuuqoHB<|m^={?T)g zO#&Js9-HYqdbYuaq6+ryZgkP6`T~+sf=Zece|DSKu1?uMH82kxE2iP^tvHIpz5bY& zi7Beq0#)6TUN7m(peg0+XVT*HP(ESR!N@`V$IjXUzPy6oi}Re^8`v8Umzj&L^Bl=O zG&U{g7gv`Y!Aq4N^kD$cSMaV?A|WE^T`c$>d&+tkjXOcYBz#NfcROEueD3Q@ZB$sg zLB@F+Bmfb`u*R5MR%bd-BoFyx6KLWY;+m`qkmj{v4K>pd|6QDv_><}iA_kwi&|Ao7 zEL$OBJ4eD>ZG_Q><}F>z*$5)$bhH|Wbcha}pU*5TF4k_7EPdbAkG#pjxF19wSpn+S zG|jT=F$YDdqJ2D1ZApycqC0&8@DFvk#*tl~(Ow)vJ~Dek1dW3$km}Y_ov5G2Hp8zRXV5TECW|qVLu$x=Xtcq1R}8ULO6Ccq5S=4D zT_AHbG3%0IVoqnWkAXJ%tMI3W*;296Fhl+l7*bv$P03}?@It9PM;~Q5Gt2)aj3{s~ z?kEyNq~j&!B{4owyLdi&HarYB|1YT2_kIY=+hHEc?P>%;flhR|858adf_+tJ%|~-Ls3At2pz-q^EC%r#Ys#<)afrYXY={E z92r_(S-H=Z$x)>Q(SSa=8JCHUIjo|nuXgDy#J`HSJsVtfMVVqQna_kd1$KO~l4#k+ zNj2=RnGc57$4zj2u<=8wTJzyM8w$;oa^IP^87? zGyJ?#ourrx_$3CX-ZVim;-O)RCvA^M6Fj75k2h?<7>2hs;{Nemo(h4fwdL{0UY&s^ z;!49Azv9>cZc$d84$nmsOpva=SF4j$QuK-_GaOr>pV&FXl zpo1b4!bFPt{5ka?aYwT_`9KL`^@0jT-wJm0Y6mvcWT%{-JwR4UMwcS6oYWkY@^}^^ z`$@txqB?VVSV2|c*?&fUDt%9%w%wO$R=sd{I2IArbg-T4>9G;D_O8dtWs~*5E_8-N zBK>NsN7)(gz*S%tp(wMzEJwcNM{J!^M|d8Ph(NfRH$J!+TTOxqBKGB{XxW}q4rBR0 z549yo5&RIHhG^=Ba6?Z&7k3tj`eX4fN+C?1L^y|~xug9F%)*H{uYtkOmJ2^QMpMjG9>WKx*ni}yq;7sjn9C-H_jRi>>6$L`kGw6!=AcL1dN4zhjoUzcks+o@yajEBtt;;QE7J{gFEf zvzB4liVbd`;dJqD!c$?$A|8r%LLb<4t~MkJ2|-(qcSBkzzFJUDxiBK#+Mr!)K?kmR zqK;Q7>Y&D(Ct+5!HU+TIr=add!dMhIk1Y`P-DREuFK3Q}6qNEgqxd4OJfr;^7nOpv z9Na`^of1O2?9y#2OqdjVoBKd34XxY<1~QT#j3g1%UaN*(C?M(P=H4#%I)Ea)iTkgL zX!BcLg_O$8h*$q2IJ009x^QG-3Cav&`puW*anqSx&DvP4&;4k_dR*UO)c={ z7o64(_k1um)bgw+O7Qzz1W4_2a_E;+gndyjSjH8-*J#FcjZ8+Yf%G~gojoUg_tq8D zc&!Mzm1${7w;DdRYR#(`nWNX>=xH(x*Wa8AMA8-C$QnMf zacvxJcO7(m`u!Hi>atc9`&O%wPw-<-ai^;G!nlr)EqzNghOAS5-w+DBg|9S>3gym` zMKbuV3HM4rnVFV~iOVYUwHSu2*3FL?oWpIB`BTA0#Biao5V#)e~wqaV7Z{(4rbi73T^ngM+6LQ=; z2#DH%7Liua4P2UJU6{(Vq|axFKTeZVDf6vet*#(sN|{fBKlLmQhufDwlzRM$mz~dK zo}+%AQ&oDpeH_11*}=1@YCUEdi)A1^KFgh+F$SIyw$YLKhp9ntiP z@Uqffm~KwlVmVIKJ!Zg191O!wMMA%ZiZXv%5_ zHbluGpk`H%67gkXvM?OtRn21jh9GS)h&S<7I3O)qqLzU(LqGJek#!BU&=_Uvo`$C~ zlM*Al!-DR1BPQb;`%Bi>O*;=asa$P*)p#4tROS$0THH2r$)|SdlU^yVgXgm_-}iG- zyRAdwbIXE7+#P^&{=B1gUCo#^v<6Ham&NbGIWS*oj%~K5{jpelTBznw5>-^6NmU{h zs0|LUNLze$<|W%qN%xbN3c}uw_Ad}N#mBi4RwAFYQ$?U~#3Wqe=xxtK73@GvpEeph z^!k94^v%s<^3+?b9BzD$I;*uhpBZ!l$?dAKxv8s)SFecBPSiR<=br>Y9Am2mmBFDb2)n=z2I(-~jd1W+JjsC2!qRD5? zDswB^%nPc!jT9hD4SS0t5M@T$G#K1%ngL3})11RoRF!Q@DZm#Z8bkW&mj;`Xf;c=3 za^uckqQ6fItYTkc(O?>R4rE#JMxk{cc`GlbccdVOBnzb(jZhdS0g~ zca=5eyTDUPnn7~>MAN$y46(S@=!c9H-#AJ8`QjY!Qd~)0r160!ociK!LKTDGYP1?I5*7Sm2}pO!5-MX6?l^7X&r+n* z#AeMdk#vvE@HOz6_v;n}9cVPPDwdpoVwO&dae>sMmTI7e`LSeT4=;zzuh!EW^+%F~ z4G0MVoP;goqs~3@VGW$|oU?biJsu7`G{MF4T6*@sa6E|gU>x_ZL~kF(l*hP9Fy#z| zMk4^wXhE;8z(8-r`lPt;-x7%+vXF*_09Z^KQ#y5QziwBIvwfvwoD^w9^i`bJsmyAJ zznRAsxQsEeG6}qb`O|=by1A$RACU0{EYTl%io@9GnlFljqzxa-q|8d~8rm}ts|HQT zfs|iB7_#{YWam|djQXck4F`%A0DM!%h3c3?kPHz7kG*i#CszA2wOpu`Xvy6y3hm!- zLp@P_wV!*K#>Ngpfzz4QX)ZsVr2{L@ z#drP;&ysNf6gM{DM52|c`~`dH(Lqo^hN3y~4e zl2Bu<>+?SUX9M2<(AsfD)@tZxVHtR&^tEa?#=ot@T0InrLt15mmm^>}W~k>j4jVO1 zFDg*YV4~3g{X^#Lo-L!Q*H&X;2=O~rTgauCZPg*WtHB#vbh>IG*vg*{=Tm~`)#c0` z2MiBcU(e+yKP~_k>j}61B(21-00NWEy%hd5EvELxM=hNLLQ-}UMAa0f$Fe9>kJm&3 z^0?VPd~N(m&Upoxw>Q*~01m{;s8RLviom9_(#o4|%AA!5OP=R(l}BExh{dMx7lA+K zE8Z0~^MZ0e6-6X{{9s1Qn)3xPms?g4z(#z!C7odjN5CfIsuaAg1jk+|6an=J(h9o= z5DqJadN`hz&&@mi6$)5`G{Q4m05am^#|hg^;`eDSLgPnE(26L4bd}A;ffV=-%^qs5 zwr%D32PE@;Ftcw*LvO?)t&wzJaY)+wP@GRATTU0eeJUwYpwD+XqGD)_&6Yda@SE5{ zqr!8>s70kp?o)t6UknvIYM7zuZqlvdGbxvbZ$C8U4mOksT_q20JiMsSq@;kEMIJ#a z+GkmDS3Hv)x98;yT7a`e8J|4gU@#%=So5W!Y5-{Vi9HCX$EpLzR;3QC2 z8yxwRz2`Is%iAm9sFi)1N`OnL<=seZRl*{MqKQPRc;Kq%zRORO-niIAh3{*)!emA* z3r-_L`go5TL5P%aQ_f`wnYwlyUf?QLAYn8djiNcQf)5y#Tt>+GCN8s(i+CQXDbEnC z^Jk1-)nA)x)A5@|I7HQeuX_>#GNIe_^%Cpw^t(SZJ! z!k#XHlBrq{nHIAMy4tsc-}`Re(B>B!rmKI8ss`XACAqXvQqX_qTf)XNJ5SXH#xS^^ zt8%i{ol|#nxd`(ugYNbqF2bp!u+IEJq#XmA0Lo-B{O0Bzwq+F|#<60Dr5kWVf(A3H zVyv%-xm}glT~40w;9zWeBZ22HaFb`oD%A-h>S?%Q6VXo_WDF4v$C<+u;kpc|ulpq* z<9`J@ZVA_=br(F-$65g~C0$L(*sj2=Lgtc51?ngoz|>!6tx0u1xJb(Eh9NK^((%0h$ zO#^v;gD_dFkzpJ1uMS8XhBBINFS0vj#h8?qe9RPxLCXpO0p@&?noK#>Ty-C0T#t^Y zx<24(DH|24iBJzXo$M=(QHK=6;W5WqZ8n4!i`G~DHMi3j9>z>DL>BdA&MqO_JwR0# z9ftKXu6pERN~=;tfYrR z-bmx?`nmA4V?@h3py9T&oqzMhtcHEi7Xo)*39Q0;rCPr9;>nSMXY}DuZ^AG?nf>=n zJUj`8piRFtoQ`)XNfv%Wrhi~;8~Rku@_$bWBT;p)zK`!)b8yGP7Lr=|jIs!-l>cv1 zLmp<2ZBgEdqb&F>ltYL19_+8T&`*K?`;?#Ik1n6n#y2o6bN&)4h(!UGFTR(4UCX;qh)eLia#ovwo~@) zugTtbrsE=isWmXQ32;Lu=r|JD;3Bi%L7esR>r8S|xV({x#5aQe(~m>Wxz&TD=gUOvmkcUeSmr|Ni8WH&f_Ungy44%kub9s7pPGx!hg z8#XDk$Miq9@SWwp4m6&4Kj$av!4gjB>ht~$+09g6qr#b{v>Ya5Sv?9L-eGf`7+#13 zoMx5xHn3gh-9{2q>ng^Q@qxZn5(s^mCS)~q8>`^wwc>d;IoWTz5_>ptrJ+qtw`VWZ zQ_$X~WA5DJsTU7l65WzZMsFyO1J0US7XIp3c7?WVsBILi>%Av)@OTmRsJ^p~+R{@T zeVLn4%tiNta!F2CX#HWpU66oIJ1KN6$US$4Y6mk!$>1lhK@pGlaAeG0`UOFeG7b%N zV)E&19-AUsg;s*R`)#!od`C5L!1?QP%=5DR+y&sg?+y$;(|_DYZlvCR-EVLXOIw<_ z+e5IPFYk3x{DpTziBF__@Z-)vY&O?j(n;>_U4!F5UJ(mfZU59$0fr{8*=bYx9B^Sp z_6UmZ0KHr*A?@d!2WLm0-WuKJxhGY9A<^5YjwPaLqM{y zCq>TIz3wgxcC8qE?s_W@$62j>prtoFPU*F4gLKY%6GHdn|3+HMT{^AG#9&;wDAbKa z)pOx<>=ly;hn47fEQTfMe2s~nOCd#VZ3qmqc{aNHPm&D#jL_XFo@5N1_BHS9wXb@# z`i2J5`oD*L*_cD@O#;N)86>Xt@cf@(k%uLrvO`LX%c5Yz4Xb=fyk(dM4V%t(l;<)? z`N-QStvV0SPa^&s6RM9)O)=3)B3+rjVWVhY{U&h?9-d~~+PXw8pa3_lL&TPvpZxyc zy9a6+I13clU+z+P-Vqi{#lTc!V?^?$Xgqn^PS?dJzaoQdUyPU9|K0w-FVrsX{#IRN z6_zaaJxzAXG5MjfKSyPbvmVySr&lcOxf~Td_y??W7jgfOa2fUX$*`W3e=C>9g6~g@ zQ*D5Xu{0@oIc41*AJGWwj_pgh_nf2u(+@6V2Isykn57HQ%g;D;>=MA*A7S{3QB<8Z z7SEGk%(VSGuN75K1@98=|ECtN)q9^s^+*oXY*i{lZaZF5LHoU^0bK!3^ zl|&@z6XDj_$#=f6?gE@JE4a+{u{3D1F4W=H@fcD&pMu6m-b8cO^e+1UR>kxH<0Eu4 zQSMH7E?xChW%M_PlL4p6LfRBy<`kQ*Wv2&%-ijch(*K{5Zw5AZAqJJA8Kt^phXR)< z567}KrW0NVjHU1s1kAh=<-=E3))dIMe4Y8w6NX*TZg}D<PLoJZ$i#$acQ1Z>%g^*lXG5yWBrI)$5jgIz zQGy!f&F*A??R_|rcxPM_(ZFq!1ct?UzrQBiJ_TN&v^oVVuzk3!%h^*YjioZYl|-*RleDlc^o5_&CVGWge$T;+8BD=8JV&DPW+(DOT=%**eO z=x@aiXu7YjoSN=^!K93fnFI?Lo1P-}7q`qn#=)`WNe~fO@aKX$yUVg`gUcUOi!?2ah|{lnf&{M=%9 z#VVIbnV(1_n3WA#h+%C0t#p+8om{xmv+~$%b`UmLQ`unl^;h9>oog-~P>8@UA;??5 zb-wa#)>5@?6HusCQrLQqwp={}qu?ikdDSjoUaQ=8apy{R*A8_G@Vg_vUl;hsaNx`S zdR<=J=`pQ2_sflrGGj(`@G31hC~vI%=>3>@yS<0n7zk{$ac?@&jA0zTPD|F1GHGv* zsjVFnbSWJsHmkqL4v#_8E*o7z25GF{7{U0 z-xtCd$O5s6L`;(=5pA-5`PFnDnQyyU|0ohE{jznN5fIs_TRCuQn^M{U8FxIQJ8_gI zw|hJRud&`aiAR1g1C|v+0?wEXv*-~?vUX8uDdq#gcHD0t%gITe9(Q-XIchT&E9=tO zr0QXNy)lJta|-dv`zd%PL*m`6)5J6^j6PO&hGbBQxzAp;q^@RKPP%iU2gmbTw;e|| ze;3-cIy^}&D%)FpTr(@rIrOfLh^C6DWxS%`xl_-PAa>nTUM9B8Rl_8368HrH+3!hy z5e&)5XN=rGcsT+cLdjSJjGIi9rVH` zksk|K$5g$Gj*_1k8w+U0a}V@>xlg`|e3&r|HL1vhElkj(vLAgGb?s&1Xi{BCi(6FY ztH1B&EH&+|WzO=gR;r93{OC#2I0eJesW8dZ47$^H8EBrpjE#=+oEY0?$zPpZ{`r~0 z3TBN^icB>2PQ0bL>Qsbbh#U|T+-Q1mP}I97`WhjWjE*Ug#uAH^CT$bJSQLBbNV|>B z%`(}rE)1lozmJ%7f4(}0t?WUEt9YyD-r+iOvl)iS=}|U@v_4ZwxJ^{7shq#0T48X( zR74jkJP){jN)1PCy{tT;qA1*hMIt-M*zVOj>=AlX?ij;^a?0#tY8>}Q3;(LqY&qn$ z0ccIM1z}FJ0swE(;Xc>d4muSng{W4oZSUiX!NsnQ@G1 zZifxpuP@FM0q1-(Y`~rKY-!zyM?I&`j@T=4Vmgqu+(>%sL66SELLw}=>(Vcm9lPF# z-Ffc4Rfl!iyEfuXS3%xTkEj1pUs%Gefh34rvIp#!V`lz_b={kO_c%02Rh*kfHoz{Q zjQswP`h({!$*nEoLFhYyptI`<-4jY-3@}$)Bkpu<(wff{T3k_qR>xxYHVgj5ZTQso zLO1GAmq)oAxLeP$b!ELP{Z>{S1GLXXuidVTEeb8=vo{`Ij&}#%IUSfcGZAOk7;+O3 zI4Oy6*%XsP_l7ZTdAV7H|DtFas!jr~D&L#BDvvAy)~_>okEA~n0NmVd7hfvCbsJyX zju#9@dCsN&ekebpw%wbwI~j$`bnLEj>MCD7=pl2?Z&}>bo@8`=TYfB~)w>vqrZxkf zsh+>5a=4^!T8-jbGu#O>pAE<-%^6WqRQ?>~4`&3<6iYfTl&2!wdYl__7DhlT35PcQ z(%zo42c_Mk9E!Jqit2$kpUA-{tn%6ca|uTLhkvo|S4wpo2TCgw8|NErGqbyq;H3p7 zZ+}BhM#%we(Yik;wnvBR)up2HxGTVW4Aj(U`#mhibbcc*Ps+lUitu z<}fAu^N;b2*WImi>8WH3!+y$`JRSkFldNVXnQt#7|k;t%mLSauKyXA~M z7Xi;T;qpSx*_w?5mRGqsDoD;n^E=d&LhjKsr=w(m8J^z8pRoeLcz?nZU6`Xx#XBB} zCJ@kgT%o)8kcWXz!GZDF`K{tYkmSnCR-kcU98>CFbMy9Hfv3#*!75N?^_D*vaSX4H z8OiEIFEik28GLKKZd*#`rtndoKl0u@-%ARO!zBz`=s+VZk^l0W=1-I4{}UF{XEM?@ zA1ezg0{*s*K`eX%a)-B}=+7G)!~-?Z*^cp4sVgH=8zo6z7qqE$cY8j;W7vdroRYWU zsoKs4GjiGMXU@Y8(lK_Uh}B{ZQY=RiVpt2Ub-K zTjUwXn_z03)mOGC-Sd4>=G~`o=&HJFz8`plJtR7u0G=+m%-`9!Ix-!EFcwl_kk}Fu zE>AAw#d;wHnO`Oqhnc1Qi2r!|(#+H8hf*UE`8RJC)!T^Q|LE0YJ*WYr64hq!-TzCf z5WB^I!d7Dy~z#f$`{&enQgkD(;in07IUc6$vu$=bk|SVjk9ntOPRcpFJD_ z|FOiFbym*1_2$p0JeFA>_Kok~YbI876gi)H9~Va|_3CR!aY1cPVY9EIF6*-YGIvR<-VLEAf{Rx9#=zITQW6G<$g|zC(Cl|V zDy!5hsB%g254(Ms^++3_&wOO!B$f>PBTiZ@y3e=K+K@6kFq_F=DKod4!wBHqVd5<1 zHeRWQaIHCBR!xHM2Zcpv-~RHK_gl8XHnL(SK~r6}ol70Bi_P->amnq@agJ9kHBMhT z*RYxUy0GLT#C`V<3;VmI6cypIR(n6vGO&JIyM3#ti|6%(d5=NhNlf9gcq?6@M*)re zI*T0b)dJPG5fjjO$jI7+R5b24bC=H&LpRFte!YqC;1U1Q3!~W%rtf~?M1G_e+D5RG z2oN6Yi4-(ZS<-^WjsA^!D%R7kZPvs%_VLbV1!vguYSN^>aU3+22`t|Mb9L2pn zzyFx+iK!lXqQ-7;blDcFuFwxR{&Kln#kMi z?M8>McamOl28Sb|y^|S2%_Ha;3MwM(Ce%b2BL~Fj@ z_E?m+%=en~`bmt0uu9kENN`{F(|mnfzS<-U;P?S-L;lDJ|8kkA2hfKeCGpViI?dos z_+A@<_{RB@bF^(hVSXbebi?=1HXI4x$kM`}ifYk-JgwZoyJ#wr_YyaN>&*4-wqvE$ z+c8Cj8|aBs&Q0s@6k{3_)P@;k(IIR0g>Ain^lgL-b1g$Zu|+{i>5+8+B%`#sN;W2db)bBT_?p5Alz)HPmoC4VT zc~9epg$BFjVbY(!mT=4Ma)49%FN>g}pL$4Myv5#eSqPRvZzmqV9)9SMEO+`gW{bXh z`E&`rYDe!nzuSvGPKjC0oeq}7hk4w=K@G(V@J2FUud>`G(Ly=X1fsKi2GV@HJd zFa%4^`=+AGX53J{K2&lvkxgN+Z7357c9Pdy;;{#)7Vv(9@yh>_F&OmL+1eX;*W2*K zX}iIq?I|GmKomGDw}SU}@NfaN?F;rQTYl$!Ui{E|oksDPMM&sPx+4o8AonM_BrJ?$ zYYvJTh(4{l+dkYgs&dw=ApX<2 zVZlK_>WwAz+P6HAygc0D2fr{O@EwE4r!vOfk@7G$I_zp?&Ze@iHdm=lM6=<+TPca%x9R8hsDE%8{dDdJ?;z^CO6&@jdqXkoj5O~WB!4o42(6CN!ZJ5~K3R*jQ&PPp=-b)R zE>nrmb-#0q(k?4p>;N}q;B__P&za*N)+gJaKie#|dhxNJ#=mmyRAL3fG=djT8Wk(R zPyjK|0?Gg*Fn$C8-YY`-mEUfn1N{MHGfP9!OnZ%U3~nUXC#?nYKX?mEpOsuD|MkAP zpsz^+**VF80M7P^CeD_E#I(Qcq_5LDvJ`-t5y0z_ZteRe)rNSOU$~|1GgK35{f-t$ z+be(tFIKqm#ZKAuYs+oO0C_mu#hZI9Di#OOaWQxr(O*a)x%{J$OR4_k}#G-2Ocd18p!WA2)*LNLX{=Ye{-nWGmIo*j~3vh4S!) z;UhlTbiuA=-G+F3C2KmKc^u6ec)bwJldu~8BoKUBuHSBaBXxd7>%|Vbz<7TwbS_!M zKsyn7F7ShDs;Ev6$m28xAyOLlza$;IU+V3bVe_eIEUxH?q+|+fO);1}K8P=fX=IqM zmg-BM>26Ro`KagqoPFDOyw+er?|l3K=<%pjpv^R_rRQErTZq(pWO$O{ewc?|CuW^R zR$K0=9lZ_0t)4HvDSQpa<{T>*WGq{G@wlVu9rb$cg*Hc9`cbIo>%wffXK}dG^9b)l zC63mg!Wp)`1%KGIG)2-9W8N{DvVo>CvjXIusQ$9qU*?&59b zVj!T(;4+|Uu|*7u>r5uVO0JM0rDBV+vhP=-`MeTEzMKVyXyw^Ga|UbVM@vepYj>Hr zQghkw4MkIR?gIF@*P*i3A@X^H$A@p>Zw2Rn>H({%DOfM9pRvl#}}10C~nK2jZSXeZo+8DJmmK0rq=F@iI>s7)j`C8J}bqIlnJ;mu+B0 zaP^fNNBs|}|B`S+MmmMbw!9^(C{F6|jPv?4{8)GC zDay6*nXFd6<6&@_rMl|0qUtu=`Tqym?+Kek8(RAnCSo`xn6XXjt_g^hLTUEH6Ap6Y z_?MKp{w;rR#px8DK+Qy{e1D4i{{puONcL1~HwGMl1|k}8enPz*^E<8%yS9Eny%8fu zjQDngb#>N3OWEwCsdGgK&30avdh&_vOPMqs2;y>3>awYnb)ofQn_lU|Hlo92Soxig zH_(6s*rwSaQyp-y-Jg2ze^4jKuC1S^LFZESMvNHo*a3P6>kO@<)XtMTRqAxv$E#qq z{VV6_OXr+?lte0PucpOEiDjam*}5Llb{)0)3Em#@Xyd2eEWZ|QM`h{(XXloG3yZtH zsosbYBjjmCj2$F8Q!TB7rA|1$<>5+xl6UbB;ySI)4}5nI{!Y8p0NUDpvK_8@-x z&2oiPo@yNf&g<04v2*kP42$!3sW)Q8w4jqLc7E1Lg05pFHeN|nN1Qt36pL?hSf?F* zE2%?{zAlUN%too}q60_%Y8tR|#E21H_?chO0jEI6fb)~;cr1n;54?>^yHjn%BMr=k%0a!U=#E8cOe&!b|f51lQ z7;s*%PQv2i&am^rzgF)%3D)6BhnRPu*0Gvh>y(LHN6PrBo3&cUJ>=CiNbACO*-3+d zl_N%s81bEhpZUdqQ!7Wufb#}*5*Ft-hn-t+OEfx3>!kC}IKI76bkyx1AR^DVhq(CG zIX7NSvo9U<*inxdF=E8G7vA`bA5tqvKH#{1x;Eg97%^hRh!K5wW9J6tF9W zkt0Wr9653dnrTp52AmiyGe(XaIdbI4NvSAYcZK6rhGmW%IdbI4k(00v9dK$1WdkEe zjvP61K0p8D!pk@-W%B&OZ89qXGbj{Gxr)7C9u;&Js&1XYY)X1Alo>}RD zr;`B&Z1Ig^G)@pIeH&c5d0r$Z^9iv%mxGxWQBF=j{lp8%7z?5K$`mk-S}|hszLI8m zWLji7kwyiT1$D8QH`)LtL^cRtYNQ;vqML>k^ChM^@YzfnXNn_nNrA_DENNyXI+>)o zI9`x=KeF_#4YGB@g9}$`Boc_{I|MkI$H&+G7fOx&=+2U8oNIF2zvf$p>4caPa~$lr#^c*|a){1#%Y_oe zqNS6;gu=G05r{yXU?WlF4CTp_!eq%qYy)e_PwlC}g=Um71KfdZN;=VkJ$Xe6jp^&A zG^Pc_xBOyKU6UlgGFe>mIW3YAW5|{S&QoH>6G|44;(UIXt#QO8AUel6!ljRy&n0|m zAlj0{Nt$O&vE+-E{`5+G82C0DCT^Zfu`?i*4V>piT-{vN=SlIri7(!=usT!1)?Es* z-^?@qn|@b@-d$#n8e~ z@)KS~v!e!JrPxO)E*p{1tPS;TE)RvX*i=8}Bp)*^6e$CBxg5x3bi>#2lm%8uQQa#! zY35QQS!0tXa*PsCpC`#Ny&1FiMCTlhiiU&~w;axjzSJw=5I1)=lxh>8~ zw&|?-$#RUUQGoz!01DG3H)%}HBCt_?hh2e4`J53cwIr_>~-6&}vm zN`*8NMuVt9g}G7kg3?!mZEZE0^D&(YnF+;?r9pBmi8I(1*KAlCMcp89eqL!ua}B&#qULQfZChD(0U(76 z6q(J03|V$1cUcDO;&o%l3z(>^E#l zKKW|7NpoM9Cxs@NE`mU-z>>HL@_?$Ew^2%*Z3#B>7-F-BQc^@`Nn;F+vu1JijWNfO zYl;m+G&lm*J@kBc&wv4-yh`dcLropJ#=5S4{Vfm`mzZlwjXJF4Fno;H-fx<_k})j~ zKx%8P1Q!Qnf6G#w$?(3(F6=<6C1(lZi$vS0F`OG7ejN;r^Pq^QcDo@tnyJMe8*l)$ z;n@jI=*?@uD*Bpa$M(c%?nIzCAv`GLpCmJK1~tGEW<*=0_tIOa>eI zwlc^NKTRw{*Q6LH!Ioh@1TMVKmDFc5w~-xfejskLYFr0CB(YiJi6!wXq**FC8x`jvERqxdK|pdxJa|i zRz(bICi)Dw1h;&%rNA6pga7~l07*qoM6N<$g7i+3ZU6uP literal 1034 zcmeAS@N?(olHy`uVBq!ia0y~yV0r{(TX3)e$sIT6#sewF;vjb?hIQv;UIIBR>5jgR z3=A9lx&I`x0{NT;9+AZi419+{nDKc2iWCM0=J}p3jv*CsZ|~T8sdzIS_&Dpix|P-n zj%93oatdfJvdtpQLG7*)HW*mcM&9 z#iq_aW7(?R>32T(=Z8+$n(Czsw9@yh|1TB>hFKmR%nS}}PBIJ(Mgl-bPiPciXK3JQ zv0z|GQ8>cLpunui$G{-TQOLk>!hwL&=AflPE0=!cep+O?W$V_Zk_-$V0?W(G7e=jJ zcJp-{@5g`t{uR{M%V%v3mzHH-J>~c-`GR?cl+K^_O>CxO!Do zPEPI;PlJ78e!hN5Sy|iNyLU^})&s4+aQpV}+<&$V|HD7pKDvJWdgixD>d0Z>kXAU; zBW9OSzs0)f$VkrY?Ci{M8gcP4F*?US78e(9-m(7Q-}v|QXU(eGCDvc@zWDt5qt%QV za*BKtF5bBlbK~AUzQ>OrA1$n`yeV+{y`-F+p55c}>C>hidhsITMdANk1nYdsqqTi5v?*3X|mKl;NoJv}}1%ZeDi<$?@nfzfT$mAz;2FQJJN zkL!bMPci@qcl%!-f2?+D$3vqyX-P@V zYc2I5G1YR{8?Wz|@0a+_P{Y5}YiW@8W2Zm)XKvrVZNkjJuy57gy?@XCwVH=J-CYoP zwDnf^^cBDa9seaR+Pvk*)vKW&XNfW}Jb0ZHe0*D-_u=Xzi~IWeF5JB<3pC#fXlzYL zjgXx3pJ&h1=4O7$0-DWGKmF`1l9K*~62(6(k`tMfGiql86C?wJr>mdKI;Vst03nsF A*8l(j diff --git a/assets/images/tutorial_own_12.png b/assets/images/tutorial_own_12.png deleted file mode 100644 index 0e96942fc735f04c7b2193de32c4a932c001178b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35726 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 diff --git a/assets/images/tutorial_own_3.png b/assets/images/tutorial_own_3.png index 7b8d8e889435b6151fa7b6c77049bb2fd0d5d2f7..b025c32b4ad1abc58dc1beb716c6c75b1de1da5f 100644 GIT binary patch literal 2741 zcmb_edt8$D8h_2KtdV7ND{pPb&$N%tw9LE~X*Nqr6i^CpH8V3sQ$z(7Tj^G(3$sMc zRBUFNiFpGWF7-}47>I&d+;A%X&crgyfp;9-4&|7m{!Xd!RWpEm=~ z=2uRf#R0(9S8I<+Z)*Jo0N5OSGSDBD9WyuPe<>>5X2azD@6BlRVE$1v$PLEvmlVwQ zuucTOF!ai^dYiPf84folznevj)_;uH^CFZV9u|mN@868daQNl-J;#$G%_tfvo9%SC zk9y%^c?NN1wcoUK)Hgvg>Ymk_E#-OMf52oikzgu2iy;O$0GvB|v58|OTH(Q)vIleG zjxFF1xw&Ct!B1D$uibv-ZwCMyPK0g*u9{d5n*1-{{Cfbao&nX9h6|}b)~v% zfoo&f4gk#&&TDaxUh@Hf&;I3YE}O_zz3tIx#Hrejk|yjEJ8@eA9Gd=w=Gc({jT@O@ zWhr|MxSYK>VM{W;d&d5upn{mgsKwFaMoN+vOn|G2XSLN;BsCmrXjcrk)QCx|2JO72 zK(f(3yV`F>(Ka@x>|RMBNFF3~w#epL%6V=ITP-k_Am%x%#zN-ziLSYJJa205r#_?L zy(}&^XO5oUYnPQFjZAF%GA8>`B$C_8ZKQ9=2Y@mL-a-~cws%2Cr5(>ly{;i25gATh z3Mm`s*p;l)r6`t{4}8+nqq4_9j5XDY|X z45#q=;g+~tl2mE%IcVbjoRy=zXO{X0sLyb%MX6lp4Vg{Bk%A6lP%Sag$k=Fsg zW}NNdwj#<$k8<6RK`sX_|P=mGNg z2^NH~&xx85z99OCCB2`uVVp=2r-Y@j#kSW0u3Jm0B3HkQIsmvf(ZX`Mw^;v0sw-Lzo(|7&Rz|%IaGZ5;UNld zAFENk5dgTjPt$$r`lW^R55L_^$uDlXPQ13PP$Vy}C^S%D1#_>clY=y z?wy$rw_NwBR4Rv8y5aZ*)WD8`HgizpZVxVeEU&vy3)a>HG-D!2B%$ux)BRp60qH zFyzyE>0UBn7nvf5<>*QLYPvz|1K> zS?r$g$z>EYvvahWappJ7)6CJkV1MK+{rMBCrFN^G4=SZ|_KET1Vq6Vm7GIT&j>Zr5 z5V%F#FhXWjS@b(>#~9;E_fCBG?SyFce(zZE3RPNkF0vOyrvErjuyXNRp+i3bRNq)y zRZbI@y{{;=A_>!rqwQ#P3Kxb7)duZER_}h9ZO3Rj%v12=LYRrfT}RH+BofJ*mw-MJ{^rn<<6v~2 zdT5NaF0$tgM6D+A3j6w@tGQvd9*@`?xV5T4=jUg6FAyVkp4Dh&mnwvV?xa8V=`L?{ zk~gGxck!Qo;?_kUYmm-WFjJj%Me^+%x7vOrNtg+KR+FS(p{Zvqr^U;yC0#8hfEV@2 z7lS(nEN@sgC3$pU;U`&tTt=k9!`o95k!6*Yb3y&}{_PQgJ48um?iBP1^m=^&@0AyV zU4??&2!~WKx6a`jtfs(pF{d$5*;G3AyTa9>!GGe$(%&+YM+V4uU7x1~;416#96V&U z9D^p3lf?}dx_r_Jn25vFX^*H776Y{+Oh0S_2wtI}r^*{HVq!$j+F;8MqQ7Fqjv^XF zN5in;Ww1-BrV|4|c{9~{dHH8`M}J*Jb?N(v+wU8;tJ9YEzQj!96NN=sI=#`6%$q{; zQ*s7`DqF%aBxs)WAyr$EkQ0q&EVi2h6>ua(mgs%L7e>4)cFub29JRN3`N5RP`u=34 zv-HJf^^v(Pgk*|A<5y%6B=CfozkB*da5;Bg$l#xX1z^R;D$j``ZtoDi?}#})(AkE< zT3yZ&pbyA&gPcu)hFeGH-TS<`MVGUPub*k$&F?p)YD9EX;Io&g>%@StfQtcw0mhH0 zLX`=>-G0!*Ua*ZaS-HSC{3wEgzSsQFb3NVFrx6RaHu@txf?y}>cs95!^DcDZYntOZdiJrrC#U*r&u)a!_qL% zJ*@yBL0*w}cq&+imJV&RpF>+WmE!hGm)l42rod#+!58`2s7S|m_~AyET`+OdK9rjE zx-bK{y1EMhW%`#4vw_~E}UmgI{UiW*(R>FPMkUHYf75ep zqSjV7`~MhLtbOaLeuUOHZ{92h0l=>#C!T~b?Bf;HB+&C))26t_O#t9!(>K^BsJU&R zx!N2`-UBwP)KVijDohw7)|~&#=!~$^XHZazMd50&K_riNF-Nnf?!;$iGJMU!cvYXX zq*5ubV}cZU*Unck(b;-)ZG>^N>sEs^*8gW}`fo?C3WU*g-Fe@iz2$w?V5gdRa= z1(~o4vb;fwp)@VZ?YhAqz;~?rU!{~Wp9uy_dUpZ+mPn^@2GAj=^=h6m6lV~gwtc`5 zimQ^fuqZNs;`VlR1xeIb09)fE%K9z;Qz@pD-}@98)p38Y#I~6i@dt|_1h!l`!ymAuT=JBELNJ&^a32m1zte%KBkqf#I}_zRcdH8Rp{R(qJ2UzBSgcEs+zz ze=Da$n5i>604w>RgV_+U=06@N7k97B3>I@C)^g6w<;h+yCw;4FG@vJufare^G5#h& zV6P;*o*B9BL~_^^bLoBeO#|Z$pie`lf8*wZgvL5vKhz5|5yQ82Ut+guni0;H08 zJKmbidulfey6XcID(X)!k~Yz0n;vQ4F31Hu3RtO};9sjKg&es9vP)TuCPvU-jtni# zGA4-r+jr4#>hP#3v3<}Glgzm-PxBu7I0{({<83IN9`0eJ`rOfPQ>oWUZ_oz}>UGW$ zf%5_Q+_W1Tj+^7wOJ+W`#V6Bk1uv%jU%EtTMq5rK@#pFG=4!(TEq4$TExLB~WXHGT z9- zC*leDK1(T`1lT}6t0(hLyg#YZ_ulwW^{M8@PT^Bt#8d>7;NC_wHA7Z48VmJ=^{-)L z7=mLXHQbiQepy?V{IsQN&ufvQX0jVhAmq(K%z;%FgZ7@c-o*4iIIMR9$ai__BRcGW zB$uS@3ln~B3Ki(fFHE-SFm^oYpn*&x_1U7P+yt8M!}!36K7P;mxv|HoW35Sx!5$`% zQguoY*p7Qb)FGHD7DO3ykF_9%Rj5&f7+~nJaih>Z)h4O?q4%6?zqRL8{B}QXfF5)2 zFQ@(g)^mNa^d*imO=G5T2OpNYYM7pVwtGArd?6UCrS?ibm-bEvBVN{t41a&D)}x$U z#B4`dVzk^cDnaQ`IK(FEYddvRw9vNreqO%#X7kSZ%O){5pM-?B(TMEXxn>H;Zp@}6 z&zz`5p-sC|9{^c5-m${8v>!n*>JT%9lM~j^h6{zZpGKdl^>5}P!=5Oy8z+b(4XG$H ze+TDP!rX{hb$Btc=;66wlwspO9{YwmbFnn(>z?L8w+_EoCU13LfuCLcFrCP(oXQsh^k7DXKHppHw^u)>x(`4s-Iry+oArt1XB77 ztuS2tW4b7WoN1s)OE|$;A87~-&8Q_bRJvDkyK>VG z6^1i|+gHEdXs9pnI``amOY0b0wEThFRhs!^)6>3AM;%?;r~R4FNK7ymF?!P@R$Nt? z_v0Dg(L!oI4j)xF*n{I>jn3{Z8PzDP^oEmF)_!m7#CtTWeQrilE=TXqM&;twfU*1c z&YhOdnAdYFm>{Niz_V=Ja&KXnDECWyVP~Xeq^k- zf|87Mc8(8+vjYqaZohuoNpnawS+P;A@wN_n?Xk7B9!Ev^=Hsm9f)A`sbxqZPD$8Y2 zDBEZQp?ebQ7<0tqcU>iTjehxLOO!eGZLqk~R9m6b?z?3TTP-04GS}s(f)y3k%E#Za zxi)4s^9||QC+5e%$Cc#zshTMsPjn2eL)x|(F*Mv^_ocWhj$#XsJ#ZFfQZiw%%q#ECfiq4*@N(5mX6Mn@Ig8-rFc+LJ4Bv^XX<7N*8xFH*3hm7kKi_Fj>~Fag z98i1o-C4QBn%uqBw%_KD?kVLY^!g86h};|7-U`3#b;cX=`sh8U^mkTVKR2x(d{ejJ z@T(cYV|K#B4hZG31>R^#l*2xSsn9B|6$Lwt8%wI*b;@8hLw$$aciQSKuf<4_;ru0X zsaFRxfL`Z~rhvAzZx<2YMgE;)e@}E%%?zfvR9hluU42; z&U|seVzmFzs>YVzW{DSX?vAh9#{kM9(lZH9tada`zRI^WWuGrv`+5S`XF5};8Ald* z2_`%;c8el&vFX|FHCkd2a9=-E;b30Q;ee9>O03jvE5Cei8~3!W(r%fw z;mSnK5*wNIxBlB>`;nBgQq7u2qgO+yojtx9ZUg!<;qClsJGD88#mUq$s}5oX@T*qxBZN#j*hU`8wS$}w|X)z^5%J|D!7_)xf6ePW5m1>cda zVCYa~R@aU8w6@cwFbM_Y9gQ%m1IX$!@6Jy!mzG zne~}`(C9{-Ox~ySFaYWb13y0w&%i0N9M9pZP*%isPVyBC zegvte3}R@n+CZg5sHT(&o?)e?ajrIIx2se%5r{2`+hpV s;2)-ubQ#Sccyg`;@_m7r8*M!Dx2LebAwuDX%5<`QepK(-=6^otKN|)6WdHyG diff --git a/assets/images/tutorial_own_4.png b/assets/images/tutorial_own_4.png index b025c32b4ad1abc58dc1beb716c6c75b1de1da5f..3162ea35d1fbcb477046baae025a86feed3a6c3d 100644 GIT binary patch literal 3080 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 F{{`tq7!d#f literal 2741 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 F{{`tq7!d#f diff --git a/assets/images/tutorial_own_6.png b/assets/images/tutorial_own_6.png index 79461fe4c01947333297cef9e2971baf2e106867..1ff494fd94a192b623e2b508bec8b24fae9f4ccc 100644 GIT binary patch literal 1034 zcmeAS@N?(olHy`uVBq!ia0y~yV0r{(TX3)e$sIT6#sewF;vjb?hIQv;UIIBR>5jgR z3=A9lx&I`x0{NT;9+AZi419+{nDKc2iWCM0=J}p3jv*CsZ|~T8sdzIS_&Dpix|P-n zj%93oatdfJvdtpQLG7*)HW*mcM&9 z#iq_aW7(?R>32T(=Z8+$n(Czsw9@yh|1TB>hFKmR%nS}}PBIJ(Mgl-bPiPciXK3JQ zv0z|GQ8>cLpunui$G{-TQOLk>!hwL&=AflPE0=!cep+O?W$V_Zk_-$V0?W(G7e=jJ zcJp-{@5g`t{uR{M%V%v3mzHH-J>~c-`GR?cl+K^_O>CxO!Do zPEPI;PlJ78e!hN5Sy|iNyLU^})&s4+aQpV}+<&$V|HD7pKDvJWdgixD>d0Z>kXAU; zBW9OSzs0)f$VkrY?Ci{M8gcP4F*?US78e(9-m(7Q-}v|QXU(eGCDvc@zWDt5qt%QV za*BKtF5bBlbK~AUzQ>OrA1$n`yeV+{y`-F+p55c}>C>hidhsITMdANk1nYdsqqTi5v?*3X|mKl;NoJv}}1%ZeDi<$?@nfzfT$mAz;2FQJJN zkL!bMPci@qcl%!-f2?+D$3vqyX-P@V zYc2I5G1YR{8?Wz|@0a+_P{Y5}YiW@8W2Zm)XKvrVZNkjJuy57gy?@XCwVH=J-CYoP zwDnf^^cBDa9seaR+Pvk*)vKW&XNfW}Jb0ZHe0*D-_u=Xzi~IWeF5JB<3pC#fXlzYL zjgXx3pJ&h1=4O7$0-DWGKmF`1l9K*~62(6(k`tMfGiql86C?wJr>mdKI;Vst03nsF A*8l(j literal 1909 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 literal 1034 zcmeAS@N?(olHy`uVBq!ia0y~yV0r{(TX3)e$sIT6#sewF;vjb?hIQv;UIIBR>5jgR z3=A9lx&I`x0{NT;9+AZi419+{nDKc2iWCM0=J}p3jv*CsZ|~T8sdzIS_&Dpix|P-n zj%93oatdfJvdtpQLG7*)HW*mcM&9 z#iq_aW7(?R>32T(=Z8+$n(Czsw9@yh|1TB>hFKmR%nS}}PBIJ(Mgl-bPiPciXK3JQ zv0z|GQ8>cLpunui$G{-TQOLk>!hwL&=AflPE0=!cep+O?W$V_Zk_-$V0?W(G7e=jJ zcJp-{@5g`t{uR{M%V%v3mzHH-J>~c-`GR?cl+K^_O>CxO!Do zPEPI;PlJ78e!hN5Sy|iNyLU^})&s4+aQpV}+<&$V|HD7pKDvJWdgixD>d0Z>kXAU; zBW9OSzs0)f$VkrY?Ci{M8gcP4F*?US78e(9-m(7Q-}v|QXU(eGCDvc@zWDt5qt%QV za*BKtF5bBlbK~AUzQ>OrA1$n`yeV+{y`-F+p55c}>C>hidhsITMdANk1nYdsqqTi5v?*3X|mKl;NoJv}}1%ZeDi<$?@nfzfT$mAz;2FQJJN zkL!bMPci@qcl%!-f2?+D$3vqyX-P@V zYc2I5G1YR{8?Wz|@0a+_P{Y5}YiW@8W2Zm)XKvrVZNkjJuy57gy?@XCwVH=J-CYoP zwDnf^^cBDa9seaR+Pvk*)vKW&XNfW}Jb0ZHe0*D-_u=Xzi~IWeF5JB<3pC#fXlzYL zjgXx3pJ&h1=4O7$0-DWGKmF`1l9K*~62(6(k`tMfGiql86C?wJr>mdKI;Vst03nsF A*8l(j diff --git a/assets/images/tutorial_own_8.png b/assets/images/tutorial_own_8.png index e4dbf8ad908d18d3f70b3c2519cf42cf9abb1c57..11f8b419fbc043b7fa37316e65095c9a668489c2 100644 GIT binary patch literal 9108 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 literal 2270 zcmbVOc|6qX8vj|su^cLws3fJvFp5E;EJN9%$(n5(+t^8CIkriEUKro-(lq{J1)0RWJ) zvNX2`0D*Fz>?YhV1o+2DzYHJDrH8~Pn-g|iZFV`$xQ2_93 z8-EGBizxR405O!6xvAsth}B6-h@8cNzZgl=XN;?EE5)m=zW*c*a|i1wXSF4(S><&!Vf#zDVu zdx(a0%oXBvj-=tySB8e8bEAuKi<3HbgVIlzp`^r_ zOuFj(8QN1Ciwetf<8X z_3=SZ8mUwkHlne0O*_n~*xI_R1Kz-fp({g?ZllBrcElJb{k+j5EtZ+c9zf%pxuInfUb*t_PZxPLGAZs&U`0j8G@&vTk0zOqtSRK7f231c1sYrb6ndbKlAfa zu~4BKDYRmE128dIkECrE#3#agEySd{^{_q2&PCr$KR5v7itz!w7iUC@I}-*Z&zSPP zS@|V%Xxp*<3-|TUbGC=#q2Hwec+$`N=Az{YRYQlNmW}n%b-i!DVm%_3j@5A+id|CK z)W!6pyOb;T33NZS%GDJxY0Whi0L)cPcu?t>to@7_E^$((v%SV9=$7&R1lDt@wh(U) z5tZ>qFB<_7{*mFU`G$$~wKgB@j7n4))$9&qFAe}yc0o601?$$EbV}3fY+m@rYSE=8 zUWd}0YZ1Olr|OmP6c5%+!RsJgCfg_YR3h~7?v>5c2`my zP~Io73*e_-qhAIXIUGIUnpUK5uuY!%+s)m4ra+)g5K1*6meu+!;h+Hp+OBeU#0KqY z>6UW%e^?kj%paHaRK(7sye^hA>1qG zbQhzxESXg@I091v2V(rEB49`AGK-L>Er~y`fZ1Hj(VE+YkspKSoUHF*8!vlayb zsr$TQF`LQafjR}vic23@OlNYSj$$D(rned2<19L*U2cH9RMdqdpp<;C?ESLCq{pre z3`T`OHx_LtGnA=^2-gjWMvcpnNmJV`E9$b)&M!Mt&5CyvgQk)6kB~`qc?DSj#}b2^ zDBIX%cpijfAPH^=MD?KVLTmd5gL#WK6gVC4x^aJQEH{MUGT{TP}Vn%${6Ieu*` z<8l-wo5!%nR|D)52mXSNE!xtW96PtOoK3$V6ZxyB{$Z~pX2I7Q6AsH8goxgR$kcm)OWlOT{Ja46r2^#o^kn_r z>yW2>bJ5NMgvcfhZd#>t4jQhcL#_cT&As2Ii=;( zS(xVi&l~l(RbnR_lU`_J;#0)Bi?OaFilc5*2j>>8e}vwrqe#Y*;cBh%tGY~%x^*q< z@9=f{LY8Pvg=D+VbSSscbAOKp*Ni>zjk~!QPBjbinC@>E@|>-CFqKFmsk)~@xz6+E z4QI<7a(xSzZ9Q!;o767EWqvLiOhrxR5aQ9+az9)YXIH$d+(-VQPXCcHlhV0FRHyc+gf%D(`r8#$5y diff --git a/assets/images/tutorial_own_9.png b/assets/images/tutorial_own_9.png index 11f8b419fbc043b7fa37316e65095c9a668489c2..cc315692698870a5248a3921c98a73c114d3cae0 100644 GIT binary patch literal 1595 zcma)6X)qgT82(&!w2IZOHiWJo*j_BFCY3EkHMXI;7IiN>&Y~Gtl6AMH!Zc}jr_`-l zl$5MeDT(Nm3e`%m8bxR+62zIfDzcy5Kl`uy9@O^e38A4FVvDr}ppLS8>lY|W z6ZiP^nnRu{a;}%Cx63p&6~D3c!aPxwWoepi;K?ytmfP1X3;tLu%JtDX!7vZezC9pX zoWpQBJ3ABQ0m$MOl*oZpd6ifIj5BSNL2CLJVS^M~M$tz*wY9Yoo^b~UJrM>5oZ|qL zsv>38vaYVK*tL0ntaMYtQ~Ee+$etY z&uF%v^>`fBibSIg_$vcI_4P>8$Dz^amVlAT#gA=a;o&pWKAZD=Mt{MX=)T6t;cE7( zXqXzRp|$Qv)~lKtoEU1mrO{vhV{UZ>0DtDkp~siUUu8GMO!qLI!q{Y_P}pBdxL55- z(WE)tj2>#JA|?sA55#lt>r2f1TRA4EouIrleOF`xp7gj@fg!P%POvE(10}Cif1Azh z{_r7Sh)IZH!9i2|pZ;(JQTfSi=xGS2SUfX8WquB^v$KN{TnLg0`xgC_Dua1V1@I!A z{=|lIH|K!&`{%fz{QLJi8Ryzn3FxO^aq4Ov0|Kp&1#@BNGjfs)#Dgho^S-F$E&M2E z0O=jresroYDE4SOi76JD*0SFK#cxeX@sk5DX8yvJ%HEc|Y}qTW58+H9Vc)g8 z5xA;{BXd@;-4CfYl)UBVD^73jQpn^fUjPD{a?s;&)D|IE51#_Srd|=2yU)H<0od50 z@@*GHBCJ#@t*WdvT7Znq&MPT#F*i34i;6n6a3ZSL#-ASL>&1wV+*}oTOW<@s5lLab zx%^zpc45MB#M$xhOieEr6?1xevLKN?%R&XA!qAz}S?30IF^k0#OFyqMVen=xEHaW$ zYD|lo(gPsBH_V%ny~B%t)A&zD|AFpDxD@2soMT2tI@W=wN19@c_)J1QF=_JkJtZEj z>sf>~_b`jy(a|?R_2?G}LM53z<-K~H3+t`jxu-pN3uCP%3C#)HTN~o_r3sits;uII z0@|>Ny!=i;=1un$bwkz~57+uKlAV*b-sYKyRFm#he2)+;-DvN0s+@7X?~YURqr7Uj zx^yymU0FllO?J7}kJ181U741aHpbcuK+ep@%Cr#DFGch^b4A<8`4NdkV)hqaP)Ne# zt*}_^gtmo@FNq|$7ZuV ztb6Pprfn}zb~hv}j558NiT33ZoLJDC_%#6ANG+k+>y|#8K0;l*p3OE%C`_hjY1}xq zYBH#MCd!SI-9jr`zhex*lbfOZd*l`F`W|8-o=&c6pLm(E8_5sGjj@sjstB{Zj%!3C z!^NOuXjX@>4*=`5nS%!p=5c5#+AI9}`g#J~hOtx{jn*7D5t!Aq!;M2w9;L?ekl<>D zJMhpyu+Ne^JuM^N(18R{MMcgwrs>l?ed>d;P#b`sSurnOos3jKCrh?RMttHp9mU1P zOz14u5P|YS<)en0wIfqpU2Ev{Gm^EnY`FD2(+@=C<>gh$xBP@ug34IrT-Sll|L-#V e(zXnIBtAz9+T)ZkVsR9T2VfkW?Q72mr2h>hP2L&+ literal 9108 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 diff --git a/lib/cli.dart b/lib/cli.dart index cabfa19..c83fd40 100644 --- a/lib/cli.dart +++ b/lib/cli.dart @@ -62,7 +62,7 @@ void main(List args) async { if(result["update"]) { stdout.writeln("Updating reboot dll..."); try { - await downloadRebootDll(0); + await downloadRebootDll(rebootDownloadUrl, 0); }catch(error){ stderr.writeln("Cannot update reboot dll: $error"); } diff --git a/lib/main.dart b/lib/main.dart index 9704854..0804e97 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -21,8 +21,7 @@ import 'package:window_manager/window_manager.dart'; final GlobalKey appKey = GlobalKey(); void main() async { - await Directory(safeBinariesDirectory) - .create(recursive: true); + await safeBinariesDirectory.create(recursive: true); WidgetsFlutterBinding.ensureInitialized(); await SystemTheme.accentColor.load(); await GetStorage.init("game"); diff --git a/lib/src/cli/compatibility.dart b/lib/src/cli/compatibility.dart index ef8474c..bf4814b 100644 --- a/lib/src/cli/compatibility.dart +++ b/lib/src/cli/compatibility.dart @@ -13,7 +13,7 @@ Future> getControllerJson(String name) async { throw Exception("Missing documents folder"); } - var file = File("$folder/$name.gs"); + var file = File("$folder\\$name.gs"); if(!file.existsSync()){ return HashMap(); } diff --git a/lib/src/cli/game.dart b/lib/src/cli/game.dart index 17b27a1..4427f8e 100644 --- a/lib/src/cli/game.dart +++ b/lib/src/cli/game.dart @@ -2,12 +2,12 @@ import 'dart:io'; import 'package:process_run/shell.dart'; import 'package:reboot_launcher/cli.dart'; -import 'package:win32_suspend_process/win32_suspend_process.dart'; import '../model/fortnite_version.dart'; import '../model/game_type.dart'; import '../util/injector.dart'; import '../util/os.dart'; +import '../util/process.dart'; import '../util/server.dart'; final List _errorStrings = [ @@ -41,7 +41,6 @@ Future startGame() async { _gameProcess = await Process.start(gamePath, createRebootArgs(username!, type)) ..exitCode.then((_) => _onClose()) ..outLines.forEach((line) => _onGameOutput(line, dll, hosting, verbose)); - _injectOrShowError("craniumv2.dll"); } @@ -51,7 +50,7 @@ Future _startLauncherProcess(FortniteVersion dummyVersion) async { } _launcherProcess = await Process.start(dummyVersion.launcher!.path, []); - Win32Process(_launcherProcess!.pid).suspend(); + suspend(_launcherProcess!.pid); } Future _startEacProcess(FortniteVersion dummyVersion) async { @@ -60,7 +59,7 @@ Future _startEacProcess(FortniteVersion dummyVersion) async { } _eacProcess = await Process.start(dummyVersion.eacExecutable!.path, []); - Win32Process(_eacProcess!.pid).suspend(); + suspend(_eacProcess!.pid); } void _onGameOutput(String line, String dll, bool hosting, bool verbose) { @@ -85,18 +84,14 @@ void _onGameOutput(String line, String dll, bool hosting, bool verbose) { } if(line.contains("Region ")){ - _injectRequiredDLLs(hosting, dll); - } -} + if(hosting) { + _injectOrShowError(dll, false); + }else { + _injectOrShowError("console.dll"); + } -void _injectRequiredDLLs(bool host, String rebootDll) { - if(host) { - _injectOrShowError(rebootDll, false); - }else { - _injectOrShowError("console.dll"); + _injectOrShowError("leakv2.dll"); } - - _injectOrShowError("leakv2.dll"); } void _kill() { diff --git a/lib/src/cli/reboot.dart b/lib/src/cli/reboot.dart index be86c0e..09f2f5f 100644 --- a/lib/src/cli/reboot.dart +++ b/lib/src/cli/reboot.dart @@ -54,6 +54,6 @@ Future downloadRequiredDLLs() async { var tempZip = File("${tempDirectory.path}/reboot_config.zip"); await tempZip.writeAsBytes(response.bodyBytes); - await extractFileToDisk(tempZip.path, "$safeBinariesDirectory\\backend\\cli"); + await extractFileToDisk(tempZip.path, "${safeBinariesDirectory.path}\\cli"); } } \ No newline at end of file diff --git a/lib/src/controller/game_controller.dart b/lib/src/controller/game_controller.dart index b036159..1e2b778 100644 --- a/lib/src/controller/game_controller.dart +++ b/lib/src/controller/game_controller.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:collection'; import 'dart:convert'; import 'dart:io'; @@ -20,7 +21,9 @@ class GameController extends GetxController { late final HashMap gameInstancesMap; late final RxBool started; late bool updated; - Future? updater; + late bool error; + late bool failing; + StreamController? updater; GameController() { _storage = GetStorage("game"); @@ -52,6 +55,10 @@ class GameController extends GetxController { started = RxBool(false); updated = false; + + error = false; + + failing = false; } String _readUsername() { diff --git a/lib/src/controller/server_controller.dart b/lib/src/controller/server_controller.dart index 1265a29..a309748 100644 --- a/lib/src/controller/server_controller.dart +++ b/lib/src/controller/server_controller.dart @@ -29,18 +29,10 @@ class ServerController extends GetxController { host.text = _readHost(); port.text = _readPort(); _storage.write("type", value.index); - if(!started.value) { return; } - if(value == ServerType.remote){ - remoteServer?.close(force: true); - remoteServer = null; - started.value = false; - return; - } - stop(); }); @@ -76,6 +68,7 @@ class ServerController extends GetxController { break; case ServerType.remote: await remoteServer?.close(force: true); + remoteServer = null; break; case ServerType.local: break; diff --git a/lib/src/controller/settings_controller.dart b/lib/src/controller/settings_controller.dart index 87d5284..5427d4b 100644 --- a/lib/src/controller/settings_controller.dart +++ b/lib/src/controller/settings_controller.dart @@ -5,15 +5,21 @@ import 'package:reboot_launcher/src/model/tutorial_page.dart'; import 'package:reboot_launcher/src/util/os.dart'; import 'dart:ui'; +import '../util/reboot.dart'; + class SettingsController extends GetxController { late final GetStorage _storage; late final String originalDll; + late final TextEditingController updateUrl; late final TextEditingController rebootDll; late final TextEditingController consoleDll; late final TextEditingController authDll; late final TextEditingController matchmakingIp; late final Rx displayType; + late final RxBool automaticallyStartMatchmaker; late final RxBool doNotAskAgain; + late final RxBool advancedMode; + late final RxBool autoUpdate; late Rx tutorialPage; late double width; late double height; @@ -24,15 +30,24 @@ class SettingsController extends GetxController { SettingsController() { _storage = GetStorage("settings"); + updateUrl = TextEditingController(text: _storage.read("update_url") ?? rebootDownloadUrl); + updateUrl.addListener(() => _storage.write("update_url", updateUrl.text)); + rebootDll = _createController("reboot", "reboot.dll"); + consoleDll = _createController("console", "console.dll"); + authDll = _createController("cranium2", "craniumv2.dll"); + matchmakingIp = TextEditingController(text: _storage.read("ip") ?? "127.0.0.1"); matchmakingIp.addListener(() async { var text = matchmakingIp.text; _storage.write("ip", text); }); + automaticallyStartMatchmaker = RxBool(_storage.read("start_matchmaker_automatically") ?? false); + automaticallyStartMatchmaker.listen((value) => _storage.write("start_matchmaker_automatically", value)); + doNotAskAgain = RxBool(_storage.read("do_not_ask_again") ?? false); doNotAskAgain.listen((value) => _storage.write("do_not_ask_again", value)); @@ -40,6 +55,12 @@ class SettingsController extends GetxController { height = _storage.read("height") ?? window.physicalSize.height; offsetX = _storage.read("offset_x"); offsetY = _storage.read("offset_y"); + + advancedMode = RxBool(_storage.read("advanced") ?? false); + advancedMode.listen((value) async => _storage.write("advanced", value)); + autoUpdate = RxBool(_storage.read("auto_update") ?? false); + autoUpdate.listen((value) async => _storage.write("auto_update", value)); + displayType = Rx(PaneDisplayMode.top); scrollingDistance = 0.0; @@ -50,7 +71,7 @@ class SettingsController extends GetxController { TextEditingController _createController(String key, String name) { loadBinary(name, true); - var controller = TextEditingController(text: _storage.read(key) ?? "$safeBinariesDirectory\\$name"); + var controller = TextEditingController(text: _storage.read(key) ?? "${safeBinariesDirectory.path}\\$name"); controller.addListener(() => _storage.write(key, controller.text)); return controller; diff --git a/lib/src/dialog/dialog.dart b/lib/src/dialog/dialog.dart index 09bb183..ddd0ad1 100644 --- a/lib/src/dialog/dialog.dart +++ b/lib/src/dialog/dialog.dart @@ -229,6 +229,16 @@ class ErrorDialog extends AbstractDialog { const ErrorDialog({super.key, required this.exception, required this.errorMessageBuilder, this.stackTrace}); + static DialogButton createCopyErrorButton({required Object error, required StackTrace? stackTrace, required Function() onClick, ButtonType type = ButtonType.primary}) => DialogButton( + text: "Copy error", + type: type, + onTap: () async { + FlutterClipboard.controlC("An error occurred: $error\nStacktrace:\n $stackTrace"); + showMessage("Copied error to clipboard"); + onClick(); + }, + ); + @override Widget build(BuildContext context) { return InfoDialog( @@ -239,14 +249,10 @@ class ErrorDialog extends AbstractDialog { ), if(stackTrace != null) - DialogButton( - text: "Copy error", - type: ButtonType.primary, - onTap: () async { - FlutterClipboard.controlC("An error occurred: $exception\nStacktrace:\n $stackTrace.toString"); - Navigator.of(context).pop(); - showMessage("Copied error to clipboard"); - }, + createCopyErrorButton( + error: exception, + stackTrace: stackTrace, + onClick: () => Navigator.pop(context) ) ], ); diff --git a/lib/src/dialog/game_dialogs.dart b/lib/src/dialog/game_dialogs.dart index 0c629eb..48a07fe 100644 --- a/lib/src/dialog/game_dialogs.dart +++ b/lib/src/dialog/game_dialogs.dart @@ -1,6 +1,19 @@ import 'package:fluent_ui/fluent_ui.dart'; -import 'package:reboot_launcher/main.dart'; import 'package:reboot_launcher/src/dialog/dialog.dart'; +import 'package:reboot_launcher/src/model/fortnite_version.dart'; + +import '../../main.dart'; + +const String _unsupportedServerError = "The build you are currently using is not supported by Reboot. " + "This means that you cannot currently host this version of the game. " + "For a list of supported versions, check #info in the Discord server. " + "If you are unsure which version works best, use build 7.40. " + "If you are a passionate programmer you can add support by opening a PR on Github. "; + +const String _corruptedBuildError = "The build you are currently using is corrupted. " + "This means that some critical files are missing for the game to launch. " + "Download the build again from the launcher or, if it's not available there, from another source. " + "Occasionally some files might get corrupted if there isn't enough space on your drive."; Future showBrokenError() async { showDialog( @@ -26,8 +39,17 @@ Future showTokenErrorFixable() async { builder: (context) => const InfoDialog( text: "A token error occurred. " "The backend server has been automatically restarted to fix the issue. " - "Relaunch your game to check if the issue has been automatically fixed. " - "Otherwise, open an issue on Discord." + "The game has been restarted automatically. " + ) + ); +} + +Future showTokenErrorCouldNotFix() async { + showDialog( + context: appKey.currentContext!, + builder: (context) => const InfoDialog( + text: "A token error occurred. " + "The game couldn't be recovered, open an issue on Discord." ) ); } @@ -42,4 +64,35 @@ Future showTokenErrorUnfixable() async { "Otherwise, open an issue on Discord." ) ); +} + +Future showCorruptedBuildError(bool server, [Object? error, StackTrace? stackTrace]) async { + if(error == null) { + showDialog( + context: appKey.currentContext!, + builder: (context) => InfoDialog( + text: server ? _unsupportedServerError : _corruptedBuildError + ) + ); + return; + } + + showDialog( + context: appKey.currentContext!, + builder: (context) => ErrorDialog( + exception: error, + stackTrace: stackTrace, + errorMessageBuilder: (exception) => _corruptedBuildError + ) + ); +} + +Future showMissingBuildError(FortniteVersion version) async { + showDialog( + context: appKey.currentContext!, + builder: (context) => InfoDialog( + text: "${version.location.path} no longer contains a Fortnite executable. " + "This probably means that you deleted it or move it somewhere else." + ) + ); } \ No newline at end of file diff --git a/lib/src/dialog/server_dialogs.dart b/lib/src/dialog/server_dialogs.dart index 38f18ef..25f7994 100644 --- a/lib/src/dialog/server_dialogs.dart +++ b/lib/src/dialog/server_dialogs.dart @@ -8,41 +8,49 @@ import 'package:reboot_launcher/src/dialog/dialog_button.dart'; import 'package:reboot_launcher/src/dialog/snackbar.dart'; import 'package:reboot_launcher/src/embedded/server.dart'; import 'package:reboot_launcher/src/model/server_type.dart'; +import 'package:reboot_launcher/src/util/os.dart'; import 'package:sync/semaphore.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../main.dart'; +import '../page/home_page.dart'; import '../util/server.dart'; extension ServerControllerDialog on ServerController { static Semaphore semaphore = Semaphore(); - Future start({required bool required, required bool askPortKill, bool isRetry = false}) async { + Future restart() async { + await resetWinNat(); + return (!started() || await stop()) && await toggle(); + } + + Future toggle() async { try{ semaphore.acquire(); if (type() == ServerType.local) { - return _pingSelfInteractive(required); + return _pingSelfInteractive(); } - var oldStarted = started(); - if(oldStarted && required){ - return true; - } - - started.value = !started.value; - var result = await _startInternal(oldStarted, required, askPortKill, isRetry); + var result = await _toggle(); if(!result){ - return false; + started.value = false; + return false; } - return await _pingSelfInteractive(true); + var ping = await _pingSelfInteractive(); + if(!ping){ + started.value = false; + return false; + } + + return true; }finally{ semaphore.release(); } } - Future _startInternal(bool oldStarted, bool required, bool askPortKill, bool isRetry) async { - if (oldStarted) { + Future _toggle([ServerResultType? lastResultType]) async { + if (started.value) { var result = await stop(); if (!result) { started.value = true; @@ -53,23 +61,23 @@ extension ServerControllerDialog on ServerController { return false; } - var conditions = await checkServerPreconditions(host.text, port.text, type.value, !required); - var result = conditions.type == ServerResultType.canStart ? await _startServer(required) : conditions; + started.value = true; + var conditions = await checkServerPreconditions(host.text, port.text, type.value); + var result = conditions.type == ServerResultType.canStart ? await _startServer() : conditions; if(result.type == ServerResultType.alreadyStarted) { started.value = false; return true; } - var handled = await _handleResultType(oldStarted, required, isRetry, askPortKill, result); + var handled = await _handleResultType(result, lastResultType); if (!handled) { - started.value = false; return false; } return handled; } - Future _startServer(bool closeAutomatically) async { + Future _startServer() async { try{ switch(type()){ case ServerType.embedded: @@ -79,7 +87,7 @@ extension ServerControllerDialog on ServerController { embeddedMatchmaker = await startEmbeddedMatchmaker(); break; case ServerType.remote: - var uriResult = await _pingRemoteInteractive(closeAutomatically); + var uriResult = await _pingRemoteInteractive(); if(uriResult == null){ return ServerResult( type: ServerResultType.cannotPingServer @@ -104,8 +112,9 @@ extension ServerControllerDialog on ServerController { ); } - Future _handleResultType(bool oldStarted, bool onlyIfNeeded, bool isRetry, bool askPortKill, ServerResult result) async { - switch (result.type) { + Future _handleResultType(ServerResult result, ServerResultType? lastResultType) async { + var newResultType = result.type; + switch (newResultType) { case ServerResultType.missingHostError: _showMissingHostError(); return false; @@ -117,33 +126,43 @@ extension ServerControllerDialog on ServerController { return false; case ServerResultType.cannotPingServer: return false; - case ServerResultType.portTakenError: - if (isRetry) { - _showPortTakenError(); + case ServerResultType.backendPortTakenError: + if (lastResultType == ServerResultType.backendPortTakenError) { + _showPortTakenError(3551); return false; } - if(askPortKill) { - var result = await _showPortTakenDialog(); - if (!result) { - return false; - } + var result = await _showPortTakenDialog(3551); + if (!result) { + return false; } await freeLawinPort(); - return _startInternal(oldStarted, onlyIfNeeded, askPortKill, true); + await stop(); + return _toggle(newResultType); + case ServerResultType.matchmakerPortTakenError: + if (lastResultType == ServerResultType.matchmakerPortTakenError) { + _showPortTakenError(8080); + return false; + } + + var result = await _showPortTakenDialog(8080); + if (!result) { + return false; + } + + await freeMatchmakerPort(); + await stop(); + return _toggle(newResultType); case ServerResultType.unknownError: - showDialog( - context: appKey.currentContext!, - builder: (context) => - ErrorDialog( - exception: result.error ?? Exception("Unknown error"), - stackTrace: result.stackTrace, - errorMessageBuilder: ( - exception) => "Cannot start server: $exception" - ) - ); - return false; + if(lastResultType == ServerResultType.unknownError) { + _showUnknownError(result); + return false; + } + + await resetWinNat(); + await stop(); + return _toggle(newResultType); case ServerResultType.alreadyStarted: case ServerResultType.canStart: return true; @@ -152,16 +171,15 @@ extension ServerControllerDialog on ServerController { } } - Future _pingSelfInteractive(bool closeAutomatically) async { + Future _pingSelfInteractive() async { try { - return await showDialog( + var resultFuture = compute(pingSelf, port.text) + .then((value) => value != null); + await showDialog( context: appKey.currentContext!, builder: (context) => FutureBuilderDialog( - future: Future.wait([ - compute(pingSelf, port.text), - Future.delayed(const Duration(seconds: 1)) - ]), + future: _waitFutureOrTime(resultFuture), loadingMessage: "Pinging ${type().id} server...", successfulBody: FutureBuilderDialog.ofMessage( "The ${type().id} server works correctly"), @@ -169,25 +187,23 @@ extension ServerControllerDialog on ServerController { "The ${type().id} server doesn't work. Check the backend tab for misconfigurations and try again."), errorMessageBuilder: ( exception) => "An error occurred while pining the ${type().id} server: $exception", - closeAutomatically: closeAutomatically + closeAutomatically: true ) - ) ?? false; + ); + return await resultFuture; } catch (_) { return false; } } - Future _pingRemoteInteractive(bool closeAutomatically) async { + Future _pingRemoteInteractive() async { try { var mainFuture = ping(host.text, port.text); - var result = await showDialog( + await showDialog( context: appKey.currentContext!, builder: (context) => FutureBuilderDialog( - future: Future.wait([ - mainFuture, - Future.delayed(const Duration(seconds: 1)) - ]), + future: _waitFutureOrTime(mainFuture.then((value) => value != null)), loadingMessage: "Pinging remote server...", successfulBody: FutureBuilderDialog.ofMessage( "The server at ${host.text}:${port @@ -195,32 +211,30 @@ extension ServerControllerDialog on ServerController { unsuccessfulBody: FutureBuilderDialog.ofMessage( "The server at ${host.text}:${port .text} doesn't work. Check the hostname and/or the port and try again."), - errorMessageBuilder: (exception) => "An error occurred while pining the server: $exception", - closeAutomatically: closeAutomatically + errorMessageBuilder: (exception) => "An error occurred while pining the server: $exception" ) ) ?? false; - return result ? await mainFuture : null; + return await mainFuture; } catch (_) { return null; } } - Future _showPortTakenError() async { + Future _showPortTakenError(int port) async { showDialog( context: appKey.currentContext!, - builder: (context) => - const InfoDialog( - text: "Port 3551 is already in use and the associating process cannot be killed. Kill it manually and try again.", + builder: (context) => InfoDialog( + text: "Port $port is already in use and the associating process cannot be killed. Kill it manually and try again.", ) ); } - Future _showPortTakenDialog() async { + Future _showPortTakenDialog(int port) async { return await showDialog( context: appKey.currentContext!, builder: (context) => InfoDialog( - text: "Port 3551 is already in use, do you want to kill the associated process?", + text: "Port $port is already in use, do you want to kill the associated process?", buttons: [ DialogButton( type: ButtonType.secondary, @@ -286,4 +300,24 @@ extension ServerControllerDialog on ServerController { void _showMissingHostError() { showMessage("Missing the host name for backend server"); } +} + +Future _showUnknownError(ServerResult result) { + return showDialog( + context: appKey.currentContext!, + builder: (context) => + ErrorDialog( + exception: result.error ?? Exception("Unknown error"), + stackTrace: result.stackTrace, + errorMessageBuilder: (exception) => "Cannot start the backend: an unknown error occurred" + ) + ); +} + +Future _waitFutureOrTime(Future resultFuture) { + return Future.wait([ + resultFuture, + Future.delayed(const Duration(seconds: 1)) + .then((value) => true) + ]).then((value) => value.reduce((f, s) => f && s)); } \ No newline at end of file diff --git a/lib/src/dialog/snackbar.dart b/lib/src/dialog/snackbar.dart index b7f76d7..f95522e 100644 --- a/lib/src/dialog/snackbar.dart +++ b/lib/src/dialog/snackbar.dart @@ -1,6 +1,7 @@ import 'package:fluent_ui/fluent_ui.dart'; import '../../main.dart'; +import '../page/home_page.dart'; void showMessage(String text){ showSnackbar( diff --git a/lib/src/embedded/auth.dart b/lib/src/embedded/auth.dart index a41d437..47f3781 100644 --- a/lib/src/embedded/auth.dart +++ b/lib/src/embedded/auth.dart @@ -328,6 +328,6 @@ File _getProfileFile(Context context) { _profiles.createSync(recursive: true); } - return File("${_profiles.path}\\ClientProfile-${parseSeasonBuild(context)}.json"); + return File("${_profiles.path}\\ClientProfile.json"); } diff --git a/lib/src/embedded/error.dart b/lib/src/embedded/error.dart index 53b3b38..75f6e14 100644 --- a/lib/src/embedded/error.dart +++ b/lib/src/embedded/error.dart @@ -4,28 +4,19 @@ import 'dart:io'; import 'package:jaguar/jaguar.dart'; class EmbeddedErrorWriter extends ErrorWriter { - static const String _errorName = "errors.com.lawinserver.common.not_found"; + static const String _errorName404 = "errors.com.lawinserver.common.not_found"; + static const String _errorName500 = "errors.com.lawinserver.common.error"; static const String _errorCode = "1004"; @override FutureOr make404(Context ctx) { stdout.writeln("Unknown path: ${ctx.uri} with method ${ctx.method}"); - ctx.response.headers.set('X-Epic-Error-Name', _errorName); + ctx.response.headers.set('X-Epic-Error-Name', _errorName404); ctx.response.headers.set('X-Epic-Error-Code', _errorCode); return Response.json( statusCode: 204, - {} - ); - } - - @override - FutureOr make500(Context ctx, Object error, [StackTrace? stack]) { - ctx.response.headers.set('X-Epic-Error-Name', _errorName); - ctx.response.headers.set('X-Epic-Error-Code', _errorCode); - return Response( - statusCode: 500, - body: { - "errorCode": _errorName, + { + "errorCode": _errorName404, "errorMessage": "Sorry the resource you were trying to find could not be found", "numericErrorCode": _errorCode, "originatingService": "any", @@ -33,4 +24,20 @@ class EmbeddedErrorWriter extends ErrorWriter { } ); } + + @override + FutureOr make500(Context ctx, Object error, [StackTrace? stack]) { + ctx.response.headers.set('X-Epic-Error-Name', _errorName500); + ctx.response.headers.set('X-Epic-Error-Code', _errorCode); + return Response.json( + statusCode: 500, + { + "errorCode": _errorName500, + "errorMessage": "Sorry the resource you were trying to find threw an error", + "numericErrorCode": _errorCode, + "originatingService": "any", + "intent": "prod" + } + ); + } } \ No newline at end of file diff --git a/lib/src/embedded/server.dart b/lib/src/embedded/server.dart index 131f3e5..24db100 100644 --- a/lib/src/embedded/server.dart +++ b/lib/src/embedded/server.dart @@ -14,24 +14,11 @@ import "error.dart"; import "lightswitch.dart"; import 'matchmaking.dart'; -bool _loggingCapabilities = false; - Future startEmbeddedServer(String Function() ipQuery) async { - var server = _createServer(ipQuery); - await server.serve(logRequests: true); - return server; -} - -Future startEmbeddedMatchmaker() async { - var server = _createMatchmaker(); - server.serve(logRequests: true); - return server; -} - -Jaguar _createServer(String Function() ipQuery) { - var server = Jaguar(address: "127.0.0.1", port: 3551, errorWriter: EmbeddedErrorWriter()); + var server = Jaguar(port: 3551, errorWriter: EmbeddedErrorWriter()); // Version + server.getJson("unknown", (context) => Response(body: "lawinserver")); server.getJson("/fortnite/api/version", getVersion); server.getJson("/fortnite/api/v2/versioncheck/*", hasUpdate); server.getJson("/fortnite/api/v2/versioncheck*", hasUpdate); @@ -105,23 +92,7 @@ Jaguar _createServer(String Function() ipQuery) { server.getJson("/fortnite/api/game/v2/privacy/account/:accountId", getPrivacy); server.postJson("/fortnite/api/game/v2/privacy/account/:accountId", postPrivacy); - return server; -} -Jaguar _createMatchmaker(){ - var server = Jaguar(address: "127.0.0.1", port: 8080); - WebSocket? ws; - server.wsStream( - "/", - (_, input) => ws = input, - after: [(_) => queueMatchmaking(ws!)] - ); - return _addLoggingCapabilities(server); -} - -Jaguar _addLoggingCapabilities(Jaguar server) { - if(_loggingCapabilities){ - return server; - } + await server.serve(logRequests: true); server.log.onRecord.listen((line) { stdout.writeln(line); @@ -133,6 +104,17 @@ Jaguar _addLoggingCapabilities(Jaguar server) { serverLogFile.writeAsString("An error occurred at ${ctx.uri}: \n$exception\n$trace\n", mode: FileMode.append); }); - _loggingCapabilities = true; + return server; +} + +Future startEmbeddedMatchmaker() async { + var server = Jaguar(port: 8080); + WebSocket? ws; + server.wsStream( + "/", + (_, input) => ws = input, + after: [(_) => queueMatchmaking(ws!)] + ); + await server.serve(logRequests: true); return server; } \ No newline at end of file diff --git a/lib/src/embedded/storage.dart b/lib/src/embedded/storage.dart index 2a24819..e9065ae 100644 --- a/lib/src/embedded/storage.dart +++ b/lib/src/embedded/storage.dart @@ -1,4 +1,4 @@ -import 'dart:convert'; +import 'package:path/path.dart' as path; import 'dart:io'; import 'package:jaguar/jaguar.dart'; @@ -11,23 +11,16 @@ import '../util/os.dart'; final Directory _settings = Directory("${Platform.environment["UserProfile"]}\\.reboot_launcher\\backend\\settings"); -const String _engineName = "DefaultEngine.ini"; -final String _engineIni = loadEmbedded("config/$_engineName").readAsStringSync(); +List getStorageSettings(Context context) => + loadEmbeddedDirectory("config") + .listSync() + .map((e) => File(e.path)) + .map(_getStorageSetting) + .toList(); -const String _gameName = "DefaultGame.ini"; -final String _gameIni = loadEmbedded("config/$_gameName").readAsStringSync(); - -const String _runtimeName = "DefaultRuntimeOptions.ini"; -final String _runtimeIni = loadEmbedded("config/$_runtimeName").readAsStringSync(); - -List> getStorageSettings(Context context) => [ - _getStorageSetting(_engineName, _engineIni), - _getStorageSetting(_gameName, _gameIni), - _getStorageSetting(_runtimeName, _runtimeIni) -]; - -Map _getStorageSetting(String name, String source){ - var bytes = utf8.encode(source); +Map _getStorageSetting(File file){ + var name = path.basename(file.path); + var bytes = file.readAsBytesSync(); return { "uniqueFilename": name, "filename": name, @@ -43,16 +36,8 @@ Map _getStorageSetting(String name, String source){ } Response getStorageSetting(Context context) { - switch(context.pathParams.get("file")){ - case _engineName: - return Response(body: _engineIni); - case _gameName: - return Response(body: _gameIni); - case _runtimeName: - return Response(body: _runtimeIni); - default: - return Response(); - } + var file = loadEmbedded("config\\${context.pathParams.get("file")}"); + return Response(body: file.readAsStringSync()); } Response getStorageFile(Context context) { @@ -107,5 +92,5 @@ File _getSettingsFile(Context context) { _settings.createSync(recursive: true); } - return File("${_settings.path}\\ClientSettings-${parseSeasonBuild(context)}.Sav"); + return File("${_settings.path}\\ClientSettings.Sav"); } \ No newline at end of file diff --git a/lib/src/model/game_instance.dart b/lib/src/model/game_instance.dart index 521324c..c1f1b84 100644 --- a/lib/src/model/game_instance.dart +++ b/lib/src/model/game_instance.dart @@ -4,8 +4,10 @@ class GameInstance { final Process gameProcess; final Process? launcherProcess; final Process? eacProcess; + bool tokenError; - GameInstance(this.gameProcess, this.launcherProcess, this.eacProcess); + GameInstance(this.gameProcess, this.launcherProcess, this.eacProcess) + : tokenError = false; void kill() { gameProcess.kill(ProcessSignal.sigabrt); diff --git a/lib/src/model/reboot_download.dart b/lib/src/model/reboot_download.dart new file mode 100644 index 0000000..aeb4416 --- /dev/null +++ b/lib/src/model/reboot_download.dart @@ -0,0 +1,11 @@ +import 'package:version/version.dart'; + +class RebootDownload { + final int updateTime; + final Object? error; + final StackTrace? stackTrace; + + RebootDownload(this.updateTime, [this.error, this.stackTrace]); + + bool get hasError => error != null; +} diff --git a/lib/src/page/home_page.dart b/lib/src/page/home_page.dart index f213085..c760a36 100644 --- a/lib/src/page/home_page.dart +++ b/lib/src/page/home_page.dart @@ -8,6 +8,7 @@ import 'package:reboot_launcher/src/controller/game_controller.dart'; import 'package:reboot_launcher/src/controller/server_controller.dart'; import 'package:reboot_launcher/src/dialog/dialog.dart'; import 'package:reboot_launcher/src/dialog/dialog_button.dart'; +import 'package:reboot_launcher/src/model/game_type.dart'; import 'package:reboot_launcher/src/page/settings_page.dart'; import 'package:reboot_launcher/src/page/launcher_page.dart'; import 'package:reboot_launcher/src/page/server_page.dart'; @@ -17,6 +18,7 @@ import 'package:reboot_launcher/src/widget/os/window_buttons.dart'; import 'package:window_manager/window_manager.dart'; import '../controller/settings_controller.dart'; +import '../model/server_type.dart'; import '../model/tutorial_page.dart'; import 'info_page.dart'; @@ -32,7 +34,6 @@ class _HomePageState extends State with WindowListener { static const double _sectionSize = 100.0; static const double _defaultPadding = 12.0; static const int _headerButtonCount = 3; - static const int _sectionButtonCount = 4; final GameController _gameController = Get.find(); final SettingsController _settingsController = Get.find(); @@ -51,20 +52,36 @@ class _HomePageState extends State with WindowListener { @override void initState() { windowManager.addListener(this); - _searchController.addListener(() { - if (searchValue.isEmpty) { - _searchItems.value = null; - return; - } - - _searchItems.value = _allItems.whereType() - .where((item) => (item.title as Text).data!.toLowerCase().contains(searchValue.toLowerCase())) - .toList() - .cast(); + _searchController.addListener(_onSearch); + _onEasyMode(); + _settingsController.advancedMode.listen((advanced) { + _onEasyMode(); + _index.value = _index.value + (advanced ? 1 : -1); }); super.initState(); } + void _onSearch() { + if (searchValue.isEmpty) { + _searchItems.value = null; + return; + } + + _searchItems.value = _allItems.whereType() + .where((item) => (item.title as Text).data!.toLowerCase().contains(searchValue.toLowerCase())) + .toList() + .cast(); + } + + void _onEasyMode() { + if(_settingsController.advancedMode.value){ + return; + } + + _gameController.type.value = GameType.client; + _serverController.type.value = ServerType.embedded; + } + @override void dispose() { windowManager.removeListener(this); @@ -119,29 +136,38 @@ class _HomePageState extends State with WindowListener { } @override - Widget build(BuildContext context) => NotificationListener( - onNotification: (notification) => _calculateSize(), - child: SizeChangedLayoutNotifier( - child: Obx(() => Stack( - children: [ - _createNavigationView(), - if(_settingsController.displayType() == PaneDisplayMode.top) - Align( - alignment: Alignment.topRight, - child: WindowTitleBar(focused: _focused()) - ), - if(_settingsController.displayType() == PaneDisplayMode.top) - _createTopDisplayGestures(), - if(_focused() && isWin11) - const WindowBorder() - ]) - ) - ) - ); + Widget build(BuildContext context) { + return NotificationListener( + onNotification: (notification) { + return _calculateSize(); + }, + child: SizeChangedLayoutNotifier( + child: Obx(_getViewStack) + ) + ); + } - Padding _createTopDisplayGestures() => Padding( - padding: const EdgeInsets.only( - left: _sectionSize * _sectionButtonCount, + Widget _getViewStack() { + var view = _createNavigationView(); + return Stack( + children: [ + view, + if(_settingsController.displayType() == PaneDisplayMode.top) + Align( + alignment: Alignment.topRight, + child: WindowTitleBar(focused: _focused()) + ), + if(_settingsController.displayType() == PaneDisplayMode.top) + _createTopDisplayGestures(view.pane?.items.length ?? 0), + if(_focused() && isWin11) + const WindowBorder() + ] + ); + } + + Padding _createTopDisplayGestures(int size) => Padding( + padding: EdgeInsets.only( + left: _sectionSize * size, right: _headerSize * _headerButtonCount, ), child: SizedBox( @@ -205,11 +231,11 @@ class _HomePageState extends State with WindowListener { ); } - RenderObjectWidget _createPage(Widget? body) { + Widget _createPage(Widget? body) { if(_settingsController.displayType() == PaneDisplayMode.top){ return Padding( - padding: const EdgeInsets.all(_defaultPadding), - child: body + padding: const EdgeInsets.all(_defaultPadding), + child: body ); } @@ -267,10 +293,9 @@ class _HomePageState extends State with WindowListener { List _createFooterItems() => searchValue.isNotEmpty ? [] : [ if(_settingsController.displayType() != PaneDisplayMode.top) PaneItem( - title: const Text("Tutorial"), - icon: const Icon(FluentIcons.info), - body: const InfoPage(), - onTap: _onTutorial + title: const Text("Settings"), + icon: const Icon(FluentIcons.settings), + body: SettingsPage() ) ]; @@ -281,24 +306,25 @@ class _HomePageState extends State with WindowListener { body: const LauncherPage() ), - PaneItem( - title: const Text("Backend"), - icon: const Icon(FluentIcons.server_enviroment), - body: ServerPage() - ), + if(_settingsController.advancedMode.value) + PaneItem( + title: const Text("Backend"), + icon: const Icon(FluentIcons.server_enviroment), + body: ServerPage() + ), PaneItem( - title: const Text("Settings"), - icon: const Icon(FluentIcons.settings), - body: SettingsPage() + title: const Text("Tutorial"), + icon: const Icon(FluentIcons.info), + body: const InfoPage(), + onTap: _onTutorial ), if(_settingsController.displayType() == PaneDisplayMode.top) PaneItem( - title: const Text("Tutorial"), - icon: const Icon(FluentIcons.info), - body: const InfoPage(), - onTap: _onTutorial + title: const Text("Settings"), + icon: const Icon(FluentIcons.settings), + body: SettingsPage() ) ]; diff --git a/lib/src/page/info_page.dart b/lib/src/page/info_page.dart index b98b0f5..94257ba 100644 --- a/lib/src/page/info_page.dart +++ b/lib/src/page/info_page.dart @@ -14,27 +14,25 @@ class InfoPage extends StatefulWidget { class _InfoPageState extends State { final List _elseTitles = [ - "Open the settings tab", - "Type the ip address of the host, including the port if it's not 7777\n The complete address should follow the schema ip:port", "Open the home page", + "Type the ip address of the host, including the port if it's not 7777\n The complete address should follow the schema ip:port", "Type your username if you haven't already", "Select the exact version that the host is using from the dropdown menu\n If necessary, install it using the download button", "As you want to play, select client from the dropdown menu", - "Click launch to open the game", + "Click launch to open the game\n If the game closes immediately, it means that the build you downloaded is corrupted\n The same is valid if an Unreal Crash window opens\n Download another and try again", "Once you are in game, click PLAY to enter in-game\n If this doesn't work open the Fortnite console by clicking the button above tab\n If nothing happens, make sure that your keyboard locale is set to English\n Type 'open TYPE_THE_IP' without the quotes, for example: open 85.182.12.1" ]; final List _ownTitles = [ - "Open the settings tab", - "Type 127.0.0.1 as the matchmaking host", "Open the home page", + "Type 127.0.0.1 as the matchmaking host\n If you didn't know, 127.0.0.1 is the ip for your local machine", "Type your username if you haven't already", - "Select the version you want to host\n If necessary, install it using the download button", - "As you want to host, select Headless Server from the dropdown menu\n If the headless server doesn't work for your version, use the normal server instead", - "Click launch to start the server and wait until the Reboot GUI shows up", + "Select the version you want to host\n If necessary, install it using the download button\n Check the supported versions in #info in the Discord server\n Fortnite 7.40 is the best one to use usually", + "As you want to host, select headless server from the dropdown menu\n If the headless server doesn't work for your version, use the normal server instead\n The difference between the two is that the first doesn't render a fortnite instance\n Both will not allow you to play, only to host\n You will see an infinite loading screen when using the normal server\n If you want to also play continue reading", + "Click launch to start the server and wait until the Reboot GUI shows up\n If the game closes immediately, it means that the build you downloaded is corrupted\n The same is valid if an Unreal Crash window opens\n Download another and try again", "To allow your friends to join your server, follow the instructions on playit.gg\n If you are an advanced user, open port 7777 on your router\n Finally, share your playit ip or public IPv4 address with your friends\n If you just want to play by yourself, skip this step", - "When you want to start the game, click on the 'Start Bus Countdown' button", - "If you also want to play, start a client by selecting Client from the dropdown menu\n Don't close or open again the launcher, use the same window", - "Click launch to open the game", + "When you want to start the game, click on the 'Start Bus Countdown' button\n Before clicking that button, make all of your friends join\n This is because joining mid-game isn't allowed", + "If you also want to play, start a client by selecting Client from the dropdown menu\n Don't close or open again the launcher, use the same window\n Remember to keep both the headless server(or server) and client open\n If you want to close the client or server, simply switch between them using the menu\n The launcher will remember what instances you have opened", + "Click launch to open the game\n If the game closes immediately, it means that the build you downloaded is corrupted\n The same is valid if an Unreal Crash window opens\n Download another and try again", "Once you are in game, click PLAY to enter in-game\n If this doesn't work open the Fortnite console by clicking the button above tab\n If nothing happens, make sure that your keyboard locale is set to English\n Type 'open TYPE_THE_IP' without the quotes, for example: open 85.182.12.1" ]; diff --git a/lib/src/page/launcher_page.dart b/lib/src/page/launcher_page.dart index a17cbe2..09c40f0 100644 --- a/lib/src/page/launcher_page.dart +++ b/lib/src/page/launcher_page.dart @@ -1,19 +1,31 @@ import 'dart:async'; +import 'dart:io'; import 'package:fluent_ui/fluent_ui.dart'; import 'package:flutter/foundation.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; +import 'package:reboot_launcher/main.dart'; import 'package:reboot_launcher/src/controller/build_controller.dart'; import 'package:reboot_launcher/src/controller/game_controller.dart'; +import 'package:reboot_launcher/src/controller/server_controller.dart'; +import 'package:reboot_launcher/src/controller/settings_controller.dart'; import 'package:reboot_launcher/src/dialog/dialog.dart'; +import 'package:reboot_launcher/src/model/reboot_download.dart'; +import 'package:reboot_launcher/src/util/os.dart'; import 'package:reboot_launcher/src/widget/home/game_type_selector.dart'; import 'package:reboot_launcher/src/widget/home/launch_button.dart'; import 'package:reboot_launcher/src/widget/home/username_box.dart'; import 'package:reboot_launcher/src/widget/home/version_selector.dart'; +import 'package:reboot_launcher/src/widget/shared/file_selector.dart'; +import '../dialog/dialog_button.dart'; +import '../model/server_type.dart'; +import '../util/checks.dart'; import '../util/reboot.dart'; +import '../widget/shared/smart_input.dart'; +import 'home_page.dart'; class LauncherPage extends StatefulWidget { const LauncherPage( @@ -26,21 +38,91 @@ class LauncherPage extends StatefulWidget { class _LauncherPageState extends State { final GameController _gameController = Get.find(); + final ServerController _serverController = Get.find(); + final SettingsController _settingsController = Get.find(); final BuildController _buildController = Get.find(); @override void initState() { - if(_gameController.updater == null){ - _gameController.updater = compute(downloadRebootDll, _updateTime) - ..then((value) => _updateTime = value) - ..then((value) => _gameController.updated = true); - _buildController.cancelledDownload - .listen((value) => value ? _onCancelWarning() : {}); + if(_gameController.updater == null) { + _startUpdater(); + _setupBuildWarning(); } super.initState(); } + void _setupBuildWarning() { + _buildController.cancelledDownload + .listen((value) => value ? _onCancelWarning() : {}); + } + + void _startUpdater() { + _gameController.updater = StreamController.broadcast(); + downloadRebootDll(_settingsController.updateUrl.text, _updateTime) + ..then((result) async { + if(!result.hasError){ + _updateTime = result.updateTime; + _gameController.updated = true; + _gameController.failing = false; + _gameController.error = false; + _gameController.updater?.add(true); + return; + } + + if(_gameController.failing){ + _gameController.updated = false; + _gameController.failing = false; + _gameController.error = true; + _gameController.updater?.add(false); + return; + } + + _gameController.failing = true; + showDialog( + context: appKey.currentContext!, + builder: (context) => InfoDialog( + text: "An error occurred while downloading the reboot dll: this usually means that your antivirus flagged it. " + "Do you want to add an exclusion to Windows Defender to fix the issue? " + "If you are using a different antivirus disable it manually as this won't work. ", + buttons: [ + ErrorDialog.createCopyErrorButton( + error: result.error ?? Exception("Unknown error"), + stackTrace: result.stackTrace, + type: ButtonType.secondary, + onClick: () { + Navigator.pop(context); + _gameController.updated = false; + _gameController.failing = false; + _gameController.error = true; + _gameController.updater?.add(false); + } + ), + DialogButton( + text: "Add", + type: ButtonType.primary, + onTap: () async { + Navigator.pop(context); + var binary = await loadBinary("antivirus.bat", true); + var result = await runElevated(binary.path, ""); + if(!result) { + _gameController.failing = false; + } + + _startUpdater(); + } + ), + ], + ) + ); + }) + ..catchError((error, stackTrace) { + _gameController.error = true; + _gameController.updater?.add(false); + return RebootDownload(0, error, stackTrace); + }); + } + int? get _updateTime { var storage = GetStorage("update"); return storage.read("last_update_v2"); @@ -64,63 +146,71 @@ class _LauncherPageState extends State { } @override - Widget build(BuildContext context) { - return FutureBuilder( - future: _gameController.updater ?? Future.value(true), - builder: (context, snapshot) { - if (!_gameController.updated && !snapshot.hasData && !snapshot.hasError) { - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: const [ - ProgressRing(), - SizedBox(height: 16.0), - Text("Updating Reboot DLL...") - ], - ), - ], - ); - } + Widget build(BuildContext context) => StreamBuilder( + stream: _gameController.updater!.stream, + builder: (context, snapshot) => !_gameController.updated && !_gameController.error ? _updateScreen : _homeScreen + ); - return Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if(snapshot.hasError) - _createUpdateError(snapshot), - UsernameBox(), - const VersionSelector(), - GameTypeSelector(), - const LaunchButton() - ], - ); - } - ); - } + Widget get _homeScreen => Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if(_gameController.error) + _updateError, + UsernameBox(), + Tooltip( + message: + "The hostname of the server that hosts the multiplayer matches", + child: Obx(() => SmartInput( + label: "Matchmaking Host", + placeholder: + "Type the hostname of the server that hosts the multiplayer matches", + controller: _settingsController.matchmakingIp, + validatorMode: AutovalidateMode.always, + validator: checkMatchmaking, + enabled: _serverController.type() == ServerType.embedded) + ) + ), + const VersionSelector(), + if(_settingsController.advancedMode.value) + GameTypeSelector(), + const LaunchButton() + ], + ); - Widget _createUpdateError(AsyncSnapshot snapshot) { + Widget get _updateScreen => Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [ + ProgressRing(), + SizedBox(height: 16.0), + Text("Updating Reboot DLL...") + ], + ), + ], + ); + + Widget get _updateError { return MouseRegion( cursor: SystemMouseCursors.click, child: GestureDetector( onTap: () { - showDialog( - context: context, - builder: (context) => ErrorDialog( - exception: snapshot.error!, - stackTrace: snapshot.stackTrace!, - errorMessageBuilder: (exception) => "Cannot update Reboot dll: ${snapshot.error}" - ) - ); + _gameController.updated = false; + _gameController.failing = false; + _gameController.error = false; + _gameController.updater?.add(false); + _startUpdater(); }, child: const SizedBox( width: double.infinity, child: InfoBar( - title: Text("Cannot update dll"), + title: Text("The Reboot dll wasn't downloaded: disable your antivirus or proxy and click here to try again" + ), severity: InfoBarSeverity.info - ), - ) + ) + ), ), ); } diff --git a/lib/src/page/server_page.dart b/lib/src/page/server_page.dart index 5344b4f..bb5d185 100644 --- a/lib/src/page/server_page.dart +++ b/lib/src/page/server_page.dart @@ -18,12 +18,17 @@ class ServerPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ if(_serverController.warning.value) - SizedBox( - width: double.infinity, - child: InfoBar( - title: const Text("The backend server handles authentication and parties, not game hosting"), - severity: InfoBarSeverity.info, - onClose: () => _serverController.warning.value = false + GestureDetector( + onTap: () => _serverController.warning.value = false, + child: const MouseRegion( + cursor: SystemMouseCursors.click, + child: SizedBox( + width: double.infinity, + child: InfoBar( + title: Text("The backend server handles authentication and parties, not game hosting"), + severity: InfoBarSeverity.info + ), + ), ), ), HostInput(), diff --git a/lib/src/page/settings_page.dart b/lib/src/page/settings_page.dart index 16661de..f671fe1 100644 --- a/lib/src/page/settings_page.dart +++ b/lib/src/page/settings_page.dart @@ -1,87 +1,121 @@ + import 'package:fluent_ui/fluent_ui.dart'; import 'package:flutter/foundation.dart'; import 'package:get/get.dart'; -import 'package:get_storage/get_storage.dart'; -import 'package:reboot_launcher/src/controller/server_controller.dart'; import 'package:reboot_launcher/src/controller/settings_controller.dart'; -import 'package:reboot_launcher/src/dialog/snackbar.dart'; -import 'package:reboot_launcher/src/model/server_type.dart'; +import 'package:reboot_launcher/src/util/os.dart'; import 'package:reboot_launcher/src/widget/shared/smart_switch.dart'; +import 'package:url_launcher/url_launcher.dart'; import '../util/checks.dart'; +import '../widget/setting/url_updater.dart'; import '../widget/shared/file_selector.dart'; -import '../widget/shared/smart_input.dart'; class SettingsPage extends StatelessWidget { - final ServerController _serverController = Get.find(); final SettingsController _settingsController = Get.find(); SettingsPage({Key? key}) : super(key: key); @override - Widget build(BuildContext context) { - return Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Tooltip( - message: - "The hostname of the server that hosts the multiplayer matches", - child: Obx(() => SmartInput( - label: "Matchmaking Host", - placeholder: - "Type the hostname of the server that hosts the multiplayer matches", - controller: _settingsController.matchmakingIp, - validatorMode: AutovalidateMode.always, - validator: checkMatchmaking, - enabled: _serverController.type() == ServerType.embedded))), - Tooltip( - message: "The dll that is injected when a server is launched", - child: FileSelector( - label: "Reboot DLL", - placeholder: "Type the path to the reboot dll", - controller: _settingsController.rebootDll, - windowTitle: "Select a dll", - folder: false, - extension: "dll", - validator: checkDll, - validatorMode: AutovalidateMode.always), - ), - Tooltip( - message: "The dll that is injected when a client is launched", - child: FileSelector( - label: "Console DLL", - placeholder: "Type the path to the console dll", - controller: _settingsController.consoleDll, - windowTitle: "Select a dll", - folder: false, - extension: "dll", - validator: checkDll, - validatorMode: AutovalidateMode.always), - ), - Tooltip( - message: "The dll that is injected to make the game work", - child: FileSelector( - label: "Cranium DLL", - placeholder: - "Type the path to the dll used for authentication", - controller: _settingsController.authDll, - windowTitle: "Select a dll", - folder: false, - extension: "dll", - validator: checkDll, - validatorMode: AutovalidateMode.always)), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text("Version Status"), - const SizedBox(height: 6.0), - Button( - child: const Text("6.0${kDebugMode ? '-DEBUG' : '-RELEASE'}"), - onPressed: () => showMessage("What a nice launcher") - ) - ], - ) - ]); - } + Widget build(BuildContext context) => + _settingsController.advancedMode.value ? _advancedSettings : _easySettings; + + Widget get _advancedSettings => Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const RebootUpdaterInput(), + _createFileSelector(), + _createConsoleSelector(), + _createGameSelector(), + _createVersionInfo(), + _createAdvancedSwitch() + ] + ); + + Widget get _easySettings => SizedBox.expand( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const CircleAvatar( + radius: 48, + backgroundImage: AssetImage("assets/images/auties.png")), + const SizedBox( + height: 16.0, + ), + const Text("Made by Auties00"), + const SizedBox( + height: 4.0, + ), + _versionText, + const SizedBox( + height: 8.0, + ), + Button( + child: const Text("Switch to advanced mode"), + onPressed: () => _settingsController.advancedMode.value = true + ) + ], + ), + ); + + Widget _createAdvancedSwitch() => SmartSwitch( + label: "Advanced Mode", + value: _settingsController.advancedMode + ); + + Widget _createVersionInfo() => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text("Version Status"), + const SizedBox(height: 6.0), + Button( + child: _versionText, + onPressed: () => launchUrl(safeBinariesDirectory.uri) + ) + ], + ); + + Widget _createGameSelector() => Tooltip( + message: "The dll that is injected to make the game work", + child: FileSelector( + label: "Cranium DLL", + placeholder: + "Type the path to the dll used for authentication", + controller: _settingsController.authDll, + windowTitle: "Select a dll", + folder: false, + extension: "dll", + validator: checkDll, + validatorMode: AutovalidateMode.always + ) + ); + + Widget _createConsoleSelector() => Tooltip( + message: "The dll that is injected when a client is launched", + child: FileSelector( + label: "Console DLL", + placeholder: "Type the path to the console dll", + controller: _settingsController.consoleDll, + windowTitle: "Select a dll", + folder: false, + extension: "dll", + validator: checkDll, + validatorMode: AutovalidateMode.always), + ); + + Widget _createFileSelector() => Tooltip( + message: "The dll that is injected when a server is launched", + child: FileSelector( + label: "Reboot DLL", + placeholder: "Type the path to the reboot dll", + controller: _settingsController.rebootDll, + windowTitle: "Select a dll", + folder: false, + extension: "dll", + validator: checkDll, + validatorMode: AutovalidateMode.always), + ); + + Widget get _versionText => const Text("6.4${kDebugMode ? '-DEBUG' : '-RELEASE'}"); } diff --git a/lib/src/util/build.dart b/lib/src/util/build.dart index af04502..4e0f269 100644 --- a/lib/src/util/build.dart +++ b/lib/src/util/build.dart @@ -51,12 +51,19 @@ Future> fetchBuilds(ignored) async { Future downloadManifestBuild( String manifestUrl, String destination, Function(double, String) onProgress) async { - var buildExe = await loadBinary("build.exe", false); + var log = await loadBinary("download.txt", true); + await log.create(); + + var buildExe = await loadBinary("build.exe", true); var process = await Process.start(buildExe.path, [manifestUrl, destination]); + log.writeAsString("Starting download of: $manifestUrl\n", mode: FileMode.append); process.errLines .where((message) => message.contains("%")) - .forEach((message) => onProgress(double.parse(message.split("%")[0]), message.substring(message.indexOf(" ") + 1))); + .forEach((message) { + log.writeAsString("$message\n", mode: FileMode.append); + onProgress(double.parse(message.split("%")[0]), message.substring(message.indexOf(" ") + 1)); + }); return process; } @@ -104,7 +111,7 @@ Future downloadArchiveBuild(String archiveUrl, String destination, var shell = Shell( commandVerbose: false, commentVerbose: false, - workingDirectory: safeBinariesDirectory + workingDirectory: safeBinariesDirectory.path ); await shell.run("./winrar.exe x \"${tempFile.path}\" *.* \"${output.path}\""); } finally { diff --git a/lib/src/util/checks.dart b/lib/src/util/checks.dart index 789f6df..1a41a36 100644 --- a/lib/src/util/checks.dart +++ b/lib/src/util/checks.dart @@ -14,6 +14,14 @@ String? checkVersion(String? text, List versions) { return null; } +String? checkChangeVersion(String? text) { + if (text == null || text.isEmpty) { + return 'Empty version name'; + } + + return null; +} + String? checkGameFolder(text) { if (text == null || text.isEmpty) { return 'Empty game path'; diff --git a/lib/src/util/error.dart b/lib/src/util/error.dart index 340fae5..6cf24f1 100644 --- a/lib/src/util/error.dart +++ b/lib/src/util/error.dart @@ -1,6 +1,7 @@ import 'package:fluent_ui/fluent_ui.dart'; import '../../main.dart'; +import '../page/home_page.dart'; import '../dialog/dialog.dart'; void onError(Object? exception, StackTrace? stackTrace, bool framework) { diff --git a/lib/src/util/os.dart b/lib/src/util/os.dart index da79d59..8eab2f9 100644 --- a/lib/src/util/os.dart +++ b/lib/src/util/os.dart @@ -4,6 +4,8 @@ import 'package:win32/win32.dart'; import 'package:ffi/ffi.dart'; import 'dart:ffi'; +import 'package:path/path.dart' as path; + const int appBarSize = 2; final RegExp _regex = RegExp(r'(?<=\(Build )(.*)(?=\))'); @@ -18,7 +20,7 @@ bool get isWin11 { } Future loadBinary(String binary, bool safe) async{ - var safeBinary = File("$safeBinariesDirectory\\$binary"); + var safeBinary = File("${safeBinariesDirectory.path}\\$binary"); if(await safeBinary.exists()){ return safeBinary; } @@ -35,36 +37,77 @@ Future loadBinary(String binary, bool safe) async{ return safeBinary; } +File _locateInternalBinary(String binary) => + File("${internalAssetsDirectory.path}\\binaries\\$binary"); + +Future resetWinNat() async { + var binary = await loadBinary("winnat.bat", true); + await runElevated(binary.path, ""); +} + Future runElevated(String executable, String args) async { var shellInput = calloc(); shellInput.ref.lpFile = executable.toNativeUtf16(); shellInput.ref.lpParameters = args.toNativeUtf16(); - shellInput.ref.nShow = SW_SHOWDEFAULT; - shellInput.ref.fMask = 0x00000040; + shellInput.ref.nShow = SW_HIDE; + shellInput.ref.fMask = ES_AWAYMODE_REQUIRED; shellInput.ref.lpVerb = "runas".toNativeUtf16(); shellInput.ref.cbSize = sizeOf(); var shellResult = ShellExecuteEx(shellInput); return shellResult == 1; } -File _locateInternalBinary(String binary){ - return File("$internalBinariesDirectory\\$binary"); -} - -String get internalBinariesDirectory => - "${File(Platform.resolvedExecutable).parent.path}\\data\\flutter_assets\\assets\\binaries"; +Directory get internalAssetsDirectory => + Directory("${File(Platform.resolvedExecutable).parent.path}\\data\\flutter_assets\\assets"); Directory get tempDirectory => Directory("${Platform.environment["Temp"]}"); -String get safeBinariesDirectory => - "${Platform.environment["UserProfile"]}\\.reboot_launcher"; +Directory get safeBinariesDirectory => + Directory("${Platform.environment["UserProfile"]}\\.reboot_launcher"); + +Directory get embeddedBackendDirectory => + Directory("${safeBinariesDirectory.path}\\backend"); File loadEmbedded(String file) { - var safeBinary = File("$safeBinariesDirectory\\backend\\cli\\$file"); + var safeBinary = File("${embeddedBackendDirectory.path}\\$file"); if(safeBinary.existsSync()){ return safeBinary; } - return File("${File(Platform.resolvedExecutable).parent.path}\\data\\flutter_assets\\assets\\$file"); + safeBinary.parent.createSync(recursive: true); + var internal = File("${internalAssetsDirectory.path}\\$file"); + if(internal.existsSync()) { + internal.copySync(safeBinary.path); + } + + return safeBinary; +} + +Directory loadEmbeddedDirectory(String directory) { + var safeBinary = Directory("${embeddedBackendDirectory.path}\\$directory"); + safeBinary.parent.createSync(recursive: true); + var internal = Directory("${internalAssetsDirectory.path}\\$directory"); + _copyFolder(internal, safeBinary); + return safeBinary; +} + +void _copyFolder(Directory dir1, Directory dir2) { + if(!dir1.existsSync()){ + return; + } + + if (!dir2.existsSync()) { + dir2.createSync(recursive: true); + } + + dir1.listSync().forEach((element) { + var newPath = "${dir2.path}/${path.basename(element.path)}"; + if (element is File) { + var newFile = File(newPath); + newFile.writeAsBytesSync(element.readAsBytesSync()); + } else if (element is Directory) { + _copyFolder(element, Directory(newPath)); + } + }); } \ No newline at end of file diff --git a/lib/src/util/process.dart b/lib/src/util/process.dart new file mode 100644 index 0000000..4f8e246 --- /dev/null +++ b/lib/src/util/process.dart @@ -0,0 +1,34 @@ +import 'dart:ffi'; + +import 'package:win32/src/kernel32.dart'; +import 'package:win32/win32.dart'; + +final _ntdll = DynamicLibrary.open('ntdll.dll'); + +// ignore: non_constant_identifier_names +int NtResumeProcess(int hWnd) { + final function = _ntdll.lookupFunction('NtResumeProcess'); + return function(hWnd); +} + +// ignore: non_constant_identifier_names +int NtSuspendProcess(int hWnd) { + final function = _ntdll.lookupFunction('NtSuspendProcess'); + return function(hWnd); +} + +bool suspend(int pid) { + final processHandle = OpenProcess(PROCESS_SUSPEND_RESUME, FALSE, pid); + final result = NtSuspendProcess(processHandle); + CloseHandle(processHandle); + return (result == 0) ? true : false; +} + +bool resume(int pid) { + final processHandle = OpenProcess(PROCESS_SUSPEND_RESUME, FALSE, pid); + final result = NtResumeProcess(processHandle); + CloseHandle(processHandle); + return (result == 0) ? true : false; +} diff --git a/lib/src/util/reboot.dart b/lib/src/util/reboot.dart index d87b3bd..b03da9b 100644 --- a/lib/src/util/reboot.dart +++ b/lib/src/util/reboot.dart @@ -4,43 +4,57 @@ import 'package:archive/archive_io.dart'; import 'package:crypto/crypto.dart'; import 'package:http/http.dart' as http; import 'package:path/path.dart' as path; +import 'package:reboot_launcher/src/model/reboot_download.dart'; import 'package:reboot_launcher/src/util/os.dart'; -const _rebootUrl = +const String rebootDownloadUrl = "https://nightly.link/Milxnor/Project-Reboot/workflows/msbuild/main/Release.zip"; -Future _getLastUpdate(int? lastUpdateMs) async { - return lastUpdateMs != null ? DateTime.fromMillisecondsSinceEpoch(lastUpdateMs) : null; +Future downloadRebootDll(String url, int? lastUpdateMs) async { + Directory? outputDir; + File? tempZip; + try { + var now = DateTime.now(); + var oldRebootDll = await loadBinary("reboot.dll", true); + var lastUpdate = await _getLastUpdate(lastUpdateMs); + var exists = await oldRebootDll.exists(); + if (lastUpdate != null && + now.difference(lastUpdate).inHours <= 24 && + await oldRebootDll.exists()) { + return RebootDownload(lastUpdateMs!); + } + + var response = await http.get(Uri.parse(rebootDownloadUrl)); + var tempZip = await loadBinary("reboot.zip", true); + await tempZip.writeAsBytes(response.bodyBytes); + + var outputDir = await safeBinariesDirectory.createTemp("reboot_out"); + await extractFileToDisk(tempZip.path, outputDir.path); + + var rebootDll = File(outputDir + .listSync() + .firstWhere((element) => path.extension(element.path) == ".dll") + .path); + + if (!exists || + sha1.convert(await oldRebootDll.readAsBytes()) != + sha1.convert(await rebootDll.readAsBytes())) { + await oldRebootDll.writeAsBytes(await rebootDll.readAsBytes()); + } + + return RebootDownload(now.millisecondsSinceEpoch); + } catch (error, stackTrace) { + return RebootDownload(-1, error, stackTrace); + } finally { + try { + outputDir?.delete(recursive: true); + tempZip?.delete(); + } catch (_) {} + } } -Future downloadRebootDll(int? lastUpdateMs) async { - var now = DateTime.now(); - var oldRebootDll = await loadBinary("reboot.dll", true); - var lastUpdate = await _getLastUpdate(lastUpdateMs); - var exists = await oldRebootDll.exists(); - if(lastUpdate != null && now.difference(lastUpdate).inHours <= 24 && await oldRebootDll.exists()){ - return lastUpdateMs!; - } - - var response = await http.get(Uri.parse(_rebootUrl)); - var tempZip = File("${tempDirectory.path}/reboot.zip"); - await tempZip.writeAsBytes(response.bodyBytes); - - var outputDir = await tempDirectory.createTemp("reboot"); - await extractFileToDisk(tempZip.path, outputDir.path); - - var rebootDll = File( - outputDir.listSync() - .firstWhere((element) => path.extension(element.path) == ".dll") - .path - ); - - if (exists && sha1.convert(await oldRebootDll.readAsBytes()) == sha1.convert(await rebootDll.readAsBytes())) { - outputDir.delete(recursive: true); - return now.millisecondsSinceEpoch; - } - - await oldRebootDll.writeAsBytes(await rebootDll.readAsBytes()); - outputDir.delete(recursive: true); - return now.millisecondsSinceEpoch; -} \ No newline at end of file +Future _getLastUpdate(int? lastUpdateMs) async { + return lastUpdateMs != null + ? DateTime.fromMillisecondsSinceEpoch(lastUpdateMs) + : null; +} diff --git a/lib/src/util/server.dart b/lib/src/util/server.dart index 49d25d4..f43ba58 100644 --- a/lib/src/util/server.dart +++ b/lib/src/util/server.dart @@ -8,29 +8,40 @@ import 'package:reboot_launcher/src/util/os.dart'; import 'package:shelf_proxy/shelf_proxy.dart'; import 'package:shelf/shelf_io.dart'; +import 'package:http/http.dart' as http; + final serverLogFile = File("${Platform.environment["UserProfile"]}\\.reboot_launcher\\server.txt"); Future isLawinPortFree() async { - try { - var portBat = await loadBinary("port.bat", true); - var process = await Process.run(portBat.path, []); - return !process.outText.contains(" LISTENING "); - }catch(_){ - return ServerSocket.bind("127.0.0.1", 3551) - .then((socket) => socket.close()) - .then((_) => true) - .onError((error, _) => false); - } + return http.get(Uri.parse("http://127.0.0.1:3551/unknown")) + .timeout(const Duration(milliseconds: 500)) + .then((value) => false) + .onError((error, stackTrace) => true); +} + +Future isMatchmakerPortFree() async { + return HttpServer.bind("127.0.0.1", 8080) + .then((socket) => socket.close()) + .then((_) => true) + .onError((error, _) => false); } Future freeLawinPort() async { - var releaseBat = await loadBinary("release.bat", false); + var releaseBat = await loadBinary("kill_lawin_port.bat", false); var result = await Process.run(releaseBat.path, []); - if(!result.outText.contains("Access is denied")){ - return; + if(result.exitCode == 1){ + await runElevated(releaseBat.path, ""); + await Future.delayed(const Duration(seconds: 1)); } +} - await runElevated(releaseBat.path, ""); +Future freeMatchmakerPort() async { + var releaseBat = await loadBinary("kill_matchmaker_port.bat", false); + var result = await Process.run(releaseBat.path, []); + if(result.exitCode == 1){ + await runElevated(releaseBat.path, ""); + await Future.delayed(const Duration(seconds: 1)); + } } List createRebootArgs(String username, GameType type) { @@ -92,7 +103,7 @@ String? _getHostName(String host) => host.replaceFirst("http://", "").replaceFir String? _getScheme(String host) => host.startsWith("http://") ? "http" : host.startsWith("https://") ? "https" : null; -Future checkServerPreconditions(String host, String port, ServerType type, bool needsFreePort) async { +Future checkServerPreconditions(String host, String port, ServerType type) async { host = host.trim(); if(host.isEmpty){ return ServerResult( @@ -113,19 +124,16 @@ Future checkServerPreconditions(String host, String port, ServerTy ); } - if(type == ServerType.embedded || type == ServerType.remote){ - var free = await isLawinPortFree(); - if (!free) { - if(!needsFreePort) { - return ServerResult( - type: ServerResultType.alreadyStarted - ); - } + if(type != ServerType.local && !(await isLawinPortFree())){ + return ServerResult( + type: ServerResultType.backendPortTakenError + ); + } - return ServerResult( - type: ServerResultType.portTakenError - ); - } + if(type == ServerType.embedded && !(await isMatchmakerPortFree())){ + return ServerResult( + type: ServerResultType.backendPortTakenError + ); } return ServerResult( @@ -151,7 +159,8 @@ enum ServerResultType { missingPortError, illegalPortError, cannotPingServer, - portTakenError, + backendPortTakenError, + matchmakerPortTakenError, canStart, alreadyStarted, unknownError, diff --git a/lib/src/widget/home/game_type_selector.dart b/lib/src/widget/home/game_type_selector.dart index df05b6f..41ce1d5 100644 --- a/lib/src/widget/home/game_type_selector.dart +++ b/lib/src/widget/home/game_type_selector.dart @@ -1,7 +1,9 @@ import 'package:fluent_ui/fluent_ui.dart'; import 'package:get/get.dart'; import 'package:reboot_launcher/src/controller/game_controller.dart'; +import 'package:reboot_launcher/src/controller/settings_controller.dart'; import 'package:reboot_launcher/src/model/game_type.dart'; +import 'package:reboot_launcher/src/widget/shared/smart_switch.dart'; class GameTypeSelector extends StatelessWidget { final GameController _gameController = Get.find(); @@ -12,33 +14,34 @@ class GameTypeSelector extends StatelessWidget { Widget build(BuildContext context) { return Tooltip( message: "The type of Fortnite instance to launch", - child: InfoLabel( - label: "Type", - child: SizedBox( - width: double.infinity, - child: Obx(() => DropDownButton( - leading: Text(_gameController.type.value.name), - items: GameType.values - .map((type) => _createItem(type)) - .toList())) - ), - ), + child: _createAdvancedSelector(), ); } - MenuFlyoutItem _createItem(GameType type) { - return MenuFlyoutItem( - text: SizedBox( - width: double.infinity, - child: Tooltip( - message: type.message, - child: Text(type.name) - ) - ), - onPressed: () { - _gameController.type(type); - _gameController.started.value = _gameController.currentGameInstance != null; - } - ); - } + Widget _createAdvancedSelector() => InfoLabel( + label: "Type", + child: SizedBox( + width: double.infinity, + child: Obx(() => DropDownButton( + leading: Text(_gameController.type.value.name), + items: GameType.values + .map((type) => _createItem(type)) + .toList()) + ) + ) + ); + + MenuFlyoutItem _createItem(GameType type) => MenuFlyoutItem( + text: SizedBox( + width: double.infinity, + child: Tooltip( + message: type.message, + child: Text(type.name) + ) + ), + onPressed: () { + _gameController.type(type); + _gameController.started.value = _gameController.currentGameInstance != null; + } + ); } diff --git a/lib/src/widget/home/launch_button.dart b/lib/src/widget/home/launch_button.dart index 548489f..02be678 100644 --- a/lib/src/widget/home/launch_button.dart +++ b/lib/src/widget/home/launch_button.dart @@ -18,7 +18,6 @@ import 'package:reboot_launcher/src/util/injector.dart'; import 'package:reboot_launcher/src/util/patcher.dart'; import 'package:reboot_launcher/src/util/reboot.dart'; import 'package:reboot_launcher/src/util/server.dart'; -import 'package:win32_suspend_process/win32_suspend_process.dart'; import 'package:path/path.dart' as path; import 'package:reboot_launcher/src/../main.dart'; @@ -26,6 +25,8 @@ import 'package:reboot_launcher/src/controller/settings_controller.dart'; import 'package:reboot_launcher/src/dialog/snackbar.dart'; import 'package:reboot_launcher/src/model/game_instance.dart'; +import '../../page/home_page.dart'; +import '../../util/process.dart'; import '../shared/smart_check_box.dart'; class LaunchButton extends StatefulWidget { @@ -39,6 +40,10 @@ class LaunchButton extends StatefulWidget { class _LaunchButtonState extends State { final String _shutdownLine = "FOnlineSubsystemGoogleCommon::Shutdown()"; + final List _corruptedBuildErrors = [ + "when 0 bytes remain", + "Pak chunk signature verification failed!" + ]; final List _errorStrings = [ "port 3551 failed: Connection refused", "Unable to login to Fortnite servers", @@ -69,7 +74,7 @@ class _LaunchButtonState extends State { child: Obx(() => Tooltip( message: _gameController.started() ? "Close the running Fortnite instance" : "Launch a new Fortnite instance", child: Button( - onPressed: _onPressed, + onPressed: () => _start(_gameController.type()), child: Text(_gameController.started() ? "Close" : "Launch") ), )), @@ -77,9 +82,9 @@ class _LaunchButtonState extends State { ); } - void _onPressed() async { + void _start(GameType type) async { if (_gameController.started()) { - _onStop(_gameController.type()); + _onStop(type); return; } @@ -87,7 +92,7 @@ class _LaunchButtonState extends State { if (_gameController.username.text.isEmpty) { if(_serverController.type() != ServerType.local){ showMessage("Missing username"); - _onStop(_gameController.type()); + _onStop(type); return; } @@ -96,25 +101,31 @@ class _LaunchButtonState extends State { if (_gameController.selectedVersionObs.value == null) { showMessage("No version is selected"); - _onStop(_gameController.type()); + _onStop(type); return; } - + + for (var element in Injectable.values) { + if(await _getDllPath(element, type) == null) { + return; + } + } + try { + _fail = false; await _resetLogFile(); - + var version = _gameController.selectedVersionObs.value!; var gamePath = version.executable?.path; if(gamePath == null){ - _onError("${version.location.path} no longer contains a Fortnite executable, did you delete it?", null); - _onStop(_gameController.type()); + showMissingBuildError(version); + _onStop(type); return; } - - var result = await _serverController.start(required: true, askPortKill: false); + + var result = _serverController.started() || await _serverController.toggle(); if(!result){ - showMessage("Cannot launch the game as the backend didn't start up correctly"); - _onStop(_gameController.type()); + _onStop(type); return; } @@ -122,15 +133,15 @@ class _LaunchButtonState extends State { await compute(patchHeadless, version.executable!); await _startMatchMakingServer(); - await _startGameProcesses(version, _gameController.type()); + await _startGameProcesses(version, type); - if(_gameController.type() == GameType.headlessServer){ + if(type == GameType.headlessServer){ await _showServerLaunchingWarning(); } } catch (exception, stacktrace) { _closeDialogIfOpen(false); - _onError(exception, stacktrace); - _onStop(_gameController.type()); + showCorruptedBuildError(type != GameType.client, exception, stacktrace); + _onStop(type); } } @@ -143,7 +154,7 @@ class _LaunchButtonState extends State { } Future _startMatchMakingServer() async { - if(_gameController.type() != GameType.client || _settingsController.doNotAskAgain()){ + if(_gameController.type() != GameType.client){ return; } @@ -158,57 +169,70 @@ class _LaunchButtonState extends State { return; } - var controller = CheckboxController(); - var result = await showDialog( - context: context, - builder: (context) => ContentDialog( - content: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - width: double.infinity, - child: Text( - "The matchmaking ip is set to the local machine, but no server is running. " - "If you want to start a match for your friends or just test out Reboot, you need to start a server, either now from this prompt or later manually.", - textAlign: TextAlign.start, - ) - ), - - const SizedBox(height: 12.0), - - SmartCheckBox( - controller: controller, - content: const Text("Don't ask again") - ) - ], - ), - actions: [ - Button( - onPressed: () => Navigator.of(context).pop(false), - child: const Text('Ignore'), - ), - FilledButton( - onPressed: () => Navigator.of(context).pop(true), - child: const Text('Start a server'), - ) - ], - ) - ) ?? false; - _settingsController.doNotAskAgain.value = controller.value; - - if(!result){ + var result = await _askToStartMatchMakingServer(); + if(result != true){ return; } var version = _gameController.selectedVersionObs.value!; - _startGameProcesses( + await _startGameProcesses( version, GameType.headlessServer ); } + Future _askToStartMatchMakingServer() async { + if(_settingsController.doNotAskAgain()) { + return _settingsController.automaticallyStartMatchmaker(); + } + + var controller = CheckboxController(); + var result = await showDialog( + context: appKey.currentContext!, + builder: (context) => + ContentDialog( + content: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + width: double.infinity, + child: Text( + "The matchmaking ip is set to the local machine, but no server is running. " + "If you want to start a match for your friends or just test out Reboot, you need to start a server, either now from this prompt or later manually.", + textAlign: TextAlign.start, + ) + ), + + const SizedBox(height: 12.0), + + SmartCheckBox( + controller: controller, + content: const Text("Don't ask again") + ) + ], + ), + actions: [ + Button( + onPressed: () => Navigator.of(context).pop(false), + child: const Text('Ignore'), + ), + FilledButton( + onPressed: () => Navigator.of(context).pop(true), + child: const Text('Start a server'), + ) + ], + ) + ); + _settingsController.doNotAskAgain.value = controller.value; + if(result != null){ + _settingsController.automaticallyStartMatchmaker.value = result; + } + + return result ?? false; + } + Future _createGameProcess(String gamePath, GameType type) async { var gameProcess = await Process.start(gamePath, createRebootArgs(_gameController.username.text, type)); gameProcess @@ -219,20 +243,20 @@ class _LaunchButtonState extends State { } Future _resetLogFile() async { - if(_logFile != null && await _logFile!.exists()){ + if(_logFile != null && await _logFile!.exists()){ await _logFile!.delete(); } } Future _createLauncherProcess(FortniteVersion version) async { var launcherFile = version.launcher; - if (launcherFile == null) { - return null; - } - - var launcherProcess = await Process.start(launcherFile.path, []); - Win32Process(launcherProcess.pid).suspend(); - return launcherProcess; + if (launcherFile == null) { + return null; + } + + var launcherProcess = await Process.start(launcherFile.path, []); + suspend(launcherProcess.pid); + return launcherProcess; } Future _createEacProcess(FortniteVersion version) async { @@ -242,7 +266,7 @@ class _LaunchButtonState extends State { } var eacProcess = await Process.start(eacFile.path, []); - Win32Process(eacProcess.pid).suspend(); + suspend(eacProcess.pid); return eacProcess; } @@ -268,8 +292,8 @@ class _LaunchButtonState extends State { var result = await showDialog( context: appKey.currentContext!, builder: (context) => ProgressDialog( - text: "Launching headless server...", - onStop: () =>_onEnd(_gameController.type()) + text: "Launching headless server...", + onStop: () =>_onEnd(_gameController.type()) ) ) ?? false; @@ -290,6 +314,17 @@ class _LaunchButtonState extends State { return; } + if(_corruptedBuildErrors.any((element) => line.contains(element))){ + if(_fail){ + return; + } + + _fail = true; + showCorruptedBuildError(type != GameType.client); + _onStop(type); + return; + } + if(_errorStrings.any((element) => line.contains(element))){ if(_fail){ return; @@ -297,7 +332,7 @@ class _LaunchButtonState extends State { _fail = true; _closeDialogIfOpen(false); - _showTokenError(); + _showTokenError(type); return; } @@ -310,30 +345,28 @@ class _LaunchButtonState extends State { } _injectOrShowError(Injectable.memoryFix, type); + _gameController.currentGameInstance?.tokenError = false; } } - Future _showTokenError() async { - if(_serverController.type() == ServerType.embedded) { - showTokenErrorFixable(); - await _serverController.start( - required: true, - askPortKill: false - ); - } else { + Future _showTokenError(GameType type) async { + if(_serverController.type() != ServerType.embedded) { showTokenErrorUnfixable(); + _gameController.currentGameInstance?.tokenError = true; + return; } - } - Future _onError(Object exception, StackTrace? stackTrace) async { - return showDialog( - context: context, - builder: (context) => ErrorDialog( - exception: exception, - stackTrace: stackTrace, - errorMessageBuilder: (exception) => "Cannot launch fortnite: $exception" - ) - ); + var tokenError = _gameController.currentGameInstance?.tokenError; + _gameController.currentGameInstance?.tokenError = true; + await _serverController.restart(); + if (tokenError == true) { + showTokenErrorCouldNotFix(); + return; + } + + showTokenErrorFixable(); + _onStop(type); + _start(type); } void _onStop(GameType type) { @@ -351,13 +384,9 @@ class _LaunchButtonState extends State { } try { - var dllPath = await _getDllPath(injectable); - if(!dllPath.existsSync()) { - await _downloadMissingDll(injectable); - if(!dllPath.existsSync()){ - _onDllFail(dllPath, type); - return; - } + var dllPath = await _getDllPath(injectable, type); + if(dllPath == null) { + return; } await injectDll(gameProcess.pid, dllPath.path); @@ -367,6 +396,34 @@ class _LaunchButtonState extends State { } } + Future _getDllPath(Injectable injectable, GameType type) async { + Future getPath(Injectable injectable) async { + switch(injectable){ + case Injectable.reboot: + return File(_settingsController.rebootDll.text); + case Injectable.console: + return File(_settingsController.consoleDll.text); + case Injectable.cranium: + return File(_settingsController.authDll.text); + case Injectable.memoryFix: + return await loadBinary("leakv2.dll", true); + } + } + + var dllPath = await getPath(injectable); + if(dllPath.existsSync()) { + return dllPath; + } + + await _downloadMissingDll(injectable); + if(dllPath.existsSync()) { + return dllPath; + } + + _onDllFail(dllPath, type); + return null; + } + void _onDllFail(File dllPath, GameType type) { WidgetsBinding.instance.addPostFrameCallback((_) { if(_fail){ @@ -380,26 +437,13 @@ class _LaunchButtonState extends State { }); } - Future _getDllPath(Injectable injectable) async { - switch(injectable){ - case Injectable.reboot: - return File(_settingsController.rebootDll.text); - case Injectable.console: - return File(_settingsController.consoleDll.text); - case Injectable.cranium: - return File(_settingsController.authDll.text); - case Injectable.memoryFix: - return await loadBinary("leakv2.dll", true); - } - } - Future _downloadMissingDll(Injectable injectable) async { if(injectable != Injectable.reboot){ await loadBinary("$injectable.dll", true); return; } - await downloadRebootDll(0); + await downloadRebootDll(rebootDownloadUrl, 0); } } diff --git a/lib/src/widget/home/version_selector.dart b/lib/src/widget/home/version_selector.dart index 9904d73..1a918c1 100644 --- a/lib/src/widget/home/version_selector.dart +++ b/lib/src/widget/home/version_selector.dart @@ -60,42 +60,62 @@ class _VersionSelectorState extends State { Widget _createSelector(BuildContext context) { return Tooltip( - message: "The version of Fortnite to launch", - child: Obx(() => DropDownButton( - leading: Text(_gameController.selectedVersionObs.value?.name ?? - "Select a version"), - items: _gameController.hasNoVersions - ? [_createDefaultVersionItem()] - : _gameController.versions.value - .map((version) => _createVersionItem(context, version)) - .toList())) + message: "The version of Fortnite to launch", + child: Obx(() => _createOptionsMenu( + version: _gameController.selectedVersionObs(), + close: false, + child: DropDownButton( + leading: Text(_gameController.selectedVersionObs.value?.name + ?? "Select a version"), + items: _createSelectorItems(context) + ) + )) ); } - MenuFlyoutItem _createVersionItem( - BuildContext context, FortniteVersion version) { - return MenuFlyoutItem( - text: Listener( - onPointerDown: (event) async { - if (event.kind != PointerDeviceKind.mouse || - event.buttons != kSecondaryMouseButton) { - return; - } + List _createSelectorItems(BuildContext context) { + return _gameController.hasNoVersions ? [_createDefaultVersionItem()] + : _gameController.versions.value + .map((version) => _createVersionItem(context, version)) + .toList(); + } - await _openMenu(context, version, event.position); - }, + MenuFlyoutItem _createVersionItem(BuildContext context, FortniteVersion version) { + return MenuFlyoutItem( + text: _createOptionsMenu( + version: version, + close: true, child: SizedBox( width: double.infinity, child: Text(version.name) ), ), - onPressed: () => _gameController.selectedVersion = version); + onPressed: () => _gameController.selectedVersion = version + ); + } + + Widget _createOptionsMenu({required FortniteVersion? version, required bool close, required Widget child}) { + return Listener( + onPointerDown: (event) async { + if (event.kind != PointerDeviceKind.mouse || + event.buttons != kSecondaryMouseButton) { + return; + } + + if(version == null) { + return; + } + + await _openMenu(context, version, event.position, close); + }, + child: child + ); } MenuFlyoutItem _createDefaultVersionItem() { return MenuFlyoutItem( text: const SizedBox( - width: double.infinity, child: Text("No versions available")), + width: double.infinity, child: Text("No versions available. Add it using the buttons on the right.")), trailing: const Expanded(child: SizedBox()), onPressed: () {}); } @@ -114,24 +134,25 @@ class _VersionSelectorState extends State { } Future _openMenu( - BuildContext context, FortniteVersion version, Offset offset) async { - var result = await showMenu( - context: context, - offset: offset, + BuildContext context, FortniteVersion version, Offset offset, bool close) async { + var controller = FlyoutController(); + var result = await controller.showFlyout( builder: (context) => MenuFlyout( items: ContextualOption.values .map((entry) => _createOption(context, entry)) .toList() ) ); - switch (result) { case ContextualOption.openExplorer: if(!mounted){ return; } - Navigator.of(context).pop(); + if(close) { + Navigator.of(context).pop(); + } + launchUrl(version.location.uri) .onError((error, stackTrace) => _onExplorerError()); break; @@ -141,7 +162,10 @@ class _VersionSelectorState extends State { return; } - Navigator.of(context).pop(); + if(close) { + Navigator.of(context).pop(); + } + await _openRenameDialog(context, version); break; @@ -155,7 +179,9 @@ class _VersionSelectorState extends State { return; } - Navigator.of(context).pop(); + if(close) { + Navigator.of(context).pop(); + } _gameController.removeVersion(version); if (_gameController.selectedVersionObs.value?.name == version.name || _gameController.hasNoVersions) { @@ -242,7 +268,7 @@ class _VersionSelectorState extends State { header: "Name", placeholder: "Type the new version name", autofocus: true, - validator: (text) => checkVersion(text, _gameController.versions.value) + validator: (text) => checkChangeVersion(text) ), const SizedBox( diff --git a/lib/src/widget/server/port_input.dart b/lib/src/widget/server/port_input.dart index 3b4a22c..a9b551d 100644 --- a/lib/src/widget/server/port_input.dart +++ b/lib/src/widget/server/port_input.dart @@ -18,7 +18,7 @@ class PortInput extends StatelessWidget { label: "Port", placeholder: "Type the backend server's port", controller: _serverController.port, - enabled: _serverController.type.value != ServerType.embedded + enabled: _serverController.type.value == ServerType.remote )) ); } diff --git a/lib/src/widget/server/server_button.dart b/lib/src/widget/server/server_button.dart index a728573..18d9d59 100644 --- a/lib/src/widget/server/server_button.dart +++ b/lib/src/widget/server/server_button.dart @@ -23,10 +23,7 @@ class _ServerButtonState extends State { child: Obx(() => Tooltip( message: _helpMessage, child: Button( - onPressed: () async => _serverController.start( - required: false, - askPortKill: true - ), + onPressed: () async => _serverController.toggle(), child: Text(_buttonText())), )), ), diff --git a/lib/src/widget/setting/url_updater.dart b/lib/src/widget/setting/url_updater.dart new file mode 100644 index 0000000..f9914ae --- /dev/null +++ b/lib/src/widget/setting/url_updater.dart @@ -0,0 +1,66 @@ +import 'dart:async'; + +import 'package:file_picker/file_picker.dart'; +import 'package:fluent_ui/fluent_ui.dart'; +import 'package:flutter/foundation.dart'; +import 'package:get/get.dart'; +import 'package:reboot_launcher/src/controller/settings_controller.dart'; +import 'package:reboot_launcher/src/dialog/snackbar.dart'; + +import 'package:reboot_launcher/src/util/selector.dart'; + +class RebootUpdaterInput extends StatefulWidget { + const RebootUpdaterInput({Key? key}) : super(key: key); + + @override + State createState() => _RebootUpdaterInputState(); +} + +class _RebootUpdaterInputState extends State { + final SettingsController _settingsController = Get.find(); + final RxBool _valid = RxBool(true); + late String? Function(String?) validator; + + @override + void initState() { + validator = (value) { + var result = value != null && Uri.tryParse(value) != null; + WidgetsBinding.instance.addPostFrameCallback((_) => _valid.value = result); + return result ? null : "Invalid URL"; + }; + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return InfoLabel( + label: "Reboot Updater", + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Obx(() => Expanded( + child: TextFormBox( + controller: _settingsController.updateUrl, + placeholder: "Type the URL of the reboot updater", + validator: validator, + autovalidateMode: AutovalidateMode.always, + enabled: _settingsController.autoUpdate.value + ) + )), + const SizedBox(width: 16.0), + Tooltip( + message: _settingsController.autoUpdate.value ? "Disable automatic updates" : "Enable automatic updates", + child: Obx(() => Padding( + padding: _valid() ? EdgeInsets.zero : const EdgeInsets.only(bottom: 21.0), + child: Button( + onPressed: () => _settingsController.autoUpdate.value = !_settingsController.autoUpdate.value, + child: Icon(_settingsController.autoUpdate.value ? FluentIcons.disable_updates : FluentIcons.refresh) + )) + ) + ) + ], + ) + ); + } +} \ No newline at end of file diff --git a/lib/src/widget/shared/file_selector.dart b/lib/src/widget/shared/file_selector.dart index eac22e9..ce24a6d 100644 --- a/lib/src/widget/shared/file_selector.dart +++ b/lib/src/widget/shared/file_selector.dart @@ -68,7 +68,7 @@ class _FileSelectorState extends State { autovalidateMode: widget.validatorMode ?? AutovalidateMode.onUserInteraction ) ), - if (widget.allowNavigator) const SizedBox(width: 8.0), + if (widget.allowNavigator) const SizedBox(width: 16.0), if (widget.allowNavigator) Tooltip( message: "Select a ${widget.folder ? 'folder' : 'file'}", diff --git a/pubspec.yaml b/pubspec.yaml index 8591219..e284646 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: reboot_launcher description: Launcher for project reboot -version: "6.0.0" +version: "6.4.0" publish_to: 'none' @@ -24,7 +24,6 @@ dependencies: process_run: ^0.12.3+2 url_launcher: ^6.1.5 archive: ^3.3.1 - win32_suspend_process: ^1.0.0 version: ^3.0.2 crypto: ^3.0.2 async: ^2.8.2 @@ -42,9 +41,6 @@ dependencies: hex: ^0.2.0 uuid: ^3.0.6 -dependency_overrides: - win32: ^3.0.0 - dev_dependencies: flutter_test: sdk: flutter @@ -66,7 +62,7 @@ msix_config: display_name: Reboot Launcher publisher_display_name: Auties00 identity_name: 31868Auties00.RebootLauncher - msix_version: 6.0.0.0 + msix_version: 6.4.0.0 publisher: CN=E6CD08C6-DECF-4034-A3EB-2D5FA2CA8029 logo_path: ./assets/icons/reboot.ico architecture: x64 diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp index c24283a..5c2ec15 100644 --- a/windows/runner/main.cpp +++ b/windows/runner/main.cpp @@ -1,6 +1,8 @@ #include auto bdw = bitsdojo_window_configure(BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP); +#include + #include #include #include @@ -34,6 +36,7 @@ bool CheckOneInstance() int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, _In_ wchar_t *command_line, _In_ int show_command) { + _putenv_s("OPENSSL_ia32cap", "~0x20000000"); if(!CheckOneInstance()){ return false; }