colored ASCII output?

Hermann O. Rodrigues hermann@dcc.ufmg.br
Mon, 10 Sep 2001 11:15:25 +0000


--------------Boundary-00=_PX1GO80YG4VDD5YS3VA4
Content-Type: text/plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

On Monday 10 September 2001 08:51, Johannes Waldmann wrote:
| I am looking for a Haskell module that would allow me
| to easily send some escape sequences that generate coloured output
| (as  ls --color  does on a linux console or on  rxvt).

=09The attached modules can be used to print colored text on a console us=
ing a=20
nicer syntax.

=09I hope this help.

-----------------------------------------------------------
      Hermann Oliveira Rodrigues - hermann@dcc.ufmg.br
               Graduated in Computer Science at
       Universidade Federal de Minas Gerais - Brazil
-----------------------------------------------------------
--------------Boundary-00=_PX1GO80YG4VDD5YS3VA4
Content-Type: text/plain;
  charset="iso-8859-1";
  name="BasicCharModes.hs"
Content-Transfer-Encoding: base64
Content-Description: Basic module used to print colored text
Content-Disposition: attachment; filename="BasicCharModes.hs"

LS0gIEJhc2ljQ2hhck1vZGVzCi0tCi0tICBBdXRob3IgOiBIZXJtYW5uIE8uIFJvZHJpZ3Vlcwot
LSAgQ3JlYXRlZDogQXByaWwgMjAwMQotLQotLSAgJElkJAotLQotLSAgQ29weXJpZ2h0IChjKSAy
MDAwIEhlcm1hbm4gTy4gUm9kcmlndWVzCi0tCi0tICBUaGlzIGZpbGUgaXMgZnJlZSBzb2Z0d2Fy
ZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQotLSAgaXQgdW5kZXIgdGhl
IHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQKLS0g
IGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhl
IExpY2Vuc2UsCi0tICBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgotLQot
LSAgVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1
c2VmdWwsIGJ1dAotLSAgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1w
bGllZCB3YXJyYW50eSBvZgotLSAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFS
VElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKLS0gIEdlbmVyYWwgUHVibGljIExpY2Vuc2Ug
Zm9yIG1vcmUgZGV0YWlscy4KLS0gCi0tLSBERVNDUklQVElPTiAtLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLS0KLS0gIFRoaXMg
bW9kdWxlIHByb3ZpZGVzIHRoZSBiYXNpYyBmdW5jdGlvbmFsaXRpZXMgdG8gYWxsb3cgY29sb3Ig
YW5kCi0tICBmb250IGZvcm1hdGluZyBkdXJpbmcgdGV4dCBwcmludGluZyBhcyBkZXNjcmliZWQg
aW4gdGhlIElTTyA2NDI5Ci0tICByZXBvcnQgYW5kIGluIHRoZSBBTlNJIHN0YW5kYXJkLgotLQot
LSAgVGhlIHVzZSBvZiB0aGUgaGlnaGVyIGxldmVsIGBDaGFyTW9kZXMnIG1vZHVsZSBpcyBwcmVm
ZXJyZWQuCi0tCi0tLSBET0NVIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLS0KLS0gIGxhbmd1YWdlOiBIYXNrZWxs
IDk4Ci0tCi0tICBBIGNhc2UgZXhhbXBsZSB0byB0ZWFjaCB0aGUgdXNpbmcgb2YgdGhlIGBCYXNp
Y0NoYXJNb2RlcycgbW9kdWxlCi0tICBpcyBwcm92aWRlZDoKLS0gIFRvIHByaW50IHRoZSB0ZXh0
ICJKZWRpIFJ1bGVzISIgdXNpbmcgYSB5ZWxsb3cgYmFja2dyb3VuZCBhbmQKLS0gIHVzaW5nIGEg
Ym9sZCBibHVlIGZvbnQgdG8gIkplZGkiIGFuZCBhbiBpdGFsaWMgZm9udCB0byAiIFJ1bGVzISIK
LS0gIGluIGFuIEFOU0kgdGVybWluYWwsIHVzZSB0aGUgZm9sbG93aW5nIGNvZGUgc2VxdWVuY2U6
Ci0tICBwdXRTdHJMbiAkICggIGRlZmF1bHQnIAotLQkgICAgICAgIC4gYmdDb2xvciBZZWxsb3cg
Ci0tICAgICAgICAgICAgICAuIGJvbGQKLS0gICAgICAgICAgICAgIC4gZmdDb2xvciBCbHVlCi0t
ICAgICAgICAgICAgICApICJKZWRpIgotLSAgICAgICAgICAgICArKwotLSAgICAgICAgICAgICAo
ICBkZWZhdWx0JwotLSAgICAgICAgICAgICAgLiBiZ0NvbG9yIFllbGxvdwotLSAgICAgICAgICAg
ICAgLiBpdGFsaWMKLS0gICAgICAgICAgICAgICkgIiBSdWxlcyEiCi0tCm1vZHVsZSBCYXNpY0No
YXJNb2RlcyAoLS0KCQkgICAgICAgLS0gIFRoZSBjaGFyYWN0ZXIgZm9ybWF0aW5nIG1vZGUuCgkJ
ICAgICAgIC0tCgkJICAgICAgIENoYXJNb2RlLAoJCSAgICAgICAtLQoJCSAgICAgICAtLSAgVGhl
IGNoYXJhY3RlciBhdHRyaWJ1dGVzLgoJCSAgICAgICAtLQoJCSAgICAgICBDaGFyQXR0cmlidXRl
ICguLiksIGF0dHJpYlRhZywKCQkgICAgICAgQ2hhckF0dHJpYnV0ZUdyb3VwLCBhdHRyaWJHcm91
cCwgYXR0cmliQ3h0LAoJCSAgICAgICAtLQoJCSAgICAgICAtLSAgVGhlIGNoYXJhY3RlciBjb2xv
cnMuCgkJICAgICAgIC0tCgkJICAgICAgIENoYXJDb2xvciAoLi4pLCBjb2xvclRhZywKCQkgICAg
ICAgLS0KCQkgICAgICAgLS0gIEVzY2FwZSBzZXF1ZW5jZSB0cmFuc2xhdGlvbi4KCQkgICAgICAg
LS0KCQkgICAgICAgQ2hhck1vZGVFc2MsIHRyYW5zTW9kZSwgYXBwTW9kZSwgcnN0TW9kZSwKCQkg
ICAgICAgLS0KCQkgICAgICAgLS0gIEF0dHJpYnV0ZSBhbmQgY29sb3IgYXBwbGljYXRpb24uCgkJ
ICAgICAgIC0tCgkJICAgICAgIGF0dHJpYiwgZmdDb2xvciwgYmdDb2xvciwKCQkgICAgICAgLS0K
CQkgICAgICAgLS0gIFByZWRlZmluZWQgYXR0cmlidXRlIGFwcGxpY2F0aW9uLgoJCSAgICAgICAt
LQoJCSAgICAgICBkZWZhdWx0JywgYm9sZCwgbm9uQm9sZCwgaXRhbGljLCB1bmRlcmxpbmUsCgkJ
ICAgICAgIGJsaW5rLCByYXBpZEJsaW5rLCByZXZlcnNlVmlkZW8sIGludmlzaWJsZSkKd2hlcmUK
CgotLSAgSGFza2VsbCBtb2R1bGUgaW1wb3J0cy4KLS0gIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
CmltcG9ydCAgTGlzdCAgKGludGVyc2VjdCkKCgotLSAgVGhlIGNoYXJhY3RlciBmb3JtYXRpbmcg
bW9kZS4KLS0gIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgotLSAgVGhlIGNoYXJhY3Rl
ciBmb3JtYXRpbmcgbW9kZSBkYXRhdHlwZSAoRVhQT1JURUQpCi0tCnR5cGUgQ2hhck1vZGUgPSAo
IFsgQ2hhckF0dHJpYnV0ZSBdCgkJLCBNYXliZSBDaGFyQ29sb3IgICAtLSAgRm9yZWdyb3VuZC4K
CQksIE1heWJlIENoYXJDb2xvciAgIC0tICBCYWNrZ3JvdW5kLgoJCSkKCgotLSAgVGhlIGNoYXJh
Y3RlciBhdHRyaWJ1dGVzLgotLSAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLS0gIFRoZSBj
aGFyYWN0ZXIgYXR0cmlidXRlIGRhdGF0eXBlIChFWFBPUlRFRCkuCi0tCmRhdGEgQ2hhckF0dHJp
YnV0ZSA9IERlZmF1bHQgICAgICAgIC0tICBBbGwgb2ZmIChFeGNlcHQgZm9yCgkJCQkgICAgLS0g
IGZvcmVncm91bmQgYW5kIGJhY2tncm91bmQgY29sb3IpLgoJCSAgIHwgSGlnaEludGVuc2l0eSAg
LS0gIEJvbGQuCgkJICAgfCBMb3dJbnRlbnNpdHkgICAtLSAgTm9ybWFsLgoJCSAgIHwgSXRhbGlj
ICAgICAgICAgLS0gIChXb3JrcyBvbmx5IG9uIHNvbWUgc3lzdGVtcykuCgkJICAgfCBVbmRlcmxp
bmUgICAgICAtLSAgVW5kZXJsaW5lZCBmb250LgoJCSAgIHwgQmxpbmsgICAgICAgICAgLS0gIEJs
aW5raW5nIGZvbnQuCgkJICAgfCBSYXBpZEJsaW5rICAgICAtLSAgKFdvcmtzIG9ubHkgb24gc29t
ZSBzeXN0ZW1zKS4KCQkgICB8IFJldmVyc2VWaWRlbyAgIC0tICBTd2FwcyB0aGUgZm9yZWdyb3Vu
ZCBhbmQgdGhlCgkJCQkgICAgLS0gIGJhY2tncm91bmQgY29sb3IuCgkJICAgfCBJbnZpc2libGUg
ICAgICAtLSAgRG8gbm90IGRpc3BsYXkgY2hhcmFjdGVycy4KICAgICAgICAgICAgICAgICAgIGRl
cml2aW5nIChFcSkKCgotLSAgUmV0dXJucyB0aGUgaW50ZXJuYWwgdGFnIG9mIHRoZSBnaXZlbiBh
dHRyaWJ1dGUgKEVYUE9SVEVEKS4KLS0KYXR0cmliVGFnIDo6IENoYXJBdHRyaWJ1dGUKCSAgLT4g
SW50CmF0dHJpYlRhZyBEZWZhdWx0ICAgICAgID0gMAphdHRyaWJUYWcgSGlnaEludGVuc2l0eSA9
IDEKYXR0cmliVGFnIExvd0ludGVuc2l0eSAgPSAyCmF0dHJpYlRhZyBJdGFsaWMgICAgICAgID0g
MwphdHRyaWJUYWcgVW5kZXJsaW5lICAgICA9IDQKYXR0cmliVGFnIEJsaW5rICAgICAgICAgPSA1
CmF0dHJpYlRhZyBSYXBpZEJsaW5rICAgID0gNgphdHRyaWJUYWcgUmV2ZXJzZVZpZGVvICA9IDcK
YXR0cmliVGFnIEludmlzaWJsZSAgICAgPSA4CgoKLS0gIFRoZSBhdHRyaWJ1dGUgZ3JvdXAgdHlw
ZSAoRVhQT1JURUQpLgotLQp0eXBlIENoYXJBdHRyaWJ1dGVHcm91cCA9IEludAoKCi0tICBSZXR1
cm5zIHRoZSBncm91cHMgb2YgdGhlIGdpdmVuIGF0dHJpYnV0ZSAoRVhQT1JURUQpLgotLQotLSAg
KiBBdHRyaWJ1dGVzIG9mIHRoZSBzYW1lIGdyb3VwIHNldC91bnNldCB0aGUgYmVoYXZpb3VyIHRv
IHRoZSBzYW1lCi0tICAgIGZ1bmN0aW9uYWxpdHkuCi0tCmF0dHJpYkdyb3VwIDo6IENoYXJBdHRy
aWJ1dGUKCSAgICAtPiBbQ2hhckF0dHJpYnV0ZUdyb3VwXQphdHRyaWJHcm91cCBEZWZhdWx0ICAg
ICAgID0gWzEsIDIsIDMsIDQsIDVdCmF0dHJpYkdyb3VwIEhpZ2hJbnRlbnNpdHkgPSBbMV0KYXR0
cmliR3JvdXAgTG93SW50ZW5zaXR5ICA9IFsxXQphdHRyaWJHcm91cCBJdGFsaWMgICAgICAgID0g
WzJdCmF0dHJpYkdyb3VwIFVuZGVybGluZSAgICAgPSBbM10KYXR0cmliR3JvdXAgQmxpbmsgICAg
ICAgICA9IFs0XQphdHRyaWJHcm91cCBSYXBpZEJsaW5rICAgID0gWzRdCmF0dHJpYkdyb3VwIFJl
dmVyc2VWaWRlbyAgPSBbNV0KYXR0cmliR3JvdXAgSW52aXNpYmxlICAgICA9IFsxLCAyLCAzLCA0
LCA1XQoKCi0tICBBbmFsaXplcyB3aGljaCBhdHRyaWJ1dGVzIGluIHRoZSBmaXJzdCBhdHRyaWJ1
dGUgbGlzdCBjYW4gYmUgdXNlZAotLSAgaW4gdGhlIGNvbnRleHQgb2YgdGhlIHNlY29uZCBvbmUg
KEVYUE9SVEVEKS4KLS0KLS0gICogUmV0dXJucyB0aGUgYXR0cmlidXRlIGNvbnRleHQgaW5jbHVk
aW5nIHRoZSBzZWxlY3RlZCBhdHRyaWJ1dGVzCi0tICAgIGluIHRoZSBnaXZlbiBhdHRyaWJ1dGUg
bGlzdC4KLS0KYXR0cmliQ3h0IDo6IFtDaGFyQXR0cmlidXRlXQogICAgICAgICAgLT4gW0NoYXJB
dHRyaWJ1dGVdCiAgICAgICAgICAtPiBbQ2hhckF0dHJpYnV0ZV0KYXR0cmliQ3h0IFtdICAgICAg
ICAgICAgICAgIGF0dHJpYmwnID0gYXR0cmlibCcKYXR0cmliQ3h0IChhdHRyaWIwOmF0dHJpYmwp
IGF0dHJpYmwnID0KICAgIGxldCBhZ2wgID0gYXR0cmliR3JvdXAgYXR0cmliMAogICAgICAgIGFn
bCcgPSAoY29uY2F0IC4gbWFwIGF0dHJpYkdyb3VwKSBhdHRyaWJsJwogICAgICAgIHNlYyAgPSBh
Z2wgYGludGVyc2VjdGAgYWdsJwogICAgIGluIGlmIHNlYyA9PSBbXQogICAgICAgIHRoZW4gYXR0
cmliQ3h0IGF0dHJpYmwgKGF0dHJpYjA6YXR0cmlibCcpCiAgICAgICAgZWxzZSBhdHRyaWJDeHQg
YXR0cmlibCAgICAgICAgICBhdHRyaWJsJwoKCi0tICBUaGUgY2hhcmFjdGVyIGNvbG9ycy4KLS0g
IC0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLS0gIFRoZSBjaGFyYWN0ZXIgY29sb3IgZGF0YXR5cGUg
KEVYUE9SVEVEKS4KLS0KZGF0YSBDaGFyQ29sb3IgPSBCbGFjayAgfCBSZWQgICAgIHwgR3JlZW4g
ICB8IFllbGxvdwoJICAgICAgIHwgQmx1ZSAgIHwgTWFnZW50YSB8IEN5YW4gICAgfCBXaGl0ZQoK
Ci0tICBSZXR1cm5zIHRoZSBpbnRlcm5hbCB0YWcgb2YgdGhlIGdpdmVuIGNvbG9yIChFWFBPUlRF
RCkuCi0tCmNvbG9yVGFnIDo6IEJvb2wgICAgICB7LSBJcyBpdCBhIGZvcmVncm91bmQgY29sb3I/
IC19CgkgLT4gQ2hhckNvbG9yCgkgLT4gSW50CmNvbG9yVGFnIFRydWUgIGNvbG9yID0gY29sb3JU
YWcnIGNvbG9yCmNvbG9yVGFnIEZhbHNlIGNvbG9yID0gY29sb3JUYWcnIGNvbG9yICsgMTAKCmNv
bG9yVGFnJyBCbGFjayAgID0gMzAKY29sb3JUYWcnIFJlZCAgICAgPSAzMQpjb2xvclRhZycgR3Jl
ZW4gICA9IDMyCmNvbG9yVGFnJyBZZWxsb3cgID0gMzMKY29sb3JUYWcnIEJsdWUgICAgPSAzNApj
b2xvclRhZycgTWFnZW50YSA9IDM1CmNvbG9yVGFnJyBDeWFuICAgID0gMzYKY29sb3JUYWcnIFdo
aXRlICAgPSAzNwoKCi0tICBFc2NhcGUgc2VxdWVuY2UgdHJhbnNsYXRpb24uCi0tICAtLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tCgotLSAgVGhlIGNoYXJhY3RlciBlc2NhcGUgc2VxdWVuY2Ug
dHlwZSAoRVhQT1JURUQpLgotLQp0eXBlIENoYXJNb2RlRXNjID0gU3RyaW5nCgoKLS0gIFRoZSAo
RSlzY2FwZSAoUyllcXVlbmNlIChTKXRhcnQvKEUpbmQgc3RyaW5nIGFuZCB0aGUgKEEpdHRyaWJ1
dGUKLS0gIChTKWVwYXJhdG9yIHN0cmluZy4KLS0KZXNzLCBlc2UsIGFzIDo6IFN0cmluZwplc3Mg
PSAiXG8zM1siCmVzZSA9ICJtIgphcyAgPSAiOyIKCgotLSAgVHJhbnNsYXRlIHRoZSBnaXZlbiBj
aGFyYWN0ZXIgbW9kZSBpbiB0aGUgZXF1aXZhbGVudCBlc2NhcGUKLS0gIHNlcXVlbmNlIChFWFBP
UlRFRCkuCi0tCnRyYW5zTW9kZSA6OiBDaGFyTW9kZQoJICAtPiBDaGFyTW9kZUVzYwp0cmFuc01v
ZGUgKFtdICAgICAsIE5vdGhpbmcgICwgTm90aGluZyAgKSA9ICIiCnRyYW5zTW9kZSAoW10gICAg
ICwgTm90aGluZyAgLCBKdXN0IGNvbDIpID0KICAgIGVzcyArKyB0cmFuc0JnQ29sb3IgY29sMiAg
ICArKyBlc2UKdHJhbnNNb2RlIChbXSAgICAgLCBKdXN0IGNvbDEsIE5vdGhpbmcgICkgPQogICAg
ZXNzICsrIHRyYW5zRmdDb2xvciBjb2wxICAgICsrIGVzZQp0cmFuc01vZGUgKFtdICAgICAsIEp1
c3QgY29sMSwgSnVzdCBjb2wyKSA9CiAgICBlc3MgKysgdHJhbnNGZ0NvbG9yIGNvbDEgICAgKysK
ICAgIGFzICArKyB0cmFuc0JnQ29sb3IgY29sMiAgICArKyBlc2UKdHJhbnNNb2RlIChhdHRyaWJs
LCBOb3RoaW5nICAsIE5vdGhpbmcgICkgPQogICAgZXNzICsrIHRyYW5zQXR0cmlibCBhdHRyaWJs
ICsrIGVzZQp0cmFuc01vZGUgKGF0dHJpYmwsIE5vdGhpbmcgICwgSnVzdCBjb2wyKSA9CiAgICBl
c3MgKysgdHJhbnNBdHRyaWJsIGF0dHJpYmwgKysKICAgIGFzICArKyB0cmFuc0JnQ29sb3IgY29s
MiAgICArKyBlc2UKdHJhbnNNb2RlIChhdHRyaWJsLCBKdXN0IGNvbDEsIE5vdGhpbmcgICkgPQog
ICAgZXNzICsrIHRyYW5zQXR0cmlibCBhdHRyaWJsICsrCiAgICBhcyAgKysgdHJhbnNGZ0NvbG9y
IGNvbDEgICAgKysgZXNlCnRyYW5zTW9kZSAoYXR0cmlibCwgSnVzdCBjb2wxLCBKdXN0IGNvbDIp
ID0KICAgIGVzcyArKyB0cmFuc0F0dHJpYmwgYXR0cmlibCArKwogICAgYXMgICsrIHRyYW5zRmdD
b2xvciBjb2wxICAgICsrCiAgICBhcyAgKysgdHJhbnNCZ0NvbG9yIGNvbDIgICAgKysgZXNlCgp0
cmFuc0F0dHJpYmwgOjogWyBDaGFyQXR0cmlidXRlIF0KCSAgICAgLT4gQ2hhck1vZGVFc2MgICAg
ICAgICAgICAgICB7LSBiYWQgc2lnbmF0dXJlPyAtfQp0cmFuc0F0dHJpYmwgW10gICAgICAgICA9
ICIiCnRyYW5zQXR0cmlibCBbYXR0cmliXSAgID0gc2hvdyAoYXR0cmliVGFnIGF0dHJpYikKdHJh
bnNBdHRyaWJsIChhdHRyaWI6bCkgPSBzaG93IChhdHRyaWJUYWcgYXR0cmliKQoJCQkgICsrIGFz
ICsrCgkJCSAgdHJhbnNBdHRyaWJsIGwKCnRyYW5zRmdDb2xvciwgdHJhbnNCZ0NvbG9yIDo6IENo
YXJDb2xvcgoJCQkgICAtPiBDaGFyTW9kZUVzYyB7LSBiYWQgc2lnbmF0dXJlPyAtfQp0cmFuc0Zn
Q29sb3IgPSBzaG93IC4gY29sb3JUYWcgVHJ1ZQp0cmFuc0JnQ29sb3IgPSBzaG93IC4gY29sb3JU
YWcgRmFsc2UKCgotLSAgQXBwbGllcyB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGZvcm1hdGluZyBtb2Rl
IHRvIHRoZSBnaXZlbiBzdHJpbmcKLS0gIChFWFBPUlRFRCkuCi0tCmFwcE1vZGUgOjogQ2hhck1v
ZGUKCS0+IFN0cmluZwoJLT4gU3RyaW5nCmFwcE1vZGUgPSAoKyspIC4gdHJhbnNNb2RlCgoKLS0g
IEF0dHJpYnV0ZSBhbmQgY29sb3IgYXBwbGljYXRpb24uCi0tICAtLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLQoKLS0gIEFwcGxpZXMgdGhlIGdpdmVuIGNoYXJhY3RlciBhdHRyaWJ1dGUg
bGlzdCB0byB0aGUgZ2l2ZW4gc3RyaW5nCi0tICAoRVhQT1JURUQpLgotLQphdHRyaWIgOjogW0No
YXJBdHRyaWJ1dGVdCiAgICAgICAtPiBTdHJpbmcKICAgICAgIC0+IFN0cmluZwphdHRyaWIgYXR0
cmlibCA9IGFwcE1vZGUgKGF0dHJpYkN4dCBhdHRyaWJsIFtdLCBOb3RoaW5nLCBOb3RoaW5nKQoK
Ci0tICBDb2xvdXJzIHRoZSBnaXZlbiBzdHJpbmcgdXNpbmcgdGhlIGdpdmVuIGZvcmVncm91bmQg
Y29sb3IKLS0gIChFWFBPUlRFRCkuCi0tCmZnQ29sb3IgOjogQ2hhckNvbG9yIAoJLT4gU3RyaW5n
CgktPiBTdHJpbmcKZmdDb2xvciBjb2wgPSBhcHBNb2RlIChbXSwgSnVzdCBjb2wsIE5vdGhpbmcp
CgoKLS0gIENvbG91cnMgdGhlIGdpdmVuIHN0cmluZyB1c2luZyB0aGUgZ2l2ZW4gYmFja2dyb3Vu
ZCBjb2xvcgotLSAgKEVYUE9SVEVEKS4KYmdDb2xvciA6OiBDaGFyQ29sb3IKCS0+IFN0cmluZwoJ
LT4gU3RyaW5nCmJnQ29sb3IgY29sID0gYXBwTW9kZSAoW10sIE5vdGhpbmcsIEp1c3QgY29sKQoK
Ci0tICBQcmVkZWZpbmVkIGF0dHJpYnV0ZSBhcHBsaWNhdGlvbi4KLS0gIC0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLQoKLS0gIFJlc2V0IHRoZSBjaGFyYWN0ZXIgZm9ybWF0aW5nIG1v
ZGVzLgotLQpyc3RNb2RlIDo6IFN0cmluZwpyc3RNb2RlID0gdHJhbnNNb2RlIChbRGVmYXVsdF0s
IE5vdGhpbmcsIE5vdGhpbmcpCgoKLS0gIEFwcGxpZXMgdGhlIGdpdmVuIHByZWRlZmluZWQgYXR0
cmlidXRlIHRvIHRoZSBnaXZlbiBzdHJpbmcKLS0gIChFWFBPUlRFRCkuCi0tCmRlZmF1bHQnLCBi
b2xkLCBub25Cb2xkLCBpdGFsaWMsIHVuZGVybGluZSwgYmxpbmssIHJhcGlkQmxpbmssCiAgICAg
ICByZXZlcnNlVmlkZW8sIGludmlzaWJsZSA6OiBTdHJpbmcKCQkJICAgICAgIC0+IFN0cmluZwpi
b2xkICAgICAgICAgPSBhdHRyaWIgW0hpZ2hJbnRlbnNpdHldCm5vbkJvbGQgICAgICA9IGF0dHJp
YiBbTG93SW50ZW5zaXR5IF0KaXRhbGljICAgICAgID0gYXR0cmliIFtJdGFsaWMgICAgICAgXQp1
bmRlcmxpbmUgICAgPSBhdHRyaWIgW1VuZGVybGluZSAgICBdCmJsaW5rICAgICAgICA9IGF0dHJp
YiBbQmxpbmsgICAgICAgIF0KcmFwaWRCbGluayAgID0gYXR0cmliIFtSYXBpZEJsaW5rICAgXQpy
ZXZlcnNlVmlkZW8gPSBhdHRyaWIgW1JldmVyc2VWaWRlbyBdCmludmlzaWJsZSAgICA9IGF0dHJp
YiBbSW52aXNpYmxlICAgIF0KLS0KLS0gIGBkZWZhdWx0JycgYmVoYXZlcyBhIGxpdHRsZSBkaWZm
ZXJlbnQgZnJvbSB0aGUgb3RoZXJzIHByZWRlZmluZWQKLS0gIGF0dHJpYnV0ZSBhcHBsaWVyczog
T25seSB0aGUgc3Vic2VxdWVudCBzdHJpbmdzIGFyZSBhZmZlY3RlZCBieQotLSAgdGhlIGF0dHJp
YnV0ZSBjaGFuZ2VzLgotLQpkZWZhdWx0JyAgICAgPSAoKysgcnN0TW9kZSkK

