pax_global_header00006660000000000000000000000064146063240240014513gustar00rootroot0000000000000052 comment=9f1d9a3af2c20e7b3076be8e3ee7aabb753d4466 leptonica-plumbing-1.4.0/000077500000000000000000000000001460632402400153065ustar00rootroot00000000000000leptonica-plumbing-1.4.0/.gitignore000066400000000000000000000005001460632402400172710ustar00rootroot00000000000000# Generated by Cargo # will have compiled files and executables /target/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk leptonica-plumbing-1.4.0/Cargo.toml000066400000000000000000000006611460632402400172410ustar00rootroot00000000000000[package] name = "leptonica-plumbing" version = "1.4.0" authors = ["Chris Couzens "] edition = "2018" description = "Safe wrapper of `leptonica-sys`" homepage = "https://github.com/ccouzens/leptonica-plumbing" repository = "https://github.com/ccouzens/leptonica-plumbing" readme = "README.md" keywords = ["leptonica", "image"] license = "MIT" [dependencies] leptonica-sys = "~0.4" thiserror = "1.0" libc = "0.2" leptonica-plumbing-1.4.0/LICENSE000066400000000000000000000020561460632402400163160ustar00rootroot00000000000000MIT License Copyright (c) 2021 Chris Couzens Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. leptonica-plumbing-1.4.0/README.md000066400000000000000000000034421460632402400165700ustar00rootroot00000000000000# leptonica-plumbing Crate to expose a safe version of the [leptonica-sys](https://crates.io/crates/leptonica-sys) api. This is designed to expose the C API of [leptonica](http://www.leptonica.org/) in a safe manner. Adding value by deviating from the API is a non-goal. That is left to libraries that build on top of `leptonica-plumbing`. ## Motivation I'm a maintainer of both [leptess](https://crates.io/crates/leptess) and [tesseract-rs](https://crates.io/crates/tesseract). I noticed that there was a lot of duplication in how they interact with both [leptonica-sys](https://crates.io/crates/leptonica-sys) and [tesseract-sys](https://crates.io/crates/tesseract-sys). Having multiple layers of abstraction in `leptess` and `tesseract-rs` made it hard to reason about their memory safety. Having a safety layer that stays simple improves the correctness and maintainability of the above libraries. ## Testing To test for memory leaks, test with `valgrind`. ```bash cargo test --release && valgrind --leak-check=yes --error-exitcode=1 --leak-check=full --show-leak-kinds=all "$(find target/*/deps/ -executable -name 'leptonica_plumbing-*')" ``` You may find that leptonica always leaks 16B of memory. To test with a manually compiled Leptonica, test with additional environment variables ```bash LD_LIBRARY_PATH="$(pwd)/../../DanBloomberg/leptonica/local/lib" PKG_CONFIG_PATH="$(pwd)/../../DanBloomberg/leptonica/local/lib/pkgconfig" cargo test ``` The two can be combined ```bash LD_LIBRARY_PATH="$(pwd)/../../DanBloomberg/leptonica/local/lib" PKG_CONFIG_PATH="$(pwd)/../../DanBloomberg/leptonica/local/lib/pkgconfig" bash -c 'cargo test --release && valgrind --leak-check=yes --error-exitcode=1 --leak-check=full --show-leak-kinds=all "$(find target/*/deps/ -executable -name 'leptonica_plumbing-*')"' ``` leptonica-plumbing-1.4.0/image.png000066400000000000000000000112211460632402400170730ustar00rootroot00000000000000‰PNG  IHDRШСR—3„iCCPICC profile(‘}‘=HУ@Х_SE‘ŠƒD‚TБ *тЈU(B…P+Дъ`rщ4iHR\з‚ƒ‹Ug]\A№ФЭЭIбEJќ_RhуСq?он{мН„Z‰iVл8 щЖ™ŒЧФtfUьxEњ0„Q™YЦœ$%р;Оюры]”gљŸћstЋY‹‘x–ІMМA<Нiœї‰УЌ ЋФчФc&]ј‘ыŠЧoœѓ. <3lІ’ѓФab1пТJ Г‚ЉOGTMЇ|!эБЪy‹ГVЊАЦ=љ CY}e™ы4Ч"– A„‚ Š(СF”V Iкљј\ПD.…\E0r,  ВыџƒпнZЙЩ /)к_чcшиъUЧљ>vœњ |ЎєІП\f>IЏ6ЕШаГ \\75eИмњŸ й”])HSШх€ї3њІ а{ t­yН5іqњЄЈЋФ ppŒф){нчн­Н§{Ібпk0rЄZxќэ pHYs.#.#xЅ?vtIMEх(г§,ГtEXtCommentCreated with GIMPW{IDAThоэZyP“WзП ЯcX$$,ЏDP:ДЕvŠДЃVtThAы6jЕEq_pЌU[[ЦЅZЉ`ЦZБ€XЕ ua@!‚$1 –ЌO’яѓЭ3љXRЋиЏ}пїќ•Й9ЯЙЫљнsЯљн‹ŒFЃVЋ•Щdƒƒƒ–І˜LІ“'OКЛЛЏXБBЅR§=GЈеjU*UWWз_жЉйl6ƒСl6лиљѓч™LfZZš\.УоQII ЧC555§C%•JЃЂЂBЁЊЊЊПсТТТиlіБcЧўš ‚јс‡vюмЙuыжбд‚‚‚`щ.\И0† ЦЖЖ6є’Хd2ё’Œгщt>ŸтrЙ\.§§Фd2566BHјkz4›ЭиН{wKK‹йlM УАщгЇ#„ьььиlі{й3ЌЏЏПqу†JЅš1cF\\мЫшТЩЩщ№сУ .фёxСССшПђЬBЃбіэл7{іl.—ёO–@ XГf Bш%Ё „ЫхОѓЮ;џЪsˆ‡‡Grrђдщt---Ж€E„\.7ЎЎЎюююЖЏL&#Тгггоооњ/ …b{zН^ЁP˜L&wwwWWWлЪ}}}JЅвйй™Хb=у< ƒBЁ ТЭЭЭЭЭmШПjЕКЗЗзl6гщtƒё‡ЃЕ-Z­VЁPаh46›§‚ІF“ЎЎЎССA6›эрр-§§§нннt:ЩdўЁƒиl6FћГ@Q(†q8*•:ќ”—ЫхZ­– ƒС№јёуЪЪЪ3gЮ`Ѓх555'Ožlhhаh4^^^ёёё|№СјёуI4Ќ\ЙRЇгНћюЛЧŽЋЉЉбыѕ|>љђх‰‰‰†ежж:tЈНН>йЛwoAA‹‹ЫюнЛс8И|љђЙsчZ[[F#є’žžюччGŽфѓЯ?П{ї.ЧлДiSqqёЙsч:;;=<<цЯŸŸ––‹kБXіюнлдд„ујЇŸ~ъххEBЊВВђЛяОzНоЫЫ+!!!==}ќјё:ЎЊЊЊЌЌL$IЅR“ЩФсpЂЂЂVЌXЅЬ3JssѓЮ;Ч—ноо^PP  ccc?њш#rЙF”мммккZ Уrrr@S­VoиАapp0&&fнКuˆœœ@“žžўѕз_———їєєLœ8qУ† !!!—.]*((hkkcГй™™™ѓцЭ7nмнккzіьй[ЗnщѕњUЋVM: bБXŠ‹‹KJJЬfѓсУ‡9BшъеЋЇNBхччпН{їєщгЭЭЭ4эѕз__Лv­ЇЇ'X67oо,,,ljjRЉTZ­V*•"„X,–њщЇŸ@Ќ M&SII ‡УЁP(‰‰‰ўўўЁз^{M(‚ŽVЋ0aBhжЌY‰‰‰~~~'N73™Ь›7oZ,–ššš€€ƒіY,–ŸŸптХ‹u:ХbщыылИq#Žу …Ч󅆆Тч dqБyѓf„P||ќ'Ÿ|тюю>qтD„ŽучЯŸ'ыъ+V „x<о“'O б`08pРбб!фюююяяятт‚кМyГС`0Ы—/Їбh</""‚Ячлйй!„^}ѕUЉTњьЕЯУ‡BіііяНїƒС „X•œœЌP(@­ООyєшQђлЌЌ,„ЏЏ/ЙЊJЅЪлЭ›7“ОXВd XЫЬЬєђђzх•W`ЈsцЬЩЭЭe2™aaaАШуЦƒ•‡щƒЉ№№№˜˜??П№№p8LМММЊЋЋЩЅ;qт8H,CcII ДьмЙ“Ус„††’[}зЎ]FЃЊЮТТBWWW …;wюм)SІюмЙгзз7АD"l 7Ъхr‚ =z4uъT˜А^ЏЗB(;;ЛББQ&“ТšІІІj4šўўўццц#GŽ€кЉSЇ?~мооН"„ЈTъЖmлZZZФbqqq1дt‹-"+dB(""ЂВВR&“]О|bвКuыL&гhРЊЌЌT-ZДшіэлЭЭЭwюмйО}{GG(ќўћяЗnнjiiQ(mmmЙЙЙАП/^Мјg…тp8EEEbБИЕЕrJ„PQQбX |vяо=БXМ~§zЊЇЇgqqБT*§ўћя!P:thАBYYYр ЂЂ" УBщщщцхцціЭ7пˆХтКККФФD„ЗЗw__ŸХbщшш€М"332žžžUЋV!„VЏ^­еj‡Ыl6@ЫуЧI\BOŸ>ЕVRRIњi4šŒŒ PkkkƒFв~ee%ЙІJЅЦииXr[›LІM›6кзггc{ў_ˆ+јЁбh^ФNXX˜X,Оxёb\\›Э–ЩdWЎ\ЬуёFЅМННзЏ_OЇг‡8‚ќ‹xŽ6л /ЮPл ›B7nмXМxБZ­^Нzujj*Ч“JЅsчЮэьь|qч‘ƒIŒУпAМНН=КvэкoП§ЖЃЃ#::КЎЎЎЊЊ ђ<&“‰H6BШYИpсŸК!Л'ђšХ†&ЩW‰DЂ!‘n~ cxnqvvі№№P*•нннZ­vHа"т—_~QЋе!!![Жl9Ц?„ћ3ŠRЉьъъ‚Y@шњ›ˆХbт‚ч*•š”””œœœŸŸЏP( мммжЎ];ўќииXъpО‹JЅО§ілЦянЛg§—FЃњњњШsНЏЏђ>&“ —wp EК“ќЪЭЭmжЌYЁКК:№фххх0чЩ“'ПШД}}}!Ы)//oiiБ>!‹ЦХЩЩ‰$~u:œђЖCнhвллK*@P[[‹ Вс?X­VKіиббAЎЦX‰RЉ„YƒKKKBŽŽŽ/~їUQQёеW_eddмО}ћЩ“'>}—Я'8Žgddаh4…BБeЫ–ђђђšššK—.eff GGGШэ„BaiiiSSSnnnww7T'dм}vЩЫЫ+--mmm­ЎЎоП__NOII!З+„ЎњњњккZƒСљ>BЈЛЛћњѕы"‘шњѕыYYY€ј1”ЋWЏ9rЄЙЙY$8qvўЦI~ёЙ3 ЁPЁЁКККЖЖіСƒuuu2™ьMmm-ь*ЧSSSu:Щd*++ƒ* Чq.—ыщщigg‡уxnnЎС`АІИ\.ƒС`2™L&RŠЄЄ$’ЌВX,НННГgЯ&o‹с 6›Э§§§йййPр0™L‡;8%%…ЄšHКСЧЧЇЅЅ…ЌРЁx$щЎy,NЗoп>А‰a˜““„чььl ŒevttєїїgБXQQQ{іьнvэкЕ?K7„††ТggghйН{7p~жє •Jхp80Ш††XdИ-ЁбhK–,yы­ЗFЄ% 4ўњыЏ0’rSлЖmB7DGG‡‡‡ГX,ђB&))‰$ƒlг eeeфLПќђKШpHя\МxJE;;;fooяьььыыЛkз.…Ba—ŸŸЯчѓ ƒ‹‹ ‡Уyу7’’’ †‹‹‹ППJJJNNЮмЙs!Тqќјёююю”””]ЛvQЉT‚ ‚ƒƒгввvьиARРJOš4‰FЃaЦbБо|ѓЭјјј€€‡ИИȘ˜:NЅRЇM›ЖrхЪььloookvƒЧу………%$$7}BЁpвЄISЇN…2[ ‡††NŸ>\‹aXLLL\\NЗЗЗg0гЇO_О|yFF†ЋЋЋЗЗwtt4ŽуT*•Эf'''чффЬœ9глл›С`Ь™3gј­тˆЂP(Ž= ”вЌYГt:Žуёёёййй™™™жDLPPA†Ož<йЫЫ‹Хb…„„X,Чљ|ўВeЫжЏ_o6›‚‚‚ЂЃЃ!+!!!!!!‰‰‰А3ЛЛЛэээccc###!ьёєщ㘘˜   ШШH*•j6›E"QTTдќљѓ—.]J„^Џ \ДhбŽ;Ќ)˜ЮЮN6›“””іхrЙ‹‹Ы”)SЂЂЂШВНЃЃƒЫхFFF&&&BєѕїїчrЙQQQ“'OŽˆˆРqМООўњѕыНННаЇRЉ$ АБжЂT*%IWW}Є Т†NЇ“JЅp—<кЛ3™L&•Jс>ЧZ ƒL&“H$§§§/уЩ›бhћУпЛ8ьўўўбfa#bA№PЋе‰ИщсЂбh$Щ7ЎbБИЇЇчЅОћ3 OŸ>•ЫхЯ>5лoSЛКК …ЕЫЬfГT*]Кtщџy63тЭ?мВй~з@В#ЖыGяШpл'fУЉбь8lx"‘шьйГУ‹RчЭ›7Є‘NЇл(‡†“jNNN'^Њр8GџX=Œyџ§ї%IFFЦš5k`• Ѕ!Їџвпc§Ce```лЖm6Жoп>Xџ!‚уxBBТж­[їяп/—Ыљ|ОНННZ­nhh€Œ-++ы…€ѕoL2™Ьттb„Gdбї, У233ЅRщ™3g>ћь3’gС0Ьггѓу?^Вd хљ8nЃбxсТx9Vдт?NФbёН{їœœœ‚ƒƒ‡\O§л‹С`hmm•H$РPR(‡рр`‹eggї?ђЯNvОђ6IENDЎB`‚leptonica-plumbing-1.4.0/multipage.tiff000066400000000000000000001456351460632402400201650ustar00rootroot00000000000000II*ўЅCр€^V.6 >()1 J2XRSМ^ li‡ъs‡ ЪќсzсzBackgroundGIMP 2.10.302022:05:16 22:26:54  lcms0mntrGRAYXYZ цacspAPPLіжг-lcmsdescЬncprt<6wtpttkTRCˆ dmndЈ$dmddЬRmluc enUSRGIMP built-in D65 Grayscale with sRGB TRCmluc enUSPublic DomainXYZ ѓQЬparaffђЇ Yа [mluc enUSGIMPmluc enUS6D65 Grayscale with sRGB TRC  ўgntk œЪџиџрJFIFџлC    $.' ",#(7),01444'9=82<.342џлC  2!!22222222222222222222222222222222222222222222222222џРg"џФ џФЕ}!1AQa"q2‘Ё#BБСRб№$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™šЂЃЄЅІЇЈЉЊВГДЕЖЗИЙКТУФХЦЧШЩЪвгдежзийкстуфхцчшщъёђѓєѕіїјљњџФ џФЕw!1AQaq"2B‘ЁБС #3R№brб $4с%ё&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™šЂЃЄЅІЇЈЉЊВГДЕЖЗИЙКТУФХЦЧШЩЪвгдежзийктуфхцчшщъђѓєѕіїјљњџк ?їњ(Ђ€ (Ђ€ (Ђ€ (Ђ€ (Ђ€ (Ђ€ (Ђ€ (Ђ€ (Ђ€ (Ђ€ (Ђ€ (Ђ€ (Ђ€ (Ђ€ (Ђ€ (Ђ€ (Ђ€ Bp3KErїП4-41НkЛuS‚вл:ЏцEP_‹^q•дїd&Њќb†!№яP)7mnvŒ§жЎGіuДЖИ№–Ђг[Х+ чКеЧы@ƒiё7Т7ВlXNqћж ќЭu6зVїЌжгЧ4L27 т+ŸёД/i“ZнXD /ЪЩ” ѕwРЏјsтНCСџЎ<)Ј]K-‹н›HDЏœ&Х#>Йэ@IбGZ(ЂŠ(ЂŠ(ЂŠ† Л{–u‚xф1ЎГДњЮ€&ЂŠ(ЂŠ(ІK*A Ы#DRЬO`:гъ–ЏЯЃ_E–‘эфUQд’Ї€9{Šž†c 7s]Ы§ЫHcџŽMOŠО,wM{f[Ѓ]йЫ ŸХд Ÿсџ„эМ=с;;YЌЃ[ H]2й$žџZоеt7XА–Ююв&ŽU*~\F:ŽhЭŽЁgЉл-Х•ЬW†ЅYЏœ>ы—žјЁ?…$žI,ц‘•˜Ÿ&ў3ьЏЃшЂŠ(ЂŠ(ЂŠ(ЂŠ(ЂŠ(јЧџ$уPџqПєЎSіpџ‘CRџЏїџбqзWёўIЦЁўуш ^]№SХ7К‡/`Жаou{Жs%ЙŒ;`юuчж€>ŽbK€dзЪЕяБ§‰ k*\ž8KŽMzЮЗтЏыЖЦЧC№ДЖЂo‘цЙ’ QOR1/ІjзУO…‰сЅеЕ)ўгЋ\ Г`™$1јwэ@‹rэoc#ЏоDШќyо‹mуoкџhIт/ьћIМЈэуŒЖ#ёŸC^”сY|m#œж\Кц‹ЅЈютˆ/DPN?!@]тпјЛсехцЌu}*тU‰–T]IмO*‹иWЋшzД:ц‰gЉл‚"К…%Pz€Р~Еф_ќCЄъ~ Š KЁ,ЂpqБ‡oq]чТпљ'/§zХџ -Qј“ё< НЅ­ЙЙдя2АG?(ф“ўаьiš‡|cЊZ%цЃтЛ‹Ye„6БBUш>h‰щŽѕц?XО6h3OХБ–лi=8n§ЏЂэˆ6А‘аЂуђ ŸО#ъў9№ЅЭІ›{Џ<њ}д€ „Š јўщТs‘щ^зс]&УIа OfxЄЬЎХšC€7ј ђЏк9•Д=*%цSvЄјл%z_УшgЗјЁХrЅfK8УƒдЃ4“ётxB;k;H ЮЉxт8"Ш@ѓѕЊ–>ёОЉdЗЗО+–вyWzAP”LђнёЊјOХD\!НPЃvpУ ŒщкНlŒŠљЃуŽЅoЎыZMо„вн’O1у…ўSђcЈі5єn›#MЇA#u)ЭZЂŠ(ЄfЅ˜рIЅЏ>ј•т™эtіа4D7:еъВ$h>рлї‰$‚WЉя@Qр;&ё/Ч+V,љ6’ћіcўuєХqПќƒ4S1–ісŒ—œrЧЦ;p=kВ Š( Š( Š( Š( Š( уќ“C§ЦџаЙOйУўE KўПпџEЧZ<@5_ ^шЖNБqtрЈ)ЇЬWю‘УСъ;з3№gVŸСкнŽБЁыqI5лJЅtйи`ЊЩъІ€=ђŠ­a}ЃhЗ1$ШбeŒЃ~ ђ*ЭyЏЦЏ^јwСЌtљLWИO0g!NAЧП5'УшіоГд.ь-ЎЕ”/5ФБ+19Ч\gЕIё‡Т—~)№l‘X!{˜HЈ’Рdрмё\Ї~%j6ЌјoU ЦЌЖвБuЮqдаЯ:u•ЏЃx-!‰МёЪ Ѕv ?фœhПѕыў€ЕТ|MxЫС/$:ХДИtˆЋДвtў €ŽО§+ЎјYЈ…№–›ЄЯemwŽЗ –= QјЩсэ#U№шККqЇadTežCЊ1Я,~5>‚~!иi№Mmcy„d-Б€ъ3—9ЎOуv‹т$еДпiђ™­,œH-ЮцEe эrGЗJЫЗјЙё Eo]Ољ–в@ў9@Єп5_ј†WХзМVџъЌр ЇъYГљWЇЄib4PЊЃ‚ОoŒо<ЖS-ЯƒЎж%х‹@штRН/спФk/iђ:D-я!Ч›™ИŒЮp=ћv ЛЖƒN§Ёцћz#EwrYD‹w>бќЋш‘Ёщ$diжИџЎK^eёkсЭюЕ{mтMэ;M­А–кл†1п$ž”žјБЈкиЅЇˆМ3Њ[мТ~`Ж•ЗуŒрGє OўУвПшkџ~–Џ*Њ(UTtИН7ЧѓkI ‡‡u2YgЗ–ъЩŠэGAš(ЂЙЯоъVПИв"’[аЁcXГчЁ4KФо+š;ьM?Дъг)]СIH3€ˆРъsŒƒСЉ|+рЫ}Iu+ТЗzЭЮLїnЃw^HЯj№ЯјУЧо‚Aƒѕ ю%rђмЫe!‘Щ$ђJgП­nТйј—џBmяўIџФPаTW…шпО!пjіжз~ЛЗ‚FУЪжrЃЅkн(ЂŠ(ЂŠ(ЂŠ(ЂŠ(ЂŠ(žTм_Ъ*?љцП•>Š@ŒіЅЂŠ*/Г[юнфEŸ]‚ЅЂ€Њ‘‚ LRбNB(>ТExќКЬў&јзƒtЬК}„-:ХЛфYqдqач­zрЗ„1рВ+‰ёGӘѕ}nJО“NесІ6П €РЉШШ§MIПрA]is‘Ч˜KŒўhЌКŠЭ-dkˆсѓQŠ№пжk7‹ѕэFС щ‡bFsHS‘џЮЛ›пјЃФƒЩзuё ‘ћаX€7}K&#]އЁiўг’ЧNa…{чA@U[@ч- l}JRб@ Hв1„EQь1NЂŠ) 0@#о–Šg•ќѓ_Ъ*?љцП•>Šg•їђЇбEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEџйџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџэџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№џ[џ[џ[џ[џ[џ[џ[џ[џ[џ[џ[џ_џ|џžџХџюџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџзџjџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџиџТџЈџ_џџџџ&џ1џ/џ%џџџџџџ”џэџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџчџ‰џџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџ§џ№џжџ—џџџџAџпџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџђџЄџџџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџеџџџџFџђџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњџЛџ;џџ`џsџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџАџџџџЉџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџ\џLџЉџрџўџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџьџџџџGџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§џйџќџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџўџKџџџџьџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџеџuџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџiџџџџоџџџџџџџџџџџџџџџћџёџчџфџыџјџџџџџџџџџџџџџџџџџџџџџџџџџџџўџяџрџоџрџюџћџўџеџtџџYџэџџџџџџџџџџџџџџџџџћџшџпџпџчџњџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџkџџџџмџџџџџџџџџтџ—џdџ)џџџџџ#џ‚џкџџџџџџџџџџџџџџџџџџџђџЎџSџџџџџџ.џ\џџџTџыџџџџџџџџџџџџџџџэџЁџ:џџџџџ2џœџьџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџ]џџџџчџџџџџџџџџУџџџnџВџЪџЪџžџџџџЦџџџџџџџџџџџџџџџмџDџџ џ•џЭџмџбџ џџџџ3џщџџџџџџџџџџџџџџџвџ5џџџœџЩџЩџ–џ џџ7џкџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџїџџџџ#џљџџџџџџџџџУџџПџўџџџџџџџџџЖџџџ2џєџџџџџџџџџџџэџ:џџџХџџџџџџџџџџџбџџџџдџџџџџџџџџџџџџпџ!џџ&џлџџџџџџџџџУџџџ;џяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџбџџџџˆџџџџџџџџџџџУџџёџџџџџџџџџџџѓџџџџЯџџџџџџџџџџџЂџџџhџўџџџџџџџџџџџџџ{џџџ}џџџџџџџџџџџ§џjџџџДџџџџџџџџџџџўџnџџџЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџњџoџџџџиџџџџџџџџџџџиџЈџџџџџџџџџџџџџўџGџџџИџџџџџџџџџ§џEџџџЉџџџџџџџџџџџџџџџГџџџ#џјџџџџџџџџџиџџџџяџџџџџџџџџџџџџЗџџџ?џћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџєџŒџџџџžџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџZџџџЕџџџџџџџџџєџџџџНџџџџџџџџџџџџџџџУџџџџьџџџџџџџџџЂџџџ`џџџџџџџџџџџџџџџдџџџџцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџЙџсџсџпџЭџЂџ<џџџџ џќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџZџџџЕџџџџџџџџџёџџџџОџџџџџџџџџџџџџџџЦџџџџщџџџџџџџџџlџџџ‹џџџџџџџџџџџџџџџпџџџџеџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџџџџџџџџ џzџжџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџZџџџЕџџџџџџџџџіџџџџЗџџџџџџџџџџџџџџџНџџџџѓџџџџџџџќџ5џџџ—џўџўџўџўџўџўџўџчџџџџЪџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџƒџЁџЁџЁџЈџДџЯџэџџџџџџџџџџџџџџџџџџџџџџџіџаџЎџ–џ‡џzџqџkџ џџџЕџџџџџџџџџџџaџџџ•џџџџџџџџџџџџџџџžџџџZџўџџџџџџџњџџџџџ;џ;џ;џ;џ;џ;џ;џ5џџџџЩџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§џЕџ1џџџSџˆџ™џ›џЁџ7џџџЕџџџџџџџџџџџЖџџџ5џєџџџџџџџџџџџїџDџџџЗџџџџџџџџџіџџџџ[џ“џ“џ“џ“џ“џ“џ“џ“џ“џ“џ“џкџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЄџџџbџпџўџџџџџџџўџZџџџЕџџџџџџџџџџџіџ^џџџ‡џєџџџџџџџїџ“џџџnџјџџџџџџџџџљџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџчџџџџсџџџџџџџџџџџўџZџџџЕџџџџџџџџџџџџџэџsџџџ2џ…џ˜џˆџ:џџџŒџѓџџџџџџџџџџџњџџџџ˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџМџџџMџўџџџџџџџџџџџўџZџџџЕџџџџџџџџџџџџџџџмџџџzџQџBџTџџЎџрџџџџџџџџџџџџџџџўџVџџџƒџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЃџџџzџџџџџџџџџџџџџўџZџџџЕџџџџџџџџџџџџџщџCџHџјџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‰џџџDџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЂџџџrџџџџџџџџџџџџџўџZџџџЕџџџџџџџџџџџ№џYџџКџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНџџџџлџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџ5џњџџџџџџџџџџџўџZџџџЕџџџџџџџџџњџpџџџЧџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџюџџџџxџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжџџџџИџџџџџџџџџљџЪџ6џџџЕџџџџџџџџџљџ.џџџџDџpџuџuџuџuџuџvџ„џЄџгџќџџџџџџџџџџџЇџџџџŽџѓџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљџцџ‰џџџџЎџхџѕџ§џџџџџџџџџџџџџџџџџџџџџџџџџћџ]џџџџ‚џЎџЈџџ6џLџfџџџ­џ§џџџџџџџџџДџџџџџџџџџџџџџџџsџёџџџџџџџџџљџ}џџџџ7џ—џЙџРџМџВџ›џwџЄџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§џјџыџпџ•џџџџгџцџђџњџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŠџџџџџџџџџџBџЂџџџџџџџџџџџџџџџџџџџџџџџџџтџHџџџџџџџ’џ№џЏџџџџIџ˜џџџџџџџўџЖџ.џџџџџџџџџџџџџџyџ§џџџџџџџџџњџЎџ0џџџџџџџџџџфџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѓџ_џ@џџџџџџџџџџџ џRџГџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџнџжџжџжџжџжџжџжџжџжџжџтџџџџџџџџџџџџџџџџџџџџџџџџџџџєџПџžџ“џЂџРџъџџџџџяџжџжџжџжџкџџџџџџџџџэџrџlџФџХџХџХџХџХџХџУџВџPџџџџнџџџџџџџџџџџџџѕџЮџЏџџ’џžџАџЯџѓџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњџжџжџжџжџжџжџжџжџжџжџжџжџжџжџцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџфџJџ;џюџџџџџџџџџџџџџџџџџџџ№џ:џџџПџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёџHџџГџџџџџџџџџџџџџџџџџџџџџџџŽџџџЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЋџџџфџџџџџџџџџџџџџџџџџџџџџџџ‰џџџЫџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџzџџџѓџџџџџџџџџџџџџџџџџџџџџјџ=џџџяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘џџџйџџџџџџџџџџџџџџџџџџџўџЅџџџЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџгџџџlџяџџџџџџџџџџџџџџџэџ•џџџ~џљџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЗџџџ(џ“џЙџХџШџРџЏџ}џџџ!џ­џњџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцџЃџXџџџџџџџ,џyџКџяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџѕџшџсџпџхџэџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџ№џчџчџщџіџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№џ[џ[џ[џ[џ[џ[џ[џ[џ[џ[џ[џ_џ|џžџХџюџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџСџšџiџ'џџџџџџSџœџмџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџиџТџЈџ_џџџџ&џ1џ/џ%џџџџџџ”џэџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџ5џŒџ­џИџЅџmџџџџŽџѕџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџ§џ№џжџ—џџџџAџпџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџЫџњџџџџџџџџџџџжџ=џџџtџљџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџеџџџџFџђџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџaџўџџџџџџџџџџџџџџџЭџџџџДџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџАџџџџЉџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџ›џџџџџџџџџџџџџџџџџ§џRџџџHџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџьџџџџGџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџOџЧџџџџџџџџџџџџџџџџџџџ“џџџџшџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџўџKџџџџьџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџеџuџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџЇџџџџиџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџiџџџџоџџџџџџџџџџџџџџџћџёџчџфџыџјџџџџџџџџџџџџџџџџџџџџџџџџџџџўџяџрџоџрџюџћџўџеџtџџYџэџџџџџџџџџџџџџџџџџћџшџпџпџчџњџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџйџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџkџџџџмџџџџџџџџџтџ—џdџ)џџџџџ#џ‚џкџџџџџџџџџџџџџџџџџџџђџЎџSџџџџџџ.џ\џџџTџыџџџџџџџџџџџџџџџэџЁџ:џџџџџ2џœџьџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ˜џџџџщџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџ]џџџџчџџџџџџџџџУџџџnџВџЪџЪџžџџџџЦџџџџџџџџџџџџџџџмџDџџ џ•џЭџмџбџ џџџџ3џщџџџџџџџџџџџџџџџвџ5џџџœџЩџЩџ–џ џџ7џкџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ|џџџ9џќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџїџџџџ#џљџџџџџџџџџУџџПџўџџџџџџџџџЖџџџ2џєџџџџџџџџџџџэџ:џџџХџџџџџџџџџџџбџџџџдџџџџџџџџџџџџџпџ!џџ&џлџџџџџџџџџУџџџ;џяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџ5џџџ–џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџбџџџџˆџџџџџџџџџџџУџџёџџџџџџџџџџџѓџџџџЯџџџџџџџџџџџЂџџџhџўџџџџџџџџџџџџџ{џџџ}џџџџџџџџџџџ§џjџџџДџџџџџџџџџџџўџnџџџЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџкџџџџоџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџњџoџџџџиџџџџџџџџџџџиџЈџџџџџџџџџџџџџўџGџџџИџџџџџџџџџ§џEџџџЉџџџџџџџџџџџџџџџГџџџ#џјџџџџџџџџџиџџџџяџџџџџџџџџџџџџЗџџџ?џћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ˜џџџ‹џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџєџŒџџџџžџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџZџџџЕџџџџџџџџџєџџџџНџџџџџџџџџџџџџџџУџџџџьџџџџџџџџџЂџџџ`џџџџџџџџџџџџџџџдџџџџцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцџџџ?џюџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџЙџсџсџпџЭџЂџ<џџџџ џќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџZџџџЕџџџџџџџџџёџџџџОџџџџџџџџџџџџџџџЦџџџџщџџџџџџџџџlџџџ‹џџџџџџџџџџџџџџџпџџџџеџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџxџџџжџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџџџџџџџџ џzџжџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџZџџџЕџџџџџџџџџіџџџџЗџџџџџџџџџџџџџџџНџџџџѓџџџџџџџќџ5џџџ—џўџўџўџўџўџўџўџчџџџџЪџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЇџџ џЦџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџƒџЁџЁџЁџЈџДџЯџэџџџџџџџџџџџџџџџџџџџџџџџіџаџЎџ–џ‡џzџqџkџ џџџЕџџџџџџџџџџџaџџџ•џџџџџџџџџџџџџџџžџџџZџўџџџџџџџњџџџџџ;џ;џ;џ;џ;џ;џ;џ5џџџџЩџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџКџџџФџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§џЕџ1џџџSџˆџ™џ›џЁџ7џџџЕџџџџџџџџџџџЖџџџ5џєџџџџџџџџџџџїџDџџџЗџџџџџџџџџіџџџџ[џ“џ“џ“џ“џ“џ“џ“џ“џ“џ“џ“џкџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНџџџЭџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЄџџџbџпџўџџџџџџџўџZџџџЕџџџџџџџџџџџіџ^џџџ‡џєџџџџџџџїџ“џџџnџјџџџџџџџџџљџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџЗџџ7џиџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџчџџџџсџџџџџџџџџџџўџZџџџЕџџџџџџџџџџџџџэџsџџџ2џ…џ˜џˆџ:џџџŒџѓџџџџџџџџџџџњџџџџ˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§џЉџџSџфџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџМџџџMџўџџџџџџџџџџџўџZџџџЕџџџџџџџџџџџџџџџмџџџzџQџBџTџџЎџрџџџџџџџџџџџџџџџўџVџџџƒџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњџ•џџpџяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЃџџџzџџџџџџџџџџџџџўџZџџџЕџџџџџџџџџџџџџщџCџHџјџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‰џџџDџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџіџџџŒџјџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЂџџџrџџџџџџџџџџџџџўџZџџџЕџџџџџџџџџџџ№џYџџКџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНџџџџлџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№џnџџЃџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕџџџ5џњџџџџџџџџџџџўџZџџџЕџџџџџџџџџњџpџџџЧџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџюџџџџxџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџщџ[џ џИџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжџџџџИџџџџџџџџџљџЪџ6џџџЕџџџџџџџџџљџ.џџџџDџpџuџuџuџuџuџvџ„џЄџгџќџџџџџџџџџџџЇџџџџŽџѓџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџZџџџ^џ_џ_џ_џ_џ_џ_џ_џ_џ_џ_џ_џ_џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљџцџ‰џџџџЎџхџѕџ§џџџџџџџџџџџџџџџџџџџџџџџџџћџ]џџџџ‚џЎџЈџџ6џLџfџџџ­џ§џџџџџџџџџДџџџџџџџџџџџџџџџsџёџџџџџџџџџљџ}џџџџ7џ—џЙџРџМџВџ›џwџЄџџџџџџџџџџџџџџџџџџџџџџџџџџџџџFџџџџџџџџџџџџџџџџvџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŠџџџџџџџџџџBџЂџџџџџџџџџџџџџџџџџџџџџџџџџтџHџџџџџџџ’џ№џЏџџџџIџ˜џџџџџџџўџЖџ.џџџџџџџџџџџџџџyџ§џџџџџџџџџњџЎџ0џџџџџџџџџџфџџџџџџџџџџџџџџџџџџџџџџџџџџџџџFџџџџџџџџџџџџџџџџvџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџнџжџжџжџжџжџжџжџжџжџжџтџџџџџџџџџџџџџџџџџџџџџџџџџџџєџПџžџ“џЂџРџъџџџџџяџжџжџжџжџкџџџџџџџџџэџrџlџФџХџХџХџХџХџХџУџВџPџџџџнџџџџџџџџџџџџџѕџЮџЏџџ’џžџАџЯџѓџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџйџжџжџжџжџжџжџжџжџжџжџжџжџжџжџжџоџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџфџJџ;џюџџџџџџџџџџџџџџџџџџџ№џ:џџџПџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёџHџџГџџџџџџџџџџџџџџџџџџџџџџџŽџџџЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЋџџџфџџџџџџџџџџџџџџџџџџџџџџџ‰џџџЫџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџzџџџѓџџџџџџџџџџџџџџџџџџџџџјџ=џџџяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘џџџйџџџџџџџџџџџџџџџџџџџўџЅџџџЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџгџџџlџяџџџџџџџџџџџџџџџэџ•џџџ~џљџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЗџџџ(џ“џЙџХџШџРџЏџ}џџџ!џ­џњџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџцџЃџXџџџџџџџ,џyџКџяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџѕџшџсџпџхџэџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўЅC>t€^V†ЫŽЫ–Ы()RSсzсzPage 1leptonica-plumbing-1.4.0/src/000077500000000000000000000000001460632402400160755ustar00rootroot00000000000000leptonica-plumbing-1.4.0/src/box.rs000066400000000000000000000057741460632402400172500ustar00rootroot00000000000000use crate::memory::{LeptonicaDestroy, RefCountedExclusive}; use leptonica_sys::{boxCreateValid, boxDestroy, boxGetGeometry, l_int32, l_ok}; use thiserror::Error; /// Wrapper around Leptonica's [`Box`](https://tpgit.github.io/Leptonica/struct_box.html) structure #[derive(Debug, PartialEq)] pub struct Box(*mut leptonica_sys::Box); /// Error returned by Box::create_valid #[derive(Debug, Error)] #[error("Box::create_valid returned null")] pub struct BoxCreateValidError(); impl AsRef for Box { fn as_ref(&self) -> &leptonica_sys::Box { unsafe { &*self.0 } } } impl AsMut for Box { fn as_mut(&mut self) -> &mut leptonica_sys::Box { unsafe { &mut *self.0 } } } impl Box { /// Create an owned Box from a box pointer /// /// # Safety /// /// The pointer must be to a valid Box struct. /// The data pointed at may not be mutated while held by /// this struct except by this struct. /// On drop, the destroy method will be called (decrements /// the ref counter). pub unsafe fn new_from_pointer(b: *mut leptonica_sys::Box) -> Self { Self(b) } /// Wrapper for [`boxCreateValid`](https://tpgit.github.io/Leptonica/boxbasic_8c.html#a435610d86a8562dc60bfd75fe0a15420) /// /// Input: x, y, w, h Return: box pub fn create_valid( x: l_int32, y: l_int32, w: l_int32, h: l_int32, ) -> Result, BoxCreateValidError> { let ptr = unsafe { boxCreateValid(x, y, w, h) }; if ptr.is_null() { Err(BoxCreateValidError()) } else { Ok(unsafe { RefCountedExclusive::new(Self(ptr)) }) } } /// Wrapper for [`boxGetGeometry`](https://tpgit.github.io/Leptonica/boxbasic_8c.html#aaf754e00c062c3f0f726bea73a17e646) pub fn get_geometry( &self, px: Option<&mut l_int32>, py: Option<&mut l_int32>, pw: Option<&mut l_int32>, ph: Option<&mut l_int32>, ) -> l_ok { unsafe { boxGetGeometry( self.0, match px { None => std::ptr::null_mut(), Some(px) => px, }, match py { None => std::ptr::null_mut(), Some(py) => py, }, match pw { None => std::ptr::null_mut(), Some(pw) => pw, }, match ph { None => std::ptr::null_mut(), Some(ph) => ph, }, ) } } } impl LeptonicaDestroy for Box { unsafe fn destroy(&mut self) { boxDestroy(&mut self.0); } } #[test] fn create_valid_test() { let r#box = Box::create_valid(1, 2, 3, 4).unwrap(); let mut pw = 0; r#box.get_geometry(None, None, Some(&mut pw), None); assert_eq!(pw, 3); } #[test] fn create_invalid_test() { assert!(Box::create_valid(1, 2, 3, -4).is_err()) } leptonica-plumbing-1.4.0/src/boxa.rs000066400000000000000000000075551460632402400174100ustar00rootroot00000000000000use std::convert::TryInto; use leptonica_sys::{boxaCreate, boxaDestroy, boxaGetBox, boxaGetCount, l_int32, L_CLONE, L_COPY}; use crate::{ memory::{LeptonicaDestroy, RefCounted, RefCountedExclusive}, Box, }; /// Wrapper around Leptonica's [`Boxa`](https://tpgit.github.io/Leptonica/struct_boxa.html) structure #[derive(Debug, PartialEq)] pub struct Boxa(*mut leptonica_sys::Boxa); impl AsRef for Boxa { fn as_ref(&self) -> &leptonica_sys::Boxa { unsafe { &*self.0 } } } impl AsMut for Boxa { fn as_mut(&mut self) -> &mut leptonica_sys::Boxa { unsafe { &mut *self.0 } } } impl Boxa { /// Create a new Boxa from a pointer /// /// # Safety /// /// The pointer must be to a valid Boxa struct. /// The Boxa struct must not be mutated whilst the wrapper exists. pub unsafe fn new_from_pointer(p: *mut leptonica_sys::Boxa) -> Self { Self(p) } /// Wrapper for [`boxaCreate`](https://tpgit.github.io/Leptonica/boxbasic_8c.html#ae59916b7506831be9bf2119dea063253) /// /// Input: n (initial number of ptrs) Return: boxa, or null on error pub fn create(n: l_int32) -> Option> { let ptr = unsafe { boxaCreate(n) }; if ptr.is_null() { None } else { Some(unsafe { RefCountedExclusive::new(Self(ptr)) }) } } /// Wrapper for [`boxaGetCount`](https://tpgit.github.io/Leptonica/boxbasic_8c.html#a82555cab9ef5578c4728ef5109264723) pub fn get_count(&self) -> l_int32 { unsafe { boxaGetCount(self.0) } } /// Wrapper for [`boxaGetBox`](https://tpgit.github.io/Leptonica/boxbasic_8c.html#ac7c6fcfadf130bfa738ce6aab51318e5) with copied `accessflag`: `L_COPY` pub fn get_box_copied(&self, index: l_int32) -> Option> { unsafe { boxaGetBox(self.0, index, L_COPY.try_into().unwrap()) .as_mut() .map(|raw| RefCountedExclusive::new(Box::new_from_pointer(raw))) } } /// Wrapper for [`boxaGetBox`](https://tpgit.github.io/Leptonica/boxbasic_8c.html#ac7c6fcfadf130bfa738ce6aab51318e5) with copied `accessflag`: `L_CLONE` pub fn get_box_cloned(&self, index: l_int32) -> Option> { unsafe { boxaGetBox(self.0, index, L_CLONE.try_into().unwrap()) .as_mut() .map(|raw| RefCounted::new(Box::new_from_pointer(raw))) } } } impl LeptonicaDestroy for Boxa { unsafe fn destroy(&mut self) { boxaDestroy(&mut self.0); } } #[test] fn get_test() { use leptonica_sys::boxaAddBox; let mut boxa = Boxa::create(4).unwrap(); assert_eq!(boxa.get_count(), 0); let mut box_1 = Box::create_valid(1, 2, 3, 4).unwrap(); let mut box_2 = Box::create_valid(5, 6, 7, 8).unwrap(); unsafe { boxaAddBox(boxa.as_mut(), box_1.as_mut(), L_CLONE.try_into().unwrap()); boxaAddBox(boxa.as_mut(), box_2.as_mut(), L_CLONE.try_into().unwrap()); } assert_eq!(boxa.get_count(), 2); let box_1_cloned = boxa.get_box_cloned(0).unwrap(); let box_2_copied = boxa.get_box_copied(1).unwrap(); let (mut px, mut py, mut pw, mut ph) = (-1, -1, -1, -1); box_1_cloned.get_geometry(Some(&mut px), Some(&mut py), Some(&mut pw), Some(&mut ph)); assert_eq!((px, py, pw, ph), (1, 2, 3, 4)); // Because Cloned reuses and reference counts the same pointer assert_eq!( box_1.as_ref() as *const leptonica_sys::Box, box_1_cloned.as_ref() as *const leptonica_sys::Box ); box_2_copied.get_geometry(Some(&mut px), Some(&mut py), Some(&mut pw), Some(&mut ph)); assert_eq!((px, py, pw, ph), (5, 6, 7, 8)); // Because Copied creates a new instance assert!( box_2.as_ref() as *const leptonica_sys::Box != box_2_copied.as_ref() as *const leptonica_sys::Box ); } leptonica-plumbing-1.4.0/src/lib.rs000066400000000000000000000026541460632402400172200ustar00rootroot00000000000000mod r#box; mod boxa; pub mod memory; mod pix; mod pixa; mod str; use self::leptonica_sys::{getImagelibVersions, getLeptonicaVersion}; pub use leptonica_sys; pub use crate::str::Str; pub use boxa::Boxa; pub use pix::{Pix, PixReadError, PixReadMemError}; pub use pixa::Pixa; pub use r#box::{Box, BoxCreateValidError}; /// Wrapper for [`getLeptonicaVersion`](https://github.com/DanBloomberg/leptonica/blob/1.82.0/src/utils1.c#L970-L982) /// /// Returns the version identifier as a LeptonicaString. pub fn get_version() -> Str { unsafe { Str::new_from_pointer(getLeptonicaVersion()) } } /// Wrapper for [`getImagelibVersions`](https://github.com/DanBloomberg/leptonica/blob/1.82.0/src/libversions.c#L82-L102) /// /// Returns the image lib version identifiers as a LeptonicaString. pub fn get_imagelib_versions() -> Option { unsafe { let pointer = getImagelibVersions(); if pointer.is_null() { None } else { Some(Str::new_from_pointer(pointer)) } } } #[cfg(test)] mod tests { use super::*; #[test] fn test_get_version() { assert_eq!(&get_version().to_str().unwrap()[0..10], "leptonica-"); } #[test] fn test_get_imagelib_versions() { // No assertions as there's not much we can guarantee given different compile time options. // Instead used when testing with valgrind to check for leaks. get_imagelib_versions(); } } leptonica-plumbing-1.4.0/src/memory/000077500000000000000000000000001460632402400174055ustar00rootroot00000000000000leptonica-plumbing-1.4.0/src/memory/borrowed_from.rs000066400000000000000000000012241460632402400226200ustar00rootroot00000000000000use std::{marker::PhantomData, ops::Deref}; /// A non-ref counted wrapper that's valid for the lifetime of a parent struct pub struct BorrowedFrom<'a, T: 'a> { inner: T, phantom: PhantomData<&'a T>, } impl<'a, T: 'a> BorrowedFrom<'a, T> { /// Creates a new borrowed-from wrapper /// /// # Safety /// /// The pointer must not be mutated whilst this wrapper exists. pub unsafe fn new(inner: T) -> Self { Self { inner, phantom: PhantomData, } } } impl<'a, T: 'a> Deref for BorrowedFrom<'a, T> { type Target = T; fn deref(&self) -> &Self::Target { &self.inner } } leptonica-plumbing-1.4.0/src/memory/leptonica_clone.rs000066400000000000000000000007631460632402400231170ustar00rootroot00000000000000/// Trait to define how leptonica clones this memory. /// /// Usually this would be to call a `clone` method that increments a reference count. pub trait LeptonicaClone { /// Call to leptonica's internal structure-clone method. /// /// # Safety /// /// This must eventually be accompanied by a destroy call to decrement the reference count and possibly free the memory. /// /// The memory will be shared, so must not be mutated. unsafe fn clone(&mut self) -> Self; } leptonica-plumbing-1.4.0/src/memory/leptonica_destroy.rs000066400000000000000000000007271460632402400235100ustar00rootroot00000000000000/// Trait to define how leptonica frees this memory. /// /// Usually this would be to call a `destroy` method that decrements a reference count. /// Sometimes a reference count isn't used, so this isn't called (eg `BorrowedFrom`). pub trait LeptonicaDestroy { /// Call to leptonica's internal structure-destroy method. /// /// # Safety /// /// The reference to the pointer must not be used after destroy is called. unsafe fn destroy(&mut self); } leptonica-plumbing-1.4.0/src/memory/mod.rs000066400000000000000000000005321460632402400205320ustar00rootroot00000000000000mod borrowed_from; mod leptonica_clone; mod leptonica_destroy; mod ref_counted; mod ref_counted_exclusive; pub use self::borrowed_from::BorrowedFrom; pub use self::leptonica_clone::LeptonicaClone; pub use self::leptonica_destroy::LeptonicaDestroy; pub use self::ref_counted::RefCounted; pub use self::ref_counted_exclusive::RefCountedExclusive; leptonica-plumbing-1.4.0/src/memory/ref_counted.rs000066400000000000000000000015511460632402400222520ustar00rootroot00000000000000use super::leptonica_destroy::LeptonicaDestroy; use std::ops::Deref; /// A wrapper for ref counted leptonica pointers. pub struct RefCounted { inner: T, } impl RefCounted { /// Creates a new ref counted wrapper /// /// # Safety /// /// It must be safe for this wrapper to destroy (decrement the ref count). /// The ref count must have already been incremented before being passed to `new`. /// The pointer must not be mutated whilst this wrapper exists. pub unsafe fn new(inner: T) -> Self { Self { inner } } } impl Drop for RefCounted { fn drop(&mut self) { unsafe { self.inner.destroy() } } } impl Deref for RefCounted { type Target = T; fn deref(&self) -> &Self::Target { &self.inner } } leptonica-plumbing-1.4.0/src/memory/ref_counted_exclusive.rs000066400000000000000000000026201460632402400243370ustar00rootroot00000000000000use super::{leptonica_destroy::LeptonicaDestroy, LeptonicaClone, RefCounted}; use std::ops::{Deref, DerefMut}; /// A wrapper for ref counted leptonica pointers that can be safely mutated. /// /// For example if it is the only reference. pub struct RefCountedExclusive { inner: T, } impl RefCountedExclusive { /// Creates a new ref counted exclusive wrapper /// # Safety /// It must be safe for this wrapper to destroy (decrement the ref count). /// The ref count must have already been incremented before being passed to `new`. /// The pointer must not be mutated whilst this wrapper exists, except via this wrapper. pub unsafe fn new(inner: T) -> Self { Self { inner } } } impl RefCountedExclusive { /// Convert to a ref counted wrapper pub fn to_ref_counted(mut self) -> RefCounted { unsafe { RefCounted::new(self.inner.clone()) } } } impl Drop for RefCountedExclusive { fn drop(&mut self) { unsafe { self.inner.destroy() } } } impl Deref for RefCountedExclusive { type Target = T; fn deref(&self) -> &Self::Target { &self.inner } } impl DerefMut for RefCountedExclusive { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner } } leptonica-plumbing-1.4.0/src/pix.rs000066400000000000000000000156071460632402400172540ustar00rootroot00000000000000use leptonica_sys::{ l_float32, l_int32, l_uint32, pixClone, pixDestroy, pixGetData, pixGetDepth, pixGetHeight, pixGetWidth, pixRead, pixReadMem, pixReadWithHint, pixScaleGeneral, pixTransferAllData, }; use crate::memory::{LeptonicaClone, LeptonicaDestroy, RefCountedExclusive}; use std::convert::{AsRef, Infallible, TryInto}; use std::{ffi::CStr, num::TryFromIntError}; use thiserror::Error; /// Wrapper around Leptonica's [`Pix`](https://tpgit.github.io/Leptonica/struct_pix.html) structure #[derive(Debug)] pub struct Pix(*mut leptonica_sys::Pix); /// Error returned by Pix::read_mem #[derive(Debug, Error, PartialEq)] pub enum PixReadMemError { #[error("Pix::read_mem returned null")] NullPtr, #[error("Failed to convert image size")] ImageSizeConversion(#[from] TryFromIntError), } impl From for PixReadMemError { fn from(_: Infallible) -> Self { unreachable!() } } /// Error returned by Pix::read #[derive(Debug, Error)] #[error("Pix::read returned null")] pub struct PixReadError(); #[derive(Debug, Error, PartialEq)] pub enum PixManipError { #[error("some internal data moving failed")] PixInternalError, #[error("Pix scaling returned null")] PixScaleError, } impl AsRef<*mut leptonica_sys::Pix> for Pix { fn as_ref(&self) -> &*mut leptonica_sys::Pix { &self.0 } } impl AsRef for Pix { fn as_ref(&self) -> &leptonica_sys::Pix { unsafe { &*self.0 } } } impl AsRef for Pix { fn as_ref(&self) -> &Pix { self } } impl AsMut for Pix { fn as_mut(&mut self) -> &mut leptonica_sys::Pix { unsafe { &mut *self.0 } } } impl Pix { /// Create a new instance from a pointer /// /// # Safety /// /// The pointer must be to a valid `Pix` struct. /// /// The structure must not be mutated or freed outside of the Rust code whilst this instance exists. pub unsafe fn new_from_pointer(ptr: *mut leptonica_sys::Pix) -> Self { Self(ptr) } /// Wrapper for [`pixRead`](https://tpgit.github.io/Leptonica/leptprotos_8h.html#a84634846cbb5e01df667d6e9241dfc53) /// /// Read an image from a filename pub fn read(filename: &CStr) -> Result, PixReadError> { let ptr = unsafe { pixRead(filename.as_ptr()) }; if ptr.is_null() { Err(PixReadError()) } else { Ok(unsafe { RefCountedExclusive::new(Self(ptr)) }) } } /// Wrapper for [`pixReadMem`](https://tpgit.github.io/Leptonica/leptprotos_8h.html#a027a927dc3438192e3bdae8c219d7f6a) /// /// Read an image from memory pub fn read_mem(img: &[u8]) -> Result, PixReadMemError> { let ptr = unsafe { pixReadMem(img.as_ptr(), img.len().try_into()?) }; if ptr.is_null() { Err(PixReadMemError::NullPtr) } else { Ok(unsafe { RefCountedExclusive::new(Self(ptr)) }) } } /// Wrapper for [`pixReadWithHint`](https://tpgit.github.io/Leptonica/leptprotos_8h.html#a3ce88fc6a624a5c5c2f698f49db1d8a5) /// /// Read an image from memory with hints for JPEG decoding /// The valid hints are: /// - [`leptonica_sys::L_JPEG_READ_LUMINANCE`] - only want luminance data; no chroma /// - [`leptonica_sys::L_JPEG_CONTINUE_WITH_BAD_DATA`] - return possibly damaged pix pub fn read_with_hint( filename: &CStr, hint: u32, ) -> Result, PixReadError> { let ptr = unsafe { pixReadWithHint(filename.as_ptr(), hint as i32) }; if ptr.is_null() { Err(PixReadError()) } else { Ok(unsafe { RefCountedExclusive::new(Self(ptr)) }) } } fn pix_transfer_data( &mut self, ptr: &mut *mut leptonica_sys::Pix, ) -> Result<(), PixManipError> { let result = unsafe { pixTransferAllData(self.0, ptr, 0, 0) }; if result != 0 { Err(PixManipError::PixInternalError) } else { Ok(()) } } /// Wrapper for [`pixScaleGeneral`](https://tpgit.github.io/Leptonica/leptprotos_8h.html#a2f8ea34f3d02024f5d42ca05d2961177) pub fn scale_general( &mut self, scalex: l_float32, scaley: l_float32, ) -> Result<(), PixManipError> { let sharpwidth = if scalex.max(scaley) < 0.7 { 1 } else { 2 }; let mut ptr = unsafe { pixScaleGeneral(self.0, scalex, scaley, 0.0, sharpwidth) }; if ptr.is_null() { Err(PixManipError::PixScaleError) } else { self.pix_transfer_data(&mut ptr)?; Ok(()) } } /// Wrapper for [`pixGetHeight`](https://tpgit.github.io/Leptonica/pix1_8c.html#ae40704b3acbd343639e9aed696da531f) pub fn get_height(&self) -> l_int32 { unsafe { pixGetHeight(self.0) } } /// Wrapper for [`pixGetWidth`](https://tpgit.github.io/Leptonica/leptprotos_8h.html#aa71e0b02548a56e723c76996ab145257) pub fn get_width(&self) -> l_int32 { unsafe { pixGetWidth(self.0) } } /// Wrapper for [`pixGetDepth`](https://tpgit.github.io/Leptonica/leptprotos_8h.html#aa71e0b02548a56e723c76996ab145257) pub fn get_depth(&self) -> l_int32 { unsafe { pixGetDepth(self.0) } } /// Wrapper for [`pixGetData`](https://tpgit.github.io/Leptonica/leptprotos_8h.html#a44546f758f2cf71bb109bfc114e3ca7f) pub fn get_data(&self) -> *mut l_uint32 { unsafe { pixGetData(self.0) } } } impl LeptonicaDestroy for Pix { unsafe fn destroy(&mut self) { pixDestroy(&mut self.0); } } impl LeptonicaClone for Pix { unsafe fn clone(&mut self) -> Self { Self::new_from_pointer(pixClone(self.0)) } } #[cfg(test)] mod tests { use super::*; #[test] fn read_error_test() { let path = std::ffi::CString::new("fail").unwrap(); assert!(Pix::read(&path).is_err()); } #[test] fn read_mem_error_test() { assert_eq!(Pix::read_mem(&[]).err(), Some(PixReadMemError::NullPtr)); } #[test] fn read_test() { let path = std::ffi::CString::new("image.png").unwrap(); let pix = Pix::read(&path).unwrap(); assert_eq!(pix.get_width(), 200); } #[test] fn read_hint_test() { let path = std::ffi::CString::new("image.png").unwrap(); let pix = Pix::read_with_hint(&path, 0).unwrap(); assert_eq!(pix.get_width(), 200); } #[test] fn read_memory_test() { let pix = Pix::read_mem(include_bytes!("../image.png")).unwrap(); assert_eq!(pix.get_height(), 23); } #[test] fn read_memory_test_02() { let pix = Pix::read_mem(include_bytes!("../image.png")).unwrap(); assert_eq!(pix.get_depth(), 32); } #[test] fn clone_test() { let pix = Pix::read_mem(include_bytes!("../image.png")).unwrap(); let pix = pix.to_ref_counted(); assert_eq!(pix.get_height(), 23); } } leptonica-plumbing-1.4.0/src/pixa.rs000066400000000000000000000062061460632402400174100ustar00rootroot00000000000000use crate::{ memory::{LeptonicaDestroy, RefCounted, RefCountedExclusive}, Pix, }; use leptonica_sys::{ pixaDestroy, pixaGetCount, pixaGetPix, pixaReadMultipageTiff, L_CLONE, L_COPY, }; use std::{convert::TryInto, ffi::CStr}; /// Wrapper around Leptonica's [`Pixa`](https://tpgit.github.io/Leptonica/struct_pixa.html) structure #[derive(Debug, PartialEq)] pub struct Pixa(*mut leptonica_sys::Pixa); impl AsRef for Pixa { fn as_ref(&self) -> &leptonica_sys::Pixa { unsafe { &*self.0 } } } impl AsMut for Pixa { fn as_mut(&mut self) -> &mut leptonica_sys::Pixa { unsafe { &mut *self.0 } } } impl Pixa { /// Create a new Pixa from a pointer /// /// # Safety /// /// The pointer must be to a valid Pixa struct. /// The Pixa struct must not be mutated whilst the wrapper exists. pub unsafe fn new_from_pointer(p: *mut leptonica_sys::Pixa) -> Self { Self(p) } /// Wrapper for [`pixaReadMultipageTiff`](https://tpgit.github.io/Leptonica/leptprotos_8h.html#a4a52e686cf67f0e5bfda661fc3a3fb7b) pub fn read_multipage_tiff(filename: &CStr) -> Option> { let ptr = unsafe { pixaReadMultipageTiff(filename.as_ptr()) }; if ptr.is_null() { None } else { Some(unsafe { RefCountedExclusive::new(Self(ptr)) }) } } /// Wrapper for [`pixaGetCount`](https://tpgit.github.io/Leptonica/leptprotos_8h.html#a098d32e94acc16c5d6e91a930a4b45ff) pub fn get_count(&self) -> leptonica_sys::l_int32 { unsafe { pixaGetCount(self.0) } } /// Wrapper for [`pixaGetPix`](https://tpgit.github.io/Leptonica/leptprotos_8h.html#a3f62a77cf11114981267a6cf9918fc45) with copied `accessflag`: `L_COPY` pub fn get_pix_copied( &self, index: leptonica_sys::l_int32, ) -> Option> { unsafe { pixaGetPix(self.0, index, L_COPY.try_into().unwrap()) .as_mut() .map(|raw| RefCountedExclusive::new(Pix::new_from_pointer(raw))) } } pub fn get_pix_cloned(&self, index: leptonica_sys::l_int32) -> Option> { unsafe { pixaGetPix(self.0, index, L_CLONE.try_into().unwrap()) .as_mut() .map(|raw| RefCounted::new(Pix::new_from_pointer(raw))) } } } impl LeptonicaDestroy for Pixa { unsafe fn destroy(&mut self) { pixaDestroy(&mut self.0); } } #[cfg(test)] mod tests { use super::*; #[test] fn read_multipage_tiff_test() { let pixa = Pixa::read_multipage_tiff(CStr::from_bytes_with_nul(b"multipage.tiff\0").unwrap()) .unwrap(); assert_eq!(pixa.get_count(), 2); assert_eq!(pixa.get_pix_copied(0).unwrap().get_width(), 165); assert_eq!(pixa.get_pix_cloned(0).unwrap().get_height(), 67); assert_eq!(pixa.get_pix_copied(1).unwrap().get_width(), 165); assert_eq!(pixa.get_pix_cloned(1).unwrap().get_height(), 67); assert!(pixa.get_pix_copied(2).is_none()); assert!(pixa.get_pix_cloned(2).is_none()); } } leptonica-plumbing-1.4.0/src/str.rs000066400000000000000000000017051460632402400172560ustar00rootroot00000000000000use self::leptonica_sys::free; pub use leptonica_sys; use libc::c_char; use std::{ffi::CStr, str::Utf8Error}; /// Wrapper for heap allocated leptonica strings #[derive(Debug)] pub struct Str { value: *mut c_char, } impl Str { /// Create a new Str from a heap allocated c-string pointer /// /// # Safety /// /// The pointer must be to a valid heap allocated c-string. /// The data pointed at may not be mutated while held by /// this struct except by this struct. /// On drop, the pointer will be freed. pub unsafe fn new_from_pointer(pointer: *mut c_char) -> Self { Self { value: pointer } } pub fn to_str(&self) -> Result<&str, Utf8Error> { AsRef::::as_ref(self).to_str() } } impl AsRef for Str { fn as_ref(&self) -> &CStr { unsafe { CStr::from_ptr(self.value) } } } impl Drop for Str { fn drop(&mut self) { unsafe { free(self.value.cast()) } } }