430 lines
20 KiB
HTML
430 lines
20 KiB
HTML
<!--startcut ==============================================-->
|
||
<!-- *** BEGIN HTML header *** -->
|
||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||
<HTML><HEAD>
|
||
<title>Kaptain - A Dialog Creator LG #64</title>
|
||
</HEAD>
|
||
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
|
||
ALINK="#FF0000">
|
||
<!-- *** END HTML header *** -->
|
||
|
||
<CENTER>
|
||
<A HREF="http://www.linuxgazette.com/">
|
||
<H1><IMG ALT="LINUX GAZETTE" SRC="../gx/lglogo.png"
|
||
WIDTH="600" HEIGHT="124" border="0"></H1></A>
|
||
|
||
<!-- *** BEGIN navbar *** -->
|
||
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="dellomodarme.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue64/evans.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="fevola.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
|
||
<!-- *** END navbar *** -->
|
||
<P>
|
||
</CENTER>
|
||
|
||
<!--endcut ============================================================-->
|
||
|
||
<H4 ALIGN="center">
|
||
"Linux Gazette...<I>making Linux just a little more fun!</I>"
|
||
</H4>
|
||
|
||
<P> <HR> <P>
|
||
<!--===================================================================-->
|
||
|
||
<center>
|
||
<H1><font color="maroon">Kaptain - A Dialog Creator</font></H1>
|
||
<H4>By <a href="mailto:pevans@catholic.org">Paul Evans</a></H4>
|
||
</center>
|
||
<P> <HR> <P>
|
||
|
||
<!-- END header -->
|
||
|
||
|
||
|
||
|
||
<p>
|
||
<i>``What Linux really needs ...''</i> is the beginning of an oft written statement which nearly as often ends with
|
||
<i>``graphical front-ends for legacy console apps.'' </i> To quote a certain magazine
|
||
editor: <i>``Of course, what Linux needs are not just dialogs, but dialogs that
|
||
optionally show you the command-line options they generate, so you can get used
|
||
to which options do what.''</i> I add that it would also be nice if the dialogs
|
||
were easy to write, so more people would bother to create them.
|
||
</p>
|
||
|
||
|
||
<h2>What Kaptain can do for you</h2>
|
||
|
||
<p>
|
||
<a href="http://kaptain.sourceforge.net" name="Kaptain">Kaptain</a>
|
||
has the ability to display mixed widget types in a modern looking dialog which
|
||
is created from a text file. The program can take care of most of the layout and
|
||
widget types for you. You can even write tabbed and child dialogs. And, importantly,
|
||
it can echo it's output to the command line for learning purposes (or the sheer delight of experimenting :-) ).
|
||
It also has tooltips and WhatsThis to aid in this regard. You could even use it as part of a pipe and have it written on the fly!
|
||
</p>
|
||
|
||
<p>
|
||
Linux is chock-full of powerful command line goodies like <b>enscript</b> and <b>mpage</b>, but, even if
|
||
you were a member of their frequent-flyer program, you'd never be able to remember all the
|
||
switches and options included with them. <b>Kaptain</b> is perfect for this sort of thing: lots of spinners,
|
||
check-boxes and combos etc. Then there are those file conversion chores. I have
|
||
constructed many, er, <i>interesting</i> looking pipelines to convert image, sound and text formats. The
|
||
latter do surrender to a little bash function - as long as you don't need to change any options for any of the commands.
|
||
By the time you write enough shell script to handle all the options... you need to write a man page for your shell script.
|
||
</p>
|
||
|
||
<a href="misc/evans/enscript1.gif"><img src="misc/evans/enscript1_thumbnail.jpg" width="250" height="248" vspace="10" hspace="10" alt="pic of a tabbed dialog for enscript" align="right"></a>
|
||
<br>
|
||
|
||
<p>
|
||
I wouldn't be writing this if <a
|
||
href="http://kaptain.sourceforge.net" name="kaptain">Kaptain</a>
|
||
couldn't do all of that, but I'd be lying if I said that it looked easy to <i>me</i>
|
||
right away. I'd like to re-stress the "me" in the preceding sentence: I'd never
|
||
written in anything object oriented before. If you've done any at all, I'm
|
||
sure <b>Kaptain</b> will be a cake-walk for you. And, if you haven't, don't
|
||
fret. I'm living proof that you'll be writing scripts for <b>Kaptain</b>
|
||
without stressing yourself overmuch.
|
||
</p>
|
||
|
||
|
||
<p>
|
||
If you're already handy with the OO approach, I suggest you just download the
|
||
thing and dive in - you'll love it. In fact, it isn't OO in the usual meaning. The author <i>``got the idea from Formal Language Theory (Maths),
|
||
where grammars generating text are mathematical objects. So the words terminal, nonterminal are well known in FLT, but nowhere else.
|
||
For those who have learnt such things, it's good to see something they are familiar with, for others these are just some new words.
|
||
BTW, YACC also uses Context-Free Grammars.</i>''
|
||
</p>
|
||
|
||
<p>
|
||
The image is a thumbnail of the <b>enscript</b> dialog. You can click on it for a larger view.
|
||
</p>
|
||
|
||
<p>
|
||
Even if you have no intention of writing anything, there are many example
|
||
scripts in the <b>Kaptain</b> 400k source tarball to make it worth the download:
|
||
<ul>
|
||
<li>arping</li>
|
||
<li>crypt</li>
|
||
<li>curl</li>
|
||
<li>enscript</li>
|
||
<li>find</li>
|
||
<li>finger</li>
|
||
<li>grep</li>
|
||
<li>indent</li>
|
||
<li>ls</li>
|
||
<li>nslookup</li>
|
||
<li>open</li>
|
||
<li>ping</li>
|
||
<li>procmail</li>
|
||
<li>tar</li>
|
||
<li>weblint</li>
|
||
<li>whois</li>
|
||
<li>zangband</li>
|
||
</ul>
|
||
After compile, the binary is about 100k.
|
||
</p>
|
||
|
||
<p>
|
||
Now, as alluded to earlier, I had never done any scripting which involved '->',
|
||
objects or inheritance at all. Sure, I'd copied and pasted Java like
|
||
many others have, but I didn't really <i>get</i> it. Any changes were
|
||
nearly pure trial and error. Anything that actually worked after I messed with it was pure accident.
|
||
</p>
|
||
|
||
<p>
|
||
I think I just wasn't properly pre-disposed to learning it. After all, the only
|
||
example of object oriented programming that I (or most other people) are
|
||
familiar seeing as code, is Java. We're aware of Java, because it turns our
|
||
normally speedy browsers into 3-toed sloths on vallium. I simply could not understand
|
||
what all the hype was about since I always dreaded seeing 'loading java' or
|
||
similar in Netscape. Apparently, <b>it doesn't have to be that way</b>. It's
|
||
really a wonderful way to write once you get into it. I'd known for years about
|
||
it being done even in perl, but I never got past my experience watching Java
|
||
ruin an evening's browsing. I was recently vindicated in my attitude towards
|
||
Java in the January 2001 issue of "Software Development". On page 26 the author
|
||
states: ``<i>I'm primarily a Java hacker ... My Plan A for dealing with a
|
||
memory-hungry application ... is to wave my hand and snort 'Bah! That is why we
|
||
have virtual memory.' The 20-GB hard disk on this system seems positively
|
||
claustrophobic to me.</i>'' I knew it! To be fair, this was in the introduction to an article on
|
||
embedded, so I hope it was meant as humour. I hope.
|
||
</p>
|
||
|
||
|
||
|
||
<h2>Let's create a dialog</h2>
|
||
|
||
<p>
|
||
I can't think of any reason not to use my own first dialog as a starting point,
|
||
so we're going to make a simple dialog to hear phone messages from
|
||
vgetty.
|
||
</p>
|
||
|
||
|
||
|
||
<h3>What we need to do</h3>
|
||
|
||
<p>
|
||
Well, we want to display and play voice messages from a graphical user interface.
|
||
The messages live in a directory named /var/spool/voice/incoming. We want to
|
||
display the messages in a list, pick one and play it. Sounds simple - and
|
||
<b>Kaptain</b> keeps it that way.
|
||
</p>
|
||
|
||
|
||
|
||
<h3>The script</h3>
|
||
|
||
<p>
|
||
I'm going to describe making a script executable here, because I dimly recall being
|
||
mystified when I first started with Linux by what I took to be weird "comments" on the top of some
|
||
scripts and I hope it may help others. Just skip down to <A href="#goodstuff">The good stuff</A> in order to avoid it.
|
||
</p>
|
||
|
||
<p>
|
||
First, lets make a file called 'playmessage'. So, we open a shell and type
|
||
"touch playmessage" or open our favourite editor and 'save as'. Whichever, at
|
||
some point, you need to be editing a file called 'playmessage' or similar. A
|
||
nice place to put this sort of thing is in "/home/yourname/bin", because it's
|
||
likely allready a part of your path and you have permissions for it all the
|
||
time. If the directory doesn't exist just create it with mkdir.
|
||
</p>
|
||
|
||
<p>
|
||
The first line of our script will be a 'shebang' line. Any file under linux is
|
||
'executable', i.e. a program, if it has its <i>x</i> bit set. Even if it's not
|
||
really a program, but only a script, the first line can tell the operating
|
||
system how to handle it as if it were a real program. The upshot is that you can
|
||
type the filename and it will be executed.
|
||
</p>
|
||
|
||
<p>
|
||
Next we need to know just where <b>kaptain</b> was installed. Pop up an xterm
|
||
or drop into console and type "which kaptain" and then enter.
|
||
Mine happens to say "/home/paul/bin/kaptain", but yours is more likely to say
|
||
"/usr/bin/kaptain" or "/usr/local/bin/kaptain". Now that we know where kaptain
|
||
is installed, we can write our first line:<br>
|
||
<pre>
|
||
#!/usr/bin/kaptain
|
||
</pre><br>
|
||
and save the file.
|
||
</p>
|
||
|
||
<p>
|
||
We're ready to write our script. The last thing we need to do, before we launch
|
||
right in, is to set the 'executable' bit on our new "program". Go back into your
|
||
shell and make sure you're in the directory which contains 'playmessage'. Now
|
||
type "chmod +x playmessage". This will set all the executable bits to on. Now a directory listing with 'ls'
|
||
should show 'playmessage' in green with an asterisk beside it indicating
|
||
that it's executable.
|
||
</p>
|
||
|
||
|
||
|
||
<h3><A name="goodstuff">The good stuff</A></h3>
|
||
|
||
<p>
|
||
There are only ten lines in this dialog and two of them are just for show. The only things they do
|
||
are to show a title and an icon. Really, we could do without the "Dismiss" button as well. I want to impress
|
||
on you just how few lines you need in order to get a functional dialog. A 'copy and paste' plain text version
|
||
is <A HREF="misc/evans/playmessage.kaptain.txt" NAME="link to plaintext">here.</A>
|
||
</p>
|
||
|
||
<PRE>
|
||
#!/home/paul/bin/kaptain
|
||
|
||
start "Play Message" -> descr msglist;
|
||
|
||
descr :horizontal -> title pic;
|
||
title -> @text ("Phone Message player.");
|
||
pic -> @icon("/usr/share/icons/large/kvoice.xpm");
|
||
|
||
msglist :framed :horizontal -> msg buttons;
|
||
msg -> @list(`ls /var/spool/voice/incoming`);
|
||
buttons -> play close;
|
||
play -> @action(play_rmd)="Play";
|
||
close -> @close="Dismiss";
|
||
|
||
play_rmd -> "rmdtopvf /var/spool/voice/incoming/"msg" | pvftowav | play -t wav - ";
|
||
</PRE>
|
||
|
||
<SPACER TYPE="vertical" SIZE="20">
|
||
|
||
<img src="misc/evans/playmessage.gif" width="543" height="282" vspace="10" hspace="10" alt="snapshot of the playmessage dialog">
|
||
|
||
<p>Here's our first line:</p>
|
||
|
||
<pre>start "Play Message" -> descr msglist;</pre>
|
||
|
||
<p>
|
||
Note the semi-colon at the end of the line. This is mandatory, just like perl. In fact Kaptain is quite "perlish"
|
||
after a fashion. The main container is actually named 'start', this is also built into Kaptain's grammar and you must
|
||
use this word for your first rule. The quoted string "Play Message" is optional and is used only for the dialog's window title.
|
||
</p>
|
||
|
||
<p>
|
||
On the right, that is, after the "-&gt", you can see the words "descr" and "msglist". In Kaptain grammar these are known as 'nonterminals' and
|
||
they refer to some area of the dialog. They may be named anything you like as long as they start with a letter. You can also specify as
|
||
many areas as you like.
|
||
</p>
|
||
|
||
<p>
|
||
So far, we've defined a dialog with two areas named "descr" and "msglist". If you try to run this without adding anything more it will fail. Why? Because,
|
||
the areas named don't resolve to anything - we haven't defined them yet. These next three lines define the "descr" area of the dialog:
|
||
</p>
|
||
|
||
<pre>
|
||
descr :horizontal -> title pic;
|
||
title -> @text ("Phone Message player.");
|
||
pic -> @icon("/usr/share/icons/large/kvoice.xpm");
|
||
</pre>
|
||
|
||
<p>
|
||
The first line of "descr" is just about the same as the very first line of our script and it does pretty much the same thing. It defines two
|
||
areas of the dialog. The only difference is the ':horizontal' option. This forces Kaptain to lay them out side by side instead of vertically. Of
|
||
course now these <i>new</i> areas need to be terminated (or point to yet more areas) and they do in the next two lines following them.
|
||
"title" now points to a text widget and "pic" points to an icon. Kaptain grammar calls these <i>"specials"</i>. There's a list of all the currently
|
||
available specials <a href="misc/evans/specials.html">here.</a> These include spinners, combos, file dialogs etc.
|
||
</p>
|
||
|
||
<p>
|
||
These last lines complete the whole dialog by terminating the "msglist" area of the dialog:
|
||
</p>
|
||
|
||
<pre>
|
||
msglist :framed :horizontal -> msg buttons;
|
||
msg -> @list(`ls /var/spool/voice/incoming`);
|
||
|
||
buttons -> play close;
|
||
play -> @action(play_rmd)="Play";
|
||
close -> @close="Dismiss";
|
||
|
||
play_rmd -> "rmdtopvf /var/spool/voice/incoming/"msg" | pvftowav | play -t wav - ";
|
||
</pre>
|
||
|
||
<p>
|
||
Again, we see a familiar line. "msglist" has just added two child areas to itself. Now that you know what the ":horizontal" option does, I
|
||
think you can guess at the ":framed" option.
|
||
</p>
|
||
|
||
<p>
|
||
The next line - the one for "msg" - is interesting. It's both simple and powerful. I'm sure you've figured out that "@list" is responsible for
|
||
the list box shown in the dialog, but look where it gets it's contents from: a line of shell script! Anything in back-quotes (n.b. It's the key to the left
|
||
of the "1" on your keyboard, the regular single quote won't work.) will be executed and it's standard out will be fed into the "special". You can stuff
|
||
anything in there, "perl -e" - whatever, even multi-line.
|
||
</p>
|
||
|
||
<p>The only area left now is the one for the buttons. This area spins off two more children, one for each button we want. The play button shows
|
||
another way to execute some shell commands, this time a pipeline for converting and playing raw modem files. That's it. Again, to see the script as
|
||
plain text you may click <A HREF="./misc/evans/playmessage.kaptain.txt" NAME="link to plaintext">here.</A> It's nice to see it all together now that you know how it works.
|
||
Simple as it is, you could tinker a bit if you like: feed the list your music directory and change the play command to your mp3 player for example. Process
|
||
text files, convert images; it can be the basis for a lot of things.
|
||
</p>
|
||
|
||
<p>
|
||
Anything this easy becomes nearly addictive and I was sorely tempted to start "embroidering" the script. Since I only have one way of dealing with
|
||
temptation (I yield to it) a pic of the over-grown results is <a href="misc/evans/voxpak.gif">here</a> and the script is <a href="misc/evans/voxpak.kaptain.txt">here.</a> This exercise
|
||
was useful for two reasons: a) I got something to replace my now kde2-broken <b>kvoice</b> and b) I learned the limitations of <b>Kaptain</b>. You can't
|
||
refresh lists or change anything after it's up (of course widget settings <i>do</i> change things). Commands are evaluated only at run-time. This is as it should be
|
||
for a dialog program and I really was pushing the envelope with my little kvoice experiment. So let's do what I originally set out to show.
|
||
</p>
|
||
|
||
<h3>A dialog for <b>mpage</b></h3>
|
||
|
||
<img src="misc/evans/mpage.gif" width="289" height="302" vspace="10" hspace="10" alt="snapshot of mpage dialog" align="right">
|
||
|
||
<p>
|
||
If you've seen the command line options for <b>mpage</b> you're probably afraid right now. Very afraid. But fear not. We're only going to use a small subset of mpage's options.
|
||
And, because we've taken a good look at the basics, I'm not going to go through it line by line. I'm including this here to show off the @echo special more than anything.
|
||
</p>
|
||
|
||
|
||
<p>
|
||
For those who aren't familiar with <b>mpage</b>, it's a command line program for printing multiple pages on a single page. You can print 2, 4 or 8 up, but you'd better
|
||
have exceptional eyesight and a good printer for 8:1! The other noteworthy thing about <b>mpage</b> is that it has about 50 options you can feed it - in fact, the sheer number of
|
||
options is listed under 'BUGS' in the man page :-) I'm sure I'll embroider this script over time too, but for now let's just choose between how many pages and the margin controls.
|
||
</p>
|
||
|
||
<p>
|
||
Here's the script:
|
||
</p>
|
||
|
||
<pre>
|
||
#!/home/paul/bin/kaptain -V
|
||
|
||
start :framed "mpage Mini-Dialog" -> file numpages margins buttons;
|
||
|
||
file "File to print" -> @infile("*.txt");
|
||
|
||
numpages :horizontal "Number of pages on each page" -> p1 | ! p2 | p4 | p8;
|
||
p1 "1 pg" -> "1";
|
||
p2 "2 pgs" -> "2";
|
||
p4 "4 pgs" -> "4";
|
||
p8 "8 pgs" -> "8";
|
||
|
||
margins :horizontal "Margins" -> left right top bottom;
|
||
left "Left" -> @integer(10,100)=40;
|
||
right "Right" -> @integer(10,100)=50;
|
||
top "Top" -> @integer(10,100)=20;
|
||
bottom "Bottom" -> @integer(10,100)=30;
|
||
|
||
buttons :horizontal -> echo print dismiss;
|
||
echo -> @echo(cmd)="Echo";
|
||
print -> @action(cmd)="Print";
|
||
dismiss -> @close()="Dismiss";
|
||
|
||
cmd -> "mpage -P -"numpages" -m" left "l" bottom "b" top "t" right" r "file;
|
||
</pre>
|
||
|
||
<p>Plain text is <A HREF="./misc/evans/mpage.kaptain.txt" NAME="link to plaintext">here.</A></p>
|
||
|
||
<p>
|
||
When run from an xterm, you can make changes and click the "Echo" button over and over to see how the changes effect the command line
|
||
without wasting any paper at all. To save more paper just take out the "-P" and everything will go to standard out even if you press print.
|
||
To really enjoy playing with it change the cmd line to:
|
||
</p>
|
||
|
||
<pre>cmd -> "mpage -" numpages " -m" left "l" bottom "b" top "t" right "r " file" >test.ps";</pre>
|
||
|
||
<p>
|
||
then you can just view the output page with a viewer. Or you could add ";viewername test.ps" to the end and save a step - you get the idea.
|
||
</p>
|
||
|
||
<p>
|
||
There is another article about <b>Kaptain</b> by <a href="mailto:renai@start.com.au">hawkeye</a> at
|
||
<A HREF="http://www.linuxtoday.com.au/r/article/jsp/sid/131347">Linux Today Australia.</A>
|
||
</p>
|
||
|
||
<p>
|
||
I haven't done a thorough job of describing everything <b>Kaptain</b> can do; there's heaps more I haven't shown or even mentioned.
|
||
<b>Kaptain</b> comes with pretty good docs and plenty of examples though. The author of <b>Kaptain</b> is <b>Ter<EFBFBD>k Zsolt</b>.
|
||
He's doing a great job with <b>Kaptain</b> - which is still only at 0.51. If it gains wider use it can be of great value in teaching console
|
||
apps and it can save all of us some mind-numbing tedium. Plus, it's the most painless way to experiment with output I've ever
|
||
found. Don't wait for someone to write one for you - give it a shot yourself. Really. Mr. Ter<65>k will be pleased to post them on his
|
||
<a href="http://kaptain.sourceforge.net">website.</a>
|
||
</p>
|
||
|
||
<p>
|
||
There are other dialog programs for X out there: <b>gdialog</b> which is probably on your system already, <b>Xdialog</b> which has some nice date/time dialogs etc.
|
||
is down-loadable from <a href="http://xdialog.free.fr/">here.</a>
|
||
If one dialog app doesn't have exactly what you want there are always options. I'm sure there are others I just haven't tried yet. Mix and match them within the same script.
|
||
|
||
|
||
|
||
|
||
<!-- *** BEGIN copyright *** -->
|
||
<P> <hr> <!-- P -->
|
||
<H5 ALIGN=center>
|
||
|
||
Copyright © 2001, Paul Evans.<BR>
|
||
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR>
|
||
Published in Issue 64 of <i>Linux Gazette</i>, March 2001</H5>
|
||
<!-- *** END copyright *** -->
|
||
|
||
<!--startcut ==========================================================-->
|
||
<HR><P>
|
||
<CENTER>
|
||
<!-- *** BEGIN navbar *** -->
|
||
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="dellomodarme.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue64/evans.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="fevola.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
|
||
<!-- *** END navbar *** -->
|
||
</CENTER>
|
||
</BODY></HTML>
|
||
<!--endcut ============================================================-->
|