--------------Boundary-00=_PX1GO80YG4VDD5YS3VA4
Content-Type: text/plain;
  charset="iso-8859-1";
  name="CharModes.hs"
Content-Transfer-Encoding: base64
Content-Description: Higher level module to print colored text
Content-Disposition: attachment; filename="CharModes.hs"

LS0gIENoYXJNb2RlcwotLQotLSAgQXV0aG9yIDogSGVybWFubiBPLiBSb2RyaWd1ZXMKLS0gIENy
ZWF0ZWQ6IEFwcmlsIDIwMDEKLS0KLS0gICRJZCQKLS0KLS0gIENvcHlyaWdodCAoYykgMjAwMCBI
ZXJtYW5uIE8uIFJvZHJpZ3VlcwotLQotLSAgVGhpcyBmaWxlIGlzIGZyZWUgc29mdHdhcmU7IHlv
dSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKLS0gIGl0IHVuZGVyIHRoZSB0ZXJt
cyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkCi0tICBieSB0
aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNl
bnNlLAotLSAgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KLS0KLS0gIFRo
aXMgZmlsZSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVs
LCBidXQKLS0gIFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQg
d2FycmFudHkgb2YKLS0gIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VM
QVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCi0tICBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBt
b3JlIGRldGFpbHMuCi0tIAotLS0gREVTQ1JJUFRJT04gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi0tCi0tICBUaGlzIG1vZHVs
ZSBwcm92aWRlcyBoaWdoZXIgbGV2ZWwgZnVuY3Rpb25hbGl0aWVzIHRvIGFsbG93IGNvbG9yCi0t
ICBhbmQgZm9udCBmb3JtYXRpbmcgZHVyaW5nIHRleHQgcHJpbnRpbmcgYXMgZGVzY3JpYmVkIGlu
IHRoZSBJU08KLS0gIDY0MjkgcmVwb3J0IGFuZCBpbiB0aGUgQU5TSSBzdGFuZGFyZC4gCi0tCi0t
LSBET0NVIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0KLS0KLS0gIGxhbmd1YWdlOiBIYXNrZWxsIDk4Ci0tCi0tICBB
IGNhc2UgZXhhbXBsZSB0byB0ZWFjaCB0aGUgdXNpbmcgb2YgdGhlIGBDaGFyTW9kZXMnIG1vZHVs
ZSBpcwotLSAgcHJvdmlkZWQ6Ci0tICBUbyBwcmludCB0aGUgdGV4dCAiSmVkaSBSdWxlcyEiIHVz
aW5nIGEgeWVsbG93IGJhY2tncm91bmQgYW5kCi0tICB1c2luZyBhIGJvbGQgYmx1ZSBmb250IHRv
ICJKZWRpIiBhbmQgYW4gaXRhbGljIGZvbnQgdG8gIiBSdWxlcyEiCi0tICBpbiBhbiBBTlNJIHRl
cm1pbmFsLCB1c2UgdGhlIGZvbGxvd2luZyBjb2RlIHNlcXVlbmNlOgotLSAgKCAgcHV0U3RyTG4K
LS0gICAuIHNob3cKLS0gICApICQgKCAgYmdDb2xvciBZZWxsb3cKLS0gICAgICAgIC4gYm9sZAot
LSAgICAgICAgLiBmZ0NvbG9yIEJsdWUKLS0gICAgICAgIC4gY21UeHQKLS0gICAgICAgICkgIkpl
ZGkiCi0tICAgICAgICsrKwotLSAgICAgICAoICBiZ0NvbG9yIFllbGxvdwotLSAgICAgICAgLiBp
dGFsaWMKLS0gICAgICAgIC4gY21UeHQKLS0gICAgICAgICkgIiBSdWxlcyEiCi0tCi0tICBUaGUg
Y29kZSBzZXF1ZW5jZSBiZWxvdyBpcyBwcmVmZXJyZWQgKGFuZCBzaG9ydGVyKTogCi0tICBwdXRT
dHJMbiAkICggIHNob3cKLS0gICAgICAgICAgICAgIC4gYmdDb2xvciBZZWxsb3cKLS0gICAgICAg
ICAgICAgICkgJCAoICBib2xkIAotLSAgICAgICAgICAgICAgICAgICAuIGZnQ29sb3IgQmx1ZQot
LSAgICAgICAgICAgICAgICAgICAuIGNtVHh0Ci0tICAgICAgICAgICAgICAgICAgICkgIkplZGki
Ci0tICAgICAgICAgICAgICAgICAgKysrCi0tICAgICAgICAgICAgICAgICAgKCAgaXRhbGljCi0t
ICAgICAgICAgICAgICAgICAgIC4gY21UeHQKLS0gICAgICAgICAgICAgICAgICAgKSAiIFJ1bGVz
ISIKLS0KbW9kdWxlIENoYXJNb2RlcyAoLS0KCQkgIC0tICBUaGUgY2hhcmFjdGVyIGZvcm1hdGlu
ZyBtb2RlLgoJCSAgLS0KCQkgIENoYXJNb2RlLAoJCSAgLS0KCQkgIC0tICBUaGUgY2hhcmFjdGVy
IGF0dHJpYnV0ZXMuCgkJICAtLQoJCSAgQ2hhckF0dHJpYnV0ZSAoLi4pLAoJCSAgLS0KCQkgIC0t
ICBUaGUgY2hhcmFjdGVyIGNvbG9ycy4KCQkgIC0tCgkJICBDaGFyQ29sb3IgKC4uKSwKCQkgIC0t
CgkJICAtLSAgVGhlIChDKWhhcmFjdGVyIChNKW9kZSBUZXh0LgoJCSAgLS0KCQkgIENNVGV4dCwg
Y21UeHRNb2RlLCBjbVR4dCwgKCsrKyksCgkJICAtLQoJCSAgLS0gIEF0dHJpYnV0ZSBhbmQgY29s
b3IgYXBwbGljYXRpb24uCgkJICAtLQoJCSAgYXR0cmliLCBmZ0NvbG9yLCBiZ0NvbG9yLAoJCSAg
LS0KCQkgIC0tICBQcmVkZWZpbmVkIGF0dHJpYnV0ZSBhcHBsaWNhdGlvbi4KCQkgIC0tCgkJICBk
ZWZhdWx0JywgYm9sZCwgbm9uQm9sZCwgaXRhbGljLCB1bmRlcmxpbmUsIGJsaW5rLAoJCSAgcmFw
aWRCbGluaywgcmV2ZXJzZVZpZGVvLCBpbnZpc2libGUpCndoZXJlCgoKLS0gIEplZGkgbW9kdWxl
IGltcG9ydHMuCi0tICAtLS0tLS0tLS0tLS0tLS0tLS0tLQppbXBvcnQgICAgICAgICAgIEJhc2lj
Q2hhck1vZGVzIChDaGFyTW9kZSwgQ2hhckF0dHJpYnV0ZSAoLi4pLAoJCQkJIENoYXJBdHRyaWJ1
dGVHcm91cCwgYXR0cmliR3JvdXAsCgkJCQkgYXR0cmliQ3h0LCBDaGFyQ29sb3IgKC4uKSwgYXBw
TW9kZSwKCQkJCSB0cmFuc01vZGUpCmltcG9ydCBxdWFsaWZpZWQgQmFzaWNDaGFyTW9kZXMgKGRl
ZmF1bHQnKQoKCi0tICBUaGUgKEMpaGFyYWN0ZXIgKE0pb2RlIFRleHQuCi0tICAtLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tCgotLSAgVGhlIChDKWhhcmFjdGVyIChNKW9kZSBUZXh0IGRhdGF0
eXBlIChFWFBPUlRFRCBBQlNUUkFDVExZKS4KLS0KZGF0YSBDTVRleHQgPSAtLQoJICAgICAgLS0g
IEFkamFjZW50IGBDTVRleHQncy4KCSAgICAgIC0tCgkgICAgICBDTVRleHRDb25jCiAgICAgICAg
ICAgICAgQ01UZXh0CiAgICAgICAgICAgICAgQ01UZXh0CiAgICAgICAgICAgICAgLS0KICAgICAg
ICAgICAgICAtLSAgQXBwbGljYXRpb24gb2YgYSBgQ2hhck1vZGUnIHRvIGEgc3RyaW5nLgoJICAg
ICAgLS0KICAgICAgICAgICAgfCBDTVRleHQKICAgICAgICAgICAgICBDaGFyTW9kZQogICAgICAg
ICAgICAgIFN0cmluZwoKCi0tICBDb25zdHJ1Y3RzIGEgYENNVGV4dCcgdXNpbmcgdGhlIGdpdmVu
IGBDaGFyTW9kZScgYW5kIHRoZSBnaXZlbgotLSAgc3RyaW5nIChFWFBPUlRFRCkuCi0tCmNtVHh0
TW9kZSA6OiBDaGFyTW9kZQoJICAtPiBTdHJpbmcKCSAgLT4gQ01UZXh0CmNtVHh0TW9kZSA9IENN
VGV4dAoKCi0tICBDb25zdHJ1Y3RzIGEgYENNVGV4dCcgdXNpbmcgdGhlIGdpdmVuIHN0cmluZyAo
RVhQT1JURUQpLgotLQotLSAgKiBUaGUgcmVzdWx0aW5nIGBDTVRleHQnIGhhcyBubyBkZWZpbmVk
IGF0dHJpYnV0ZSBvciBjb2xvci4KLS0KY21UeHQgOjogU3RyaW5nCiAgICAgIC0+IENNVGV4dApj
bVR4dCA9IGNtVHh0TW9kZSAoW10sIE5vdGhpbmcsIE5vdGhpbmcpCgoKLS0gIEpvaW5zIHRoZSBn
aXZlbiBgQ01UZXh0J3MgKEVYUE9SVEVEKS4KLS0KaW5maXhyIDUgKysrCigrKyspIDo6IENNVGV4
dAogICAgICAtPiBDTVRleHQKICAgICAgLT4gQ01UZXh0CigrKyspID0gQ01UZXh0Q29uYwoKCi0t
ICBgQ01UZXh0JyB0byBzdHJpbmcgdHJhbnNsYXRpb24uCi0tICAtLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tCgppbnN0YW5jZSBTaG93IENNVGV4dCB3aGVyZQogICAgc2hvd3NQcmVjIF8g
PSBzaG93cycKCgotLSAgVHJhbnNsYXRlIHRoZSBnaXZlbiBgQ01UZXh0JyB0byB0aGUgZXF1aXZh
bGVudCBzdHJpbmcuCi0tCnNob3dzJyA6OiBDTVRleHQKICAgICAgIC0+IFNob3dTCnNob3dzJyAo
Q01UZXh0Q29uYyBjbXR4dDEgY210eHQyKSA9CiAgICAgIHNob3dzIGNtdHh0MQogICAgLiBzaG93
cyBjbXR4dDIKc2hvd3MnIChDTVRleHQgY20gcykgPQogICAgKCAgc2hvd1N0cmluZwogICAgIC4g
QmFzaWNDaGFyTW9kZXMuZGVmYXVsdCcKICAgICAuIGFwcE1vZGUgY20KICAgICApIHMKCgotLSAg
QXR0cmlidXRlIGFuZCBjb2xvciBhcHBsaWNhdGlvbi4KLS0gIC0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tCgotLSAgQXBwbGllcyB0aGUgZ2l2ZW4gY2hhcmFjdGVyIGF0dHJpYnV0ZSBs
aXN0IHRvIHRoZSBnaXZlbiBgQ01UZXh0JwotLSAgKEVYUE9SVEVEKS4KLS0KLS0gICogVGhpcyBo
YXMgbm8gZWZmZWN0IGlmIHRoZSBnaXZlbiBgQ01UZXh0JyBhdHRyaWJ1dGVzIGJlbG9uZyB0bwot
LSAgICB0aGUgYXR0cmlidXRlIGdyb3VwIG9mIHRoZSBhdHRyaWJ1dGVzIGluIHVzZS4KLS0KYXR0
cmliIDo6IFtDaGFyQXR0cmlidXRlXQogICAgICAgLT4gQ01UZXh0CiAgICAgICAtPiBDTVRleHQK
YXR0cmliIGF0dHJpYmwgY210eHRAKENNVGV4dCAoYXR0cmlibCcsIG1jb2wxLCBtY29sMikgcykg
PQogICAgbGV0IGF0dHJpYmwnJyA9IGF0dHJpYkN4dCBhdHRyaWJsIGF0dHJpYmwnCiAgICAgaW4g
aWYgYXR0cmlibCcnID09IGF0dHJpYmwnCiAgICAgICAgdGhlbiBjbXR4dAogICAgICAgIGVsc2Ug
Q01UZXh0CiAgICAgICAgICAgICAoYXR0cmlibCcnLCBtY29sMSwgbWNvbDIpCiAgICAgICAgICAg
ICBzCmF0dHJpYiBhdHRyaWJsIChDTVRleHRDb25jIGNtdHh0MSBjbXR4dDIpID0KICAgIENNVGV4
dENvbmMKICAgIChhdHRyaWIgYXR0cmlibCBjbXR4dDEpCiAgICAoYXR0cmliIGF0dHJpYmwgY210
eHQyKQoKCi0tICBDb2xvdXJzIHRoZSBnaXZlbiBgQ01UZXh0JyB1c2luZyB0aGUgZ2l2ZW4gZm9y
ZWdyb3VuZCBjb2xvcgotLSAgKEVYUE9SVEVEKS4KLS0KLS0gICogVGhpcyBoYXMgbm8gZWZmZWN0
IGlmIHRoZSBgQ01UZXh0JyBmb3JlZ3JvdW5kIGNvbG9yIGlzIGFscmVhZHkKLS0gICAgZGVmaW5l
ZC4KLS0KZmdDb2xvciA6OiBDaGFyQ29sb3IKCS0+IENNVGV4dAoJLT4gQ01UZXh0CmZnQ29sb3Ig
Y29sIGNtdHh0QChDTVRleHQgKGF0dHJpYmwsIG1jb2wxLCBtY29sMikgcykgPQogICAgY2FzZSBt
Y29sMSBvZgogICAgIE5vdGhpbmcgLT4gQ01UZXh0CiAgICAgICAgICAgICAgICAoYXR0cmlibCwg
SnVzdCBjb2wsIG1jb2wyKQogICAgICAgICAgICAgICAgcwogICAgIF8gICAgICAgLT4gY210eHQK
ZmdDb2xvciBjb2wgKENNVGV4dENvbmMgY210eHQxIGNtdHh0MikgPQogICAgQ01UZXh0Q29uYwog
ICAgKGZnQ29sb3IgY29sIGNtdHh0MSkKICAgIChmZ0NvbG9yIGNvbCBjbXR4dDIpCgoKLS0gIENv
bG91cnMgdGhlIGdpdmVuIGBDTVRleHQnIHVzaW5nIHRoZSBnaXZlbiBiYWNrZ3JvdW5kIGNvbG9y
Ci0tICAoRVhQT1JURUQpLgotLQotLSAgKiBUaGlzIGhhcyBubyBlZmZlY3QgaWYgdGhlIGBDTVRl
eHQnIGJhY2tncm91bmQgY29sb3IgaXMgYWxyZWFkeQotLSAgICBkZWZpbmVkLgotLQpiZ0NvbG9y
IDo6IENoYXJDb2xvcgoJLT4gQ01UZXh0CgktPiBDTVRleHQKYmdDb2xvciBjb2wgY210eHRAKENN
VGV4dCAoYXR0cmlibCwgbWNvbDEsIG1jb2wyKSBzKSA9CiAgICBjYXNlIG1jb2wyIG9mCiAgICAg
Tm90aGluZyAtPiBDTVRleHQKICAgICAgICAgICAgICAgIChhdHRyaWJsLCBtY29sMSwgSnVzdCBj
b2wpCiAgICAgICAgICAgICAgICBzCiAgICAgXyAgICAgICAtPiBjbXR4dApiZ0NvbG9yIGNvbCAo
Q01UZXh0Q29uYyBjbXR4dDEgY210eHQyKSA9CiAgICBDTVRleHRDb25jCiAgICAoYmdDb2xvciBj
b2wgY210eHQxKQogICAgKGJnQ29sb3IgY29sIGNtdHh0MikKCgotLSAgUHJlZGVmaW5lZCBhdHRy
aWJ1dGUgYXBwbGljYXRpb24uCi0tICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0K
Ci0tICBBcHBsaWVzIHRoZSBnaXZlbiBwcmVkZWZpbmVkIGF0dHJpYnV0ZSB0byB0aGUgZ2l2ZW4g
YENNVGV4dCcKLS0gIChFWFBPUlRFRCkuCi0tCmRlZmF1bHQnLCBib2xkLCBub25Cb2xkLCBpdGFs
aWMsIHVuZGVybGluZSwgYmxpbmssIHJhcGlkQmxpbmssCiAgICAgICByZXZlcnNlVmlkZW8sIGlu
dmlzaWJsZSA6OiBDTVRleHQKCQkJICAgICAgIC0+IENNVGV4dApkZWZhdWx0JyAgICAgPSBhdHRy
aWIgW0RlZmF1bHQgICAgICBdCmJvbGQgICAgICAgICA9IGF0dHJpYiBbSGlnaEludGVuc2l0eV0K
bm9uQm9sZCAgICAgID0gYXR0cmliIFtMb3dJbnRlbnNpdHkgXQppdGFsaWMgICAgICAgPSBhdHRy
aWIgW0l0YWxpYyAgICAgICBdCnVuZGVybGluZSAgICA9IGF0dHJpYiBbVW5kZXJsaW5lICAgIF0K
YmxpbmsgICAgICAgID0gYXR0cmliIFtCbGluayAgICAgICAgXQpyYXBpZEJsaW5rICAgPSBhdHRy
aWIgW1JhcGlkQmxpbmsgICBdCnJldmVyc2VWaWRlbyA9IGF0dHJpYiBbUmV2ZXJzZVZpZGVvIF0K
aW52aXNpYmxlICAgID0gYXR0cmliIFtJbnZpc2libGUgICAgXQoK

--------------Boundary-00=_PX1GO80YG4VDD5YS3VA4--