From bc103235ac6d6bab88487cda56832b202e374afe Mon Sep 17 00:00:00 2001 From: alploskov Date: Wed, 29 Oct 2025 20:24:25 +0300 Subject: [PATCH 1/2] AP_HAL_ChibiOS: add Aocoda-RC-F405 flight controller --- .../hwdef/Aocoda-RC-F405/hwdef-bl.dat | 38 +++++ .../hwdef/Aocoda-RC-F405/hwdef.dat | 145 ++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 libraries/AP_HAL_ChibiOS/hwdef/Aocoda-RC-F405/hwdef-bl.dat create mode 100644 libraries/AP_HAL_ChibiOS/hwdef/Aocoda-RC-F405/hwdef.dat diff --git a/libraries/AP_HAL_ChibiOS/hwdef/Aocoda-RC-F405/hwdef-bl.dat b/libraries/AP_HAL_ChibiOS/hwdef/Aocoda-RC-F405/hwdef-bl.dat new file mode 100644 index 0000000000000..4f7bff279a25d --- /dev/null +++ b/libraries/AP_HAL_ChibiOS/hwdef/Aocoda-RC-F405/hwdef-bl.dat @@ -0,0 +1,38 @@ +# hw definition file for processing by chibios_pins.py +# for speedybeef4 bootloader + +# MCU class and specific type +MCU STM32F4xx STM32F405xx + +# board ID. See Tools/AP_Bootloader/board_types.txt +APJ_BOARD_ID AP_HW_AOCODA-RC-F405V3 + +# crystal frequency +OSCILLATOR_HZ 8000000 + +FLASH_SIZE_KB 1024 + +# don't allow bootloader to use more than 16k +FLASH_USE_MAX_KB 16 + +# bootloader is installed at zero offset +FLASH_RESERVE_START_KB 0 + +# LEDs +PB5 LED_BOOTLOADER OUTPUT LOW +define HAL_LED_ON 0 + +# the location where the bootloader will put the firmware +FLASH_BOOTLOADER_LOAD_KB 64 + + +# order of UARTs +SERIAL_ORDER OTG1 + +PA11 OTG_FS_DM OTG1 +PA12 OTG_FS_DP OTG1 + +# Add CS pins to ensure they are high in bootloader +PB10 MAX7456_CS CS +PC0 FLASH_CS CS +PB11 MPU6000_CS CS diff --git a/libraries/AP_HAL_ChibiOS/hwdef/Aocoda-RC-F405/hwdef.dat b/libraries/AP_HAL_ChibiOS/hwdef/Aocoda-RC-F405/hwdef.dat new file mode 100644 index 0000000000000..46aad043c9389 --- /dev/null +++ b/libraries/AP_HAL_ChibiOS/hwdef/Aocoda-RC-F405/hwdef.dat @@ -0,0 +1,145 @@ +# hw definition file for AOCODARC F405V3 hardware +# with thanks to betaflight for pinout + +# MCU class and specific type +MCU STM32F4xx STM32F405xx + +# board ID. See Tools/AP_Bootloader/board_types.txt +APJ_BOARD_ID AP_HW_AOCODA-RC-F405V3 + +# crystal frequency +OSCILLATOR_HZ 8000000 + +define STM32_ST_USE_TIMER 5 +#define CH_CFG_ST_RESOLUTION 16 + +FLASH_SIZE_KB 1024 + +# I2C buses +I2C_ORDER I2C1 + +# order of UARTs (and USB) +SERIAL_ORDER OTG1 USART1 USART2 USART3 UART4 UART5 + +# LEDs +PC13 LED0 OUTPUT LOW GPIO(0) +PA14 PINIO2 OUTPUT LOW GPIO(1) + +define AP_NOTIFY_GPIO_LED_2_ENABLED 1 +define HAL_GPIO_A_LED_PIN 0 +define HAL_GPIO_B_LED_PIN 1 + + +# spi buses +PA5 SPI1_SCK SPI1 +PA6 SPI1_MISO SPI1 +PA7 SPI1_MOSI SPI1 + +PB13 SPI2_SCK SPI2 +PB14 SPI2_MISO SPI2 +PB15 SPI2_MOSI SPI2 + +PB3 SPI3_SCK SPI3 +PB4 SPI3_MISO SPI3 +PB5 SPI3_MOSI SPI3 + +# CS pins +PA4 MPU6000_CS CS +PC0 FLASH_CS CS +PA13 MAX7456_CS CS + +# I2C bus +PB6 I2C1_SCL I2C1 +PB7 I2C1_SDA I2C1 + +# analog pins +PC2 BATT_VOLTAGE_SENS ADC1 SCALE(1) +PC1 BATT_CURRENT_SENS ADC1 SCALE(1) +PC3 RSSI_ADC_PIN ADC1 SCALE(1) + +# battery setup +define HAL_BATT_VOLT_PIN 12 +define HAL_BATT_CURR_PIN 11 +define HAL_BATT_VOLT_SCALE 11 +define HAL_BATT_CURR_SCALE 206 + +# analog rssi pin +define BOARD_RSSI_ANA_PIN 13 + +# UARTs +PA9 USART1_TX USART1 +PA10 USART1_RX USART1 + +PA2 USART2_TX USART2 +PA3 USART2_RX USART2 + +PC10 USART3_TX USART3 +PC11 USART3_RX USART3 + +PA0 UART4_TX UART4 +PA1 UART4_RX UART4 + +PC12 UART5_TX UART5 +PD2 UART5_RX UART5 + +# USB +PA11 OTG_FS_DM OTG1 +PA12 OTG_FS_DP OTG1 + +# USB detection +PB12 VBUS INPUT OPENDRAIN + +# PWM outputs +PC6 TIM8_CH1 TIM8 PWM(1) GPIO(50) BIDIR +PC7 TIM8_CH2 TIM8 PWM(2) GPIO(51) +PC8 TIM8_CH3 TIM8 PWM(3) GPIO(52) +PC9 TIM8_CH4 TIM8 PWM(4) GPIO(53) BIDIR +PA15 TIM2_CH1 TIM2 PWM(5) GPIO(54) +PA8 TIM1_CH1 TIM1 PWM(6) GPIO(55) BIDIR +PB10 TIM2_CH3 TIM2 PWM(7) GPIO(56) +PB11 TIM2_CH4 TIM2 PWM(8) GPIO(57) + +DMA_NOSHARE TIM8* + +define HAL_STORAGE_SIZE 15360 +STORAGE_FLASH_PAGE 2 + +FLASH_RESERVE_START_KB 64 + +# IMUs +IMU Invensensev3 SPI:icm42688 ROTATION_YAW_90 + +# barometers +BARO DPS310 I2C:0:0x76 +BARO DPS310 I2C:0:0x77 +BARO BMP280 I2C:0:0x76 +BARO BMP280 I2C:0:0x77 +BARO MS5611 I2C:0:0x76 +BARO MS5611 I2C:0:0x77 + +# compass +define ALLOW_ARM_NO_COMPASS +define AP_COMPASS_PROBING_ENABLED 1 +define HAL_I2C_INTERNAL_MASK 0 + +# SPI devices +# SPIDEV mpu6000 SPI1 DEVID1 MPU6000_CS MODE3 1*MHZ 8*MHZ +SPIDEV icm42688 SPI1 DEVID1 MPU6000_CS MODE3 2*MHZ 16*MHZ + + +SPIDEV osd SPI2 DEVID1 MAX7456_CS MODE0 10*MHZ 10*MHZ +SPIDEV dataflash SPI3 DEVID1 FLASH_CS MODE3 32*MHZ 32*MHZ + +# logging +define HAL_LOGGING_DATAFLASH_ENABLED 1 + +# OSD +define OSD_ENABLED 1 +define HAL_OSD_TYPE_DEFAULT 1 +ROMFS_WILDCARD libraries/AP_OSD/fonts/font*.bin + +# minimal drivers +include ../include/minimize_fpv_osd.inc +include ../include/no_bootloader_DFU.inc +undef AP_BATTERY_SYNTHETIC_CURRENT_ENABLED +define AP_BATTERY_SYNTHETIC_CURRENT_ENABLED 0 From 5e3cb817a4966c059e35a86c46eef62b03027742 Mon Sep 17 00:00:00 2001 From: alploskov Date: Wed, 29 Oct 2025 20:25:08 +0300 Subject: [PATCH 2/2] bootloaders: add Aocoda-RC-F405 flight controller --- Tools/bootloaders/Aocoda-RC-F405_bl.bin | Bin 0 -> 13776 bytes Tools/bootloaders/Aocoda-RC-F405_bl.hex | 863 ++++++++++++++++++++++++ 2 files changed, 863 insertions(+) create mode 100755 Tools/bootloaders/Aocoda-RC-F405_bl.bin create mode 100644 Tools/bootloaders/Aocoda-RC-F405_bl.hex diff --git a/Tools/bootloaders/Aocoda-RC-F405_bl.bin b/Tools/bootloaders/Aocoda-RC-F405_bl.bin new file mode 100755 index 0000000000000000000000000000000000000000..ce220f5b125e1ce5cb70a6c4509ea45c349e70e7 GIT binary patch literal 13776 zcmd6Ndwd(k)#%Lb%34W&$d*ZL*-7+>!HJTf*bXt65?NB#4<*>dP!b2)wH09H;6&xo zn(}>Lln0PUTMSOAiJ?tnTEe4AY*32{Mj;7>7AR7Jsgpos8j5fX?JAa|^-FutND74B ze&4UZ`^UXkzu#zPXU?2CbIzGFXU+^tLxxWsrBlA5ANT=^?wR;Malnr8vZ-l zjaU8uM;kSSL?p$-_xyHgwQrQ&ehvJq;QyK$mbYC%=v_!RUM&0GpDrNG@`2I1M+2i9 zA0;hEE{M>w{ibiW)QJdv@^`KJ#*5dd`lK0rqq*BjFDzPRN}M0B6K}E3sVS&^%zk~K zQerd{;aN3#mwoA>t-!U%ena3UXthIe9=yyzFA@lwpWdZ zk!Y8)SLA%74vQCGN1(^Z1PLLQ{Spm9ZXk8-OAt%yZK*W05E+I**Dp^ChsC;uUut*0 zA*Bb82~TtVUubvse=a_X%v(pZw-d&i-(64ODo z8%(lMz5kTN)+6!F$(L$%ZQXsn)!0b$+1@0_ll)#faiI3aulRjsir-Y1uID)ywMWnI zuce;S0Z(TKkXh$_rWV$VCNI#yzb7$=zQdj7FwA%55qxk$F?rx9_;`DuuK7Si{id?{I!h#g@On*qrK=}}02NTmI(R9>n= z>_e%34?1$$U4(xYjfU&QLe>VFUNXT(7*>vT z#$Smn$QldbE|}+pGB(FC*^4`XKWZedo?O&}yJ%5EYb4mpWX2y4yd)hU{{_ZtMa39Y_*9^o0%n};cHx|XqLCsb(p)Izkz!ZXjm4# z``{%iHbw6|NJhOkUIG++fBaAcvGT>+4(0)0Hbqw-1gr*jL_v4hmtDN+;45RkP0L~{ z4;H!Tj#rjzK2CCX?KmoyFWL{%U3e)iVT~Am8!%2ylbJ1xUUP8H!tB8}BL>R8T>V0k zNTcF_oy)DEAJ21w4o%Q|va4m_(uRq;^ZV({8oJ}{(MKpUi`I!Wz_2|?cPU1;D(b?w z!J7Q%^(??X%0pTQ={8um2ojl3|1=p}I)KEzK;5$F=mB)qD+wMQw&$Iib9MHhx(k

