diff -Naurd ../nethack-3.3.1/win/Qt/Install.Qt ./win/Qt/Install.Qt
--- ../nethack-3.3.1/win/Qt/Install.Qt Thu Aug 3 21:54:13 2000
+++ ./win/Qt/Install.Qt Fri Mar 22 14:40:55 2002
@@ -2,12 +2,12 @@
 ---------------------------------------------
 
 This document describes the installation of NetHack with a Qt interface
-on X11.  The Qt interface is an alternative to the Athena-widgets interface
-found in ../X11.  You can download Qt for UNIX from http://www.troll.no.
-You need Qt 2.0 or later to use this code.
+on UNIX/X11 or Mac OS X. This code should also work with Qt/Windows, but
+support for that is not currently official.
 
-There are no explicit UNIX dependencies in this code, but we only regularly
-test it under UNIX.  If you have Qt for Windows, that should also work.
+You can download Qt for UNIX and Qt for Windows from http://www.trolltech.com.
+Qt for Mac OS X is currently only available commercially.  You need Qt 2.0 or
+later to use this code.
 
 To use this code:
 
@@ -36,8 +36,10 @@
 
    4. ../../Makefile (the top-level makefile)
 
-        change the VARDATND setting to contain the files "x11tiles"
-        and "rip.xpm".
+        change the VARDATND setting to contain the files "x11tiles",
+        "rip.xpm", and "nhsplash.xpm":
+
+            VARDATND = x11tiles rip.xpm nhsplash.xpm
 
    5. Follow all the instructions in ../../sys/unix/Install.unx for
       the remainder of the installation process.
@@ -46,7 +48,7 @@
       likely to give the best interface for this window port:
 
         OPTIONS=name:player,number_pad,menustyle:partial,!time,showexp
-        OPTIONS=hilite_pet,toptenwin,msghistory:200
+        OPTIONS=hilite_pet,toptenwin,msghistory:200,windowtype:Qt
 
 
 If you are using KDE, you may want to also try the KDE version. It just
diff -Naurd ../nethack-3.3.1/win/Qt/nhsplash.xpm ./win/Qt/nhsplash.xpm
--- ../nethack-3.3.1/win/Qt/nhsplash.xpm Thu Jan 1 01:00:00 1970
+++ ./win/Qt/nhsplash.xpm Fri Mar 22 14:40:55 2002
@@ -0,0 +1,374 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"196 111 256 2",
+/* colors */
+" ` c None",
+"   c #A094A7",
+" . c #761C1B",
+" X c #751A1A",
+" o c #361414",
+" O c #18181E",
+" + c #CF0909",
+" @ c #F4F2E2",
+" # c #AD110F",
+" $ c #AB0D0D",
+" % c #C9BEC5",
+" & c #CF977F",
+" * c #627EB9",
+" = c #512A21",
+" - c #5F201B",
+" ; c #A45841",
+" : c #D3281D",
+" > c #661B18",
+" , c #78443A",
+" < c #721110",
+" 1 c #61332A",
+" 2 c #7C231D",
+" 3 c #533226",
+" 4 c #978A8D",
+" 5 c #AF0A0A",
+" 6 c #841111",
+" 7 c #783226",
+" 8 c #B80D0C",
+" 9 c #981514",
+" 0 c #DDDACE",
+" q c #881918",
+" w c #B0A5B9",
+" e c #74352F",
+" r c #CCA799",
+" t c #ADA8AC",
+" y c #9B9897",
+" u c #651413",
+" i c #712C22",
+" p c #710C0B",
+" a c #8E1817",
+" s c #861B19",
+" d c #E4100C",
+" f c #9B1010",
+" g c #B49795",
+" h c #EB0909",
+" j c #3E302B",
+" k c #8F5D53",
+" l c #9E0909",
+" z c #701717",
+" x c #D1CBCF",
+" c c #846E69",
+" v c #9987A2",
+" b c #291413",
+" n c #281212",
+" m c #691110",
+" M c #BA0A0A",
+" N c #DED4D5",
+" B c #71291B",
+" V c #918E90",
+" C c #721F1C",
+" Z c #664231",
+" A c #7D1313",
+" S c #C2B5C0",
+" D c #6B332C",
+" F c #D40909",
+" G c #66625F",
+" H c #460A0B",
+" J c #446CCF",
+" K c #CB0A0A",
+" L c #BB100E",
+" P c #867A85",
+" I c #C64529",
+" U c #273FA2",
+" Y c #B70A0A",
+" T c #A19AA6",
+" R c #811B1A",
+" E c #441916",
+" W c #A50C0C",
+" Q c #521110",
+" ! c #C2BDC3",
+" ~ c #580C0C",
+" ^ c #0E0E0F",
+" / c #481210",
+" ( c #751818",
+" ) c #E0DCDD",
+" _ c #C90C0B",
+" ' c #B5B2C0",
+" ] c #A898B0",
+" [ c #722522",
+" { c #8F1B17",
+" } c #78201E",
+" | c #8D1515",
+".  c #7C1918",
+".. c #831615",
+".X c #E20909",
+".o c #950909",
+".O c #7D100F",
+".+ c #9D7E7A",
+".@ c #792C22",
+".# c #878382",
+".$ c #BC897E",
+".% c #2C2622",
+".& c #D7D4D7",
+".* c #F30909",
+".= c #693D33",
+".- c #CDCBD7",
+".; c #510C0B",
+".: c #0E0B0B",
+".> c #ABA3AF",
+"., c #AE1914",
+".< c #6B1414",
+".1 c #CB0909",
+".2 c #5B513C",
+".3 c #65463C",
+".4 c #1E2856",
+".5 c #6A0909",
+".6 c #8A3425",
+".7 c #381913",
+".8 c #930D0D",
+".9 c #D5D099",
+".0 c #774E3D",
+".q c #403F35",
+".w c #3F231D",
+".e c #7B0909",
+".r c #211110",
+".t c #655A56",
+".y c #171010",
+".u c #BC6F59",
+".i c #AB0A0A",
+".p c #51423F",
+".a c #931110",
+".s c #D2C4AD",
+".d c #7E6F7F",
+".f c #7B1616",
+".g c #BC1914",
+".h c #602519",
+".j c #DAD5C2",
+".k c #B7AAA3",
+".l c #9C231C",
+".z c #67382D",
+".x c #D90909",
+".c c #BAB4BD",
+".v c #A48997",
+".b c #D2C4C4",
+".n c #AF2B1E",
+".m c #EBEAE3",
+".M c #A30F0F",
+".N c #7D1C1B",
+".B c #841918",
+".V c #931313",
+".C c #8B1615",
+".Z c #1A0D0C",
+".A c #640909",
+".S c #635A43",
+".D c #C07D63",
+".F c #8B0B0B",
+".G c #651817",
+".H c #C20909",
+".J c #591715",
+".K c #A21111",
+".L c #9C3122",
+".P c #6A241F",
+".I c #9E0D0D",
+".U c #775B53",
+".Y c #A11513",
+".T c #C7C3C9",
+".R c #280D0C",
+".E c #720909",
+".W c #8D4941",
+".Q c #5B5655",
+".! c #8B1111",
+".~ c #A54427",
+".^ c #E1E0DF",
+"./ c #8D4037",
+".( c #A11B16",
+".) c #727072",
+"._ c #7C0C0C",
+".` c #310E0E",
+".' c #621110",
+".] c #5A1212",
+".[ c #B30A0A",
+".{ c #532318",
+".} c #521F17",
+".| c #792623",
+"X  c #A7A29F",
+"X. c #B6ABBB",
+"XX c #7D1F1D",
+"Xo c #908099",
+"XO c #7B1B1B",
+"X+ c #90878F",
+"X@ c #C5B698",
+"X# c #E90A0A",
+"X$ c #100F0E",
+"X% c #A50909",
+"X& c #580909",
+"X* c #2A1717",
+"X= c #65503D",
+"X- c #3D0C0C",
+"X; c #B00E0D",
+"X: c #807B7F",
+"X> c #7A1D1D",
+"X, c #781D1B",
+"X< c #5A0F0E",
+"X1 c #EF0909",
+"X2 c #696765",
+"X3 c #605B45",
+"X4 c #CD130F",
+"X5 c #D20A0A",
+"X6 c #4C0A0A",
+"X7 c #533E2B",
+"X8 c #850A0A",
+"X9 c #3C59B3",
+"X0 c #C00C0C",
+"Xq c #C70909",
+"Xw c #971915",
+"Xe c #7E1A1A",
+"Xr c #7E7580",
+"Xt c #5E0C0B",
+"Xy c #5D0A0A",
+"Xu c #520909",
+"Xi c #8B2520",
+"Xp c #C85C48",
+"Xa c #CEC5CB",
+"Xs c #6C2A1F",
+"Xd c #642B21",
+"Xf c #9B1212",
+"Xg c #706A68",
+"Xh c #841919",
+"Xj c #A7999E",
+"Xk c #69201C",
+"Xl c #E7E0E0",
+"Xz c #9C6F65",
+"Xx c #C3B9C0",
+"Xc c #826D48",
+"Xv c #AFADA9",
+"Xb c #8A2B22",
+"Xn c #741413",
+"Xm c #9A929B",
+"XM c #CBB5B4",
+"XN c #8F5341",
+"XB c #783C31",
+"XV c #73211F",
+"XC c #911515",
+"XZ c #630D0C",
+"XA c #881616",
+"XS c #E5E4E1",
+"XD c #6E1B1A",
+"XF c #DC0A09",
+"XG c #741616",
+"XH c #8E7F85",
+"XJ c #591B19",
+"XK c #8A201B",
+"XL c #BE0909",
+"XP c #4E1A18",
+"XI c #FEFDF6",
+"XU c #6A0C0C",
+/* pixels */
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XIXI.m ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XIXIXIXI.j ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XIXIXIXI.$Xl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.b.s N.D.$ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ).S.~.~.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.c kXp N ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` g I.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xx.~ & ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.^ ;.uXl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.+Xp.j ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `X  ; r ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.T ; & ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.^XzXp N ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` g.~.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XlXMXMXM r &XMXM N ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xx.~ & ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xl rXp : :X#.X h hX#.X :.X.X.X.x.x :Xp.u &.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.^XN.uXl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.b & :X#X1.*.* : dX5.x F _ K.,.nX0 _X5 _ FXFX4X4.x.xXp.D r N ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.+Xp.j ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.s :X# hX1 h.XX5 8 L.LXw 9 9Xh q.|XB 2 qXCXC |.VXi.6X; # _ _.x.X :.D r ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `X Xp r ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` NXpX#.*.* :X4 _X;.KXhXh.=.| X X.< i 1 1 1.P i.G u.<.=.zX>XhXh.V | #X;.n KX4Xp rXl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.T ; & `Xl r.$XpXpXpXp.$.$XM N ` ` ` ` ` ` ` `XIXI 0 ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XlXpX#.*X1.*X5.,.6 2XhXO z D.=.3.3 GX2.).d.dXrXrXrXo P PXrXg.3 , DXk zXO [ , {.KX0 _ KXp rXl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.^ ;XpX0 8 # | a.  RXhXe qXf.L.u rXl ` ` `XIXIXI @.k ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` 0 & :.*.*X#X0.K R.=XDXd.=.t GX2X2.).d P P P P PXoXoXoXo ] ] v ] vX+.# V.d.U.3.P.NXhXC.VX0X0 _.DXM ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XlXpXF.!.~ { XXD.< > D u.'.<Xk z.  R a.u r.m.m @ @.sX3 x ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` 4Xc & d.gX; qXe z.=.Q G G G.).d v P.d PXrXo v PXoXoXo PX+  Xo     ]  Xm ]      XH.0 iX>XOXCXK.L _ : &Xl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` 0.uXFX0XCXD.~.L.U P P PX+ P P.d.U.3Xd -XJ.f ; @ 0 0.+ g ) ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.SXcXcXN.6.|X,.'XJ.Q G G G P PXo PXrXo vXo v v v ]   vX+Xo vXo v ] ] ] ]   wXmXm T.>XmXm c.U 1.z q.KX0 +Xp.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `X@ IX# 8.! [XrXB kXj v v vXoXoXo v vXoX+.U D , @.j @ c.m.m ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` eX7XcXcXzXb.V f.8 pXd.t.d.d.d.) P.d P P ]Xo PXo vXo vX+ v vXo v v ] wXmXm     TXm T.> w w ' w.d.W C RXC #X0 I rXS ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.+X0 h.* 8 f { k.3Xz.b v vXo v v v v v vXoXo.k g @.s c.s r ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.WXz.mXS.j i.N aXC.V 6.O.6.d.d.)Xr P P.dXr PXo P PXoXoX+ PX+   vXm ]XmXmXmXm   T T w.>.> w.>.> wX..> c ,XGXh.K 8.n &Xl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `X@.NX0.*.*Xq $ $Xp.sXzXzXoXoXo v vXoXo vXoXo P.s @X@.q o (./XM ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.WXz.mXS.D .X>.NXh qXb 2.o.8 ,.).dXo P P P v PXoXoX+ PXo vX+ vXm VXmXm  Xm ] ] ].> w T.>.> w.> w.> tX..c wXz e i , #.g &Xl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.jXMXi 8.*.*X5 $.,.p.yXs.uXo v vXoXo v vXo   ].kX3 O.yX2.U 3 A ;XM ` ` ` ` ` ` `.-XS ` ` ` ` `.WXz.mXSXbX> <.fX, }.= 7 |.M.oXC.0Xr.)Xr P P PXo PX: PXHXoX+ v V V  XmXm   ] ] ] w w w w wX. TX. w wX. S.cX..cXj c C |.K.g &Xl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ).^ 0.b.| W.*.* + 5.F.yX$ 3.~ k v v v v v     T  .%.j 0.4 J.4.4X9 U.d.-.-XS.- * J J J J.- ` ` `.W ;.m.j.P X iXdXZ > i [.NXhXf.! { A.U P PXo P P PXoX+Xo vXoX+X+XmXm VXmXmXm ]Xm ] T wX. w.>X. w wX. tX.X.X..c SXx t c [XhX; 8.u N ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XS 0 ` `.bXiX0X1.*.x 8X0X-.% k.~.n.WXo v v ] ] ].) 4XI.- J J J J U U U U U U UX9 U U J J JX9 * w ,.W @X@Xd.< [.|.< Q.=.P zX>.N s ,XC.8.l kXoXr P vXoXo v  X+X+ VXmXm ]XmXmXmXm ] T T T w.>.>.>.>X. t tX. ' S S.c.c.c.c !.+ iXh 9 8.DXl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xx.m ` ` `.bXbX;X1.*XF.I.[.Z.% j.~ & @ 0Xm ] N !.d &X9X9.- `Xl.Q O.4.4.4.4 O O O O.Q.4 U U U * J.= i @.u ( mXnX>X>.'.p G.t.z C D.=.| a.V.oXb cXoXo PX+X+X+   vXmXmXmXmXm ] wXm T T.> w.>.>.>X..> tX..c t.c.c !.c S !.T.T.T.TXj k. ./.n &Xl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` 0 ` ` ` ` `.bXi L.*.*.X.I lXtX* j B.D.s gXIXIXI J.Q 0XIXIXIXIXIX+.4.4 U U.p.4.Q.% O.q.)X2X9 J J /.G 0.uX, - 1XnX, iXP.QX2X2X2.3 D X.NXeXA s.C.6 cX+X+X+   w v ]Xm V ]     wXm T T w wX. w wX.X. tX.X.X..cX..c.T !.T.TXa.-.T.-Xa ! c [.K.g r ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.bXi M.X.*X#X;.!.i l =.w.~.$.m @ ` J.-XIXIXI @ 0 0 gXoXo     ]  .) j.4Xo.- ` `.>X9.]XnX@Xb.N - G.=.P DXkXJX2X2X2XgXg G.= CX>.= 7.V W.6.dX+X+XmX+XmXmX+      Xm T T TX. w w.>X..>X..> tX..c SXv S ! !Xx !Xa.T.T.-.T.TXa.c kXO.M :XM ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.bXi 8 h.* h.[XD <.i./.3Xp.uXl ' J *XIXIXI.sX3X@.sXo v     ] T T  .U./.b ` ` `.^.J }.U i.P - G GXd z.N.<.pX2X2XgXg.).).) G.3 [.N a f |./ P vXmXm V VXm ] T T ] T T T w.>.> wX.X.X.X.X..c.c !XaX.Xx ! ! !XaXaXaXaXaXa.&.& S.WXA.KXpXM ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.bXi.,.X.*.*X0 eXVX;.,.UXp & J J J `XI @.s.q.+ @.s     ] ] ] T wX. 4 e.$ ` ` ` zXD D DXVXJ G G GXdXGXV 3.QX2XgXg.).).).).).) ,.PXe.@ 7.I.WX+Xm ]  Xm TXm TXm.>.>.>.> T.>X.X. tX. tX..c.c S.T ! !.T !.T.TXa.TXa.-Xa x.&.& xXj.W a #.u ) ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.m ) ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` xXi M h.*.* _.W.UXOX%./ ;.W J J J @ @X@.%Xg @.jXj ] ] ] ].>X. w ! ) g.W N.bX6Xn.f . (Xk G GX2X2 1.z DXJXgXg.).).).).).).)XrXr.U.S D R f.Y.WX+XmXm ]Xm T T T T T.>.>.> t w.c t tX..c S.c.c ! % ! !.T.T x x !Xa.& x.&.&.&.&.&.k.WXi ; & ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XS.9.q y ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.bXiX;XFX1 h K.6Xo ,.OX  U.6 J JXl 0.t j O.+.s c ] ] ] ]X.X. ! ` ` ` NXlXM.G zX>X> .XJ G GX2X2 GXD. XD.pXg.).).).).).).)XrXrX:X:Xg ,.|XhXi.@.W.v ] T TXm T w.>X..>.> w w tX..c.c S.c.c.c ! ! !.T.T.T xXaXa x.&Xa x.& x.&.& ) ).c.U a IXM ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XM.k.9.qX$ t ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.bXi.( F.*.* F.LXHXo y ^.4.L.dX9Xx.q.q.4.% c g k.v ] w.cX. x ` ` ` ` `.k Q .XVXV C.{ G GX2X2X2 G > C 3.t.).).).).).).)XrXrX:X:X:X:X:.U.U e.C 9.WXm T T TX..>.>.>X. wX.X.X. S.c.c.c.cXx.T.T !.T.T.TXa.T.-.- x.& x.&.& ).& ) ) ).&.v 2Xf.uXl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` `XS.jX@X X .c ` ` ` ` ` ` ` ` ` ` ` ` ` ` r.g.H./X@.qX$ O.^ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XMXh 8X#.*.*X5.l P.4 J O ^.h rXI 0 ' *X+ @ 0.+ c.W gX.X. x ` ` ` ` `.+.'XV D D [.J GX2X2X2X2Xg GXd D -.).).).).).)XrXrX:X:X:X:X:.#.#.#Xr , }.CXb kXm T.>.>.>.>.> w wX..c !X..c.c.c.c.T ! !.TXa.T.T.T.T x x x.& x.&.& ).& ) ) ).^ !Xz |., & ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` `.m 0.s.kX  cXcX3X3X3X3Xv r.D.$.+.kXS ` ` ` ` ` rX5.xX5 = O.yX$X$X: ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` rXh 8XFX#.*.XX;X2 J J U ^.+ @ @ 0.t.+.s.+ 4 ]   kXz.v ! ` ` ` ` ` cX6Xn.f .XGXJ GX2X2X2XgXg.).t X.<.p.).).).)Xg.)XrX:X:X:X:.3Xg.#.#.#.#.#.U.U.@Xw ;Xm.> w.> t w tX..cX..c.c.c %Xx.T !.T.-Xa !.- x.TXa x x x.& x ) ) ) ) )XSXSXS.&Xx kXfXp.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` `.m.jX@ cXcXcX3X3X3.p.q.2.q.. I ;.~Xi.@ ,XM ` ` ` NX4X1.* FXPX$X$X$X$ O ` ` ` ` ` ` ` ` `Xl N ` ` ` ` ` ` ` r |.,X5 h.* h.l J J J J.4.2 =.p.4 O O O.% wX.X. %XMXz g ` ` ` `.0 < XXOX,XnXP GX2X2X2XgXg.).).U.PX7 G.).).) =.w.)X:X:X:.q o j.#.#.#.#X+X+ V c ,..XwXzXjX.X. S '.cX.X..c.cX..cXx !.T.TXa.T.T.TXa x x.- x.&.& )XS.m.m ` ` ` ` ` ` ` `XM./.K.$ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` `.j.+ c.2.q.q j j j j.q.q.q.h ; &.u.~ #Xh RX> r ` `Xp h.*.*.oXZ.yX$X$X$X$.T ` ` `Xl k.^ ` `.D j.^ ` ` ` g ` ` `.k q 8.xX#.* d J J J J.4 ^ ^ BXs O ^ O ^X9X..k.& ` ` N ` ` x `XJ.] }XV C C =X2X2X2.Q.w G.).).) 3 i -.).).Q oX*.w.)X:.3.r o b G.#.#Xr.tX+ V V VXH k.U { k T S.cX..c.c.c.c.cXxXx.c !.TXa.T.T x xXa x )XS ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` gXM ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` `.+.% O O O.y.y.y O O O.%.% |.D &.D.(.K.VXC R.f g rXq.x.1 MX8X6 QX$X$X$X$ y ` ` ` g o.Q ` x E n.Q ` ` r E.# ` ` ` r q 8X5 hX1 J J J.4X9X9 U ^ 1.~.4 ^.y.4 * 2.3.^ ` ` ` !.:X: HXt i [ [XD 1X2X2 G.w oX*.t.)X2X* QX>.3.) oX* o n.w.Q b b o n.%X:.p o o.# V V V V V y c.6 {XzX..c.c.c.c S !XxXxXx !.T.TXa.T x.^ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` `.T.c.c.c yX:.).pX$X$X$ OX*Xb ; ; :.i W.MXf.YX;Xq M.M fXUXyXuXu q QX$X$X$.% ! ` `.W.Z.r y.D n n.Z t ` 1 b n.T ` ` `.$ a.,Xq & * J U J U U J U O.4.~ U U UX9.pXP.p.^ `.^.%.:.r HX<.f. .NXn.7.QX2.q b o bX*.t j.r o =X7 = nX* o n nX* bX* o n b.w n o o.t V V V VXm y y yXH c.6XzX..c.cXa !.T !.T !Xa x.^ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` `.^ y.pX$.r._.M.a.FX%XL K.1 L.a M.xX;.!X6X-X- H R zX-X$.y.Z.p ` x.7.Z.ZX* j.r n.ZX* g o b.r j ` ` ` `Xz.L.jXI.- J.4 J J J U U O O.4.6 U U U U.q.7.U `.+ oXJ o H < (Xn ..'.`X*.Q o b o n bX* b b o n.J Q nX* o.r.r b b o b n o bX* o b.q V V VXg.w V y y y y 4 kXiXz.c ! ! !Xx.T x.m ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` `.z.F $.. R.! W $XF F.F $ K.[ f Q Q.J Q.G z.f <.` o.ZX$ y.v.r.Z.r.y.y.r n.y.Z.7 n b.r.r.t.$.$ rXz.~ 2XK.~.QX9 J.- @.s.q.4.4 ^ UX9 UX9X9 U.4X*.U E EXJ /.' XXV [XV.<.` b b b b o n b b n b o b nXJ.w b b.r.rX* n o n.r o b o o bX* VX+.pX* o.t y y y y T TX .+XN.u S.T xXS ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` `Xz M.[ f.C.C K +.MXA.F.oX#.*.1X8 u u -.<Xy.C.' <Xu.`.R.R =.3.`.R.R.R.Z.r.R.r.r n.r n.r.y.Z B B B.h B B B B B B 1 @XIXIX@.Z.:.:.: ^ O O.4.4.4 O O.yX* o HXyXG .XVXVXU.% OX* n b o.r b.r.r b o n.r.`.h /.`.`.` E H H /.` o b o b b b.t.w b o.7.w ! x.&XM k ` ` ` `XM ;.u ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` N M FXL W f.F h L 6 p.EXLX1.XXf. .<.'XPX< ( AXZ.;.<XJ EXG.P > EXk.{XP.{.{ - (XJ >._.]XPX<X-.O.;X-.R.R.`.{ B B B B./XIXI 0.w.R.7.:.r.r.:.J bX*.`.r O O.yXuXyXG A ..<XZ.%.r n.`.`X-X-.`X-X-X- HX-X-X6.;.<X6 ~ =.hXUXZ.5X<.]X-.` n nX*.7.7 EXkXPXP.bXl cXJXkXj ` ` `Xl ` N ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` `Xp.X.X Y.[X; fX4 8.M.o W F.o <.O 9.].6Xc j CXG.fXZ.]X7Xk =.P =.@ =XbX7 7.=.3 = >.SXV u./Xc.(.O.].h.JXy.`.R /.h B B.h.uXI.m./.n.nXK.7.}.Z.RXU.i l f {.l.' ~.'.B.f X zXtX- HX-XuXuX6X&X&X6XyXuX&.AX6X&XuX<XdXU.} 1 1 m p.5XtX< u <.A.J =X<.GXJ E E k.= E - -.U ` `.+.@.k ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` `.+ 6 M.[XF M | <X8 l.o.i.KX, /.h.~ /Xp.~.p EX> mXu.]XV 3 -X7 1 j = 3XP 1 =Xd =.6X= DXf a.3.~XG.aXw.h.!X&Xu.R.}.h B.~.h 0.mX7 I.n.LXK.h /X-X6XuX& j.q.pX6.A.' XXD }XO.; / ~X&X6.AX&.E.E ~.E.A ~.E.A.5.5.A < < <.hXs.hXU.o l M.M.K {._ B 3.! z.J /XkXP.}XD E.}.k.=.} C.U ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` `Xl.V m 8.* WXh 6 W W.8 ~ >.J j.D.9.h.~.~X7 OXG z Q.]XPXV 3XJ =.P j.P 1 - 1.PXd 3.N ,.|...6./.K #.I.!.F.E.e HX-.h B B.h.z @.%.n.n.n.L B.}X<.  >XkXJ.3 jX6.AXU q.f X <.;X- Q ~Xy.E.E.5.eXU.E.eXUX8.EXt.E.5 p (.< 6 Z.~., K., LX0 8.M |._Xd 7X;., W.O.G.<.}XP E - E -Xk.}.^ ` ` N ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` 7 I $.* _.VX;.FX;.VXi.| u.v &.D.~.6.6X7 O /XDXb.J E = C =.PXJXkXdXX - -XJ.PXJ.PXK D.! R.=Xb 9 f.V.Y.8.o.e H.}.h B B.7.m.%XK { 2XK B.{ /.! 6 [ iXA mX&.5Xt AXn (XZ ~ ~Xt.;.;.5.e.E.e.e.EX8.o.F 5.o 5X%X% l (.,.u.u.~.g.H +.,.l.(.(Xw.8XKXw M $.[.aXb.!.'XP EXJXDXPXP.k N cX>Xx ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` `.j.~ $ YXq.[.o l.a #XhXKXXXC.u.9.D I.h 7.q O o Q.  } Q -.]XJ.].J z u.]XPX<XD.'Xn X 6.<XG._.  i.M.8 8.. {.FX8.AX-.7 /.7 b @ c &.D.l Q /.7.R p 6.' E >Xy.EXU uXnXG C p.' Q QXt.;.E.eX8 YXq _.x +.x.x.1 K FX;X5 K _ : I IX4.g.n.g.n.YXw.LXK p.8 K M M $X0 $.i 7.h.<XJXP E ,XJXJXk.+ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` &.I.e.iXLX%.8X;.I f 6 z { 9.n.&.DXp.6 Z j.yX*.J.G.G QX<X6Xu.;.;X<.; HXu.;X6X6.;Xt.fXAXA.O._ .Xn 6._ BXs A.F.FX6.Z.Z.:X3 g g @ @ @.D <X6 /.8.I.F.}X<.5.e.A.O.O A <XtX7 3.w.{XA.[.1 +X5 F +XF FX0 F +X0X5 F F.x.XX1.X.nXp ;XcXcXN.n.l.L {X8X8XL.[ LXLXq.H + 8.,.Y.8 - /XPXP CXJ.0 `.^.$.$ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` `XM $XL.H.[ Y Y W f.!XC A mXw.,.gXp.T.DXc 1 EX* /.JXP.GXuXtXZ ~.;X&XtXyX6XyXZ.5 p p 6..XhXe.V.!XA.. f.8.!.PXXX8X& ~ H.`.R.Z.r.q g.j.j.s.D {.8.8 pX8XZXZ.E.E.5.OX8.f.O Q.q.2XcXc.0.( MX0X4.g L + KX0 + K F F.1 K.xX5 d I.u.D.DXcXzXc ;.L.,.Y.a.8.[.H., L.H _ 8.HXq MXq.,XNXX zXJXPXPXzXPXV 3 ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` r., l l.H.[X;.[X0.V |.a <.< 6.,X4X4X4 :.g.F z mX<.GX6XyXy.A m.AXt.A.5.5.5.5.A.AXy._Xt (XG.N ( | 9XAXh fXC A z.8 6.! p Q >X-.`.R.r j cX@.sX@ qX8.o.E.A.'.eX8XU < A.fXU QX7X=X3X3.2 D R.N 7 e e 7XXXhXh q a.K.MX; 8X4.D.D.u.u.DXcXcXc ;.L., #.M.!.8 MX; LX;X0.L F.HX0X5Xq +X0 8.@XkXJXJ - }XP.b ` ` `.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` rXL.1.X +.XX#.H 8 f f.V 6 p.] R 9 # LX0.( z.<.G Q.]X&XZ.A.A.A.AX&XyXZ.A.AXyXUXZ p.E p A aXGXh..XAXAXh. .  |Xh q 9.KXf.! z i <.'.;.R.:X$X*.q 3X@XNXK.o.e.E.5.E.EX8.F AXZ uX> } DX=X3 D i.= Z.SX=.=.|X>X>X>X>X>X>X>.|X=.SXc.0.6./XcXcXc.~.,.( # 9.M.O lX; W Y.[ _Xq.1X0.g K.HXqXq.g.~.~ A. .}.}.+ g.U.PXB ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` `.b.g FXF F F +.x W.[.[.M f 9...fXh.N RXOX<.|XkXD (.'XZXU ~X& ~.A ~XZXt.AXZ.AXU.AXZ.5.A p.f.fX>. Xe X. XwXA | qXe s.f.fXeXh.(.| 6.V |.F B.`.R.R.R b.z.u.sXw.EX8XU.EX8.!.FXZ XX>X>X> [ D.=.=.SX3X3.SX=.6XC.V | | |Xh.|.SX3.S.2.3Xd 1.2.3 Z eXf.I W $.a fX8 #.M M $X0 MXq.H K _.1 KX5Xq _X0.H.l 7 u - E -XX.}.^ `.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` I _ F.X.X F.H.[.oX% $.K..Xf q.NXeXeXO.N.'.<.P m ~.'XZXZXuX&XZXZX<X&XtXUX<.'XZ mXZ m <.' z AX, R.N R a.N q.N q sXh aXA q.V . {.K.Y 9XA B.h u.`.RX- o.+ 0.9.nX8 <XZ.F.o.EXyX<.< XX>.N RXV D.SX3X3X3X3.S { W.M.M $ f.6XcXcXc , 7XiXK 7XB.zXs z z. .! W.a.a.IX; 8X; W.[ MX0XqXL K _ _ F KX5 +.g.~XNXw.<X> -.}.+.W.l.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` &XL l FX1.X + F.M.Y.C.V mXh qXh z mX>.'.f u u.JXGXuXZX& Q Q.' u u.]X<.J.G -Xk.G.PXD CXD ..fXG.fXhX,.NX> X R.N.  .Xw a |XCXhXCXD q A A.BXn.{ 7 /X6 ~XD / 3 &.j 6 9 ( W.[.a | 6 6XGXO.V.MXf s 7.SX3X3X3.S.3XV.NXh | f #./XcXc.L.,.( _.Y.lXw.M l.! . C (.!.!.F f.K.MX0X;X; 8.[X0.[.HXF.1 F + +.x.x + _Xq { u [XJXbXiXz ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` `.$.xXLX0XqX5.H.H.H 5 $.V. .< zXhXh R.<Xn X.'.<Xt < p.'.< ~.;.'.JXJ.}.h 3.{ 3 =X7X7 =.3 ZXd.P [ }XeXOXe X R R R s a R.B {.N XXO.| R.f 9.CXw >.} 7XD f 6.Y.B EXz.9XwXiXb L.x hX5XL.[.f.. W f.K $.M./XcXc.UXcX3.=X>X>X>X> R qXb.6.K M $ M 5.[ WX%.i l.8 qXe XXG.F._.K.a f f #.M _., _X; K _X0.H F FX5.x F K ; ;.6 s.l.} e `XMXp.$ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` `.$ _ F.1X0.H +.X h FXL f |.fXG XXh R. XG m z.'XyX&.'.]X<.G ~XJ.z.=XB 7 DXs 7 i -Xk.h = 1 ZX=X=.= D D D [XVX> .Xh.NX>Xh.N aXe {XeXV {.CXh 9Xf.{.}XbXiXA..Xf.C.N.P -.(XbXw _.x.xXF Y M.  | K fXCX; 9.(XcXcXcXzXc.~ WXf.YXh.NX>X,X>XAXf.K f f 9.iX%X%X%X%.a sXA.fXn.e. .I |.( a.M #.( #.H 8.nX0Xq KX5X5X5 +XF.g :X4 _X; XXJ e.P.n.P N ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` NX5X#XF FXq.x F.X + +XL.KXCXh.<.<.G.< <XG ~XtXZX8.GX<Xt.;.PX<.U g.k % N ` ` ` ` ` x gXzXkXd i i.=.=.3.= e D CX> 2XX A aXe a.N.N q RXeXhXC.N q /.} e.NXA | a.C | [.= eXi #Xq.x.HXFX;XL..XC $ #.V.K L #./ ;XcXcXc.g $X; 8X; _XfXCXC.  }XVXkXsXdXkXnXn A.8.8.BXA A A.O.O...KXKXC 6.VXK 9.IX0.( # W.[.g L +.x.xXF +XF.x :.~.Y.fXb.lXVXz ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` `.$XqX%.x F.[X5XLX&X6.`._ qXhXn.<.; mX>X,XnXZ pXU.< uX& ~.G Q.J N ` ` ` ` ` ` ` ` ` ` ` `Xl gXN CXd.= D } i.z C.=.= [XX.NXG |XO ..| RXCXh s.NXC.` = eXw | a.Y.Y qXX.S.=.,., _ F.H.1 FXFXf 9Xf.MX0XCXfX0 f.Y.nXNXc.L.gX0 9.( L.VXf 8.K |XwXKXi.6.,.Y 8 f.aX,.PXV.  A.O._ a.BXK s f a { {.VXf.(.(.KX0.,., # MX5 _ FX5.X :.u I.g 8.B iXV.b.$.L.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` k <.;.RX8 $.x.F.5 H.RX-.|.| XXZ p <.N X u.5XUX6XtX& ~ ~XD ~.+ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` N.$ e uX>XV D.=.3 i } e.| zXnXi.P X...NX> a.C u.` CXC aXhXhXhXh { eX= D RXF.x hXqXLXLX0X;Xf 9Xf 9.V.V $.M f.(.L.n.6.6.,.lXb.l L 9.MX0.(Xw.@.L 7.(X; # LX;.(.(XiXs.z C.O < s 7Xi..XwXiXK f.V.(XK a.M.(.L., M L.~X4 +.XX4XFXF.XX4.g.IXKXDXbXb.W ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` k m.;.R.R f.I.F.F.F.A.e [ e [.< pX,. X,XG u.`.:.; ~ ~.G -XV ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XMXz.JXJ -.|X> C i [ [ 2 ZXkXhXn |.NXn.C.7 /XhXe.BXCXh.NXh.@.U.U 7 9 F.HXqXF.[X;.MXLX5.K a a # #.VX;.(Xb.L.n./.6.l.LXb {.VX;Xf.V.Y 9XX.l eXwXwXi L.,.l.l.l.@ iXd.< p i.@.B R i e R R {.|XA #.Y {XbXK LX;.L.L LX5 IX4.x d.u.D I + A.l.|Xs.+ ` ` `Xl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` `.+.J.. 6._.! AX8X8 YX#.X 7.= iXOXnX>X, X.<.`.:.:X-.J ~ .XyXz ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xl.v e z u zX>.| DX= [.N ..f qXG 6.J.Z.<. Xf A..XA 9XX e Z.@.,.x 8XLX; FX; $ fX;Xf 8 aXhXA.MXA.V.n./.0.W./.6Xb.lX0XC.C.M.. 2.l L q.(XV i ZX=.~.6.(XK.6 7XK 2Xk.G uX> } i.|X>..XK 2 2.NXA {Xb {.Y.K f.l./X4X0.L.gXF :Xp : dX#.X M a.P.6 NXx k.z ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` N i.L I :XK.|.'X8.H +.(.= DXk XX>X>X>.G.R.:.:.: E Q.' } ~XM ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XM k u u C i }X>X>XG }.f.O u.Z EXe.fXn. .! 6Xe.6 6.Y F.1.1.1 + $XLX; +Xf 9 |X;X0 a A 9 |.C {XB ,XB.6.n.6XKXf 9 |.K # 2XX {.C } D.P 1.z.6Xi.YX% {XbXw 6 2 C.JXD.@ i 2.N } i }X>Xh s s.| RXh a |XiXb.M 8.g.~X0X4 IX4.*X1 I :.XX; s 1 E > EXM ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` `.s ;.~.6 D [ R < z i [ C }XG XX>X>.J.:.:.:X$.: EXP.P.' i ` ` ` ` ` ` ` ` ` ` ` `XM N ` ` ` ` ` ` ` ` ` ` ` ` ` ` 3.`.].'X> CX>XGXGXD >.r.R.f z A.B 6._ 9. .I.*.X h.1.HXLXF.[ $ $X0 8.V | f qXCXG |.K., s.6.~XBXBXb.L s.C.Y #XA aXi iXK {.zXXXn >XkXD 6 l Y Y q 7.NXD X C.hX=.S i }.=.3 [X, R [ 2X>.N RXC 2 2 |.YXf.Y ; MX;.n : h IXp IX1.X _X<XJ.}.} c ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` `.TX:X3 Z i { aXe.<Xn .X>X>XD >.R.:.:X$X$X$.:XP.} 1 uXz ` ` ` ` ` ` ` ` ` N.DXp.~Xi.uXM ` ` ` ` ` ` ` ` ` ` ` g =.w.Z.r.R.`.R.;.. /X$ oXnXnXG.f.f._ p 6 #.1.*.x.* h.HXL.[Xq W.MXfX; | qXAXeXC |XhXA.MXh s./ ,XB 7XB.,XhXh.( [XB.0.0 7.6 , > u.].hXJ z.I.F Y.8 i B...B < mXH g.+ cX:.0 i i.=X= DX>.NXX.N sX>XOXhXhXK.(.KXf.L.n.x d I.*.*.*X1.X.I E E i ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` `.+.=.@.N. .N.N.NX> .X-.`.: ^X$X$.:X$X$.:X- = - Q N ` ` ` ` ` ` `XS 0Xp d & d I.l 6 p <.U ! ` ` ` ` ` ` ` c = - - /.R.r.R.7 n o >X> X.N XX,.f <.E.I.H.H F.XXq hX0.H.i.H fXf a 8 L.Y.f.N f 9 R R 9 aXhXBXN.6 2.@Xi. .| 2./ , Z.UX=Xs.z - ~ m ~.J.G <X8 l.FXs.z < A.C p c ` ` ` ` ` ` x.T.k.+ k.UX=.= [.NXXX>.N RXeXh 9Xi.YX;.g I h d : :.* h K.J.W.&.+XP.& ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` `XM.W.NX>X>XD.J.`.r O ^X$X$X$X$.:X$.:.: QXd u k ` ` ` ` ` ` `.m 0.j &X@.j : ;.n..X&.J =X7 c.^ ` ` ` `.^ =XJ.GX< ~XZ.'.<X<.G C X X (X,.< > -.O.[.IXq K.H.xXL.x.1X5 MX% $X;Xh 9XA 9XC ..f.V.CXe q.(.6XB.@ {.| 7 7Xb i i Z DXG.0.0Xd Z.h Q.}X7.{.{.G m 6Xn.PXsXn p.O.E ~.b ` ` ` ` ` ` ` ` ` ` ` ` % g.+.U.= [.NX>.N R.N.YXf 9., MX4 :.*.*.*X#.H ; 3 E o.v ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` `.^.%.y.yX$ ^ OX* OX$ OX$X$X$.:X$.:.y.J -.]XM ` ` ` ` `.m.m.m.mXS.sXzXBXi {XCXe / BX7.wXZ DXM ` ` `.k.}.}.' H ~X&Xy.<.; E.{ -.G u u z . { K.I.C L + 8X#Xq _.1XLXq.I f $XA q RXAXf.N.f A.Y a. .|.6 i.| 2.6 1 Z 1 , 1.2.z.{.h.3.{ 3 3 ZX7.2.2.2X= 1.h.G >XD.. 6 p pXt ..b ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XlXM 4 k D }Xh.NXh a |.K #.,XLXF d h.X F / E o = ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` `.T.% j.p G.Q.q 4.%.qX$.%.:.:.:X$.R.P.J.W ` ` ` ` ` ` ` ` ` ` ` ` g./ D , k -.w jX7X7 /X-X-.p.+.k.U.{.J HX& ~.;X& m u E EX7X= Z 1Xd X A 6.8.B.YX5.K dXF 8.H MXL _.I.a.! R.NXhXh.. z (. XhXOXX 7XB.=.=XB Z.3.2.S 3 - e.{.{ 1 =X7 3.S.2X3X3Xv `XS 4Xd QX<Xn mXUXZXtXZ a.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XS.kXzXB [X>X> X a.! f 8X; +XFXF FX<.7 EXM ` `.& ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` `.bXg GX:.Q.q.t j.%.y j.:X$.:X$.`.h.< % ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` g 3 j jX7 j j.7.7.%.w.w.w QX-.; /.;Xt.< k.U =.2 Z.SX3X3Xd ..B.aXA $.[.Y.K.XX;X5XL Y.i.H.!.8 9XO.NXe {XnXO.N aXCXOX,XK i e.=.0.2 1.2 1 3 1 3X7.PX=.2 [ Z.SX3Xv ` ` ` ` NXz.J ~XUXZXt.A.E.eXw.+ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XMXz.@ }X> {.. f.OX8XLXq.x.H.O.JXM x.p.3 ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ).#.) V.% O.%.Q.y.y.yX$.:X$ b E.' k ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xv.t j j.w.w.7.7.wX*.7X- / /X6 ~.' g ` %.3.3 Z.SX3X3X=Xh.C.K.V.aX%.I.(X5 LX#.X M.i.i.I 6 < 6.NXO.N R.NXOX> (.NX> a a C.=XcX7X7 ZX=.2.3X7.2X7.S i .X= c x ` ` ` ` ` ` `.kXJX6 HX6.A.5X%.1XL.LXl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XS.k.WX>.NXe.C 6X%.I M.1Xq K.~X* n o N ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` `Xv G x.qX$X$ G OX$X$X$X$ ^ =XJ.P.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xx 1 /.w j.w E / HX- /X6Xt.' g ` ` `.+.= [ ZX3.S.S i CXV C. X% $XwX;X;XLX#.i.[X% l._Xy < 9X>XO.N qX> X.N a.N.N 2Xs.3.S.SX3.2X7X3X7.SX3 Z [.|.0Xj ` ` ` ` ` ` ` ` ` N.J / H HX&.5.X h.x 5.W ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XM k iXeXO.K 6.8 YXq 8.8.Z.r.r r ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` x.Q `.)X$.:.q.%X$X$X$X$ b D u.+ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.^.2 E.;.;.; Q Q.w /.;XD g ` ` ` ` `.W } i.SX3.SX= zXV.P.P.!.i {Xw #.i + + MX% l.[XZXZ.NXhX>X>Xh R [ [XK.| i.3.S.2.S.2X3X3.SX3X3 Z.= }XzXv ` ` ` ` ` ` ` ` ` ` ` `XB.]X< ~Xu.e F.x.*XqX8.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` N kX> } X 6 W l W.[XU.y.r g ` ` yXM ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` `XSXg ! t.q.q.%.q.yX$X$ O - i ,XS ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.^ kXuXu.; QXP.w Q >.b ` ` ` ` ` `Xl.WX>.|X=.S.S =.G C.P.B 8XKXw # 5XL.H.H Y.o.O p.'.NXhX> XX>.|.| [.|.@X=.SX3X3X3X3X3.SX3X3X3.0.$Xl ` ` ` ` ` ` ` ` ` ` ` ` ` ` gXy.5.5.E.e.8 l.i lX8 g ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` %.U.N. Xn.O.F.I $._ Q.nXMX X$.+ ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` !X  `.Q.#.q.%.%X$ ^.'X>Xs.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.vXuXuXP j = >.b ` ` ` ` ` ` ` `Xl.WX> }.0X3.S ZXd [.|X,.  2.[ W.HXL 5Xq.F } m uX,.N 2 [ D.=.= D [ iXB ZX=X3X3X3X3X3X3 cXv ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.^X&Xy.E.E u =X8.E.E.A.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` g 7 i X.O <.F $ f 6.C =X$X= ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xv ` c c.p j c ^ n s. .v ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.b ,.w Q ,.b ` ` ` ` ` ` ` ` ` `XlXz [ D.S.S.2 3 1.z 1 C C W.[.i Y Y 5.C 7 -.'X> } C.| [ }XX }XV D.=.=.=.3X=.2 3 3 /.& ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` kX&.E.eXU =X<.5Xy.P ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` N.+ DX, iXn A.O.F.a ~ ~XP.+ 4 cXB r ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.v k.W.W.n.7.G.BXz ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XM ,.3X3X3X=.zX7Xs z.O.o 5X% M.i.i.YXNXd ~X> } }X>X>XD C.P - -.G Q / HX-.7X6X6 k ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` NX&.AX8.o.~ B.E.A k ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` % kX=.@ R Z.fXV.P < D 1 ZX3 c ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` g.xX#XF _.Y.N.WXS ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xl.$XB.3.3.= i > z.O l 5.o 5X;X% W.6 BXt k g.$.$.kXxXM.3XuXuX6 H HX6X6X6Xu e.^ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` e.E.o l.6.n M.e.+ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.b.+ i.S e.zX3.zX3X3.S c ) ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` NX0.*.*.KXXXzXl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` r.+XBXVXV >.< p._.F.o # l l.CXB.]XM ` ` ` ` `.b -XuXuX6X6XuXuXuXu.J.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.+Xy.e {.l YX%.e.$ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XS.k.# k.S.S c cXv ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.$X5 9./.k ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` NXM r./.'.5X8._ 8 l.i l 2 6 g ` ` ` ` ` k -X6Xu ~.;XuXuXu.J.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XM ~.{X=.n.1X%.eXM ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` N.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xl./X&.e.E l M FXL.Y.e.+ ` ` ` ` `.|XdX,.'XD.J u u k N ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.^X7X7 Z.~X4 5.oXM ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.^XB.5.F 5XF.*.X f.o.W ` ` ` ` ` DXD D > D >XD.PXM ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.^.w.hXKXpX4 Y.o.$ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ;.i.i.1X#.xXF $.o.G ` ` ` ` `.= } Z z Z DXDXVXl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `X .w u. .~X0Xq l k ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.$.i Y.[Xq + + 8.a.E , ` ` ` ` `.2 [X=Xd.3.S ZXz ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` 1XU p B.6 L Y.iXb ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.k ;.[Xq.1.iX;.i._ p.e.E.+ ` ` ` ` `.p.=.SX7.P.z ,Xl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.kX&.EX8.iX0Xq YX%. .b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `X  e l.1.XXF.H.C.f.FXU.AXy , ` ` ` ` ` `.pXP i 3.y.yXl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.^.GXy.E l.i M.[Xq 5X8.+ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` k 2.Y.X hX1Xq.8 1 mXt QXd g ` ` ` ` ` ` `.).p n o.% O ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xz.A p.F l.i M + Y lX8Xz ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.+ 6 YX5.*X1 5.F m.{ Q.U.k ` ` ` ` ` ` ` ` `.cX:X$.p.).p ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` NXu.A.5 l Y.xX1 +.H 5X8.W ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` 1 l.1.*.xX; >.}.UX XS ` ` ` ` ` ` ` ` ` ` ` ` tX$X:.c.p ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `XMXy.5 p.o Y.*.*.x.1XL l > ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xl k.<.iXL.X.i 3X7Xx ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.^X$ y ` G ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xz /.A p.[X5X#X1.XXLX%.o [ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xl.gX0 B.i F.[.GX3.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.q.c `.^ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.$ lX8 ~.5X8.oXL.x.i.iX8X8.+ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.D IX0., + F._.t.^ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` y.c ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xi 8 IXtX&.E.E lX%.F.E.A e ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xp., :X4 :X5.!.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.^ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.b.B.6.l.IXF.8.[.*.*X0 q.+ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xz.g I.~ d.gXX N ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.b.|./ 6 8 :.V.g.D d.g ; ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.D.~.n ; ;.l k ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` NXB 7.V.,.u |.~ d.X., k ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` gXN.0.(XNXB.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `./X, aXN.gXA./ ;.g.Y g ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` gXi 1.s.D N ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.k 1XiXN ; 7 ,XcXcXBXl ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.T.sXz.s 0 ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` y.q ,.0XcXd {.L.0XM ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xv.s.j.sXS ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `X .p [Xb.6.w.$.D r ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.&.s.^.b ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.# y.+./ 7 k.k.sXS ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.s ` x ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` VXa.#.s.s.m V.s ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.T ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.&XS V.s.s `X .s ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.^ ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.c.j 0 `Xv 0 ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `X  ) ` `.^ y ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `.TXv ` ` `.& ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `Xg ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `",
+" ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` x ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `"
+};
diff -Naurd ../nethack-3.3.1/win/Qt/qt_clust.cpp ./win/Qt/qt_clust.cpp
--- ../nethack-3.3.1/win/Qt/qt_clust.cpp Sat Nov 20 05:43:28 1999
+++ ./win/Qt/qt_clust.cpp Fri Mar 22 14:40:55 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)qt_clust.cpp	3.3	1999/11/19	*/
+/*	SCCS Id: @(#)qt_clust.cpp	3.4	1999/11/19	*/
 /* Copyright (c) Warwick Allison, 1999. */
 /* NetHack may be freely redistributed.  See license for details. */
 #include "qt_clust.h"
