[Bio] / FigWebServices / pir.cgi Repository:
ViewVC logotype

Annotation of /FigWebServices/pir.cgi

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.26 - (view) (download)

1 : redwards 1.1 # -*- perl -*-
2 :    
3 :     =pod
4 :    
5 :     =head1
6 :    
7 :     Compare some data between SEED and PIR. We probably need to add things like p2p or automatic ftp gets or something like that
8 :    
9 :     =cut
10 :    
11 :     use strict;
12 :     use FIG;
13 :     use HTML;
14 :     use raelib;
15 :     use CGI;
16 :     my $cgi=new CGI;
17 : redwards 1.22 use LWP::Simple qw(!head); # see the caveat in perldoc LWP about importing two head methods.
18 : redwards 1.1
19 :     my $fig;
20 :     eval {
21 :     $fig = new FIG;
22 :     };
23 :    
24 :     if ($@ ne "")
25 :     {
26 :     my $err = $@;
27 :    
28 :     my(@html);
29 :    
30 :     push(@html, $cgi->p("Error connecting to SEED database."));
31 :     if ($err =~ /Could not connect to DBI:.*could not connect to server/)
32 :     {
33 :     push(@html, $cgi->p("Could not connect to relational database of type $FIG_Config::dbms named $FIG_Config::db on port $FIG_Config::dbport."));
34 :     }
35 :     else
36 :     {
37 :     push(@html, $cgi->pre($err));
38 :     }
39 :     &HTML::show_page($cgi, \@html, 1);
40 :     exit;
41 :     }
42 :    
43 :    
44 :    
45 :     $ENV{"PATH"} = "$FIG_Config::bin:$FIG_Config::ext_bin:" . $ENV{"PATH"};
46 :    
47 : redwards 1.22
48 :     # these should probably be in FIG::Config. Oh well.
49 :     my $pir_file_from_pir="$FIG_Config::data/Global/pirsfinfo.dat";
50 :     my $pir_correspondence_file="$FIG_Config::data/Global/pirsfcorrespondence.txt";
51 :     my $pir_source_file="ftp://ftp.pir.georgetown.edu/pir_databases/pirsf/data/pirsfinfo.dat";
52 :    
53 :     # ha ha ha ha ha
54 :     # I am an idiot, and can't spell. so we need to correct that and make sure we always use an e
55 :     if (-e "$FIG_Config::data/Global/pirsfcorrespondance.txt") {rename("$FIG_Config::data/Global/pirsfcorrespondance.txt", $pir_correspondence_file)}
56 :    
57 :    
58 :    
59 : redwards 1.1 my $html = [];
60 :     my $user = $cgi->param('user');
61 :    
62 : redwards 1.19 unshift(@$html, "<TITLE>The SEED - PIR/SEED comparisons </TITLE>\n");
63 : redwards 1.1 # make sure that we read the file at the beginning
64 : redwards 1.26
65 :     unless (-e $pir_file_from_pir) {$html=&check_updates($html); &HTML::show_page($cgi,$html,1); exit(0)}
66 : redwards 1.22 my ($pegbypir, $pirid) =&read_pir_file("initial");
67 :    
68 : redwards 1.1
69 :    
70 : redwards 1.17 if ($cgi->param('submit') eq "Tabulate summary") {
71 : redwards 1.9 $html=&table_annotations($html, $pegbypir, $pirid);
72 : redwards 1.22 push @$html, $cgi->p({class=>"diagnostic"}, ("\n<small>Generating this table took approximately " . (time-$^T) . " seconds\n</small>"));
73 :     }
74 : redwards 1.24 elsif ($cgi->param('submit') =~ m/^Update/) {
75 :     # this should catch Update Data and Updata Anyway
76 :     $html=&update_data($html);
77 :     }
78 : redwards 1.22 elsif ($cgi->param('submit') eq "Check for updates") {
79 :     $html=&check_updates($html);
80 :     push @$html, $cgi->p({class=>"diagnostic"}, ("\n<small>Checking for updates took approximately " . (time-$^T) . " seconds\n</small>"));
81 : redwards 1.5 }
82 : redwards 1.17 elsif ($cgi->param('pirsf') && !($cgi->param('submit') eq "Update view")) {
83 : overbeek 1.21 # we want to display one of the correspondences
84 : redwards 1.5 my $selfurl=$cgi->url;
85 : redwards 1.23 push @$html, $cgi->p, "<a href=\"/FIG/Html/pir.html#correspondence\" class=\"help\" target=\"pirhelp\">Help on this correspondence table</a>";
86 : redwards 1.22 if ($cgi->param('ssonly')) {push @$html, "<a href=\"$selfurl?pirsf=" . $cgi->param("pirsf") . "&user=$user\">Show All Matches</a>\n"}
87 :     else {push @$html, "<a href=\"$selfurl?pirsf=" . $cgi->param("pirsf") . "&ssonly='1'&user=$user\">Show only matches with a subsystem</a>\n"}
88 : redwards 1.5
89 : overbeek 1.21 my $col_hdrs = ["PIR Superfamily<br><small>Link goes to PIR<small>", "Genome", "UniProt","PEG", "FIG Function", "FIG Subsystem"];
90 : redwards 1.1 my $tab = [];
91 : redwards 1.22
92 :     # figure out the colors
93 : redwards 1.23 my %color;
94 :     {
95 :     my %function_cnt; my $max;
96 :     foreach my $peg (@{$pegbypir->{$cgi->param('pirsf')}}) {
97 :     $function_cnt{scalar $fig->function_of($peg)}++;
98 :     }
99 :    
100 :     my @all_functions=sort {$function_cnt{$b} <=> $function_cnt{$a}} keys %function_cnt;
101 :     my @color=&cool_colors();
102 :    
103 :     for (my $i=0; $i<=$#all_functions; $i++) {
104 :     if ($i > $#color) {$color{$all_functions[$i]}="#FFFFFF"}
105 :     else {$color{$all_functions[$i]}=$color[$i]}
106 :     }
107 : redwards 1.22 }
108 :    
109 : redwards 1.2 foreach my $peg (@{$pegbypir->{$cgi->param('pirsf')}}) {
110 : redwards 1.1 my @sslinks;
111 :     foreach my $subsys ($fig->subsystems_for_peg($peg)) {
112 : redwards 1.22 my $spaced=$$subsys[0];
113 :     $spaced =~ s/_/ /g;
114 :     push @sslinks, $cgi->a({href => "subsys.cgi?&user=$user&ssa_name=" . $$subsys[0] . "&request=show_ssa"}, $spaced);
115 : redwards 1.1 }
116 :    
117 :     my $pirlink=$cgi->param('pirsf');
118 : redwards 1.2 $pirlink =~ /^PIR(SF\d+)/;
119 :     $pirlink="<a href='http://pir.georgetown.edu/sfcs-cgi/new/pirclassif.pl?id=$1'>PIR$1</a>" . $pirid->{$cgi->param('pirsf')};
120 : redwards 1.4 next if ($cgi->param("ssonly") && !(scalar @sslinks));
121 : redwards 1.22 push (@$tab,
122 :     [$pirlink,
123 :     $fig->genus_species($fig->genome_of($peg)),
124 :     &HTML::uni_link($cgi,$fig->to_alias($peg,"uni")),
125 :     &HTML::fid_link($cgi, $peg, 1),
126 : redwards 1.23 [scalar $fig->function_of($peg), "td style=\"background: $color{scalar $fig->function_of($peg)}\""],
127 : redwards 1.22 (join ", ", @sslinks)]
128 :     );
129 : redwards 1.1 }
130 : redwards 1.22 push(@$html,&HTML::make_table($col_hdrs,$tab,"\nCorrespondence between SEED and PIR"));
131 : redwards 1.1 }
132 :     else {
133 :     unshift @$html, "<TITLE>The SEED - PIR comparison page</TITLE>\n";
134 :     &show_initial($fig,$cgi,$html);
135 :     }
136 :    
137 :     &HTML::show_page($cgi,$html,1);
138 :     exit;
139 :    
140 :    
141 :    
142 :    
143 :    
144 :     sub show_initial {
145 :     my ($fig,$cgi,$html)=@_;
146 :     # generate a blank page
147 :     # we want a list of all functions that have >= 1 peg unless we want all
148 :     my $min=10;
149 :     if ($cgi->param("min")) {$min=$cgi->param("min")}
150 :     if ($cgi->param("showall")) {$min=0}
151 :     my $full=1;
152 :     if ($cgi->param("preliminary")) {$full=0}
153 :     # count different subsystems per sf
154 : redwards 1.26 my $textlimit;
155 :     $cgi->param('textlimit') && ($textlimit = $cgi->param('textlimit'));
156 : redwards 1.1 my $ss; my @pirsf;
157 : redwards 1.2 foreach my $sf (keys %$pegbypir) {
158 :     next unless ($pegbypir->{$sf});
159 :     next unless (scalar @{$pegbypir->{$sf}} >= $min);
160 :     next if ($full && $pirid->{$sf} =~ /\(preliminary\)/i);
161 :     next if (!$full && $pirid->{$sf} =~ /\(full/i);
162 : redwards 1.26 next if ($textlimit && !($pirid->{$sf} =~ m/$textlimit/i || $sf =~ m/$textlimit/i));
163 : redwards 1.1 push @pirsf, $sf;
164 :     if ($cgi->param('showsubsys')) {
165 : redwards 1.2 foreach my $peg (@{$pegbypir->{$sf}}) {
166 : redwards 1.1 foreach my $subsys ($fig->subsystems_for_peg($peg)) {
167 :     $ss->{$sf}->{$$subsys[0]}++;
168 :     }
169 :     }
170 :     }
171 :     }
172 : redwards 1.26
173 : redwards 1.1 # now generate the labels
174 :     my $display;
175 :     foreach my $sf (@pirsf) {
176 :     next unless ($sf);
177 : redwards 1.26 my $displayname=$sf . " " . $pirid->{$sf};
178 : redwards 1.1 if (length($displayname) > 50) {$displayname=substr($displayname, 0, 50)}
179 : redwards 1.2 if ($cgi->param('showsubsys')) {$display->{$sf}=$displayname . " [". scalar @{$pegbypir->{$sf}} . "/". (scalar keys %{$ss->{$sf}}) . "]"}
180 :     else {$display->{$sf}=$displayname . " [". scalar @{$pegbypir->{$sf}} . "]"}
181 : redwards 1.1 }
182 :    
183 : redwards 1.26 unshift @pirsf, ''; $display->{''}='';
184 :     my $size=10;
185 :     if (scalar keys %$display < $size) {$size=scalar keys %$display}
186 :    
187 : redwards 1.1 push (@$html, $cgi->start_form(-action => "pir.cgi"),
188 :     $cgi->h2("Please choose your super family"),
189 : redwards 1.22 "\nFirst, please enter a username: ", $cgi->textfield(-name=>"user", -value=>$user), $cgi->p,
190 : redwards 1.23 "\n<a href=\"/FIG/Html/pir.html\" class=\"help\" target=\"pirhelp\">Help on SEED/PIR Correspondence</a>",
191 : redwards 1.22 "\nThe list shows the PIR superfamilies. If only one number is shown (default) this is the number of PEGs that map to that superfamily. ",
192 :     "\nIf you choose to show subsystem counts in this menu, you will get two numbers. The first of the two numbers in parenthesis is the number ",
193 :     "\nof PEGs that map to that superfamily, and the second number in parenthesis is the number of <em>different</em> ",
194 :     "\nsubsystems that those PEGs are in.\n", $cgi->p,"\n",
195 : redwards 1.26 $cgi->scrolling_list(-name=>'pirsf', -values=>[keys %$display], -labels=>$display, -size=>$size), $cgi->p,"\n",
196 : redwards 1.22 "\nNummber of superfamilies shown: ", scalar keys %$display, $cgi->p,"\n",
197 : redwards 1.23 "\n<a href=\"/FIG/Html/pir.html#menu\" class=\"help\" target=\"pirhelp\">Help on the menu contents</a>","\n",
198 : redwards 1.22 "\nMinimum number of pegs per PIR superfamily shown in list &nbsp; <input type='text' name='min' value='$min' size=3 />","\n",
199 :     "\nor show all PIR superfamilies: ", $cgi->checkbox(-name=>"showall", -label=>""), $cgi->p,"\n",
200 :     $cgi->checkbox(-name=>"showsubsys", -label=>"Show subsystem counts in list"), $cgi->p,"\n",
201 :     $cgi->checkbox(-name=>"preliminary", -label=>"Show only preliminary PIR superfamilies"), $cgi->p,"\n",
202 : redwards 1.26 "Limit the list to some text: ", $cgi->textfield(-name=>'textlimit', -size=>20), $cgi->p, "\n",
203 :     $cgi->submit('submit', 'Recreate List'),"\n",
204 : redwards 1.22 $cgi->submit('submit', 'Show Correspondence'),"\n",
205 :     $cgi->reset,"\n",
206 :     $cgi->p, $cgi->hr, $cgi->p,"\n",
207 :     $cgi->p("<strong>Generate Data Tables</strong>"),
208 : redwards 1.23 "<a href=\"/FIG/Html/pir.html#datatables\" class=\"help\" target=\"pirhelp\">Help on Generating Data Tables</a>",
209 : redwards 1.22 $cgi->p("The data tables are an alternative way to view the data in summary form. For the summary of the comparisons between PIR and SEED annotations, please check here:\n"),
210 :     $cgi->checkbox(-name=>"onlyss", -label=>"Show only those PEGs that are in a subsystem and a superfamily", -checked=>"on"), $cgi->p,"\n",
211 :     $cgi->checkbox(-name=>"totalsort", -label=>"Sort by the total number of different annotations"), $cgi->p,"\n",
212 :     $cgi->submit('submit', 'Tabulate summary'),"\n",
213 :     $cgi->reset,"\n",
214 :     $cgi->p, $cgi->hr, "\n",
215 :     $cgi->p("<strong>Check for Updates</strong>"),"\n",
216 : redwards 1.23 "<a href=\"/FIG/Html/pir.html#updates\" class=\"help\" target=\"pirhelp\">Help on updates</a>", "\n",
217 : redwards 1.22 $cgi->p("Please click the button to check the PIR site and see whether there is a new version of the PIR superfamily data you should use"),"\n",
218 :     $cgi->submit('submit', 'Check for updates'),"\n",
219 : redwards 1.1 $cgi->end_form,
220 :     );
221 :    
222 :     }
223 :    
224 :    
225 :    
226 :     =head1 read_pir_file
227 :    
228 :     Read the PIR data file that describes superfamilies and the PIR proteins that have those families.
229 :     The PIR data file is from ftp://ftp.pir.georgetown.edu/pir_databases/pirsf/data/pirsfinfo.dat and
230 :     contains the family name beginning with a > and then a list of PIR ids.
231 :    
232 : redwards 1.2 I split this using the PIRSF\d+ and return two hashes. One that correlates PIRSF\d+ to fig id and one
233 :     that correlates it to superfamily names.
234 : redwards 1.1
235 :     =cut
236 :    
237 :     sub read_pir_file {
238 : redwards 1.22 unless (-e $pir_file_from_pir) {
239 : redwards 1.23 # background the job here
240 :     &update_data($html);
241 :     }
242 : redwards 1.22 # just read the file, convert it to an HTML table and return it
243 :     unless (-e $pir_correspondence_file) {
244 :     #print STDERR "Can't find the correspondence file pirsfcorrespondence.txt so we are going to make it\n";
245 :     raelib->pirsfcorrespondence($pir_file_from_pir, $pir_correspondence_file);
246 : redwards 1.23 push @$html, "<h2 style=\"background: red\">The PIR correspondence file was rebuilt for you</h2>";
247 : redwards 1.1 }
248 : redwards 1.22 open (IN, $pir_correspondence_file) || die "Can't open $pir_correspondence_file";
249 : redwards 1.1 my $pir;
250 : redwards 1.2 my $functions;
251 :     my $id;
252 : redwards 1.1 my $added;
253 :     while (<IN>) {
254 :     chomp;
255 :     if (s/^>//) {
256 :     unless ($added) {
257 :     # we didn't find anything that maps here
258 : redwards 1.2 $pir->{$id}=undef;
259 : redwards 1.1 }
260 : redwards 1.2 /^(PIRSF\d+)\s+(.*?)$/;
261 :     $id=$1;
262 :     $functions->{$id}=$2;
263 : redwards 1.1 undef $added;
264 :     }
265 :     else {
266 : redwards 1.2 my ($pirid, $peg)=split /\t/;
267 : redwards 1.1 next unless ($peg);
268 : redwards 1.2 push @{$pir->{$id}}, $peg;
269 : redwards 1.1 $added=1;
270 :     }
271 :     }
272 : redwards 1.2 return $pir, $functions;
273 : redwards 1.1 }
274 : redwards 1.5
275 : redwards 1.9 =head1 table_annotations
276 : redwards 1.5
277 : redwards 1.9 Return a table sorted by the number of annotations, and list a bunch of stuff
278 : redwards 1.5
279 :     =cut
280 :    
281 : redwards 1.9 sub table_annotations {
282 :     my ($html, $pegbypir, $pirid)=@_;
283 : redwards 1.12 my $count; my $subsystems; my $countinss;
284 : redwards 1.9 foreach my $sf (keys %$pegbypir) {
285 : redwards 1.12 my $function; my $ss; my $functionandss;
286 : redwards 1.9 foreach my $peg (@{$pegbypir->{$sf}}) {
287 : redwards 1.13 my $fn=scalar $fig->function_of($peg);
288 : redwards 1.16 my $newss=0; # this is a boolean to see whether this peg has a subsys associated with it.
289 :     foreach my $subsys ($fig->subsystems_for_peg($peg)) {$ss->{$$subsys[0]}++; $newss++}
290 : redwards 1.13 $function->{$fn}++;
291 : redwards 1.16 $functionandss->{$fn}++ if ($newss);
292 : redwards 1.5 }
293 : redwards 1.9 $subsystems->{$sf}=join "; ", keys %$ss;
294 :     $count->{$sf}=scalar keys %$function;
295 : redwards 1.12 $countinss->{$sf}=scalar keys %$functionandss;
296 : redwards 1.5 }
297 :    
298 : redwards 1.12 my $col_hdrs = ["Number of annotations in subsystems", "Number of SEED annotations", "PIRSF<br><small>(Link goes to SEED/PIR comparison)</small>",
299 : redwards 1.6 "Superfamily name", "Subsystems in superfamily"];
300 : redwards 1.10 my $tab; my $lastcount; my $row;
301 : redwards 1.12 # note we are going to make a new table every 200 or so rows because that way the browsers don't get messed up. We actually increment between two identical counts
302 :     my @superfamilies=sort {$countinss->{$b} <=> $countinss->{$a}} keys %$count;
303 :     if ($cgi->param('totalsort')) {@superfamilies=sort {$count->{$b} <=> $count->{$a}} keys %$count}
304 :     foreach my $sf (@superfamilies) {
305 :     next if ($cgi->param('onlyss') && !($countinss->{$sf}));
306 : redwards 1.10 $row++;
307 : redwards 1.9 if ($lastcount ne $count->{$sf}) {
308 :     $lastcount=$count->{$sf};
309 : redwards 1.12 if ($tab && ($row > 200)) {
310 : redwards 1.10 push(@$html,&HTML::make_table($col_hdrs,$tab,""));
311 : redwards 1.18 my $et=time-$^T;
312 :     print STDERR "pir.cgi: Added to table at $lastcount after $et total seconds\n";
313 : redwards 1.10 $row=0;
314 :     undef $tab;
315 :     }
316 : redwards 1.9 }
317 :     push @$tab, [
318 : redwards 1.22 "\n".$countinss->{$sf},
319 : redwards 1.9 $count->{$sf},
320 : redwards 1.22 "<a href=\"/FIG/pir.cgi?pirsf=$sf&ssonly='1'&user='$user'\">$sf</a>",
321 : redwards 1.9 $pirid->{$sf},
322 :     $subsystems->{$sf},
323 :     ];
324 : redwards 1.5 }
325 : redwards 1.6 push(@$html,&HTML::make_table($col_hdrs,$tab,""));
326 : redwards 1.5 return $html;
327 :     }
328 : redwards 1.22
329 :    
330 :     =pod
331 :    
332 :     =head2 check_updates()
333 :    
334 :     Check the PIR remote site and see whether there are updates that we need to get
335 :    
336 :     =cut
337 :    
338 :     sub check_updates {
339 :     my $html=shift;
340 :    
341 :     # first lets see if we can get the times of the updates to see if we have a newer file
342 :     # using LWP::Simple. this is straight from the perldoc
343 :     my ($content_type, $document_length, $remotemtime, $expires, $server)=LWP::Simple::head($pir_source_file);
344 :     my $localmtime=0;
345 :     # if we don't have the file yet, we don't want to panic!
346 :     if (-e $pir_file_from_pir) {
347 :     my @stat=stat($pir_file_from_pir);
348 :     $localmtime=$stat[8];
349 :     }
350 :     # now we are going to translate the difference in times into some English for the website
351 :     if (!$remotemtime) {
352 :     push @$html, $cgi->p({class=>"error"}, "Could not connect to PIR to check the status of the PIR file. Please check the location of $pir_source_file");
353 :     }
354 :     elsif ($remotemtime > $localmtime) {
355 :     # the remote version is newer
356 :     push @$html, $cgi->p("\nThe remote file $pir_source_file is newer than your current file. You should proceed with the update."),
357 :     $cgi->p("\nThe remote file was modified on ". scalar(localtime($remotemtime))),
358 :     $cgi->p("\nThe local file was modified on ". scalar(localtime($localmtime))),
359 :     $cgi->start_form(), $cgi->hidden(-name=>"user", -value=>$user), $cgi->submit('submit', 'Update Data'), $cgi->end_form();
360 :     }
361 :     else {
362 :     # the local version is as new as the remote one.
363 :     push @$html, $cgi->p("\nThe local file is up to date and there is no need to update your source PIR superfamilies."),
364 :     $cgi->p("\nThe remote file was modified on ". scalar(localtime($remotemtime))),
365 :     $cgi->p("\nThe local file was modified on ". scalar(localtime($localmtime))),
366 :     $cgi->start_form(), $cgi->hidden(-name=>"user", -value=>$user), $cgi->submit('submit', 'Update Anyway'), $cgi->end_form();
367 :     }
368 :    
369 :     return $html;
370 :     }
371 :    
372 :    
373 :     =pod
374 :    
375 :     =head2 update_data()
376 :    
377 :     Download the new data file from pir, and generate the correspondence
378 :    
379 :     =cut
380 :    
381 :     sub update_data {
382 :     # rename the old correspondence file. We are going to add a number to the old file so that we keep it, but this should allow us
383 :     # to save the information for a while in case something happens. At somepoint we should probably move these to /tmp or delete them
384 :     # or something.
385 :     my $html=shift;
386 : redwards 1.23
387 :     # here we need to background downloading and installing the data.
388 :     my $bkj=$fig->run_in_background(sub
389 :     {
390 : redwards 1.25 my $time=time;
391 :     print "Loading new PIR superfamily data started at ", scalar(localtime($time)), "\n";
392 : redwards 1.24 system("load_pirsf 1");
393 : redwards 1.25 print "Complete at ", scalar(localtime(time)), ". Running took ", (time-$time)/60, " minutes\n";
394 : redwards 1.23 }
395 :     );
396 :    
397 : redwards 1.24 push @$html, "<h2>Downloading and installing new data has started</h2>",
398 :     "<p>The job has started in the background but will likely take some time.<br />\n",
399 :     "The job has an ID of $bkj, and you can check it out from the <A href=\"/FIG/seed_ctl.cgi\">SEED Control Panel</a></p>\n",
400 :     "<p>You should not use the PIR superfamilies while the job is runnning</p>\n";
401 :    
402 : redwards 1.23
403 :     return $html;
404 : redwards 1.22 }
405 :    
406 :    
407 :    
408 :    
409 :    
410 :    
411 :     sub cool_colors {
412 :     # just an array of "websafe" colors or whatever colors we want to use. Feel free to remove bad colors (hence the lines not being equal length!)
413 :     return (
414 :     '#C0C0C0', '#FF40C0', '#FF8040', '#FF0080', '#FFC040', '#40C0FF', '#40FFC0', '#C08080', '#C0FF00', '#00FF80', '#00C040',
415 :     "#6B8E23", "#483D8B", "#2E8B57", "#008000", "#006400", "#800000", "#00FF00", "#7FFFD4",
416 :     "#87CEEB", "#A9A9A9", "#90EE90", "#D2B48C", "#8DBC8F", "#D2691E", "#87CEFA", "#E9967A", "#FFE4C4", "#FFB6C1",
417 :     "#E0FFFF", "#FFA07A", "#DB7093", "#9370DB", "#008B8B", "#FFDEAD", "#DA70D6", "#DCDCDC", "#FF00FF", "#6A5ACD",
418 :     "#00FA9A", "#228B22", "#1E90FF", "#FA8072", "#CD853F", "#DC143C", "#FF6347", "#98FB98", "#4682B4",
419 :     "#D3D3D3", "#7B68EE", "#FF7F50", "#FF69B4", "#BC8F8F", "#A0522D", "#DEB887", "#00DED1",
420 :     "#6495ED", "#800080", "#FFD700", "#F5DEB3", "#66CDAA", "#FF4500", "#4B0082", "#CD5C5C",
421 :     "#EE82EE", "#7CFC00", "#FFFF00", "#191970", "#FFFFE0", "#DDA0DD", "#00BFFF", "#DAA520",
422 :     "#00FF7F", "#9400D3", "#BA55D3", "#D8BFD8", "#8B4513", "#3CB371", "#5F9EA0", "#4169E1", "#20B2AA", "#8A2BE2", "#ADFF2F",
423 :     "#F0FFFF", "#B0E0E6", "#FF1493", "#B8860B", "#FF0000", "#F08080", "#7FFF00", "#8B0000",
424 :     "#40E0D0", "#0000CD", "#48D1CC", "#8B008B", "#696969", "#AFEEEE", "#FF8C00", "#EEE8AA", "#A52A2A",
425 :     "#FFE4B5", "#B0C4DE", "#FAF0E6", "#9ACD32", "#B22222", "#FAFAD2", "#808080", "#0000FF",
426 :     "#000080", "#32CD32", "#FFFACD", "#9932CC", "#FFA500", "#F0E68C", "#E6E6FA", "#F4A460", "#C71585",
427 :     "#BDB76B", "#00FFFF", "#FFDAB9", "#ADD8E6", "#778899",
428 :     );
429 :     }
430 :    

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3