Byla vydána beta verze openSUSE Leap 16. Ve výchozím nastavení s novým instalátorem Agama.
Devadesátková hra Brány Skeldalu prošla portací a je dostupná na platformě Steam. Vyšel i parádní blog autora o portaci na moderní systémy a platformy včetně Linuxu.
Lidi dělají divné věci. Například spouští Linux v Excelu. Využít je emulátor RISC-V mini-rv32ima sestavený jako knihovna DLL, která je volaná z makra VBA (Visual Basic for Applications).
Revolut nabídne neomezený mobilní tarif za 12,50 eur (312 Kč). Aktuálně startuje ve Velké Británii a Německu.
Společnost Amazon miliardáře Jeffa Bezose vypustila na oběžnou dráhu první várku družic svého projektu Kuiper, který má z vesmíru poskytovat vysokorychlostní internetové připojení po celém světě a snažit se konkurovat nyní dominantnímu Starlinku nejbohatšího muže planety Elona Muska.
Poslední aktualizací začal model GPT-4o uživatelům příliš podlézat. OpenAI jej tak vrátila k předchozí verzi.
Google Chrome 136 byl prohlášen za stabilní. Nejnovější stabilní verze 136.0.7103.59 přináší řadu novinek z hlediska uživatelů i vývojářů. Podrobný přehled v poznámkách k vydání. Opraveno bylo 8 bezpečnostních chyb. Vylepšeny byly také nástroje pro vývojáře.
Homebrew (Wikipedie), správce balíčků pro macOS a od verze 2.0.0 také pro Linux, byl vydán ve verzi 4.5.0. Na stránce Homebrew Formulae lze procházet seznamem balíčků. K dispozici jsou také různé statistiky.
Byl vydán Mozilla Firefox 138.0. Přehled novinek v poznámkách k vydání a poznámkách k vydání pro vývojáře. Řešeny jsou rovněž bezpečnostní chyby. Nový Firefox 138 je již k dispozici také na Flathubu a Snapcraftu.
Šestnáctý ročník ne-konference jOpenSpace se koná 3. – 5. října 2025 v Hotelu Antoň v Telči. Pro účast je potřeba vyplnit registrační formulář. Ne-konference neznamená, že se organizátorům nechce připravovat program, ale naopak dává prostor všem pozvaným, aby si program sami složili z toho nejzajímavějšího, čím se v poslední době zabývají nebo co je oslovilo. Obsah, který vytvářejí všichni účastníci, se skládá z desetiminutových
… více »time -p perl6 -e ' join q{ },"AAAA" .. "DZZZ"' real 11.67 user 11.60 sys 0.06Pro srovnání Perl 5:
time -p perl -e ' join q{ },"AAAA" .. "DZZZ"' real 0.07 user 0.05 sys 0.01Další informace jako proč Perl 6 vznikl, jak se nainstaluje, jaký je maskot Perlu 6, tutoriál a dokumentaci atd. věřím, že případný zájemce dokáže najít sám, např. na oficiálních stránkách Perlu 6.
my @a = ( 1, 2, 3 ); my @b = 1, 2, 3; if ( True ) { say "A" }; if True { say "A" };Podprogramy nebo i metody lze volat bez závorek
join ';', ( 1, 2, 3 ); ( 1, 2, 3 ).join: ';';dokonce by jsme v první případě mohli vynechat závorky i kolem pole, ale nic se nemá přehánět. Už volání metody bez závorek může být pro někoho silné kafe, ale to teprve začínáme.
join
jednou použil jako podprogram a jednou jako metodu. V Perlu 6 je poměrně běžné, že k podprogramu existuje stejná nebo podobná metoda a obráceně. Ale co víc můžeme podprogram pomocí prefixu &
volat jako metodu ';'.&join: 1, 2, 3;
, srdce pythonisty muselo zaplesat. A také i metodu jako podprogram, i když tady mi to při přímém zadaní pole nefunguje, všimněte si dvojtečky my @a = 1,2,3; join @a : ';';
.
Celkově jsme dostali 4 možnosti jak zavolat join
:
my @a = 1..10; say join ';', @a; say @a.join: ';'; say ';'.&join: @a; say join @a : ';';
if, while, for, ⋯
umožňuje postfixový zápis.
Tedy můžeme použít obě následující možnosti.
my $a; for <a b c d> { if ++$a %% 2 { .say } } .say if ++$a %% 2 for <a b c d>;Některé podprogramy mají jako alternativu (hyper)operátor
say zip ^10, 'a' .. 'j'; say ^10 Z 'a' .. 'j'; say ^10 »,« 'a' .. 'j';
*
, proměnná $_
(malá skrytá ochutnávka je v posledním příkladu) atd. Abych udržel rozumnou délku, tak se k tomuto dostanu snad někdy příště.
Doufám, že jsem vám alespoň trochu ukázal možnosti syntaxe Perlu 6 a to proč ho někteří budou označovat jako write-only a jiní za to ctít. Jaké jsou vaše názory na variabilnost Perlu 6? Jak jsou na tom vaše oblíbené skriptovací/programovací jazyky s volností psaní kódu?
Tiskni
Sdílej:
Už dlouho tvrdím, že PHP sice vypadá, jako když pejsek s kočičkou vařili dort, ale že na perl těch zvířátek muselo být nejméně deset.
Když jsem poprvé viděl obrácený podmíněný příkaz (statement if condition), dlouze jsem přemýšlel, jaké trauma musí mít za sebou člověk, který je schopen tohle vymyslet. A to jsem ještě netušil, že to není zdaleka nejhorší konstrukce.
zmateného
kódu začali programátoři v C a ne v Perlu. V Perlu, jestli se nepletu, se jako v prvním jazyce začal hrát golf. :)
dlouze jsem přemýšlel, jaké trauma musí mít za sebou člověk, který je schopen tohle vymysleTak podobnou syntaxi má třeba VHDL:
statement1 "when" condition "else" statement2a VHDL vzniklo na objednávku americké armády
if
někdy může mít smysl:
for ( 1 .. 10 ) { next if $_ % 2; say $_; };tady hned vidím, že se na druhém řádku dějí nějaké nekalosti; zatímco při klasickém zápisu
for ( 1 .. 10 ) { if ( $_ % 2 ) { next ; }; say $_; };se ten
next
poněkud ztrácí v závorkách a předpokládal bych, že po if
se bude pokračovat vždy na dalé.
A samozřejmě one-liners snesou hodně, tak často používám něco jako
perl -ne 'print if /word/'
I'm a Perl 5 programmer. Where is a list of differences between Perl 5 and 6?
Prostě je to jiný jazyk. Já osobně považuji za důležité jinou syntaxi regularních výrazů a vestavěný metaobjektový systém.
Tá rýchosť nie je náhodou dôsledkom použitia grafémov? V jazykoch bez podpory grafémov sú operácie nad reťazcami pomerne jednoduché a dajú sa pekne optimalizovať na SIMD, ale mergovanie tabuliek grafémov, ktoré musí robiť perl nie je práve najjednoduchšia operácia.
Celkovo mám z unicode zmiešané pocity. Páčilo by sa mi kódovanie s pevnou šírkou (ani UTF32 nemá pevnú šírku) ...
ani UTF32 nemá pevnú šírkuHuh?
Mysleli javisti, mysleli a nedomysleli.
import unicodedata len(unicodedata.normalize('NFKD', 'č')) > 2
Ukážka jedného znaku, ktorý zaberá 8 bytov (pretože je dekomponovaný na 'c' a '̌') [ehm áno je to úvodzovka s mäkčeňom]
Podľa akého pravidla? Perl aj python mi hlásia dĺžku 'č' ako 1. Pri dekomponovanej forme hlási python 2 znaky, perl stále 1.
Čo sa mimochodom stane ak niekde do formulára na webovej stránke hodím znak ̌ ? Je znak '<̌' považovaný za zobáčik z HTML, alebo tým spôsobím xss?
Podľa akého pravidla?Unicode.
Pri dekomponovanej forme hlási python 2 znaky, perl stále 1.Pak to je IMHO špatně v Perlu, případně si věř, že skutečně počítáš délku normalizvaného stringu a že to Perl nějak nenormalizuje ještě vevnitř, čemuž bych se až tak nedivil...
Je znak '<' považovaný za zobáčik z HTML, alebo tým spôsobím xss?Jsou to dva znaky a první je zobáček. Jeden znak zobáčku s háčkem AFAIK neexistuje.
Podľa toho skvelého pravidla ak dám vypísať reverzne 'česko' vznikne mi z toho oksěc pretože sa prehodí poradie kompozitných znakov. Perl tieto veci rieši korektne pomocou clusterov grafémov.
Mimochodom Perl skutočne texty normalizuje do vlastnej normalizovanej formy s použitím nepriradeného priestoru unicode. Dokáže normalizovať všetky kombinácie háčikov, čiarok atď pretože si dynamicky vytvára tabuľku s grafémmi.
Ak je <̌ interpretovaný ako 2 znaky prečo mi ho abclinuxu dovolí zapísať?
Podľa toho skvelého pravidla ak dám vypísať reverzne 'česko' vznikne mi z toho oksěc pretože sa prehodí poradie kompozitných znakov.No to ano... a v čem je problém?
Perl tieto veci rieši korektne pomocou clusterov grafémov.De/normalizace je typicky k dispozici ve všech možných jazycích, python to taky zpracuje správně, respektive zpracuje to tak, jak mu řekneš, aby to zpracoval. Pokud si to hodíš do NFKD jako výše, pak "č" budou dva znaky, pokud do NFKC, pak jeden. Obojí je korektní. Použij takovou normalizační formu, kterou potřebuješ ke svému účelu.
Ak je <̌ interpretovaný ako 2 znaky prečo mi ho abclinuxu dovolí zapísať?Proč by ti ho nedovolil zapsat? Zobáček můžeš zapsat zcela bez ohledu na to, jestli je za ním háček nebo ne: <
Za bežných okolností ho zmení na <. V mojom komentári nie je escapovaný (pri troche snahy by som tam možno prepašoval nejaký javascript na onmouseover, alebo niečo podobné).
pri troche snahy by som tam možno prepašoval nejaký javascript na onmouseover, alebo niečo podobnéZkus to
Inak k tej téme odporúčam pozrieť túto prezentáciu. Sú tam aj krásne ukázané exploity v rôznych webových službách. Ako je vidieť tu na zdrojových kódoch tak aj mne sa podarilo nechtiac exploitnúť tunajší HTML sanitizer. A to je len špička ľadovca. Vďaka nekompletnej podpore grafémov vo väčšine jazykov je mnoho webových aplikácií zbyčočne náchylných na XSS.
Ako je vidieť tu na zdrojových kódoch tak aj mne sa podarilo nechtiac exploitnúť tunajší HTML sanitizer.Ale prd...
Vďaka nekompletnej podpore grafémov vo väčšine jazykov je mnoho webových aplikácií zbyčočne náchylných na XSS.Prezentace je to moc pěkná, o tom žádná. Ale ten problém zdaleka není jen v grafémech, spousta problémů je s podporou non-BMP znaků, zejména kvůli všeobecné mizerné podpoře UTF-16.
Unicode.Grafémy (znaky z pohledu uživatele) != code pointy (znaky z pohledu programátora).
Pak to je IMHO špatně v PerluZ pohledu uživatele je to v Perlu dobře. Počet znaků by měl jít IMO určit bez znalosti interní reprezentace (tato je pro uživatele technický detail; IMO úplně ideální by bylo, aby šel počet znaků určit i po vytištění na papír).
Větší kravinu už jste plácnout nemohl. Vzhledme k tomu, že Unicode obsahuje také řící znaky, jak je budete počítat na papíře?Ty bych nepočítal, to nejsou znaky z uživatelského pohledu.
A nebo typografie? Máte v Unicode např. mezery různých šířek, jako je 1/3 em-size, 1/4, a asi 20 dalších. Přeji hodně štěstí ve zjišťování kolik mezer bylo v počítačové formě a kde, až to vyrisknete na papír.Ano, z tohoto pohledu mi Unicode přijde špatně navržený – je tam řada znaků, které vypadají stejně (nebo velmi podobně).
Unicode nikdy o grafémech, ani tvarech znaků (tedy to co vytisknete) nebyl.To se pletete, Unicode je i o grafémech – viz část Unicode Text Segmentation.
Ono to hledání grafému není ani jednoznačná funkce.Standard Unicode obsahuje algoritmy pro určování hranic grafémů.
Ty bych nepočítal, to nejsou znaky z uživatelského pohledu.Jasně, že to jsou znaky, v jazycích typicky nesou význam. Unicode je IMHO považuje za znaky i grafémy. Každopádně, počítání grafémů mi nepřijde nijak moc užitečné. Člověk potřeuje počítat nebo iterovat znaky typicky právě z technických důvodů než z uživatelských. Jasně, pokud třeba chci uživateli spočítat, kolik písmen nebo slov má jeho text, dává smysl použít počítat grafémy, ale to je IMHO okrajový případ, většinou potřebuje iterovat/indexovat string právě z technických důvodů (různé validace, sázecí algoritmy, et al.). A i z uživatelského pohledu dává kolikrát větší smysl použít znaky - například kursor v editačním UI taky neoperuje nad grafémy, ale nad znaky. Určitě je fajn mi API pro práci s grafémy, ale stringy, které by-default pracují s grafémy, mi nepřijdou jako dobrý nápad - dříve nebo později to někoho kousne do zadku.
ale stringy, které by-default pracují s grafémy, mi nepřijdou jako dobrý nápad - dříve nebo později to někoho kousne do zadku
Práve naopak. Ak používajú grafémy nemôže sa omylom stať, že odseknem čať znaku (hovorím o znakoch z pohľadu používateľa nie code pointoch) keď chcem napríklad na webe skrátiť text.
Keď by sme už mali túto myšlienku dotiahnuť dokonca prečo by vlastne mal string typ pracovať s unicode? Správne to má vyriešené v tom prípade PHP.
unicode.pl:
# my $str = "नि";
my $str = "X̊̀̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃X̊̀̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃X̊̀̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃X̊̀̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃X̊̀̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃X̊̀̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃X̊̀̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃X̊̀̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃X̊̀̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃X̊̀̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃̊̀̇̎̍̋̊̑̓̆̃";
say "Chars: {$str.chars}";
say "Codes: {$str.codes}";
Výstup:
$ perl6 unicode.pl
Chars: 10
Codes: 14000
Skvělé. Už se těším, až tohle někdo použije ve webové aplikaci a zkontroluje pouze chars, nikoli codes. To půjdou ty DoSy jedna báseň To půjdou ty DoSy jedna báseňPokud budou aplikace psány v rozumných jazycích a s rozumnými knihovnami, tak ne.
do Perl 6 stringu mohl člověk narvat nadbytek dat, například pokud by normální znak byl vždy následovaný N diakritickými znaky
Tu nie je problém, že to umožňuje perl. Problém je v šialenom návrhu unicode. Najradšej by som bol keby žiadne skladanie a normalizované formy neexistovali, znaky by mali jednoznačnú pevnú šírku. Bez tejto podmienky tu nevidím jednoznačné výhody UTF-32. Nemôžem jednoducho spočítať šírku keď chcem napríklad do konzoly zarovnať výpís tabuľky. Nemôžem sa spoliehať na substringy ...
Tu nie je problém, že to umožňuje perl.Souhlasím, nicméně nelíbí se mi, že to API je prezentované jako jednoduché, na které se člověk může spolehnout. Nemůže. Nicméně to neplatí pouze pro Perl 6, ale i pro většinu jiných stringových API...
Problém je v šialenom návrhu unicode.IMO to není problém Unicode. Viz komentář Ivana níže, to je přesně ono. Unicode je komplexní, protože řeší komplexní problém. Pokud má Unicode fungovat správně a pokrýt veškeré nároky, musí být trochu "šílený". Bez skládání znaků a normalizace by např. byl velký problém s ligaturami - tj. třeba fi za sebou - a to je jen blbá latinka, co třeba semitské, indické nebo japonické jazyky - viz třeba full-width katakana, jejiž znaky zabárají šířku dvou znaků latinky.
Nemôžem jednoducho spočítať šírku keď chcem napríklad do konzoly zarovnať výpís tabuľky.Za to může komplexnost daného problému - zarovnávání obecných Unicode znaků na nějakou pevnou šířku. Mimo jiné je to závislé také na tom, jak to daná konzole interpretuje, nicméně pokud použiješ správné nástroje, dostaneš se s trochou štěstí ke správnému výsledku. Viz tato otázka na SO (psal jsem tam odpověď, koukám, že linky už nefungují, ale dohledat se to určitě dá...). Naprostá většina "problémů Unicode" spočívá v tom, že někdo si neuvědomuje, jak je ten problém ve skutečnosti složitý. Unicode není šílené, šílené je zpracování textu, protože šílená jsou lidská písma.
Problém je v šialenom návrhu unicode.
Co je šílené, je svět, unicode se ho snaží jen nějak popsat. Stejně jako třeba definiční soubory časových zón nebo locale.
Člověk potřeuje počítat nebo iterovat znaky typicky právě z technických důvodů než z uživatelských.To mi přijde dost nízkoúrovňové. Z uživatelského hlediska mi to dává smysl pouze při ukládání nebo přenosu dat – v jiných situacích mi dávají grafémy mnohem větší smysl než code pointy nebo menší jednotky, neboť uživatelé většinou neznají věci jako znaková sada, kódování atd.
to je IMHO okrajový případ, většinou potřebuje iterovat/indexovat string právě z technických důvodůPak se spíše jedná o pole bajtů než o text.
sázecí algoritmyProč by sázecí algoritmy měly pracovat s code pointy nebo menšími jednotkami? Přijde mi, že tam se naopak pracuje se znaky nebo většími jednotkami (např. slitky).
Ano, z tohoto pohledu mi Unicode přijde špatně navržený – je tam řada znaků, které vypadají stejně (nebo velmi podobně).Zrovna nedavno jsem v praci resil proc mam v databazi dva uzivatele se stejnym jmenem. Nakonec se ukazalo, ze jedno ze jmen zacima na M z azbuky. V byvale praci se nekomu poradilo zastavit celou banku tim, ze udelal copy&paste z PDF od weboveho formulare a vlozil do DB znak, se kterym si zbytek systemu nedokazal poradit. Nemyslim, ze je to uple spatne navrzeno, jen si malo lidi uvedomuje, jak je to ve skutecnosti slozite a vubec tyhle problemy neresi. I autori Javy si dlouho mysleli, ze UTF16 ma pevnou sirku znaku. PS: Unicode obsahuje nejake indicke znaky, u kterych je to naopak, je to jedno pismeno(znak), ale typograficky ma sirku 2 pismen.
Unicode není o vzhledu znaků.Součástí standardu je Character Code Charts – referenční vzhled znaků.
Škoda, že jste se neobtěžoval si tu číst vůbec přečíst, jinak byste se z ní dosvěděl přesně to, co vám píši. Ale chápu, vědět kulové, a zkusit praštit dokumentem, aniž vím, o jaký dokument jde – to zkouší na plebs kdejaký úřada – a někdy se tím lidi nechají zastrašit.Lze se tam mj. dočíst
It is important to recognize that what the user thinks of as a “character”—a basic unit of a writing system for a language—may not be just a single Unicode code point. Instead, that basic unit may be made up of multiple Unicode code points. To avoid ambiguity with the computer use of the term character, this is called a user-perceived character. For example, “G” + acute-accent is a user-perceived character: users think of it as a single character, yet is actually represented by two Unicode code points. These user-perceived characters are approximated by what is called a grapheme cluster, which can be determined programmatically.a ve slovníčku
Grapheme. (1) A minimally distinctive unit of writing in the context of a particular writing system. For example, ‹b› and ‹d› are distinct graphemes in English writing systems because there exist distinct words like big and dig. Conversely, a lowercase italiform letter a and a lowercase Roman letter a are not distinct graphemes because no word is distinguished on the basis of these two different forms. (2) What a user thinks of as a character.Tj. zjevně se to týká grafémů a jejich aproximace pomocí grafémových klastrů.
A zároveň konstatuje, že tyto algoritmy nemohou být jednoznačnéAlgoritmy pro grafémové klastry (viz 3.1.1 Grapheme Cluster Boundary Rules) jsou IMO jednoznačné a jednoduché, co vám tam přijde nejasné?
Chybí např. opakované upozornění daného dokumentu, že segmentaci textu nelze provést jednoznačně, a že podle kontextu může být za „grafém“ považováno v různých případech různě dlouhé sekvence code pointů na stejném místě textu.To nechybí – píši, že se jedná o aproximaci.
že dokument uvádí hned dva algoritmy (označené jako výchozí) – pochopitelně s nestejnými výsledky.Však píši algoritmy (množné číslo).
zlé jazyky by řekli k manipulaci, že existuje jasný, a jednoznačný postup segmentace textu, stejně jako definice grafému, ačkoli i zběžné přečtení dokumentu na první dojem ukazuje, že dokument se snaží tvrdit spíše opak.Ty algoritmy jsou jednoznačné.
Kromě toho v dokumentu uvádějí tu podstatnou věc, že poznat grafém je těžký, téměř neřešitelný problémAno, to je pravda, proto se používají zmíněné aproximace, které jsou jednoznačné a jednoduché. Jediné, co vás tedy trápí je, že se říká grafém místo grafémový klastr (případně ještě přesněji legacy grapheme cluster nebo extended grapheme cluster)?
$j=$j+1
a $j++
:)
Nebo jde použít knihovny z Perlu 5, ale u mě to prodlouží spouštění skriptu o cca 8s.
Chápu, že to často budou problémy v idei, něco jako zatím toto implementujeme správně a na rychlost přijde čas později. Ale pro nás, kdo se snažíme v Perlu 6 skriptovat je to dost otravné.
perltidy
a perlcritic
zatím pro něj nejsou.