diff -Naurd ../nethack-3.3.1/win/Qt/qttableview.cpp ./win/Qt/qttableview.cpp
--- ../nethack-3.3.1/win/Qt/qttableview.cpp Thu Jan 1 01:00:00 1970
+++ ./win/Qt/qttableview.cpp Fri Mar 22 14:40:55 2002
@@ -0,0 +1,2275 @@
+/**********************************************************************
+** $Id: qttableview.cpp,v 1.2 2002/03/09 03:13:15 jwalz Exp $
+**
+** Implementation of QtTableView class
+**
+** Created : 941115
+**
+** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
+**
+** This file contains a class moved out of the Qt GUI Toolkit API. It
+** may be used, distributed and modified without limitation.
+**
+**********************************************************************/
+
+#include "qttableview.h"
+#if QT_VERSION >= 300
+#ifndef QT_NO_QTTABLEVIEW
+#include <qscrollbar.h>
+#include <qpainter.h>
+#include <qdrawutil.h>
+#include <limits.h>
+
+enum ScrollBarDirtyFlags {
+    verGeometry	  = 0x01,
+    verSteps	  = 0x02,
+    verRange	  = 0x04,
+    verValue	  = 0x08,
+    horGeometry	  = 0x10,
+    horSteps	  = 0x20,
+    horRange	  = 0x40,
+    horValue	  = 0x80,
+    verMask	  = 0x0F,
+    horMask	  = 0xF0
+};
+
+
+#define HSBEXT horizontalScrollBar()->sizeHint().height()
+#define VSBEXT verticalScrollBar()->sizeHint().width()
+
+
+class QCornerSquare : public QWidget		// internal class
+{
+public:
+    QCornerSquare( QWidget *, const char* = 0 );
+    void paintEvent( QPaintEvent * );
+};
+
+QCornerSquare::QCornerSquare( QWidget *parent, const char *name )
+	: QWidget( parent, name )
+{
+}
+
+void QCornerSquare::paintEvent( QPaintEvent * )
+{
+}
+
+
+// NOT REVISED
+/*!
+  \class QtTableView qttableview.h
+  \brief The QtTableView class provides an abstract base for tables.
+
+  \obsolete
+
+  A table view consists of a number of abstract cells organized in rows
+  and columns, and a visible part called a view. The cells are identified
+  with a row index and a column index. The top-left cell is in row 0,
+  column 0.
+
+  The behavior of the widget can be finely tuned using
+  setTableFlags(); a typical subclass will consist of little more than a
+  call to setTableFlags(), some table content manipulation and an
+  implementation of paintCell().  Subclasses that need cells with
+  variable width or height must reimplement cellHeight() and/or
+  cellWidth(). Use updateTableSize() to tell QtTableView when the
+  width or height has changed.
+
+  When you read this documentation, it is important to understand the
+  distinctions among the four pixel coordinate systems involved.
+
+  \list 1
+  \i The \e cell coordinates.  (0,0) is the top-left corner of a cell.
+  Cell coordinates are used by functions such as paintCell().
+
+  \i The \e table coordinates.  (0,0) is the top-left corner of the cell at
+  row 0 and column 0. These coordinates are absolute; that is, they are
+  independent of what part of the table is visible at the moment. They are
+  used by functions such as setXOffset() or maxYOffset().
+
+  \i The \e widget coordinates. (0,0) is the top-left corner of the widget,
+  \e including the frame.  They are used by functions such as repaint().
+
+  \i The \e view coordinates.  (0,0) is the top-left corner of the view, \e
+  excluding the frame.  This is the least-used coordinate system; it is used by
+  functions such as viewWidth().  \endlist
+
+  It is rather unfortunate that we have to use four different
+  coordinate systems, but there was no alternative to provide a flexible and
+  powerful base class.
+
+  Note: The row,column indices are always given in that order,
+  i.e., first the vertical (row), then the horizontal (column). This is
+  the opposite order of all pixel operations, which take first the
+  horizontal (x) and then the vertical (y).
+
+  <img src=qtablevw-m.png> <img src=qtablevw-w.png>
+
+  \warning the functions setNumRows(), setNumCols(), setCellHeight(),
+  setCellWidth(), setTableFlags() and clearTableFlags() may cause
+  virtual functions such as cellWidth() and cellHeight() to be called,
+  even if autoUpdate() is FALSE.  This may cause errors if relevant
+  state variables are not initialized.
+
+  \warning Experience has shown that use of this widget tends to cause
+  more bugs than expected and our analysis indicates that the widget's
+  very flexibility is the problem.  If QScrollView or QListBox can
+  easily be made to do the job you need, we recommend subclassing
+  those widgets rather than QtTableView. In addition, QScrollView makes
+  it easy to have child widgets inside tables, which QtTableView
+  doesn't support at all.
+
+  \sa QScrollView
+  \link guibooks.html#fowler GUI Design Handbook: Table\endlink
+*/
+
+
+/*!
+  Constructs a table view.  The \a parent, \a name and \f arguments
+  are passed to the QFrame constructor.
+
+  The \link setTableFlags() table flags\endlink are all cleared (set to 0).
+  Set \c Tbl_autoVScrollBar or \c Tbl_autoHScrollBar to get automatic scroll
+  bars and \c Tbl_clipCellPainting to get safe clipping.
+
+  The \link setCellHeight() cell height\endlink and \link setCellWidth()
+  cell width\endlink are set to 0.
+
+  Frame line shapes (QFrame::HLink and QFrame::VLine) are disallowed;
+  see QFrame::setFrameStyle().
+
+  Note that the \a f argument is \e not \link setTableFlags() table
+  flags \endlink but rather \link QWidget::QWidget() widget
+  flags. \endlink
+
+*/
+
+QtTableView::QtTableView( QWidget *parent, const char *name, WFlags f )
+    : QFrame( parent, name, f )
+{
+    nRows		 = nCols      = 0;	// zero rows/cols
+    xCellOffs		 = yCellOffs  = 0;	// zero offset
+    xCellDelta		 = yCellDelta = 0;	// zero cell offset
+    xOffs		 = yOffs      = 0;	// zero total pixel offset
+    cellH		 = cellW      = 0;	// user defined cell size
+    tFlags		 = 0;
+    vScrollBar		 = hScrollBar = 0;	// no scroll bars
+    cornerSquare	 = 0;
+    sbDirty		 = 0;
+    eraseInPaint	 = FALSE;
+    verSliding		 = FALSE;
+    verSnappingOff	 = FALSE;
+    horSliding		 = FALSE;
+    horSnappingOff	 = FALSE;
+    coveringCornerSquare = FALSE;
+    inSbUpdate		 = FALSE;
+}
+
+/*!
+  Destroys the table view.
+*/
+
+QtTableView::~QtTableView()
+{
+    delete vScrollBar;
+    delete hScrollBar;
+    delete cornerSquare;
+}
+
+
+/*!
+  \internal
+  Reimplements QWidget::setBackgroundColor() for binary compatibility.
+  \sa setPalette()
+*/
+
+void QtTableView::setBackgroundColor( const QColor &c )
+{
+    QWidget::setBackgroundColor( c );
+}
+
+/*!\reimp
+*/
+
+void QtTableView::setPalette( const QPalette &p )
+{
+    QWidget::setPalette( p );
+}
+
+/*!\reimp
+*/
+
+void QtTableView::show()
+{
+    showOrHideScrollBars();
+    QWidget::show();
+}
+
+
+/*!
+  \overload void QtTableView::repaint( bool erase )
+  Repaints the entire view.
+*/
+
+/*!
+  Repaints the table view directly by calling paintEvent() directly
+  unless updates are disabled.
+
+  Erases the view area \a (x,y,w,h) if \a erase is TRUE. Parameters \a
+  (x,y) are in \e widget coordinates.
+
+  If \a w is negative, it is replaced with <code>width() - x</code>.
+  If \a h is negative, it is replaced with <code>height() - y</code>.
+
+  Doing a repaint() usually is faster than doing an update(), but
+  calling update() many times in a row will generate a single paint
+  event.
+
+  At present, QtTableView is the only widget that reimplements \link
+  QWidget::repaint() repaint()\endlink.	 It does this because by
+  clearing and then repainting one cell at at time, it can make the
+  screen flicker less than it would otherwise.  */
+
+void QtTableView::repaint( int x, int y, int w, int h, bool erase )
+{
+    if ( !isVisible() || testWState(WState_BlockUpdates) )
+	return;
+    if ( w < 0 )
+	w = width()  - x;
+    if ( h < 0 )
+	h = height() - y;
+    QRect r( x, y, w, h );
+    if ( r.isEmpty() )
+	return; // nothing to do
+    QPaintEvent e( r );
+    if ( erase && backgroundMode() != NoBackground )
+	eraseInPaint = TRUE;			// erase when painting
+    paintEvent( &e );
+    eraseInPaint = FALSE;
+}
+
+/*!
+  \overload void QtTableView::repaint( const QRect &r, bool erase )
+  Replaints rectangle \a r. If \a erase is TRUE draws the background
+  using the palette's background.
+*/
+
+
+/*!
+  \fn int QtTableView::numRows() const
+  Returns the number of rows in the table.
+  \sa numCols(), setNumRows()
+*/
+
+/*!
+  Sets the number of rows of the table to \a rows (must be non-negative).
+  Does not change topCell().
+
+  The table repaints itself automatically if autoUpdate() is set.
+
+  \sa numCols(), setNumCols(), numRows()
+*/
+
+void QtTableView::setNumRows( int rows )
+{
+    if ( rows < 0 ) {
+#if defined(QT_CHECK_RANGE)
+	qWarning( "QtTableView::setNumRows: (%s) Negative argument %d.",
+		 name( "unnamed" ), rows );
+#endif
+	return;
+    }
+    if ( nRows == rows )
+	return;
+
+    if ( autoUpdate() && isVisible() ) {
+	int oldLastVisible = lastRowVisible();
+	int oldTopCell = topCell();
+	nRows = rows;
+	if ( autoUpdate() && isVisible() &&
+	     ( oldLastVisible != lastRowVisible() || oldTopCell != topCell() ) )
+		repaint( oldTopCell != topCell() );
+    } else {
+	// Be more careful - if destructing, bad things might happen.
+	nRows = rows;
+    }
+    updateScrollBars( verRange );
+    updateFrameSize();
+}
+
+/*!
+  \fn int QtTableView::numCols() const
+  Returns the number of columns in the table.
+  \sa numRows(), setNumCols()
+*/
+
+/*!
+  Sets the number of columns of the table to \a cols (must be non-negative).
+  Does not change leftCell().
+
+  The table repaints itself automatically if autoUpdate() is set.
+
+  \sa numCols(), numRows(), setNumRows()
+*/
+
+void QtTableView::setNumCols( int cols )
+{
+    if ( cols < 0 ) {
+#if defined(QT_CHECK_RANGE)
+	qWarning( "QtTableView::setNumCols: (%s) Negative argument %d.",
+		 name( "unnamed" ), cols );
+#endif
+	return;
+    }
+    if ( nCols == cols )
+	return;
+    int oldCols = nCols;
+    nCols = cols;
+    if ( autoUpdate() && isVisible() ) {
+	int maxCol = lastColVisible();
+	if ( maxCol >= oldCols || maxCol >= nCols )
+	    repaint();
+    }
+    updateScrollBars( horRange );
+    updateFrameSize();
+}
+
+
+/*!
+  \fn int QtTableView::topCell() const
+  Returns the index of the first row in the table that is visible in
+  the view.  The index of the first row is 0.
+  \sa leftCell(), setTopCell()
+*/
+
+/*!
+  Scrolls the table so that \a row becomes the top row.
+  The index of the very first row is 0.
+  \sa setYOffset(), setTopLeftCell(), setLeftCell()
+*/
+
+void QtTableView::setTopCell( int row )
+{
+    setTopLeftCell( row, -1 );
+    return;
+}
+
+/*!
+  \fn int QtTableView::leftCell() const
+  Returns the index of the first column in the table that is visible in
+  the view.  The index of the very leftmost column is 0.
+  \sa topCell(), setLeftCell()
+*/
+
+/*!
+  Scrolls the table so that \a col becomes the leftmost
+  column.  The index of the leftmost column is 0.
+  \sa setXOffset(), setTopLeftCell(), setTopCell()
+*/
+
+void QtTableView::setLeftCell( int col )
+{
+    setTopLeftCell( -1, col );
+    return;
+}
+
+/*!
+  Scrolls the table so that the cell at row \a row and colum \a
+  col becomes the top-left cell in the view.  The cell at the extreme
+  top left of the table is at position (0,0).
+  \sa setLeftCell(), setTopCell(), setOffset()
+*/
+
+void QtTableView::setTopLeftCell( int row, int col )
+{
+    int newX = xOffs;
+    int newY = yOffs;
+
+    if ( col >= 0 ) {
+	if ( cellW ) {
+	    newX = col*cellW;
+	    if ( newX > maxXOffset() )
+		newX = maxXOffset();
+	} else {
+	    newX = 0;
+	    while ( col )
+		newX += cellWidth( --col );   // optimize using current! ###
+	}
+    }
+    if ( row >= 0 ) {
+	if ( cellH ) {
+	    newY = row*cellH;
+	    if ( newY > maxYOffset() )
+		newY = maxYOffset();
+	} else {
+	    newY = 0;
+	    while ( row )
+		newY += cellHeight( --row );   // optimize using current! ###
+	}
+    }
+    setOffset( newX, newY );
+}
+
+
+/*!
+  \fn int QtTableView::xOffset() const
+
+  Returns the x coordinate in \e table coordinates of the pixel that is
+  currently on the left edge of the view.
+
+  \sa setXOffset(), yOffset(), leftCell() */
+
+/*!
+  Scrolls the table so that \a x becomes the leftmost pixel in the view.
+  The \a x parameter is in \e table coordinates.
+
+  The interaction with \link setTableFlags() Tbl_snapToHGrid
+  \endlink is tricky.
+
+  \sa xOffset(), setYOffset(), setOffset(), setLeftCell()
+*/
+
+void QtTableView::setXOffset( int x )
+{
+    setOffset( x, yOffset() );
+}
+
+/*!
+  \fn int QtTableView::yOffset() const
+
+  Returns the y coordinate in \e table coordinates of the pixel that is
+  currently on the top edge of the view.
+
+  \sa setYOffset(), xOffset(), topCell()
+*/
+
+
+/*!
+  Scrolls the table so that \a y becomes the top pixel in the view.
+  The \a y parameter is in \e table coordinates.
+
+  The interaction with \link setTableFlags() Tbl_snapToVGrid
+  \endlink is tricky.
+
+  \sa yOffset(), setXOffset(), setOffset(), setTopCell()
+*/
+
+void QtTableView::setYOffset( int y )
+{
+    setOffset( xOffset(), y );
+}
+
+/*!
+  Scrolls the table so that \a (x,y) becomes the top-left pixel
+  in the view. Parameters \a (x,y) are in \e table coordinates.
+
+  The interaction with \link setTableFlags() Tbl_snapTo*Grid \endlink
+  is tricky.  If \a updateScrBars is TRUE, the scroll bars are
+  updated.
+
+  \sa xOffset(), yOffset(), setXOffset(), setYOffset(), setTopLeftCell()
+*/
+
+void QtTableView::setOffset( int x, int y, bool updateScrBars )
+{
+    if ( (!testTableFlags(Tbl_snapToHGrid) || xCellDelta == 0) &&
+	 (!testTableFlags(Tbl_snapToVGrid) || yCellDelta == 0) &&
+	 (x == xOffs && y == yOffs) )
+	return;
+
+    if ( x < 0 )
+	x = 0;
+    if ( y < 0 )
+	y = 0;
+
+    if ( cellW ) {
+	if ( x > maxXOffset() )
+	    x = maxXOffset();
+	xCellOffs = x / cellW;
+	if ( !testTableFlags(Tbl_snapToHGrid) ) {
+	    xCellDelta	= (short)(x % cellW);
+	} else {
+	    x		= xCellOffs*cellW;
+	    xCellDelta	= 0;
+	}
+    } else {
+	int xn=0, xcd=0, col = 0;
+	while ( col < nCols-1 && x >= xn+(xcd=cellWidth(col)) ) {
+	    xn += xcd;
+	    col++;
+	}
+	xCellOffs = col;
+	if ( testTableFlags(Tbl_snapToHGrid) ) {
+	    xCellDelta = 0;
+	    x = xn;
+	} else {
+	    xCellDelta = (short)(x-xn);
+	}
+    }
+    if ( cellH ) {
+	if ( y > maxYOffset() )
+	    y = maxYOffset();
+	yCellOffs = y / cellH;
+	if ( !testTableFlags(Tbl_snapToVGrid) ) {
+	    yCellDelta	= (short)(y % cellH);
+	} else {
+	    y		= yCellOffs*cellH;
+	    yCellDelta	= 0;
+	}
+    } else {
+	int yn=0, yrd=0, row=0;
+	while ( row < nRows-1 && y >= yn+(yrd=cellHeight(row)) ) {
+	    yn += yrd;
+	    row++;
+	}
+	yCellOffs = row;
+	if ( testTableFlags(Tbl_snapToVGrid) ) {
+	    yCellDelta = 0;
+	    y = yn;
+	} else {
+	    yCellDelta = (short)(y-yn);
+	}
+    }
+    int dx = (x - xOffs);
+    int dy = (y - yOffs);
+    xOffs = x;
+    yOffs = y;
+    if ( autoUpdate() && isVisible() )
+	scroll( dx, dy );
+    if ( updateScrBars )
+	updateScrollBars( verValue | horValue );
+}
+
+
+/*!
+  \overload int QtTableView::cellWidth() const
+
+  Returns the column width in pixels.	Returns 0 if the columns have
+  variable widths.
+
+  \sa setCellWidth(), cellHeight()
+*/
+
+/*!
+  Returns the width of column \a col in pixels.
+
+  This function is virtual and must be reimplemented by subclasses that
+  have variable cell widths. Note that if the total table width
+  changes, updateTableSize() must be called.
+
+  \sa setCellWidth(), cellHeight(), totalWidth(), updateTableSize()
+*/
+
+int QtTableView::cellWidth( int )
+{
+    return cellW;
+}
+
+
+/*!
+  Sets the width in pixels of the table cells to \a cellWidth.
+
+  Setting it to 0 means that the column width is variable.  When
+  set to 0 (this is the default) QtTableView calls the virtual function
+  cellWidth() to get the width.
+
+  \sa cellWidth(), setCellHeight(), totalWidth(), numCols()
+*/
+
+void QtTableView::setCellWidth( int cellWidth )
+{
+    if ( cellW == cellWidth )
+	return;
+#if defined(QT_CHECK_RANGE)
+    if ( cellWidth < 0 || cellWidth > SHRT_MAX ) {
+	qWarning( "QtTableView::setCellWidth: (%s) Argument out of range (%d)",
+		 name( "unnamed" ), cellWidth );
+	return;
+    }
+#endif
+    cellW = (short)cellWidth;
+
+    updateScrollBars( horSteps | horRange );
+    if ( autoUpdate() && isVisible() )
+	repaint();
+
+}
+
+/*!
+  \overload int QtTableView::cellHeight() const
+
+  Returns the row height, in pixels.  Returns 0 if the rows have
+  variable heights.
+
+  \sa setCellHeight(), cellWidth()
+*/
+
+
+/*!
+  Returns the height of row \a row in pixels.
+
+  This function is virtual and must be reimplemented by subclasses that
+  have variable cell heights.  Note that if the total table height
+  changes, updateTableSize() must be called.
+
+  \sa setCellHeight(), cellWidth(), totalHeight()
+*/
+
+int QtTableView::cellHeight( int )
+{
+    return cellH;
+}
+
+/*!
+  Sets the height in pixels of the table cells to \a cellHeight.
+
+  Setting it to 0 means that the row height is variable.  When set
+  to 0 (this is the default), QtTableView calls the virtual function
+  cellHeight() to get the height.
+
+  \sa cellHeight(), setCellWidth(), totalHeight(), numRows()
+*/
+
+void QtTableView::setCellHeight( int cellHeight )
+{
+    if ( cellH == cellHeight )
+	return;
+#if defined(QT_CHECK_RANGE)
+    if ( cellHeight < 0 || cellHeight > SHRT_MAX ) {
+	qWarning( "QtTableView::setCellHeight: (%s) Argument out of range (%d)",
+		 name( "unnamed" ), cellHeight );
+	return;
+    }
+#endif
+    cellH = (short)cellHeight;
+    if ( autoUpdate() && isVisible() )
+	repaint();
+    updateScrollBars( verSteps | verRange );
+}
+
+
+/*!
+  Returns the total width of the table in pixels.
+
+  This function is virtual and should be reimplemented by subclasses that
+  have variable cell widths and a non-trivial cellWidth() function, or a
+  large number of columns in the table.
+
+  The default implementation may be slow for very wide tables.
+
+  \sa cellWidth(), totalHeight() */
+
+int QtTableView::totalWidth()
+{
+    if ( cellW ) {
+	return cellW*nCols;
+    } else {
+	int tw = 0;
+	for( int i = 0 ; i < nCols ; i++ )
+	    tw += cellWidth( i );
+	return tw;
+    }
+}
+
+/*!
+  Returns the total height of the table in pixels.
+
+  This function is virtual and should be reimplemented by subclasses that
+  have variable cell heights and a non-trivial cellHeight() function, or a
+  large number of rows in the table.
+
+  The default implementation may be slow for very tall tables.
+
+  \sa cellHeight(), totalWidth()
+*/
+
+int QtTableView::totalHeight()
+{
+    if ( cellH ) {
+	return cellH*nRows;
+    } else {
+	int th = 0;
+	for( int i = 0 ; i < nRows ; i++ )
+	    th += cellHeight( i );
+	return th;
+    }
+}
+
+
+/*!
+  \fn uint QtTableView::tableFlags() const
+
+  Returns the union of the table flags that are currently set.
+
+  \sa setTableFlags(), clearTableFlags(), testTableFlags()
+*/
+
+/*!
+  \fn bool QtTableView::testTableFlags( uint f ) const
+
+  Returns TRUE if any of the table flags in \a f are currently set,
+  otherwise FALSE.
+
+  \sa setTableFlags(), clearTableFlags(), tableFlags()
+*/
+
+/*!
+  Sets the table flags to \a f.
+
+  If a flag setting changes the appearance of the table, the table is
+  repainted if - and only if - autoUpdate() is TRUE.
+
+  The table flags are mostly single bits, though there are some multibit
+  flags for convenience. Here is a complete list:
+
+  <dl compact>
+  <dt> Tbl_vScrollBar <dd> - The table has a vertical scroll bar.
+  <dt> Tbl_hScrollBar <dd> - The table has a horizontal scroll bar.
+  <dt> Tbl_autoVScrollBar <dd> - The table has a vertical scroll bar if
+  - and only if - the table is taller than the view.
+  <dt> Tbl_autoHScrollBar <dd> The table has a horizontal scroll bar if
+  - and only if - the table is wider than the view.
+  <dt> Tbl_autoScrollBars <dd> - The union of the previous two flags.
+  <dt> Tbl_clipCellPainting <dd> - The table uses QPainter::setClipRect() to
+  make sure that paintCell() will not draw outside the cell
+  boundaries.
+  <dt> Tbl_cutCellsV <dd> - The table will never show part of a
+  cell at the bottom of the table; if there is not space for all of
+  a cell, the space is left blank.
+  <dt> Tbl_cutCellsH <dd> - The table will never show part of a
+  cell at the right side of the table; if there is not space for all of
+  a cell, the space is left blank.
+  <dt> Tbl_cutCells <dd> - The union of the previous two flags.
+  <dt> Tbl_scrollLastHCell <dd> - When the user scrolls horizontally,
+  let him/her scroll the last cell left until it is at the left
+  edge of the view.  If this flag is not set, the user can only scroll
+  to the point where the last cell is completely visible.
+  <dt> Tbl_scrollLastVCell <dd> - When the user scrolls vertically, let
+  him/her scroll the last cell up until it is at the top edge of
+  the view.  If this flag is not set, the user can only scroll to the
+  point where the last cell is completely visible.
+  <dt> Tbl_scrollLastCell <dd> - The union of the previous two flags.
+  <dt> Tbl_smoothHScrolling <dd> - The table scrolls as smoothly as
+  possible when the user scrolls horizontally. When this flag is not
+  set, scrolling is done one cell at a time.
+  <dt> Tbl_smoothVScrolling <dd> - The table scrolls as smoothly as
+  possible when scrolling vertically. When this flag is not set,
+  scrolling is done one cell at a time.
+  <dt> Tbl_smoothScrolling <dd> - The union of the previous two flags.
+  <dt> Tbl_snapToHGrid <dd> - Except when the user is actually scrolling,
+  the leftmost column shown snaps to the leftmost edge of the view.
+  <dt> Tbl_snapToVGrid <dd> - Except when the user is actually
+  scrolling, the top row snaps to the top edge of the view.
+  <dt> Tbl_snapToGrid <dd> - The union of the previous two flags.
+  </dl>
+
+  You can specify more than one flag at a time using bitwise OR.
+
+  Example:
+  \code
+    setTableFlags( Tbl_smoothScrolling | Tbl_autoScrollBars );
+  \endcode
+
+  \warning The cutCells options (\c Tbl_cutCells, \c Tbl_cutCellsH and
+  Tbl_cutCellsV) may cause painting problems when scrollbars are
+  enabled. Do not combine cutCells and scrollbars.
+
+
+  \sa clearTableFlags(), testTableFlags(), tableFlags()
+*/
+
+void QtTableView::setTableFlags( uint f )
+{
+    f = (f ^ tFlags) & f;			// clear flags already set
+    tFlags |= f;
+
+    bool updateOn = autoUpdate();
+    setAutoUpdate( FALSE );
+
+    uint repaintMask = Tbl_cutCellsV | Tbl_cutCellsH;
+
+    if ( f & Tbl_vScrollBar ) {
+	setVerScrollBar( TRUE );
+    }
+    if ( f & Tbl_hScrollBar ) {
+	setHorScrollBar( TRUE );
+    }
+    if ( f & Tbl_autoVScrollBar ) {
+	updateScrollBars( verRange );
+    }
+    if ( f & Tbl_autoHScrollBar ) {
+	updateScrollBars( horRange );
+    }
+    if ( f & Tbl_scrollLastHCell ) {
+	updateScrollBars( horRange );
+    }
+    if ( f & Tbl_scrollLastVCell ) {
+	updateScrollBars( verRange );
+    }
+    if ( f & Tbl_snapToHGrid ) {
+	updateScrollBars( horRange );
+    }
+    if ( f & Tbl_snapToVGrid ) {
+	updateScrollBars( verRange );
+    }
+    if ( f & Tbl_snapToGrid ) {			// Note: checks for 2 flags
+	if ( (f & Tbl_snapToHGrid) != 0 && xCellDelta != 0 || //have to scroll?
+	     (f & Tbl_snapToVGrid) != 0 && yCellDelta != 0 ) {
+	    snapToGrid( (f & Tbl_snapToHGrid) != 0,	// do snapping
+			(f & Tbl_snapToVGrid) != 0 );
+	    repaintMask |= Tbl_snapToGrid;	// repaint table
+	}
+    }
+
+    if ( updateOn ) {
+	setAutoUpdate( TRUE );
+	updateScrollBars();
+	if ( isVisible() && (f & repaintMask) )
+	    repaint();
+    }
+
+}
+
+/*!
+  Clears the \link setTableFlags() table flags\endlink that are set
+  in \a f.
+
+  Example (clears a single flag):
+  \code
+    clearTableFlags( Tbl_snapToGrid );
+  \endcode
+
+  The default argument clears all flags.
+
+  \sa setTableFlags(), testTableFlags(), tableFlags()
+*/
+
+void QtTableView::clearTableFlags( uint f )
+{
+    f = (f ^ ~tFlags) & f;		// clear flags that are already 0
+    tFlags &= ~f;
+
+    bool updateOn = autoUpdate();
+    setAutoUpdate( FALSE );
+
+    uint repaintMask = Tbl_cutCellsV | Tbl_cutCellsH;
+
+    if ( f & Tbl_vScrollBar ) {
+	setVerScrollBar( FALSE );
+    }
+    if ( f & Tbl_hScrollBar ) {
+	setHorScrollBar( FALSE );
+    }
+    if ( f & Tbl_scrollLastHCell ) {
+	int maxX = maxXOffset();
+	if ( xOffs > maxX ) {
+	    setOffset( maxX, yOffs );
+	    repaintMask |= Tbl_scrollLastHCell;
+	}
+	updateScrollBars( horRange );
+    }
+    if ( f & Tbl_scrollLastVCell ) {
+	int maxY = maxYOffset();
+	if ( yOffs > maxY ) {
+	    setOffset( xOffs, maxY );
+	    repaintMask |= Tbl_scrollLastVCell;
+	}
+	updateScrollBars( verRange );
+    }
+    if ( f & Tbl_smoothScrolling ) {	      // Note: checks for 2 flags
+	if ((f & Tbl_smoothHScrolling) != 0 && xCellDelta != 0 ||//must scroll?
+	    (f & Tbl_smoothVScrolling) != 0 && yCellDelta != 0 ) {
+	    snapToGrid( (f & Tbl_smoothHScrolling) != 0,      // do snapping
+			(f & Tbl_smoothVScrolling) != 0 );
+	    repaintMask |= Tbl_smoothScrolling;		     // repaint table
+	}
+    }
+    if ( f & Tbl_snapToHGrid ) {
+	updateScrollBars( horRange );
+    }
+    if ( f & Tbl_snapToVGrid ) {
+	updateScrollBars( verRange );
+    }
+    if ( updateOn ) {
+	setAutoUpdate( TRUE );
+	updateScrollBars();	     // returns immediately if nothing to do
+	if ( isVisible() && (f & repaintMask) )
+	    repaint();
+    }
+
+}
+
+
+/*!
+  \fn bool QtTableView::autoUpdate() const
+
+  Returns TRUE if the view updates itself automatically whenever it
+  is changed in some way.
+
+  \sa setAutoUpdate()
+*/
+
+/*!
+  Sets the auto-update option of the table view to \a enable.
+
+  If \a enable is TRUE (this is the default), the view updates itself
+  automatically whenever it has changed in some way (for example, when a
+  \link setTableFlags() flag\endlink is changed).
+
+  If \a enable is FALSE, the view does NOT repaint itself or update
+  its internal state variables when it is changed.  This can be
+  useful to avoid flicker during large changes and is singularly
+  useless otherwise. Disable auto-update, do the changes, re-enable
+  auto-update and call repaint().
+
+  \warning Do not leave the view in this state for a long time
+  (i.e., between events). If, for example, the user interacts with the
+  view when auto-update is off, strange things can happen.
+
+  Setting auto-update to TRUE does not repaint the view; you must call
+  repaint() to do this.
+
+  \sa autoUpdate(), repaint()
+*/
+
+void QtTableView::setAutoUpdate( bool enable )
+{
+    if ( isUpdatesEnabled() == enable )
+	return;
+    setUpdatesEnabled( enable );
+    if ( enable ) {
+	showOrHideScrollBars();
+	updateScrollBars();
+    }
+}
+
+
+/*!
+  Repaints the cell at row \a row, column \a col if it is inside the view.
+
+  If \a erase is TRUE, the relevant part of the view is cleared to the
+  background color/pixmap before the contents are repainted.
+
+  \sa isVisible()
+*/
+
+void QtTableView::updateCell( int row, int col, bool erase )
+{
+    int xPos, yPos;
+    if ( !colXPos( col, &xPos ) )
+	return;
+    if ( !rowYPos( row, &yPos ) )
+	return;
+    QRect uR = QRect( xPos, yPos,
+		      cellW ? cellW : cellWidth(col),
+		      cellH ? cellH : cellHeight(row) );
+    repaint( uR.intersect(viewRect()), erase );
+}
+
+
+/*!
+  \fn QRect QtTableView::cellUpdateRect() const
+
+  This function should be called only from the paintCell() function in
+  subclasses. It returns the portion of a cell that actually needs to be
+  updated in \e cell coordinates. This is useful only for non-trivial
+  paintCell().
+
+*/
+
+/*!
+  Returns the rectangle that is the actual table, excluding any
+  frame, in \e widget coordinates.
+*/
+
+QRect QtTableView::viewRect() const
+{
+    return QRect( frameWidth(), frameWidth(), viewWidth(), viewHeight() );
+}
+
+
+/*!
+  Returns the index of the last (bottom) row in the view.
+  The index of the first row is 0.
+
+  If no rows are visible it returns -1.	 This can happen if the
+  view is too small for the first row and Tbl_cutCellsV is set.
+
+  \sa lastColVisible()
+*/
+
+int QtTableView::lastRowVisible() const
+{
+    int cellMaxY;
+    int row = findRawRow( maxViewY(), &cellMaxY );
+    if ( row == -1 || row >= nRows ) {		// maxViewY() past end?
+	row = nRows - 1;			// yes: return last row
+    } else {
+	if ( testTableFlags(Tbl_cutCellsV) && cellMaxY > maxViewY() ) {
+	    if ( row == yCellOffs )		// cut by right margin?
+		return -1;			// yes, nothing in the view
+	    else
+	       row = row - 1;			// cut by margin, one back
+	}
+    }
+    return row;
+}
+
+/*!
+  Returns the index of the last (right) column in the view.
+  The index of the first column is 0.
+
+  If no columns are visible it returns -1.  This can happen if the
+  view is too narrow for the first column and Tbl_cutCellsH is set.
+
+  \sa lastRowVisible()
+*/
+
+int QtTableView::lastColVisible() const
+{
+    int cellMaxX;
+    int col = findRawCol( maxViewX(), &cellMaxX );
+    if ( col == -1 || col >= nCols ) {		// maxViewX() past end?
+	col = nCols - 1;			// yes: return last col
+    } else {
+	if ( testTableFlags(Tbl_cutCellsH) && cellMaxX > maxViewX() ) {
+	    if ( col == xCellOffs )		// cut by bottom margin?
+		return -1;			// yes, nothing in the view
+	    else
+	       col = col - 1;			// cell by margin, one back
+	}
+    }
+    return col;
+}
+
+/*!
+  Returns TRUE if \a row is at least partially visible.
+  \sa colIsVisible()
+*/
+
+bool QtTableView::rowIsVisible( int row ) const
+{
+    return rowYPos( row, 0 );
+}
+
+/*!
+  Returns TRUE if \a col is at least partially visible.
+  \sa rowIsVisible()
+*/
+
+bool QtTableView::colIsVisible( int col ) const
+{
+    return colXPos( col, 0 );
+}
+
+
+/*!
+  \internal
+  Called when both scroll bars are active at the same time. Covers the
+  bottom left corner between the two scroll bars with an empty widget.
+*/
+
+void QtTableView::coverCornerSquare( bool enable )
+{
+    coveringCornerSquare = enable;
+    if ( !cornerSquare && enable ) {
+	cornerSquare = new QCornerSquare( this );
+	Q_CHECK_PTR( cornerSquare );
+	cornerSquare->setGeometry( maxViewX() + frameWidth() + 1,
+				   maxViewY() + frameWidth() + 1,
+                                   VSBEXT,
+                                 HSBEXT);
+    }
+    if ( autoUpdate() && cornerSquare ) {
+	if ( enable )
+	    cornerSquare->show();
+	else
+	    cornerSquare->hide();
+    }
+}
+
+
+/*!
+  \internal
+  Scroll the view to a position such that:
+
+  If \a horizontal is TRUE, the leftmost column shown fits snugly
+  with the left edge of the view.
+
+  If \a vertical is TRUE, the top row shown fits snugly with the top
+  of the view.
+
+  You can achieve the same effect automatically by setting any of the
+  \link setTableFlags() Tbl_snapTo*Grid \endlink table flags.
+*/
+
+void QtTableView::snapToGrid( bool horizontal, bool vertical )
+{
+    int newXCell = -1;
+    int newYCell = -1;
+    if ( horizontal && xCellDelta != 0 ) {
+	int w = cellW ? cellW : cellWidth( xCellOffs );
+	if ( xCellDelta >= w/2 )
+	    newXCell = xCellOffs + 1;
+	else
+	    newXCell = xCellOffs;
+    }
+    if ( vertical && yCellDelta != 0 ) {
+	int h = cellH ? cellH : cellHeight( yCellOffs );
+	if ( yCellDelta >= h/2 )
+	    newYCell = yCellOffs + 1;
+	else
+	    newYCell = yCellOffs;
+    }
+    setTopLeftCell( newYCell, newXCell );  //row,column
+}
+
+/*!
+  \internal
+  This internal slot is connected to the horizontal scroll bar's
+  QScrollBar::valueChanged() signal.
+
+  Moves the table horizontally to offset \a val without updating the
+  scroll bar.
+*/
+
+void QtTableView::horSbValue( int val )
+{
+    if ( horSliding ) {
+	horSliding = FALSE;
+	if ( horSnappingOff ) {
+	    horSnappingOff = FALSE;
+	    tFlags |= Tbl_snapToHGrid;
+	}
+    }
+    setOffset( val, yOffs, FALSE );
+}
+
+/*!
+  \internal
+  This internal slot is connected to the horizontal scroll bar's
+  QScrollBar::sliderMoved() signal.
+
+  Scrolls the table smoothly horizontally even if \c Tbl_snapToHGrid is set.
+*/
+
+void QtTableView::horSbSliding( int val )
+{
+    if ( testTableFlags(Tbl_snapToHGrid) &&
+	 testTableFlags(Tbl_smoothHScrolling) ) {
+	tFlags &= ~Tbl_snapToHGrid;	// turn off snapping while sliding
+	setOffset( val, yOffs, FALSE );
+	tFlags |= Tbl_snapToHGrid;	// turn on snapping again
+    } else {
+	setOffset( val, yOffs, FALSE );
+    }
+}
+
+/*!
+  \internal
+  This internal slot is connected to the horizontal scroll bar's
+  QScrollBar::sliderReleased() signal.
+*/
+
+void QtTableView::horSbSlidingDone( )
+{
+    if ( testTableFlags(Tbl_snapToHGrid) &&
+	 testTableFlags(Tbl_smoothHScrolling) )
+	snapToGrid( TRUE, FALSE );
+}
+
+/*!
+  \internal
+  This internal slot is connected to the vertical scroll bar's
+  QScrollBar::valueChanged() signal.
+
+  Moves the table vertically to offset \a val without updating the
+  scroll bar.
+*/
+
+void QtTableView::verSbValue( int val )
+{
+    if ( verSliding ) {
+	verSliding = FALSE;
+	if ( verSnappingOff ) {
+	    verSnappingOff = FALSE;
+	    tFlags |= Tbl_snapToVGrid;
+	}
+    }
+    setOffset( xOffs, val, FALSE );
+}
+
+/*!
+  \internal
+  This internal slot is connected to the vertical scroll bar's
+  QScrollBar::sliderMoved() signal.
+
+  Scrolls the table smoothly vertically even if \c Tbl_snapToVGrid is set.
+*/
+
+void QtTableView::verSbSliding( int val )
+{
+    if ( testTableFlags(Tbl_snapToVGrid) &&
+	 testTableFlags(Tbl_smoothVScrolling) ) {
+	tFlags &= ~Tbl_snapToVGrid;	// turn off snapping while sliding
+	setOffset( xOffs, val, FALSE );
+	tFlags |= Tbl_snapToVGrid;	// turn on snapping again
+    } else {
+	setOffset( xOffs, val, FALSE );
+    }
+}
+
+/*!
+  \internal
+  This internal slot is connected to the vertical scroll bar's
+  QScrollBar::sliderReleased() signal.
+*/
+
+void QtTableView::verSbSlidingDone( )
+{
+    if ( testTableFlags(Tbl_snapToVGrid) &&
+	 testTableFlags(Tbl_smoothVScrolling) )
+	snapToGrid( FALSE, TRUE );
+}
+
+
+/*!
+  This virtual function is called before painting of table cells
+  is started. It can be reimplemented by subclasses that want to
+  to set up the painter in a special way and that do not want to
+  do so for each cell.
+*/
+
+void QtTableView::setupPainter( QPainter * )
+{
+}
+
+/*!
+  \fn void QtTableView::paintCell( QPainter *p, int row, int col )
+
+  This pure virtual function is called to paint the single cell at \a
+  (row,col) using \a p, which is open when paintCell() is called and
+  must remain open.
+
+  The coordinate system is \link QPainter::translate() translated \endlink
+  so that the origin is at the top-left corner of the cell to be
+  painted, i.e. \e cell coordinates.  Do not scale or shear the coordinate
+  system (or if you do, restore the transformation matrix before you
+  return).
+
+  The painter is not clipped by default and for maximum efficiency. For safety,
+  call setTableFlags(Tbl_clipCellPainting) to enable clipping.
+
+  \sa paintEvent(), setTableFlags() */
+
+
+/*!
+  Handles paint events, \a e, for the table view.
+
+  Calls paintCell() for the cells that needs to be repainted.
+*/
+
+void QtTableView::paintEvent( QPaintEvent *e )
+{
+    QRect updateR = e->rect();			// update rectangle
+    if ( sbDirty ) {
+	bool e = eraseInPaint;
+	updateScrollBars();
+	eraseInPaint = e;
+    }
+
+    QPainter paint( this );
+
+    if ( !contentsRect().contains( updateR, TRUE  ) ) {// update frame ?
+	drawFrame( &paint );
+	if ( updateR.left() < frameWidth() ) 		//###
+	    updateR.setLeft( frameWidth() );
+	if ( updateR.top() < frameWidth() )
+	    updateR.setTop( frameWidth() );
+    }
+
+    int maxWX = maxViewX();
+    int maxWY = maxViewY();
+    if ( updateR.right() > maxWX )
+	updateR.setRight( maxWX );
+    if ( updateR.bottom() > maxWY )
+	updateR.setBottom( maxWY );
+
+    setupPainter( &paint );			// prepare for painting table
+
+    int firstRow = findRow( updateR.y() );
+    int firstCol = findCol( updateR.x() );
+    int	 xStart, yStart;
+    if ( !colXPos( firstCol, &xStart ) || !rowYPos( firstRow, &yStart ) ) {
+	paint.eraseRect( updateR ); // erase area outside cells but in view
+	return;
+    }
+    int	  maxX	= updateR.right();
+    int	  maxY	= updateR.bottom();
+    int	  row	= firstRow;
+    int	  col;
+    int	  yPos	= yStart;
+    int	  xPos = maxX+1; // in case the while() is empty
+    int	  nextX;
+    int	  nextY;
+    QRect winR = viewRect();
+    QRect cellR;
+    QRect cellUR;
+#ifndef QT_NO_TRANSFORMATIONS
+    QWMatrix matrix;
+#endif
+
+    while ( yPos <= maxY && row < nRows ) {
+	nextY = yPos + (cellH ? cellH : cellHeight( row ));
+	if ( testTableFlags( Tbl_cutCellsV ) && nextY > ( maxWY + 1 ) )
+	    break;
+	col  = firstCol;
+	xPos = xStart;
+	while ( xPos <= maxX && col < nCols ) {
+	    nextX = xPos + (cellW ? cellW : cellWidth( col ));
+	    if ( testTableFlags( Tbl_cutCellsH ) && nextX > ( maxWX + 1 ) )
+		break;
+
+	    cellR.setRect( xPos, yPos, cellW ? cellW : cellWidth(col),
+				       cellH ? cellH : cellHeight(row) );
+	    cellUR = cellR.intersect( updateR );
+	    if ( cellUR.isValid() ) {
+		cellUpdateR = cellUR;
+		cellUpdateR.moveBy( -xPos, -yPos ); // cell coordinates
+		if ( eraseInPaint )
+		    paint.eraseRect( cellUR );
+
+#ifndef QT_NO_TRANSFORMATIONS
+		matrix.translate( xPos, yPos );
+		paint.setWorldMatrix( matrix );
+		if ( testTableFlags(Tbl_clipCellPainting) ||
+		     frameWidth() > 0 && !winR.contains( cellR ) ) { //##arnt
+		    paint.setClipRect( cellUR );
+		    paintCell( &paint, row, col );
+		    paint.setClipping( FALSE );
+		} else {
+		    paintCell( &paint, row, col );
+		}
+		matrix.reset();
+		paint.setWorldMatrix( matrix );
+#else
+		paint.translate( xPos, yPos );
+		if ( testTableFlags(Tbl_clipCellPainting) ||
+		     frameWidth() > 0 && !winR.contains( cellR ) ) { //##arnt
+		    paint.setClipRect( cellUR );
+		    paintCell( &paint, row, col );
+		    paint.setClipping( FALSE );
+		} else {
+		    paintCell( &paint, row, col );
+		}
+		paint.translate( -xPos, -yPos );
+#endif
+	    }
+	    col++;
+	    xPos = nextX;
+	}
+	row++;
+	yPos = nextY;
+    }
+
+    // while painting we have to erase any areas in the view that
+    // are not covered by cells but are covered by the paint event
+    // rectangle these must be erased. We know that xPos is the last
+    // x pixel updated + 1 and that yPos is the last y pixel updated + 1.
+
+    // Note that this needs to be done regardless whether we do
+    // eraseInPaint or not. Reason: a subclass may implement
+    // flicker-freeness and encourage the use of repaint(FALSE).
+    // The subclass, however, cannot draw all pixels, just those
+    // inside the cells. So QtTableView is reponsible for all pixels
+    // outside the cells.
+
+    QRect viewR = viewRect();
+    const QColorGroup g = colorGroup();
+
+    if ( xPos <= maxX ) {
+	QRect r = viewR;
+	r.setLeft( xPos );
+	r.setBottom( yPos<maxY?yPos:maxY );
+	if ( inherits( "QMultiLineEdit" ) )
+	    paint.fillRect( r.intersect( updateR ), g.base() );
+	else
+	    paint.eraseRect( r.intersect( updateR ) );
+    }
+    if ( yPos <= maxY ) {
+	QRect r = viewR;
+	r.setTop( yPos );
+	if ( inherits( "QMultiLineEdit" ) )
+	    paint.fillRect( r.intersect( updateR ), g.base() );
+	else
+	    paint.eraseRect( r.intersect( updateR ) );
+    }
+}
+
+/*!\reimp
+*/
+void QtTableView::resizeEvent( QResizeEvent * )
+{
+    updateScrollBars( horValue | verValue | horSteps | horGeometry | horRange |
+		      verSteps | verGeometry | verRange );
+    showOrHideScrollBars();
+    updateFrameSize();
+    int maxX = QMIN( xOffs, maxXOffset() );			// ### can be slow
+    int maxY = QMIN( yOffs, maxYOffset() );
+    setOffset( maxX, maxY );
+}
+
+
+/*!
+  Redraws all visible cells in the table view.
+*/
+
+void QtTableView::updateView()
+{
+    repaint( viewRect() );
+}
+
+/*!
+  Returns a pointer to the vertical scroll bar mainly so you can
+  connect() to its signals.  Note that the scroll bar works in pixel
+  values; use findRow() to translate to cell numbers.
+*/
+
+QScrollBar *QtTableView::verticalScrollBar() const
+{
+    QtTableView *that = (QtTableView*)this; // semantic const
+    if ( !vScrollBar ) {
+	QScrollBar *sb = new QScrollBar( QScrollBar::Vertical, that );
+#ifndef QT_NO_CURSOR
+	sb->setCursor( arrowCursor );
+#endif
+        sb->resize( sb->sizeHint() ); // height is irrelevant
+	Q_CHECK_PTR(sb);
+	sb->setTracking( FALSE );
+	sb->setFocusPolicy( NoFocus );
+	connect( sb, SIGNAL(valueChanged(int)),
+		 SLOT(verSbValue(int)));
+	connect( sb, SIGNAL(sliderMoved(int)),
+		 SLOT(verSbSliding(int)));
+	connect( sb, SIGNAL(sliderReleased()),
+		 SLOT(verSbSlidingDone()));
+	sb->hide();
+	that->vScrollBar = sb;
+	return sb;
+    }
+    return vScrollBar;
+}
+
+/*!
+  Returns a pointer to the horizontal scroll bar mainly so you can
+  connect() to its signals. Note that the scroll bar works in pixel
+  values; use findCol() to translate to cell numbers.
+*/
+
+QScrollBar *QtTableView::horizontalScrollBar() const
+{
+    QtTableView *that = (QtTableView*)this; // semantic const
+    if ( !hScrollBar ) {
+	QScrollBar *sb = new QScrollBar( QScrollBar::Horizontal, that );
+#ifndef QT_NO_CURSOR
+	sb->setCursor( arrowCursor );
+#endif
+	sb->resize( sb->sizeHint() ); // width is irrelevant
+	sb->setFocusPolicy( NoFocus );
+	Q_CHECK_PTR(sb);
+	sb->setTracking( FALSE );
+	connect( sb, SIGNAL(valueChanged(int)),
+		 SLOT(horSbValue(int)));
+	connect( sb, SIGNAL(sliderMoved(int)),
+		 SLOT(horSbSliding(int)));
+	connect( sb, SIGNAL(sliderReleased()),
+		 SLOT(horSbSlidingDone()));
+	sb->hide();
+	that->hScrollBar = sb;
+	return sb;
+    }
+    return hScrollBar;
+}
+
+/*!
+  Enables or disables the horizontal scroll bar, as required by
+  setAutoUpdate() and the \link setTableFlags() table flags\endlink.
+*/
+
+void QtTableView::setHorScrollBar( bool on, bool update )
+{
+    if ( on ) {
+	tFlags |= Tbl_hScrollBar;
+	horizontalScrollBar(); // created
+	if ( update )
+	    updateScrollBars( horMask | verMask );
+	else
+	    sbDirty = sbDirty | (horMask | verMask);
+	if ( testTableFlags( Tbl_vScrollBar ) )
+	    coverCornerSquare( TRUE );
+	if ( autoUpdate() )
+	    sbDirty = sbDirty | horMask;
+    } else {
+	tFlags &= ~Tbl_hScrollBar;
+	if ( !hScrollBar )
+	    return;
+	coverCornerSquare( FALSE );
+	bool hideScrollBar = autoUpdate() && hScrollBar->isVisible();
+	if ( hideScrollBar )
+	    hScrollBar->hide();
+	if ( update )
+	    updateScrollBars( verMask );
+	else
+	    sbDirty = sbDirty | verMask;
+	if ( hideScrollBar && isVisible() )
+	    repaint( hScrollBar->x(), hScrollBar->y(),
+		     width() - hScrollBar->x(), hScrollBar->height() );
+    }
+    if ( update )
+	updateFrameSize();
+}
+
+
+/*!
+  Enables or disables the vertical scroll bar, as required by
+  setAutoUpdate() and the \link setTableFlags() table flags\endlink.
+*/
+
+void QtTableView::setVerScrollBar( bool on, bool update )
+{
+    if ( on ) {
+	tFlags |= Tbl_vScrollBar;
+	verticalScrollBar(); // created
+	if ( update )
+	    updateScrollBars( verMask | horMask );
+	else
+	    sbDirty = sbDirty | (horMask | verMask);
+	if ( testTableFlags( Tbl_hScrollBar ) )
+	    coverCornerSquare( TRUE );
+	if ( autoUpdate() )
+	    sbDirty = sbDirty | verMask;
+    } else {
+	tFlags &= ~Tbl_vScrollBar;
+	if ( !vScrollBar )
+	    return;
+	coverCornerSquare( FALSE );
+	bool hideScrollBar = autoUpdate() && vScrollBar->isVisible();
+	if ( hideScrollBar )
+	    vScrollBar->hide();
+	if ( update )
+	    updateScrollBars( horMask );
+	else
+	    sbDirty = sbDirty | horMask;
+	if ( hideScrollBar && isVisible() )
+	    repaint( vScrollBar->x(), vScrollBar->y(),
+		     vScrollBar->width(), height() - vScrollBar->y() );
+    }
+    if ( update )
+	updateFrameSize();
+}
+
+
+
+
+int QtTableView::findRawRow( int yPos, int *cellMaxY, int *cellMinY,
+			    bool goOutsideView ) const
+{
+    int r = -1;
+    if ( nRows == 0 )
+	return r;
+    if ( goOutsideView || yPos >= minViewY() && yPos <= maxViewY() ) {
+	if ( yPos < minViewY() ) {
+#if defined(QT_CHECK_RANGE)
+	    qWarning( "QtTableView::findRawRow: (%s) internal error: "
+		     "yPos < minViewY() && goOutsideView "
+		     "not supported. (%d,%d)",
+		     name( "unnamed" ), yPos, yOffs );
+#endif
+	    return -1;
+	}
+	if ( cellH ) {				     // uniform cell height
+	    r = (yPos - minViewY() + yCellDelta)/cellH; // cell offs from top
+	    if ( cellMaxY )
+		*cellMaxY = (r + 1)*cellH + minViewY() - yCellDelta - 1;
+	    if ( cellMinY )
+		*cellMinY = r*cellH + minViewY() - yCellDelta;
+	    r += yCellOffs;			     // absolute cell index
+	} else {				     // variable cell height
+	    QtTableView *tw = (QtTableView *)this;
+	    r	     = yCellOffs;
+	    int h    = minViewY() - yCellDelta; //##arnt3
+	    int oldH = h;
+	    Q_ASSERT( r < nRows );
+	    while ( r < nRows ) {
+		oldH = h;
+		h += tw->cellHeight( r );	     // Start of next cell
+		if ( yPos < h )
+		    break;
+		r++;
+	    }
+	    if ( cellMaxY )
+		*cellMaxY = h - 1;
+	    if ( cellMinY )
+		*cellMinY = oldH;
+	}
+    }
+    return r;
+
+}
+
+
+int QtTableView::findRawCol( int xPos, int *cellMaxX, int *cellMinX ,
+			    bool goOutsideView ) const
+{
+    int c = -1;
+    if ( nCols == 0 )
+	return c;
+    if ( goOutsideView || xPos >= minViewX() && xPos <= maxViewX() ) {
+	if ( xPos < minViewX() ) {
+#if defined(QT_CHECK_RANGE)
+	    qWarning( "QtTableView::findRawCol: (%s) internal error: "
+		     "xPos < minViewX() && goOutsideView "
+		     "not supported. (%d,%d)",
+		     name( "unnamed" ), xPos, xOffs );
+#endif
+	    return -1;
+	}
+	if ( cellW ) {				// uniform cell width
+	    c = (xPos - minViewX() + xCellDelta)/cellW; //cell offs from left
+	    if ( cellMaxX )
+		*cellMaxX = (c + 1)*cellW + minViewX() - xCellDelta - 1;
+	    if ( cellMinX )
+		*cellMinX = c*cellW + minViewX() - xCellDelta;
+	    c += xCellOffs;			// absolute cell index
+	} else {				// variable cell width
+	    QtTableView *tw = (QtTableView *)this;
+	    c	     = xCellOffs;
+	    int w    = minViewX() - xCellDelta; //##arnt3
+	    int oldW = w;
+	    Q_ASSERT( c < nCols );
+	    while ( c < nCols ) {
+		oldW = w;
+		w += tw->cellWidth( c );	// Start of next cell
+		if ( xPos < w )
+		    break;
+		c++;
+	    }
+	    if ( cellMaxX )
+		*cellMaxX = w - 1;
+	    if ( cellMinX )
+		*cellMinX = oldW;
+	}
+    }
+    return c;
+}
+
+
+/*!
+  Returns the index of the row at position \a yPos, where \a yPos is in
+  \e widget coordinates.  Returns -1 if \a yPos is outside the valid
+  range.
+
+  \sa findCol(), rowYPos()
+*/
+
+int QtTableView::findRow( int yPos ) const
+{
+    int cellMaxY;
+    int row = findRawRow( yPos, &cellMaxY );
+    if ( testTableFlags(Tbl_cutCellsV) && cellMaxY > maxViewY() )
+	row = - 1;				//  cell cut by bottom margin
+    if ( row >= nRows )
+	row = -1;
+    return row;
+}
+
+
+/*!
+  Returns the index of the column at position \a xPos, where \a xPos is
+  in \e widget coordinates.  Returns -1 if \a xPos is outside the valid
+  range.
+
+  \sa findRow(), colXPos()
+*/
+
+int QtTableView::findCol( int xPos ) const
+{
+    int cellMaxX;
+    int col = findRawCol( xPos, &cellMaxX );
+    if ( testTableFlags(Tbl_cutCellsH) && cellMaxX > maxViewX() )
+	col = - 1;				//  cell cut by right margin
+    if ( col >= nCols )
+	col = -1;
+    return col;
+}
+
+
+/*!
+  Computes the position in the widget of row \a row.
+
+  Returns TRUE and stores the result in \a *yPos (in \e widget
+  coordinates) if the row is visible.  Returns FALSE and does not modify
+  \a *yPos if \a row is invisible or invalid.
+
+  \sa colXPos(), findRow()
+*/
+
+bool QtTableView::rowYPos( int row, int *yPos ) const
+{
+    int y;
+    if ( row >= yCellOffs ) {
+	if ( cellH ) {
+	    int lastVisible = lastRowVisible();
+	    if ( row > lastVisible || lastVisible == -1 )
+		return FALSE;
+	    y = (row - yCellOffs)*cellH + minViewY() - yCellDelta;
+	} else {
+	    //##arnt3
+	    y = minViewY() - yCellDelta;	// y of leftmost cell in view
+	    int r = yCellOffs;
+	    QtTableView *tw = (QtTableView *)this;
+	    int maxY = maxViewY();
+	    while ( r < row && y <= maxY )
+		y += tw->cellHeight( r++ );
+	    if ( y > maxY )
+		return FALSE;
+
+	}
+    } else {
+	return FALSE;
+    }
+    if ( yPos )
+	*yPos = y;
+    return TRUE;
+}
+
+
+/*!
+  Computes the position in the widget of column \a col.
+
+  Returns TRUE and stores the result in \a *xPos (in \e widget
+  coordinates) if the column is visible.  Returns FALSE and does not
+  modify \a *xPos if \a col is invisible or invalid.
+
+  \sa rowYPos(), findCol()
+*/
+
+bool QtTableView::colXPos( int col, int *xPos ) const
+{
+    int x;
+    if ( col >= xCellOffs ) {
+	if ( cellW ) {
+	    int lastVisible = lastColVisible();
+	    if ( col > lastVisible || lastVisible == -1 )
+		return FALSE;
+	    x = (col - xCellOffs)*cellW + minViewX() - xCellDelta;
+	} else {
+	    //##arnt3
+	    x = minViewX() - xCellDelta;	// x of uppermost cell in view
+	    int c = xCellOffs;
+	    QtTableView *tw = (QtTableView *)this;
+	    int maxX = maxViewX();
+	    while ( c < col && x <= maxX )
+		x += tw->cellWidth( c++ );
+	    if ( x > maxX )
+		return FALSE;
+	}
+    } else {
+	return FALSE;
+    }
+    if ( xPos )
+	*xPos = x;
+    return TRUE;
+}
+
+
+/*!
+  Moves the visible area of the table right by \a xPixels and
+  down by \a yPixels pixels.  Both may be negative.
+
+  \warning You might find that QScrollView offers a higher-level of
+	functionality than using QtTableView and this function.
+
+  This function is \e not the same as QWidget::scroll(); in particular,
+  the signs of \a xPixels and \a yPixels have the reverse semantics.
+
+  \sa setXOffset(), setYOffset(), setOffset(), setTopCell(),
+  setLeftCell()
+*/
+
+void QtTableView::scroll( int xPixels, int yPixels )
+{
+    QWidget::scroll( -xPixels, -yPixels, contentsRect() );
+}
+
+
+/*!
+  Returns the leftmost pixel of the table view in \e view
+  coordinates.	This excludes the frame and any header.
+
+  \sa maxViewY(), viewWidth(), contentsRect()
+*/
+
+int QtTableView::minViewX() const
+{
+    return frameWidth();
+}
+
+
+/*!
+  Returns the top pixel of the table view in \e view
+  coordinates.	This excludes the frame and any header.
+
+  \sa maxViewX(), viewHeight(), contentsRect()
+*/
+
+int QtTableView::minViewY() const
+{
+    return frameWidth();
+}
+
+
+/*!
+  Returns the rightmost pixel of the table view in \e view
+  coordinates.	This excludes the frame and any scroll bar, but
+  includes blank pixels to the right of the visible table data.
+
+  \sa maxViewY(), viewWidth(), contentsRect()
+*/
+
+int QtTableView::maxViewX() const
+{
+    return width() - 1 - frameWidth()
+        - (tFlags & Tbl_vScrollBar ? VSBEXT
+           : 0);
+}
+
+
+/*!
+  Returns the bottom pixel of the table view in \e view
+  coordinates.	This excludes the frame and any scroll bar, but
+  includes blank pixels below the visible table data.
+
+  \sa maxViewX(), viewHeight(), contentsRect()
+*/
+
+int QtTableView::maxViewY() const
+{
+    return height() - 1 - frameWidth()
+        - (tFlags & Tbl_hScrollBar ? HSBEXT
+           : 0);
+}
+
+
+/*!
+  Returns the width of the table view, as such, in \e view
+  coordinates.  This does not include any header, scroll bar or frame,
+  but it does include background pixels to the right of the table data.
+
+  \sa minViewX() maxViewX(), viewHeight(), contentsRect() viewRect()
+*/
+
+int QtTableView::viewWidth() const
+{
+    return maxViewX() - minViewX() + 1;
+}
+
+
+/*!
+  Returns the height of the table view, as such, in \e view
+  coordinates.  This does not include any header, scroll bar or frame,
+  but it does include background pixels below the table data.
+
+  \sa minViewY() maxViewY() viewWidth() contentsRect() viewRect()
+*/
+
+int QtTableView::viewHeight() const
+{
+    return maxViewY() - minViewY() + 1;
+}
+
+
+void QtTableView::doAutoScrollBars()
+{
+    int viewW = width()	 - frameWidth() - minViewX();
+    int viewH = height() - frameWidth() - minViewY();
+    bool vScrollOn = testTableFlags(Tbl_vScrollBar);
+    bool hScrollOn = testTableFlags(Tbl_hScrollBar);
+    int w = 0;
+    int h = 0;
+    int i;
+
+    if ( testTableFlags(Tbl_autoHScrollBar) ) {
+	if ( cellW ) {
+	    w = cellW*nCols;
+	} else {
+	    i = 0;
+	    while ( i < nCols && w <= viewW )
+		w += cellWidth( i++ );
+	}
+	if ( w > viewW )
+	    hScrollOn = TRUE;
+	else
+	    hScrollOn = FALSE;
+    }
+
+    if ( testTableFlags(Tbl_autoVScrollBar) ) {
+	if ( cellH ) {
+	    h = cellH*nRows;
+	} else {
+	    i = 0;
+	    while ( i < nRows && h <= viewH )
+		h += cellHeight( i++ );
+	}
+
+	if ( h > viewH )
+	    vScrollOn = TRUE;
+	else
+	    vScrollOn = FALSE;
+    }
+
+    if ( testTableFlags(Tbl_autoHScrollBar) && vScrollOn && !hScrollOn )
+	if ( w > viewW - VSBEXT )
+	    hScrollOn = TRUE;
+
+    if ( testTableFlags(Tbl_autoVScrollBar) && hScrollOn && !vScrollOn )
+	if ( h > viewH - HSBEXT )
+	    vScrollOn = TRUE;
+
+    setHorScrollBar( hScrollOn, FALSE );
+    setVerScrollBar( vScrollOn, FALSE );
+    updateFrameSize();
+}
+
+
+/*!
+  \fn void QtTableView::updateScrollBars()
+
+  Updates the scroll bars' contents and presence to match the table's
+  state.  Generally, you should not need to call this.
+
+  \sa setTableFlags()
+*/
+
+/*!
+  Updates the scroll bars' contents and presence to match the table's
+  state \c or \a f.
+
+  \sa setTableFlags()
+*/
+
+void QtTableView::updateScrollBars( uint f )
+{
+    sbDirty = sbDirty | f;
+    if ( inSbUpdate )
+	return;
+    inSbUpdate = TRUE;
+
+    if ( testTableFlags(Tbl_autoHScrollBar) && (sbDirty & horRange) ||
+	 testTableFlags(Tbl_autoVScrollBar) && (sbDirty & verRange) )
+					// if range change and auto
+	doAutoScrollBars();		// turn scroll bars on/off if needed
+
+    if ( !autoUpdate() ) {
+	inSbUpdate = FALSE;
+	return;
+    }
+    if ( yOffset() > 0 && testTableFlags( Tbl_autoVScrollBar ) &&
+	 !testTableFlags( Tbl_vScrollBar ) ) {
+	setYOffset( 0 );
+    }
+    if ( xOffset() > 0 && testTableFlags( Tbl_autoHScrollBar ) &&
+	 !testTableFlags( Tbl_hScrollBar ) ) {
+	setXOffset( 0 );
+    }
+    if ( !isVisible() ) {
+	inSbUpdate = FALSE;
+	return;
+    }
+
+    if ( testTableFlags(Tbl_hScrollBar) && (sbDirty & horMask) != 0 ) {
+	if ( sbDirty & horGeometry )
+	    hScrollBar->setGeometry( 0,height() - HSBEXT,
+                                     viewWidth() + frameWidth()*2,
+                                   HSBEXT);
+
+	if ( sbDirty & horSteps ) {
+	    if ( cellW )
+		hScrollBar->setSteps( QMIN(cellW,viewWidth()/2), viewWidth() );
+	    else
+		hScrollBar->setSteps( 16, viewWidth() );
+	}
+
+	if ( sbDirty & horRange )
+	    hScrollBar->setRange( 0, maxXOffset() );
+
+	if ( sbDirty & horValue )
+	    hScrollBar->setValue( xOffs );
+
+			// show scrollbar only when it has a sane geometry
+	if ( !hScrollBar->isVisible() )
+	    hScrollBar->show();
+    }
+
+    if ( testTableFlags(Tbl_vScrollBar) && (sbDirty & verMask) != 0 ) {
+	if ( sbDirty & verGeometry )
+	    vScrollBar->setGeometry( width() - VSBEXT, 0,
+                                     VSBEXT,
+                                     viewHeight() + frameWidth()*2 );
+
+	if ( sbDirty & verSteps ) {
+	    if ( cellH )
+		vScrollBar->setSteps( QMIN(cellH,viewHeight()/2), viewHeight() );
+	    else
+		vScrollBar->setSteps( 16, viewHeight() );  // fttb! ###
+	}
+
+	if ( sbDirty & verRange )
+	    vScrollBar->setRange( 0, maxYOffset() );
+
+	if ( sbDirty & verValue )
+	    vScrollBar->setValue( yOffs );
+
+			// show scrollbar only when it has a sane geometry
+	if ( !vScrollBar->isVisible() )
+	    vScrollBar->show();
+    }
+    if ( coveringCornerSquare &&
+	 ( (sbDirty & verGeometry ) || (sbDirty & horGeometry)) )
+	cornerSquare->move( maxViewX() + frameWidth() + 1,
+			    maxViewY() + frameWidth() + 1 );
+
+    sbDirty = 0;
+    inSbUpdate = FALSE;
+}
+
+
+void QtTableView::updateFrameSize()
+{
+    int rw = width()  - ( testTableFlags(Tbl_vScrollBar) ?
+                          VSBEXT : 0 );
+    int rh = height() - ( testTableFlags(Tbl_hScrollBar) ?
+                          HSBEXT : 0 );
+    if ( rw < 0 )
+	rw = 0;
+    if ( rh < 0 )
+	rh = 0;
+
+    if ( autoUpdate() ) {
+        int fh = frameRect().height();
+	int fw = frameRect().width();
+	setFrameRect( QRect(0,0,rw,rh) );
+
+	if ( rw != fw )
+	    update( QMIN(fw,rw) - frameWidth() - 2, 0, frameWidth()+4, rh );
+	if ( rh != fh )
+	    update( 0, QMIN(fh,rh) - frameWidth() - 2, rw, frameWidth()+4 );
+    }
+}
+
+
+/*!
+  Returns the maximum horizontal offset within the table of the
+  view's left edge in \e table coordinates.
+
+  This is used mainly to set the horizontal scroll bar's range.
+
+  \sa maxColOffset(), maxYOffset(), totalWidth()
+*/
+
+int QtTableView::maxXOffset()
+{
+    int tw = totalWidth();
+    int maxOffs;
+    if ( testTableFlags(Tbl_scrollLastHCell) ) {
+	if ( nCols != 1)
+	    maxOffs =  tw - ( cellW ? cellW : cellWidth( nCols - 1 ) );
+	else
+	    maxOffs = tw - viewWidth();
+    } else {
+	if ( testTableFlags(Tbl_snapToHGrid) ) {
+	    if ( cellW ) {
+		maxOffs =  tw - (viewWidth()/cellW)*cellW;
+	    } else {
+		int goal = tw - viewWidth();
+		int pos = tw;
+		int nextCol = nCols - 1;
+		int nextCellWidth = cellWidth( nextCol );
+		while( nextCol > 0 && pos > goal + nextCellWidth ) {
+		    pos -= nextCellWidth;
+		    nextCellWidth = cellWidth( --nextCol );
+		}
+		if ( goal + nextCellWidth == pos )
+		    maxOffs = goal;
+		 else if ( goal < pos )
+		   maxOffs = pos;
+		 else
+		   maxOffs = 0;
+	    }
+	} else {
+	    maxOffs = tw - viewWidth();
+	}
+    }
+    return maxOffs > 0 ? maxOffs : 0;
+}
+
+
+/*!
+  Returns the maximum vertical offset within the table of the
+  view's top edge in \e table coordinates.
+
+  This is used mainly to set the vertical scroll bar's range.
+
+  \sa maxRowOffset(), maxXOffset(), totalHeight()
+*/
+
+int QtTableView::maxYOffset()
+{
+    int th = totalHeight();
+    int maxOffs;
+    if ( testTableFlags(Tbl_scrollLastVCell) ) {
+	if ( nRows != 1)
+	    maxOffs =  th - ( cellH ? cellH : cellHeight( nRows - 1 ) );
+	else
+	    maxOffs = th - viewHeight();
+    } else {
+	if ( testTableFlags(Tbl_snapToVGrid) ) {
+	    if ( cellH ) {
+		maxOffs =  th - (viewHeight()/cellH)*cellH;
+	    } else {
+		int goal = th - viewHeight();
+		int pos = th;
+		int nextRow = nRows - 1;
+		int nextCellHeight = cellHeight( nextRow );
+		while( nextRow > 0 && pos > goal + nextCellHeight ) {
+		    pos -= nextCellHeight;
+		    nextCellHeight = cellHeight( --nextRow );
+		}
+		if ( goal + nextCellHeight == pos )
+		    maxOffs = goal;
+		 else if ( goal < pos )
+		   maxOffs = pos;
+		 else
+		   maxOffs = 0;
+	    }
+	} else {
+	    maxOffs = th - viewHeight();
+	}
+    }
+    return maxOffs > 0 ? maxOffs : 0;
+}
+
+
+/*!
+  Returns the index of the last column, which may be at the left edge
+  of the view.
+
+  Depending on the \link setTableFlags() Tbl_scrollLastHCell\endlink flag,
+  this may or may not be the last column.
+
+  \sa maxXOffset(), maxRowOffset()
+*/
+
+int QtTableView::maxColOffset()
+{
+    int mx = maxXOffset();
+    if ( cellW )
+	return mx/cellW;
+    else {
+	int xcd=0, col=0;
+	while ( col < nCols && mx > (xcd=cellWidth(col)) ) {
+	    mx -= xcd;
+	    col++;
+	}
+	return col;
+    }
+}
+
+
+/*!
+  Returns the index of the last row, which may be at the top edge of
+  the view.
+
+  Depending on the \link setTableFlags() Tbl_scrollLastVCell\endlink flag,
+  this may or may not be the last row.
+
+  \sa maxYOffset(), maxColOffset()
+*/
+
+int QtTableView::maxRowOffset()
+{
+    int my = maxYOffset();
+    if ( cellH )
+	return my/cellH;
+    else {
+	int ycd=0, row=0;
+	while ( row < nRows && my > (ycd=cellHeight(row)) ) {
+	    my -= ycd;
+	    row++;
+	}
+	return row;
+    }
+}
+
+
+void QtTableView::showOrHideScrollBars()
+{
+    if ( !autoUpdate() )
+	return;
+    if ( vScrollBar ) {
+	if ( testTableFlags(Tbl_vScrollBar) ) {
+	    if ( !vScrollBar->isVisible() )
+		sbDirty = sbDirty | verMask;
+	} else {
+	    if ( vScrollBar->isVisible() )
+	       vScrollBar->hide();
+	}
+    }
+    if ( hScrollBar ) {
+	if ( testTableFlags(Tbl_hScrollBar) ) {
+	    if ( !hScrollBar->isVisible() )
+		sbDirty = sbDirty | horMask;
+	} else {
+	    if ( hScrollBar->isVisible() )
+		hScrollBar->hide();
+	}
+    }
+    if ( cornerSquare ) {
+	if ( testTableFlags(Tbl_hScrollBar) &&
+	     testTableFlags(Tbl_vScrollBar) ) {
+	    if ( !cornerSquare->isVisible() )
+		cornerSquare->show();
+	} else {
+	    if ( cornerSquare->isVisible() )
+		cornerSquare->hide();
+	}
+    }
+}
+
+
+/*!
+  Updates the scroll bars and internal state.
+
+  Call this function when the table view's total size is changed;
+  typically because the result of cellHeight() or cellWidth() have changed.
+
+  This function does not repaint the widget.
+*/
+
+void QtTableView::updateTableSize()
+{
+    bool updateOn = autoUpdate();
+    setAutoUpdate( FALSE );
+    int xofs = xOffset();
+    xOffs++; //so that setOffset will not return immediately
+    setOffset(xofs,yOffset(),FALSE); //to calculate internal state correctly
+    setAutoUpdate(updateOn);
+
+    updateScrollBars( horSteps |  horRange |
+		      verSteps |  verRange );
+    showOrHideScrollBars();
+}
+
+
+#endif
+#endif
diff -Naurd ../nethack-3.3.1/win/Qt/qt_win.cpp ./win/Qt/qt_win.cpp
--- ../nethack-3.3.1/win/Qt/qt_win.cpp Sat Jul 22 01:59:19 2000
+++ ./win/Qt/qt_win.cpp Fri Mar 22 14:40:55 2002
@@ -1,14 +1,10 @@
-//	SCCS Id: @(#)qt_win.cpp	3.3	1999/11/19
+//	SCCS Id: @(#)qt_win.cpp	3.4	1999/11/19
 // Copyright (c) Warwick Allison, 1999.
 // NetHack may be freely redistributed.  See license for details.
 
