From 3edb3159385cb842a6805301726b74926925955e Mon Sep 17 00:00:00 2001 From: ShahlaHuseynova <121937511+ShahlaHuseynova@users.noreply.github.com> Date: Wed, 12 Jun 2024 10:41:44 +0200 Subject: [PATCH] pyrecoy --- pyrecoy/.vs/ProjectSettings.json | 3 + pyrecoy/.vs/VSWorkspaceState.json | 11 + ...0062bb29-2b94-4e4b-9323-e2eb61396713.vsidx | Bin 0 -> 107 bytes ...2b9a0a9e-14bd-43a1-b3ee-98764114df6d.vsidx | Bin 0 -> 794914 bytes ...5f785a9b-4ecf-4815-9457-ede32ca8bb05.vsidx | Bin 0 -> 107 bytes ...cf3214f8-06fa-462c-9ca5-e67ee6237457.vsidx | Bin 0 -> 107 bytes ...f607662a-174d-4632-bc3f-60cd06b08d1a.vsidx | Bin 0 -> 107 bytes pyrecoy/.vs/pyrecoy/v17/.wsuo | Bin 0 -> 63488 bytes pyrecoy/.vs/pyrecoy/v17/DocumentLayout.json | 100 + pyrecoy/.vs/slnx.sqlite | Bin 0 -> 90112 bytes pyrecoy/pyrecoy/.gitignore | 6 + pyrecoy/pyrecoy/README.md | 25 + pyrecoy/pyrecoy/Untitled.ipynb | 35 + pyrecoy/pyrecoy/build/lib/pyrecoy/__init__.py | 1 + pyrecoy/pyrecoy/build/lib/pyrecoy/assets.py | 789 + pyrecoy/pyrecoy/build/lib/pyrecoy/basepath.py | 11 + .../pyrecoy/build/lib/pyrecoy/casestudy.py | 537 + pyrecoy/pyrecoy/build/lib/pyrecoy/colors.py | 43 + .../pyrecoy/build/lib/pyrecoy/converters.py | 66 + .../pyrecoy/build/lib/pyrecoy/databases.py | 69 + .../pyrecoy/build/lib/pyrecoy/decorators.py | 17 + .../pyrecoy/build/lib/pyrecoy/financial.py | 667 + .../pyrecoy/build/lib/pyrecoy/forecasts.py | 343 + .../pyrecoy/build/lib/pyrecoy/framework.py | 60 + .../build/lib/pyrecoy/intelligent_baseline.py | 226 + pyrecoy/pyrecoy/build/lib/pyrecoy/plotting.py | 143 + .../lib/pyrecoy/prices-LAPTOP-2MK43FDK.py | 765 + pyrecoy/pyrecoy/build/lib/pyrecoy/prices.py | 792 + pyrecoy/pyrecoy/build/lib/pyrecoy/reports.py | 156 + .../pyrecoy/build/lib/pyrecoy/rop_assets.py | 34 + .../pyrecoy/build/lib/pyrecoy/rop_prices.py | 92 + .../pyrecoy/build/lib/pyrecoy/sensitivity.py | 225 + pyrecoy/pyrecoy/build/lib/pyrecoy/styling.py | 47 + pyrecoy/pyrecoy/dist/pyrecoy-0.1-py3.9.egg | Bin 0 -> 95081 bytes pyrecoy/pyrecoy/notepad.py | 11 + pyrecoy/pyrecoy/pyrecoy/__init__.py | 1 + pyrecoy/pyrecoy/pyrecoy/assets.py | 789 + pyrecoy/pyrecoy/pyrecoy/basepath.py | 11 + pyrecoy/pyrecoy/pyrecoy/casestudy.py | 548 + pyrecoy/pyrecoy/pyrecoy/colors.py | 43 + pyrecoy/pyrecoy/pyrecoy/converters.py | 66 + .../pyrecoy/data/grid_tariffs/enexis_2020.csv | 6 + .../pyrecoy/data/grid_tariffs/enexis_2021.csv | 6 + .../pyrecoy/data/grid_tariffs/enexis_2022.csv | 6 + .../pyrecoy/data/grid_tariffs/enexis_2023.csv | 6 + .../pyrecoy/data/grid_tariffs/enexis_2024.csv | 6 + .../data/grid_tariffs/liander_2020.csv | 7 + .../data/grid_tariffs/liander_2021.csv | 7 + .../data/grid_tariffs/liander_2022.csv | 7 + .../data/grid_tariffs/liander_2023.csv | 7 + .../data/grid_tariffs/liander_2024.csv | 7 + .../pyrecoy/data/grid_tariffs/stedin_2020.csv | 3 + .../pyrecoy/data/grid_tariffs/stedin_2021.csv | 5 + .../pyrecoy/data/grid_tariffs/stedin_2022.csv | 5 + .../pyrecoy/data/grid_tariffs/stedin_2023.csv | 5 + .../pyrecoy/data/grid_tariffs/stedin_2024.csv | 5 + .../pyrecoy/data/grid_tariffs/tennet_2020.csv | 3 + .../pyrecoy/data/grid_tariffs/tennet_2021.csv | 3 + .../pyrecoy/data/grid_tariffs/tennet_2022.csv | 3 + .../pyrecoy/data/grid_tariffs/tennet_2023.csv | 3 + .../pyrecoy/data/grid_tariffs/tennet_2024.csv | 3 + .../data/tax_tariffs/electricity_eb.json | 72 + .../data/tax_tariffs/electricity_ode.json | 67 + .../pyrecoy/data/tax_tariffs/gas_eb.json | 86 + .../data/tax_tariffs/gas_horticulture_eb.json | 1 + .../tax_tariffs/gas_horticulture_ode.json | 1 + .../pyrecoy/data/tax_tariffs/gas_ode.json | 54 + .../pyrecoy/pyrecoy/database/Models/base.py | 25 + pyrecoy/pyrecoy/pyrecoy/databases.py | 69 + pyrecoy/pyrecoy/pyrecoy/decorators.py | 17 + pyrecoy/pyrecoy/pyrecoy/financial.py | 678 + pyrecoy/pyrecoy/pyrecoy/forecasts.py | 293 + pyrecoy/pyrecoy/pyrecoy/framework.py | 61 + .../pyrecoy/pyrecoy/intelligent_baseline.py | 226 + pyrecoy/pyrecoy/pyrecoy/plotting.py | 143 + .../pyrecoy/pyrecoy/prices-LAPTOP-2MK43FDK.py | 765 + pyrecoy/pyrecoy/pyrecoy/prices.py | 752 + pyrecoy/pyrecoy/pyrecoy/reports.py | 156 + pyrecoy/pyrecoy/pyrecoy/rop_assets.py | 34 + pyrecoy/pyrecoy/pyrecoy/rop_prices.py | 92 + pyrecoy/pyrecoy/pyrecoy/sensitivity.py | 225 + pyrecoy/pyrecoy/pyrecoy/styling.py | 47 + pyrecoy/pyrecoy/setup.py | 29 + .../pyrecoy/templates/pyrecoy_template.ipynb | 16965 ++++++++++++++++ pyrecoy/pyrecoy/tests/__init__.py | 0 pyrecoy/pyrecoy/tests/test_assets.py | 324 + pyrecoy/pyrecoy/tests/test_financial.py | 61 + 87 files changed, 28078 insertions(+) create mode 100644 pyrecoy/.vs/ProjectSettings.json create mode 100644 pyrecoy/.vs/VSWorkspaceState.json create mode 100644 pyrecoy/.vs/pyrecoy/FileContentIndex/0062bb29-2b94-4e4b-9323-e2eb61396713.vsidx create mode 100644 pyrecoy/.vs/pyrecoy/FileContentIndex/2b9a0a9e-14bd-43a1-b3ee-98764114df6d.vsidx create mode 100644 pyrecoy/.vs/pyrecoy/FileContentIndex/5f785a9b-4ecf-4815-9457-ede32ca8bb05.vsidx create mode 100644 pyrecoy/.vs/pyrecoy/FileContentIndex/cf3214f8-06fa-462c-9ca5-e67ee6237457.vsidx create mode 100644 pyrecoy/.vs/pyrecoy/FileContentIndex/f607662a-174d-4632-bc3f-60cd06b08d1a.vsidx create mode 100644 pyrecoy/.vs/pyrecoy/v17/.wsuo create mode 100644 pyrecoy/.vs/pyrecoy/v17/DocumentLayout.json create mode 100644 pyrecoy/.vs/slnx.sqlite create mode 100644 pyrecoy/pyrecoy/.gitignore create mode 100644 pyrecoy/pyrecoy/README.md create mode 100644 pyrecoy/pyrecoy/Untitled.ipynb create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/__init__.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/assets.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/basepath.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/casestudy.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/colors.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/converters.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/databases.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/decorators.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/financial.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/forecasts.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/framework.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/intelligent_baseline.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/plotting.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/prices-LAPTOP-2MK43FDK.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/prices.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/reports.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/rop_assets.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/rop_prices.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/sensitivity.py create mode 100644 pyrecoy/pyrecoy/build/lib/pyrecoy/styling.py create mode 100644 pyrecoy/pyrecoy/dist/pyrecoy-0.1-py3.9.egg create mode 100644 pyrecoy/pyrecoy/notepad.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/__init__.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/assets.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/basepath.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/casestudy.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/colors.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/converters.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2020.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2021.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2022.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2023.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2024.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2020.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2021.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2022.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2023.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2024.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2020.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2021.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2022.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2023.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2024.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2020.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2021.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2022.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2023.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2024.csv create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/electricity_eb.json create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/electricity_ode.json create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_eb.json create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_horticulture_eb.json create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_horticulture_ode.json create mode 100644 pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_ode.json create mode 100644 pyrecoy/pyrecoy/pyrecoy/database/Models/base.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/databases.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/decorators.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/financial.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/forecasts.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/framework.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/intelligent_baseline.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/plotting.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/prices-LAPTOP-2MK43FDK.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/prices.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/reports.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/rop_assets.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/rop_prices.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/sensitivity.py create mode 100644 pyrecoy/pyrecoy/pyrecoy/styling.py create mode 100644 pyrecoy/pyrecoy/setup.py create mode 100644 pyrecoy/pyrecoy/templates/pyrecoy_template.ipynb create mode 100644 pyrecoy/pyrecoy/tests/__init__.py create mode 100644 pyrecoy/pyrecoy/tests/test_assets.py create mode 100644 pyrecoy/pyrecoy/tests/test_financial.py diff --git a/pyrecoy/.vs/ProjectSettings.json b/pyrecoy/.vs/ProjectSettings.json new file mode 100644 index 0000000..f8b4888 --- /dev/null +++ b/pyrecoy/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": null +} \ No newline at end of file diff --git a/pyrecoy/.vs/VSWorkspaceState.json b/pyrecoy/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..023fff2 --- /dev/null +++ b/pyrecoy/.vs/VSWorkspaceState.json @@ -0,0 +1,11 @@ +{ + "ExpandedNodes": [ + "", + "\\pyrecoy", + "\\pyrecoy\\pyrecoy", + "\\pyrecoy\\pyrecoy\\data", + "\\pyrecoy\\pyrecoy\\data\\tax_tariffs" + ], + "SelectedNode": "\\pyrecoy\\pyrecoy\\prices.py", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/pyrecoy/.vs/pyrecoy/FileContentIndex/0062bb29-2b94-4e4b-9323-e2eb61396713.vsidx b/pyrecoy/.vs/pyrecoy/FileContentIndex/0062bb29-2b94-4e4b-9323-e2eb61396713.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..70aef67a00f5a48bfb0d87044cf8f151e2685b5d GIT binary patch literal 107 wcmZ>EaTnxZU~p%E02V0C38Z0cW+XOHDO{Wlsuo0n)bd05(ok9*N*hCI0FV0t;Q#;t literal 0 HcmV?d00001 diff --git a/pyrecoy/.vs/pyrecoy/FileContentIndex/2b9a0a9e-14bd-43a1-b3ee-98764114df6d.vsidx b/pyrecoy/.vs/pyrecoy/FileContentIndex/2b9a0a9e-14bd-43a1-b3ee-98764114df6d.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..1d8edeb29978055aeee22a2c2307863179fc0730 GIT binary patch literal 794914 zcmdSCdz4*Ab?3iN-`nkbrS7ZlmQkxESvp6SY{`#S8@XH3ZApD4-PUx#fPWdB@er-Z zvMt*pLNb;xHV}M{Ejz+IB3MiUNg(HjM_5cUF#$|~43>?7z`%k1@b zU>nl&4$F2hhb|2h%;Na`7 z-Lw0^&YN~$v;S7dF1}{hf!!C+M7$7mHkw5e&%g%^$Ud>fAHX*eb<-E zR-Qut&(mi{ecpJ}o@;g=xcIUym%s8AmtXwim%a4TwcFb-oh|jPvf_+*?_SQ?a+T{+ z-1&=ayECbrzv$hcDdjw{d*1IxNZkZ#wUcXrDWG?%B8J;Le>V>+%2PuTIDM=-NF84u+-C#iJvaTzuoL zYezPW?7sf`6UUf9)!BwxFlCoTpl4&X)7O zr9XT9+y2x4>-Br6&r_{3&zN$aVwE{t&hIT;eH!{vQJ<$+WzLrKkv}}0t?0vf3fXzxRW?_wD1*?|Jk4t><5KMzzn`avtA4&)jkz-#*XWavtA4 z&wz3s+;z*W`MG!ZH3!+UWt(Z|?yE;$ePI7SH$h+YSEqBmY5nMA<;29FE$A6m&g*v_ zIKCc(LH~shJaZb?@6W4GE$0nvEbqDIb$buK?xx*Eq5t#f&V>)Y`?QXq<@f%)a)y_G z@0NLepF6Y48HyHOx&42d-}@;}UuTPYde_CLI(?lj=jpA_Q=PufmUGJ`qo;9xzwQ*L zue0U6_yec2oToZ{oh|3VnyUve7X`>9S}&#ZF3@DAN<8CClJ1<#$v zdGl1Kud`)6XZppb@x7nw^z}?C=Px>aoh|31?>(LMd8*UbGp3xUIDMThXL9k{)7U;w zb^1D6&eL-q_sdgT+Ao_LdCj%61v!PZ`wvdXc`^5gUw7lbX4ouB|689t9q;|%?$_M7 zch|w)2g2d@&VY>Ux$)M0R~N-Agws_{Zqn_boCkm5<&~n8B3rx1PD4M^63&$KUui0z z&T{_id;96C&nxyF+;ed6?rTrh8cQ#HMhy2u{^0tGA?ml~p0@P2<;t@p?v}IXNWCuK zuE?>P{5+Cl^W^h=@(+XZ?S>p%EN2hNu}dXhC-rf8a-)2HQoh}ke;AfyV{+Ss9NQ+f zwjAr0YDNBfu~diUuPbsxO(z{V^Z%S=K z`fIXkOxhKx)#TbpuIZDd4Ou!Q*ED76u++w6YC@LOmqq9ISLlVn`Jw@G?7%X^#h#Dsjm zSC(#&rENLVCtW;3)1IQOwSD`r*5|;G40LIZX-)2E%iJ+pLT#AN_brf7Q}wd%kw)V-l8uIXBsjZVE8|0R8+1iwEO~_lU%L9_tcIMmUZPFXwOP`poYj`)bvfK8A8W|Rn)0y;eU-}_vb-tF zYm$yxA=^@EORFwXP3H8;%?-J^DL0SFUW(Zt(tU= zNq?Wbq9JRV@`?$0`JmQkrJ=1WZc1fBdZzWw^1jw=Q~x>=j!3*lT0QcCCGvr~e6%84 zBQ1G6pilSZhJ1NQ(sB9dCW$x8!lrzAO70n!trPNlFP7*MiAJTiR#nkF2IoqvBGtOK ztF%w@hJ2K?>!mfWZzLa<>V#a;mVaqWyHD6Hl=Dgwnn77Mrsi1l2Xs(TDG)DT1%u=s0zX-;nbwoCvUcDeDj#J zs75kv%ip%;Ppv$c67(MDeXTC>xYT+iU7``{Ea&$s6^t9z^G*l#-C-sd|AC?IH z6rkL-=gRUv`J;wBxn5uEA5F;49=U&sKB;yJ=eMQamisD_MsjpWjt*-FjOR&hqtwW{ zEj`c%wf#KWkVnx!sde}$$tUFN3>tmXGbr_j^w`i*-!4xyrDw|e)P#;6(+!z!%JhUB zY0GoHIut}h5^c~b{pL1F=jp)G%iHgg|F5pS>8iFw3+0Mlxw0a+)Z|rzQr#d|PO8HD zhUJzq`OdV=A@@k09Fiy7@_!bps()cHtZT!&d_da$+9RsGsX>Vv@;gIP-6YYt^lz5- zq(s~0*tE7E?e#V)&Y6(kACz=bYxuVs@|#WhtqGYoN2HdD(m_#Fn@9yzu|j#c!1oi|UW`{eS5ymq5j z$mK@M#^jO-NosN^k{v^`V_MtT&&Om%(FUkAhTL9RRgt@Gw6D&SPx3??WYtFbq$#<3 zOrGSy$K-Y^=i7YL-LCDNV*If+mFk#86&<=;ebV2M{%!ga`^jrq`p0yPic2|ujvTwC zK1beJm(LDJ)F;PmW~r}}caF<{-mD`GZ=cHVowkv-=oAw=YQ>9H+nXBl=BB)9LY5Ec z_!iSbtmiU=EM!osOV#@I;)X09mkQ&Ob?U_v@?z!-#-Bd9sv%b~WiU`QwN*UJh%_Nb z>vC>I35>4Qahcva^B!Xc9GjcE84MW)r)|C%lU2M&Cag$~49O8**_b?7kssFNNouJf zhnSwG^bx)@EI%BRH%`bQtHWz;UVDE--f#2T`BKZNGeMo-5khNaNsAx)#l8QFdCAErAK~3lnJ?{W91m>l?Cuy<9Xd=Wde0&2nc`)(>mVFh$IrF>rPNiEkI@FU%cWB~XMKKH=hpZ3${a@QntXSI4u;fHIwoiN zcs@@q+bEZ9)3HmNgpUT+_vuqwy;Q9AdU_MH?dV(?tmyErQ$KU}5*b}DgEl@aZ_7fm zgGSq?N%u-^gEonj3Z#cJdfQ+{7Ki7_4%dL0w^4RrLNJU^Xk9&HgWl!aq~8X;f0>Yc zt{QXo!9$D6}1zsLW7v}B~SvDkHo20f`O)vU_n%1;fpX7eXmml)Xw zwb1CiJbTx$Jhe^BIXa|6(5R0g&@A>?mweQbh4RsEnPZdGA)BP;*z|M=>(?f`qi!;_ zWv5MZ*<77jE@{Xm>$SID)s#zU7Ufe1!L*&82V@fynTi~G}yZ4-3v6~Q`8UD z(w5KCn{XAmzb4Pkm(R51GuSG_a{rh-Hc$FDs;W;c&`$Rdk4Ep{iE1){wlO)3t%5az zHiG0>m){+bf&MU}ZqkZ9Z?g>0_ig4?8_9;^$ILX+dBl1s5Bn5$OSg7*dK@F?Gc|ed zfEx4NjE#$>Mfulj1ExE756d$)c6DJNVixww$_=uzwBld^b#rOOfsudDg#33`MRKOm zF>M=+FtlNoNGpeBrOh&Ie4>_1~xSb^lgv15_r~8ZSuI+KV_=omp}YR3%!Z zZGa`GFBKnu{@T;({3lgu*$R}jz5<1L+zK@4=M7?h`+`&nK{E)s#9=*Kq>me z>QR=}WwpmIu2sqLi)&P|GMde}|_dAA%TpDsreMZ=ueI z<9n$SlJmk<(bwF_!3Nf~i9HLm5|cR7%2jpQ&RZClAKI%)nvxJirn>qhqY|2uv1oNwyaik4 ze8{XOj9#WB9`M0X11y3bq3*@@yFEoC*KBj z*p`dJ$d9e-^*O5qV+I?hPrf@Y8=LZ7a;J*=>(|6!o*>9^5$7be;er!d@ zF$n!FSR-fgrBkX^HL{u?p*c~8E9-K17OgQ8N%0eKIbZ?^V7w;^w3^Nr;{ zCf{axPgBmFkRe-WAHfPTd$=`EKG7$iZ^-u-OP#&Gjq-`6b_ZXif5~4l%M+F%tU6g~ zGMh6^Gb3APNm&h{hZWG2JZJ@=o8RshIOaFDHkiBMGTykn%)>1r_F+;|4vic^jH&W-}vR zTjsa*ahRuQY}Da)%V?&{(Bz={q9>|d$1Gb~rq?^u{)Cu1a&%aqKezxZSFj8pQ<^c`N`lnhMin&m2t zZGV-K4$JG=B4*Exo#83%y!T^E&}Qm#6ZH?Zz9ywy$gd%4mLU-ctBTXD*!_hg1*zFSX?_ttH18 z|I`l^G9^c*bihCCqY8bN0#no}9d9Wls#wFagHfTj{dpN)?2(t6LEgV^wp8r*(ki~| z4clfm5dQ(k0VJSgjw0HPAYn|N1Cgiw0#NvX!#^Qpm z!N#C1Jo{|(Q?q6rVN>ck-YhrhT+h@)<@|`@k?CW;Zfmo#Tx;p(HfG@$tnp}5w=;;j z%$4J^!dCs-uNi^8Uo(#|-D7z8EHJKX7T)Gxvs&LE5o_}?-RNWF#PDG4w!SWB^~>1< zaz&p!){s{$(bXJ#4!^lc&fY9nH07}gc|X-&Y=qj7$VTX4Urj8Q!>pdnv}-h^(Ub;L z0L_W537d@Ak>+s@H}t40W^1A;huL19kbyoquOa6({|yra z?-#R;xw|c|@d1Q`BuZdzKwwQ4+G#t;=F5XWLLclRBu5f>Wwq?fZ9duw_Hm zSsQe@%}{d|XKJ>hWcr}NP?=0^ok*VRlU_EBhvd1Y^fKJBLieeYC_omutZLcKsOv5( z1AD7a<~C$58ye$sm|3H#t4rqn1vIL*j)&Cqf^K zQ`jbR#t6ykIFg5aO)(@7u{!36&~2MY&rmozp>ICktM+q)In=g9?qK$G!-lS5qpl8C zygu5G*|bbs_p@}J)RUbz)pVQdHrsW%+4fs*8`ER5y*}jf$Ti8xk=o{nXG{-Y9%5I7 zAw80VLvoOf5f;&NrBl(j|1xh~>!o9FGZ~W$%>ut-T(-04HYLA?nS@=`uiN0uH>nA< ze6A$x)hv&Fvyp}8T(w=hSbnaTt(2Jww_oZ5a-CIj!fe}+WRui4%XRE?V$!qKX;sa7 zgeIzb*mR=zG2JlHgppG>(g$VRq|RBoFLai4vvDy;uC2>s72VzEK{Xl%HEur>8v07-i#9k8d~8Z01X~rB%%d?3TH*ur5Eb0h!0F4CuPm z*QZ;?<*D_uaFbLvtI18rp}|w7G!iyQX&x(hSv_(!d*Eh9GLqcJao7^M+KxgPPk1#9 zBLlv(>f`^EJl8Gv_sZ`rmisrz@6ngdAU{fv9@9>T6~Ww^QXw=I8?RV(G9+r&bTl?P zC`O;Wydh_wql3xICuG_hiSDG?fXT#1w;F87AQLyMJf^=1S;2(Pl7T&ZTF!jAwI#RG zc&7Bwje0n0)+t6cL${8ooE@~~5zYv(UKn*FJ)zb`?vQL{?DbP`x+h(-FbJpQD)05a zlT(q)u@JBghUM~JokrQ6n9rkeB+becwG5RElD11jr^X0L8Q5)OpC&Q8pk_~rhRrO% zMFK2}V31r+J1N^#6+I5i%dNDn$Nd+!<#*b0$DrIXDR*GYVY#vAR_Lb~ENW~LVI4{h z_j@1VP@b1EPoCv0exp3gtFg-%TprMU6~?-@JYi>xoc(D_Fd1|4Pi;i{;IRCu4N4y* zitb?BFW4KG*u1>LZH8bl=!>R{@lxnzyb+QVh99lVY%?7P;DA%ZX8OY9&0<+GH#JB* zt`8XdbihKA9@;0bY{)CwaG?)KwVzv9)MRzeA&~$bYQM z?d%3ba#^1|(vU~YqP~pvT2mge_1%B8TL%wx3)e8(N4$Bkv=&U=x%ro*X=04m0i)|gjI2p30Npu)449aY zfCG2ua&CP5Ea1cTvjRrLGZkkBSAovlLUthA3`U*ZiK|}$b1M0Ao#c} z2#(;#M#D!51o-Y?0)n_Jrm0MM~Ocq5F$VA~21&Ewj5QHFpA!MNeI1UpeKAzUG zAULU#5bMFnqFAKg4$g*uNQeekf}cAlgf!$!6s}`FIC2V&>lrp;w+sQq zkrqEIJsQC@I42N`19URJ3%LnNh|Pjp7hDOHU5Gn^(%4&zD8#NzW=-c(L?cBs~{O z&jr$h$+}t=E|qwh^u*GWD8J`i=~*c~=PS8qwQ@cmOKqt}b)75mN?Eu{x-ORLg;J&A zt(GpxtPNx7U#^6OmgHC>{VOCsSC*sXBB>JOE}3oasS(cNPl%{q+oKs^q(iy3#7VK`t5P5 zbP!70mU&C1E76Qrp>U;iEmNH}Cnr)pS6a(tbfqe+Qs8CMze-c}@?7@FEH|3^WL-nn4asN6Xzf3 zoDErabKA0r%M#lq4a>AeCNQYBC?rds?Q+hvHjnONN!XU(WqrpHxhG*|%Bs_zh_3zn z-0RYP8G zm-*R8dKInIww^c^AyaNk>Q-uxo}RB{qnmp*zFSVd=pk$0)??ISb7P@Q*(UkSOYx0* z&SEV0Zh9r%gg!_IVe^p9XSN{NJhZ*&xJP1Ydx>s4^VFA~PMHdRP2%365U?t z-l%th)6|nt-dTizF=$mxe>Wz)H+nS*?7-34YsCaH8-_rS0nOT$RpBd%jZV))%<8m z`&WBRmUqj*Vi_2fw~xvoyU_FXV2FKPJ^`TnqvRg?CTVSmd+Dg`Wr$-~7}Z0`yC^Vk zkk`a*F+g;}9F?u3dJXuYQ5`Y3FS=-hEV8RpG}n8WH2_UvO4;aTZJ1=vtfq zO%A&`+U8)QBELbK=U{?+hQsn3#bEB+{_Ofzw4869CqL?w1#Hl97}}5pYz1$WAGP$N zAiHx5Y&Uxcn`X9oyR;_%os&5BZ@G;*CV$QmgWdK0XZ!ByTXxp)EjuYDA-8<5pOBAo zoOHIn&~%GVG&C5F7-qT#J85=flfmTk3+1X|`FurwMn;?n49b7tAi&Pz|3h1D9G0K4 zKgl*Y8ANpDWVCLMTrpQTOM0#%_YKH}3_jdju&X{i-TSB$ zyX3|J&BN>U{y+M8x(lhLNqL_gQgB3jpKTpKQ<2v)wA$fFP7@lI*D}I$yV%Z#XdArx zA1~D7KVIlc|L9-AbFBvZCvYPJ%8IJsl+PK`XRXfXr zd^yO_#4R-jBC4gXrw@xFd6!QLL-MY1S;U!(oo78}HN&&e@HpvHGlK&f&hqSpg;SE4 z4md2y0=<2)fG_X(7=&{l?kTOaTS*-Ebg5NVTPQsoB}evA7+nv!rrY>4wjWos{B`%r z6LV!*ML+puAbnt-oJGGF6l(Pt4Pb*jVeN3)MmcLz3rX8sGA0W+AY-?ggO7@Qi!+g7 z`4$Hv6l1>ZZOLBBV3%h&u=x0-eB5r!aI``1u9QC^w6p07vvat*^PX^N=RGuUKE2_) zn~GNT4=3e^ys1b!L(=Kh6RvcFEVQafEAj)M@`mLHoMP1V!;1TB`Uo%L4tAe>upytY zqm8>;ddK5MP5B_#u9po>FBMH7QAPJ+{6V@cSd%*c4!|5mZ4wrsSeexYH#~k$KVZA4&w`({? z;RGR)Hx0>~-0EZ6vI|T1%~d<_#z=0i=?5B*_371!oejBSNN#3c+XufKgRUObBevC?!NK$oS}`FoEZyp31?q<#KC|$Q{?!$4 z)4B!*`Id%kIY&Roi!pn+R5>BHoBj*vQyjgWC37y-TQ1y0(gO&lGe#b(E?y!xPiVcI zAk%<3iDSOoB{N?)Y{Lxem-7bXEq(GcF8puOyY6pk%FnRG7)c_zd`MR@_Z3rBkG?XF zsJ7JQQxzGk$!0gtxNqYh_i=K{C!F@B?GM+>7VI=`;8>Y&V?rO+GgIzG-)6%FNATQt z`X3zGghMV$*b2v6=iA%);*fmNW@oi;-HzfB%$#m93SoqE31L8v*j+)6w6vnQlfXD^ zS#uME+h|9qG3(>+XE4EHx7vFbO1ORxlNRN*nAMPFT zrkFGtma*rHBU(&)-km)KpYcYR2iCf(b9DLej||1whkm1y`vcqywM*J7$K@ZnND%II zKVwbzR_+zh$LH$zbTmTlY%nqm+9Bp4E{ScFL5?HsRP>j*)fS#N3r*qy>xo-2n{ASP z5`)?L;7b@lCgd?p8u~@AbePjCa$8-#Qor*V{Y}zeS>n<2DxuizZ#?G z_K*c_V_YvVqpDt&s8=4T$fx-PhI(71!y|*q1mu}nr~rf1EQa}Qj-igbGY^p z$xD1R8oxIDngcuhXdB`zjhW>}_Ij>!3N&o2oK%IKtw4$7UAa;KlL zo6cAJhuEg-?ZfhFzQrDtxs&=O8m19uRaTJ?&yzp)zPVBUnB(|i`LG*%gVLGQ8!~DT z`h^N=X;3~q83_AxQ+#r z;Dcl)J1sX3vAJ)9*s_sgr-sAnn2Z2|9Ff+?I?u~jiyn5_U`#I>Cu8aAXL8L?tG7Oa>`9E~KFVE;#5u2@&vJ z$SjzLU|Ldz?6knAqt%|wwVPurLt=PXdo3)dH9U_*nkeRtQVfMd)=%Q z9`nzrNzNB2{%AC5|Hj{X)=@OjknE+CFAlZnbj`>vfCJ({GNaLnuJRGpS~V6RzqjD6 z+EcL})TVA#+97S9JkXE_n(_cTC*;nc5S@9D$%V8a2rid{Q3*t5*CO_TgN z4>C*~LT&@S($M7{0s6IMDKtZ{oIrDIr$XIysVG8IoVI z@^rvi0*uSmHrk-d^&mJuvsCCLEm7e39)+OeutlXd9x4)Oa0t2s%q*&i%?&9C2=L*! z0L>l2e+oK13O_Rh4am^al0cAHkR)t2<{n$zav_!#Tq#w@lqBYpoV4zc|1rpUcyN?Q zCR1tH(r^gkrv@Up>_K!QK)~fDdn_^nT?T`Sm!6igRy^=MAqa$sLj(>2VmnIUykmtP zd314_aK3b{k}gg|LSC7b1SO=3*^!M0%$B6IMO-Niu(QOKkv7Uw}n@ZAyX0VAbj%JR$qYXfDK{hw3W@#gQvKvb{gevXu_X9ti%nMZ+Y}OXkk~?Y zf$_i9mVdSe|5JAPe2Au0_9bj$dN6Khl5;1J6?&=9{w{X{?T#5rGOGm0sVRv~1Ct0* zBu|49WOqp@8$xcf_qOG6?~5^AQLFI;W6bAU3J#rE4~#9l=jbMsOsxw17C2;PRl^gAia6 zn}vjq1A=snpMtt%b2J~WkXWr_}SJmp0wu2N0~N zJObrMtviD0$ar@F zIWXnOj~Zr+-i}%l4o%pkq7RmiRAzp7iUSv>jBPU~9UO4nHY$I>^kJtJZzRd6{zwZ4 z7NaJAoq?Jo29w#HsQRuH=ML;a@v#Fqj%H~m1;=QOen4QqYQjGM_xO%}T4NbPVU}yA zs3HVvDG#yADF!GTot!}O6%^852mHg>pXg*u%04FQAV|I4@77lc{d2ZW`Y=UuY_Z&MXR3?=c66&uxK}P@a6}WY+{6#Yi9}l zYvkIsve5Jl@+)NAl;GZlagI>u6psoou4Me;`xsotfX^uy$?@&8Sj}TDh0mA%K5N z)s4!3T`L!J{1?DKStGwXDsNmXuj1ZF0DpCj+&d~iU8@_LGiTx<>fSZ7e^mb0TG?af zcNXy1tdZ}G%6HbvH(58?whvR-(Nbgh_8NI^R6ey^mIdei`tzBObCzW=Fh~1U)TO9tWskKSY2frW6IXk!w>xMj2Ia`ih zA@6D-d=Uja3ISI8kJt>kE-Rb)ne9~Hrh3E?pi&R z;RR91+pQt-nEDjqiQ@3QfVj+@$0n|Jjl7#CLE1G^16ivyWv)@=khKtg{*J6^53N!m zV-8RK443{=8Zk&4TLBW&gX|7m^CgSW`zW@yK+8I_j9P1@IwC1gI%=s#G{+)I7oD*% zQQ%{NtkGW-?4eXsLzq ze7)G_3Zcy?Tq#XV2rgft*-QvZ<>jQp)9Q`Cj#v!5QR&s;iq^E?6!;wLT10E0}Vb7yl{nvr|d1m%&o4R;IWDE({Q)Mqo5T6 zG#o+vEC?MdBs4%=>PkX^9Vw!c@MtIC=*&VAWRwtuoCk&Q34(Vl7vwBtga94~oG1^1 z;EcT6UT0Pc=p5^AGNjsqD&fdi8EyP;r2f%KRL|+!V!e#L1bJZcPy9(%|x+LnGV>-*JfoB6`Rv26Yvug z@EyrYg7YC4e5b*5(ET_BU4Y{_G!XYe3fTn^Towud=tv&QNfbz82|WrwHiaHUbAcn{ zGDF}bAyr;#65wz=iOcvf9qCvs1Y8zy2*iSPOd)t~L42aXiA@XyAr=|LafCvS4FpGU zhs>Cx?cBNp7fo}!q>AC!s_Vrq?z(*0K3e}vJ}tMy;xBXg$`(8C^veu>lOg=78&f|c zwp;jjW8q`o^FzCg?KoywGks?km{q+K`?W>-JBMFn@yMF4DPJ?=|Lr~(j7VW{{x*78 z5!g?p9`%`;pGdXKJe2tmzmIA+d-V%_uD-Af#3haJi64)jmny1b6#|%9MNtnd-|#`G zjohoq3$RQYu{08C*ga~!XKqv8m)J^W-sE~VGbxwA{WdkzVxpE0lL!a9l$PBp3bxg+ z99Q&yGWUzvFr;7@8)-uiFi9VnE`QG4hP6lFK@xw!<9D3=>4-(ZA>@?DX4OMeQuhr9E@;_qK+9Id{Px0c zb329QKd)v)%`G-(HnJgLH|wTq^0Y0Gx3ECA&4Ddkv@6!dQ(CJlMr2@Euk5~^g&X;r z9fhhE&xN_}OF6FZ()O@jZH>nAld@?mGFQATUX3GaY}i_o_2W@=@(OqtD8#11)aM@K zc3t4G!|)EC4uMS%)`@`5aihWt!~K`f^>H zwZ>INkwOEbgt@gJ^2)p+;V-rIICdA`0@yA6w|MJfC4wExuelcY$xD~Xd0s8msNQ|m zd&>k_+F-C#TmCqdjRKPqPlvBL z1_8YK{60wASSBkl;Fn9AlGq0khoFtfYFkF-_6oQ|i=M>ZayDXmtm-r`$drV;g&{iy zLp73$U}ipG;)MytV3|3yJm*(07>i)WvSNj_&y}_tvD_c9!gNsp?0L*=du!Y+{{R)p zPqp)aRr`&^?bL51chp&(h4RmCS+IQYC0KZaEh{Rkv%5&n5J#u5%8#w( zV0G)Ov~F_$sD5pMeio{17;49{94T;OG6``6!9iR;@m)tR5l)a+>0)tO(v{FL3YCJSnbB{p5JZpHB2A(Iw4 z3T{^@1{*$~^bH>ftP1(^h?$5_hiJVg>=D_H5UTdrC2humX_8o<>NVx)*DsjtM_He? z3V}?H;0R^kaia22Fp75%FWSoN6*%Lw?ZYMy`^=P$Jt)4DvMs5Z&nwOqzEslDi~=u{ zK~5NH4}Pl1w8$ovoh>qXT@~3~9V-a~rWb%rSsalOW$T1O0^&d-b1-pPFr2_~ASArk z95fJoz}y7L1QSCLh{ZXG0Pay8+d~71N=){;9U&GRIk(s}qyhv1&&)>v;fe5*wmckS z!BcZi@SyuJiP8^DsxwCeAVjS;pQtQo2E=&~92q7-e1eXo?1~qk2?WbJX@6-khBS$NVUd1c4}=BWcLJhyo!h56KC76d*z;1d)kyM-&2xJ7kcu zoP?6(AzzQpN=%Y;EO=GmxDtHa7tM!H!qoi45D$V7M23m%1Z0p-sb&b`h$YH7?&qPB z!EsK*2ge6VLn=qycU4Y?gOG$IS;&-x9z_yj;ea3`z`=Lt2vP3hkQ@O74gxL@#qc0L zN?cAuTFAL22Tv?5QP98<@Et^e0FsA<1S7jl&i!z#T*k5d1^=K4zw3f={=A=WMXf7D zGY-wF&>TV@%886itr!JZq$LWOSl8gb2MZZa;j&P8kIh3`2uaA)qd?LSivS360+W{f+G+L2jYBasr@|{-47}5 zVsZ4w5sdxKox2BhsdAY6%#(Udc{jfS#qE0gy;ICi=3jnAiuD4*J>^3Ow&OTg1zDt5 zlCZvfrNfUHll8@65}Y;aFy2trZNLA21E-5`bPwG{{Qx^^p`7m}uXf3n50W7qa%c7NPgiu#{6or9`UF}R?RgoPC z#}H=69RK~wuN1UqB$g`3*XlwplN z1^H&iS!oZIm`^NG_(V|vcex2kv3L)KnO%U`*(h(h$>-|l%N*OH?`MCW-F_;Wh1Z5T%0qSoqus}SpG!9W-^O%2ZR*-d6T4EeyAz78y zBJKMmFI;MJX1*#9&klZ%o$u(84O;{>2K$I(klb07_)5yQk_d9zsO7hVBo>3CcJ6b_ z3c2N6xn-r?QabmUJxJp4!jAhpJOWLcVG0elm*RcO3j;`z5`W&%=84h*GlsY2f0CT8 z%0k9YUG+s<{quJI(53+Pg;0V{)|fL#is4~Viz;F}_}iuXT>W*0nx9OyWeF=3>uYH^ zg}KBRZltnYwDM6Kmc7WRa)(+RvV+J;$W)^|p_i)geU4x!kUN%att2{A=xT^I52sl8 zRA>JDA1`<2?*MWoqpH)QXGcc4<>fg#=m>>Dh|M8GAQm6QWe4#=h$?&pcSRI@5PY12 zarpCU4t9({6b=MG4LThpc@{XxfCb`$#~!o=n#U%lirCZ~V5cpA7L<6bM}g;|c<^C* zEHdtshCl!(mO0R1}8BYq~I5VCwETA2#`G(1?42f!34>|x7D5yBr(1dNQeN~ z328yxIZi5Kae(*)5fYQ#CkU7a0-SW~!83EsE$O!HO<`%>U!MPqM5KK$XgAh6}E4nCcgNJ4U4R#KRR z0(cavTma9*BZD}O1{d&=3#Jns$qh#?2u>?}@HnJJNQ{{oNR&G#JB=uU1&#n-xFkG| za~uaG=tv43_p?THE#x{z@Iz0+Zc{a6#^2`&o>K!-@=ZVgQ*B>lW)p zRWw1~X=v#7yzUvzraJiaj(m^Ks>3%@MoeJ!a)1Csry12&wswc+hct9I;Ly%3T&r z<=hi;ao4tjSqO7h#f~>$G4MepRk75b>-EK|ihQ}fNpjYGW-U;MSpF1jCTJIy$PQbY z2V@Tu8AsXhV_f+cekSx=NGuAz)L>hfSEJW8N8~6MpRkVnD9{s{g@Xnj2a^eH2=0Dp z1fmKz6U8EzYPWT6#a}lY&fLzjrNQSYiS1yMYE^i@{N@#9Zkp!IN{g!4T!+_oLqttp4bDT z%AKmREHXRPCJ2sC(DB4%et>H^zgEq0q1BteBexRoG=x7|g0j3_ow>gIhb)Cn)>8=P*3q89p{t*Q1Q0mKIZksJ?qXSPEtcf~4Z9WDQAkBsPkhWN{Tk(u2awrHqZ zG@vau=Yr?8DpW6r6a|hD856%_GGx+%=N3dDNYp)5nX^b2!gpFmGyw3Zw7P^3!a5Y6 zR7Eb}1S50KL55TK#CnnrxgZ}uN;|FKL(Wd35KbOi1-JTBXkjgk64z4@(1U}cG=@s1$P8cZvOorOW+l93 zq8v$#1Hly*0(fi=RW1+(2n``K5WyW_Vn}Mf#}){&;2w+u%{j3J-6zUp3y>hR3E~s% z7&!`v)9|xU3`YpUbTB$TDk=R^8BuvjAwf@$ke1}kg7`S1;1G*Tf&kb#J_-bv1ki;% z)G%q|KtL!Qw9N3x6y_l>f;ea(i3y#MDhrQEESwXP5KN6p6a<$GkRUid2o6>FvAHBf zA%H~OJh5vhDmxOGj*!-I7m!m!l2BlR1=9umyi}wDL_kSud9>u8z7nykJJZ{2vziHgL}qvCv6<~pEa`89a6yRU51a2W z!f&?%c#$%Dt|*iQ&~cE&XgR)H3mD1R{Oo>Xw8wg|g58Ks9<$xYr6UfE?A}q2EkG98 zWHHg!v#?e$22dCW=lTgE;L?C&7+ed#*ZycMe-jhjo(s+@1S2yCmG#Uhsm|;o?mEde zMK-{Bb~55b1|O%|%nIV90QqsE$`?E=7oYpcA_)xuCTTxrXMFl8&8U6>ffYgJvq>`Z z0Tk;pdo>AWJo&Oci*ma)1e5Z6?x;l@z6&jkSQKK+vqoT3{hXO=T8hIogOe2#WD4U+ z3fY5$D7PX_JHft-oVm2g#T7pbV;RK_7G4lr#PIDLA!Es7uZ;4j&2I}&f6~+niR{jU zWal|*1K=%NP;CRdw-Z8bG04N*pfNPtbr`G^C+Bd#3mpw0wf6#~)UcdaA{v zv0ZPgGhXE;D?GH^G$h3OCAaF#WhC&T%t@$oGQvgd_xfi?OXPn0>tHP-YhxR=opuBq zhqm@pqQvHA3Z8fnW7<%zZL)YeKwFrTJE>B8U--Hl#ZyWf`Chm10Fls%8X_--~jOnBH*vGH4ZW^Bg&c|N_f8oxns=4IMBeepahU0 zdhk8>S>M_fdlYQ%bK@6bp>Jhy1j*A~tlfcSsb`Ikl8*TZ9z;OD2Xh0-#T^8q@Cmx_ zLHsh3nNARJWOoEz8z3?+EeXgdBnrR4l@k^MoiNw}Lc`^j9HB@;!puOBD3p+z0mmeU z3D^k&APxkds5k_X9l-}=aKOjGe98m}$RG$=kO`&+7Jk8T1OkXVkV5X5p4^h-gA*GE zAHkW4<>gThx=d`x$XTg{Lk7pe#K8nXaK!!0aF-z71I0!`HyO5fI4;eoXv2Y4nY%;Nq;JaK#;A8=ZPKFt=b5 zK#z4lE0ICcQtrqgq;fs(I|m;Jl84x|ln{_u5;_Pivml`3AUKy36LRw%NlR%#I^l^t z2?zo%3rdhZiQ^uG=8j+}?u%i^ zW>w$s+8Q=~kMT<#R%VKgE7YDKXFLUYF*n&Qh?X%iPPm_svBV}%&UEb6X!~GpEvsD@ z)Fvi-Fh{QGU9XhM(agUek=#rvC1CT|<#6T&nE0gql<8Szer&2p3)y{WIJN!kHpLGN zf5yna4{n#eA+Idar&V@w7!6hEan1NG_`E?bKVU=!4dANK9s%RF z#mc2ESJ+dNJSioImP0o4p61aG3Bh5aA+64smt0EWh69EuI1VNFX$WQ}c)s|#t2NLc znO283XvC`7iEm9bF@%d5dfemnX{lhM92&k0vEk$Vb_5+~troSzT^%b41lP$UP{L#O zq@I>kiRr=5OR7jha*u*T*^YD6IX1lgMGQTnve=6(IZAMm6^4We=<#4`QHiyd4033_ z(CBf*;+%}Ym;)0b4#}gS(~*KnkmSTVnN&D};JEaJ;UXx^j877n?mHi!r5{KUgn&yz zLKh&o;4}z@o3;FHfJ#Cyh6x9sgjD9kL9K&jKM&fR$wB1(EKGt)nTC>h5`xfB+cBS> z=!pA7LBm0C2ks6&0#QjIAb`Xnh>(X=$ixyX$eBf@mZVIBi35p(Lrz0pM1hmG@DYf` zcbW%5V7f#0*fNq^Y=Ju`GiFlC4nil?9&(`pnItelTz0=x;t-WvQ4vz3Avn#0$VF5V z5&}9-l)Ae9RIelMlQuVn#3sQZgS&G%3mk%uKn9G=N6t;acLF|9?ovxz4rYcxPJ&uw zXmQX98M$K`h;lwYphw}a2x=iXo(6$fcS%4XIL(>FLdGZP&gIOCQ31d~u02n2B+ z3yve01rQk|wIBjP9KkHe1moa5mY3q+j-}z-u`l!YXl!TfqxPfL3;EcPZ^!(@vAQg` z3;AE=2jsa^&7ZYx%2%<4_#t;wo0w0I?s5yxWE7$@i}hj@QO+z|AgVzfg!;g2dvGaV{iQy}2QAh$856C(w!{AVhhr`)LVr8J!58#ATQT zl9l+K@Nyx;gocBV2R^C5@xkHjG;{PJwu6`=?PsYN^f<^{u}GU}aU**6vp#NvV7PKy zK9nafX)DyC8QFs|dAa?`m4I+7@)+mNTwCQnJm1VR*K>&Je-nxcC>RfHL!kjxXvj?< z=m;P#3qc5qM|SQR>EG>|xo%qAHN`sRb_ajO!*9UaZ)J0At;gK_ygWB%IUWspF`*!< zWsOiH=oTa<0PFc7DVwB_&f-L%jxl& zpO4S6Ev#fzwiHZsV%2js)LyP9$xL$+)FR->%QKzX&t(78Y)gEOWph*b6HC%DIVybt zN5KjW$VX6R);RVaIx(>@haSgJFB=J?`eRTnRI#1amJgd|(&A#1vyh7iDSr#xs)*gl z)&6^8W|Js^pZBp;N9IUtovF3tdC8~1sVT?rgeUSBiUzi1@o~gDNNXo}XJ8`pj5rAH z7h6~uy)DZ<4ZD9Qm_zVMj*Fb;N_dv)%om;Dt+05B{RjGtxg(^~9Jz*M8^08w(1Sn_ z2Lb)~8O~~nD4ah9FHuv`mH2ESBqx?6xdn+m!4U<)V-sUS$V{Mqj&mp6lc&95?Q_k8 zpAO?T#R@Gp<}3Mr3!T=53wz#m7Cr)*;^(Ct9qAYzTNJTys6D@(PGOuwEI57=N>0!b z7o3)bS&twNzSok<UBA>RGknN2Zfm-*zG)ib&>XK_}J2g5}5Q;l9LvhSa(hUbODf99BKVtL1IzFI>BS{ zQ!5xCayhC%9K^>Z$NPm6PwNCY=)@7k_ozGwSqUVHAbwf`JBGj~xknW;2zMbyz6&HtEEPU-Y^f?HX90HtK_|dL$jvVh z2NO#Im|84BWc*G*pb^B+EeZh#Cp7^dxd;*kIS*-_I6!v=;-JSSf#yM&x#dDI4#~?h1cGJfH1uSF z58^JjtUEy!AjzS5Y#Is%=&nGVi4U2mBxr_ExB^6g=`JrZJz+TtBn^4FoLNFr5p)NF za~ggUT1y;2XhkewLGV-^QwT^@6kZ=fk(?-!cMJh!{N%h9;fQyNViXNl&An@6_V*UH z>tBOH0}64Z!lj`+bSr-5^r-y>c{m>HOnj&1mYgVp__)k7vY!%Nm`EIUa(Xc){iG?J zH~D54lM!iguGy84T_=FZ4yIh3)3R+pc&JhK2VNm$fnSh`O+s40)b&rP@Ch?c z^u{KiU-434+BaNI%Ppf(<1hA9B|i%?WSDWt0wuA}hW|f5C`;{wGLk30A7#I5H1mf7 z`F#n~Kl5rVJ931KqX08y;P~6jzdSthC+xE_m?Xq8y=EaTpeIBFa>s(i5=2Hw0vQ1? zKf$s>A+=|pm_?Qrjv|&2g$N)xmkSO;huErZqGF?lzK~l9;Y08w_>?)bU=p6lV+j(Q zo9~Y{>$5A%!So9CyEv7$9ohpS7n0*ho(4k&B?LRB3Y}RfHi$>znMa6)cO5b&r(Mh3)B0*+1`i2L9Rf}EP*K7`zY5MXwKT;K?fI{~tr znt+8%tyD01LH&znZa4#a5`^5y5I~e>K~EKj*iP8pg@ZW^xzY8954!e2UB}Yd?yf# zjQ@P+ctJ~oeox|f;S&p91T&KX(-MfBThKv#r;*T|!hxd0!bV}5qL+QdLK zkQNROf`j-jkepa#gw%W&kOA@YP$c9maH0}34w{MW1U*T}8jyr=+>b)S69o8h@N>(B zSoruLSxAly2hgJ&Cx`c!qRJpLNgxoLmvTXN zniGh{LBqL#p9YSTiMnUIT_R{iV_={elsIDJXC`>~2q6)-8a2IkffGgxj z9{3S3{{bsIk#DhshjGY7FXq-|avmlw_X*h^KfyvMJ_oa3@@JO-X;kb}tw#=XJ*lolj}@=~LMsplz%ADK>b2XdB3xXJ@`932JreXITR#;n{PGZJJL)qSDe^BZzYiB=6YD zk-`H$Zfzjqv&x$N8E*atH{XAmeh8WWoJB~E2Gru?^6)Gm=<%Rup#y0=5)y(yh)iMryqZT94jckBWCVi9xHJ?Mp$sA?LDf?s z6$wc~6lCN$s463X#A1%J+gWfxTqZekZcmpO2o4wr--8{?JqZM2!Er9&=O#nQLKH|E z3I+(L6N1Q*IS9E4NyyRh!iVWmAPDda0hw5W__;+Pq=q<1kRC+ z2pUM$2|0o%K}N_*g@;Kj4*kf)lF)s?EW{E84&s9QPIDh54;*OjI;A8aS>QlM#sS6# zA^_qDI_Lt32RlJkVjN-%CP)?v4~-Kzjl2jn>!$g3L?+zK41;PnY1sMX4SmvNdAT#w;XQs$|gIzcK6RF__ zX^{&;YFXr^>;TaTo>&xeWHLT9jdjf&7V|3v-2G$ckWWJRPJ}Pq`6;3BtKIy8o|wPQ zZGWJLD-c?8qmVmts)zPqzp@KX5`s>{M~3D| zVkN;x558xoLMSJEG+aTF>g*r9a8=L{aL!Ld5(H1q-XnjH2^&B^H|E#2jZnnqRvVr+ zwj>}f;3IQ27sCmg#5okhPgiqpDFju{hme}{Ah{FFgAWKnqs;!9JEGr5YtZjx8chi& zSojprUJX&16)*Bs#&?9M)G|_SA(kjAvzK>Qveltc18{H&jj%2MK0Fr)n?C zNk}E=L9_izc{k0YFxtVxmpGc-49m!VOyIuo$gT<{i4_$AB%>RKUZ&4z4G+RQ{c-G5 z8b3bfcgCRm@l?j=F9*f@zw8RPqlO!IC>;h2;nH9;wf(Gbv8ps6UJBSbk zg&1kbxkV9+kOr9`GO<}8cq(uZqHwu6a9TLHg9sq_(2~GG1}t1|u>})6u_OpYrPdBz zCkR1g2*@~31(*f76QXh>7eP4iq0y?5!T&F9?;a*;Ro(lqw`;nm`cl=G!RhIl9;}y( zTvQlws;9fUr@N=8domGD9Q42sCWq((GxJ?a50Jq12ezR`mWw(fu83_{`fu5e%@!l`(69;?#tTiw%5)(Ao&!p z6;;aDfR86%i4cH^2q{g4N=hLTabSo<79vdn5Q)S{Zz+){U)$+?%2Sg_tSgX0gjYf{ z0mmy(vXIzPMk4i;LZlsliSS!fDuQez7+#y{H;EI-TThXAjdT(Tk+G?GF0go#iwL2W zN&vVb_=ZyWL@u700-pdNg$OCc8|f1;t@Md_rg%I9m^guWBXtGYv0Svy>|$Kt>|3#9Iltks428MF9XJxt=8Q zTGx|EBoYCDXG?kGD=9>t0ze`G$o8jr<=Ipsk-Fl*5N|(;G*YF+f#KPX1Y}dyk(jF` z0T8di1JelxOlL|%Sx9Lqdp$kL&Znk;^C!0l;P^^}09ZY>3djfmkjU4FkVxbyz-<81 z0cZo09=S+~&`8-yZ+29{S5o*&g!H-suMr_JR{*A!V2HN^S%7K35|7tZ$i9}v`5+}kF7@kdqNQ|$f6Cn_(>)A>vL~&QKy!qXXk!_dLv4u7Ek`c@1+)@;^_|+peH0Q>&OVJfQZV|DEORP8m zRkCx+_O_axgB8KFynXDc?F+pNx;pL3|4bGV&zg#DI#c#pD!!*W%!$9Zfob-=`L zYduUhdr(AJAV95=jtCm+2*{^gxl(!Zr6=U2%ua#|3jZnhSUkIjR=EZJ&m^-#M(dX)Zih+g~ee*I~({T8E>vdpf+6oyVb3`RU?` z;C)C$EY}WlN{&l#_?L3q?}2*02aCrz=}+N^1o>rU^wZe~yS)S!n8?PnLo7SYvP1o@ zlk5ohGn^f1P{^2(WY4zjXv>arXWIWY_{HVRh#`z&wKxgRT6jbVts&Et&&b94JK8gU zs};BUl}`tktfy=}Q+9C8dZujv{}q~JZ_^xm8>l0u*;Ze|M-RI@;(ssOzq5E}-8JRE zPum?#%LzY%@mnS*MGgAxLVI9lXRH@~R;4ut{77atYT1(S~O# zT!-PnAD?^s%l1oMv$cQP{tSO&1MUEj0-q?`6F3%|a!-Koso4|L_Va#UJ1cZa&2-tO zxmRVu3^7w`NCMXoBRjo z=j_7pR6xlbFxhHd1IunXsTu?3jkB^z)MKq!X6B^LH-U za~X7o8;{BqxMZ(d@_q9g1Kyu>2n82>E9YZqagU`C??E&j$q86;o ze+}FDQ`XC*owf7FtSk@wzlQ8=s#YI=;q8ekC_g6EuxID*4y)P%E0l%VV+;LuO|Rbu zMc+adJiOkraa)+QYi7OYp$+ciwm$CZ8?ZIK_QHbA7427pK3AJsS*(IJ6ZV1`>ta~J zLaeVbo2%MNHpHjY-fO3Ezg3@K1HrW6=Bax(`AVsCN#C@6oo)ej&~YX7n(9OR2z!h67nwacXe&o-N6Bt0 z+ij!v;FNuR!ag-)E9Y!S&3!Y{3@*05b=q2B4A2F}keZ@y56M{LO>xYx_S?{@=jFfn zsrbZX&g|MzyB5S=upMzdV)QB)KJH0OlV=Buw@sqRbK^Vl+&E_M1h;?_KrbMKG}fTv z^U8LfMwv?w&zrWDQR9F$=*%f===@!Q>A_+Fv+=dp|N8So)&SKH+v9_FPsz?5v0Y{R zArnT(pL1T1Pg;GmHD>IdS$llWcGc|MB|k#4kw2~4e@@%yGrMHeE*bX8*;lr`vp)a( zrVWCMzm5su&*(A8>CA>k{fa>5r>_^fkzXFLe9CgxEUUF(4K}7R$8yY4P&B{`Q{Hm+ z!5)5R*p`O8bF#8EHaj+E6)bI)D`qLypA`!qbTnu~Bi1$JI0~|j22&Bef&SW$;Rl%Z z+(x^rLD4K{mJj_LiTnt?t>sf;lmRH&d&<7Aao5Q~thE?!VK&U($i+SNY`#FU?Xr_T z5-Fqhh+sTDZS>$VD1ldMX9@E7SEBi`4T#shi?&;Gzl&1}=^+iPF4`}Z_#caoZv#G_ zQ9fvp$fb*RJqU!xod@Z!UG($si;MPcFqN(mKVM$3*usupv`N7rXUlLmqv)vcVI_sKrG{~k543mwa+@rx_pz9iL zp1A@k1ORv?k-#fYQsR|Jq#POJ6_VACPGcss#HcG~wKsrzMN~BUo&0-e*ZR z-^o0gwrhrMk+sRHoVCUFenFNl>sjsEjaRR+o^C60nQ5RPJZ7lh9vra({k+ccDz`WO z3*Iy49FspNJOk}!s7X-3G1D8ga)q{)a(Og`y4KaYxcmj-4fhx>P&i!zG}7S41Gv02?v-V z6i6T6vmRaxsLlSm2i%vE4huRM7roo7ZwO(hZ`thV@6NzDMV{gp)GJV}heYf~vi za%CYBA;2P?csr3efzGL?(%N5JN{rX|8rkzyDW4*pC*hiu-dQ-n0rQl+q&E}%lO|r! zmZ0mRQ-hGT?9slb_u3XDA+R$DLsFS7MR>LYWfIT(?dHHIlXf#Gg+y)Ed3@!`#c-3p zA{-b3;J?ITlMAkVjXTGqgu4EM0%`DN|D|$3W%PL}>J~MI(r6?NZg3H^QZoE|FSwH& zQm$5YP1RUQhxLf$Y(u?vx#;lw4{}6$V7>h#8`Fec0WGn`@#_8L1+zt&19qTbr-BRz zt!Kpcmh9DKd-aqZn6aKY+gr0&Gn!*|sy3h#Qj=&^uIyBIhPZOJjLVC5V90LB>?6Z= zU{H(ztZ3Q3HEw5&+DBm6g&S{}vEr;9fahJXVOWDDdj_*^%r37woA6Qn5#joLvoHik58%zCS~O%33eeUnXR9_#8B@~+d@7M~=7fE?;sz>b)$B1HEk7Uj zYT7-nG!gL?>|y#4!71#_y!CChUE6GC!M?Bld6@obFO&E?X2O7NM#NFDe_+Qi+V0H0 zJZK{j>Vd%9lW^3&oIec_)0AySJThY=>_=k!>CYz9a?JigqeI7%;yr3z)s8Td878cjvc3w<~hYygbk>L&<*2IvKJy6 zg*B+z3vr#Qq7L-f@g@5N*V~QT@sMOS`vhGirx28YT|^I8f%n>M!CkGw`*069;wWVa!-ckxr65~mFrdM*2cul{%1%png_uJy6ErOtg zaQIqDrDgqg(xel&;(x-+Q5uG&e~kCySBT<$WO-H8%dr*R77_Afw)&)vY(di zr#1U2B~RP!{r0uAB_XxT0MM2MaIQdvyaYaxy`s=itB6O0uYlEA^{lv}Jv3~$ipcz7 z*=}Wmi3Gj1Weyj84$=FH}Vps1AE>jbc|km^-MX9MR_1E6)^ zUbbJ2+T4Wg1VyVED@3useaWjnWX!ITyan^rM*1lV{B_BxH=-iav(#ge!YhGzLmk*s zA*4hJyyodEDRre2X(|%Wyw3+0CS^3sxAj z0^R8MSLB?eqydpN@hzthxH*7h|@iYU9)PMruKxpl#v+Qq4ijnPVgNR_54x z8%4Y}V>zPEIeY6iI|e2cA%Hdx_8Q`d7cJ?(dKUJ?Xz74ds)$D zHE$7aKeEnxHE&`4?$nHZS=D}qaJ$WUpCglV#gJ>Y^~zBF9hK?@9XlxoyJy_;Re-Ymj9v+7Bg(eGOc8k8Q|oy+&=r zsI6x%t*~sREq1%C>=C3B^klEgnV$e*j`;3y=2|B~&s=AyK39W3H`*eyizydLoj2#Z z#+h1ikE>VVe;+Cs2pLK*)AXye3Nkx*)DC90Ggu?`+Bp{@HQ3Zf>_v0-A~qU1=RxSl zUVr_Nojh!JW%i17PLsSs?s{0@C(qhli}rriaxdHjRG-G^1MG~wc3siFF>LE3xPF3R z+GHO<0LzX!YwNTneYa{aLYLI*iVv{I&I$Wv&2}QzOS}V-3dN4teaK1X>^{nuNQw!Z zOI$|8+pjR*p81Fwi++FBv1L0Jd1K9v1wb?NAR=A%Ni^pCV2_>MXXg)i16U~sp!b9i znX#W5bdnnZh4(f(qu5x-?QC^*Ws^($e?H;FJZkzrX}&&1w{La3R`l#W+wHGKf%_U< zhpZLn?JWt)u;vE>Zflc;25>-fdw|$i! zDASBmU`vlHH;WKdz4reUY=6-nWCabo zeh0AGzp`A9W4b6@X3oX7rzsUc{L&fW^K8I|dFxGTCpZ73`p*dz5`QOj+6f0;~eJ zGHx55zCs+4=A@lgvv-5;#H1Xg?ci8#1dRUi%xk06WbI^XOx$*njtofba2ZwKT#Y(J#pNi>bqC%+r{-X7c*)>&rrG%N3 zwsWKHRN;B5g$Q+hR!@GJ&`NP40oF_%OG<itwt4{xCsTN2Gw!FH;*Z*aM z4Jn~0sv(iEcS=lawjR&ISZa0|w%KF$_Nwik zw&xGn9Z)hfW6JIj-EzHz;U}>G`&^mz&jq`PO$6oUh`qdIr)mv;VUx>7eu27k&R)*i zsX0RmZfuO%MZzbi^SaWywQ@&5P%!4wQn9UfPuNOb><(IE8SW9E&I~+9(jn#vS4c1q zFCKJd-@XpH#Krm3kV`=POxZag*@Q7?7cSUYQn;Xr zhFbn9QX@F8wRQ=LPBcW)VpPy{AVk{g=XNJR@9XTr-zY3D6z_Ej|zPbRl^21?;@H%m7+X^ zGeav~X|=b{9`3gBb)5uDQCnEOxhPW+Z$(X z@0^_g9*9lk7(c?mJY+_Nw6G~OSm!B$;XGm-G#W^95S~avh=hdhf;fSOA@Zv=u8M6S zfzf1UG7J{%5vbgvy<^G-r5f%Vvq!4Fv%s)0cI+27GcH&ZRP9W?vKHQ@SD4)Y22om- zWF`<}Xz>!p01`yB9s84lUBbSZ*_u&T)*~o@XSpP^jia_PrfA!eBy30)?Y?R0voN|t ze2PSr3D9pB2DwG&BTa?S%IwElfKMP+T_sv;y?qnO>Ztu#^Aq6!J$WItRtQ>InDc(= z%sydJ=&P4>&{vL&gq&jyBG_cnLG__{V(6I+^fp}$82{Dmwl}P^H(*($iP|XGUn8Hy zW>P}Pe9ZnDBNhsTT$krWO^R5VC0sz8`|@@i*l=Ev>lZQ>A7*o>VB)ih@( zZ?kW+9&gs_O_zEIkOGx?4nWIAYbvAn!K%Q>$ZEJ%p>GM5r74e z)RbSxx?{rs1(5=j$=9(RnzoBUgGKw8WDagz0Ww735H=N6I~>x5ofK0Fi~*|72EE-2dtpqCjtr6vO&?B%-cRz#Eow!7aR z?3hJNA#6x6en5K3V%*C_T5SWO>u!~l{`gTxbh|Z?9-OhyZ?@wRm2dG4dM_O)QKxTM z?TM7ySx+)OZ)&#-PFMEXCN z&9-*No;Pd%3d-H;*peLqalP}o?FK}jblFRLZC}A|XR%0geJ)c=BYy6pUA)F#I%c;+ zbui+vitL*MPK+@>=X>pgWI;-4x zpVR{)hc29Q91Dq3FF0AnKXU2q4nz$c6dJP+SM8UX6C}UCWN>YFn%bAU1-rg~1-%K0a-?OrM?W&?JWp-)FE-%~Vqjsru1XtJW zau#gWPMx+*RFsx*PPbFqb~hM*W|}g!((gdNp4-uaiJ;IF$hIYHC-S7`2H-d!KCl z=G9sX2R=*vz-v<}E!9h$PXt~YN(Z2>2+t;sL205-eB~3*rhs!rh!Y{Slq+5vQDB=N zPo)6^WL+66lm_brmdNbiM(y8Vk(S(Gm2Con^RrRw6z%Pqo4&jG&8R(&P2i+Gdz-5a z*!U_{`zMVEvJp@XDWDokX2++NOiiTT+v^wFD3Ni2B_H(3c`GJ%$b@0fr|b&}Ltd(l?^X>ra}|?@kEj7O zgG!sJVf?b2&~!ACmS+H{L(q${Yf~?}t$zrPb-gpc2d3--^j2Cd_epcaygFI5&A4bA z{_bkZ!~hu6-z2^c3yME1+wUQdl`!@X7i}QPu0PT?ZxCTg8wicmFyi^5J!jaqC4J2{ z^fmkoJue~u^Wrdq#QPVK&S>(4)rlC3P;%9@)smJ!_}jw@NCY&(&{A++D_ z1R;=^xAh7>(~}a2)YH%MO5l~mCIFqYH;H)zo@WH;hwb27Y8%i7Sp7lnjw#ujYxd?vx79?}>U;!D1RMl|Sg`k&Y)9F4FqAdhK^0?eOUWFA z{9}?gAodD&e$gQ9&ac{zu%g83rf5gYsOH38x5oTz**;sd&raJPt0hn}ND>MN4@72nr%S@#-mL$hrXqm3TI7`?zjH9Kh9j%0F{?4q(=#Qdxo z!;K_-Rl&Ymv>Ordj#w3;?wosT!PxJsRToz>A@_hl%61ET*0k*%unkkTq2Dbk867D3 z4U7xTE7}K2_E6a#s=4O(;%U3Pt;9qi+;4wBX@B2t7{u@jdjS&Zwe|vtSU8KIZHmrJ zoe*)&H-?e{%@tZ2*%;hL8gT{@B(t;X^dXR>=P@5rAxA>A7wrU&$|47r{2W%uHDWS8 zMAri~P8KgGJ)0>`dXyQTfT=5`{n|(X@rkby$k* zS^q3$X=jfTqA21mwS)p29kq}hfY0kmgx6;J3K+RaA;hP6^4d)4b$!a!+oTiegrrrx zMoK{P1dJ3Sgl0z-q!W%z@Og@m2=WAyNL>*=5pN`bR;rhjNUS5=K#s9!Z%+*)BOzA+ zo{*`K3b>%_P$Ikws^twj@ncQ&m%l z2l(_6>xKKCb5wsI7*8o9E)T9ymcXY#i8&9KkwUpDjDXR*~ zp}=~?!$2ijr%;{OQnD>N^Rk6ki3^a-Krj8;YP4#{iMVP}ROa?e6iB>5NJe7+@&9Ec z_B+$Q4N)Vx*bwJo-1G_sLf0WOdd8r=ewB^D;*HufW?UnKg(u5xMdqX65A}xh%yC1E(G36qWsvG*$ zh9o6dMp7c4MPAK~03(G+Q%~XqAOozWM4pY*JU#(TN<@eg$(0xpAbABK(~}4xPY94i zvJgm#XQLxRA^lpj`{CHD#Zkv1>(c!CE5g3#<-& zggpIA`={EU8iD~Js>l)gg}4KS1qZd1UQb_1X(`^&Gv^ge1nLGALJ3W!6Cn%b%gv2_NZ#@cZAoqO$QHk#^M=?Iy%1&-@kp{P0w2$Rmwp7Ijm6LXJ;3+>P z0RW1a^JDX6rKC1om;MoesE%hPwY-^1%Mv^(K=LF7$d)dSj91bTyr5a$rcVLDlfWmQ z6-62;LSlrb${`L+OYO-Ok5`_&R#FPDK=R6y^hV0tRANB3pCo3$$X@OjEPs?WGG1i? zo;PN{(833xS@csgotw@E;UB8tE6<2fEU!%0qHf`gPmPj&rEFiR*;n{F?YHnWqG3fl zrfNTyweSL_!q^EX3t=)6DuBhFxYapXf0ayzPYu<`lSEI~BxxyXNF~pUq2QWf_0RSYg z4yH&mWsGz_k-{e+ndj$@%Cc_2_M|i2NL_mLwYkO(K7p^N!kNZ{H;xBXR9>)wqG}(r0fb8`oHC>p+zY~x-pN9N|EHYB8U(iBcNFfOHG{gW$X*`K9XBn}p=Ui6S zN`KLYd3J)&72)Yw+B7z8NNAZ)bp-&J(k>W5DuPI)J-yRf@DdapGBuu*mO?{qAf1$W zMoQk%SEQ3jbwmP;uf*e(lzSDvfMyUYChU>S5A^*bG{(67BQn(RAb1`lMZi|of~5++5%7nwqONMqSPFy>X-BLa*P z$VgG~theK+grpB@X0A^}DhNQp1TZ5-gdVOVjMbrjiXw#)0y2Q(HRETaz$lGZLAFw2 zyO7AmGXQdx8Lv@zJR7R|!qH_*5)uiOc4LxcW1V_0zUFB_8v-Vg6rL1LaE3Zw6N?>R zc}7csSq4zX_}Wh7Q^WyAp3{z#4kWLn6OX`aNTnKlYR?&9WY_=7FH}L<9f=UttxY8Cr_-iNr<%Cen`cDdJ=y zU>zE@1D`7w0K@|f03yva7Q7ON@<+3ohY$lo2ysx`pHF5!%BYZV7l~5~d|706-l*Z` z==&vmKI9FjP;2&l$eTSQHj%-7J*|&95~{%k-m}+BR-Ai6H}vv!^yxEFH=q>mR)Y^DyNi>s$c?5-6}tzc z3uup$-Hm#2)b=D>3pXl20+y^SI8BDM|8D5FWW7Km55e6;zuPH-G_s-#RprYBh$U-?rH{%-R5U9X0uNpSH&!RG?D2WqGT^Tu_xrka`eIaXJr!+jVZu!Zw7| zD4%j2R*w4=>};iD+J$!r*nb>EAOTqNGGT1Vi_nRE3XN4y!QO*4(U`qQ9ZOSbB+Ucm zI{N_Cq4R*%I1iZF<>^RZog;yxcKPH}&jZ3%oVaA~Pv-$aziSKjBYu3$pDmFVz|7M* zI_yJ@;Vk74tdw;k47-#=)P|f~@*;vlihe6Rba0&V+(WkM>;`3 ztM-lAXR7v4)TOz>4|-Q?R&X{g@3o&7?5bhsP#$0HUZEb>NqkOT>`@_{4!DZ!nH@5^ z+(qOi)b-a*#d&S1*w%{WbJp?NP$EwNGSvt?fp}e6a=r3w=(VL5@`;pqMoOkEJV~#l zx_E6VV?%|IPD-8vuf$s^@Y+l%fDsyPDK2res~v>^OdtiR7Z!bNf?erU2&O3~$WRBf zrM;W|?9U;X?TOTUQ0!;ZYzD%QO+iOmP}f4`o*(B~*d}J|y;#vh@v73gDx$8IP8m1# zJ0!L+qzv){01PA51`d0E5LYd7Aq6V_AO_g-&5|<^RU4bOVf{j*;H02aeK43~zI$>s z4173GV$j(CCHpZZtrkuL%Q1?QVEoduU0QP=Bdn$)Qor#R&146~kMI`+5;N^4=Vtb< zK|k>Ft{J~oqzhC04m*4%s`s|!U@ghPFd%${gStyj+w8&wkz;^GyEt=uGpM^Ja-Ib@ z)wr-~H>vmN1nR2j(9MQkuN3tw-0`d8uoA~@M(tIom237k>XJ?4NqFj$0m*o#yE60E`gmK+q;qCbZReAz6z3bgk#&5KSB@yt^RO{KTg+hEiuQF{7BA$6UL{C@KH!qTSSLL7ws81l)s zEC?AReNOq*m8G^-;0L2KI|P^z1_iux2n?da3yi~G~G~tqiO_Q=WIg@UVBU=alg(o#QDUtp=ZwVmJn!E9^kGmBFa}?r4SM9&o7`_i}{lje~aEi2Y3zyVmL9vP`3&n6z7D8qKD5 z+noK)cDJYiLU!C(R_qgFPrz&bHXD{VswtL8S4ci+KM9B8|!LseAZR>5zxE%nCj@s_0e_lp& z9&^D*HruXAtIgUQpngR^ur@JGgaSc8(Z}D(MmOkuj1|8uv+XjC(c!^+SNVx)j8xA< zJvV3f&bv=M`UHBOMcv{Y6DKKT-Lx{6j7%|C>f9e@PAi}}5!4_9DcHG1dtqi*j@p$= zb{dwMWA5qbmyFj+cMnLt-&ZHB*P!2{6P@7X^&72ELyyV&J=@)0-I2+deZOkwip*fd zTU|EKaO+$EMEjNzYp#~b6N9U>0B@0_xs7ZDI>*hhZjqz{_5lY_Ou0(YMyk5DUURaZ zRs@sEzou!)yy{GeS5lfC(xiIION37itsn{km=vB7C(=rRc!Yp&CP)&=lBd^*lh{%K zj5uEj9ua}DQ?^^|ylna;R`iKyfVEOZ*odx#-GJw1&9Y#%O!khsRV^zHWh=YYJgUqo z^-sy3QFf&v8bkIztgPKPNYTE;%4NZBbZct&?*abNRs~_U7s!Gg97F{|OUQ{C7qQad zZ;jc(Rl7l2SGTo5>)O$B>a8Ov>liG@u0m6Hu*8H|?g#{nTvVPe9G_?i+PUbNic*LW zB7M1+3bv0ELlXAxKW6zT%03pj6ihoxc4XO(4ADx>ci4V${X3@JB9Rg(3KH~d{CKj< z-Hkc!l5JkJPgU(0NxYH9vk@P%StK-Q1RSEqke$#}lQOlCC&9~9q?P_UPrpM-d~FDz zlCl#a9k2)iL%fx$Aks{)nG)kuBh48~=uFQALrN4&qzw=eQX(`{#{x-c2ojiF(rzX!QQ*pn}q6TLPj0nKwiWI>v*B6y59}54zV^ z-DDc`Q8zToY0R9ovDX==~iAg&y-0R_(hz&&>F37FU z?<0Zlv4@dLA#y=oi&wgFdl|2XY z^!~R+SLn=hgE>S3w#S3^qZ#|rk~69>o-=qE3c(k+h+>!QGr09b_LbR5qju7gjV{>& z!^8k_;7(rtK3Q}x5X-veB{#-{7Udu?c;J;w-bEDNhh46e7Zt9sL~)7A5@H6XY|yQh zT#Pp3o>alKOwmSaKm$cTZNLJ2$*m@S6dDP@4 zAcuatV#z&UvF$={+!!V+v_za>d6k_!?;e5p{d$lSpj>!iSYR<$u4alK}@Th0KV zg8-I)>|6E%`hL92mhAU+Aou;7TrIUy?m#&U!^HmEjx~NVYg`r8HR4p{gZrCnB(1nc zT5ha0)?GYVdQC0QR>#_Bwh%}Gj7USFl5&yK47X!=8^Z-6wt0|<{2&uMvm^D7&MS?& z4Mv4Om4|Km`6a9)dYBW1C0k_9)NB#`6zeX|h3V8DbJ&lDjk|64+Ilc2U5cnb4x2CfdZe`s^hS-ycbV#(hOXM7({_~1PB;YNYC-6VlI^2jEKg7o zLSV=~pIV@AKY_b|Ui%@W3(eC3E?kRbxXgvrK}$02H2hhj!RS~5zZqQ}ozH9Y$%zdO z4Um8ZWMpA#f&FOVd`bs~PlS`xIFb?pbV{U^3Xen}D+)vie7#1IoW^5)B%RLHOoJ86 zBD*#)Ux_yaOe9`;QV59=$@N-a@$2i++mL|qHFC8C7AZUlq%_n{1UqD*Fp2f3t36}Ec(O|YfKLGPq|8i_M?2yG@Rf7|@d(VxWi>14D=gLZDf*D20Q)6OTt^mM6>v0%k;D#48zGR269W2=*%G@PqX+iH$ z$f#6cnL!1P6+wx~_ch9K4ys&>Nn~jPzhsoKj&=o&{!p_DmvwSQVJ z4Fucg`_3P1a-9DMzv1t07nmHc*P5l#y*xVujrUi!C$^+TTg}F&qhUOuG3rQP)m_ae zcO#I5T#0lYk*m@`v=rgl>@XZ{$#4|g={0h5gf%Y?jy}M_Qv7~kW$_!%bI=9cmz?L| zisTNwwZvJBV{F&4hJUKVpYL|>%XP*1eU6iJPM_oCGEMwjuv|Dr!I!vDI=_Pg=x>r! zl^JVV!MGJ_aHt%j3kI$26s6|phW=Dr|LdoX6V2b^WNtbei@3%;>cDUz z1!90Y4(A@w;oKSNM!&V*zK^Fth=EPkJ{}8?(|JDk0Q$%6?uyWdqb(iMKhnMQf3xG@ z*h9%(+X2eoGon97N)L6X%#X zi`20$>S=)xVW26*Q+jNRL{eMSs#bz0Ldbt(N{}%Un^6ejsbrjkHzAxO9sT550LxS+ zb@3PEB}5|W6@B7K9Q;p&-HLcU&!&bnw z6o@nl-L_(#;}(hqjK+}I(395|ezT>ibn)Ff=e40@YvF2A$IRaybTym^X8 zKZ5j9y)lDB@1kEQfOk+NS_t#kgvk@6J3?d3R}d77Bi=b?ZvKSZG{_0QLU8g`bX^4( zYPu5yw|lG?2#JSrK321b`5mnS$d!;%LQ27XL|34%! zu=7FChm=Eagn6NC3oE~&1VLcy9@|iYthX19x`Wx!gU}?}@FVmfy?&R(Nk#k1%x`k3 zh~7iGir*l5F>?4&8Xa>9wOBjI#r?A}?sY2Llqy<(gD z+2G_mvl{DY<}JPpKo_B8Vd$9&-g|v^Wxsu?*N}VsgJd`-tGZXk;hj-Cd6Sp_y-EAh z7MBsdYOBl2{7k(ROyR_XVvifO<3bz}bb^HBKI^3DXFfZ=f*BdK@8M8x#=h4^I68w5 zd5I5Ow=>M_>cll%%~TAV!)UdH91JKyCO}h9xI~3E5 zAJn{R^|*^R*LRHDL+gD`qVY*1Gp(;N9*@HK30KUi}n~dg<;qxHUu^t zyL5UUUt#m%nrzZu2Tm#IFVKwbW#YU@BSwD3DVmSGj4zJ`CrZ$^n=FFi%*ydFBb-0-3?@ z;{#cj^$f8hR@q}Lfq8qZBO|$5%1cER1yTqhcg<6=jnv41X{lj6GezpxuhHmz#|$h+K~uC7i|x+zN&2z#{`pjb>^OtAg&<2*!{Up37AIJw}7aN za%cupns3b6Hwt#B4sLVhN^{ijSZOkW$Lvrf1HfSF91MGsky6fZQbU9T2Z%%3vp>`g z1v?wB%i2NyYRt}-0-`cv-E(f#lxdbaDg$o|i7~kI`u)7KD^i@+)>H6*SMZj1baenU zQuhW-8vtMeFr>6nu1fsA5*sR$PXGYMYeaw{PD%hrgii!dX`2l%xgPcgjE7YwSwIe5 zSPn=F&`PzFB?9G80$@4Mtuj#IFcAuUjuA0@Y=s&xU?`-O8soq!fpiiHyb>sl#lpT! zN~Twyghm1;PQ6VfwiM3=Mx0Mn5uXBvcq4T(Un7vn*IduK;EA`Q{RuuY0uLl{zyOF> zp1BhF6zR(VFeCa|&^|CNVA^tQ=-3ctBe@c0eu^}^+2ta7uzEf0mlkbMF1f(l%yTUE zqf)A)QsOA=D4%##&GV3l2-f$R3gk~ zY}qoYLZUT~Ukmt0xdNM)EY9(XJb#7zi!eb2|o+ z*K0a&!U7)AsM>Zu0@4Y)1{Pa%4n@%7ysTP`iFg=a`Ndk(=b_I%Z_JyT9IP;oY30ia&+ zn=xz8#4iN23a%lPg}hm0RKyDrwf0_oEsAb@J(Xe>ShVrXFOm5W4o1rMp;4QZr??MM z2JY@x+s%C;khCWwU8B!=Hf72NmG$?3`&OFdSw`PCXE}E14Ia{0YBB0 zQ5N%XUK5Wpn;p%jwGpEHy1J1Xi8S?zXG;wrg;0rR=t&kn5lG~jC$KD46e)ad=o9Ir zG!t;d`9z38tSindpNR8psqjp3UL(S@fqy*YJQKcsQ+}kAg*YJ~BfZs;LV8mr15Y5% zS3+H{4$t1rt_@`l8Mf%x260UrhXE1);w_D}fX?MXl}}#aBLH8=C>jYo{V!s*2fB38 z&Jh6R=PEzb6X2#&$jhg8BI$s|Cr^h)ov@cGkxzt*-~)y@DdZ(W3K5=-^x9H{S71md z07hb_NK+9$wc_k~ITwj%YSiefZ{acur|mdv3`l z@Gw)e3AoOFmk;1E>=l#V;qVe0!KI?#_)$=?{vd`{h%E zRw~&UTreuJ1Kbv-5g=P+IJ;_g2A-d%?F}gD#)#M$r@~~Yu zXyYaOxl}6qvmbDF48aJyv!>tC zB|~TQT^JmMB*;e4`PS^C(mygGIiB|EZLYrDA*trJqTfIA0fd&6EH`f7=(Ta2siF*( z{5dv9*ax;nkP^%eHaXa_Gl-lG9{Rg(4V%Dn=~myrj9_ zz;%07J9*kpB3G{u5Xa&;j7AoCb2cNK!eMGMFN^eH?MjU7z_i`f=MohcmoXV)k#2GW z47|8Q9npB2M>9TFvR`qx!h~(F*{|ec@u5ZgGfs|xTcls>Em{q;WDu!1aVRC~LRt%9 zT$CGIE_kA}+a*~-@a{Tgp73Sb2)^m4qR+N4aGGh43PnIl{l%dF1@?P&<{N`JYJaiGwrD7SLG3g4u{r1F zo?rxpPmmcN==N!L3X~GJ)vR+nDE#7bHsKVgGOn#b5D~ICjxD4U3UzdR==B!ud-NxL zC;;#eEk_h{5*ls(f&wW)%03?;xwu4K&K8NcV~6$I3v{9CpBL?)rM2hoCnR0> z=tj~1EZZI9b{G~!T&_B4FOXd89^_iOTJ%4eV`KK`Rd*lyi9jjhk}#{Tr~Q!#y9Q6T zjHY%CUWt>^NRjx&D|@k18i`MN?pEu9Ro5w@k8tiOF5uww69OL&HnK}r?F|Jdbzs%+ zMO9IC!*!-5it@vU>=>4${(7b6`2ylKbvt+f(x|IoHzHDiOdYcuxoI8Q9l|AdwJpvb14{qo+f-u~%Q?6JLQO9vLG-9I*IQU*Sh(`TggmdIKKFJmn?6 z44jI3Sw{+B07R~aa`Diy|-2T-nyCa0G6NZr|g(Y448U?3;AS zDN+E-Q+DDJ$ORaIPoxASPg2@(BD7~{t)_Gba6?&|dgiH|RstXwpD2e<4MiF-p5ix` z4R55uykXIAAD+ecxQ@x7v}Mq{d(Cw0$*M zF5R2?#sReh!lXvF%U%}XlKtJHALD}k@x(E=)qy}lIRe>J!D^8*(Z;f^1Z6HRo2?o8 zr)#Sp%BFAU_Z6znhsj>B52ue)Mr~SkST0hi$qBD{9 z|1w+=j{40b4R$Wgz36s&o(Ka`S0LgkkilF+r|aiHYZvsm8)roKpw?f6@-cJ1crUxp zY8Q$B>$q<^6|O=Pa=umDI%^zNCRlnd-5y2Btu%{TvaI`fySu1V4iz_Rzr&1e7D$<~ zq0G9CyA_zpj9@azglqtL*12#2bSk|YqvnI6f64pgA{b4_D!ZX%pN62?WPd(yH(;q= zvrnsGP$tN-K82`yd*Y@ch$K;Rvaa z;S4a)_<$Aplr6Z01FZ`51z4+X1}3FRPubN{J!(=ELfZ(?w|HQ9yu$;-&A3Eh(W%XK z!2s4+v@b<(2st$6LYyPL_lrQfTgP}=>H9grD}m?TasYn6E>gT!6Rgp`y+t0nXeW~m z$NrE;^{07u48rNzmL08iq2mnr_J>;LMx+fooE1v6e;c%Kv{jSx?u#drZ!9?3#wo3~ z9v`_4r|MuUI85iJJDfbyZo&~%AEx-(E@xW~fclDY*lL}J5pHZBMi7w+*T6tz3}`}zIj>lZV;vFqE=ebdqI1`%`gm4YA?&SBv09kqKQ4v_;0rTCmd;VW4I1vW>V z)@{O*f)a6UA#Lycf^!Y9fzW1{@w`sQ%wNZ4USbwDV&tZUSyq9}>X?T|r4jMz%|;MI z##e?+yZ>imj>WUj-jBw%XkW+FFw}55u7alN{pf0?EggXdleY9)5UG@sbO>voMY;mM z8+8vRsnYm>0KqUUflM=>?gFx@C-G*73qIrqJH@1DAbf1{5tII3WR+lhWR-M20kDQj z+a-Ad>+$-c{ZJRdu*Ebvt|-|8{3d-!E~HObBmXNy6Y_!7Fv_8kxq5&nC<6VsOG+iQ zp(xIVW5bh$$W&cN?NFhV*-}QbFGo7?KLGG7%z>YB>Bgvc_)n>b8xL35afr&ptse_v zt?RhmxgT{)PI@Hor|c$_p#>7NE! zKo?Sxuq`5;co#>=b#UW3xKq<BX|IG& zud|`6*m%-KoE&E|oGb_IF7&_wyX+PqJP;!shM+@DqA`?)K=Q4~6Uz2hZq7oaP;(QA z?@#+dJZ|r$@lDNYB9sgoUxS+nEcx}?Sm9SO?p*8F9qvqv8YIAFEA!F;ohwnsVT(35 z=JRBq>TN+=CT;!;C+rR_z>2a{OGB^JMc|J};S+&)E3GdgO#uKy;I$FCo@HInwXWw_ z*R!qbXy1nTN?rg65$BnuGHEKue0(R>xt>7md~F5rfM0M^pK^y|)V?`2%+Z2mK};%e zzV~o+FCE)&TY7CJrXZ3#@pUiPdSVbVVLzF)Et~+7q4i#>(1o7-1za{Y#d*h~`laflm?ml%WsTG!JW77q&GVRkHRoaJLnt~Vfu{(PybZwx4^&>VmW7p5w z7{9~eeVk?Wr{m<4?lSkB5VK6$IdKd@XGWHfkI8HvIY~wS0S?s;!kH1&C@k|sw^reS%+`3b8#yXK3B&>|a*7yqXK${)4>p&Mm&FX8(e*(;B<#7#orSDu2!0-$>d& zy~2k3Yy_lQuwNE^IGlZ0>-J!{%YYB9)5CJXu|ovmFF6y(q>UlYWK{^2f|D+AorWIf zqCQ|x^xFfy_7UCajS?Zt?9oBLQ0$j+?aL~Am+pgx=6Q6=IA#0*jL(b>BM9AMTZ{>%xmaYI{enKM+2bOjo?Ufo)kl>Po*l03OCmMV&cGABRAsh! zB8^AtzG#m_CKX(w#cp`1m}oE(=;8^nT{IHR*2Bz)@EEcG3Dq%Y|C2;!b+Rw@77|bd zNWunr1KsYoyVBeG9d>zOTB1^RQkT|y6)L4{Rc>6ZSv9TqKgD36*Ka_hSNF)Oa8a`z zq=zVb0Qsua{rRH(SQ0-_!~&Nwjo3!a!sl#bQj|BeFq;W$HA4Ct{4bk3>ld}A%v0YN zQqz)se#CxWw$D!(ifk93&bhz4&vW6dELYz$?QR|^hg=ZbkEFBGD6P6NY?BuY2ycYO z53aN|eQvpZz1H2^hy2VMIQ%ZoTQR9d>|?9l{E`K@W|P~bK?h#H*}AzwmD5;r_Awb` zGM%vb;cBp6rkvK!3=&r;jm#z>OGfNExFl|PVFgXNz=T1$ZmS!wf}p@xFjh0%#RYzwAkEBp#7JQE_Y;s_pA zg2xu@&B0-DQIUFSkuE~M$2^Z?{-CT)F8%)FN$b^JMT<;(YFw~8ncj(mK*O~(W^b0@ zBKi$&PFtx_XMj-N>4JDj9z{L5~)U%=zuAz!xVWS_(4)_W< zcG8m3{a4m z*1)2&``pF&>g4+h3~P0r>la7uF2*#7VeD*cE}v=31l}M_3w3v%_UpsaIz7AXaEYId zrCPJI0hYt1?{%Az_E-Gk1dI8xXtmgzcdONv^JuU~?YHmCR9Ii*qVe zy&wu{#!)lPW03;9ROGJ}@qbgFQwyMxKPcIE%Jv-*_Sm3)M@#7{)!xw9)oB~Rz4j^Y zhZ=VF4WCg=X6Di-XMO5E0RfY)g`(Smr-ym+3-K2`n@Y)4Yt9O3s{wSi>FS2qbIH_%}<2%YE3KX3dU3>{ha~%63-G&O*Y_ z?TGzRxR^mZ0U6gi*DpUh;|>ZkRv)JIGCVkNjE<0_j@O)7%xqZ8c7D{&GtLf-vC{f6 zgplTXg{To0)Vy5J?Po;Ry8sQW*w0Rlqy8DI&+D{l&Gxf_F50NZH_z;T)O@3MKbpQJ z`zLPMVBZNVGSITFqWcj%9SZcCdj>l_m>Me0{G|We&~<_#MeTg0ti z9<@)yGg2~3vS?ov!gr=MDx!SYz$L%R7Qx{A;bGahg{42L%h4_sir%L?%baKAem9XB z9}VXlco;+Ct-s(By2tquSly?grD7ZXIV7TFK0Au`<;?yrw#Y#{8LC4Eevtxk<`=;N zGWnAsBXt6TUuK}cB}vqds(l7CZ1ii~7Rueq>s{b~F}gM`P-c2``>dXnig1CwW}Qoo zxGkt_>#sK#2!qM0y`bAJT<7jIktDAgut!1T1^ax$;WWl?g*|D~c8}Rg9G`-zgvpr?uH)eB ziS%*5x821Ep97h5y{zacTDVVK24W4!n6G6vC$Yxc%l3A}8f;sVY&4KW)$Hw>7|46C zs@kp7_Mct$4ETj!dsMf?a?)Y%uw6Oi?qV=PcvRO4!;$Tkw?oeC;P2(=S-W!HyK7!# z?MXGK#9ppTL)guqn6|lYyIi~82MhM@UcbqGH}ZiIr(MJO3|HOl)=qc*q%frj#uQ}H{)G9-KE=I?()D0}5^n2Y@L#NL>kN^F_mV|a1p6R_v=3Qw zS)UKto?&~wq*9NS-KvMb*fVR-m(MHex(m4|=mJE+$xYo#d?kk}J7kkz700dd zpPaNkFqlvmh~Q)yMQ`8Up;-poN5~WM=e3c!CI5~QJABl(&)AMRJAA>xdN2pYfP^in zWS<(bg|ht*tV21pHD?Q3U8?XYI9%;bt09Il%i+vs*^w=nVI5OKcf=pu!)4k- z#xt?E$}mPVb_2M**FG?4KW1}e%4v18GlH%+OxUYt+|dD(4Sott#pI!=hh;OlEY+7t z|7Q}0b5syA6#%b}Ck8f{?)2JCnu<^qK0_w#dBPQUt2F+R9sHYG#dN9rOD|b$94m30 zK4A^^3)uqg$AmuIr{ieIoO}9ekDaUS@-f;2i-$cDw+|1y!=(o>W)s0V21~onzN&FN z7xOl4qc>ooG-D6U+HOg-#lg_FMwodGJWwTu* zKK<2@=)vNR87DW-751YO_&XR|7%{}5P$`^|Up?Z6ZEVU|g01ETNybhV4*MW++3`ng z%bZ_+ly$pzh^}7yFp|K6ol&&k!y1P_q7Sk7Wu9|1201X!cGQ`OFS^Iyr+(X^H=!`S{xq$S(V|S*1 z>Y69?5^<`ohYbv-#kwrJtK{k!Pz}g!r&OZz@ID+wE!b(?AfOvLzgf2b!y!{$CGgGd z&dWR~TzcBHK{P@kKhmk4S+q|lcUw?yz1l&z?iqCL7loJ1Zwcp$a8Yr;!!6;GTwS(k z{o>ldx9~x<8L#6U#9-b|peV^~D-&bb)@bQ*R(k73UpR*%fYscfV_Av67<0?XL4ouGF-Y{(k3oW>G0)kmejmH<=AIR8B+tO`6?6DVfUvQrtq@Vg?za6Ij zk`)tu2G2IPi#S&((FWNa^ zp&=^_+jsTvbh!Is6-Gh}aL#5cXuQ6wwH)Ub_i9;n__phPju2k<;sB_cL?M3{#v8j7&}-G+yp%!zQ~mGxF1Uv3o*pm_u$pap+ruVI5I zIBWKe*v;8%*eqD!B2nHyX6K=%S36rNZ(WgG3po;r6DYZ73{vIG}kvkI_7^H}kFEN{9rbRm?QqS%zqWHNt`7!ladEtcUrA61nE*KHeiy zAyaN7kamoMSn^=)L5VnKp<(B0m4Tg3>0s^8O?*ASj1;S`-OY^zHYdkoqANhTMGbB) z4)kNPC4ktw4qJk)8dgcVDq=+s*X7ZzG_nn$cZiTZ*gqsaOC6MsC58y^y^HovWkdpe zgK{ANxiU`6l0}Z`phiOSiF6&p>BrB)H(NcDA_#D{QX>M+nvT!bgjuV^eOH z?4+`9b0N!b{D`h!l}pDskDrE z!FzRHs1kx4$tt)mU?`9Xfk;DR0eq`Nr_4{Wgj)jO$yZD`c45O@vX_?aDA4{U+cjZd zuemUsjo?M8K!7RM;nVMcjj_&}*LjU?IM?m+liGzfHUy%JsVGh#5f)q|D&0e%)8hO- zyA0yH5xZl~?tqYH&^4ggS}?)z81S&n5*SLT!H1{qK6XZ_59T2k+37@mQFRxj9UC$B z@JV`h0(bmzvpg&} z>oj36o3Tx^e%6M``KmEHhiiFzT=2fSXeUWN+^xw^Z=gmUoOemC*n!0-dE zQpqzzV6tz@bAfJkO{fdLJ+{O}D>WD`}C5@+F$gtrNd!THWh&zLy`V;g!bM^oS zf~M_oU58Eozg!k&P&;Ae4&zqQ_Qw`B#A%UU-}fIxErsS?=Z~Njcdzz^3@hD@u?IFP zNTSfiPr7CDn0y65UvaeL%4z!)h4lJOrr#d4eK<}L3xA(-ZJV)u_(%yNllyU|?T*Zk z=7sF>8l;YFveLYuj)Y)%C8Rjl2(srgF~A$!yfa@p=2s{G67?=34t#LoKXASMquRjs z1UYwM!Jve}|A*k^9{i7sdzK7`^g&8sp#ke>)10z?>^TQ)^^~nH8T{;-aIfZfNO7nE z+2$#5UL|t^4~h;fE%p%e!iHE^P?IBDJi|+*#>#>dIfye05Pq0VVlatFKXj}pSXp|Q zg<}C81V2cxWG^V&F*SPuI}6+mCu(72s3K@22vHT4(S zdCQ)~Y-hSgEeP~5+KjgSzm%N|oL^OS@7I}s9y6KDf0BtX84}=sLbwD$0c9qcM>3Pi ze=rI~?CteYtqt5NSgB}>LRHK;0U_Lv+JMx`Rq&iXe79oj`;~we@KLp*NaZT%^{Q7b zX?+wF2=}{wYxeOUwD+T*&;IPs+H0@SC?Tlq^Mzef}o)1DF#wLB6UJcJP zvjbc~f~CyT&k7jx)qp);XA{`G*Q>>raC0z<;9&^9i&GwlJGN3fR{J7C4;i(a*h(=i zXt`m!ptkJs7)l2igD`wp%3Jn4Oq^x*efrEA8${4HYTsumpYtEhocTN~p7EQ=mP{J6 zA&uN0^*mS^NX;hfsQ68^81oWM#GEM+_QQRI~^BaVa5h)?X^Z#nzSx*CJ`+ce26NtMz36J$CEL9^5US4Mm0Wyb2?Ie!J(u)Y##8qWdSa_o7CTL#zOhB*$f{Z3BRJ8X*BXO#TUuB=1)cf(jrRyCcd)Y5E+ZIMCg!XQ0U; zvZ@7?i2zEH6NCTcTa zBtggkD*3gNfa$1Ed>p}C05k;g_Z?%|v6gi#%Prer*+$Ebv+Q`wPO$91ShmTs$60o= zWhY5@8hu6Gj_(hn`YaGE4PCo4eSVe z^6OMCG$4t>k(MAp_+<}3RL~HW$pJtBT&F04kbwt-9|XW4!)Ic5iLC^+we&!8k!2}E z08-(TgeZn#=cvUDe=&BTiQyv?E2T2$GYfrV1o3fX60T0cPRc*Xas{Eu1QY=LCS}NM zP$oU+J#D*kt22K2gL{abb^%|cZ89V+FuvniEM)Cxw{$p>vF>KIlC>XLPl%kLWUqoK z|4-uV1MhLG&fq%Z$1j5>ioib@yNlS1l7Cz&WvyprkA_mwrRqR`$QXc`J!#aQ6oaCt z^H;rf>#0~NGend{CY(6fwrxaK+rwf-Kgap2+nj5?F5a4%*2NiBpq5{$0%THQ5uIwV zw^xQ)q5xm^DROsOa+gC2mWKmvrzQn}E8AqY@J z{yho7)Ivf73{6lH#06Zb0uc-!d;rkniY8~a9Q|rHPCyc!!vrhTR)})gHqVnM2jPYx zFWywayQ0X;hHYFbg&7ZwPP#H7CbH=X-_VCt((Qq*TJ+l?iSRHw&4_@_%WQ*u=M)L= z(C6_V#35y;A7Mz&i&U@$I2QwBX`ju~m;1f_zn!-9-)7eYzj}wSN(kcVP8`ay{c`mVm~Ie?N{;n(*{SHcBp|@+O0^s`|WGI2dWQ0b<%F-tS1I$DH%8O zFqF{KRsb|wo*KLoKB7PZgewJr31WhEipo;^gCw>$H=+pQSIR$6!MZ0oNCbxP+iYGg!^*le zIXUtpL4c)pYU;-1mZx$(&s2>lC1OE#6jiI*x%xn0fCGRAxE2{0fFect_|+=bNry)W zB2@q+Y%suivn?SvO|1=Crcz4LJq>Z6d+|Xs2H%Xwd^8d`|UFHqKEBTSc|eMfN6-I!G7QD>Q#5n*tKvP zHUGOsaejvuaa!!6al0G4;*sqNHzEFf{f>hisrv1wQqyt~D*D5lT~&23>m zjkS(+wQBfIt~xtvpXWUhq!^Q~euLEM0{9`)lo;CXi!yrGtsMrBu1_K@YPF1>u-2I~ zpG2!XX3mfTGovaP6$`(Ne-Q&Mgzq$k*fM^G4aQ6F_)jc$Y4Jg_v)YcNkHXR(+VEFhjX9UAG0LY_ zo|V$#7s?-Ghggh|tg>Yo$&|@=T(cKu57rXe~^cVjCnt zBmp2*rmu*E__#V@0HDED@d<+AO1(t7ANb&j%|y>}!1*e$%~Q6K3W8dc1aXCulnEd$ zE>HOY5QL^93;+%cjwp}-_&D%5kYK6=)F~~<8vP9}fWtbQbSd6k${~{AcjN$Yb;Us@)5Xo{2%01nDp4oYA!9n~-ZFgQ|y#03q09ipfy-Tma26W0d0D}({S zA;WI=%#^>!guD;7v-cdjO#^i8?`d$74BJwYaG^e)^F!+olcy;AVe)i^oz}8zH`{5* zD7hMj9n=BaIbkC$ztq`98zoHKsdpSM=(peHDm~{H_@8L^q07f5dM<-Z8hU+j zFX0j|iTkshG<7izX&o{*}L@PjoIT13&Jv z!S98e%A|)jJ~C^ru$|g`pawo83poPYJouR~+!*QTx}c)T4)f}^-nYe&<{H~FXInH* zcd}l@@*yjA4e1$ zFqoEoW*Pbqz5L`M<2bg5gP0^i)S16Y51fl@KAg%qdN&(vWQ*e4zlAMv>L;Fgg89J1 zrp?%Is6OA=zDHSluFtd>}_)4D)43MQ>NrumvtyI7(()Xv%U#jg9oX+w_}w#m7Vx*^+hJ+?|U zp&(qDilb0>iK~g8FqGkPRRh1)CpcNEVJQHz$O<1AWK%H>nEu)kb#H3R1yG! zAPEM(Aa;rE8@A^hUo?|I$RZ~v_KDfs(Wg|Kzhu9CdWg%9NAvVeP_f~x+M5g^$qyszuV~Xvd3=ubK$p0oXW;yKeALr;kp;V zk?m(=_8J%$x>7_b9C=`vJcbJtT%ADKjIxj(A|*^BBzS#nvyVe9bI@MgvQG@y18`Tk z=qd)wtx|V{!Sa-(w1#B-#x3?@I4!6?ZnIlw?J3gD3%#|2(&7BXxE+imgTArSU*luX zr9tRFEh%Gg6Peq`+`@~KvNrs_^G_`UJqfe)L-Pbf&&&;cbZu*ioYK2*!r`G6`?{YzC38Ze#I)Z}0H1c@!>DrH41 z7<`i8ld9$}4E7;~Co1wG3RlXn6-Dv@GT}*1Fc&>OvEV`CH^7e*Ch&DsY^5`8oM(tS z%A`H0fk{)N{7frBS*GIhNKQWyV<(o6PSjaZzzFDFlO%Y>Z1CVHs#bAM3>crH$qh%6 zN&uL8rw?tkRRdG1Xz&2JC<6eKB@B4rGL=s7+^A$qMO2nBl*P)0j{~2FtXZ*?$i^Ey zAJwNMq=KfvPwY6)Cm1rB)I@u;5@oLM;!Bs2!%C|r{X@tTyyq;S?g^4PL1=Jgqf6f$ty8k0Fql}@2li8kTHikcG=F|@D><}S4Iw4hMQ z5`ty+(0b?9N1bz}#jga^kxBdu_^6?A2ZL0q-83K_m{Lfah2L`Zj3>#=>60+`Bs@`M z7zDqd6g@#&KDZWD)JJ})*p8|}LV#XBf<=_L)2FXnQW16hO$Boj{wk{`{Kv3rlE-0L z99O=DKI1tjQOglY$Z|y2jdN0gN`BM?N*qO$scuDz1qls~sGtGPlLHAQ_&@?ws&k#_ z0|PzyBBcTe3GTT=_0z&HosX0kA-as42Qegb{G7vDZ6Xh-mA%E$39+}G4`JE;*Ov*qjM*z^=i zS_%rkPPsKm4m-f?7#XUR>#%wkKB>R}fW!q*2_T9fK6rdwp1LbQL^VDDWHOjd;rMGM4SsKMBgMQ7&H(AhXW=RaGf&Ddy0S_M{Jeo2|^!8@VG3|15_yrpuy)t z2BxDVU;;@n0Q@2)hq58dQa;2&L$FkA;6Vc9!jJ?&I1B zK@6Mu1AfMYt-2P5hRnG$O|9lJ8Zl4yhNi37uxJ*AUI#l&9QphM*D$-TUH{3hy?|+? z>o$Ve|2(#9lU;vKk^0Pu82UPWMWM9#fyvV!cMO*cVh+*$0xmE6Wst3lDkvE_U{pl< zv?#GNHEm`(m0I=H>)c|%W)y2R0bVVIb`I%lRMx{3(dP$$u2FnZCRR8;qb!O7>OB*7 z@vNQ2ZeQp6&vTm?o;lx(-c%?XqbMb1`)e8gSl?x*0qY~PGi8ANR2fV=6YIOW3v()a zk8!_ou#0kaVD!1YYuH!p^!#Q25V;1Z70lHXrRod}5?3h*Js5m~0EPTa1o(j@76*(E z5;9JHi6ZTr0b(cZ?U?v&k~SaYm9$H=B`@yljK(I<)Z5giik zvY7wrij+>#)RVo|qinS~k{vbGMxM)X_?2dk7$DPb#+;6anzze4(BMGP2Fs0Yg8mc5Wnw@(onB1~NkS7dL4vT?# z2xSj6J<#qzwSz$yssc(9X~`M-N@+B_PP~9WSXX z2VO=f`t}ITS-!dMbgp83L1$wF;|PYcct^F^K_twml|)pCYoFY<+a)Mxe}Zj?IUSVz zfUKe2AuVDi4Q&do#U`4Q#=^49?a!Pe9?={$^M2V7yJzQUGOSbkP;H8%P#ie`M-VtV zK&?+BSSpHOE&xn%I1o`Fp@aq>3_ci$aUjD7p9v-wBtiU4#8sj%Qx4#Zlmp2bBfax8 zWFTwdL#~J1%EtxA(inHBD`@ux2Psc=AVVC%Onw#21R)~|zoS_EN;GAvX9P(LCSd#q z2A_$tP%8Y6Fwg+tAi%GcBrptBlz9qv$WV^iD^-oiB#5h&7J!7L0uKQW7-W(D5qJ*K zaTy#73`>5U%iye2+yqx{B!@8=`cZ6;5lO6?x8LDm7pYmkizO+Yg5RZ6uy03o5H4jS z=$V+Yl~Ev!#W9a@*yO2{S=LJJ(g!lTZp8M<(i&Ut>vRJJ!xa0lC)TK3M5ZJ z@)av=#h`O0xqvX=Zy(BR8_E@M&%}^N8+qGiw-SJyw}z9(CPdukgI%{DMOLq#wx=QA z1mWl9T8p8hESv0!jPS*23Ikfb9A5ClPk4;fJ)0q}91$f32UJd>}r zT|N3Uc~1^yDxG}5H#q?F3lKcbv5AtfiEFt`CUYlP|0e4{(fW_ERma+@j;+dV)dpL& z(N-O2tB(K0N=F@vRFh(Z&26-~<81DDoBJ=e>~Xg2WLtKUEqkn=0jUF}^k<}KnsBAkGRgy`3NVF{sb~x&M zY$F_pjCEEyP-2d8u&(hGNJpjD>MHoo9MD7XOnP{lY>)WzaLp7%Dg!ph~zjW`FY&{jnSkAEF>vKq6rf)Bl6_g-x zx$wk-X?&2G$N->^s7l1Z5zCSnhL{3VC}3pmZE@jVH&?72(n7V4Sk^? zG+@e9frgS;kOcEo1Y{s_0N|^hZzKpFdK_>=kSo|A!8eZN#F8o;coO2O1b~46Op!7N z22-XF2M-NMFaWqpa4rBJ46zTi?BX%IIQ_m-l8&{ReTZugqxK_u!yM(sr$nilLEa9m-x4tVfQY%|zbFd=hD;b1~; zn*E{#97mhiuzlrJJFkXPam?Xlf}=k8wZ4nm<~SXB5MiL*ia7p}P~Ar& zxnQqpRQIU>J7?x|?Z)Gy3gtr%EOzK)?AEjF7wB2`3$%@4tMFiILrTmjD>$qD_Af)O z;*LT)x0NyGwkee5QbR!*^Z=eJRhV)+nK+g^7R7vEsz}wy^r0ViX~?OgcIu4p#_tnN zt$aFz{tV6Ky;gU6elfXG9Q&>-^y0?G%&x>DN81erUpe7Qec#r1aUXep+Bcl!i8O>~ zeZD3A;rI00+g8~VR=Wu4XxRe#v~-65alPLiJ6fv3-`Z+V*tTeMm5au3S1`Z!o^iJ% z4@`y}Mo>ESJyR(v6)5MUaCSC#jH$$1A{bOy23; zj9-sQN#7O6W<$v{{R?UWfU6@1o#~ja*)5zdPA{x)nBE5<(7}yD`J(+R{TaS@s&V$} zEMJ7qAxD5ozcKwzo#-k0C2FfrNf9xZXpbCllvpmfvMT@%`*<$A(}=^c@Tua-Q@30K zyOM^YOLP67yZ`iRuKe@u*cf@#!@KJIujQtg&hHnhk-6H;3mVU-6xl<7RmIi6YxNu| zCk5XM^7tJBM4sA|sg~z*nTzK&yLN;mhCk}s3)N_lQJ=>BaawH)WcIdlv{2U5eI1H~p8+dLq~-2tv6iDh>{o$#75 zpUSpR`$n!(o$IBpt5B`;$Caw+NIGa^j*>gnxhB1pm<_~c;E?@R+y0vl-9O_pwKQ;; z!9D?VZ_0kFYxl}@Fk4pgN417q19ZR6Dc-y^2(mm5fUMVSYY*@h{Lm49@sqvoB|6|l z1M+E9j4fqH|0t6W2K@?}G-9C)d`%x0;7!}?SM{$%(S`6mD7F#-98$rXi>*^u}EK}*J-h(7pnHQoYmJ$O)+M3!XCA5+t-`MgG zoL37+5v&~<8TP8vXuxiQ2_uaf-itwuPQ|X&^vLlRn@Aih=%qAlrQ&GJy=30+6Zki= z;HUhVxb}*My5Xn{-{>Z(DX|f%24A8Pt%^GVJBa+fR{EThWd+F{*QgQR2^mrNI4Y3K zMG!yA0sxQSNi73qz~G?)CKjMdc?Kr@h=Q_~3jkt(#$~Ap05TyVt`-tX9F#=iBC1S< zg6F@qro+* zZ!JzNtTK!v+Lk0t><7}*56s3s!^n8JN6C>q*XNW$uWtm|nfLw)4X4GWJe`o}!4yqR zQrb?x4KxpJVDK|G-butyZaDHME$he}U(|BzD04e}D}w3oz9qh62g&DiyVh-0ad`(x z1Pl`{r0cyc--M&7&Lth0Jk2Ru><*rGU9J3Un1lna+J}hYJ{Z55y;AD^kBr(YCv2ES zO_v|i*+B`h<#)Y8^fck>_dt{?2u$`up$BvSu9|u)l7(*zAE|Y_pWO*n1sB|%wxxET*l73$<)@V#$d>5r~Kd7@q z?aXk~yVdjx?ufk{<@WR=$iWviRy3Bge!FYjZq={hTS_$ulm+jFEwfY8lVNZ(*i${f zc`r;NTDDlvpLF}BFQXf1`?^c-O6LP^C3t%>i*$x8iZijlT2~BmEWyg0_#ce9k<5Fh z?Yqluda2#E!i_0m6N$|v3X|NXL8fqzZlvC>hl#P6cbm*AVs&tOv+b8<#f!EXQ{3%4 zUAdHbgDHh==UdXHDj352os;`r9RFdBCbqaA)*N!|n7=CWEg7WZdvWpYojz+Vx7Jcy zjiJSrwt0oE8?=iCY=6t{me%pX)iylr)_c$|joV?vN4jba)x)s%TV#px;OW-dZ0ja% zGn~CGcF~LtZnNR-i?_pucUX3Y-Ot(-)n2em^g;*PICqcRM^$+$<9(iWB(obe`LjW~ zQ40+(Td|1vibD_Nw2S&dD9|DzL@#K;uAm)ayB;P=;P_#j1p3&$lVs3edi@@H(X0_e zwxex3csz*YTkK}miz(Zodumsra69OmE6&9Q*SGs!^dCyv13WLT3Qz~?iDQOGbn?;6 zt{CyX_Z72tY8)kW1sJP?Tmk+DWMWbBQ^p4De%h1uk?Ui6yRgGe8MG9{qU6#?!J>(A zCs|t}|8I`jnC`vKEtMf(+3tI4%hu3m`t9e#ZmaovnW{rX$UA`ij+Ly281a)uUvz+< zI%E5FW99l;e+1K<^3|Kbxb_X!1KfmDD*Zl`NA6w zy6#6M8DjfW_j~rVZ9!L7mUA#xymZLk85dN!?1O^tl)Y1?PEOCZ9X?iek0Yxc|=Lb>o1YD?_Op zGut}sCg#{(3}D)wo#8r}&>Xd`6E?ZUZk(|*u=GA_13PTvyqzWGJF?cQTc&JKCvHr*4@}#UgKko3ADgkb?777rmieH4vT4i)I8Ouc zrj>THWZ#!DXUgvPKMmP6lEB`Kt?zC2Pg8cyg8jH_?9!2j!=LXUQ$UEIX}?rH{0lPV zi#pmd@`EZc7?9Vvcz?g$F=SJ+8$Y$#)-VKQE`Cbp;@>}RH%{Bdng=rF=2>Y*%@K(3 zRwMHFm3AX%ANBArMMqj?*RHnvhTT}!!*L%L(aF)qdHH2j9?|@y-8f;}w%WCvm}czz z+w8tsdw7Q(pjCI;OBlin{wPMw`DjxxqA8sZaX(39T;Ecaslr<6fc+g?g$a8XPowfK zs;s3^Rg&N@rcL?q6@e*R_CtPsSjUo8EA~jojoA;iD_cw+=bhNI#i>UN&GE5wOU(9j zQsxEyaEA{=vZC@-pjL4Rkym9BZ0+#=!y0i@*It|1ZKHM@m}Gy0Lc>+ckgAd#xT7F2 z7=nQ*h0F*t%HkRzLq z-?`unj`k_li+Ym0GwJZ+k{4^-i0zuST^M8JeTNZWH*Z8&dBoQ;Y+2Ceb80= z8nMe~?Q;GRoTvfY&P7Y9oxgs_K94dm`V0t4FmWs+^RJga@aMUADf6dq)@#4B@Nmej zW&aX=n-08S^IiM-nEi`vi5GN!?Nt9VUOGsdRrDoz@8AL6JD9LN^mFZ0v6jDAPad$Q zAOZhNammP^s+P<}y8gLSIue}qaynQ{demPhYnXvcxDtXU4AWhj>vDZUj#dnF-MnX& ziLq0t+T0braLz8IS=bx%it8%hmSZe^x1K+^zipTBVCz$W$uDW`v)GK-(sJXuJUevG2BksW@o&7P=C|>FZ7O;%Qr6j3LJO{OHN9PD;euSX~x6&HhiKtYuQ6!U=Ju{N? zBM{W8pMN|(Pkh6$y??~UC+%-%+<@D7*LLf9;ve#41{+bjR==NrPvosGJ@PU#YA4d8 zc(jY(!D}z+19?P);?N1H$seN%sC%(+aCu?SIg{`1w^v|_XUHxbvFqA)AxrRjo5wN_ z>j;+`w)ocTx+%L*>+F?C%Es*7vZ!#E_VawgN&WV>nY~JT8?-D=jm^Ba7O(pCw-%G$ z)SMzuh4;n&0W*E$_6O7cQUja^{vF%$3v_jbX@UO09-xEeC7vassZrL_kE_(|Io9xE z)Qs2*WC{RtqwoP^*tFZ8KR?T{5MaYQVqgO9E6|TZcVNbSYn(oLD_sEXLUPP)4 z7xpFekl71#mf`LRk7)cc?+mu>PmZ=*WJ-c%j+5!f*yv)ybjtpieDtUpuP~fTS=wVT z#C&h89R&?eSq%9(m6EGyiUV1x=3q)i6)6e~1UN*xO%%ag1o*fztv;E8U}_=B6AX_0 z@yRon15cyDqho)|FgdPm$8mI>vg3H!kPX9XAAtTO0sDk)J_c845$xxA9qiolunx9u zQ~Q@G^9p0LtkILcaiX`!T|Wx-vKn(haP@Tz?<6Zg)CU5{Iw>Cjkb%L^7VIArhJz2f z5WxUpHDQ!7+rMeZmP-y#~@_En&7QpcskKe1>&O9QJwE~%eAyEf zWZ-il$pj2RXsS58rzi**`vaIqX3k;m%Iv2@c9rgcyp0=J94JQZr&vqo8VKjCDYxzX zA5tB`4)&iZPqK~7$;!(`+l13-sxw7kPO0aoVATCMl3pqUqhn;Q5HZ`u|gk9H3A79O!xq}DiJp{ z9T5`+1_yDSFd)N$%zJ(iNxIkV zLlzDsu1f7dl7NXNRW7nxu|$Ev4+l&_$Z){9d;lDn2o@;`m|6}Da6=XV$iR~dSEfv$ z#1T~s0ERx0RZ0>-5I{*RaNa`}Ng52iwd;RFxk)Lx$>)?UMKq3rfbp|bB4w3A=E4&M z_(9iYtPvF${5oMW(Lh!TLll^B0apqZ>3cy2CTPF|)bfb}CN}ROE>l^7$Hzg|k%Og- z-kR$KvPEh5k#kQIIr#0g&~fGA*G0GaS*iX~Mp$AlbL;0Z=7^jXRo3^2s_IczKO z2JeZ57;e?PCwYTd7Kc)DC?f}=fN_<4kOAa9buLmWV!`9;lqyq@B+%ekgQ&;&t5feAc*Etpu~s;8q81evFbMX=K&T*$@0h55{FP)-o+spy=` zQWKF?N15Z}2$BPi3~^w9K^DrNAdX-yd?_Cclpvuj zM1c$+09VKbrs~NGJh3FKMGpZmE`T~ABM2pF0}0Hm^4Tr+*+Iiz?wPvDQl<|ndh#id zQ}o-VL-tMH*PE~tru^p1iDG@qHMRl;J}UoF@#q zF{v^DVKT7m<8%{wLY5_(N<~9S6i5It5zKo&2bfs=QnA3$hXVs17yx_(0dSS@MM~Sy z2U&x!d-BXvr-B9t4Y2^EZ7{>4P!IZ-1DHaT_N!t-jEC6@_qHqAE0FXox!~s;o z17v~xC4nidD$couVuJ=4SEagv4A+T|3a)$DSP=7s!#mnyeelm=o}<0cOq&UV#T#-c zl@FN!;Nw8z7b*+C34+8C1o_OyiXbNl7)`+uP2UAgm8wdTGJVBjawcsup>E18G7K`{ z2!>y(ti@DL!xUwg0Z;<3o4kQG|hZvel{RAH*7<`cU zo%E-GBM2s!3rv}aNlR4FLqKc+*@FEU9VxTVjM``7<%N`w$EFI@Aa~fld4HAff2#tO zk_Qbw1bLrdL*RJmcIh`eR}l7l#;4Ej0& z1Urc=VhIvk2?;gG#sCD@ZhAn#tZXUPWR(qYlhYby`VqvCfFyZ>!89;Hz!2cF^s%lYrDrB;A))E0 zZcY$-?};))k`5OgSvidKuH6nktqUY!k1?klNQfh!07}75pjzQaEI^fLAjSnHvEd*H zR|{x}iOWbQ&vPl53+HQ96y(0KgH%&ku(oD21$)Tb+WP)CeR2#)mTCG6id*TF$1v9BIOg3(>q|GlZ2kh;tGm z(@beWf+1G+MzU_eGNq6p&N+wx1n2U1M}i4P5~!slfu9)VI? zFlA5XK?5DT1q0|C-DsGb6qTo*0~s{907w|YAP78B1c8ag1!dWjs!mbRRLU6)1iA2FvYz5V zLKc)nbrg#q0F*__tyC2B0W>rafDHO37G##H1QLfOc2^QcAccTQXGZRp`kE!}#3d+U zhB^u&eiRY)GzoTnM`Ui@54@OIXH13A1Zyp55v;du=xZ@#Fe$uFrh}KcUJXTiZsdUC z*?`-=K*ei=h8SA~>Alps6ufg>2X;e!Vg!3OA!g`kuRN@xHez(rILLqjl6B?1?zT;Onl zfgT4YfJy*6Rm!s=1ISb6frJbPTqH-ZO!-7CQ2@{cS=AE+ z4{_jw2ER}#;44uQ44O_@4##XbHp6+}R%Y$7ef_ewy^I$PQ1q2S`vYkCb`9N2*TfDr z?3O(po&R88P~4b3ou>idV8Fg$^fAyfDP5qLjRnp=Tc+E%jLq8;Gwn7e7PLFyr=j^T zJ(&x7G`idH{6}0F`24orhZLUc07mzdD*{ymh#b<8QX zRPoB{qE;a)g(Geblq2fX5Tv4OdbnaCht{XjCR*CQB&|XkjiEFTGTz+jy2|c@4F6wg zZ-nNZ_LUbs9PXN((6$pMeVXEh==G?P4BATu?2S^8z83@R+?>*DhG?k1WWuh{QLc-T zIw{!jvf*~6x=26KtAVZ*%FO7g>b~BGnSR4O9eP14{1N$0EnC}f-$#pb*gx~!cxneD ze!R^jMa?UC{ba_THf!giPqkp*>iPj{t=OIqNoN&J)VTrIJbVQj3nO+kr#}>vCj4#p zkImZAXkE^`76;`%D5Wnt4_yd{BI1Wo;F+`!p|QiNLZ% zc2GJRdQ%*(iPh6K5S04ZTuJ^^-(JZF!vTM;=aLr~i19rt%35N(7~?eTQLa!&iL`3p zGCPlTs-;K6b(Mg3PS4W|o^U6AUt^FrGDdhL9gU8-gD~lgAismK%m?@#1IFmyiFF-v z=8gt$CG)T{3!kJIUl_OUw0FNpGQZIA_|^7NX@{OLYJ0cZu^gWy zUc^2g?532K9TWF1dDMn2jjZ?VMe?Fyh*7UX{Eg$V_08LSUHihA9W!p9KpeBeZ}|QM zJLl-o#*S;VU-wu^BahinP@RR#5#mK@Q*7rGG!0(LRZ!{D%t;55hC-K{hC(;qEmWg2 zBwi5O7yKYs#o;MH{Zs!6>K}Tid|eNFAMI$q^f{TmJ>J+|=V~NxKf`{)GrJ4+(yqO0 z+%AWMG-%rfY z-GBqmX4^I4PuqWY)}E_+vfus>P0qXHdW(`g!g-kw(S*F4n=ITW(AgP544=mLhRZcn zJN#DlaDY-kB?6F;1u_8W3E~I>f1 zw4K=J>RUOQx}m7RA}+onY%3Iuxh@Ku6rLo#=u^7KeG!+q(V*5nZdR@{P$V95Gn)r= z*Z76pHAaQIWw-P@54?^jDRS2$C?CIg8~T=U8|9*FpZ%roW-^C-YruxoIsatX&Y^3u zg9=@7ZjW-eYm2|wdk!6pZIv!|v1YwQiY%4gyLwc1&r2%1JEZ}8NE09}QclFetQ>3e#ve9Ba?b$DtT20xA*$=E1yE~eQQaEe($*SaHS}wM?>`Xmg$-?Tw zAZ+eQ81(otJ9FGNNFGFcev~}`>;4XZVzTM>;G3qd)hv}TACnIprQqkn-~$)&IZ`Imp*}g(ankqViJ~0o5?2#fCGpO0fG`F82nm3+l=`Ed#1MWZ(~Z=7UhsMu{oPO zU6)fB!td7xe(SXTgbfM9jeW>c8$zp7&*a_ACTEqMyV|}^@)0{?jeSH{y@u%OTqD|Q z=WesF&)G+2?FbE3GTb=kkFUjT7naDJ*O7FA{k_yGG55ew&kSAbReDx(tIJAw$zp@J z_k2aZ#Em=MGh+2ovZXoe_U-w7?6}xvodB@Xma?gsw59ATc6dMJ?^Ak3BhUe~YjqJ% zW^d(s1)bq&XC=LrEf7~NuzRNY1o~2q<|QToxDbqwqn<$%1c3qBkt3=WS(Q>j7I4tu zgCSKQ0l?tnzz1BWv;;fC2c}N70-r0YQa<=Z;g=+gdpCkX763zbOWSUtxu*OgKUUyg zo#||=dyfBOsr7SbmNknJI%2!m`B;O)!&uwRvPG5HfUUG6*gP|PGbghFo3taC5SWnJ zGq+sBb`@_9ZucD#$LCF{@}%uBEu#P&qlw8G)n5h_L(Uw8GFMcJ*SYB5gwly3@x$v^aUfp&x?*(rx zPTCtMT#@F!8C$c>;0(N)`!8&9wUV-h=J{zqYE8S$G*8W#QSHO!m5lDWu3r|Q({j|M zZ}=C9tZ4gMP^fOG`R$r?E36-D`RkT*aXcB*fjV}%Eql4%0%py6IX7#VXE4IRiLBQG z35T+lxQ;wMiL8)mmYqBePCKU_1%NB$sOC9m6yTC7l%)&e;V~%gk{o%tGiF& zZo-6JI-?(lZIf|Zy~Mt-+`8)FkF4-t04E1yH4igA>axkDN7)zJb}4=SXggB7-|l7~ zAWWDpIhwLdb!p{c^{D%%?cbt(Xec&UzovBHr1W~b_Wx0H23>oliw@7$-7a=STrFqf zy=d6JnAwo#-dq!Jd(?&|{dyo*z0Tfh+%9Kl{>53#)d$X2#qLSn!2ccnhhy5WdI7WI zTqfxWT?NL)81i&hOdk5-b^{3|Qkhd9AeifSlUr2SvsFipAbVgYB9arV=*h&&Zp>rH z?HVP_dlFU{j=*Gua;Su_m4D-VCQ)<6W-C1NV@B;5j#^3;1Z9E=;)ucriJ!}_(@=_F zC;cokhbHI&BDNF;8iGMd6i9+l1`rtEoUfY<>h+nuaMWHXt68KXXJ*te2ZNu>hX5FQg1{ZQGPq%b zwrPuTUZ}_IbPm@XtNU$6ue7sy7$hNVw3gi<)sD4r($MP|vm3^(HDbR#Yrn17D>6HI z)J`UrdU7RA%f}4&&PcA&an+!$72lYd6U*cqFfIWHxN9q60>_;o-3EG0%U(KWFCDTE zx7{Gaho|jNP&kjPsVJOt$(nbLc;RTlp3CQOfx2a9utglRGk9^V<=4rdGi00Ewn-OZ zp0nBiFWj>^U6-4SJ(X_8aiP*TQL(pFZC?``PSy4gSgAFm#sb9Y+vjll8;8eO*43j< z<=PRLIFfMTbif~><58!0yY^t){xyy#lP=!kB~YHlyq?F-n1rY8ZjQ-Z-y3vu*$Bco z7#_=Yv$h?J_>3!iTWl|@5(_K0&$wDUWyf~yN4$E_wJZDW)2nSnreFDl5iGu{W3)oJ zHe{b^+uu#uXQu7926VlB!oI_bAk(ijHCjU?VVKYvO7#l9%SVlF5i$qPb5&4{Fc0e< zvf%i!>|($H>kXKNXW8xA<%#QfxiYEMqsX&THv*6T9$Z2(#xsUjoJ%jMSu3rIy%5J>!rp!TcK z*OG`)pK!SdpdnbK0RjL%2!M&jfe8S=6bu2e;Xw8VA*e*t8w*W1C~?pPkS7%*V!>1? z^IDmM0pGa%3>!Grp8Q06G8;=allYt?08rPIzAif-Mll0~{fYB1k$a|m96%(>AJ=u} zeY&tbqRjJD9|{775?3jzkWbKoC^TUp07(=s5|TDB_)S&-0Y?q*O&UV#qpd)QBlg{T)vb(5GE9=0 z7gk1=HYQu5!jW5{_OBD)k5O}f%y>JT`9mzP&h3wlD?0%;b&b{^`vG=$Qu%AKz5G=c zfe!tWMW92;A`pF&F1ia@q3)y)X7&VRNu$mZL6mSb=h?2^Gv@0KyXCo+u8My-3oATi z)>gzH>)dk7^|8W=r3}lC53dnXB|XDea=IV34WVbq)X}!@Bdg-HC2hkE+jNt3hZSeo zgpSYO!{7tQSgeJQ`%TZU=v|2~x9qH8yDzilL(a&(YK`yezdLHn^~S{S%-DT%_VQV~ zYNxfP?7OP-S;_c6e~S8CIcO)bj>JYc_ z@z6lbW<@W%wcoBDx3l=m1HM|ViQX8lp@|6IhFn7`6-7*a#c@Q9EMBEeZHMBbf`O z(@J^EzQ$>Yl_d^DtS@3b!tMVWH}Q2Kih80odIlDvl&V%Y4xiW{V8(l0zZ=F`tyk%Of!HNr{t~F0z`qqRq_jswT7%trDRdno}x>&0ORYaFwLgysj4Rl$)Ry%3#N*; zO8G~^T1fl=APYy(0gPiTvsWSz;S$_{oxa-Mw94)3Ae-PseE)iTC6WV=K9O5CKqa3+UrW!sjocb*J+Q@+jP;L}Fb!m((;85-=#*&B1<;;Q)DM(oHT+r@dGZJQ)7e*b;KuAQ;B zp};(AM^3qg2iB|u%t$-kbNfDi3MVYtg2Ncmr!Z5=f#OJK zNAStJLt@3C+h(7dasF6Ghl_1pdk-&vN%F`xZxy=J9N8GrbTA$QV>mFDdsGc;cn&Ze z*a-*ELEAza#Mut)2Kf=}kb~{e!%NAZuxMXy-zk=#YR5m(`Q!zPdFQMg z4?rJ76O#Q>3r$ES5H^b9Cv2PWlVgr!2y1>m2idX2g51!*9p;b5^4m36-;R86-oAox zZOR^!l<*W8+F*l@6s;u2C>M_R_COXUoviY&^dXvVVRvN zK0LOwcI)YuuMXQ|v9PBc?qS7TZ)c9$S5J2?-1+L~kA*+ag_oU17h zmI)G zYhic_EgH8p#aUSPVLqstHoARu_)0TUM>896t2C z03^v19-vmmGGWR@Q1l$qIqy7GMt3=AL(r07x&vD;-UueS7`Ay-Ns_+L$@D9SlzC{7 zp(IDrR86r+4c^}FwZ9KAF-LnMMW`_&s^}U z2ahB>Z2M#y@eO=n*q)lOJG#!s{2^Z?G57Io{KW3-HLx=)zMmV|VL-u5PQpQKai9o+ zaBu|~Hu6CjQxf9TseLkl%x)TWOFn#f{DsCRmZl~MJurR~1x!>fS1LC!1hZ&8VJi8M zMJi&!G&Gz#zcOoINtECrBRMXTl)^+>eB2Lox*;|klvPiLAi)#~LsVecFD<7OX3`^kSx+_u)Jbf#lIw zq-u~P@+3ocN0(s)scU~VW|zrY6h+jj4+D6K@&U@F{+?qWj1Kr4stIClf_^+y zoJ`cpQCqp$ZQim@A>CLyZ0l$I^zpG&TfU3M;zTxt7%ak05pPn%yc)9C^1UcUPuXi1 z{8?mlhhDqXwhvj^wsM_qpYq1%jK!H5Ip6ZJJ%gXjKjO3nw~#F;a18^Q!)$D0hV9*)VPp3)WA9dLXH5@GLE4`RkdUZK zzotw-2xKlKm`r3H`M?19d2-|c3=+Q-0H#i4l>lP1L`GB{4@qE)4Etm8oWwD<@>pBh zv6Z>4{Qrv-sRmL-Rfghnpbl|F|4j`fNsAkuVC?^rrN*jKb@&q7BC;i7f5tk4k3Pi+)fHJd6f{FEQ zTOR^JWNpYMrhH;KfnLO962^Y9^s60Roib!m-i6^=Wy`EWww0nN$csp&QvonV`Z|IU z3o&?tK?#fl#wV&yQKf*QClxTU_{=uGFX}qa;p3TIIO_K0K+f@eu(UqlmOq2t>8L$} znq$YWZM&yzH>GeGR9T%=DDy*=DxYUA2jq*gz$|sc(Xgh`Ltv-$v~_lU+y0u(68hK+ zwpV*~X5-z{_9<00S3+{*Pwm49;gnl6rNkGfvdI4!1Y078j8Y0YK8n%0bI9+5T#DGS zWkZ?0c+_6J;NLhfW<$!MlUjy^ltmC9M^?ST2F_GO1c50F7-GjCy=a%CR1hSwos=O+ zV94^Ge@75Jez;sozyOdOKj0iI$0;{}$P*x9n`~<(!3UouA0SWV0+4OwTqGKj1LNut z80qQQ%ULwz5K1$`fYOl@$;a5kPT2#~_V1FWah5@p#@@-T#)X8a?MJGzxzWP}%R0qM)bgX^6PmG!y=!s5*Dy$# zJqDd8cEym5w{4u6WQz-P*)X3n<@Ojk<-L4~Ti>PYGQH37u=P>4rR};*NW0L%nA_=E z@vB9-VTnyGwVg7T4J!lrFtYT{78#&#l|nX{dl{bbZtnqdtg!90KcNA=Wg$qy zDEEZ@4_YbgpVLI_DA-7>bv0nuKZ)%(_qJ9^?PRO;jp6UXrc=-HpQzr_(NdCy>PV=> z(_G>?85-~!nISt<^oZt~yh%w(qP z;_!k>1$&c_Tb{B7t`Y$-#D${jlr2HMzKi3&^rz*WKk z=OTbOVk1eNa)SUov3bgns6c|r1P4%x5@O~hW~2d*3^Q(A{XnuLfC?PbIMW(4z@kVO zRtCHa`Y?lwgEP{KMs*X}1RHM@P^G#_wv>e*0I=&Vz=fs)vbO5euWYE!0gTum&e|XL zFo&sOlQ7rp@tDjt@m`>tp#`cM5*Z`CVpl(p+>KET^KF@32BT7J;aORg|Actj@!$x{ znJYMnKm5pgyG*RS4qReAJ#f)hH}T420ejJLf>*4gD{OquEZc&UFH`fEOxtemiJ%NN zV7v5qD=#Umz$|m(BwxW(?`Vi&rFqs*UVW0^F^jTed7UnjJRSD3zK(XdK+={U&-#}5 z1G*4LvvgX%bl$@!N8ZHQ5H&^cFVWwp%`4FW6j5SQ z5}i->$<{iEi!zNIIkxMOiq-_Fc$_qK&{LHJZJ0%EceTUB`WUs(6hGB}u_~ zTn5iS%obGL@7u9BW`1@03}lxW(~hT1)-66CaNLCbO~}r8K>+a?hP9Dw>T#0`#W#5K zw4JZ~`Ce`T-^s$t0~x%I5x+0}yE}QiO4Wu1!D78yPh+@#U9VnQ=-Q=QKb_FHi`4{E ztEk(tLu=X5+)?69%*`$XMeaGLhck{I_gC=v#yYKuz&v@}C!Xhqet&G`O{4av(_Ml< zBfnTu&JDa-px?pffh#abjWGj$KgO0P{P26fp8Z-qZ3oF2;Rr_?gd;l6FcR6KBZmc8 z%gTttOv`4lHq&oE9rj%cTalF`)?MQpl9e!L*nOcnGh_G8*}1cRv1lbS&@tCdLi!17 zV$*1exPvw-B@7=nD%_gX%MPV@KFjrL$xQ?H3F?L#kMud2H`pHhlx;kZ zl}y<57P|@cPF=vKxM!+vKUk`(bNb7%r(&vP1f90pA3S1Xc{{t=BVBHO`#Q^X>+Lkv z+_$MSu8)M7aU?G=nr_z}E9O!*pP$xD&g&Z=8t`|8Zfo0Z6SjAYeQ3&VqZy~|s>2^! zc_Ih!emfK|t+2})cA+^_ABuU8@ZJj2EG zOFz$5%9e4PgH0^c+82iH??&vLA^T$6zNkBuUtrTXV}Cd6t@lNkOS;){<+M+d!CSkP zdpa#U*l&NK$?7b4YrHr!V&4cJ+N4i<@6yKpEMA|P^(S~(91rrK0H+d|TGYH{*Yw*E z=J%;5_V#&*dCaaEw+r-lXsb-Fq{H*Nfq25_>)E~yeAw&qqO-{d8~p)&rIe+o*X6>Upd>&@eCm(pE%xOtg0e(2CyZ+!8WZ+2DgV@CcA7HeFW35fZUNj4<%qp_$oBI{ zE9SqTpRv1Vox!pn8{qshel9;$^i|X(8YCJ}J}v2uscbu%Eumx|^=WoW%ysMS)4K2& zA41V3u|2OQ@%UZyYEqjWgiObTgOXd{h{f#Oih2eCJ@TF^i8=^Gy-_U#H z?gId`${IiKUp?oq?Oe^QqW;e__nUa)M0!W3GYWX#FPj=4yBRCJ+m)O1)c8#9#n&-Ml%eQ|>oOywc3HBgMM%#XHlZn61TEYM%o=wm~U4Ehe$w&tCzcpgiAKO&dS~rmW@j>W=xwr3uD6Fq z?M&XWLKz0W0nd|l?N~AJc^B_y7zpG*$G~O+>x-H+Q?KL7A<7u{XEqzF32&_M)1`?) zH)cVh=t}fd0GMjy15>LCAh9=VVFC{fS(Y#W;6Va}BUnT%j|el47(3{jfnly-T7c{n zSJ~q4&?h0rMJ5d45AY)hvXH^qNUgzg!#oB@^o44WJKA;!><(1TwYqtmFpbkJJABmN zAvWo(W_Xxg|DDRPn8vP;Wi&D;A?2>{lh-SxpK~3{+_0UXr!){u!>L$&N`seEka^Lz z+?G{6sVZL=)dr~brDggGVyo0XL6#GRtszp$L@h{YaCx#{T7>;lY)*z!;;3EAycFt) zqU?}oW?vh%uVJH71(lJ5YC={J;PONqMG(Y+FNMd?8IO#_W|T3+^ccj=JpCXeLO1jD zLzv|WgFO02nQ|a2fGS)VWI$^oY% zjt;_ zP)qB12ar#DnlkxPyZ}gXY4CbkWYw5C#m1>@GFKGDJt^i!y=sk?+LviVu1&?Of?D|K z2A^7KFO)%m?@ZbY^;SE~aC!^!CXQNtXx540Pi{DtA^#$MY?i)}&+$4a3M6C@5X2G0 z1<*;IEszY%jICx*>>@sqmC7eqwj4%Q&v-MQ+><8+b!yBk;Q{iL12BcM@tEW9GbFLq zc7`9y=Ead?uM1=UwG*ym+18CDu32%pb*|qoMq07XpDSYidFx7FU;et^o;+e3+xFH; zUx_wyD|XEO8vSIHAJ8O`a>5LgTi9~p0U#+xa^x?=oQoa<;#E_4*VrDRR%L3Xic0EK zMY&&QF&*}e*0ZTV+n&wB3g25hZLiF{ZxNr3P!B_e)Ak?mqxA6W<5t^6tNe7s@rpgq zI3`Eh_I@-puxPZ^hGu*Ux(M4Nh==qbEM162lU6EdKn z3kBNxQBPr_f+FVRH`5bc9H3^p_F?HvqCSyx)=r&@K{q?%Z$@)oX2v_fd0FZ}NVl&I z4lU2Up(Kx7FFoSMbm#p%GbPErs{dkgLFAq1gr=Xb|>GZ+g11S z)zkKtmUDYJg7u5>vY~Ao#CTzI4jCuYT_Wr9BL?h4X!~O#Y0SjSRiE@9SL*i- zj{754j0-jlPan0XC#B*_pIOSMJqrQ&;JKCa7%}cHL*W_r2rswlM6gL4>`m+JF`Ns~ zbLRC`lYQ*Xasb{oJ{V~k3s*2G0*24IDy4|FI6^)^@v`U@R#QCLv;SxnBv z(i0dv00mu9ddMG#?}5Iq-WmLk`V6N+#>KYZsOR${;e_AP{f?MRwJuFy`@%)cVjXv+ z+q_T5a~Lx8O!REG>l=45dvhwM?oGtgnz8Vxai z0hvsBJHysM_2~De?VsapsOE~ULMG&Z^UrVDpjzw{F2AS&OOW~<@K09L^2j=Q0ag=u zr6ju$eDgZ6G?Zpz8!&8tB&O?uH8ug?b)AcSu_ILQ&hL!<5uDiz9p)S?=(FLi3Niz)8~*6 zt_czaJs1F7CLatAxDq9?ID&!6QxU`lrdFyT>j()AQTPOd47dy=atfqlf-@nZiByFE zqM9HCm4bmG3I~#4IN%~>LKHBVGGz{?PDzL&Ndy51LWU1bCIJvH%j3ZRD;zRT=;y3YA0Qf3hW@PQ7U{g!4>kW^vA&v6%J$}7$ESEO41OQhxbpC*C~^r`G2&%3z%P3efRs@ z`A;S@naqDO17tEu!2gCsf^vzPnanMj$z0+TZ_yVYIWG!<`YL*C#Z#<^K>j-*1PY2M zyilv`O{=0FTdJjs+ya6(w1St{QmFx{qP0~iFCua~pWpYF_4kix4}G3UsLuQjd|@Na;eQ z6p`O5B9mHKf&rKuVls)zkC?|u^VkYar6Z;^00Of8u}F=R8NjqqwsoUQ>0FS&lK?VP zOgbK^LV~&kN(rUXt;|eSs+7rNp)@gRY7ytENSXxID+ThKsWsB^7%};g)BaegH5zFJ zN=XAuoVUFt0HTz97?_xNz^veWWTiW~hqxyh*is!xLZNmdO$(JCVP?W^Jr;QZ7Yb-~ zzqM{}Zu1TGR@r!N6q0ttgne60(Pr89b$RqNoE4-&;6=Ow6ar-XV|Z5VwR`Gz4@dvF z-2;qhD4b1gNbLYmC_}9xwNF2J7coVi24@3@p*l#KigM+b0HB1Hxkoz~Q`^VnNn_5Q ztFJE98Zk5@?Ep+u#GuWPHXHPTU(@4xgU)AYrk0D$t{k*0=UvFcW*EM(?o3{=zJcxS zYU`D}?9_1GApGhZbM|go-L{ZVUYg^wMgx+AX@gfQ&5IzbMg+eg~GbxmY8G3X9?rUQAF+<~8nQruD`4(QVB-!(A}+vt36Hy(tM!iJAQnTQMj zO_CRL7&Wjd6G6clN|zQ7IR}g*Xg`YZ{ z)bUZBwpHl&R(&9M(4!lG@g{tytAubuMEix{*kVZF%dQ9_?G_orz^`U7xBB#O(+v3s z?p$!Yb>>Ek-9$Q1v)8R%X1#l7CxaKK1leyf^q^z%|G;GC=kgVN0+bzFv46NIcb1{& zOGJCG%u7dcDkxDSeg#J*Be;}VirWxa3TY^snyVor{yUg&5{3A2zsZeQ|0SH}wJWC5 zTWExq6DkcajqqxEUZp|y$EPEld?o>_s;N&xH^aHa&%G7 z3HluYP^7ej>C-AzM3n;b;S5cQ)D$1<-<#k`(>_(mDM`zM<`T#vkP|4TK(NVAgaa^C z0k~4dLUqY$Ms=0)b&k{O>;`}k0946SU5v!LmixBc)a6H^EI}i`l0;R-<;lYwDP`#N#yn?3UE#yanxKamlv7`6uYSj0M z)eJ|SA^^$&NW+*bK^!e)dIgUpj!o&P!bZm`@R=rZzC~35`6yaFTpcC&LJiVdGuoU{ zx06r8$mcWxR|juLip`S002w#C)2Lm54lSZ>`3~9$PZDmV+y`yMT{h=0wP%ySD)@K8{Xqz zvIS*sdE`Dkxzz=jU{9%i@ZORgX3WK`Ac5>=d{LRXm%rUGI`F-zp`%xg4!4@03IB?? z4p`-E2OJ&GKzD?rMLY@6f{;o2&$|kAv2^-yOe`I+{^&MWYoU=fVhdB&&u*!6kPm@V zIx%5a^ZCEetyyMA^x56osB>xN;MVMjWVP3FYj$_C+WU=LGsdmU)vY;Apt%^0ouC%X z)gHTg)ZYl3f`P?D)C?PV98&NBM%*u}BgXO;g>DZ^_@MCY1o|{;2Zetp*gnt>UG{&- z-uWjH!h1`eE_t_IzDs6J|>MRTvChZAXEqzLk zIF3$Jor=x$?KED}4r(gcRwT;{=WfZug2~Ch2;&P_RgSv`;@aWDonyt0rt=%XnpQb8 z|5)8Z!W^Dnu(!@R7pn%_AL{_j3LwwL);k3intuCQCKCfmqA^;(TAF6y$)}+UA*C8j zJHI9=KiJD*(j;VrF&}s(%*M>A@?&Fj9(448FZ!^!i>yjV zRgMZ1qDyK1a&5uasWy4Cs2|fk3^oD=w_Qm1Z3=H$u*X4Wa3Chi0u&C`#}|bGhL{p9f|i)_yZC-N&|V5#17us0O88(| z2rKa)J8s{Vyz*T-MA)nzdZy|Qs0hdgKTaZkc*_HABJ2}dl4yj^aw5dSVfwjfxLw@~ zY8~-Yo5t4{LgS08y|wWcNxXH$VtYLbtIO;%39UeZ_?(*t+*QTvX<^WAlE(FA{L?9W z9AOqBp?NoW2L**G^c1R$;?S?B1iv$gM~Wigy@lsNTu z^j7RmRD+%kdlNxhZP-50VsC0Wb1LonE&kY?OP|rA@&5~f2G+1{bghj+vuq;cmLb=&@E@alCeKz<+FNK=E3Do`z^2Yy&4!cXWR~;0TN&+ z_o_b`oopGX*6hPw_WjH*O_r)?#&!?drD#}%u_`o0qKq)}1Z90h<9z(6yEbwaHJ*z@dX>k~SY`^P5;8 z!atuQ8;5DJ3wSACQShZTdjzko1NOjvzU|!>k*=VraT%cC&O% zZw}SgdD~1oNxO*-Q`ehKF^Mw$MAB9IWYU=)iCgJhr7bY@gq=2A@LBOx&92hHbUOm9 zm^Sj#a|(8#h_RSLD5iq1GLg2~o#SrW`D!-pA-f9QS8nuJ=B^{B$80?=XK|yX3Bapi za-wUxn{#T+zBgpM!5F*TA!q#PhC1m4HTWub(bjw?KZqZSqB{rx>UJ=GK|Ii@1NS)4 zPp&70exR2Q2g8xZ4o40jgiotJ?*>s>;ra=CgeC4-V-KP!r}@7dM(&Kw=<0zd&?oG% zle_JDq4(QF`u(JC7fR6i(?M^W5%r3%bTCbfevj|Sxb5RB!w2PkZGwne6 zOgmS-f@(nL-;HrJ0Up*I;QYcmfJNt<8~W<(U6gkC*!IJ*mw)nX%=%mY$>G>9`i*aa z`;i8uWO_Yz=rUhvu9s)1ry-Bs8pu(}WQVK|A{C=NGsWG{`w!cAXghEPVX-%w@KI(AKk! zNVZ;awHbZ*Js$G;DQw7j8e|d$1{V-M9EH$39Dkr^Dy=vlITrO(fB}-Q22j}_FCUct(x_P2C~fnv!BgTfCs zoV_2hA+TO#lEZ<;C5hZkgQvB>rOz!PyUcT-5onf0!EUw>v(k#F7P&CD0gsOJB_v{W zZ>cRs8=oCRsuAGlS7d&j6Efc$2krVzuES8V(P1PqW3NFC2Fb5{fYUOBJe$TV*|I`~ zkNrwI|FCrU*PrXL6R@_BgpQT&I)2i)`y8IlM(qUjYT!dIIGzR)_yk=QxgDd&kTQUb z2{9oai3ttGrBve%*DZDA@UKxa*~*cJ9~jp4fV~4P`U71Mb|r3MrtBS39f`Xh_=B{` ze*ujLCt(}s(eY&X5^6kNM5gC!CX_LgJFI`e-os@IQ}&)Y`-7Ujw$DzQw3E=E8M4=+ zGr-!R1)635XXn@W(?St_PE(H4#Qy@nfF5eS-^@J}OaKw@+*9*h1`W0z!v$Uh`ZQ}z z{Y@_8?v?ol{dtUwIoO%8t?sj3f$gw4Px{Qy<8VhPfVCI;A$&-O3u^zUZfCA?5y>CT z*}Ep}pY(Nfph*H5rPe08F?1fD$^N}|cirv=*Fta!_A+JrkNX-wF_9aeQFZEmHcj}d z^<8uJKFsJOl|Y?_KJ>JyEHWC@iZO{qL;DHoDvf!rM3#O>si6amTBOM*L7b=fnpxX` zSt#fJ3f~(Uu?{Tw0uO<2lXQfDrx7X=Hx+1&bfd#ww#r^cQHSNLT>1GDU1WcWF0zOF zQSq)0d;WlxtL*tw<1h4fVp^lt2e=q0^$p02K`@lRW0mi*yagDJSE{2S&tr3u^BkHA z-a>SS3C8SF8h?O`JM1a24p@aEfpdWcWYv0C8VYg(fW{kbAIK{rpG=B)j09=&uL;~K z(6%nO!Ffa7#V&6ccF#yJ#i$K8mB=;Nd6H8~h8I7U?AYL?kZikg+X&BawI582a0ZTt zMxA=>3ER2&X2fyw=};tqc7{?8d3VeQiP~8&)5zKB3GS!Br6p%C5oT?cgdNmcqWNiX zJg_Y2Q!Iv{Nih^cm!2gfogDU}-QnB`&rYZ{cH1~wWB_-`8#6mq%k9tVG5GWf|ldpD-p!T$`S zY%H?DxO8zLpXsM?Xdi*9F%BB2IH5oY{g>$=bB8~W^HA5*D_`XiA5fYJaUhetw{ zU@|>YN}@<$07RPnD55k^70Cf0ibxPBB`%do9642Ltw>#Jcl(}NVL*C(g<-Y!6Pk14lzwN^cb0>31m`4AWc3Ya&l!>${|f@1k#z(Wts*> zs@PP1mGXH65-NiKYTzq=_>nNRw!V_D5i-lBbHLz{mt9@|o?<9SYVE z>kjq^1cJ77zcm=5fLnvLnd1f=OM$h4OQ<@H#7n)k!~*q98JmYO<0G?n@r>P#JtOX7 zu#%9g(k7i3KLp^CHO^2Z9+7V^> z6Fv`g#0^L8yEpKi;=;WM@}F%%KKYkJ`$O`xCrI20mRLgHEwb0hdi^e}PQq#?E_Icq zOu5otGh}zkJ1D)X;?GJUiC1YQca0qy~lb_H_SF=vU;hi);)qCdcpQ>AYylqRMHibxQXCPDCotPD;;D;oxa zNRLxkCajUAw$Nq&)@$Fc+qXB_!nl2V*!@SX@3j?m_kF!$!i_jeSuUT}Ye&}IZ`F}9 zPyPb;S#uV15Vtsu?F_~icM;r)K8UGEpCiz{oL*_xA<6wp-M+$<8+Y^nH%qJS{Wbdn zs!D(j*%yZ0DI$Mrcb8q5xv6gx9SP{x8TafljmSxCvD@Hof&4>CKu73B{tA6QFJ;{| zaP=St5liD-d^>=si}QIdqX#u46TiSkp-e&GuUKmPNx%AL-NqZD3NGmU{D8e~KiB6u z9d~doUOg|(Ej!qoGSH_CNv#LrZ6tPh|ejP*>Q=jDqb^{-5Dc|Q z6UZl!C_Q^hKMLVJDyS0Y151Cy&FiGnmrXwZ70e%9xUYi`mC z{DjaZGO_{tp4@WcW5|7u!)#D&OlSpb>hrm{M+)N>N_jTo8~{#94%F!V34 zCO}wCukvXRjI;6(Dk%+K=LX=UYu=4r90X9uZ2LpLwR#JDs9+`61I^2T? zLKTONlx;96to|Dm4N;Ay2P^sCS<;nCXepvFVwXddPi10EF@GXt&oBTjrI)zQDJGtoEu7 z+ku(GQpW^XARFX_c4uaIw?08mXitFDUG032&%>IQTa}gv+7rZ=``_|F`$65D6@7-v z*a7{>m~)M_uJm13w{@%CmnI7kBzzs53f(^oUa^p-1mDPs@H?-+WMmkVQgI9gTLh;P zyCpUzcj)?(RdOS+3Ni{dV7k6!6=OJLSeG2HJIkmWO%XGm#7rSaLew%jge+k=09S%3 zH1eb~0puy+)s+T-Qt}DpP%%>|+o}g7F^~X|AT9((nn0CYG5Mq^iu@=dGeW5%Aj_5( zQ}W7kmIMdr-XAQ-EWm@&{hzuVjeXTumIjT50}1Jze~lIIdXSxvIitQ+fc>Ye{_Fq0 zWA)d553B!rPz6o$JG<=xO~@NzdMA#3xDz>x87_|^@a^vu-+oLJ8)wKLlgcOq#fH$^ z&U2gH$8h_p9E~zQ1p)7f(@t#qLC~fF*i1i#1Ymjktrb@-Xx$yIa~A(gb5NaJvY?|D zV!uNy$6GaBsa2_+ebbc{(VDURf?gZYq#a2A!sjgu1b)J}t3#Zxse8hN)6TR5?#(~S zqRqfbcuQNK3%x7XtNrt%=lj{RX?N5^X+xnBK&GaE;gOLJ`MVHHZY=zEx_MBV#>|Y1$I0;1ZLAzy> z+mc^4YAYt~U#IN28Q(f+Ik?}CA$3)kyjj^WHae|Si~?koe}irKa(kgXsF#@?C{9*yAmOTJ!)>~DtcL1C@_Ii2nz1MWSnp1qmf z03(-Q&{BUzBYKV7p5Gw053C!c?aN{D>8|Zd6LXcWMxen$p;XMHb4x(%<@*T5@_TT3 zw8T9rG1R=pxhwEh_+Ig%9bW&11T9p0g!K(B4e%bWR_BPEu~+HXeWO&A3%w{yakK4r z^9tVpp%&ZzH2^dlVALhi$^kD5VuXBP$~1W#2EU_np0l1S0!O^hNYlWSKv~f$0hlVl zXG-wDHgM65_=>mI?6^=YNiJK@#MiVKN(i~oFoD^75-dlo?6I$(bu9W!c_TS)*v`}) zxU|_&$mx%ioas-c7geDi6KQpz(C3sj|0vhu*5jKw^*H9llcy0{D~V-t_zJGD$JkIe zhSO%i0}x;&;5E6`s$2`+9AC%5DlYMfd@n*1RP2zO$m~6Yq`{biTsi^K$us39T1~eJ z$>fb$>s@S&Y<*(zGFu#pO+!jIiUdZLQjf&cB}6GPhwP3qXJ5Bqnm~f=f$4!N3z9^U z5@l+W1Xai<5KoFDYXg{pZ49NwI8VN5p zBD{d9g8TxSbl!&==@{)a&8bUpu#3C*UBQ!saUEzYWsdRkZMJE~?pd&#*_Sjq@nSJc z|8*QNKV8pIBpwaYpT?YPiNHmnKUEq`^1Z_fWRfNn2_W)`a}7%Xla74ANRSz!5)8{0 z22O^oVa|^ym_OMX$2X7{>_#;OtJ2U&>9xIe+dFQ1x#*|O5gfunq=zTs7#Xj~xI_-| z0ir{gNGKEbSy{JN!(m2;kewOe341k;{qg4?#~D`t;{4b9?L*@H*SFY*kW--Rh>9b- z5SvfL!Qh(relCv*5F(5aUbG;E6is6=&elCI&vmdS*yvzK;5?8MAIQwf9R8+*Z4xB^ zQ8YCp!w@kV5qK=xa&qMdfJ5TP0QR*2%2WhAMN|i@6?lwHS|E@nrnF3tq=BiFLni4$ zMY+<%&9*9(63B@_8i2@bq?htosWlR00!bV&#HG^Y6e{AU-?GO2*pS~;ARjOQhzXHd zDUqifN+Z7=Cep-F+A4}1GE0SAb$M)srkbskAHd`USed?^9MXg$^?@8hJT{*3QgQ-- z1_?Y8lLI_4=}MWU5|PtTet<;|=?JYyU`l01T&T4?fsp``%uJ2*NT5nQQWSy5Qkgt9 zQYnz+6N;2c4glm36XFs02xTe?_!e-LfC0-=3y}u9_(Z>p#_%KY#E2b?TVNb`PS|5I z5U90#`+=5}Gu0RO+SgIX64|(C+`SIswiMSr*f%Yp7M?zY7ZLKdz#A)tLLF`jl9+tr z$OIr$;4x2M4FH+I5X#g70Fh4-Y4Rz}1sVA~QbZuLl}}NX0!5??Rg5ZmdJ*|qs!O6w z`2Y~2s7e*%MZ}Tgk3F_9;NA?dHF&|S_wx|-wn%lOg{Vj=fudY-rFH<|kw5}45{1%0 zlEWi0p;ec3AxIJdPaGlgO92y;nWq+bB;81mmD&U#V92Mm5I~lykVB{xM>^s{V5CV@ zDlOF-kAz%plBkp*CQbWUdOL}{trm}kN=fYN3<`TF<|&^dGAU|rft(0c+gpIim0zY( zU|_HyJvn8>)(qKOQiBaONGb5tDpJR&ND=vDwn|$76y?e%K_EW@>85fblQ=@9mWc^v zdJzd8a|IGvf@!8kBByK_6@p-=TU~&mln@DU?@WB`CfwHpZIH8ji?hnTsfpioDR052 z>Sf!9&>D{o^(xZ9)ABU3fVM6*)lVQPB?hucBTu4{8YG_pFge78Dm{{4wtYKAJO(g{ zJoOEDGI=Bb)6gRTMFJ+D%qo=v6CrDRDQN=vKoW92M!HB%Rq4ZlBv2Z0^XYHr5lD(k z#UuhO;!2Oe@JKomd3ps^8p@=IG%y58TM06o${|61ghm1guz0Lg3UHyOND#^d>5pwL z$Ma0S69of2?c@o#p-f^jy;kaW01%U3>Mf)xZKMGtO%5S)cm$F(2|^@_rZMa;c)}GAn@3$AhH;@5a> zKZ-mtb&}EuWg1Kp&9*?F31l`D@>E1-GvcuQ`((-ncH9#)&}#4Ol2mu@f7a-<8uJTPsBf z?5Kqw^3cE!ie}JWuvxC35W1m$4}l}vq(lK#qP>pH_9Cenw7sa9hNMQiwXcRn1DTw; z6U);F-Fo+QNM<;qQg{C_vbF=AT@1d5-2{sT3FB(?a3*av>Nhx2o_6}kl@&u#5Zyu) zd*qCcOn93E8VU&B<3mR`4s9svwp~KjF=yDlZ);O!XVk z;0TMSeDIxLk-SY}z>dYl*_quo=*|NhV@^=BtwCxbBiNp~X3?>${iNe;Y7Dv)(R|vD zg|5^sgg!$!5XEjHP3N1MCxsFblTT;|<1r?WD;F`sp{)d^KWDdM05$K|fTF(oM9{CXvH8P`OBy+|*-Y(#Mvr+4%sUA|Ar>>HSG?`VawNxGW zD9w}u3<)v`qzR>R$c)EUCizWe7O5gd(MT(woX8}nRB5h0@JK#^%qq3RV^k+5-Ar{! z696NQB4RYRiCd4kz9Jq2o}5wxLT2QX6Gg<$)PD8!id3OAAOi+~7I4rf0M+?A^894zK={y0KDlO6*$p;`HTNRti3CLC^VB`~1g#oS`g^!=?s)t`+N)(T7&_RpGgyxA+z-#8e?td`H=F#3Y+Nhz73c-dO8==5fGz@Qx< zwO&}G)S?|YGknp*C^d0+2Ky~MKz$>b1U@qo#8phoWwyXYFmR#!Y+%4n4MURu(g=*% z!lYkMeCjr57xRjT7!%zQ6O2B1Q2uJXZDX&5jS^0zj>f`OUFLRG$=NLX;XApn z4ZErl+ZEhztgCc|**m4K&k%)O)r0z>uphT{*}SwAuJ?(cpK zHED73F?t2>LIHIzZZNy-!OT7z4$tfM7<$y|56t|}%I+0RY@g5bPn4)&AZ=rb@#e_xbBf13urlOmlA84=Qr-ScF{{-jfxaoLc-g$1D zk}T#MX$kO~9)pd{HRw{T8XI;W{$v(yF^_~&zYmlzCQPmt$c#iotAWo(?9j}Z09PMJ9k>Xu{TH;02C0g|BpgWc7u~JV_Au@$~xS9xO0{3FLloB6JF4tB8`I+BOIn7#)>)2kt#{n z4JeAIA*EyVKSO_Sk*hbY8ii{ZMsU`^RD1oK)RBKZjv?rd;&MXr@G$h$@c1+r_m@3R#2qXSk!if7r7{O+Rd4d)Q($&Aj zw1Lm8*%G0GXAIcAm^pwA;zxy#nzDNlmGYN|++~WRg&p?7E_-|CIyvCaKVD@otlN(V zT{)+eqt2s-?UQ)vTxREL^Fg!dTuBhFWs^s4TeF8zRmE?4uf4r)Z$~VPw#m4?U1Gk6 zhm9`%cV5?HTf1$EF7ZKt?!tu;yMNTSqKu@wd-gKTkTuNN4#}obL!EASLp|h@5wzk@ zTI2{edW<&=*wCciFl9qn5#q*&g`*6mx2EF8gat z$zrcYQL5L!_wP|j#kg$5zJjE3)Yi%wIJ5VKbM}p4yLQ6fiEjr4-`)10FnkQD?&)(+ zR>z@5Abah5B=yFz!{b;-O6t8>*FrU9UW$-t4@-~pLbuN#YQdQyi-mog1@-7Am;549 zoQ6F+YdauCB{SmOL7a{K^*M;MXLPvJ2OK9#qWv)6yWGyl&6HdCA}# ziw&FYd~DnCH#KXGZH||+JB1*gqwT3Bwso<6uhWiUFIsB*)5Drw$0*@;7zK=eyPR7% z``iGHFU5EIPbG-|9ulrKb_^FQ>rrCdChhtycKNjZbjmM}KTbC(rSNKLoKj-N8jjJyy%f7 zwir@3vkyTRLq-kShc-GHwS?D+$X%Wwf%hskzdnp@nHP<4H4pUWY`T$W$h86%R_^OR zFU``ZMuI+&StvhOYfy8$u|-n%$S0JFfoz4yq++Ft08o?#fG%8PE1)wMqP79S&i?{E zK&=;QT^7XbV~oQ z9{U6INl+$9nj|a}^j&?K)a(gerEpxR6uR(i3|bW5|Y&&(#V0WX-W| zG{itwL7uPF$A6|Dws|EfXm#ut6gKBC50S3X809O zco&!A6N?e_1|Ja*tZ>!+M_`-CS?jr|;&7(O$9M(`B;)-asXt*k^>e8xch~G%e8&yg zL%lXG)x>dhj7O~-Cw|EbE~!)t#C7rCHbN;oRpdp2V0aWbXI^ z!j6DV9=}icF2Dtl%m=v4j;$UO)E#J%1ywTVx6b{B@TWET%Y|ie-juF#;FDn+!XX4b z*5~u0JSLtVfhQ+RF$qcuWg8fefRR%u0X%7PNOVC%k*JA&!7vI=<2D-!zY1;bH^J>U zxi2{86=Un31kgsKB6e*Zwo8_eyMjd0TizuchQCA0XJE_By6E@1KZaGs!L8o`=HFnA zY;lE(Y&NZ5o#sr`Glp#m2RdKTVFRmto@A-pk)ZQ@0$)Ue96}B34yt6%<~rR317d{J z7FvL%2TX%Ul;Y|(aG*~HI8Fm%eNdFEsc0lxYe>mwMx?J zAbCZ_WT@FvP$2B?d)>n`Zq|<0#HbC~QW+HUMj%W1F#v-_m;22te0yj7ci=T*#$Jvs zFg^|9S1!2LU%%3HgZ2wu9d!rDaF_i&U6wRkw^{T~+pmtosB_MybjcdW-;BOGUhSU~ zjY~xz{krd93d(&Gx@_Wc^f9<#Le<%wb`RT)Tr-iXH#8v84voM!VDZu*IaL~4ItEd| z#Ks~LPA0lHtfqo_C5^s&<;U`KEk!>v95MhrYC!ZG&aLtZj!!sbD-(i3Utiv!kSgy3Ak|ZqgZ?gLWnyZkz>!{ z9@Q{=k%yn|N&Dy)d!rCSRKa)2$q)RNT#jOJ=0CI7x^LOm%F< z9i}J(!Bk-a>}D1X$rV6{Gddo{ULHorxI5+GT>gw^3-gDg7U$$lRECAXL~14Y-2h|+ zOlDAS$0$ZG;=F6YG&}aG{FQ2u>Kv)038V{j9dRlmRYvAN4K^ZQ2_9*j96~FR>!svS zO3Y(Z0RTcPO(JrDfh7*L%U|ZJIou)N;Hxi8yT-+|s+6fIs^m(0EfQ@!5YTLRAVs_- ze8q^Ef>J=k3T2NM)a?a0Yz)^iqrO64FlSc|8D!djq>FxNoOjVOsNhvxW&7-A0y|`D zCQ!XvW_!kb&!M$SaiKO#c{bSEWw+@1MfO|PHK+ep{0dGuA=!Wri9i8l6*&Szgs@4G zUL3^NG<$*$ooPCWzXeT_TeygA%ul+bHC5`MIw5NSbB6B}T>9`iAYI(1Mvo7qZ={>u z28!~wF8jO8zSHM+%2&uZ@jJ3i#7_B&A$!}fT{>YenzMUF1J3EaY)vJXvxw9J{QwbV zZE{S|vWKLZ3Bkpo<5OCq0klAI<;UUf|C&=ZSS55uS3KaM=t3lw3$6o+s`dxeN&3kG zXDi^CE28ru9@TY$bU3I;s8<(~;>l!-AtYsi_!g%?3v`KBK;yehC>X7a{FXEbu2*;2 z=3)DZ?h9aZa|K|ue|2R5Eo|?!`;q&Ac&~A49WOUsG!;02`qR1CmU5)_IPnO_<3ypy z-+-*H+yBxn6|8h9{ToJY|4F~Cm>&uU@8}8p`cm7@EkDe2+K0@99`CcedTn#v4&3CP z3a*BtoV2^3#Ch+yZDt`%IIhSR&3b&48-aVQU!0=bVEjVSx5hzB_17?tMy-E~-3Dt{ zyBv-{{n}y>5B4bSv~1}I<39~TUiUNN*{=z`gHItjI6@K!I|B1Pm?Zua8A%X(u<c_w{s8z%`vWj`F0;<;ivxa(F*0&p5%>(1}TchGrgipe}_cmL?80h;YhS+0!DwPVPpyMdoZELm0B*+ zub~Qcc_h)$0g<)6iy|^9A~O=COQp#n6e+HhAcq71(paI7_-mA|i?V%;Jp70UArq_zPojvY& z^^$IP*5pd*aEEkHUzYv?3EFRRu+o(HQ9RNb`NXtSwf$exvX?atf91>!GB6 zFlLuYruM5j`{GLHk-i5z8c>DhPTTHgNhV>$ua{XL9vAU9C?$tob=!r8!GLucGg zq`8#M+m91pa*zf{JGv7nNOalZD9NjzuVxZ5{qS_x<@7jLalHq|GG;_9TSl8>Iy4Y6 zduY%eg5qZHW!Hu1Zu!aKipfDYKw!|AA;*=s&5P#<7Q@?*0L%!Dx!OJ_N5^!n|5 z`Oy0@D#2nGtWR$A&Y$&r=zh$l6-=rwN3PRVe%jCvb78*O86YF3?}OLbN-9*qX@eDGFYZ_b_=L} zhac{UfZ>z#`On3mK=REgZV9j3#47iBxLjgQ-gPi{g^Qs*HSZ_#$)f2_oG@rNKckr* zh%=ZQNHK)1y`|6jz4uKzzxTd5yFl357nk^1gBc)ajh`c7a1_|)yyM20OYfPoJ+uHk za?;q_$Nbc0NE!3L7qgU!%4squ7sU9Lx(P~$nIO@|oHTZB5{<+B{Ck!UjGbk+nyp~W zRx_R0DkT=gCJ`q&e5(XN4h3NgmGyA}RozA!5xCx^(>@^1M15(}Tp0d;VG!4$Y z#CChMTIoqEv=%Z6GV>J5v>Pf zi|{f26b^4Qz6i1%VjPhf@Juk8g@+JMSqJQmfrrQJVk&Bay%Dd5!*&b9%h>)tkC9q> zh;m}*+`!I>-V{t}lqe9OAPt$f70c`wHMe!TX3Tye2ldwsS@l7OnRqrg@m(=f3 zb6b9}tz2s>53!Z&Y-O5Mz%Z%2!5Keo3u?8xN@mwS?|+<|K2_8=x(!&RbcWJ0IRuItsfbJhj}dZJC*4f>0ZcwQ5hy((!AD(ULZy~V#d#Y5MN}yS1GY(; zQZk82|5hMBLQ_SpM`!syJ%`6Ub*WHM3xNDGy(KbCfM({*xmMATXcjiI@}gL-xfX3C-a8q*oKB}$Zf;HcG_Ay z?GQU{ot?&Hey(+}NgiPxhg-+byt!Nh+00_j|9orhTGI_o^tI@eq0Va`0{CJ|OW zr@5cA5Zw}uH6hRCnQdCTWhqNucF3*p$NK!r`1jQ9J(KPi_dUaYAJCemc3zKbnVwy9 z$50%FATxV8H<8Y7vhzlq^hRHl{inndaLBEg;cwi`5z}ikc-7;G8TZQvceR@lu@!@; zgi4Igkp|567P^91M7(s)_qB*GInmhJ#7F_ngRe-h$nj4LO)$<}`5Izl=cAkz%;764 zn?2U~!yJp^n1T5Ow&1IqZJZ69gN)A5hgSEvVT$(Y4}EB9qShRKZTz=E%=7s%ZvP7 ziVNkFF4Zgm`${w0IA|M1^*~wzP!TWkl?Ah!T7VJr2&Zdwjo%IiOa$=f)tOz>XJ1AY zdC*VB)syz+Y3~C~QL7?`-wyK}6%OU(HPIkRK0YH)3;Z&WWFNN}#@4yRRZzUw99_Sv zW_P130Z&Qv``ujaN)I{9W+h=1X`HE_#H~P|A75jSr~HNzxdwrB^BK2Yf12B_^>x5B zJM8RL`|i@J)FzpkN~ueN;5mq`C9np`xmXe(<|@W_Q1Kl1C>=rHeO&?zggzNKdAGfy z$Bsscg1-rqbHp7oAI%R%vwF^Ny5Y|j(z4hr^yaiayLrIA8e|B>FGt~|JM8-EHdiGI zzQo-_&H${jF1Wa@X7_d3xqWunfV~EMY0?e@Wty_rXx#1_c85i!I`1RU>8$?U-S(j# z`&rF4!dJ;`f$Jv*Y@ydayPv(g?gPlLSr~IpK8jvHUhM3w=4$(6{#3B4gm0j6(MT70uqgc33nzp?t028$o`bOIN`>n( zdjlI|-3}SFH-N%PXQ0Ut=_Z8_PS`dnnZs(ME*r)6q`%G_+?UwS+~h=7Dkx|0T5)xQ=x$gw@1t55z#4sG$8@>QmbjV z?9S}l=kc8hR8_j`Rx77_}QG?SE{uZ%g3;Khi8TWKyp1fP+xoxx?Oz z)*l~>!WCb7f=J!%(vgD>g@U*7XG)OZk@JPw!l_CXaw3zs(3TaM0GH88#kpcKDJ4w|3%$kpr!FC2hzq63 zsgzGlPOCK@^Aw^rO0(1grDUEIuaN2{kIiThKI9_%60&c3Xm>Wkh@A>1KW9%chH_*b z?KD|mGMQOmSz$FpYdSRfiSCaYXVhAx`{OB5BgV8T^$L2D$GeD^*)GoUE;|j@bf5hP zx(z{^!I~bkU6b}79P!Ynu%@N$z|TE9jUkQDXIiV&GM|tshn|q%dh|rn^Z=5*XubID z^z)+F7PziLx2-*-ezHKQ&LOfJvW3Zo=S%5R*6 zDMLwA3D}8D7-#E;}@{$NKF112)rZ=kMp9md{5iYmKwu9vgF0>wMC_KW*Em zY=$jepM1Vn3a2m(lj|mIKM*15cl{boCsx^jeVL2cSZK(Dz>B8r%d@WkvvR?urHFOj z34u9m-<@!e7A2h*PXO`CiEITZbxZ#fZxS%L&gylhG#vO1qHs}>It!i;8_SIU+zoT~ zO5HvHUUUkwt^R$>1QHt`4%1o}_lZ!7U%h(x8hY^xQSxqvBch8N}36ggRHGujErrt+gGgAD?PsT@iR**I(k zYZbDzm6ytgN$aK50*pX|g=&$Yv|zt|mWo@UwM8RR(3;lg&d&QSR5};+gre91yDr3S_Y=|7_H^$y%Z5>p$L{TJ9Av~ z%9b9CWw^@Pcpn#Uxfzl**@pP(&^9CoCz}o^9s)Mqz#FGg=`m&@m(Bq zKyr$4rgO4%+ZF5#(&M^MdR+H$%5#*A*rB1#C3Wljq$_oV6eMotrQPnc9WjvKQ8;2X zWI)_hsH^=7lzxTF5NEbN~6afehL#FB^=am+86?KlDD8Z0f(0BMe=cX zHhygSWegyJp#!YwaHEV2?afX5a>)0P9D#D~fSKUr5PZJ5;Am~Xwwl{iy{W%b=qI9| z$$`EYU*Zdn=fDkqN>271293~!_MeC@sK$ACKdVpsHGG-I_TwZL`(*eiCmk*U@H!>C~o}T1YX~dmevTg5&tb0Fxh8sFiCTRvL|>)85u*hyL9) z_O>ni?9em4u84}U5635mg%JXMdLj!W8Yj>)Ari!;DmGJop&S5m1xkTo7i!3%7GOM5 zO6>uwDc1^h&q5{$1v z(Gq(=x-?%7VP*I0Lt2r{!<*;eHNc?y*A7ki!!)?bPfJWVnnBG=*@{lb|d(ZbUxZ z!Eklj&fs>&gkNJjTV%3si=OUqp+?nX_se55Q~)Ffj7?OOGkB_FasoMO_lw+!Q~UTK zdnZHz3~eOTT`n4C0Ya6m!tzTBIeE>`ATV%nY-r4!_1J04*SMN@r%>OkgX=5BNS}53 zzlS4U>fjakcF1NS# z+ulCgCTXu5&a7}|!c(j53p%EEZnS|-_OK99_Q1DJ+O{o*ZW1RiM!{=m?6s2r@3L4Y>r+vBXSciL&r z*-=AwjVuKo;u~ewkt^nVU*2W^+H0>Kv2EjiCl|&tJJ=F6CcL`94=pN%agmm8@O+Y+ z(WHnAt%08BH=>h^Z8sO;EwwknTkiHwen;j5om?@~XO}ai>S_ZwO&XTn==VO$QxB#@ z9DJMXO>nIlLv-dRo%MYM4h*48HUIDAOdPWB#D!4HbcbWNQ?fg|?5)V=ki2NgTtDbD zZG)8PSeOXx*vFU{Q*qT1@*S3~G(Xv3f2M`D9ZL}Iw!lT0G{b*}NeDL7D1oOH$|}nl z1YAj@#TVYBQP0DhG=DQ3N^6L&LEso02)rQk9rbD`2qqG&s?08zu=uP&yBrPbZLVO+ zR)Ex)`EWJ1OB2p0$P}tbzyu?KgiFm%$~ckv03V69Jjp9$a>(GYu5V&LOj{F;@YAWw z&!yY6R>Z%q88?x&EI!!lXsyXsuf-0_3qud6r#DC_#*Ct4Xie|rXy~zXM1n!eZPDpK z2eyp5xOrtD@Y;-N_p){Da7xP6tOn6Q_%IDx!0guiT?0^V7-U*fY}VE?W*8G%ycz$-{+ zdgLvH$RU&cjeK%Qdw$KGKRB8XnNUU}eD$n4gV;zd033A-61}#PixJ0d<(OfB7XSF$b|ZXzNoa9b#OuHR!OP@;aSyVZreV zEf31gX1kmd9~4W5*aKSKG=eDnm0XeBWv4)8!)XjnsuBBuT!F!&DZA|rUG}OGyJFP& z!27{5?y)nw?98yK8MQOTF8*%KzKWXnkgw&x?s1=uXG<>v{f(_PSDM;7WRG{-^I85{ z`(GWgFUQ)SuuIvy;?wvpnbk1PWv?Akw8zvc05}dmW(LLi+42MWiN-TkCHrU zmY`wiSHRUDw*L#kbj`L6`E_O|p|sX(N7wDhan~w*X~+mbeZe%qe8A%ow>*e9TH@i7SFbi!WSX=h0N8)W7aC?)pW_Fnsm_=i7PV`o4SLpYDv z^H4|J;{#MnAp_pbWC`d+t^eN+3D=q?W>HvvDa3KVg;vK!FeRCsUr}=5ob#5CzPqdlwi$v z$~pt?7Sd`oGx-rBXU?nJm(a%4zc_E+_UNv|_e#uh3LDgj{gwEu$M?En6mkkUjRT$D z!%FJ~4M|Q$78HkIC)0k78%s6P(JPq9e2>^+tK|`a@t&_&>T&Sd^l#3{wV~#b56p60}2gA7D_Y;1^YHw|tzrdVf zqB3omsPut((%}iT1sDX1Ag>yr#Qat%rZVhEtk3~FCA0U+!9Jdlm)4zk^xhHsM~Tml z8+X4VPau98a>8?ey3uPdueM!MV_a$4>& zQ9^*qU_5)JZNi4LL%2Ot?x;TdZv%cSH~0gJQb4YPIW}qkZOT?++90)u9qfDB*qID0 zz({9GmpWyNwCzV`#DL}G&-iIhx!5gRSJM(t?ob~is4c^71Ga~xYFu_qRw{7C0R2}R7!*B4A zT{di6TR4fNrH;0-;+U3Pp2f{sFaxEKjK*vzLUZ*SDo@vMmfK`0Fke4sAE2uf_6|;g zUfW%_bJ+RWSjKHP^jC-TA~IBoVEwU8fwpO?0C^GDje)%JzwpMxveJ!XPNr$ci1GKq z*RU7FEeRTDH!u{53iF==w=*0jhZ0CS;(v;^Rmf1dAw}&pkF<41+0h&9B`>n00|OC3 z_m1=;T7xSBj!^}?{yT4P>e1h&TDcOykWVR(giL{)@^{q@NQy`R+)$tjX)+0E(J;4RQDnQ03lDI#Kcne zl^3&_utmoX4`Kk{yImWNU1-jJ1#ldKRN>TWD!7AO zp7067=6ndo1=IyiWebJT(V{`vaKbPFs{~HT{(XuHNaD_hzqHAbkT6MrZo(d62^^|E zcRjH~OeAy*Ggf-E#(L-QWfNOwonwYQqaTYgXzd6L4&>p?u(5MR2nc}s`MltEj=9}2 zdw9o!?MQ4-I{dx~TMEX$)ZWYCivY39^|3iF;io+X8o$X;)vpS9Yr+{22L9Ayr_;xD z8Zvb2dhN!#eSEdc(6^4-7~TWMU8r}jFoAC|JvwccZvi`kSHp!YVC-Ncz4l8e&^2zt z!0F!rKi9_lOL1n{c>j%!cbT2t65H?DBer+c?uaIqWbSm{oYMJb*IJF zW7yF{W)|H9=TL4RKBSq3h5HxaV&R-z1I1Rr9Aj|&1gzQ3i75mF869a3Sp+d4X&p)G zmrLZg4Ng(85GCTgQT_z@-uSsC>`E~zvF<^y;8Cc6;8Mb_qz}QLeAXDtjiYn=xOAD@QjwX@*H1@I#41Mfw`9Is)D0zXzT?>X(SI%a!`k zkOmui?9nP3M&caQ=LF*gj|n+5pdP=sUEut%wN_PAL_GfF+dxzVQkRG z>{BvByJ^y{owDI^$9q}eNP+(ilQgwlX?$phmK$lfzM@Qu$d962Z!9#&F79*MGuK>N zJ89jti4KW&X0UXYFkcD}XWy5?Gl690dm%vhSn-7b811ru4C|^<8%0thqvm&m3}Zuw z_wp_~uh(v`+wI`PGNZd4f9At3<2$?8uBzKr<93z$-0GfpRX(Y@gW{I^sqGT4LmKek zeJf_00_E1816@WZJ47r)AvPofWqx|+#rc7JfXrd;F*2#Z?oBeOC<$sy?D^wV8*v=1dg-ZAs3Hn0*Pnhsq=e%fFuN_=>HAp5y zHDPmM0EN4x^hfwQ?-*k^XFCxqr~{oK23=0Pzkk4O72nU>u``;o&&+zCe>LP>FJxpp zU_>C0g*P5|ZjSop2sNoFaJcNGLGdN>WQCgZukmQQ*v3Lo!j9KtpJe$`FNNsP4?zKQ8#NBS2xPG9YYj%$cXm&-a~6 z{US5etFUc6A;exNr}f%Va`W|Ga1stgG}AV@Gn@-T5GFTYJ7*k?IZACF!ku(-U^Ted z7B96!b?8H&;dXDSw&)G&=i&qH&P{fx1RqPc*q>|Tx)E*+ooUVaWpZ!Bv4Vu8pca@UgH;~WWmjkRE@2c*tqnS7-?hm)VK$0-fJk#t-w^qx9+nlSFzJZSd zQS7#JQB=-s7R|AKA6Pej)OXEdAv{+;%k`5DRDU>t<3L#m*c2qC4r9;;oKWN8G zn0~W%LWHDLe=Wj-%%#TeopR8&A>Wi}wPhmx+F_eO#;S`m_VQlbW70AGStv3%jW=Nh z%o`!ZS|k$P7I&J@@m`59=OZb;94IS9Xfdl9wZtYC+n3~}69!RepMu1KGPyXrZ43Gm zTM$@E1{z?@+}8^;{1 zg>w$tj@+_?En92ZA(s8VOJgVPEu6M6*`{1#KCVM*&zvn0!nuCfUIDhlWazX%Ws-wc za@$}nvCKuq6zcNBBerF;T>@^vjdEKI3Gdq(A4Ct# zOnu!c>Fa#|=N8Ls-zq>jvIDQ++NO#aSa5j${u-Y-{1gs8$p5_qb~0`Xru_N|&Z9u{ znl-T|D8iv8>LPnl!<*``93wnTCwkWV64 zAmKexD3vZ!4n?E`ph^Hd5~77DDu8FlV2e-@kC9Kaqyw^2n-ND2afARS=CKj*Gp=Eh z^T^0x@66y}@*LxXH+6;xswx&EY1N`4EtKg?X$t+%cXwGMlPTh$?|W!{cg%`yOD%~P z{S~Q)Bnaft4uR^sQ5u){tkSzmK@#)W1ct@M<>_EndMuRh6;p_Gr7i&v7&*jc3=8(T zy>>v|4!}xx++AT5@m|G|j+niIeJ|?f>0R*%06D}oO9Et-J&<%$jbti{(hy0w=wBw= zAO>_EFo0S9V3=syz;g(l5Gt~PxZ**tUs5?Ik8SM0?5+$*figDS>7aSVln%`Em-;EC znr$M$lHw~mKbY8*7_*CS@Cr5=c{$i`%mq@MYphL2t+m&oy5G#4Dv7<0b=LsxjO`9Q znO#oatB%4&8(W#Aa$rh)!skWZZ-8Bf52ehO!WGAtCJvEcjL-V<5g*G<_nY;xSE5MF zCWgnVco$b=v(m?Gvqs>}v#u2k4*39X--hf;ol|%ep*2n}G+2H&IX~wYe>)+c?qz0X zGQtcdJ>)NBi|y;;`OMX9URR=jjitTZ6?LF)pc$dK1D*Ri3mg^@Dkz%`5`GRQ0L(P) zGv5~e*16z+6Vb4vh}sOR=uEeS z(cN|lv@`T0lDl-xSpekf9v#jU=nOE758HTux4ni0=UtRO<6fk*Qx)pc0!@`|pI@nE zGAUvb`rENgK|`tLggi3t)gWU7_S3d220+QMjKF__dk31bpGv5K>CHuL{2BBCrh^p& zA4Y69W)4_uoUQ&Yy^)>}{E>_1xnCX;Bq#Wgo0V|{KZS-TTKe)Xer=cCD0!uO7f0t4 z2eUe%wzSU5XLC@t+>DD@f&avX zDZhZJtDjP$4+hr9IAfdKW&g~~kx~IPGLGOLk%LE8<+Q|Ps1}@ujBng#=Y90J)xC}m z06remKg~K^xwi|CYO8#6VD7Q0!fnof%XilQZ_Zd4Ksv@w3)ORLIP1uKr*gjWpcQi2 zfuYKeL?W@JKR1m7T*o!yGkj{&K7}KKAzQ=o1dTK6lv-1ZWf3z<9t^-h*z~5Q-$=!s zT{eRDT2KV2t8MersX6PDy4w3uR}&7oHP#~-DGPAOKpLUWm}3PqP;$CH1jk6|5Eipe zhpZ24{WZ=G{aZ#47ZA(`nYVXh_%GL^Ye(!qWZu4E))kCtwsYPF`TQYQ&>G-;>9)fT zwyw3-b%=GXv#zk4<}z08#u-MY8ZMSz6-z)<0-R?(US1Ef#&fLEutsi;gRQaF8i!b8 zoewY5i~-3MlkhDovtJL|ui3a{(Xd?~MVkddTG=uF*N65vFlpGM5n>>T<1w!}a*oj! zs+c(535A?DKqe#qWuL*_4RocHMtaxy7KH48Q|t&714LjR3G%7$qN{mI&~l;nD<#M; zNr>EIhuO`vhvA?D2sX=ZZ7kEVNumKL8unPU!66OC?O3=j6Z`mYdGf*a7DPW_&b{_f z-To&s^yG%?EqFRg`0zt>cHV@Y5Th49WQ0nw7(u1Hhn&JXfBoW>IC6VCP$Or;v5xKNa7u5JF8NR7ewjgAg&~+)X#9Rx)xkk}_O7b$LaNS&`3zUp5N_-6 zjSzG(Mxz?8@CC=gbTy9PG+Zyzckv;Wz9`~Son(}91-_cVW2OX|Bud4tOmav!6azrI zN^M3_lmbwyVv(BSKcZW*RBy~Ody_tIg zZD0V9Nlrr{5-k`K0F==&ou0dOdhTxVh`?;2w&tt`LJPIk<=*>u;Q%KLhlBA_b7UU8 z@kfL9BT?(n<{U|^wPV#d?dR$3Kytt_0zVwIAI|$cId{O_%AF`kI@3r$f`nH@g#(=p z_V7^Bi_hV>hZo8`thqOMPQ6_J8W^x9m~5b<2tyYzm}QE>UW2w;FgyWrZbC#Kk~k;L zUVC5N-ZyUV&T(Q+0n7UN|@ zX7hu7%>hCUYSoY?a4|vMRRNDjcGmA`|E{|I!xlef5E-AKtB2uEu*V*TC_(oQqa_Y@ zcT(G5Yp7$y{0L$O6Afw(%5F92`|~E>OD|Bf)a5hjIbh8IMjk=qh$QqFjSvS64H5w6 zk<3czf;TR>9AGQ_kgn?1h%Sz~9T{KRZ;0aHS%jEiVD93D-;v_+`cw%znZf@M?nh@imax2JDLTB zov-+rxZKaAW`=3fG>XvOc5RQX>#~jg_B}LlvA(IF$d)D{mDW5 zoP-o0OV}whVOY!Mu$`p&0Phz8%`eaa{888DR^FVbUF zr!?v|)7t|$GD#CC0*nMPfyXM<0*p{7CNoRjCX>ffz@&2lG}EgABeV5LIzpKezyrf$ zR1A1xLebWrW?O?4@z_Y6iK0@O5d%PJfYC_nF*1qCjC2%5I!{$fb%r8xC~CHKgU1K~ z9O(c6J|3eYF`-ONMJbTLkgn3#WeYCM{X^xD&(Q;49UARZAd_)`4!U&-tCC|Bh7bGX zAL}rs9d>{UyaLWZawYm;-SvN-b{Qxrhmcraou{E7!J%L1yLc%@5y+_k%WM)GoB-~U zo8n}`Oeyd6DrjxtRKISoKzD1z?*;oYMH4pJV*3D=_;`P%SM!QX+O?YXQuL0>=$IrI zv>bsK5ulF4AQ4pLULNsVF8G3X$-{XAAu^D%j?bfGYK=CVdTdBsb*YquFGXS{w%(=s zihTe|dm{m_nD!|xmCk5ToE+RLz7QH@#7=|nN0Fo$px@Nx)i6o0b>)P*1@vAOX%H}n zOrdOl7k@cSw1PmGbiV!2oV}M{419;Z2ZO;?_8zdHVOKNoJri*ZJ20{mlpkOv)$9T} zYemoJp3F|gS?hq$nVq;C9JEuR5and=M_j`#JuCKS&d`fx)^tJmXcf2NAYpp1>vnhU z=VY!mgr`K>nU>#Il!2kOXC%Zw2m}MAtj+HK4cYy<^7}filj3#5e(lbHT38D@#J!M1 zHZW|j*EC}U8hjK^59A3ML>DWzT{t}kmBkfy&80{g4qNn=JyR}C`)2x&1wTTrwn3F| z*HI3=$vtROaKj)uMOK$`ul>>qW2QAaZ0jmVeyEu1-*tBRFrFjPJZMb8qyq8A#X;ib z-Z$btPGP9t3?43%K>iv51Moe%Ef=Kp&ds)mdvb-BGS90H|C~qUe-H8H_4t;Tjp6Ay z)2Q1x%EqusH#x`h5yXqQ(STdR4Wz;%u9r^5F`5+&3!UU$e7+l@z-mVE9?Q)%b6NnE zAeqlQ2j!nfL+T%>1T6qisuop9L_TTqiJJl6l6NZ~81e&vIEUZG42P+u8BQsIx&%+d zb#nj!*4@d!YsM{=41ASN?cek2-tBqu^4 z0Kh6W5-=3;NG8ApGBZ7T4g<^bnRUzAPNbqxNi*sIng1nTB2B?aLfDDQfU%|Jb^X!*dAA@Za`90B;ZDBlbo{k;mQnPkJ)xYp@=KV zFylgK$bDqUo?xtLA#=X?{v+okqjFAy0wG8~CM{b;dLUJV*kPkPa@b#8@%AI-5E}(W z1{1ZnIeUu+C%Vl`0RzngM{P(T(nP$A6jC@m+MeKJAk3I)#9duL{zcvX0?{Np57J2x z`!L?b@*>%9{>8lQO1<4FYdhW&0n!5^XmMN%!hSX7OB?r1Aid}4VErb@wvJJD7$ui+V!jb>(X9KH!Pdfl%?zC@fd_M5-YU||4)j7ZiVo9%(!?kguiwwb zVe6-TR(p;Ahehp1yNsh#6w3F9+=T6yzw4$9z86N~ ziETG!KsvEmHMk>#aen4C8G3v14AvQ^ITIC)ab_3ee1mu|Grjiyy1jqg-cRQz>`;9p z8d>g7HGO6?{t@UF3x}~{)sVBqo+pBinS7%L_Q2!{`w`u-e&9xX9weR^?5G_4NG#b$ z+Ga1mCT|N>xJeHO>3SpY1%Nn4l{8% zIUx!I%pi;~DCV3KV8)!|(Qe=*!TD7Wn?cF=nu3f>yYywxNcw^Ir5n#F5Z-)Gnh zx*$fdp{-l^iu+D!wzD*CbT1OX37_YbS6LhhDs(W+7H>BGe)9p;~H6T4q zI}As-)mp-7Eid~-N&hcx$O~zy`2Vup;s4f#d_nDUhn@fXimTkpx&J#e&79hO$-;P4po3N4R&I{mUtAdu-wGV$>cz#C#dX2^ zT9cink8;?#C}<(~2^DjQKJVPG-1MS*e0_SryUlc3!X6g+0k#w}bwzF|6PagwtPQf8 z!8bDIn)5F44|tmc#jCJ&9|gc1*UNAf^h)nBAyqbY8_$s$?B=NS9y3$5r*=j<`;(gU zWVA0()jRugfrcHyXBQr)2Q@u`=|1h}>O`8exF|RR-hqV59%f~C>@tHvcrUP93ipI) zuHm~3cVNEUG0O+zDCusOORG1f)#+B}O>I5tK$}awc>iijy}aRwA=un?b9C#<=|5h`TNTnUr5`1N=6&bQ`0n5^b61qMGTwG*>H6-e-$$ZigHKlNW+Qk zoHk%Fi<&VDoLw8xcHNRbs2RDynNMqHBTs4$2(7;UqDM<9eMmTYmg$uS`T~XA3VJlA z9`qmfrr;TCTf6r_?^(@7)WdJ)bXII{vyr3~dfd_1jt+Z%f~`T#hjv1KXp+-ZIL^Cf zc}0kt0Ed?YnW0Hg; zjFN=-CEqo|Mb{8z7Z+i_zR*V!d<+V1k23USj}3j*3>#vJ3Rm)SRy-|HIoFdUG}sV8 zM30}(!iczn`_*uzMns8N$m~f=7>AN@Im?i6E;B|58M-$<47C=MV&_|er z`K%;_an#?QW^J-AzGgjBA`GwVq_yG3)n*^6h}?LoA@fGh>%4z-U^F`I!_?5I zS#e>`V9nE5TZAcMn3=P7uwKMwyG&uCBowCL`x^oDrL1^_!(oZ5hRY-w=!235*uJ12 z>q)Rd3`=a#<4Ue1Q1Eal^H~&P*~6s55*suX_X&hUnXk!~Fq*K;c>o_v^!S8J9$u+t zG;!#OD!T!e1W<-UjHrSq3=tn!&g=;jiy49N2}HPP zv7tvSdlrqWX)gG+S9Q4#+vz5mKAz^vo;Vty=kjtRC3N%P8>4cdbM%B4PuaW)=`}N z$s9idY$6wp9#my>_9>YvpEV6NS^K$WRUMyJrI21<#h!$G6z112*PJ1<`8t_pOMn_0 zUBA}wKIeIQn^T30ud8Eiu`Q}A3`L3->r)r%~uhi}t z7X971$R06pgXv=EUd1q_9=25d`*pTzz;n4Yi!rv|6mz6E#W2Eg4n41$(yWo`ik9@t z2x~N^ALfxX|I!dN!4_Sz>Qk)z>dE7@yb@irevfT@#m zzT8qrx{(Q#vVEV#lq24sS>2o3JlrS>-Z)7@#k4C-jabyh#<~B&1b`rf;vDSGWqd3nDtzn=cZ z8v;0#xoo?|%o2SyA+b0#;lc(@IomXrm8?hvFd#NG1TZUPE}{_86DCmdK%UNCyX9HTp=@yD8y2>vte2Ggy<2mAr=ij4l$qQR>;fsF+*u_Z4?A=6_(I1&=hXZhz`NmL~(FtI4n;4mZ1eIV~+RfaBN zv%MWNA|1ns8-~)*tF1?xHzLi8m*1HBhL7)jVed#Ab+Y*hi~Vd`8}eMglh0)3WuuNn z+EH|&r_a1=rsh&dQ|bs!j0wu6Rhz6fMH6K^wSr!0GEMH(4MwHOG`x?u0UhY6eNo7> z>A_x~=w^vQyMNuI$-Uycz=qg*>3@ zN{t4ya+U)&d3Q_kU2>p(JFxE1e59zeDkYbvHKuW;aGlaoyxMi#b0cTck{bbhT!|9$ zeV+@B53+pRZ#RR5{_a!BHiQk9ll>Kjfjk>}kBCNp8KK^CejL@VHl+izIrXfwj>>$i zeUuM;w6y!^r*VAg8=5)~w>eIGGAWHW(U0@b7Vl)QHa+Nh+m^=iEymy7xHZ*h9SLYQ zq>gQ`C#+}9yH(a>zu-H9Pg8s`mo9Hgm-8X4!`9)V!0bpl+XcdCu%s%5UvY;L7h=v0 z!bd~GQWhI&(clPIJPEP6Ohki7RKacV5p&^kX--p`!{J5gM-}~DZd}ar!MNfYqAG!wU-^(HeYB z95zaF>5Lo={vr+Hl^>p zhHzMRsIehoq%DL!$Gm6iMx}zeJF-vtoFQ12!k88q0?a|m*Ted>X)fK}l@ZmFf4wr$c(|_p35Nlil81{P%Pp=F+l^_rJ&GI( zt|uyDNrfYv%Zf*G!YB#gB2e})ekm&wHi#AXQDTOsnAu0T*vanRd-Su9zlXP`Jv!2{ zZRuUNAqmD|h9AiZ6gSQv#j;t|HM2Yldo07Ad`j7Vg%W+$g=Od~ZWiH^7XTlJ zO_9mxd3^Xp(|lp)mT0}#2BaT(l<=hU=T3j7nD)t7%3erPA%PgoO@Yg262<6Ms^0r4x%IHZqSe2572!q6mjr_N@?$4X)(dMZ~7! zsX~t?l;M}%0GphrqS1cZ&@|0$Dw!ow82^V)9UCP#imU(;Tgs9YvJYV#gZ0O>gT*Q4D_-5?Nsuq;WO-_F12tkjq%{ksU^FXi=KIzEymji_TERu zdUVj8gS6f+g(7i#S!AT$LMb+4_>_oqgW3V+(&~W93p zCZa+_j}2k;gv&K%C_^6x__(}hh))zgsZf?&3{AzA_$cwqF4C-|mnk2*yAG$QuLMEb zoLd&M+(<&U;ZP!$I?~-){<&eY~@G^Q!7X$oCTsfWa6>)+xJV#X?}H#|CdI5PT-S?(EY#sidb zSad_;Dd{7ju4XtYtpwhqhR+sMW9Bk0l~snR!;kc?>D3nysvKNUy_2n38Fv6aAX4jK zg-UJ(TxHw`dZZpBQV*ZLK2HvDE9P3}vz-sD<28qyC&K~qydAKR1UCoPUtkKChSaw) z^`&PrOJ}yGzHMoF?jgjoUJ}bBF_A)lduy=6;*)4~_P(sqF=?_-nZ@nMMw3NTMrWJD zw!OdA*vX&L^43EgnBuVu)P?fwqYnw>C*UI#Jrb>8vA9EhT9WmQ;ucg*NGAv19lo3v z_*%+q4lOyf|I?Vmm&Dkp|G50hwXU3<2K@9mqBtKo83+?VB+P&y?saIG@PE#zG$%&p zMi)x@Pcjp}*D$H5+i{CV9JINa^rTOsdo+dYl?IHmL7;rd z;~cYv)tFwGuf6O7W2M;zA1htXibP2wOn^e-=e?Zxh-KeRe8iILEAAIv#K#eZBQ^{O zqs+MHL|dchkZ2)gHnw>3B!y4dK_XXNrgj1iH0zKh=nXwB~#LMA!-rWbRTcM98c+yy7fw3 zMx<_|Y(Nm*mUvTRhHdU?47TNkWl3*-;qteOo!etfBgV}zUZuGo#!aSL|KW}ouX}FK z>q%jxwZ_am$ILdK!htE%e{y$j@*rZcd_hg%UQQQY|xZ?+OpL7 zk!dAwEaerf;AVLb6tggaT;y3}fDNvk6@xHoacGL}M-sxgN|sgL14KojlpSgetPQH0 z4>_lH7hO$!U>Y3=^UShB!xRq-?`m=a#=MEQrFVRbb}d9B5T@O!$(Z;(mi5WdedJq$N^_Lcvck`LsRyAm}O{buSn1KpKodZ`6hZ@y1`SG z+$T8!^1+V)VH{ZzMIcvmh|u8BpfC9z;bU3OG(_Pl+0h6wG6^5!f*T`ZMz~zFEtDm9 z=yR^euLeRHB4He9NfH`-!lB16d2GcqK_8arbJ=zY<01*Mm8?`4RPC){ivATfmJx+L zX>rAzO~zYn^3Ic7(X2$wGQ_R+@t1S2FMiK-Z*|F-`g9Fb$9TVvGW|M6rh9#S4gI5- zL#7;EIDB;ca&0z!CEF^xZyWMJB~#`+Krsjqiytn+6}PXAMW1(N7!Va=(UXUL&ND$n z6k+^o0417|=MZMKQB?S?<}=PKKQ);|4jh4%xO;eVGzE9%+RUqUzbt>uikT($Y!OZP zksPt&1~H(6sBkEWDrF+!vWsYl%6YZ~&=V%A@Spb8s4&3CVTLi5#q0;OmK*}ikGc~#)s?`v)w_1%ezmYkm+-t2|hVg!vwGl z5j|mC1d5(R)c~>Lu?1Gx@gybRQ|z(9kqW<(6%RdO{6h9|v*=OSpse)^*+zNec&f?P z3?deXJ&r)h6XFxb72GEi3q>4BpA*bs$% zi1^r}A%H`V%lnZ;B&w1{5e}PjmQT)e4t>Fu_}G*@A%VOnuVewla<;jgD?^M_`1H|Y z)W#awc8SHI&%37N;arwUB@;tKEE>Z2VP6Q583=t9hG$#SX}s(__w`=5*(m7UbI-=KXOpc-$5Iqb__-0^F8Nf%K=?lCB)%3gBjR|Q6N!srrTVl1^+4)= z^kV9knlbYi&vh_svGGT&@WoN(K|Iy#jl4>)&d977xyksfmh>n!MrJ=7Z}aOuGc0}5 zX03uJ_DSaFDmk9>k}awls(4-*M^K2{!Eyb%T96rKRiB3~E{Z zQq;2evM{4ldV&uVd^qcuo}lfK4-@0O1(LBju|g|rv--lUbO$ZA+POr7Dqn)e`cKIL zr#E$uPdr@vq-8=Ox<~qU$X)eX|a_eQBiPC!iID zUXj`RRLQTeII%f6Id_PJ@o^RR^Vua(_CP6OeFDtqVg-p1Akk<4^ zTl$%wwLbljy+rKLm^R7Y9d__3!e}*Gsx4g_6AF#9A9`q9J3di!t|RSAfJ-2kR>*4U zEBIG{o?btvV+=nZuX{(4mhPQAIL6zP?$c)bX1CgS`=MtrjGAAQ#|l5Ck6$~J2M~=# zw3g6V6mu)_3K?&RyhV;rf7GSx7!cQ-u0zj*X`uDUEfVD=X0;|23XR%U6ou0iY?#}>cfN1G!|7{?KggUku6=5+L&&u(V+ zj6-Cwp;wquma-%k`B-swzW|rj%_i!Wfi&6BrP#xL+FxeZlo4!4Zp+0Lqq3 zM1w22oJK6#57d{+}9@VS`_ES9VP(v9Bg6 zc`PDkq0eQOXb9sXKx`xrC1Ld8M-)Dq2os1{jIqJTmHlX-#|9UA#FED%;t{P$EV~jLV)1hxz{ll1T<~ycDjtr6#G;JY2$wTW z$+IG=l5H#J0Ym~k%jg9+V~h=qok|N#EdQ#5xoqab(YqF-MHFEdHFIWQ@~B$j-wNmcY%a;Wr7ON_KG9Dim<%#?lvO0LO! zt#U};)V`H?cecTcM%GCOm1gFv-h2%E`e;Jrls8BrALla_@fj+(-Pxcd*Rn z;;9r3{_#}G$`A>$Arq3|w}$y=G0%aWLVr?g6+RPL8np*6#eNsEhw7}SOf*;a_f7%^Og!x9a#giBc_RSg03 z;VM~HJ$$1?;m8NQMKQ9~=L4MDn5KI7m8pz!^~L-0Zkh9mHTLv*8joZ?4Q7L3ZbqNm zgnV+I6_y0>OJ0&<7LHiNf*TM^0JE?pwi+f7QRQr3(1bzJvqg`~PtdQ4GM^a`K#b%h zDP=`MgZSTKu|!k$B-F&V7@4+kvq(rRZ?72SSk{M{UcYp%&(unu7!Yew?g$ioTcIb6 z23K^wY`Ednr)kX7LUpmPwS+I>v$Zf{$P9+10a& zpR)ZTEtcU37h+$stU_PP3=m7nZqx*@thz8j41HyhbW$$u+m!YlZ%Z@hmsFbx23X?f zeCzl{50k2#?QFh_dK$E6$}qzcM>rp@Q<~Y&KAxJAc0YPT^3{wcdIq@h>60#zwD>X7 zjp`ZSK*y$S{YJ5l*V51T97sr31{+`p;U>-rgx}0^G+IbhsK(lS+y~@-g9UpY(pV*4X>JocdxG zOf}3)3Qt%LX^swEUa*oUL~~-d^k{rp7@kh#J&`%?{D#0*I5N}v*~=QQrA^e#n^Kdn z0z>B|V#|xzA?5pNJf;g-sR)pH^6+lU3wUsW~i> zL*8xhi7I6Kf>?BYRrB9O^bu8Zvx?j2JUQWN@<aMOWfiV3fU$wBaF*s+a(Yh%pw*I zf$)i{WNFc06Z#03T!S(Cf;$3bw+XWlLsQK3C@YyUVJt}-_7OmdD`({)5MgWx8!k3M01ewJW;gSSi|7kDZiD!% zr$q;+!Wwp~p}p7M_p@1yupuoz1uJ^DcEXix6F){Ko;ewY%lW1;EBU4|#u0^I$ZQCd zJxl;SuByp-Zun?Og;`aDh>IwE9IQZYGt?R+}DqySCKJ zpG{PXO76&^x)HRvl@ zZp4;7Ol;AUAQCQRK9<;^!N-MY;hKdrO!RkuYp>?rf1G^^r;bO}7oQ{~FM8&Mno^ZK z!?H(_10rDp;Rsi*`~vo*h*Fs%n)(aD8eX9nFc+Y zifahqay45aw(OQAk1Bd>B{LuvJwA?9ArdGPru~zaPY+{{LtnsUAKVF-vdoFX6~n;u zsdyCmpf9*1fLN+YlFzn_lGsA#lTTQpthf>pW5jTTaVQJE(V_>iB!C`AAjDFZB!`~& zP_NkVbnwhh{q7zNvQ7HbO#-afQt1T8>XwXeyaLHdM~UFlM_sFF?tC zj4>mOk|@FiaOEsa6nZoTcZfL3`Iyf}RhtAG90^h43hwe*c?g6iVzG<>N&@(3@G+~3 z6&J%tkHdi2oQDysVe}}=HJb>Vs$~SQ$EK87qC``u$&he9D@j;lfLX=$Xb9tnNK`({ zfp93%gfaq!tVje(ZX9NWLz8p+FfP{=rkHIPdn_@lI*bX2vgGAK3?+ezha;ucl$eFfxiNk|3t&*m4h1$um9jDu#tcUQS9Tw<;@KA63?EG)iz;XK z5lgC4mI)d}{JgtzwiVJ=vK%nRVS_T46|CYSdJ^Inve?KchsZoj*}6z?_D|ijb&+1A zO3;u_ipoH%trpkI7l!5&3^Th@G2oLl-%n}kXLSH3SK$fHSNlt8!>miJFwTqK_q`Jz zvIjM$-DuUMo;Eu1IeSoZ>Nd=pjJnp@!du*b^ud&Y$-}H|nPCfqSct)2nRjnV6PPE8 zbGuLZ*iIt@y$BeM-fkaOXl~83Ygya!vJGioYnsP>HO6Idccr5>zb4ya z+T<2%ZL9F3P#I`QyS3UnDb4<+n4TU#`m!Tbup|6JYxhv!f6Xk{&WhaZNba0Iw6*nMjl1 z=i1WE-aNu3)`wrjn@0w8u_cl@U9G1|?RKkEWV1T0&ke{qKdLc}VmVqm!?dPRBCnV$E3|TT+B%u9io_- zHabBuhjum)hVOlxZyZ%#(CD$hU`$#-Z;%)XMW>+nRL8!vvpFAg)FaIuVU4JC-gtaW zdfc0&Zt}*c!+N9zBhrHSv7+!aJaWvrrEu7}b$EwivZ8D#`GPRIAx&>g(_3wc0S?hy zG?(>Bi;qc**QINk(=|R7*lmsJw$^l8TiT6j=xRIL3`?EI+Q~`l`qRE&{bL(MQjfCRhBgWH)f~goa{&| zdYG?Q7~mMQz{Hieb=YL%hVoZUt+1dk^vn$*G_ne=` zz>`n_W$Rh36@JUv{{^x9f>=khGOyf-~_IY z3gk3yNFOz(k6P15Z8rB{G%_$)fRA@HM6f^-?*iL#PS&R{8|+K^*{$hpf3B_P8{c$sb+x}=fMIWoTX%$(hkvk{%z-2iJDL~xT;#*9dz@4o~R>J<)6OV-? zPT_V}oivX=wDb+*(ZeH{FGPG5;t|Z1Tc1wjgPLEt{5ouI_qhLa=k!&LHmgq;`Gf|& zxUc%~hvgXl5Ko6bY3!IZmRlD0s~8#?CplfAd;*8rJTbY|L_4kDWH=h!w5R9Wg8$j}&d=?gJkOv5As0CPJn22yoX(*4 zpjQuAiEmz`tq#mhb>6VFLtFZW=4f`dF1_UY+oL(X#EQ(!e#yL-tjNq$ucu8X&cqQ` z0icK5$n+s=K6>jtjb?RzDsC2w&-yp7GQC!6KLIcuD|4}Wzf)FGr=!j^?{vy{0a|G| zw!N76ogL&*vv4zautn7!@f}}Z@}20B=u1q#)0Xb&lctSH)B2|S+tdBY&ICK7SV@qo zRIjvJpLBRbI=?ZU&ys>8ZIz_-Z6-y z7yFy_*6W^2_R~6*H;%u1K^ydPNVJl0)g(X?6bv@?BBd!?Iw7{~+sF4TfpY-ND0 zCj7|I)SZLhk{(<;Z8kdXJSyEhCOxoj`kB5Kw8MMCH*-feKjf# zAD!p~JB{vqY?==%&FNxVM7yMyd!!}n(k!aA+~EhLmq(-}o6{_>*3#I*7a1FR;GbhY zY_q~J;FLwIM*B4HqemsKM0SKLh|9dAF?CS)YqR-MI6k}juSp&I_d2_QtlVrB*UjtF zn{?FlQ3-RK)0@Lm*O)VWysi2{o#B&VHqdD?I=IFaH$HvPks6w96)-BL%;~X5xAXwZ zp7u^F=Tb|yIBDkrX^*DV!YW#RJ6f6Rg%v8j$@jlLc2Mo9Ucc0ex$*kcF5Il>y26;TKeap~^gPd!?`Yrehjxh&ST`IND6S z_VtKVXivwCwR%FHzQl}Z=7!@vpU<|G@ZR>Ws24`hi-V?)5IQWA=g@+op=jlsn8fp&h4}z z-Q!E=EEt|9w%D7?LRJp-mzSB`T^Tt(!R~wa_^PbDcRb=1trJ)xkO~+}1P)6-_D($- z(!Pyp-_iCRaNjmNGY@J=lN!^c)-;K=gWJ;M6tDJf$*q#Z$f|H0#-{WUOE$1rLtXli z;x(ra=|$f&o!28xYe+{lrXxnC^F~;;_6SaF?!CD*xG4?h+NT=H(nbB#l09vWSDrz$ z7*d@}$2O&7N2Vb@u-dxy4ojbRP7NF)U&w>I&7|I13;2uvHb*E^Elu*n^*)ON^FuRb z5X;iV5bwG)iYhd-a8T3Z&K8w4X5<*{3ljO&!OixuW~*{{;mxJ1J!{4ewPw|sJ?yoV zs^g>abMql}L|VtYZP2%{==Oc%+KhdP-ja3p1F>wxLZ9G^+uFh|>2E#L&)$=HvcFb* z-;nNWOb-l5f8(Y)GX2b>&0jRWr()Tf?(@3Pkv?jM4*$&f%?s2T-E89G=Nr@WEvY9{ zO#3*93-}3Wf#)Zn1wI=0ST>h6bD276Sn5;T>AEg$QJ+@uyA2-&wisqjh#d2?xiK=c zL0oZMZeA_n;^Hmf!uqsJF2w}Pyc6}IZcjBk>uY_XFNw&U0GsAq5z?y0wBaLbkQlhNVY*QLsh3q))n~4vb?J-~s6qKN)xr>h0xxg0+^q zSRLTRy7Yaw^dm1X_33V(HtO?Sy2~FEJNkOQd=%!+$+T2=F+`#zz3sC|u@>Z9_K5pQ zbNZgk#P6aL{gd%TZb9__j4x zN+sX$D#w1cq;*HzD?G1Moa*a)?@Hb`nFr=iUK?|XDidGp-l3~Mm5rwK-iXAr=C5(S za&fDT0{)AB2+iqFuWUTfBb`4Yo!`fnP<%MvhFEclwU+om5MN&^M&j`lg7sZr^~#OMs49mRu^hXzptIv z`cotJCi>^SMCc|G^R`Xm2p@sY{a#|i$ko!!;1qS<6`k0zQ^@UZ_z~N z)d`-Pyx4N^muXDP_*sz~nckv0?W+dxIOB3VkmUe+r2BdL(9?qs9wXBIJhr$+@I>ZW z%qs?Sf-&nCOWrr6Za%36?Nr^fPFcK$=Y4`Q9=JS7hsIlTbi?*zes_I(&0oEX9A|C| z&FSu8>2mMJ#*6S#^eW**@|yp#Uh}6qYHM3Zj|)x}um5X>YhE091>kq7eG7;RXKfD+ zVyOdAbEwJo|9Q!5a*O0#p+H6eCO))%GP5#>L}D@|xjtMY3yVF+f})W&9gW~>fO zz0nycFNt7-mqL& z^oHd+%9biVx?38+5T1Ig6?gS+IY$k%I>4;PG^;huYDYpQKk@FqC!$HImtZg;$8&?;;5?PO!qsHd@jSCJP_uB^U3R2G;x4pocEYf~yfWBRhUbgFEU^1_-i9V;s~)#E zrO!E@)y=UQNJn}+&R(u}Pj2I?_zApCo5I+^@#?{I{yMfX2Z7!1V$boSw;Nl@qb)jG z3_8*^S)&2F&jCNKF&)>Mj;lTLS!2$xxiquMIvCI9x8Ns;mwnFd=rG1}&`%z=XlD*b zJ1Y-U@u)l}au$@3*Iko=qY2kgZ^?IoTMjTD}aN|cjp(f4zJPh?z#i}%#a{q% z=|ViSyG-)s(DJKDe=W51w?ZrbZP4<+3*yqPr*j`n)Gi#+wL4__8*BKEB;gQbMZ^Xe+6y-zk^nudC>B)LRvmF$a*}Vr@dT! ze|CL6wBt#=&ab;cif1snAFsjC(yt-?nj%AZ~aTB!d-y;1i@m6s*wDfm~cSEzkSMm3W_lpleEBBMoj^E4B&bv9#(tRv`3hg+~ zg_i$M(*GjPhqj*!B>x6+X`$r5#2g2~@~sm)i(R4F_YiwQJ5Lsu+zkEq7W<0>pxG@0 zE#GCOUrt;eT6tGe{3_C~DtUFugQ3~2DGrmqMH~(-|B;egC6AK4w&XFA+r@RnvC#4# zFL_;YJ#hlG{5KFcl73@x6X`dTyt(8pC2u8eEp7vCd)rIiLEKT?N!(f71={u}ij$$G z-$U_xihGHBi~ERE#C^s6pyhV}wBP42=?@p_D(t`Kk>XL%uD2qz^I*C-Lp)9K=R!LV z&XatZ;w#Y3-&-W#Cf)_j{%*}h~?{hy*0-t?WI*>{0NrJj--MLuhI`Fe|epgl(i zD1IsFmzGRxisv^7TK+3Qdk(D$t$f23KT`2)L%XimhgM(NPVqa4JBhnMJARWS?*=Wu zy(Le9w!H(OmG3C&kAZfdnyUB{C7%H;zq24NU5IDD<3-T&xeVHIxkCCfwC!CZ`C9Qh z@p|zFXvgtZXz6bg?@;`m;$70;Bi;us-6PPp|Ah2UiBCf-?{mlJ@ryW5oDVJE-zEP6ZF@AWxjhXWo=wjb*%o^KzXenXM=BhQ~TK0F=YrkvYA zE62{zwzsP|3EJ_P46Qu-N@fx$*Y7X#xz*(Zp_S_pX!#r_9wE~5>H1^DhU_U}*WS z1+Bb8p_O+GwByQ1O5gql;uhi#(9-P!?fC2_c`s=B>*+elHz@uV$+tq=-tExr9)z}?hoI&27_{^7 z8EEBwPJBUp3EKVcU1<5d4=w!%(9(SdE!`I)y;D5j@1X79Jn8APPq`}aCSH%y7w!IeVTP2TzwqIkQ zvr8GH;R44C7_jK zNy!7C;o;`{)#^k+V+nWPk?rwoC<9_ zXF$uJE*t(HU50kP&VtsC@(8qiABATB1T_1npl#<_#Xl!LFTNo1z1Zy;J>cnI72gow zhWxbYV`$s?MEq3z4BGyFBl%ls+y7qtL3(;9czNbQE9bA`AJFU|8Zi6I9^;=Tu)>&8Mj|w+(6t=+(_J5+(g_| z+)UhD+(O(^+)CV9+(z6M+V8f5JG#GS=m#9hUS;v{jhxSL2nVBa4)%Q^QH_Y(IO z_YtRv`-=OC`-=yN2Z{%Y2aAV@hl+=Zhl@vuM~X*@M~f`g>gA+=hx0g*eo!tSFP;GH z`kN+sy7+hTMDZk%4v3!qWbqX7RPi+Nbny)FOmU`omUy;!j(Dzko_M}^fq0>Kk$ACq ziO2{lFW+V2<>D1$S*(axidTtOi`R(Pir0zPi#LcjiZ_Wji?@ig#9PJL;%(yX;vM3h z;$7n1;yvQM;(g-%;sfG?;zQ!Y;v?dt;$!0D;uGSN;#1;3#HYn)#An6l#OK8q#23Yv z#D9t}i?4{Uim!>Ui*JZ;if@T;i|>f>h#!d`i=T*}il2#}i(iOe zieHIei{FUfir|<#Gl1q#ChU;ae?@&_?!5<_=os!aiRF9_?Kueh4vhx ztAmr_0!|icb@FB3N$(qH7qP2Ie+Spo`^wo}r0a^ybjWkk71_yf2PaECIq8SsWcFw$ zy&Ihjb#yK!E-o%1Hi>k>bh~DeaeFTJ7YB%RU3C3Y;?iPXq?@3})91}ONL*H2PF!AO zDqgo+QCvw}SzJY=mzmqGCax|H7S|Amh-->#i9^Ldy0FBdyD&sQ^bA6 z{Y1KEc{vUc4-^j)4;Bv*4;2p+4;PORj}(s*>FDVB(^cP}-^WWnK`e?TajG~?oG$)d zJW)JJoFSepo+6$qo+h3yo*|wo&J@oQ&lb-S&lS%T&lfKcFBC5lFBUHmFBR!E>c`=7 z@d~jlR>UjCtHi6tYs71z)q`%7e3N*yc#Akoyj7en-X`8I-XY#8-X-2G-Xq>C-Y4EK zJ|I3QJ|sRYJ|aFUJ|;dcJ|R9SJ|+G`d|G@)d{%r;d|rG(d{KN!{HOS`_=@TCl_%HE2@qO_F@k4Qr_>uUr_=)(b_?h^*_=WhT_?7sz_>K6j_?`H@ zI9L2Z{89W#{8{`(oF~o~7l^-#zlpz#e~AAU7m9z1e~I>z?ayhX z*B3VsHxwC5=J{_dZX#|fZYFLnZXs?dZY6FlZX+^Hj_13bxV^Z8xTCm}$P5r}zl*r5 zI8kI|l*dmNcN2FP_keak-$(KkabIyiaewgu@j&q)@nG=~@lf$F@oE&=ZhCWJIM?JH@-8?azIZ?-w5s9~2)F9~K`G9~B=H9~YkxpA?@G{~?8IS z7ZVp3mk^u8CBIX^yC3f)?gH(++*R@<$&9`C zek!#5PllHNsp9F-wtp71?VJtm`@;o_zew?yL3^H*q1jc$E1~6gwd8BWYsKrJrMpq` zP0;Lbk<7Sd-`*XP?^OKV;=R(}C*BV&zlWfe^Kt2)5T6vEf@b#&wCz17zM%LQ#h0Mj zy(0Nl$!|bQ_m=c;i|>f)f>y58pyfAM@>=3>Xy0`i zL+R<)k$yb1{n$YI4aJS1oljdz-U?d2+d%uSwhOd$yD5HmaSv#AdqFGDzR>IrQvAW< zA<&M~QId}qj}ecBme1cLA1}Emxg;_#neWduaXPegCqmoqsnVY&{TU*w&3n4D#Iwb7 z#B;^-#Ph`q#0$lX#EZpCpl$y$$(KVr4p&OPO1xV7>m}bH-Uu!I&600{yi%t7B{Q#u z$3Fxu-^V0B0quPFhva9VoiEQy|AP2W#lNEXSH;)F*P-S6HniX81IZsN{u9YxNd6L9 zdB2wYjrc9J^2}BIkJA4HE&ut_{|fCqW1za1*KTr_A2SCznG?_1MPyPBm%EESq3vgb z*a&UAy~V|#ZEs0v`SueBh)aoiaT#d&4T6?#1!(!LtoT(GznbL1lGhN2h-*T-Pmh9& zL8gK6?Qa1s-)*4fyFIkyysPBN(8{?xwCi<$X!Zv~E7u|7q2ghRKMLCRrb0`1DzxkL z9K~M%?RvNr+VQ>$T7FkU+upU}_0Y<7lj3idewO50CEq6bcJU7B?-K73nL5z7bHDh2 z^bd)TNdKt#7_|L;O7cITmG2qJ&x+4MvwKPLFH8T5_^R};OMXLq6Wad0Bl%tNU*db> z`_Sy>Nd8FtSo}o%RQwE@{g;xz62F%IJMjl-`}33HnTOGj&oAOUalW`f{8ju-{2ki% z7E1n8WTHsVFZBsB5Z7g}DH?(y7Lc1;wlYAt!avuxrIyesI;ib}-p23r0v ziLXOT{|4k$BYgsGJKsXf{|D&5H?(rhgJwS;T0Z}Vc7N|iXE57NBcv-!YKE46AT+x{ z5NFGMx;#o83(bCGaXV=FZx5|Jdr96KS~;dbJ6;DvE6-uj@;^rM-=L*GUUEtDRA_cH zpxw_dg_hst(8_tGcr7%$o5kCq+1&~4e)OQ^hoPl=T=J99_WxPwUxb{>=>urx`4HOg zJr`R3^PuIo5Zdq5l|os5J)mu`LF@%>yyEhTUs?K9p>1!7^6XQ{5FQRy-lUxO!_UM+3zI%&eBhWR^BO+_ZJU>Ha=|zwDaLS=`Vz~y^Elg z<1%RdJMWPGPU-K3R*w6jmH$y_+kY0?e!c|lcYgzN$kLb4>Y2Ylv;Q61cK(1?zRnE( zwDJsumhaNgj`s@C>{f)9?`qTs%@d8rtu4oaE!hBDDNU(2mn7l229q>5|V7&lG2hXNhNv z=ZNQu=ZWWw7l;>%7l{{(mxz~&mx-5)SBPb?B3>z81#SPYk$kOqop`-?gLtEOlX$au zi#SWXRh%u}2JLv>Dfuq(Zt))RUhzKhe(?cl=gp(g%KNzZq~f0v{~5|Y>Ax1g5x*6`6TcVd zia&@yia&`zi@%8T#QEX^@mKLT@pthL@!#S?@lWwD(QY1g-si+c#5%E)*jel%b`|Tz zZen+_huBkW5F5o_;-X@2v5(kSTufYCTtaLTmlT`Deqw)dfH+WGN?cmZiv@8RageyI zxSY7WxPrK%xRSWCxQe){xSF`SI9Oam93rkMt|bl?hlwrXaB+kXL}(c&@UvEp&!-^Am^6U3re5~qsO#OcuPrzc82Nt_{`ES>`GK7OX; znc`XE+2T3S>N91@74b@F&+Qu|-zeTB-YniC&Ju4GXN$Lqw~Kd(cZzq3cZ>Ik_loz4 z_d_esW0D^ipAerEpMrLLo|gQK_^kLGwBzzm$uEnqh_8yTiLZ-qh;NE-iEoSVi0_L3 z65kWw7e5d`6z7N^i64ufh@Xm|L3_S^1?~Cvt@PiC--~m_AH*NUpTwWVU&MLhd~t#J ztN5GvyZ8sR<7bt2e@=6H$XsDAGliRz2@0KEMdrtHxf`_oVlqsZ8%1Ulc9|70 zoxR0AVqbAFadB}8u}NG~Y!>^8{lx*|KyfK?X)!Mr#AU=mBC`kj@3Dg96~&drm7yIk z<_-1zSVJ5luBrIpl1GRm#a6LRWOgghXKit`$TY65Zx`2rc3j6xURPXCoFJ|b?R?ru z^2XvO(9&-qc}sCCacglKaa(aaaeHwGk!d!)d^?Fdi@S)siW9|2A`^i5^}M@e=H2yt z_7wLL_ZIgNr--aC?DqSK`-=yN2Z{%Y2aAV@hl+=Zhl@vuM~bXP>DxJ4JVrcLJWgcZ zRJS``JV7jqC2^`aO`I|HR>UjCtHi6tYs72C>%{BD8^jyMo5Y*NTf|x7t>SF)Ht}}x z4)IR$E@;n-dnDg0-Y4EKJ|I3QJ|sRYJ|aFUJ|;dcJ|R9SJ|+G`d|G@)d{%r;d>&dk zUzGfk_)qa=@fGn^@ip;v@eT1!@h$Of@g4D9Xzf;?N&Z~?Li|$vO8i> z58{vFPvXzwFXB9LzPLdARs2o-9a{biCI2b@C0gT%wP*B%_MB=E8=<$~N$w~17YB#~ z#ihih#k^P$mk|ev%Zkg1%Zn?BD~c;YEB~sJR})tk2a9WnL&P;jmZR|f8Y&JGTg2hw z2yvv?Dz=HE#I?oI;ux`ATt^%$juSh?@#4DTdg26V_l1omZz66A?R?%`@)qKj;#MLH zclds8BW^2hCvGq9AnqvcB_PZDQ{ zCyS?ur;4YEr;BHZXF{vDpD+0W@j~$;@nUGl?NZ5?iIlOp_=xzZ_?Y;(_=NbR z_!PAJ$1{?j6`zB)fB%&HviOSls`#4tI<)rH_a%QIekjfnKZ2I;=aRn=zZAa`zZSm{ zzZJg|zZd6h_WKEQ={oB~rXqHk z8Ofbp#I7RCGWqdlT@{b-DYC4E%Z*|$ktxw#&!P{`J|e3)xV)ISxVVJaB(j2s+ck^* z#Qx#{aiF-AxU|R&x}LruGP$H+d65aNeLq?1!{b*GR~1(iR~H9EyKb3_ z-|g2F*Aj<{!=Tv>mpnooDYlAj(Aty7N$wEGLrcG&WF{~7?X54e7LUstiW`X=i<^j> zikpd>i(80Wid%_Wi`$6Xirb0Xi#v!riaUv{zvt!JMch@KC{7Y5i@S-ti+hNBihGHB zi~EREpdFw6B=0XCARZ_lBpxgtA|5IpCLS&xAs#6nB_1svBOWUrC;m-5UOYi8iY0NX zI8B@`{#`s#JV~4(o-Cdso+_Ruo-Upto(b*voF$$ko(JtddZBoUcsaE1ZdZ#pLaRsK zB;G9EBF=)A&u!4|Gk1yiLCfb6Xz3q?R*uKTC#8Q%{D=6o_>B0h_?-B>_=5N%^zX5f zKZLfOkD!(7Q|UhwKbQV1$zMY&_xF2yvv?Dz-r@ zU%TXWAfH;(){sv#X$rJ@%)!w1`!Hzv9wis1I2^HgGCm5@^puahlz)aM~Fv?M~O#^$3Qy|Pk>g= zk~mHA(PsGo}FQA=AUy5IeUyI*}--_Rf--~m_ zAH*NUpTwWVU&MLhd~t#JtN5GvyZ8sR{rXe#Ut$^%(RiII%+< zFRlyCegd@LaYN}h5;qn%fo8XvJGq~AsIuHr=L zCrjQ<++Ey5+*903+*@S9C*S`m;=ba3;{M_R;(_8p;=$q};-TVU;^E>E(4HG7LaRTW zBbK544p&3Fj;|4~6|WPo7jF=66mJr57H<(}iMNWg#oNT&#XH11#k<72#e2ki#rwqj zMV5Z^az7|OBtHCqSi0+YE2{Qyz&vz!BS?35hk}KIAl=fSfFPx!(nt!3piw;m?%)|MNWub21lmGY|7JAM>*S z3$hRkvj~f_7>lz6OR^M8vkc3!9Luu;E3y(RvkI%S8eihetj-#Ig|G58zRovTlW+1Z z)?#hG%{r{hcUX`0*?h8VP1%gi*@7+Eis4TP{{Q3Nnr+yY?bx0j*pZ#sneXv^ zc41d`;|J`{9{i9!*^9jy{$l0-@3${M;>Y}i{rD+AhF@|l$8mfxx?fI|C-ED8%kMauQ#h5=IGx{f24`{>XLAncavtY%0T*%+7jp@h zav7I%1%Kd5{>W8a%{BaqKXWaA;X3}x_1wUX{EeHqnOnG(+qj*-a|d^F7k6_H|KOk8 z%YEF>13bt>Jj^3J%40mv6FkXNJk7uOH_z}a&+#9g=LKHmC0^zgUgb4j=MCQEE&j{f zyu-V^$NT(`5BQLe_?S=ll+XB_F|z#M_2Pew$ykidIE>49!RY;%NKVWoOv+?T&J;|^ zR7}k@Ov`jk&kW4SOniZvnT0PhE3+{>b1)}!F*oxtFY_@!3$P#yu`r9UD2uT;ORywM zu{6uDEX%PxE3hIfu`;W$Dy#7&zRc>Z!B_YyU*qe1gEjdk-(oG+=G&~px_pQASf35p zkd4@wP1uyp*qklclCAhITeA(@vK`yA13R)4JM%rh&o1oBZv24V*@GXlCws9s`>-!R z;>Y}i{rD+AhF@|l$8mfx`dmFh{yG?4PreOC z|1M{?JUv!6?TLM)MG#iG$Jnq>|GGqxCWbqt|6*CiTq0X!}{! zvjwB=<&tw-o=?ut0xZZvEF6qpUtBK1k}Sp2EW@%a7mWI?AXj81^(w(=e6Iwf^QC4m z{HkY+=D}zjt%A`w-(~Ayw7s@$uiioK6pUW?zIqpSWjB7n?(D%2*^|B4n|*@O_CJN*|OSz28xgr={7uE%%@orMz%q_vF-)-{tU^GuVgVFkXc{muYchvF|@~L2SoKLHt zk}iR8pg z!lX>b8EYAw8$V#ltDy+(Ce2Fi!I%@=@zH0`f>*zbd=zh^G81>bhE!dK+f>FP% zHlpb0R14 zn_#rx$-!tlQ-jg^)8y~v8Jwv;Tb{$YoX7cGz=d4I#azOrT*l>G5sc28UxHDe>x0qz zWot0%b6YSP?{0ZdFj{Y~ypQ{NfCqVqhk1lYd5p(-f+u;3r-M-+{{*9Xybw$ryd8}C zyc3M-_vHKXgJA4Xf1>`B&w|l7{+I3lULTXO7@Khzm+=^%379Y#&07jNWiU?2>4H(; znbordqdv1TyLt}hWG?1r9_D2}=4SyGWFZ!25f)`J7H0{TWGR+r8J1-^mS+W4WF=N+ z6;@?6zQmV<(Y(|MM#t;*V04|R6O87uK`=UAjf4LSHeu6X^t$G93$|n{zRT8Z!?tY4 z_Uyop?8MG|kMFY!yRsWUV0ZT5hwRB-?9D#x%a8amKVd(9%Fp;Y`*Q#Xau5e|2#0bQ zzu<6=;7E?*XpZ5R9LsSW&#yRvUvnZS@f&{2?>L!LIF-{lo!@f?XL1&2a}MWn9_Mob z7jh97a|xGn8JBYff8a{~$W>g;HNoh-{#jnjU$~CHay>V2BY)#2Zsrzl6w8UnTanjGqdnTW@R>JXAb6MF6L$)=4C$SX8{&uAr@v4 z7G*IOX9<>MDVAm#mSs7XX9ZSdC01q?R%JE5#Ftr}HTVi&h=VzVLph9Ja5zVBBu8;H$M8#zU1rIg7J7hjTfP^SOWvxhNQYzgQEDKG&~T-@uLhjhncc zTey|mxShXq2X}H8cXJQ_;Gf*fecaCjJjg>l%p*L?V?53iJjqi$&A<3J&+shI@gJV& z1zzMOUgi~E$6E!@Io4`}~g&_>hnIm{0hW&-k1%a=7m@CSx%+<1jAc zF+LM8Armn%lQ1chF*#E(B~vjq(=aX5F+DRdBQx;@W@Z+?$gIr9?99QO%*EWy!@SJL z{4BtNEX2Yr!lEq3;w-_EEXC3+!?G;L@~ps$tQ3qH-v3pC(f82m!RUMGo9eZK(dXW} zay_|GFnT`pZZNujbPWD4*omEk(RSaLy9A@{bZ0Mq6pYsUBpAKEA3x=1{G9zcfCD** zgE@plIgDR$I7e_KM{zXA@Jo&jM*WWGgkY?YC-J*rG>*x^XuYZOG)`Ba5sc-)fh3oh$*K-3m2BUs9$(y-_Te*$f`8#)T zXD}M?UU^?Ix(}TSM)Pq-{cJE=?@};n@P07*eWZ9f|8IWdGXWDa5fd{BlQJ2TGX+yJ z6;m?}(=r{?GXpa+Q!sizWDiE~qx`|x!NS4lyePt=EEbIBwS-)frC6F}SeE5jo)uV; zl~_3#J^y@7emxky&uhuG`F1esqpti;FjmM7*jT*@o3a_3vjtnS72joRwqaYgV|#XB zM|NUozQ_03B^ZsfkK8vHU7rR7V+V(*59Kg^5sbz;G8m12v^+K#JLC!K6NAz5n-q-J z|4yFFDV)k_oX+n#gEKjcvpI)zIgj(XfD5^Zi@AhLgVFi7T3*ASf>Hm!1f%i(DsPlG z1*36p4o2tkPI(u1a}WREpWMrR+|L6%$V0)XkE8N2`D8HK@3~;q-+9X~@M17}-4*#N zuLYy^Z^$=!D;S;c_vHJ*XuSvWLq6hTKH*b7<8#Ky^?&p9KgMLNVC=B{cyjz;w7-N* zte%8PgVA_W$SH%-`l;2^si$WK%QML@Ff+68MP_9-W@irOWG?1r9_D4fVD$bfA(sqB zeV38TvRp8_PQM}73`XO5D;TZ+wt5}b1!8l?6ZG%xC z9n?Fr6FUc^e&3h7uq(Uq19oQ*e#oBe#op}0zWgW{o$vkS0m10}86po2M*R+#M{r~? z>T|R_hF@|l$8kKr;sk!piJZi5_$|NVWKQ8!PUCcb&l#M_S;1&LbAxe$i_{l$36}<= z@h#^M>MP|{@@lRLM%!I0|H5_rmFu~I8~GbIaWl7YE4Ohwf9DSF!9{#~UxtII6 zp9gr5hj^Grc$CL@oF{mar+Auw@o%2tS)L0<^LatO$VV$^He++PU`w{*yKK!iY|D0R&kpR!PVCJ0_&&R^E4%Rnc4rTM$e!%Q-t5D^{D>d( z6ZYe${EVNoKL>Ci2XQcma43iI3l8T9j^rqg<`{m-u^h+o{E8F!H79Zszu~w1j*~fs zQ#p;(`8{WFCTDRr=Ws6PaXuGtAs2BmmvAYUaXDA;2d?CgT*cK~!=Lyw*YX#xi=E$NfCOgFM8;Ji?1Y{hrknr+yY?bx0j*pZ#sneXv^ zc41d`;|J`{9{i9!*^9l|hkf}GKjtUw$4~hgKWBdq;6M)IU=HC>4&xUb&Ji5RQ5?-N z{E}lij^p_iC-7@dZ}}Z3a|)+&8mIGn&frYW;%v_0T+ZWsF5p5g;$kl0QZD0i zuHX+`$sf6jtGR|h@n^2(FI>l8xt<%ik-u>hH**WOavQhvckT#A-*b1%dxCL7-XDxU z_a6+#4IU3h&t*=l{~e5;lb%sO&&$Dhp?)hEz5aGETJH|;2BYmfkRS39AM**H@)@5q zMqc+n#$+tUW*o+4ykOKWiN>0Oc>Y0MkI9_08^=xu>=3vfXw4dB^9_D2} z=4SyGWFZ!25f)`J7H0{TWGR+r8J1-^mS+W4WF=N+m0&cUYVu2bnbj?SMSe9HFRWin zt{sfdt9o*MHekbGbRISdM*C^T7M8bUE56ItY{Rx}$M)>Nj=`vpE^^mk{E&MGqy6?( z|A-&+6ZYe${EVNoKL>Ci2XQcma43iI3l8T9jtu_)-$#(Y4o3Y>lE2}%{Em}3g;P0= z)A>DTa3*JQHs^3I=W#w4a3L3QF_&;DmvK2)1fy}SSzc@TI<8mWz>UFZ z{mt^0V6@$B@^*QLypy}Qn|p%McJ|8qxSt1jkcW7fM|hOSc$_DAlBal@fAMdg;n`r+ z*LnE@FY=P*SLJKG&KtbRTl|-|d53p-kN5c>AMjx?x~@JAM)Un#Jw`s)>tIxmCC8TI z%JCSV37C+Hn3zeJl*yQ!DVUO}n3`#rmg$&27~S`>1f%Ok4)vVDsQ=u|tDY|ytyh>O z)Jw7yOS25ivK-5^0xPl-E3*o#vKn9F%dE~C!KlAC3UGb$MMKSupaj^#Lx=U2gK{jcSToWyVVEx+Sr zPT^Ee<8*${8Jx*koXt6$%Xys71zgBQT+Ah0%4J;675srK`C~8||LS0L-B~NIJqMmZB-U}k3Fi_FSw z%+4Il$z06MJj}~{%+CTW$U-d4A}q>cEY1=v$x{yRa*}@dI{e4}Qp=?8V;f!@m58AM+FTjnnx(XK*HGaW?00F6VJR z7jPjLaWR*0DVK3MSMUd}M$lth$o4JKsxsBWTJ9ls= zcX2oO@DKjUz1+wBJivoI#KSzoqddmrJi(JZ#nb$YfAb8_@*Mx+d0yZ}UgBk5;Z84j-r~Q!%{#oyd%Vy8_<#@jh>!V%Px*|`8KZ#ji;T%wjLkTV%Xo~>1Wd?8Ow1%q z%4AH=6imrfOwBY*%XCc749v((e1Vyng)cHIvoSk!Feh^{H}fzr^D#dQupkSuFpID# zi?KLMup~>dG|R9o%dtEwup%q5GOMsEtMMhi%<8PcSNJMlN*|OSz28xq?4%C4b~9uI3v4 z#GkpAzi=IY<$7-5M*hZ4+{`W9%5B`v-?@W3xr@8Ghkx)-?&Uu24@TcJ4$6mkm`8Y& z$9SA4c#@}hnt$V|*rHLMCEjCSg)0V{)coN~U6JreRv9V|r#_MrPs* z!RS27!mP}0d5&Q8oH?JIKNvj+EE0@fS4_P)ORywMu{6uDEX%PxE3hIfu`;W$Dy#9O z;Q#;LE!W^He3h^9^h8VP1%gi*@7+Eitn;D z+psO$v3)QaN5^2)_j~H^t9RuG>fPCcAF?NVu{Zm$FFy)K`{@^q9~`VcghPW-KVQhh zIf5fCA1#mJmmC|6o|{dOzvjeXwB2vyZ}}Z3a|)+&8m9-N?aq>CbB_9gU^K49>PzJ1 z@(TXImHd&bxSDJD6MyDf{=#*^=>4@x-pnoB%5B`v-?@W3xr@8Ghkx)-?hQucJs=@A4k+2c!NT$Pf95k1c;1 zjK&$Gkn1>OG8SVqPB1!8637Xeh>4kmNtukvnSv>qim90<81A%^d(6ZYe${45yt+g~2QfgHra9KxX-#xFRWBRG~lT$z9ydJ^X`zaxeFBKM(LA5AiUM@F>Ov%%;*|3^O03%tlnyv!@S%4@vN8@$O|{Fk?Rhj)38_xT?m@F5@Z zF`w`$pYb_k6m~yiOvYkt#$jB>V|*rHLMCEjCSg)0V{)coN~U6JreRv9V|r#_MrPs* z%*-r&ky)9I*_nemnTxrZhk2Qg`B{JkS%`&Mghg45#aV(SS&F4uhGkifAoXTmO&hI&cGdYX1 zIfrvOkMp^J3%Q7kxr9r(jLW%#KX4^~=3o4qXLy$9_z%zX0x$9s zFY^ko@*1!625<5f|K)Ao;a%S2eg4M>e8@+9%qM)xXMD~WMcnThld%|^aTu5J7@rB4 zkcpU>Ntl$$n4Bq?lBt-QX_%Jjn4TG!k(u}cGcyZcWL9QlcIIGC=3;K#;r?upt|4&xUb&Ji5RQ5?-N{E}li zj^p_iC-7@d@Fs8ZU*6^&-VH|EyUz#e59P=56Fyac zF2^Y9e#e-M#n_C)xQxg6Ou&Rp#KcU(q)f)-!DxO{$*Gx!X_+nau#QE4(DZs+gZ z!JXX2-NC5uKjppL$NfCOgFF{)#nep0v`okJ%)pGy#21*ES@lz6OR^M8vkc3!9Luu;E3y(RvkI%S8eihetj-#Ig|G58zRovTlW+2^U^Fjv zjnnx(XK*HGaW?00F6VJR7jPjLaWR*0DVK3MSMUd}M$lth$o4JKsxsBWTJ9ls=cX2oO@DKjUz1+wB!RUQ{NIuLX zJj!D{&J#SzQ#{ST_&3k+EYI;Dp63N#V$^He++P zU`w{*yKK!iY|D0R&kpR!PVCJ0_&&R^E4%Rnc4rTM$e!%Q-t5D^{D>d(6ZYe${EVNo zKL>Ci2L+Rb>&5tBg5YHJDV)k_oX+n#gEKjcvpI)zIgj(XfD5^Zi@AhLxs1!XfDw*%q`r?ZQRb^xq~~oi@UjpfACN48n2?E>m`RwF$(Woen3AcOnrWDp>6o4w zm@ycA?#e7@;fw0ogVE0~^2!A)FUUeH%pxqxVl2)QEXh(V%`z;@ax5Q=KHpT7D+Qyz ztIE~*l6npKm0kKu|6BHAsewVo3JUH1*1M&1fzdH z-buZ4F#35>cew{YWKZ^DZ}tgB*Y*DL01o6J4(1RJ<*;D%+;@~bnq&B7FzR=lJU$q$ zKS}4~#Kl~~rNL-C%lU))O8&@IT+KE7 zi9d5Kf8jd*%Jtm9jr=Vbo!49Bt=z`#{GB_vle@T^d-wZjz>!RR^8S^1ph=j98$$V49jL!s2$V5!cBuvU=OwJU+sJ~QlYNlaYrek_$U`A%* z3(U+ce34n1joFza81<1$&dof`Yk7XT01F1A`7bILV{w*XNtR-1mSI_z3r2lZkSofS zC;0T*%+7jp@hav7I%1%Kd5{>W8a%{BaqKXWaA;X3}x_1qAQ-q)Lh(ec`< zzKz@YJ9ls=cX2oO@DKjUz1+wBJivoI#KSzoqddmrJi(JZ#nb#N7>(8n5#PZ}JxZKUEbq;{>KNwsQ*XuV?NcEY1=v$x##20VLjGo12$wMHf9qxWivKs3$|n{zRT8Z!?tY4_Uyop?8MG|kMFY! zyRsWUV0ZT5hwRB-?9D#x8;sufAIqPxA3x=1{G9zcfCD**gE@plIgDR$I7e_KM{zXA z@Jo*6IF9F6oWQR+k(2lhzvXwF%qg78X`IgQIfFAfi?cb0b2*Rmxqu6~h>N*|OSz28 zxq?4%C4b~9uI3v4#GkpAzi=IY<$7-5M*hZ4+{`W9%5B`v-?@W3xr@8Ghkx)-?&Uu2 z=K&t%As*%t9_29}=Lw$VDW2wE{F`TZmgo2n&+`H=@)9re3a|1Suk!|P@)rN)ZQkKs z-s64##|M1KM|{jDe9C8h&KRZL_ZgG17@Khzm+=^%37C+Hn3zeJl*yQ!DVUO}n3`#r zmg$(D8JLlo_yRLC3twbbW@C2dU{2;@ZsuWL=3{;qU_lmQVHROg7GrUiU`du@X_jGG zmScHVU`1A9WmaKTR^v;2nblc?ukcmA#@G1jnnx(XK*HG zaW?00F6RZK@hy-SauF9>zEobu|B1oH5F{e=;UxF*f5cF5@vi z6EGnYF)@=cDU&fdQ!ph{F*VaLEz>bQGcY4F@dajPmSFV0&L(GP4(4Po=4Kw|Wj^L- z0TyH-7G@C^Wib|K36=~-&lSrBqdqIDS7K#WVO3V+OMIEtS%a_eRldg8`37t9O}@oi ztj)JshjoL|`B*QQBG^v7Jv*=?I|ZZXab4uD?8Xn+ojv#=d$JdMvk&|7BYqr=`s*iu z%Fp<@4kmNtukvnSv>qim91~X_=1cnSmLZi7zlSv+zY`Wj1DK4(4Po=4Kw|Wj^L- z0TyH-7G@C^Wib|K36^9jmS!22WjU5-1y*DwRt`q*kE(JtzQmVVoi+FhU*&6joo}!v z-{f1Y#oBzEby%10upaBP0UNRr8waEFzlGeAt@timvklv_9ow@5JF*iy^F6-LF6_!~ z{D9rrgCDXdd$BkBurEL2$NYr-_$fc*=j_h`9LPZ&%pn}gVf=!_If5fOilaG(UvezR zaXi1`1b)qloWyVVEx+SrPT^Ee<8*${8Jx*koXt6$%Xys71zgBQT+Ah0%4J;675srK z`6E|xHP`Sb{>-)fh3oh$*K-3m@;7ecW^UnDZsT_T&K=yzUEIw*{DXgTFZXdj5AYxl z@i33@D39?tPw*s9@ihP9-#o*!JjZ`{o)>tLmw1_1c$L?9oi})sxA-q_^A7Lw9`Ex% zKHx(>;$uGHQ$FK!#wh2$&X|nF*o?!tjK}y)z=TZ1#7x4ZOvdC)!IVtJ)J(&)Ovm)h zz>Lhq7nqq@_#(418?!S9b21lmGY|7JAM>*S3$hRkvj~f_7>lz6OR^M8vkc3!9Luu; zE3y(RvkI%S8eihetj-#Ig|G58zRovTlW+1Z)?#hG%{r{hcUX`0*?h8VP1%gi z*@7+Eitn;D+psO$u{}GmBRjD(-{br2!mjMb57?bO_#u0;7kjf0`|=}x%um>lpYk() z&i)+0fgHra9KxX-#xFRWBRGG!5_GiKXMgUa}9su&s@u2xQ@SaJvVS8f8!=@ z<`!<{Hg4zd+`*mP#ogS)Klms2av%5e01xsI5Az6*@)(cv1W)o5PxCMS%`-g9bNq+r zd4U&siI;hWS9y)sd4o53i~sUA@9-|~@jn0K13u&_e5-iD5EX^`3%W^Ew3arRVtjsFGsNZVA=($#P^%{JIuky8Ev|i0% z^gOqAF#29xPi_>9{yl7CHepjXV{^7(OSa;>Y|S=o%XVzf4(!NI?9BK0KD)3hyYT~d zXAgcDjOM8q`>6K~M)UEB+|TmQik1A@`|gXJL{%3=J1!#RQ@If|n>CK&ZMHW+RH zEAN*|OSvoC4b~9 zuI3v4#GkpAzi=IY<$7-5M*bFz_P<5m8jR+7yZpPnQ{Khh+!KsmzgOPJ{XD>fJjBC1 z!lOLKA&J$q)EY z{jvOnPx*|`8KZ*x31c!AV>1rpG9KdxqwywUQuSm^9*p`-DW_s;rm;MooSqq&k(u}c zGcyZcWL9QlcIIGC=3;K9=&PU1KGmfvwQr*JB#aXP=}49?^% z&gLA>$!m&`5QNJGq-Rn zw{bgv=ML`VF7DAMha`@iCw9DWCBq!dLkkU*{XF$v62H zYq2)pW*ye$JFLh0Y`}(W#KvsGrfkOMY{8an#dq17ZP=FW*q$BOk)7C?@9}+hVOMtJ z2kg!s{E$7_i@n*0efbeT<|pjOPx%=?XMYahKn~(y4&hJ^;};yx5gf@;9L+KOl4CiJ z4~#Kl~~rCi44T)`i>G8px{N?y%1!RYv{m4D$n{>t^-z>WNko4A=tLmw1_1 zc$L?9oi})sxA-q_^A7Lw9`Ex%KHx(>3P#8Isr-!38KbiMA!9NYV>1rpG9KeI0TTwJ z{Uwo;G8vOI1yeE=Q!@?IG9A-112ZxcUtnft;fu`5Y|PFa%*kBA=seCN=VdMDVAm#mSs7XX9ZSdC01q?R%JE5#Ftr}HG$3qHvJo4z37fJRo3lkQ>ZcW3tG8iWwqtvCU`KXhXTHbx*@a!%jUTW( zd+tLmw1_1c$L?9oi})sxA-q_^A7Lw9`Ex%KHx(> z;$uGHQ$FK!#;D@{$(W4A*o?!tjK}y)z=TZ1#7x4ZOvdC)!IVtJ)J(&)Ovm)hz>Lhq z7nqq@_#(418?!S9b21lmGY|7JAM>*S3$hRkvj~f_7>lz6OR^M8vkc3!9Luu;E3y(R zvkI%S8eihetj-#Ig|G58zRovTlW+1Z)?#hG%{r{hcUX`0*?h8VP1%gi*@7+E zitn;D+psO$u{}GmBRjD(-{br2!mjMb57?bO_#u0;7kjf0`|=}x%um>lpYk()&i)+0 zfgHra9KxX-#xFRWBRGG!5_GiKXMgUa}9su&s@u2xQ@SaJvVS8f8!=@<`!<{ zHg4zd+`*mP#ogS)Klms2av%5e01xsI5Az6*@)(cv1W)o5PxCMS%`-g9bNq+rd4U&s ziI;hWS9y)sd4o53i~sUA@9-|~@jn0K13u&ScjLBGx%{Yw9c#O{k zOvpq`%p^?8WK7N!OvzMC%`{BQbWG0-%*af9fti_wFET5$F*|cGCv!13^Dr;-F+U5i zAPccDi?Aq*u{cYxBulY0%djlVu{a4+6_$puH>wJSX`6l0D zE!O7Sti!r|hxJ&W4cL&4*qBY&l+D=q?9Txl$Uz*;AsotK{DQ+df+IPKqdA6OaxBMj zJip=ue$9!T#Bca5zvE<1;Z#oJbbiknoXJ_7%{iRQd7RG$T*yUS%q3jPWn9h`{DCX^ zBUf=X*YGF)%(eW5>-a0za|1W>H*Vr)ZsAsL<97be9o)%X+|51wgMV@__i;ZD@E{NI zFpuykkMTH9@FY+1H2>n?Jj1g*$A5U97kH7Ec$rstmDhNkH+Yk`_%Cns4)5|F@AE%C z;6py*V?N+L;X$uQe16XyO0 z@sKc&J2Wg99>&UH?q4;`?bTR4%<-HU77S13DPitcGtBeWV=ML6Y{Rx}$M(F09oUhb z*qL2;DZBDAcH`x|g5ATs4!y&Ct_)JYM!r5Q81)fh&hM@2_l9}h#)NtN1ly;DIUi4P zR+#fPH_ZJPh6Te{!1})=d*))$1u;|HO%&|2=lu3 zw!IJgvLE}0+1}Oiz%Y*=EDy1LnEDO!jq=T5_VX6r%G-E*nC;)myTk0~1M(O?#BrR! zNqjiWd6^Mr|DKj-%k#O2Z-o2Cev89A|Jz*3Wn3QSb@@pCBrFqoW4LeltNQQU9Ok@l z5BCjssqYE1e?=SY?O(Al=cRa<=Pw!N{$=E{Jct#-Lb1J~Tq(@;QJu%CA0HNq`pIG0 zu%3E@Fz2kmg7Mz&k8)4hwxBVG^Se4aSok#FU9>t@143Fh;Jf0`;M4rTx zS%asrCTsCjp2pfdoppEy&tzSm#j|-1&kYO3^{yZ0`fVsT4)cC!%4Td4=DKPrw`NEueZo|gxQ}vc~_YIzK8dP`P`Zi z=5bTQT;DUoJZ`4#FNJyBtT6X`#r6eZK0n`)m-1aM<9l4r6!uiK$vwo^IG zc|L|U!y=LEgn9lm!<_HBJd0=Z9G)8%j{O?Q7qFpvlQ7TMT)hQbvK3pi4coFE+lP6c z&T8?z1fF-*^m7>fLC)M2ZcE=*UE!AghM%u!+9OA=M5ae8+j8) zaujdoExeVt@pj(9J9$@_}$Ao#mj+Mu8JST7>Cvh?#<`holG(N&d`4}JP z6P(T&oXIEoRG8QG`7p1;i|Q}&WzOPk&f#3n<9xot1zgBQe3h^9b-uwj`4$&*3E$>B zT*`O3jPG$dS8yd)aW&U)E!XjVe!vgIoUf1giTbDfjGyxhe#x)+HNWAv{Epvq1ApL; z{E0tvBRBCE{>tC@JOAKj{>d%;i+}SUZsj&^=ML`VF7D%SZ;KIGn#eGoPRQ&^L=cq&h0ZJy3LVLlhn3iG}=N3JI~kS_}J^RE#bvk9B> zVm4!QwqQ%PV(YMIwA)ec#Ln!(OT&CFcatv<%S9d{59Kfp56j2)2jtNl!w2~g$8sFU za{?!F5-0OvPT^Ee<0E{OkMVIn5tfX8zAVq;?66eS7t2fdHs9e=zRP7{#W?PJc>{mo zkNhdj_nklGE&Pjrhq)fM%Ghx1>u^;s~?T!=-~i*i5i&jVO2%;QSPC0UB4StiW=%F5-!ysj1G zgLw!KWkntq=Jl*DAHgHT3Q<2R%=LUe8`^#$FJdD$4zoW^*-X8;+%nAmwNY=&c5Kf} z*nu6{DcnDf?=JV?mAop<=igv?2#0bQhx0mK&l@;`H}a-1=i$~c=j$HzdwC!4=K~zg zF?^5@aV*DiJST7>Cvh?#<`hm1^S*vgex5JzMZOf~IOfXpIG?X@0T*%+U*&6jop10> zzQx5{!ngSjm-1aM<9lJQla=x+uI3u9# zTbAW`5X-Xy59T2}lofdxE3q;UXBAduHCE>lJd#K8Xdc63c^r@D2|SS}@nqKEDXhs_ zJe8-hHcw|Ap20I&H_YcqE4ek>ux*&v`4YJUJBGPVyULfb8!zV-?9Luxw%1ec#op}0 zzU&v~^J)MGst*eD{6oY2!kg4bhWUATdzkOJck})*+Zi3^d&w9+$cH#K%;P48`5bv9 z%-{8A**;rdD!&`%`BurRxhBl}{j2bhaGUye?%+=D;_fit=PESW+is;WbDc29dv=)p zJ3q{E)C+T54de^hQ2nAXKi@mZo#eh@_Ir@}wPCh5Sp9nS5$ZScCXVDN-ppHgYna#h zj&T2QwECFv*vJdzMSPX7g*nc}@)Ewyces@AhS~nwFvt0=`gi<3%+H%YBT*`O3jPG$dS8yd)aW&U)E!XjVe!vg8o*(gJe!@@rS(tww_fwej zvr&B$f8nqEjlc7cFpv8)%Ru4R`??@eLjRkIgG=@Jbpx&e{bNvFz?R?!~Fc1 z5$1WG3-kSDahUBb3G?~1PJTbk`}XfJpZlen?LDr1nC(>zv%QnlPYbi1+B`kX{mu%r zA5Fu-Kt%2y=X+!rbp}^?SoS-x!V$bG=OpvtN_LY-b9m zsXxL;`4}G$bN}gK&eyYHp7%w0UYPC9537ft$)EF!F#Gp|{3Czj&)mpOVfO!zFweJD zeOs9Ge_-ltSI zz1W+5*q8m-p98`?@4zs}eO;LIGBwP0ALSEawm&^QB3vfF$K_$ksDBdXxc^fBJIr>r z$=k!cKMJ(iJB~tOwp%#N{q|EY9%g%oh9$zI!`$x}9?Ro+e3;jvMwsKNsa}hx@-)`w z>8!&ucqZ%eES}ACcrMT5`K-tKY`_b`yuQul7Hr8@Y|S=o8+vpAb`!n}`Pkr!|w7x7iT#@G2q znAc%xnAdB)`bS~5`<1hJd{===|L9xA9 z%f0t+ah707mSSm^;elb^&*kKUSe_MlFc0COVfMdrn9tAS)Q=DU|D2Fd3A6oLVLoTh z3-h=JwqL-8ypR{M5gW4!n}&IPT8H`m)j_>unCq~Md?~x~GIrzTyn@}?gI9(*o<4G4 z_GAAr*T)F?M&87c9L1Z%9RKZMKBq>jkKu!Sh+{d9<2iv7If;|`FsE=Tr-eB`kI9dR zd3~nKGdPn^@+m&eXTs8P+`=&1do9d)S{&wjT@hxxtGFi2aepAMmp={jxUb~z!n~e8 z%fE*Cx%69@?fqfDyZUe6mif;aLej^rrb%v*RXZ{zK}gLm>S-pzY>FYn|1e1M}lh7a-~ zj^#Lx=LAmVBu?hToWiM`#z*)lALHYEg3~!8%=`9f`58XT=lDEd;EQ~TFNe9_=g4z8 zkMsEo7jPjL@m0RY*ZBtDJS*^E z9>POek%zGoEAwzxVO3URbsoVZc@&T4F+7&X@pzuV6L}I(W(}UgnykfBc^Yf;bk^Y+ zJd<^K7SHB6JeTM3eAZ)qHsA$p$P0N98?iB)uxXgjtLAbGwqz@|W*fF;JGSQ~?7)uf z#Li)!uWOj^PglylZ12rJ?8|=aA08OTjg&|6X5PYEd0Uw8RdwJT6@+~gr628rMxRmd58QRaV)+|C``$z9ydJ^VM!aTjc}_j$Z;nCB}j7YXw{zqnk2CBvMDGV*~e%W^!3Nnw~^bjoq8v^bC}PUE9CC%5$5&iDfeRUFuzX^m#^dXydliv zZjwia`Md2sVUF{GF#9#u_Hi5^=5dqc$$XeoIF-}*2p{ERe4I~kI%jYupX5_~n$PfA zKF8#U*qe1gKzRJF6I)x&3Cwz?{XR6<8rRx zO0ME+uHjm)Y}ipYk()&M){Szv9>YhTrl#e$Ng3fj{ym{>+Ws#9#O; zf8+1`gPZv$x9~6i&40L++qj)OxRblMn|t_gnD@`VZTCJO3bAmQ^#kN$EFR{4RZ1?+ zGCVNM-v=wphqDT+vKp(0c|V^dpUfIOg*91=r}8w`=IN}%Gk7NJ@+_Xsb9gS#&f(lJuhT1Go`0eGBEHJk_&VRe#TE7+YqcqOl5PxfMO_F-T4V}B0d)f~t{yoT3uFo$p`hlTk)X_S03ZwYff-Ywt5 zdwC!4=K~zgF?=x0>pM;!&k12ZAE(GuIgO8m`FwsX%;)@*>QC`$KEr3j-0x+17H4w~ z=W-tB^A#@OLN4N~VfObec`=vpZN9^$VSawCme+7C*YSORzz?~eAMs;;!cX}bKj#4&!iM$Lo0mNAO18#E~4uo5Nh+cgS~!xlZqv@8P|?kN5Kdj^-FX7-lc}P&y(^~e45YjSw6?-!+fuMnRC_WaXw$+0xskt zzRK75I^W=%e2a^@gm3d5F6Fyi#`n0KE4Y%YxSDIYmh1RFKj4R4&yV;qKjEkRjGu>j zy}t}|{=W z`p7VkJDSJx_%Qc7fhY1L+iQe*-A|QkhxuM~ZkX-XQ*R(&7-oAHu@M`y37hg_He++P zU`w_Nvmfo`_Pm50*pZ#snO%4(yYe!2NoNxj^rrb%v*RXZ{zK}gLm>S-pzY>FYn|1e1M}lh7a-~j^#Lx4|5(S%9G@W znsjz=L@R4`oFj#!9Tr!&!w@ zS&h}he6AfMAIsx-JWt?>Jc%c>22Wv4*5au=jkS3?>+lSo$+|p?XY-seujl!4J=SLf zUciRDkQcEL8?yc>+)5Nj#Y~cnWK>7Ek4Atj*I|hiC9i*5z3|o9FOcp2zc9kM+a+{jRax zgiY03%Wc?}?bx1|umd}?Q<&GIt9%)|@p4|l?qRO~E9I-$lfBrReb|@%*q;M>E%pn}gVI0oucs+062;Rt>IFh4yGjHLoVg5Pl=rG6sU|2Ss5$5OAGhyEE&&n@_ zxgKY$&*5Co<9xmnX1fc+gTgiHYq>7W_CA!?hk4%5{k?|5g4i%;&*Y zd0UwG`+lAFj${8Y+bJF9^WX&a6L}I(W(}UgnyeM(bLRXo$5&sy0WV-fUdW5sh>h8V zO?fe!g*iVhO_-ni>*bHaLn8kX z=5c?k|HG}^#_eI=4?E>u+|51wm;Z(N{3+IX@BLYvCBj_yrNit``7rP6!)>p^s;tK9 zVa{8vFpoPU%y!PQ{cN72etwwuadWwq?XB5{ZP||Pc?mnPBRjD(yYNzWa(I?T`Wv0wF{3b-7G_kITdC?`nAs*K%E$?S3e)4|CoAApgjp_%kFaFAK3Si?As7}y6ta-`TSfZua>_E^LemA z{fDqzF7d zRG9b8aq{szfhY1Lp3E9Ng*91=r}8w`=IN}%Gk7NJ@+_Xsb9gS#K)jTo!FUOcqzN`GIk5|`^&ZRU=HEXFyCWt zkVo)F-o%j{#hZBxZ{=;gop*#eu6yKrc^~iR102mUe2@=uEXQ#?CvYMsaWWs~6i($d zKEg-&SeSo5_Br`^zQ7m5e16Od^Lot*^SSa?nDe$*b6tz1W+5*q8m-p96R`2XYXv;k6vhAsotK9M0=_J#XL$-pHFc zlB0MtZ{e-Hjkog--pRXoH}B!SypQ+u0gmPvKFEhSmg6{{6F8BRIGGP~3a4@!AK{~X zjF0mPPUj5Hci+5YG97yOc6@oRn)<~Y8Szvl-2z#sV& zf96JR;xGJ_zwvke!Oi@WTlg3M=0DuZZQRZs+{s(%l1A$i-!5UDG}!Q zOR)^g@}MyHs~G0I9vw0{c>!U`P$DhhNVb;$M^Y^_5VQ#;O zO~X7-GqzwWwqZM766X0kggMS`;s4(&!h8o{a zFwe6l%>I55=JxgcIL!LzVb1F}VYc^EnEP!E^Y~3+o^NxQ^Rg@a|L1SFy~mXZb9-4H z67CcEP*&t&ti;MZoK;wr)mWWJ@JJrTqj?OE<#9ZoC-6j`#FJTrr?4h#@l>7`=DeLD zpUJvmeoty-`^91YJLj%p`EYQ!PdFsZ`5hMKyxpjNllmz6<}laOJz=&xDa`qwZu<<* z+Ws z#9#O;f8+1`gPZv$xA3np*Wo|%R&L{V?%+=D;%@HYzx1Y{k}W!?tY4_Pm50*pZ#snO%4(yYe!2NWg!-35flz6OR^M8 zvrL%p!R6%&;l7a%4fD^7jt}#F?UXR*w#U*qe1 zgKzS!Fz5GOc^Tj1a<1S?uHtI0;aaZa`}}|(ay>ud$NYq!^0RQ?=--#}SNxja@LPVz z@410L@JIf{pSh8n!hPd>zsbMz4{qk4+!E&Zg51ybHA!`wXkC3v*mMmF3$_|I@b&H&n26Mg~C>0;jn#}{pi9g!aPrR_TZJgiaptj zz1fF-*^m7>fLC)M2k{zS%fTGNp&Z8HypGrN295}Ge7DHA@;2ViJ9sDW3iG%J!koV` zVb0q)+sAVPCvp-e^I=ZmR8Hd~e3XxcdA=v)>72ote3DP`X+Fbe`5d3;3w)6;@nz29 zY|i0a&f|Q(!UbH&MSPX7@pZnzH~AJ9a|z$(J6y_lxs2~|IahEcS8+Aha4pyIeSW|X zxt<^KV}8O<`58YC^E!She--Baw@Lmb%=PtWn7{k%R^P*a`5y~hx%a-@C(L&D4f8or zT)jk?&!ckcmEbk&*8Z|kLR-< z>$3qbU_)NWi`a;b*@R7bF`KbDTd*Ztu{GPUE!(j@FJT9EWG8lJ7hcM)yo}v=Ij>-M z_TZJgiaptjy~84LeXo`WauBZx|Nprr59Kfp=XJcEH*f@RBT*`O3jPG$dS8yd) zaW&U)E!XjVe!vg8KFoFXsr(r~5A*xf&+^7FpO0JQzxX%*;Z|(7Ud@3V z6z2DuTjX1L8*k?wypwnFZr;Ot!(1=p!u($MNSN#WG20&x^ZuO~=I6q*e2H_zyl>`l zK40O2FpqzYZ>cZl628rMxRmd58QACm16b*A6 z#pL2F!ICV+(k#OR!~FhSMXt(ftj;5NB#+|JJSNQXoG70Z=KJ-Ta@{bm&pGnBJdfwI z9_zCKFJQwk&(lP18WxS*T5c2OdD^q1dM9>f7hcM)yo}v=Ij>-M_TZJgiaptjz1fF- z*^m7>fLC)M2k{zS%fTGNp&Z8HypGrN29Ds3yon<@iZ}BX-pbo}JMZ9~yo-199^T9Q zct0QDXpZ57e28N?j^jCj6FG^K`7oz&DyQ+0@c++6`EfqM>72ote3DP`X+Fbe`5d3; z3w)6;@nz29Y|i0a&f|Q(!UbH&MPZKXHTiY<%`oqqch#5iJuc@8uH-7N4zu00^1AT< z&tG{xKjO#ygrD*=e$FrWCBNd={D$B1JATg%{DD96C;rThVfOzQ`B(nN-}whO^G|N! zU;LZ@a4WZQJ9ls=cX2oO@L&GN0=@P=@AqLr?#n_f%pxqx{kT652y^_!SyH_eOS23Q z4D)lQJP&2%FrUZO!+hVb5f%w+hx>)+$PL0=9~a6OvvrvLXd7nx9oQwz_1Qhlzn^?< znEMS0v;7;w+<#=4=eg7NyLqqeqr-gfnXEpA)A%SK=kzfD9?`roe;-~I9vuDsTXED z7lrvdbf+-;(I?E$*P&s~(~V)ae-lTB`5rkY%=RA&v;Fa5_WNP=sbL;BjgN%c-pnx1 z|4f+kJ1fk2SRUr@W9!50*XLoj`&F3d`6kTcHmLukzA@ZC>RZD6_m9Q;?A^aanCCCa zQY_6fJdkBsjt8+kEAU_*!b4e+hp`eX^Ke#SRaOggd`Ivo^`m(Vj|~rq{c43d&vnAQ z{uhQhPmRNzw-#Yuzs_Oq*DcKUuaJAny~Eu9YIzW^4f8xVhB@CihdGb8@K)Z&+j$4? z8=F6Roa2di9>8KO&JrxiQY_6fJdkBsF3js#K|Yv= z@K9FdVXVZ;Je*ZnmDO0CNAO4<73Op482MNp$K!bdPvl8FnKgI{Ylb z7Ut*cyYh-K|6cjGVIKEgnC)%gk74#}qwSl*JkMtNPj2B~{G0!9E4OhwcW@_ng*pBL z{r2{&e3<>Jz=L@R4`oFj7UuidkzuxToci%$vBqT>Zr~4L_IsneiNA#TeW+mnz1RDoFt1DbFuyNU3bVh5 zt5;#wuu9a=m+P^9nAfABd|{Y>Z|3qa$KO-E7kjf0`?4SVhj~4Q%EQ83k0aD?SHC07 z>-?bnP*^hZV`29H3H9lm!I^xLPlegf7vvZD5?|&l&JOc_d0T#mOT+B<8hI_(@qK>4 z54oNn@#8SZ`vt!Zv)xU$|H5DS8-M2?+#Kfj%K`)T&PTy8uk*ev#KJ7XqTG-B^MJ5q z9DlHU2oGgN9>z+n9Oihchq=Cv3-h|27M2L>h1swAVLq2Tgt^~k>fLxbuVD8u+wB$R z_3jhqI_z)z0A9_39K>tFoS$35;^718qdA5ThIt>2mnU#ySSspI%1`m>FxS(I@=JU< zEEV-P<+sATuFJ#h_bT<(T*I|o$M^X`nAhXmFwgf>nEm|4_Fu!Cm*3?-xS4-)3;zo9 zy8J8u#{yUHy*~Sd+1~@?Vl2)QEXh(V%`#z*vz&Yo%ZGU#E6RtlQkdsEN+lSo$+|p?XY(AM%ky|X>#;r?@B%gr^LjRwFJ?0~ zXA8DuE4F4Ewq?68=ed*InO%4(yYjLy_wONJ$*b5i%=Okc%>4$2rNWW6kK)a|g|~*e z|6RO4%yu5M{UMI!IF9E8PUIv`=EI!Ashq|~_$VLa<9veCIfFC#B%k8be1^~RIX=%9 z!W`!;c{b;8F6VJRU*Q5S_YyALjN8!+h_#G|b0v&9X39_UDL!rc zv+{Fc_HS00&%wE2_G^Ld3%Q7|^0n~)-(Tcqe2>e+GSSZG@)!Iv{Qtbm8~6i%46`2_ z!<^48>VNTX^*!>x{Er0&`CJIIf5qhDVb0URVVUsQFvodfnDcdVnDbtPr?4h#@l>7` z=5eR<4Au>^{ib2IcX62K?GWbs=e1$}ze;!7epi^EmlNcPoW#j|m{Y>MpPrPT3Uj@^ zB)`mA>I=havHgoM-(S8D|G(bD?BDPFgPX&=K3l__pPlNvxSMnsj5dQx@l`HdbR$LKx`Mj+j=6=V9`MfzH% zdOOVa*M)f#%INCCvX9uH@jo=Q}FQ?MH_>KefZ0kF(Uz4s#tg3UfZ1 zs5cFB{;rU_+kR!3%=WJfb3SeibG{x_AItG!j%!kw9;z+5Yk{_glf0T*cK~!?j_a_k%FU|3#Sdy~*}p!dwSi@ctI1!2x-d%0_PROH*j-0$u%$8%4Z>v>F= z^ZAhaSb2Pye@^^jnCF>o`UaZ}3gN#l>6_=KL&`-{msC$K_$}w@O~k zHC)SeVea>#ygtnJ^`ra~f96JR;xA#2<2U{hW_w#~|BHX~A8zF~Zs!i}4D-2DblBec z-jDn902X6$mS9PiVriD)fh@~%Jc#94fd}&t9?FV5EX;YR%qr?t+nbUC;rTh+!W^L+zxpscZE5wQp5N5zckD6K$Z=29x8_UygODt zCCul?X^u z?+)|*XskSr<2iv7If;|`FsE>8nB#gxew2^#@i6CihCDOO_47iQ^D-;U9;y<-@PSTyMYHzBSDIqR4f7KgSOYvz>Bb9(P!n&x2}V9#sL3d5Vi{QKIj(a z{9P#z4)gdCye-Uj?+CNM_sI8!Ij+%R9zV|ZNnzfHGsC?>TAP%{(Nlvr(w?9_hG(|{2JzYHiy~HR_+e7y?<>lc>Ug7 zh(*HOzj&DADx+RD%=RmVIj+j;Rah!9{$V!Sm1`e?eD{a+?Rz|m_=BW`*D9Bz+x=U5-iD5EX^`J zkY!np2eCXW@L(RoLs^lBu@Woua8_YeR%3M@!6SJTkLEEvmdEjUp1>1%5>I9gp2C`} z#Z!42Yx8v0;Tb$L%=`On`5d0h^LRe%u|6B{0ygA@yoin1m`&J}7qc0gvjtm*+0Qm| zTef3+UcwIS$WH9cF1(aoc^SL$a$dpi?7=H}6??K5d$SMwvLE|%0I%ji4&pVumV-Hj zLphAYc^$9k4IIH6c@sx+6mJgmxpb?18*k?wypwnF?l6zLSH6$;^8t?L7(U2{IF{o$ zo)b8clQ@|Va|)+&8XpPsx%q@VoijL-Px2`~&1d*5pX2jF5%mJhfDb`m+?I==L)V2^LnqA*KjS@@qK>454oNn@ne3% zPx%=?=NJ5vU-4^x!*BT=zvl-2z#sV&f96JR;xGJ_zwvke!Oi@WTlg3M=0DuZZQRZs z+{svl>0y2kXeKvj3$|n{wq~0!+i5Rf66SmHeRGBNDUXimSPX zYq^f^^8ym&xyi`QGxW{8^ay$M^CE{=gr@{QYH%{1^Y`KitY~+|C``$z9yd zJ^YvdvA|8vJeZi2#az*?#}~QjKx`kC0UB4S%wF)EX(mAmS+VX%tLr6EAlW_ zVr3rADy+(Ctj;5NB#+|JVLlg+mrvk{VLlgX$fvL-Yw^@D{~Y8Zxe*()37hg_He++P zU`w`QYqnuqwqtu zVa~^RPE?=7$$XeoIF-}*2pzXQ*e=W#w?2@j9$ zAIqQc(=f;Px%>scR;7;!1Ztmf~{Er1jdS0_2_hlg#W)T+Ue%zl2uo#Q81WU3MOS23QWLcKuK`hS- zJeY^@P*&t&tQ6)tI9#s6s;tK9;h_cMcVYP)o*U-#wYA)aZP||Pc?mnPBRhr17l{97 zQNAP0=l(tNy}Xb2^8t?L7(N*0xW;n4`h+l_J5$13FOP)zyT+q@jF0mPPUj5H~i@-}Yg4({YG?&co; z%l}wll>40pxi1T`FpID#_Y1RMCFGJU#nLRp16elAd8sTP9_IV$@$v~gktgwF*5E0u z$yz*>r?ECqXC0owGg+5s@ob*Mb9o-mXFb+u175&}ypR{M5gW4!oAP2dV{^7(OSWQb zwqaYg3-iA3Aa`UZc4ik|8s>d+ncR(+^9pun4_?Wu*pt23n|;`q{n(!acr^!d5U=62 z9Lymc%3&PN>v%nH;0WHxn>doAcr$O|t-Ou5^A6t0yLdP6;k~?%_w#`;KL;L?$8sFU za{?!F5-0OvPT^Ee<0E{OkMVIn!RegAnS7E@@o7H8XZakT=L>w1FY#s0;%v_0T+ZWs zzQP4u$VGgWukm%h!8iF97jp^U<~v-7hxX% zO_=+CC;!Mz>c8^$Fh8%h$ve1nBzD>J}J!YCx^LzE%npXYx8v5>xTJ$UO&us8rps#FJdD$W)n8$#camrY{8an z#nx=Ywrt1tyd*3b{pu)pV&^c&cNx2fMI!eO3x<8e9M6C-_q!&{dAXK@IfO$wjKg_d znAhQ^Fx$IX{TB5*<-2${@8P|?kN5Kdj^>y!+aD{B<9JTsL{8#lKFlec%4vLrkMc1- z&L=pXGdPn^@~JTU`K)0*YSORzz?~eAMs;;!cX}bKj#m3%5B`v9sC~)cNs54(e?qDhwd&V1W6S{ zB?QGTKsuzs#sUPS1f{#%M5G((1_cbT!0uKA6@xIS_nw#Q)Ajq$?9R^4&d%b1)}!F*oxtFY_@!3$P#yu`r9UD2uT;&*S+l z!ICV+(!79WSe6&E9Luu;E3y(R^CDi%OIU?fc`2*$GG5LrSe-RkleKsyYqJio;?=Cn zYj`cMZs(3LQ?&nzyoh8VP1!6=_i6hu?bj(x|Gwd2^^dSC zyM@`JzIT|;cR*M&oTdILKFw$NET7}^oE@g)FP4{ZDVK3MS8yd)@g=V28m{F!uIC1B zZs!i}wJTIxsPx1Exyfn_%8SJ0N>;L{D2?wBYwXb+vk9AqX&y9ZOXaP22V1iZ+p-^cd7<;o1`?4SV^KlN~ zKt91IIf#QfghM%u!#RQ@If|n>hGRL7<2iv7If;`wg;P0=)5A1Ro|k9y1U-Bz{&2RWEzvK7(fj{ym9t_j? z9Fh<77ycTib>?^Z5B|x&c$CM&wEf@mKVfSBKjo*DpW#_%80r0y8JUThnT1)y)NXb; z2XitPb2AU~G9UA^01L7Z3$qA|vKWhp>3mDbC0UB4)t8koWI2{+1y*DwR^~;#n3u2$ ztMXD-<7K>@SFk#3uqJEqO4eo_Ud5|fm)G!GUdQWs18?L_yqUM~R^G;Xtj`9#oekND zjoE}v*^JHEf-TvKcd#|vur1rMJv*>tm^J3XJ@UO_`u%Ws`BC;@&oF&|50Qs*7>9F2 zm?gFwE05!NPT)jN;$%+Y)G)2vGsCq0zo2|hn7$Jhg{eOqlyBrFZswLSwX-8k{o1X3 z4_^(_{qTmom;3l8-{RYRhwpMf5AZ#{AEy3(CV$Q^_$9yM*J0}C5Au)vi3j;J5AiU6 z;jjFSNBBGc2-AA>mwc4Rc$_ErH~-;sHtFs1cvKFso zZPwvcyqa}+4X@>Oyq-7kM&87mc?)mlZLG)oY{1*ukd4@wP1uyp*qklclC5|LTeA(@ zvK`yA13R)4JM&K7#k+YA@8x~GpI!I>ALK)Pn2)e4yRkbTWe@gbFFwZJ?8Cn7$Npiu z4+h8sJ@5Ze|5uoPj(C*El%ELGey5b5 zR(>{2$ImqS+vj%Ij7OxD`^XK|7jn9o?I=@@h-^O~Z&j!4m4cUl| z*@R8mjLq4CEyHvjTFY(NmhIS{9oUhb*qL|oF5b<1crWkc{p`XA_#hwR!+eBY*^S-# zD0{Fcd+{;$W*_!tKlbP29KeBmf=_Y~2XhFAau|nm1V?fdM{^9vavaBV0w;13Cvys? zhG~9HmuGM$XYnaM&1d*5pX2kK%@;U_FLEyDaXuGtAs2BmmvAYUaXD9TC0Fq!uI3u9 zPxSe_MFk(F4P7x7|V!YX0*SjTF}HCc;SvNr34>3i;4 z`8raCYAP)@Fcn^_>hUxE3rpnVeoioDp zcd+xq9N}_#OPI!UYna-5S$>7PxSM|F8A{Q-{brIfFJTB ze#}q!DL>=q{DNQdD}K#y_$|NV_xyoB@+ThT&pgD#{Dr^rHy+{d{DXh;FCOJF9_I=E z&42hW|KmxX;%T1YS!Nh(U1dgQVrFJxR%T;%=3q|dVs7SPUgl$d7GOaZV&O2YBSqz6 zEY9d;py&vQ0k;2gflxtz!OT)>4~#Kl~~rCi44T)~xG#h196Yq*x{xSkuh zk(;=gTey|mxScz=lP~iX?&5Cl;j4U&uk#J=S;k(?=1ALF~^8PxSe_MFk(F4P7x7|V!YZuFOIeMV@p4|l z>a4+x?n{{{72otoW-a3G@s$Ke2&kD>G?fZ zp2zuIz=d4I#azOrT*l>G!IfOam$;g1xR&dv%nH;ElYAH}e+W%G+3v_1S>8 zvmqO?F`KX{o3S}tuq9jZ4z^|+wq-lEX9sp=q{DNQdt1z|m zjr=XYK zgM5e&^AUDsH+JWv?7^Pw#mCs2eb|@%*q@Jc00;63KFL8G%pn}gVPRUoMulnJ8^dwR zCvjSs*8S<6!I_-Jr^3|EGhu3Xwmc`y9eH_}+F8MsT*a5Tnrpb0>$pBl?Y$!J3e)jk zlV9f>+{=A@GfdxoAIKl_BYw+>*u2Y)Mnul@)A$e(zSKl2a|^B4Zg-*|+- zhv~eI%Ex$|C-`@mwmTW7=X!=o)_Z1TCT0%P`D6{#emRxrVs7SPUgl%|Fi-4PN-oU{ z!t3Tk){z>J7IaK*D4(AAtR2-7&d8m9j2^RsLC+`tybSWtfih zlYCJ9A^9+W;jjFSNBDb~j`x>*G)(>cPd*tIikx@yx%r%r`B{Jk!!(bJ%EiLGkt@g* zS&5aybloovi-os@Y5)3R8lT2tI^U*Y>QC!1ty^u_mhIS{9oUhb*qL{RsolHfdw4JJ z*XxEB}xm z@#8Sf=Wpb1`5nLK4`FKOV3^jQzmy;4F&^iMFrEK@@=2cJX`bO(W|(6AW=3XWW@cel zW@C2dU{2;@ZsuWL=3{;qU_lmQVHROg7GrUq$Mac&C0UB4c>&9?EH7j^mS+W4WF=PS zMZB1ounMd4QdZ+-yqs6CI%}{dYw=3fW*uI|t67)VglQeRNxnHu_g{Uv0dHr+Fg-t8 z%B^?@TeA(@hUvbzQ@$%q?cXnV;R9jXuDkpwd$1>a@iF#hANFNG_UGdq5T^Cw3Hiw| z-A_a0p&Z8H9Kn$s#nBwYv0*yDNntw96i!n=oijL-v-nh)_IoBw?Yt1Czdu^1emysE zV^|>S-;nomAKwg9JNv`54t${e!?1Yd-{d3wJxtf(g#0)E;lE*O=X99nO{S^m)``r_ z!mMH1E@zm|C%5uE%*%Yt&jKtMrsr;jus~QVO#iP;bM-CQGEDE`cglD1Zr;Otd0$v1 zwx1$TnaTJex0sY2GhV|5BKq?>oYDp1Z;{9&d!{IlY(r_$J@t+hOYWr}AfE z`n~EOVLH#;)8cokVWlu_S3Rr|b_vsXJ{YF!HzZ8Q9TleIj^-GS4b%4H!?gW;x!{U;Z>q lo^ql=GOzj=zF&^iMFn`o%oqle+Y+*W14ml@tF*oxtFY|@z{wpXK zV&O3Lr<`1#6q~(>UL${4U4~#Kl~~rCi44T)~xG6{h=at-Oxwxq%zGiJQ5FTe*$fxg$*P zQ+vZS4(}*`m-~5u@9}+p5T^U)EBR}Fqx^7~#`#a>fAJ`f@pzc7=RaXO-&0|lpJ$k1 z#<`p^O!ZmAbf0EpcIIGC=3?$JwU;+67?ugs@ye+$AEtG#id;2J>(Wi~&AcT{=hHAO z9Nww?t}u@8g?cnl~SXX*_>ceu#&|w7zDV8UJ@v zSRqX9UJ|D3R)tl=bbi&sbUm(6UY#{qleNP1{JB}aB}~tWW^!}3U`w{*9c;}uY|D0R z&kpR!PVCG(!!$nk$@jAhAK-(0C`{+sHB9H-UHPNz!Jh2J$Jm>F*q8mn)ZXLr01o66 zVbQ3cCQlFl|9LOZ<_ny|7de;nIG+o+kc+sOOSqKFxST7vlB@UYK^U*@7+Eig&Oz+l1-5w3FMj13R)4JM&K7 z6{dN4UzpnI!Uy@V`tEX%FwKj;a(@os6CA`LVR~*1t5e4exU0_X5W&gDGL=K?O|A};0|jcq?yXJ=SLf-p+<>#KvsGrfkOMY{8an#XH!V zZP=FW*q$BOk)7C?ck(XY&3nT1yze9TWk2@k;~c<&e1cDM5C?MzhjJK)a|B0n6i0Im z$8sFUa{?!F5+`#Cr*ayna|UN}7N6qNe1^~RIX=(Xe1UWLBIj}*=W_uUauFAE372vi zmvaSIaur|VYOdj0uH$-c;6`rZW^UnDZsYbay?^bN_wZG|#@G1<_i`WKtCN^z)p* z<$w4u|KmxX;%T1YS!Q_J^NtyriJ6&&S(%O5nS(i*i@BMHd6|#-S%3vuh=o~%MOiFN zKL;r(mttvNz%ne$3t5ikS%DQ!mjMb?tGLz*pt2Z7<;o1`?4SV^KlN~Kt91I zIf#QfghM%u!#RQ@IVw!+*jRa7n7*?o$P+nN*|OSz28xq>UXiZ5|B*KjS@aXmM1BR6p~w{R=BaXWW#Ctv0( z+{NA8!&mtlU*{X#%YA&4Z}Dxu!*{u#2lyV}=Lh_dAMs;;!cX}bKj#)B4_mt(4!v)@;MJY{&NOz>e$`rr-N?kssiLe25S85q4!ab`R6{ zLvOhc`?4SV^KlN~Kt91IIf#QfghM%u!#RQ@If|n>hGRL7<2iv7If;`wg;P0=(>a4P zIg3y6X+Fbe`5d3;Y`(xbVY>cv<$3Y~c_9~ZF_&;DmvK2)a3xpqC9dWguH`ze57YX( zS>D2}+{W$P!JT}WuW%Q4a}QtTYkZw=a4+}qO}@pq`3~RZejea^e4iiiLw>}M`3XPe zXZ)OB@JoKhulWtX<#+s^Kk!HX#Dn~qhj^I3@K^rEBmA9z@K655qddmrJi)*D5C7$V zJjqi$%`-g949|MLG9xoFGqW%&voSk!Feh^{H}fzr^D#dQupkSuFpID#i?KM*uyR^_Fv#>;p)uV8i7U`^KIm8{J=VOnpl<~3ou&u<9R zI)9t;`eFJ#Tm#Zs!i}wJTIxsPx1 zExyfn_%8SJ0N>;L{D2?wBYw<{6%4hUYv#nUR^8nOT^X*_fRPxSe_Na^c{1lT#c9Ua$dpe ztihVB#Vc8xb$Au8W?f#xYk3{7=MB7(H-+ivALK)Pn2)e4yRkbTWe@gbFFwZJ?8Cn7 z$Nqer12~XR@JSBhU=HC>4&!i+;7E?*XpZ4nj^lVv;6zU1WKQ8!PUCdW2-AJ`RG8-7 z^I^JQ7OG#w#azOrVR{c;Ew2gFep}^jVfwq@*Tb~kJ7M}e=C9J}#yp+|#G;gkutFs1cvKFso?J#{W z)D2Vru2p^=ujdWCkvH*X-ojgX8|$$?8}N2EWFt0a6E^cd7<;o1`?4SV^KlN~Kt91I zIf#QfghM%u!#RQ@If|n>hGRL7<2iv7If;`wg;P0=(>a4PIg3y6X+9IC@qA8xp0oJ^ z=kP_&a4+x?n{{{72otoW-a3G@s$Ke2&j^HecWzzR0$!m&xrv*(gH8D8)_U`A$QW@cg5F!e8|oQt`chk2Qg`B{JkS%`&M zghg45#d#jjX9<>MDVF91EW@(AkmXpO6$U*Rt9<{rKp zrgiiUd9VDI{5Id=yWAh9adEES(FaHpx{eF@U@@F36VgABj z`5TY$_b|2hr~DU>@)(cv1pnqg{FndnBv0`)&+u%Rj{Cnk=dNc)W@2V$VOC~icIIGC z=3;K@SFk#3uqJEqO4eo_Ud5|fm)G!GUdQWs18?L_yqUM~R^G;Xtj`9#oekND zjoE}v*^JHEf-TvKcd#|vur1rMJv*=?JFzqGVC*&0)q2@%s*L4|7I-J^WwzMwmH#E6f(YAExa;$shH}jS-ZPzF)7Ty~c2z#sV z!@lgt{$bYGZjd~fLpYSfIGiImGECz$S{}o(9LMpTz=@p1$(+KeoW|*#!I_-Jr}%W3 z`txj<#&@%o4ei+&N6`J|cGw3q>9r<_gD!sb5pWeBp~> zng{d4)Q<&WI^QMoQhBAkDopKf3)B7lc9`1xK>ded+W*rqo%ccYN5XXe$HH`+(=Z;f2O#2lH)A^n+mr!3NOy_g8^18f+*YY}E&l`9nZ{p3og}3rH z)?M?#AwXls(v!y~0efUmv+I`>{VC=Kv1m6MT|`IG95?l*2fjBRG}- zcsNY=)gSVoVH*FVVY=VXgy}xbH~(CDfiSgSG)(OjWAU&^uXueS0!VW!A+_e^LRc>up~=``J?|;!!(aB3)A;PJ@xg&%#jqdm zn8u?;nAW4Va(ne1!t~y9ZCF=ny)9q^gR6E!gKRBbC{l+S(r5}6}g;To)uV;l~_5<65Ce| z(|J`>ep#6Ai|TR>)(q46)RC_W(|&d3Yr?FNZ&H3snA&e3Hw?2zZq7E!+lA>o+Oq>Y zvJ*S=PTs}4!}Q$hEa@iF#hANFNG_UGdqz=3>%PjV0ka|nlW7>9ENM{*QLa}39F9LIA4 zCvp-ea|)+&T9~f)40&dl=I;yg9KOi8VS3+KBd_H;uIC1BZs!i}mZm;do3Pw_O*@GLVdwtj`_I%i@QW@8TK3e$5YH}f!Wm_5pihN+$6Vb-v8 zm@TXzUlOKu=h84;hbzLgeGR!b>xOCn8^g5yEn#~8H(^`#ox{}r{b6e70X`I__Pd2? z-5$)TVe0?1FnjoHnD%=1VQS}&Fzwe)d3$zXM|NUo-pRXoH}B!SypQ*@3m@QvVd}@j@+0iZZtTuS*@HdV zi;uB4`>-$ju|FT@01o66e3FAWm_s;}!#JEHIFh3{nqxSY<2arZIFXY$nNv8G(>R?o zIFqyZ6rbiZe3sAgdCukwoWmD6m-9HE3%HPrxR^`0l*_oBE4Y%Y_!3uh4cBrV*K-3m zauYXm3%7C`w{r(~@@2llUEIw*e3h^9b-uy9+{ZWh7T@MOe3$!qfba2re!vg;5kKZ9 z{FI;ZbAG`u`4zwBH~g00@q7NjANdmx@@F0j)4KDUe1yOA5B|x&c$CL@JWTH)C*@N- z%`-g93`@^FH~+_s%*4#h5@wHf^T>I_oRN!%>GzPA$Th?Co>MDKKkvI)z9me*@8}d3 z4tpx^#mCq?EF1MR!?X@Q6{c}{PM#g6_FqswFHGzHV&zM?l*_oBE5h`9lO6I-z8vO= z^1WetpZ`Glhx~{itN%{^o%*-sz%52Qe9L&jF%*{N^%Y4kw0xZZvEX*P-8m8-gzFdMOS&F530n4x~ zFJw8EX9ZSdC06D|yqK4;3aj!`R^w&7oL8`VSTxS3ewe;bnuh0x4~6M_WMG*7j%Hez zexEZpOy|EaO!IsZ7jp@hav7J0Y5%SAwlLk7?}oX;&%!h>zYJ5mUxn%Z{58xOo(NO_ zPOCq|vtjB_rse0>l^kK(KWCWEtBhPWO!sR!xqO(u|7(Ql_mB0%bl&%bsUP=;shuui zTCcjw-Pk=${pv429_EfbGED8xR6Z-r6?v{akMp^J3%Q7kxr9r(jLW%#E4hjYhTrl#e$OBHBY)yS{>(!>%wPB`f8!DU&Oi7k|Kd>|<8hwg-~5OF z@;{#BDW2vTo@Is==jQ+an30*7IZXFSHaWYTOU}(aVY+V%%SBj}#lo~MR1DKRtQ@BG z<~sG)hw1rwi+pRCwyPJW`>%PJJM0vu{@fL&`}S_$!+UvOn6`UBevl9GVLrmH?8feV zls(v!z4#b=vk&{SAN%uh4&XpO!6!M0gE@plIgG&vSN|uJauEMb70s&gTLy; z{5DMY*-!F8{>(!>%wPB`f8!DU&OgF5K7a9;^5gQ~{8#yZJjqi$%`-g93@fcu%*ag4 z%q+~xY|PFa%*kBL%{ff9&y`L>pzMLz#GECd8 zme+7C*Ks{Jgy}tUzkDF968W@zhG&^!)w%J?5&r*sD|0b-n4X8_?WG!CF+N{H?cs1+t8eYrmcs+06jl79B^A_I9+gOkF*?_mRAsewVo3JUH zu{m3?C0p?hwq_f)WjnTK2X+k8eSA-tzC*f%>3yV^`p4Lteb|@%!ZiPe$-_BmZm;do3Pw_O*@GLXD+do>AF-5)AQyMaWIE) zD2H)4M{p!ZaWuzpEXQ#?CvYMsaWbcHDyMNeXK*HG@hLvdXZS3iKUlOLDchn5id*3x-YVX!C9j{)P_HU@X6+4A#`}@Q6UfnfJ+w}<3e!aqU zyvM?{uJjMn`3(xwd&$@^Z9h@{v@q>ABTVD;RG7A(&G}(!ZvhvEY5T=os(cxja|Ks& z6<^|NuHjm)<9cr3MsDI}ZsAsL<96=gPQJ`n!gLvj%Ij7O!M&*5OsWnss>% zujO^TK1}oMM)@Y*%v*RXZ(}{yX9M2OhHS*fY{I5&#^!9nmTbj4*qUwFmhIS{9oUhb z*qL|oF5b<1crWkc{p`XA_#hwR!+eBY*^S-#D0{Fcd+{;$W*_!tKlbP29KeBmf=_Y~ z2XhFAau|nm1V?fdM{^9vavaBV0w;13Cvys?avG;|24`{>pW@SehR^ajKF`^FfphpG z=W-tBa{(7}5f^g_mvR}Ga|Ks&6<^|NuHjm)<9cr3MsDI}ZsAsL<96=gPQJ`nxQn~F zhp+NAzRowem;3l8-{RYRhwpMf5AZ#{&kw@%zVo^KMVOw)--Kzs`i?*Fr!YO24~FS| z>38`L{>i_1l*f3SC&Kg`{WnbSQ)iT)4byS|xAt5=vV`e)S(%O5nIlZ^iABQlVVyAj zKD&wfrfe3b^K2ux4b#ta?w7mpfiRu_BVp=acjb?=2Ya#?A7gL!Vc#&d^SC@9Oy~E6 z{3Hh{A0iLsFb?Mkj^rqg4pX~h<#8O(37p7DoXjbl%4wX=8DY9k&+rB1bHa4ox$->D z=K?O|A}$Wo_^+2Ya3eQ`>ECUAD1XF{`AL}G^S_h7=MQ0lC_gTr2-Ez?xbECM%EZiJ zx-Qw|>|xrjuv~;i!*rZ7a@jD=qsn1A?~B7U->whyhfTvYUz>#m!+XMfVNd0~_!xV$ z5Bsto`-kcH!{p&%p~$nsG(PK;ujhs^eediHONU=7|B7Gpn=sAuALJkTQ<%>0H~9#E z=O60-mj4OU_fMwv=i18_rt{Cv9L&jF%*{N^%Y0$#SD`SiFD2v))R$q|FpWbE-ln`> zSR~3jhUxlr4%2u%5T<@T$cOkaA7NK^3)6Y^4^uk>ln+!sDopcdtnzVTnm@DD&kfUg zEDTdWH;3u?Tevk$?QRd#eYGo0+rOs%b-uy9VVX~$hv_&6!_>dO)F0(B^%*vtyT9^; z>9~2BkNLy2e+ju{nEF#%zJO&|mKU-d%d-M2vJxxvB3{f(ScO%2DXWF)JFuo)i&wHX z>x5}MZjo>0ZLG)oY{1*ukd4B0{!PL(|L+LX^=%ubesm7gdi99hQ+@9+&C@5swBPVB zjrRzS?yQjt|rEriN)fnH#2l%~!vG3&YgEC1Lt|%w5WNb5EGYWxsrY?}h2Q ze<^>(ulWtX<#%D4zsJLLynn*fpa0aK+!J4ea zD_J{C<9>CRu5(M}t-{oPTe)4Bw(A(CdDB&SH+JWv?7^Pw#mCs2eb|@%*q@Jc00;63 zKFL8G9HxE_lZSHzM{-n{wi_#tuuJ1AV zI8X3z{=Gd zt6pJ|aCDf?e;g-<>Asy5rhZQg%Y5`rtNp~H0{>5P1q88)9=$Fhd$e6lfnnBGeYhiQE( zp}b_6#-XfyA#k_=7Se2Ku8ZYDJyn@wPgEd);SF$$i@G4%-x?vip zYvt>BJ#XNRyoopS7T(I+SdaDDfVYR~`ZkuEuqm6dIa{zLTk#IIW*fF;JGN&Bc4Q}Z z4%79%pIw!A3)A!Nu`s=t4hqxv`(*V~IF-{loioDpU9>1n>)2N1+qj)O!vACGzT<`* z+dhEzRA?aWo%Yr;vQkmW-bsX{Nui}7qk)DkGdnx9R0z>7q^zk>n{p(|E&shem+(I89xv6-x+L_f8eGtuk(leC;tkw{{`OMx6l8_ zf??jb<-@#gHRXr0I%}{dYlZndX(TrebKf)x^EyX_`5ZYq%=_`QFn=!T9Oiv?k@~Lk zrD6X3+bhiT`zi0wYj`cM;{XoiAP(k`uw1k^QNAP0`Mf)<6uzYVs&X?`K_bDT%YN3ms?^WI86fvwqwZNrLjTo?IbUc#=tG|YMFBlqQ1yqf*kKg{u6 zD_n~j9>jxLf`_mqOR+S|uq?~5JS(swE3q=GuqvzZP*!IR)?_W#W*ydLJ=SLfHe@3< z=3#8YreQvRj|_8NTPi=A$M9Gl7v^!T*qUwCpBQF)9m9M+ofGDB=K}SelwYR2J9~xM zZl5rJFE%jD_r*}a4+xcsyJ21h!@y zw&jUDiS5{)9e6T3@)VxR(|9`1;F&y&XY(AM%ky|XFJLEL$j-coU3f7sVOL(t%Xm4v z@d|e5mF&Tu?8V;f!@j(VSF<1c^BP{u>o|Y|If#Qfgx7N@hjBPZ@CJ_Ljl79B^A?Wc zXpZ4n-pbo}JI8T6CvYO~;GMjSck>?J%lmjgC-DJ3$cOkaAK{~%%*XgRpWu^xicj+y zPT{kBj?eQ2zQ~vOGNdG|Pnf-l!~BVO3V+p{&jt ztjSue%{pQBqk-Ho%<(mr4`UNHWwS8PJ0i?=Yp1+@nDgFIJ|)cdPLoepf0leU&k3`= z3*=6`ke$Q)KJF%8!R}$MUw`=;Ud!t^fCIz)_cNoy?C01p`*&NIzbCs(z9-E7ObYY( zDPewxJj>_!JYV38d@0P|3(l73gn7L;<+nI5tPxetDpH*-sv z^Yd$%*Ddg_{mOzY#KPP!%%2}hggM^Q%FD2<@``dLR%R7eWi=kk>Z}oF`*q~HtjGFc z{`_*7+$79(X(l&ki!j?cipMHHF3j`WC~p_$x}B%~d|tp#ypWy4Z1)nmD=+0`yqw*5 z1-tV~_Fzx;VsG|g-!S(@Ke<1z;kCSu12~X_IG96tJ%@5wnByBM-x%in-YnlDkCw-9 zEN|s)yq)7Xo)b8cckoW$#k<4o&;9ZwKEMb05Fh3ve3X;J-1pChd7r$jd@5hzt9*^q zIGr;%le73bXLAnc@(sSpw>Xb)^Bum+`FxM>a{(7}5f^g_mvR}Ga|J)(hx~{u`7u{< zH9z5}{EVOT3$Ec>ei`O^ejDcVXS4Dx{DoV&joZ0{JGqOy`73|p@7%*b_$U7gb3YWA z?>WeVEX2axkNfig7GY5qV{snHgLp7Y@DP?{DVAm#mSwpx`&~t@%4$3`%=@;6T$8m} zn{`;1^;kd5^Bc0U^26AKP1QH&;bHdc7`6`cJ=7u0_u|Ry$WwSKPvhx4Bh3ABPMGhX zi^FW^5_S#qdfmf(uJ;bJzE7CX%d6#nVb%|j2Xc_|Ve)W}2oEk$pujkJJST8sn13&P zOnyA99Qlnf`}=m7{dgzLe!Lgvd@cyHd|{Y>KU)>%{HzI!ha1AI-xy|pe-5*~tznjL z<96=gPVVAv{u<`|{1xW>6@G8u^@@kt-hn(Q%;QRj`JAkxylR;Jt1Z_Fb3FCs24SAp zRBp!RVTmYjBe&&=Jc;eto*j5HJMt8s8s5yYKJ-Q`eCk1(=gj@73Og#ur=F+dEQB3*|2k1 zJshfjSeSnYn;=i*9lVowg*m=S@&jS^4u@zt9 zv;XhN?}pirMe<@U3G=&rWtjKn_sZ9CJvVS;`2Y7;nC<_fd@HwcJ9ls=cZGTWo-nUh zWWm1i77YtVE*@sP2ZuRNrNW$#(k#QWEXVR;p*XIRTsh4150$I425W{n|3}F!!$Ogd zm5<}`Y!w!Y`Zi&<+fI3VcHqfj&gWTSq43-=_iMK>$8iO_^Gfyz^ZC(Vz9!81xGp>} z9I5<9-o%@E3rBG@$8aofQd3`L* z`)!6in{S4>f9HoeFYkvrp9{E$x{E0tvGq;2}4_oDJ+|C``$z9ydU-=t<=bkXv zx8S0E^H_+5xnG#;S3*7{+%Iz3FxRV!@~U!exlWkltuHrVLpEaLaKAXNx!i(>hk5={ za!Ve~V|Xl&M;Ae zR{oM-@oRp=Z}}a+=Q^(EhH$@V_a|-*bDwVy^S<7p{5Sb`?%^N&lYjB=Fvqu7{*MI~ z?`!veEXYD(uHzwcNtR;i@c+Me<*H$}UtO*d=KR!`8?Yf8v2mE+0j=Z{*qUwFmM8M0 zFt67^J~=EL`84_TFz4+|`7EBzb9gS#QT^CEWP#k_=Fc_}aBr4;xyqWTB^>a9v zZ}3gN#d&<2@9VA;|BL@{Z&~~@o_#8 z<~lvaXTn^k7v-1310v5*K3Dmh^87H@V_}%{{;~XNnEUCwFxy`j=De)u25#gJ+{7RG z6MyDrZs9N7%5B`v9o)%X+|6J48-M2>{=q-_7ysrz{Fi(A9}6t?eq})xVqxyb{doY3 zuqcbMI1l7OJeVbT2urdQOS25ivK-5^0xPl-E3*o#vKkL%b=F`_)?#heVO`c^eKuf2 zHezEQ#wKjaW^B$DJe)`HNFK$OJetSwSRTjY*@`EyHQTT)Pvl8#$M)>Nli87{@Km10 z(|HEZn5AZ=g#E1C^ALV2|#>e>tpX5_~n$K_wpXGCWo-go4zQmU~m9Ows zzQ$>s&KaD^S$v(dIfrxk2H)gcoX5BM4&UW`zQ^~ufD5^Zi@AhLxs1!heBXW~ujI#J zktkmi=KJ?0F;|88z5GR(<69dR3D<>rpZ*Z${kKW^wlI&|5$5k# z{#C!1|FOVw-;FHDLSfN3@4zsBekrNERG9Zq)iB#XG|c;=rutf}%{r{hdSQOQA1)uk zBY9NVDC)a~dEK7Md$BkBgxS9V@<0v>vtL8PoR{HY&fCq(M}^tnvFgW#|NnE8`iZ<# z`CYu5_wZic$NM>n4}{r|hvbL(2p{F-Fvt0n{4}586h6!6_&i_Wi+qVMb1Glqt6}zQ znmnB|IFqyZI%jhZ=Y~0tZ^`rcHs9g9oX_|8J{NEy7jZF{a4DB@Ialxle#nowk{@#w zSMw8o%Fp;Yzu+3K<(K@5U-KJ&%kTI-*Ks{Jgt;C+$eZ{hf8x*F%q?N=@9o^J{8#yp zFrN9Kn2V8}qO*`_nYcakW%_G>_r2JdVe+6;EJmwqaYI$dlNP?b(4Rvm;O8sXUFR^9-KJ zvv@Yo;ki7I=ko$~;)U$Yi`a!1^AdLDrM!%nvm38qcV5XJ?8#p2%|7hQt9Uj0u|Kcj zwY-i4I55or-Sb5G4*5CxdA`6G!~FZnT=@;Y$+tK!%D25xRu+uojbUbySSUb@;Cm@J^X`z@-P0) zfA}x=@;?^%z;^@-vJeY%Kkm;1ScFAcjKz5%58}Zr!9!S*rC6F}SeE5jo)uV;l~|co zSe4ayD65CXV%-|bjo3KM=X5ieLYsbmACPBj^lVv;6&cRJHy=H_sIA1KHkqse1H$~AwJAU_$Vjy zF+LvV{5&Z?#i#iUr|?-m$LGWR-g-@*#_62FnViMfIXlev_)7U>uHtHb!cW8O@8|Lt zT*I|t&fnMaH~g00@q4Zd^Z1SO58R~uXL&QX@E2|k^XIc&@^1dh-}pQC@DKjUzrx&~ zd*%OF;G=#0D-`BFEga^*7px#xWF=N+6;=&%z7Ay#)>2=aby%16Sf35pkd4@whp`Ep zvKgDR1rHB%-j9-7@@O8zW5YbIm3#tQvklwwM4rTUY|jonnH_lwPvvPmooDb&p2f3y z4$tLzJf9b^6E9?EUc@fEn3u3CFXd%n?w9WJmF&Tu?8V;f!@j(VSF<1c^BP{u>o|Y| zIVj9^x<1V3;VsHXg}ML6$YaC2U&hN5IFWboPTs}4c@OX9eY~HO!o1#tVP0pl^2d}v zAwS8dls_X+;j_x04|7~EDStUUDDqtSjWECWm&+@{y#9yb|9_t-U(HYWX_&`-E`Px_ zT+1){6~E>;{FdMGd#>YpZs11#z)k#-Kk;X7<`(|Kt=z`#+`*mP#ohdszlAyeJ@Oy? zlYgoIhkL`E&w?xWxj&1A`CKe6mk6`nlFCbk`8`}&dDSr2vwE06=hai*fQ@)qn8!5> zv;F4E4-c~+E#+gvY^P0_$Db4)7@ig8d1vz+p3C!iJ}+P=UdYb8h+TLwFJV_+8s_*f zm%H%_cITDs!Jh2J-t5D^yoy(|AN%tfUd!t^fCD**gE@rPb0~*#I7jdXj^vHJi8u2W zj^b#J;aJ|v+ju+2aXcq*BJbdxyo-199^T9Qct0oc0Y1ow_%I*gqnymg_&A^7lYA=7 zeK|#bme28dzQ7mx5?|(2zQR}e8mDnOXK*HG@paDT9M0t%e3Nf+9^d9We3$e29^dBz zF61IE<`ORDGA`!|e!vg;5m)kKuHtHb!cX}bKj#-*!?pa9U-4^x!*BT=zvnux=LT-% z58T8b`4fNUW^Umx+{$g-&K=yzUEIxI`5S-d9{#~U`4|7@Km3<_`5y~>yzhDYKNe&m z7Uq83p9ioAi?SGt^FSWNgIR)yup~>dG|R9o%dtEwup%q5GOMsEtMO1)XARb5E!Jio z)@41`X9G55BR1w?Y{I5&#^!9n!+8Xca{(7}5f^g_mvR}Ga|J)(hx~{u`7u{ ze#x)+HNWAv{Epvq9oKUMH}VH=;*b1^KXWs;@E307Hg4w*?&L1+=CAyXzjF`&;Gg`9 zfAb&y%f0-M1y*@qvLFkwF!$sBJb*=5l*L$_2l5~u%o03=C0UB4S%zgEwAGM4&)#X<`7=bp&Z8H9Kjnnk~fC= zbKWgs?#t22$8aofzvIwoXa=(Cg0*bzRh>|F6Z+-zRv|*$VFVt zC0xp7T+S8zfFJTBuH?sD#nt?TpYk()&M&xzYxyO=;@A9!-|{a4+%;!*RQT^CEWP#k_=Fc_}aBYtXM;S@d_=Fe#_ z%TxIZU*&6@#_62FnViMfIh%7hmv8V*zQuWboA2;l&gXl4p9{E$sj9xRF0_6My7S{F$4%g}-ns zw{bgna3^{G0#qU+(39Ebxi<7Yniw3v)m2&jVP5MOlo+c_0ts z!7RZ;Sdyh!nq^p)#`o}vjH2j5gYR`HepjX zV{^9P;XHyz@+h|C(L5&1_ttT2#nxfI*G>xa=ZOyTsbPu87lrxrLH979TYbX(eQDn? z|K5I0nC)K2fnh%XMu+)#(YwMtZ&H|lmwi0U>pdOjc~ipt{p?ib)52_jy84-XJuDsN zOXcPKfFFf<-b#5DKjCNL!BM{<%;PrlhcNr|v%HyG_zSmk8@F=@cXC&l?fowA;U8g+ z_b>H(mH)>ApYH3||H3@3kX$&-_KL_wS&YSbAP?ffVV+k?F3mD58|L~|k}I?N4leJizby%16Sf35pkd4@whp`EpvKgDR1rO&DJd#JTC6DGYJeJ4tc(&pRY|S=o z%M*DL+p#@6@ML!6DLj>@@pPWSGkF%z<~cl<=ka`Az)rl7op}+v@M2!VuDq0&@p5+K z73|I{*@HdVi@n*0eR&nHW<8Y4P4IIfEc@uBuEgZ$s z9K*4^mACPBj^lVv;6&cRJ9!uH<~_WZ_wjyC;sbn;5Ak6>!bdrokMVIn!6*3?pXM{1 z!e{v$pXUpFkuULOPUS0nm9KFcr*j5pau#3bY|i0azQH&77U%J8zQcDppYQQ~F5p5g z;$kl0QZD0iuHXm!kRNd+Kjtc~<|q7=pYd~k!8KgVFZmU}<~RJ7-|>5{<9cr3M*hG} z{E;!hDYv4fB0xfz?Y1rO&DJd#JTC6DGYJeJ3W)#G{>%a^b#FAcMw z-Q_F8{P*?4X!>ZvkVg7e%-&X%lnBP~6M7-m0y zmN#tC@JNNJp{>i`iH~-B53nER&) zizzQIA0!{l58e2@?EVLlS(`IGs0`2YVsarJM8 z&7*!xn9sMr!%47XHGm+{W$P z!JXX2-Talm@ptawA7QTNKk~oa%l}wl&A#y!3v)chc_0ts!7RZ;!rVXQ!km{1$}5IB zpVj0;S)DalleJho%z3XT*Jpz;pU=(Z7Cb!6e`kDbnCG=pega#w4cqcWp2T)+9~O^x z&X&*Nxjc{O^MWvszg+IdE7+Y^vIl#z7kjf0`|>JY&3^39Yr-7&0C^w>aWIGQdJg3< z4(ABoz>&O>H}PiP!ciQ}F=0MW?hSJvJQ(KvHa*PWm&^}qha1)Z%xz)rzwO)+=KTI0 z<~a8%|1Zq;Dz4r4d*+5=-k(Q=dH#`M{$8bRnCG=q-agF!oGPED{!IC-Fz=W1E3#6U=U0)dvKkK!^SRJaZp6mQTgpfC7#^#>z1)E(hk3nIN&^|KtK+?fdV9mkRTFTso{6 zHV(7h7GdtwW7HqZ<9K|S{XIc$%{FYy6L}Kbu{}HRWOfYmd3A<-CePy8JSWWYo-bd( zPP~wvc@ewt;xMmsx!jFcusg405B6j)_GTaU2?}s^#h4LaU<`ORDGA3loR9Tk-VYnpZ&AKI z%=_Xu^}llu|KOkei+_iC9~b@F^Eu4#o^o<|RtR%_D$7;Ey#H#+wbj>?>#J`nH)C_Q z2(!H-<)hd#%%9iV$?e&JC$l3@33Fb~2(!Jj!wl$uW0=?96J~$@4s*Tt z`(|H1_U8dC!lGf0r=(nprNi9M6~bJ%+RE#&F6)JPy+&-Ryjhs@-73s+wN~DSZFwS3 zVmr2Hhp=j#-(9|vJ=l}I*qeRA9REOh5C?NenByBE-@uW)kvH+?Fvl@U9?dZv%UgLH zZ|69U=LAmV9lVowh4~(PLVl7@@#!${%NOJq`4V5|RKCJj`5LEjI%jYuXYqB;<{ZxD z8+?;*aUS31JA9Y(!yLzAc?p+t8JBYfKj4S_h%5OqS8+8z;ivqJpYsc@;aYylulO~; z;kW#b-*X+;a|1W>2X5kz{E0tvGq>;;Zsj&^=ML`VF76KVe%&Mg5$640;M;xAlLNxM zZ%T%_F6F~~j#XeqR$^sVVO3TO^LbS-%=@N+@`h~0#$i5Ro661DoGrra&+&3Ap1{^@ z!?rvz%y!$$9e6T3@)VvL=DeIKpCz9c=5wO6@{8Do7xNN!<)vX>zngpoyYou+U{Cg9 zZ}wqdUd5}~kNtTKujO?dz=0gZ!5qTtIW)|58_pYeqxze8GjCBpI?VUd_%NUU4~99f zk1BsU%yy^nxiI(H)G*h1w(`01`|`pt*I}8wBFuJI%B#ZMr>n!9_s^7np?r<}CBNpk zVYahA%=3Ow{$rT$z1?9xhYNkT?>;FWW_kHAkFONw&wF*k99O+C`%#|_!t#;Zs6R2x z>vah8{y0lMFU<4K53`+4?948_gqManZ&!x--oHM~c1MKS&JAI(;;E5Tg5Pss}g2AwZiO2 zy)duSILzxb3A4O~d_qkM9xY`t)Qk z_GTaULW3$y(P!z_O|%>F(iPnI9! z<9vcohI#%J`B^^4=lKF(+Q~3&C72otoW<8Un{zmqZ}3gN#d&<2@9? zWG&Wa9oA(%)@K7YWFt1_VQj*tY{uqn!NYk3kK|Eo$)kA;kL7VZo~?KSTeA(@@=KJ)z@R0D9uy{C8{T*SxSMK6HVZJXWsed5M@0rPAk#I^_Dx9r+UYN(vmlucm zKL0Sxc2~-u%WL>$nD4<&@=sx&w_V;DX1{-z|KML?_NT!5ecxAQ!v94q8|JvG%QaY& zwOE^VST`&f=hY9h-6qPLvKgDRMVS3+8Rqp)RDKfMu{}G4MdP@$$^uk+;#*ohai zGcRHnUd&6_m6!4|Ue0d3g57y#nEmK2_hDaN73TL+fB70-%j-BGEEvZPk_U4LujkM( z=iwH46i0JRnAf{azMbR3+;{hc|GzK!u=+>TKP^8K=K8!KzsQ&PGN#2{4UIW zx>@~}uyo|T@_*`!ZP<4o73YCGhzExi;=HU&6BC|2FRHXF(QXVeZHMc>s&BD2uUpSSZ>(ST4asSdyh!nq^p)<9Iw< z@dUPJ8@A<%Jc;eto*j5HJMxq;->c`z=ko$~3iE#G8sI?U(K59&AZ$FOjeZwdeZ`4r|n9`M7y`>_a%vRIhUp;B^bmSI_zV|i9!MOI>E zR$*0EQ4DC-pzY>FYgO;o*$GS z;=_D|k8&~}Aig!$fHA%DOR`B9kbvr1mg zPxxt=<60xH4f8%-C$Cq(N&b;Pg}Hxsb8lECa;YEp?emIZ-j9{S{ln^Ej=N@<`>Ao5 z*KHQ&an0F+hw}&?8Ronk8|HXgDL)~s6S;es?e|dLlfA-vxgdB|IQbhGTgvZ{zJ8$MKxNiM)e%@-E)Z zdw4JJiV702X1^LckznESSwd=!rl^L{&lZFpjs^U*=>$Wy~??`(Do^SCbR zFX5%iuV7E*z1dfJ|1h76*YH|i7iND4h1vd4<-@}Nf39*QZwj+tW5YatT$tbMlhr@Y zC&N7MIZh3WM4lDqd2>0B^VKg6^SqDvX_)=^Jj|aH*2^2YDa`gZb6c3>+^&9SnD3>% zVY#r(=6(M=rdnb4r%{;aHw|;Y9}yM}TZMVu)?v=iiD6#<%rN_RewgQV4)gbl{p9Py zJZ~TehuNPY^3X8PyCKZ?!Dx;Ti$%Ua%DGEME?@o!7#=-t;iPH|B-; z9q~b!?SB&Hd27RL@5?a9`CXXjZwT}ExjWVG;_fid`!g&S7TU6Joy&#UPI*>fMOI>E zR$*0EXQa~%e72#2d58Rq&-2y;E}4YPmuhuQ8V z`N1&P=_&acJ{#t7&+&P_z!&)vUk?9&UxnGv8OmpJR+!^`Q+|u{!aV+6c|PCc`(d`b zSYE=VVUB0Hyn-L_Lw*$IaUaX8xSF5vQ+~$J`32W-Ex+Vf{F>kJTYksyxsL0(fgAY) zH}OaQ#GkpDTlfpNavQgE2X}H8ck@^N#^1SzfACNK#lQIv|K(o(#{$3X+fV;vK^9_R z?#KOk0E@6Fi?KKldV?7)-R zk*Dxfp2pL82G8VKJe%k6T%O1Cc>z1|LU!gw?81wA3A^%AUdGGWjaRTcuVfGQWH0t+ zANJ){yqf*kpV#nOUdI6($Uz*;A-tYLIgGbr)+c}Qo zIe`;-2k+!vyqov%Uf#$1If)POK|aKX`3N87WIo2n`2?TjQ+%4wa0;L0b78(0UzA_s z%i;gOXE{^(EWRG*d-g4P9^VeLz4>8&Pb^ZtSoyLr-;*o&Ay>{~f@PFt0OG{f%K>XOujeV>p(#hS{&%!yM1O%I^#F_ixXKIUg^D z`8_v7{md}`-NEuOue(b5>M*~@zL(d9IgTCSLE*n)@vz9YeZN1f5$5=7vR2q2^66pr zr&E~M>8HMbnCmh~9vtS+SGUXK!aVOjKBoL}KEWsX6rbiZVa~_1@^gHiFYraa#Fsgh zukcmA#%Y|+8JrpBJkOTra4z5An_>R^vmnfVE(&v9J`8ieuMTrQKjEkRjGu>j-kLDy z@!K%>$$Ir0xRF1EdA)7&cJAO#?&5C#8s>QR$baxp{>8uf5C7#}{>K8__l@g+EEwjx zmzB%0JS(swE3q=GuqvzZP*!IR)?_W#W*ycIbDo-pIqnwWf#C^Zu1^Q~T=f@(xlWyU zAv^OTcHzZgu2;7(_xDv{-gg5yEX?)4G0f+}-C_3UVdam9*{`Rbr)+c_@Gb(|niT#p}*w6`A?YlNwJ;#_IvR#`(0Kp$MRvmr<=;n*qkkRIFAT(9*>e+@@O8zV|iSd z_f^|4&pSzZyD;bTWVs_x;i){0r-ym|nPEN$&JFWEyf8c@>=ovI?5}(vhlY8-594r- z2(w?e$fLq+e@vM7`BP!ta7kD@+!E$<>(?;b`z_4t|0Vw|7udCLT!q5ySLra1FT=7d z$MUSeimb%Stir0S#zR@1HCU6iSetcNm-Sem4cL&4*qDd037fJRo3jNE=Mg-TN3kW3 z<}o~$$MN_u*XIPeHQTT)Pvl8#$M)>Nli87{@Km10(|HEZ0?!1yc*pt23n|;`qSMh503-h~ns633rIf6HEByZ$RyqULfRG9bgSov1o z#@jiL<2iv7c}JM-+%4b3dwC!4=OjMB2l)^m<|BNRlld4Q=M#LAPx0w6pARp{FY+b6 z%&B~Zuktlc3v<0^$TK;MuX8r%a4z5An|zD&_%`1O^E&h8_xL^+a3L3QF_(ln-Vf!E zxRM`-`Mz5d=5zKt<==<7e}9%Ya|?e7bA7jm`9AwQ%=c2!-TU@snJ~|<8s>AdT9`lI zwFvXPBg5RkZRC@}Jgyzvvjb0N$FOo7*FDVlMK9&O*@u036|ZJL_UAQWwlh#3#K9cG z>p7IeIGiJR14r`4Fvoj~Jc^^ke9zn-=KK3z<@bg8etAZo!e{whnET-c`9=9s&KaD^S$v(dIVa5Py%FX-y{-Hmz8mKLS|l-#O3F6Rn^{FJb!PP<1hH@zI|FKtR1Zi!h^0_eE zeI?BOH$#3S%=>sznD^~RVcw4``Ei)%eG%q-tPRVATf-dRA7LKSU7%yx>gI1l7OJeVcI+<#@|axBjZtQh8Vu7+HbwOE^VSeNx!pAFbB%=u^@ zX8#XYengn_(OPc9wmgw1u^rp915aj0p2Aak8c*jLVXogrVUDw#@+;UqEE(m4a4P zIV;TP>zpvhzd-pyF5+S?;ZiQ+a;^w-+^fT!moJpB3A4Xn%in}`A{YF9-}s7$xo;2T zK|GixcnC|f6ic%V%d#BHvjQu!5-YO`tFjsoWp&nIP1a&<)?r=NV|_MYLpEY#9>ykY z%4TfN7Cf9s@JJpN=KXcFd<>5bbA4LNZP=D4hIw8)xjj4ZWOn2!Je8;Mbe_R8c^1#+ zIXsu=@qAvuPP~wvc@ewtVqU_oyp)&ma(3et?9MCMgFV@cy~EtsSBH5YT@&WK4hnPr zhNvGN=KdZL=KV2B{TStAc`I+@?HtGPVYWLl%JMz1n&-eH~7jPjLg?XJNVLs)qff0xV{bZy|gjR z=igTK+qj)OxRblMo4@im{?0vNK9~QuXWzOMWFZ#je%wFIc`7OwV{snHgLp7Y@DP?{ zDVAm#mSs7XXN54|OVz`iznWprQ(d`!nDf;n%zidkemIY0OCA&Eemqt_UT(z`l(*rD zVb0g-VXnsoVg7ySim-GzSRNJTd*seA`*Ba0{dzDg8%_;#9JAEV33L75k>3mRIxE6# z=Zi4MyH@@o%;SFv^E>|^xzHc`=Hmbs53_$2!aToHnEj|8=D2IHCTp=a>##2Cu|6BH zAsewV4`UNHWivKs3m(oRcqETvOCHT*cr1_O@oW|5{I>~npR@~e9y+K$nH_lwPvvPm zooDb&p2f3yPMFVyPV$B9%!}BC7xNN!<)yrgm$MtMVD~V`*HiAr-t5D^yoy(|AN%tf zUd!t^fCD**gE@rPb0~*#I7jdXj^vHJi8u2Wj^b#J;aJ|v+ju+2aXcq*BJbdxyo-19 z9^T9Qct0oc0Y1ow_%I*gqnymg_&A^7lYEL#^BGRzvwV)v^98=hm-sTL@)f?y*Eo&S zIfFAfi?4Gw=Ws6H;G2Al^Y}L3;k%sA_xL^+a3L3QF_&;DmvK2)@B@CxkGPT_a}`(f z6Mo9i_&LAe8m{G+{EA=m8-C00_&wKgJvVS8f8Zwm$e;K#H**Vr;Z|1h!@yw&jUDiS5{)9e6T3 z@)VxR(|CHA@0qjYv*q*T^LYU~@j`YE^Lyv=FyD_ol=oyW_GTaU4fFVG zhxrH}oP@tme28dzQ7m5yxvs#6~4;XIE~XegEKjcuX8r%a4z5An|zD& z_%`3+yPVJW_&yhKAs2BmmvAYUaXDA;1AfSlxRM`p6<6~Ue#+1IIltf>cLu{lZG&ZOU)wIF9FpFyBM>g}EOeR{jVdOf@Q~+p%!HXS3ueV^nBCO#MQ+M@FfZoA{8#`BVj(PSD(_;Zj&mhbc}20kJ~l8l zj;55OO+6RHvAzxK6EVqDyX`3_V+wY_j;7k}Wa_>?fb|1$5Dvy6_^PS#ze#y04#VL% z0!QK~9F1?`7#xe^a6C@Hi8u-0#&_^td=KBp$)?8n3FRsHDSpQGuPJ|n-_n4};kMiH9j^_c&2k}2Vgop769>rsL98cg$JcXz644%bvcpfj{MZAQU@d{ow zmG@0ka*W>e3>`6%Z%b=*pry5H7heJxX;uVBg{rml-o zlQR_856{Vs5x@&&wzm+&%PG1cD< zQ~BOC)!zfQKg37)7@wHRFYDu{`{y+E{*=qq`U0lrvpDNZnChnt<+7&cy*lL@7=$&k z7S=X3zrm*3k6?Wy)-!dSVol}W%GCAyIktB*)qf9D=hZ8$AAkdK5Dqrg-dm=A7x{?w zADcQazBbj*cdVa^-{Ul#jx%tksd3DvJjc|$FQB{-7vYb%7?NB9_@V89cu$CwE-V;0Pc*)Tiiz?_&1b7LONi}^4=7Qlj72n%BoEQ-ajIF`VY zSPDy<`rMVJTn@`)1+0jburfY_Rj?{n!$7Q#H89B3=cqR2Iv9*07>Z#Sj&(5tBe5Pv zVSQ|X4Y3h6#wOSlqp=yrU~_DNvDgyhuobq(cuc@Hn21T(7TaNaOg43#I+(i7ccR?I z)b+a?<#{2d3ufBg!A+CpZN^#n13_`~ttkukdU92EWDca4LR}({MV@z?nD; zXX6~4i$CBzoR14|AuhrnaWO8zrML{2;|g4ft8g{`glljuuEU>kJ^q3la3gNQ&A7$X z=YA{YZTLHG$3O5-{0n#BPTYmNaS!grefT&2ga6`wJb(xBKRkqo@dzHpV|W}-;7L4% zr|}G)#dCNbFW^PIgqQIOUd3y89dF=GyoI;%4&KFkcpo3&Lwtmf@d@f`q3eaB%!HXS z3ueV^m>qLqPRxb5F%Ra&e3%~#U_mT|g|P@0#bQ_-OJGSXg{83!mc?>d9xGr)tb~>E z8LVRJd=I2t9cy3^*2G#^8|z>&hF~a$VK~;s2#myf7=`t*0XD=&*ch8&Q;f!D7=z8R z1;%1ajKfyg8sjkm+h8IlVOwm6?J*fsumg6)R7}Hk%)n0A8N1-K*cG3{ZumTQ#}}{% zzKAbjPwa&+V{hz(eX$?*$5(Iw4#Yt?7>D4i_!_>BZ{V9a6o=t(9DyTol&SmbTa?G( zSR9AraRN@nN%%ItgYV*d_&!d?4@|uWPNDp%ssCPLCgoW;+bnDAH=BAM+G^@Odk5Qh z;x626>OJSDL=r6_y`~46Abvjr`N~-!%UbNvtU-thS@O( z=EPi>8}ndZ%!m2002ahTSQv|7Q7neVu>_XHQdkv9`gf+1i*2X#*j3F3`VHl2eF#;p89!6n(Y=8~15jMsq*c79&8OC69Y=N=Z663HH zw#Il&z&4m@>ir*xns`u>M7S343BMd>MOVA5;DGGyVHQ z)(^#DINVeoV=0fr@i+k|n)!!piszR>7)R4Fj<{*1#aFiM6mc*1=#5!B7mtaIA|F7>V^T z3hQG7Y>17pF*d=b7>&&^2AiAu+_f|HxkzJuI%Z%e?2KJZeLkP3+#O%Q9;Uu8?nk-5 zsq51~%7bt)4#8LPHGCc4z&CLy4#VL%0!QK~9F1?`7#xe^a6C@Hi8u-0#&_^td=KBp z$@l?&h#%p{_z6zIPw_MS9KXOX@hkiqzrkU?X zpZFKJYK+y zcnL4#6}*bq@H*bWn|KRv;~l(<_wYVGz=!w|*eX2%?u)714Y zALaa501KMB-j$+U8p~i=EQjT>0#?LISQ($eDp=Ljb+kI=8W@B%u@=_GIv9*07>Z#S zj&(5tBe5PvVSQ|X4Y3h6#wOSlqp=yrU~_DNvDgyhuobq(cuc@Hn21T(7TaNaOvV)K zfE_Uv(=Z(~uoHI1F8C~V#pkdaK9Ak;1?+(@;!D^Qd*RF28~b2i?1%mF6&!#AaS#s1 zA^0l3hOgrr_@=4n=wXzH;|Lsyqi{67g=0+ZKaTQvoPZN?626V^;Jf%9zK@gf1N;y_ z!jJJ2oPwX?XZSgOfnVZR_%(im-{N;T6~D)6I2~u;Oq_+YaSqPKA8;Pd#|5|$7vYb% z7?Xc!Kzpd1F<^Rz#y!NwXinU z!C(x*Pz=LxtcwvCiS;lF>th3Kh>fr@Ho>MCjm`qYU+Ev8I)(@ES!yVa4!CU^Kd>cz=gO7f5gSO1efA6T#hSnC9cBN_!F)%mH&EE z^R&U#aoCK%nVN^KxQ+FHQ2vwhPE*HapQ-ltv;6=b#Q*RR9>ybh6pxu|=M?4Bcm~hn zIXsUS@FHHq%XkH^;x)XEH%yKHHr`|XeSClq@ew}8Cm4{G`vzvh%$NnUVm8cXc!Kzpd1F<^R zz#y!NwXinU!C(x*Pz=LxtcwvCiS;lF>th3Kh>fr@Ho>MCjm!AwH*qKq!{ImrN8%_Pjc?%?9E;;{JWjxgI0@gz zcko?&58ubh_yK;1AK}ON2~NRJ@iY7!zrZi?EBqS2!Ef<9oQmJ$G@Onza3;>e**FL1 z;tx0v=i>rgh>P$?T#QR_DK5k1xB^$=DqM{};Tl|v>+ok>kH6ps+=!cSGj73O@i*Lx z+f3b${xEfa{>#*TaX00?rtZ)COx63B@_syk2k}2Vgop769>rs(eor||`5d0d3wRMP z;bl|*9mj3Tckr&M|9-nbwx_?tmN7M+a;EYxj}@>YRxv9`gf+1i*2X#* zj3F3`VHl2eF#;p89!6n(Y=8~15jMsq*c79&8OC69Y=N=Z663HHw#Il&z&4nON!S+K zVS7x*6zpK?_@tUTuQFKQ2|HsKd=|UnbJz`^$L{z7_P`hMCG3g4@MY|ceXuX~!~XaR z4#0sp2nXX3d=+2A*YOQ}6Nln39F8M!B#y$-rsi=B<*_&p$KwQ?h?DSbQ|JF=${*l| zrrt}wr2G|rjo;w6ruv^s`Fos(({YBW|Gs7sJ($Un*{@{Zgzijb*T`ssH`h+LY^HFou}Qr!nOw*c78pwcng_3yj5< z7>BK}HO8A7cYDgon1UU!Bc@^+reg+n!p^4V?Rm=G@dfOGFPb_IJxzUn2e5visn6eV z$|G6HV?xSB&{t~~!ukjoF7Qe%(_&rX;={N&t;w+qvb8s&Hfb(!ZF2IGj2!F)I zxCEEtGF*-;a3!w7)%X*x!L_&!f5!Fr3vR%TxCuAo7W@@|!>zatf5+|k2mXnF;SSu1 zyKpz|!M&!=?|&%&i~I2a9>o9f5FW-OcodJ}aXf)1@f4oMGk6xy;d#7(7x5Ba#w&Og zui9t@>l^YVkNAM&tMg-iq$X>t78oe!kSnMYhxV@#t;m}Fbv1K z7-8z~l$%p-fw9;U*cRJidrZa@?0_9H71K-|moAi_#jf}qcEjhf zJHCKDOnp9kQtpK>V{hz(eX$?*$5(Iw4#Yt?7>D4i_!_>BZ{V9a6o=t(9DyTo6pqHX za14&caX20);6$8+Z{s`oF20BF<789w_Yvif@e`bapWOizg}eOy>_Lk=b=@s|H;&KX9Mdu;wIdTTkuy??QJ#H-cHu< zGS%;1%KPwd{0INV{dfQm;(vGu591L$ipTIcp1_lM3Qyx1JZtJX@1m)3T&8@T?Kkiy z-oo2>2k+uNypIp?AwDwI&lAc4IiJq||6wM~j9D-%X2a~519M_7%#C?4FXqGiSO5!R zAuNnVuqYP8;#dMpVks<*Ww0!k!}3@GD`F+AjL%>dtcukz5UXPi48odN3u|K?48{-) z#V`!Vx)_0xSP!GHJ~qIH*a#bA6Ksmn*bHM#eGXewj>iOSgNc}gZLuA;$7D>w4%iV> zF%8o(13O`7?1Il?S9}h;nYteIqWm)U#y;2=`(b~41qa|j9E5{$2)>H1;p_MYzKKI| z7!Jn~I1)$UXnYID;8+}o<8cB`#7X!zzJu@Ld-y(1#t-mA{0KkBPjCu;il5=<_yvB6 zU*XsI4StK?;Z*z{r{Q#*firOy&c-=77k|KcI3E|_LR^GD;$mEaOK}-4#}&8|SK(^> z3D@9ST!%m7di(`9;6~hpn{f;NYU+Ns&D8aMJL~_zKk+Y9^>&%6x5w0b@?lfYb0iY1|RQ-TlPwQtk_1^{MH??0uQ|*^ARj-1n&t)LnYhX>R zjlrh=ch~AuZfI)%rq~?gOy!eks=v0_9#c&1muC9&D&=l$?{4b(;|1)2FXBts6MNyy z*cK zzc4i)-%_5&_USkSXW}fJjdO4={($pvJ}$t8xCnp5#kd5Q;xb&0D{v*Q!qxZ_uEDjq z4u8h=_zP~pjkpOn;}-lCf5WY~4S&b&_y_)pf8h??iMwz&?!mpd5C6u0@L$}I2k;>N zhllVm9>Jq{43FapJc+09G@ik;cn;6w1-yut@G@S(t9T8s;|;utx9~RJ!Mk`5@8bh} zh>!3wKEZ(8JojQI%#2wuD`vy&m;-ZSF3gR2FfZoA{8#`BVj(PyMX)Fq!{S&1OJXT3 zjb*Sbmc#N`0V`r9tc=fK6|9QYFc7O_4GhAXSPN@o9Sp`048<@E$GRASkysC-us$}x zhS&%jV-swO(bx=QusOECSZs-L*a}-?JSJcpOvEH?i|w#ICSwYAz>b)TX_$@~*abdJv%Ac8f4*0^< z{r(&Lp7qly&!#*V=b3sgTFmz4tY3+%aSg7+^``pSWa@chGj73O@i*Lx+wgbXj(^~v z_!sWLowy5kn;P$4%KPwd{0INV{if#YKgx&ju<6gUluzO*JdJ1YES|&jcmXfsCA^GR z@G4%z>v#ii;w`+5cknLW!~6IEAL1i?j88Bi5BD?7gqbl5X2oon9dlq#%!Roz59T%X zdt*7u<*@=*#7bBhpTR0v6{}$&R>v9`gf+1i*2X#*j3F3`VHl2eF#;p89!6n(Y=8~1 z5jMsq*c79&8OC69Y=N=Z663HHw#Il&z&4nON!S+KVS7wAbsb1I^dz^;TaR$!BSvVW#;9UFx=iz)@ zfD3UE{)mfl2`&B;cnc6dvPEBjsM`kxE~MTLHrL7nYvFMrF;yJ;|V;8r|>kM!Lz3BYnSjk z>u;F)-!;mX_vw8gJLbTgm;O(V-YNh#jrS*z>-)BOJf-SOu$MH4Mb+SObHwCf35*SOby;*oQCO`ft|23cEM+{D?W$a z@OkWxFJKRR5nsZdrpEU&<=)r_`(i)rkFVeW9EgK(Fb=_2@ilxM-@rF)J%;TRl?<8VAqz==2s-^O?FU3?GU$I18seuy98$M^|O!B6os{2af)FYzn<8o$AB z@jIM~-{Ul#jx%s3&cfL^2j}7sI1lIJ0$hlT@JC#XOK>SJ!{xXFSK=yMjX&WUT#M^W zeO`W{ya6|wdj9&0@($dIyKpz|!M(T-|HgmtU)+xe@F4z&hwv~S!J~K#kK+kEiKp;1 zp24$t4$tESyoi_ZGG4)}cnz=P4ZMlB@HXDTyLb=p;{$w%kMJ=*!GL_cH(@5sj9D-% zX2a~519M_7%#C?4FXl6K{VG7YAQr;HSOkk=F)WTHuq2kk(pbh+KjkQw#|l^xD`91P z2CHCItcHPD9cy3^*2G$-`mci_ral+plp{=izYvM_SYMxV18j(murW5lrl#7BF?GLe z$@(~Kg{@81YeP8^ldvte!}gerDW>*MHPufiQ_o?~vA(;h@%At^t{3qo?1{bbW$cZ8 zurKz*{`d+Gz=1dj2jdWY6<@>G@eO6IS7LLKOI1b0-1e}PI@NIkt z-^KUveVmLR;D`7TevF^s6#NuF!_V;x{1U&yukjoF7Qe%(_&rX;={N&t;w+qvb8s&H zfb(!ZF2IGj2!F)IxCEEtGF*-;a3!w7)%X*x!L_&!f5!Fr3vR%TxCuAo7W@@|!>zat zf5+|k2mXnF;SSu1yKpz|!M(T-|HgmtU)+xe@F4z&hwv~S!K0==-^VGRz>|0iPvaRp zi|6n>UcifZ2`}Rnyo%TGI^MvWcnfdi9lVS8@IF2;HJ(S5ALA1Y$j^NdGht@Tf>|*e zX2%?u6LVp1%!7F`ALhpbSP%P$?Q~NEWyqxlCT!$M><-g5TKHFKp1NX3g zALad&51Pv7u&Mn|o67eJ+ppmbQ~BPceA`rB_f6H$T;OTHSxwc;hS@O(=EPi>8}ndZ z%!m2002ahTSQv|7Q7neVu>_XHQl_5ctD5@nYQjv-Lj>C+P0eEz<@(qF8)73<^VWiL ztf~FtOdbCuQ}dK;s{M{^PcwDCJj?dyP0d?(Q}tdnbsqIL)y_au?G84z-RZ^PQ&Rq z183qaoQ-pEF8+Y?a6T@;g}4ZR#KpJ-m*O&9jw^5_uEN#$6RyFvxDJ2D_4o^Jz>T;G zH{%xk6@SC6xD9{D?f3`&iGSe^+=;tzH}1i`xDWrvfAC-2j|cD|{)dO~Fdo69cnpu@ z2|S6X@HC#mvv>~A;|08km+&%P!K-);uj388iMQ}J-od+g5AWjxe29tX~(Vm*w)`q%&)Vk2yfO|U6O zV>67w=GX#bu_eY~D{PJNn1F3C5tFbjw!`+Aj49XwJ7OxPVLE1DC+v(}@LBAN&tW%w z9=qcU*aKh0m#`=H!k4i(_QAf`5BuXQH~;%~SWx8d)&9sj^TP360n z@;>|<|G|H8KOVq?_@AkKj!-^|$M86wFjem~p5^24Z!rfk9XkYhi7ygTWYrp%{kYSQjHO66;|U z);IN@8ArJlwl+2IZ73&V61K&5*dCKjoev!-cf?do!*t9r^*QNA`FZS)FJKRR5nsZd z*b86A-q;8GVn6JUuiyY2h=Xu24#8LPHGCc4z&CLy4#VL%0!QK~9F1?`7#xe^a6C@H zi8u-0#&_^td=KBp$@l?&XzI9qO!*U>f}i4NrryiGru+?li{If?{2r&_bew@RaTdb-v#<=wak_p<#z%7^eU9>Jq{43FapJc+09G@ik;cn;6w1-yut@G@S(t9T8s z;|;utx9~RJ!Mk`5@8bh}h>!3wKEZ&(y#HV(%xvns&q_HPX2%?u6LVp1%!7F`ALhpb zSP%Ug%L+z#8D8fPlyG)%_~?1Y`M z3qFfo@j2{<&trFd0ej$!_!9QSUih-9y!%k@i~X=azJddAAP&O8I0Roc_1r&<@^Bo1 zBXJat#T~}9w*>LoP=+idarn&@?`t~Kg5slWBdfC;HUVRsq_0w%3qoK|CgUf zc|I<{g}4ZR#KpJ-m*O&9jw^5_t}=^Te>*7e#9gNH+DmyK{*C|OzqlU{;6YQz{Sf8D zcm$8)F+7eZ@FbqX(|88Y;yFBz7w{rp!pnHY)VQuwzJWLK7T(4?co*;CeSClq@sX*& z3(r^N>2*0j7Qlj72n%BoEQ-ajIF`VYSPDyH8B_PuXH1=+fvm4?>No^Zu8FmMOVAMA_$us^l|Bt6U0Vm=ld>h}v zckw-ZA1C7n_#u9TALA!D#nkU@-%*~5-{Ul#jx%s3&cfL^2j}7sI1lIJ0$hlT@JC#X zOK>SJ!{xXFSK=yMjX&WUT#M`QXIziJ;0D}?n{YF3!C&z=+=|=qcifJD;Gg&x?!cY6 z3wPrl+>870Z~Vv9dA*mx~|-#d>wWEVjfrQ}fW;RJ}yXZB5-5I`-rLWonZS(JcXz644%bvcpfj{MZAQU@d{qWYj_=R;7z=RxA6|%#d~-k zAK*iLgpctF1{CA^gqbiiX2GnO4YOko%!#=$H|D{-m=E(~0W64xurL2y0?3tc`Ur7(*}=!!R7{VgyEFJ&eNo z*Z>=1BW#RKuqj4kGmOFJ*aBm*CB|VZY>n}lfNd}lldvte!}gerDcAu!Vk)L#I%Z%e z?2KLTS?r3>VK;mpyW7xt_i-|QfFI&V_%VKhQ}9##3_r&& z@Jsv(zs7IyTl@~E;`cZWr{fHqiL-Dv&cV6(1J1+wxBwU8BK#2-;}Tqo%Wyfaz?HZP zSL08(2G`;`{2ABdFSr3W;wIdTTku!>4Y%Sp{2jOBANVK!g*$L3?!w);2lwJWQ}^jZ zrk+!dn0}u&^*nRV)bq%Bynq++5?;nDconbVb-aN$@fP03J9roG;eC8yDzE=5{`C1f zi>dswVm8cXc!Kzpd1F<^Rz#y!NwXinU!C(x*Pz=LxtcwvCiS;lF>th3Kh>fr@Ho>MCjm8R%9HT})_+X-6P$vdntE^ghVr-g9ZogX?sUpCa3;>e**FL1;tx0v=bIYmLduKq zM_i0ca49as<+uV@;woH?Kj9i&i|g=bT#vut2Hc37a5HYfU-38Giresa+>U?XpZFK< zz@4}YcjF%1i~I0z{0INV{dfQm;(vGu591L$ipTIcp1_lM3Qyx1Jd5Y>JYK+ycnL4# z6}*bq@H*bWn|KRv;~l(<_wYVGz=!w zKFp5=upkz~!dL{0Vlga^C9tHa=Z>J(o+SL7NEah=H9w*>LoMfv0yOiI<_i-|QfFI&V_%VKh zQ}9##3_r&&@Jsv(zs7IyTl@~E;`cZWr{fHqiL-Dv&cV6(1J1+wxBwU8BK#2-;}Tqo z%Wyfaz?HZPSL08(2G`;`{2ABdFSr3W;wIdTTku!>&D4KawTJRv+=qYTKlm^1#{;I$ zk3*CX;}JZH$M86wz>|0iPvaRpi|6n>UcifZ2`}Rnyo%TGI^MvWcnfdi9lVS8@IF4k zhxiB|;}cW!lBwj=`($R!f>|*eX2%?u6LVp1%!7F`ALhpbSP%&hF~a$VK~;s2#myf7=`t* z0XD=&*ch8&Q;f!D7=z8R1;%1ajKfyg8sjkm+h8IlVOwm6?J*fsumg6)R7}Hk%)n0A z8N1-K*cG3{ZumTQ#}}{%zKAbjPwa&+V{hz(eX$?*$5(Iw4#Yt?7>D4i_!_>BZ{V9a z6o=t(9DyTo6pqHXa14&caX20);6$8+Z{s`oF20BF<7E5*Kg5slWBdfC;HUT*evV(@ zm-rQajo;w6_#IBg?{OMV#~C;iXW?v|gLCl*oQLyq0WQQv_#-aHCAbuq;c{GoD{&RB z#-DHvuElluGp@&9a070{O}H7i;IH@_ZpCf*J8s86@K5{;ci>Lkg}ZSN?!|rhH~xeF z;(k1U2k}2Vgop769>rsL98cg$JcXz644%bvcpfj{MZAQU@d{qWYj_=R;7z=RxA6|% z#d~-kAK*iLgpctF29)Bx7&BpJ%z{}l8)nBGm=kkhZp?#uF(2l~0$30WVPPzSMX?wb z#}Zf)OJQj&gJrQCmd6UF-k$?aeP3Q1!?C{U|DBAfdTlYy)O&bmQ~Nz{>hDqqn)?20 zFurQ4-kX$%nfkl4@uv2B*UWEzWvcz@Y+pcmxvA%}Ri@fmi@%uaXCrPl_5J=9%DhBH8 zLrwKF8Yh^l{|-(z)&GZ-r%?V3zre3dWJG0#-JMYz<|`MAbZ zzw2;O(V-YNh#jrS*z>-)B zOJf-SOu$^Iv#;ogY`jJ6Ki2@tb@TAVru@vDc8jajKq4T`m2u( zP3_l&?M*4iP;PFjek{geYqrN@0=B_KOfuDed&UU;)7kn1G;&Z0X z^B$(^_r%_&&aeKa&eK;|KZy0Onc8m{$W(iu zndi=S@-bUQa_O18_>;J-?xEuH4-=@a#kEwY% zV5Lp@i(zprVXA&9%B8Ukmc??Wt~1YI4b}&ln(r`d!1{)!jz=`cn!3)lHPuc> zQ~9Kt%CD2DJi4&GyQy}2o7!&(+h4;s%p$h_JyX9ge$M(Y%}Q2YYwEacGS%NUwr@A} z|6_f^RJ)hhe#6xL>!GQ90?IwjKdY&7PE+mVr(D=nzC}&tS=Q8e%9(l&s%>h&P*eNW zqukI`UNNTjZ^8C>wkKh-sqgu^nyS~$EMyKc^*lD()Oj)%Cz$HzJyY#}VrsunDSu-s zpYKi8o6YvQrt)7*d8w&(S5RJMYMwTlWz55-+Bt5jowIluZ?gTass8U%er#%fvzLFm ze{NIT^O`z-B~1NyG1XZgWNIE8nCh>IsriVfoMdYMcBb-3H8nrI*xuLFxQ0-E!&LpD zI2=c^eT=DgCQ*LR)cO07srjC2D*w5r=4ZaC_7N6x0yN*em9lx-)1TEs;P0@ zG}X_2Q^)E5Dm)!`AyfamSgRJ)r@9ml<<>K$PFVN>lL zHI@G{)}Lbi8Oj$-ZNG?@Ozn3CubIl@0oxy%8ut@Zk<9x1_21WlSBP zK(^N~)o&2xT3E-_c@S=D|9aSv?Tslnqud;0O|{n&o9gccQ+f7e{ma+~`{665>J2uv-w?`guze^F$B{VN)PCbku^18FxBox%A4_5 zQ+fQ3f3be2sl4`>I?oQV{g|oq`<$uv&YP-t$@KFRubFE17Ues54_71&;xaurj@ttRE#7;LJ)a8vC?n#!Xd zMwx1_0p*6K>NhntKXGhtjR~ecKkX4jOe$NZiY+`UpDOmRqH0$0tyKb)Ta^IiP$eMU<4}uL z1603SfZD0%b*crlvE@KtQ{9#-1yr|x6g30Y18RG$@3Dc$P98gZ?Ba2_#TxdnqOz(H zp!um0pqY6(kF{*6Qb4T$jk;EVMqSH$RO^+jk2)S(d(=$U@ioETdk9hU780Pj3JIv| zQF9gIGZW&ih4^?w0+d^*?-lB^9p=kn0h-}3uOA)|XUlbceO<3p*SALaay{>*zAx7g z(7b8nl>!=iRt&jXH>NJ743aR2XwGC&Ahc{KHJTFwww8EH}jg!yiQDjj#`Y@ zjPaT=KI$0nCC2N=c>7P!?B-sxxo6ni>p%TOH20bZ5jI{6;TKJjM!n1AR?X>WI zTLg5pep>{jS&a2rjrEpeeblkua;%R!)?179_G7(;SZ|@F*Kg@HTl#t(txA@?&aOD$ zE6(?d3(zdZ`OLKP3|slEw(|B{`OLKPJX?95t-O9KZ?l!pRV&Z7wf7iLR4?&fCq5w6 zmJ@t^g7==_y(f6@`s7ry*26sN)7Qr9wDI2Cc+ED{)Y+0~XT74%_C#+p(Q{7py%Ig! zM4#J4-z(9xP4qkyeP$9p+a%vB$w!*xb&@>WB(KxfTW;%Zw)Gs^dYf&%&9+{%Ej4vz zXy`I`2=Z+qXjz30>3_iFDswD);V_T!lBy(fFkWIwNxy`5yQpX^yBQ(tFninpBN z^;5iliq}u^`YD!$>ga4w@xD_0s@1`lJ9s-Cy@ih6LPy^#)z_qYYpLE^s;}3XSIN#l zU1!p~PMV(sY2JRCpP6a?Y1Q~ESx>5&?lsfB{d8|9-Rq}&Ch1;3!|P;toeXbN*P2SU zO`qA$K8IcW`q{;=d|mts)5SlDT>^CF>|*~^3ea6aQRj76ALCHF9#^vKh0da(KEp$O zhKKr580s~L`c-16AI+icrO(=M?{T>IINaMGZtHZ{scG?l|3uqTu>GUh++z!ix}qvZ zd5pCf8W8DG^~3G+tEl=BcAhJ0Inrt=s)a~9+baju^ELH+O_b$d*+$aLqv|*FcA8l& zEo)7TXA*I>`y<&YYU5hH)p31+q9lOeQ6qD?Jsd=m7bE??TmK)fyt>V{z-DNx2vaXqm z)jZbnm|`)`jcZ@mQ`n{ZK-N4M_bfYRQK#8 zi*0<3KEGA%)6&SIKATnTJa`&A*s?xNI*)2v)M%7lx<%d56{~x!?XkYc1|Biu^!c$?j607IgJi)Lw18j;_+xY#-&L^Q4;ntC`UiSW#K&s;j6vy51_b_o%J9 z(kg0M*Vt;-x?0e6vYP#?eszUZRL!SHQ`bW+t4;^cS=YmAb|+AMU3nDMrmj4SI{Lcu zC~E$7%~8~m)fGljvp3Y|O;;E#$9vRRbZt>oFT=f^;dUeg{TVsX&uPVKwnk5miZwje z^jOLxSv=x&)s$U%+MfDiydj)#^K(8O@^#koV2U_2n z4}HoMH5+<}R-jm*+SOiqeh#$jtYSTnQQmta&sop9nn7hA?enH|rP zU30Xon$5kJ=63#TS^2c^zH~*>vTEwNS5b9zMN&-jsPj;7S&I6M=qXoGndnNcsPXDq zH_)$FiaG;ZS{sTw|MlD(Xk*YCUBMLFdQ^{k%2m|4s_U4dw(7}N@o639)7ob>-rI@y zI=bQoS~i*oJ<}>GLtXt8brf_BRMb{o2^F=qjpwZEVW9O|-J{MuJ%j8yUS~hMwjke^>nIb ztoTd3N$~b@JKnWap8#s{KyhS0~S;lV{S&v+d;9B0a|j+LE%>-6YWZ z(EN1uzVr?pXml&?bbh0a$qOPf({Ce5RR5seGxl&Ziy5}k?XWeZT)tY8W8LR$q zdp=XtbC|X%s=l7s6}#HCU-fhk2=y4|vAM@q9^)<6w&SAM!lTw})QW0BS8Uxs+FR7q zl)jNku&C!EMXlErqlQ2E=sTJeTTTmj)}lrfWI5Ed_`iRGeJR9asK+pm;U4RHtmiSx zV>6F29%DVW^cd$+?FU((ifui%^Vr^Fvd0vU9X+OcO!JuTF~edVU($C(T2^j#?8>aD ze(Tt{71etkyZ$N0dsM%5yx%%@ZfIG3)v+U}s9x&WXDi5#y7CM5mV@oSre(Ds?Cl48 zYr!_FTGPg(#ue=23bq;6vf2;!_Je6tnd?kaRQn;;o1%IP@pU0~+_fCxG18+(6yhTa zu_LKv&1Z-mLq&})#4`!;OhWt!hIl3+KGG1oI;xJc3h}H$?CPy$<)i)-l|!hP^bDY7 z^&V<(g^C(`sE<9=`wjITL%pw1?<>^%3iZB1y{}Lod#KNCs9opOf@V0>XCu^m5A$Ba zyq7RLKZES-RbOE~-Y_3;m>w1QDea7l~FLh~I$0EYd2R%V)S-nJfFA<(?g!P~`>MO!$EW&3j z!u!=*xz_6piSQYV@VSccej|K-BD~)SA7g~~9^t)5__2ue9wWW4NNXd=j*X5*q>m`l z+t-`E*60k3^wCB7=py}mi1g7#dM}aQex#pokv@}=-dCjer7;Bg^P!?fTF=^3)RubQ zV?FOt-zR8|`mN{v*7JVrdB631boIR7dfsn6A6-2^_nuylqI_1Pd{(1;KBIh$Q9hqh zK9f;ClTkk2DDOAQ`;GE`qkJZ#yvHc-G0J<1@-asFnHJ?EjiO(j?NNT_MEN-%*7w6&qtCm(8CKNT^~|iOIgj?S>$_qt>uMJ5Ip}JyWnFXhEwQ4m zY0-Y>M|&pGKJ(2yhh{$K&3rbRc_z(#HuNn`kj;XQLNlKkJ%?*qXM&!_6_r&p&#IZv zOfx_F&HO0nDP3FJdeoIi-$g6xy4uWhP%A;!mS#iW0x9Yo&@;TE&T~D(E2?gc&qj>* zt8a(2M%RHDpN$xwjTk?}V?2i#?>)w6M&EC%re;RZ|BAZ$#dtn3o{#1_$ofzw%{`Om zo=J1hq`4oX<~|#GcTgSep?j;M^3l74qK->*&!o9$qPGdH(QN3QLQ$FM%|cPCd>-^ZqBZJWZzYQAQST;-8g&aFwcb#) ztYgu_dsOy8HU^Dd-7mOkpI&mwU?-Z&p=oS*Y?KGHZJX`JO7Wb>=Kao%H`_Za7W z#d%+GK9)EiOPu!-=cCYE1lf$}n%2r&Zsqy6@|Iiq?CBQ@ZPoLGp2rk5OL~J-)Va~h zThnNRECbC+Yrl52_BQpKh1Te}wDy^4ZS$dJ<=on5rnR@<+Rum9-m=~YwN>XvYwxAC zXCCjzJ>KU$-sdFVdx`g6;(cb~y{~xhE8g>u_a5WD$9T&($mU3+i1%LNy_a}D3h_Sw z@jjw>KMFcmf-Fm&dkKCl61?{WA7g?a_XMBA1n)P&dr7dYRbS^-f{!b~dra`rC3s&6 zKCT4sE5ZBHEC<NcF3YmNk2Ad_?-yM$4MRHr|)se6<|!QTev?e+Alp-YC3;_aQ`WNjO7y-Gy%&AEs5NR&Z_tYREGPQt z^h=PIb?o#`t*G-P(dRbNGfDC>Ci$!;`K%`Sc#}N0B+n|zvr6);k~}NDo9nq;Gmzw2 zC3#j!KHEv2Rg#TfTa}OA8Wfd7lIM`*XHk-8lH@a!rTiY_<(O8o0A4TP#>~oduqe%8qB>Rl%*M}e*XRyZ*kGkfk_%TZHvp2;*cPTzb zefy!U>RsP~C~9;mK0199qGf$5Q#_v(KU?(Oh}LMN`ffx~=S+&{mg2dkcy1}4o4zdx z@@0WJjOpjy_WT&ZzY|f*pNC9le*1-iyAs(Rz)pqxaR(`|4;Vtc=SIjx98x`pR3C4uXOil3p6dDN7tbK;Lo=W1bDruM zrh0Dr4OHuuVXB`Msh(%5&rGW4nd*6_dWNZd4G|w%~XGy=P zs*XOnX`WA-XOiaUK$_>1=K1JXSJhEIX`V@%=aA+(qsJE(rHo=-k8LdK_cX;si?wZZHSOQ0QT2npez1*E%i$g)Jl3o~jwv_lNqckeU|td-Bs?i52y0 z@c;g4>`R?3*72n}c6{~wP;HO;ohR7Z|KHzN>02f(t4(cFR84)?q^NZ|Qi>5C>wD~C zQAbKq`|59~6t$O*nqrto)zmLUifT>ANU^TRNRP@#-{;h_c~Q-9Z%xNe%i1g4_tFv6 zvi1tMc~Xq=s9y9pT8i3B$5c@{=$I<1zUEg^HFX>nl}UtsBU;PmMf>U-2E}NLIxdPD zyN-*Z+R+<&EvuoN^$xBW=P|)!TaU>eHUD}eR!p*}zg|#O`+8SZ)V})dsg|{+@#>9I zv4Ka`)LW!tD~l~WbG_whInkot$P_gqyZR**$mR&Wp ztS4AS<*cVoMU6sFdbMmxb@bbcVh4{p>-1EksCM+cp{REBn~0)nruZoIJfLOO)UO`3 zY@6EGJ*$?V;ffvX$ms7~{-3Bj(QPA1wlLh!;){W0*di&3T5W0C@}h+lx8mBip?Qx+ zzx$2vqzesW{>i4qjFXW`s(3Q8h@5w;9r@*U5(fD%JWAV7+dp2e_aM*Z#kcn(9H#9R zz^6s4)%y}!Yn)rOE=D!`coo`{9Mx>&_mC2`i71NK4(i|Q1@(WD{=L6x>;EJ@+fmil z^GW*jIvUh-^y3wTdhlL{RB>6+vrh9Y?;3-OA) z(6hWNB5f)rkt**>sDJN@NXdE473x#1B>H`?FVv@37E*GVpL!?NHe=p7kp}OR*nZQ` zy)&Y?-YwDZc+VVE7DT*GpWY?4^~SYB&*I&oXI)p{*q$qg*U|4)Y=7uJw0`V0<1Ac+ zt56PkT=*^A6upYkBVNTg4d;C%_|yG>(eMw>(i*6Fg^H0iF)u^68(;MIi$*`JUfMc-)A@UEbn`0)IOcr zNAx@13DJ7+eu$KGiDK_qn;xIVP!HZM?Lm63y<_xT@0m!6&pvi2jmY~adhRyw1L}OV zWqz9#uI_PAS<{=Vanz5U;z6}M;z}4jV!smg-`&bD*Qk0;^w%1<$3=XN z61%{|RLQw2SD)<~9osIP_hWlIcovSswx@BKc5~u;7u;_)54gE~kNKTx*gTBp9JJ5e zT^`?s?UTV@)pp&4G_=3oTK>^9jGkfi4C{TvBlHaGeFLvT8vK<({;PdMq-t0>!AVHl zuvROo;T_ftBAvs^7}9A!5w{`D_7;)yVa+xEUH|jf3eUsOAtj?I8AXGAMvsVVKN0mj zN}u)??SQJF_ZJHF=`R!-ufIxYbaoHXxa=OH{_P&(JTxLZhA84mMr7Ym+gR)#%C9{8 zyM{*L?;6VRX|n3?nzp!h4^jX23Q-h$g(z?K2T}h%i=rs5Fi{kL2T>GPm}nmD6{59d ze-Mq%{vevQvy9O$p*9U?iEfurTlBL;AJ^;1y3w-=Sk%9>187x@)BiaA+c)%x5!pRN z8MAvhEZrxeRp+V|DYrj}dOJ@)=jq`*s?O7cUBZ6ts>0Ql2Y-c;LVJHmp}jxUv%Nnw z-ixfyi}ZYvd9(xQ^&ro(iL&kU4(k81{vpkm$%&moZE@8Aqlk6`(O51M*PfuZoLnZZ z-9T;GzKjNYf?ka@wAZ9sVr|h~x1;E;-qBpx8ARi~N_4w{+GgCIAR6^mMtzmIR~heB zB3>urb>_u2#;{@-wQCF%-8BZ%Wls=|^g1iqo}jk4*BS41;$CNs*$wo#@!AbUBURyz z)`J~Dlu7%2Xhin=(Cg)MqS*D*Hk+p&1BmkcIeE4Ns7}Hx-)ENX z{b?Jo9YCbV6%qPfpK(ymT_Yid_WqE<`zW*zs7;~IL@57i_K>#wB}58+vO@}84We<_D?|$I6{4B_n(Vn&)TYqBAyR0^5Y4G;NHnKv z5s}WX(P`h%-z~2lF_0d+he(NQPNc-{AyVS{6KVLCT-ig^rpM_Xl(%nDWmi#~Dtn7a zkMlk#Z*~|_-s~{;RXBDPwPj2-K3;^@+xMuo&!{bL_8E~{*T87Kxduks>@cE?eUCO* z#oFf7J|og*hY_jb=OR6J7*WO^vhp9I&N~hQt}uL_9C_A#EvA&$zwFwk<`}5V>H;8)Rql9k|-OG(eoHR z_9#6L1eZlsxzxp-qX;5oope z9D$VB*+i@5DN3HQPV673)-of{Ss~BK#&h)8@$|S=ZQm2k$aD1A_td7xjwjOKGYeAk z93?)#Xj9_E2h#H#C6j0{qpta^QhT6i7VLhaJlOq2aqWAe=S`Ac0W-?9wqb4!aREB(KC;pd6dkPlX;ZPqhuZ>^UTpadgjT`ykKSf!xGtqy#SY!qlnXg4u*+unJ`B62ER;EwBXr`S0L-|=mk59zf zvgC6yQevkS=~-k3?Ye54JNvEJRLPj%Myq!jZOdeDnb*rQ+LpgUdz)m>p074-n`pEDt4-l1 z+U);oTh;s%q|IJ1QniU5d%@Z=wuve#eO4cZaTu8X!A+(v^PVQu-@Ci*rrxJ{O} zQDS%4Pi4s-F;Zfu80oQJjIw0E7^$*fjIy-Ltl25n9)~is%PY$su{Le?h>bYNQpgPq`_`4(%_UI>i_SI(TP9pRjqfsFxc*M@T=O+x#Fjy zQwr#Job5o5*vIX6Vw`@^{-@~F!l=e-?*!Ele)b0oB&8`KuJqo?qG4Q&lnx}<+hckhG z$ES8|pZUacEssy(b2tfSq1<{WMkBRCsgpz5MVT~uY@^q*lZEv229bUaA<||i3uzlg z+bAy1zhLqc( z>~-5I)25#fiS*kkL;CHPA^n_5v;t3}|0McPqTk74kIOd466rswR|FabmlD^Zv7BTq zyh?3j;Z@2hE~@C{dVqljn&PwiRGEP@5`yf=Cq?6zOq>0x3C5Ci$Y;^qfTrcT`(G zd88<-oKjqbGI>_-Y$%5uQLB(D`-~`K6d-N(9FaCVk0@j6F_1#LkVxk^I>*sD&Ww+v zkhAKi^21HVE~ICiEZMv4Uk^N0ZPD#!qUiQCQFJ?-C_3L2W$8R?j0dZ2zMR@XSvpUa zxU$;QkSb?4P_CTdz*R`+dGf}y)t0yO%&8q!uU^XirR-nHPI+k4&(}rzxw}aJMf9sn z(Wd_*`Y)0_r$0PmmN~#Ehx}fo@FEJizS`T6Hs?OPn^0xP7Dcyji}I$v1!e3q5qZDb zGRFHw8RPw;jPZWa3U?j^>2WFqWsDn)W|kX_^2QDJ?naf03Y0NAP{#PfC}Z}Kk!FrD z`dyAOQhpW9&Xs7>>?{dd|GZ+P(7tp3uF4tK7KY- z-+<5gozHo$GbSFVkmro%j@yiM@|;mlILs(B9A-3k&X}ONbGihrD3xt!*2F;B<1?ci zI$eU4aG23r;w>X3yk(q*){@gDNXdPa@QtB`B`zDiodfi(+wrQ7k?%`Yqls>e*=#)W6drsDIus$}^`Ijnp|2 z`+_p;Y8AzGUlf#QCr3~QIKW5=2N-GK0Hg78fYEq4y+{M6x4&ZG+-mEYXN%VV_l%cw zt1Sxu7DeIKqLFfFvGr+0&V8U9e$UEx)oZ^~6n-p<#g9e(^J7u}{8%)Khx&&i@@7$1 zod-el#g#=X)_D*VT^%jTBqtU{=ft8peT)Wm6x!y+Sr62Mcxb)xOOaZ4qe7Z_r>F-G zDvHT9MeE#25TsW11yai|MX_WP<)0&pdgg_qJa9o#&(46Lo;jjuF1Vnm|L3f$Nmdch z)9F_Ib3V~nIG?EhNj(GgJV|epsO5HgWF1n=;p|Vz@;0?)b()^lifGG{^Brg`?nr=Q zIqQM+JLQ3*Op||i*Rd}yCtOW5cl=EBZpzO@QC<>-tEnvtR};l@;sa%m!-;bEQqfSH zm#krKr?xrbcA`XI%4)Yn~C!6KkGvE%G{DB-@K*dy&yC zlJiBPERyX-qAU_+k&!MEYmxCTlHo<-E|TFz#=fZdKA9LbPZH&sCy6rP3l z<^iHtpOYPE4e3;jBxg} z#pUUth)#2$dEw@vF>>%wuN*uSh3kPv$F)Ndw~6RXhql?_*P&53$AS9i%c1#oQe#xT z%Nyqn&q8y(OaHs{&xP}d)y0KFndHKuSi9tn^QJ9h&R?L_>*NI*g_95cXYYNY@Y6h^ zXTBNAlG7GwMx3)iBjTQ+C{9?QD9%%;5Yj(a2#ts*hNAGq&>T5cf#Pz;(1@I;K+z8w z9hXd7TxTfIyzst8^*<3gP-rDM8G)iZ8G+*R#Lyf$6M^Eo!ybyr4MS^#Cx%AN4MX$j zOayxUIun61;2Z?XHfIbeQW1xqt0Iom;SqP@zz^XdbQci!(L$f&dN;)HyXPMMQ)^Id zGxD*xYFrYJ@X%BhYje-~3S;*OImx{@oWXKO23bQsiaI)M_Zw*U15h*K6g9S!%C7!+ zYxo>aLw|Xk%tNmaZW}tM;w;8{9LbjeCZ)anH~vLhcz_C)_i93h7kohjPe0Lkd;*;WpfbvdTT9 zhFXppnt6^H(%iIi%(Q9dm?6y^Go+SRhSZ)$?P=7WMlIjWRz?i>}jz8Q+nD?<^vWGL2oV)4qfMLe%}V-!*CBFc=~MUaVMy&oW=$oeHii5#lpmFlC`&vs zq^;duT5Y5@h4#0QLXH{IqfQcKk7I_k@y(DPE*Z+0`=uZy?va9W#Ro&G+yNZT7dH&W z)jP@t*9%2gCy9Q}`$EyxOro{T0YiDXO028jv1CA1r1unY)kdPYPDY`z>la0L3Ij#w ziJ|DuQlaSAnHT<;w$~JA3}u5ehSriQN|YJ3lqf&$uY$6qmJ(%2MI}=1{wmn?|4iEq z-XvpmXqzv78q&{CL#vUi*1v~x)wKO4KkcOM!shqg!_a%H%s3x~e(GK>=yyIR8}8_$ zEe||5Y|k}nZW|iAs!lXgZW~&e+%`07ZW|gqpUpcvh5R%$3U_Wnv%q0PaXD-#I-d<` z;IknOYBG_&e0Q9mjz z-RnwLX+>k?q#@-zG^Ct|hE@x&4E3WbQoXx5;+3I(zC{&JOj{4CAJN!VKcWn9!_e5> z+Z>HueIpvL`bKBHtOuv*@G3NFo)}WDrV))@H6t2@b3G{f_e59Os4Y6j4CP8qBhsLz z5#^1ChV*>@t;foD-HcYnLsW6nw5j5rq3F&Ep|~6~6p>ekVsXq+EOm@0l{;B|Og zsUbu?JVzU^Oj|#^G8FB({-N3Dm?5?9mx2_k4@5ny62#Ncx^ll1ybP@Y6@y5*(^6=? zsSHFtPoh>$pthdf`vdi?4iNP=&D`dgcL$4H7e<-eJqPYAql)YJ^ zs{qs%T?HUoQL6sXtT`Qqdg7I#49xOM;gxAq!ZAa6=9nQpsya{xIAdtOcw%UzD*8~Y zdHUprX&cufBl5{p+gSKuXvR5Rs0Z#A(z!^k7U^vfZHuT{{O*&sWqMoYFUvCXvP{p* z=v*cn%jjGt$}&-wiL$Km=|QYzMMLYs9Zpa-mWidB&SwDg!rek+StYv4I&G`MDLFJ3 z>gdpntm-v^MyGZTMN~V7;;NuSGs62q8r0FDOmf5eyAyVa&J**{+E){O*HKm>nWs>)WGO3acMREUF6h$Q)>XXOOe{$o1Y3o_V8tR$%g?i?F zA^qymP;V;G`tw~J6Ky%+fT5nN3>7x-z7k_k|*Iz|g#?E< z^TAMb4j9U+3NaK>Js66}2W!bQejq$L=&J+R5Z-p&dDQLBr?JUtRb8LVrDYT(}O^ zle&uxx1!zGL|h|8E=7Mg5gPbi*zW&9iThh1oqR3yT)q~z$32&q#RoCEVSdM{L2WFtYLF5x z1=8d5H_D#RXGn?bM3gIk!B8yk?kJY`68u@Te$hJY=fBNli|kRJ6^hHPLV4g>p=|K1 zkOn>#nn(3rC@1Q>&?;5sg>>?-kV5BMaU0Uf%R>3#Vj;D>EHr~>S$%vhZOWTszLvJU zakr3u9v9Nj<3jpXg`rV!y3km-TS&ipFr?p^Sv0?#E|hbA7a9@23yq8G#rvb5$Az-3 zS_~=YbRo^0E~J^$g>) zs#JfW%<#LAHcl7H45tez7=MssuyYxL!yh*9*OBI9>f~z$svD^Tp{x zsyJOp6{ibnQyYf#@Vn58;&&k>YQT^Zt`}}Ys+bPcMnDx;Ao)?aI}yTUKU!MkBRy)#kRCo5%FLIjavoWm9^W&CZ$oV)!iz&1cyTDY9#KwsaVQ(S zI24y7hklnMhcq~4jAn`#hoW=jP-ZxCNC`&{y;_|wMsuW|4b6@-#VEQOHWb%6Vl-YZ z9E#{nF^a{DLs7VJXw+P|zOtNdZLv6VC>BQ!MR5mX)SDVM)Z1gS=k$v^bWrXrFzSc@ zhH~Y!FVg9pFUpM5zDO-E4ykp{*Hw|8?cDcQNY43cpNBMa>QI*4(-=kM(V@61*-+-4 z;YIrSZ>R^J8yYp|4fUX64QW=lhF*7EIHZ;rhjPn{!;?_|&g7yM#gRi1Rj;9l&g!DI z#G^yeRkES{PwO8V%QSj8c-nHvyF;pYcSw~}y+|7e59N?+hqUqTkhYil3xE`I@Q_YE z9?A?i4=Lp4Ar0I-q=cu3^f<|jlyLU!(VAJGLXigE9g3^w4UJue8yfp8{X3bfZ8rIJ zCWx!}bgD)}z47Z% zPPleRGw%*%z-MnX3p_fM?Pc=3O#l2kkBGvlL$Q|03BOKT&&y zkl*vULQYnRxJqVLiMvYNRU)pErB&jt5_gq|t3+I7bgPP~AH8zw(CBz{D0`ebG+s_! z|9OT-r!A9wIh0SeYG{tSjMOPtZMo&wp{#Q1P(*$mitA)6ipaa`?-1now2fUQ8(MGt zI<($YwIL;{+EC_scPK9J4vktR8|s^bhoZYLG19=n^ZCtcS1p9*-EX7WSM7#opR-;ffH zA5!9!C>py{qDYUs3Zo3TpDtR)XSk!a1KxFlM8^re9c0VDpc!SvPPh-69P=dzGC&YH=jCR)wqju&LjoQgm zY-gZlfH#N~atM*5$s0tYGowf|ZxCtb4Wg0q2C!Il?cj=zwk(>zieo}`~^Uoyi28rV!Vg62jUR}{#Sg?!q0w;#(dg8_p)qm@(JVVFibkpy z4vq9IW8@QR8y#;Djmy3D(74=Nk85dMd_pu9ejw7U<_+mo?S>Tc1Cgq6qB|?9Ezjdb z94D4L?|H=g2`3O`j~|F4@&i%E#6~NDD~R&O6+}wZ!XXV@K{Wd+;*b*cZ)nE(f!Kxe zz!gMmQY{=($QA5Q^YR0GC%4U?$~TWt#T7)__f7P{wk`SLrU!Mp^T}TLvhv1p|~7H6kVkpiq2O=8RIJ=J={g4fuo4BHJf^>Qfx{6@4+_>Cw7oJN!Z^>Qc!?th3f;4X+L1MY>0 zUVZn`>C~z=wS36_-H;EdO{e-gG+&%aq?sp)=7<}K)bb&bT0SJ2HI;QpEjJRaC7vWw z&XYvSxsgcoeKd0>y;IZd?uba66R$`ie-bI=Qld<{BO=nnheX-qKq3w9g@~f7%|p?- zktn)4Jv5tqNTh)SiK6o!QGPg(XioW%C`;~th%&>0M0z-oC_j8iq>T@WRB<5DJaQe; zOmP~K2B%-qyl@xMD&jGs=xY2>|J+3sMZF)2!dFCV!x+%0-Omt>o!^M!@*7bGIF0Ce zoJOQU)gKx)UlA$cE+ReLMWjTfADRnJBT}VD6rIP2VmTFyVyW~)^Uh;LaXF1Bx_cO+ z=NvcYvk(S3)S{X%h_%<1d0$e(nzVRSsn z{>tMi*>=*_BNw44{7DqW=~|RkE+rZ%e-cIEPok{yC(*ckw(PHOe9xM;SnflJ=GUoP zG@EJ&(OCGCD6Sep6kR1D8mapbqTF&X(MVMoA|?DxY zjq{1};QoY2p%c4E8|M=#nIs!d>}pfO1w~5SrO*|g=v+{gpJ_DkLbXNbg(3}nP85sJ ziSoebMA12%C@!B9#pP|fnmh{Mg&)E}NQuv}C~sBc87)HkB_!!JeIJEMS7eIMta=6 z5WRw&4n`WdtSDFWM0ZBmCjt542%y!nNH&}W)|P)>D;nt{{qtJ2Md7ugSR7Y0-bG?@ zU$u>QnTX3o^h}S4xXgIfOlli1KNe|FKZ%rZWzl%mOrp4)STsg{EQ+{FhF5uAtTOMb z%sVI6PsQTIqF8)aG~QLl%Y)T6KdVIK#A+M$DsfkdyGq9 zU7~jxX_x3-#@Ho#m*`#Mc8S|1A}3Z=hdgs)(Wp7G$jNc07|rQAan(#}8?|alG`T3zldh;p)yD(8!}<%Ca*a>AiS+BmdG6^9nhi0VqT>bO*BC2(cY%ID1@ zg&bO>&>3X35}ZLs+BVVV?tacsGh;(uukt)tG(xVC#>EQ_@4bDL$ z4Lo5qQ>s8wuGE4eB`QLZ5-u^)z$SjP!7TQ3g1`C=Zk&J$zuKM+GUGHFcy&AvYMUBB!U3Hs_|1D&Hc9l<KxyBjVZOy2zD9%K5RV zPfjd~%Y8*za_=0}C$AM{fa8kB!gobIb6iocYLQW9v``ejD~jbr9g65Y9JW(#?NpZN z&cvXZa~lxaNbO5_edwPH zihA|R!RDXong4-C#MMBV^a&4*#We+PLZh(uQ55SM#WHW$W~pV-e{(WXTuvs6%g;n{ zIhm-ch@XkZsJ;>9lf#Kt%Q&mW-SD(`Aw6mxksfy%MM}7uCkp`!C(M+jnL^-+2yr^T; zriUkqhw!f=PZFtek{9XWOd=(!9FZQLBvQhSL>l;zXm*_2MLALBh~`CQBU&fiNTiJ$ ziDrr$i4>}J^xB|@Cy7+uWR57%rjQ%i*9UXG``6OP{FF0kpTJ1Dj%X~-;i6IS7*Qs9 zjA%rhMl>$Etvbot#FbmeYvTavG6NP9vHZ9wXApOGFt{>xi_q_a=^_wj6R4kv5JZ z(x&basZ#fd^tf*x(xBE6X;9yYa>ZRlYk;GO@}plg?|en1fvojYy%&MwA&2B+3A% z5k*wBh{o%52wDJAW9C7?metb6QuQ{fP#pUye8R7DwxK1LYxauBJbk&b&MCu+93~MN!9y#;ckU&4mg^+=Z@H_;`2{ip8%( zQTTNz3XcwDl{<%`sAEL^`#up@Y4ke{i28K@Jv0jb8;ZhzL)qiJq50yrA^r2{cSk;L z+2gjMSbVnrZZC^O;j?)}6mA>Jl{@dD8Byhk=7r~mM!{!8tB%8lqVU$xi2NQJ3s(*4 z=cl3mRW_pjml=zb$lB&&S^v<8xN0cY@^>ujkhg~7a@EkdcxxzcyfrkgRU&fOv}JFV zvGCBetu(%wt7q%Vr(84&jv4B+OP_o*Z9R7xQI{<7$~;1Omn?PB-$j3yDBbTUMzKz; zb@C>s9x;k_W@nwa>qJ~9;yO88XN|2Bcb##qGp=>5T+cOM>uBJBX^X}CLL=gI;dN*w z^SIE6cw8t~d@a-`cMFY?e}(eql(C8mv*6x(sAu1ff%3+`LOt`WP|tiSGJL#|z7w{%qVby0Skxb)Eb*66T=j=2 zE|&>qOywbp$VbA~r(AK9+-u3`RL-F&P7tHfagb0HwS}mEP7#^~9uaz_@QBb@R1ac{ zVqSPeco~YKG7$Bz8W2U{1)&k~g3yRKLMS?42t`x}h(^c%K@r_C4~?DwgZ~uW*UafV z&In94{}QQ zJm|9>KgTz&>&flL z4rSxtGi}=KTpCsC?$C@lZG%*)tV2pv{-SwTJBPBNMh->e3!&&*D7s1_l#_p}V69&zv~iG7PWWU9UGRpE7jZT{PcMd|;ErP>X}QuBsl@rcmaIYManRh=7(<&-P7Sih>p^Fa|+ zEu-I1y@q0OdrXhmHnqB=BfBUOin=9lw>%h1?Wqv19*%c{}j(c0qzp;_hvA%$wV(Ok5Q^MAA{ zfsYXLt;sv2Bae+{l_&-P?&j;m%=YzD}L>mRxpPxF}ihj!HaYsVq;`X4Q zsv<-BxjjfTp9ifa-VRdE)j>MBH0ZUd1`PGdrRi6{d#q`jDK%gy3a%{|iQdIIH&SA(?iYLGTw4N}FcL8`bk zXtk>cL#ntmNC}q)Y2eSGS+fU*q8l^Hk5i~9y7Q;#=Uf^Toil?Xs{2A?SL=mcXw7hD zkOuw?Qt~ac&xg?#-3e0^mji=F?Sv`%Ep7~YKT!jQl=!Y&q{KN>q=ZX@qN@bskG~1! zL0@Rps=rX?c`_)&s=QFoPLHBKxh|+@HC<@!spdi%cK0?kF5U|om-;R=E_ZT6qfpa@ z^sDJYS>?%~tny?~Ty6|{mr%`xR+k-3G_yPz6rBTu;`%lOG)CV@i!^XxP~68vRMVv` zt}~}7E;j~^)ZK0HG!)&nKFTm>2Iba?RHT6qgQEK`T9j>W3{t|ALD}HRASIj`q=Y|% zG^hbX(e;I9LG>4!3*SPEl<;#?6+Z{{p(+fmF_mB_KO7#UhtGr7nET728R7gO zZLZgm9xf2-pTmPjJxLU&T(!mG`JmZX<%MFY^1>ET9=Jg6a3Q+7FBDz%7mCjRL8IpX zpt<1upi!#cuA`2-|i-pGSd@EAI3qmW0BZS7N=E_}2WKzu)nlHQiXuQ6o0gak3grcaz zLj9}4LZefKg<`3>LSuBFIuwy3g!=b;XzutzXhhs0lvUMMD4*ORlvSr+QAF+#8lCzp zG|OtPTx-gzGq5PS^L1#X&cmWHa*B|KRYuAw(iTzW6`B*3S12Oa2t`zRg~r<@F7HTN zT$NWSuIHfWUFNil2F{X4Xy7lQJgCJ&Iq#AUby?c-&uc=ex*9jq*400>!g)<-_Pb=p zeeLYXz71*PHKA;*qk-3?ZQj?(2CqrmT=17rT>cV@xUPR_4Xl%sb>eQa-Zsg}CfV3z zCHOtxf@bWSMBF6eCga^?yqiSaWYn9)-6ZZN5mi!ou95Pf&`3E^?j>z>YIo4uGfyZY z4+`bh{qE2x)I_0vR7Tmc_Ilw#p_x_hg8Ebwg;${*@}^MsxKgNpP83>8+$R)~kKSfvAibKvnnQ(AN5P9fA_UR{i|j2dCcg1;{#f;DtJ&V zt`v&p+$&n8Tq!gH4Dm4q^;9tq6|-wE~UEGp_*4H6n7 z_X$PeL7_1^k%~sZiBfH#2TqjxiGL_Mk?OAE+D@LjrbI?A})%&^<~yQRtoKeZ|FHs3waCh5Qv2N61&;k)hA4s*F&qLWB#_W?p0I8G?K zdxRhjs*=zwINgcja-vXlbxQcN$dy7GxKb!SR|@4^3n@{dgmTV(LQ0&IK;u;di`Jx? zN)(;rgyO1?Lvd9uq3GNv9EYN7p=|J)@Kfj$wyFW7hX;kSVOI*x1rG{ovxk5*@P?5R zt`s^;&ACKMxK>CB4+C#PaeWTMc2zF(u7FTnf3ZjK;Sx2(6( zi{AgcOv_w2Q;9TirH~R8N=T17C8U8{h2nCkdgrV4$d&SlG4iI+7@dnmv&@e|bFKOa z#o|GsC@PV#Me)AJeL^GUL7_bJppX(C6dJYnYovq+h2~xL5mLp2LK)yeAwBM;hQ@xC zoU1<4mUDGSNQ1MGC@v2Q#dQi2MRfiV??Q1oPADhNKcbwtyBeAWHApxK?HKc;&|L7N zP{#OCXldKg<=)MdL2YB? zO`*qBBB88usL&WyBB3#=K|-TbiG;?b1__Oee}%@S1_`&JaXH(FG>eB;9TyAf;bNhm zbFq*fE*8?jxk4FMWrXs~#X=fX7NO|;E0k3y7P-1I!?{BF5eezxTp>N2E2M{Wh4k>R zP=5GVXbrf>8dAl@LaNjqp)7Hg~r0;LSs>Pght`JK2bhtLa|gFp|S9|ka8y$ zQTEgtA?50eP(;d?yrFH4%#CIVcvd35`oN5$f5AKQu0$ z66&9)gnH&Iq0#Y|Tw$1fE)yD~iX#-4^ooADTPo z{?OXsJE5GbL_*qlQ1<6&aN-X|@lBv8)*@r)J86rkDhb6^m4xDQqRc7aP!#SH8XfluMNyCBUKqy0Swd@Ol^k-Gw2g?fgnCwk zg!**85B0`VLVfa%P;Z@)T%y0ee!}(9ymfM|6Rte`bb;;Wdx0#+k<*jL4rljPB5o6Fo7vnZ);3YLiLy<8wuz$3$g|{}^V8q&*newN zyGsu$h_vNd1reGxP7cbLIwI63KL_>6k3iYr*r1ihw?V7gUCYocaB@&Kd{ZZi#oIx# zoKQotcspp0xH|6C{5~9pW{S6il&CU78RO@mb;Zv?dYn^3dU!iXmAWIO$6d>i9-a?U z!t+5&oCL#hD7rIfD7uqqXlj)4gQaNRlg~6 zelAk=;yc?^{qTJ7rpWVg8idoM;t184aL3T6CjJjPE8z4Qy4K_Wpz9I$97BI&-E9oL zuRE27-gWpw=p?Q?kD*tOnkD2Zs#!wb8@~woEBqo;$S5K_XmLRvTkC_g@7qt)dT zB+}z^2GZlI87XmXh@yKhM{)aCxrpWjMWhS8e*1scfb(c5uJdRp8$2Qumq&!+a*9xN zRZJ)wydyM6>X%SXR59T$q|^PikXk+xTB}?mr1mO0n?8P#M=0bMq0I1zkOpVgP;{r& zP(-c~ilt@=MO3qdBJzt+X3PhQs6q)vqgn~+QLThjaek00&JWV2atUcuvxM|;ez2)B zo17n{kpF}7z~Mm}xH>30R|iGp=b(uE95i3gyO1_LeW)8p@^!aP?l6lq39eWlpj@6 zC^|O@<$;fcqWexvq=B1+lyH;WC(#@^zlI_@r-mZ(l+buNOK2`QOK80OB^385`R6ie zi_2?5aXC&XF2@OtU6mBlz;QxKI8I0p#|i1-IHAm|fI@3P9Taw<3~-!KbiNac&V9o3 z(2UC?iq3sP5uJlW5#9d^#Z@JR^5D+@D2hraG%htx{a;O|-n8}1gF^kNZbH5Bqfl14 zQfOShg%d^LP@&xNsj$U0E)`HHx(W<5Iz6Iw#i2sE0Y2ad^JgB5X8hBYK z8!D;L>^NbEvccm*(fL{^x~eLa4UQJdzq?wYHP6dJdQ?~;C44PcX_RocP&RxvM$wm< z5l)x3xGJpBsQFzeI;RV1;B=w5&flR?tFZE&Ok%03LZkLM9IXNMR4C`p-=Vl_t595S z7PMfxE^1!vzrfM5i+ft!T+b$Y* ziMvbOUHac;)Vs{-F8%M)|1SOS((^7o@3Ojf8T&5%@6!M7cmKxD%|kQ3Pek9EseKlj zecltAefOk7Bjxy^k#hXdc%2qRBjx*{k#hXdTyXr*TyXr59@Sjf^jPzJKeQe=erV0} z{g5hkTxb>!$v@vun<`!((xaLSY2fdnxcohz^u$uxg`)8Ka2(15O(-JY59LIy7kb4x zZ-}BhX^1p9X^3*d_d|L(ekdotj{vO%9w1W414JX{{<+_ZY`E_;(#8W+{m^(*ZQoC- z5`xdi14N#R|3;t8_?n)`?DvfvI>=pK`*ztFoce-FJP`Fpqv_o3O~@1e7Os=`o( z5q}R=NPH;8NC~g6zi&0KPg_Li7LjI-ANozcANr{?jHv%%p6m3Ywy~%dLnCr}5shnD zGlE9P4@A2hs>smjh8Z1iP}{gvk)f>e32_)w!XZRT_=HHa`Z4?%%K0b?Rgr1Cav#-d zK?+Av#WU2FbFQG%Q=)SPQN^4SjwmjN5M@}^BZ|uvL|NqoqHJ&iQCz1QQ8s+PH!eca zIfN(=zEc3{ajFqzfJ2Dl`u;sMQdMLqB8L!-kt>M$=MAFFa|lrs^<(JOrhbg`V(e(p6Alw0l}dNtX3M(f8uEgH2wI+R=PA5vlm1Ai6m zSD@(JKNOLVg3YmLu7C{tEQn8`QM-yqqjs%?=G0$xw4(f#!}iWCy7w)V2d{6G2df+D zF=N<9PgVcVT&NR6Iyrtwt+R?qr#t7P{9HvRCs3POcdtTOQa^^&as_c8${24@bsDw& zK%|W;h!py3gnrveMl@5rL8O8EhgPQAFci_rL==nrhw{MvLlL=uC?fX{{ZtJY`Y8{P z6Y3EjAkxGAL;2zUp;wACiD(|Ve@Gz@5b5Lrq7|jq3%hU~nq__<8ijjLp|QBvy%{nh zceY2G`GiOtZxHW7I{AbsZ+t>Dr+h-BoKJ}6mqUouas`oEcb!5CIfO`|vyDihIx(xq zYUC3lwZ07<<*=H@(x z5amIY7aBWn5cSLREjk>QiMG>eF4~Q8svJNGJEqUk=)w6GXl7$55aA zF{GI@hBDwD?^2`amg63!UP17{5B;fWzVs=SaMo*2^L zbRp6(j|MK8ww!RukRC1>o`iD3B|~e{NkgQEKZY{H8ABTQV`z5V2OedHKZZ2$$B+j1 zq(U0_V^^hBboVbtvE1DqjhEkrUQ=qikaE5jT0g3}(6hK$NE;Um^}we>nc-6*Rn7*w zYLN$(U8raEU1)`HqR?EZ??T$#T?)lg--V*^pwM`o^}`m$c->11_3slhQtr-Cs87BV z((gc7LkOn>yQnHPbZK89HJRj$M!(e#}Pu6lIpvVH^v1*8n{46gIX{2iS{@@JaQ8q|8B=qkHV-1CfGWtX;B zABP9ckrRI?56*cbZTufJYfcGs3aq03Brb*gACw=S56X{sHEsR}ohro8>iV}1RGV7WVn`>a2Wsc{BRB=bpdh?kW>G8=4WzV%0 zitY*mTXZ?`-fxuFn0GZ4*J}~2F7u3S-eji#M*~L)Wri<=l&Bm-uRC>OXx2DIXx3DV zA#KhNB5lqOx@VR=aE*{2t`SnjHFC<)Pq{|ur~D!(9*xWSK|Buqrus3ILw{dUJXK^U zdwe96L$zdRX8A}+KL-hof`f!+Sw$Hd3kL~}h<7AM6xvln8RG?^=)52lofm}ircMk+ zS1pF3bA(WIrv*`5z7X!h7FRxbK`0N-45Cb`Ye(5=^T!d=rjR3qGQjyk8aO{FF8>F` zQaNS?h{Xj$5qUuQl&Bv=dQ_32xll!hv^n!=KZ7>@7}Dmn zBT{9@9mVB|q5P{BL(w^7C?}jTlo`$#(xY+=yO0tmAF*jLJG?TafmepIPQ-OxG@!60t&=}p( z%k`x(u9I!PpSJO?6IV@|_C+Y$6r-^_0gCjfNkd9FgeddtWPn4cE%PeVkT#WRXcp9` zA)Q=AloRJhT>)DUYSoZJwQ4vHWrm}OR5>?_R5>?_RH3#khX1d$aU1FjoXFtriKkEQXCDpwXy9#nT*mx1$`ywb<%+|JwC$4a)&y`1?em$2vhn~xwL(k>Wq381G&~s(q zXJ*gkq@m|>($I4`Y3RB9H1u5WJ3eW9F24&s*LU}!=kmVLb5%5==bCSy&plTS5_&Gr z3O(07snB!zSLnG`$xXF9SGCMdt;<=_wE-@Q{*vDO@#Bxbi@a;xgg=YF;#mL6eEnUs ze^bBrwcG)ow)+h=eyp|`L8o2K2>K>NGlK1Y+3o&B?R*;F#f)$qJlBk%=b91pTr+~6 zYeuj+6rN=+(6h`1dX~9B&oT=tVEm?Rqo2yKdztIUeLp_d>i=A{&T&@!r~aQ0@-^(j zb}wd-xDOhEL%noQA%E{7sDr=iwr3de&)g!fm(@55>2YH#`k#cv~Yy(cjiP42u4? z#)zW7t*oF}Z)@DB|F^Y*ZtI)WuR{GC)qC=7z3Yi$uK~q6uDL_~94Bvf2X3?Ka8PZo zK6;$1kL_`pv>I_7o`?P>c>YYhFAXO8;u-LU8puixAHJ&*8^Z%dy?)ZpFL z|2*!sc3c0b>i_+$mf9+me|NP)W9M0+%y5&?*m+9mH=Q~}ndA}O)^j}0=Rx_m8d08A z89nZL__ju_?MfAm)T<1|YOgF;hT4A> z?f>596^)){clEaZs+l`i0_gYmQRT1pZN>JuztKqTk7Vyhtz2z$^dl?kM>6@NGUpMR zf7JUWTH)S9P*z{loA=M#ynmute`maZ*H78sc7Y+ws+mTS}`9& zk6X{E2k)PEH7g$R4v8MIl2I)0hbW4_K6q91w+21SUm5f}{<5Ix_8{)+z1ZX4BkyYE zeJ)zJI4@eO_$_=YTAz1Wd$_8$daApuy1Sa8mug#S=%>~X>dj~EyJ|IVs_j!G`c10^ z<w>}Fs2R{U-a#}BGTuRy z4AYwv2fkO;{sXY5 zVa7iEnqg1YhBd8 za|CE~_ODU@cCJxA?O&rPP7|QHvww~HcMaBme~GIvZTU1d6w7xWp%K}kMrxfJKr7SP z0i@qPHCiF=G=d_!ibD~-N1<`Kaz+vDM5EPWCmLnX9yA)4-DfnSvnX-D5p7EBM59@A zngEU3nF96D#~~%I&rxJo<0!hFXf$4D3Q&gaN25Hu>nzeUPEOp7MB6HI;sE8u9cWQb z+>Hb&acz(C;CdcqUPh1-cN#&_oi9KU?LngqxVs3-fSqU*(eAU|JL7ex0L8MujON-^ z4T|g2K8kLa8Rfx!MNo9R$!LsrlTlo|$tbRUWc!8Y-TiD(6nn%divLDY>CKl&Jed zdQ`?CC91KI9<@v8ommYIjzUW85hFc5&m$#v*pLQ0MJOBgI#A|$?MMkv6lH^NfimEF z8TI2@59x2$P~NkRUUX})WdbSb|Iy>Fut=4CUeud?UNlGcd671!29QE~z9_DpU!>N~ zFUp>sU-as*^NTX+>;M{({a-Y$`>f&n`pckgW}PEI`LsujM&wKZTE%va(VTNkP>=SJ z(HQL`qtV$%Mx%440FBO`G8&!TWHc^&%4l46lhG*bBcoA#$(nSsK$~*c|46faWTeX8 zG5Rm336LtM36Lsh3Xm%ICqb&*r37hnJ%&{I9D(v|#~EpJ?f~WXOV+CUmYDCO@Lfpr z*Sh9JnYTlY^!tu%GzzB`Q0Cp?1ZCdNHOjoJf4mEg*IqUnuX7D()ONAaNbOmp5!tgw z>&Koo8kgN_G$Omz=+*bNuE+78qMd7`-<~y6>!btH*;cu$R&A>6T%(`Zvqsu{=0dYz z{~FDLPhm){d!C?Ku#1f}+r>t+V9y%Of}LxxF*@yBqs)I#=Ivr@k3!1rUnBkBb2Zpr zpUy;hgnlO@kbXPbXcTs|(J1U|BmM4_f=1ypBN~OPcckCB3EYHoZjT#{;(L86@*ZLR z*y%>2u-}dJKVlIm zJX3@8+u29@?e8Py_VkfXd-_PByS^ZW?)`$ax%UfFWyc?7(vCmUHc3A1{%cbuBPgFv ztROx1{gEE`fkCP`Drf{M0gz7h07$2*0Hjt`08;A?#wedoxFF5y1d!%Q-uI??Cz+O; z;ji*h_%5_6rg>FP^H+76cNldA9ycx(1!%R{Tf&>rdpNCVyy^fJUd%0L{oW@0Qc@VYI!^PxC(il2Q9UcUK|Ct1p>$`!+_>g4Fejf?+8P4>ZA`EwR#3LYVI)_yLtvR zcJ&Ns)an_~cvUr^@xJ7J^(CWz$*5-;=`1rl%Shcn$5odxs(e7BQ}ckvMF$#-$_F$e z^$%!7&I+MXI4gvn$CE+IofSgLRYV~DsvwYZCx*}*@dI58Qm8rtPeMA?MIfDWgmSJf z0_jv2fpn^iK$%w;fikZy0%cxx1X8X#0_j&Bf%L16K>AfjpjGFz5gLorMrbUHQ*Ds*JA2Lo3>@NxpTEPZE7cwHnkH-n+gh)a}^XQ=jtes zPSq4Bf^StrYE@Ps&F%t(G&>=MG_U@jrn^y2y6_b{S$A0YYCSR$|HeaO5~E zz!I3Kco3KJ?76?wR&DLSCbB(!?(GJ_J$-wU?Nze9$_ig4=c}x6yD$75IoC^tB3k90 zYE_PoYneAH%DKuRib%f|ipZ`E6pOtXC>G}hp;+wGK(W}Tfnu>+1I1#`2AT!^Stueq zH_)e}RbIubye?LGU99rnwNAY2ymze=uih@-l*ZvCoQAVd2JHR7WhhcTUnpMHQ53b^ zASh~kLQvG}MC}=Hu0`$KZxpq?A}DI76`^?T8$t2v6ho1&6XQB@c`BUmcwIOO#j?o^ z+FRmUMD~`T+0{LOqa7oaZy5vw4cCDaT>{>xHVy6ny@8l(<+`a*% z+?+a<qc}J@=X4ecrwI zKmAkxinEF0b;|vRM2jLiB%(v^d`K*ZWcZN#A9DXg?s*Pk(A}JQg%loDu8>aN z6H>x~Lcbq4Q0P_eS&Gh5F^;`eNQqrlNQs?PD0^OANR=liqP%gVke+F>H?0|TEqgpE zq-q*f)2QN4`3WV{WO5ok94j?hs`yqo3+2b|ETn{Eg~sAcp|PBVk1{YzyiUSb;dN(w zf!?aU+$h)XGfym@hv?cpooa=0tAi5VnOB8!J5N@*RIaTDUX?oXAe@9^;i{up_*Tdp zvDXMid>D0XfXidq*WigA%U zbDdnbJ6kz=BvGWiCslG;<@=)u`2Hv^JIc`NL>X3vLK#-`KympNj^gtD55?u% z1B%OML)?aP?zg(}MdV!{MdaNPMdbYhMPvnGTM=yrS_FQ|?Lsrc^Fs5&^Fk5vyii2k zE))yT3&q0oLb2$hM6p~Y7CYQrn}+W^r^==T{sR!!52fb zqjM9*#TP>nal}wW95FOIJ`1AkaKTVScKV@t;f0~NbabLv_+ls)z8H#yJBDV2JBA|S zk)gOaWhgp*owyHu9^;f@7mAl_hT`(<02H0BPZS*o4Mo(}76;9>_&8`NE@Hw{I>O+!)e)KC;WHKbqnDALba^ZKNmcZSsR%aB^9 zt00}eOQ03SHA6bNX6R4&Wk@H#3}v2QhBD7DLz=l}NG;b4spXm>wOli7YGs>ihBSLx z0m?S-4C&{cA^p5Fq@Qbslyl8co}G$@^y^DS%6VrO+!&| z(@+#VH53I;4e95pp?6e18q(?63U50tjOUs*4jR(KHA6}`Wk?C93~Atzq0xC{Xmsuv z8eK0f%9~zVls8?pcoxc-ssYl&?Lw-!T_{)FE|e>77gEUWLJE0aC^H-`q>aOc6mqyw zX82ZUe)ZKNg}f@HP`vE}IR(=X@xb5RuhCKQD(U8LXHcX%F(Lj4Fu!EZwP`AsP2{3a9yzX?UbbwW|_ zo=_BAC#0YEgrd;Bi?sg&tlM3x5hlq5g%U;7_4g_){nr z{uENqjY7(~QAjyA3f+khg_QH5kbWoip(wafD2i2-dn&7ID~I=llTIZT( z&#FLbc~3|!*9qmE_k@)5o{)0h6Vl9SLTWipNFjF#y>G1Z$&GX5TF%$eypGy+)an}c zb86SgvrbXhG|LOhGv^3t<{Y8b!Z||9`A0}O{|G7PAEBIcj*xOb5z@^4L0RPiA#Hpg zq=d7BlyG*C63!0Npqm(t&e=hub9PYnI6LUBJROunZVpn#)A1cf_V_qRAvXujI5!7n z?`w2^O%7GY{e)&d4${oWL7MqED0_Syls!HU($B|1`uR9Wzm8*+Np21rjhln?>o`W5 zbsQt*d>oWpJ`Q?)adVJzcR};c%|ZIPIY>V@2Px;{Amw}~0+k&#nb3yv`I3wkp7u2`L`9S(PFGxTC1!?BFAmuz4v^IDy zC<;Cc%J423)*tO!6xR2F1mxL2>bGuIgL2 zm7~|}DsBs^WpR~|wnH*}h!Wn4pBSCPg2v^uAP-qz5{|=V_!7PrhxyZCW%9aKhQHbU z^mFLBzB-lA6Ki!Oq3`isjf;LKbT!s>{Y%|Ex{%a#^ccOXc|mv3AE2l|iDK0!}EK|9Mh zJ}5fpWTJ?8Jx-z@g!JgeMoM@+Xmt9}Se}54qT}hH&#-(PG?w!-(O7&O^*AemkAp_x z=Ae7)LPAmNLPGKCxJTJ;eXU#`*EBd$6V0Z+Bor^N2kDtbk0+bBwpQm+qTA86ak)Qe zz0K<#39TP9fmRMb2#vxCLSylRPzE?bC63kfOV=AcMJ%4Uk2&t%bJD$=johxDrnA^oZvNWX8`NWbrYNWbqfNWV|nNWag9NV(4lDD!^Lpv-$0 zL=ky!Kv7szC>GIUi^G*?D5F?7GAI_l42p#>gH{no2F1dWL9uXTP%L_vP%L~I6ouX; z6a_~H>DPaR6!KP(LcK*u6;}nR;;JB3AEU}?nXYN$upm{u6{L!{f>iNVP=ej zDdeZ%FzmunNcl~E*WA=64%edaOcpc?d=`}doBZx`nt*F@wOn&pT>CE$3yP7$f@0*b zpv-evP>dWFlz$Ejij>2GBIU547fx}s_Fo(p6cL97MWlBLMWlBLMZ|4E5%F12EPNIe3!eo=p?Ar8rJ37; zH0x19v%q;lQE*;R6#N$y1^)#_K{1Mg|AKzTe?d|3Ur-eM7Ze5m1x4ZcGH717Fenx- z42p#dgXV<`gCg?GXcQ3_21Ue$K~d;kLQ!yGP!#+Zq@4eP^z&bkejQ9mKNkk+=fxoX zI+&1tjttVzkwLE@z6^?jFN00L&*A!*P!!G)MYEur390ox4dt9igOu}Vka8XkQp=Y? zYWXrqCr1Y9rC5-b3DD^e*{1g*+Fe&HhNFjpu^2abA!@{tHsb zg+V#w#UO=T7^ILFgL0@}3FVL@gJ$+~zJc;$T$^8x4ARMwL25ZNNT*SeLeIrU3b`;y zp{HY`zsr9?+VmVDZF-K7HjWI^#*smp)NSN<6@|PQq|mvhcp92zeM3kaF9s>(#UO3^ zgOE0k4ARDnLE3mRNSkM5BW)ZRq>UqkyO6>!`NqVNaV>is8Kjf*g0iQAfOPU-kWMZP z$|M&CsnrLBGRccU|C$$rlWRPZ#3@$?Yxie@D zaA!~~>L4fRd=I{{^Y#zaX{xgOFzZK}a)425IKVAmzLmq?sdw^30Jz zYn~&6vdxh}5$O-YVJISw42psmgOu}PkbWZ}{TvyjpCg0x^JS27UJTN#0|;r>0faR3 zWsq9EKiCvn54;$Zd0q_4EzbpMQ#VA~^z0y2JQt*j=Yq1zZ9&?&ElAtCMn-qir-L%7 zPX}pp$}7sG4jq(3eL6S_Y2M`1scs$D^z&#?o^|CQ{YFChLKpmPg}y5n2P>8KhH97OCaVAhp~Xq?03q zbaG^nT8<3LGcN|I<;5VKo@S2J@?ucNI4?-gQ)Zw4;#v;*FG!oaAZ?r%q>b}}G;mnZ z=)4v5?|3WNMwcb73d#=;1u4-lgVrHe1u5aGASLdFRwF+JDdDG}T=7#-#`MdejOmv_ zYPl*%Ek6aR<)olF)feM?9ku)vlsEk^NG(?d>Ex#%o$i8ka#D~^P6|@EjY8cnu4&_^ zpiJ^pkWSq$XijyzAhjG8G#ZD+?m%j}D%gi+oU4LXAXfz`=c=G@a6AB{oQHyx>tR94 z`6(#3JQSo^#|qNSH$mF?CfKyeC&$G1WIFjKD7SnQq?2QU^2w7xs(2zu8)pP%(lfJ= z9=$3^6*mN_;)bA1azjuixgkg`Hw3BWhFsU{c@Pf6E~Iv!Z@#KUuBqB5GrCt?8%6gD zx|_b0>vXKxwJ9#{5xRqp6%?1g6_j%h3yOueg6_;)xvo5p!g2lU|J1vs(^5vEpExfS zUy2+S^z&hU;zT&-s`ytt7vxKDThKXP&V@tW16|DsdInKfD5SW$t6?qny8k;u=-&70Uf65pjG}Ug+ob zApIO4q@VADG;@5Aa=s5z?k-5VQ|XX$?hjJV{Xv>}K8Q?kMLrLQ2<3r8gz~@} zLfLTQGs=VhAQZb3>d>s|5<(f^6QMll7(#i_F@#j{kB}-ILntS_B$Sh*dsPhvq_;5Q<%|5E^TivGfYL7U?YGI^)i@(RB}@ah;ZlMs&h3nhQTg(an>8Zjoza z@r+QOc}6J1`i9Ub&bULPaE{O#;2fb5ofM5?=oP~Q;Jz(qnD zxJXC?7YXIoiFRm2&Jl`~bA(3szK=%dA0Z8Ti_qxKvO^irTZBf}PlRS!R}s>1lGhpM z$Tba4t42zANk{`P35}?$2+gt{A~Yf|2}SBGJ2ciw#yU;BdWh_>7quQDlygoK8qv9S zXhc6n@t$UM{Y0+4;`mJ{+q#NSjGQJEBc}=pI6GI{^>np96)m!Fxigcu#0X&XW^; zL#}D#Mj>syC!~b;gfwuSkOt@7Aq~7Iv=VqvND0>ojjlfk&4tb&G_L2XpmB8xp`7Rs zLYd)1Ate{d2{+0q=JL?a_I6^klgNhQBs7owDWuk!(CA+|0U9aSYmGAIggvC$>BvZ@ z)Ao=;=NTh~JTLSc))~NPTqpaYah=+W#&z;88rR9Y=qz%*PP`3K=y*ce{*d3=&R%sb z^SYnVo%v|!&U`d{iuk*do3gNP$b)x$T%@>yq<$=qFvcY9T zIpMOQoN(FD+;Q2^s^+qx8PtW0e%tDYLNV%uLecTvP+WXB6c_gm#ld|;ak)Zqao^y_Rw`nhi?^V~NS1@{d_!F@wfaNkh=odIaaX1H}IGu%3q8EzfQ37-z-L?;x=3AYaAgj<$-^P z@}OG^WkAmq$^b79#m>t^@$&Leydp&La`aHV96huWIC>~*jvk7amxtojIfbI;=%J{c zMu?);Ifdfo>!EKhw~6;Q@pAgCMbUBk&@6NMP;@*#6c=|7#l_u2aq;y~MBF_T5qA$o z#N9&?araPM+&vT#M-N58%R^D{@=z4KJfxYIhi1f?glH}}dT2(tcu1{k0-6Pm9@5Oq zLuz?>NG&f9spaJ%wY)r}nU{x@^YV~>ULMk~y9(*&;-PFijS%J8GXYVabzLFl96h9* zKBSzZhqBGlLw~O83MuF7A?18Mq?V(H)N=HYT8*%DL_; zlye>*Qm$5llymx!avmT06Xz46+;a4gHjW<3AurFnBn|vKq=A2jGQ>EYR- z8RXfaoN()qHl0&QA-4`?hEIpIap)Vo ztq{H*%0FKZ>38BEih{3)=7PJ2%TQcAJ`@*aC@vl!ii^jG=7qb5;^OY1xcGV~7LFc@ zg`gj56uPF4{7G~AD&8uj3?w@O#d3;E-@z84F z?jg1Mt&nE@R!BLI4=LyLA?2Jtq+IV6(#+{Yn)!V`n-0P*9EI}l1V8LUbFofDda_)L zh$o0*ahf0c^vEAX5mA65;t!&@_=6}q{ve8rGl(MM529H3gJ>4`gD4{YAc|<6_n%EF zsGbGsGdKNuwQwHN@4P-VBl@<`D$E|Az{OjaG`niWlzfLZspNEL_>*_+QOIH`t%vD6nd5cInZxQ96tBCZwFH+7`M9R5} zNV$G4q}o5{T1E))eX5-I0J;(16p7ZNFV zFQl9ciIj68(aPaMBK=%Qq@N3k^y~9N`ZEuNsg}g|lkQa$E%!@=id67sbFB0i={+{o>gK!vjVINYf z=L=>%?oD} z>E~=B{X9*ipQnlR^EA;oJWZU0?#!J;_xFsdkM+IOx;o@j>*2>W&HTz%zd&mFl_=YX zXy#hFru>l1JB80R<$O$}T&EaP&eKH74^e)I@MfFsF8^yx+M6qx`k#fE#(#i2ezkhh0XcbR#w@Gqko%x9v zooA??MH|QSZI`*ZbZvCLCmPW?hbV8{Pn0+AC(^+EL`wQ7(Isc+y4mD`q8Zc^hvL-@ zhi20*1f;>=Mx%2)(cI~YL!)y%kp_+@Qo`{>N_d?pCpzX-?%bQdiRQxTh)5NG6KQig zB2s1MP)?kVh?MA_Lt{-dmcBXH-s5%8sS+ARmmHpjM&W6qJL`r+k?Mm(cjjrL=yb!O zS>|b~Jc`9rQ_(1T;!rGnOccvJQTQ9Ktt;JdD64wn(71Zya1|Pnvxze48D1zZCnBQU zI0X@nz~4kGoU@7I?}J|>!Lrz4^jrDG0_ z&dpS<_L|izheqdGq7nI(Xe_@?QO03A4E#Hgh&aO5ao?0h-QZ;h-Sy9 z6O>7wAj%|95UJI9hw{l8M9MjXXf`>6XihnUxDG|c8ARFU45H|Gg4`5Yy-HTE>i4i~ ztNJRRK%Cd>T8vym6c>LG#l;guaq$FET>cxyr6Ui;#Ti6#IY$b`r7sV~#VbT{aSTyh z977Zl#}GxtF+}sF`ybohG|}nKL-WNqM6qxW(R}H(MRD;EQFJ^+6b&a4Mdu1d$4Nxd zaS~B=zg7=4_ z;QgT);rAis{63_U--mQ^`jA3SA5usMQpo8;3ORj9A*T;%9L^+O8v z?xCFX`@Cl8Z;14J${4;6#lkm4QP797%{N3*@C}i2z9G`D z*AFSz>xcC75YbBDAtL>H{m`c-&lf|lLFX}|cWga?DF6IK6b1JXW!}zsq?sn9+4I7X zX1*c%bG{+c%r`{J`G!b2-wE+P7NTtcLoONcac36a{zyec2_s(j3P&%`lX0&kI8<#8bm?6853F z;40!QG$R~F^jh%jF#J6f9d8lMj#?^;RR17~RR18FDLx~Ln$L)$<};$$`HbjJ97Ys1 zpAkjPXGAN?d5`El%5%if>ta<;rAO~kTu77+r$M4@=tD%=SSK4CN!PN$kwn?xOX5jr z#`%(H#<`OyKio-_86G9d311RrgD;7);jBoM4elh$19uXw0Ujl~6OR&QgFA`xpnDOm zTTdKA*;r?7c>0)Y+1TW}hCWBva-z=><%F||a1|?};LErX`At2Z|!%fuj8D#Khl1k#a)O zT=1Dty!=oUFFzE;%MV5I@1 z^a}F)G8C^aP86g5O%xrU6qlh_jb2U^qn4D;9m7C?ZcNL$UBrQ4~B=6bsK3#lj~=vG7SzEb@rvi(85! z(&LFD;+&$H;+dkj^n0TD;-8}EoS%uJPY22e_yxB7LA}cASlgV&Rq| z{oGQd-@TB2CuAc1JX55ZTZ(jYNRdK5Dat>e6zSxXqI>g6?MrSHJ8u-dtG{HWy<~P? zvc_IAcZXzNkEc2X%{F1WB z*Ttd!XBRd7oKv)x_^0@HsTln9zi=3i!#-SwzlFbts;YyE2-WI%#;Ce6sQ;rn#GqyY zeODe-bm-g0pyEQGZ3h(>`kXSTxX|ySLB)brB@Y+B7dg2|o1FycZX8%NIu{k)P2Z@! zIOyk zt=}K+@3c?5*p1R>6#brW``Y_tQiOhDT)m$tlYKJD33V->oKU2suN98+$q&Ug7A1X@ z^vSCJQ1vqL@kUW*oFIxaqcap~=8z(t98xsn{v}e#Ek$#!GZZQ0lcFqfNRc)UDf+$5 zCq+7SgQAR0Yld+W8jW*`$KfKRmUD`-I<5aB4NewCBl1Sk{dIt%6`}(a-C5Tsx|_2@ zQSAECQSAO6irUlSP^7v+(TKA|$0v1d4e0koQOs*(bSKU!iiLBEGCz-oc_MPAsGrba zmkG+he~H!!M-}POC5kevClqCve~R?*PmvzZDH@$;iZW?03mQwt(OCLG(Twv<(Yzlg z1DsRWX51;GC?{N0q(pxxHYMibICHVcTrZLz9iuurWX8FpXkNIhC@205sp6s{Ra{gw zBIgw4!TF+S^pko`pt*3eD9VHWP&A_cP&6)I6=g=3D4G$we2@}nkRlCSSCpBP=;6S+ zwoaT)it@vaMG85vPNOqBo<@h}NIxl3sFM`U7dI9u zie}AOrbv&oOi`|Mn4;IqS+qIJ)HPLHTBM3si}dI!MH>7RY2e$U{BUnkPIQ%`(Yd#1 zzPPuz4R;|uXVG&WJvvNv`^b-TO_3^3rbBwTx=59sSV$FD7p)&1rYJu;Oi_Mxm?DMT zUX&kwrbyL!^jt)bZc}|nvUHIwae-Y^=vj40p)OQ3OS({z&Wq^e4!iam^i!mkJB-wF zhml%+sYtE9RHXSLnsukTmRqhd($6nOS-nUUzvP~L;oJHINja~Uk78x&?nKdXY|-E0 z)uOoca-tk_Y|+Z(*rHkB*rMqC8H$c$i=yM$qUdB3Ov2bZoEL>U?1!opT!I?!- z@MMvG&McZE&Mb<8GmGYn8;hdg!=flSut+}#7U}21BK>?=q@NFq^!sn5pAU=l^I_3? ze~OfINRduES&%}z8<0XiDbnTBKT^m^ zLppgrD8uUdNTGTyQmD#^bgCpFohlYcr*FeZr|&Vw8H8Op3T0bQCHA4r`%Hu~?~?)^ zhvM>%i`I|#18lEaF`7wixo`3LZ|*9Jk-Lgw-btjKmx?qutz1;sbaGLVS}rP5%SAMeJ|Ix4&%-sd@$C?ZZJib#D5MZ~E@ z5pgO}M4U<#3wIL5!lOj7@F-C%dLB_M{7MvyK1ZaSUy0^|Yl&t-ha*zX$3)6Gm`F1P zNG%5wtthS~(#f?%f0t{C)bcBlPJSiQslyRvTUR4esH+hv)Z2*ithW(mn_r1^>TN_B z=31f*Q-HF{wM4n)S|a5-9FcO~CDP2bM9R6ANV(odlv`bme%Hz{UlK*Zi$qayA(2jQ zBT}d?i4<}hQC7K)NG+cc>EtsaoqR_0ulbBfA%_tu^HA>}$5k#g=H zQm%&)Dd+JaxkIt=?2vxli%37u4(aFFAk zY)CCn4e8{*pjE+BL&~{nNGI-wd7ns~gX;R9A|DM! zr@PRpH?qeaYbW5K{P4d}mN;Day~xSJ|AwP*Tsih!Ib4P>;cIbNKf_Vz@8|)%D{sh8 zI7jHUtG5on7o9bV92owQ9lBf~&yqt`Or8;{#&L_#cP~B>`mD+)LZ6J@RVLAUvtBv$ zI^z(bmBJ^ws|vUp*ra9z{r=G_hxBlc@N?+?`rUljrI4G0dc}A;sP45<58`9%EPo!rWJv?C7 z^oRuMnMTjFR;gV`v~?DWJTRXXFGqa+);;cyXBq7M#@?p1{DruPlS$jw2q zIK9*JSKN(vgU6xh^t+*mI5j91?;|Ldd1B$$xHgu4H#7=&294zmPn8QZ%c(*4(Bp=p z;M$;AJP8hs!ks~*II$DuibsQT#g{=b>T5%};>#cn&hT{d6b(-AMB_Tc6VF5A>UTr2 z>vuyL@cxeU@MVw^eQjuTjtm;txt(ZS&wWEt^JVZP6g77Sjn0=r<8owB=D9Fv&2VAR z%<^2&xF;Ex+v0RBBkFxaBXV2Nh(;-sKa_$es2I^EES`rS~By57*Z z{1h}gR|Un$PeCzqRnX{XiP1a0YZ>OJASKS~MC*!^f=1`0pgik_LnG>ULo>)FL8I7* zfkxqypt1D9p%uj$!N*Y4o&<-+bq*)C5k<`(LGf}%&@6L9P`3FXNEJ5(>G4yfgad-+ zmji-g=YXILa6phY4hYi52SKyL2SGY7k{{2ByQ}UIKX*#!U43$*>V5qWWrHW;{55~7 zTMexl4hWhxt_R90*8@et^+5OWH&8@e50qPdYA7y#2a1K?fnwozpjh}FC<=ZD%DLV& zwN5$bcc9GcK|?v`aUd;x4WyQ@fpq#Q(#g?4I(3|(%=0ynTD}HStK$sm>ybPq! zGft5zE(XdZF9Xdy=K^WrTp)#<3#8LekxtG9(#g3%I`xhro%{==lYfD-%D+Hr`4=d+ zoD01-qi`Hj&a*(u^@1V&dcn|o;9Ma6oC~C%bAgm|E|7BlUr0Is0_o>pApQIcq@Rm{ zl=Cl;a{dL%Ip;#Xdk_x8E)(?$VbUKB7B`6lV0MIL%uYn@s zsv-US6Qo?V8!1=iMatDRk!F=Dq*j#zsrCIB&4ur6NVD%BNVCt;#+ih4`s9LidZ$4d z_FBQVQd(Y{Mn84ZBhtygKsxysD8rl!lv~aPQmg+9>Eu};g**$S@IGsXTj6>Z$|uhP ztqt8?cpl0s=K?9`Tp<0N3v_p$1yatlK+1U*D8oDpq?~7gl=Cc5o_Q81&pZpHT;~^3 z&Zoe6NIA~}tp{!eQqHqL$~hNEIp+dpzU7*K;o5(3F_3;<28x20fuhh6hN9qWpeXnn zC<=XHXcqK^p;-Q?Zz?zn#l`PHQ8@b%%>wTO#lrhQvFH~=v2Z|8EN#VbLtN9$0YREM zAV{r#F{G9cg48-65~<~epjRJH1dl>Goezn$aYm3fJz_|kosmeJY$9zs#gJaU3Cc6~ z1ZmbUhBEAlZ%82z1?l9WAf0-|kV5@mNE?>~Y2%e3Z5$J%ierLQaZHdZU0_HR#{}h2 z7Z}PU#{}h&Z-P{DOwjun-vnvno}ksM+Y9BBhk~-oNkN)9DM+*3r6`{?A?5nNkaFG% zQqEgJ`Q)u2{k#>VpSOad;H{u2cq=H+Tot~l3_Cp%#llrVv2ayTEc_I-hPf)Z48_G; zL2>a`P+Y18C@$U#ipw+OP+S}q6c>jD#l>Mk5ph^hM7$Lg3vUI@4sQj`&X=rk-ir6u zJ`^2q1;xc%L9@e8K~eBiP!wt|NIxe9>DTjxl^4T@az;?z^md_f`6Fmt&IrmFe*}%rA3=H3&xJJbN00{22+9vP1m%Yt zg7U)+LE5+>C`+P6S>lW!wVV-@C7uXU%M(HWjwgcD@PfiE=7n}~1PfiEY&*Q+RT%AoH6UwSS zCOiqL)yIS~%Y4g-Jq>X=pwDB*{JvbM3kkG)VKr_pgKw08M zAPstskOuz}jn0Wc`QbsJ(YX(3biMbJQo>C@ zdfW@;gr|U1aTZW!_zNgMoCTBD1kWa>#2ynsxV}5jYM=v%Vgre3wuDdb1JcZKKx+98XvR4XNG-1c>Etz_yXw|KpWiqRD8qaQlxN*K zXgxUX5M`SOf%NkrkbWKn($6_S`Z*CuKPLj|*TsW!?#x4^pDTf);7y>Mb0|<_|Wkq3e9#)&|`!JX&WPPITvco1kr9>iVw4&(Y0Ck$FsPvwX0&Gdj;M9D9ZT}u4&^( zAcg!0q>w9t6mlid-S`pM?&ed!z7nKXM+wr&k3iYuL?E@C2&B-H#n9-UDTb#ZB|Hc; zIu8QH!h=8>co1lGUIWsguf#WDk#ZUEIMk8g%srHC-6H4{w-ffz9h|C%?LKnLYe33% zjv)Pf2c%!O2+E;85flaA0V(G)pbw{_baE(Ae)Nx^ndML*oxBMZ2czo^L1Xb9&{%v2 zGJU;?u-gCr|61^U1bbbUH(fcoYy*O-QhBKxJ=ZS z_1}JC&0pr8m(g~aJ6~oNE;9?4KkhF&X8@`a($7Odnmrc`Dfe73Gz&UP&|L6VkRGlI z%D+EDuLT|o%D?^*lz)B-%0E8^tq^_+nhR(Bp}F9yAkF*~q?wa~lsnT8Dc3)O)bdu4 zTHXrMtY-wxg3n1vIfn%)=c*vh{1l{Cw+K?GLj)=0s-QKaHw3K;ehN~hD+J|}tAa-6 zsvsqA3@sqBS;m01Zm@sAZ=U{73wZD*W3`4N$21qwLB4&Nj?bD z%m+al`5;KS&%Q`GHw5YDh9Ldi5R_qV2#SImf}-GqpeVQ@C<<-}ih}oHkB@xnFGM=| z9Y`(L1F6-)fz;W@gVef0+U$}>s`wp955EJc;&&ib{0^jw-+^*#ZwSh#y%lH;*mr7M=*2 z3!VsyizkBO;)Wpo+z^y`{TfIu2L!3*fFQNJ52Vw#HFRIz2hz#)Knl4YDChhRq>a;o zRC(4F$~LD%v=ll459#!*E0pIyl4l-=YihY0NGEp#WtF>u)cRJ8)avy>|E1#tY36qz zwR$~JKKUI;Grt2V*Y|;xb3M>H@oX%#9`t~qd~!OFPEH3>$m2i?xf@6uM+2$iXrQ^~ zYanepM354W2GXDh1Z7MQ2vWk=KuY);XmsDVQGR$CC^K9Pq=bKgM(0+barJtj(LL)5 z%^kM_tu77)(!i%c8u%0_8ypIx$2WhZhc|(ga3zou9t6q&_W`NmJ|I;(J5Wye4k$Bx z2b3S(97rMG0V(7@AcY(Uw5~V~NT*5x(#df^YB>%_Gsgk_Ej=AbIhO$`=QSYZyauG4 z*TDPqir^+7ojNs;PHqBH$W1^Bc?w7&2LUPJAfOe+K|p$RWFS?11f)tw22#aM@Qy=| zjtrDfy%f70jbrOfz~{Nq?{jtH0#kon$^pYTCN0IrThq_nJa-b>&`&& z@g|URXTc%O915hILxGe#=M6`p{5#JLWu7;I^m8as=J^!341WpD0&fE8rvT}9VjEJ< zk3c&45lAOL0;%OkAhrAmza0l5wa!~ZI`v$jZ1X0N!c7$NCS23GsXb!oOmuDq%0Hh1 zDd$!o{WKx{`ZCa((U*Z@;as4II2R}`&IP&${{ltCtw7(QcorxMo(0Oer$?a-^DmH2 z{smIY#X#D47DyZC0%_x4AZp& zNG*>8>2&51%BspN$||P=Y1VUrG;=yoCiPh$&HN7ZulXHlZSXs=>GvMu~$h^6cC*q*l)b$}?vKspX6ywfqs3XXBw2!XH7(`5;IwHw0yv8-g@*K(MKmTiyrK z>@+i^S?2{($Ol0RxgjX4+z_Ob4}uiBJ5tC8K??aGX!UYKkXrp0NT<#Vq?Q|kbaFkA zHhu>#LYd@oAXVHAq=)x_lsJ(L%{5;G>CtC_vd7UtdE;mxJ-iH*J*Sf)RlJP*`gSJ| z92yk6lf=-S`4{MJP6@kD4+RcOmyU@~^~xNDu6YVL3++{RQWn~m%11yu6P?SPu_t%erJ}+0s|D)CFs^{kF@C~KzUHTM|V(}cV4;C)#1_KS64@Kp{|a`br*C8r!%4ZsH-DA zs_Q7a#jDm=t2T}lozGu>Hv|7}|@hOxaCmo@2 z&oi#7xND=>!;kV~$37ax{(N+2b#LG8-A9!h-9cp=Wmsh!R-F2N{tt(Qt3r8+CPu9c^5`A zX#YIYsrHNJRP7gOR{KRcQTs)6t@evDul9@2q3G0p(d>Vy_f(Y;5!q3XUX|*=NQ-(e zQm)>Ml&kb2&He^btKN&$s`nzDs=i34{qsnhsxMNd-iuUS*SkAfCu+ZFWvcq3Jlj!^ zbgKO#h4#{;+^Pd3onk<_RSiaJRfCaQbzr1c9T??P1sG{o2S)i+2S&=T%RR^T{6P9W zfd#FckIAz=_O9hwtr*4SsVgYDkBQ4uS6o{~cHN^G?Yc*iswbmJ)ss=A>d7cZ^<=bi z)RR$+>d7cZrv{-&Rh3bss>&!*Rb>>Zr!V5)VLJy@yq;2s??SWYWFZutXRn}GRG3jL zD$FPr6=oERPj6_})Rs{!YRf1hwPh5M+A@mBPJ0xQ3NwmGg&Dt>mjABuLMzN?rqgd3RQ7rx&&5j-TC>A^LQ7lekK(VMuBmHX8NWUsH z(yu2K&4MmcwCZ$ZqF1*{HJTAMY803K`RLW8a|o?E^=cHCdNqnm)f&a2YK`J@h2m1R zMscZEqqx+oQCxNcqUcnuQFN--C_43Ow9-_qk$yF5G#6^rXfD*Hk!E#iq?w0+G^>Im z&Hj%xt2m<7rP79!s}&*Tsv1bS@83wdZ(2yX?*~Y~&$&jhmV5$2%Kbh>IrkonG<)a3 zw%*%HX?gWib!ntibsFhZoklwC$wxZv$wxZXsF6a|X{1eE8Y%oE3RS0F(`h$8%CPD* z(y2O)a;rLx)T&OSysAqhwd&GHr@A!KsVWu zu6v|PMH;E{y#+2&$hbq-bp&j^WmOX(5 zy_2h2Bh7Z>Bh7Z>BhBjANOPNMd-7e=teTBx-&sZ|t18=JyLFuJ<6)O zH&U+djn;{ZH?}CeGuvJ7^(n)DB?{*kxwf7?R|Vx+Jsd@0k3EV)RUAd3DvqL16-QA} ziS($B z9H~_&M>;-LC8rOeEU9cGJ$BtARYpR3 zRJM^Gm2IR-WgBT%*+$w_wvisyY^29oLpTi0tjacy!#C{Z6pQLN`n#&%D9@_jC@#D4(We4WC&AaE=Z~Nj zs}hdlQVGXdcpQpLJsicQ5{}~9)U#<&bSmK}I`wcAoq9NmPGt&3rv{GZOWhkqr0$LW zmby2J$c}v!ks3I9uh`UcXLQh+5!G*`+*3u6Hq~#W%D#Q1N5u{4Q3FRgR|7}d)WA{x zRl<>4^>CzCJsjzD?hw+cD(>@yJUej+DOBr5JEv52zPDP{kW5RPja% z?ej+pRlkuob#D}<>Nk2Ns(vG#s^4gZsC(lgltUG7v<93ngw(2aBeiPXD7SWFBh7aH zBhBjGNVA>)NVB>(%BTJRNV6I^x|6!M9Rt?wHm}ER*6p_TBm0Tfs~(PKUoQYsuKJBu zucv;X)vE@MVo?c4QK){SwIN3+3e|6fzX;c*(WZyUpuS zZQN%~`qjqKYSA5lqEI16QK*n3{VL>0zX~~uLY*ANqK=GWQ71<;qFRn(Q71>SsFtHx z^bVj{)XdQ;QZq+))h~eb>l8qmbq65LD(6V8?f|4#cK}jo6(WV|=SZRYInt?$jufh* zBW>#ED9ZqQfijKZzs->gv87k^%&w`3NQl+AfRH>^YRqEi>+VJ!QbSL}d(Tu3uqjA;kQM~>J8f%fU z7Kv1?-cO98O7Au6`k499tN8iuvibok%y+<*s z-eVhGjP}E$JKF<~?yrWAUSFq)%YJy*)|H*`X!h0f(f#dpx06g$?Qci- zx4#|b%`SHok!VpwD)}g%cDbXt)b`N~s_LWY>~%-csqmxRdMZ7hhvHS?NAqa+J5r_Q zkCb?CMS48T04d=DpbU6^0UF)DcQhhL0F7(MJG#I9?I>!$Y0&-cX-65hj~zwlj2$$J z-R#)Ll5I~AK;zo!jp9=0M{%k1qjA;wQMT3jkp}+;#i-7Y^r-Nocvbk39<_a>N^Kuy zUOiuRhAKO{(Hc|9N7-=xKT@ckkF=@bBMs{IC>!ebXmtCu(der8Xmr(kq(KcIDRHVl zQsN{WlqGe0lzVl1q{p6ZlrhzNlrhzNq|om+q*L7hnmm`aDvuN{?ruC{*cD6e{y53YB>jg~~jNLS-IB;cuW=)aOwws`O~~ zRq0Vgs`Mx#)p!((YP=d8{VMH9v%TC%p?W(~sNRmoS8qppRM*kyD(YxlwRDtEwREIG zEgj9i-P%Zxin?kbJ*wzPl`1;Qo}JrBmC89%r9zJMsEQ*!s^Tac_Gu$M_Gu#}_GTju z>fT6$iZ{}r;*CaE-$tXWZ=;;3Z=+dL-$tr@;zYBizKs;BZzF{&+en-J*eF*j+bCBm z+bBzF+DM@~HkviNtdT<1Y@|>%8!1%HMv7FkkwRBUp=vhLshW*)Xr~oYrD~0`r)rI~ z+3$d~sbJ$G^eW(yB86(#NFhfEDdb2Xg=*nQq5mU=s*fmpYB^|reWyp+^BoT9^w}IK z^mzg4@tX%_&-*me=G_Qs^IAdLtQ2hXNr{Rynn87GlqGd(q`^*Uq(NO;b$bxXl^QkD zV2?B!U0oWD=o2}L+P-KsFLp$uah>#nM)yo`G_HNoXk2H!pm|YqMzixd*-&|QO^G@) z(xA?al&CPHc~MnHdeoEAjHo0dRVv9yl^QZq<%}2S?8t!q(l`&zi|R4ThPp9Q;w%@W z!M7lkQ*~pMAJt=|NA(!#aas$?j6Kq5^{N~57$~tv8YxjFMtbayMwwA1Mygbakt$VU zlqKKIkT&&Uq)mMo{fWvj(q>0AQm8(Rw5bUrg=)Vz4b7lBFj}{&zDSiyFH+)L98#jj zi~h^bXEeI%F3OBO&nQ2tyGVoG&S-QMU6dbnT|5gZQPD+8RCG~(RCJLl66vmN*zJt8spX>l*zJrII)5IiQp-i!RCJLxbzP)QT^H%`T^cEI&ODkm z6ihiiJl zsc2p{$&Wq8uB{(6RWwH`s7Q$lD$0_oDawg+PLLkEg^?arQ>04O6sfXX7^zY<_3mu7 zsFWgY>ZM4PliSe@+CPj`shuKKDyT@CIx14Aj*4`uprRR6J4Kq+PLXD{Q>0d<)b9-1 zoP2^**)5Dz*)xo0P3;tEQ#D1Z?BhhM$b29TYNSYs{lF+!Dx&D`s)(XosfeO^wEGv0 zrRIt9pyrA4pyrA4pdyAwSMx*~)I5;}HBXccl~1HfKGf$9CwN0c`RTC*x$wV2mzZdCL)kGO{&WYdmW>EDK zX?CVMQmcB2bgEt=wW^m$t?DJxscwnXs#qeO_V*&4Dwas6iY3aViY3ylVu>_6^8{(O zR?r|dbO#OJDI_)_fZ4iBkVI)l$HUA0P7VN$C^bqo7@(asusdXdj> zPcQl%Zf7t09i@7S&b4w*2wLMRmJd~h_g&Mu<>>GCQKEY3)1Ifrs#_u@P6a{V=I#DP z8dQ+cr#Jrw=~1yndekkE9#u-D#O`06ct%m5M5CxfqEVdkf$r}_adc<x88gV$m11WKK2g;ZVB#K?#97U}HiBvhe z1F3R$hi6T>r%EH5Q)h#td)gt4?ra64dpdao#cNkEy0hvc((Gxi*hcZ1Q)5J{NOciq z!wz8-iy9-!$s(hxG`cpre}l4ZS1^js`5S0-`+*-S5@V?)qFkvWqWpLTqPwXdBK<0d z=nkrdC}R75kxunPbkEahRz-A8v-c*HA2maCPp4$)=cLMxU!+Z)5XG)Gh@x}S1+GHc z?CC}MbP6|G6`o#-6sq{4yQ%V_8MLPtWk9VDtq^}3sde@RnoT=?(dg=aXk5F0(L6Y3 z8;zyPhwiV+hw@;TFS?Iv9?F9qzevC5grX>%CV}Er>qG0)DcLA*_Wh#lss5ozRryeK zs(dIq^*xkT`*@Km^*y9bl@Hsv@~p~-)T;9NRyhr+bv^^qpuUGjQ{_W??Ak?{aY_SH zsP2dI<8LE{YJfLuyt3kWSS9ltj< zkY=?$q*<*GX;$k)YW?m+xmD#unpOFbW>r3 zPy<9+RS86z)c}!NyJwMFyJwMFwLzrTpCQevg-Ek%Ak(YKcg{`XSQnGZWIRa){Kb93q|e#3G$4he)ByAyTM* zh}>N#y4lxAp(-NM<|GG{ZM$Sq&Q%oA+E7tM*;Y|R8C6k4YGoX$RX;>owGS3$(hgXp zP|XmHt~QA7uO5i*uO5i*tsaQRa)oBo9zZmr+8`R&?kbcYdt|VUD>J-hlnw4E%7EG+ znlDvBlmS&iq)=55X;T43ihP$q+SIy`Hq{iQO3eVxoo~rVn{R<=27T|rrqc}iB!zP2 z_dL?+_Z!mbofYZyibp!-8=EewR1uLXds&elRYau3URI>UURJcu)e_PAQAs`iK! zI$Z&2Q+q@T?IuO4R2`8j;~_mxQ9wUaZ$x9MGL2=xPd#SsoOCS%>VarnX9(af z8eKgQfLe)aFic|}cPSrxBP@NDdwBr%Y zquL(2g%D{|6-28}-4AI{@k4W`;)imj;)hhJ z_#ss)en^j6AJU`NhxDlRAw6n~Xg2L&L>aS#5vfw~L%CA%LvyOuhji-wN6!iNjG`EI z`u|>czi+cxjB%V)jHh@%=%ix2i+?L+(swY&PN{5r||iR7kwt1kI~V) zkokxOJ-5w=e!LxYjxo}(9RI^jbm!%GbfD_Ra?CHf|FZipMG%QCp(4%}ga)_$Mm&LLg^ZR(r$ilujZa-wdD zl-p^E_Ix?h7~NA16J=@B-R!`0Eo17LC>HfhG?q#xio)JY6onm_C>FI%?>OmkvN2L( z*CiTVZ4W^aGRuXCUA)8hzJ1s*Ado zL;EmM)E-gjeXg?+P}J(BNQtT`%7EG_(qqRa(&OZW*Fyn4PEJ5d?BqnT?;Bk;)wQVi z-P4Xu*Y4x2WAEB!(q2t;H|HDURTPWUjL~e`tBH1qsHUR0{0)jrO%=tZvWntz-U5n9 zO%-W4ra?{BwM?p}qS;haMYE}Mpb?Kn>Wl@~?r*Oqy8l%%I@#E@zf)O7 z_jiIZy0g9hC>A?2(Y!dX7~S8g#b|cy(nKRVuNY-dO%<&NJ2TP!?FdKu?b1Y}sJNmm z*`JB-sp5+6tnP|3V}B+Z#r{k*iv5{rEYI2~OKP)dMEf(*?5NYCi0sTn5vkK64fbcE zHKS&W)``k3iq|epq)q)6sZy;)YsTvb8eO#(jjm3MVs};pQeuB5%7FcuXhii}G>W~N zC|)}-(Hz-_iSDLyi{f%t1B&a^E5&I%+v&8th_fh@D!NGFx%>F`L!WgoqrZCE>Qc*f zEp`=M6uUi~Xhu|bQ8v7SqIpr>MPsS%qRgoAqS4iOQCxO%qPWy}QCv=G@Cn=;IgAon>D#Iwx>ce=7PvSZLJDLS` zV-%yhF^W;$7{#b=jAB$bMv?kG6shVlniu;>QKV|fXyw~MisncS8O8ge*>NU=Ywz)# z0F2)0y==XyFuNA}%VJk;b}e=_XEb+e&S>p9w*lou{TW4V4=RdU{TW50{*0nlb4D?$ zHlr9-n^B~y%_vgUW)!JvGm2NW8AYnjj3QNGMml}7E>ft%jC9(qigenoigcOsa0)8YE_$&9#v(e$F5X$J!?r-89jdOO+|TALqG%`6i}AbkdYphWTeVYR24?Esj7@-)Ar*Wn&8&(vT9bCJqPezP6)9JXMhexR zkt#K3q)O!(sZw)BN>rPX5_M*z#|{gh)#$OC0BPV(qfGKYQ4ZCdQ4TpFNQoSwan+5` zh-wLF6ra*?7U$8pKChrWc;}18^}3D5^$LT=^;pO0(KfB(X?~`BOj`VgIy1_QYBN%( z=8SZzIioD8JR{92&p0Xf7<3YXJJPHQjTEXaBZX?qXr@$^(R`^YBZWQ{BW)_oNSg{X zQe_t_Ql-v}RN2cao^_NfHDsj0K2e8wi%7X0s<@7#aB41^myc!1 zc>=Dz8*!=t(r?cy%AU$I(yXq8G^;!#&GxdQe5yhtwa&{$SyhEb@BP%G(Yp($2Y7Z6 zg);b#kOxog8Ua zCr1j6gcPcfBZVsDNTEHnNT;&}kWQ6zq|;7Xq*nc0{{yuu+kv6q)q)lxc z&9$mHQm879bgGIYg{tC6q1rggl|8iRuhqtp&aXYbzV_bWYmYMD9_Z(naTV8b6UAb; zEs8~59YtifEqdNiS4TNlS4R=4sH2sjmX6k~8Z?SdMIA+_u8w9wT^+3f`)pBM_SvFm z58o>2-2=6D)gqm$>qwQIv`CfeI?|@PjI|M62SqJKXlSx6PW`yKiN7XWt?CdOQ!xyfXy62cq0b0!Z`sG~1)=nr7cEh%)Ac zUbG&*r%estHC5lMu{f>w^?05&79OJ$jf8%#%V}+nkma{QB zdY?WY|3kl{l8;`;RPXWI;G(}>bggdhy`8G0FMrgeo^G_GlEfdgS{1OZ2Wv zO&&d?sL7*8iOM{hx64LcjX2(n`uu889UduM_pfU2-eo%NRqY*bA|-0?sM?|Sjy`v) zy(4W_9@3`vj@)m%h|yST@8}s??Hy@$`hnBFM5Ydpa-sr{^r*ulCF<}fKil*;_rNtJ zb{!)P&OJcms>7oZw~eR*Z*PacP=QAo*fp-IyKCdxlZ;|_A~Bkm-FUp9(be8jT&n9R z|LW=}7T++4?y0VhV%Zmq8oO)vw__RIS-l;9kMiu~1e8^~mr-=8@hG3F@ph|RMCtDs*wKZU$Gtzk&?}+dmX;!yKnYRlXY4evT1FG~$q53>hs7j9%s@3D9 z@cXz{t4HIi(xb8Lc1GD&pGP^d^BLttl^%`gj0H5JozG~LW9!^W3%=i-UR8QDiYh%C z%Z_L?iq(Mb?-T`;bG3SOe-(Qakv-CAMBg@u;<_HQfyPzIM|rk)8bxjIG+GZT{78w~ zK8n}t4N|4TkF=@tBZa<^5M^G?A1PG%N80STMhcy`j1+PN&?C+n%SaV30Of}ZfK)ks z2F-%ML8`a_NW-IY#RYKfaiQ{WzZ4BB|0qjp{^(BjY$FXS|0pvm|7b+NfkssGNAsfE zk7neisBaq4$qYV4i&y0z&4tQ8x}W+#8d3cpjc6A)irOx2q`_-HQsUeO6uZ+KPzJaL zNEN>TWx)3jqS$@&AbO?n&4VbnKaT%WnnoF^=-@ z+x?Jcd&N=aIS5EO2LU}RauCoga1fAwe}nXM5Rh^X0-6PT#gS${0@7^9IC>VcZyYJ) z4j^sLh`>{%lShDb+AEH9+AEH9@(YkoegV?SFF<+b7a+Cvha;W51C(dp0n*GnK$`6s zM;W$n9OcvL&G;x%Zm&2RpI?B~@(Yk!egRTzuQ*c6DL`sD1t_bW0;HB-fOPT;kU|~- z&f+{SBF&rvq?}WLyXd*d*%5dZMZ_;akBJvOBJ41CZ7w(kNHwPbMaL;Xad8LGYWEu` zI(y5}T<{1`j64DqqkZORMmPm1QceL*@p}An3ebvrF;34z?<6?_C_1~)(d?-FqbOAV zQ4}iwC<>K-G)H!xqgcETMzL@KP%P^IC<^s|q+jJ9>9@}uDOdSdLo^ra|7b3pQ-RhM zM*z)*?-NA&IRZ#I7XT^Z1t7Kd?jW^(iqtxX8L74B9I16?1=7qNK$>|3DCax^6;F=> z9s$a&-R4N4^DB@-P65)%FF zlu51u$|UaqDdZX;ZTteHjbDJYaSD(&P61Nrr$`~E04d}YAcdR)lvPdvQft>bQp+_! zS>+m_HNYuA`t4&!`t4>%`t4>%8Ri`z<@T|oEZV`2l>2OnlyeY}T0R0&%S}LPxd})u zPXVdrDX4LqecgmeCr<%yB8A)plwo_Ynfjt^PK;Qb!h!VLGmn&WH;{6><&l0)2U5=I zK+5?YNVzjQka7+PQqBQE|HT18$~hoNIR^yI2nPhs2nPg3@vhbWu2**FGyBORis)Ul z^RCx-r+oN{==dXOz41p-r1smRNbS1EQxvarKhS(}Pf*m{6BIS~1Vzn5K`U@tb37E+ z{>u)06e&LiMaoY>k=lWeQ>0!Qo$YMxijKpAqHrDv(#&T;I=L-KAgOu2xk2LUHP{!=iM;WtAAL+46AL-$|ASG4+Qev+@ z`WgQPDdD`JEIAJZ<;r;=9?w?7$Er*p)9DOnKiNfVzHy8R6!J=t zLN!*TjZ1U&R$>5l>P-YM|u{Je&?JZ{oEO(pF4x}>s&zkbuJ+N zbf73WH7E*B4brcF0nG)E1}WFMfU@nh6SS_JbArbx^Ew)kX3h&ztCs<(<-8!Z{1>E_ z|AN%=Uyx@03)0MgL28|Lf;97AkY@c3DBD~Z?^mehzaX7D9gtd`4oEX!2IZMAgOu}S zkaE5ZQqGq_%K0)#xv`OQy$?t^j|SzOQ-h-5)SxxPsX?*mi9q+`*Ss0ej~CIMxifFZ z8d}85LB0&q%$Gr$c`oSp@Bi_yq3dG&4;S$=p5omgZw38aCk5UQ>ZCxO5WE#sWuK3g zfa)mR7W6rOK1N5Mgyv&x^iFL)vVpqLI5Oy&V?LrrbFQlbc_Vr&@W;rTTBPcSexG;a zJt&uBIkJTNNR`eDR14(eAZ- zydg9TydgA}(`L|IaEQ>17zwA*#mf~!QFDb*)J~g0QR~YU;`x=eN4?-h4g$9kNFT;14n_s;c=sXp!5E_vmgrasv4I15fMrd?yG14HLXmn>~ zqtQ7;XhbL2px@Phfkx*Up=@)DP`unCG%lYAjm{xLqdVUQ#m*-}qw|SS)Xv#PtBYIY zvy=6}AwsI0yp6Q!=0K_rWrI)Tnl@+Spf%v+ZKQ`Ajq<=7!grB2=Wioz93rIckSY$5 zPG%Z7L}*6zbf6jG79kCKI#7N%M<`32BczIFgvND34$6ZQa(r$SyOXz3bQ~gdXFd_S z^Hq1&+2LAr93pg2t`NF2KgefM`guU;FL*#mzcX{tC^|dPo&5&N7-t7%iKl}eBRn0S za?KYv2aTn(1C7PgL62X~4jNa-2O5{lgEGeDK^nL`XpQlD&^$g$m0l0mv~hfpLXHp0 z0Ivu4(dc?Q(CC~UG_G@a&{$j^lmWdPINeRuJRSQH-I=q4qJG>c{2kXaz~4a`;PN01 zkJG^GaV>Tya--OJJt%gL4_e9o5@q0V8Q}G}mI00rdW>^?kaE5cQqKMPW4yZ1tTzNH zKc_)&h-)+cQ~bF*``%CW3-NM)&|LF?P`sQVq>%@NqT>Xi7u467GK8YjV}fGT zOM(>fiBLp*A`}sy2t~vvLJ{eJMRVaj7K(^lgd);of+FG>p;)*@C>B1E3fD!PMG-wO zBL0zU5&1q)6p?-t6bnZQ%@;=rtuEgOirypnR!|hL&J+|crwPT&X+rUGnozu)CKRvz zJt$s(iK2EY5sH`VgyQ8op{RLJXdd;d;1s((N4^^ry|;Yc%s%fOCVxupPiAzopt<&) zp(ryi#=9+)A1)P|Yt9tPjII`x87>t*iSom%LiyoUq5SZwP=2^nC^Nh&lnw8yQ8u_# zC>vZVloKu$$_bYW<%COxa>AuTInmF8R=DmJ6sf)yH2YjCvHE`X4AKhqS^el z=zeV;eFLeVh?LKT;&qY|ikI7k;^lLp7=0Tlnpx*8p{O}uC|>>-idPp5idPp5ikb_C zqV{_zUM?7lmkWlX=7OPkIbUcVe{CL}zoc4i9=TvBB3>AZ$jM7+?s#Enrg&jUIWG)p z)-{9Fa>0;V|Ayv>3x+gv!H{NWF`+r)f+5X1Xw=i?liP(f@Vt-)o)=mRJTEjR=L_lK zc_BT1ij;7>kP>beQo`**D~Ef9G&qF`%`Eo{>2Vel(!;|-8n{>GUk&`~&+dY36O=I#R2H2CXzc7gEmWLiyxvAw^`7e@?5#}Px(al}w`95ECf7Y@yc|3lI77EpBR=qN6=RTP)%9g0YW#$SuVXI2!2 z&u}OTpE;2Jhj-BQdtZZ;dnH85J%b|U9;ryVHH*^LX&;LSEaKTU%Trd;`7Ys$g|3dmz$B+}C!L zLs9U*kbce=($D!4EzP_wq*(_L(#+LDYPniSGY<=?$UVHFObWn8Sr~%jZHXL5C5_us$QCob!d0bG}fvIbTRW z=L_lAd4w{oLW(lX|3dotUr4$BBa~bI7t+uFLi+U|;VjPMB3?#ohA)Pq(}jd$(S?Mk z=-mZh3`OMpd=wFn3`N8vLlN=FP+Yo`P;}IzxHx5KUU+0EE*=@07oAEdI(`{W(RnY; zHN(5;c~!p>idVl9nn7JlxQb%eyM$urvY`ymC1{cZz zCk|zR6NfUO9*y##n+fHCD~D!THxv3T-W+&bJxF*@xZ zMf9nNcy_ME!m~rMaO+SMdYX`am2{+^Plq(~>5yhV9hyNt9a7Gr^IU9>^faM)`P{sG z?s<%V=O>iwaze^=IiY#s;-M(GcxYZe_fA;%lWP%i^w3(>35Di}qlcp7=%E-ndMHNf z(H!yeP^7#(6e%wc{Vo>|%?=k2t7MTNUavo0#6TrU;U%&kM3 zxphc0pAM5yiw57Nx1Lz?wfA?4gUq?~7mH1q6m(k%0OsgQErQb@UODU@w) z9n!2%3TfunAU0kWOwL zQplS_3VCxVtGqd+lQ)NS^5&3Et{hTmRFqq;98$}VLu&bPXg%=bkaB(;x`!?*bWg4v zx-(Y}{g>}x#r5F#=0g9JYf*6PP!!xc6ot+)bZ1>uNay#~fLVeil-q*9rYCR}1OkYN1`0TrKo2 z-l{_HDD^!dZTg;&Dh?NVoN=|h)1`r{g_P)WLK=8mNCSrpWx(1+_vdP%JL_pecXp~6 z>WtxDq0IBJ&?ww16dkV$>33on(#)muUVI)G(fM#3E8IqZ$G1YWyl-6Ym1}d&y+R}E zazYX9$0G=3Rj(6@(T)TZsa_|fij#%rTHh0Tt#JMr$^a(|twT;0Qp?FgI`ulC%``2uB(pM?~1vXC}T7RsTHC#20cJ|I;*EHt|ACp0_!ER-wV zPv}u_EI-Fa*YV^h#?tGAGN9whdAsiKj52h89Z%@aJS=o)9u|u0s{1>g%(ZOuvygsH zmQP~z>u*B&}NNC}?{DdBLT73j4J-$qLKTqqkHE~LttX7*^(<9lXNPHxJH zZYI~1@VSr%eN1R{o)?N;22tjnU53Wuf8jKi3~;_s1~^}Mj8-*=3ysU+LZkD!(C8d4 zlz$Ev{vKt(4i%IK_dj;uaI)? z6;jTBl@iiMM<;xLb*(8q-4 znyZD@KW_^~!P`P(aWdF9*Vp?GR%`g z+MIHR=SUT23gwnFg%t9nP*!EubFtonPDPd*gV$&Es4^)4aJJSn`5o~56S zcMa+|7f~$yDO^XfIQ^Ef?}K!5e2_wp z4^rsVGPH{LJ}C3vgCflwAEZ{l5>m+JK{{WilfR?VXPx+V47BpOIcS~magcIdOGv-d z%#eN#4$3X>2CWd@4N}g#LCSeINV#|aNI3@w>F3~}C^$GM+d7!g`r+fChh45}r z&UrUTKko+V_szUWKOYBWo{xi~(9?v}@pMoW+#ICe=N6=#kApOGa8UmBG$G~O92He- z!?*DwwR)P6Ha-s0z{f!v_&6w^d>o|2rzVs`J`PgC!9kEhousQl#++$}vc%az z8n`(qGkhGRM=ugm!p%V%_&7+3pCTptk5C@CIYk#Ezn%>deBU zC{q3oij>QPBK3(HMatztk#c!Zq`V#!DX#~uE?y6sO?z)~it&D2+e?eHXqN3!MX~FR z!c~+9ZV}1@p9rl?yWUVX>?1=t;TfTv*r|jv^T$7aj`G7xLiyn(q5SZYP?mT}C_h{{ zln<2)lo^f$%8WWX%8c47%8Ys*S_5iMC_kzrXg#Qcp!J|Wf!=wlNf<|FeDX$l@EH;1 z!Dl8Emv>btF0bt7|k#(ea^BEbog&UzKaCQFj$Sj%J4^g`(h0p(r?0C<@LL ziiIqT^Me==f787S0rk zMGqJH7ycBAf-{9?hckudNDr4smpS4+A?NA^pzHL;AT(NI72#DW?o6=P@DuJSL={yM&Z;mymKE6TjRF;UXcmTqKlvXXT+a z!$m@xIY%hxJR_u87Z}paGeVDOZV^(h5{)!-h)^6lypTe!kY`&fTvrz^qTK50Ldt#1 z3{vj!O$a`yM$I3cL_!0+ig%p zJSG$oj|oM@X+jZknovZXCKMN^3B|=}LeWu)qVtW|C`R5Bijnt(V$>;yV&p^N6rDNx zI?e|1s&8KOi=kNbh#~zPD5ReQh4gcvkbVvn($9fH$~jO-xy&Nv`ofTMJ`_^UheFCZ zP)IWe>g~{NMz~ApJrzd@sp2RhRnFx@N_>+J(!*mydU#A|biNWAoxAjQ-2GqU-+kK- zp5oo09x-&SI}Cl#$$aDu)%NBiV`#6m?lANjS6>+V%)zHb?`ZUeq1PWBVR#$A4eATS zSzJeY^nW3DV%g}tE!VmtI9y1H@83a6cw1*?}&A6-mOyb&<)y;T(xt7~a z(QU>f%eA;R-G5VDo8sCu)@IDUe-+)PaW`WnxEATA{BP3W@$4s*Z;E%5p3VR3@mjPg z_D!*Gih7$)9bw)Fn|%%%@4?4ooSQMijQaZxWE12)%K_lu5^Uhw3`od6*{52FQe+|XR zSwkc01w$k9(a^a59*xUKL!E}n9f8&l*9=9$DMR}CWoRr; z8Pd-wL*w$uP$r!Oh{n|yhQ{KNp@{T_`DAEZP8o{PDSt@yqw!lv3BL^GkW+?~==nk; z>S0Eid{pe#fomH0VrcGkejz=N(&OAepHb=Il%YKE%aAH3{vjp&GNgoGhO(hM4C&#T zp;@pRkP_Y*ngtFTQl*0osnS8_v=MsvXh@F^GL#=(W9Z&IHKdA(CDYeJ*EH2c#VBGJ}X{CzklwPNS~Koq*QUu(5&&xkScx|T1EUaq>WRC z^2RAcYl%CC)N;pA4&4PQ=Z+!$JTjC??ik7;cMQeils}}CBZhLw5kooTh#`eKypTeU z7*fa=L$j>63#sLfA+_EWA+ExHGfGnaJcgi19>#RSd(}{mbCyxwe zQpXn3$sI!qIbui~M+|8bA=0K-3uTf=h7@wdQ1+hnu0~Im8jVc)_8;6u3b|cq#<^Wc zA-4LOJJlp}2h456U^u3&rKPQCyra6c^_UMaTI4 zdfYj+54|&WUZ3iicwhG3@8x(`=vt(@rBI}tGBiiJrBI~$q)?=sG8CPzD5R7}hN9z? zq3AeeC_3&Kiq3DN==4LOh;&7v`O+1I;^LQ~i1a$4)y@|~3VC5jq3`rT`R9e9F*#yL zAx8`;R>`T`ClljoG+wS9}`Y$W%ak7Pn_@P+N$`iRly^3 zE$2Kk6p=FkQ7pbQ2v1QgI-yYJd1ojJC;lPLKI0+foHC@GUxt+P%aCTS8Pfb)EBv?C z0|!mDmrmabgtR%?59L{h6v{R?4JqWQA%)yDq==`6Rt0AbW!ss4NFg^3<(8X zP7WGU<-6%o_PA+iJ@C|!PTf*SCua@m)FFj($XP==d1^=-PYq?&_h2KndZUn9{u;4C&#QAyxb`q>5jL^2RAc+BjuMo1Y?uoHCS89vR9fj|?f~ zd7->H-w(|!&kJeed?AJ0E~Jy&h1BY4LTb5PXqLHMNEf#Ysr3mTspWPdoqR5&md}OM za=VabE)~+upF)~>Qb@Dzd8C%>gmiM9kWPLR(#B~*s$3xr93`ZIi=-Oi5y2ZmbIKt? zO6)sBO6lJ$36w5hg*bH@r;l*o*vSrI)fB)9?&eSZKLd|Wg^Y$WGHVc zH2!W8FXJl8r%z5OlRgumD7G$e~^m}f`>6ua#9-~OVdBZ8MlXm~jAwv2& zL`Xk}2t~mmLQ!ytaEik7DsKqs*Q11#>rO(NIYCG>CkScg1R>3wAf%ZSgp~7ukY*kb zQp*WKYJCe5Qm97>DdYhmg*+gnQ@;{gIs71$d9D!3zpf>ef2a1Lh`2&1BCZgMh%1C5 z;tHXN^e&@r8OaDq@QoFEjDP9+oXm0)=7jk^L>zJ?hn$es|cy({ve%nAcY(sq>$r- zv~hfpHja-+vOIro<>)GMZT)b3(0b4lgj8{MkSfj&%Ar0Wq>875R2ds(PahD{#^pi( zuJ;EgJ+j2jLG!NP2kFuEgJztkgB0>{kU|a)QpmwUdE?z6og5sLJq`|1D@RBt*9Ph2 z-JpNx-5|}p8_$5tNHcc^Dg4iH@bRZeCr1V;7A9v`HZ3xhJui@}>H!(V%3@nT%dGcN|k!i7P3=D(m=_%A5W z{1+4#Hv+8(&I?)(oEH=w&jm%tbHOP(k0WRFd8HAZZXgtkZXgtqZXgs9M+UE>dC?z) zBI3@Vh&VE6Rr6v{EKce}QSf3=6f~h&crj?T@Ly0ATo@Du7smbx_u<7%eZ1(ebowAY zd>NEsz6{dFkwJIhKOqfzd{8ENG4IFS7x6OQ4RTv>7X2%41$`dnp1dD_vyP`hC*$EU z-bA$!J_!0N9X;rMqP`yVYRvUOF0^y-P)8c?9B-jQsg7`J21AU)gS-Hz4bnzn7Kwqssg zQ?*UiHdWj7Y}2z%&vvX9zaul-GP6ygHR>m{ZJVQQdbZ_co2uQ&kexKV1>a|clsK&p z<-s|1DCeA1l=EHj>i2OiQXYgIIqs?72i=ngfuhsbgL2MyK>GO(NHebitt-v~nn%up zla$?`zku$nD+ej(GNARND+i6mYe4hMYd|y0Ye1v(hEa6<1^gH(;WD7rr9%g);xgEQ zM3oL5bdO`I_zte=(XE449p3@z;X9!9=G-~7-t_OFndL{IwdYv|>EucvZO63nCR|hH zY&tXxzQYLR#MyLcbf?mxJX|%Ro<`TQ!J$B-a467N&Z9%w*2RP3(!YbU&6PlLaUxI@ z*WKCkqic8OM4+tlBanVh1k%rUKqESp4&{>vf#TvspmBBUpwV^fpiJ^3P;{Q1Q6~8j zC`KLx%B1fb!d;ZZn~`0lf%||oIGYY>;6We_JP0(W+y^uw-vMQS?|@bp#{p@$Ndw2h zo;FH24oHJ@>d^go4M>Up9i)WsfO5ijKy%@2I;4mDfU@B(NEHtPsnVx|a>9vtpYMRP zu8nf;{^ue+cL)7DK7-Nh#5t62-#UcU@*t2}Jv&Gz4+6~{4+1IIt%LOQBanW61d76a zQ52jAw8l6QC<wq>cN4l<*pm62FaRSyv9yz-vHC zxC|(t`f<=|=PaOcc?u{$`fgBuI15MvX8~n~zkrl*7LXEd0vcC;4H})B;8U^Do#%$K zp?3zYF+Kv)!$ClIA8F9%f;8xGLF20VqtU&;K{-+LM;g@mkp|U%lpozLDh2YRdXMs>&jo37;u%^w zD)}g5>iI~y&KIOy=L=GLdN?`AD<#%~1AK_0=zEb4D4;n7TdErk@3= z(!GK-sM{kAs`qFF)q6C9s`p5V>OIP;>OIP;>OIP;zeEakvY_1RXF*w2!$(X zvmniC_(-!FKFXmQKGLsxkCdz4Bh9M!NVDoaQmA5&@}^e>&9z!RQl(a}1|)~NRM5E2 zA4B7+x}(w6-cjDv-jN1N--Q#*XypUO{nMA#Q?3H< znsRk`^cc~@f;8(}L7LU!ky>?lG|TGnXqMICk!E#xq}eA@lvNdYG{0)^NUaJynq?=C z*>_I44iu!*X=6yO$~;o58jsYf#-j|Y#v{$D@kp&|Jj$YKJkqQhk2L$dhw`i%kMgV< zkFu>AkM!$0Q6Z&SO&+OLhetY9;E_Ugc%)Dr9;tF}7*eJ01L^S@80pdRf%K@%BRwkf zNRM6*wOV@Aj`a8>jP$6tBR%#tBPD9=KB?1S zR~nj4JETy4RM(LnyGu~6RN9d$HFl&*jU8!IS4SCBT}O(1K1W$n-9*|{ypT5a8I9F8T6`%lz7%ex$?+EdaMha=55LrZ4dvWP4@&+rE-o`sfr^# zs^3V1DmTi5`ZgL@eH)Fg%8kZV>qg_Ma-(t8y3y!r-Dq^RZZ&eWbQ+GcRGmf&Ri{xVRi}|!b!ntoT^eatmqs~Mi`F4yU42TM`m<}Q z^c^5os?bQ4Dl}513XN2$MWY<5LZdlVe@052XN5GVJR>D4&(@jjsWzkR={P_$>%=OQ zJymF=N);NZ(qDk|=r2He)S^+w)S^+A)Sr%wzjAm117-{g`E+{i< z!bp!D`$&)aFw&z+jB=$)jI^l?BUQ#m+U(LtSyClNI@O0!uGEL$k9QkJRNY0t|9$-L z{n*c>itBVH{cM-<6z>Lo0}J~3Y*bj$&sBZVzuH}oJ^|ZZkM@qK0HarO&H;MnwXYsI zc)o81c@e&E1;0gl7LBWV?3$`Y|7wptpLG}25uGB1cD&kYkB=j5cG@F7_SK`&)s0au zS0nR!_QbVL|9Z@hYoBt~V-`?{uD$V`T|4pZibs2g)tphiN97rfuI7yHrrM15=BP6x zJ$ApN`>Q-7pI_w}rx861+U1VM-IjsvSZ}V4zHMApW!J`4Pe$XaDx=X=mC@*`%4kIO zWSqt_JKOPmfaXY58D(tO=)1ADi@WSJbxn@NBMEy6w1Rs4QkY` zX|Vep#jYZa)Tv9O5!I#9i0aa4Ty<$QmUE&|=Iwh&Gj88I%0Gt*JyO)A(d)2UG@1n! zX*3He(nyu>LqV!lr;#>iNg+Kd(nyb5G*V?hJj%c^CC4;a*?vNa$}>`8hrGQDMs$`G z8tbY&I9JNG5uGlD# zG}o%rXe>2qG@?p18cU@bjiow`?r*m|8bys7X2Jqr5#XZ(jRdQ?8PXMtsum+qJIGc^2n!6|EfKZ-Vl9PSv?gp3`tH zSH9uiznY`-_&+qtxrolaA~;Lx!`P+awZpff_!J>OYSAcOCrY8HRi{zx_Q|6Rs8OQ~ zs8OQ~s8pl5Q>jKdQK?3mQK?31RjQF@m1>kFV<7!1)%ZD@Wjp85OxZba_m5Slc8xM- z|2&FF1slbpf{jK{!AAO3u#tXy>5+cbY^2{_dZb@{8!7jG1!-2(Mr!SxM>^HC?N2hl zcF`lv&YMEYojQe-+eMG3Xg*cHQO?!9k!ICzq*?VFX||&tWmw%C>Gb#Lv11oK%BmVT zQmY1z-d#9X3Mp3=M{4b>$9<&PzIvoqZ5)lJ9*z{Mgd>G&;7FlLI8rD!q|i5&Af4*r zNT+@E`1hcF^*E1mYezlGt#2MdI#tf`I$96*(j(>e(&JB&esy&eg}OS5MO__5WM4gs z$i8~CPSo2`jOy)Zg?lfHVzj#+#i-tnVpM5Ik5fD9@qW-QdK8`g^Jo^-+tE5#Z%5Io zx1(58+EFYj?I;R0b`*t5JBq?dQz!~mcQi+KLZB%8J&Ho@9j$*m>QO9q)T4;(s7Dd` zwhQNM`^e75ddK85!J&Hn=9>tFJP z6pLCtibcg9#p2sT)LiISu}9B5_THnFrf!e)tJ|X)QMX4?sN17ls@tO|)a_9ezDWe> zxAz|Dw^s%!x9c8hw)Y-sR?k-zqEICtX;aTfD_=byPwI5|wogXPz;YXUC zScNp(U5|9C^CN{mJtBqb{79iXKhmbokF@#z5u8V}@B2q^9VzDpAho;zJVkj{|3_-o z|52XR|B+^=SE1ah|D)Mg|3?{C?MInZ?Z-)>mFWyCoW(_?_H}CQy>~6c>i=lns{Es@ z+JTR9>kKQTp9_H0s{f-5tN$bA>ii0i=y1fV6Q0aMC8L z&V549$Yk-vdZ={)PfHdL0IynnyRd5!NTFyUG%U?ihISWW9PXQ_9U?7G54=Gfw zM5@%f{L4k0$3^t~ppJsFs-l4VNV89qNVCsLNV#|7NV#{8NV#_|Xl;1SMEX6`BmL$R zr;NJdN}#Mdg$e2BN}#OTfsa;#^OtZI#lo||%eao>^1UG_F1z$mTz2N8xO|5Q{un*) zaW_zO+zk{RcLPPo-9XXtIMAbjyMfjcj{`-@<3KU;IMABsaiADE9e5i(PJM3(irOxH z6t%OPQ0$x$6uWN^K^fqcpbXg0kD}&}pn0^DA4Sb8L6P!DP^5P6qv-e}C`SGWiqU>z zv<5jNC{oS{iqwvM6zQMEXs^EODZ2Y{?R!Ab9ND*z=7?j0W`tLQ6!J>YT<}VeT3!iK z=)5MRQ!N;+B)$pK$u~g?`6g&CKBbL&!Yz|Y?g`TAye2$GYB?!Lv-6sea=ZG`TH>c5 zB z(#&%~YMsc0blU%qbaGpePHqd*$!9@2bpfCZQ-gBLXF)nSES`@pqDP|r|G0>kaUChQ z^B?8h&VQ6`UJS~!J^$!2Xy-qQf=7d*;L)I1cr+*$`~Okq`86mat__O9ZhsU7zXrv^ zwL!o2wa25=mRx&0e(e(|H^(zC{d^pxpM!(+^Kp=7J`U2%$3dF;IA|95I7l-e2Wht3 zAI$3kTG81c4I?EiOupZT)$AH`_@KhkXfKhkXfKho(e zCZtdo08*$60BO?&fK)k=32FPDD&P9yT0Z}7mhXG^zHhbM_l)g(K%6RQwQ!xhwk_gi zJVig}I-#F)o$y=quUseGMmsLKPU!RceB>X!2cM5v&^yQZ$ToUkV;!Scs`-crJx6k* zkmKj9Cp7M2{C_kqPYS8xNqzjs4y-o*I!*==;+I8#uO^|ZE4@kdn zHbMKI^g*B~^g*B~jD(cyhCs^sS!e~Vy638UI{nF6jdVH#3gyj7P-t{+7s}pxtP1=s zQo{d2N}Lmgl&s6=daMxFvMMh)jY!pctX^kC8hz8OIYr8~{P523I;wng&`_2*Xh^LN z4y2ZwhSYM?P~P}xNGBf+>9ppMDjgg+sp2zlM)lbHCv&$=q23MG6zbhTN;qq1bj}(Y zotuWn)t7;CVvVA4xn|yW??_p2#Rr^o_!kjY1pS>pN4%J_T_wE)cZ!?H}1Z1_vLe6KKJ9< zz&)q2#JleibZEpw89tPiL+TFYmTTtSstoJqK(nlm1LfJ7Q7B%18H$%*hN9+

dBz z${lkp=e#hKbB-9wxlRo( zqwvDeC|oe~SmT1BQFvh}M(WX8(w%`GUrvrf9q~&?xpspi#^Riq2_KC_4TZ znpyrAQo{d2Iln1h{+Da2bY~z{yfBn!Cq$tq+bC$NrVG_Hn$I zn#Fmf>O7wN(M<8zkj`@o&*g`|<|i_vn**uR(}DDG+)z$*d7zw}o0oGl!h`b@ua%rQ z^jzv>Dl{&y4dsNthDPV9p?Tq{q0xD2XpVSl=&`_4L#nuGNEJ5?%@j8c%@;QfDdeM} ztn$&2Dy|v26W0vQ7uO6alk9$pyA4@V5C;)S7EbD|Vd#SufQIAS=d^3IO`g|u(+p%u>mLTWi*NG;C` zPtnTNOM>+CypR^27m9-Cg`(hjp>@dfLJ{%2P((a0lx^>%QFJ^nlylA(ijnh$Q*<6F z&Xq#>=X|03>o>teJVw!RzEBk0E)<2n5)=iu3+d-}A^qGgq~FO=XtnUXP!#?i>F0JK z{oF1zN8BzH1#b(jWF07Y73p+-6q*YT7gEmQLdrQ@DD%86q?W6N)N-|uPJR~3w!cAY z`B_LUKMU#9d!lY-E&2Wwlv^Ga%B}OGkY>FnXytISkY;`s(yR{!Ws9qYa?aI4Id`HI z($CdG+2(4YD17chQE<4Be%=2hWt`<_IZw2Ymv4T|bu#gfS7E;2)LV4q1q0xQj zM;f?SXmsus8l8J(zqOojrtmr%U6%@)SzRh9GyEx(8D~JDSUFQDCp;;X6Z=F_9-RJ! zvcZ{B2^Bl13C)EQpO6NA6B=E=3DV%(Qji9I6H>x&LUB9&31x=sgj8{z&`kN@Q9=s&N=Ts|6Qqr=gtVz6AU*seXSf*M zw~gQ~QsNs%&>ZoP(CC~aG&;`+jmsxOvGaq_DEuIt#b&_9A!6b}eR!2?23aDq@2dPz_eoFEhh4+!Ox2ZUnr-zdX8AQTZN2t~vR!YMAV zWjgqgavl)MHV+7?<@+FQI!cf>?hn$YuLNo1`yf?%4v-%1kGhoX@pMp@_&6v_92}G% z-VGX^cY{XffunIboM>h_I4Bcpb0{Zj`6wIexF{Q{i6|QnwGgxUPzj*WXJWjHbox|* zvgBPqPVcxW_x=&-_x=d!_d1Mn=v4y6;u#TT(&HXQ^NYsxbp2dU-Ypxo-3LAmANpbYbIP!!x8lxJ=ZiiM|xV&UwdSa>=p&paIzg$^2| zpQnT3&^v=P>zYBi)jNaMGuH-b=Gq{&yc?vJUxRe=YmiQU4btgbGmuVx4bsV}K^f*2 zpbT?uP;U7(NG-nxW%#ewFptJH8>EvvgLLv` zkWLDaPF*%gEnf!xyYFGgS+oXj%k6DCZ&P)fs@t-6n>G%P-=yR=4Y$oKH^)yXQCmTy z-!|@T`ME7WxBWZc=i_+J^80)rZu%l##&tXme($-OE96?1xI!pbTp^^2H-xlth|sFz z5TUX36QNx3evnSy5PIhPUPZ_^cYGYa&$sdK|1;EjEm_3Nc#3y}{~Y7;{{1Tt2>A&* zkG%HyTjxz7_l6&Ys_gTzlJOALN_8ip3JsqKRUqagQuKM3XN1O`k9g7hN^TK)$H6l~ zuLnj&&&Ttz2GFC8bA;xKb7a>7wLBvf1uEyuNX`+8f@g%H z@QoozIkyPu=N2L59yv(4Q?t;DzHG!*Bd!{8RmN70!bP&v!YHfmyecQFV&^E?fg!`Z zB=r01vdT+xO%?wLY2zOuZJZ;d&>BSw*JJ&l+^$o*F1PEkn!L9#t`01eJ-!mkl|C$# zEB+Chef|+r=AEa%YHa%RfY16}nX5YzRNa1e$ z4C&-dAys;~kSfj;Ql*~@tqm>}QpK4ClrxBEVQC@ zW7&5ltG>qsjmwQftB4zgqHu;7iiIbIlyIidI(L#7di3eiLV7q;NQo{j{qW}WQRC{y zaxGpxS!i4?6&gz)78;97h2rH>p|LnqXa;#wC~9sLPUDLDrqO*bdEtGj~6pGY)8l=IwVQ5@Fl$~v|{kU1?M!BZJca$I{JSn7v8-+&aMxoK2 z6^1h4tT2=Z9bQO@J};CL?*);n$7ROpVXkGy>0v(It)n$?O3$frd02lASIa9PC(9?m zi#Us`xQ$j3_X_=$?l2S!CktiuTwI(i*CIL>i{3HUV)1S;Qkj@NddR2R{zd)n*!)8f^4<|p*?zmRg>XJ|%roZ%@_!5u>pamUb1 z={`eoamrA1oH8_PoH8_boH7(Irwq-SJwRyIjD+TkM}}g5+WVHLMg6q*T2IRc@62a% zvFJNPQTW~#6blCpY37|F%{tDIPTm>Psmly0-b}1p9a)BOqJT?3hsnvI;MquUW zK11`O2MuZFwV}CqmQHF2v4 z<$O1_45~P5D0|PxDnm+~v4)gz)=>6%YDfcT4UMj|42{cQL*u#&8kfI@GR9d`Ns+M^ zWlU$8YZ>FL;X2BjZ)rg@?ps>Wyz4AOnbcW^^z+wHKKW}X7XBKFg};U(;;*5&_-iP) z{52FEmkq_pWkWH#FUl~N4MplaHx#cfGrWr)*LuxVk<0?G4aKO}4EOO6MXlouMeS@i z6e$l5MaqLiig<7+QcfI-lm~}m7) zn)IxpDEN0M7XBTIh<}G7;^LwC(yfN#;^?8cIC>~9ds0zc{vO4}-9yoF_fTAV){uU_ z9@5XRGw%^0HPc^l@6)0UlwWe+enpeHKdI*s5ZTfv~dY> z7b$cq9m*%K5UJIhhVscVM48l^hBC<|M4CB+NG&%IX%hodrSA-7j2oz8PMeN1ls6q` zNR_@bltbSRgH&+|kt!}B(#9o3`Q#5GZTvx`g-eL?$sa^I{S?hFuMnx#YlhTv4^bw$ zhe)&Uf4 zP9@5`pQ2d!l_(Z|C5nY>iC%Yn2QO#EEa*)`ad9fqT<|DSTu!>fQxp-W5=F$RL=o{Q zQ7oKF6bq*kMZu{=QE)0zEb5Oa7EUFKg;R<2JG~wk@iMNXSRPJK7ZC>&k5NQA+E83h zYesRsFD@q{yEbdO+fa1;O%xZG6Gg<|M6;vE4Mm|cj-udiBK^AC&|JLl{fr(rp4L2y zhzE+|(&L6=(c^}q;EE#s4`+3lmxmKIycgw`qM72EqF8vQXr}bLp}6>`C@%gfii>lK z=0s;6iczN#njOw5ijH%NW=ih@T5q}pa2CaD-#z{iMXehSJ=Pxfo}1H$o!9cfbwzW^ zdqsKRx}rSTYl&vl&Owv`PAiI<(~6?zw4$hatY|iQtSEMFFq&EahcdwFLK)z4px7TO z{W746k5eB09@h^QT+ylFp|~FEOvkQ8r!InK{Na zilWdfhgKbT70m@-6-B{UMN#lok!Fr6(#%msnsvz`%^Vk$Umh#^FCHt>%wshl)as8z z3U$UIg?i#po_Vb3*?`B2bn;kHhPkLn6&Dq$;-Vr|6d+YxRP-}mDo(1b3N9*A$V)}} z^bI&@ZE#ePPW~xU$T>yXiiNL=BI2u}^{fL9tqQ&>ip#l$DF573 zlzBaIC^{Z1`WNmhdbau6vyGlO*Y|^e_4@Kx&$oXS-Csq=f%UIu$N7h7c6hQVQs*C{ zcsa8u>c4t+<YGFJ$c07ma%oY#`sPr)yjm0^ z#}-AwnMIlB$s!GWSTrK<)xHpa^{ou>TU{ILuKe7UL++|wBksvvMKN+$(fz*{DUa2) zv3RT~QXVV1KaUm7tX@16@3bRFB(7=Gi-#iRz5Y37ky_rXXIs5uzJCXutH*7`LsZx2 zHlp41%b_3DvAB(>;-XIteeUNxqEC=I*U%0`E+l%7%!Nd+{9H)%>`4uJu3C;YiPkA! z^3!-NH}0xCa}2#s_zS&bs2;CV3{{{xeMmE>4{7G~A+tMM{grbR(cd~p(JQX3^5D?Dxo>Dy?8h@Lic4P@$}ryzMaOqT z(Q)6<==&nlPwScz&k-nZ`$p%%dA&E{p%FQ8u8qryL!P#_HfzUL&av4!c4yCb{>t5s-R;=j zuEt%xkD*`x7t-nEL!|a9wY)ahR^U~d`D?D-^SU|Wthts4J{p<}4jQ^A?+o4fI-MLe z*VYo(45_{D{!Tk|Edx5dywkEC^m(ED`z{{5iRPV;hGNm}g~sKhp;(+}h$7PGg+}L^ zc_(KSJzQuk-Wke2?+iuCJ40jno*lHtxMpas^>E?aXx?uckzeLo4!LIDI~tc$hE|&M z578*xF?4^v7>b1phVIP&LV4qMp}alq&U_!&9&H>SltU*CqFLkbps_eRXhhBq${}Y5 zjn2nGIppKurzkqTPDlx-2G>z;ebWt!_m`CLZd}vDyFvHU{e-mfaZt|rI7p!$D5Q;> zgA{Ue&@6CskXmjIdh~fMM9R52IBAx>UwReg+Solw`LnX8L&`OUdZUm+y-`RZ*9Ix% z-5{O38>EwWgLHCjkWQ`*Qs{LWDdgH9h5DqBP90KcmY=7Po8y{J=L90Px~0(lI6Fu! zX9ua(GlkUhcaTE<4pPY9L7C+5Af4`rbaHu+T3!!Q%j>~eoX17HjMmAEBGN_W+GCK* zgQs|oBI56$i1<4wBK{7Fh`)m}&(lE>@pMq;c{(UAo(_u3y--Bl92AkBDZGo$9^m8n zyk{=BHb^?bn<18HeL+U#*0DPcri#DF9xa73FXr!4SJx^^9kn# zt%P68A?L+4J)9S$$G7kxB|I0DF`f%j#dATbbUz_gb}^!rAReTR|AG|qUr_eAE%@J} z?ryn_>*&I8s+@zI&KKRS+XTcAVVMJ8d8NqZX@@Qt4u$u zJ%umj_ZxxW?A5(D@zZO154C(2ls9e*QqFThv(IfoQSerfe%=boDu)F{!Dm6S@L5nq z_V+_^aa&Mad=?ZDp9Mwa(=duiKNO0H+kztEw)k!@3Qh{r$u~hdxhF^`_XH{An;?Z8 z6Qqq}g0yi=kTzZk(&jTdQpF`fs`Nl1RlE|U&CY(f3T2fug0$&`LfZHvNTGfxq>w*? zw7GW=${S|{Y2%NejOmR+syHJ^)m3JnKjQc_q{@AK&|K?{LJD<7AyszmL#ntWNEJ5( zDe=7pY2bq(C43O1gd3v%@-U=?4}!A92SKyR0YQ57NugYEK#(5Z2bw$H2bw!wQAnG8 z^HF|$r$VauAV?J-L_KI09)%Rziw`N}jNn;FCuam@Pv;blq3r3OLYg@vD3ki9P$u~! zXx{iEC<^^kC<^=Xp(uDID8qK-L$Pp4P%Q828=tC{D0n3(3jJ0{Kd%I-<&PlEcIrc# zxg#`ZrR@`#{=sY@yt`*AG4lspW$p&3d&^ zp7m#;40AnDhPfU{Grt4r=LC!^l)G3fQ{sq#*xj>n8KL?ag&IK+)S+&PJ z(#fqrI(ZXFCszU~8ya|+5-UQOjp+NcLP@vqpiXG|aQ=qJJC{R9ok0suO zO7Sv04Q1FKBxnuTuL6CJ;wd2II=PU3{sPj^UqJf#3rIhI0V(GxAf0MnD9=0vq?4O~ zs#6>UH7aUdN00LFI&_qOSAyfC&@Av5P(-foM5~3HfES^-Tswy5WxDQ3bo>Pr9cKZ> z#aTdcaTZW?JOwl(oGuiZ3Kxn|4I9mf>MV*^RS&me*W^U4o`hD^R67xoZ|X?7PxnZ( zPnSruPftj>cX*`SyBShGy=KsCU0~0KBd!6`$uB@Uxdtf1oB})xhftpFs)rQn!$Jyq z1V|f?0BO^Kg|u-EP*%AHNFl!f=~OX9nm7e0tDFL)Rv#A1o(?RemS2FYkXlXw(rNcR zlu1qj(x&$csp1--8Rr@xZCnGSic^68#VNp6C5Jo$q>4L$ROz%rs`OYPZ9D>`jZ=UW z>Z?LIv|}F1p6)87lV5-oat+WdtG6PxyaS|`cYxG#5X}8aNHbpmY32(c<+`qravlLv z&KE$+`2t8eUjQlR3!n^h2ata50LrtjE2Nw z(PM??S`8m%RV5#(Qo~0|bXTE#s@tPX>Zn55Q?W$~w+r{1jN2JMWc29D~2`fkv*u`1r^`>2XH`bMJGjXvk9b)&J=y3xJ9 z)Vk5@vGLGa)^~$^7*+1i^=fN$oi#|Uo!PjF6h6*Rb+tHl?YW9Ky4qUB8~gdx+7%6{ zRq;k@RlJc}wQi(VKMNZ7ag?ijJEmOq8|hc~M*4NNpzP^n!6Bqm_X<*_29C6;ej`;n zR?z5b-6(Hr-Dq^RZZvnx`VV__dDFLo)ahG6nLLdiyQ?{tF+D6OW4c$69vv%4kA2lp ze(a@&ROwqmdQ{Po67_R5kE-Zi!Rb*mM>%u=xsq7RMe4% ze#cTvcPuA5Sx}zN>oJs#^UQ*}x?`iOtD_Zrp8Tt;J2vilMpR>WY(%d?x|HR4$S6bR zeaKiU?H)JRLq-{r^C8(DGS-l>hQvE0-XS?3GWw9whr~N%_J?G6NOVJ@TV?cBMqJf6 ze0>q=WI++Bz@rtVhXqBXhXrL)4-1M;O&;Y_WgbPUGLPm|W!}{TW>aqqT35PSP(Ib< z(QN8%LG!2rkH)p@8X8wM9*xVRMdR9C%{2=CrtGeUM%2}U;#HGJW2wfYsP(X*^V>@e zo!R>tibx&aCmZWz%=uO09UH|xiO^X3R#0wL=Fw`gml_&Z-wKLU-wGOCl^#XMbw=y+ zA{lrZCI6`Rlh5h$@EOao8a~pdl8@Gv4i2PHJs&C5$AM-+?*>w) zHjr{%8)&9f`_W9P`J-6$ZlG9EsG;0BQF7NHcc;Y32_2K1{7{3#5}rfbz*B zKni&TNTCi3q)=A{$|R2fY2yx{+2;`;g**bJ&`cn0JOZSOJAh_iKLt{#p8{o4R|Qhb zFF*=81xOo@0F9%Q0_o%qAXVG}q{?+vNEMF&sp1hJZ9D>`kVk;#+FgE-9_|3joBh*} zDoz2?#v?#_?4pJ;#xFqHd>cf1I0Z-#rvT}3A0Lz}P65*MHhJS0IF>g%t)aZ>n?SRy zZvyG$9Uz_dSVKB>ParMa1f-ddfYj=zKsodc7AfZ@Am!Wyq?~tvlyeY}a$OZjv#tuH znRkFR>#9H*<{%*D90ZhM4g%88K|qQ)2xygZ5KzuJ2q+5O7AOkOMp5t)kbZsv(tI7w zTm#26>##tYIS5EI?*OUg9U!&3Dv&~c0aC~>KnnQ=?rq*k3DikHjIzQ5>!jE*S^P}AABS32H)rK^x{G$x3ogwAA36OFw z08*~Pk8-Z6k8-ZIk8*Cu2$XGgeiVhOK8ixu0E$At0E$9YA4Q>_kD|~ifTB>xcYX(I^(##g4-f7XZb=1wi@d1)%lA3qbkTL4ac62%uQ> z5ujMO11J{m0E&f2fMT&@8=4V*0h$qewV{Z(1}Gw~0g8xgfFf%3Tm#3V;2NMP^cSFc z(O-b(!d`7C3JwB_f{%doa}bbbJF_9p90a6U#{p8yJ3wkV2uLjl0jcF6p!|2nIS7vZ zi-Ula>mxuqIR!`?rvNGB6rc=q3XnD)0m>v_0BPe3AXTm!M@sktXmmXSR)Ac&&L1gp zRX-Y+7l6j)2%s!+1ds+^0Ll_a0O@g6Khnb;K>6VdAXO9~ReS;TnCtUDSM6gK`fljj zd!)ye^XL_2R{z73@FKh`auCqt?lOZOx6c^PL(kzdpzm`>r5}BI;xeFD-=mCW*RL;i zUcbwCKxgJY;4*YAHunM5P`MB2jt4vl^o^effxe${AJFLB2c+R)H1Hi9TkA$btBK=) z@@LO36pP)u(E07wh0brEE)`3Mf*Z0*aBFV7E=G+^YrYaeY2orQ8Ih zgr|U%xEdcR;Vd8x`~{?hzku}c7f@#S3rG)t0cGCU*sA2;-dQMPyauGrHT*~+#{nti zJ0OMJ2c+;k3V9HYtw!zx(&Gw$lo{9dqtQ7LXmm~l%F>XT8ZtU3!Xw7zL7>d=AW&v_ z5GXT4VjnUh_rW7#7Y~{j9t0Y3RkMWF#wsJOvO-oFca^AD8GV%zR~c)SNLQJKRpMP` zE>?+pm8e%4z2D1Me~c^kbw*!j+;wzuB0MfqegukFcL0i%AAvILUNC6w@gPu!c@QXG zXT%;+w)G33Z0i(2e+!%lG^cjfLgQ`{k&Xbz#^Ohy9P%L0nRNu9d~zbt`S}rO6ix&h zixYuH;Y6V5#^jR|;n>=?gBH@DcL1#@-UN!8H-Xl z0%_)1pjqHtAmyA3Gz&&Tn%%brY35=e&HM|blV^c`k7t1taxRcg&IQuRxj=sfdJ~XZ zE(TJ|#XxF#8AvTJ1L-sp(#g3%S=F0>vdYCkYIQ51mB7V78RlXj{ag&BpNoO?^DmHc z{smIYxj+gz7f2!J0_p5e`OfHAK6w^C_n(Axaw3p6P6SfOi9iau4@e>R0V(7@AZ_{% zP*%AQNGJCJsnvIY)N&t?TJ8hV$#+0H`3oqMoCTy-uL07@SwK2D3rHtt0iBhzfK~!$ z0cqwhAkF**q?W&c)bbaQ&c2$ezc1-Q@CcpugFIX0jc63 zAUzxeltcXpNEJ5$Y2zs%ZF~guSMOX%n|+^f9v+3qq1m_Z6Vl9C!1GXU?ec_w4|%pa z5l}4r1r!T^0mZ^!KpEDFfFja~fMVem3`i}P0jce8%g*JPX8j0AImZF5 zSi3VJReBJRD$W8@#aTeA^c^4#+ypdwU&-egj*ZAi@LgSgI0z^|c40!9(Pe;RNC`Iq zDd8p{C42;=goA)I@D7j?J1?P`k~^e?gP>kO2?qfw;UFMAyaO~-dJT{segV?MH9&f} z21pOr07b9k0L>0}0L@5OE6k;1s<;E{7c}T2Kr_Mxz;!4yTmYnm3xJex0gw{)f22h3 z02)pGAE{FRN7~f?QO0zYBb}a&v|Z=#RM&uGdE){g&Ab4loFjlVUnhH90LL`zBS4zD z07$K_0i=@)fE23#BZcb!NT>QgnqSp^w4Uvxgp}wGK$+AXfM!#708(WSC8UZYfHJ9H z0If8g0!SN20OgPufK+h=kSfrO66t^JXZT0R0& z%SS+J?Tmz09UlRyxZ6HWor%p*XWIR!{LrvNE;{XbI9FF?xq1xPt}0BPn9Ahmn} zq?03nw7Iq)X>)BqS{qY`w6(ztKnghmNETyuvqsoIZps`ewD(^Vw0H+lGUs`ewDs{JT?d^R-i>ikHf zDk@T|u8cCNwujWJ{UEif9Z2W&y`0YJdlH>K(WAMZKK;q3&mc(W^ln4p^r}gxzk8(9 zTEkZ7NcA2mRJTWSt!|H}A+>7wNUdxBQ6^pOj})rgqZwDRM+(*Lkxp0sqkO8~quE!z zM`~5?ky_Pzlw0+Bq*>h_DR;jWq}(X|oH;rASO9zoCK3!v-rjw*I^wbxO_j=o8_s|fl$ z$TdLMGVl)2Yp^~A^mpk_A~$t*8aN2JFaA*f^OvBmuZsa)dF@^ys8+{8Kv%r-5s)ff z3`m1+1vI)o1vEPE0IgkPASHSe(Bq4o)BQdii+YhWFA^yS!6Ra{Zx6l?y?^o%P`33r z;4)Noc1L)0X08EJ&NV>!bhi$4eog_pzJODJeP*%n3y@|bp;f~vK;!ZY(71XTP$qc? zD2F;4&@6KhkT$LX%BNliq=a99M)&uF#?`Zc#^oKLQS>RGu}*V-T?vjwsy6|Rr9%PD z1s?%rRSamR^dsnovP!uLD7V}M6r){z(CB;w6dfM{MaNA*ndc@TJ=_EoF9!i-UM~}h z+Uo^U#Ye!~A~yl4I!hjOC^)8#vw*bm7jP3&$X`I(_zOteSyXWr9AAaj24?{&Q7Eq+#Ine0b1hgL3(Xft&bu{o7Jnp&c`X9>t zI-{>M`Z}YpGx|E?u9Nw7{!-R?l~_l^I{9BG|Lf#oojj~F3(n5zr)Luln`qcX!zLOw z(ZF}`9NBPp50rV`5GVusAkZ4%M4&uyBG78o8G+`V6X8>fdFMf(xv)bK%7C5-H13#j z`4NuI1wR7Kf}M-dYXv6)jn0Wc8aNSXJ#Zh;?C>3s9(U-tsqZ9IxsN>3=Dr(fT=(5T zvAcIX8ka+X#&WL>6t8=2pgWkk%f?MP7nJL~Kx6SNQ0#mPG$Nk@jmW1!<8mud)I1B6 zdCmpO0OtZ_KvxBt1SJ+XMwVzw*swI&IQWG^Q;iP6^_jj=K`IBbAgm| zE|6ND1yZZe0;%O(AhkRTltZ2c(#*3!n!BUbwGNIcHy%>Xvp||Jqn2~wSZ?)SAm#3k zfi!b5P=@&zNHhNeY35%b&72FQmS=&~@+^?f?zwe!h+{g9fvr=9`4=d+oC~D(Mbz>y z98;?o12-Y%{0o#}o(0m(vp`wpS)kl+n4Wyi}ft2$#&E~!5{TvOXUzY^Z&)q=l zp}##kujAG)=k70$H0z8&%DELtA-4kQ;Y}btya|+B4h7O?mn5W09|Y3Fr$Bo8d#p1$ zriW+Yo9)9;Zn+gGt9%NSPxqcc3i%XBA)f-}P&Wh`foFl#@+pu`J_X7cZvrXw{R*k# zNBE{ql@17$F?|q76`um-O&2{puEwI z^7b~L=Q$dVY0wRUl<0jxN_ZJ4Cp-%@BF_TlfpdZKz`sBluvZew11|%uv95{uO~!3Z#T*ft2tpkRF}|${4o-WsF;a zRB&q(Xx=#&NVyIOlu0fI($B>}`necL zKNkZ<;n^q_UIyC#ST_WUNH+wE#jZyv3cd!?&)q=EIT}baF9T`jXdulT4WwD`1JbPb z0jcF~Af0>-6+=om8b}E*1Lc;NfpW{sK-zd2X!dy-NT*H*q*IRrQpnLj3OO1`8%G0W zPfZPFkC%b6=dKE9m3~SN`4o<2k6VFbNTKcqq>V#?RB0YCvu!|9j#hnpQMD{X5-%fZLC^}vS zijJ3oV&r0==r|WBE}af2E}af2E-nU&NF5VJq`Lt{WFK*LWclZ4AkDlCq}lGdXr1VB zKx%b5pw+_NKsxyvXl?K^kWP*U(mCzUMJHba>Fn##9XY16_hmWk0;1k+g&g*Na4f?* z8jw!D2GYshKnnR9D63P~sjN=DiPj8v11aZjAm!W*q?x;clusQPpK~nFj*xy%hnler zPgf8xb1Vve2g)|T1L=1a9#Vd|-pVok{0@|7eg|3=lk-nG?;0te+*iu^9Z31)#?b6P zq*+ZGtp{~Pq;{&V(LB|1XjUD;O-T9lU6%goTNmZiXK?y`W<)vn-i|bTmq6>pD;ZMm zFApiVF0eD*+WngYf^yCQK~eBNkWQ`#(#h{YYnb1GbaFb7Lc1Fwh5QbrQ~v_e#_2%X zI33t(T8UQ-?gq*yM+2=}yBi@@?pA=-Esq1K;%gvPd<`_?dKr)^jt0seM*}J3Wgu<6 zgH=0QlzGJe-&U0!X>%|5n|fWa2HejbPm2G{`^Y~t3P`im&Bj%tL2$ zA9nPOpI3suvvNt$cNZ=R`i#jRL7!ImBk1+=sI=lXG$NM-7a={o5^IikVV5UV-{p_s zI^2XRUhZ*#ROz!ok#b3p23`qzKj)aB*F}yAQe`~kNQN~G><;8>)O za()hrdxywBhXqw}_$)}9P7QQ6{Tk>z+!myk+k$;I@9;bqq*Lz(x<`cG4SXER68{C| zL>~vzz>7hn^Iy=odNKngu&Vp_RaqK}vWrXmtJy8eNwM(!hm5bHR&2dh~Z7Jvuv3HuQ9$(K#<@4RBtN z5*-|9X6zh=#^tu4ak(vMTzf{L+2^yM4CviJqw`!)?A#VKdiT!pupL_uJQus~8GT3w zcrK332+sxS;kh6sJQtJ!ZVSqQJ`SX3h#osiIhGCn3({jZJ)}fW2g-w<4y1t>gJy*P zg0jJXL8J3u(CDj-&TVmQMBN-{Ts<9VT%Q$C?CZqNZEd-}ToSm)qhKfT%Z__f2Bwzj%Zmo(od4iIPo}Y?6UZR>CHF zHi>a{5v*XU`U*pAmO()3L`j#@QN1o=rl{@3u zn&HSGJscS{mOGxKQTkp}PwU9>uIMi3t~fCZJQp;go)MIPE(}@&To@EP7Y2>Rg+Z%= z3xhJig+Z}%VNmQ`7^IC0gEG+jUG^0)K6`nDS}u&wh}I1M1-(}AT+j;PyrAFUyda%+ zwL&`iFGwf<1u5jbAf5adq?7-GbaGyhPM!;X3F$PRnT#!!A3!a74+U*Ld<+-5W z=DZ-yJQt*s=YsOdb3tl3FGwx_1*zq~AkBJ4kmlY$w0nd5x}yHHZB(DRY395jwVW5U z5_m31xy})!ob!Ut!GA&7=E9&T^p7C@ycndM7lV{@VUSM#3(9SO6X3k~J|MU5OOAB9 zV+GQwiv+3SzaUlo7oQ8 zVH~YhUJTN#e*|Tf7lV}ZVvurP3_3S22IW)#2-44&L7F)-D4)C-q?Z4J)cRI{)bd$S z_V_GF51$38;rUC$|MgT zq>XQawCVdm+PEi38{Y)whhu_NaZJ$M^*soC$6?=oJ!01ECFNT>ZTdb?uH0z?%@@Z6 zsp6O*RU8wfierNGa7@q$_LV}j#y3Fyh=@7wRL+gs4f^_=$|qL^3)0DdL1Xe?kXrr=Qpw;+!mBEJ`2hf zp9STL&w^C(S&$wM3sS{fL9y~vkRDD7$_yt3&7fx>Jvu><5?%>zLP|I$NQoX0q=93C zl<-Z^d~rt5yl_U)=$sLh4Ld=p*~tTE1dYoLK_hZN(2Q_E&{(_=G#2jzMa}gxU>wzND z$AKc^eV~YVA1ET;2Z}`p2a1IQf}-GnpeS^6peXntXfC)RXfFH=MWmYp<(vb8bn-ip zHXR&D8>a*1nbU!?%Hu$zb2rfFeFc11hyB}*GBReTCX_K<8)$Sr8Yp8N4WxvZft2tv zP?qe-gp_bDkP^-X$_dW`jjt~QDX}968hzUF!hB8p78rf%r#D|*38aK8ft2tjP-b`& zXx64KN!oZ5Xx4ZWNa57yBySuFq_cYlRQVm7Dc%H9d$@|$v5ZYuILg)Gsx-&c9+Ua|Md+rFOj zt$ub~CsPtGNW#fGNW#fzCY=tKuXl=kp{ak zp*a$*zdh$ynMY?1uJWA}aK0_8zX9*wT|0clW;M;cV)(R%AwH@Ws2M}rDHirs!nXmoXWG`ea$8rR-R zXfD*`Q8rZL(Ojs;rW3n-3cE*f8W+jZ#FlO{I*%&kWn3XU_!r;;d(yYdgG^@0uRpFBangx}1q}hEXkaCrF zq+E9c(yZ!^G^@I!GpV{G<+>h_aus-#c@=mRh1xrcLhT(zq4tiVPhLHQb$E0>b$AquIy{O+9UjG^8jm7UlSdJ$ z$)kw$N1%xGN1%w*=TSu6@!MC%^yf}v`}8>rkHX_njJhXKjB5C3zI0Nch}?Ao#ifRi z&Z>Hk^sCY%wR$CxTD5wlR>dA^?)#JVo}}HMtZwgdvmjG=8~Qw^hL6;$;Ul%G_h?4+ zQy}Fk`Dk9$^O1h_d=!OxK8ivmAI*qLKAI677AQLPd=#Ay3lyCW3lyCSKbn!=YqhUW z>d*Z~^66g`IxNt-a+hkPS+yT&R_#ZcbyXnEYW_&GIzLjYlLBd0^GBN1{E=ogf23AF z1yb9c;e8!de?L*}cTE+w`YBMhRr`@zHGia5%^&Gh?MFK80flm_=8x2>`6IPz{z#`j z3zSv+K_Q*I0JP5gN-t;hJ&HnI6-Xgp0A-agfE4ltP(JwrNFgr(osSoQ6xss{Y2yeW zg&YBtNjpIyow_ZM&fZ;@Q{dRz?(cif?iw|@3;0qund;v7B`ac?7{U2%I z0w5(^0HlNqfIYgLsQ)7+c8EfHbX6c#>i=>Wq+AyU(yacE zG^_t3&FcS1GZz5ODK7wN?rMVhaP6b4as+T0QqB=TS#>W7q@N>zH1h(`-v}=N%{WH@ z<(U_NM&kt_s>WqBy3s63}21ql%0IdOj0n*GbK$^J* zNVDz?q?vbsvdTL^$~g!~vyKd;nU8=p^AXVOcm2q-UFS-z&I_cIn}B9q{{>QOk13>? zvw(E+6p%Ju7)YVc3zQZ90@B7`K-#zrD3g7~t!JohQDt{2q{_ZhNSj^^q>b-@vd3{i zdE+}EJ$wh0F+CSZ8{Yxx`4~Oi2gh>7cR(5ITASyoxY5RIKzZXhAcgKRffVY(Ksxne zAhnzbq?r?elyf3bJ~E}Bj{oDr>1@{5z>>AkV5VQQt18>NFgTzDb#0ya?6iE3iVl_ zOzNsYdE-7HRon-p>TtI%$5iR0Ky$5=0%_AjfwXZVkScxzQpJxzs$AKRtxDeXP#}fV zZs=Alw*uu*4+YZ9tw8zYRv_iv3Z$P~ft2$pkaC?AX!f}kNI$m%<(6B4qTp7bD5l-5 z=;t#b{dToM`lsDl=;vP`{kkep6ubhmz$3<#Y8BtabbuY)%s!X7K9=;PhwnBWfL7IIMN1A<_ zLo38*5Tx9@C|V(2Ymt6`{YbwRjnj&7JVo%WD)LsTz6ox}v+y!}5&jgu3}1z>!#Cm2 z;Z@jYc$eer@O}6p{3ZMtehS^eepcG1-K_L}IQ~|g*Nh`2^O{qnWM26}O6HXxq-0)s zKx55ojiIsTl?^nOUJN}ar{NINxhy{g7vYbgD3;~zZ0p&6dRo7So^x6b3wq{hp7W%h zyDi0@e-@tSw}$W{bnWQ2@=K385>lwDgW^@IL9wWH;PX)IDggLf@nz)+J;!%ybT;3P zx0M}_`#x)rFtPZCg);mm3SE7)tyLvsuK7Xd@tGNEc$a7T)Vi(T_lT=d&?r7Ool*Y1_n}$yuD7k<_lQ?%yQJI~{pBLf9I$QuPo(A$s$Y0q zmk^qlyLxO}SNh8EF310=40zt(!tX=(Cvk5SJPq{+%xd27B6Ov&zXg0AUWR=(wUb$C zz*phx@J;wOd>3Aa@52w_$M93A57Itv*u78fHGaz@JjPjKnw8ggTd&~GY5m+*W{qf_ z+*X8W_HRoK4Jre-HM8`)GKzCK3!T$v_1l^$W0|SjI-|4sY=E-iz1v+}oS6!AHe;eZ z7!zf{n0OV^X-w=hh}~%D%tk=5Pyf5GBOWMM^(4Fq?}`uVckk-&_jS=7XYe@mO#M*k z`N#EFiB^M|wm#hD#(Y~P&%(>_MffuGH?b)F_%^im7a3Pqk>g*(-@?zKz4ok6>{knC z_E&{^*sNmf^14U`QhQf(>Oa4`&*S`D$D-KRUP0K;+gBIdbv@_4o_$=jFCWgsAHvJ< zWq2LBMn-1t^WS~xTh=i*^S;*oX?Pxb#2#h$^|MV;FUEZxIrgfB_62tbXLNq|M8J=s zvDDuA-_Jt#tyK@lH{tux^VPc1-}hzWx{OAzejYKF$}{>c*L9=cnw)jdRP{v)ReI6$ z)ol6hp5y9h^c>YxbY?YG6pK14((lz3y&5??=iYf#HPK^UZ_#;FEKyuud(j??UV+i` z)eq5g)bY^cs&?oMs&K9hco9};*>Sz>o z74#gh4Ctp`?U8=94%a1kj_L%8)ayTbj#qwHEgXk3tYUzadxb%&eBZ}@{#_mW=8n$n zy#t-udk1=cUkTv~I@d#ZzE>)gCEqdia~l0qR*vt6j?IyG92A!;&CvXM4?@4|od`YC z`w@D+Z(B%-?^bA)`gVgJ_u7bl>irA-mQVh@cfP(`f1x*7+jjqQ?5AGkUDM&Gx>C^N z-u2K=y~A5~N1+&}zhKcFR;6Q_%?45^H|VO6U9z#u*>;(iT_W}V=%?b^*C@Z&^Dc^3 z^6z!V%kW+Jp{R1QE5*z3N%$Ur1Ur=nK|^h~b_yIO4?@#zRD^mmPZ%ik~Vi~d^CZ}~gL--`YoWyIsJ^GttJ zyZSrwe1B8BI-_HMJG=V3FrvSgUH#0lHHm&|O`;L4K=im(ho6hq8+zRL_g&VHo#A>u z{M2%H+-imsfy_4c?@g$FX58c=Ac#d9O{JHozk35bt^S4hAm-jGA=tsZny&WHf zlz2}>O1$G)xt`-a3XNjT Rga7^ayBz%M-+#&f|360Wc0&LF literal 0 HcmV?d00001 diff --git a/pyrecoy/.vs/pyrecoy/FileContentIndex/5f785a9b-4ecf-4815-9457-ede32ca8bb05.vsidx b/pyrecoy/.vs/pyrecoy/FileContentIndex/5f785a9b-4ecf-4815-9457-ede32ca8bb05.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..70aef67a00f5a48bfb0d87044cf8f151e2685b5d GIT binary patch literal 107 wcmZ>EaTnxZU~p%E02V0C38Z0cW+XOHDO{Wlsuo0n)bd05(ok9*N*hCI0FV0t;Q#;t literal 0 HcmV?d00001 diff --git a/pyrecoy/.vs/pyrecoy/FileContentIndex/cf3214f8-06fa-462c-9ca5-e67ee6237457.vsidx b/pyrecoy/.vs/pyrecoy/FileContentIndex/cf3214f8-06fa-462c-9ca5-e67ee6237457.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..70aef67a00f5a48bfb0d87044cf8f151e2685b5d GIT binary patch literal 107 wcmZ>EaTnxZU~p%E02V0C38Z0cW+XOHDO{Wlsuo0n)bd05(ok9*N*hCI0FV0t;Q#;t literal 0 HcmV?d00001 diff --git a/pyrecoy/.vs/pyrecoy/FileContentIndex/f607662a-174d-4632-bc3f-60cd06b08d1a.vsidx b/pyrecoy/.vs/pyrecoy/FileContentIndex/f607662a-174d-4632-bc3f-60cd06b08d1a.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..70aef67a00f5a48bfb0d87044cf8f151e2685b5d GIT binary patch literal 107 wcmZ>EaTnxZU~p%E02V0C38Z0cW+XOHDO{Wlsuo0n)bd05(ok9*N*hCI0FV0t;Q#;t literal 0 HcmV?d00001 diff --git a/pyrecoy/.vs/pyrecoy/v17/.wsuo b/pyrecoy/.vs/pyrecoy/v17/.wsuo new file mode 100644 index 0000000000000000000000000000000000000000..cfe34f113561824780d9ab2886d9dadd63a5c81e GIT binary patch literal 63488 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 literal 0 HcmV?d00001 diff --git a/pyrecoy/.vs/pyrecoy/v17/DocumentLayout.json b/pyrecoy/.vs/pyrecoy/v17/DocumentLayout.json new file mode 100644 index 0000000..d4ecd3e --- /dev/null +++ b/pyrecoy/.vs/pyrecoy/v17/DocumentLayout.json @@ -0,0 +1,100 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\shahla.huseynova\\Documents\\asset_studies_recoy\\asset-case-studies\\asset-case-studies\\pyrecoy\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\shahla.huseynova\\Documents\\asset_studies_recoy\\asset-case-studies\\asset-case-studies\\pyrecoy\\pyrecoy\\pyrecoy\\prices.py||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:pyrecoy\\pyrecoy\\prices.py||{8B382828-6202-11D1-8870-0000F87579D2}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\shahla.huseynova\\Documents\\asset_studies_recoy\\asset-case-studies\\asset-case-studies\\pyrecoy\\pyrecoy\\pyrecoy\\data\\tax_tariffs\\gas_horticulture_eb.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:pyrecoy\\pyrecoy\\data\\tax_tariffs\\gas_horticulture_eb.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\shahla.huseynova\\Documents\\asset_studies_recoy\\asset-case-studies\\asset-case-studies\\pyrecoy\\pyrecoy\\pyrecoy\\data\\tax_tariffs\\gas_eb.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:pyrecoy\\pyrecoy\\data\\tax_tariffs\\gas_eb.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Users\\shahla.huseynova\\Documents\\asset_studies_recoy\\asset-case-studies\\asset-case-studies\\pyrecoy\\pyrecoy\\pyrecoy\\data\\tax_tariffs\\electricity_eb.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:pyrecoy\\pyrecoy\\data\\tax_tariffs\\electricity_eb.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 6, + "Children": [ + { + "$type": "Bookmark", + "Name": "ST:129:0:{1fc202d4-d401-403c-9834-5b218574bb67}" + }, + { + "$type": "Bookmark", + "Name": "ST:128:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}" + }, + { + "$type": "Bookmark", + "Name": "ST:130:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "gas_eb.json", + "DocumentMoniker": "C:\\Users\\shahla.huseynova\\Documents\\asset_studies_recoy\\asset-case-studies\\asset-case-studies\\pyrecoy\\pyrecoy\\pyrecoy\\data\\tax_tariffs\\gas_eb.json", + "RelativeDocumentMoniker": "pyrecoy\\pyrecoy\\data\\tax_tariffs\\gas_eb.json", + "ToolTip": "C:\\Users\\shahla.huseynova\\Documents\\asset_studies_recoy\\asset-case-studies\\asset-case-studies\\pyrecoy\\pyrecoy\\pyrecoy\\data\\tax_tariffs\\gas_eb.json", + "RelativeToolTip": "pyrecoy\\pyrecoy\\data\\tax_tariffs\\gas_eb.json", + "ViewState": "AQIAAEMAAAAAAAAAAAAAAE8AAAADAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|", + "WhenOpened": "2024-04-22T13:54:50.515Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "gas_horticulture_eb.json", + "DocumentMoniker": "C:\\Users\\shahla.huseynova\\Documents\\asset_studies_recoy\\asset-case-studies\\asset-case-studies\\pyrecoy\\pyrecoy\\pyrecoy\\data\\tax_tariffs\\gas_horticulture_eb.json", + "RelativeDocumentMoniker": "pyrecoy\\pyrecoy\\data\\tax_tariffs\\gas_horticulture_eb.json", + "ToolTip": "C:\\Users\\shahla.huseynova\\Documents\\asset_studies_recoy\\asset-case-studies\\asset-case-studies\\pyrecoy\\pyrecoy\\pyrecoy\\data\\tax_tariffs\\gas_horticulture_eb.json", + "RelativeToolTip": "pyrecoy\\pyrecoy\\data\\tax_tariffs\\gas_horticulture_eb.json", + "ViewState": "AQIAAAAAAAAAAAAAAAAAAAAAAABhAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|", + "WhenOpened": "2024-04-22T13:54:38.231Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "electricity_eb.json", + "DocumentMoniker": "C:\\Users\\shahla.huseynova\\Documents\\asset_studies_recoy\\asset-case-studies\\asset-case-studies\\pyrecoy\\pyrecoy\\pyrecoy\\data\\tax_tariffs\\electricity_eb.json", + "RelativeDocumentMoniker": "pyrecoy\\pyrecoy\\data\\tax_tariffs\\electricity_eb.json", + "ToolTip": "C:\\Users\\shahla.huseynova\\Documents\\asset_studies_recoy\\asset-case-studies\\asset-case-studies\\pyrecoy\\pyrecoy\\pyrecoy\\data\\tax_tariffs\\electricity_eb.json", + "RelativeToolTip": "pyrecoy\\pyrecoy\\data\\tax_tariffs\\electricity_eb.json", + "ViewState": "AQIAACgAAAAAAAAAAAAIwEEAAAABAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|", + "WhenOpened": "2024-04-22T08:40:35.654Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "prices.py", + "DocumentMoniker": "C:\\Users\\shahla.huseynova\\Documents\\asset_studies_recoy\\asset-case-studies\\asset-case-studies\\pyrecoy\\pyrecoy\\pyrecoy\\prices.py", + "RelativeDocumentMoniker": "pyrecoy\\pyrecoy\\prices.py", + "ToolTip": "C:\\Users\\shahla.huseynova\\Documents\\asset_studies_recoy\\asset-case-studies\\asset-case-studies\\pyrecoy\\pyrecoy\\pyrecoy\\prices.py", + "RelativeToolTip": "pyrecoy\\pyrecoy\\prices.py", + "ViewState": "AQIAALEBAAAAAAAAAAASwMoBAAAAAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.002457|", + "WhenOpened": "2024-04-16T14:15:11.652Z", + "EditorCaption": "" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/pyrecoy/.vs/slnx.sqlite b/pyrecoy/.vs/slnx.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..72a6ce3310a944243b1db4385f7dbadcec8e0a2f GIT binary patch literal 90112 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 KfWWOp;Qs)F?4@@A literal 0 HcmV?d00001 diff --git a/pyrecoy/pyrecoy/.gitignore b/pyrecoy/pyrecoy/.gitignore new file mode 100644 index 0000000..71db39a --- /dev/null +++ b/pyrecoy/pyrecoy/.gitignore @@ -0,0 +1,6 @@ +*.egg-info +.vscode +__pycache__ +*.__pycache__ +*.ipynb_checkpoints +*.pytest_cache \ No newline at end of file diff --git a/pyrecoy/pyrecoy/README.md b/pyrecoy/pyrecoy/README.md new file mode 100644 index 0000000..6bd22b9 --- /dev/null +++ b/pyrecoy/pyrecoy/README.md @@ -0,0 +1,25 @@ +# The _pyrecoy_ Package + +Modelling framework and tools and modelling of flexible assets on energy markets. + +## Getting started: +### Prerequisites +* It is recommended to set-up your Python development environment according to [this Wiki page](https://gitlab.com/recoy-internal/pyrecoy-package/-/wikis/Recommended-Development-Environment) +* The _pyrecoy_ package is best used in a Jupyter Lab / Notebooks environment +* Environment variables: + * `ICE_USERNAME` and `ICE_PASSWORD` login credentials to https://www.ice.if5.com are required if you want to use TTF (gas) and ETS (CO2) prices in your model. + * `FORECAST_DATA_FOLDER`: Local path to the "Forecast Data" folder on the Sharepoint server. This is required if you want to use forecast/price data in your model, e.g. `C:/Users/username/Recoy/Recoy - Documents/03 - Libraries/12 - Data Management/Forecast Data/` +* Jupyter Lab extensions: + * `ipywidgets` and the [Plotly extension ](https://plotly.com/python/getting-started/#jupyterlab-support-python-35) may be needed to view all graphs as intended. + +### Installation + __For usage in specific project only__ +* Clone the repo to your project directory + +__For global installation in your Python environment__ +* Run `pip install git+ssh://git@gitlab.com/recoy-internal/pyrecoy-package.git` +* You should be able `import pyrecoy` package in any Python script using your environment + +## Usage: +... + diff --git a/pyrecoy/pyrecoy/Untitled.ipynb b/pyrecoy/pyrecoy/Untitled.ipynb new file mode 100644 index 0000000..e196edb --- /dev/null +++ b/pyrecoy/pyrecoy/Untitled.ipynb @@ -0,0 +1,35 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "56a3f3f4-59a6-441f-96c7-f44845539991", + "metadata": {}, + "outputs": [], + "source": [ + "from pyrecoy.colors import *" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/__init__.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/__init__.py new file mode 100644 index 0000000..bdad31f --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/__init__.py @@ -0,0 +1 @@ +from .database.Models.base import * \ No newline at end of file diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/assets.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/assets.py new file mode 100644 index 0000000..d8a420c --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/assets.py @@ -0,0 +1,789 @@ +import warnings +from functools import partial, lru_cache +from numbers import Number +from itertools import count + +import numpy as np +from numpy.polynomial import Polynomial +from scipy.optimize import minimize_scalar + +from .converters import * + + +class Asset: + """Generic class for producing/consuming assets. Specific asset classes can + inherit from this class. + + Parameters: + ----------- + max_power : int/float + Maximum asset power in MW electric + min_power : int/float + Minimium asset load in MW electric + + Usage: + ------ + Use the set_load and get_load methods to set and get asset status in MW. + + Convention is negative values for inputs (consumption) and positive + values for outputs (production). + """ + + _freq_to_multiplier = {"H": 1, "15T": (1 / 4), "1T": (1 / 60)} + _ids = count(0) + + def __init__(self, name, max_power, min_power): + if min_power > max_power: + raise ValueError("'min_power' can not be larger than 'max_power'.") + + self.name = name + self.id = next(self._ids) + self.max_power = max_power + self.min_power = min_power + self.modes = {"max": max_power, "min": min_power} + + def __repr__(self): + return f"{self.__class__.__name__}(self, max_power={self.max_power}, min_power={self.min_power})" + + def set_load(self, load): + """Set Asset load in MW. + + Convention is negative value for consumption and positive value + for production. Subclasses might use a different convention if + this seems more intiutive. + + Returns the load that is set in MW. + """ + if load < self.min_power or load > self.max_power: + warnings.warn( + f"Chosen Asset load for {self.name} is out of range. " + f"Should be between {self.min_power} and {self.max_power}. " + f"Function will return boundary load level for now." + ) + load = min(max(load, self.min_power), self.max_power) + return load + + def set_mode(self, mode): + """ """ + load = self.modes[mode] + return self.set_load(load) + + def MW_to_MWh(self, MW): + """Performs conversion from MW to MWh using the time_factor variable.""" + return MW * self.time_factor + + def MWh_to_MW(self, MWh): + """Performs conversion from MWh to MW using the time_factor variable.""" + return MWh / self.time_factor + + def set_freq(self, freq): + """ + Function that aligns time frequency between Model and Asset. + Can be '1T', '15T' or 'H' + The time_factor variable is used in subclasses to perform MW to MWh conversions. + """ + self.freq = freq + self.time_factor = Asset._freq_to_multiplier[freq] + + def set_financials( + self, capex, opex, devex, lifetime=None, depreciate=True, salvage_value=0 + ): + """Set financial data of the asset.""" + self.capex = capex + self.opex = opex + self.devex = devex + self.lifetime = lifetime + self.depreciate = depreciate + self.salvage_value = salvage_value + + +class Eboiler(Asset): + """Subclass for an E-boiler.""" + + def __init__(self, name, max_power, min_power=0, efficiency=0.99): + super().__init__(name, min_power=-max_power, max_power=-min_power) + self.efficiency = efficiency + self.max_thermal_output = max_power * 0.99 + + def __repr__(self): + return ( + f"{self.__class__.__name__}(name={self.name}, max_power={self.max_power}, " + f"min_power={self.min_power}, efficiency={self.efficiency})" + ) + + def set_load(self, load): + """Set load in MWe, returns (load, heat_output) in MWe and MWth + + Convention is negative numbers for consumption. + Inserting a positive value will return an exception. + """ + + if load > 0: + raise ValueError( + f"Eboiler.set_load() only accepts negative numbers by convention. " + f"{load} was inserted." + ) + + load = super().set_load(load) + heat_output = -load * self.efficiency + return (load, heat_output) + + def set_heat_output(self, heat_output): + """Set heat output in MWth, returns tuple (heat_output, eload) in MW""" + load = -heat_output / self.efficiency + load, heat_output = self.set_load(load) + return heat_output, load + + +class Heatpump(Asset): + """Subclass for a Heatpump. + + Use cop parameter to set fixed COP (float/int) or COP curve (func). + COP curve should take load in MWhe and return COP. + + Parameters: + ----------- + max_th_power : numeric + Maximum thermal output in MW (positive value) + cop_curve : numeric or list or function + 3 ways to set the COP of the Heatpump: + (1) Fixed COP based on [numeric] value. + (2) Polynomial with coefficients based on [list] input. + + Input coeficients in format [c0, c1, c2, ..., c(n)], + will generate Polynomial p(x) = c0 + c1*x + c2*x^2 ... cn*x^n, + where x = % thermal load (in % of thermal capacity) as decimal value. + + Example: + cop=[1, 2, 3, 4] will result in following COP curve: + p(x) = 1 + 2x + 3x**2 + 4x**3, + + (3) [function] in format func(*args, **kwargs) + Function should return a Polynomial that takes 'load_perc' as parameter. + + min_th_power : numeric + Minimum thermal output in MW (positive value) + + Notes: + ------ + Sign convention: + Thermal power outputs have positive values + Electric power inputs have negative values + """ + + def __init__( + self, + name, + max_th_power, + cop_curve, + min_th_power=0, + ): + if max_th_power < 0 or min_th_power < 0: + raise ValueError("Thermal power can not have negative values.") + + if min_th_power > max_th_power: + raise ValueError("'min_th_power' can not be larger than 'max_th_power'.") + + self.name = name + self.max_th_power = max_th_power + self.min_th_power = min_th_power + self.cop_curve = self._set_cop_curve(cop_curve) + + def __repr__(self): + return ( + f"{self.__class__.__name__}(name='{self.name}', max_thermal_power={self.max_th_power}, " + f"cop_curve={self.cop_curve}, min_th_power={self.min_th_power})" + ) + + # Is turning everything into a Polynomial the best solution here? + @staticmethod + @lru_cache(maxsize=None) + def _set_cop_curve(cop_curve): + """Generate COP curve function based on different inputtypes. + + Returns a function that takes *args **kwargs and returns a Polynomial. + """ + if isinstance(cop_curve, list): + + def func(*args, **kwargs): + return Polynomial(cop_curve) + + return func + + return cop_curve + + @lru_cache(maxsize=None) + def get_cop(self, heat_output, Tsink=None, Tsource=None): + """Get COP corresponding to certain load. + + Parameters: + ----------- + heat_output : numeric + Thermal load in MW + Tsink : numeric + Sink temperature in degrees celcius + Tsource : numeric + Source temperature in degrees celcius + + Notes: + ------ + Sign convention: + Positive values for thermal load + Negative values for electric load + """ + load_perc = heat_output / self.max_th_power + cop_curve = self.cop_curve + + if not callable(cop_curve): + return cop_curve + else: + return cop_curve(Tsink=Tsink, Tsource=Tsource)(load_perc) + + def th_to_el_power(self, heat_output, Tsink=None, Tsource=None): + if not self.min_th_power <= heat_output <= self.max_th_power: + warnings.warn( + f"Chosen heat output is out of range [{self.min_th_power} - {self.max_th_power}]. " + "Heat output is being limited to the closest boundary." + ) + heat_output = min(max(heat_output, self.min_th_power), self.max_th_power) + + cop = self.get_cop(heat_output=heat_output, Tsink=Tsink, Tsource=Tsource) + return -heat_output / cop + + def set_load(self, *args, **kwargs): + raise NotImplementedError( + "Directly setting the electric load of the heatpump is not possible (yet). " + "Functionality will be implemented if there is a specific usecase for it." + ) + + @lru_cache(maxsize=None) + def set_heat_output(self, heat_output, Tsink=None, Tsource=None): + """Set heat output in MWth, returns load of heatpump as tuple (MWe, MWth)""" + if not self.min_th_power <= heat_output <= self.max_th_power: + warnings.warn( + f"Chosen heat output is out of range [{self.min_th_power} - {self.max_th_power}]. " + "Heat output is being limited to the closest boundary." + ) + heat_output = min(max(heat_output, self.min_th_power), self.max_th_power) + + if Tsink is not None and Tsource is not None and Tsink <= Tsource: + raise ValueError(f"Tsource '{Tsource}' can not be higher than '{Tsink}'.") + + cop = self.get_cop(heat_output=heat_output, Tsink=Tsink, Tsource=Tsource) + e_load = -heat_output / cop + return e_load, heat_output + + def _cost_function(self, x, c1, c2, c3, Tsink=None, Tsource=None): + """Objective function for set_opt_load function. + + x = heatpump thermal load in MW + c1 = electricity_cost + c2 = alt_heat_price + c3 = demand + """ + return ( + x / self.get_cop(heat_output=x, Tsink=Tsink, Tsource=Tsource) * c1 + + (c3 - x) * c2 + ) + + @lru_cache(maxsize=None) + def set_opt_load( + self, + electricity_cost, + alt_heat_price, + demand, + Tsink=None, + Tsource=None, + tolerance=0.01, + ): + """Set optimal load of Heatpump with minimal total heat costs. + + Function uses np.minimize_scalar to minimize cost function. + + Parameters: + ----------- + electricity_cost: + Cost of input electricity in €/MWh(e) + alt_heat_price: + Price of heat from alternative source in €/MWh(th) + demand: + Heat demand in MW(th) + + Returns: + -------- + Optimal load of heatpump as tuple (MWe, MWth) + """ + c1 = electricity_cost + c2 = alt_heat_price + c3 = demand + + cop_curve = self.cop_curve + if isinstance(cop_curve, Number): + if c1 / cop_curve <= c2: + return self.max_th_power + else: + return self.min_th_power + + obj_func = partial( + self._cost_function, c1=c1, c2=c2, c3=c3, Tsink=Tsink, Tsource=Tsource + ) + + low_bound = 0 + up_bound = min(c3, self.max_th_power) + + opt_th_load = minimize_scalar( + obj_func, + bounds=(low_bound, up_bound), + method="bounded", + options={"xatol": tolerance}, + ).x + opt_e_load, opt_th_load = self.set_heat_output( + opt_th_load, Tsink=Tsink, Tsource=Tsource + ) + + return opt_e_load, opt_th_load + + +class Battery(Asset): + """Subclass for a Battery. + + Battery is modeled as follows: + - Rated power is power in MW that battery can + import from and export to the grid + - Efficiency loss is applied at charging, meaning that + SoC increase when charging is lower than the SoC decrease + when discharging + """ + + def __init__( + self, + name, + rated_power, + rated_capacity, + roundtrip_eff, + min_soc=0, + max_soc=1, + soc_at_start=None, + cycle_lifetime=None, + ): + super().__init__(name=name, max_power=rated_power, min_power=-rated_power) + self.capacity = rated_capacity + self.min_soc = min_soc + self.max_soc = max_soc + self.min_chargelevel = min_soc * self.capacity + self.max_chargelevel = max_soc * self.capacity + self.rt_eff = roundtrip_eff + self.one_way_eff = np.sqrt(roundtrip_eff) + self.cycle_count = 0 + self.cycle_lifetime = cycle_lifetime + + soc_at_start = min_soc if soc_at_start is None else soc_at_start + self.set_chargelevel(soc_at_start * self.capacity) + + def __repr__(self): + return ( + f"Battery(self, rated_power={self.max_power}, rated_capacity={self.capacity}, " + f"roundtrip_eff={self.rt_eff}, min_soc={self.min_soc}, max_soc={self.max_soc})" + ) + + def get_soc(self): + """Get the SoC in % (decimal value)""" + return self.chargelevel / self.capacity + + def set_chargelevel(self, chargelevel): + """Set the chargelevel in MWh. Will automatically change the SoC accordingly.""" + # if round(chargelevel,2) < round(self.min_chargelevel,2) or round(chargelevel,2) > round(self.max_chargelevel,2): + # raise ValueError( + # f"Tried to set Charge Level to {chargelevel}. " + # f"Charge Level must be a value between " + # f"{self.min_chargelevel} and {self.max_chargelevel} (in MWh)" + # ) + + self.chargelevel = chargelevel + + def set_load(self, load): + """Set load of the battery. + + Use negative values for charging and positive values for discharging. + Returns actual chargespeed, considering technical limitations of the battery. + + Note: We currently assume all efficiency losses occur during charging (no losses during discharge) + """ + if not hasattr(self, "freq"): + raise AttributeError( + "Time frequency of the model is not defined. " + "Assign asset to a CaseStudy or use Asset.freq(). " + "to set de time frequency and try again." + ) + + load = super().set_load(load) + + unbound_charging = self.MW_to_MWh(load) + + if load < 0: + unbound_charging *= self.rt_eff + + chargelevel = self.chargelevel + max_charging = chargelevel - self.max_chargelevel + max_discharging = chargelevel - self.min_chargelevel + + bound_charging = min(max(unbound_charging, max_charging), max_discharging) + newcl = chargelevel - bound_charging + self.set_chargelevel(newcl) + + if bound_charging < 0: + bound_charging /= self.rt_eff + + self.cycle_count += abs(bound_charging / (self.capacity * 2)) + + return self.MWh_to_MW(bound_charging) + + def charge(self, chargespeed): + """Charge the battery with given chargespeed. + + Redirects to Battery.set_load(). + Returns load (negative value for charging). + """ + chargespeed = self.max_power if chargespeed == "max" else chargespeed + + if chargespeed < 0: + raise ValueError( + f"Chargespeed should be always be a positive value by convention. " + f"Inserted {chargespeed}." + ) + + chargespeed = self.set_load(-chargespeed) + + return chargespeed + + def discharge(self, dischargespeed): + """Discharge the battery by given amount. + + Redirects to Battery.set_load(). + Returns load (positive value for discharging). + """ + dischargespeed = self.max_power if dischargespeed == "max" else dischargespeed + + if dischargespeed < 0: + raise ValueError( + f"Dischargespeed should be always be a positive value by convention. " + f"Inserted {dischargespeed}." + ) + + dischargespeed = self.set_load(dischargespeed) + + return dischargespeed + + def get_cost_per_cycle(self, cycle_lifetime): + return self.capex / self.cycle_lifetime + + +class EV(Battery): + def __init__( + self, + name, + rated_power, + rated_capacity, + roundtrip_eff, + min_soc=0, + max_soc=1, + soc_at_start=None, + id=None, + ): + super().__init__( + name, + rated_power, + rated_capacity, + roundtrip_eff, + min_soc, + max_soc, + soc_at_start, + ) + if id: + self.id = id + + +class HotWaterStorage(Battery): + """Subclass for a storage asset. + + Parameters: + ----------- + rated_capacity : int/float + Rated capacity in MWh + min_buffer_level_perc : float + Minimum buffer level in % + buffer_level_at_start : float + Buffer level at start in % + """ + + def __init__( + self, + name, + rated_power, + capacity_per_volume, + volume, + temperature, + min_storagelevel, + initial_storagelevel=None, + ): + rated_capacity = capacity_per_volume * volume + + if not initial_storagelevel: + initial_storagelevel = min_storagelevel + soc_at_start = initial_storagelevel / rated_capacity + max_storagelevel = rated_capacity * 0.95 + min_soc = min_storagelevel / rated_capacity + max_soc = max_storagelevel / rated_capacity + self.temperature = temperature + + super().__init__( + name=name, + rated_power=rated_power, + rated_capacity=rated_capacity, + roundtrip_eff=1, + min_soc=min_soc, + max_soc=max_soc, + soc_at_start=soc_at_start, + ) + + def __repr__(self): + return ( + f"{self.__class__.__name__}(name={self.name}, rated_power={self.max_power}, capacity={self.capacity}, " + f"temperature={self.temperature}, min_storagelevel={self.min_chargelevel})" + ) + + @property + def charging_power_limit(self): + max_charging_energy = self.max_chargelevel - self.chargelevel + return min(self.MWh_to_MW(max_charging_energy), -self.min_power) + + @property + def discharging_power_limit(self): + max_discharging_energy = self.chargelevel - self.min_chargelevel + return min(self.MWh_to_MW(max_discharging_energy), self.max_power) + + +class GasBoiler(Asset): + """Representation of a Gas-fired boiler. + + name : str + Unique name of the asset + max_th_output : numeric + Maximum thermal output in MW thermal + efficiency : float + Thermal efficiency of the gasboiler as decimal value. + min_th_output : numeric + Minimum thermal output in MW thermal + """ + + def __init__( + self, + name, + max_th_output, + min_th_output=0, + efficiency=0.9, + ): + super().__init__(name=name, max_power=max_th_output, min_power=min_th_output) + self.efficiency = efficiency + + def __repr__(self): + return ( + f"{self.__class__.__name__}(name={self.name}, max_power={self.max_power}, " + f"min_power={self.min_power}, efficiency={self.efficiency})" + ) + + def set_load(self, *args, **kwargs): + raise NotImplementedError( + "Gasboiler does not have electric load. " + "Use Gasboiler.set_heat_output() instead." + ) + + @lru_cache(maxsize=None) + def set_heat_output(self, output): + """Redirect to Gasboiler.set_load()""" + heat_output = super().set_load(output) + gas_input = -heat_output / self.efficiency + return heat_output, gas_input + + +class Electrolyser(Asset): + def __init__( + self, + name, + rated_power, + kwh_per_kg=60, + min_flex_load_in_perc=15, + ): + min_flex_power = min_flex_load_in_perc / 100 * rated_power + + super().__init__(name=name, max_power=-min_flex_power, min_power=-rated_power) + + self.rated_power = rated_power + self.min_flex_load = min_flex_load_in_perc + self.min_flex_power = self.min_flex_load / 100 * self.rated_power + self.kwh_per_kg = kwh_per_kg + self.kg_per_MWh = 1000 / self.kwh_per_kg + + def __repr__(self): + return ( + f"Electrolyser(name={self.name}, rated_power={self.rated_power}, " + f"kwh_per_kg={self.kwh_per_kg}, flex_range_in_perc=[{self.min_flex_load}, " + f"{self.max_flex_load}])" + ) + + def set_load(self, load): + """Set load of the Electrolyser in MW.""" + if not hasattr(self, "freq"): + raise AttributeError( + "Time frequency of the model is not defined. " + "Assign asset to a CaseStudy or use Asset.freq(). " + "to set de time frequency and try again." + ) + + load = -abs(load) + load = super().set_load(load) + + h2_output_kg = self.MW_to_MWh(-load) * self.kg_per_MWh + return load, h2_output_kg + + +class Battolyser(Asset): + def __init__( + self, + name, + rated_power, + rated_capacity, + rt_eff, + soc_at_start=None, + ): + super().__init__(name=name, max_power=rated_power, min_power=-rated_power) + + self.capacity = rated_capacity + self.min_soc = 0.05 + self.max_soc = 1.00 + self.min_chargelevel = self.min_soc * self.capacity + self.max_chargelevel = self.max_soc * self.capacity + self.rt_eff = rt_eff + self.cycle_count = 0 + + soc_at_start = self.min_soc if soc_at_start is None else soc_at_start + self.set_chargelevel(soc_at_start * self.capacity) + + def __repr__(self): + return ( + f"Battolyser(name={self.name}, rated_power={self.max_power}, " + f"rated_capacity={self.capacity}, rt_eff={self.rt_eff})" + ) + + def get_soc(self): + """Get the SoC in % (decimal value)""" + return self.chargelevel / self.capacity + + def set_chargelevel(self, chargelevel): + """Set the chargelevel in MWh. Will automatically change the SoC accordingly.""" + if chargelevel < self.min_chargelevel or chargelevel > self.max_chargelevel: + raise ValueError( + f"Tried to set Charge Level to {chargelevel}. " + f"Charge Level must be a value between " + f"{self.min_chargelevel} and {self.max_chargelevel} (in MWh)" + ) + self.chargelevel = chargelevel + + def set_load(self, load): + """Set load of the Battolyser in MW. + + Use negative values for charging and positive values for discharging. + Returns actual chargespeed, considering technical limitations of the battery. + + Note: We currently assume all efficiency losses occur during discharging + (no losses during charging) + """ + if not hasattr(self, "freq"): + raise AttributeError( + "Time frequency of the model is not defined. " + "Assign asset to a CaseStudy or use Asset.freq(). " + "to set de time frequency and try again." + ) + + load = super().set_load(load) + + unbound_charging = self.MW_to_MWh(load) + if load > 0: + unbound_charging /= self.rt_eff + + chargelevel = self.chargelevel + max_charging = chargelevel - self.max_chargelevel + max_discharging = chargelevel - self.min_chargelevel + bound_charging = min(max(unbound_charging, max_charging), max_discharging) + newcl = chargelevel - bound_charging + self.set_chargelevel(newcl) + + if bound_charging > 0: + bound_charging *= self.rt_eff + charging_power = self.MWh_to_MW(bound_charging) + h2_power = -self.MWh_to_MW(max(bound_charging - unbound_charging, 0)) + self.cycle_count += abs(bound_charging / (self.capacity * 2)) + return charging_power, h2_power + + def charge(self, chargespeed): + """Charge the battery with given chargespeed. + + Redirects to Battery.set_load(). + Returns load (negative value for charging). + """ + chargespeed = self.max_power if chargespeed == "max" else chargespeed + + if chargespeed < 0: + raise ValueError( + f"Chargespeed should be always be a positive value by convention. " + f"Inserted {chargespeed}." + ) + + chargespeed, h2_prod_in_MW = self.set_load(-chargespeed) + + return chargespeed, h2_prod_in_MW + + def discharge(self, dischargespeed): + """Discharge the battery by given amount. + + Redirects to Battery.set_load(). + Returns load (positive value for discharging). + """ + dischargespeed = self.max_power if dischargespeed == "max" else dischargespeed + + if dischargespeed < 0: + raise ValueError( + f"Dischargespeed should be always be a positive value by convention. " + f"Inserted {dischargespeed}." + ) + + dischargespeed = self.set_load(dischargespeed)[0] + return dischargespeed + + +##Added by Shahla, very similar to Hotwaterstorage +class HeatBuffer(Battery): + """Subclass for a storage asset. + + Parameters: + ----------- + rated_capacity : int/float + Rated capacity in MWh + min_buffer_level_perc : float + Minimum buffer level in % + buffer_level_at_start : float + Buffer level at start in % + """ + + def __init__( + self, name, rated_capacity, min_buffer_level_perc, buffer_level_at_start + ): + super().__init__( + name=name, + rated_power=100, + rated_capacity=rated_capacity, + roundtrip_eff=1, + min_soc=min_buffer_level_perc, + max_soc=1, + soc_at_start=buffer_level_at_start, + ) diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/basepath.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/basepath.py new file mode 100644 index 0000000..9afd49e --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/basepath.py @@ -0,0 +1,11 @@ +import os +from pathlib import Path + +# if os.environ.get("USERNAME") == "mekre": +# BASEPATH = Path("C:\\Users\\mekre\\") +# elif os.environ.get("USERNAME") == "Karel van Doesburg": +# BASEPATH = Path("C:\\RecoyShare\\") +# elif os.environ.get("USERNAME") == "Shahla Huseynova": +# BASEPATH = Path("C:\\Users\\Shahla Huseynova\\") +# elif os.environ.get("USERNAME") == "shahla.huseynova": +BASEPATH = Path("(C:\\Users\\shahla.huseynova\\Heliox Group B.V\\") diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/casestudy.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/casestudy.py new file mode 100644 index 0000000..9feb669 --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/casestudy.py @@ -0,0 +1,537 @@ +import warnings +from copy import deepcopy + +import numpy as np +import pandas as pd + +from .framework import TimeFramework +from .financial import ( + calc_business_case, + calc_co2_costs, + calc_electr_market_results, + calc_grid_costs, + calculate_eb_ode, +) +from .forecasts import Mipf, Qipf +from .prices import get_ets_prices, get_ttf_prices +from .converters import EURpertonCO2_to_EURperMWh + + +class CaseStudy: + """ + Representation of a casestudy + """ + + instances = {} + + def __init__(self, time_fw: TimeFramework, freq, name, data=None, forecast=None): + self.name = name + self.modelled_time_period_years = time_fw.modelled_time_period_years + self.start = time_fw.start + self.end = time_fw.end + self.freq = freq + self.dt_index = time_fw.dt_index(freq) + self.data = pd.DataFrame(index=self.dt_index) + self.assets = {} + self.cashflows = {} + self.irregular_cashflows = {} + self.capex = {} + self.total_capex = 0 + self.kpis = {} + + amount_of_days_in_year = 365 + + if self.start.year % 4 == 0: + amount_of_days_in_year = 366 + + self.year_case_duration = (self.end - self.start).total_seconds() / ( + 3600 * 24 * amount_of_days_in_year + ) + self.days_case_duration = self.year_case_duration * amount_of_days_in_year + self.hours_case_duration = self.days_case_duration * 24 + self.quarters_case_duration = self.days_case_duration * 24 * 4 + self.minutes_case_duration = self.days_case_duration * 24 * 60 + # self.year_case_duration = 1 + + if data is not None: + if len(data) != len(self.data): + raise ValueError( + "Length of data is not same as length of CaseStudy.data" + ) + data.index = self.dt_index + self.data = pd.concat([self.data, data], axis=1) + + if forecast is not None: + self.add_forecast(forecast, freq) + + CaseStudy.instances[self.name] = self + + @classmethod + def list_instances(cls): + """ + Returns a list with all CaseStudy instances. + Useful if you want to iterate over all instances + or use them as input to a function. + """ + return list(cls.instances.values()) + + def add_forecast(self, forecast, freq): + """ + Add forecast and price data to the data table of the CaseStudy instance. + """ + # TODO Add error handling for frequencies + if forecast == "mipf" and freq == "1T": + forecast_data = Mipf( + start=self.start, end=self.end, tidy=True, include_nextQ=False + ).data + elif forecast == "mipf" and freq == "15T": + forecast_data = Mipf( + start=self.start, end=self.end, tidy=False, include_nextQ=False + ).data + elif forecast == "qipf": + forecast_data = Qipf(start=self.start, end=self.end, freq=self.freq).data + else: + raise ValueError("Forecast does not exist. Use 'mipf' or 'qipf'.") + + self.data = pd.concat([self.data, forecast_data], axis=1) + + def add_gasprices(self): + """ + Add gas price data (TTF day-head) to the data table of the CaseStudy instance. + """ + self.data["Gas prices (€/MWh)"] = get_ttf_prices( + start=self.start, end=self.end, freq=self.freq + )["Gas prices (€/MWh)"] + + def add_co2prices(self, perMWh=False): + """ + Add CO2 prices (ETS) data to the data table of the CaseStudy instance. + """ + self.data["CO2 prices (€/ton)"] = get_ets_prices( + start=self.start, end=self.end, freq=self.freq + )["CO2 prices (€/MWh)"] + + if perMWh: + self.data["CO2 prices (€/MWh)"] = EURpertonCO2_to_EURperMWh( + self.data["CO2 prices (€/ton)"] + ).round(2) + + def add_asset(self, asset): + """Assign an Asset instance to CaseStudy instance. + + Method will create a unique copy of the Asset instance. + If Asset contains financial information, + cashflows are automatically updated. + """ + assetcopy = deepcopy(asset) + assetcopy.set_freq(self.freq) + self.assets[assetcopy.name] = assetcopy + + if hasattr(assetcopy, "opex"): + self.add_cashflow(f"{assetcopy.name} OPEX (€)", -assetcopy.opex) + + if hasattr(assetcopy, "capex"): + self.add_capex(f"{assetcopy.name} CAPEX (€)", -assetcopy.capex) + + if hasattr(assetcopy, "devex"): + self.add_capex(f"{assetcopy.name} DEVEX (€)", -assetcopy.devex) + + def get_assets(self): + """Returns all Asset instances assigned to CaseStudy instance.""" + return list(self.assets.values()) + + def add_cashflow(self, label, amount): + """Add a yearly cashflow to the CaseStudy + + Convention is negative values for costs and positive values for revenue. + """ + self.cashflows[label] = round(amount, 2) + + def add_capex(self, label, amount): + """Add a capex component to the CaseStudy + + Convention is to use positive values + """ + capex = round(amount, 2) * -1 + self.capex[label] = capex + self.total_capex += capex + + def add_irregular_cashflow(self, amount, year): + base = self.irregular_cashflows[year] if year in self.irregular_cashflows else 0 + self.irregular_cashflows[year] = base + amount + + def generate_electr_market_results(self, real_col, nom_col=None): + """Generates a dictionary with results of the simulation on energy market. + + Dictionary is saved in CaseStudy.energy_market_results. + Total market result is automatically added to cashflow dictionary. + """ + if nom_col is None: + nom_col = "Nom. vol." + self.data[nom_col] = 0 + + data = calc_electr_market_results(self.data, nom_col=nom_col, real_col=real_col) + self.data = data + + total_produced = data["Prod. vol."].sum() + total_consumed = -data["Cons. vol."].sum() + + self.total_electricity_cons = total_consumed * (-1) + + selling = data[real_col] > 0 + mean_selling_price = ( + data["Combined Result"].where(selling).sum() / total_produced + if total_produced != 0 + else 0 + ) + + mean_buying_price = ( + data["Combined Result"].where(~selling).sum() / total_consumed * (-1) + if round(total_consumed, 2) != 0 + else 0 + ) + + total_comb_result = data["Combined Result"].sum() + + self.electr_market_results = { + "Total net volume (MWh)": data[real_col].sum(), + "Total exported to grid (MWh)": total_produced, + "Total consumed from grid (MWh)": total_consumed, + "Total nominated volume (MWh)": data[nom_col].sum(), + "Absolute imbalance volume (MWh)": data["Imb. vol."].abs().sum(), + "Mean selling price (€/MWh)": mean_selling_price, + "Mean buying price (€/MWh)": mean_buying_price, + "Total day-ahead result (€)": data["Day-Ahead Result"].sum(), + "Total POS result (€)": data["POS Result"].sum(), + "Total NEG result (€)": data["NEG Result"].sum(), + "Total imbalance result (€)": data["Imbalance Result"].sum(), + "Total combined result (€)": total_comb_result, + } + + self.electr_market_result = total_comb_result + self.add_cashflow("Result on electricity market (€)", total_comb_result) + + def add_gas_costs(self, gasvolumes_col, gasprice_col="Gas prices (€/MWh)"): + """Calculate gas costs and add to cashflows + + Parameters: + ----------- + gasprices_col : str + Column containing gas prices in CaseStudy.data dataframe + gasvolumes_col : str + List of column names containing gas volumes in CaseStudy.data dataframe + """ + gasprices = self.data[gasprice_col] + gasvolumes = self.data[gasvolumes_col].abs() + gas_costs = gasprices * gasvolumes * -1 + self.data["Gas commodity costs (€)"] = gas_costs + + self.total_gas_cons = gasvolumes.sum() + self.total_gas_costs = round(gas_costs.sum(), 2) + self.add_cashflow("Gas consumption costs (€)", self.total_gas_costs) + + def add_co2_costs( + self, volume_cols, co2_price_col="CO2 prices (€/ton)", fuel="gas" + ): + """Calculate co2 costs and add to cashflows + + Parameters: + ----------- + Gasprices : str + Column containing gas prices in CaseStudy.data dataframe + Gasvolumes : list + List of column names containing gas volumes in CaseStudy.data dataframe + """ + if isinstance(volume_cols, str): + volume_cols = [volume_cols] + + co2_prices = self.data[co2_price_col] + volumes = [self.data[col] for col in volume_cols] + self.total_co2_costs = calc_co2_costs( + co2_prices=co2_prices, volumes=volumes, fuel=fuel + ) + self.add_cashflow("CO2 emission costs (€)", self.total_co2_costs) + + def add_eb_ode( + self, + commodity, + cons_col=None, + tax_bracket=None, + base_cons=None, + horti=False, + m3=False, + add_cons_MWh=0, + year=2020, + split=False, + ): + """Add EB & ODE to cashflows + + See financial.calc_eb_ode() for more detailed documentation. + + Parameters: + ----------- + commodity : str + {'gas', 'electricity'} + cons_col : str + Optional parameter to specificy column name of the + consumption values in MWh. + tax_bracket : numeric + Tax bracket that the client is in [1-4] + Use either 'tax_bracket' of 'base_cons', not both. + base_cons : numeric + Base consumption volume of the client + Use either 'tax_bracket' of 'base_cons', not both. + horti : bool + Set to True to use horticulture rates + m3 : bool + Set to True if you want to enter gas volumes in m3 + add_cons_MWh : + Enables manually adding extra consumption + """ + if cons_col: + cons = self.data[cons_col].abs().sum() + else: + cons = getattr(self, f"total_{commodity}_cons") + + cons = cons + add_cons_MWh + + eb, ode = calculate_eb_ode( + cons=cons, + electr=(commodity == "electricity"), + tax_bracket=tax_bracket, + base_cons=base_cons, + horti=horti, + m3=m3, + year=year, + ) + if split: + self.add_cashflow(f"EB {commodity.capitalize()} (€)", eb) + self.add_cashflow(f"ODE {commodity.capitalize()} (€)", ode) + else: + self.add_cashflow(f"{commodity.capitalize()} taxes (€)", eb + ode) + + def add_grid_costs( + self, + power_MW_col, + grid_operator, + year, + connection_type, + cons_MWh_col=None, + kw_contract_kW=None, + path=None, + add_peak_kW=0, + add_cons_MWh=0, + ): + """Add variable grid transport costs to cashflows + + See financial.calc_grid_costs() for more detailed documentation. + + Parameters: + ----------- + power_MW_col : str + Column in data table with power usage in MW + grid_operator : str + {'tennet', 'liander', 'enexis', 'stedin'} + year : int + Year, e.g. 2020 + connection_type : str + Connection type, e.g. 'HS' + cons_MWh_col : str + Column in data table containing grid consumption in MWh + kw_contract_kW : numeric + in kW. If provided, function will assume fixed value kW contract + path : str + Specify path with grid tariff files. Leave empty to use default path. + add_peak_kW : float + Enables manually adding peak consumption to the data + """ + cols = [power_MW_col] + if cons_MWh_col is not None: + cols.append(cons_MWh_col) + + peaks_kW = ( + (self.data[power_MW_col] * 1000 - add_peak_kW) + .resample("15T") + .mean() + .abs() + .resample("M") + .max() + .to_list() + ) + + cons_kWh = ( + self.data[cons_MWh_col].sum() * 1000 if cons_MWh_col is not None else 0 + ) + add_cons_MWh + + self.grid_costs = calc_grid_costs( + peakload_kW=peaks_kW, + grid_operator=grid_operator, + year=year, + connection_type=connection_type, + kw_contract_kW=kw_contract_kW, + totalcons_kWh=cons_kWh, + path=path, + modelled_time_period_years=self.modelled_time_period_years, + ) + + total_grid_costs = sum(self.grid_costs.values()) + + self.add_cashflow("Grid transport costs (€)", total_grid_costs) + + def calculate_ebitda(self, project_duration, residual_value=None): + """Calculate yearly EBITDA based on cashflows + + Calculation table and EBITDA value are saved in CaseStudy. + """ + for key, val in self.cashflows.items(): + if np.isnan(val): + warnings.warn( + f"Cashflow '{key}' for CaseStudy '{self.name}' contains NaN value. " + "Something might have gone wrong. Replacing NaN with 0 for now." + ) + self.cashflows[key] = 0 + + assets = self.get_assets() + + for asset in assets: + if not asset.depreciate: + pass + elif asset.lifetime is None: + raise ValueError(f"'lifetime' property of {asset.name} was not set.") + elif project_duration > asset.lifetime: + warnings.warn( + f"Project duration is larger than technical lifetime of asset '{asset.name}'. " + "Will continue by limiting project duration to the technical lifetime of the asset." + ) + project_duration = int(asset.lifetime) + + depreciations, residual_value = CaseStudy._calc_depr_and_residual_val( + assets, self.total_capex, residual_value, project_duration + ) + + depreciations = self.total_capex / project_duration + + self.ebitda = sum(self.cashflows.values()) + self.ebitda_calc = deepcopy(self.cashflows) + self.ebitda_calc["EBITDA (€)"] = self.ebitda + self.ebitda_calc["Depreciation (€)"] = depreciations * -1 + self.ebitda_calc["EBITDA + depr (€)"] = self.ebitda + depreciations * -1 + + def calculate_business_case( + self, + project_duration, + discount_rate, + residual_value=None, + baseline=None, + bl_res_value=None, + eia=False, + vamil=False, + fixed_income_tax=False, + ): + """Calculates business case (NPV, IRR) for the CaseStudy. + + Business case calculation is stored in CaseStudy.business_case + NPV is stored in CaseStudy.npv + IRR is stored in Casestudy.irr + + Parameters: + ----------- + project_duration : int + In years + discount_rate : float + In % (decimal value) + residual_value : numeric + Can be used to manually set residual value of assets (all assets combined). + + Defaults to None, in which case residual_value is calculated + based on linear depreciation over technical lifetime. + baseline : CaseStudy + Baseline to compare against + bl_res_value : numeric + Similar to 'residual_value' for baseline + eia : bool + Apply EIA ("Energie Investerings Aftrek") tax discounts. + Defaults to False. + vamil : bool + Apply VAMIL ("Willekeurige afschrijving milieu-investeringen") tax discounts. + Defaults to False. + """ + + assets = self.get_assets() + + for asset in assets: + if not asset.depreciate: + pass + elif asset.lifetime is None: + raise ValueError(f"'lifetime' property of {asset.name} was not set.") + elif project_duration > asset.lifetime: + warnings.warn( + f"Project duration is larger than technical lifetime of asset '{asset.name}'. " + "Will continue by limiting project duration to the technical lifetime of the asset." + ) + project_duration = int(asset.lifetime) + + capex = self.total_capex + yearly_ebitda = self.ebitda / self.modelled_time_period_years + + irregular_cashflows = ( + self._calc_irregular_cashflows(project_duration, baseline=baseline) + if self.irregular_cashflows + else 0 + ) + + depreciations, residual_value = CaseStudy._calc_depr_and_residual_val( + assets, capex, residual_value, project_duration + ) + + if baseline is not None: + bl_assets = baseline.assets.values() + bl_capex = baseline.total_capex + bl_depr, bl_res_val = CaseStudy._calc_depr_and_residual_val( + bl_assets, bl_capex, bl_res_value, project_duration + ) + capex -= bl_capex + depreciations -= bl_depr + residual_value -= bl_res_val + yearly_ebitda -= baseline.ebitda / self.modelled_time_period_years + + self.business_case = calc_business_case( + capex=capex, + discount_rate=discount_rate, + project_duration=project_duration, + depreciation=depreciations, + residual_value=residual_value, + regular_earnings=yearly_ebitda, + irregular_cashflows=irregular_cashflows, + eia=eia, + vamil=vamil, + fixed_income_tax=fixed_income_tax, + ) + + self.irr = self.business_case.loc["IRR (%)", "Year 0"] / 100 + self.npv = self.business_case.loc["NPV (€)", "Year 0"] + self.spp = self.business_case.loc["Simple Payback Period", "Year 0"] + + @staticmethod + def _calc_depr_and_residual_val(assets, capex, residual_value, project_duration): + if residual_value is None: + assets = [asset for asset in assets if asset.depreciate] + depreciations = sum( + (asset.capex - asset.salvage_value) / asset.lifetime for asset in assets + ) + residual_value = capex - depreciations * project_duration + else: + depreciations = (capex - residual_value) / project_duration + + return depreciations, residual_value + + def _calc_irregular_cashflows(self, project_duration, baseline=None): + irr_earnings = [0] * (project_duration) + + for year, cashflow in self.irregular_cashflows.items(): + if baseline: + cashflow -= baseline.irregular_cashflows.get(year, 0) + + irr_earnings[int(year) - 1] = cashflow + + return irr_earnings diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/colors.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/colors.py new file mode 100644 index 0000000..1660c9e --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/colors.py @@ -0,0 +1,43 @@ +recoy_colordict = { + "RecoyDarkBlue": "#0e293b", + "RecoyBlue": "#1f8376", + "RecoyRed": "#dd433b", + "RecoyYellow": "#f3d268", + "RecoyGreen": "#46a579", + "RecoyPurple": "#6d526b", + "RecoyOrange": "#f2a541", + "RecoyBlueGrey": "#145561", + "RecoyDarkGrey": "#2a2a2a", + "RecoyLilac": "#C3ACCE", + "RecoyBrown": "#825E52", + "RecoyLightGreen": "#7E9181", + "RecoyCitron": "#CFD186", + "RecoyPink": "#F5B3B3" +} + +recoy_greysdict = { + "RecoyLightGrey": "#e6e6e6", + "RecoyGrey": "#c0c0c0", + "RecoyDarkGrey": "#2a2a2a", +} + +recoydarkblue = recoy_colordict["RecoyDarkBlue"] +recoyyellow = recoy_colordict["RecoyYellow"] +recoygreen = recoy_colordict["RecoyGreen"] +recoyred = recoy_colordict["RecoyRed"] +recoyblue = recoy_colordict["RecoyBlue"] +recoyorange = recoy_colordict["RecoyOrange"] +recoypurple = recoy_colordict["RecoyPurple"] +recoybluegrey = recoy_colordict["RecoyBlueGrey"] +recoylightgrey = recoy_greysdict["RecoyLightGrey"] +recoygrey = recoy_greysdict["RecoyGrey"] +recoydarkgrey = recoy_greysdict["RecoyDarkGrey"] +recoylilac = recoy_colordict["RecoyLilac"] +recoybrown = recoy_colordict["RecoyBrown"] +recoylightgreen = recoy_colordict["RecoyLightGreen"] +recoycitron = recoy_colordict["RecoyCitron"] +recoypink = recoy_colordict["RecoyPink"] + +recoycolors = list(recoy_colordict.values()) + +transparent = "rgba(0, 0, 0, 0)" diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/converters.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/converters.py new file mode 100644 index 0000000..6b5b239 --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/converters.py @@ -0,0 +1,66 @@ +import pandas as pd + + +def MWh_to_m3(MWh): + return MWh / 9.769 * 1000 + + +def MWh_to_GJ(MWh): + return MWh * 3.6 + + +def EURperm3_to_EURperMWh(EURperm3): + return EURperm3 / 9.769 * 1000 + + +def EURperMWh_to_EURperGJ(EURperMWh): + return EURperMWh * 3.6 + + +def MWh_gas_to_tonnes_CO2(MWh): + return MWh * 1.84 / 9.769 + + +def EURpertonCO2_to_EURperMWh(EURpertonCO2): + return EURpertonCO2 * 1.884 / 9.769 + + +def EURperLHV_to_EURperHHV(MWh_LHV): + return MWh_LHV / 35.17 * 31.65 + + +def EURperHHV_to_EURperLHV(MWh_HHV): + return MWh_HHV / 31.65 * 35.17 + + +def GJ_gas_to_kg_NOX(GJ): + return GJ * 0.02 + + +def MWh_gas_to_kg_NOX(MWh): + return GJ_gas_to_kg_NOX(MWh_to_GJ(MWh)) + + +def fastround(n, decimals): + """Round a value to certain number of decimals, faster than Python implementation""" + multiplier = 10**decimals + return int(n * multiplier + 0.5) / multiplier + + +def add_season_column(data): + """Adds a column containing seasons to a DataFrame with datetime index""" + data["season"] = (data.index.month % 12 + 3) // 3 + + seasons = {1: "Winter", 2: "Spring", 3: "Summer", 4: "Fall"} + data["season"] = data["season"].map(seasons) + return data + + +def dt_column_to_local_time(column): + return column.dt.tz_localize("UTC").dt.tz_convert("Europe/Amsterdam") + + +def timestamp_to_utc(timestamp): + if isinstance(timestamp, str): + timestamp = pd.to_datetime(timestamp).tz_localize("Europe/Amsterdam") + return timestamp.tz_convert("UTC") diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/databases.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/databases.py new file mode 100644 index 0000000..9654153 --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/databases.py @@ -0,0 +1,69 @@ +from sqlalchemy import create_engine, MetaData, Table +import pandas as pd + +DATABASES = { + "ngsc_dev": { + "db_url": "ngsc-dev-msql.cyqrsg0mmelh.eu-central-1.rds.amazonaws.com", + "db_name": "ngsc_dev", + "db_user": "ngsc_dev", + "db_password": "AKIAZQ2BV5F5K6LLBC47", + "db_port": "1433", + }, + "ngsc_test": { + "db_url": "ngsc-test-msql.cyqrsg0mmelh.eu-central-1.rds.amazonaws.com", + "db_name": "ngsc_test", + "db_user": "ngsc_test", + "db_password": "AKIAZQ2BV5F5K6LLBC47", + "db_port": "1433", + }, + "ngsc_prod": { + "db_url": "rop-ngsc-prod.cyqrsg0mmelh.eu-central-1.rds.amazonaws.com", + "db_name": "ngsc_test", + "db_user": "ngsc_test", + "db_password": "AKIAZQ2BV5F5K6LLBC47", + "db_port": "1433", + }, + "rop_prices_test": { + "db_url": "rop-prices-test.cyqrsg0mmelh.eu-central-1.rds.amazonaws.com", + "db_name": "test", + "db_user": "rop", + "db_password": "OptimalTransition", + "db_port": "8472", + }, + "rop_assets_test": { + "db_url": "rop-assets-test.cyqrsg0mmelh.eu-central-1.rds.amazonaws.com", + "db_name": "test", + "db_user": "rop", + "db_password": "OptimalTransition", + "db_port": "1433", + }, +} + + +def db_engine(db_name): + db_config = DATABASES[db_name] + + connection_string = ( + f"mssql+pyodbc://{db_config['db_user']}:{db_config['db_password']}" + f"@{db_config['db_url']}:{db_config['db_port']}/" + f"{db_config['db_name']}?driver=ODBC+Driver+17+for+SQL+Server" + ) + return create_engine(connection_string) + + +def read_entire_table(table_name, db_engine): + return pd.read_sql_table(table_name, db_engine) + + +def create_connection(engine, tables): + connection = engine.connect() + metadata = MetaData() + + if isinstance(tables, str): + return connection, Table(tables, metadata, autoload=True, autoload_with=engine) + else: + db_tables = { + table: Table(table, metadata, autoload=True, autoload_with=engine) + for table in tables + } + return connection, db_tables diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/decorators.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/decorators.py new file mode 100644 index 0000000..135cb2d --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/decorators.py @@ -0,0 +1,17 @@ +import time +from functools import wraps + + +def time_method(func): + """Prints the runtime of a method of a class.""" + + @wraps(func) + def wrapper_timer(self, *args, **kwargs): + start = time.perf_counter() + value = func(self, *args, **kwargs) + end = time.perf_counter() + run_time = end - start + print(f"Finished running {self.name} in {run_time:.2f} seconds.") + return value + + return wrapper_timer diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/financial.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/financial.py new file mode 100644 index 0000000..166a134 --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/financial.py @@ -0,0 +1,667 @@ +from pathlib import Path +from datetime import timedelta + +import numpy as np +import numpy_financial as npf +import pandas as pd + +import warnings + + +def npv(discount_rate, cashflows): + cashflows = np.array(cashflows) + print('discount rate',discount_rate) + print('cashflows', cashflows) + print('answer', cashflows / (1 + discount_rate) ** np.arange(1, len(cashflows) + 1)) + return (cashflows / (1 + discount_rate) ** np.arange(1, len(cashflows) + 1)).sum( + axis=0 + ) + + +def calc_electr_market_results(model, nom_col=None, real_col=None): + """Function to calculate the financial result on Day-Ahead and Imbalance market for the input model. + + Parameters: + ----------- + model : df + DataFrame containing at least 'DAM', 'POS' and 'NEG' columns. + nom_col : str + Name of the column containing the Day-Ahead nominations in MWh + Negative values = Buy, positive values = Sell + imb_col : str + Name of the column containing the Imbalance volumes in MWh + Negative values = Buy, positive values = Sell + + Returns: + -------- + Original df with added columns showing the financial results per timeunit. + """ + if nom_col is None: + nom_col = "Nom. vol." + model[nom_col] = 0 + + producing = model[real_col] > 0 + model["Prod. vol."] = model[real_col].where(producing, other=0) + model["Cons. vol."] = model[real_col].where(~producing, other=0) + model["Imb. vol."] = model[real_col] - model[nom_col] + + model["Day-Ahead Result"] = model[nom_col] * model["DAM"] + model["POS Result"] = 0 + model["NEG Result"] = 0 + posimb = model["Imb. vol."] > 0 + model["POS Result"] = model["POS"] * model["Imb. vol."].where(posimb, other=0) + model["NEG Result"] = model["NEG"] * model["Imb. vol."].where(~posimb, other=0) + model["Imbalance Result"] = model["POS Result"] + model["NEG Result"] + model["Combined Result"] = model["Day-Ahead Result"] + model["Imbalance Result"] + return model + + +def calc_co2_costs(co2_prices, volumes, fuel): + """Calculates gas market results + + Parameters: + ----------- + co2_prices : numeric or array + CO2 prices in €/ton + volumes : list + List of arrays containing volumes + fuel : list + List of arrays containing gas volumes + + Returns: + -------- + Returns a single negative value (=costs) in € + """ + if not isinstance(volumes, list): + volumes = [volumes] + + emission_factors = { + "gas": 1.884 / 9.769 + } # in ton/MWh (based on 1.884 kg CO2/Nm3, 9.769 kWh/Nm3) + + if fuel not in emission_factors.keys(): + raise NotImplementedError( + f"Emission factor for chosen fuel '{fuel}' is not implemented." + f"Implement it by adding emission factor to the 'emission_factors' table." + ) + + emission_factor = emission_factors[fuel] + return -round( + abs(sum((array * emission_factor * co2_prices).sum() for array in volumes)), 2 + ) + + +def calculate_eb_ode( + cons, + electr=True, + year=2020, + tax_bracket=None, + base_cons=None, + horti=False, + m3=False, +): + """Calculates energy tax and ODE for consumption of electricity or natural gas in given year. + + Function calculates total tax to be payed for electricity or natural gas consumption, + consisting of energy tax ('Energiebelasting') and sustainable energy surcharge ('Opslag Duurzame Energie'). + + Tax bracket that applies is based on consumption level, with a different tax + rate for each bracket. + + For Gas + 1: 0 - 170.000 m3 + 3: 170.000 - 1 mln. m3 + 4: 1 mln. - 10 mln. m3 + 5: > 10 mln. m3 + + For Electricity + 1: 0 - 10 MWh + 2: 10 - 50 MWh + 3: 50 - 10.000 MWh + 4: > 10.000 MWh + + Parameters: + ----------- + cons : numeric + Total consumption in given year for which to calculate taxes. + Electricity consumption in MWh + Gas consumption in MWh (or m3 and use m3=True) + electr : bool + Set to False for natural gas rates. Default is True. + year : int + Year for which tax rates should be used. Tax rates are updated + annually and can differ significantly. + tax_bracket : int + Tax bracket (1-4) to assume. + Parameter can not be used in conjunction ith 'base_cons'. + base_cons : numeric + Baseline consumption to assume, in same unit as 'cons'. + Specified value is used to decide what tax bracket to start in. + Taxes from baseline consumption are not included in calculation of the tax amount. + Parameter can not be used in conjunction with 'tax_bracket'. + horti : bool + The horticulture sector gets a discount on gas taxes. + m3 : bool + Set to True if you want to enter gas consumption in m3. + Default is to enter consumption in MWh. + + Returns: + -------- + Total tax amount as negative number (costs). + + Note: + ----- + This function is rather complicated, due to all its optionalities. + Should probably be simplified or split into different functions. + """ + if tax_bracket is not None and base_cons is not None: + raise ValueError( + "Parameters 'tax_bracket' and 'base_cons' can not be used at the same time." + ) + if tax_bracket is None and base_cons is None: + raise ValueError( + "Function requires input for either 'tax_bracket' or 'base_cons'." + ) + + cons = abs(cons) + commodity = "electricity" if electr else "gas" + + if commodity == "gas": + if not m3: + cons /= 9.769 / 1000 # Conversion factor for gas: 1 m3 = 9.769 kWh + base_cons = base_cons / (9.769 / 1000) if base_cons is not None else None + else: + cons *= 1000 # conversion MWh to kWh + base_cons = base_cons * 1000 if base_cons is not None else None + + tax_brackets = { + "gas": [0, 170_000, 1_000_000, 10_000_000], + "electricity": [0, 10_000, 50_000, 10_000_000], + } + tax_brackets = tax_brackets[commodity] + base_cons = tax_brackets[tax_bracket - 1] if tax_bracket else base_cons + + if commodity == "gas" and horti: + commodity += "_horticulture" + eb_rates, ode_rates = get_tax_tables(commodity) + + eb = 0 + ode = 0 + + for bracket in range(4): + if bracket < 3: + br_lower_limit = tax_brackets[bracket] + br_upper_limit = tax_brackets[bracket + 1] + if base_cons > br_upper_limit: + continue + bracket_size = br_upper_limit - max(br_lower_limit, base_cons) + cons_in_bracket = min(cons, bracket_size) + else: + cons_in_bracket = cons + + # print(eb_rates.columns[bracket], cons_in_bracket, round(eb_rates.loc[year, eb_rates.columns[bracket]], 6), round(eb_rates.loc[year, eb_rates.columns[bracket]] * cons_in_bracket,2)) + eb += eb_rates.loc[year, eb_rates.columns[bracket]] * cons_in_bracket + ode += ode_rates.loc[year, ode_rates.columns[bracket]] * cons_in_bracket + cons -= cons_in_bracket + + if cons == 0: + break + + return -round(eb, 2), -round(ode, 2) + + +def get_tax_tables(commodity): + """Get EB and ODE tax rate tables from json files. + + Returns two tax rate tables as DataFrame. + If table is not up-to-date, try use update_tax_tables() function. + """ + folder = Path(__file__).resolve().parent / "data" / "tax_tariffs" + eb_table = pd.read_json(folder / f"{commodity}_eb.json") + ode_table = pd.read_json(folder / f"{commodity}_ode.json") + + if commodity == "electricity": + ode_table.drop(columns=ode_table.columns[3], inplace=True) + else: + eb_table.drop(columns=eb_table.columns[0], inplace=True) + + if commodity != "gas_horticulture": + eb_table.drop(columns=eb_table.columns[3], inplace=True) + return eb_table, ode_table + + +def get_tax_rate(commodity, year, tax_bracket, perMWh=True): + """Get tax rate for specific year and tax bracket. + + Parameters: + ----------- + commodity : str + {'gas' or 'electricity'} + year : int + {2013 - current year} + tax_bracket : int + {1 - 4} + + For Gas: + 1: 0 - 170.000 m3 + 3: 170.000 - 1 mln. m3 + 4: 1 mln. - 10 mln. m3 + 5: > 10 mln. m3 + + For Electricity: + 1: 0 - 10 MWh + 2: 10 - 50 MWh + 3: 50 - 10.000 MWh + 4: > 10.000 MWh + perMWh : bool + Defaults to True. Will return rates (for gas) in €/MWh instead of €/m3. + + Returns: + -------- + Dictionary with EB, ODE and combined rates (in €/MWh for electricity and €/m3 for gas) + {'EB' : float + 'ODE' : float, + 'EB+ODE' : float} + """ + eb_table, ode_table = get_tax_tables(commodity) + + eb_rate = eb_table.loc[year, :].iloc[tax_bracket - 1].astype(float).round(5) * 1000 + ode_rate = ( + ode_table.loc[year, :].iloc[tax_bracket - 1].astype(float).round(5) * 1000 + ) + + if commodity == "gas" and perMWh == True: + eb_rate /= 9.769 + ode_rate /= 9.769 + + comb_rate = (eb_rate + ode_rate).round(5) + return {"EB": eb_rate, "ODE": ode_rate, "EB+ODE": comb_rate} + + +def update_tax_tables(): + """Function to get EB and ODE tax rate tables from belastingdienst.nl and save as json file.""" + url = ( + "https://www.belastingdienst.nl/wps/wcm/connect/bldcontentnl/belastingdienst/" + "zakelijk/overige_belastingen/belastingen_op_milieugrondslag/tarieven_milieubelastingen/" + "tabellen_tarieven_milieubelastingen?projectid=6750bae7-383b-4c97-bc7a-802790bd1110" + ) + + tables = pd.read_html(url) + + table_index = { + 3: "gas_eb", + 4: "gas_horticulture_eb", + 6: "electricity_eb", + 8: "gas_ode", + 9: "gas_horticulture_ode", + 10: "electricity_ode", + } + + for key, val in table_index.items(): + table = tables[key].astype(str) + table = table.applymap(lambda x: x.strip("*")) + table = table.applymap(lambda x: x.strip("€ ")) + table = table.applymap(lambda x: x.replace(",", ".")) + table = table.astype(float) + table["Jaar"] = table["Jaar"].astype(int) + table.set_index("Jaar", inplace=True) + path = Path(__file__).resolve().parent / "data" / "tax_tariffs" / f"{val}.json" + table.to_json(path) + + +def calc_grid_costs( + peakload_kW, + grid_operator, + year, + connection_type, + totalcons_kWh=0, + kw_contract_kW=None, + path=None, + modelled_time_period_years = 1 +): + """Calculate grid connection costs for one full year + + Parameters: + ----------- + peakload_kW : numeric or list + Peak load in kW. Can be single value (for entire year) or value per month (list). + grid_operator : str + {'tennet', 'liander', 'enexis', 'stedin'} + year : int + Year to get tariffs for, e.g. 2020 + connection_type : str + Type of grid connection, e.g. 'TS' or 'HS'. + Definitions are different for each grid operator. + totalcons_kWh : numeric + Total yearly consumption in kWh + kw_contract_kW : numeric + in kW. If provided, function will assume fixed value kW contract + path : str + Path to directory with grid tariff files. + Default is None; function will to look for default folder on SharePoint. + Returns: + -------- + Total variable grid connection costs in €/year (fixed costs 'vastrecht' nog included) + """ + + totalcons_kWh /= modelled_time_period_years + + tariffs = get_grid_tariffs_electricity(grid_operator, year, connection_type, path) + kw_max_kW = np.mean(peakload_kW) + max_peakload_kW = np.max(peakload_kW) + + if kw_contract_kW is None: + kw_contract_kW = False + + if bool(kw_contract_kW) & (kw_contract_kW < max_peakload_kW): + warnings.warn( + "Maximum peak consumption is higher than provided 'kw_contract' value." + "Will continue to assume max peak consumption as kW contract." + ) + kw_contract_kW = max_peakload_kW + + if not bool(kw_contract_kW): + kw_contract_kW = max_peakload_kW + + if (tariffs["kWh tarief"] != 0) and (totalcons_kWh is None): + raise ValueError( + "For this grid connection type a tariff for kWh has to be paid. " + "Therefore 'totalcons_kWh' can not be None." + ) + + return { + "Variable": -round(tariffs["kWh tarief"] * abs(totalcons_kWh) * modelled_time_period_years, 2), + "kW contract": -round(tariffs["kW contract per jaar"] * kw_contract_kW * modelled_time_period_years, 2), + "kW max": -round(tariffs["kW max per jaar"] * max_peakload_kW * modelled_time_period_years, 2), + } + + +def get_grid_tariffs_electricity(grid_operator, year, connection_type, path=None): + """Get grid tranposrt tariffs + + Parameters: + ----------- + grid_operator : str + {'tennet', 'liander', 'enexis', 'stedin'} + year : int + Year to get tariffs for, e.g. 2020 + connection_type : str + Type of grid connection, e.g. 'TS' or 'HS'. + Definitions are different for each grid operator. + path : str + Path to directory with grid tariff files. + Default is None; function will to look for default folder on SharePoint. + + Returns: + -------- + Dictionary containing grid tariffs in €/kW/year and €/kWh + """ + if path is None: + path = Path(__file__).resolve().parent / "data" / "grid_tariffs" + else: + path = Path(path) + + if not path.exists(): + raise SystemError( + f"Path '{path}' not found. Specify different path and try again." + ) + + filename = f"{grid_operator.lower()}_{year}.csv" + filepath = path / filename + + if not filepath.exists(): + raise NotImplementedError( + f"File '{filename}' does not exist. Files available: {[file.name for file in path.glob('*.csv')]}" + ) + + rates_table = pd.read_csv( + path / filename, sep=";", decimal=",", index_col="Aansluiting" + ) + + if connection_type not in rates_table.index: + raise ValueError( + f"The chosen connection type '{connection_type}' is not available " + f"for grid operator '{grid_operator}'. Please choose one of {list(rates_table.index)}." + ) + return rates_table.loc[connection_type, :].to_dict() + + +def income_tax(ebit, fixed_tax_rate): + """ + Calculates income tax based on EBIT. + 2021 tax rates + """ + if fixed_tax_rate: + return round(ebit * -0.25, 0) + if ebit > 245_000: + return round(245_000 * -0.15 + (ebit - 200_000) * -0.25, 2) + if ebit < 0: + return 0 + else: + return -round(ebit * 0.15, 2) + + +def calc_business_case( + capex, + discount_rate, + project_duration, + depreciation, + residual_value, + regular_earnings, + irregular_cashflows=0, + eia=False, + vamil=False, + fixed_income_tax=False +): + """Calculate NPV and IRR for business case. + + All input paremeters are either absolute or relative to a baseline. + + Parameters: + ----------- + capex : numeric + Total CAPEX or extra CAPEX compared to baseline + discount_rate : numeric + % as decimal value + project_duration : numeric + in years + depreciation : numeric of list + Yearly depreciation costs + residual_value : numeric + Residual value at end of project in €, total or compared to baseline. + regular_earnings : numeric + Regular earnings, usually EBITDA + irregular_cashflows : list + Pass list with value for each year. + eia : bool + Apply EIA ("Energie Investerings Aftrek") tax discounts. + Defaults to False. + vamil : bool + Apply VAMIL ("Willekeurige afschrijving milieu-investeringen") tax discounts. + Defaults to False. + + Returns: + -------- + DataFrame showing complete calculation resulting in NPV and IRR + """ + years = [f"Year {y}" for y in range(project_duration + 1)] + years_o = years[1:] + + bc_calc = pd.DataFrame(columns=years) + bc_calc.loc["CAPEX (€)", "Year 0"] = -capex + bc_calc.loc["Regular Earnings (€)", years_o] = regular_earnings + bc_calc.loc["Irregular Cashflows (€)", years_o] = irregular_cashflows + bc_calc.loc["EBITDA (€)", years_o] = ( + bc_calc.loc["Regular Earnings (€)", years_o] + + bc_calc.loc["Irregular Cashflows (€)", years_o] + ) + + depreciations = [depreciation] * project_duration + + if vamil: + ebitdas = bc_calc.loc["EBITDA (€)", years_o].to_list() + depreciations = _apply_vamil(depreciations, project_duration, ebitdas) + + bc_calc.loc["Depreciations (€) -/-", years_o] = np.array(depreciations) * -1 + bc_calc.loc["EBIT (€)", years_o] = ( + bc_calc.loc["EBITDA (€)", years_o] + + bc_calc.loc["Depreciations (€) -/-", years_o] + ) + + if eia: + bc_calc = _apply_eia(bc_calc, project_duration, capex, years_o) + + bc_calc.loc["Income tax (Vpb.) (€)", years_o] = bc_calc.loc["EBIT (€)", :].apply( + income_tax, args=[fixed_income_tax] + ) + + if eia: + bc_calc.loc["NOPLAT (€)", years_o] = ( + bc_calc.loc["EBIT before EIA (€)", :] + + bc_calc.loc["Income tax (Vpb.) (€)", years_o] + ) + else: + bc_calc.loc["NOPLAT (€)", years_o] = ( + bc_calc.loc["EBIT (€)", :] + bc_calc.loc["Income tax (Vpb.) (€)", years_o] + ) + + bc_calc.loc["Depreciations (€) +/+", years_o] = depreciations + bc_calc.loc["Free Cash Flow (€)", years] = ( + bc_calc.loc["CAPEX (€)", years].fillna(0) + + bc_calc.loc["NOPLAT (€)", years].fillna(0) + + bc_calc.loc["Depreciations (€) +/+", years].fillna(0) + ) + + spp = calc_simple_payback_time( + capex=capex, + free_cashflows=bc_calc.loc["Free Cash Flow (€)", years_o].values, + ) + bc_calc.loc["Simple Payback Period", "Year 0"] = spp + + try: + bc_calc.loc["IRR (%)", "Year 0"] = ( + npf.irr(bc_calc.loc["Free Cash Flow (€)", years].values) * 100 + ) + except: + bc_calc.loc["IRR (%)", "Year 0"] = np.nan + + bc_calc.loc["WACC (%)", "Year 0"] = discount_rate * 100 + + bc_calc.loc["NPV of explicit period (€)", "Year 0"] = npv( + discount_rate, bc_calc.loc["Free Cash Flow (€)"].values + ) + bc_calc.loc["Discounted residual value (€)", "Year 0"] = ( + residual_value / (1 + discount_rate) ** project_duration + ) + bc_calc.loc["NPV (€)", "Year 0"] = ( + bc_calc.loc["NPV of explicit period (€)", "Year 0"] + # + bc_calc.loc["Discounted residual value (€)", "Year 0"] + ) + + return bc_calc.round(2) + + +def calc_simple_payback_time(capex, free_cashflows): + if free_cashflows.sum() < capex: + return np.nan + + year = 0 + spp = 0 + while capex > 0: + cashflow = free_cashflows[year] + spp += min(capex, cashflow) / cashflow + capex -= cashflow + year += 1 + return round(spp, 1) + + +def _apply_vamil(depreciations, project_duration, ebitdas): + remaining_depr = sum(depreciations) + remaining_vamil = 0.75 * remaining_depr + for i in range(project_duration): + vamil_depr = min(ebitdas[i], remaining_vamil) if remaining_vamil > 0 else 0 + + if remaining_depr > 0: + lin_depr = remaining_depr / (project_duration - i) + depr = max(vamil_depr, lin_depr) + depreciations[i] = max(vamil_depr, lin_depr) + + remaining_vamil -= vamil_depr + remaining_depr -= depr + else: + depreciations[i] = 0 + + return depreciations + + +def _apply_eia(bc_calc, project_duration, capex, years_o): + remaining_eia = 0.45 * capex + eia_per_year = [0] * project_duration + bc_calc = bc_calc.rename(index={"EBIT (€)": "EBIT before EIA (€)"}) + ebits = bc_calc.loc["EBIT before EIA (€)", years_o].to_list() + eia_duration = min(10, project_duration) + for i in range(eia_duration): + if remaining_eia > 0: + eia_curr_year = max(min(remaining_eia, ebits[i]), 0) + eia_per_year[i] = eia_curr_year + remaining_eia -= eia_curr_year + else: + break + + bc_calc.loc["EIA (€)", years_o] = np.array(eia_per_year) * -1 + bc_calc.loc["EBIT (€)", :] = ( + bc_calc.loc["EBIT before EIA (€)", :] + bc_calc.loc["EIA (€)", :] + ) + return bc_calc + + +def calc_irf_value( + data, irf_volume, nomination_col=None, realisation_col=None, reco_col="reco" +): + """Calculate IRF value + + Takes a DataFrame [data] and returns the same DataFrame with a new column "IRF Value" + + Parameters + ---------- + data : DataFrame + DataFrame that contains data. Should include price data (DAM, POS and NEG). + irf_volume : int + Volume on IRF in MW. + nomination_col : str + Name of the column containing nomination data in MWh. + realisation_col : str + Name of the column containing realisation data in MWh. + reco_col : str + Name of the column contaning recommendations. + """ + if not nomination_col: + nomination_col = "zero_nom" + data[nomination_col] = 0 + + if not realisation_col: + realisation_col = "zero_nom" + data[realisation_col] = 0 + + conversion_factor = pd.to_timedelta(data.index.freq) / timedelta(hours=1) + + imb_pre_irf = data[realisation_col] - data[nomination_col] + result_pre_irf = ( + data[nomination_col] * data["DAM"] + + imb_pre_irf.where(imb_pre_irf > 0, other=0) * data["POS"] + + imb_pre_irf.where(imb_pre_irf < 0, other=0) * data["NEG"] + ) + + data["IRF Nom"] = ( + data[nomination_col] - data[reco_col] * irf_volume * conversion_factor + ) + data["IRF Imb"] = data[realisation_col] - data["IRF Nom"] + + result_post_irf = ( + data["IRF Nom"] * data["DAM"] + + data["IRF Imb"].where(data["IRF Imb"] > 0, other=0) * data["POS"] + + data["IRF Imb"].where(data["IRF Imb"] < 0, other=0) * data["NEG"] + ) + data["IRF Value"] = result_post_irf - result_pre_irf + + return data diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/forecasts.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/forecasts.py new file mode 100644 index 0000000..6bd3f71 --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/forecasts.py @@ -0,0 +1,343 @@ +import json +import os +import time +import pytz +from datetime import datetime, timedelta +from pathlib import Path + +import numpy as np +import pandas as pd +import requests +from pyrecoy.prices import * + + +class Forecast: + """Load dataset from SharePoint server as DataFrame in local datetime format. + + Parameters: + ---------- + filename : str + Name of the csv file, e.g. "marketprices_nl.csv" + start : datetime + Startdate of the dataset + end : datetime + Enddate of the dataset + freq : str + {'1T', '15T', 'H'} + Time frequency of the data + folder_path : str + Local path to forecast data on Recoy SharePoint, + e.g. "C:/Users/username/Recoy/Recoy - Documents/03 - Libraries/12 - Data Management/Forecast Data/" + + """ + + def __init__(self, filename, start=None, end=None, freq="15T", folder_path=None, from_database=False, add_days_to_start_end=False): + self.file = filename + self.from_database = from_database + + if isinstance(start, str): + start = datetime.strptime(start, "%Y-%m-%d").astimezone(pytz.timezone('Europe/Amsterdam')) + print(start) + if isinstance(end, str): + end = datetime.strptime(end, "%Y-%m-%d").astimezone(pytz.timezone('Europe/Amsterdam')) + print(end) + + self.data = self.get_dataset(start, end, freq, folder_path=folder_path, add_days_to_start_end=add_days_to_start_end) + + # print(self.data) + + if len(self.data) == 0: + raise Exception("No data available for those dates.") + + def get_dataset(self, start, end, freq, folder_path=None, add_days_to_start_end=False): + if folder_path is None and self.from_database: + if add_days_to_start_end: + start = start + timedelta(days=-1) + end = end + timedelta(days=1) + + start = start.astimezone(pytz.utc) + end = end.astimezone(pytz.utc) + + dam = get_day_ahead_prices_from_database(start, end, 'NLD') + dam = dam.resample('15T').ffill() + + imb = get_imbalance_prices_from_database(start, end, 'NLD') + data = pd.concat([imb, dam], axis='columns') + data = data[['DAM', 'POS', 'NEG']] + data = data.tz_convert('Europe/Amsterdam') + # data = data.loc[(data.index >= start) & (data.index < end)] + return data + + + else: + if folder_path is None: + folder_path = Path(os.environ["FORECAST_DATA_FOLDER"]) + else: + folder_path = Path(folder_path) + + data = pd.read_csv( + folder_path / self.file, + delimiter=";", + decimal=",", + parse_dates=False, + index_col="datetime", + ) + ix_start = pd.to_datetime(data.index[0], utc=True).tz_convert( + "Europe/Amsterdam" + ) + ix_end = pd.to_datetime(data.index[-1], utc=True).tz_convert("Europe/Amsterdam") + new_idx = pd.date_range(ix_start, ix_end, freq=freq, tz="Europe/Amsterdam") + + if len(new_idx) == len(data.index): + data.index = new_idx + else: + print(f"Warning: Entries missing from dataset '{self.file}'.") + data.index = pd.to_datetime(data.index, utc=True).tz_convert( + "Europe/Amsterdam" + ) + data = data.reindex(new_idx) + print("Issue solved: Dataset was reindexed automatically.") + + data.index.name = "datetime" + + if start and end: + return data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")].round(2) + elif start: + return data[start.strftime("%Y-%m-%d") :].round(2) + elif end: + return data[: end.strftime("%Y-%m-%d")].round(2) + else: + return data.round(2) + + + def reindex_to_freq(self, freq): + """Reindex dataset to a different timefrequency. + + Parameters: + ----------- + freq : string + options: '1T' + """ + ix_start = pd.to_datetime(self.data.index[0], utc=True).tz_convert( + "Europe/Amsterdam" + ) + ix_end = pd.to_datetime(self.data.index[-1], utc=True).tz_convert( + "Europe/Amsterdam" + ) + + idx = pd.date_range( + ix_start, ix_end + timedelta(minutes=14), freq=freq, tz="Europe/Amsterdam" + ) + self.data = self.data.reindex(index=idx, method="ffill") + + +class Mipf(Forecast): + """Load MIPF dataset from SharePoint server as DataFrame in local datetime format. + + Parameters: + ---------- + start : datetime + Startdate of the dataset + end : datetime + Enddate of the dataset + tidy : bool + Get a dataframe in tidy format (1 minute freq). + include_nextQ : bool + Include forecast for next Quarter hour. + Requires tidy=True to work. + folder_path : str + Local path to forecast data on Recoy SharePoint, + e.g. "C:/Users/username/Recoy/Recoy - Documents/03 - Libraries/12 - Data Management/Forecast Data/" + """ + + def __init__( + self, start=None, end=None, tidy=True, include_nextQ=False, folder_path=None + ): + self.file = "imbalanceRT_nl.csv" + super().__init__( + self.file, start=start, end=end, freq="15T", folder_path=folder_path + ) + + if tidy and self.from_database == False: + self.tidy(include_nextQ=include_nextQ) + + elif self.from_database == True: + self.addMipfData(include_nextQ=include_nextQ) + + def tidy(self, include_price_data=True, include_nextQ=False): + self.data = tidy_mipf(self.data, include_price_data, include_nextQ) + + + # def addMipfData(self, include_nextQ=False): + + + + + +def tidy_mipf(data, include_price_data=True, include_nextQ=False): + """Takes MIPF dataset (unstacked) and turns it into a tidy dataset (stacked). + + Parameters: + ---------- + include_price_data : bool + Set as True if columns 'DAM', 'POS' and 'NEG' data should be included in the output. + include_nextQ : bool + Set to True to include next Qh forecast + """ + mipf_pos = data[[f"POS_horizon{h}" for h in np.flip(np.arange(3, 18))]].copy() + mipf_neg = data[[f"NEG_horizon{h}" for h in np.flip(np.arange(3, 18))]].copy() + + cols = ["ForePos", "ForeNeg"] + dfs = [mipf_pos, mipf_neg] + + if include_nextQ: + pos_nextQ = data[[f"POS_horizon{h}" for h in np.flip(np.arange(18, 30))]].copy() + neg_nextQ = data[[f"NEG_horizon{h}" for h in np.flip(np.arange(18, 30))]].copy() + + for h in np.arange(30, 33): + pos_nextQ.insert(0, f"POS_horizon{h}", np.NaN) + neg_nextQ.insert(0, f"POS_horizon{h}", np.NaN) + + cols += ["ForePos_nextQ", "ForeNeg_nextQ"] + dfs += [pos_nextQ, neg_nextQ] + + tidy_df = pd.DataFrame() + + for df, col in zip(dfs, cols): + df.columns = range(15) + df.reset_index(drop=True, inplace=True) + df.reset_index(inplace=True) + df_melt = ( + df.melt(id_vars=["index"], var_name="min", value_name=col) + .sort_values(["index", "min"]) + .reset_index(drop=True) + ) + tidy_df[col] = df_melt[col] + + ix_start = data.index[0] + ix_end = data.index[-1] + timedelta(minutes=14) + + tidy_df.index = pd.date_range(ix_start, ix_end, freq="1T", tz="Europe/Amsterdam") + tidy_df.index.name = "datetime" + + if include_price_data: + for col in np.flip(["DAM", "POS", "NEG", "regulation state"]): + try: + price_col = data.loc[:, col].reindex( + index=tidy_df.index, method="ffill" + ) + if col == "regulation state": + price_col.name = "RS" + tidy_df = pd.concat([price_col, tidy_df], axis="columns") + except Exception as e: + print(e) + + return tidy_df + + +class Qipf(Forecast): + """Load QIPF dataset from SharePoint server as DataFrame in local datetime format. + + Parameters: + ---------- + start : datetime + Startdate of the dataset + end : datetime + Enddate of the dataset + folder_path : str + Local path to forecast data on Recoy SharePoint, + e.g. "C:/Users/username/Recoy/Recoy - Documents/03 - Libraries/12 - Data Management/Forecast Data/" + """ + + def __init__(self, start=None, end=None, freq="15T", folder_path=None): + self.file = "imbalance_nl.csv" + self.data = self.get_dataset(start, end, "15T", folder_path=folder_path) + + if freq != "15T": + self.reindex_to_freq(freq) + + +class Irf(Forecast): + """Load QIPF dataset from SharePoint server as DataFrame in local datetime format.""" + + def __init__( + self, country, horizon, start=None, end=None, freq="60T", folder_path=None + ): + if freq == "15T": + self.file = f"irf_{country}_{horizon}_15min.csv" + else: + self.file = f"irf_{country}_{horizon}.csv" + + self.data = self.get_dataset(start, end, freq, folder_path=folder_path) + + return data + + +class NsideApiRequest: + """ + Request forecast data from N-SIDE API + + If request fails, code will retry 5 times by default. + + Output on success: data as DataFrame, containing forecast data. Index is timezone-aware datetime (Dutch time). + Output on error: [] + """ + + def __init__( + self, + endpoint, + country, + start=None, + end=None, + auth_token=None, + ): + if not auth_token: + try: + auth_token = os.environ["NSIDE_API_KEY"] + except: + raise ValueError("N-SIDE token not provided.") + + self.data = self.get_data(auth_token, endpoint, country, start, end) + + def get_data(self, token, endpoint, country, start, end): + if start is not None: + start = pd.to_datetime(start).strftime("%Y-%m-%d") + if end is not None: + end = pd.to_datetime(end).strftime("%Y-%m-%d") + + url = f"https://energy-forecasting-api.eu.n-side.com/api/forecasts/{country}/{endpoint}" + if start and end: + url += f"?from={start}&to={end}" + print(url) + headers = {"Accept": "application/json", "Authorization": f"Token {token}"} + + retry = 5 + self.success = False + + i = 0 + while i <= retry: + resp = requests.get(url, headers=headers) + self.statuscode = resp.status_code + + if self.statuscode == requests.codes.ok: + self.content = resp.content + json_data = json.loads(self.content) + data = pd.DataFrame(json_data["records"]) + data = data.set_index("datetime") + data.index = pd.to_datetime(data.index, utc=True).tz_convert( + "Europe/Amsterdam" + ) + self.success = True + return data.sort_index() + else: + print( + f"Attempt failled, status code {str(self.statuscode)}. Trying again..." + ) + time.sleep(5) + i += 1 + + if not self.success: + print( + "Request failed. Please contact your Recoy contact person or try again later." + ) + return [] diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/framework.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/framework.py new file mode 100644 index 0000000..6a49ce0 --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/framework.py @@ -0,0 +1,60 @@ +import warnings +from datetime import datetime, timedelta + +import pandas as pd +import pytz + + +class TimeFramework: + """ + Representation of the modelled timeperiod. + Variables in this class are equal for all CaseStudies. + """ + + def __init__(self, start, end): + if type(start) is str: + start = pytz.timezone("Europe/Amsterdam").localize( + datetime.strptime(start, "%Y-%m-%d") + ) + + if type(end) is str: + end = pytz.timezone("Europe/Amsterdam").localize( + datetime.strptime(end, "%Y-%m-%d") + ) + end += timedelta(days=1) + end -= timedelta(minutes=1) + + self.start = start + self.end = end + + amount_of_days = 365 + + if start.year % 4 == 0: + amount_of_days = 366 + + self.days = (self.end - self.start + timedelta(days=1)) / timedelta(days=1) + + self.modelled_time_period_years = (end - start).total_seconds() / (3600 * 24 * amount_of_days) + + if self.days != 365: + warnings.warn( + f"The chosen timeperiod spans {self.days} days, " + "which is not a full year. Beware that certain " + "functions that use yearly rates might return " + "incorrect values." + ) + + def dt_index(self, freq): + # Workaround to make sure time range is always complete, + # Even with DST changes + # end = self.end + timedelta(days=1) # + timedelta(hours=1) + # end = self.end + # end - timedelta(end.hour) + return pd.date_range( + start=self.start, + end=self.end, + freq=freq, + tz="Europe/Amsterdam", + # inclusive="left", + name="datetime", + ) diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/intelligent_baseline.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/intelligent_baseline.py new file mode 100644 index 0000000..286f734 --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/intelligent_baseline.py @@ -0,0 +1,226 @@ +import numpy as np +import pandas as pd +import warnings +from tqdm.notebook import tqdm + +from .prices import get_tennet_data, get_balansdelta_nl +from .forecasts import Forecast + +# TODO: This whole thing needs serious refactoring /MK + + +def generate_intelligent_baseline(startdate, enddate): + bd = get_balansdelta_nl(start=startdate, end=enddate) + bd.drop( + columns=[ + "datum", + "volgnr", + "tijd", + "IGCCBijdrage_op", + "IGCCBijdrage_af", + "opregelen_reserve", + "afregelen_reserve", + ], + inplace=True, + ) + net_regelvolume = bd["opregelen"] - bd["Afregelen"] + bd.insert(2, "net_regelvolume", net_regelvolume) + vol_delta = bd["net_regelvolume"].diff(periods=1) + bd.insert(3, "vol_delta", vol_delta) + + pc = get_tennet_data( + exporttype="verrekenprijzen", start=startdate, end=enddate + ).reindex(index=bd.index, method="ffill")[["prikkelcomponent"]] + + if len(pc) == 0: + pc = pd.Series(0, index=bd.index) + + prices = Forecast("marketprices_nl.csv", start=startdate, end=enddate) + prices.reindex_to_freq("1T") + prices = prices.data + + inputdata = pd.concat([prices, bd, pc], axis=1) + + Qhs = len(inputdata) / 15 + + if Qhs % 1 > 0: + raise Exception( + "A dataset with incomplete quarter-hours was passed in, please insert new dataset!" + ) + + data = np.array([inputdata[col].to_numpy() for col in inputdata.columns]) + + lstoutput = [] + + for q in tqdm(range(int(Qhs))): + q_data = [col[q * 15 : (q + 1) * 15] for col in data] + q_output = apply_imbalance_logic_for_quarter_hour(q_data) + + if lstoutput: + for (ix, col) in enumerate(lstoutput): + lstoutput[ix] += q_output[ix] + else: + lstoutput = q_output + + ib = pd.DataFrame( + lstoutput, + index=[ + "DAM", + "POS", + "NEG", + "regulation state", + "ib_inv", + "ib_afn", + "ib_rt", + "nv_op", + "nv_af", + "opgeregeld", + "afgeregeld", + ], + ).T + + ib.index = inputdata.index + return ib + + +def apply_imbalance_logic_for_quarter_hour(q_data): + [nv_op, nv_af, opgeregeld, afgeregeld] = [False] * 4 + + lst_inv = [np.NaN] * 15 + lst_afn = [np.NaN] * 15 + lst_rt = [np.NaN] * 15 + + lst_nv_op = [np.NaN] * 15 + lst_nv_af = [np.NaN] * 15 + lst_afr = [np.NaN] * 15 + lst_opr = [np.NaN] * 15 + + mins = iter(range(15)) + + for m in mins: + [ + DAM, + POS, + NEG, + rt, + vol_op, + vol_af, + net_vol, + delta_vol, + nood_op, + nood_af, + prijs_hoog, + prijs_mid, + prijs_laag, + prikkelc, + ] = [col[0 : m + 1] for col in q_data] + + delta_vol[0] = 0 + + if nood_op.sum() > 0: + nv_op = True + + if nood_af.sum() > 0: + nv_af = True + + if pd.notna(prijs_hoog).any() > 0: + opgeregeld = True + + if pd.notna(prijs_laag).any() > 0: + afgeregeld = True + + if (opgeregeld == True) and (afgeregeld == False): + regeltoestand = 1 + + elif (opgeregeld == False) and (afgeregeld == True): + regeltoestand = -1 + + elif (opgeregeld == False) and (afgeregeld == False): + if nv_op == True: + regeltoestand = 1 + if nv_af == True: + regeltoestand = -1 + else: + regeltoestand = 0 + + else: + # Zowel opregeld als afregeld > kijk naar trend + # Continue niet-dalend: RT1 + # Continue dalend: RT -1 + # Geen continue trend: RT 2 + + if all(i >= 0 for i in delta_vol): + regeltoestand = 1 + elif all(i <= 0 for i in delta_vol): + regeltoestand = -1 + else: + regeltoestand = 2 + + # Bepaal de verwachte onbalansprijzen + dam = DAM[0] + pc = prikkelc[0] + + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + + hoogste_prijs = np.nanmax(prijs_hoog) + mid_prijs = prijs_mid[-1] + laagste_prijs = np.nanmin(prijs_laag) + + if regeltoestand == 0: + prijs_inv = mid_prijs + prijs_afn = mid_prijs + + elif regeltoestand == -1: + if nv_af: + prijs_afn = np.nanmin((dam - 200, laagste_prijs)) + + else: + prijs_afn = laagste_prijs + + prijs_inv = prijs_afn + + elif regeltoestand == 1: + if nv_op: + prijs_inv = np.nanmax((dam + 200, hoogste_prijs)) + + else: + prijs_inv = hoogste_prijs + + prijs_afn = prijs_inv + + elif regeltoestand == 2: + if nv_op: + prijs_afn = np.nanmax((dam + 200, hoogste_prijs, mid_prijs)) + else: + prijs_afn = np.nanmax((mid_prijs, hoogste_prijs)) + + if nv_af: + prijs_inv = np.nanmin((dam - 200, laagste_prijs, mid_prijs)) + else: + prijs_inv = np.nanmin((mid_prijs, laagste_prijs)) + + prijs_inv -= pc + prijs_afn += pc + + lst_inv[m] = prijs_inv + lst_afn[m] = prijs_afn + lst_rt[m] = regeltoestand + lst_nv_op[m] = nv_op + lst_nv_af[m] = nv_af + lst_opr[m] = opgeregeld + lst_afr[m] = afgeregeld + + return [ + list(DAM), + list(POS), + list(NEG), + list(rt), + lst_inv, + lst_afn, + lst_rt, + lst_nv_op, + lst_nv_af, + lst_opr, + lst_afr, + ] diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/plotting.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/plotting.py new file mode 100644 index 0000000..74ceade --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/plotting.py @@ -0,0 +1,143 @@ +import plotly.graph_objects as go +from millify import millify +from plotly import figure_factory as ff + +from .colors import * +from .reports import SingleFigureComparison + + +def npv_bar_chart( + cases, color=recoydarkblue, title="NPV Comparison in k€", n_format="%{text:.3s}€" +): + series = SingleFigureComparison(cases, "npv", "NPV (€)").report + case_names = series.index + npvs = series.values + return single_figure_barchart(npvs, case_names, title, color, n_format) + + +def irr_bar_chart( + cases, color=recoydarkblue, title="IRR Comparison in %", n_format="%{text:.1f}%" +): + series = SingleFigureComparison(cases, "irr", "IRR (€)").report + case_names = series.index + irrs = series.values * 100 + return single_figure_barchart(irrs, case_names, title, color, n_format) + + +def ebitda_bar_chart( + cases, color=recoydarkblue, title="EBITDA comparison in k€", n_format="%{text:.3s}€" +): + series = SingleFigureComparison(cases, "ebitda", "EBITDA (€)").report + case_names = series.index + ebitdas = series.values + return single_figure_barchart(ebitdas, case_names, title, color, n_format) + + +def capex_bar_chart( + cases, color=recoydarkblue, title="CAPEX comparison in k€", n_format="%{text:.3s}€" +): + series = SingleFigureComparison(cases, "total_capex", "CAPEX (€)").report + case_names = series.index + capex = series.values * -1 + return single_figure_barchart(capex, case_names, title, color, n_format) + + +def single_figure_barchart(y_values, x_labels, title, color, n_format): + fig = go.Figure() + fig.add_trace( + go.Bar( + x=x_labels, + y=y_values, + text=y_values, + marker_color=color, + cliponaxis=False, + ) + ) + fig.update_layout(title=title) + ymin = min(y_values.min(), 0) * 1.1 + ymax = max(y_values.max(), 0) * 1.1 + fig.update_yaxes(range=[ymin, ymax]) + fig.update_traces(texttemplate=n_format, textposition="outside") + return fig + + +def heatmap( + data, + title=None, + labels=None, + colormap="reds", + mult_factor=1, + decimals=2, + min_value=None, + max_value=None, + width=600, + height=400, + hover_prefix=None, + reversescale=False, +): + data_lists = (data * mult_factor).round(decimals).values.tolist() + + xs = data.columns.tolist() + ys = data.index.to_list() + + annotations = ( + (data * mult_factor) + .applymap(lambda x: millify(x, precision=decimals)) + .values.tolist() + ) + if hover_prefix: + hover_labels = [ + [f"{hover_prefix} {ann}" for ann in sublist] for sublist in annotations + ] + else: + hover_labels = annotations + + # This is an ugly trick to fix a bug with + # the axis labels not showing correctly + xs_ = [f"{str(x)}_" for x in xs] + ys_ = [f"{str(y)}_" for y in ys] + + fig = ff.create_annotated_heatmap( + data_lists, + x=xs_, + y=ys_, + annotation_text=annotations, + colorscale=colormap, + showscale=True, + text=hover_labels, + hoverinfo="text", + reversescale=reversescale, + ) + + # Part 2 of the bug fix + fig.update_xaxes(tickvals=xs_, ticktext=xs) + fig.update_yaxes(tickvals=ys_, ticktext=ys) + + fig.layout.xaxis.type = "category" + fig.layout.yaxis.type = "category" + fig["layout"]["xaxis"].update(side="bottom") + + if min_value: + fig["data"][0]["zmin"] = min_value * mult_factor + if max_value: + fig["data"][0]["zmax"] = max_value * mult_factor + + if labels: + xlabel = labels[0] + ylabel = labels[1] + else: + xlabel = data.columns.name + ylabel = data.index.name + + fig.update_xaxes(title=xlabel) + fig.update_yaxes(title=ylabel) + + if title: + fig.update_layout( + title=title, + title_x=0.5, + title_y=0.85, + width=width, + height=height, + ) + return fig diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/prices-LAPTOP-2MK43FDK.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/prices-LAPTOP-2MK43FDK.py new file mode 100644 index 0000000..2f90008 --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/prices-LAPTOP-2MK43FDK.py @@ -0,0 +1,765 @@ +import os +from datetime import timedelta +from io import BytesIO +from pathlib import Path +from zipfile import ZipFile +import time +import warnings +import json +import pytz + +import numpy as np +import pandas as pd +import requests +from bs4 import BeautifulSoup +from entsoe.entsoe import EntsoePandasClient +from sqlalchemy import MetaData, Table, insert, and_, or_ +from pyrecoy import * + + +def get_fcr_prices(start, end, freq="H") -> pd.DataFrame: + """Get FCR settlement prices from Regelleistung website + + Returns: DataFrame with FCR prices with index with given time frequency in local time. + """ + start = start + timedelta(-1) + end = end + timedelta(1) + data = get_FCR_prices_from_database(start, end, 'NLD') + data = data.resample('15T').ffill() + data = data[['PricePerMWPerISP']] + data.columns = ['FCR NL (EUR/ISP)'] + data.index.name = 'datetime' + data = data.tz_convert('Europe/Amsterdam') + return data + + path = Path( + f"./data/fcr_prices_{freq}_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + ) + if path.exists(): + df = pd.read_csv(path, sep=";", decimal=",", index_col="datetime").astype(float) + startdate = pd.to_datetime(df.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(df.index[-1]).strftime("%Y-%m-%d %H:%M") + df.index = pd.date_range( + startdate, enddate, freq=freq, tz="Europe/Amsterdam", name="datetime" + ) + return df + + dfs = [] + retry = 5 + for date in pd.date_range(start=start, end=end + timedelta(days=1)): + r = 0 + # print(f'DEBUG: {date}') + while r < retry: + try: + url = ( + f"https://www.regelleistung.net/apps/cpp-publisher/api/v1/download/tenders/" + f"resultsoverview?date={date.strftime('%Y-%m-%d')}&exportFormat=xlsx&market=CAPACITY&productTypes=FCR" + ) + df = pd.read_excel(url, engine="openpyxl")[ + [ + "DATE_FROM", + "PRODUCTNAME", + "NL_SETTLEMENTCAPACITY_PRICE_[EUR/MW]", + "DE_SETTLEMENTCAPACITY_PRICE_[EUR/MW]", + ] + ] + # print(f'DEBUG: {date} read in') + dfs.append(df) + break + except Exception: + # print(r) + time.sleep(1) + r += 1 + warnings.warn( + f'No data received for {date.strftime("%Y-%m-%d")}. Retrying...({r}/{retry})' + ) + + if r == retry: + raise RuntimeError(f'No data received for {date.strftime("%Y-%m-%d")}') + + df = pd.concat(dfs, axis=0) + df["hour"] = df["PRODUCTNAME"].map(lambda x: int(x.split("_")[1])) + df["Timeblocks"] = ( + df["PRODUCTNAME"].map(lambda x: int(x.split("_")[2])) - df["hour"] + ) + df.index = df.apply( + lambda row: pd.to_datetime(row["DATE_FROM"]) + timedelta(hours=row["hour"]), + axis=1, + ).dt.tz_localize("Europe/Amsterdam") + df.drop(columns=["DATE_FROM", "PRODUCTNAME", "hour"], inplace=True) + df.rename( + columns={ + "NL_SETTLEMENTCAPACITY_PRICE_[EUR/MW]": f"FCR Price NL [EUR/MW/{freq}]", + "DE_SETTLEMENTCAPACITY_PRICE_[EUR/MW]": f"FCR Price DE [EUR/MW/{freq}]", + }, + inplace=True, + ) + + try: + df[f"FCR Price NL [EUR/MW/{freq}]"] = df[ + f"FCR Price NL [EUR/MW/{freq}]" + ].astype(float) + df[f"FCR Price DE [EUR/MW/{freq}]"] = df[ + f"FCR Price NL [EUR/MW/{freq}]" + ].astype(float) + except Exception as e: + warnings.warn( + f"Could not convert data to floats. Should check... Exception: {e}" + ) + + df = df[~df.index.duplicated(keep="first")] + new_ix = pd.date_range( + start=df.index[0], end=df.index[-1], freq=freq, tz="Europe/Amsterdam" + ) + df = df.reindex(new_ix, method="ffill") + mult = {"H": 1, "4H": 4, "D": 24} + df[f"FCR Price NL [EUR/MW/{freq}]"] /= df["Timeblocks"] / mult[freq] + df[f"FCR Price DE [EUR/MW/{freq}]"] /= df["Timeblocks"] / mult[freq] + df = df[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + df.to_csv(path, sep=";", decimal=",", index_label="datetime") + return df + + +def get_tennet_data(exporttype, start, end): + """Download data from TenneT API + + TenneT documentation: + https://www.tennet.org/bedrijfsvoering/exporteer_data_toelichting.aspx + + Parameters: + ----------- + exporttype : str + Exporttype as defined in TenneT documentation. + start : pd.Timestamp + Start date + end : pd.Timestamp + End date + + Returns: + -------- + DataFrame with API output. + """ + datefrom = start.strftime("%d-%m-%Y") + dateto = end.strftime("%d-%m-%Y") + url = ( + f"http://www.tennet.org/bedrijfsvoering/ExporteerData.aspx?exporttype={exporttype}" + f"&format=csv&datefrom={datefrom}&dateto={dateto}&submit=1" + ) + + return pd.read_csv(url, decimal=",") + + +def get_imb_prices_nl(start: pd.Timestamp, end: pd.Timestamp) -> pd.DataFrame: + exporttype = "verrekenprijzen" + data = get_tennet_data(exporttype, start, end) + first_entry, last_entry = _get_index_first_and_last_entry(data, exporttype) + date_ix = pd.date_range(first_entry, last_entry, freq="15T", tz="Europe/Amsterdam") + + if len(data) == len(date_ix): + data.index = date_ix + else: + data = _handle_missing_data_by_reindexing(data) + + data = data[["invoeden", "Afnemen", "regeltoestand"]] + data.columns = ["POS", "NEG", "RS"] + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + return data + + +def get_balansdelta_nl(start: pd.Timestamp, end: pd.Timestamp) -> pd.DataFrame: + filename = f"balansdelta_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + path = Path("./data") / filename + if path.exists(): + data = pd.read_csv(path, sep=";", decimal=",", index_col="datetime") + startdate = pd.to_datetime(data.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(data.index[-1]).strftime("%Y-%m-%d %H:%M") + data.index = pd.date_range(startdate, enddate, freq="1T", tz="Europe/Amsterdam") + return data + + exporttype = "balansdelta2017" + data = get_tennet_data(exporttype, start, end) + first_entry, last_entry = _get_index_first_and_last_entry(data, exporttype) + date_ix = pd.date_range(first_entry, last_entry, freq="1T", tz="Europe/Amsterdam") + data.index = date_ix + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + if not path.exists(): + data.to_csv(path, sep=";", decimal=",", index_label="datetime") + return data + + +def _get_afrr_prices_from_entsoe(start, end, marketagreement_type, entsoe_api_key): + client = EntsoePandasClient(entsoe_api_key) + return client.query_contracted_reserve_prices( + country_code="NL", + start=start, + end=end + timedelta(days=1), + type_marketagreement_type=marketagreement_type, + ) + + +def get_afrr_capacity_fees_nl(start, end, entsoe_api_key=None): + path = Path( + f"./data/afrr_capacity_fees_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + ) + if path.exists(): + df = pd.read_csv(path, sep=";", decimal=",", index_col="datetime").astype(float) + startdate = pd.to_datetime(df.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(df.index[-1]).strftime("%Y-%m-%d %H:%M") + df.index = pd.date_range(startdate, enddate, freq="D", tz="Europe/Amsterdam") + return df + + if not entsoe_api_key: + try: + entsoe_api_key = os.environ["ENTSOE_API_KEY"] + except: + raise ValueError("Please enter ENTSOE API key") + + date_to_daily_bids = pd.to_datetime("2020-08-31").tz_localize("Europe/Amsterdam") + + if start < date_to_daily_bids: + _start = start - timedelta(days=7) + data = _get_afrr_prices_from_entsoe( + start=_start, + end=min(date_to_daily_bids, end), + marketagreement_type="A02", + entsoe_api_key=entsoe_api_key, + )[["Automatic frequency restoration reserve - Symmetric"]] + + if end > date_to_daily_bids: + _end = date_to_daily_bids - timedelta(days=1) + else: + _end = end + dt_index = pd.date_range(start, _end, freq="D", tz="Europe/Amsterdam") + data = data.reindex(dt_index, method="ffill") + + # ENTSOE: + # "Before week no. 1 of 2020 the values are published per period + # per MW (Currency/MW per procurement period); meaning that it + # is not divided by MTU/ISP in that period." + if start < pd.to_datetime("2019-12-23"): + data[: pd.to_datetime("2019-12-22")] /= 7 * 24 * 4 + + if end >= date_to_daily_bids: + _data = ( + _get_afrr_prices_from_entsoe( + start=max(date_to_daily_bids, start), + end=end, + marketagreement_type="A01", + entsoe_api_key=entsoe_api_key, + ) + .resample("D") + .first() + ) + cols = [ + "Automatic frequency restoration reserve - Down", + "Automatic frequency restoration reserve - Symmetric", + "Automatic frequency restoration reserve - Up", + ] + + for col in cols: + if col not in _data.columns: + _data[col] = np.NaN + + _data = _data[cols] + + try: + data = pd.concat([data, _data], axis=0) + except Exception: + data = _data + + data = data[start:end] + + new_col_names = { + "Automatic frequency restoration reserve - Down": "aFRR Down [€/MW/day]", + "Automatic frequency restoration reserve - Symmetric": "aFRR Symmetric [€/MW/day]", + "Automatic frequency restoration reserve - Up": "aFRR Up [€/MW/day]", + } + data.rename(columns=new_col_names, inplace=True) + hours_per_day = ( + pd.Series( + data=0, + index=pd.date_range( + start, + end + timedelta(days=1), + freq="15T", + tz="Europe/Amsterdam", + inclusive="left", + ), + ) + .resample("D") + .count() + ) + data = data.multiply(hours_per_day.values, axis=0).round(2) + if not path.exists(): + data.to_csv(path, sep=";", decimal=",", index_label="datetime") + return data + + +def _get_afrr_prices_nl_from_tennet(start, end): + """Get aFRR prices from TenneT API + + Parameters: + ----------- + start : pd.Timestamp + Start date + end : pd.Timestamp + End date + + Returns: + -------- + DataFrame with imbalance prices. + """ + filename = f"afrr_prices_nl_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + path = Path("./data") / filename + if path.exists(): + data = pd.read_csv(path, sep=";", decimal=",", index_col="datetime").astype( + float + ) + startdate = pd.to_datetime(data.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(data.index[-1]).strftime("%Y-%m-%d %H:%M") + data.index = pd.date_range( + startdate, enddate, freq="15T", tz="Europe/Amsterdam" + ) + return data + + data = get_tennet_data("verrekenprijzen", start, end) + first_entry, last_entry = _get_index_first_and_last_entry(data, "verrekenprijzen") + date_ix = pd.date_range(first_entry, last_entry, freq="15T", tz="Europe/Amsterdam") + + if len(data) == len(date_ix): + data.index = date_ix + else: + data = _handle_missing_data_by_reindexing(data) + + data = data[["opregelen", "Afregelen"]] + data.columns = ["price_up", "price_down"] + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + + if not path.exists(): + data.to_csv(path, sep=";", decimal=",", index_label="datetime") + return data + + +def get_afrr_prices_nl(start, end): + bd = get_balansdelta_nl(start=start, end=end)[ + ["Hoogste_prijs_opregelen", "Laagste_prijs_afregelen"] + ] + bd.columns = ["rt_price_UP", "rt_price_DOWN"] + afrr_prices = _get_afrr_prices_nl_from_tennet(start, end).reindex( + bd.index, method="ffill" + ) + return pd.concat([afrr_prices, bd], axis=1) + + +def _get_index_first_and_last_entry(data, exporttype): + if exporttype == "balansdelta2017": + time_col_name = "tijd" + elif exporttype == "verrekenprijzen": + time_col_name = "periode_van" + return [ + pd.to_datetime( + " ".join((data["datum"].iloc[ix], data[time_col_name].iloc[ix])), + format="%d-%m-%Y %H:%M", + ) + for ix in [0, -1] + ] + + +def _handle_missing_data_by_reindexing(data): + print("Warning: Entries missing from TenneT data.") + data.index = data[["datum", "periode_van"]].apply(lambda x: " ".join(x), axis=1) + data.index = pd.to_datetime(data.index, format="%d-%m-%Y %H:%M").tz_localize( + "Europe/Amsterdam", ambiguous=True + ) + data = data[~data.index.duplicated(keep="first")] + date_ix = pd.date_range( + data.index[0], data.index[-1], freq="15T", tz="Europe/Amsterdam" + ) + data = data.reindex(date_ix) + print("Workaround implemented: Dataset was reindexed automatically.") + return data + + +def get_imb_prices_be(startdate, enddate): + start = pd.to_datetime(startdate).tz_localize("Europe/Brussels").tz_convert("UTC") + end = ( + pd.to_datetime(enddate).tz_localize("Europe/Brussels") + timedelta(days=1) + ).tz_convert("UTC") + rows = int((end - start) / timedelta(minutes=15)) + resp_df = pd.DataFrame() + + while rows > 0: + print(f"Getting next chunk, {rows} remaining.") + chunk = min(3000, rows) + end = start + timedelta(minutes=chunk * 15) + resp_df = pd.concat([resp_df, elia_api_call(start, end)], axis=0) + start = end + rows -= chunk + + resp_df.index = pd.date_range( + start=resp_df.index[0], end=resp_df.index[-1], tz="Europe/Brussels", freq="15T" + ) + + resp_df.index.name = "datetime" + resp_df = resp_df[ + ["positiveimbalanceprice", "negativeimbalanceprice", "qualitystatus"] + ].rename(columns={"positiveimbalanceprice": "POS", "negativeimbalanceprice": "NEG"}) + resp_df["Validated"] = False + resp_df.loc[resp_df["qualitystatus"] == "Validated", "Validated"] = True + resp_df.drop(columns=["qualitystatus"], inplace=True) + return resp_df + + +def elia_api_call(start, end): + dataset = "ods047" + sort_by = "datetime" + url = "https://opendata.elia.be/api/records/1.0/search/" + rows = int((end - start) / timedelta(minutes=15)) + end = end - timedelta(minutes=15) + endpoint = ( + f"?dataset={dataset}&q=datetime:[{start.strftime('%Y-%m-%dT%H:%M:%SZ')}" + f" TO {end.strftime('%Y-%m-%dT%H:%M:%SZ')}]&rows={rows}&sort={sort_by}" + ) + + for _ in range(5): + try: + resp = requests.get(url + endpoint) + if resp.ok: + break + else: + raise Exception() + except Exception: + print("retrying...") + time.sleep(1) + + if not resp.ok: + raise Exception(f"Error when calling API. Status code: {resp.status_code}") + + resp_json = json.loads(resp.content) + resp_json = [entry["fields"] for entry in resp_json["records"]] + + df = pd.DataFrame(resp_json).set_index("datetime") + df.index = pd.to_datetime(df.index, utc=True).tz_convert("Europe/Brussels") + df = df.sort_index() + return df + + +def get_da_prices_from_entsoe( + start, end, country_code, tz, freq="H", entsoe_api_key=None +): + """Get Day-Ahead prices from ENTSOE + + Parameters: + ----------- + start : pd.Timestamp + Start date + end : pd.Timestamp + End date + freq : str + Frequency, e.g. '15T' or 'H' + + Returns: + -------- + Series with day-ahead prices. + """ + if not entsoe_api_key: + try: + entsoe_api_key = "f6c67fd5-e423-47bc-8a3c-98125ccb645e" + except: + raise ValueError("Please enter ENTSOE API key") + + client = EntsoePandasClient(entsoe_api_key) + data = client.query_day_ahead_prices( + country_code, start=start, end=end + timedelta(days=1) + ) + data = data[~data.index.duplicated()] + data.index = pd.date_range(data.index[0], data.index[-1], freq="H", tz=tz) + + if freq != "H": + data = _reindex_to_freq(data, freq, tz) + + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + return data + + +def _reindex_to_freq(data, freq, tz): + new_ix = pd.date_range( + data.index[0], + data.index[-1] + timedelta(hours=1), + freq=freq, + tz=tz, + ) + return data.reindex(index=new_ix, method="ffill") + + +def get_da_prices_nl(start, end, freq="H", entsoe_api_key=None): + return get_da_prices_from_entsoe( + start, end, "NL", "Europe/Amsterdam", freq=freq, entsoe_api_key=entsoe_api_key + ) + + +def get_da_prices_be(start, end, freq="H", entsoe_api_key=None): + return get_da_prices_from_entsoe( + start, end, "BE", "Europe/Brussels", freq=freq, entsoe_api_key=entsoe_api_key + ) + + +def get_ets_prices(start, end, freq="D"): + """Get CO2 prices (ETS) from ICE + + Values are in €/ton CO2 + + Parameters: + ----------- + start : datetime + Start date + end : datetime + End date + freq : str + Frequency, e.g. '15T' or 'H' + + Returns: + -------- + Series with ETS settlement prices with datetime index (local time) + """ + + start_x = start + timedelta(days=-2) + end_x = end + timedelta(days=2) + + data = get_ets_prices_from_database(start_x, end_x, 'NLD') + data = data.resample('1T').ffill() + data = data.loc[(data.index >= start) & (data.index < end)] + return data + + + # here = pytz.timezone("Europe/Amsterdam") + # start_file = pd.Timestamp(str(start.year) + "-1-1", tz=here).to_pydatetime() + # end_file = pd.Timestamp(str(start.year) + "-12-31", tz=here).to_pydatetime() + + # path = Path( + # f"./data/ets_prices_{freq}_{start_file.strftime('%Y%m%d')}_{end_file.strftime('%Y%m%d')}.csv" + # ) + # if path.exists(): + # return _load_from_csv(path, freq=freq) + # else: + # raise Exception("Data not available for chosen dates.") + + +def get_ttf_prices(start, end, freq="D"): + """Get Day-Ahead natural gas prices (TTF Day-ahead) from ICE + + Values are in €/MWh + + Parameters: + ----------- + start : datetime + Start date + end : datetime + End date + freq : str + Frequency, e.g. '15T' or 'H' + + Returns: + -------- + Series with TTF day-ahead prices with datetime index (local time) + + Start and End are converted into start of year and end of year + """ + + start_x = start + timedelta(days=-2) + end_x = end + timedelta(days=2) + + data = get_ttf_prices_from_database(start_x, end_x, 'NLD') + data = data.resample('1T').ffill() + data = data.loc[(data.index >= start) & (data.index < end)] + return data + + # # while start_year <= end_year: + # here = pytz.timezone("Europe/Amsterdam") + # start_file = pd.Timestamp(str(start.year) + "-1-1", tz=here).to_pydatetime() + # end_file = pd.Timestamp(str(start.year) + "-12-31", tz=here).to_pydatetime() + + # path = Path( + # f"./data/ttf_prices_{freq}_{start_file.strftime('%Y%m%d')}_{end_file.strftime('%Y%m%d')}.csv" + # ) + # print(path) + + # if path.exists(): + # return _load_from_csv(path, freq=freq) + # else: + # raise Exception("Data not available for chosen dates.") + + +def _load_from_csv(filepath, freq): + data = pd.read_csv( + filepath, + delimiter=";", + decimal=",", + parse_dates=False, + index_col="datetime", + ) + ix_start = pd.to_datetime(data.index[0], utc=True).tz_convert("Europe/Amsterdam") + ix_end = pd.to_datetime(data.index[-1], utc=True).tz_convert("Europe/Amsterdam") + data.index = pd.date_range(ix_start, ix_end, freq=freq, tz="Europe/Amsterdam") + return data.squeeze() + + +##### RECOY DATABASE QUERIES ##### + +def get_day_ahead_prices_from_database(start_hour, end_hour, CountryIsoCode, tz='utc'): + table = 'DayAheadPrices' + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter(and_( + table.columns['CountryIsoCode'] == CountryIsoCode, + table.columns['HourStartTime'] >= start_hour, + table.columns['HourStartTime'] < end_hour + )) + + data = pd.DataFrame(data) + data['HourStartTime'] = pd.to_datetime(data['HourStartTime'], utc=True) + data.index = data['HourStartTime'] + data.index.name = 'datetime' + data = data[['Price', 'CountryIsoCode']] + data.columns = ['DAM', 'CountryIsoCode'] + if tz.__eq__('utc') is False: + data = data.tz_convert(tz) + return data + + +def get_imbalance_prices_from_database(start_quarter, end_quarter, CountryIsoCode, tz='utc'): + table = 'ImbalancePrices' + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter(and_( + table.columns['CountryIsoCode'] == CountryIsoCode, + table.columns['QuarterStartTime'] >= start_quarter, + table.columns['QuarterStartTime'] < end_quarter + )) + + data = pd.DataFrame(data) + data['QuarterStartTime'] = pd.to_datetime(data['QuarterStartTime'], utc=True) + data.index = data['QuarterStartTime'] + data.index.name = 'datetime' + data = data[['FeedToGridPrice', 'TakeFromGridPrice', 'CountryIsoCode']] + data.columns = ['POS', 'NEG', 'CountryIsoCode'] + if tz.__eq__('utc') is False: + data = data.tz_convert(tz) + return data + + +def get_FCR_prices_from_database(start_day, end_day, CountryIsoCode, tz='utc'): + table = 'ReservePrices' + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter(and_( + table.columns['CountryIsoCode'] == CountryIsoCode, + table.columns['Timestamp'] >= start_day, + table.columns['Timestamp'] <= end_day, + table.columns['ReserveType'] == 'FCR' + )) + + data = pd.DataFrame(data) + data['Timestamp'] = pd.to_datetime(data['Timestamp'], utc=True) + data.index = data['Timestamp'] + data.index.name = 'datetime' + data = data[['PricePerMWPerISP', 'CountryIsoCode']] + if tz.__eq__('utc') is False: + data = data.tz_convert(tz) + return data + + +def get_imbalance_forecasts_from_database_on_publication_time(start_publication_time, end_publication_time, ForecastSources, CountryIsoCodes): + table = 'ImbalancePriceForecasts' + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter(and_( + table.columns['CountryIsoCode'].in_(CountryIsoCodes), + table.columns['PublicationTime'] >= start_publication_time, + table.columns['PublicationTime'] < end_publication_time, + table.columns['ForecastSource'].in_(ForecastSources) + )) + + return pd.DataFrame(data) + + +def get_imbalance_forecasts_from_database_on_quarter_start_time(start_quarter, end_quarter, ForecastSources, CountryIsoCode): + table = 'ImbalancePriceForecasts' + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter(and_( + table.columns['CountryIsoCode'] == CountryIsoCode, + table.columns['QuarterStartTime'] >= start_quarter, + table.columns['QuarterStartTime'] < end_quarter, + table.columns['PublicationTime'] < end_quarter, + table.columns['ForecastSource'].in_(ForecastSources) + )) + + return pd.DataFrame(data) + + +def get_ttf_prices_from_database(start, end, CountryIsoCode, tz='utc'): + if start.tzinfo != pytz.utc: + start = start.astimezone(pytz.utc) + if end.tzinfo != pytz.utc: + end = end.astimezone(pytz.utc) + + table = 'GasPrices' + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter(and_( + table.columns['CountryIsoCode'] == CountryIsoCode, + table.columns['Timestamp'] >= start, + table.columns['Timestamp'] < end + )) + + data = pd.DataFrame(data) + data['Timestamp'] = pd.to_datetime(data['Timestamp'], utc=True) + data.index = data['Timestamp'] + data.index.name = 'datetime' + data = data[['TTFPrice']] + data.columns = ['Gas prices (€/MWh)'] + if tz.__eq__('utc') is False: + data = data.tz_convert(tz) + return data + + +def get_ets_prices_from_database(start, end, CountryIsoCode, tz='utc'): + if start.tzinfo != pytz.utc: + start = start.astimezone(pytz.utc) + if end.tzinfo != pytz.utc: + end = end.astimezone(pytz.utc) + + table = 'Co2Prices' + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter(and_( + table.columns['CountryIsoCode'] == CountryIsoCode, + table.columns['Timestamp'] >= start, + table.columns['Timestamp'] < end + )) + + data = pd.DataFrame(data) + data['Timestamp'] = pd.to_datetime(data['Timestamp'], utc=True) + data.index = data['Timestamp'] + data.index.name = 'datetime' + data = data[['Price']] + data.columns = ['CO2 prices (€/MWh)'] + if tz.__eq__('utc') is False: + data = data.tz_convert(tz) + return data + diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/prices.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/prices.py new file mode 100644 index 0000000..1570e8c --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/prices.py @@ -0,0 +1,792 @@ +import os +from datetime import timedelta +from io import BytesIO +from pathlib import Path +from zipfile import ZipFile +import time +import warnings +import json +import pytz + +import numpy as np +import pandas as pd +import requests +from bs4 import BeautifulSoup +from entsoe.entsoe import EntsoePandasClient +from sqlalchemy import MetaData, Table, insert, and_, or_ +from pyrecoy import * + + +def get_fcr_prices(start, end, freq="H") -> pd.DataFrame: + """Get FCR settlement prices from Regelleistung website + + Returns: DataFrame with FCR prices with index with given time frequency in local time. + """ + start = start + timedelta(-1) + end = end + timedelta(1) + data = get_FCR_prices_from_database(start, end, "NLD") + data = data.resample("15T").ffill() + data = data[["PricePerMWPerISP"]] + data.columns = ["FCR NL (EUR/ISP)"] + data.index.name = "datetime" + data = data.tz_convert("Europe/Amsterdam") + return data + + path = Path( + f"./data/fcr_prices_{freq}_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + ) + if path.exists(): + df = pd.read_csv(path, sep=";", decimal=",", index_col="datetime").astype(float) + startdate = pd.to_datetime(df.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(df.index[-1]).strftime("%Y-%m-%d %H:%M") + df.index = pd.date_range( + startdate, enddate, freq=freq, tz="Europe/Amsterdam", name="datetime" + ) + return df + + dfs = [] + retry = 5 + for date in pd.date_range(start=start, end=end + timedelta(days=1)): + r = 0 + # print(f'DEBUG: {date}') + while r < retry: + try: + url = ( + f"https://www.regelleistung.net/apps/cpp-publisher/api/v1/download/tenders/" + f"resultsoverview?date={date.strftime('%Y-%m-%d')}&exportFormat=xlsx&market=CAPACITY&productTypes=FCR" + ) + df = pd.read_excel(url, engine="openpyxl")[ + [ + "DATE_FROM", + "PRODUCTNAME", + "NL_SETTLEMENTCAPACITY_PRICE_[EUR/MW]", + "DE_SETTLEMENTCAPACITY_PRICE_[EUR/MW]", + ] + ] + # print(f'DEBUG: {date} read in') + dfs.append(df) + break + except Exception: + # print(r) + time.sleep(1) + r += 1 + warnings.warn( + f'No data received for {date.strftime("%Y-%m-%d")}. Retrying...({r}/{retry})' + ) + + if r == retry: + raise RuntimeError(f'No data received for {date.strftime("%Y-%m-%d")}') + + df = pd.concat(dfs, axis=0) + df["hour"] = df["PRODUCTNAME"].map(lambda x: int(x.split("_")[1])) + df["Timeblocks"] = ( + df["PRODUCTNAME"].map(lambda x: int(x.split("_")[2])) - df["hour"] + ) + df.index = df.apply( + lambda row: pd.to_datetime(row["DATE_FROM"]) + timedelta(hours=row["hour"]), + axis=1, + ).dt.tz_localize("Europe/Amsterdam") + df.drop(columns=["DATE_FROM", "PRODUCTNAME", "hour"], inplace=True) + df.rename( + columns={ + "NL_SETTLEMENTCAPACITY_PRICE_[EUR/MW]": f"FCR Price NL [EUR/MW/{freq}]", + "DE_SETTLEMENTCAPACITY_PRICE_[EUR/MW]": f"FCR Price DE [EUR/MW/{freq}]", + }, + inplace=True, + ) + + try: + df[f"FCR Price NL [EUR/MW/{freq}]"] = df[ + f"FCR Price NL [EUR/MW/{freq}]" + ].astype(float) + df[f"FCR Price DE [EUR/MW/{freq}]"] = df[ + f"FCR Price NL [EUR/MW/{freq}]" + ].astype(float) + except Exception as e: + warnings.warn( + f"Could not convert data to floats. Should check... Exception: {e}" + ) + + df = df[~df.index.duplicated(keep="first")] + new_ix = pd.date_range( + start=df.index[0], end=df.index[-1], freq=freq, tz="Europe/Amsterdam" + ) + df = df.reindex(new_ix, method="ffill") + mult = {"H": 1, "4H": 4, "D": 24} + df[f"FCR Price NL [EUR/MW/{freq}]"] /= df["Timeblocks"] / mult[freq] + df[f"FCR Price DE [EUR/MW/{freq}]"] /= df["Timeblocks"] / mult[freq] + df = df[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + df.to_csv(path, sep=";", decimal=",", index_label="datetime") + return df + + +def get_tennet_data(exporttype, start, end): + """Download data from TenneT API + + TenneT documentation: + https://www.tennet.org/bedrijfsvoering/exporteer_data_toelichting.aspx + + Parameters: + ----------- + exporttype : str + Exporttype as defined in TenneT documentation. + start : pd.Timestamp + Start date + end : pd.Timestamp + End date + + Returns: + -------- + DataFrame with API output. + """ + datefrom = start.strftime("%d-%m-%Y") + dateto = end.strftime("%d-%m-%Y") + url = ( + f"http://www.tennet.org/bedrijfsvoering/ExporteerData.aspx?exporttype={exporttype}" + f"&format=csv&datefrom={datefrom}&dateto={dateto}&submit=1" + ) + + return pd.read_csv(url, decimal=",") + + +def get_imb_prices_nl(start: pd.Timestamp, end: pd.Timestamp) -> pd.DataFrame: + exporttype = "verrekenprijzen" + data = get_tennet_data(exporttype, start, end) + first_entry, last_entry = _get_index_first_and_last_entry(data, exporttype) + date_ix = pd.date_range(first_entry, last_entry, freq="15T", tz="Europe/Amsterdam") + + if len(data) == len(date_ix): + data.index = date_ix + else: + data = _handle_missing_data_by_reindexing(data) + + data = data[["invoeden", "Afnemen", "regeltoestand"]] + data.columns = ["POS", "NEG", "RS"] + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + return data + + +def get_balansdelta_nl(start: pd.Timestamp, end: pd.Timestamp) -> pd.DataFrame: + filename = f"balansdelta_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + path = Path("./data") / filename + if path.exists(): + data = pd.read_csv(path, sep=";", decimal=",", index_col="datetime") + startdate = pd.to_datetime(data.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(data.index[-1]).strftime("%Y-%m-%d %H:%M") + data.index = pd.date_range(startdate, enddate, freq="1T", tz="Europe/Amsterdam") + return data + + exporttype = "balansdelta2017" + data = get_tennet_data(exporttype, start, end) + first_entry, last_entry = _get_index_first_and_last_entry(data, exporttype) + date_ix = pd.date_range(first_entry, last_entry, freq="1T", tz="Europe/Amsterdam") + data.index = date_ix + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + if not path.exists(): + data.to_csv(path, sep=";", decimal=",", index_label="datetime") + return data + + +def _get_afrr_prices_from_entsoe(start, end, marketagreement_type, entsoe_api_key): + client = EntsoePandasClient(entsoe_api_key) + return client.query_contracted_reserve_prices( + country_code="NL", + start=start, + end=end + timedelta(days=1), + type_marketagreement_type=marketagreement_type, + ) + + +def get_afrr_capacity_fees_nl(start, end, entsoe_api_key=None): + path = Path( + f"./data/afrr_capacity_fees_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + ) + if path.exists(): + df = pd.read_csv(path, sep=";", decimal=",", index_col="datetime").astype(float) + startdate = pd.to_datetime(df.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(df.index[-1]).strftime("%Y-%m-%d %H:%M") + df.index = pd.date_range(startdate, enddate, freq="D", tz="Europe/Amsterdam") + return df + + if not entsoe_api_key: + try: + entsoe_api_key = os.environ["ENTSOE_API_KEY"] + except: + raise ValueError("Please enter ENTSOE API key") + + date_to_daily_bids = pd.to_datetime("2020-08-31").tz_localize("Europe/Amsterdam") + + if start < date_to_daily_bids: + _start = start - timedelta(days=7) + data = _get_afrr_prices_from_entsoe( + start=_start, + end=min(date_to_daily_bids, end), + marketagreement_type="A02", + entsoe_api_key=entsoe_api_key, + )[["Automatic frequency restoration reserve - Symmetric"]] + + if end > date_to_daily_bids: + _end = date_to_daily_bids - timedelta(days=1) + else: + _end = end + dt_index = pd.date_range(start, _end, freq="D", tz="Europe/Amsterdam") + data = data.reindex(dt_index, method="ffill") + + # ENTSOE: + # "Before week no. 1 of 2020 the values are published per period + # per MW (Currency/MW per procurement period); meaning that it + # is not divided by MTU/ISP in that period." + if start < pd.to_datetime("2019-12-23"): + data[: pd.to_datetime("2019-12-22")] /= 7 * 24 * 4 + + if end >= date_to_daily_bids: + _data = ( + _get_afrr_prices_from_entsoe( + start=max(date_to_daily_bids, start), + end=end, + marketagreement_type="A01", + entsoe_api_key=entsoe_api_key, + ) + .resample("D") + .first() + ) + cols = [ + "Automatic frequency restoration reserve - Down", + "Automatic frequency restoration reserve - Symmetric", + "Automatic frequency restoration reserve - Up", + ] + + for col in cols: + if col not in _data.columns: + _data[col] = np.NaN + + _data = _data[cols] + + try: + data = pd.concat([data, _data], axis=0) + except Exception: + data = _data + + data = data[start:end] + + new_col_names = { + "Automatic frequency restoration reserve - Down": "aFRR Down [€/MW/day]", + "Automatic frequency restoration reserve - Symmetric": "aFRR Symmetric [€/MW/day]", + "Automatic frequency restoration reserve - Up": "aFRR Up [€/MW/day]", + } + data.rename(columns=new_col_names, inplace=True) + hours_per_day = ( + pd.Series( + data=0, + index=pd.date_range( + start, + end + timedelta(days=1), + freq="15T", + tz="Europe/Amsterdam", + inclusive="left", + ), + ) + .resample("D") + .count() + ) + data = data.multiply(hours_per_day.values, axis=0).round(2) + if not path.exists(): + data.to_csv(path, sep=";", decimal=",", index_label="datetime") + return data + + +def _get_afrr_prices_nl_from_tennet(start, end): + """Get aFRR prices from TenneT API + + Parameters: + ----------- + start : pd.Timestamp + Start date + end : pd.Timestamp + End date + + Returns: + -------- + DataFrame with imbalance prices. + """ + filename = f"afrr_prices_nl_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + path = Path("./data") / filename + if path.exists(): + data = pd.read_csv(path, sep=";", decimal=",", index_col="datetime").astype( + float + ) + startdate = pd.to_datetime(data.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(data.index[-1]).strftime("%Y-%m-%d %H:%M") + data.index = pd.date_range( + startdate, enddate, freq="15T", tz="Europe/Amsterdam" + ) + return data + + data = get_tennet_data("verrekenprijzen", start, end) + first_entry, last_entry = _get_index_first_and_last_entry(data, "verrekenprijzen") + date_ix = pd.date_range(first_entry, last_entry, freq="15T", tz="Europe/Amsterdam") + + if len(data) == len(date_ix): + data.index = date_ix + else: + data = _handle_missing_data_by_reindexing(data) + + data = data[["opregelen", "Afregelen"]] + data.columns = ["price_up", "price_down"] + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + + if not path.exists(): + data.to_csv(path, sep=";", decimal=",", index_label="datetime") + return data + + +def get_afrr_prices_nl(start, end): + bd = get_balansdelta_nl(start=start, end=end)[ + ["Hoogste_prijs_opregelen", "Laagste_prijs_afregelen"] + ] + bd.columns = ["rt_price_UP", "rt_price_DOWN"] + afrr_prices = _get_afrr_prices_nl_from_tennet(start, end).reindex( + bd.index, method="ffill" + ) + return pd.concat([afrr_prices, bd], axis=1) + + +def _get_index_first_and_last_entry(data, exporttype): + if exporttype == "balansdelta2017": + time_col_name = "tijd" + elif exporttype == "verrekenprijzen": + time_col_name = "periode_van" + return [ + pd.to_datetime( + " ".join((data["datum"].iloc[ix], data[time_col_name].iloc[ix])), + format="%d-%m-%Y %H:%M", + ) + for ix in [0, -1] + ] + + +def _handle_missing_data_by_reindexing(data): + print("Warning: Entries missing from TenneT data.") + data.index = data[["datum", "periode_van"]].apply(lambda x: " ".join(x), axis=1) + data.index = pd.to_datetime(data.index, format="%d-%m-%Y %H:%M").tz_localize( + "Europe/Amsterdam", ambiguous=True + ) + data = data[~data.index.duplicated(keep="first")] + date_ix = pd.date_range( + data.index[0], data.index[-1], freq="15T", tz="Europe/Amsterdam" + ) + data = data.reindex(date_ix) + print("Workaround implemented: Dataset was reindexed automatically.") + return data + + +def get_imb_prices_be(startdate, enddate): + start = pd.to_datetime(startdate).tz_localize("Europe/Brussels").tz_convert("UTC") + end = ( + pd.to_datetime(enddate).tz_localize("Europe/Brussels") + timedelta(days=1) + ).tz_convert("UTC") + rows = int((end - start) / timedelta(minutes=15)) + resp_df = pd.DataFrame() + + while rows > 0: + print(f"Getting next chunk, {rows} remaining.") + chunk = min(3000, rows) + end = start + timedelta(minutes=chunk * 15) + resp_df = pd.concat([resp_df, elia_api_call(start, end)], axis=0) + start = end + rows -= chunk + + resp_df.index = pd.date_range( + start=resp_df.index[0], end=resp_df.index[-1], tz="Europe/Brussels", freq="15T" + ) + + resp_df.index.name = "datetime" + resp_df = resp_df[ + ["positiveimbalanceprice", "negativeimbalanceprice", "qualitystatus"] + ].rename(columns={"positiveimbalanceprice": "POS", "negativeimbalanceprice": "NEG"}) + resp_df["Validated"] = False + resp_df.loc[resp_df["qualitystatus"] == "Validated", "Validated"] = True + resp_df.drop(columns=["qualitystatus"], inplace=True) + return resp_df + + +def elia_api_call(start, end): + dataset = "ods047" + sort_by = "datetime" + url = "https://opendata.elia.be/api/records/1.0/search/" + rows = int((end - start) / timedelta(minutes=15)) + end = end - timedelta(minutes=15) + endpoint = ( + f"?dataset={dataset}&q=datetime:[{start.strftime('%Y-%m-%dT%H:%M:%SZ')}" + f" TO {end.strftime('%Y-%m-%dT%H:%M:%SZ')}]&rows={rows}&sort={sort_by}" + ) + + for _ in range(5): + try: + resp = requests.get(url + endpoint) + if resp.ok: + break + else: + raise Exception() + except Exception: + print("retrying...") + time.sleep(1) + + if not resp.ok: + raise Exception(f"Error when calling API. Status code: {resp.status_code}") + + resp_json = json.loads(resp.content) + resp_json = [entry["fields"] for entry in resp_json["records"]] + + df = pd.DataFrame(resp_json).set_index("datetime") + df.index = pd.to_datetime(df.index, utc=True).tz_convert("Europe/Brussels") + df = df.sort_index() + return df + + +def get_da_prices_from_entsoe( + start, end, country_code, tz, freq="H", entsoe_api_key=None +): + """Get Day-Ahead prices from ENTSOE + + Parameters: + ----------- + start : pd.Timestamp + Start date + end : pd.Timestamp + End date + freq : str + Frequency, e.g. '15T' or 'H' + + Returns: + -------- + Series with day-ahead prices. + """ + if not entsoe_api_key: + try: + entsoe_api_key = "f6c67fd5-e423-47bc-8a3c-98125ccb645e" + except: + raise ValueError("Please enter ENTSOE API key") + + client = EntsoePandasClient(entsoe_api_key) + data = client.query_day_ahead_prices( + country_code, start=start, end=end + timedelta(days=1) + ) + data = data[~data.index.duplicated()] + data.index = pd.date_range(data.index[0], data.index[-1], freq="H", tz=tz) + + if freq != "H": + data = _reindex_to_freq(data, freq, tz) + + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + return data + + +def _reindex_to_freq(data, freq, tz): + new_ix = pd.date_range( + data.index[0], + data.index[-1] + timedelta(hours=1), + freq=freq, + tz=tz, + ) + return data.reindex(index=new_ix, method="ffill") + + +def get_da_prices_nl(start, end, freq="H", entsoe_api_key=None): + return get_da_prices_from_entsoe( + start, end, "NL", "Europe/Amsterdam", freq=freq, entsoe_api_key=entsoe_api_key + ) + + +def get_da_prices_be(start, end, freq="H", entsoe_api_key=None): + return get_da_prices_from_entsoe( + start, end, "BE", "Europe/Brussels", freq=freq, entsoe_api_key=entsoe_api_key + ) + + +def get_ets_prices(start, end, freq="D"): + """Get CO2 prices (ETS) from ICE + + Values are in €/ton CO2 + + Parameters: + ----------- + start : datetime + Start date + end : datetime + End date + freq : str + Frequency, e.g. '15T' or 'H' + + Returns: + -------- + Series with ETS settlement prices with datetime index (local time) + """ + + start_x = start + timedelta(days=-2) + end_x = end + timedelta(days=2) + + data = get_ets_prices_from_database(start_x, end_x, "NLD") + data = data.resample("1T").ffill() + data = data.loc[(data.index >= start) & (data.index < end)] + return data + + here = pytz.timezone("Europe/Amsterdam") + start_file = pd.Timestamp(str(start.year) + "-1-1", tz=here).to_pydatetime() + end_file = pd.Timestamp(str(start.year) + "-12-31", tz=here).to_pydatetime() + + path = Path( + f"./data/ets_prices_{freq}_{start_file.strftime('%Y%m%d')}_{end_file.strftime('%Y%m%d')}.csv" + ) + if path.exists(): + return _load_from_csv(path, freq=freq) + else: + raise Exception("Data not available for chosen dates.") + + +def get_ttf_prices(start, end, freq="D"): + """Get Day-Ahead natural gas prices (TTF Day-ahead) from ICE + + Values are in €/MWh + + Parameters: + ----------- + start : datetime + Start date + end : datetime + End date + freq : str + Frequency, e.g. '15T' or 'H' + + Returns: + -------- + Series with TTF day-ahead prices with datetime index (local time) + + Start and End are converted into start of year and end of year + """ + + start_x = start + timedelta(days=-2) + end_x = end + timedelta(days=2) + + data = get_ttf_prices_from_database(start_x, end_x, "NLD") + data = data.resample("1T").ffill() + data = data.loc[(data.index >= start) & (data.index < end)] + return data + + # while start_year <= end_year: + here = pytz.timezone("Europe/Amsterdam") + start_file = pd.Timestamp(str(start.year) + "-1-1", tz=here).to_pydatetime() + end_file = pd.Timestamp(str(start.year) + "-12-31", tz=here).to_pydatetime() + + path = Path( + f"./data/ttf_prices_{freq}_{start_file.strftime('%Y%m%d')}_{end_file.strftime('%Y%m%d')}.csv" + ) + + if path.exists(): + return _load_from_csv(path, freq=freq) + else: + raise Exception("Data not available for chosen dates.") + + +def _load_from_csv(filepath, freq): + data = pd.read_csv( + filepath, + delimiter=";", + decimal=",", + parse_dates=False, + index_col="datetime", + ) + ix_start = pd.to_datetime(data.index[0], utc=True).tz_convert("Europe/Amsterdam") + ix_end = pd.to_datetime(data.index[-1], utc=True).tz_convert("Europe/Amsterdam") + data.index = pd.date_range(ix_start, ix_end, freq=freq, tz="Europe/Amsterdam") + return data.squeeze() + + +##### RECOY DATABASE QUERIES ##### + + +def convert_columns_to_localized_datetime_from_utc(df, columns, tz): + for column in columns: + df[column] = pd.to_datetime(df[column], utc=True) + df[column] = df[column].dt.tz_convert(tz) + return df + + +def get_price_data_from_database( + database_name, + time_index_column, + database_columns, + rename_columns, + start, + end, + CountryIsoCode, + tz="utc", + to_datetime_columns=[], +): + """_summary_ + + Args: + database_name (string): name of the database + time_index_column (string): column which is converted to a datetime column and used as the index + database_columns (list of strings): columns of the database table you want to query + rename_columns (list of strings): new names for the columns which are queried + start (string or datetime): start time of the data you want to select based on the time_index_column + end (string or datetime): end time of the data you want to select based on the time_index_column + CountryIsoCode (string): CountryIsoCode of the data + tz (str, optional): Timezone you want the datatime columns to be converted to + to_datetime_columns (list, optional): Additional columns which are transferred to datetime columns. Defaults to []. + + Returns: + _type_: _description_ + """ + table = database_name + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter( + and_( + table.columns["CountryIsoCode"] == CountryIsoCode, + table.columns[time_index_column] >= start, + table.columns[time_index_column] < end, + ) + ) + data = pd.DataFrame(data) + data[time_index_column] = pd.to_datetime(data[time_index_column], utc=True) + data.index = data[time_index_column] + data.index.name = "datetime" + data = data[database_columns + ["CountryIsoCode"]] + data.columns = rename_columns + ["CountryIsoCode"] + if tz.__eq__("utc") is False: + data = data.tz_convert(tz) + data = convert_columns_to_localized_datetime_from_utc(data, to_datetime_columns, tz) + return data + + +def get_day_ahead_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_price_data_from_database( + "DayAheadPrices", + "HourStartTime", + ["Price"], + ["DAM"], + start, + end, + CountryIsoCode, + tz=tz, + ) + + +def get_imbalance_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_price_data_from_database( + "ImbalancePrices", + "QuarterStartTime", + ["FeedToGridPrice", "TakeFromGridPrice"], + ["POS", "NEG"], + start, + end, + CountryIsoCode, + tz=tz, + ) + + +def get_imbalance_forecasts_from_database_on_publication_time( + start, end, CountryIsoCode, tz="utc" +): + return get_price_data_from_database( + "ImbalancePriceForecasts", + "PublicationTime", + ["PublicationTime", "QuarterStartTime", "FeedToGridPrice", "TakeFromGridPrice"], + ["PublicationTime", "QuarterStartTime", "ForePos", "ForeNeg"], + start, + end, + CountryIsoCode, + tz=tz, + to_datetime_columns=["QuarterStartTime"], + ) + + +def get_imbalance_forecasts_from_database_on_quarter_start_time( + start, end, CountryIsoCode, tz="utc" +): + return get_price_data_from_database( + "ImbalancePriceForecasts", + "QuarterStartTime", + ["PublicationTime", "QuarterStartTime", "FeedToGridPrice", "TakeFromGridPrice"], + ["PublicationTime", "QuarterStartTime", "ForePos", "ForeNeg"], + start, + end, + CountryIsoCode, + tz=tz, + to_datetime_columns=["QuarterStartTime"], + ) + + +def get_ttf_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_price_data_from_database( + "GasPrices", + "DeliveryDate", + ["Price"], + ["Gas prices (€/MWh)"], + start, + end, + CountryIsoCode, + tz=tz, + ) + + +def get_ets_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_price_data_from_database( + "Co2Prices", + "DeliveryDate", + ["Price"], + ["CO2 prices (€/MWh)"], + start, + end, + CountryIsoCode, + tz=tz, + ) + + +def get_reserve_prices_from_database( + start, end, reserve_type, CountryIsoCode, tz="utc" +): + data = get_price_data_from_database( + "ReservePrices", + "Timestamp", + ["PricePerMWPerISP", "ReserveType"], + ["PricePerMWPerISP", "ReserveType"], + start, + end, + CountryIsoCode, + tz=tz, + ) + data = data.loc[data["ReserveType"] == reserve_type] + return data + + +def get_FCR_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_reserve_prices_from_database(start, end, "FCR", CountryIsoCode, tz=tz) + + +def get_aFRR_up_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_reserve_prices_from_database( + start, end, "aFRR Up", CountryIsoCode, tz=tz + ) + + +def get_aFRR_up_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_reserve_prices_from_database( + start, end, "aFRR Down", CountryIsoCode, tz=tz + ) + + +def get_aFRR_up_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_reserve_prices_from_database( + start, end, "mFRR Up", CountryIsoCode, tz=tz + ) + + +def get_aFRR_up_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_reserve_prices_from_database( + start, end, "mFRR Up", CountryIsoCode, tz=tz + ) diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/reports.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/reports.py new file mode 100644 index 0000000..6108272 --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/reports.py @@ -0,0 +1,156 @@ +import numpy as np +import pandas as pd + +from .styling import businesscase_formatter, num_formatting, perc_formatting + + +class CaseReport: + """Dataframe report showing KPIs for specific CaseStudy. + + Parameters: + ----------- + case : CaseStudy + kind : str + The report type. {electr_market_results', cashflows', 'ebitda_calc'}. + baseline : CaseStudy + include_perc: bool + """ + + def __init__(self, case, kind): + self._check_if_attr_exists(case, kind) + case_data = getattr(case, kind) + self.report = self.create_report(case.name, case_data) + self.formatting = "number" + + def _check_if_attr_exists(self, case, kind): + if not hasattr(case, kind): + raise AttributeError( + f"Attribute '{kind}' is not available for '{case.name}' case. " + "You should first generate it using " + "the appropriate CaseStudy method." + ) + + def create_report(self, case_name, case_data): + if isinstance(case_data, dict): + case_data = pd.Series(case_data) + + return pd.DataFrame(case_data, columns=[case_name]) + + def show(self, presentation_format=True): + if not presentation_format: + return self.report + + if self.formatting == "percentage": + return self.report.applymap(perc_formatting) + else: + return self.report.applymap(num_formatting) + + +class ComparisonReport(CaseReport): + """Dataframe report showing a copmarison of KPIs between CaseStudy instances. + + Parameters: + ----------- + cases : list + List of CaseStudy instances + kind : str + Type of report + baseline : CaseStudy + CaseStudy instance to use as baseline + comparison : str + {'absolute', 'relative', 'percentage'} + Sets how the numbers in the comparison are in relation to the baseline. + """ + + def __init__(self, cases, kind, baseline=None, comparison="absolute"): + case_reports = [] + self.formatting = "number" + + for case in cases: + case_report = CaseReport(case=case, kind=kind).report + case_reports.append(case_report) + + self.report = pd.concat(case_reports, axis=1).fillna(0) + + if comparison == "relative": + self._comp_relative(baseline) + elif comparison == "percentage": + self._comp_percentage(baseline) + + # ugly fix to make sure EBITDA is at the bottom when df is printed + if kind == "ebitda_calc": + ix = self.report.index.to_list() + ix.remove("EBITDA (€)") + ix.remove("Depreciation (€)") + ix.remove("EBITDA + depr (€)") + ix.append("EBITDA (€)") + ix.append("Depreciation (€)") + ix.append("EBITDA + depr (€)") + self.report = self.report.reindex(ix) + + def _comp_relative(self, baseline): + baseline_report = self.report[baseline.name] + self.report = self.report.subtract(baseline_report, axis=0) + + if baseline.name in self.report.columns: + self.report.drop(columns=baseline.name, inplace=True) + if baseline.name in self.report.index: + self.report.drop(index=baseline.name, inplace=True) + + self.formatting = "number" + + def _comp_percentage(self, baseline): + baseline_report = self.report[baseline.name] + self.report = self.report.divide(baseline_report / 100, axis=0).replace( + [-np.inf, np.inf], 0 + ) + self.report.replace([-np.inf, np.inf], 0, inplace=True) + self.formatting = "percentage" + + +class BusinessCaseReport(CaseReport): + """Show business case for CaseStudy""" + + def __init__(self, case, presentation_format=False): + self._check_if_attr_exists(case, "business_case") + self.report = getattr(case, "business_case") + + def show(self, presentation_format=True): + if presentation_format: + return businesscase_formatter(self.report) + else: + return self.report + + +class SingleFigureComparison(ComparisonReport): + def __init__( + self, + cases, + kpi, + label, + baseline=None, + comparison="absolute", + ): + figure_dict = {} + for case in cases: + self._check_if_attr_exists(case, kpi) + figure_dict[case.name] = getattr(case, kpi) + + self.report = pd.Series(figure_dict, name=label) + + if comparison == "relative": + self._comp_relative(baseline) + elif comparison == "percentage": + self._comp_percentage(baseline) + + def show(self, nformat=None): + if nformat is not None: + return self.report.apply(nformat.format) + else: + return self.report + + def _comp_relative(self, baseline): + baseline_report = self.report[baseline.name] + self.report = self.report.subtract(baseline_report, axis=0) + self.report.drop(index=baseline.name, inplace=True) + self.formatting = "number" diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/rop_assets.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/rop_assets.py new file mode 100644 index 0000000..41f604a --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/rop_assets.py @@ -0,0 +1,34 @@ +def get_power_profiles(start, end, country, in_local_time=True): + start = timestamp_to_utc(start) + end = timestamp_to_utc(end) + engine = db_engine("rop_test") + connection, table = create_connection(engine, "ImbalancePrices") + start = start.floor("15T") + query = ( + select([table]) + .where( + table.columns.QuarterStartTime >= start.strftime("%Y-%m-%d %H:%M"), + table.columns.QuarterStartTime < end.strftime("%Y-%m-%d %H:%M"), + table.columns.CountryIsoCode == country, + ) + .order_by(table.columns.QuarterStartTime) + ) + result = connection.execute(query).fetchall() + if len(result) == 0: + raise Exception("Day-ahead prices data not yet available.") + + data = pd.DataFrame(result, columns=result[0].keys()) + + if in_local_time: + data["QuarterStartTime"] = dt_column_to_local_time(data["QuarterStartTime"]) + + data.drop(columns=["Id", "CountryIsoCode"], inplace=True) + data.rename( + columns={ + "QuarterStartTime": "datetime", + "TakeFromGridPrice": "NEG", + "FeedToGridPrice": "POS", + }, + inplace=True, + ) + return data.set_index("datetime")[["POS", "NEG"]] \ No newline at end of file diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/rop_prices.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/rop_prices.py new file mode 100644 index 0000000..9ab908a --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/rop_prices.py @@ -0,0 +1,92 @@ +from sqlalchemy import select +import pandas as pd +from .converters import dt_column_to_local_time, timestamp_to_utc +from .databases import db_engine, create_connection + + +def get_imbalance_prices(start, end, country, in_local_time=True): + start = timestamp_to_utc(start) + end = timestamp_to_utc(end) + engine = db_engine("rop_prices_test") + connection, table = create_connection(engine, "ImbalancePrices") + start = start.floor("15T") + query = ( + select([table]) + .where( + table.columns.QuarterStartTime >= start.strftime("%Y-%m-%d %H:%M"), + table.columns.QuarterStartTime < end.strftime("%Y-%m-%d %H:%M"), + table.columns.CountryIsoCode == country, + ) + .order_by(table.columns.QuarterStartTime) + ) + result = connection.execute(query).fetchall() + if len(result) == 0: + raise Exception("Day-ahead prices data not yet available.") + + data = pd.DataFrame(result, columns=result[0].keys()) + + if in_local_time: + data["QuarterStartTime"] = dt_column_to_local_time(data["QuarterStartTime"]) + + data.drop(columns=["Id", "CountryIsoCode"], inplace=True) + data.rename( + columns={ + "QuarterStartTime": "datetime", + "TakeFromGridPrice": "NEG", + "FeedToGridPrice": "POS", + }, + inplace=True, + ) + return data.set_index("datetime")[["POS", "NEG"]] + + +def get_dayahead_prices(start, end, country, in_local_time=True): + start = timestamp_to_utc(start) + end = timestamp_to_utc(end) + engine = db_engine("rop_prices_test") + connection, table = create_connection(engine, "DayAheadPrices") + start = start.floor("60T") + query = ( + select([table]) + .where( + table.columns.HourStartTime >= start.strftime("%Y-%m-%d %H:%M"), + table.columns.HourStartTime < end.strftime("%Y-%m-%d %H:%M"), + table.columns.CountryIsoCode == country, + ) + .order_by(table.columns.HourStartTime) + ) + result = connection.execute(query).fetchall() + if len(result) == 0: + raise Exception("Day-ahead prices data not yet available.") + + data = pd.DataFrame(result, columns=result[0].keys()) + + if in_local_time: + data["HourStartTime"] = dt_column_to_local_time(data["HourStartTime"]) + + data.drop(columns=["Id", "CountryIsoCode"], inplace=True) + data.rename(columns={"HourStartTime": "datetime", "Price": "DAM"}, inplace=True) + return data.set_index("datetime") + + +def get_market_price_data(start, end, country, in_local_time=True): + tz = "Europe/Amsterdam" if in_local_time else "UTC" + dt_ix = pd.date_range( + start=start.floor("H"), + end=end.ceil("H"), + freq="15T", + tz=tz, + inclusive="left", + ) + prices = pd.DataFrame(index=dt_ix, columns=["DAM", "POS", "NEG"]) + prices["DAM"] = get_dayahead_prices( + start, end, country=country, in_local_time=in_local_time + ).reindex(dt_ix, method="ffill") + prices["DAM"].fillna(method="ffill", inplace=True) + + imbprices = get_imbalance_prices( + start, end, country=country, in_local_time=in_local_time + ) + prices["POS"] = imbprices["POS"] + prices["NEG"] = imbprices["NEG"] + return prices diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/sensitivity.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/sensitivity.py new file mode 100644 index 0000000..3c5628f --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/sensitivity.py @@ -0,0 +1,225 @@ +import itertools +import gc +from copy import deepcopy +from tkinter import Label +import warnings + +import pandas as pd +import numpy as np +from tqdm.notebook import tqdm +from millify import millify +from plotly.graph_objs import Figure + +from .casestudy import CaseStudy +from .colors import recoygreen, recoyred + + +class SensitivityAnalysis: + """ + Runs an simulation routine with different input configurations, + so that sensitivity of variables can be analysed. + """ + + def __init__(self, c, s, routine, param, values, output_kpis): + self.configs = self._generate_configs(c, param, values) + output_dict = self._prepare_output_dict(s.cases, output_kpis) + self.kpis = self._run_sensitivities(s, routine, output_kpis, output_dict) + + def _generate_configs(self, c, param, values): + configs = {} + for value in values: + _c = deepcopy(c) + setattr(_c, param, value) + configs[value] = _c + return configs + + def _prepare_output_dict(self, cases, output_kpis): + output_dict = dict.fromkeys(self.configs.keys()) + for value in self.configs: + output_dict[value] = dict.fromkeys(output_kpis) + for kpi in output_kpis: + output_dict[value][kpi] = dict.fromkeys([case.name for case in cases]) + return output_dict + + def _run_sensitivities(self, s, routine, output_kpis, output_dict): + for name, c in tqdm(self.configs.items()): + _s = deepcopy(s) + _s = routine(c, _s) + for kpi in output_kpis: + for case in _s.cases: + output_dict[name][kpi][case.name] = getattr(case, kpi, np.nan) + del _s + gc.collect() + return output_dict + + def single_kpi_overview(self, kpi, case_names=None): + """Creates a DataFrame with chosen output kpi, + for each CaseStudy in each Configuration. + """ + if not case_names: + case_names = CaseStudy.instances.keys() + + kpi_values = { + name: {case: self.kpis[name][kpi][case] for case in case_names} + for name in self.kpis.keys() + } + + return pd.DataFrame(kpi_values).T + + def cashflows_comparison(self, case=None, baseline=None): + ebitda_calc_overview = {} + baseline_calc = {} + for input_value, kpi_data in self.kpis.items(): + for kpi, case_data in kpi_data.items(): + for case_name, data in case_data.items(): + if kpi == "cashflows": + if case_name == case: + ebitda_calc_overview[input_value] = data + if case_name == baseline: + baseline_calc[input_value] = data + + ebitda_calc_overview = pd.DataFrame(ebitda_calc_overview) + if not baseline: + return ebitda_calc_overview + + baseline_calc = pd.DataFrame(baseline_calc) + return ebitda_calc_overview.subtract(baseline_calc, fill_value=0) + + +class SensitivityMatrix: + def __init__(self, c, s, routine, x_param, y_param, x_vals, y_vals, output_kpis): + self.x_param = x_param + self.y_param = y_param + + self.configs = self._generate_configs(c, x_vals, y_vals) + output_dict = self._prepare_output_dict(s.cases, output_kpis) + self.kpis = self._run_sensitivities(s, routine, output_kpis, output_dict) + + def _generate_configs(self, c, x_vals, y_vals): + configs = {x_val: dict.fromkeys(y_vals) for x_val in x_vals} + + self.xy_combinations = list(itertools.product(x_vals, y_vals)) + for x_val, y_val in self.xy_combinations: + _c = deepcopy(c) + setattr(_c, self.x_param, x_val) + setattr(_c, self.y_param, y_val) + configs[x_val][y_val] = _c + return configs + + def _prepare_output_dict(self, cases, output_kpis): + output_dict = {} + for name in [case.name for case in cases]: + output_dict[name] = dict.fromkeys(output_kpis) + for kpi in output_kpis: + output_dict[name][kpi] = deepcopy(self.configs) + return output_dict + + def _run_sensitivities(self, s, routine, output_kpis, output_dict): + for x_val, y_val in tqdm(self.xy_combinations): + _c = self.configs[x_val][y_val] + _s = deepcopy(s) + _s = routine(_c, _s) + for kpi in output_kpis: + for case in _s.cases: + output = getattr(case, kpi, np.nan) + output_dict[case.name][kpi][x_val][y_val] = output + del _s + del _c + gc.collect() + return output_dict + + def show_matrix(self, case_name, kpi): + """ + Creates a DataFrame with chosen output kpi, + for each XY combination + """ + matrix = pd.DataFrame(self.kpis[case_name][kpi]) + matrix.columns.name = self.x_param + matrix.index.name = self.y_param + return matrix + + +class ScenarioAnalysis(SensitivityAnalysis): + def __init__(self, c, s, routine, params_dict, labels, output_kpis): + self.labels = labels + self.configs = self._generate_configs(c, params_dict, labels) + output_dict = self._prepare_output_dict(s.cases, output_kpis) + self.kpis = self._run_sensitivities(s, routine, output_kpis, output_dict) + + def _generate_configs(self, c, params_dict, labels): + configs = {} + for i, label in enumerate(labels): + _c = deepcopy(c) + for param, values in params_dict.items(): + setattr(_c, param, values[i]) + configs[label] = _c + return configs + + +class TornadoChart: + """ + TODO: Absolute comparison instead of relative + """ + + def __init__(self, c, s, routine, case, tornado_vars, output_kpis): + self.case = case + self.kpis = self._run_sensitivities( + c, s, routine, case, tornado_vars, output_kpis + ) + + def _run_sensitivities(self, c, s, routine, case, tornado_vars, output_kpis): + labels = ["Low", "Medium", "High"] + outputs = {kpi: pd.DataFrame(index=labels) for kpi in output_kpis} + + for param, values in tornado_vars.items(): + sens = SensitivityAnalysis(c, s, routine, param, values, output_kpis) + + for kpi in output_kpis: + output = sens.single_kpi_overview(kpi, case_names=[case.name])[ + case.name + ] + output.index = labels + outputs[kpi][" ".join((param, str(values)))] = output + + for kpi in output_kpis: + base_performance = deepcopy(outputs[kpi].loc["Medium", :]) + for scen in labels: + scen_performance = outputs[kpi].loc[scen, :] + relative_performance = (scen_performance / base_performance - 1) * 100 + outputs[kpi].loc[scen, :] = relative_performance + + outputs[kpi] = outputs[kpi].round(1) + outputs[kpi].sort_values(by="Low", axis=1, ascending=False, inplace=True) + return outputs + + def show_chart( + self, kpi, dimensions=(800, 680), title="Tornado Chart", sort_by="Low" + ): + outputs = self.kpis[kpi].sort_values(by=sort_by, axis=1, ascending=False) + traces = [] + colors = {"Low": recoyred, "High": recoygreen} + + for scenario in ["Low", "High"]: + trace = { + "type": "bar", + "x": outputs.loc[scenario, :].tolist(), + "y": outputs.columns, + "orientation": "h", + "name": scenario, + "marker": {"color": colors[scenario]}, + } + traces.append(trace) + + layout = { + "title": title, + "width": dimensions[0], + "height": dimensions[1], + "barmode": "relative", + "autosize": True, + "showlegend": True, + } + fig = Figure(data=traces, layout=layout) + fig.update_xaxes( + title_text=f"{kpi.upper()} % change compared to base scenario (Base {kpi.upper()} = {millify(getattr(self.case, kpi))})" + ) + return fig diff --git a/pyrecoy/pyrecoy/build/lib/pyrecoy/styling.py b/pyrecoy/pyrecoy/build/lib/pyrecoy/styling.py new file mode 100644 index 0000000..bc224cf --- /dev/null +++ b/pyrecoy/pyrecoy/build/lib/pyrecoy/styling.py @@ -0,0 +1,47 @@ +from copy import deepcopy +from numbers import Number +import numpy as np + + +def num_formatting(val): + if np.isnan(val) or round(val, 0) == 0: + return "-" + else: + return f"{val:,.0f}" + + +def perc_formatting(val): + if np.isnan(val) or round(val, 0) == 0: + return "-" + else: + return f"{val:.1f}%" + + +def bc_formatting(val): + if not isinstance(val, Number): + return val + if np.isnan(val): + return "" + elif round(val, 2) == 0: + return "-" + else: + return f"{val:,.0f}" + + +def businesscase_formatter(df): + df_c = deepcopy(df) + + spp = df_c.loc["Simple Payback Period", "Year 0"] + spp_str = "N/A" if np.isnan(spp) else str(spp) + " years" + df_c.loc["Simple Payback Period", "Year 0"] = spp_str + + irr = df_c.loc["IRR (%)", "Year 0"] + if np.isnan(irr): + df_c.loc["IRR (%)", "Year 0"] = "N/A" + + df_c = df_c.applymap(bc_formatting) + + if not np.isnan(irr): + df_c.loc["IRR (%)", "Year 0"] += "%" + df_c.loc["WACC (%)", "Year 0"] += "%" + return df_c diff --git a/pyrecoy/pyrecoy/dist/pyrecoy-0.1-py3.9.egg b/pyrecoy/pyrecoy/dist/pyrecoy-0.1-py3.9.egg new file mode 100644 index 0000000000000000000000000000000000000000..6b32d2b1f0159524199e7bc9421fa95f918b9d5b GIT binary patch literal 95081 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

Y@S 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 max_power: + raise ValueError("'min_power' can not be larger than 'max_power'.") + + self.name = name + self.id = next(self._ids) + self.max_power = max_power + self.min_power = min_power + self.modes = {"max": max_power, "min": min_power} + + def __repr__(self): + return f"{self.__class__.__name__}(self, max_power={self.max_power}, min_power={self.min_power})" + + def set_load(self, load): + """Set Asset load in MW. + + Convention is negative value for consumption and positive value + for production. Subclasses might use a different convention if + this seems more intiutive. + + Returns the load that is set in MW. + """ + if load < self.min_power or load > self.max_power: + warnings.warn( + f"Chosen Asset load for {self.name} is out of range. " + f"Should be between {self.min_power} and {self.max_power}. " + f"Function will return boundary load level for now." + ) + load = min(max(load, self.min_power), self.max_power) + return load + + def set_mode(self, mode): + """ """ + load = self.modes[mode] + return self.set_load(load) + + def MW_to_MWh(self, MW): + """Performs conversion from MW to MWh using the time_factor variable.""" + return MW * self.time_factor + + def MWh_to_MW(self, MWh): + """Performs conversion from MWh to MW using the time_factor variable.""" + return MWh / self.time_factor + + def set_freq(self, freq): + """ + Function that aligns time frequency between Model and Asset. + Can be '1T', '15T' or 'H' + The time_factor variable is used in subclasses to perform MW to MWh conversions. + """ + self.freq = freq + self.time_factor = Asset._freq_to_multiplier[freq] + + def set_financials( + self, capex, opex, devex, lifetime=None, depreciate=True, salvage_value=0 + ): + """Set financial data of the asset.""" + self.capex = capex + self.opex = opex + self.devex = devex + self.lifetime = lifetime + self.depreciate = depreciate + self.salvage_value = salvage_value + + +class Eboiler(Asset): + """Subclass for an E-boiler.""" + + def __init__(self, name, max_power, min_power=0, efficiency=0.99): + super().__init__(name, min_power=-max_power, max_power=-min_power) + self.efficiency = efficiency + self.max_thermal_output = max_power * 0.99 + + def __repr__(self): + return ( + f"{self.__class__.__name__}(name={self.name}, max_power={self.max_power}, " + f"min_power={self.min_power}, efficiency={self.efficiency})" + ) + + def set_load(self, load): + """Set load in MWe, returns (load, heat_output) in MWe and MWth + + Convention is negative numbers for consumption. + Inserting a positive value will return an exception. + """ + + if load > 0: + raise ValueError( + f"Eboiler.set_load() only accepts negative numbers by convention. " + f"{load} was inserted." + ) + + load = super().set_load(load) + heat_output = -load * self.efficiency + return (load, heat_output) + + def set_heat_output(self, heat_output): + """Set heat output in MWth, returns tuple (heat_output, eload) in MW""" + load = -heat_output / self.efficiency + load, heat_output = self.set_load(load) + return heat_output, load + + +class Heatpump(Asset): + """Subclass for a Heatpump. + + Use cop parameter to set fixed COP (float/int) or COP curve (func). + COP curve should take load in MWhe and return COP. + + Parameters: + ----------- + max_th_power : numeric + Maximum thermal output in MW (positive value) + cop_curve : numeric or list or function + 3 ways to set the COP of the Heatpump: + (1) Fixed COP based on [numeric] value. + (2) Polynomial with coefficients based on [list] input. + + Input coeficients in format [c0, c1, c2, ..., c(n)], + will generate Polynomial p(x) = c0 + c1*x + c2*x^2 ... cn*x^n, + where x = % thermal load (in % of thermal capacity) as decimal value. + + Example: + cop=[1, 2, 3, 4] will result in following COP curve: + p(x) = 1 + 2x + 3x**2 + 4x**3, + + (3) [function] in format func(*args, **kwargs) + Function should return a Polynomial that takes 'load_perc' as parameter. + + min_th_power : numeric + Minimum thermal output in MW (positive value) + + Notes: + ------ + Sign convention: + Thermal power outputs have positive values + Electric power inputs have negative values + """ + + def __init__( + self, + name, + max_th_power, + cop_curve, + min_th_power=0, + ): + if max_th_power < 0 or min_th_power < 0: + raise ValueError("Thermal power can not have negative values.") + + if min_th_power > max_th_power: + raise ValueError("'min_th_power' can not be larger than 'max_th_power'.") + + self.name = name + self.max_th_power = max_th_power + self.min_th_power = min_th_power + self.cop_curve = self._set_cop_curve(cop_curve) + + def __repr__(self): + return ( + f"{self.__class__.__name__}(name='{self.name}', max_thermal_power={self.max_th_power}, " + f"cop_curve={self.cop_curve}, min_th_power={self.min_th_power})" + ) + + # Is turning everything into a Polynomial the best solution here? + @staticmethod + @lru_cache(maxsize=None) + def _set_cop_curve(cop_curve): + """Generate COP curve function based on different inputtypes. + + Returns a function that takes *args **kwargs and returns a Polynomial. + """ + if isinstance(cop_curve, list): + + def func(*args, **kwargs): + return Polynomial(cop_curve) + + return func + + return cop_curve + + @lru_cache(maxsize=None) + def get_cop(self, heat_output, Tsink=None, Tsource=None): + """Get COP corresponding to certain load. + + Parameters: + ----------- + heat_output : numeric + Thermal load in MW + Tsink : numeric + Sink temperature in degrees celcius + Tsource : numeric + Source temperature in degrees celcius + + Notes: + ------ + Sign convention: + Positive values for thermal load + Negative values for electric load + """ + load_perc = heat_output / self.max_th_power + cop_curve = self.cop_curve + + if not callable(cop_curve): + return cop_curve + else: + return cop_curve(Tsink=Tsink, Tsource=Tsource)(load_perc) + + def th_to_el_power(self, heat_output, Tsink=None, Tsource=None): + if not self.min_th_power <= heat_output <= self.max_th_power: + warnings.warn( + f"Chosen heat output is out of range [{self.min_th_power} - {self.max_th_power}]. " + "Heat output is being limited to the closest boundary." + ) + heat_output = min(max(heat_output, self.min_th_power), self.max_th_power) + + cop = self.get_cop(heat_output=heat_output, Tsink=Tsink, Tsource=Tsource) + return -heat_output / cop + + def set_load(self, *args, **kwargs): + raise NotImplementedError( + "Directly setting the electric load of the heatpump is not possible (yet). " + "Functionality will be implemented if there is a specific usecase for it." + ) + + @lru_cache(maxsize=None) + def set_heat_output(self, heat_output, Tsink=None, Tsource=None): + """Set heat output in MWth, returns load of heatpump as tuple (MWe, MWth)""" + if not self.min_th_power <= heat_output <= self.max_th_power: + warnings.warn( + f"Chosen heat output is out of range [{self.min_th_power} - {self.max_th_power}]. " + "Heat output is being limited to the closest boundary." + ) + heat_output = min(max(heat_output, self.min_th_power), self.max_th_power) + + if Tsink is not None and Tsource is not None and Tsink <= Tsource: + raise ValueError(f"Tsource '{Tsource}' can not be higher than '{Tsink}'.") + + cop = self.get_cop(heat_output=heat_output, Tsink=Tsink, Tsource=Tsource) + e_load = -heat_output / cop + return e_load, heat_output + + def _cost_function(self, x, c1, c2, c3, Tsink=None, Tsource=None): + """Objective function for set_opt_load function. + + x = heatpump thermal load in MW + c1 = electricity_cost + c2 = alt_heat_price + c3 = demand + """ + return ( + x / self.get_cop(heat_output=x, Tsink=Tsink, Tsource=Tsource) * c1 + + (c3 - x) * c2 + ) + + @lru_cache(maxsize=None) + def set_opt_load( + self, + electricity_cost, + alt_heat_price, + demand, + Tsink=None, + Tsource=None, + tolerance=0.01, + ): + """Set optimal load of Heatpump with minimal total heat costs. + + Function uses np.minimize_scalar to minimize cost function. + + Parameters: + ----------- + electricity_cost: + Cost of input electricity in €/MWh(e) + alt_heat_price: + Price of heat from alternative source in €/MWh(th) + demand: + Heat demand in MW(th) + + Returns: + -------- + Optimal load of heatpump as tuple (MWe, MWth) + """ + c1 = electricity_cost + c2 = alt_heat_price + c3 = demand + + cop_curve = self.cop_curve + if isinstance(cop_curve, Number): + if c1 / cop_curve <= c2: + return self.max_th_power + else: + return self.min_th_power + + obj_func = partial( + self._cost_function, c1=c1, c2=c2, c3=c3, Tsink=Tsink, Tsource=Tsource + ) + + low_bound = 0 + up_bound = min(c3, self.max_th_power) + + opt_th_load = minimize_scalar( + obj_func, + bounds=(low_bound, up_bound), + method="bounded", + options={"xatol": tolerance}, + ).x + opt_e_load, opt_th_load = self.set_heat_output( + opt_th_load, Tsink=Tsink, Tsource=Tsource + ) + + return opt_e_load, opt_th_load + + +class Battery(Asset): + """Subclass for a Battery. + + Battery is modeled as follows: + - Rated power is power in MW that battery can + import from and export to the grid + - Efficiency loss is applied at charging, meaning that + SoC increase when charging is lower than the SoC decrease + when discharging + """ + + def __init__( + self, + name, + rated_power, + rated_capacity, + roundtrip_eff, + min_soc=0, + max_soc=1, + soc_at_start=None, + cycle_lifetime=None, + ): + super().__init__(name=name, max_power=rated_power, min_power=-rated_power) + self.capacity = rated_capacity + self.min_soc = min_soc + self.max_soc = max_soc + self.min_chargelevel = min_soc * self.capacity + self.max_chargelevel = max_soc * self.capacity + self.rt_eff = roundtrip_eff + self.one_way_eff = np.sqrt(roundtrip_eff) + self.cycle_count = 0 + self.cycle_lifetime = cycle_lifetime + + soc_at_start = min_soc if soc_at_start is None else soc_at_start + self.set_chargelevel(soc_at_start * self.capacity) + + def __repr__(self): + return ( + f"Battery(self, rated_power={self.max_power}, rated_capacity={self.capacity}, " + f"roundtrip_eff={self.rt_eff}, min_soc={self.min_soc}, max_soc={self.max_soc})" + ) + + def get_soc(self): + """Get the SoC in % (decimal value)""" + return self.chargelevel / self.capacity + + def set_chargelevel(self, chargelevel): + """Set the chargelevel in MWh. Will automatically change the SoC accordingly.""" + # if round(chargelevel,2) < round(self.min_chargelevel,2) or round(chargelevel,2) > round(self.max_chargelevel,2): + # raise ValueError( + # f"Tried to set Charge Level to {chargelevel}. " + # f"Charge Level must be a value between " + # f"{self.min_chargelevel} and {self.max_chargelevel} (in MWh)" + # ) + + self.chargelevel = chargelevel + + def set_load(self, load): + """Set load of the battery. + + Use negative values for charging and positive values for discharging. + Returns actual chargespeed, considering technical limitations of the battery. + + Note: We currently assume all efficiency losses occur during charging (no losses during discharge) + """ + if not hasattr(self, "freq"): + raise AttributeError( + "Time frequency of the model is not defined. " + "Assign asset to a CaseStudy or use Asset.freq(). " + "to set de time frequency and try again." + ) + + load = super().set_load(load) + + unbound_charging = self.MW_to_MWh(load) + + if load < 0: + unbound_charging *= self.rt_eff + + chargelevel = self.chargelevel + max_charging = chargelevel - self.max_chargelevel + max_discharging = chargelevel - self.min_chargelevel + + bound_charging = min(max(unbound_charging, max_charging), max_discharging) + newcl = chargelevel - bound_charging + self.set_chargelevel(newcl) + + if bound_charging < 0: + bound_charging /= self.rt_eff + + self.cycle_count += abs(bound_charging / (self.capacity * 2)) + + return self.MWh_to_MW(bound_charging) + + def charge(self, chargespeed): + """Charge the battery with given chargespeed. + + Redirects to Battery.set_load(). + Returns load (negative value for charging). + """ + chargespeed = self.max_power if chargespeed == "max" else chargespeed + + if chargespeed < 0: + raise ValueError( + f"Chargespeed should be always be a positive value by convention. " + f"Inserted {chargespeed}." + ) + + chargespeed = self.set_load(-chargespeed) + + return chargespeed + + def discharge(self, dischargespeed): + """Discharge the battery by given amount. + + Redirects to Battery.set_load(). + Returns load (positive value for discharging). + """ + dischargespeed = self.max_power if dischargespeed == "max" else dischargespeed + + if dischargespeed < 0: + raise ValueError( + f"Dischargespeed should be always be a positive value by convention. " + f"Inserted {dischargespeed}." + ) + + dischargespeed = self.set_load(dischargespeed) + + return dischargespeed + + def get_cost_per_cycle(self, cycle_lifetime): + return self.capex / self.cycle_lifetime + + +class EV(Battery): + def __init__( + self, + name, + rated_power, + rated_capacity, + roundtrip_eff, + min_soc=0, + max_soc=1, + soc_at_start=None, + id=None, + ): + super().__init__( + name, + rated_power, + rated_capacity, + roundtrip_eff, + min_soc, + max_soc, + soc_at_start, + ) + if id: + self.id = id + + +class HotWaterStorage(Battery): + """Subclass for a storage asset. + + Parameters: + ----------- + rated_capacity : int/float + Rated capacity in MWh + min_buffer_level_perc : float + Minimum buffer level in % + buffer_level_at_start : float + Buffer level at start in % + """ + + def __init__( + self, + name, + rated_power, + capacity_per_volume, + volume, + temperature, + min_storagelevel, + initial_storagelevel=None, + ): + rated_capacity = capacity_per_volume * volume + + if not initial_storagelevel: + initial_storagelevel = min_storagelevel + soc_at_start = initial_storagelevel / rated_capacity + max_storagelevel = rated_capacity * 0.95 + min_soc = min_storagelevel / rated_capacity + max_soc = max_storagelevel / rated_capacity + self.temperature = temperature + + super().__init__( + name=name, + rated_power=rated_power, + rated_capacity=rated_capacity, + roundtrip_eff=1, + min_soc=min_soc, + max_soc=max_soc, + soc_at_start=soc_at_start, + ) + + def __repr__(self): + return ( + f"{self.__class__.__name__}(name={self.name}, rated_power={self.max_power}, capacity={self.capacity}, " + f"temperature={self.temperature}, min_storagelevel={self.min_chargelevel})" + ) + + @property + def charging_power_limit(self): + max_charging_energy = self.max_chargelevel - self.chargelevel + return min(self.MWh_to_MW(max_charging_energy), -self.min_power) + + @property + def discharging_power_limit(self): + max_discharging_energy = self.chargelevel - self.min_chargelevel + return min(self.MWh_to_MW(max_discharging_energy), self.max_power) + + +class GasBoiler(Asset): + """Representation of a Gas-fired boiler. + + name : str + Unique name of the asset + max_th_output : numeric + Maximum thermal output in MW thermal + efficiency : float + Thermal efficiency of the gasboiler as decimal value. + min_th_output : numeric + Minimum thermal output in MW thermal + """ + + def __init__( + self, + name, + max_th_output, + min_th_output=0, + efficiency=0.9, + ): + super().__init__(name=name, max_power=max_th_output, min_power=min_th_output) + self.efficiency = efficiency + + def __repr__(self): + return ( + f"{self.__class__.__name__}(name={self.name}, max_power={self.max_power}, " + f"min_power={self.min_power}, efficiency={self.efficiency})" + ) + + def set_load(self, *args, **kwargs): + raise NotImplementedError( + "Gasboiler does not have electric load. " + "Use Gasboiler.set_heat_output() instead." + ) + + @lru_cache(maxsize=None) + def set_heat_output(self, output): + """Redirect to Gasboiler.set_load()""" + heat_output = super().set_load(output) + gas_input = -heat_output / self.efficiency + return heat_output, gas_input + + +class Electrolyser(Asset): + def __init__( + self, + name, + rated_power, + kwh_per_kg=60, + min_flex_load_in_perc=15, + ): + min_flex_power = min_flex_load_in_perc / 100 * rated_power + + super().__init__(name=name, max_power=-min_flex_power, min_power=-rated_power) + + self.rated_power = rated_power + self.min_flex_load = min_flex_load_in_perc + self.min_flex_power = self.min_flex_load / 100 * self.rated_power + self.kwh_per_kg = kwh_per_kg + self.kg_per_MWh = 1000 / self.kwh_per_kg + + def __repr__(self): + return ( + f"Electrolyser(name={self.name}, rated_power={self.rated_power}, " + f"kwh_per_kg={self.kwh_per_kg}, flex_range_in_perc=[{self.min_flex_load}, " + f"{self.max_flex_load}])" + ) + + def set_load(self, load): + """Set load of the Electrolyser in MW.""" + if not hasattr(self, "freq"): + raise AttributeError( + "Time frequency of the model is not defined. " + "Assign asset to a CaseStudy or use Asset.freq(). " + "to set de time frequency and try again." + ) + + load = -abs(load) + load = super().set_load(load) + + h2_output_kg = self.MW_to_MWh(-load) * self.kg_per_MWh + return load, h2_output_kg + + +class Battolyser(Asset): + def __init__( + self, + name, + rated_power, + rated_capacity, + rt_eff, + soc_at_start=None, + ): + super().__init__(name=name, max_power=rated_power, min_power=-rated_power) + + self.capacity = rated_capacity + self.min_soc = 0.05 + self.max_soc = 1.00 + self.min_chargelevel = self.min_soc * self.capacity + self.max_chargelevel = self.max_soc * self.capacity + self.rt_eff = rt_eff + self.cycle_count = 0 + + soc_at_start = self.min_soc if soc_at_start is None else soc_at_start + self.set_chargelevel(soc_at_start * self.capacity) + + def __repr__(self): + return ( + f"Battolyser(name={self.name}, rated_power={self.max_power}, " + f"rated_capacity={self.capacity}, rt_eff={self.rt_eff})" + ) + + def get_soc(self): + """Get the SoC in % (decimal value)""" + return self.chargelevel / self.capacity + + def set_chargelevel(self, chargelevel): + """Set the chargelevel in MWh. Will automatically change the SoC accordingly.""" + if chargelevel < self.min_chargelevel or chargelevel > self.max_chargelevel: + raise ValueError( + f"Tried to set Charge Level to {chargelevel}. " + f"Charge Level must be a value between " + f"{self.min_chargelevel} and {self.max_chargelevel} (in MWh)" + ) + self.chargelevel = chargelevel + + def set_load(self, load): + """Set load of the Battolyser in MW. + + Use negative values for charging and positive values for discharging. + Returns actual chargespeed, considering technical limitations of the battery. + + Note: We currently assume all efficiency losses occur during discharging + (no losses during charging) + """ + if not hasattr(self, "freq"): + raise AttributeError( + "Time frequency of the model is not defined. " + "Assign asset to a CaseStudy or use Asset.freq(). " + "to set de time frequency and try again." + ) + + load = super().set_load(load) + + unbound_charging = self.MW_to_MWh(load) + if load > 0: + unbound_charging /= self.rt_eff + + chargelevel = self.chargelevel + max_charging = chargelevel - self.max_chargelevel + max_discharging = chargelevel - self.min_chargelevel + bound_charging = min(max(unbound_charging, max_charging), max_discharging) + newcl = chargelevel - bound_charging + self.set_chargelevel(newcl) + + if bound_charging > 0: + bound_charging *= self.rt_eff + charging_power = self.MWh_to_MW(bound_charging) + h2_power = -self.MWh_to_MW(max(bound_charging - unbound_charging, 0)) + self.cycle_count += abs(bound_charging / (self.capacity * 2)) + return charging_power, h2_power + + def charge(self, chargespeed): + """Charge the battery with given chargespeed. + + Redirects to Battery.set_load(). + Returns load (negative value for charging). + """ + chargespeed = self.max_power if chargespeed == "max" else chargespeed + + if chargespeed < 0: + raise ValueError( + f"Chargespeed should be always be a positive value by convention. " + f"Inserted {chargespeed}." + ) + + chargespeed, h2_prod_in_MW = self.set_load(-chargespeed) + + return chargespeed, h2_prod_in_MW + + def discharge(self, dischargespeed): + """Discharge the battery by given amount. + + Redirects to Battery.set_load(). + Returns load (positive value for discharging). + """ + dischargespeed = self.max_power if dischargespeed == "max" else dischargespeed + + if dischargespeed < 0: + raise ValueError( + f"Dischargespeed should be always be a positive value by convention. " + f"Inserted {dischargespeed}." + ) + + dischargespeed = self.set_load(dischargespeed)[0] + return dischargespeed + + +##Added by Shahla, very similar to Hotwaterstorage +class HeatBuffer(Battery): + """Subclass for a storage asset. + + Parameters: + ----------- + rated_capacity : int/float + Rated capacity in MWh + min_buffer_level_perc : float + Minimum buffer level in % + buffer_level_at_start : float + Buffer level at start in % + """ + + def __init__( + self, name, rated_capacity, min_buffer_level_perc, buffer_level_at_start + ): + super().__init__( + name=name, + rated_power=100, + rated_capacity=rated_capacity, + roundtrip_eff=1, + min_soc=min_buffer_level_perc, + max_soc=1, + soc_at_start=buffer_level_at_start, + ) diff --git a/pyrecoy/pyrecoy/pyrecoy/basepath.py b/pyrecoy/pyrecoy/pyrecoy/basepath.py new file mode 100644 index 0000000..0ca1bfd --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/basepath.py @@ -0,0 +1,11 @@ +import os +from pathlib import Path + +if os.environ.get("USERNAME") == "mekre": + BASEPATH = Path("C:\\Users\\mekre\\") +elif os.environ.get("USERNAME") == "christiaan.buitelaar": + BASEPATH = Path("C:\\Users\\christiaan.buitelaar\\Documents\\GitHub\\asset-case-studies\\") +elif os.environ.get("USERNAME") == "karel.van.doesburg": + BASEPATH = Path("C:\\Users\\karel.van.doesburg\\Documents\\asset_studies_recoy\\") +elif os.environ.get("USERNAME") == "shahla.huseynova": + BASEPATH = Path("C:\\Users\\shahla.huseynova\\Documents\\asset_studies_recoy\\asset-case-studies\\") diff --git a/pyrecoy/pyrecoy/pyrecoy/casestudy.py b/pyrecoy/pyrecoy/pyrecoy/casestudy.py new file mode 100644 index 0000000..355a3d1 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/casestudy.py @@ -0,0 +1,548 @@ +import warnings +from copy import deepcopy + +import numpy as np +import pandas as pd + +from .framework import TimeFramework +from .financial import ( + calc_business_case, + calc_co2_costs, + calc_electr_market_results, + calc_grid_costs, + calculate_eb_ode, +) +from .forecasts import Mipf, Qipf +from .prices import get_ets_prices, get_ets_prices_excel, get_ttf_prices +from .converters import EURpertonCO2_to_EURperMWh + + +class CaseStudy: + """ + Representation of a casestudy + """ + + instances = {} + + def __init__(self, time_fw: TimeFramework, freq, name, data=None, forecast=None): + self.name = name + self.modelled_time_period_years = time_fw.modelled_time_period_years + self.start = time_fw.start + self.end = time_fw.end + self.freq = freq + self.dt_index = time_fw.dt_index(freq) + self.data = pd.DataFrame(index=self.dt_index) + self.assets = {} + self.cashflows = {} + self.irregular_cashflows = {} + self.capex = {} + self.total_capex = 0 + self.kpis = {} + + amount_of_days_in_year = 365 + + if self.start.year % 4 == 0: + amount_of_days_in_year = 366 + + self.year_case_duration = (self.end - self.start).total_seconds() / ( + 3600 * 24 * amount_of_days_in_year + ) + self.days_case_duration = self.year_case_duration * amount_of_days_in_year + self.hours_case_duration = self.days_case_duration * 24 + self.quarters_case_duration = self.days_case_duration * 24 * 4 + self.minutes_case_duration = self.days_case_duration * 24 * 60 + # self.year_case_duration = 1 + + if data is not None: + if len(data) != len(self.data): + raise ValueError( + "Length of data is not same as length of CaseStudy.data" + ) + data.index = self.dt_index + self.data = pd.concat([self.data, data], axis=1) + + if forecast is not None: + self.add_forecast(forecast, freq) + + CaseStudy.instances[self.name] = self + + @classmethod + def list_instances(cls): + """ + Returns a list with all CaseStudy instances. + Useful if you want to iterate over all instances + or use them as input to a function. + """ + return list(cls.instances.values()) + + def add_forecast(self, forecast, freq): + """ + Add forecast and price data to the data table of the CaseStudy instance. + """ + # TODO Add error handling for frequencies + if forecast == "mipf" and freq == "1T": + forecast_data = Mipf( + start=self.start, end=self.end, tidy=True, include_nextQ=False + ).data + elif forecast == "mipf" and freq == "15T": + forecast_data = Mipf( + start=self.start, end=self.end, tidy=False, include_nextQ=False + ).data + elif forecast == "qipf": + forecast_data = Qipf(start=self.start, end=self.end, freq=self.freq).data + else: + raise ValueError("Forecast does not exist. Use 'mipf' or 'qipf'.") + + self.data = pd.concat([self.data, forecast_data], axis=1) + + def add_gasprices(self): + """ + Add gas price data (TTF day-head) to the data table of the CaseStudy instance. + """ + self.data["Gas prices (€/MWh)"] = get_ttf_prices( + start=self.start, end=self.end, freq=self.freq + )["Gas prices (€/MWh)"] + + def add_co2prices(self, perMWh=False): + """ + Add CO2 prices (ETS) data to the data table of the CaseStudy instance. + """ + self.data["CO2 prices (€/ton)"] = get_ets_prices( + start=self.start, end=self.end, freq=self.freq + )["CO2 prices (€/MWh)"] + + if perMWh: + self.data["CO2 prices (€/MWh)"] = EURpertonCO2_to_EURperMWh( + self.data["CO2 prices (€/ton)"] + ).round(2) + + def add_co2prices_excel(self, perMWh=False): + """ + Add CO2 prices (ETS) data to the data table of the CaseStudy instance. + """ + self.data["CO2 prices (€/ton)"] = get_ets_prices_excel( + start=self.start, end=self.end, freq=self.freq + )["CO2 prices (€/ton)"] + + if perMWh: + self.data["CO2 prices (€/MWh)"] = EURpertonCO2_to_EURperMWh( + self.data["CO2 prices (€/ton)"] + ).round(2) + + def add_asset(self, asset): + """Assign an Asset instance to CaseStudy instance. + + Method will create a unique copy of the Asset instance. + If Asset contains financial information, + cashflows are automatically updated. + """ + assetcopy = deepcopy(asset) + assetcopy.set_freq(self.freq) + self.assets[assetcopy.name] = assetcopy + + if hasattr(assetcopy, "opex"): + self.add_cashflow(f"{assetcopy.name} OPEX (€)", -assetcopy.opex) + + if hasattr(assetcopy, "capex"): + self.add_capex(f"{assetcopy.name} CAPEX (€)", -assetcopy.capex) + + if hasattr(assetcopy, "devex"): + self.add_capex(f"{assetcopy.name} DEVEX (€)", -assetcopy.devex) + + def get_assets(self): + """Returns all Asset instances assigned to CaseStudy instance.""" + return list(self.assets.values()) + + def add_cashflow(self, label, amount): + """Add a yearly cashflow to the CaseStudy + + Convention is negative values for costs and positive values for revenue. + """ + self.cashflows[label] = round(amount, 2) + + def add_capex(self, label, amount): + """Add a capex component to the CaseStudy + + Convention is to use positive values + """ + capex = round(amount, 2) * -1 + self.capex[label] = capex + self.total_capex += capex + + def add_irregular_cashflow(self, amount, year): + base = self.irregular_cashflows[year] if year in self.irregular_cashflows else 0 + self.irregular_cashflows[year] = base + amount + + def generate_electr_market_results(self, real_col, nom_col=None): + """Generates a dictionary with results of the simulation on energy market. + + Dictionary is saved in CaseStudy.energy_market_results. + Total market result is automatically added to cashflow dictionary. + """ + if nom_col is None: + nom_col = "Nom. vol." + self.data[nom_col] = 0 + + data = calc_electr_market_results(self.data, nom_col=nom_col, real_col=real_col) + self.data = data + + total_produced = data["Prod. vol."].sum() + total_consumed = -data["Cons. vol."].sum() + + self.total_electricity_cons = total_consumed * (-1) + + selling = data[real_col] > 0 + mean_selling_price = ( + data["Combined Result"].where(selling).sum() / total_produced + if total_produced != 0 + else 0 + ) + + mean_buying_price = ( + data["Combined Result"].where(~selling).sum() / total_consumed * (-1) + if round(total_consumed, 2) != 0 + else 0 + ) + + total_comb_result = data["Combined Result"].sum() + + self.electr_market_results = { + "Total net volume (MWh)": data[real_col].sum(), + "Total exported to grid (MWh)": total_produced, + "Total consumed from grid (MWh)": total_consumed, + "Total nominated volume (MWh)": data[nom_col].sum(), + "Absolute imbalance volume (MWh)": data["Imb. vol."].abs().sum(), + "Mean selling price (€/MWh)": mean_selling_price, + "Mean buying price (€/MWh)": mean_buying_price, + "Total day-ahead result (€)": data["Day-Ahead Result"].sum(), + "Total POS result (€)": data["POS Result"].sum(), + "Total NEG result (€)": data["NEG Result"].sum(), + "Total imbalance result (€)": data["Imbalance Result"].sum(), + "Total combined result (€)": total_comb_result, + } + + self.electr_market_result = total_comb_result + self.add_cashflow("Result on electricity market (€)", total_comb_result) + + def add_gas_costs(self, gasvolumes_col, gasprice_col="Gas prices (€/MWh)"): + """Calculate gas costs and add to cashflows + + Parameters: + ----------- + gasprices_col : str + Column containing gas prices in CaseStudy.data dataframe + gasvolumes_col : str + List of column names containing gas volumes in CaseStudy.data dataframe + """ + gasprices = self.data[gasprice_col] + gasvolumes = self.data[gasvolumes_col].abs() + gas_costs = gasprices * gasvolumes * -1 + self.data["Gas commodity costs (€)"] = gas_costs + + self.total_gas_cons = gasvolumes.sum() + self.total_gas_costs = round(gas_costs.sum(), 2) + self.add_cashflow("Gas consumption costs (€)", self.total_gas_costs) + + def add_co2_costs( + self, volume_cols, co2_price_col="CO2 prices (€/ton)", fuel="gas" + ): + """Calculate co2 costs and add to cashflows + + Parameters: + ----------- + Gasprices : str + Column containing gas prices in CaseStudy.data dataframe + Gasvolumes : list + List of column names containing gas volumes in CaseStudy.data dataframe + """ + if isinstance(volume_cols, str): + volume_cols = [volume_cols] + + co2_prices = self.data[co2_price_col] + volumes = [self.data[col] for col in volume_cols] + self.total_co2_costs = calc_co2_costs( + co2_prices=co2_prices, volumes=volumes, fuel=fuel + ) + self.add_cashflow("CO2 emission costs (€)", self.total_co2_costs) + + def add_eb_ode( + self, + commodity, + cons_col=None, + tax_bracket=None, + base_cons=None, + horti=False, + m3=False, + add_cons_MWh=0, + year=2020, + split=False, + ): + """Add EB & ODE to cashflows + + See financial.calc_eb_ode() for more detailed documentation. + + Parameters: + ----------- + commodity : str + {'gas', 'electricity'} + cons_col : str + Optional parameter to specificy column name of the + consumption values in MWh. + tax_bracket : numeric + Tax bracket that the client is in [1-4] + Use either 'tax_bracket' of 'base_cons', not both. + base_cons : numeric + Base consumption volume of the client + Use either 'tax_bracket' of 'base_cons', not both. + horti : bool + Set to True to use horticulture rates + m3 : bool + Set to True if you want to enter gas volumes in m3 + add_cons_MWh : + Enables manually adding extra consumption + """ + if cons_col: + cons = self.data[cons_col].abs().sum() + else: + cons = getattr(self, f"total_{commodity}_cons") + + cons = cons + add_cons_MWh + + eb, ode = calculate_eb_ode( + cons=cons, + electr=(commodity == "electricity"), + tax_bracket=tax_bracket, + base_cons=base_cons, + horti=horti, + m3=m3, + year=year, + ) + if split: + self.add_cashflow(f"EB {commodity.capitalize()} (€)", eb) + self.add_cashflow(f"ODE {commodity.capitalize()} (€)", ode) + else: + self.add_cashflow(f"{commodity.capitalize()} taxes (€)", eb + ode) + + def add_grid_costs( + self, + power_MW_col, + grid_operator, + year, + connection_type, + cons_MWh_col=None, + kw_contract_kW=None, + path=None, + add_peak_kW=0, + add_cons_MWh=0, + ): + """Add variable grid transport costs to cashflows + + See financial.calc_grid_costs() for more detailed documentation. + + Parameters: + ----------- + power_MW_col : str + Column in data table with power usage in MW + grid_operator : str + {'tennet', 'liander', 'enexis', 'stedin'} + year : int + Year, e.g. 2020 + connection_type : str + Connection type, e.g. 'HS' + cons_MWh_col : str + Column in data table containing grid consumption in MWh + kw_contract_kW : numeric + in kW. If provided, function will assume fixed value kW contract + path : str + Specify path with grid tariff files. Leave empty to use default path. + add_peak_kW : float + Enables manually adding peak consumption to the data + """ + cols = [power_MW_col] + if cons_MWh_col is not None: + cols.append(cons_MWh_col) + + peaks_kW = ( + (self.data[power_MW_col] * 1000 - add_peak_kW) + .resample("15T") + .mean() + .abs() + .resample("M") + .max() + .to_list() + ) + + cons_kWh = ( + self.data[cons_MWh_col].sum() * 1000 if cons_MWh_col is not None else 0 + ) + add_cons_MWh + + self.grid_costs = calc_grid_costs( + peakload_kW=peaks_kW, + grid_operator=grid_operator, + year=year, + connection_type=connection_type, + kw_contract_kW=kw_contract_kW, + totalcons_kWh=cons_kWh, + path=path, + modelled_time_period_years=self.modelled_time_period_years, + ) + + total_grid_costs = sum(self.grid_costs.values()) + + self.add_cashflow("Grid transport costs (€)", total_grid_costs) + + def calculate_ebitda(self, project_duration, residual_value=None): + """Calculate yearly EBITDA based on cashflows + + Calculation table and EBITDA value are saved in CaseStudy. + """ + for key, val in self.cashflows.items(): + if np.isnan(val): + warnings.warn( + f"Cashflow '{key}' for CaseStudy '{self.name}' contains NaN value. " + "Something might have gone wrong. Replacing NaN with 0 for now." + ) + self.cashflows[key] = 0 + + assets = self.get_assets() + + for asset in assets: + if not asset.depreciate: + pass + elif asset.lifetime is None: + raise ValueError(f"'lifetime' property of {asset.name} was not set.") + elif project_duration > asset.lifetime: + warnings.warn( + f"Project duration is larger than technical lifetime of asset '{asset.name}'. " + "Will continue by limiting project duration to the technical lifetime of the asset." + ) + project_duration = int(asset.lifetime) + + depreciations, residual_value = CaseStudy._calc_depr_and_residual_val( + assets, self.total_capex, residual_value, project_duration + ) + + self.ebitda = sum(self.cashflows.values()) + self.ebitda_calc = deepcopy(self.cashflows) + self.ebitda_calc["EBITDA (€)"] = self.ebitda + self.ebitda_calc["Depreciation (€)"] = depreciations * -1 + self.ebitda_calc["EBITDA + depr (€)"] = self.ebitda + depreciations * -1 + + def calculate_business_case( + self, + project_duration, + discount_rate, + residual_value=None, + baseline=None, + bl_res_value=None, + eia=False, + vamil=False, + fixed_income_tax=False, + ): + """Calculates business case (NPV, IRR) for the CaseStudy. + + Business case calculation is stored in CaseStudy.business_case + NPV is stored in CaseStudy.npv + IRR is stored in Casestudy.irr + + Parameters: + ----------- + project_duration : int + In years + discount_rate : float + In % (decimal value) + residual_value : numeric + Can be used to manually set residual value of assets (all assets combined). + + Defaults to None, in which case residual_value is calculated + based on linear depreciation over technical lifetime. + baseline : CaseStudy + Baseline to compare against + bl_res_value : numeric + Similar to 'residual_value' for baseline + eia : bool + Apply EIA ("Energie Investerings Aftrek") tax discounts. + Defaults to False. + vamil : bool + Apply VAMIL ("Willekeurige afschrijving milieu-investeringen") tax discounts. + Defaults to False. + """ + + assets = self.get_assets() + + for asset in assets: + if not asset.depreciate: + pass + elif asset.lifetime is None: + raise ValueError(f"'lifetime' property of {asset.name} was not set.") + elif project_duration > asset.lifetime: + warnings.warn( + f"Project duration is larger than technical lifetime of asset '{asset.name}'. " + "Will continue by limiting project duration to the technical lifetime of the asset." + ) + project_duration = int(asset.lifetime) + + capex = self.total_capex + yearly_ebitda = self.ebitda / self.modelled_time_period_years + + irregular_cashflows = ( + self._calc_irregular_cashflows(project_duration, baseline=baseline) + if self.irregular_cashflows + else 0 + ) + + depreciations, residual_value = CaseStudy._calc_depr_and_residual_val( + assets, capex, residual_value, project_duration + ) + + if baseline is not None: + bl_assets = baseline.assets.values() + bl_capex = baseline.total_capex + bl_depr, bl_res_val = CaseStudy._calc_depr_and_residual_val( + bl_assets, bl_capex, bl_res_value, project_duration + ) + capex -= bl_capex + depreciations -= bl_depr + residual_value -= bl_res_val + yearly_ebitda -= baseline.ebitda / self.modelled_time_period_years + + self.business_case = calc_business_case( + capex=capex, + discount_rate=discount_rate, + project_duration=project_duration, + depreciation=depreciations, + residual_value=residual_value, + regular_earnings=yearly_ebitda, + irregular_cashflows=irregular_cashflows, + eia=eia, + vamil=vamil, + fixed_income_tax=fixed_income_tax, + ) + + self.irr = self.business_case.loc["IRR (%)", "Year 0"] / 100 + self.npv = self.business_case.loc["NPV (€)", "Year 0"] + self.spp = self.business_case.loc["Simple Payback Period", "Year 0"] + + @staticmethod + def _calc_depr_and_residual_val(assets, capex, residual_value, project_duration): + if residual_value is None: + assets = [asset for asset in assets if asset.depreciate] + depreciations = sum( + (asset.capex - asset.salvage_value) / asset.lifetime for asset in assets + ) + residual_value = capex - depreciations * project_duration + else: + depreciations = (capex - residual_value) / project_duration + + return depreciations, residual_value + + def _calc_irregular_cashflows(self, project_duration, baseline=None): + irr_earnings = [0] * (project_duration) + + for year, cashflow in self.irregular_cashflows.items(): + if baseline: + cashflow -= baseline.irregular_cashflows.get(year, 0) + + irr_earnings[int(year) - 1] = cashflow + + return irr_earnings diff --git a/pyrecoy/pyrecoy/pyrecoy/colors.py b/pyrecoy/pyrecoy/pyrecoy/colors.py new file mode 100644 index 0000000..1660c9e --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/colors.py @@ -0,0 +1,43 @@ +recoy_colordict = { + "RecoyDarkBlue": "#0e293b", + "RecoyBlue": "#1f8376", + "RecoyRed": "#dd433b", + "RecoyYellow": "#f3d268", + "RecoyGreen": "#46a579", + "RecoyPurple": "#6d526b", + "RecoyOrange": "#f2a541", + "RecoyBlueGrey": "#145561", + "RecoyDarkGrey": "#2a2a2a", + "RecoyLilac": "#C3ACCE", + "RecoyBrown": "#825E52", + "RecoyLightGreen": "#7E9181", + "RecoyCitron": "#CFD186", + "RecoyPink": "#F5B3B3" +} + +recoy_greysdict = { + "RecoyLightGrey": "#e6e6e6", + "RecoyGrey": "#c0c0c0", + "RecoyDarkGrey": "#2a2a2a", +} + +recoydarkblue = recoy_colordict["RecoyDarkBlue"] +recoyyellow = recoy_colordict["RecoyYellow"] +recoygreen = recoy_colordict["RecoyGreen"] +recoyred = recoy_colordict["RecoyRed"] +recoyblue = recoy_colordict["RecoyBlue"] +recoyorange = recoy_colordict["RecoyOrange"] +recoypurple = recoy_colordict["RecoyPurple"] +recoybluegrey = recoy_colordict["RecoyBlueGrey"] +recoylightgrey = recoy_greysdict["RecoyLightGrey"] +recoygrey = recoy_greysdict["RecoyGrey"] +recoydarkgrey = recoy_greysdict["RecoyDarkGrey"] +recoylilac = recoy_colordict["RecoyLilac"] +recoybrown = recoy_colordict["RecoyBrown"] +recoylightgreen = recoy_colordict["RecoyLightGreen"] +recoycitron = recoy_colordict["RecoyCitron"] +recoypink = recoy_colordict["RecoyPink"] + +recoycolors = list(recoy_colordict.values()) + +transparent = "rgba(0, 0, 0, 0)" diff --git a/pyrecoy/pyrecoy/pyrecoy/converters.py b/pyrecoy/pyrecoy/pyrecoy/converters.py new file mode 100644 index 0000000..6b5b239 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/converters.py @@ -0,0 +1,66 @@ +import pandas as pd + + +def MWh_to_m3(MWh): + return MWh / 9.769 * 1000 + + +def MWh_to_GJ(MWh): + return MWh * 3.6 + + +def EURperm3_to_EURperMWh(EURperm3): + return EURperm3 / 9.769 * 1000 + + +def EURperMWh_to_EURperGJ(EURperMWh): + return EURperMWh * 3.6 + + +def MWh_gas_to_tonnes_CO2(MWh): + return MWh * 1.84 / 9.769 + + +def EURpertonCO2_to_EURperMWh(EURpertonCO2): + return EURpertonCO2 * 1.884 / 9.769 + + +def EURperLHV_to_EURperHHV(MWh_LHV): + return MWh_LHV / 35.17 * 31.65 + + +def EURperHHV_to_EURperLHV(MWh_HHV): + return MWh_HHV / 31.65 * 35.17 + + +def GJ_gas_to_kg_NOX(GJ): + return GJ * 0.02 + + +def MWh_gas_to_kg_NOX(MWh): + return GJ_gas_to_kg_NOX(MWh_to_GJ(MWh)) + + +def fastround(n, decimals): + """Round a value to certain number of decimals, faster than Python implementation""" + multiplier = 10**decimals + return int(n * multiplier + 0.5) / multiplier + + +def add_season_column(data): + """Adds a column containing seasons to a DataFrame with datetime index""" + data["season"] = (data.index.month % 12 + 3) // 3 + + seasons = {1: "Winter", 2: "Spring", 3: "Summer", 4: "Fall"} + data["season"] = data["season"].map(seasons) + return data + + +def dt_column_to_local_time(column): + return column.dt.tz_localize("UTC").dt.tz_convert("Europe/Amsterdam") + + +def timestamp_to_utc(timestamp): + if isinstance(timestamp, str): + timestamp = pd.to_datetime(timestamp).tz_localize("Europe/Amsterdam") + return timestamp.tz_convert("UTC") diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2020.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2020.csv new file mode 100644 index 0000000..23eb1a4 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2020.csv @@ -0,0 +1,6 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +MS/LS;441;0,0092;20,54;17,04 +MS-D;441;0,0092;12,24;17,04 +MS-T;441;0,0055;10,84;13,56 +HS/MS;2760;0;16,95;20,52 +TS;2760;0;12,01;16,56 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2021.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2021.csv new file mode 100644 index 0000000..dda155d --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2021.csv @@ -0,0 +1,6 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +MS/LS;441,00;0,0101;22,74;18,84 +MS-D;441,00;0,0101;13,57;18,84 +MS-T;441,00;0,0062;12,26;15,36 +HS/MS;2760,00;0,00;18,71;22,68 +TS;2760,00;0,00;13,68;18,84 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2022.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2022.csv new file mode 100644 index 0000000..25e20d6 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2022.csv @@ -0,0 +1,6 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +MS/LS;441,00;0,0111;24,23;20,4 +MS-D;441,00;0,0111;14,30;20,4 +MS-T;441,00;0,0069;13,03;16,8 +HS/MS;2760,00;0,00;20,12;24,72 +TS;2760,00;0,00;14,43;21 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2023.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2023.csv new file mode 100644 index 0000000..061f6ac --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2023.csv @@ -0,0 +1,6 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +MS/LS;441,00;0,0111;31,55;26,52 +MS-D;441,00;0,0111;18,62;26,52 +MS-T;441,00;0,0069;16,99;21,96 +HS/MS;2760,00;0,00;26,19;32,16 +TS;2760,00;0,00;18,80;27,36 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2024.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2024.csv new file mode 100644 index 0000000..e5dde2d --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/enexis_2024.csv @@ -0,0 +1,6 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +MS/LS;441;0,0206;44,84;37,68 +MS-D;441;0,0206;26,47;37,68 +MS-T;441;0,0128;24,19;31,2 +HS/MS;2760;0;37,2;45,84 +TS;2760;0;26,89;38,64 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2020.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2020.csv new file mode 100644 index 0000000..1bd3bc5 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2020.csv @@ -0,0 +1,7 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +MS/LS;441;0,0097;21,12;19,2 +MS;441;0,0097;13,44;19,2 +TS/MS;2760;0;21,84;27,24 +HS/MS;2760;0;21,84;27,24 +TS;2760;0;20,88;26,4 +HS;2760;0;10,56;13,32 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2021.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2021.csv new file mode 100644 index 0000000..d137767 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2021.csv @@ -0,0 +1,7 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +MS/LS;441,00;0,01;23,16;20,88 +MS;441,00;0,01;14,76;20,88 +TS/MS;2760,00;0,00;24,12;30,00 +HS/MS;2760,00;0,00;24,12;30,00 +TS;2760,00;0,00;23,04;29,16 +HS;2760,00;0,00;11,64;14,76 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2022.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2022.csv new file mode 100644 index 0000000..c42f9f6 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2022.csv @@ -0,0 +1,7 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +MS/LS;441,00;0,0107;23,04;20,76 +MS;441,00;0,0107;14,52;20,76 +TS/MS;2760,00;0,00;23,28;32,40 +HS/MS;2760,00;0,00;23,28;32,40 +TS;2760,00;0,00;23,16;30,00 +HS;2760,00;0,00;12,00;14,88 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2023.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2023.csv new file mode 100644 index 0000000..7f83aee --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2023.csv @@ -0,0 +1,7 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +MS/LS;441,00;0,0160;34,56;31,08 +MS;441,00;0,0160;21,84;31,08 +TS/MS;2760,00;0,00;35,04;48,72 +HS/MS;2760,00;0,00;35,04;48,72 +TS;2760,00;0,00;34,68;45,00 +HS;2760,00;0,00;18,00;22,44 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2024.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2024.csv new file mode 100644 index 0000000..4542fa5 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/liander_2024.csv @@ -0,0 +1,7 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +MS/LS;705,6;0,0256;55,296;49,728 +MS;705,6;0,0256;34,944;49,728 +TS/MS;4416;0;56,064;77,952 +HS/MS;4416;0;56,064;77,952 +TS;4416;0;55,488;72 +HS;4416;0;28,8;35,904 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2020.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2020.csv new file mode 100644 index 0000000..6838cde --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2020.csv @@ -0,0 +1,3 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +EHS;12478,96;0,00;13,29;16,20 +HS;2760;0,00;23,58;27,48 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2021.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2021.csv new file mode 100644 index 0000000..f3d35bb --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2021.csv @@ -0,0 +1,5 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +MS/LS;441;0,01;23,00;18,80 +MS;441;0,01;12,36;18,80 +HS+TS/MS;2760;0,00;23,00;29,52 + TS ;2760;0,00;21,80;30,48 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2022.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2022.csv new file mode 100644 index 0000000..3111dda --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2022.csv @@ -0,0 +1,5 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +MS/LS;453;0,01;25,04;19,16 +MS;453;0,01;12,71;19,16 +HS+TS/MS;2760;0,00;24,06;32,1 +TS ;2760;0,00;23,25;31,73 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2023.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2023.csv new file mode 100644 index 0000000..bed966f --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2023.csv @@ -0,0 +1,5 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +MS/LS;441;0,01;38,06;29,12 +MS;441;0,01;19,32;29,12 +HS+TS/MS;2760;0,00;36,57;48,78 +TS ;2760;0,00;35,33;48,22 \ No newline at end of file diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2024.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2024.csv new file mode 100644 index 0000000..9afcc83 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/stedin_2024.csv @@ -0,0 +1,5 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +MS/LS;441;0,0176;43,1;34,23 +MS;441;0,0176;23;34,23 +HS+TS/MS;2760;0;42,45;56,62 +TS ;2760;0;33,46;46,52 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2020.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2020.csv new file mode 100644 index 0000000..6838cde --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2020.csv @@ -0,0 +1,3 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +EHS;12478,96;0,00;13,29;16,20 +HS;2760;0,00;23,58;27,48 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2021.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2021.csv new file mode 100644 index 0000000..f2981ec --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2021.csv @@ -0,0 +1,3 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +EHS;12478,96;0,00;14,80;18,00 +HS;2760;0,00;24,80;29,04 \ No newline at end of file diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2022.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2022.csv new file mode 100644 index 0000000..0154df6 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2022.csv @@ -0,0 +1,3 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +EHS;12478,96;0,00;11,45;14,88 +HS;2760,00;0,00;23,70;29,16 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2023.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2023.csv new file mode 100644 index 0000000..232d699 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2023.csv @@ -0,0 +1,3 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +EHS;12478,96;0,00;27,98;36,36 +HS;2760,00;0,00;41,04;50,52 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2024.csv b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2024.csv new file mode 100644 index 0000000..0227fed --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/grid_tariffs/tennet_2024.csv @@ -0,0 +1,3 @@ +Aansluiting;Vastrecht per jaar;kWh tarief;kW contract per jaar;kW max per jaar +EHS;12478,96;0,00;60,65;82,92 +HS;2760,00;0,00;73,52;91,44 diff --git a/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/electricity_eb.json b/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/electricity_eb.json new file mode 100644 index 0000000..17d9914 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/electricity_eb.json @@ -0,0 +1,72 @@ +{ + "0 t/m 10.000 kWh": { + "2013": 0.1165, + "2014": 0.1185, + "2015": 0.1196, + "2016": 0.1007, + "2017": 0.1013, + "2018": 0.10458, + "2019": 0.09863, + "2020": 0.0977, + "2021": 0.09428, + "2022": 0.03679, + "2023": 0.12599, + "2024": 0.1088 + }, + "10.001 t/m 50.000 kWh": { + "2013": 0.0424, + "2014": 0.0431, + "2015": 0.0469, + "2016": 0.04996, + "2017": 0.04901, + "2018": 0.05274, + "2019": 0.05337, + "2020": 0.05083, + "2021": 0.05164, + "2022": 0.04361, + "2023": 0.10046, + "2024": 0.09037 + }, + "50.001 t/m 10 miljoen kWh": { + "2013": 0.0113, + "2014": 0.0115, + "2015": 0.0125, + "2016": 0.01331, + "2017": 0.01305, + "2018": 0.01404, + "2019": 0.01421, + "2020": 0.01353, + "2021": 0.01375, + "2022": 0.01189, + "2023": 0.03942, + "2024": 0.03943 + }, + "meer dan 10 miljoen kWh particulier": { + "2013": 0.001, + "2014": 0.001, + "2015": 0.001, + "2016": 0.00107, + "2017": 0.00107, + "2018": 0.00116, + "2019": 0.00117, + "2020": 0.00111, + "2021": 0.00113, + "2022": 0.00114, + "2023": 0.00175, + "2024": 0.00254 + }, + "meer dan 10 miljoen kWh zakelijk": { + "2013": 0.0005, + "2014": 0.0005, + "2015": 0.0005, + "2016": 0.00053, + "2017": 0.00053, + "2018": 0.00057, + "2019": 0.00058, + "2020": 0.00055, + "2021": 0.00056, + "2022": 0.00057, + "2023": 0.00115, + "2024": 0.00188 + } +} \ No newline at end of file diff --git a/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/electricity_ode.json b/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/electricity_ode.json new file mode 100644 index 0000000..d203659 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/electricity_ode.json @@ -0,0 +1,67 @@ +{ + "0 t/m 10.000 kWh": { + "2013": 0.0011, + "2014": 0.0023, + "2015": 0.0036, + "2016": 0.0056, + "2017": 0.0074, + "2018": 0.0132, + "2019": 0.0189, + "2020": 0.0273, + "2021": 0.03, + "2022": 0.0305, + "2023": 0.00 + }, + "10.001 t/m 50.000 kWh": { + "2013": 0.0014, + "2014": 0.0027, + "2015": 0.0046, + "2016": 0.007, + "2017": 0.0123, + "2018": 0.018, + "2019": 0.0278, + "2020": 0.0375, + "2021": 0.0411, + "2022": 0.0418, + "2023": 0.00 + }, + "50.001 t/m 10 mln kWh": { + "2013": 0.0004, + "2014": 0.0007, + "2015": 0.0012, + "2016": 0.0019, + "2017": 0.0033, + "2018": 0.0048, + "2019": 0.0074, + "2020": 0.0205, + "2021": 0.0225, + "2022": 0.0229, + "2023": 0.00 + }, + "meer dan 10 mln kWh niet zakelijk": { + "2013": 0.000017, + "2014": 0.000034, + "2015": 0.000055, + "2016": 0.000084, + "2017": 0.000131, + "2018": 0.000194, + "2019": 0.0003, + "2020": 0.0004, + "2021": 0.0004, + "2022": 0.0005, + "2023": 0.00 + }, + "meer dan 10 mln kWh zakelijk": { + "2013": 0.000017, + "2014": 0.000034, + "2015": 0.000055, + "2016": 0.000084, + "2017": 0.000131, + "2018": 0.000194, + "2019": 0.0003, + "2020": 0.0004, + "2021": 0.0004, + "2022": 0.0005, + "2023": 0.00 + } + } \ No newline at end of file diff --git a/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_eb.json b/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_eb.json new file mode 100644 index 0000000..a2e4ff3 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_eb.json @@ -0,0 +1,86 @@ +{ + "0 t/m 5.000 m3 en blokverwarming": { + "2013": 0.1862, + "2014": 0.1894, + "2015": 0.1911, + "2016": 0.25168, + "2017": 0.25244, + "2018": 0.26001, + "2019": 0.29313, + "2020": 0.33307, + "2021": 0.34856, + "2022": 0.36322, + "2023": 0.48980, + "2024": 0.58301 + }, + "5.001 t/m 170.000 m3": { + "2013": 0.1862, + "2014": 0.1894, + "2015": 0.1911, + "2016": 0.25168, + "2017": 0.25244, + "2018": 0.26001, + "2019": 0.29313, + "2020": 0.33307, + "2021": 0.34856, + "2022": 0.36322, + "2023": 0.48980, + "2024": 0.58301 + }, + "170.001 t/m 1 miljoen m3": { + "2013": 0.0439, + "2014": 0.0446, + "2015": 0.0677, + "2016": 0.06954, + "2017": 0.06215, + "2018": 0.06464, + "2019": 0.06542, + "2020": 0.06444, + "2021": 0.06547, + "2022": 0.06632, + "2023": 0.09621, + "2024": 0.22378 + }, + "meer dan 1 miljoen t/m 10 miljoen m3": { + "2013": 0.016, + "2014": 0.0163, + "2015": 0.0247, + "2016": 0.02537, + "2017": 0.02265, + "2018": 0.02355, + "2019": 0.02383, + "2020": 0.02348, + "2021": 0.02386, + "2022": 0.02417, + "2023": 0.05109, + "2024": 0.12825 + }, + "meer dan 10 miljoen m3 particulier": { + "2013": 0.0115, + "2014": 0.0117, + "2015": 0.0118, + "2016": 0.01212, + "2017": 0.01216, + "2018": 0.01265, + "2019": 0.0128, + "2020": 0.01261, + "2021": 0.01281, + "2022": 0.01298, + "2023": 0.03919, + "2024": 0.04886 + }, + "meer dan 10 miljoen m3 zakelijk": { + "2013": 0.0115, + "2014": 0.0117, + "2015": 0.0118, + "2016": 0.01212, + "2017": 0.01216, + "2018": 0.01265, + "2019": 0.0128, + "2020": 0.01261, + "2021": 0.01281, + "2022": 0.01298, + "2023": 0.03919, + "2024": 0.04886 + } + } \ No newline at end of file diff --git a/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_horticulture_eb.json b/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_horticulture_eb.json new file mode 100644 index 0000000..a1defc9 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_horticulture_eb.json @@ -0,0 +1 @@ +{"0 t\/m 5.000 m\u00b3":{"2013":0.02991,"2014":0.03042,"2015":0.03069,"2016":0.04042,"2017":0.04054,"2018":0.04175,"2019":0.04707,"2020":0.05348,"2021":0.05597, "2022":0.05833, "2023":0.07867, "2024":0.09365},"5.001 t\/m 170.000 m\u00b3":{"2013":0.02991,"2014":0.03042,"2015":0.03069,"2016":0.04042,"2017":0.04054,"2018":0.04175,"2019":0.04707,"2020":0.05348,"2021":0.05597, "2022":0.05833, "2023":0.07867, "2024":0.09365},"170.001 t\/m 1\u00a0miljoen m\u00b3":{"2013":0.0222,"2014":0.02258,"2015":0.02278,"2016":0.02339,"2017":0.02346,"2018":0.0244,"2019":0.02469,"2020":0.02432,"2021":0.02471, "2022":0.02503, "2023":0.03629, "2024":0.08444},"meer dan 1\u00a0miljoen t\/m 10\u00a0miljoen m\u00b3":{"2013":0.016,"2014":0.0163,"2015":0.0247,"2016":0.02537,"2017":0.02265,"2018":0.02355,"2019":0.02383,"2020":0.02348,"2021":0.02386, "2022":0.02417, "2023":0.05109, "2024":0.12855},"meer dan 10 miljoen m\u00b3":{"2013":0.0115,"2014":0.0117,"2015":0.0118,"2016":0.01212,"2017":0.01216,"2018":0.01265,"2019":0.0128,"2020":0.01261,"2021":0.01281, "2022":0.01298, "2023":0.03919, "2024":0.04886}} \ No newline at end of file diff --git a/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_horticulture_ode.json b/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_horticulture_ode.json new file mode 100644 index 0000000..52606e7 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_horticulture_ode.json @@ -0,0 +1 @@ +{"0 t\/m 170.000 m\u00b3":{"2013":0.0004,"2014":0.0007,"2015":0.0012,"2016":0.0018,"2017":0.0026,"2018":0.0046,"2019":0.0084,"2020":0.0124,"2021":0.0137, "2022":0.0139, "2023":0.00},"170.001 t\/m 1 mln m\u00b3":{"2013":0.0004,"2014":0.0009,"2015":0.0014,"2016":0.0021,"2017":0.0025,"2018":0.004,"2019":0.0061,"2020":0.0081,"2021":0.0089, "2022":0.0090, "2023":0.00},"meer dan 1 mln t\/m 10 mln m\u00b3":{"2013":0.0003,"2014":0.0005,"2015":0.0008,"2016":0.0013,"2017":0.0027,"2018":0.0039,"2019":0.0059,"2020":0.0212,"2021":0.0232, "2022":0.0236, "2023":0.00},"meer dan 10 mln m\u00b3":{"2013":0.0002,"2014":0.0004,"2015":0.0006,"2016":0.0009,"2017":0.0013,"2018":0.0021,"2019":0.0031,"2020":0.0212,"2021":0.0232, "2022":0.0236, "2023":0.00}} \ No newline at end of file diff --git a/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_ode.json b/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_ode.json new file mode 100644 index 0000000..1390ce4 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/data/tax_tariffs/gas_ode.json @@ -0,0 +1,54 @@ +{ + "0 t/m 170.000 m3 en blokverwarming": { + "2013": 0.0023, + "2014": 0.0046, + "2015": 0.0074, + "2016": 0.0113, + "2017": 0.0159, + "2018": 0.0285, + "2019": 0.0524, + "2020": 0.0775, + "2021": 0.0851, + "2022": 0.0865, + "2023": 0.00 + }, + "170.001 t/m 1 mln m3": { + "2013": 0.0009, + "2014": 0.0017, + "2015": 0.0028, + "2016": 0.0042, + "2017": 0.0074, + "2018": 0.0106, + "2019": 0.0161, + "2020": 0.0214, + "2021": 0.0235, + "2022": 0.0239, + "2023": 0.00 + }, + "meer dan 1 mln t/m 10 mln m3": { + "2013": 0.0003, + "2014": 0.0005, + "2015": 0.0008, + "2016": 0.0013, + "2017": 0.0027, + "2018": 0.0039, + "2019": 0.0059, + "2020": 0.0212, + "2021": 0.0232, + "2022": 0.0236, + "2023": 0.00 + }, + "meer dan 10 mln m3": { + "2013": 0.0002, + "2014": 0.0004, + "2015": 0.0006, + "2016": 0.0009, + "2017": 0.0013, + "2018": 0.0021, + "2019": 0.0031, + "2020": 0.0212, + "2021": 0.0232, + "2022": 0.0236, + "2023": 0.00 + } + } \ No newline at end of file diff --git a/pyrecoy/pyrecoy/pyrecoy/database/Models/base.py b/pyrecoy/pyrecoy/pyrecoy/database/Models/base.py new file mode 100644 index 0000000..f746c28 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/database/Models/base.py @@ -0,0 +1,25 @@ +from sqlalchemy import create_engine +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +import pytz +from sqlalchemy import DateTime, TypeDecorator + +class DateTimeTZ(TypeDecorator): + impl = DateTime + + def process_result_value(self, value, dialect): + if value is None: + return None + return value.replace(tzinfo=pytz.utc) + +DATABASE_URL = 'mssql+pyodbc://rop:OptimalTransition@rop-prices-test.cyqrsg0mmelh.eu-central-1.rds.amazonaws.com:8472/test?driver=ODBC+Driver+17+for+SQL+Server' +# DATABASE_URL = 'mssql+pyodbc://rop:OptimalTransition@rop-prices-dev-20230123.cyqrsg0mmelh.eu-central-1.rds.amazonaws.com:1433/test?driver=ODBC+Driver+17+for+SQL+Server' +# DATABASE_URL = Config().SQLALCHEMY_DATABASE_URI +BASE = declarative_base() +ENGINE_PRICES = create_engine( + DATABASE_URL, + pool_size=2000, + max_overflow=0, + connect_args={"options": "-c timezone=utc"}, +) +SESSION = sessionmaker(bind=ENGINE_PRICES) diff --git a/pyrecoy/pyrecoy/pyrecoy/databases.py b/pyrecoy/pyrecoy/pyrecoy/databases.py new file mode 100644 index 0000000..9654153 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/databases.py @@ -0,0 +1,69 @@ +from sqlalchemy import create_engine, MetaData, Table +import pandas as pd + +DATABASES = { + "ngsc_dev": { + "db_url": "ngsc-dev-msql.cyqrsg0mmelh.eu-central-1.rds.amazonaws.com", + "db_name": "ngsc_dev", + "db_user": "ngsc_dev", + "db_password": "AKIAZQ2BV5F5K6LLBC47", + "db_port": "1433", + }, + "ngsc_test": { + "db_url": "ngsc-test-msql.cyqrsg0mmelh.eu-central-1.rds.amazonaws.com", + "db_name": "ngsc_test", + "db_user": "ngsc_test", + "db_password": "AKIAZQ2BV5F5K6LLBC47", + "db_port": "1433", + }, + "ngsc_prod": { + "db_url": "rop-ngsc-prod.cyqrsg0mmelh.eu-central-1.rds.amazonaws.com", + "db_name": "ngsc_test", + "db_user": "ngsc_test", + "db_password": "AKIAZQ2BV5F5K6LLBC47", + "db_port": "1433", + }, + "rop_prices_test": { + "db_url": "rop-prices-test.cyqrsg0mmelh.eu-central-1.rds.amazonaws.com", + "db_name": "test", + "db_user": "rop", + "db_password": "OptimalTransition", + "db_port": "8472", + }, + "rop_assets_test": { + "db_url": "rop-assets-test.cyqrsg0mmelh.eu-central-1.rds.amazonaws.com", + "db_name": "test", + "db_user": "rop", + "db_password": "OptimalTransition", + "db_port": "1433", + }, +} + + +def db_engine(db_name): + db_config = DATABASES[db_name] + + connection_string = ( + f"mssql+pyodbc://{db_config['db_user']}:{db_config['db_password']}" + f"@{db_config['db_url']}:{db_config['db_port']}/" + f"{db_config['db_name']}?driver=ODBC+Driver+17+for+SQL+Server" + ) + return create_engine(connection_string) + + +def read_entire_table(table_name, db_engine): + return pd.read_sql_table(table_name, db_engine) + + +def create_connection(engine, tables): + connection = engine.connect() + metadata = MetaData() + + if isinstance(tables, str): + return connection, Table(tables, metadata, autoload=True, autoload_with=engine) + else: + db_tables = { + table: Table(table, metadata, autoload=True, autoload_with=engine) + for table in tables + } + return connection, db_tables diff --git a/pyrecoy/pyrecoy/pyrecoy/decorators.py b/pyrecoy/pyrecoy/pyrecoy/decorators.py new file mode 100644 index 0000000..135cb2d --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/decorators.py @@ -0,0 +1,17 @@ +import time +from functools import wraps + + +def time_method(func): + """Prints the runtime of a method of a class.""" + + @wraps(func) + def wrapper_timer(self, *args, **kwargs): + start = time.perf_counter() + value = func(self, *args, **kwargs) + end = time.perf_counter() + run_time = end - start + print(f"Finished running {self.name} in {run_time:.2f} seconds.") + return value + + return wrapper_timer diff --git a/pyrecoy/pyrecoy/pyrecoy/financial.py b/pyrecoy/pyrecoy/pyrecoy/financial.py new file mode 100644 index 0000000..33710e2 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/financial.py @@ -0,0 +1,678 @@ +from pathlib import Path +from datetime import timedelta + +import numpy as np +import numpy_financial as npf +import pandas as pd + +import warnings + + +def npv(discount_rate, cashflows): + cashflows = np.array(cashflows) + return (cashflows / (1 + discount_rate) ** np.arange(1, len(cashflows) + 1)).sum( + axis=0 + ) + + +def calc_electr_market_results(model, nom_col=None, real_col=None): + """Function to calculate the financial result on Day-Ahead and Imbalance market for the input model. + + Parameters: + ----------- + model : df + DataFrame containing at least 'DAM', 'POS' and 'NEG' columns. + nom_col : str + Name of the column containing the Day-Ahead nominations in MWh + Negative values = Buy, positive values = Sell + imb_col : str + Name of the column containing the Imbalance volumes in MWh + Negative values = Buy, positive values = Sell + + Returns: + -------- + Original df with added columns showing the financial results per timeunit. + """ + if nom_col is None: + nom_col = "Nom. vol." + model[nom_col] = 0 + + producing = model[real_col] > 0 + model["Prod. vol."] = model[real_col].where(producing, other=0) + model["Cons. vol."] = model[real_col].where(~producing, other=0) + model["Imb. vol."] = model[real_col] - model[nom_col] + + model["Day-Ahead Result"] = model[nom_col] * model["DAM"] + model["POS Result"] = 0 + model["NEG Result"] = 0 + posimb = model["Imb. vol."] > 0 + model["POS Result"] = model["POS"] * model["Imb. vol."].where(posimb, other=0) + model["NEG Result"] = model["NEG"] * model["Imb. vol."].where(~posimb, other=0) + model["Imbalance Result"] = model["POS Result"] + model["NEG Result"] + model["Combined Result"] = model["Day-Ahead Result"] + model["Imbalance Result"] + return model + + +def calc_co2_costs(co2_prices, volumes, fuel): + """Calculates gas market results + + Parameters: + ----------- + co2_prices : numeric or array + CO2 prices in €/ton + volumes : list + List of arrays containing volumes + fuel : list + List of arrays containing gas volumes + + Returns: + -------- + Returns a single negative value (=costs) in € + """ + if not isinstance(volumes, list): + volumes = [volumes] + + emission_factors = { + "gas": 1.884 / 9.769 + } # in ton/MWh (based on 1.884 kg CO2/Nm3, 9.769 kWh/Nm3) + + if fuel not in emission_factors.keys(): + raise NotImplementedError( + f"Emission factor for chosen fuel '{fuel}' is not implemented." + f"Implement it by adding emission factor to the 'emission_factors' table." + ) + + emission_factor = emission_factors[fuel] + return -round( + abs(sum((array * emission_factor * co2_prices).sum() for array in volumes)), 2 + ) + + +def calculate_eb_ode( + cons, + electr=True, + year=2020, + tax_bracket=None, + base_cons=None, + horti=False, + m3=False, +): + """Calculates energy tax and ODE for consumption of electricity or natural gas in given year. + + Function calculates total tax to be payed for electricity or natural gas consumption, + consisting of energy tax ('Energiebelasting') and sustainable energy surcharge ('Opslag Duurzame Energie'). + + Tax bracket that applies is based on consumption level, with a different tax + rate for each bracket. + + For Gas + 1: 0 - 170.000 m3 + 3: 170.000 - 1 mln. m3 + 4: 1 mln. - 10 mln. m3 + 5: > 10 mln. m3 + + For Electricity + 1: 0 - 10 MWh + 2: 10 - 50 MWh + 3: 50 - 10.000 MWh + 4: > 10.000 MWh + + Parameters: + ----------- + cons : numeric + Total consumption in given year for which to calculate taxes. + Electricity consumption in MWh + Gas consumption in MWh (or m3 and use m3=True) + electr : bool + Set to False for natural gas rates. Default is True. + year : int + Year for which tax rates should be used. Tax rates are updated + annually and can differ significantly. + tax_bracket : int + Tax bracket (1-4) to assume. + Parameter can not be used in conjunction ith 'base_cons'. + base_cons : numeric + Baseline consumption to assume, in same unit as 'cons'. + Specified value is used to decide what tax bracket to start in. + Taxes from baseline consumption are not included in calculation of the tax amount. + Parameter can not be used in conjunction with 'tax_bracket'. + horti : bool + The horticulture sector gets a discount on gas taxes. + m3 : bool + Set to True if you want to enter gas consumption in m3. + Default is to enter consumption in MWh. + + Returns: + -------- + Total tax amount as negative number (costs). + + Note: + ----- + This function is rather complicated, due to all its optionalities. + Should probably be simplified or split into different functions. + """ + if tax_bracket is not None and base_cons is not None: + raise ValueError( + "Parameters 'tax_bracket' and 'base_cons' can not be used at the same time." + ) + if tax_bracket is None and base_cons is None: + raise ValueError( + "Function requires input for either 'tax_bracket' or 'base_cons'." + ) + + cons = abs(cons) + commodity = "electricity" if electr else "gas" + + if commodity == "gas": + if not m3: + cons /= 9.769 / 1000 # Conversion factor for gas: 1 m3 = 9.769 kWh + base_cons = base_cons / (9.769 / 1000) if base_cons is not None else None + else: + cons *= 1000 # conversion MWh to kWh + base_cons = base_cons * 1000 if base_cons is not None else None + + tax_brackets = { + "gas": [0, 170_000, 1_000_000, 10_000_000], + "electricity": [0, 10_000, 50_000, 10_000_000], + } + tax_brackets = tax_brackets[commodity] + base_cons = tax_brackets[tax_bracket - 1] if tax_bracket else base_cons + + if commodity == "gas" and horti: + commodity += "_horticulture" + eb_rates, ode_rates = get_tax_tables(commodity) + + eb = 0 + ode = 0 + + for bracket in range(4): + if bracket < 3: + br_lower_limit = tax_brackets[bracket] + br_upper_limit = tax_brackets[bracket + 1] + if base_cons > br_upper_limit: + continue + bracket_size = br_upper_limit - max(br_lower_limit, base_cons) + cons_in_bracket = min(cons, bracket_size) + else: + cons_in_bracket = cons + + # print(eb_rates.columns[bracket], cons_in_bracket, round(eb_rates.loc[year, eb_rates.columns[bracket]], 6), round(eb_rates.loc[year, eb_rates.columns[bracket]] * cons_in_bracket,2)) + eb += eb_rates.loc[year, eb_rates.columns[bracket]] * cons_in_bracket + ode += ode_rates.loc[year, ode_rates.columns[bracket]] * cons_in_bracket + cons -= cons_in_bracket + + if cons == 0: + break + + return -round(eb, 2), -round(ode, 2) + + +def get_tax_tables(commodity): + """Get EB and ODE tax rate tables from json files. + + Returns two tax rate tables as DataFrame. + If table is not up-to-date, try use update_tax_tables() function. + """ + folder = Path(__file__).resolve().parent / "data" / "tax_tariffs" + eb_table = pd.read_json(folder / f"{commodity}_eb.json") + ode_table = pd.read_json(folder / f"{commodity}_ode.json") + + if commodity == "electricity": + ode_table.drop(columns=ode_table.columns[3], inplace=True) + else: + eb_table.drop(columns=eb_table.columns[0], inplace=True) + + if commodity != "gas_horticulture": + eb_table.drop(columns=eb_table.columns[3], inplace=True) + return eb_table, ode_table + + +def get_tax_rate(commodity, year, tax_bracket, perMWh=True): + """Get tax rate for specific year and tax bracket. + + Parameters: + ----------- + commodity : str + {'gas' or 'electricity'} + year : int + {2013 - current year} + tax_bracket : int + {1 - 4} + + For Gas: + 1: 0 - 170.000 m3 + 3: 170.000 - 1 mln. m3 + 4: 1 mln. - 10 mln. m3 + 5: > 10 mln. m3 + + For Electricity: + 1: 0 - 10 MWh + 2: 10 - 50 MWh + 3: 50 - 10.000 MWh + 4: > 10.000 MWh + perMWh : bool + Defaults to True. Will return rates (for gas) in €/MWh instead of €/m3. + + Returns: + -------- + Dictionary with EB, ODE and combined rates (in €/MWh for electricity and €/m3 for gas) + {'EB' : float + 'ODE' : float, + 'EB+ODE' : float} + """ + eb_table, ode_table = get_tax_tables(commodity) + + eb_rate = eb_table.loc[year, :].iloc[tax_bracket - 1].astype(float).round(5) * 1000 + ode_rate = ( + ode_table.loc[year, :].iloc[tax_bracket - 1].astype(float).round(5) * 1000 + ) + + if commodity == "gas" and perMWh == True: + eb_rate /= 9.769 + ode_rate /= 9.769 + + comb_rate = (eb_rate + ode_rate).round(5) + return {"EB": eb_rate, "ODE": ode_rate, "EB+ODE": comb_rate} + + +def update_tax_tables(): + """Function to get EB and ODE tax rate tables from belastingdienst.nl and save as json file.""" + url = ( + "https://www.belastingdienst.nl/wps/wcm/connect/bldcontentnl/belastingdienst/" + "zakelijk/overige_belastingen/belastingen_op_milieugrondslag/tarieven_milieubelastingen/" + "tabellen_tarieven_milieubelastingen?projectid=6750bae7-383b-4c97-bc7a-802790bd1110" + ) + + tables = pd.read_html(url) + + table_index = { + 3: "gas_eb", + 4: "gas_horticulture_eb", + 6: "electricity_eb", + 8: "gas_ode", + 9: "gas_horticulture_ode", + 10: "electricity_ode", + } + + for key, val in table_index.items(): + table = tables[key].astype(str) + table = table.applymap(lambda x: x.strip("*")) + table = table.applymap(lambda x: x.strip("€ ")) + table = table.applymap(lambda x: x.replace(",", ".")) + table = table.astype(float) + table["Jaar"] = table["Jaar"].astype(int) + table.set_index("Jaar", inplace=True) + path = Path(__file__).resolve().parent / "data" / "tax_tariffs" / f"{val}.json" + table.to_json(path) + + +def calc_grid_costs( + peakload_kW, + grid_operator, + year, + connection_type, + totalcons_kWh=0, + kw_contract_kW=None, + path=None, + modelled_time_period_years = 1 +): + """Calculate grid connection costs for one full year + + Parameters: + ----------- + peakload_kW : numeric or list + Peak load in kW. Can be single value (for entire year) or value per month (list). + grid_operator : str + {'tennet', 'liander', 'enexis', 'stedin'} + year : int + Year to get tariffs for, e.g. 2020 + connection_type : str + Type of grid connection, e.g. 'TS' or 'HS'. + Definitions are different for each grid operator. + totalcons_kWh : numeric + Total yearly consumption in kWh + kw_contract_kW : numeric + in kW. If provided, function will assume fixed value kW contract + path : str + Path to directory with grid tariff files. + Default is None; function will to look for default folder on SharePoint. + Returns: + -------- + Total variable grid connection costs in €/year (fixed costs 'vastrecht' nog included) + """ + + totalcons_kWh /= modelled_time_period_years + + tariffs = get_grid_tariffs_electricity(grid_operator, year, connection_type, path) + kw_max_kW = np.mean(peakload_kW) + max_peakload_kW = np.max(peakload_kW) + + if kw_contract_kW is None: + kw_contract_kW = False + + if bool(kw_contract_kW) & (kw_contract_kW < max_peakload_kW): + warnings.warn( + "Maximum peak consumption is higher than provided 'kw_contract' value." + "Will continue to assume max peak consumption as kW contract." + ) + kw_contract_kW = max_peakload_kW + + if not bool(kw_contract_kW): + kw_contract_kW = max_peakload_kW + + if (tariffs["kWh tarief"] != 0) and (totalcons_kWh is None): + raise ValueError( + "For this grid connection type a tariff for kWh has to be paid. " + "Therefore 'totalcons_kWh' can not be None." + ) + + # kw_contract = 1000 + + # print("tarieven") + # print(abs(totalcons_kWh)) + # print(modelled_time_period_years) + # print(-round(tariffs["kWh tarief"])) + + # print({ + # "Variable": -round(tariffs["kWh tarief"] * abs(totalcons_kWh) * modelled_time_period_years, 2), + # "kW contract": -round(tariffs["kW contract per jaar"] * kw_contract_kW * modelled_time_period_years, 2), + # "kW max": -round(tariffs["kW max per jaar"] * max_peakload_kW * modelled_time_period_years, 2), + # }) + + return { + "Variable": -round(tariffs["kWh tarief"] * abs(totalcons_kWh) * modelled_time_period_years, 2), + "kW contract": -round(tariffs["kW contract per jaar"] * kw_contract_kW * modelled_time_period_years, 2), + "kW max": -round(tariffs["kW max per jaar"] * max_peakload_kW * modelled_time_period_years, 2), + } + + +def get_grid_tariffs_electricity(grid_operator, year, connection_type, path=None): + """Get grid tranposrt tariffs + + Parameters: + ----------- + grid_operator : str + {'tennet', 'liander', 'enexis', 'stedin'} + year : int + Year to get tariffs for, e.g. 2020 + connection_type : str + Type of grid connection, e.g. 'TS' or 'HS'. + Definitions are different for each grid operator. + path : str + Path to directory with grid tariff files. + Default is None; function will to look for default folder on SharePoint. + + Returns: + -------- + Dictionary containing grid tariffs in €/kW/year and €/kWh + """ + if path is None: + path = Path(__file__).resolve().parent / "data" / "grid_tariffs" + else: + path = Path(path) + + if not path.exists(): + raise SystemError( + f"Path '{path}' not found. Specify different path and try again." + ) + + filename = f"{grid_operator.lower()}_{year}.csv" + filepath = path / filename + + if not filepath.exists(): + raise NotImplementedError( + f"File '{filename}' does not exist. Files available: {[file.name for file in path.glob('*.csv')]}" + ) + + rates_table = pd.read_csv( + path / filename, sep=";", decimal=",", index_col="Aansluiting" + ) + + if connection_type not in rates_table.index: + raise ValueError( + f"The chosen connection type '{connection_type}' is not available " + f"for grid operator '{grid_operator}'. Please choose one of {list(rates_table.index)}." + ) + return rates_table.loc[connection_type, :].to_dict() + + +def income_tax(ebit, fixed_tax_rate): + """ + Calculates income tax based on EBIT. + 2021 tax rates + """ + if fixed_tax_rate: + return round(ebit * -0.25, 0) + if ebit > 245_000: + return round(245_000 * -0.15 + (ebit - 200_000) * -0.25, 2) + if ebit < 0: + return 0 + else: + return -round(ebit * 0.15, 2) + + +def calc_business_case( + capex, + discount_rate, + project_duration, + depreciation, + residual_value, + regular_earnings, + irregular_cashflows=0, + eia=False, + vamil=False, + fixed_income_tax=False +): + """Calculate NPV and IRR for business case. + + All input paremeters are either absolute or relative to a baseline. + + Parameters: + ----------- + capex : numeric + Total CAPEX or extra CAPEX compared to baseline + discount_rate : numeric + % as decimal value + project_duration : numeric + in years + depreciation : numeric of list + Yearly depreciation costs + residual_value : numeric + Residual value at end of project in €, total or compared to baseline. + regular_earnings : numeric + Regular earnings, usually EBITDA + irregular_cashflows : list + Pass list with value for each year. + eia : bool + Apply EIA ("Energie Investerings Aftrek") tax discounts. + Defaults to False. + vamil : bool + Apply VAMIL ("Willekeurige afschrijving milieu-investeringen") tax discounts. + Defaults to False. + + Returns: + -------- + DataFrame showing complete calculation resulting in NPV and IRR + """ + years = [f"Year {y}" for y in range(project_duration + 1)] + years_o = years[1:] + + bc_calc = pd.DataFrame(columns=years) + bc_calc.loc["CAPEX (€)", "Year 0"] = -capex + bc_calc.loc["Regular Earnings (€)", years_o] = regular_earnings + bc_calc.loc["Irregular Cashflows (€)", years_o] = irregular_cashflows + bc_calc.loc["EBITDA (€)", years_o] = ( + bc_calc.loc["Regular Earnings (€)", years_o] + + bc_calc.loc["Irregular Cashflows (€)", years_o] + ) + + depreciations = [depreciation] * project_duration + + if vamil: + ebitdas = bc_calc.loc["EBITDA (€)", years_o].to_list() + depreciations = _apply_vamil(depreciations, project_duration, ebitdas) + + bc_calc.loc["Depreciations (€) -/-", years_o] = np.array(depreciations) * -1 + bc_calc.loc["EBIT (€)", years_o] = ( + bc_calc.loc["EBITDA (€)", years_o] + + bc_calc.loc["Depreciations (€) -/-", years_o] + ) + + if eia: + bc_calc = _apply_eia(bc_calc, project_duration, capex, years_o) + + bc_calc.loc["Income tax (Vpb.) (€)", years_o] = bc_calc.loc["EBIT (€)", :].apply( + income_tax, args=[fixed_income_tax] + ) + + if eia: + bc_calc.loc["NOPLAT (€)", years_o] = ( + bc_calc.loc["EBIT before EIA (€)", :] + + bc_calc.loc["Income tax (Vpb.) (€)", years_o] + ) + else: + bc_calc.loc["NOPLAT (€)", years_o] = ( + bc_calc.loc["EBIT (€)", :] + bc_calc.loc["Income tax (Vpb.) (€)", years_o] + ) + + bc_calc.loc["Depreciations (€) +/+", years_o] = depreciations + bc_calc.loc["Free Cash Flow (€)", years] = ( + bc_calc.loc["CAPEX (€)", years].fillna(0) + + bc_calc.loc["NOPLAT (€)", years].fillna(0) + + bc_calc.loc["Depreciations (€) +/+", years].fillna(0) + ) + + spp = calc_simple_payback_time( + capex=capex, + free_cashflows=bc_calc.loc["Free Cash Flow (€)", years_o].values, + ) + bc_calc.loc["Simple Payback Period", "Year 0"] = spp + + try: + bc_calc.loc["IRR (%)", "Year 0"] = ( + npf.irr(bc_calc.loc["Free Cash Flow (€)", years].values) * 100 + ) + except: + bc_calc.loc["IRR (%)", "Year 0"] = np.nan + + bc_calc.loc["WACC (%)", "Year 0"] = discount_rate * 100 + + bc_calc.loc["NPV of explicit period (€)", "Year 0"] = npv( + discount_rate, bc_calc.loc["Free Cash Flow (€)"].values + ) + bc_calc.loc["Discounted residual value (€)", "Year 0"] = ( + residual_value / (1 + discount_rate) ** project_duration + ) + bc_calc.loc["NPV (€)", "Year 0"] = ( + bc_calc.loc["NPV of explicit period (€)", "Year 0"] + # + bc_calc.loc["Discounted residual value (€)", "Year 0"] + ) + + return bc_calc.round(2) + + +def calc_simple_payback_time(capex, free_cashflows): + if free_cashflows.sum() < capex: + return np.nan + + year = 0 + spp = 0 + while capex > 0: + cashflow = free_cashflows[year] + spp += min(capex, cashflow) / cashflow + capex -= cashflow + year += 1 + return spp + return round(spp, 1) + + +def _apply_vamil(depreciations, project_duration, ebitdas): + remaining_depr = sum(depreciations) + remaining_vamil = 0.75 * remaining_depr + for i in range(project_duration): + vamil_depr = min(ebitdas[i], remaining_vamil) if remaining_vamil > 0 else 0 + + if remaining_depr > 0: + lin_depr = remaining_depr / (project_duration - i) + depr = max(vamil_depr, lin_depr) + depreciations[i] = max(vamil_depr, lin_depr) + + remaining_vamil -= vamil_depr + remaining_depr -= depr + else: + depreciations[i] = 0 + + return depreciations + + +def _apply_eia(bc_calc, project_duration, capex, years_o): + remaining_eia = 0.45 * capex + eia_per_year = [0] * project_duration + bc_calc = bc_calc.rename(index={"EBIT (€)": "EBIT before EIA (€)"}) + ebits = bc_calc.loc["EBIT before EIA (€)", years_o].to_list() + eia_duration = min(10, project_duration) + for i in range(eia_duration): + if remaining_eia > 0: + eia_curr_year = max(min(remaining_eia, ebits[i]), 0) + eia_per_year[i] = eia_curr_year + remaining_eia -= eia_curr_year + else: + break + + bc_calc.loc["EIA (€)", years_o] = np.array(eia_per_year) * -1 + bc_calc.loc["EBIT (€)", :] = ( + bc_calc.loc["EBIT before EIA (€)", :] + bc_calc.loc["EIA (€)", :] + ) + return bc_calc + + +def calc_irf_value( + data, irf_volume, nomination_col=None, realisation_col=None, reco_col="reco" +): + """Calculate IRF value + + Takes a DataFrame [data] and returns the same DataFrame with a new column "IRF Value" + + Parameters + ---------- + data : DataFrame + DataFrame that contains data. Should include price data (DAM, POS and NEG). + irf_volume : int + Volume on IRF in MW. + nomination_col : str + Name of the column containing nomination data in MWh. + realisation_col : str + Name of the column containing realisation data in MWh. + reco_col : str + Name of the column contaning recommendations. + """ + if not nomination_col: + nomination_col = "zero_nom" + data[nomination_col] = 0 + + if not realisation_col: + realisation_col = "zero_nom" + data[realisation_col] = 0 + + conversion_factor = pd.to_timedelta(data.index.freq) / timedelta(hours=1) + + imb_pre_irf = data[realisation_col] - data[nomination_col] + result_pre_irf = ( + data[nomination_col] * data["DAM"] + + imb_pre_irf.where(imb_pre_irf > 0, other=0) * data["POS"] + + imb_pre_irf.where(imb_pre_irf < 0, other=0) * data["NEG"] + ) + + data["IRF Nom"] = ( + data[nomination_col] - data[reco_col] * irf_volume * conversion_factor + ) + data["IRF Imb"] = data[realisation_col] - data["IRF Nom"] + + result_post_irf = ( + data["IRF Nom"] * data["DAM"] + + data["IRF Imb"].where(data["IRF Imb"] > 0, other=0) * data["POS"] + + data["IRF Imb"].where(data["IRF Imb"] < 0, other=0) * data["NEG"] + ) + data["IRF Value"] = result_post_irf - result_pre_irf + + return data diff --git a/pyrecoy/pyrecoy/pyrecoy/forecasts.py b/pyrecoy/pyrecoy/pyrecoy/forecasts.py new file mode 100644 index 0000000..ca2696e --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/forecasts.py @@ -0,0 +1,293 @@ +import json +import os +import time +import pytz +from datetime import datetime, timedelta +from pathlib import Path + +import numpy as np +import pandas as pd +import requests +from pyrecoy.prices import * + + +class Forecast: + """Load dataset from SharePoint server as DataFrame in local datetime format. + + Parameters: + ---------- + filename : str + Name of the csv file, e.g. "marketprices_nl.csv" + start : datetime + Startdate of the dataset + end : datetime + Enddate of the dataset + freq : str + {'1T', '15T', 'H'} + Time frequency of the data + folder_path : str + Local path to forecast data on Recoy SharePoint, + e.g. "C:/Users/username/Recoy/Recoy - Documents/03 - Libraries/12 - Data Management/Forecast Data/" + + """ + + def __init__(self, filename, start=None, end=None, freq="15T", folder_path=None, from_database=False, add_days_to_start_end=False): + self.file = filename + self.from_database = from_database + + if isinstance(start, str): + start = datetime.strptime(start, "%Y-%m-%d").astimezone(pytz.timezone('Europe/Amsterdam')) + print(start) + if isinstance(end, str): + end = datetime.strptime(end, "%Y-%m-%d").astimezone(pytz.timezone('Europe/Amsterdam')) + print(end) + + self.data = self.get_dataset(start, end, freq, folder_path=folder_path, add_days_to_start_end=add_days_to_start_end) + + # print(self.data) + + if len(self.data) == 0: + raise Exception("No data available for those dates.") + + def get_dataset(self, start, end, freq, folder_path=None, add_days_to_start_end=False): + if folder_path is None and self.from_database: + if add_days_to_start_end: + start = start + timedelta(days=-1) + end = end + timedelta(days=1) + + start = start.astimezone(pytz.utc) + end = end.astimezone(pytz.utc) + + dam = get_day_ahead_prices_from_database(start, end, 'NLD') + dam = dam.resample('15T').ffill() + + imb = get_imbalance_prices_from_database(start, end, 'NLD') + data = pd.concat([imb, dam], axis='columns') + data = data[['DAM', 'POS', 'NEG']] + data = data.tz_convert('Europe/Amsterdam') + # data = data.loc[(data.index >= start) & (data.index < end)] + return data + + + def reindex_to_freq(self, freq): + """Reindex dataset to a different timefrequency. + + Parameters: + ----------- + freq : string + options: '1T' + """ + ix_start = pd.to_datetime(self.data.index[0], utc=True).tz_convert( + "Europe/Amsterdam" + ) + ix_end = pd.to_datetime(self.data.index[-1], utc=True).tz_convert( + "Europe/Amsterdam" + ) + + idx = pd.date_range( + ix_start, ix_end + timedelta(minutes=14), freq=freq, tz="Europe/Amsterdam" + ) + self.data = self.data.reindex(index=idx, method="ffill") + + +class Mipf(Forecast): + """ + Load MIPF dataset from SharePoint server as DataFrame in local datetime format. + """ + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + forecasts = get_imbalance_forecasts_from_database_on_quarter_start_time(kwargs['start'], kwargs['end'],'NLD') + forecasts['PublicationTime'] = pd.to_datetime(forecasts['PublicationTime'], utc=True) + forecasts['PublicationTime'] = forecasts['PublicationTime'].dt.ceil('min') + forecasts['PublicationTime'] = forecasts['PublicationTime'].dt.tz_convert('Europe/Amsterdam') + forecasts['QuarterStartTime'] = pd.to_datetime(forecasts['QuarterStartTime'], utc=True) + forecasts['QuarterStartTime'] = forecasts['QuarterStartTime'].dt.tz_convert('Europe/Amsterdam') + + forecasts = forecasts.loc[ + (forecasts['PublicationTime'] >= forecasts['QuarterStartTime']) + & (forecasts['PublicationTime'] < forecasts['QuarterStartTime'] + pd.Timedelta(minutes=15)) + ] + forecasts = forecasts.groupby('PublicationTime').last() + forecasts.index.name = '' + forecasts = forecasts[['ForeNeg','ForePos']] + + prices = self.data + idx = pd.date_range( + prices.index[0], prices.index[-1] + timedelta(minutes=14), freq='1T', tz="Europe/Amsterdam" + ) + prices = prices.reindex(idx, method='ffill') + res = pd.concat([prices, forecasts], axis='columns') + + self.data = res + + + + + +def tidy_mipf(data, include_price_data=True, include_nextQ=False): + """Takes MIPF dataset (unstacked) and turns it into a tidy dataset (stacked). + + Parameters: + ---------- + include_price_data : bool + Set as True if columns 'DAM', 'POS' and 'NEG' data should be included in the output. + include_nextQ : bool + Set to True to include next Qh forecast + """ + mipf_pos = data[[f"POS_horizon{h}" for h in np.flip(np.arange(3, 18))]].copy() + mipf_neg = data[[f"NEG_horizon{h}" for h in np.flip(np.arange(3, 18))]].copy() + + cols = ["ForePos", "ForeNeg"] + dfs = [mipf_pos, mipf_neg] + + if include_nextQ: + pos_nextQ = data[[f"POS_horizon{h}" for h in np.flip(np.arange(18, 30))]].copy() + neg_nextQ = data[[f"NEG_horizon{h}" for h in np.flip(np.arange(18, 30))]].copy() + + for h in np.arange(30, 33): + pos_nextQ.insert(0, f"POS_horizon{h}", np.NaN) + neg_nextQ.insert(0, f"POS_horizon{h}", np.NaN) + + cols += ["ForePos_nextQ", "ForeNeg_nextQ"] + dfs += [pos_nextQ, neg_nextQ] + + tidy_df = pd.DataFrame() + + for df, col in zip(dfs, cols): + df.columns = range(15) + df.reset_index(drop=True, inplace=True) + df.reset_index(inplace=True) + df_melt = ( + df.melt(id_vars=["index"], var_name="min", value_name=col) + .sort_values(["index", "min"]) + .reset_index(drop=True) + ) + tidy_df[col] = df_melt[col] + + ix_start = data.index[0] + ix_end = data.index[-1] + timedelta(minutes=14) + + tidy_df.index = pd.date_range(ix_start, ix_end, freq="1T", tz="Europe/Amsterdam") + tidy_df.index.name = "datetime" + + if include_price_data: + for col in np.flip(["DAM", "POS", "NEG", "regulation state"]): + try: + price_col = data.loc[:, col].reindex( + index=tidy_df.index, method="ffill" + ) + if col == "regulation state": + price_col.name = "RS" + tidy_df = pd.concat([price_col, tidy_df], axis="columns") + except Exception as e: + print(e) + + return tidy_df + + +class Qipf(Forecast): + """Load QIPF dataset from SharePoint server as DataFrame in local datetime format. + + Parameters: + ---------- + start : datetime + Startdate of the dataset + end : datetime + Enddate of the dataset + folder_path : str + Local path to forecast data on Recoy SharePoint, + e.g. "C:/Users/username/Recoy/Recoy - Documents/03 - Libraries/12 - Data Management/Forecast Data/" + """ + + def __init__(self, start=None, end=None, freq="15T", folder_path=None): + self.file = "imbalance_nl.csv" + self.data = self.get_dataset(start, end, "15T", folder_path=folder_path) + + if freq != "15T": + self.reindex_to_freq(freq) + + +class Irf(Forecast): + """Load QIPF dataset from SharePoint server as DataFrame in local datetime format.""" + + def __init__( + self, country, horizon, start=None, end=None, freq="60T", folder_path=None + ): + if freq == "15T": + self.file = f"irf_{country}_{horizon}_15min.csv" + else: + self.file = f"irf_{country}_{horizon}.csv" + + self.data = self.get_dataset(start, end, freq, folder_path=folder_path) + + return data + + +class NsideApiRequest: + """ + Request forecast data from N-SIDE API + + If request fails, code will retry 5 times by default. + + Output on success: data as DataFrame, containing forecast data. Index is timezone-aware datetime (Dutch time). + Output on error: [] + """ + + def __init__( + self, + endpoint, + country, + start=None, + end=None, + auth_token=None, + ): + if not auth_token: + try: + auth_token = os.environ["NSIDE_API_KEY"] + except: + raise ValueError("N-SIDE token not provided.") + + self.data = self.get_data(auth_token, endpoint, country, start, end) + + def get_data(self, token, endpoint, country, start, end): + if start is not None: + start = pd.to_datetime(start).strftime("%Y-%m-%d") + if end is not None: + end = pd.to_datetime(end).strftime("%Y-%m-%d") + + url = f"https://energy-forecasting-api.eu.n-side.com/api/forecasts/{country}/{endpoint}" + if start and end: + url += f"?from={start}&to={end}" + print(url) + headers = {"Accept": "application/json", "Authorization": f"Token {token}"} + + retry = 5 + self.success = False + + i = 0 + while i <= retry: + resp = requests.get(url, headers=headers) + self.statuscode = resp.status_code + + if self.statuscode == requests.codes.ok: + self.content = resp.content + json_data = json.loads(self.content) + data = pd.DataFrame(json_data["records"]) + data = data.set_index("datetime") + data.index = pd.to_datetime(data.index, utc=True).tz_convert( + "Europe/Amsterdam" + ) + self.success = True + return data.sort_index() + else: + print( + f"Attempt failled, status code {str(self.statuscode)}. Trying again..." + ) + time.sleep(5) + i += 1 + + if not self.success: + print( + "Request failed. Please contact your Recoy contact person or try again later." + ) + return [] diff --git a/pyrecoy/pyrecoy/pyrecoy/framework.py b/pyrecoy/pyrecoy/pyrecoy/framework.py new file mode 100644 index 0000000..e4d6785 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/framework.py @@ -0,0 +1,61 @@ +import warnings +from datetime import datetime, timedelta + +import pandas as pd +import pytz + + +class TimeFramework: + """ + Representation of the modelled timeperiod. + Variables in this class are equal for all CaseStudies. + """ + + def __init__(self, start, end): + print('testets') + if type(start) is str: + start = pytz.timezone("Europe/Amsterdam").localize( + datetime.strptime(start, "%Y-%m-%d") + ) + + if type(end) is str: + end = pytz.timezone("Europe/Amsterdam").localize( + datetime.strptime(end, "%Y-%m-%d") + ) + end += timedelta(days=1) + end -= timedelta(minutes=1) + + self.start = start + self.end = end + + amount_of_days = 365 + + if start.year % 4 == 0: + amount_of_days = 366 + + self.days = (self.end - self.start + timedelta(days=1)) / timedelta(days=1) + + self.modelled_time_period_years = (end - start).total_seconds() / (3600 * 24 * amount_of_days) + + if self.days != 365: + warnings.warn( + f"The chosen timeperiod spans {self.days} days, " + "which is not a full year. Beware that certain " + "functions that use yearly rates might return " + "incorrect values." + ) + + def dt_index(self, freq): + # Workaround to make sure time range is always complete, + # Even with DST changes + # end = self.end + timedelta(days=1) # + timedelta(hours=1) + # end = self.end + # end - timedelta(end.hour) + return pd.date_range( + start=self.start, + end=self.end, + freq=freq, + tz="Europe/Amsterdam", + # inclusive="left", + name="datetime", + ) diff --git a/pyrecoy/pyrecoy/pyrecoy/intelligent_baseline.py b/pyrecoy/pyrecoy/pyrecoy/intelligent_baseline.py new file mode 100644 index 0000000..286f734 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/intelligent_baseline.py @@ -0,0 +1,226 @@ +import numpy as np +import pandas as pd +import warnings +from tqdm.notebook import tqdm + +from .prices import get_tennet_data, get_balansdelta_nl +from .forecasts import Forecast + +# TODO: This whole thing needs serious refactoring /MK + + +def generate_intelligent_baseline(startdate, enddate): + bd = get_balansdelta_nl(start=startdate, end=enddate) + bd.drop( + columns=[ + "datum", + "volgnr", + "tijd", + "IGCCBijdrage_op", + "IGCCBijdrage_af", + "opregelen_reserve", + "afregelen_reserve", + ], + inplace=True, + ) + net_regelvolume = bd["opregelen"] - bd["Afregelen"] + bd.insert(2, "net_regelvolume", net_regelvolume) + vol_delta = bd["net_regelvolume"].diff(periods=1) + bd.insert(3, "vol_delta", vol_delta) + + pc = get_tennet_data( + exporttype="verrekenprijzen", start=startdate, end=enddate + ).reindex(index=bd.index, method="ffill")[["prikkelcomponent"]] + + if len(pc) == 0: + pc = pd.Series(0, index=bd.index) + + prices = Forecast("marketprices_nl.csv", start=startdate, end=enddate) + prices.reindex_to_freq("1T") + prices = prices.data + + inputdata = pd.concat([prices, bd, pc], axis=1) + + Qhs = len(inputdata) / 15 + + if Qhs % 1 > 0: + raise Exception( + "A dataset with incomplete quarter-hours was passed in, please insert new dataset!" + ) + + data = np.array([inputdata[col].to_numpy() for col in inputdata.columns]) + + lstoutput = [] + + for q in tqdm(range(int(Qhs))): + q_data = [col[q * 15 : (q + 1) * 15] for col in data] + q_output = apply_imbalance_logic_for_quarter_hour(q_data) + + if lstoutput: + for (ix, col) in enumerate(lstoutput): + lstoutput[ix] += q_output[ix] + else: + lstoutput = q_output + + ib = pd.DataFrame( + lstoutput, + index=[ + "DAM", + "POS", + "NEG", + "regulation state", + "ib_inv", + "ib_afn", + "ib_rt", + "nv_op", + "nv_af", + "opgeregeld", + "afgeregeld", + ], + ).T + + ib.index = inputdata.index + return ib + + +def apply_imbalance_logic_for_quarter_hour(q_data): + [nv_op, nv_af, opgeregeld, afgeregeld] = [False] * 4 + + lst_inv = [np.NaN] * 15 + lst_afn = [np.NaN] * 15 + lst_rt = [np.NaN] * 15 + + lst_nv_op = [np.NaN] * 15 + lst_nv_af = [np.NaN] * 15 + lst_afr = [np.NaN] * 15 + lst_opr = [np.NaN] * 15 + + mins = iter(range(15)) + + for m in mins: + [ + DAM, + POS, + NEG, + rt, + vol_op, + vol_af, + net_vol, + delta_vol, + nood_op, + nood_af, + prijs_hoog, + prijs_mid, + prijs_laag, + prikkelc, + ] = [col[0 : m + 1] for col in q_data] + + delta_vol[0] = 0 + + if nood_op.sum() > 0: + nv_op = True + + if nood_af.sum() > 0: + nv_af = True + + if pd.notna(prijs_hoog).any() > 0: + opgeregeld = True + + if pd.notna(prijs_laag).any() > 0: + afgeregeld = True + + if (opgeregeld == True) and (afgeregeld == False): + regeltoestand = 1 + + elif (opgeregeld == False) and (afgeregeld == True): + regeltoestand = -1 + + elif (opgeregeld == False) and (afgeregeld == False): + if nv_op == True: + regeltoestand = 1 + if nv_af == True: + regeltoestand = -1 + else: + regeltoestand = 0 + + else: + # Zowel opregeld als afregeld > kijk naar trend + # Continue niet-dalend: RT1 + # Continue dalend: RT -1 + # Geen continue trend: RT 2 + + if all(i >= 0 for i in delta_vol): + regeltoestand = 1 + elif all(i <= 0 for i in delta_vol): + regeltoestand = -1 + else: + regeltoestand = 2 + + # Bepaal de verwachte onbalansprijzen + dam = DAM[0] + pc = prikkelc[0] + + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + + hoogste_prijs = np.nanmax(prijs_hoog) + mid_prijs = prijs_mid[-1] + laagste_prijs = np.nanmin(prijs_laag) + + if regeltoestand == 0: + prijs_inv = mid_prijs + prijs_afn = mid_prijs + + elif regeltoestand == -1: + if nv_af: + prijs_afn = np.nanmin((dam - 200, laagste_prijs)) + + else: + prijs_afn = laagste_prijs + + prijs_inv = prijs_afn + + elif regeltoestand == 1: + if nv_op: + prijs_inv = np.nanmax((dam + 200, hoogste_prijs)) + + else: + prijs_inv = hoogste_prijs + + prijs_afn = prijs_inv + + elif regeltoestand == 2: + if nv_op: + prijs_afn = np.nanmax((dam + 200, hoogste_prijs, mid_prijs)) + else: + prijs_afn = np.nanmax((mid_prijs, hoogste_prijs)) + + if nv_af: + prijs_inv = np.nanmin((dam - 200, laagste_prijs, mid_prijs)) + else: + prijs_inv = np.nanmin((mid_prijs, laagste_prijs)) + + prijs_inv -= pc + prijs_afn += pc + + lst_inv[m] = prijs_inv + lst_afn[m] = prijs_afn + lst_rt[m] = regeltoestand + lst_nv_op[m] = nv_op + lst_nv_af[m] = nv_af + lst_opr[m] = opgeregeld + lst_afr[m] = afgeregeld + + return [ + list(DAM), + list(POS), + list(NEG), + list(rt), + lst_inv, + lst_afn, + lst_rt, + lst_nv_op, + lst_nv_af, + lst_opr, + lst_afr, + ] diff --git a/pyrecoy/pyrecoy/pyrecoy/plotting.py b/pyrecoy/pyrecoy/pyrecoy/plotting.py new file mode 100644 index 0000000..74ceade --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/plotting.py @@ -0,0 +1,143 @@ +import plotly.graph_objects as go +from millify import millify +from plotly import figure_factory as ff + +from .colors import * +from .reports import SingleFigureComparison + + +def npv_bar_chart( + cases, color=recoydarkblue, title="NPV Comparison in k€", n_format="%{text:.3s}€" +): + series = SingleFigureComparison(cases, "npv", "NPV (€)").report + case_names = series.index + npvs = series.values + return single_figure_barchart(npvs, case_names, title, color, n_format) + + +def irr_bar_chart( + cases, color=recoydarkblue, title="IRR Comparison in %", n_format="%{text:.1f}%" +): + series = SingleFigureComparison(cases, "irr", "IRR (€)").report + case_names = series.index + irrs = series.values * 100 + return single_figure_barchart(irrs, case_names, title, color, n_format) + + +def ebitda_bar_chart( + cases, color=recoydarkblue, title="EBITDA comparison in k€", n_format="%{text:.3s}€" +): + series = SingleFigureComparison(cases, "ebitda", "EBITDA (€)").report + case_names = series.index + ebitdas = series.values + return single_figure_barchart(ebitdas, case_names, title, color, n_format) + + +def capex_bar_chart( + cases, color=recoydarkblue, title="CAPEX comparison in k€", n_format="%{text:.3s}€" +): + series = SingleFigureComparison(cases, "total_capex", "CAPEX (€)").report + case_names = series.index + capex = series.values * -1 + return single_figure_barchart(capex, case_names, title, color, n_format) + + +def single_figure_barchart(y_values, x_labels, title, color, n_format): + fig = go.Figure() + fig.add_trace( + go.Bar( + x=x_labels, + y=y_values, + text=y_values, + marker_color=color, + cliponaxis=False, + ) + ) + fig.update_layout(title=title) + ymin = min(y_values.min(), 0) * 1.1 + ymax = max(y_values.max(), 0) * 1.1 + fig.update_yaxes(range=[ymin, ymax]) + fig.update_traces(texttemplate=n_format, textposition="outside") + return fig + + +def heatmap( + data, + title=None, + labels=None, + colormap="reds", + mult_factor=1, + decimals=2, + min_value=None, + max_value=None, + width=600, + height=400, + hover_prefix=None, + reversescale=False, +): + data_lists = (data * mult_factor).round(decimals).values.tolist() + + xs = data.columns.tolist() + ys = data.index.to_list() + + annotations = ( + (data * mult_factor) + .applymap(lambda x: millify(x, precision=decimals)) + .values.tolist() + ) + if hover_prefix: + hover_labels = [ + [f"{hover_prefix} {ann}" for ann in sublist] for sublist in annotations + ] + else: + hover_labels = annotations + + # This is an ugly trick to fix a bug with + # the axis labels not showing correctly + xs_ = [f"{str(x)}_" for x in xs] + ys_ = [f"{str(y)}_" for y in ys] + + fig = ff.create_annotated_heatmap( + data_lists, + x=xs_, + y=ys_, + annotation_text=annotations, + colorscale=colormap, + showscale=True, + text=hover_labels, + hoverinfo="text", + reversescale=reversescale, + ) + + # Part 2 of the bug fix + fig.update_xaxes(tickvals=xs_, ticktext=xs) + fig.update_yaxes(tickvals=ys_, ticktext=ys) + + fig.layout.xaxis.type = "category" + fig.layout.yaxis.type = "category" + fig["layout"]["xaxis"].update(side="bottom") + + if min_value: + fig["data"][0]["zmin"] = min_value * mult_factor + if max_value: + fig["data"][0]["zmax"] = max_value * mult_factor + + if labels: + xlabel = labels[0] + ylabel = labels[1] + else: + xlabel = data.columns.name + ylabel = data.index.name + + fig.update_xaxes(title=xlabel) + fig.update_yaxes(title=ylabel) + + if title: + fig.update_layout( + title=title, + title_x=0.5, + title_y=0.85, + width=width, + height=height, + ) + return fig diff --git a/pyrecoy/pyrecoy/pyrecoy/prices-LAPTOP-2MK43FDK.py b/pyrecoy/pyrecoy/pyrecoy/prices-LAPTOP-2MK43FDK.py new file mode 100644 index 0000000..2f90008 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/prices-LAPTOP-2MK43FDK.py @@ -0,0 +1,765 @@ +import os +from datetime import timedelta +from io import BytesIO +from pathlib import Path +from zipfile import ZipFile +import time +import warnings +import json +import pytz + +import numpy as np +import pandas as pd +import requests +from bs4 import BeautifulSoup +from entsoe.entsoe import EntsoePandasClient +from sqlalchemy import MetaData, Table, insert, and_, or_ +from pyrecoy import * + + +def get_fcr_prices(start, end, freq="H") -> pd.DataFrame: + """Get FCR settlement prices from Regelleistung website + + Returns: DataFrame with FCR prices with index with given time frequency in local time. + """ + start = start + timedelta(-1) + end = end + timedelta(1) + data = get_FCR_prices_from_database(start, end, 'NLD') + data = data.resample('15T').ffill() + data = data[['PricePerMWPerISP']] + data.columns = ['FCR NL (EUR/ISP)'] + data.index.name = 'datetime' + data = data.tz_convert('Europe/Amsterdam') + return data + + path = Path( + f"./data/fcr_prices_{freq}_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + ) + if path.exists(): + df = pd.read_csv(path, sep=";", decimal=",", index_col="datetime").astype(float) + startdate = pd.to_datetime(df.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(df.index[-1]).strftime("%Y-%m-%d %H:%M") + df.index = pd.date_range( + startdate, enddate, freq=freq, tz="Europe/Amsterdam", name="datetime" + ) + return df + + dfs = [] + retry = 5 + for date in pd.date_range(start=start, end=end + timedelta(days=1)): + r = 0 + # print(f'DEBUG: {date}') + while r < retry: + try: + url = ( + f"https://www.regelleistung.net/apps/cpp-publisher/api/v1/download/tenders/" + f"resultsoverview?date={date.strftime('%Y-%m-%d')}&exportFormat=xlsx&market=CAPACITY&productTypes=FCR" + ) + df = pd.read_excel(url, engine="openpyxl")[ + [ + "DATE_FROM", + "PRODUCTNAME", + "NL_SETTLEMENTCAPACITY_PRICE_[EUR/MW]", + "DE_SETTLEMENTCAPACITY_PRICE_[EUR/MW]", + ] + ] + # print(f'DEBUG: {date} read in') + dfs.append(df) + break + except Exception: + # print(r) + time.sleep(1) + r += 1 + warnings.warn( + f'No data received for {date.strftime("%Y-%m-%d")}. Retrying...({r}/{retry})' + ) + + if r == retry: + raise RuntimeError(f'No data received for {date.strftime("%Y-%m-%d")}') + + df = pd.concat(dfs, axis=0) + df["hour"] = df["PRODUCTNAME"].map(lambda x: int(x.split("_")[1])) + df["Timeblocks"] = ( + df["PRODUCTNAME"].map(lambda x: int(x.split("_")[2])) - df["hour"] + ) + df.index = df.apply( + lambda row: pd.to_datetime(row["DATE_FROM"]) + timedelta(hours=row["hour"]), + axis=1, + ).dt.tz_localize("Europe/Amsterdam") + df.drop(columns=["DATE_FROM", "PRODUCTNAME", "hour"], inplace=True) + df.rename( + columns={ + "NL_SETTLEMENTCAPACITY_PRICE_[EUR/MW]": f"FCR Price NL [EUR/MW/{freq}]", + "DE_SETTLEMENTCAPACITY_PRICE_[EUR/MW]": f"FCR Price DE [EUR/MW/{freq}]", + }, + inplace=True, + ) + + try: + df[f"FCR Price NL [EUR/MW/{freq}]"] = df[ + f"FCR Price NL [EUR/MW/{freq}]" + ].astype(float) + df[f"FCR Price DE [EUR/MW/{freq}]"] = df[ + f"FCR Price NL [EUR/MW/{freq}]" + ].astype(float) + except Exception as e: + warnings.warn( + f"Could not convert data to floats. Should check... Exception: {e}" + ) + + df = df[~df.index.duplicated(keep="first")] + new_ix = pd.date_range( + start=df.index[0], end=df.index[-1], freq=freq, tz="Europe/Amsterdam" + ) + df = df.reindex(new_ix, method="ffill") + mult = {"H": 1, "4H": 4, "D": 24} + df[f"FCR Price NL [EUR/MW/{freq}]"] /= df["Timeblocks"] / mult[freq] + df[f"FCR Price DE [EUR/MW/{freq}]"] /= df["Timeblocks"] / mult[freq] + df = df[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + df.to_csv(path, sep=";", decimal=",", index_label="datetime") + return df + + +def get_tennet_data(exporttype, start, end): + """Download data from TenneT API + + TenneT documentation: + https://www.tennet.org/bedrijfsvoering/exporteer_data_toelichting.aspx + + Parameters: + ----------- + exporttype : str + Exporttype as defined in TenneT documentation. + start : pd.Timestamp + Start date + end : pd.Timestamp + End date + + Returns: + -------- + DataFrame with API output. + """ + datefrom = start.strftime("%d-%m-%Y") + dateto = end.strftime("%d-%m-%Y") + url = ( + f"http://www.tennet.org/bedrijfsvoering/ExporteerData.aspx?exporttype={exporttype}" + f"&format=csv&datefrom={datefrom}&dateto={dateto}&submit=1" + ) + + return pd.read_csv(url, decimal=",") + + +def get_imb_prices_nl(start: pd.Timestamp, end: pd.Timestamp) -> pd.DataFrame: + exporttype = "verrekenprijzen" + data = get_tennet_data(exporttype, start, end) + first_entry, last_entry = _get_index_first_and_last_entry(data, exporttype) + date_ix = pd.date_range(first_entry, last_entry, freq="15T", tz="Europe/Amsterdam") + + if len(data) == len(date_ix): + data.index = date_ix + else: + data = _handle_missing_data_by_reindexing(data) + + data = data[["invoeden", "Afnemen", "regeltoestand"]] + data.columns = ["POS", "NEG", "RS"] + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + return data + + +def get_balansdelta_nl(start: pd.Timestamp, end: pd.Timestamp) -> pd.DataFrame: + filename = f"balansdelta_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + path = Path("./data") / filename + if path.exists(): + data = pd.read_csv(path, sep=";", decimal=",", index_col="datetime") + startdate = pd.to_datetime(data.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(data.index[-1]).strftime("%Y-%m-%d %H:%M") + data.index = pd.date_range(startdate, enddate, freq="1T", tz="Europe/Amsterdam") + return data + + exporttype = "balansdelta2017" + data = get_tennet_data(exporttype, start, end) + first_entry, last_entry = _get_index_first_and_last_entry(data, exporttype) + date_ix = pd.date_range(first_entry, last_entry, freq="1T", tz="Europe/Amsterdam") + data.index = date_ix + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + if not path.exists(): + data.to_csv(path, sep=";", decimal=",", index_label="datetime") + return data + + +def _get_afrr_prices_from_entsoe(start, end, marketagreement_type, entsoe_api_key): + client = EntsoePandasClient(entsoe_api_key) + return client.query_contracted_reserve_prices( + country_code="NL", + start=start, + end=end + timedelta(days=1), + type_marketagreement_type=marketagreement_type, + ) + + +def get_afrr_capacity_fees_nl(start, end, entsoe_api_key=None): + path = Path( + f"./data/afrr_capacity_fees_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + ) + if path.exists(): + df = pd.read_csv(path, sep=";", decimal=",", index_col="datetime").astype(float) + startdate = pd.to_datetime(df.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(df.index[-1]).strftime("%Y-%m-%d %H:%M") + df.index = pd.date_range(startdate, enddate, freq="D", tz="Europe/Amsterdam") + return df + + if not entsoe_api_key: + try: + entsoe_api_key = os.environ["ENTSOE_API_KEY"] + except: + raise ValueError("Please enter ENTSOE API key") + + date_to_daily_bids = pd.to_datetime("2020-08-31").tz_localize("Europe/Amsterdam") + + if start < date_to_daily_bids: + _start = start - timedelta(days=7) + data = _get_afrr_prices_from_entsoe( + start=_start, + end=min(date_to_daily_bids, end), + marketagreement_type="A02", + entsoe_api_key=entsoe_api_key, + )[["Automatic frequency restoration reserve - Symmetric"]] + + if end > date_to_daily_bids: + _end = date_to_daily_bids - timedelta(days=1) + else: + _end = end + dt_index = pd.date_range(start, _end, freq="D", tz="Europe/Amsterdam") + data = data.reindex(dt_index, method="ffill") + + # ENTSOE: + # "Before week no. 1 of 2020 the values are published per period + # per MW (Currency/MW per procurement period); meaning that it + # is not divided by MTU/ISP in that period." + if start < pd.to_datetime("2019-12-23"): + data[: pd.to_datetime("2019-12-22")] /= 7 * 24 * 4 + + if end >= date_to_daily_bids: + _data = ( + _get_afrr_prices_from_entsoe( + start=max(date_to_daily_bids, start), + end=end, + marketagreement_type="A01", + entsoe_api_key=entsoe_api_key, + ) + .resample("D") + .first() + ) + cols = [ + "Automatic frequency restoration reserve - Down", + "Automatic frequency restoration reserve - Symmetric", + "Automatic frequency restoration reserve - Up", + ] + + for col in cols: + if col not in _data.columns: + _data[col] = np.NaN + + _data = _data[cols] + + try: + data = pd.concat([data, _data], axis=0) + except Exception: + data = _data + + data = data[start:end] + + new_col_names = { + "Automatic frequency restoration reserve - Down": "aFRR Down [€/MW/day]", + "Automatic frequency restoration reserve - Symmetric": "aFRR Symmetric [€/MW/day]", + "Automatic frequency restoration reserve - Up": "aFRR Up [€/MW/day]", + } + data.rename(columns=new_col_names, inplace=True) + hours_per_day = ( + pd.Series( + data=0, + index=pd.date_range( + start, + end + timedelta(days=1), + freq="15T", + tz="Europe/Amsterdam", + inclusive="left", + ), + ) + .resample("D") + .count() + ) + data = data.multiply(hours_per_day.values, axis=0).round(2) + if not path.exists(): + data.to_csv(path, sep=";", decimal=",", index_label="datetime") + return data + + +def _get_afrr_prices_nl_from_tennet(start, end): + """Get aFRR prices from TenneT API + + Parameters: + ----------- + start : pd.Timestamp + Start date + end : pd.Timestamp + End date + + Returns: + -------- + DataFrame with imbalance prices. + """ + filename = f"afrr_prices_nl_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + path = Path("./data") / filename + if path.exists(): + data = pd.read_csv(path, sep=";", decimal=",", index_col="datetime").astype( + float + ) + startdate = pd.to_datetime(data.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(data.index[-1]).strftime("%Y-%m-%d %H:%M") + data.index = pd.date_range( + startdate, enddate, freq="15T", tz="Europe/Amsterdam" + ) + return data + + data = get_tennet_data("verrekenprijzen", start, end) + first_entry, last_entry = _get_index_first_and_last_entry(data, "verrekenprijzen") + date_ix = pd.date_range(first_entry, last_entry, freq="15T", tz="Europe/Amsterdam") + + if len(data) == len(date_ix): + data.index = date_ix + else: + data = _handle_missing_data_by_reindexing(data) + + data = data[["opregelen", "Afregelen"]] + data.columns = ["price_up", "price_down"] + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + + if not path.exists(): + data.to_csv(path, sep=";", decimal=",", index_label="datetime") + return data + + +def get_afrr_prices_nl(start, end): + bd = get_balansdelta_nl(start=start, end=end)[ + ["Hoogste_prijs_opregelen", "Laagste_prijs_afregelen"] + ] + bd.columns = ["rt_price_UP", "rt_price_DOWN"] + afrr_prices = _get_afrr_prices_nl_from_tennet(start, end).reindex( + bd.index, method="ffill" + ) + return pd.concat([afrr_prices, bd], axis=1) + + +def _get_index_first_and_last_entry(data, exporttype): + if exporttype == "balansdelta2017": + time_col_name = "tijd" + elif exporttype == "verrekenprijzen": + time_col_name = "periode_van" + return [ + pd.to_datetime( + " ".join((data["datum"].iloc[ix], data[time_col_name].iloc[ix])), + format="%d-%m-%Y %H:%M", + ) + for ix in [0, -1] + ] + + +def _handle_missing_data_by_reindexing(data): + print("Warning: Entries missing from TenneT data.") + data.index = data[["datum", "periode_van"]].apply(lambda x: " ".join(x), axis=1) + data.index = pd.to_datetime(data.index, format="%d-%m-%Y %H:%M").tz_localize( + "Europe/Amsterdam", ambiguous=True + ) + data = data[~data.index.duplicated(keep="first")] + date_ix = pd.date_range( + data.index[0], data.index[-1], freq="15T", tz="Europe/Amsterdam" + ) + data = data.reindex(date_ix) + print("Workaround implemented: Dataset was reindexed automatically.") + return data + + +def get_imb_prices_be(startdate, enddate): + start = pd.to_datetime(startdate).tz_localize("Europe/Brussels").tz_convert("UTC") + end = ( + pd.to_datetime(enddate).tz_localize("Europe/Brussels") + timedelta(days=1) + ).tz_convert("UTC") + rows = int((end - start) / timedelta(minutes=15)) + resp_df = pd.DataFrame() + + while rows > 0: + print(f"Getting next chunk, {rows} remaining.") + chunk = min(3000, rows) + end = start + timedelta(minutes=chunk * 15) + resp_df = pd.concat([resp_df, elia_api_call(start, end)], axis=0) + start = end + rows -= chunk + + resp_df.index = pd.date_range( + start=resp_df.index[0], end=resp_df.index[-1], tz="Europe/Brussels", freq="15T" + ) + + resp_df.index.name = "datetime" + resp_df = resp_df[ + ["positiveimbalanceprice", "negativeimbalanceprice", "qualitystatus"] + ].rename(columns={"positiveimbalanceprice": "POS", "negativeimbalanceprice": "NEG"}) + resp_df["Validated"] = False + resp_df.loc[resp_df["qualitystatus"] == "Validated", "Validated"] = True + resp_df.drop(columns=["qualitystatus"], inplace=True) + return resp_df + + +def elia_api_call(start, end): + dataset = "ods047" + sort_by = "datetime" + url = "https://opendata.elia.be/api/records/1.0/search/" + rows = int((end - start) / timedelta(minutes=15)) + end = end - timedelta(minutes=15) + endpoint = ( + f"?dataset={dataset}&q=datetime:[{start.strftime('%Y-%m-%dT%H:%M:%SZ')}" + f" TO {end.strftime('%Y-%m-%dT%H:%M:%SZ')}]&rows={rows}&sort={sort_by}" + ) + + for _ in range(5): + try: + resp = requests.get(url + endpoint) + if resp.ok: + break + else: + raise Exception() + except Exception: + print("retrying...") + time.sleep(1) + + if not resp.ok: + raise Exception(f"Error when calling API. Status code: {resp.status_code}") + + resp_json = json.loads(resp.content) + resp_json = [entry["fields"] for entry in resp_json["records"]] + + df = pd.DataFrame(resp_json).set_index("datetime") + df.index = pd.to_datetime(df.index, utc=True).tz_convert("Europe/Brussels") + df = df.sort_index() + return df + + +def get_da_prices_from_entsoe( + start, end, country_code, tz, freq="H", entsoe_api_key=None +): + """Get Day-Ahead prices from ENTSOE + + Parameters: + ----------- + start : pd.Timestamp + Start date + end : pd.Timestamp + End date + freq : str + Frequency, e.g. '15T' or 'H' + + Returns: + -------- + Series with day-ahead prices. + """ + if not entsoe_api_key: + try: + entsoe_api_key = "f6c67fd5-e423-47bc-8a3c-98125ccb645e" + except: + raise ValueError("Please enter ENTSOE API key") + + client = EntsoePandasClient(entsoe_api_key) + data = client.query_day_ahead_prices( + country_code, start=start, end=end + timedelta(days=1) + ) + data = data[~data.index.duplicated()] + data.index = pd.date_range(data.index[0], data.index[-1], freq="H", tz=tz) + + if freq != "H": + data = _reindex_to_freq(data, freq, tz) + + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + return data + + +def _reindex_to_freq(data, freq, tz): + new_ix = pd.date_range( + data.index[0], + data.index[-1] + timedelta(hours=1), + freq=freq, + tz=tz, + ) + return data.reindex(index=new_ix, method="ffill") + + +def get_da_prices_nl(start, end, freq="H", entsoe_api_key=None): + return get_da_prices_from_entsoe( + start, end, "NL", "Europe/Amsterdam", freq=freq, entsoe_api_key=entsoe_api_key + ) + + +def get_da_prices_be(start, end, freq="H", entsoe_api_key=None): + return get_da_prices_from_entsoe( + start, end, "BE", "Europe/Brussels", freq=freq, entsoe_api_key=entsoe_api_key + ) + + +def get_ets_prices(start, end, freq="D"): + """Get CO2 prices (ETS) from ICE + + Values are in €/ton CO2 + + Parameters: + ----------- + start : datetime + Start date + end : datetime + End date + freq : str + Frequency, e.g. '15T' or 'H' + + Returns: + -------- + Series with ETS settlement prices with datetime index (local time) + """ + + start_x = start + timedelta(days=-2) + end_x = end + timedelta(days=2) + + data = get_ets_prices_from_database(start_x, end_x, 'NLD') + data = data.resample('1T').ffill() + data = data.loc[(data.index >= start) & (data.index < end)] + return data + + + # here = pytz.timezone("Europe/Amsterdam") + # start_file = pd.Timestamp(str(start.year) + "-1-1", tz=here).to_pydatetime() + # end_file = pd.Timestamp(str(start.year) + "-12-31", tz=here).to_pydatetime() + + # path = Path( + # f"./data/ets_prices_{freq}_{start_file.strftime('%Y%m%d')}_{end_file.strftime('%Y%m%d')}.csv" + # ) + # if path.exists(): + # return _load_from_csv(path, freq=freq) + # else: + # raise Exception("Data not available for chosen dates.") + + +def get_ttf_prices(start, end, freq="D"): + """Get Day-Ahead natural gas prices (TTF Day-ahead) from ICE + + Values are in €/MWh + + Parameters: + ----------- + start : datetime + Start date + end : datetime + End date + freq : str + Frequency, e.g. '15T' or 'H' + + Returns: + -------- + Series with TTF day-ahead prices with datetime index (local time) + + Start and End are converted into start of year and end of year + """ + + start_x = start + timedelta(days=-2) + end_x = end + timedelta(days=2) + + data = get_ttf_prices_from_database(start_x, end_x, 'NLD') + data = data.resample('1T').ffill() + data = data.loc[(data.index >= start) & (data.index < end)] + return data + + # # while start_year <= end_year: + # here = pytz.timezone("Europe/Amsterdam") + # start_file = pd.Timestamp(str(start.year) + "-1-1", tz=here).to_pydatetime() + # end_file = pd.Timestamp(str(start.year) + "-12-31", tz=here).to_pydatetime() + + # path = Path( + # f"./data/ttf_prices_{freq}_{start_file.strftime('%Y%m%d')}_{end_file.strftime('%Y%m%d')}.csv" + # ) + # print(path) + + # if path.exists(): + # return _load_from_csv(path, freq=freq) + # else: + # raise Exception("Data not available for chosen dates.") + + +def _load_from_csv(filepath, freq): + data = pd.read_csv( + filepath, + delimiter=";", + decimal=",", + parse_dates=False, + index_col="datetime", + ) + ix_start = pd.to_datetime(data.index[0], utc=True).tz_convert("Europe/Amsterdam") + ix_end = pd.to_datetime(data.index[-1], utc=True).tz_convert("Europe/Amsterdam") + data.index = pd.date_range(ix_start, ix_end, freq=freq, tz="Europe/Amsterdam") + return data.squeeze() + + +##### RECOY DATABASE QUERIES ##### + +def get_day_ahead_prices_from_database(start_hour, end_hour, CountryIsoCode, tz='utc'): + table = 'DayAheadPrices' + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter(and_( + table.columns['CountryIsoCode'] == CountryIsoCode, + table.columns['HourStartTime'] >= start_hour, + table.columns['HourStartTime'] < end_hour + )) + + data = pd.DataFrame(data) + data['HourStartTime'] = pd.to_datetime(data['HourStartTime'], utc=True) + data.index = data['HourStartTime'] + data.index.name = 'datetime' + data = data[['Price', 'CountryIsoCode']] + data.columns = ['DAM', 'CountryIsoCode'] + if tz.__eq__('utc') is False: + data = data.tz_convert(tz) + return data + + +def get_imbalance_prices_from_database(start_quarter, end_quarter, CountryIsoCode, tz='utc'): + table = 'ImbalancePrices' + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter(and_( + table.columns['CountryIsoCode'] == CountryIsoCode, + table.columns['QuarterStartTime'] >= start_quarter, + table.columns['QuarterStartTime'] < end_quarter + )) + + data = pd.DataFrame(data) + data['QuarterStartTime'] = pd.to_datetime(data['QuarterStartTime'], utc=True) + data.index = data['QuarterStartTime'] + data.index.name = 'datetime' + data = data[['FeedToGridPrice', 'TakeFromGridPrice', 'CountryIsoCode']] + data.columns = ['POS', 'NEG', 'CountryIsoCode'] + if tz.__eq__('utc') is False: + data = data.tz_convert(tz) + return data + + +def get_FCR_prices_from_database(start_day, end_day, CountryIsoCode, tz='utc'): + table = 'ReservePrices' + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter(and_( + table.columns['CountryIsoCode'] == CountryIsoCode, + table.columns['Timestamp'] >= start_day, + table.columns['Timestamp'] <= end_day, + table.columns['ReserveType'] == 'FCR' + )) + + data = pd.DataFrame(data) + data['Timestamp'] = pd.to_datetime(data['Timestamp'], utc=True) + data.index = data['Timestamp'] + data.index.name = 'datetime' + data = data[['PricePerMWPerISP', 'CountryIsoCode']] + if tz.__eq__('utc') is False: + data = data.tz_convert(tz) + return data + + +def get_imbalance_forecasts_from_database_on_publication_time(start_publication_time, end_publication_time, ForecastSources, CountryIsoCodes): + table = 'ImbalancePriceForecasts' + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter(and_( + table.columns['CountryIsoCode'].in_(CountryIsoCodes), + table.columns['PublicationTime'] >= start_publication_time, + table.columns['PublicationTime'] < end_publication_time, + table.columns['ForecastSource'].in_(ForecastSources) + )) + + return pd.DataFrame(data) + + +def get_imbalance_forecasts_from_database_on_quarter_start_time(start_quarter, end_quarter, ForecastSources, CountryIsoCode): + table = 'ImbalancePriceForecasts' + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter(and_( + table.columns['CountryIsoCode'] == CountryIsoCode, + table.columns['QuarterStartTime'] >= start_quarter, + table.columns['QuarterStartTime'] < end_quarter, + table.columns['PublicationTime'] < end_quarter, + table.columns['ForecastSource'].in_(ForecastSources) + )) + + return pd.DataFrame(data) + + +def get_ttf_prices_from_database(start, end, CountryIsoCode, tz='utc'): + if start.tzinfo != pytz.utc: + start = start.astimezone(pytz.utc) + if end.tzinfo != pytz.utc: + end = end.astimezone(pytz.utc) + + table = 'GasPrices' + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter(and_( + table.columns['CountryIsoCode'] == CountryIsoCode, + table.columns['Timestamp'] >= start, + table.columns['Timestamp'] < end + )) + + data = pd.DataFrame(data) + data['Timestamp'] = pd.to_datetime(data['Timestamp'], utc=True) + data.index = data['Timestamp'] + data.index.name = 'datetime' + data = data[['TTFPrice']] + data.columns = ['Gas prices (€/MWh)'] + if tz.__eq__('utc') is False: + data = data.tz_convert(tz) + return data + + +def get_ets_prices_from_database(start, end, CountryIsoCode, tz='utc'): + if start.tzinfo != pytz.utc: + start = start.astimezone(pytz.utc) + if end.tzinfo != pytz.utc: + end = end.astimezone(pytz.utc) + + table = 'Co2Prices' + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + + data = session.query(table).filter(and_( + table.columns['CountryIsoCode'] == CountryIsoCode, + table.columns['Timestamp'] >= start, + table.columns['Timestamp'] < end + )) + + data = pd.DataFrame(data) + data['Timestamp'] = pd.to_datetime(data['Timestamp'], utc=True) + data.index = data['Timestamp'] + data.index.name = 'datetime' + data = data[['Price']] + data.columns = ['CO2 prices (€/MWh)'] + if tz.__eq__('utc') is False: + data = data.tz_convert(tz) + return data + diff --git a/pyrecoy/pyrecoy/pyrecoy/prices.py b/pyrecoy/pyrecoy/pyrecoy/prices.py new file mode 100644 index 0000000..600b42d --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/prices.py @@ -0,0 +1,752 @@ +import os +from datetime import timedelta +from io import BytesIO +from pathlib import Path +from zipfile import ZipFile +import time +import warnings +import json +import pytz + +import numpy as np +import pandas as pd +import requests +from bs4 import BeautifulSoup +from entsoe.entsoe import EntsoePandasClient +from sqlalchemy import MetaData, Table, insert, and_, or_ +from pyrecoy import * + + +def get_fcr_prices(start, end, freq="H") -> pd.DataFrame: + """Get FCR settlement prices from Regelleistung website + + Returns: DataFrame with FCR prices with index with given time frequency in local time. + """ + start = start + timedelta(-1) + end = end + timedelta(1) + data = get_FCR_prices_from_database(start, end, "NLD") + data = data.resample("15T").ffill() + data = data[["PricePerMWPerISP"]] + data.columns = ["FCR NL (EUR/ISP)"] + data.index.name = "datetime" + data = data.tz_convert("Europe/Amsterdam") + return data + + +def get_tennet_data(exporttype, start, end): + """Download data from TenneT API + + TenneT documentation: + https://www.tennet.org/bedrijfsvoering/exporteer_data_toelichting.aspx + + Parameters: + ----------- + exporttype : str + Exporttype as defined in TenneT documentation. + start : pd.Timestamp + Start date + end : pd.Timestamp + End date + + Returns: + -------- + DataFrame with API output. + """ + datefrom = start.strftime("%d-%m-%Y") + dateto = end.strftime("%d-%m-%Y") + url = ( + f"http://www.tennet.org/bedrijfsvoering/ExporteerData.aspx?exporttype={exporttype}" + f"&format=csv&datefrom={datefrom}&dateto={dateto}&submit=1" + ) + + return pd.read_csv(url, decimal=",") + + +def get_imb_prices_nl(start: pd.Timestamp, end: pd.Timestamp) -> pd.DataFrame: + exporttype = "verrekenprijzen" + data = get_tennet_data(exporttype, start, end) + first_entry, last_entry = _get_index_first_and_last_entry(data, exporttype) + date_ix = pd.date_range(first_entry, last_entry, freq="15T", tz="Europe/Amsterdam") + + if len(data) == len(date_ix): + data.index = date_ix + else: + data = _handle_missing_data_by_reindexing(data) + + data = data[["invoeden", "Afnemen", "regeltoestand"]] + data.columns = ["POS", "NEG", "RS"] + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + return data + + +def get_balansdelta_nl(start: pd.Timestamp, end: pd.Timestamp) -> pd.DataFrame: + filename = f"balansdelta_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + path = Path("./data") / filename + if path.exists(): + data = pd.read_csv(path, sep=";", decimal=",", index_col="datetime") + startdate = pd.to_datetime(data.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(data.index[-1]).strftime("%Y-%m-%d %H:%M") + data.index = pd.date_range(startdate, enddate, freq="1T", tz="Europe/Amsterdam") + return data + + exporttype = "balansdelta2017" + data = get_tennet_data(exporttype, start, end) + first_entry, last_entry = _get_index_first_and_last_entry(data, exporttype) + date_ix = pd.date_range(first_entry, last_entry, freq="1T", tz="Europe/Amsterdam") + data.index = date_ix + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + if not path.exists(): + data.to_csv(path, sep=";", decimal=",", index_label="datetime") + return data + + +def _get_afrr_prices_from_entsoe(start, end, marketagreement_type, entsoe_api_key): + client = EntsoePandasClient(entsoe_api_key) + return client.query_contracted_reserve_prices( + country_code="NL", + start=start, + end=end + timedelta(days=1), + type_marketagreement_type=marketagreement_type, + ) + + +def get_afrr_capacity_fees_nl(start, end, entsoe_api_key=None): + path = Path( + f"./data/afrr_capacity_fees_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + ) + if path.exists(): + df = pd.read_csv(path, sep=";", decimal=",", index_col="datetime").astype(float) + startdate = pd.to_datetime(df.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(df.index[-1]).strftime("%Y-%m-%d %H:%M") + df.index = pd.date_range(startdate, enddate, freq="D", tz="Europe/Amsterdam") + return df + + if not entsoe_api_key: + try: + entsoe_api_key = os.environ["ENTSOE_API_KEY"] + except: + raise ValueError("Please enter ENTSOE API key") + + date_to_daily_bids = pd.to_datetime("2020-08-31").tz_localize("Europe/Amsterdam") + + if start < date_to_daily_bids: + _start = start - timedelta(days=7) + data = _get_afrr_prices_from_entsoe( + start=_start, + end=min(date_to_daily_bids, end), + marketagreement_type="A02", + entsoe_api_key=entsoe_api_key, + )[["Automatic frequency restoration reserve - Symmetric"]] + + if end > date_to_daily_bids: + _end = date_to_daily_bids - timedelta(days=1) + else: + _end = end + dt_index = pd.date_range(start, _end, freq="D", tz="Europe/Amsterdam") + data = data.reindex(dt_index, method="ffill") + + # ENTSOE: + # "Before week no. 1 of 2020 the values are published per period + # per MW (Currency/MW per procurement period); meaning that it + # is not divided by MTU/ISP in that period." + if start < pd.to_datetime("2019-12-23"): + data[: pd.to_datetime("2019-12-22")] /= 7 * 24 * 4 + + if end >= date_to_daily_bids: + _data = ( + _get_afrr_prices_from_entsoe( + start=max(date_to_daily_bids, start), + end=end, + marketagreement_type="A01", + entsoe_api_key=entsoe_api_key, + ) + .resample("D") + .first() + ) + cols = [ + "Automatic frequency restoration reserve - Down", + "Automatic frequency restoration reserve - Symmetric", + "Automatic frequency restoration reserve - Up", + ] + + for col in cols: + if col not in _data.columns: + _data[col] = np.NaN + + _data = _data[cols] + + try: + data = pd.concat([data, _data], axis=0) + except Exception: + data = _data + + data = data[start:end] + + new_col_names = { + "Automatic frequency restoration reserve - Down": "aFRR Down [€/MW/day]", + "Automatic frequency restoration reserve - Symmetric": "aFRR Symmetric [€/MW/day]", + "Automatic frequency restoration reserve - Up": "aFRR Up [€/MW/day]", + } + data.rename(columns=new_col_names, inplace=True) + hours_per_day = ( + pd.Series( + data=0, + index=pd.date_range( + start, + end + timedelta(days=1), + freq="15T", + tz="Europe/Amsterdam", + inclusive="left", + ), + ) + .resample("D") + .count() + ) + data = data.multiply(hours_per_day.values, axis=0).round(2) + if not path.exists(): + data.to_csv(path, sep=";", decimal=",", index_label="datetime") + return data + + +def _get_afrr_prices_nl_from_tennet(start, end): + """Get aFRR prices from TenneT API + + Parameters: + ----------- + start : pd.Timestamp + Start date + end : pd.Timestamp + End date + + Returns: + -------- + DataFrame with imbalance prices. + """ + filename = f"afrr_prices_nl_{start.strftime('%Y%m%d')}_{end.strftime('%Y%m%d')}.csv" + path = Path("./data") / filename + if path.exists(): + data = pd.read_csv(path, sep=";", decimal=",", index_col="datetime").astype( + float + ) + startdate = pd.to_datetime(data.index[0]).strftime("%Y-%m-%d %H:%M") + enddate = pd.to_datetime(data.index[-1]).strftime("%Y-%m-%d %H:%M") + data.index = pd.date_range( + startdate, enddate, freq="15T", tz="Europe/Amsterdam" + ) + return data + + data = get_tennet_data("verrekenprijzen", start, end) + first_entry, last_entry = _get_index_first_and_last_entry(data, "verrekenprijzen") + date_ix = pd.date_range(first_entry, last_entry, freq="15T", tz="Europe/Amsterdam") + + if len(data) == len(date_ix): + data.index = date_ix + else: + data = _handle_missing_data_by_reindexing(data) + + data = data[["opregelen", "Afregelen"]] + data.columns = ["price_up", "price_down"] + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + + if not path.exists(): + data.to_csv(path, sep=";", decimal=",", index_label="datetime") + return data + + +def get_afrr_prices_nl(start, end): + bd = get_balansdelta_nl(start=start, end=end)[ + ["Hoogste_prijs_opregelen", "Laagste_prijs_afregelen"] + ] + bd.columns = ["rt_price_UP", "rt_price_DOWN"] + afrr_prices = _get_afrr_prices_nl_from_tennet(start, end).reindex( + bd.index, method="ffill" + ) + return pd.concat([afrr_prices, bd], axis=1) + + +def _get_index_first_and_last_entry(data, exporttype): + if exporttype == "balansdelta2017": + time_col_name = "tijd" + elif exporttype == "verrekenprijzen": + time_col_name = "periode_van" + return [ + pd.to_datetime( + " ".join((data["datum"].iloc[ix], data[time_col_name].iloc[ix])), + format="%d-%m-%Y %H:%M", + ) + for ix in [0, -1] + ] + + +def _handle_missing_data_by_reindexing(data): + print("Warning: Entries missing from TenneT data.") + data.index = data[["datum", "periode_van"]].apply(lambda x: " ".join(x), axis=1) + data.index = pd.to_datetime(data.index, format="%d-%m-%Y %H:%M").tz_localize( + "Europe/Amsterdam", ambiguous=True + ) + data = data[~data.index.duplicated(keep="first")] + date_ix = pd.date_range( + data.index[0], data.index[-1], freq="15T", tz="Europe/Amsterdam" + ) + data = data.reindex(date_ix) + print("Workaround implemented: Dataset was reindexed automatically.") + return data + + +def get_imb_prices_be(startdate, enddate): + start = pd.to_datetime(startdate).tz_localize("Europe/Brussels").tz_convert("UTC") + end = ( + pd.to_datetime(enddate).tz_localize("Europe/Brussels") + timedelta(days=1) + ).tz_convert("UTC") + rows = int((end - start) / timedelta(minutes=15)) + resp_df = pd.DataFrame() + + while rows > 0: + print(f"Getting next chunk, {rows} remaining.") + chunk = min(3000, rows) + end = start + timedelta(minutes=chunk * 15) + resp_df = pd.concat([resp_df, elia_api_call(start, end)], axis=0) + start = end + rows -= chunk + + resp_df.index = pd.date_range( + start=resp_df.index[0], end=resp_df.index[-1], tz="Europe/Brussels", freq="15T" + ) + + resp_df.index.name = "datetime" + resp_df = resp_df[ + ["positiveimbalanceprice", "negativeimbalanceprice", "qualitystatus"] + ].rename(columns={"positiveimbalanceprice": "POS", "negativeimbalanceprice": "NEG"}) + resp_df["Validated"] = False + resp_df.loc[resp_df["qualitystatus"] == "Validated", "Validated"] = True + resp_df.drop(columns=["qualitystatus"], inplace=True) + return resp_df + + +def elia_api_call(start, end): + dataset = "ods047" + sort_by = "datetime" + url = "https://opendata.elia.be/api/records/1.0/search/" + rows = int((end - start) / timedelta(minutes=15)) + end = end - timedelta(minutes=15) + endpoint = ( + f"?dataset={dataset}&q=datetime:[{start.strftime('%Y-%m-%dT%H:%M:%SZ')}" + f" TO {end.strftime('%Y-%m-%dT%H:%M:%SZ')}]&rows={rows}&sort={sort_by}" + ) + + for _ in range(5): + try: + resp = requests.get(url + endpoint) + if resp.ok: + break + else: + raise Exception() + except Exception: + print("retrying...") + time.sleep(1) + + if not resp.ok: + raise Exception(f"Error when calling API. Status code: {resp.status_code}") + + resp_json = json.loads(resp.content) + resp_json = [entry["fields"] for entry in resp_json["records"]] + + df = pd.DataFrame(resp_json).set_index("datetime") + df.index = pd.to_datetime(df.index, utc=True).tz_convert("Europe/Brussels") + df = df.sort_index() + return df + + +def get_da_prices_from_entsoe( + start, end, country_code, tz, freq="H", entsoe_api_key=None +): + """Get Day-Ahead prices from ENTSOE + + Parameters: + ----------- + start : pd.Timestamp + Start date + end : pd.Timestamp + End date + freq : str + Frequency, e.g. '15T' or 'H' + + Returns: + -------- + Series with day-ahead prices. + """ + if not entsoe_api_key: + try: + entsoe_api_key = "f6c67fd5-e423-47bc-8a3c-98125ccb645e" + except: + raise ValueError("Please enter ENTSOE API key") + + client = EntsoePandasClient(entsoe_api_key) + data = client.query_day_ahead_prices( + country_code, start=start, end=end + timedelta(days=1) + ) + data = data[~data.index.duplicated()] + data.index = pd.date_range(data.index[0], data.index[-1], freq="H", tz=tz) + + if freq != "H": + data = _reindex_to_freq(data, freq, tz) + + data = data[start.strftime("%Y-%m-%d") : end.strftime("%Y-%m-%d")] + return data + + +def _reindex_to_freq(data, freq, tz): + new_ix = pd.date_range( + data.index[0], + data.index[-1] + timedelta(hours=1), + freq=freq, + tz=tz, + ) + return data.reindex(index=new_ix, method="ffill") + + +def get_da_prices_nl(start, end, freq="H", entsoe_api_key=None): + return get_da_prices_from_entsoe( + start, end, "NL", "Europe/Amsterdam", freq=freq, entsoe_api_key=entsoe_api_key + ) + + +def get_da_prices_be(start, end, freq="H", entsoe_api_key=None): + return get_da_prices_from_entsoe( + start, end, "BE", "Europe/Brussels", freq=freq, entsoe_api_key=entsoe_api_key + ) + + +def get_ets_prices(start, end, freq="D"): + """Get CO2 prices (ETS) from ICE + + Values are in €/ton CO2 + + Parameters: + ----------- + start : datetime + Start date + end : datetime + End date + freq : str + Frequency, e.g. '15T' or 'H' + + Returns: + -------- + Series with ETS settlement prices with datetime index (local time) + """ + + start_x = start + timedelta(days=-2) + end_x = end + timedelta(days=2) + + data = get_ets_prices_from_database(start_x, end_x, "NLD") + data = data.resample("1T").ffill() + data = data.loc[(data.index >= start) & (data.index < end)] + return data + + here = pytz.timezone("Europe/Amsterdam") + start_file = pd.Timestamp(str(start.year) + "-1-1", tz=here).to_pydatetime() + end_file = pd.Timestamp(str(start.year) + "-12-31", tz=here).to_pydatetime() + + path = Path( + f"./data/ets_prices_{freq}_{start_file.strftime('%Y%m%d')}_{end_file.strftime('%Y%m%d')}.csv" + ) + if path.exists(): + return _load_from_csv(path, freq=freq) + else: + raise Exception("Data not available for chosen dates.") + +def get_ets_prices_excel(start, end, freq="D"): + """Get CO2 prices (ETS) from ICE + + Values are in €/ton CO2 + + Parameters: + ----------- + start : datetime + Start date + end : datetime + End date + freq : str + Frequency, e.g. '15T' or 'H' + + Returns: + -------- + Series with ETS settlement prices with datetime index (local time) + """ + + start_x = start + timedelta(days=-2) + end_x = end + timedelta(days=2) + + data = pd.read_excel(r"C:\Users\shahla.huseynova\Heliox Group B.V\Recoy - Documents\01 _ Acquisition\FOLBB\CO2 prijzen EEX 2021-2023.xlsx", + sheet_name = 'SINGLE COL', + parse_dates = True, + index_col = 0 + ) + data.set_index(pd.to_datetime(data.index)) + data.index = pd.to_datetime(data.index,dayfirst=True) + data = data.groupby(data.index).last() + data.index = data.index.tz_localize('Europe/Amsterdam') + data = data.resample("1T").ffill() + data = data.loc[(data.index >= start) & (data.index < end)] + return data + + here = pytz.timezone("Europe/Amsterdam") + start_file = pd.Timestamp(str(start.year) + "-1-1", tz=here).to_pydatetime() + end_file = pd.Timestamp(str(start.year) + "-12-31", tz=here).to_pydatetime() + + path = Path( + f"./data/ets_prices_{freq}_{start_file.strftime('%Y%m%d')}_{end_file.strftime('%Y%m%d')}.csv" + ) + if path.exists(): + return _load_from_csv(path, freq=freq) + else: + raise Exception("Data not available for chosen dates.") + +def get_ttf_prices(start, end, freq="D"): + """Get Day-Ahead natural gas prices (TTF Day-ahead) from ICE + + Values are in €/MWh + + Parameters: + ----------- + start : datetime + Start date + end : datetime + End date + freq : str + Frequency, e.g. '15T' or 'H' + + Returns: + -------- + Series with TTF day-ahead prices with datetime index (local time) + + Start and End are converted into start of year and end of year + """ + + start_x = start + timedelta(days=-2) + end_x = end + timedelta(days=2) + + data = get_ttf_prices_from_database(start_x, end_x, "NLD") + data = data.resample("1T").ffill() + data = data.loc[(data.index >= start) & (data.index < end)] + return data + + # while start_year <= end_year: + here = pytz.timezone("Europe/Amsterdam") + start_file = pd.Timestamp(str(start.year) + "-1-1", tz=here).to_pydatetime() + end_file = pd.Timestamp(str(start.year) + "-12-31", tz=here).to_pydatetime() + + path = Path( + f"./data/ttf_prices_{freq}_{start_file.strftime('%Y%m%d')}_{end_file.strftime('%Y%m%d')}.csv" + ) + + if path.exists(): + return _load_from_csv(path, freq=freq) + else: + raise Exception("Data not available for chosen dates.") + + +def _load_from_csv(filepath, freq): + data = pd.read_csv( + filepath, + delimiter=";", + decimal=",", + parse_dates=False, + index_col="datetime", + ) + ix_start = pd.to_datetime(data.index[0], utc=True).tz_convert("Europe/Amsterdam") + ix_end = pd.to_datetime(data.index[-1], utc=True).tz_convert("Europe/Amsterdam") + data.index = pd.date_range(ix_start, ix_end, freq=freq, tz="Europe/Amsterdam") + return data.squeeze() + + +##### RECOY DATABASE QUERIES ##### + + +def convert_columns_to_localized_datetime_from_utc(df, columns, tz): + for column in columns: + df[column] = pd.to_datetime(df[column], utc=True) + df[column] = df[column].dt.tz_convert(tz) + return df + + +def get_price_data_from_database( + database_name, + time_index_column, + database_columns, + rename_columns, + start, + end, + CountryIsoCode, + tz="utc", + to_datetime_columns=[], +): + """_summary_ + + Args: + database_name (string): name of the database + time_index_column (string): column which is converted to a datetime column and used as the index + database_columns (list of strings): columns of the database table you want to query + rename_columns (list of strings): new names for the columns which are queried + start (string or datetime): start time of the data you want to select based on the time_index_column + end (string or datetime): end time of the data you want to select based on the time_index_column + CountryIsoCode (string): CountryIsoCode of the data + tz (str, optional): Timezone you want the datatime columns to be converted to + to_datetime_columns (list, optional): Additional columns which are transferred to datetime columns. Defaults to []. + + Returns: + _type_: _description_ + """ + table = database_name + md = MetaData(ENGINE_PRICES) + table = Table(table, md, autoload=True) + session = sessionmaker(bind=ENGINE_PRICES)() + end = end + timedelta(days=+1) + + data = session.query(table).filter( + and_( + table.columns["CountryIsoCode"] == CountryIsoCode, + table.columns[time_index_column] >= start, + table.columns[time_index_column] < end, + ) + ) + data = pd.DataFrame(data) + data[time_index_column] = pd.to_datetime(data[time_index_column], utc=True) + data.index = data[time_index_column] + data.index.name = "datetime" + data = data[database_columns + ["CountryIsoCode"]] + data.columns = rename_columns + ["CountryIsoCode"] + if tz.__eq__("utc") is False: + data = data.tz_convert(tz) + data = convert_columns_to_localized_datetime_from_utc(data, to_datetime_columns, tz) + return data + + +def get_day_ahead_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_price_data_from_database( + "DayAheadPrices", + "HourStartTime", + ["Price"], + ["DAM"], + start, + end, + CountryIsoCode, + tz=tz, + ) + + +def get_imbalance_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_price_data_from_database( + "ImbalancePrices", + "QuarterStartTime", + ["FeedToGridPrice", "TakeFromGridPrice"], + ["POS", "NEG"], + start, + end, + CountryIsoCode, + tz=tz, + ) + + +def get_imbalance_forecasts_from_database_on_publication_time( + start, end, CountryIsoCode, tz="utc" +): + return get_price_data_from_database( + "ImbalancePriceForecasts", + "PublicationTime", + ["PublicationTime", "QuarterStartTime", "FeedToGridPrice", "TakeFromGridPrice"], + ["PublicationTime", "QuarterStartTime", "ForePos", "ForeNeg"], + start, + end, + CountryIsoCode, + tz=tz, + to_datetime_columns=["QuarterStartTime"], + ) + + +def get_imbalance_forecasts_from_database_on_quarter_start_time( + start, end, CountryIsoCode, tz="utc" +): + return get_price_data_from_database( + "ImbalancePriceForecasts", + "QuarterStartTime", + ["PublicationTime", "QuarterStartTime", "FeedToGridPrice", "TakeFromGridPrice"], + ["PublicationTime", "QuarterStartTime", "ForePos", "ForeNeg"], + start, + end, + CountryIsoCode, + tz=tz, + to_datetime_columns=["QuarterStartTime"], + ) + + +def get_ttf_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_price_data_from_database( + "GasPrices", + "DeliveryDate", + ["Price"], + ["Gas prices (€/MWh)"], + start, + end, + CountryIsoCode, + tz=tz, + ) + + +def get_ets_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_price_data_from_database( + "Co2Prices", + "DeliveryDate", + ["Price"], + ["CO2 prices (€/MWh)"], + start, + end, + CountryIsoCode, + tz=tz, + ) + + +def get_reserve_prices_from_database( + start, end, reserve_type, CountryIsoCode, tz="utc" +): + data = get_price_data_from_database( + "ReservePrices", + "Timestamp", + ["PricePerMWPerISP", "ReserveType"], + ["PricePerMWPerISP", "ReserveType"], + start, + end, + CountryIsoCode, + tz=tz, + ) + data = data.loc[data["ReserveType"] == reserve_type] + return data + + +def get_FCR_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_reserve_prices_from_database(start, end, "FCR", CountryIsoCode, tz=tz) + + +def get_aFRR_up_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_reserve_prices_from_database( + start, end, "aFRR Up", CountryIsoCode, tz=tz + ) + + +def get_aFRR_up_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_reserve_prices_from_database( + start, end, "aFRR Down", CountryIsoCode, tz=tz + ) + + +def get_aFRR_up_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_reserve_prices_from_database( + start, end, "mFRR Up", CountryIsoCode, tz=tz + ) + + +def get_aFRR_up_prices_from_database(start, end, CountryIsoCode, tz="utc"): + return get_reserve_prices_from_database( + start, end, "mFRR Up", CountryIsoCode, tz=tz + ) diff --git a/pyrecoy/pyrecoy/pyrecoy/reports.py b/pyrecoy/pyrecoy/pyrecoy/reports.py new file mode 100644 index 0000000..6108272 --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/reports.py @@ -0,0 +1,156 @@ +import numpy as np +import pandas as pd + +from .styling import businesscase_formatter, num_formatting, perc_formatting + + +class CaseReport: + """Dataframe report showing KPIs for specific CaseStudy. + + Parameters: + ----------- + case : CaseStudy + kind : str + The report type. {electr_market_results', cashflows', 'ebitda_calc'}. + baseline : CaseStudy + include_perc: bool + """ + + def __init__(self, case, kind): + self._check_if_attr_exists(case, kind) + case_data = getattr(case, kind) + self.report = self.create_report(case.name, case_data) + self.formatting = "number" + + def _check_if_attr_exists(self, case, kind): + if not hasattr(case, kind): + raise AttributeError( + f"Attribute '{kind}' is not available for '{case.name}' case. " + "You should first generate it using " + "the appropriate CaseStudy method." + ) + + def create_report(self, case_name, case_data): + if isinstance(case_data, dict): + case_data = pd.Series(case_data) + + return pd.DataFrame(case_data, columns=[case_name]) + + def show(self, presentation_format=True): + if not presentation_format: + return self.report + + if self.formatting == "percentage": + return self.report.applymap(perc_formatting) + else: + return self.report.applymap(num_formatting) + + +class ComparisonReport(CaseReport): + """Dataframe report showing a copmarison of KPIs between CaseStudy instances. + + Parameters: + ----------- + cases : list + List of CaseStudy instances + kind : str + Type of report + baseline : CaseStudy + CaseStudy instance to use as baseline + comparison : str + {'absolute', 'relative', 'percentage'} + Sets how the numbers in the comparison are in relation to the baseline. + """ + + def __init__(self, cases, kind, baseline=None, comparison="absolute"): + case_reports = [] + self.formatting = "number" + + for case in cases: + case_report = CaseReport(case=case, kind=kind).report + case_reports.append(case_report) + + self.report = pd.concat(case_reports, axis=1).fillna(0) + + if comparison == "relative": + self._comp_relative(baseline) + elif comparison == "percentage": + self._comp_percentage(baseline) + + # ugly fix to make sure EBITDA is at the bottom when df is printed + if kind == "ebitda_calc": + ix = self.report.index.to_list() + ix.remove("EBITDA (€)") + ix.remove("Depreciation (€)") + ix.remove("EBITDA + depr (€)") + ix.append("EBITDA (€)") + ix.append("Depreciation (€)") + ix.append("EBITDA + depr (€)") + self.report = self.report.reindex(ix) + + def _comp_relative(self, baseline): + baseline_report = self.report[baseline.name] + self.report = self.report.subtract(baseline_report, axis=0) + + if baseline.name in self.report.columns: + self.report.drop(columns=baseline.name, inplace=True) + if baseline.name in self.report.index: + self.report.drop(index=baseline.name, inplace=True) + + self.formatting = "number" + + def _comp_percentage(self, baseline): + baseline_report = self.report[baseline.name] + self.report = self.report.divide(baseline_report / 100, axis=0).replace( + [-np.inf, np.inf], 0 + ) + self.report.replace([-np.inf, np.inf], 0, inplace=True) + self.formatting = "percentage" + + +class BusinessCaseReport(CaseReport): + """Show business case for CaseStudy""" + + def __init__(self, case, presentation_format=False): + self._check_if_attr_exists(case, "business_case") + self.report = getattr(case, "business_case") + + def show(self, presentation_format=True): + if presentation_format: + return businesscase_formatter(self.report) + else: + return self.report + + +class SingleFigureComparison(ComparisonReport): + def __init__( + self, + cases, + kpi, + label, + baseline=None, + comparison="absolute", + ): + figure_dict = {} + for case in cases: + self._check_if_attr_exists(case, kpi) + figure_dict[case.name] = getattr(case, kpi) + + self.report = pd.Series(figure_dict, name=label) + + if comparison == "relative": + self._comp_relative(baseline) + elif comparison == "percentage": + self._comp_percentage(baseline) + + def show(self, nformat=None): + if nformat is not None: + return self.report.apply(nformat.format) + else: + return self.report + + def _comp_relative(self, baseline): + baseline_report = self.report[baseline.name] + self.report = self.report.subtract(baseline_report, axis=0) + self.report.drop(index=baseline.name, inplace=True) + self.formatting = "number" diff --git a/pyrecoy/pyrecoy/pyrecoy/rop_assets.py b/pyrecoy/pyrecoy/pyrecoy/rop_assets.py new file mode 100644 index 0000000..41f604a --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/rop_assets.py @@ -0,0 +1,34 @@ +def get_power_profiles(start, end, country, in_local_time=True): + start = timestamp_to_utc(start) + end = timestamp_to_utc(end) + engine = db_engine("rop_test") + connection, table = create_connection(engine, "ImbalancePrices") + start = start.floor("15T") + query = ( + select([table]) + .where( + table.columns.QuarterStartTime >= start.strftime("%Y-%m-%d %H:%M"), + table.columns.QuarterStartTime < end.strftime("%Y-%m-%d %H:%M"), + table.columns.CountryIsoCode == country, + ) + .order_by(table.columns.QuarterStartTime) + ) + result = connection.execute(query).fetchall() + if len(result) == 0: + raise Exception("Day-ahead prices data not yet available.") + + data = pd.DataFrame(result, columns=result[0].keys()) + + if in_local_time: + data["QuarterStartTime"] = dt_column_to_local_time(data["QuarterStartTime"]) + + data.drop(columns=["Id", "CountryIsoCode"], inplace=True) + data.rename( + columns={ + "QuarterStartTime": "datetime", + "TakeFromGridPrice": "NEG", + "FeedToGridPrice": "POS", + }, + inplace=True, + ) + return data.set_index("datetime")[["POS", "NEG"]] \ No newline at end of file diff --git a/pyrecoy/pyrecoy/pyrecoy/rop_prices.py b/pyrecoy/pyrecoy/pyrecoy/rop_prices.py new file mode 100644 index 0000000..9ab908a --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/rop_prices.py @@ -0,0 +1,92 @@ +from sqlalchemy import select +import pandas as pd +from .converters import dt_column_to_local_time, timestamp_to_utc +from .databases import db_engine, create_connection + + +def get_imbalance_prices(start, end, country, in_local_time=True): + start = timestamp_to_utc(start) + end = timestamp_to_utc(end) + engine = db_engine("rop_prices_test") + connection, table = create_connection(engine, "ImbalancePrices") + start = start.floor("15T") + query = ( + select([table]) + .where( + table.columns.QuarterStartTime >= start.strftime("%Y-%m-%d %H:%M"), + table.columns.QuarterStartTime < end.strftime("%Y-%m-%d %H:%M"), + table.columns.CountryIsoCode == country, + ) + .order_by(table.columns.QuarterStartTime) + ) + result = connection.execute(query).fetchall() + if len(result) == 0: + raise Exception("Day-ahead prices data not yet available.") + + data = pd.DataFrame(result, columns=result[0].keys()) + + if in_local_time: + data["QuarterStartTime"] = dt_column_to_local_time(data["QuarterStartTime"]) + + data.drop(columns=["Id", "CountryIsoCode"], inplace=True) + data.rename( + columns={ + "QuarterStartTime": "datetime", + "TakeFromGridPrice": "NEG", + "FeedToGridPrice": "POS", + }, + inplace=True, + ) + return data.set_index("datetime")[["POS", "NEG"]] + + +def get_dayahead_prices(start, end, country, in_local_time=True): + start = timestamp_to_utc(start) + end = timestamp_to_utc(end) + engine = db_engine("rop_prices_test") + connection, table = create_connection(engine, "DayAheadPrices") + start = start.floor("60T") + query = ( + select([table]) + .where( + table.columns.HourStartTime >= start.strftime("%Y-%m-%d %H:%M"), + table.columns.HourStartTime < end.strftime("%Y-%m-%d %H:%M"), + table.columns.CountryIsoCode == country, + ) + .order_by(table.columns.HourStartTime) + ) + result = connection.execute(query).fetchall() + if len(result) == 0: + raise Exception("Day-ahead prices data not yet available.") + + data = pd.DataFrame(result, columns=result[0].keys()) + + if in_local_time: + data["HourStartTime"] = dt_column_to_local_time(data["HourStartTime"]) + + data.drop(columns=["Id", "CountryIsoCode"], inplace=True) + data.rename(columns={"HourStartTime": "datetime", "Price": "DAM"}, inplace=True) + return data.set_index("datetime") + + +def get_market_price_data(start, end, country, in_local_time=True): + tz = "Europe/Amsterdam" if in_local_time else "UTC" + dt_ix = pd.date_range( + start=start.floor("H"), + end=end.ceil("H"), + freq="15T", + tz=tz, + inclusive="left", + ) + prices = pd.DataFrame(index=dt_ix, columns=["DAM", "POS", "NEG"]) + prices["DAM"] = get_dayahead_prices( + start, end, country=country, in_local_time=in_local_time + ).reindex(dt_ix, method="ffill") + prices["DAM"].fillna(method="ffill", inplace=True) + + imbprices = get_imbalance_prices( + start, end, country=country, in_local_time=in_local_time + ) + prices["POS"] = imbprices["POS"] + prices["NEG"] = imbprices["NEG"] + return prices diff --git a/pyrecoy/pyrecoy/pyrecoy/sensitivity.py b/pyrecoy/pyrecoy/pyrecoy/sensitivity.py new file mode 100644 index 0000000..3c5628f --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/sensitivity.py @@ -0,0 +1,225 @@ +import itertools +import gc +from copy import deepcopy +from tkinter import Label +import warnings + +import pandas as pd +import numpy as np +from tqdm.notebook import tqdm +from millify import millify +from plotly.graph_objs import Figure + +from .casestudy import CaseStudy +from .colors import recoygreen, recoyred + + +class SensitivityAnalysis: + """ + Runs an simulation routine with different input configurations, + so that sensitivity of variables can be analysed. + """ + + def __init__(self, c, s, routine, param, values, output_kpis): + self.configs = self._generate_configs(c, param, values) + output_dict = self._prepare_output_dict(s.cases, output_kpis) + self.kpis = self._run_sensitivities(s, routine, output_kpis, output_dict) + + def _generate_configs(self, c, param, values): + configs = {} + for value in values: + _c = deepcopy(c) + setattr(_c, param, value) + configs[value] = _c + return configs + + def _prepare_output_dict(self, cases, output_kpis): + output_dict = dict.fromkeys(self.configs.keys()) + for value in self.configs: + output_dict[value] = dict.fromkeys(output_kpis) + for kpi in output_kpis: + output_dict[value][kpi] = dict.fromkeys([case.name for case in cases]) + return output_dict + + def _run_sensitivities(self, s, routine, output_kpis, output_dict): + for name, c in tqdm(self.configs.items()): + _s = deepcopy(s) + _s = routine(c, _s) + for kpi in output_kpis: + for case in _s.cases: + output_dict[name][kpi][case.name] = getattr(case, kpi, np.nan) + del _s + gc.collect() + return output_dict + + def single_kpi_overview(self, kpi, case_names=None): + """Creates a DataFrame with chosen output kpi, + for each CaseStudy in each Configuration. + """ + if not case_names: + case_names = CaseStudy.instances.keys() + + kpi_values = { + name: {case: self.kpis[name][kpi][case] for case in case_names} + for name in self.kpis.keys() + } + + return pd.DataFrame(kpi_values).T + + def cashflows_comparison(self, case=None, baseline=None): + ebitda_calc_overview = {} + baseline_calc = {} + for input_value, kpi_data in self.kpis.items(): + for kpi, case_data in kpi_data.items(): + for case_name, data in case_data.items(): + if kpi == "cashflows": + if case_name == case: + ebitda_calc_overview[input_value] = data + if case_name == baseline: + baseline_calc[input_value] = data + + ebitda_calc_overview = pd.DataFrame(ebitda_calc_overview) + if not baseline: + return ebitda_calc_overview + + baseline_calc = pd.DataFrame(baseline_calc) + return ebitda_calc_overview.subtract(baseline_calc, fill_value=0) + + +class SensitivityMatrix: + def __init__(self, c, s, routine, x_param, y_param, x_vals, y_vals, output_kpis): + self.x_param = x_param + self.y_param = y_param + + self.configs = self._generate_configs(c, x_vals, y_vals) + output_dict = self._prepare_output_dict(s.cases, output_kpis) + self.kpis = self._run_sensitivities(s, routine, output_kpis, output_dict) + + def _generate_configs(self, c, x_vals, y_vals): + configs = {x_val: dict.fromkeys(y_vals) for x_val in x_vals} + + self.xy_combinations = list(itertools.product(x_vals, y_vals)) + for x_val, y_val in self.xy_combinations: + _c = deepcopy(c) + setattr(_c, self.x_param, x_val) + setattr(_c, self.y_param, y_val) + configs[x_val][y_val] = _c + return configs + + def _prepare_output_dict(self, cases, output_kpis): + output_dict = {} + for name in [case.name for case in cases]: + output_dict[name] = dict.fromkeys(output_kpis) + for kpi in output_kpis: + output_dict[name][kpi] = deepcopy(self.configs) + return output_dict + + def _run_sensitivities(self, s, routine, output_kpis, output_dict): + for x_val, y_val in tqdm(self.xy_combinations): + _c = self.configs[x_val][y_val] + _s = deepcopy(s) + _s = routine(_c, _s) + for kpi in output_kpis: + for case in _s.cases: + output = getattr(case, kpi, np.nan) + output_dict[case.name][kpi][x_val][y_val] = output + del _s + del _c + gc.collect() + return output_dict + + def show_matrix(self, case_name, kpi): + """ + Creates a DataFrame with chosen output kpi, + for each XY combination + """ + matrix = pd.DataFrame(self.kpis[case_name][kpi]) + matrix.columns.name = self.x_param + matrix.index.name = self.y_param + return matrix + + +class ScenarioAnalysis(SensitivityAnalysis): + def __init__(self, c, s, routine, params_dict, labels, output_kpis): + self.labels = labels + self.configs = self._generate_configs(c, params_dict, labels) + output_dict = self._prepare_output_dict(s.cases, output_kpis) + self.kpis = self._run_sensitivities(s, routine, output_kpis, output_dict) + + def _generate_configs(self, c, params_dict, labels): + configs = {} + for i, label in enumerate(labels): + _c = deepcopy(c) + for param, values in params_dict.items(): + setattr(_c, param, values[i]) + configs[label] = _c + return configs + + +class TornadoChart: + """ + TODO: Absolute comparison instead of relative + """ + + def __init__(self, c, s, routine, case, tornado_vars, output_kpis): + self.case = case + self.kpis = self._run_sensitivities( + c, s, routine, case, tornado_vars, output_kpis + ) + + def _run_sensitivities(self, c, s, routine, case, tornado_vars, output_kpis): + labels = ["Low", "Medium", "High"] + outputs = {kpi: pd.DataFrame(index=labels) for kpi in output_kpis} + + for param, values in tornado_vars.items(): + sens = SensitivityAnalysis(c, s, routine, param, values, output_kpis) + + for kpi in output_kpis: + output = sens.single_kpi_overview(kpi, case_names=[case.name])[ + case.name + ] + output.index = labels + outputs[kpi][" ".join((param, str(values)))] = output + + for kpi in output_kpis: + base_performance = deepcopy(outputs[kpi].loc["Medium", :]) + for scen in labels: + scen_performance = outputs[kpi].loc[scen, :] + relative_performance = (scen_performance / base_performance - 1) * 100 + outputs[kpi].loc[scen, :] = relative_performance + + outputs[kpi] = outputs[kpi].round(1) + outputs[kpi].sort_values(by="Low", axis=1, ascending=False, inplace=True) + return outputs + + def show_chart( + self, kpi, dimensions=(800, 680), title="Tornado Chart", sort_by="Low" + ): + outputs = self.kpis[kpi].sort_values(by=sort_by, axis=1, ascending=False) + traces = [] + colors = {"Low": recoyred, "High": recoygreen} + + for scenario in ["Low", "High"]: + trace = { + "type": "bar", + "x": outputs.loc[scenario, :].tolist(), + "y": outputs.columns, + "orientation": "h", + "name": scenario, + "marker": {"color": colors[scenario]}, + } + traces.append(trace) + + layout = { + "title": title, + "width": dimensions[0], + "height": dimensions[1], + "barmode": "relative", + "autosize": True, + "showlegend": True, + } + fig = Figure(data=traces, layout=layout) + fig.update_xaxes( + title_text=f"{kpi.upper()} % change compared to base scenario (Base {kpi.upper()} = {millify(getattr(self.case, kpi))})" + ) + return fig diff --git a/pyrecoy/pyrecoy/pyrecoy/styling.py b/pyrecoy/pyrecoy/pyrecoy/styling.py new file mode 100644 index 0000000..bc224cf --- /dev/null +++ b/pyrecoy/pyrecoy/pyrecoy/styling.py @@ -0,0 +1,47 @@ +from copy import deepcopy +from numbers import Number +import numpy as np + + +def num_formatting(val): + if np.isnan(val) or round(val, 0) == 0: + return "-" + else: + return f"{val:,.0f}" + + +def perc_formatting(val): + if np.isnan(val) or round(val, 0) == 0: + return "-" + else: + return f"{val:.1f}%" + + +def bc_formatting(val): + if not isinstance(val, Number): + return val + if np.isnan(val): + return "" + elif round(val, 2) == 0: + return "-" + else: + return f"{val:,.0f}" + + +def businesscase_formatter(df): + df_c = deepcopy(df) + + spp = df_c.loc["Simple Payback Period", "Year 0"] + spp_str = "N/A" if np.isnan(spp) else str(spp) + " years" + df_c.loc["Simple Payback Period", "Year 0"] = spp_str + + irr = df_c.loc["IRR (%)", "Year 0"] + if np.isnan(irr): + df_c.loc["IRR (%)", "Year 0"] = "N/A" + + df_c = df_c.applymap(bc_formatting) + + if not np.isnan(irr): + df_c.loc["IRR (%)", "Year 0"] += "%" + df_c.loc["WACC (%)", "Year 0"] += "%" + return df_c diff --git a/pyrecoy/pyrecoy/setup.py b/pyrecoy/pyrecoy/setup.py new file mode 100644 index 0000000..72b3202 --- /dev/null +++ b/pyrecoy/pyrecoy/setup.py @@ -0,0 +1,29 @@ +from setuptools import setup + +# to install run : pip install -e pyrecoy from directory + +setup( + name="pyrecoy", + version="0.1", + description="Private package containing utils for flexible power system modelling on energy markets.", + url="#", + author="mekremer", + author_email="kremer@recoy.com", + license="", + packages=["pyrecoy"], + install_requires=[ + "requests", + "pandas", + "numpy", + "entsoe-py", + "numpy-financial", + "scipy", + "plotly", + "tqdm", + "millify", + "bs4", + "xmltodict", + "openpyxl", + ], + zip_safe=False, +) diff --git a/pyrecoy/pyrecoy/templates/pyrecoy_template.ipynb b/pyrecoy/pyrecoy/templates/pyrecoy_template.ipynb new file mode 100644 index 0000000..7a43e3e --- /dev/null +++ b/pyrecoy/pyrecoy/templates/pyrecoy_template.ipynb @@ -0,0 +1,16965 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Demo of pyrecoy package\n", + "Recoy Modelling Package for Python" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Imports" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import cufflinks\n", + "from tqdm.notebook import tqdm\n", + "import numpy as np\n", + "\n", + "from pyrecoy.assets import Heatpump, Eboiler, GasBoiler, Battery\n", + "from pyrecoy.colors import *\n", + "from pyrecoy.converters import *\n", + "from pyrecoy.financial import calculate_eb_ode, get_tax_tables\n", + "from pyrecoy.framework import TimeFramework, CaseStudy\n", + "from pyrecoy.plotting import ebitda_bar_chart, npv_bar_chart\n", + "from pyrecoy.reports import CaseReport, ComparisonReport, BusinessCaseReport, SingleFigureComparison\n", + "\n", + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Model set-up" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Timeframework" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "time_fw = TimeFramework(start='2019-01-01', end='2019-12-31')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "datetime.datetime(2019, 1, 1, 0, 0)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "time_fw.start" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "datetime.datetime(2019, 12, 31, 0, 0)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "time_fw.end" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "365.0" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "time_fw.days" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Casestudies" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "baseline = CaseStudy(time_fw=time_fw, freq='1T', name='Baseline')\n", + "hpcase = CaseStudy(time_fw=time_fw, freq='1T', name='Optimisation', forecast='mipf')\n", + "\n", + "cases = CaseStudy.get_instances().values()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
datetime
2019-01-01 00:00:00+01:00
2019-01-01 00:01:00+01:00
2019-01-01 00:02:00+01:00
2019-01-01 00:03:00+01:00
2019-01-01 00:04:00+01:00
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: []\n", + "Index: [2019-01-01 00:00:00+01:00, 2019-01-01 00:01:00+01:00, 2019-01-01 00:02:00+01:00, 2019-01-01 00:03:00+01:00, 2019-01-01 00:04:00+01:00]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "baseline.data.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DAMPOSNEGRSForePosForeNeg
datetime
2019-01-01 00:00:00+01:0068.9234.8558.012.046.8352.70
2019-01-01 00:01:00+01:0068.9234.8558.012.032.1254.45
2019-01-01 00:02:00+01:0068.9234.8558.012.030.9748.64
2019-01-01 00:03:00+01:0068.9234.8558.012.051.1348.35
2019-01-01 00:04:00+01:0068.9234.8558.012.048.0452.01
\n", + "
" + ], + "text/plain": [ + " DAM POS NEG RS ForePos ForeNeg\n", + "datetime \n", + "2019-01-01 00:00:00+01:00 68.92 34.85 58.01 2.0 46.83 52.70\n", + "2019-01-01 00:01:00+01:00 68.92 34.85 58.01 2.0 32.12 54.45\n", + "2019-01-01 00:02:00+01:00 68.92 34.85 58.01 2.0 30.97 48.64\n", + "2019-01-01 00:03:00+01:00 68.92 34.85 58.01 2.0 51.13 48.35\n", + "2019-01-01 00:04:00+01:00 68.92 34.85 58.01 2.0 48.04 52.01" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hpcase.data.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Gas & CO2 prices" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "baseline.add_gasprices()\n", + "baseline.add_co2prices()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Gas prices (€/MWh)CO2 prices (€/ton)
datetime
2019-01-01 00:00:00+01:0022.3824.98
2019-01-01 00:01:00+01:0022.3824.98
2019-01-01 00:02:00+01:0022.3824.98
2019-01-01 00:03:00+01:0022.3824.98
2019-01-01 00:04:00+01:0022.3824.98
\n", + "
" + ], + "text/plain": [ + " Gas prices (€/MWh) CO2 prices (€/ton)\n", + "datetime \n", + "2019-01-01 00:00:00+01:00 22.38 24.98\n", + "2019-01-01 00:01:00+01:00 22.38 24.98\n", + "2019-01-01 00:02:00+01:00 22.38 24.98\n", + "2019-01-01 00:03:00+01:00 22.38 24.98\n", + "2019-01-01 00:04:00+01:00 22.38 24.98" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "baseline.data.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Heat demand" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "for case in cases:\n", + " case.data['Heat demand'] = 5" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Gas prices (€/MWh)CO2 prices (€/ton)Heat demand
datetime
2019-01-01 00:00:00+01:0022.3824.985
2019-01-01 00:01:00+01:0022.3824.985
2019-01-01 00:02:00+01:0022.3824.985
2019-01-01 00:03:00+01:0022.3824.985
2019-01-01 00:04:00+01:0022.3824.985
\n", + "
" + ], + "text/plain": [ + " Gas prices (€/MWh) CO2 prices (€/ton) Heat demand\n", + "datetime \n", + "2019-01-01 00:00:00+01:00 22.38 24.98 5\n", + "2019-01-01 00:01:00+01:00 22.38 24.98 5\n", + "2019-01-01 00:02:00+01:00 22.38 24.98 5\n", + "2019-01-01 00:03:00+01:00 22.38 24.98 5\n", + "2019-01-01 00:04:00+01:00 22.38 24.98 5" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "baseline.data.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DAMPOSNEGRSForePosForeNegHeat demand
datetime
2019-01-01 00:00:00+01:0068.9234.8558.012.046.8352.705
2019-01-01 00:01:00+01:0068.9234.8558.012.032.1254.455
2019-01-01 00:02:00+01:0068.9234.8558.012.030.9748.645
2019-01-01 00:03:00+01:0068.9234.8558.012.051.1348.355
2019-01-01 00:04:00+01:0068.9234.8558.012.048.0452.015
\n", + "
" + ], + "text/plain": [ + " DAM POS NEG RS ForePos ForeNeg \\\n", + "datetime \n", + "2019-01-01 00:00:00+01:00 68.92 34.85 58.01 2.0 46.83 52.70 \n", + "2019-01-01 00:01:00+01:00 68.92 34.85 58.01 2.0 32.12 54.45 \n", + "2019-01-01 00:02:00+01:00 68.92 34.85 58.01 2.0 30.97 48.64 \n", + "2019-01-01 00:03:00+01:00 68.92 34.85 58.01 2.0 51.13 48.35 \n", + "2019-01-01 00:04:00+01:00 68.92 34.85 58.01 2.0 48.04 52.01 \n", + "\n", + " Heat demand \n", + "datetime \n", + "2019-01-01 00:00:00+01:00 5 \n", + "2019-01-01 00:01:00+01:00 5 \n", + "2019-01-01 00:02:00+01:00 5 \n", + "2019-01-01 00:03:00+01:00 5 \n", + "2019-01-01 00:04:00+01:00 5 " + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hpcase.data.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Assets" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Heatpump" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "heatpump = Heatpump(\n", + " name='Heatpump',\n", + " max_th_power=5,\n", + " min_th_power=0,\n", + " cop_curve=3.5\n", + ")\n", + "\n", + "heatpump.set_financials(capex=1_000_000, opex=10_000, devex=20_000, lifetime=25)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Heatpump(name='Heatpump', max_thermal_power=5, cop_curve=3.5, min_th_power=0)" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "heatpump" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Eboiler" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "eboiler = Eboiler(name='Eboiler', min_power=-6, max_power=0)\n", + "eboiler.set_financials(capex=200_000, opex=2_000, devex=10_000, lifetime=25)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Gasboiler" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "gasboiler = GasBoiler(\n", + " name='Gasboiler',\n", + " max_th_output=5,\n", + " efficiency=0.9\n", + ")\n", + "\n", + "gasboiler.set_financials(capex=0, opex=20_000, devex=0, lifetime=25)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Battery" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "battery = Battery(\n", + " name='Battery', \n", + " rated_power=2, \n", + " rated_capacity=2, \n", + " roundtrip_eff=0.9, \n", + " min_soc=0.1,\n", + " max_soc=0.9, \n", + " soc_at_start=0.5\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.5" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "battery.get_soc()" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "battery.set_freq('15T')" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\users\\mekre\\onedrive - recoy\\work\\code\\python\\_packages\\pyrecoy\\pyrecoy\\assets.py:57: UserWarning:\n", + "\n", + "Chosen Asset load for Battery is out of range. Should be between -2 and 2. Function will return boundary load level for now.\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "-2.0" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "battery.charge(3)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.725" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "battery.get_soc()" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1.45" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "battery.chargelevel" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1.5555555555555558" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "battery.charge(2)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.9" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "battery.get_soc()" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "battery.charge(2)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2.0" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "battery.discharge(2)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.65" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "battery.get_soc()" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2.0" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "battery.discharge(2)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2.0" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "battery.discharge(2)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.40000000000000013" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "battery.discharge(2)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.1" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "battery.get_soc()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Assign assets to casestudies" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "#add type annotation\n", + "baseline.add_asset(gasboiler)\n", + "hpcase.add_asset(heatpump)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Optimization" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [], + "source": [ + "# make getting asset from casestudy more readable\n", + "def simulation(case):\n", + " asset = case.get_assets()[0]\n", + " demand = case.data['Heat demand'].to_list()\n", + " minutes = range(len(case.data))\n", + " output_MW = [0] * len(case.data)\n", + " input_MW = [0] * len(case.data)\n", + " \n", + " for m in minutes:\n", + " output_MW[m], input_MW[m] = asset.set_heat_output(demand[m])\n", + " case.data['output_MW'] = np.array(output_MW)\n", + " case.data['input_MW'] = np.array(input_MW)\n", + " \n", + " for col in case.data.columns:\n", + " if col.endswith('MW'):\n", + " case.data[col + 'h'] = case.data[col] / 60" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [], + "source": [ + "baseline.assign_algorithm(simulation)\n", + "hpcase.assign_algorithm(simulation)" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wall time: 682 ms\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Gas prices (€/MWh)CO2 prices (€/ton)Heat demandoutput_MWinput_MWoutput_MWhinput_MWh
datetime
2019-01-01 00:00:00+01:0022.3824.9855-5.5555560.083333-0.092593
2019-01-01 00:01:00+01:0022.3824.9855-5.5555560.083333-0.092593
2019-01-01 00:02:00+01:0022.3824.9855-5.5555560.083333-0.092593
2019-01-01 00:03:00+01:0022.3824.9855-5.5555560.083333-0.092593
2019-01-01 00:04:00+01:0022.3824.9855-5.5555560.083333-0.092593
\n", + "
" + ], + "text/plain": [ + " Gas prices (€/MWh) CO2 prices (€/ton) \\\n", + "datetime \n", + "2019-01-01 00:00:00+01:00 22.38 24.98 \n", + "2019-01-01 00:01:00+01:00 22.38 24.98 \n", + "2019-01-01 00:02:00+01:00 22.38 24.98 \n", + "2019-01-01 00:03:00+01:00 22.38 24.98 \n", + "2019-01-01 00:04:00+01:00 22.38 24.98 \n", + "\n", + " Heat demand output_MW input_MW output_MWh \\\n", + "datetime \n", + "2019-01-01 00:00:00+01:00 5 5 -5.555556 0.083333 \n", + "2019-01-01 00:01:00+01:00 5 5 -5.555556 0.083333 \n", + "2019-01-01 00:02:00+01:00 5 5 -5.555556 0.083333 \n", + "2019-01-01 00:03:00+01:00 5 5 -5.555556 0.083333 \n", + "2019-01-01 00:04:00+01:00 5 5 -5.555556 0.083333 \n", + "\n", + " input_MWh \n", + "datetime \n", + "2019-01-01 00:00:00+01:00 -0.092593 \n", + "2019-01-01 00:01:00+01:00 -0.092593 \n", + "2019-01-01 00:02:00+01:00 -0.092593 \n", + "2019-01-01 00:03:00+01:00 -0.092593 \n", + "2019-01-01 00:04:00+01:00 -0.092593 " + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time baseline.run()\n", + "baseline.data.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "linkText": "Export to plot.ly", + "plotlyServerURL": "https://plot.ly", + "showLink": true + }, + "data": [ + { + "line": { + "color": "rgba(255, 153, 51, 1.0)", + "dash": "solid", + "shape": "linear", + "width": 1.3 + }, + "mode": "lines", + "name": "input_MW", + "text": "", + "type": "scatter", + "x": [ + "2019-01-01 00:00:00+01:00", + "2019-01-01 00:01:00+01:00", + "2019-01-01 00:02:00+01:00", + "2019-01-01 00:03:00+01:00", + "2019-01-01 00:04:00+01:00", + "2019-01-01 00:05:00+01:00", + "2019-01-01 00:06:00+01:00", + "2019-01-01 00:07:00+01:00", + "2019-01-01 00:08:00+01:00", + "2019-01-01 00:09:00+01:00", + "2019-01-01 00:10:00+01:00", + "2019-01-01 00:11:00+01:00", + "2019-01-01 00:12:00+01:00", + "2019-01-01 00:13:00+01:00", + "2019-01-01 00:14:00+01:00", + "2019-01-01 00:15:00+01:00", + "2019-01-01 00:16:00+01:00", + "2019-01-01 00:17:00+01:00", + "2019-01-01 00:18:00+01:00", + "2019-01-01 00:19:00+01:00", + "2019-01-01 00:20:00+01:00", + "2019-01-01 00:21:00+01:00", + "2019-01-01 00:22:00+01:00", + "2019-01-01 00:23:00+01:00", + "2019-01-01 00:24:00+01:00", + "2019-01-01 00:25:00+01:00", + "2019-01-01 00:26:00+01:00", + "2019-01-01 00:27:00+01:00", + "2019-01-01 00:28:00+01:00", + "2019-01-01 00:29:00+01:00", + "2019-01-01 00:30:00+01:00", + "2019-01-01 00:31:00+01:00", + "2019-01-01 00:32:00+01:00", + "2019-01-01 00:33:00+01:00", + "2019-01-01 00:34:00+01:00", + "2019-01-01 00:35:00+01:00", + "2019-01-01 00:36:00+01:00", + "2019-01-01 00:37:00+01:00", + "2019-01-01 00:38:00+01:00", + "2019-01-01 00:39:00+01:00", + "2019-01-01 00:40:00+01:00", + "2019-01-01 00:41:00+01:00", + "2019-01-01 00:42:00+01:00", + "2019-01-01 00:43:00+01:00", + "2019-01-01 00:44:00+01:00", + "2019-01-01 00:45:00+01:00", + "2019-01-01 00:46:00+01:00", + "2019-01-01 00:47:00+01:00", + "2019-01-01 00:48:00+01:00", + "2019-01-01 00:49:00+01:00", + "2019-01-01 00:50:00+01:00", + "2019-01-01 00:51:00+01:00", + "2019-01-01 00:52:00+01:00", + "2019-01-01 00:53:00+01:00", + "2019-01-01 00:54:00+01:00", + "2019-01-01 00:55:00+01:00", + "2019-01-01 00:56:00+01:00", + "2019-01-01 00:57:00+01:00", + "2019-01-01 00:58:00+01:00", + "2019-01-01 00:59:00+01:00", + "2019-01-01 01:00:00+01:00", + "2019-01-01 01:01:00+01:00", + "2019-01-01 01:02:00+01:00", + "2019-01-01 01:03:00+01:00", + "2019-01-01 01:04:00+01:00", + "2019-01-01 01:05:00+01:00", + "2019-01-01 01:06:00+01:00", + "2019-01-01 01:07:00+01:00", + "2019-01-01 01:08:00+01:00", + "2019-01-01 01:09:00+01:00", + "2019-01-01 01:10:00+01:00", + "2019-01-01 01:11:00+01:00", + "2019-01-01 01:12:00+01:00", + "2019-01-01 01:13:00+01:00", + "2019-01-01 01:14:00+01:00", + "2019-01-01 01:15:00+01:00", + "2019-01-01 01:16:00+01:00", + "2019-01-01 01:17:00+01:00", + "2019-01-01 01:18:00+01:00", + "2019-01-01 01:19:00+01:00", + "2019-01-01 01:20:00+01:00", + "2019-01-01 01:21:00+01:00", + "2019-01-01 01:22:00+01:00", + "2019-01-01 01:23:00+01:00", + "2019-01-01 01:24:00+01:00", + "2019-01-01 01:25:00+01:00", + "2019-01-01 01:26:00+01:00", + "2019-01-01 01:27:00+01:00", + "2019-01-01 01:28:00+01:00", + "2019-01-01 01:29:00+01:00", + "2019-01-01 01:30:00+01:00", + "2019-01-01 01:31:00+01:00", + "2019-01-01 01:32:00+01:00", + "2019-01-01 01:33:00+01:00", + "2019-01-01 01:34:00+01:00", + "2019-01-01 01:35:00+01:00", + "2019-01-01 01:36:00+01:00", + "2019-01-01 01:37:00+01:00", + "2019-01-01 01:38:00+01:00", + "2019-01-01 01:39:00+01:00", + "2019-01-01 01:40:00+01:00", + "2019-01-01 01:41:00+01:00", + "2019-01-01 01:42:00+01:00", + "2019-01-01 01:43:00+01:00", + "2019-01-01 01:44:00+01:00", + "2019-01-01 01:45:00+01:00", + "2019-01-01 01:46:00+01:00", + "2019-01-01 01:47:00+01:00", + "2019-01-01 01:48:00+01:00", + "2019-01-01 01:49:00+01:00", + "2019-01-01 01:50:00+01:00", + "2019-01-01 01:51:00+01:00", + "2019-01-01 01:52:00+01:00", + "2019-01-01 01:53:00+01:00", + "2019-01-01 01:54:00+01:00", + "2019-01-01 01:55:00+01:00", + "2019-01-01 01:56:00+01:00", + "2019-01-01 01:57:00+01:00", + "2019-01-01 01:58:00+01:00", + "2019-01-01 01:59:00+01:00", + "2019-01-01 02:00:00+01:00", + "2019-01-01 02:01:00+01:00", + "2019-01-01 02:02:00+01:00", + "2019-01-01 02:03:00+01:00", + "2019-01-01 02:04:00+01:00", + "2019-01-01 02:05:00+01:00", + "2019-01-01 02:06:00+01:00", + "2019-01-01 02:07:00+01:00", + "2019-01-01 02:08:00+01:00", + "2019-01-01 02:09:00+01:00", + "2019-01-01 02:10:00+01:00", + "2019-01-01 02:11:00+01:00", + "2019-01-01 02:12:00+01:00", + "2019-01-01 02:13:00+01:00", + "2019-01-01 02:14:00+01:00", + "2019-01-01 02:15:00+01:00", + "2019-01-01 02:16:00+01:00", + "2019-01-01 02:17:00+01:00", + "2019-01-01 02:18:00+01:00", + "2019-01-01 02:19:00+01:00", + "2019-01-01 02:20:00+01:00", + "2019-01-01 02:21:00+01:00", + "2019-01-01 02:22:00+01:00", + "2019-01-01 02:23:00+01:00", + "2019-01-01 02:24:00+01:00", + "2019-01-01 02:25:00+01:00", + "2019-01-01 02:26:00+01:00", + "2019-01-01 02:27:00+01:00", + "2019-01-01 02:28:00+01:00", + "2019-01-01 02:29:00+01:00", + "2019-01-01 02:30:00+01:00", + "2019-01-01 02:31:00+01:00", + "2019-01-01 02:32:00+01:00", + "2019-01-01 02:33:00+01:00", + "2019-01-01 02:34:00+01:00", + "2019-01-01 02:35:00+01:00", + "2019-01-01 02:36:00+01:00", + "2019-01-01 02:37:00+01:00", + "2019-01-01 02:38:00+01:00", + "2019-01-01 02:39:00+01:00", + "2019-01-01 02:40:00+01:00", + "2019-01-01 02:41:00+01:00", + "2019-01-01 02:42:00+01:00", + "2019-01-01 02:43:00+01:00", + "2019-01-01 02:44:00+01:00", + "2019-01-01 02:45:00+01:00", + "2019-01-01 02:46:00+01:00", + "2019-01-01 02:47:00+01:00", + "2019-01-01 02:48:00+01:00", + "2019-01-01 02:49:00+01:00", + "2019-01-01 02:50:00+01:00", + "2019-01-01 02:51:00+01:00", + "2019-01-01 02:52:00+01:00", + "2019-01-01 02:53:00+01:00", + "2019-01-01 02:54:00+01:00", + "2019-01-01 02:55:00+01:00", + "2019-01-01 02:56:00+01:00", + "2019-01-01 02:57:00+01:00", + "2019-01-01 02:58:00+01:00", + "2019-01-01 02:59:00+01:00", + "2019-01-01 03:00:00+01:00", + "2019-01-01 03:01:00+01:00", + "2019-01-01 03:02:00+01:00", + "2019-01-01 03:03:00+01:00", + "2019-01-01 03:04:00+01:00", + "2019-01-01 03:05:00+01:00", + "2019-01-01 03:06:00+01:00", + "2019-01-01 03:07:00+01:00", + "2019-01-01 03:08:00+01:00", + "2019-01-01 03:09:00+01:00", + "2019-01-01 03:10:00+01:00", + "2019-01-01 03:11:00+01:00", + "2019-01-01 03:12:00+01:00", + "2019-01-01 03:13:00+01:00", + "2019-01-01 03:14:00+01:00", + "2019-01-01 03:15:00+01:00", + "2019-01-01 03:16:00+01:00", + "2019-01-01 03:17:00+01:00", + "2019-01-01 03:18:00+01:00", + "2019-01-01 03:19:00+01:00", + "2019-01-01 03:20:00+01:00", + "2019-01-01 03:21:00+01:00", + "2019-01-01 03:22:00+01:00", + "2019-01-01 03:23:00+01:00", + "2019-01-01 03:24:00+01:00", + "2019-01-01 03:25:00+01:00", + "2019-01-01 03:26:00+01:00", + "2019-01-01 03:27:00+01:00", + "2019-01-01 03:28:00+01:00", + "2019-01-01 03:29:00+01:00", + "2019-01-01 03:30:00+01:00", + "2019-01-01 03:31:00+01:00", + "2019-01-01 03:32:00+01:00", + "2019-01-01 03:33:00+01:00", + "2019-01-01 03:34:00+01:00", + "2019-01-01 03:35:00+01:00", + "2019-01-01 03:36:00+01:00", + "2019-01-01 03:37:00+01:00", + "2019-01-01 03:38:00+01:00", + "2019-01-01 03:39:00+01:00", + "2019-01-01 03:40:00+01:00", + "2019-01-01 03:41:00+01:00", + "2019-01-01 03:42:00+01:00", + "2019-01-01 03:43:00+01:00", + "2019-01-01 03:44:00+01:00", + "2019-01-01 03:45:00+01:00", + "2019-01-01 03:46:00+01:00", + "2019-01-01 03:47:00+01:00", + "2019-01-01 03:48:00+01:00", + "2019-01-01 03:49:00+01:00", + "2019-01-01 03:50:00+01:00", + "2019-01-01 03:51:00+01:00", + "2019-01-01 03:52:00+01:00", + "2019-01-01 03:53:00+01:00", + "2019-01-01 03:54:00+01:00", + "2019-01-01 03:55:00+01:00", + "2019-01-01 03:56:00+01:00", + "2019-01-01 03:57:00+01:00", + "2019-01-01 03:58:00+01:00", + "2019-01-01 03:59:00+01:00", + "2019-01-01 04:00:00+01:00", + "2019-01-01 04:01:00+01:00", + "2019-01-01 04:02:00+01:00", + "2019-01-01 04:03:00+01:00", + "2019-01-01 04:04:00+01:00", + "2019-01-01 04:05:00+01:00", + "2019-01-01 04:06:00+01:00", + "2019-01-01 04:07:00+01:00", + "2019-01-01 04:08:00+01:00", + "2019-01-01 04:09:00+01:00", + "2019-01-01 04:10:00+01:00", + "2019-01-01 04:11:00+01:00", + "2019-01-01 04:12:00+01:00", + "2019-01-01 04:13:00+01:00", + "2019-01-01 04:14:00+01:00", + "2019-01-01 04:15:00+01:00", + "2019-01-01 04:16:00+01:00", + "2019-01-01 04:17:00+01:00", + "2019-01-01 04:18:00+01:00", + "2019-01-01 04:19:00+01:00", + "2019-01-01 04:20:00+01:00", + "2019-01-01 04:21:00+01:00", + "2019-01-01 04:22:00+01:00", + "2019-01-01 04:23:00+01:00", + "2019-01-01 04:24:00+01:00", + "2019-01-01 04:25:00+01:00", + "2019-01-01 04:26:00+01:00", + "2019-01-01 04:27:00+01:00", + "2019-01-01 04:28:00+01:00", + "2019-01-01 04:29:00+01:00", + "2019-01-01 04:30:00+01:00", + "2019-01-01 04:31:00+01:00", + "2019-01-01 04:32:00+01:00", + "2019-01-01 04:33:00+01:00", + "2019-01-01 04:34:00+01:00", + "2019-01-01 04:35:00+01:00", + "2019-01-01 04:36:00+01:00", + "2019-01-01 04:37:00+01:00", + "2019-01-01 04:38:00+01:00", + "2019-01-01 04:39:00+01:00", + "2019-01-01 04:40:00+01:00", + "2019-01-01 04:41:00+01:00", + "2019-01-01 04:42:00+01:00", + "2019-01-01 04:43:00+01:00", + "2019-01-01 04:44:00+01:00", + "2019-01-01 04:45:00+01:00", + "2019-01-01 04:46:00+01:00", + "2019-01-01 04:47:00+01:00", + "2019-01-01 04:48:00+01:00", + "2019-01-01 04:49:00+01:00", + "2019-01-01 04:50:00+01:00", + "2019-01-01 04:51:00+01:00", + "2019-01-01 04:52:00+01:00", + "2019-01-01 04:53:00+01:00", + "2019-01-01 04:54:00+01:00", + "2019-01-01 04:55:00+01:00", + "2019-01-01 04:56:00+01:00", + "2019-01-01 04:57:00+01:00", + "2019-01-01 04:58:00+01:00", + "2019-01-01 04:59:00+01:00", + "2019-01-01 05:00:00+01:00", + "2019-01-01 05:01:00+01:00", + "2019-01-01 05:02:00+01:00", + "2019-01-01 05:03:00+01:00", + "2019-01-01 05:04:00+01:00", + "2019-01-01 05:05:00+01:00", + "2019-01-01 05:06:00+01:00", + "2019-01-01 05:07:00+01:00", + "2019-01-01 05:08:00+01:00", + "2019-01-01 05:09:00+01:00", + "2019-01-01 05:10:00+01:00", + "2019-01-01 05:11:00+01:00", + "2019-01-01 05:12:00+01:00", + "2019-01-01 05:13:00+01:00", + "2019-01-01 05:14:00+01:00", + "2019-01-01 05:15:00+01:00", + "2019-01-01 05:16:00+01:00", + "2019-01-01 05:17:00+01:00", + "2019-01-01 05:18:00+01:00", + "2019-01-01 05:19:00+01:00", + "2019-01-01 05:20:00+01:00", + "2019-01-01 05:21:00+01:00", + "2019-01-01 05:22:00+01:00", + "2019-01-01 05:23:00+01:00", + "2019-01-01 05:24:00+01:00", + "2019-01-01 05:25:00+01:00", + "2019-01-01 05:26:00+01:00", + "2019-01-01 05:27:00+01:00", + "2019-01-01 05:28:00+01:00", + "2019-01-01 05:29:00+01:00", + "2019-01-01 05:30:00+01:00", + "2019-01-01 05:31:00+01:00", + "2019-01-01 05:32:00+01:00", + "2019-01-01 05:33:00+01:00", + "2019-01-01 05:34:00+01:00", + "2019-01-01 05:35:00+01:00", + "2019-01-01 05:36:00+01:00", + "2019-01-01 05:37:00+01:00", + "2019-01-01 05:38:00+01:00", + "2019-01-01 05:39:00+01:00", + "2019-01-01 05:40:00+01:00", + "2019-01-01 05:41:00+01:00", + "2019-01-01 05:42:00+01:00", + "2019-01-01 05:43:00+01:00", + "2019-01-01 05:44:00+01:00", + "2019-01-01 05:45:00+01:00", + "2019-01-01 05:46:00+01:00", + "2019-01-01 05:47:00+01:00", + "2019-01-01 05:48:00+01:00", + "2019-01-01 05:49:00+01:00", + "2019-01-01 05:50:00+01:00", + "2019-01-01 05:51:00+01:00", + "2019-01-01 05:52:00+01:00", + "2019-01-01 05:53:00+01:00", + "2019-01-01 05:54:00+01:00", + "2019-01-01 05:55:00+01:00", + "2019-01-01 05:56:00+01:00", + "2019-01-01 05:57:00+01:00", + "2019-01-01 05:58:00+01:00", + "2019-01-01 05:59:00+01:00", + "2019-01-01 06:00:00+01:00", + "2019-01-01 06:01:00+01:00", + "2019-01-01 06:02:00+01:00", + "2019-01-01 06:03:00+01:00", + "2019-01-01 06:04:00+01:00", + "2019-01-01 06:05:00+01:00", + "2019-01-01 06:06:00+01:00", + "2019-01-01 06:07:00+01:00", + "2019-01-01 06:08:00+01:00", + "2019-01-01 06:09:00+01:00", + "2019-01-01 06:10:00+01:00", + "2019-01-01 06:11:00+01:00", + "2019-01-01 06:12:00+01:00", + "2019-01-01 06:13:00+01:00", + "2019-01-01 06:14:00+01:00", + "2019-01-01 06:15:00+01:00", + "2019-01-01 06:16:00+01:00", + "2019-01-01 06:17:00+01:00", + "2019-01-01 06:18:00+01:00", + "2019-01-01 06:19:00+01:00", + "2019-01-01 06:20:00+01:00", + "2019-01-01 06:21:00+01:00", + "2019-01-01 06:22:00+01:00", + "2019-01-01 06:23:00+01:00", + "2019-01-01 06:24:00+01:00", + "2019-01-01 06:25:00+01:00", + "2019-01-01 06:26:00+01:00", + "2019-01-01 06:27:00+01:00", + "2019-01-01 06:28:00+01:00", + "2019-01-01 06:29:00+01:00", + "2019-01-01 06:30:00+01:00", + "2019-01-01 06:31:00+01:00", + "2019-01-01 06:32:00+01:00", + "2019-01-01 06:33:00+01:00", + "2019-01-01 06:34:00+01:00", + "2019-01-01 06:35:00+01:00", + "2019-01-01 06:36:00+01:00", + "2019-01-01 06:37:00+01:00", + "2019-01-01 06:38:00+01:00", + "2019-01-01 06:39:00+01:00", + "2019-01-01 06:40:00+01:00", + "2019-01-01 06:41:00+01:00", + "2019-01-01 06:42:00+01:00", + "2019-01-01 06:43:00+01:00", + "2019-01-01 06:44:00+01:00", + "2019-01-01 06:45:00+01:00", + "2019-01-01 06:46:00+01:00", + "2019-01-01 06:47:00+01:00", + "2019-01-01 06:48:00+01:00", + "2019-01-01 06:49:00+01:00", + "2019-01-01 06:50:00+01:00", + "2019-01-01 06:51:00+01:00", + "2019-01-01 06:52:00+01:00", + "2019-01-01 06:53:00+01:00", + "2019-01-01 06:54:00+01:00", + "2019-01-01 06:55:00+01:00", + "2019-01-01 06:56:00+01:00", + "2019-01-01 06:57:00+01:00", + "2019-01-01 06:58:00+01:00", + "2019-01-01 06:59:00+01:00", + "2019-01-01 07:00:00+01:00", + "2019-01-01 07:01:00+01:00", + "2019-01-01 07:02:00+01:00", + "2019-01-01 07:03:00+01:00", + "2019-01-01 07:04:00+01:00", + "2019-01-01 07:05:00+01:00", + "2019-01-01 07:06:00+01:00", + "2019-01-01 07:07:00+01:00", + "2019-01-01 07:08:00+01:00", + "2019-01-01 07:09:00+01:00", + "2019-01-01 07:10:00+01:00", + "2019-01-01 07:11:00+01:00", + "2019-01-01 07:12:00+01:00", + "2019-01-01 07:13:00+01:00", + "2019-01-01 07:14:00+01:00", + "2019-01-01 07:15:00+01:00", + "2019-01-01 07:16:00+01:00", + "2019-01-01 07:17:00+01:00", + "2019-01-01 07:18:00+01:00", + "2019-01-01 07:19:00+01:00", + "2019-01-01 07:20:00+01:00", + "2019-01-01 07:21:00+01:00", + "2019-01-01 07:22:00+01:00", + "2019-01-01 07:23:00+01:00", + "2019-01-01 07:24:00+01:00", + "2019-01-01 07:25:00+01:00", + "2019-01-01 07:26:00+01:00", + "2019-01-01 07:27:00+01:00", + "2019-01-01 07:28:00+01:00", + "2019-01-01 07:29:00+01:00", + "2019-01-01 07:30:00+01:00", + "2019-01-01 07:31:00+01:00", + "2019-01-01 07:32:00+01:00", + "2019-01-01 07:33:00+01:00", + "2019-01-01 07:34:00+01:00", + "2019-01-01 07:35:00+01:00", + "2019-01-01 07:36:00+01:00", + "2019-01-01 07:37:00+01:00", + "2019-01-01 07:38:00+01:00", + "2019-01-01 07:39:00+01:00", + "2019-01-01 07:40:00+01:00", + "2019-01-01 07:41:00+01:00", + "2019-01-01 07:42:00+01:00", + "2019-01-01 07:43:00+01:00", + "2019-01-01 07:44:00+01:00", + "2019-01-01 07:45:00+01:00", + "2019-01-01 07:46:00+01:00", + "2019-01-01 07:47:00+01:00", + "2019-01-01 07:48:00+01:00", + "2019-01-01 07:49:00+01:00", + "2019-01-01 07:50:00+01:00", + "2019-01-01 07:51:00+01:00", + "2019-01-01 07:52:00+01:00", + "2019-01-01 07:53:00+01:00", + "2019-01-01 07:54:00+01:00", + "2019-01-01 07:55:00+01:00", + "2019-01-01 07:56:00+01:00", + "2019-01-01 07:57:00+01:00", + "2019-01-01 07:58:00+01:00", + "2019-01-01 07:59:00+01:00", + "2019-01-01 08:00:00+01:00", + "2019-01-01 08:01:00+01:00", + "2019-01-01 08:02:00+01:00", + "2019-01-01 08:03:00+01:00", + "2019-01-01 08:04:00+01:00", + "2019-01-01 08:05:00+01:00", + "2019-01-01 08:06:00+01:00", + "2019-01-01 08:07:00+01:00", + "2019-01-01 08:08:00+01:00", + "2019-01-01 08:09:00+01:00", + "2019-01-01 08:10:00+01:00", + "2019-01-01 08:11:00+01:00", + "2019-01-01 08:12:00+01:00", + "2019-01-01 08:13:00+01:00", + "2019-01-01 08:14:00+01:00", + "2019-01-01 08:15:00+01:00", + "2019-01-01 08:16:00+01:00", + "2019-01-01 08:17:00+01:00", + "2019-01-01 08:18:00+01:00", + "2019-01-01 08:19:00+01:00", + "2019-01-01 08:20:00+01:00", + "2019-01-01 08:21:00+01:00", + "2019-01-01 08:22:00+01:00", + "2019-01-01 08:23:00+01:00", + "2019-01-01 08:24:00+01:00", + "2019-01-01 08:25:00+01:00", + "2019-01-01 08:26:00+01:00", + "2019-01-01 08:27:00+01:00", + "2019-01-01 08:28:00+01:00", + "2019-01-01 08:29:00+01:00", + "2019-01-01 08:30:00+01:00", + "2019-01-01 08:31:00+01:00", + "2019-01-01 08:32:00+01:00", + "2019-01-01 08:33:00+01:00", + "2019-01-01 08:34:00+01:00", + "2019-01-01 08:35:00+01:00", + "2019-01-01 08:36:00+01:00", + "2019-01-01 08:37:00+01:00", + "2019-01-01 08:38:00+01:00", + "2019-01-01 08:39:00+01:00", + "2019-01-01 08:40:00+01:00", + "2019-01-01 08:41:00+01:00", + "2019-01-01 08:42:00+01:00", + "2019-01-01 08:43:00+01:00", + "2019-01-01 08:44:00+01:00", + "2019-01-01 08:45:00+01:00", + "2019-01-01 08:46:00+01:00", + "2019-01-01 08:47:00+01:00", + "2019-01-01 08:48:00+01:00", + "2019-01-01 08:49:00+01:00", + "2019-01-01 08:50:00+01:00", + "2019-01-01 08:51:00+01:00", + "2019-01-01 08:52:00+01:00", + "2019-01-01 08:53:00+01:00", + "2019-01-01 08:54:00+01:00", + "2019-01-01 08:55:00+01:00", + "2019-01-01 08:56:00+01:00", + "2019-01-01 08:57:00+01:00", + "2019-01-01 08:58:00+01:00", + "2019-01-01 08:59:00+01:00", + "2019-01-01 09:00:00+01:00", + "2019-01-01 09:01:00+01:00", + "2019-01-01 09:02:00+01:00", + "2019-01-01 09:03:00+01:00", + "2019-01-01 09:04:00+01:00", + "2019-01-01 09:05:00+01:00", + "2019-01-01 09:06:00+01:00", + "2019-01-01 09:07:00+01:00", + "2019-01-01 09:08:00+01:00", + "2019-01-01 09:09:00+01:00", + "2019-01-01 09:10:00+01:00", + "2019-01-01 09:11:00+01:00", + "2019-01-01 09:12:00+01:00", + "2019-01-01 09:13:00+01:00", + "2019-01-01 09:14:00+01:00", + "2019-01-01 09:15:00+01:00", + "2019-01-01 09:16:00+01:00", + "2019-01-01 09:17:00+01:00", + "2019-01-01 09:18:00+01:00", + "2019-01-01 09:19:00+01:00", + "2019-01-01 09:20:00+01:00", + "2019-01-01 09:21:00+01:00", + "2019-01-01 09:22:00+01:00", + "2019-01-01 09:23:00+01:00", + "2019-01-01 09:24:00+01:00", + "2019-01-01 09:25:00+01:00", + "2019-01-01 09:26:00+01:00", + "2019-01-01 09:27:00+01:00", + "2019-01-01 09:28:00+01:00", + "2019-01-01 09:29:00+01:00", + "2019-01-01 09:30:00+01:00", + "2019-01-01 09:31:00+01:00", + "2019-01-01 09:32:00+01:00", + "2019-01-01 09:33:00+01:00", + "2019-01-01 09:34:00+01:00", + "2019-01-01 09:35:00+01:00", + "2019-01-01 09:36:00+01:00", + "2019-01-01 09:37:00+01:00", + "2019-01-01 09:38:00+01:00", + "2019-01-01 09:39:00+01:00", + "2019-01-01 09:40:00+01:00", + "2019-01-01 09:41:00+01:00", + "2019-01-01 09:42:00+01:00", + "2019-01-01 09:43:00+01:00", + "2019-01-01 09:44:00+01:00", + "2019-01-01 09:45:00+01:00", + "2019-01-01 09:46:00+01:00", + "2019-01-01 09:47:00+01:00", + "2019-01-01 09:48:00+01:00", + "2019-01-01 09:49:00+01:00", + "2019-01-01 09:50:00+01:00", + "2019-01-01 09:51:00+01:00", + "2019-01-01 09:52:00+01:00", + "2019-01-01 09:53:00+01:00", + "2019-01-01 09:54:00+01:00", + "2019-01-01 09:55:00+01:00", + "2019-01-01 09:56:00+01:00", + "2019-01-01 09:57:00+01:00", + "2019-01-01 09:58:00+01:00", + "2019-01-01 09:59:00+01:00", + "2019-01-01 10:00:00+01:00", + "2019-01-01 10:01:00+01:00", + "2019-01-01 10:02:00+01:00", + "2019-01-01 10:03:00+01:00", + "2019-01-01 10:04:00+01:00", + "2019-01-01 10:05:00+01:00", + "2019-01-01 10:06:00+01:00", + "2019-01-01 10:07:00+01:00", + "2019-01-01 10:08:00+01:00", + "2019-01-01 10:09:00+01:00", + "2019-01-01 10:10:00+01:00", + "2019-01-01 10:11:00+01:00", + "2019-01-01 10:12:00+01:00", + "2019-01-01 10:13:00+01:00", + "2019-01-01 10:14:00+01:00", + "2019-01-01 10:15:00+01:00", + "2019-01-01 10:16:00+01:00", + "2019-01-01 10:17:00+01:00", + "2019-01-01 10:18:00+01:00", + "2019-01-01 10:19:00+01:00", + "2019-01-01 10:20:00+01:00", + "2019-01-01 10:21:00+01:00", + "2019-01-01 10:22:00+01:00", + "2019-01-01 10:23:00+01:00", + "2019-01-01 10:24:00+01:00", + "2019-01-01 10:25:00+01:00", + "2019-01-01 10:26:00+01:00", + "2019-01-01 10:27:00+01:00", + "2019-01-01 10:28:00+01:00", + "2019-01-01 10:29:00+01:00", + "2019-01-01 10:30:00+01:00", + "2019-01-01 10:31:00+01:00", + "2019-01-01 10:32:00+01:00", + "2019-01-01 10:33:00+01:00", + "2019-01-01 10:34:00+01:00", + "2019-01-01 10:35:00+01:00", + "2019-01-01 10:36:00+01:00", + "2019-01-01 10:37:00+01:00", + "2019-01-01 10:38:00+01:00", + "2019-01-01 10:39:00+01:00", + "2019-01-01 10:40:00+01:00", + "2019-01-01 10:41:00+01:00", + "2019-01-01 10:42:00+01:00", + "2019-01-01 10:43:00+01:00", + "2019-01-01 10:44:00+01:00", + "2019-01-01 10:45:00+01:00", + "2019-01-01 10:46:00+01:00", + "2019-01-01 10:47:00+01:00", + "2019-01-01 10:48:00+01:00", + "2019-01-01 10:49:00+01:00", + "2019-01-01 10:50:00+01:00", + "2019-01-01 10:51:00+01:00", + "2019-01-01 10:52:00+01:00", + "2019-01-01 10:53:00+01:00", + "2019-01-01 10:54:00+01:00", + "2019-01-01 10:55:00+01:00", + "2019-01-01 10:56:00+01:00", + "2019-01-01 10:57:00+01:00", + "2019-01-01 10:58:00+01:00", + "2019-01-01 10:59:00+01:00", + "2019-01-01 11:00:00+01:00", + "2019-01-01 11:01:00+01:00", + "2019-01-01 11:02:00+01:00", + "2019-01-01 11:03:00+01:00", + "2019-01-01 11:04:00+01:00", + "2019-01-01 11:05:00+01:00", + "2019-01-01 11:06:00+01:00", + "2019-01-01 11:07:00+01:00", + "2019-01-01 11:08:00+01:00", + "2019-01-01 11:09:00+01:00", + "2019-01-01 11:10:00+01:00", + "2019-01-01 11:11:00+01:00", + "2019-01-01 11:12:00+01:00", + "2019-01-01 11:13:00+01:00", + "2019-01-01 11:14:00+01:00", + "2019-01-01 11:15:00+01:00", + "2019-01-01 11:16:00+01:00", + "2019-01-01 11:17:00+01:00", + "2019-01-01 11:18:00+01:00", + "2019-01-01 11:19:00+01:00", + "2019-01-01 11:20:00+01:00", + "2019-01-01 11:21:00+01:00", + "2019-01-01 11:22:00+01:00", + "2019-01-01 11:23:00+01:00", + "2019-01-01 11:24:00+01:00", + "2019-01-01 11:25:00+01:00", + "2019-01-01 11:26:00+01:00", + "2019-01-01 11:27:00+01:00", + "2019-01-01 11:28:00+01:00", + "2019-01-01 11:29:00+01:00", + "2019-01-01 11:30:00+01:00", + "2019-01-01 11:31:00+01:00", + "2019-01-01 11:32:00+01:00", + "2019-01-01 11:33:00+01:00", + "2019-01-01 11:34:00+01:00", + "2019-01-01 11:35:00+01:00", + "2019-01-01 11:36:00+01:00", + "2019-01-01 11:37:00+01:00", + "2019-01-01 11:38:00+01:00", + "2019-01-01 11:39:00+01:00", + "2019-01-01 11:40:00+01:00", + "2019-01-01 11:41:00+01:00", + "2019-01-01 11:42:00+01:00", + "2019-01-01 11:43:00+01:00", + "2019-01-01 11:44:00+01:00", + "2019-01-01 11:45:00+01:00", + "2019-01-01 11:46:00+01:00", + "2019-01-01 11:47:00+01:00", + "2019-01-01 11:48:00+01:00", + "2019-01-01 11:49:00+01:00", + "2019-01-01 11:50:00+01:00", + "2019-01-01 11:51:00+01:00", + "2019-01-01 11:52:00+01:00", + "2019-01-01 11:53:00+01:00", + "2019-01-01 11:54:00+01:00", + "2019-01-01 11:55:00+01:00", + "2019-01-01 11:56:00+01:00", + "2019-01-01 11:57:00+01:00", + "2019-01-01 11:58:00+01:00", + "2019-01-01 11:59:00+01:00", + "2019-01-01 12:00:00+01:00", + "2019-01-01 12:01:00+01:00", + "2019-01-01 12:02:00+01:00", + "2019-01-01 12:03:00+01:00", + "2019-01-01 12:04:00+01:00", + "2019-01-01 12:05:00+01:00", + "2019-01-01 12:06:00+01:00", + "2019-01-01 12:07:00+01:00", + "2019-01-01 12:08:00+01:00", + "2019-01-01 12:09:00+01:00", + "2019-01-01 12:10:00+01:00", + "2019-01-01 12:11:00+01:00", + "2019-01-01 12:12:00+01:00", + "2019-01-01 12:13:00+01:00", + "2019-01-01 12:14:00+01:00", + "2019-01-01 12:15:00+01:00", + "2019-01-01 12:16:00+01:00", + "2019-01-01 12:17:00+01:00", + "2019-01-01 12:18:00+01:00", + "2019-01-01 12:19:00+01:00", + "2019-01-01 12:20:00+01:00", + "2019-01-01 12:21:00+01:00", + "2019-01-01 12:22:00+01:00", + "2019-01-01 12:23:00+01:00", + "2019-01-01 12:24:00+01:00", + "2019-01-01 12:25:00+01:00", + "2019-01-01 12:26:00+01:00", + "2019-01-01 12:27:00+01:00", + "2019-01-01 12:28:00+01:00", + "2019-01-01 12:29:00+01:00", + "2019-01-01 12:30:00+01:00", + "2019-01-01 12:31:00+01:00", + "2019-01-01 12:32:00+01:00", + "2019-01-01 12:33:00+01:00", + "2019-01-01 12:34:00+01:00", + "2019-01-01 12:35:00+01:00", + "2019-01-01 12:36:00+01:00", + "2019-01-01 12:37:00+01:00", + "2019-01-01 12:38:00+01:00", + "2019-01-01 12:39:00+01:00", + "2019-01-01 12:40:00+01:00", + "2019-01-01 12:41:00+01:00", + "2019-01-01 12:42:00+01:00", + "2019-01-01 12:43:00+01:00", + "2019-01-01 12:44:00+01:00", + "2019-01-01 12:45:00+01:00", + "2019-01-01 12:46:00+01:00", + "2019-01-01 12:47:00+01:00", + "2019-01-01 12:48:00+01:00", + "2019-01-01 12:49:00+01:00", + "2019-01-01 12:50:00+01:00", + "2019-01-01 12:51:00+01:00", + "2019-01-01 12:52:00+01:00", + "2019-01-01 12:53:00+01:00", + "2019-01-01 12:54:00+01:00", + "2019-01-01 12:55:00+01:00", + "2019-01-01 12:56:00+01:00", + "2019-01-01 12:57:00+01:00", + "2019-01-01 12:58:00+01:00", + "2019-01-01 12:59:00+01:00", + "2019-01-01 13:00:00+01:00", + "2019-01-01 13:01:00+01:00", + "2019-01-01 13:02:00+01:00", + "2019-01-01 13:03:00+01:00", + "2019-01-01 13:04:00+01:00", + "2019-01-01 13:05:00+01:00", + "2019-01-01 13:06:00+01:00", + "2019-01-01 13:07:00+01:00", + "2019-01-01 13:08:00+01:00", + "2019-01-01 13:09:00+01:00", + "2019-01-01 13:10:00+01:00", + "2019-01-01 13:11:00+01:00", + "2019-01-01 13:12:00+01:00", + "2019-01-01 13:13:00+01:00", + "2019-01-01 13:14:00+01:00", + "2019-01-01 13:15:00+01:00", + "2019-01-01 13:16:00+01:00", + "2019-01-01 13:17:00+01:00", + "2019-01-01 13:18:00+01:00", + "2019-01-01 13:19:00+01:00", + "2019-01-01 13:20:00+01:00", + "2019-01-01 13:21:00+01:00", + "2019-01-01 13:22:00+01:00", + "2019-01-01 13:23:00+01:00", + "2019-01-01 13:24:00+01:00", + "2019-01-01 13:25:00+01:00", + "2019-01-01 13:26:00+01:00", + "2019-01-01 13:27:00+01:00", + "2019-01-01 13:28:00+01:00", + "2019-01-01 13:29:00+01:00", + "2019-01-01 13:30:00+01:00", + "2019-01-01 13:31:00+01:00", + "2019-01-01 13:32:00+01:00", + "2019-01-01 13:33:00+01:00", + "2019-01-01 13:34:00+01:00", + "2019-01-01 13:35:00+01:00", + "2019-01-01 13:36:00+01:00", + "2019-01-01 13:37:00+01:00", + "2019-01-01 13:38:00+01:00", + "2019-01-01 13:39:00+01:00", + "2019-01-01 13:40:00+01:00", + "2019-01-01 13:41:00+01:00", + "2019-01-01 13:42:00+01:00", + "2019-01-01 13:43:00+01:00", + "2019-01-01 13:44:00+01:00", + "2019-01-01 13:45:00+01:00", + "2019-01-01 13:46:00+01:00", + "2019-01-01 13:47:00+01:00", + "2019-01-01 13:48:00+01:00", + "2019-01-01 13:49:00+01:00", + "2019-01-01 13:50:00+01:00", + "2019-01-01 13:51:00+01:00", + "2019-01-01 13:52:00+01:00", + "2019-01-01 13:53:00+01:00", + "2019-01-01 13:54:00+01:00", + "2019-01-01 13:55:00+01:00", + "2019-01-01 13:56:00+01:00", + "2019-01-01 13:57:00+01:00", + "2019-01-01 13:58:00+01:00", + "2019-01-01 13:59:00+01:00", + "2019-01-01 14:00:00+01:00", + "2019-01-01 14:01:00+01:00", + "2019-01-01 14:02:00+01:00", + "2019-01-01 14:03:00+01:00", + "2019-01-01 14:04:00+01:00", + "2019-01-01 14:05:00+01:00", + "2019-01-01 14:06:00+01:00", + "2019-01-01 14:07:00+01:00", + "2019-01-01 14:08:00+01:00", + "2019-01-01 14:09:00+01:00", + "2019-01-01 14:10:00+01:00", + "2019-01-01 14:11:00+01:00", + "2019-01-01 14:12:00+01:00", + "2019-01-01 14:13:00+01:00", + "2019-01-01 14:14:00+01:00", + "2019-01-01 14:15:00+01:00", + "2019-01-01 14:16:00+01:00", + "2019-01-01 14:17:00+01:00", + "2019-01-01 14:18:00+01:00", + "2019-01-01 14:19:00+01:00", + "2019-01-01 14:20:00+01:00", + "2019-01-01 14:21:00+01:00", + "2019-01-01 14:22:00+01:00", + "2019-01-01 14:23:00+01:00", + "2019-01-01 14:24:00+01:00", + "2019-01-01 14:25:00+01:00", + "2019-01-01 14:26:00+01:00", + "2019-01-01 14:27:00+01:00", + "2019-01-01 14:28:00+01:00", + "2019-01-01 14:29:00+01:00", + "2019-01-01 14:30:00+01:00", + "2019-01-01 14:31:00+01:00", + "2019-01-01 14:32:00+01:00", + "2019-01-01 14:33:00+01:00", + "2019-01-01 14:34:00+01:00", + "2019-01-01 14:35:00+01:00", + "2019-01-01 14:36:00+01:00", + "2019-01-01 14:37:00+01:00", + "2019-01-01 14:38:00+01:00", + "2019-01-01 14:39:00+01:00", + "2019-01-01 14:40:00+01:00", + "2019-01-01 14:41:00+01:00", + "2019-01-01 14:42:00+01:00", + "2019-01-01 14:43:00+01:00", + "2019-01-01 14:44:00+01:00", + "2019-01-01 14:45:00+01:00", + "2019-01-01 14:46:00+01:00", + "2019-01-01 14:47:00+01:00", + "2019-01-01 14:48:00+01:00", + "2019-01-01 14:49:00+01:00", + "2019-01-01 14:50:00+01:00", + "2019-01-01 14:51:00+01:00", + "2019-01-01 14:52:00+01:00", + "2019-01-01 14:53:00+01:00", + "2019-01-01 14:54:00+01:00", + "2019-01-01 14:55:00+01:00", + "2019-01-01 14:56:00+01:00", + "2019-01-01 14:57:00+01:00", + "2019-01-01 14:58:00+01:00", + "2019-01-01 14:59:00+01:00", + "2019-01-01 15:00:00+01:00", + "2019-01-01 15:01:00+01:00", + "2019-01-01 15:02:00+01:00", + "2019-01-01 15:03:00+01:00", + "2019-01-01 15:04:00+01:00", + "2019-01-01 15:05:00+01:00", + "2019-01-01 15:06:00+01:00", + "2019-01-01 15:07:00+01:00", + "2019-01-01 15:08:00+01:00", + "2019-01-01 15:09:00+01:00", + "2019-01-01 15:10:00+01:00", + "2019-01-01 15:11:00+01:00", + "2019-01-01 15:12:00+01:00", + "2019-01-01 15:13:00+01:00", + "2019-01-01 15:14:00+01:00", + "2019-01-01 15:15:00+01:00", + "2019-01-01 15:16:00+01:00", + "2019-01-01 15:17:00+01:00", + "2019-01-01 15:18:00+01:00", + "2019-01-01 15:19:00+01:00", + "2019-01-01 15:20:00+01:00", + "2019-01-01 15:21:00+01:00", + "2019-01-01 15:22:00+01:00", + "2019-01-01 15:23:00+01:00", + "2019-01-01 15:24:00+01:00", + "2019-01-01 15:25:00+01:00", + "2019-01-01 15:26:00+01:00", + "2019-01-01 15:27:00+01:00", + "2019-01-01 15:28:00+01:00", + "2019-01-01 15:29:00+01:00", + "2019-01-01 15:30:00+01:00", + "2019-01-01 15:31:00+01:00", + "2019-01-01 15:32:00+01:00", + "2019-01-01 15:33:00+01:00", + "2019-01-01 15:34:00+01:00", + "2019-01-01 15:35:00+01:00", + "2019-01-01 15:36:00+01:00", + "2019-01-01 15:37:00+01:00", + "2019-01-01 15:38:00+01:00", + "2019-01-01 15:39:00+01:00", + "2019-01-01 15:40:00+01:00", + "2019-01-01 15:41:00+01:00", + "2019-01-01 15:42:00+01:00", + "2019-01-01 15:43:00+01:00", + "2019-01-01 15:44:00+01:00", + "2019-01-01 15:45:00+01:00", + "2019-01-01 15:46:00+01:00", + "2019-01-01 15:47:00+01:00", + "2019-01-01 15:48:00+01:00", + "2019-01-01 15:49:00+01:00", + "2019-01-01 15:50:00+01:00", + "2019-01-01 15:51:00+01:00", + "2019-01-01 15:52:00+01:00", + "2019-01-01 15:53:00+01:00", + "2019-01-01 15:54:00+01:00", + "2019-01-01 15:55:00+01:00", + "2019-01-01 15:56:00+01:00", + "2019-01-01 15:57:00+01:00", + "2019-01-01 15:58:00+01:00", + "2019-01-01 15:59:00+01:00", + "2019-01-01 16:00:00+01:00", + "2019-01-01 16:01:00+01:00", + "2019-01-01 16:02:00+01:00", + "2019-01-01 16:03:00+01:00", + "2019-01-01 16:04:00+01:00", + "2019-01-01 16:05:00+01:00", + "2019-01-01 16:06:00+01:00", + "2019-01-01 16:07:00+01:00", + "2019-01-01 16:08:00+01:00", + "2019-01-01 16:09:00+01:00", + "2019-01-01 16:10:00+01:00", + "2019-01-01 16:11:00+01:00", + "2019-01-01 16:12:00+01:00", + "2019-01-01 16:13:00+01:00", + "2019-01-01 16:14:00+01:00", + "2019-01-01 16:15:00+01:00", + "2019-01-01 16:16:00+01:00", + "2019-01-01 16:17:00+01:00", + "2019-01-01 16:18:00+01:00", + "2019-01-01 16:19:00+01:00", + "2019-01-01 16:20:00+01:00", + "2019-01-01 16:21:00+01:00", + "2019-01-01 16:22:00+01:00", + "2019-01-01 16:23:00+01:00", + "2019-01-01 16:24:00+01:00", + "2019-01-01 16:25:00+01:00", + "2019-01-01 16:26:00+01:00", + "2019-01-01 16:27:00+01:00", + "2019-01-01 16:28:00+01:00", + "2019-01-01 16:29:00+01:00", + "2019-01-01 16:30:00+01:00", + "2019-01-01 16:31:00+01:00", + "2019-01-01 16:32:00+01:00", + "2019-01-01 16:33:00+01:00", + "2019-01-01 16:34:00+01:00", + "2019-01-01 16:35:00+01:00", + "2019-01-01 16:36:00+01:00", + "2019-01-01 16:37:00+01:00", + "2019-01-01 16:38:00+01:00", + "2019-01-01 16:39:00+01:00", + "2019-01-01 16:40:00+01:00", + "2019-01-01 16:41:00+01:00", + "2019-01-01 16:42:00+01:00", + "2019-01-01 16:43:00+01:00", + "2019-01-01 16:44:00+01:00", + "2019-01-01 16:45:00+01:00", + "2019-01-01 16:46:00+01:00", + "2019-01-01 16:47:00+01:00", + "2019-01-01 16:48:00+01:00", + "2019-01-01 16:49:00+01:00", + "2019-01-01 16:50:00+01:00", + "2019-01-01 16:51:00+01:00", + "2019-01-01 16:52:00+01:00", + "2019-01-01 16:53:00+01:00", + "2019-01-01 16:54:00+01:00", + "2019-01-01 16:55:00+01:00", + "2019-01-01 16:56:00+01:00", + "2019-01-01 16:57:00+01:00", + "2019-01-01 16:58:00+01:00", + "2019-01-01 16:59:00+01:00", + "2019-01-01 17:00:00+01:00", + "2019-01-01 17:01:00+01:00", + "2019-01-01 17:02:00+01:00", + "2019-01-01 17:03:00+01:00", + "2019-01-01 17:04:00+01:00", + "2019-01-01 17:05:00+01:00", + "2019-01-01 17:06:00+01:00", + "2019-01-01 17:07:00+01:00", + "2019-01-01 17:08:00+01:00", + "2019-01-01 17:09:00+01:00", + "2019-01-01 17:10:00+01:00", + "2019-01-01 17:11:00+01:00", + "2019-01-01 17:12:00+01:00", + "2019-01-01 17:13:00+01:00", + "2019-01-01 17:14:00+01:00", + "2019-01-01 17:15:00+01:00", + "2019-01-01 17:16:00+01:00", + "2019-01-01 17:17:00+01:00", + "2019-01-01 17:18:00+01:00", + "2019-01-01 17:19:00+01:00", + "2019-01-01 17:20:00+01:00", + "2019-01-01 17:21:00+01:00", + "2019-01-01 17:22:00+01:00", + "2019-01-01 17:23:00+01:00", + "2019-01-01 17:24:00+01:00", + "2019-01-01 17:25:00+01:00", + "2019-01-01 17:26:00+01:00", + "2019-01-01 17:27:00+01:00", + "2019-01-01 17:28:00+01:00", + "2019-01-01 17:29:00+01:00", + "2019-01-01 17:30:00+01:00", + "2019-01-01 17:31:00+01:00", + "2019-01-01 17:32:00+01:00", + "2019-01-01 17:33:00+01:00", + "2019-01-01 17:34:00+01:00", + "2019-01-01 17:35:00+01:00", + "2019-01-01 17:36:00+01:00", + "2019-01-01 17:37:00+01:00", + "2019-01-01 17:38:00+01:00", + "2019-01-01 17:39:00+01:00", + "2019-01-01 17:40:00+01:00", + "2019-01-01 17:41:00+01:00", + "2019-01-01 17:42:00+01:00", + "2019-01-01 17:43:00+01:00", + "2019-01-01 17:44:00+01:00", + "2019-01-01 17:45:00+01:00", + "2019-01-01 17:46:00+01:00", + "2019-01-01 17:47:00+01:00", + "2019-01-01 17:48:00+01:00", + "2019-01-01 17:49:00+01:00", + "2019-01-01 17:50:00+01:00", + "2019-01-01 17:51:00+01:00", + "2019-01-01 17:52:00+01:00", + "2019-01-01 17:53:00+01:00", + "2019-01-01 17:54:00+01:00", + "2019-01-01 17:55:00+01:00", + "2019-01-01 17:56:00+01:00", + "2019-01-01 17:57:00+01:00", + "2019-01-01 17:58:00+01:00", + "2019-01-01 17:59:00+01:00", + "2019-01-01 18:00:00+01:00", + "2019-01-01 18:01:00+01:00", + "2019-01-01 18:02:00+01:00", + "2019-01-01 18:03:00+01:00", + "2019-01-01 18:04:00+01:00", + "2019-01-01 18:05:00+01:00", + "2019-01-01 18:06:00+01:00", + "2019-01-01 18:07:00+01:00", + "2019-01-01 18:08:00+01:00", + "2019-01-01 18:09:00+01:00", + "2019-01-01 18:10:00+01:00", + "2019-01-01 18:11:00+01:00", + "2019-01-01 18:12:00+01:00", + "2019-01-01 18:13:00+01:00", + "2019-01-01 18:14:00+01:00", + "2019-01-01 18:15:00+01:00", + "2019-01-01 18:16:00+01:00", + "2019-01-01 18:17:00+01:00", + "2019-01-01 18:18:00+01:00", + "2019-01-01 18:19:00+01:00", + "2019-01-01 18:20:00+01:00", + "2019-01-01 18:21:00+01:00", + "2019-01-01 18:22:00+01:00", + "2019-01-01 18:23:00+01:00", + "2019-01-01 18:24:00+01:00", + "2019-01-01 18:25:00+01:00", + "2019-01-01 18:26:00+01:00", + "2019-01-01 18:27:00+01:00", + "2019-01-01 18:28:00+01:00", + "2019-01-01 18:29:00+01:00", + "2019-01-01 18:30:00+01:00", + "2019-01-01 18:31:00+01:00", + "2019-01-01 18:32:00+01:00", + "2019-01-01 18:33:00+01:00", + "2019-01-01 18:34:00+01:00", + "2019-01-01 18:35:00+01:00", + "2019-01-01 18:36:00+01:00", + "2019-01-01 18:37:00+01:00", + "2019-01-01 18:38:00+01:00", + "2019-01-01 18:39:00+01:00", + "2019-01-01 18:40:00+01:00", + "2019-01-01 18:41:00+01:00", + "2019-01-01 18:42:00+01:00", + "2019-01-01 18:43:00+01:00", + "2019-01-01 18:44:00+01:00", + "2019-01-01 18:45:00+01:00", + "2019-01-01 18:46:00+01:00", + "2019-01-01 18:47:00+01:00", + "2019-01-01 18:48:00+01:00", + "2019-01-01 18:49:00+01:00", + "2019-01-01 18:50:00+01:00", + "2019-01-01 18:51:00+01:00", + "2019-01-01 18:52:00+01:00", + "2019-01-01 18:53:00+01:00", + "2019-01-01 18:54:00+01:00", + "2019-01-01 18:55:00+01:00", + "2019-01-01 18:56:00+01:00", + "2019-01-01 18:57:00+01:00", + "2019-01-01 18:58:00+01:00", + "2019-01-01 18:59:00+01:00", + "2019-01-01 19:00:00+01:00", + "2019-01-01 19:01:00+01:00", + "2019-01-01 19:02:00+01:00", + "2019-01-01 19:03:00+01:00", + "2019-01-01 19:04:00+01:00", + "2019-01-01 19:05:00+01:00", + "2019-01-01 19:06:00+01:00", + "2019-01-01 19:07:00+01:00", + "2019-01-01 19:08:00+01:00", + "2019-01-01 19:09:00+01:00", + "2019-01-01 19:10:00+01:00", + "2019-01-01 19:11:00+01:00", + "2019-01-01 19:12:00+01:00", + "2019-01-01 19:13:00+01:00", + "2019-01-01 19:14:00+01:00", + "2019-01-01 19:15:00+01:00", + "2019-01-01 19:16:00+01:00", + "2019-01-01 19:17:00+01:00", + "2019-01-01 19:18:00+01:00", + "2019-01-01 19:19:00+01:00", + "2019-01-01 19:20:00+01:00", + "2019-01-01 19:21:00+01:00", + "2019-01-01 19:22:00+01:00", + "2019-01-01 19:23:00+01:00", + "2019-01-01 19:24:00+01:00", + "2019-01-01 19:25:00+01:00", + "2019-01-01 19:26:00+01:00", + "2019-01-01 19:27:00+01:00", + "2019-01-01 19:28:00+01:00", + "2019-01-01 19:29:00+01:00", + "2019-01-01 19:30:00+01:00", + "2019-01-01 19:31:00+01:00", + "2019-01-01 19:32:00+01:00", + "2019-01-01 19:33:00+01:00", + "2019-01-01 19:34:00+01:00", + "2019-01-01 19:35:00+01:00", + "2019-01-01 19:36:00+01:00", + "2019-01-01 19:37:00+01:00", + "2019-01-01 19:38:00+01:00", + "2019-01-01 19:39:00+01:00", + "2019-01-01 19:40:00+01:00", + "2019-01-01 19:41:00+01:00", + "2019-01-01 19:42:00+01:00", + "2019-01-01 19:43:00+01:00", + "2019-01-01 19:44:00+01:00", + "2019-01-01 19:45:00+01:00", + "2019-01-01 19:46:00+01:00", + "2019-01-01 19:47:00+01:00", + "2019-01-01 19:48:00+01:00", + "2019-01-01 19:49:00+01:00", + "2019-01-01 19:50:00+01:00", + "2019-01-01 19:51:00+01:00", + "2019-01-01 19:52:00+01:00", + "2019-01-01 19:53:00+01:00", + "2019-01-01 19:54:00+01:00", + "2019-01-01 19:55:00+01:00", + "2019-01-01 19:56:00+01:00", + "2019-01-01 19:57:00+01:00", + "2019-01-01 19:58:00+01:00", + "2019-01-01 19:59:00+01:00", + "2019-01-01 20:00:00+01:00", + "2019-01-01 20:01:00+01:00", + "2019-01-01 20:02:00+01:00", + "2019-01-01 20:03:00+01:00", + "2019-01-01 20:04:00+01:00", + "2019-01-01 20:05:00+01:00", + "2019-01-01 20:06:00+01:00", + "2019-01-01 20:07:00+01:00", + "2019-01-01 20:08:00+01:00", + "2019-01-01 20:09:00+01:00", + "2019-01-01 20:10:00+01:00", + "2019-01-01 20:11:00+01:00", + "2019-01-01 20:12:00+01:00", + "2019-01-01 20:13:00+01:00", + "2019-01-01 20:14:00+01:00", + "2019-01-01 20:15:00+01:00", + "2019-01-01 20:16:00+01:00", + "2019-01-01 20:17:00+01:00", + "2019-01-01 20:18:00+01:00", + "2019-01-01 20:19:00+01:00", + "2019-01-01 20:20:00+01:00", + "2019-01-01 20:21:00+01:00", + "2019-01-01 20:22:00+01:00", + "2019-01-01 20:23:00+01:00", + "2019-01-01 20:24:00+01:00", + "2019-01-01 20:25:00+01:00", + "2019-01-01 20:26:00+01:00", + "2019-01-01 20:27:00+01:00", + "2019-01-01 20:28:00+01:00", + "2019-01-01 20:29:00+01:00", + "2019-01-01 20:30:00+01:00", + "2019-01-01 20:31:00+01:00", + "2019-01-01 20:32:00+01:00", + "2019-01-01 20:33:00+01:00", + "2019-01-01 20:34:00+01:00", + "2019-01-01 20:35:00+01:00", + "2019-01-01 20:36:00+01:00", + "2019-01-01 20:37:00+01:00", + "2019-01-01 20:38:00+01:00", + "2019-01-01 20:39:00+01:00", + "2019-01-01 20:40:00+01:00", + "2019-01-01 20:41:00+01:00", + "2019-01-01 20:42:00+01:00", + "2019-01-01 20:43:00+01:00", + "2019-01-01 20:44:00+01:00", + "2019-01-01 20:45:00+01:00", + "2019-01-01 20:46:00+01:00", + "2019-01-01 20:47:00+01:00", + "2019-01-01 20:48:00+01:00", + "2019-01-01 20:49:00+01:00", + "2019-01-01 20:50:00+01:00", + "2019-01-01 20:51:00+01:00", + "2019-01-01 20:52:00+01:00", + "2019-01-01 20:53:00+01:00", + "2019-01-01 20:54:00+01:00", + "2019-01-01 20:55:00+01:00", + "2019-01-01 20:56:00+01:00", + "2019-01-01 20:57:00+01:00", + "2019-01-01 20:58:00+01:00", + "2019-01-01 20:59:00+01:00", + "2019-01-01 21:00:00+01:00", + "2019-01-01 21:01:00+01:00", + "2019-01-01 21:02:00+01:00", + "2019-01-01 21:03:00+01:00", + "2019-01-01 21:04:00+01:00", + "2019-01-01 21:05:00+01:00", + "2019-01-01 21:06:00+01:00", + "2019-01-01 21:07:00+01:00", + "2019-01-01 21:08:00+01:00", + "2019-01-01 21:09:00+01:00", + "2019-01-01 21:10:00+01:00", + "2019-01-01 21:11:00+01:00", + "2019-01-01 21:12:00+01:00", + "2019-01-01 21:13:00+01:00", + "2019-01-01 21:14:00+01:00", + "2019-01-01 21:15:00+01:00", + "2019-01-01 21:16:00+01:00", + "2019-01-01 21:17:00+01:00", + "2019-01-01 21:18:00+01:00", + "2019-01-01 21:19:00+01:00", + "2019-01-01 21:20:00+01:00", + "2019-01-01 21:21:00+01:00", + "2019-01-01 21:22:00+01:00", + "2019-01-01 21:23:00+01:00", + "2019-01-01 21:24:00+01:00", + "2019-01-01 21:25:00+01:00", + "2019-01-01 21:26:00+01:00", + "2019-01-01 21:27:00+01:00", + "2019-01-01 21:28:00+01:00", + "2019-01-01 21:29:00+01:00", + "2019-01-01 21:30:00+01:00", + "2019-01-01 21:31:00+01:00", + "2019-01-01 21:32:00+01:00", + "2019-01-01 21:33:00+01:00", + "2019-01-01 21:34:00+01:00", + "2019-01-01 21:35:00+01:00", + "2019-01-01 21:36:00+01:00", + "2019-01-01 21:37:00+01:00", + "2019-01-01 21:38:00+01:00", + "2019-01-01 21:39:00+01:00", + "2019-01-01 21:40:00+01:00", + "2019-01-01 21:41:00+01:00", + "2019-01-01 21:42:00+01:00", + "2019-01-01 21:43:00+01:00", + "2019-01-01 21:44:00+01:00", + "2019-01-01 21:45:00+01:00", + "2019-01-01 21:46:00+01:00", + "2019-01-01 21:47:00+01:00", + "2019-01-01 21:48:00+01:00", + "2019-01-01 21:49:00+01:00", + "2019-01-01 21:50:00+01:00", + "2019-01-01 21:51:00+01:00", + "2019-01-01 21:52:00+01:00", + "2019-01-01 21:53:00+01:00", + "2019-01-01 21:54:00+01:00", + "2019-01-01 21:55:00+01:00", + "2019-01-01 21:56:00+01:00", + "2019-01-01 21:57:00+01:00", + "2019-01-01 21:58:00+01:00", + "2019-01-01 21:59:00+01:00", + "2019-01-01 22:00:00+01:00", + "2019-01-01 22:01:00+01:00", + "2019-01-01 22:02:00+01:00", + "2019-01-01 22:03:00+01:00", + "2019-01-01 22:04:00+01:00", + "2019-01-01 22:05:00+01:00", + "2019-01-01 22:06:00+01:00", + "2019-01-01 22:07:00+01:00", + "2019-01-01 22:08:00+01:00", + "2019-01-01 22:09:00+01:00", + "2019-01-01 22:10:00+01:00", + "2019-01-01 22:11:00+01:00", + "2019-01-01 22:12:00+01:00", + "2019-01-01 22:13:00+01:00", + "2019-01-01 22:14:00+01:00", + "2019-01-01 22:15:00+01:00", + "2019-01-01 22:16:00+01:00", + "2019-01-01 22:17:00+01:00", + "2019-01-01 22:18:00+01:00", + "2019-01-01 22:19:00+01:00", + "2019-01-01 22:20:00+01:00", + "2019-01-01 22:21:00+01:00", + "2019-01-01 22:22:00+01:00", + "2019-01-01 22:23:00+01:00", + "2019-01-01 22:24:00+01:00", + "2019-01-01 22:25:00+01:00", + "2019-01-01 22:26:00+01:00", + "2019-01-01 22:27:00+01:00", + "2019-01-01 22:28:00+01:00", + "2019-01-01 22:29:00+01:00", + "2019-01-01 22:30:00+01:00", + "2019-01-01 22:31:00+01:00", + "2019-01-01 22:32:00+01:00", + "2019-01-01 22:33:00+01:00", + "2019-01-01 22:34:00+01:00", + "2019-01-01 22:35:00+01:00", + "2019-01-01 22:36:00+01:00", + "2019-01-01 22:37:00+01:00", + "2019-01-01 22:38:00+01:00", + "2019-01-01 22:39:00+01:00", + "2019-01-01 22:40:00+01:00", + "2019-01-01 22:41:00+01:00", + "2019-01-01 22:42:00+01:00", + "2019-01-01 22:43:00+01:00", + "2019-01-01 22:44:00+01:00", + "2019-01-01 22:45:00+01:00", + "2019-01-01 22:46:00+01:00", + "2019-01-01 22:47:00+01:00", + "2019-01-01 22:48:00+01:00", + "2019-01-01 22:49:00+01:00", + "2019-01-01 22:50:00+01:00", + "2019-01-01 22:51:00+01:00", + "2019-01-01 22:52:00+01:00", + "2019-01-01 22:53:00+01:00", + "2019-01-01 22:54:00+01:00", + "2019-01-01 22:55:00+01:00", + "2019-01-01 22:56:00+01:00", + "2019-01-01 22:57:00+01:00", + "2019-01-01 22:58:00+01:00", + "2019-01-01 22:59:00+01:00", + "2019-01-01 23:00:00+01:00", + "2019-01-01 23:01:00+01:00", + "2019-01-01 23:02:00+01:00", + "2019-01-01 23:03:00+01:00", + "2019-01-01 23:04:00+01:00", + "2019-01-01 23:05:00+01:00", + "2019-01-01 23:06:00+01:00", + "2019-01-01 23:07:00+01:00", + "2019-01-01 23:08:00+01:00", + "2019-01-01 23:09:00+01:00", + "2019-01-01 23:10:00+01:00", + "2019-01-01 23:11:00+01:00", + "2019-01-01 23:12:00+01:00", + "2019-01-01 23:13:00+01:00", + "2019-01-01 23:14:00+01:00", + "2019-01-01 23:15:00+01:00", + "2019-01-01 23:16:00+01:00", + "2019-01-01 23:17:00+01:00", + "2019-01-01 23:18:00+01:00", + "2019-01-01 23:19:00+01:00", + "2019-01-01 23:20:00+01:00", + "2019-01-01 23:21:00+01:00", + "2019-01-01 23:22:00+01:00", + "2019-01-01 23:23:00+01:00", + "2019-01-01 23:24:00+01:00", + "2019-01-01 23:25:00+01:00", + "2019-01-01 23:26:00+01:00", + "2019-01-01 23:27:00+01:00", + "2019-01-01 23:28:00+01:00", + "2019-01-01 23:29:00+01:00", + "2019-01-01 23:30:00+01:00", + "2019-01-01 23:31:00+01:00", + "2019-01-01 23:32:00+01:00", + "2019-01-01 23:33:00+01:00", + "2019-01-01 23:34:00+01:00", + "2019-01-01 23:35:00+01:00", + "2019-01-01 23:36:00+01:00", + "2019-01-01 23:37:00+01:00", + "2019-01-01 23:38:00+01:00", + "2019-01-01 23:39:00+01:00", + "2019-01-01 23:40:00+01:00", + "2019-01-01 23:41:00+01:00", + "2019-01-01 23:42:00+01:00", + "2019-01-01 23:43:00+01:00", + "2019-01-01 23:44:00+01:00", + "2019-01-01 23:45:00+01:00", + "2019-01-01 23:46:00+01:00", + "2019-01-01 23:47:00+01:00", + "2019-01-01 23:48:00+01:00", + "2019-01-01 23:49:00+01:00", + "2019-01-01 23:50:00+01:00", + "2019-01-01 23:51:00+01:00", + "2019-01-01 23:52:00+01:00", + "2019-01-01 23:53:00+01:00", + "2019-01-01 23:54:00+01:00", + "2019-01-01 23:55:00+01:00", + "2019-01-01 23:56:00+01:00", + "2019-01-01 23:57:00+01:00", + "2019-01-01 23:58:00+01:00", + "2019-01-01 23:59:00+01:00" + ], + "xaxis": "x", + "y": [ + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555, + -5.555555555555555 + ], + "yaxis": "y" + }, + { + "line": { + "color": "rgba(55, 128, 191, 1.0)", + "dash": "solid", + "shape": "linear", + "width": 1.3 + }, + "mode": "lines", + "name": "output_MW", + "text": "", + "type": "scatter", + "x": [ + "2019-01-01 00:00:00+01:00", + "2019-01-01 00:01:00+01:00", + "2019-01-01 00:02:00+01:00", + "2019-01-01 00:03:00+01:00", + "2019-01-01 00:04:00+01:00", + "2019-01-01 00:05:00+01:00", + "2019-01-01 00:06:00+01:00", + "2019-01-01 00:07:00+01:00", + "2019-01-01 00:08:00+01:00", + "2019-01-01 00:09:00+01:00", + "2019-01-01 00:10:00+01:00", + "2019-01-01 00:11:00+01:00", + "2019-01-01 00:12:00+01:00", + "2019-01-01 00:13:00+01:00", + "2019-01-01 00:14:00+01:00", + "2019-01-01 00:15:00+01:00", + "2019-01-01 00:16:00+01:00", + "2019-01-01 00:17:00+01:00", + "2019-01-01 00:18:00+01:00", + "2019-01-01 00:19:00+01:00", + "2019-01-01 00:20:00+01:00", + "2019-01-01 00:21:00+01:00", + "2019-01-01 00:22:00+01:00", + "2019-01-01 00:23:00+01:00", + "2019-01-01 00:24:00+01:00", + "2019-01-01 00:25:00+01:00", + "2019-01-01 00:26:00+01:00", + "2019-01-01 00:27:00+01:00", + "2019-01-01 00:28:00+01:00", + "2019-01-01 00:29:00+01:00", + "2019-01-01 00:30:00+01:00", + "2019-01-01 00:31:00+01:00", + "2019-01-01 00:32:00+01:00", + "2019-01-01 00:33:00+01:00", + "2019-01-01 00:34:00+01:00", + "2019-01-01 00:35:00+01:00", + "2019-01-01 00:36:00+01:00", + "2019-01-01 00:37:00+01:00", + "2019-01-01 00:38:00+01:00", + "2019-01-01 00:39:00+01:00", + "2019-01-01 00:40:00+01:00", + "2019-01-01 00:41:00+01:00", + "2019-01-01 00:42:00+01:00", + "2019-01-01 00:43:00+01:00", + "2019-01-01 00:44:00+01:00", + "2019-01-01 00:45:00+01:00", + "2019-01-01 00:46:00+01:00", + "2019-01-01 00:47:00+01:00", + "2019-01-01 00:48:00+01:00", + "2019-01-01 00:49:00+01:00", + "2019-01-01 00:50:00+01:00", + "2019-01-01 00:51:00+01:00", + "2019-01-01 00:52:00+01:00", + "2019-01-01 00:53:00+01:00", + "2019-01-01 00:54:00+01:00", + "2019-01-01 00:55:00+01:00", + "2019-01-01 00:56:00+01:00", + "2019-01-01 00:57:00+01:00", + "2019-01-01 00:58:00+01:00", + "2019-01-01 00:59:00+01:00", + "2019-01-01 01:00:00+01:00", + "2019-01-01 01:01:00+01:00", + "2019-01-01 01:02:00+01:00", + "2019-01-01 01:03:00+01:00", + "2019-01-01 01:04:00+01:00", + "2019-01-01 01:05:00+01:00", + "2019-01-01 01:06:00+01:00", + "2019-01-01 01:07:00+01:00", + "2019-01-01 01:08:00+01:00", + "2019-01-01 01:09:00+01:00", + "2019-01-01 01:10:00+01:00", + "2019-01-01 01:11:00+01:00", + "2019-01-01 01:12:00+01:00", + "2019-01-01 01:13:00+01:00", + "2019-01-01 01:14:00+01:00", + "2019-01-01 01:15:00+01:00", + "2019-01-01 01:16:00+01:00", + "2019-01-01 01:17:00+01:00", + "2019-01-01 01:18:00+01:00", + "2019-01-01 01:19:00+01:00", + "2019-01-01 01:20:00+01:00", + "2019-01-01 01:21:00+01:00", + "2019-01-01 01:22:00+01:00", + "2019-01-01 01:23:00+01:00", + "2019-01-01 01:24:00+01:00", + "2019-01-01 01:25:00+01:00", + "2019-01-01 01:26:00+01:00", + "2019-01-01 01:27:00+01:00", + "2019-01-01 01:28:00+01:00", + "2019-01-01 01:29:00+01:00", + "2019-01-01 01:30:00+01:00", + "2019-01-01 01:31:00+01:00", + "2019-01-01 01:32:00+01:00", + "2019-01-01 01:33:00+01:00", + "2019-01-01 01:34:00+01:00", + "2019-01-01 01:35:00+01:00", + "2019-01-01 01:36:00+01:00", + "2019-01-01 01:37:00+01:00", + "2019-01-01 01:38:00+01:00", + "2019-01-01 01:39:00+01:00", + "2019-01-01 01:40:00+01:00", + "2019-01-01 01:41:00+01:00", + "2019-01-01 01:42:00+01:00", + "2019-01-01 01:43:00+01:00", + "2019-01-01 01:44:00+01:00", + "2019-01-01 01:45:00+01:00", + "2019-01-01 01:46:00+01:00", + "2019-01-01 01:47:00+01:00", + "2019-01-01 01:48:00+01:00", + "2019-01-01 01:49:00+01:00", + "2019-01-01 01:50:00+01:00", + "2019-01-01 01:51:00+01:00", + "2019-01-01 01:52:00+01:00", + "2019-01-01 01:53:00+01:00", + "2019-01-01 01:54:00+01:00", + "2019-01-01 01:55:00+01:00", + "2019-01-01 01:56:00+01:00", + "2019-01-01 01:57:00+01:00", + "2019-01-01 01:58:00+01:00", + "2019-01-01 01:59:00+01:00", + "2019-01-01 02:00:00+01:00", + "2019-01-01 02:01:00+01:00", + "2019-01-01 02:02:00+01:00", + "2019-01-01 02:03:00+01:00", + "2019-01-01 02:04:00+01:00", + "2019-01-01 02:05:00+01:00", + "2019-01-01 02:06:00+01:00", + "2019-01-01 02:07:00+01:00", + "2019-01-01 02:08:00+01:00", + "2019-01-01 02:09:00+01:00", + "2019-01-01 02:10:00+01:00", + "2019-01-01 02:11:00+01:00", + "2019-01-01 02:12:00+01:00", + "2019-01-01 02:13:00+01:00", + "2019-01-01 02:14:00+01:00", + "2019-01-01 02:15:00+01:00", + "2019-01-01 02:16:00+01:00", + "2019-01-01 02:17:00+01:00", + "2019-01-01 02:18:00+01:00", + "2019-01-01 02:19:00+01:00", + "2019-01-01 02:20:00+01:00", + "2019-01-01 02:21:00+01:00", + "2019-01-01 02:22:00+01:00", + "2019-01-01 02:23:00+01:00", + "2019-01-01 02:24:00+01:00", + "2019-01-01 02:25:00+01:00", + "2019-01-01 02:26:00+01:00", + "2019-01-01 02:27:00+01:00", + "2019-01-01 02:28:00+01:00", + "2019-01-01 02:29:00+01:00", + "2019-01-01 02:30:00+01:00", + "2019-01-01 02:31:00+01:00", + "2019-01-01 02:32:00+01:00", + "2019-01-01 02:33:00+01:00", + "2019-01-01 02:34:00+01:00", + "2019-01-01 02:35:00+01:00", + "2019-01-01 02:36:00+01:00", + "2019-01-01 02:37:00+01:00", + "2019-01-01 02:38:00+01:00", + "2019-01-01 02:39:00+01:00", + "2019-01-01 02:40:00+01:00", + "2019-01-01 02:41:00+01:00", + "2019-01-01 02:42:00+01:00", + "2019-01-01 02:43:00+01:00", + "2019-01-01 02:44:00+01:00", + "2019-01-01 02:45:00+01:00", + "2019-01-01 02:46:00+01:00", + "2019-01-01 02:47:00+01:00", + "2019-01-01 02:48:00+01:00", + "2019-01-01 02:49:00+01:00", + "2019-01-01 02:50:00+01:00", + "2019-01-01 02:51:00+01:00", + "2019-01-01 02:52:00+01:00", + "2019-01-01 02:53:00+01:00", + "2019-01-01 02:54:00+01:00", + "2019-01-01 02:55:00+01:00", + "2019-01-01 02:56:00+01:00", + "2019-01-01 02:57:00+01:00", + "2019-01-01 02:58:00+01:00", + "2019-01-01 02:59:00+01:00", + "2019-01-01 03:00:00+01:00", + "2019-01-01 03:01:00+01:00", + "2019-01-01 03:02:00+01:00", + "2019-01-01 03:03:00+01:00", + "2019-01-01 03:04:00+01:00", + "2019-01-01 03:05:00+01:00", + "2019-01-01 03:06:00+01:00", + "2019-01-01 03:07:00+01:00", + "2019-01-01 03:08:00+01:00", + "2019-01-01 03:09:00+01:00", + "2019-01-01 03:10:00+01:00", + "2019-01-01 03:11:00+01:00", + "2019-01-01 03:12:00+01:00", + "2019-01-01 03:13:00+01:00", + "2019-01-01 03:14:00+01:00", + "2019-01-01 03:15:00+01:00", + "2019-01-01 03:16:00+01:00", + "2019-01-01 03:17:00+01:00", + "2019-01-01 03:18:00+01:00", + "2019-01-01 03:19:00+01:00", + "2019-01-01 03:20:00+01:00", + "2019-01-01 03:21:00+01:00", + "2019-01-01 03:22:00+01:00", + "2019-01-01 03:23:00+01:00", + "2019-01-01 03:24:00+01:00", + "2019-01-01 03:25:00+01:00", + "2019-01-01 03:26:00+01:00", + "2019-01-01 03:27:00+01:00", + "2019-01-01 03:28:00+01:00", + "2019-01-01 03:29:00+01:00", + "2019-01-01 03:30:00+01:00", + "2019-01-01 03:31:00+01:00", + "2019-01-01 03:32:00+01:00", + "2019-01-01 03:33:00+01:00", + "2019-01-01 03:34:00+01:00", + "2019-01-01 03:35:00+01:00", + "2019-01-01 03:36:00+01:00", + "2019-01-01 03:37:00+01:00", + "2019-01-01 03:38:00+01:00", + "2019-01-01 03:39:00+01:00", + "2019-01-01 03:40:00+01:00", + "2019-01-01 03:41:00+01:00", + "2019-01-01 03:42:00+01:00", + "2019-01-01 03:43:00+01:00", + "2019-01-01 03:44:00+01:00", + "2019-01-01 03:45:00+01:00", + "2019-01-01 03:46:00+01:00", + "2019-01-01 03:47:00+01:00", + "2019-01-01 03:48:00+01:00", + "2019-01-01 03:49:00+01:00", + "2019-01-01 03:50:00+01:00", + "2019-01-01 03:51:00+01:00", + "2019-01-01 03:52:00+01:00", + "2019-01-01 03:53:00+01:00", + "2019-01-01 03:54:00+01:00", + "2019-01-01 03:55:00+01:00", + "2019-01-01 03:56:00+01:00", + "2019-01-01 03:57:00+01:00", + "2019-01-01 03:58:00+01:00", + "2019-01-01 03:59:00+01:00", + "2019-01-01 04:00:00+01:00", + "2019-01-01 04:01:00+01:00", + "2019-01-01 04:02:00+01:00", + "2019-01-01 04:03:00+01:00", + "2019-01-01 04:04:00+01:00", + "2019-01-01 04:05:00+01:00", + "2019-01-01 04:06:00+01:00", + "2019-01-01 04:07:00+01:00", + "2019-01-01 04:08:00+01:00", + "2019-01-01 04:09:00+01:00", + "2019-01-01 04:10:00+01:00", + "2019-01-01 04:11:00+01:00", + "2019-01-01 04:12:00+01:00", + "2019-01-01 04:13:00+01:00", + "2019-01-01 04:14:00+01:00", + "2019-01-01 04:15:00+01:00", + "2019-01-01 04:16:00+01:00", + "2019-01-01 04:17:00+01:00", + "2019-01-01 04:18:00+01:00", + "2019-01-01 04:19:00+01:00", + "2019-01-01 04:20:00+01:00", + "2019-01-01 04:21:00+01:00", + "2019-01-01 04:22:00+01:00", + "2019-01-01 04:23:00+01:00", + "2019-01-01 04:24:00+01:00", + "2019-01-01 04:25:00+01:00", + "2019-01-01 04:26:00+01:00", + "2019-01-01 04:27:00+01:00", + "2019-01-01 04:28:00+01:00", + "2019-01-01 04:29:00+01:00", + "2019-01-01 04:30:00+01:00", + "2019-01-01 04:31:00+01:00", + "2019-01-01 04:32:00+01:00", + "2019-01-01 04:33:00+01:00", + "2019-01-01 04:34:00+01:00", + "2019-01-01 04:35:00+01:00", + "2019-01-01 04:36:00+01:00", + "2019-01-01 04:37:00+01:00", + "2019-01-01 04:38:00+01:00", + "2019-01-01 04:39:00+01:00", + "2019-01-01 04:40:00+01:00", + "2019-01-01 04:41:00+01:00", + "2019-01-01 04:42:00+01:00", + "2019-01-01 04:43:00+01:00", + "2019-01-01 04:44:00+01:00", + "2019-01-01 04:45:00+01:00", + "2019-01-01 04:46:00+01:00", + "2019-01-01 04:47:00+01:00", + "2019-01-01 04:48:00+01:00", + "2019-01-01 04:49:00+01:00", + "2019-01-01 04:50:00+01:00", + "2019-01-01 04:51:00+01:00", + "2019-01-01 04:52:00+01:00", + "2019-01-01 04:53:00+01:00", + "2019-01-01 04:54:00+01:00", + "2019-01-01 04:55:00+01:00", + "2019-01-01 04:56:00+01:00", + "2019-01-01 04:57:00+01:00", + "2019-01-01 04:58:00+01:00", + "2019-01-01 04:59:00+01:00", + "2019-01-01 05:00:00+01:00", + "2019-01-01 05:01:00+01:00", + "2019-01-01 05:02:00+01:00", + "2019-01-01 05:03:00+01:00", + "2019-01-01 05:04:00+01:00", + "2019-01-01 05:05:00+01:00", + "2019-01-01 05:06:00+01:00", + "2019-01-01 05:07:00+01:00", + "2019-01-01 05:08:00+01:00", + "2019-01-01 05:09:00+01:00", + "2019-01-01 05:10:00+01:00", + "2019-01-01 05:11:00+01:00", + "2019-01-01 05:12:00+01:00", + "2019-01-01 05:13:00+01:00", + "2019-01-01 05:14:00+01:00", + "2019-01-01 05:15:00+01:00", + "2019-01-01 05:16:00+01:00", + "2019-01-01 05:17:00+01:00", + "2019-01-01 05:18:00+01:00", + "2019-01-01 05:19:00+01:00", + "2019-01-01 05:20:00+01:00", + "2019-01-01 05:21:00+01:00", + "2019-01-01 05:22:00+01:00", + "2019-01-01 05:23:00+01:00", + "2019-01-01 05:24:00+01:00", + "2019-01-01 05:25:00+01:00", + "2019-01-01 05:26:00+01:00", + "2019-01-01 05:27:00+01:00", + "2019-01-01 05:28:00+01:00", + "2019-01-01 05:29:00+01:00", + "2019-01-01 05:30:00+01:00", + "2019-01-01 05:31:00+01:00", + "2019-01-01 05:32:00+01:00", + "2019-01-01 05:33:00+01:00", + "2019-01-01 05:34:00+01:00", + "2019-01-01 05:35:00+01:00", + "2019-01-01 05:36:00+01:00", + "2019-01-01 05:37:00+01:00", + "2019-01-01 05:38:00+01:00", + "2019-01-01 05:39:00+01:00", + "2019-01-01 05:40:00+01:00", + "2019-01-01 05:41:00+01:00", + "2019-01-01 05:42:00+01:00", + "2019-01-01 05:43:00+01:00", + "2019-01-01 05:44:00+01:00", + "2019-01-01 05:45:00+01:00", + "2019-01-01 05:46:00+01:00", + "2019-01-01 05:47:00+01:00", + "2019-01-01 05:48:00+01:00", + "2019-01-01 05:49:00+01:00", + "2019-01-01 05:50:00+01:00", + "2019-01-01 05:51:00+01:00", + "2019-01-01 05:52:00+01:00", + "2019-01-01 05:53:00+01:00", + "2019-01-01 05:54:00+01:00", + "2019-01-01 05:55:00+01:00", + "2019-01-01 05:56:00+01:00", + "2019-01-01 05:57:00+01:00", + "2019-01-01 05:58:00+01:00", + "2019-01-01 05:59:00+01:00", + "2019-01-01 06:00:00+01:00", + "2019-01-01 06:01:00+01:00", + "2019-01-01 06:02:00+01:00", + "2019-01-01 06:03:00+01:00", + "2019-01-01 06:04:00+01:00", + "2019-01-01 06:05:00+01:00", + "2019-01-01 06:06:00+01:00", + "2019-01-01 06:07:00+01:00", + "2019-01-01 06:08:00+01:00", + "2019-01-01 06:09:00+01:00", + "2019-01-01 06:10:00+01:00", + "2019-01-01 06:11:00+01:00", + "2019-01-01 06:12:00+01:00", + "2019-01-01 06:13:00+01:00", + "2019-01-01 06:14:00+01:00", + "2019-01-01 06:15:00+01:00", + "2019-01-01 06:16:00+01:00", + "2019-01-01 06:17:00+01:00", + "2019-01-01 06:18:00+01:00", + "2019-01-01 06:19:00+01:00", + "2019-01-01 06:20:00+01:00", + "2019-01-01 06:21:00+01:00", + "2019-01-01 06:22:00+01:00", + "2019-01-01 06:23:00+01:00", + "2019-01-01 06:24:00+01:00", + "2019-01-01 06:25:00+01:00", + "2019-01-01 06:26:00+01:00", + "2019-01-01 06:27:00+01:00", + "2019-01-01 06:28:00+01:00", + "2019-01-01 06:29:00+01:00", + "2019-01-01 06:30:00+01:00", + "2019-01-01 06:31:00+01:00", + "2019-01-01 06:32:00+01:00", + "2019-01-01 06:33:00+01:00", + "2019-01-01 06:34:00+01:00", + "2019-01-01 06:35:00+01:00", + "2019-01-01 06:36:00+01:00", + "2019-01-01 06:37:00+01:00", + "2019-01-01 06:38:00+01:00", + "2019-01-01 06:39:00+01:00", + "2019-01-01 06:40:00+01:00", + "2019-01-01 06:41:00+01:00", + "2019-01-01 06:42:00+01:00", + "2019-01-01 06:43:00+01:00", + "2019-01-01 06:44:00+01:00", + "2019-01-01 06:45:00+01:00", + "2019-01-01 06:46:00+01:00", + "2019-01-01 06:47:00+01:00", + "2019-01-01 06:48:00+01:00", + "2019-01-01 06:49:00+01:00", + "2019-01-01 06:50:00+01:00", + "2019-01-01 06:51:00+01:00", + "2019-01-01 06:52:00+01:00", + "2019-01-01 06:53:00+01:00", + "2019-01-01 06:54:00+01:00", + "2019-01-01 06:55:00+01:00", + "2019-01-01 06:56:00+01:00", + "2019-01-01 06:57:00+01:00", + "2019-01-01 06:58:00+01:00", + "2019-01-01 06:59:00+01:00", + "2019-01-01 07:00:00+01:00", + "2019-01-01 07:01:00+01:00", + "2019-01-01 07:02:00+01:00", + "2019-01-01 07:03:00+01:00", + "2019-01-01 07:04:00+01:00", + "2019-01-01 07:05:00+01:00", + "2019-01-01 07:06:00+01:00", + "2019-01-01 07:07:00+01:00", + "2019-01-01 07:08:00+01:00", + "2019-01-01 07:09:00+01:00", + "2019-01-01 07:10:00+01:00", + "2019-01-01 07:11:00+01:00", + "2019-01-01 07:12:00+01:00", + "2019-01-01 07:13:00+01:00", + "2019-01-01 07:14:00+01:00", + "2019-01-01 07:15:00+01:00", + "2019-01-01 07:16:00+01:00", + "2019-01-01 07:17:00+01:00", + "2019-01-01 07:18:00+01:00", + "2019-01-01 07:19:00+01:00", + "2019-01-01 07:20:00+01:00", + "2019-01-01 07:21:00+01:00", + "2019-01-01 07:22:00+01:00", + "2019-01-01 07:23:00+01:00", + "2019-01-01 07:24:00+01:00", + "2019-01-01 07:25:00+01:00", + "2019-01-01 07:26:00+01:00", + "2019-01-01 07:27:00+01:00", + "2019-01-01 07:28:00+01:00", + "2019-01-01 07:29:00+01:00", + "2019-01-01 07:30:00+01:00", + "2019-01-01 07:31:00+01:00", + "2019-01-01 07:32:00+01:00", + "2019-01-01 07:33:00+01:00", + "2019-01-01 07:34:00+01:00", + "2019-01-01 07:35:00+01:00", + "2019-01-01 07:36:00+01:00", + "2019-01-01 07:37:00+01:00", + "2019-01-01 07:38:00+01:00", + "2019-01-01 07:39:00+01:00", + "2019-01-01 07:40:00+01:00", + "2019-01-01 07:41:00+01:00", + "2019-01-01 07:42:00+01:00", + "2019-01-01 07:43:00+01:00", + "2019-01-01 07:44:00+01:00", + "2019-01-01 07:45:00+01:00", + "2019-01-01 07:46:00+01:00", + "2019-01-01 07:47:00+01:00", + "2019-01-01 07:48:00+01:00", + "2019-01-01 07:49:00+01:00", + "2019-01-01 07:50:00+01:00", + "2019-01-01 07:51:00+01:00", + "2019-01-01 07:52:00+01:00", + "2019-01-01 07:53:00+01:00", + "2019-01-01 07:54:00+01:00", + "2019-01-01 07:55:00+01:00", + "2019-01-01 07:56:00+01:00", + "2019-01-01 07:57:00+01:00", + "2019-01-01 07:58:00+01:00", + "2019-01-01 07:59:00+01:00", + "2019-01-01 08:00:00+01:00", + "2019-01-01 08:01:00+01:00", + "2019-01-01 08:02:00+01:00", + "2019-01-01 08:03:00+01:00", + "2019-01-01 08:04:00+01:00", + "2019-01-01 08:05:00+01:00", + "2019-01-01 08:06:00+01:00", + "2019-01-01 08:07:00+01:00", + "2019-01-01 08:08:00+01:00", + "2019-01-01 08:09:00+01:00", + "2019-01-01 08:10:00+01:00", + "2019-01-01 08:11:00+01:00", + "2019-01-01 08:12:00+01:00", + "2019-01-01 08:13:00+01:00", + "2019-01-01 08:14:00+01:00", + "2019-01-01 08:15:00+01:00", + "2019-01-01 08:16:00+01:00", + "2019-01-01 08:17:00+01:00", + "2019-01-01 08:18:00+01:00", + "2019-01-01 08:19:00+01:00", + "2019-01-01 08:20:00+01:00", + "2019-01-01 08:21:00+01:00", + "2019-01-01 08:22:00+01:00", + "2019-01-01 08:23:00+01:00", + "2019-01-01 08:24:00+01:00", + "2019-01-01 08:25:00+01:00", + "2019-01-01 08:26:00+01:00", + "2019-01-01 08:27:00+01:00", + "2019-01-01 08:28:00+01:00", + "2019-01-01 08:29:00+01:00", + "2019-01-01 08:30:00+01:00", + "2019-01-01 08:31:00+01:00", + "2019-01-01 08:32:00+01:00", + "2019-01-01 08:33:00+01:00", + "2019-01-01 08:34:00+01:00", + "2019-01-01 08:35:00+01:00", + "2019-01-01 08:36:00+01:00", + "2019-01-01 08:37:00+01:00", + "2019-01-01 08:38:00+01:00", + "2019-01-01 08:39:00+01:00", + "2019-01-01 08:40:00+01:00", + "2019-01-01 08:41:00+01:00", + "2019-01-01 08:42:00+01:00", + "2019-01-01 08:43:00+01:00", + "2019-01-01 08:44:00+01:00", + "2019-01-01 08:45:00+01:00", + "2019-01-01 08:46:00+01:00", + "2019-01-01 08:47:00+01:00", + "2019-01-01 08:48:00+01:00", + "2019-01-01 08:49:00+01:00", + "2019-01-01 08:50:00+01:00", + "2019-01-01 08:51:00+01:00", + "2019-01-01 08:52:00+01:00", + "2019-01-01 08:53:00+01:00", + "2019-01-01 08:54:00+01:00", + "2019-01-01 08:55:00+01:00", + "2019-01-01 08:56:00+01:00", + "2019-01-01 08:57:00+01:00", + "2019-01-01 08:58:00+01:00", + "2019-01-01 08:59:00+01:00", + "2019-01-01 09:00:00+01:00", + "2019-01-01 09:01:00+01:00", + "2019-01-01 09:02:00+01:00", + "2019-01-01 09:03:00+01:00", + "2019-01-01 09:04:00+01:00", + "2019-01-01 09:05:00+01:00", + "2019-01-01 09:06:00+01:00", + "2019-01-01 09:07:00+01:00", + "2019-01-01 09:08:00+01:00", + "2019-01-01 09:09:00+01:00", + "2019-01-01 09:10:00+01:00", + "2019-01-01 09:11:00+01:00", + "2019-01-01 09:12:00+01:00", + "2019-01-01 09:13:00+01:00", + "2019-01-01 09:14:00+01:00", + "2019-01-01 09:15:00+01:00", + "2019-01-01 09:16:00+01:00", + "2019-01-01 09:17:00+01:00", + "2019-01-01 09:18:00+01:00", + "2019-01-01 09:19:00+01:00", + "2019-01-01 09:20:00+01:00", + "2019-01-01 09:21:00+01:00", + "2019-01-01 09:22:00+01:00", + "2019-01-01 09:23:00+01:00", + "2019-01-01 09:24:00+01:00", + "2019-01-01 09:25:00+01:00", + "2019-01-01 09:26:00+01:00", + "2019-01-01 09:27:00+01:00", + "2019-01-01 09:28:00+01:00", + "2019-01-01 09:29:00+01:00", + "2019-01-01 09:30:00+01:00", + "2019-01-01 09:31:00+01:00", + "2019-01-01 09:32:00+01:00", + "2019-01-01 09:33:00+01:00", + "2019-01-01 09:34:00+01:00", + "2019-01-01 09:35:00+01:00", + "2019-01-01 09:36:00+01:00", + "2019-01-01 09:37:00+01:00", + "2019-01-01 09:38:00+01:00", + "2019-01-01 09:39:00+01:00", + "2019-01-01 09:40:00+01:00", + "2019-01-01 09:41:00+01:00", + "2019-01-01 09:42:00+01:00", + "2019-01-01 09:43:00+01:00", + "2019-01-01 09:44:00+01:00", + "2019-01-01 09:45:00+01:00", + "2019-01-01 09:46:00+01:00", + "2019-01-01 09:47:00+01:00", + "2019-01-01 09:48:00+01:00", + "2019-01-01 09:49:00+01:00", + "2019-01-01 09:50:00+01:00", + "2019-01-01 09:51:00+01:00", + "2019-01-01 09:52:00+01:00", + "2019-01-01 09:53:00+01:00", + "2019-01-01 09:54:00+01:00", + "2019-01-01 09:55:00+01:00", + "2019-01-01 09:56:00+01:00", + "2019-01-01 09:57:00+01:00", + "2019-01-01 09:58:00+01:00", + "2019-01-01 09:59:00+01:00", + "2019-01-01 10:00:00+01:00", + "2019-01-01 10:01:00+01:00", + "2019-01-01 10:02:00+01:00", + "2019-01-01 10:03:00+01:00", + "2019-01-01 10:04:00+01:00", + "2019-01-01 10:05:00+01:00", + "2019-01-01 10:06:00+01:00", + "2019-01-01 10:07:00+01:00", + "2019-01-01 10:08:00+01:00", + "2019-01-01 10:09:00+01:00", + "2019-01-01 10:10:00+01:00", + "2019-01-01 10:11:00+01:00", + "2019-01-01 10:12:00+01:00", + "2019-01-01 10:13:00+01:00", + "2019-01-01 10:14:00+01:00", + "2019-01-01 10:15:00+01:00", + "2019-01-01 10:16:00+01:00", + "2019-01-01 10:17:00+01:00", + "2019-01-01 10:18:00+01:00", + "2019-01-01 10:19:00+01:00", + "2019-01-01 10:20:00+01:00", + "2019-01-01 10:21:00+01:00", + "2019-01-01 10:22:00+01:00", + "2019-01-01 10:23:00+01:00", + "2019-01-01 10:24:00+01:00", + "2019-01-01 10:25:00+01:00", + "2019-01-01 10:26:00+01:00", + "2019-01-01 10:27:00+01:00", + "2019-01-01 10:28:00+01:00", + "2019-01-01 10:29:00+01:00", + "2019-01-01 10:30:00+01:00", + "2019-01-01 10:31:00+01:00", + "2019-01-01 10:32:00+01:00", + "2019-01-01 10:33:00+01:00", + "2019-01-01 10:34:00+01:00", + "2019-01-01 10:35:00+01:00", + "2019-01-01 10:36:00+01:00", + "2019-01-01 10:37:00+01:00", + "2019-01-01 10:38:00+01:00", + "2019-01-01 10:39:00+01:00", + "2019-01-01 10:40:00+01:00", + "2019-01-01 10:41:00+01:00", + "2019-01-01 10:42:00+01:00", + "2019-01-01 10:43:00+01:00", + "2019-01-01 10:44:00+01:00", + "2019-01-01 10:45:00+01:00", + "2019-01-01 10:46:00+01:00", + "2019-01-01 10:47:00+01:00", + "2019-01-01 10:48:00+01:00", + "2019-01-01 10:49:00+01:00", + "2019-01-01 10:50:00+01:00", + "2019-01-01 10:51:00+01:00", + "2019-01-01 10:52:00+01:00", + "2019-01-01 10:53:00+01:00", + "2019-01-01 10:54:00+01:00", + "2019-01-01 10:55:00+01:00", + "2019-01-01 10:56:00+01:00", + "2019-01-01 10:57:00+01:00", + "2019-01-01 10:58:00+01:00", + "2019-01-01 10:59:00+01:00", + "2019-01-01 11:00:00+01:00", + "2019-01-01 11:01:00+01:00", + "2019-01-01 11:02:00+01:00", + "2019-01-01 11:03:00+01:00", + "2019-01-01 11:04:00+01:00", + "2019-01-01 11:05:00+01:00", + "2019-01-01 11:06:00+01:00", + "2019-01-01 11:07:00+01:00", + "2019-01-01 11:08:00+01:00", + "2019-01-01 11:09:00+01:00", + "2019-01-01 11:10:00+01:00", + "2019-01-01 11:11:00+01:00", + "2019-01-01 11:12:00+01:00", + "2019-01-01 11:13:00+01:00", + "2019-01-01 11:14:00+01:00", + "2019-01-01 11:15:00+01:00", + "2019-01-01 11:16:00+01:00", + "2019-01-01 11:17:00+01:00", + "2019-01-01 11:18:00+01:00", + "2019-01-01 11:19:00+01:00", + "2019-01-01 11:20:00+01:00", + "2019-01-01 11:21:00+01:00", + "2019-01-01 11:22:00+01:00", + "2019-01-01 11:23:00+01:00", + "2019-01-01 11:24:00+01:00", + "2019-01-01 11:25:00+01:00", + "2019-01-01 11:26:00+01:00", + "2019-01-01 11:27:00+01:00", + "2019-01-01 11:28:00+01:00", + "2019-01-01 11:29:00+01:00", + "2019-01-01 11:30:00+01:00", + "2019-01-01 11:31:00+01:00", + "2019-01-01 11:32:00+01:00", + "2019-01-01 11:33:00+01:00", + "2019-01-01 11:34:00+01:00", + "2019-01-01 11:35:00+01:00", + "2019-01-01 11:36:00+01:00", + "2019-01-01 11:37:00+01:00", + "2019-01-01 11:38:00+01:00", + "2019-01-01 11:39:00+01:00", + "2019-01-01 11:40:00+01:00", + "2019-01-01 11:41:00+01:00", + "2019-01-01 11:42:00+01:00", + "2019-01-01 11:43:00+01:00", + "2019-01-01 11:44:00+01:00", + "2019-01-01 11:45:00+01:00", + "2019-01-01 11:46:00+01:00", + "2019-01-01 11:47:00+01:00", + "2019-01-01 11:48:00+01:00", + "2019-01-01 11:49:00+01:00", + "2019-01-01 11:50:00+01:00", + "2019-01-01 11:51:00+01:00", + "2019-01-01 11:52:00+01:00", + "2019-01-01 11:53:00+01:00", + "2019-01-01 11:54:00+01:00", + "2019-01-01 11:55:00+01:00", + "2019-01-01 11:56:00+01:00", + "2019-01-01 11:57:00+01:00", + "2019-01-01 11:58:00+01:00", + "2019-01-01 11:59:00+01:00", + "2019-01-01 12:00:00+01:00", + "2019-01-01 12:01:00+01:00", + "2019-01-01 12:02:00+01:00", + "2019-01-01 12:03:00+01:00", + "2019-01-01 12:04:00+01:00", + "2019-01-01 12:05:00+01:00", + "2019-01-01 12:06:00+01:00", + "2019-01-01 12:07:00+01:00", + "2019-01-01 12:08:00+01:00", + "2019-01-01 12:09:00+01:00", + "2019-01-01 12:10:00+01:00", + "2019-01-01 12:11:00+01:00", + "2019-01-01 12:12:00+01:00", + "2019-01-01 12:13:00+01:00", + "2019-01-01 12:14:00+01:00", + "2019-01-01 12:15:00+01:00", + "2019-01-01 12:16:00+01:00", + "2019-01-01 12:17:00+01:00", + "2019-01-01 12:18:00+01:00", + "2019-01-01 12:19:00+01:00", + "2019-01-01 12:20:00+01:00", + "2019-01-01 12:21:00+01:00", + "2019-01-01 12:22:00+01:00", + "2019-01-01 12:23:00+01:00", + "2019-01-01 12:24:00+01:00", + "2019-01-01 12:25:00+01:00", + "2019-01-01 12:26:00+01:00", + "2019-01-01 12:27:00+01:00", + "2019-01-01 12:28:00+01:00", + "2019-01-01 12:29:00+01:00", + "2019-01-01 12:30:00+01:00", + "2019-01-01 12:31:00+01:00", + "2019-01-01 12:32:00+01:00", + "2019-01-01 12:33:00+01:00", + "2019-01-01 12:34:00+01:00", + "2019-01-01 12:35:00+01:00", + "2019-01-01 12:36:00+01:00", + "2019-01-01 12:37:00+01:00", + "2019-01-01 12:38:00+01:00", + "2019-01-01 12:39:00+01:00", + "2019-01-01 12:40:00+01:00", + "2019-01-01 12:41:00+01:00", + "2019-01-01 12:42:00+01:00", + "2019-01-01 12:43:00+01:00", + "2019-01-01 12:44:00+01:00", + "2019-01-01 12:45:00+01:00", + "2019-01-01 12:46:00+01:00", + "2019-01-01 12:47:00+01:00", + "2019-01-01 12:48:00+01:00", + "2019-01-01 12:49:00+01:00", + "2019-01-01 12:50:00+01:00", + "2019-01-01 12:51:00+01:00", + "2019-01-01 12:52:00+01:00", + "2019-01-01 12:53:00+01:00", + "2019-01-01 12:54:00+01:00", + "2019-01-01 12:55:00+01:00", + "2019-01-01 12:56:00+01:00", + "2019-01-01 12:57:00+01:00", + "2019-01-01 12:58:00+01:00", + "2019-01-01 12:59:00+01:00", + "2019-01-01 13:00:00+01:00", + "2019-01-01 13:01:00+01:00", + "2019-01-01 13:02:00+01:00", + "2019-01-01 13:03:00+01:00", + "2019-01-01 13:04:00+01:00", + "2019-01-01 13:05:00+01:00", + "2019-01-01 13:06:00+01:00", + "2019-01-01 13:07:00+01:00", + "2019-01-01 13:08:00+01:00", + "2019-01-01 13:09:00+01:00", + "2019-01-01 13:10:00+01:00", + "2019-01-01 13:11:00+01:00", + "2019-01-01 13:12:00+01:00", + "2019-01-01 13:13:00+01:00", + "2019-01-01 13:14:00+01:00", + "2019-01-01 13:15:00+01:00", + "2019-01-01 13:16:00+01:00", + "2019-01-01 13:17:00+01:00", + "2019-01-01 13:18:00+01:00", + "2019-01-01 13:19:00+01:00", + "2019-01-01 13:20:00+01:00", + "2019-01-01 13:21:00+01:00", + "2019-01-01 13:22:00+01:00", + "2019-01-01 13:23:00+01:00", + "2019-01-01 13:24:00+01:00", + "2019-01-01 13:25:00+01:00", + "2019-01-01 13:26:00+01:00", + "2019-01-01 13:27:00+01:00", + "2019-01-01 13:28:00+01:00", + "2019-01-01 13:29:00+01:00", + "2019-01-01 13:30:00+01:00", + "2019-01-01 13:31:00+01:00", + "2019-01-01 13:32:00+01:00", + "2019-01-01 13:33:00+01:00", + "2019-01-01 13:34:00+01:00", + "2019-01-01 13:35:00+01:00", + "2019-01-01 13:36:00+01:00", + "2019-01-01 13:37:00+01:00", + "2019-01-01 13:38:00+01:00", + "2019-01-01 13:39:00+01:00", + "2019-01-01 13:40:00+01:00", + "2019-01-01 13:41:00+01:00", + "2019-01-01 13:42:00+01:00", + "2019-01-01 13:43:00+01:00", + "2019-01-01 13:44:00+01:00", + "2019-01-01 13:45:00+01:00", + "2019-01-01 13:46:00+01:00", + "2019-01-01 13:47:00+01:00", + "2019-01-01 13:48:00+01:00", + "2019-01-01 13:49:00+01:00", + "2019-01-01 13:50:00+01:00", + "2019-01-01 13:51:00+01:00", + "2019-01-01 13:52:00+01:00", + "2019-01-01 13:53:00+01:00", + "2019-01-01 13:54:00+01:00", + "2019-01-01 13:55:00+01:00", + "2019-01-01 13:56:00+01:00", + "2019-01-01 13:57:00+01:00", + "2019-01-01 13:58:00+01:00", + "2019-01-01 13:59:00+01:00", + "2019-01-01 14:00:00+01:00", + "2019-01-01 14:01:00+01:00", + "2019-01-01 14:02:00+01:00", + "2019-01-01 14:03:00+01:00", + "2019-01-01 14:04:00+01:00", + "2019-01-01 14:05:00+01:00", + "2019-01-01 14:06:00+01:00", + "2019-01-01 14:07:00+01:00", + "2019-01-01 14:08:00+01:00", + "2019-01-01 14:09:00+01:00", + "2019-01-01 14:10:00+01:00", + "2019-01-01 14:11:00+01:00", + "2019-01-01 14:12:00+01:00", + "2019-01-01 14:13:00+01:00", + "2019-01-01 14:14:00+01:00", + "2019-01-01 14:15:00+01:00", + "2019-01-01 14:16:00+01:00", + "2019-01-01 14:17:00+01:00", + "2019-01-01 14:18:00+01:00", + "2019-01-01 14:19:00+01:00", + "2019-01-01 14:20:00+01:00", + "2019-01-01 14:21:00+01:00", + "2019-01-01 14:22:00+01:00", + "2019-01-01 14:23:00+01:00", + "2019-01-01 14:24:00+01:00", + "2019-01-01 14:25:00+01:00", + "2019-01-01 14:26:00+01:00", + "2019-01-01 14:27:00+01:00", + "2019-01-01 14:28:00+01:00", + "2019-01-01 14:29:00+01:00", + "2019-01-01 14:30:00+01:00", + "2019-01-01 14:31:00+01:00", + "2019-01-01 14:32:00+01:00", + "2019-01-01 14:33:00+01:00", + "2019-01-01 14:34:00+01:00", + "2019-01-01 14:35:00+01:00", + "2019-01-01 14:36:00+01:00", + "2019-01-01 14:37:00+01:00", + "2019-01-01 14:38:00+01:00", + "2019-01-01 14:39:00+01:00", + "2019-01-01 14:40:00+01:00", + "2019-01-01 14:41:00+01:00", + "2019-01-01 14:42:00+01:00", + "2019-01-01 14:43:00+01:00", + "2019-01-01 14:44:00+01:00", + "2019-01-01 14:45:00+01:00", + "2019-01-01 14:46:00+01:00", + "2019-01-01 14:47:00+01:00", + "2019-01-01 14:48:00+01:00", + "2019-01-01 14:49:00+01:00", + "2019-01-01 14:50:00+01:00", + "2019-01-01 14:51:00+01:00", + "2019-01-01 14:52:00+01:00", + "2019-01-01 14:53:00+01:00", + "2019-01-01 14:54:00+01:00", + "2019-01-01 14:55:00+01:00", + "2019-01-01 14:56:00+01:00", + "2019-01-01 14:57:00+01:00", + "2019-01-01 14:58:00+01:00", + "2019-01-01 14:59:00+01:00", + "2019-01-01 15:00:00+01:00", + "2019-01-01 15:01:00+01:00", + "2019-01-01 15:02:00+01:00", + "2019-01-01 15:03:00+01:00", + "2019-01-01 15:04:00+01:00", + "2019-01-01 15:05:00+01:00", + "2019-01-01 15:06:00+01:00", + "2019-01-01 15:07:00+01:00", + "2019-01-01 15:08:00+01:00", + "2019-01-01 15:09:00+01:00", + "2019-01-01 15:10:00+01:00", + "2019-01-01 15:11:00+01:00", + "2019-01-01 15:12:00+01:00", + "2019-01-01 15:13:00+01:00", + "2019-01-01 15:14:00+01:00", + "2019-01-01 15:15:00+01:00", + "2019-01-01 15:16:00+01:00", + "2019-01-01 15:17:00+01:00", + "2019-01-01 15:18:00+01:00", + "2019-01-01 15:19:00+01:00", + "2019-01-01 15:20:00+01:00", + "2019-01-01 15:21:00+01:00", + "2019-01-01 15:22:00+01:00", + "2019-01-01 15:23:00+01:00", + "2019-01-01 15:24:00+01:00", + "2019-01-01 15:25:00+01:00", + "2019-01-01 15:26:00+01:00", + "2019-01-01 15:27:00+01:00", + "2019-01-01 15:28:00+01:00", + "2019-01-01 15:29:00+01:00", + "2019-01-01 15:30:00+01:00", + "2019-01-01 15:31:00+01:00", + "2019-01-01 15:32:00+01:00", + "2019-01-01 15:33:00+01:00", + "2019-01-01 15:34:00+01:00", + "2019-01-01 15:35:00+01:00", + "2019-01-01 15:36:00+01:00", + "2019-01-01 15:37:00+01:00", + "2019-01-01 15:38:00+01:00", + "2019-01-01 15:39:00+01:00", + "2019-01-01 15:40:00+01:00", + "2019-01-01 15:41:00+01:00", + "2019-01-01 15:42:00+01:00", + "2019-01-01 15:43:00+01:00", + "2019-01-01 15:44:00+01:00", + "2019-01-01 15:45:00+01:00", + "2019-01-01 15:46:00+01:00", + "2019-01-01 15:47:00+01:00", + "2019-01-01 15:48:00+01:00", + "2019-01-01 15:49:00+01:00", + "2019-01-01 15:50:00+01:00", + "2019-01-01 15:51:00+01:00", + "2019-01-01 15:52:00+01:00", + "2019-01-01 15:53:00+01:00", + "2019-01-01 15:54:00+01:00", + "2019-01-01 15:55:00+01:00", + "2019-01-01 15:56:00+01:00", + "2019-01-01 15:57:00+01:00", + "2019-01-01 15:58:00+01:00", + "2019-01-01 15:59:00+01:00", + "2019-01-01 16:00:00+01:00", + "2019-01-01 16:01:00+01:00", + "2019-01-01 16:02:00+01:00", + "2019-01-01 16:03:00+01:00", + "2019-01-01 16:04:00+01:00", + "2019-01-01 16:05:00+01:00", + "2019-01-01 16:06:00+01:00", + "2019-01-01 16:07:00+01:00", + "2019-01-01 16:08:00+01:00", + "2019-01-01 16:09:00+01:00", + "2019-01-01 16:10:00+01:00", + "2019-01-01 16:11:00+01:00", + "2019-01-01 16:12:00+01:00", + "2019-01-01 16:13:00+01:00", + "2019-01-01 16:14:00+01:00", + "2019-01-01 16:15:00+01:00", + "2019-01-01 16:16:00+01:00", + "2019-01-01 16:17:00+01:00", + "2019-01-01 16:18:00+01:00", + "2019-01-01 16:19:00+01:00", + "2019-01-01 16:20:00+01:00", + "2019-01-01 16:21:00+01:00", + "2019-01-01 16:22:00+01:00", + "2019-01-01 16:23:00+01:00", + "2019-01-01 16:24:00+01:00", + "2019-01-01 16:25:00+01:00", + "2019-01-01 16:26:00+01:00", + "2019-01-01 16:27:00+01:00", + "2019-01-01 16:28:00+01:00", + "2019-01-01 16:29:00+01:00", + "2019-01-01 16:30:00+01:00", + "2019-01-01 16:31:00+01:00", + "2019-01-01 16:32:00+01:00", + "2019-01-01 16:33:00+01:00", + "2019-01-01 16:34:00+01:00", + "2019-01-01 16:35:00+01:00", + "2019-01-01 16:36:00+01:00", + "2019-01-01 16:37:00+01:00", + "2019-01-01 16:38:00+01:00", + "2019-01-01 16:39:00+01:00", + "2019-01-01 16:40:00+01:00", + "2019-01-01 16:41:00+01:00", + "2019-01-01 16:42:00+01:00", + "2019-01-01 16:43:00+01:00", + "2019-01-01 16:44:00+01:00", + "2019-01-01 16:45:00+01:00", + "2019-01-01 16:46:00+01:00", + "2019-01-01 16:47:00+01:00", + "2019-01-01 16:48:00+01:00", + "2019-01-01 16:49:00+01:00", + "2019-01-01 16:50:00+01:00", + "2019-01-01 16:51:00+01:00", + "2019-01-01 16:52:00+01:00", + "2019-01-01 16:53:00+01:00", + "2019-01-01 16:54:00+01:00", + "2019-01-01 16:55:00+01:00", + "2019-01-01 16:56:00+01:00", + "2019-01-01 16:57:00+01:00", + "2019-01-01 16:58:00+01:00", + "2019-01-01 16:59:00+01:00", + "2019-01-01 17:00:00+01:00", + "2019-01-01 17:01:00+01:00", + "2019-01-01 17:02:00+01:00", + "2019-01-01 17:03:00+01:00", + "2019-01-01 17:04:00+01:00", + "2019-01-01 17:05:00+01:00", + "2019-01-01 17:06:00+01:00", + "2019-01-01 17:07:00+01:00", + "2019-01-01 17:08:00+01:00", + "2019-01-01 17:09:00+01:00", + "2019-01-01 17:10:00+01:00", + "2019-01-01 17:11:00+01:00", + "2019-01-01 17:12:00+01:00", + "2019-01-01 17:13:00+01:00", + "2019-01-01 17:14:00+01:00", + "2019-01-01 17:15:00+01:00", + "2019-01-01 17:16:00+01:00", + "2019-01-01 17:17:00+01:00", + "2019-01-01 17:18:00+01:00", + "2019-01-01 17:19:00+01:00", + "2019-01-01 17:20:00+01:00", + "2019-01-01 17:21:00+01:00", + "2019-01-01 17:22:00+01:00", + "2019-01-01 17:23:00+01:00", + "2019-01-01 17:24:00+01:00", + "2019-01-01 17:25:00+01:00", + "2019-01-01 17:26:00+01:00", + "2019-01-01 17:27:00+01:00", + "2019-01-01 17:28:00+01:00", + "2019-01-01 17:29:00+01:00", + "2019-01-01 17:30:00+01:00", + "2019-01-01 17:31:00+01:00", + "2019-01-01 17:32:00+01:00", + "2019-01-01 17:33:00+01:00", + "2019-01-01 17:34:00+01:00", + "2019-01-01 17:35:00+01:00", + "2019-01-01 17:36:00+01:00", + "2019-01-01 17:37:00+01:00", + "2019-01-01 17:38:00+01:00", + "2019-01-01 17:39:00+01:00", + "2019-01-01 17:40:00+01:00", + "2019-01-01 17:41:00+01:00", + "2019-01-01 17:42:00+01:00", + "2019-01-01 17:43:00+01:00", + "2019-01-01 17:44:00+01:00", + "2019-01-01 17:45:00+01:00", + "2019-01-01 17:46:00+01:00", + "2019-01-01 17:47:00+01:00", + "2019-01-01 17:48:00+01:00", + "2019-01-01 17:49:00+01:00", + "2019-01-01 17:50:00+01:00", + "2019-01-01 17:51:00+01:00", + "2019-01-01 17:52:00+01:00", + "2019-01-01 17:53:00+01:00", + "2019-01-01 17:54:00+01:00", + "2019-01-01 17:55:00+01:00", + "2019-01-01 17:56:00+01:00", + "2019-01-01 17:57:00+01:00", + "2019-01-01 17:58:00+01:00", + "2019-01-01 17:59:00+01:00", + "2019-01-01 18:00:00+01:00", + "2019-01-01 18:01:00+01:00", + "2019-01-01 18:02:00+01:00", + "2019-01-01 18:03:00+01:00", + "2019-01-01 18:04:00+01:00", + "2019-01-01 18:05:00+01:00", + "2019-01-01 18:06:00+01:00", + "2019-01-01 18:07:00+01:00", + "2019-01-01 18:08:00+01:00", + "2019-01-01 18:09:00+01:00", + "2019-01-01 18:10:00+01:00", + "2019-01-01 18:11:00+01:00", + "2019-01-01 18:12:00+01:00", + "2019-01-01 18:13:00+01:00", + "2019-01-01 18:14:00+01:00", + "2019-01-01 18:15:00+01:00", + "2019-01-01 18:16:00+01:00", + "2019-01-01 18:17:00+01:00", + "2019-01-01 18:18:00+01:00", + "2019-01-01 18:19:00+01:00", + "2019-01-01 18:20:00+01:00", + "2019-01-01 18:21:00+01:00", + "2019-01-01 18:22:00+01:00", + "2019-01-01 18:23:00+01:00", + "2019-01-01 18:24:00+01:00", + "2019-01-01 18:25:00+01:00", + "2019-01-01 18:26:00+01:00", + "2019-01-01 18:27:00+01:00", + "2019-01-01 18:28:00+01:00", + "2019-01-01 18:29:00+01:00", + "2019-01-01 18:30:00+01:00", + "2019-01-01 18:31:00+01:00", + "2019-01-01 18:32:00+01:00", + "2019-01-01 18:33:00+01:00", + "2019-01-01 18:34:00+01:00", + "2019-01-01 18:35:00+01:00", + "2019-01-01 18:36:00+01:00", + "2019-01-01 18:37:00+01:00", + "2019-01-01 18:38:00+01:00", + "2019-01-01 18:39:00+01:00", + "2019-01-01 18:40:00+01:00", + "2019-01-01 18:41:00+01:00", + "2019-01-01 18:42:00+01:00", + "2019-01-01 18:43:00+01:00", + "2019-01-01 18:44:00+01:00", + "2019-01-01 18:45:00+01:00", + "2019-01-01 18:46:00+01:00", + "2019-01-01 18:47:00+01:00", + "2019-01-01 18:48:00+01:00", + "2019-01-01 18:49:00+01:00", + "2019-01-01 18:50:00+01:00", + "2019-01-01 18:51:00+01:00", + "2019-01-01 18:52:00+01:00", + "2019-01-01 18:53:00+01:00", + "2019-01-01 18:54:00+01:00", + "2019-01-01 18:55:00+01:00", + "2019-01-01 18:56:00+01:00", + "2019-01-01 18:57:00+01:00", + "2019-01-01 18:58:00+01:00", + "2019-01-01 18:59:00+01:00", + "2019-01-01 19:00:00+01:00", + "2019-01-01 19:01:00+01:00", + "2019-01-01 19:02:00+01:00", + "2019-01-01 19:03:00+01:00", + "2019-01-01 19:04:00+01:00", + "2019-01-01 19:05:00+01:00", + "2019-01-01 19:06:00+01:00", + "2019-01-01 19:07:00+01:00", + "2019-01-01 19:08:00+01:00", + "2019-01-01 19:09:00+01:00", + "2019-01-01 19:10:00+01:00", + "2019-01-01 19:11:00+01:00", + "2019-01-01 19:12:00+01:00", + "2019-01-01 19:13:00+01:00", + "2019-01-01 19:14:00+01:00", + "2019-01-01 19:15:00+01:00", + "2019-01-01 19:16:00+01:00", + "2019-01-01 19:17:00+01:00", + "2019-01-01 19:18:00+01:00", + "2019-01-01 19:19:00+01:00", + "2019-01-01 19:20:00+01:00", + "2019-01-01 19:21:00+01:00", + "2019-01-01 19:22:00+01:00", + "2019-01-01 19:23:00+01:00", + "2019-01-01 19:24:00+01:00", + "2019-01-01 19:25:00+01:00", + "2019-01-01 19:26:00+01:00", + "2019-01-01 19:27:00+01:00", + "2019-01-01 19:28:00+01:00", + "2019-01-01 19:29:00+01:00", + "2019-01-01 19:30:00+01:00", + "2019-01-01 19:31:00+01:00", + "2019-01-01 19:32:00+01:00", + "2019-01-01 19:33:00+01:00", + "2019-01-01 19:34:00+01:00", + "2019-01-01 19:35:00+01:00", + "2019-01-01 19:36:00+01:00", + "2019-01-01 19:37:00+01:00", + "2019-01-01 19:38:00+01:00", + "2019-01-01 19:39:00+01:00", + "2019-01-01 19:40:00+01:00", + "2019-01-01 19:41:00+01:00", + "2019-01-01 19:42:00+01:00", + "2019-01-01 19:43:00+01:00", + "2019-01-01 19:44:00+01:00", + "2019-01-01 19:45:00+01:00", + "2019-01-01 19:46:00+01:00", + "2019-01-01 19:47:00+01:00", + "2019-01-01 19:48:00+01:00", + "2019-01-01 19:49:00+01:00", + "2019-01-01 19:50:00+01:00", + "2019-01-01 19:51:00+01:00", + "2019-01-01 19:52:00+01:00", + "2019-01-01 19:53:00+01:00", + "2019-01-01 19:54:00+01:00", + "2019-01-01 19:55:00+01:00", + "2019-01-01 19:56:00+01:00", + "2019-01-01 19:57:00+01:00", + "2019-01-01 19:58:00+01:00", + "2019-01-01 19:59:00+01:00", + "2019-01-01 20:00:00+01:00", + "2019-01-01 20:01:00+01:00", + "2019-01-01 20:02:00+01:00", + "2019-01-01 20:03:00+01:00", + "2019-01-01 20:04:00+01:00", + "2019-01-01 20:05:00+01:00", + "2019-01-01 20:06:00+01:00", + "2019-01-01 20:07:00+01:00", + "2019-01-01 20:08:00+01:00", + "2019-01-01 20:09:00+01:00", + "2019-01-01 20:10:00+01:00", + "2019-01-01 20:11:00+01:00", + "2019-01-01 20:12:00+01:00", + "2019-01-01 20:13:00+01:00", + "2019-01-01 20:14:00+01:00", + "2019-01-01 20:15:00+01:00", + "2019-01-01 20:16:00+01:00", + "2019-01-01 20:17:00+01:00", + "2019-01-01 20:18:00+01:00", + "2019-01-01 20:19:00+01:00", + "2019-01-01 20:20:00+01:00", + "2019-01-01 20:21:00+01:00", + "2019-01-01 20:22:00+01:00", + "2019-01-01 20:23:00+01:00", + "2019-01-01 20:24:00+01:00", + "2019-01-01 20:25:00+01:00", + "2019-01-01 20:26:00+01:00", + "2019-01-01 20:27:00+01:00", + "2019-01-01 20:28:00+01:00", + "2019-01-01 20:29:00+01:00", + "2019-01-01 20:30:00+01:00", + "2019-01-01 20:31:00+01:00", + "2019-01-01 20:32:00+01:00", + "2019-01-01 20:33:00+01:00", + "2019-01-01 20:34:00+01:00", + "2019-01-01 20:35:00+01:00", + "2019-01-01 20:36:00+01:00", + "2019-01-01 20:37:00+01:00", + "2019-01-01 20:38:00+01:00", + "2019-01-01 20:39:00+01:00", + "2019-01-01 20:40:00+01:00", + "2019-01-01 20:41:00+01:00", + "2019-01-01 20:42:00+01:00", + "2019-01-01 20:43:00+01:00", + "2019-01-01 20:44:00+01:00", + "2019-01-01 20:45:00+01:00", + "2019-01-01 20:46:00+01:00", + "2019-01-01 20:47:00+01:00", + "2019-01-01 20:48:00+01:00", + "2019-01-01 20:49:00+01:00", + "2019-01-01 20:50:00+01:00", + "2019-01-01 20:51:00+01:00", + "2019-01-01 20:52:00+01:00", + "2019-01-01 20:53:00+01:00", + "2019-01-01 20:54:00+01:00", + "2019-01-01 20:55:00+01:00", + "2019-01-01 20:56:00+01:00", + "2019-01-01 20:57:00+01:00", + "2019-01-01 20:58:00+01:00", + "2019-01-01 20:59:00+01:00", + "2019-01-01 21:00:00+01:00", + "2019-01-01 21:01:00+01:00", + "2019-01-01 21:02:00+01:00", + "2019-01-01 21:03:00+01:00", + "2019-01-01 21:04:00+01:00", + "2019-01-01 21:05:00+01:00", + "2019-01-01 21:06:00+01:00", + "2019-01-01 21:07:00+01:00", + "2019-01-01 21:08:00+01:00", + "2019-01-01 21:09:00+01:00", + "2019-01-01 21:10:00+01:00", + "2019-01-01 21:11:00+01:00", + "2019-01-01 21:12:00+01:00", + "2019-01-01 21:13:00+01:00", + "2019-01-01 21:14:00+01:00", + "2019-01-01 21:15:00+01:00", + "2019-01-01 21:16:00+01:00", + "2019-01-01 21:17:00+01:00", + "2019-01-01 21:18:00+01:00", + "2019-01-01 21:19:00+01:00", + "2019-01-01 21:20:00+01:00", + "2019-01-01 21:21:00+01:00", + "2019-01-01 21:22:00+01:00", + "2019-01-01 21:23:00+01:00", + "2019-01-01 21:24:00+01:00", + "2019-01-01 21:25:00+01:00", + "2019-01-01 21:26:00+01:00", + "2019-01-01 21:27:00+01:00", + "2019-01-01 21:28:00+01:00", + "2019-01-01 21:29:00+01:00", + "2019-01-01 21:30:00+01:00", + "2019-01-01 21:31:00+01:00", + "2019-01-01 21:32:00+01:00", + "2019-01-01 21:33:00+01:00", + "2019-01-01 21:34:00+01:00", + "2019-01-01 21:35:00+01:00", + "2019-01-01 21:36:00+01:00", + "2019-01-01 21:37:00+01:00", + "2019-01-01 21:38:00+01:00", + "2019-01-01 21:39:00+01:00", + "2019-01-01 21:40:00+01:00", + "2019-01-01 21:41:00+01:00", + "2019-01-01 21:42:00+01:00", + "2019-01-01 21:43:00+01:00", + "2019-01-01 21:44:00+01:00", + "2019-01-01 21:45:00+01:00", + "2019-01-01 21:46:00+01:00", + "2019-01-01 21:47:00+01:00", + "2019-01-01 21:48:00+01:00", + "2019-01-01 21:49:00+01:00", + "2019-01-01 21:50:00+01:00", + "2019-01-01 21:51:00+01:00", + "2019-01-01 21:52:00+01:00", + "2019-01-01 21:53:00+01:00", + "2019-01-01 21:54:00+01:00", + "2019-01-01 21:55:00+01:00", + "2019-01-01 21:56:00+01:00", + "2019-01-01 21:57:00+01:00", + "2019-01-01 21:58:00+01:00", + "2019-01-01 21:59:00+01:00", + "2019-01-01 22:00:00+01:00", + "2019-01-01 22:01:00+01:00", + "2019-01-01 22:02:00+01:00", + "2019-01-01 22:03:00+01:00", + "2019-01-01 22:04:00+01:00", + "2019-01-01 22:05:00+01:00", + "2019-01-01 22:06:00+01:00", + "2019-01-01 22:07:00+01:00", + "2019-01-01 22:08:00+01:00", + "2019-01-01 22:09:00+01:00", + "2019-01-01 22:10:00+01:00", + "2019-01-01 22:11:00+01:00", + "2019-01-01 22:12:00+01:00", + "2019-01-01 22:13:00+01:00", + "2019-01-01 22:14:00+01:00", + "2019-01-01 22:15:00+01:00", + "2019-01-01 22:16:00+01:00", + "2019-01-01 22:17:00+01:00", + "2019-01-01 22:18:00+01:00", + "2019-01-01 22:19:00+01:00", + "2019-01-01 22:20:00+01:00", + "2019-01-01 22:21:00+01:00", + "2019-01-01 22:22:00+01:00", + "2019-01-01 22:23:00+01:00", + "2019-01-01 22:24:00+01:00", + "2019-01-01 22:25:00+01:00", + "2019-01-01 22:26:00+01:00", + "2019-01-01 22:27:00+01:00", + "2019-01-01 22:28:00+01:00", + "2019-01-01 22:29:00+01:00", + "2019-01-01 22:30:00+01:00", + "2019-01-01 22:31:00+01:00", + "2019-01-01 22:32:00+01:00", + "2019-01-01 22:33:00+01:00", + "2019-01-01 22:34:00+01:00", + "2019-01-01 22:35:00+01:00", + "2019-01-01 22:36:00+01:00", + "2019-01-01 22:37:00+01:00", + "2019-01-01 22:38:00+01:00", + "2019-01-01 22:39:00+01:00", + "2019-01-01 22:40:00+01:00", + "2019-01-01 22:41:00+01:00", + "2019-01-01 22:42:00+01:00", + "2019-01-01 22:43:00+01:00", + "2019-01-01 22:44:00+01:00", + "2019-01-01 22:45:00+01:00", + "2019-01-01 22:46:00+01:00", + "2019-01-01 22:47:00+01:00", + "2019-01-01 22:48:00+01:00", + "2019-01-01 22:49:00+01:00", + "2019-01-01 22:50:00+01:00", + "2019-01-01 22:51:00+01:00", + "2019-01-01 22:52:00+01:00", + "2019-01-01 22:53:00+01:00", + "2019-01-01 22:54:00+01:00", + "2019-01-01 22:55:00+01:00", + "2019-01-01 22:56:00+01:00", + "2019-01-01 22:57:00+01:00", + "2019-01-01 22:58:00+01:00", + "2019-01-01 22:59:00+01:00", + "2019-01-01 23:00:00+01:00", + "2019-01-01 23:01:00+01:00", + "2019-01-01 23:02:00+01:00", + "2019-01-01 23:03:00+01:00", + "2019-01-01 23:04:00+01:00", + "2019-01-01 23:05:00+01:00", + "2019-01-01 23:06:00+01:00", + "2019-01-01 23:07:00+01:00", + "2019-01-01 23:08:00+01:00", + "2019-01-01 23:09:00+01:00", + "2019-01-01 23:10:00+01:00", + "2019-01-01 23:11:00+01:00", + "2019-01-01 23:12:00+01:00", + "2019-01-01 23:13:00+01:00", + "2019-01-01 23:14:00+01:00", + "2019-01-01 23:15:00+01:00", + "2019-01-01 23:16:00+01:00", + "2019-01-01 23:17:00+01:00", + "2019-01-01 23:18:00+01:00", + "2019-01-01 23:19:00+01:00", + "2019-01-01 23:20:00+01:00", + "2019-01-01 23:21:00+01:00", + "2019-01-01 23:22:00+01:00", + "2019-01-01 23:23:00+01:00", + "2019-01-01 23:24:00+01:00", + "2019-01-01 23:25:00+01:00", + "2019-01-01 23:26:00+01:00", + "2019-01-01 23:27:00+01:00", + "2019-01-01 23:28:00+01:00", + "2019-01-01 23:29:00+01:00", + "2019-01-01 23:30:00+01:00", + "2019-01-01 23:31:00+01:00", + "2019-01-01 23:32:00+01:00", + "2019-01-01 23:33:00+01:00", + "2019-01-01 23:34:00+01:00", + "2019-01-01 23:35:00+01:00", + "2019-01-01 23:36:00+01:00", + "2019-01-01 23:37:00+01:00", + "2019-01-01 23:38:00+01:00", + "2019-01-01 23:39:00+01:00", + "2019-01-01 23:40:00+01:00", + "2019-01-01 23:41:00+01:00", + "2019-01-01 23:42:00+01:00", + "2019-01-01 23:43:00+01:00", + "2019-01-01 23:44:00+01:00", + "2019-01-01 23:45:00+01:00", + "2019-01-01 23:46:00+01:00", + "2019-01-01 23:47:00+01:00", + "2019-01-01 23:48:00+01:00", + "2019-01-01 23:49:00+01:00", + "2019-01-01 23:50:00+01:00", + "2019-01-01 23:51:00+01:00", + "2019-01-01 23:52:00+01:00", + "2019-01-01 23:53:00+01:00", + "2019-01-01 23:54:00+01:00", + "2019-01-01 23:55:00+01:00", + "2019-01-01 23:56:00+01:00", + "2019-01-01 23:57:00+01:00", + "2019-01-01 23:58:00+01:00", + "2019-01-01 23:59:00+01:00" + ], + "xaxis": "x2", + "y": [ + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5 + ], + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": { + "size": 16 + }, + "showarrow": false, + "text": "Input (MW)", + "x": 0.225, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": { + "size": 16 + }, + "showarrow": false, + "text": "Output (MW)", + "x": 0.775, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + } + ], + "autosize": true, + "legend": { + "bgcolor": "#F5F6F9", + "font": { + "color": "#4D5663" + } + }, + "paper_bgcolor": "#F5F6F9", + "plot_bgcolor": "#F5F6F9", + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "font": { + "color": "#4D5663" + }, + "text": "Gasboiler" + }, + "xaxis": { + "anchor": "y", + "autorange": true, + "domain": [ + 0, + 0.45 + ], + "gridcolor": "#E1E5ED", + "range": [ + "2019-01-01", + "2019-01-01 23:59" + ], + "showgrid": true, + "tickfont": { + "color": "#4D5663" + }, + "title": { + "font": { + "color": "#4D5663" + }, + "text": "" + }, + "type": "date", + "zerolinecolor": "#E1E5ED" + }, + "xaxis2": { + "anchor": "y2", + "autorange": true, + "domain": [ + 0.55, + 1 + ], + "gridcolor": "#E1E5ED", + "range": [ + "2019-01-01", + "2019-01-01 23:59" + ], + "showgrid": true, + "tickfont": { + "color": "#4D5663" + }, + "title": { + "font": { + "color": "#4D5663" + }, + "text": "" + }, + "type": "date", + "zerolinecolor": "#E1E5ED" + }, + "yaxis": { + "anchor": "x", + "autorange": true, + "domain": [ + 0, + 1 + ], + "gridcolor": "#E1E5ED", + "range": [ + -6.555555555555555, + -4.555555555555555 + ], + "showgrid": true, + "tickfont": { + "color": "#4D5663" + }, + "title": { + "font": { + "color": "#4D5663" + }, + "text": "" + }, + "type": "linear", + "zerolinecolor": "#E1E5ED" + }, + "yaxis2": { + "anchor": "x2", + "autorange": true, + "domain": [ + 0, + 1 + ], + "gridcolor": "#E1E5ED", + "range": [ + 4, + 6 + ], + "showgrid": true, + "tickfont": { + "color": "#4D5663" + }, + "title": { + "font": { + "color": "#4D5663" + }, + "text": "" + }, + "type": "linear", + "zerolinecolor": "#E1E5ED" + } + } + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAABBgAAAHCCAYAAABFfHqHAAAgAElEQVR4Xu3dedxUdd3/8Y+oXKAsgguLC5pabkjuGqGiYSiJoaAIKCBEJgoUd/7CvHMt7iwTEVIJFBIRFUNRlMDERMJyC3G3VBIBdzZlUeH3+J4601zDXNc1850z73OdM6/r/uNOrvM935nnd+DM9brOObPNp59t3GJ8IYAAAggggAACCCCAAAIIIIAAAiUIbENgKEGPoQgggAACCCCAAAIIIIAAAgggEAgQGHghIIAAAggggAACCCCAAAIIIIBAyQIEhpIJ2QECCCCAAAIIIIAAAggggAACCBAYeA0ggAACCCCAAAIIIIAAAggggEDJAgSGkgnZAQIIIIAAAggggAACCCCAAAIIEBh4DSCAAAIIIIAAAggggAACCCCAQMkCBIaSCdkBAggggAACCCCAAAIIIIAAAggQGHgNIIAAAggggAACCCCAAAIIIIBAyQIEhpIJ2QECCCCAAAIIIIAAAggggAACCBAYeA0ggAACCCCAAAIIIIAAAggggEDJAgSGkgnZAQIIIIAAAggggAACCCCAAAIIEBh4DSCAAAIIIIAAAggggAACCCCAQMkCBIaSCdkBAggggAACCCCAAAIIIIAAAggQGHgNIIAAAggggAACCCCAAAIIIIBAyQIEhpIJ2QECCCCAAAIIIIAAAggggAACCBAYeA0ggAACCCCAAAIIIIAAAggggEDJAgSGkgnZAQIIIIAAAggggAACCCCAAAIIEBh4DSCAAAIIIIAAAggggAACCCCAQMkCBIaSCdkBAggggAACCCCAAAIIIIAAAggQGHgNIIAAAggggAACCCCAAAIIIIBAyQIEhpIJ2QECCCCAAAIIIIAAAggggAACCBAYeA0ggAACCCCAAAIIIIAAAggggEDJAgSGkgnZAQIIIIAAAggggAACCCCAAAIIEBh4DSCAAAIIIIAAAggggAACCCCAQMkCBIaSCdkBAggggAACCCCAAAIIIIAAAggQGHgNIIAAAggggAACCCCAAAIIIIBAyQIEhpIJ2QECCCCAAAIIIIAAAggggAACCBAYeA0ggAACCCCAAAIIIIAAAggggEDJAgSGkgnZAQIIIIAAAggggAACCCCAAAIIEBh4DSCAAAIIIIAAAggggAACCCCAQMkCBIaSCdkBAggggAAC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", + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "baseline.data.loc['2019-01-01', ['input_MW', 'output_MW']].iplot(subplots=True, title='Gasboiler', subplot_titles=['Input (MW)', 'Output (MW)'])" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wall time: 786 ms\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DAMPOSNEGRSForePosForeNegHeat demandoutput_MWinput_MWoutput_MWhinput_MWh
datetime
2019-01-01 00:00:00+01:0068.9234.8558.012.046.8352.7055-1.4285710.083333-0.02381
2019-01-01 00:01:00+01:0068.9234.8558.012.032.1254.4555-1.4285710.083333-0.02381
2019-01-01 00:02:00+01:0068.9234.8558.012.030.9748.6455-1.4285710.083333-0.02381
2019-01-01 00:03:00+01:0068.9234.8558.012.051.1348.3555-1.4285710.083333-0.02381
2019-01-01 00:04:00+01:0068.9234.8558.012.048.0452.0155-1.4285710.083333-0.02381
\n", + "
" + ], + "text/plain": [ + " DAM POS NEG RS ForePos ForeNeg \\\n", + "datetime \n", + "2019-01-01 00:00:00+01:00 68.92 34.85 58.01 2.0 46.83 52.70 \n", + "2019-01-01 00:01:00+01:00 68.92 34.85 58.01 2.0 32.12 54.45 \n", + "2019-01-01 00:02:00+01:00 68.92 34.85 58.01 2.0 30.97 48.64 \n", + "2019-01-01 00:03:00+01:00 68.92 34.85 58.01 2.0 51.13 48.35 \n", + "2019-01-01 00:04:00+01:00 68.92 34.85 58.01 2.0 48.04 52.01 \n", + "\n", + " Heat demand output_MW input_MW output_MWh \\\n", + "datetime \n", + "2019-01-01 00:00:00+01:00 5 5 -1.428571 0.083333 \n", + "2019-01-01 00:01:00+01:00 5 5 -1.428571 0.083333 \n", + "2019-01-01 00:02:00+01:00 5 5 -1.428571 0.083333 \n", + "2019-01-01 00:03:00+01:00 5 5 -1.428571 0.083333 \n", + "2019-01-01 00:04:00+01:00 5 5 -1.428571 0.083333 \n", + "\n", + " input_MWh \n", + "datetime \n", + "2019-01-01 00:00:00+01:00 -0.02381 \n", + "2019-01-01 00:01:00+01:00 -0.02381 \n", + "2019-01-01 00:02:00+01:00 -0.02381 \n", + "2019-01-01 00:03:00+01:00 -0.02381 \n", + "2019-01-01 00:04:00+01:00 -0.02381 " + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%time hpcase.run()\n", + "hpcase.data.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "linkText": "Export to plot.ly", + "plotlyServerURL": "https://plot.ly", + "showLink": true + }, + "data": [ + { + "line": { + "color": "rgba(255, 153, 51, 1.0)", + "dash": "solid", + "shape": "linear", + "width": 1.3 + }, + "mode": "lines", + "name": "input_MW", + "text": "", + "type": "scatter", + "x": [ + "2019-01-01 00:00:00+01:00", + "2019-01-01 00:01:00+01:00", + "2019-01-01 00:02:00+01:00", + "2019-01-01 00:03:00+01:00", + "2019-01-01 00:04:00+01:00", + "2019-01-01 00:05:00+01:00", + "2019-01-01 00:06:00+01:00", + "2019-01-01 00:07:00+01:00", + "2019-01-01 00:08:00+01:00", + "2019-01-01 00:09:00+01:00", + "2019-01-01 00:10:00+01:00", + "2019-01-01 00:11:00+01:00", + "2019-01-01 00:12:00+01:00", + "2019-01-01 00:13:00+01:00", + "2019-01-01 00:14:00+01:00", + "2019-01-01 00:15:00+01:00", + "2019-01-01 00:16:00+01:00", + "2019-01-01 00:17:00+01:00", + "2019-01-01 00:18:00+01:00", + "2019-01-01 00:19:00+01:00", + "2019-01-01 00:20:00+01:00", + "2019-01-01 00:21:00+01:00", + "2019-01-01 00:22:00+01:00", + "2019-01-01 00:23:00+01:00", + "2019-01-01 00:24:00+01:00", + "2019-01-01 00:25:00+01:00", + "2019-01-01 00:26:00+01:00", + "2019-01-01 00:27:00+01:00", + "2019-01-01 00:28:00+01:00", + "2019-01-01 00:29:00+01:00", + "2019-01-01 00:30:00+01:00", + "2019-01-01 00:31:00+01:00", + "2019-01-01 00:32:00+01:00", + "2019-01-01 00:33:00+01:00", + "2019-01-01 00:34:00+01:00", + "2019-01-01 00:35:00+01:00", + "2019-01-01 00:36:00+01:00", + "2019-01-01 00:37:00+01:00", + "2019-01-01 00:38:00+01:00", + "2019-01-01 00:39:00+01:00", + "2019-01-01 00:40:00+01:00", + "2019-01-01 00:41:00+01:00", + "2019-01-01 00:42:00+01:00", + "2019-01-01 00:43:00+01:00", + "2019-01-01 00:44:00+01:00", + "2019-01-01 00:45:00+01:00", + "2019-01-01 00:46:00+01:00", + "2019-01-01 00:47:00+01:00", + "2019-01-01 00:48:00+01:00", + "2019-01-01 00:49:00+01:00", + "2019-01-01 00:50:00+01:00", + "2019-01-01 00:51:00+01:00", + "2019-01-01 00:52:00+01:00", + "2019-01-01 00:53:00+01:00", + "2019-01-01 00:54:00+01:00", + "2019-01-01 00:55:00+01:00", + "2019-01-01 00:56:00+01:00", + "2019-01-01 00:57:00+01:00", + "2019-01-01 00:58:00+01:00", + "2019-01-01 00:59:00+01:00", + "2019-01-01 01:00:00+01:00", + "2019-01-01 01:01:00+01:00", + "2019-01-01 01:02:00+01:00", + "2019-01-01 01:03:00+01:00", + "2019-01-01 01:04:00+01:00", + "2019-01-01 01:05:00+01:00", + "2019-01-01 01:06:00+01:00", + "2019-01-01 01:07:00+01:00", + "2019-01-01 01:08:00+01:00", + "2019-01-01 01:09:00+01:00", + "2019-01-01 01:10:00+01:00", + "2019-01-01 01:11:00+01:00", + "2019-01-01 01:12:00+01:00", + "2019-01-01 01:13:00+01:00", + "2019-01-01 01:14:00+01:00", + "2019-01-01 01:15:00+01:00", + "2019-01-01 01:16:00+01:00", + "2019-01-01 01:17:00+01:00", + "2019-01-01 01:18:00+01:00", + "2019-01-01 01:19:00+01:00", + "2019-01-01 01:20:00+01:00", + "2019-01-01 01:21:00+01:00", + "2019-01-01 01:22:00+01:00", + "2019-01-01 01:23:00+01:00", + "2019-01-01 01:24:00+01:00", + "2019-01-01 01:25:00+01:00", + "2019-01-01 01:26:00+01:00", + "2019-01-01 01:27:00+01:00", + "2019-01-01 01:28:00+01:00", + "2019-01-01 01:29:00+01:00", + "2019-01-01 01:30:00+01:00", + "2019-01-01 01:31:00+01:00", + "2019-01-01 01:32:00+01:00", + "2019-01-01 01:33:00+01:00", + "2019-01-01 01:34:00+01:00", + "2019-01-01 01:35:00+01:00", + "2019-01-01 01:36:00+01:00", + "2019-01-01 01:37:00+01:00", + "2019-01-01 01:38:00+01:00", + "2019-01-01 01:39:00+01:00", + "2019-01-01 01:40:00+01:00", + "2019-01-01 01:41:00+01:00", + "2019-01-01 01:42:00+01:00", + "2019-01-01 01:43:00+01:00", + "2019-01-01 01:44:00+01:00", + "2019-01-01 01:45:00+01:00", + "2019-01-01 01:46:00+01:00", + "2019-01-01 01:47:00+01:00", + "2019-01-01 01:48:00+01:00", + "2019-01-01 01:49:00+01:00", + "2019-01-01 01:50:00+01:00", + "2019-01-01 01:51:00+01:00", + "2019-01-01 01:52:00+01:00", + "2019-01-01 01:53:00+01:00", + "2019-01-01 01:54:00+01:00", + "2019-01-01 01:55:00+01:00", + "2019-01-01 01:56:00+01:00", + "2019-01-01 01:57:00+01:00", + "2019-01-01 01:58:00+01:00", + "2019-01-01 01:59:00+01:00", + "2019-01-01 02:00:00+01:00", + "2019-01-01 02:01:00+01:00", + "2019-01-01 02:02:00+01:00", + "2019-01-01 02:03:00+01:00", + "2019-01-01 02:04:00+01:00", + "2019-01-01 02:05:00+01:00", + "2019-01-01 02:06:00+01:00", + "2019-01-01 02:07:00+01:00", + "2019-01-01 02:08:00+01:00", + "2019-01-01 02:09:00+01:00", + "2019-01-01 02:10:00+01:00", + "2019-01-01 02:11:00+01:00", + "2019-01-01 02:12:00+01:00", + "2019-01-01 02:13:00+01:00", + "2019-01-01 02:14:00+01:00", + "2019-01-01 02:15:00+01:00", + "2019-01-01 02:16:00+01:00", + "2019-01-01 02:17:00+01:00", + "2019-01-01 02:18:00+01:00", + "2019-01-01 02:19:00+01:00", + "2019-01-01 02:20:00+01:00", + "2019-01-01 02:21:00+01:00", + "2019-01-01 02:22:00+01:00", + "2019-01-01 02:23:00+01:00", + "2019-01-01 02:24:00+01:00", + "2019-01-01 02:25:00+01:00", + "2019-01-01 02:26:00+01:00", + "2019-01-01 02:27:00+01:00", + "2019-01-01 02:28:00+01:00", + "2019-01-01 02:29:00+01:00", + "2019-01-01 02:30:00+01:00", + "2019-01-01 02:31:00+01:00", + "2019-01-01 02:32:00+01:00", + "2019-01-01 02:33:00+01:00", + "2019-01-01 02:34:00+01:00", + "2019-01-01 02:35:00+01:00", + "2019-01-01 02:36:00+01:00", + "2019-01-01 02:37:00+01:00", + "2019-01-01 02:38:00+01:00", + "2019-01-01 02:39:00+01:00", + "2019-01-01 02:40:00+01:00", + "2019-01-01 02:41:00+01:00", + "2019-01-01 02:42:00+01:00", + "2019-01-01 02:43:00+01:00", + "2019-01-01 02:44:00+01:00", + "2019-01-01 02:45:00+01:00", + "2019-01-01 02:46:00+01:00", + "2019-01-01 02:47:00+01:00", + "2019-01-01 02:48:00+01:00", + "2019-01-01 02:49:00+01:00", + "2019-01-01 02:50:00+01:00", + "2019-01-01 02:51:00+01:00", + "2019-01-01 02:52:00+01:00", + "2019-01-01 02:53:00+01:00", + "2019-01-01 02:54:00+01:00", + "2019-01-01 02:55:00+01:00", + "2019-01-01 02:56:00+01:00", + "2019-01-01 02:57:00+01:00", + "2019-01-01 02:58:00+01:00", + "2019-01-01 02:59:00+01:00", + "2019-01-01 03:00:00+01:00", + "2019-01-01 03:01:00+01:00", + "2019-01-01 03:02:00+01:00", + "2019-01-01 03:03:00+01:00", + "2019-01-01 03:04:00+01:00", + "2019-01-01 03:05:00+01:00", + "2019-01-01 03:06:00+01:00", + "2019-01-01 03:07:00+01:00", + "2019-01-01 03:08:00+01:00", + "2019-01-01 03:09:00+01:00", + "2019-01-01 03:10:00+01:00", + "2019-01-01 03:11:00+01:00", + "2019-01-01 03:12:00+01:00", + "2019-01-01 03:13:00+01:00", + "2019-01-01 03:14:00+01:00", + "2019-01-01 03:15:00+01:00", + "2019-01-01 03:16:00+01:00", + "2019-01-01 03:17:00+01:00", + "2019-01-01 03:18:00+01:00", + "2019-01-01 03:19:00+01:00", + "2019-01-01 03:20:00+01:00", + "2019-01-01 03:21:00+01:00", + "2019-01-01 03:22:00+01:00", + "2019-01-01 03:23:00+01:00", + "2019-01-01 03:24:00+01:00", + "2019-01-01 03:25:00+01:00", + "2019-01-01 03:26:00+01:00", + "2019-01-01 03:27:00+01:00", + "2019-01-01 03:28:00+01:00", + "2019-01-01 03:29:00+01:00", + "2019-01-01 03:30:00+01:00", + "2019-01-01 03:31:00+01:00", + "2019-01-01 03:32:00+01:00", + "2019-01-01 03:33:00+01:00", + "2019-01-01 03:34:00+01:00", + "2019-01-01 03:35:00+01:00", + "2019-01-01 03:36:00+01:00", + "2019-01-01 03:37:00+01:00", + "2019-01-01 03:38:00+01:00", + "2019-01-01 03:39:00+01:00", + "2019-01-01 03:40:00+01:00", + "2019-01-01 03:41:00+01:00", + "2019-01-01 03:42:00+01:00", + "2019-01-01 03:43:00+01:00", + "2019-01-01 03:44:00+01:00", + "2019-01-01 03:45:00+01:00", + "2019-01-01 03:46:00+01:00", + "2019-01-01 03:47:00+01:00", + "2019-01-01 03:48:00+01:00", + "2019-01-01 03:49:00+01:00", + "2019-01-01 03:50:00+01:00", + "2019-01-01 03:51:00+01:00", + "2019-01-01 03:52:00+01:00", + "2019-01-01 03:53:00+01:00", + "2019-01-01 03:54:00+01:00", + "2019-01-01 03:55:00+01:00", + "2019-01-01 03:56:00+01:00", + "2019-01-01 03:57:00+01:00", + "2019-01-01 03:58:00+01:00", + "2019-01-01 03:59:00+01:00", + "2019-01-01 04:00:00+01:00", + "2019-01-01 04:01:00+01:00", + "2019-01-01 04:02:00+01:00", + "2019-01-01 04:03:00+01:00", + "2019-01-01 04:04:00+01:00", + "2019-01-01 04:05:00+01:00", + "2019-01-01 04:06:00+01:00", + "2019-01-01 04:07:00+01:00", + "2019-01-01 04:08:00+01:00", + "2019-01-01 04:09:00+01:00", + "2019-01-01 04:10:00+01:00", + "2019-01-01 04:11:00+01:00", + "2019-01-01 04:12:00+01:00", + "2019-01-01 04:13:00+01:00", + "2019-01-01 04:14:00+01:00", + "2019-01-01 04:15:00+01:00", + "2019-01-01 04:16:00+01:00", + "2019-01-01 04:17:00+01:00", + "2019-01-01 04:18:00+01:00", + "2019-01-01 04:19:00+01:00", + "2019-01-01 04:20:00+01:00", + "2019-01-01 04:21:00+01:00", + "2019-01-01 04:22:00+01:00", + "2019-01-01 04:23:00+01:00", + "2019-01-01 04:24:00+01:00", + "2019-01-01 04:25:00+01:00", + "2019-01-01 04:26:00+01:00", + "2019-01-01 04:27:00+01:00", + "2019-01-01 04:28:00+01:00", + "2019-01-01 04:29:00+01:00", + "2019-01-01 04:30:00+01:00", + "2019-01-01 04:31:00+01:00", + "2019-01-01 04:32:00+01:00", + "2019-01-01 04:33:00+01:00", + "2019-01-01 04:34:00+01:00", + "2019-01-01 04:35:00+01:00", + "2019-01-01 04:36:00+01:00", + "2019-01-01 04:37:00+01:00", + "2019-01-01 04:38:00+01:00", + "2019-01-01 04:39:00+01:00", + "2019-01-01 04:40:00+01:00", + "2019-01-01 04:41:00+01:00", + "2019-01-01 04:42:00+01:00", + "2019-01-01 04:43:00+01:00", + "2019-01-01 04:44:00+01:00", + "2019-01-01 04:45:00+01:00", + "2019-01-01 04:46:00+01:00", + "2019-01-01 04:47:00+01:00", + "2019-01-01 04:48:00+01:00", + "2019-01-01 04:49:00+01:00", + "2019-01-01 04:50:00+01:00", + "2019-01-01 04:51:00+01:00", + "2019-01-01 04:52:00+01:00", + "2019-01-01 04:53:00+01:00", + "2019-01-01 04:54:00+01:00", + "2019-01-01 04:55:00+01:00", + "2019-01-01 04:56:00+01:00", + "2019-01-01 04:57:00+01:00", + "2019-01-01 04:58:00+01:00", + "2019-01-01 04:59:00+01:00", + "2019-01-01 05:00:00+01:00", + "2019-01-01 05:01:00+01:00", + "2019-01-01 05:02:00+01:00", + "2019-01-01 05:03:00+01:00", + "2019-01-01 05:04:00+01:00", + "2019-01-01 05:05:00+01:00", + "2019-01-01 05:06:00+01:00", + "2019-01-01 05:07:00+01:00", + "2019-01-01 05:08:00+01:00", + "2019-01-01 05:09:00+01:00", + "2019-01-01 05:10:00+01:00", + "2019-01-01 05:11:00+01:00", + "2019-01-01 05:12:00+01:00", + "2019-01-01 05:13:00+01:00", + "2019-01-01 05:14:00+01:00", + "2019-01-01 05:15:00+01:00", + "2019-01-01 05:16:00+01:00", + "2019-01-01 05:17:00+01:00", + "2019-01-01 05:18:00+01:00", + "2019-01-01 05:19:00+01:00", + "2019-01-01 05:20:00+01:00", + "2019-01-01 05:21:00+01:00", + "2019-01-01 05:22:00+01:00", + "2019-01-01 05:23:00+01:00", + "2019-01-01 05:24:00+01:00", + "2019-01-01 05:25:00+01:00", + "2019-01-01 05:26:00+01:00", + "2019-01-01 05:27:00+01:00", + "2019-01-01 05:28:00+01:00", + "2019-01-01 05:29:00+01:00", + "2019-01-01 05:30:00+01:00", + "2019-01-01 05:31:00+01:00", + "2019-01-01 05:32:00+01:00", + "2019-01-01 05:33:00+01:00", + "2019-01-01 05:34:00+01:00", + "2019-01-01 05:35:00+01:00", + "2019-01-01 05:36:00+01:00", + "2019-01-01 05:37:00+01:00", + "2019-01-01 05:38:00+01:00", + "2019-01-01 05:39:00+01:00", + "2019-01-01 05:40:00+01:00", + "2019-01-01 05:41:00+01:00", + "2019-01-01 05:42:00+01:00", + "2019-01-01 05:43:00+01:00", + "2019-01-01 05:44:00+01:00", + "2019-01-01 05:45:00+01:00", + "2019-01-01 05:46:00+01:00", + "2019-01-01 05:47:00+01:00", + "2019-01-01 05:48:00+01:00", + "2019-01-01 05:49:00+01:00", + "2019-01-01 05:50:00+01:00", + "2019-01-01 05:51:00+01:00", + "2019-01-01 05:52:00+01:00", + "2019-01-01 05:53:00+01:00", + "2019-01-01 05:54:00+01:00", + "2019-01-01 05:55:00+01:00", + "2019-01-01 05:56:00+01:00", + "2019-01-01 05:57:00+01:00", + "2019-01-01 05:58:00+01:00", + "2019-01-01 05:59:00+01:00", + "2019-01-01 06:00:00+01:00", + "2019-01-01 06:01:00+01:00", + "2019-01-01 06:02:00+01:00", + "2019-01-01 06:03:00+01:00", + "2019-01-01 06:04:00+01:00", + "2019-01-01 06:05:00+01:00", + "2019-01-01 06:06:00+01:00", + "2019-01-01 06:07:00+01:00", + "2019-01-01 06:08:00+01:00", + "2019-01-01 06:09:00+01:00", + "2019-01-01 06:10:00+01:00", + "2019-01-01 06:11:00+01:00", + "2019-01-01 06:12:00+01:00", + "2019-01-01 06:13:00+01:00", + "2019-01-01 06:14:00+01:00", + "2019-01-01 06:15:00+01:00", + "2019-01-01 06:16:00+01:00", + "2019-01-01 06:17:00+01:00", + "2019-01-01 06:18:00+01:00", + "2019-01-01 06:19:00+01:00", + "2019-01-01 06:20:00+01:00", + "2019-01-01 06:21:00+01:00", + "2019-01-01 06:22:00+01:00", + "2019-01-01 06:23:00+01:00", + "2019-01-01 06:24:00+01:00", + "2019-01-01 06:25:00+01:00", + "2019-01-01 06:26:00+01:00", + "2019-01-01 06:27:00+01:00", + "2019-01-01 06:28:00+01:00", + "2019-01-01 06:29:00+01:00", + "2019-01-01 06:30:00+01:00", + "2019-01-01 06:31:00+01:00", + "2019-01-01 06:32:00+01:00", + "2019-01-01 06:33:00+01:00", + "2019-01-01 06:34:00+01:00", + "2019-01-01 06:35:00+01:00", + "2019-01-01 06:36:00+01:00", + "2019-01-01 06:37:00+01:00", + "2019-01-01 06:38:00+01:00", + "2019-01-01 06:39:00+01:00", + "2019-01-01 06:40:00+01:00", + "2019-01-01 06:41:00+01:00", + "2019-01-01 06:42:00+01:00", + "2019-01-01 06:43:00+01:00", + "2019-01-01 06:44:00+01:00", + "2019-01-01 06:45:00+01:00", + "2019-01-01 06:46:00+01:00", + "2019-01-01 06:47:00+01:00", + "2019-01-01 06:48:00+01:00", + "2019-01-01 06:49:00+01:00", + "2019-01-01 06:50:00+01:00", + "2019-01-01 06:51:00+01:00", + "2019-01-01 06:52:00+01:00", + "2019-01-01 06:53:00+01:00", + "2019-01-01 06:54:00+01:00", + "2019-01-01 06:55:00+01:00", + "2019-01-01 06:56:00+01:00", + "2019-01-01 06:57:00+01:00", + "2019-01-01 06:58:00+01:00", + "2019-01-01 06:59:00+01:00", + "2019-01-01 07:00:00+01:00", + "2019-01-01 07:01:00+01:00", + "2019-01-01 07:02:00+01:00", + "2019-01-01 07:03:00+01:00", + "2019-01-01 07:04:00+01:00", + "2019-01-01 07:05:00+01:00", + "2019-01-01 07:06:00+01:00", + "2019-01-01 07:07:00+01:00", + "2019-01-01 07:08:00+01:00", + "2019-01-01 07:09:00+01:00", + "2019-01-01 07:10:00+01:00", + "2019-01-01 07:11:00+01:00", + "2019-01-01 07:12:00+01:00", + "2019-01-01 07:13:00+01:00", + "2019-01-01 07:14:00+01:00", + "2019-01-01 07:15:00+01:00", + "2019-01-01 07:16:00+01:00", + "2019-01-01 07:17:00+01:00", + "2019-01-01 07:18:00+01:00", + "2019-01-01 07:19:00+01:00", + "2019-01-01 07:20:00+01:00", + "2019-01-01 07:21:00+01:00", + "2019-01-01 07:22:00+01:00", + "2019-01-01 07:23:00+01:00", + "2019-01-01 07:24:00+01:00", + "2019-01-01 07:25:00+01:00", + "2019-01-01 07:26:00+01:00", + "2019-01-01 07:27:00+01:00", + "2019-01-01 07:28:00+01:00", + "2019-01-01 07:29:00+01:00", + "2019-01-01 07:30:00+01:00", + "2019-01-01 07:31:00+01:00", + "2019-01-01 07:32:00+01:00", + "2019-01-01 07:33:00+01:00", + "2019-01-01 07:34:00+01:00", + "2019-01-01 07:35:00+01:00", + "2019-01-01 07:36:00+01:00", + "2019-01-01 07:37:00+01:00", + "2019-01-01 07:38:00+01:00", + "2019-01-01 07:39:00+01:00", + "2019-01-01 07:40:00+01:00", + "2019-01-01 07:41:00+01:00", + "2019-01-01 07:42:00+01:00", + "2019-01-01 07:43:00+01:00", + "2019-01-01 07:44:00+01:00", + "2019-01-01 07:45:00+01:00", + "2019-01-01 07:46:00+01:00", + "2019-01-01 07:47:00+01:00", + "2019-01-01 07:48:00+01:00", + "2019-01-01 07:49:00+01:00", + "2019-01-01 07:50:00+01:00", + "2019-01-01 07:51:00+01:00", + "2019-01-01 07:52:00+01:00", + "2019-01-01 07:53:00+01:00", + "2019-01-01 07:54:00+01:00", + "2019-01-01 07:55:00+01:00", + "2019-01-01 07:56:00+01:00", + "2019-01-01 07:57:00+01:00", + "2019-01-01 07:58:00+01:00", + "2019-01-01 07:59:00+01:00", + "2019-01-01 08:00:00+01:00", + "2019-01-01 08:01:00+01:00", + "2019-01-01 08:02:00+01:00", + "2019-01-01 08:03:00+01:00", + "2019-01-01 08:04:00+01:00", + "2019-01-01 08:05:00+01:00", + "2019-01-01 08:06:00+01:00", + "2019-01-01 08:07:00+01:00", + "2019-01-01 08:08:00+01:00", + "2019-01-01 08:09:00+01:00", + "2019-01-01 08:10:00+01:00", + "2019-01-01 08:11:00+01:00", + "2019-01-01 08:12:00+01:00", + "2019-01-01 08:13:00+01:00", + "2019-01-01 08:14:00+01:00", + "2019-01-01 08:15:00+01:00", + "2019-01-01 08:16:00+01:00", + "2019-01-01 08:17:00+01:00", + "2019-01-01 08:18:00+01:00", + "2019-01-01 08:19:00+01:00", + "2019-01-01 08:20:00+01:00", + "2019-01-01 08:21:00+01:00", + "2019-01-01 08:22:00+01:00", + "2019-01-01 08:23:00+01:00", + "2019-01-01 08:24:00+01:00", + "2019-01-01 08:25:00+01:00", + "2019-01-01 08:26:00+01:00", + "2019-01-01 08:27:00+01:00", + "2019-01-01 08:28:00+01:00", + "2019-01-01 08:29:00+01:00", + "2019-01-01 08:30:00+01:00", + "2019-01-01 08:31:00+01:00", + "2019-01-01 08:32:00+01:00", + "2019-01-01 08:33:00+01:00", + "2019-01-01 08:34:00+01:00", + "2019-01-01 08:35:00+01:00", + "2019-01-01 08:36:00+01:00", + "2019-01-01 08:37:00+01:00", + "2019-01-01 08:38:00+01:00", + "2019-01-01 08:39:00+01:00", + "2019-01-01 08:40:00+01:00", + "2019-01-01 08:41:00+01:00", + "2019-01-01 08:42:00+01:00", + "2019-01-01 08:43:00+01:00", + "2019-01-01 08:44:00+01:00", + "2019-01-01 08:45:00+01:00", + "2019-01-01 08:46:00+01:00", + "2019-01-01 08:47:00+01:00", + "2019-01-01 08:48:00+01:00", + "2019-01-01 08:49:00+01:00", + "2019-01-01 08:50:00+01:00", + "2019-01-01 08:51:00+01:00", + "2019-01-01 08:52:00+01:00", + "2019-01-01 08:53:00+01:00", + "2019-01-01 08:54:00+01:00", + "2019-01-01 08:55:00+01:00", + "2019-01-01 08:56:00+01:00", + "2019-01-01 08:57:00+01:00", + "2019-01-01 08:58:00+01:00", + "2019-01-01 08:59:00+01:00", + "2019-01-01 09:00:00+01:00", + "2019-01-01 09:01:00+01:00", + "2019-01-01 09:02:00+01:00", + "2019-01-01 09:03:00+01:00", + "2019-01-01 09:04:00+01:00", + "2019-01-01 09:05:00+01:00", + "2019-01-01 09:06:00+01:00", + "2019-01-01 09:07:00+01:00", + "2019-01-01 09:08:00+01:00", + "2019-01-01 09:09:00+01:00", + "2019-01-01 09:10:00+01:00", + "2019-01-01 09:11:00+01:00", + "2019-01-01 09:12:00+01:00", + "2019-01-01 09:13:00+01:00", + "2019-01-01 09:14:00+01:00", + "2019-01-01 09:15:00+01:00", + "2019-01-01 09:16:00+01:00", + "2019-01-01 09:17:00+01:00", + "2019-01-01 09:18:00+01:00", + "2019-01-01 09:19:00+01:00", + "2019-01-01 09:20:00+01:00", + "2019-01-01 09:21:00+01:00", + "2019-01-01 09:22:00+01:00", + "2019-01-01 09:23:00+01:00", + "2019-01-01 09:24:00+01:00", + "2019-01-01 09:25:00+01:00", + "2019-01-01 09:26:00+01:00", + "2019-01-01 09:27:00+01:00", + "2019-01-01 09:28:00+01:00", + "2019-01-01 09:29:00+01:00", + "2019-01-01 09:30:00+01:00", + "2019-01-01 09:31:00+01:00", + "2019-01-01 09:32:00+01:00", + "2019-01-01 09:33:00+01:00", + "2019-01-01 09:34:00+01:00", + "2019-01-01 09:35:00+01:00", + "2019-01-01 09:36:00+01:00", + "2019-01-01 09:37:00+01:00", + "2019-01-01 09:38:00+01:00", + "2019-01-01 09:39:00+01:00", + "2019-01-01 09:40:00+01:00", + "2019-01-01 09:41:00+01:00", + "2019-01-01 09:42:00+01:00", + "2019-01-01 09:43:00+01:00", + "2019-01-01 09:44:00+01:00", + "2019-01-01 09:45:00+01:00", + "2019-01-01 09:46:00+01:00", + "2019-01-01 09:47:00+01:00", + "2019-01-01 09:48:00+01:00", + "2019-01-01 09:49:00+01:00", + "2019-01-01 09:50:00+01:00", + "2019-01-01 09:51:00+01:00", + "2019-01-01 09:52:00+01:00", + "2019-01-01 09:53:00+01:00", + "2019-01-01 09:54:00+01:00", + "2019-01-01 09:55:00+01:00", + "2019-01-01 09:56:00+01:00", + "2019-01-01 09:57:00+01:00", + "2019-01-01 09:58:00+01:00", + "2019-01-01 09:59:00+01:00", + "2019-01-01 10:00:00+01:00", + "2019-01-01 10:01:00+01:00", + "2019-01-01 10:02:00+01:00", + "2019-01-01 10:03:00+01:00", + "2019-01-01 10:04:00+01:00", + "2019-01-01 10:05:00+01:00", + "2019-01-01 10:06:00+01:00", + "2019-01-01 10:07:00+01:00", + "2019-01-01 10:08:00+01:00", + "2019-01-01 10:09:00+01:00", + "2019-01-01 10:10:00+01:00", + "2019-01-01 10:11:00+01:00", + "2019-01-01 10:12:00+01:00", + "2019-01-01 10:13:00+01:00", + "2019-01-01 10:14:00+01:00", + "2019-01-01 10:15:00+01:00", + "2019-01-01 10:16:00+01:00", + "2019-01-01 10:17:00+01:00", + "2019-01-01 10:18:00+01:00", + "2019-01-01 10:19:00+01:00", + "2019-01-01 10:20:00+01:00", + "2019-01-01 10:21:00+01:00", + "2019-01-01 10:22:00+01:00", + "2019-01-01 10:23:00+01:00", + "2019-01-01 10:24:00+01:00", + "2019-01-01 10:25:00+01:00", + "2019-01-01 10:26:00+01:00", + "2019-01-01 10:27:00+01:00", + "2019-01-01 10:28:00+01:00", + "2019-01-01 10:29:00+01:00", + "2019-01-01 10:30:00+01:00", + "2019-01-01 10:31:00+01:00", + "2019-01-01 10:32:00+01:00", + "2019-01-01 10:33:00+01:00", + "2019-01-01 10:34:00+01:00", + "2019-01-01 10:35:00+01:00", + "2019-01-01 10:36:00+01:00", + "2019-01-01 10:37:00+01:00", + "2019-01-01 10:38:00+01:00", + "2019-01-01 10:39:00+01:00", + "2019-01-01 10:40:00+01:00", + "2019-01-01 10:41:00+01:00", + "2019-01-01 10:42:00+01:00", + "2019-01-01 10:43:00+01:00", + "2019-01-01 10:44:00+01:00", + "2019-01-01 10:45:00+01:00", + "2019-01-01 10:46:00+01:00", + "2019-01-01 10:47:00+01:00", + "2019-01-01 10:48:00+01:00", + "2019-01-01 10:49:00+01:00", + "2019-01-01 10:50:00+01:00", + "2019-01-01 10:51:00+01:00", + "2019-01-01 10:52:00+01:00", + "2019-01-01 10:53:00+01:00", + "2019-01-01 10:54:00+01:00", + "2019-01-01 10:55:00+01:00", + "2019-01-01 10:56:00+01:00", + "2019-01-01 10:57:00+01:00", + "2019-01-01 10:58:00+01:00", + "2019-01-01 10:59:00+01:00", + "2019-01-01 11:00:00+01:00", + "2019-01-01 11:01:00+01:00", + "2019-01-01 11:02:00+01:00", + "2019-01-01 11:03:00+01:00", + "2019-01-01 11:04:00+01:00", + "2019-01-01 11:05:00+01:00", + "2019-01-01 11:06:00+01:00", + "2019-01-01 11:07:00+01:00", + "2019-01-01 11:08:00+01:00", + "2019-01-01 11:09:00+01:00", + "2019-01-01 11:10:00+01:00", + "2019-01-01 11:11:00+01:00", + "2019-01-01 11:12:00+01:00", + "2019-01-01 11:13:00+01:00", + "2019-01-01 11:14:00+01:00", + "2019-01-01 11:15:00+01:00", + "2019-01-01 11:16:00+01:00", + "2019-01-01 11:17:00+01:00", + "2019-01-01 11:18:00+01:00", + "2019-01-01 11:19:00+01:00", + "2019-01-01 11:20:00+01:00", + "2019-01-01 11:21:00+01:00", + "2019-01-01 11:22:00+01:00", + "2019-01-01 11:23:00+01:00", + "2019-01-01 11:24:00+01:00", + "2019-01-01 11:25:00+01:00", + "2019-01-01 11:26:00+01:00", + "2019-01-01 11:27:00+01:00", + "2019-01-01 11:28:00+01:00", + "2019-01-01 11:29:00+01:00", + "2019-01-01 11:30:00+01:00", + "2019-01-01 11:31:00+01:00", + "2019-01-01 11:32:00+01:00", + "2019-01-01 11:33:00+01:00", + "2019-01-01 11:34:00+01:00", + "2019-01-01 11:35:00+01:00", + "2019-01-01 11:36:00+01:00", + "2019-01-01 11:37:00+01:00", + "2019-01-01 11:38:00+01:00", + "2019-01-01 11:39:00+01:00", + "2019-01-01 11:40:00+01:00", + "2019-01-01 11:41:00+01:00", + "2019-01-01 11:42:00+01:00", + "2019-01-01 11:43:00+01:00", + "2019-01-01 11:44:00+01:00", + "2019-01-01 11:45:00+01:00", + "2019-01-01 11:46:00+01:00", + "2019-01-01 11:47:00+01:00", + "2019-01-01 11:48:00+01:00", + "2019-01-01 11:49:00+01:00", + "2019-01-01 11:50:00+01:00", + "2019-01-01 11:51:00+01:00", + "2019-01-01 11:52:00+01:00", + "2019-01-01 11:53:00+01:00", + "2019-01-01 11:54:00+01:00", + "2019-01-01 11:55:00+01:00", + "2019-01-01 11:56:00+01:00", + "2019-01-01 11:57:00+01:00", + "2019-01-01 11:58:00+01:00", + "2019-01-01 11:59:00+01:00", + "2019-01-01 12:00:00+01:00", + "2019-01-01 12:01:00+01:00", + "2019-01-01 12:02:00+01:00", + "2019-01-01 12:03:00+01:00", + "2019-01-01 12:04:00+01:00", + "2019-01-01 12:05:00+01:00", + "2019-01-01 12:06:00+01:00", + "2019-01-01 12:07:00+01:00", + "2019-01-01 12:08:00+01:00", + "2019-01-01 12:09:00+01:00", + "2019-01-01 12:10:00+01:00", + "2019-01-01 12:11:00+01:00", + "2019-01-01 12:12:00+01:00", + "2019-01-01 12:13:00+01:00", + "2019-01-01 12:14:00+01:00", + "2019-01-01 12:15:00+01:00", + "2019-01-01 12:16:00+01:00", + "2019-01-01 12:17:00+01:00", + "2019-01-01 12:18:00+01:00", + "2019-01-01 12:19:00+01:00", + "2019-01-01 12:20:00+01:00", + "2019-01-01 12:21:00+01:00", + "2019-01-01 12:22:00+01:00", + "2019-01-01 12:23:00+01:00", + "2019-01-01 12:24:00+01:00", + "2019-01-01 12:25:00+01:00", + "2019-01-01 12:26:00+01:00", + "2019-01-01 12:27:00+01:00", + "2019-01-01 12:28:00+01:00", + "2019-01-01 12:29:00+01:00", + "2019-01-01 12:30:00+01:00", + "2019-01-01 12:31:00+01:00", + "2019-01-01 12:32:00+01:00", + "2019-01-01 12:33:00+01:00", + "2019-01-01 12:34:00+01:00", + "2019-01-01 12:35:00+01:00", + "2019-01-01 12:36:00+01:00", + "2019-01-01 12:37:00+01:00", + "2019-01-01 12:38:00+01:00", + "2019-01-01 12:39:00+01:00", + "2019-01-01 12:40:00+01:00", + "2019-01-01 12:41:00+01:00", + "2019-01-01 12:42:00+01:00", + "2019-01-01 12:43:00+01:00", + "2019-01-01 12:44:00+01:00", + "2019-01-01 12:45:00+01:00", + "2019-01-01 12:46:00+01:00", + "2019-01-01 12:47:00+01:00", + "2019-01-01 12:48:00+01:00", + "2019-01-01 12:49:00+01:00", + "2019-01-01 12:50:00+01:00", + "2019-01-01 12:51:00+01:00", + "2019-01-01 12:52:00+01:00", + "2019-01-01 12:53:00+01:00", + "2019-01-01 12:54:00+01:00", + "2019-01-01 12:55:00+01:00", + "2019-01-01 12:56:00+01:00", + "2019-01-01 12:57:00+01:00", + "2019-01-01 12:58:00+01:00", + "2019-01-01 12:59:00+01:00", + "2019-01-01 13:00:00+01:00", + "2019-01-01 13:01:00+01:00", + "2019-01-01 13:02:00+01:00", + "2019-01-01 13:03:00+01:00", + "2019-01-01 13:04:00+01:00", + "2019-01-01 13:05:00+01:00", + "2019-01-01 13:06:00+01:00", + "2019-01-01 13:07:00+01:00", + "2019-01-01 13:08:00+01:00", + "2019-01-01 13:09:00+01:00", + "2019-01-01 13:10:00+01:00", + "2019-01-01 13:11:00+01:00", + "2019-01-01 13:12:00+01:00", + "2019-01-01 13:13:00+01:00", + "2019-01-01 13:14:00+01:00", + "2019-01-01 13:15:00+01:00", + "2019-01-01 13:16:00+01:00", + "2019-01-01 13:17:00+01:00", + "2019-01-01 13:18:00+01:00", + "2019-01-01 13:19:00+01:00", + "2019-01-01 13:20:00+01:00", + "2019-01-01 13:21:00+01:00", + "2019-01-01 13:22:00+01:00", + "2019-01-01 13:23:00+01:00", + "2019-01-01 13:24:00+01:00", + "2019-01-01 13:25:00+01:00", + "2019-01-01 13:26:00+01:00", + "2019-01-01 13:27:00+01:00", + "2019-01-01 13:28:00+01:00", + "2019-01-01 13:29:00+01:00", + "2019-01-01 13:30:00+01:00", + "2019-01-01 13:31:00+01:00", + "2019-01-01 13:32:00+01:00", + "2019-01-01 13:33:00+01:00", + "2019-01-01 13:34:00+01:00", + "2019-01-01 13:35:00+01:00", + "2019-01-01 13:36:00+01:00", + "2019-01-01 13:37:00+01:00", + "2019-01-01 13:38:00+01:00", + "2019-01-01 13:39:00+01:00", + "2019-01-01 13:40:00+01:00", + "2019-01-01 13:41:00+01:00", + "2019-01-01 13:42:00+01:00", + "2019-01-01 13:43:00+01:00", + "2019-01-01 13:44:00+01:00", + "2019-01-01 13:45:00+01:00", + "2019-01-01 13:46:00+01:00", + "2019-01-01 13:47:00+01:00", + "2019-01-01 13:48:00+01:00", + "2019-01-01 13:49:00+01:00", + "2019-01-01 13:50:00+01:00", + "2019-01-01 13:51:00+01:00", + "2019-01-01 13:52:00+01:00", + "2019-01-01 13:53:00+01:00", + "2019-01-01 13:54:00+01:00", + "2019-01-01 13:55:00+01:00", + "2019-01-01 13:56:00+01:00", + "2019-01-01 13:57:00+01:00", + "2019-01-01 13:58:00+01:00", + "2019-01-01 13:59:00+01:00", + "2019-01-01 14:00:00+01:00", + "2019-01-01 14:01:00+01:00", + "2019-01-01 14:02:00+01:00", + "2019-01-01 14:03:00+01:00", + "2019-01-01 14:04:00+01:00", + "2019-01-01 14:05:00+01:00", + "2019-01-01 14:06:00+01:00", + "2019-01-01 14:07:00+01:00", + "2019-01-01 14:08:00+01:00", + "2019-01-01 14:09:00+01:00", + "2019-01-01 14:10:00+01:00", + "2019-01-01 14:11:00+01:00", + "2019-01-01 14:12:00+01:00", + "2019-01-01 14:13:00+01:00", + "2019-01-01 14:14:00+01:00", + "2019-01-01 14:15:00+01:00", + "2019-01-01 14:16:00+01:00", + "2019-01-01 14:17:00+01:00", + "2019-01-01 14:18:00+01:00", + "2019-01-01 14:19:00+01:00", + "2019-01-01 14:20:00+01:00", + "2019-01-01 14:21:00+01:00", + "2019-01-01 14:22:00+01:00", + "2019-01-01 14:23:00+01:00", + "2019-01-01 14:24:00+01:00", + "2019-01-01 14:25:00+01:00", + "2019-01-01 14:26:00+01:00", + "2019-01-01 14:27:00+01:00", + "2019-01-01 14:28:00+01:00", + "2019-01-01 14:29:00+01:00", + "2019-01-01 14:30:00+01:00", + "2019-01-01 14:31:00+01:00", + "2019-01-01 14:32:00+01:00", + "2019-01-01 14:33:00+01:00", + "2019-01-01 14:34:00+01:00", + "2019-01-01 14:35:00+01:00", + "2019-01-01 14:36:00+01:00", + "2019-01-01 14:37:00+01:00", + "2019-01-01 14:38:00+01:00", + "2019-01-01 14:39:00+01:00", + "2019-01-01 14:40:00+01:00", + "2019-01-01 14:41:00+01:00", + "2019-01-01 14:42:00+01:00", + "2019-01-01 14:43:00+01:00", + "2019-01-01 14:44:00+01:00", + "2019-01-01 14:45:00+01:00", + "2019-01-01 14:46:00+01:00", + "2019-01-01 14:47:00+01:00", + "2019-01-01 14:48:00+01:00", + "2019-01-01 14:49:00+01:00", + "2019-01-01 14:50:00+01:00", + "2019-01-01 14:51:00+01:00", + "2019-01-01 14:52:00+01:00", + "2019-01-01 14:53:00+01:00", + "2019-01-01 14:54:00+01:00", + "2019-01-01 14:55:00+01:00", + "2019-01-01 14:56:00+01:00", + "2019-01-01 14:57:00+01:00", + "2019-01-01 14:58:00+01:00", + "2019-01-01 14:59:00+01:00", + "2019-01-01 15:00:00+01:00", + "2019-01-01 15:01:00+01:00", + "2019-01-01 15:02:00+01:00", + "2019-01-01 15:03:00+01:00", + "2019-01-01 15:04:00+01:00", + "2019-01-01 15:05:00+01:00", + "2019-01-01 15:06:00+01:00", + "2019-01-01 15:07:00+01:00", + "2019-01-01 15:08:00+01:00", + "2019-01-01 15:09:00+01:00", + "2019-01-01 15:10:00+01:00", + "2019-01-01 15:11:00+01:00", + "2019-01-01 15:12:00+01:00", + "2019-01-01 15:13:00+01:00", + "2019-01-01 15:14:00+01:00", + "2019-01-01 15:15:00+01:00", + "2019-01-01 15:16:00+01:00", + "2019-01-01 15:17:00+01:00", + "2019-01-01 15:18:00+01:00", + "2019-01-01 15:19:00+01:00", + "2019-01-01 15:20:00+01:00", + "2019-01-01 15:21:00+01:00", + "2019-01-01 15:22:00+01:00", + "2019-01-01 15:23:00+01:00", + "2019-01-01 15:24:00+01:00", + "2019-01-01 15:25:00+01:00", + "2019-01-01 15:26:00+01:00", + "2019-01-01 15:27:00+01:00", + "2019-01-01 15:28:00+01:00", + "2019-01-01 15:29:00+01:00", + "2019-01-01 15:30:00+01:00", + "2019-01-01 15:31:00+01:00", + "2019-01-01 15:32:00+01:00", + "2019-01-01 15:33:00+01:00", + "2019-01-01 15:34:00+01:00", + "2019-01-01 15:35:00+01:00", + "2019-01-01 15:36:00+01:00", + "2019-01-01 15:37:00+01:00", + "2019-01-01 15:38:00+01:00", + "2019-01-01 15:39:00+01:00", + "2019-01-01 15:40:00+01:00", + "2019-01-01 15:41:00+01:00", + "2019-01-01 15:42:00+01:00", + "2019-01-01 15:43:00+01:00", + "2019-01-01 15:44:00+01:00", + "2019-01-01 15:45:00+01:00", + "2019-01-01 15:46:00+01:00", + "2019-01-01 15:47:00+01:00", + "2019-01-01 15:48:00+01:00", + "2019-01-01 15:49:00+01:00", + "2019-01-01 15:50:00+01:00", + "2019-01-01 15:51:00+01:00", + "2019-01-01 15:52:00+01:00", + "2019-01-01 15:53:00+01:00", + "2019-01-01 15:54:00+01:00", + "2019-01-01 15:55:00+01:00", + "2019-01-01 15:56:00+01:00", + "2019-01-01 15:57:00+01:00", + "2019-01-01 15:58:00+01:00", + "2019-01-01 15:59:00+01:00", + "2019-01-01 16:00:00+01:00", + "2019-01-01 16:01:00+01:00", + "2019-01-01 16:02:00+01:00", + "2019-01-01 16:03:00+01:00", + "2019-01-01 16:04:00+01:00", + "2019-01-01 16:05:00+01:00", + "2019-01-01 16:06:00+01:00", + "2019-01-01 16:07:00+01:00", + "2019-01-01 16:08:00+01:00", + "2019-01-01 16:09:00+01:00", + "2019-01-01 16:10:00+01:00", + "2019-01-01 16:11:00+01:00", + "2019-01-01 16:12:00+01:00", + "2019-01-01 16:13:00+01:00", + "2019-01-01 16:14:00+01:00", + "2019-01-01 16:15:00+01:00", + "2019-01-01 16:16:00+01:00", + "2019-01-01 16:17:00+01:00", + "2019-01-01 16:18:00+01:00", + "2019-01-01 16:19:00+01:00", + "2019-01-01 16:20:00+01:00", + "2019-01-01 16:21:00+01:00", + "2019-01-01 16:22:00+01:00", + "2019-01-01 16:23:00+01:00", + "2019-01-01 16:24:00+01:00", + "2019-01-01 16:25:00+01:00", + "2019-01-01 16:26:00+01:00", + "2019-01-01 16:27:00+01:00", + "2019-01-01 16:28:00+01:00", + "2019-01-01 16:29:00+01:00", + "2019-01-01 16:30:00+01:00", + "2019-01-01 16:31:00+01:00", + "2019-01-01 16:32:00+01:00", + "2019-01-01 16:33:00+01:00", + "2019-01-01 16:34:00+01:00", + "2019-01-01 16:35:00+01:00", + "2019-01-01 16:36:00+01:00", + "2019-01-01 16:37:00+01:00", + "2019-01-01 16:38:00+01:00", + "2019-01-01 16:39:00+01:00", + "2019-01-01 16:40:00+01:00", + "2019-01-01 16:41:00+01:00", + "2019-01-01 16:42:00+01:00", + "2019-01-01 16:43:00+01:00", + "2019-01-01 16:44:00+01:00", + "2019-01-01 16:45:00+01:00", + "2019-01-01 16:46:00+01:00", + "2019-01-01 16:47:00+01:00", + "2019-01-01 16:48:00+01:00", + "2019-01-01 16:49:00+01:00", + "2019-01-01 16:50:00+01:00", + "2019-01-01 16:51:00+01:00", + "2019-01-01 16:52:00+01:00", + "2019-01-01 16:53:00+01:00", + "2019-01-01 16:54:00+01:00", + "2019-01-01 16:55:00+01:00", + "2019-01-01 16:56:00+01:00", + "2019-01-01 16:57:00+01:00", + "2019-01-01 16:58:00+01:00", + "2019-01-01 16:59:00+01:00", + "2019-01-01 17:00:00+01:00", + "2019-01-01 17:01:00+01:00", + "2019-01-01 17:02:00+01:00", + "2019-01-01 17:03:00+01:00", + "2019-01-01 17:04:00+01:00", + "2019-01-01 17:05:00+01:00", + "2019-01-01 17:06:00+01:00", + "2019-01-01 17:07:00+01:00", + "2019-01-01 17:08:00+01:00", + "2019-01-01 17:09:00+01:00", + "2019-01-01 17:10:00+01:00", + "2019-01-01 17:11:00+01:00", + "2019-01-01 17:12:00+01:00", + "2019-01-01 17:13:00+01:00", + "2019-01-01 17:14:00+01:00", + "2019-01-01 17:15:00+01:00", + "2019-01-01 17:16:00+01:00", + "2019-01-01 17:17:00+01:00", + "2019-01-01 17:18:00+01:00", + "2019-01-01 17:19:00+01:00", + "2019-01-01 17:20:00+01:00", + "2019-01-01 17:21:00+01:00", + "2019-01-01 17:22:00+01:00", + "2019-01-01 17:23:00+01:00", + "2019-01-01 17:24:00+01:00", + "2019-01-01 17:25:00+01:00", + "2019-01-01 17:26:00+01:00", + "2019-01-01 17:27:00+01:00", + "2019-01-01 17:28:00+01:00", + "2019-01-01 17:29:00+01:00", + "2019-01-01 17:30:00+01:00", + "2019-01-01 17:31:00+01:00", + "2019-01-01 17:32:00+01:00", + "2019-01-01 17:33:00+01:00", + "2019-01-01 17:34:00+01:00", + "2019-01-01 17:35:00+01:00", + "2019-01-01 17:36:00+01:00", + "2019-01-01 17:37:00+01:00", + "2019-01-01 17:38:00+01:00", + "2019-01-01 17:39:00+01:00", + "2019-01-01 17:40:00+01:00", + "2019-01-01 17:41:00+01:00", + "2019-01-01 17:42:00+01:00", + "2019-01-01 17:43:00+01:00", + "2019-01-01 17:44:00+01:00", + "2019-01-01 17:45:00+01:00", + "2019-01-01 17:46:00+01:00", + "2019-01-01 17:47:00+01:00", + "2019-01-01 17:48:00+01:00", + "2019-01-01 17:49:00+01:00", + "2019-01-01 17:50:00+01:00", + "2019-01-01 17:51:00+01:00", + "2019-01-01 17:52:00+01:00", + "2019-01-01 17:53:00+01:00", + "2019-01-01 17:54:00+01:00", + "2019-01-01 17:55:00+01:00", + "2019-01-01 17:56:00+01:00", + "2019-01-01 17:57:00+01:00", + "2019-01-01 17:58:00+01:00", + "2019-01-01 17:59:00+01:00", + "2019-01-01 18:00:00+01:00", + "2019-01-01 18:01:00+01:00", + "2019-01-01 18:02:00+01:00", + "2019-01-01 18:03:00+01:00", + "2019-01-01 18:04:00+01:00", + "2019-01-01 18:05:00+01:00", + "2019-01-01 18:06:00+01:00", + "2019-01-01 18:07:00+01:00", + "2019-01-01 18:08:00+01:00", + "2019-01-01 18:09:00+01:00", + "2019-01-01 18:10:00+01:00", + "2019-01-01 18:11:00+01:00", + "2019-01-01 18:12:00+01:00", + "2019-01-01 18:13:00+01:00", + "2019-01-01 18:14:00+01:00", + "2019-01-01 18:15:00+01:00", + "2019-01-01 18:16:00+01:00", + "2019-01-01 18:17:00+01:00", + "2019-01-01 18:18:00+01:00", + "2019-01-01 18:19:00+01:00", + "2019-01-01 18:20:00+01:00", + "2019-01-01 18:21:00+01:00", + "2019-01-01 18:22:00+01:00", + "2019-01-01 18:23:00+01:00", + "2019-01-01 18:24:00+01:00", + "2019-01-01 18:25:00+01:00", + "2019-01-01 18:26:00+01:00", + "2019-01-01 18:27:00+01:00", + "2019-01-01 18:28:00+01:00", + "2019-01-01 18:29:00+01:00", + "2019-01-01 18:30:00+01:00", + "2019-01-01 18:31:00+01:00", + "2019-01-01 18:32:00+01:00", + "2019-01-01 18:33:00+01:00", + "2019-01-01 18:34:00+01:00", + "2019-01-01 18:35:00+01:00", + "2019-01-01 18:36:00+01:00", + "2019-01-01 18:37:00+01:00", + "2019-01-01 18:38:00+01:00", + "2019-01-01 18:39:00+01:00", + "2019-01-01 18:40:00+01:00", + "2019-01-01 18:41:00+01:00", + "2019-01-01 18:42:00+01:00", + "2019-01-01 18:43:00+01:00", + "2019-01-01 18:44:00+01:00", + "2019-01-01 18:45:00+01:00", + "2019-01-01 18:46:00+01:00", + "2019-01-01 18:47:00+01:00", + "2019-01-01 18:48:00+01:00", + "2019-01-01 18:49:00+01:00", + "2019-01-01 18:50:00+01:00", + "2019-01-01 18:51:00+01:00", + "2019-01-01 18:52:00+01:00", + "2019-01-01 18:53:00+01:00", + "2019-01-01 18:54:00+01:00", + "2019-01-01 18:55:00+01:00", + "2019-01-01 18:56:00+01:00", + "2019-01-01 18:57:00+01:00", + "2019-01-01 18:58:00+01:00", + "2019-01-01 18:59:00+01:00", + "2019-01-01 19:00:00+01:00", + "2019-01-01 19:01:00+01:00", + "2019-01-01 19:02:00+01:00", + "2019-01-01 19:03:00+01:00", + "2019-01-01 19:04:00+01:00", + "2019-01-01 19:05:00+01:00", + "2019-01-01 19:06:00+01:00", + "2019-01-01 19:07:00+01:00", + "2019-01-01 19:08:00+01:00", + "2019-01-01 19:09:00+01:00", + "2019-01-01 19:10:00+01:00", + "2019-01-01 19:11:00+01:00", + "2019-01-01 19:12:00+01:00", + "2019-01-01 19:13:00+01:00", + "2019-01-01 19:14:00+01:00", + "2019-01-01 19:15:00+01:00", + "2019-01-01 19:16:00+01:00", + "2019-01-01 19:17:00+01:00", + "2019-01-01 19:18:00+01:00", + "2019-01-01 19:19:00+01:00", + "2019-01-01 19:20:00+01:00", + "2019-01-01 19:21:00+01:00", + "2019-01-01 19:22:00+01:00", + "2019-01-01 19:23:00+01:00", + "2019-01-01 19:24:00+01:00", + "2019-01-01 19:25:00+01:00", + "2019-01-01 19:26:00+01:00", + "2019-01-01 19:27:00+01:00", + "2019-01-01 19:28:00+01:00", + "2019-01-01 19:29:00+01:00", + "2019-01-01 19:30:00+01:00", + "2019-01-01 19:31:00+01:00", + "2019-01-01 19:32:00+01:00", + "2019-01-01 19:33:00+01:00", + "2019-01-01 19:34:00+01:00", + "2019-01-01 19:35:00+01:00", + "2019-01-01 19:36:00+01:00", + "2019-01-01 19:37:00+01:00", + "2019-01-01 19:38:00+01:00", + "2019-01-01 19:39:00+01:00", + "2019-01-01 19:40:00+01:00", + "2019-01-01 19:41:00+01:00", + "2019-01-01 19:42:00+01:00", + "2019-01-01 19:43:00+01:00", + "2019-01-01 19:44:00+01:00", + "2019-01-01 19:45:00+01:00", + "2019-01-01 19:46:00+01:00", + "2019-01-01 19:47:00+01:00", + "2019-01-01 19:48:00+01:00", + "2019-01-01 19:49:00+01:00", + "2019-01-01 19:50:00+01:00", + "2019-01-01 19:51:00+01:00", + "2019-01-01 19:52:00+01:00", + "2019-01-01 19:53:00+01:00", + "2019-01-01 19:54:00+01:00", + "2019-01-01 19:55:00+01:00", + "2019-01-01 19:56:00+01:00", + "2019-01-01 19:57:00+01:00", + "2019-01-01 19:58:00+01:00", + "2019-01-01 19:59:00+01:00", + "2019-01-01 20:00:00+01:00", + "2019-01-01 20:01:00+01:00", + "2019-01-01 20:02:00+01:00", + "2019-01-01 20:03:00+01:00", + "2019-01-01 20:04:00+01:00", + "2019-01-01 20:05:00+01:00", + "2019-01-01 20:06:00+01:00", + "2019-01-01 20:07:00+01:00", + "2019-01-01 20:08:00+01:00", + "2019-01-01 20:09:00+01:00", + "2019-01-01 20:10:00+01:00", + "2019-01-01 20:11:00+01:00", + "2019-01-01 20:12:00+01:00", + "2019-01-01 20:13:00+01:00", + "2019-01-01 20:14:00+01:00", + "2019-01-01 20:15:00+01:00", + "2019-01-01 20:16:00+01:00", + "2019-01-01 20:17:00+01:00", + "2019-01-01 20:18:00+01:00", + "2019-01-01 20:19:00+01:00", + "2019-01-01 20:20:00+01:00", + "2019-01-01 20:21:00+01:00", + "2019-01-01 20:22:00+01:00", + "2019-01-01 20:23:00+01:00", + "2019-01-01 20:24:00+01:00", + "2019-01-01 20:25:00+01:00", + "2019-01-01 20:26:00+01:00", + "2019-01-01 20:27:00+01:00", + "2019-01-01 20:28:00+01:00", + "2019-01-01 20:29:00+01:00", + "2019-01-01 20:30:00+01:00", + "2019-01-01 20:31:00+01:00", + "2019-01-01 20:32:00+01:00", + "2019-01-01 20:33:00+01:00", + "2019-01-01 20:34:00+01:00", + "2019-01-01 20:35:00+01:00", + "2019-01-01 20:36:00+01:00", + "2019-01-01 20:37:00+01:00", + "2019-01-01 20:38:00+01:00", + "2019-01-01 20:39:00+01:00", + "2019-01-01 20:40:00+01:00", + "2019-01-01 20:41:00+01:00", + "2019-01-01 20:42:00+01:00", + "2019-01-01 20:43:00+01:00", + "2019-01-01 20:44:00+01:00", + "2019-01-01 20:45:00+01:00", + "2019-01-01 20:46:00+01:00", + "2019-01-01 20:47:00+01:00", + "2019-01-01 20:48:00+01:00", + "2019-01-01 20:49:00+01:00", + "2019-01-01 20:50:00+01:00", + "2019-01-01 20:51:00+01:00", + "2019-01-01 20:52:00+01:00", + "2019-01-01 20:53:00+01:00", + "2019-01-01 20:54:00+01:00", + "2019-01-01 20:55:00+01:00", + "2019-01-01 20:56:00+01:00", + "2019-01-01 20:57:00+01:00", + "2019-01-01 20:58:00+01:00", + "2019-01-01 20:59:00+01:00", + "2019-01-01 21:00:00+01:00", + "2019-01-01 21:01:00+01:00", + "2019-01-01 21:02:00+01:00", + "2019-01-01 21:03:00+01:00", + "2019-01-01 21:04:00+01:00", + "2019-01-01 21:05:00+01:00", + "2019-01-01 21:06:00+01:00", + "2019-01-01 21:07:00+01:00", + "2019-01-01 21:08:00+01:00", + "2019-01-01 21:09:00+01:00", + "2019-01-01 21:10:00+01:00", + "2019-01-01 21:11:00+01:00", + "2019-01-01 21:12:00+01:00", + "2019-01-01 21:13:00+01:00", + "2019-01-01 21:14:00+01:00", + "2019-01-01 21:15:00+01:00", + "2019-01-01 21:16:00+01:00", + "2019-01-01 21:17:00+01:00", + "2019-01-01 21:18:00+01:00", + "2019-01-01 21:19:00+01:00", + "2019-01-01 21:20:00+01:00", + "2019-01-01 21:21:00+01:00", + "2019-01-01 21:22:00+01:00", + "2019-01-01 21:23:00+01:00", + "2019-01-01 21:24:00+01:00", + "2019-01-01 21:25:00+01:00", + "2019-01-01 21:26:00+01:00", + "2019-01-01 21:27:00+01:00", + "2019-01-01 21:28:00+01:00", + "2019-01-01 21:29:00+01:00", + "2019-01-01 21:30:00+01:00", + "2019-01-01 21:31:00+01:00", + "2019-01-01 21:32:00+01:00", + "2019-01-01 21:33:00+01:00", + "2019-01-01 21:34:00+01:00", + "2019-01-01 21:35:00+01:00", + "2019-01-01 21:36:00+01:00", + "2019-01-01 21:37:00+01:00", + "2019-01-01 21:38:00+01:00", + "2019-01-01 21:39:00+01:00", + "2019-01-01 21:40:00+01:00", + "2019-01-01 21:41:00+01:00", + "2019-01-01 21:42:00+01:00", + "2019-01-01 21:43:00+01:00", + "2019-01-01 21:44:00+01:00", + "2019-01-01 21:45:00+01:00", + "2019-01-01 21:46:00+01:00", + "2019-01-01 21:47:00+01:00", + "2019-01-01 21:48:00+01:00", + "2019-01-01 21:49:00+01:00", + "2019-01-01 21:50:00+01:00", + "2019-01-01 21:51:00+01:00", + "2019-01-01 21:52:00+01:00", + "2019-01-01 21:53:00+01:00", + "2019-01-01 21:54:00+01:00", + "2019-01-01 21:55:00+01:00", + "2019-01-01 21:56:00+01:00", + "2019-01-01 21:57:00+01:00", + "2019-01-01 21:58:00+01:00", + "2019-01-01 21:59:00+01:00", + "2019-01-01 22:00:00+01:00", + "2019-01-01 22:01:00+01:00", + "2019-01-01 22:02:00+01:00", + "2019-01-01 22:03:00+01:00", + "2019-01-01 22:04:00+01:00", + "2019-01-01 22:05:00+01:00", + "2019-01-01 22:06:00+01:00", + "2019-01-01 22:07:00+01:00", + "2019-01-01 22:08:00+01:00", + "2019-01-01 22:09:00+01:00", + "2019-01-01 22:10:00+01:00", + "2019-01-01 22:11:00+01:00", + "2019-01-01 22:12:00+01:00", + "2019-01-01 22:13:00+01:00", + "2019-01-01 22:14:00+01:00", + "2019-01-01 22:15:00+01:00", + "2019-01-01 22:16:00+01:00", + "2019-01-01 22:17:00+01:00", + "2019-01-01 22:18:00+01:00", + "2019-01-01 22:19:00+01:00", + "2019-01-01 22:20:00+01:00", + "2019-01-01 22:21:00+01:00", + "2019-01-01 22:22:00+01:00", + "2019-01-01 22:23:00+01:00", + "2019-01-01 22:24:00+01:00", + "2019-01-01 22:25:00+01:00", + "2019-01-01 22:26:00+01:00", + "2019-01-01 22:27:00+01:00", + "2019-01-01 22:28:00+01:00", + "2019-01-01 22:29:00+01:00", + "2019-01-01 22:30:00+01:00", + "2019-01-01 22:31:00+01:00", + "2019-01-01 22:32:00+01:00", + "2019-01-01 22:33:00+01:00", + "2019-01-01 22:34:00+01:00", + "2019-01-01 22:35:00+01:00", + "2019-01-01 22:36:00+01:00", + "2019-01-01 22:37:00+01:00", + "2019-01-01 22:38:00+01:00", + "2019-01-01 22:39:00+01:00", + "2019-01-01 22:40:00+01:00", + "2019-01-01 22:41:00+01:00", + "2019-01-01 22:42:00+01:00", + "2019-01-01 22:43:00+01:00", + "2019-01-01 22:44:00+01:00", + "2019-01-01 22:45:00+01:00", + "2019-01-01 22:46:00+01:00", + "2019-01-01 22:47:00+01:00", + "2019-01-01 22:48:00+01:00", + "2019-01-01 22:49:00+01:00", + "2019-01-01 22:50:00+01:00", + "2019-01-01 22:51:00+01:00", + "2019-01-01 22:52:00+01:00", + "2019-01-01 22:53:00+01:00", + "2019-01-01 22:54:00+01:00", + "2019-01-01 22:55:00+01:00", + "2019-01-01 22:56:00+01:00", + "2019-01-01 22:57:00+01:00", + "2019-01-01 22:58:00+01:00", + "2019-01-01 22:59:00+01:00", + "2019-01-01 23:00:00+01:00", + "2019-01-01 23:01:00+01:00", + "2019-01-01 23:02:00+01:00", + "2019-01-01 23:03:00+01:00", + "2019-01-01 23:04:00+01:00", + "2019-01-01 23:05:00+01:00", + "2019-01-01 23:06:00+01:00", + "2019-01-01 23:07:00+01:00", + "2019-01-01 23:08:00+01:00", + "2019-01-01 23:09:00+01:00", + "2019-01-01 23:10:00+01:00", + "2019-01-01 23:11:00+01:00", + "2019-01-01 23:12:00+01:00", + "2019-01-01 23:13:00+01:00", + "2019-01-01 23:14:00+01:00", + "2019-01-01 23:15:00+01:00", + "2019-01-01 23:16:00+01:00", + "2019-01-01 23:17:00+01:00", + "2019-01-01 23:18:00+01:00", + "2019-01-01 23:19:00+01:00", + "2019-01-01 23:20:00+01:00", + "2019-01-01 23:21:00+01:00", + "2019-01-01 23:22:00+01:00", + "2019-01-01 23:23:00+01:00", + "2019-01-01 23:24:00+01:00", + "2019-01-01 23:25:00+01:00", + "2019-01-01 23:26:00+01:00", + "2019-01-01 23:27:00+01:00", + "2019-01-01 23:28:00+01:00", + "2019-01-01 23:29:00+01:00", + "2019-01-01 23:30:00+01:00", + "2019-01-01 23:31:00+01:00", + "2019-01-01 23:32:00+01:00", + "2019-01-01 23:33:00+01:00", + "2019-01-01 23:34:00+01:00", + "2019-01-01 23:35:00+01:00", + "2019-01-01 23:36:00+01:00", + "2019-01-01 23:37:00+01:00", + "2019-01-01 23:38:00+01:00", + "2019-01-01 23:39:00+01:00", + "2019-01-01 23:40:00+01:00", + "2019-01-01 23:41:00+01:00", + "2019-01-01 23:42:00+01:00", + "2019-01-01 23:43:00+01:00", + "2019-01-01 23:44:00+01:00", + "2019-01-01 23:45:00+01:00", + "2019-01-01 23:46:00+01:00", + "2019-01-01 23:47:00+01:00", + "2019-01-01 23:48:00+01:00", + "2019-01-01 23:49:00+01:00", + "2019-01-01 23:50:00+01:00", + "2019-01-01 23:51:00+01:00", + "2019-01-01 23:52:00+01:00", + "2019-01-01 23:53:00+01:00", + "2019-01-01 23:54:00+01:00", + "2019-01-01 23:55:00+01:00", + "2019-01-01 23:56:00+01:00", + "2019-01-01 23:57:00+01:00", + "2019-01-01 23:58:00+01:00", + "2019-01-01 23:59:00+01:00" + ], + "xaxis": "x", + "y": [ + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286, + -1.4285714285714286 + ], + "yaxis": "y" + }, + { + "line": { + "color": "rgba(55, 128, 191, 1.0)", + "dash": "solid", + "shape": "linear", + "width": 1.3 + }, + "mode": "lines", + "name": "output_MW", + "text": "", + "type": "scatter", + "x": [ + "2019-01-01 00:00:00+01:00", + "2019-01-01 00:01:00+01:00", + "2019-01-01 00:02:00+01:00", + "2019-01-01 00:03:00+01:00", + "2019-01-01 00:04:00+01:00", + "2019-01-01 00:05:00+01:00", + "2019-01-01 00:06:00+01:00", + "2019-01-01 00:07:00+01:00", + "2019-01-01 00:08:00+01:00", + "2019-01-01 00:09:00+01:00", + "2019-01-01 00:10:00+01:00", + "2019-01-01 00:11:00+01:00", + "2019-01-01 00:12:00+01:00", + "2019-01-01 00:13:00+01:00", + "2019-01-01 00:14:00+01:00", + "2019-01-01 00:15:00+01:00", + "2019-01-01 00:16:00+01:00", + "2019-01-01 00:17:00+01:00", + "2019-01-01 00:18:00+01:00", + "2019-01-01 00:19:00+01:00", + "2019-01-01 00:20:00+01:00", + "2019-01-01 00:21:00+01:00", + "2019-01-01 00:22:00+01:00", + "2019-01-01 00:23:00+01:00", + "2019-01-01 00:24:00+01:00", + "2019-01-01 00:25:00+01:00", + "2019-01-01 00:26:00+01:00", + "2019-01-01 00:27:00+01:00", + "2019-01-01 00:28:00+01:00", + "2019-01-01 00:29:00+01:00", + "2019-01-01 00:30:00+01:00", + "2019-01-01 00:31:00+01:00", + "2019-01-01 00:32:00+01:00", + "2019-01-01 00:33:00+01:00", + "2019-01-01 00:34:00+01:00", + "2019-01-01 00:35:00+01:00", + "2019-01-01 00:36:00+01:00", + "2019-01-01 00:37:00+01:00", + "2019-01-01 00:38:00+01:00", + "2019-01-01 00:39:00+01:00", + "2019-01-01 00:40:00+01:00", + "2019-01-01 00:41:00+01:00", + "2019-01-01 00:42:00+01:00", + "2019-01-01 00:43:00+01:00", + "2019-01-01 00:44:00+01:00", + "2019-01-01 00:45:00+01:00", + "2019-01-01 00:46:00+01:00", + "2019-01-01 00:47:00+01:00", + "2019-01-01 00:48:00+01:00", + "2019-01-01 00:49:00+01:00", + "2019-01-01 00:50:00+01:00", + "2019-01-01 00:51:00+01:00", + "2019-01-01 00:52:00+01:00", + "2019-01-01 00:53:00+01:00", + "2019-01-01 00:54:00+01:00", + "2019-01-01 00:55:00+01:00", + "2019-01-01 00:56:00+01:00", + "2019-01-01 00:57:00+01:00", + "2019-01-01 00:58:00+01:00", + "2019-01-01 00:59:00+01:00", + "2019-01-01 01:00:00+01:00", + "2019-01-01 01:01:00+01:00", + "2019-01-01 01:02:00+01:00", + "2019-01-01 01:03:00+01:00", + "2019-01-01 01:04:00+01:00", + "2019-01-01 01:05:00+01:00", + "2019-01-01 01:06:00+01:00", + "2019-01-01 01:07:00+01:00", + "2019-01-01 01:08:00+01:00", + "2019-01-01 01:09:00+01:00", + "2019-01-01 01:10:00+01:00", + "2019-01-01 01:11:00+01:00", + "2019-01-01 01:12:00+01:00", + "2019-01-01 01:13:00+01:00", + "2019-01-01 01:14:00+01:00", + "2019-01-01 01:15:00+01:00", + "2019-01-01 01:16:00+01:00", + "2019-01-01 01:17:00+01:00", + "2019-01-01 01:18:00+01:00", + "2019-01-01 01:19:00+01:00", + "2019-01-01 01:20:00+01:00", + "2019-01-01 01:21:00+01:00", + "2019-01-01 01:22:00+01:00", + "2019-01-01 01:23:00+01:00", + "2019-01-01 01:24:00+01:00", + "2019-01-01 01:25:00+01:00", + "2019-01-01 01:26:00+01:00", + "2019-01-01 01:27:00+01:00", + "2019-01-01 01:28:00+01:00", + "2019-01-01 01:29:00+01:00", + "2019-01-01 01:30:00+01:00", + "2019-01-01 01:31:00+01:00", + "2019-01-01 01:32:00+01:00", + "2019-01-01 01:33:00+01:00", + "2019-01-01 01:34:00+01:00", + "2019-01-01 01:35:00+01:00", + "2019-01-01 01:36:00+01:00", + "2019-01-01 01:37:00+01:00", + "2019-01-01 01:38:00+01:00", + "2019-01-01 01:39:00+01:00", + "2019-01-01 01:40:00+01:00", + "2019-01-01 01:41:00+01:00", + "2019-01-01 01:42:00+01:00", + "2019-01-01 01:43:00+01:00", + "2019-01-01 01:44:00+01:00", + "2019-01-01 01:45:00+01:00", + "2019-01-01 01:46:00+01:00", + "2019-01-01 01:47:00+01:00", + "2019-01-01 01:48:00+01:00", + "2019-01-01 01:49:00+01:00", + "2019-01-01 01:50:00+01:00", + "2019-01-01 01:51:00+01:00", + "2019-01-01 01:52:00+01:00", + "2019-01-01 01:53:00+01:00", + "2019-01-01 01:54:00+01:00", + "2019-01-01 01:55:00+01:00", + "2019-01-01 01:56:00+01:00", + "2019-01-01 01:57:00+01:00", + "2019-01-01 01:58:00+01:00", + "2019-01-01 01:59:00+01:00", + "2019-01-01 02:00:00+01:00", + "2019-01-01 02:01:00+01:00", + "2019-01-01 02:02:00+01:00", + "2019-01-01 02:03:00+01:00", + "2019-01-01 02:04:00+01:00", + "2019-01-01 02:05:00+01:00", + "2019-01-01 02:06:00+01:00", + "2019-01-01 02:07:00+01:00", + "2019-01-01 02:08:00+01:00", + "2019-01-01 02:09:00+01:00", + "2019-01-01 02:10:00+01:00", + "2019-01-01 02:11:00+01:00", + "2019-01-01 02:12:00+01:00", + "2019-01-01 02:13:00+01:00", + "2019-01-01 02:14:00+01:00", + "2019-01-01 02:15:00+01:00", + "2019-01-01 02:16:00+01:00", + "2019-01-01 02:17:00+01:00", + "2019-01-01 02:18:00+01:00", + "2019-01-01 02:19:00+01:00", + "2019-01-01 02:20:00+01:00", + "2019-01-01 02:21:00+01:00", + "2019-01-01 02:22:00+01:00", + "2019-01-01 02:23:00+01:00", + "2019-01-01 02:24:00+01:00", + "2019-01-01 02:25:00+01:00", + "2019-01-01 02:26:00+01:00", + "2019-01-01 02:27:00+01:00", + "2019-01-01 02:28:00+01:00", + "2019-01-01 02:29:00+01:00", + "2019-01-01 02:30:00+01:00", + "2019-01-01 02:31:00+01:00", + "2019-01-01 02:32:00+01:00", + "2019-01-01 02:33:00+01:00", + "2019-01-01 02:34:00+01:00", + "2019-01-01 02:35:00+01:00", + "2019-01-01 02:36:00+01:00", + "2019-01-01 02:37:00+01:00", + "2019-01-01 02:38:00+01:00", + "2019-01-01 02:39:00+01:00", + "2019-01-01 02:40:00+01:00", + "2019-01-01 02:41:00+01:00", + "2019-01-01 02:42:00+01:00", + "2019-01-01 02:43:00+01:00", + "2019-01-01 02:44:00+01:00", + "2019-01-01 02:45:00+01:00", + "2019-01-01 02:46:00+01:00", + "2019-01-01 02:47:00+01:00", + "2019-01-01 02:48:00+01:00", + "2019-01-01 02:49:00+01:00", + "2019-01-01 02:50:00+01:00", + "2019-01-01 02:51:00+01:00", + "2019-01-01 02:52:00+01:00", + "2019-01-01 02:53:00+01:00", + "2019-01-01 02:54:00+01:00", + "2019-01-01 02:55:00+01:00", + "2019-01-01 02:56:00+01:00", + "2019-01-01 02:57:00+01:00", + "2019-01-01 02:58:00+01:00", + "2019-01-01 02:59:00+01:00", + "2019-01-01 03:00:00+01:00", + "2019-01-01 03:01:00+01:00", + "2019-01-01 03:02:00+01:00", + "2019-01-01 03:03:00+01:00", + "2019-01-01 03:04:00+01:00", + "2019-01-01 03:05:00+01:00", + "2019-01-01 03:06:00+01:00", + "2019-01-01 03:07:00+01:00", + "2019-01-01 03:08:00+01:00", + "2019-01-01 03:09:00+01:00", + "2019-01-01 03:10:00+01:00", + "2019-01-01 03:11:00+01:00", + "2019-01-01 03:12:00+01:00", + "2019-01-01 03:13:00+01:00", + "2019-01-01 03:14:00+01:00", + "2019-01-01 03:15:00+01:00", + "2019-01-01 03:16:00+01:00", + "2019-01-01 03:17:00+01:00", + "2019-01-01 03:18:00+01:00", + "2019-01-01 03:19:00+01:00", + "2019-01-01 03:20:00+01:00", + "2019-01-01 03:21:00+01:00", + "2019-01-01 03:22:00+01:00", + "2019-01-01 03:23:00+01:00", + "2019-01-01 03:24:00+01:00", + "2019-01-01 03:25:00+01:00", + "2019-01-01 03:26:00+01:00", + "2019-01-01 03:27:00+01:00", + "2019-01-01 03:28:00+01:00", + "2019-01-01 03:29:00+01:00", + "2019-01-01 03:30:00+01:00", + "2019-01-01 03:31:00+01:00", + "2019-01-01 03:32:00+01:00", + "2019-01-01 03:33:00+01:00", + "2019-01-01 03:34:00+01:00", + "2019-01-01 03:35:00+01:00", + "2019-01-01 03:36:00+01:00", + "2019-01-01 03:37:00+01:00", + "2019-01-01 03:38:00+01:00", + "2019-01-01 03:39:00+01:00", + "2019-01-01 03:40:00+01:00", + "2019-01-01 03:41:00+01:00", + "2019-01-01 03:42:00+01:00", + "2019-01-01 03:43:00+01:00", + "2019-01-01 03:44:00+01:00", + "2019-01-01 03:45:00+01:00", + "2019-01-01 03:46:00+01:00", + "2019-01-01 03:47:00+01:00", + "2019-01-01 03:48:00+01:00", + "2019-01-01 03:49:00+01:00", + "2019-01-01 03:50:00+01:00", + "2019-01-01 03:51:00+01:00", + "2019-01-01 03:52:00+01:00", + "2019-01-01 03:53:00+01:00", + "2019-01-01 03:54:00+01:00", + "2019-01-01 03:55:00+01:00", + "2019-01-01 03:56:00+01:00", + "2019-01-01 03:57:00+01:00", + "2019-01-01 03:58:00+01:00", + "2019-01-01 03:59:00+01:00", + "2019-01-01 04:00:00+01:00", + "2019-01-01 04:01:00+01:00", + "2019-01-01 04:02:00+01:00", + "2019-01-01 04:03:00+01:00", + "2019-01-01 04:04:00+01:00", + "2019-01-01 04:05:00+01:00", + "2019-01-01 04:06:00+01:00", + "2019-01-01 04:07:00+01:00", + "2019-01-01 04:08:00+01:00", + "2019-01-01 04:09:00+01:00", + "2019-01-01 04:10:00+01:00", + "2019-01-01 04:11:00+01:00", + "2019-01-01 04:12:00+01:00", + "2019-01-01 04:13:00+01:00", + "2019-01-01 04:14:00+01:00", + "2019-01-01 04:15:00+01:00", + "2019-01-01 04:16:00+01:00", + "2019-01-01 04:17:00+01:00", + "2019-01-01 04:18:00+01:00", + "2019-01-01 04:19:00+01:00", + "2019-01-01 04:20:00+01:00", + "2019-01-01 04:21:00+01:00", + "2019-01-01 04:22:00+01:00", + "2019-01-01 04:23:00+01:00", + "2019-01-01 04:24:00+01:00", + "2019-01-01 04:25:00+01:00", + "2019-01-01 04:26:00+01:00", + "2019-01-01 04:27:00+01:00", + "2019-01-01 04:28:00+01:00", + "2019-01-01 04:29:00+01:00", + "2019-01-01 04:30:00+01:00", + "2019-01-01 04:31:00+01:00", + "2019-01-01 04:32:00+01:00", + "2019-01-01 04:33:00+01:00", + "2019-01-01 04:34:00+01:00", + "2019-01-01 04:35:00+01:00", + "2019-01-01 04:36:00+01:00", + "2019-01-01 04:37:00+01:00", + "2019-01-01 04:38:00+01:00", + "2019-01-01 04:39:00+01:00", + "2019-01-01 04:40:00+01:00", + "2019-01-01 04:41:00+01:00", + "2019-01-01 04:42:00+01:00", + "2019-01-01 04:43:00+01:00", + "2019-01-01 04:44:00+01:00", + "2019-01-01 04:45:00+01:00", + "2019-01-01 04:46:00+01:00", + "2019-01-01 04:47:00+01:00", + "2019-01-01 04:48:00+01:00", + "2019-01-01 04:49:00+01:00", + "2019-01-01 04:50:00+01:00", + "2019-01-01 04:51:00+01:00", + "2019-01-01 04:52:00+01:00", + "2019-01-01 04:53:00+01:00", + "2019-01-01 04:54:00+01:00", + "2019-01-01 04:55:00+01:00", + "2019-01-01 04:56:00+01:00", + "2019-01-01 04:57:00+01:00", + "2019-01-01 04:58:00+01:00", + "2019-01-01 04:59:00+01:00", + "2019-01-01 05:00:00+01:00", + "2019-01-01 05:01:00+01:00", + "2019-01-01 05:02:00+01:00", + "2019-01-01 05:03:00+01:00", + "2019-01-01 05:04:00+01:00", + "2019-01-01 05:05:00+01:00", + "2019-01-01 05:06:00+01:00", + "2019-01-01 05:07:00+01:00", + "2019-01-01 05:08:00+01:00", + "2019-01-01 05:09:00+01:00", + "2019-01-01 05:10:00+01:00", + "2019-01-01 05:11:00+01:00", + "2019-01-01 05:12:00+01:00", + "2019-01-01 05:13:00+01:00", + "2019-01-01 05:14:00+01:00", + "2019-01-01 05:15:00+01:00", + "2019-01-01 05:16:00+01:00", + "2019-01-01 05:17:00+01:00", + "2019-01-01 05:18:00+01:00", + "2019-01-01 05:19:00+01:00", + "2019-01-01 05:20:00+01:00", + "2019-01-01 05:21:00+01:00", + "2019-01-01 05:22:00+01:00", + "2019-01-01 05:23:00+01:00", + "2019-01-01 05:24:00+01:00", + "2019-01-01 05:25:00+01:00", + "2019-01-01 05:26:00+01:00", + "2019-01-01 05:27:00+01:00", + "2019-01-01 05:28:00+01:00", + "2019-01-01 05:29:00+01:00", + "2019-01-01 05:30:00+01:00", + "2019-01-01 05:31:00+01:00", + "2019-01-01 05:32:00+01:00", + "2019-01-01 05:33:00+01:00", + "2019-01-01 05:34:00+01:00", + "2019-01-01 05:35:00+01:00", + "2019-01-01 05:36:00+01:00", + "2019-01-01 05:37:00+01:00", + "2019-01-01 05:38:00+01:00", + "2019-01-01 05:39:00+01:00", + "2019-01-01 05:40:00+01:00", + "2019-01-01 05:41:00+01:00", + "2019-01-01 05:42:00+01:00", + "2019-01-01 05:43:00+01:00", + "2019-01-01 05:44:00+01:00", + "2019-01-01 05:45:00+01:00", + "2019-01-01 05:46:00+01:00", + "2019-01-01 05:47:00+01:00", + "2019-01-01 05:48:00+01:00", + "2019-01-01 05:49:00+01:00", + "2019-01-01 05:50:00+01:00", + "2019-01-01 05:51:00+01:00", + "2019-01-01 05:52:00+01:00", + "2019-01-01 05:53:00+01:00", + "2019-01-01 05:54:00+01:00", + "2019-01-01 05:55:00+01:00", + "2019-01-01 05:56:00+01:00", + "2019-01-01 05:57:00+01:00", + "2019-01-01 05:58:00+01:00", + "2019-01-01 05:59:00+01:00", + "2019-01-01 06:00:00+01:00", + "2019-01-01 06:01:00+01:00", + "2019-01-01 06:02:00+01:00", + "2019-01-01 06:03:00+01:00", + "2019-01-01 06:04:00+01:00", + "2019-01-01 06:05:00+01:00", + "2019-01-01 06:06:00+01:00", + "2019-01-01 06:07:00+01:00", + "2019-01-01 06:08:00+01:00", + "2019-01-01 06:09:00+01:00", + "2019-01-01 06:10:00+01:00", + "2019-01-01 06:11:00+01:00", + "2019-01-01 06:12:00+01:00", + "2019-01-01 06:13:00+01:00", + "2019-01-01 06:14:00+01:00", + "2019-01-01 06:15:00+01:00", + "2019-01-01 06:16:00+01:00", + "2019-01-01 06:17:00+01:00", + "2019-01-01 06:18:00+01:00", + "2019-01-01 06:19:00+01:00", + "2019-01-01 06:20:00+01:00", + "2019-01-01 06:21:00+01:00", + "2019-01-01 06:22:00+01:00", + "2019-01-01 06:23:00+01:00", + "2019-01-01 06:24:00+01:00", + "2019-01-01 06:25:00+01:00", + "2019-01-01 06:26:00+01:00", + "2019-01-01 06:27:00+01:00", + "2019-01-01 06:28:00+01:00", + "2019-01-01 06:29:00+01:00", + "2019-01-01 06:30:00+01:00", + "2019-01-01 06:31:00+01:00", + "2019-01-01 06:32:00+01:00", + "2019-01-01 06:33:00+01:00", + "2019-01-01 06:34:00+01:00", + "2019-01-01 06:35:00+01:00", + "2019-01-01 06:36:00+01:00", + "2019-01-01 06:37:00+01:00", + "2019-01-01 06:38:00+01:00", + "2019-01-01 06:39:00+01:00", + "2019-01-01 06:40:00+01:00", + "2019-01-01 06:41:00+01:00", + "2019-01-01 06:42:00+01:00", + "2019-01-01 06:43:00+01:00", + "2019-01-01 06:44:00+01:00", + "2019-01-01 06:45:00+01:00", + "2019-01-01 06:46:00+01:00", + "2019-01-01 06:47:00+01:00", + "2019-01-01 06:48:00+01:00", + "2019-01-01 06:49:00+01:00", + "2019-01-01 06:50:00+01:00", + "2019-01-01 06:51:00+01:00", + "2019-01-01 06:52:00+01:00", + "2019-01-01 06:53:00+01:00", + "2019-01-01 06:54:00+01:00", + "2019-01-01 06:55:00+01:00", + "2019-01-01 06:56:00+01:00", + "2019-01-01 06:57:00+01:00", + "2019-01-01 06:58:00+01:00", + "2019-01-01 06:59:00+01:00", + "2019-01-01 07:00:00+01:00", + "2019-01-01 07:01:00+01:00", + "2019-01-01 07:02:00+01:00", + "2019-01-01 07:03:00+01:00", + "2019-01-01 07:04:00+01:00", + "2019-01-01 07:05:00+01:00", + "2019-01-01 07:06:00+01:00", + "2019-01-01 07:07:00+01:00", + "2019-01-01 07:08:00+01:00", + "2019-01-01 07:09:00+01:00", + "2019-01-01 07:10:00+01:00", + "2019-01-01 07:11:00+01:00", + "2019-01-01 07:12:00+01:00", + "2019-01-01 07:13:00+01:00", + "2019-01-01 07:14:00+01:00", + "2019-01-01 07:15:00+01:00", + "2019-01-01 07:16:00+01:00", + "2019-01-01 07:17:00+01:00", + "2019-01-01 07:18:00+01:00", + "2019-01-01 07:19:00+01:00", + "2019-01-01 07:20:00+01:00", + "2019-01-01 07:21:00+01:00", + "2019-01-01 07:22:00+01:00", + "2019-01-01 07:23:00+01:00", + "2019-01-01 07:24:00+01:00", + "2019-01-01 07:25:00+01:00", + "2019-01-01 07:26:00+01:00", + "2019-01-01 07:27:00+01:00", + "2019-01-01 07:28:00+01:00", + "2019-01-01 07:29:00+01:00", + "2019-01-01 07:30:00+01:00", + "2019-01-01 07:31:00+01:00", + "2019-01-01 07:32:00+01:00", + "2019-01-01 07:33:00+01:00", + "2019-01-01 07:34:00+01:00", + "2019-01-01 07:35:00+01:00", + "2019-01-01 07:36:00+01:00", + "2019-01-01 07:37:00+01:00", + "2019-01-01 07:38:00+01:00", + "2019-01-01 07:39:00+01:00", + "2019-01-01 07:40:00+01:00", + "2019-01-01 07:41:00+01:00", + "2019-01-01 07:42:00+01:00", + "2019-01-01 07:43:00+01:00", + "2019-01-01 07:44:00+01:00", + "2019-01-01 07:45:00+01:00", + "2019-01-01 07:46:00+01:00", + "2019-01-01 07:47:00+01:00", + "2019-01-01 07:48:00+01:00", + "2019-01-01 07:49:00+01:00", + "2019-01-01 07:50:00+01:00", + "2019-01-01 07:51:00+01:00", + "2019-01-01 07:52:00+01:00", + "2019-01-01 07:53:00+01:00", + "2019-01-01 07:54:00+01:00", + "2019-01-01 07:55:00+01:00", + "2019-01-01 07:56:00+01:00", + "2019-01-01 07:57:00+01:00", + "2019-01-01 07:58:00+01:00", + "2019-01-01 07:59:00+01:00", + "2019-01-01 08:00:00+01:00", + "2019-01-01 08:01:00+01:00", + "2019-01-01 08:02:00+01:00", + "2019-01-01 08:03:00+01:00", + "2019-01-01 08:04:00+01:00", + "2019-01-01 08:05:00+01:00", + "2019-01-01 08:06:00+01:00", + "2019-01-01 08:07:00+01:00", + "2019-01-01 08:08:00+01:00", + "2019-01-01 08:09:00+01:00", + "2019-01-01 08:10:00+01:00", + "2019-01-01 08:11:00+01:00", + "2019-01-01 08:12:00+01:00", + "2019-01-01 08:13:00+01:00", + "2019-01-01 08:14:00+01:00", + "2019-01-01 08:15:00+01:00", + "2019-01-01 08:16:00+01:00", + "2019-01-01 08:17:00+01:00", + "2019-01-01 08:18:00+01:00", + "2019-01-01 08:19:00+01:00", + "2019-01-01 08:20:00+01:00", + "2019-01-01 08:21:00+01:00", + "2019-01-01 08:22:00+01:00", + "2019-01-01 08:23:00+01:00", + "2019-01-01 08:24:00+01:00", + "2019-01-01 08:25:00+01:00", + "2019-01-01 08:26:00+01:00", + "2019-01-01 08:27:00+01:00", + "2019-01-01 08:28:00+01:00", + "2019-01-01 08:29:00+01:00", + "2019-01-01 08:30:00+01:00", + "2019-01-01 08:31:00+01:00", + "2019-01-01 08:32:00+01:00", + "2019-01-01 08:33:00+01:00", + "2019-01-01 08:34:00+01:00", + "2019-01-01 08:35:00+01:00", + "2019-01-01 08:36:00+01:00", + "2019-01-01 08:37:00+01:00", + "2019-01-01 08:38:00+01:00", + "2019-01-01 08:39:00+01:00", + "2019-01-01 08:40:00+01:00", + "2019-01-01 08:41:00+01:00", + "2019-01-01 08:42:00+01:00", + "2019-01-01 08:43:00+01:00", + "2019-01-01 08:44:00+01:00", + "2019-01-01 08:45:00+01:00", + "2019-01-01 08:46:00+01:00", + "2019-01-01 08:47:00+01:00", + "2019-01-01 08:48:00+01:00", + "2019-01-01 08:49:00+01:00", + "2019-01-01 08:50:00+01:00", + "2019-01-01 08:51:00+01:00", + "2019-01-01 08:52:00+01:00", + "2019-01-01 08:53:00+01:00", + "2019-01-01 08:54:00+01:00", + "2019-01-01 08:55:00+01:00", + "2019-01-01 08:56:00+01:00", + "2019-01-01 08:57:00+01:00", + "2019-01-01 08:58:00+01:00", + "2019-01-01 08:59:00+01:00", + "2019-01-01 09:00:00+01:00", + "2019-01-01 09:01:00+01:00", + "2019-01-01 09:02:00+01:00", + "2019-01-01 09:03:00+01:00", + "2019-01-01 09:04:00+01:00", + "2019-01-01 09:05:00+01:00", + "2019-01-01 09:06:00+01:00", + "2019-01-01 09:07:00+01:00", + "2019-01-01 09:08:00+01:00", + "2019-01-01 09:09:00+01:00", + "2019-01-01 09:10:00+01:00", + "2019-01-01 09:11:00+01:00", + "2019-01-01 09:12:00+01:00", + "2019-01-01 09:13:00+01:00", + "2019-01-01 09:14:00+01:00", + "2019-01-01 09:15:00+01:00", + "2019-01-01 09:16:00+01:00", + "2019-01-01 09:17:00+01:00", + "2019-01-01 09:18:00+01:00", + "2019-01-01 09:19:00+01:00", + "2019-01-01 09:20:00+01:00", + "2019-01-01 09:21:00+01:00", + "2019-01-01 09:22:00+01:00", + "2019-01-01 09:23:00+01:00", + "2019-01-01 09:24:00+01:00", + "2019-01-01 09:25:00+01:00", + "2019-01-01 09:26:00+01:00", + "2019-01-01 09:27:00+01:00", + "2019-01-01 09:28:00+01:00", + "2019-01-01 09:29:00+01:00", + "2019-01-01 09:30:00+01:00", + "2019-01-01 09:31:00+01:00", + "2019-01-01 09:32:00+01:00", + "2019-01-01 09:33:00+01:00", + "2019-01-01 09:34:00+01:00", + "2019-01-01 09:35:00+01:00", + "2019-01-01 09:36:00+01:00", + "2019-01-01 09:37:00+01:00", + "2019-01-01 09:38:00+01:00", + "2019-01-01 09:39:00+01:00", + "2019-01-01 09:40:00+01:00", + "2019-01-01 09:41:00+01:00", + "2019-01-01 09:42:00+01:00", + "2019-01-01 09:43:00+01:00", + "2019-01-01 09:44:00+01:00", + "2019-01-01 09:45:00+01:00", + "2019-01-01 09:46:00+01:00", + "2019-01-01 09:47:00+01:00", + "2019-01-01 09:48:00+01:00", + "2019-01-01 09:49:00+01:00", + "2019-01-01 09:50:00+01:00", + "2019-01-01 09:51:00+01:00", + "2019-01-01 09:52:00+01:00", + "2019-01-01 09:53:00+01:00", + "2019-01-01 09:54:00+01:00", + "2019-01-01 09:55:00+01:00", + "2019-01-01 09:56:00+01:00", + "2019-01-01 09:57:00+01:00", + "2019-01-01 09:58:00+01:00", + "2019-01-01 09:59:00+01:00", + "2019-01-01 10:00:00+01:00", + "2019-01-01 10:01:00+01:00", + "2019-01-01 10:02:00+01:00", + "2019-01-01 10:03:00+01:00", + "2019-01-01 10:04:00+01:00", + "2019-01-01 10:05:00+01:00", + "2019-01-01 10:06:00+01:00", + "2019-01-01 10:07:00+01:00", + "2019-01-01 10:08:00+01:00", + "2019-01-01 10:09:00+01:00", + "2019-01-01 10:10:00+01:00", + "2019-01-01 10:11:00+01:00", + "2019-01-01 10:12:00+01:00", + "2019-01-01 10:13:00+01:00", + "2019-01-01 10:14:00+01:00", + "2019-01-01 10:15:00+01:00", + "2019-01-01 10:16:00+01:00", + "2019-01-01 10:17:00+01:00", + "2019-01-01 10:18:00+01:00", + "2019-01-01 10:19:00+01:00", + "2019-01-01 10:20:00+01:00", + "2019-01-01 10:21:00+01:00", + "2019-01-01 10:22:00+01:00", + "2019-01-01 10:23:00+01:00", + "2019-01-01 10:24:00+01:00", + "2019-01-01 10:25:00+01:00", + "2019-01-01 10:26:00+01:00", + "2019-01-01 10:27:00+01:00", + "2019-01-01 10:28:00+01:00", + "2019-01-01 10:29:00+01:00", + "2019-01-01 10:30:00+01:00", + "2019-01-01 10:31:00+01:00", + "2019-01-01 10:32:00+01:00", + "2019-01-01 10:33:00+01:00", + "2019-01-01 10:34:00+01:00", + "2019-01-01 10:35:00+01:00", + "2019-01-01 10:36:00+01:00", + "2019-01-01 10:37:00+01:00", + "2019-01-01 10:38:00+01:00", + "2019-01-01 10:39:00+01:00", + "2019-01-01 10:40:00+01:00", + "2019-01-01 10:41:00+01:00", + "2019-01-01 10:42:00+01:00", + "2019-01-01 10:43:00+01:00", + "2019-01-01 10:44:00+01:00", + "2019-01-01 10:45:00+01:00", + "2019-01-01 10:46:00+01:00", + "2019-01-01 10:47:00+01:00", + "2019-01-01 10:48:00+01:00", + "2019-01-01 10:49:00+01:00", + "2019-01-01 10:50:00+01:00", + "2019-01-01 10:51:00+01:00", + "2019-01-01 10:52:00+01:00", + "2019-01-01 10:53:00+01:00", + "2019-01-01 10:54:00+01:00", + "2019-01-01 10:55:00+01:00", + "2019-01-01 10:56:00+01:00", + "2019-01-01 10:57:00+01:00", + "2019-01-01 10:58:00+01:00", + "2019-01-01 10:59:00+01:00", + "2019-01-01 11:00:00+01:00", + "2019-01-01 11:01:00+01:00", + "2019-01-01 11:02:00+01:00", + "2019-01-01 11:03:00+01:00", + "2019-01-01 11:04:00+01:00", + "2019-01-01 11:05:00+01:00", + "2019-01-01 11:06:00+01:00", + "2019-01-01 11:07:00+01:00", + "2019-01-01 11:08:00+01:00", + "2019-01-01 11:09:00+01:00", + "2019-01-01 11:10:00+01:00", + "2019-01-01 11:11:00+01:00", + "2019-01-01 11:12:00+01:00", + "2019-01-01 11:13:00+01:00", + "2019-01-01 11:14:00+01:00", + "2019-01-01 11:15:00+01:00", + "2019-01-01 11:16:00+01:00", + "2019-01-01 11:17:00+01:00", + "2019-01-01 11:18:00+01:00", + "2019-01-01 11:19:00+01:00", + "2019-01-01 11:20:00+01:00", + "2019-01-01 11:21:00+01:00", + "2019-01-01 11:22:00+01:00", + "2019-01-01 11:23:00+01:00", + "2019-01-01 11:24:00+01:00", + "2019-01-01 11:25:00+01:00", + "2019-01-01 11:26:00+01:00", + "2019-01-01 11:27:00+01:00", + "2019-01-01 11:28:00+01:00", + "2019-01-01 11:29:00+01:00", + "2019-01-01 11:30:00+01:00", + "2019-01-01 11:31:00+01:00", + "2019-01-01 11:32:00+01:00", + "2019-01-01 11:33:00+01:00", + "2019-01-01 11:34:00+01:00", + "2019-01-01 11:35:00+01:00", + "2019-01-01 11:36:00+01:00", + "2019-01-01 11:37:00+01:00", + "2019-01-01 11:38:00+01:00", + "2019-01-01 11:39:00+01:00", + "2019-01-01 11:40:00+01:00", + "2019-01-01 11:41:00+01:00", + "2019-01-01 11:42:00+01:00", + "2019-01-01 11:43:00+01:00", + "2019-01-01 11:44:00+01:00", + "2019-01-01 11:45:00+01:00", + "2019-01-01 11:46:00+01:00", + "2019-01-01 11:47:00+01:00", + "2019-01-01 11:48:00+01:00", + "2019-01-01 11:49:00+01:00", + "2019-01-01 11:50:00+01:00", + "2019-01-01 11:51:00+01:00", + "2019-01-01 11:52:00+01:00", + "2019-01-01 11:53:00+01:00", + "2019-01-01 11:54:00+01:00", + "2019-01-01 11:55:00+01:00", + "2019-01-01 11:56:00+01:00", + "2019-01-01 11:57:00+01:00", + "2019-01-01 11:58:00+01:00", + "2019-01-01 11:59:00+01:00", + "2019-01-01 12:00:00+01:00", + "2019-01-01 12:01:00+01:00", + "2019-01-01 12:02:00+01:00", + "2019-01-01 12:03:00+01:00", + "2019-01-01 12:04:00+01:00", + "2019-01-01 12:05:00+01:00", + "2019-01-01 12:06:00+01:00", + "2019-01-01 12:07:00+01:00", + "2019-01-01 12:08:00+01:00", + "2019-01-01 12:09:00+01:00", + "2019-01-01 12:10:00+01:00", + "2019-01-01 12:11:00+01:00", + "2019-01-01 12:12:00+01:00", + "2019-01-01 12:13:00+01:00", + "2019-01-01 12:14:00+01:00", + "2019-01-01 12:15:00+01:00", + "2019-01-01 12:16:00+01:00", + "2019-01-01 12:17:00+01:00", + "2019-01-01 12:18:00+01:00", + "2019-01-01 12:19:00+01:00", + "2019-01-01 12:20:00+01:00", + "2019-01-01 12:21:00+01:00", + "2019-01-01 12:22:00+01:00", + "2019-01-01 12:23:00+01:00", + "2019-01-01 12:24:00+01:00", + "2019-01-01 12:25:00+01:00", + "2019-01-01 12:26:00+01:00", + "2019-01-01 12:27:00+01:00", + "2019-01-01 12:28:00+01:00", + "2019-01-01 12:29:00+01:00", + "2019-01-01 12:30:00+01:00", + "2019-01-01 12:31:00+01:00", + "2019-01-01 12:32:00+01:00", + "2019-01-01 12:33:00+01:00", + "2019-01-01 12:34:00+01:00", + "2019-01-01 12:35:00+01:00", + "2019-01-01 12:36:00+01:00", + "2019-01-01 12:37:00+01:00", + "2019-01-01 12:38:00+01:00", + "2019-01-01 12:39:00+01:00", + "2019-01-01 12:40:00+01:00", + "2019-01-01 12:41:00+01:00", + "2019-01-01 12:42:00+01:00", + "2019-01-01 12:43:00+01:00", + "2019-01-01 12:44:00+01:00", + "2019-01-01 12:45:00+01:00", + "2019-01-01 12:46:00+01:00", + "2019-01-01 12:47:00+01:00", + "2019-01-01 12:48:00+01:00", + "2019-01-01 12:49:00+01:00", + "2019-01-01 12:50:00+01:00", + "2019-01-01 12:51:00+01:00", + "2019-01-01 12:52:00+01:00", + "2019-01-01 12:53:00+01:00", + "2019-01-01 12:54:00+01:00", + "2019-01-01 12:55:00+01:00", + "2019-01-01 12:56:00+01:00", + "2019-01-01 12:57:00+01:00", + "2019-01-01 12:58:00+01:00", + "2019-01-01 12:59:00+01:00", + "2019-01-01 13:00:00+01:00", + "2019-01-01 13:01:00+01:00", + "2019-01-01 13:02:00+01:00", + "2019-01-01 13:03:00+01:00", + "2019-01-01 13:04:00+01:00", + "2019-01-01 13:05:00+01:00", + "2019-01-01 13:06:00+01:00", + "2019-01-01 13:07:00+01:00", + "2019-01-01 13:08:00+01:00", + "2019-01-01 13:09:00+01:00", + "2019-01-01 13:10:00+01:00", + "2019-01-01 13:11:00+01:00", + "2019-01-01 13:12:00+01:00", + "2019-01-01 13:13:00+01:00", + "2019-01-01 13:14:00+01:00", + "2019-01-01 13:15:00+01:00", + "2019-01-01 13:16:00+01:00", + "2019-01-01 13:17:00+01:00", + "2019-01-01 13:18:00+01:00", + "2019-01-01 13:19:00+01:00", + "2019-01-01 13:20:00+01:00", + "2019-01-01 13:21:00+01:00", + "2019-01-01 13:22:00+01:00", + "2019-01-01 13:23:00+01:00", + "2019-01-01 13:24:00+01:00", + "2019-01-01 13:25:00+01:00", + "2019-01-01 13:26:00+01:00", + "2019-01-01 13:27:00+01:00", + "2019-01-01 13:28:00+01:00", + "2019-01-01 13:29:00+01:00", + "2019-01-01 13:30:00+01:00", + "2019-01-01 13:31:00+01:00", + "2019-01-01 13:32:00+01:00", + "2019-01-01 13:33:00+01:00", + "2019-01-01 13:34:00+01:00", + "2019-01-01 13:35:00+01:00", + "2019-01-01 13:36:00+01:00", + "2019-01-01 13:37:00+01:00", + "2019-01-01 13:38:00+01:00", + "2019-01-01 13:39:00+01:00", + "2019-01-01 13:40:00+01:00", + "2019-01-01 13:41:00+01:00", + "2019-01-01 13:42:00+01:00", + "2019-01-01 13:43:00+01:00", + "2019-01-01 13:44:00+01:00", + "2019-01-01 13:45:00+01:00", + "2019-01-01 13:46:00+01:00", + "2019-01-01 13:47:00+01:00", + "2019-01-01 13:48:00+01:00", + "2019-01-01 13:49:00+01:00", + "2019-01-01 13:50:00+01:00", + "2019-01-01 13:51:00+01:00", + "2019-01-01 13:52:00+01:00", + "2019-01-01 13:53:00+01:00", + "2019-01-01 13:54:00+01:00", + "2019-01-01 13:55:00+01:00", + "2019-01-01 13:56:00+01:00", + "2019-01-01 13:57:00+01:00", + "2019-01-01 13:58:00+01:00", + "2019-01-01 13:59:00+01:00", + "2019-01-01 14:00:00+01:00", + "2019-01-01 14:01:00+01:00", + "2019-01-01 14:02:00+01:00", + "2019-01-01 14:03:00+01:00", + "2019-01-01 14:04:00+01:00", + "2019-01-01 14:05:00+01:00", + "2019-01-01 14:06:00+01:00", + "2019-01-01 14:07:00+01:00", + "2019-01-01 14:08:00+01:00", + "2019-01-01 14:09:00+01:00", + "2019-01-01 14:10:00+01:00", + "2019-01-01 14:11:00+01:00", + "2019-01-01 14:12:00+01:00", + "2019-01-01 14:13:00+01:00", + "2019-01-01 14:14:00+01:00", + "2019-01-01 14:15:00+01:00", + "2019-01-01 14:16:00+01:00", + "2019-01-01 14:17:00+01:00", + "2019-01-01 14:18:00+01:00", + "2019-01-01 14:19:00+01:00", + "2019-01-01 14:20:00+01:00", + "2019-01-01 14:21:00+01:00", + "2019-01-01 14:22:00+01:00", + "2019-01-01 14:23:00+01:00", + "2019-01-01 14:24:00+01:00", + "2019-01-01 14:25:00+01:00", + "2019-01-01 14:26:00+01:00", + "2019-01-01 14:27:00+01:00", + "2019-01-01 14:28:00+01:00", + "2019-01-01 14:29:00+01:00", + "2019-01-01 14:30:00+01:00", + "2019-01-01 14:31:00+01:00", + "2019-01-01 14:32:00+01:00", + "2019-01-01 14:33:00+01:00", + "2019-01-01 14:34:00+01:00", + "2019-01-01 14:35:00+01:00", + "2019-01-01 14:36:00+01:00", + "2019-01-01 14:37:00+01:00", + "2019-01-01 14:38:00+01:00", + "2019-01-01 14:39:00+01:00", + "2019-01-01 14:40:00+01:00", + "2019-01-01 14:41:00+01:00", + "2019-01-01 14:42:00+01:00", + "2019-01-01 14:43:00+01:00", + "2019-01-01 14:44:00+01:00", + "2019-01-01 14:45:00+01:00", + "2019-01-01 14:46:00+01:00", + "2019-01-01 14:47:00+01:00", + "2019-01-01 14:48:00+01:00", + "2019-01-01 14:49:00+01:00", + "2019-01-01 14:50:00+01:00", + "2019-01-01 14:51:00+01:00", + "2019-01-01 14:52:00+01:00", + "2019-01-01 14:53:00+01:00", + "2019-01-01 14:54:00+01:00", + "2019-01-01 14:55:00+01:00", + "2019-01-01 14:56:00+01:00", + "2019-01-01 14:57:00+01:00", + "2019-01-01 14:58:00+01:00", + "2019-01-01 14:59:00+01:00", + "2019-01-01 15:00:00+01:00", + "2019-01-01 15:01:00+01:00", + "2019-01-01 15:02:00+01:00", + "2019-01-01 15:03:00+01:00", + "2019-01-01 15:04:00+01:00", + "2019-01-01 15:05:00+01:00", + "2019-01-01 15:06:00+01:00", + "2019-01-01 15:07:00+01:00", + "2019-01-01 15:08:00+01:00", + "2019-01-01 15:09:00+01:00", + "2019-01-01 15:10:00+01:00", + "2019-01-01 15:11:00+01:00", + "2019-01-01 15:12:00+01:00", + "2019-01-01 15:13:00+01:00", + "2019-01-01 15:14:00+01:00", + "2019-01-01 15:15:00+01:00", + "2019-01-01 15:16:00+01:00", + "2019-01-01 15:17:00+01:00", + "2019-01-01 15:18:00+01:00", + "2019-01-01 15:19:00+01:00", + "2019-01-01 15:20:00+01:00", + "2019-01-01 15:21:00+01:00", + "2019-01-01 15:22:00+01:00", + "2019-01-01 15:23:00+01:00", + "2019-01-01 15:24:00+01:00", + "2019-01-01 15:25:00+01:00", + "2019-01-01 15:26:00+01:00", + "2019-01-01 15:27:00+01:00", + "2019-01-01 15:28:00+01:00", + "2019-01-01 15:29:00+01:00", + "2019-01-01 15:30:00+01:00", + "2019-01-01 15:31:00+01:00", + "2019-01-01 15:32:00+01:00", + "2019-01-01 15:33:00+01:00", + "2019-01-01 15:34:00+01:00", + "2019-01-01 15:35:00+01:00", + "2019-01-01 15:36:00+01:00", + "2019-01-01 15:37:00+01:00", + "2019-01-01 15:38:00+01:00", + "2019-01-01 15:39:00+01:00", + "2019-01-01 15:40:00+01:00", + "2019-01-01 15:41:00+01:00", + "2019-01-01 15:42:00+01:00", + "2019-01-01 15:43:00+01:00", + "2019-01-01 15:44:00+01:00", + "2019-01-01 15:45:00+01:00", + "2019-01-01 15:46:00+01:00", + "2019-01-01 15:47:00+01:00", + "2019-01-01 15:48:00+01:00", + "2019-01-01 15:49:00+01:00", + "2019-01-01 15:50:00+01:00", + "2019-01-01 15:51:00+01:00", + "2019-01-01 15:52:00+01:00", + "2019-01-01 15:53:00+01:00", + "2019-01-01 15:54:00+01:00", + "2019-01-01 15:55:00+01:00", + "2019-01-01 15:56:00+01:00", + "2019-01-01 15:57:00+01:00", + "2019-01-01 15:58:00+01:00", + "2019-01-01 15:59:00+01:00", + "2019-01-01 16:00:00+01:00", + "2019-01-01 16:01:00+01:00", + "2019-01-01 16:02:00+01:00", + "2019-01-01 16:03:00+01:00", + "2019-01-01 16:04:00+01:00", + "2019-01-01 16:05:00+01:00", + "2019-01-01 16:06:00+01:00", + "2019-01-01 16:07:00+01:00", + "2019-01-01 16:08:00+01:00", + "2019-01-01 16:09:00+01:00", + "2019-01-01 16:10:00+01:00", + "2019-01-01 16:11:00+01:00", + "2019-01-01 16:12:00+01:00", + "2019-01-01 16:13:00+01:00", + "2019-01-01 16:14:00+01:00", + "2019-01-01 16:15:00+01:00", + "2019-01-01 16:16:00+01:00", + "2019-01-01 16:17:00+01:00", + "2019-01-01 16:18:00+01:00", + "2019-01-01 16:19:00+01:00", + "2019-01-01 16:20:00+01:00", + "2019-01-01 16:21:00+01:00", + "2019-01-01 16:22:00+01:00", + "2019-01-01 16:23:00+01:00", + "2019-01-01 16:24:00+01:00", + "2019-01-01 16:25:00+01:00", + "2019-01-01 16:26:00+01:00", + "2019-01-01 16:27:00+01:00", + "2019-01-01 16:28:00+01:00", + "2019-01-01 16:29:00+01:00", + "2019-01-01 16:30:00+01:00", + "2019-01-01 16:31:00+01:00", + "2019-01-01 16:32:00+01:00", + "2019-01-01 16:33:00+01:00", + "2019-01-01 16:34:00+01:00", + "2019-01-01 16:35:00+01:00", + "2019-01-01 16:36:00+01:00", + "2019-01-01 16:37:00+01:00", + "2019-01-01 16:38:00+01:00", + "2019-01-01 16:39:00+01:00", + "2019-01-01 16:40:00+01:00", + "2019-01-01 16:41:00+01:00", + "2019-01-01 16:42:00+01:00", + "2019-01-01 16:43:00+01:00", + "2019-01-01 16:44:00+01:00", + "2019-01-01 16:45:00+01:00", + "2019-01-01 16:46:00+01:00", + "2019-01-01 16:47:00+01:00", + "2019-01-01 16:48:00+01:00", + "2019-01-01 16:49:00+01:00", + "2019-01-01 16:50:00+01:00", + "2019-01-01 16:51:00+01:00", + "2019-01-01 16:52:00+01:00", + "2019-01-01 16:53:00+01:00", + "2019-01-01 16:54:00+01:00", + "2019-01-01 16:55:00+01:00", + "2019-01-01 16:56:00+01:00", + "2019-01-01 16:57:00+01:00", + "2019-01-01 16:58:00+01:00", + "2019-01-01 16:59:00+01:00", + "2019-01-01 17:00:00+01:00", + "2019-01-01 17:01:00+01:00", + "2019-01-01 17:02:00+01:00", + "2019-01-01 17:03:00+01:00", + "2019-01-01 17:04:00+01:00", + "2019-01-01 17:05:00+01:00", + "2019-01-01 17:06:00+01:00", + "2019-01-01 17:07:00+01:00", + "2019-01-01 17:08:00+01:00", + "2019-01-01 17:09:00+01:00", + "2019-01-01 17:10:00+01:00", + "2019-01-01 17:11:00+01:00", + "2019-01-01 17:12:00+01:00", + "2019-01-01 17:13:00+01:00", + "2019-01-01 17:14:00+01:00", + "2019-01-01 17:15:00+01:00", + "2019-01-01 17:16:00+01:00", + "2019-01-01 17:17:00+01:00", + "2019-01-01 17:18:00+01:00", + "2019-01-01 17:19:00+01:00", + "2019-01-01 17:20:00+01:00", + "2019-01-01 17:21:00+01:00", + "2019-01-01 17:22:00+01:00", + "2019-01-01 17:23:00+01:00", + "2019-01-01 17:24:00+01:00", + "2019-01-01 17:25:00+01:00", + "2019-01-01 17:26:00+01:00", + "2019-01-01 17:27:00+01:00", + "2019-01-01 17:28:00+01:00", + "2019-01-01 17:29:00+01:00", + "2019-01-01 17:30:00+01:00", + "2019-01-01 17:31:00+01:00", + "2019-01-01 17:32:00+01:00", + "2019-01-01 17:33:00+01:00", + "2019-01-01 17:34:00+01:00", + "2019-01-01 17:35:00+01:00", + "2019-01-01 17:36:00+01:00", + "2019-01-01 17:37:00+01:00", + "2019-01-01 17:38:00+01:00", + "2019-01-01 17:39:00+01:00", + "2019-01-01 17:40:00+01:00", + "2019-01-01 17:41:00+01:00", + "2019-01-01 17:42:00+01:00", + "2019-01-01 17:43:00+01:00", + "2019-01-01 17:44:00+01:00", + "2019-01-01 17:45:00+01:00", + "2019-01-01 17:46:00+01:00", + "2019-01-01 17:47:00+01:00", + "2019-01-01 17:48:00+01:00", + "2019-01-01 17:49:00+01:00", + "2019-01-01 17:50:00+01:00", + "2019-01-01 17:51:00+01:00", + "2019-01-01 17:52:00+01:00", + "2019-01-01 17:53:00+01:00", + "2019-01-01 17:54:00+01:00", + "2019-01-01 17:55:00+01:00", + "2019-01-01 17:56:00+01:00", + "2019-01-01 17:57:00+01:00", + "2019-01-01 17:58:00+01:00", + "2019-01-01 17:59:00+01:00", + "2019-01-01 18:00:00+01:00", + "2019-01-01 18:01:00+01:00", + "2019-01-01 18:02:00+01:00", + "2019-01-01 18:03:00+01:00", + "2019-01-01 18:04:00+01:00", + "2019-01-01 18:05:00+01:00", + "2019-01-01 18:06:00+01:00", + "2019-01-01 18:07:00+01:00", + "2019-01-01 18:08:00+01:00", + "2019-01-01 18:09:00+01:00", + "2019-01-01 18:10:00+01:00", + "2019-01-01 18:11:00+01:00", + "2019-01-01 18:12:00+01:00", + "2019-01-01 18:13:00+01:00", + "2019-01-01 18:14:00+01:00", + "2019-01-01 18:15:00+01:00", + "2019-01-01 18:16:00+01:00", + "2019-01-01 18:17:00+01:00", + "2019-01-01 18:18:00+01:00", + "2019-01-01 18:19:00+01:00", + "2019-01-01 18:20:00+01:00", + "2019-01-01 18:21:00+01:00", + "2019-01-01 18:22:00+01:00", + "2019-01-01 18:23:00+01:00", + "2019-01-01 18:24:00+01:00", + "2019-01-01 18:25:00+01:00", + "2019-01-01 18:26:00+01:00", + "2019-01-01 18:27:00+01:00", + "2019-01-01 18:28:00+01:00", + "2019-01-01 18:29:00+01:00", + "2019-01-01 18:30:00+01:00", + "2019-01-01 18:31:00+01:00", + "2019-01-01 18:32:00+01:00", + "2019-01-01 18:33:00+01:00", + "2019-01-01 18:34:00+01:00", + "2019-01-01 18:35:00+01:00", + "2019-01-01 18:36:00+01:00", + "2019-01-01 18:37:00+01:00", + "2019-01-01 18:38:00+01:00", + "2019-01-01 18:39:00+01:00", + "2019-01-01 18:40:00+01:00", + "2019-01-01 18:41:00+01:00", + "2019-01-01 18:42:00+01:00", + "2019-01-01 18:43:00+01:00", + "2019-01-01 18:44:00+01:00", + "2019-01-01 18:45:00+01:00", + "2019-01-01 18:46:00+01:00", + "2019-01-01 18:47:00+01:00", + "2019-01-01 18:48:00+01:00", + "2019-01-01 18:49:00+01:00", + "2019-01-01 18:50:00+01:00", + "2019-01-01 18:51:00+01:00", + "2019-01-01 18:52:00+01:00", + "2019-01-01 18:53:00+01:00", + "2019-01-01 18:54:00+01:00", + "2019-01-01 18:55:00+01:00", + "2019-01-01 18:56:00+01:00", + "2019-01-01 18:57:00+01:00", + "2019-01-01 18:58:00+01:00", + "2019-01-01 18:59:00+01:00", + "2019-01-01 19:00:00+01:00", + "2019-01-01 19:01:00+01:00", + "2019-01-01 19:02:00+01:00", + "2019-01-01 19:03:00+01:00", + "2019-01-01 19:04:00+01:00", + "2019-01-01 19:05:00+01:00", + "2019-01-01 19:06:00+01:00", + "2019-01-01 19:07:00+01:00", + "2019-01-01 19:08:00+01:00", + "2019-01-01 19:09:00+01:00", + "2019-01-01 19:10:00+01:00", + "2019-01-01 19:11:00+01:00", + "2019-01-01 19:12:00+01:00", + "2019-01-01 19:13:00+01:00", + "2019-01-01 19:14:00+01:00", + "2019-01-01 19:15:00+01:00", + "2019-01-01 19:16:00+01:00", + "2019-01-01 19:17:00+01:00", + "2019-01-01 19:18:00+01:00", + "2019-01-01 19:19:00+01:00", + "2019-01-01 19:20:00+01:00", + "2019-01-01 19:21:00+01:00", + "2019-01-01 19:22:00+01:00", + "2019-01-01 19:23:00+01:00", + "2019-01-01 19:24:00+01:00", + "2019-01-01 19:25:00+01:00", + "2019-01-01 19:26:00+01:00", + "2019-01-01 19:27:00+01:00", + "2019-01-01 19:28:00+01:00", + "2019-01-01 19:29:00+01:00", + "2019-01-01 19:30:00+01:00", + "2019-01-01 19:31:00+01:00", + "2019-01-01 19:32:00+01:00", + "2019-01-01 19:33:00+01:00", + "2019-01-01 19:34:00+01:00", + "2019-01-01 19:35:00+01:00", + "2019-01-01 19:36:00+01:00", + "2019-01-01 19:37:00+01:00", + "2019-01-01 19:38:00+01:00", + "2019-01-01 19:39:00+01:00", + "2019-01-01 19:40:00+01:00", + "2019-01-01 19:41:00+01:00", + "2019-01-01 19:42:00+01:00", + "2019-01-01 19:43:00+01:00", + "2019-01-01 19:44:00+01:00", + "2019-01-01 19:45:00+01:00", + "2019-01-01 19:46:00+01:00", + "2019-01-01 19:47:00+01:00", + "2019-01-01 19:48:00+01:00", + "2019-01-01 19:49:00+01:00", + "2019-01-01 19:50:00+01:00", + "2019-01-01 19:51:00+01:00", + "2019-01-01 19:52:00+01:00", + "2019-01-01 19:53:00+01:00", + "2019-01-01 19:54:00+01:00", + "2019-01-01 19:55:00+01:00", + "2019-01-01 19:56:00+01:00", + "2019-01-01 19:57:00+01:00", + "2019-01-01 19:58:00+01:00", + "2019-01-01 19:59:00+01:00", + "2019-01-01 20:00:00+01:00", + "2019-01-01 20:01:00+01:00", + "2019-01-01 20:02:00+01:00", + "2019-01-01 20:03:00+01:00", + "2019-01-01 20:04:00+01:00", + "2019-01-01 20:05:00+01:00", + "2019-01-01 20:06:00+01:00", + "2019-01-01 20:07:00+01:00", + "2019-01-01 20:08:00+01:00", + "2019-01-01 20:09:00+01:00", + "2019-01-01 20:10:00+01:00", + "2019-01-01 20:11:00+01:00", + "2019-01-01 20:12:00+01:00", + "2019-01-01 20:13:00+01:00", + "2019-01-01 20:14:00+01:00", + "2019-01-01 20:15:00+01:00", + "2019-01-01 20:16:00+01:00", + "2019-01-01 20:17:00+01:00", + "2019-01-01 20:18:00+01:00", + "2019-01-01 20:19:00+01:00", + "2019-01-01 20:20:00+01:00", + "2019-01-01 20:21:00+01:00", + "2019-01-01 20:22:00+01:00", + "2019-01-01 20:23:00+01:00", + "2019-01-01 20:24:00+01:00", + "2019-01-01 20:25:00+01:00", + "2019-01-01 20:26:00+01:00", + "2019-01-01 20:27:00+01:00", + "2019-01-01 20:28:00+01:00", + "2019-01-01 20:29:00+01:00", + "2019-01-01 20:30:00+01:00", + "2019-01-01 20:31:00+01:00", + "2019-01-01 20:32:00+01:00", + "2019-01-01 20:33:00+01:00", + "2019-01-01 20:34:00+01:00", + "2019-01-01 20:35:00+01:00", + "2019-01-01 20:36:00+01:00", + "2019-01-01 20:37:00+01:00", + "2019-01-01 20:38:00+01:00", + "2019-01-01 20:39:00+01:00", + "2019-01-01 20:40:00+01:00", + "2019-01-01 20:41:00+01:00", + "2019-01-01 20:42:00+01:00", + "2019-01-01 20:43:00+01:00", + "2019-01-01 20:44:00+01:00", + "2019-01-01 20:45:00+01:00", + "2019-01-01 20:46:00+01:00", + "2019-01-01 20:47:00+01:00", + "2019-01-01 20:48:00+01:00", + "2019-01-01 20:49:00+01:00", + "2019-01-01 20:50:00+01:00", + "2019-01-01 20:51:00+01:00", + "2019-01-01 20:52:00+01:00", + "2019-01-01 20:53:00+01:00", + "2019-01-01 20:54:00+01:00", + "2019-01-01 20:55:00+01:00", + "2019-01-01 20:56:00+01:00", + "2019-01-01 20:57:00+01:00", + "2019-01-01 20:58:00+01:00", + "2019-01-01 20:59:00+01:00", + "2019-01-01 21:00:00+01:00", + "2019-01-01 21:01:00+01:00", + "2019-01-01 21:02:00+01:00", + "2019-01-01 21:03:00+01:00", + "2019-01-01 21:04:00+01:00", + "2019-01-01 21:05:00+01:00", + "2019-01-01 21:06:00+01:00", + "2019-01-01 21:07:00+01:00", + "2019-01-01 21:08:00+01:00", + "2019-01-01 21:09:00+01:00", + "2019-01-01 21:10:00+01:00", + "2019-01-01 21:11:00+01:00", + "2019-01-01 21:12:00+01:00", + "2019-01-01 21:13:00+01:00", + "2019-01-01 21:14:00+01:00", + "2019-01-01 21:15:00+01:00", + "2019-01-01 21:16:00+01:00", + "2019-01-01 21:17:00+01:00", + "2019-01-01 21:18:00+01:00", + "2019-01-01 21:19:00+01:00", + "2019-01-01 21:20:00+01:00", + "2019-01-01 21:21:00+01:00", + "2019-01-01 21:22:00+01:00", + "2019-01-01 21:23:00+01:00", + "2019-01-01 21:24:00+01:00", + "2019-01-01 21:25:00+01:00", + "2019-01-01 21:26:00+01:00", + "2019-01-01 21:27:00+01:00", + "2019-01-01 21:28:00+01:00", + "2019-01-01 21:29:00+01:00", + "2019-01-01 21:30:00+01:00", + "2019-01-01 21:31:00+01:00", + "2019-01-01 21:32:00+01:00", + "2019-01-01 21:33:00+01:00", + "2019-01-01 21:34:00+01:00", + "2019-01-01 21:35:00+01:00", + "2019-01-01 21:36:00+01:00", + "2019-01-01 21:37:00+01:00", + "2019-01-01 21:38:00+01:00", + "2019-01-01 21:39:00+01:00", + "2019-01-01 21:40:00+01:00", + "2019-01-01 21:41:00+01:00", + "2019-01-01 21:42:00+01:00", + "2019-01-01 21:43:00+01:00", + "2019-01-01 21:44:00+01:00", + "2019-01-01 21:45:00+01:00", + "2019-01-01 21:46:00+01:00", + "2019-01-01 21:47:00+01:00", + "2019-01-01 21:48:00+01:00", + "2019-01-01 21:49:00+01:00", + "2019-01-01 21:50:00+01:00", + "2019-01-01 21:51:00+01:00", + "2019-01-01 21:52:00+01:00", + "2019-01-01 21:53:00+01:00", + "2019-01-01 21:54:00+01:00", + "2019-01-01 21:55:00+01:00", + "2019-01-01 21:56:00+01:00", + "2019-01-01 21:57:00+01:00", + "2019-01-01 21:58:00+01:00", + "2019-01-01 21:59:00+01:00", + "2019-01-01 22:00:00+01:00", + "2019-01-01 22:01:00+01:00", + "2019-01-01 22:02:00+01:00", + "2019-01-01 22:03:00+01:00", + "2019-01-01 22:04:00+01:00", + "2019-01-01 22:05:00+01:00", + "2019-01-01 22:06:00+01:00", + "2019-01-01 22:07:00+01:00", + "2019-01-01 22:08:00+01:00", + "2019-01-01 22:09:00+01:00", + "2019-01-01 22:10:00+01:00", + "2019-01-01 22:11:00+01:00", + "2019-01-01 22:12:00+01:00", + "2019-01-01 22:13:00+01:00", + "2019-01-01 22:14:00+01:00", + "2019-01-01 22:15:00+01:00", + "2019-01-01 22:16:00+01:00", + "2019-01-01 22:17:00+01:00", + "2019-01-01 22:18:00+01:00", + "2019-01-01 22:19:00+01:00", + "2019-01-01 22:20:00+01:00", + "2019-01-01 22:21:00+01:00", + "2019-01-01 22:22:00+01:00", + "2019-01-01 22:23:00+01:00", + "2019-01-01 22:24:00+01:00", + "2019-01-01 22:25:00+01:00", + "2019-01-01 22:26:00+01:00", + "2019-01-01 22:27:00+01:00", + "2019-01-01 22:28:00+01:00", + "2019-01-01 22:29:00+01:00", + "2019-01-01 22:30:00+01:00", + "2019-01-01 22:31:00+01:00", + "2019-01-01 22:32:00+01:00", + "2019-01-01 22:33:00+01:00", + "2019-01-01 22:34:00+01:00", + "2019-01-01 22:35:00+01:00", + "2019-01-01 22:36:00+01:00", + "2019-01-01 22:37:00+01:00", + "2019-01-01 22:38:00+01:00", + "2019-01-01 22:39:00+01:00", + "2019-01-01 22:40:00+01:00", + "2019-01-01 22:41:00+01:00", + "2019-01-01 22:42:00+01:00", + "2019-01-01 22:43:00+01:00", + "2019-01-01 22:44:00+01:00", + "2019-01-01 22:45:00+01:00", + "2019-01-01 22:46:00+01:00", + "2019-01-01 22:47:00+01:00", + "2019-01-01 22:48:00+01:00", + "2019-01-01 22:49:00+01:00", + "2019-01-01 22:50:00+01:00", + "2019-01-01 22:51:00+01:00", + "2019-01-01 22:52:00+01:00", + "2019-01-01 22:53:00+01:00", + "2019-01-01 22:54:00+01:00", + "2019-01-01 22:55:00+01:00", + "2019-01-01 22:56:00+01:00", + "2019-01-01 22:57:00+01:00", + "2019-01-01 22:58:00+01:00", + "2019-01-01 22:59:00+01:00", + "2019-01-01 23:00:00+01:00", + "2019-01-01 23:01:00+01:00", + "2019-01-01 23:02:00+01:00", + "2019-01-01 23:03:00+01:00", + "2019-01-01 23:04:00+01:00", + "2019-01-01 23:05:00+01:00", + "2019-01-01 23:06:00+01:00", + "2019-01-01 23:07:00+01:00", + "2019-01-01 23:08:00+01:00", + "2019-01-01 23:09:00+01:00", + "2019-01-01 23:10:00+01:00", + "2019-01-01 23:11:00+01:00", + "2019-01-01 23:12:00+01:00", + "2019-01-01 23:13:00+01:00", + "2019-01-01 23:14:00+01:00", + "2019-01-01 23:15:00+01:00", + "2019-01-01 23:16:00+01:00", + "2019-01-01 23:17:00+01:00", + "2019-01-01 23:18:00+01:00", + "2019-01-01 23:19:00+01:00", + "2019-01-01 23:20:00+01:00", + "2019-01-01 23:21:00+01:00", + "2019-01-01 23:22:00+01:00", + "2019-01-01 23:23:00+01:00", + "2019-01-01 23:24:00+01:00", + "2019-01-01 23:25:00+01:00", + "2019-01-01 23:26:00+01:00", + "2019-01-01 23:27:00+01:00", + "2019-01-01 23:28:00+01:00", + "2019-01-01 23:29:00+01:00", + "2019-01-01 23:30:00+01:00", + "2019-01-01 23:31:00+01:00", + "2019-01-01 23:32:00+01:00", + "2019-01-01 23:33:00+01:00", + "2019-01-01 23:34:00+01:00", + "2019-01-01 23:35:00+01:00", + "2019-01-01 23:36:00+01:00", + "2019-01-01 23:37:00+01:00", + "2019-01-01 23:38:00+01:00", + "2019-01-01 23:39:00+01:00", + "2019-01-01 23:40:00+01:00", + "2019-01-01 23:41:00+01:00", + "2019-01-01 23:42:00+01:00", + "2019-01-01 23:43:00+01:00", + "2019-01-01 23:44:00+01:00", + "2019-01-01 23:45:00+01:00", + "2019-01-01 23:46:00+01:00", + "2019-01-01 23:47:00+01:00", + "2019-01-01 23:48:00+01:00", + "2019-01-01 23:49:00+01:00", + "2019-01-01 23:50:00+01:00", + "2019-01-01 23:51:00+01:00", + "2019-01-01 23:52:00+01:00", + "2019-01-01 23:53:00+01:00", + "2019-01-01 23:54:00+01:00", + "2019-01-01 23:55:00+01:00", + "2019-01-01 23:56:00+01:00", + "2019-01-01 23:57:00+01:00", + "2019-01-01 23:58:00+01:00", + "2019-01-01 23:59:00+01:00" + ], + "xaxis": "x2", + "y": [ + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5 + ], + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": { + "size": 16 + }, + "showarrow": false, + "text": "Input (MW)", + "x": 0.225, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": { + "size": 16 + }, + "showarrow": false, + "text": "Output (MW)", + "x": 0.775, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + } + ], + "autosize": true, + "legend": { + "bgcolor": "#F5F6F9", + "font": { + "color": "#4D5663" + } + }, + "paper_bgcolor": "#F5F6F9", + "plot_bgcolor": "#F5F6F9", + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "font": { + "color": "#4D5663" + }, + "text": "Heatpump" + }, + "xaxis": { + "anchor": "y", + "autorange": true, + "domain": [ + 0, + 0.45 + ], + "gridcolor": "#E1E5ED", + "range": [ + "2019-01-01", + "2019-01-01 23:59" + ], + "showgrid": true, + "tickfont": { + "color": "#4D5663" + }, + "title": { + "font": { + "color": "#4D5663" + }, + "text": "" + }, + "type": "date", + "zerolinecolor": "#E1E5ED" + }, + "xaxis2": { + "anchor": "y2", + "autorange": true, + "domain": [ + 0.55, + 1 + ], + "gridcolor": "#E1E5ED", + "range": [ + "2019-01-01", + "2019-01-01 23:59" + ], + "showgrid": true, + "tickfont": { + "color": "#4D5663" + }, + "title": { + "font": { + "color": "#4D5663" + }, + "text": "" + }, + "type": "date", + "zerolinecolor": "#E1E5ED" + }, + "yaxis": { + "anchor": "x", + "autorange": true, + "domain": [ + 0, + 1 + ], + "gridcolor": "#E1E5ED", + "range": [ + -2.428571428571429, + -0.4285714285714286 + ], + "showgrid": true, + "tickfont": { + "color": "#4D5663" + }, + "title": { + "font": { + "color": "#4D5663" + }, + "text": "" + }, + "type": "linear", + "zerolinecolor": "#E1E5ED" + }, + "yaxis2": { + "anchor": "x2", + "autorange": true, + "domain": [ + 0, + 1 + ], + "gridcolor": "#E1E5ED", + "range": [ + 4, + 6 + ], + "showgrid": true, + "tickfont": { + "color": "#4D5663" + }, + "title": { + "font": { + "color": "#4D5663" + }, + "text": "" + }, + "type": "linear", + "zerolinecolor": "#E1E5ED" + } + } + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAABBgAAAHCCAYAAABFfHqHAAAgAElEQVR4Xu3debyUdd3/8Y8gHJDFJZPFhVwqNyS31AgVDUJRCgVZFRAiC0WK+7YwS1HvKMtEklsjSCgE3MJdAhOTTPu53binLS4EaKVwQHbO+T2+l13TdebMnDPznWve17nmvM79x50y3+sz8/yOzDmvc801u3y4aWut8YUAAggggAACCCCAAAIIIIAAAgiUILALgaEEPZYigAACCCCAAAIIIIAAAggggEAgQGDgiYAAAggggAACCCCAAAIIIIAAAiULEBhKJuQACCCAAAIIIIAAAggggAACCCBAYOA5gAACCCCAAAIIIIAAAggggAACJQsQGEom5AAIIIAAAggggAACCCCAAAIIIEBg4DmAAAIIIIAAAggggAACCCCAAAIlCxAYSibkAAgggAACCCCAAAIIIIAAAgggQGDgOYAAAggggAACCCCAAAIIIIAAAiULEBhKJuQACCCAAAIIIIAAAggggAACCCBAYOA5gAACCCCAAAIIIIAAAggggAACJQsQGEom5AAIIIAAAggggAACCCCAAAIIIEBg4DmAAAIIIIAAAggggAACCCCAAAIlCxAYSibkAAgggAACCCCAAAIIIIAAAgggQGDgOYAAAggggAACCCCAAAIIIIAAAiULEBhKJuQACCCAAAIIIIAAAggggAACCCBAYOA5gAACCCCAAAIIIIAAAggggAACJQsQGEom5AAIIIAAAggggAACCCCAAAIIIEBg4DmAAAIIIIAAAggggAACCCCAAAIlCxAYSibkAAgggAACCCCAAAIIIIAAAgggQGDgOYAAAggggAACCCCAAAIIIIAAAiULEBhKJuQACCCAAAIIIIAAAggggAACCCBAYOA5gAACCCCAAAIIIIAAAggggAACJQsQGEom5AAIIIAAAggggAACCCCAAAIIIEBg4DmAAAIIIIAAAggggAACCCCAAAIlCxAYSibkAAgggAACCCCAAAIIIIAAAgggQGDgOYAAAggggAACCCCAAAIIIIAAAiULEBhKJuQACCCAAAIIIIAAAggggAACCCBAYOA5gAACCCCAAAIIIIAAAggggAACJQsQGEom5AAIIIAAAggggAACCCCAAAIIIEBg4DmAAAIIIIAAAggggAACCCCAAAIlCxAYSibkAAgggAAC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c10G92dz599ur73+l+DijUce/mkbcu4A+9XCu8xdDDLOMxi+1L9vcE2Jxx7/g23fscMO+sQBdsHwQfapQw4q6cnFYgQQQAABBBBAAAEEEEAAgeYjUJGBoalunwsMuS7ymNT9DS8umesij0ndJ+YigAACCCCAAAIIIIAAAgikU4DAINw3AoMQm1EIIIAAAggggAACCCCAAAJSAQKDkJvAIMRmFAIIIIAAAggggAACCCCAgFSAwCDkJjAIsRmFAAIIIIAAAggggAACCCAgFSAwSLkZhgACCCCAAAIIIIAAAggggEBlChAYKnNfeVQIIIAAAggggAACCCCAAAIISAUIDFJuhiGAAAIIIIAAAggggAACCCBQmQIEhsrcVx4VAggggAACCCCAAAIIIIAAAlIBAoOUm2EIIIAAAggggAACCCCAAAIIVKYAgaEy95VHhQACCCCAAAIIIIAAAggggIBUgMAg5WYYAggggAACCCCAAAIIIIAAApUpQGCozH3lUSGAAAIIIIAAAggggAACCCAgFSAwSLkZhgACCCCAAAIIIIAAAggggEBlChAYKnNfeVQIIIAAAggggAACCCCAAAIISAUIDFJuhiGAAAIIIIAAAggggAACCCBQmQIEhsrcVx4VAggggAACCCCAAAIIIIAAAlIBAoOUm2EIIIAAAggggAACCCCAAAIIVKYAgaEy95VHhQACCCCAAAIIIIAAAggggIBUgMAg5WYYAggggAACCCCAAAIIIIAAApUpQGCozH3lUSGAAAIIIIAAAggggAACCCAgFSAwSLkZhgACCCCAAAIIIIAAAggggEBlChAYKnNfeVQIIIAAAggggAACCCCAAAIISAUIDFJuhiGAAAIIIIAAAggggAACCCBQmQIEhsrcVx4VAggggAACCCCAAAIIIIAAAlIBAoOUm2EIIIAAAggggAACCCCAAAIIVKYAgaEy95VHhQACCCCAAAIIIIAAAggggIBUgMAg5WYYAggggAACCCCAAAIIIIAAApUpQGCozH3lUSGAAAIIIIAAAggggAACCCAgFSAwSLkZhgACCCCAAAIIIIAAAggggEBlChAYKnNfeVQIIIAAAggggAACCCCAAAIISAUIDFJuhiGAAAIIIIAAAggggAACCCBQmQIEhsrcVx4VAggggAACCCCAAAIIIIAAAlIBAoOUm2EI5Ba4b+kT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NpZbmOMjgAACCCDQ9AVSHxiiF3pq6OMm49wK3usZpybHQgABBBCIWyD8DX/0TIG4Z2Qfj9fGcgtzfAQQQAABBJq+QOoDQ9Mn5h4igAACCCCAAAIIIIAAAgggUPkCBIbK32MeIQIIIIAAAggggAACCCCAAAJlFyAwlJ2YAQgggAACCCCAAAIIIIAAAghUvgCBofL3mEeIAAIIIIAAAggggAACCCCAQNkFCAxlJ2YAAggggAACCCCAAAIIIIAAApUvQGCo/D3mESKAAAIIIIAAAggggAACCCBQdgECQ9mJGYAAAggggAACCCCAAAIIIIBA5QsQGCp/j3mECCCAAAIIIIAAAggggAACCJRdgMBQdmIGIIAAAggggAACCCCAAAIIIFD5AgSGyt9jHiECCCCAAAIIIIAAAggggAACZRcgMJSdmAEIIIAAAggggAACCCCAAAIIVL4AgaHy95hHiAACCCCAAAIIIIAAAggggEDZBQgMZSdmAAIIIIAAAggggAACCCCAAAKVL0BgqPw95hEigAACCCCAAAIIIIAAAgggUHYBAkPZiRmAAAIIIIAAAggggAACCCCAQOULEBgqf495hAgggAACCCCAAAIIIIAAAgiUXYDAUHZiBiCAAAIIIIAAAggggAACCCBQ+QIEhsrfYx4hAggggAACCCCAAAIIIIAAAmUXIDCUnZgBCCCAAAIIIIAAAggggAACCFS+AIGh8veYR4gAAggggAACCCCAAAIIIIBA2QUIDGUnZgACCCCAAAIIIIAAAggggAAClS9AYKj8PeYRIoAAAggggAACCCCAAAIIIFB2AQJD2YkZgAACCCCAAAIIIIAAAggggEDlCxAYKn+PeYQIIIAAAggggAACCCCAAAIIlF2AwFB2YgYggAACCCCAAAIIIIAAAgggUPkCBIbK32MeIQIIIIAAAggggAACCCCAAAJlFyAwlJ2YAQgggAACCCCAAAIIIIAAAghUvgCBofL3mEeIAAIIIIAAAggggAACCCCAQNkFCAxlJ2YAAggggAACCCCAAAIIIIAAApUvQGCo/D3mESKAAAIIIIAAAggggAACCCBQdgECQ9mJGYAAAggggAACCCCAAAIIIIBA5QsQGCp/j3mECCCAAAIIIIAAAggggAACCJRdgMBQdmIGIIAAAggggAACCCCAAAIIIFD5AgSGyt9jHiECCCCAAAIIIIAAAggggAACZRcgMJSdmAEIIIAAAggggAACCCCAAAIIVL4AgaHy95hHiAACCCCAAAIIIIAAAggggEDZBQgMZSdmAAIIIIAAAggggAACCCCAAAKVL0BgqPw95hEigAACCCCAAAIIIIAAAgggUHYBAkPZiRmAAAIIIIAAAggggAACCCCAQOULEBgqf495hAgggAACCCCAAAIIIIAAAgiUXYDAUHZiBiCAAAIIIIAAAggggAACCCBQ+QIEhsrfYx4hAggggAACCCCAAAIIIIAAAmUXIDCUnZgBCCCAAAIIIIAAAggggAACCFS+AIGh8veYR4gAAggggAACCCCAAAIIIIBA2QUIDGUnZgACCCCAAAIIIIAAAggggAAClS9AYKj8PeYRIoAAAggggAACCCCAAAIIIFB2AQJD2YkZgAACCCCAAAIIIIAAAggggEDlCxAYKn+PeYQIIIAAAggggAACCCCAAAIIlF2AwFB2YgYggAACCCCAAAIIIIAAAgggUPkC/x8MWqM98ApywQAAAABJRU5ErkJggg==", + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "hpcase.data.loc['2019-01-01', ['input_MW', 'output_MW']].iplot(subplots=True, title='Heatpump', subplot_titles=['Input (MW)', 'Output (MW)'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Financials" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Collect cashflows" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Electricity market results*" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [], + "source": [ + "hpcase.generate_electr_market_results(nom_col=None, real_col='input_MWh')" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'CaseReport' object has no attribute 'formatting'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mmarketreport\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mCaseReport\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcase\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mhpcase\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkind\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'electr_market_results'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mmarketreport\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshow\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;32mc:\\users\\mekre\\onedrive - recoy\\work\\code\\python\\_packages\\pyrecoy\\pyrecoy\\reports.py\u001b[0m in \u001b[0;36mshow\u001b[1;34m(self, presentation_format)\u001b[0m\n\u001b[0;32m 40\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mreport\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 41\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 42\u001b[1;33m \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mformatting\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m\"percentage\"\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 43\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mreport\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mapplymap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mperc_formatting\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 44\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mAttributeError\u001b[0m: 'CaseReport' object has no attribute 'formatting'" + ] + } + ], + "source": [ + "marketreport = CaseReport(case=hpcase, kind='electr_market_results')\n", + "marketreport.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DAMPOSNEGRSForePosForeNegHeat demandoutput_MWinput_MWoutput_MWhinput_MWhNom. vol.Prod. vol.Cons. vol.Imb. vol.Day-Ahead ResultPOS ResultNEG ResultImbalance ResultCombined Result
datetime
2019-01-01 00:00:00+01:0068.9234.8558.012.046.8352.7055-1.4285710.083333-0.0238100.0-0.02381-0.023810.00.0-1.38119-1.38119-1.38119
2019-01-01 00:01:00+01:0068.9234.8558.012.032.1254.4555-1.4285710.083333-0.0238100.0-0.02381-0.023810.00.0-1.38119-1.38119-1.38119
2019-01-01 00:02:00+01:0068.9234.8558.012.030.9748.6455-1.4285710.083333-0.0238100.0-0.02381-0.023810.00.0-1.38119-1.38119-1.38119
2019-01-01 00:03:00+01:0068.9234.8558.012.051.1348.3555-1.4285710.083333-0.0238100.0-0.02381-0.023810.00.0-1.38119-1.38119-1.38119
2019-01-01 00:04:00+01:0068.9234.8558.012.048.0452.0155-1.4285710.083333-0.0238100.0-0.02381-0.023810.00.0-1.38119-1.38119-1.38119
\n", + "
" + ], + "text/plain": [ + " DAM POS NEG RS ForePos ForeNeg \\\n", + "datetime \n", + "2019-01-01 00:00:00+01:00 68.92 34.85 58.01 2.0 46.83 52.70 \n", + "2019-01-01 00:01:00+01:00 68.92 34.85 58.01 2.0 32.12 54.45 \n", + "2019-01-01 00:02:00+01:00 68.92 34.85 58.01 2.0 30.97 48.64 \n", + "2019-01-01 00:03:00+01:00 68.92 34.85 58.01 2.0 51.13 48.35 \n", + "2019-01-01 00:04:00+01:00 68.92 34.85 58.01 2.0 48.04 52.01 \n", + "\n", + " Heat demand output_MW input_MW output_MWh \\\n", + "datetime \n", + "2019-01-01 00:00:00+01:00 5 5 -1.428571 0.083333 \n", + "2019-01-01 00:01:00+01:00 5 5 -1.428571 0.083333 \n", + "2019-01-01 00:02:00+01:00 5 5 -1.428571 0.083333 \n", + "2019-01-01 00:03:00+01:00 5 5 -1.428571 0.083333 \n", + "2019-01-01 00:04:00+01:00 5 5 -1.428571 0.083333 \n", + "\n", + " input_MWh Nom. vol. Prod. vol. Cons. vol. \\\n", + "datetime \n", + "2019-01-01 00:00:00+01:00 -0.02381 0 0.0 -0.02381 \n", + "2019-01-01 00:01:00+01:00 -0.02381 0 0.0 -0.02381 \n", + "2019-01-01 00:02:00+01:00 -0.02381 0 0.0 -0.02381 \n", + "2019-01-01 00:03:00+01:00 -0.02381 0 0.0 -0.02381 \n", + "2019-01-01 00:04:00+01:00 -0.02381 0 0.0 -0.02381 \n", + "\n", + " Imb. vol. Day-Ahead Result POS Result \\\n", + "datetime \n", + "2019-01-01 00:00:00+01:00 -0.02381 0.0 0.0 \n", + "2019-01-01 00:01:00+01:00 -0.02381 0.0 0.0 \n", + "2019-01-01 00:02:00+01:00 -0.02381 0.0 0.0 \n", + "2019-01-01 00:03:00+01:00 -0.02381 0.0 0.0 \n", + "2019-01-01 00:04:00+01:00 -0.02381 0.0 0.0 \n", + "\n", + " NEG Result Imbalance Result Combined Result \n", + "datetime \n", + "2019-01-01 00:00:00+01:00 -1.38119 -1.38119 -1.38119 \n", + "2019-01-01 00:01:00+01:00 -1.38119 -1.38119 -1.38119 \n", + "2019-01-01 00:02:00+01:00 -1.38119 -1.38119 -1.38119 \n", + "2019-01-01 00:03:00+01:00 -1.38119 -1.38119 -1.38119 \n", + "2019-01-01 00:04:00+01:00 -1.38119 -1.38119 -1.38119 " + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hpcase.data.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Gas costs* " + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [], + "source": [ + "baseline.add_gas_costs(gasvolumes_cols=['input_MWh'])\n", + "baseline.add_co2_costs(volume_cols=['input_MWh'], fuel='gas')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Grid costs and EB & ODE*" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "CaseStudy 'Optimisation' does not have attribute 'total_electricity_cons', so EB & ODE for electricity could not be calculated. Use 'calculate_eb_ode' function from pyrecoy.financial if you want to do the calculation manually.", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mbaseline\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0madd_eb_ode\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcommodity\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'gas'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtax_bracket\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mhpcase\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0madd_eb_ode\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcommodity\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'electricity'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtax_bracket\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m hpcase.add_grid_costs(\n\u001b[0;32m 5\u001b[0m \u001b[0mpower_MW_col\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'input_MW'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mc:\\users\\mekre\\onedrive - recoy\\work\\code\\python\\_packages\\pyrecoy\\pyrecoy\\framework.py\u001b[0m in \u001b[0;36madd_eb_ode\u001b[1;34m(self, commodity, tax_bracket, base_cons, horti, m3)\u001b[0m\n\u001b[0;32m 281\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34mf\"total_{commodity}_cons\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 282\u001b[0m raise AttributeError(\n\u001b[1;32m--> 283\u001b[1;33m \u001b[1;34mf\"CaseStudy '{self.name}' does not have attribute 'total_{commodity}_cons', \"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 284\u001b[0m \u001b[1;34mf\"so EB & ODE for {commodity} could not be calculated. Use 'calculate_eb_ode' function \"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 285\u001b[0m \u001b[1;34m\"from pyrecoy.financial if you want to do the calculation manually.\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mAttributeError\u001b[0m: CaseStudy 'Optimisation' does not have attribute 'total_electricity_cons', so EB & ODE for electricity could not be calculated. Use 'calculate_eb_ode' function from pyrecoy.financial if you want to do the calculation manually." + ] + } + ], + "source": [ + "baseline.add_eb_ode(commodity='gas', tax_bracket=4)\n", + "\n", + "hpcase.add_eb_ode(commodity='electricity', tax_bracket=4)\n", + "hpcase.add_grid_costs(\n", + " power_MW_col='input_MW',\n", + " grid_operator='tennet',\n", + " year=2020, \n", + " connection_type='HS'\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Other cashflows*" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [], + "source": [ + "hpcase.add_cashflow('SDE++ subsidy', 20_000)" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Heatpump OPEX (€)': -10000,\n", + " 'Result on electricity market (€)': -532533.94,\n", + " 'SDE++ subsidy': 20000}" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hpcase.cashflows" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### EBITDA" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [], + "source": [ + "baseline.calculate_ebitda()\n", + "hpcase.calculate_ebitda()" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "cliponaxis": false, + "marker": { + "color": "#0e293b" + }, + "text": [ + -1080682.3, + -522533.93999999994 + ], + "textposition": "outside", + "texttemplate": "%{text:.3s}€", + "type": "bar", + "x": [ + "Baseline", + "Optimisation" + ], + "y": [ + -1080682.3, + -522533.93999999994 + ] + } + ], + "layout": { + "height": 400, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "EBITDA comparison in k€" + }, + "width": 800, + "xaxis": { + "autorange": true, + "range": [ + -0.5, + 1.5 + ], + "type": "category" + }, + "yaxis": { + "range": [ + -1188750.5300000003, + 0 + ], + "type": "linear" + } + } + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAABBgAAAGQCAYAAAAEOtN7AAAgAElEQVR4Xu3dC7zmU70/8EUug4acjnJcMomQXHMrZ8otRBLOUEbkzjCHRpwxJ06HzoxcJpKZEFFIzXEpETUkk864DqZOoyTCHELuY6jM/7V+/X9Pz96z98zevmbs9fzez+vVq5n9POv3rPX+LvP7PZ+9futZZM6cOXOSBwECBAgQIECAAAECBAgQIEAgILCIgCGgpykBAgQIECBAgAABAgQIECBQCQgYTAQCBAgQIECAAAECBAgQIEAgLCBgCBM6AAECBAgQIECAAAECBAgQICBgMAcIECBAgAABAgQIECBAgACBsICAIUzoAAQIECBAgAABAgQIECBAgICAwRwgQIAAAQIECBAgQIAAAQIEwgIChjChAxAgQIAAAQIECBAgQIAAAQICBnOAAAECBAgQIECAAAECBAgQCAsIGMKEDkCAAAECBAgQIECAAAECBAgIGMwBAgQIECBAgAABAgQIECBAICwgYAgTOgABAgQIECBAgAABAgQIECAgYDAHCBAgQIAAAQIECBAgQIAAgbCAgCFM6AAECBAgQIAAAQIECBAgQICAgMEcIECAAAECBAgQIECAAAECBMICAoYwoQMQIECAAAECBAgQIECAAAECAgZzgAABAgQIECBAgAABAgQIEAgLCBjChA5AgAABAgQIECBAgAABAgQICBjMAQIECBAgQIAAAQIECBAgQCAsIGAIEzoAAQIECBAgQIAAAQIECBAgIGAwBwgQIECAAAECBAgQIECAAIGwgIAhTOgABAgQIECAAAECBAgQIECAgIDBHCBAgAABAgQIECBAgAABAgTCAgKGMKEDECBAgAABAgQIECBAgAABAgIGc4AAAQIECBAgQIAAAQIECBAICwgYwoQOQIAAAQIECBAgQIAAAQIECAgYzAECBAgQIECAAAECBAgQIEAgLCBgCBM6AAECBAgQIECAAAECBAgQICBgMAcIECBAgAABAgQIECBAgACBsICAIUzoAAQIECBAgAABAgQIECBAgICAwRwgQIAAAQIECBAgQIAAAQIEwgIChjChAxAgQIAAAQIECBAgQIAAAQICBnOAAAECBAgQIECAAAECBAgQCAsIGMKEDkCAAAECBAgQIECAAAECBAgIGMwBAgQIECBAgAABAgQIECBAICwgYAgTOgABAgQIECBAgAABAgQIECAgYDAHCBAgQIAAAQIECBAgQIAAgbCAgCFM6ABvpsCfnnk+nTrh8rTPHh9N71/73W9mV7q893U3Tk2//u3DaeSBe6QlFl8s1K8HH56ZxpzyjTR29EFp9dVWCh1LYwIECBAgQIAAAQIECCwogY4MGGbPfjWdePqF6drJU+dyW3+d96QJpxydll9ucLryuinphFMv6PKaVf5phfTBTdZNn9lj+/SeIX//MJdfO/XuX6WTPn9Amn7/g+mzR50yz5rsvN0Wvb72H/9hubTphmunT39y27TR+9dMiy66SI/HmvXy7DRm3PlppRVXSMccOiy95S1vWVDzoNjjPvb4U+lzJ34tHX3wv6QPbfr+ATOOCy//Ufr1bx5K/3ns/mnppQaF+tWfgOG11+akW++Ynr7+rR+kX97/++p9N17vvemze+6Q/nmz9cyhUCU0JkCAAAECBAgQIEBgXgIdHTBs8L410k7bbt5l/Isusmga/Nalqw/1OTS4Zeq9afSRe6cll1w8zXltTvrdH2amb0/6cfrdwzPT1/7rqPTud/1T1b49YHjLWxZNL856uXXc6268Ld1xz4zWcfITi73lLemtyyyV7rzv/nTaOZenU084LC237DJVm0dm/jFNvuWudMkVP0nDd98uHbH/bmnQkkvMVad7fvlAGnnCV9M7/3H5dM64o6v/92ieQF8Dhr/+9a9p4rd+kCZdc3M6aO+d01Yf2jC98uqf082/uCflCOuze+0oYGje9DFiAgQIECBAgAABAgtNoKMDhi02XjftvtPQXjHbQ4NBg/7+Af+Jp55JI0Z/Je23547pE9t/aK6Aof213cOH7s/dce+MNP7rk1qrJto7c+e996djT56YRh6wx1z9zB8Wzzh3Ulp8sbek//vj02mrD22Udtqma1iy0GaJN3pTBfoaMORAatQXz0ljxxycttj4fW9qn705AQIECBAgQIAAAQLNExAw/P/bHtqDgXxf/2Gjv5IO2nuntP1HNl1gAcOcOXPSeZf8MN027X/TV754ZGuFQ37DvMrhmP+cmP7z859Nv3/k8fTjm29PY48/eL7L7V/9819Svv//4kk3pN/87pG07OBl0se23iwdO+JTaalBS6b8nr+6/6F01gVXpNun/Tq9ZdFF04e32CAdtu8n0tprvKv1X0AOX2Y88HB633uH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AAECBAgQaJaAgKFZ9TZaAgT6JyBg6J+XVxMgQIAAAQIECBAgQIAAAQI9CAgYTAsCBAgQIECAAAECBAgQIEAgLCBgCBM6AAECBAgQIECAAAECBAgQICBgMAcIECBAgAABAgQIECBAgACBsICAIUzoAAQIECBAgAABAgQIECBAgICAwRwgQIAAAQIECBAgQIAAAQIEwgIChjChAxAgQIAAAQIECBAgQIAAAQICBnOAAAECBAgQIECAAAECBAgQCAsIGMKEDkCAAAECBAgQIECAAAECBAgIGMwBAgQIECBAgAABAgQIECBAICwgYAgTOgABAgQIECBAgAABAgQIECAgYDAHCBAgQIAAAQIECBAgQIAAgbCAgCFM6AAECBAgQIAAAQIECBAgQICAgMEcIECAAAECBAgQIECAAAECBMICAoYwoQMQIECAAAECBAgQIECAAAECAgZzgAABAgQIECBAgAABAgQIEAgLCBjChA5AgAABAgQIECBAgAABAgQICBjMAQIECBAgQIAAAQIECBAgQCAsIGAIEzoAAQIECBAgQIAAAQIECBAgIGAwBwgQIECAAAECBAgQIECAAIGwgIAhTOgABAgQIECAAAECBAgQIECAgIDBHCBAgAABAgQIECBAgAABAgTCAgKGMKEDECBAgAABAgQIECBAgAABAgIGc4AAAQIECBAgQIAAAQIECBAICwgYwoQOQIAAAQIECBAgQIAAAQIECAgYzAECBAgQIECAAAECBAgQIEAgLCBgCBM6AAECBAgQIECAAAECBAgQICBgMAcIECBAgAABAgQIECBAgACBsICAIUzoAAQIECBAgAABAgQIECBAgICAwRwgQIAAAQIECBAgQIAAAQIEwgIChjChAxAgQIAAAQIECBAgQIAAAQICBnOAAAECBAgQIECAAAECBAgQCAsIGMKEDkCAAAECBAgQIECAAAECBAgIGMwBAgQIECBAgAABAgQIECBAICwgYAgTOgABAgQIECBAgAABAgQIECAgYDAHCBAgQIAAAQIECBAgQIAAgbCAgCFM6AAECBAgQIAAAQIECBAgQICAgMEcIECAAAECBAgQIECAAAECBMICAoYwoQMQIECAAAECBAgQIECAAAECAgZzgAABAgQIECBAgAABAgQIEAgLCBjChA5AgAABAgQIECBAgAABAgQICBjMAQIECBAgQIAAAQIECBAgQCAsIGAIEzoAAQIECBAgQIAAAQIECBAgIGAwBwgQIECAAAECBAgQIECAAIGwgIAhTOgABAgQIECAAAECBAgQIECAgIDBHCBAgAABAgQIECBAgAABAgTCAgKGMKEDECBAgAABAgQIECBAgAABAgIGc4AAAQIECBAgQIAAAQIECBAICwgYwoQOQIAAAQIECBAgQIAAAQIECAgYzAECBAgQIECAAAECBAgQIEAgLCBgCBM6AAECBAgQIECAAAECBAgQICBgMAcIECBAgAABAgQIECBAgACBsICAIUzoAAQIECBAgAABAgQIECBAgICAwRwgQIAAAQIECBAgQIAAAQIEwgIChjChAxAgQIAAAQIECBAgQIAAAQICBnOAAAECBAgQIECAAAECBAgQCAsIGMKEDkCAAAECBAgQIECAAAECBAgIGMwBAgQIECBAgAABAgQIECBAICwgYAgTOgABAgQIECBAgAABAgQIECAgYDAHCBAgQIAAAQIECBAgQIAAgbCAgCFM6AAECBAgQIAAAQIECBAgQICAgMEcIECAAAECBAgQIECAAAECBMICAoYwoQMQIECAAAECBAgQIECAAAECAgZzgAABAgQIECBAgAABAgQIEAgL/D8W51VtvGBxRgAAAABJRU5ErkJggg==", + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ebitda_bar_chart(cases, color=recoydarkblue).update_layout(width=800, height=400)" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BaselineOptimisation
Gasboiler OPEX (€)-20,000-
Gas consumption costs (€)-658,886-
CO2 emission costs (€)-233,364-
Gas taxes (€)-168,433-
Heatpump OPEX (€)--10,000
Result on electricity market (€)--532,534
SDE++ subsidy-20,000
EBITDA (€)-1,080,682-522,534
\n", + "
" + ], + "text/plain": [ + " Baseline Optimisation\n", + "Gasboiler OPEX (€) -20,000 -\n", + "Gas consumption costs (€) -658,886 -\n", + "CO2 emission costs (€) -233,364 -\n", + "Gas taxes (€) -168,433 -\n", + "Heatpump OPEX (€) - -10,000\n", + "Result on electricity market (€) - -532,534\n", + "SDE++ subsidy - 20,000\n", + "EBITDA (€) -1,080,682 -522,534" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "casereport = ComparisonReport(cases=cases, kind='ebitda_calc')\n", + "casereport.show(presentation_format=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Business case" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [], + "source": [ + "hpcase.calculate_business_case(project_duration=15, discount_rate=0.1, baseline=baseline)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Year 0Year 1Year 2Year 3Year 4Year 5Year 6Year 7Year 8Year 9Year 10Year 11Year 12Year 13Year 14Year 15
CAPEX (€)-1,020,000
Regular Earnings (€)558,148558,148558,148558,148558,148558,148558,148558,148558,148558,148558,148558,148558,148558,148558,148
Irregular Earnings (€)---------------
EBITDA (€)558,148558,148558,148558,148558,148558,148558,148558,148558,148558,148558,148558,148558,148558,148558,148
Depreciations (€) -/--40,000-40,000-40,000-40,000-40,000-40,000-40,000-40,000-40,000-40,000-40,000-40,000-40,000-40,000-40,000
EBIT (€)518,148518,148518,148518,148518,148518,148518,148518,148518,148518,148518,148518,148518,148518,148518,148
Income tax (Vpb.) (€)-106,209-106,209-106,209-106,209-106,209-106,209-106,209-106,209-106,209-106,209-106,209-106,209-106,209-106,209-106,209
NOPLAT (€)411,939411,939411,939411,939411,939411,939411,939411,939411,939411,939411,939411,939411,939411,939411,939
Depreciations (€) +/+40,00040,00040,00040,00040,00040,00040,00040,00040,00040,00040,00040,00040,00040,00040,000
Free Cash Flow (€)-1,020,000451,939451,939451,939451,939451,939451,939451,939451,939451,939451,939451,939451,939451,939451,939451,939
IRR (%)44%
WACC (%)10%
NPV of explicit period (€)2,197,712
Discounted residual value (€)95,757
NPV (€)2,293,469
\n", + "
" + ], + "text/plain": [ + " Year 0 Year 1 Year 2 Year 3 \\\n", + "CAPEX (€) -1,020,000 \n", + "Regular Earnings (€) 558,148 558,148 558,148 \n", + "Irregular Earnings (€) - - - \n", + "EBITDA (€) 558,148 558,148 558,148 \n", + "Depreciations (€) -/- -40,000 -40,000 -40,000 \n", + "EBIT (€) 518,148 518,148 518,148 \n", + "Income tax (Vpb.) (€) -106,209 -106,209 -106,209 \n", + "NOPLAT (€) 411,939 411,939 411,939 \n", + "Depreciations (€) +/+ 40,000 40,000 40,000 \n", + "Free Cash Flow (€) -1,020,000 451,939 451,939 451,939 \n", + "IRR (%) 44% \n", + "WACC (%) 10% \n", + "NPV of explicit period (€) 2,197,712 \n", + "Discounted residual value (€) 95,757 \n", + "NPV (€) 2,293,469 \n", + "\n", + " Year 4 Year 5 Year 6 Year 7 \\\n", + "CAPEX (€) \n", + "Regular Earnings (€) 558,148 558,148 558,148 558,148 \n", + "Irregular Earnings (€) - - - - \n", + "EBITDA (€) 558,148 558,148 558,148 558,148 \n", + "Depreciations (€) -/- -40,000 -40,000 -40,000 -40,000 \n", + "EBIT (€) 518,148 518,148 518,148 518,148 \n", + "Income tax (Vpb.) (€) -106,209 -106,209 -106,209 -106,209 \n", + "NOPLAT (€) 411,939 411,939 411,939 411,939 \n", + "Depreciations (€) +/+ 40,000 40,000 40,000 40,000 \n", + "Free Cash Flow (€) 451,939 451,939 451,939 451,939 \n", + "IRR (%) \n", + "WACC (%) \n", + "NPV of explicit period (€) \n", + "Discounted residual value (€) \n", + "NPV (€) \n", + "\n", + " Year 8 Year 9 Year 10 Year 11 \\\n", + "CAPEX (€) \n", + "Regular Earnings (€) 558,148 558,148 558,148 558,148 \n", + "Irregular Earnings (€) - - - - \n", + "EBITDA (€) 558,148 558,148 558,148 558,148 \n", + "Depreciations (€) -/- -40,000 -40,000 -40,000 -40,000 \n", + "EBIT (€) 518,148 518,148 518,148 518,148 \n", + "Income tax (Vpb.) (€) -106,209 -106,209 -106,209 -106,209 \n", + "NOPLAT (€) 411,939 411,939 411,939 411,939 \n", + "Depreciations (€) +/+ 40,000 40,000 40,000 40,000 \n", + "Free Cash Flow (€) 451,939 451,939 451,939 451,939 \n", + "IRR (%) \n", + "WACC (%) \n", + "NPV of explicit period (€) \n", + "Discounted residual value (€) \n", + "NPV (€) \n", + "\n", + " Year 12 Year 13 Year 14 Year 15 \n", + "CAPEX (€) \n", + "Regular Earnings (€) 558,148 558,148 558,148 558,148 \n", + "Irregular Earnings (€) - - - - \n", + "EBITDA (€) 558,148 558,148 558,148 558,148 \n", + "Depreciations (€) -/- -40,000 -40,000 -40,000 -40,000 \n", + "EBIT (€) 518,148 518,148 518,148 518,148 \n", + "Income tax (Vpb.) (€) -106,209 -106,209 -106,209 -106,209 \n", + "NOPLAT (€) 411,939 411,939 411,939 411,939 \n", + "Depreciations (€) +/+ 40,000 40,000 40,000 40,000 \n", + "Free Cash Flow (€) 451,939 451,939 451,939 451,939 \n", + "IRR (%) \n", + "WACC (%) \n", + "NPV of explicit period (€) \n", + "Discounted residual value (€) \n", + "NPV (€) " + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "BusinessCaseReport(hpcase).show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:py38]", + "language": "python", + "name": "conda-env-py38-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/pyrecoy/pyrecoy/tests/__init__.py b/pyrecoy/pyrecoy/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pyrecoy/pyrecoy/tests/test_assets.py b/pyrecoy/pyrecoy/tests/test_assets.py new file mode 100644 index 0000000..4a7c3f6 --- /dev/null +++ b/pyrecoy/pyrecoy/tests/test_assets.py @@ -0,0 +1,324 @@ +import pytest +from pyrecoy import assets +from numpy.polynomial import Polynomial + + +class TestAsset: + @pytest.fixture() + def asset(self): + return assets.Asset( + name="TestAsset", max_power=2, min_power=-2, default_load=1, idle_load=0.2 + ) + + def test_init(self, asset): + assert asset.max_power == 2 + assert asset.min_power == -2 + assert asset.default_load == 1 + assert asset.idle_load == 0.2 + + @pytest.mark.skip(reason="Not implemented.") + def test_set_load(self): + assert NotImplementedError() + + @pytest.mark.skip(reason="Not implemented.") + def test_set_freq(self): + assert NotImplementedError() + + @pytest.mark.skip(reason="Not implemented.") + def test_MW_to_MWh(self): + assert NotImplementedError() + + @pytest.mark.skip(reason="Not implemented.") + def test_MWh_to_MW(self): + assert NotImplementedError() + + @pytest.mark.skip(reason="Not implemented.") + def test_set_financials(self): + assert NotImplementedError() + + +class TestEboiler: + @pytest.fixture() + def eboiler(self): + return None + + @pytest.mark.skip(reason="Not implemented.") + def test_init(self): + assert NotImplementedError() + + @pytest.mark.skip(reason="Not implemented.") + def test_set_load(self): + assert NotImplementedError() + + @pytest.mark.skip(reason="Not implemented.") + def test_set_heat_output(self): + assert NotImplementedError() + + +class TestHeatpump: + @pytest.fixture + def hp_fixed(self): + return assets.Heatpump( + name="Heatpump w/ Fixed COP", max_th_power=4, cop_curve=2 + ) + + @pytest.fixture + def hp_poly(self): + return assets.Heatpump( + name="Heatpump w/ Polynomial COP", max_th_power=4, cop_curve=[4, -2] + ) + + @pytest.fixture + def hp_func(self): + def func(Tsource, Tsink): + Tsink += 273 + Tsource += 273 + + c1 = 0.267 * Tsink / (Tsink - Tsource) + c2 = 0.333 * Tsink / (Tsink - Tsource) + + return Polynomial([c2, c1]) + + return assets.Heatpump( + name="Heatpump w/ Func COP", max_th_power=4, cop_curve=func + ) + + def test_init(self, hp_fixed, hp_poly, hp_func): + assert hp_fixed.max_th_power == 4 + assert hp_fixed.min_th_power == 0 + assert callable(hp_fixed.cop_curve) + + assert callable(hp_poly.cop_curve) + + assert callable(hp_func.cop_curve) + + def test_get_cop(self, hp_fixed, hp_poly, hp_func): + assert hp_fixed.get_cop(load=4) == 2 + assert hp_fixed.get_cop(load=4, Tsink=100, Tsource=10) == 2 + assert hp_fixed.get_cop(load=0) == 2 + assert hp_fixed.get_cop(load=2) == 2 + assert hp_fixed.get_cop(load=1.25) == 2 + + assert hp_poly.get_cop(load=0) == 4 + assert hp_poly.get_cop(load=2) == 3 + assert hp_poly.get_cop(load=4) == 2 + + with pytest.raises(ValueError): + hp_fixed.get_cop(load=5) + + with pytest.raises(ValueError): + hp_fixed.get_cop(load=-1) + + assert round(hp_func.get_cop(load=3, Tsink=110, Tsource=20), 2) == 2.27 + + def test_th_to_el_power(self, hp_fixed, hp_poly, hp_func): + assert hp_fixed._th_to_el_power(p_th=4) == -2 + assert hp_fixed._th_to_el_power(p_th=2) == -1 + assert hp_fixed._th_to_el_power(p_th=0) == 0 + + assert hp_poly._th_to_el_power(p_th=2) == -2 / 3 + + assert round( + hp_func._th_to_el_power(p_th=3, Tsink=110, Tsource=20), 2 + ) == round(-3 / 2.27, 2) + + def test_set_load(self, hp_fixed): + with pytest.raises(NotImplementedError): + hp_fixed.set_load(3) + + def test_set_heat_output(self, hp_fixed, hp_poly, hp_func): + with pytest.raises(ValueError): + hp_fixed.set_heat_output(th_output=-1) + + with pytest.raises(ValueError): + hp_fixed.set_heat_output(th_output=5) + + with pytest.raises(ValueError): + hp_fixed.set_heat_output(th_output=5, Tsink=20, Tsource=100) + + assert hp_fixed.set_heat_output(th_output=2) == 2 + assert hp_fixed.set_heat_output(th_output=2, Tsink=100, Tsource=10) == 2 + assert hp_fixed.set_heat_output(th_output=2, return_eload=True) == (2, -1) + assert hp_fixed.get_heat_output() == 2 + + assert hp_poly.set_heat_output(th_output=2, return_eload=True) == (2, -2 / 3) + assert hp_poly.get_heat_output() == 2 + + assert hp_func.set_heat_output(th_output=2, Tsink=110, Tsource=20) == 2 + + def test_cost_function(self, hp_fixed): + assert hp_fixed._cost_function(x=2, c1=40, c2=20, c3=4) == 40 + 40 + assert hp_fixed._cost_function(x=2, c1=40, c2=20, c3=5) == 40 + 60 + + def test_set_opt_load(self, hp_fixed, hp_poly, hp_func): + assert round(hp_fixed.set_opt_load(50, 20, 4), 2) == 0 + assert round(hp_fixed.set_opt_load(30, 20, 4), 2) == -2 + assert round(hp_fixed.set_opt_load(30, 20, 5), 2) == -2 + e_load, th_load = hp_fixed.set_opt_load(30, 20, 5, return_th_load=True) + assert round(e_load, 2) == -2 + assert round(th_load, 2) == 4 + + assert round(hp_poly.set_opt_load(20, 20, 4), 2) == -2 + assert round(hp_poly.set_opt_load(30, 20, 4), 2) == -1.27 + assert round(hp_poly.set_opt_load(40, 20, 4), 2) == -0.83 + assert round(hp_poly.set_opt_load(50, 20, 4), 2) == -0.53 + assert round(hp_poly.set_opt_load(60, 20, 4), 2) == -0.31 + assert round(hp_poly.set_opt_load(70, 20, 4), 2) == -0.14 + assert round(hp_poly.set_opt_load(80, 20, 4), 2) == 0 + assert round(hp_poly.set_opt_load(100, 20, 4), 2) == 0 + + assert round(hp_func.set_opt_load(0, 20, 4, Tsink=110, Tsource=20), 2) == -1.57 + assert round(hp_func.set_opt_load(30, 20, 4, Tsink=110, Tsource=20), 2) == -1.57 + assert round(hp_func.set_opt_load(100, 20, 4, Tsink=110, Tsource=20), 2) == 0 + + +class TestBattery: + @pytest.fixture + def battery(self): + return assets.Battery( + name="Battery", + rated_power=2, + rated_capacity=2, + roundtrip_eff=0.9, + min_soc=0.2, + max_soc=0.8, + ) + + def test_init(self, battery): + assert battery.max_power == 2 + assert battery.min_power == -2 + assert battery.min_soc == 0.2 + assert battery.min_chargelevel == 0.4 + assert battery.max_soc == 0.8 + assert battery.max_chargelevel == 1.6 + assert battery.soc == battery.min_soc + assert battery.rt_eff == 0.9 + + def test_set_soc(self, battery): + battery.set_soc(0.5) + assert battery.get_soc() == 0.5 + assert battery.get_chargelevel() == 1 + + with pytest.raises(ValueError): + battery.set_soc(0.9) + + with pytest.raises(ValueError): + battery.set_soc(1.1) + + with pytest.raises(ValueError): + battery.set_soc(0.1) + + with pytest.raises(ValueError): + battery.set_soc(-0.1) + + def test_set_chargelevel(self, battery): + battery.set_chargelevel(1) + assert battery.get_soc() == 0.5 + assert battery.get_chargelevel() == 1 + + battery.set_chargelevel(1.6) + assert battery.get_chargelevel() == 1.6 + assert battery.get_chargelevel() == battery.max_chargelevel + assert battery.get_soc() == battery.max_soc + + with pytest.raises(ValueError): + battery.set_chargelevel(2) + + with pytest.raises(ValueError): + battery.set_chargelevel(1.9) + + with pytest.raises(ValueError): + battery.set_chargelevel(0) + + with pytest.raises(ValueError): + battery.set_chargelevel(-1) + + def test_set_load(self, battery): + battery.set_freq("15T") + battery.set_soc(0.5) + assert round(battery.set_load(2), 4) == 2 + assert round(battery.get_load(), 4) == 2 + assert round(battery.get_soc(), 4) == 0.25 + assert round(battery.get_chargelevel(), 4) == 0.5 + + battery.set_soc(0.5) + assert round(battery.set_load(-2), 4) == -2 + assert round(battery.get_load(), 4) == -2 + assert round(battery.get_soc(), 4) == round(0.5 + 0.25 * 0.9, 4) + assert round(battery.get_chargelevel(), 4) == round(1 + 0.5 * 0.9, 4) + + battery.set_soc(0.25) + assert round(battery.set_load(2), 4) == 0.4 + assert round(battery.get_load(), 4) == 0.4 + assert round(battery.get_soc(), 4) == 0.2 + assert round(battery.get_chargelevel(), 4) == 0.4 + + battery.set_soc(0.75) + assert round(battery.set_load(-2), 4) == round(-0.4 / 0.9, 4) + assert round(battery.get_load(), 4) == round(-0.4 / 0.9, 4) + assert round(battery.get_soc(), 4) == 0.8 + assert round(battery.get_chargelevel(), 4) == 1.6 + + battery.set_soc(0.5) + + with pytest.warns(UserWarning): + assert round(battery.set_load(3), 4) == 2 + + battery.set_soc(0.5) + with pytest.warns(UserWarning): + assert round(battery.set_load(-3), 4) == -2 + + battery.set_soc(0.5) + assert round(battery.set_load("max"), 4) == 2 + + battery.set_soc(0.5) + assert battery.set_load("min") == -2 + + def test_charge(self, battery): + battery.set_freq("15T") + battery.set_soc(0.5) + assert battery.charge(2) == -2 + assert battery.get_load() == -2 + assert battery.get_soc() == round(0.5 + 0.25 * 0.9, 4) + + with pytest.raises(ValueError): + battery.charge(-1) + + def test_discharge(self, battery): + battery.set_freq("15T") + battery.set_soc(0.5) + assert battery.discharge(2) == 2 + assert battery.get_load() == 2 + assert battery.get_soc() == 0.25 + + with pytest.raises(ValueError): + battery.discharge(-1) + + +class TestGasBoiler: + @pytest.fixture() + def gasboiler(self): + return assets.GasBoiler(name="Gasboiler", max_th_output=10, efficiency=0.90) + + def test_init(self, gasboiler): + assert gasboiler.max_power == 10 + assert gasboiler.min_power == 0 + assert gasboiler.efficiency == 0.9 + + def test_get_load(self, gasboiler): + with pytest.raises(NotImplementedError): + gasboiler.get_load() + + def test_set_load(self, gasboiler): + with pytest.raises(NotImplementedError): + gasboiler.set_load(5) + + def test_set_heat_output(self, gasboiler): + assert gasboiler.set_heat_output(5) == 5 + assert gasboiler.get_heat_output() == 5 + assert gasboiler.set_heat_output("max") == 10 + assert gasboiler.set_heat_output("min") == 0 + + def test_get_gas_cons(self, gasboiler): + gasboiler.set_heat_output(5) + assert gasboiler.get_gas_cons() == -5 / gasboiler.efficiency diff --git a/pyrecoy/pyrecoy/tests/test_financial.py b/pyrecoy/pyrecoy/tests/test_financial.py new file mode 100644 index 0000000..a6f5f8a --- /dev/null +++ b/pyrecoy/pyrecoy/tests/test_financial.py @@ -0,0 +1,61 @@ +import pytest +from pyrecoy.financial import * + + +@pytest.mark.skip(reason="Not implemented.") +def test_calc_energy_market_results(): + assert NotImplementedError() + + +@pytest.mark.parametrize( + "inputs, exp_output", + [ + ({"cons": 1, "year": 2020, "base_cons": 0}, -125), + ({"cons": 10, "year": 2020, "base_cons": 0}, -1250), + ({"cons": 100, "year": 2020, "base_cons": 0}, -6484.7), + ({"cons": 1000, "year": 2020, "base_cons": 0}, -37_111.7), + ({"cons": 100_000, "year": 2020, "base_cons": 0}, -428_881.7), + ({"cons": 100, "year": 2020, "base_cons": 100_000}, -95), + ({"cons": 100_000, "year": 2020, "tax_bracket": 1}, -428_881.7), + ({"cons": 100_000, "year": 2020, "tax_bracket": 2}, -427_641.2), + ({"cons": 100_000, "year": 2020, "tax_bracket": 3}, -424_146), + ({"cons": 100_000, "year": 2020, "tax_bracket": 4}, -95_000), + ( + {"cons": 100_000, "electr": False, "year": 2020, "base_cons": 100}, + -547_302.20, + ), + ( + { + "cons": 100_000, + "electr": False, + "year": 2020, + "base_cons": 0, + "m3": True, + }, + -41_057, + ), + ( + { + "cons": 100_000, + "electr": False, + "year": 2020, + "base_cons": 0, + "horti": True, + "m3": True, + }, + -6_588, + ), + ], +) +def test_calculate_eb_ode(inputs, exp_output): + assert calculate_eb_ode(**inputs) == exp_output + + +@pytest.mark.skip(reason="Not implemented.") +def test_income_tax(): + assert NotImplementedError() + + +@pytest.mark.skip(reason="Not implemented.") +def test_calc_business_case(): + assert NotImplementedError()