File Coverage

blib/lib/Ham/Reference/QRZ.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Ham::Reference::QRZ;
2              
3             # --------------------------------------------------------------------------
4             # Ham::Reference::QRZ - An interface to the QRZ XML Database Service
5             #
6             # Copyright (c) 2008-2010 Brad McConahay N8QQ.
7             # Cincinnati, Ohio USA
8             # --------------------------------------------------------------------------
9              
10 1     1   27832 use strict;
  1         2  
  1         37  
11 1     1   5 use warnings;
  1         2  
  1         26  
12 1     1   469 use XML::Simple;
  0            
  0            
13             use LWP::UserAgent;
14             use HTML::Entities;
15             use vars qw($VERSION);
16              
17             our $VERSION = '0.03';
18              
19             my $qrz_url = "http://www.qrz.com/xml";
20             my $site_name = 'QRZ XML Database Service';
21             my $default_timeout = 10;
22              
23             sub new
24             {
25             my $class = shift;
26             my %args = @_;
27             my $self = {};
28             bless $self, $class;
29             $self->_set_agent;
30             $self->set_timeout($args{timeout});
31             $self->set_callsign($args{callsign}) if $args{callsign};
32             $self->set_username($args{username}) if $args{username};
33             $self->set_password($args{password}) if $args{password};
34             $self->set_key($args{key}) if $args{key};
35             $self->_clear_errors;
36             return $self;
37             }
38              
39             sub login
40             {
41             my $self = shift;
42             $self->_clear_errors;
43             if (!$self->{_username}) { die "No QRZ subscription username given" }
44             if (!$self->{_password}) { die "No QRZ subscription password given" }
45             my $url = "$qrz_url/bin/xml?username=$self->{_username};password=$self->{_password};agent=$self->{_agent}";
46             my $login = $self->_get_xml($url);
47             if ($login->{Session}->{Error}) {
48             die $login->{Session}->{Error};
49             } elsif (!$login->{Session}->{Key}) {
50             die "Unknown Error - Could not retrieve session key";
51             } else {
52             $self->set_key($login->{Session}->{Key});
53             $self->{_session} = $login->{Session};
54             }
55             }
56              
57             sub set_callsign
58             {
59             my $self = shift;
60             my $callsign = shift;
61             $callsign =~ tr/a-z/A-Z/;
62             $self->{_callsign} = $callsign;
63             $self->{_listing} = {};
64             $self->{_bio} = {};
65             }
66              
67             sub set_username
68             {
69             my $self = shift;
70             my $username = shift;
71             $self->{_username} = $username;
72             }
73              
74             sub set_password
75             {
76             my $self = shift;
77             my $password = shift;
78             $self->{_password} = $password;
79             }
80              
81             sub set_key
82             {
83             my $self = shift;
84             my $key = shift;
85             $self->{_key} = $key;
86             }
87              
88             sub set_timeout
89             {
90             my $self = shift;
91             my $timeout = shift || $default_timeout;
92             $self->{_timeout} = $timeout;
93             }
94              
95             sub get_listing
96             {
97             my $self = shift;
98             $self->_clear_errors;
99             return $self->{_listing} if $self->{_listing}->{call};
100             if (!$self->{_callsign}) {
101             $self->{is_error} = 1;
102             $self->{error_message} = "Can not get data without a callsign";
103             return undef;
104             }
105             if (!$self->{_key}) {
106             $self->login;
107             }
108             my $url = "$qrz_url/bin/xml?s=$self->{_key};callsign=$self->{_callsign}";
109             my $listing = $self->_get_xml($url);
110             if ($listing->{Session}->{Error}) {
111             $self->{is_error} = 1;
112             $self->{error_message} = $listing->{Session}->{Error};
113             return undef;
114             }
115             $self->{_session} = $listing->{Session};
116             $self->{_listing} = $listing->{Callsign};
117             }
118              
119             sub get_bio
120             {
121             my $self = shift;
122             $self->_clear_errors;
123             return $self->{_bio} if $self->{_bio}->{call};
124             if (!$self->{_callsign}) {
125             $self->{is_error} = 1;
126             $self->{error_message} = "Can not get data without a callsign";
127             return undef;
128             }
129             if (!$self->{_key}) {
130             $self->login;
131             }
132             my $url = "$qrz_url/bin/xml?s=$self->{_key};bio=$self->{_callsign}";
133             my $bio = $self->_get_xml($url);
134             if ($bio->{Session}->{Error}) {
135             $self->{is_error} = 1;
136             $self->{error_message} = $bio->{Session}->{Error};
137             return undef;
138             }
139             $self->{_session} = $bio->{Session};
140             $self->{_bio} = $bio->{Bio};
141             }
142              
143             sub get_bio_file
144             {
145             my $self = shift;
146             $self->_clear_errors;
147             $self->get_bio if !$self->{_bio}->{call};
148             if (!$self->{_bio}->{bio}) {
149             $self->{is_error} = 1;
150             $self->{error_message} = 'No URL for bio file is available for this callsign';
151             return undef;
152             }
153             my $url = "$self->{_bio}->{bio}";
154             my $content = $self->_get_http($url);
155             return undef if $self->{is_error};
156             $content =~ s/ / /g; # convert nbsp entity to regular printable spaces
157             $content = decode_entities($content);
158             $content =~ s/<.*?>//g; # strip html
159             return $content;
160             }
161              
162             sub get_dxcc
163             {
164             my $self = shift;
165             $self->_clear_errors;
166             return $self->{_dxcc} if $self->{_dxcc}->{call};
167             if (!$self->{_callsign}) {
168             $self->{is_error} = 1;
169             $self->{error_message} = "Can not get data without a callsign";
170             return undef;
171             }
172             if (!$self->{_key}) {
173             $self->login;
174             }
175             my $url = "$qrz_url/bin/xml?s=$self->{_key};dxcc=$self->{_callsign}";
176             my $bio = $self->_get_xml($url);
177             if ($bio->{Session}->{Error}) {
178             $self->{is_error} = 1;
179             $self->{error_message} = $bio->{Session}->{Error};
180             return undef;
181             }
182             $self->{_session} = $bio->{Session};
183             $self->{_dxcc} = $bio->{DXCC};
184             }
185              
186             sub get_arrl_section
187             {
188             my $self = shift;
189             $self->_clear_errors;
190             $self->get_listing if !$self->{_listing}->{callsign};
191             if (!$self->{_listing}->{state} or (!$self->{_listing}->{county} and $self->{_listing}->{country} ne 'Canada')) {
192             $self->{is_error} = 1;
193             $self->{error_message} = "Unable to look up ARRL Section without state or county";
194             return undef;
195             }
196             my $sections = $self->_get_arrl_sections;
197             my $section = (ref($sections->{$self->{_listing}->{state}}) eq 'HASH') ? $sections->{$self->{_listing}->{state}}->{$self->{_listing}->{county}} : $sections->{$self->{_listing}->{state}};
198             return $section;
199             }
200              
201             sub get_session
202             {
203             my $self = shift;
204             return $self->{_session};
205             }
206              
207              
208             sub is_error { my $self = shift; $self->{is_error} }
209             sub error_message { my $self = shift; $self->{error_message} }
210              
211              
212             # -----------------------
213             # PRIVATE
214             # -----------------------
215              
216             sub _set_agent
217             {
218             my $self = shift;
219             $self->{_agent} = "Ham-Reference-QRZ-$VERSION";
220             }
221              
222             sub _get_xml
223             {
224             my $self = shift;
225             my $url = shift;
226             my $content = $self->_get_http($url);
227             return undef if $self->{is_error};
228             chomp $content;
229             $content =~ s/(\r|\n)//g;
230              
231             $content =~ s/iso8859-1/iso-8859-1/; # added to account for what appears to be an
232             # incorrect encoding declearation string, 2009-10-31 bam
233             my $xs = XML::Simple->new( SuppressEmpty => 0 );
234             my $data = $xs->XMLin($content);
235             return $data;
236             }
237              
238             sub _get_http
239             {
240             my $self = shift;
241             my $url = shift;
242             $self->_clear_errors;
243             my $ua = LWP::UserAgent->new( timeout=>$self->{_timeout} );
244             $ua->agent( $self->{_agent} );
245             my $request = HTTP::Request->new('GET', $url);
246             my $response = $ua->request($request);
247             if (!$response->is_success) {
248             $self->{is_error} = 1;
249             $self->{error_message} = "Could not contact $site_name - ".HTTP::Status::status_message($response->code);
250             return undef;
251             }
252             return $response->content;
253             }
254              
255             sub _clear_errors
256             {
257             my $self = shift;
258             $self->{is_error} = 0;
259             $self->{error_message} = '';
260             }
261              
262             sub _get_arrl_sections {
263             return {
264             'AL' => 'AL',
265             'AK' => 'AK',
266             'AB' => 'AB',
267             'AZ' => 'AZ',
268             'AR' => 'AR',
269             'BC' => 'BC',
270             'CA' => {
271             'Alameda' => 'EB',
272             'Contra Costa' => 'EB',
273             'Napa' => 'EB',
274             'Solano' => 'EB',
275             'Los Angeles' => 'LAX',
276             'Inyo' => 'ORG',
277             'Orange' => 'ORG',
278             'Riverside' => 'ORG',
279             'San Bernardino' => 'ORG',
280             'San Luis Obispo' => 'SB',
281             'Santa Barbara' => 'SB',
282             'Ventura' => 'SB',
283             'Monterey' => 'SCV',
284             'San Benito' => 'SCV',
285             'San Mateo' => 'SCV',
286             'Santa Clara' => 'SCV',
287             'Santa Cruz' => 'SCV',
288             'Imperial' => 'SDG',
289             'San Diego' => 'SDG',
290             'Del Norte' => 'SF',
291             'Humboldt' => 'SF',
292             'Lake' => 'SF',
293             'Marin' => 'SF',
294             'Mendocino' => 'SF',
295             'San Francisco' => 'SF',
296             'Sonoma' => 'SF',
297             'Calaveras' => 'SJV',
298             'Fresno' => 'SJV',
299             'Kern' => 'SJV',
300             'Kings' => 'SJV',
301             'Madera' => 'SJV',
302             'Mariposa' => 'SJV',
303             'Merced' => 'SJV',
304             'Mono' => 'SJV',
305             'San Joaquin' => 'SJV',
306             'Stanislaus' => 'SJV',
307             'Tulare' => 'SJV',
308             'Tuolumne' => 'SJV',
309             'Alpine' => 'SV',
310             'Amador' => 'SV',
311             'Butte' => 'SV',
312             'Colusa' => 'SV',
313             'El Dorado' => 'SV',
314             'Glenn' => 'SV',
315             'Lassen' => 'SV',
316             'Modoc' => 'SV',
317             'Nevada' => 'SV',
318             'Placer' => 'SV',
319             'Plumas' => 'SV',
320             'Sacramento' => 'SV',
321             'Shasta' => 'SV',
322             'Sierra' => 'SV',
323             'Siskiyou' => 'SV',
324             'Sutter' => 'SV',
325             'Tehama' => 'SV',
326             'Trinity' => 'SV',
327             'Yolo' => 'SV',
328             'Yuba' => 'SV'
329             },
330             'CO' => 'CO',
331             'CT' => 'CT',
332             'DE' => 'DE',
333             'DC' => 'MDC',
334             'FL' => {
335             'Alachua' => "NFL",
336             'Lee' => "SFL",
337             'Baker' => "NFL",
338             'Leon' => "NFL",
339             'Bay' => "NFL",
340             'Levy' => "NFL",
341             'Bradford' => "NFL",
342             'Liberty' => "NFL",
343             'Brevard' => "SFL",
344             'Madison' => "NFL",
345             'Broward' => "SFL",
346             'Manatee' => "WCF",
347             'Calhoun' => "NFL",
348             'Marion' => "NFL",
349             'Charlotte' => "WCF",
350             'Martin' => "SFL",
351             'Citrus' => "NFL",
352             'Miami-Dade' => "SFL",
353             'Clay' => "NFL",
354             'Monroe' => "SFL",
355             'Collier' => "SFL",
356             'Nassau' => "NFL",
357             'Columbia' => "NFL",
358             'Okaloosa' => "NFL",
359             'Desoto' => "WCF",
360             'Okeechobee' => "SFL",
361             'Dixie' => "NFL",
362             'Orange' => "NFL",
363             'Duval' => "NFL",
364             'Osceola' => "SFL",
365             'Escambia' => "NFL",
366             'Palm Beach' => "SFL",
367             'Flagler' => "NFL",
368             'Pasco' => "WCF",
369             'Franklin' => "NFL",
370             'Pinellas' => "WCF",
371             'Gadsden' => "NFL",
372             'Polk' => "WCF",
373             'Gilchrist' => "NFL",
374             'Putnam' => "NFL",
375             'Glades' => "SFL",
376             'Santa Rosa' => "NFL",
377             'Gulf' => "NFL",
378             'Sarasota' => "WCF",
379             'Hamilton' => "NFL",
380             'Seminole' => "NFL",
381             'Hardee' => "WCF",
382             'St. Johns' => "NFL",
383             'Hendry' => "SFL",
384             'St. Lucie' => "SFL",
385             'Hernando' => "NFL",
386             'Sumter' => "NFL",
387             'Highlands' => "WCF",
388             'Suwannee' => "NFL",
389             'Hillsborough' => "WCF",
390             'Taylor' => "NFL",
391             'Holmes' => "NFL",
392             'Union' => "NFL",
393             'Indian River' => "SFL",
394             'Volusia' => "NFL",
395             'Jackson' => "NFL",
396             'Wakulla' => "NFL",
397             'Jefferson' => "NFL",
398             'Walton' => "NFL",
399             'Lafayette' => "NFL",
400             'Washington' => "NFL",
401             'Lake' => "NFL"
402             },
403             'GA' => 'GA',
404             'GU' => 'GU',
405             'HI' => 'PAC',
406             'ID' => 'ID',
407             'IL' => 'IL',
408             'IN' => 'IN',
409             'IA' => 'IA',
410             'KS' => 'KS',
411             'KY' => 'KY',
412             'LA' => 'LA',
413             'MA' => {
414             'Barnstable' => 'EMA',
415             'Bristol' => 'EMA',
416             'Dukes' => 'EMA',
417             'Essex' => 'EMA',
418             'Middlesex' => 'EMA',
419             'Nantucket' => 'EMA',
420             'Norfolk' => 'EMA',
421             'Plymouth' => 'EMA',
422             'Berkshire' => 'WMA',
423             'Franklin' => 'WMA',
424             'Hampden' => 'WMA',
425             'Hampshire' => 'WMA',
426             'Worcester' => 'WMA'
427             },
428             'ME' => 'ME',
429             'MB' => 'MB',
430             'MD' => 'MDC',
431             'MI' => 'MI',
432             'MN' => 'MN',
433             'MS' => 'MS',
434             'MO' => 'MO',
435             'MT' => 'MT',
436             'NB' => 'NB',
437             'NC' => 'NC',
438             'ND' => 'ND',
439             'NE' => 'NE',
440             'NH' => 'NH',
441             'NJ' => {
442             'Bergen' => 'NNJ',
443             'Essex' => 'NNJ',
444             'Hudson' => 'NNJ',
445             'Hunterdon' => 'NNJ',
446             'Middlesex' => 'NNJ',
447             'Monmouth' => 'NNJ',
448             'Morris' => 'NNJ',
449             'Passaic' => 'NNJ',
450             'Somerset' => 'NNJ',
451             'Sussex' => 'NNJ',
452             'Union' => 'NNJ',
453             'Warren' => 'NNJ',
454             'Atlantic' => 'SNJ',
455             'Burlington' => 'SNJ',
456             'Camden' => 'SNJ',
457             'Cape May' => 'SNJ',
458             'Cumberland' => 'SNJ',
459             'Gloucester' => 'SNJ',
460             'Mercer' => 'SNJ',
461             'Ocean' => 'SNJ',
462             'Salem' => 'SNJ'
463             },
464             'NL' => 'NL',
465             'NM' => 'NM',
466             'NS' => 'NS',
467             'NT' => 'NT',
468             'NU' => 'NU',
469             'NV' => 'NV',
470             'NY' => {
471             'Bronx' => 'NLI',
472             'New York' => 'NLI',
473             'Kings' => 'NLI',
474             'Queens' => 'NLI',
475             'Richmond' => 'NLI',
476             'Nassau' => 'NLI',
477             'Suffolk' => 'NLI',
478             'Albany' => 'ENY',
479             'Columbia' => 'ENY',
480             'Dutchess' => 'ENY',
481             'Greene' => 'ENY',
482             'Orange' => 'ENY',
483             'Putnam' => 'ENY',
484             'Rensselaer' => 'ENY',
485             'Rockland' => 'ENY',
486             'Saratoga' => 'ENY',
487             'Schenectady' => 'ENY',
488             'Sullivan' => 'ENY',
489             'Ulster' => 'ENY',
490             'Warren' => 'ENY',
491             'Washington' => 'ENY',
492             'Westchester' => 'ENY',
493             'Clinton' => 'NNY',
494             'Essex' => 'NNY',
495             'Franklin' => 'NNY',
496             'Fulton' => 'NNY',
497             'Hamilton' => 'NNY',
498             'Jefferson' => 'NNY',
499             'Lewis' => 'NNY',
500             'Montgomery' => 'NNY',
501             'St. Lawrence' => 'NNY',
502             'Schoharie' => 'NNY',
503             'Allegany' => 'WNY',
504             'Broome' => 'WNY',
505             'Cattaraugus' => 'WNY',
506             'Cayuga' => 'WNY',
507             'Chautauqua' => 'WNY',
508             'Chemung' => 'WNY',
509             'Chenango' => 'WNY',
510             'Cortland' => 'WNY',
511             'Delaware' => 'WNY',
512             'Erie' => 'WNY',
513             'Genesee' => 'WNY',
514             'Herkimer' => 'WNY',
515             'Livingston' => 'WNY',
516             'Madison' => 'WNY',
517             'Monroe' => 'WNY',
518             'Niagara' => 'WNY',
519             'Oneida' => 'WNY',
520             'Onondaga' => 'WNY',
521             'Ontario' => 'WNY',
522             'Orleans' => 'WNY',
523             'Oswego' => 'WNY',
524             'Otsego' => 'WNY',
525             'Schuyler' => 'WNY',
526             'Seneca' => 'WNY',
527             'Steuben' => 'WNY',
528             'Tioga' => 'WNY',
529             'Tompkins' => 'WNY',
530             'Wayne' => 'WNY',
531             'Wyoming' => 'WNY',
532             'Yates' => 'WNY'
533             },
534             'OH' => 'OH',
535             'OK' => 'OK',
536             'ON' => 'ON',
537             'OR' => 'OR',
538             'PA' => {
539             'Adams' => 'EPA',
540             'Berks' => 'EPA',
541             'Bradford' => 'EPA',
542             'Bucks' => 'EPA',
543             'Carbon' => 'EPA',
544             'Chester' => 'EPA',
545             'Columbia' => 'EPA',
546             'Cumberland' => 'EPA',
547             'Dauphin' => 'EPA',
548             'Delaware' => 'EPA',
549             'Juniata' => 'EPA',
550             'Lackawanna' => 'EPA',
551             'Lancaster' => 'EPA',
552             'Lebanon' => 'EPA',
553             'Lehigh' => 'EPA',
554             'Luzerne' => 'EPA',
555             'Lycoming' => 'EPA',
556             'Monroe' => 'EPA',
557             'Montgomery' => 'EPA',
558             'Montour' => 'EPA',
559             'Northhampton' => 'EPA',
560             'Northumberland' => 'EPA',
561             'Perry' => 'EPA',
562             'Philadelphia' => 'EPA',
563             'Pike' => 'EPA',
564             'Schuylkill' => 'EPA',
565             'Snyder' => 'EPA',
566             'Sullivan' => 'EPA',
567             'Susquehanna' => 'EPA',
568             'Tioga' => 'EPA',
569             'Union' => 'EPA',
570             'Wayne' => 'EPA',
571             'Wyoming' => 'EPA',
572             'York' => 'EPA',
573             'Allegheny' => 'WPA',
574             'Armstrong' => 'WPA',
575             'Beaver' => 'WPA',
576             'Bedford' => 'WPA',
577             'Blair' => 'WPA',
578             'Butler' => 'WPA',
579             'Cambria' => 'WPA',
580             'Cameron' => 'WPA',
581             'Centre' => 'WPA',
582             'Clarion' => 'WPA',
583             'Clearfield' => 'WPA',
584             'Clinton' => 'WPA',
585             'Crawford' => 'WPA',
586             'Elk' => 'WPA',
587             'Erie' => 'WPA',
588             'Fayette' => 'WPA',
589             'Franklin' => 'WPA',
590             'Fulton' => 'WPA',
591             'Greene' => 'WPA',
592             'Huntingdon' => 'WPA',
593             'Indiana' => 'WPA',
594             'Jefferson' => 'WPA',
595             'Lawrence' => 'WPA',
596             'McKean' => 'WPA',
597             'Mercer' => 'WPA',
598             'Mifflin' => 'WPA',
599             'Potter' => 'WPA',
600             'Somerset' => 'WPA',
601             'Venango' => 'WPA',
602             'Warren' => 'WPA',
603             'Washington' => 'WPA',
604             'Westmoreland' => 'WPA'
605             },
606             'PE' => 'MAR',
607             'PR' => 'PR',
608             'QC' => 'QC',
609             'RI' => 'RI',
610             'SK' => 'SK',
611             'SC' => 'SC',
612             'SD' => 'SD',
613             'TN' => 'TN',
614             'TX' => {
615             'Anderson' => 'WTX',
616             'Andrews' => 'WTX',
617             'Angelina' => 'STX',
618             'Aransas' => 'STX',
619             'Archer' => 'NTX',
620             'Armstrong' => 'WTX',
621             'Atascosa' => 'STX',
622             'Austin' => 'STX',
623             'Bailey' => 'WTX',
624             'Bandera' => 'STX',
625             'Bastrop' => 'WTX',
626             'Baylor' => 'NTX',
627             'Bee' => 'STX',
628             'Bell' => 'NTX',
629             'Bexar' => 'STX',
630             'Blanco' => 'STX',
631             'Borden' => 'WTX',
632             'Bosque' => 'NTX',
633             'Bowie' => 'NTX',
634             'Brazoria' => 'STX',
635             'Brazos' => 'STX',
636             'Brewster' => 'WTX',
637             'Briscoe' => 'WTX',
638             'Brooks' => 'STX',
639             'Brown' => 'NTX',
640             'Burleson' => 'STX',
641             'Burnet' => 'STX',
642             'Caldwell' => 'STX',
643             'Calhoun' => 'STX',
644             'Callahan' => 'WTX',
645             'Cameron' => 'STX',
646             'Camp' => 'NTX',
647             'Carson' => 'WTX',
648             'Cass' => 'NTX',
649             'Castro' => 'WTX',
650             'Chambers' => 'STX',
651             'Cherokee' => 'NTX',
652             'Childress' => 'WTX',
653             'Clay' => 'NTX',
654             'Cochran' => 'WTX',
655             'Coke' => 'WTX',
656             'Coleman' => 'WTX',
657             'Collin' => 'NTX',
658             'Collingsworth' => 'WTX',
659             'Colorado' => 'STX',
660             'Comal' => 'STX',
661             'Comanche' => 'NTX',
662             'Concho' => 'WTX',
663             'Cooke' => 'NTX',
664             'Coryell' => 'NTX',
665             'Cottle' => 'WTX',
666             'Crane' => 'WTX',
667             'Crockett' => 'WTX',
668             'Crosby' => 'WTX',
669             'Culberson' => 'WTX',
670             'Dallam' => 'WTX',
671             'Dallas' => 'NTX',
672             'Dawson' => 'WTX',
673             'Deaf Smith' => 'WTX',
674             'Delta' => 'NTX',
675             'Denton' => 'NTX',
676             'DeWitt' => 'STX',
677             'Dickens' => 'WTX',
678             'Dimmit' => 'STX',
679             'Donley' => 'WTX',
680             'Duval' => 'STX',
681             'Eastland' => 'NTX',
682             'Ector' => 'WTX',
683             'Edwards' => 'STX',
684             'El Paso' => 'WTX',
685             'Ellis' => 'NTX',
686             'Erath' => 'NTX',
687             'Falls' => 'NTX',
688             'Fannin' => 'NTX',
689             'Fayette' => 'STX',
690             'Fisher' => 'WTX',
691             'Floyd' => 'WTX',
692             'Foard' => 'WTX',
693             'Fort Bend' => 'STX',
694             'Franklin' => 'NTX',
695             'Freestone' => 'NTX',
696             'Frio' => 'STX',
697             'Gaines' => 'WTX',
698             'Galveston' => 'STX',
699             'Garza' => 'WTX',
700             'Gillespie' => 'STX',
701             'Glasscock' => 'WTX',
702             'Goliad' => 'STX',
703             'Gonzales' => 'STX',
704             'Gray' => 'WTX',
705             'Grayson' => 'NTX',
706             'Gregg' => 'NTX',
707             'Grimes' => 'STX',
708             'Guadalupe' => 'STX',
709             'Hale' => 'WTX',
710             'Hall' => 'WTX',
711             'Hamilton' => 'NTX',
712             'Hansford' => 'WTX',
713             'Hardeman' => 'WTX',
714             'Hardin' => 'STX',
715             'Harris' => 'STX',
716             'Harrison' => 'NTX',
717             'Hartley' => 'WTX',
718             'Haskell' => 'WTX',
719             'Hays' => 'STX',
720             'Hemphill' => 'WTX',
721             'Henderson' => 'NTX',
722             'Hidalgo' => 'STX',
723             'Hill' => 'NTX',
724             'Hockley' => 'WTX',
725             'Hood' => 'NTX',
726             'Hopkins' => 'NTX',
727             'Houston' => 'STX',
728             'Howard' => 'WTX',
729             'Hudspeth' => 'WTX',
730             'Hunt' => 'NTX',
731             'Hutchinson' => 'WTX',
732             'Irion' => 'WTX',
733             'Jack' => 'NTX',
734             'Jackson' => 'STX',
735             'Jasper' => 'STX',
736             'Jeff Davis' => 'WTX',
737             'Jefferson' => 'STX',
738             'Jim Hogg' => 'STX',
739             'Jim Wells' => 'STX',
740             'Johnson' => 'NTX',
741             'Jones' => 'WTX',
742             'Karnes' => 'STX',
743             'Kaufman' => 'NTX',
744             'Kendall' => 'STX',
745             'Kenedy' => 'STX',
746             'Kent' => 'WTX',
747             'Kerr' => 'STX',
748             'Kimble' => 'STX',
749             'King' => 'WTX',
750             'Kinney' => 'STX',
751             'Kleberg' => 'STX',
752             'Knox' => 'WTX',
753             'La Salle' => 'STX',
754             'Lamar' => 'NTX',
755             'Lamb' => 'WTX',
756             'Lampasas' => 'NTX',
757             'Lavaca' => 'STX',
758             'Lee' => 'STX',
759             'Leon' => 'STX',
760             'Liberty' => 'STX',
761             'Limestone' => 'NTX',
762             'Lipscomb' => 'WTX',
763             'Live Oak' => 'STX',
764             'Llano' => 'STX',
765             'Loving' => 'WTX',
766             'Lubbock' => 'WTX',
767             'Lynn' => 'WTX',
768             'Madison' => 'STX',
769             'Marion' => 'NTX',
770             'Martin' => 'WTX',
771             'Mason' => 'STX',
772             'Matagorda' => 'STX',
773             'Maverick' => 'STX',
774             'McCulloch' => 'STX',
775             'McLennan' => 'NTX',
776             'McMullen' => 'STX',
777             'Medina' => 'STX',
778             'Menard' => 'STX',
779             'Midland' => 'WTX',
780             'Milam' => 'STX',
781             'Mills' => 'NTX',
782             'Mitchell' => 'WTX',
783             'Montague' => 'NTX',
784             'Montgomery' => 'STX',
785             'Moore' => 'WTX',
786             'Morris' => 'NTX',
787             'Motley' => 'WTX',
788             'Nacogdoches' => 'NTX',
789             'Navarro' => 'NTX',
790             'Newton' => 'STX',
791             'Nolan' => 'WTX',
792             'Nueces' => 'STX',
793             'Ochiltree' => 'WTX',
794             'Oldham' => 'WTX',
795             'Orange' => 'STX',
796             'Palo Pinto' => 'NTX',
797             'Panola' => 'NTX',
798             'Parker' => 'NTX',
799             'Parmer' => 'WTX',
800             'Pecos' => 'WTX',
801             'Polk' => 'STX',
802             'Potter' => 'WTX',
803             'Presidio' => 'WTX',
804             'Rains' => 'NTX',
805             'Randall' => 'WTX',
806             'Reagan' => 'WTX',
807             'Real' => 'STX',
808             'Red River' => 'NTX',
809             'Reeves' => 'WTX',
810             'Refugio' => 'STX',
811             'Roberts' => 'WTX',
812             'Robertson' => 'STX',
813             'Rockwall' => 'NTX',
814             'Runnels' => 'WTX',
815             'Rusk' => 'NTX',
816             'Sabine' => 'STX',
817             'San Augustine' => 'STX',
818             'San Jacinto' => 'STX',
819             'San Patricio' => 'STX',
820             'San Saba' => 'STX',
821             'Schleicher' => 'WTX',
822             'Scurry' => 'WTX',
823             'Shackelford' => 'WTX',
824             'Shelby' => 'NTX',
825             'Sherman' => 'WTX',
826             'Smith' => 'NTX',
827             'Somervell' => 'NTX',
828             'Starr' => 'STX',
829             'Stephens' => 'NTX',
830             'Sterling' => 'WTX',
831             'Stonewall' => 'WTX',
832             'Sutton' => 'WTX',
833             'Swisher' => 'WTX',
834             'Tarrant' => 'NTX',
835             'Taylor' => 'WTX',
836             'Terrell' => 'WTX',
837             'Terry' => 'WTX',
838             'Throckmorton' => 'NTX',
839             'Titus' => 'NTX',
840             'Tom Green' => 'WTX',
841             'Travis' => 'STX',
842             'Trinity' => 'STX',
843             'Tyler' => 'STX',
844             'Upshur' => 'NTX',
845             'Upton' => 'WTX',
846             'Uvalde' => 'STX',
847             'Val Verde' => 'STX',
848             'Van Zandt' => 'NTX',
849             'Victoria' => 'STX',
850             'Walker' => 'STX',
851             'Waller' => 'STX',
852             'Ward' => 'WTX',
853             'Washington' => 'STX',
854             'Webb' => 'STX',
855             'Wharton' => 'STX',
856             'Wheeler' => 'WTX',
857             'Wichita' => 'NTX',
858             'Wilbarger' => 'NTX',
859             'Willacy' => 'STX',
860             'Williamson' => 'STX',
861             'Wilson' => 'STX',
862             'Winkler' => 'WTX',
863             'Wise' => 'NTX',
864             'Wood' => 'NTX',
865             'Yoakum' => 'WTX',
866             'Young' => 'NTX',
867             'Zapata' => 'STX',
868             'Zavala' => 'STX'
869             },
870             'UT' => 'UT',
871             'VT' => 'VT',
872             'VA' => 'VA',
873             'VI' => 'VI',
874             'WA' => {
875             'Adams' => 'EWA',
876             'Asotin' => 'EWA',
877             'Benton' => 'EWA',
878             'Chelan' => 'EWA',
879             'Columbia' => 'EWA',
880             'Douglas' => 'EWA',
881             'Ferry' => 'EWA',
882             'Franklin' => 'EWA',
883             'Garfield' => 'EWA',
884             'Grant' => 'EWA',
885             'Kittitas' => 'EWA',
886             'Klickitat' => 'EWA',
887             'Lincoln' => 'EWA',
888             'Okanogan' => 'EWA',
889             'Pend Oreille' => 'EWA',
890             'Spokane' => 'EWA',
891             'Stevens' => 'EWA',
892             'Walla Walla' => 'EWA',
893             'Whitman' => 'EWA',
894             'Yakima' => 'EWA',
895             'Clallam' => 'WWA',
896             'Clark' => 'WWA',
897             'Cowlitz' => 'WWA',
898             'Grays Harbor' => 'WWA',
899             'Island' => 'WWA',
900             'Jefferson' => 'WWA',
901             'King' => 'WWA',
902             'Kitsap' => 'WWA',
903             'Lewis' => 'WWA',
904             'Mason' => 'WWA',
905             'Pacific' => 'WWA',
906             'Pierce' => 'WWA',
907             'San Juan' => 'WWA',
908             'Skagit' => 'WWA',
909             'Skamania' => 'WWA',
910             'Snohomish' => 'WWA',
911             'Thurston' => 'WWA',
912             'Wahkiakum' => 'WWA',
913             'Whatcom' => 'WWA'
914             },
915             'WI' => 'WI',
916             'WV' => 'WV',
917             'WY' => 'WY',
918             'YT' => 'YT'
919             };
920             }
921              
922             1;
923             __END__