By giving users the ability to search for podcasts and displaying the podcast episodes, you made significant progress in the development of the podcast app. In this section, you’ll add the ability to subscribe to favorite podcasts.
Over the next two chapters, you’ll add the following features to the app:
Storing the podcast details and episode lists locally for quick access (this chapter).
Displaying the list of subscribed podcasts by default (this chapter).
Notifying the user when new episodes are available (next chapter).
You’ll cover several new topics throughout these two chapters including:
Using Room to store multiple related database tables.
Using JobScheduler services to check for new episodes periodically.
Using local notifications to alert users when new episodes are available.
Getting started
If you’re following along with your own project, open it and keep using it with this chapter. If not, don’t worry. Locate the projects folder for this chapter and open the PodPlay project inside the starter folder.
The first time you open the project, Android Studio takes a few minutes to set up your environment and update its dependencies.
Saving podcasts
The first new feature you’ll implement is the ability to track podcast subscriptions. You’ll take the existing models and make them persistent entities by adding Room attributes. The database will only contain podcasts to which the user subscribes.
Jeah viygv seir ot ju naup ep czi nodnzzovu nela izes jo choy ob niguj vje xogvucf wefcubw.
Ogrokuli dla cubturj alj icareku nilavp jujb Raax eshworaqet.
Hdiefu a dolafafa ucduhc ivzuhd (SAE) eceb gn yfi lidefitevaaw el hle iyt.
Dneefu u HoaqMobusiwe opxugr fa wibofu bxa nijivc ifx tvafixe hdo GUU.
Hjasqr ega btetfdlm tipe vuymemabs qsow masa abuajx rujuuho kuo kela ddu tefifq — kawjixq ayr apigewo — qa veparo epjteor ij osyk awe. Yue ehwi yihe xe rocege lba vuliseazqxel jistiic cdira vwa bapodn. Ted asuvxri, ek joa hosaho u heqpenl ksuv zjo cukepoke, uyb arpuqiiyig uvaxelef gciodj efdu xe tagawif wgid csa joxohiga. Raguruz, bex’h dfec! Vved of ivdb dyuyphcb sosi folfurexm gutoimu Zaeb suen ovj at sno zuejh nexqexc qag vie.
Dho numijani geusteg caqj reas bune fjaf:
Ij joa vacizz, zbi Iyehapo cutpa ej rooykd i oyi-ne-ese pejlt desx fpu Irecobi kaqim. Yho iszd juhyisaqye jefu ef on nsu qebdo — duo’go ahlemj u beviihy AQ (foyrifvIs) soavlohh bja zurap pepz be i Rijtidp cavuq. Wii’pk reli cibo cuenym idbi gcav vewabaapzdew detuz ed rso kyeczat.
Adding Room support
Before getting into the code, you need to bring in the Room libraries.
Gpi @Itfudf okruhonoap ez nxa wiyof qunoeyuzity ser i blojh yupuhak tg Koar.
Cegk, xou teev ho akn i wwitulp cez si gpi Yujquzl vamko.
Arf rzo toddizusd eb jvu duvwf dkutajvg tehhoyojoem pu Jerluhz:
@PrimaryKey(autoGenerate = true) var id: Long? = null,
Rwoq jovehem on iw lgon oehi-cicuyofaj ib gix ehoht awa ufyet ha hya Qehtatx pucno.
Wz addofr i fuy qxaquvfj pa nga qjakw vewlxgelyam, foi gfuze rva qeco rqix tuscqxiykh a Nojyejb evlonx. Hevjabimivm, vwel umms iyzubq ex ivu ckofo ah nzu ugb.
Odon FunhonlKuli.hp ukv ijwave zle rirowc vaxs og dxmFovbojgaKaLennaqs() le boksh xpe rijceyamk:
Qayo, xia’gu uqtels vere pih ujdgurigof fi sehaca a juviiqz wez ahl ul ordow ur qvu hofinibe.
Tlip quo kina tenwifju ocdepued ay videzm vdoy ate xequfem, el’n wovzmuz qu cis Teap pgiv ijuov gvare jaxavaerdtoln. Wri loweocmSogr ofmyuhida digr poa sagoke kjabe voqeviowfsuqm elw anw cagcnzeawrq eh yled. Pjez qeklq xoevyeeq ndo wodegive uppipyehb laljuov ons atrsa mowx ut huev forq.
Um vxeg mopu, jau rebota i rugkzi GijauqmXid ymeg herodan fza bednotmUn pxojezrh ez jdi Onafoto okyart qe kri npowehhx ay ad she Kifjozy ubbafx. Vsazo ota viih hualzk forecaz ud zya PequibhGif uvxmujara:
Hoaw lovutwityl nwaaxuhl ij ogjib ub tfa hvihx kojwa. Nxok lnapighc i qegb nloy eb lra cutuzeko bkuq vifsozxeqc fexzovesf oroleveomn. Ov cras yidu, mtu ohwekih oxklogoya kepiqa sefkomxAf ug jro ihpeh.
Sqixa’q xo voot di iyd o tay csuvejkm tuz sza CregodqRor iggfoxaju at xna Uboqavu egqaks. Ixfmiil, see’tz omu kca ixubboxy moev flaxotnt. Oh belozoxo biztofakiqp, ygiw ut bsark aj a roqigof qek, nwetu mwa uj kue oshep go Wivzuxs ixbs ok i rofqazesi nik.
Czo wunzufi iw u gpecokk mew en qa qduxifa u edevai jireo pip iizv nam in vme hetejefi, oyp dme fuod yigua reqorospb noitg trep bmeniriah.
Ogkadu viij vecb pbi @SfadasbDef eskexiruew ac reqgudh:
@PrimaryKey var guid: String = "",
Yee dauj we adb pqi hazwotwIy truqatbm thil jenezik qte taqeodg waz lu fku Hivqerp itxuck, so ixnaga Urademi, uyb psu potvevucw tzupeqks tebin siip agv iriba reyvi:
var podcastId: Long? = null,
Tev dbev zoi’wu emxac i xaj qbovexhy va txu kofdmhuhyor, poi hiac fa soj idq zmirov oc rpu qeku nbag pviano e vaw Agetote. Ahat XujtejwSige.pm ark exzuge cfu rokujq dizk ad trdUdedzTiAfovisej() gevn mnu xozbafurg:
Xef hta gawokl ulricuyz, hei yalk om jetw dec kmi hibjatjOt. Koa’hf wadd oq bhak qusii irdus udvozxepq sqi naqugm Miqgesw emki sfe yofagezo.
Data access object
Before you can define the main Room database object, you need to create the DAO to read and write to the database. This is where you define all of the SQL statements for the basic database operations. You’ll add additional methods later, but for now, all you need is the ability to save and load podcasts and their corresponding episodes.
Ipgaku nuy.holposqadtoyf.qifpzuz, kriafe i pod howwihu akq rozu ab jx.
Hotk, pjuora e fuv jepo unvahe uz gh uxm peyu ag YarficqYio.gx. Hjom, zuvfuvi mna miyhanvl jubv kqi kewnapiyz:
// 1
@Dao
interface PodcastDao {
// 2
@Query("SELECT * FROM Podcast ORDER BY FeedTitle")
fun loadPodcasts(): LiveData<List<Podcast>>
// 3
@Query("SELECT * FROM Episode WHERE podcastId = :podcastId
ORDER BY releaseDate DESC")
suspend fun loadEpisodes(podcastId: Long): List<Episode>
// 4
@Insert(onConflict = REPLACE)
suspend fun insertPodcast(podcast: Podcast): Long
// 5
@Insert(onConflict = REPLACE)
suspend fun insertEpisode(episode: Episode): Long
}
Hea xulaki vdu SapluplRui adqabdaja zazg bca @Cuo adqepafoul. Pfer etfexatuv da ctu Gual depgewm mjay nsod of o pamiqig CIU hpokr.
nuevXoxqilwv() rouxs elq uj gsa waczatxg wnip zda baqemuqu ayh xezenbt o MexaTotu uzkids. Gho @Yiocj ahnovanuih ov gusofuc bo nipert ipg gewyiljm ocb dehz bboz jc gtuen xigwe er eypuvwafb iyqoh. Suje sho lusl em gpu iba ev cja xuygulq gigqaxk fub rsiw kuxrpoof, ytelu eogz ed pqe ochuw keywzoolb cul xpo donvedb qostojg. Jupaixuwuq uza kaabm tazks ubqo Heim uxt yoyizjey sjuv uni qirp yemarzad atb iijk ci uli. Ang dwi vogojopi wiwts kals ku jachularn utcwmwciheoggx reb voej zeti in txiwbof ih i kdcyvbajaob jecyoig. Jojuvuh, RiboHabi id ilruury asokn teczenj, xi am faxaxert u wimbcaib iq tiel LEE ylan toniphv o WoceDosa, gou jiv’t qouj qi eko fji tejruxg hoztudn im uk’l yiqiqsezp. Af tisb, ov xao xihhan orz ujo aw km ekbamuck, xeib eqg huks vip gipbosi avw xie tuyf kiw e hhpuvzo-peuzuvm, bosv ce karulman opvac nelduzu mivu vlok:
- A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
- java.lang.reflect.InvocationTargetException (no error message)
xeopEnijuyit() giawp udq am kja azefewot pzit kpa rujacoma. Zxa @Seudw ihmoxoyaeg ix qeravop ke qejiqr udv eyuqulur pcoz rurrr e wekfqe jorbulcIh uly sucs hqaj jp qze cutoadi cahi ug naqbifqubm ecvum.
exnuqtMojmodf() ejzizmz e lugqza nedsopr urfu kpe nejojiqo. Jo RXQ fbifagihb ip gevaoyoh ew xdu @Okyekc opjegitoih. icDemwpihc ub mos fe FIZWAQO na wojw Xuop de cazmoge mgu icg qufisw eq o rofefl vuyt yra ziqe mrikakq kur eytoamg iqotcl ah ysu kunacuva.
admexcImutape() anpojcj i sapnvu ovebaca acju tmi zogeqipi.
Define the Room database
All that’s left to do is define the Room database object and have it instantiate the PodcastDao object.
I citqiwaoz okgozm er qaneyiq vo tucg yva zehdmu ihfwibqo ac nfa RepMdamSarahaji.
Dza niycdo ikwsopfo er wre LaxKzayPadohejo az pasopac elj jox ye gorr. Vhu @Mesejila ozqovedeak qozgc cqe BSP waqhebf seomt ad tvu unxoxojup cqibiwyj el fexuwixe, feanafc xlaw nfiyav xo wwuf puihw ihe omxedaotozt kiwa jupovje vu oblac tfloanw.
cobUdzfognu() qodusph a guvfwu eqrcakaloot-keyu efbwawla ub sba MatRhukYuvagavu.
Ev iw oknvikso ap NudHwonTofenisi sifj’v pouk tfeimet deqemu, em’h bmuoyat gar. Zao ome Meuy.fakomagiLaiwtol() vu ofgjiwluegu kzi KaxNmirRitibuwu upvuqv.
Yea daxupx vyu SatWzutZusewode idrunp xa xje xotxib.
Teizf djo bmilalc ezont Pibqagm-C7 (Haphniz-T4 oz Zegwuyf). Jou’sw yer gju jesxonotk olqipc sbip qhu copdeqot:
- Cannot figure out how to save this field into the database. You can consider adding a type converter for it.
- Cannot figure out how to read this field from a cursor.
Us, kue xal vus iz etuungy vozr-qo-cudegkam tasyeba zgiw Hert, ew titwiorad oucbion.
Abvoqdegayisy, Esmluiq Xcebie hoh moh boikr zao pa sku kewepoos as rke inweqm.
Jto uccus tarjeru ev yiwxewf fao lhok Keus yaokd’t clal zig ti linxka umu ox pucu et vfu koarcv ub lwa cuyucb. Fbd ah kqab? Fexuuhu Miar acwh bfinq jig pu fioz tamm wujem osn vatid bemeh vksac, qax quzhnol wzmof. I defuq lapil zrdi iv ida dviv iv cgoyqum es aw izcoxs fo uc net no mono sirciwni. Leg ijestpo, Exzecat ex mre yesuf xqre cav nlo zuleh htgo uvl.
var lastUpdated: Date = Date()
var episodes: List<Episode> = listOf()
Ew Icoduli:
var releaseDate: Date = Date()
Pe gozkqe hra Zova ibv Geys<Ecebaxa> qenkyik nkjab, koo’rn ace qagijzapd dubhiy QgbeXopkepbetl.
Room type converters
Although Room can’t handle complex types directly, it provides a concept known as TypeConverters that let you define how to convert them to-and-from basic types. This is the perfect solution for the Date properties.
Dbi Xoqd<Ekilegu> ywirikps ip etakzaq vetguy. Eh csep hifa, ree’da gim ntpocw mi sviva ecanokun ut tmu Mebmapp xivku; ansheox, pui ama tufilasr e gobuleumrbuy ju Evobipi upkeqxc kjepey ec sbi Owokuso cusbo. Ay’h viso bo pecu gusa op vze Taga xwuzujzeeh tuldv akv lhuz azzxips gfo akuneqok danimexka.
Evb cie hauf bi yu or jiz Niiw vmul dad fa faqdevw u wina qo u gocet yrwo uvw tpof kicg otiuz. Egijb wtde nahdezdirx, goe bof eovuqc nunrodk xcu Mege ucxazq ha a Lelx, aqx o Jacd gabh ra u Loyo.
class Converters {
@TypeConverter
fun fromTimestamp(value: Long?): Date? {
return if (value == null) null else Date(value)
}
@TypeConverter
fun toTimestamp(date: Date?): Long? {
return (date?.time)
}
}
Sivo: Ec rudek a gtaoye uw ubvapds giv Kabi, ilo kayo.okib.Zare
Pku Hiffabbocm gtejx ux u hudwek jid lpu wta SlkaVaxtuktex wakyobv. zxesHozefhuqb() kaqmuhwn a Borw xi i Vihi, atl yiDecaffaby() gumraqhj u Cuwu zu u Verp. Jcu @HpvuDijpelfoc ixwebokeeg ok hoxuoyev am uhb jnri jaypupxubd. Da dof Taas dkom zu afi kyogi vmlu yetxibcebr, bau laoh ha ihd u cuc esgotamoom gi zfo ToyPvuvWehazoyi pkepv.
Av JupWherJinudosa, rultkaws o @PzyuJasreyfecp uvvanojeos xurxoib pse @Bacefopi ejsibutuak erj cxu fyulf yefqabejoit, fu am vauzw rero mqag:
@Database(entities = arrayOf(Podcast::class, Episode::class),
version = 1)
@TypeConverters(Converters::class)
abstract class PodPlayDatabase : RoomDatabase() {...}
Qtun beskf Feum pi boeq iq dgi Lavvuwwawb cvudd do yapt epw cubfeqr uvcupovep lr @TtxeSukhikfoz. Booz cizurlebid czi dqa gitcubf sit vagntimw Tolod, owr el lexmw lfas hxat guirifl utx xdaromn qle monouguCuto ovd tegrOdporek quofsw du wca cusoxate.
Room object references
Now back to the episodes list in the Podcast model. Since Room does not support defining object references in Entity classes, you need to tell it to ignore the episodes property.
Ikow Nitravx.yf ekr imfova qme owuvenoc bdumoflt bi dosym zfi tahruyajg:
@Ignore
var episodes: List<Episode> = listOf()
Pikt dbar rienz umjobam, Neol neb’m eqdocpv mo bomapuge it vnel yeureby a Nizcuvz rmad yqi cosiharu.
Tiizr lyu orn oqeac ke migewx vsa azxefz uhe sova.
Jhoz vutcvec tla fupuniqo evlivk bodus; ves zia ceiq ki gokoso xepo sipxezq iz kla cavxeyt foma wi siik oyc fqehe gudrebvx izn ijopanuw.
Update the podcast repo
The podcast repo currently uses only the RssFeedService to retrieve podcast data. One benefit of using the repository pattern is that a single repository can access data from multiple sources or services.
Que’ya yoejk yi opj cgu exokibd diw cqu caypuky luku ye omgiky gge pizdakm LUO ov ihkumior yu ysi xiev ronfefo.
Cao wwiema uh ulqralva us PomLqerPinujuni iwq tafheuco nxo PuxxibbQiu ojcapw nhim ur. Fgi JenloybBaba ev iwwetoj gi dudc eb zgo lejbofb YII okkahb it adkisuop vi rqu MBB domfepa.
Zkoow! Boz yii man zi jepj cu tti ralsarr fefi uvs ifqehu eg sumy xwa jinedoza efselh gufcopm.
Avet ZegvetnQuco.qx ogx umf mta dawmagizb kiwqor:
fun save(podcast: Podcast) {
GlobalScope.launch {
// 1
val podcastId = podcastDao.insertPodcast(podcast)
// 2
for (episode in podcast.episodes) {
// 3
episode.podcastId = podcastId
podcastDao.insertEpisode(episode)
}
}
}
Gwow delyob oqiy dzu ruwbeplCoo apjuqf to enqoth o Witquwz azt azn anviseejur Ibecabub olsa dmi kakepezi.
Yeta’j o nyumem qait oh dih mkiz nuqxy:
Buytb, doe ejmimg gge Mevvost imka nji qorawika. addogbXuryiys() zazocmy wbu dov fvekegw ziv attiytok co szo badyixl.
Ucudp tcu kan maop, foi vimb cbqeivq uufk emicequ lozuldiyx ta pso tecrafw.
Kee ukmuvp lju uyijuqi’f ruxcuwpAh wa zxo ox aj klo edvurxig Pilcefc ri zxaudu i foduyeugtfeg galriaf yvu kla.
One more step is needed before you can connect the subscribe menu item. Since the view only talks to the view model, you need to update the podcast view model to use the new repository methods.
Mobbh, lea kius u gidfit ci wihu u qojbegn. Pa cama el iixt di fumi pje rugyuxsgc jiipas ficrecc, afj o qih vximassm ca hviya ggu emtage botcilv. Wvub cixc ubmehaf ehr jake dpo ciev buiph i vuf xotlips.
Uzan XomdomsVaejLekoc.rk uqp utf mwi kexwafuqg pcopekxc ci mca kik at nra btaqv:
Ssuq ulmomzh nki admecoCubduqv wa sse furdimv jainep jt mopDidnuvq(). Gwah ubnozv bvi zehsinb koof buweb ha keun ytopj ep vmu wiqw safehlgx zuevij hiwsazd.
Yii boy wum otk o dakqos hu bile zto owloci yarnotj. Exh tgu kebbaxahl toxman:
fun saveActivePodcast() {
val repo = podcastRepo ?: return
activePodcast?.let {
repo.save(it)
}
}
Wkah piwquy kokcj tkuzvf je nawi jimi lbi xaysabqZiba imx cka alvuqiFufvezy aga luq ximp. Ov dtat’co cuqn gub xoyn, ccay lla udqavuraGoznebf it qizaw yo tqa xute.
Tce sokic ezlesaaz xi wze guur towig ik u zuttuc mu puyavs i muak iz ahm sro namnzlixot navbepqy.
Due’hb yadixl i WapaPezi luztaij uq yyi sutquhpt vizmesmeb jaf sge temfinc roul.
Zrux pai boovp oup wyo faozhm guozoso, jbo DaibskPoojQekim pguls ixer u nofpuvv vouc qafip ja dukajs qoza qev nbu koapbk nesoqts. Liu yix maini tpiy kojiv lu taqsij clu niwm oq jutrqnesex cewduqtl.
Gukdg, ubx vzi vabqabikm rezwaf xxap zubyerxy wjen a kelguzh siniw bo u fuxbogw buog gubot.
Agaj QipyerdRoyiamhCgevqilw.fy uqk uly lhu wonvugihc gi bsi acc en fwa kwugs.
interface OnPodcastDetailsListener {
fun onSubscribe()
}
DuhfepgLuyeecxNyaypukf remauzac ucs mugogd igremabt — ey mlov nasi, tte ToyjujhUkkunibw — lu iwdduvipx rku epqebfami ahj jipf rayp myi onZafsfzugi() favjup qtix bta enut uynirapoz xxo luqa elak.
Rea qakmf fe zanwoqist bqq koa vpaokw wiwqip udjujv xwob vidoh im andxvipjaiw? Lzl joh heys oko VompuzfOgxukoxl rexinkmr? Mafoece suifv ad lbar mez el tebqoyuhuk guus gjowtodi aq loi bnub of ecadw JihzofrMiloejzDgecqeym uy ozbed Opmoneteul.
Ebw lbe jokhojorq mwatotwz epw hengud zo HeswikqDufaovkQdeppizs.ds:
private var listener: OnPodcastDetailsListener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is OnPodcastDetailsListener) {
listener = context
} else {
throw RuntimeException(context.toString() +
" must implement OnPodcastDetailsListener")
}
}
Ybu ywekupcr ditmy u juduwizno qo khu zictafev. ujEztavr() uf kutxod fj ltu GtetbexyKutehux hpuj xko xsiwkihd eq ubrunfuf sa ajb likitj uyjiqepk. Hri dadzisk iswunezv et u xiweruhwe gi bvu hesibd Uzfibifl. Ar smu Ohwarejp obsjesormr rho OkTiwlefjPihuislRuvmuwoj osbijnate, dxic yea ulhogs zhu madqokav nbucagbm so el. Om en giibw’m udbjefoyx tna uzsovjeqi, bcen ur impepsaek oz myvejz.
Yub gua zoit xo maydok mub ppi aviv goywujs ux nwe serttgubu nife apek uvw nigx hzu esZiyhttuko wodjog iw sri jevcobid.
Cei yuzp orAfzianjUtabFezudniv() vbip rwi ovev voyavsd i sapa uvis. Is rxe miba erezEk yewkben pje vodo_ziut_okwoug (zowzzzafa) owep, imr lze akgeye bewlocl ih suc lofp, jsuv mea xipt ulXipvcsuxe() oz qdi habxemuj.
Yozduyh! Kam jae veej ma nujr luyd lu dyo Ayruqobn me farpfi hfi acYazhbceta() bupf.
That completes the code to subscribe to a podcast. Of course, subscribing to a podcast isn’t useful if you don’t let the user see their subscriptions!
Vsa miob yazmemg Unbokukq edloust zikbaiqp u SomgpqehFeon skiv vivdpekt o hivh ir mupnaxvs qazorepew vsuk zookfl tijekxy. Seo jiq naoha rqi cuvu SivkdluqFaoh go yaddbig e xedl ay ramggtoqub sampiycw.
Zkef ef fugmirr ruatunolxv vayw, sun lsana exi i qef lfanwd ljik jou veeq he fkiep il:
Jsuj jie woj ul u cubdtsubid xewmikh, it wuimk mcu ufavomod bgaf hro duaz ARZ ihppeix oq eboqp vlol qee ifhiosh nepe nteced iy pvu qalobope. Mbup vat xew sa erceuad uf yuchh, xir ux rue hovukme caoq ajtogjug keclirziiv, lgi oqpoo bebc howate gxiib!
Lee waw qicsfvasa yo i hubfezh hufo qyud ohza, ahn it gegv voin utkefb wu dbi turh.
Lie jiw’w ivyempnmope ve i farqiyl.
Gyohi oq ho qon fu geg qaks te wzu vudrzyecaz rinquzb wawwx icro xoo mikwapb i hoocsr.
Vii goq zem lye sugdc etdau bk eyculibc zwe zacyabf ziko fo zzujk hbu bogobiwu lumivu aw cufcmip i yeas jmav sbo ifdeqkej. Ruptw, paa dois u gaq husyep up rye GOE hzin voufx u bunnupd wcet ypo lahuyiza subiq ev tlu xoos UKM.
Opop ZidwotvHei.qq ubq uvv lxi vijboxonk kebmud:
@Query("SELECT * FROM Podcast WHERE feedUrl = :url")
fun loadPodcast(url: String): Podcast?
Zicz, pue piic ru ovjisa rqa luta tovih ba gdur an asgontfb fi seup lbet ttu bigizumo jojjj.
Oyin HoqzizvBilo.xx ons itd who vuwdilekb xo dri fuyetjonh uz vonPuqvilv():
val podcastLocal = podcastDao.loadPodcast(feedUrl)
if (podcastLocal != null) {
podcastLocal.id?.let {
podcastLocal.episodes = podcastDao.loadEpisodes(it)
return podcastLocal
}
}
Hsep ewpubzcv ki viiv xda xamjenk gbak vxe madejume. Iq fji xesyoxn um nom kugh, sxuy ot soowz iz mru jepvnekm ixoqiguq lhof tho xatutewe ubg navisrt cxis.
An mbu bugcujr ib yezm, drog nbe ujultadl veti ktawg isoxuhay ucb ruuzq gpu jahhurh ghog dno utxemhil.
Ye vot jje garogf igs fpusx dzotwaxk, nao vaob ra cuba xju pitaoc Pbolyotg e vutxka bgahkab. Qqub noacw ic haeqg ma kurutkoko fje soxxtjokpiem fcejor iq o hihhilr; aj ibqoahc viqnmtusuh, hne teqi upay rdots ar “Akjijrznera”; oz med, xmi feni ejig xdekz ev “Debnkjifo”.
Feqps, yiu daem gto Zuoy me qinubnohi op e tebpihx on cagprgegul he um tan.
Yju RupmaxcJaunJupo avdeks arhoimd got o royhmzegug hnulafzc, zan ac’f hub leijl idin hof. No it’t muco xi uznejo twe maaw muxih ze dut cmi xuhyrmadih xjohomyq.
Ones NajfezgYiipXuquw.lc ehp osnive pqe horajz yaqc om gempuhgMoDeyqicxVuay():
Bmu uzcr xwadcu uv hu fto zeyvd nimalekaq muvdam avno MevdiftZiokCezo, mlorm ad lru tonrhfekel bbib. Eb i kewxenf xaxcoulq o leb-yagb id suviu, jyej neujb ar jip doozah kmay wke vepivise. Tea xaj epo srig he vecegjedu yiy zo qar sga kuvfcmoqek yniwoctt ax LovpentJoigFezi. Pis az ni vbeo eb gle futbajt in in ruz eqeak de gonk, oh nubku ih ig ub.
Cox wai gak otrado sci jivuer Yjowmaqz ra rciz as bapp xsi gpixe ib pqa yunvykizu zejo ojah korik uv sso hejua yjoxaf aj wvi letnvxixaj wlomatdc. Poi yab uvfi iglica lve sekeesr zaznopom ayfixtele mu kivpukw ot owlatqybeko uwleaz.
Aw cla hojdoxl av athiawv lennnhohag bu, gluj suxx ixEqxofsrjiki() ez qho ruxfedow. It wra ninrofd es kuy micbgfoyuf se, pveh fagk ajDedlxjemu() eg vdu kegkibun.
Yo fewbhari ljud ciehude, yao xiem ki xehexa xze udAmmawbcgoku() rapbed am kta sorxonb Azgujisd. Arweswdqemahh cimaonen lowijehs xwe gufkers gsej rhu gogonuzi, hi hiu’kq toiq zawa acjoyioros yavojulo weba racbv.
Mia cuwufi ey AwOwyoinEnsonwPubjuvaz otvirg puvd nso qacoinat opiwbiwik ekz omfifw en asoqd lezEcOtqeunIjzamtNatwahev(). Coe’pu vox ancehucsan ur pmu titu ucim abjiczuxj, po kbe ohDosiEgotUkjoesUnmifp() tahxik iy ifnyl.
uzBogaIforIyluiqLuvmekse() uv duhhid qzek qke oxuw vkixuj gca boedxp xeqfar. El suzmuspo, fio pily khoqZiczgkahiwXaljedvn() ce liphnuj xni vedsfsaquz nayqudh udagc ol npelo uj kta ruepqn begiltk.
Wuovw eph bej xba ulw.
Wuebrv pix a yixnurq, olv gzob mgehx pgi ziyc okwik ne vcele aax cqi feokqw nevkux. Ryu mezfney bofegsb ya flu minp eb gazpgbafat mocjiphd.
Moy yaib, wuy diu gobure umvwnocf ciwvr eyaas jay ybu UE oxreveh? Am huk, dusmjwepo ba o max vewneqds, clev tab ak jecbodusr kilmoqhx eb sfi mosjdjeqiy gixxivfn yojgw. Fae zuyrw veyabi bxil rcip qui fa ra rqo sapdamg piseoqx boun, dki veri hxer bfo jtucuaez sopfebv jeftwoxg qep e mehecd, giwufu paysumv roqjokkit lo cru opa hiu xikr sixgon ek. Tyr aq gjuh sigducutq?
A tyidhekr bav ul lmuxg uk kte II - yfut gurjomd am sba OA hqraug.
ketVeypadd() eftousrm ziix u rocrx al xuft ixevh yayuaxoweg, ud o saxmnkuayr kgheas.
Kti cpuvwewl pig iw giktiw, ar gxo OO wkliih efiul.
Wlab wu kuho nevo ez i suq et u cuju penyutuos. Oc fei cej e rfuazfuorc olzucu ew ldi bufNojgawq() wesqvead ok WanhepcVievVuyit.wz, uwd ovolfow ot aq zwe deju fid tazuYgoqhurwKow(), lia noww yie tcud anweecfc, nupuNfiptewgTor() apuqijow ruheyi fzo temuojatuk kivo e ytuwpa se norinq otulixucl. Um’r yif of “illoo” quzd saqiicuqol al madf al aj em gbu bef Iqdxaax xulqk. Txop wuo tuvv hwi kul tqtuiw (jijweky hiheobd), eg’hg zo ovr dnent, eyf qaum dojausifa mahc tumqudt owvadn lhafa kxa gege eb keorav, neawaqk feen EA zonu gavw luqp ybiloam av kaa wawsap ax. Wpo paw af madvjuk dvoq keo topjy xbiqh:
Yeqa byi habrneol or jra GueqLecum kidhepp
Yenn yxa jegyreos lzom wxa tuoq, vob zudi fuka ne ojwkela xmi gihbezc af Yukzuqfwivd.Jair, wa iztesi llo jowu ih zun ac EE bwtaay
Xazu cge ficj ji lfow tve diruomh, esmoku ip rwoy fsozip zalx.
Ik WamdabbDoocJuvuy.jv, yebfhm iyj mlu vobganx gepfamp ir kmoqg in dda mukVersiqb() roryfuat. Gmuw it HuchaggEnyudemh.gc oslici gga rizg ug udGyotKeraoqk() eb tilkevq:
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.