-#define VERSION_QT_MAJOR 2
-#define VERSION_QT_MINOR 0
-#define VERSION_QT_PATCH 0
-
-// Qt Binding for NetHack 3.3
+// Qt Binding for NetHack 3.4
 //
-// Copyright (C) 1996,1997 by Warwick W. Allison (warwick@troll.no)
+// Copyright (C) 1996-2001 by Warwick W. Allison (warwick@troll.no)
 // 
 // Contributors:
 //    Michael Hohmuth <hohmuth@inf.tu-dresden.de>
@@ -51,6 +47,8 @@
 // enough, and we undefine NetHack macros which conflict with Qt
 // identifiers.
 
+#define alloc hide_alloc // avoid treading on STL symbol
+#define lock hide_lock // avoid treading on STL symbol
 #ifdef _MSC_VER
 #define NHSTDC
 #endif
@@ -58,6 +56,7 @@
 #include "func_tab.h"
 #include "dlb.h"
 #include "patchlevel.h"
+#include "tile2x11.h"
 #undef Warning
 #undef red
 #undef green
@@ -68,11 +67,15 @@
 #undef FALSE
 #undef min
 #undef max
+#undef alloc
+#undef lock
 
 }
 
 #include "qt_win.h"
+#include <qregexp.h>
 #include <qpainter.h>
