added files from PsN-2_2_0_patches_serial missing in MAIN
[PsN.git] / html / developers_guide.php
blobedb5df75b7a3ddf30512d8cbeb71dc8ab577ccce
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html>
3 <head>
4 <title>PsN :: Developer's Guide</title>
5 <!--Adobe(R) LiveMotion(TM) 1.0 Generated JavaScript. Please do not edit. -->
6 <script>
8 <!--
10 function newImage(arg) {
12 if (document.images) {
14 rslt = new Image();
16 rslt.src = arg;
18 return rslt;
24 ImageArray = new Array;
26 var preloadFlag = false;
28 function preloadImages() {
30 if (document.images) {
32 ImageArray[ImageArray.length++] = newImage(/* OWNER('object', 'dflt') *//*URL*/'images/indexhome.jpg');
33 ImageArray[ImageArray.length++] = newImage(/* OWNER('object', 'movr') *//*URL*/'images/indexhomeov.jpg');
34 ImageArray[ImageArray.length++] = newImage(/* OWNER('object1', 'dflt') *//*URL*/'images/indexdocumentation.jpg');
35 ImageArray[ImageArray.length++] = newImage(/* OWNER('object1', 'movr') *//*URL*/'images/indexdocumentationov.jpg');
36 ImageArray[ImageArray.length++] = newImage(/* OWNER('object2', 'dflt') *//*URL*/'images/indexdownload.jpg');
37 ImageArray[ImageArray.length++] = newImage(/* OWNER('object2', 'movr') *//*URL*/'images/indexdownloadov.jpg');
38 ImageArray[ImageArray.length++] = newImage(/* OWNER('object3', 'dflt') *//*URL*/'images/indexbuglist.jpg');
39 ImageArray[ImageArray.length++] = newImage(/* OWNER('object3', 'movr') *//*URL*/'images/indexbuglistov.jpg');
40 ImageArray[ImageArray.length++] = newImage(/* OWNER('object4', 'dflt') *//*URL*/'images/indexmailing_list.jpg');
41 ImageArray[ImageArray.length++] = newImage(/* OWNER('object4', 'movr') *//*URL*/'images/indexmailing_listov.jpg');
42 preloadFlag = true;
45 function changeImages() {
46 if (document.images && (preloadFlag == true)) {
47 for (var i=0; i<changeImages.arguments.length; i+=2) {
48 document[changeImages.arguments[i]].src = changeImages.arguments[i+1];
52 // -->
53 </script><!-- End generated JavaScript. -->
54 <meta http-equiv="Content-Type"
55 content="text/html; charset=ISO-8859-1">
56 <style type="text/css">
57 <!--
58 body,td,th {
59 font-family: Helvetica, Arial, serif;
60 font-size: 12px;
61 color: #000000;
63 body {
64 margin-left: 6px;
65 margin-top: 0px;
66 margin-right: 0px;
67 margin-bottom: 0px;
68 background-image: url(gfx/bg.jpg);
70 .style1 {
71 font-size: 36px;
72 font-weight: bold;
74 .heading1 {
75 font-size: 16px;
76 font-weight: bold;
77 color: #333399;
78 margin-left: 40px;
80 a:link {
81 color: #656D9C;
82 text-decoration: none;
84 a:visited {
85 color: #656D9C;
86 text-decoration: none;
88 a:hover {
89 color: #AF9D49;
90 text-decoration: none;
92 a:active {
93 color: #656D9C;
94 text-decoration: none;
96 -->
97 </style>
98 <script language="JavaScript" type="text/JavaScript">
99 <!--
100 function MM_reloadPage(init) { //reloads the window if Nav4 resized
101 if (init==true) with (navigator) {if ((appName=="Netscape")&&(parseInt(appVersion)==4)) {
102 document.MM_pgW=innerWidth; document.MM_pgH=innerHeight; onresize=MM_reloadPage; }}
103 else if (innerWidth!=document.MM_pgW || innerHeight!=document.MM_pgH) location.reload();
105 MM_reloadPage(true);
106 //-->
107 </script>
108 <meta content="Pontus Pihlgren" name="author">
109 </head>
110 <body onload="preloadImages();"
111 style="background-color: rgb(255, 255, 255);">
112 <!-- The table is not formatted nicely because some browsers cannot join images in table cells if there are any hard carriage returns in a TD. -->
113 <div id="Layer1"
114 style="position: absolute; left: 335px; top: 42px; width: 388px; height: 43px; z-index: 1; font-size: x-small;">
115 <div class="style1" align="right">Developer's
116 Guide<br>
117 </div>
118 </div>
119 <div id="Layer2"
120 style="position: absolute; z-index: 2; width: 497px; left: 226px; top: 188px; height: 2972px;">
121 <h3 style="margin-left: 40px;" class="heading1">Introduction</h3>
122 <div style="text-align: justify;">
123 So you want to dig into the PsN code. Maybe you want to write a new
124 tool for the toolkit or just learn more about PsN. Either way, here you
125 will find what you need to learn how to use PsN as well as writing nice
126 maintainable and readable code in the spirit of PsN. <br>
127 </div>
128 <p style="text-align: justify;">To
129 fully apprecieate this document
130 you should have some coding
131 experience and should have worked with object oriented programming. If
132 you know about UML and XML that is a bonus. If you don't know about
133 these fancy things, don't sweat it, We'll try to keep it as simple as
134 possible.</p>
135 <h3 style="margin-left: 40px;" class="heading1">Dia
136 and Dia2Code</h3>
137 <p style="text-align: justify;">
138 PsN is written in <a target="_blank" href="http://www.perl.org/">Perl</a>.
139 Perl is powerful, good at text manipulation and system interaction and
141 very flexible. A little too flexible for a piece of software the size
143 PsN. When we took the first steps to making PsN object oriented we felt
144 that defining the object structure in Perl was a bit cumbersome. Also,
145 Perl lacks type-checking, which very much eases debugging. Adding that
146 manually for accessors and methods in all of PsN's classes would be
147 time-consuming and probably wouldn't be done homogenous and be
148 difficult
149 to maintain. Our answer to the hurdles is <a target="_blank"
150 href="http://www.gnome.org/projects/dia/">Dia</a>.
151 Dia is a GTK+ based diagram creation program released under the GPL
152 license. </p>
153 <p style="text-align: justify;">With
154 Dia, we have created UML
155 diagrams for all classes in PsN. Dia saves
156 its diagrams in XML format. This allows us to generate code through <a
157 target="_blank" href="http://dia2code.sourceforge.net/">Dia2Code</a>.
158 Dia2Code is a small utility used to generate code from a Dia diagram.
159 Dia2Code didn't support Perl, so we added a plugin to it that generates
160 appropriate code. It gave us freedom in how we do type checking, and
161 how accessors
162 and methods are created. </p>
163 <p> In order to produce
164 usable PsN code from the diagrams it takes three steps. </p>
165 <ol>
166 <li>
167 <div style="text-align: justify;">
168 <p> The first is to
169 create a Dia UML diagram that defines classes complete with typed
170 members, methods and inheritance between classes.</p>
171 </div>
172 <p style="text-align: justify;">Read
173 our <a href="dia_index.php">Dia
174 UML guide</a> for details. You can
175 also have a look at the Dia authors' <a target="_blank"
176 href="http://www.gnome.org/projects/dia/diatut/all/all.html">tutorial</a>
177 on how to use Dia. </p>
178 <p> </p>
179 </li>
180 <li>
181 <p style="text-align: justify;">The
182 second step is to
183 add code that goes into the class structure skeleton generated by
184 Dia2Code. As described in step three.</p>
185 <p style="text-align: justify;">Dia2Code
186 will, for
187 each class, generate a constructor(a method named "new"), a skeleton
188 for each class method and accessors for each class member. Each members
189 accessor can take one argument, that argument will then be set as the
190 new value for the member. If no argument is given, the accessor will
191 return the current value of the accessor. </p>
192 <p style="text-align: justify;">Both
193 accessors and
194 constructor are in fact perl methods, but since
195 Dia2Code writes slightly different skeletons for them, we give them
196 different names to ease discussion. </p>
197 <p style="text-align: justify;">
198 Now, for every
199 method you can add your own code (Otherwise it would be rather
200 pointless, wouldn't it). You can also add code to the constructur, and
201 to accessors (something we don't do much, but there are cases where it
202 might be useful). </p>
203 <p style="text-align: justify;">To
204 add your own code you
205 must create a file parallel to the file
206 generated by Dia2Code. So, for example, we can look the class <tt>"problem"</tt>
207 defined in <tt>"model.dia"</tt>.
208 Dia2Code would generate the file: </p>
209 <blockquote>
210 <p class="style2"><tt>[
211 Path to PsN Diagrams ]lib/model/problem.pm</tt><br>
212 </p>
213 </blockquote>
214 Then you should create the file:
215 <blockquote>
216 <p class="style2"><tt>[
217 Path to PsN Diagrams ]lib/model/problem_subs.pm</tt><br>
218 </p>
219 </blockquote>
220 <p style="text-align: justify;">The
221 extension <tt>_subs</tt>
222 and the <tt>"lib"</tt>
223 directory is just a convention, you
224 can call it whatever you like, but if you want to use our makefile
225 script described in step three, you should add <tt>_subs</tt>
226 to the filename
227 and put it in the <tt>"lib"</tt>
228 directory. It will make life easier. </p>
229 <p>Note that you should keep
230 the <tt>.pm</tt>
231 extension.</p>
232 <p style="text-align: justify;">
233 In the <tt>_subs</tt>
234 file
235 you add a block of code for each method you need to add. Each block
236 must start with <tt>"start
237 method_name"</tt> and end with <tt>"end
238 method_name"</tt>,
239 Everything in between must be valid Perl code. A typical block might
240 look like this: </p>
241 <blockquote>
242 <p><tt>start
243 nthetas<br>
244 {<br>
245 # returns the number of thetas in the model for the given<br>
246 # problem number.<br>
247 $nthetas = $self -&gt; _parameter_count( 'record' =&gt;
248 'theta', <br>
249 'problem_number' =&gt; $problem_number );<br>
250 }<br>
251 end nthetas</tt></p>
252 </blockquote>
253 <p style="text-align: justify;">What
254 you notice from the
255 example is that you have accecss to any
256 argument that was defined for the method in the Dia diagram. And the <tt>$self</tt>
257 variable which is a reference to the class instance from which
259 method was called (comparable to the <tt>"this"</tt>
260 variable in C++).</p>
261 <p style="text-align: justify;">In
262 the code block for
263 accessors
264 you have access to the variable <tt>$parm</tt>
265 which is the given argument, if any. And in the constructor block(the
266 special method named <tt>"new"</tt>),
267 <tt>$self</tt>
268 is called <tt>$this</tt>
269 for some obscure
270 reason, this might change.</p>
271 <p> </p>
272 </li>
273 <li>
274 <div style="text-align: justify;"></div>
275 <p style="text-align: justify;">The
276 final step is to
277 compile the diagrams and <tt>_subs</tt>
278 files into a functional PsN library. If
279 you have everything installed in place and have not added any new Perl
280 files or diagrams you only need to run make from the diagrams
281 directory. If you have added new files or new classes(which implicitly
282 means Dia2Code will generate files for them) you must add those files
283 to the makefile.</p>
284 <p style="text-align: justify;">
285 You can also choose
286 to run Dia2Code manually. Assuming that you have Dia2Code installed and
287 working you should start your shell and go to the directory where you
288 created the Dia file and type the following: </p>
289 <blockquote>
290 <p class="style2"><tt>dia2code
291 -t perl file.dia</tt></p>
292 </blockquote>
293 <p style="text-align: justify;">Dia2Code
294 will generate a
295 file called <tt>"class.pm"</tt>
296 for each defined class.
297 In each it has defined a Perl package, a constructor (called <tt>new</tt>),
299 method and an accessor.</p>
300 <p style="text-align: justify;">
301 You can now editing
302 this file and add your own code to the skeleton. Notice though, that
303 the file will be overwritten each time you run Dia2Code. We have solved
304 this with a script called fill_diacode.pl that takes code from <tt>file_subs.pm</tt>
305 and puts it into the <tt>file.pm</tt>
306 file generated by Dia. To use <tt>fill_diacode.pl</tt>
307 type: </p>
308 <blockquote>
309 <p class="style2"><tt>fill_diacode.pl
310 file_subs file.pm</tt></p>
311 </blockquote>
312 <p style="text-align: justify;">Now
313 file.pm contains all
314 code and should be ready to run. I suggest you
315 also have perl check it for syntax errors (and enable warnings):</p>
316 <blockquote>
317 <p class="style2"><tt>perl
318 -c -W -t -T file.pm</tt></p>
319 </blockquote>
320 </li>
321 </ol>
322 <p style="text-align: justify;">Now
323 you should at least have an
324 overview of how the system is thought
325 out to work. If you find any inconsistencies or even errors (I'm sure
326 there are), please don't be afraid to contact us with questions.</p>
327 <p style="text-align: justify;"></p>
328 <h3 style="margin-left: 40px;" class="heading1">Coding
329 Style and Conventions</h3>
330 <p style="text-align: justify;">
331 Since there are several
332 developers working on PsN, we have tried to conform to a coding
333 standard. It is not
334 100% enforced throughout PsN and it is not expected that you follow our
335 recommendations to the extreme. Consider our recommendations as
336 friendly guidelines to something we think is readable code. </p>
337 <ul>
338 <li>
339 <div style="text-align: justify;"><span style="font-weight: bold;">Variables</span>
340 - We don't mind
341 long variables, several words are more than OK. But try to limit
342 yourself to four or five words. And for the love of God, don't write
343 them together and capitalize letters, like so: <tt>$thisIsALongAndHardToReadVariableName</tt>.
344 Instead separate word with and
345 underscore and keep them lowercase, like this: <tt>$nice_readable_variable</tt>.
346 <p>Long
347 variable names are
348 only needed when the use of the varible is not entirely clear and is
349 used in a long scope (such as an entire function). In other cases
350 shorter names are allowed (and encouraged) such as <tt>$i</tt>,
351 <tt>$temp</tt>
352 or even <tt>$string</tt>.</p>
353 </div>
354 </li>
355 <li>
356 <p>when it is obvious how the
357 variable is intended to be used. </p>
358 </li>
359 <li>
360 <div style="text-align: justify;"><span style="font-weight: bold;">Loops</span>
361 - In Perl it is easy
362 to write loops with the powerful <tt>foreach</tt>
363 construct. Try to use them as
364 much as you can. In cases where you need an index in the loop, use <tt>$i</tt>
365 as loop variable and keep initial values and loop conditions simple.
366 </div>
367 </li>
368 <li>
369 <p><span style="font-weight: bold;">Conditions</span>
370 - Avoid the <tt>"
371 cond ? this : that"</tt> constructs,
372 they are hard to read!</p>
373 </li>
374 <li style="text-align: justify;">
375 <p><span style="font-weight: bold;">Methods</span>
376 - Method names
377 should be similar to variable names, and should start with double
378 underscores if they are private.</p>
379 </li>
380 </ul>
381 <h3 style="margin-left: 40px;" class="heading1">Error
382 Handling</h3>
383 <p style="text-align: justify;"> To simplify debugging a bit we
384 have created a wrapper around Perl's Carp module. Every Perl file
385 genereted with our perl plugin for Dia2Code uses it. </p>
386 <p style="text-align: justify;"> It is a common Perl module
388 you include it with <tt>use debug;</tt>.
389 Then you have a few methods to print warning messages and die with a
390 bit more detailed error message than is produced by perl <tt>die</tt>
391 function. </p>
392 <p style="text-align: justify;"> The Debug class is a little
393 bit special in that it should never be instantiated. An instance is
394 kept globally which can be accessed by the members of the debug class
395 if they are called statically. Calling a member statically means that
396 you adress them using the Perl module name, for example:</p>
397 <p style="text-align: justify;"> <tt>debug
398 -&gt; level( );</tt></p>
399 <p style="text-align: justify;"> Notice that there is no $ in
400 front of 'debug'. Here level is called "statically". In other words, it
401 means "call a member without an instance".</p>
402 <p style="text-align: justify;"> The reason for this is that
403 debug keeps a "level" variable globaly, which indicates how verbose PsN
404 should be, the higher the level, the more messages you will see. The
405 level variable is numerical, but each level has a name in order to make
406 its use a bit more intuitive. The levels are, starting with the lowest:</p>
407 <p style="text-align: justify;"></p>
408 <dl style="text-align: justify;">
409 <dt style="font-weight: bold;">"fatal"</dt>
410 <dd>only when an error so grave
411 that PsN has to exit, a fatal message may be printed. This is the least
412 amount of messages you can see.</dd>
413 <dt style="font-weight: bold;">"warning"</dt>
414 <dd>When something critical
415 happens, somethings that probably should be examined closer, though not
416 serious enough to exit PsN a warning message may be printed.</dd>
417 <dt style="font-weight: bold;">"information"</dt>
418 <dd>When something out of the
419 ordinary happens and we think the user should be informed, an
420 informational message may be printed.</dd>
421 <dt style="font-weight: bold;">"call_trace"</dt>
422 <dd>This level is mostly used by
423 developers when debugging PsN. If this level is set a message will be
424 printed for each method which is called inside PsN. Needless to say,
425 this will print a lot of text. The only time a user should turn this is
426 when filing a bug report, and only then if a developer thinks it is
427 necessary.</dd>
428 </dl>
429 <div style="text-align: justify;">Setting a higher level than "fatal"
430 also means that message of all
431 lower levels will be printed.
432 </div>
433 <p style="text-align: justify;"> No PsN class may change the
434 level. </p>
435 <p style="text-align: justify;"> The methods available debug
436 are:</p>
437 <p style="text-align: justify;"> </p>
438 <dl>
439 <dt style="text-align: justify;"><b>level(
440 )</b></dt>
441 <dd style="text-align: justify;">If you give a value to level
442 as a single argument, you will set the global level of debug messages.
443 <p> <tt>debug
444 -&gt; level( debug::warning )</tt></p>
445 <p> If you don't give any
446 argument the current level is returned. </p>
447 <p> <tt>my
448 $current_level = debug -&gt; level</tt></p>
449 <p> </p>
450 </dd>
451 <dt style="text-align: justify;"><b>package(
452 )</b></dt>
453 <dd style="text-align: justify;">If you give a value to
454 package as a single argument, you will set the global package of debug
455 messages. If you don't give any argument the current package is
456 returned.
457 <p> <tt>my
458 $current_package = debug -&gt; package</tt></p>
459 <p> </p>
460 </dd>
461 <dt style="text-align: justify;"><b>subroutine(
462 )</b></dt>
463 <dd style="text-align: justify;">If you give a value to
464 subroutine as a single argument, you will set the global subroutine of
465 debug messages.
466 <p> <tt>debug
467 -&gt; subroutine( 'output' )</tt></p>
468 <p> If you don't give any
469 argument the current subroutine is returned. <tt>my
470 $current_subroutine = debug -&gt; subroutine</tt></p>
471 <p> </p>
472 </dd>
473 <dt style="text-align: justify;"><b>level_name(
474 )</b></dt>
475 <dd style="text-align: justify;"><span style="font-family: monospace;">level_name</span>
476 will map an
477 integer in the interval 0 to 3 to a string. The string is the name of
478 the level with that number in the order of levels. ( <span
479 style="font-family: monospace;">"fatal"</span>
480 is lowest
481 and <span style="font-family: monospace;">"call_trace"</span>
482 highest ).
483 <p> <tt>my
484 $level_name = debug -&gt; level_name( level =&gt; 1 )</tt></p>
485 <p> By default it returns the
486 name of the current set level.</p>
487 <p> <tt>my
488 $current_level_name = debug -&gt; level_name;</tt>
489 </p>
490 </dd>
491 <dt style="text-align: justify;"><b>warn_with_trace(
492 )</b></dt>
493 <dd style="text-align: justify;">By default, a trace of
494 function calls is printed when PsN dies. If you like you can set a
495 level for which you like traces to be printed. Notice that all lower
496 level messages will also have a trace printed after them.
497 <p> <tt>debug
498 -&gt; warn_with_trace( debug::warning )</tt>
499 </p>
500 </dd>
501 <dt style="text-align: justify;"><b>warn(
502 )</b></dt>
503 <dd style="text-align: justify;"><span style="font-family: monospace;">debug::warn</span>
504 will print out
505 warning, informational or call_trace messages corresponding to the
506 level specified as argument. <tt>debug::warn</tt>
507 will look at the level given
508 and the global level to see whether anything should be printed.
509 <p> <tt>debug
510 -&gt; warn( level =&gt; debug::warning, message =&gt; "This
511 is a warning" );</tt></p>
512 <p> NOTICE the lack of <tt>"\n"</tt>
514 the end of the message, <tt>debug::warn</tt>
515 will append one <tt>"\n"</tt>.
516 In case there ever is a GUI for PsN <tt>debug::warn</tt>
517 could be used to create a message in the GUI. And in that
518 case, an extra <tt>"\n"</tt>
519 might be annoying. </p>
520 </dd>
521 <dt style="text-align: justify;"><b>die(
522 )</b></dt>
523 <dd>
524 <div style="text-align: justify;"><span
525 style="font-family: monospace;">debug::die</span>
526 is what PsN calls
527 instead of <span style="font-family: monospace;">"die"</span>
528 in order to get a call trace. The given message is
529 allways printed.
530 </div>
531 <p style="text-align: justify;"> <tt>debug
532 -&gt; die( message =&gt; "This message will print, and then PsN
533 will die" );</tt></p>
534 <p style="text-align: justify;"> NOTICE the lack of <span
535 style="font-family: monospace;">"\n"</span>
537 the end of the message, <span style="font-family: monospace;">debug::warn</span>
538 will append one <span style="font-family: monospace;">"\n"</span>.
539 In case there
540 ever is a GUI for PsN debug::doe could be used to create a message in
541 the GUI. And in that case, an extra <span
542 style="font-family: monospace;">"\n"</span> might be annoying. </p>
543 </dd>
544 </dl>
545 <p></p>
546 </div>
547 <table border="0" cellpadding="0" cellspacing="0" width="780">
548 <tbody>
549 <tr>
550 <td height="600" width="780">
551 <table border="0" cellpadding="0" cellspacing="0" width="780">
552 <tbody>
553 <tr>
554 <td colspan="7" height="201" width="780"><img
555 src="images/indexpane1_1_.jpg" name="" alt="" border="0" height="201"
556 width="780"></td>
557 </tr>
558 <tr>
559 <td height="46" width="26"><img
560 src="images/indexpane1_2_.jpg" name="" alt="" border="0" height="46"
561 width="26"></td>
562 <td height="46" width="73"><a href="index.php"
563 onmouseover="changeImages(/*CMP*/ 'object', /*URL*/ 'images/indexhomeov.jpg'); return true;"
564 onmouseout="changeImages(/*CMP*/ 'object', /*URL*/ 'images/indexhome.jpg'); return true;"><img
565 src="images/indexhome.jpg" name="object" alt="Home" border="0"
566 height="46" width="73"></a></td>
567 <td height="46" width="11"><img
568 src="images/indexpane3_2_.jpg" name="" alt="" border="0" height="46"
569 width="11"></td>
570 <td height="46" width="25"><img
571 src="images/indexpane4_2_.jpg" name="" alt="" border="0" height="46"
572 width="25"></td>
573 <td height="46" width="15"><img
574 src="images/indexpane5_2_.jpg" name="" alt="" border="0" height="46"
575 width="15"></td>
576 <td height="46" width="40"><img
577 src="images/indexpane6_2_.jpg" name="" alt="" border="0" height="46"
578 width="40"></td>
579 <td height="46" width="590"><img
580 src="images/indexpane7_2_.jpg" name="" alt="" border="0" height="46"
581 width="590"></td>
582 </tr>
583 <tr>
584 <td colspan="7" height="7" width="780"><img
585 src="images/indexpane1_3_.jpg" name="" alt="" border="0" height="7"
586 width="780"></td>
587 </tr>
588 <tr>
589 <td height="46" width="26"><img
590 src="images/indexpane1_4_.jpg" name="" alt="" border="0" height="46"
591 width="26"></td>
592 <td colspan="5" height="46" width="164"><a href="docs.php"
593 onmouseover="changeImages(/*CMP*/ 'object1', /*URL*/ 'images/indexdocumentationov.jpg'); return true;"
594 onmouseout="changeImages(/*CMP*/ 'object1', /*URL*/ 'images/indexdocumentation.jpg'); return true;"><img
595 src="images/indexdocumentation.jpg" name="object1" alt="Documentation"
596 border="0" height="46" width="164"></a></td>
597 <td height="46" width="590"><img
598 src="images/indexpane7_4_.jpg" name="" alt="" border="0" height="46"
599 width="590"></td>
600 </tr>
601 <tr>
602 <td colspan="7" height="7" width="780"><img
603 src="images/indexpane1_5_.jpg" name="" alt="" border="0" height="7"
604 width="780"></td>
605 </tr>
606 <tr>
607 <td height="46" width="26"><img
608 src="images/indexpane1_6_.jpg" name="" alt="" border="0" height="46"
609 width="26"></td>
610 <td colspan="3" height="46" width="109"><a
611 href="download.php"
612 onmouseover="changeImages(/*CMP*/ 'object2', /*URL*/ 'images/indexdownloadov.jpg'); return true;"
613 onmouseout="changeImages(/*CMP*/ 'object2', /*URL*/ 'images/indexdownload.jpg'); return true;"><img
614 src="images/indexdownload.jpg" name="object2" alt="Download" border="0"
615 height="46" width="109"></a></td>
616 <td colspan="3" height="46" width="645"><img
617 src="images/indexpane5_6_.jpg" name="" alt="" border="0" height="46"
618 width="645"></td>
619 </tr>
620 <tr>
621 <td colspan="7" height="7" width="780"><img
622 src="images/indexpane1_7_.jpg" name="" alt="" border="0" height="7"
623 width="780"></td>
624 </tr>
625 <tr>
626 <td height="46" width="26"><img
627 src="images/indexpane1_8_.jpg" name="" alt="" border="0" height="46"
628 width="26"></td>
629 <td colspan="2" height="46" width="84"><a href="buglist.php"
630 onmouseover="changeImages(/*CMP*/ 'object3', /*URL*/ 'images/indexbuglistov.jpg'); return true;"
631 onmouseout="changeImages(/*CMP*/ 'object3', /*URL*/ 'images/indexbuglist.jpg'); return true;"><img
632 src="images/indexbuglist.jpg" name="object3" alt="Buglist" border="0"
633 height="46" width="84"></a></td>
634 <td colspan="4" height="46" width="670"><img
635 src="images/indexpane4_8_.jpg" name="" alt="" border="0" height="46"
636 width="670"></td>
637 </tr>
638 <tr>
639 <td colspan="7" height="7" width="780"><img
640 src="images/indexpane1_9_.jpg" name="" alt="" border="0" height="7"
641 width="780"></td>
642 </tr>
643 <tr>
644 <td height="46" width="26"><img
645 src="images/indexpane1_10_.jpg" name="" alt="" border="0" height="46"
646 width="26"></td>
647 <td colspan="4" height="46" width="124"><a href="list.php"
648 onmouseover="changeImages(/*CMP*/ 'object4', /*URL*/ 'images/indexmailing_listov.jpg'); return true;"
649 onmouseout="changeImages(/*CMP*/ 'object4', /*URL*/ 'images/indexmailing_list.jpg'); return true;"><img
650 src="images/indexmailing_list.jpg" name="object4" alt="Mailing List"
651 border="0" height="46" width="124"></a></td>
652 <td colspan="2" height="46" width="630"><img
653 src="images/indexpane6_10_.jpg" name="" alt="" border="0" height="46"
654 width="630"></td>
655 </tr>
656 <tr>
657 <td colspan="7" height="141" width="780"><img
658 src="images/indexpane1_11_.jpg" name="" alt="" border="0" height="141"
659 width="780"></td>
660 </tr>
661 </tbody>
662 </table>
663 </td>
664 </tr>
665 <tr>
666 <td><img src="images/is_single_pixel_gif.gif" alt="" height="1"
667 width="780"></td>
668 </tr>
669 </tbody>
670 </table>
671 <!--Adobe(R) LiveMotion(TM) DataMap1.0 DO NOT EDIT
672 end DataMap -->
673 </body>
674 </html>