| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package WWW::PTV; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 1 |  |  | 1 |  | 14463 | use warnings; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 27 |  | 
| 4 | 1 |  |  | 1 |  | 4 | use strict; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 26 |  | 
| 5 |  |  |  |  |  |  |  | 
| 6 | 1 |  |  | 1 |  | 829 | use LWP; | 
|  | 1 |  |  |  |  | 62529 |  | 
|  | 1 |  |  |  |  | 44 |  | 
| 7 | 1 |  |  | 1 |  | 806 | use WWW::Mechanize; | 
|  | 1 |  |  |  |  | 112120 |  | 
|  | 1 |  |  |  |  | 33 |  | 
| 8 | 1 |  |  | 1 |  | 731 | use HTML::TreeBuilder; | 
|  | 1 |  |  |  |  | 16611 |  | 
|  | 1 |  |  |  |  | 9 |  | 
| 9 | 1 |  |  | 1 |  | 36 | use Carp qw(croak); | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 58 |  | 
| 10 | 1 |  |  | 1 |  | 467 | use WWW::PTV::Area; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 21 |  | 
| 11 | 1 |  |  | 1 |  | 318 | use WWW::PTV::Stop; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 24 |  | 
| 12 | 1 |  |  | 1 |  | 277 | use WWW::PTV::Route; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 1579 |  | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | our $VERSION = '0.06'; | 
| 15 |  |  |  |  |  |  | our $CACHE; | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | sub __request { | 
| 18 | 0 |  |  | 0 |  |  | my($self,$uri)	= @_; | 
| 19 | 0 | 0 |  |  |  |  | my $res = ( $uri !~ /^http:/ | 
| 20 |  |  |  |  |  |  | ? $self->{ua}->get( $self->{uri} . $uri ) | 
| 21 |  |  |  |  |  |  | : $self->{ua}->get( $uri ) ); | 
| 22 | 0 | 0 |  |  |  |  | $res->is_success and return $res->content; | 
| 23 | 0 |  |  |  |  |  | croak 'Unable to retrieve content: ' . $res->status_line | 
| 24 |  |  |  |  |  |  | } | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | sub __tl_request { | 
| 27 | 0 |  |  | 0 |  |  | my ($self, $tag_id)= @_; | 
| 28 | 0 |  | 0 |  |  |  | my $r = ( $self->{cache} and $CACHE->{timetables}->{master} | 
| 29 |  |  |  |  |  |  | ? $CACHE->{timetables}->{master} | 
| 30 |  |  |  |  |  |  | : $self->__request( 'http://ptv.vic.gov.au/timetables' ) ); | 
| 31 | 0 | 0 |  |  |  |  | $CACHE->{timetables}->{master} = $r if $self->{cache}; | 
| 32 | 0 |  |  |  |  |  | my $t 		= HTML::TreeBuilder->new_from_content( $r ); | 
| 33 | 0 |  |  |  |  |  | $t		= $t->look_down( _tag => 'select', id => $tag_id ); | 
| 34 | 0 |  |  |  |  |  | my @routes	= $t->look_down( _tag => 'option' ); | 
| 35 | 0 |  |  |  |  |  | return my %routes = map { $_->attr( 'value' ) => $_->as_text } grep { $_->attr( 'value' ) ne '' } @routes | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  | } | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  | sub new { | 
| 39 | 0 |  |  | 0 | 1 |  | my($class,%args)= @_; | 
| 40 | 0 |  |  |  |  |  | my $self 	= bless {}, $class; | 
| 41 | 0 | 0 |  |  |  |  | $self->{uri} 	= 'http://' . ( defined $args{uri} ? $args{uri} : 'ptv.vic.gov.au' ) . '/'; | 
| 42 | 0 |  |  |  |  |  | $self->{ua}	= LWP::UserAgent->new; | 
| 43 | 0 |  |  |  |  |  | $self->{tree}	= HTML::TreeBuilder->new; | 
| 44 | 0 | 0 |  |  |  |  | $self->{cache}++ if $args{cache}; | 
| 45 | 0 |  |  |  |  |  | return $self | 
| 46 |  |  |  |  |  |  | } | 
| 47 |  |  |  |  |  |  |  | 
| 48 | 0 |  |  | 0 | 1 |  | sub cache { $_[0]->{cache}++ } | 
| 49 |  |  |  |  |  |  |  | 
| 50 | 0 |  |  | 0 | 1 |  | sub nocache { $_[0]->{cache} = 0 } | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | sub get_metropolitan_bus_routes { | 
| 53 | 0 |  |  | 0 | 1 |  | return $_[0]->__tl_request( 'RouteForm1_RouteUrl' ); | 
| 54 |  |  |  |  |  |  | } | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  | sub get_metropolitan_train_routes { | 
| 57 | 0 |  |  | 0 | 1 |  | return $_[0]->__tl_request( 'RouteForm2_RouteUrl' ) | 
| 58 |  |  |  |  |  |  | } | 
| 59 |  |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  | sub get_metropolitan_tram_routes { | 
| 61 | 0 |  |  | 0 | 1 |  | return $_[0]->__tl_request( 'RouteForm3_RouteUrl' ); | 
| 62 |  |  |  |  |  |  | } | 
| 63 |  |  |  |  |  |  |  | 
| 64 |  |  |  |  |  |  | sub get_vline_bus_routes { | 
| 65 | 0 |  |  | 0 | 1 |  | return $_[0]->__tl_request( 'RouteForm4_RouteUrl' ) | 
| 66 |  |  |  |  |  |  | } | 
| 67 |  |  |  |  |  |  |  | 
| 68 |  |  |  |  |  |  | sub get_vline_train_routes { | 
| 69 | 0 |  |  | 0 | 1 |  | return $_[0]->__tl_request( 'RouteForm5_RouteUrl' ) | 
| 70 |  |  |  |  |  |  | } | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | sub get_regional_bus_routes { | 
| 73 | 0 |  |  | 0 | 1 |  | return $_[0]->__tl_request( 'RouteForm6_RouteUrl' ) | 
| 74 |  |  |  |  |  |  | } | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | sub get_route_by_id { | 
| 77 | 0 |  |  | 0 | 1 |  | my( $self, $id )= @_; | 
| 78 | 0 | 0 |  |  |  |  | $id or return "Mandatory parameter id not given"; | 
| 79 |  |  |  |  |  |  |  | 
| 80 | 0 | 0 | 0 |  |  |  | return $CACHE->{ROUTE}->{$id} if ( $self->{cache} and $CACHE->{ROUTE}->{$id} ); | 
| 81 |  |  |  |  |  |  |  | 
| 82 | 0 |  |  |  |  |  | my $r 		= $self->__request( "/route/view/$id" ); | 
| 83 | 0 |  |  |  |  |  | my $t		= HTML::TreeBuilder->new_from_content( $r ); | 
| 84 |  |  |  |  |  |  | #my $t		= HTML::TreeBuilder->new_from_file( './metro_train_route_1' ); | 
| 85 |  |  |  |  |  |  | #my $t		= HTML::TreeBuilder->new_from_file( './regional_bus_route_geelong_19' ); | 
| 86 | 0 |  |  |  |  |  | my %route	= (id => $id); | 
| 87 | 0 |  |  |  |  |  | my $r_link	= $t->look_down( _tag => 'div', id => 'content' ); | 
| 88 | 0 |  |  |  |  |  | $route{name}	= $t->look_down( _tag => 'h1' )->as_text; | 
| 89 | 0 |  |  |  |  |  | ( $route{direction_in}, $route{direction_out} ) | 
| 90 |  |  |  |  |  |  | = $r_link->look_down( _tag => 'a' ); | 
| 91 |  |  |  |  |  |  |  | 
| 92 | 0 |  |  |  |  |  | ( $route{direction_in_link}, $route{direction_out_link} ) | 
| 93 | 0 |  |  |  |  |  | = map { $_->attr( 'href' ) } $r_link->look_down( _tag => 'a' ); | 
| 94 |  |  |  |  |  |  |  | 
| 95 | 0 |  |  |  |  |  | ( $route{direction_in}, $route{direction_out} ) | 
| 96 | 0 |  |  |  |  |  | = map { $_->as_text } ( $route{direction_in}, $route{direction_out} ); | 
| 97 |  |  |  |  |  |  |  | 
| 98 | 0 |  |  |  |  |  | ( $route{description_in}, $route{description_out} ) | 
| 99 | 0 |  |  |  |  |  | = map { $_->as_text } $r_link->look_down( _tag => 'p' ); | 
| 100 | 0 |  |  |  |  |  | my $operator 	= $t->look_down( _tag => 'div', class => 'operator' )->as_text; | 
| 101 | 0 |  |  |  |  |  | $operator 	=~ s/(Contact|Website|:)/,/g; | 
| 102 | 0 |  |  |  |  |  | $operator 	=~ s/\s//g; | 
| 103 | 0 |  |  |  |  |  | ( $route{operator} ,$route{operator_ph} ) = ( split /,/, $operator )[0,2]; | 
| 104 | 0 |  |  |  |  |  | $route{ua}	= $self->{ua}; | 
| 105 | 0 |  |  |  |  |  | $route{uri}	= $self->{uri}; | 
| 106 | 0 |  |  |  |  |  | my $route 	= WWW::PTV::Route->new( %route ); | 
| 107 | 0 | 0 |  |  |  |  | $CACHE->{ROUTE}->{$id} = $route if ( $self->{cache} ); | 
| 108 | 0 |  |  |  |  |  | return $route | 
| 109 |  |  |  |  |  |  | } | 
| 110 |  |  |  |  |  |  |  | 
| 111 |  |  |  |  |  |  |  | 
| 112 |  |  |  |  |  |  |  | 
| 113 |  |  |  |  |  |  | sub get_stop_by_id { | 
| 114 | 0 |  |  | 0 | 1 |  | my( $self, $id )= @_; | 
| 115 | 0 | 0 |  |  |  |  | $id or return "Mandatory parameter id not given"; | 
| 116 | 0 | 0 | 0 |  |  |  | return $CACHE->{STOP}->{$id} if ( $self->{cache} and $CACHE->{STOP}->{$id} ); | 
| 117 | 0 |  |  |  |  |  | my $r				= $self->__request( "/stop/view/$id" ); | 
| 118 | 0 |  |  |  |  |  | my $t				= HTML::TreeBuilder->new_from_content( $r ); | 
| 119 |  |  |  |  |  |  | #my $t				= HTML::TreeBuilder->new_from_file( './45470' ); | 
| 120 | 0 |  |  |  |  |  | my %stop			= (id => $id ); | 
| 121 | 0 |  |  |  |  |  | my $s_type 			= $t->look_down( _tag => 'img', class => 'stopModeImage' ); | 
| 122 | 0 |  |  |  |  |  | $stop{address}			= $t->look_down( _tag => 'div', id => 'container' ) | 
| 123 |  |  |  |  |  |  | ->look_down( _tag => 'p' ) | 
| 124 |  |  |  |  |  |  | ->as_text; | 
| 125 |  |  |  |  |  |  |  | 
| 126 | 0 |  |  |  |  |  | $stop{transport_type}		= $s_type->attr('src'); | 
| 127 | 0 |  |  |  |  |  | $stop{transport_type}		=~ s|themes/transport-site/images/jp/icons/icon||; | 
| 128 | 0 |  |  |  |  |  | $stop{transport_type}		=~ s|\.png||; | 
| 129 | 0 |  |  |  |  |  | ( $stop{street}, $stop{locality} ) = ( split /,/, $stop{address} ); | 
| 130 | 0 |  |  |  |  |  | ( $stop{postcode} ) = $stop{locality} =~ /\b(\d{4})\b/; | 
| 131 | 0 |  |  |  |  |  | $stop{municipiality}		= $t->look_down( _tag	=> 'table', class => 'stationSummary' ) | 
| 132 |  |  |  |  |  |  | ->look_down( _tag => 'a' ) | 
| 133 |  |  |  |  |  |  | ->as_text; | 
| 134 |  |  |  |  |  |  |  | 
| 135 | 0 |  |  |  |  |  | ( $stop{municipiality_id} )	= $t->look_down( _tag	=> 'table', class => 'stationSummary' ) | 
| 136 |  |  |  |  |  |  | ->look_down( _tag => 'a' ) | 
| 137 |  |  |  |  |  |  | ->attr( 'href' ); | 
| 138 | 0 |  |  |  |  |  | ( $stop{municipiality_id} )	= $stop{municipiality_id} =~ /\/(\d.*)$/; | 
| 139 |  |  |  |  |  |  |  | 
| 140 | 0 |  |  |  |  |  | $stop{zone}			= ( $t->look_down( _tag => 'table', class => 'stationSummary' ) | 
| 141 |  |  |  |  |  |  | ->look_down( _tag => 'td' ) | 
| 142 |  |  |  |  |  |  | )[2]->as_text; | 
| 143 |  |  |  |  |  |  |  | 
| 144 | 0 |  |  |  |  |  | $stop{map_ref}			= $t->look_down( _tag => 'div', class => 'aside' ) | 
| 145 |  |  |  |  |  |  | ->look_down( _tag => 'a' ) | 
| 146 |  |  |  |  |  |  | ->attr( 'href' ); | 
| 147 |  |  |  |  |  |  |  | 
| 148 | 0 |  |  |  |  |  | ( $stop{latitude} )		= $stop{map_ref} =~ /=(-?\d.*),/; | 
| 149 |  |  |  |  |  |  |  | 
| 150 | 0 |  |  |  |  |  | ( $stop{longitude} )		= $stop{map_ref} =~ /,(-?\d.*)$/; | 
| 151 |  |  |  |  |  |  |  | 
| 152 | 0 |  |  |  |  |  | ( $stop{phone_feedback}, $stop{phone_station} ) | 
| 153 | 0 |  |  |  |  |  | = map {	$_->as_text } $t->look_down( _tag => 'div', class => 'expander phone-numbers' ) | 
| 154 |  |  |  |  |  |  | ->look_down( _tag => 'dd' ); | 
| 155 |  |  |  |  |  |  |  | 
| 156 | 0 |  |  |  |  |  | $stop{staff_hours}		= $t->look_down( _tag => 'div', 'data-cookie' => 'stop-staff' ) | 
| 157 |  |  |  |  |  |  | ->look_down( _tag => 'dd' )->as_text; | 
| 158 |  |  |  |  |  |  |  | 
| 159 | 0 |  |  |  |  |  | ( $stop{myki_machines}, $stop{myki_checks}, $stop{vline_bookings} ) | 
| 160 | 0 |  |  |  |  |  | = map { $_->as_text } $t->look_down( _tag => 'div', 'data-cookie' => 'stop-ticketing' ) | 
| 161 |  |  |  |  |  |  | ->look_down( _tag => 'dd' ); | 
| 162 |  |  |  |  |  |  |  | 
| 163 | 0 |  |  |  |  |  | ( $stop{car_parking}, $stop{_bicycles}, $stop{taxi_rank} ) | 
| 164 | 0 |  |  |  |  |  | = map { $_->as_text } $t->look_down( _tag => 'div', 'data-cookie' => 'stop-other-transport-links' ) | 
| 165 |  |  |  |  |  |  | ->look_down( _tag => 'dd' ); | 
| 166 |  |  |  |  |  |  |  | 
| 167 | 0 |  |  |  |  |  | ( $stop{bicycle_racks}, $stop{bicycle_lockers}, $stop{bicycle_cage} ) | 
| 168 | 0 |  |  |  |  |  | = map { s/.*://; $_ } split /,/, $stop{_bicycles}; | 
|  | 0 |  |  |  |  |  |  | 
| 169 |  |  |  |  |  |  |  | 
| 170 | 0 |  |  |  |  |  | ( $stop{wheelchair_accessible}, $stop{stairs}, $stop{escalator}, $stop{lift}, $stop{tactile_paths}, $stop{hearing_loop} ) | 
| 171 | 0 |  |  |  |  |  | = map { $_->as_text } $t->look_down( _tag => 'div', 'data-cookie' => 'stop-accessibility' ) | 
| 172 |  |  |  |  |  |  | ->look_down( _tag => 'dd' ); | 
| 173 |  |  |  |  |  |  |  | 
| 174 | 0 |  |  |  |  |  | ( $stop{seating}, $stop{lighting}, $stop{lockers}, $stop{public_phone}, $stop{public_toilet}, $stop{_waiting_area} ) | 
| 175 | 0 |  |  |  |  |  | = map { $_->as_text } $t->look_down( _tag => 'div', 'data-cookie' => 'stop-general-facilities' ) | 
| 176 |  |  |  |  |  |  | ->look_down( _tag => 'dd' ); | 
| 177 |  |  |  |  |  |  |  | 
| 178 | 0 |  |  |  |  |  | ( $stop{waiting_area_indoor}, $stop{waiting_area_sheltered} ) | 
| 179 | 0 |  |  |  |  |  | = map { s/.*://; $_ } split /,/, $stop{_waiting_area}; | 
|  | 0 |  |  |  |  |  |  | 
| 180 |  |  |  |  |  |  |  | 
| 181 | 0 |  |  |  |  |  | foreach my $line ( $t->look_down( _tag => 'div', 'data-cookie' => 'stop-line-timetables' ) | 
| 182 |  |  |  |  |  |  | ->look_down( _tag => 'div', class => 'timetable-row' ) ) { | 
| 183 | 0 |  |  |  |  |  | my $ref = { id => $line->look_down( _tag => 'a' )->attr( 'href' ) =~ /^.*\/(.*)/ }; | 
| 184 | 0 |  |  |  |  |  | $ref->{ name } = $line->look_down( _tag => 'a' )->as_text; | 
| 185 | 0 |  |  |  |  |  | $ref->{ type } = _get_line_type( $line->look_down( _tag => 'img' )->attr( 'src' ) ); | 
| 186 | 0 |  |  |  |  |  | push @{ $stop{routes} }, $ref | 
|  | 0 |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | } | 
| 188 |  |  |  |  |  |  |  | 
| 189 | 0 |  |  |  |  |  | $stop{ua} = $self->{ua}; | 
| 190 |  |  |  |  |  |  |  | 
| 191 | 0 |  |  |  |  |  | my $stop = WWW::PTV::Stop->new( %stop ); | 
| 192 | 0 | 0 |  |  |  |  | $CACHE->{STOP}->{$id} = $stop if ( $self->{cache} ); | 
| 193 |  |  |  |  |  |  |  | 
| 194 | 0 |  |  |  |  |  | return $stop | 
| 195 |  |  |  |  |  |  | } | 
| 196 |  |  |  |  |  |  |  | 
| 197 |  |  |  |  |  |  | sub get_area_by_id { | 
| 198 | 0 |  |  | 0 | 1 |  | my( $self, $id )= @_; | 
| 199 | 0 | 0 |  |  |  |  | $id or return "Mandatory parameter id not given"; | 
| 200 | 0 | 0 | 0 |  |  |  | return $CACHE->{AREA}->{$id} if ( $self->{cache} and $CACHE->{AREA}->{$id} ); | 
| 201 | 0 |  |  |  |  |  | my $r				= $self->__request( "/location/view/$id" ); | 
| 202 | 0 |  |  |  |  |  | my $t				= HTML::TreeBuilder->new_from_content( $r ); | 
| 203 |  |  |  |  |  |  | #my $t				= HTML::TreeBuilder->new_from_file( './local_area_19' ); | 
| 204 |  |  |  |  |  |  | #my $t				= HTML::TreeBuilder->new_from_file( './area_30' ); | 
| 205 | 0 |  |  |  |  |  | my %area 			= ( id => $id ); | 
| 206 | 0 |  |  |  |  |  | $area{name}			= $t->look_down( _tag => 'h1' )->as_text; | 
| 207 | 0 |  |  |  |  |  | @{ $area{suburbs}}		= split /, /, $t->look_down( _tag => 'p' )->as_text; | 
|  | 0 |  |  |  |  |  |  | 
| 208 | 0 |  |  |  |  |  | my $t_type; | 
| 209 |  |  |  |  |  |  |  | 
| 210 | 0 |  |  |  |  |  | foreach my $service ( $t->look_down( _tag => 'div', id => 'content' )->look_down( _tag => 'div' ) ) { | 
| 211 | 0 |  |  |  |  |  | my $type = $service->look_down( _tag => 'h3' ); | 
| 212 |  |  |  |  |  |  |  | 
| 213 | 0 | 0 |  |  |  |  | if ( $type->as_text ne '' ) { $t_type = $type->as_text } | 
|  | 0 |  |  |  |  |  |  | 
| 214 |  |  |  |  |  |  |  | 
| 215 | 0 |  |  |  |  |  | @{ $area{service}{names}{$t_type} } | 
|  | 0 |  |  |  |  |  |  | 
| 216 | 0 |  |  |  |  |  | = map { $_->as_text } $service->look_down( _tag => 'li' ); | 
| 217 |  |  |  |  |  |  |  | 
| 218 | 0 |  |  |  |  |  | @{ $area{service}{links}{$t_type} } | 
|  | 0 |  |  |  |  |  |  | 
| 219 | 0 |  |  |  |  |  | = map { $_->attr( 'href' ) } $service->look_down( _tag => 'a' ); | 
| 220 |  |  |  |  |  |  | } | 
| 221 |  |  |  |  |  |  |  | 
| 222 | 0 |  |  |  |  |  | my $area =  WWW::PTV::Area->new( %area ); | 
| 223 | 0 | 0 |  |  |  |  | $CACHE->{AREA}->{$id} = $area if ( $self->{cache} ); | 
| 224 |  |  |  |  |  |  |  | 
| 225 | 0 |  |  |  |  |  | return $area | 
| 226 |  |  |  |  |  |  | } | 
| 227 |  |  |  |  |  |  |  | 
| 228 |  |  |  |  |  |  | sub get_local_areas { | 
| 229 | 0 |  |  | 0 | 1 |  | my $self = shift; | 
| 230 | 0 |  |  |  |  |  | my $r = $self->__request( '/getting-around/local-areas/' ); | 
| 231 | 0 |  |  |  |  |  | my $t = HTML::TreeBuilder->new_from_content( $r ); | 
| 232 |  |  |  |  |  |  | #my $t = HTML::TreeBuilder->new_from_file( './local_areas_list' ); | 
| 233 | 0 |  |  |  |  |  | $t = $t->look_down( _tag => 'div', id => 'content' ); | 
| 234 |  |  |  |  |  |  |  | 
| 235 | 0 |  |  |  |  |  | @{ $self->{local_areas}{names} } | 
|  | 0 |  |  |  |  |  |  | 
| 236 | 0 |  |  |  |  |  | = map { $_->as_text } $t->look_down( _tag => 'li' ); | 
| 237 |  |  |  |  |  |  |  | 
| 238 | 0 |  |  |  |  |  | @{ $self->{local_areas}{links} } | 
|  | 0 |  |  |  |  |  |  | 
| 239 | 0 |  |  |  |  |  | = map { $_->attr( 'href' ) } $t->look_down( _tag => 'a' ); | 
| 240 |  |  |  |  |  |  |  | 
| 241 | 0 |  |  |  |  |  | my %res; | 
| 242 | 0 |  |  |  |  |  | @res{ @{ $self->{local_areas}{names} } } = @{ $self->{local_areas}{links} }; | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 243 | 0 |  |  |  |  |  | return %res | 
| 244 |  |  |  |  |  |  | } | 
| 245 |  |  |  |  |  |  |  | 
| 246 |  |  |  |  |  |  | sub _get_line_type { | 
| 247 | 0 |  |  | 0 |  |  | my $obj = shift; | 
| 248 | 0 |  |  |  |  |  | $obj =~ s/^.*\/icon//; | 
| 249 | 0 |  |  |  |  |  | $obj =~ s/\..*$//; | 
| 250 | 0 |  |  |  |  |  | return lc $obj | 
| 251 |  |  |  |  |  |  | } | 
| 252 |  |  |  |  |  |  |  | 
| 253 |  |  |  |  |  |  | 1; | 
| 254 |  |  |  |  |  |  |  | 
| 255 |  |  |  |  |  |  | __END__ |