+#include <qdir.h>
 #include <qbitmap.h>
 #include <qkeycode.h>
 #include <qmenubar.h>
@@ -80,9 +83,14 @@
 #include <qlayout.h>
 #include <qheader.h>
 #include <qradiobutton.h>
+#include <qtoolbar.h>
+#include <qtoolbutton.h>
 #include <qcombobox.h>
 #include <qvbox.h>
+#include <qdragobject.h>
+#include <qtextbrowser.h>
 #include <qhbox.h>
+#include <qsignalmapper.h>
 //#include <qgrid.h>
 //#include <qlabelled.h>
 
@@ -91,15 +99,31 @@
 #include "qt_clust.h"
 #include "qt_xpms.h"
 
-#include <malloc.h>
+#include <dirent.h>
+#ifdef Q_WS_MACX
+#  include <sys/malloc.h>
+#else
+#  include <malloc.h>
+#endif
 
 #ifdef _WS_X11_
 // For userid control
 #include <unistd.h>
 #endif
 
+// Some distributors released Qt 2.1.0beta4
+#if QT_VERSION < 220
+# define nh_WX11BypassWM 0x01000000
+#else
+# define nh_WX11BypassWM WX11BypassWM
+#endif
+
 #ifdef USER_SOUNDS
-#include <qaudio.h>
+# if QT_VERSION < 220
+#  undef USER_SOUNDS
+# else
+#  include <qsound.h>
+# endif
 #endif
 
 