f^%Ua-iaxaYg%uu#J;rUDFw1WL{@f>{oOk zF)E?rP0_awkkKAajP}L>MJE#L$A>S2`XmAMasuk!1k`~9)XMP>!=$GtQTGhcdE5AV zi5fmp({(`cTrNoD)^WOBj(umEep0a?iN~dPKO=J5Cn;yk7k3;u3^IE70FjY$M4gb) zro>1$Byc=%0A{DW)%oi3Wzn7k^)Q#9B*)69)e%M=4HMbPv3Uu|bufN9@Tn$9xS|QN zCiQb;vAcjiIS+iTPd6O+nn%qN(Sc3TvIJG5 zQ@(^oEIdFNHGtuE3HBB%5-l>}+ZW>;Q24v?>$%|H(zw;1krg%bv%}o>&z5oze@0}y z_hF2@{w!BP8!kQ5i!JF~_F($Tc>=NZnJxP!=@QJDxMJ>5)iyg5Qi3(td$GaWUl*MK z8z9AzK?-Zh9&jZx>;_#@`jMI9urVW|L_e04Ryh`w4LwgwN|fBA>O|QJI~!7SEbL%% z>2>#>O*sjh0^U? z?d&NmzCUge7$+`$dCa%W!e2P)1)Kf^&>}#>;(f282;$M0&x!{nvI)=r%#k;p?~9bzIho z+;P0|#vV$->o11!b##QKzX)x%YdGq}0uxvei@H`ZcgFSuAjMAmw!jl@P`4gmPemAN zG_+bzct*y05p<#x5>-qEC|6w+2(Fsu(w|e`q5#hgYVvU{AOG_9)|rFY5lldJC2uC z^gK3>Y){$gkiG{m#@9u|dQxNP)NA{-+*Fw6C@!ea8OH@^-bBb-MLB7%!%hWZCIu5= zZ`HzK$uVbTF85Puu0hFd=T;p)D|y?WdI`R*mOirLs=2G1<=8nHYS57gOYO542Ta_D zy_MYKNHO9=a_k^!vp!QW+j+5O2L1Hwcvvsa3iZFntt{2UWmfv}h^1Dq3g86TiHg8=q!oI0fK&xQ5#=<5ihx=LYcJPo`hRW%D1NA7AE0J2;5arCTmXX4}L`v!_5p~peZ-B=7Ciy znleKKgE&ob)jfo!x~T8orUwi{|L0m8_|JVrmu&0h*cre_=D5k9uHy6w!YA3m<7~;^(&K^NG>Y+!A22dBt9^;O}e?Bj7q+VwL#*>*UDkdU?amZU`q>S zWH$c*psZxB<*?RJ5uv_un)E9A0T$=Q4YLRq4A>R2fg@Pt*s4IgwpmeNCX?H0Gvbkt3+Bi1Mzba&}Dk z6^ddw>pUM{-GiSarO5O*wZ<>ehpa%e=tm=)>4y&e+{17gT)ZdgKQki_DXp_up!tRP zq_EagAf&;33VLum7Ee#(PWm}4zMYUe-8B#P1tk7hN}gsEhs6F#q0y5gp!s9Lf}OZR zXN!cGh?6=WRxK{~*Gop*N2yVOqPaR@6_FZ!M(Fa~E-de1jC`IP^Tvs^b3xnRnKFP^ z@@hPZy}X~u4vX_&!DiZv%twZC>9MA*&2;mzW=Ava_Er%YB3+D+p~7 zC=usu;gRXcFk{-%gvAwo;>&=CsoL?WfQz2-{Mhy_$MVf)(D8k|n-^ch;$5((C1I2a zm~{yl#W!F+0T{2JGNU4fqrI>;fNJKJH`hJX{rM}&un>vwKED0hbseg7dnLjy6=+O0~L2YMMnt2=a_4bo8D*iP1vQ%sR z>-s(R?SXUd-Q!N{-_|2booJ)U`OIpa*~5M!9f}{5}Bb_=~H1Q zQb%{YG2k_~F&1qosl$Xr$Kyn6X`@@%Ce_s&L5`Xp!gDe{viv0owN?f&5zNT)VUSAT zJ^}PqTW6)wViq=V>H#dOC0xt|DezQt4_aJ%!WLI2L}()NXksP^X2KpMeRR;{rJz2| zz){evf8sX~NjWs}{8vz82QESF4Hl%Jo|xDJP&+1m7S8=j#ujcqM>JNBwI*gT{Mqe2 zSA5m_wFZ1AKK+^ItNO2dt&5)vqreo{`6wg_Qh7>mk>!S9TE*$!todbwS(cK)v!B!A z(#4BeQ_14gZ|TxE*B=6XeA=FS;+Rmd(?2Ez3U_p?4)CtRM-DMuR?xz!Y6VyyH;)s2IVB^A(U9+NkMH*=VV{y? z@5|$1((m>eh-Ki6a7JhcTh(db4PG+Y7fD;WU*jqiJ{FP`V3Xw zWB(F$?BDiKj43CV%`oU+C`#)#FQ@9CyC(3n3=xoX|$gvdx(w@`_ zIW`JytRJW3#zOneDQn91r$L`16e{nh1v7se{}4z$Lym^Eep+}+*k?~4yiM52Yxotskzd0Ure>wUL}YGC1{>d_ESRn84ze38vszc6#vs!bK3_84ar!F{cvy zs{xDezUqZNOY-NsGPqMsbVQ3QdG-8!&lVmqnJ{0?=QZum%Z2^OJ)yn|i?>ZU3cBrS zT-wS1C@cp2cTQZzE#WSN)mIaok_`jSeXmL&L&7u3p9Yj*v2r4-R>w6++D*T(r-kOj zsn!bmAOWY3211_0f>XaBzc{df>xR?kJm5-~Y~mJkbafKuzY@6i13vA`;9Z!J8REPy z2k_^8kcHNtzryV41phxsqM8C(AA1C~a}W3fbb>?OP1=4l2fn|gy}AMX2#Pm(_Q3gy zc+BMd+aYWgG|mpt!Y{{7o=-fF13mlfpPtHwv#!>r(#x@iKyp4153M>Yz2;*hTIGTp z2PG}|2`9$~r9#{D0$l*{`oUc108jy5rRr^{CA7RLp>}|@z62`*{I~HPu(}6^>BYsc zn(Q`b+QJ}}@>yST!0)&T&H3e&z#OR6cCAAaueO`Ky zp2r07JY{trtZ#1>Jzp`Xs75140gkB#Sg1pRk6>LIz#ncW=P&=BLkf=N@N>CfH;zhp zKb##UN8wuZ<}fNlCbO3|yS=~f#V=50S}xT46FU>37(A$lvxE-LtBgbyG7?V5C1RLO z#qH^8IaZU38nd8B3*I((q|Z;_&dgeJI{DQ^22k|w zcybR&#&42xQ$qa{;}^ooFGBZk#z(?d;LFXB2;JrW^p)u=GHT|7U(F&pc9*P({E=cJ zTBNFxW4x>w`{O-KBoE>s$rH-0pl8AP$Uyk31sr-vMUcpfW??1CF(m!I7retVx=qsu zQI-A@kbXS&37o%2L)dT;WJ+{Y!KFj(dD&9)`(9#!&&q6%@|ugi#Wmz>5WckVq~nIv z-PA6)y(rkO^C_2PmVF#%O*IL~pUItlS+0GB`E4o{Rq}`1DTyg0GRNTQG%P3IbfFl^ zD`S@&3xf`<$4dg?snmRRWw75s(*97MQwWLNx>2TA~XZ2uy-&m!<_=$|o|z9PNG-1cB!`pQf$-3)8I`4)+Jkdqh-oVOs>aGmpF z2!l^}lLVVqKQc^(c^KOYX)eqKyC4z_D~XiTVI^sb$w>mA0!hP8`zJXK+UHvHoJaMV zK5U4Fa|BowA*KRk8X$d=@J7(;Hd&7O#QIcmGt(q!>eI4n(Yqq#mUagQp;bTTdc+&&xx2su}lTY&dx$ydir$~AUdJ-Q_eKkiQabDbG7}>Lexv-LvCY-dZU1^z8KlETvmVK z#<`60gTjr@D7vrku0-xEyh{x+THy7)W}b4gDJ<3m7MR~!hh(TvU?DVlk&WO|`mqT^ z>>Ktx8P4*FyGk8sfE>FZ@3n)cnrOwl!LO4^Y>C)r8hkE2ct0nk`-=6vw`v{HWh>Er zITn#Ah>ji^wZZ&IJ%PWJh;3K9G}W5gcDv@J#&xi@ras64UgR9s`V}h-U|B+P zow(QGzJqdg-vQbg5P*(0&`+ML8f(LwD%7s)Yxcbzt?k3`&yPLWN2k37%?*$K#=nkQs z=%Xzc*=PubqU)_kSV)rJ*{a|WoE7ER1M+jNa4QY5jYk1rSvlB~I{|Mo*^ikKM-DFi zh5e|6JdoBOl~@%d&4m*hp`~@?4tKNGtZSO#nIUS^CPRde8zw%08JeSUH<@WS*a4f_ zA!_OFCKb$DTMks0t6d}D4;^v9cLhs0QUN6ohUTTcr!gfx*(yLUEaQH)gT(m5ZOHL-cT?tG;dW`vJP z+5(s(hCPq&4E&bC6ZGg~o}UCtZ%m8$zMVFPI5h9N;H^8E$ZA}JmpV4q4@iZ18poTU zF_t_8x7FJG1`ocfY4)?Wu9tK>AK%r*;`!SH4UR$SHbZBg{XFf!5gVm|806d1ZOF(q zB;@tSI6JZfkyEJS{I-VbvUPa2W6@23yL=A8-9{qSijkU`f0j^zF^VeRf}D(OJWta{ zATF?shMPfJ4f{zkX9Q{OivzS4?lP`5N0H+QcgV5t zLVS1iVn=HYUb|WsMK&e~|8vp<;L|16Y4!im27JZu2>C48XO{OfH_q_OAbi8!XYvakaUF=)-3oFm2+2aXiXcj z=@{;$#6Ae?`oVIgdf-FQseEPHfMR4DZRE}f#oSt) z^E+_r9t|2f3eE&#WnNWkjR9Z0z!yjB-JUCj&-hyW?ZbMAh$F*MNvoOJ8vuJ%Zxc~H=)VeD$h^U>F*cYt*tIeio2UsK!H#26S)R8ac)kdD zZZPl$VbRWQ`Gn&aqqg(MZ3Ktj`TH=rcd59XPdk85JMu)FRd?PtQy=^gR^b`t4B&~6 zJ|(z3Ngh~%2e3|5dj6Qiv?n=X1pi5nJtmWrLZ0Z$Dulje<@m~9+e+;-f`r?xttX}Q zBOgh*23+=OFHkZ}}A`2LRf9J}vD{sSIuf;6^6FNlSv0md(3>lP7_b zr3xwK_2^ zYeXn6I!&N8 zJ>ReHtQw{6``~xfRRbSLH@Baa-tIwHfu&NbMye8PfCdW+QP8WiVa=clWXU+)yaQf) zjGDkgxHmH+k3jVN48&!xvQTmXMVmkn*Z^1E0{;0Pzu=@qJJtFEEzH-B2Po z`q#y;f)Wj-CGq>|O=I;3hm=X^H{!p95`lg#-V7xI{kynXxoPZ%g9N@Oer?#@dRF>$ zFWmW%S*p5QyM*sfJTlp}eA&hSByToGTsqjz^KsN>>;YQmz=}cnXkNi-l2?lDm9XFE zC+jB9tl{`pIhHqN+@YG#j1rq^29E3^_X)s}HC#P#1TTFz{FssrfQ9ub=XVC+esUKT z!Bl6U?tEVHwlGx+T%gGOR|zMiJkVy=@X;_T{N+e`Ix=pzs|lAFh>d&p2o#*=8{xl^ zZwY6MG`ztfSbwy9djM{Fcfl&f+Y?wx?2_oDqm>@1%nlJt7DYOENmk*l`l{~QRNb|g z)m4C1|KH$JbpVGVyn`NVa;WehdbdhQhfVM%i{4{%sJalHYC9(RjKoK?`st_eJxnPx zNyA-8S_9KXyOB}R^#-%jguOBzi^2X8 z9A+RIk3&ZVbzj~rpaFIc+LO;8g>%7C{-{Ui+~T2|I_z@;juyI!cyz(n$vsR4cTTA2 zY4+%5E$w?Eu+1NhbN$O^c-c^JNn;SAc{^4AtP*{$tvhI{Cf#J3qp zMa2FA_`xpLFr_MBY=WLY0Y#?=Rtn#I6KJuvw3OFs#mb zc0{3BrSDi?9O&Q^X<+s#MP*Toajl$2y)Vqc!Ii=25B)}$G;&fha3D+ zM712{?JY!pL|$rBQc|YZK~69(k&_8dFL(>m8V8(T%ggN1 z&)V1gSCGL!%WDAM(OfRClnz|?FLdBCiNRR_WR?N(zU-9T7J=N}lC=q`5t+^M61ib` zd)VE~oczRN;FxR4JC)>Z?U!Uf1G!~z?c9?@Zfe3&bmdFjvn_RfH3^CB1&KWZwTW0B zk(ly2{r-_O<Db+JcT0uyTOh9+oPP@^`8+cOG5DUXExUS{iY|R-P{$vGmz&4|sHL}Fn81NWJU*qFb-h27+K z@Zm$N`G=Y_A;J}qh#z}=m?ayWtW*NJF4694{6;%ts6TRY5+yy0Cx9*<2= z%CSc!aw?C<)`PtxbNI)oYOA8Ac0HlG)-9B7g_qdLxEr+o0}WXdFA17|o9@b}JtY{U zLrp41m9BQ2=1)pf22~B52JblrCADA&3~JtBI{kyK@Fs!q5Ro^}^n?OD^&xF4)|ly9 zD}ZP2&J9NXuDuRM-zHoSI&kl~CY9^Vdh?yzVElM&%cQm^4bFPneuZl?OspWh-AdvE zny!ZXgAzzt@HUr>s$ZwykjU>$uPxZnkvJK4z`4ukXfW+*2E8dc-HhP%P^0@aM2E4d zv5D*&fRDrq49pNf+F5_L=cJ&qo$CFAqf43Hq#Q_khVfY2WRf3j{~U;4Z9IQ;)yDHD z67PJEjSp$hs3~dRDA-_|< zK~t+0Y*C+A%ja!GQJeSB7}_*DP#5)C^X|&Os{#BkbT7ov#fOtJh1f=^3n&I0CAD=? zTV*yx(Gs(V{4wR!z#f4_9rp0^U3-KaF`b$W!JB7s9Ov_U2xQb(LgH?Z(^CVD8%e*$ zyXLqWH?~91IdJwOxP15M`GVR8VGT1ikO%RQ$MMuae(fGUAIkagVmjYt4CU8m3;FPV zzA$9FpvcklxwSet^JLKq%S1>6Bils^XaGL~C}8JLgc|RLk?oD^8aE{JJJ)XTRzc5u zJ|S{V#cbG{ZA!FzdpVIw_PS&Yk?2t6(X2`mf3c+QicW#zxMQO^$WMlXpt}VDE{J(;U20vXHlEX#P07-^$Slfhfu@KD@#kbWy_YON@doz zOQn*pN@drqUX9?LfuR&GKPnN{HX>TP1}U|Rp%$UL;m%gaAoP96^C9;^ZiIX%S+#L`bRe8_4`|CY-Z@do`+3PA- zIg1wB;n7XQ@>MmJD~bS=BAwuOix#nOK(Zkl+6yu5Ly#`D(Mb@b$WD$0EI>z~om5{M zm-ulQQ|MFyVu$tcE*o+WBnQBB0zE3qfhdfQl&D~Gn1Z5WF496A5+lsar6|SRG=!Ck zEi?q)RSZUy8agT!n6i;nH;`=5`E8gl zNo4+mkozFF!3W`0Ym;XK@~pf24k&{}2~zYt{74S(^^?E7FhQn1QBJniqqCRVpqAhz zKhj3ZU-e7WCjXNC{_nLBk&xddeMo-&&;M(4FSTbS3Nm_v