← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 18:42:36 2015
Reported on Fri Jul 31 18:48:15 2015

Filename/var/www/foswikidev/core/lib/Foswiki/Macros/INCLUDE.pm
StatementsExecuted 1021 statements in 4.09ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1211742µs125msFoswiki::::_includeTopicFoswiki::_includeTopic (recurses: max depth 2, inclusive time 72.7ms)
811674µs151msFoswiki::::__ANON__[:339]Foswiki::__ANON__[:339]
1011534µs126msFoswiki::::INCLUDEFoswiki::INCLUDE (recurses: max depth 2, inclusive time 73.2ms)
1111426µs665µsFoswiki::::_fixIncludeLinkFoswiki::_fixIncludeLink
4811224µs889µsFoswiki::::_fixupIncludedTopicFoswiki::_fixupIncludedTopic
81184µs2.80msFoswiki::::__ANON__[:356]Foswiki::__ANON__[:356]
41135µs34.1msFoswiki::::_includeWarningFoswiki::_includeWarning
11113µs26µsFoswiki::::BEGIN@4.74Foswiki::BEGIN@4.74
1119µs13µsFoswiki::::BEGIN@5.75Foswiki::BEGIN@5.75
1114µs4µsFoswiki::::BEGIN@7.76Foswiki::BEGIN@7.76
0000s0sFoswiki::::_includeProtocolFoswiki::_includeProtocol
0000s0sFoswiki::::applyPatternToIncludedTextFoswiki::applyPatternToIncludedText
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# See bottom of file for license and copyright information
2package Foswiki;
3
4228µs240µs
# spent 26µs (13+13) within Foswiki::BEGIN@4.74 which was called: # once (13µs+13µs) by Foswiki::_expandMacroOnTopicRendering at line 4
use strict;
# spent 26µs making 1 call to Foswiki::BEGIN@4.74 # spent 13µs making 1 call to strict::import
5247µs217µs
# spent 13µs (9+4) within Foswiki::BEGIN@5.75 which was called: # once (9µs+4µs) by Foswiki::_expandMacroOnTopicRendering at line 5
use warnings;
# spent 13µs making 1 call to Foswiki::BEGIN@5.75 # spent 4µs making 1 call to warnings::import
6
7
# spent 4µs within Foswiki::BEGIN@7.76 which was called: # once (4µs+0s) by Foswiki::_expandMacroOnTopicRendering at line 12
BEGIN {
814µs if ( $Foswiki::cfg{UseLocale} ) {
9 require locale;
10 import locale();
11 }
1211.68ms14µs}
# spent 4µs making 1 call to Foswiki::BEGIN@7.76
13
14# applyPatternToIncludedText( $text, $pattern ) -> $text
15# Apply a pattern on included text to extract a subset
16# Package-private; used by IncludeHandlers.
17sub applyPatternToIncludedText {
18 my ( $text, $pattern ) = @_;
19
20 $pattern = Foswiki::Sandbox::untaint( $pattern, \&validatePattern );
21
22 my $ok = 0;
23 eval {
24
25 # The eval acts as a try block in case there is anything evil in
26 # the pattern.
27
28 # The () ensures that $1 is defined if $pattern matches
29 # but does not capture anything
30 if ( $text =~ m/$pattern()/is ) {
31 $text = $1;
32 }
33 else {
34
35 # The pattern did not match, so return nothing
36 $text = '';
37 }
38 $ok = 1;
39 };
40 $text = '' unless $ok;
41
42 return $text;
43}
44
45# Replace web references in a topic. Called from forEachLine, applying to
46# each non-verbatim and non-literal line. The in_noautolink option is
47# set by Foswiki::Render when processing a line inside a noautolink block.
48
# spent 889µs (224+665) within Foswiki::_fixupIncludedTopic which was called 48 times, avg 19µs/call: # 48 times (224µs+665µs) by Foswiki::Render::forEachLine at line 930 of /var/www/foswikidev/core/lib/Foswiki/Render.pm, avg 19µs/call
sub _fixupIncludedTopic {
494826µs my ( $text, $options ) = @_;
50
514813µs my $fromWeb = $options->{web};
52
53488µs unless ( $options->{Pref_NOAUTOLINK} || $options->{in_noautolink} ) {
54
55 # 'TopicName' to 'Web.TopicName'
56 $text =~
57s#(?:^|(?<=[\s(]))($Foswiki::regex{wikiWordRegex})(?=\s|\)|$)#$fromWeb.$1#g;
58 }
59
60 # Handle explicit [[]] everywhere
61 # '[[TopicName][...]]' to '[[Web.TopicName][...]]'
624880µs $text =~ s/\[\[([^]]+)\](?:\[([^]]+)\])?\]/
631113µs11665µs _fixIncludeLink( $fromWeb, $1, $2 )/geo;
# spent 665µs making 11 calls to Foswiki::_fixIncludeLink, avg 60µs/call
64
6548116µs return $text;
66}
67
68# Add a web reference to a [[...][...]] link in an included topic
69
# spent 665µs (426+239) within Foswiki::_fixIncludeLink which was called 11 times, avg 60µs/call: # 11 times (426µs+239µs) by Foswiki::_fixupIncludedTopic at line 63, avg 60µs/call
sub _fixIncludeLink {
701113µs my ( $web, $link, $label ) = @_;
71
72 # Detect absolute and relative URLs and web-qualified wikinames
7311424µs3239µs if ( $link =~
# spent 239µs making 3 calls to utf8::SWASHNEW, avg 80µs/call
74m#^($Foswiki::regex{webNameRegex}\.|$Foswiki::regex{defaultWebNameRegex}\.|$Foswiki::regex{linkProtocolPattern}:|/)#
75 )
76 {
77 if ($label) {
78 return "[[$link][$label]]";
79 }
80 else {
81 return "[[$link]]";
82 }
83 }
84 elsif ( !$label ) {
85
86 # Must be wikiword or spaced-out wikiword (or illegal link :-/)
87 $label = $link;
88 }
89
90 # If link is only an anchor, leave it as is (Foswikitask:Item771)
9112µs return "[[$link][$label]]" if $link =~ m/^#/;
9214µs return "[[$web.$link][$label]]";
93}
94
95# generate an include warning
96# SMELL: varying number of parameters idiotic to handle for customized $warn
97
# spent 34.1ms (35µs+34.1) within Foswiki::_includeWarning which was called 4 times, avg 8.53ms/call: # 4 times (35µs+34.1ms) by Foswiki::_includeTopic at line 155, avg 8.53ms/call
sub _includeWarning {
9842µs my $this = shift;
9942µs my $warn = shift;
10042µs my $message = shift;
101
102423µs434.1ms if ( $warn eq 'on' ) {
# spent 34.1ms making 4 calls to Foswiki::inlineAlert, avg 8.52ms/call
103 return $this->inlineAlert( 'alerts', $message, @_ );
104 }
105 elsif ( isTrue($warn) ) {
106
107 # different inlineAlerts need different argument counts
108 my $argument = '';
109 if ( $message eq 'topic_not_found' ) {
110 my ( $web, $topic ) = @_;
111 $argument = "$web.$topic";
112 }
113 else {
114 $argument = shift;
115 }
116 $warn =~ s/\$topic/$argument/g if $argument;
117 return Foswiki::expandStandardEscapes($warn);
118 } # else fail silently
119 return '';
120}
121
122sub _includeProtocol {
123 my ( $this, $handler, $control, $params ) = @_;
124
125 eval 'use Foswiki::IncludeHandlers::' . $handler . ' ()';
126 if ($@) {
127 return $this->_includeWarning( $control->{warn}, 'bad_include_path',
128 "BROKEN $handler for " . $control->{_DEFAULT} );
129 }
130 else {
131 $handler = 'Foswiki::IncludeHandlers::' . $handler;
132 return $handler->INCLUDE( $this, $control, $params );
133 }
134}
135
136
# spent 125ms (742µs+124) within Foswiki::_includeTopic which was called 12 times, avg 10.4ms/call: # 12 times (742µs+124ms) by Foswiki::INCLUDE at line 415, avg 10.4ms/call
sub _includeTopic {
137128µs my ( $this, $includingTopicObject, $control, $params ) = @_;
138
139122µs my $includedWeb;
140127µs my $includedTopic = $control->{_DEFAULT};
141127µs $includedTopic =~ s/\.txt$//; # strip optional (undocumented) .txt
142
1431239µs24111µs ( $includedWeb, $includedTopic ) =
# spent 93µs making 12 calls to Foswiki::normalizeWebTopicName, avg 8µs/call # spent 18µs making 12 calls to Foswiki::Meta::web, avg 2µs/call
144 $this->normalizeWebTopicName( $includingTopicObject->web,
145 $includedTopic );
146
1471221µs12934µs if ( !Foswiki::isValidTopicName( $includedTopic, 1 ) ) {
# spent 934µs making 12 calls to Foswiki::isValidTopicName, avg 78µs/call
148 return $this->_includeWarning(
149 $control->{warn}, 'bad_include_path', $control->{_DEFAULT}
150 ),
151 'bad_include_path';
152 }
153
154 # See Codev.FailedIncludeWarning for the history.
1551259µs1635.0ms unless ( $this->{store}->topicExists( $includedWeb, $includedTopic ) ) {
# spent 34.1ms making 4 calls to Foswiki::_includeWarning, avg 8.53ms/call # spent 894µs making 12 calls to Foswiki::Store::Rcs::Store::topicExists, avg 75µs/call
156 return _includeWarning( $this, $control->{warn}, 'topic_not_found',
157 $includedWeb, $includedTopic ),
158 'topic_not_found';
159 }
160
161 # prevent recursive includes. Note that the inclusion of a topic into
162 # itself is not blocked; however subsequent attempts to include the
163 # topic will fail. There is a hard block of 99 on any recursive include.
164831µs1629µs my $key = $includingTopicObject->web . '.' . $includingTopicObject->topic;
# spent 17µs making 8 calls to Foswiki::Meta::web, avg 2µs/call # spent 12µs making 8 calls to Foswiki::Meta::topic, avg 2µs/call
165818µs my $count = grep( $key, keys %{ $this->{_INCLUDES} } );
16685µs $key .= $control->{_sArgs};
16788µs if ( $this->{_INCLUDES}->{$key} || $count > 99 ) {
168 return _includeWarning( $this, $control->{warn}, 'already_included',
169 "$includedWeb.$includedTopic", '' ),
170 'already_included';
171 }
172
173 # Push the topic context to the included topic, so we can create
174 # local (SESSION) macro definitions without polluting the including
175 # topic namespace.
176819µs82.87ms $this->{prefs}->pushTopicContext( $this->{webName}, $this->{topicName} );
# spent 2.87ms making 8 calls to Foswiki::Prefs::pushTopicContext, avg 359µs/call
177
178813µs $this->{_INCLUDES}->{$key} = 1;
179
180824µs83.99ms my $includedTopicObject =
# spent 3.99ms making 8 calls to Foswiki::Meta::load, avg 499µs/call
181 Foswiki::Meta->load( $this, $includedWeb, $includedTopic,
182 $control->{rev} );
183811µs8197µs unless ( $includedTopicObject->haveAccess('VIEW') ) {
# spent 197µs making 8 calls to Foswiki::Meta::haveAccess, avg 25µs/call
184 if ( isTrue( $control->{warn} ) ) {
185 return $this->inlineAlert( 'alerts', 'access_denied',
186 "[[$includedWeb.$includedTopic]]" ),
187 'access_denied';
188 } # else fail silently
189 return '', 'access_denied';
190 }
191816µs818µs my $memWeb = $this->{prefs}->getPreference('INCLUDINGWEB');
# spent 18µs making 8 calls to Foswiki::Prefs::getPreference, avg 2µs/call
192813µs812µs my $memTopic = $this->{prefs}->getPreference('INCLUDINGTOPIC');
# spent 12µs making 8 calls to Foswiki::Prefs::getPreference, avg 2µs/call
193
19484µs my $text = '';
19582µs my $error = '';
19683µs my $verbatim = {};
19782µs my $dirtyAreas = {};
198
# spent 151ms (674µs+150) within Foswiki::__ANON__[/var/www/foswikidev/core/lib/Foswiki/Macros/INCLUDE.pm:339] which was called 8 times, avg 18.9ms/call: # 8 times (674µs+150ms) by Error::subs::try at line 419 of Error.pm, avg 18.9ms/call
try {
199
200 # Copy params into session level preferences. That way finalisation
201 # will apply to them. These preferences will be popped when the topic
202 # context is restored after the include.
203820µs8254µs $this->{prefs}->setSessionPreferences(%$params);
# spent 254µs making 8 calls to Foswiki::Prefs::setSessionPreferences, avg 32µs/call
204
205 # Set preferences that finalisation does *not* apply to
206831µs2472µs $this->{prefs}->setInternalPreferences(
# spent 44µs making 8 calls to Foswiki::Prefs::setInternalPreferences, avg 6µs/call # spent 16µs making 8 calls to Foswiki::Meta::web, avg 2µs/call # spent 12µs making 8 calls to Foswiki::Meta::topic, avg 2µs/call
207 INCLUDINGWEB => $includingTopicObject->web,
208 INCLUDINGTOPIC => $includingTopicObject->topic
209 );
210
211813µs823µs $text = $includedTopicObject->text;
# spent 23µs making 8 calls to Foswiki::Meta::text, avg 3µs/call
212
213 # Simplify leading, and remove trailing, newlines. If we don't remove
214 # trailing, it becomes impossible to %INCLUDE a topic into a table.
215818µs $text =~ s/^[\r\n]+/\n/;
2168106µs $text =~ s/[\r\n]+$//;
217
218 # remove everything before and after the default include block unless
219 # a section is explicitly defined
22086µs if ( !$control->{section} ) {
221829µs $text =~ s/.*?%STARTINCLUDE%//s;
222832µs $text =~ s/%(?:END|STOP)INCLUDE%.*//s;
223 }
224
225 # prevent dirty areas in included topics from being parsed
22686µs $text = takeOutBlocks( $text, 'dirtyarea', $dirtyAreas )
227 if $Foswiki::cfg{Cache}{Enabled};
228
229 # handle sections
230816µs8103µs my ( $ntext, $sections ) = Foswiki::parseSections($text);
# spent 103µs making 8 calls to Foswiki::parseSections, avg 13µs/call
231
23285µs my $interesting = ( defined $control->{section} );
23383µs if ( $interesting || scalar(@$sections) ) {
234
235 # Rebuild the text from the interesting sections
236 $text = '';
237 foreach my $s (@$sections) {
238 my $process_this_section;
239 if ( $control->{section}
240 && $s->{type} eq 'section'
241 && $s->{name} eq $control->{section} )
242 {
243 $interesting = 1;
244 $process_this_section = 1;
245 }
246 elsif ( $s->{type} eq 'include' && !$control->{section} ) {
247 $interesting = 1;
248 $process_this_section = 1;
249 }
250
251 if ($process_this_section) {
252 $text .=
253 substr( $ntext, $s->{start}, $s->{end} - $s->{start} );
254
255 my %defaults;
256 foreach my $key ( keys(%$s) ) {
257
258 #remove the section parsing specific keys (probably should add a _ to them?)
259 next
260 if ( ( $key eq 'name' )
261 || ( $key eq 'type' )
262 || ( $key eq 'start' )
263 || ( $key eq 'stop' ) );
264
265#don't over-ride existing INCLUDE params and settings (so that nested INCLUDEs pass on their values as they used to), and to avoid FINALISE issues
266 next if ( $this->{prefs}->getPreference($key) );
267 $defaults{$key} = $s->{$key};
268 }
269 $this->{prefs}->setSessionPreferences(%defaults);
270
271 #we only process the first named section
272 last if ( $control->{section} );
273 }
274 }
275 }
276
277822µs if ( $interesting and ( length($text) eq 0 ) ) {
278 $text =
279 _includeWarning( $this, $control->{warn},
280 'topic_section_not_found', $includedWeb, $includedTopic,
281 $control->{section} );
282 $error = 'topic_section_not_found';
283 }
284 else {
285
286 # If there were no interesting sections, restore the whole text
28782µs $text = $ntext unless $interesting;
288
28983µs $text = applyPatternToIncludedText( $text, $control->{pattern} )
290 if ( $control->{pattern} );
291
292 # Do not show TOC in included topic if TOC_HIDE_IF_INCLUDED
293 # preference has been set
294821µs16359µs if ( isTrue( $this->{prefs}->getPreference('TOC_HIDE_IF_INCLUDED') )
# spent 289µs making 8 calls to Foswiki::Prefs::getPreference, avg 36µs/call # spent 70µs making 8 calls to Foswiki::isTrue, avg 9µs/call
295 )
296 {
297 $text =~ s/%TOC(?:{(.*?)})?%//g;
298 }
299
300816µs80s $this->innerExpandMacros( \$text, $includedTopicObject );
# spent 136ms making 8 calls to Foswiki::innerExpandMacros, avg 17.0ms/call, recursion: max depth 3, sum of overlapping time 136ms
301
302 # Item9569: remove verbatim blocks from text passed to commonTagsHandler
303812µs8325µs $text = takeOutBlocks( $text, 'verbatim', $verbatim );
# spent 325µs making 8 calls to Foswiki::takeOutBlocks, avg 41µs/call
304
305 # 4th parameter tells plugin that its called for an included file
306815µs8918µs $this->{plugins}
# spent 918µs making 8 calls to Foswiki::Plugins::dispatch, avg 115µs/call
307 ->dispatch( 'commonTagsHandler', $text, $includedTopic,
308 $includedWeb, 1, $includedTopicObject );
309812µs826µs putBackBlocks( \$text, $verbatim, 'verbatim' );
# spent 26µs making 8 calls to Foswiki::putBackBlocks, avg 3µs/call
310
311 # We have to expand tags again, because a plugin may have inserted
312 # additional tags.
313812µs80s $this->innerExpandMacros( \$text, $includedTopicObject );
# spent 494µs making 8 calls to Foswiki::innerExpandMacros, avg 62µs/call, recursion: max depth 3, sum of overlapping time 494µs
314
315 # If needed, fix all 'TopicNames' to 'Web.TopicNames' to get the
316 # right context so that links continue to work properly
317816µs814µs if ( $includedWeb ne $includingTopicObject->web ) {
# spent 14µs making 8 calls to Foswiki::Meta::web, avg 2µs/call
318615µs12268µs my $noautolink = Foswiki::isTrue(
# spent 212µs making 6 calls to Foswiki::Prefs::getPreference, avg 35µs/call # spent 56µs making 6 calls to Foswiki::isTrue, avg 9µs/call
319 $this->{prefs}->getPreference('NOAUTOLINK') );
320
321 # pre and noautolink parms are used by Foswiki::Render to determine
322 # whether or not to process those blocks.
323 # Pref_NOAUTOLINK passes the preference setting to _fixupIncludedTopic
324646µs1210.9ms $text = $this->renderer->forEachLine(
# spent 9.02ms making 6 calls to Foswiki::renderer, avg 1.50ms/call # spent 1.88ms making 6 calls to Foswiki::Render::forEachLine, avg 313µs/call
325 $text,
326 \&_fixupIncludedTopic,
327 {
328 web => $includedWeb,
329 pre => 1,
330 noautolink => 1,
331 Pref_NOAUTOLINK => $noautolink,
332 }
333 );
334
335 # handle tags again because of plugin hook
336612µs60s innerExpandMacros( $this, \$text, $includedTopicObject );
# spent 408µs making 6 calls to Foswiki::innerExpandMacros, avg 68µs/call, recursion: max depth 3, sum of overlapping time 408µs
337 }
338 }
339 }
340
# spent 2.80ms (84µs+2.72) within Foswiki::__ANON__[/var/www/foswikidev/core/lib/Foswiki/Macros/INCLUDE.pm:356] which was called 8 times, avg 350µs/call: # 8 times (84µs+2.72ms) by Error::subs::try at line 433 of Error.pm, avg 350µs/call
finally {
341
342 # always restore the context, even in the event of an error
343813µs delete $this->{_INCLUDES}->{$key};
344
345811µs839µs $this->{prefs}->setInternalPreferences(
# spent 39µs making 8 calls to Foswiki::Prefs::setInternalPreferences, avg 5µs/call
346 INCLUDINGWEB => $memWeb,
347 INCLUDINGTOPIC => $memTopic
348 );
349
350 # restoring dirty areas
35185µs putBackBlocks( \$text, $dirtyAreas, 'dirtyarea' )
352 if $Foswiki::cfg{Cache}{Enabled};
353
354840µs82.68ms ( $this->{webName}, $this->{topicName} ) =
# spent 2.68ms making 8 calls to Foswiki::Prefs::popTopicContext, avg 335µs/call
355 $this->{prefs}->popTopicContext();
3568231µs1620µs };
# spent 20µs making 8 calls to Error::subs::finally, avg 2µs/call # spent 154ms making 8 calls to Error::subs::try, avg 19.2ms/call, recursion: max depth 3, sum of overlapping time 154ms
357
358873µs return ( $text, $error );
359}
360
361# Processes a specific instance %<nop>INCLUDE{...}% syntax.
362# Returns the text to be inserted in place of the INCLUDE command.
363# $includingTopicObject should be for the immediate parent topic in the
364# include hierarchy. Works for both URLs and absolute server paths.
365
# spent 126ms (534µs+125) within Foswiki::INCLUDE which was called 10 times, avg 12.6ms/call: # 10 times (534µs+125ms) by Foswiki::_expandMacroOnTopicRendering at line 3435 of /var/www/foswikidev/core/lib/Foswiki.pm, avg 12.6ms/call
sub INCLUDE {
366108µs my ( $this, $params, $includingTopicObject ) = @_;
367
368 # remember args for the key before mangling the params
3691018µs10118µs my $args = $params->stringify();
# spent 118µs making 10 calls to Foswiki::Attrs::stringify, avg 12µs/call
370
371 # Remove params, so they don't get expanded in the included page
372102µs my %control;
373108µs for my $p (qw(_DEFAULT pattern rev section raw warn)) {
37460111µs60114µs $control{$p} = $params->remove($p);
# spent 114µs making 60 calls to Foswiki::Attrs::remove, avg 2µs/call
375 }
376107µs $control{_sArgs} = $args;
377
3781017µs9336µs $control{warn} ||= $this->{prefs}->getPreference('INCLUDEWARNING');
# spent 336µs making 9 calls to Foswiki::Prefs::getPreference, avg 37µs/call
379
380101µs my $text;
381
382 # make sure we have something to include. If we don't do this, then
383 # normalizeWebTopicName will default to WebHome. TWikibug:Item2209.
3841025µs unless ( $control{_DEFAULT} ) {
385 $text =
386 $this->_includeWarning( $control{warn}, 'bad_include_path', '' );
387 }
388
389 # Filter out '..' from path to prevent includes of '../../file'
390 elsif ( $Foswiki::cfg{DenyDotDotInclude} && $control{_DEFAULT} =~ m/\.\./ )
391 {
392 $text =
393 $this->_includeWarning( $control{warn}, 'bad_include_path',
394 $control{_DEFAULT} );
395 }
396
397 else {
398
399 # no sense in considering an empty string as an unfindable section
400103µs delete $control{section}
401 if ( defined( $control{section} ) && $control{section} eq '' );
402105µs $control{raw} ||= '';
4031019µs1017µs $control{inWeb} = $includingTopicObject->web;
# spent 17µs making 10 calls to Foswiki::Meta::web, avg 2µs/call
4041015µs1016µs $control{inTopic} = $includingTopicObject->topic;
# spent 16µs making 10 calls to Foswiki::Meta::topic, avg 2µs/call
405
406 # Protocol links e.g. http:, https:, doc:
4071020µs if ( $control{_DEFAULT} =~ m/^([a-z]+):/ ) {
408 $text = $this->_includeProtocol( $1, \%control, $params );
409 }
410 else {
4111028µs my @topics = split( /,\s*/, $control{_DEFAULT} );
412101µs my $error;
413108µs foreach my $t (@topics) {
414125µs $control{_DEFAULT} = $t;
4151262µs12125ms ( $text, $error ) =
# spent 198ms making 12 calls to Foswiki::_includeTopic, avg 16.5ms/call, recursion: max depth 2, sum of overlapping time 72.7ms
416 $this->_includeTopic( $includingTopicObject, \%control,
417 $params );
4181215µs last if ( $error eq '' );
419 }
420 }
421 }
422
423 # Apply any heading offset
424107µs my $hoff = $params->{headingoffset};
425102µs if ( $hoff && $hoff =~ m/^([-+]?\d+)$/ && $1 != 0 ) {
426 my ( $off, $noff ) = ( 0 + $1, 0 - $1 );
427 $text = "<ho off=\"$off\"/>\n$text\n<ho off=\"$noff\">";
428 }
429
4301044µs return $text;
431}
432
43312µs1;
434__END__