@@ -110,18 +134,21 @@
 // Warwick prefers it this way...
 #define QT_CHOOSE_RACE_FIRST
 
+static const char nh_attribution[] = "<center><big>NetHack</big>"
+	"<br><small>by the NetHack DevTeam</small></center>";
+
 static QString
 aboutMsg()
 {
     QString msg;
     msg.sprintf(
-    "Qt NetHack is a version of NetHack built using\n"
+    "Qt NetHack is a version of NetHack built\n"
 #ifdef KDE
-    "KDE and the Qt GUI toolkit for the user interface.\n"
+    "using KDE and the Qt GUI toolkit.\n"
 #else
-    "the Qt GUI toolkit for the user interface.\n"
+    "using the Qt GUI toolkit.\n"
 #endif
-    "This is version %d.%d.%d.%d.%d.%d\n\n"
+    "This is version %d.%d.%d\n\n"
     "Homepage:\n     http://trolls.troll.no/warwick/nethack/\n\n"
 #ifdef KDE
 	  "KDE:\n     http://www.kde.org\n"
@@ -129,10 +156,7 @@
 	  "Qt:\n     http://www.troll.no",
 	VERSION_MAJOR,
 	VERSION_MINOR,
-	PATCHLEVEL,
-	VERSION_QT_MAJOR,
-	VERSION_QT_MINOR,
-	VERSION_QT_PATCH);
+	PATCHLEVEL);
     return msg;
 }
 
@@ -140,6 +164,7 @@
 centerOnMain( QWidget* w )
 {
     QWidget* m = qApp->mainWidget();
+    if (!m) m = qApp->desktop();
     QPoint p = m->mapToGlobal(QPoint(0,0));
     w->move( p.x() + m->width()/2  - w->width()/2,
               p.y() + m->height()/2 - w->height()/2 );
@@ -166,6 +191,7 @@
 char *qt_tilewidth=NULL;
 char *qt_tileheight=NULL;
 char *qt_fontsize=NULL;
+int qt_compact_mode = 0;
 extern const char *enc_stat[]; /* from botl.c */
 extern const char *hu_stat[]; /* from eat.c */
 extern const char *killed_by_prefix[];
@@ -177,8 +203,8 @@
 #define TILEWBASE 16
 #define TILEHBASE 16
 
-#define TILEWMIN 4
-#define TILEHMIN 4
+#define TILEWMIN 1
+#define TILEHMIN 1
 
 
 /* XPM */
@@ -230,6 +256,339 @@
 "                                        ",
 "                                        ",
 "                                        "};
+/* XPM */
+static const char * nh_icon_small[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 16 1",
+/* colors */
+"  c #587070",
+". c #D1D5C9",
+"X c #8B8C84",
+"o c #2A2A28",
+"O c #9AABA9",
+"+ c #6A8FB2",
+"@ c #C4CAC4",
+"# c #B6BEB6",
+"$ c None",
+"% c #54564E",
+"& c #476C6C",
+"* c #ADB2AB",
+"= c #ABABA2",
+"- c #5E8295",
+"; c #8B988F",
+": c #E8EAE7",
+/* pixels */
+"$$$$$$$$$$$$$$$$",
+"$$$.$#::.#==*$$$",
+"$.*:::::....#*=$",
+"$@#:..@#*==#;XX;",
+"$@O:+++- &&; X%X",
+"$#%.+++- &&;% oX",
+"$$o.++-- &&;%%X$",
+"$$$:++-- &&;%%$$",
+"$$$.O++- &&=o $$",
+"$$$=:++- & XoX$$",
+"$$*:@O--  ;%Xo$$",
+"$*:O#$+--;oOOX $",
+"$:+ =o::=oo=-;%X",
+"$::.%o$*;X;##@%$",
+"$$@# ;$$$$$=*;X$",
+"$$$$$$$$$$$$$$$$"
+};
+
+/* XPM */
+static const char * map_xpm[] = {
+"12 13 4 1",
+".	c None",
+" 	c #000000000000",
+"X	c #0000B6DAFFFF",
+"o	c #69A69248B6DA",
+"           .",
+" XXXXX ooo  ",
+" XoooX o    ",
+" XoooX o o  ",
+" XoooX ooo  ",
+" XXoXX o    ",
+"  oooooXXX  ",
+" oo o oooX  ",
+"    o XooX  ",
+" oooo XooX  ",
+" o  o XXXX  ",
+"            ",
+".           "};
+/* XPM */
+static const char * msg_xpm[] = {
+"12 13 4 1",
+".	c None",
+" 	c #FFFFFFFFFFFF",
+"X	c #69A69248B6DA",
+"o	c #000000000000",
+"           .",
+" XXX XXX X o",
+"           o",
+" XXXXX XX  o",
+"           o",
+" XX XXXXX  o",
+"           o",
+" XXXXXX    o",
+"           o",
+" XX XXX XX o",
+"           o",
+"           o",
+".ooooooooooo"};
+/* XPM */
+static const char * stat_xpm[] = {
+"12 13 5 1",
+"  c None",
+".	c #FFFF00000000",
+"X	c #000000000000",
+"o	c #FFFFFFFF0000",
+"O	c #69A6FFFF0000",
+"            ",
+"            ",
+"...         ",
+"...X        ",
+"...X    ... ",
+"oooX    oooX",
+"oooXooo oooX",
+"OOOXOOOXOOOX",
+"OOOXOOOXOOOX",
+"OOOXOOOXOOOX",
+"OOOXOOOXOOOX",
+"OOOXOOOXOOOX",
+" XXXXXXXXXXX"};
+/* XPM */
+static const char * info_xpm[] = {
+"12 13 4 1",
+"  c None",
+".	c #00000000FFFF",
+"X	c #FFFFFFFFFFFF",
+"o	c #000000000000",
+"    ...     ",
+"  .......   ",
+" ...XXX...  ",
+" .........o ",
+"...XXXX.... ",
+"....XXX....o",
+"....XXX....o",
+"....XXX....o",
+" ...XXX...oo",
+" ..XXXXX..o ",
+"  .......oo ",
+"   o...ooo  ",
+"     ooo    "};
+
+
+/* XPM */
+static const char * again_xpm[] = {
+"12 13 2 1",
+" 	c None",
+".	c #000000000000",
+"    ..      ",
+"     ..     ",
+"   .....    ",
+" .......    ",
+"...  ..  .. ",
+"..  ..   .. ",
+"..        ..",
+"..        ..",
+"..        ..",
+" ..      .. ",
+" .......... ",
+"   ......   ",
+"            "};
+/* XPM */
+static const char * kick_xpm[] = {
+"12 13 3 1",
+" 	c None",
+".	c #000000000000",
+"X	c #FFFF6DB60000",
+"            ",
+"            ",
+"   .  .  .  ",
+"  ...  .  . ",
+"   ...  .   ",
+"    ...  .  ",
+"     ...    ",
+"XXX   ...   ",
+"XXX.  ...   ",
+"XXX. ...    ",
+"XXX. ..     ",
+" ...        ",
+"            "};
+/* XPM */
+static const char * throw_xpm[] = {
+"12 13 3 1",
+" 	c None",
+".	c #FFFF6DB60000",
+"X	c #000000000000",
+"            ",
+"            ",
+"            ",
+"            ",
+"....     X  ",
+"....X     X ",
+"....X XXXXXX",
+"....X     X ",
+" XXXX    X  ",
+"            ",
+"            ",
+"            ",
+"            "};
+/* XPM */
+static const char * fire_xpm[] = {
+"12 13 5 1",
+" 	c None",
+".	c #B6DA45140000",
+"X	c #FFFFB6DA9658",
+"o	c #000000000000",
+"O	c #FFFF6DB60000",
+" .          ",
+" X.         ",
+" X .        ",
+" X .o       ",
+" X  .    o  ",
+" X  .o    o ",
+"OOOOOOOOoooo",
+" X  .o    o ",
+" X . o   o  ",
+" X .o       ",
+" X. o       ",
+" . o        ",
+"  o         "};
+/* XPM */
+static const char * get_xpm[] = {
+"12 13 3 1",
+" 	c None",
+".	c #000000000000",
+"X	c #FFFF6DB60000",
+"            ",
+"     .      ",
+"    ...     ",
+"   . . .    ",
+"     .      ",
+"     .      ",
+"            ",
+"   XXXXX    ",
+"   XXXXX.   ",
+"   XXXXX.   ",
+"   XXXXX.   ",
+"    .....   ",
+"            "};
+/* XPM */
+static const char * drop_xpm[] = {
+"12 13 3 1",
+" 	c None",
+".	c #FFFF6DB60000",
+"X	c #000000000000",
+"            ",
+"   .....    ",
+"   .....X   ",
+"   .....X   ",
+"   .....X   ",
+"    XXXXX   ",
+"            ",
+"      X     ",
+"      X     ",
+"    X X X   ",
+"     XXX    ",
+"      X     ",
+"            "};
+/* XPM */
+static const char * eat_xpm[] = {
+"12 13 4 1",
+" 	c None",
+".	c #000000000000",
+"X	c #FFFFB6DA9658",
+"o	c #FFFF6DB60000",
+"  .X.  ..   ",
+"  .X.  ..   ",
+"  .X.  ..   ",
+"  .X.  ..   ",
+"  ...  ..   ",
+"   ..  ..   ",
+"   ..  ..   ",
+"   oo  oo   ",
+"   oo  oo   ",
+"   oo  oo   ",
+"   oo  oo   ",
+"   oo  oo   ",
+"   oo  oo   "};
+/* XPM */
+static const char * rest_xpm[] = {
+"12 13 2 1",
+" 	c None",
+".	c #000000000000",
+"  .....     ",
+"     .      ",
+"    .       ",
+"   .    ....",
+"  .....   . ",
+"         .  ",
+"        ....",
+"            ",
+"     ....   ",
+"       .    ",
+"      .     ",
+"     ....   ",
+"            "};
+/* XPM */
+static const char * cast_a_xpm[] = {
+"12 13 3 1",
+" 	c None",
+".	c #FFFF6DB60000",
+"X	c #000000000000",
+"    .       ",
+"    .       ",
+"   ..       ",
+"   ..       ",
+"  ..  .     ",
+"  ..  .     ",
+" ......     ",
+" .. ..  XX  ",
+"    .. X  X ",
+"   ..  X  X ",
+"   ..  XXXX ",
+"   .   X  X ",
+"   .   X  X "};
+/* XPM */
+static const char * cast_b_xpm[] = {
+"12 13 3 1",
+" 	c None",
+".	c #FFFF6DB60000",
+"X	c #000000000000",
+"    .       ",
+"    .       ",
+"   ..       ",
+"   ..       ",
+"  ..  .     ",
+"  ..  .     ",
+" ......     ",
+" .. .. XXX  ",
+"    .. X  X ",
+"   ..  XXX  ",
+"   ..  X  X ",
+"   .   X  X ",
+"   .   XXX  "};
+/* XPM */
+static const char * cast_c_xpm[] = {
+"12 13 3 1",
+" 	c None",
+".	c #FFFF6DB60000",
+"X	c #000000000000",
+"    .       ",
+"    .       ",
+"   ..       ",
+"   ..       ",
+"  ..  .     ",
+"  ..  .     ",
+" ......     ",
+" .. ..  XX  ",
+"    .. X  X ",
+"   ..  X    ",
+"   ..  X    ",
+"   .   X  X ",
+"   .    XX  "};
 
 NetHackQtSettings::NetHackQtSettings(int w, int h) :
     tilewidth(TILEWMIN,32,1,this),
@@ -241,7 +600,7 @@
 #ifdef WS_WIN
     normalfixed("courier new"),
 #else
-    normalfixed("fixed"),
+    normalfixed("helvetica"), // ################# normally fixed, just testing
 #endif
     large("times"),
     theglyphs(0)
@@ -249,7 +608,12 @@
 {
     int default_fontsize;
 
-    if (w<=700) {
+    if (w<=300) {
+	// ~240x320
+	default_fontsize=4;
+	tilewidth.setValue(8);
+	tileheight.setValue(12);
+    } else if (w<=700) {
 	// ~640x480
 	default_fontsize=3;
 	tilewidth.setValue(8);
@@ -291,6 +655,7 @@
 	  case 'l': default_fontsize = 1; break;
 	  case 'm': default_fontsize = 2; break;
 	  case 's': default_fontsize = 3; break;
+	  case 't': default_fontsize = 4; break;
 	}
 	free(qt_fontsize); 
     }
@@ -305,6 +670,7 @@
     fontsize.insertItem("Large");
     fontsize.insertItem("Medium");
     fontsize.insertItem("Small");
+    fontsize.insertItem("Tiny");
     fontsize.setCurrentItem(default_fontsize);
     connect(&fontsize,SIGNAL(activated(int)),this,SIGNAL(fontChanged()));
 
@@ -341,29 +707,28 @@
 
 const QFont& NetHackQtSettings::normalFont()
 {
-    static int size[]={ 18, 14, 12, 10 };
+    static int size[]={ 18, 14, 12, 10, 8 };
     normal.setPointSize(size[fontsize.currentItem()]);
     return normal;
 }
 
 const QFont& NetHackQtSettings::normalFixedFont()
 {
-    static int size[]={ 18, 14, 13, 10 };
+    static int size[]={ 18, 14, 13, 10, 8 };
     normalfixed.setPointSize(size[fontsize.currentItem()]);
     return normalfixed;
 }
 
 const QFont& NetHackQtSettings::largeFont()
 {
-    static int size[]={ 24, 18, 14, 12 };
+    static int size[]={ 24, 18, 14, 12, 10 };
     large.setPointSize(size[fontsize.currentItem()]);
     return large;
 }
 
 bool NetHackQtSettings::ynInMessages()
 {
-    // XXX Two out of two users prefer True.
-    return TRUE;
+    return !qt_compact_mode;
 }
 
 
@@ -387,9 +752,14 @@
     in=(in+1)%maxkey;
 }
 
