This is the historical archive of the now-inactive 'grubstreet' list.
Discussion on OpenGuides development has now moved to OpenGuides-Dev. Discussion on The Open Guide to London now takes place on OpenGuides-London.

[grubstreet] Search version 1.01

[prev] [thread] [next] [lurker] [Date index for 2003/1/30]

From: Ivor Williams
Subject: [grubstreet] Search version 1.01
Date: 15:51 on 30 Jan 2003
------ =_NextPart_000_01C2C877.80F5EFE0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit

Details are in the Grubstreet wiki on 
http://grault.net/cgi-bin/grubstreet.pl?Search_Script/Dev
 
Attached is the file, diff listing follows:

14a15,16
> our $VERSION = '1.01';
>
122c124,125
< # Output HTML search form with appropriate headers.
---
> # Build HTML search form with appropriate headers.
> # Don't output it just yet
124,126c127,131
< print header,start_html("Usemod Search"),
< 					h1("Usemod Search"),"\n";
< print start_form, textfield(
---
> my $outstr = header . start_html("Usemod Search") .
> 		h1("Usemod Search") .
> 		p(small("Search version $VERSION")). "\n".
> 		start_form .
> 		textfield(
129c134,135
< 					-maxlength=>80),end_form,"\n";
---
> 			-maxlength=>80) .
> 		end_form . "\n";
143,144c149,150
< 		if ($srh !~ /^("[^"]*"|[a-z _\-'&|()!*%])+$/i) { #"
< 			print h1("Search expression contains invalid character");
---
> 		if ($srh !~ /^("[^"]*"|[\w \-'&|()!*%\[\]])+$/i) { #"
> 			print $outstr,h1("Search expression contains invalid character");
169a176
> 			|		'[' word(s) ']' {$return = ['title', @{$item[2]}]}
179,180c186,187
< 		my $tree = $parse->search($srh) or (print h1("Search syntax error")),last 
RESULTS;
< #		print pre(Dumper($tree));
---
> 		my $tree = $parse->search($srh) or (print $outstr,h1("Search syntax 
error")),last RESULTS;
> #		print $outstr,pre(Dumper($tree));
183d189
< 		print hr,h2('Search Results'),start_ol({start=>$startpos+1}),"\n";
185c191,192
< # Apply search and display results
---
> # Apply search
> # Do different things depending on how many results:
188c195,215
< 		my @res_selected = sort {@{$results{$b}} <=> @{$results{$a}}} keys 
%results;
---
> 		my $numres = scalar(keys %results);
>
> # 0 results - 'No items matched'
>
> 		(print $outstr,hr,h2('No items matched')),last RESULTS if !$numres;
>
> # 1 result - redirect to the page
>
> 		if ($numres == 1) {
> 			my ($pag) = each %results;
> 			print redirect($wikimain.'?'.$pag);
> 			exit;
> 		}
>
> # Otherwise browse selection of results, 20 at a time
>
> 		print $outstr,hr,h2('Search Results'),start_ol({start=>$startpos+1}),"\n";
>
> # Sort the results - first index of array in HoA is the score.
>
> 		my @res_selected = sort {$results{$b}[0] <=> $results{$a}[0]} keys 
%results;
189a217,219
>
> # Skip those before $startpos
>
190a221,223
>
> # Display 20
>
194c227
< 			print p(li(a({href=>$wikimain."?$_"},b($_)),br,@{$results{$_}}[0..5]));
---
> 			print p(li(a({href=>$wikimain."?$_"},b($_)),br,@{$results{$_}}[1..6]));
195a229,231
>
> # More to do: display 'out of' how many, and 'more' button
>
207a244,245
> 	} else {
> 		print $outstr;
222c260
< 	my $wexp = qr/(?:\W|^).{0,60}\W$wmatch\W.{0,60}/is;
---
> 	my $wexp = qr/\b.{0,60}\b$wmatch\b.{0,60}\b/is;
224a263,265
>
> # Search every wiki page for matches
> 	
230c271
< 			$match =~ s!(\W)($wmatch)(?=\W)!$1<b>$2</b>!i;
---
> 			$match =~ s!\b($wmatch)\b!<b>$&</b>!i;
232a274,277
> 		my $temp = $k;
> 		$temp =~ s/_/ /g;
>
> # Compute score and prepend to array of matches
234c279,281
< 		$res{$k} = \@out if @out;
---
> 		my $score = @out;
> 		$score +=10 if $temp =~ /$wexp/;
> 		$res{$k} = unshift(@out,$score) && \@out if @out;
243a291
> 	my $score = 0;
247c295,296
< 			push @mixed,[$_,$j->{$pagnam}[$_]] for 0..$#{$j->{$pagnam}};
---
> 			$score += $j->{$pagnam}[0];
> 			push @mixed,[$_,$j->{$pagnam}[$_]] for 1..$#{$j->{$pagnam}};
252a302,303
> 	unshift @interspersed,$score;
> 	
275a327,344
> # matched_title - title only search, we have a list of words
>
> sub matched_title {
> 	my $wmatch = join '\W+',@_;
> 	$wmatch =~ s/%/\\w/g;
> 	$wmatch =~ s/\*/\\w*/g;
>
> 	my $wexp = qr/\b$wmatch\b/is;
> 	my %res;
> 	
> 	for (keys %wikitext) {
> 		$res{$_} = [10] if /$wexp/g;
> 	}
> 	
> 	%res;
> }
>
>
333c402
< 	my %out = map {$_=>[]} keys %wikitext;
---
> 	my %out = map {$_=>[0]} keys %wikitext;


------ =_NextPart_000_01C2C877.80F5EFE0
Content-Type: application/x-perl; name="search-1.01.pl"
Content-Transfer-Encoding: base64

IyFwZXJsIC1UCiMKIyBVc2Vtb2QgV2lraSBzZWFyY2ggZmFjaWxpdHkKIwojIEl2b3IgV2lsbGlh
bXM6IE9jdG9iZXIgMjAwMgojCiMgQ2hhbmdlIHRoZSB2YXJpYWJsZSAkd2lraXJvb3QgYW5kICR3
aWtpbWFpbiBiZWxvdyBmb3IgeW91ciBzaXRlIHNwZWNpZmljCiMgZGF0YWRpciBwYXRoIGFuZCB3
aWtpIHVybC4KIwojIFRoZSBwcm9nIHVzZXMgYm9nLXN0YW5kYXJkIENHSS5wbSBzdHVmZi4gVGhl
IG1haW4gcHJvZ3JhbSBjYW4gYmUgdGFpbG9yZWQgZm9yIGxvb2sgYW5kIGZlZWwuCgp1c2Ugc3Ry
aWN0Owp1c2Ugd2FybmluZ3M7CgpvdXIgJFZFUlNJT04gPSAnMS4wMSc7Cgp1c2UgQ0dJIHF3KDpz
dGFuZGFyZCAqb2wpOwp1c2UgQ0dJOjpDYXJwIHF3KGZhdGFsc1RvQnJvd3Nlcik7CSNSZW1vdmUg
ZmF0YWxzVG9Ccm93c2VyIGlmIHBhcmFub2lkCgp1c2UgUGFyc2U6OlJlY0Rlc2NlbnQ7CnVzZSBE
YXRhOjpEdW1wZXI7CnVzZSBGaWxlOjpTcGVjOjpGdW5jdGlvbnMgcXcoOkFMTCk7Cgp1c2UgdmFy
cyBxdygkd2lraXJvb3QgJHdpa2ltYWluICV3aWtpdGV4dCk7Cgokd2lraXJvb3QgPSAiYzpcXHBy
b2dyYW1zd2lraWRiIjsKJHdpa2ltYWluID0gIndpa2kucGwiOwoKIyBzdWIgbWF0Y2hlZF9pdGVt
cyBpcyBjYWxsZWQgd2l0aCBwYXJzZSB0cmVlLiBVc2VzIGhvcnJpYmxlIHN1Ym5hbWUgY29uY2F0
ZW5hdGlvbiAtIHRoaXMKIyBjb3VsZCBiZSByZXdyaXR0ZW4gdG8gdXMgT08gaW5zdGVhZCBhbmQg
YmUgbXVjaCBuZWF0ZXIuIFRoaXMgd291bGQgYmUgYSBtYWpvciByZWZhY3RvcjoKIyBuZWVkIHRv
IGFkZHJlc3MgZGVzaWduIGlzc3VlcyAtIHBldHRlcm5zPwoKc3ViIG1hdGNoZWRfaXRlbXMgewoJ
bXkgJG9wID0gc2hpZnQ7CgkKCW5vIHN0cmljdCAnc3Vicyc7Cglnb3RvICZ7bWF0Y2hlZF8uJG9w
fTsKfQoKbXkgJGZzID0gJ1x4YjMnOwoKIyBzdWIgcmVhZHBhZ2UgaXMgdXNlZCB0byByZWFkIGlu
IGEgVXNlbW9kIFdpa2kgcGFnZSwgYW5kIGludGVycHJldCB0aGUgZGVsaW1pdGVycy4gVGhpcyBm
b3JtcwojIGEgaGFzaC4gVGhlIG91dHB1dCBnb2VzIGludG8gdGhlIGdsb2JhbCBoYXNoICV3aWtp
dGV4dCwgYXMgdGhpcyBpcyB3aGF0IGlzIHVzZWQgZm9yIHNlYXJjaGluZyAKIyBvbi4gVGhlIHBh
Z2UgdGl0bGUgaXMgcHJlcGVuZGVkLCBlbmFibGluZyB0aGUgdGl0bGUgdG8gYmUgaW5jbHVkZWQg
aW4gbWF0Y2hlcy4KCnN1YiByZWFkcGFnZSB7CglteSAoJHRlcm0sJGZpbGUpID0gQF87CglteSAk
dGV4dCA9IGRvIHsgbG9jYWwgKEBBUkdWLCAkLykgPSAkZmlsZTsgPD4gfTsgIyBzbHVycCBlbnRp
cmUgZmlsZQoKIyBFc2NhcGUgb3V0IGFueSBzaW5nbGUgcXVvdGVzCgoJJHRleHQgPX4gcy8nL1xc
Jy9nOwoKIyBBZGQgc2luZ2xlIHF1b3RlcyBhcm91bmQgdGV4dCBzdHJpbmdzCgoJJHRleHQgPX4g
cy8oJGZzXGR8XikoW14kZnNdKj9bXiRmc1xkXS4qPykoPz0oJGZzXGR8JCkpLyQxJyQyJy9nczsK
CSR0ZXh0ID1+IC8kZnNcZC8gb3IgcmV0dXJuOwoKIyBSZXBsYWNlIHNlcGFyYXRvcnMgd2l0aCAn
LCcgYW5kIGFkZCBicmFjZXMgdG8gc3Vycm91bmQgc3RyaW5nLiBUaGlzIGlzIHRvIHByZXBhcmUK
IyB0aGUgc3RyaW5nIGZvciBhbiBldmFsIGFzIGFuIGFub255bW91cyBoYXNoCgoJbXkgJHN0cnVu
ZyA9ICZyZXBsYWNlX3NlcGFyYXRvcnMoJHRleHQsJCYsJ3snLCd9Jyk7CgoJbXkgJG91dCA9IGV2
YWwoJHN0cnVuZyk7CSMgY29uc3RydWN0cyBuZXN0ZWQgaGFzaCBvZiBkaWZmZXJlbnQgZGF0YSBp
dGVtcy4KCW15ICR0aXRsZSA9ICR0ZXJtOwoJJHRpdGxlID1+IHMvXy8gL2c7Cgkkd2lraXRleHR7
JHRlcm19ID0gJyAnIC4gJHRpdGxlIC4gJzogJyAuICRvdXQtPnt0ZXh0X2RlZmF1bHR9e2RhdGF9
e3RleHR9IAoJCQlpZiAhJEA7Cn0KCiMgc3ViIHJlcGxhY2Vfc2VwYXJhdG9ycyAtIHJlY3Vyc2l2
ZSBwcm9jIHRvIG11bmdlIHNlcGFyYXRvcnMgaW50byBjb21tYXMsIGFuZCByZXNvbHZlCiMgbmVz
dGluZy4KCnN1YiByZXBsYWNlX3NlcGFyYXRvcnMgewoJbXkgKCR0ZXh0LCRkZWxpbSwkb3Blbmlu
ZywkY2xvc2luZykgPSBAXzsKCQoJbXkgQGNodW54ID0gc3BsaXQgLyRkZWxpbS8sJHRleHQ7CgkK
CWZvciAoQGNodW54KSB7CgkJJF8gPSAndW5kZWYnIGlmICRfIGVxICcnOwoJCSRfID0gcmVwbGFj
ZV9zZXBhcmF0b3JzKCRfLCQmLCd7JywnfScpIGlmIC8kZnNcZC87CgkJJF8gPSAvXihcJyhbXidd
fFxcJykqW15cXF1cJ3xbXFtcXVx7XH0sXGRdfHVuZGVmKSskLyA/ICQmIDogJyc7Cgl9CgkKCSRv
cGVuaW5nIC4gKGpvaW4gJywnLEBjaHVueCkgLiAkY2xvc2luZzsKfQoKCiMgc3ViIGxvYWRfd2lr
aV90ZXh0IGlzIHVzZWQgdG8gbG9hZCB0aGUgZW50aXJlIHdpa2kgaW50byBnbG9iYWwgaGFzaCAl
d2lraXRleHQuIFRoaXMgaXMgYSAKIyBwZXJmb3JtYW5jZSBoaXQgZXZlcnl0aW1lIHRoZSBzZWFy
Y2ggaXMgdXNlZC4gTG9va3MgT0sgZm9yIHNtYWxsIHdpa2lzLiBDb3VsZCByZXBsYWNlIAojIHRo
aXMgc3ViIHdpdGggc29tZXRoaW5nIHRoYXQgbWFrZXMgJXdpa2l0ZXh0IHBlcnNpc3RlbnQsIHVz
aW5nIGEgdGllZCBoYXNoIC0gaXNzdWUgb2Ygd2hlbgojIHRvIHJlbG9hZCBjb21lcyB1cC4KIwoj
IE5vdGU6IHVzZXMgRmlsZTo6U3BlYyByb3V0aW5lcyBzbyBhcyB0byBiZSBmdWxseSBwb3J0YWJs
ZS4gV29ya3Mgb24gV2luZG96ZSwgc2hvdWxkIHdvcmsgb24KIyBVbml4IGp1c3QgYXMgd2VsbC4g
VXNlcyB0aGUgcGF0ZW50IFBlcmxtb25rcyBzdXBlcnNsdXJwZXIgdHJpY2suCgpzdWIgbG9hZF93
aWtpX3RleHQgewoKIyBnbG9iIGZvciB0b3BpY3MKCglteSAkd2lraWdsb2IgPSBjYXRkaXIoJHdp
a2lyb290LCdwYWdlJywnKicsJyouZGInKTsKCQoJZm9yIChnbG9iICR3aWtpZ2xvYikgewoJCW15
ICgkZGV2LCRkaXIsJHRlcm0pID0gc3BsaXRwYXRoKCRfKTsKCQkKCQkkdGVybSA9fiBzL1wuZGIv
LzsKCQlyZWFkcGFnZSgkdGVybSwkXyk7Cgl9CgojIGdsb2IgZm9yIHN1YnRvcGljcwoKCSR3aWtp
Z2xvYiA9IGNhdGRpcigkd2lraXJvb3QsJ3BhZ2UnLCcqJywnKicsJyouZGInKTsKCQkKCWZvciAo
Z2xvYiAkd2lraWdsb2IpIHsKCQlteSAoJGRldiwkZGlyLCR0ZXJtKSA9IHNwbGl0cGF0aCgkXyk7
CgkJbXkgQHNkID0gc3BsaXRkaXIoJGRpcik7CgoJCSR0ZXJtID1+IHMvXC5kYi8vOwoJCSR0ZXJt
ID0gJHNkWy0yXS4nLycuJHRlcm07CgkJcmVhZHBhZ2UoJHRlcm0sJF8pOwoJfQp9CgojIEJ1aWxk
IEhUTUwgc2VhcmNoIGZvcm0gd2l0aCBhcHByb3ByaWF0ZSBoZWFkZXJzLgojIERvbid0IG91dHB1
dCBpdCBqdXN0IHlldAoKbXkgJG91dHN0ciA9IGhlYWRlciAuIHN0YXJ0X2h0bWwoIlVzZW1vZCBT
ZWFyY2giKSAuCgkJaDEoIlVzZW1vZCBTZWFyY2giKSAuIAoJCXAoc21hbGwoIlNlYXJjaCB2ZXJz
aW9uICRWRVJTSU9OIikpLiAiXG4iLgoJCXN0YXJ0X2Zvcm0gLiAKCQl0ZXh0ZmllbGQoCgkJCS1u
YW1lPT4nc2VhcmNoJywKCQkJLXNpemU9PjUwLAoJCQktbWF4bGVuZ3RoPT44MCkgLgoJCWVuZF9m
b3JtIC4gIlxuIjsKCiMgRG8gd2UgaGF2ZSBhbiBleGlzdGluZyBzZWFyY2g/IGlmIHNvLCBkbyBp
dC4KCm15ICRxID0gQ0dJLT5uZXc7Cm15ICRzcmggPSAkcS0+cGFyYW0oJ3NlYXJjaCcpOwoKUkVT
VUxUUzoKewoJaWYgKCRzcmgpIHsKCQkKIyBDaGVjayBmb3Igb25seSB2YWxpZCBjaGFyYWN0ZXJz
IGluIHRhaW50ZWQgc2VhcmNoIHBhcmFtCiMgKHF1b3RlZCBsaXRlcmFscyBhcmUgT0ssIGFzIHRo
ZXkgYXJlIGVzY2FwZWQpCgoJCWlmICgkc3JoICF+IC9eKCJbXiJdKiJ8W1x3IFwtJyZ8KCkhKiVc
W1xdXSkrJC9pKSB7ICMiCgkJCXByaW50ICRvdXRzdHIsaDEoIlNlYXJjaCBleHByZXNzaW9uIGNv
bnRhaW5zIGludmFsaWQgY2hhcmFjdGVyIik7CgkJCWxhc3QgUkVTVUxUUzsKCQl9CgoJCWxvYWRf
d2lraV90ZXh0KCk7CgojIEJ1aWxkIFJlY0Rlc2NlbnQgZ3JhbW1hciBmb3Igc2VhcmNoIHN5bnRh
eC4KIyBOb3RlOiAnJicgYW5kICd8JyBjYW4gYmUgcmVwbGFjZWQgd2l0aCBvdGhlciBub24tYWxw
aGEuIFRoaXMgbWF5IGJlIG5lZWRlZCBpZgojIHlvdSBuZWVkIHRvIGNhbGwgdGhlIHNjcmlwdCBm
cm9tIE1FVEhPRD1HRVQgKGFzICYgaXMgYSBzZXBhcmF0b3IpCiMgQWxzbywgd29yZDogcGF0dGVy
biBjb3VsZCBiZSBjaGFuZ2VkIHRvIGluY2x1ZGUgbnVtYmVycyBhbmQgaGFuZGxlIGxvY2FsZXMg
cHJvcGVybHkuCiMgSG93ZXZlciwgcXVvdGVkIGxpdGVyYWxzIGFyZSB1c3VhbGx5IGdvb2QgZW5v
dWdoIGZvciBtb3N0IG9kZCBjaGFyYWN0ZXJzLgoJCgkJbXkgJHBhcnNlID0gUGFyc2U6OlJlY0Rl
c2NlbnQtPm5ldyhxewoKCQkJc2VhcmNoOiBsaXN0IGVvc3RyaW5nIHskcmV0dXJuID0gJGl0ZW1b
MV19CgoJCQlsaXN0OiA8bGVmdG9wOiBjb21ieSAnfCcgY29tYnk+IAoJCQkJeyRyZXR1cm4gPSAo
QHskaXRlbVsxXX0+MSkgPyBbJ09SJywgQHskaXRlbVsxXX1dIDogJGl0ZW1bMV1bMF19CgoJCQlj
b21ieTogPGxlZnRvcDogdGVybSAnJicgdGVybT4gCgkJCQl7JHJldHVybiA9IChAeyRpdGVtWzFd
fT4xKSA/IFsnQU5EJywgQHskaXRlbVsxXX1dIDogJGl0ZW1bMV1bMF19CgoJCQl0ZXJtOiAnKCcg
bGlzdCAnKScgeyRyZXR1cm4gPSAkaXRlbVsyXX0KCQkJfAkJJyEnIHRlcm0geyRyZXR1cm4gPSBb
J05PVCcsIEB7JGl0ZW1bMl19XX0KCQkJfAkJJyInIC9bXiJdKi8gJyInIHskcmV0dXJuID0gWyds
aXRlcmFsJywgJGl0ZW1bMl1dfQoJCQl8CQl3b3JkKHMpIHskcmV0dXJuID0gWyd3b3JkJywgQHsk
aXRlbVsxXX1dfQoJCQl8CQknWycgd29yZChzKSAnXScgeyRyZXR1cm4gPSBbJ3RpdGxlJywgQHsk
aXRlbVsyXX1dfQoKCQkJd29yZDogL1tcdycqJV0rLyB7JHJldHVybiA9ICRpdGVtWzFdfQoJCQkK
CQkJZW9zdHJpbmc6IC9eXFovCgoJCX0pIG9yIGRpZSAkQDsgIAoKIyBUdXJuIHNlYXJjaCBzdHJp
bmcgaW50byBwYXJzZSB0cmVlCgkKCQlteSAkdHJlZSA9ICRwYXJzZS0+c2VhcmNoKCRzcmgpIG9y
IChwcmludCAkb3V0c3RyLGgxKCJTZWFyY2ggc3ludGF4IGVycm9yIikpLGxhc3QgUkVTVUxUUzsK
IwkJcHJpbnQgJG91dHN0cixwcmUoRHVtcGVyKCR0cmVlKSk7CgoJCW15ICRzdGFydHBvcyA9ICRx
LT5wYXJhbSgnbmV4dCcpIHx8IDA7CgojIEFwcGx5IHNlYXJjaAojIERvIGRpZmZlcmVudCB0aGlu
Z3MgZGVwZW5kaW5nIG9uIGhvdyBtYW55IHJlc3VsdHM6CgoJCW15ICVyZXN1bHRzID0gbWF0Y2hl
ZF9pdGVtcyhAJHRyZWUpOwoJCW15ICRudW1yZXMgPSBzY2FsYXIoa2V5cyAlcmVzdWx0cyk7Cgoj
IDAgcmVzdWx0cyAtICdObyBpdGVtcyBtYXRjaGVkJwoKCQkocHJpbnQgJG91dHN0cixocixoMign
Tm8gaXRlbXMgbWF0Y2hlZCcpKSxsYXN0IFJFU1VMVFMgaWYgISRudW1yZXM7CgojIDEgcmVzdWx0
IC0gcmVkaXJlY3QgdG8gdGhlIHBhZ2UKCgkJaWYgKCRudW1yZXMgPT0gMSkgewoJCQlteSAoJHBh
ZykgPSBlYWNoICVyZXN1bHRzOwoJCQlwcmludCByZWRpcmVjdCgkd2lraW1haW4uJz8nLiRwYWcp
OwoJCQlleGl0OwoJCX0KCiMgT3RoZXJ3aXNlIGJyb3dzZSBzZWxlY3Rpb24gb2YgcmVzdWx0cywg
MjAgYXQgYSB0aW1lCgoJCXByaW50ICRvdXRzdHIsaHIsaDIoJ1NlYXJjaCBSZXN1bHRzJyksc3Rh
cnRfb2woe3N0YXJ0PT4kc3RhcnRwb3MrMX0pLCJcbiI7CgojIFNvcnQgdGhlIHJlc3VsdHMgLSBm
aXJzdCBpbmRleCBvZiBhcnJheSBpbiBIb0EgaXMgdGhlIHNjb3JlLgoKCQlteSBAcmVzX3NlbGVj
dGVkID0gc29ydCB7JHJlc3VsdHN7JGJ9WzBdIDw9PiAkcmVzdWx0c3skYX1bMF19IGtleXMgJXJl
c3VsdHM7CgkJbXkgJHRvdF9yZXN1bHRzID0gQHJlc19zZWxlY3RlZDsKCiMgU2tpcCB0aG9zZSBi
ZWZvcmUgJHN0YXJ0cG9zCgoJCXNwbGljZSBAcmVzX3NlbGVjdGVkLDAsJHN0YXJ0cG9zOwoKIyBE
aXNwbGF5IDIwCgoJCWZvciAoQHJlc19zZWxlY3RlZFswLi4xOV0pIHsKCQkJKHByaW50IGVuZF9v
bCwiXG4iKSxsYXN0IFJFU1VMVFMgaWYgISRfOwoJCQkKCQkJcHJpbnQgcChsaShhKHtocmVmPT4k
d2lraW1haW4uIj8kXyJ9LGIoJF8pKSxicixAeyRyZXN1bHRzeyRffX1bMS4uNl0pKTsKCQl9Cgoj
IE1vcmUgdG8gZG86IGRpc3BsYXkgJ291dCBvZicgaG93IG1hbnksIGFuZCAnbW9yZScgYnV0dG9u
CgoJCXByaW50IGVuZF9vbCxwKCRzdGFydHBvcysyMCwnLycsJHRvdF9yZXN1bHRzLCJtYXRjaGVz
IiksIlxuIjsKCgkJaWYgKCR0b3RfcmVzdWx0cyA+ICRzdGFydHBvcyArIDIwKSB7CgkJCW15ICRu
cSA9IENHSS0+bmV3KCcnKTsKCQkJcHJpbnQgc3RhcnRfZm9ybSwKCQkJCSRucS0+aGlkZGVuKCAt
bmFtZT0+J3NlYXJjaCcsCgkJCQkJLXZhbHVlPT4kc3JoKSwKCQkJCSRucS0+aGlkZGVuKCAtbmFt
ZT0+J25leHQnLAoJCQkJCS12YWx1ZT0+KCRzdGFydHBvcyArIDIwKSksCgkJCQlzdWJtaXQoICdN
b3JlJyksCgkJCQllbmRfZm9ybTsKCQl9Cgl9IGVsc2UgewoJCXByaW50ICRvdXRzdHI7Cgl9Cn0K
CnByaW50IGVuZF9odG1sLCJcbiI7CgojIyMjIyMjIyMgRW5kIG9mIG1haW4gcHJvZ3JhbS4KCiMg
VXRpbGl0eSByb3V0aW5lcyB0byBhY3R1YWxseSBkbyB0aGUgc2VhcmNoCgpzdWIgZG9fc2VhcmNo
IHsKCW15ICR3bWF0Y2ggPSBzaGlmdDsKCiMgQnVpbGQgcmVnZXhwIGZyb20gcGFyYW1ldGVyLiBH
b2JibGUgdXB0byA2MCBjaGFyYWN0ZXJzIG9mIGNvbnRleHQgZWl0aGVyIHNpZGUuCgoJbXkgJHdl
eHAgPSBxci9cYi57MCw2MH1cYiR3bWF0Y2hcYi57MCw2MH1cYi9pczsKCW15ICVyZXM7CgoKIyBT
ZWFyY2ggZXZlcnkgd2lraSBwYWdlIGZvciBtYXRjaGVzCgkKCXdoaWxlIChteSAoJGssJHYpID0g
ZWFjaCAld2lraXRleHQpIHsKCQlteSBAb3V0OwoJCWZvciAoJHYgPX4gLyR3ZXhwL2cpIHsKCQkJ
bXkgJG1hdGNoIC49ICIuLi4kXy4uLiI7CgkJCSRtYXRjaCA9fiBzLzxbXj5dKz4vL2dzOwoJCQkk
bWF0Y2ggPX4gcyFcYigkd21hdGNoKVxiITxiPiQmPC9iPiFpOwoJCQlwdXNoIEBvdXQsJG1hdGNo
OwoJCX0KCQlteSAkdGVtcCA9ICRrOwoJCSR0ZW1wID1+IHMvXy8gL2c7CgojIENvbXB1dGUgc2Nv
cmUgYW5kIHByZXBlbmQgdG8gYXJyYXkgb2YgbWF0Y2hlcwoKCQlteSAkc2NvcmUgPSBAb3V0OwoJ
CSRzY29yZSArPTEwIGlmICR0ZW1wID1+IC8kd2V4cC87CgkJJHJlc3ska30gPSB1bnNoaWZ0KEBv
dXQsJHNjb3JlKSAmJiBcQG91dCBpZiBAb3V0OwoJfQoJCgklcmVzOwp9CgpzdWIgaW50ZXJzcGVy
c2UgewoJbXkgJHBhZ25hbSA9IHNoaWZ0OwoJCglteSBAbWl4ZWQ7ICAgCglteSAkc2NvcmUgPSAw
OwoJCglmb3IgbXkgJGogKEBfKSB7CgkJaWYgKGV4aXN0cyAkai0+eyRwYWduYW19KSB7CgkJCSRz
Y29yZSArPSAkai0+eyRwYWduYW19WzBdOwoJCQlwdXNoIEBtaXhlZCxbJF8sJGotPnskcGFnbmFt
fVskX11dIGZvciAxLi4kI3skai0+eyRwYWduYW19fTsKCQl9Cgl9CgkKCW15IEBpbnRlcnNwZXJz
ZWQgPSBtYXAgJF8tPlsxXSwgc29ydCB7JGEtPlswXSA8PT4gJGItPlswXX0gQG1peGVkOwoJCgl1
bnNoaWZ0IEBpbnRlcnNwZXJzZWQsJHNjb3JlOwoJCglcQGludGVyc3BlcnNlZDsKfQoKIyBtYXRj
aGVkX3dvcmQgLSB3ZSBoYXZlIGEgbGlzdCBvZiBhZGphY2VudCB3b3Jkcy4gV29yZHMgYXJlIGFs
bG93ZWQgdG8gY29udGFpbgojIHdpbGRjYXJkcyAqIGFuZCAlCgpzdWIgbWF0Y2hlZF93b3JkIHsK
CglteSAkd21hdGNoID0gam9pbiAnXFcrJyxAXzsKCSR3bWF0Y2ggPX4gcy8lL1xcdy9nOwoJJHdt
YXRjaCA9fiBzL1wqL1xcdyovZzsKCglkb19zZWFyY2goJHdtYXRjaCk7Cn0KCiMgbWF0Y2hlZF9s
aXRlcmFsIC0gd2UgaGF2ZSBhIGxpdGVyYWwuCgpzdWIgbWF0Y2hlZF9saXRlcmFsIHsKCW15ICRs
aXQgPSBzaGlmdDsKCQoJZG9fc2VhcmNoKHF1b3RlbWV0YSAkbGl0KTsKfQoKIyBtYXRjaGVkX3Rp
dGxlIC0gdGl0bGUgb25seSBzZWFyY2gsIHdlIGhhdmUgYSBsaXN0IG9mIHdvcmRzCgpzdWIgbWF0
Y2hlZF90aXRsZSB7CglteSAkd21hdGNoID0gam9pbiAnXFcrJyxAXzsKCSR3bWF0Y2ggPX4gcy8l
L1xcdy9nOwoJJHdtYXRjaCA9fiBzL1wqL1xcdyovZzsKCglteSAkd2V4cCA9IHFyL1xiJHdtYXRj
aFxiL2lzOwoJbXkgJXJlczsKCQoJZm9yIChrZXlzICV3aWtpdGV4dCkgewoJCSRyZXN7JF99ID0g
WzEwXSBpZiAvJHdleHAvZzsKCX0KCQoJJXJlczsKfQoKCiMgbWF0Y2hlZF9BTkQgLSB3ZSBoYXZl
IGEgY29tYmluYXRpb24gb2Ygc3Vic2VhcmNoZXMuCgpzdWIgbWF0Y2hlZF9BTkQgewoKIyBEbyBh
bGwgdGhlIHNlYXJjaGVzCgoJbXkgQGNvbWJ5X3JlcyA9IG1hcCB7bXkgJW1hdGNoX2hhc2ggPSBt
YXRjaGVkX2l0ZW1zKEAkXyk7XCVtYXRjaF9oYXNofSBAXzsKCiMgVXNlIHRoZSBmaXJzdCBvbmUn
cyByZXN1bHRzIGFzIGEgYmFzaXMgZm9yIHRoZSBvdXRwdXQgaGFzaAoJCglteSBAb3V0PSBrZXlz
ICV7JGNvbWJ5X3Jlc1swXX07CglteSAlb3V0OwoKIyBaYXAgb3V0IGFueSBlbnRyaWVzIHdoaWNo
IGRvIG5vdCBhcHBlYXIgaW4gb25lIG9mIHRoZSBvdGhlciBzZWFyY2hlcy4KCQoJUEFHRToKCWZv
ciBteSAkcGFnZSAoQG91dCkgewoJCWZvciAoQGNvbWJ5X3Jlc1sxLi4kI2NvbWJ5X3Jlc10pIHsK
CQkJKGRlbGV0ZSAkb3V0eyRwYWdlfSksbmV4dCBQQUdFIGlmICFleGlzdHMgJF8tPnskcGFnZX07
CgkJfQoJCQoJCSRvdXR7JHBhZ2V9ID0gaW50ZXJzcGVyc2UoJHBhZ2UsQGNvbWJ5X3Jlcyk7Cgl9
CgkKCSVvdXQ7Cn0KCiMgbWF0Y2hlZF9PUiAtIHdlIGhhdmUgYSBsaXN0IG9mIHN1YnNlYXJjaGVz
CgpzdWIgbWF0Y2hlZF9PUiB7CgojIERvIGFsbCB0aGUgc2VhcmNoZXMKCglteSBAbGlzdF9yZXMg
PSBtYXAge215ICVtYXRjaF9oYXNoID0gbWF0Y2hlZF9pdGVtcyhAJF8pO1wlbWF0Y2hfaGFzaH0g
QF87CgkKCW15ICV1bmlvbjsKCiMgQXBwbHkgdW5pb24gb2YgaGFzaGVzLCBtZXJnaW5nIGFueSBk
dXBsaWNhdGVzLgoJCglmb3IgKEBsaXN0X3JlcykgewoJCXdoaWxlIChteSAoJGssJHYpID0gZWFj
aCAlJF8pIHsKCQkJJHVuaW9ueyRrfSsrOwoJCX0KCX0KCQoJbXkgJW91dDsKCQoJJG91dHskX30g
PSBpbnRlcnNwZXJzZSgkXyxAbGlzdF9yZXMpIGZvciBrZXlzICV1bmlvbjsKCQoJJW91dDsKfQoK
IyBtYXRjaGVkX05PVCAtIEZvcm0gY29tcGxlbWVudCBvZiBoYXNoIGFnYWluc3QgJXdpa2l0ZXh0
CgpzdWIgbWF0Y2hlZF9OT1QgewoKCW15ICVleGNsdWRlcyA9IG1hdGNoZWRfaXRlbXMoQF8pOwoJ
bXkgJW91dCA9IG1hcCB7JF89PlswXX0ga2V5cyAld2lraXRleHQ7CgoJZGVsZXRlICRvdXR7JF99
IGZvciBrZXlzICVleGNsdWRlczsKCSVvdXQ7Cn0KCj1oZWFkMSBOQU1FCgpzZWFyY2gucGwgLSBF
bmhhbmNlbWVudCB0byBVc2Vtb2QgV2lraSBmb3Igc2VhcmNoZXMKCj1oZWFkMSBTWU5PUFNJUwoK
SW52b2tlZCBhcyBhIENHSSBzY3JpcHQuCgpFeGFtcGxlcyBvZiBzZWFyY2ggc3RyaW5nczoKCmtp
bmcncyBoZWFkCmtpbmcncyBoZWFkJmZ1bGxlcnMKY29hY2ggYW5kIGhvcnNlc3xjcm93biBhbmQg
YW5jaG9yCih2ZWdldGFyaWFufHZlZ2FuKSZ0YWtlYXdheQpjYXRlZ29yeSByZXN0YXVyYW50cyYh
ZXhwZW5zaXZlCgo9aGVhZDEgREVTQ1JJUFRJT04KClRoaXMgc2NyaXB0IHByZXNlbnRzIGEgc2lu
Z2xlIHNlYXJjaCBmb3JtIHdoZW4gY2FsbGVkLiBUaGUgc2VhcmNoIHN0cmluZyBpcyBwYXJzZWQg
d2l0aCBhIGZ1bGwKUmVjRGVzY2VudCBncmFtbWFyLCBhbmQgdGhlIHdpa2kgcGFnZXMgYXJlIHNl
YXJjaGVkIGZvciBtYXRjaGVzLgoKQm9ycm93aW5nIGZyb20gUGVybCAob3IgQykgJiByZXByZXNl
bnRzIEFORCwgfCByZXByZXNlbnRzIE9SLCBhbmQgISByZXByZXNlbnRzIE5PVC4KCkZvciBub3Rl
cyBhYm91dCBob3cgdG8gdGFpbG9yIHRoaXMgc2NyaXB0LCBwbGVhc2UgcmVhZCB0aGUgc2NyaXB0
IGNvbW1lbnRzLgoKPWhlYWQxIEFVVEhPUgoKSS4gV2lsbGlhbXMsIEU8bHQ+aXZvci53aWxsaWFt
c0B0aXNjYWxpLmNvLnVrRTxndD4KCj1oZWFkMSBTRUUgQUxTTwoKTDx1c2Vtb2Q+LgoK

------ =_NextPart_000_01C2C877.80F5EFE0
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

-- 
grubstreet mailing list
http://london.openguides.org/old-list-archives/

------ =_NextPart_000_01C2C877.80F5EFE0--