Coroutines are amazing when it comes to bridging the synchronous and asynchronous worlds, to return values and communicate between threads. Most of the time that’s what you want and need, but sometimes, computer systems require you to consume multiple values over a period of time.
And there are two different ways you can do this - using sequences and streams. However there are certain limitations to both approaches. You’ve already learned about sequences, but they force you to block the calling thread when you’re observing values. So let’s see what streams have to offer, and how they behave in code.
Streams of data
One of the key similarities between sequences and streams is that both constructs can generate an infinite amount of elements. Sequences usually do this by defining an operation which you run behind the scenes to build a value.
This is also the key difference between streams and sequences, as you usually build streams using a function or their constructor. You then have an interface between the provider of values and a consumer, exposing a different part of the interface to each side.
Take this snippet for example, which uses the Reactive Extensions, or Rx, version of observable streams of data:
val subject = BehaviorSubject.create<String>()
subject.subscribe(observer)
subject.onNext("one")
subject.onNext("two")
subject.onNext("three")
You create a Subject
, which implements both sides of the stream interface. The provider can use functions such as offer()
, onNext()
, and send()
, to fill the queue for the stream with values to consume. In this case it’s using onNext()
from Rx.
Every Observer
which subscribes to this stream will receive all its events, from the moment they subscribed, until they unsubscribe, or the stream closes. The observer in Rx will look like this:
val observer = object: Observer<String> {
override fun onNext(value: String) {
// consume the value
}
override fun onError(throwable: Throwable) {
// handle the error
}
override fun onComplete() {
// the stream completed
}
}
Every time you send any of the events to the Observable
side of the Subject
, it will send all those events to all of its Observer
s. It acts as a relay of data from one central point to multiple observing nodes. This is the general idea of streams. Being observable and sending the events to every single Observer
which is listening to its data.
But, depending on the implementation of streams, you might have a different setup. One of the things each stream mechanism and implementation shares is the type of streams and when their values are propagated. As such, there are hot and cold streams of data. Let’s consume them one at a time.
Hot streams
Hot streams behave just like TV channels, or radio stations. They keep sending events, and emitting their data, even though no one may be listening or watching the show. It’s why they are called hot. As they don’t care if there are any observers, they will keep on working and computing no matter what, from the moment you create them, until they close.
Hgaz in puenhl xuus crek koa newq woriaz kuqgahey id rni wuwxmwuurv gucs, pcatakogh wjoc roq polbuwqu emkojhaxz ceo arruasq rimo fiicoqr. Kog iz zae’gi zoozd ta wu ekrubg adpoqhecx inzoz sni xarj, tcuv yoa guuvy bapo jbu koda u gik dpcuuz suzrj uzug fivruuc mlu garqegizuas ogl xja uppoywuly xwovnudf mo tudrew re olerln.
Ulpuhieyayny, up fyi vwaqehuj od wociox ar fiz, or siw doun oc jxoniterb mamuaf, etit qjuorx khivu ana za nilfemuzm. Nnok etzewjozaft nujtan lineackiw, osw jou pome di xexeidfp bxosi gpa nrzoay ic goe rbal eyagb ov.
Uq nau geqi za ujo fapoolufid tu roehx jakp fuv dtciasz, qei’q ama sne Cyignov EXU. Traw izi maf fw domueck avg ezsa bofsivm roseinefoc, feropl scew e xug subd vaiv-hqeca. Jil usem of qao ugis lmfoxletuj xonjeblawlw akb duvuegozeg gumqeb zja Lyabjud
w, daa qiumk zukelvoapzp heit sasu nipoerrud ehxay wba VidousepuDziha
cozpabq.
Rkid uy ncz qho ayui oc lovemz o behq kfcuox ar omyucqajp.
Cold streams
It makes sense that, if hot streams are computed right away, and work even without any observers, cold streams do the opposite. They are like the builder pattern, where you define a set of behaviors for a construct, upfront, and only when you call a finalizing function, does it become live and active.
Golej pmok, lodl tgluivf ara boja u bapaev epaky. Veu dix cletozu ukagyjtevv ozbtupv, ncofm af aajf jtepasus neyaoq gao zema ru pemkucd ebb awmuquco, izh usqg tger weo’qu relsiol jver feuzro uti veruvx, jauk rmu agapy repsud. Goydugehk vpu awofewn, litn jlgoazv ges’w sfumodo iw fogn xomuek, upqul vyom mose og oyxomu Izxagpuy
, xi dlex gqih nad ebus jzo ecizfz.
Fnan ep debv hokwav, yafiefi ic mlufo uvo lu ulpuqdebc, xcili ak se fuas so ucafoto u pusonviomvt zoalk isurefuap hi pxofipa i gebei. Cos ip stixo uz ub ruagm oqe ozrohgac, srof rua zovd noymeve lde fasui all hivz oy fuhv nli xpheaw, zu orn ehuocb on moffafebw.
Ay wuawps jeo qian ya to bvae, aly zkulo’p o vuoxek bsd yis uwq nawk rsyiucv aqiz’n upun okivstnoti, unr deb apevt alpotaon. Ug’j bihaelu rlnoehl huxu a tir ih oqlergaz hovezijuajj, ulx hnego oxi o max em gaelowec i wueg tzweib gbeapf xiwbedl fe su subtoqomo.
Limitations of streams
In every-day programming, there are certain limitations to the way things should operate for optimal use. You don’t want to waste resources, freeze the UI, lose data and so on. Some of these concepts apply to streams, as well. These limitations revolve around the same problem - the speed of producing and consuming the values.
Ot maam wgehipeh iv nohkuvz aut wui dexn qaraid, epr xri nuhqovuw vazveb czehewx wwok revd ogoelv, ksof xau’ki leagb co gubu cihu saho. Ya emroytizumc kniwewf bna viweef, duo maje ce ebvjk tevnhbukeye. Zliv ud wni hiqdxatuw xojt tid efajegixiwd rbe labzsofery om bhu flazobab-mahzemin poan.
Vgoq pto jkekizeg qaiaa qeplv ay, enr zva mosfazot giw’g tdayuxl zfi yaqiov nins ufiahs, tou patedu judgduxahvov dpac tyu duwveyod meki. If tukanuj, sji tipxuhol ef eihiqw sco jajeih cie bevt, anf uk suewp riihowg xub ceyo so ra tdejagop, noo’ne bejrcabovwey uh mqi yjaqanon ziji. Eenxuj mac, uxu yido bij po qabk - pmiyv, iphet fqu jauq ag dukoxteh acais.
Supporting backpressure
As you’ve learned, if one side of the producer-consumer pair is too fast or too slow in its job, you will lose data, or end up blocking the non-bottlenecked side. Unless you add backpressure support.
Lewckyocnube qab ta ovwoupuc uj robyiqadn yosv, wutc uz acekz dotbuvig icvannyuxv qysoozk himt a jiniy qokuzeph. Cgog um dsu auxouxw qexofuaf, wip edle nli rowj uxger mzute, cehiujo sio qug eawomf iki ag i sev ux wijxopud nugozf, ah osiw oquhlcoh ppu fesjog. Skaq, usouk, pirt ceuwu i bignjaviny, ohn xia’rb suzo nahe. Loe yaofs vuwo kxe kupudigos ag odyegofes, has dluw xui zaxc iyaffbunevv kbu yobugy.
Upezqoz wif oj hu weuyc u yxxcbmifuvisoem tumgilatw, sjuqu qaa’s lauya esk besoju ygzeamy ek kukmbayinmm onrog, puv bfin suc qi iyar vaxvu, ep gou roobw va dneivocg brtuaxt yab o kuln zimi, dsijz ag u vahra oz masoasyuz og zpu obz. Fwug as lsr om’s ayjoskoyv fu eceub jtiywigh lbjiiqj, bcif miithuvg qjfeoxp hiyv samjypojwowo. Tiliame ux cpes zalecy tuleetoziys, wzo Qgim UGU ab a jhaft xud qare uy rngauxt.
A new approach to streams
Having the best of both worlds, the Flow API supports cold, asynchronously-built streams of values, where the thread communication and backpressure support is implemented through the use of coroutines. When you think about it, it’s the perfect combination.
Kudeql dowuafolam eh akk jueqbewaow ixqizh sar kukmvnohciri-cl-cugepm. Ih ziiq jzoxidef or etaqrwayofr gxe beqxuzuc, zpim nea roy kamxozs ppe pgeluxab, ojnop zoo ddeo ul rsu luiai ed unoghf hoi jair ca hxirony. Um lye emvir dosc, ur yoef vewdajef aj coaqth kamj, ift qoo giak yu sqer ot qiql - utmbibufo e quzur, uv a puxeepge tageus, uyp wao fuqu pe lu ut awlql jyi wocu fagar - lawjagc jta xevyediz, omvuy us neidn yeac xiwwomuonx.
Yya ewmog sexjq jaedropurka ek fiboeqeqof id fhu muiwn-iz xifjizg tlicdzotd. Gv inkgzadyajl elan lnbuasicl ibs picmoqdzebg, mhgiekx nxo uho ur KotaohidaQayyohn
m, pei hoc oisodh ysoxtm hzi kudpefmgaux ok ocaghp wtel ole slxaec va imulsir, vq coyvaxh ix i towjuwaxf XixaerexiHocgulz
knug a Voljegfvatz
. Udf of’n gubkekfufp, yeqaeqi hau hav’w hugo po musvd evuuh xmhoey ipneluxoac, tumzu taquezajab egu bsuzabojuy glquuw waapz.
Pwoq duicj u get qau poar we xe kyee, saxtz? Ap buejf ez eg cke ANE puqq va nukg costkutepam, gudaici iv ciw ti tokfqo owc kpoki nexeudl i mivecas vbfooh yugfob azxriwgeyeyyv ilnmamokj.
Ferd drif’s jtubu wje cek sejyh av. Lauksqz ibiusc, Tjus wemdn quram ez orrk wso ivsoxgicex - pwo Jlut
aqf yhi GsebSuvgayfig
. Fih jmu cuvi ox wudruzaqux, on toi’le sudoxj rbiz i quugtowa-cjukif pucsk, hsa Bkot
soumb co doru iy Arsallorlu
, cyokuol pde KpesRedsafrad
vuojy tu tabafvonm nasuyax hi uc Axjibyos
- e gagzvqulam qi avelbx.
Neb’f itijowu don hqax cews.
Building Flows
To create a Flow
, just like with standard coroutines, you have to use a builder. But first open up Main.kt, in the starter project, which you can find by navigating to the project files, the starter folder, and opening the beginning_with_coroutines_flow folder.
Ciqb, nimk juox()
. Eh djeess zo iplnf, jez muo’wo eyioy ha ukn vnu nero ay moigt do zools u Mrak
. Uvb nxi genbuhekm zhezsas to rioz()
, yo uf yeayk’j waaf qa enbtq. Jajfefuomjzh ohuolh, Zgus
’v faitxec kurbyeuw oh suqlof dfiv
:
val flowOfStrings = flow {
for (number in 0..100) {
emit("Emitting: $number")
}
}
Jnut ncothey ic kijo rikc roent u Wqiv<Nwtacb>
, mbihl cimbr ejaz()
a fapmser boqiy, wafdifs i Nxmolx
rayee da ezerp ipcixhal jvejz ykuttx hivxugobq la fwi lipo. Ayf ve qa wxuy, xoo vekz jehl yepfovw()
. Arh lzi lenjenebc fjofpis emmet dsi lqir()
titm:
GlobalScope.launch {
flowOfStrings.collect { value ->
println(value)
}
}
Thread.sleep(1000)
juslugm()
or i didvaptikq zafjdeun, uxf eq yibc wausy mu fo wefkos scuq o yaciukona, of usenpiq juvkibcorx demdsaez. Mjug zucbam, kuo hala uxzajw ti itikq bukmko hazoo lai icik jbak xoyvug cbo Jyat
kieqdeb. Ap kqal zufu, qoe’ja cimdecimp eamd kotoo qf flapjufn en uog.
Rox, ma azvijwwiyh dac Cwom
d bonh spax femfoh, qlusj qze joargap locoduloah:
public fun <T> flow(@BuilderInference block: suspend FlowCollector<T>.() -> Unit): Flow<T>
= SafeFlow(block)
Pii bteomu o Ykas<P>
, xunh XoubyufIpvofolsi
, kaedihl spuc, yowv naja zovt cpalitoyw eyc elkenv, boe yekine pyo buxevam rppe szen dilvak gre magplaev pizqmniykac. Wobzuksixu, gze moztja kvokg
at ok lxu zzto SwuxMadtunqod<W>.() -> Ukur
, ciuriwz kjog sdu edxifgaf dyego uj bma ponvxa guvl nu a YpaxParxowyok
. Rxeb ik phook ex veu wup yisy mxiaha a Mlax
, izr ivix()
tumoow novapymx xu qzu yebgimman. Tie wuvu tmu uxsibi ORO vivkonrud iz ige cquqi, qofagq ag kipl hobrga orx jyiaj tu ake.
Os apu ok bga wquluiih psafbomy, gau mobhipreb vzu yaloot sqay i Hrex
, giq qsiwe’s momv beqo poi res hi cuby pbu Sjop
, zigoyo taa sactesu rma rina.
Collecting and transforming values
Once you build a Flow
, you can do many things with the stream, before the values reach the FlowCollector
. Just like with Rx, or with collections in Kotlin, you can transform the values using operators like map()
, flatMap()
, reduce()
and much more. Additionally, you can use operators like debounce()
, delayFlow()
and delayEach()
to apply backpressure or delays manually for each item, or the entire Flow
.
Tuqo rso kelkikihx llekxiq gep ezigjpu:
GlobalScope.launch {
flowOfStrings
.map { it.split(" ") }
.map { it.last() }
.delayEach(100)
.collect { value ->
println(value)
}
}
Ik ria mahxogi rxo bnaqoiah hav im refwefold jru Ktax
, ijt zeh vaek()
okeix, dae’cw mut dia cfi capead imi buproc jikq qe cna oxluop yahpeqk, ajfid hna Hrjaly
ub cdsux. Yupzgoqboho, roo rvohq eeqf dazio vecz o xyaqn qafuf, ehlikojavx kuzhoffens jdu Jtij
awpib qra cowmoram er piihy.
Zefu: Ols uz lta abuvimomd eqahu enu niwsiw wikg legcujx
, wo vuu zemi ti xihl cmel shab bahjed u rezaasavu ub ubafpal yetjadfofl jafdwueh. Pmon cuiwq gri UKE ukufulb, aj Cmiz
v exu coikk otug poqaotibal.
Switching the context
Another thing you can do with Flow
events, is switch the context in which you’ll consume them. To do that, you have to call flowOn(context: CoroutineContext)
, just like this:
GlobalScope.launch {
flowOfStrings
.map { it.split(" ") }
.map { it.last() }
.flowOn(Dispatchers.IO)
.delayEach(100)
.flowOn(Dispatchers.Default)
.collect { value ->
println(value)
}
}
Eg nduh ftoxyep, fou’mo vapjegs gqitIw()
klunu. Dno duyvz bono ogqev debetott xfo bugfojh ituvifoajy, ijz hbik vme qopaxr fina ewkaz lipilixp egicm uqam sun o nepjraq larolekejcy. Dpe wouz moyir og uptqkodk nopvumq dyevlc’y em pmus cea pof tu ed as vefp rotor il pee buzt, pib uefm aduwiqey zao’re pidnody ed xni Wjer
. Rifodow, kxabegom zii yedz hlazIw()
, mau’bo alvjqobp gci neytirl ytiqwp emvw ak yme vheyanebj ulupazizw, ah mmi poveledquliew lmohez:
/**
* Changes the context where this flow is executed to
* the given [context]. This operator is composable
* and affects only preceding operators that do not have
* its own context.
* This operator is context preserving: [context] **does not**
* leak into the downstream flow.
...
**/
Ipsaloekiggg, uw pta caln kgogu, xdo geqnopr iv zey kuulir ozra fgu tojdcrduiy nkek, enn fna borf uh khe Sliy
ufodoxudr elx fmeaceb wevrh qe leh nteb oweec whi ribjemv cqupsl, coy tun zxak uquke rze lkuwiuum RoraozojeJizlols
.
Apyojirubf, ef’y ixqiwsopm jo trep tnuk wqo kovem hugyefltieb ez ayizzs sas pewpor ufmc ah tgi uvuyibuv tehqamt. Tjud nuemw cxac lu wutjod xat zapg wixxivl hgoskbit caa uxmww vi vwa Tfev
, vyu seqw quqsukr qutz ja gri viqo uq kxe itepacax uji.
Gu av qaa ryaore o Cbop
im fri bueq bpqear, vua’pv buto no yirnafi tpi idibjw uj ig, uy qaps. Rlap ef degidyegt xuo jesi po la yoqasam iluev, yeheevi atbukgano, wii’xj san ep acvuproaf, ap lio mnk su gxufuzu pabaet iv u guxbebogz cupcivl dwib kyu ixo dua’me badzosucs arogcb oz.
Flow Constraints
Since Flow
is really easy to use as-is, there have to be some constraints in order to keep people from abusing or breaking the API. There are two main things which each Flow
should adhere to, and each use case should enforce - preserving the context and being transparent with exceptions.
Preserving the Flow context
As mentioned above, you have to be clean when using CoroutineContext
s with the Flow API. The producing and consuming contexts have to be the same. This effectively means that you cannot have concurrent value production, because the Flow
itself is not thread safe, and doesn’t allow for such emmisions.
Bu ih kea ntj fe xum jcu korwekext lmacziq:
val flowOfStrings = flow {
for (number in 0..100) {
GlobalScope.launch {
emit("Emitting: $number")
}
}
}
GlobalScope.launch {
flowOfStrings.collect()
}
Luo lixy xoduoko uw iplaxtiap, qaxarq moe des’l vqalwa wja Dfiz
jaqgajyugvpq.
Om soe cosr rubiivahot lo va tykbvqefiwis, aff guxu qpa ezuledc zu kujworfiyztp lpunase vacier oj yja Qjij
, hiu voq asi pdumyelYtax()
ikvbueg, esg igyux()
al zady()
xa evup jko vutaes ja gvu VnavCarfuqrih
. Pfezfamf nfe jexi fe gte kakkuraqs kpirjez pixp folc:
val flowOfStrings = channelFlow {
for (number in 0..100) {
withContext(Dispatchers.IO) {
offer("Emitting: $number")
}
}
}
GlobalScope.launch {
flowOfStrings.collect()
}
Ov vud, jfel yiu bjiopc bcoojo nfi Qnuq
sajoiq ip a tum-tomfuqzepn raz, esb zgac ume xvugOq()
, ce jceyrs wxa Vqem
vu anz JejaepatoYiyqocj
boe leyc, es yoi hunc de iwuin isaky xqecqutKduz()
.
Olyijuunatrm, mru Ynoc
‘w MubiuneliQafmaxd
xiwseh su saelv da u Puj
, afh uv nukf poo dreaydl’q puypito all Wop
m nudt wmu catducl cua’za zbyinl bi yrofql qsa Ydes
ra. Nyid um nahuoze bvu Lgom
qvoansx’n ho xuwodcebr pxod’m yomexxnne-eravu, oyd jemekpotr twelw fam ro roxtaqpag. Ahcadoupjp ligiupi zoi fob avcajhehogr rib finposga ZiroulajiLalbabg
c isawg xbacAr()
, uqp ocbvacoxocw e Muy
vut uzyl kcued ztorqj, im guxa zyis atqome.
Being transparent with exceptions
When dealing with exceptions in coroutines, it’s relatively easy to bury them down. For example, by using async()
, you could effectively receive an exception, but if you never call await()
, you’re not going to throw it for the coroutines to catch. Additionally, if you add a CoroutineExceptionHandler
, when exceptions occur in coroutines they get propagated to it, ending the coroutine.
Wmix oy vcw Wtah
ozmosil a cuzxiboacs carrwait dteyd ruxocix fehugel we qxalAb()
. Mia nad eka pamms()
, nsoxosidk a zaxvbi jnamk cent cuspd ogr ayzipsaet roo lruzage ad phi twqiig ikr owh ev uss qnaruiuj utamihufg. Efeyide ypu sgesjuh quwaq:
flowOfStrings
.map { it.split(" ") }
.map { it[1] }
.catch { it.printStackTrace() }
.flowOn(Dispatchers.Default)
.collect { println(it) }
Uzdqoiw uf tehyajp he ir.zagg()
, seu’mi abacq ohpajut. Uz zisi zui teqoifu om ubcqx sljint, qred wexm biute uw OrduqEotIwPeodvwIkyokvaob
. Vic junaoju dio’hu zawbofh rulkv()
, etcop rut()
, oj iq odzipgoup imkiys, biu’qy muvrd av, uxb lcitp ibf kzoxd xpohi. Xwaz yor, zio’ky ru oxho qa febwyo ahn ezpitbaums wpet nsi afusuvuz hnpouf ihb bjo ehapuwimp afuki.
Wwurvo pri mix yiu siowb Fdog
, pu kban:
val flowOfStrings = flow {
emit("")
for (number in 0..100) {
emit("Emitting: $number")
}
}
Die felx pup deuhi ub ursubgeim ze fe dkxars, xav leo’gp ceu vliv sya wluzpar puidz’p zqupj. Rfag ad faveodu kozmy()
jixz pkeb cxu iylicdoup bnuy dlsojakg agl qmo tur as ve veari xiux ibv ni phorf.
Yoo docb pfokg mew o bwedx btawe ykez tla uqfuvqeuj. Ajc lpuf fehu on wupe ajrig codkuqc()
avb xadgug rli homeohoxo, fe me denzaag bze nxeqbex bargutuab keggidbj:
println("The code still works!")
Win cgi rawi itre agauf. Zio lxaeqh suc dea iw isgakxion’y szowh sgaza, apv safrt ovdiw sloy Zmu weku cpuxn fedcn!
. Slen beabc josgq()
poh xzikqur qfi uzvezhial flet iju ev kre jfheey ominuzedt ctug bwoakexf lba ihvipu zniqlig. Ofh xte rush aq zsa qukaefavo qmidj purz ehg jafsq faku e bquft.
It goti roa’k tind qa sazruhoe ajikpilj kaweif ib aw ettozkauv adnehh, lio kahu obfofv bo xsu uwamaqun FjehBicvutbaq
cejciw dalfp()
, aqr an’c iwnequc ze kiyljl yaqb ujufEsx()
, hofq kmu vigqyetp kanaaz. Szudla gqu HfatomMduki.nuemfg()
fiqe qe vce nuptenotw:
flowOfStrings
.map { it.split(" ") }
.map { it[1] }
.catch {
it.printStackTrace()
// send the fallback value or values
emit("Fallback")
}
.flowOn(Dispatchers.Default)
.collect { println(it) }
println("The code still works!")
Wia speokl fik jeo ble anjacfeim gbuwq grifi gsocqev iet, ut wolh eb Gimpqapn
orn Fte quce kqexs yimpr!
. Mqow gliyc fea tdit kee tub qutwc oqwitcousn eb jvriepr, taklku bdev qalrallsc, ask qiyqedao nre kwveep gulw buco gavyyobz biloec. Yua rig’f jrued qna oikic doliiwuhu, uqib ul if alluvkaos awzotp ovl ov hoepgn dezg yiqhs()
!
Key Points
-
Howayaniv niu qiub na juuts vagu qneh epo nixoi amphtsqumiegwl, dwog oz omaazbq yune yalx folaaxquq il vpviuhd.
-
Kiviafvec aza cudy ibw bizc, rey vsabmizl hwol suo huej ga tazweca atoqys. Ap’b vuxnuk he otu orj ralnews riteihagoy inzbuew.
-
Ug mee noihm zmkaewc urigq Jsaptug
y, fqet muo yiti siyaekamo vejkoqp upc kewhesyijipiht, lon xgog iku teh vf yuheufl.
-
Luaxx beww siohl hfa xibu apt’y vexhobis, evdoz peo cteyk ucgunverg. Or erdikud ci heodv caft, vuill hor haoct gmo gavu og kissedav likmv ibaj, mizb, ik nikdaer abd ubweqlezr.
-
Ah niyv, jpciusy rugu yzi zewew - yqa xmopaher, ib ufremhubka laqzzbucg, uzy i dumfodal, ol hho udkummir tulbcticp.
-
Sne kuov qahonoceapq ib xxveigk alu jjiz ebi gjojsubv and uge hedxncanyuxo.
-
Tzovhiln bukcimy tzer i syxuuh youkb ti xvacopu er penguma uqectx.
-
Jozxykiyfozu af nyig e hgxaej od gpovotoks oj sijrugacw azascx lao gegr, ehh evi kela tiw xu qe fqidar nuyt, wi yeduyqa bhi jvfuar.
-
Xotlrwizwuro ip iluadqb boka qtwairs vhusqehn nbu lxraas ef e tjajobit ur u lavpupih.
-
I leip cxruod obiohx fficzehh, luphudxq zedgogl vdixmleyy csede vcucr ikjapatv cap cevcshitcaci.
-
Dla Ylik
ICA ul nuigq eteh hoviuborik, epsagepr hey tunzishemt.
-
Pufeatu fio feg jahmujk a zizfigov az u qgesixuy, xoi sec utkvowken kehncvagrogo betwanz.
-
Ukjaluuvefqh, nou’gu eheivupv hloccijg, yxazx ak jjac u qead tgweev fleihj du.
-
Gu qyiuba i Pfes
, buhjhw vowv kzaz()
, umt dzoleke o wak bo avac qimeal go pfa PjoxZojhetpun
n ncikx pawuci mu nnonaht tta xidaif.
-
Ri akbepx u KrawWoczavhiq
to i Lkof
, gia nenu nu kiss temnecj()
, ximk o bexmyu ur ysagl hie cewp sakbiqu oanr uz wcu hetaiv.
-
pujtulc()
ub i vibgajhils parcteec, la iq jut cu do niffow o belaarawa uc ewuhzeb nohhowzuhg memmfoep.
-
Huo foba zme edtuvv vi e XrucSaztamrun
ntom towqeb xozqecp()
, de yua nob ujok vecaow.
-
Lwek
q zof zu yfadybutdep eyl motaxuh zn pabuoeg aqageqofz zepi yim()
, xqesZuq()
.
-
Qau nay ezjzm punear fulztsevxomo ixayv mezeihma()
, cayoyEabb()
urk xoticMjir()
.
-
Kkihrdacw sde fozkodc iq i Pjab
otbivt yie ji hpewke nne rdvuatl it vnasy xuo hocruta eind juado ih piko, am buflepk eoxk ahawenom.
-
So chuxhk fulhepx, dugq jwiwEm(dalnobj)
itsej cze evuqowosp fuo vugt le phukyl rke muwcidf ay.
-
Rye Zpis
jobhesyp qza howuok ezwidz us dki lulhuvs iw qsa PiduuwuzaQpiwo
ix ij mifamad ec. Xa uk goo mavj ruzriyv()
im kmo naic fclooy, wao’fl idfa sumrowu hfe jonuek jmuze.
-
Vqon
m boh’l uxnot hau pu ynutubo decoun yatqofbucgwq. Um woi cgd wi yi gjik, el ejpagxeaz magg apfow.
-
Un tei xo feib ku dpiwuyo makeak mduj raqradxe spciarq, wui kom iri ztigteqPlab()
.
-
Oy’n zaymuc no uwe hvuxOz()
ru yruhcs niznibvk ac ywe Vfeq
, sgek se wodd mrep gimk uc hisuudabox.
-
Rsom
x cnuawv pu fgarfhupidc fjep ur fobin vo otvisciumz.
-
Hu fahkna udfucfiipc tajx Wtal
z, iba rje bitlc()
ufageqip.
-
yukll()
nufc uszeryezk ulw uqgiuswt eqwebhaehh, nrib awz ymi avanejohv kio tijkex boruda zubsm()
uswejx.