+void NetHackQtKeyBuffer::Put(char a)
+{
+    Put(0,a,0);
+}
+
 void NetHackQtKeyBuffer::Put(const char* str)
 {
-    while (*str) Put(0,*str++,0);
+    while (*str) Put(*str++);
 }
 
 int NetHackQtKeyBuffer::GetKey()
@@ -559,10 +929,15 @@
     int selectedItemNumber() const
     {
 	int i=0;
-	QListViewItem* c=firstChild();
-	while (c && c != selectedItem())
-	    i++,c = c->nextSibling();
-	return i;
+	QListViewItem* c = firstChild();
+	while (c) {
+	    if (c == selectedItem()) {
+		return i;
+	    }
+	    i++;
+	    c = c->nextSibling();
+	}
+	return -1;
     }
 
     void setSelectedItemNumber(int i)
@@ -576,7 +951,8 @@
 
 NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks) :
     QDialog(0,"plsel",TRUE),
-    keysource(ks)
+    keysource(ks),
+    fully_specified_role(TRUE)
 {
     /*
                0             1             2
@@ -614,11 +990,15 @@
     race = new NhPSListView(this);
     role->addColumn("Role");
     race->addColumn("Race");
-    QButtonGroup* genderbox = new QButtonGroup(1,Horizontal,"Sex",this);
-    QButtonGroup* alignbox = new QButtonGroup(1,Horizontal,"Alignment",this);
-
-    QLabel* logo = new QLabel("<big>Qt NetHack</big>"
-	"<br><i>by Warwick Allison<br>and the NetHack DevTeam", this);
+    QButtonGroup* genderbox = new QButtonGroup("Sex",this);
+    QButtonGroup* alignbox = new QButtonGroup("Alignment",this);
+    QVBoxLayout* vbgb = new QVBoxLayout(genderbox,3,1);
+    vbgb->setAutoAdd(TRUE);
+    vbgb->addSpacing(fontMetrics().height()*3/4);
+    QVBoxLayout* vbab = new QVBoxLayout(alignbox,3,1);
+    vbab->setAutoAdd(TRUE);
+    vbab->addSpacing(fontMetrics().height());
+    QLabel* logo = new QLabel(nh_attribution, this);
 
     l->addMultiCellWidget( namebox, 0,0,0,2 );
 #ifdef QT_CHOOSE_RACE_FIRST
@@ -672,29 +1052,60 @@
     l->addWidget( cancel, 5, 2 );
     connect( cancel, SIGNAL(clicked()), this, SLOT(reject()) );
 
-    // Randomize
-    int ro = rn2(nrole);
-    int ra = rn2(nrace);
+    // Randomize race and role, unless specified in config
+    int ro = flags.initrole;
+    if (ro == -1) {
+	ro = rn2(nrole);
+	fully_specified_role = FALSE;
+    }
+    int ra = flags.initrace;
+    if (ra == -1) {
+	ra = rn2(nrace);
+	fully_specified_role = FALSE;
+    }
 
+    // make sure we have a valid combination, honoring 
+    // the users request if possible.
+    bool choose_race_first;
 #ifdef QT_CHOOSE_RACE_FIRST
-    while (!validrace(ro,ra))
-	ro = rn2(nrole);
+    choose_race_first = TRUE;
+    if (flags.initrole != -1 && flags.initrace == -1) {
+	choose_race_first = FALSE;
+    }
 #else
-    while (!validrace(ro,ra))
-	ra = rn2(nrace);
+    choose_race_first = FALSE;
+    if (flags.initrace != -1 && flags.initrole == -1) {
+	choose_race_first = TRUE;
+    }
 #endif
+    while (!validrace(ro,ra)) {
+	fully_specified_role = FALSE;
+	if (choose_race_first) {
+	    ro = rn2(nrole);
+	} else {
+	    ra = rn2(nrace);
+	}
+    }
 
-    int g;
-    do {
+    int g = flags.initgend;
+    if (g == -1) {
 	g = rn2(ROLE_GENDERS);
-    } while (!validgend(ro,ra,g));
+	fully_specified_role = FALSE;
+    }
+    while (!validgend(ro,ra,g)) {
+	g = rn2(ROLE_GENDERS);
+    }
     gender[g]->setChecked(TRUE);
     selectGender(g);
 
-    int a;
-    do {
+    int a = flags.initalign;
+    if (a == -1) {
 	a = rn2(ROLE_ALIGNS);
-    } while (!validalign(ro,ra,a));
+	fully_specified_role = FALSE;
+    }
+    while (!validalign(ro,ra,a)) {
+	a = rn2(ROLE_ALIGNS);
+    }
     alignment[a]->setChecked(TRUE);
     selectAlignment(g);
 
@@ -717,6 +1128,10 @@
 
 void NetHackQtPlayerSelector::selectRole()
 {
+    int ra = race->selectedItemNumber();
+    int ro = role->selectedItemNumber();
+    if (ra == -1 || ro == -1) return;
+
 #ifndef QT_CHOOSE_RACE_FIRST
     selectRace();
 #else
@@ -725,7 +1140,6 @@
     int j;
     NhPSListViewItem* item;
     item = (NhPSListViewItem*)role->firstChild();
-    int ra = race->selectedItemNumber();
     for (j=0; roles[j].name.m; j++) {
 	bool v = validrace(j,ra);
 	item->setSelectable(TRUE);
@@ -750,16 +1164,18 @@
 
 void NetHackQtPlayerSelector::selectRace()
 {
+    int ra = race->selectedItemNumber();
+    int ro = role->selectedItemNumber();
+    if (ra == -1 || ro == -1) return;
+
 #ifdef QT_CHOOSE_RACE_FIRST
     selectRole();
-    flags.initrace = race->selectedItemNumber();
 #else
     QListViewItem* i=race->currentItem();
     QListViewItem* valid=0;
     int j;
     NhPSListViewItem* item;
     item = (NhPSListViewItem*)race->firstChild();
-    int ro = role->selectedItemNumber();
     for (j=0; races[j].noun; j++) {
 	bool v = validrace(ro,j);
 	item->setSelectable(TRUE);
@@ -851,11 +1267,23 @@
 
 bool NetHackQtPlayerSelector::Choose()
 {
-    centerOnMain(this);
+    if (fully_specified_role) return TRUE;
+
+#if defined(QWS) // probably safe with Qt 3, too (where show!=exec in QDialog).
+    if ( qt_compact_mode ) {
+	showMaximized();
+    } else
+#endif
+    {
+	adjustSize();
+	centerOnMain(this);
+    }
+
     if ( exec() ) {
 	return TRUE;
-    } else
+    } else {
 	return FALSE;
+    }
 }
 
 
@@ -871,6 +1299,7 @@
     okay=new QPushButton("Okay",this);
     connect(okay,SIGNAL(clicked()),this,SLOT(accept()));
     connect(&input,SIGNAL(returnPressed()),this,SLOT(accept()));
+    okay->setDefault(TRUE);
 
     setFocusPolicy(StrongFocus);
 }
@@ -994,18 +1423,45 @@
     setBackgroundColor(black);
     viewport.setBackgroundColor(black);
 
-    pet_annotation = QPixmap(pet_mark_xpm);
+    pet_annotation = QPixmap(qt_compact_mode ? pet_mark_small_xpm : pet_mark_xpm);
 
     cursor.setX(0);
     cursor.setY(0);
     Clear();
 
     connect(qt_settings,SIGNAL(tilesChanged()),this,SLOT(updateTiles()));
+    connect(&viewport, SIGNAL(contentsMoving(int,int)), this,
+		SLOT(moveMessages(int,int)));
 
     updateTiles();
     //setFocusPolicy(StrongFocus);
 }
 
+void NetHackQtMapWindow::moveMessages(int x, int y)
+{
+    QRect u = messages_rect;
+    messages_rect.moveTopLeft(QPoint(x,y));
+    u |= messages_rect;
+    update(u);
+}
+
+void NetHackQtMapWindow::clearMessages()
+{
+    messages = "";
+    update(messages_rect);
+    messages_rect = QRect();
+}
+
+void NetHackQtMapWindow::putMessage(int attr, const char* text)
+{
+    if ( !messages.isEmpty() )
+	messages += "\n";
+    messages += text;
+    QFontMetrics fm = fontMetrics();
+    messages_rect = fm.boundingRect(viewport.contentsX(),viewport.contentsY(),viewport.width(),0, WordBreak|AlignTop|AlignLeft|DontClip, messages);
+    update(messages_rect);
+}
+
 void NetHackQtMapWindow::updateTiles()
 {
     NetHackQtGlyphs& glyphs = qt_settings->glyphs();
@@ -1016,10 +1472,12 @@
 
     viewport.verticalScrollBar()->setSteps(gh,gh);
     viewport.horizontalScrollBar()->setSteps(gw,gw);
+    /*
     viewport.setMaximumSize(
 	gw*COLNO + viewport.verticalScrollBar()->width(),
 	gh*ROWNO + viewport.horizontalScrollBar()->height()
     );
+    */
     viewport.updateScrollBars();
 
     change.clear();
@@ -1152,66 +1610,13 @@
 	    for (int i=garea.left(); i<=garea.right(); i++) {
 		unsigned short g=Glyph(i,j);
 		uchar ch;
-		
-		/* (from wintty, naturally)
-		 *
-		 *  Map the glyph back to a character.
-		 *
-		 *  Warning:  For speed, this makes an assumption on the order of
-		 *		  offsets.  The order is set in display.h.
-		 */
-
-
-#ifdef TEXTCOLOR
-		int	    color;
-
-#define zap_color(n)  color = iflags.use_color ? zapcolors[n] : NO_COLOR
-#define cmap_color(n) color = iflags.use_color ? defsyms[n].color : NO_COLOR
-#define obj_color(n)  color = iflags.use_color ? objects[n].oc_color : NO_COLOR
-#define mon_color(n)  color = iflags.use_color ? mons[n].mcolor : NO_COLOR
-#define pet_color(n)  color = iflags.use_color ? mons[n].mcolor : NO_COLOR
-#define warn_color(n) color = iflags.use_color ? def_warnsyms[n].color : NO_COLOR
-
-# else /* no text color */
+		int color, och;
+		unsigned special;
 
-#define zap_color(n)
-#define cmap_color(n)
-#define obj_color(n)
-#define mon_color(n)
-#define pet_color(c)
-#define warn_color(c)
 		painter.setPen( green );
-#endif
-
-		if ((offset = (g - GLYPH_WARNING_OFF)) >= 0) { 	  /* a warning flash */
-		    ch = warnsyms[offset];
-		    warn_color(offset);
-		} else if ((offset = (g - GLYPH_SWALLOW_OFF)) >= 0) {	/* swallow */
-		    /* see swallow_to_glyph() in display.c */
-		    ch = (uchar) showsyms[S_sw_tl + (offset & 0x7)];
-		    mon_color(offset >> 3);
-		} else if ((offset = (g - GLYPH_ZAP_OFF)) >= 0) {	/* zap beam */
-		    /* see zapdir_to_glyph() in display.c */
-		    ch = showsyms[S_vbeam + (offset & 0x3)];
-		    zap_color((offset >> 2));
-		} else if ((offset = (g - GLYPH_CMAP_OFF)) >= 0) {	/* cmap */
-		    ch = showsyms[offset];
-		    cmap_color(offset);
-		} else if ((offset = (g - GLYPH_OBJ_OFF)) >= 0) {	/* object */
-		    ch = oc_syms[(int)objects[offset].oc_class];
-		    obj_color(offset);
-		} else if ((offset = (g - GLYPH_BODY_OFF)) >= 0) {	/* a corpse */
-		    ch = oc_syms[(int)objects[CORPSE].oc_class];
-		    mon_color(offset);
-		} else if ((offset = (g - GLYPH_PET_OFF)) >= 0) {	/* a pet */
-		    ch = monsyms[(int)mons[offset].mlet];
-		    pet_color(offset);
-		} else {							/* a monster */
-		    ch = monsyms[(int)mons[g].mlet];
-		    mon_color(g);
-		}
-		// end of wintty code
-
+		/* map glyph to character and color */
+    		mapglyph(g, &och, &color, &special, i, j);
+		ch = (uchar)och;
 #ifdef TEXTCOLOR
 		painter.setPen( nhcolor_to_pen(color) );
 #endif
@@ -1232,6 +1637,8 @@
 		}
 	    }
 	}
+
+	painter.setFont(font());
     } else
 #endif
     {
@@ -1280,6 +1687,15 @@
 	    qt_settings->glyphs().width(),qt_settings->glyphs().height());
     }
 
+    if (area.intersects(messages_rect)) {
+	painter.setPen(black);
+	painter.drawText(viewport.contentsX()+1,viewport.contentsY()+1,
+	    viewport.width(),0, WordBreak|AlignTop|AlignLeft|DontClip, messages);
+	painter.setPen(white);
+	painter.drawText(viewport.contentsX(),viewport.contentsY(),
+	    viewport.width(),0, WordBreak|AlignTop|AlignLeft|DontClip, messages);
+    }
+
     painter.end();
 }
 
@@ -1485,6 +1901,7 @@
     list(new NetHackQtScrollText(::iflags.msg_history))
 {
     ::iflags.window_inited = 1;
+    map = 0;
     connect(qt_settings,SIGNAL(fontChanged()),this,SLOT(updateFont()));
     updateFont();
 }
@@ -1497,9 +1914,17 @@
 
 QWidget* NetHackQtMessageWindow::Widget() { return list; }
 
+void NetHackQtMessageWindow::setMap(NetHackQtMapWindow* m)
+{
+    map = m;
+    updateFont();
+}
+
 void NetHackQtMessageWindow::updateFont()
 {
     list->setFont(qt_settings->normalFont());
+    if ( map )
+	map->setFont(qt_settings->normalFont());
 }
 
 void NetHackQtMessageWindow::Scroll(int dx, int dy)
@@ -1509,6 +1934,8 @@
 
 void NetHackQtMessageWindow::Clear()
 {
+    if ( map )
+	map->clearMessages();
     if (list->uncleared) {
 	list->uncleared=0;
 	changed=TRUE;
@@ -1536,6 +1963,9 @@
 
     // Force scrollbar to bottom
     // XXX list->setTopItem(list->count());
+
+    if ( map )
+	map->putMessage(attr, text);
 }
 
 
@@ -1616,7 +2046,12 @@
 }
 void NetHackQtLabelledIcon::show()
 {
-    if (!isVisible()) highlight(hl_bad);
+#if QT_VERSION >= 300
+    if (isHidden())
+#else
+    if (!isVisible())
+#endif
+	highlight(hl_bad);
     QWidget::show();
 }
 void NetHackQtLabelledIcon::highlightWhenChanging()
@@ -1965,7 +2400,7 @@
  */
 void NetHackQtStatusWindow::updateStats()
 {
-    if (!isVisible()) return;
+    if (!parentWidget()) return;
 
     char buf[BUFSZ];
 
@@ -2051,7 +2486,11 @@
 	dlevel.setLabel(buf,(long)depth(&u.uz));
     }
 
-    gold.setLabel("Au:",(long)u.ugold);
+#ifndef GOLDOBJ
+    gold.setLabel("Au:", u.ugold);
+#else
+    gold.setLabel("Au:", money_cnt(invent));
+#endif
     if (u.mtimedone) {
 	// You're a monster!
 
@@ -2357,20 +2796,27 @@
     invert->setEnabled(how==PICK_ANY);
     search->setEnabled(how!=PICK_NONE);
 
+    dialog->SetResult(-1);
+
     // 20 allows for scrollbar or spacing
     // 4 for frame borders
     int mh = QApplication::desktop()->height()*3/5;
-    dialog->resize(totalWidth()+20,
-	QMIN(totalHeight(), mh)+buth+4+(prompt.text().isNull() ? 0 : buth));
+    if ( qt_compact_mode && totalHeight() > mh ) {
+	// big, so make it fill
+	dialog->showMaximized();
+    } else {
+	dialog->resize(totalWidth()+20,
+	    QMIN(totalHeight(), mh)+buth+4+(prompt.text().isNull() ? 0 : buth));
+	if ( dialog->width() > QApplication::desktop()->width() )
+	    dialog->resize(QApplication::desktop()->width(),dialog->height()+16);
+	centerOnMain(dialog);
+	dialog->show();
+    }
 
-    dialog->SetResult(-1);
-    centerOnMain(dialog);
-    dialog->show();
     setFocus();
     while (dialog->result()<0) {
-	qApp->enter_loop();
 	// changed the defaults below to the values in wintype.h 000119 - azy
-	if (dialog->result()<0 && !keysource.Empty()) {
+	if (!keysource.Empty()) {
 	    char k=keysource.GetAscii();
 	    k=map_menu_cmd(k); /* added 000119 - azy */
 	    if (k=='\033')
@@ -2392,6 +2838,8 @@
 		}
 	    }
 	}
+	if (dialog->result()<0)
+	    qApp->enter_loop();
     }
     dialog->hide();
     int result=dialog->result();
@@ -2516,7 +2964,7 @@
 		AlignHCenter|AlignVCenter,text);
 	}
     break; case 1:
