From 5e262b169784d8fac878f424be2e12bc2f3fff99 Mon Sep 17 00:00:00 2001 From: DudeNr33 <3929834+DudeNr33@users.noreply.github.com> Date: Sat, 28 Feb 2026 21:02:49 +0100 Subject: [PATCH 1/2] docs(tips-and-tricks): LSP setup guide for Neovim --- docs/04_tip_and_tricks/04_neovim_lsp_setup.md | 188 ++++++++++++++++++ .../images/neovim-mason-import-errors.png | Bin 0 -> 62349 bytes 2 files changed, 188 insertions(+) create mode 100644 docs/04_tip_and_tricks/04_neovim_lsp_setup.md create mode 100644 docs/04_tip_and_tricks/images/neovim-mason-import-errors.png diff --git a/docs/04_tip_and_tricks/04_neovim_lsp_setup.md b/docs/04_tip_and_tricks/04_neovim_lsp_setup.md new file mode 100644 index 000000000..3f67f4771 --- /dev/null +++ b/docs/04_tip_and_tricks/04_neovim_lsp_setup.md @@ -0,0 +1,188 @@ +# Configuring RobotCode as Language Server for Neovim + +[Neovim](https://neovim.io/) is an extensible Vim-based text editor. +While there is no fully featured plugin of RobotCode that you can just install +and use "as is" like for VS Code, it is still possible to leverage the +[Language Server](https://microsoft.github.io/language-server-protocol/) +provided by RobotCode to enable static analysis, go-to-definition, and other +useful features. + +This guide shows two alternatives to set up and configure your Neovim +installation to use the RobotCode language server properly. + +## Common Prerequisites + +To follow this guide, the reader is expected to already know the basics of + +* installing and configuring Neovim +* adding plugins to Neovim +* Python virtual environments and how to create them + +Regardless of the option you choose, using a language server in Neovim +always requires to + +* **install** the language server +* **configure** the language server +* **enable** the language server + +This guide assumes a Neovim version >= 0.11 and uses the built-in LSP API. + +## The Common Pitfall When Using Mason and nvim-lspconfig + +Two plugins are commonly used to install and configure LSP servers for Neovim, +and are included in Neovim starter distributions like [LazyVim](https://www.lazyvim.org/): + +* [mason.nvim](https://github.com/mason-org/mason.nvim): + a package manager that lets you install and manage LSP servers, including RobotCode +* [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig): + quickstart configurations for LSP servers, including a configuration for RobotCode + +While this combination sounds ideal, you will quickly experience import errors for +third party libraries and custom keywords. Understanding why this happens is important +to understand the differences of the alternatives discussed below. + +![Import Errors in Neovim](./images/neovim-mason-import-errors.png) + +`Mason` installs every package in a dedicated virtual environment, and makes the +corresponding binary available globally from within Neovim. + +`nvim-lspconfig` provides the following configuration: + +```lua +return { + cmd = { 'robotcode', 'language-server' }, -- [!code focus] + filetypes = { 'robot', 'resource' }, + root_markers = { 'robot.toml', 'pyproject.toml', 'Pipfile', '.git' }, + get_language_id = function(_, _) + return 'robotframework' + end, +} +``` + +This will start the language server by using the first `robotcode` binary found +in `PATH`, which most likely is the one installed via `Mason`. + +In this situation, RobotCode can only "see" the packages that are available in the +virtual environment created by `Mason`, lacking all third party keyword libraries +you may have installed in your project's virtual environment. + +## Setup Alternatives + +### Option 1: Use Local Installation of RobotCode + +The easiest way to run RobotCode in the context of your project's virtual environment +is to add `robotcode[languageserver]` (or simply `robotcode[all]`) to your dependencies. + +To configure the RobotCode language server, install `nvim-lspconfig`, or create +the file manually under `~/.config/nvim/lsp/robotcode.lua`: + +```lua +---@brief +--- +--- https://robotcode.io +--- +--- RobotCode - Language Server Protocol implementation for Robot Framework. +return { + cmd = { 'robotcode', 'language-server' }, + filetypes = { 'robot', 'resource' }, + root_markers = { 'robot.toml', 'pyproject.toml', 'Pipfile', '.git' }, + get_language_id = function(_, _) + return 'robotframework' + end, +} +``` + +Enable the LSP server by adding the following line to `~/.config/nvim/init.lua`: + +```lua +vim.lsp.enable("robotcode") +``` + +Before starting Neovim, make sure to first activate the virtual environment. +If your virtual environment is created in the folder `.venv`: + +::: code-group + +``` shell [Mac/Linux] +source .venv/bin/activate +nvim +``` + +``` ps [Windows PowerShell/pwsh] +.venv\Scripts\activate.ps1 +nvim +``` + +``` cmd [Windows CMD] +.venv\Scripts\activate.cmd +nvim +``` + +::: + +This ensures the `robotcode` binary from your project's environment is the first +in `PATH`. + +### Option 2: Use Globally Installed RobotCode and Set PYTHONPATH + +With this approach it is not necessary to install RobotCode in each and +every project. +You use `Mason` to install and update RobotCode globally for Neovim. The LSP configuration +provides a helper function to set the PYTHONPATH variable so the globally installed +RobotCode can import all your project specific libraries. + +First, install RobotCode by executing `:MasonInstall robotcode` from within +Neovim, or by using the `Mason` UI (`:Mason`). + +Next, create the LSP configuration under +`~/.config/nvim/lsp/robotcode.lua`: + +```lua +---@brief +--- +--- https://robotcode.io +--- +--- RobotCode - Language Server Protocol implementation for Robot Framework. +local function get_python_path() + local project_site_packages = vim.fn.glob(vim.loop.cwd() .. "/.venv/lib/python*/site-packages", true, true)[1] + local pythonpath = project_site_packages + if vim.env.PYTHONPATH then + pythonpath = project_site_packages .. ":" .. vim.env.PYTHONPATH + end + return pythonpath +end + +---@type vim.lsp.Config +return { + cmd = { 'robotcode', 'language-server' }, + cmd_env = { + PYTHONPATH = get_python_path(), + }, + filetypes = { 'robot', 'resource' }, + root_markers = { 'robot.toml', 'pyproject.toml', 'Pipfile', '.git' }, + get_language_id = function(_, _) + return 'robotframework' + end, +} +``` + +Note that `get_python_path` assumes that your virtual environment is created +inside your project folder in a folder called `.venv`, which is a +widespread standard but not necessarily true for some tools (e.g. `pyenv`). + +Finally, enable the LSP server in `~/.config/nvim/init.lua`: + +```lua +vim.lsp.enable("robotcode") +``` + +This solution also works if you have some projects that have RobotCode installed +locally. The downside is that you may have to tweak `get_python_path` if you don't +follow the `.venv` folder convention. + +## Final Notes + +Be aware that this setup only enables the features provided by the language server, +i.e. diagnostics, completions, go-to-definition etc. +Unlike the VS Code plugin this setup does not enable you to run or debug robot tests +from within Neovim. diff --git a/docs/04_tip_and_tricks/images/neovim-mason-import-errors.png b/docs/04_tip_and_tricks/images/neovim-mason-import-errors.png new file mode 100644 index 0000000000000000000000000000000000000000..a6728452bf6a54ceff07f30a54ab6f2cd8dda7cb GIT binary patch literal 62349 zcmY&btiub5XDKaBw$T zO0v>go|$J^C;>zZ3jtGh1$7wgmVrjzm*@!eU*YA>mJRssB<0QXYl_It`NV4&Yx*l| z?y>37^{Qv2y)P}<&T7vlCGR^0fmR0_BD_`S+3G2RE z8G%6z=B!0GCh55BRLq{zK&r1Mfp-6r<@k6+^=ndPyWx@M!p#GpQ;^N? zmWtyy^Rf!xWprB^T{H6c69z|LVKHA80149uZeVX9A2P$>sB&a>q@+p1hCcbOKTh_WY}7+@LSm4Oa(xc7 zt8M1K_#1onag55qL9Q8PzNs%xM_!|ox@$kXtXlGSmO}?em6P~(lHfmQ9juTX-;f)9 zrdpI+;$+Lxvm^+}A~C*UKH6_u^2??I_#k0Q2G_T-UaU>Q*;w!J;b8l;-$K$q5U!gw z5WQ`Kv?-(w?z%I@lGDfx(r4^9Bcx(kjzr1JE(x#~8N&|nG(?NCF>4uc*1W4s5TFGI z>mGRSa}9gOSgHwBlH~DTz)epH5{biIkq%}Q*P3JlK6`q4F`$dSZ|#ZxO|ak?0kd3j zN#Aey2hRI(RM|&c)(abfpUSUFSm)uno7IHgO-CrRq%g;!H#yi;!pS&bdAqu+=Tyk{kaL}UC}E(!6&3y_V1_jIs}{JNUjta&bHt@ zQ%If(J)9RvhLxV6^WO{kdoE<`^M}{PJkj~RY>(+~AZSR7HQ&iv6D+Lhwon{!!f<0q zoiTm8%;?IuTG2gs=Dz5v+G@LA0~EG^LT=Z35I|TC^i)BT-G$Ww=>tunAHj+?R&b7( zX&Tn-MQQU?ElEAs^f`&14eP$5Km<}?`eb(?zhVkjgyskCt1vdI_@vL8Ut{D?A0#cX%6Xw`8(lg4|(>V5p7!CD2gpb&AjX(|%$1&cek`Jh(hs5@<_xONBk zSdI-DB;%X^RR*xsyVQX^s!NPN4WPk|LFpqsT2R?q+NJhfeNym#LK{`TN&B|rz;#x6 zKzzaKvykk898~(+V2DZ*Jm_gGZXk(g7I8B!`d&GJgr1*^zK1X7^*sQMo$M3rs+DE? zace5Ff)R5oyDb0;QBSG~jtw+d$gxYR^7h;*P}o)grDN-^i(|b!!m9GhZDRqfv}IG5j45uN?0QB!gF5gAs7ji6gm|c9xYXM@TusL(36LV!AaW zPlktph0WQe!{gSV2S2G)P~NqNv8j0U@r~6EmAx4FS zB{W67*7r(y*o>de*soF!`5rmD);??@J2ar&OLd9<7h^t~)EpBLjPT=O)p%y5xF2(j zSm2BQ!#)Lg_3XF#Ne)*Q)&fe|&Z6=wrb0|AW^5;fL`cs^gRWczDm!(Vfcu*wGWVZF zzOH@t?~f`?(DFIFV*G_b&E3^l(}-S6$85I^>@maTJGrMy9@5VXN<;K%5&0>EneYT0 zWN{oci&qLul`%B6Oa=IVRgq;%ET zcoRXw&&~{&8-Sv|HMi!TJ{K;Ixd#DkYB=k+^n{IUQ5Y+I9_?7h#+i>LOmTh*tCnks zl^wbqJ_2*GErgRsdUyT=<7y*kU#v6$yIu`1zAzjYil*!16A`_sGXCOek#mkV*v=R~XRKU?Fug40{h zTSe7Qhx#e6p^sU|cP~4B3Nq3eABTBrbL+nfmN&q>-0n1Qb#?CSwcNQ%lhtK<#5~6l zs!#F9_{zphLyY#iz6&x32yN1X;BQZ|1*snG(YI7Tw+*Trbds&`a&^GhF?}>5klu5XS`Mvk zOJZbs*W&S1heOmL9$e3EDG%pPlGB3Y!w8OXX2-X7GqdBs?#!5+a+p&q+b6+zQ8*Z% zmJ&)Dg_s{eNbaS2^v4p1u~)LVPkd3q`?K=T(I?;4f2EXKN)x^V_#9%Tynlg%iNOax z(K>22tVgbYcGCSV0fr$s4g!+#x2tEs<;lQzyham3OUqN%KW!LRk%sACNqIt}43#P!FxR>hSUxG+eINw-N(2jVBT`{rBJlx$zbb7k3CqJR6&y`t1=Yd0#pO@`1 z;jAC;CF*8X<~akTR2wef!E5j14Z^zF9oN71@DwDdZC2Ne2M=XNiPm}stBaO)b)#j( zh>VFFrvkifNb%hk5*U=Nr>il@p`|5ztN~(Y^i6ugXt^{x#(H}fNBbS=qUFE9rO{uf zYFSv3X}u0Y6G@okCGD1k{vnm`Ef#%eAf23Z$5kaCu?g@hG2UG{kbRu+IZWbU$fe5S zgWpcE-sIx$jkELI@6(vKN;6v_+ApB7I3CxWLkrL0j+#YAdefiCaj*00Y_GRlPzK9a2I$rUWY=9jmTx#ew!4U_M6k$ zWUn~ND@~O3;$$8rF4b*~7m4|Ykf7d2l{5@i%jr|~y(RThW>nGl#fMF3iHJ&jv(}P< z37meW`-21E8JM8i#crC0SMHCKB<+jfY`N#{ekZG$=%6>>BcP&9uxFKHY~Zf6x4tR9 z5*@QQf5AjEkh%r%+;%A$E^aCM>+C1BE1?P%2z!2Br;nlP8BM|fhL`$H+|^+V%R%U} z>DF$jY^oXg1vYN~K~!+#9S$mT-#|~;;v%M=TOS-}B41Ge$pOERm0lYw)_M-IPIrLG-D%|_ zOnYxGj&kt}DKm|e2$2w|(}LJd6cz2CoFv%waT7J2qIoxNds(@BT*Wty8*Prv@~Sa0 zUOS^hE)2-!9er23^`5UlsDK4$^v6COex}CuGVaU>o$uA-o*SRZrt3C4Y|42`cEg6% zlW8_<%HglBh=;b+H~A&-Kd8pBh&cg?_MCHN(;Hj9)i zEbLX?<|^uXIiHALKfHBo&J~P^QdR~dZ+(ULjrcq zFLVLcJRY6sdcGBYaDOypMKx-MDzj$pN+UUkcpOOJ+z?Mh{JC6iL%slAsXdITX9s>p zj0x!tn$&5h|ENtbRX;LjPwd0|aXvkG!LSRq$}n$$Fhd@$QQvq+`yS8U&HZc*oon1v zsJPu>>>j+;^n&1Fc;|7n(jZxHI|qNKeHM8fOT`oUG6{v+dwOhQe1HIT$Agn6^n2V6 zVNu6Mv6X(um!d8?(P)xrC>0OlPd#t@c|UhgJYn#0;RPM6e6(LDuSKH|tzSaGE&Qh& zU#zCFEuxWJc%o+g*W(!P5V_|_Z>Un;5Hn+}Yh82ZdO|A=+=4&dY@)3}v8eXLD=`?l6XC)bk^%dt#QkSsU#EB! zCNs5aNcgfnUhYL6W^PTohvEO4tylj&%CSzb_JsI)o+th`8-Rv7-FbUZNr6bpp*(89 zr|bzW+|`C^ByU2XCFFRC#i4}>iI%T-k7C#TD@}w5zdSi4d zU?>n#`?g6t8Ya|nl8y)-_jwKCj$m6N-)B!87X$&~g3PMvIOC&q%)09oS2c5F8@d_1@X{Dc)5^ZhvTLAqrlL+^X~8A|6T-`8af758oQEFM#fKCnLm{*ie&j8b^y zWQDWu!#(<}GFkV7Q8$1`9(HnKV+L|#s&`1k5nj3AIQMGtx@{Vrz5n8ti*LgL&nQeX zKbFw2^#z`wyB-U91&XYzg;0lgcc-M#wLgG)#*KE7)N93!atbbDyAXD1YCAvTaOaq z(SlT7W@v~rHeVCXIcKh>3{_6M_OccS3?i|x-GFH+D+>QE79;f;8&$QAKHq1v_e24u zc0`(Ft~JHNm0&sM?1g^wZg6#4@@k^DC!*^U5;hO>Ve`qdUoC(=QKdz zi5qyY?Y<3$UlfR0m1E#u5zbM!Gc9mXbcxeAk4rjmp zvX~^)pH!assFz%Y_wTn_6SrCULeHg<>h8r(8_mvr;Aq$H1pOu{6uVDlIV zbyf1{>Wt@hgMGV1S;?qk=ffjsMnkM_>HhzZUM0lNICz~u(c;n){JrwZI^r#9X;){!rGFk6E0<=1`h@%Wr}M>qx*+G-Z(@DytLdpIe5YFTSUe115{?S3eZn71*1mY8V~9%}D9 z%%)Q;|M`)-_3%p=Dj-pbP{mK_`SFrcZ`v3p!kb> zSboyDvx`aorCV+RvVs2=PY$sB`DNRdDSW1?-GH*qUT}4X{m(qZZwgl1EKkoHvEkoL zRa5{WxAial1;h@TJ7h>FwH|5Do<_$0BPV5aPMREs-dA{S96-5tr!V#%?RRdPMz@t2 z1=5QjPIAA9JU@_qBLz5s2MPSw(Strw4BE;Bx0ZceKE~c*G8)`<$kF3hY|yFMz+CnB zGHanLlVp7^A2wR7n-iZAqooFr*Uh`>(;80=MYqhwu*<>C8(hg@L$85>&Yb4{8LV3EpzFGSJStMH!({RGzTQ_YWFTEms#M4lms!eZ3AYUi0u)PX6S12HLn`n}bkFKJkd%&Arp{z(QzX{;0!f*$#rU zbE_hQ^XLDX!Ero`5<}z1I&biix|W`&7I`JaL&67M2dIy2uTR`9JY+(B=%AFciRS}> zpx>#4gOWQwG|eSxX@-53RND3 zUwP?tS|jJiL~JFxi@2Ga%4y5|FluEetXaP_Yh6W0UE{r1Yn62BW&En5E)tNRZe#2{ zH=$0B03JhwYdb4xEwUL@Z|;M-t(P(I4>{4@O!J6Yo#Zaa(7#!E(0);=n44Qx1 z{OhLOmp$&9G$0BvQ%iAGl6}ZLK0=`a!R_{8bdQ-NUJ`S!vI`uVba|1v3$w^t1-P}_UOP3K>>>S@y2fQV|I1ee#D(0J- z)J>~|*NhD_32B?6bDZaq;}Vk)4cyDaRYjLtZZr1z!j;uu(CQs#hz~fSxH=Ao_;VDi zhmJ?Houa=Cc8qE-3{u4D**gx#4b0Z#%uSyg7c_{7lD+%94?ald#$JN1&?!s)I3Ev~ zvcpBxSq&M`y)cd|{1gi`{(5_H$mKLaC3(R2eW@6?(^!H;z|Mr|w|ZmY;l4od%2p>v z8&wKnJW+;1T*f3vAPwH#`FdN@CNZc#x4^nNW4|F+Fc&2B>h`{Bm88yNYsxs}rq~eq zw5dElg~scz%XP@jcM0E?Tl3{s9|j~Qoyo@2Bwp*s`3jtFaO?uAJf`4rm82p=&x&!4 zDTgCMn3v2hHIObvQ`PFKraX%X>yzhLsus+x6h7ivK48%4K4!{_x__Q0a+08_$OZNdUs!^M^M6#hds(7MZPGIt`a<^2YPk z?=8B@y6=s>pc9UJ)qm-_RDC=le_3)j%cI$v-5}xHseQ%L%F19ly*5i^3o<}lVwUo2 zgw%vrcCm?%>~<=}0s}~nD%yHEV%v357dS9KV$uPisXN6FaEK-e$o9UKn;s_)NESeq z5HDm2#zUImrt!Gu+vBa$l3rds!!2!qr=~LL>X%5+8KvGvbj3zm^ zPEs=mwTRmD*aN&jtG;{7DY`G8DsoZ2EGpcWfO?P0->?8)vbqeAE9=_z!qSWpLaY=z zXD;4Eb{(JuUcb6DSWK@5h_8%S_$E z&KZ_^qOhV3y;oL*9ebB~P0zN?Ip`ckmkk;z4%mHZzJYEy#h%($_cGVwCOSY+yocd5wg^1T@cpgxX)$-PXaOkSt-Pq<)>suW$O5d z&X{r6T>`T3)^*2}aWP13m@FG0U-&L@p;&Fv9)RWndtwzjT~;=8tol6NXbHc!ckmI? z^IYxpM4o!JK*4?3h6DF6!Z(Yac}w>uPFl>LKb5xcq!Xm4wF`^`JMEYRfNr(lkvm2e zf-Ndarr;cr-zU@%dR$gN-c=ZzKPQkeH7?X>4AR8~Yi(YU`>{kbk52 z=MBaiAszmtez@r7jP~U|MttXb&i~Wak{uwXSN-2)!vCdSxq1Z6g={pt9fr$t%f!Di z1bsJbYah2ln!49=;Ruy{L>ey9Utz~LD&o#F^8~LG}Mo0=hEyh{4DRzJ^F>QMqIWmp;9lF$iPKg^LH@%RsNt8Z`@k1|#>`KQTp$`kL(=^fQ9hdaS z|K;r8M!(=DQP!r_?`;BFW1&$|$$9I+vZ~hIIy9P~NCb_4W%!(1ZD|Y5_@_<5F-7^L zyMBo8J0>F=4uvwHhbM=edjpRpk`+g95|^<~nDBXk1N`q+dEHCTs6S zL_qq+fPnwnkSlKgaahL(RGb<~nYU~Oej%0u{QG~kf)7E9MdnW?-%bdYl9d*xo*YlC z3h`MH!iHz~N@WIJT6~}%-rF%c*llO~MDo9ou_|>JNqKQW9ARifkJ7ww(4XounN|>^ za$`495E~*yYJJ@?WhY=Cqyo9F<419(s2Z0i(2{DCz z+k%3k6s-*tO@kz=RauHnBMPl*VVOI%W6H_e#_baw#!cFv>U0IQlSHzMK z0%40mA&0o{aMoe?gv73aJ~{1V#N|+Y*Ad`C47wy56^BQw#|c`Q0EcDz^P4dY-84e! z?lS2>k$Ai_l1j%mY9s9aaab9vSyfRHeBQ>kUC_d|y<>Iw5%35vbxSIqkMe_Rg<#Qc z8ToR`_+8{~wb=mpR+20Dy3~dgbduA9!=gei`vzn0I-Iv0d}?h7zR!O7Fu$Yd-P#j2>jxfzF6g_n+#SiV z2!}Y>qvw9WV>C)o%I|x;DToOtfMT1TWZm@s)$o?`W6#w$Zf%?hXZdY{1Sv*ik$mQ+ zEVa648>uw-DF=4*&3SQL>mRv&9Dfx@PvS>OI}mAdK%C0-Q_A$NNTO*gD>dC5bOW#F zSLNjwzrzpQ@MmtLQVj!**qDU5vIc=vLNNz+Wz`X9p= zs7qd3RTQuNw<-f<4-gMS@lvH6hUZ--jZ|YiG9WDP7fAZE5{Wjw6UFd+^xl&{YK8PAj1H@<@(3=BSfq-;1+g6CEDK02T5fzQTUF$N~bMxAYu-fQ= z9YJlC&4=&rdOXAJYO1Tq*rAMmdE_zv*hFf(*PiX_lDx%RGOQ{wp=e6Z2NNh! zoWYlxVd1tljHIM*8Fu2}OEaUYsGSL-a*_!Tk|Vhz7$sjUWBXJ@qCfiVWjIRQ6=O)x zGNmz!WDY!@q1h!dY1FX%DK!Yv9#eK&bHDYl^%6$^j4$>1wDHy>g{hwq%_Qn(?Zbjg zU2R^8szEF6-b>bGozTRtZ5USaW z*R`uqsRHo*_f0Wo7^5942I#Edi}Azrr=P$b7COa^^BK-B{&H?iWcD&n^^+GRIW0|S+;o{elO zQ_h#5Spl@{o2?J5;J#p!$vera4NLlIOLzY`d=(J%Tv84 z@KUAJ5QYO6z7XR^=fgS*_GZr7rT+B~|w7ImKn72{l$n5BFFe7W;~>7lrl37T-~ zc1?PcVIqpM`z0AIJf$;R_E=R~gu z$0BK)Dp4($hGP@Zf|+ds!}_Hoh)QZ})0d)I@+(ELYZmNpc=qj68%P?GPH*(`smZ?1d(Oj_cPZO!jG-%U-v~v zJVj5HI=7C<)I(G~R%6pN3{2EdrE}avt6dKT!u@53DGPt@<;_i|$UdzhuQhd7NqCdI z;n!uhnhYjC(4=tEAk|$0S0=zOp^^8|{K97o!M016L9MOOROm%V68Nmlq^G;n$P_vs z&;3mnM{1sqK+(tTywpvUHvTpWTIcZBL6PqceVVpcr_gCmjD-XiSK#T{X&1Cj`JS-h zC*^6i|CaFu9R18;KUvg4La6u=y>$Y1VKf}m#%!oUoMUOB%LJW=`0*?&kJpxAdb3h~ zM}nQXwGB)DPc$oI4{HKzl%y%eZWDBuxq>b$1eEkMd$;c?K!LW zcsFtFY%Av#TgAC6nv5dgeBypFzBO+8O17THpxvB}Qb!B(8C|p$DR;m=GHw=Cd`szh z!TRt#sf6P0yzaVC-ycK9KDbEW4eRVvhKC zL2h+4Eyxe!iSpgnESTXh9ilS^{T^qf0f3v%@bH`rlp@Qs{qs<&)$Ug#9z5osmnc-| z`n}2Lmf#1BoE{1q&M@Fs*Uwf_$S#WM++x_E^(79{pHrhas1(?+Ib}7Kmy`z3Ly!n0wowyAa}@>W9WWLN{dNFpsmAx&g0iA zIHMMK78Rj<95-{RoJqcNj1>F8t{1C!>~+1T`}6>g zJAjhyye=QsUmxsJa5syUfBQDST$^tn)%YD@K^R{zJ1_m3pOQ6qmKjjGO{mkYlX9kt zUb5^Sbs4WN&sjjSe;?*VO~P;_ovP#+_s_~afT6?_&Sp?;oW6Toe70rzAOfO6xwxUWgM;>J)X^4+mXCE1eicp5b0)%)lLObV=j5&ya9-l?UZGm zx;j1UShm|Mawc;`@Wy9#{W|9x$by|Ws_*pYw5b_m$|}VC zYjm9#w`m5d+`=S5`T?VRd8>>3n?4+tr!sSKpY)khM*$k{kK` zvg}V`*72h?@Ru~7N3rs<11?-ehs6du4T$F&-4IuI)FK!gUQ>v+G1I>Fo5z02Pm5e(U>{;x- zmNoGqVYWgR+rA3@@IEb9IDrU^jlN=ao>bIjffo%#r?Mb-bC9b;&dwq|U^L;W2`T0Y zAwash_Y;U{=XZ|#G*I-iP*zjpvZ?EQx|Yb0=PTw<8ewcxD{ZFsR$sdI7GE^i*lbt&$*-|2{4N1)WAfy0Z3$pSxvh64(v;>?*~Wk zjdVJv@WyHO9+#$pm13mFr@Yt1o|3K(x=6a2-iiD@K&8+;0APi?{gRY)*#&9+dHE;! zd2qn6Ek)(&L#B|s_qZ|3SOqV$5vF()v^OWab6^4Y-#XW>*4>=xrl;*xay*d)<(wGt zGYe9|J-vqwP*u2_f$qCI;9b*YcUq!9+`maTrO!0W%^aNsZ}{xhZ3?PJMglm|w2GRM z1X6vp#>;BBw&yUe-#8o$+HjHhK}HQA)7N)`yQ2|89k6JF3I8=6E$ngJY>4gMoMlZB zcaEIYyf=DBwboF434t&Z2|ZsNXy%3PGh6!(uOt{W39{b+XT(TE+`dy`DZpq8lz%sB zJt$rK_8s`;g(RX{UAEm&4%d*o>~hw4U z@bVUC;9Qj_s{0xH{R2r&ll7_b!{Oy*V8P&R9?3uPunU|0Eo~CD05RnV=x>l8DajePz=J$oq0;kt(wi&8A;dwpt@@%$uu=SCckj&Roi21 z#K_Vj;yQCu=NYUaH2*#NP)|J#HEoeW`U6VyerI?EbQhBDGO<$cj5J zvcMN^FJW7MxUh91ka`LVwBNV9je~wzEKIbErhkcVHWq?$i+u2W@2#ayVQV@_o_Phv zMm>j5Pnp<<+3PW~-$jvJH@w~z{GQ%mD!fSOAyP^S)D-Po07}rX^fUIxb*YOd8dplw zIx#rlN!#6=8J-9Ll<>74$oPzg(SL5KOCZa;#$;X^I;eJH>+R4#DoiRdmho5mJPkDa z(yVo`ObFJlrWGoAx&7pC`BMUFi9J zjf7rYENYGafH$f3{6?w5@4h4;EY`UHuWXaVvTM`ml8Jgc_PIfQ?q&aEO~=zrD==rN zsfAr)e1qx5$n-Jg^eXmf<-C7z*3Zf7^LN$qNZin0;T#F)KmCzb`awL$bmfWVpRDy} zh8(zji2GBJ@r#Kwq0>p4G-pC_-Y*{N5^*EPssu3&>p$i_oZ;tUqM}kkg;@XC5s}$? zO*u1PBvAaxSUCnzw{PMLCK>_Vp6lq$Q#ogdbSTE=hu%w{+Q(Wf7_eo6veF;CmEW+Z zc>^vgqEim1-`x7I2{moq!~s>B;4z>#l!MDbaM>QM%YJamkdnovSpiRo8c>D>&UnT zx?NP(=@g{AGM#>qi*;V9r>>-O`31S^kcRto;wvc9$+x>Z!y`ELX-c#FmL1_R$=9d? zCggGSo^-K@4L1L2s`aS3UA68YaP=|a2;t|?B5$_OUXPpF+#roHNrkQzu`geF)!CPW5hSo2?P&L%6LlP|@`z0@bO=Y_nOnXMdGS1Y6PsCVZ>qeaf)L!SY z)vo6rTHxgdb2LN$6LmAis=o5AoSrJ`*2Vo;j*s@mJ6n?-Yo;TsKr_9ZKC{^pYw&I3 zlaWKC&CEObI~wI2Nh7cXACrEAojkIgY;Ik0jdvVsTZ|~Hv(Fk!P7Bve>*?WdjlA6` ze$j1RkT-AR32=V;!g0&!@C)7C0tpTBy#zRLY*V}`M>;eoqcNp-(CEzw0p zWI+i`iZ*$9!;}xMn zFeA@0U2q#mP@q@Sk*W1yIuUsCer%iD*7D8zqdiEo@mtx=2Le+KGpn&Ke{OTgJ*Q8jRIQaXN^9)_N|hMm8tdpW-1Bb*YFoea z3+&&Rq?ob(H^TNZBc&0VIetiIn>Y3FGCQR+3i>bhVJ1V954I0NUf{SV#BCahG%|Y@ z`fnF$&g5A4#62xWM&&*9!XA-te5LFUVy0U8Rj}~>H7|eI5V`Vf9d*&~>TybpG$`j| z_!xhl-2JzcOCryTAwCkk60FesHcLqw_hfgeYf-dW(HO3LE8q4;r^ijm-=kdLiB55F zig4Z6vdnh|)-H!mb4P{g(!c$BX*8)bgf+Nv+QYv~Lm@p8SHYFQ1LRpNx~d?l8&TYPwmG`N}& zt3o?!z-)#@Vq_7oivQaL^~j7gdXOx`7in61j}CKqWb3MtNaqGOw{aZ0Mn`*(g_mCo zYoljqSEbFo1 zxE}(!Btk9Q+%@Q^tW72<`GV5v6p+C>vG~KJlVQuca(6YXjZq@dnaE!tALRFBGOF*7 z<(dYj)|#;$GDrc1`_FNgR+LJx4#;=^R+YoTXydlAY?>M0SmWzLo@~d1CzHd;AZ?%g z$IX?|d-LBjt!^{mnM&U#$@dA$6iQn)J|L#&_fpWLV4Y=A08PX&FF?C(i~vVeJTeP3 zm7}nBs_1>^R%iu!aD<@Sbk-J&h{XKZrdAMHdmJWRU74IiCL}j!(|LPsW7M_v1GUF| zA(Nfp^+KVE`}Lx+Q>`$)wN*yL4=i9L58PTkCip^N12d@SO3TR z`SH9~eOm`D90T{t@Nnaf@bqI{F{IVTuUpiM(sNz0U6Je~k~R;7WpNg5w=twVBlxuY zy>Df=rX8jO*5>`j6HWHI$VNogGCI6!;)CRvut)sX-Sbm9ik$*4EFx>gS9)a->MvdG zzF7aOcH6NV4`qQqO)j~Rse&-#HWsjcTl}%?8kIww_lwwHxNeix`JYLM6 zx*2z@G36hb%0wd_Svjd^>{pDX_2L}y>CP+tk{l1WHY3p(&hb_tG>pPHDE@$X z^NEF-3kG*${M7Jwu7F+jXCU<{dwN97S|f+M)&;F9t3aOyelHf1s5rD4E~`%aG$U1% zbc?cwvbVY_K?A|hE;2{D-vu`c%9!sKCX0F?mUnK!S7J;JDf2k*A=wapNb~K0aquxHT zUpuJAN}3?$-V_yyVf~VD4c={RrXAW9Ab;AA-<{X{3`qE45PO<5g17>|%#*##k|Pw% zUcA{`yMs^aEdOo$=<(*CDw-@#q20Y|TGMj73acCmFYZrYG)eGgN3Jh7g?W#Q9D$X3 zA7hoi$U)4L{C*$_8;8sTd0yy-UNM`HKvnD}Qfpzx=lM5cL(4;#Le3G4My0~XyGsSuj~WHjcD7v6^P&! zdH&mB=eZW`r;voliZ#uyjw9&(LajOnopsB;u_);Zklpv@+3JJ1&(qWIE&hsy93%rz zc^zraEC^e18WUSnk7}3CfVPvm2xl$6)!=Wo-9{0DI|W@q9Uq;MpORv;kNz#D;^q1z zUHkrXjefTWw{F=O?q>_WVm+F%CDmhX_A5Z4H4@p7ua=f5sR+9C%}gNrvxOk~z^|k) zD<4N_KMFgm1o$xqe#dC{gP%>uYTKEc(j7Qn3tC%UeF$vg5Mv~<^4Ci)TFEjhFxbfq7VtS06aG8rlZ~BsZMt{b()3CFXeRoFbG zqn^SMG1eNz81ax1K+kLXbLA=dXoC;^cO2(i-F&`S^k~bwwx$La8Ow3k6#^n=AFd*i zd>^!DCX*?ELC`Qd8qb4r|3sF^@kgB+`~$s2-^)d{-oT@iaGNPsRG&67yuDhaBw4sy zB8CoF7%yg20VKGv<6b$<)!Wk)NGVr|F{WuE@vm`D3eo6x6n ziEnT6w77r@FXHb4n53Mcx;PiD129!Z3-<6Kyp2yV8dphAF2Rg5x!I!@!LQ}S0 zI34)c!P4czMzP)@ zNCeW+E8n%V-oWC#Nr*T2@^`XsXN@VN#MJS5aKn{}PFeA|NWsHrp%g}$P5T1*fzGsq zj61sWcF9hyd4NT^M6TQ`p8YdDPTl}szXp5q#Y0^D*38=!8Eufrte zm&tZfb#tw5h2_i#`(qiaRnt^wFv?l)Dejj9nK2uWIB@3_D;y3^u z$2MDKCy_19s+d3?w94p)}QM*=< zJAa|vIH+A2(h+;2k_?UPCCrEKE~k5f6Vv}iwNjL6W-3Q_GR(O0F0G%$gVG! zCURPY5(g%M_T-lcpz<+4Yr6W^&SEN=nG>V8C`E~gFW280u)iv%<+J4y>Hytw;z0h@ zEEp8N<*f}U^X1pO@}7I{cg}sD{bPRgbXQmP-n(|ys#WzjS^D?5?QIU)e=NAWZgN3R z5)&9ikm`<_3NZIJI?n!YQW}&3tet9-oU> zmltoG0bz%g;DP%aMK#+}FPOv1Q!IQ&=Mx`##b?G_8?rUA%agq1EbQf*6?8YO#w-2r zE1kvwq){-&awn58MQlH9ez@3R`Y{!k4tcLCy35&ClQgo5hBfGz z=`O_=1H@k&0bM!rvp@DuyySxJ_|>}}PPyLF#*mfh;oFF=c(j>wUID#i7Mq-fb>`9_4N%wmxs6(y{lq4Hp*CZvUo_)bjrkmuC05RBJ+euv*Z_gjJ9TlMx zSvL|16=gJ5N?OoFeL{Q~3-FNp!S6g$=N2ij5{;4C)b9sKa0x~OJ9)b9#r{^KdIe6E zr9C^#c%)7$3M&M~5!9)qJKPn1T8vL$+cP;@PYSjYvPbdA!$iXa(jlN3%~&n)faGPy9#NA+F5mnYj#R8ZnG={{f1I9Z~iuq~bvbiB6+ zk9Op+?mpLmxT%fbx(f|{k%r*zHAgRR6^1{qYa@W2YA3a*_V8DU1ky)Qc*;lJ%dajW z=_E_b8U>BcSa###Y_#DSZA(q0W|=rUXY7EPNjM(1W42-jJJZazK?YXd@;G9R@3oo* z`|}9yfo!tUv&&6POm@1Kk#_c2Dj% z7h|3$Y_-BirPgTs(H0ZY`6Om)qsAo`&uIg2Io?i*N&5ytd>Z@vR z#=02>=kLwpY!vBno;^6h3oJBJGDMtVeZaSl!jXO?mco0I!*6RppQr^^ne1Q@D}HQH zbnaYZyWoBtq-2|LxRb4wP0HJ7j+WckB)}q(94W_2wz<4+7;Loi1Us)zAUFv9GG6n7 zE*ly!d4BMxe&c?jMHcpS$SDeY<)IjDvE_eLV0hN8Ih1vIKIv*}n#0L@J&_ty&#&ti z7!^vt(b4Q~tz4Ty$&4cLBJsHIKdL=BbHww2lE=~^Z!vqRT4b11?9xIz$0=uXqR&|= z?_fk(*=dddJ9j!2K8>OtJl-a1OkI7+b_EIwkWB|=5X-O}Q`Erz*cPQ-$OSVFSh;gr79ZPv9nuhgSG z-S%s^PDI;Svslao4XhDMcHMNpmWUhnw*_wfM6(qH8aI@4PDH~hxQiSzQ&hOMjVs%_ zK42AO)->ZGe1k57WbAO1Y>~8Vmr5GI0+;#Wgw)Mn5o8ouTgiqI%U;6HZu{fd7rC12 zH_0sw;zGf@ym0f|#xt+q_LNblE^>+$o(QE{rwesi^}cTjNeWPIZ7EcKV?W`c9|qV8 z-Ay;Sq8N21Yd>@*>^^;GT*F{{{$xz%JH+{RnP#!C{@XVTjz|W7<|g(d8_V7uBP`!5 zaf{B-(g}Ywb|AZI$8Wo)8!m6m9kS}R0ym$4fnTJ(xivW`B>Ya8e+ybmcz zGi)#GXu$31KYc7wndQk|y;UG*MC-T?Yn5ezDJ!wk+Er{~Y;J@zia6O8Xq5_xGy!hU zpP2ggnu`S_XM1#py)JRsCZTZY@e#7{dvbKZWzs=GBE%nU>H@6F5T>3kq7ji!8jzac zR`nl-@Q+Oa01=r5>31U|2+D#thb;O$BRzO-XSJ|%kU)m+3mU3X0oj}MGcPa%6}7Bv zQxhqIRQo#+Tf3&~k^J~iAuGRV9Lmz|JR4VQVsV5)Rol|L7nM6?B?rC&W>`ZslFJY8 z9Or%VawM)6lL+^qf;}iEMkhkc2E9q>t>(h?2QZPi+@TIZJ#*vsr%8uj(ULr;#Dn`P zjmw9ya4MWAnxEsk>+a0J9*iBwPW0uW)o1ywPQ_i@qG5;2-w<)0ZeUh7iNTrvCqn-$o?X!kfoBY9gsLP;#YGX5Z1kM8?)JpRrE8saxagR_09S_i$ zop2w`wCLJwUd7YyF?Z-jEtMJ@J zidR91jU}3-O>9oIH-jkwjE-Z92pa0VO^@_X&tCH3WhR;k*@$m?E8))}uTCY*4 zGhcACM*kYLba=vIl)q*dM!whv5K)L3+A(*1x(GWGrNk=4 zZl>sGdD{nSm|I5H6yfZJ4LE6YxN60kE{^za0mAL88dj;r_Z?Vqf6BfYB5`rGPQXTz z74Wi>m3${@VJk4!e3aFQOi%z zt5mchk8>?;UmRX#O#O?p(UwB6509wWy9Ii;_#!mIluQ99@xC+IiuvC%$<9+(n{Tr z>X#pfv0R;R88lG|SwrWe5qf6{J%4&^rgiBw(NB?=2rOhppFe;?d5 zyg`e$<6PR|O2@Z>h*I+GB_iEP>`6#>k4;NCnLj$o?+*?CIPNj)O;a60a?%HiS zCe3YaKgj?(T$Xrz_*%60Q9JID`knE{Jkr`LJ4=;~w5@1f5ZueMv)c_{L&Hpc7CTF{ zhY#J&i!gJW^&DY#3%*jwkq`TqmkF|E%iDB?v09q4%RabtpbQ-AU0( zoLupVpiJ&a1$_3Wb2xzqlghwWT_sCsxMzKG=6%Vm&p80UD(vG5ki}OFT;tvITv2gF zMH6a>+9HBf)IXFypR6?JF~0A}_za}}6%ZQ)Z@FNRhFT;b| z^ET_i<+nYws=X83cmEFEpX&`%*RBH@JGlW@2zwEM)vF!2ubz_+zrGuGv0Q_8S~Gv; zyC+L?H=n()utD$c((i{v1t=GF*0~U26K>JYVci*j#vjZ`P8+lxbJuF793oLu^~|Gd zyzcC_vWm5>kA1#wel%o0Hmn#pJ}`#+_<&hsZ&^Uq3PE)lU58+QV|lteg?($kB01`n zFL;OKFbjn(*e*!nj2>h7X*$a0-Do(H3>9PArY3Do)9?x-GonQ0)z%-uQtxdNgEQ-n z+ZO93$)qp)4tL%r-+_m}a<5%igBtB^9+xb33uK*+9wr#P88wa*<8;KOkj3fJS4Nh~ z-=7Ru-$k^tF}~bM!p(6-2oXI3_oXMhDGiR#_)n=Vd+@+EDLz-NPSd8|PUo`d8_ivP zd_1{lQ1=hYgT2G=;M-=4F$kd{02|zAughUM(35jW(@tTV7!rWM$p-f#S}q|YnUxz$ z{#t9N-?Hs=;HsEQqCr$1+k!N*Ig_^{fn6upxtK(t`62>tUhm)fg zLeA^KBaRcCdBn(_T%F@?jFQRL{3LOl$w?j;?8qf9xJgX3(N06809X#zwguTAR_3l} zm#!PsuEV=zUQ%1^S%XY&ZVNDvm?@+?n4RzG(#4i99OqX?wQrgT+g30C$ikbnxp=A7 zeB^uAKp~*>qqrD9(cTv)(W^g5)AqzEv5|G$p>A`T3G_s%P&@;V7T8wN>aw$cQOjYx zQ>rPiuAxlQ_FLY`#_YLFW{Nuw@m^sof{J*WCOwv=#g2_m4}G3*8Qc`%49aN(n;MZ3 zVhw|84cU{GiCDeqJJ)Xx`u9NS(s=sqF>0dE(NDxgZMUY9y>dauw&Z>0J z{M<*DP46FVR_Rt1NyoFht1K2x-XBq*oNa&1%U_?!miK2@AV5!VY9&qq5>p!B4Oz6V zeKX?)S;+DwKzs7`cAW{3IXF=6Ofec#ik5<(C^OG9xiUp3&8Zo&5VZZeA@C;X$iXP^ z&iQ8gS`hZc3j+Eyao-@>JTU|&D%C8BGej6Os7L_CrBBEc@!-ES>KiO@CiDlJJihWx zJjCj4$CVBf`ni6x^-qI!_9(_#c85c}a6q?$KpYEoB;v}Qn%&7wM3n`&q2s-m>z2%{ z?R2VhV?YOJ)dN|MXdxO>IC?#5(Ap#YXCDtYG#p`6sl3b{Zrb3?# zOSrn1czp(Y`XL@V^97I{*jU*F6EkN zU#^FYjjZlSopSD$rvq7p7Lrd3{rRw0(<`A#mcD(3^E^S>043$v+6}T?pFe3PvDz(B zSr-cUTr)y7t`u(Qh5g`8-`gE{J;p%iG^xXqsSoiQ)TlHzs2FDMS7=*`sugc;dY0jq z=bC6KrT(GFnxdHf^v(RDT6NO5nYELMl=p?-O=GFmvn}uxUW86h<9JnuE{K|WsQdXt z{+>P-#ROb0MzO0Rt*O2U_5+b(6YYoj#x`|Mw}AnJz855#j*YP1ftfqS`O2i=`uYzO zK@KNq0D?tEap~8r-?ropW23+anc0(WS25Sn=l`hK>dxguQ=s7dYTnh89 z(433Pv*btgV)m1r8)p(vjPljX=TY_ZNqzaI@iJKjp<}nbie}ETn|YnJtwU=aP)Fla zmu50tb#nj&qXbx8xoKiAUrjnucVJJwS=4`#X+leug$+kLSdwED0FI)d{Oh^2BD0Lo zrcZu?f^>FcOgH6rYGqKD=YTV%ouJADswQ*iIPsq#=0zUBzbiPb;J+y=MeZaPtg6@a zS!RSAZi&-jB;F+8iW;*ekXofDkP4gGF|lclxsGgX+lnsSi^F!+G-v}`TQ;|i`V3M? zb!IQxVhSvPzsx)A@DT#$rhdM8Y+gj&wnAW*#5@nAgk8k;8_|DYZND9;^v%-Y=f)<+ zuG+h1qi0>~Hu(?>-Ezl)Ck9~~(-?;&t`L+v>n{}x*Qom}-ukHqe+!Xr-}Xs$y^{27 zLxAe!vt3(jnh;Vd#{Da?<_?j-bbaJ2zFtVh>hHqag1Nmn1}1OyN!a2y7G+|-tWwmIbOL5O`l+;+a@&!5I-?A6RhSOq~Z0uuLa zs7EPYQ57ViR}Y$mL^2v^;kAaK*5xN}snG~P_1^N)2WD0>9aE#j z&;A>kbl&ergiV!ZY znuOZX0dgOpaU}12xk%gaG^)Uma*GEg@;5~4$ntW_4bf3n%0(J{)A3g;8vciA{PS5M zmO?W-ly(vau}ZQbqgyYEy%{j@xqn= z3Q+E~k2{R&EbnFakSk9-i-FZQfM+S0DBYLIte1DmS$DJ}fQilk1vV{A0XpxDE37eH zoC7Kse1pXr*fCC99slYw|1X~!-wazNni|Z6JUZ<^w0C+S@jJMg1bR@iWc-%FuX{P@ zntzIp;zp*uIhK9PI3XX-4z9R-12>JcfOf5QQ6Sz;QqjQ~onrp(5FRa?%a^>FVjc|$ zLFc2pEB8u&@D&eZMzrN0>M|HYt9YR}7NKlAk{8F#F;Le|zu=lxR^nv5+l}c$KI>ke z^#L`0&wVKdV`b=Eo!-iUxY6VK#&OZ*9MBi zCQ%t+X$_%7NM0Y3RrPQ^fVqE?iOrNI#!;#Q*0AP%&m43evZ%+iSrZNXCgpSloo#JJ zz>ejcnGJc`{qb&h#w7tD=|nM|O1vF=ym`#Hl?(|$>E!@*J?XY0q?qo8tbcF&wQo1&5sPEs%8(gFHgk?8@d>FvQB5MV67;tOcg9QDcNikxH9qcy5}QE^d?(hEtIs&wk?w*gH? z*n&d6+fN`Bv`<4W-=n`|?L%?txO&yot-YD-JVkuL($+A^xN+rJd-~nQYpIa@0W4!7 zz;@NKLF)#(Z~pc|^bms2LpBpJBP2a@g>quwf|F@)61okejwk-Q1A0|DJK>sCJK{o$ zyu_x~fCIPK690L*SKMf)*A&UNc}KDG`1LPSv5Wm~{xuhq*@XAI+r+aVRXTmdj@H{^ zKQzid&$n>R63iqzC^Y}3%1eqa^@4M(t~7>P+?)(tYsbCnP()$EJs-iV5s$@|HW)9v zTW*5i#W?CKKU+vTzqMm!xdR0&^t-|jc5PoDqiAaQq3AyFrL3NJ0Hp}q1sp%)ej0aw zF|#mZHV*%c)uXPa-it9whVkynsR*Wud1bUD=OPrp%LnYfw8HTm;ApVq_4EF5aO07T z^qo}1q0A&UO^-C?FPd@*1Ft7OmqG09u!+djs~wA>f1kt7#TrHdlc5HjB4S zr%c6uzz;U}bK!PR(TV~2Q8m0mvMwEq*kRbvmt5hTJ%7QRSu2x1BA$FYrY@k5uULZj zCWJ4JqMZSEhgkLtskDgckeUh~6Jy0!@!u$4NItZ804;IEYRnbehx_7n55?d~C+aVb zeeqIBo-KA)?8dSF0T0$K!6cn6Lr=24;^A3^AE%t_L!A#?_RmA@K*^D@Wq7&LF{Tb{ zn;Y1yLa{QxpgXfS{a$2j7}}8w)&&5{#G2|}?I+~8y%#rX6ID4UILQ4SR;hyn9Wm)z zb5jjbQe2Z6J=$%)K;&#PTjEMClRI@%md8(DNMg>zH;^Oa?|JlF_4RsKGexVxKUp-} zIiY0WxE9se{&T-tZnsoIWhkC}dX37V(sX+)1hrBT`q0Lh+{47UT11_3_idxy2Ww&+ zNsCbSK2W`B*f2fASHdO)_8WnCd?U<}u;Qa$<+v@boEq!WLQUlHmLiW56& zyfGjfg57APqU}ksp-}?F&C#wLz?z08dRyL}`szey$!RumHxDnpo?L6c3F>vFLGlXm z6G0~}p~FJzt@t6DHt}^*usO!9$$bY8r5FKSo}4S#46{nm-;UaK7mW%}DjFFpIqjg^ z-MV-FoMUbvYQsUm(aIWv63de(iMVQZUzaCUCQ>IuE1D_APr{p5N1ojWFVBn>_>_;i zlfQ}c&aPzo9$G^@rL-!yHVqY9?UR6!K&1nH+f0r>P}Q_*SVen+i~@A6Gwjl?_M+1- z_+-ORxWrv2qb~*?$hcqT>^!oee>Z899+#8^5L$K>Z_O;QL^QGbH9XqQAwPB(C(d!k zeqP!9&>aos^gTMTy+@u7O$xq$aB7k}Zkz41;8q+JCeqo-yJnQ?%l@>0Jh8BSI}4gVDrzB{Y2MHun@Jd!*e?t9@9xLT6@Z zIR%NmxI5IOIie!Kj5)6FJUqDPuE4fk<_QU?inp=+(thOSI>VfAH!B+5))=%3zr#wz zni}I1Gfj53_Ra66=iDK6OQ;71u&l3pUq4oILrE#V5#tU}dLZjG1vyEYZc_Q7TCKL+ zTRghY9ZfnStV?q*?s-6vsLAb@92^>cNuz3U!$yj@+Zj3zvtq9DXc>^2@INwks{R#Y zbc||4BZI10uHr{=*i6CFTIVAwt+P6|_oNLy;sL+K5wE7w68~1`CyP~5!5m7qz%-Py z+0Uvy@)aXhzshkvUWa(_tk$@)A`8VPh)n1;PUg|XBp%R!m%FRIh?c&+bRV03e71sx z%_IkfS8XEIefSU>tUIu-%e=Ft$hg#W|1*~`FuOER-E6v0@F<9iOXP-=>9XQH zmbtsq;c7kMRjl;9{!xk9qt;x2{2;u91iq5-9vTse_`MG&_FwAx$vm%Xj~Ul+08AX| z^#LK4Pu1W_zcjMz`l;hVOCA%Xav#mxbDv5$CTNs)#M3%>d{)FFuh(;BYH)_VQ!C~Q zX6;)oY|MZn?_A`k5q_TZl#GS`?_vjnZk)+v*qI8gr@?cAG2tH&)2Dy9+tbF5yh`l& zrKsf+M~Tm^)ZAZ%7Wc*|pzW!}vA?|XgYeWo@FRMeSCFYc$CT92e!Zu6ARgwQF09Id zYKZ-0zAbYN+BmGvX@F^FE<(A54C zDGYU%lh8Xggbc%C{1h_jyl%E2@=~hQ8;m12H~$BJ^3ra>ckkhH{^8dUHpceh1QK1r z7SPL8P18rE#;tN6M8%Xi{koRGmS-CwNHV4-EJQ;hBWapg3rt zaincgR&SYD+2#;(F~#TfV~2q&)(8$uR3NRgsZ>)Vq4{!vGJM?BX(@7HobRx!LW62lMR z9>r|nw6dJi&o^8~{Sq2@alj<%Dz@ur1W>y968s z_`jSZGGE&6H2=4Gggk1Oitdcj8l%1D%j3S2|DKfb>gszKxJs(z3K}5XN5-!9o$k^o z1BfF3Kch-agdfe%>oy57Y7()HVm28a=)-Z0JqyJor9ZG^V*fD^lREHTJ9iJ)%5}0- z87KyiJdq%?jI4CVLz?H{Q!ezMyecsXTT;S1@2v<0!5ku;yuYE|=g`N^;^tIb37&xH zN_n|S|Nr_BSzvJHA2QfB2&!PzDa~P&R+lQ#ve$QVCW z#F6D!((NCx|0yA?3`)CBuJ!q5UP6o-bjcke>^z(_lotAb&J}|iNV6_V@#Cw^67zY5 z`mc56-n#!Hk12rF;ojN9bD?Wzo-FHOT}q7$Nhqj-qFLM-Ff4KHruy&M60p>``?2+d zu;BTHRKg4N{lsgUJ4P>&t}y;{i!y{py28}Ux5t|Ifuiizah));LCrLzaEpHr>Ax@O zd`T&&UEID+4HxS=av2x6j8zXDFnsj?9|0LELo?-9`bi^&@+UZFGt!2iE`fJo;fXa)yKPB;DHgPWe1%hvZT9{%)ymZ8x0 zlTsB~L(PfqlZIH?9auc9^lsfCEbzaiiHyoAf3qWQWTWSKmq3Gfq(93b&1MsrdZCZ+RGgAfdT6C5~QXDj%=aLQDN8q+~Ae zcnlcuu;U5uOY|`*$ zeul}reFHmCqVc&T2_q@J^`)JOG{hTK0@!6;yAY|iomt|&S8B@ZHS>*z+2tf?jMT4y zF({AJG9s8f)i3)&WH#@|P#UM95H*dIYaWBDDiQxSI{|h6*ijQM?-|2O*w>X_F&d2Lq-^pXsvqekyk0m{vj{^6Dj@NifL)`9avV-| zXnxsG`*ZIMpL(Cxp^?2p$L=M7oe;hVy8MX;YXmLVq^bZt5Ku^(=ftPirfgbK1OK^C zanQDyYNGEglPrcZvOJ(+3*Do1MumO&?fqzodwl5d zn3IJ#d#QjT+XbU=A)Fsq9`w0^Y7ceDTb_ohhM0eYcq{V{Ozc>x)vU?tr*^#9J0{98 z4po|cY|1@8;h!6KMMjGy+dSo7Jh3}G)gFYu&boW|%_W?*se+tD8U@Q5fL_zF$qRXe zEY%TpmnrzHT_^q)4>x>iH!Dfy+p?60PR0_AW2LQyD`&MMf%w@E2gOKVO`2mS2$qSE zsY?Vc6qm6BC|m&tp=M!aw>+Kf&g$TeFUEN`Si&9Qx2>7`MxHUZ zszs90YM{zA(8xtNnQdQr3@F}u4#je@&vCXC1KW|Z3%JaHi;5=n65wyDiMLmC==W9U zgCzJ9^`Xcg+7da(h7XYo%Jf0zRIvS}(8(mOmK8It2&MFFZ$P)s8cFC0P-YUB{+wD< z`Lth{9(FhqL^b-&9h2Q)ixB@m;GhAzl(RBQ!sf86g(s%V$d`#roiA24H=nM8g0msK zsn1ai_vYqZSKs&nVCWEhzEmRXT_wA9kS86k`J_d&_rzX5!o4dtwqkoVrBk~T>t7#k$-E}CUJgM|c&5eE} zL&a|dJ!#J2b|mRxD8G&l&GxL*(V-1EVtQl2L^6Nbl*qcMI#-vgy=w=}d7$gkXaju$yQZ8)e@__1 z(tt&ie9z&hf`(w)=+W}=LuO0+3hVU%g~00JsDnOnO`kGT$MsvtXE@=Bx@IsPb={2? zkd8^M)$~MAeiOes+NcqO;neknI1UusrO>5LoRMQpr-wSsr^t*&kah;?(c_8}S!xQl z$ioVZG}WNVU^py$OA0L;#U-bwdVo*Tg_!&yzd zJW}C(=qJtos60u3pZabb+aEy7HohW@FU-1HjngrUp8{Go=kI1-;rhLaS-+yqXj0&G zD|EPI`#(|~n$n1@f8)}X?9hPr3tqJo2$dWR8cg`+4REodQ~ABD6>9B!$EjCZa?6CR zO8($h8UjkOpS_v%S}?Cd9S6m_)on%9%<#v45K&SaO_r;skFR)6nDb0sW7ttPqdUGo z2naM~Q8uq$&bovpU7t#Bp+X5(Xk(pLRYvJ$1$%tv$j&@tFjf7MnK=~jR&hZh+ttna z)M&q@cu(&f`*Q4Yx9h)-E&m4@MyOBQUP7bKtds?p2zJ#1TaCbnMu6vBw#GNBo0~H|hkd-KzF&i|FrxunjMn;LBNy+sNFO1EUqBaXHxfIQiE%1)`bd1KAUupg&hLH z8y7S29d3PYqNZ(%3=a&l&YU=M?6VYIF5!~+2)AQTjYh!7Ryvy<>~JP|V793ngR{%+ z=2Ou1hqjUg*F9pzb<2CZ71NM8`eHsLRO6(QjenTvVMU1Of|}stP}KrBR)eV7tK}7bsKF8*r_`Grr!JA#_BY?^#BfU- z7weR{7}H>%*1kdsYv;_Tm@`~lhkKoT&U-6FR|cP#5k|dH4!MI0f7ZeyAADQH{&NiY zpT1_(eck4oyhglU66J=dQEm(u$XdjNEPSWsWmWo|8jn0sA;ciFXHrLIe08qdBTQ2ZRrIjTWD>35twA+W2z^wi4X0G zx#!75IwmNO^PtGpG#n0tW_@!h_ct}-!W}Q9%5xy=8+VdJIYTxoZY7)6lk_j(OVxDy zlg;BaW=SLm+9#8ZR-1?VOH9dQdjOvFBC%39&oM}(Ax-c8*km)*z z?KEP2)ob%H6&XKCX$-{{A&VZUO_KlVP?T~V>1k6Qu3tb;V;rQRUvsT(%7NPbehtk& z3o!jBL9f}rShuwhnsHFeRC11)jt!J)7BdiCnzJb>m60O2f4f$+Wgstm09QVRNS^_h zxjeN-QXMq>V2Tu>&MO3tK;g++M?^ZoGQSx#TvYxw%Pl{vha=|t;Rd}AYZ z4`^3+&GluRj##-B`kwex&7b5K-tqGLMD&9pWIkKF+4ssHARJJ!6&dG;gtq4+4)J>! zN11b8SAVYkE0{v3lK`uh6Q$@m3q`fl^WkBHD;YD^)oGe~?*VuWyXrj$PX3zc?Pl$_ zE*q-Wj3)NVH>&*xa~vC~bEPO73PbF$iZDw$W7r3g74qj%&09e6PM_X>_-r{}`lQwc z-1Ys^fIc-2I?l7o6DG3F!0)snD_`~B3YK3lXPvf~&V=! zW-oQsB-K}hGn-W4l;2EvU(sfS?CujS+6z;Y!@WkbhV%d(cgwQDPWIT&sg_~;ck!v= z3fdQ$$VSd$Mw@`T91(Qy5W}aTGb^>8eBxd4UEdODTr?uJ;{aSz+y zJR9UyAS6{iXREx}gVVI%j(Y^-(6bh~9L(|Ewcwf2X7|;w(QcHhC?dkvKRI{1av3Ouk zJs@Cyl-c68O~-U*I7(UgGRVqjMAKBScF`{^vP{qsQHPbF-$+I=jqPotE98 zEQ@0+FkfF8#l`&4N~^hGSXS1kKK!W{y;yU>Hr=Le?5ZEOmOKS4WS%!m-hxK2jfADD zBh}@NoNtg6iK4yhw1>#B^>zKeP>cbtxZ*J<4W3D$+LQJ0>Qkml+{k-5 z-%z$aHOzNiO@(IzVdaJNwT=N$uC6NdfQsvw#vgecwb>%;)hj|XxmBF)8pFnkx%FHE z;Le(vR5Awp*3zVR+I-y%It)9J0E}PWZ3W*tU4iu?a}OvPppMo8oTi$?AG|%~Yr_$a zdC!+Crx!}42>g6`fO$SvxuRB(JUoaDtNnd(9=gj5=#}>~ObIbb*YkjSF=~11)*#xF zme@S&icQG#JR-j3{l<+bX8}l?81tc(djx1W}n4JIK`siV8hjUPJT(F9#O2*nylTq)d`GXZbl5^~yqB&xUs2 zkgdR1tH-b~(|}8SvJBE5rfj!fK})W`CWYwsd9#?LydargIesa*G;|Es+|sGlsmtrA z3EybDnMv2{O5P;;j%DUbHMzF}r_3wJh(+~6r;FW}{3MGEgcC>@7AyG<6lKo)3any4 z-3(PMZ(Z|hAh|0)EfzF^Y29K~=MuflDjbM&qIQ%dAd4m7LZTjNnJI?P+C=!J zt_lA8XH^+ZaJ#yQ1`8HC1#L{l*%uyXHSleo&K`~ofi+KgR*@Kl7S$QdF3`p4btq^X zQOw?Xg~CeuOL;FbU9Fd>IWU!Tns@!QLaRFjBkq80)LD_jgGsSx3?DRmzf&heUjB&} zlFCuUG4U+vo>wqaR=$}uS13j{l~x!w8h?lVNpRi(+T!b~`f=&((x<~l28PT^dZqXl zDhHi@J@saBiy~11ahnuu5OC(}ZuUo1Hoh{OvLu;Ae$7SVcU|_=%x#oh?UVdp z^se-QLiP(t{x&2|bG<)SdMTApIpH(>EmL`x5Rlco;!^kY?@W6%v(8ZnZe6^}_TkJ& zJM2|oxG7~(aPCEM*YD|YplA)JizEoPm@?a?IlUf3b4rli<3E#P%}FJ9-!}`3s8k;D z?)2KaA9|W~(81`ZQ(9vD${obM4taK5zA2+2R?hxtX{&w4uwRh;p8c`9`-TCvy*p7u zd)@o$owRil9U6d==2H*-GR(h2JM^?AJ_4#rFQ1GUQe^O-w=*^6B^HYOR=f=OX`iu(oUN=l5eH)`uuG{X_6^0gE{IP4i2Tc1lDAs@lill z4iPT0|D_9t1W%-Cd$2Jdv}+^DBXO&)l?$f>_Bwt*SF*pKVAn?rZBx(@o$R>Rj!c(E z9dL)~N&3&;wH)Yj6J&lI>TPlD{LiS+ zw2Lx!S*qK>2Q&5Y@F-bewvq+IBOpv*tFlP0xK|?nIv4(5ao~UdNqS3CX2{H96yBOA z-vV>}d3+nsEYaQ9#8~5we2C~wBMm7t~DH80`rmgoc0Ir;iJ1f8S zqUe!>De6b)K4=DP{`Xi|BqXu%5N3}A=AwvZq;H&Ry?IPj93-oRB!kmv?Qs7cdll_L z?MEC;qF1`Azn*ql;^04oVNA8ZrK3QC(f&`vLToD^4duu6dZ;+%rtFD3S*cmxK3z)I1~VfQ0>-92-zJdYoa&bwlH6rWQxoRie77UsUl*z5ag%CWM2|Ev*C~ z1O25RGXQb$K*p1RdVg5YmAdf|?&=$WRLul4 zgkCAjl;@VC1L`?9&|noY)SpF%3hAvd) zJ)6U^>uB(~uRc$8r^C5t=u}eOBn~r`1j3-&Ynh>ai#@eI@|DDINcv7j(2qk>9LHC# zG`g%O$|SI#mPtrG&`Nr!U@3xQ+%Mh<70ojX6CATYdMzxX2&`bncKf2?w7glA#90?j zUHTP4`=^$LQILA`o9gFDYrFxGKu}P-*tLc7?%bY@|Y*1HAHV z;~RH2kH{sool~_r*J8rvc5o{Bckk_7VUwSb$cmF>koejIDF+!_pgANfWe zFQWY3V+q5tG(6HBV?}Hwi&0b=J5r*N1A*7a)-Bv~F1UoSH21K$X`~kOU5~Hl*S=+~I@mp=L@Sb4{K5-*;>w2|i17#Pj zjd$l<0jd~S)e_f11H^1IMtqkxh>nu;;g=3##UPafpvf2Ig5BAzz+4d;RJDQk@|a>3 z`xD;1>KeVH#H@Ku!-NcH^{7G{>ZPU?c06+~rvcE_wyG!YS|N|q;=PuIF3c8n8;Rp; z0W``SMLz>V*J=a2QPI?O1U|nMv!v<=IjzWRkWsLW64TU;!68bnTYVx>eAQD4m8Uix z(((rf6Mm&I&)ec5+pekCNE#~Z?>5oFNpxivLX&u@+5GXbl^NMTyJl$YFkn>4Nry&` z(p!DA6kAd(2Ojy>)J&~s^lIg$g13A3sdxT!;qKh1Vu3xd>s^U_sg^1lE5B#_QQkrU z>82AfO+|UH1EG?A^YZv)_IgAnh7&Wu4Q+=<-#}m-xPnz&MnTV20TOyGZBVCl-)x91 z$j1Uqt2qz{*pzpbqh&gI#HT6`(_|8a93LE(&Qm8Q8EDE6woAiqssjYx^>*BIvg-#H z&X#<-N9J`s6;D85no7D$J_)ywN$ed_(SHctZyAKQA?7Uvhg`{;scM||8({@1=+P5DM~o|JE#2doj9Zb5jV`kLYV5)^2< zpymMSRxGxLxE|Fmp+0EHAGqaTp${#9^f_l&K@Z!C%)$=_o?7m#Mnsy|3LkYlRdZ0nQ` zERMVKFQ`zw#r-KMG#^eU)mV!%o%$rJCsuY?EOuK?_ccBzv5&RRLj}!%jrfOHuUt%b zs0GjG_gNw$0^p$pyEn{*kTQt?s{m+sWR-g($8@@7`1KMm~ULjUIIJX9{A zWoY;7KW{miSjw^^oiQkVRyiQDM5=<8*Fa2zlYw+89hNI!{+~7%&qmy@*2n89*ni(< zY{X3w!yz+YQpyfwsoN)%5OPARF5kz#hc1cyhL?uS0GS?gNo#Rr*5ZZzlli5NH#);K zD^H8jHqMZCA-+{YKyL#z7DJ~df24@xfd1jJVItGG6lX(H_ODDNb*ebpFO^o3cS7ZV z+m=Wd_2Qw|HAe%o_=lD7yd*cx!Z?;D<<*9gAX#JBCKuI=cid_c|0FtPNZ_~VjYwTJ zN!OEY{&}@>gc=+nVJBV>x;jR+X2cnfTtB;Es95`LRTrQLBYDA2&~h9kw*E`zNaFVa z|46Wja;tY(#z@bOYxGB}7^a3r!a}q_9BM=qFc$9jFV`!^4$CGVIXq!aI7~(3?@Gfa z_m|{4gNBDD$P?;0yt{=df+V&k+rr35R3|g$JE!va;CJ~59}2Br58V}f!^+sCXz zHyT3mr}wz__z@5+%PC?bh(3`PMe(6LIuXN;r#A*%mU-5=jB}ko(kb>ffr+92@g}z8 zukC9@=m^|A z=AVY@+Iz~^)@SEF`bjpuhtcUllMD0PF{%ruh|E1zwo-2;%I>tlB_m) z5Kei%3S1L*)@YJFspjHG`+&^b3uzbh4zK!kxlq&b9Et>!;<279PzoG^!T^Gd+Awa8DeI`UjK8SykkY32ct zcB59^#Hn9RZ+|^hdJXD-gggIjdDoMqN4zc!#I0Cvc>nr*U0L%c45x?2Tlc0V?BNqH z4LKLopB7X9-Vcazx@y}F$9${u1MDkF%ZF3fzt$#xzzr8sxGK`feEWY~odr;vTidR2 zcP$PrR@~jCrFe@&vEnYpCAd2jcZz$VK+zO;Dems>1PIAV_x`{Cob%0Ol1yfjSJui} zkKR{lHi^MzXP=c&8CNzNZ@AFebjQyGDj%#Iu6yM}ty!9e#;>LeU1yj5(+OK=t&`I3 z*ap_ibU@y<0f~+aYi4T=G`)8u-?UFlSi6*$@^{Wq2L710%n(yz+g!}jM1IK27k;Qp%yZ6)(&H- zITZZ#gZ1D%vv*t#&(xb;kd)@P9c`PR;<3^Ugk|EY=>bRSuB=I%dC&jOP8*qwW%5k5 z{aVa_rs@E^U3NQl^X$+!5T3UHm5z8ryoqvz3;ao}Myj(5%w$V+JP2gWD6WQUirL#- z|6X8cikrR;lY)CP@GKWdJ0HK%|J{eL@ufN9RsyTd{TnB>z$h$NGN7!`A&8e=}KV!*|VWs>%*3^q@HtmdeOS!+|DBL)`$*MljuETkrr;9LqY4 z>y;qG}Wk z_y{oUpL(umtnOwJJr=h-ESxlJ^heI9us3sQSQQs_AbfKYz5}I)+9jE}g6|cxRgm2` ze_5Oui<~j3PnY0Uuhzekcsj<;X!l~&q>fw-HnKz?@FBSitJs+ccj=993@sQpJvmpY zw;a8W?40N{-5X%wnrRSp!vCS8dX}n_rhos$zc_lgc=BawrC#oE!)w%tSLsmkG)XI{ z^6$P}VS-8vVbgc@1<$^j49Z%z_1bNc?CI!lWE=Ns+rEPJd0}?8xnk&; zD{>`cz0yVnD~pQQdBf0HP}`Na+C2iolfhkP=by=+<@j9Xmf(3Y)YT}U8J(5`+-6@V4e?{~7``XEXk7gCJCiPNP zR~Ms%`J9>By#6zG?t2`pw~)rT)|YGKj=bvg=&^A}XPl!iB~(FNBxx(3nS;&UsPk%` z%xU>*I`IH!bfaFq0?N`tj!-`nbC;SthvGXUdpn_|^AUs<-Ubi$adIAuetNaeImw3B z!#1sRM@a9oDSmSry?G}M?k+MgY_ZR#1Y$+e7(qKsNjiPkY+{E->ajjj{IE|0$rb94TkWFS};nH|j!BiNJ3yzi)# zMQycH2meDCux$yRa&9<(xd!06-Q#|`faVkUH0xIwk>QF@NXI+fvPWq~D(g!^Ux+BK_RM*38frdm6`tSgV~f!>yW_&Kj3_j12%@^{bN z4g1!CCwJ#~`+RSJQ7h_s`y<1lj#wy$>nK%^fp#0-1L%l=PFEsOM&hU2<6yL)T7p>n z@yDMM<=;*~PlB;#oYTa-XEq?F7)&Mcv9(Q;vPS8~iFsk;8GO>ZlijBt z%`xiAR#c3`=go>S{f3#!Q}IR8+Ms6T9Ar}lZvJZ8q|{-x4QxfdY|f?6MIZ5^4iL7xf;D2R3L*0_GVeZ$gl$tmJtwAdb>*6e;-PA$0H zrDrW|iok(s$hQ(N!&;TTH1+5B|k$ z@*nRfEMnK2Ro5TV2z`xva*%0y8t&M9eIQ5Owr!oM%duV8S^9*3(dGFhx?5NK=z1!@ zdI?TF&U9s**4Hi2i|vQxWkToKuXkW8M5v>hK~Ia9Tg0LfSWq99-6OUPc;*;1M)XK? z{BH2;Ys1$9n2LcCoIW}45vL)oiA2US(n4_aGT1 z%59`xZ|td?kwAll;7%eZbYRg;Wl0Q&TL^x9vGaR!Lq%h-E&012<;)O*GT zZw=>5cbbVdG_Ies!(>hY;SefeKb}>*rWTlq>71}YEmh5f_Tt;qU^OqxB^L*GlDanA zY(1aVm8N|PPeKnd#8fJ9AN5Orf`QX}h9EnetHU}n2ls}iJMm3!cWn6cXB;ayT}Ak{ zTPUIun6A<%I9!jBGv&?=-bSnopgxjND+{akQ;-U2iQnPSa0EQvZpdr>yP+0wjd3I9 zyCGcDme{sjLF+6vkBeGQwq3ra=&@defV2(2 z#-a}&z(}vDM)I&Uw)DDfQ+nONN+#$QJ>*HSZ1tt69(J#jmOHQrJlNVyOOH z89B{p-FCG)&7EB>X1O#oY?aq4x1h0hP2afleo}42o&^#tXBfdX`t>y$kHnP2o8DX5 z1?6BDoQsZLjwL~yx#Jp!54Z8iFPN{-4u{4wKi`EqhN=bs{upihIxI8`?wjEKOy*aw z)5I9N+Dw4xH?6afy0r12VKdc`7&S1r*xkARm807O=b zI}wb#*`Emwlf7#?cfPuwrO^JPL#$_-I<6#r&LIrFX{G^_!MHk@G67;2BS)WfPNp?R zPYu>#9iki2*2;?!?i$`?t)(EG8`sr1FD~TS)Gd7x)m|&$mT?b zTq8(pxnR3XIj^9QWBn>grjE^^=2n;vkz<;FCi!UIj3k_m@$1`soiuL?S#1uvd#Ott zJb>QLBSkaK+d)lrv&<_qfyi9A@^7R`WFNivj+lfLZDJIk`*ZY4^n#<76+b@L95)vp z=Bqv*xnoMzfUjp?etH6WhA_(%MZC^p#%_AbH7)r+lF@>(X{xXCOI(8v%p+baoKkb}(Wuj#jIvrBO-zy9G;0Q@wff*8;RPxDjtm=-eam1W zzF&Q|5J|-I5a(=}sK7}2St=$h`A{&XEg=(JUbXxU1A)F|O~#@$o0m;W}BkV(Sj@SBF@ zdF1ND7wZhIVOc%>!)8el$0`Co+>qVuXvs=QHiqNqEcjQ=H8qLpUMr1mh)o^!q%x!O z`RV1#WYoRVEeFq=DyCr$(xZ4svfWffN#5^V-28bjx7jQZ%6_2?t<+<1~!@8^qAsGf`9?=FjRc*uh8XARTeE&_9ggmU=HX;F*v!;BH_a)ef zLHZ3QkL-`MwojDRA}Lb4!T5Lbl)>~^85-hw_~_fRj7J8W=%o2>RBpC9NZFpXA-F(4 zs^epvZdMve6w+KTs?RP@)8-uEg=5sHh(c%)h0XgX__GqSSsm&$9mH z5dyND)5fI~$VjtMz^wMTd`%4Yq`o4d^Ka-pxrg=>>Ti`RWu_vtCFmoLnrZ2}w}yl1 zH9pP$<%yGbN)iv&9VhoTaOvhw zVQqO2%gwg9rcx8GIqjRWi@*G_UxmZ3Vfae12zzn4-uMBk5K19&q^rod8xRuZY-dO1 z8d+(kr}h?mCJoS1rF?eyTz>S>G=s)9tnEtTMlXT>PI`QO4;DBm3VRE4$pTm`b@#oi z{G1U&{&7=-Vg8%`gouUDyBrQ0D!qbAsZ<;8wShi#EHw`R;9x_B;BD0^s;E*+Z@5F1 z$$C#FxBCpAX@7WsntBz#*vmTNZL?i%r@WXiZnz~UTPc+{$4~op@_i04Uh~CT55HjX z!`4)ZtS56zj}phMi%h8BLXJ0PEQJqS^+wkS0gCp(?Roo=ypYp~Rz2WEvGkcqO$b-N z#U9g`BNyAi)4}}7|1WbJ2xD&ZP?j&@Min?+nH;V;(8k3)TY463wO{tx9bru20=Oq}F!ec_3v=1Y>81RrBF*DO-Z++=f9jG_@V)UvUL&^^4yv(5FnFJT+DIwN7JiIG!LIN0y-Un8x zwr3tUIn3Y~y?{QnVN6=eZM-S)Jutd;g0Z93jkFZ!qVnbHg)J}t%z_&)pfPV(tE(ho ztTchRET-zUwqT>nlz*7kfiYm@l4~hsN?*{ho09Lr{hG;h-nhEcymZ}b*NQoZ+wkY< zkQ}N!=1fAi{)-8tAOR183 z^mR9`N(J>_chp{w9BpBuSQEk!jK7|Jh7YQp-KN^) zDu&X$-_ECezrG{q5(clIOMkoWi4Fc(x!!=51`SoiVq0ELTy=r&T4SGKd_^sZ|2wv5 z$p~0^4Ox7uZo6X7Ix0j=HSZj=F_XwxS&BWbQ zsg^|NW6ti=eP{Mj+77DG6IJzBG?2X_>-}$?(F3XMG>1a>s^+QJbqs5jD%w1?YYhl_ z`HyHFybs8Qz`oV>>$Tfp3fEf3)?b6+)u(R`bi%tE+&8-0*f$Ke*y^_zP+(!6!^+9J znoCL0h+)0u4NNV(t7W^BKxEgm=tySqrx`ZbX+W0irb=+@_B&_kRjx1;`=NbcyyJx;-DbN8M}(ErY#%Fq{ol|pA6 zw0W3tyi>VEH-;wguk3InrpAdXb*}}l5$*B&+H@j#E0HyXd@0v|!i)bzZvTdhvR;Qb zho@;Y z4;y`YUBIE(1FSn6z4rxg^+N%k?x7W)fBq(e!vFp`U~d#=q(1y6$s^+UcrD-XB7WJg z_}@ulzSn$?^oo7kLnz+gvql?uC18jz5YgG{|8SW9GdrifToidrlE))0UpqN0;0H5) zV{CXz3H+~m0+*srwbfWXC3=?krq`2?eVB=E((ugx?*L7E{Ykbg9c&mHQuQZt3rGGB z-#W20ZtL+*;vXba+n zn_fw!>$_W!ovw7@bmc=iszKLO>b2+{!*50@S#zotnOz4tqq1fz`KE{KnruPn=?b(% zCv3V;4Jbl$M-174rmU}Uoi2a#q|~}2*hskt_7PH#jE$~->K6^X4VMq^_Qw4r;ceP* z*Heqwfh*8q1qa#uET3?K9D6C0ieF1~ z0CE>vo@#VVldYk0k6+Nnkgs~H@=hB}odKPbB4>z``M-C5pu`Nb`J9_uUv7lbYa==> z3yQq1$msp3_G?fzt7RghsO!y<@kP>L&vU{$#+`eFRJ84$iu;@2H-k|lCh1yFFF3&( zarw?I1*h<;cnrdFI zGd3;Iz~OE6Pf}qfe-qyD8ZpH|r3@P(YDsYZ%&;k|k_x=(BpfO|&}03w=ZinvVV79{aK zKIG3#ZE$k;j_KGe>*lB@HOj}|JD41t#i}<&(fQ?HYBN|wLbz)g?et)}_ltVF)R=a&$sm5}KZufa-HlH&=@AOAX6d5 z}llAm>=IOup_V1N737DJM7@S;fOnJBU zJ0^kFZ9_4Q4{J;J1J7f%p4CxuEH2?2*^IUxYxm^aHS?oLxz|tKhC1Xgk?A2@Af3T? zNS>m9rp|{}0zocuynID!9Y%s{wG1f0GhM&ujMcV@6UiKwZ3yzWxlYIWXCy$^&C@rK zm|%v)&GJFLbHpUxJ?ezWCRIStV3$Eo73mib=-yq-K`otI3O@%Lrjx;@ih;l2G^%!M zY_sozRv#RS>@IzC89P*imZ#McMAa@eV!^P>_yK7{y4uJ)AEel2I;*J*0C|t zgxs*na*iYAm8~Rl&0fmA&Pd5pwtQBcfD=E?$u883X;z>5fqJ^uCNiOXfj`)j7-c1G z>Jl(CG7&Zc1Bs0X>(!ggH#(O;1&&6%DT5+~tBBxA_#CSqeqH=A<^LPM-uLE#>*mT> z_PN&IWLsEJ+9+ne{`drU>t^A?%CY@I(1!&p%bA?W;{;VtxK+K$3ANf-jI=BJkxx@6 zEqG(Gjg`(xvG0T=i!nSnuh2wWp2kKDbf%CvTbOKhtU)dg)dcG}IBBlDF$~7(%eAdM zvQ{{)`Z-x(BA|t2!{lXCaIDHQ9U_jxO~E(g07og(eW5&OQ`TcYNHA9$dS=|v`xYal zwyV}hJ;36u!ckaJGygk!D($2h0P^~;3+SfQaCsN#2-D(IW|v8qdj`<%kDk;P(?2FhTngOx9CO^n zWR9vhIW7iPsX6BZDcENI)c%J+%IED$YgFwB9~L4;`(50O;K}iJ-uRQxf~c_C?4I!h z%8l2*OYys6nVkdGv=&1Sxc z|7Fd%E22Ve;)b5j$q>%;Nk^+I=FIr2d)4U6f1>g)YU2vbsHQE8kgaooU>yooZF?a!-8w6=%t?jQf>QcZYhWc%M9 z{@5TqBQ0S2Ic(AgiP~nf-Xx)%_9Wa!%I4_)eipvvv9QTLn79Ta?<^r63$G`SpFV1G ze3f&_d)jw9j>4;I%0BY9ZiAeEaV+LTH^c$pVScbLT@@_zbSi$*xG%-<;;?lRtERCM zduCkKOqE$`&=eQiSXxQ>pJ9rk6wglfM7j!5T0g|I^+8VO5RVkxArKQ8Z^-ioT$(&q zeaX|Z`TR*OT=-o-&yR+`J|=ML_20WdpAtp!!01z9-hi^qd|@NP zWf8`>Gdb_tkzzITW^)%EGxL~Ia(fp0or%RH9JZa0myB**+YFjE0&F=bMOsIid_7HC zY6NHNZ|Jbr#fv3*j_@jAA6wIAcvYwHd`dd~N6A;?@4)ZzK(uhGuhe{YOKHn63ki|Y z_(}8?*SYzjfC<(q?h)3MMSiDrKm@frBc;c-#Z;vs(~!eDK{RSy7$E?J>hoc`bkA63 zZ~g3_5)QQFij0wHGKJMjsp1bNEMWM^z0?AeNfNGsVd_qtl{)HfmKj4{$eM(pCJ{$a zHR<0)fLtyM`feINlx0xmimYJJ=oa(o08FB|XpK$`^u7SP>@RTUA;w7hqlZ)b<0xl9 z2%mI}jZxoe3(QHn)stI_f3?cl{FZ*#AoIgmtw+U0ugcJf0Q11RSOEdD=d zHq4hpI)}!t7wK#CeFL4xgmC{by!>RE-E@I-KuV^|-BK;Rf_p9iJx)G2~? zc6ddPpiinL!J_;lq@(%fbc)$>kKJ~ndPi)oYTBxrCqP@#j4=tpxya*CTZyR4QsHDj z&1aoFz$5AZTP-XXmn?YvEIosMUq#5jno)Ak zN%l&q;3TB;Hbm!@TX*()u~-o#yN{ycwOw%AO(08GYnU0pvV5iDXx(QEzUBE%ltz=< za1qPO>F0M9e#C_j5Z+y2HK}a7*~pfiXzn)OSM$rtba5oxjIR?FS4o%f8i@y_OvLBU zpc)zU*rjV;51rst{Tv;Q<5*9dAv$cF(Xm`N0c~qKF_T(;rm{*W%L|B-{We)S)5aw; zQb~AaF@9Tq_*&IP4jbw{aUQYwQvKGw-&klBB5>u3x3DWPD{3gspv2IX%lA`5tgB7| zHQCr>)gd3BG`TN+8K0>%I64dceo^Aup1IYO=S<|;ImAY%gcFzpyRijig^E{^5mTsRu_s2*30>G+BMb6ftaaP|LWRpcU znN*aAVXd#y8j@_9BMEG3nxlyuPXt7gcZ!yi-^!~Z*S+?&&Yq;*g=&hZ`_z)2hX>Z~tua$q zXQnLw3;H{~U{)fcR+lupCZ4=V*JG>C6(`L!o~tqZ%IPAK{NKv7$%jf^Ch9M*KWXCX z?!if2^dd|ehFq~Wjw)$X1LH7LUEvFuiis*>ijO{z+&gmE2>G08Q+8$Fs9 zPOpq^_Va7)rKRJ-**?A@4}#g{%rEkg$dOQ6Z}<;Fgt_O{*XasS?>)oax^lKlb*iI= z)8b&cr*YO%v9E0o5qM!A@>R1dFzWKIpUz4{+45iZ+w4rj!JwQS_-3Rp!(rGqOtwZi*O+T>lu2kGt2RE>3_ zp6o#$&u-H+!EvNogUYjSTRaYZN5uyDNix$eV}+jzzD4bNsg9YJF&Xho4*BS1J~u#y zW^Xyk%KJ3tDN1AuHO47`9>L2xbG-auOaiMlF<#=ll%V6G$dXdtovC4`x!b96PK}S8 z_!(Ijrq5;DbsId@8mOO^ni-~@v|4&kt-RkT&n0~>dU`0hvc)Pdj@Yot3QoS;Jq1#!d zMZps0=-Pm!ZnU9=6k~KVVOyzx>}{Ha{>>tv7%M@vZOa@TJWcko@hGlN(N8&wyeic! z6_c04&8QteyIJ^vo4>2s9TU9c|83}-*nUzx&zRdA)PHvOVM@>q9g?)0iNBQdaRrA} zQfnO2;4V0N)1Us!(m{>o!dukJWF*#U~#kjzNW=e2VTYD@TXt~=M*iM6tjF%5+kjHM{HUpLw-4#4^$5hjqB6>gbF_S zdRKycr=wxdEZE7sB#aB@c)E{OI(E}3>ODEi=#`3rgm~2d8`@K$Skn_rh8!yB>hgN7 z*F{r^z-IH_U|fCA>MIy=Ic495haisu&myV`uJ5(bC2S2>!73syWZWT>V$;|v2_ zmNrRis?iEuo%G8$R&@S z`=2hU*!<6K(>iu3HpASDsLdsIM`Hg@z7aI?$C)zdrTC6@W?hs2>Q#e4r5 zS6Y{>6aGW|pda*Qrg&xB90x%wAsd@4M+;Wmi}uRHK455KIM{z>#AGMg0lg(cZfJyO zGYfSx#1TX~t098>6m^5Cf zQ?q06ii95~%)ekY#HWWlQV;6rQ7};P;7qQ>(;N&)Aw-eg52SOKm|3n+_=U)ksl1P& zt|!63jOYsBK9Upi9YU+@aynjFd4iK*&Gu1}vyjZ07V+>Rm~7O&8vRWEx~?%bfJR^h zj7csjQ{}!#TEw40(NeOXB z7JHVak-n2j>B=7m`h>o>g*|FA3j)ZB9uc1B7;j?Qy2GdaFNdGzWEu@u_Ip!iID>s= zLR0bquW;t9=2@QQMs+?hXlAUINv?{x@c2vI1SH5<#DTus0&e!5=Qr`WYJZUuH4UTA zR7a@nm0YfmSin%>N|`*tf}CyS`nw|wq=vWG8ug701lJ8;H_w!68>Z#hwYrv?$sC_I zRZ7=)B@nAYRBHK?;EjM9(417!k?|rv$14Hya1V}#=_)-oYTz>nF{9BGn~(9!8QJ%Q znb)zrB=Uj}^(^)A`E90z=t3#TYP2IIE`VSc68KQuS~&Ti!cSm>^2?bI+4s4oQ@=C{ zCx>=6*PyFdD+?S*^nXB39XDBfQ#Ey=oW=&_Y}VHGR<=u{nj&uOf!p1NM>joWtbAw0 zHY*wo$+%`mjQ|L~@4Mv#%$Vjd!+d_;q+di~w4Civ zQ>~a@1R>r&{&AWm@yvlKapz2V!gc&I4^oFy>@ivuAh>WK-XmiI(_c(x4D<+;Gkd@kf^&X}o zWqxkXLdUi>HrqUbl@)Z9294@KI?6;g?gj$02Kl|}&+%v#>hM#(^h_c*=7sFt7)2na zmP~b(<0@wW#NF7)um+)8cAGZ;4|~WOPeem~3I&zyOMPk=K{$doqGZTY94=;?ZOSDVn6$@)`=nTCa5 zXzOO3ZV%6ap$V|+b4q8kV&nBT5X)t6i19?&gATF*`sW;)%vbaJJ$b9u_J=dIZ`jtB zoPWwZG~>e`m40&ZR{9xOLQg)yPHf@kZUh^ZreW2KI18UM<)YrsFAq3E7h!`VC zd63$bmiN~2p`E{I_18zIHPGm*ti)cFopMFrBNv<~dSZ?@jg5x1Gv+IY<+FNRghKUY zuC;tUq*wOGw}J~JdOy6NcE3eL>CI*((c3e18p~q`t(&3?*7@xOe11@Al$Mh|&3`(5 z!|_5BPmVc*iW>og=5=p~%gnd6`Jj;lxoByU&okT*hyh)Vu4H0B5CwBhZT!)~tUwoT z2E${LKwve(JDyx+XihJR4xkc0g@cOc#590CuP!{2jLVYz#qe$p^|Jp2w{Lbhdh&r9 zBK#S2qEjB&P(B$c1kX^oPEcHh!E#c4t&6(OLsqdI!6r`R74A+PL?fyqtHA9#0*fn2 zeND|V_I)b$mM~GvNrSCVNuk$K^eOwot(y@!cpO1*<7?pzJIp93wP&fGh)LRz3Yr5o zn^~CuuxC+C#Fb<=iM-YDT}$TEdpzk=(Y_BV9~Z5-o{t`> zeFaK;^EAd`j0T~};ME_11mcOSDF=0Yb1SRvff8*Y=(DiB(S*c866iy7?>(8}7xX!U zpd^bahd&0|=Rd(99u9z!Pr@tdh_`a zq{W!x??AAfb8l|I)g#`I1xDL-0ohYS>~+MDo-s)oe}D1LKI@Ux_b^=_%cYn}pc#iS z0;916b%%~<+Ie{(FbDc-f#x9dS9{AhmJ+L1c+%U48WA$-61lWYf)pd3+P|+S=X=T~ z{gJgwP`Af$B`R@0do5Jd`_35sf<{|yWyB2XI${M2gw+&&@nm4jx)b*U&-w|uaRCP9 zjbc9gfcxsro~5fiY6|>xko}(5KY?~z>$U_hpczjA8+&TK6Ykq{A1e1W&W+RdHh7hx z;i|`|W|OZ}Z)ioCC=^@LyOY(lyH`oO!m?h@6ZEB*N$LITk#lYYog&esRy@BPJ6%^J z(FO#A z0S~IbuGSVlucSvoqFzvXzDXb!dbZ;vrst}(WC5COsKl(o8iRlA-TpWt)$gfC_+@vG zdU@pY;O$lH?t8Oc#oq0X^Z8}~v)*Ha`qknO-qnC>z03XR5@#rBl0=nzqnOuY$Ec0S z+S8W7<=MQ7roVCvL7V(TKulNIVAo3#T~6(-y;F%*GoScbBfier8nR&54S9~FJrU(b zyQG`_T$Up-)cQ=(%eC8YxzzV)s)6`3&lfBh>Kv7b&k0Agie+nV4|8jLPpQC{qA3-~ z11=uD(QX3^W^w3HO5_a;kLnl*^ic7xTRuIGAnQo2SdMScLj9M8U2LIQlB7lk&CK)P z2awJze2)aSV&2Dx1E{L+r&wf1Jscw5cR?uUPqCd+*UhYq6kh1}s%J+ysh|qf#sao% z<3Rg2m|g1)@aNEL4G@eh)D7A;y1ZP-?^aSG=^KNd4w)Tc47E!>;>91$k>XtFD~AOF zGw(RC*iI1^Vuhy_TS&AsAE_Y@B{4c&1C{SZYkY273#h~7)3yH)CqMVu1ZXBm+&(lB z$9(Bgqaer+6K$56E0kgOtoEW`JR5EE??y^oyLoYF;)ot_sxeP>eT8*QB>de!Osh*X zG`~16Z`U^6^^hAb$>WHk$}rkE^lnu+U4O5Uc-3+4PhCyhap-JQOZ9zY=H5h;Q`aHO z#)QX$Ax%T|Q+*t@?++i`cC5Z8tLK_~`^>dG`I{0Voj^;h>6k=NxXhybMGURXnEGzm z5xu;Mx-Lvw);cMBAqS$Z(;&K+sRltwG&hxsI7fCKQHyW7WJhOJ4D5~O`HX{{=#Ghg#4n72@UqIkU0DZ>Y0!Q0#*n<4c zxr89qA1{|iH@dsdj!BJTMNIKt421*4HB+e+0y}9R%VO*u-v4^EYG0}?XU}<>*(uP& zT%ndb#XdnvSOc@z6AetNV`R_d0dH>yZw*R+n=)a$R5V>^!x2shV}(=C;8M3j7?hkx zIh|$zZa*35De;viJ>(y`j*9-4_#Lenp&t0X9wneOzCYkCG*?(CkGAo*9*G#%QLaZy z^)3iee2jg-ErL)TT_)smG8s#v52z)ek=xqY77kRlQ~A0DngvY3htmkcQFmThJkf*^skN@RGSUGj7GGoNO&~6CRel7m(ZhQ{zy~zJ7`?);uyE)?Su_AuH_c9iC27BB=#!^ zHv+YBOAJ6F$l(vUX1Xf!6**@w2E(>H&AzP_y}nU-#8b*2G565-A$^t}Qy#PWv>cr(?g>IhjF-{Od8760IOQ$)pkbUCvEn z4(p}DuMXBpIr9Tc4LTCjt%zf*owqA7rB-I+lGz`baN?`U%@;+-8y`9z$1i-j<3_8Lr&c$@$QcHRW0eE)Ux0xX$hss5>NlKBvtHiVY>CM{G0N}x;FQ_s9;?c1F1q;y3%}8ld|AQMrNe&(X-9nvYL^xtC zRlBebGB?A!HkaB~X60e|0DZCM=Uq!}`=kSXGS&iS<0|DDV~-EU_ilcD>P7A13mNp> zS!>)3s)Kwyra8IVyn5M!aEjxsXrBj9D3{B}43A3kW546>CXruha&j1HlZ0lue2(n{ zJj2wBv_$d*;pP`V~90jjSrIQ_Aum%Ma`X6ffB$BvEu@APHF!BSQhB52G zCH$KWT(+59exoh5mV1BF)1k5(LuV%0?_TIJ5*+>XC&M~a{d^8R?rEd7lbDg*z66sw z3d}}`mv5^M4rWgM(DB*?kKB@h3tzo}lcVgEJRJ8Bevg^H*}BL~6e+Fc9QzVHwlQB9 z)t4_v@(`x~QCBEIoM?mFlpr7ja@EnAgt}AL;8tYa7=(@qJ!m3*^a&i&O}qECH0qV_ z5oJ^kH)hL7zncNR=O^92q|;~o`FK)vEv=tEJOK+nRvnK|L6&gy9VyPEAGF9qN70V4feE2bDO2e`b9+0=53#c2Ba6H{dz4P zk27NCW?Sq+0yS!WCSTm%fdJ?}rt!_Wf$CoM{U07;Sl)4%jUD!tK|(XVWlpobz;-ts zE$tru?*l!EF*hyN7lX%Swe2wl{fq+BeZ+9s5ty_n(KoPjBrpna_{si>VTAT68B{SdmvYkx{%Q^;k~gC{DJ+{}-)TBr?m8uLd%du_~U1Ym-u1f4{8T|WB; z)*t+i@8vpx9;Cfl?6SlKKSI0E@iEBahWMCoL{u>1Tdy%cD^acr4<>LSC;VsaR*Mn%;xn!@Q-}t!O}4`#CVz zpzZ!xhrLOpw)O%(fy)ze4L|-q;ih6ub^tdpDJ7z(yuuXT?X>?5h>2tG@@Ypn=+((9 z{Z;^o;^F|PVn(v^L>BM#gGa(enJ26>L&~|*cS?j}6cj}xhHC7y`JL;j$F$IIxC%fZ zFDnSSty#O2ekJ{Jr$<`W^c7+0JdbI=F)n_8sRFMC6H@H!oA#j#{H8z_F z_TI}gWUEoy(l{`L+j$DF$@U8(q!og{O{_EjrI2ZJV#`Ef4-Nu9AE*o+B*;;=}|E7{{4 zN!c3j<#P$L%iPCuNx69aG0u3xUUpf%B_} z;wEkt@v73YN)t=aNqefm8T9vwU%cN_R~ zv-lnO78Y|94=~$Zow)OT^vPp(y{GxeNi3DnD8gnS>VDEL+6uSasFpBwwTyCM>fc** zcvpjtRuXSoZf+pyutOMOiTKXfF1W_v*V}E}(U;%xvg(56f`q`6FYNE7zX?EmBDyku znnEQw0*mfQNu^$F4ua?QZs~eK2QZFTiQW8`ezJo6Ko)FtQEiFn{qZqt61%*YQdhq? zT}?P#ZYGD}2c%=)RhJ$(EaMS4_+|0VzaI>1LU^g@sl*O+I~mTMP`=CSlat6{OgJ$B zIFEVd86nkBCT-q6_+2;By+M=cbd}%L+tF1ru{sDW2z!kXY?GpAU5NZPy20SnXHL!! zU6BP%S(1Az9xPSHX#(e8MSs&oR~tm0I$aA~isel&H+O0A>XQvdIUUn-);VLpGX~#Y zonT;WO5;x@U?x0kkG}A_TYdd~{AZ(&i8-%`pCy6QQdAK$_NKc8GwvKFa!HUe067qq z$j*hF-rx{AKp&UNTp>R5uP(aBPfKc5!B_({o-b+uf2Fa7^w6NWtG=fK1tEXu2EbdZ z8cwILOAw9EMRcaVLw8mN(ewHE$bE{PKMfFnzCzO2W|_$DpCbD7nYR0*5-W4((mFVZ z!Kpi7EC3m;D3LAq8L#8JtX#$_Bmox?dk*PjH&? zkgrm+s~vw1!DrC|6c1oaf|FxozzN-1TeQtoldqLyNjO^+_ltNGP(TBa%lhdqoyZ2j zQ^4-G#&pdLv$A6pDk+5ZMLgr+jW_D`wP9 ze>Dr;@!I$Sy2?jh&_+3lr2epETZ@87l)B*BICyL3R?uuL?mIxVqD3t&s)yHW*Y5Xi zIzIDR&lEG>=({nx1_-zZ)-E2Z`H=t9)mMhK)irBVT#8$Zw$LI)QlPk`SSe16JH;s) zyhteSf#R+Oin~j23&kP0yE_T`@jUN2=Q`)hwf|)Am9=KgUfK8TH8b~AB!-d*sDCxL z3fQM+Xy|JFtO&Pr*bJ#gUP~t{x>udDmI)_j{K5DWWq%r?A=5nDg=o6>L>%MxS-Uk1 zzYSw$nY&3kpRmrnP3=U6QdB(Xq|3WW!=1`@*GjwK-RS-%zJ&)5LZOyiEV;U7d1p5< z#;E{#R3rm83*%Nzn%LiNhvufu+gWq2+8N3@vmc=s{Tr}hlidh2D(*`Km%l}bPiE7* z-fknDdGw$gPgkDmkI6Ut#h8JAe3KLD<{?{W^2?B>ck^E=U+Nt~D^ACcYNK|vq)YI? zz~F?6W$>!D)l6BBxj0xLRo=4Tbjs7Mi=1#HWAV<6P^G11Jrt`J9D60-rrtETHhv7O zrzcLd{OAM87j@p+?zwW%C>H{^B;9Kp^l!<8OT_He4@JoZkStPA>o4SJQ7!@18H+** zrpm&k9k{{K?sHjN9yX}oIrf$N*1Yzte^M;gC0J6slUvNEV4UnX14igtZ>oX5&ls6e zztGrVs+#$Z5^}hE2u39HMc7yIY~J8xJ6Y=2I}g80x}E38t72Lad$pHdt$%A|b;{#EbN+=c0f1)%71WwX5KHP1 z3i*d7uz(BADZQF>hmnzT>z@r>+Pus5-EjVfv9UDeg?LeLZx3tgNZ0E6nPNvv?GX)P zu7?MC1EO0EX0EZjUmqlY?bC?m9FIa(d*R5ly2`A>t3)e6wq>W)H4(DHr5A25v5c7n zbsO#?S#XmBoExGGFiMI{$z- zKY1%O(BV~=1?{(~>boaBU*j3G_FQ=IwK*h==Ra_+M~3bg5t7?UK% zyclg|22>iQJ*50H5KeiCt-cHii?pvig3tT^Rm{FLf_l%Yd)aDM8lK&VW7SoQg!8zF zk@zSB(rWf(UcV@**h~Bd2MET1SykZ#1M_L{OyOUb@lJ>0#DT@9VWF&1HuwFVA+e8D=OEDYZ?NIwyYRl4B^#F`_51KQA`4QR{DxrMAZ4mb zlhog_;7=S8I}_G2uaFA`D%jRRwj zhr)!@ENyTM{bPw0%uaXDs5_yOm#Wjp=y%d<6R-2b?^k=3m~|&nyT8=@jF0~n4N?0t z#WSTP4!5Ym%>PwhSv`)CMlTrt_PB$nfN-tJuPbTAw=)j9WITFCqPnLXtFFjq*Dr!n zP@5eLl{_Dqu&7ck1nJ8!P;W;t&=)m32ks4LyuF?q>Xi{!`5+yhU65os;lqk8X|5)+wO7uj9_|Dgc8M)patL=E&C z(GgwLW<@J@_({p)1i#Ad_-n4c>>hYgf;ZB+H)6c4LheoTz>g0UaErzb(rL+3;3aB;Xm zc1nd)l6`w|Y`b^E6~U1%czowTdc8hS=g^oJDMgKC>Ql1XN_$xsvbMaPYatE8?d+4o z`Wr?_Z>FuG(F9H(2jRTOcG8`Y#%Tlbv$0=IvFY4&^=Hh5cSTpP@FwDzR!QCXwu?g1 z=A3nLLMg8EVmX#1P3!6O8MZ;+eWVK@uN3Wr4DJJOtQriKQF%$|S=L}H+c1-5pJ}^D z<#{hk;=o;j?gLWeU_+Let$6kJ0RTzq(Oyy0X@}eBIB`KoZr)}^iq4;Xjh+!K4F8*< z;gb-BkfP$EwY4`@ym^IL8D@!S%idP5uDQAN24LDuKJV>-0WW_@NM;1@ST^b3lR&7* zv$_>D7h6qx$+%wCFXC9zBF+;-0r4x7BP-@Wfxox?q3b6Eq(Md86MSQY`ILd}^>y~c zH^s+GjH#LPdB|DO)XX(1SEg{*mn;+rVYB171GU5LdD*M43!grGARbK2W;fLFL#}OJ z$B9e2d-x$4x+wK*_<2sHvJp1`{om}bRW?9GF}+dF071#ti7VLNZKTf97V ziRj%)VEFoaIS@U^Xv{Cz7tI+l8Ky=0#qg zI52d@x=H+f_xw^~DL7S&7dH@#Q{ArRClSk%aMYKPAHoW zwr)09;h^=MY3WTO*PR`nKWII=4tW|~oV}HENq3`x!zR&9Lc8E?(w~&*P>s_?g{#X7 zAeQ&fg8^H854IhMPN{Vm^71^-Q;}Z<-a|GB=*gOVHe2^v{YBy1VTQ74w9-6>^(fIk zs_JQj{+o!}jSb(Yl6FPzZFR-h(H=3P4s~e|PUJ}&82^q`x^at)FT8^`WuJ$zS3LW8 zmE8V(q)$9T8$li8{u}4c7#Mg|DirX)gaI3GBbohFlA;h6=G&pktlhB{P z-foR>^8sXt(sOy?w-3tck61yw!O;g-A*Aq{-y~RjH+lY;b>1^I{oX>k{PDp``0ql% z{+3t)zA>^&ItG9*X%rX@;HIjgrqb5=d1IUv*kk!fml53=_;P?M^Wg#^`mEzUJry_g z@t?Kx0^;z~DT}#fu4Kf(_>6G%Q8B`?lhXg5FQC~U?tDa5haF$CIK%eOBE4_&)Ckln zNPUy=XZ@CNWiwoOz#d3bXK8=p#sQ4EL-vg{cPX$WaL9al_k2Lf7ntQjSzw5}<#t@w zSQ$UWfbhN-_1V8Z#=8W}Uaj<66Ixwau;k?Sf0uVyXJ@_@=D%_Xcot>zyNud4wCgSN zD!tU#&CfEQArATwQ})fzlH`m1opH3F4`sB0K7x=n&&rUk0#eynA$^K#ZMeg5;97Vl z6K-4v!D?pJ_mc0JxCL3rNe`R9!1r%vdL#Ezq<~dUR)*nap&OJB9r~&6EdG5;;oZ8z zM(Ca=*LEbgb!GVJZY2{&pB+!Kj<`$LRX5Wkb$?o-+H{7KMk$IFjx>jzbNKRNvLQZw z=x`qB;NjrNf&Nj}{@hSq>s|+T0PLg?cM=?lkcI8C5&Dp{oge7GcN`>&-mHiIP?{!D zbc_`B(Clz|e2*q}R$Bb+0>eW5!{h6i{A>MHj!r0hvup%AFlY0{)%NEFUupNc&8N5> z-X=%F3@q$kT7{kv8{{S=e3O}aLkdQFe@QX8n4cm13g*^)M^Y|()b>ryu;CU8#9#J4 z3V(mTPHEW*GU`iNyqlk;%peEx7)jB$DWFxE92&egjM^nM>XElbZg*ct1;UQfhHhq$ zMr(^mn1-nE6BoF&wRk>IeX0Q$oeiJUL+s_4+JNknQ};s1F)vV}o_B>!OBEJ5v)JtY^kjVakqV zy0!)@li^x7yWpiu`ktU!WOhNJZQ8)}Sqh(Eb3JNqgi(v*HD{YJm*XwsoKbr&u5ziH zwaZffjrqAc<8V+jAO!;+Nk=IJA%qKa`>ipLq~fmM;;$qqSzMO+9}hL891BH-Xe8P( zq1F^h%IEXf*<3&@=$f$LlOLCh=uSMg8b%6vz+l&v)H-yoO$*n^=@+VY_by(-n$AOZ zSsVWFABQ`Y21!V*N{q8PAI#3nTW921%G0083$N!eK~?+q@;=UO=hz7m!5*TpCu;dbs7MTa$%fi`{nn&#cV8Eht@+J-lO5lspSE^vCN33B$2y} zv0WH<_}XV-l9j`qHA~@lVg`Bp{RRPRY7a(k;fFgAoLIz&CVx4hXku=j38kxkLk;G! zA;}Ud=5<`6=9^ID()bxlBG1n3EOl3MiJCXp*aE=zc^(hqYl%-j7ENqx*EUl$qviN0m1{qifzI zJ?Z~TZ<6z!&}w!k3^!mIvQ>{Gb0(VkeTAj%7HYOTp)QSeP+akj{l~kOV=FzU!k=)X z6jXa!71o?)>>uB@6*W+L_;nVA)a4$8PJtrFQeW5mNpZ7eOIjL>-vKTCVqIQTDQlPH zT@}a`9HmUOFjYLaKJ=Tto9~y^?3~;e!xHtlG%;4wd?B#s)o`W?+~EJEe_U!LvD^FE z<5U-m@8ieoA}9eZ8_M&=R61`(Ii8WT0c&+3HO<_cNZs3u7vJ@ElKGA1S;t#D>SE+b?=@M-t-{Wx#Ko6C2 z!I?86Q;^E;aj90Mw8`=1hkU>!{vL*fQl{@FpsbQ}19~oYJ*VwaBdaVcR@x8?3>sl3+G08(CTTX1N zz?^Pt{H0r9@UUxjQp@~6&~`esy_#TefG?l?=jDRx=jQ;~`wu->F^K5;hckl57R2=V zx0_&Q3HXt|`Q*_!1T?_901fhieRQLs=y^MX zy&STf_XL9oB(&2Mfw41l^DutiP)Ts~4no*rXokvwTWFal*iuJul>CGD98L(yu=Hit z?hGo_exJE!~prN1#U^!4KhZ_MRZ zA!E^j1(B8^Jj%eh%(h4WlSE-4-nITCG1DvOfuoa>xfiAi-t=_GIkdV6d&8Zs!t?&S z(r?*O+svfN?}5i#$k|jp49h8xks<4rI~&1g%4K>9iu4ca=Sse*pvP$ z=~b`ZmQ|O%7nGe%8m4=nr4i*-{!82rDoiwOb@^rbNe*OvUlG({soH`W@q5Hq1y0So zE8ud&J)^zEgrM2&O-@tu$^_Zx?UHhuIYfd4`@!=O30RG-k<%tE!#b|gs;dUGPt@BriacEdr6G(5Q@ zy%r;cZS}+3rF{6``%rQL5tMoZ(wp|kg(-&t+gPKyzod;0v#)vnA|?kWPKKaRGSFkE z{Z^OuHs8lb;>(jB!{q@tPq*Zs6QMY-!CvLSI&8?1b({h9*C`$g^?)1-T(!S4Q>yF3 ztzOR`pLWA3EJaL#ifo0zD8$>N^~A0V1wnMK_{@?8F2lzx4(PypQ5EoxfjStRB%h?k zcPM!bOYoHOhx+{3tJXtMh<`hq9|6C1KKNxXidJkePZX-2>XZ_@*1PfG(aUXLyj2>E zpSRcJpC> zfV{y`pK?_blE!|d=(er|d~@fE)aSFn?=MrONEnFZOmp0Ls9*m1rev-eFD7QuLBf5d z`*I4BDYO~N9CL2@8kyQ--$7YmFhoa&)lqK$JPHp|ThsnjT8Dyww}1zKvc4oti@j39 zu*!+LWUf9n6ym+=%7k+7zNB|zjiwZOcbUV#T2@HektZp00!;Hb)E&)E@}P&gJ(n!` z=rdoD63)t>CYqsKD(ZYEK)I9Q<;MCH1en@#K_mF$Y#T4V0kUz&k=pRY-)27^KoPJ% z+a;v5`uxUPu%B$ zxD>CXd@*T6iST)WiHiZS*V``5-Rb9N7zpI(CBCC|UB^qmFD~Xmu4%WJpXXU9i_y9& zo6N|aXQu)Od$3=+bM`-GT%!)nR$zAT_nKjs0dHwu%oX#CcsaQb-R_+Al+cZgJkZ4v zYt_l*!#&|#4RgZf25^n|s}dnT^(8$Z!~%P zasS+FexxS*fgN@tlA@h?sXGnu1`j&FfY;OCo!#h4Y=cs+L;<3ig%*NPf1XZ$yXXsx zs~pK5`QuW5Pwj`Iew|4=0zBs)nRMubPJu1~ExHSpC~yXFpKvK}_~fx747x@3+CZIY z{A}qGNgt=?&sVJ}NBmCjZ@TR5oBW{;r!wvhR@3!{Nq_g%-{Yf6!qlZE_ylhK7-r}y zfYw2?)|%B1HW5ugH0Tkme764RYPP?7`HWsY4y$Q<&#~LQMW-TUet^t(whQU2fV649~1RKh&B`^UDNU132c?zz zJHjK@9(b!XU8R7jldyVWpuiR;SNG;JIPMd2^KMt_b@^RJ4JRn?BhmH1_Xa($}ZqM3J2pW)|R|`o0m{D1W@o=*uE-yb2-*>^CM_#By_=%R}W})k+mM`wyq zKqD8%zZGfnBKESM=6!E6^V!{DKw{=)64Rqh!tnjy$dhcY?N065+64v&0BM@W!4i&- z@irgr8QdFUzEYezT@5`6r}BE_XJI1=Rb6S#s*uKV>65Y1T&K4OVjdBA zAwEWC*OP~tTXvHYN@<$pN*^ikx58sjtpA;8S= zpR{OzJ}L1x7WeL-J#5jc_oW6gsI>2z*3mpCE!SYRBevOymXYHs%I9vCltijjm|a#0 zQN_tDVSb#``}kN_U2s4f&8Nv}v$=@a`BGt(eC-a-iMD1n=MCzl)vu(2Tysv=%aHc9 z8<)$;E3wyZ*OP;03r#2aT%?E?a`FSQFz>PX5;~DOW1IuK2*_J$7>GPSj}Y?{`u?;; zI#lxecjPw3VeQ7=T&70(3hKI|3A5!*o~7PQ;s@>yWCDovn|tZDJ-jmaF0h+)Xjy!~ zqv|1ssEBsE>ku&X6t5D0Y0>xge)j8hrgvELY*F&rA=YWx5?!;m*B_wSU&e3os!YUMDEi0CQnNl1f%+9A zRFnxAnG(;H*F#0^5F;uTzJ0!nPmkz( zc{fux)y!aQS^@4Q2i_y@!0^!S`qb_bK5>bO5yt}THRdux?T$pxfms0I&KPN%b4T9Y zHCrlQG(wh0O4i>xC1=X1K1|7BamT3v5eiFfX>{QsLjNKcx9dJ^{%ax*z{dMbE$Ci~ z%I`gCTFbf|gj9+|NK?Ht$;#sN7`8R1Oj@R}6ZI-))cPa77cyJ<^GJ3>sOpG+z}|Km z;*!VCOGdo}m!@GBn2khPkR=+mBdISG8u%NzE|-4ZEbDfENn zDMe52rH}VSenM=;_hn9Zn;v7WDktHmx$A6*VzkjlK7Q3ji?f{fIsz`MD2c;sDN|YZ z%U(waM4q8G5*m0hM@3<@~%a|QbN)qWma%5-CP@q~ZWbHC3|I=0~ zc?H*pZ#unqHJJ@ma>LGx8^=lVG1N8C`bWe+>69VQtrl5qyRv`m{X2;oMw)0s9|h~5 zRA}njK6C8cI+kG~_q433ydR}co5&K_Ukzf#PSqc5V*fkk(vQ!u*6qyEWv@N{Gm&TM zV&4qVCe^X_0%!(BC~fLp*wiSs+nwWUF#gEJB^*XbYj_3VwrU;8MX7lIt8ePE4P9{t z5NVpc=zkPNR2nsSqq;yOD|IWUNhZ*PAB`esLe;X@IiHI0XNiGd(>TYBUOSjX?0d1Y z=K44eZQjj4TB&h~yY4rBDlQ!%^G*LJ1*wubjqJ7iKT@$64&EEkfuE(TJ}wNY?^=XW zvwzfIt$*4!7q?bv2YnlR`YO+VmiSnU0vShu|{W7#)7tXe8@|B3$QSE6T z;DFY)ztM@$Y+d4mLh7Y~i#%_C8>|y0(&v2uhkW92%v?g256a~ksqCEPyLA8VOtwPR zKne9DzEjxQS2u;{x|jOoQG5I^h70$iiUsUF7g5gmikkSMyX~9NLzC(ne(bSyMok>~ zLv81N;p#$*t}<%?*lRlZ0|AQQ{xuk-KJAC}D9^|ahaTk$MCn;+wOGN+1rWaqR9yE^r3TpAD73?wQ0q)BYZ%GgXW8{dC6s&%X19Vs%}EtiF) zNi2_M-)7EMk$+O{o>PCV_S2LK_D4}N2x-}Yz)$2CS^k5XP-cRlpFozl!c<2ZFs$2C*JA1sl_Bp4Qav=}Hs9uw?UReg@#J@eks_cMAxi`5@Z2_n zR%kS%cC=$XMOXLaSRS+VznDhu`ns8GxaZy$TgUY{!5b^&OP7mpxAax}1l7i`k+;fX zmjLra|4Cl_;0^?_j{;niGhNej*AyqG7H81^8}Zm1uDr`VA=;Kn%!&1a z;%B!H8n_iM^Zn;Pvsbz6v?lv}=QE{Wne&D+9p%vaFFy}9OhBhKA_ zCDmKj1ZVpdr=JMD|D2BpEjwiY&W%`F}F%Q47|EBUE9L{^G{95HwRV=W9)9=+Fb#Y}PwIdZ7nb|XP zd#w%IK1;fgAL#}cV_hqNffwbp5jbpTP5m`IHKQ*x%n@T$T2zE2d0(w;F?abIa2Cmm zIS1&{Y=-ymHo`fFul&BFlzOO4hQ61buPup+PPd2c&<(A>DxPRES#ukuQJy1EJT373 z%bPUkxp2|*R}#+6ewtKxjE)Co0@_8m+jgSK1Cf(xs?cX#QBRA4RPd}7xR35Sb=q*K z>cXz{7!9zh&y^UZ+iOsyWswpIY_C)LvMfzx8zlg6mo^2L(1vfPg}}U)8UrNbLX-0G zoU1sWu{T41dz-R~W>Tu3-Z8luL++bQ9;#y+ej!KcO>Ajgd4N z);r)o&&3d#lo5rTJuQ(D;>lR9J08BhGSbsLb!>HG$Hp%x#5HLDgQ@@Gm~Q(g-I|NE zDA9ed{I{i26Gi{l6gdUns)PvHj&2lF&^z38&hm$O4rp zh}PS!NYG5^ni@rt!lZ%xj$-pnEL(xtAoEg_e;;|ev8bWB|7}|Q*AHwHMFQFcNT;QJASc3w zg60miqf$3Uqh2*+(jyEXo7?{d?f8G#)$74VjN;@>^aNc?(N;pqaU-hQIhKC zk5m00anXN8qp#`E;Hkjf`IJx{`Esk)D@PT>0leWVDX9NK|Nl%5r;-95Q|w?jxSAKl zh+Nd6ezUvw=D+QW|0v6k<-@7EK;K{>+9~todeUKNehdK(Y}iIMi1e*U-~3m1|Ckooeng*h@WQ|gqm3&~8D(7Pt+aov z&kUMsB&cLj-u~O*Kh0jvG2u+#E2w6wQkw|H&@LVtYut_yx!I0ww&k&1+!& zD);|&7{@OT6PMZkc(f4T^iD*!dnC=!M{z7p4Q3pYS!(Jq|C*%npgC8dK&QXm)#54D z!__!L^WK$xc-u4b32WSC&lu>PcS%P4*IEu52Gd!Wb^UiJY`(jpoQYK10BT#PiyLf!YOWNz|GY1(-? z8xm~Wh1noxVSBdWfrSE4r0iNuAY}oauu=VJscmxV-3~ZaOx{<(<((n%q%$YMyGP{J zkGf0d9fPaIUT@uYwG7al=IgO|s}u49yfL9yp5*U@0k;I0&?lj={NPC&UZb=>g_PBy z>%EdSVpXnBRTi7TLl{m#=6z}$2K?^ZhP|YnB|aN^%0CbJktIWS#|%Z4Ix!6>8|%PD z0U|Q6`mXAftp1JZDtZ^zXjG(HpT0Cr)p--bc8y};E9MF;p zv6jk*r8|X*vxc7QB{3YD;(8S>7MlEKw#y6I%=q-)7I#8X-I=j@Hh&4{3$3*a4a`Yt z$OH-I|Dwc5!aQ>Rt{#LHZEH;iuVb}@T7TqQu_<1xQCyl6Nt+AUeK8!qy_V2?^kkjB zs=Ee_(#Vrw{Q}l``&;Qz@N;S>J?TYB3p8QP_PY==i?A1KflL~PLF^8*b8t~Z;P3GI)7tfbJse9~wF5c+MGXyT19X9k)i4M=8}Zzn^_^f3GGy(s@2;>)+x^(MXP z_0Q{|c+Lqc(BYv*^7p88^ZEi@X#5}SUi(;rfAsGbcw#}dz7GlQTkl?H5wq=d<9?J8 z#)QAasG5Ikx#lmj*ez(U>bm8z@&$_MKE2)rg_FyEG^_EKKoOey` zPUkeVnTU;g+Ok!%Qv^NTk+kY??Q4CJeEHHsjV*{wFl;Z4qUY>Ql%*~8{L;@?YdP-d zvM%WQM!4hboo*Ua{wZ$k%fbOT=|;pdG_U3;>lg**Zzd@AwAeTGVbV`xOTaH zv;&P5J~G(4*Ix||);sUBS~Af)A{iqk&CoXj#Bxo#S#p*aPIqeSFxDatY==Yb4l;!g z7gE;-_!p(f%54L6t!2lY3~ord(5hU|*VY|2=)8kzW%G<{0Gj~vox&8q%`9pl7USI12vLEB8q z)HrH>S4yqBsY|H9XC(ewk_^9_@>A0dVU}Gms9c^?kePpGTq{<|W{Qe(y29pT@ literal 0 HcmV?d00001 From b35f06024f1940f1f041f3feb4b4cefb17a1672e Mon Sep 17 00:00:00 2001 From: DudeNr33 <3929834+DudeNr33@users.noreply.github.com> Date: Sun, 1 Mar 2026 20:27:11 +0100 Subject: [PATCH 2/2] docs(tips-and-tricks): make LSP config OS independent More robust implementation of get_python_path helper function. --- docs/04_tip_and_tricks/04_neovim_lsp_setup.md | 56 ++++++++++++++----- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/docs/04_tip_and_tricks/04_neovim_lsp_setup.md b/docs/04_tip_and_tricks/04_neovim_lsp_setup.md index 3f67f4771..d1c4a5297 100644 --- a/docs/04_tip_and_tricks/04_neovim_lsp_setup.md +++ b/docs/04_tip_and_tricks/04_neovim_lsp_setup.md @@ -68,6 +68,13 @@ you may have installed in your project's virtual environment. ## Setup Alternatives +If you want a simple LSP configuration and have RobotCode installed in your +project anyway (or don't mind adding it), [Option 1](#option-1-use-local-installation-of-robotcode) +is ideal. + +If you prefer to install RobotCode globally via `Mason`, you need to tweak +the LSP configuration a bit - see [Option 2](#option-2-use-globally-installed-robotcode-and-set-pythonpath). + ### Option 1: Use Local Installation of RobotCode The easiest way to run RobotCode in the context of your project's virtual environment @@ -143,26 +150,45 @@ Next, create the LSP configuration under --- https://robotcode.io --- --- RobotCode - Language Server Protocol implementation for Robot Framework. + +---@return string|nil local function get_python_path() - local project_site_packages = vim.fn.glob(vim.loop.cwd() .. "/.venv/lib/python*/site-packages", true, true)[1] - local pythonpath = project_site_packages - if vim.env.PYTHONPATH then - pythonpath = project_site_packages .. ":" .. vim.env.PYTHONPATH - end - return pythonpath + -- Search for the site-packages directory in the .venv folder. + -- The folder structure differs between Windows and Unix, + -- but this function handles both. + local cwd = vim.uv.cwd() + local project_site_packages = vim.fs.find("site-packages", { + path = cwd .. "/.venv", + type = "directory", + limit = 1, + })[1] + + if not project_site_packages then + -- If the site-packages were not found, RobotCode will still work, + -- but import errors will appear for third party libraries. + vim.notify("RobotCode: project virtual environment not found.") + return nil + end + + local pythonpath = project_site_packages + if vim.env.PYTHONPATH then + -- Preserve original PYTHONPATH if already set by some other plugin + pythonpath = project_site_packages .. ":" .. vim.env.PYTHONPATH + end + return pythonpath end +local python_path = get_python_path() + ---@type vim.lsp.Config return { - cmd = { 'robotcode', 'language-server' }, - cmd_env = { - PYTHONPATH = get_python_path(), - }, - filetypes = { 'robot', 'resource' }, - root_markers = { 'robot.toml', 'pyproject.toml', 'Pipfile', '.git' }, - get_language_id = function(_, _) - return 'robotframework' - end, + cmd = { "robotcode", "language-server" }, + cmd_env = python_path and { PYTHONPATH = python_path } or nil, + filetypes = { "robot", "resource" }, + root_markers = { "robot.toml", "pyproject.toml", "Pipfile", ".git" }, + get_language_id = function(_, _) + return "robotframework" + end, } ```