From 4935f977a0348484512452083c14cc2252143ed0 Mon Sep 17 00:00:00 2001 From: lupeng Date: Wed, 15 Aug 2018 09:56:22 +0800 Subject: [PATCH] ihwplayer use tplayer instead of tinaplayer --- .../tina_multimedia/libcedarx/cdx_config.h | 5 + .../libcore/playback/audioRenderComponent.c | 53 ++++++- .../libcore/playback/audioRenderComponent.h | 2 + .../libcore/playback/baseComponent.c | 1 + .../libcore/playback/baseComponent.h | 1 + .../libcore/playback/include/player.h | 2 + .../libcedarx/libcore/playback/player.c | 17 ++- .../libcedarx/xplayer/include/xplayer.h | 2 + .../libcedarx/xplayer/xplayer.c | 24 ++++ .../tina_multimedia/tplayer/tplayer.c | 7 + .../tina_multimedia/tplayer/tplayer.h | 4 +- package/libs/libspeech/lib/libspeech.so | Bin 0 -> 156680 bytes package/netease/ihw_player/Makefile | 4 +- package/netease/ihw_player/src/Makefile | 17 ++- package/netease/ihw_player/src/ihwplayer.c | 2 +- .../netease/ihw_player/src/include/jsonc.h | 2 +- .../netease/ihw_player/src/include/luplayer.h | 131 ++++++++++++++++++ .../netease/ihw_player/src/include/readCmd.h | 2 +- .../ihw_player/src/include/updatelist.h | 2 +- .../ihw_player/src/libplayer/audioplayer.cpp | 34 +++-- .../ihw_player/src/libplayer/background.cpp | 34 +++-- .../src/libplayer/include/alsa_interface.h | 2 +- .../src/libplayer/include/audioplayer.h | 5 +- .../src/libplayer/include/background.h | 5 +- .../ihw_player/src/libplayer/include/dlist.h | 2 +- .../src/libplayer/include/musicplayer.h | 6 +- .../src/libplayer/include/pcmplayer.h | 2 +- .../include/{player.h => playerapi.h} | 4 +- .../src/libplayer/include/soundeffect.h | 5 +- .../ihw_player/src/libplayer/musicplayer.cpp | 45 +++--- .../libplayer/{player.cpp => playerapi.cpp} | 6 +- .../ihw_player/src/libplayer/soundeffect.cpp | 33 +++-- .../netease/ihw_player/src/unit/cppunit.cpp | 2 +- target/allwinner/mandolin-pv1/defconfig | 13 +- 34 files changed, 383 insertions(+), 93 deletions(-) mode change 100644 => 100755 package/allwinner/tina_multimedia/libcedarx/libcore/playback/baseComponent.h create mode 100755 package/libs/libspeech/lib/libspeech.so mode change 100644 => 100755 package/netease/ihw_player/Makefile mode change 100644 => 100755 package/netease/ihw_player/src/Makefile mode change 100644 => 100755 package/netease/ihw_player/src/ihwplayer.c mode change 100644 => 100755 package/netease/ihw_player/src/include/jsonc.h create mode 100755 package/netease/ihw_player/src/include/luplayer.h mode change 100644 => 100755 package/netease/ihw_player/src/include/readCmd.h mode change 100644 => 100755 package/netease/ihw_player/src/include/updatelist.h mode change 100644 => 100755 package/netease/ihw_player/src/libplayer/audioplayer.cpp mode change 100644 => 100755 package/netease/ihw_player/src/libplayer/background.cpp mode change 100644 => 100755 package/netease/ihw_player/src/libplayer/include/alsa_interface.h mode change 100644 => 100755 package/netease/ihw_player/src/libplayer/include/audioplayer.h mode change 100644 => 100755 package/netease/ihw_player/src/libplayer/include/background.h mode change 100644 => 100755 package/netease/ihw_player/src/libplayer/include/dlist.h mode change 100644 => 100755 package/netease/ihw_player/src/libplayer/include/musicplayer.h mode change 100644 => 100755 package/netease/ihw_player/src/libplayer/include/pcmplayer.h rename package/netease/ihw_player/src/libplayer/include/{player.h => playerapi.h} (98%) mode change 100644 => 100755 mode change 100644 => 100755 package/netease/ihw_player/src/libplayer/include/soundeffect.h mode change 100644 => 100755 package/netease/ihw_player/src/libplayer/musicplayer.cpp rename package/netease/ihw_player/src/libplayer/{player.cpp => playerapi.cpp} (99%) mode change 100644 => 100755 mode change 100644 => 100755 package/netease/ihw_player/src/libplayer/soundeffect.cpp mode change 100644 => 100755 package/netease/ihw_player/src/unit/cppunit.cpp diff --git a/package/allwinner/tina_multimedia/libcedarx/cdx_config.h b/package/allwinner/tina_multimedia/libcedarx/cdx_config.h index dc4a0b4f9..e85074103 100755 --- a/package/allwinner/tina_multimedia/libcedarx/cdx_config.h +++ b/package/allwinner/tina_multimedia/libcedarx/cdx_config.h @@ -11,4 +11,9 @@ #ifndef CDX_CONFIG_H #define CDX_CONFIG_H +/* wk */ +#define DEFAULT_GAIN_IHW 1.0 +#define ERR_THRESHOLD 0.000001 + + #endif diff --git a/package/allwinner/tina_multimedia/libcedarx/libcore/playback/audioRenderComponent.c b/package/allwinner/tina_multimedia/libcedarx/libcore/playback/audioRenderComponent.c index 45d97e9fe..b36d4a2fe 100755 --- a/package/allwinner/tina_multimedia/libcedarx/libcore/playback/audioRenderComponent.c +++ b/package/allwinner/tina_multimedia/libcedarx/libcore/playback/audioRenderComponent.c @@ -55,6 +55,8 @@ struct AudioRenderComp { CdxPlaybkCfg cfg; RenderThreadCtx *threadCtx; + + float gain; }; static void handleStart(AwMessage *msg, void *arg); @@ -136,9 +138,19 @@ int AudioRenderCompDestroy(AudioRenderComp* p) return 0; } +AudioRenderComp* AudioRenderCompSetGain(AudioRenderComp* a, float gain){ + AudioRenderComp* p = (AudioRenderComp*)a; + + p->gain = gain; + + return p; +} + + int AudioRenderCompStart(AudioRenderComp* p) { - return BaseCompStart(&p->base, NULL, NULL); + //return BaseCompStart(&p->base, NULL, NULL); + return BaseCompStart(&p->base, NULL, &p->gain); } int AudioRenderCompStop(AudioRenderComp* p) @@ -276,6 +288,7 @@ static void* AudioRenderThread(void* arg) }; p->threadCtx = &threadCtx; + p->gain = DEFAULT_GAIN_IHW; while (AwMessageQueueGetMessage(p->mq, &msg) == 0) { @@ -294,6 +307,11 @@ static void handleStart(AwMessage *msg, void *arg) logi("audio render process start message."); + float gainTmp = msg->gain; + //WK_PRINT("begin to process MESSAGE_ID_START, gainIn:%f", *gainTmp); + p->gain = gainTmp; + //WK_PRINT("gain:%f",p->gain); + if (p->eStatus == PLAYER_STATUS_STARTED) { logw("already in started status."); @@ -719,6 +737,37 @@ static inline int notifyAudioPts(AudioRenderComp *p) return 0; } +static void pcmDataTransByGain(unsigned char* data, unsigned int len, float gain, unsigned int nBitsPerSample) +{ + if(fabs(gain-DEFAULT_GAIN_IHW) < ERR_THRESHOLD){ + //WK_PRINT("gain :%f..............", gain); + return ; + } + + if(16 != nBitsPerSample){ + //WK_PRINT("nBitsPerSample err :%d..............", nBitsPerSample); + return ; + } + + if((len % 4) != 0){ + //WK_PRINT("len info of pcm data:%d..............\n", len); + } + int dataByGain; + + short* pcm16Bit; + unsigned char * tmp; + unsigned char * dataMax = &data[len]; + for (tmp = data; tmp < dataMax; ++tmp){ + pcm16Bit = (short*)tmp; + dataByGain = (*pcm16Bit) * gain; + if(dataByGain > 32767 || dataByGain < -32768){ + //WK_PRINT("%d out of range to %d by gain of %f..............", *pcm16Bit, dataByGain, gain); + } + *tmp = dataByGain & 0xff; + *++tmp = (dataByGain & 0xff00) >> 8; + } +} + static inline int writeToSoundDevice(AudioRenderComp *p) { RenderThreadCtx *threadCtx = p->threadCtx; @@ -745,6 +794,8 @@ static inline int writeToSoundDevice(AudioRenderComp *p) if(p->bForceWriteToDeviceFlag == 1) memset(pPcmData, 0, nPcmDataLen); + pcmDataTransByGain(pPcmData, nPcmDataLen, p->gain, p->threadCtx->nSampleRate); + while(nPcmDataLen > 0) { nWritten = SoundDeviceWrite(p->pSoundCtrl, diff --git a/package/allwinner/tina_multimedia/libcedarx/libcore/playback/audioRenderComponent.h b/package/allwinner/tina_multimedia/libcedarx/libcore/playback/audioRenderComponent.h index 10c7aa663..ac7855686 100755 --- a/package/allwinner/tina_multimedia/libcedarx/libcore/playback/audioRenderComponent.h +++ b/package/allwinner/tina_multimedia/libcedarx/libcore/playback/audioRenderComponent.h @@ -21,6 +21,8 @@ AudioRenderComp* AudioRenderCompCreate(void); int AudioRenderCompDestroy(AudioRenderComp* a); +AudioRenderComp* AudioRenderCompSetGain(AudioRenderComp* a, float gain); + int AudioRenderCompStart(AudioRenderComp* a); int AudioRenderCompStop(AudioRenderComp* a); diff --git a/package/allwinner/tina_multimedia/libcedarx/libcore/playback/baseComponent.c b/package/allwinner/tina_multimedia/libcedarx/libcore/playback/baseComponent.c index e8de6a6ba..55b4dd8b6 100755 --- a/package/allwinner/tina_multimedia/libcedarx/libcore/playback/baseComponent.c +++ b/package/allwinner/tina_multimedia/libcedarx/libcore/playback/baseComponent.c @@ -86,6 +86,7 @@ int BaseCompStart(BaseCompCtx *p, task_t afterPostBeforeWait, void *arg) .execute = p->handler.start, .replySem = &p->replySem[MESSAGE_ID_START], .result = &reply, + .gain = *((float*)arg), }; BaseCompPostAndWait(p, &msg, afterPostBeforeWait, arg); diff --git a/package/allwinner/tina_multimedia/libcedarx/libcore/playback/baseComponent.h b/package/allwinner/tina_multimedia/libcedarx/libcore/playback/baseComponent.h old mode 100644 new mode 100755 index a5b709879..dded312c1 --- a/package/allwinner/tina_multimedia/libcedarx/libcore/playback/baseComponent.h +++ b/package/allwinner/tina_multimedia/libcedarx/libcore/playback/baseComponent.h @@ -25,6 +25,7 @@ struct AwMessage { int64_t seekTime; void *opaque; int64_t int64Value; + float gain; }; }; diff --git a/package/allwinner/tina_multimedia/libcedarx/libcore/playback/include/player.h b/package/allwinner/tina_multimedia/libcedarx/libcore/playback/include/player.h index 9dd0e12f7..bebc10725 100755 --- a/package/allwinner/tina_multimedia/libcedarx/libcore/playback/include/player.h +++ b/package/allwinner/tina_multimedia/libcedarx/libcore/playback/include/player.h @@ -131,6 +131,8 @@ int PlayerSetCallback(Player* pl, PlayerCallback callback, void* pUserData); //** Play Control APIs. //** +Player* PlayerGainSet(Player* pl, float gain); + int PlayerStart(Player* pl); int PlayerStop(Player* pl); //* media stream information is still kept by the player. diff --git a/package/allwinner/tina_multimedia/libcedarx/libcore/playback/player.c b/package/allwinner/tina_multimedia/libcedarx/libcore/playback/player.c index b4c408908..19e6d5d0b 100755 --- a/package/allwinner/tina_multimedia/libcedarx/libcore/playback/player.c +++ b/package/allwinner/tina_multimedia/libcedarx/libcore/playback/player.c @@ -131,7 +131,7 @@ typedef struct PlayerContext int nUnSurpportVideoBufferSize; int bDiscardAudio; - + float mGain; }PlayerContext; static int CallbackProcess(void* pSelf, int eMessageId, void* param); @@ -721,6 +721,13 @@ int PlayerHasAudio(Player* pl) return 0; } +Player* PlayerGainSet(Player* pl, float gain){ + PlayerContext* p; + p = (PlayerContext*)pl; + p->mGain = gain; + return (Player*)p; +} + int PlayerStart(Player* pl) { PlayerContext* p; @@ -760,8 +767,10 @@ int PlayerStart(Player* pl) SubtitleDecCompStart(p->pSubtitleDecComp); if(p->pVideoRender != NULL) VideoRenderCompStart(p->pVideoRender); - if(p->pAudioRender != NULL) + if(p->pAudioRender != NULL){ + p->pAudioRender = AudioRenderCompSetGain(p->pAudioRender, p->mGain); AudioRenderCompStart(p->pAudioRender); + } if(p->pSubtitleRender != NULL) SubtitleRenderCompStart(p->pSubtitleRender); } @@ -824,8 +833,10 @@ int PlayerStart(Player* pl) SubtitleDecCompStart(p->pSubtitleDecComp); if(p->pVideoRender != NULL) VideoRenderCompStart(p->pVideoRender); - if(p->pAudioRender != NULL) + if(p->pAudioRender != NULL){ + p->pAudioRender = AudioRenderCompSetGain(p->pAudioRender, p->mGain); AudioRenderCompStart(p->pAudioRender); + } if(p->pSubtitleRender != NULL) SubtitleRenderCompStart(p->pSubtitleRender); } diff --git a/package/allwinner/tina_multimedia/libcedarx/xplayer/include/xplayer.h b/package/allwinner/tina_multimedia/libcedarx/xplayer/include/xplayer.h index 6449687f7..63b804c5d 100755 --- a/package/allwinner/tina_multimedia/libcedarx/xplayer/include/xplayer.h +++ b/package/allwinner/tina_multimedia/libcedarx/xplayer/include/xplayer.h @@ -161,6 +161,8 @@ int XPlayerPrepareAsync(XPlayer* p); int XPlayerStart(XPlayer* p); +int XPlayerStartWithGain(XPlayer* p, float gain); + int XPlayerStop(XPlayer* p); int XPlayerPause(XPlayer* p); diff --git a/package/allwinner/tina_multimedia/libcedarx/xplayer/xplayer.c b/package/allwinner/tina_multimedia/libcedarx/xplayer/xplayer.c index 99fcd72cd..510019fc6 100755 --- a/package/allwinner/tina_multimedia/libcedarx/xplayer/xplayer.c +++ b/package/allwinner/tina_multimedia/libcedarx/xplayer/xplayer.c @@ -187,6 +187,7 @@ typedef struct PlayerContext XPlayerNotifyCallback mCallback; void* pUser; + float gain; }PlayerContext; static void* XPlayerThread(void* arg); @@ -233,6 +234,8 @@ XPlayer* XPlayerCreate() mPriData->mSeekTobug = 0; #endif + mPriData->gain = DEFAULT_GAIN_IHW; + pthread_mutex_init(&mPriData->mMutexMediaInfo, NULL); pthread_mutex_init(&mPriData->mMutexStatus, NULL); sem_init(&mPriData->mSemSetDataSource, 0, 0); @@ -744,11 +747,18 @@ int XPlayerStart(XPlayer* p) msg.messageId = XPLAYER_COMMAND_START; msg.params[0] = (uintptr_t)&mPriData->mSemStart; msg.params[1] = (uintptr_t)&mPriData->mStartReply; + msg.params[2] = (uintptr_t)&mPriData->gain; AwMessageQueuePostMessage(mPriData->mMessageQueue, &msg); SemTimedWait(&mPriData->mSemStart, -1); return mPriData->mStartReply; } +int XPlayerStartWithGain(XPlayer * p, float gain) +{ + PlayerContext* mPriData = (PlayerContext*)p; + mPriData->gain = gain; + XPlayerStart(p); +} int XPlayerStop(XPlayer* p) { @@ -1972,6 +1982,15 @@ static void* XPlayerThread(void* arg) else if(msg.messageId == XPLAYER_COMMAND_START) { logd("process message XPLAYER_COMMAND_START."); + + mPriData->gain = *(float*)msg.params[2]; + //WK_PRINT("gain_ihw orginal:%f",gain_ihw); + if(mPriData->gain > 0){ + + } else { + mPriData->gain = DEFAULT_GAIN_IHW; + } + if(mPriData->mStatus != XPLAYER_STATUS_PREPARED && mPriData->mStatus != XPLAYER_STATUS_STARTED && mPriData->mStatus != XPLAYER_STATUS_PAUSED && @@ -2070,6 +2089,9 @@ static void* XPlayerThread(void* arg) //* post a start message. memset(&newMsg, 0, sizeof(AwMessage)); newMsg.messageId = XPLAYER_COMMAND_START; + newMsg.params[0] = 0; + newMsg.params[1] = 0; + newMsg.params[2] = (unsigned int)&mPriData->gain; AwMessageQueuePostMessage(mPriData->mMessageQueue, &newMsg); //* should I reply 0 to the user at this moment? @@ -2086,6 +2108,8 @@ static void* XPlayerThread(void* arg) pthread_mutex_unlock(&mPriData->mMutexStatus); + mPriData->mPlayer = PlayerGainSet(mPriData->mPlayer, mPriData->gain); + if(mPriData->mApplicationType == APP_STREAMING) { PlayerFast(mPriData->mPlayer, 0); diff --git a/package/allwinner/tina_multimedia/tplayer/tplayer.c b/package/allwinner/tina_multimedia/tplayer/tplayer.c index 38e3e9132..512f65f14 100755 --- a/package/allwinner/tina_multimedia/tplayer/tplayer.c +++ b/package/allwinner/tina_multimedia/tplayer/tplayer.c @@ -291,6 +291,13 @@ int TPlayerStart(TPlayer* p){ return XPlayerStart(p->mXPlayer); } +int TPlayerStartWithGain(TPlayer * p, float gain) +{ + TP_CHECK(p); + TP_CHECK(p->mXPlayer); + return XPlayerStartWithGain(p->mXPlayer, gain); +} + int TPlayerPause(TPlayer* p){ TP_CHECK(p); TP_CHECK(p->mXPlayer); diff --git a/package/allwinner/tina_multimedia/tplayer/tplayer.h b/package/allwinner/tina_multimedia/tplayer/tplayer.h index c4ebcaeac..a3fb43119 100755 --- a/package/allwinner/tina_multimedia/tplayer/tplayer.h +++ b/package/allwinner/tina_multimedia/tplayer/tplayer.h @@ -1,5 +1,5 @@ #ifndef TPLAYER_H -#define TAPLAYER_H +#define TPLAYER_H #include #include @@ -145,6 +145,8 @@ int TPlayerPrepareAsync(TPlayer* p); int TPlayerStart(TPlayer* p); +int TPlayerStartWithGain(TPlayer* p, float gain); + int TPlayerPause(TPlayer* p); int TPlayerStop(TPlayer* p); diff --git a/package/libs/libspeech/lib/libspeech.so b/package/libs/libspeech/lib/libspeech.so new file mode 100755 index 0000000000000000000000000000000000000000..824f9185bbd9cfa235add1da8295f7b9d8398825 GIT binary patch literal 156680 zcmdqK4`9_*{r`XNW#B~2sc59A7e$?hdM^wZhB<-hP{b=tMI-M98!#Q)ZM(oQ(wV4O z5L2_}7rT`r{;a34+q&D?+Bnez#M6ig5v3Qi*YPwuVU{x#PU?o7A*Bcf;1^(31$&}>3@8Fp;A#VoPlYRwv88qr- zYHh}Iq0e?7vh<5i+$W(gvgLO`PvRL}^DT;gKk1*hc@+K}^kdv7kY}3BcN^hZ&{Mdj zyFa%1hY)^)@FU#cv2o9U|3`Q$xQF`!?s{9!Jg}I1EOE`;%emcaB;oPg@3fIKoWxUz z|Bx+b4)IH&N7=BljfOshJPq7axxdA&YasEbbKg#QF842OywYxleg`-}0j>|&^6rL? zK);(iV)H)@ewTX*_dmJcN!l(jpL;R%16~Qqe?IQeEu`x@hdjDIoCGt?#vcy;k^4UG zcJ4R1|IDqc1Kh+N=YE3wV(wv-a|DPvGPjUtC-+0#6~yVfiug+Is|Y_}!bTG#V7eSr<1Ok9L} zIN`@_+GLv+B>Y1gcdU(58J7`vyp31*HttIZ2W*}d&|@r}2cAIq%TE5QiTf+zTfj!{ zPx1T{+>de}NBlRrM?>qXfj)^mx-R3s9{MAq!QrI&*QL+5-2dXPAg+Y_Na#}VTjW~>?O&(ZXB0jf z`bH=GFmWFy@9+K07H_c6*OGUfrC$YqMEV}?3%HLX?PhQ~@gKBh*4wD);%& zySXQE&mrG7;?A@AHP0I8$)rWOPa`;(J8IJx5$9ivAZFWm#a&I>g@i{!4+Vchc#X}! zQW@;E*x~{|!s10db20Z?o@oF>_Sws!&*J_$;ql<{bPGg90v~r z^SDdN_d54i^?lUvsZxJzs~UWD_{Q^emz_-EiLHvWA)_a{sL8a$Ek9i$%v zzR$*o3EyhzHt0rf|GI&EorIs`{u}qloismBE_hfjnKJSmn-T7Ba9EZHkIoYJRz!`> zsN}siJRQ7}`=X5W%-~g-5rl_0aVI%+cjV<636+G$IC1AVbWh|6o7m7prt^A8Q_}4= zeX_;FEoQ>d%!rI|A|qU7!yzYry+ijz&L{B;+}CrD%93%s6Zbvn&)e{wPQ1vgZFsgt z+;y|Y(k^_+2HtIPiJJ)hH23>$+&J);miFONOB7gK?k8CMDENzvxX%!NE+ftlehp$G zcg&9f@3Hg`z-5-+Yte-=8`uqg&`D@==ph+4q}-+rBz_a=oh%p;`Xlx zeWC|EkLNo{F9K(RJGlSIJ&oJFj&lNG=ug=2I*YAfDP{c1h6Q)owiQFaY2zzxoDF(# zGI25P-#L+^2(Ko5IrtE_t}5^wNz(iGG5-CaO}oY7V2jGo;^j*HGu)EDwK&_!`)M2Z zG2$+?@vjm0X-ogirhglJ)W+E;^JSj^pW?oU^o`sDp>K5Ze!$YpEN&wG`_SLxe$d7( zwn&nh0eutrbp`D8UGOX1PuhH^+W46^ywKvmY`oxIHqMVahVZf6_uBY&5`OLEska%g z0sle#Z*AH!gg?i<(5Ama{417z2lU$soc{-Of*8U#K;1GbCj+3CpOO@;@hAXfdAqCyUnNMBJ$o!_%qzU z;ofZ1v{y0(`g~iK^6s-~qQ9hnxF!%+%pE4*%iy!zR}jC{OHKZBB5@(o-v{bC-YIh& z^n19^uyHq%Uco(q@D}oao%uXF%q7D&pNKrq3V8J&L;BC&$@8ZN zjOGi4|L_p&(G3A_PfOvaPr@f>lj>yB)&9LPbcIEQ)@MrpHG`n`>QsN0z>2)#0dKvb z^c(4al>W+ZQ-Aki0P~jyyuA*!@9(sK6o#vWbcNT>Kt>F9^;geNf?u0H5%AW+O0Oc` zzd{f{gK^-`QI_tPgR(Cv4FMZsj2=gh{6x}okyC=dy4v6s89US^P5-Df8^(< z@1Z}1^oM49>8FwZ!7Jgv4ZolI%TcJ6w!Ggk5$8t&o=>6j4rdY?#=zKP^A|5?edh4v z`Z)d5LWBR+o~1N;)5uhN7g66%>YHVszv3LqM;}Jn`rgL?t8ECF<>-Uzy9-8a!H7<@ z>7QQ%|Jf&1|Bfcda30)%K7?%giyJ5p`Q;Oqe7=sp_!mtv%PwH8?#SzkW6>}4$LCM$ zwb&F#pRfKb?Z@D+x9z$0T|7TCDSy>}vm+lwV+L0t|GNTaHnjSG7zXSy_%D4?_--23 z$)u?Esefhg$-mUTryjx9{5Yi_f6QoqMZ%bs52VuHe=72v8Zbk7R^@+{cKVmfn?4?W zXiB9I#j*P@o2T-xr2k*I2s;Nq)E+%Q2mPpJ1NcqarS@$>KK`ZhZdt{8nEv?n9RojB zvSBLu98G!0Ux@v1_&fhz^z;8x{GCL9mR%a~=5N(E{3_^1h&*SD`MWxUY- z;iPLkJPLm%u@Qxt^yL3R?DIq>p%UBwI_%$G$Nmv*7O;`1@o|hf!o)Mi>)o{fY3z~s zt@i!}`4*iY@aANN3r`_^M#^6P^E@)zOYMK-Xg_56cN_CK^NaW|{oHv*divKt%6>oc zSAFX5r5N(pu;(Gd(!YJQ|MhP&|Jd=m;xpK@pQPk*$+g(4+fwpaayWZ3=$Fs$zc9(a ziT(EVyz9$tpNqkl69OTO2_h|eM{sfEJt9fS|==>MqCvnR&}?ns-y zum-|jYJb6(@R@ljR1K}?C%uO_#~%E-0{+bkc>8^7?_T8NUwZzj&*GQiU~Pm}`cA?x zI{H8MKKg_G^6k?jXZTMi_4U3J$d7*eI)IZh#1oDg`PhZ|QoRvP`w*)DO$sumbJ5GYPmxl7s zvG)b=%YXj24>JGZgs-vs(n)=rUJaO5@~XZcPo#WDURU3VJ)-@v%WMC28S}-rMv!1H z_4gypZ|j};Ein&!=*-`<79jtRQaS&N9}i=XTAlHF7WTXee$ot&pI6RD=RcAhzaIa1 z&c9UO799E3*#XaQQ~Uq&G4j)1U*GR*pnr~kcl_<}-|5fBM(VpiIp3)KNoV?{iyzFL zt;~-ooBSiC$20tkF(^uY4gMPKQvFX|$=W%Zv~LPOe+~WraLS*$Y7*mrY06%njQ-BT zpMx#l^RL}QdC1G>_hH2QR|w+bJFtIF`(HpG-1(;RGVBlYjjwOlp6)-L?9W&fC0@;Z zk6)qoorM4WpfewgT8RI(8hdEva|ZtYf-j`}@yqB>A^j<*Sn=bC5sXJV@7H(i8tgmv zZwl!u|CvwHzV8OS{SxKB2!5BWP1*m;#?T&KUdSFP{n4AK4}BR)So32!)}C^?~LDk6=E-u?eL=*d2WPOc^7|$`G^IszOP9Re4*PZ=YrT^SW*C*Qc^?=J+$GqDOm9Ov+#R zZ>EA5&ZRxbL*W;YR|tOk`uvaM8MCYhC10ig2YZyqdeWE2(skrVp0i08zb?U^`?U3LTb=Q*_5@d;&+yOJ-&dH=?8b_yj9<7<_G^$eJh8ff5~{5BmBKC;Jw$> z^SjUWpH_MFk@AM3uVv6mpY&1MOZ!!x+WSTHa}$Rk@~r%RPk)zRj6JaYxEucXm&&VJ zi@kT|=f9EfMfe#a?P&P<M}8ggf9Jz2o`->@j)osUsEre^=8 z`mS7*zTR4OKl<|B)ObB_0rI*Q`PugWEn|Lp9mZ~gztRVlAEzPie18XmbN3IPg5Un7 z`E)z_=U-}1JN{1Va{==hw90#7NxHpAj6xphLka2P??1?2{!{FUZQn-_{D$wO(jR{} z^Aq_e+WhM`K)_$|OY)9V{|fBogEoC*Is3;SO65QL9_%sY71;D!ufX1YFctn{A@e_r zsw&dG{-Zz3ocXB}!;@fqYkaD`4`ZKNMx^#j)-zDcC_iM=SKo(!_yqE#KgvIQG5*^_ zsqs98jO&>n{P90v9{p!NZ?@0BkB$y?#>a1&fBZ}Qy@ZZzVLdwsH zo&2x+KgM`QpNEoP?dd>%zr>$~ZSZf1dGvbh+3iVtru3nz#9ks_9Lzt?_^W=1{(cVr zS$X{o`_YWQr135Oorb;hFFk)lM)*3$Qz!O5PMY$6lkw!*ua_A=ZR?Zsqtd@cAtl(y zDK>uz^%ZOjn9Vl)L*`5WQhn1u#QP}x_XW`E-^tV$#~&PG+k3@o%7-7Y!Q;oz&f%TO z1p)89iR$~(seWl{ALnDL;1Bk6h0T96^U2|?=NLv_`M<<|KlprVzB-fo9_P>#k9qwI zpqOjFml}^t(f0~x{`wg8x&G{J8dRsH^lM`V|MsHa?s{k9M)Jo}_WGQw)Aut!*36zb zhlU!+CVtGQ#$Gu7=U?xIpUlS$1CJkHe-wRm+IMsYf4_`=T~Gf}Yp=ZZlW9Ntns1*U z(ZqOl*7HZ52*1xx^*@}^-q(;z74xN@7ytir9Qfw~ekdvLGxeaols*{y<&NK0K{%jn7{*Uo|aG?QeYJ2>dfUFiB0{9BkzgG-{?t{Y(A% z{jKzu@ihcm^V8q)Z~RN?`N;1D(dy|b)pZmC{O+U^Lp&rk5l&S-1jjbE>F#GtML!>C#2T< zqdw03_+)B6ef10qvX}bvi#qg~mwEpB=-=4qS$|HJulkm6;5{b$BeJ*R7gO*4OV1yF z5&U=b?Re~i>wi8}vp+lS=Uvli#{Z<$`g|$+;9pArz$egu_A{k#;@71m_>YdhUM0rc zOQtq>Is9RM_x0n|akR(opG$tX5iWG>&*jLw0DUUqS(QJz5`AL)PqE<$?RV|*OYpaV z`L)QV!_NJe+B=`}k7j-2kLSt7$bIvRbyko^+mB6*#CcKUj-rHuZ=AL+Bod!B)} zb|LdK4N(4%({T5F%w?44Uuw@Ek>4oRpJ8Y{KT8d>m(nl$6#mTjQ}+4?YY4ZJ-?nGk zCFrA5|F`myzoY-ZqL6LQeDJ#j{Bh>D(KpgR>Su_1^^YWf*s)iiVLVT9#_P5y@*=bN ztM;xt)o-o(%hY@>^Bapf*y5#c!G3N+UXq{kuRWjV9esON1=&l_mtY@jo%!*}5q@g2 z{2#u9`C~+CJ`65nz9+xaO(l`^DJ%5cXC4Q~i@P=ckY|L*&<_KfxXXEfijK8XUFzdJsIzxixx{yJ|O z?RWa0xP>`$WY9ZXs`fwrF#P=y!nE>iW&U^9cP;3Xf2lnK)o^<${7LNLhKhjM0^il& z?|zZ_)R`Z5qaPLDPU-7d?BO;(hF-@bdTWwj%D;&5 z@$BzX`W?#z6xtR-a`IPdvRrIet+(I+C%%*AC-R{Oi4KQZq%jNYlr_|fKTrJ$FcZBo0xBK2|Rw# z6cgfL%TCHue=o|==jG`89{hv#w!WX2C?;`}5&L#QT@{HI#%3{Cm|e`_Qx+`%nIngw>wskmpc`pQ|evpZLQ? zHvI(Fn`N{&--ahkvGDi({(oc&_JVYo1(o;AW$?q1-}^H7|J1pR=l7=e8!pV4UxvWH zHuAUI**DmCS$Bs89U(%R87aMx^xj`VHti^S9co@jVqH>YPV7@nP1J z&)`o4lkFXfy&lG(Q-4(6?)ShC`jcn-Gg(Zum&p5RUorcW&Ctrf4St5clalYol63z! z2qUA|8>y+<^V_4a|BSbZ_W7G`h2QKK#Juz&<^^+4oZZ^G!VGu804Oeca6ZXZ2s@<)5E^KBH+m_TI4{v+3X7-=_4V zJi|Vo%z9&m<4+wvl7j6e`Miuhd%>}1U#(|9YE4SsKfD@!xiz)Ey7b-nJMZCrFwaV! zOVB5Gzwyc|(FeyrU5PzP+=9NLpXv`oC2hU;Wdxz~bJCw<;8Jl5{)eL<^WfiU_x+dm2+yVlWEygVso1+RX}BJ z%}r!6LZ$(MhFsbL;6{WK6Y3#2OO~ zHFfh#qmj|^Ik9>|)s+iljnT^@VZ!rjs%xthiY_(;?IVfG`LTKR4arm|K3Nn^t*ow` zQxjWMx1^@7DmFJBkHs6hZS3UHr8k&`)e9S|6K0{;)9js^93fw3r!1q2YU}6TNT1`0 z1vI}Zws29Rx+$heo|u^!9gf9Fsb3OnT#85+#;O|{>Kl-B_L{~ms>@nlGP=uCnT#Dj zv$~AVu^;znndH&xur8J z`KPp0jP>O)uc3ZnY>uZCDSoRZeJ^)hWn*K_{JPTUWplgoGqW$FlM+v=V`;BlFG^;= zsBz|^IhQwfQL0qaV~vaEEUa#9tenqK$&f;38^)m-mRm`ULs!SZo4J*>wR0-x-WY3~ zaalk3(0gz8j}Y40wKG{pNSB^OE?SgWFr)edi>ezF==oyf4f0rhyt*!y9O*G9N3wT~ zT^W*AOxCgO=J2dWzf>acWA)O~{)?yY+C70DSOuSP z+03F?&&-SztBqCFi)-dq#}Z5980o45Xl|MfkGR~5jBzSDRCPqWfl}R|-W-} zifB^TSuEn@^7_hLm^f&hbPD&CdTwnc0&6%FRZNgd%U_v$C`ylv^+pVeR$Cows7zF6 z@h~FeW_m8!74Za0-&k5V7ekIW)YXzN9vw@|+O3$omKafqU1pCi`8;XXR^qK?k$RWh z4)1cw9vLlWESC2KzjLY~;wjG}O$We-MX5*UCJ#O;#4KUqV&$ za$sVziTI;x9R5^gLypo)+7SC(ZFSxJ#Dd(!?D3@W#+uq%Jf7s}IdlSWc!IfWs61%0 z9+Mo@z1Vku?AvVJj{S_%vRe7{Jl377s?BC1GP34STo3a`dSOYi;}c~w1?gG65$5UR zA>z8HNgD45OMlYa9~sMnQS1BtdMayNw}kbPx2l(cn_F95S+|IFc;;#)5@q=utz24L zUs=_SkI(GyWa?Ho(n`uIN;gN+iZ)b#Kt5|01K%}o9Sh(@ymV>LeMps?Ltf7zY^ZLG z+k)-NAM@N)lju^69LcmrkD< zjuk^rt6p4PtCcS+gPDm5F{Zm%ExSBses#i|!RA#}E;TIvD{B>uHJHV5c1JikA77Nv zB0X!DB8$Bu$HZ>RzV#8w{!~@!sSKU+T3yp~@{*pDtGiA1m)BFOllws9q}faei`ZL= zRaGV`lWb;NVjTVq&etL)-KrRy7S&UyO^0Xm>lS%C8KYy<*kFmp>uYP~E-f8hTAExw z;<-1}FZBx~+)ABC0>29NH%+pNh^;kh(6cysOZ{-PLwyHe^h)!RZ^;e%~@Ttg|^wqmz4WY;V;y zR@-@~{Oa_b_eff%(k#n7w~%h9^0ZRex%Or*xKtGL^~$rWy%^M#CF|>h+2+zn#M^@C zx%+OOY`yn4GLofq+kdwhzx(OBTjaadJ+~(#Th=C}eD7Xbl~I^&SY4$zO7!9&Inw*O zQ?EV8xjfGP!HgTcJ@vltTSk~Im}}!pV{$VZOQUn;rHuFN($#N^@k#O`GJ3zp_IG6W zJX?>&d#p|*2S~bxxH=T+#!E?mB168pJ(O0>m8|-oEMu`sMFI zm(OJIM`D+I@1=5ZrC`1{9rf{%tEV$%$T{Qn+u}$>4X$N3+-_|%{mIIDZRx9T=QpT7 z&!x9YFXI|(vNtTl7N^f|UfZYko@Hi6mNZ+OwUDkkGRtt4Bx?~}GGvyJp_^F?$(Bco z(~VOiLB0)Mrd5Tvr{*3Vv6%@iTBwfap|*pmv%%V@rLR+tFqXFMRT$@CNjFdF4geTnTg_gRz_1VUL2i1GdAIx z>Nzvnwx~`dThG=|ED|Y8B;t1GRtGN-OlB`5W9#dt)HKpF%amNo7EiJlH=(}n^5pS{ zT*{#snmO)@_+-7A$zI}k-pJ}yOJ;eCvu7VyUl*t>Hqi7 zj*Y8~bKu0=ZZwxq85^6*g5D#pinHHW?U5Jj;F^l>MLtE9oMd*AqpjXm z<0u1iCL806=gb@zE9K6i_Ke}(Lo<5mMx=N_WnC2;{^|}#@){S_Cc5jDH~L2JAAWu( zT^p!(CFR~baBm~N7aPcF!km|Z+nilRxw zYhQx%wSuC$2$t5!VwDSqx!Bk%8dvmha6?}^-9l@F! zEsECH*2+1I#7ay339-9m+l0)Cz<;bue75|NR5fY&6>syWcvz%25gF^73FQsiE7!_R z?H)tBC&cUHoE@#Nvx{adxDJ~pDr;&ZV`I}OgIDWS)n5O#GqI>{L4CarNBYMyYpZG& z^NPQ#5V{yNosZDFeYL?mzM53qOoN*|Q`t9z8!4)+N-J4!_QElzziMAkeH%~Tyq-mQ zE}1zJSyWepq`i}$+Re@MtxD6JtKPGxPJ()k>HPs;JE*(YwsfZf(d;&O5*E5)=?vbr zd8$z4sluYh1qj+Z*^u?HTNaVV^^E5j%kISy=|Y^c`YeMo%fp#YP&XFXaRxKkko16^ z!I#M=KSNdv(6vQHUU$@y+T-O>o;qKIF zO|*Qs(WARA9AcGqOUK8q@(yHcL}#c|*Aeck7I}+t{VNyEUyz7ZH_ff~PN2vN>YV-@ z4)@n_f|!@OHm0H4J0WgEGJ7_ajkxq(wXrcBexJ*`q2vMggWrSwQ$yCJ6uWv$I4Mr; ziJID24Rf7dxL6;!xM~ruBx};CO-yVaIdxi7q?9}CUxl{#GQR9rRoVDXn zW;qgzguU0{aaL-~P()Z)+p+wmu||$%`@iRr1iMr-&f_- z3#Nm#Q*CF>xU9_LnubJjgECz%qa$gjqc5+os^ROhhSZs6`Ts@Jbh^2VOuKp3IpM5_ z$7*|QZq83<9C%g<CJ2Asvt7cJJfOI zqH0#Q-W;8Jd&FkO)Vk7|(h12_zIe;|$kbb1amv-{wZ{{#;Dnmz+e~Kh+rU!3T1QRr zPDUp+Yo_PRu%kv)-jB?QP8$t}Ks=HD)zkO>j7~GT zhpIRIsbzm(-eR{PrC;H0A0sX^T-g}WT)L1NJ8v4GhoZhaAlM+n- z*rxZszZDiSb>8cLqdooORECzk)oYagtJPcF(p9BY%k~2%Jbgqc6oi7p2hCKq<1VWi*pPzV_i5Q?S)%eeJwxx zn7z)dIkQ&n@YEL7)CK>7N19FXq9YZqrlSQyIsC zYyp|a_xkqrE&bzsDQ~8eP3Ysp-nW0rhtq}E%@Rz?mhl>ksPxxZkuXO;brMIvwB)lU zd)IqB=xEua4l)vK|FV~(Zy0T!^lo%HzEZ?@EQ@&`N2^n_r1z;chmE}GV&0S4uP3hH za|`dx^^EeEer1J^6ssE&v3ZF36wK`9w`uZiK zXH?U^gz1GLS>IK3?T3F1G`%!u5RLQAmQK{9e`XJ_ZQu95ut9NO3qwojypg_`S?*Ae@oIH5%ec7EkN_*61Z*j&? z+IZ)Cy78j(O9|-BD_FO#a33jQL z-J@|>mHzE>PQA~m{<-==JN+&uCrvRsSq>z374ZS|H{$)cE2{_Z!=F;jeb?fhUPs1N z)yL*0YV~6@b@TPJh~8oEG!ve_hW1=DYi4@ZnRIK{^O+-jiYxYiaPLou$?xP2*^H9g zOgN4o9c0DAaOU?+yeR`Oy)h9>O&rXZEFY)X(_!^T9PK!bPeyX_0OT! z1L}WYJewRngdCcD2pHA78ZnuoM#cUrJ>%z?(#4fI_w-?K_0id%Ji5z)d0m4em$L;zd7Ro%O<@ew28q_|}i6*v`S1|9^Sf+T-O< zL~z8s#|dS`DtiBy>~Nc@cEbMrwr+mJfvxsAmHa6F-0C^q zJWF$Cc)#%JjMD!JCnEJtuV>FPR-QNzNmF+KGj?Al%G?~E%y}|>2Fh?4`m-RG`%Wckf(Cu1ax3(Q-bCLv)BC)19bEm&745?FXx`R%@)OPO~aCb-uCDmim5)rG7Uf zX>C#o`%R4ZXU{wp>c-YsL(}7^$jaI={H#am3~w>$YMKtV&*)k4i}(fZTKiJdzCyAu zSCZyqe>V=MM)qf9AC#@Gbg^c<@yyWS{xq_y`RPtF<9n41-zR$W(+3*;P2EExi-R>{ zx}DS~^)jimA>~i%{dAvu954M5V=ubahqcK;&?&unNT1T2J>Em*w7)GZeJjS}SnqS| zZ1em<5LMUVKQ8&}>AZqU_W}5E=AO4(kvT3RAe}P(&im9~Q{?p|1=BajAZvCC%mJ z=T)Y}ui%$RD5~clsmSPfy5-5~z+zupJGIBwX0*rgv5PfAyuVJzkHSU09{|hXgH$Np zkU5V>BFP_KNUpQHdmcXa#P>`m_aJgUv*?4w`^;kd%l$|(KRn42N9S;2bC!z21I>DX zM`GyvCQwo1l1jZeDC&8yBoaxr!#YZ7BDW`vBBON{!2er6oKlCWO#gCPwi6fHju%MSQ)1-Bq zF|)*UzGf{eOO}jMteRwd+D*!M%00lD?a?mj8PE5?b$-bujd49?&G?D@2!EMsVK={# zk3BoMN2VlWZPy+AQuW*QSxW7@CF$i?J9_BBA*rjIex*q}lHs-VXAyH?>xSHf`t~<7 zCvJB0?)zY$>B@~~Z&hP*;!K7B57=eTjRgn2R{EOrmjeBBY1OeqT}5Adk?F_f>K^u~ zAN{VRFFkP_ikw}mKJ}ts74)G8-A&DhLL>)TSGrRXDdvxQ*~8!dPpakkvuN2Kjc}@- z-|+YTA~q*C?GK@4pT-aJbk~=U?o%IzWN|Ov#&-4LRC~8`$OHuH{F0gE`?maw*}-T> zANXPau6zzh{QcvNxoBk{O3ivEGRx@lt4~+6Y#I0WKId5{ODVY-RKHPunBn?gSD*Ve z9vwcEzdF^&^7pqt+u|f$tQl@j-<|kAST#0Ed;j^{-kW?V4a-4lV(z2zAXRusd6MPh z-rlA3Rw|Zrn)`ohx=em3<$k}Li%CC}vg`||4rM#~$C=!RRbTp3%A z{MN&`)XKc4-(KjNt*45+`OyWxU3!I)zCqxp_&>Ig-rsH}G5sMXXB8Tb$!OVCXxASh zNH4Od9|lPKE4ev*rr%r1I$xFi2>?g3z5m=mH!SM;LwnWGpReqD;AHl%>v4iIzVhgY z_3rspQSzHQ@9zthE{=NVL$Yhl*v5Eu<&E~Q9_02dNACVYa)$Ze@|BZ5jO#k2>tH_y z%)$MJJx!e=?!Zhnt@qbu*`*yBV?X<|U)}4=ME5YN_lnq+uV-!??aci%__R{A&HA=~ z1E021_xuO{OWZ^M9dqu-^wV4EHM8_B`@FgDPGm-NyL|o3=OX@}3`>5^uJ1=upGD}9 zb>^QsBS*KBT-Hh5p8>P}(8~VA{f>O5@y%)cN75(E{*B9ieCeEK4brCR9=~w*d)=?E zn|r9UA73^5P3htDjg(>I*MCxf_@hTBrT6ch{fc}4&?C)Ob*p<_4|{j{Zs#rf<~3u` z$-2r$WPZ7mvfGFBW2p4js4=pu|5J_W{VQCW%vZRRy@PCr=)0G<$hh|56QKUIDD7LV z|F=1HXumY6Dec>LCBC_GzV?wJ{$KpkCw;^x&j!0cVUu;z@Al)9ORyF_eNjqj|63oQ zWOTp(r|BQ>Snp8U`DiHJXtdpLfbwoTHl!_nKh z=`omx13aVbw>7uz)GjTJ$aAuLCI{G({%`Wqs?4L(SqtmZdcX7iIV0U=Q!ne;;_SIH zP8hpP%vy@WWG_AAd8t9R=k~{E`fTU+J*Ojq)cz?<~Ay6PtWsB&61{o;$Fc%jOlhK((*Y~Zh;j~U%1%85u+ z&R3}M#+rDtLWPna|0Q^OeynlPoaASvN|;+)-&oBb5$>8|tE}ViuItY??{7m@b#2W; zepIE3pDgGu$;n=~sJ510;#^o$$B|CAFOA90I9cb_G*wrnb-JiBy^ zy#OyopZJTm2zV`sS69znpkmHjP`|MHyd^jCLwe^esc*QkFh`n<-4l?{oD7FE^M zpVv@-V@=gLa~tX#8_%KPUZc-bqtD@IzRz3K*r34q=90;iV`I)8YbMW{bL0Z-1(v*0s!mHqRhiXELm2cg?Gq!@QL4Qj^cPsrfwPhW%0p+4B7~zpaPu zuh(yx|HR?@QxxMr*R@8aWKT_x^~+7iRGt)-%8@P3<+GnNJ)hsVRBVdU6X_wJ$9`G8 zq0h-=KEEtuT>ho#^xWBMPvuS3oGjI#QGWS;T1o?zl9Ha%lXYb)Pbpnn;+N^ykwoQ7 zQt74pv8kH;=Y@L0FUO5f#Y!rvHe}{arKFx1oY6l?-tApd&Y30Y`OKE5wwIg`wS=BxvXzsbKcy@G`ie0H)Ewfz>WrmF80^!hHWJ`cFLv2< zg&+CK)O=$Go6nN2XBvL~74jc$zGcHTdp{90JoB^-KmU~*2a3PX+i>Endw713`GXBt zdie*MT{ipyFPvxoWy958IB4>}s@jbicI5!`PH?!zki|laqb!Ck7FjH|IML!1i)9w4 zS&UkoWpTE}3X4@17g(&dn6TJnahb(tiz_UywAf;Cjm5PVAGEmM;s%S4THI)Hlf}m^ zZnpTe#Vr<}wfKU?Z5Cg&*k-ZQ;%ZNkSsZRLWO1a$ zLW`p;7FjH|IMHH>#VHocEKai+wODR(mc`i?D=aRsSZgtEF=4UE;xdcP7MELGVX?(x zd}gx$O%|IiuCUl*ajnJm7B^aa+)uwMS^*9CLLN^DVAbJ$D)NpzyN+v(e(y z7WZ1rQ#quEEv~WHYVlEvn=HO*F~22y2uCdr^@llJL zEQZw|@=df@X0hC2g~g%pUHL*5M_DYkIK^VC`aLdS)(Zy&%%j3f1LiSdfiateM`J40 zPjHCE&5Cabm@UHV0_Iua7GsK)4nAgav&B61llTIQ!z~tCEV5W)ahk6jy%rN1R%u&ME0%oL_9x$VXUkR8Z;dWz6gr5(X2Q6;! z!|E6D8!Q&8y@ZP_PE)=m0aGsA5HPcZ#|O-8;j_k62+s|eD&Zny76{J>nk~W-W3~#H z1kE;Kg)uJ*UkaE4@d<2Gcw4~i7FN<<;aub|{;x1*h;R!16rL6|BZd1IFT$(POW~}b zDHDE#b_$uoD}*-~Q!6|wXyU@>jY$aq8Zb@53yoPO{E{)v!k+}pa^W#SvqHErU|NKK zWSj_337WOSY2z3_eLv+&(Pvr!mEuZ4dOm`%d70_JhyE9jGO5_}St z1kJO;kHIhDSwZuH@O1bl{C2>+D0~Wi5k6o{r*MAI>=xFeFTy7HC;V=}>=j;Qa9qF- z;sFbf!vhhHXIu%NWPAwkK%a!`0%o{yCF59l75oE!g=slxGZ3{36DlEg{KBh zn{YXN7CsK2g~y?v!h!Hvm=`p!3oDIzQ+QI)WThL1-9P!Z!LZTxCpL_zU_ioES7s!ixiDnQ$8Y7QUN)3qNJdN?|+w7Op{G zg<}I|t?)whRrn2KT7~(Hcj3M0t8h5_Dx88H71m;hh2xERTsXj(r-cL2SK&M0r*Itn z6s`}L7lgmVz6l4xN8zl1*(vOVkHT{FRd_ml6kcM?>%zU*H{tYvF|s?Sps&Kk__x9< zumi&HqOZab_CR8J2&`YD_pFbQD=<4Bl5pM=c;(=7ZN`XqchU{(l!8Zaw`zrqd*-$bv3Mc6^% zd(kW5^q^@KUL7>+g|VR7Ae<94j|y)@zl1jh&11rwv1_vinBxy)+zIoIX%imKxD&E+ z>J$!PJ`^5h%pT#f=!=kr&R*e(j6dPY*tu)L5$KKZH0+%44D?2LCh`*&B0u5T$WQog z?2($WJ&G`3WyY ze!|O;pD>F2gjXUz;SBUtSdN|wuVVfZUX48vUW1+rXBpEZycRnsybgOHe4jDPg|m%W zA$&h}L0E-d5LO$rMmW!ywZaAXr@|WSg78M>F=4$i8-#IV9uAw5#%piiTs7Dk-xA7`3vtw{=zlL zU-)t4FIA%EdFk-u;g@)v#^`3t{;{DuFA{Dn^-f8l22FZ?0$7e0ghg+D_6!XG1l;ZKmi z@Hyl!#BNmye}?>pTamx;1>`UMCGr>k8u<&iA%EeE$Y1z-!dH>M@Gr<;xCi+QUqk-FzaoF(>&RdDPvkHB7xEYW8~F?0K>ou2Ab;UL~Pgv0TZg(oo|3s1)16rRGoEF8i7Av_I#M>rCHM|dXwv+(SIDHM*vj~1ST zzbT9`e+$P1OtFypb)vAC`CK?5V5SHs227do0{kA~g#i;4mf)WXFJitIPQs5CPR9Qc zmSVq!mtenzW!P`wW!P`wH0-zVa_qM-iv1Q|iTxJNzA;aBY)usk-zXm$X|Ff@)zEM{Drq7f8mFbzwkEXFIA4C4aZz6x;w~)W^JIG)7f5>0> zIPw=hf&7I}B7fmi$X~b_`3t{?{DnV2{=y$2f8mdjzwkNaFZ>zu7j8xV!e1bN;q%B} z_yY15{u22Me~tWwzd`=O-y(nEi^yO2d*mc%|BU>Fe?k7jJ;-19I`S9(9r+9Yf&7L4ME>sw|AqX8|3UsjJnJFCV9*o@ z2L#Pf;bB2DOqd@u!-ak3L~t8 zgrkEdAsoYcKsYXFmI+zUH47&M&2r)StY3xiVLc>d{m>%3AZXSIFT#HlUX1@HyafME zScd;5oQnS@ycGXUcp3hia2o!b@Cy86VKitS7tRct&BAMf=4s)ztP_OSv91-)W}P6c zVBICG!T%H95Hv3eYgsP{7Y5BvVO`L43hP-f2;)JsN7%@^OPC0ny~3uTc~iJFXbgVk z@gHOzCS1n4LHHq7Rwd`W94L9B^W=T!ZO>~vrz5XzUB^4xR=4Hvd9q_G{V+dV-9GZi zE8Dm3d%VM^w>b1>hu-AS8y$LsL$^BgT8D0N=oJp#?9fdP9e3yj4qf5Uvm83=&}9x? z;?Tto9d_tKhYmUPFo!O1=zNDZ4!!rkDIV@|=uU@jbLedjz15+&IP_+R-sI359eRU9 zw>tD%hi-A`6%O6(&`k~y9D0RAH#>BbL&qI@fkRg~ z^el&tI&_&smpF8>Lx&x@(4j*PJI}O)uGoqbc;i;aOh@-ZgS|jLoaaX3WuKM&{2mjbLbL>E_Ud!Ll-)9$f1Wh zbb&+XJG61=y>B@Dcj!)sZgc2u4!zZ(w>b1>hu-AS8y$LsL$^BgT8D0N=oJp#?9fdP z9e3yj4qf5Uvm83=&}9x?;?Tto9d_tKhYmUPFo!O1=zNDZ4!!r^4*wmx)1liOdYeOU zb?7Y)z1g8RIrK({-r&%!4!zc)TO4|YLpM8glS9WHdVxb%IP@%sjyiOiLzg&ou|tO) zy3nCR4n54F3miJ%p^ZcD{g=akhwgOfHizEk&|4jPi$iaA=uHm2(V;gubgM(Jb?6p{ zUg6Nq4&CI?afe>u&=n3n%b}wVUFOgw4qfcfVTUes=#WDXbLawx&Ua|z(0lhf{CDV1 zhi-G|Z4SNFp|?2nW{2M7&>J0kgG0AE^je2*ap)Be-R#g!4jp&s1rA-|(6bym>d<8l zUEWy3?WC9D18WZ*}M`4!zl-H#zi1hu+}O ztq#4`p<5h!g+n(xbdy8J9eRO7S2*-6hmJaQnM0R2bg@H+9lFq=Lk>O6p$i;3-=U2| z@BN3ve~0dL=r)Jm=FnRmdW%DEcIZtGz0sjJICQH+uXX4ahhE{(%?{n<&~b-e;LsHg zJ54 zlS6NG=nW3t>d;0!q7VMKh&YLU}$w)9%%y#TDRwKUDaN|`v1TG-M4FK3Hu%c+0*83 z;~jMw&y|^VJhQsZ7?pcl`$Wna5Uyw&WM=MAIqVzUJ&Jt!TQ6@P5WeRnmCNB2cDBr5 zm3=Jx3PSBKJVu!txi|2>wV67mQTDU~wQF@-pkQ^|6v_z{RJ2`mbnAB2`RP+`ZToJ) z#_c>C7)8CRBN)E7$2!U>KgvCgI#yE00?I6aM=GzPgu24ddpuGb3!0x87A0LgQJCG1 z!BeOwXx6fQ|93GN-o zz9Mv({9(#he)U6j4x-Lb!MctR<*J?HgI~Vn@{N7_cEu^LjB=(?##+i!K2rjZOiSlE z|K0aW906N0|z@?HJ(2uj)9JwBUdC zy)wcq?^Jt+BJ(ii`fXJ?Rc}&`iSl;V4BqmF=rtbCl=fltF9ClNmOpzgqL1;`?ZJ|J zUm8Zc0?n=4^P;QTRraxzlNVakLHo9wiq`Gw(|d^%n$RaY@(MoDu}O7BqwNEzt044H z#~||NlYS5Ns*D-5Rr!a}&ONt2(HUj$Pr6SZ*`-xE_fpQi9e2T_p|oo#^6}&>{R`cS z9^Kj@o!-RW;TE2Ad4Ed=?`gx?;+yIf?-#$B;=7*9uV`);uf_YaaC7^Vg658raC1j7 zye%u(+)+W?Y~p4S*92WbTpYRuIzfCB;T4285MD{Rg>Wn3&4kwz-avR0;cbK;C%l>P zR>ChpZ-X90yM{;Cb*z9V!|1EpIWUSIRxGE__c7j#@X!C`g zd{5eZTb+C-+kC}NzQ=4nS0{?X&Fx`iH42%HL??=n*)-zHh?_!O74$UXW4I{&wy>?V=X3T|}+lPdjJ7jwbz#*Ggw+#(#W-fylUv?KTd*g$d3B4ijr- zjwWr`vT$>IQ?$7w5pM3NrCnrRu!XcWgb#xcp^9}KH!u!{Te~x;0=pBJ z-TC-S>!Zs%WP4h3^}O}n%~x!ATLwC<8bVIIdyCz+cEQeTB9SNuJMf6>AbM4KK|CO{$E1i62+kCFQ*=+Nv z&9$a=$1d`WEV$jXc{kAp>HYeW+dD$xA9!|G?NNIVr@aYowI#nIX(L1MQuBmwuZQz| zPh)#H@4p_DZrgtC8L?Tu)b_m@SU?@#d|$%6r}8ORZIF$YPbQy8bD!Fx`B;90e3yJ< zP8dd?zCoYVKk2POX82LN#M^EE+V{$2`k;AU{d#;X@5gA5^d-uio@cJyF}!4z^k#c7 z&b-^)dbjFT8=!9+P|>>mHOd%Skev7Lr!18_!z(lCM|_j?Wwf!FIbLl{m~|bC&;4-w z(DKaaX zI`Q(A3QC^n90E!{-IZ~yQ$_$D`DI+thcbdr89}FvQGF=mHTvuKg*C+fcAVIUGTNLn z@|-dTXDQ%2GKhF)s^Fq>OLCXn%j%GrEh1_|7kpv zhwoJwTHfx@r+O|QTlgw^7$)AIKVK%SF{3^fVej6{^P|9tV3o!OZQDt^W;t!!rnb?h z7t}V|sJ4x=Z7Zf76S>vC5>V}{z<$doE#scX9px_PmOm=LRQ{;iz8C&4w{0(`jlLc9 z+x{f&DIwnXv%W*PjIi%dX)H$x`+n2c2>X4L4|zI$lC2*o9)SbEDPRDU?cYcJXYx!N z=K;#;@6+6St~lrA;f%%ncuPms-SpR7v*Yj;@0|VIOA>4YW#N2X2j{t25#9y^}WzEx67V~k(KP-pP3u|v|`eBk)}05Cs+pl z35?pjJM26fcIJKAfno6cINBr|ptaywcot@U|25A_Cp9kAMxnxEXs6_*acja++1r3@ zNglWMDilA2wtNJ?#&6ph8k(S5c`~DD4xis9!5X%LikgXKRT;1FMZ9I9)v<2XG!+RRsOQt zf;}8Km^LGSPSVWKSQyMc#xD7A-rfeZ+8)rD3Exeb=st21Z;LqNry|F4LcNqTjB>;$-MQ#m0zJ>vwGz%tN!N0D zUUNj|^Ts~E;Gg?;&FA*VLDfG~BT2`_Kry#fBPWaU`}&V^_YaAzuAD zvLqQNKY0o5l27#!a3^C_`IX0i#`7hj>?u=*@{fV1%6~KYAJ3BiQR0k~|6R0S`5VZ; zCQE+#6>k2B%|DO)wOR7d&d7f)`BeUOpzjmzgD=vXtB89S{Ca~h_LgaA->zDWQU06z z_O%_!8F(;s6ldGP1V(KdxDsSPb6>pZ?v610oF*TGwM;Q{ueS#dUu#M8_S&gKwzZsa zNkQw53#d!;mE<+r>drKDHjK_b@MpWHAHqHt(B~57&9SWck+F1j4*ibiNtdEK2730j zb%%6Rx_Ulo(u-&jzT;T!_0IIx$BI+mrPo(ZU*29%zCts!V=Mc(@@4N1J<_%(^mOuF z0BxwC4JDK4Z~?a4v~+YbXZdqoA^B%eM&aqHHeFz4aV@Aa-LhWg487)86S{|Snk;Yd zKlbes&&uJMr+@H7b4>yKTZH}&!SBd758)H9>-gSnr5- z`PjyutN2-N`Kb2aMcrC!PWmJ7CMu8z<j#M(Z1iX%WYfx{0 zM&+x{^60AepF8#31-+HLgLuYolk#qH@-#zlB#+WV5qv1xr94kLd6q!8*gPYhJl}Nk z)IrB>o(`*yag4c|PgnnF;-9#j19V>32fULI$GC3m)qD z7y7FG^C`%vkhGbh-+O(V68^o{w_^Ot8N?NVSAtMmezZp$1N@Y314WJ+Ov*l z|M7Qh;L)jhY8O#Yy$ljlCk0f4xXkNuCjcNQ0)>k~g483SVkGH~$!wKJO^I@5GX%0}|K1ST< zpp~w9KzzQ7IMshXZ5<3=FTJ_*iO!|y!yN+xW*m0}4^=)zAOzo{t=mV^9@%W!YVq+O zl%ck0-6s1hTcA1lHf-wFmuZ2uiNC`p%2w%JS3W!q#+h52={se4GNJ5GQdWKlou(|s z$yR6{5FZ|N`0x|rN6@#G#Aywe9209gp6B_Y$i?dA32MtvUf=i10NVHOlaqdre4S|d z@{R{7qX|D^70)Q&oxDdtmv?C%(H!yz;x&h8uS7OqbBN|4@k{pKlUb;B`+el|-?7!v z-;Z+3Hb|yTO*=daDgR-}%xkYlwE4ll)KuK%BRNQ@BUPWs_K2#oMseH*@^x-O>GS&VW z*WcbgoOtzhJ*fWe4V8NHqx{MZ)X_#6@^K~mk)footMb&&;d-}#?>mwBeBNhBhDF4c z6AlqSoIT@dglh@weMc4aa_C|`LpTbSgA2e~a2e^%(95C!OM4bjca(b6)?wEF+e>`t zy?NdoxrVs#*u!?L1-D!{c*ldF+Pw^UzJOe-z+ZscL)i*y-{_~H%6k@+ynhV7fNp${ zz8=Z#={WpUU*hn4Sopq<;p}4%=UKJkM&gPHtE>gk)1Xy;HFOoU>YM|uHY_6?gI+@! zs!Q!%3$6A(2>R{y&n?J)6u@WIt+lq+hVXZ1p5eW*ZEpenD>;SlI0o`fBk_M>4ExXQ z#>Y}UMf69gyt$Npqf_?IlY1`vB&TfcIjODkZ~pc-_;OWp%`X4{Vr>1Wu^T%Iqxd_m ztJ?E7-rKRY^84GjjrhLj+kBb)YU3B#yOcbRr(F3)!?20o{tR;0p3N}qU^!`>%!AUo zZRWY{zvNldj9#}S_4o+%d6=FLdHU_?_8;ieWA+)@5ZRJv^c;Bt;pB6dpi3<_&sNHP zDkD9J><06k+Nb$NHVAk5gbMW1x5bw$59!6!7hvtrI&jw%(vP4XKhIZ4Q#tDI3FQAP zGFxc-t+l_Nm%lNZKFF`rzLIRmEm)4F+_IM%t!j~Zx zcX;bi6PN8^Pou55{V4Nz=TYX%ode8++#l=IxIc`#KEQKDWAEz-pkGB}Z|`Vk{>IIJ zKzu5reD$}K_H8Rk>g_V(Hn7(;g*K`WdoFsS^8()Ok4IOBF~+3>dZvMV^2Y~I9(*_< z>hMWE9&^-=SILuKu&SMTg#8!!x+B>4Ywm1gygW_+wWd3pyee-bZIHbSqsIz|2*1qp zAKS@yxvUj@U%iBSG~dcDX`fKGa0X=*p00T~xlS0!{*Crt{JF{7uPS+>^LKySx69wV znnbx~GxNsg2f0`AY`Q=H0D1S=@u~M7`R2pzLCFQ4e~WgR3T#y2h2lTYtZ z_E>(*BK#Tde@G_GpguYzXZVF9wB?5A70vW_)US`w{R)Hvdd8xsLe} zb2fXZ$PN7-EcqQt`%-;jFIM$VexmdKzwg^sh`%wAG7qE7{DP!j`{{oqJw*L_wh)=9 zZq=)?;OF`M>-%db*W#{)9=HZN2w>@nfHGQpF(l` zEAqWwvb{0Xx}JU@$oj+MC}9OpKIGwIcNJPC`;ws zO*ucOjy!m!I_4AqI{BYPrm~ZY(;T{mJn~@_7H{6Kwou;;aFp~BJE`z=!aJyY1iW3w zJ&}7j_ayF{w`-nk>3CGS1kb0y^DzEQ=arOe`8g4OO0V`5VK*2byVtjL+f^f5}C#M7;Fp4*=A_%e07 z-alxb35Kq28xVe`&6pX?MbAqfU)UP@(RR&knQ4r}@33y#CB0R7AAxsT6AiVz8w}4> zUlH|fJ@q-yPuxRUQR$kQirk-r16T8okNQG0+5+M4w*|>R06weEy}?wS+bW%a_5J5<;eu5U7Z$AgnsjhO2!Ggocl%#oOU{efKIWmHx62kDPMc+i zr6>9D=ilcs?&zzYJFMXOwqQl;R|mvf`3jnTVKbSt$k)34QrfI{GPB^<$Kn095wyp& zw3UQbwcq#75p4qsKHat_Fvqhw(ysyZSmR`Ny*0f>zk(d^7bbv%kFKS;LoKA+I$54kUc${ zdgR-C>x9!E@%YRdzg@iEYvyeCpBYNNLUek7DQPb_s(yQGFnNwpc74Jhlj{cGKKSPo zM=}Q0#@~oX){gO&Z<~A}jVaj&e5Z~%gypBurV|3_jM9E!WyG5C1dUC-m-@1eLk1@( z&x^FFj54&RIe_pzKRS@K&)M`D7?c-x@i;9+79vc-eRclkx)(em3oN$!JOKBh5 z`t-5o|NYJ0lWYzr0eSTOy#F_!&(7>Uvu0+^T5Hy+v@vseBaBrY%_hQfd4S= z`DZ&_*0Qi^<=2>0lIY^w?0MNnxIehc-z)#EbZi(Im`2`@Sl^j&C*xhIr<3=iOrwLL z`HA4B^t*r7n_dt||9AMX^H&S;L3(*5|Es`nJ-(m8r!Gt#5b5k1gKtp2D9N1C$MGGj z*i4_tMx*{o1&J=vYC_Y(R7IHis_dsqYz5|o((6fZ$bqk?@SMuS6))ZA<7+tYCid*L zElGU@+{aTkUIwwP`t_#v{?=e|7-FoKmvFC|vL((#`}npE<=M-bL>Zs8f6yM5r-O zFv{PF58t0((`Uf3az*-3U?fK$k-ioAnhI>hxg-4nZBw2?-Z6aXuXm*XNLWl*NH~{# zKj*%ZV|nCvntWMXs<3jA@e8~MKPB@n{nL%G?-qWlj@)W+A>Rb>9RvL|ZflN|OPxFL zxojLvK6tquKaFHcW5;{MYaDq2nDfY|zNkEP$dY&i{ks-225$nVNG1Lh#@-@Ahq@f> zxS^y!Oj-yY8~Yj?J1@@M2i_L1z_tL!j1RK;+y%^c&3boQV`l|04s+Y$7<>Di;c3%` z=-PLr7u3IQq%ESS#$@g1(R%sN__CDvUf6br)~St59uJ)OuoFB~hV|@CHZWeSHSrPJ+EyQEVsbizIx!3CDo9aGV0}!k6{>bP;u{t{Fib6X3`r{48z* zeB563ar-^t4sdfj7^m?iNd|;_hoAl;A#&H_m%1K#{0q;{Hyq~;o(3hGjy(;Ru$4#p1pnMq^JlFZTf3vykfUy|B?V_^mJ9(mPo z$eUluyW-vn#7*+!9As8yX>H*?A1B&e@>^&XEKe|FfU$jXJo(G%WA;17w}qEJh-(hw z<5@)CE3Ia28+@h12B0^<{kX8RX4@$8X`M&wh$r}E#A&Z-Cw1oS&wdx;zltwx3HY5( z_yV}e7JH6x8{xBrFB3jZxS4P>;ReDd2=5_mCtOYV7~w*~O@yt4j}q1qZX}#S_z2;6 z!VQFK%fo&s`UmlGeSGSCeC`GAL-MJ=ZzH^i@MXfg2{#ia2saS^fbbr|+X+__-bT2P za4lgg;Vp!9gsTas5UwN~Pq>0m_}uJ=z4)xa?}cwOdZyNRjsND}Klyx!F>m}+uir)d z6|X{0B3Jq_9DSK@?`+6X^uK4wr}lcfV{=+{grglj@}@DEyj}kRoRt?VU$yw#)vv?R z-Sc^{PQicpyj8hIHsEa`<%KE}$tBdQF-m@G_31E=qrGE<&7|cs&dLvZDF2PLHIMRl zAfJ~1i+lPAI6=p!X%`ck?#+bQk=-GDoubv(fxDahvk1rX5Z6715NB8qZad{O0k@9W z6Uk7U=WCrFU7qT2pEP}0cF>u?S4t0JqiJ5gB6ohL6Il!IrgX9g$h4yzd}Z4`1gvcL z4)E2OJ!eHdUTR~l>@FNHQ58%ovw1>XLn6Mfj90Bd!=aMQc;RFY>N-?qTnyKjN> zH>(*p!Ksw?Vc)W672B+OdFK|=g5$98oB|)MU0i`(s(saV&siaL>U>j0rDvBaO=GX- z&i8{0_OR*S#y_Dx0G{pCaV}{?3%IK$&)eT+$Dpkr?CgGn$I9)iv{iX}bw?t(B@nka z`%^YipZa`oFIBZa{_Rcv`?KWNxOp$QYn>pcI*}ZFLNhWowd?NBOBW>Q+81;UL4F2A zYdS^q1EsUXbLfJv>^AwN#IN99l>sjD1MM`Xoa(3b>`j3`!F?%V2mU$BJ3j=s;uk&N zy6h5j&dH%qQrC-=kso2dA@x`BUdX#>c{TKl`0r`>P~^W~uCgM(H!z_{C^e8g_WO5{ z&Ue}*Tah)?dwy5BbTMUVj8mN6bspiXg2Df;?*j@}z28O|_B$F`m97%JpI*WDa=%Q$ zk0bxpg7?dt!uL9Tqf;kFymN$8qAQKfskX}&8^^covIDMN`TjH4{``ZSZ!CMif;iDR zN+=t(SRs1{O4T0vlXUT$-0N5K8h0d)_H>2%ihQo3RWo+7^wKiur1|D-<{YkcE%;~+ z=X<72_{&ExG=8@z<)QPjqw&|8F(A=Z9APYoFgEb5{jltPML)EgeX;C!O=*3{HRny( zx66BsXFT6#Pb}{`i=sYZ#~jJdQP8TGbr1PFUEZV6aU9>{`1bnn8q<%*5I+WaITRR; z$5VhQ;$1XW+ar+<=z;x2J^zBw!f|EfakCe>koQQ$tGgB3x|Ml?Y;TK)IdfQvEnKa+ znZ~xZZL%vwpJ~)_2y?_sm;gp%zQgcqNtdGLaiD4?5p1)JhB|hAG(l+o+<6C82O4*zER(b7&hf<#{?^(W8-V21q;J5L@h3U;a9XuMp zE~Sji$S-*1?*wiek8s%zjMjW!1#Up0=9q0M>DyY(XMh!q;yQ@?-2ULg`xkhhNxI(4 zcyBslVe0GDv00?Sz|oI;L(;YaZK7Ud?G=B~CmFbHDF& z^o!a1i0+VlMv+hLLuT%j3L}e>Rmr}_iH`UEafmaAA?F}$l2t=E1IO)Y2X*E1&e^LW zVcrXQ=L`zZsv+zPACga8apdJ8Ma~xD+7B&`Y#tIJt|+=?NU{6!kS)>9Lsz+v9~!}y zDRwsx34sfHgNHC*jI_CT<`FuwONvOB4H0+lMC~n)G&*;J{c_HYc=4RY8p7GD$n^F* z^9UX4q#rNa{=3f3cXWnV`i8X&`iZC43Ol{I<;lpF+V?%^t9`-hYx-Wp_kYmlV(#fI z;2FU4kKa4aUwEo`7IBZ~Q-pi7Mt2=$i6;@tj^*~hMpr?d7ItsS)>v=hx8?L-_ThoD zjg1w9uSa*J_pjz04D;?+L!KX7y6?}Fdl@oQh#W{)t&^@A?b*gPkVLYkKG`vPb2>!1 zhg^z3DUOZ9{9p8&3|*HZ^DB5RxeR$H{{A7W)2rud|2VSFcPVwOCw&9Y#lYkXhV+d- z%>Pj5TGDRkQTYi!e(QU^eW;DJg*;10lU*uYe@nh+2dqw?t#GPr+6#>>ta`r&t_okL z4EC3&YH6cneIRjP2YwoOIBmV{5brioeml>leml0(j?IgD+i?>xouqH$ITSqAj;*9` z_hJ4r_>I@Z>=6nK?4^MFN+ zkMItC=`i-MrVMN$=Fn5{zq1!SdPXWIy2bOa#u8lzlP15h_N<${$;Et&Us{{g+~V`l{rs04=WxPf3CjrgC!B>{ z73RH;M>dc8BK_(~?Bgxer~TD8?~u*F*epNyWe4D21HVgHKMuuZ$6@Q?H^>DSoyAc7 z!jCPmginVb?%K zpD}#b@uZ=}@D5}XA0ll?s-3b&3?FIZ^Y8ZRo*C4aK(6wr@AiPcddlE*Vb>wwLTAOV zPaW7HO>iAd{Ryq5bf=fH4g@*Iv*I}jJOo#Q)+^h7=WpB0I&r5CbJ(1sm^-M;pu)k8QB zVV-dHsv&vK*OG^*9&FF`(U+2wBOkmY8IX)Qi8aP%5Z<8`-%Wi)|1E$Xe@4cNqwp&F z1a!v_01jU!O=UQhYm6P58*S(;j$W63Tk=S~^r_cvJI@p!pj$4yhX$st8oOyXWA}WH zsO&5Wwr#fGHrbhKo7G|8HF{`S>RHmIZ=WVKvW~A%-%s%U0nbre9OvQR`g@(gUwe^uUspVTp7J%H0(W@i$xxASr|cj5br~Cm?|N4eltNL05y1b`2V6>jv^lji&jf0`=amcKh{SVet;s^HLx6e8aD23iV9sqn>|KHaeqAXTWSb+lb5Y>pRbHXE9|I zQ-*M}`t<|hMc!y2@0EePF+cA%`sFq=X7uKL3pml~p>A}#WYVW`4e=qr?q~*$zvzG8 zPI>C%L0n#-jHSdcHSxW3wV$I$zB%&F^oY+pUGqqvN4my|p@DHChdQ+$6geix_|#n1 zSxz@~RiL7N zK1>*Umfr&azMSuF`u+sseoXl5=UB^kbq zF|=)&*)vhfyIB*7K9MdZe;Ke2@8fun`R`MBzlitRBhbmdEhm`2(Uw2+o?^@sKxaAdSd~p{|D#(j!yh|kSKja~Nc;_b% zJA6?NbM}M6(VMpk_YaVVV%bL#jiYy@UHG6q#_|lp|V<4D_QYIK5$H=YlTE#SZMn zce#(RY$}Vd8OPOj;fw8*2fTdNvZJQ?I8Udp=@~e8P}aAy;JqXZ-rONo;DYxg_A3mf ztf5)(&Y`^5z&n!;t&|sX;$2R4A~^{@8J-1bf~`;@`h*!zMehQ~x#1x2+JwFt3!SuP zxzX1*K{~yS{K?i$02eAxbXk2SdY&Di=T_jB0OKMXN*hqK06Y5pt}#*kY1F6nMbQhI z7F0)nhx{-{L8fw|iGxWW@-Tf_c}t0xkL&^e+xTtx{)zuBU(H0m|DErl;5-zZIj7rW zx3@x{F!OBby(48m0pkE8AEDKIR{$d!6i?sdoymB&_WcY(o@C3(ZnipbDD4_S``giB z?E%~H65yoYq-Sn{_R>S8jGY^SSO0p1@J-^CeiNb69`MtCMkxJNA^pT2qTgUc{~7)A ztzSFNl|0Y#T|-zxxCUMH(Pq4z=$?Pjf!FaQpFu|vw-uN(`0jX;-{;`{C3M-nypQL- zi}$6xOW$4jG{2`ocn;xBg!>Unf5}drcrf>wp~uGOLL>U1Xk>I4W4m;i%Om}D1nn(t zVV;CuDMc3zj4$tWAM*N@bdmIu^iPEJdDyO!0qLc(O6(=(r<#N3(dH-Mo1KHNLKY6e zPlSIa#n}{Kc;LxG>e5;8iR|Mkb`o8GCr?E+bAuHcd+;05_f8fK;hA(mbj7l?Xd6Yw z^zEX*gtyMe=pKp+zAO0FxtL1e+!g8v7j@};wiEqsn(^zo>GZpy)bFC#gnRz{1+2le zrRtcIg@L)`2io64K5SXdC1f)z{}}R!mu{PvRvI0ao)5qGW3DntdIg$Bsay3QfV_N! zJPt$$e~3(8LO-`MSx9;RY5Fz$B`HsKS`jo0M+f7hU6vk3ne2aJPu-GK7+Ap^uC`ES znDW|&c={Y2TaeFLV9A?kE;?KTTpRZM684QLpVkzYoP;lNJ8i&z8044twE6Ds3wJ3V zKcDsMT?`*$;2#5bi}zY!Mu3A0e>C>W{v8aiPMf#Ra|e026`^Z5cqvUVG4g0U0QV9* z&MYQQ=Vz=hLwKG{UUR1idTirp<|EP<vQwq=IZIe_DBqH?2T4oNUlW1; z+C=%HNe5*PC47-^T!+{Hl;?-!nGF5)emC#7KX3NoCAZzgYyO~iNH&HLr!hqMtRYQ% z;a_{6dEis@!^hbNNMHLa-+!jBrg>gy$JU_leVe{~EKi93*-l@*_z7>1V9_6Uc6U6@ z{MkRRAs+=g^x#l?VvEzB0GjoY_NBRg`e5x>(OQQ3vG#yyUXmO4aLZ}K4s(u8hpO4v z18(X^!@(C{bZVfxg#OAt5!xYJJy ze8n5)Vye&OJJ08BH8A3h;4k&xm1in2*YQk5U;Y|8OTRH!NDe--IoUC~BdxuzcO69i z%#G``wp7WQMht(HPq&c#T^BlxCD>o+iJ{Q$&38Py{Q+7OK?jYkR{tDI-I9X>>W)+| zOW(|Q1RbFME?PU4OVArj($5+?;>%H9Xs+>~1w1vrIPUfAb7Wo*{Y%$-`-bU9X^lf) zQa*fBdRHINS-w*A7<;`~FIdZ&y(LC352aqMk4ZMvpCZ(K$g+j0`^Ya`RHya}seX~2h1&l=eQLW?jy-{&rHdG`vu*T z030+bndaMv18JA?hp;)q?gH-Q0dM-%dSpW7YYwF`R`@SPHYD5QfOpqJBfn2Zkw5X_ zSoo~|rapZH?Wlmy<-kW|n^OPz;8)?__0hmW$FKU+p~j2FY!eE3%^rxgX#hHLqhIr=oa5ADaTDnSDkOYJ6N zzUu?^jrHsMBVlHJ;&*0!?OE!(mb}8}QNl{x!%R7q-0#)5Z+$K0OQyrX$hWR@Z+0x{B){sJN2vai zul!SXEW!v z{Vhp(u?O!=*JAsRV}2mp-}+djbJ(YwlHOK(meR(VO^hRq0m4gkz~5-nG-eHSsRvlC zH@;5Wm6nUoOnEPZo+E*g4-NahWaH)1jZ^6(o=;5Uf*XB0{RU;q7rXHg_OlIpI@vMo zaqd%i+>|T2NPd_zL6@&}VGA2OS$#@l*%>Mq8(KWlxfdtCDlMFD6W$ST%|-UDUCV3W zUAX;3xP!OKKOY(?yb}E7bJkeN8bH^^qZt$8%Tk~F3GGMjH7@9`0r5m*b_sd^H`BpyzYxJ|~812_JmAnPig;R&~xE`MEei<>pjD>+Ra;Q)B{+>AbH>B@X z-sk=D&Y+yXAtP$rRlw{A%#VnxW^4_Pt1~EDaxsQ{t2=t<3Eu~{jr>;THc^J&Ro-gS z^saozk?&2umtl(z-^f}S&tl$Rc?{eC5zpQqk=|*}foNUKsm4|+l)aX~uOvHTS^5;p z{$^Zu7`ll0wz1=4$PxD3tf=PRx0*d>5%!n-6nrltPBIye**)I3_Utn|2z+$khssyk zszY~<=^irSegkz$Zj01b?XBQlwE79pJ?wg{&hz%5Y0qVu@I`*h91mZWr#%+?Q^wkA z4`1z*3*x)b;Op&)6TbhsjeW7i6(QTbd*v3Ur&2~W@$wruZHcbZHukCXw5NC9oM zl6gxy!V`{OPg|}xZTT8yNCwK(7S=A+mIHymmghr8`c1TDp=}TI1kDZ1T%g*w6DvKv zHq<#fEj;C~czHhl5p3-BX2+dZCUV^ohP5rDy7kH@UL~7 zwg&Lm9YoH04}a-9ga3N=cd@s>h%mUf-=0Od0z7oKM7nh7diJ962v>`zcqcrQ)GIvS zB76Zn2T{M`-|*vK^YKz2RQp!KJH1P;U*!ECJbHhgFa#g${9!0E@zF!9VZYArO(GZf z@cWX**zUT6k~vUUG40bnGsWc-my;1!NL-jW-JNVi( zHSl+nt~1dIAN~gc`0oR+vyEf6?d;i$dJ?o%f73pph`(1b8i>oyLNBaKeELA zHA~!%K-~LXJG=L0Kkci?yl55NkK4iTn@T?SCjYZp@~`*=`8WFcBZ0dWD?dU0d$ZIZ z@$*OMM-gO8zB}!?F63MGpZ&fE8m;5Go5%7{`?V)q-e`Qva(-bMbe8Pez1`yJm&qgj zYtJv(y@K+KNDk?@{qB2L9~%dLW?wk^e;783%Wqp~EI2~;3iWBfKr8i(t6ZJ#sOG#Y z^~GJzVTPUp7w_!rL~x6ooWmMvWm0)q2f5)@r2{)2SPOR=aJo}OaM*u095b#iHMg)D zANhh*R5ZeWmFpz9c@_V`z#RO8*f{8dLXCCMMdwU|G?NUW>vC}#7G$0aIi0$O^LRRZ zGvlb=XTizP(df1I^bPbMe@shSI?BIh?tArZ=+Fx0WbE0M?UNHvB%dWuXLNPCvyyR< z{U_{YVOsXJu8HgQ?UZP2kS)3yID94M{OYyfGLf-O=NwiIOm?30CGWh1Y@?4-(1kRe zXVtj_ot4l!r09kXVeHx@Wr-KFC`Wa3K3a49g8WMDgSk+9rV2W%SEsj=rg1=iaGe`{ ziL&)QfP7l77H?S-D3LF!o$;)}Wlw6vTf^3PX6FY-BIDXK<=ut6D5bghkHJCsYMlC` z=>x2{#S#az##GWq8TKssCg8#`-COH)HwNM#Azpd&NPCU^^4sXVx6XR!#uB*$C`-H- zokf!g;H>w*@-Dq)?}fGJKqL=(Uw<#_+xK%mo#(4O=kmyw)7eJxI@CtLfhVFL_DM=S zl#RH5rR)}LQfwp7&ihUJd~o!9Q}_whUSuqf_T3X`$3o&mv;n?%uOMEwr|72k->7!E z)J1*5`ME$D@)uhgRnw*%$|$6a9B?rA)xmS+IY6`}je3pk{V=e0tp6+J?c`f@{28Hm zyMs98Gv@)Z34ios$N4GG&w0Z5#N&)rI_Dx<^xO^mTb+TKzRTUPaem7t3{CQ*Yqr_D zVa>UjFRe+2@FT4}auIpFb2HiptTg4Z_rhwN)!netd#Y1@G}T$2_b@!>T#s~0^@?<@ zkGJkf)Opbf+P6vne~fnM%&p{S7I&gNN~klp8wtnotv#s^^Zpg$9wHPC9w6Mw*}5Yr zGkE6q*TjEF|NPy7i&EmF?xY%wJWU`R;nPoTHGSFH6~8YA@Y8wQYss%O@dpvkBh;8H zyWs#ro%bF|xuQR`*p56UrK6%TtyxWxt&l$k9jpGRyO{*{ev_5UmBjYpZVU-V&53BdkWAFxp$c0>SnJFrF;V#q?J_Lr=HE*Ek?J+gq_LIca63M&7lPmR`Rp|SO zH^-Dbb`r031k>*;y}9Tu#ChX{H&=WQetvNGIe5KYWICqRb*7z!25(_Qb zjy~*itDj0sH)>Ch%KnIbJ@YA3esR+Ws#zO}pbrSGPiY%6VErp~z>YC``y%xA0_4Ql z|0T+=d@*=6j=0mPLpou;2{~6u89(O{-xaU-%}W;n%w{erLWCAj1pj z;9wi(A)nCD*oKAGE4H-*EBW~b@B?Crq%LZ;rmtf>WlPzYTJ|5@n1s>z~5|0oxwRoHyz+)S7 zu??F>W2HHx34ZFM;cDs41*!JY-koBz!RZS0l=%I1-tV9K2<^L&^(gi!(YC_)if!V% z-jAgGfwWEZ)*7tx{2d)+{Z$`IANlK2f973hV6?|wI`a>daVYDR`Mi(keVU(t6Yn~Q zqdonCla9KWZ^7-)yVf{WkH$N_|EUunD{{7qP_&nCVaH1$a|R_MT^>s$e@8y0{g)3D zq5r8r@9FOE{IRGq3m4ujFi?0RL3}Q%5f75SdUnA40KU_(vRQ7 zUN&;miJv(7SlVef_c?MG)@0e6=o0+yG3^g#Ukvh-$Jzz{uaa@dUbuQ8b$a(EYagx? z6HP8mhT3&b&zyUGPWCy2EcWJfBae*DX8lp7)&r9l0cXmUelmCvdiv((ZCaaq#>YiE#A(jl4WxJLu0vE?T|&f?w7e&CM_lzS;~+1h5t>piq>MWAhwKH9b~ zwEu?R4oiC@gU~o$&Ag^k^ya)Ae2`Bt1n+Z!4~`{gn{nipcM4+~Te$ndS!Bi!BS-M^ z0AxyYbX0SJ#^x&Wi+-2-^%m2v(|G>C_k6<67eh`0V2j7BKJZ8)vq3y$TgVsL7as3X zzVM(!6i6nf`SpMF7Qb^qy+7x>hVUZlpGW=quJk)=zWi2}Y#yx#F{dbS+HX!rI#(ih zmn93^S3aEUCLYLdU-?69T=w6yW=0>={106a*1e?>bb!_?bDhLp(hu7A5voSkNed?y zr$pnNIBQ_gR_#%LrC+oE_tv!N9brF^_Q>SBH$P1JL+oMwA^5DziJ+%Uf1Ye;TZpX7 z9#dYmZzyfi{8H~u^j7eYUBW#|&LWeaHHQ1b&L#Xd1a++-o&K2XT%2T|);i{c4;91n zCD2%T>G$A4pKGJ<^X*V~5#I$--Pgqad*F(w-)UPUpBv}K7ZYmU{#06WpuHfJ$yNaT z>*z=IL3=j>+&1H6HGGg<{K3~n>Q^_v<@dwLinQXT8+3k%xlPKcX3i@9M2<@5f=^Cc zB6$#P9vbC53iNlFH-DA3X&qm>LiWD&vG!XSdXg4lPI@l;xC#d|$6;TT#=Jwo-_8+l zQM=HkPNnq7g-Lw7xr0Ps+RZ!dV{ZUuu6JKbUf}Bd1UkNQ6=xE4FVbZ6*7YgIcI+J1 zLZe%flcR$1eiJHzyiQ>6=Is&om^-`IeKmFGV;5>Xd!Kfx4DH2Q?`~lYC~+`t&K>N& zc<6ff$-$%z;e83E-~ zcCVXwdQ5<)!^G1{Xc@Z&*__hD)4cw88uNInvq`-?)w!8nd8&Jy#nTRW+TrswSa*(i zijM*x2>bgy*$GEn-66qx0Q6^EE#x`GhwGc)Yj)wc+M)F~ox=(8+m3%uoIMKWE|SIR z#cz83?4Qt8x?v;VI-fX@KEnE~kpp{{Z_`?gjUPD97w=@xD({!^{s*3rEB(d&6zH;W z9KRMaBwaPIT6%Jd_U;x)pE#^D%jdlKR+{Ib4hjUc6>%mbUX=~C& zZ8|%nGgV&;X?=VEv|?@1=*XAQIkFYddB&IV@6cpF^0h#dBJzr6MbSlRoqNi2*z*ft z(7j!S@kNYvi?}0W5oR7?qpg8qa zlODN|^9SEgOMm865{FH6EA=|)r=VQPp4L5=>tkD!Q(_;y6N-+wXtK;G+V(+8p(`-!T7SAE|m?nl%Wif&D}IR~3FU*YKOX?Tcjbv^AS zo^_2-^o2BgAXtaJg*`6QlJbKw>&6D`%#DeLZQFCyqdlU< z4tuL8TWia|pS=u&j{VCq?xenjPE&__0~ z%0b6>Jw{oo&%?pne=9uhC0`MBtfhZG2d!4qKUe$xGf1lv;AA5+j&hD%W8DJ=cgB78 z0$-p0fsgy&fm5A#Q=jmajRzjxf(e7igVC+D;fC}|AO2k*{ubc1Mu z_dKJ@=Xw)iQcnRFcZ?W-;RL+G(Lws;qCduxl^IaXhDy(N_8+3}v=a8Gl+Rq!G> z*V{&Z+4Lzwwf&B*JKuehXF6~Lpvi~rAt#pCyOzOT%v5o;XHN{p1{6PK+YbeHC_Yr# z5@^YTPeUJTFNXGjRjH0Rwj+9XeY7K~xrz1&A8F1hwd`ukw-2Q4kB1Q_n?tyG zbErk>)x?F!gWY6&pDXy@NI7;LM80A9g^leT_vS;gC9M7YBCtcFoaez#l8!TTp=xg~ zWNi%D5+T_b)FT~X_PAiD>_=Vf&)J2p`RuFzBy^PydITJ_4_b7RuVz!UlDXrH?`(?3 z7+*cVO*?h%=Q5|n&QSZ?_?8SSzvfr6X+;yAD?g7kOB1C};=6@9tWS7PGQ9;pe-fE~ zlk$TyeFEQ->Ej6{)7#(J`R)PK|8IPsPv|}tayIUTOmFB%rtc%|(~#+I(S9FgdJ*l~ zlT6nEV`chV;G8MbmlKyM({B-H`6ph#!FR6c*0Id&_u7+8tIU0s=_%y>G-P_U=(-1) z9)vsuWqKsE>Px0&3t5^-rf=cA@)R-{%?k%aF4b zxxSaj;8O`M!l{xqKb|Rt>F#4^QU2&=ae}1=>^=a-jCM+c! zPpI{v>4Z}VH4X^xqRP$ba-Q)#(|N+N#4c@k*0f=JlPJWC0)I3x7 zQ0f*>rrzi{E^}#jnCFW#;|TC}eVYEXZ6o!nzSn5Ow5EkA-35p5!`u_6b5?4j?t;@D zaN3)syQfz3t>2E&U2u|P-TS8dq!N7J!*eh18o#v0rTjV{tGk}$d)`>TFujTA3evSE zrt$M>>bB=P1*^DP(r1vaJklHW{`)U^F9Ap4vJko~;W>=&rBlVHMAr(1@L)CJTAtf^ z?&ZF=kDN1;I~?z>)Ahu~p^wJAo2X|kH2Co6A?Iv5jopuhyoV$|{HB=MkD__L+NwGG z4B(wg&W6jMg0F%7Hbe4V-P?As{5>U#7i^esH@apB{eQ?*>X9!}_2x%()|=n*rY-V! z3-(;nucF+0182sT&PP9B3u%upzL5g#xMZjr9AfP6!Z*^2Z^Zg_Unjpy`#UJpg@&Sm zd|3JMMX8AD#%9u*hkQIne(+=GS9)vdPm(8SKgfpD9qk&gbGet>tffP5yN<4LLO$G! zkx$y&{T$_M-1{P-^y{my?R@uNJh$@AnKgW3ccdi?8cWUk12$xsb0GHtqcoil4CB8v z_;L2b_>?NOcLZKmE=WsPn{fi2YxFKOP(IDUy|pqY{ZEy}w`ln-;8(CmN%AEdOE9{} z@FMWhyz5WE3g15iC;WBJ57rw$(st6cZ%65WBz-VEQJd_zHRh3!^D6$0|K#Z;)85=C z_XouzOQ>d!XzwdnkKOplmbV#i3&i+rF?ZCAl)Ro2?B?B5Cd`wO-IV`WB7Xk^9Oc)mByVLP z@9}xYQ7LnbV(Q9%Rc#G)TR6Jbnl$%97A5olVC(A-F<29;zO>U zpnWQD0AYfA<`z(Hf;;l;`nB@ke!#56RhG!0WEQOKws>@aj8}IPC@4 zz+M2=r+YSaZ=Yx*UAu$2bibx-tBv5G`!#jvpY-hWq*;BLScFdIkxu@_tGzmP4KS)( zA6KR2SJxgvOK0Kz722pgGe#_YDePYN5;}5ASb5n8N>?r+ z-i%kIr7Znc`fXlLUX}4Ha0d6(n}kLupwAUA+KL8B`vdQ}hIWsqL*V^7@pmqEoILzA zcK^w<((4ZEc-*t2zPI$BJKrs3?Vtm_KBbcLnT#{)V>;WopR;WHCUm{-mh$~JrUGfJUh7Q+$4B0C81FPSv(b%v4^pQI;sr#XRXmG7$ z9JnPtpb`1!Y?|(C+XmltKT4-;P`CF!s99}^gX`N8xkG%~kE>pmKAf_}8|iw<(v9F? z?F1*5=#m{JJg)+7C^|%YJy&FudmwqlGo5YU54aV`y`2wh9MoEt8{M2f3b+p1v18cg zq<&W^METXg<9FyeZ}n~J6W>LT2Wj6T()BLBsP8=6;mrZ7S8(sba_(JN#C<1(Gk6}j z33<@kN(?you6xlp!)NIj@m?|@erumAw)eaDGbSJUE%ejPcbYNtp1VA|F3g&&?2>%O z&eg!^_px*biq;7=4~ig9mj8>v%l5fbp#2i`OFnD)^rsT-Z7TrhXQ)fMPW+SZ`3`x$ zK$~@shwjyo-oh5ZcX4!jF|bP>UY*u>JBYkm-_Tfl*B>;GzA;ryy5hI+ExSTAIi2#H z^`1QbLhsHr-5Y6sLrCdOz-msQ@kV}G-TQPm<>(xLus=^GubI!|Pg&vL$1z0ZP{u2i zAwH;Ho%hvy2k-Nchj{`0vXpYwmJcY)+}qCjg5UnSpKXXhTk63L*~ zp0?Dylkk~S_Vmr$9t!)&7Euo3O>`tF*oA zIOyvzUQ5@gy+?^I@Ji<@m9PE)V38To%FKa~WqY5N=299{1ot6lTR+UWn@TcBJj83!e;fBwZQ}gv^Wd?OayI(+QXPn`XYG>d)FZtc24~9M1?RuPBjL;* zv>u#w7o4}Bf_Vz%3fCN`ty6bvRromDy8wgt#(hlMce3C;ISbypPpcTbU!(jY@Gi=N z_Xx^+O>&n(hc8iH$iGkP9Qa~*6rc&?nAv;EZ`yT!l zMLHo!r-P_(2lcH5E&<$X;8y!^Zh)Toz_kIR{JKla_~WTZcMjXaTI#CvWu zv4FLW8ze{4mjeh%FJMo?iP#ro>-m%JqMz2%IL@trhNr@il1d+o&A zuvu4M-uVO46zAWoRkDMAy@P(ObSndEfU)xUByx&w;EeDcMo-Ben}MuKFG^m&O!`UC zVLj!n59kNkpXf$2A87x*rxSE%ND6rMp-zR!lg6Blq$}+WKkYTb0^-X%7z5BNPu=J^ z|BVhPqyK-7_vuR*3wXcpI&4?I>!H>?*JID}{+IcVQ^9+Zxa)W?1rB`J83RjI6`n~K!3>|eh%H$+=6#BOJ zJ_;9^lFwf}#J^N>vER2>&`zzVF(2&;BgbLnSoXr^3Ktei(S(dg&*6IDaQ4b z?y(%sZ@~zTyr}%;o#ntq;iKxvrw*m-9ec1uXU@+h6uyh0rM-hkdpq;MI>Dba<+WCQWX~Z2S{mp)hW$6d0bJ}T(%(}(?(7CVsg01eQKNn=) z7yM)DlTJL7P z8Ns`?;lJR&i|%E-S5nS6%E^J=W7Nl3vk21Um%zM5InR8TJKd1eF2do27Zc7!R-ZvG zA711*KO(Fl)R;E~`4nGd`)r<%%|cx-QO_pmZfsqA9;!n!vX1iae*hov{n$Pu@k?-~ zKl9!L@iC7w&ZRHbH!+W5yb`UJQ6_T-llBAkQ;!HLlPzZA!OK=#Or z%O#h)-+OQe_~_n)6&d#)s9ecqy-)w^s82XO$oDJINB1D0CyjkF)6`Sh#h#%O*)Fn? z%smJiZ^MZq7sCPVZKPH^w>n!1a9c4&1SboW9;)=lN8LT}82L1Jc$xlc^fi5SHu5ZcBhT%%oAOqllrFpEx~Me50n5Wn!N`eqIEZ6!oPdq z8(HwScMr5GjedC~PbU8Ra`(X5;L+dR1LB?Ve8R_5HpxAKy9YM;@sIj=iRZFGTF9q& z$@7y`9w>!BS_@K~8<9VDL6?oQ z>qH8*J|W#MKk>uhf()2-A`9bCr`|I|o!_7Ma_<_`1n{$YWwVnfblx9&(@)Kk?gsLo zlqG%nE4}$A(Jxf~7Xom?J$R-rA9-GA+YsY7mILJ*&F3u7sI=JvwJ|5lIz?y(r zquHA^vi~NZH^*9dkUi5d`HTGgdpi4`-mFKlnlrvC=`{?4Y~wFSF>FV3dl3f%wpZ2F$gjgN(Po$zc==f+0^ht0qm zEII_d`Z_oMb>WN+)8D!A$&{sXUI$in@9nwq@xZH3&m;UK=f-cQzRYvuhZCoczH8B#)u}R!`3)?Ml8CKa5bkok5)FWA~OcL5r(+zQe=VYV>Y@=a_#9 zE?RpW<(H!~Det|sv)fxM#}ADiqjflq)3iG&d&Y^#zF3z2g=nGi+#jRsuu*iU|1M{g zNYmWVahDNtetf5!MhzF!As z>)MdBn#^&H*TN~b`x)bZ16DFO1NZ^R#GcL=f8U3nnh8(d%rnO40He0<>5Op&ZLw#2 zW6DEWTI1P_3~qKkzm#2D37+j;>!0nt3Y;47*=pV^TWDdHv%Ry47cOO#KM-1|opv3_ zAB`Sf<6+ywAO)~cZux-th@VVy5& zbag~?8|hEy_VeGG*HHOxmZA&ly9>!Dn?Qt-o`I1;|+NoMEMW zRM_}xL$-5L;JoxwHSK-pn%}tV0xh(sO5n0&5`8(8kO&F`bex z`2Ja+i76MoBD0hle z>bx4dY+C{O`Z^O6q}4aU2}8Eeb7xQaxZm#M{_bzRy;)2729Mp&o&CaxU*W^Q1$^e2 zn0)2}bLv@NrEhI*q`%cU&aIdGYa-R^XP@o)^j6VK^oM5qdM2h5S=yU3F-Jg$PwPy~ zlSY1f?fN~PiFuK_?S2W_;79T;8~kuWwf$9i^DmxT`92+*bS?`y?bw)hp4QiymzSCT#ATiz_$_fE z*%8Q&Z1v~){x9ff=XiTMKX90#+rFKN8BblG#`%F6l(VPv1OEfees1rXnA5@k3gmbEJ(A3i4`y7; zZHfNr?OgD7IwqyU>+jfRe4P{7PYlixaE^ep>Qdc>QSj%zrwsJ4#>PvL2MbfceYNJD zI&GYV&j(&{TDw)K``k=hoWs(`Lt~ZoRmxHw+RK^m*B9bF8qG~b{q;i^+OEvag~o$eclPkIWwiO_hbcc3 zPnFNQsKG}zX~?IEcq-g=FNtk~;V1Tp>dKAI@62_t>-1oJSn^8-f;?5ac&fIEcVT$v zEMd--!M7sG8nB{?aJ28@huT-9I@zZ((8pD9YTtp-DBo*ef$AW=I|7e>gIt?3%zh3p zFZYTV83^KGWnTAON`8b#F*0xKmmJx0iiLyUX34*B68+4*OFnH2sJ{prcr?1MvoOLt z-#PAl_PxABe|gfRd2Frp5VnN_BI@+IQ1Kqj~*_t-_+H8JM#_AF^Va# zkhO31rz8Aw)DG1%Gy-kF_e8B}M70mD7hlTnDKA_3u`K1QUj*^YaclVa<?dq$OQU^M#wjby$-R{z+pe(=q@y?x=p4v|n>~n+2C)rZ}y^FIqnLI}i zvPY|z?zGX9`+$6jmg-}|=`v_AC^{|O68)Kxab)mOeGAvgqzwdSzv!g2;=Ut2LVOSh zegj}P9Be=N3iXQJ91c1W{fwODMz2Fp4@xU;AoDHTPD_i; zJ9j>+w4=Zy0v%OG+#he$w`{#u-t4#V(E6JCZV(UJf}W9#(Y7r8=>_KH<9RIagMCRh zgq8oReVPY#bd<58kTG8RuMF8Nk9ab-KeSa|@%rOolal+>hA+_`@W0KI&0gJOzlFcn zkcEF4xZ3`B4DpBi@>hoZh5F&W_COy_T`exUle)j-fI~!bm(v-F=63EMnU;3jPp2Q% zqz*ox`=+KZN{*^rlsxEke%lH>*$bbEa#iy0v^?kb!hn>+K4!|w-;n0f)_n_X8jTpQ@l|yix=L08WuNAkEnW!5 z&=eSjw*Hd>w6(e~n=Z7p-BlO%+PM>JdueO?scg((U%I%Twz}Xbdr~;$Ft*xp)zh`& zNw2-tAD-U5hr8-*`Gh1BURjN+ z@4Jtx4=RuL#|sD9*!nK?zcsh)OGk}iY=|;8R6yG?$ix`sm+T=M1JJDl&~*pWm+xmE zzjS}j$W`yic2T_MYY}9az1;;0k?H5eYxGz_2ROOBGsYKaPWSJG&l6|LkE}BFXpSU2 zqqNW3sxSI5MWhKfB069fGfo!hyGXdHFQeb~R2DyH)m=dz?aRIx-DTPW&e|h>A-IYr z=zdd<%9U+a?(1sdbVn9@AGtDp=^h_X;Wq|Z(A+J|JS9hV7~h(+tPJIJvcHD?={{W} ztJ3ApB=(bQZr9u9U|)rXrhMVW?eu2Ot$wO`kH$^Omf9|xQnbc4H#UdkZt>^=K4xwU z&3@0k$im4siIOL%>+HA2_72ui#NQ}**|Gf!;)C>frJu2@8d!~svK=j-Wb;}cX3|LW zmmrNab`_hp?cNS>A8T>7y2O49_u?$Lk5jzL3((FhzgKR=2aSV4`5O_y-{NfNpH_Yb zLU(vmV%p|-a;iQfe}?U|zehJIUGW2gvW$G>IIJ;;94{T2Fy&J6Fl-rvgt~M{o=r+Q%3eoSW>xIb_H5i_j-A^vU=Lb0GA| zL};KsqA}3uCgfQ9L+`3j{o1_y^~=T>A2}=?a}GBXflqxW86t8+x~ZS{xM_zZpU)jW#hnOy7EM*6Pa4a7*XCn zDWy0&-etDm=$}CQgYxpx^j_Kj#@9u}onzdkT6fzsAEt#ssCQEfu7f(Uu#1dIotM zVNRIOoKWXGgZ_$g9~bpi;iIuoehJ|vJuZ0_J(Ol1_zly&u}5*SRmQJT3jZV2FaJe_ z?|&LBJA(XW|VDN)a((9rVT*8hDL^+;~y z!%)1n*WjC}UpAJ-L-Z3(^(|Y-n=3w<)||`cb*V@C+J4Kf%d=$#@@QV7I^`#kUihM4 zuBC_QpfMD?)!?CcjgdXL_+w<0qh;mPuXqEaI>;xvGq8@A$D~Di-|aa3*t4wR`T6x* z+O`~ zq+itc#4q)I*?aQ0F>ks-??;jrqTkC0X>I0p2kB0(!_wzY7W(6x>@0N;_VgXT zu#n>6iPn@#-CSd9#RTW$HYiKm)W?NeEx1W$tn64C3CHV@Db+1IO>`Ch`1lOX#E>2@Y_qn+IEd01LLZ~C~&YtwCfri@v62;wLI zS{PjcJ+dD>&Y``f)Y;;&t`JFd9i?}FjUjgmzi-VtLe6;lmea;PF!Ph252mjr zeeHLXIZLn^N#Bq3VZroolHPiKGN+OA2W}hfoS$?f)6!S^bx~h38et5jUir{o&Yi^k zzKwfz=X3Y0#s$v72H}g)>puKA!mU~0j|jpSCz3HAUUTY~!@HM%co2SQB015AKU?Kz zf!F*YxHdAhV^V6zjlFvdGWCP8JAD0ceU`D`$^&iy_#j)2aoE%SC0d917+Ezk$$Jj; zki0zcrG$wO!fWg(12@UG@RLo|;XaxCkbKPhd&-voPPU`w@q&>|nUFEwmaRO}_qKfb z0F~!scbX}e-|{fw4t`^z#r@UW!bf?u_F(hKPp>>%{XFu!8JtX>pY`PN=4HE%MVgyv zY=So3IzKDln%3s+SR`Hga%fUgZO!HGlN_fqq%qCrvty_IRylU;2$qv=?AU&`<80uu z{X292gVveVzqLo;;C}eY5ajv!eSV5RFGC~Qtm2Pw6Mw|tlLD}oKL*z4k6<-#6n|uY zC{I}+kN6{dS9#{RJKq+(cw|CD@117NQ28);d+-vEdh`9sq0U*i)D z+6=|ilgTHIr@Qb8oVGf<^2z42e6rs`J_XCk#;4dM&Y<(`4WEvCx^F%FS@FsC(Z2cg zt6lgM>`VRg>1Vs}sUy&z{%_>d+Ozoma~{j5-Ryt}^9%aYRDX=>%LdrRpXTSO_U)%^ zc{2NLB+zefd#Z1FkiS%RuJ*?v^S4>q%qFW9zVAFJs}ubEcCVFuborF$+qeCex82uu z!Sb|5srggTX9iwo4@zHs@t!Q@=v=$XvGex;PRI4v#_3tgk}i;r(ELNRlAe%FFWsTg z%n@j})ss6nd-M+SsdXav;_%G-3Ma{UtbFvxxAK1Ywj15SL+gw_-TQ6hwk&Pj7rN_r zvoux(`M0lhzbH#tqPys=aX{mU#-MwB+RA67G>vbX>ta8dbw2r#f^^^XWoXSaMxj4H z%CuQDh7Vx85r2dB%f0>Bk@%a;*spx*E0R%9M!av$W$m~0yxofz9FIjS)otheF6Cga z8$XWbO`0#LEqD2NXl^oqJi;-Uev~gKN)O`yVL#&l)YxraH4CA#G|HSq2G`OT`#cEx zSZJe}_i2BE`kK`z;!&{Q+HcWhz0Y&w*Z22YmHPQbQ_;fs%CRYoEr8uD87QD#*vgu7 zoAs0|eZ0WdWA&K*R=wl0)GN9M>#}#?QW$^2><}j&s=g1&Xu#&6UUM^D^Fp^s(Qr!}xBcm-upK8;cb{{p|uraq#1Xg1!`exrAm_&8WypmACIDO9HTXzdg6*wU5z zFvqHIstul8dh-p@seV4DQrU%M{Y$9AEf zcB^}=%8GdFeb@EVKF!ZEWs`f_N^G3uN%ta#eR-7(D^7dVG!BaPx@%JHwDo0cBR(O+ zJL&OHLKFFtgv%%4b$ejnztvxLr#p^av*cR%?FPN2Z+vVypO#>%-DNVIPeAWEJRp@m$X#b+hQaL4oayW-!bTsQPX01qTLE^9W4{OZU9%!>C zmNC1h&Au!{Ka(zfBY4}^{r&ytti6tv?V>s}*PS(H2hX06-|UyyJjV1f_SQu*_SPv) z@~QU2hXVU;Y-Z9Vud+3yPi;ANZI^yjBD;Dhv>oTu$>&L*@}o9EKeGm*cUz|9sSO+? zKe8XB8|~Sa%rb-dEG~>8yX_0Sl6qXqWN0<}0?#LGRGi8uUb;py8XOnxw{YAZn6KJ# zQDxdQFQ@l2?#%>FdQA4Zh0mtLm_HjG#x@dTFIagHt~TE>{nT^LUe;sRyG{?(BOV)F z%N;lJl?HKrBg=ju_8%EsHFwdNsC|IqpKz9)Q3gFN&j0ZHgVi5~hkkx{FL6fZOns6) z%NLa+`_6ugPvZk~Kg%aIEj`r~l=CJEz+4zp^nK?#K_GCloTWxX!a}3)i;hu?iQ2^ge8(O@z z_F)XV;kz_@s3^ZcbY#Dau{$(R%%=~(=da-ork@0? zMsbpH`K&ajyVq}TuncRTY5gG+{`@TPMlPvSbTNJi+BM$CO?26sg)X+OnX(_0-euEn%9|=%>D=C z@AT`{8Z-B0n6u6L4F&Nn*#J#1{blxESGVh;Xi0!*{N%E-G+?hrlU$F7Bh@Z7MdDJ|9M}+v} zZ2Z~8k6)NPYC6BaMf|aTd@j0Idx_N##t@F9jxs+@?Hli>#R$ifc8pDJZ&--azR_lVsR~+canKG5hXR9AIN71=5+5WQSWrr9&PspHa&X{Q&weNxv zUee{t!|w!`cj-*^Va2mYusg?p$8In_?cf+3v>V1`u^Uvso!_awc8oeHKtn4>&tgd1 zezTiS4bV&WLbXqypw72CTw`HS2Op57E?ZC3*GW1vDu0&?ulv%8N{hOlKSzE2T3@#Z zaiH!3)m;X@W`8ua(|!Tbpl8hV`7YftqMvqXuBvjZjhDyRCm)a#@q9I}`t?un;p{mm z`6!hy=%Y0F`1XWsSo;mlx;uTo1$}U`vu)j)3+Y|9hvt*{ylajv*|Ga7rOPwvGs?$L zdPMn!pXgxmlRr{(QByYWLAv$ak>Kxv6HHLf@`vrpdBT44`b#NSf_ISr><*~fq zZT!_b3~iFW6`q>sYu#ORmkp7*e#@N0xBa%HwXSdBGS`Q7_Q94X|DuHxU)3k<`m^R5 z7EZPfoY$8I_~f{sClRX*0gO_FUtKvNdl_t`J$lhU2)gEo}S zsD5O0HTqDtQPF>Rc(}gY*m;~_50>sEzhqW6p!AD5$H+Y>^sC$KI3`%>NBb@P5?ph$ z^I?sxDlZgSVD8Q^ehB)q@c7H7-RUvz*j_qjuAAF2ST=!lj^_5V8>CY+eN^CszqZq? zd0Af)?YC%YZ3NY2X(=1QmZ32~c9!I7Q5GD+D4G87uzq!&%~2W4vy>6y-rW%Q zo9ce3spHT3+Jxb??(k?u-SNYtqr887j;b5m^KZoP=;+3|?zG`8m%7g6){!Ht&Y9a< zKd)*=O-ub*XPAmx0X_>TIbX>w6>g8J7IDS|0XDyd{WhfJv2W9*O60NTY6E=NUWG_ z+8aop+&a2-)|~p9x{=YUvu4K|4fWK-zMC?+^`zNij?jzl5xwJRxnIReriQa<@2ILX z8k*{=S{kUa{;V%wl7Z%E56v^1o0{rtTN|32Mn)T&8d@7_8XK;ypU`l@q;n^qST(Yu za!!35;-426NXvxENwpI$Y`khh)m6}Lg7bgA;;5~8&+Qo*_i(S8HFw5@t3bQ*+!N=1 zZSpB!tDi9$@vd(@>+Bg(T5;~=QB@;HPHb(BUr>ML-1?T*2@|TE<37Fe8!BtRJ|X(4 z7D`G+MkWAR_sYu)srUdxhMT!g}E>6 zdxv^Z;f)0^3H3L(w$*K#+t}zfHMhD~(Yx!o>9nyPonNk~hRd&UuWp`mh3jc3 z=j+W4O}j({65aZF4Jd!->Xw$VC!8?6W$f^|!&{uWSGTzJbLKS98SBn%sh?9<(^}&W zkC(eGsOx%nc%1>5Q(t?Pi)x=awl{uwW8+-siu!9#rI4fR>aS|3t*>gmCSG6FP#28y zzbIM|CgrO7IW4Fo^WNGp+ly?euborhsyIfxi~cu{GrR62w`ESPd#XFUrQFrmocflz zjjblasbQcR>&E9aw>Hn1d$|i@p3-zLuW4w6JW6*PnhdR7lxNLsLju?#Okd;0}X0t|kg)x5C*3-Jno6FsXIuWGK ziO+4B<%xjk(mzUY~EiK4Uc@U~O zZt_Rx4WEY`BUHodytbCRev-88hZQXHna#+2~qtVckY}9R}n2vP`c;LZKD0b zsIj(?-Qustig0NoC{T?nA&k>=T6fLe*xVf7J;sG8!C3doxecurwb?b-&@FrDSnjsY zxyG*rad12$nZ}g61_{5JbO*QQDg>}*Mk5pxLd_6i_*}^Bj2tm)#2Cl3!$zFhGvYhO zJ_|&QfFgd2XbZHeX%vU&A~%wuj5r_7p1K5?Y1N(LNvUr>Ol)q1T z(W6H0lIxu2x`xXeWLIMPoRnc9o>iG){P;C8-k*ge@5%bhUgAC&n|rV_v)8k$6+Lot zE0*N!^XJyj-8X~x+{q)WMvj`=j4riC-Go!T;#%ux?;9z0Me&sL;`MWCWG^CWt#g_i z8|&v_o2y!nWs_TLTIaT4cM;`tae@Yr2@`s=ej12m(2Cl6ZFAJpOMLRkf{+RZQuc zX4Y4sWs$g+dPUFiY4DM)K*8xx0hUz`?)m;CCS@ZY+*ghxh4zI<7IQw(WXZ~z zd+br4_AKO+;u^5t_l#^%AsZXH_KLFMEytF-S4mUjwrH3+vwn^j<$vJZsF~ARHheBn zHp;W7yf`msy!mS7yBwgFD;gRb=`3a{A1u9o9%h{)tc}oOTo}#?vzlkupK$dRbg~m< zDYe8g{!VC_O|_@bt!rpL!59$7*Uo8fX*s^7rE%nl=!mEv*&MHLG8i1+Qg_7(Skoue zHqV~j+;oChwq_^3<6*=s`gBXYN;3!3y935`&@lGXJS)4r$27z6nE@X4O~ybClG9AiW~&GETTymq#8?JU14e}Hvo zd&Wr}7UNjvV0Dn1xf2|bEnDkxq7fo{Z%xfrO^xxg;dKD;Zmh1^^>qz3t@TwkE%37L zSigKJ=n*}$xnB2;ZfUW z;6Gi#@g&9yj{I38YHOkPh?(`RWyiXwp6Z@^;n`<9n(G*elcoRZV&ID|B3*|eT!oit zZareF3DBu-*>Mf6$DhXZv$?76*yB%Qf?al8V@*qIRYNPEqMCftCnV#^)@y~Z1@u$Qo!iR`I*uT&v2qrSF=DZUXA4}DE{ z_b$I_b5_u?UQ;D^hE|%~Fym-wJ*LHl*Qk~TrZmHx%WE1L;rlDXP)p@_DgxS~^XiSX z8wUjnz zNcK98Hpeb%bM9VefNxp)~B87M%|;2_6R@DZNc^1 ze0f<_YrN&y6Z{Xa%nOWKoPsRxqI=X3P->k!r-{I5&fRoJcBFO{JX4OQvzb(~g&XF> z&AKayG2W{>$MaaZ$B6AR`&y1cLT5HKIiIv?SMJuXo+7G_$8`{PJ5NEn>)t7O3XgaM()Bh#Q%+5{c?g4XV);Gy;WyJdb+Pm7A z$gcDJo_h~pyOZ6qjl1JDtKyWbu{ulH7{}P92^-UdB)BFHwpZ;cyX?XiUHbI!eY z1`PYrWUEx#D;=Kmew_E5dp_TD&z;Npi*Ga5zt0?hC#4Tg-}|MY@eeEv>{iU(E*EBT zf)n9C`wF^_c_dV4ng#Qn-)@Cm&~kYAQgkoDyEGcOH7%Td_TU*Nu3^H#hUEs6;$-{FDgZZNlXQF*k_mAXXB@ zN`qKg5HkkMAB9DO&o7Iw0?!GgZV=NC>1~^W&pf&2h?EAgvR56ieC4nDC9QbGPjM(n zdpL-N0=*9fF=N#Hp?#a%zGVqglmxNTAXXN{_O%z(h8yVVAXXBTZ{M^*Z4{-&PX}$w zl!R5@*315BwWr5AwJCHEE2I!Uf;iQ8`4o=b(TgGI?X%~i)cH~;UPZ!o5C@Q#V|{N0 zUh-SL1NPh-I(*dzIyOBfQp}`1eFJgn92mg4V30IOixaOH9uV-kwct4JN@omDqN)eq z?C)nP5ghHtE_Pme-9MVX(u>_RPVzWuBik+vB^W?Cz0+!LiSfqJmthXPcsCw7no`6% z2Y!=0bE;fa4yqO_px`tg6x6qC%h}aEcxj-wKi)S0Q?T!!abNBoLQ%YMAcJpSbZoPy~z`-7KxZ>H@!_2Jbt@ChZ6-C;uInww`FvqmFdxF-OLgo^WJA=}AYn zlum!6#f1{GN!=V;I{bbalBXdp!uWgz% z8On4B2TP5luR5edVdNjJjY%9>P5!%@{3Gp{G-7&GNy=8Vrp&f$CF?92Sx_>fbVf;z z8tco<|B%T)3VKXsRnC!RR>`7~g(*8cwC-%Wa?1rwvcJ!)?8;1t!?iQl1UPE%z z1k%JbUf-@Siq{myBSrC$A5T4@!Vz8TR>N+CZjq)i58Kr5uu*VrA6K&WSFnApoaL#C zm8TpTMQfrBl-@M$i}(bKHA}sBP5mFLVS9U>IZggm(`OGS9X;;w{$YER{EX>;k5=Qy z3T-)s&M@JI&@oUSCjTy@WBOdUsWq)+nys>|IuLC&`I&Y-+5|2}BMO90hLlmtuA6j6 z*{)41&VnmBV>L|KJ4O~_f34SN1|TgiydnsInj>1lR)YroytH+}Mn7O>iCF{;oei>_ppo^xehZ7L9} zUL96b|C*`)O7`Ja<}s_91Cz#Hlx29axdZ8uX%;=pp{=Z=rz<4qv`kjW0u3&?wTRAY zJyIcSS|gq<(PI^|RKj?=RHwi%O*tTNP5lMys)n|sl}KG%zoyZ_)v}f`w`M`ZT>YY! zQLVwjbOPy3_UIVXd1IDs)T$>G2NG?zQvIdi%sheM9mu{~_mm21@ zgON99Iw}}5X7ZVG^}OHHwwGYj8$X+jdvh#pw2nJTPF2icnX-%-n@1bLcnnJ5!6^Qfk7qCMp&~W{RyDxH`jr+SH>eRIS@pTo0k#fyTML z@|f;7lbdIuiSip}>^+33%^xV3BM`+^bqD$OpCdijy#w-JrQEykrZ&v^s$t5JjOmf{ zl<{7%HlBlQMd>6a2_u`jgWZwa*zLKE-8RbXT=OB@KZYb}yMWaDd7^)?{c5?Cnd%m) zq|A=}@|cdBDi%MV)M<6HF@zs==^2G}Mq_qfR63`)d?Ai?aNCg-`$5od3x5`r!}i6F zDaBF9I-jP@&To}we(Og!nsGu~s2my@HEB(~Rq`I1+cAA1!*y>G>oMt1vtFNUMX@eK zFfrmLF|@~372+7DIZSG5QGr-9{j-5-ZkW0HL~UD|ni(~YWatR4Oj8G=7^!fT8(lM2 z9>SbZhDKd4nJ$xsGE;oH`KPdD=cd}O_MFDl8lKlO>*yIRYmP>IOh>?9=7`_A)j7Lm5 z>pSfo*V{Sfx&OFcql|qf^_V(ZqvHw#Y+MNjbD<;5QRg1U`xy0aGhSnq-)20vQGUR9 ztoO^Z&v<0Lv-1w2&u?z!6Qg#lBP8NTw6hJc=U|%GoTMYi*nuuxn)} zF#${iCxNTLG%)fvJBcY^2XGpg0>Yx5c z4LI?y;N!k?K&D$Fje4E=F7RC^S^jT8uchGL&w*YzH!@wlyG?4eR1{?+*%|o7X zlheQn&~uVE@*FS=`hv1_*a40DNf|6j&by$mI!V!1-VS6wlO8?i(T$~flW%{S)vGQ? zo4{`PP(CpQOdrlCW`UC-+!HW%B%fFVE&?}!T@OR|hxtU!G4vT==D4*(YyrLTcs|h& zTseU@rryt^9Kg+A$S3rVVDF^WCq_Y6KABH616P3^z>TLo`Kf$j81yiZ^_l^)o<{2| zy$AJ$bXq($&8LI-`=~AGh>6knJ|sZ0YnFTduViEWOo|PmIA{!>6sCXsflK z0nUKG`We(Q@aAU`2ljj}pV$IUwB-}!x6n2(<`Y%G=&vC?#>Xnqlj(aPh0~XzmQMd z0){Wa*88yEZRNx!&>3JmaP%_l0w;Q`JlAW>wGL#t&%KWPAdg(hC&r0ySbiHY4f>`> zhx$-Ipd0$Vbc3{$NoIkxBXQ7Zhp{&;o&J*5UmK#{_2kOixDTX1`(@NCaP+s)7lGr$ zUV4~l!=5f3Q8NFSu_&1@V2O?@(WjJzpI5St_%H&mamZGlQ|LGFa+@u07Q8s*5$MlA zCcrsQKMmP1cykChKk3k%%19|4Yd z`ccSg!RtXd`$s^yWR2g)9{2}JM&E;dgiVC$A0fZ@t-ap!hNb5L1+*7$y%uw0Cv|5%|dzEKpf zd$z#;mKVRjh1F)C)H|Cb(=!@ACEH zprP0Qd%()iIVSMt=>zie^%98t_9{OQJp^A?toIcV^h?=ig(o-tU88by1H# zY4rj2z6v?>rCts6YM_^5<9L@}hU=iorXKypnb#aaRU4YB)MGjR7{RwkpEh^a!PzvJ z-bFozIRsyi^U>TF_rKpifgbHL-+AcGL$4We|MJWCO)zMW6BaM(owQN&mokPW1lZ~~ dO#Jz0=$-ZnAa!^VnWujpJCElrJ^}Rg{s-%T3Ag|N literal 0 HcmV?d00001 diff --git a/package/netease/ihw_player/Makefile b/package/netease/ihw_player/Makefile old mode 100644 new mode 100755 index bda15f852..73b18628e --- a/package/netease/ihw_player/Makefile +++ b/package/netease/ihw_player/Makefile @@ -16,12 +16,14 @@ define Package/$(PKG_NAME) SECTION:=utils CATEGORY:=Netease TITLE:=$(PKG_NAME) app - DEPENDS:=+netease_voice +liballwinner +libmad +libjson-c +cppunit +libuws +libspeech $(MAKE_COMMON_DEPEND) + DEPENDS:=+netease_voice +libmad +libjson-c +cppunit +libuws +libspeech +libcedarx2.7 +alsa-utils +libuapi $(MAKE_COMMON_DEPEND) ifeq ('$(CONFIG_XUNFEI_TTS_SDK)_$(CONFIG_TTS_TEXT_XUNFEI)', 'y_y') DEPENDS+=+libmsc endif endef +#+liballwinner + ifeq ('$(CONFIG_XUNFEI_TTS_SDK)_$(CONFIG_TTS_TEXT_XUNFEI)', 'y_y') TARGET_LDFLAGS += -lmsc endif diff --git a/package/netease/ihw_player/src/Makefile b/package/netease/ihw_player/src/Makefile old mode 100644 new mode 100755 index ee2fd8492..39a373603 --- a/package/netease/ihw_player/src/Makefile +++ b/package/netease/ihw_player/src/Makefile @@ -11,10 +11,13 @@ CppFiles = $(shell find $(MK_PWD) -name "*.cpp" ! -name "cppunit.cpp") CFiles = $(shell find $(MK_PWD) -name "*.c") CFilesForUint = $(shell find $(MK_PWD) -name "*.c" ! -name "ihwplayer.c") +SourceIncludePath := -I$(STAGING_DIR)/usr/include/allwinner/include -I$(STAGING_DIR)/usr/include/allwinner + # 依赖的第3方库 -LoadLibs += -ltinaplayer -lxplayer -lcdc_vdecoder -lcdc_adecoder -lcdc_sdecoder -lcdc_base -lcdc_ve -lcdc_memory \ - -lcdx_parser -lplayer -lcdx_stream -lcdx_base -lpostprocess \ - -law_plugin -ldl -lstdc++ -lrt -lm -lc -lasound -lmad -ljson-c -lspeech -luWS -lcrypto -lssl $(BUILD_COMMON_LIB) +LoadLibs += -ltplayer -lxplayer -lcdc_vdecoder -ladecoder -lcdc_sdecoder -lcdc_base -lcdc_ve -lcdc_memory \ + -lcdx_parser -lcdx_playback -lcdx_stream -lcdx_base -luapi \ + -lpthread -ldl -lstdc++ -lrt -lm -lc -lz -lasound -lmad -ljson-c -lspeech -luWS -lcrypto -lssl $(BUILD_COMMON_LIB) + # 依赖文件 CppObject = $(CppFiles:%.cpp=%.o) CObject = $(CFiles:%.c=%.o) @@ -25,19 +28,19 @@ StlNeed = -std=c++11 # 链接 $(Target): $(CppObject) $(CObject) @echo "Begin link.............." - $(CC) -Wall -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LoadLibs) + $(CC) -Wall -o $@ $^ $(CFLAGS) $(SourceIncludePath) $(LDFLAGS) $(LoadLibs) # 编译 $(CppObject): %.o : %.cpp @echo "Begin bulid cpp.............." - $(CXX) -c $< $(CXXFLAGS) $(Include) -o $@ $(StlNeed) + $(CXX) -c $< $(CXXFLAGS) $(SourceIncludePath) $(Include) -o $@ $(StlNeed) $(CObject): %.o : %.c @echo "Begin bulid c.............." - $(CXX) -c $< $(CFLAGS) $(Include) -o $@ $(StlNeed) + $(CXX) -c $< $(CFLAGS) $(SourceIncludePath) $(Include) -o $@ $(StlNeed) # 编译单元测试 @echo "Begin bulid unittest.............." - $(CXX) $(CXXFLAGS) $(Include) -lcppunit -ldl $(LoadLibs) $(LDFLAGS) \ + $(CXX) $(CXXFLAGS) $(SourceIncludePath) $(Include) -lcppunit -ldl $(LoadLibs) $(LDFLAGS) \ ./unit/cppunit.cpp $(CppFiles) $(CFilesForUint) $(StlNeed) -o unitIhwplayer # 伪目标 diff --git a/package/netease/ihw_player/src/ihwplayer.c b/package/netease/ihw_player/src/ihwplayer.c old mode 100644 new mode 100755 index 8f4c9a3f0..d16f2c271 --- a/package/netease/ihw_player/src/ihwplayer.c +++ b/package/netease/ihw_player/src/ihwplayer.c @@ -11,7 +11,7 @@ 2017/07/13 wk Initially created *****************************************************************************/ -#include "player.h" +#include "playerapi.h" #include #include "readCmd.h" #include "updatelist.h" diff --git a/package/netease/ihw_player/src/include/jsonc.h b/package/netease/ihw_player/src/include/jsonc.h old mode 100644 new mode 100755 index a62913ac9..565e68adf --- a/package/netease/ihw_player/src/include/jsonc.h +++ b/package/netease/ihw_player/src/include/jsonc.h @@ -14,7 +14,7 @@ #ifndef _JSON_C_H_ #define _JSON_C_H_ -#include "player.h" +#include "playerapi.h" #include #include #include diff --git a/package/netease/ihw_player/src/include/luplayer.h b/package/netease/ihw_player/src/include/luplayer.h new file mode 100755 index 000000000..23e5a2405 --- /dev/null +++ b/package/netease/ihw_player/src/include/luplayer.h @@ -0,0 +1,131 @@ +#ifndef _LU_PLAYER_H_ +#define _LU_PLAYER_H_ + +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace aw{ + +#define POINT_CHECK_NULL(a, ret) {do{if(a == NULL){ \ + LOG_EX(LOG_Error ,"point is null!\n"); \ + return ret; \ + }}while(0); \ + } + + +class LuPlayer{ + public: + LuPlayer() + { + tplayer = TPlayerCreate(CEDARX_PLAYER); + } + ~LuPlayer() + { + TPlayerDestroy(tplayer); + tplayer = NULL; + } + int setDebugFlag(bool debugFlag) + { + POINT_CHECK_NULL(tplayer, -1); + return TPlayerSetDebugFlag(tplayer, debugFlag); + } + int setNotifyCallback(TPlayerNotifyCallback notifier, void* pUserData) + { + POINT_CHECK_NULL(tplayer, -1); + return TPlayerSetNotifyCallback(tplayer, notifier, pUserData); + } + int setDataSource(const char* pUrl, const CdxKeyedVectorT* pHeaders) + { + POINT_CHECK_NULL(tplayer, -1); + POINT_CHECK_NULL(pUrl, -1); + return TPlayerSetDataSource(tplayer, pUrl, pHeaders); + } + int prepare() + { + POINT_CHECK_NULL(tplayer, -1); + return TPlayerPrepare(tplayer); + } + int prepareAsync() + { + POINT_CHECK_NULL(tplayer, -1); + return TPlayerPrepareAsync(tplayer); + } + int start() + { + POINT_CHECK_NULL(tplayer, -1); + return TPlayerStart(tplayer); + } + int start(float gain) + { + POINT_CHECK_NULL(tplayer, -1); + return TPlayerStartWithGain(tplayer, gain); + } + int stop() + { + POINT_CHECK_NULL(tplayer, -1); + return TPlayerStop(tplayer); + } + int pause() + { + POINT_CHECK_NULL(tplayer, -1); + return TPlayerPause(tplayer); + } + int reset() + { + POINT_CHECK_NULL(tplayer, -1); + return TPlayerReset(tplayer); + } + int isPlaying() + { + POINT_CHECK_NULL(tplayer, -2); + return TPlayerIsPlaying(tplayer); + } + int seekTo(int msec) + { + POINT_CHECK_NULL(tplayer, -1); + if(msec < 0) msec = 0; + return TPlayerSeekTo(tplayer, msec); + } + int getCurrentPosition(int* msec) + { + POINT_CHECK_NULL(tplayer, -1); + return TPlayerGetCurrentPosition(tplayer, msec); + } + int getDuration(int* msec) + { + POINT_CHECK_NULL(tplayer, -1); + return TPlayerGetDuration(tplayer, msec); + } + MediaInfo* getMediaInfo() + { + POINT_CHECK_NULL(tplayer, NULL); + return TPlayerGetMediaInfo(tplayer); + } + int setLooping(int bLoop) + { + POINT_CHECK_NULL(tplayer, -1); + return TPlayerSetLooping(tplayer, bLoop); + } + int setVolume(int volume) + { + POINT_CHECK_NULL(tplayer, -1); + return TPlayerSetVolume(tplayer, volume); + } + int getVolume() + { + POINT_CHECK_NULL(tplayer, -1); + return TPlayerGetVolume(tplayer); + } + private: + TPlayer *tplayer; + }; +} + +#endif diff --git a/package/netease/ihw_player/src/include/readCmd.h b/package/netease/ihw_player/src/include/readCmd.h old mode 100644 new mode 100755 index 13fcd4001..5abafbbd1 --- a/package/netease/ihw_player/src/include/readCmd.h +++ b/package/netease/ihw_player/src/include/readCmd.h @@ -10,7 +10,7 @@ #include #include -#include "player.h" +#include "playerapi.h" #ifdef __cplusplus extern "C" { diff --git a/package/netease/ihw_player/src/include/updatelist.h b/package/netease/ihw_player/src/include/updatelist.h old mode 100644 new mode 100755 index 4ae3d9621..4b3846d78 --- a/package/netease/ihw_player/src/include/updatelist.h +++ b/package/netease/ihw_player/src/include/updatelist.h @@ -9,7 +9,7 @@ #include #include -#include "player.h" +#include "playerapi.h" #ifdef __cplusplus extern "C" { diff --git a/package/netease/ihw_player/src/libplayer/audioplayer.cpp b/package/netease/ihw_player/src/libplayer/audioplayer.cpp old mode 100644 new mode 100755 index 1e394c9f1..af6ae9e91 --- a/package/netease/ihw_player/src/libplayer/audioplayer.cpp +++ b/package/netease/ihw_player/src/libplayer/audioplayer.cpp @@ -98,7 +98,8 @@ typedef enum{ // 非tts的audio播放 #define STOP_ERR_TYR_TIMES 3 typedef struct { - TinaPlayer *nTinaplayer; + //TinaPlayer *nTinaplayer; + LuPlayer *nTinaplayer; volatile PlayerStatus nStatus; u8 nError; #if LOCK_ENABLE @@ -791,20 +792,23 @@ static void audioPlayerPlayThreadFun(void){ RETURNED VALUES: void *****************************************************************************/ -static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* param1) +//static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* param1) +static int callbackForTinaPlayer(void* pUserData, int msg, int param0, void* param1) { AudioPlayer* mAudioPlayer = (AudioPlayer*)pUserData; //LOG_EX(LOG_Debug, "callbackForTinaPlayer:%d\n", msg); switch(msg) { - case TINA_NOTIFY_NOT_SEEKABLE: + //case TINA_NOTIFY_NOT_SEEKABLE: + case TPLAYER_NOTIFY_NOT_SEEKABLE: { LOG_EX(LOG_Debug, "TINA_NOTIFY_NOT_SEEKABLE\n"); break; } - case TINA_NOTIFY_ERROR: + //case TINA_NOTIFY_ERROR: + case TPLAYER_NOTIFY_MEDIA_ERROR: { PlayerStatus audioSt; if(param0 == NOTIFY_ERROR_TYPE_IO) @@ -832,7 +836,8 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa break; } - case TINA_NOTIFY_PREPARED: + //case TINA_NOTIFY_PREPARED: + case TPLAYER_NOTIFY_PREPARED: { #if LOCK_ENABLE pthread_mutex_lock(&mAudioPlayer->nMutex); @@ -850,7 +855,7 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa pthread_mutex_unlock(&mutexPlay); break; } - + /* case TINA_NOTIFY_BUFFERRING_UPDATE: { int nBufferedFilePos; @@ -861,9 +866,10 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa LOG_EX(LOG_Debug, "TINA_NOTIFY_BUFFERRING_UPDATE: buffer %d percent of the media file, buffer fullness = %d percent.\n", nBufferedFilePos, nBufferFullness); break; - } + }*/ - case TINA_NOTIFY_PLAYBACK_COMPLETE: + //case TINA_NOTIFY_PLAYBACK_COMPLETE: + case TPLAYER_NOTIFY_PLAYBACK_COMPLETE: { LOG_EX(LOG_Debug, "TINA_NOTIFY_PLAYBACK_COMPLETE\n"); #if LOCK_ENABLE @@ -877,7 +883,8 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa break; } - case TINA_NOTIFY_SEEK_COMPLETE: + //case TINA_NOTIFY_SEEK_COMPLETE: + case TPLAYER_NOTIFY_SEEK_COMPLETE: { LOG_EX(LOG_Debug, "TINA_NOTIFY_SEEK_COMPLETE\n"); break; @@ -892,7 +899,7 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa } } - return; + return 0; } /***************************************************************************** @@ -920,7 +927,8 @@ bool audioPlayerInit(AudioPlayerCallback callback){ #if LOCK_ENABLE pthread_mutex_init(&mAudioPlayer.nMutex, NULL); #endif - mAudioPlayer.nTinaplayer = new TinaPlayer(); + //mAudioPlayer.nTinaplayer = new TinaPlayer(); + mAudioPlayer.nTinaplayer = new LuPlayer(); if(NULL == mAudioPlayer.nTinaplayer){ LOG_EX(LOG_Error, "can not create tinaplayer, quit.\n"); @@ -935,12 +943,12 @@ bool audioPlayerInit(AudioPlayerCallback callback){ goto ErrRet; } - + /* if(mAudioPlayer.nTinaplayer->initCheck() != 0){ LOG_EX(LOG_Error, "initCheck of tinaplayer fail, quit.\n"); notifyCallback(0, AUDIO_ST_ERR); goto ErrRet; - } + }*/ mAudioPlayer.nStatus = AUDIO_ST_IDLE; LOG_EX(LOG_Debug, "mAudioPlayer Create successfully.\n"); diff --git a/package/netease/ihw_player/src/libplayer/background.cpp b/package/netease/ihw_player/src/libplayer/background.cpp old mode 100644 new mode 100755 index e110b2703..e6d5c3a5a --- a/package/netease/ihw_player/src/libplayer/background.cpp +++ b/package/netease/ihw_player/src/libplayer/background.cpp @@ -19,7 +19,8 @@ typedef enum } BackGrondIndex; typedef struct { - TinaPlayer *nTinaplayer[BG_TINA_PLAYER_NUM]; + //TinaPlayer *nTinaplayer[BG_TINA_PLAYER_NUM]; + LuPlayer *nTinaplayer[BG_TINA_PLAYER_NUM]; BackGrondIndex Index; PlayerStatus nStatus[BG_TINA_PLAYER_NUM]; u8 nError; @@ -46,7 +47,8 @@ static uint32 nonMusicPlayerId; RETURNED VALUES: void *****************************************************************************/ -static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* param1) +//static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* param1) +static int callbackForTinaPlayer(void* pUserData, int msg, int param0, void* param1) { BackGroundPlayer* mBackGroundPlayer = (BackGroundPlayer*)pUserData; @@ -55,13 +57,15 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa //LOG_EX(LOG_Debug, "callbackForTinaPlayer:%d\n", msg); switch(msg) { - case TINA_NOTIFY_NOT_SEEKABLE: + //case TINA_NOTIFY_NOT_SEEKABLE: + case TPLAYER_NOTIFY_NOT_SEEKABLE: { LOG_EX(LOG_Debug, "TINA_NOTIFY_NOT_SEEKABLE\n"); break; } - case TINA_NOTIFY_ERROR: + //case TINA_NOTIFY_ERROR: + case TPLAYER_NOTIFY_MEDIA_ERROR: { for(int i = 0; i < BG_TINA_PLAYER_NUM ; i++){ pthread_mutex_lock(&mBackGroundPlayer->nMutex[i]); @@ -74,7 +78,8 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa break; } - case TINA_NOTIFY_PREPARED: + //case TINA_NOTIFY_PREPARED: + case TPLAYER_NOTIFY_PREPARED: { pthread_mutex_lock(&mBackGroundPlayer->nMutex[mBackGroundPlayer->Index]); mBackGroundPlayer->nStatus[mBackGroundPlayer->Index] = BG_ST_PREPARED; @@ -88,7 +93,7 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa } break; } - + /* case TINA_NOTIFY_BUFFERRING_UPDATE: { int nBufferedFilePos; @@ -100,9 +105,10 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa nBufferedFilePos, nBufferFullness); break; - } + }*/ - case TINA_NOTIFY_PLAYBACK_COMPLETE: + //case TINA_NOTIFY_PLAYBACK_COMPLETE: + case TPLAYER_NOTIFY_PLAYBACK_COMPLETE: { //* stop the player. //* TODO @@ -110,7 +116,8 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa break; } - case TINA_NOTIFY_SEEK_COMPLETE: + //case TINA_NOTIFY_SEEK_COMPLETE: + case TPLAYER_NOTIFY_SEEK_COMPLETE: { LOG_EX(LOG_Debug, "TINA_NOTIFY_SEEK_COMPLETE\n"); @@ -124,7 +131,7 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa } } - return; + return 0; } /***************************************************************************** FUNCTION NAME: soundEffectInit @@ -143,7 +150,8 @@ bool backGroundPlayerInit(bgPlayerCallback callback){ memset(&mBackGroundPlayer, 0, sizeof(BackGroundPlayer)); pthread_mutex_init(&mBackGroundPlayer.nMutex[0], NULL); - mBackGroundPlayer.nTinaplayer[0] = new TinaPlayer(); + //mBackGroundPlayer.nTinaplayer[0] = new TinaPlayer(); + mBackGroundPlayer.nTinaplayer[0] = new LuPlayer(); mBackGroundPlayer.Index = BG_TINA_PLAYER_1; bgPlayerInited = true; mBackGroundPlayer.needResetTinaplay[mBackGroundPlayer.Index] = FALSE; @@ -161,12 +169,12 @@ bool backGroundPlayerInit(bgPlayerCallback callback){ goto ErrRet; } - + /* if(mBackGroundPlayer.nTinaplayer[0]->initCheck() != 0){ LOG_EX(LOG_Error, "initCheck of tinaplayer fail, quit.\n"); notifyCallback(0, PLAYER_ERR_TINA_INIT); goto ErrRet; - } + }*/ mBackGroundPlayer.nStatus[0] = BG_ST_IDLE; LOG_EX(LOG_Debug, "backGroundPlayerInit successfully.\n"); diff --git a/package/netease/ihw_player/src/libplayer/include/alsa_interface.h b/package/netease/ihw_player/src/libplayer/include/alsa_interface.h old mode 100644 new mode 100755 index a062c7d15..ad88dce58 --- a/package/netease/ihw_player/src/libplayer/include/alsa_interface.h +++ b/package/netease/ihw_player/src/libplayer/include/alsa_interface.h @@ -1,6 +1,6 @@ #pragma once -#include "player.h" +#include "playerapi.h" #include #include #include diff --git a/package/netease/ihw_player/src/libplayer/include/audioplayer.h b/package/netease/ihw_player/src/libplayer/include/audioplayer.h old mode 100644 new mode 100755 index 632125d79..23b60f3a4 --- a/package/netease/ihw_player/src/libplayer/include/audioplayer.h +++ b/package/netease/ihw_player/src/libplayer/include/audioplayer.h @@ -15,9 +15,10 @@ #ifndef __AUDIO_PLAYER_H__ #define __AUDIO_PLAYER_H__ -#include "player.h" +#include "playerapi.h" -#include +//#include +#include #include "alsa_interface.h" /* typedef enum diff --git a/package/netease/ihw_player/src/libplayer/include/background.h b/package/netease/ihw_player/src/libplayer/include/background.h old mode 100644 new mode 100755 index 00e10e04f..5cd6d803c --- a/package/netease/ihw_player/src/libplayer/include/background.h +++ b/package/netease/ihw_player/src/libplayer/include/background.h @@ -22,12 +22,13 @@ #include #include -#include +//#include +#include #include #include #include -#include "player.h" +#include "playerapi.h" using namespace aw; diff --git a/package/netease/ihw_player/src/libplayer/include/dlist.h b/package/netease/ihw_player/src/libplayer/include/dlist.h old mode 100644 new mode 100755 index 7948b76db..b04cddc21 --- a/package/netease/ihw_player/src/libplayer/include/dlist.h +++ b/package/netease/ihw_player/src/libplayer/include/dlist.h @@ -18,7 +18,7 @@ #include #include -#include "player.h" +#include "playerapi.h" #ifdef __cplusplus extern "C" { diff --git a/package/netease/ihw_player/src/libplayer/include/musicplayer.h b/package/netease/ihw_player/src/libplayer/include/musicplayer.h old mode 100644 new mode 100755 index a1d9991fb..e784cc728 --- a/package/netease/ihw_player/src/libplayer/include/musicplayer.h +++ b/package/netease/ihw_player/src/libplayer/include/musicplayer.h @@ -24,12 +24,14 @@ #include #include -#include +//#include #include #include #include -#include "player.h" +#include "playerapi.h" + +#include "luplayer.h" using namespace aw; diff --git a/package/netease/ihw_player/src/libplayer/include/pcmplayer.h b/package/netease/ihw_player/src/libplayer/include/pcmplayer.h old mode 100644 new mode 100755 index 678298052..90553abfb --- a/package/netease/ihw_player/src/libplayer/include/pcmplayer.h +++ b/package/netease/ihw_player/src/libplayer/include/pcmplayer.h @@ -15,7 +15,7 @@ #ifndef __PCM_PLAYER_H__ #define __PCM_PLAYER_H__ -#include "player.h" +#include "playerapi.h" #include "alsa_interface.h" #include "ringbuffer.h" diff --git a/package/netease/ihw_player/src/libplayer/include/player.h b/package/netease/ihw_player/src/libplayer/include/playerapi.h old mode 100644 new mode 100755 similarity index 98% rename from package/netease/ihw_player/src/libplayer/include/player.h rename to package/netease/ihw_player/src/libplayer/include/playerapi.h index 0cb90e60d..4f19059df --- a/package/netease/ihw_player/src/libplayer/include/player.h +++ b/package/netease/ihw_player/src/libplayer/include/playerapi.h @@ -293,8 +293,8 @@ typedef struct{ #define DBUS_UV_MSG #ifdef CALLBACK_MSG -typedef void (* PlayerCallback)(uint32, PlayerStatus, char *, int); -bool playerInit(PlayerCallback); +typedef void (* IhwPlayerCallback)(uint32, PlayerStatus, char *, int); +bool playerInit(IhwPlayerCallback); #else bool playerInit(void); #endif diff --git a/package/netease/ihw_player/src/libplayer/include/soundeffect.h b/package/netease/ihw_player/src/libplayer/include/soundeffect.h old mode 100644 new mode 100755 index 84f4d39fa..cdb852948 --- a/package/netease/ihw_player/src/libplayer/include/soundeffect.h +++ b/package/netease/ihw_player/src/libplayer/include/soundeffect.h @@ -23,12 +23,13 @@ #include #include -#include +//#include +#include #include #include #include -#include "player.h" +#include "playerapi.h" using namespace aw; diff --git a/package/netease/ihw_player/src/libplayer/musicplayer.cpp b/package/netease/ihw_player/src/libplayer/musicplayer.cpp old mode 100644 new mode 100755 index aa8896e4f..f4fa6e692 --- a/package/netease/ihw_player/src/libplayer/musicplayer.cpp +++ b/package/netease/ihw_player/src/libplayer/musicplayer.cpp @@ -12,7 +12,7 @@ *****************************************************************************/ #include "musicplayer.h" -#include "player.h" +#include "playerapi.h" #define NET_PLAYER_DEBUG @@ -37,7 +37,8 @@ TinaPlayerPrepareSt tinaPlayerPrepareSt = MUSIC_TINA_NOTIFY_NULL; #endif typedef struct { - TinaPlayer *nTinaplayer[MUSIC_TINA_PALYER_NUM]; + //TinaPlayer *nTinaplayer[MUSIC_TINA_PALYER_NUM]; + LuPlayer *nTinaplayer[MUSIC_TINA_PALYER_NUM]; MusicPlayerIndex nPlayerIndex; u8 nPreStatus[MUSIC_TINA_PALYER_NUM]; PlayerStatus nStatus[MUSIC_TINA_PALYER_NUM]; @@ -560,7 +561,8 @@ static void threadMainFun(void){ RETURNED VALUES: void *****************************************************************************/ -static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* param1) +//static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* param1) +static int callbackForTinaPlayer(void* pUserData, int msg, int param0, void* param1) { MusicPlayer* pMusicPlayer = (MusicPlayer*)pUserData; @@ -570,14 +572,16 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa switch(msg) { - case TINA_NOTIFY_NOT_SEEKABLE: + //case TINA_NOTIFY_NOT_SEEKABLE: + case TPLAYER_NOTIFY_NOT_SEEKABLE: { pMusicPlayer->nSeekable = 0; LOG_EX(LOG_Debug, "TINA_NOTIFY_NOT_SEEKABLE\n"); break; } - case TINA_NOTIFY_ERROR: + //case TINA_NOTIFY_ERROR: + case TPLAYER_NOTIFY_MEDIA_ERROR: { for(int i = 0; i < MUSIC_TINA_PALYER_NUM ; i++){ pthread_mutex_lock(&pMusicPlayer->nMutex[i]); @@ -592,7 +596,8 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa break; } - case TINA_NOTIFY_PREPARED: + //case TINA_NOTIFY_PREPARED: + case TPLAYER_NOTIFY_PREPARED: { MusicPlayerIndex musicPlayerindex; bool isPrepareNext = false; @@ -635,7 +640,7 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa } break; } - + /* case TINA_NOTIFY_BUFFERRING_UPDATE: { int nBufferedFilePos; @@ -647,9 +652,10 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa nBufferedFilePos, nBufferFullness); break; - } + }*/ - case TINA_NOTIFY_PLAYBACK_COMPLETE: + //case TINA_NOTIFY_PLAYBACK_COMPLETE: + case TPLAYER_NOTIFY_PLAYBACK_COMPLETE: { //* stop the player. //* TODO @@ -677,17 +683,20 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa break; } - case TINA_NOTIFY_SEEK_COMPLETE: + //case TINA_NOTIFY_SEEK_COMPLETE: + case TPLAYER_NOTIFY_SEEK_COMPLETE: { LOG_EX(LOG_Debug, "TINA_NOTIFY_SEEK_COMPLETE\n"); break; } - case TINA_NOTIFY_BUFFER_START: + //case TINA_NOTIFY_BUFFER_START: + case TPLAYER_NOTIFY_BUFFER_START: { LOG_EX(LOG_Debug, "TINA_NOTIFY_BUFFER_START\n"); break; } - case TINA_NOTIFY_BUFFER_END: + //case TINA_NOTIFY_BUFFER_END: + case TPLAYER_NOTIFY_BUFFER_END: { LOG_EX(LOG_Debug, "TINA_NOTIFY_BUFFER_END\n"); break; @@ -700,7 +709,7 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa } } - return; + return 0; } /***************************************************************************** @@ -754,8 +763,10 @@ bool musicPlayerInit(MusicPlayerCallback callback){ memset(&musicplayer, 0, sizeof(MusicPlayer)); pthread_mutex_init(&musicplayer.nMutex[0], NULL); pthread_mutex_init(&musicplayer.nMutex[1], NULL); - musicplayer.nTinaplayer[0] = new TinaPlayer(); - musicplayer.nTinaplayer[1] = new TinaPlayer(); + //musicplayer.nTinaplayer[0] = new TinaPlayer(); + //musicplayer.nTinaplayer[1] = new TinaPlayer(); + musicplayer.nTinaplayer[0] = new LuPlayer(); + musicplayer.nTinaplayer[1] = new LuPlayer(); musicplayer.needResetTinaplay[0] = false; musicplayer.needResetTinaplay[1] = false; @@ -776,11 +787,11 @@ bool musicPlayerInit(MusicPlayerCallback callback){ } - if(musicplayer.nTinaplayer[0]->initCheck() != 0 || musicplayer.nTinaplayer[1]->initCheck() != 0){ + /*if(musicplayer.nTinaplayer[0]->initCheck() != 0 || musicplayer.nTinaplayer[1]->initCheck() != 0){ LOG_EX(LOG_Error, "initCheck of tinaplayer fail, quit.\n"); notifyCallback(0, PLAYER_ERR_TINA_INIT); goto ErrRet; - } + }*/ musicplayer.nStatus[0] = MUSIC_ST_IDLE; musicplayer.nStatus[1] = MUSIC_ST_IDLE; diff --git a/package/netease/ihw_player/src/libplayer/player.cpp b/package/netease/ihw_player/src/libplayer/playerapi.cpp old mode 100644 new mode 100755 similarity index 99% rename from package/netease/ihw_player/src/libplayer/player.cpp rename to package/netease/ihw_player/src/libplayer/playerapi.cpp index 176ae32bd..2b04318a1 --- a/package/netease/ihw_player/src/libplayer/player.cpp +++ b/package/netease/ihw_player/src/libplayer/playerapi.cpp @@ -14,7 +14,7 @@ #include #include -#include "player.h" +#include "playerapi.h" #include "musicplayer.h" #include "dlist.h" #include "audioplayer.h" @@ -27,7 +27,7 @@ #define TIMER_UINT 1 #ifdef CALLBACK_MSG -PlayerCallback playerCallback; +IhwPlayerCallback playerCallback; #endif static SEPlayerStateCallback seplayerStateCb; @@ -861,7 +861,7 @@ bool uvTimerInit(uv_loop_t *loop){ RETURNED VALUES: bool of init status *****************************************************************************/ -bool playerInit(PlayerCallback callback){ +bool playerInit(IhwPlayerCallback callback){ playerCallback = callback; return playerInitInter(); } diff --git a/package/netease/ihw_player/src/libplayer/soundeffect.cpp b/package/netease/ihw_player/src/libplayer/soundeffect.cpp old mode 100644 new mode 100755 index 84f4d757a..ccd261f95 --- a/package/netease/ihw_player/src/libplayer/soundeffect.cpp +++ b/package/netease/ihw_player/src/libplayer/soundeffect.cpp @@ -19,7 +19,8 @@ typedef enum } SoundEffectIndex; typedef struct { - TinaPlayer *nTinaplayer[SE_TINA_PALYER_NUM]; + //TinaPlayer *nTinaplayer[SE_TINA_PALYER_NUM]; + LuPlayer *nTinaplayer[SE_TINA_PALYER_NUM]; SoundEffectIndex Index; volatile PlayerStatus nStatus[SE_TINA_PALYER_NUM]; u8 nError; @@ -53,7 +54,7 @@ static char *sourceRec = NULL; RETURNED VALUES: void *****************************************************************************/ -static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* param1) +static int callbackForTinaPlayer(void* pUserData, int msg, int param0, void* param1) { SoundEffect* mSEplayer = (SoundEffect*)pUserData; @@ -63,13 +64,15 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa switch(msg) { - case TINA_NOTIFY_NOT_SEEKABLE: + //case TINA_NOTIFY_NOT_SEEKABLE: + case TPLAYER_NOTIFY_NOT_SEEKABLE: { LOG_EX(LOG_Debug, "TINA_NOTIFY_NOT_SEEKABLE\n"); break; } - case TINA_NOTIFY_ERROR: + //case TINA_NOTIFY_ERROR: + case TPLAYER_NOTIFY_MEDIA_ERROR: { for(int i = 0; i < SE_TINA_PALYER_NUM ; i++){ #if LOCK_ENABLE @@ -91,7 +94,8 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa break; } - case TINA_NOTIFY_PREPARED: + //case TINA_NOTIFY_PREPARED: + case TPLAYER_NOTIFY_PREPARED: { #if LOCK_ENABLE pthread_mutex_lock(&mSEplayer->nMutex[mSEplayer->Index]); @@ -111,7 +115,7 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa pthread_mutex_unlock(&mutexWaitPrepared); break; } - + /* case TINA_NOTIFY_BUFFERRING_UPDATE: { int nBufferedFilePos; @@ -123,9 +127,10 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa nBufferedFilePos, nBufferFullness); break; - } + }*/ - case TINA_NOTIFY_PLAYBACK_COMPLETE: + //case TINA_NOTIFY_PLAYBACK_COMPLETE: + case TPLAYER_NOTIFY_PLAYBACK_COMPLETE: { //* stop the player. //* TODO @@ -141,7 +146,8 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa break; } - case TINA_NOTIFY_SEEK_COMPLETE: + //case TINA_NOTIFY_SEEK_COMPLETE: + case TPLAYER_NOTIFY_SEEK_COMPLETE: { LOG_EX(LOG_Debug, "TINA_NOTIFY_SEEK_COMPLETE\n"); break; @@ -154,7 +160,7 @@ static void callbackForTinaPlayer(void* pUserData, int msg, int param0, void* pa } } - return; + return 0; } /***************************************************************************** FUNCTION NAME: soundEffectInit @@ -175,7 +181,8 @@ bool soundEffectInit(SEPlayerCallback callback){ pthread_mutex_init(&mSEplayer.nMutex[0], NULL); #endif - mSEplayer.nTinaplayer[0] = new TinaPlayer(); + //mSEplayer.nTinaplayer[0] = new TinaPlayer(); + mSEplayer.nTinaplayer[0] = new LuPlayer(); mSEplayer.Index = SE_TINA_PLAYER_1; sePlayerInited = true; mSEplayer.needResetTinaplay[mSEplayer.Index] = FALSE; @@ -193,12 +200,12 @@ bool soundEffectInit(SEPlayerCallback callback){ goto ErrRet; } - + /* if(mSEplayer.nTinaplayer[0]->initCheck() != 0){ LOG_EX(LOG_Error, "initCheck of tinaplayer fail, quit.\n"); notifyCallback(0, PLAYER_ERR_TINA_INIT); goto ErrRet; - } + }*/ mSEplayer.nStatus[0] = SE_ST_IDLE; LOG_EX(LOG_Debug, "mSEplayerCreate successfully.\n"); diff --git a/package/netease/ihw_player/src/unit/cppunit.cpp b/package/netease/ihw_player/src/unit/cppunit.cpp old mode 100644 new mode 100755 index 53e286021..538ee82e9 --- a/package/netease/ihw_player/src/unit/cppunit.cpp +++ b/package/netease/ihw_player/src/unit/cppunit.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #define AUDIO_MP3_URL "/mnt/SDCARD/netplay/audio/audio.mp3" diff --git a/target/allwinner/mandolin-pv1/defconfig b/target/allwinner/mandolin-pv1/defconfig index 1e7ae92f7..20effa503 100644 --- a/target/allwinner/mandolin-pv1/defconfig +++ b/target/allwinner/mandolin-pv1/defconfig @@ -1529,7 +1529,7 @@ CONFIG_PACKAGE_wifimanager-smartaudio=y # CONFIG_PACKAGE_zlib-dev is not set # CONFIG_PACKAGE_ar is not set # CONFIG_PACKAGE_binutils is not set -# CONFIG_PACKAGE_cppunit is not set +CONFIG_PACKAGE_cppunit=y # CONFIG_PACKAGE_gdb is not set # CONFIG_PACKAGE_gdbserver is not set # CONFIG_PACKAGE_objdump is not set @@ -2552,7 +2552,7 @@ CONFIG_PACKAGE_libs2json=y # CONFIG_PACKAGE_libsocks is not set # CONFIG_PACKAGE_libsodium is not set # CONFIG_PACKAGE_libsoxr is not set -# CONFIG_PACKAGE_libspeech is not set +CONFIG_PACKAGE_libspeech=y CONFIG_PACKAGE_libspeex=y # CONFIG_PACKAGE_libspeexdsp is not set # CONFIG_PACKAGE_libtalloc is not set @@ -2821,7 +2821,14 @@ CONFIG_PACKAGE_SPlayer-demo=y # CONFIG_PACKAGE_config_server is not set # CONFIG_PACKAGE_factoryTest is not set # CONFIG_PACKAGE_golangtest is not set -# CONFIG_PACKAGE_ihwplayer is not set +CONFIG_PACKAGE_ihwplayer=y + +# +# ttsText Mode Select +# +# CONFIG_TTS_TEXT_XUNFEI is not set +# CONFIG_TTS_TEXT_ROKID is not set +CONFIG_TTS_TEXT_NIL=y CONFIG_PACKAGE_libuvdbus=y #