-	if (i.ch>=0) {
+	if ((signed char)i.ch >= 0) {
 	    char text[2]={i.ch,0};
 	    painter->drawText(0,0,cellWidth(col),cellHeight(),
 		AlignHCenter|AlignVCenter,text);
@@ -2669,6 +3117,11 @@
     riplines=n;
 }
 
+QSize NetHackQtRIP::sizeHint() const
+{
+    return pixmap->size();
+}
+
 void NetHackQtRIP::paintEvent(QPaintEvent* event)
 {
     if ( riplines ) {
@@ -2704,8 +3157,14 @@
     ok.setDefault(TRUE);
     connect(&ok,SIGNAL(clicked()),this,SLOT(accept()));
     connect(&search,SIGNAL(clicked()),this,SLOT(Search()));
-
     connect(qt_settings,SIGNAL(fontChanged()),this,SLOT(doUpdate()));
+
+    QVBoxLayout* vb = new QVBoxLayout(this);
+    vb->addWidget(&rip);
+    QHBoxLayout* hb = new QHBoxLayout(vb);
+    hb->addWidget(&ok);
+    hb->addWidget(&search);
+    vb->addWidget(lines);
 }
 
 void NetHackQtTextWindow::doUpdate()
@@ -2756,7 +3215,11 @@
     Sprintf(rip_line[NAME_LINE], "%s", plname);
 
     /* Put $ on stone */
+#ifndef GOLDOBJ
     Sprintf(rip_line[GOLD_LINE], "%ld Au", u.ugold);
+#else
+    Sprintf(rip_line[GOLD_LINE], "%ld Au", done_money);
+#endif
 
     /* Put together death description */
     switch (killer_format) {
@@ -2813,21 +3276,33 @@
 {
     if (str_fixed) {
 	lines->setFont(qt_settings->normalFixedFont());
+    } else {
+	lines->setFont(qt_settings->normalFont());
     }
 
-    int h=ok.height()*2;
+    int h=0;
     if (use_rip) {
 	h+=rip.height();
+	ok.hide();
+	search.hide();
 	rip.show();
     } else {
+	h+=ok.height()*2;
+	ok.show();
+	search.show();
 	rip.hide();
     }
     int mh = QApplication::desktop()->height()*3/5;
-    resize(QMAX(use_rip ? rip.width() : 200,
-	    lines->TotalWidth()+24),
-	QMIN(mh, lines->TotalHeight()+h));
-    centerOnMain(this);
-    show();
+    if ( qt_compact_mode && lines->TotalHeight() > mh || use_rip ) {
+	// big, so make it fill
+	showMaximized();
+    } else {
+	resize(QMAX(use_rip ? rip.width() : 200,
+		lines->TotalWidth()+24),
+	    QMIN(mh, lines->TotalHeight()+h));
+	centerOnMain(this);
+	show();
+    }
     if (block) {
 	setResult(-1);
 	while (result()==-1) {
@@ -2857,23 +3332,6 @@
     qApp->exit_loop();
 }
 
-void NetHackQtTextWindow::resizeEvent(QResizeEvent*)
-{
-    const int margin=8;
-    const int gutter=8;
-    const int butw = (width()-margin*2-gutter)/2;
-    const int buth=fontMetrics().height()*2;
-    int y=0;
-    if (use_rip) {
-	rip.setGeometry(0,0,width(),rip.height());
-	y+=rip.height();
-    }
-    y+=margin;
-    ok.setGeometry(margin, y, butw, buth);
-    search.setGeometry(margin+butw+gutter, y, butw, buth);
-    y+=buth+margin;
-    lines->setGeometry(0,y,width(),height()-y);
-}
 void NetHackQtTextWindow::keyPressEvent(QKeyEvent* e)
 {
     if ( e->ascii() != '\r' && e->ascii() != '\n' && e->ascii() != '\033' )
@@ -2891,8 +3349,8 @@
 	int current=lines->currentItem();
 	for (int i=1; i<lines->count(); i++) {
 	    int lnum=(i+current)%lines->count();
-	    const char* str=lines->text(lnum);
-	    if (strstr(str,line)) {
+	    QString str=lines->text(lnum);
+	    if (str.contains(line)) {
 		lines->setCurrentItem(lnum);
 		lines->centerCurrentItem();
 		return;
@@ -2982,132 +3440,162 @@
     painter.end();
 }
 
+class SmallToolButton : public QToolButton {
+public:
+    SmallToolButton(const QPixmap & pm, const QString &textLabel,
+                 const QString& grouptext,
+                 QObject * receiver, const char* slot,
+                 QToolBar * parent) :
+	QToolButton(pm, textLabel,
+#if QT_VERSION < 210
+		QString::null,
+#else
+		grouptext,
+#endif
+		    receiver, slot, parent)
+    {
+    }
+
+    QSize sizeHint() const
+    {
+	// get just a couple more pixels for the map
+	return QToolButton::sizeHint()-QSize(0,2);
+    }
+};
 
 
 NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) :
-    message(0), map(0), status(0), invusage(this),
-#ifdef KDE
-    menubar(new KMenuBar(this)),
-#else
-    menubar(new QMenuBar(this)),
-#endif
+    message(0), map(0), status(0), invusage(0),
     keysink(ks)
 {
-    setCaption("Qt NetHack");
-    setIcon(QPixmap(nh_icon));
-
-    setBackgroundColor(black);
-#ifndef KDE
-    menubar->setSeparator(QMenuBar::InWindowsStyle);
+    QToolBar* toolbar = new QToolBar(this);
+#if QT_VERSION >= 210
+    setToolBarsMovable(FALSE);
+    toolbar->setHorizontalStretchable(TRUE);
+    toolbar->setVerticalStretchable(TRUE);
 #endif
+    addToolBar(toolbar);
+    menubar = menuBar();
+
+    setCaption("Qt NetHack");
+    if ( qt_compact_mode )
+	setIcon(QPixmap(nh_icon_small));
+    else
+	setIcon(QPixmap(nh_icon));
 
     QPopupMenu* game=new QPopupMenu;
     QPopupMenu* apparel=new QPopupMenu;
-    QPopupMenu* action=new QPopupMenu;
+    QPopupMenu* act1=new QPopupMenu;
+    QPopupMenu* act2 = qt_compact_mode ? new QPopupMenu : act1;
     QPopupMenu* magic=new QPopupMenu;
-    QPopupMenu* nonaction=new QPopupMenu;
+    QPopupMenu* info=new QPopupMenu;
+
+    QPopupMenu *help;
 
 #ifdef KDE
-    QPopupMenu *help = kapp->getHelpMenu( TRUE, "" );
+    help = kapp->getHelpMenu( TRUE, "" );
     help->insertSeparator();
 #else
-    QPopupMenu* help = new QPopupMenu;
+    help = qt_compact_mode ? info : new QPopupMenu;
 #endif
 
+    enum { OnDesktop=1, OnHandhelds=2 };
     struct Macro {
 	QPopupMenu* menu;
 	const char* name;
 	const char* action;
+	int flags;
     } item[] = {
-	{ game,		0, 0 },
-	{ game,		"Version\tv",           "v" },
-	{ game,		"Compilation\tAlt-V",     "\366" },
-	{ game,		"History\tShift-V",           "V" },
-	{ game,		"Redraw\tCtrl-R",          "\022" },
-	{ game,		"Options\tShift-O",           "O" },
-	{ game,		"Explore mode\tShift-X",      "X" },
-	{ game,		0, 0 },
-	{ game,		"Save\tShift-S",              "S" },
-	{ game,		"Quit\tAlt-Q",                "\361" },
+	{ game,		0, 0, 3},
+	{ game,		"Version\tv",           "v", 3},
+	{ game,		"Compilation\tAlt+V",     "\366", 3},
+	{ game,		"History\tShift+V",           "V", 3},
+	{ game,		"Redraw\tCtrl+R",          "\022", 0}, // useless
+	{ game,		"Options\tShift+O",           "O", 3},
+	{ game,		"Explore mode\tShift+X",      "X", 3},
+	{ game,		0, 0, 3},
+	{ game,		"Save\tShift+S",              "Sy", 3},
+	{ game,		"Quit\tAlt+Q",                "\361", 3},
 
-	{ apparel,	"Apparel off\tShift-A",       "A" },
-	{ apparel,	0, 0 },
-	{ apparel,	"Wield weapon\tw",      "w" },
-	{ apparel,	"Exchange weapons\tx",      "x" },
-	{ apparel,	"Two weapon combat\t#two",      "#tw" },
-	{ apparel,	0, 0 },
-	{ apparel,	"Wear armour\tShift-W",       "W" },
-	{ apparel,	"Take off armour\tShift-T",   "T" },
-	{ apparel,	0, 0 },
-	{ apparel,	"Put on non-armour\tShift-P", "P" },
-	{ apparel,	"Remove non-armour\tShift-R", "R" },
+	{ apparel,	"Apparel off\tShift+A",       "A", 2},
+	{ apparel,	"Remove many\tShift+A",       "A", 1},
+	{ apparel,	0, 0, 3},
+	{ apparel,	"Wield weapon\tw",      "w", 3},
+	{ apparel,	"Exchange weapons\tx",      "x", 3},
+	{ apparel,	"Two weapon combat\t#two",      "#tw", 3},
+	{ apparel,	"Load quiver\tQ",       "Q", 3},
+	{ apparel,	0, 0, 3},
+	{ apparel,	"Wear armour\tShift+W",       "W", 3},
+	{ apparel,	"Take off armour\tShift+T",   "T", 3},
+	{ apparel,	0, 0, 3},
+	{ apparel,	"Put on non-armour\tShift+P", "P", 3},
+	{ apparel,	"Remove non-armour\tShift+R", "R", 3},
 
-	{ action,	"Again\tCtrl-A",           "\001" },
-	{ action,	0, 0 },
-	{ action,	"Get\t,",               "," },
-	{ action,	"Loot\tAlt-L",            "\354" },
-	{ action,	"Sit\tAlt-S",             "\363" },
-	{ action,	"Force\tAlt-F",           "\346" },
-	{ action,	"Kick\tCtrl-D",              "\004" },
-	{ action,	"Jump\tAlt-J",            "\352" },
-	{ action,	"Wipe face\tAlt-W",       "\367" },
-	{ action,	"Throw\tt",             "t" },
-	{ action,	"Load quiver\tQ",       "Q" },
-	{ action,	"Fire from quiver\tf",  "f" },
-	{ action,	"Fight\tF",             "F" },
-	{ action,	"Open door\to",         "o" },
-	{ action,	"Close door\tc",        "c" },
-	{ action,	"Drop\td?",             "d?" },
-	{ action,	"Drop many\tShift-D",         "D" },
-	{ action,	"Eat\te?",              "e?" },
-	{ action,	"Engrave\tShift-E",           "E" },
-	{ action,	"Apply\ta?",            "a?" },
-	{ action,	0, 0 },
-	{ action,	"Ride\t#ri",            "#ri" },
-	{ action,	"Up\t<",                "<" },
-	{ action,	"Down\t>",              ">" },
-	{ action,	"Rest\t.",              "." },
-	{ action,	"Search\ts",            "s" },
-	{ action,	0, 0 },
-	{ action,	"Chat\tAlt-C",            "\343" },
-	{ action,	"Pay\tp",               "p" },
+	{ act1,	"Again\tCtrl+A",           "\001", 2},
+	{ act1,	0, 0, 3},
+	{ act1,	"Apply\ta?",            "a?", 3},
+	{ act1,	"Chat\tAlt+C",            "\343", 3},
+	{ act1,	"Close door\tc",        "c", 3},
+	{ act1,	"Down\t>",              ">", 3},
+	{ act1,	"Drop many\tShift+D",         "D", 2},
+	{ act1,	"Drop\td?",             "d?", 2},
+	{ act1,	"Eat\te?",              "e?", 2},
+	{ act1,	"Engrave\tShift+E",           "E", 3},
+	{ act1,	"Fight\tF",             "F", 3},
+	{ act1,	"Fire from quiver\tf",  "f", 2},
+	{ act1,	"Force\tAlt+F",           "\346", 3},
+	{ act1,	"Get\t,",               ",", 2},
+	{ act1,	"Jump\tAlt+J",            "\352", 3},
+	{ act2,	"Kick\tCtrl+D",              "\004", 2},
+	{ act2,	"Loot\tAlt+L",            "\354", 3},
+	{ act2,	"Open door\to",         "o", 3},
+	{ act2,	"Pay\tp",               "p", 3},
+	{ act2,	"Rest\t.",              ".", 2},
+	{ act2,	"Ride\t#ri",            "#ri", 3},
+	{ act2,	"Search\ts",            "s", 3},
+	{ act2,	"Sit\tAlt+S",             "\363", 3},
+	{ act2,	"Throw\tt",             "t", 2},
+	{ act2,	"Up\t<",                "<", 3},
+	{ act2,	"Wipe face\tAlt+W",       "\367", 3},
 
-	{ magic,	"Quaff potion\tq",      "q?" },
-	{ magic,	"Read scroll/book\tr?", "r?" },
-	{ magic,	"Zap wand\tz?",         "z?" },
-	{ magic,	"Zap spell\tShift-Z?",        "Z?" },
-	{ magic,	"Dip\tAlt-D",             "\344" },
-	{ magic,	"Rub\tAlt-R",             "\362" },
-	{ magic,	"Invoke\tAlt-I",          "\351" },
-	{ magic,	0, 0 },
-	{ magic,	"Offer\tAlt-O",           "\357" },
-	{ magic,	"Pray\tAlt-P",            "\360" },
-	{ magic,	0, 0 },
-	{ magic,	"Teleport\tCtrl-T",        "\024" },
-	{ magic,	"Monster action\tAlt-M",  "\355" },
-	{ magic,	"Turn undead\tAlt-T",     "\364" },
+	{ magic,	"Quaff potion\tq",      "q?", 3},
+	{ magic,	"Read scroll/book\tr?", "r?", 3},
+	{ magic,	"Zap wand\tz?",         "z?", 3},
+	{ magic,	"Zap spell\tShift+Z",        "Z", 3},
+	{ magic,	"Dip\tAlt+D",             "\344", 3},
+	{ magic,	"Rub\tAlt+R",             "\362", 3},
+	{ magic,	"Invoke\tAlt+I",          "\351", 3},
+	{ magic,	0, 0, 3},
+	{ magic,	"Offer\tAlt+O",           "\357", 3},
+	{ magic,	"Pray\tAlt+P",            "\360", 3},
+	{ magic,	0, 0, 3},
+	{ magic,	"Teleport\tCtrl+T",        "\024", 3},
+	{ magic,	"Monster action\tAlt+M",  "\355", 3},
+	{ magic,	"Turn undead\tAlt+T",     "\364", 3},
 
-	{ nonaction,	"Inventory\ti",         "i" },
+	{ help,		"Help\t?",              "?", 3},
+	{ help,		0, 0, 3},
+	{ help,		"What is here\t:",      ":", 3},
+	{ help,		"What is there\t;",      ";", 3},
+	{ help,		"What is...\t/",        "/y", 2},
+	{ help,		0, 0, 1},
+
+	{ info,		"Inventory\ti",         "i", 3},
 #ifdef SLASHEM
-	{ nonaction,	"Angbandish inventory\t*",    "*" },
+	{ info,		"Angbandish inventory\t*",    "*", 3},
 #endif
-	{ nonaction,	"Conduct\t#co",         "#co" },
-	{ nonaction,	"Discoveries\t\\",      "\\" },
-	{ nonaction,	"List/reorder spells\t+",     "+" },
-	{ nonaction,	"Adjust letters\tAlt-A",  "\341" },
-	{ nonaction,	0, 0 },
-	{ nonaction,	"Name objects\tAlt-N",    "\356" },
-	{ nonaction,	"Name creature\tShift-C",      "C" },
-	{ nonaction,	0, 0 },
-	{ nonaction,	"Qualifications\tAlt-E",  "\345" },
-
-	{ help,		"Help\t?",              "?" },
-	{ help,		0, 0 },
-	{ help,		"What is here\t:",      ":" },
-	{ help,		"What is that\t;",      ";" },
-	{ help,		"What is...\t/",        "/y" },
+	{ info,		"Conduct\t#co",         "#co", 3},
+	{ info,		"Discoveries\t\\",      "\\", 3},
+	{ info,		"List/reorder spells\t+",     "+", 3},
+	{ info,		"Adjust letters\tAlt+A",  "\341", 2},
+	{ info,		0, 0, 3},
+	{ info,		"Name object\tAlt+N",    "\356y?", 3},
+	{ info,		"Name object type\tAlt+N",    "\356n?", 3},
+	{ info,		"Name creature\tShift+C",      "C", 3},
+	{ info,		0, 0, 3},
+	{ info,		"Qualifications\tAlt+E",  "\345", 3},
 
-	{ 0, 0, 0 }
+	{ 0, 0, 0, 0 }
     };
 
     int i;
@@ -3119,24 +3607,73 @@
 
     game->insertItem("Qt settings...",1000);
     help->insertItem("About Qt NetHack...",2000);
+    //help->insertItem("NetHack Guidebook...",3000);
+    help->insertSeparator();
 
     count=0;
     for (i=0; item[i].menu; i++) {
-	if (item[i].name) {
-	    item[i].menu->insertItem(item[i].name,count);
-	    macro[count++]=item[i].action;
-	} else {
-	    item[i].menu->insertSeparator();
+	if ( item[i].flags & (qt_compact_mode ? 1 : 2) ) {
+	    if (item[i].name) {
+		QString name = item[i].name;
+		if ( qt_compact_mode ) // accelerators aren't
+		    name.replace(QRegExp("\t.*"),"");
+		item[i].menu->insertItem(name,count);
+		macro[count++]=item[i].action;
+	    } else {
+		item[i].menu->insertSeparator();
+	    }
 	}
     }
 
     menubar->insertItem("Game",game);
-    menubar->insertItem("Apparel",apparel);
-    menubar->insertItem("Action",action);
-    menubar->insertItem("Magic",magic);
-    menubar->insertItem("Non-action",nonaction);
-    menubar->insertSeparator();
-    menubar->insertItem("Help",help);
+    menubar->insertItem("Gear",apparel);
+
+    if ( qt_compact_mode ) {
+	menubar->insertItem("A-J",act1);
+	menubar->insertItem("K-Z",act2);
+	menubar->insertItem("Magic",magic);
+	menubar->insertItem(QPixmap(info_xpm),info);
+	menubar->insertItem(QPixmap(map_xpm), this, SLOT(raiseMap()));
+	menubar->insertItem(QPixmap(msg_xpm), this, SLOT(raiseMessages()));
+	menubar->insertItem(QPixmap(stat_xpm), this, SLOT(raiseStatus()));
+    } else {
+	menubar->insertItem("Action",act1);
+	menubar->insertItem("Magic",magic);
+	menubar->insertItem("Info",info);
+	menubar->insertSeparator();
+	menubar->insertItem("Help",help);
+    }
+
+    QSignalMapper* sm = new QSignalMapper(this);
+    connect(sm, SIGNAL(mapped(const QString&)), this, SLOT(doKeys(const QString&)));
+    QToolButton* tb;
+    tb = new SmallToolButton( QPixmap(again_xpm),"Again","Action", sm, SLOT(map()), toolbar );
+    sm->setMapping(tb, "\001" );
+    tb = new SmallToolButton( QPixmap(get_xpm),"Get","Action", sm, SLOT(map()), toolbar );
+    sm->setMapping(tb, "," );
+    tb = new SmallToolButton( QPixmap(kick_xpm),"Kick","Action", sm, SLOT(map()), toolbar );
+    sm->setMapping(tb, "\004" );
+    tb = new SmallToolButton( QPixmap(throw_xpm),"Throw","Action", sm, SLOT(map()), toolbar );
+    sm->setMapping(tb, "t" );
+    tb = new SmallToolButton( QPixmap(fire_xpm),"Fire","Action", sm, SLOT(map()), toolbar );
+    sm->setMapping(tb, "f" );
+    tb = new SmallToolButton( QPixmap(drop_xpm),"Drop","Action", sm, SLOT(map()), toolbar );
+    sm->setMapping(tb, "D" );
+    tb = new SmallToolButton( QPixmap(eat_xpm),"Eat","Action", sm, SLOT(map()), toolbar );
+    sm->setMapping(tb, "e" );
+    tb = new SmallToolButton( QPixmap(rest_xpm),"Rest","Action", sm, SLOT(map()), toolbar );
+    sm->setMapping(tb, "." );
+    tb = new SmallToolButton( QPixmap(cast_a_xpm),"Cast A","Magic", sm, SLOT(map()), toolbar );
+    sm->setMapping(tb, "Za" );
+    tb = new SmallToolButton( QPixmap(cast_b_xpm),"Cast B","Magic", sm, SLOT(map()), toolbar );
+    sm->setMapping(tb, "Zb" );
+    tb = new SmallToolButton( QPixmap(cast_c_xpm),"Cast C","Magic", sm, SLOT(map()), toolbar );
+    sm->setMapping(tb, "Zc" );
+    if ( !qt_compact_mode ) {
+	QWidget* filler = new QWidget(toolbar);
+	filler->setBackgroundMode(PaletteButton);
+	toolbar->setStretchableWidget(filler);
+    }
 
     connect(menubar,SIGNAL(activated(int)),this,SLOT(doMenuItem(int)));
 
@@ -3172,7 +3709,60 @@
     }
 
     setGeometry(x,y,w,h);
+
+    if ( qt_compact_mode ) {
+	stack = new QWidgetStack(this);
+	setCentralWidget(stack);
+    } else {
+	setCentralWidget(new QWidget(this));
+	invusage = new NetHackQtInvUsageWindow(centralWidget());
+    }
 }
+
+void NetHackQtMainWindow::raiseMap()
+{
+    stack->raiseWidget(0);
+}
+
+void NetHackQtMainWindow::raiseMessages()
+{
+    stack->raiseWidget(1);
+}
+
+void NetHackQtMainWindow::raiseStatus()
+{
+    stack->raiseWidget(2);
+}
+
+class NetHackMimeSourceFactory : public QMimeSourceFactory {
+public:
+    const QMimeSource* data(const QString& abs_name) const
+    {
+	const QMimeSource* r = 0;
+	if ( (NetHackMimeSourceFactory*)this == QMimeSourceFactory::defaultFactory() )
+	    r = QMimeSourceFactory::data(abs_name);
+	else
+	    r = QMimeSourceFactory::defaultFactory()->data(abs_name);
+	if ( !r ) {
+	    int sl = abs_name.length();
+	    do {
+		sl = abs_name.findRev('/',sl-1);
+		QString name = sl>=0 ? abs_name.mid(sl+1) : abs_name;
+		int dot = name.findRev('.');
+		if ( dot >= 0 )
+		    name = name.left(dot);
+		if ( name == "map" )
+		    r = new QImageDrag(QImage(map_xpm));
+		else if ( name == "msg" )
+		    r = new QImageDrag(QImage(msg_xpm));
+		else if ( name == "stat" )
+		    r = new QImageDrag(QImage(stat_xpm));
+	    } while (!r && sl>0);
+	}
+	return r;
+    }
+};
+
 void NetHackQtMainWindow::doMenuItem(int id)
 {
     switch (id) {
@@ -3180,15 +3770,33 @@
 	centerOnMain(qt_settings);
 	qt_settings->show();
 	break;
-      case 2000: {
-	    QMessageBox::about(this,  "About Qt NetHack", aboutMsg());
-	} break;
+      case 2000:
+	QMessageBox::about(this,  "About Qt NetHack", aboutMsg());
+	break;
+      case 3000: {
+	    QDialog dlg(this,0,TRUE);
+	    (new QVBoxLayout(&dlg))->setAutoAdd(TRUE);
+	    QTextBrowser browser(&dlg);
+	    NetHackMimeSourceFactory ms;
+	    browser.setMimeSourceFactory(&ms);
+	    browser.setSource(QDir::currentDirPath()+"/Guidebook.html");
+	    if ( qt_compact_mode )
+		dlg.showMaximized();
+	    dlg.exec();
+	}
+	break;
       default:
-	keysink.Put(macro[id]);
-	qApp->exit_loop();
+	if ( id >= 0 )
+	    doKeys(macro[id]);
     }
 }
 
+void NetHackQtMainWindow::doKeys(const QString& k)
+{
+    keysink.Put(k);
+    qApp->exit_loop();
+}
+
 void NetHackQtMainWindow::AddMessageWindow(NetHackQtMessageWindow* window)
 {
     message=window;
@@ -3224,7 +3832,8 @@
 
 void NetHackQtMainWindow::updateInventory()
 {
-    invusage.repaint(FALSE);
+    if ( invusage )
+	invusage->repaint(FALSE);
 }
 
 void NetHackQtMainWindow::fadeHighlighting()
@@ -3236,21 +3845,23 @@
 
 void NetHackQtMainWindow::layout()
 {
+    if ( qt_compact_mode )
+	return;
     if (message && map && status) {
 	QSize maxs=map->Widget()->maximumSize();
 	int maph=QMIN(height()*2/3,maxs.height());
 
-	int y=menubar->height();
-	int h=height()-y;
+	QWidget* c = centralWidget();
+	int h=c->height();
 	int toph=h-maph;
 	int iuw=3*qt_settings->glyphs().width();
-	int topw=(width()-iuw)/2;
+	int topw=(c->width()-iuw)/2;
 
-	message->Widget()->setGeometry(0,y,topw,toph);
-	invusage.setGeometry(topw,y,iuw,toph);
-	status->Widget()->setGeometry(topw+iuw,y,topw,toph);
-	map->Widget()->setGeometry(QMAX(0,(width()-maxs.width())/2),
-				   y+toph,width(),maph);
+	message->Widget()->setGeometry(0,0,topw,toph);
+	invusage->setGeometry(topw,0,iuw,toph);
+	status->Widget()->setGeometry(topw+iuw,0,topw,toph);
+	map->Widget()->setGeometry(QMAX(0,(c->width()-maxs.width())/2),
+				   toph,c->width(),maph);
     }
 }
 
@@ -3266,15 +3877,32 @@
 {
     // Global key controls
 
+    // For desktop, arrow keys scroll map, since we don't want players
+    // to think that's the way to move. For handhelds, the normal way is to
+    // click-to-travel, so we allow the cursor keys for fine movements.
+
+    const char* d = iflags.num_pad ? ndir : sdir; 
     switch (event->key()) {
      case Key_Up:
-	if (map) map->Scroll(0,-1);
+	if (qt_compact_mode)
+	    keysink.Put(d[2]);
+	else
+	    if (map) map->Scroll(0,-1);
     break; case Key_Down:
-	if (map) map->Scroll(0,+1);
+	if (qt_compact_mode)
+	    keysink.Put(d[6]);
+	else
+	    if (map) map->Scroll(0,+1);
     break; case Key_Left:
-	if (map) map->Scroll(-1,0);
+	if (qt_compact_mode)
+	    keysink.Put(d[0]);
+	else
+	    if (map) map->Scroll(-1,0);
     break; case Key_Right:
-	if (map) map->Scroll(+1,0);
+	if (qt_compact_mode)
+	    keysink.Put(d[4]);
+	else
+	    if (map) map->Scroll(+1,0);
     break; case Key_Prior:
 	if (message) message->Scroll(0,-1);
     break; case Key_Next:
@@ -3289,20 +3917,17 @@
     if ( program_state.something_worth_saving ) {
 	switch ( QMessageBox::information( this, "NetHack",
 	    "This will end your NetHack session",
-	    "&Save", "&Quit", "&Cancel", 0, 2 ) )
+	    "&Save", "&Cancel", 0, 1 ) )
 	{
 	    case 0:
 		// See dosave() function
 		if (dosave0()) {
 		    u.uhp = -1;
+		    NetHackQtBind::qt_exit_nhwindows(0);
 		    terminate(EXIT_SUCCESS);
 		}
 		break;
 	    case 1:
-		u.uhp = -1;
-		terminate(EXIT_SUCCESS);
-		break;
-	    case 2:
 		break; // ignore the event
 	}
     } else {
@@ -3314,12 +3939,20 @@
 {
     if (message && map && status) {
 	QPoint pos(0,0);
-	message->Widget()->recreate(this,0,pos);
-	map->Widget()->recreate(this,0,pos);
-	status->Widget()->recreate(this,0,pos);
-
-	layout();
-	show();
+	QWidget* p = qt_compact_mode ? stack : centralWidget();
+	message->Widget()->recreate(p,0,pos);
+	map->Widget()->recreate(p,0,pos);
+	status->Widget()->recreate(p,0,pos);
+	if ( qt_compact_mode ) {
+	    message->setMap(map);
+	    stack->addWidget(map->Widget(), 0);
+	    stack->addWidget(message->Widget(), 1);
+	    stack->addWidget(status->Widget(), 2);
+	    raiseMap();
+	} else {
+	    layout();
+	}
+	showMaximized();
     } else if (isVisible()) {
 	hide();
     }
@@ -3336,12 +3969,82 @@
 
 char NetHackQtYnDialog::Exec()
 {
-    if (choices) {
-	QButtonGroup group(question, this);
+    QString ch(choices);
+    int ch_per_line=6;
+    QString qlabel;
+    QString enable;
+    if ( qt_compact_mode && !choices ) {
+	// expand choices from prompt
+	// ##### why isn't choices set properly???
+	const char* c=question;
+	while ( *c && *c != '[' )
+	    c++;
+	qlabel = QString(question).left(c-question);
+	if ( *c ) {
+	    c++;
+	    if ( *c == '-' )
+		ch.append(*c++);
+	    char from=0;
+	    while ( *c && *c != ']' && *c != ' ' ) {
+		if ( *c == '-' ) {
+		    from = c[-1];
+		} else if ( from ) {
+		    for (char f=from+1; f<=*c; f++)
+			ch.append(f);
+		    from = 0;
+		} else {
+		    ch.append(*c);
+		    from = 0;
+		}
+		c++;
+	    }
+	    if ( *c == ' ' ) {
+		while ( *c && *c != ']' ) {
+		    if ( *c == '*' || *c == '?' )
+			ch.append(*c);
+		    c++;
+		}
+	    }
+	}
+	if ( strstr(question, "what direction") ) {
+	    // We replace this regardless, since sometimes you get choices.
+	    const char* d = iflags.num_pad ? ndir : sdir; 
+	    enable=ch;
+	    ch="";
+	    ch.append(d[1]);
+	    ch.append(d[2]);
+	    ch.append(d[3]);
+	    ch.append(d[0]);
+	    ch.append('.');
+	    ch.append(d[4]);
+	    ch.append(d[7]);
+	    ch.append(d[6]);
+	    ch.append(d[5]);
+	    ch.append(d[8]);
+	    ch.append(d[9]);
+	    ch_per_line = 3;
+	    def = ' ';
+	} else {
+	    // Hmm... they'll have to use a virtual keyboard
+	}
+    } else {
+	qlabel = question;
+    }
+    if (!ch.isNull()) {
+	QVBoxLayout vb(this);
+	vb.setAutoAdd(TRUE);
+	bool bigq = qlabel.length()>40;
+	if ( bigq ) {
+	    QLabel* q = new QLabel(qlabel,this);
+	    q->setAlignment(AlignLeft|WordBreak);
+	    q->setMargin(4);
+	}
+	QButtonGroup group(ch_per_line, Horizontal,
+	    bigq ? QString::null : qlabel, this);
 
-	int nchoices=strlen(choices);
+	int nchoices=ch.length();
 
-	bool allow_count=strchr(choices,'#')!=0;
+	bool allow_count=ch.contains('#');
 
 	const int margin=8;
 	const int gutter=8;
@@ -3351,11 +4054,14 @@
 	int butsize=fontMetrics().height()*2+5;
 
 	QPushButton* button;
-	for (int i=0; i<nchoices && choices[i]!='\033'; i++) {
-	    char text[2]={choices[i],0};
-	    button=new QPushButton(text,&group);
-	    button->setGeometry(x,y,butsize,butsize); // Square
-	    if (choices[i]==def) button->setDefault(TRUE);
+	for (int i=0; i<nchoices && ch[i]!='\033'; i++) {
+	    button=new QPushButton(QString(ch[i]),&group);
+	    if ( !enable.isNull() ) {
+		if ( !enable.contains(ch[i]) )
+		    button->setEnabled(FALSE);
+	    }
+	    button->setFixedSize(butsize,butsize); // Square
+	    if (ch[i]==def) button->setDefault(TRUE);
 	    if (i%10==9) {
 		// last in row
 		x=margin;
@@ -3365,47 +4071,50 @@
 	    }
 	}
 
-	group.resize(margin*2+(gutter+button->width())*10,
-	    extra+margin*2+(gutter+button->height())*(nchoices/10+1));
-	connect(&group,SIGNAL(clicked(int)),this,SLOT(done(int)));
+	connect(&group,SIGNAL(clicked(int)),this,SLOT(doneItem(int)));
 
 	QLabel* lb=0;
 	QLineEdit* le=0;
 
 	if (allow_count) {
-	    lb=new QLabel("Count: ",this);
-	    le=new QLineEdit(this);
-	    lb->setGeometry(margin,group.height()+margin,group.width()*1/3,le->height());
-	    le->setGeometry(lb->geometry().right()+margin,lb->geometry().top(),
-		group.width()*2/3,le->height());
+	    QHBox *hb = new QHBox(this);
+	    lb=new QLabel("Count: ",hb);
+	    le=new QLineEdit(hb);
 	}
 
+	adjustSize();
 	centerOnMain(this);
 	show();
 	char choice=0;
+	char ch_esc=0;
+	for (int i=0; i<ch.length(); i++) {
+	    if (ch[i].latin1()=='q') ch_esc='q';
+	    else if (!ch_esc && ch[i].latin1()=='n') ch_esc='n';
+	}
+	setResult(-1);
 	while (!choice) {
-	    if (!result()) {
-		if (!keysource.Empty()) {
-		    char k=keysource.GetAscii();
-		    char ch_esc=0;
-		    for (int i=0; choices[i]; i++) {
-			if (choices[i]==k)
-			    choice=k;
-			if (choices[i]=='q') ch_esc='q';
-			else if (!ch_esc && choices[i]=='n') ch_esc='n';
-		    }
-		    if (!choice) {
-			if (k=='\033' && ch_esc)
-			    choice=ch_esc;
-			else if (k==' ' || k=='\r' || k=='\n')
-			    choice=def;
-			// else choice remains 0
-		    }
+	    if (!keysource.Empty()) {
+		char k=keysource.GetAscii();
+		char ch_esc=0;
+		for (int i=0; i<ch.length(); i++)
+		    if (ch[i].latin1()==k)
+			choice=k;
+		if (!choice) {
+		    if (k=='\033' && ch_esc)
+			choice=ch_esc;
+		    else if (k==' ' || k=='\r' || k=='\n')
+			choice=def;
+		    // else choice remains 0
 		}
-	    } else {
-		choice=choices[result()-1000];
+	    } else if ( result() == 0 ) {
+		choice = ch_esc ? ch_esc : def ? def : ' ';
+	    } else if ( result() == 1 ) {
+		choice = def ? def : ch_esc ? ch_esc : ' ';
+	    } else if ( result() >= 1000 ) {
+		choice = ch[result() - 1000].latin1();
 	    }
-	    qApp->enter_loop();
+	    if ( !choice )
+		qApp->enter_loop();
 	}
 	hide();
 	if (allow_count && !le->text().isEmpty()) {
@@ -3414,16 +4123,17 @@
 	}
 	return choice;
     } else {
-	QLabel label(question,this);
+	QLabel label(qlabel,this);
 	QPushButton cancel("Dismiss",this);
 	label.setFrameStyle(QFrame::Box|QFrame::Sunken);
 	label.setAlignment(AlignCenter);
-	label.resize(fontMetrics().width(question)+60,30+fontMetrics().height());
+	label.resize(fontMetrics().width(qlabel)+60,30+fontMetrics().height());
 	cancel.move(width()/2-cancel.width()/2,label.geometry().bottom()+8);
 	connect(&cancel,SIGNAL(clicked()),this,SLOT(reject()));
 	centerOnMain(this);
+	setResult(-1);
 	show();
-	while (!result() && keysource.Empty()) {
+	while (result()<0 && keysource.Empty()) {
 	    qApp->enter_loop();
 	}
 	hide();
@@ -3440,9 +4150,14 @@
     event->ignore();
 }
 
+void NetHackQtYnDialog::doneItem(int i)
+{
+    done(i+1000);
+}
+
 void NetHackQtYnDialog::done(int i)
 {
-    setResult(i+1000);
+    setResult(i);
     qApp->exit_loop();
 }
 
@@ -3464,10 +4179,10 @@
 	    tiles_per_row = 40;
 	}
     } else {
-        tiles_per_row = 1;
-        if (img.height()%total_tiles_used) {
-            impossible("Tile file \"%s\" has %d lines, not multiple of glyph count (%d)",
-               tile_file, img.height(), total_tiles_used);
+        tiles_per_row = TILES_PER_ROW;
+        if (img.width()%tiles_per_row) {
+            impossible("Tile file \"%s\" has %d columns, not multiple of row count (%d)",
+               tile_file, img.width(), tiles_per_row);
         }
     }
     int rows = ((total_tiles_used+tiles_per_row-1) / tiles_per_row);
@@ -3604,12 +4319,53 @@
 NetHackQtBind::NetHackQtBind(int& argc, char** argv) :
 #ifdef KDE
     KApplication(argc,argv)
+#elif defined(QWS) // not quite the right condition
+    QPEApplication(argc,argv)
 #else
     QApplication(argc,argv)
 #endif
 {
+    QPixmap pm("nhsplash.xpm");
+    if ( !pm.isNull() ) {
+	QVBox *vb = new QVBox(0,0,
+	    WStyle_Customize | WStyle_NoBorder | nh_WX11BypassWM | WStyle_StaysOnTop );
+	splash = vb;
+	QLabel *lsplash = new QLabel(vb);
+	lsplash->setAlignment(AlignCenter);
+	lsplash->setPixmap(pm);
+	QLabel* capt = new QLabel("Loading...",vb);
+	capt->setAlignment(AlignCenter);
+	if ( pm.mask() ) {
+	    lsplash->setFixedSize(pm.size());
+	    lsplash->setMask(*pm.mask());
+	}
+	splash->move((QApplication::desktop()->width()-pm.width())/2,
+		      (QApplication::desktop()->height()-pm.height())/2);
+	//splash->setGeometry(0,0,100,100);
+	if ( qt_compact_mode ) {
+	    splash->showMaximized();
+	} else {
+	    vb->setFrameStyle(QFrame::WinPanel|QFrame::Raised);
+	    vb->setMargin(10);
+	    splash->adjustSize();
+	    splash->show();
+	}
+
+	// force content refresh outside event loop
+	splash->repaint(FALSE);
+	lsplash->repaint(FALSE);
+	capt->repaint(FALSE);
+	qApp->flushX();
+
+    } else {
+	splash = 0;
+    }
     main = new NetHackQtMainWindow(keybuffer);
+#if defined(QWS) // not quite the right condition
+    showMainWidget(main);
+#else
     setMainWidget(main);
+#endif
     qt_settings=new NetHackQtSettings(main->width(),main->height());
 }
 
@@ -3656,29 +4412,146 @@
 	qt_askname();
 }
 
+NetHackQtSavedGameSelector::NetHackQtSavedGameSelector(const char** saved) :
+    QDialog(0,"sgsel",TRUE)
+{
+    QVBoxLayout *vbl = new QVBoxLayout(this,6);
+    QHBox* hb;
+
+    QLabel* logo = new QLabel(this); vbl->addWidget(logo);
+    logo->setAlignment(AlignCenter);
+    logo->setPixmap(QPixmap("nhsplash.xpm"));
+    QLabel* attr = new QLabel("by the NetHack DevTeam",this);
+    attr->setAlignment(AlignCenter);
+    vbl->addWidget(attr);
+    vbl->addStretch(2);
+    /*
+    QLabel* logo = new QLabel(hb);
+    hb = new QHBox(this);
+    vbl->addWidget(hb, AlignCenter);
+    logo->setPixmap(QPixmap(nh_icon));
+    logo->setAlignment(AlignRight|AlignVCenter);
+    new QLabel(nh_attribution,hb);
+    */
+
+    hb = new QHBox(this);
+    vbl->addWidget(hb, AlignCenter);
+    QPushButton* q = new QPushButton("Quit",hb);
+    connect(q, SIGNAL(clicked()), this, SLOT(reject()));
+    QPushButton* c = new QPushButton("New Game",hb);
+    connect(c, SIGNAL(clicked()), this, SLOT(accept()));
+    c->setDefault(TRUE);
+
+    QButtonGroup* bg = new QButtonGroup(3, Horizontal, "Saved Characters",this);
+    vbl->addWidget(bg);
+    connect(bg, SIGNAL(clicked(int)), this, SLOT(done(int)));
+    for (int i=0; saved[i]; i++) {
+	QPushButton* b = new QPushButton(saved[i],bg);
+	bg->insert(b, i+2);
+    }
+}
+
+int NetHackQtSavedGameSelector::choose()
+{
+#if defined(QWS) // probably safe with Qt 3, too (where show!=exec in QDialog).
+    if ( qt_compact_mode )
+	showMaximized();
+#endif
+    return exec()-2;
+}
+
+static char** get_saved_names()
+{
+    int myuid=getuid();
+    struct dirent **namelist;
+    int n = scandir("save", &namelist, 0, alphasort);;
+    if ( n > 0 ) {
+	int i,j=0;
+	char** result = (char**)malloc((n+1)*sizeof(char*)); /* at most */
+	for (i=0; i<n; i++) {
+	    int uid;
+	    char name[NAME_MAX];
+	    if ( sscanf( namelist[i]->d_name, "%d%s", &uid, name ) == 2 ) {
+		if ( uid == myuid ) {
+		    char* end = strstr(name,".gz");
+		    if ( !end ) end = strstr(name,".Z");
+		    if ( end ) *end = 0;
+		    result[j++] = strdup(name);
+		}
+	    }
+	}
+	result[j++] = 0;
+	return result;
+    } else {
+	return 0;
+    }
+}
+
+static void free_saved_names(char** saved)
+{
+    if ( saved ) {
+	int i=0;
+	while (saved[i]) free(saved[i++]);
+	free(saved);
+    }
+}
+
 void NetHackQtBind::qt_askname()
 {
     have_asked = TRUE;
 
     // We do it all here, and nothing in askname
 
-    NetHackQtPlayerSelector selector(keybuffer);
+    char** saved = get_saved_names();
+    int ch = -1;
+    if ( saved && *saved ) {
+	if ( splash ) splash->hide();
+	NetHackQtSavedGameSelector sgsel((const char**)saved);
+	ch = sgsel.choose();
+	if ( ch >= 0 )
+	    strcpy(plname,saved[ch]);
+    }
+    free_saved_names(saved);
 
-    if (selector.Choose()) {
-	// ...
-    } else {
-	clearlocks();
-	qt_exit_nhwindows(0);
-	terminate(0);
+    switch (ch) {
+      case -1:
+	if ( splash ) splash->hide();
+	if (NetHackQtPlayerSelector(keybuffer).Choose())
+	    return;
+      case -2:
+	break;
+      default:
+	return;
     }
+
+    // Quit
+    clearlocks();
+    qt_exit_nhwindows(0);
+    terminate(0);
 }
 
 void NetHackQtBind::qt_get_nh_event()
 {
 }
 
+#if defined(QWS)
+// Kludge to access lastWindowClosed() signal.
+class TApp : public QApplication {
+public:
+    TApp(int& c, char**v) : QApplication(c,v) {}
+    void lwc() { emit lastWindowClosed(); }
+};
+#endif
+ 
 void NetHackQtBind::qt_exit_nhwindows(const char *)
 {
+#if defined(QWS)
+    // Avoids bug in SHARP SL5500
+    ((TApp*)qApp)->lwc();
+    qApp->quit();
+#endif
+ 
+    delete instance; // ie. qApp
 }
 
 void NetHackQtBind::qt_suspend_nhwindows(const char *)
@@ -3722,6 +4595,19 @@
 	window=new NetHackQtTextWindow(keybuffer);
     }
 
+    // Note: use of isHidden does not work with Qt 2.1
+    if ( splash 
+#if QT_VERSION >= 300
+        && !main->isHidden()
+#else
+	&& main->isVisible()
+#endif
+	)
+    {
+	delete splash;
+	splash = 0;
+    }
+
     id_to_window[id] = window;
     return id;
 }
@@ -3955,7 +4841,7 @@
 #ifdef USE_POPUPS
 	// Improve some special-cases (DIRKS 08/02/23)
 	if (strcmp (choices,"ynq") == 0) {
-	    switch (QMessageBox::information (0,"NetHack",question,"&Yes","&No","&Quit",0,2))
+	    switch (QMessageBox::information (qApp->mainWidget(),"NetHack",question,"&Yes","&No","&Quit",0,2))
 	    {
 	      case 0: return 'y'; 
 	      case 1: return 'n'; 
@@ -3964,7 +4850,7 @@
 	}
 
 	if (strcmp (choices,"yn") == 0) {
-	    switch (QMessageBox::information(0,"NetHack",question,"&Yes", "&No",0,1))
+	    switch (QMessageBox::information(qApp->mainWidget(),"NetHack",question,"&Yes", "&No",0,1))
 	    {
 	      case 0: return 'y';
 	      case 1: return 'n'; 
@@ -4141,6 +5027,11 @@
 
 bool NetHackQtBind::notify(QObject *receiver, QEvent *event)
 {
+    // Ignore Alt-key navigation to menubar, it's annoying when you
+    // use Alt-Direction to move around.
+    if ( main && event->type()==QEvent::KeyRelease && main==receiver )
+	return TRUE;
+
     bool result=QApplication::notify(receiver,event);
     if (event->type()==QEvent::KeyPress) {
 	QKeyEvent* key_event=(QKeyEvent*)event;
@@ -4179,12 +5070,14 @@
 NetHackQtKeyBuffer NetHackQtBind::keybuffer;
 NetHackQtClickBuffer NetHackQtBind::clickbuffer;
 NetHackQtMainWindow* NetHackQtBind::main=0;
+QWidget* NetHackQtBind::splash=0;
 
 
 extern "C" struct window_procs Qt_procs;
 
 struct window_procs Qt_procs = {
     "Qt",
+    WC_COLOR|WC_HILITE_PET,
     NetHackQtBind::qt_init_nhwindows,
     NetHackQtBind::qt_player_selection,
     NetHackQtBind::qt_askname,
@@ -4238,13 +5131,15 @@
 #else
     genl_outrip,
 #endif
+    genl_preference_update,
 };
 
 extern "C" void play_usersound(const char* filename, int volume)
 {
 #ifdef USER_SOUNDS
-    // Qt 2.2 has sound
-    //QSound::play(filename,volume);
+#ifndef QT_NO_SOUND
+    QSound::play(filename);
+#endif
 #endif
 }
 
@@ -4252,3 +5147,6 @@
 #ifndef KDE
 #include "qt_kde0.moc"
 #endif
+#if QT_VERSION >= 300
+#include "qttableview.moc"
+#endif
diff -Naurd ../nethack-3.3.1/win/Qt/tileedit.cpp ./win/Qt/tileedit.cpp
--- ../nethack-3.3.1/win/Qt/tileedit.cpp Sat Nov 20 05:43:28 1999
+++ ./win/Qt/tileedit.cpp Fri Mar 22 14:40:55 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)tileedit.cpp	3.3	1999/11/19	*/
+/*	SCCS Id: @(#)tileedit.cpp	3.4	1999/11/19	*/
 /* Copyright (c) Warwick Allison, 1999. */
 /* NetHack may be freely redistributed.  See license for details. */
 /*
@@ -180,7 +180,7 @@
 {
     pen = rgb;
     for (penpixel = 0;
-	    penpixel<img.numColors()-1 && img.color(penpixel)!=pen.rgb();
+	    penpixel<img.numColors()-1 && (img.color(penpixel)&0xffffff)!=(pen.rgb()&0xffffff);
 	    penpixel++)
 	continue;
 }
@@ -217,6 +217,8 @@
 void TrivialTileEditor::mousePressEvent(QMouseEvent* e)
 {
     QPoint p = imagePoint(e->pos());
+    if ( !img.rect().contains(p) )
+	return;
     uchar& pixel = img.scanLine(p.y())[p.x()];
     if ( e->button() == LeftButton ) {
 	pixel = penpixel;
@@ -226,7 +228,8 @@
 	emit pick( img.color(pixel) );
     } else if ( e->button() == MidButton ) {
 	QPainter painter(this);
-	fill(painter,p,pixel);
+	if ( pixel != penpixel )
+	    fill(painter,p,pixel);
     }
 }
 
@@ -253,6 +256,8 @@
 void TrivialTileEditor::mouseMoveEvent(QMouseEvent* e)
 {
     QPoint p = imagePoint(e->pos());
+    if ( !img.rect().contains(p) )
+	return;
     uchar& pixel = img.scanLine(p.y())[p.x()];
     pixel = penpixel;
     QPainter painter(this);
diff -Naurd ../nethack-3.3.1/win/Qt/tileedit.h ./win/Qt/tileedit.h
--- ../nethack-3.3.1/win/Qt/tileedit.h Sat Nov 20 05:43:28 1999
+++ ./win/Qt/tileedit.h Fri Mar 22 14:40:55 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)tileedit.h	3.3	1999/11/19	*/
+/*	SCCS Id: @(#)tileedit.h	3.4	1999/11/19	*/
 /* Copyright (c) Warwick Allison, 1999. */
 /* NetHack may be freely redistributed.  See license for details. */
 #ifndef QNHTILEEDIT_H
diff -Naurd ../nethack-3.3.1/include/qt_clust.h ./include/qt_clust.h
--- ../nethack-3.3.1/include/qt_clust.h Sat Nov 20 05:43:27 1999
+++ ./include/qt_clust.h Fri Mar 22 14:40:55 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)qt_clust.h	3.3	1999/11/19	*/
+/*	SCCS Id: @(#)qt_clust.h	3.4	1999/11/19	*/
 /* Copyright (c) Warwick Allison, 1999. */
 /* NetHack may be freely redistributed.  See license for details. */
 
diff -Naurd ../nethack-3.3.1/include/qt_kde0.h ./include/qt_kde0.h
--- ../nethack-3.3.1/include/qt_kde0.h Sat Nov 20 05:43:28 1999
+++ ./include/qt_kde0.h Fri Mar 22 14:40:55 2002
@@ -1,10 +1,10 @@
-/*	SCCS Id: @(#)qt_kde0.h	3.3	1999/11/19	*/
+/*	SCCS Id: @(#)qt_kde0.h	3.4	1999/11/19	*/
 /* Copyright (c) Warwick Allison, 1999. */
 /* NetHack may be freely redistributed.  See license for details. */
 
 #ifndef QT_DUMMYKDE
 #define QT_DUMMYKDE
-class KTopLevelWidget : public QWidget {
+class KTopLevelWidget : public QMainWindow {
         Q_OBJECT
 };
 #endif
diff -Naurd ../nethack-3.3.1/include/qt_win.h ./include/qt_win.h
--- ../nethack-3.3.1/include/qt_win.h Sat Jan 22 01:10:00 2000
+++ ./include/qt_win.h Fri Mar 22 14:40:55 2002
@@ -1,8 +1,8 @@
-//	SCCS Id: @(#)qt_win.h	3.3	1999/11/19
+//	SCCS Id: @(#)qt_win.h	3.4	1999/11/19
 // Copyright (c) Warwick Allison, 1999.
 // NetHack may be freely redistributed.  See license for details.
 //
-// Qt Binding for NetHack 3.3
+// Qt Binding for NetHack 3.4
 //
 // Unfortunately, this doesn't use Qt as well as I would like,
 // primarily because NetHack is fundamentally a getkey-type
@@ -21,7 +21,11 @@
 #include <qbuttongroup.h>
 #include <qlabel.h>
 #include <qlineedit.h> 
+#if defined(QWS)
+#include <qpeapplication.h> 
+#else
 #include <qapplication.h> 
+#endif
 #include <qspinbox.h>
 #include <qfile.h> 
 #include <qlistbox.h> 
@@ -32,7 +36,15 @@
 #include <qarray.h>
 #include <qcombobox.h>
 #include <qscrollview.h>
+#if QT_VERSION >= 300
+#include <qttableview.h>
+// Should stop using QTableView
+#define QTableView QtTableView
+#else
 #include <qtableview.h>
+#endif
+#include <qmainwindow.h>
+#include <qwidgetstack.h>
 
 #ifdef KDE
 #include <kapp.h>
@@ -103,6 +115,7 @@
 	bool Full() const;
 
 	void Put(int k, int ascii, int state);
+	void Put(char a);
 	void Put(const char* str);
 	int GetKey();
 	int GetAscii();
@@ -144,6 +157,12 @@
 };
 
 
+class NetHackQtSavedGameSelector : public QDialog {
+public:
+	NetHackQtSavedGameSelector(const char** saved);
+
+	int choose();
+};
 
 class NetHackQtPlayerSelector : private QDialog {
 	Q_OBJECT
@@ -175,6 +194,7 @@
 	NhPSListView* race;
 	QRadioButton **gender;
 	QRadioButton **alignment;
+	bool fully_specified_role;
 };
 
 class NetHackQtStringRequestor : QDialog {
@@ -268,6 +288,8 @@
 	QPixmap pet_annotation;
 	Clusterizer change;
 	QFont *rogue_font;
+	QString messages;
+	QRect messages_rect;
 
 	void Changed(int x,int y);
 
@@ -276,6 +298,7 @@
 
 private slots:
 	void updateTiles();
+	void moveMessages(int x, int y);
 
 protected:
 	virtual void paintEvent(QPaintEvent*);
@@ -296,6 +319,11 @@
 	virtual void PrintGlyph(int x,int y,int glyph);
 
 	void Scroll(int dx, int dy);
+
+	// For messages
+	void displayMessages(bool block);
+	void putMessage(int attr, const char* text);
+	void clearMessages();
 };
 
 class NetHackQtScrollText;
@@ -312,9 +340,12 @@
 
 	void Scroll(int dx, int dy);
 
+	void setMap(NetHackQtMapWindow*);
+
 private:
 	NetHackQtScrollText* list;
 	bool changed;
+	NetHackQtMapWindow* map;
 
 private slots:
 	void updateFont();
@@ -558,6 +589,7 @@
 
 protected:
 	virtual void paintEvent(QPaintEvent* event);
+	QSize sizeHint() const;
 };
 
 
@@ -580,7 +612,6 @@
 
 protected:
 	virtual void done(int);
-	virtual void resizeEvent(QResizeEvent*);
 	virtual void keyPressEvent(QKeyEvent*);
 
 private slots:
@@ -673,6 +704,7 @@
 
 public slots:
 	void doMenuItem(int);
+	void doKeys(const QString&);
 
 protected:
 	virtual void resizeEvent(QResizeEvent*);
@@ -681,6 +713,9 @@
 
 private slots:
 	void layout();
+	void raiseMap();
+	void raiseMessages();
+	void raiseStatus();
 
 private:
 	void ShowIfReady();
@@ -693,14 +728,16 @@
 	NetHackQtMessageWindow* message;
 	NetHackQtMapWindow* map;
 	NetHackQtStatusWindow* status;
-	NetHackQtInvUsageWindow invusage;
+	NetHackQtInvUsageWindow* invusage;
 
 	NetHackQtKeyBuffer& keysink;
+	QWidgetStack* stack;
 
 	const char* *macro;
 };
 
 class NetHackQtYnDialog : QDialog {
+	Q_OBJECT
 private:
 	const char* question;
 	const char* choices;
@@ -711,6 +748,9 @@
 	virtual void keyPressEvent(QKeyEvent*);
 	virtual void done(int);
 
+private slots:
+	void doneItem(int);
+
 public:
 	NetHackQtYnDialog(NetHackQtKeyBuffer& keysource,const char*,const char*,char);
 
@@ -719,6 +759,8 @@
 
 #ifdef KDE
 #define NetHackQtBindBase KApplication
+#elif defined(QWS)
+#define NetHackQtBindBase QPEApplication
 #else
 #define NetHackQtBindBase QApplication
 #endif
@@ -733,6 +775,7 @@
 	static NetHackQtKeyBuffer keybuffer;
 	static NetHackQtClickBuffer clickbuffer;
 
+	static QWidget* splash;
 	static NetHackQtMainWindow* main;
 
 public:
diff -Naurd ../nethack-3.3.1/include/qt_xpms.h ./include/qt_xpms.h
--- ../nethack-3.3.1/include/qt_xpms.h Thu Oct 7 00:05:59 1999
+++ ./include/qt_xpms.h Fri Mar 22 14:40:55 2002
@@ -932,6 +932,19 @@
 ".... ..."
 };
 /* XPM */
+static const char *pet_mark_small_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"5 5 2 1",
+/* colors */
+". c None",
+"X c #FF0000",
+/* pixels */
+".X.X.",
+"XXXXX",
+".XXX.",
+"..X.."
+};
+/* XPM */
 static const char *satiated_xpm[] = {
 /* width height ncolors chars_per_pixel */
 "40 40 23 1",
diff -Naurd ../nethack-3.3.1/include/qttableview.h ./include/qttableview.h
--- ../nethack-3.3.1/include/qttableview.h Thu Jan 1 01:00:00 1970
+++ ./include/qttableview.h Fri Mar 22 14:40:55 2002
@@ -0,0 +1,251 @@
+/**********************************************************************
+** $Id: qttableview.h,v 1.2 2002/03/09 03:13:13 jwalz Exp $
+**
+** Definition of QtTableView class
+**
+** Created : 941115
+**
+** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
+**
+** This file contains a class moved out of the Qt GUI Toolkit API. It
+** may be used, distributed and modified without limitation.
+**
+**********************************************************************/
+
+#ifndef QTTABLEVIEW_H
+#define QTTABLEVIEW_H
+
+#ifndef QT_H
+#include <qframe.h>
+#endif // QT_H
+
+#ifndef QT_NO_QTTABLEVIEW
+
+class QScrollBar;
+class QCornerSquare;
+
+
+class QtTableView : public QFrame
+{
+    Q_OBJECT
+public:
+    virtual void setBackgroundColor( const QColor & );
+    virtual void setPalette( const QPalette & );
+    void	show();
+
+    void	repaint( bool erase=TRUE );
+    void	repaint( int x, int y, int w, int h, bool erase=TRUE );
+    void	repaint( const QRect &, bool erase=TRUE );
+
+protected:
+    QtTableView( QWidget *parent=0, const char *name=0, WFlags f=0 );
+   ~QtTableView();
+
+    int		numRows()	const;
+    virtual void setNumRows( int );
+    int		numCols()	const;
+    virtual void setNumCols( int );
+
+    int		topCell()	const;
+    virtual void setTopCell( int row );
+    int		leftCell()	const;
+    virtual void setLeftCell( int col );
+    virtual void setTopLeftCell( int row, int col );
+
+    int		xOffset()	const;
+    virtual void setXOffset( int );
+    int		yOffset()	const;
+    virtual void setYOffset( int );
+    virtual void setOffset( int x, int y, bool updateScrBars = TRUE );
+
+    virtual int cellWidth( int col );
+    virtual int cellHeight( int row );
+    int		cellWidth()	const;
+    int		cellHeight()	const;
+    virtual void setCellWidth( int );
+    virtual void setCellHeight( int );
+
+    virtual int totalWidth();
+    virtual int totalHeight();
+
+    uint	tableFlags()	const;
+    bool	testTableFlags( uint f ) const;
+    virtual void setTableFlags( uint f );
+    void	clearTableFlags( uint f = ~0 );
+
+    bool	autoUpdate()	 const;
+    virtual void setAutoUpdate( bool );
+
+    void	updateCell( int row, int column, bool erase=TRUE );
+
+    QRect	cellUpdateRect() const;
+    QRect	viewRect()	 const;
+
+    int		lastRowVisible() const;
+    int		lastColVisible() const;
+
+    bool	rowIsVisible( int row ) const;
+    bool	colIsVisible( int col ) const;
+
+    QScrollBar *verticalScrollBar() const;
+    QScrollBar *horizontalScrollBar() const;
+
+private slots:
+    void	horSbValue( int );
+    void	horSbSliding( int );
+    void	horSbSlidingDone();
+    void	verSbValue( int );
+    void	verSbSliding( int );
+    void	verSbSlidingDone();
+
+protected:
+    virtual void paintCell( QPainter *, int row, int col ) = 0;
+    virtual void setupPainter( QPainter * );
+
+    void	paintEvent( QPaintEvent * );
+    void	resizeEvent( QResizeEvent * );
+
+    int		findRow( int yPos ) const;
+    int		findCol( int xPos ) const;
+
+    bool	rowYPos( int row, int *yPos ) const;
+    bool	colXPos( int col, int *xPos ) const;
+
+    int		maxXOffset();
+    int		maxYOffset();
+    int		maxColOffset();
+    int		maxRowOffset();
+
+    int		minViewX()	const;
+    int		minViewY()	const;
+    int		maxViewX()	const;
+    int		maxViewY()	const;
+    int		viewWidth()	const;
+    int		viewHeight()	const;
+
+    void	scroll( int xPixels, int yPixels );
+    void	updateScrollBars();
+    void	updateTableSize();
+
+private:
+    void	coverCornerSquare( bool );
+    void	snapToGrid( bool horizontal, bool vertical );
+    virtual void	setHorScrollBar( bool on, bool update = TRUE );
+    virtual void	setVerScrollBar( bool on, bool update = TRUE );
+    void	updateView();
+    int		findRawRow( int yPos, int *cellMaxY, int *cellMinY = 0,
+			    bool goOutsideView = FALSE ) const;
+    int		findRawCol( int xPos, int *cellMaxX, int *cellMinX = 0,
+			    bool goOutsideView = FALSE ) const;
+    int		maxColsVisible() const;
+
+    void	updateScrollBars( uint );
+    void	updateFrameSize();
+
+    void	doAutoScrollBars();
+    void	showOrHideScrollBars();
+
+    int		nRows;
+    int		nCols;
+    int		xOffs, yOffs;
+    int		xCellOffs, yCellOffs;
+    short	xCellDelta, yCellDelta;
+    short	cellH, cellW;
+
+    uint	eraseInPaint		: 1;
+    uint	verSliding		: 1;
+    uint	verSnappingOff		: 1;
+    uint	horSliding		: 1;
+    uint	horSnappingOff		: 1;
+    uint	coveringCornerSquare	: 1;
+    uint	sbDirty			: 8;
+    uint	inSbUpdate		: 1;
+
+    uint	tFlags;
+    QRect	cellUpdateR;
+
+    QScrollBar *vScrollBar;
+    QScrollBar *hScrollBar;
+    QCornerSquare *cornerSquare;
+
+private:	// Disabled copy constructor and operator=
+#if defined(Q_DISABLE_COPY)
+    QtTableView( const QtTableView & );
+    QtTableView &operator=( const QtTableView & );
+#endif
+};
+
+
+const uint Tbl_vScrollBar	= 0x00000001;
+const uint Tbl_hScrollBar	= 0x00000002;
+const uint Tbl_autoVScrollBar	= 0x00000004;
+const uint Tbl_autoHScrollBar	= 0x00000008;
+const uint Tbl_autoScrollBars	= 0x0000000C;
+
+const uint Tbl_clipCellPainting = 0x00000100;
+const uint Tbl_cutCellsV	= 0x00000200;
+const uint Tbl_cutCellsH	= 0x00000400;
+const uint Tbl_cutCells		= 0x00000600;
+
+const uint Tbl_scrollLastHCell	= 0x00000800;
+const uint Tbl_scrollLastVCell	= 0x00001000;
+const uint Tbl_scrollLastCell	= 0x00001800;
+
+const uint Tbl_smoothHScrolling = 0x00002000;
+const uint Tbl_smoothVScrolling = 0x00004000;
+const uint Tbl_smoothScrolling	= 0x00006000;
+
+const uint Tbl_snapToHGrid	= 0x00008000;
+const uint Tbl_snapToVGrid	= 0x00010000;
+const uint Tbl_snapToGrid	= 0x00018000;
+
+
+inline int QtTableView::numRows() const
+{ return nRows; }
+
+inline int QtTableView::numCols() const
+{ return nCols; }
+
+inline int QtTableView::topCell() const
+{ return yCellOffs; }
+
+inline int QtTableView::leftCell() const
+{ return xCellOffs; }
+
+inline int QtTableView::xOffset() const
+{ return xOffs; }
+
+inline int QtTableView::yOffset() const
+{ return yOffs; }
+
+inline int QtTableView::cellHeight() const
+{ return cellH; }
+
+inline int QtTableView::cellWidth() const
+{ return cellW; }
+
+inline uint QtTableView::tableFlags() const
+{ return tFlags; }
+
+inline bool QtTableView::testTableFlags( uint f ) const
+{ return (tFlags & f) != 0; }
+
+inline QRect QtTableView::cellUpdateRect() const
+{ return cellUpdateR; }
+
+inline bool QtTableView::autoUpdate() const
+{ return isUpdatesEnabled(); }
+
+inline void QtTableView::repaint( bool erase )
+{ repaint( 0, 0, width(), height(), erase ); }
+
+inline void QtTableView::repaint( const QRect &r, bool erase )
+{ repaint( r.x(), r.y(), r.width(), r.height(), erase ); }
+
+inline void QtTableView::updateScrollBars()
+{ updateScrollBars( 0 ); }
+
+
+#endif // QT_NO_QTTABLEVIEW
+
+#endif // QTTABLEVIEW_H
diff -Naurd ../nethack-3.3.1/src/files.c ./src/files.c
--- ../nethack-3.3.1/src/files.c Wed Aug 9 18:38:07 2000
+++ ./src/files.c Fri Mar 22 14:40:55 2002
@@ -1463,12 +1513,24 @@
 		extern char *qt_fontsize;
 		if (qt_fontsize == NULL)
 			qt_fontsize=(char *)strdup(bufp);
+	} else if (match_varname(buf, "QT_COMPACT", 10)) {
+		extern int qt_compact_mode;
+		qt_compact_mode = atoi(bufp);
 #endif
 	} else
 		return 0;
 	return 1;
 }
 
+#ifdef USER_SOUNDS
+boolean
+can_read_file(filename)
+const char *filename;
+{
+	return (access(filename, 4) == 0);
+}
+#endif /* USER_SOUNDS */
+
 void
 read_config_file(filename)
 const char *filename;

