| 1 |
<HTML> |
|---|
| 2 |
|
|---|
| 3 |
<!-- $Id$ --> |
|---|
| 4 |
|
|---|
| 5 |
<HEAD> |
|---|
| 6 |
<TITLE>Use of the VR Juggler configure Script</TITLE> |
|---|
| 7 |
</HEAD> |
|---|
| 8 |
|
|---|
| 9 |
<BODY |
|---|
| 10 |
TEXT="#000000" BGCOLOR="#FFFFFF" |
|---|
| 11 |
LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000"> |
|---|
| 12 |
|
|---|
| 13 |
<DIV ALIGN="CENTER"> |
|---|
| 14 |
<H1>Configure Script Guide</H1> |
|---|
| 15 |
</DIV> |
|---|
| 16 |
|
|---|
| 17 |
<HR WIDTH="80%" NOSHADE> |
|---|
| 18 |
|
|---|
| 19 |
<H3>Usage</H3> |
|---|
| 20 |
|
|---|
| 21 |
Use of the <I>configure</I> script and its accompanying template files is |
|---|
| 22 |
designed to be as simple as possible at the user level. It provides a |
|---|
| 23 |
platform-independent method for creating platform-specific Makefiles that can |
|---|
| 24 |
be used to build VR Juggler for the target platform. The following example |
|---|
| 25 |
illustrates the typical way to use the <I>configure</I> script: |
|---|
| 26 |
|
|---|
| 27 |
<OL> |
|---|
| 28 |
<LI><B><TT>cd <I>path/to/source/juggler</I></TT></B> |
|---|
| 29 |
<LI><B><TT>mkdir <I>build</I></TT></B> |
|---|
| 30 |
<LI><B><TT>cd <I>build</I></TT></B> |
|---|
| 31 |
<LI><B><TT>../configure <I>--user-options-here</I></TT></B> |
|---|
| 32 |
<LI><B><TT>gmake</TT></B> |
|---|
| 33 |
</OL> |
|---|
| 34 |
|
|---|
| 35 |
The directory named ``<TT>build</TT>'' in this example can actually |
|---|
| 36 |
be put anywhere--it does not have to be a subdirectory of <TT>juggler</TT>. |
|---|
| 37 |
It can also be given any name desired. In fact, the directory does not even |
|---|
| 38 |
need to be used, but doing so will not give the full functionality offered by |
|---|
| 39 |
building in a subdirectory. |
|---|
| 40 |
|
|---|
| 41 |
<P> |
|---|
| 42 |
|
|---|
| 43 |
The above example results in the library object files and the library itself |
|---|
| 44 |
being built in separate <TT>obj</TT> and <TT>lib</TT> subdirectories of |
|---|
| 45 |
<TT>build</TT> respectively. If you are building a debugging version of the |
|---|
| 46 |
library on IRIX with compiler options <TT>-n32 -mips3</TT>, the |
|---|
| 47 |
subdirectory where the final library will be is <TT>lib32/mips3/debug</TT>, |
|---|
| 48 |
and the object files will all be in <TT>obj/SGI/N32/mips3/debug</TT>. As a |
|---|
| 49 |
result of following the above steps, there will be no pollution of the base |
|---|
| 50 |
VR Juggler source tree with object files, library binaries, compile-time |
|---|
| 51 |
directories, etc. It all goes in <TT>build</TT> and can all be removed |
|---|
| 52 |
quickly and easily by removing that directory. Thus, the source tree becomes |
|---|
| 53 |
entirely read-only from the perspective of the build process. What follows |
|---|
| 54 |
is a list of what actually goes in <TT>build</TT>. |
|---|
| 55 |
|
|---|
| 56 |
<DL> |
|---|
| 57 |
<DT><B>Makefiles</B> |
|---|
| 58 |
<DD><I>configure</I> generates a tree of Makefiles from the |
|---|
| 59 |
<TT>Makefile.in</TT> template files found in the base Juggler source |
|---|
| 60 |
tree. In so doing, it creates a copy of the source tree that |
|---|
| 61 |
contains only those Makefiles until things start getting compiled. |
|---|
| 62 |
<I>gmake</I>(1) (which is required by all the Makefiles except those |
|---|
| 63 |
in the <TT>test</TT> subtree) will recurse through the directory tree |
|---|
| 64 |
to build all the object files and the final library binaries. The |
|---|
| 65 |
following diagram illustrates the tree created by <I>configure</I>: |
|---|
| 66 |
|
|---|
| 67 |
<PRE> <B>Directories created by <I>configure</I>:</B> |
|---|
| 68 |
|
|---|
| 69 |
juggler -+-- build ----------\ |
|---|
| 70 |
+-- Config +-- Config |
|---|
| 71 |
+-- GUI ---+-- ... +-- GUI |
|---|
| 72 |
| \-- ... | |
|---|
| 73 |
| | |
|---|
| 74 |
+-- Environment +-- Environment |
|---|
| 75 |
+-- Kernel +-- GL +-- Kernel -----+-- GL |
|---|
| 76 |
| \-- Pf | \-- Pf |
|---|
| 77 |
| | |
|---|
| 78 |
+-- Kernel +-- Input ------+-- InputManager |
|---|
| 79 |
+-- Math +-- Math +-- ... |
|---|
| 80 |
+-- ... +-- Performance : |
|---|
| 81 |
: +-- SharedMem : |
|---|
| 82 |
: +-- Sync |
|---|
| 83 |
+-- Threads |
|---|
| 84 |
\-- test -------+-- CfgTest |
|---|
| 85 |
+-- Quat |
|---|
| 86 |
+-- Sync |
|---|
| 87 |
+-- input |
|---|
| 88 |
+-- ogl ----+-- cubes |
|---|
| 89 |
| \-- wand |
|---|
| 90 |
| |
|---|
| 91 |
+-- pfNav |
|---|
| 92 |
: |
|---|
| 93 |
: |
|---|
| 94 |
</PRE> |
|---|
| 95 |
|
|---|
| 96 |
Two or more directory trees are created within <TT>build</TT> during |
|---|
| 97 |
the build process. The first tree holds the compiled object files, |
|---|
| 98 |
and the remaining tress hold the built libraries. The structure is |
|---|
| 99 |
as follows: |
|---|
| 100 |
|
|---|
| 101 |
<PRE> |
|---|
| 102 |
... build -+-- obj -------+-- SGI ---+-- N32 ---+-- mips3 -+-- debug |
|---|
| 103 |
| | | | \-- opt |
|---|
| 104 |
| : | \-- mips4 -+-- debug |
|---|
| 105 |
| : | \-- opt |
|---|
| 106 |
| \-- 64 ----+-- mips3 -+-- debug |
|---|
| 107 |
| | \-- opt |
|---|
| 108 |
| \-- mips4 -+-- debug |
|---|
| 109 |
| \-- opt |
|---|
| 110 |
| |
|---|
| 111 |
+-- lib32 -----+-- mips3 -+-- debug |
|---|
| 112 |
| | \-- opt |
|---|
| 113 |
| \-- mips4 -+-- debug |
|---|
| 114 |
| \-- opt |
|---|
| 115 |
| |
|---|
| 116 |
\-- lib64 -----+-- mips3 -+-- debug |
|---|
| 117 |
| \-- opt |
|---|
| 118 |
\-- mips4 -+-- debug |
|---|
| 119 |
\-- opt |
|---|
| 120 |
</PRE> |
|---|
| 121 |
|
|---|
| 122 |
The tree shown here is what results from making the |
|---|
| 123 |
``<TT>all-abi</TT>'' target on an SGI. When building a single ABI, |
|---|
| 124 |
only that directory is created under <TT>obj</TT>. As can be seen, |
|---|
| 125 |
this structure allows object files to be built for more than one |
|---|
| 126 |
platform in the same <TT>obj</TT> directory. However, it is unlikely |
|---|
| 127 |
that this functionality would ever be very useful since different |
|---|
| 128 |
Makefiles are needed for different platforms. |
|---|
| 129 |
<DT><B>Object files</B> |
|---|
| 130 |
<DD>As all compilations do, the build process creates the object files |
|---|
| 131 |
needed to make the VR Juggler library. These files go in a directory |
|---|
| 132 |
named by the <TT>${OBJDIR}</TT> variable. The default value for this |
|---|
| 133 |
variable is the current directory, but the recursion process |
|---|
| 134 |
overrides this default with the <TT>obj/...</TT> directory mentioned |
|---|
| 135 |
above. |
|---|
| 136 |
<DT><B>Library binaries</B> |
|---|
| 137 |
<DD>The actual library binaries ... |
|---|
| 138 |
</DL> |
|---|
| 139 |
|
|---|
| 140 |
<P> |
|---|
| 141 |
|
|---|
| 142 |
<HR WIDTH="80%" NOSHADE> |
|---|
| 143 |
|
|---|
| 144 |
<H3>Run-Time Options</H3> |
|---|
| 145 |
|
|---|
| 146 |
As of this writing, <I>configure</I> has the following run-time options: |
|---|
| 147 |
|
|---|
| 148 |
<DL> |
|---|
| 149 |
<DT><B>--with-abi=[O32|N32_M3|N32_M4|64_M3|64_M4]</B> |
|---|
| 150 |
<DD>Define the Application Binary Interface to use. The default is |
|---|
| 151 |
<TT>N32_M3</TT>. These names correspond to compiler options as |
|---|
| 152 |
follows: |
|---|
| 153 |
|
|---|
| 154 |
<P> |
|---|
| 155 |
|
|---|
| 156 |
<DIV ALIGN="CENTER"> |
|---|
| 157 |
<TABLE BORDER="1" WIDTH="500"> |
|---|
| 158 |
<TR> |
|---|
| 159 |
<TH BGCOLOR="#d0d0d0"> |
|---|
| 160 |
Name |
|---|
| 161 |
</TH> |
|---|
| 162 |
<TH BGCOLOR="#d0d0d0"> |
|---|
| 163 |
Compiler Options |
|---|
| 164 |
</TH> |
|---|
| 165 |
<TH BGCOLOR="#d0d0d0"> |
|---|
| 166 |
Description |
|---|
| 167 |
</TH> |
|---|
| 168 |
</TR> |
|---|
| 169 |
<TR> |
|---|
| 170 |
<TD ALIGN="RIGHT"> |
|---|
| 171 |
<TT>O32</TT> |
|---|
| 172 |
</TD> |
|---|
| 173 |
<TD ALIGN="CENTER"> |
|---|
| 174 |
<TT>-o32 -mips2</TT> |
|---|
| 175 |
</TD> |
|---|
| 176 |
<TD> |
|---|
| 177 |
Build an old 32-bit binary (standard on IRIX 5 systems) using |
|---|
| 178 |
the mips2 instruction set architecture (ISA)--<B>this is |
|---|
| 179 |
currently not possible</B> |
|---|
| 180 |
</TD> |
|---|
| 181 |
</TR> |
|---|
| 182 |
<TR> |
|---|
| 183 |
<TD ALIGN="RIGHT"> |
|---|
| 184 |
<TT>N32_M3</TT> |
|---|
| 185 |
</TD> |
|---|
| 186 |
<TD ALIGN="CENTER"> |
|---|
| 187 |
<TT>-n32 -mips3</TT> |
|---|
| 188 |
</TD> |
|---|
| 189 |
<TD> |
|---|
| 190 |
Build a new, high-performance 32-bit binary (introduced on |
|---|
| 191 |
IRIX 6.2) using the mips3 ISA |
|---|
| 192 |
</TD> |
|---|
| 193 |
</TR> |
|---|
| 194 |
<TR> |
|---|
| 195 |
<TD ALIGN="RIGHT"> |
|---|
| 196 |
<TT>N32_M4</TT> |
|---|
| 197 |
</TD> |
|---|
| 198 |
<TD ALIGN="CENTER"> |
|---|
| 199 |
<TT>-n32 -mips4</TT> |
|---|
| 200 |
</TD> |
|---|
| 201 |
<TD> |
|---|
| 202 |
Build a new, high-performance 32-bit binary (introduced on |
|---|
| 203 |
IRIX 6.2) using the mips4 ISA |
|---|
| 204 |
</TD> |
|---|
| 205 |
</TR> |
|---|
| 206 |
<TR> |
|---|
| 207 |
<TD ALIGN="RIGHT"> |
|---|
| 208 |
<TT>64_M3</TT> |
|---|
| 209 |
</TD> |
|---|
| 210 |
<TD ALIGN="CENTER"> |
|---|
| 211 |
<TT>-64 -mips3</TT> |
|---|
| 212 |
</TD> |
|---|
| 213 |
<TD> |
|---|
| 214 |
Build a 64-bit binary (introduced on IRIX 6.0) using the mips3 |
|---|
| 215 |
ISA |
|---|
| 216 |
</TD> |
|---|
| 217 |
</TR> |
|---|
| 218 |
<TR> |
|---|
| 219 |
<TD ALIGN="RIGHT"> |
|---|
| 220 |
<TT>64_M4</TT> |
|---|
| 221 |
</TD> |
|---|
| 222 |
<TD ALIGN="CENTER"> |
|---|
| 223 |
<TT>-64 -mips4</TT> |
|---|
| 224 |
</TD> |
|---|
| 225 |
<TD> |
|---|
| 226 |
Build a 64-bit binary (introduced on IRIX 6.0) using the mips4 |
|---|
| 227 |
ISA |
|---|
| 228 |
</TD> |
|---|
| 229 |
</TR> |
|---|
| 230 |
</TABLE> |
|---|
| 231 |
</DIV> |
|---|
| 232 |
|
|---|
| 233 |
<P> |
|---|
| 234 |
|
|---|
| 235 |
<DT><B>--with-threads=[SGI_IPC|POSIX]</B> |
|---|
| 236 |
<DD>Define the type of threading model to use. The default is SGI IPC, |
|---|
| 237 |
but POSIX is used if compiling on HP-UX. |
|---|
| 238 |
<DT><B>--with-jdkhome=[PATH]</B> |
|---|
| 239 |
<DD>Give the Java Development Kit (JDK) installation directory. It |
|---|
| 240 |
defaults to <TT>/usr/java</TT>. This is needed on systems where the |
|---|
| 241 |
JDK is not installed in <TT>/usr/java</TT> or <TT>/usr/local/java</TT> |
|---|
| 242 |
(the fallback installation directory). |
|---|
| 243 |
<DT><B>--with-pfroot=[PATH]</B> |
|---|
| 244 |
<DD>Define the root of the Performer installation. The default is |
|---|
| 245 |
<TT>/usr</TT>. |
|---|
| 246 |
<DT><B>--with-oglroot=[PATH]</B> |
|---|
| 247 |
<DD>Define the root of the OpenGL installation. The default is |
|---|
| 248 |
<TT>/usr</TT>. This is particularly useful on HP-UX where the OpenGL |
|---|
| 249 |
libraries and header files are in <TT>/opt/graphics/OpenGL</TT>. |
|---|
| 250 |
<DT><B>--enable-debug</B> |
|---|
| 251 |
<DD>Enable (or disable) debugging. The default is to have debugging |
|---|
| 252 |
turned on. Enabling debugging defines <B><TT>VJ_DEBUG</TT></B> in |
|---|
| 253 |
<TT>vjDefines.h</TT>. |
|---|
| 254 |
<DT><B>--enable-opengl</B> |
|---|
| 255 |
<DD>Enable the OpenGL API. This is on by default. If this is enabled and |
|---|
| 256 |
the libraries and header files are found, the OpenGL API code in the |
|---|
| 257 |
<TT>Kernel</TT> directory is compiled in. This also defines |
|---|
| 258 |
<B><TT>VJ_API_OPENGL</TT></B> in <TT>vjDefines.h</TT>. |
|---|
| 259 |
<DT><B>--enable-perf</B> |
|---|
| 260 |
<DD>Enable the Performer API. This is on by default. The same holds |
|---|
| 261 |
true here as with the OpenGL API. It defines |
|---|
| 262 |
<B><TT>VJ_API_PERFORMER</TT></B> in <TT>vjDefines.h</TT>. |
|---|
| 263 |
<DT><B>--with-builddir=[PATH]</B> |
|---|
| 264 |
<DD>Define the directory where the library will be built. This is not |
|---|
| 265 |
currently in use. However, it could prove to be useful later. |
|---|
| 266 |
</DL> |
|---|
| 267 |
|
|---|
| 268 |
<HR WIDTH="80%" NOSHADE> |
|---|
| 269 |
|
|---|
| 270 |
<H3>What <I>configure</I> Actually Does</H3> |
|---|
| 271 |
|
|---|
| 272 |
<TT>vjDefines.h</TT> is <TT>#include</TT>'d in all source and header files |
|---|
| 273 |
via <TT>vjConfig.h</TT>. This file is generated by <I>configure</I> in the |
|---|
| 274 |
<TT>build</TT> directory when it is run. In order for the compilers to find |
|---|
| 275 |
it, <TT>-I.</TT> is added to the include path. Sample (possibly outdated) |
|---|
| 276 |
copies of it can be found at: |
|---|
| 277 |
|
|---|
| 278 |
<PRE> |
|---|
| 279 |
~patrick/samples/vjDefines.h-sgiipc |
|---|
| 280 |
~patrick/samples/vjDefines.h-pthreads |
|---|
| 281 |
</PRE> |
|---|
| 282 |
|
|---|
| 283 |
Both of these files were generated using the default values (except for |
|---|
| 284 |
the threading package in the pthreads copy) for SGIs. |
|---|
| 285 |
|
|---|
| 286 |
<P> |
|---|
| 287 |
|
|---|
| 288 |
The <I>configure</I> script will check the host system for the following items |
|---|
| 289 |
when it is run: |
|---|
| 290 |
|
|---|
| 291 |
<UL> |
|---|
| 292 |
<LI>A check is made for which C and C++ compilers to use. On both IRIX and |
|---|
| 293 |
HP-UX, use of <I>gcc</I>(1) and <I>g++</I>(1) are disallowed by forcing |
|---|
| 294 |
the use of the proprietary compilers that have been used for compiling |
|---|
| 295 |
developmental versions of libraries. On HP-UX, use of aC++ |
|---|
| 296 |
(<I>aCC</I>(1), HP's C++ compiler that implements the ANSI X3J16/ISO |
|---|
| 297 |
WG21 C++ Draft Working paper) is required because their <I>CC</I>(1) is |
|---|
| 298 |
<I>really</I> lacking in features. <I>g++</I>(1) 2.7.2.x cannot be used |
|---|
| 299 |
because its C++ Standard Template Library support does not meet the |
|---|
| 300 |
needs of the library code. However, <I>egcs</I>(1) is known to meet |
|---|
| 301 |
the requirements. |
|---|
| 302 |
<LI>If using POSIX threads, it makes sure that the library is there and that |
|---|
| 303 |
the header files are in the include path. On HP-UX, the pthreads code |
|---|
| 304 |
and re-entrant C library are combined in the CMA library, so if the |
|---|
| 305 |
pthreads library is not found, it falls back on a check for the CMA |
|---|
| 306 |
library. After it figures out which library to link, it determines |
|---|
| 307 |
which draft of the POSIX threads standard is in place (either Draft 4 |
|---|
| 308 |
or Draft 10) by checking for <I>pthread_kill</I>(3) that is part of |
|---|
| 309 |
Draft 10 but not Draft 4. If the libraries or header files are not |
|---|
| 310 |
found, the threading implementation falls back on SGI IPC. |
|---|
| 311 |
<LI>If using SGI IPC, a check is made for the header file |
|---|
| 312 |
<TT>sys/prctl.h.</TT> |
|---|
| 313 |
<LI>If neither threading implementation is available, the script exits with |
|---|
| 314 |
an error. |
|---|
| 315 |
<LI>As mentioned above, if the OpenGL and/or Performer APIs are enabled, it |
|---|
| 316 |
checks for the basic libraries (GL and pf respectively) and header |
|---|
| 317 |
files. If not found, the missing API is disabled. If the OpenGL API is |
|---|
| 318 |
not found, the script exits with an error. |
|---|
| 319 |
<LI>A check for <I>sginap</I>(2) is made. If it is not found, an |
|---|
| 320 |
<I>sginap</I>() CPP macro using <I>usleep</I>(2) is defined in |
|---|
| 321 |
<TT>vjDefines.h</TT>. |
|---|
| 322 |
<LI>A check for the header file <TT>sys/z8530.h</TT> is made. This a file |
|---|
| 323 |
that is needed by <TT>Input/vjGlove/vt_serial_io.C</TT> but only exists |
|---|
| 324 |
on SGIs. |
|---|
| 325 |
<LI>Related to the above check, a check is made for <TT>sys/stdsyms.h</TT>. |
|---|
| 326 |
This is a file that defines a lot of CPP macros and such (on HP-UX at |
|---|
| 327 |
least) so that they do not need to be defined in our source files. At |
|---|
| 328 |
present, this file is only included by |
|---|
| 329 |
<TT>Input/vjGlove/vt_serial_io.C</TT>. |
|---|
| 330 |
<LI>Miscellaneous checks are made for several header files and system calls |
|---|
| 331 |
that may not actually be necessary but were added when I generated a |
|---|
| 332 |
generic <I>configure</I> script. These can be removed easily if they |
|---|
| 333 |
are deemed to be unnecessary. The checks include looking for |
|---|
| 334 |
<TT>strings.h</TT>, <TT>fcntl.h</TT>, <I>gettimeofday</I>(3), |
|---|
| 335 |
<I>socket</I>(2), <I>strerror</I>(3), etc. |
|---|
| 336 |
</UL> |
|---|
| 337 |
|
|---|
| 338 |
<HR WIDTH="80%" NOSHADE> |
|---|
| 339 |
|
|---|
| 340 |
<H3>Debugging</H3> |
|---|
| 341 |
|
|---|
| 342 |
While <I>configure</I> runs, a file called <TT>config.log</TT> is constantly |
|---|
| 343 |
updated in <I>configure</I>'s working directory. When something goes wrong |
|---|
| 344 |
with the configuration process, the first thing to do is refer to the bottom |
|---|
| 345 |
of this file to see what was done and why it failed. Debugging the actual |
|---|
| 346 |
script is more difficult. Refer to the documentation on |
|---|
| 347 |
<A HREF="config_maintain.html">maintaining and updating <TT>configure.in</TT> |
|---|
| 348 |
and <TT>Makefile.in</TT></A> for more information relating to this topic. |
|---|
| 349 |
|
|---|
| 350 |
<P> |
|---|
| 351 |
|
|---|
| 352 |
<HR WIDTH="80%" NOSHADE> |
|---|
| 353 |
|
|---|
| 354 |
<H3>Miscellaneous Notes</H3> |
|---|
| 355 |
|
|---|
| 356 |
Only the template files that are used for generating other files are in the |
|---|
| 357 |
CVS repository. This only matters in the base directory where |
|---|
| 358 |
<TT>configure.in</TT> is ``compiled'' to make the <I>configure</I> script and |
|---|
| 359 |
where <TT>acconfig.h</TT> is used to build a <TT>vjDefines.h.in</TT> file. |
|---|
| 360 |
<I>configure</I> is created by running <I>autoconf</I>(1) on |
|---|
| 361 |
<TT>configure.in</TT> and <TT>vjDefines.h.in</TT> is created by running |
|---|
| 362 |
<I>autoheader</I>(1) on <TT>acconfig.h</TT> and <TT>configure.in</TT>. |
|---|
| 363 |
|
|---|
| 364 |
<P> |
|---|
| 365 |
|
|---|
| 366 |
If strange errors occur while compiling (after running <I>configure</I> |
|---|
| 367 |
successfully), check to make sure that all the files are in sync. The |
|---|
| 368 |
revision number at the top of <TT>configure.in</TT> (passed as the parameter |
|---|
| 369 |
to <I>AC_REVISION</I>) and at the top of the <I>configure</I> script must be |
|---|
| 370 |
the same. If they are not, run <I>autoconf</I>(1) to update <I>configure</I> |
|---|
| 371 |
to be in sync with <TT>configure.in</TT>. Also check the revision number at |
|---|
| 372 |
the top of <TT>acconfig.h</TT> (in the line reading ``<TT>Generated from |
|---|
| 373 |
acconfig.h ($Revision x.y$)</TT>'') and at the top of <TT>vjDefines.h.in</TT>. |
|---|
| 374 |
These two lines should be identical. If not, run <I>autoheader</I>(1) to |
|---|
| 375 |
regenerate <TT>vjDefines.h.in</TT> from <TT>acconfig.h</TT>. What can easily |
|---|
| 376 |
happen is a new variable could be added to the <TT>Makefile.in</TT> files that |
|---|
| 377 |
is set with <I>configure</I>, but the revision of <I>configure</I> used will |
|---|
| 378 |
not know about this new symbol and thus will not substitute a value for it. |
|---|
| 379 |
|
|---|
| 380 |
<P> |
|---|
| 381 |
|
|---|
| 382 |
<HR WIDTH="80%" NOSHADE> |
|---|
| 383 |
|
|---|
| 384 |
</BODY> |
|---|
| 385 |
|
|---|
| 386 |
</HTML> |
|---|