Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl -w
- #
- # .wxg2 --crb3 18Mar14/13may15/20aug15
- #
- # wunderground changed things around. seems an opportune time to
- # adjust things a little...
- # the less extraneal stuff they send, the less I have to flense
- # and the less either side has to expend in bandwidth.
- #
- # --crb3 07May15:
- # especially since they've discontinued the page we were scraping.
- # time to get serious about this minimal version.
- # --crb3 13May15:
- # - Forecast for s/Bedford/Central Middlesex County/
- # - add dating to today-labels
- # --crb3 20Aug15:
- # - WU stops supplying 5-day within the 5day page. go looking;
- # find a suitable 7day at wbz.cbslocal. This time I flense off
- # all the html, then rebuild from hashstructed strings.
- #
- #
- #
- #
- use strict;
- my $uagent="Mozilla/5.0 (compatible; GEM; U; CP/M 2.2; en-US; rv:1.0.0; not a spoon)";
- my $wget="/usr/bin/wget -U \"$uagent\" -O - ";
- my $odir="/home/httpd/html/wx/";
- #my $odir="/home/httpd/html/wx2/wxg"; # or /var/www/html, or...
- my $ofile="wxhr.html"; # "R R WX HR TSUNAMI"
- my $baks=16; # how many rolled-aside backups to keep
- # 10-day in minimal mobile form
- my $u_mobile10day=
- "http://m.wund.com/cgi-bin/findweather/getForecast?brand=mobile&query=01730";
- # lite site, 5-day
- my $u_lite5day=
- # "http://www.wund.com/cgi-bin/findweather/getForecast?query=01730";
- "http://weather.boston.cbslocal.com/cgi-bin/findweather/getForecast?brand=wbz4V3&query=01730";
- my $d5file="wxhr.raw5.html"; # will be used for debugging slice 'n' dice
- my $dXfile="wxhr.rawX.html"; # onsite for review
- my $rightnow=`date`;
- chomp $rightnow;
- my $minsize=1024;
- my $localpixdir="/wx";
- my $origpixdir="http://icons-[a-z]+.wxug.com/graphics/[a-z]+";
- my $origpixdir2="http://icons-[a-z]+.wxug.com(\/[a-z0-9](?=\/))+";
- my $use_alarm=10; # wget-fetch wait in minutes. 0 = don't use.
- # if Net connection can go down (dialup),
- # don't hang around waiting for wget.
- my $hrage=1.99; # hours to expire
- my $refresh=int(($hrage*(60*60)+60)/2);
- my($chatty,$force,$local_debug,$save_dfile)=(0,0,0,0,0);
- my($key,$arg);
- while(defined($ARGV[0]) and index($ARGV[0],'-')==0){
- $arg=shift(@ARGV); # get any the switches
- $key=substr($arg,1,1); # get no-arg switches first
- substr($arg,0,2)="";
- if($key eq "v"){ # verbose?
- $chatty ^= 1;
- next;
- }elsif($key eq "f"){ # olde enuf or not
- $force^=1;
- next;
- }elsif($key eq "D"){ # debug mode
- $local_debug^=1;
- next;
- }elsif($key eq "S"){ # save debug-input file
- $save_dfile^=1;
- next;
- }
- $arg =~ s/^\=//; # handles switch=arg
- $arg=shift(@ARGV) if($arg eq "" and ($ARGV[0] !~ /^\-\w/) );
- # if $arg eq ""; # handles space-separated switch/arg
- # if($key eq "w"){ # waits base
- # $waitbase=$arg;
- # }elsif($key eq "l"){ # number of line to start with
- # $ofsline=0+$arg;
- # }elsif($key eq 'm'){ # match of line to start with
- # $smatch=$arg;
- # }else{
- warn "$0: unrecognized option -$key $arg\n";
- # }
- }
- unless($chatty){
- $wget .= '-q ';
- }
- #my $pdiv;
- $ofile = "debug.$ofile" if $local_debug;
- my $opage="$odir/$ofile";
- #
- # file old enough?
- #
- my $itsage= -M "$opage";
- my $aval=$hrage/24;
- my($lite5day,$mobile10day);
- unless($local_debug){
- if(!$force and ($itsage <= $aval)){
- print "file not old enough yet.\n" if $chatty;
- exit(0);
- }
- #
- # net up?
- #
- unless($force){
- my $netstate=`$wget http://192.168.1.1/netstate.txt`;
- if(index($netstate,'DOWN')>-1){
- print "net not up.\n" if $chatty;
- exit(0);
- }
- }
- $SIG{ALRM}=\&sigalarm_die; # set ALRM handling
- #
- # fetch. did it work?
- #
- alarm($use_alarm*60) if($use_alarm);
- $mobile10day = `$wget \"$u_mobile10day\"`;
- $lite5day = `$wget \"$u_lite5day\"`;
- alarm(0) if($use_alarm);
- my $retv=$?>>8;
- my $bad=0;
- if($retv){
- warn "retv = $retv.\n" if $chatty; $bad=1;
- }
- if(length($mobile10day) < $minsize){
- warn "mobile10day too small.\n" if $chatty; $bad=1;
- }
- if(length($lite5day) < $minsize){
- warn "lite5day too small.\n" if $chatty; $bad=1;
- }
- exit(1) if $bad;
- if($save_dfile){
- if(open(D,">$odir/$d5file")){
- print D $lite5day;
- close(D);
- }else{
- $bad += 5;
- }
- if(open(D,">$odir/$dXfile")){
- print D $mobile10day;
- close(D);
- }else{
- $bad += 10;
- }
- if($bad){
- warn "couldn't write debugging file $odir/$d5file or $odir/$dXfile\n";
- }
- }
- }else{ # debug run using locally-saved input file
- $lite5day=`cat ./$d5file`;
- $mobile10day=`cat ./$dXfile`;
- die "no got!\n" unless(length($lite5day) and length($mobile10day));
- }
- if(0){ #$chatty){
- print "lite5day: "; pr_length($lite5day);
- print "mobile10day: "; pr_length($mobile10day);
- }
- #-----------
- #
- # whack down 5-day to just the data table. we still need to extract
- # details from one setting to another, but the garbage is gone.
- #
- my($pta);
- my $bad=0;
- #my $s_lite='<h2>Forecast for Bedford (01730)</h2>';
- #my $s_lite='<h2>Forecast for Central Middlesex County (01730)</h2>';
- my $s_lite='<div id="sevenday">';
- my $e_lite='<!-- Google - pmims';
- #my $len=length($lite5day);
- if( ($pta=index($lite5day,$s_lite)) >-1){
- substr($lite5day,0,$pta)="";
- if( ($pta=index($lite5day,$e_lite)) >-1){
- $pta += length($e_lite);
- substr($lite5day,$pta)="";
- }else{
- $bad=2;
- }
- }else{
- $bad=1;
- }
- die "can't make sense out of the lite5day page (error: $bad).\n" if $bad;
- my $pc;
- if( ($pc=index($lite5day,$e_lite)) >-1){
- while(substr($lite5day,$pc,1) ne "\n" and $pc>0){
- $pc--;
- }
- if($pc>0){
- substr($lite5day,$pc)="";
- }
- }
- #
- # --crb3 20Aug15:
- # it says 5day on the tin but we're now flensing a 7day source,
- # then throwing away the spare two (because I want 5day dammit).
- # thus, $hcnt is 0..6; twice, because of how the source is divved
- # (none dare say 'tabled')
- #
- my $l5day; # href because the syntax is more consistent
- my $hcnt=0; # hash-count
- my $hcmax=6; # max valid count
- my $hst=0; # hash-building state
- foreach my $ln (split(/\r?\n/,$lite5day)){
- if($hst==0){
- if(index($ln,'<div class="desc">')>-1){
- $hst=1;
- next;
- }elsif(index($ln,'<div class="desc_lo">')>-1){
- $hst=6; # yes there's a gap, it's cuz i'm paranoid
- next; # and we're all explicit here anyway
- }
- }elsif($hst==1){ # grab next line with dayname in it
- $hst=2;
- $ln =~ s/^\s+//;
- $l5day->{$hcnt}->{n}=$ln;
- next;
- }elsif($hst==2){ # grab next line with wx-icon IMG name in it
- $ln =~ s/^\s+\<img\s.*src\=\"//;
- $ln =~ s/\"\s+\/\>//; # now is bare graphic url
- $ln =~ s/^http\:.*\///; # now it's just a gifname
- $l5day->{$hcnt}->{i}=$ln;
- $hst=3;
- next;
- }elsif($hst==3){ # grab next line with short description string in it
- $ln =~ s/\s+\<div class\=\"cond\"\>//;
- $ln =~ s/\<\/div\>.*$//; # addendum just in case eol rubbish
- $l5day->{$hcnt}->{d}=$ln;
- $hcnt++;
- $hcnt=0 if $hcnt>$hcmax;
- $hst=0; # done with this day-chain half
- next;
- }elsif($hst==6){ # grabbing temp strings
- $ln =~ s/\s+\<div\sclass\=\"day\"\>//;
- $ln =~ s/\<\/div\>.*$//;
- $l5day->{$hcnt}->{hilo}=$ln;
- $hst=7;
- next;
- }elsif($hst==7){
- $ln =~ s/\s+\<div\sclass\=\"cond\"\>//;
- $ln =~ s/\<\/div\>.*$//;
- $l5day->{$hcnt}->{t}=$ln;
- $hst=0;
- $hcnt++;
- $hcnt=0 if $hcnt>$hcmax;
- next;
- }
- }
- #
- # now to build a display from a hashstruct.
- #
- #
- #
- $lite5day=<<EOT;
- <h2>5-day Forecast for Bedford</h2>
- <table align="center" width="100%">
- <tr>
- EOT
- foreach $hcnt (0..4){ # only 5day, remember
- $l5day->{$hcnt}->{d} =~ s/ /\ \;/g;
- $l5day->{$hcnt}->{i}=
- '<img src="'
- . '/wx/'
- . $l5day->{$hcnt}->{i}
- . '.gif'
- . '" />';
- my($h,$l)=split(/\ \;\/\ \;/,$l5day->{$hcnt}->{t});
- $l5day->{$hcnt}->{t}=
- '<div><span class="hi">H <span>'
- . $h
- . '</span>°</span> / <span class="lo">L <span>'
- . $l
- . '</span>°</span></div>';
- $lite5day .= <<EOT;
- <td valign="top" width="20%" align="center">
- <span><b>$l5day->{$hcnt}->{n}</b></span>
- <div>$l5day->{$hcnt}->{i}</div>
- <div>$l5day->{$hcnt}->{d}</div>
- $l5day->{$hcnt}->{t}
- </td>
- EOT
- }
- # $l5day->{$hcnt}->{hilo}<br />
- #</tr>
- #<tr><td colspan="7"><h2> </h2></td></tr>
- $lite5day .= <<EOT;
- </table>
- EOT
- my $add = '<h2> </h2>';
- #my $add = '<tr><td colspan="2"><h2> </h2></td></tr>';
- my $fetch=$lite5day.$add."<br />"; #<br />";
- my $ptb;
- #
- # Now for the mobile 10-day.
- #
- #
- my $m_Xday='Forecast as of <b>'; # landmark on this
- my $s_Xday='<center>'; # backstep to this...
- my $e_Xday="</td></tr></table>\n"; # search forward to this...
- # ...and lose everything outside those two points.
- if( ($pta=index($mobile10day,$m_Xday)) >-1){
- $ptb=$pta;
- while(substr($mobile10day,$pta,length($s_Xday)) ne $s_Xday and $pta>0){
- $pta--;
- }
- if($pta>0){
- if( ($ptb=index($mobile10day,$e_Xday,$ptb)) >-1){
- $ptb += length($e_Xday);
- substr($mobile10day,$ptb)=""; # lose the tail cruft
- substr($mobile10day,0,$pta)=""; # lose the head cruft
- }else{
- warn "Can't shave mobile10day\n";
- }
- }else{
- warn "Can't parse mobile10day\n";
- }
- }else{
- warn "mobile10day doesn't look right at all\n";
- }
- #
- # get rid of crud, swapping in tabletopping. draw a fresh bead
- # on the top mark first because we shaved things. well, actually
- # it's right at the start.
- #
- #$e_Xday="</center>\n</td>\n</tr>";
- $e_Xday="</tr><tr>";
- my $r_Xday="\n <table>\n <tr><td></td><td></td></tr>\n<tr>";
- if( ($pta=index($mobile10day,$s_Xday)) ==0){ #>-1){
- if( ($ptb=index($mobile10day,$e_Xday,$pta)) >-1){
- $ptb += length($e_Xday);
- substr($mobile10day,$pta,$ptb-$pta)=""; #$r_Xday;
- }else{
- warn "10day crud end not found\n";
- }
- }else{
- warn "10day crud start not found\n";
- }
- #
- # get rid of tail-end stuff too
- #
- $m_Xday="Marine Information";
- $s_Xday="<div align";
- $e_Xday="</div>";
- blk_flense(\$mobile10day,$m_Xday,$s_Xday,$e_Xday);
- $m_Xday="Scientific forecaster";
- blk_flense(\$mobile10day,$m_Xday,$s_Xday,$e_Xday);
- $m_Xday="National Weather Service:";
- $s_Xday="<br />\n";
- #$s_Xday='\t<table border="0" cellspacing="0" cellpadding="0">';
- $e_Xday='</table><br />';
- blk_flense(\$mobile10day,$m_Xday,$s_Xday,$e_Xday);
- while($mobile10day =~ /^\r?\n/){
- $mobile10day =~ s/^\r?\n//;
- }
- $mobile10day =~ s/^\<td align\=\"left\"\>\r?\n?//;
- #
- # Impose our framing to get a more dense display
- # -- paste in abs MIL dates while we're at it
- # ...maybe even styling.
- #
- my $framing;
- $framing = $r_Xday;
- #$mobile10day =~ s/substr($r_Xday,1)//;
- $mobile10day =~ s/\r?\n?\<tr\>\r?\n\<td align\=\"left\"\>//;
- # $mobile10day =~ s/\<br \/\>\r?\n?$/\r\n/g;
- while($mobile10day =~ /\r?\n$/){
- $mobile10day =~ s/\r?\n$//;
- }
- if( ($pta=rindex($mobile10day,"</td></tr></table>")) >-1){
- substr($mobile10day,$pta)="";
- }
- if(1){ #$save_dfile){
- my $debugf="/home/httpd/html/wx2/dump10day.html";
- if(open(DUMPF,">$debugf")){
- print DUMPF $mobile10day;
- close(DUMPF);
- }
- }
- my(@lines,$ln,$pic,$dayn,$txt);
- my $ct=0;
- @lines=split(/\r?\n/,$mobile10day);
- while(@lines and !defined($lines[0])){
- shift(@lines);
- } # flush out any leading empties
- my($dt,%dset,$k,$v);
- my $fmt="+%A:%a %d%b%y"; # longday:shortday DDmonYY
- my $tcnt=0;
- my $dofs="";
- #=" -d \"next $tcnt day\"";
- $dt=`date $dofs \"$fmt\"`; # Wednesday:Wed 05Feb14
- chomp $dt;
- ($k,$v)=split(/\:/,$dt,2); # split off longday from 'Dow 00Mon00' string
- $dset{$k}=$v; # set up normal, then handle day-labels
- $k="Today";
- my($dow,$dat) = split(' ',$v,2);
- $v = "$k $dat";
- $dset{$k}=$v; # so, no change on dow field
- $k="This Afternoon";
- $v = "$k $dat";
- $dset{$k}=$v;
- $k="Tonight";
- $v = "$k $dat";
- $dset{$k}=$v;
- my $toggle=1; # set hi for haste in doing the next entry.
- while($ct < @lines){
- $dayn=$lines[$ct];
- $pic=$lines[$ct+1];
- $txt=$lines[$ct+2];
- $ct += 3;
- #
- # we've left a coupla empty lines and i'm tired of this, so...
- # rather than try to flense them, trigger a 'next' on them.
- # --crb3 09May15: and then special stuff gets tacked on, and
- # that's totally variable. So... Shave it at the point where it
- # doesn't look pretty. The only brittleness I can see is if WU
- # converts to PNGs, and that will take some attention anyway.
- #
- unless(defined($pic) and $pic =~ /\.gif\"/){
- $ct -= 3;
- splice(@lines,$ct);
- next; # or 'last', but it feels better to have the loop end.
- }
- # next unless(defined($pic) and defined($txt));
- $pic =~ s/\<br \/\>$//; # if defined $pic;
- $txt =~ s/\<br \/\>$//; # if defined $txt;
- foreach my $ky (keys %dset){
- $dayn =~ s/$ky/$dset{$ky}/;
- }
- #
- # do date-convert on $dayn. The clockwork setup here rolls the
- # hash, which only ever holds seven days, to stay even with the
- # two-per-day entries, plus the uncertainty over whether the
- # first day has two entries (for day and night) or one (for
- # night). right now, the scraped source has two, but
- # historically that's been variable... and I *really* don't want
- # to have to keep revisiting this code for minor tweaks. this
- # program gets cron-invoked every 2 hrs, and browser refresh is
- # tied to that, so effectively this covers all (2)hours of the
- # day.
- #
- $toggle ^= 1; # one-bit state-counter
- if(!$toggle){
- $tcnt++;
- $dofs = " -d \"next $tcnt day\"";
- $dt=`date $dofs \"$fmt\"`; # Wednesday:Wed 05Feb14
- chomp $dt;
- ($k,$v)=split(/\:/,$dt,2); # split off longday from 'Dow 00Mon00' string
- $dset{$k}=$v;
- #
- # Paste abs MIL dates into the top5 display too, along with any
- # style enforcement...
- #
- # do the 5-day dating en-passant, just the once when the hash
- # first fills up. shortly after this, the hash starts getting
- # overwritten by later dates, so this is exactly the right time.
- #
- if($tcnt==6){
- foreach my $ky (keys %dset){
- $fetch =~ s/$ky/\<b\>$dset{$ky}\<\/b\>/;
- }
- }
- }
- #
- # shove that completed entry into the buffer and get to work on
- # the next one.
- #
- # swapping back and forth between two buffers, mobile10day and
- # framing, is an artifact of debugging which I'm in no hurry to
- # eradicate. it's under 100k of text, right? it's not tubby.
- #
- # <br />
- #
- $framing .= <<EOT;
- <tr>
- <td align="right" width="10%">
- $pic
- </td>
- <td align="left">
- $dayn
- $txt
- </td>
- </tr>
- EOT
- }
- $framing .= "</td></tr></table>";
- $mobile10day=$framing;
- #
- # Done with the Xday? Paste that in too.
- #
- $fetch .= $mobile10day;
- #
- # swap in local icons all at once
- #
- my $fic_url="http://icons.wunderground.com/graphics/conds/2005/";
- my $lic_url="/wx/";
- $fetch =~ s/$fic_url/$lic_url/g;
- $fic_url="http://icons.wunderground.com/graphics/fun_map/";
- $fetch =~ s/$fic_url/$lic_url/g;
- #
- # last thing before emission: rollover earlier fetches.
- # turns out they're useful for figuring out what's outside.
- # is the retarded pun in the renaming obvious enough?
- #
- if($baks){
- do_baks($opage,$baks);
- }
- #
- # now dump the result.
- #
- open(H,">$opage") or die "can't open outfile $opage\n";
- #my $ln;
- while(defined($ln=<DATA>) and index($ln,'__END__')<0){
- if(index($ln,'#PAYLOAD#')>=0){
- print H $fetch;
- }else{
- $ln =~ s/\#UPDATE\#/$rightnow/ if index($ln,'#UPDATE#')>-1;
- $ln =~ s/\#REFRESH\#/$refresh/ if index($ln,'#REFRESH#')>-1;
- print H $ln;
- }
- }
- close(H);
- #######################################
- # do_baks.
- #
- # last thing before emission: rollover earlier fetches.
- # turns out they're useful for figuring out what's outside.
- # is the retarded pun in the renaming obvious enough?
- #
- # blind-rename: we don't care if there's actually something
- # there to rename, just so that anything that is there is
- # rolled out of the way of the incoming fresh take.
- #
- sub do_baks {
- my($opage,$baks)=(@_);
- my($bakct,$obak,$inst,$onst,$plume);
- ($plume=$opage) =~ s/\.html$//;
- for($bakct = 0+$baks;$bakct>0;$bakct -= 1){
- $obak=($bakct-1);
- $inst=sprintf(".b%d",$bakct);
- $onst=($obak ? sprintf(".b%d",$obak) : "");
- rename("$plume$onst.html","$plume$inst.html");
- }
- }
- #
- # sigalarm_die.
- #
- #
- #
- sub sigalarm_die {
- my($sig)=shift(@_);
- warn "Somebody set up us the SIG$sig bomb.\n" if $chatty;
- die;
- }
- #
- # get_daylist.
- #
- # return a shortform list of the current and upcoming days
- # as a hashref. depends on the GNU version of 'date'.
- #
- sub get_daylist {
- my($dt,%dset,$k,$v);
- my $fmt="+%A:%a %d%b%y"; # longday:shortday DDmonYY
- $dt=`date \"$fmt\"`; # Wednesday:Wed 05Feb14
- chomp $dt;
- ($k,$v)=split(/\:/,$dt,2); # split off longday from 'Dow 00Mon00' string
- $dset{$k}=$v;
- $dset{'_todayname'}=$k; # grab longname
- $dset{'Today'}=$v;
- $dset{'This Afternoon'}=$v;
- $dset{'Tonight'}=$v;
- $dset{'Rest of Tonight'}=$v; # ...should be nextday?
- my $tcnt=1; # skip today-count
- while($tcnt<7){ # same process for incremental days
- $dt=`date -d \"next $tcnt day\" \"$fmt\"`;
- chomp $dt;
- ($k,$v)=split(/\:/,$dt,2);
- $dset{$k}=$v;
- $tcnt++;
- }
- while($tcnt<14){ # same process for incremental days
- $dt=`date -d \"next $tcnt day\" \"$fmt\"`;
- chomp $dt;
- ($k,$v)=split(/\:/,$dt,2);
- $dset{$k.'2'}=$v;
- $tcnt++;
- }
- return(\%dset);
- }
- #
- # pr_length.
- #
- # print length of ref'd buffer.
- #
- sub pr_length {
- my($ref)=shift;
- return unless $chatty;
- my $len=length($$ref);
- print "length = $len.\n";
- }
- #
- # blk_flense.
- #
- # factored out: take a landmark, a beginning border, an ending
- # border, and the ref'd text-buffer to flense it from. works
- # directly on the ref'd buffer; reports 1/0.
- #
- sub blk_flense {
- my($tref,$landmark,$fedge,$ledge)=(@_);
- my($pa,$pb);
- unless( ($pa=index($$tref,$landmark)) >-1){
- return(0);
- }
- $pb=$pa;
- $pa-- while substr($$tref,$pa,length($fedge)) ne $fedge and $pa>=0;
- $pb = index($$tref,$ledge,$pb);
- # $pb++ while substr($$tref,$pb,length($ledge)) ne $ledge and $pb <= length($$tref);
- return(0) if ($pa<0 or $pb<0); # > length($$tref);
- $pb += length($ledge);
- substr($$tref,$pa,$pb-$pa)="";
- return(1);
- }
- __DATA__
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
- <head>
- <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
- <meta name="generator" content="wxget, chopped down from weatherunderground pages" />
- <meta http-equiv="pragma" content="no-cache">
- <meta http-equiv="refresh" content="#REFRESH#">
- <link rel="stylesheet" type="text/css" href="/wx/Style_v1_2.css" />
- <link rel="stylesheet" type="text/css" href="/wx/wund_base.css" />
- <title>
- 5-day forecast for 01730 from WeatherUnderground
- </title>
- </head>
- <body>
- <center>
- <h2>
- 5-day forecast for 01730 from WeatherUnderground - Fetched #UPDATE#<br />
- </h2>
- <h4>
- from
- <a href="http://www.wund.com/cgi-bin/findweather/getForecast?query=01730">
- WeatherUnderground (http://www.wund.com)
- </a> -
- <a href="wxhr.b1.html">.</a>
- <a href="wxhr.b2.html">.</a>
- <a href="wxhr.b3.html">.</a>
- <a href="wxhr.b4.html">b4</a>
- <a href="wxhr.b5.html">.</a>
- <a href="wxhr.b6.html">.</a>
- <a href="wxhr.b7.html">.</a>
- <a href="wxhr.b8.html">b8</a>
- <a href="wxhr.b9.html">.</a>
- <a href="wxhr.b10.html">.</a>
- <a href="wxhr.b11.html">.</a>
- <a href="wxhr.b12.html">b12</a>
- <a href="wxhr.b13.html">.</a>
- <a href="wxhr.b14.html">.</a>
- <a href="wxhr.b15.html">.</a>
- <a href="wxhr.b16.html">b16</a>
- <a href="radar.html">radar</a>
- </h4>
- <table align="center" width="60%">
- <tr><td colspan="2">
- #PAYLOAD#
- </td></tr>
- </table>
- </center>
- </body>
- </html>
- __END__
Advertisement
Add Comment
Please, Sign In to add comment