From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.io/gmane.comp.tex.context/36493 Path: news.gmane.org!not-for-mail From: Arthur Reutenauer Newsgroups: gmane.comp.tex.context Subject: Re: Greek in luatex Date: Thu, 13 Sep 2007 03:15:18 +0200 Message-ID: <20070913011518.GA29626@phare.normalesup.org> References: <7EFEDA40-D45B-4A94-A9CC-2599CF5CF462@uni-bonn.de> Reply-To: mailing list for ConTeXt users NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="qDbXVdCdHGoSgWSk" Content-Transfer-Encoding: 7bit X-Trace: sea.gmane.org 1189646147 23167 80.91.229.12 (13 Sep 2007 01:15:47 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Thu, 13 Sep 2007 01:15:47 +0000 (UTC) To: mailing list for ConTeXt users Original-X-From: ntg-context-bounces@ntg.nl Thu Sep 13 03:15:44 2007 Return-path: Envelope-to: gctc-ntg-context-518@m.gmane.org Original-Received: from ronja.vet.uu.nl ([131.211.172.88] helo=ronja.ntg.nl) by lo.gmane.org with esmtp (Exim 4.50) id 1IVdJ1-0001ow-1C for gctc-ntg-context-518@m.gmane.org; Thu, 13 Sep 2007 03:15:43 +0200 Original-Received: from localhost (localhost [127.0.0.1]) by ronja.ntg.nl (Postfix) with ESMTP id 4C59D1FFC1; Thu, 13 Sep 2007 03:15:42 +0200 (CEST) Original-Received: from ronja.ntg.nl ([127.0.0.1]) by localhost (smtp.ntg.nl [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 22747-04-3; Thu, 13 Sep 2007 03:15:33 +0200 (CEST) Original-Received: from ronja.vet.uu.nl (localhost [127.0.0.1]) by ronja.ntg.nl (Postfix) with ESMTP id 2D8BD1FFCD; Thu, 13 Sep 2007 03:15:33 +0200 (CEST) Original-Received: from localhost (localhost [127.0.0.1]) by ronja.ntg.nl (Postfix) with ESMTP id 020731FFC1 for ; Thu, 13 Sep 2007 03:15:31 +0200 (CEST) Original-Received: from ronja.ntg.nl ([127.0.0.1]) by localhost (smtp.ntg.nl [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 22747-04-2 for ; Thu, 13 Sep 2007 03:15:19 +0200 (CEST) Original-Received: from nef2.ens.fr (nef2.ens.fr [129.199.96.40]) by ronja.ntg.nl (Postfix) with ESMTP id 7D0A41FFCD for ; Thu, 13 Sep 2007 03:15:19 +0200 (CEST) Original-Received: from phare.normalesup.org (phare.normalesup.org [129.199.129.80]) by nef2.ens.fr (8.13.6/1.01.28121999) with ESMTP id l8D1FI44051451 for ; Thu, 13 Sep 2007 03:15:19 +0200 (CEST) X-Envelope-To: Original-Received: by phare.normalesup.org (Postfix, from userid 1008) id 837CB3806D; Thu, 13 Sep 2007 03:15:18 +0200 (CEST) Content-Disposition: inline In-Reply-To: <7EFEDA40-D45B-4A94-A9CC-2599CF5CF462@uni-bonn.de> User-Agent: Mutt/1.5.13 (2006-08-11) X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-3.1.4 (nef2.ens.fr [129.199.96.32]); Thu, 13 Sep 2007 03:15:19 +0200 (CEST) X-Virus-Scanned: amavisd-new at ntg.nl X-BeenThere: ntg-context@ntg.nl X-Mailman-Version: 2.1.9 Precedence: list List-Id: mailing list for ConTeXt users List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: ntg-context-bounces@ntg.nl Errors-To: ntg-context-bounces@ntg.nl X-Virus-Scanned: amavisd-new at ntg.nl Xref: news.gmane.org gmane.comp.tex.context:36493 Archived-At: --qDbXVdCdHGoSgWSk Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hello Thomas, I was waiting for someone else to answer your questions because I had no clue how to address them even if I was interested; but now I do, thanks to Hans' reply: For your general problem you need to define a new regime that will map each relevant character sequence to the corresponding Unicode character. That is, you inform ConTeXt that the character stream it sees is actually a way of coding another set of characters and that it can forget the original stream. This treatment should be done before any sort of font property intervenes, because it does not depend on the appearance of the typeset text. That's what regimes are for. Now I turn up to Hans to give us guidelines on how to define an advanced regime in Mark IV: Hans, what we need here is to replace sequences of characters by other characters, so the mapping is not one-to-one and it's more complicated than simple regimes defined by a table lookup; but I guess all we have to do is write a lua function that we could plug into the input stream reading routine (just like other regimes work). As far as the rest of Hans' reply is concerned (Opentype features and such), I would like to add that it is a very interesting and fascinating thing to do, but definitely not what you want here, for a lot of reasons: Opentype features can be used to alter the appearance of the text, but the not nature of characters themselves. That is, if you did the transformation of your input stream at the font level, you would actually tell ConTeXt that you are handling Latin characters with a special appearance (that the font takes care of), so for example, the underlying text in a PDF would be a stream of Latin characters, and copying-and-pasting would yield Latin characters, not Greek. That is not what you want here: you want your "a" to be understood as "alpha" and your "less-than acute-sign w vertical-bar" to be considered an "omega with dasia, varia and subscribed iota". Nor should you think of these transformations as a collection of ligatures (which act at the font level), but rather as a text encoding, just like UTF-8 is an encoding of the Unicode characters: in UTF-8 the byte sequence "hexadecimal byte E1, hexadecimal byte BC, hexadecimal byte 80" is the coding for the Unicode character U+1F00 GREEK SMALL LETTER ALPHA WITH PSILI, and in the Babel input scheme for Ancient Greek the same character is encoded with the byte sequence "hexadecimal byte 3C [ASCII '<'], hexadecimal byte 61 [ASCII 'a']". Of course in the past, these transformations were handled at the font level and sequences like "< a" were actually ligatures, because that was all we had (and copypasting from a PDF was, mostly, doomed to fail); but we should not persist in that use now we can treat them as real Unicode characters. As for your other question in your original message from September 1st (remapping single characters, for example U+03C3 to U+03F2), I have to say first that I'm not very comfortable commenting on it since I'm not quite sure what the issues are here; it may be that you have a simple variant of some character, and this you should handle at font level (some glyph being transformed into some other one); but if I am to judge by the very example you gave, I would deem this should be a part of your input regime: indeed, if every sigma is to be mapped to lunate sigma, then it probably means that the lunate sigmas are part of your character stream (even if you didn't input it directly). But I really can't give any general advice here, especially because I don't actually know what a lunate sigma really is ;-) You would have to decide for yourself as a specialist of Greek if you're dealing with really different characters or simple font variants; in the former case you should handle the transformation as a part of your regime; in the latter, by defining a font feature like Hans demonstrated. But for now, as long as it is understood that font tricks aren't the general solution for the problem at stake, I would like to demonstrate that it is still possible to do everything at font level :-) If you have a look at the attached greek-babel.tex (and the features definition file greek-babel.fea) you will see that (almost) everything is taken care of using Opentype substitutions. You need Bosporos and GFS Baskerville to compile the file; by the way, the line with GFS Baskerville is a further proof that you shouldn't handle the transformation at font level: can you explain why it doesn't work here? As a compliment, I also attach the Perl script which I wrote to generate the .fea file. Arthur --qDbXVdCdHGoSgWSk Content-Type: text/x-tex; charset=us-ascii Content-Disposition: attachment; filename="greek-babel.tex" % For Thomas Schmitz. % Define a new Opentype feature to replace new Babel input scheme and use it % with some polytonic Greek fonts % Not quite complete; some rhos with breathings and accents are missing from % the .fea file (where are they?) and the final sigma isn't accounted for. \installfontfeature[otf][grbl] \definefontfeature [greek-babel] [mode=node,language=dflt,script=latn, grbl=yes,featurefile=greek-babel.fea] \font\grbask=name:GFSBaskerville*greek-babel at 20pt \font\bosphoros=name:BosporosU*greek-babel at 20pt \starttext \catcode`\~=11 \bosphoros Peis'istratis m'en o>~un >egkateg'hrase t~h| >arq~h| ka`i >ap'ejane nos'hsas >ep`i Fil'onew >'rqontos, af' o<~ou m`en kat'esth t`o pr~wton t'urannos >'eth tri'akonta ka`i tr'ia Bi'wsas, <`a d' >en t~h| >arq~h| di'emeinen 'ikosi; >'efeuge g`ap t`a loip`a. % Don't do that! \grbask Peis'istratis m'en o>~un >egkateg'hrase t~h| >arq~h| ka`i >ap'ejane nos'hsas >ep`i Fil'onew >'rqontos, af' o<~ou m`en kat'esth t`o pr~wton t'urannos >'eth tri'akonta ka`i tr'ia Bi'wsas, <`a d' >en t~h| >arq~h| di'emeinen 'ikosi; >'efeuge g`ap t`a loip`a. \stoptext --qDbXVdCdHGoSgWSk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="greek-babel.fea" # An Opentype feature to replace the Babel input scheme # Not quite complete; some rhos with breathings and accents are missing (where # are they?) and the final sigma isn't accounted for. lookup GreekBabelLookupSimple { lookupflag 0 ; sub a by alpha ; sub b by beta ; sub g by gamma ; sub d by delta ; sub e by epsilon ; sub z by zeta ; sub h by eta ; sub j by theta ; sub i by iota ; sub k by kappa ; sub l by lambda ; sub m by mu ; sub n by nu ; sub x by xi ; sub o by omicron ; sub p by pi ; sub r by rho ; sub c by sigmafinal ; sub s by sigma ; sub t by tau ; sub u by upsilon ; sub f by phi ; sub q by chi ; sub y by psi ; sub w by omega ; sub A by Alpha ; sub B by Beta ; sub G by Gamma ; sub D by Delta ; sub E by Epsilon ; sub Z by Zeta ; sub H by Eta ; sub J by Theta ; sub I by Iota ; sub K by Kappa ; sub L by Lambda ; sub M by Mu ; sub N by Nu ; sub X by Xi ; sub O by Omicron ; sub P by Pi ; sub R by Rho ; sub C by Uni03C2 ; sub S by Sigma ; sub T by Tau ; sub U by Upsilon ; sub F by Phi ; sub Q by Chi ; sub Y by Psi ; sub W by Omega ; sub semicolon by periodcentered ; } GreekBabelLookupSimple ; lookup GreekBabelLookupMultiple { lookupflag 1 ; # sub s 'space by sigmafinal ; sub greater a by uni1F00 ; sub greater A by uni1F08 ; sub greater e by uni1F10 ; sub greater E by uni1F18 ; sub greater h by uni1F20 ; sub greater H by uni1F28 ; sub greater i by uni1F30 ; sub greater I by uni1F38 ; sub greater o by uni1F40 ; sub greater O by uni1F48 ; sub greater u by uni1F50 ; # sub greater U by uni1F58 ; sub greater w by uni1F60 ; sub greater W by uni1F68 ; sub greater grave a by uni1F02 ; sub greater grave A by uni1F0A ; sub greater grave e by uni1F12 ; sub greater grave E by uni1F1A ; sub greater grave h by uni1F22 ; sub greater grave H by uni1F2A ; sub greater grave i by uni1F32 ; sub greater grave I by uni1F3A ; sub greater grave o by uni1F42 ; sub greater grave O by uni1F4A ; sub greater grave u by uni1F52 ; # sub greater grave U by uni1F5A ; sub greater grave w by uni1F62 ; sub greater grave W by uni1F6A ; sub greater quotesingle a by uni1F04 ; sub greater quotesingle A by uni1F0C ; sub greater quotesingle e by uni1F14 ; sub greater quotesingle E by uni1F1C ; sub greater quotesingle h by uni1F24 ; sub greater quotesingle H by uni1F2C ; sub greater quotesingle i by uni1F34 ; sub greater quotesingle I by uni1F3C ; sub greater quotesingle o by uni1F44 ; sub greater quotesingle O by uni1F4C ; sub greater quotesingle u by uni1F54 ; sub greater quotesingle U by uni1F5C ; sub greater quotesingle w by uni1F64 ; sub greater quotesingle W by uni1F6C ; sub greater asciitilde a by uni1F06 ; sub greater asciitilde A by uni1F0E ; sub greater asciitilde e by uni1F16 ; sub greater asciitilde E by uni1F1E ; sub greater asciitilde h by uni1F26 ; sub greater asciitilde H by uni1F2E ; sub greater asciitilde i by uni1F36 ; sub greater asciitilde I by uni1F3E ; sub greater asciitilde o by uni1F46 ; sub greater asciitilde O by uni1F4E ; sub greater asciitilde u by uni1F56 ; sub greater asciitilde U by uni1F5E ; sub greater asciitilde w by uni1F66 ; sub greater asciitilde W by uni1F6E ; sub less a by uni1F01 ; sub less A by uni1F09 ; sub less e by uni1F11 ; sub less E by uni1F19 ; sub less h by uni1F21 ; sub less H by uni1F29 ; sub less i by uni1F31 ; sub less I by uni1F39 ; sub less o by uni1F41 ; sub less O by uni1F49 ; sub less u by uni1F51 ; sub less U by uni1F59 ; sub less w by uni1F61 ; sub less W by uni1F69 ; sub less grave a by uni1F03 ; sub less grave A by uni1F0B ; sub less grave e by uni1F13 ; sub less grave E by uni1F1B ; sub less grave h by uni1F23 ; sub less grave H by uni1F2B ; sub less grave i by uni1F33 ; sub less grave I by uni1F3B ; sub less grave o by uni1F43 ; sub less grave O by uni1F4B ; sub less grave u by uni1F53 ; sub less grave U by uni1F5B ; sub less grave w by uni1F63 ; sub less grave W by uni1F6B ; sub less quotesingle a by uni1F05 ; sub less quotesingle A by uni1F0D ; sub less quotesingle e by uni1F15 ; sub less quotesingle E by uni1F1D ; sub less quotesingle h by uni1F25 ; sub less quotesingle H by uni1F2D ; sub less quotesingle i by uni1F35 ; sub less quotesingle I by uni1F3D ; sub less quotesingle o by uni1F45 ; sub less quotesingle O by uni1F4D ; sub less quotesingle u by uni1F55 ; sub less quotesingle U by uni1F5D ; sub less quotesingle w by uni1F65 ; sub less quotesingle W by uni1F6D ; sub less asciitilde a by uni1F07 ; sub less asciitilde A by uni1F0F ; sub less asciitilde e by uni1F17 ; sub less asciitilde E by uni1F1F ; sub less asciitilde h by uni1F27 ; sub less asciitilde H by uni1F2F ; sub less asciitilde i by uni1F37 ; sub less asciitilde I by uni1F3F ; sub less asciitilde o by uni1F47 ; sub less asciitilde O by uni1F4F ; sub less asciitilde u by uni1F57 ; sub less asciitilde U by uni1F5F ; sub less asciitilde w by uni1F67 ; sub less asciitilde W by uni1F6F ; sub grave a by uni1F70 ; sub quotesingle a by uni1F71 ; sub grave e by uni1F72 ; sub quotesingle e by uni1F73 ; sub grave h by uni1F74 ; sub quotesingle h by uni1F75 ; sub grave i by uni1F76 ; sub quotesingle i by uni1F77 ; sub grave o by uni1F78 ; sub quotesingle o by uni1F79 ; sub grave u by uni1F7A ; sub quotesingle u by uni1F7B ; sub grave w by uni1F7C ; sub quotesingle w by uni1F7D ; sub grave A by uni1FBA ; sub quotesingle A by uni1FBB ; sub grave E by uni1FC8 ; sub quotesingle E by uni1FC9 ; sub grave H by uni1FCA ; sub quotesingle H by uni1FCB ; sub grave I by uni1FDA ; sub quotesingle I by uni1FDB ; sub grave U by uni1FEA ; sub quotesingle U by uni1FEB ; sub grave W by uni1FFA ; sub quotesingle W by uni1FFB ; sub greater a bar by uni1F80 ; sub greater A bar by uni1F88 ; sub greater h bar by uni1F90 ; sub greater H bar by uni1F98 ; sub greater w bar by uni1FA0 ; sub greater W bar by uni1FA8 ; sub greater grave a bar by uni1F82 ; sub greater grave A bar by uni1F8A ; sub greater grave h bar by uni1F92 ; sub greater grave H bar by uni1F9A ; sub greater grave w bar by uni1FA2 ; sub greater grave W bar by uni1FAA ; sub greater quotesingle a bar by uni1F84 ; sub greater quotesingle A bar by uni1F8C ; sub greater quotesingle h bar by uni1F94 ; sub greater quotesingle H bar by uni1F9C ; sub greater quotesingle w bar by uni1FA4 ; sub greater quotesingle W bar by uni1FAC ; sub greater asciitilde a bar by uni1F86 ; sub greater asciitilde A bar by uni1F8E ; sub greater asciitilde h bar by uni1F96 ; sub greater asciitilde H bar by uni1F9E ; sub greater asciitilde w bar by uni1FA6 ; sub greater asciitilde W bar by uni1FAE ; sub less a bar by uni1F81 ; sub less A bar by uni1F89 ; sub less h bar by uni1F91 ; sub less H bar by uni1F99 ; sub less w bar by uni1FA1 ; sub less W bar by uni1FA9 ; sub less grave a bar by uni1F83 ; sub less grave A bar by uni1F8B ; sub less grave h bar by uni1F93 ; sub less grave H bar by uni1F9B ; sub less grave w bar by uni1FA3 ; sub less grave W bar by uni1FAB ; sub less quotesingle a bar by uni1F85 ; sub less quotesingle A bar by uni1F8D ; sub less quotesingle h bar by uni1F95 ; sub less quotesingle H bar by uni1F9D ; sub less quotesingle w bar by uni1FA5 ; sub less quotesingle W bar by uni1FAD ; sub less asciitilde a bar by uni1F87 ; sub less asciitilde A bar by uni1F8F ; sub less asciitilde h bar by uni1F97 ; sub less asciitilde H bar by uni1F9F ; sub less asciitilde w bar by uni1FA7 ; sub less asciitilde W bar by uni1FAF ; sub grave a bar by uni1FB2 ; sub a bar by uni1FB3 ; sub quotesingle a bar by uni1FB4 ; sub grave h bar by uni1FC2 ; sub h bar by uni1FC3 ; sub quotesingle h bar by uni1FC4 ; sub grave w bar by uni1FD2 ; sub w bar by uni1FD3 ; sub quotesingle w bar by uni1FD4 ; sub asciitilde a by uni1FB6 ; sub asciitilde a bar by uni1FB7 ; sub asciitilde h by uni1FC6 ; sub asciitilde h bar by uni1FC7 ; sub asciitilde w by uni1FD6 ; sub asciitilde w bar by uni1FD7 ; sub greater r by uni1FE4 ; sub less r by uni1FE5 ; sub less R by uni1FEC ; } GreekBabelLookupMultiple ; feature grbl { script DFLT ; language dflt ; lookup GreekBabelLookupMultiple ; lookup GreekBabelLookupSimple ; script latn; language dflt ; lookup GreekBabelLookupMultiple ; lookup GreekBabelLookupSimple ; } grbl ; --qDbXVdCdHGoSgWSk Content-Type: application/pdf Content-Disposition: attachment; filename="greek-babel.pdf" Content-Transfer-Encoding: base64 JVBERi0xLjUKJdDUxdgKMyAwIG9iaiA8PAovTGVuZ3RoIDU3NCAgICAgICAKL0ZpbHRlciAv RmxhdGVEZWNvZGUKPj4Kc3RyZWFtCnjahVa7shMxDO3zFVsmRTaybMnrgoYZbkGb5Q6XGxgK hj9g+H3s9WPlx4bKsa3H0TmyNh/X0+1FTUrNjgin9feEC8ykDU2W/Q9Udlp/Te/nBwDcLt/X z7cX7SblZoekg/0Vwc3MlqYrm1kpsxQH9UDEuBqOK6U9a7/iN7EJq0mrSk5Yn+/Ol6tit2H6 E+K8pnvy5xZSarLh6oO4ii7qoa1NCXJgPU6YUW92+PUAXXZmkSKGQH/qEyOZlJhsHYPtbiWQ Szj4JpGXACDrbhARFUResAm8RjgDWS2VyUYlopY1toToEX0RxJuEjraWiiINSpsWWlyt2qV8 gLZxVTCgSWDNUUpjyBqCf6Bz4XNTBOfoUqjiu0sQm+rLoHPGnZJ1aPuY4An/0fM9ANVnwWcu GwfxrIC0mCrQj3FzFpU7tUviYNkDbxOI2Ju2uNaEHEljUFbYd/Y4S54MtTfIOYA/j1q19EAm X81GOxbka/Zx/dzKDUJ7Y5TT0uWB7d22ftdUnuVFnY+fNiqQqUoJr7nZBhOyfSkCBka4R7o2 hZUp8UQh4cIxgbZjfTPdG0z4613RtF3ENXKmeto+HUtx1N7zgxDDM1F/l0fUvgyUk+meZLXp u7XI71ZIDzOwER84L7of4ui436kylQADx47kaWc7sEmn5PDYc5CzxBnj2U7jHvRxHOAOQbIh pyrM/J9crU3yH9x1qDYcWXtlZ9b+r0RHPvWlPyW0pYf2VId3HXV0JOmy5Ai8tdHp03r6B7Zm F50KZW5kc3RyZWFtCmVuZG9iagoxMCAwIG9iaiA8PAovU3VidHlwZSAvQ0lERm9udFR5cGUw QwovTGVuZ3RoIDY3MyAgICAgICAKL0ZpbHRlciAvRmxhdGVEZWNvZGUKPj4Kc3RyZWFtCnja Y2RgYWFgZGSUC4rwcg1203Z3C3ZKLM5OLSrLzMlJ1Q1KTS/NSSwCqXD9IfNDtptH7ocAww85 xh/yTD8UmH9IsPx+xMO8k4fld+/vr78e/PzIKsvAwMjODyLlBL+v4FECsphZeVRAAmI8qgxs QKuUtdPrevHa55iSn5TqmZKaV5JZUumcX1BZlJmeUaKgkayp4F6Umpqt4JafV6IQnJ+cmVpS qaNgZGBgrqfgmJOjAFZXrFCUWgw0MTVFD2i8ApL5ClDz0YQZgOA7wz9GZkZWRjZGDkZhZgZG kBgHAwcTkMXMoMQQzrCb0YwxkrGG8bINX3b3dyXG99+VmL+3XRLdlL06JSU7OyVldfamTatX b5Ljc/5RVvY9u5zxu/NPM9Ge9vaeDumy+sq0dvmKtvAGC7m5rZteLdjd2yc5YUbf9KlSc5qn VffL8RX/liv7vryc8dt3ZebvfWtEVzUuzZktN6mutq9Our2ju6tDvqytrqWlkaOlvr2+Tqqu v35Sg9yU+umts7tmdk7q6Onoq2ktrymqLigvKMnf2Sgxf+7c+bMWTZoyceqEKRwLt0xbt0wK bMcPI6DbvzOAHN/3/RbY9ck5QNevyt4Mdv3vnSy0sPr7hp6yH0vKGX8c+hEteoD9T9zvGlZv 9h8gah/7H5PvmaxwJe/LRX/Efa9hPQ1UBaTC2H+Y/E7/Y/IbpOTI94DjAWUPT84oFxKe8GP3 97uioQXZBRnSdVnTFoXLCycsikybViwdFZvqkCS/OmPOiunzpkyRnDdn/tSF0svWNFVulj9c yCo8oWnB3PYZ0vu2r7u0ST57HSsfKHkL/JDmUQOmUgZFUIqVFGqd+MO3/3t7N9vvy93sclpm Hof+83De41pwkofnJ5fIDy5RAASGTxwKZW5kc3RyZWFtCmVuZG9iagoxNCAwIG9iaiA8PAov TGVuZ3RoIDg5NDAgICAgICAKL0ZpbHRlciAvRmxhdGVEZWNvZGUKPj4Kc3RyZWFtCnja7XwL dBvXeea9M5g3ZjAYzACDwWsAEA+CJECBIEGRFClK1NsyZcmSJduyTUkQRYsvk5QcJZvUPXXr RHHb1EndJNt0c9Jskm67G9VNHUpKG3dzTrrONrvaR5J2692026yT9HST5sR2kjYW978zAxqS LItS5PSxxugH/vln5s69//3+152hEEYISegxRKPu8X2V6r1j9/aB5HNADx09vWT7xrCJEI7D fvz4/OQMu+fXy7DfD7Q4OX3m+Pmxd78PIep3EBpSTzQmjn1j3+iPEBom1/edAAEbZffA/kuw 33ZiZult99+Fv4HQCLQpPjs9d3Ti3/R/CK7dcQkh5uGZibfN+77k++8IjQ/B+fbsxEzjzBdC H4D9+xHiX55faMz/5cMfTSB08G44/jii8Yfx+xAD/DHYEHpy9beK/g56iJqf5xD6ror+4q+b +5MnT55BG5H99xT1nZUDKEl/GU/bRA/wwc9Tnyd3Rz6kIxNl0D50GJ0gkpVhpOGvII76DeRf RqhzF3ztOfi7GP/SoWW88vPLaCxxHs6jH3ygaxnhTtveMjV2Dj8EO1QnCEpp4OhOe+s5Ord1 78HsIfusfXbHsbP2VvvExLFzvpzzCwcaZw9V7HNo38Ep+L77YPrcxkOxVbZx6NAAtOMj7fic ds4eghYe9lp42GkBGngVTmI6d9nn6Pyeg3cdPPfYWOzcxrFDsXTa3nLuuT0Hzz03FksfOgRn sas9hd93TplenznoM1sChndb2Xfw3MbYOXTo7Fl3L5s+99jZs7GzMA5vfxk9d5UAo6sFGz0B aIK0SOe2LOPH9jiHHsumY0SQTWfT0M9DY3BvoXPXvoNboKfpQ11kQm38AfRuahmpaOQiTBcD m69jVEBPw84ngJ4F+iKQ7/Aog74CzP8Bog4vI0ldRtoL6ALiyQx1dK8LleneWl9PNWzoCsVt ZxS/kAyHk4Ks+PAHcsP1eiqcTIZT9fpwDu7LrvwmegodRSX02YuoHe5qk/sy6H8A89dA1GHo xIeA+S2g80DPkzMOX0BR+G0PausRDLgCMwLEAYlAfiC05eAySlRi51ECscOHllHbC6MB9Guo DX0S6LNAfwz0NaBvAv0AiDs8KiMOmAhQAagOtA3oHiD2EejTcWBOA1GPkNsnUBvcvntdRMHZ TCHDZWs91fowrg/T8N1by3IK5jL53loddJGkDP1JpWbwdESkMUXRPMubpkbTPsz6RC6SsjRJ iai8kctgCmPso2hFD0uSn8I0xVAZPernA2YqECJmhLLw/X40DxPwyxeRADqjm3MlwFwJMFcC zJXQnCsB5koARSJPK4hoBblaYV2tsKAVFrTCglZY0AoLWmFBK2xTKyxohQWtsKAVFrTCglbY plZY0AoLWule10MG7M49e5+VzBpAzheQ4wJQDp2i2inSgAGYYUBCd1yAAWDEONrETG8X7mWo 9ld/jH/v8m7Kh3d9tfLsH1a+jvDK91d0Ssa/hzbByN1ZD1VA/31avUehI0nsKh94I0n11fuS FKdQ+UKZYt1fDBOiYAJKNj+MuVRNuhvAydFMZ2+PrMo+mtnPBFUJB8y4ohgyxUj59jaeDmgh Tl9XafdLKpzs57A/mQz4sbSwiMVPDd23uaz25sR1ma6h9aPV0oE7R7RkKeiPRrFVkBMpKpYQ dImW27M4BjpRomJ2sFpIhllaTVecucSD6P34t2FE9ZuaywugQc/eXkfnePA1rdMrr6ysUHPU 18C8BtA4+tcXUA/qgEuXUQfY7uAl0KXRtBiVYENFfoINR9BPBP0tgtfQcwHtQqNOO/3QTvcL 0MEp1I3OAFGPAKw+CMyngOAY+g9Afwr0LaAfAjmw4oExgYpA/UDbgQ4CsYCkSCZPppPK9wZr ZQomsa8n7ZgRmT4dJhtGy9GGnsQw9L5eOCebYYOwT/VUh6l6H9nPK3hPtcj3lGQ/2JkS1cw0 F8vhHbXdVTPalpdte2z8/ntfDMTy5r33R8ujhd6BQLxkjdxV0TDODI13mflYAPuEoExzwZSF n+nq1BmGDypCvqdH7t2QCTBSQrXuGtt/iKKeeMaOi/QdWwq1pJ+7/PH/atsKjnfVrfYN7Tr2 +WGuVyB+Uz+kvoI2o8rr2aIjKBBBgQguoiCiwNx8HcSu+lp0gUEVYQJm2gjCgCNJiu3ALfrK Z9MZ1juEs4rqtzWNw5gPqiXOoP6L7OeTCTXIY8xIkhUXWP7HPMeFDXJSxLr8im2SU3OMwaii qlkGflk1dfBNHNxR5jXdEC+XrbwVZGQFWvXxPG8kcib+plFK5y5LZtII8CqkDjRCK69Qfw64 24UeQHOocAEdQHc4eDkAeBEvuc6a8DbwNtFJkdhzyTFkqtY7hMu4UGZ6a8MwqeG+fKGW94AA Fo2NOA47rpUjmIABu6rIF7AHAqIJ0FEuGMdJ7Ajg+gz7F6rC27ZhcJJl+Sv9g5VU5+bxTKE9 gOmUbcXYgIoHDbVSyiopu3pgJEuXdk0OGZzPH9ZMk/HLlx9OlvtMIyJSuYrZlQ3jTZxhVEYL wX37rYjPJ0q8GtQkLSKzNOUPp8sDudLOuk2zmlHqlHjehzlD7cwRZdv1naXqHb1xuK9myCIv iTRN4/ncWG+KBtDhmhEUmWjX5vHLr6iGzOaHduX272dKgBcKfOH38PP4OTDAw/izy+gB0ORe oAdAmyOgzRFi0JcIvpxYuhdi6d5mLN0LsXQvxNK9EEv3gmOBK1vmY696HmmIeWkZ6SDRK+7R CvAV4Efg6BZEvwTm/TQwnwB6FuiLQF8FehHoFSAwbxoc1BaESYQwgMkBUY+4jY1DY+PQmAb8 gy8g4nU89BcJ+ost5lAiglKLYIAIBlz7YMA+7gH7gOugWxaiXnKCmQXBzIJgZkEwsyCYWRDM LAhmFulWGoKZBcHMAiOzwLosCGYWtGKhSaBHgZ4AeqNG1EdGIzfViLQAOngWmC+SPi4so+0w /h2XutcVhumeaoRgE6wbvg09gAHGYcgjANiAb0Avx2Yzjs2De4NdsgN2UQf46+EIAfUIJtkG cXdw2M8W65tSlaQQEhWT5sJigOtnTDUcSMoChhCZEilGCCgyx/kZTqQZs63LCnYWYkcYJt7G p8qZMEfTlBpNKhFZikaNz4xMbErnJE5m9WhST3w9IicsvT3sExkzqQk09muGqIgyJDMRNdwx 0s7KA5GSnu/xdW7cFvMLQV6PBTmWMdLdJNbxl7+J/wp/CTA7fhGyN9rNMQmSbECSDTqyQUc2 IMkGJNmAJLuJJLuJJBuQZDtIYgA9vaDJXuIzIO7X+oi3cIJ9DfKAJCZ+EaJEuM/JysAHEHWC 29SJ9yiTXGGZ4TmGppmgLiUyWVXSJF5Il7q7igrrgywMXEFuh82HAjCCrr6xLlVhwraUjGs0 k8ik84xs5m1j+56dphjiJE0O+WTN7Er6lXJJ6+7ttzSdCqilx8dV1h9VR44/NDFgJC1ruKSK om0l+spZYsc/WPk2foJ6FfWBa+TAFIIwmkKNRLDeWgXnXd+XwiS4ZzMgyGYUCIIpGI2LDwcd MHwCAQgC5CB4P6F9aJMl+qdMPV2KJMx3sYaqKHcJflEPiuzPbu3DfG5gd8Ue7E7S/z67Lqko Zkb32dVMSIpkzf/cc3Csg/H5/XB9Us8lNGVKkoKWdFT0a2FRYt+9a6mLEZje+7cUcxvGSx+k 09VhO7OxmioO35mL1woRMtfxlR/jO/EfoDKKo2ts+QJJnp3kpV4b9rmpSwfOZ8jguOauMxAn zpMxxtO9o6PrgwIn8jTDM8mhatr3YZ4XpI9m1tWNqGEEe+/dlP/C0P56SqUDkmJiNdVtB6Hj VHs1IVKGXwnHenY6OSi3MoC/gcGZwbaMIuB8Mk0H1EX62IX410l34CzwMiJ4GcIB7l6AuAy4 g4nKO8YJJgrZPjHksGPUDgspC4Fdtk8bwTVn9sju3aIWDEpUUlcSoqDzfk0v6ZGCxAk8L1s7 cmZXRseyGbXUbXbFj5PhUCmfYKWALHED42NbKqIvbCqKIivBeCJq6cGEXsjI4URQGDn7i09u +mXMHOcjumLlIl3bNtRjJE+E7OPr+Lepr6MYzEAfCkH+GHem4AJahzqdqYg4dZuTQTsz4IAr TyvORAxiklUVeshgO7BCvydbS6uS3xjYvreTXr+J44SebftLDF/n/byeMnFluBSVvvXdYC4H sCq1pbjuLfdUinsLm97+4JDvFx5tG+9a/86pMYzfmRwvJvs7rYFD09WeHfWhbVRu7AEyR/mV H6Bv4d9FSbB3byoiZCoiLbHAIgKLCABIoR6nq57aPeMogUcA79g+snuEov1akg+LIYoyklmN 5mi7/Z24dvkP5RAfrQe0NOPnQ6mIHzMb84pbq/hX/gq/F38e7UPvuAhRqSU3L4K/KoK/KoK/ KjZz8yLk5kW3zmIBT7EmpnpJN3tb+u3l1K8Jeoigp0UwTgTj3siIf3fze+K9WHeMdH21xFbo BE6Cc4dsmGPBhiBJoiu4GTEcXIIfCRuplBYwMcMxOASeLJUvyLIcispaiPGnk2EcsixBjJnB GKjG7A6p0ZDCsIzKSzp4SIahqXhAMXeO/+bORFzXOJ+VN3x8IiKWOvM8F/HzGlROVNhuN3zm UL3oYwKQ4fhpHFWktvZSEO4Y1rR0Jm9qBlirq1995e8ohfp1qOdW57idDLy9RRPDRDDcnGOi ijwZWwFG5NgZHXG+krQLWjdY0gXPIpuDT31KEkm5ULP5KG9IyUouJlGUGrNiAZaTo5GAEtO1 jnyC4fVQgBYjSlKxkiLTqSvGQZzSDUnQg1z33QmOkxkmsH7ztoSPr+4c3VRSIwFe5KQIqS4S mzd0S9lUW+9DJSsdikScMYorL+NP4/No42tjvGb6B4lgsDnbtOtPCHah5yO4Wes0Jx4OEzv1 pt/nTjlI4mYyyLICIwuMyEbtn6EkhabGeYlTtC2bq5qiBSTdjHWP7txT9Bt8LCRvdqpVww85 vKywHAApwCrC5VctSWH58o7GiB6TeD/HJOzc3fvuHG73UZIoJSDnCqy8hH8Jf8FJffRrKxnP lUBXBzEBpeNJCuGqW5iRQFVw/aDjWT7Rvr4tyIrtQ3dWFL0rF/X5+NLA1jaos3xmMaVDiaJH FT5RyUZZhpYjCb8vV9+cTSY6dvXblNW9pSuY1fM7+jP92CxUY6W2+Lo2A1sdA7bRpqZK8QDM gbDyf6kx/CeQ7JIIm644Wq67rsztiKNB4jgglLlBR6GypKbgwhGHd4/TGzC5xkEW7V31AJNu sxlfRGUTGUMVGYXnJKxWDDydivl5GYpFJcD1GYYhSgEzLis6zYTDKqvf4/PRPN3PtemhRF3e uHunGVIiPA0Jll9WFM430s9LPKVKoqFJdMB4/4Mpn2IZsmH6g8aG7XsKvoAJVqlIl7+VSVoR nuQS37n89/g9+I+huN+G/vwiksFf9TnpsQzhSr1E8mxwVBYISQxwavQPAfNbQOeBngf6M6Bv A/0IyEm9BGDwI24TO0iuXmi6NYNMuNEC4xQRpNzUHMIk2uDc24ALy+4qUxnS4TLk1GXIqcuQ U5chpy5DTl1urjKVwb2XIacuA7DKMIgy5NTl5ipTGZ0GIqtMHFlio1uiFCAqf6W3C4UdtLmp cSG/irewpFpWQhMTuUpiZCdFMfHO9RlDE0RZDvgNH0VRPtqXCgYinw5H9ZwdYXlO1i2ZEY1s 3GDhDh+949eemM9puWTowP2BtJbbPVL08YoEwNQq1R4TKsiEgYVAKJkPWd1GCsBIYz3dbuj9 icIIKAWqYiqMSR40glAPyebdmJv2VnBIvp8H23d6G3GR6NkOKV+9/C/88cKGolEo8lYqreKM LCmiLjGi1mYxMqtFsSiGu3cNQ5IWKyXVpO2XEuuyoUKyZyxXPV7ktaBM+wCbMRoLmFFlhtaq ifZ7tpc3UZnaqF0a5Wm7Z2OqNAa2Uwf/9WX8+6jymqW/lsd1rwt52Q8YUjMDAgNKV8lImslO 07z+J6covOFnpXiAD3J+MRiBEjebs/eR5RmagYyb4teZoRiLqwkNsiNO4yVNTZpKULI4UTPl wo4NFbmrMxYLGI5vlVZexOfxH6G78KMXwb3STny+CIUmAxWiV1nkIFLnIFLnIFLnoLLIQWWR g8oi16wscs3KIudsZG2Xh4ZyQW39MuIrZP2Yfqm5RLGMtqgklkMBTMrqASirB5pl9QAY0gAi xenz5PaHybnLaN8L6JqYfhGZgATJMY9xlRS8XuVaBAMpgoEUwUCKYCBFMJAiGEixWbkWwUCK YCBFMJAiGEgRDKQIRWcRis4iFJ3FN2zEq1zX3ohXubpZDqlcO0AL5uoSA/hRkl2BnV2TAUPa 62RgpEpten7HGvMFr6YJe3HNLXHz80E5oAepkOwPM2JYkA2ly9Ta4kFMaSHVsn0cnSzFNRYM lPIrvKQakhRieZEXGT3TV7CSZq+qlS17bHS9YZsBERIOLaXrfihnfLzPWD88YsXzDLYrVY3h RUtJjUIlQ6ohORDZmE0OhLVafy0kk/V1euXlFY7aSX0QMuPNaD/MFXi/ptOLkUmMeaG6TJGB DOP8CO7hWGf1yV2JckDvVJi9fTX4DUFpSupSZ0GuLx9h4RsOknqVLEp/evPdWXl4ZtzQWEwF DhUZQY/LPdvbmL6Td6tpJ/miY/Egz0ssTUuRrhJNK3Gzd4PFJLqTps7hOsUGY1p2qF1TqhUt IjNY9m8/fPxAHfMh7fynzXiAo9Ut9zx41wCXUuVytVPUdDqWSLSn46oYlKW9OM/zFEVzfTv2 bq8xDCXoflWmGFrsHt6+dYPB+yA5dnK2lb+5/DUqjv8j+GMZuSuUfmeFsl5mIDB69l9N+iJh Z1WDceuhBFYYz6MxLbkaWZQn/wA9AUyqJC8s/wEEt2S2GGYhH5NCppLqzkY1PxMOCuEAbcQS lkZRuhSwqEimPZ/ktCwN0mQ8wsiWqfOKakQGRgyjX6dhTDQt+8x8Lm9uMwcH1sks97DYN7Zj QxFLjCzxsc6+3rIyHI1w2a5qV5YTpEhcFArV/mpBiKQgn+IKtcG+dkHTBUri+UAkZy9tEQJM wGBzg0NbK7UjezeGBFEIO+sbK39L7cHn0EP4uYvgLt31jYuoRtyJw+0CbrjpmXTwTDpYlw7W pYNn0sEz6eCZ9KZn0pueSYfLdWfNIwe2l75EchjCk0qVcZfiatBYDRqrQWM1aKwGjdWgsVqz sVqzsRo0ViPBn2QCw+DHh5uZwDA4sGFEsu3ngf4M6NtAPwLyMoFhJxPYBX04QryaBJ3YWrne QvYeItjjCf5JLc+tv0QeP3iR2VmW8xyZW9RDEuh6vWb9xTpObjVCO8WaF7nJsrwHcOLpnrJ7 2kK9g0GTV+VoRud5VsyH42FGkQWK4oLJSCTICgJFQ7UU0ktpI2YbfiGkdxXMUr/ty/WqPpYO sIwky0Y0E0is25Qbeqwmi2pAjfav74tYRTEYjTJyQBVof1KNVPJmzAhkMrZfEcOpgGL3bc3l d9kGpKhydrLedc9YKZllRcbSdckMK47vc9aVqR+CjzuM3oO+f9GJqvc56P05wPPpJnppABwN aqNBbTQAjgbA0QA4ugk4ugk42gnNBL0/p5JnSySa3gcYigOO4wAfFaRlZ8FZBenDIH3YXbQ+ DdH1dDO6ngZwngZwngZwQidWH2aOEZiNteBuKxFsbREcIIID7rLTO9AiomEoafBbhhN/D8Dd WWdNpw/u3Edi2nXWVrlbXq11/aKT5uVdKLCrBUfViQkujvZfZxX2xC2u6mIpJbLBgFOau4+V GdlvZDkpoSqxsAreUU8kReqb11my3XfTi794VqJ94FXloBmSBIFn+LQhiyEVfLgMLceL8SBD kTjiuwJn74b5XWlFGsABgHLLSHPQowJ61CZ6VECPigj6nicNH25F4AXUgNvSTr7XgHxvwcFi GY6/95L7+y9fuDW0zaBTN0DbMpqB9p++9GagLpQpNFf0SLblRlznJI7lyLqJoWczdec776w0 kwokcrsx+HFMicmEDoFYDccUNSFxWcMvk2SfIJIsPiVZ8b/RMhvgjshGQLWF2wlHigkC6Pig IAMg1ZAoG2kApSBIoUjAz0cE2uZ9Mi8+GVIDwbAJpZm7bg24LKN7b9PKdWiN1r+2Fe5PrMmk b7gOjp9Yk6W+Kfq4AS7JidnM2rTxzBuiS1I1PhBkxTVo4/pAMYMyL8k+4pzCoIsZRxcH0Ynb pQ2vaOpzrd4z4haEgIZ0AhBy3Gki4IaTtSnoTlnzQVFCUVIUU4AOlpXkcJbz28F4N0cFDHOm n08piqbcJ0vyjfX0Pl4ATflA3R0BaFfyQ5UPuNGDxQQjMKF8xmI/bBrBQFB/Mhjk3FrqB/gO 6gcoibaD1m7DWv4tK+x6DwGyN6Oi6z4xwM/cpGoAT9LKN/F5+nE0jh5BH0H7L0BJBemRG/Vk iHoyRD0Zop4MUU+GqCdD1JPdtTIWmDBQHqgPaCvQASBnrawBzCkgslbGeGXWdcv0ZnIbfuMi nUyIt5Djrj07zxscw3Wc2lq9HA7EE2bNaq32I4JfV7qiIbfa16HaZ8REa7EfNERJYwWv2P8k gFJmWSjJNg3bgzFWDUiSzDKKuq5uVbesyT36ZS1yxWqBFnBWC8w2U2C8xQIftstvtFhA82pK lURRUvus/R0lwYpHedME2VDi8nfW4lzple95OdAougvN4E8vo1lICCaBZiEpYC65LzXyl8gy lJPSTEJKM9lMaSYhpZmElGYSUppJJ6WZJG9iwtkaacWpuEgi00yzydE68HXysiQcvRf5XgIg PQ3MJ4CeBfoi0FeBXgRiSW71MjCYMAxhHnEbOQaNHINGLODnSGZ053VrwG4i6G4RVImg6q6B AT7RtJMVdUN3Ms3yMANFWQYquwxUdhmo7DJQ2WWgsss0y8MM+I0MVHYZqOwyUNlloLLLgAoy UNlloLLLvGEjXnm49ka88jAD2sk45eFhGP8DzRJxCNdvPkELOUnXazkX7awXXZv+LQS7ijHM tvdvSpVtXheVCM1FhBsnXrMYPNV94LGUFK+T5I27KqlLKeFApGO0xEgsSaraAKqrSVU8prcb jMBem1RRG2kuGHxSBx9mmJc/SXIy+9pc7aoacgaHXFyrHq7vA/XdB2k23XyL6M3J70ktKV9y V+6urDaXUR74/BWVZ/clAlb36C7gd1XczN/B95HKLWT/P+0aM1S/Mtrd7jz+xZYgeBsz9Mev jImt+ebw7cqwrrK2tSVO/6vFhm6cF32kxTLQFeMItI7jtZfXLqAusi5IXt+9auLotY7r37XM yK+saUzUuhZtX/7VNbwrQ7nvysA4RiBL2YaIDdz4TZmLxFMi0cE+eVMmcsl7y+YnfGvmalXd +ls0v9jUHcDxFt6oaVUk6853hryvAnpKAnJvR5Z7FWivl7y+pwWm189Nn2uFJ0XercGx29jX +toS7RNryqOfa/UItPuuAfSVrONu+8nfNrharzf79sEDLfq+2TcRKHyFl7j9Y7tqHm52bBta 5ufmx3aFI6fcZ7MwtrvQBH7HP9qns0dJfD9QeesJ7Rqe0F4Nr5/8iW1rYX1bnt5S/VemEzCH zjM5wOFDaB4/86Y/lfuHeBa3QDDceOs53E08h7sayrf1udx7W1B925/RURuv8rNufvYlyM8a aDdaS262G6560AH+m5SlrS78rJ7vPmtYnYEAVvCt524JIcBLmAkZ+pCdrGuqwWCFVxmJk+Ll cJdOidKtZHSFoCgwlNpuZduybUaHSvsUUVJVqTtq0Yru+JKVVyFv6gJdJ6EIvB1505oUdb1s irqhGq6fYz17o8FitPpH3g8Ghl5GUfpbhP8jZaXb+33vq++//AHmUfrLqPUD17h/9818CY6/ m3m05U/FnQ/1SXQZvfHnU8i+WoQfcP7akfxm0U/wocgK9Fuf2/6hule+fzvm563PW5+3Pv+f +Y7fX3nlVq6j15G/p75Kpt7EfVnXZ1E64vFzENmfRnFvn8P/CWE8iPLw66e6kY5fgDyJ+Lev oAB1Agn4Kyvfcc6tIxqO1fEPkUQ9tfIyFVv5G0f+lPO/YfzzmytPZ1fza/0QHTf17O2Hf5r9 x4MrL/9D6I3g402aj++ReWjVq4PfQZRx8At4JdTah3+u2PyJ9Ojq7LqflVdfVzy0un0VfRXX brDt/Se0fQ6277y1vbW93kY9c/2NLq1uf/p6G1OF7XNskT0N299y27mz/AD/O0IYtlnhf4uf ET8j+aV7/b8g6/LH5I8FfD+9Te0nW/Dx622aX3uKbKHOW9wu3Pqm38QWzkfGIp8y/bB91Hwl ekf0glW0irHp2HT8hX8sW+Kp629J3ltH+Awe9qKmu4YgkuUu+lc931vEL66uLexCaY/HSEDT Hk8hDp3yeBqtQ//C431wzr/1eMZ5x8rlWZB/weM5tAH9icfzqA0LHi8A3+XxEsrhuzzejwr4 tMfL6An8EY9XkUC1eXwQcVTzWg3kNZeHL4Ha4PHQf2qrx1NIo8Y9ngb5hMf7kEo97PEMEqm3 ezyLLOpxj+dAI6Rp7BOIfqjfIC9ROPzT1Lc9HiON/hmPp5BC/4rH0+gI/a883oc0H/Z4Blm+ kMezIO/yeA693Tfi8Tza7jvv8QLazjSvldBOZofH+9GdzPs9XsYK85ceryKN/a7HB5HC4R1z SxP2QuPYqaONY/bEscWjC1PzS3bx0amlE/bRifnF9s1z82cWpiZPgPBouz0601iYOjoxa+85 MTU9Nz03CTvT9uji4tzRqYmlqbnZTrva3d1btkenp23nskVofbGxcLpxrLxpbnF+bmFucf/e xuSp6YmFsbnZieljuycWlxaAWzjW6Jw4vtRY2D2xcHTz3OTE7IC9esWA0+zq7oHGwiLczF5X 7u7uXpWuMvbUoj1hLy1MHGvMTCyctOeO37jjbmfs1t7YTnds0h/b6dBazllcmltolGHI09ON hYmlRnm2sVSZmJ8gNLnQaJw82ThD7kqOLZaPNBZONqYbZ8owA5V3zU/NTrytsnpWZXrqaGN2 ESbm+NyCfWqxYR85Y8+fWjh6YgI0uugMa88oHJwFLc9PHD05Mdmw4cxtpIFd0MCgPTNxxp6d W7KPNOyJaeho41gnmY+5afiFMyenTjdm7YlH4Swy43OnluxHF6aWlkA431iYmVokWr5m3lb3 75yzN5+YmJ1s3DE1ObF0Chre23jk1BTcxV6VrDKb52ZmYMpW9x3kbZ1bmHG5faeOvKngQ5vR HJpHZ9ACmkKT6ARaQjYqoqOoHX5H0QxqOEeOogk0C5I9cMYUuLk5hya9I9POuYuwzcH+FEiW 4HsOruiEI1XUDVsvKjtnTTtnv3a3RWevAb/kTqfh+xicuQmuXoR+zYGMcPvRXjgyCU51Glpf QGNO6+TOx9Bu+F2ElhY82QLIGnDnCXQcpKTV3Y70qDPWSWckA3DXa+8x0NLba48ecNpa9EZm g1svO+d2v86510psuI6MdQKI9HXC6eWM07OTIJuD3t4Ojbdqxr6ubuwW7dir+rFbNHS72iFX zTkzXPZmmSCg4WhgyZHOwvcSqsD+PFDzd9K5pgG6OQnfZ1bH2rxuEa484rRz0mmTnFN20HMK 2ngXtDHl9PRtsHdtWxW4gmiy4fSw4YzxuNNPG64nEhtaPwPf87BPxnTC0YCLgNdmaw+Qe+Ws h2XS96NwHzKChnMmaXPbag92eT0YBCmZfXKPWThrybljw9HotKdR0q/OVfuYc+aic7VNgoXT zgjINY96bT0K0iXo7Rz0e8nZX3AkS96Z807LMw4am1i+sb0h8sipA12AyE0hqgNfcN6pAObz 8LMZ1eFYCpG/YOY7Pg+RewiMI49iEEtdCQMG1YkyKOqsB/Ad6PPQ0Ivoc+gp6MGIdxKFPoZ+ Hu65E3W5J5H/Z9KHuA64tft/2P4/2arrzAplbmRzdHJlYW0KZW5kb2JqCjE4IDAgb2JqIDw8 Ci9TdWJ0eXBlIC9DSURGb250VHlwZTBDCi9MZW5ndGggNTEzICAgICAgIAovRmlsdGVyIC9G bGF0ZURlY29kZQo+PgpzdHJlYW0KeNp1Uc9rE1EQfi9JGzXP+gMRatrNWGpRanaTBhV605hI Qhqh3Yoet92XZMl2X9i3MfbktbJZW9EiBiq10JBDwEMPHsSLJ0EP/htS73k0Bd1F8CLO4fuG b2YYZj6MIhGEMR4vLKt3H+RnSwuLbE2z0nPJRVptmpodFHNiQky6RBISEgksICQuh8VUZJgl 4Q8kcjw/7E+M2EfDkUmEcOdMgPvnPpKpIBFkOqAdcgWdCCGMxpGEZtAsOsIxfAFf+t/W2zpb oQWdWo7hrKflVDqVZY1126jWHJhLpTLXA7wFd2Qoaqt11uJ1AzRLh6IMCzKUWctXDbjKLFih Nc2sAKuASh9Ck1ObQ9VmzQa/JoNaMzi0mF0Hn21qUo1THZqWTm1wahTuLS+pkGeWAyVjlVqc QjIJwCmFmuM05hXFaVZlZleVit/DFfNPE1eCuWT+fllNlgrZXHkpJztPHKgwG3TqaIbJ5X8u /iuUmb2mmcgPJew/zI8QCmEcKQ/6Y7/wj1c33Z446H1t4QH7HhbyxZ4ZzWy8fp8QX6J7brsl NfijynTciu59cvc/J453otWNpxnJtEa97k+3H+8fus+6ibHA1rMiTmZ8d9ANH0Lk/ONdke0M 2PbL3VGpqJoKOemSWO/Ut9jbtrfVbr/YbHsHHULedd94m97Wc8/b3iSnfwMfebu4CmVuZHN0 cmVhbQplbmRvYmoKNyAwIG9iaiA8PAovVHlwZSAvT2JqU3RtCi9OIDE3Ci9GaXJzdCAxMTkK L0xlbmd0aCAxMTQzICAgICAgCi9GaWx0ZXIgL0ZsYXRlRGVjb2RlCj4+CnN0cmVhbQp42rVW XU/bSBR9z6+4bw1ibc+MZ8Z2hSoBIW3o0rIQKFKUByeZDd6aOLKdUv79nmsnEEph2VVXCuTm ft8754ytSJCkJKGEZBSSlKS0IEtaG5KKjI1JhhQZSxIKKWJiPfwlNFokHRlBhFqySgnSJGOl CJJMkCkmJZXGP3ysJbYoGXb29jrB8G7pKDhN564THBaL2i3qikL0c9YJzlxVrMqpq9Bcozhx syw9KL7TSEBhEuMrbirW0o/jJB53kKhEBhRk/3fvmhJ9pKW9PQr6Eo3BAClMMMJajDEpi3AP Tstieu5qGqGnXp+Cofte05gzjbCTiEahVmNSRkMSjZRAMgKSlY1E1sT8Cx6tFBlIUTweb83L LfVcNS2zZV2UbYuf0htYzq6Oj877u+/75wdp9dWV37I8d96Zm6/ylB3zdF6RbiMOmlV4Sifk hYbPTWDXVmIP+9WU9xDpEGtNlx9cNr+uSXQCrsoWT5moEwzqNM+m+4t57th4XrubS6RB/qt1 SCxEW6yf5Q4lxPZmH4ZB7GpSNz9ZiZijxbSYZYs5BYMZCmb1nfehE2Ao15zHPw3a9jlLUbhg SIyAQ1Qev1j6cNBjzbqDV9d6fBoM/wZtX0CHRkDa87sKuxks/iyIqyM0q+ryjrr7s2LidjrB 53LmSh63uxl3hxtbLnN3w/sW3HgDoxizWAADjGqRA061QggEWcEa8GlkbCNt8BXGCLRJOCYt FI1iGbEEvyjWkCSsRiKtBulGJlQgbwwHyxq91liFGqb5RnbSEVu5qrYJWZAZ36wxXD1iOxmh GdFkQrZouUa1TsymXrKpbCRnEratanisVtI8qTSQcLmMkHHM3G2iiP/uYzB82yl32XaatD1Z uLSRfM20PdgoarwhJbKt8DqOXf5xODj+sntQVMuiLKqLn9JKgCLAHCglKELhe07ZxG5zCrZt Vkn1LKuiB1ZpJt+GVSiifxWrno72lEj2XxFJNfgfFu8HvZN0+VD35ao/UspsKCXD/4NTfDPr RLzy/AcXw95lf/f3k7PiJl1I9fL1qvG48lSMR1mY4LkmVbSNBb2NBRuHW1gIhX0GC4ncgkJo H12w8a+CwvNTPoGEEv/9bn1hmT9gILnHQPTrMfD4XaLil4kVzFj0x2zGI/5kwsMUh1PMO23I +qUhuHRllRULkr7ZuOOtYLaaupK6+SoduitP+FL6Ap0My3S5dDNsK80rx28wMNf+JkdXCRH5 IvHx3FTybSh37l2GGaD4YAct1NvQPNiPi8mC0dqdl8599SbpxOUP1osyp+7t7a2/LNP5Teql M+dPi5udYJjV+Q9BxIf4l5vW1IW8v6qvcRosHpYu5ZPprrOSR0/6peCkmPXSet2rSGQI3aD3 qIS/Zfro7m6LEivvYj1NBSyiTdB7u/ETKjTK7gr1Rog38DsdHl35/VWeT9LFgvc8vM4qwqfd 92+0WWjoSy1NoryJq9P1MXhHiPYuj87OB58/UfeLm6hDinzj2x36ukzr68ql9O0+gfHNDh/s 30esDLAKZW5kc3RyZWFtCmVuZG9iagoyMyAwIG9iaiA8PAovVHlwZSAvWFJlZgovSW5kZXgg WzAgMjNdCi9TaXplIDIzCi9XIFsxIDIgMV0KL1Jvb3QgMjEgMCBSCi9JbmZvIDIyIDAgUgov SUQgWzw2MEZDRTRFQjExQTQzRDYxQjMxMjM4NzFBMTY3NEE1MT4gPDYwRkNFNEVCMTFBNDNE NjFCMzEyMzg3MUExNjc0QTUxPl0KL0xlbmd0aCA3MSAgICAgICAgCi9GaWx0ZXIgL0ZsYXRl RGVjb2RlCj4+CnN0cmVhbQp42hXHuQ2AQBQDUXs5lnspA4kA6qBGUgqjEpgfPNkj6UvKhqwi dkKH2vsVvSA53fErNGjdPNEZPQZvb/SIGQWrz0M/Ao4FWwplbmRzdHJlYW0KZW5kb2JqCnN0 YXJ0eHJlZgoxMjMzNQolJUVPRgo= --qDbXVdCdHGoSgWSk Content-Type: text/plain; charset=utf-8 Content-Disposition: attachment; filename=babelify Content-Transfer-Encoding: quoted-printable #!/usr/bin/perl -W # Outputs GSUB rules for replacing Babel-inputted greek characters with t= heir # Unicode value. # In Adobe Feature Language, suitable for use in Fontlab's .fea files. use strict ; use utf8 ; # Character types: breathings, accents, vowels # The void string is considered an accent for convenience with breathings my %charmask ; my $charshift =3D 8 ; my @breathings =3D ('greater', 'less') ; my @accents =3D ('', 'grave', 'quotesingle', 'asciitilde') ; my @vowels =3D ('a', 'e', 'h', 'i', 'o', 'u', 'w') ; # Unicode masks for characters with breathings $charmask{''} =3D 0 ; $charmask{'greater'} =3D 0 ; $charmask{'less'} =3D 1 ; $charmask{'grave'} =3D 2 ; $charmask{'quotesingle'} =3D 4 ; $charmask{'asciitilde'} =3D 6 ; $charmask{'a'} =3D 0x1F00 ; $charmask{'e'} =3D 0x1F10 ; $charmask{'h'} =3D 0x1F20 ; $charmask{'i'} =3D 0x1F30 ; $charmask{'o'} =3D 0x1F40 ; $charmask{'u'} =3D 0x1F50 ; $charmask{'w'} =3D 0x1F60 ; # Local variables my $breathing ; my $accent ; my $vowel ; my $uchar ; # First the U+1F00=E2=80=93U+1F6F sequence: breathing accent vowel # We compile the Unicode code points by simply ORing the mask of each ele= ment # Note that some of these characters actually don't exist! # But is was easier this way (we can always edit the output afterward) foreach $breathing (@breathings) { foreach $accent (@accents) { foreach $vowel (@vowels) { # Space cadet input scheme ;-) $uchar =3D $charmask{$breathing} | $charmask{$accent} | $charmask{$= vowel} ; printf "sub $breathing $accent $vowel by uni%04X ;\n", $uchar ; # Uppercase characters: the same shifted 8. $uchar =3D $charmask{$breathing} | $charmask{$accent} | $charmask{$vowel} | $charshift ; printf "sub $breathing $accent %s by uni%04X ;\n", uc($vowel), $uch= ar ; } } } # The U+1F7x range: lowercase vowels with only one accent. # I have no idea why Unicode decided to put them there ... (especially se= en as # the uppercase vowels are somewhere else, and in an even more clumsy # arrangement). # We have to change the masks $charmask{'grave'} =3D 0 ; $charmask{'quotesingle'} =3D 1 ; $charmask{'a'} =3D 0x1F70 ; $charmask{'e'} =3D 0x1F72 ; $charmask{'h'} =3D 0x1F74 ; $charmask{'i'} =3D 0x1F76 ; $charmask{'o'} =3D 0x1F78 ; $charmask{'u'} =3D 0x1F7A ; $charmask{'w'} =3D 0x1F7C ; foreach $vowel (@vowels) { foreach $accent ('grave', 'quotesingle') { $uchar =3D $charmask{$accent} | $charmask{$vowel} ; printf "sub $accent $vowel by uni%04X ;\n", $uchar ; } } # As announced before, the uppercase counterparts of these 14 characters = are in # a delighfully crappy mess. Simply output them one by one. print "sub grave A by uni1FBA ;\n" ; print "sub quotesingle A by uni1FBB ;\n" ; print "sub grave E by uni1FC8 ;\n" ; print "sub quotesingle E by uni1FC9 ;\n" ; print "sub grave H by uni1FCA ;\n" ; print "sub quotesingle H by uni1FCB ;\n" ; print "sub grave I by uni1FDA ;\n" ; print "sub quotesingle I by uni1FDB ;\n" ; print "sub grave U by uni1FEA ;\n" ; print "sub quotesingle U by uni1FEB ;\n" ; print "sub grave W by uni1FFA ;\n" ; print "sub quotesingle W by uni1FFB ;\n" ; # U+1F80=E2=80=93U+1FAF: characters with subscribed iotas and breathings. # We have to change the masks once again. $charmask{'grave'} =3D 2 ; $charmask{'quotesingle'} =3D 4 ; $charmask{'a'} =3D 0x1F80 ; $charmask{'h'} =3D 0x1F90 ; $charmask{'w'} =3D 0x1FA0 ; foreach $breathing (@breathings) { foreach $accent (@accents) { foreach $vowel ('a', 'h', 'w') # Only these three vowels! { $uchar =3D $charmask{$breathing} | $charmask{$accent} | $charmask{$= vowel} ; printf "sub $breathing $accent $vowel bar by uni%04X ;\n", $uchar ; # Uppercase counterparts $uchar =3D $charmask{$breathing} | $charmask{$accent} | $charmask{$vowel} | $charshift ; printf "sub $breathing $accent %s bar by uni%04X ;\n", uc($vowel), = $uchar ; } } } # And finally, the characters with subscribed iotas but without breathing= s. # Only nine of them, write them one by one. print "sub grave a bar by uni1FB2 ;\n" ; print "sub a bar by uni1FB3 ;\n" ; print "sub quotesingle a bar by uni1FB4 ;\n" ; print "sub grave h bar by uni1FC2 ;\n" ; print "sub h bar by uni1FC3 ;\n" ; print "sub quotesingle h bar by uni1FC4 ;\n" ; print "sub grave w bar by uni1FD2 ;\n" ; print "sub w bar by uni1FD3 ;\n" ; print "sub quotesingle w bar by uni1FD4 ;\n" ; # And some more with perispomeni ... print "sub asciitilde a by uni1FB6 ;\n" ; print "sub asciitilde a bar by uni1FB7 ;\n" ; print "sub asciitilde h by uni1FC6 ;\n" ; print "sub asciitilde h bar by uni1FC7 ;\n" ; print "sub asciitilde w by uni1FD6 ;\n" ; print "sub asciitilde w bar by uni1FD7 ;\n" ; # Rhos print "sub greater r by uni1FE4 ;\n" ; print "sub less r by uni1FE5 ;\n" ; print "sub less R by uni1FEC ;\n" ; # We leave some over but that should already be useful. Enjoy! --qDbXVdCdHGoSgWSk Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki! maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://tex.aanhet.net archive : https://foundry.supelec.fr/projects/contextrev/ wiki : http://contextgarden.net ___________________________________________________________________________________ --qDbXVdCdHGoSgWSk--