From fd6719a6773b7aa8a111bb0d776f6d3785f67f55 Mon Sep 17 00:00:00 2001 From: Lukas Klingsbo Date: Mon, 24 Jun 2024 23:42:45 +0200 Subject: [PATCH] feat: Package for loading XML spritesheets by kenney.nl (#3205) A parsing package for https://kenney.nl spritesheets. --- .github/.cspell/people_usernames.txt | 1 + packages/flame_kenney_xml/.metadata | 10 +++ packages/flame_kenney_xml/CHANGELOG.md | 4 + packages/flame_kenney_xml/LICENSE | 21 +++++ packages/flame_kenney_xml/README.md | 41 ++++++++++ .../flame_kenney_xml/analysis_options.yaml | 1 + packages/flame_kenney_xml/example/.gitignore | 43 +++++++++++ packages/flame_kenney_xml/example/.metadata | 30 +++++++ packages/flame_kenney_xml/example/README.md | 3 + .../example/analysis_options.yaml | 1 + .../assets/images/spritesheet_stone.png | Bin 0 -> 77870 bytes .../example/assets/license.txt | 14 ++++ .../example/assets/spritesheet_stone.xml | 57 ++++++++++++++ .../flame_kenney_xml/example/lib/main.dart | 45 +++++++++++ .../flame_kenney_xml/example/pubspec.yaml | 23 ++++++ .../lib/xml_sprite_sheet.dart | 66 ++++++++++++++++ packages/flame_kenney_xml/pubspec.yaml | 30 +++++++ .../test/xml_sprite_sheet_test.dart | 73 ++++++++++++++++++ 18 files changed, 463 insertions(+) create mode 100644 packages/flame_kenney_xml/.metadata create mode 100644 packages/flame_kenney_xml/CHANGELOG.md create mode 100644 packages/flame_kenney_xml/LICENSE create mode 100644 packages/flame_kenney_xml/README.md create mode 100644 packages/flame_kenney_xml/analysis_options.yaml create mode 100644 packages/flame_kenney_xml/example/.gitignore create mode 100644 packages/flame_kenney_xml/example/.metadata create mode 100644 packages/flame_kenney_xml/example/README.md create mode 100644 packages/flame_kenney_xml/example/analysis_options.yaml create mode 100644 packages/flame_kenney_xml/example/assets/images/spritesheet_stone.png create mode 100644 packages/flame_kenney_xml/example/assets/license.txt create mode 100644 packages/flame_kenney_xml/example/assets/spritesheet_stone.xml create mode 100644 packages/flame_kenney_xml/example/lib/main.dart create mode 100644 packages/flame_kenney_xml/example/pubspec.yaml create mode 100644 packages/flame_kenney_xml/lib/xml_sprite_sheet.dart create mode 100644 packages/flame_kenney_xml/pubspec.yaml create mode 100644 packages/flame_kenney_xml/test/xml_sprite_sheet_test.dart diff --git a/.github/.cspell/people_usernames.txt b/.github/.cspell/people_usernames.txt index a8155a585..7bfcc866e 100644 --- a/.github/.cspell/people_usernames.txt +++ b/.github/.cspell/people_usernames.txt @@ -6,6 +6,7 @@ erickzanardo # github.com/erickzanardo feroult # github.com/feroult fröber # github.com/Brixto gnarhard # github.com/gnarhard +kenney # kenney.nl Klingsbo # github.com/spydon luanpotter # github.com/luanpotter Lukas # github.com/spydon diff --git a/packages/flame_kenney_xml/.metadata b/packages/flame_kenney_xml/.metadata new file mode 100644 index 000000000..2b377030c --- /dev/null +++ b/packages/flame_kenney_xml/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "7482962148e8d758338d8a28f589f317e1e42ba4" + channel: "stable" + +project_type: package diff --git a/packages/flame_kenney_xml/CHANGELOG.md b/packages/flame_kenney_xml/CHANGELOG.md new file mode 100644 index 000000000..b208df87e --- /dev/null +++ b/packages/flame_kenney_xml/CHANGELOG.md @@ -0,0 +1,4 @@ +## 0.1.0 + + - **FEAT**: Add initial version of `flame_kenney_xml`. + diff --git a/packages/flame_kenney_xml/LICENSE b/packages/flame_kenney_xml/LICENSE new file mode 100644 index 000000000..0cf87ff46 --- /dev/null +++ b/packages/flame_kenney_xml/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Blue Fire + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/flame_kenney_xml/README.md b/packages/flame_kenney_xml/README.md new file mode 100644 index 000000000..e1bda7d67 --- /dev/null +++ b/packages/flame_kenney_xml/README.md @@ -0,0 +1,41 @@ + +

+ + flame + +

+ +

+Adds support for parsing XML sprite sheets from https://kenney.nl, and other sprite sheets on the same format. +

+ +

+ + + + +

+ +--- + + + +## Getting started + +To get started, first add `flame_kenney_xml` as a dependency in your flutter project. + +```bash +flutter pub add flame_kenney_xml +``` + +Then place the `spritesheet.json` in `assets/` and `spritesheet.png` in `assets/images/` +(or whatever the names of the files are). + +Then load the image and the spritesheet using: + +```dart +final spritesheet = await XmlSpriteSheet.load( + image: 'spritesheet.png', + xml: 'spritesheet.xml`, +); +``` diff --git a/packages/flame_kenney_xml/analysis_options.yaml b/packages/flame_kenney_xml/analysis_options.yaml new file mode 100644 index 000000000..85732fa02 --- /dev/null +++ b/packages/flame_kenney_xml/analysis_options.yaml @@ -0,0 +1 @@ +include: package:flame_lint/analysis_options.yaml diff --git a/packages/flame_kenney_xml/example/.gitignore b/packages/flame_kenney_xml/example/.gitignore new file mode 100644 index 000000000..29a3a5017 --- /dev/null +++ b/packages/flame_kenney_xml/example/.gitignore @@ -0,0 +1,43 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/packages/flame_kenney_xml/example/.metadata b/packages/flame_kenney_xml/example/.metadata new file mode 100644 index 000000000..36786568e --- /dev/null +++ b/packages/flame_kenney_xml/example/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "761747bfc538b5af34aa0d3fac380f1bc331ec49" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49 + base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49 + - platform: linux + create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49 + base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/packages/flame_kenney_xml/example/README.md b/packages/flame_kenney_xml/example/README.md new file mode 100644 index 000000000..c7c39f28b --- /dev/null +++ b/packages/flame_kenney_xml/example/README.md @@ -0,0 +1,3 @@ +# flame_kenney_xml example + +An example of how to use the flame_kenney_xml package. diff --git a/packages/flame_kenney_xml/example/analysis_options.yaml b/packages/flame_kenney_xml/example/analysis_options.yaml new file mode 100644 index 000000000..85732fa02 --- /dev/null +++ b/packages/flame_kenney_xml/example/analysis_options.yaml @@ -0,0 +1 @@ +include: package:flame_lint/analysis_options.yaml diff --git a/packages/flame_kenney_xml/example/assets/images/spritesheet_stone.png b/packages/flame_kenney_xml/example/assets/images/spritesheet_stone.png new file mode 100644 index 0000000000000000000000000000000000000000..83be767c5372aa88949746247aac02b5a8231d2f GIT binary patch literal 77870 zcmZs@c{~*C*FS#E7$PaVLK$1OES0hpMp03=Y$00;rIPIHjHM!?ED>2si+#<$j22{< zoh*frZL*GG%>1s=eSf~6=lMOa{0D4vejA|>PB8e^EGoOoc%+Tns)S~Km4DRL-^0A{#w~AXt?5Z-ELX+ zoPZU*{34eoC%wXcHm-U`gu1%A2&1Gn=1GI%a{bw_f<5?r?T+?03p&Q`#%noQV<#F; zT>7BUYwS9jXMDe<&0C0-A^IIdvnYem8O;)ynLvjM*;+ro$$ z((SqVLsP1!mLlStU-rBtU7OC+OFykQ#TW9sRiWnmdiUm$DT}U-Jl~Gg$_{G}w}8Hx zK|cx!tGbk`f8wO@R@)S0^7>q(vXRMY3~cxg5tbAIe3MPst8qoxS`;CP{~1 zIJ1^I*GiAVZ@9+zPA4$hlzym>BloAL)R4u5FooOC0@9^XUo10kvU|owndYy4 zAJ?w&`WDeLJBi;MoS_nq$nqxF*`BpqmJb1TIDlsPpb4%Nj+E1hWvilcoExE&n8}M z5Oj)!%DRND&HU0oU`;>JTDE@w_Rm-S-sCUbP*T*fgNiejFDjCny$WM;%_G=m6B+q zFoZ{3c%ESU*o}tpsm0_65B5zdraz~}N9Dte+mXJ&BX!AAc6m9uyQyfI#> z-Q`E4lSw9?9V>jASJKStiZ$__iAhpJIE|ysHFMESZTbxiuvJcyv@_Rq);@%vKnf4IEUx#!G|L4i5fzUal$ z|J+oVN=g#Kq@%>zmd=pN9*#KL@U&kIUUVj z&&@GUS}NLd>_|0VbExL5@?pHre=Fdcw(#2v>1(at59kIpFx8x45Z5) zkR4!odUltb@~OrU4-M2;pJlB7VlDCWBxgrO>x;NJeAEo>0^)?&Agd|9h+~lF{kv=% z0uN>n9^5Pu8++@&G{kF@$S@nivLzBJCj=(ws}Re^$SF^Wnzr4=9734B7_4P}qEeWV zG}-d8gXd&#YS|P|xdQ89Ox*WlV>Yo%mwPs%NNfT88#k!Gw%#xMh*HgOMwu_B_C5b{ ziw%PpbacfuFvHt3+JmawA07)K9kIrTnkgmk4e_?r7saP1iZ<_huHJxL9(my`*X$)o zvExS_-1TnWI(a?LD4Q9}UHNk^^b`}9a%4dlf5ECnP$-DtnP>R=iq7U(l_2uE3MrnB z>}{9cC1|X3+p9r9Ok|jY@rCnKOv;9=?*v9?b-sxD%QW9S@1;@jOw4Cf@&k?&{&||) zNml9orR>6zx-mAdv;jx97RsjDMgi;vr3R?4n=aT}%IU`+v<j6 zRQFyI^Al}1*R=NEcAB)((w=NHNHEAC&K_SiGtdAhBtK~4?BCPLSrzc5)$L82UY5Ir z>t7uGel3*vQaSne*ve|Z^>&xy_H#>>#<|+XKlQIJQQO~eL}vsdLcB#*SPm;e6)hj2 z)+_C8b>hs|l-TMIy3o-nigo#NDEn5yd*NTT^E2f6@Z>7hT-p`vN(J`M7O%dr<*{h> zz*XE&AGdEbJZ_~rI;+ir!O`KQUHR%FF8QJs^-c7qc!#dWmcB{+3mYURkH4%-fRU4Ba+NYA093`W}> z)xFX9@$BdzpF$bgxACVi*7(%R`IdR-OHzU#FC)lC8{Qlq7F;X20}~InVgtz2uT%Hl z?}$}=WVTjzal2$FpCfhLCo*eq!2?`@{~P=MKJvMT%57-|YM_C+Nex;9V-|12iI1^+ z4)LCz7JIlEAR4^gpC^pG)Uok!AQXHjE;wtUzo{7C90)9?%Vd`3X%wq2QE-;BK&&S( z=97~`SdOnRssuy;jLmM$JX11Keq~Hu15EKD0g(xTZuj-LF_qWvGU=%KG@^1`02QE# zF}<#C`XBtg`iQs7vHgZAwugH(57U+mf`0GdnVBM}?wz zqOng+*=!Uu7+D){;eV%PP3rlM#-V2wxmKLDZL(YH!zGak>^{a95`15am=g_|YS{gm zP*2v?Z_!&3H?RI4ES)GjQhQ~rhzoP=VZ}+6t(F)=Mu2(;M4oq&M2irmbaG?+WrxL3 zIK{;mmg{3VRRP2L<98t=gL`c@5eZ&bS#}+e6`=w)^lC_6$#*s5<6Cb~{ZkJv z2RT{2*I4Q#F`wXbTeUi{w3%lm6~UM`sdC}7@PRuu9$tQ*2(wv}L$&y!n6b#QSGi#J zj!h|Y|3{&@Y$_uF*Tr6SH(xoo#L4b z@@st-s5Mr0&Gl5`mOsm>pZg+5c31CH&E}$yiF#ft?{GA%mSP=7Nv_w#KYnd~sj#BD z@b{P#)9wY%`%R^M@v?Vsk}9#IowHhLjXgcxa5W9Z$XE=S_5`iyihQGj+HI#0upD^(MDAZ zARYVTf_?YfdW}NzIMaVE#icVBJpQaxZJ)LODi4Si=GVvOTs|{q`IuBsrOq5BP_>n` z-BZ{f-Xz`wby{q7sa|K}Z!IpErYjT=IiqkbZ$&7RUwbjWuB~HpYvFTq0(Y4HaF7h& ztKA1vKDUeoW)fo+vtw0T!rn<9CUa3rrsKB0Mdnd*^~WP_Y9~DE#lj|KSa;^r$iPK6f8M!Pqu0D#rzo9*{ck@ov@0N}${re}&j>KNOXIPlo z{b`&XMDxoIo#dC#H076+H2roh{XYFKzIBrur$*1AzymIXk+R5V1It6g6OMZOmp&Fd zjE)vz?s=@9`%$CRi&dliv2Bw^TwdK9TlGUhdvn35>y~$4j86BZj+5HjS;hCaPv!Jd z?R(KXe*7V^^MC;N2PWUVAA_rz9>_ z`)IMxrNQrDoE1d#%9^h!h()}ZvK_j<2iGnB7&Lu^nFyWOid zu+_qZ_g*NeA|m;g&8hazOmgR&dMgiQdiBOw__oij@qLvvUX*34o9}3T%-Cso_nLTm z&UAEA3@QDp$U#^2a3XV@UYZwkNno6r)wET4vRif6O~>YuXm;t4~iO0akq{Y~P_X8O}@zr3OuOai8dVhu!%g~-qqp_hj zlqCn~5gESveOpYA?5A#I=OTUS@#9m$CmZwDEM)XXNZm$WXe92FB3&GQAgnZ6FImF* z@a3Az{7eik%DBQU;+zM*!?(-&BC3E-wDJgY^|{oUt7hBIrMskCD+)zK02;Q(xN0$~ zCOc@QV5N^`a@G!R8A;pb$5xSZdQ;Ie-=a1b-lfJ@h{@~*$}+=@C$%?Ycx5XcLP45b zJBFiKgbJI7Oz-D@YZ`Mh1S&z`K-dT(<2B|xi$)l$*>7Cx*V&a%)++3m(zzE3`GV)D{8*qa6?6s zLb40+zK(6e37ql_Xpvx2e*Ud@o4RYWqufR1XrwGVJAl@L#EiyJ&oF^sHOp$M3Hw%S zw;kFOjhCG*u~S2@)0}!~hga@eS8>q+1uawuQ#mmFO=8|wv} zA0>85R_(oo3VQB1{mlHAn*ON0t-#G=D=QtkcZ2nVA z(`vxlHmd(Z;YbfKgzoL*Ta)l$ds%#*(pTrCBlU3<6$yopu9`q@qF#pDfAZ&thVa4l zS6e~#^bhodl5}Q1^E{F~XLOKk))b|-R2HRbbnQ;0t&#IXa|`*a16ek_+_z3)s)(z? z0Lr+|&#sztyW)|GsBjZ>3HzE^27&ceTy@*Nk>HGV`6o-)crQscL^vV#R3R=>l6!nC_2R}Ef z^A#^%D?K(~T3sn~-u`0U_`9OhKuz2@`OoCqoc8BWirF+hqYZ3p5zy9f9-F_h*tHSr zb=z;UvPfLmvl4M`2l^wBYBSI_6>WgR32JGzS8R`%rFFW5MY!W!YV;La6G-kM%WFsE@PGj&_ zJ0+K&DPxSsfeUl0@cay3+Q=eVc~oYv{elemvou^8cKt=32a9+Rr~# zerkln)%vR9$*$Fg#DvtS8pKHtx*q_k>sb7{a=PcYcDiyHLhI#pVwvzZuPEi#%jx?L zRPmnm2jx5Rt{`w2y8!JGsbRR zP+O=^v@pwbTkp3bRf|$i_SSXIzc4&tda4w_Qt;-cPt7|s+?g{-fCLyI?n9nFCTs*Y zvM1>j8j&?HI;3~~82F_Mw14P~R~OVCnkh?`A(SZeve;_i-lR;|c5laN78h>qgT~@m zMpv$^GBILybye)G(#ps?Wsh6q>qP{-5Qxy#b6C89H<1XI{&*H|edB6wfYpG?wyp8> z$3hDzXEY6N9LFOWfi+=qXfDUnOU1xKNmVJGF$#g)FlZo%0#aX38H|tOAGm6H}F8|U_ zSIZ5Jy41m`4GauF`@h#E5iwjsHv>Fh`f_SrfR~2~X9R5zHqXU*?gW^?-?8{Ig3%8m zrMmFvstd02u&aL*GLI6j{m04pBxJ&TP{{Z8Of+%(cL0H!Gf{Bo*0ZCFi?o7y7wb2K zcv!OEhe@#yrL5?zq#DbEfBdO0E=c8h|BP~VEzHF^Tz)32#GE`b6zPitFrw1(TM&4f z0$9)2TbeVCOs7((Ikrh7fx&@eRUb%2P!08xpm;Oispt6vG+s-q#$PW>t@s5a>*1dS z2~lzu>taUCAE)m@x)zv-@n}G6G#J4m6UfV%3Ft1FzL5|EAfmMWrN^%!{$O%y z#qvuX&EO2Do)QL<4$s}FEyA~&4C3Gu4cs~Z0?w68=Y-!=)=m$suRY*?e985860J7L zT!P-8rarg@i<4?!DXGzLPeL`!v(Vx*%s*w+UsegfLZ4>1cgTSLzl4DU`p*0i>0Ru` zW;0oJ5@qo|zgVL5$Z_)V(bsrNk&eGcMP@2bTH1Av6;oTy48L{u&zzbK191xi!lr6N zc!85YO-Iunoc*;oxXdK1eTi}gE5c=Qvj)vFn;oJ4ju9kf$jgTrs z{CLbi|HFN&Y&X^3N&MBOG^ef-ddqE7_IznppZrD5VnP--q6g#BUzn2ER4cF&cTH`r zuB*@H4%^#;Ctzb8hysPL*gp_6Kz zS|zY?`~%*KDc5Y+(NqnbBK4QdBnB;RM=8s;{$?^@54gi*=~uW&WHWqlo4b)2C_+am zMaa)Fp1$8(OnjrYM;+9Cq=o)2UfIJf*LKTybi*S)ksn41pFi6cp6}sKX(_G9QtW(AcaU^7dA?tJV@2-o6;M-O$bN!l zhy>mI%OUO}X^BW7@WY1YDmNo|PLVuG^B&{)by2q|d0c@pfGFmAU%*zIUbT)W&Sau{ zhAE9uU`lakspPga?3|<8-p{fnQqMKvxl3M)kfE*p0K4NDJJc+)GrlM@yk*3b>IMU~ zyLsY*o{T2_+K=Ji0}T=#w{%U6s%`Z+AT`LNQZ^Bw6DC$ZnIJL*>SPIH&Vzf?RF-GI zruMA#I3)RRKn$xt%_-CU3Hyl;ruf96&jLpKi(|0TGYKKqV|<5y(mKUPBxbDFNk^>M z%1{J>IWL-c2Pm_P67Z&t_ym~(NtPH8y}2F?Cgf(kLwkQvFR# zT3HMZ1!hmE<}auoJlkn!!laRoYnEZUla-WUbhEvGq0ix5<;lrI-^4&REC3A|T=D#qM8o>jTJNi4gwLJ46JjLbm<@d(h zPuIpYcCx_NQLjQxoQFVv-(9x4*a`&>#N(HpFE|jo)>VhJQ2HFIqEpHfqelKFCf_ek z=xKRAT|oFev2qIG^Ci@%T8zCS>@J#yAwMK1q%a11=e=z;%{m7e^kW>HhjU^nbNlx% zu(W(8XiEtOvIcbc1s6uf-(pM4a7nYA8g-1T`pT5dPAE{}$Rhn9F=L&p*^nO`tZJUV zj&!auO|@mm`j^%U-!8_>Au*kk0ti~(*pE{njJB+u#L=)E!rZ~i*zhjc972rEX1y^y zx5vYPpmN70iykfHfnrz^?*`OU3C3QYnc=hAzvcU4j z#U0@K=DsTxufj~6m{8FZO+Td`Tv=1-8C4W^yYS=dgmXkuMk5S$-J z{=T;`R0uZ}{lb)1R_*X;;w(^U7RJqn7*f~~-*|Z$ui?7Mg}5K@4cO9L?ub!bBApwU zk>IP~Z9CEW=)5Mm<`k;Wjo3}!mBi|Bka)_YyYWu)$mbpTwXqvmRzV&||B7)Jg*HO9 z+kCn|i{HBUf{O|LS6#$@o84J^uULb29;12x1fSsgJ@^ zVSStN-emLKZ2oNwcrOa^`L zud1qzV_`hrzh+)@o^Yq6(AuD(1;X)CMCW-59po)>|GS#|38FG#C}GyVdtZK$URAtS zN`Gg!kl^f7gA6J!qd!VmQL?geX}D-$YhuxT<)9|`iU&^>s;cU1p?ymPIQASzw@kbx zE*D@I&NDF7Jo|kB(!G`2UbLIZRymGMtF^3ry=2JuoozrP^O1AEjM?m7WLWgFLdSc2 z+f#H;4?A!1X{)^~DJ%KgtzQ}61MtV7&id|Yk;T(qUtuhre4?x8>nbIs%F~~+H9dHi zk@|Wn(P-2Jch(qV+qo*fNaal_3qBrQ#{A`iMMCC9AZ^^ZEVA03Heru8GPgE*Nw{&Pi&_me;VT?UG;rmc zZ_!}#A`mYc>2>aL?sYyHcdnrpo_ECg_NE12Yf0h)*d)N7=7b8Zrr^xGs>^Yf!zz#- z!5xyj@^OVHKq=WEy;ohajbtAV+O(|}ip-*^*CKfmws++D$zF`wD}=KOhU(Inef4>< zuT<7-zwGQEJY|t6&9!G}Z<<<3$*VzHQ=E1ovbbY@&GL%1SV557Ic+TkDP78vx=H{75DJb^055*5vMTMa=E@K|7Oq6!4EpUk~0goM>P z7bvJYv2gKuLpU2kCborIFQuj<1c1IYh-h!Ook3s1c|I4Qx|iN1rl@^CF?K5qh*0m| zx4-drVS?ViyOvXhWO_~D-It0Pni<(4Kvh+5?e#m=``PLix4!v$?}yQ;h+{hq;pY?( zXtVnhDr0Yz3GR1C*>};#*mZZK)V-Kx!s2Ml>{5{bL-l#)ChSIq$#ph>NL%Cv^LJUc zqU)EAQE%S~XH4q`uuq4q*)S9wR{F>p(o`@MSn5$_=83^zhKl3x=JPcbOmnZr~~9t10t zh9)b3w}fF2O)HA_91N+~p2=$+UQ>=r#W2!73#Najwv57tj=c#h%!V1uBpjxk1$DL8 zEkL=V>d)L-pBhcnfNRk{1Z;;;2mh$VKN1YNad-g}Q@vil=B_rdFt21)kw;h;_)|+z z`&`^M@>$Ok8_{J=s=DX$}#ooQ#;o*i$L*|+$#Y} zQ5`iV%hZ-F;w!%5n@)xU3p&vE$%N)AXy|_w8o3W~H!PM~0R2m^mbcCZPY)eCbncx) zwPC#M7XIz@I4csMJ23!Pa0Q8x7R2~Y(za^?WzXzjCHDlO2^}i=DM7QK^vSW+FN1x( zH6h?>HR#M?v+f!;Na;3xzX-K~WP#OaxC9tDQ#X`U#)#Narb3e%?Tb$*$4*JLm64;?+UnQuwmDvM1~`}gclB<7cA+)JUqr^1B;YHwaUHY^m{L~nJTw6k#&mTk(q ziXP(D`>KWMf+-GbPp<0tpI+T#xs11XkGPuh@(i>H-UScfZ<_C2V|p&}WLKBdsyX}a zQ1Eo#ugZg%LWDzdHYCh(NX+4AEXQ!tcZER^svHfz zL{je(Hl}G{TJB-0_PmoQRVxfs+FPDlvM!xpd_IYXeU9Tw#{)wU@G@yd?P43~KD6(# z>FUU5we1iH&&U^vgQxl!6wYnhqBs|!eEB^dj;GmZT<1CBKjHPVRR2nxF_G+~mUmlAstK<;M_U76S*bD51eV!(N-aVdHhP@74wV&jMOoWF z7ckZMAm13I6o?tiwTI+znDhrs2i*t(#Wk?seHtQTvC_tkG&!kIb6i;XA3M0bj9>rm zJlfNIYjRTU68q?5#y^G<-rq{>Em7jL+&Fuhkt`!|(S*_a_(=J(eOc2uYVun`WQ*QJ zA;y*-R}iLA^AC03m4)$*ko>89{MNz0BG=HR#9ev+j4X`gv;dBWVc>jY_;Dce9PY6u zIV<=Z-wul-OiWxf=C)RHU$A0gV4%Q(AKJ@NjCDtGYqXf;hQck8NZN$74-KCp?{~a@ zmU)WyMLGmH0}HaLBxzJ@Zq5eYlL+CE>4jskuEe;YKz}s#bvV%E0T7X41iu-oz1Pf+KFmRqw5=}NWxy7NK=g*er)X}1-3AQ~@fVhyC;%+dX zCxxv0x_aps>Xk_uBSV;NWy=s{F+qLg$q8tcY|hM!}x^* zop%v7%RjFjc>;pJ9G%*9mLH4^#nYpBCB#Hn-xa8RIfib#xAG*yTe))>J8Cx{L4j3xfc-i>|? zSXb8|8ZF7PtLRuaP4OYp)vwz3OHD@sg=4a89wU>e%m#!sQMdcw{IKIegH1Z;1j(gQxotKjua(#~PlI zr3yWclFABmi+vTLnu&X1QDVV~s5`=*a3@HcQgTIqL`pof{O)z12C8b?XWAHqw{>k^ zxo^VxETeg52%erMIXSV$%?j=-*KgLY?Xk?7|1~kAhBVOMgQyevqIrQ5!;V<>W`tE( zH8ZT%oo{Q_sH$r<9*27t)oY&kt^Txy#~vr@V9y;`CXp%07)8HZ3WO->Rrjvc3m&Ni zKW6=6eDcQLbyY4!2VcL<9vb9Fqoby*Vi~$)o5Y;tzjk206s}Czr97=&DejpE zUX6(8$31!XTdYY918|*hCy!62PztiAre2z%aGUabt(qyV%XST-f#P2afxZ;U^bFq# zlCvq3-?zUNhX^6OaxS|ipd?qHRO955%q?winrf7Y%2IB;&8%S_iqIMrs}j3ikqUwf2JWzJB8xcW1_mxi42#)+u)=e~RgqRDh997@bFoy!!$Si_0VHE%ogC-~jF@0j#G z0vPn}A}R2c+}{Wr%yoMmSZQIvh4ETPa#HWId^A;Lyt4ku6YUeY5fQm?i#YHVu2{VW zY@q1)n31wWJ;h5D9THBw%8q`9BWz8m&NEK$1%6SG^KVb<@PX zAs!Njt}NnW9V@;sN^c|I7>iD3cp6{6xY+IRc8pjlgyd{`hd=>#_E6d#m^9RN>2b4@ z)^GDA1C9S&TuzN-l&jekSt_!lm7OAs;p^>A^NAwfW4|d^>)o>$yz~>}H!N@vHbTwvvU0G<0Tp%(TbhchOE9dfMavt=9V>^X<{@qFXcMxbpvMPoT1RX)>U=xR3osEU@e;cdLFO{{Cy`4F=z zr?l-9nsTA+fZ{xWi(F315^KEd^a&!t5uej0zTH6JNY8UIJrGdp3IRB4-MNYwvRF8+ z@_O&|SGUnb%@Jy^d_G)crqms$KZH06L7W&!gG#qxv&zKX=ErJx&hjDR(|QxMeYPrSAI``w8O_+16w#yTCC zrvU=}d*c_ZP0H4%a{Dc~cb(cRpbluQz!?;nvT$jJ8GsSJd3s zO^Z@2flS!$^?7dl*O5Pr$CDhKMrT$(P$@9I`O>x&0ZsRUf%Gf6`zJJ6>ef@0_%g04 z&wF{38U^IeUy@`kiNPlK=Jr;Uj0LQ85cbA|%HVzKT_1;4#@jB|ve*_NB5aW^Oo0L-2N*ap2pkl{+SE+=f9 zD}D*|8l^bFi(DeRa~H8=w@4>B5Ct7_5&nXZ2S#Be&B8-S{w|y8-Jea(m6<-fS25$Z zkQfKgREDLduIpa{&+Jz#*;Val;wpf|EU{zVRZ}GBr)Gn$&K*!-|4S-!oj`l%aSoQP zX-CrvaZtUT(SS8Z?b!K8x311|^4p~si6G^Rs=#%m_5AQ!CPQJR;lyddh}2td=}Paw z9ysWq=d0jVTyo|P?fZwnLjNkH)A5s96gI@IgG!GfP1Y%5{m&?v^f#2Mv?Zj3Fe+8d zn7%Ba>WEIQ^*A`qWE*kXOvbgFU+QvQoWpwj{3Ogyuh^;RKt~leu(c<6DBiq@wvEut z<_dNHS}DuGF75eFlwe&amW)T;5~Y@uN><1qdx{~erMofwg?3CK*thBoc}}H`HSh3slE>x^`-v`a@*fv`+0^-L=0jP z%R_WBxs;1Q4zHtCtPz;Q5MH@n&Ouc~f%)UN?XCCo$%!u%20_g|{h+oxk=)OYxLQ^P zCK*z(lvF*VLxc*zTH~b+}`uvd!%pc>l$5N{U7A(a@+oyUo7wmimQdn$R|0j+blKHb8- ztmCR@`E*WQSB0%^G`??fx%u^Ngq$&$#W}N2Rm5?@c<=QqAVUqe-c$7fPlaHNRe#v% z!!YV{!#f2Z=aVHEqbB^I(-o&w!Sw?V&5Z4;>x4FiVPJ(m&3NHxX-DbeUpRQ{V|97? zdNuq0vk52Nhlgqn-_Je3K0bITaqJs3Q&FGY_TO!j1=aSGGQR*;fCE zqD5B#Y@?~7$D6o7QgN0UiC~3n*~$hX`m1qu*{eCTYr8JY4%DT*x;P4#V*;p%QwiP0avf)z0&;E4I$Bkw zzN_6Q{9&^$2u;5)2)k^58JW*CW+v#dFkeG%9Cylus`A9xi^n`@~3n4|LnGcL< z#hp*=Zk=Bq3*BAI=>?Z;n6^#GcphvB~1vLihR#0H6`xK@VuSIekX3-iN3b-gLU@m<{r`6UeWE%l)+xH(O+SylKJs+ zojD&nYpUwfTO7NWv0w<-5lBDQX0V^{ zgCzPA)YC)Th5sTRNRRtAsKhTE!t|$oc>=%g6;GTJ0=F%1_V4zup#YDYc$2&j&DJB| zu4b=lcQ!7n{ZY%`JS8HOppB^M=Vth1<&>L+n@um}HKq^IqCiRI{FkKAU%7Gn5(nVB zpL>z;-H-eANZu=xmcX$`03$X3F3@^S5^t4#-S4{3yPwmyPK?Sk#CoN@!@AtDE67HQ z9LbQZ<2NwN|3A5A34DocXZv(L6tLE+;dJhB>3_<#qj$<(?oW@T`@lzi;O(sc^UUiY z|2Fm`SyAlr#t2(F30N;&v)(Vu`j3Hzwy|OunaaCn_N5sIi1xRckob~0Z5GR-@84m& zu$;I?npLwgrO$|d)%ToX{gLn9OjwV=_{jW?pxCW5d4;$Gh_M7Yt)jtINuz9 zqVkEldW>6+o8@0#=(l#7fzT}k*pCE^owmV{YI(f<1YSJQk#*;MCO)Yx*#q}sVswA0i)#Nl2+7f zI2WN^K70KwVfI8mvH3!GgF9Tn2tRlhHbm&fUBCuHGZ?W9mfj7$gX@+~WF8ULT(KSM zW+k$=rv~8ricimJk&l%~2jozIHSP1%6KZQA_7+)zv@^8!sb5xzG9h4E8reGH}0ALM?P(D&v7OR-hfQ5C1?nw$WU#K=pTpPW6 zxL8)5xTx^G1@;&Jea}e1Dy1`l|GC8Eyi~6oD87DRtLwEtQ&M^VKOY?t{r6($L1@jA zwL^yserfDilLXQL3gc}X5^zBs4Ospo-6<9%X1U zDif*43dOS20zLA-?nv=Aya>C3(1zM)*<9a?%h!kbs;IdCKjXl2ise1{^4YS{hrHzh z@$%LaG`!}25YvC^ZKr{|V>xmW;<{e1zCg%3U;+>4(>p4I)shed3Bvw5%(6fl&olEi zENs3;=Vv*PZcwTJ^AoIKS^FTdY~z|r%oB*HAZYj>;~??ZUl$m0d52~8@e}cgFBbqf zL0V@i1i<{o+E_2k{69_@I|Y$&CT3$@ z04?TUJwa~`1)xAScPL(w==hn;3~U==Nc)eqi(nd|5AYYtx-5QsNa6vXXuAskar6tg zNPjr2J@U$KR2XO+fONlX@5CU~%u{gi|3#+%-@n$?(r}c2M6}~!JO5&R?5I@_Yr&vX z@W~fn{?~QjHef9$d{y~>e2Z2|{gHx*JB$w)nsIoaV-jN(t*&=l9Eh-~Au+ z`sWi}pRPo@MxAWM16Ge}6xW_TyBhD>{x9M*S((9S;q>5N?}7m!qP1Azu8+#uco;p` z>1p698vHPY<1`r8rdSX@DHYS#Q>iak#c0xon%Jo`VFUrKe8|<8%ROI>ou@yZr4-L9 z`hCe~!~pO&GU8w?hW~@}K8s5^E>nAjNE@cmc6mFTwraPn#=aWUlp08Lc3PlE0g#}8 zn(?N+_Z!`;8mpOh9`kWHcTQ5M4kEp9a`Z22fL3POjIyRphY5EdADzwaA8mmTd}#B& zj=N*O1O9KS^_R!<7XUkA@raDcCK5ui9GS8pQ2d_@{l@^1ZjY3T$pbtH?*0_tWR*s# zHpJ(3dNeEj|BCjyxRh75z{8bRJkrzyQ_8jLa91%f23y1ZZybV2fn$N$CXw#(uJ*lX zXynWqK>P>HZU9Oc)Kv>&WG`6bzWx5)e0%}#k&NNAu}1$_XkK{;RHFP5GQ;J+)jG}^ z{rx`X-@LISf%sF+?~ysT@A|}xy@#ImS498h3YY{tSI(WFb{C&MCO6~E^uI4bJHJD) zN_Ta$V|jhppBe%o?tk?0k9qIt*MNn(%I|sT^ki<0_eJ#X0$Dj?*xk`E2s$Ak7{8N2 za%H;1OnApn>}k&CvceGbkyiCD`V~O=02a zX&{_-OblG+&s!ATCVieX`Wb^Aq1#INA7AiaRPHmpNrC+kHv-sL+nl7wwJ)k}d&5U$ zKk0#MR(ORNOd~MY$iu{WT^Z94Cq->@jIrI$6gX941!+#mI-XOW{#k0LBKg~{cLi(= zd#Aei^+8x>lQ`KD+1~O0obam~E?~W(t(mxPb?C7E-M}qf;`v+uA%kle+Ie2O1`J(f+ncT2bi=#SPQHmHY0-{2@%X5Ey@4q zs~G)pCyK7`PfJxU`0EqYs+x(^Yn<@w-*U+DrqoB_>^u{u08km76pun-h+#}&|5!}% za*aVNy_>>9KY~V#08?iGYb;2@o9cl(OyyQZ?lNN3siCzo^)kAQ@9<{}wj0cw;IKP@ z9(U$Pwq-JPcX8BiSaowI()qF;HWjJx8$Ik6{Xs0;G8ShtB3n~Rm`N8&eOz$V}$7h-HoWcNhu@rWPbJS z`)PefJG%{zd||X|4FYKKCKGEQ+6Q*7b}AD?n^p2;9{y6u_2^2El~dOndpR5&%+Lxtpkxh!0C*(k zm8}3%dSoUnOpCbEzPC}$2a9!A@c1OEwDawEhtfDQY+?Oo(}l!oPqdA}1$!^Jf7N!o zNFa9e$!0EGKhE}L-=Sk`OGNI6a1^|Y9qlg8Q`4z8DbtvLZ^H>{X|LAVluFLzO>V$e zx(5CVK=okB31^?RFvIhRbFTtE(|YGw1?j)N^EB0D+uo2R%{Oqz^CtzM-lvdm-DHSW zD7I0r-KO+Mf@BN}OjIDINLJEU!9vw|kr3bFeA^3do45OQ352lIiJ*pIH*5@G%!Km3 zK%p6<3`U`i%Gt@4OR|O)d%*aiMu!7}nr&1#!P$wKt#QC+Ts4_9ebSoAg^eAXMEkvq zGP(pwu=erHj$158!D}9;>0OLFmox?&1B0BnABM;~TQZn_6b>#!`ZqL4 z$C5R_MPttzt7KT~dh^v;p=b)NXrwJ7(Cg56DnFRUQ%FjU-acq@-r+10(&goA*7N^} zE|~)~w^836Qjxs9Z2gl=e(noXvo!+UFXvFpptbXDzBE$>s??bZY=4+lhiawv_e1mT z?aH6@@}1t2#$bB;Yt$xSe{!-^HMr+MD#Yqt(nIaAf#QX_f4Q%7VG8TAVCEUOnfp#X zHPfpgDzE6&sX2F;rG=Oz_VxD-@uu1Bl*)1+r2z%mnM-=`i5Vyhripv-;9;VM4iy7N zVm}g}M~{@R=Tu!;%s2LT73fWKc3G%MU4?rGBT4YhOWP5(yq7CEScUu%&q_776*Yfu zT9&Uny&F8#4q(R9r(yn!-u8G@nN;?uq;1FdXMXRFjKywcyTq9-^}9TRKNujHFHoZ} z$Bf)8o0Ueu2w><;;W>WF)dckeaOd#*_xP8X76}= zAG^?^@Qbq9wic-zi%!Glmx%s=DM1I?e(e=K6^!XJ6~3@}ciMCR|51kt?7}kdlX^=~ z?jOwYa*BABumDlK}D$tzU9AXxE1 zcQr-fQd&O05c#)O#N4HGGu%uOWBV~RpX2G^Qh0eWpW%^51vX);%kd&km-#{#$+{T8 zou#P11pd2YTzzPy!^ge zAtDj2$U1s;4~~5AEpGKR0K z;3ZJjg!(;M1%~nO+&~ELB3W(u(JS9HJq|ubjOTrur0tb(&He%Yh)R`-IR4`)L?izO zJ=Dd0G4-MB(a{Yj+~ns|;;p<#XB`TNXr^bcAwaeqbx=Ax{b4wVec(m0^pVcixWdQV7%LZa}#jt<}O_MuwhT_ zyFBH}vSvL2gdL`|SY>3AIU788RePq@?1}!{DDP5F4MYtHM+Q;U|C4513xq~@d1)FA zqIa_CnhEvnjdrm*Bje*G?2QF6y^paK8bIkFRqMd52BWaw0#~S%+S*1fNC;iuD|rVl z8DLvxg{rPXFI2|$^Iu5+8!oa+J36KNnE6j)GbUQSNvCa}tm2<5K5zW78PqN~(BPlH zvm#6EQ*K=N&cq}f541mU5hT27s)L}AEOY(v5fhPC@Db1guSXK`|IX-xQ@tu}HSGgY zA8DJ>$`cHw?9#dW61iFjFtbOJesvH(_g2ODCMj*;s65dq8w3CYP(0^|khc8QWyJhv zSmOU!Z-x-h@NV+Wix|g}R=2|+pRb)n@{LzjTb3I~Axm@BmdUTYO>#R1J!BxR^%bOKZ>ntSf5BTwh^N)zl(tbs+J=p1WvT5 z|7#rPKL8Gl-?m}b$3dji&xxx5@zHx%ORFwBJ-HtLjk$RJTNJqFG>aoThAH+Yk<=f9 z{oRIq|IZkDg%Ve+SqiD^GK*5>S;;{@jJ4$IOu}aw{{GDYp{gBCec1k!_L26kNxS`g ze6fQNpI>!XGC2-T15EBC&8a0KED@~VE;$z0{wLj(+P5Bw-y$qKY@^11^kj1UKY2-G zos)nxpj9_x-v{k^A=eWU`rrOz5&x5(lJ-^>5k}nz;;u=!!%|_S!%5`7DDTIJeURkgY(b>-uxblb1Yv+T1mK2a z9V$EQak(@3e^aVSB%HDgJ@Hv@@bGeejge^lZ&FNQLk7bQoe@wNvDv?=FYIt^Z@91f zUL;yC^4b4PviRJ*@(7lA({+K^@VfPXQ*bad1tKR6N1e}$p9*8WDaGS@)tw~IM^Ag+|3`~OGQHBN>ya}Yx{9h~(s{;%5 z0tBlQW4gd!$E#1jg!w7|tOXJr%%6|$v3XI8^RM6l@|0OhzdAOI_zVXUSmTBsP!#ZC-}|FfC%@8@G;ZP%!w z&P}vbcbEO1PY?n?XJWKPh=T$nigR_#jK&__Z$?1EItD;M6>O55tMk*lW0Kkr5CK?gG z#V$jcal_~3Ln^v10^KszHnXQ$*7?>(ky8gC3~Bg%2-lpsqYS_l08qm#ZP!X_e;4q2 z4m1oVz#(Ezsq6=hX}nu=_#Oz>l^dhhg;Eo| zBG`t#$R_O+PH=xy=^ms%1G9`Oc&2l1;S0~W31FB|&X>Wi{aOJCcIZ=^@<&h$=8ep$ zPs+|~G)m$$h0bzQaOE&NoAmW?w4|-%?>ds~{d}wR^tw@jbHYWTD}S-D+Tm>aO3tqM zd9uILZ4W|FvJe2}q0t{b7x7tN-FJ@?8sIq^rP|Y&_Qi3dW}00foh2otEo99kY5coENNY%Q%Ql42zkExD zi3XD11l!sx-uF(M_R1|K-$%=1+sbCt)~Vnw7c=S}&3yyxw3kl@%(TeDsVGl}y;Q)H zeHY;P6FIM*&&@z=wZ9AG2WUM;4|)=|3oRGF=c~67c5nw$e-dhc(bA+y4h-{~fqeyN zZ$0PH>lIkFj>@6mzy`_}G~)clmGGn;l+vmfTZS2>-A-=&PmT)ehpa0`f_Q}F^NHyZ ztB?#&HApk(Zi&mndX{BqqaJOSR)-pkXycsMchH6N%8#;l?o>Jw&ZaA*)e95Ruu8^7 zFn8)4dGG-gHF{F3T{}J_XZx^zbItpf)6LK#u&613Ad#Bf9WK=*Kor*V6I(JWbn})> z>Jo-jdMkONQO)J+WWb}OY_T-`uDw1kg6OQBjoFrE%+D#>tJH}58B3%2eWt)IVz}V3 zHISOv*&4K=PlJ0eb)O6AbD5>{p+%k0Ps;flB4TV;TAi8xr>KZ{REqNR=CA7CDt93| z)+bj}YybbNi;RU@^A?t)e{w6R&BU#mi*zye-H<@9d=KCU1p(6gLJMxTZ<=+p!JlOWlUD9Hk=u^y_Ye64Y~_E}!6j@SuoQ{^@520K;x2Q{4hwAU-U(e0C4N7VtPB zcW1a|GXYTf%Nx{qm`uabvY4L{M5TRZIU+OM#3x#4pn0hA`xowQB@1@<3`xpm*0KD#^QKkuq$u5CyR|A+fC_$vjEw(PS`*0N z-pt1EqA<@WpuaARO>m>7$xa7Lc^Awnp|2kxApIC%?kWw7b+T-LOgFD;DDL@aW$vk3 z#k@3f+wY*l%_#p zN-ow4V=*rOv^n@LwmDDa5R-G-HSnC^3kcFX4d#&l1-vq7N>+a|NIg*cjw)h-)KuW| z^#jJ8CDe8tgIO{Sl_=-V)BUtP6rV;?DPLf_kO5bk7#@&zo@(=~oHd5RW zP&@?5p=62uFXFAv{74kQ}s0p^1OfIU|!&{TX;q)c1-Jpz_> z^wm0{56VgR&m6pg8ePQ8Uat~bpgB9F(7wx!w;0*^dA%Gu;*~qXjqqcFT=J+3Fo)4NjEv% zbmveE_%havgJ+}=^i`;n{8M9BaVHsc!x#J$)XKs&YYKdlA z$${}SkdZY3#6Q-qpV)V#DVOEjP6dGx_TUN^9HQ}}iulb1aKvD~ZvY)AD219$n#Tth zw}!i9f*}Q-Lq--O5ga@T3IUw?kgQ-5UwEy9O?}*JJ1bpY4DEa?ki4Z^`!!9vH9FUGSIP?SaY5DfHC+hxK+E9WgmJg6G22j%W? z5Q%`$kqKa0?x`M)?8aOEHgq52jy8?`L7|s)stGZ z5ds+j@FJ~Xvwge*U$_HIPpANOwN^#I1jGMUG7=O{sNmI%S?s-y50nZYX`&Wa#qiqf z(g67=J7NNKm!7Fx0+Ol6imymI#7k;+uNWDJ8We~-aO719%jJHc_@H{ zU~?QpLcn4m1O|hssD43ILd0JkU?+kZT%~~LAN(Il z5(rKEZy77bjKzXNB(Q&@X}~m-LSDxc2IRdcsS%BPKaGP*X&2qukLwx#X$Gn!#_(JW zEw~Fz0OaHRjgdqJtVcOvx4zlD*_JU}a|vPJfN4=|KXyWZ{Yq5Nw|GVG-_I{jUsqH( zaYk1OA9aK0>8X7Q$7{C~FYgtyBNuD8c>mL(f;`t+-?-ZeyOzLqKjK$!`m=?RQqObQ z!-n91!tgKPobi01I+2QiU#=wtUD}hi8-cFUX?!H|~G|0OcVJzb$+8TdgxqdHg@wuOGnv1!t1E;MoC4q0FLm=y_|UDVk`~ zY3Ih5Al1tF$c&DRlxlwtg+;2f$f1fhfXTuBwJB1O_;a4}OT)p(WldqCi0QA5CQ5CD zk<;OXDp|}`lmS=+OVAOG`*2WHjEf{K$}c^*BS@1{;s(@2fb#>E6gHj2OB!+N>N6Ch z7aer!PjZ{=)>IB@SQLf=OzG<5+W}HN4N}ftbyd!KJ+K^61PpK5T}BQcjRvsNt1>BW z!+Qk-u3!Zs4jE(scc784HtuK(hM(i(JwG(2jLPz7IqG%eyZIZyxDOLo(e<^q8}L2c zXDgm_1snvgW5dx^Tl^&kh|ynyfiCW~@LLLtB7{{o|1uc_So|7H4c7n?mT5SfIvG~T2g>|>wOi-{-VkBybeb= zq3$*8vEg|Fr}6;`W7UQhtPLgw%MAe+N(!l7Cd_AHv!gU&k-URBoR3s5H9N`hZRyr` zX${o;`zDhTy6aEYfE9vms^`{~PhxO%Fv9uubkFbUP>T*>xm87ehE^qD3*o=|6)U=? z29@y7hYf*E0p9^T(0lam)Ihb|y%LS{5WF}Igw*Q%th@ISA6I&G-hNayIJ$2FT2zpER{TwhJQwiI3Ez| zS${Sr(RzKQVX*Uivz@6F0zkI7V_m726(2V~(_H1?nIn(KzT!Ey{^>U>A zpj7Mv0=~M&S`HOoSa^xiI%Lw@?2wYH(yWj{Ka$ z*UP-XfQ!e3)5sF8e|&?8ijtOa>qXPx3If%60nLZ2D3MahtDSaA_j?XMKnkd=l zyJ%u+-^Co8)F!J2;jE(nHS9P2ELYk(n>=AM){$j`ex{@YUzz<3!JY#e`fGA=$=Lu+c&JLCAS9eGZ%7K*h{b1N$OtgT}W0?PE zFcs{CF8>XnPEikPLb$Q=xdibGy?=;$D=@*cbg^Fk;27Fplc2hwsC=}`FM-1g1DG)I zR?8$hNowlJ@h%2D9>7xn z@KF}_l+NKn6jv+2VfaMp=rCl3q`_$c{E(>gcA7IGs;f&m>cCp_zh9gog};b-Nc6V& zWdOi(&I9RLos6i%+;KF_Y?{LZt%}%dyFJGRlGN-@04@QC5&6--nu~!Bmco}G0c}@c z=BBz!$Hp1sI9pJSyz@;3ETelhHe4_2Aii0uV-BxN2Q~{e1XLLh#VBV(4bDLO?G-mj z58@scTWTD2_A(EwG1JDMaIWE*%L{(Q4yB<$Ys+>EDCPS!pjb!S4U~FX;tqG;3$5c|!|X4799W(P#r-W}w_~8WD&baGd;Dq$xTMUW zRbfwX;vjJFpWaOrk6Lji%uOeXp?$bnEwJCiWfp*B=Aly);=N^Jc;D5m|h3D@5}lV zaY|N3e!#yw)c%NxCCt0hvEbQ&XHwA$lM zZQ+3C0wU#n#YM%N@V?5bq)&0Ki`k*hc@ZYyz$m;o1*0`DGP!_!&THf~{lmcULmnBS z-D~-PwCsaZDanZdwlT^BJOnEwJMnxqRSIbM@C@l~(Fa0H2bcb1aylOx2Uah>;OACJ zF^x_;6QoxkI`eQ1ENEIdnmx=k(f8r9k852@1NQe{GUO8D@M}_P5$cyMw}vEn@O9!e z`L||HXUv8c@okbqx|d*I=df2S-u%AfH#L!o(x=38N~ZokAYAcxj4ap~Y{SyZv4<$K z_EVnvlbGRkKG$iD9s$UxxrSd2e=lt3q*5dLcIAho&5pOjtG2)$n)auWRhMTHOxr(o z+>f018k9-zmJkVYqvheT^0z5i^w!)C8~kbP`|I$f2jKbL-f?`Qg5sZjlXSHx%KYoE zg%;f94SY;hczeZ&Q++P)L9FG zR7ZZuWlM&Za6wt0GWK_5X;y(HbGdIBYe)vPa?&cruqx}J?txTP z-Y(@1ldx2SwBBznP>t)iHeVK?WzGsh z7II|78youj5k?`%0J2gJ~iUHQa$X zV}7GtJL=1umh_~0-Qv7kT2!F*ziDh^(Q?1JD3H=_TPzE=?+LV*Dc!Whb2Ds7M0Z=Eh$Omv}a1S ztHmFEO8#7g&kEdO|9aEe5X#~{U~%}FJ4=hm!O=jhD@f^T-QIyT`5X5@4T7}KSwj^( zPeO8Gq@mT1dj)cH{_ZA-2&tOf@3;jWQLgx*MIBLKpfjPb9gLT|)833f2YNR58*1Le z_?t9Lw)lL#N%=LT%1L0K)b%&GlDkVxAy2pHZGCr$@@ji3g)$fawa_TNU1NGa?$(FD z0vOf#HL`Mj`c}7Fl0R$VG&I(fO1*xTB#ZPE><{-`_H(-gPX!Q>nQEMhGj0@XQg(8j zy0Q>~);J&g_LBY2EY0xj#^%D)T-UoU>$|6XdwkmslQn%Qd%73oHKNYQk5zheqom+%$WhIgYtW`adzKVcC9mz{HdEnYU2=)mgs3 zE-@$2k&8FE_jpG#wQx!Xy>2$DD{;^MBI{LqIC3_?InVM%y8X)ZIn(z$o3WCa8L`65<4?C9UF4a=%jEDGF!K$%Uisi4;$Kpim_F$VmgeSO znvk9Bs6v@tI6AquhSPQ=nKkp=V6M%Ry8|H2zXvs5X}YTM*1lxmO@US;d!{|!C^6P2 zfOk*cW2w%{2@p-DUT~gVu2uF}^k&1H$1IjB7$*B&1CL}#>}d;@m93lhPFW=t7O0$j z-{~m4+aTjrDL9)R=U%z!KIP*kuFY^LH`@xTWACUkoOQ38?lHY^s1g3#20Vd4u-AO1 zXZ)~OOu5gP@2M2vHwu2eB41*^f0Dsre0(d(%I_qY1Hd_nn_s*@d?nO>k39krZ5YRE zUGTBxC2RIOQWIqJr$C_m8p^A20GZV+bZ9z#G@L@=Mc6aj0)k`%c{6+>=<)mThKc(7% zMFGW!E*AE?I5`|lCewJZV$)odwO&`)jICjN47BPeZ(s3`)zi)QvfnawZ^78b*y+}1 zgwT>4KZya26W-Fes_kP7IwEnHC7jIqfa> zhmHu@EyJN#ajZ5va_8o2 zCbit34gb85r0&!b2)zv_JXTZ>%QDS*Ash6f=Dn2)34mY$2+}JCh@b^G_^*ta@3L43 zOy4iPSSqi_1M!}a+u@e2rCaf40}>hNJH(DweD!Eb?N?udJA`IAfn-?y<}-jbe$ACq z4Bubdxk=6}e;_}rr*eAj7P;bKT2i~yj~&nHpV;?BrW6SM{qvCpQIimeTd4V^Gra%< zRdES>ZUxjBu96tcSt$V>E-{wVYikF#EFa={YqX+R!HWTg^r6Q4rdLD}ONYLec@~fA zEI!b(Mq|5}fZG5{`1@%e#dH z0sK+khmN{Z0El8ieFQC{0#HMh`TPU8aXMU?aQhQeiX(H5J&g9ubj7MLEabgmSp0Il z!rxfZKY`bk+HaCGNsYAzjUK(F#E#9*M`S!oQ60`s2)ke7zK;YMSMLty!@q?wa-wiy z%;z2{pS%)bFDZ<_ATy~-Eu<6R z3wh;$8BlQ^OI1Z_c#5`j8OwCyicZ#0c2%NKQ}2@Pkc*$H$C)n_u8v?!(SW*wAKGo7 zNui?$nC3VKUrJGAaxUJJg&$z*6*^%d0i(yU4$LVKW*mD?jq3F$W4R38;JfR&;I>HwRCgLAfd zR+C>SI(LpN;Pj`4W}u)Y8I&4{vz^2HwqcX9;>B>6g{m|0(o>qU2h4Th0M+{yhivI=9}GX>_7NssboA1|R}FiMuo8O_~u zm=*9il;Ysab|!kes&fOe*VqEOjafe&T{I~`jlj{cLPDXjQ8xne!}=fBD;$PW8E?{g zZHqrnR|~&&C)x4^W*kizgjIMLe zyk;k1H8&4mJN%?LPQHCtYwRv*uh{puFS<_xcsRtbZQqZKR*=W(ROzx~^nNlg&LcsE zZ(BDrzh}tfWj0BSq5kj6!|nI+D}7YQNLLIKcnnHQk)RnaQhIo!|LM!b!}t<$Z6aR# z+M<`y;5DJ{se^v)!u=uN=~Ymk0R%M8Bf;Ba2jOu*UPn-#rBhpRXWKeF({QnLZKKcQ zM16P5+mlnf@&1q<@iFL|al15ApZgC?z}7l{&vRJA*;kKv=ygeRpcXP%uMOLQ#OUIr z1O>u_2GN_hgKDho&t8<4hu{e`sgq^q(?-633sn7o|9ISOt%%pZvK?9?+-OHe+RyrH zDP9!6BsKR6!*T<>MFK;{F;$-hkQmRIKC0|I?|6TraxM+&gHCqp0XkIEWkLba(A_qE zs6Bf%4>1NKtb%2kGrES+R$Ow5H%!*N-_D+{6k0>^%2x>qcF`xuNrdFRG8jDg2n@n z*Jpy=q{xQ8p{-cr!q+DmpWh)P&+w^J@Gjp_nbKFm)fc2Ev6^&$kkWN7l2TR`R>6Zu zPlQ6j%S4|JrZ#ppwFm(m9C7Zu?m3Tsjy%OyytTOel&i0Lofoc6Iux6=v`uA}Lw(Kh z3*v^dm>Y5~N0J7_nu~|?t%2*-F@&p%%*JORiOGGPsvZKK``%3x%#*Ee;mN){XC(#r zb(|_dxkBaPh$3xQ4i-hizPrzRUf4#JnX#787;oq|v&))w2IZFz9F8~0Wp|R``3;`JoPjlh8R(b{KFZ>)s z907f}WjQ^IAMnEx_Oo2f?+kskr5L4>)`U0;zSXnp1DqG`YYDq_P~}LpBRCslUW)A+ zDkM%AsLvhlE3^O6TchGp&bn>tWnMb}9+4IUL@j1w9A$PDMaCo^X%W~1h4hd5sHVDy zmEpWm7WZpNZ!U;i{4SYnZaBeo2&g8X2e+$98&)1&vY5QlXs+F3b%Ny^`GF_A2Ro) z_F%Vp_341^ff@PoGD!${dC~SQvo@###?+D}hJ$M?M(xsCxuZ=Hd0@8wDSu?7F_*Ah zv*El!XBb~_{T_XzT1P0(KHQGzc%du&lrZ6f58h{JPU!{3($+6)62L1DQH0P^(}Y-t z2RylW?oV5}+Jw-05B-pt_6jUkbWtAu{krtGeaP<{&4elQ>Tt!L?eohvc9e|NvKO@*boj$~dAtA1=X&t%>u zoGE2$V}Z1o^Nyh2vE_Lv>kuVQCoW8W+4?YENt8dglvHi~6E+fixJ}pGJ zQ!Kv$Z~vf`^fVpB2q`m~v{s_BZX{zJv25SRa}E_}3p8IA9#-lv_KY3`z3RDfPscU^KtJas>$DNXwle2xv7Ek7{v|xAnZ`7mIIO@^)52;}SiQyuM)Ic;PG`w1= z^+AM=Kx-S9^7|&IQTStzg?MPtCt^lg+U*nG1$9&}`lgx>6u-Jg zVnb5<1=WIrNFX|rVS4Vh$qJN><0=)H}xFmW_?{f%cTwPY!M_UvznSYCX*pfvor`3fvlntl5hzeut7rYGz{yJnL zxLNpkO;?!F6n_$G(Zt~%e#v>GwR=HFmdK|^Q}-Jct|1l^?J(C%?^_P_ZncP@RJ;`;q@5=EVMI(6K_M3ciXAVB`{^&f?k zI~#{-8s6+A(6fT5>cxulb6%=-mrbFVzm@LQ?Qzbf>z$OE6@%-uoaENf@LqC(fwk$R zsDW3vb@rMu&och{c*>x;WUJ$p!^i|Fq<)_WYI5kUKxLgzeqo%u*= z8k}bY5Xy^g`n|Y=#bO=Mzca1^UQA^E^uBfVhn^8MrvtvfV=Ev_@kUAH8Zx}uzZ(Bg zpInp#dJ|!4!2$KS%%mF<0lYxDy?SskbU9ULWo&;HLzo~$5PUU!M#h<;L2oAQ4ZauN zQ%fZIFG@QFqs&jaI4}`0(;XQfwUylAqx3126|Dt~Twye0nIcZ_lg&_hkA8fCBbM;N zopOI;4b-+pRMcDd%(+{toxP|)f&Zus(Q`bEml3^l_ezx2!)jrYXUdqXXCV!(SGr{D zZ&F-TFnr$LQt+%b3q!6O*@1PB=m?hv>CNb?G?l6{9VcZ)i1Z}2#of?B;=JXjAPTCc zv(Qk%0G6F(_?J0t1U0jZB-YoDbl=wG@cZGMS{C&B`{`1c*z^qCJ2y|E<<7D-j-Ny`Rr zA6T!vMB|!E-jQJtn3R=2xR(oF)s&c`8SE{iPRc66s_tdM6m5>*OM=z>5U6zm%UXPH zjUc-0ML$0-M8XJaTp?GBrpD*zGF0f@OLs(Q9WD8xQ=vv%R`2}_=*uaVeWp68iySBf zP+RXWhP@{<8B#cWa-y>$+_q585L(>+-qZN{1Gw7Fum8el_Ai-*vK~n#f zwS$+3wpJa(#-u%OUCquoIzwmeyaz>GCr0(AQi<<*`gB`xZWCe1h&u1KSM8YUAGRjG z_<4<}vA#iwWR$NkpKjXzu#JRXH!okdu!>(`5Jtpw3w}9%f0=5tiM$R4COfw(Mf$Y0wXc+) z%zt;5I`YwXhYv=S7!pIM!00n*7oMuC8%7TKHu_If1(+c{r{dWMOtpPOE4AEJV+TMGI~4Ekh~h z_iGyg&2S}ac5AO znJewV?=j%^)~I}LW3^khwrDv=OQ=OkKb`-_v7ZUi`}Cf=!j|n#VAskETj07vM{$F@ zd7*=Pi(4NF)hD_WIWva)PhN*uH);3rea42k=ywUSo7k$^)ap%bKMCWzOQ36WP)uJ`JsyaxyGS5#E$goh0#N-l=0oV?(+r_?z~EghoisVEoQ!F9fhp!@b` zBV{+N;8kd*Ac3y-;O5Zy`Z1{_{ovpr$%q*y*x{bop5lJSu!GCVGmcy)%vTCbbJMd_ohS9+e$*kJ=# zi}PTlW9>TVAmqBIy}O?H@yhujD9Z}r+e--TnWDg*)pa0abl<>coe3NS#oS!%;1sLz zCwib)v3+&uIa`~b8TA>>-Zd%or-K5vPJ48EGhv|KCx}9Pkf!MNYrCFL5C#};?PjW& z$!R*){DWYDemjkYPosJqU+xyUV@w4vzgcipwdNIZRo3YKU_IqON^OFM63Y63tmsEIxDD=6SRK+v^w62rwIt+>axbm3Y~{+wZ>{GU zR!FFYDW;dx*f&7UO>7Xw`QVT%tDD9#Ngwv5z;cYl@*jF`J?vtCAE+R%LfOPdE?zm2 zTo8ZIla$WA_{Cu&l^QHUGlUVl4uQk;(YSGBqSaKbx|fKhy+Os!4pnO#viHJ1fG6A} zIb12l-=~;IW;=O${=Ag4E+dRXGe&`6Q(Bvo@_AbH<7`3>wbHVb#k0woxN4ytjaqCg zGxOw+_Hv5|zIu+O>#+&(Y1AgFv*}TP)h-!<@2)oVo-{{(bV3(@M~{lTrwLScj8@qY zkH2PrWly#k2TgRMdObvG3EMol?Ex{uY=RcRaSWu#!Q+~`kPJVE2ojNy)rYz^PSL>7OX(EazY0x zkh|Lw+C9%Sd^*1U=YX&3NP_pRpnb<7)V_a16-=Btc!tuWIhI4}3 zBN`#Z;B2SFD62A-NpkrH<_MbCHOzh^5q{@$3&TvZ|zcEU~hG5kOl<4vLvC#GawyQ92Ko*;H*9APv(9Lh!BQu5s$!WL< zw5)=0e~ffhI?T;@9%8ugE0hn5<9SR9mVbbQGVa${gFnv>n??$G@eb39p~It2g^ze! zsW{EM3{m0kX%sKNvCzLZe#V-#!5z`hU{oVmD2Jl9yqe& z4dZSME&G?I`nOB>ixgGKx%P2LGm&8IPyEesT*$o{3&l61=Z4)*alsqvemuVo((w_F zcGugcitbE4t>R(4x^{7l`vbzYiK%P1)3l!LV9c7p0hQSrPsOrNcW3j@oWe$LwF_RD z>pMf>>)R8TIn~juXsO zmMFq|XKk0_x25JG%Y_RvheVLLIW$nX&yzouV3z)xI6Xpvby3*q0bvFE!0P!qTc3M_ z3@J~;$h@}_{L9K7IS&Uat*qedr3YU0DHDC8Br2X1qHJelHLBvM#!~Y&E7gE=~{s3N3SFLL?B8BNn-lp2T?eOV6^3BF2PSBO09ug2xx#3 z146$bRmRA0=Cb9&XZ-W0c{DrEP0Gn(=vQsEgnBzk@}U}C)OT+=voty??yoO`$-Hl- zN$(;xbcw7Ov)Ibcl5lejwx8}@31lcxSm$e|*u0o8X^LXurNRtS$*|yrbfq;A6Hk2fJ2VXuR!MCaU}j!+~GVF##7%DS4O_SG0#Q z(-J<6OuIO1WrUI_jU#Z#MSVB|Ufat?;c0>tvkoWHD)?hnHL??`M13n(y;V=Mx40QK)-A^f_XCSS9 zWUsQn@ozz@aE8N%#xta7P z=#L;wM@f(0*2+WXE^lP)uhepFoq+BQpt7*VcyQuRHyjk@;@2#Q7Y{7R7dOh}b(ZkT zNLD)Ddv($?FFh|By*|sAv-DBSScfiUj06)5C;bznLsB?RLbudRMN@v}Ev4k_9=SFM zx_=$9`pVnYu1?EUP1J5 zC%v6+{3gLr(9eyPq;1%C)lP^!yGD$jEB6kaR5F!@qPx;f*X)R*w^?1x9E5d-a2xcV~<4_)rf<< zBYL4CmRGaPw)@j7|2x&0CZA4E5azvFbP_!K6i5JBSY2*#XbgX&?2Q}V zL1YYcuJC+;opat0=hzCx#KiN}Bc9mq6-#mSod6L$IWIo*!cB`Nh>ninZQ@8+g6McT z7L|LC=Q-UxmvFrj^6gF5K64>*5>gMq?C*eb>hK^m2PJ=w{#2<)GGThy%QFmo=}&>n z^h{CZ!B-6_ksyYzxR=*CjJ9a_oU{pJXBmQ~`Wz8iwxOgD7iq=Lwpsu^0VMLL6>SFh z7jJnr!G3S((W?Qxp!L6hb*6>?`Z=T{s4ZJ1m!R%^u7MW?AfFW*w_QfBV0s8lOrplf&cWtnVN4c4J^$k87@P+q&h zw3SrnKT$rY#bMB!#dMmpNzzKmBiBa{Fpt9vK zFmP00z?bTs<^j=v%hK5yVrTS4qrm8M&B5YiIG-n3?s-$1>$4iRRkAb$%QyyeIAnr9 z+>~ZMJDHT$`k0E+l4x-w=E-%L4fh||A1k7DKx^`7+JNH%(82Dk78;kka1GS;bH0tAR>&YGb1ZYj7jV^KrD~-H#UyU>7`dt)DLw)zq z972T-!X6~#7zvP8G|65}mdw&D19U0KbhkAzp{5B{&-#+!aE;e0m5vz97TD3vH!9n4 z5(URCu;LMokVz9{?hMitbc=8>_~S_kfH?E(m*mHC&UGF8k2bA3)LF#n(G|5&HXWjILmMyo_4`#&ia?uw#vO1pM`+MAZO%z3l_jHTdIeDMrwmZ zT4K}L)AOTP3Yk_O}ayeHTr-hYa%Ygp0%}HNgoZgBPC|*ETlIg`upnyxyefc?57`n_;=Xt z41C*Q2I*LXoPxN=$GUWs+o47nK}}hqg2q}Us5di6ekY#%WjNQvg%u-_-ph*eYk5;k z-+1j%6k8G=+k`%LkbRPurr{g*n|Fjwn_?hc05?P-Fk~IB zAezpoqrjq;q5F+=vdCmEtXmMdrslKI75L__eid>ayS0SXw75TpqP4xkSlofyyuWoO zvYDb8`np>6mGs7w9fJpS5RpkKnaS)^*yd9%)$RQug1&!#8E63prIl zFS5Itt4R10E?n6AiuxLk zptka-D|e>>ZL#)~U}RJ1?LN>+S1<0k3?;2!=BeRa$`bt1PNMmzhx=ybsK9BrP?2XL zk~nxiba+>*5@Hf^-nKAE)+d7u;OqUmquZ=SMm25DZK-oopNJY{2R0J5?s`ySW}IAi zDvU*&D&Aby5M+DI0wA^3B~Ex!Znd^3WAf{9Ed0Q20!(gki)gz2unz4jK}EHN;UgRD zpWv=h8erG`Ru3XG6<(nclV?f3UDQ0JS*tWH8njnNNyWjSh|Qp@g1ko{H>UfEvqOj~ z#Gcl9A$PIimtDRs-M$bd=936!2tUa z$d0LFglI9}$x<{F`L3RdTKX{MZRRer>A$Xf9ZHRXnq^(P^KWg=wpJhqJg61Y$X$k) zJ2YnJa`B1iMYZzW+r4w2p+&1Y6JVpqtwI=Z`Nft9wSNL+$9-%mc{S{wXK>@C7SIdO zn_$n0JK#-^-ClJQT$qDuW9paS(fdc^{EI7{_)Z0n@Mvy9|1Nr3SVV%Enf4egTeJPW zTem`W!QJn6as`6=3u^JtPVoNV)=fv^|BtP&42Wv`-abPKDpJydh=58+2`D+JgaQgk zNO!k%&ZwX?7=$397<6|yh=kG&k_t-0fTYCCyU*aQ-~at`KU|q}&fa_Fv!1m!JXnf# z`~GvyQYqo@;pRlHr$2&|sfRd>tK}}5iQFIQpl$%L|H%>PvW%F*IrP)ggTCxM9hVZJ zSJ+@gcPq(UZVzpym{ZHpGx)%2x_UV zrJ(Jnj*f^qojl4XJB}W;DL#-G{;mBzH(c*Z zv8@^|@t#zoJDm~4$m}wb`lMnBaw1hfbHnL^n`r3km7ZvOCOx^GH`6~&CO7u;;wb75 z-bign<0BZvvW!J>ZJvS!+qlNt!=?~z44kqt5u_u@~Ki@(u zBtf)3XDhHC?S^+|LNsU6FoBCMAJxYxbKYPzhcbdaj2GN8BSPs(PEIE>>9sQ1SrNI) zeYxF?WLbLvTrje>RPJJ&&6?@^kRgfFb{#Nd% zGEbofi&ffxg!bui@{u9=)?z@7>rgzN)?mF}8@Wt`_Ywh_>oq9KA!qaMy|sW6&bo9j z0uu+W37FbYy+8@+4!_`#_?WlhIr_;sjlR3HjC-L(ZC`@6S%mZ*2viJ2Ut1pee0;8& zTFQGuj^PEpyh)$iI)`bJ{cB&WrSJC7Z8mqCMtFMR+H^!IutLf!ne2lvPML_)CkEe zS#DH+9G$biZggPec@9EP)<1`E3}8OW{={C6oimkPp4;07kl7;er~TR?`O4 z03Zmh$qdg>?0{tA__)Bd!rFgJo%Of99qYLRok8e1gxe5b#=FszsV@T080vgKgX!1?9a2#%onQ%dzI(Q2Low$Ru~XQ zw?}SGyD<6`rTV3ij@k?1-$>2l2Q_=Q4$j4e2>ICYZ*ZvI)rC}4F&=9B$>+m4BTa*v@HS}&>w?a_0X=GvgObgVeiGfq zyj2H$T{1m&#evbwc>j?{v5JBB&ns}34ZKPgBTqa;M1Hd+z$74+IEk`T=a$v>1>h4N{RDjU?yOcM8b& zPyxS}O+Gm)T7K{ha2|yd1R>ayqYWFj zq{BwKl09_Me)2m7E`GSd>&H)65S>)om)OgT*r{3EclwE`-j#Elz1tWT66Wf8TDhbR znNdwVvR$xpgxBNq^^-Kg>1T~Y0f^!D5v(qF@~AqU>CL{OcyLjuzY$F^XkMhnE9{JW z<|*&gqzD+UnP?H$Yp&WP1g+S%$&GFo+&XfjY~SMWt3WCMf7kP)w2sc&I4)*w>S}Z9 znFzN=)RQ1@C$}E2_+9r1$)e8>=U=VQ%eWS12uOQVo){=T@q8BrcotWg?cC12E_?~< zOXNm`^tPL!RKkS5jl1!w2r*aa6!}$EbU^rIB}g4GdxIZvb`*F;QmP1^x#!%LR|C8@ zZzvt(%br0u;sIU(tLC8@JlrcUQG^yF^1-_XZjFW$_m6$IF8P#CWyDu)t)*4c<7tIe zscu%Ru;p9pW0O2xQ8+a<;ts?7Dre@xVX=icJ(xjg2qBx(2ii)@A>>_#1(u^DL>w7N zd=OA~>P_~g0Gs%DNnV@)@weUHt`Iu+@F;unFPcxLfWan2KY!LlEwEf&fEu~zp*_fc z*?S^6F=cZ`S0})}N$o-fb%R`%LqmQH9C=t|WZ=rC84w;7#CL11y)BwG@>!DctoBOf z4Y+)7@78;L-XN#1%Dk8LN(bB)ozw4L(5$WBmqN=tDCG7>lH3E zKGe0frxkq2{Du^L+BZ3zSPjVYqkH@|F zoMJiV14lNt{mmmzQ? zV&qo2tT7ylQCAZ}oOJH}8y;4i1rY}GI34Z1nO_zp?7_kp00M>f>mS99?ee3g!=G}j zVaW%stD$#G@rv7mbf0}C5DT5&x-?U7U!1?aZa9W@a~L`Kg@imD9N=*%_##37Y$@`x zs|3op45?kI%e(f#Rg|L${$us@?Ma2B*R=h8);SEvW$;mwY{NRQz0@GxvCnsHy{P&s zlfqso(IHzL_^P5hC1Tck?G@__=YFw zydEo0;THJ(un~2jQ&F1)nN9usko5uai@xTCQVg{t^}CNDAu;8M$_BC9P7=vscn-Ss z4xR8%8Y@=$6tNQawGEL@6I0xC(rV9Zv={sKQx$n`rhYyD?;YnTMFvY@u_R;ZUY$_luG;wIT})N;DS1}oeZF^}8pXQY|0O>4paF)C z49#at)|mosE)dtGOX+BQxGY9xCw#$HGOZ|K@)&+MN1~#9rXyc=UYS*{LfynzfA(j}u2b3g&3>1?BiGB7tMv&xPGGlHx0D80jwr zBLoEC{E(+bPLlq7VBv=e`d4;5Xxw!ln}}AjBKqaRW!4COoKu8q>`s9MVoczql^8%F zgrMT{9@}YG76VK6{IQRx&oRNa7o;Q5&uVA>1Jq1UM*h(bP)QGUTRElrs;$hIDX?FV1nR} zG9-gI8Ska38Sf{IA8ucEw>Cq4YqR3Alr|%p;FC>(rw0J#jg=C+FuXNSJ|+5miS~2rh_QCBP}j!H|_PQ2pN7rNsMVatvb# zHX3X>SaCj}eW5Wmd^qmLGTzfl`&5%3rbS!*t@&QV7qK04AuG%VHv-E6iE--aR-#C;7 zQ_wR{27QwqRag@|!>+qO`hy-mpc&mcW7KLlI7+)0q^=&0WB6?^5z<3kfbc$O%*LG) z%w)o>J%MF)g9ZM;qKRZn)aIRR1ufT4Ir10Rg$tHIHY{B6XO$4v}YNNys&t;-cjiMwA z?Itn)RC+$;iUc?e9d-doI(pCXNfW+@dP?pB-M8PP6}X!gscM9^)KZLx)woZ<(swua zTiVwCBL1AU4d{)5O$-FDhOm-%5XFph7#=Jkxhnr#n z4Se1%WX~um>7Oi)hEXTNF+(dQFKF@fAIH?zVh(=-4%p4F8MBhh@OWJ5IkRicJ)?Nf ze-0UJx~Kq-`=!_uZ2XR3&Eao!U**W);z>Cs^bI$3P=Q9f1o0ITCI!dnng&33SPZUG zjJwmXxeO&oqBp(qYof&eJxWm^IWM`>Kc&vbH7R9<0#}Kg)b;>^z=1kddufI;GIH0A z<@&*>=`-;}1)A!>$7DEuBA=C73>Lrp@G;X_<_N~rACQpnPerKGSqMVjz?R^5evM*y z&fp$r6Uk7nnYe(VR8NHvALix{P7*^rO^R3ZQ_sE6KdCbZ>N3w!r|g@u76rlr@d{#4 zHM5}f7lf&KYZT-i*5chT5xpblRMoEQ=?kVBh zYYop%f%6?BhlVK0pz~FTLI>CL5>uGtKqis6tqlOo7Y5=-xAy1q938nnVC4j-pT76` ze&YlXYA}v#k&GC6{!Nyz2xFx*nV$#J`R0OMuMgqokfp*tBWxBwo7_Y(Q$pU8cu;tB z0any*^z6(9W1pvh5dWMN@vZtJm@vSDs&@6mLG{HZl*XYdjL9b5J3lE z35(*uO_%N_S7N@geYg~_M>y)cp6$zkUGB9J7zO^8S|^=Sr{IaTM@0S4ukhl_cTv+H zKSl5JD2V)@(k^`2^x?5uQYyKDaqeCovGT+jng&3GZ^d}{9KS0qM$Q1 z_bSghv=s4_=y@fTvPDaSvJ>b`Cxpn6k*w(dyF*ENVb#G-C(pdpT}un5aK-;VhHB66 zm|RQ(8ywpu0Cnh8XMige#v%10OcUcG&hzykN`!gb5ptqAZ{QRx-E{2sJzxUworMe~ zn4olyZM{a6FtD8H710Iu`6EcL}doj^~ zgXVXf_v;>$)dFx0&`!@7TN2sw_cO$wy8@}I(r^*P{l|tZ-R)u~#I19Xmb&+D|~Khv~oSeQLtSXid;8`%8JS{Yf*afW6MN zJs-g+dj0(xX+wd*x9)(2M_@j6$?naXz&@tFWmW?AF|5d;sAS4jJn&OnsWLEH_>XKa zm+lBA-*p%wQEzgm6SYeu?2v+;xA*?9A7EY1ZAdHPrBjl<#T{$}mjYA?xDNG^J^m?7 z4G+wYgDHA-pr1#h>hegeHuG z4BN=mpCGq)P?v)mx|r(!^|vpWQR?6V2Q6TzY5PwN*t)l{JM zVnt`gVNj%7fOe;21zSfPhZmfx^bq~8ox0H2HgV^@gSimJn&ABluP%HH+Yu}$SS$5% zt!;M+XCKgEIp=x@2(~6>vi@*Qvmm6L4?SS?+wQ>AkryX18llAtXg*p(Z zP$C2}3^1t)zfy6fWMM{Q8Ucr-?PTb1{MRev{=b6%y##+kwRcMj1v79of^v9zHPc?~w$|gF85lg|*SDVL!BhJtGMi8^BWPgm)(KSv$KEkGYt`#_wabD#Mr27_;I&oW01o8u1 zdMq#hm*I~bFm_bVLdo!UI3*c}dVjC3)L`ji)Z!d)A1l)#z}S#8lTZ*mBU^3P%~dO- z{ZThSo(7aa0=1p>>;mU24EAe9n%l$s`&*A?f|lljG*1$ng18mudy189^WDn0%P6G0 zD_QJs!H$h^hBp)hkPk=*A#7FM zg)u`n43$>uG=^+bS0d!sh#*t*a1I3FG=KWI^?9sw;Fbe~5t1%Ml^3c3&@<^kB{y(FmdK3Bo9C00q2J=WWQ^^0lDtwY z-10LNn=`*9RqIs?J_=(zbSs3Dy3i7_e62$SAU&}ZP@h$|tWgw--JJZL%8P6ALw5ap znu9(w;AV~;f2va(@#4mB2eGo9p8dH-?`!h-ZvW46zXBfJV(w8}wa`zhw1IT#NnfBl zNrk%R*NbQ`;nD)Px-hl_8acj+2yW4k-QD+|QM_bND+R5h%6nx44jxIA6elGisKG=8 z9vtvYrQ!enOrz>9`+HdjSxJT3m0X;~5mombFa<#l2Q$347{qV@OMd$`@Is6j=NP9a zRT@V5hv>LCdceUdY0Dc<1ITHC&qNNbl<23J(K9~k_`qRoTH^CWBOQeil6hvZhOJPP zx%cDKfKm+3c2-o3Y(RT8rd_!AJAxo3usM&Ov?*h;LKVd8f~uT9U`t3}g@Jtqxgy~#v%p8TTIE#gf9-p-0bJsNxa%Puk8UKD{`syG z7N+B2%6L;SKHHr!h^7a5E7hbBU=woRtQ}^cDXVBp-jM)}0vZl1cPIT9-h4V1aTGEw@5lU&F4PZcbTk=_ow;C9Z;+rh1<+@*>qIFyk| z#F(Uwh}skT<=P0UTSlkI#aa>2WL_O(9Sq#c-`x}A0SVffha3p7@;3~Eo6j^H=*#?V zKc@xTbH=3Kp8}E0{)V%`fc9I|6sckuV~yOrvBfsqa!8k^F0`GR$wJn#QWDhGlZ_Z` zCF#a|ZABf}3{4im+W}i4*n6${P$bRi%k$E2_!WMLj=i6pIS@$49h58w9vI5F&HmOu zdK{%ihcqB+=5u?_xORGwM7<0}fl9H+=sHntVnGB(U5b#?)_a0Dj5Z=ckhA|SVAq4WSyw*dw{XZ*HqBRg2IXWU7&K4yLb_wn-fm?954oHU#6s_6HLrJyJv z9U%H7gl~=DNpX3B#Oaaa4+^UVghQ!Bj0lpLJ!n znv};!EpL_@NRZUv?H8~0?_Gq?7{mau=ulrU)_*}LUP681P_9?-WuWqt7ljJU<@o<5 zowCh-i1^o>p3g*WuH~m4WiE# zAw(bGBi~s;bFvn3zv5P~@7pi|^W%m=hT*E@pc|41(Bz!$qnOS;Bm4LEoD`JjfdCWu zjW6no=TBaK>WtC)AVAaDTbKxBg$E#Mu;~3IX0P=-|o%`1=$}G=^Q{ zl$)7ZUt;MURai?8PmVx(11H}828Pv5{D{8|{+gB(Eyxz58CiaJ|L^UUR|0hC^h;#* z-`)zlm|B)veU}8|=oRX{t&Y_nIquh)BbLCF30QWyX1d}6vg0Nomo)dR7vhtA(8 z5XtJnms3a%vBHm5WdQ`mm5PzJ7=*esF~@>S61{a3)5kyCK$5Z;1*|Ia9q^J(@ykD3 zpwBS~p-m9FAs>sJ6#{|_Vs9b&S%A`oGO9BXqXD0<46!8RbN)F6()zm4xfMZEpws}< z`c^I9jhG@e1&V5^I~N2an*{f2rUr?eec)?rdGeqAJV7l8fiOG7{h^FCt*?Q|cogq~38f z94=QB?0Vy921&YI9{zJAfBgzn_;twYdFax4{j7*c!X})puQq-OwY4z>WTo8`|Ji4B zFAGF#XEsTv-E9VOxj=CCUXGCyzA~_O99=oi(|d~X1r+D@8xVjBv43r(=fia3#$)H- zBI;9du6)CQ)Ykx*n}EV#12Hw6yy<~C_CL!<(;w8+FA=yGC_PHF5D)TT+w7mM{Oe3Z zjrh(`zN&#S70^|#Q5!s7lcvRU9i#@|4;#Sbq@{cB8U8sb*Kv+H;JFV^p&2SXST<`! z>95g>(Y*#e3I^1!*sQ)+qJN$1fBw1wMB785UMp#Nji{VFn*Wb@k&g?UaZDgNj<%$P z!kqSM6sP1=ok;#{ooaX0#9wdbx_KP^1MY&Cb9B4@KmTso36Ym@j<4Jl1IYmrz!&GI z6oTtekoZ8XLV{ts2rvt9CJqsv!-1ir9Jl2NM$yV2 z0eS%c-#`BXWE^x(ldu7GWP(8TnLs~{oeU!j7Lug#7_$+E{~AuB4~-HMl)BTWWmSNp zgN2PTL-w0Yy8GVQYL&N{ik-8cqmiJN@B@iCJYS7om~kTrK$bb2t~j4y zd}l*#4{CHq2Gz|=`q#S8%z;pC0>~I2CPn{yhiFD_dIihvlz#PnxIKaX`|-dZt*(BSKi zP&J7!^zEy`K|&T`KuM1p+~eBF5`1BG^z_ya)dbvRqCoftuv-3P1hsgZ{DX>T(^KJi z7$DqTDna469foM&ugK#^Q&nF$#muTyD4)m?r+3Hb0N>r&m|Am^V1tDq(;iCnt!S0l zof!86M9^#pnYFyz$4mscz06CqE5ubyQHq;93G4(ovrt4g*u}V=u4;nWQYOXkzMFN?p@Xh6#U$M& zk_7 z?Rvtep>H)F6AR!VLr&+>InE)OHp;X3J(!u%j*kW$G|<& zMoh|0k68IqL?AN3sIrrIKehMvXDfNosYA;i2v}Nwu;_m*WvvIrD8K)S-f>YxS9i{N zsts?tIpI?A)B`a4!O_P2K48yrfQEo>GNcPW9j7I%*?95z>uTw$BF#sypL9rW^@|{0 zK0y0kg8IGg&eERSJ3@fDCAzk(FP9OY%&@5`gebKN zmJ)?XAJ9M0K$L*~9%-R7sDem5gonF% z-1|;lC|JBd7a+jsB-YYl(-(C&UO*!Bm7>JzT*T@6;KJ#iv+PL(!osjq0{mIPn9^>0 zCs3#72|o8xc`e}7qlZb5U3833!X`mC%EV_nk0TM3=&&kZc8L02y+KgAyigRq#wNs{4MUQBMz$m6z2trM;hZJuJi(7F2NV{u*(HV4XQ6$j~}Rm$3t3mfyyF zF$37YlG`T*(wZ&Kv#*Gnd9|#^b#jM|GD^4KbSpPzWju|xfvd8^OP5(S3VIwi_vY%N z8jW~COB8u&IBEO=bDlHvz%Vlx47GqOqCjLu4E<<^Ttgl;J{Wm2qrLR_ZKuZU!V2p4 zuJ`Yjgh`zC{Ll&x3>W}Vx?cqYBOUW>TvSw27EK|Qe?s(`to5F9ibdKd6*dbX>iS@N zdtp7-;Of)mm2d_@2u*wY(h0*;kEnIR(usj4sDS0*Rc&pX)H%Pyd2qS$pSH9y)@;cm zP6j7EZ>g{rz{6&K&t|)qJEGs{T#ZvxH(|P!Q$TCH$>|JeSO-Nq$A$q(r$4%cW|O7P zYje{D=f9{%Y2~!RetAbjzWj~IDaVM=k?S)z_LEH~{TDn&)7~Es<>DJ>yaLt?e5g6Z zF$cWJXXRSkr!KFrU9G>JP!Jjd>X#}{?6_eu~kcI_6jdfswwt%$x5CNl|~Mm8oOwGmUqMu(hT(!x(Ffa6cJC0Xr{%b{-IrSSlp zYsqb_1$F7Lauachw3d(GG*{+(6;Dd7yP>7)=3T{CNvplmn)iWE&0Qhwz%;Nfew?Fq z*lm$*j%n0r+_USB-KO61QD7nld|my=mBbJp(dEBf(uO*j;xGJnImp_(8WL|=RLGx~ z&4d@TJKpwqscj_ptikSC<_Hl_=5xRCsQeou?)*Ou$XbwPwkc%_j=KHes?pgj9&|ZL zr0&%DXH%0|Sn2_i?khKTYV=5MgyM^vj=}QrR{%0D4rMptt=VN>?<_Q2&2@sDk5=fo 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

Wg$rB^)nj1~%`>`QL2Sqn34cmNGPaJW-81S!zW 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 literal 0 HcmV?d00001 diff --git a/packages/flame_kenney_xml/example/assets/license.txt b/packages/flame_kenney_xml/example/assets/license.txt new file mode 100644 index 000000000..188521c56 --- /dev/null +++ b/packages/flame_kenney_xml/example/assets/license.txt @@ -0,0 +1,14 @@ + +############################################################################### + + Physics asset pack by Kenney Vleugels (www.kenney.nl) + + ------------------------------ + + License (CC0) + http://creativecommons.org/publicdomain/zero/1.0/ + + You may use these graphics in personal and commercial projects. + Credit (Kenney or www.kenney.nl) would be nice but is not mandatory. + +############################################################################### \ No newline at end of file diff --git a/packages/flame_kenney_xml/example/assets/spritesheet_stone.xml b/packages/flame_kenney_xml/example/assets/spritesheet_stone.xml new file mode 100644 index 000000000..d1940c1d9 --- /dev/null +++ b/packages/flame_kenney_xml/example/assets/spritesheet_stone.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/flame_kenney_xml/example/lib/main.dart b/packages/flame_kenney_xml/example/lib/main.dart new file mode 100644 index 000000000..0a7a0a3ce --- /dev/null +++ b/packages/flame_kenney_xml/example/lib/main.dart @@ -0,0 +1,45 @@ +import 'dart:async'; + +import 'package:flame/components.dart'; +import 'package:flame/events.dart'; +import 'package:flame/extensions.dart'; +import 'package:flame/game.dart'; +import 'package:flame_kenney_xml/xml_sprite_sheet.dart'; +import 'package:flutter/material.dart'; + +/// A simple game that adds a random sprite component created from a kenney.nl +/// sprite sheet to the screen when tapped. +void main() { + runApp( + GameWidget.controlled( + gameFactory: () => FlameGame(world: KenneyWorld()), + ), + ); +} + +class KenneyWorld extends World with TapCallbacks { + late final XmlSpriteSheet spritesheet; + + @override + Future onLoad() async { + spritesheet = await XmlSpriteSheet.load( + imagePath: 'spritesheet_stone.png', + xmlPath: 'spritesheet_stone.xml', + ); + add(randomSpriteComponent()); + } + + @override + void onTapDown(TapDownEvent event) { + add(randomSpriteComponent(position: event.localPosition)); + } + + SpriteComponent randomSpriteComponent({Vector2? position}) { + final name = spritesheet.spriteNames.random(); + return SpriteComponent( + sprite: spritesheet.getSprite(name), + position: position, + anchor: Anchor.center, + ); + } +} diff --git a/packages/flame_kenney_xml/example/pubspec.yaml b/packages/flame_kenney_xml/example/pubspec.yaml new file mode 100644 index 000000000..0729cbd7c --- /dev/null +++ b/packages/flame_kenney_xml/example/pubspec.yaml @@ -0,0 +1,23 @@ +name: flame_kenney_xml_example +description: "An example for the `XmlSpriteSheet` used to load kenney.nl assets." + +publish_to: "none" + +version: 1.0.0 + +environment: + sdk: ">=3.4.0 <4.0.0" + +dependencies: + flame: ^1.18.0 + flame_kenney_xml: ^0.1.2 + flutter: + sdk: flutter + +dev_dependencies: + flame_lint: ^1.2.0 + +flutter: + assets: + - assets/ + - assets/images/ diff --git a/packages/flame_kenney_xml/lib/xml_sprite_sheet.dart b/packages/flame_kenney_xml/lib/xml_sprite_sheet.dart new file mode 100644 index 000000000..73b5dc0d5 --- /dev/null +++ b/packages/flame_kenney_xml/lib/xml_sprite_sheet.dart @@ -0,0 +1,66 @@ +import 'package:flame/cache.dart'; +import 'package:flame/components.dart'; +import 'package:flame/extensions.dart'; +import 'package:flame/flame.dart'; +import 'package:xml/xml.dart'; +import 'package:xml/xpath.dart'; + +/// A sprite sheet loaded from an XML file and an image. +/// +/// The XML file must be in the format of a ShoeBox XML file, formatted in the +/// same way as the Kenney.nl sprite sheets. +/// https://twitter.com/KenneyNL/status/1777429120936202344 +class XmlSpriteSheet { + XmlSpriteSheet({ + required this.image, + required String xml, + }) { + final document = XmlDocument.parse(xml); + for (final node in document.xpath('//TextureAtlas/SubTexture')) { + final name = node.getAttribute('name')!; + final x = double.parse(node.getAttribute('x')!); + final y = double.parse(node.getAttribute('y')!); + final width = double.parse(node.getAttribute('width')!); + final height = double.parse(node.getAttribute('height')!); + _spriteBoundaries[name] = Rect.fromLTWH(x, y, width, height); + } + } + + /// Load an [XmlSpriteSheet] from an image and an XML file. + /// + /// The [imagePath] should be in relation to `assets/images/`. + /// The [xmlPath] should be in relation to `assets/`. + static Future load({ + required String imagePath, + required String xmlPath, + Images? imageCache, + AssetsCache? assetsCache, + }) async { + final image = await (imageCache ?? Flame.images).load(imagePath); + final xml = await (assetsCache ?? Flame.assets).readFile(xmlPath); + return XmlSpriteSheet(image: image, xml: xml); + } + + final Image image; + final _spriteBoundaries = {}; + + late final List spriteNames = _spriteBoundaries.keys.toList(); + + /// Get a sprite from the sprite sheet by its name. + /// + /// Throws an [ArgumentError] if the sprite is not found. + Sprite getSprite(String name) { + final rect = _spriteBoundaries[name]; + if (rect == null) { + throw ArgumentError('Sprite $name not found'); + } + return Sprite( + image, + srcPosition: rect.topLeft.toVector2(), + srcSize: rect.size.toVector2(), + ); + } + + /// Get a random sprite from the sprite sheet. + Sprite getRandomSprite() => getSprite(spriteNames.random()); +} diff --git a/packages/flame_kenney_xml/pubspec.yaml b/packages/flame_kenney_xml/pubspec.yaml new file mode 100644 index 000000000..c83aa82fe --- /dev/null +++ b/packages/flame_kenney_xml/pubspec.yaml @@ -0,0 +1,30 @@ +name: flame_kenney_xml +description: "Support for Kenney XML spritesheets for the Flame game engine. This package parses XML files produced by Kenney." +version: 0.1.2 +homepage: https://github.com/flame-engine/flame/tree/main/packages/flame_kenney_xml +funding: + - https://opencollective.com/blue-fire + - https://github.com/sponsors/bluefireteam + - https://patreon.com/bluefireoss +topics: + - flame + - spritesheet + - kenney + - tilemap + +environment: + sdk: ">=3.4.0 <4.0.0" + flutter: ">=3.22.0" + +dependencies: + flame: ^1.18.0 + flutter: + sdk: flutter + xml: ^6.5.0 + +dev_dependencies: + build_runner: ^2.4.11 + flame_lint: ^1.2.0 + flutter_test: + sdk: flutter + mockito: ^5.4.4 diff --git a/packages/flame_kenney_xml/test/xml_sprite_sheet_test.dart b/packages/flame_kenney_xml/test/xml_sprite_sheet_test.dart new file mode 100644 index 000000000..4617d6759 --- /dev/null +++ b/packages/flame_kenney_xml/test/xml_sprite_sheet_test.dart @@ -0,0 +1,73 @@ +import 'dart:ui'; + +import 'package:flame/cache.dart'; +import 'package:flame_kenney_xml/xml_sprite_sheet.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; + +class _MockImage extends Mock implements Image { + @override + int get width => 100; + + @override + int get height => 100; +} + +class _MockImages extends Mock implements Images { + @override + Future load(String fileName, {String? key}) async { + return _MockImage(); + } +} + +class _MockAssetsCache extends Mock implements AssetsCache { + @override + Future readFile(String fileName) async { + return ''' + + + + + '''; + } +} + +void main() { + group('XmlSpriteSheet', () { + test('creation from constructor', () { + final spritesheet = XmlSpriteSheet( + image: _MockImage(), + xml: ''' + + + + + ''', + ); + + expect(spritesheet.spriteNames, equals(['sprite1', 'sprite2'])); + final sprite1 = spritesheet.getSprite('sprite1'); + expect(sprite1.src, equals(const Rect.fromLTWH(0, 0, 32, 32))); + final sprite2 = spritesheet.getSprite('sprite2'); + expect(sprite2.src, equals(const Rect.fromLTWH(32, 0, 32, 32))); + }); + + test('creation from load method', () async { + final mockImages = _MockImages(); + final mockAssetsCache = _MockAssetsCache(); + + final spritesheet = await XmlSpriteSheet.load( + imagePath: 'spritesheet_stone.png', + xmlPath: 'spritesheet_stone.xml', + imageCache: mockImages, + assetsCache: mockAssetsCache, + ); + + expect(spritesheet.spriteNames, equals(['sprite1', 'sprite2'])); + final sprite1 = spritesheet.getSprite('sprite1'); + expect(sprite1.src, equals(const Rect.fromLTWH(0, 0, 32, 32))); + final sprite2 = spritesheet.getSprite('sprite2'); + expect(sprite2.src, equals(const Rect.fromLTWH(32, 0, 32, 32))); + }); + }); +}