#!/usr/bin/env perl
#BOOTSTRAP-BEGIN
# This is the standalone Jemplate compiler.
#
# All you need is this program and the program called `perl`. You don't need
# to install any Perl modules.
#
# If you downloaded this program from the internet, don't forget to put it in
# your path and make sure it is executable. Like this:
#
# mv jemplate /usr/local/bin/
# chmod +x /usr/local/bin/jemplate
#
# Try this command to make sure it works:
#
# jemplate --help
use Config;
BEGIN {
@INC = (
$Config::Config{archlib},
$Config::Config{privlib},
);
}
use strict;
use warnings;
#
# Inline include of Number/Compare.pm
#
BEGIN { $INC{'Number/Compare.pm'} = 'dummy/Number/Compare.pm'; }
BEGIN {
#line 0 "Number/Compare.pm"
package Number::Compare;
use strict;
use Carp qw(croak);
use vars qw/$VERSION/;
$VERSION = '0.01';
sub new {
my $referent = shift;
my $class = ref $referent || $referent;
my $expr = $class->parse_to_perl( shift );
bless eval "sub { \$_[0] $expr }", $class;
}
sub parse_to_perl {
shift;
my $test = shift;
$test =~ m{^
([<>]=?)? # comparison
(.*?) # value
([kmg]i?)? # magnitude
$}ix
or croak "don't understand '$test' as a test";
my $comparison = $1 || '==';
my $target = $2;
my $magnitude = $3;
$target *= 1000 if lc $magnitude eq 'k';
$target *= 1024 if lc $magnitude eq 'ki';
$target *= 1000000 if lc $magnitude eq 'm';
$target *= 1024*1024 if lc $magnitude eq 'mi';
$target *= 1000000000 if lc $magnitude eq 'g';
$target *= 1024*1024*1024 if lc $magnitude eq 'gi';
return "$comparison $target";
}
sub test { $_[0]->( $_[1] ) }
1;
}
#
# Inline include of Text/Glob.pm
#
BEGIN { $INC{'Text/Glob.pm'} = 'dummy/Text/Glob.pm'; }
BEGIN {
#line 0 "Text/Glob.pm"
package Text::Glob;
use strict;
use Exporter;
use vars qw/$VERSION @ISA @EXPORT_OK
$strict_leading_dot $strict_wildcard_slash/;
$VERSION = '0.09';
@ISA = 'Exporter';
@EXPORT_OK = qw( glob_to_regex glob_to_regex_string match_glob );
$strict_leading_dot = 1;
$strict_wildcard_slash = 1;
use constant debug => 0;
sub glob_to_regex {
my $glob = shift;
my $regex = glob_to_regex_string($glob);
return qr/^$regex$/;
}
sub glob_to_regex_string
{
my $glob = shift;
my ($regex, $in_curlies, $escaping);
local $_;
my $first_byte = 1;
for ($glob =~ m/(.)/gs) {
if ($first_byte) {
if ($strict_leading_dot) {
$regex .= '(?=[^\.])' unless $_ eq '.';
}
$first_byte = 0;
}
if ($_ eq '/') {
$first_byte = 1;
}
if ($_ eq '.' || $_ eq '(' || $_ eq ')' || $_ eq '|' ||
$_ eq '+' || $_ eq '^' || $_ eq '$' || $_ eq '@' || $_ eq '%' ) {
$regex .= "\\$_";
}
elsif ($_ eq '*') {
$regex .= $escaping ? "\\*" :
$strict_wildcard_slash ? "[^/]*" : ".*";
}
elsif ($_ eq '?') {
$regex .= $escaping ? "\\?" :
$strict_wildcard_slash ? "[^/]" : ".";
}
elsif ($_ eq '{') {
$regex .= $escaping ? "\\{" : "(";
++$in_curlies unless $escaping;
}
elsif ($_ eq '}' && $in_curlies) {
$regex .= $escaping ? "}" : ")";
--$in_curlies unless $escaping;
}
elsif ($_ eq ',' && $in_curlies) {
$regex .= $escaping ? "," : "|";
}
elsif ($_ eq "\\") {
if ($escaping) {
$regex .= "\\\\";
$escaping = 0;
}
else {
$escaping = 1;
}
next;
}
else {
$regex .= $_;
$escaping = 0;
}
$escaping = 0;
}
print "# $glob $regex\n" if debug;
return $regex;
}
sub match_glob {
print "# ", join(', ', map { "'$_'" } @_), "\n" if debug;
my $glob = shift;
my $regex = glob_to_regex $glob;
local $_;
grep { $_ =~ $regex } @_;
}
1;
}
#
# Inline include of File/Find/Rule.pm
#
BEGIN { $INC{'File/Find/Rule.pm'} = 'dummy/File/Find/Rule.pm'; }
BEGIN {
#line 0 "File/Find/Rule.pm"
package File::Find::Rule;
use strict;
use File::Spec;
use Text::Glob 'glob_to_regex';
use Number::Compare;
use Carp qw/croak/;
use File::Find (); # we're only wrapping for now
our $VERSION = '0.32';
sub import {
my $pkg = shift;
my $to = caller;
for my $sym ( qw( find rule ) ) {
no strict 'refs';
*{"$to\::$sym"} = \&{$sym};
}
for (grep /^:/, @_) {
my ($extension) = /^:(.*)/;
eval "require File::Find::Rule::$extension";
croak "couldn't bootstrap File::Find::Rule::$extension: $@" if $@;
}
}
*rule = \&find;
sub find {
my $object = __PACKAGE__->new();
my $not = 0;
while (@_) {
my $method = shift;
my @args;
if ($method =~ s/^\!//) {
# jinkies, we're really negating this
unshift @_, $method;
$not = 1;
next;
}
unless (defined prototype $method) {
my $args = shift;
@args = ref $args eq 'ARRAY' ? @$args : $args;
}
if ($not) {
$not = 0;
@args = $object->new->$method(@args);
$method = "not";
}
my @return = $object->$method(@args);
return @return if $method eq 'in';
}
$object;
}
sub new {
my $referent = shift;
my $class = ref $referent || $referent;
bless {
rules => [],
subs => {},
iterator => [],
extras => {},
maxdepth => undef,
mindepth => undef,
}, $class;
}
sub _force_object {
my $object = shift;
$object = $object->new()
unless ref $object;
$object;
}
sub _flatten {
my @flat;
while (@_) {
my $item = shift;
ref $item eq 'ARRAY' ? push @_, @{ $item } : push @flat, $item;
}
return @flat;
}
sub name {
my $self = _force_object shift;
my @names = map { ref $_ eq "Regexp" ? $_ : glob_to_regex $_ } _flatten( @_ );
push @{ $self->{rules} }, {
rule => 'name',
code => join( ' || ', map { "m($_)" } @names ),
args => \@_,
};
$self;
}
use vars qw( %X_tests );
%X_tests = (
-r => readable => -R => r_readable =>
-w => writeable => -W => r_writeable =>
-w => writable => -W => r_writable =>
-x => executable => -X => r_executable =>
-o => owned => -O => r_owned =>
-e => exists => -f => file =>
-z => empty => -d => directory =>
-s => nonempty => -l => symlink =>
=> -p => fifo =>
-u => setuid => -S => socket =>
-g => setgid => -b => block =>
-k => sticky => -c => character =>
=> -t => tty =>
-M => modified =>
-A => accessed => -T => ascii =>
-C => changed => -B => binary =>
);
for my $test (keys %X_tests) {
my $sub = eval 'sub () {
my $self = _force_object shift;
push @{ $self->{rules} }, {
code => "' . $test . ' \$_",
rule => "'.$X_tests{$test}.'",
};
$self;
} ';
no strict 'refs';
*{ $X_tests{$test} } = $sub;
}
use vars qw( @stat_tests );
@stat_tests = qw( dev ino mode nlink uid gid rdev
size atime mtime ctime blksize blocks );
{
my $i = 0;
for my $test (@stat_tests) {
my $index = $i++; # to close over
my $sub = sub {
my $self = _force_object shift;
my @tests = map { Number::Compare->parse_to_perl($_) } @_;
push @{ $self->{rules} }, {
rule => $test,
args => \@_,
code => 'do { my $val = (stat $_)['.$index.'] || 0;'.
join ('||', map { "(\$val $_)" } @tests ).' }',
};
$self;
};
no strict 'refs';
*$test = $sub;
}
}
sub any {
my $self = _force_object shift;
# compile all the subrules to code fragments
push @{ $self->{rules} }, {
rule => "any",
code => '(' . join( ' || ', map '( ' . $_->_compile . ' )', @_ ). ')',
args => \@_,
};
# merge all the subs hashes of the kids into ourself
%{ $self->{subs} } = map { %{ $_->{subs} } } $self, @_;
$self;
}
*or = \&any;
sub not {
my $self = _force_object shift;
push @{ $self->{rules} }, {
rule => 'not',
args => \@_,
code => '(' . join ( ' && ', map { "!(". $_->_compile . ")" } @_ ) . ")",
};
# merge all the subs hashes into us
%{ $self->{subs} } = map { %{ $_->{subs} } } $self, @_;
$self;
}
*none = \¬
sub prune () {
my $self = _force_object shift;
push @{ $self->{rules} },
{
rule => 'prune',
code => '$File::Find::prune = 1'
};
$self;
}
sub discard () {
my $self = _force_object shift;
push @{ $self->{rules} }, {
rule => 'discard',
code => '$discarded = 1',
};
$self;
}
sub exec {
my $self = _force_object shift;
my $code = shift;
push @{ $self->{rules} }, {
rule => 'exec',
code => $code,
};
$self;
}
sub grep {
my $self = _force_object shift;
my @pattern = map {
ref $_
? ref $_ eq 'ARRAY'
? map { [ ( ref $_ ? $_ : qr/$_/ ) => 0 ] } @$_
: [ $_ => 1 ]
: [ qr/$_/ => 1 ]
} @_;
$self->exec( sub {
local *FILE;
open FILE, $_ or return;
local ($_, $.);
while (<FILE>) {
for my $p (@pattern) {
my ($rule, $ret) = @$p;
return $ret
if ref $rule eq 'Regexp'
? /$rule/
: $rule->(@_);
}
}
return;
} );
}
for my $setter (qw( maxdepth mindepth extras )) {
my $sub = sub {
my $self = _force_object shift;
$self->{$setter} = shift;
$self;
};
no strict 'refs';
*$setter = $sub;
}
sub relative () {
my $self = _force_object shift;
$self->{relative} = 1;
$self;
}
sub DESTROY {}
sub AUTOLOAD {
our $AUTOLOAD;
$AUTOLOAD =~ /::not_([^:]*)$/
or croak "Can't locate method $AUTOLOAD";
my $method = $1;
my $sub = sub {
my $self = _force_object shift;
$self->not( $self->new->$method(@_) );
};
{
no strict 'refs';
*$AUTOLOAD = $sub;
}
&$sub;
}
sub in {
my $self = _force_object shift;
my @found;
my $fragment = $self->_compile;
my %subs = %{ $self->{subs} };
warn "relative mode handed multiple paths - that's a bit silly\n"
if $self->{relative} && @_ > 1;
my $topdir;
my $code = 'sub {
(my $path = $File::Find::name) =~ s#^(?:\./+)+##;
my @args = ($_, $File::Find::dir, $path);
my $maxdepth = $self->{maxdepth};
my $mindepth = $self->{mindepth};
my $relative = $self->{relative};
# figure out the relative path and depth
my $relpath = $File::Find::name;
$relpath =~ s{^\Q$topdir\E/?}{};
my $depth = scalar File::Spec->splitdir($relpath);
#print "name: \'$File::Find::name\' ";
#print "relpath: \'$relpath\' depth: $depth relative: $relative\n";
defined $maxdepth && $depth >= $maxdepth
and $File::Find::prune = 1;
defined $mindepth && $depth < $mindepth
and return;
#print "Testing \'$_\'\n";
my $discarded;
return unless ' . $fragment . ';
return if $discarded;
if ($relative) {
push @found, $relpath if $relpath ne "";
}
else {
push @found, $path;
}
}';
#use Data::Dumper;
#print Dumper \%subs;
#warn "Compiled sub: '$code'\n";
my $sub = eval "$code" or die "compile error '$code' $@";
for my $path (@_) {
# $topdir is used for relative and maxdepth
$topdir = $path;
# slice off the trailing slash if there is one (the
# maxdepth/mindepth code is fussy)
$topdir =~ s{/?$}{}
unless $topdir eq '/';
$self->_call_find( { %{ $self->{extras} }, wanted => $sub }, $path );
}
return @found;
}
sub _call_find {
my $self = shift;
File::Find::find( @_ );
}
sub _compile {
my $self = shift;
return '1' unless @{ $self->{rules} };
my $code = join " && ", map {
if (ref $_->{code}) {
my $key = "$_->{code}";
$self->{subs}{$key} = $_->{code};
"\$subs{'$key'}->(\@args) # $_->{rule}\n";
}
else {
"( $_->{code} ) # $_->{rule}\n";
}
} @{ $self->{rules} };
#warn $code;
return $code;
}
sub start {
my $self = _force_object shift;
$self->{iterator} = [ $self->in( @_ ) ];
$self;
}
sub match {
my $self = _force_object shift;
return shift @{ $self->{iterator} };
}
1;
}
#
# Inline include of Template/Constants.pm
#
BEGIN { $INC{'Template/Constants.pm'} = 'dummy/Template/Constants.pm'; }
BEGIN {
#line 0 "Template/Constants.pm"
package Template::Constants;
require Exporter;
use strict;
use warnings;
use Exporter;
use vars qw( @EXPORT_OK %EXPORT_TAGS );
use vars qw( $DEBUG_OPTIONS @STATUS @ERROR @CHOMP @DEBUG @ISA );
@ISA = qw( Exporter );
our $VERSION = 2.75;
use constant STATUS_OK => 0; # ok
use constant STATUS_RETURN => 1; # ok, block ended by RETURN
use constant STATUS_STOP => 2; # ok, stoppped by STOP
use constant STATUS_DONE => 3; # ok, iterator done
use constant STATUS_DECLINED => 4; # ok, declined to service request
use constant STATUS_ERROR => 255; # error condition
use constant ERROR_RETURN => 'return'; # return a status code
use constant ERROR_FILE => 'file'; # file error: I/O, parse, recursion
use constant ERROR_VIEW => 'view'; # view error
use constant ERROR_UNDEF => 'undef'; # undefined variable value used
use constant ERROR_PERL => 'perl'; # error in [% PERL %] block
use constant ERROR_FILTER => 'filter'; # filter error
use constant ERROR_PLUGIN => 'plugin'; # plugin error
use constant CHOMP_NONE => 0; # do not remove whitespace
use constant CHOMP_ALL => 1; # remove whitespace up to newline
use constant CHOMP_ONE => 1; # new name for CHOMP_ALL
use constant CHOMP_COLLAPSE => 2; # collapse whitespace to a single space
use constant CHOMP_GREEDY => 3; # remove all whitespace including newlines
use constant DEBUG_OFF => 0; # do nothing
use constant DEBUG_ON => 1; # basic debugging flag
use constant DEBUG_UNDEF => 2; # throw undef on undefined variables
use constant DEBUG_VARS => 4; # general variable debugging
use constant DEBUG_DIRS => 8; # directive debugging
use constant DEBUG_STASH => 16; # general stash debugging
use constant DEBUG_CONTEXT => 32; # context debugging
use constant DEBUG_PARSER => 64; # parser debugging
use constant DEBUG_PROVIDER => 128; # provider debugging
use constant DEBUG_PLUGINS => 256; # plugins debugging
use constant DEBUG_FILTERS => 512; # filters debugging
use constant DEBUG_SERVICE => 1024; # context debugging
use constant DEBUG_ALL => 2047; # everything
use constant DEBUG_CALLER => 4096; # add caller file/line
use constant DEBUG_FLAGS => 4096; # bitmask to extraxt flags
$DEBUG_OPTIONS = {
&DEBUG_OFF => off => off => &DEBUG_OFF,
&DEBUG_ON => on => on => &DEBUG_ON,
&DEBUG_UNDEF => undef => undef => &DEBUG_UNDEF,
&DEBUG_VARS => vars => vars => &DEBUG_VARS,
&DEBUG_DIRS => dirs => dirs => &DEBUG_DIRS,
&DEBUG_STASH => stash => stash => &DEBUG_STASH,
&DEBUG_CONTEXT => context => context => &DEBUG_CONTEXT,
&DEBUG_PARSER => parser => parser => &DEBUG_PARSER,
&DEBUG_PROVIDER => provider => provider => &DEBUG_PROVIDER,
&DEBUG_PLUGINS => plugins => plugins => &DEBUG_PLUGINS,
&DEBUG_FILTERS => filters => filters => &DEBUG_FILTERS,
&DEBUG_SERVICE => service => service => &DEBUG_SERVICE,
&DEBUG_ALL => all => all => &DEBUG_ALL,
&DEBUG_CALLER => caller => caller => &DEBUG_CALLER,
};
@STATUS = qw( STATUS_OK STATUS_RETURN STATUS_STOP STATUS_DONE
STATUS_DECLINED STATUS_ERROR );
@ERROR = qw( ERROR_FILE ERROR_VIEW ERROR_UNDEF ERROR_PERL
ERROR_RETURN ERROR_FILTER ERROR_PLUGIN );
@CHOMP = qw( CHOMP_NONE CHOMP_ALL CHOMP_ONE CHOMP_COLLAPSE CHOMP_GREEDY );
@DEBUG = qw( DEBUG_OFF DEBUG_ON DEBUG_UNDEF DEBUG_VARS
DEBUG_DIRS DEBUG_STASH DEBUG_CONTEXT DEBUG_PARSER
DEBUG_PROVIDER DEBUG_PLUGINS DEBUG_FILTERS DEBUG_SERVICE
DEBUG_ALL DEBUG_CALLER DEBUG_FLAGS );
@EXPORT_OK = ( @STATUS, @ERROR, @CHOMP, @DEBUG );
%EXPORT_TAGS = (
'all' => [ @EXPORT_OK ],
'status' => [ @STATUS ],
'error' => [ @ERROR ],
'chomp' => [ @CHOMP ],
'debug' => [ @DEBUG ],
);
sub debug_flags {
my ($self, $debug) = @_;
my (@flags, $flag, $value);
$debug = $self unless defined($debug) || ref($self);
if ($debug =~ /^\d+$/) {
foreach $flag (@DEBUG) {
next if $flag =~ /^DEBUG_(OFF|ALL|FLAGS)$/;
# don't trash the original
my $copy = $flag;
$flag =~ s/^DEBUG_//;
$flag = lc $flag;
return $self->error("no value for flag: $flag")
unless defined($value = $DEBUG_OPTIONS->{ $flag });
$flag = $value;
if ($debug & $flag) {
$value = $DEBUG_OPTIONS->{ $flag };
return $self->error("no value for flag: $flag") unless defined $value;
push(@flags, $value);
}
}
return wantarray ? @flags : join(', ', @flags);
}
else {
@flags = split(/\W+/, $debug);
$debug = 0;
foreach $flag (@flags) {
$value = $DEBUG_OPTIONS->{ $flag };
return $self->error("unknown debug flag: $flag") unless defined $value;
$debug |= $value;
}
return $debug;
}
}
1;
}
#
# Inline include of Template/Base.pm
#
BEGIN { $INC{'Template/Base.pm'} = 'dummy/Template/Base.pm'; }
BEGIN {
#line 0 "Template/Base.pm"
package Template::Base;
use strict;
use warnings;
use Template::Constants;
our $VERSION = 2.78;
sub new {
my $class = shift;
my ($argnames, @args, $arg, $cfg);
{ no strict 'refs';
no warnings 'once';
$argnames = \@{"$class\::BASEARGS"} || [ ];
}
# shift off all mandatory args, returning error if undefined or null
foreach $arg (@$argnames) {
return $class->error("no $arg specified")
unless ($cfg = shift);
push(@args, $cfg);
}
# fold all remaining args into a hash, or use provided hash ref
$cfg = defined $_[0] && ref($_[0]) eq 'HASH' ? shift : { @_ };
my $self = bless {
(map { ($_ => shift @args) } @$argnames),
_ERROR => '',
DEBUG => 0,
}, $class;
return $self->_init($cfg) ? $self : $class->error($self->error);
}
sub error {
my $self = shift;
my $errvar;
{
no strict qw( refs );
$errvar = ref $self ? \$self->{ _ERROR } : \${"$self\::ERROR"};
}
if (@_) {
$$errvar = ref($_[0]) ? shift : join('', @_);
return undef;
}
else {
return $$errvar;
}
}
sub _init {
my ($self, $config) = @_;
return $self;
}
sub debug {
my $self = shift;
my $msg = join('', @_);
my ($pkg, $file, $line) = caller();
unless ($msg =~ /\n$/) {
$msg .= ($self->{ DEBUG } & Template::Constants::DEBUG_CALLER)
? " at $file line $line\n"
: "\n";
}
print STDERR "[$pkg] $msg";
}
sub module_version {
my $self = shift;
my $class = ref $self || $self;
no strict 'refs';
return ${"${class}::VERSION"};
}
1;
}
#
# Inline include of Template/Config.pm
#
BEGIN { $INC{'Template/Config.pm'} = 'dummy/Template/Config.pm'; }
BEGIN {
#line 0 "Template/Config.pm"
package Template::Config;
use strict;
use warnings;
use base 'Template::Base';
use vars qw( $VERSION $DEBUG $ERROR $INSTDIR
$PARSER $PROVIDER $PLUGINS $FILTERS $ITERATOR
$LATEX_PATH $PDFLATEX_PATH $DVIPS_PATH
$STASH $SERVICE $CONTEXT $CONSTANTS @PRELOAD );
$VERSION = 2.75;
$DEBUG = 0 unless defined $DEBUG;
$ERROR = '';
$CONTEXT = 'Template::Context';
$FILTERS = 'Template::Filters';
$ITERATOR = 'Template::Iterator';
$PARSER = 'Template::Parser';
$PLUGINS = 'Template::Plugins';
$PROVIDER = 'Template::Provider';
$SERVICE = 'Template::Service';
$STASH = 'Template::Stash::XS';
$CONSTANTS = 'Template::Namespace::Constants';
@PRELOAD = ( $CONTEXT, $FILTERS, $ITERATOR, $PARSER,
$PLUGINS, $PROVIDER, $SERVICE, $STASH );
$INSTDIR = '';
sub preload {
my $class = shift;
foreach my $module (@PRELOAD, @_) {
$class->load($module) || return;
};
return 1;
}
sub load {
my ($class, $module) = @_;
$module =~ s[::][/]g;
$module .= '.pm';
eval { require $module; };
return $@ ? $class->error("failed to load $module: $@") : 1;
}
sub parser {
my $class = shift;
my $params = defined($_[0]) && ref($_[0]) eq 'HASH'
? shift : { @_ };
return undef unless $class->load($PARSER);
return $PARSER->new($params)
|| $class->error("failed to create parser: ", $PARSER->error);
}
sub provider {
my $class = shift;
my $params = defined($_[0]) && ref($_[0]) eq 'HASH'
? shift : { @_ };
return undef unless $class->load($PROVIDER);
return $PROVIDER->new($params)
|| $class->error("failed to create template provider: ",
$PROVIDER->error);
}
sub plugins {
my $class = shift;
my $params = defined($_[0]) && ref($_[0]) eq 'HASH'
? shift : { @_ };
return undef unless $class->load($PLUGINS);
return $PLUGINS->new($params)
|| $class->error("failed to create plugin provider: ",
$PLUGINS->error);
}
sub filters {
my $class = shift;
my $params = defined($_[0]) && ref($_[0]) eq 'HASH'
? shift : { @_ };
return undef unless $class->load($FILTERS);
return $FILTERS->new($params)
|| $class->error("failed to create filter provider: ",
$FILTERS->error);
}
sub iterator {
my $class = shift;
my $list = shift;
return undef unless $class->load($ITERATOR);
return $ITERATOR->new($list, @_)
|| $class->error("failed to create iterator: ", $ITERATOR->error);
}
sub stash {
my $class = shift;
my $params = defined($_[0]) && ref($_[0]) eq 'HASH'
? shift : { @_ };
return undef unless $class->load($STASH);
return $STASH->new($params)
|| $class->error("failed to create stash: ", $STASH->error);
}
sub context {
my $class = shift;
my $params = defined($_[0]) && ref($_[0]) eq 'HASH'
? shift : { @_ };
return undef unless $class->load($CONTEXT);
return $CONTEXT->new($params)
|| $class->error("failed to create context: ", $CONTEXT->error);
}
sub service {
my $class = shift;
my $params = defined($_[0]) && ref($_[0]) eq 'HASH'
? shift : { @_ };
return undef unless $class->load($SERVICE);
return $SERVICE->new($params)
|| $class->error("failed to create context: ", $SERVICE->error);
}
sub constants {
my $class = shift;
my $params = defined($_[0]) && ref($_[0]) eq 'HASH'
? shift : { @_ };
return undef unless $class->load($CONSTANTS);
return $CONSTANTS->new($params)
|| $class->error("failed to create constants namespace: ",
$CONSTANTS->error);
}
sub instdir {
my ($class, $dir) = @_;
my $inst = $INSTDIR
|| return $class->error("no installation directory");
$inst =~ s[/$][]g;
$inst .= "/$dir" if $dir;
return $inst;
}
package Template::TieString;
sub TIEHANDLE {
my ($class, $textref) = @_;
bless $textref, $class;
}
sub PRINT {
my $self = shift;
$$self .= join('', @_);
}
1;
}
#
# Inline include of Template/Document.pm
#
BEGIN { $INC{'Template/Document.pm'} = 'dummy/Template/Document.pm'; }
BEGIN {
#line 0 "Template/Document.pm"
package Template::Document;
use strict;
use warnings;
use base 'Template::Base';
use Template::Constants;
our $VERSION = 2.79;
our $DEBUG = 0 unless defined $DEBUG;
our $ERROR = '';
our ($COMPERR, $AUTOLOAD, $UNICODE);
BEGIN {
# UNICODE is supported in versions of Perl from 5.008 onwards
if ($UNICODE = $] > 5.007 ? 1 : 0) {
if ($] > 5.008) {
# utf8::is_utf8() available from Perl 5.8.1 onwards
*is_utf8 = \&utf8::is_utf8;
}
elsif ($] == 5.008) {
# use Encode::is_utf8() for Perl 5.8.0
require Encode;
*is_utf8 = \&Encode::is_utf8;
}
}
}
sub new {
my ($class, $doc) = @_;
my ($block, $defblocks, $metadata) = @$doc{ qw( BLOCK DEFBLOCKS METADATA ) };
$defblocks ||= { };
$metadata ||= { };
# evaluate Perl code in $block to create sub-routine reference if necessary
unless (ref $block) {
local $SIG{__WARN__} = \&catch_warnings;
$COMPERR = '';
# DON'T LOOK NOW! - blindly untainting can make you go blind!
$block =~ /(.*)/s;
$block = $1;
$block = eval $block;
return $class->error($@)
unless defined $block;
}
# same for any additional BLOCK definitions
@$defblocks{ keys %$defblocks } =
# MORE BLIND UNTAINTING - turn away if you're squeamish
map {
ref($_)
? $_
: ( /(.*)/s && eval($1) or return $class->error($@) )
} values %$defblocks;
bless {
%$metadata,
_BLOCK => $block,
_DEFBLOCKS => $defblocks,
_HOT => 0,
}, $class;
}
sub block {
return $_[0]->{ _BLOCK };
}
sub blocks {
return $_[0]->{ _DEFBLOCKS };
}
sub process {
my ($self, $context) = @_;
my $defblocks = $self->{ _DEFBLOCKS };
my $output;
# check we're not already visiting this template
return $context->throw(Template::Constants::ERROR_FILE,
"recursion into '$self->{ name }'")
if $self->{ _HOT } && ! $context->{ RECURSION }; ## RETURN ##
$context->visit($self, $defblocks);
$self->{ _HOT } = 1;
eval {
my $block = $self->{ _BLOCK };
$output = &$block($context);
};
$self->{ _HOT } = 0;
$context->leave();
die $context->catch($@)
if $@;
return $output;
}
sub AUTOLOAD {
my $self = shift;
my $method = $AUTOLOAD;
$method =~ s/.*:://;
return if $method eq 'DESTROY';
return $self->{ $method };
}
sub _dump {
my $self = shift;
my $dblks;
my $output = "$self : $self->{ name }\n";
$output .= "BLOCK: $self->{ _BLOCK }\nDEFBLOCKS:\n";
if ($dblks = $self->{ _DEFBLOCKS }) {
foreach my $b (keys %$dblks) {
$output .= " $b: $dblks->{ $b }\n";
}
}
return $output;
}
sub as_perl {
my ($class, $content) = @_;
my ($block, $defblocks, $metadata) = @$content{ qw( BLOCK DEFBLOCKS METADATA ) };
$block =~ s/\n(?!#line)/\n /g;
$block =~ s/\s+$//;
$defblocks = join('', map {
my $code = $defblocks->{ $_ };
$code =~ s/\n(?!#line)/\n /g;
$code =~ s/\s*$//;
" '$_' => $code,\n";
} keys %$defblocks);
$defblocks =~ s/\s+$//;
$metadata = join('', map {
my $x = $metadata->{ $_ };
$x =~ s/(['\\])/\\$1/g;
" '$_' => '$x',\n";
} keys %$metadata);
$metadata =~ s/\s+$//;
return <<EOF
$class->new({
METADATA => {
$metadata
},
BLOCK => $block,
DEFBLOCKS => {
$defblocks
},
});
EOF
}
sub write_perl_file {
my ($class, $file, $content) = @_;
my ($fh, $tmpfile);
return $class->error("invalid filename: $file")
unless $file =~ /^(.+)$/s;
eval {
require File::Temp;
require File::Basename;
($fh, $tmpfile) = File::Temp::tempfile(
DIR => File::Basename::dirname($file)
);
my $perlcode = $class->as_perl($content) || die $!;
if ($UNICODE && is_utf8($perlcode)) {
$perlcode = "use utf8;\n\n$perlcode";
binmode $fh, ":utf8";
}
print $fh $perlcode;
close($fh);
};
return $class->error($@) if $@;
return rename($tmpfile, $file)
|| $class->error($!);
}
sub catch_warnings {
$COMPERR .= join('', @_);
}
1;
}
#
# Inline include of Template/Exception.pm
#
BEGIN { $INC{'Template/Exception.pm'} = 'dummy/Template/Exception.pm'; }
BEGIN {
#line 0 "Template/Exception.pm"
package Template::Exception;
use strict;
use warnings;
use constant TYPE => 0;
use constant INFO => 1;
use constant TEXT => 2;
use overload q|""| => "as_string", fallback => 1;
our $VERSION = 2.70;
sub new {
my ($class, $type, $info, $textref) = @_;
bless [ $type, $info, $textref ], $class;
}
sub type {
$_[0]->[ TYPE ];
}
sub info {
$_[0]->[ INFO ];
}
sub type_info {
my $self = shift;
@$self[ TYPE, INFO ];
}
sub text {
my ($self, $newtextref) = @_;
my $textref = $self->[ TEXT ];
if ($newtextref) {
$$newtextref .= $$textref if $textref && $textref ne $newtextref;
$self->[ TEXT ] = $newtextref;
return '';
}
elsif ($textref) {
return $$textref;
}
else {
return '';
}
}
sub as_string {
my $self = shift;
return $self->[ TYPE ] . ' error - ' . $self->[ INFO ];
}
sub select_handler {
my ($self, @options) = @_;
my $type = $self->[ TYPE ];
my %hlut;
@hlut{ @options } = (1) x @options;
while ($type) {
return $type if $hlut{ $type };
# strip .element from the end of the exception type to find a
# more generic handler
$type =~ s/\.?[^\.]*$//;
}
return undef;
}
1;
}
#
# Inline include of Template/Service.pm
#
BEGIN { $INC{'Template/Service.pm'} = 'dummy/Template/Service.pm'; }
BEGIN {
#line 0 "Template/Service.pm"
package Template::Service;
use strict;
use warnings;
use base 'Template::Base';
use Template::Config;
use Template::Exception;
use Template::Constants;
use Scalar::Util 'blessed';
use constant EXCEPTION => 'Template::Exception';
our $VERSION = 2.80;
our $DEBUG = 0 unless defined $DEBUG;
our $ERROR = '';
sub process {
my ($self, $template, $params) = @_;
my $context = $self->{ CONTEXT };
my ($name, $output, $procout, $error);
$output = '';
$self->debug("process($template, ",
defined $params ? $params : '<no params>',
')') if $self->{ DEBUG };
$context->reset()
if $self->{ AUTO_RESET };
# pre-request compiled template from context so that we can alias it
# in the stash for pre-processed templates to reference
eval { $template = $context->template($template) };
return $self->error($@)
if $@;
# localise the variable stash with any parameters passed
# and set the 'template' variable
$params ||= { };
# TODO: change this to C<||=> so we can use a template parameter
$params->{ template } = $template
unless ref $template eq 'CODE';
$context->localise($params);
SERVICE: {
# PRE_PROCESS
eval {
foreach $name (@{ $self->{ PRE_PROCESS } }) {
$self->debug("PRE_PROCESS: $name") if $self->{ DEBUG };
$output .= $context->process($name);
}
};
last SERVICE if ($error = $@);
# PROCESS
eval {
foreach $name (@{ $self->{ PROCESS } || [ $template ] }) {
$self->debug("PROCESS: $name") if $self->{ DEBUG };
$procout .= $context->process($name);
}
};
if ($error = $@) {
last SERVICE
unless defined ($procout = $self->_recover(\$error));
}
if (defined $procout) {
# WRAPPER
eval {
foreach $name (reverse @{ $self->{ WRAPPER } }) {
$self->debug("WRAPPER: $name") if $self->{ DEBUG };
$procout = $context->process($name, { content => $procout });
}
};
last SERVICE if ($error = $@);
$output .= $procout;
}
# POST_PROCESS
eval {
foreach $name (@{ $self->{ POST_PROCESS } }) {
$self->debug("POST_PROCESS: $name") if $self->{ DEBUG };
$output .= $context->process($name);
}
};
last SERVICE if ($error = $@);
}
$context->delocalise();
delete $params->{ template };
if ($error) {
# $error = $error->as_string if ref $error;
return $self->error($error);
}
return $output;
}
sub context {
return $_[0]->{ CONTEXT };
}
sub _init {
my ($self, $config) = @_;
my ($item, $data, $context, $block, $blocks);
my $delim = $config->{ DELIMITER };
$delim = ':' unless defined $delim;
# coerce PRE_PROCESS, PROCESS and POST_PROCESS to arrays if necessary,
# by splitting on non-word characters
foreach $item (qw( PRE_PROCESS PROCESS POST_PROCESS WRAPPER )) {
$data = $config->{ $item };
$self->{ $item } = [ ], next unless (defined $data);
$data = [ split($delim, $data || '') ]
unless ref $data eq 'ARRAY';
$self->{ $item } = $data;
}
# unset PROCESS option unless explicitly specified in config
$self->{ PROCESS } = undef
unless defined $config->{ PROCESS };
$self->{ ERROR } = $config->{ ERROR } || $config->{ ERRORS };
$self->{ AUTO_RESET } = defined $config->{ AUTO_RESET }
? $config->{ AUTO_RESET } : 1;
$self->{ DEBUG } = ( $config->{ DEBUG } || 0 )
& Template::Constants::DEBUG_SERVICE;
$context = $self->{ CONTEXT } = $config->{ CONTEXT }
|| Template::Config->context($config)
|| return $self->error(Template::Config->error);
return $self;
}
sub _recover {
my ($self, $error) = @_;
my $context = $self->{ CONTEXT };
my ($hkey, $handler, $output);
# there shouldn't ever be a non-exception object received at this
# point... unless a module like CGI::Carp messes around with the
# DIE handler.
return undef
unless blessed($$error) && $$error->isa(EXCEPTION);
# a 'stop' exception is thrown by [% STOP %] - we return the output
# buffer stored in the exception object
return $$error->text()
if $$error->type() eq 'stop';
my $handlers = $self->{ ERROR }
|| return undef; ## RETURN
if (ref $handlers eq 'HASH') {
if ($hkey = $$error->select_handler(keys %$handlers)) {
$handler = $handlers->{ $hkey };
$self->debug("using error handler for $hkey") if $self->{ DEBUG };
}
elsif ($handler = $handlers->{ default }) {
# use default handler
$self->debug("using default error handler") if $self->{ DEBUG };
}
else {
return undef; ## RETURN
}
}
else {
$handler = $handlers;
$self->debug("using default error handler") if $self->{ DEBUG };
}
eval { $handler = $context->template($handler) };
if ($@) {
$$error = $@;
return undef; ## RETURN
};
$context->stash->set('error', $$error);
eval {
$output .= $context->process($handler);
};
if ($@) {
$$error = $@;
return undef; ## RETURN
}
return $output;
}
sub _dump {
my $self = shift;
my $context = $self->{ CONTEXT }->_dump();
$context =~ s/\n/\n /gm;
my $error = $self->{ ERROR };
$error = join('',
"{\n",
(map { " $_ => $error->{ $_ }\n" }
keys %$error),
"}\n")
if ref $error;
local $" = ', ';
return <<EOF;
$self
PRE_PROCESS => [ @{ $self->{ PRE_PROCESS } } ]
POST_PROCESS => [ @{ $self->{ POST_PROCESS } } ]
ERROR => $error
CONTEXT => $context
EOF
}
1;
}
#
# Inline include of Template/Provider.pm
#
BEGIN { $INC{'Template/Provider.pm'} = 'dummy/Template/Provider.pm'; }
BEGIN {
#line 0 "Template/Provider.pm"
package Template::Provider;
use strict;
use warnings;
use base 'Template::Base';
use Template::Config;
use Template::Constants;
use Template::Document;
use File::Basename;
use File::Spec;
use constant PREV => 0;
use constant NAME => 1; # template name -- indexed by this name in LOOKUP
use constant DATA => 2; # Compiled template
use constant LOAD => 3; # mtime of template
use constant NEXT => 4; # link to next item in cache linked list
use constant STAT => 5; # Time last stat()ed
our $VERSION = 2.94;
our $DEBUG = 0 unless defined $DEBUG;
our $ERROR = '';
our $DOCUMENT = 'Template::Document' unless defined $DOCUMENT;
our $STAT_TTL = 1 unless defined $STAT_TTL;
our $MAX_DIRS = 64 unless defined $MAX_DIRS;
our $UNICODE = $] > 5.007 ? 1 : 0;
my $boms = [
'UTF-8' => "\x{ef}\x{bb}\x{bf}",
'UTF-32BE' => "\x{0}\x{0}\x{fe}\x{ff}",
'UTF-32LE' => "\x{ff}\x{fe}\x{0}\x{0}",
'UTF-16BE' => "\x{fe}\x{ff}",
'UTF-16LE' => "\x{ff}\x{fe}",
];
our $RELATIVE_PATH = qr[(?:^|/)\.+/];
BEGIN {
if ($] < 5.006) {
package bytes;
$INC{'bytes.pm'} = 1;
}
}
sub fetch {
my ($self, $name) = @_;
my ($data, $error);
if (ref $name) {
# $name can be a reference to a scalar, GLOB or file handle
($data, $error) = $self->_load($name);
($data, $error) = $self->_compile($data)
unless $error;
$data = $data->{ data }
unless $error;
}
elsif (File::Spec->file_name_is_absolute($name)) {
# absolute paths (starting '/') allowed if ABSOLUTE set
($data, $error) = $self->{ ABSOLUTE }
? $self->_fetch($name)
: $self->{ TOLERANT }
? (undef, Template::Constants::STATUS_DECLINED)
: ("$name: absolute paths are not allowed (set ABSOLUTE option)",
Template::Constants::STATUS_ERROR);
}
elsif ($name =~ m/$RELATIVE_PATH/o) {
# anything starting "./" is relative to cwd, allowed if RELATIVE set
($data, $error) = $self->{ RELATIVE }
? $self->_fetch($name)
: $self->{ TOLERANT }
? (undef, Template::Constants::STATUS_DECLINED)
: ("$name: relative paths are not allowed (set RELATIVE option)",
Template::Constants::STATUS_ERROR);
}
else {
# otherwise, it's a file name relative to INCLUDE_PATH
($data, $error) = $self->{ INCLUDE_PATH }
? $self->_fetch_path($name)
: (undef, Template::Constants::STATUS_DECLINED);
}
return ($data, $error);
}
sub store {
my ($self, $name, $data) = @_;
$self->_store($name, {
data => $data,
load => 0,
});
}
sub load {
my ($self, $name) = @_;
my ($data, $error);
my $path = $name;
if (File::Spec->file_name_is_absolute($name)) {
# absolute paths (starting '/') allowed if ABSOLUTE set
$error = "$name: absolute paths are not allowed (set ABSOLUTE option)"
unless $self->{ ABSOLUTE };
}
elsif ($name =~ m[$RELATIVE_PATH]o) {
# anything starting "./" is relative to cwd, allowed if RELATIVE set
$error = "$name: relative paths are not allowed (set RELATIVE option)"
unless $self->{ RELATIVE };
}
else {
INCPATH: {
# otherwise, it's a file name relative to INCLUDE_PATH
my $paths = $self->paths()
|| return ($self->error(), Template::Constants::STATUS_ERROR);
foreach my $dir (@$paths) {
$path = File::Spec->catfile($dir, $name);
last INCPATH
if $self->_template_modified($path);
}
undef $path; # not found
}
}
# Now fetch the content
($data, $error) = $self->_template_content($path)
if defined $path && !$error;
if ($error) {
return $self->{ TOLERANT }
? (undef, Template::Constants::STATUS_DECLINED)
: ($error, Template::Constants::STATUS_ERROR);
}
elsif (! defined $path) {
return (undef, Template::Constants::STATUS_DECLINED);
}
else {
return ($data, Template::Constants::STATUS_OK);
}
}
sub include_path {
my ($self, $path) = @_;
$self->{ INCLUDE_PATH } = $path if $path;
return $self->{ INCLUDE_PATH };
}
sub paths {
my $self = shift;
my @ipaths = @{ $self->{ INCLUDE_PATH } };
my (@opaths, $dpaths, $dir);
my $count = $MAX_DIRS;
while (@ipaths && --$count) {
$dir = shift @ipaths || next;
# $dir can be a sub or object ref which returns a reference
# to a dynamically generated list of search paths.
if (ref $dir eq 'CODE') {
eval { $dpaths = &$dir() };
if ($@) {
chomp $@;
return $self->error($@);
}
unshift(@ipaths, @$dpaths);
next;
}
elsif (ref($dir) && UNIVERSAL::can($dir, 'paths')) {
$dpaths = $dir->paths()
|| return $self->error($dir->error());
unshift(@ipaths, @$dpaths);
next;
}
else {
push(@opaths, $dir);
}
}
return $self->error("INCLUDE_PATH exceeds $MAX_DIRS directories")
if @ipaths;
return \@opaths;
}
sub DESTROY {
my $self = shift;
my ($slot, $next);
$slot = $self->{ HEAD };
while ($slot) {
$next = $slot->[ NEXT ];
undef $slot->[ PREV ];
undef $slot->[ NEXT ];
$slot = $next;
}
undef $self->{ HEAD };
undef $self->{ TAIL };
}
sub _init {
my ($self, $params) = @_;
my $size = $params->{ CACHE_SIZE };
my $path = $params->{ INCLUDE_PATH } || '.';
my $cdir = $params->{ COMPILE_DIR } || '';
my $dlim = $params->{ DELIMITER };
my $debug;
# tweak delim to ignore C:/
unless (defined $dlim) {
$dlim = ($^O eq 'MSWin32') ? ':(?!\\/)' : ':';
}
# coerce INCLUDE_PATH to an array ref, if not already so
$path = [ split(/$dlim/, $path) ]
unless ref $path eq 'ARRAY';
# don't allow a CACHE_SIZE 1 because it breaks things and the
# additional checking isn't worth it
$size = 2
if defined $size && ($size == 1 || $size < 0);
if (defined ($debug = $params->{ DEBUG })) {
$self->{ DEBUG } = $debug & ( Template::Constants::DEBUG_PROVIDER
| Template::Constants::DEBUG_FLAGS );
}
else {
$self->{ DEBUG } = $DEBUG;
}
if ($self->{ DEBUG }) {
local $" = ', ';
$self->debug("creating cache of ",
defined $size ? $size : 'unlimited',
" slots for [ @$path ]");
}
# create COMPILE_DIR and sub-directories representing each INCLUDE_PATH
# element in which to store compiled files
if ($cdir) {
require File::Path;
foreach my $dir (@$path) {
next if ref $dir;
my $wdir = $dir;
$wdir =~ s[:][]g if $^O eq 'MSWin32';
$wdir =~ /(.*)/; # untaint
$wdir = "$1"; # quotes work around bug in Strawberry Perl
$wdir = File::Spec->catfile($cdir, $wdir);
File::Path::mkpath($wdir) unless -d $wdir;
}
}
$self->{ LOOKUP } = { };
$self->{ NOTFOUND } = { }; # Tracks templates *not* found.
$self->{ SLOTS } = 0;
$self->{ SIZE } = $size;
$self->{ INCLUDE_PATH } = $path;
$self->{ DELIMITER } = $dlim;
$self->{ COMPILE_DIR } = $cdir;
$self->{ COMPILE_EXT } = $params->{ COMPILE_EXT } || '';
$self->{ ABSOLUTE } = $params->{ ABSOLUTE } || 0;
$self->{ RELATIVE } = $params->{ RELATIVE } || 0;
$self->{ TOLERANT } = $params->{ TOLERANT } || 0;
$self->{ DOCUMENT } = $params->{ DOCUMENT } || $DOCUMENT;
$self->{ PARSER } = $params->{ PARSER };
$self->{ DEFAULT } = $params->{ DEFAULT };
$self->{ ENCODING } = $params->{ ENCODING };
$self->{ STAT_TTL } = $params->{ STAT_TTL } || $STAT_TTL;
$self->{ PARAMS } = $params;
# look for user-provided UNICODE parameter or use default from package var
$self->{ UNICODE } = defined $params->{ UNICODE }
? $params->{ UNICODE } : $UNICODE;
return $self;
}
sub _fetch {
my ($self, $name, $t_name) = @_;
my $stat_ttl = $self->{ STAT_TTL };
$self->debug("_fetch($name)") if $self->{ DEBUG };
# First see if the named template is in the memory cache
if ((my $slot = $self->{ LOOKUP }->{ $name })) {
# Test if cache is fresh, and reload/compile if not.
my ($data, $error) = $self->_refresh($slot);
return $error
? ( $data, $error ) # $data may contain error text
: $slot->[ DATA ]; # returned document object
}
# Otherwise, see if we already know the template is not found
if (my $last_stat_time = $self->{ NOTFOUND }->{ $name }) {
my $expires_in = $last_stat_time + $stat_ttl - time;
if ($expires_in > 0) {
$self->debug(" file [$name] in negative cache. Expires in $expires_in seconds")
if $self->{ DEBUG };
return (undef, Template::Constants::STATUS_DECLINED);
}
else {
delete $self->{ NOTFOUND }->{ $name };
}
}
# Is there an up-to-date compiled version on disk?
if ($self->_compiled_is_current($name)) {
# require() the compiled template.
my $compiled_template = $self->_load_compiled( $self->_compiled_filename($name) );
# Store and return the compiled template
return $self->store( $name, $compiled_template ) if $compiled_template;
# Problem loading compiled template:
# warn and continue to fetch source template
warn($self->error(), "\n");
}
# load template from source
my ($template, $error) = $self->_load($name, $t_name);
if ($error) {
# Template could not be fetched. Add to the negative/notfound cache.
$self->{ NOTFOUND }->{ $name } = time;
return ( $template, $error );
}
# compile template source
($template, $error) = $self->_compile($template, $self->_compiled_filename($name) );
if ($error) {
# return any compile time error
return ($template, $error);
}
else {
# Store compiled template and return it
return $self->store($name, $template->{data}) ;
}
}
sub _fetch_path {
my ($self, $name) = @_;
$self->debug("_fetch_path($name)") if $self->{ DEBUG };
# the template may have been stored using a non-filename name
# so look for the plain name in the cache first
if ((my $slot = $self->{ LOOKUP }->{ $name })) {
# cached entry exists, so refresh slot and extract data
my ($data, $error) = $self->_refresh($slot);
return $error
? ($data, $error)
: ($slot->[ DATA ], $error );
}
my $paths = $self->paths
|| return ( $self->error, Template::Constants::STATUS_ERROR );
# search the INCLUDE_PATH for the file, in cache or on disk
foreach my $dir (@$paths) {
my $path = File::Spec->catfile($dir, $name);
$self->debug("searching path: $path\n") if $self->{ DEBUG };
my ($data, $error) = $self->_fetch( $path, $name );
# Return if no error or if a serious error.
return ( $data, $error )
if !$error || $error == Template::Constants::STATUS_ERROR;
}
# not found in INCLUDE_PATH, now try DEFAULT
return $self->_fetch_path( $self->{DEFAULT} )
if defined $self->{DEFAULT} && $name ne $self->{DEFAULT};
# We could not handle this template name
return (undef, Template::Constants::STATUS_DECLINED);
}
sub _compiled_filename {
my ($self, $file) = @_;
my ($compext, $compdir) = @$self{ qw( COMPILE_EXT COMPILE_DIR ) };
my ($path, $compiled);
return undef
unless $compext || $compdir;
$path = $file;
$path =~ /^(.+)$/s or die "invalid filename: $path";
$path =~ s[:][]g if $^O eq 'MSWin32';
$compiled = "$path$compext";
$compiled = File::Spec->catfile($compdir, $compiled) if length $compdir;
return $compiled;
}
sub _load_compiled {
my ($self, $file) = @_;
my $compiled;
# load compiled template via require(); we zap any
# %INC entry to ensure it is reloaded (we don't
# want 1 returned by require() to say it's in memory)
delete $INC{ $file };
eval { $compiled = require $file; };
return $@
? $self->error("compiled template $compiled: $@")
: $compiled;
}
sub _load {
my ($self, $name, $alias) = @_;
my ($data, $error);
my $tolerant = $self->{ TOLERANT };
my $now = time;
$alias = $name unless defined $alias or ref $name;
$self->debug("_load($name, ", defined $alias ? $alias : '<no alias>',
')') if $self->{ DEBUG };
# SCALAR ref is the template text
if (ref $name eq 'SCALAR') {
# $name can be a SCALAR reference to the input text...
return {
name => defined $alias ? $alias : 'input text',
path => defined $alias ? $alias : 'input text',
text => $$name,
time => $now,
load => 0,
};
}
# Otherwise, assume GLOB as a file handle
if (ref $name) {
local $/;
my $text = <$name>;
$text = $self->_decode_unicode($text) if $self->{ UNICODE };
return {
name => defined $alias ? $alias : 'input file handle',
path => defined $alias ? $alias : 'input file handle',
text => $text,
time => $now,
load => 0,
};
}
# Otherwise, it's the name of the template
if ( $self->_template_modified( $name ) ) { # does template exist?
my ($text, $error, $mtime ) = $self->_template_content( $name );
unless ( $error ) {
$text = $self->_decode_unicode($text) if $self->{ UNICODE };
return {
name => $alias,
path => $name,
text => $text,
time => $mtime,
load => $now,
};
}
return ( "$alias: $!", Template::Constants::STATUS_ERROR )
unless $tolerant;
}
# Unable to process template, pass onto the next Provider.
return (undef, Template::Constants::STATUS_DECLINED);
}
sub _refresh {
my ($self, $slot) = @_;
my $stat_ttl = $self->{ STAT_TTL };
my ($head, $file, $data, $error);
$self->debug("_refresh([ ",
join(', ', map { defined $_ ? $_ : '<undef>' } @$slot),
'])') if $self->{ DEBUG };
# if it's more than $STAT_TTL seconds since we last performed a
# stat() on the file then we need to do it again and see if the file
# time has changed
my $now = time;
my $expires_in_sec = $slot->[ STAT ] + $stat_ttl - $now;
if ( $expires_in_sec <= 0 ) { # Time to check!
$slot->[ STAT ] = $now;
# Grab mtime of template.
# Seems like this should be abstracted to compare to
# just ask for a newer compiled template (if it's newer)
# and let that check for a newer template source.
my $template_mtime = $self->_template_modified( $slot->[ NAME ] );
if ( ! defined $template_mtime || ( $template_mtime != $slot->[ LOAD ] )) {
$self->debug("refreshing cache file ", $slot->[ NAME ])
if $self->{ DEBUG };
($data, $error) = $self->_load($slot->[ NAME ], $slot->[ DATA ]->{ name });
($data, $error) = $self->_compile($data)
unless $error;
if ($error) {
# if the template failed to load/compile then we wipe out the
# STAT entry. This forces the provider to try and reload it
# each time instead of using the previously cached version
# until $STAT_TTL is next up
$slot->[ STAT ] = 0;
}
else {
$slot->[ DATA ] = $data->{ data };
$slot->[ LOAD ] = $data->{ time };
}
}
} elsif ( $self->{ DEBUG } ) {
$self->debug( sprintf('STAT_TTL not met for file [%s]. Expires in %d seconds',
$slot->[ NAME ], $expires_in_sec ) );
}
# Move this slot to the head of the list
unless( $self->{ HEAD } == $slot ) {
# remove existing slot from usage chain...
if ($slot->[ PREV ]) {
$slot->[ PREV ]->[ NEXT ] = $slot->[ NEXT ];
}
else {
$self->{ HEAD } = $slot->[ NEXT ];
}
if ($slot->[ NEXT ]) {
$slot->[ NEXT ]->[ PREV ] = $slot->[ PREV ];
}
else {
$self->{ TAIL } = $slot->[ PREV ];
}
# ..and add to start of list
$head = $self->{ HEAD };
$head->[ PREV ] = $slot if $head;
$slot->[ PREV ] = undef;
$slot->[ NEXT ] = $head;
$self->{ HEAD } = $slot;
}
return ($data, $error);
}
sub _store {
my ($self, $name, $data, $compfile) = @_;
my $size = $self->{ SIZE };
my ($slot, $head);
# Return if memory cache disabled. (overridding code should also check)
# $$$ What's the expected behaviour of store()? Can't tell from the
# docs if you can call store() when SIZE = 0.
return $data->{data} if defined $size and !$size;
# extract the compiled template from the data hash
$data = $data->{ data };
$self->debug("_store($name, $data)") if $self->{ DEBUG };
# check the modification time -- extra stat here
my $load = $self->_modified($name);
if (defined $size && $self->{ SLOTS } >= $size) {
# cache has reached size limit, so reuse oldest entry
$self->debug("reusing oldest cache entry (size limit reached: $size)\nslots: $self->{ SLOTS }") if $self->{ DEBUG };
# remove entry from tail of list
$slot = $self->{ TAIL };
$slot->[ PREV ]->[ NEXT ] = undef;
$self->{ TAIL } = $slot->[ PREV ];
# remove name lookup for old node
delete $self->{ LOOKUP }->{ $slot->[ NAME ] };
# add modified node to head of list
$head = $self->{ HEAD };
$head->[ PREV ] = $slot if $head;
@$slot = ( undef, $name, $data, $load, $head, time );
$self->{ HEAD } = $slot;
# add name lookup for new node
$self->{ LOOKUP }->{ $name } = $slot;
}
else {
# cache is under size limit, or none is defined
$self->debug("adding new cache entry") if $self->{ DEBUG };
# add new node to head of list
$head = $self->{ HEAD };
$slot = [ undef, $name, $data, $load, $head, time ];
$head->[ PREV ] = $slot if $head;
$self->{ HEAD } = $slot;
$self->{ TAIL } = $slot unless $self->{ TAIL };
# add lookup from name to slot and increment nslots
$self->{ LOOKUP }->{ $name } = $slot;
$self->{ SLOTS }++;
}
return $data;
}
sub _compile {
my ($self, $data, $compfile) = @_;
my $text = $data->{ text };
my ($parsedoc, $error);
$self->debug("_compile($data, ",
defined $compfile ? $compfile : '<no compfile>', ')')
if $self->{ DEBUG };
my $parser = $self->{ PARSER }
||= Template::Config->parser($self->{ PARAMS })
|| return (Template::Config->error(), Template::Constants::STATUS_ERROR);
# discard the template text - we don't need it any more
delete $data->{ text };
# call parser to compile template into Perl code
if ($parsedoc = $parser->parse($text, $data)) {
$parsedoc->{ METADATA } = {
'name' => $data->{ name },
'modtime' => $data->{ time },
%{ $parsedoc->{ METADATA } },
};
# write the Perl code to the file $compfile, if defined
if ($compfile) {
my $basedir = &File::Basename::dirname($compfile);
$basedir =~ /(.*)/;
$basedir = $1;
unless (-d $basedir) {
eval { File::Path::mkpath($basedir) };
$error = "failed to create compiled templates directory: $basedir ($@)"
if ($@);
}
unless ($error) {
my $docclass = $self->{ DOCUMENT };
$error = 'cache failed to write '
. &File::Basename::basename($compfile)
. ': ' . $docclass->error()
unless $docclass->write_perl_file($compfile, $parsedoc);
}
# set atime and mtime of newly compiled file, don't bother
# if time is undef
if (!defined($error) && defined $data->{ time }) {
my ($cfile) = $compfile =~ /^(.+)$/s or do {
return("invalid filename: $compfile",
Template::Constants::STATUS_ERROR);
};
my ($ctime) = $data->{ time } =~ /^(\d+)$/;
unless ($ctime || $ctime eq 0) {
return("invalid time: $ctime",
Template::Constants::STATUS_ERROR);
}
utime($ctime, $ctime, $cfile);
$self->debug(" cached compiled template to file [$compfile]")
if $self->{ DEBUG };
}
}
unless ($error) {
return $data ## RETURN ##
if $data->{ data } = $DOCUMENT->new($parsedoc);
$error = $Template::Document::ERROR;
}
}
else {
$error = Template::Exception->new( 'parse', "$data->{ name } " .
$parser->error() );
}
# return STATUS_ERROR, or STATUS_DECLINED if we're being tolerant
return $self->{ TOLERANT }
? (undef, Template::Constants::STATUS_DECLINED)
: ($error, Template::Constants::STATUS_ERROR)
}
sub _compiled_is_current {
my ( $self, $template_name ) = @_;
my $compiled_name = $self->_compiled_filename($template_name) || return;
my $compiled_mtime = (stat($compiled_name))[9] || return;
my $template_mtime = $self->_template_modified( $template_name ) || return;
# This was >= in the 2.15, but meant that downgrading
# a source template would not get picked up.
return $compiled_mtime == $template_mtime;
}
sub _template_modified {
my $self = shift;
my $template = shift || return;
return (stat( $template ))[9];
}
sub _template_content {
my ($self, $path) = @_;
return (undef, "No path specified to fetch content from ")
unless $path;
my $data;
my $mod_date;
my $error;
local *FH;
if (open(FH, "< $path")) {
local $/;
binmode(FH);
$data = <FH>;
$mod_date = (stat($path))[9];
close(FH);
}
else {
$error = "$path: $!";
}
return wantarray
? ( $data, $error, $mod_date )
: $data;
}
sub _modified {
my ($self, $name, $time) = @_;
my $load = $self->_template_modified($name)
|| return $time ? 1 : 0;
return $time
? $load > $time
: $load;
}
sub _dump {
my $self = shift;
my $size = $self->{ SIZE };
my $parser = $self->{ PARSER };
$parser = $parser ? $parser->_dump() : '<no parser>';
$parser =~ s/\n/\n /gm;
$size = 'unlimited' unless defined $size;
my $output = "[Template::Provider] {\n";
my $format = " %-16s => %s\n";
my $key;
$output .= sprintf($format, 'INCLUDE_PATH',
'[ ' . join(', ', @{ $self->{ INCLUDE_PATH } }) . ' ]');
$output .= sprintf($format, 'CACHE_SIZE', $size);
foreach $key (qw( ABSOLUTE RELATIVE TOLERANT DELIMITER
COMPILE_EXT COMPILE_DIR )) {
$output .= sprintf($format, $key, $self->{ $key });
}
$output .= sprintf($format, 'PARSER', $parser);
local $" = ', ';
my $lookup = $self->{ LOOKUP };
$lookup = join('', map {
sprintf(" $format", $_, defined $lookup->{ $_ }
? ('[ ' . join(', ', map { defined $_ ? $_ : '<undef>' }
@{ $lookup->{ $_ } }) . ' ]') : '<undef>');
} sort keys %$lookup);
$lookup = "{\n$lookup }";
$output .= sprintf($format, LOOKUP => $lookup);
$output .= '}';
return $output;
}
sub _dump_cache {
my $self = shift;
my ($node, $lut, $count);
$count = 0;
if ($node = $self->{ HEAD }) {
while ($node) {
$lut->{ $node } = $count++;
$node = $node->[ NEXT ];
}
$node = $self->{ HEAD };
print STDERR "CACHE STATE:\n";
print STDERR " HEAD: ", $self->{ HEAD }->[ NAME ], "\n";
print STDERR " TAIL: ", $self->{ TAIL }->[ NAME ], "\n";
while ($node) {
my ($prev, $name, $data, $load, $next) = @$node;
$prev = $prev ? "#$lut->{ $prev }<-": '<undef>';
$next = $next ? "->#$lut->{ $next }": '<undef>';
print STDERR " #$lut->{ $node } : [ $prev, $name, $data, $load, $next ]\n";
$node = $node->[ NEXT ];
}
}
}
sub _decode_unicode {
my $self = shift;
my $string = shift;
return undef unless defined $string;
use bytes;
require Encode;
return $string if Encode::is_utf8( $string );
# try all the BOMs in order looking for one (order is important
# 32bit BOMs look like 16bit BOMs)
my $count = 0;
while ($count < @{ $boms }) {
my $enc = $boms->[$count++];
my $bom = $boms->[$count++];
# does the string start with the bom?
if ($bom eq substr($string, 0, length($bom))) {
# decode it and hand it back
return Encode::decode($enc, substr($string, length($bom)), 1);
}
}
return $self->{ ENCODING }
? Encode::decode( $self->{ ENCODING }, $string )
: $string;
}
1;
}
#
# Inline include of Template.pm
#
BEGIN { $INC{'Template.pm'} = 'dummy/Template.pm'; }
BEGIN {
#line 0 "Template.pm"
package Template;
use strict;
use warnings;
use 5.006;
use base 'Template::Base';
use Template::Config;
use Template::Constants;
use Template::Provider;
use Template::Service;
use File::Basename;
use File::Path;
use Scalar::Util qw(blessed);
our $VERSION = '2.22';
our $ERROR = '';
our $DEBUG = 0;
our $BINMODE = 0 unless defined $BINMODE;
our $AUTOLOAD;
Template::Config->preload() if $ENV{ MOD_PERL };
sub process {
my ($self, $template, $vars, $outstream, @opts) = @_;
my ($output, $error);
my $options = (@opts == 1) && ref($opts[0]) eq 'HASH'
? shift(@opts) : { @opts };
$options->{ binmode } = $BINMODE
unless defined $options->{ binmode };
# we're using this for testing in t/output.t and t/filter.t so
# don't remove it if you don't want tests to fail...
$self->DEBUG("set binmode\n") if $DEBUG && $options->{ binmode };
$output = $self->{ SERVICE }->process($template, $vars);
if (defined $output) {
$outstream ||= $self->{ OUTPUT };
unless (ref $outstream) {
my $outpath = $self->{ OUTPUT_PATH };
$outstream = "$outpath/$outstream" if $outpath;
}
# send processed template to output stream, checking for error
return ($self->error($error))
if ($error = &_output($outstream, \$output, $options));
return 1;
}
else {
return $self->error($self->{ SERVICE }->error);
}
}
sub service {
my $self = shift;
return $self->{ SERVICE };
}
sub context {
my $self = shift;
return $self->{ SERVICE }->{ CONTEXT };
}
sub _init {
my ($self, $config) = @_;
# convert any textual DEBUG args to numerical form
my $debug = $config->{ DEBUG };
$config->{ DEBUG } = Template::Constants::debug_flags($self, $debug)
|| return if defined $debug && $debug !~ /^\d+$/;
# prepare a namespace handler for any CONSTANTS definition
if (my $constants = $config->{ CONSTANTS }) {
my $ns = $config->{ NAMESPACE } ||= { };
my $cns = $config->{ CONSTANTS_NAMESPACE } || 'constants';
$constants = Template::Config->constants($constants)
|| return $self->error(Template::Config->error);
$ns->{ $cns } = $constants;
}
$self->{ SERVICE } = $config->{ SERVICE }
|| Template::Config->service($config)
|| return $self->error(Template::Config->error);
$self->{ OUTPUT } = $config->{ OUTPUT } || \*STDOUT;
$self->{ OUTPUT_PATH } = $config->{ OUTPUT_PATH };
return $self;
}
sub _output {
my ($where, $textref, $options) = @_;
my $reftype;
my $error = 0;
# call a CODE reference
if (($reftype = ref($where)) eq 'CODE') {
&$where($$textref);
}
# print to a glob (such as \*STDOUT)
elsif ($reftype eq 'GLOB') {
print $where $$textref;
}
# append output to a SCALAR ref
elsif ($reftype eq 'SCALAR') {
$$where .= $$textref;
}
# push onto ARRAY ref
elsif ($reftype eq 'ARRAY') {
push @$where, $$textref;
}
# call the print() method on an object that implements the method
# (e.g. IO::Handle, Apache::Request, etc)
elsif (blessed($where) && $where->can('print')) {
$where->print($$textref);
}
# a simple string is taken as a filename
elsif (! $reftype) {
local *FP;
# make destination directory if it doesn't exist
my $dir = dirname($where);
eval { mkpath($dir) unless -d $dir; };
if ($@) {
# strip file name and line number from error raised by die()
($error = $@) =~ s/ at \S+ line \d+\n?$//;
}
elsif (open(FP, ">$where")) {
# binmode option can be 1 or a specific layer, e.g. :utf8
my $bm = $options->{ binmode };
if ($bm && $bm eq 1) {
binmode FP;
}
elsif ($bm){
binmode FP, $bm;
}
print FP $$textref;
close FP;
}
else {
$error = "$where: $!";
}
}
# give up, we've done our best
else {
$error = "output_handler() cannot determine target type ($where)\n";
}
return $error;
}
1;
}
#
# Inline include of Template/Grammar.pm
#
BEGIN { $INC{'Template/Grammar.pm'} = 'dummy/Template/Grammar.pm'; }
BEGIN {
#line 0 "Template/Grammar.pm"
package Template::Grammar;
use strict;
use warnings;
our $VERSION = 2.25;
my (@RESERVED, %CMPOP, $LEXTABLE, $RULES, $STATES);
my ($factory, $rawstart);
@RESERVED = qw(
GET CALL SET DEFAULT INSERT INCLUDE PROCESS WRAPPER BLOCK END
USE PLUGIN FILTER MACRO PERL RAWPERL TO STEP AND OR NOT DIV MOD
IF UNLESS ELSE ELSIF FOR NEXT WHILE SWITCH CASE META IN
TRY THROW CATCH FINAL LAST RETURN STOP CLEAR VIEW DEBUG
);
%CMPOP = qw(
!= ne
== eq
< <
> >
>= >=
<= <=
);
$LEXTABLE = {
'FOREACH' => 'FOR',
'BREAK' => 'LAST',
'&&' => 'AND',
'||' => 'OR',
'!' => 'NOT',
'|' => 'FILTER',
'.' => 'DOT',
'_' => 'CAT',
'..' => 'TO',
'=' => 'ASSIGN',
'=>' => 'ASSIGN',
',' => 'COMMA',
'\\' => 'REF',
'and' => 'AND', # explicitly specified so that qw( and or
'or' => 'OR', # not ) can always be used in lower case,
'not' => 'NOT', # regardless of ANYCASE flag
'mod' => 'MOD',
'div' => 'DIV',
};
{
my @tokens = qw< ( ) [ ] { } ${ $ + / ; : ? >;
my @cmpop = keys %CMPOP;
my @binop = qw( - * % ); # '+' and '/' above, in @tokens
# fill lexer table, slice by slice, with reserved words and operators
@$LEXTABLE{ @RESERVED, @cmpop, @binop, @tokens }
= ( @RESERVED, ('CMPOP') x @cmpop, ('BINOP') x @binop, @tokens );
}
sub new {
my $class = shift;
bless {
LEXTABLE => $LEXTABLE,
STATES => $STATES,
RULES => $RULES,
}, $class;
}
sub install_factory {
my ($self, $new_factory) = @_;
$factory = $new_factory;
}
$STATES = [
{#State 0
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'loop' => 4,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'atomdir' => 12,
'anonblock' => 50,
'template' => 52,
'defblockname' => 14,
'ident' => 16,
'assign' => 19,
'macro' => 20,
'lterm' => 56,
'node' => 23,
'term' => 58,
'rawperl' => 59,
'expr' => 62,
'use' => 63,
'defblock' => 66,
'filter' => 29,
'sterm' => 68,
'perl' => 31,
'chunks' => 33,
'setlist' => 70,
'try' => 35,
'switch' => 34,
'directive' => 71,
'block' => 72,
'condition' => 73
}
},
{#State 1
ACTIONS => {
"\$" => 43,
'LITERAL' => 75,
'IDENT' => 2,
"\${" => 37
},
GOTOS => {
'setlist' => 76,
'item' => 39,
'assign' => 19,
'node' => 23,
'ident' => 74
}
},
{#State 2
DEFAULT => -130
},
{#State 3
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 79,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 4
DEFAULT => -23
},
{#State 5
ACTIONS => {
";" => 80
}
},
{#State 6
DEFAULT => -37
},
{#State 7
DEFAULT => -14
},
{#State 8
ACTIONS => {
"\"" => 89,
"\$" => 86,
'LITERAL' => 88,
'FILENAME' => 83,
'IDENT' => 81,
'NUMBER' => 84
},
GOTOS => {
'filepart' => 87,
'names' => 91,
'nameargs' => 90,
'filename' => 85,
'name' => 82
}
},
{#State 9
ACTIONS => {
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"]" => 94,
"\${" => 37
},
GOTOS => {
'sterm' => 96,
'item' => 39,
'range' => 93,
'node' => 23,
'ident' => 77,
'term' => 95,
'lterm' => 56,
'list' => 92
}
},
{#State 10
ACTIONS => {
";" => 97
}
},
{#State 11
DEFAULT => -5
},
{#State 12
ACTIONS => {
";" => -20
},
DEFAULT => -27
},
{#State 13
DEFAULT => -78,
GOTOS => {
'@5-1' => 98
}
},
{#State 14
ACTIONS => {
'IDENT' => 99
},
DEFAULT => -87,
GOTOS => {
'blockargs' => 102,
'metadata' => 101,
'meta' => 100
}
},
{#State 15
ACTIONS => {
'IDENT' => 99
},
GOTOS => {
'metadata' => 103,
'meta' => 100
}
},
{#State 16
ACTIONS => {
'DOT' => 104,
'ASSIGN' => 105
},
DEFAULT => -109
},
{#State 17
ACTIONS => {
"\"" => 89,
"\$" => 86,
'LITERAL' => 88,
'FILENAME' => 83,
'IDENT' => 81,
'NUMBER' => 84
},
GOTOS => {
'filepart' => 87,
'names' => 91,
'nameargs' => 106,
'filename' => 85,
'name' => 82
}
},
{#State 18
ACTIONS => {
'IDENT' => 107
}
},
{#State 19
DEFAULT => -149
},
{#State 20
DEFAULT => -12
},
{#State 21
ACTIONS => {
"{" => 30,
'LITERAL' => 78,
'IDENT' => 108,
"\"" => 60,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'sterm' => 68,
'item' => 39,
'loopvar' => 110,
'node' => 23,
'ident' => 77,
'term' => 109,
'lterm' => 56
}
},
{#State 22
DEFAULT => -40
},
{#State 23
DEFAULT => -127
},
{#State 24
DEFAULT => -6
},
{#State 25
ACTIONS => {
"\"" => 117,
"\$" => 114,
'LITERAL' => 116,
'FILENAME' => 83,
'IDENT' => 111,
'NUMBER' => 84,
"\${" => 37
},
GOTOS => {
'names' => 91,
'lvalue' => 112,
'item' => 113,
'name' => 82,
'filepart' => 87,
'filename' => 85,
'nameargs' => 118,
'lnameargs' => 115
}
},
{#State 26
DEFAULT => -113
},
{#State 27
ACTIONS => {
"\$" => 43,
'IDENT' => 2,
"\${" => 37
},
GOTOS => {
'item' => 39,
'node' => 23,
'ident' => 119
}
},
{#State 28
ACTIONS => {
'LITERAL' => 124,
'FILENAME' => 83,
'IDENT' => 120,
'NUMBER' => 84
},
DEFAULT => -87,
GOTOS => {
'blockargs' => 123,
'filepart' => 87,
'filename' => 122,
'blockname' => 121,
'metadata' => 101,
'meta' => 100
}
},
{#State 29
DEFAULT => -43
},
{#State 30
ACTIONS => {
"\$" => 43,
'LITERAL' => 129,
'IDENT' => 2,
"\${" => 37
},
DEFAULT => -119,
GOTOS => {
'params' => 128,
'hash' => 125,
'item' => 126,
'param' => 127
}
},
{#State 31
DEFAULT => -25
},
{#State 32
ACTIONS => {
"\"" => 117,
"\$" => 114,
'LITERAL' => 116,
'FILENAME' => 83,
'IDENT' => 111,
'NUMBER' => 84,
"\${" => 37
},
GOTOS => {
'names' => 91,
'lvalue' => 112,
'item' => 113,
'name' => 82,
'filepart' => 87,
'filename' => 85,
'nameargs' => 118,
'lnameargs' => 130
}
},
{#State 33
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -2,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 131,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'try' => 35,
'switch' => 34,
'assign' => 19,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 34
DEFAULT => -22
},
{#State 35
DEFAULT => -24
},
{#State 36
ACTIONS => {
"\"" => 89,
"\$" => 86,
'LITERAL' => 88,
'FILENAME' => 83,
'IDENT' => 81,
'NUMBER' => 84
},
GOTOS => {
'filepart' => 87,
'names' => 91,
'nameargs' => 132,
'filename' => 85,
'name' => 82
}
},
{#State 37
ACTIONS => {
"\"" => 60,
"\$" => 43,
'LITERAL' => 78,
'IDENT' => 2,
'REF' => 27,
'NUMBER' => 26,
"\${" => 37
},
GOTOS => {
'sterm' => 133,
'item' => 39,
'node' => 23,
'ident' => 77
}
},
{#State 38
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 134,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 39
ACTIONS => {
"(" => 135
},
DEFAULT => -128
},
{#State 40
ACTIONS => {
";" => 136
}
},
{#State 41
DEFAULT => -38
},
{#State 42
DEFAULT => -11
},
{#State 43
ACTIONS => {
'IDENT' => 137
}
},
{#State 44
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 138,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 45
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 139,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 46
DEFAULT => -42
},
{#State 47
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 140,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 48
ACTIONS => {
'IF' => 144,
'FILTER' => 143,
'FOR' => 142,
'WHILE' => 146,
'WRAPPER' => 145,
'UNLESS' => 141
}
},
{#State 49
DEFAULT => -39
},
{#State 50
DEFAULT => -10
},
{#State 51
ACTIONS => {
"\"" => 89,
"\$" => 86,
'LITERAL' => 88,
'FILENAME' => 83,
'IDENT' => 81,
'NUMBER' => 84
},
GOTOS => {
'filepart' => 87,
'names' => 91,
'nameargs' => 147,
'filename' => 85,
'name' => 82
}
},
{#State 52
ACTIONS => {
'' => 148
}
},
{#State 53
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 57,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 151,
'sterm' => 68,
'item' => 39,
'assign' => 150,
'node' => 23,
'ident' => 149,
'term' => 58,
'lterm' => 56
}
},
{#State 54
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 152,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 55
ACTIONS => {
"\"" => 89,
"\$" => 86,
'LITERAL' => 88,
'FILENAME' => 83,
'IDENT' => 81,
'NUMBER' => 84
},
GOTOS => {
'filepart' => 87,
'names' => 91,
'nameargs' => 153,
'filename' => 85,
'name' => 82
}
},
{#State 56
DEFAULT => -103
},
{#State 57
ACTIONS => {
'ASSIGN' => 154
},
DEFAULT => -112
},
{#State 58
DEFAULT => -146
},
{#State 59
DEFAULT => -15
},
{#State 60
DEFAULT => -176,
GOTOS => {
'quoted' => 155
}
},
{#State 61
ACTIONS => {
"\"" => 89,
"\$" => 86,
'LITERAL' => 88,
'FILENAME' => 83,
'IDENT' => 81,
'NUMBER' => 84
},
GOTOS => {
'filepart' => 87,
'names' => 91,
'nameargs' => 156,
'filename' => 85,
'name' => 82
}
},
{#State 62
ACTIONS => {
";" => -16,
"+" => 157,
'CAT' => 163,
'CMPOP' => 164,
"?" => 158,
'DIV' => 159,
'MOD' => 165,
"/" => 166,
'AND' => 160,
'BINOP' => 161,
'OR' => 162
},
DEFAULT => -26
},
{#State 63
DEFAULT => -13
},
{#State 64
DEFAULT => -36
},
{#State 65
ACTIONS => {
"\"" => 89,
"\$" => 86,
'LITERAL' => 88,
'FILENAME' => 83,
'IDENT' => 81,
'NUMBER' => 84
},
GOTOS => {
'filepart' => 87,
'names' => 91,
'nameargs' => 167,
'filename' => 85,
'name' => 82
}
},
{#State 66
DEFAULT => -9
},
{#State 67
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 168,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 68
DEFAULT => -104
},
{#State 69
ACTIONS => {
"\$" => 43,
'LITERAL' => 75,
'IDENT' => 2,
"\${" => 37
},
GOTOS => {
'setlist' => 169,
'item' => 39,
'assign' => 19,
'node' => 23,
'ident' => 74
}
},
{#State 70
ACTIONS => {
"\$" => 43,
'COMMA' => 171,
'LITERAL' => 75,
'IDENT' => 2,
"\${" => 37
},
DEFAULT => -19,
GOTOS => {
'item' => 39,
'assign' => 170,
'node' => 23,
'ident' => 74
}
},
{#State 71
DEFAULT => -8
},
{#State 72
DEFAULT => -1
},
{#State 73
DEFAULT => -21
},
{#State 74
ACTIONS => {
'ASSIGN' => 172,
'DOT' => 104
}
},
{#State 75
ACTIONS => {
'ASSIGN' => 154
}
},
{#State 76
ACTIONS => {
'COMMA' => 171,
'LITERAL' => 75,
'IDENT' => 2,
"\$" => 43,
"\${" => 37
},
DEFAULT => -30,
GOTOS => {
'item' => 39,
'assign' => 170,
'node' => 23,
'ident' => 74
}
},
{#State 77
ACTIONS => {
'DOT' => 104
},
DEFAULT => -109
},
{#State 78
DEFAULT => -112
},
{#State 79
ACTIONS => {
'CMPOP' => 164,
"?" => 158,
";" => 173,
"+" => 157,
'MOD' => 165,
'DIV' => 159,
"/" => 166,
'AND' => 160,
'CAT' => 163,
'BINOP' => 161,
'OR' => 162
}
},
{#State 80
DEFAULT => -7
},
{#State 81
DEFAULT => -173
},
{#State 82
DEFAULT => -166
},
{#State 83
DEFAULT => -172
},
{#State 84
DEFAULT => -174
},
{#State 85
ACTIONS => {
'DOT' => 174
},
DEFAULT => -168
},
{#State 86
ACTIONS => {
"\$" => 43,
'IDENT' => 2,
"\${" => 37
},
GOTOS => {
'item' => 39,
'node' => 23,
'ident' => 175
}
},
{#State 87
DEFAULT => -171
},
{#State 88
DEFAULT => -169
},
{#State 89
DEFAULT => -176,
GOTOS => {
'quoted' => 176
}
},
{#State 90
DEFAULT => -35
},
{#State 91
ACTIONS => {
"+" => 177,
"(" => 178
},
DEFAULT => -156,
GOTOS => {
'args' => 179
}
},
{#State 92
ACTIONS => {
"{" => 30,
'COMMA' => 182,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"]" => 180,
"\${" => 37
},
GOTOS => {
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 181,
'lterm' => 56
}
},
{#State 93
ACTIONS => {
"]" => 183
}
},
{#State 94
DEFAULT => -107
},
{#State 95
DEFAULT => -116
},
{#State 96
ACTIONS => {
'TO' => 184
},
DEFAULT => -104
},
{#State 97
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 185,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 98
ACTIONS => {
";" => 186
}
},
{#State 99
ACTIONS => {
'ASSIGN' => 187
}
},
{#State 100
DEFAULT => -99
},
{#State 101
ACTIONS => {
'COMMA' => 189,
'IDENT' => 99
},
DEFAULT => -86,
GOTOS => {
'meta' => 188
}
},
{#State 102
ACTIONS => {
";" => 190
}
},
{#State 103
ACTIONS => {
'COMMA' => 189,
'IDENT' => 99
},
DEFAULT => -17,
GOTOS => {
'meta' => 188
}
},
{#State 104
ACTIONS => {
"\$" => 43,
'IDENT' => 2,
'NUMBER' => 192,
"\${" => 37
},
GOTOS => {
'item' => 39,
'node' => 191
}
},
{#State 105
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'WRAPPER' => 55,
'FOR' => 21,
'NEXT' => 22,
'LITERAL' => 57,
"\"" => 60,
'PROCESS' => 61,
'FILTER' => 25,
'RETURN' => 64,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 193,
'DEFAULT' => 69,
"{" => 30,
"\${" => 37
},
GOTOS => {
'item' => 39,
'node' => 23,
'term' => 58,
'loop' => 4,
'expr' => 195,
'wrapper' => 46,
'atomexpr' => 48,
'atomdir' => 12,
'mdir' => 194,
'filter' => 29,
'sterm' => 68,
'ident' => 149,
'perl' => 31,
'setlist' => 70,
'try' => 35,
'switch' => 34,
'assign' => 19,
'directive' => 196,
'condition' => 73,
'lterm' => 56
}
},
{#State 106
DEFAULT => -33
},
{#State 107
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'INCLUDE' => 17,
"(" => 198,
'SWITCH' => 54,
'WRAPPER' => 55,
'FOR' => 21,
'NEXT' => 22,
'LITERAL' => 57,
"\"" => 60,
'PROCESS' => 61,
'FILTER' => 25,
'RETURN' => 64,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 193,
'DEFAULT' => 69,
"{" => 30,
"\${" => 37
},
GOTOS => {
'item' => 39,
'node' => 23,
'term' => 58,
'loop' => 4,
'expr' => 199,
'wrapper' => 46,
'atomexpr' => 48,
'atomdir' => 12,
'mdir' => 197,
'filter' => 29,
'sterm' => 68,
'ident' => 149,
'perl' => 31,
'setlist' => 70,
'try' => 35,
'switch' => 34,
'assign' => 19,
'directive' => 196,
'condition' => 73,
'lterm' => 56
}
},
{#State 108
ACTIONS => {
'IN' => 201,
'ASSIGN' => 200
},
DEFAULT => -130
},
{#State 109
DEFAULT => -156,
GOTOS => {
'args' => 202
}
},
{#State 110
ACTIONS => {
";" => 203
}
},
{#State 111
ACTIONS => {
'ASSIGN' => -130
},
DEFAULT => -173
},
{#State 112
ACTIONS => {
'ASSIGN' => 204
}
},
{#State 113
DEFAULT => -159
},
{#State 114
ACTIONS => {
"\$" => 43,
'IDENT' => 205,
"\${" => 37
},
GOTOS => {
'item' => 39,
'node' => 23,
'ident' => 175
}
},
{#State 115
ACTIONS => {
";" => 206
}
},
{#State 116
ACTIONS => {
'ASSIGN' => -161
},
DEFAULT => -169
},
{#State 117
DEFAULT => -176,
GOTOS => {
'quoted' => 207
}
},
{#State 118
DEFAULT => -158
},
{#State 119
ACTIONS => {
'DOT' => 104
},
DEFAULT => -110
},
{#State 120
ACTIONS => {
'ASSIGN' => 187
},
DEFAULT => -173
},
{#State 121
DEFAULT => -83
},
{#State 122
ACTIONS => {
'DOT' => 174
},
DEFAULT => -84
},
{#State 123
ACTIONS => {
";" => 208
}
},
{#State 124
DEFAULT => -85
},
{#State 125
ACTIONS => {
"}" => 209
}
},
{#State 126
ACTIONS => {
'ASSIGN' => 210
}
},
{#State 127
DEFAULT => -122
},
{#State 128
ACTIONS => {
"\$" => 43,
'COMMA' => 212,
'LITERAL' => 129,
'IDENT' => 2,
"\${" => 37
},
DEFAULT => -118,
GOTOS => {
'item' => 126,
'param' => 211
}
},
{#State 129
ACTIONS => {
'ASSIGN' => 213
}
},
{#State 130
DEFAULT => -73
},
{#State 131
DEFAULT => -4
},
{#State 132
ACTIONS => {
";" => 214
}
},
{#State 133
ACTIONS => {
"}" => 215
}
},
{#State 134
ACTIONS => {
'DIV' => 159,
'BINOP' => 161,
"+" => 157,
'CAT' => 163,
'CMPOP' => 164,
'MOD' => 165,
"/" => 166
},
DEFAULT => -142
},
{#State 135
DEFAULT => -156,
GOTOS => {
'args' => 216
}
},
{#State 136
DEFAULT => -76,
GOTOS => {
'@4-2' => 217
}
},
{#State 137
DEFAULT => -132
},
{#State 138
ACTIONS => {
'CMPOP' => 164,
"?" => 158,
";" => 218,
"+" => 157,
'MOD' => 165,
'DIV' => 159,
"/" => 166,
'AND' => 160,
'CAT' => 163,
'BINOP' => 161,
'OR' => 162
}
},
{#State 139
ACTIONS => {
"+" => 157,
'CAT' => 163,
'CMPOP' => 164,
"?" => 158,
'DIV' => 159,
'MOD' => 165,
"/" => 166,
'AND' => 160,
'BINOP' => 161,
'OR' => 162
},
DEFAULT => -29
},
{#State 140
ACTIONS => {
"+" => 157,
'CAT' => 163,
'CMPOP' => 164,
"?" => 158,
'DIV' => 159,
'MOD' => 165,
"/" => 166,
'AND' => 160,
'BINOP' => 161,
'OR' => 162
},
DEFAULT => -28
},
{#State 141
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 219,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 142
ACTIONS => {
"{" => 30,
'LITERAL' => 78,
'IDENT' => 108,
"\"" => 60,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'sterm' => 68,
'item' => 39,
'loopvar' => 220,
'node' => 23,
'ident' => 77,
'term' => 109,
'lterm' => 56
}
},
{#State 143
ACTIONS => {
"\"" => 117,
"\$" => 114,
'LITERAL' => 116,
'FILENAME' => 83,
'IDENT' => 111,
'NUMBER' => 84,
"\${" => 37
},
GOTOS => {
'names' => 91,
'lvalue' => 112,
'item' => 113,
'name' => 82,
'filepart' => 87,
'filename' => 85,
'nameargs' => 118,
'lnameargs' => 221
}
},
{#State 144
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 222,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 145
ACTIONS => {
"\"" => 89,
"\$" => 86,
'LITERAL' => 88,
'FILENAME' => 83,
'IDENT' => 81,
'NUMBER' => 84
},
GOTOS => {
'filepart' => 87,
'names' => 91,
'nameargs' => 223,
'filename' => 85,
'name' => 82
}
},
{#State 146
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 224,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 147
DEFAULT => -41
},
{#State 148
DEFAULT => 0
},
{#State 149
ACTIONS => {
'DOT' => 104,
'ASSIGN' => 172
},
DEFAULT => -109
},
{#State 150
ACTIONS => {
")" => 225
}
},
{#State 151
ACTIONS => {
'CMPOP' => 164,
"?" => 158,
"+" => 157,
'MOD' => 165,
'DIV' => 159,
"/" => 166,
'AND' => 160,
'CAT' => 163,
'BINOP' => 161,
")" => 226,
'OR' => 162
}
},
{#State 152
ACTIONS => {
'CMPOP' => 164,
"?" => 158,
";" => 227,
"+" => 157,
'MOD' => 165,
'DIV' => 159,
"/" => 166,
'AND' => 160,
'CAT' => 163,
'BINOP' => 161,
'OR' => 162
}
},
{#State 153
ACTIONS => {
";" => 228
}
},
{#State 154
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 229,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 155
ACTIONS => {
"\"" => 234,
'TEXT' => 231,
";" => 233,
"\$" => 43,
'IDENT' => 2,
"\${" => 37
},
GOTOS => {
'item' => 39,
'node' => 23,
'ident' => 230,
'quotable' => 232
}
},
{#State 156
DEFAULT => -34
},
{#State 157
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 235,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 158
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 236,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 159
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 237,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 160
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 238,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 161
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 239,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 162
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 240,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 163
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 241,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 164
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 242,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 165
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 243,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 166
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 244,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 167
DEFAULT => -32
},
{#State 168
ACTIONS => {
'CMPOP' => 164,
"?" => 158,
";" => 245,
"+" => 157,
'MOD' => 165,
'DIV' => 159,
"/" => 166,
'AND' => 160,
'CAT' => 163,
'BINOP' => 161,
'OR' => 162
}
},
{#State 169
ACTIONS => {
'COMMA' => 171,
'LITERAL' => 75,
'IDENT' => 2,
"\$" => 43,
"\${" => 37
},
DEFAULT => -31,
GOTOS => {
'item' => 39,
'assign' => 170,
'node' => 23,
'ident' => 74
}
},
{#State 170
DEFAULT => -147
},
{#State 171
DEFAULT => -148
},
{#State 172
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 246,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 173
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 247,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 174
ACTIONS => {
'FILENAME' => 83,
'IDENT' => 81,
'NUMBER' => 84
},
GOTOS => {
'filepart' => 248
}
},
{#State 175
ACTIONS => {
'DOT' => 104
},
DEFAULT => -156,
GOTOS => {
'args' => 249
}
},
{#State 176
ACTIONS => {
"\"" => 250,
'TEXT' => 231,
";" => 233,
"\$" => 43,
'IDENT' => 2,
"\${" => 37
},
GOTOS => {
'item' => 39,
'node' => 23,
'ident' => 230,
'quotable' => 232
}
},
{#State 177
ACTIONS => {
"\"" => 89,
'LITERAL' => 88,
'FILENAME' => 83,
'IDENT' => 81,
'NUMBER' => 84
},
GOTOS => {
'filepart' => 87,
'filename' => 85,
'name' => 251
}
},
{#State 178
DEFAULT => -156,
GOTOS => {
'args' => 252
}
},
{#State 179
ACTIONS => {
'NOT' => 38,
'LITERAL' => 256,
'IDENT' => 2,
"\"" => 60,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"{" => 30,
'COMMA' => 258,
"(" => 53,
"\${" => 37
},
DEFAULT => -163,
GOTOS => {
'expr' => 257,
'sterm' => 68,
'item' => 254,
'param' => 255,
'node' => 23,
'ident' => 253,
'term' => 58,
'lterm' => 56
}
},
{#State 180
DEFAULT => -105
},
{#State 181
DEFAULT => -114
},
{#State 182
DEFAULT => -115
},
{#State 183
DEFAULT => -106
},
{#State 184
ACTIONS => {
"\"" => 60,
"\$" => 43,
'LITERAL' => 78,
'IDENT' => 2,
'REF' => 27,
'NUMBER' => 26,
"\${" => 37
},
GOTOS => {
'sterm' => 259,
'item' => 39,
'node' => 23,
'ident' => 77
}
},
{#State 185
ACTIONS => {
'FINAL' => 260,
'CATCH' => 262
},
DEFAULT => -72,
GOTOS => {
'final' => 261
}
},
{#State 186
ACTIONS => {
'TEXT' => 263
}
},
{#State 187
ACTIONS => {
"\"" => 266,
'LITERAL' => 265,
'NUMBER' => 264
}
},
{#State 188
DEFAULT => -97
},
{#State 189
DEFAULT => -98
},
{#State 190
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'loop' => 4,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'atomdir' => 12,
'anonblock' => 50,
'template' => 267,
'defblockname' => 14,
'ident' => 16,
'assign' => 19,
'macro' => 20,
'lterm' => 56,
'node' => 23,
'term' => 58,
'rawperl' => 59,
'expr' => 62,
'use' => 63,
'defblock' => 66,
'filter' => 29,
'sterm' => 68,
'perl' => 31,
'chunks' => 33,
'setlist' => 70,
'switch' => 34,
'try' => 35,
'directive' => 71,
'block' => 72,
'condition' => 73
}
},
{#State 191
DEFAULT => -125
},
{#State 192
DEFAULT => -126
},
{#State 193
ACTIONS => {
";" => 268
}
},
{#State 194
DEFAULT => -89
},
{#State 195
ACTIONS => {
";" => -150,
"+" => 157,
'LITERAL' => -150,
'IDENT' => -150,
'CAT' => 163,
"\$" => -150,
'CMPOP' => 164,
"?" => 158,
'DIV' => 159,
'MOD' => 165,
'COMMA' => -150,
"/" => 166,
'AND' => 160,
'BINOP' => 161,
'OR' => 162,
"\${" => -150
},
DEFAULT => -26
},
{#State 196
DEFAULT => -92
},
{#State 197
DEFAULT => -91
},
{#State 198
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 57,
'IDENT' => 269,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 151,
'sterm' => 68,
'item' => 39,
'assign' => 150,
'margs' => 270,
'node' => 23,
'ident' => 149,
'term' => 58,
'lterm' => 56
}
},
{#State 199
ACTIONS => {
"+" => 157,
'CAT' => 163,
'CMPOP' => 164,
"?" => 158,
'DIV' => 159,
'MOD' => 165,
"/" => 166,
'AND' => 160,
'BINOP' => 161,
'OR' => 162
},
DEFAULT => -26
},
{#State 200
ACTIONS => {
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 271,
'lterm' => 56
}
},
{#State 201
ACTIONS => {
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 272,
'lterm' => 56
}
},
{#State 202
ACTIONS => {
'NOT' => 38,
"{" => 30,
'COMMA' => 258,
'LITERAL' => 256,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
DEFAULT => -64,
GOTOS => {
'expr' => 257,
'sterm' => 68,
'item' => 254,
'param' => 255,
'node' => 23,
'ident' => 253,
'term' => 58,
'lterm' => 56
}
},
{#State 203
DEFAULT => -56,
GOTOS => {
'@1-3' => 273
}
},
{#State 204
ACTIONS => {
"\"" => 89,
"\$" => 86,
'LITERAL' => 88,
'FILENAME' => 83,
'IDENT' => 81,
'NUMBER' => 84
},
GOTOS => {
'filepart' => 87,
'names' => 91,
'nameargs' => 274,
'filename' => 85,
'name' => 82
}
},
{#State 205
ACTIONS => {
'ASSIGN' => -132
},
DEFAULT => -130
},
{#State 206
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 275,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 207
ACTIONS => {
"\"" => 276,
'TEXT' => 231,
";" => 233,
"\$" => 43,
'IDENT' => 2,
"\${" => 37
},
GOTOS => {
'item' => 39,
'node' => 23,
'ident' => 230,
'quotable' => 232
}
},
{#State 208
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 277,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 209
DEFAULT => -108
},
{#State 210
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 278,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 211
DEFAULT => -120
},
{#State 212
DEFAULT => -121
},
{#State 213
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 279,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 214
DEFAULT => -74,
GOTOS => {
'@3-3' => 280
}
},
{#State 215
DEFAULT => -131
},
{#State 216
ACTIONS => {
'NOT' => 38,
"{" => 30,
'COMMA' => 258,
'LITERAL' => 256,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
")" => 281,
"\${" => 37
},
GOTOS => {
'expr' => 257,
'sterm' => 68,
'item' => 254,
'param' => 255,
'node' => 23,
'ident' => 253,
'term' => 58,
'lterm' => 56
}
},
{#State 217
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 282,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 218
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 283,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 219
ACTIONS => {
'CMPOP' => 164,
"?" => 158,
"+" => 157,
'MOD' => 165,
'DIV' => 159,
"/" => 166,
'AND' => 160,
'CAT' => 163,
'BINOP' => 161,
'OR' => 162
},
DEFAULT => -47
},
{#State 220
DEFAULT => -58
},
{#State 221
DEFAULT => -81
},
{#State 222
ACTIONS => {
'CMPOP' => 164,
"?" => 158,
"+" => 157,
'MOD' => 165,
'DIV' => 159,
"/" => 166,
'AND' => 160,
'CAT' => 163,
'BINOP' => 161,
'OR' => 162
},
DEFAULT => -45
},
{#State 223
DEFAULT => -66
},
{#State 224
ACTIONS => {
'CMPOP' => 164,
"?" => 158,
"+" => 157,
'MOD' => 165,
'DIV' => 159,
"/" => 166,
'AND' => 160,
'CAT' => 163,
'BINOP' => 161,
'OR' => 162
},
DEFAULT => -61
},
{#State 225
DEFAULT => -144
},
{#State 226
DEFAULT => -145
},
{#State 227
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 284,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 228
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 285,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 229
ACTIONS => {
"+" => 157,
'CAT' => 163,
'CMPOP' => 164,
"?" => 158,
'DIV' => 159,
'MOD' => 165,
"/" => 166,
'AND' => 160,
'BINOP' => 161,
'OR' => 162
},
DEFAULT => -151
},
{#State 230
ACTIONS => {
'DOT' => 104
},
DEFAULT => -177
},
{#State 231
DEFAULT => -178
},
{#State 232
DEFAULT => -175
},
{#State 233
DEFAULT => -179
},
{#State 234
DEFAULT => -111
},
{#State 235
ACTIONS => {
'DIV' => 159,
'MOD' => 165,
"/" => 166
},
DEFAULT => -135
},
{#State 236
ACTIONS => {
":" => 286,
'CMPOP' => 164,
"?" => 158,
"+" => 157,
'MOD' => 165,
'DIV' => 159,
"/" => 166,
'AND' => 160,
'CAT' => 163,
'BINOP' => 161,
'OR' => 162
}
},
{#State 237
ACTIONS => {
'MOD' => 165
},
DEFAULT => -136
},
{#State 238
ACTIONS => {
'DIV' => 159,
'BINOP' => 161,
"+" => 157,
'CAT' => 163,
'CMPOP' => 164,
'MOD' => 165,
"/" => 166
},
DEFAULT => -140
},
{#State 239
ACTIONS => {
'DIV' => 159,
"+" => 157,
'MOD' => 165,
"/" => 166
},
DEFAULT => -133
},
{#State 240
ACTIONS => {
'DIV' => 159,
'BINOP' => 161,
"+" => 157,
'CAT' => 163,
'CMPOP' => 164,
'MOD' => 165,
"/" => 166
},
DEFAULT => -141
},
{#State 241
ACTIONS => {
'DIV' => 159,
'BINOP' => 161,
"+" => 157,
'CMPOP' => 164,
'MOD' => 165,
"/" => 166
},
DEFAULT => -139
},
{#State 242
ACTIONS => {
'DIV' => 159,
'BINOP' => 161,
"+" => 157,
'MOD' => 165,
"/" => 166
},
DEFAULT => -138
},
{#State 243
DEFAULT => -137
},
{#State 244
ACTIONS => {
'DIV' => 159,
'MOD' => 165
},
DEFAULT => -134
},
{#State 245
DEFAULT => -59,
GOTOS => {
'@2-3' => 287
}
},
{#State 246
ACTIONS => {
"+" => 157,
'CAT' => 163,
'CMPOP' => 164,
"?" => 158,
'DIV' => 159,
'MOD' => 165,
"/" => 166,
'AND' => 160,
'BINOP' => 161,
'OR' => 162
},
DEFAULT => -150
},
{#State 247
ACTIONS => {
'ELSIF' => 290,
'ELSE' => 288
},
DEFAULT => -50,
GOTOS => {
'else' => 289
}
},
{#State 248
DEFAULT => -170
},
{#State 249
ACTIONS => {
'NOT' => 38,
'LITERAL' => 256,
'IDENT' => 2,
"\"" => 60,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"{" => 30,
'COMMA' => 258,
"(" => 53,
"\${" => 37
},
DEFAULT => -162,
GOTOS => {
'expr' => 257,
'sterm' => 68,
'item' => 254,
'param' => 255,
'node' => 23,
'ident' => 253,
'term' => 58,
'lterm' => 56
}
},
{#State 250
DEFAULT => -167
},
{#State 251
DEFAULT => -165
},
{#State 252
ACTIONS => {
'NOT' => 38,
"{" => 30,
'COMMA' => 258,
'LITERAL' => 256,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
")" => 291,
"\${" => 37
},
GOTOS => {
'expr' => 257,
'sterm' => 68,
'item' => 254,
'param' => 255,
'node' => 23,
'ident' => 253,
'term' => 58,
'lterm' => 56
}
},
{#State 253
ACTIONS => {
'DOT' => 104,
'ASSIGN' => 292
},
DEFAULT => -109
},
{#State 254
ACTIONS => {
"(" => 135,
'ASSIGN' => 210
},
DEFAULT => -128
},
{#State 255
DEFAULT => -153
},
{#State 256
ACTIONS => {
'ASSIGN' => 213
},
DEFAULT => -112
},
{#State 257
ACTIONS => {
"+" => 157,
'CAT' => 163,
'CMPOP' => 164,
"?" => 158,
'DIV' => 159,
'MOD' => 165,
"/" => 166,
'AND' => 160,
'BINOP' => 161,
'OR' => 162
},
DEFAULT => -152
},
{#State 258
DEFAULT => -155
},
{#State 259
DEFAULT => -117
},
{#State 260
ACTIONS => {
";" => 293
}
},
{#State 261
ACTIONS => {
'END' => 294
}
},
{#State 262
ACTIONS => {
";" => 296,
'DEFAULT' => 297,
'FILENAME' => 83,
'IDENT' => 81,
'NUMBER' => 84
},
GOTOS => {
'filepart' => 87,
'filename' => 295
}
},
{#State 263
ACTIONS => {
'END' => 298
}
},
{#State 264
DEFAULT => -102
},
{#State 265
DEFAULT => -100
},
{#State 266
ACTIONS => {
'TEXT' => 299
}
},
{#State 267
ACTIONS => {
'END' => 300
}
},
{#State 268
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 301,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 269
ACTIONS => {
'IDENT' => -96,
")" => -96,
'COMMA' => -96
},
DEFAULT => -130
},
{#State 270
ACTIONS => {
'COMMA' => 304,
'IDENT' => 302,
")" => 303
}
},
{#State 271
DEFAULT => -156,
GOTOS => {
'args' => 305
}
},
{#State 272
DEFAULT => -156,
GOTOS => {
'args' => 306
}
},
{#State 273
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 307,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 274
DEFAULT => -157
},
{#State 275
ACTIONS => {
'END' => 308
}
},
{#State 276
ACTIONS => {
'ASSIGN' => -160
},
DEFAULT => -167
},
{#State 277
ACTIONS => {
'END' => 309
}
},
{#State 278
ACTIONS => {
'DIV' => 159,
'AND' => 160,
'BINOP' => 161,
'OR' => 162,
"+" => 157,
'CAT' => 163,
'CMPOP' => 164,
"?" => 158,
'MOD' => 165,
"/" => 166
},
DEFAULT => -124
},
{#State 279
ACTIONS => {
'DIV' => 159,
'AND' => 160,
'BINOP' => 161,
'OR' => 162,
"+" => 157,
'CAT' => 163,
'CMPOP' => 164,
"?" => 158,
'MOD' => 165,
"/" => 166
},
DEFAULT => -123
},
{#State 280
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 310,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 281
DEFAULT => -129
},
{#State 282
ACTIONS => {
'END' => 311
}
},
{#State 283
ACTIONS => {
'ELSIF' => 290,
'ELSE' => 288
},
DEFAULT => -50,
GOTOS => {
'else' => 312
}
},
{#State 284
ACTIONS => {
'CASE' => 313
},
DEFAULT => -55,
GOTOS => {
'case' => 314
}
},
{#State 285
ACTIONS => {
'END' => 315
}
},
{#State 286
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 316,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 287
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 317,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 288
ACTIONS => {
";" => 318
}
},
{#State 289
ACTIONS => {
'END' => 319
}
},
{#State 290
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 320,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 291
DEFAULT => -164
},
{#State 292
ACTIONS => {
'NOT' => 38,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'expr' => 321,
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 58,
'lterm' => 56
}
},
{#State 293
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 322,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 294
DEFAULT => -67
},
{#State 295
ACTIONS => {
'DOT' => 174,
";" => 323
}
},
{#State 296
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 324,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 297
ACTIONS => {
";" => 325
}
},
{#State 298
DEFAULT => -79
},
{#State 299
ACTIONS => {
"\"" => 326
}
},
{#State 300
DEFAULT => -82
},
{#State 301
ACTIONS => {
'END' => 327
}
},
{#State 302
DEFAULT => -94
},
{#State 303
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'WRAPPER' => 55,
'FOR' => 21,
'NEXT' => 22,
'LITERAL' => 57,
"\"" => 60,
'PROCESS' => 61,
'FILTER' => 25,
'RETURN' => 64,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 193,
'DEFAULT' => 69,
"{" => 30,
"\${" => 37
},
GOTOS => {
'item' => 39,
'node' => 23,
'term' => 58,
'loop' => 4,
'expr' => 199,
'wrapper' => 46,
'atomexpr' => 48,
'atomdir' => 12,
'mdir' => 328,
'filter' => 29,
'sterm' => 68,
'ident' => 149,
'perl' => 31,
'setlist' => 70,
'try' => 35,
'switch' => 34,
'assign' => 19,
'directive' => 196,
'condition' => 73,
'lterm' => 56
}
},
{#State 304
DEFAULT => -95
},
{#State 305
ACTIONS => {
'NOT' => 38,
"{" => 30,
'COMMA' => 258,
'LITERAL' => 256,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
DEFAULT => -62,
GOTOS => {
'expr' => 257,
'sterm' => 68,
'item' => 254,
'param' => 255,
'node' => 23,
'ident' => 253,
'term' => 58,
'lterm' => 56
}
},
{#State 306
ACTIONS => {
'NOT' => 38,
"{" => 30,
'COMMA' => 258,
'LITERAL' => 256,
'IDENT' => 2,
"\"" => 60,
"(" => 53,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
DEFAULT => -63,
GOTOS => {
'expr' => 257,
'sterm' => 68,
'item' => 254,
'param' => 255,
'node' => 23,
'ident' => 253,
'term' => 58,
'lterm' => 56
}
},
{#State 307
ACTIONS => {
'END' => 329
}
},
{#State 308
DEFAULT => -80
},
{#State 309
DEFAULT => -88
},
{#State 310
ACTIONS => {
'END' => 330
}
},
{#State 311
DEFAULT => -77
},
{#State 312
ACTIONS => {
'END' => 331
}
},
{#State 313
ACTIONS => {
";" => 332,
'DEFAULT' => 334,
"{" => 30,
'LITERAL' => 78,
'IDENT' => 2,
"\"" => 60,
"\$" => 43,
"[" => 9,
'NUMBER' => 26,
'REF' => 27,
"\${" => 37
},
GOTOS => {
'sterm' => 68,
'item' => 39,
'node' => 23,
'ident' => 77,
'term' => 333,
'lterm' => 56
}
},
{#State 314
ACTIONS => {
'END' => 335
}
},
{#State 315
DEFAULT => -65
},
{#State 316
ACTIONS => {
'DIV' => 159,
'AND' => 160,
'BINOP' => 161,
'OR' => 162,
"+" => 157,
'CAT' => 163,
'CMPOP' => 164,
"?" => 158,
'MOD' => 165,
"/" => 166
},
DEFAULT => -143
},
{#State 317
ACTIONS => {
'END' => 336
}
},
{#State 318
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 337,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 319
DEFAULT => -46
},
{#State 320
ACTIONS => {
'CMPOP' => 164,
"?" => 158,
";" => 338,
"+" => 157,
'MOD' => 165,
'DIV' => 159,
"/" => 166,
'AND' => 160,
'CAT' => 163,
'BINOP' => 161,
'OR' => 162
}
},
{#State 321
ACTIONS => {
"+" => 157,
'CAT' => 163,
'CMPOP' => 164,
"?" => 158,
'DIV' => 159,
'MOD' => 165,
"/" => 166,
'AND' => 160,
'BINOP' => 161,
'OR' => 162
},
DEFAULT => -154
},
{#State 322
DEFAULT => -71
},
{#State 323
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 339,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 324
ACTIONS => {
'FINAL' => 260,
'CATCH' => 262
},
DEFAULT => -72,
GOTOS => {
'final' => 340
}
},
{#State 325
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 341,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 326
DEFAULT => -101
},
{#State 327
DEFAULT => -93
},
{#State 328
DEFAULT => -90
},
{#State 329
DEFAULT => -57
},
{#State 330
DEFAULT => -75
},
{#State 331
DEFAULT => -44
},
{#State 332
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 342,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 333
ACTIONS => {
";" => 343
}
},
{#State 334
ACTIONS => {
";" => 344
}
},
{#State 335
DEFAULT => -51
},
{#State 336
DEFAULT => -60
},
{#State 337
DEFAULT => -49
},
{#State 338
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 345,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 339
ACTIONS => {
'FINAL' => 260,
'CATCH' => 262
},
DEFAULT => -72,
GOTOS => {
'final' => 346
}
},
{#State 340
DEFAULT => -70
},
{#State 341
ACTIONS => {
'FINAL' => 260,
'CATCH' => 262
},
DEFAULT => -72,
GOTOS => {
'final' => 347
}
},
{#State 342
DEFAULT => -54
},
{#State 343
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 348,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 344
ACTIONS => {
'SET' => 1,
'PERL' => 40,
'NOT' => 38,
'IDENT' => 2,
'CLEAR' => 41,
'UNLESS' => 3,
'IF' => 44,
"\$" => 43,
'STOP' => 6,
'CALL' => 45,
'THROW' => 8,
'GET' => 47,
"[" => 9,
'TRY' => 10,
'LAST' => 49,
'DEBUG' => 51,
'RAWPERL' => 13,
'META' => 15,
'INCLUDE' => 17,
"(" => 53,
'SWITCH' => 54,
'MACRO' => 18,
'WRAPPER' => 55,
";" => -18,
'FOR' => 21,
'LITERAL' => 57,
'NEXT' => 22,
"\"" => 60,
'TEXT' => 24,
'PROCESS' => 61,
'RETURN' => 64,
'FILTER' => 25,
'INSERT' => 65,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 67,
'BLOCK' => 28,
'DEFAULT' => 69,
"{" => 30,
'USE' => 32,
'VIEW' => 36,
"\${" => 37
},
DEFAULT => -3,
GOTOS => {
'item' => 39,
'node' => 23,
'rawperl' => 59,
'term' => 58,
'loop' => 4,
'use' => 63,
'expr' => 62,
'capture' => 42,
'statement' => 5,
'view' => 7,
'wrapper' => 46,
'atomexpr' => 48,
'chunk' => 11,
'defblock' => 66,
'atomdir' => 12,
'anonblock' => 50,
'sterm' => 68,
'defblockname' => 14,
'filter' => 29,
'ident' => 16,
'perl' => 31,
'setlist' => 70,
'chunks' => 33,
'try' => 35,
'switch' => 34,
'assign' => 19,
'block' => 349,
'directive' => 71,
'macro' => 20,
'condition' => 73,
'lterm' => 56
}
},
{#State 345
ACTIONS => {
'ELSIF' => 290,
'ELSE' => 288
},
DEFAULT => -50,
GOTOS => {
'else' => 350
}
},
{#State 346
DEFAULT => -68
},
{#State 347
DEFAULT => -69
},
{#State 348
ACTIONS => {
'CASE' => 313
},
DEFAULT => -55,
GOTOS => {
'case' => 351
}
},
{#State 349
DEFAULT => -53
},
{#State 350
DEFAULT => -48
},
{#State 351
DEFAULT => -52
}
];
$RULES = [
[#Rule 0
'$start', 2, undef
],
[#Rule 1
'template', 1,
sub
{ $factory->template($_[1]) }
],
[#Rule 2
'block', 1,
sub
{ $factory->block($_[1]) }
],
[#Rule 3
'block', 0,
sub
{ $factory->block() }
],
[#Rule 4
'chunks', 2,
sub
{ push(@{$_[1]}, $_[2])
if defined $_[2]; $_[1] }
],
[#Rule 5
'chunks', 1,
sub
{ defined $_[1] ? [ $_[1] ] : [ ] }
],
[#Rule 6
'chunk', 1,
sub
{ $factory->textblock($_[1]) }
],
[#Rule 7
'chunk', 2,
sub
{ return '' unless $_[1];
$_[0]->location() . $_[1];
}
],
[#Rule 8
'statement', 1, undef
],
[#Rule 9
'statement', 1, undef
],
[#Rule 10
'statement', 1, undef
],
[#Rule 11
'statement', 1, undef
],
[#Rule 12
'statement', 1, undef
],
[#Rule 13
'statement', 1, undef
],
[#Rule 14
'statement', 1, undef
],
[#Rule 15
'statement', 1, undef
],
[#Rule 16
'statement', 1,
sub
{ $factory->get($_[1]) }
],
[#Rule 17
'statement', 2,
sub
{ $_[0]->add_metadata($_[2]); }
],
[#Rule 18
'statement', 0, undef
],
[#Rule 19
'directive', 1,
sub
{ $factory->set($_[1]) }
],
[#Rule 20
'directive', 1, undef
],
[#Rule 21
'directive', 1, undef
],
[#Rule 22
'directive', 1, undef
],
[#Rule 23
'directive', 1, undef
],
[#Rule 24
'directive', 1, undef
],
[#Rule 25
'directive', 1, undef
],
[#Rule 26
'atomexpr', 1,
sub
{ $factory->get($_[1]) }
],
[#Rule 27
'atomexpr', 1, undef
],
[#Rule 28
'atomdir', 2,
sub
{ $factory->get($_[2]) }
],
[#Rule 29
'atomdir', 2,
sub
{ $factory->call($_[2]) }
],
[#Rule 30
'atomdir', 2,
sub
{ $factory->set($_[2]) }
],
[#Rule 31
'atomdir', 2,
sub
{ $factory->default($_[2]) }
],
[#Rule 32
'atomdir', 2,
sub
{ $factory->insert($_[2]) }
],
[#Rule 33
'atomdir', 2,
sub
{ $factory->include($_[2]) }
],
[#Rule 34
'atomdir', 2,
sub
{ $factory->process($_[2]) }
],
[#Rule 35
'atomdir', 2,
sub
{ $factory->throw($_[2]) }
],
[#Rule 36
'atomdir', 1,
sub
{ $factory->return() }
],
[#Rule 37
'atomdir', 1,
sub
{ $factory->stop() }
],
[#Rule 38
'atomdir', 1,
sub
{ "\$output = '';"; }
],
[#Rule 39
'atomdir', 1,
sub
{ $_[0]->block_label('last ', ';') }
],
[#Rule 40
'atomdir', 1,
sub
{ $_[0]->in_block('FOR')
? $factory->next($_[0]->block_label)
: $_[0]->block_label('next ', ';') }
],
[#Rule 41
'atomdir', 2,
sub
{ if ($_[2]->[0]->[0] =~ /^'(on|off)'$/) {
$_[0]->{ DEBUG_DIRS } = ($1 eq 'on');
$factory->debug($_[2]);
}
else {
$_[0]->{ DEBUG_DIRS } ? $factory->debug($_[2]) : '';
}
}
],
[#Rule 42
'atomdir', 1, undef
],
[#Rule 43
'atomdir', 1, undef
],
[#Rule 44
'condition', 6,
sub
{ $factory->if(@_[2, 4, 5]) }
],
[#Rule 45
'condition', 3,
sub
{ $factory->if(@_[3, 1]) }
],
[#Rule 46
'condition', 6,
sub
{ $factory->if("!($_[2])", @_[4, 5]) }
],
[#Rule 47
'condition', 3,
sub
{ $factory->if("!($_[3])", $_[1]) }
],
[#Rule 48
'else', 5,
sub
{ unshift(@{$_[5]}, [ @_[2, 4] ]);
$_[5]; }
],
[#Rule 49
'else', 3,
sub
{ [ $_[3] ] }
],
[#Rule 50
'else', 0,
sub
{ [ undef ] }
],
[#Rule 51
'switch', 6,
sub
{ $factory->switch(@_[2, 5]) }
],
[#Rule 52
'case', 5,
sub
{ unshift(@{$_[5]}, [ @_[2, 4] ]);
$_[5]; }
],
[#Rule 53
'case', 4,
sub
{ [ $_[4] ] }
],
[#Rule 54
'case', 3,
sub
{ [ $_[3] ] }
],
[#Rule 55
'case', 0,
sub
{ [ undef ] }
],
[#Rule 56
'@1-3', 0,
sub
{ $_[0]->enter_block('FOR') }
],
[#Rule 57
'loop', 6,
sub
{ $factory->foreach(@{$_[2]}, $_[5], $_[0]->leave_block) }
],
[#Rule 58
'loop', 3,
sub
{ $factory->foreach(@{$_[3]}, $_[1]) }
],
[#Rule 59
'@2-3', 0,
sub
{ $_[0]->enter_block('WHILE') }
],
[#Rule 60
'loop', 6,
sub
{ $factory->while(@_[2, 5], $_[0]->leave_block) }
],
[#Rule 61
'loop', 3,
sub
{ $factory->while(@_[3, 1]) }
],
[#Rule 62
'loopvar', 4,
sub
{ [ @_[1, 3, 4] ] }
],
[#Rule 63
'loopvar', 4,
sub
{ [ @_[1, 3, 4] ] }
],
[#Rule 64
'loopvar', 2,
sub
{ [ 0, @_[1, 2] ] }
],
[#Rule 65
'wrapper', 5,
sub
{ $factory->wrapper(@_[2, 4]) }
],
[#Rule 66
'wrapper', 3,
sub
{ $factory->wrapper(@_[3, 1]) }
],
[#Rule 67
'try', 5,
sub
{ $factory->try(@_[3, 4]) }
],
[#Rule 68
'final', 5,
sub
{ unshift(@{$_[5]}, [ @_[2,4] ]);
$_[5]; }
],
[#Rule 69
'final', 5,
sub
{ unshift(@{$_[5]}, [ undef, $_[4] ]);
$_[5]; }
],
[#Rule 70
'final', 4,
sub
{ unshift(@{$_[4]}, [ undef, $_[3] ]);
$_[4]; }
],
[#Rule 71
'final', 3,
sub
{ [ $_[3] ] }
],
[#Rule 72
'final', 0,
sub
{ [ 0 ] }
],
[#Rule 73
'use', 2,
sub
{ $factory->use($_[2]) }
],
[#Rule 74
'@3-3', 0,
sub
{ $_[0]->push_defblock(); }
],
[#Rule 75
'view', 6,
sub
{ $factory->view(@_[2,5],
$_[0]->pop_defblock) }
],
[#Rule 76
'@4-2', 0,
sub
{ ${$_[0]->{ INPERL }}++; }
],
[#Rule 77
'perl', 5,
sub
{ ${$_[0]->{ INPERL }}--;
$_[0]->{ EVAL_PERL }
? $factory->perl($_[4])
: $factory->no_perl(); }
],
[#Rule 78
'@5-1', 0,
sub
{ ${$_[0]->{ INPERL }}++;
$rawstart = ${$_[0]->{'LINE'}}; }
],
[#Rule 79
'rawperl', 5,
sub
{ ${$_[0]->{ INPERL }}--;
$_[0]->{ EVAL_PERL }
? $factory->rawperl($_[4], $rawstart)
: $factory->no_perl(); }
],
[#Rule 80
'filter', 5,
sub
{ $factory->filter(@_[2,4]) }
],
[#Rule 81
'filter', 3,
sub
{ $factory->filter(@_[3,1]) }
],
[#Rule 82
'defblock', 5,
sub
{ my $name = join('/', @{ $_[0]->{ DEFBLOCKS } });
pop(@{ $_[0]->{ DEFBLOCKS } });
$_[0]->define_block($name, $_[4]);
undef
}
],
[#Rule 83
'defblockname', 2,
sub
{ push(@{ $_[0]->{ DEFBLOCKS } }, $_[2]);
$_[2];
}
],
[#Rule 84
'blockname', 1, undef
],
[#Rule 85
'blockname', 1,
sub
{ $_[1] =~ s/^'(.*)'$/$1/; $_[1] }
],
[#Rule 86
'blockargs', 1, undef
],
[#Rule 87
'blockargs', 0, undef
],
[#Rule 88
'anonblock', 5,
sub
{ local $" = ', ';
print STDERR "experimental block args: [@{ $_[2] }]\n"
if $_[2];
$factory->anon_block($_[4]) }
],
[#Rule 89
'capture', 3,
sub
{ $factory->capture(@_[1, 3]) }
],
[#Rule 90
'macro', 6,
sub
{ $factory->macro(@_[2, 6, 4]) }
],
[#Rule 91
'macro', 3,
sub
{ $factory->macro(@_[2, 3]) }
],
[#Rule 92
'mdir', 1, undef
],
[#Rule 93
'mdir', 4,
sub
{ $_[3] }
],
[#Rule 94
'margs', 2,
sub
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 95
'margs', 2,
sub
{ $_[1] }
],
[#Rule 96
'margs', 1,
sub
{ [ $_[1] ] }
],
[#Rule 97
'metadata', 2,
sub
{ push(@{$_[1]}, @{$_[2]}); $_[1] }
],
[#Rule 98
'metadata', 2, undef
],
[#Rule 99
'metadata', 1, undef
],
[#Rule 100
'meta', 3,
sub
{ for ($_[3]) { s/^'//; s/'$//;
s/\\'/'/g };
[ @_[1,3] ] }
],
[#Rule 101
'meta', 5,
sub
{ [ @_[1,4] ] }
],
[#Rule 102
'meta', 3,
sub
{ [ @_[1,3] ] }
],
[#Rule 103
'term', 1, undef
],
[#Rule 104
'term', 1, undef
],
[#Rule 105
'lterm', 3,
sub
{ "[ $_[2] ]" }
],
[#Rule 106
'lterm', 3,
sub
{ "[ $_[2] ]" }
],
[#Rule 107
'lterm', 2,
sub
{ "[ ]" }
],
[#Rule 108
'lterm', 3,
sub
{ "{ $_[2] }" }
],
[#Rule 109
'sterm', 1,
sub
{ $factory->ident($_[1]) }
],
[#Rule 110
'sterm', 2,
sub
{ $factory->identref($_[2]) }
],
[#Rule 111
'sterm', 3,
sub
{ $factory->quoted($_[2]) }
],
[#Rule 112
'sterm', 1, undef
],
[#Rule 113
'sterm', 1, undef
],
[#Rule 114
'list', 2,
sub
{ "$_[1], $_[2]" }
],
[#Rule 115
'list', 2, undef
],
[#Rule 116
'list', 1, undef
],
[#Rule 117
'range', 3,
sub
{ $_[1] . '..' . $_[3] }
],
[#Rule 118
'hash', 1, undef
],
[#Rule 119
'hash', 0,
sub
{ "" }
],
[#Rule 120
'params', 2,
sub
{ "$_[1], $_[2]" }
],
[#Rule 121
'params', 2, undef
],
[#Rule 122
'params', 1, undef
],
[#Rule 123
'param', 3,
sub
{ "$_[1] => $_[3]" }
],
[#Rule 124
'param', 3,
sub
{ "$_[1] => $_[3]" }
],
[#Rule 125
'ident', 3,
sub
{ push(@{$_[1]}, @{$_[3]}); $_[1] }
],
[#Rule 126
'ident', 3,
sub
{ push(@{$_[1]},
map {($_, 0)} split(/\./, $_[3]));
$_[1]; }
],
[#Rule 127
'ident', 1, undef
],
[#Rule 128
'node', 1,
sub
{ [ $_[1], 0 ] }
],
[#Rule 129
'node', 4,
sub
{ [ $_[1], $factory->args($_[3]) ] }
],
[#Rule 130
'item', 1,
sub
{ "'$_[1]'" }
],
[#Rule 131
'item', 3,
sub
{ $_[2] }
],
[#Rule 132
'item', 2,
sub
{ $_[0]->{ V1DOLLAR }
? "'$_[2]'"
: $factory->ident(["'$_[2]'", 0]) }
],
[#Rule 133
'expr', 3,
sub
{ "$_[1] $_[2] $_[3]" }
],
[#Rule 134
'expr', 3,
sub
{ "$_[1] $_[2] $_[3]" }
],
[#Rule 135
'expr', 3,
sub
{ "$_[1] $_[2] $_[3]" }
],
[#Rule 136
'expr', 3,
sub
{ "int($_[1] / $_[3])" }
],
[#Rule 137
'expr', 3,
sub
{ "$_[1] % $_[3]" }
],
[#Rule 138
'expr', 3,
sub
{ "$_[1] $CMPOP{ $_[2] } $_[3]" }
],
[#Rule 139
'expr', 3,
sub
{ "$_[1] . $_[3]" }
],
[#Rule 140
'expr', 3,
sub
{ "$_[1] && $_[3]" }
],
[#Rule 141
'expr', 3,
sub
{ "$_[1] || $_[3]" }
],
[#Rule 142
'expr', 2,
sub
{ "! $_[2]" }
],
[#Rule 143
'expr', 5,
sub
{ "$_[1] ? $_[3] : $_[5]" }
],
[#Rule 144
'expr', 3,
sub
{ $factory->assign(@{$_[2]}) }
],
[#Rule 145
'expr', 3,
sub
{ "($_[2])" }
],
[#Rule 146
'expr', 1, undef
],
[#Rule 147
'setlist', 2,
sub
{ push(@{$_[1]}, @{$_[2]}); $_[1] }
],
[#Rule 148
'setlist', 2, undef
],
[#Rule 149
'setlist', 1, undef
],
[#Rule 150
'assign', 3,
sub
{ [ $_[1], $_[3] ] }
],
[#Rule 151
'assign', 3,
sub
{ [ @_[1,3] ] }
],
[#Rule 152
'args', 2,
sub
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 153
'args', 2,
sub
{ push(@{$_[1]->[0]}, $_[2]); $_[1] }
],
[#Rule 154
'args', 4,
sub
{ push(@{$_[1]->[0]}, "'', " .
$factory->assign(@_[2,4])); $_[1] }
],
[#Rule 155
'args', 2,
sub
{ $_[1] }
],
[#Rule 156
'args', 0,
sub
{ [ [ ] ] }
],
[#Rule 157
'lnameargs', 3,
sub
{ push(@{$_[3]}, $_[1]); $_[3] }
],
[#Rule 158
'lnameargs', 1, undef
],
[#Rule 159
'lvalue', 1, undef
],
[#Rule 160
'lvalue', 3,
sub
{ $factory->quoted($_[2]) }
],
[#Rule 161
'lvalue', 1, undef
],
[#Rule 162
'nameargs', 3,
sub
{ [ [$factory->ident($_[2])], $_[3] ] }
],
[#Rule 163
'nameargs', 2,
sub
{ [ @_[1,2] ] }
],
[#Rule 164
'nameargs', 4,
sub
{ [ @_[1,3] ] }
],
[#Rule 165
'names', 3,
sub
{ push(@{$_[1]}, $_[3]); $_[1] }
],
[#Rule 166
'names', 1,
sub
{ [ $_[1] ] }
],
[#Rule 167
'name', 3,
sub
{ $factory->quoted($_[2]) }
],
[#Rule 168
'name', 1,
sub
{ "'$_[1]'" }
],
[#Rule 169
'name', 1, undef
],
[#Rule 170
'filename', 3,
sub
{ "$_[1].$_[3]" }
],
[#Rule 171
'filename', 1, undef
],
[#Rule 172
'filepart', 1, undef
],
[#Rule 173
'filepart', 1, undef
],
[#Rule 174
'filepart', 1, undef
],
[#Rule 175
'quoted', 2,
sub
{ push(@{$_[1]}, $_[2])
if defined $_[2]; $_[1] }
],
[#Rule 176
'quoted', 0,
sub
{ [ ] }
],
[#Rule 177
'quotable', 1,
sub
{ $factory->ident($_[1]) }
],
[#Rule 178
'quotable', 1,
sub
{ $factory->text($_[1]) }
],
[#Rule 179
'quotable', 1,
sub
{ undef }
]
];
1;
}
#
# Inline include of Template/Directive.pm
#
BEGIN { $INC{'Template/Directive.pm'} = 'dummy/Template/Directive.pm'; }
BEGIN {
#line 0 "Template/Directive.pm"
package Template::Directive;
use strict;
use warnings;
use base 'Template::Base';
use Template::Constants;
use Template::Exception;
our $VERSION = 2.20;
our $DEBUG = 0 unless defined $DEBUG;
our $WHILE_MAX = 1000 unless defined $WHILE_MAX;
our $PRETTY = 0 unless defined $PRETTY;
our $OUTPUT = '$output .= ';
sub _init {
my ($self, $config) = @_;
$self->{ NAMESPACE } = $config->{ NAMESPACE };
return $self;
}
sub pad {
my ($text, $pad) = @_;
$pad = ' ' x ($pad * 4);
$text =~ s/^(?!#line)/$pad/gm;
$text;
}
sub template {
my ($class, $block) = @_;
$block = pad($block, 2) if $PRETTY;
return "sub { return '' }" unless $block =~ /\S/;
return <<EOF;
sub {
my \$context = shift || die "template sub called without context\\n";
my \$stash = \$context->stash;
my \$output = '';
my \$_tt_error;
eval { BLOCK: {
$block
} };
if (\$@) {
\$_tt_error = \$context->catch(\$@, \\\$output);
die \$_tt_error unless \$_tt_error->type eq 'return';
}
return \$output;
}
EOF
}
sub anon_block {
my ($class, $block) = @_;
$block = pad($block, 2) if $PRETTY;
return <<EOF;
$OUTPUT do {
my \$output = '';
my \$_tt_error;
eval { BLOCK: {
$block
} };
if (\$@) {
\$_tt_error = \$context->catch(\$@, \\\$output);
die \$_tt_error unless \$_tt_error->type eq 'return';
}
\$output;
};
EOF
}
sub block {
my ($class, $block) = @_;
return join("\n", @{ $block || [] });
}
sub textblock {
my ($class, $text) = @_;
return "$OUTPUT " . &text($class, $text) . ';';
}
sub text {
my ($class, $text) = @_;
for ($text) {
s/(["\$\@\\])/\\$1/g;
s/\n/\\n/g;
}
return '"' . $text . '"';
}
sub quoted {
my ($class, $items) = @_;
return '' unless @$items;
return ("('' . " . $items->[0] . ')') if scalar @$items == 1;
return '(' . join(' . ', @$items) . ')';
}
sub ident {
my ($class, $ident) = @_;
return "''" unless @$ident;
my $ns;
# does the first element of the identifier have a NAMESPACE
# handler defined?
if (ref $class && @$ident > 2 && ($ns = $class->{ NAMESPACE })) {
my $key = $ident->[0];
$key =~ s/^'(.+)'$/$1/s;
if ($ns = $ns->{ $key }) {
return $ns->ident($ident);
}
}
if (scalar @$ident <= 2 && ! $ident->[1]) {
$ident = $ident->[0];
}
else {
$ident = '[' . join(', ', @$ident) . ']';
}
return "\$stash->get($ident)";
}
sub identref {
my ($class, $ident) = @_;
return "''" unless @$ident;
if (scalar @$ident <= 2 && ! $ident->[1]) {
$ident = $ident->[0];
}
else {
$ident = '[' . join(', ', @$ident) . ']';
}
return "\$stash->getref($ident)";
}
sub assign {
my ($class, $var, $val, $default) = @_;
if (ref $var) {
if (scalar @$var == 2 && ! $var->[1]) {
$var = $var->[0];
}
else {
$var = '[' . join(', ', @$var) . ']';
}
}
$val .= ', 1' if $default;
return "\$stash->set($var, $val)";
}
sub args {
my ($class, $args) = @_;
my $hash = shift @$args;
push(@$args, '{ ' . join(', ', @$hash) . ' }')
if @$hash;
return '0' unless @$args;
return '[ ' . join(', ', @$args) . ' ]';
}
sub filenames {
my ($class, $names) = @_;
if (@$names > 1) {
$names = '[ ' . join(', ', @$names) . ' ]';
}
else {
$names = shift @$names;
}
return $names;
}
sub get {
my ($class, $expr) = @_;
return "$OUTPUT $expr;";
}
sub call {
my ($class, $expr) = @_;
$expr .= ';';
return $expr;
}
sub set {
my ($class, $setlist) = @_;
my $output;
while (my ($var, $val) = splice(@$setlist, 0, 2)) {
$output .= &assign($class, $var, $val) . ";\n";
}
chomp $output;
return $output;
}
sub default {
my ($class, $setlist) = @_;
my $output;
while (my ($var, $val) = splice(@$setlist, 0, 2)) {
$output .= &assign($class, $var, $val, 1) . ";\n";
}
chomp $output;
return $output;
}
sub insert {
my ($class, $nameargs) = @_;
my ($file, $args) = @$nameargs;
$file = $class->filenames($file);
return "$OUTPUT \$context->insert($file);";
}
sub include {
my ($class, $nameargs) = @_;
my ($file, $args) = @$nameargs;
my $hash = shift @$args;
$file = $class->filenames($file);
$file .= @$hash ? ', { ' . join(', ', @$hash) . ' }' : '';
return "$OUTPUT \$context->include($file);";
}
sub process {
my ($class, $nameargs) = @_;
my ($file, $args) = @$nameargs;
my $hash = shift @$args;
$file = $class->filenames($file);
$file .= @$hash ? ', { ' . join(', ', @$hash) . ' }' : '';
return "$OUTPUT \$context->process($file);";
}
sub if {
my ($class, $expr, $block, $else) = @_;
my @else = $else ? @$else : ();
$else = pop @else;
$block = pad($block, 1) if $PRETTY;
my $output = "if ($expr) {\n$block\n}\n";
foreach my $elsif (@else) {
($expr, $block) = @$elsif;
$block = pad($block, 1) if $PRETTY;
$output .= "elsif ($expr) {\n$block\n}\n";
}
if (defined $else) {
$else = pad($else, 1) if $PRETTY;
$output .= "else {\n$else\n}\n";
}
return $output;
}
sub foreach {
my ($class, $target, $list, $args, $block, $label) = @_;
$args = shift @$args;
$args = @$args ? ', { ' . join(', ', @$args) . ' }' : '';
$label ||= 'LOOP';
my ($loop_save, $loop_set, $loop_restore, $setiter);
if ($target) {
$loop_save = 'eval { $_tt_oldloop = ' . &ident($class, ["'loop'"]) . ' }';
$loop_set = "\$stash->{'$target'} = \$_tt_value";
$loop_restore = "\$stash->set('loop', \$_tt_oldloop)";
}
else {
$loop_save = '$stash = $context->localise()';
$loop_set = "\$stash->get(['import', [\$_tt_value]]) "
. "if ref \$_tt_value eq 'HASH'";
$loop_restore = '$stash = $context->delocalise()';
}
$block = pad($block, 3) if $PRETTY;
return <<EOF;
do {
my (\$_tt_value, \$_tt_error, \$_tt_oldloop);
my \$_tt_list = $list;
unless (UNIVERSAL::isa(\$_tt_list, 'Template::Iterator')) {
\$_tt_list = Template::Config->iterator(\$_tt_list)
|| die \$Template::Config::ERROR, "\\n";
}
(\$_tt_value, \$_tt_error) = \$_tt_list->get_first();
$loop_save;
\$stash->set('loop', \$_tt_list);
eval {
$label: while (! \$_tt_error) {
$loop_set;
$block;
(\$_tt_value, \$_tt_error) = \$_tt_list->get_next();
}
};
$loop_restore;
die \$@ if \$@;
\$_tt_error = 0 if \$_tt_error && \$_tt_error eq Template::Constants::STATUS_DONE;
die \$_tt_error if \$_tt_error;
};
EOF
}
sub next {
my ($class, $label) = @_;
$label ||= 'LOOP';
return <<EOF;
(\$_tt_value, \$_tt_error) = \$_tt_list->get_next();
next $label;
EOF
}
sub wrapper {
my ($class, $nameargs, $block) = @_;
my ($file, $args) = @$nameargs;
my $hash = shift @$args;
local $" = ', ';
return $class->multi_wrapper($file, $hash, $block)
if @$file > 1;
$file = shift @$file;
$block = pad($block, 1) if $PRETTY;
push(@$hash, "'content'", '$output');
$file .= @$hash ? ', { ' . join(', ', @$hash) . ' }' : '';
return <<EOF;
$OUTPUT do {
my \$output = '';
$block
\$context->include($file);
};
EOF
}
sub multi_wrapper {
my ($class, $file, $hash, $block) = @_;
$block = pad($block, 1) if $PRETTY;
push(@$hash, "'content'", '$output');
$hash = @$hash ? ', { ' . join(', ', @$hash) . ' }' : '';
$file = join(', ', reverse @$file);
return <<EOF;
$OUTPUT do {
my \$output = '';
$block
foreach ($file) {
\$output = \$context->include(\$_$hash);
}
\$output;
};
EOF
}
sub while {
my ($class, $expr, $block, $label) = @_;
$block = pad($block, 2) if $PRETTY;
$label ||= 'LOOP';
return <<EOF;
do {
my \$_tt_failsafe = $WHILE_MAX;
$label:
while (--\$_tt_failsafe && ($expr)) {
$block
}
die "WHILE loop terminated (> $WHILE_MAX iterations)\\n"
unless \$_tt_failsafe;
};
EOF
}
sub switch {
my ($class, $expr, $case) = @_;
my @case = @$case;
my ($match, $block, $default);
my $caseblock = '';
$default = pop @case;
foreach $case (@case) {
$match = $case->[0];
$block = $case->[1];
$block = pad($block, 1) if $PRETTY;
$caseblock .= <<EOF;
\$_tt_match = $match;
\$_tt_match = [ \$_tt_match ] unless ref \$_tt_match eq 'ARRAY';
if (grep(/^\\Q\$_tt_result\\E\$/, \@\$_tt_match)) {
$block
last SWITCH;
}
EOF
}
$caseblock .= $default
if defined $default;
$caseblock = pad($caseblock, 2) if $PRETTY;
return <<EOF;
do {
my \$_tt_result = $expr;
my \$_tt_match;
SWITCH: {
$caseblock
}
};
EOF
}
sub try {
my ($class, $block, $catch) = @_;
my @catch = @$catch;
my ($match, $mblock, $default, $final, $n);
my $catchblock = '';
my $handlers = [];
$block = pad($block, 2) if $PRETTY;
$final = pop @catch;
$final = "# FINAL\n" . ($final ? "$final\n" : '')
. 'die $_tt_error if $_tt_error;' . "\n" . '$output;';
$final = pad($final, 1) if $PRETTY;
$n = 0;
foreach $catch (@catch) {
$match = $catch->[0] || do {
$default ||= $catch->[1];
next;
};
$mblock = $catch->[1];
$mblock = pad($mblock, 1) if $PRETTY;
push(@$handlers, "'$match'");
$catchblock .= $n++
? "elsif (\$_tt_handler eq '$match') {\n$mblock\n}\n"
: "if (\$_tt_handler eq '$match') {\n$mblock\n}\n";
}
$catchblock .= "\$_tt_error = 0;";
$catchblock = pad($catchblock, 3) if $PRETTY;
if ($default) {
$default = pad($default, 1) if $PRETTY;
$default = "else {\n # DEFAULT\n$default\n \$_tt_error = '';\n}";
}
else {
$default = '# NO DEFAULT';
}
$default = pad($default, 2) if $PRETTY;
$handlers = join(', ', @$handlers);
return <<EOF;
$OUTPUT do {
my \$output = '';
my (\$_tt_error, \$_tt_handler);
eval {
$block
};
if (\$@) {
\$_tt_error = \$context->catch(\$@, \\\$output);
die \$_tt_error if \$_tt_error->type =~ /^return|stop\$/;
\$stash->set('error', \$_tt_error);
\$stash->set('e', \$_tt_error);
if (defined (\$_tt_handler = \$_tt_error->select_handler($handlers))) {
$catchblock
}
$default
}
$final
};
EOF
}
sub throw {
my ($class, $nameargs) = @_;
my ($type, $args) = @$nameargs;
my $hash = shift(@$args);
my $info = shift(@$args);
$type = shift @$type; # uses same parser production as INCLUDE
# etc., which allow multiple names
# e.g. INCLUDE foo+bar+baz
if (! $info) {
$args = "$type, undef";
}
elsif (@$hash || @$args) {
local $" = ', ';
my $i = 0;
$args = "$type, { args => [ "
. join(', ', $info, @$args)
. ' ], '
. join(', ',
(map { "'" . $i++ . "' => $_" } ($info, @$args)),
@$hash)
. ' }';
}
else {
$args = "$type, $info";
}
return "\$context->throw($args, \\\$output);";
}
sub clear {
return "\$output = '';";
}
sub OLD_break {
return 'last LOOP;';
}
sub return {
return "\$context->throw('return', '', \\\$output);";
}
sub stop {
return "\$context->throw('stop', '', \\\$output);";
}
sub use {
my ($class, $lnameargs) = @_;
my ($file, $args, $alias) = @$lnameargs;
$file = shift @$file; # same production rule as INCLUDE
$alias ||= $file;
$args = &args($class, $args);
$file .= ", $args" if $args;
return "# USE\n"
. "\$stash->set($alias,\n"
. " \$context->plugin($file));";
}
sub view {
my ($class, $nameargs, $block, $defblocks) = @_;
my ($name, $args) = @$nameargs;
my $hash = shift @$args;
$name = shift @$name; # same production rule as INCLUDE
$block = pad($block, 1) if $PRETTY;
if (%$defblocks) {
$defblocks = join(",\n", map { "'$_' => $defblocks->{ $_ }" }
keys %$defblocks);
$defblocks = pad($defblocks, 1) if $PRETTY;
$defblocks = "{\n$defblocks\n}";
push(@$hash, "'blocks'", $defblocks);
}
$hash = @$hash ? '{ ' . join(', ', @$hash) . ' }' : '';
return <<EOF;
do {
my \$output = '';
my \$_tt_oldv = \$stash->get('view');
my \$_tt_view = \$context->view($hash);
\$stash->set($name, \$_tt_view);
\$stash->set('view', \$_tt_view);
$block
\$stash->set('view', \$_tt_oldv);
\$_tt_view->seal();
};
EOF
}
sub perl {
my ($class, $block) = @_;
$block = pad($block, 1) if $PRETTY;
return <<EOF;
\$context->throw('perl', 'EVAL_PERL not set')
unless \$context->eval_perl();
$OUTPUT do {
my \$output = "package Template::Perl;\\n";
$block
local(\$Template::Perl::context) = \$context;
local(\$Template::Perl::stash) = \$stash;
my \$_tt_result = '';
tie *Template::Perl::PERLOUT, 'Template::TieString', \\\$_tt_result;
my \$_tt_save_stdout = select *Template::Perl::PERLOUT;
eval \$output;
select \$_tt_save_stdout;
\$context->throw(\$@) if \$@;
\$_tt_result;
};
EOF
}
sub no_perl {
my $class = shift;
return "\$context->throw('perl', 'EVAL_PERL not set');";
}
sub rawperl {
my ($class, $block, $line) = @_;
for ($block) {
s/^\n+//;
s/\n+$//;
}
$block = pad($block, 1) if $PRETTY;
$line = $line ? " (starting line $line)" : '';
return <<EOF;
$block
EOF
}
sub filter {
my ($class, $lnameargs, $block) = @_;
my ($name, $args, $alias) = @$lnameargs;
$name = shift @$name;
$args = &args($class, $args);
$args = $args ? "$args, $alias" : ", undef, $alias"
if $alias;
$name .= ", $args" if $args;
$block = pad($block, 1) if $PRETTY;
return <<EOF;
$OUTPUT do {
my \$output = '';
my \$_tt_filter = \$context->filter($name)
|| \$context->throw(\$context->error);
$block
&\$_tt_filter(\$output);
};
EOF
}
sub capture {
my ($class, $name, $block) = @_;
if (ref $name) {
if (scalar @$name == 2 && ! $name->[1]) {
$name = $name->[0];
}
else {
$name = '[' . join(', ', @$name) . ']';
}
}
$block = pad($block, 1) if $PRETTY;
return <<EOF;
\$stash->set($name, do {
my \$output = '';
$block
\$output;
});
EOF
}
sub macro {
my ($class, $ident, $block, $args) = @_;
$block = pad($block, 2) if $PRETTY;
if ($args) {
my $nargs = scalar @$args;
$args = join(', ', map { "'$_'" } @$args);
$args = $nargs > 1
? "\@_tt_args{ $args } = splice(\@_, 0, $nargs)"
: "\$_tt_args{ $args } = shift";
return <<EOF;
\$stash->set('$ident', sub {
my \$output = '';
my (%_tt_args, \$_tt_params);
$args;
\$_tt_params = shift;
\$_tt_params = { } unless ref(\$_tt_params) eq 'HASH';
\$_tt_params = { \%_tt_args, %\$_tt_params };
my \$stash = \$context->localise(\$_tt_params);
eval {
$block
};
\$stash = \$context->delocalise();
die \$@ if \$@;
return \$output;
});
EOF
}
else {
return <<EOF;
\$stash->set('$ident', sub {
my \$_tt_params = \$_[0] if ref(\$_[0]) eq 'HASH';
my \$output = '';
my \$stash = \$context->localise(\$_tt_params);
eval {
$block
};
\$stash = \$context->delocalise();
die \$@ if \$@;
return \$output;
});
EOF
}
}
sub debug {
my ($class, $nameargs) = @_;
my ($file, $args) = @$nameargs;
my $hash = shift @$args;
$args = join(', ', @$file, @$args);
$args .= @$hash ? ', { ' . join(', ', @$hash) . ' }' : '';
return "$OUTPUT \$context->debugging($args); ## DEBUG ##";
}
1;
}
#
# Inline include of Template/Parser.pm
#
BEGIN { $INC{'Template/Parser.pm'} = 'dummy/Template/Parser.pm'; }
BEGIN {
#line 0 "Template/Parser.pm"
package Template::Parser;
use strict;
use warnings;
use base 'Template::Base';
use Template::Constants qw( :status :chomp );
use Template::Directive;
use Template::Grammar;
use constant CONTINUE => 0;
use constant ACCEPT => 1;
use constant ERROR => 2;
use constant ABORT => 3;
our $VERSION = 2.89;
our $DEBUG = 0 unless defined $DEBUG;
our $ERROR = '';
our $TAG_STYLE = {
'default' => [ '\[%', '%\]' ],
'template1' => [ '[\[%]%', '%[\]%]' ],
'metatext' => [ '%%', '%%' ],
'html' => [ '<!--', '-->' ],
'mason' => [ '<%', '>' ],
'asp' => [ '<%', '%>' ],
'php' => [ '<\?', '\?>' ],
'star' => [ '\[\*', '\*\]' ],
};
$TAG_STYLE->{ template } = $TAG_STYLE->{ tt2 } = $TAG_STYLE->{ default };
our $DEFAULT_STYLE = {
START_TAG => $TAG_STYLE->{ default }->[0],
END_TAG => $TAG_STYLE->{ default }->[1],
ANYCASE => 0,
INTERPOLATE => 0,
PRE_CHOMP => 0,
POST_CHOMP => 0,
V1DOLLAR => 0,
EVAL_PERL => 0,
};
our $QUOTED_ESCAPES = {
n => "\n",
r => "\r",
t => "\t",
};
our $CHOMP_FLAGS = qr/[-=~+]/;
sub new {
my $class = shift;
my $config = $_[0] && ref($_[0]) eq 'HASH' ? shift(@_) : { @_ };
my ($tagstyle, $debug, $start, $end, $defaults, $grammar, $hash, $key, $udef);
my $self = bless {
START_TAG => undef,
END_TAG => undef,
TAG_STYLE => 'default',
ANYCASE => 0,
INTERPOLATE => 0,
PRE_CHOMP => 0,
POST_CHOMP => 0,
V1DOLLAR => 0,
EVAL_PERL => 0,
FILE_INFO => 1,
GRAMMAR => undef,
_ERROR => '',
IN_BLOCK => [ ],
FACTORY => $config->{ FACTORY } || 'Template::Directive',
}, $class;
# update self with any relevant keys in config
foreach $key (keys %$self) {
$self->{ $key } = $config->{ $key } if defined $config->{ $key };
}
$self->{ FILEINFO } = [ ];
# DEBUG config item can be a bitmask
if (defined ($debug = $config->{ DEBUG })) {
$self->{ DEBUG } = $debug & ( Template::Constants::DEBUG_PARSER
| Template::Constants::DEBUG_FLAGS );
$self->{ DEBUG_DIRS } = $debug & Template::Constants::DEBUG_DIRS;
}
# package variable can be set to 1 to support previous behaviour
elsif ($DEBUG == 1) {
$self->{ DEBUG } = Template::Constants::DEBUG_PARSER;
$self->{ DEBUG_DIRS } = 0;
}
# otherwise let $DEBUG be a bitmask
else {
$self->{ DEBUG } = $DEBUG & ( Template::Constants::DEBUG_PARSER
| Template::Constants::DEBUG_FLAGS );
$self->{ DEBUG_DIRS } = $DEBUG & Template::Constants::DEBUG_DIRS;
}
$grammar = $self->{ GRAMMAR } ||= do {
require Template::Grammar;
Template::Grammar->new();
};
# build a FACTORY object to include any NAMESPACE definitions,
# but only if FACTORY isn't already an object
if ($config->{ NAMESPACE } && ! ref $self->{ FACTORY }) {
my $fclass = $self->{ FACTORY };
$self->{ FACTORY } = $fclass->new( NAMESPACE => $config->{ NAMESPACE } )
|| return $class->error($fclass->error());
}
# load grammar rules, states and lex table
@$self{ qw( LEXTABLE STATES RULES ) }
= @$grammar{ qw( LEXTABLE STATES RULES ) };
$self->new_style($config)
|| return $class->error($self->error());
return $self;
}
sub enter_block {
my ($self, $name) = @_;
my $blocks = $self->{ IN_BLOCK };
push(@{ $self->{ IN_BLOCK } }, $name);
}
sub leave_block {
my $self = shift;
my $label = $self->block_label;
pop(@{ $self->{ IN_BLOCK } });
return $label;
}
sub in_block {
my ($self, $name) = @_;
my $blocks = $self->{ IN_BLOCK };
return @$blocks && $blocks->[-1] eq $name;
}
sub block_label {
my ($self, $prefix, $suffix) = @_;
my $blocks = $self->{ IN_BLOCK };
my $name = @$blocks
? $blocks->[-1] . scalar @$blocks
: undef;
return join('', grep { defined $_ } $prefix, $name, $suffix);
}
sub new_style {
my ($self, $config) = @_;
my $styles = $self->{ STYLE } ||= [ ];
my ($tagstyle, $tags, $start, $end, $key);
# clone new style from previous or default style
my $style = { %{ $styles->[-1] || $DEFAULT_STYLE } };
# expand START_TAG and END_TAG from specified TAG_STYLE
if ($tagstyle = $config->{ TAG_STYLE }) {
return $self->error("Invalid tag style: $tagstyle")
unless defined ($tags = $TAG_STYLE->{ $tagstyle });
($start, $end) = @$tags;
$config->{ START_TAG } ||= $start;
$config->{ END_TAG } ||= $end;
}
foreach $key (keys %$DEFAULT_STYLE) {
$style->{ $key } = $config->{ $key } if defined $config->{ $key };
}
push(@$styles, $style);
return $style;
}
sub old_style {
my $self = shift;
my $styles = $self->{ STYLE };
return $self->error('only 1 parser style remaining')
unless (@$styles > 1);
pop @$styles;
return $styles->[-1];
}
sub parse {
my ($self, $text, $info) = @_;
my ($tokens, $block);
$info->{ DEBUG } = $self->{ DEBUG_DIRS }
unless defined $info->{ DEBUG };
# store for blocks defined in the template (see define_block())
my $defblock = $self->{ DEFBLOCK } = { };
my $metadata = $self->{ METADATA } = [ ];
$self->{ DEFBLOCKS } = [ ];
$self->{ _ERROR } = '';
# split file into TEXT/DIRECTIVE chunks
$tokens = $self->split_text($text)
|| return undef; ## RETURN ##
push(@{ $self->{ FILEINFO } }, $info);
# parse chunks
$block = $self->_parse($tokens, $info);
pop(@{ $self->{ FILEINFO } });
return undef unless $block; ## RETURN ##
$self->debug("compiled main template document block:\n$block")
if $self->{ DEBUG } & Template::Constants::DEBUG_PARSER;
return {
BLOCK => $block,
DEFBLOCKS => $defblock,
METADATA => { @$metadata },
};
}
sub split_text {
my ($self, $text) = @_;
my ($pre, $dir, $prelines, $dirlines, $postlines, $chomp, $tags, @tags);
my $style = $self->{ STYLE }->[-1];
my ($start, $end, $prechomp, $postchomp, $interp ) =
@$style{ qw( START_TAG END_TAG PRE_CHOMP POST_CHOMP INTERPOLATE ) };
my $tags_dir = $self->{ANYCASE} ? qr<TAGS>i : qr<TAGS>;
my @tokens = ();
my $line = 1;
return \@tokens ## RETURN ##
unless defined $text && length $text;
# extract all directives from the text
while ($text =~ s/
^(.*?) # $1 - start of line up to directive
(?:
$start # start of tag
(.*?) # $2 - tag contents
$end # end of tag
)
//sx) {
($pre, $dir) = ($1, $2);
$pre = '' unless defined $pre;
$dir = '' unless defined $dir;
$prelines = ($pre =~ tr/\n//); # newlines in preceeding text
$dirlines = ($dir =~ tr/\n//); # newlines in directive tag
$postlines = 0; # newlines chomped after tag
for ($dir) {
if (/^\#/) {
# comment out entire directive except for any end chomp flag
$dir = ($dir =~ /($CHOMP_FLAGS)$/o) ? $1 : '';
}
else {
s/^($CHOMP_FLAGS)?\s*//so;
# PRE_CHOMP: process whitespace before tag
$chomp = $1 ? $1 : $prechomp;
$chomp =~ tr/-=~+/1230/;
if ($chomp && $pre) {
# chomp off whitespace and newline preceding directive
if ($chomp == CHOMP_ALL) {
$pre =~ s{ (\r?\n|^) [^\S\n]* \z }{}mx;
}
elsif ($chomp == CHOMP_COLLAPSE) {
$pre =~ s{ (\s+) \z }{ }x;
}
elsif ($chomp == CHOMP_GREEDY) {
$pre =~ s{ (\s+) \z }{}x;
}
}
}
# POST_CHOMP: process whitespace after tag
s/\s*($CHOMP_FLAGS)?\s*$//so;
$chomp = $1 ? $1 : $postchomp;
$chomp =~ tr/-=~+/1230/;
if ($chomp) {
if ($chomp == CHOMP_ALL) {
$text =~ s{ ^ ([^\S\n]* \n) }{}x
&& $postlines++;
}
elsif ($chomp == CHOMP_COLLAPSE) {
$text =~ s{ ^ (\s+) }{ }x
&& ($postlines += $1=~y/\n//);
}
# any trailing whitespace
elsif ($chomp == CHOMP_GREEDY) {
$text =~ s{ ^ (\s+) }{}x
&& ($postlines += $1=~y/\n//);
}
}
}
# any text preceding the directive can now be added
if (length $pre) {
push(@tokens, $interp
? [ $pre, $line, 'ITEXT' ]
: ('TEXT', $pre) );
}
$line += $prelines;
# and now the directive, along with line number information
if (length $dir) {
# the TAGS directive is a compile-time switch
if ($dir =~ /^$tags_dir\s+(.*)/) {
my @tags = split(/\s+/, $1);
if (scalar @tags > 1) {
($start, $end) = map { quotemeta($_) } @tags;
}
elsif ($tags = $TAG_STYLE->{ $tags[0] }) {
($start, $end) = @$tags;
}
else {
warn "invalid TAGS style: $tags[0]\n";
}
}
else {
# DIRECTIVE is pushed as:
# [ $dirtext, $line_no(s), \@tokens ]
push(@tokens,
[ $dir,
($dirlines
? sprintf("%d-%d", $line, $line + $dirlines)
: $line),
$self->tokenise_directive($dir) ]);
}
}
# update line counter to include directive lines and any extra
# newline chomped off the start of the following text
$line += $dirlines + $postlines;
}
# anything remaining in the string is plain text
push(@tokens, $interp
? [ $text, $line, 'ITEXT' ]
: ( 'TEXT', $text) )
if length $text;
return \@tokens; ## RETURN ##
}
sub interpolate_text {
my ($self, $text, $line) = @_;
my @tokens = ();
my ($pre, $var, $dir);
while ($text =~
/
( (?: \\. | [^\$] ){1,3000} ) # escaped or non-'$' character [$1]
|
( \$ (?: # embedded variable [$2]
(?: \{ ([^\}]*) \} ) # ${ ... } [$3]
|
([\w\.]+) # $word [$4]
)
)
/gx) {
($pre, $var, $dir) = ($1, $3 || $4, $2);
# preceding text
if (defined($pre) && length($pre)) {
$line += $pre =~ tr/\n//;
$pre =~ s/\\\$/\$/g;
push(@tokens, 'TEXT', $pre);
}
# $variable reference
if ($var) {
$line += $dir =~ tr/\n/ /;
push(@tokens, [ $dir, $line, $self->tokenise_directive($var) ]);
}
# other '$' reference - treated as text
elsif ($dir) {
$line += $dir =~ tr/\n//;
push(@tokens, 'TEXT', $dir);
}
}
return \@tokens;
}
sub tokenise_directive {
my ($self, $text, $line) = @_;
my ($token, $uctoken, $type, $lookup);
my $lextable = $self->{ LEXTABLE };
my $style = $self->{ STYLE }->[-1];
my ($anycase, $start, $end) = @$style{ qw( ANYCASE START_TAG END_TAG ) };
my @tokens = ( );
while ($text =~
/
# strip out any comments
(\#[^\n]*)
|
# a quoted phrase matches in $3
(["']) # $2 - opening quote, ' or "
( # $3 - quoted text buffer
(?: # repeat group (no backreference)
\\\\ # an escaped backslash \\
| # ...or...
\\\2 # an escaped quote \" or \' (match $1)
| # ...or...
. # any other character
| \n
)*? # non-greedy repeat
) # end of $3
\2 # match opening quote
|
# an unquoted number matches in $4
(-?\d+(?:\.\d+)?) # numbers
|
# filename matches in $5
( \/?\w+(?:(?:\/|::?)\w*)+ | \/\w+)
|
# an identifier matches in $6
(\w+) # variable identifier
|
# an unquoted word or symbol matches in $7
( [(){}\[\]:;,\/\\] # misc parenthesis and symbols
| [+\-*] # math operations
| \$\{? # dollar with option left brace
| => # like '='
| [=!<>]?= | [!<>] # eqality tests
| &&? | \|\|? # boolean ops
| \.\.? # n..n sequence
| \S+ # something unquoted
) # end of $7
/gmxo) {
# ignore comments to EOL
next if $1;
# quoted string
if (defined ($token = $3)) {
# double-quoted string may include $variable references
if ($2 eq '"') {
if ($token =~ /[\$\\]/) {
$type = 'QUOTED';
# unescape " and \ but leave \$ escaped so that
# interpolate_text() doesn't incorrectly treat it
# as a variable reference
for ($token) {
s/\\([^\$nrt])/$1/g;
s/\\([nrt])/$QUOTED_ESCAPES->{ $1 }/ge;
}
push(@tokens, ('"') x 2,
@{ $self->interpolate_text($token) },
('"') x 2);
next;
}
else {
$type = 'LITERAL';
$token =~ s['][\\']g;
$token = "'$token'";
}
}
else {
$type = 'LITERAL';
$token = "'$token'";
}
}
# number
elsif (defined ($token = $4)) {
$type = 'NUMBER';
}
elsif (defined($token = $5)) {
$type = 'FILENAME';
}
elsif (defined($token = $6)) {
# Fold potential keywords to UPPER CASE if the ANYCASE option is
# set, unless (we've got some preceeding tokens and) the previous
# token is a DOT op. This prevents the 'last' in 'data.last'
# from being interpreted as the LAST keyword.
$uctoken =
($anycase && (! @tokens || $tokens[-2] ne 'DOT'))
? uc $token
: $token;
if (defined ($type = $lextable->{ $uctoken })) {
$token = $uctoken;
}
else {
$type = 'IDENT';
}
}
elsif (defined ($token = $7)) {
# reserved words may be in lower case unless case sensitive
$uctoken = $anycase ? uc $token : $token;
unless (defined ($type = $lextable->{ $uctoken })) {
$type = 'UNQUOTED';
}
}
push(@tokens, $type, $token);
}
return \@tokens; ## RETURN ##
}
sub define_block {
my ($self, $name, $block) = @_;
my $defblock = $self->{ DEFBLOCK }
|| return undef;
$self->debug("compiled block '$name':\n$block")
if $self->{ DEBUG } & Template::Constants::DEBUG_PARSER;
$defblock->{ $name } = $block;
return undef;
}
sub push_defblock {
my $self = shift;
my $stack = $self->{ DEFBLOCK_STACK } ||= [];
push(@$stack, $self->{ DEFBLOCK } );
$self->{ DEFBLOCK } = { };
}
sub pop_defblock {
my $self = shift;
my $defs = $self->{ DEFBLOCK };
my $stack = $self->{ DEFBLOCK_STACK } || return $defs;
return $defs unless @$stack;
$self->{ DEFBLOCK } = pop @$stack;
return $defs;
}
sub add_metadata {
my ($self, $setlist) = @_;
my $metadata = $self->{ METADATA }
|| return undef;
push(@$metadata, @$setlist);
return undef;
}
sub location {
my $self = shift;
return "\n" unless $self->{ FILE_INFO };
my $line = ${ $self->{ LINE } };
my $info = $self->{ FILEINFO }->[-1];
my $file = $info->{ path } || $info->{ name }
|| '(unknown template)';
$line =~ s/\-.*$//; # might be 'n-n'
$line ||= 1;
return "#line $line \"$file\"\n";
}
sub _parse {
my ($self, $tokens, $info) = @_;
my ($token, $value, $text, $line, $inperl);
my ($state, $stateno, $status, $action, $lookup, $coderet, @codevars);
my ($lhs, $len, $code); # rule contents
my $stack = [ [ 0, undef ] ]; # DFA stack
# retrieve internal rule and state tables
my ($states, $rules) = @$self{ qw( STATES RULES ) };
# call the grammar set_factory method to install emitter factory
$self->{ GRAMMAR }->install_factory($self->{ FACTORY });
$line = $inperl = 0;
$self->{ LINE } = \$line;
$self->{ FILE } = $info->{ name };
$self->{ INPERL } = \$inperl;
$status = CONTINUE;
my $in_string = 0;
while(1) {
# get state number and state
$stateno = $stack->[-1]->[0];
$state = $states->[$stateno];
# see if any lookaheads exist for the current state
if (exists $state->{'ACTIONS'}) {
# get next token and expand any directives (i.e. token is an
# array ref) onto the front of the token list
while (! defined $token && @$tokens) {
$token = shift(@$tokens);
if (ref $token) {
($text, $line, $token) = @$token;
if (ref $token) {
if ($info->{ DEBUG } && ! $in_string) {
# - - - - - - - - - - - - - - - - - - - - - - - - -
# This is gnarly. Look away now if you're easily
# frightened. We're pushing parse tokens onto the
# pending list to simulate a DEBUG directive like so:
# [% DEBUG msg line='20' text='INCLUDE foo' %]
# - - - - - - - - - - - - - - - - - - - - - - - - -
my $dtext = $text;
$dtext =~ s[(['\\])][\\$1]g;
unshift(@$tokens,
DEBUG => 'DEBUG',
IDENT => 'msg',
IDENT => 'line',
ASSIGN => '=',
LITERAL => "'$line'",
IDENT => 'text',
ASSIGN => '=',
LITERAL => "'$dtext'",
IDENT => 'file',
ASSIGN => '=',
LITERAL => "'$info->{ name }'",
(';') x 2,
@$token,
(';') x 2);
}
else {
unshift(@$tokens, @$token, (';') x 2);
}
$token = undef; # force redo
}
elsif ($token eq 'ITEXT') {
if ($inperl) {
# don't perform interpolation in PERL blocks
$token = 'TEXT';
$value = $text;
}
else {
unshift(@$tokens,
@{ $self->interpolate_text($text, $line) });
$token = undef; # force redo
}
}
}
else {
# toggle string flag to indicate if we're crossing
# a string boundary
$in_string = ! $in_string if $token eq '"';
$value = shift(@$tokens);
}
};
# clear undefined token to avoid 'undefined variable blah blah'
# warnings and let the parser logic pick it up in a minute
$token = '' unless defined $token;
# get the next state for the current lookahead token
$action = defined ($lookup = $state->{'ACTIONS'}->{ $token })
? $lookup
: defined ($lookup = $state->{'DEFAULT'})
? $lookup
: undef;
}
else {
# no lookahead actions
$action = $state->{'DEFAULT'};
}
# ERROR: no ACTION
last unless defined $action;
# - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# shift (+ive ACTION)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if ($action > 0) {
push(@$stack, [ $action, $value ]);
$token = $value = undef;
redo;
};
# - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# reduce (-ive ACTION)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - -
($lhs, $len, $code) = @{ $rules->[ -$action ] };
# no action imples ACCEPTance
$action
or $status = ACCEPT;
# use dummy sub if code ref doesn't exist
$code = sub { $_[1] }
unless $code;
@codevars = $len
? map { $_->[1] } @$stack[ -$len .. -1 ]
: ();
eval {
$coderet = &$code( $self, @codevars );
};
if ($@) {
my $err = $@;
chomp $err;
return $self->_parse_error($err);
}
# reduce stack by $len
splice(@$stack, -$len, $len);
# ACCEPT
return $coderet ## RETURN ##
if $status == ACCEPT;
# ABORT
return undef ## RETURN ##
if $status == ABORT;
# ERROR
last
if $status == ERROR;
}
continue {
push(@$stack, [ $states->[ $stack->[-1][0] ]->{'GOTOS'}->{ $lhs },
$coderet ]),
}
# ERROR ## RETURN ##
return $self->_parse_error('unexpected end of input')
unless defined $value;
# munge text of last directive to make it readable
return $self->_parse_error("unexpected end of directive", $text)
if $value eq ';'; # end of directive SEPARATOR
return $self->_parse_error("unexpected token ($value)", $text);
}
sub _parse_error {
my ($self, $msg, $text) = @_;
my $line = $self->{ LINE };
$line = ref($line) ? $$line : $line;
$line = 'unknown' unless $line;
$msg .= "\n [% $text %]"
if defined $text;
return $self->error("line $line: $msg");
}
sub _dump {
my $self = shift;
my $output = "[Template::Parser] {\n";
my $format = " %-16s => %s\n";
my $key;
foreach $key (qw( START_TAG END_TAG TAG_STYLE ANYCASE INTERPOLATE
PRE_CHOMP POST_CHOMP V1DOLLAR )) {
my $val = $self->{ $key };
$val = '<undef>' unless defined $val;
$output .= sprintf($format, $key, $val);
}
$output .= '}';
return $output;
}
1;
}
#
# Inline include of Jemplate/Directive.pm
#
BEGIN { $INC{'Jemplate/Directive.pm'} = 'dummy/Jemplate/Directive.pm'; }
BEGIN {
#line 0 "Jemplate/Directive.pm"
package Jemplate::Directive;
use strict;
use warnings;
our $OUTPUT = 'output +=';
our $WHILE_MAX = 1000;
our $INJAVASCRIPT = 0;
sub template {
my ($class, $block) = @_;
return "function() { return ''; }" unless $block =~ /\S/;
return <<"...";
function(context) {
if (! context) throw('Jemplate function called without context\\n');
var stash = context.stash;
var output = '';
try {
$block
}
catch(e) {
var error = context.set_error(e, output);
throw(error);
}
return output;
}
...
}
sub _attempt_range_expand_val ($) {
my $val = shift;
return $val unless
my ( $from, $to ) = $val =~ m/\s*\[\s*(\S+)\s*\.\.\s*(\S+)\s*\]/;
die "Range expansion is current supported for positive/negative integer values only (e.g. [ 1 .. 10 ])\nCannot expand: $val" unless $from =~ m/^-?\d+$/ && $to =~ m/^-?\d+$/;
return join '', '[', join( ',', $from .. $to ), ']';
}
sub textblock {
my ($class, $text) = @_;
return $text if $INJAVASCRIPT;
return "$OUTPUT " . $class->text($text) . ';';
}
sub text {
my ($class, $text) = @_;
for ($text) {
s/([\'\\])/\\$1/g;
s/\n/\\n/g;
s/\r/\\r/g;
}
return "'" . $text . "'";
}
sub ident {
my ($class, $ident) = @_;
return "''" unless @$ident;
my $ns;
# does the first element of the identifier have a NAMESPACE
# handler defined?
if (ref $class && @$ident > 2 && ($ns = $class->{ NAMESPACE })) {
my $key = $ident->[0];
$key =~ s/^'(.+)'$/$1/s;
if ($ns = $ns->{ $key }) {
return $ns->ident($ident);
}
}
if (scalar @$ident <= 2 && ! $ident->[1]) {
$ident = $ident->[0];
}
else {
$ident = '[' . join(', ', @$ident) . ']';
}
return "stash.get($ident)";
}
sub assign {
my ($class, $var, $val, $default) = @_;
if (ref $var) {
if (scalar @$var == 2 && ! $var->[1]) {
$var = $var->[0];
}
else {
$var = '[' . join(', ', @$var) . ']';
}
}
$val = _attempt_range_expand_val $val;
$val .= ', 1' if $default;
return "stash.set($var, $val)";
}
sub args {
my ($class, $args) = @_;
my $hash = shift @$args;
push(@$args, '{ ' . join(', ', @$hash) . ' }')
if @$hash;
return '[]' unless @$args;
return '[ ' . join(', ', @$args) . ' ]';
}
sub filenames {
my ($class, $names) = @_;
if (@$names > 1) {
$names = '[ ' . join(', ', @$names) . ' ]';
}
else {
$names = shift @$names;
}
return $names;
}
sub get {
my ($class, $expr) = @_;
return "$OUTPUT $expr;";
}
sub block {
my ($class, $block) = @_;
return join "\n", map {
s/^#(?=line \d+)/\/\//gm;
$_;
} @{ $block || [] };
}
sub call {
my ($class, $expr) = @_;
$expr .= ';';
return $expr;
}
sub set {
my ($class, $setlist) = @_;
my $output;
while (my ($var, $val) = splice(@$setlist, 0, 2)) {
$output .= $class->assign($var, $val) . ";\n";
}
chomp $output;
return $output;
}
sub default {
my ($class, $setlist) = @_;
my $output;
while (my ($var, $val) = splice(@$setlist, 0, 2)) {
$output .= &assign($class, $var, $val, 1) . ";\n";
}
chomp $output;
return $output;
}
sub include {
my ($class, $nameargs) = @_;
my ($file, $args) = @$nameargs;
my $hash = shift @$args;
$file = $class->filenames($file);
$file .= @$hash ? ', { ' . join(', ', @$hash) . ' }' : '';
return "$OUTPUT context.include($file);";
}
sub process {
my ($class, $nameargs) = @_;
my ($file, $args) = @$nameargs;
my $hash = shift @$args;
$file = $class->filenames($file);
$file .= @$hash ? ', { ' . join(', ', @$hash) . ' }' : '';
return "$OUTPUT context.process($file);";
}
sub if {
my ($class, $expr, $block, $else) = @_;
my @else = $else ? @$else : ();
$else = pop @else;
my $output = "if ($expr) {\n$block\n}\n";
foreach my $elsif (@else) {
($expr, $block) = @$elsif;
$output .= "else if ($expr) {\n$block\n}\n";
}
if (defined $else) {
$output .= "else {\n$else\n}\n";
}
return $output;
}
sub foreach {
my ($class, $target, $list, $args, $block) = @_;
$args = shift @$args;
$args = @$args ? ', { ' . join(', ', @$args) . ' }' : '';
my ($loop_save, $loop_set, $loop_restore, $setiter);
if ($target) {
$loop_save =
'try { oldloop = ' . $class->ident(["'loop'"]) . ' } finally {}';
$loop_set = "stash.data['$target'] = value";
$loop_restore = "stash.set('loop', oldloop)";
}
else {
die "XXX - Not supported yet";
$loop_save = 'stash = context.localise()';
$loop_set =
"stash.get(['import', [value]]) if typeof(value) == 'object'";
$loop_restore = 'stash = context.delocalise()';
}
$list = _attempt_range_expand_val $list;
return <<EOF;
// FOREACH
(function() {
var list = $list;
list = new Jemplate.Iterator(list);
var retval = list.get_first();
var value = retval[0];
var done = retval[1];
var oldloop;
$loop_save
stash.set('loop', list);
try {
while (! done) {
$loop_set;
$block;
retval = list.get_next();
value = retval[0];
done = retval[1];
}
}
catch(e) {
throw(context.set_error(e, output));
}
$loop_restore;
})();
EOF
}
sub next {
return <<EOF;
retval = list.get_next();
value = retval[0];
done = retval[1];
continue;
EOF
}
sub wrapper {
my ($class, $nameargs, $block) = @_;
my ($file, $args) = @$nameargs;
my $hash = shift @$args;
s/ => /: / for @$hash;
return $class->multi_wrapper($file, $hash, $block)
if @$file > 1;
$file = shift @$file;
push(@$hash, "'content': output");
$file .= @$hash ? ', { ' . join(', ', @$hash) . ' }' : '';
return <<EOF;
// WRAPPER
$OUTPUT (function() {
var output = '';
$block;
return context.include($file);
})();
EOF
}
sub multi_wrapper {
my ($class, $file, $hash, $block) = @_;
push(@$hash, "'content': output");
$hash = @$hash ? ', { ' . join(', ', @$hash) . ' }' : '';
$file = join(', ', reverse @$file);
return <<EOF;
// WRAPPER
$OUTPUT (function() {
var output = '';
$block;
var files = new Array($file);
for (var i = 0; i < files.length; i++) {
output = context.include(files[i]$hash);
}
return output;
})();
EOF
}
sub while {
my ($class, $expr, $block) = @_;
return <<EOF;
// WHILE
var failsafe = $WHILE_MAX;
while (--failsafe && ($expr)) {
$block
}
if (! failsafe)
throw("WHILE loop terminated (> $WHILE_MAX iterations)\\n")
EOF
}
sub javascript {
my ( $class, $javascript ) = @_;
return $javascript;
}
sub no_javascript {
my ( $class ) = @_;
die "EVAL_JAVASCRIPT has not been enabled, cannot process [% JAVASCRIPT %] blocks";
}
sub switch {
my ($class, $expr, $case) = @_;
my @case = @$case;
my ($match, $block, $default);
my $caseblock = '';
$default = pop @case;
foreach $case (@case) {
$match = $case->[0];
$block = $case->[1];
$caseblock .= <<EOF;
case $match:
$block
break;
EOF
}
if (defined $default) {
$caseblock .= <<EOF;
default:
$default
break;
EOF
}
return <<EOF;
switch($expr) {
$caseblock
}
EOF
}
sub throw {
my ($class, $nameargs) = @_;
my ($type, $args) = @$nameargs;
my $hash = shift(@$args);
my $info = shift(@$args);
$type = shift @$type;
return qq{throw([$type, $info]);};
}
sub clear {
return "output = '';";
}
sub break {
return 'break;';
}
sub return {
return "return output;"
}
sub stop {
return "throw('Jemplate.STOP\\n' + output);";
}
sub use {
my ($class, $lnameargs) = @_;
my ($file, $args, $alias) = @$lnameargs;
$file = shift @$file; # same production rule as INCLUDE
$alias ||= $file;
$args = &args($class, $args);
$file .= ", $args" if $args;
return "// USE\n"
. "stash.set($alias, context.plugin($file));";
}
sub raw {
my ($class, $lnameargs) = @_;
my ($file, $args, $alias) = @$lnameargs;
$file = shift @$file; # same production rule as INCLUDE
$alias ||= $file;
$args = &args($class, $args);
$file =~ s/'|"//g;
return "// RAW\n"
. "stash.set($alias, $file);";
}
sub filter {
my ($class, $lnameargs, $block) = @_;
my ($name, $args, $alias) = @$lnameargs;
$name = shift @$name;
$args = &args($class, $args);
$args = $args ? "$args, $alias" : ", null, $alias"
if $alias;
$name .= ", $args" if $args;
return <<EOF;
// FILTER
$OUTPUT (function() {
var output = '';
$block
return context.filter(output, $name);
})();
EOF
}
sub quoted {
my $class = shift;
if ( @_ && ref($_[0]) ) {
return join( " + ", @{$_[0]} );
}
return "throw('QUOTED called with unknown arguments in Jemplate');";
}
sub macro {
my ($class, $ident, $block, $args) = @_;
if ($args) {
$args = join(';', map { "args['$_'] = fargs.shift()" } @$args);
return <<EOF;
//MACRO
stash.set('$ident', function () {
var output = '';
var args = {};
var fargs = Array.prototype.slice.call(arguments);
$args;
args.arguments = Array.prototype.slice.call(arguments);
var params = fargs.shift() || {};
for (var key in params) {
args[key] = params[key];
}
context.stash.clone(args);
try {
$block
}
catch(e) {
var error = context.set_error(e, output);
throw(error);
}
context.stash.declone();
return output;
});
EOF
}
else {
return <<EOF;
//MACRO
stash.set('$ident', function () {
var output = '';
var args = {};
var fargs = Array.prototype.slice.call(arguments);
args.arguments = Array.prototype.slice.call(arguments);
if (typeof arguments[0] == 'object') args = arguments[0];
context.stash.clone(args);
try {
$block
}
catch(e) {
var error = context.set_error(e, output);
throw(error);
}
context.stash.declone();
return output;});
EOF
}
}
sub capture {
my ($class, $name, $block) = @_;
if (ref $name) {
if (scalar @$name == 2 && ! $name->[1]) {
$name = $name->[0];
}
else {
$name = '[' . join(', ', @$name) . ']';
}
}
return <<EOF;
// CAPTURE
(function() {
var output = '';
$block
stash.set($name, output);
})();
EOF
}
BEGIN {
return; # Comment out this line to get callback traces
no strict 'refs';
my $pkg = __PACKAGE__ . '::';
my $stash = \ %$pkg;
use strict 'refs';
for my $name (keys %$stash) {
my $glob = $stash->{$name};
if (*$glob{CODE}) {
my $code = *$glob{CODE};
no warnings 'redefine';
$stash->{$name} = sub {
warn "Calling $name(@_)\n";
&$code(@_);
};
}
}
}
1;
}
#
# Inline include of Jemplate/Grammar.pm
#
BEGIN { $INC{'Jemplate/Grammar.pm'} = 'dummy/Jemplate/Grammar.pm'; }
BEGIN {
#line 0 "Jemplate/Grammar.pm"
package Jemplate::Grammar;
require 5.004;
use strict;
use vars qw( $VERSION );
$VERSION = sprintf("%d.%02d", q$Revision: 2.10 $ =~ /(\d+)\.(\d+)/);
my (@RESERVED, %CMPOP, $LEXTABLE, $RULES, $STATES);
my ($factory, $rawstart);
@RESERVED = qw(
GET CALL SET DEFAULT INSERT INCLUDE PROCESS WRAPPER BLOCK END
USE RAW PLUGIN FILTER MACRO JAVASCRIPT TO STEP AND OR NOT DIV MOD
IF UNLESS ELSE ELSIF FOR NEXT WHILE SWITCH CASE META IN
TRY THROW CATCH FINAL LAST RETURN STOP CLEAR VIEW DEBUG
);
%CMPOP = qw(
!= !=
== ==
< <
> >
>= >=
<= <=
);
$LEXTABLE = {
'FOREACH' => 'FOR',
'BREAK' => 'LAST',
'&&' => 'AND',
'||' => 'OR',
'!' => 'NOT',
'|' => 'FILTER',
'.' => 'DOT',
'_' => 'CAT',
'..' => 'TO',
'=' => 'ASSIGN',
'=>' => 'ASSIGN',
',' => 'COMMA',
'\\' => 'REF',
'and' => 'AND', # explicitly specified so that qw( and or
'or' => 'OR', # not ) can always be used in lower case,
'not' => 'NOT', # regardless of ANYCASE flag
'mod' => 'MOD',
'div' => 'DIV',
};
{
my @tokens = qw< ( ) [ ] { } ${ $ + / ; : ? >;
my @cmpop = keys %CMPOP;
my @binop = qw( - * % ); # '+' and '/' above, in @tokens
# fill lexer table, slice by slice, with reserved words and operators
@$LEXTABLE{ @RESERVED, @cmpop, @binop, @tokens }
= ( @RESERVED, ('CMPOP') x @cmpop, ('BINOP') x @binop, @tokens );
}
sub new {
my $class = shift;
bless {
LEXTABLE => $LEXTABLE,
STATES => $STATES,
RULES => $RULES,
}, $class;
}
sub install_factory {
my ($self, $new_factory) = @_;
$factory = $new_factory;
}
$STATES = [
{#State 0
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'loop' => 5,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'atomdir' => 13,
'anonblock' => 51,
'template' => 53,
'defblockname' => 14,
'ident' => 16,
'assign' => 19,
'macro' => 20,
'lterm' => 58,
'node' => 23,
'term' => 60,
'expr' => 64,
'use' => 65,
'defblock' => 68,
'filter' => 30,
'sterm' => 70,
'chunks' => 34,
'setlist' => 72,
'try' => 36,
'switch' => 35,
'directive' => 73,
'block' => 74,
'raw' => 39,
'condition' => 75
}
},
{#State 1
ACTIONS => {
"\$" => 44,
'LITERAL' => 77,
'IDENT' => 2,
"\${" => 38
},
GOTOS => {
'setlist' => 78,
'item' => 41,
'assign' => 19,
'node' => 23,
'ident' => 76
}
},
{#State 2
DEFAULT => -131
},
{#State 3
DEFAULT => -26
},
{#State 4
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 81,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 5
DEFAULT => -24
},
{#State 6
ACTIONS => {
";" => 82
}
},
{#State 7
DEFAULT => -39
},
{#State 8
DEFAULT => -15
},
{#State 9
ACTIONS => {
"\"" => 91,
"\$" => 88,
'LITERAL' => 90,
'FILENAME' => 85,
'IDENT' => 83,
'NUMBER' => 86
},
GOTOS => {
'filepart' => 89,
'names' => 93,
'nameargs' => 92,
'filename' => 87,
'name' => 84
}
},
{#State 10
ACTIONS => {
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"]" => 96,
"\${" => 38
},
GOTOS => {
'sterm' => 98,
'item' => 41,
'range' => 95,
'node' => 23,
'ident' => 79,
'term' => 97,
'lterm' => 58,
'list' => 94
}
},
{#State 11
ACTIONS => {
";" => 99
}
},
{#State 12
DEFAULT => -5
},
{#State 13
ACTIONS => {
";" => -21
},
DEFAULT => -29
},
{#State 14
ACTIONS => {
'IDENT' => 100
},
DEFAULT => -88,
GOTOS => {
'blockargs' => 103,
'metadata' => 102,
'meta' => 101
}
},
{#State 15
ACTIONS => {
'IDENT' => 100
},
GOTOS => {
'metadata' => 104,
'meta' => 101
}
},
{#State 16
ACTIONS => {
'DOT' => 105,
'ASSIGN' => 106
},
DEFAULT => -110
},
{#State 17
ACTIONS => {
"\"" => 91,
"\$" => 88,
'LITERAL' => 90,
'FILENAME' => 85,
'IDENT' => 83,
'NUMBER' => 86
},
GOTOS => {
'filepart' => 89,
'names' => 93,
'nameargs' => 107,
'filename' => 87,
'name' => 84
}
},
{#State 18
ACTIONS => {
'IDENT' => 108
}
},
{#State 19
DEFAULT => -150
},
{#State 20
DEFAULT => -12
},
{#State 21
ACTIONS => {
"{" => 31,
'LITERAL' => 80,
'IDENT' => 109,
"\"" => 62,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'sterm' => 70,
'item' => 41,
'loopvar' => 111,
'node' => 23,
'ident' => 79,
'term' => 110,
'lterm' => 58
}
},
{#State 22
DEFAULT => -42
},
{#State 23
DEFAULT => -128
},
{#State 24
DEFAULT => -6
},
{#State 25
ACTIONS => {
"\"" => 118,
"\$" => 115,
'LITERAL' => 117,
'FILENAME' => 85,
'IDENT' => 112,
'NUMBER' => 86,
"\${" => 38
},
GOTOS => {
'names' => 93,
'lvalue' => 113,
'item' => 114,
'name' => 84,
'filepart' => 89,
'filename' => 87,
'nameargs' => 119,
'lnameargs' => 116
}
},
{#State 26
DEFAULT => -114
},
{#State 27
ACTIONS => {
"\$" => 44,
'IDENT' => 2,
"\${" => 38
},
GOTOS => {
'item' => 41,
'node' => 23,
'ident' => 120
}
},
{#State 28
ACTIONS => {
"\"" => 118,
"\$" => 115,
'LITERAL' => 117,
'FILENAME' => 85,
'IDENT' => 112,
'NUMBER' => 86,
"\${" => 38
},
GOTOS => {
'names' => 93,
'lvalue' => 113,
'item' => 114,
'name' => 84,
'filepart' => 89,
'filename' => 87,
'nameargs' => 119,
'lnameargs' => 121
}
},
{#State 29
ACTIONS => {
'LITERAL' => 126,
'FILENAME' => 85,
'IDENT' => 122,
'NUMBER' => 86
},
DEFAULT => -88,
GOTOS => {
'blockargs' => 125,
'filepart' => 89,
'filename' => 124,
'blockname' => 123,
'metadata' => 102,
'meta' => 101
}
},
{#State 30
DEFAULT => -45
},
{#State 31
ACTIONS => {
"\$" => 44,
'LITERAL' => 131,
'IDENT' => 2,
"\${" => 38
},
DEFAULT => -120,
GOTOS => {
'params' => 130,
'hash' => 127,
'item' => 128,
'param' => 129
}
},
{#State 32
DEFAULT => -27
},
{#State 33
ACTIONS => {
"\"" => 118,
"\$" => 115,
'LITERAL' => 117,
'FILENAME' => 85,
'IDENT' => 112,
'NUMBER' => 86,
"\${" => 38
},
GOTOS => {
'names' => 93,
'lvalue' => 113,
'item' => 114,
'name' => 84,
'filepart' => 89,
'filename' => 87,
'nameargs' => 119,
'lnameargs' => 132
}
},
{#State 34
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -2,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 133,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'try' => 36,
'switch' => 35,
'assign' => 19,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 35
DEFAULT => -23
},
{#State 36
DEFAULT => -25
},
{#State 37
ACTIONS => {
"\"" => 91,
"\$" => 88,
'LITERAL' => 90,
'FILENAME' => 85,
'IDENT' => 83,
'NUMBER' => 86
},
GOTOS => {
'filepart' => 89,
'names' => 93,
'nameargs' => 134,
'filename' => 87,
'name' => 84
}
},
{#State 38
ACTIONS => {
"\"" => 62,
"\$" => 44,
'LITERAL' => 80,
'IDENT' => 2,
'REF' => 27,
'NUMBER' => 26,
"\${" => 38
},
GOTOS => {
'sterm' => 135,
'item' => 41,
'node' => 23,
'ident' => 79
}
},
{#State 39
DEFAULT => -14
},
{#State 40
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 136,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 41
ACTIONS => {
"(" => 137
},
DEFAULT => -129
},
{#State 42
DEFAULT => -40
},
{#State 43
DEFAULT => -11
},
{#State 44
ACTIONS => {
'IDENT' => 138
}
},
{#State 45
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 139,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 46
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 140,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 47
DEFAULT => -44
},
{#State 48
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 141,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 49
ACTIONS => {
'IF' => 145,
'FILTER' => 144,
'FOR' => 143,
'WHILE' => 147,
'WRAPPER' => 146,
'UNLESS' => 142
}
},
{#State 50
DEFAULT => -41
},
{#State 51
DEFAULT => -10
},
{#State 52
ACTIONS => {
"\"" => 91,
"\$" => 88,
'LITERAL' => 90,
'FILENAME' => 85,
'IDENT' => 83,
'NUMBER' => 86
},
GOTOS => {
'filepart' => 89,
'names' => 93,
'nameargs' => 148,
'filename' => 87,
'name' => 84
}
},
{#State 53
ACTIONS => {
'' => 149
}
},
{#State 54
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 59,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 152,
'sterm' => 70,
'item' => 41,
'assign' => 151,
'node' => 23,
'ident' => 150,
'term' => 60,
'lterm' => 58
}
},
{#State 55
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 153,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 56
ACTIONS => {
";" => 154
}
},
{#State 57
ACTIONS => {
"\"" => 91,
"\$" => 88,
'LITERAL' => 90,
'FILENAME' => 85,
'IDENT' => 83,
'NUMBER' => 86
},
GOTOS => {
'filepart' => 89,
'names' => 93,
'nameargs' => 155,
'filename' => 87,
'name' => 84
}
},
{#State 58
DEFAULT => -104
},
{#State 59
ACTIONS => {
'ASSIGN' => 156
},
DEFAULT => -113
},
{#State 60
DEFAULT => -147
},
{#State 61
DEFAULT => -16
},
{#State 62
DEFAULT => -177,
GOTOS => {
'quoted' => 157
}
},
{#State 63
ACTIONS => {
"\"" => 91,
"\$" => 88,
'LITERAL' => 90,
'FILENAME' => 85,
'IDENT' => 83,
'NUMBER' => 86
},
GOTOS => {
'filepart' => 89,
'names' => 93,
'nameargs' => 158,
'filename' => 87,
'name' => 84
}
},
{#State 64
ACTIONS => {
";" => -17,
"+" => 159,
'CAT' => 165,
'CMPOP' => 166,
"?" => 160,
'DIV' => 161,
'MOD' => 167,
"/" => 168,
'AND' => 162,
'BINOP' => 163,
'OR' => 164
},
DEFAULT => -28
},
{#State 65
DEFAULT => -13
},
{#State 66
DEFAULT => -38
},
{#State 67
ACTIONS => {
"\"" => 91,
"\$" => 88,
'LITERAL' => 90,
'FILENAME' => 85,
'IDENT' => 83,
'NUMBER' => 86
},
GOTOS => {
'filepart' => 89,
'names' => 93,
'nameargs' => 169,
'filename' => 87,
'name' => 84
}
},
{#State 68
DEFAULT => -9
},
{#State 69
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 170,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 70
DEFAULT => -105
},
{#State 71
ACTIONS => {
"\$" => 44,
'LITERAL' => 77,
'IDENT' => 2,
"\${" => 38
},
GOTOS => {
'setlist' => 171,
'item' => 41,
'assign' => 19,
'node' => 23,
'ident' => 76
}
},
{#State 72
ACTIONS => {
"\$" => 44,
'COMMA' => 173,
'LITERAL' => 77,
'IDENT' => 2,
"\${" => 38
},
DEFAULT => -20,
GOTOS => {
'item' => 41,
'assign' => 172,
'node' => 23,
'ident' => 76
}
},
{#State 73
DEFAULT => -8
},
{#State 74
DEFAULT => -1
},
{#State 75
DEFAULT => -22
},
{#State 76
ACTIONS => {
'ASSIGN' => 174,
'DOT' => 105
}
},
{#State 77
ACTIONS => {
'ASSIGN' => 156
}
},
{#State 78
ACTIONS => {
'COMMA' => 173,
'LITERAL' => 77,
'IDENT' => 2,
"\$" => 44,
"\${" => 38
},
DEFAULT => -32,
GOTOS => {
'item' => 41,
'assign' => 172,
'node' => 23,
'ident' => 76
}
},
{#State 79
ACTIONS => {
'DOT' => 105
},
DEFAULT => -110
},
{#State 80
DEFAULT => -113
},
{#State 81
ACTIONS => {
'CMPOP' => 166,
"?" => 160,
";" => 175,
"+" => 159,
'MOD' => 167,
'DIV' => 161,
"/" => 168,
'AND' => 162,
'CAT' => 165,
'BINOP' => 163,
'OR' => 164
}
},
{#State 82
DEFAULT => -7
},
{#State 83
DEFAULT => -174
},
{#State 84
DEFAULT => -167
},
{#State 85
DEFAULT => -173
},
{#State 86
DEFAULT => -175
},
{#State 87
ACTIONS => {
'DOT' => 176
},
DEFAULT => -169
},
{#State 88
ACTIONS => {
"\$" => 44,
'IDENT' => 2,
"\${" => 38
},
GOTOS => {
'item' => 41,
'node' => 23,
'ident' => 177
}
},
{#State 89
DEFAULT => -172
},
{#State 90
DEFAULT => -170
},
{#State 91
DEFAULT => -177,
GOTOS => {
'quoted' => 178
}
},
{#State 92
DEFAULT => -37
},
{#State 93
ACTIONS => {
"+" => 179,
"(" => 180
},
DEFAULT => -157,
GOTOS => {
'args' => 181
}
},
{#State 94
ACTIONS => {
"{" => 31,
'COMMA' => 184,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"]" => 182,
"\${" => 38
},
GOTOS => {
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 183,
'lterm' => 58
}
},
{#State 95
ACTIONS => {
"]" => 185
}
},
{#State 96
DEFAULT => -108
},
{#State 97
DEFAULT => -117
},
{#State 98
ACTIONS => {
'TO' => 186
},
DEFAULT => -105
},
{#State 99
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 187,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 100
ACTIONS => {
'ASSIGN' => 188
}
},
{#State 101
DEFAULT => -100
},
{#State 102
ACTIONS => {
'COMMA' => 190,
'IDENT' => 100
},
DEFAULT => -87,
GOTOS => {
'meta' => 189
}
},
{#State 103
ACTIONS => {
";" => 191
}
},
{#State 104
ACTIONS => {
'COMMA' => 190,
'IDENT' => 100
},
DEFAULT => -18,
GOTOS => {
'meta' => 189
}
},
{#State 105
ACTIONS => {
"\$" => 44,
'IDENT' => 2,
'NUMBER' => 193,
"\${" => 38
},
GOTOS => {
'item' => 41,
'node' => 192
}
},
{#State 106
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
'FOR' => 21,
'NEXT' => 22,
'LITERAL' => 59,
"\"" => 62,
'PROCESS' => 63,
'FILTER' => 25,
'RETURN' => 66,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'BLOCK' => 194,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
"\${" => 38
},
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'expr' => 196,
'wrapper' => 47,
'atomexpr' => 49,
'atomdir' => 13,
'mdir' => 195,
'filter' => 30,
'sterm' => 70,
'ident' => 150,
'setlist' => 72,
'try' => 36,
'switch' => 35,
'assign' => 19,
'directive' => 197,
'condition' => 75,
'lterm' => 58
}
},
{#State 107
DEFAULT => -35
},
{#State 108
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'INCLUDE' => 17,
"(" => 199,
'SWITCH' => 55,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
'FOR' => 21,
'NEXT' => 22,
'LITERAL' => 59,
"\"" => 62,
'PROCESS' => 63,
'FILTER' => 25,
'RETURN' => 66,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'BLOCK' => 194,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
"\${" => 38
},
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'expr' => 200,
'wrapper' => 47,
'atomexpr' => 49,
'atomdir' => 13,
'mdir' => 198,
'filter' => 30,
'sterm' => 70,
'ident' => 150,
'setlist' => 72,
'try' => 36,
'switch' => 35,
'assign' => 19,
'directive' => 197,
'condition' => 75,
'lterm' => 58
}
},
{#State 109
ACTIONS => {
'IN' => 202,
'ASSIGN' => 201
},
DEFAULT => -131
},
{#State 110
DEFAULT => -157,
GOTOS => {
'args' => 203
}
},
{#State 111
ACTIONS => {
";" => 204
}
},
{#State 112
ACTIONS => {
'ASSIGN' => -131
},
DEFAULT => -174
},
{#State 113
ACTIONS => {
'ASSIGN' => 205
}
},
{#State 114
DEFAULT => -160
},
{#State 115
ACTIONS => {
"\$" => 44,
'IDENT' => 206,
"\${" => 38
},
GOTOS => {
'item' => 41,
'node' => 23,
'ident' => 177
}
},
{#State 116
ACTIONS => {
";" => 207
}
},
{#State 117
ACTIONS => {
'ASSIGN' => -162
},
DEFAULT => -170
},
{#State 118
DEFAULT => -177,
GOTOS => {
'quoted' => 208
}
},
{#State 119
DEFAULT => -159
},
{#State 120
ACTIONS => {
'DOT' => 105
},
DEFAULT => -111
},
{#State 121
DEFAULT => -76
},
{#State 122
ACTIONS => {
'ASSIGN' => 188
},
DEFAULT => -174
},
{#State 123
DEFAULT => -84
},
{#State 124
ACTIONS => {
'DOT' => 176
},
DEFAULT => -85
},
{#State 125
ACTIONS => {
";" => 209
}
},
{#State 126
DEFAULT => -86
},
{#State 127
ACTIONS => {
"}" => 210
}
},
{#State 128
ACTIONS => {
'ASSIGN' => 211
}
},
{#State 129
DEFAULT => -123
},
{#State 130
ACTIONS => {
"\$" => 44,
'COMMA' => 213,
'LITERAL' => 131,
'IDENT' => 2,
"\${" => 38
},
DEFAULT => -119,
GOTOS => {
'item' => 128,
'param' => 212
}
},
{#State 131
ACTIONS => {
'ASSIGN' => 214
}
},
{#State 132
DEFAULT => -75
},
{#State 133
DEFAULT => -4
},
{#State 134
ACTIONS => {
";" => 215
}
},
{#State 135
ACTIONS => {
"}" => 216
}
},
{#State 136
ACTIONS => {
'DIV' => 161,
'BINOP' => 163,
"+" => 159,
'CAT' => 165,
'CMPOP' => 166,
'MOD' => 167,
"/" => 168
},
DEFAULT => -143
},
{#State 137
DEFAULT => -157,
GOTOS => {
'args' => 217
}
},
{#State 138
DEFAULT => -133
},
{#State 139
ACTIONS => {
'CMPOP' => 166,
"?" => 160,
";" => 218,
"+" => 159,
'MOD' => 167,
'DIV' => 161,
"/" => 168,
'AND' => 162,
'CAT' => 165,
'BINOP' => 163,
'OR' => 164
}
},
{#State 140
ACTIONS => {
"+" => 159,
'CAT' => 165,
'CMPOP' => 166,
"?" => 160,
'DIV' => 161,
'MOD' => 167,
"/" => 168,
'AND' => 162,
'BINOP' => 163,
'OR' => 164
},
DEFAULT => -31
},
{#State 141
ACTIONS => {
"+" => 159,
'CAT' => 165,
'CMPOP' => 166,
"?" => 160,
'DIV' => 161,
'MOD' => 167,
"/" => 168,
'AND' => 162,
'BINOP' => 163,
'OR' => 164
},
DEFAULT => -30
},
{#State 142
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 219,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 143
ACTIONS => {
"{" => 31,
'LITERAL' => 80,
'IDENT' => 109,
"\"" => 62,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'sterm' => 70,
'item' => 41,
'loopvar' => 220,
'node' => 23,
'ident' => 79,
'term' => 110,
'lterm' => 58
}
},
{#State 144
ACTIONS => {
"\"" => 118,
"\$" => 115,
'LITERAL' => 117,
'FILENAME' => 85,
'IDENT' => 112,
'NUMBER' => 86,
"\${" => 38
},
GOTOS => {
'names' => 93,
'lvalue' => 113,
'item' => 114,
'name' => 84,
'filepart' => 89,
'filename' => 87,
'nameargs' => 119,
'lnameargs' => 221
}
},
{#State 145
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 222,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 146
ACTIONS => {
"\"" => 91,
"\$" => 88,
'LITERAL' => 90,
'FILENAME' => 85,
'IDENT' => 83,
'NUMBER' => 86
},
GOTOS => {
'filepart' => 89,
'names' => 93,
'nameargs' => 223,
'filename' => 87,
'name' => 84
}
},
{#State 147
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 224,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 148
DEFAULT => -43
},
{#State 149
DEFAULT => 0
},
{#State 150
ACTIONS => {
'DOT' => 105,
'ASSIGN' => 174
},
DEFAULT => -110
},
{#State 151
ACTIONS => {
")" => 225
}
},
{#State 152
ACTIONS => {
'CMPOP' => 166,
"?" => 160,
"+" => 159,
'MOD' => 167,
'DIV' => 161,
"/" => 168,
'AND' => 162,
'CAT' => 165,
'BINOP' => 163,
")" => 226,
'OR' => 164
}
},
{#State 153
ACTIONS => {
'CMPOP' => 166,
"?" => 160,
";" => 227,
"+" => 159,
'MOD' => 167,
'DIV' => 161,
"/" => 168,
'AND' => 162,
'CAT' => 165,
'BINOP' => 163,
'OR' => 164
}
},
{#State 154
DEFAULT => -79,
GOTOS => {
'@4-2' => 228
}
},
{#State 155
ACTIONS => {
";" => 229
}
},
{#State 156
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 230,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 157
ACTIONS => {
"\"" => 235,
'TEXT' => 232,
";" => 234,
"\$" => 44,
'IDENT' => 2,
"\${" => 38
},
GOTOS => {
'item' => 41,
'node' => 23,
'ident' => 231,
'quotable' => 233
}
},
{#State 158
DEFAULT => -36
},
{#State 159
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 236,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 160
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 237,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 161
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 238,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 162
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 239,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 163
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 240,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 164
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 241,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 165
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 242,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 166
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 243,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 167
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 244,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 168
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 245,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 169
DEFAULT => -34
},
{#State 170
ACTIONS => {
'CMPOP' => 166,
"?" => 160,
";" => 246,
"+" => 159,
'MOD' => 167,
'DIV' => 161,
"/" => 168,
'AND' => 162,
'CAT' => 165,
'BINOP' => 163,
'OR' => 164
}
},
{#State 171
ACTIONS => {
'COMMA' => 173,
'LITERAL' => 77,
'IDENT' => 2,
"\$" => 44,
"\${" => 38
},
DEFAULT => -33,
GOTOS => {
'item' => 41,
'assign' => 172,
'node' => 23,
'ident' => 76
}
},
{#State 172
DEFAULT => -148
},
{#State 173
DEFAULT => -149
},
{#State 174
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 247,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 175
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 248,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 176
ACTIONS => {
'FILENAME' => 85,
'IDENT' => 83,
'NUMBER' => 86
},
GOTOS => {
'filepart' => 249
}
},
{#State 177
ACTIONS => {
'DOT' => 105
},
DEFAULT => -157,
GOTOS => {
'args' => 250
}
},
{#State 178
ACTIONS => {
"\"" => 251,
'TEXT' => 232,
";" => 234,
"\$" => 44,
'IDENT' => 2,
"\${" => 38
},
GOTOS => {
'item' => 41,
'node' => 23,
'ident' => 231,
'quotable' => 233
}
},
{#State 179
ACTIONS => {
"\"" => 91,
'LITERAL' => 90,
'FILENAME' => 85,
'IDENT' => 83,
'NUMBER' => 86
},
GOTOS => {
'filepart' => 89,
'filename' => 87,
'name' => 252
}
},
{#State 180
DEFAULT => -157,
GOTOS => {
'args' => 253
}
},
{#State 181
ACTIONS => {
'NOT' => 40,
'LITERAL' => 257,
'IDENT' => 2,
"\"" => 62,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"{" => 31,
'COMMA' => 259,
"(" => 54,
"\${" => 38
},
DEFAULT => -164,
GOTOS => {
'expr' => 258,
'sterm' => 70,
'item' => 255,
'param' => 256,
'node' => 23,
'ident' => 254,
'term' => 60,
'lterm' => 58
}
},
{#State 182
DEFAULT => -106
},
{#State 183
DEFAULT => -115
},
{#State 184
DEFAULT => -116
},
{#State 185
DEFAULT => -107
},
{#State 186
ACTIONS => {
"\"" => 62,
"\$" => 44,
'LITERAL' => 80,
'IDENT' => 2,
'REF' => 27,
'NUMBER' => 26,
"\${" => 38
},
GOTOS => {
'sterm' => 260,
'item' => 41,
'node' => 23,
'ident' => 79
}
},
{#State 187
ACTIONS => {
'FINAL' => 261,
'CATCH' => 263
},
DEFAULT => -74,
GOTOS => {
'final' => 262
}
},
{#State 188
ACTIONS => {
"\"" => 266,
'LITERAL' => 265,
'NUMBER' => 264
}
},
{#State 189
DEFAULT => -98
},
{#State 190
DEFAULT => -99
},
{#State 191
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'loop' => 5,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'atomdir' => 13,
'anonblock' => 51,
'template' => 267,
'defblockname' => 14,
'ident' => 16,
'assign' => 19,
'macro' => 20,
'lterm' => 58,
'node' => 23,
'term' => 60,
'expr' => 64,
'use' => 65,
'defblock' => 68,
'filter' => 30,
'sterm' => 70,
'chunks' => 34,
'setlist' => 72,
'switch' => 35,
'try' => 36,
'directive' => 73,
'block' => 74,
'raw' => 39,
'condition' => 75
}
},
{#State 192
DEFAULT => -126
},
{#State 193
DEFAULT => -127
},
{#State 194
ACTIONS => {
";" => 268
}
},
{#State 195
DEFAULT => -90
},
{#State 196
ACTIONS => {
";" => -151,
"+" => 159,
'LITERAL' => -151,
'IDENT' => -151,
'CAT' => 165,
"\$" => -151,
'CMPOP' => 166,
"?" => 160,
'DIV' => 161,
'MOD' => 167,
'COMMA' => -151,
"/" => 168,
'AND' => 162,
'BINOP' => 163,
'OR' => 164,
"\${" => -151
},
DEFAULT => -28
},
{#State 197
DEFAULT => -93
},
{#State 198
DEFAULT => -92
},
{#State 199
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 59,
'IDENT' => 269,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 152,
'sterm' => 70,
'item' => 41,
'assign' => 151,
'margs' => 270,
'node' => 23,
'ident' => 150,
'term' => 60,
'lterm' => 58
}
},
{#State 200
ACTIONS => {
"+" => 159,
'CAT' => 165,
'CMPOP' => 166,
"?" => 160,
'DIV' => 161,
'MOD' => 167,
"/" => 168,
'AND' => 162,
'BINOP' => 163,
'OR' => 164
},
DEFAULT => -28
},
{#State 201
ACTIONS => {
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 271,
'lterm' => 58
}
},
{#State 202
ACTIONS => {
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 272,
'lterm' => 58
}
},
{#State 203
ACTIONS => {
'NOT' => 40,
"{" => 31,
'COMMA' => 259,
'LITERAL' => 257,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
DEFAULT => -66,
GOTOS => {
'expr' => 258,
'sterm' => 70,
'item' => 255,
'param' => 256,
'node' => 23,
'ident' => 254,
'term' => 60,
'lterm' => 58
}
},
{#State 204
DEFAULT => -58,
GOTOS => {
'@1-3' => 273
}
},
{#State 205
ACTIONS => {
"\"" => 91,
"\$" => 88,
'LITERAL' => 90,
'FILENAME' => 85,
'IDENT' => 83,
'NUMBER' => 86
},
GOTOS => {
'filepart' => 89,
'names' => 93,
'nameargs' => 274,
'filename' => 87,
'name' => 84
}
},
{#State 206
ACTIONS => {
'ASSIGN' => -133
},
DEFAULT => -131
},
{#State 207
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 275,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 208
ACTIONS => {
"\"" => 276,
'TEXT' => 232,
";" => 234,
"\$" => 44,
'IDENT' => 2,
"\${" => 38
},
GOTOS => {
'item' => 41,
'node' => 23,
'ident' => 231,
'quotable' => 233
}
},
{#State 209
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 277,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 210
DEFAULT => -109
},
{#State 211
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 278,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 212
DEFAULT => -121
},
{#State 213
DEFAULT => -122
},
{#State 214
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 279,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 215
DEFAULT => -77,
GOTOS => {
'@3-3' => 280
}
},
{#State 216
DEFAULT => -132
},
{#State 217
ACTIONS => {
'NOT' => 40,
"{" => 31,
'COMMA' => 259,
'LITERAL' => 257,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
")" => 281,
"\${" => 38
},
GOTOS => {
'expr' => 258,
'sterm' => 70,
'item' => 255,
'param' => 256,
'node' => 23,
'ident' => 254,
'term' => 60,
'lterm' => 58
}
},
{#State 218
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 282,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 219
ACTIONS => {
'CMPOP' => 166,
"?" => 160,
"+" => 159,
'MOD' => 167,
'DIV' => 161,
"/" => 168,
'AND' => 162,
'CAT' => 165,
'BINOP' => 163,
'OR' => 164
},
DEFAULT => -49
},
{#State 220
DEFAULT => -60
},
{#State 221
DEFAULT => -82
},
{#State 222
ACTIONS => {
'CMPOP' => 166,
"?" => 160,
"+" => 159,
'MOD' => 167,
'DIV' => 161,
"/" => 168,
'AND' => 162,
'CAT' => 165,
'BINOP' => 163,
'OR' => 164
},
DEFAULT => -47
},
{#State 223
DEFAULT => -68
},
{#State 224
ACTIONS => {
'CMPOP' => 166,
"?" => 160,
"+" => 159,
'MOD' => 167,
'DIV' => 161,
"/" => 168,
'AND' => 162,
'CAT' => 165,
'BINOP' => 163,
'OR' => 164
},
DEFAULT => -63
},
{#State 225
DEFAULT => -145
},
{#State 226
DEFAULT => -146
},
{#State 227
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 283,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 228
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 284,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 229
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 285,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 230
ACTIONS => {
"+" => 159,
'CAT' => 165,
'CMPOP' => 166,
"?" => 160,
'DIV' => 161,
'MOD' => 167,
"/" => 168,
'AND' => 162,
'BINOP' => 163,
'OR' => 164
},
DEFAULT => -152
},
{#State 231
ACTIONS => {
'DOT' => 105
},
DEFAULT => -178
},
{#State 232
DEFAULT => -179
},
{#State 233
DEFAULT => -176
},
{#State 234
DEFAULT => -180
},
{#State 235
DEFAULT => -112
},
{#State 236
ACTIONS => {
'DIV' => 161,
'MOD' => 167,
"/" => 168
},
DEFAULT => -136
},
{#State 237
ACTIONS => {
":" => 286,
'CMPOP' => 166,
"?" => 160,
"+" => 159,
'MOD' => 167,
'DIV' => 161,
"/" => 168,
'AND' => 162,
'CAT' => 165,
'BINOP' => 163,
'OR' => 164
}
},
{#State 238
ACTIONS => {
'MOD' => 167
},
DEFAULT => -137
},
{#State 239
ACTIONS => {
'DIV' => 161,
'BINOP' => 163,
"+" => 159,
'CAT' => 165,
'CMPOP' => 166,
'MOD' => 167,
"/" => 168
},
DEFAULT => -141
},
{#State 240
ACTIONS => {
'DIV' => 161,
"+" => 159,
'MOD' => 167,
"/" => 168
},
DEFAULT => -134
},
{#State 241
ACTIONS => {
'DIV' => 161,
'BINOP' => 163,
"+" => 159,
'CAT' => 165,
'CMPOP' => 166,
'MOD' => 167,
"/" => 168
},
DEFAULT => -142
},
{#State 242
ACTIONS => {
'DIV' => 161,
'BINOP' => 163,
"+" => 159,
'CMPOP' => 166,
'MOD' => 167,
"/" => 168
},
DEFAULT => -140
},
{#State 243
ACTIONS => {
'DIV' => 161,
'BINOP' => 163,
"+" => 159,
'MOD' => 167,
"/" => 168
},
DEFAULT => -139
},
{#State 244
DEFAULT => -138
},
{#State 245
ACTIONS => {
'DIV' => 161,
'MOD' => 167
},
DEFAULT => -135
},
{#State 246
DEFAULT => -61,
GOTOS => {
'@2-3' => 287
}
},
{#State 247
ACTIONS => {
"+" => 159,
'CAT' => 165,
'CMPOP' => 166,
"?" => 160,
'DIV' => 161,
'MOD' => 167,
"/" => 168,
'AND' => 162,
'BINOP' => 163,
'OR' => 164
},
DEFAULT => -151
},
{#State 248
ACTIONS => {
'ELSIF' => 290,
'ELSE' => 288
},
DEFAULT => -52,
GOTOS => {
'else' => 289
}
},
{#State 249
DEFAULT => -171
},
{#State 250
ACTIONS => {
'NOT' => 40,
'LITERAL' => 257,
'IDENT' => 2,
"\"" => 62,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"{" => 31,
'COMMA' => 259,
"(" => 54,
"\${" => 38
},
DEFAULT => -163,
GOTOS => {
'expr' => 258,
'sterm' => 70,
'item' => 255,
'param' => 256,
'node' => 23,
'ident' => 254,
'term' => 60,
'lterm' => 58
}
},
{#State 251
DEFAULT => -168
},
{#State 252
DEFAULT => -166
},
{#State 253
ACTIONS => {
'NOT' => 40,
"{" => 31,
'COMMA' => 259,
'LITERAL' => 257,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
")" => 291,
"\${" => 38
},
GOTOS => {
'expr' => 258,
'sterm' => 70,
'item' => 255,
'param' => 256,
'node' => 23,
'ident' => 254,
'term' => 60,
'lterm' => 58
}
},
{#State 254
ACTIONS => {
'DOT' => 105,
'ASSIGN' => 292
},
DEFAULT => -110
},
{#State 255
ACTIONS => {
"(" => 137,
'ASSIGN' => 211
},
DEFAULT => -129
},
{#State 256
DEFAULT => -154
},
{#State 257
ACTIONS => {
'ASSIGN' => 214
},
DEFAULT => -113
},
{#State 258
ACTIONS => {
"+" => 159,
'CAT' => 165,
'CMPOP' => 166,
"?" => 160,
'DIV' => 161,
'MOD' => 167,
"/" => 168,
'AND' => 162,
'BINOP' => 163,
'OR' => 164
},
DEFAULT => -153
},
{#State 259
DEFAULT => -156
},
{#State 260
DEFAULT => -118
},
{#State 261
ACTIONS => {
";" => 293
}
},
{#State 262
ACTIONS => {
'END' => 294
}
},
{#State 263
ACTIONS => {
";" => 296,
'DEFAULT' => 297,
'FILENAME' => 85,
'IDENT' => 83,
'NUMBER' => 86
},
GOTOS => {
'filepart' => 89,
'filename' => 295
}
},
{#State 264
DEFAULT => -103
},
{#State 265
DEFAULT => -101
},
{#State 266
ACTIONS => {
'TEXT' => 298
}
},
{#State 267
ACTIONS => {
'END' => 299
}
},
{#State 268
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 300,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 269
ACTIONS => {
'IDENT' => -97,
")" => -97,
'COMMA' => -97
},
DEFAULT => -131
},
{#State 270
ACTIONS => {
'COMMA' => 303,
'IDENT' => 301,
")" => 302
}
},
{#State 271
DEFAULT => -157,
GOTOS => {
'args' => 304
}
},
{#State 272
DEFAULT => -157,
GOTOS => {
'args' => 305
}
},
{#State 273
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 306,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 274
DEFAULT => -158
},
{#State 275
ACTIONS => {
'END' => 307
}
},
{#State 276
ACTIONS => {
'ASSIGN' => -161
},
DEFAULT => -168
},
{#State 277
ACTIONS => {
'END' => 308
}
},
{#State 278
ACTIONS => {
'DIV' => 161,
'AND' => 162,
'BINOP' => 163,
'OR' => 164,
"+" => 159,
'CAT' => 165,
'CMPOP' => 166,
"?" => 160,
'MOD' => 167,
"/" => 168
},
DEFAULT => -125
},
{#State 279
ACTIONS => {
'DIV' => 161,
'AND' => 162,
'BINOP' => 163,
'OR' => 164,
"+" => 159,
'CAT' => 165,
'CMPOP' => 166,
"?" => 160,
'MOD' => 167,
"/" => 168
},
DEFAULT => -124
},
{#State 280
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 309,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 281
DEFAULT => -130
},
{#State 282
ACTIONS => {
'ELSIF' => 290,
'ELSE' => 288
},
DEFAULT => -52,
GOTOS => {
'else' => 310
}
},
{#State 283
ACTIONS => {
'CASE' => 311
},
DEFAULT => -57,
GOTOS => {
'case' => 312
}
},
{#State 284
ACTIONS => {
'END' => 313
}
},
{#State 285
ACTIONS => {
'END' => 314
}
},
{#State 286
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 315,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 287
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 316,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 288
ACTIONS => {
";" => 317
}
},
{#State 289
ACTIONS => {
'END' => 318
}
},
{#State 290
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 319,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 291
DEFAULT => -165
},
{#State 292
ACTIONS => {
'NOT' => 40,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'expr' => 320,
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 60,
'lterm' => 58
}
},
{#State 293
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 321,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 294
DEFAULT => -69
},
{#State 295
ACTIONS => {
'DOT' => 176,
";" => 322
}
},
{#State 296
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 323,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 297
ACTIONS => {
";" => 324
}
},
{#State 298
ACTIONS => {
"\"" => 325
}
},
{#State 299
DEFAULT => -83
},
{#State 300
ACTIONS => {
'END' => 326
}
},
{#State 301
DEFAULT => -95
},
{#State 302
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
'FOR' => 21,
'NEXT' => 22,
'LITERAL' => 59,
"\"" => 62,
'PROCESS' => 63,
'FILTER' => 25,
'RETURN' => 66,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'BLOCK' => 194,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
"\${" => 38
},
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'expr' => 200,
'wrapper' => 47,
'atomexpr' => 49,
'atomdir' => 13,
'mdir' => 327,
'filter' => 30,
'sterm' => 70,
'ident' => 150,
'setlist' => 72,
'try' => 36,
'switch' => 35,
'assign' => 19,
'directive' => 197,
'condition' => 75,
'lterm' => 58
}
},
{#State 303
DEFAULT => -96
},
{#State 304
ACTIONS => {
'NOT' => 40,
"{" => 31,
'COMMA' => 259,
'LITERAL' => 257,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
DEFAULT => -64,
GOTOS => {
'expr' => 258,
'sterm' => 70,
'item' => 255,
'param' => 256,
'node' => 23,
'ident' => 254,
'term' => 60,
'lterm' => 58
}
},
{#State 305
ACTIONS => {
'NOT' => 40,
"{" => 31,
'COMMA' => 259,
'LITERAL' => 257,
'IDENT' => 2,
"\"" => 62,
"(" => 54,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
DEFAULT => -65,
GOTOS => {
'expr' => 258,
'sterm' => 70,
'item' => 255,
'param' => 256,
'node' => 23,
'ident' => 254,
'term' => 60,
'lterm' => 58
}
},
{#State 306
ACTIONS => {
'END' => 328
}
},
{#State 307
DEFAULT => -81
},
{#State 308
DEFAULT => -89
},
{#State 309
ACTIONS => {
'END' => 329
}
},
{#State 310
ACTIONS => {
'END' => 330
}
},
{#State 311
ACTIONS => {
";" => 331,
'DEFAULT' => 333,
"{" => 31,
'LITERAL' => 80,
'IDENT' => 2,
"\"" => 62,
"\$" => 44,
"[" => 10,
'NUMBER' => 26,
'REF' => 27,
"\${" => 38
},
GOTOS => {
'sterm' => 70,
'item' => 41,
'node' => 23,
'ident' => 79,
'term' => 332,
'lterm' => 58
}
},
{#State 312
ACTIONS => {
'END' => 334
}
},
{#State 313
DEFAULT => -80
},
{#State 314
DEFAULT => -67
},
{#State 315
ACTIONS => {
'DIV' => 161,
'AND' => 162,
'BINOP' => 163,
'OR' => 164,
"+" => 159,
'CAT' => 165,
'CMPOP' => 166,
"?" => 160,
'MOD' => 167,
"/" => 168
},
DEFAULT => -144
},
{#State 316
ACTIONS => {
'END' => 335
}
},
{#State 317
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 336,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 318
DEFAULT => -48
},
{#State 319
ACTIONS => {
'CMPOP' => 166,
"?" => 160,
";" => 337,
"+" => 159,
'MOD' => 167,
'DIV' => 161,
"/" => 168,
'AND' => 162,
'CAT' => 165,
'BINOP' => 163,
'OR' => 164
}
},
{#State 320
ACTIONS => {
"+" => 159,
'CAT' => 165,
'CMPOP' => 166,
"?" => 160,
'DIV' => 161,
'MOD' => 167,
"/" => 168,
'AND' => 162,
'BINOP' => 163,
'OR' => 164
},
DEFAULT => -155
},
{#State 321
DEFAULT => -73
},
{#State 322
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 338,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 323
ACTIONS => {
'FINAL' => 261,
'CATCH' => 263
},
DEFAULT => -74,
GOTOS => {
'final' => 339
}
},
{#State 324
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 340,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 325
DEFAULT => -102
},
{#State 326
DEFAULT => -94
},
{#State 327
DEFAULT => -91
},
{#State 328
DEFAULT => -59
},
{#State 329
DEFAULT => -78
},
{#State 330
DEFAULT => -46
},
{#State 331
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 341,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 332
ACTIONS => {
";" => 342
}
},
{#State 333
ACTIONS => {
";" => 343
}
},
{#State 334
DEFAULT => -53
},
{#State 335
DEFAULT => -62
},
{#State 336
DEFAULT => -51
},
{#State 337
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 344,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 338
ACTIONS => {
'FINAL' => 261,
'CATCH' => 263
},
DEFAULT => -74,
GOTOS => {
'final' => 345
}
},
{#State 339
DEFAULT => -72
},
{#State 340
ACTIONS => {
'FINAL' => 261,
'CATCH' => 263
},
DEFAULT => -74,
GOTOS => {
'final' => 346
}
},
{#State 341
DEFAULT => -56
},
{#State 342
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 347,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 343
ACTIONS => {
'SET' => 1,
'NOT' => 40,
'IDENT' => 2,
'CLEAR' => 42,
'UNLESS' => 4,
'IF' => 45,
"\$" => 44,
'STOP' => 7,
'CALL' => 46,
'THROW' => 9,
'GET' => 48,
"[" => 10,
'TRY' => 11,
'LAST' => 50,
'DEBUG' => 52,
'META' => 15,
'INCLUDE' => 17,
"(" => 54,
'SWITCH' => 55,
'MACRO' => 18,
'JAVASCRIPT' => 56,
'WRAPPER' => 57,
";" => -19,
'FOR' => 21,
'LITERAL' => 59,
'NEXT' => 22,
'rawperl' => 61,
"\"" => 62,
'TEXT' => 24,
'PROCESS' => 63,
'RETURN' => 66,
'FILTER' => 25,
'INSERT' => 67,
'NUMBER' => 26,
'REF' => 27,
'WHILE' => 69,
'RAW' => 28,
'BLOCK' => 29,
'DEFAULT' => 71,
"{" => 31,
'perl' => 32,
'USE' => 33,
'VIEW' => 37,
"\${" => 38
},
DEFAULT => -3,
GOTOS => {
'item' => 41,
'javascript' => 3,
'node' => 23,
'term' => 60,
'loop' => 5,
'use' => 65,
'expr' => 64,
'capture' => 43,
'statement' => 6,
'view' => 8,
'wrapper' => 47,
'atomexpr' => 49,
'chunk' => 12,
'defblock' => 68,
'atomdir' => 13,
'anonblock' => 51,
'sterm' => 70,
'defblockname' => 14,
'filter' => 30,
'ident' => 16,
'setlist' => 72,
'chunks' => 34,
'try' => 36,
'switch' => 35,
'assign' => 19,
'block' => 348,
'directive' => 73,
'macro' => 20,
'condition' => 75,
'lterm' => 58,
'raw' => 39
}
},
{#State 344
ACTIONS => {
'ELSIF' => 290,
'ELSE' => 288
},
DEFAULT => -52,
GOTOS => {
'else' => 349
}
},
{#State 345
DEFAULT => -70
},
{#State 346
DEFAULT => -71
},
{#State 347
ACTIONS => {
'CASE' => 311
},
DEFAULT => -57,
GOTOS => {
'case' => 350
}
},
{#State 348
DEFAULT => -55
},
{#State 349
DEFAULT => -50
},
{#State 350
DEFAULT => -54
}
];
$RULES = [
[#Rule 0
'$start', 2, undef
],
[#Rule 1
'template', 1,
sub
{ $factory->template($_[1]) }
],
[#Rule 2
'block', 1,
sub
{ $factory->block($_[1]) }
],
[#Rule 3
'block', 0,
sub
{ $factory->block() }
],
[#Rule 4
'chunks', 2,
sub
{ push(@{$_[1]}, $_[2])
if defined $_[2]; $_[1] }
],
[#Rule 5
'chunks', 1,
sub
{ defined $_[1] ? [ $_[1] ] : [ ] }
],
[#Rule 6
'chunk', 1,
sub
{ $factory->textblock($_[1]) }
],
[#Rule 7
'chunk', 2,
sub
{ return '' unless $_[1];
$_[0]->location() . $_[1];
}
],
[#Rule 8
'statement', 1, undef
],
[#Rule 9
'statement', 1, undef
],
[#Rule 10
'statement', 1, undef
],
[#Rule 11
'statement', 1, undef
],
[#Rule 12
'statement', 1, undef
],
[#Rule 13
'statement', 1, undef
],
[#Rule 14
'statement', 1, undef
],
[#Rule 15
'statement', 1, undef
],
[#Rule 16
'statement', 1, undef
],
[#Rule 17
'statement', 1,
sub
{ $factory->get($_[1]) }
],
[#Rule 18
'statement', 2,
sub
{ $_[0]->add_metadata($_[2]); }
],
[#Rule 19
'statement', 0, undef
],
[#Rule 20
'directive', 1,
sub
{ $factory->set($_[1]) }
],
[#Rule 21
'directive', 1, undef
],
[#Rule 22
'directive', 1, undef
],
[#Rule 23
'directive', 1, undef
],
[#Rule 24
'directive', 1, undef
],
[#Rule 25
'directive', 1, undef
],
[#Rule 26
'directive', 1, undef
],
[#Rule 27
'directive', 1, undef
],
[#Rule 28
'atomexpr', 1,
sub
{ $factory->get($_[1]) }
],
[#Rule 29
'atomexpr', 1, undef
],
[#Rule 30
'atomdir', 2,
sub
{ $factory->get($_[2]) }
],
[#Rule 31
'atomdir', 2,
sub
{ $factory->call($_[2]) }
],
[#Rule 32
'atomdir', 2,
sub
{ $factory->set($_[2]) }
],
[#Rule 33
'atomdir', 2,
sub
{ $factory->default($_[2]) }
],
[#Rule 34
'atomdir', 2,
sub
{ $factory->insert($_[2]) }
],
[#Rule 35
'atomdir', 2,
sub
{ $factory->include($_[2]) }
],
[#Rule 36
'atomdir', 2,
sub
{ $factory->process($_[2]) }
],
[#Rule 37
'atomdir', 2,
sub
{ $factory->throw($_[2]) }
],
[#Rule 38
'atomdir', 1,
sub
{ $factory->return() }
],
[#Rule 39
'atomdir', 1,
sub
{ $factory->stop() }
],
[#Rule 40
'atomdir', 1,
sub
{ $factory->clear() }
],
[#Rule 41
'atomdir', 1,
sub
{ $factory->break() }
],
[#Rule 42
'atomdir', 1,
sub
{ $factory->next() }
],
[#Rule 43
'atomdir', 2,
sub
{ if ($_[2]->[0]->[0] =~ /^'(on|off)'$/) {
$_[0]->{ DEBUG_DIRS } = ($1 eq 'on');
$factory->debug($_[2]);
}
else {
$_[0]->{ DEBUG_DIRS } ? $factory->debug($_[2]) : '';
}
}
],
[#Rule 44
'atomdir', 1, undef
],
[#Rule 45
'atomdir', 1, undef
],
[#Rule 46
'condition', 6,
sub
{ $factory->if(@_[2, 4, 5]) }
],
[#Rule 47
'condition', 3,
sub
{ $factory->if(@_[3, 1]) }
],
[#Rule 48
'condition', 6,
sub
{ $factory->if("($_[2]) == false", @_[4, 5]) }
],
[#Rule 49
'condition', 3,
sub
{ $factory->if("($_[3]) == false", $_[1]) }
],
[#Rule 50
'else', 5,
sub
{ unshift(@{$_[5]}, [ @_[2, 4] ]);
$_[5]; }
],
[#Rule 51
'else', 3,
sub
{ [ $_[3] ] }
],
[#Rule 52
'else', 0,
sub
{ [ undef ] }
],
[#Rule 53
'switch', 6,
sub
{ $factory->switch(@_[2, 5]) }
],
[#Rule 54
'case', 5,
sub
{ unshift(@{$_[5]}, [ @_[2, 4] ]);
$_[5]; }
],
[#Rule 55
'case', 4,
sub
{ [ $_[4] ] }
],
[#Rule 56
'case', 3,
sub
{ [ $_[3] ] }
],
[#Rule 57
'case', 0,
sub
{ [ undef ] }
],
[#Rule 58
'@1-3', 0,
sub
{ $_[0]->{ INFOR }++ }
],
[#Rule 59
'loop', 6,
sub
{ $_[0]->{ INFOR }--;
$factory->foreach(@{$_[2]}, $_[5]) }
],
[#Rule 60
'loop', 3,
sub
{ $factory->foreach(@{$_[3]}, $_[1]) }
],
[#Rule 61
'@2-3', 0,
sub
{ $_[0]->{ INWHILE }++ }
],
[#Rule 62
'loop', 6,
sub
{ $_[0]->{ INWHILE }--;
$factory->while(@_[2, 5]) }
],
[#Rule 63
'loop', 3,
sub
{ $factory->while(@_[3, 1]) }
],
[#Rule 64
'loopvar', 4,
sub
{ [ @_[1, 3, 4] ] }
],
[#Rule 65
'loopvar', 4,
sub
{ [ @_[1, 3, 4] ] }
],
[#Rule 66
'loopvar', 2,
sub
{ [ 0, @_[1, 2] ] }
],
[#Rule 67
'wrapper', 5,
sub
{ $factory->wrapper(@_[2, 4]) }
],
[#Rule 68
'wrapper', 3,
sub
{ $factory->wrapper(@_[3, 1]) }
],
[#Rule 69
'try', 5,
sub
{ $factory->try(@_[3, 4]) }
],
[#Rule 70
'final', 5,
sub
{ unshift(@{$_[5]}, [ @_[2,4] ]);
$_[5]; }
],
[#Rule 71
'final', 5,
sub
{ unshift(@{$_[5]}, [ undef, $_[4] ]);
$_[5]; }
],
[#Rule 72
'final', 4,
sub
{ unshift(@{$_[4]}, [ undef, $_[3] ]);
$_[4]; }
],
[#Rule 73
'final', 3,
sub
{ [ $_[3] ] }
],
[#Rule 74
'final', 0,
sub
{ [ 0 ] }
],
[#Rule 75
'use', 2,
sub
{ $factory->use($_[2]) }
],
[#Rule 76
'raw', 2,
sub
{ $factory->raw($_[2]) }
],
[#Rule 77
'@3-3', 0,
sub
{ $_[0]->push_defblock(); }
],
[#Rule 78
'view', 6,
sub
{ $factory->view(@_[2,5],
$_[0]->pop_defblock) }
],
[#Rule 79
'@4-2', 0,
sub
{ ${$_[0]->{ INJAVASCRIPT }}++; }
],
[#Rule 80
'javascript', 5,
sub
{ ${$_[0]->{ INJAVASCRIPT }}--;
$_[0]->{ EVAL_JAVASCRIPT }
? $factory->javascript($_[4])
: $factory->no_javascript(); }
],
[#Rule 81
'filter', 5,
sub
{ $factory->filter(@_[2,4]) }
],
[#Rule 82
'filter', 3,
sub
{ $factory->filter(@_[3,1]) }
],
[#Rule 83
'defblock', 5,
sub
{ my $name = join('/', @{ $_[0]->{ DEFBLOCKS } });
pop(@{ $_[0]->{ DEFBLOCKS } });
$_[0]->define_block($name, $_[4]);
undef
}
],
[#Rule 84
'defblockname', 2,
sub
{ push(@{ $_[0]->{ DEFBLOCKS } }, $_[2]);
$_[2];
}
],
[#Rule 85
'blockname', 1, undef
],
[#Rule 86
'blockname', 1,
sub
{ $_[1] =~ s/^'(.*)'$/$1/; $_[1] }
],
[#Rule 87
'blockargs', 1, undef
],
[#Rule 88
'blockargs', 0, undef
],
[#Rule 89
'anonblock', 5,
sub
{ local $" = ', ';
print STDERR "experimental block args: [@{ $_[2] }]\n"
if $_[2];
$factory->anon_block($_[4]) }
],
[#Rule 90
'capture', 3,
sub
{ $factory->capture(@_[1, 3]) }
],
[#Rule 91
'macro', 6,
sub
{ $factory->macro(@_[2, 6, 4]) }
],
[#Rule 92
'macro', 3,
sub
{ $factory->macro(@_[2, 3]) }
],
[#Rule 93
'mdir', 1, undef
],
[#Rule 94
'mdir', 4,
sub
{ $_[3] }
],
[#Rule 95
'margs', 2,
sub
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 96
'margs', 2,
sub
{ $_[1] }
],
[#Rule 97
'margs', 1,
sub
{ [ $_[1] ] }
],
[#Rule 98
'metadata', 2,
sub
{ push(@{$_[1]}, @{$_[2]}); $_[1] }
],
[#Rule 99
'metadata', 2, undef
],
[#Rule 100
'metadata', 1, undef
],
[#Rule 101
'meta', 3,
sub
{ for ($_[3]) { s/^'//; s/'$//;
s/\\'/'/g };
[ @_[1,3] ] }
],
[#Rule 102
'meta', 5,
sub
{ [ @_[1,4] ] }
],
[#Rule 103
'meta', 3,
sub
{ [ @_[1,3] ] }
],
[#Rule 104
'term', 1, undef
],
[#Rule 105
'term', 1, undef
],
[#Rule 106
'lterm', 3,
sub
{ "[ $_[2] ]" }
],
[#Rule 107
'lterm', 3,
sub
{ "[ $_[2] ]" }
],
[#Rule 108
'lterm', 2,
sub
{ "[ ]" }
],
[#Rule 109
'lterm', 3,
sub
{ "{ $_[2] }" }
],
[#Rule 110
'sterm', 1,
sub
{ $factory->ident($_[1]) }
],
[#Rule 111
'sterm', 2,
sub
{ $factory->identref($_[2]) }
],
[#Rule 112
'sterm', 3,
sub
{ $factory->quoted($_[2]) }
],
[#Rule 113
'sterm', 1, undef
],
[#Rule 114
'sterm', 1, undef
],
[#Rule 115
'list', 2,
sub
{ "$_[1], $_[2]" }
],
[#Rule 116
'list', 2, undef
],
[#Rule 117
'list', 1, undef
],
[#Rule 118
'range', 3,
sub
{ $_[1] . '..' . $_[3] }
],
[#Rule 119
'hash', 1, undef
],
[#Rule 120
'hash', 0,
sub
{ "" }
],
[#Rule 121
'params', 2,
sub
{ "$_[1], $_[2]" }
],
[#Rule 122
'params', 2, undef
],
[#Rule 123
'params', 1, undef
],
[#Rule 124
'param', 3,
sub
{ "$_[1]: $_[3]" }
],
[#Rule 125
'param', 3,
sub
{ "$_[1]: $_[3]" }
],
[#Rule 126
'ident', 3,
sub
{ push(@{$_[1]}, @{$_[3]}); $_[1] }
],
[#Rule 127
'ident', 3,
sub
{ push(@{$_[1]},
map {($_, 0)} split(/\./, $_[3]));
$_[1]; }
],
[#Rule 128
'ident', 1, undef
],
[#Rule 129
'node', 1,
sub
{ [ $_[1], 0 ] }
],
[#Rule 130
'node', 4,
sub
{ [ $_[1], $factory->args($_[3]) ] }
],
[#Rule 131
'item', 1,
sub
{ "'$_[1]'" }
],
[#Rule 132
'item', 3,
sub
{ $_[2] }
],
[#Rule 133
'item', 2,
sub
{ $_[0]->{ V1DOLLAR }
? "'$_[2]'"
: $factory->ident(["'$_[2]'", 0]) }
],
[#Rule 134
'expr', 3,
sub
{ "$_[1] $_[2] $_[3]" }
],
[#Rule 135
'expr', 3,
sub
{ "$_[1] $_[2] $_[3]" }
],
[#Rule 136
'expr', 3,
sub
{ "$_[1] $_[2] $_[3]" }
],
[#Rule 137
'expr', 3,
sub
{ "Math.floor($_[1] / $_[3])" }
],
[#Rule 138
'expr', 3,
sub
{ "$_[1] % $_[3]" }
],
[#Rule 139
'expr', 3,
sub
{ "$_[1] $CMPOP{ $_[2] } $_[3]" }
],
[#Rule 140
'expr', 3,
sub
{ "$_[1] + $_[3]" }
],
[#Rule 141
'expr', 3,
sub
{ "$_[1] && $_[3]" }
],
[#Rule 142
'expr', 3,
sub
{ "$_[1] || $_[3]" }
],
[#Rule 143
'expr', 2,
sub
{ "! $_[2]" }
],
[#Rule 144
'expr', 5,
sub
{ "$_[1] ? $_[3] : $_[5]" }
],
[#Rule 145
'expr', 3,
sub
{ $factory->assign(@{$_[2]}) }
],
[#Rule 146
'expr', 3,
sub
{ "($_[2])" }
],
[#Rule 147
'expr', 1, undef
],
[#Rule 148
'setlist', 2,
sub
{ push(@{$_[1]}, @{$_[2]}); $_[1] }
],
[#Rule 149
'setlist', 2, undef
],
[#Rule 150
'setlist', 1, undef
],
[#Rule 151
'assign', 3,
sub
{ [ $_[1], $_[3] ] }
],
[#Rule 152
'assign', 3,
sub
{ [ @_[1,3] ] }
],
[#Rule 153
'args', 2,
sub
{ push(@{$_[1]}, $_[2]); $_[1] }
],
[#Rule 154
'args', 2,
sub
{ push(@{$_[1]->[0]}, $_[2]); $_[1] }
],
[#Rule 155
'args', 4,
sub
{ push(@{$_[1]->[0]}, "'', " .
$factory->assign(@_[2,4])); $_[1] }
],
[#Rule 156
'args', 2,
sub
{ $_[1] }
],
[#Rule 157
'args', 0,
sub
{ [ [ ] ] }
],
[#Rule 158
'lnameargs', 3,
sub
{ push(@{$_[3]}, $_[1]); $_[3] }
],
[#Rule 159
'lnameargs', 1, undef
],
[#Rule 160
'lvalue', 1, undef
],
[#Rule 161
'lvalue', 3,
sub
{ $factory->quoted($_[2]) }
],
[#Rule 162
'lvalue', 1, undef
],
[#Rule 163
'nameargs', 3,
sub
{ [ [$factory->ident($_[2])], $_[3] ] }
],
[#Rule 164
'nameargs', 2,
sub
{ [ @_[1,2] ] }
],
[#Rule 165
'nameargs', 4,
sub
{ [ @_[1,3] ] }
],
[#Rule 166
'names', 3,
sub
{ push(@{$_[1]}, $_[3]); $_[1] }
],
[#Rule 167
'names', 1,
sub
{ [ $_[1] ] }
],
[#Rule 168
'name', 3,
sub
{ $factory->quoted($_[2]) }
],
[#Rule 169
'name', 1,
sub
{ "'$_[1]'" }
],
[#Rule 170
'name', 1, undef
],
[#Rule 171
'filename', 3,
sub
{ "$_[1].$_[3]" }
],
[#Rule 172
'filename', 1, undef
],
[#Rule 173
'filepart', 1, undef
],
[#Rule 174
'filepart', 1, undef
],
[#Rule 175
'filepart', 1, undef
],
[#Rule 176
'quoted', 2,
sub
{ push(@{$_[1]}, $_[2])
if defined $_[2]; $_[1] }
],
[#Rule 177
'quoted', 0,
sub
{ [ ] }
],
[#Rule 178
'quotable', 1,
sub
{ $factory->ident($_[1]) }
],
[#Rule 179
'quotable', 1,
sub
{ $factory->text($_[1]) }
],
[#Rule 180
'quotable', 1,
sub
{ undef }
]
];
1;
}
#
# Inline include of Jemplate/Parser.pm
#
BEGIN { $INC{'Jemplate/Parser.pm'} = 'dummy/Jemplate/Parser.pm'; }
BEGIN {
#line 0 "Jemplate/Parser.pm"
package Jemplate::Parser;
use strict;
use warnings;
use base 'Template::Parser';
use Jemplate::Grammar;
use Jemplate::Directive;
sub new {
my $class = shift;
my $parser = $class->SUPER::new(
GRAMMAR => Jemplate::Grammar->new(),
FACTORY => 'Jemplate::Directive',
@_,
);
# flags passed from Jemplate object
my %args = @_;
# eval-javascript is default "on"
$parser->{EVAL_JAVASCRIPT} = exists $args{EVAL_JAVASCRIPT}
? $args{EVAL_JAVASCRIPT} : 1;
# tie the parser state-variable to the global Directive var
$parser->{INJAVASCRIPT} = \$Jemplate::Directive::INJAVASCRIPT;
return $parser;
}
1;
}
#
# Inline include of Jemplate/Runtime.pm
#
BEGIN { $INC{'Jemplate/Runtime.pm'} = 'dummy/Jemplate/Runtime.pm'; }
BEGIN {
#line 0 "Jemplate/Runtime.pm"
package Jemplate::Runtime;
use strict;
use warnings;
sub main { return &kernel }
sub kernel {
<<'...';
/*------------------------------------------------------------------------------
Jemplate - Template Toolkit for JavaScript
DESCRIPTION - This module provides the runtime JavaScript support for
compiled Jemplate templates.
AUTHOR - Ingy döt Net <ingy@cpan.org>
Copyright 2006,2008 Ingy döt Net.
This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
------------------------------------------------------------------------------*/
//------------------------------------------------------------------------------
// Main Jemplate class
//------------------------------------------------------------------------------
if (typeof Jemplate == 'undefined') {
var Jemplate = function() {
this.init.apply(this, arguments);
};
}
Jemplate.VERSION = '0.22';
Jemplate.process = function() {
var jemplate = new Jemplate(Jemplate.prototype.config);
return jemplate.process.apply(jemplate, arguments);
}
;(function(){
if (! Jemplate.templateMap)
Jemplate.templateMap = {};
var proto = Jemplate.prototype = {};
proto.config = {
AUTO_RESET: true,
BLOCKS: {},
CONTEXT: null,
DEBUG_UNDEF: false,
DEFAULT: null,
ERROR: null,
EVAL_JAVASCRIPT: false,
GLOBAL : true,
SCOPE : this,
FILTERS: {},
INCLUDE_PATH: [''],
INTERPOLATE: false,
OUTPUT: null,
PLUGINS: {},
POST_PROCESS: [],
PRE_PROCESS: [],
PROCESS: null,
RECURSION: false,
STASH: null,
TOLERANT: null,
VARIABLES: {},
WRAPPER: []
};
proto.defaults = {
AUTO_RESET: true,
BLOCKS: {},
CONTEXT: null,
DEBUG_UNDEF: false,
DEFAULT: null,
ERROR: null,
EVAL_JAVASCRIPT: false,
GLOBAL : true,
SCOPE : this,
INCLUDE_PATH: [''],
INTERPOLATE: false,
OUTPUT: null,
PLUGINS: {},
POST_PROCESS: [],
PRE_PROCESS: [],
PROCESS: null,
RECURSION: false,
STASH: null,
TOLERANT: null,
VARIABLES: {},
WRAPPER: []
};
Jemplate.init = function(config) {
Jemplate.prototype.config = config || {};
for (var i in Jemplate.prototype.defaults) {
if(typeof Jemplate.prototype.config[i] == "undefined") {
Jemplate.prototype.config[i] = Jemplate.prototype.defaults[i];
}
}
}
proto.init = function(config) {
this.config = config || {};
for (var i in Jemplate.prototype.defaults) {
if(typeof this.config[i] == "undefined") {
this.config[i] = Jemplate.prototype.defaults[i];
}
}
}
proto.process = function(template, data, output) {
var context = this.config.CONTEXT || new Jemplate.Context();
context.config = this.config;
context.stash = new Jemplate.Stash(this.config.STASH, this.config);
context.__filter__ = new Jemplate.Filter();
context.__filter__.config = this.config;
context.__plugin__ = new Jemplate.Plugin();
context.__plugin__.config = this.config;
var result;
var proc = function(input) {
try {
if (typeof context.config.PRE_PROCESS == 'string') context.config.PRE_PROCESS = [context.config.PRE_PROCESS];
for (var i = 0; i < context.config.PRE_PROCESS.length; i++) {
context.process(context.config.PRE_PROCESS[i]);
}
result = context.process(template, input);
if (typeof context.config.POST_PROCESS == 'string') context.config.PRE_PROCESS = [context.config.POST_PROCESS];
for (i = 0; i < context.config.POST_PROCESS.length; i++) {
context.process(context.config.POST_PROCESS[i]);
}
}
catch(e) {
if (! String(e).match(/Jemplate\.STOP\n/))
throw(e);
result = e.toString().replace(/Jemplate\.STOP\n/, '');
}
if (typeof output == 'undefined')
return result;
if (typeof output == 'function') {
output(result);
return null;
}
if (typeof(output) == 'string' || output instanceof String) {
if (output.match(/^#[\w\-]+$/)) {
var id = output.replace(/^#/, '');
var element = document.getElementById(id);
if (typeof element == 'undefined')
throw('No element found with id="' + id + '"');
element.innerHTML = result;
return null;
}
}
else {
output.innerHTML = result;
return null;
}
throw("Invalid arguments in call to Jemplate.process");
return 1;
}
if (typeof data == 'function')
data = data();
else if (typeof data == 'string') {
// Jemplate.Ajax.get(data, function(r) { proc(Jemplate.JSON.parse(r)) });
var url = data;
Jemplate.Ajax.processGet(url, function(data) { proc(data) });
return null;
}
return proc(data);
}
//------------------------------------------------------------------------------
// Jemplate.Context class
//------------------------------------------------------------------------------
if (typeof Jemplate.Context == 'undefined')
Jemplate.Context = function() {};
proto = Jemplate.Context.prototype;
proto.include = function(template, args) {
return this.process(template, args, true);
}
proto.process = function(template, args, localise) {
if (localise)
this.stash.clone(args);
else
this.stash.update(args);
var func = Jemplate.templateMap[template];
if (typeof func == 'undefined')
throw('No Jemplate template named "' + template + '" available');
var output = func(this);
if (localise)
this.stash.declone();
return output;
}
proto.set_error = function(error, output) {
this._error = [error, output];
return error;
}
proto.plugin = function(name, args) {
if (typeof name == 'undefined')
throw "Unknown plugin name ':" + name + "'";
// The Context object (this) is passed as the first argument to the plugin.
var func = eval(name);
return new func(this, args);
}
proto.filter = function(text, name, args) {
if (name == 'null')
name = "null_filter";
if (typeof this.__filter__.filters[name] == "function")
return this.__filter__.filters[name](text, args, this);
else
throw "Unknown filter name ':" + name + "'";
}
//------------------------------------------------------------------------------
// Jemplate.Plugin class
//------------------------------------------------------------------------------
if (typeof Jemplate.Plugin == 'undefined') {
Jemplate.Plugin = function() { };
}
proto = Jemplate.Plugin.prototype;
proto.plugins = {};
//------------------------------------------------------------------------------
// Jemplate.Filter class
//------------------------------------------------------------------------------
if (typeof Jemplate.Filter == 'undefined') {
Jemplate.Filter = function() { };
}
proto = Jemplate.Filter.prototype;
proto.filters = {};
proto.filters.null_filter = function(text) {
return '';
}
proto.filters.upper = function(text) {
return text.toUpperCase();
}
proto.filters.lower = function(text) {
return text.toLowerCase();
}
proto.filters.ucfirst = function(text) {
var first = text.charAt(0);
var rest = text.substr(1);
return first.toUpperCase() + rest;
}
proto.filters.lcfirst = function(text) {
var first = text.charAt(0);
var rest = text.substr(1);
return first.toLowerCase() + rest;
}
proto.filters.trim = function(text) {
return text.replace( /^\s+/g, "" ).replace( /\s+$/g, "" );
}
proto.filters.collapse = function(text) {
return text.replace( /^\s+/g, "" ).replace( /\s+$/g, "" ).replace(/\s+/, " ");
}
proto.filters.html = function(text) {
text = text.replace(/&/g, '&');
text = text.replace(/</g, '<');
text = text.replace(/>/g, '>');
text = text.replace(/"/g, '"'); // " end quote for emacs
return text;
}
proto.filters.html_para = function(text) {
var lines = text.split(/(?:\r?\n){2,}/);
return "<p>\n" + lines.join("\n</p>\n\n<p>\n") + "</p>\n";
}
proto.filters.html_break = function(text) {
return text.replace(/(\r?\n){2,}/g, "$1<br />$1<br />$1");
}
proto.filters.html_line_break = function(text) {
return text.replace(/(\r?\n)/g, "$1<br />$1");
}
proto.filters.uri = function(text) {
return encodeURIComponent(text);
}
proto.filters.url = function(text) {
return encodeURI(text);
}
proto.filters.indent = function(text, args) {
var pad = args[0];
if (! text) return null;
if (typeof pad == 'undefined')
pad = 4;
var finalpad = '';
if (typeof pad == 'number' || String(pad).match(/^\d$/)) {
for (var i = 0; i < pad; i++) {
finalpad += ' ';
}
} else {
finalpad = pad;
}
var output = text.replace(/^/gm, finalpad);
return output;
}
proto.filters.truncate = function(text, args) {
var len = args[0];
if (! text) return null;
if (! len)
len = 32;
// This should probably be <=, but TT just uses <
if (text.length < len)
return text;
var newlen = len - 3;
return text.substr(0,newlen) + '...';
}
proto.filters.repeat = function(text, iter) {
if (! text) return null;
if (! iter || iter == 0)
iter = 1;
if (iter == 1) return text
var output = text;
for (var i = 1; i < iter; i++) {
output += text;
}
return output;
}
proto.filters.replace = function(text, args) {
if (! text) return null;
var re_search = args[0];
var text_replace = args[1];
if (! re_search)
re_search = '';
if (! text_replace)
text_replace = '';
var re = new RegExp(re_search, 'g');
return text.replace(re, text_replace);
}
//------------------------------------------------------------------------------
// Jemplate.Stash class
//------------------------------------------------------------------------------
if (typeof Jemplate.Stash == 'undefined') {
Jemplate.Stash = function(stash, config) {
this.__config__ = config;
this.data = {
GLOBAL : this.__config__.SCOPE
};
this.LOCAL_ANCHOR = {};
this.data.LOCAL = this.LOCAL_ANCHOR;
this.update(stash);
};
}
proto = Jemplate.Stash.prototype;
proto.clone = function(args) {
var data = this.data;
this.data = {
GLOBAL : this.__config__.SCOPE
};
this.data.LOCAL = this.LOCAL_ANCHOR;
this.update(data);
this.update(args);
this.data._PARENT = data;
}
proto.declone = function(args) {
this.data = this.data._PARENT || this.data;
}
proto.update = function(args) {
if (typeof args == 'undefined') return;
for (var key in args) {
if (key != 'GLOBAL' && key != 'LOCAL') {
this.set(key, args[key]);
}
}
}
proto.get = function(ident, args) {
var root = this.data;
var value;
if ( (ident instanceof Array) || (typeof ident == 'string' && /\./.test(ident) ) ) {
if (typeof ident == 'string') {
ident = ident.split('.');
var newIdent = [];
for (var i = 0; i < ident.length; i++) {
newIdent.push(ident.replace(/\(.*$/,''));
newIdent.push(0);
}
ident = newIdent;
}
for (var i = 0; i < ident.length; i += 2) {
var dotopArgs = ident.slice(i, i+2);
dotopArgs.unshift(root);
value = this._dotop.apply(this, dotopArgs);
if (typeof value == 'undefined')
break;
root = value;
}
}
else {
value = this._dotop(root, ident, args);
}
if (typeof value == 'undefined' || value == null) {
if (this.__config__.DEBUG_UNDEF)
throw("undefined value found while using DEBUG_UNDEF");
value = '';
}
return value;
}
proto.set = function(ident, value, set_default) {
var root, result, error;
root = this.data;
while (true) {
if ( (ident instanceof Array) || (typeof ident == 'string' && /\./.test(ident) ) ) {
if (typeof ident == 'string') {
ident = ident.split('.');
var newIdent = [];
for (var i = 0; i < ident.length; i++) {
newIdent.push(ident.replace(/\(.*$/,''));
newIdent.push(0);
}
ident = newIdent;
}
for (var i = 0; i < ident.length - 2; i += 2) {
var dotopArgs = ident.slice(i, i+2);
dotopArgs.unshift(root);
dotopArgs.push(1);
result = this._dotop.apply(this, dotopArgs);
if (typeof value == 'undefined')
break;
root = result;
}
var assignArgs = ident.slice(ident.length-2, ident.length);
assignArgs.unshift(root);
assignArgs.push(value);
assignArgs.push(set_default);
result = this._assign.apply(this, assignArgs);
} else {
result = this._assign(root, ident, 0, value, set_default);
}
break;
}
return (typeof result != 'undefined') ? result : '';
}
proto._dotop = function(root, item, args, lvalue) {
if (root == this.LOCAL_ANCHOR) root = this.data;
var atroot = root == this.data;
var value,result = undefined;
var is_function_call = args instanceof Array;
args = args || [];
if (typeof root == 'undefined' || typeof item == 'undefined' || typeof item == 'string' && item.match(/^[\._]/)) {
return undefined;
}
//root is complex object, not scalar
if (atroot || (root instanceof Object && !(root instanceof Array)) || root == this.data.GLOBAL) {
if (typeof root[item] != 'undefined' && root[item] != null && (!is_function_call || !this.hash_functions[item])) { //consider undefined == null
if (typeof root[item] == 'function') {
result = root[item].apply(root,args);
} else {
return root[item];
}
} else if (lvalue) {
return root[item] = {};
} else if (this.hash_functions[item] && !atroot || item == 'import') {
args.unshift(root);
result = this.hash_functions[item].apply(this,args);
} else if (item instanceof Array) {
result = {};
for (var i = 0; i < item.length; i++) result[item[i]] = root[item[i]];
return result;
}
} else if (root instanceof Array) {
if (this.list_functions[item]) {
args.unshift(root);
result = this.list_functions[item].apply(this,args);
} else if (typeof item == 'string' && /^-?\d+$/.test(item) || typeof item == 'number' ) {
if (typeof root[item] != 'function') return root[item];
result = root[item].apply(this, args);
} else if (item instanceof Array) {
for (var i = 0; i < item.length; i++) result.push(root[item[i]]);
return result;
}
} else if (this.string_functions[item] && !lvalue) {
args.unshift(root);
result = this.string_functions[item].apply(this, args);
} else if (this.list_functions[item] && !lvalue) {
args.unshift([root]);
result = this.list_functions[item].apply(this,args);
} else {
result = undefined;
}
if (result instanceof Array) {
if (typeof result[0] == 'undefined' && typeof result[1] != 'undefined') {
throw result[1];
}
}
return result;
}
proto._assign = function(root, item, args, value, set_default) {
var atroot = root == this.data;
var result;
args = args || [];
if (typeof root == 'undefined' || typeof item == 'undefined' || typeof item == 'string' && item.match(/^[\._]/)) {
return undefined;
}
if (atroot || root.constructor == Object || root == this.data.GLOBAL) {
if (root == this.LOCAL_ANCHOR) root = this.data;
if (!(set_default && typeof root[item] != 'undefined')) {
if (atroot && item == 'GLOBAL') throw "Attempt to modify GLOBAL access modifier"
if (atroot && item == 'LOCAL') throw "Attempt to modify LOCAL access modifier"
return root[item] = value;
}
} else if ((root instanceof Array) && (typeof item == 'string' && /^-?\d+$/.test(item) || typeof item == 'number' )) {
if (!(set_default && typeof root[item] != 'undefined')) {
return root[item] = value;
}
} else if ( (root.constructor != Object) && (root instanceof Object) ) {
try {
result = root[item].apply(root,args);
} catch (e) {
}
} else {
throw 'dont know how to assign to [' + root + '.' + item +']';
}
return undefined;
}
proto.string_functions = {};
// typeof
proto.string_functions['typeof'] = function(value) {
return typeof value;
}
// chunk(size) negative size chunks from end
proto.string_functions.chunk = function(string, size) {
//var size = args;
var list = new Array();
if (! size)
size = 1;
if (size < 0) {
size = 0 - size;
for (var i = string.length - size; i >= 0; i = i - size)
list.unshift(string.substr(i, size));
if (string.length % size)
list.unshift(string.substr(0, string.length % size));
}
else
for (i = 0; i < string.length; i = i + size)
list.push(string.substr(i, size));
return list;
}
// defined is value defined?
proto.string_functions.defined = function(string) {
return 1;
}
// hash treat as single-element hash with key value
proto.string_functions.hash = function(string) {
return { 'value': string };
}
// length length of string representation
proto.string_functions.length = function(string) {
return string.length;
}
// list treat as single-item list
proto.string_functions.list = function(string) {
return [ string ];
}
// match(re) get list of matches
proto.string_functions.match = function(string, re, modifiers) {
var regexp = new RegExp(re, modifiers == undefined ? 'g' : modifiers);
var list = string.match(regexp);
return list;
}
// repeat(n) repeated n times
proto.string_functions.repeat = function(string, args) {
var n = args || 1;
var output = '';
for (var i = 0; i < n; i++) {
output += string;
}
return output;
}
// replace(re, sub, global) replace instances of re with sub
proto.string_functions.replace = function(string, re, sub, modifiers) {
var regexp = new RegExp(re, modifiers == undefined ? 'g' : modifiers);
if (! sub) sub = '';
return string.replace(regexp, sub);
}
// search(re) true if value matches re
proto.string_functions.search = function(string, re) {
var regexp = new RegExp(re);
return (string.search(regexp) >= 0) ? 1 : 0;
}
// size returns 1, as if a single-item list
proto.string_functions.size = function(string) {
return 1;
}
// split(re) split string on re
proto.string_functions.split = function(string, re) {
var regexp = new RegExp(re);
var list = string.split(regexp);
return list;
}
proto.list_functions = {};
// typeof
proto.list_functions['typeof'] = function(list) {
return 'array';
};
proto.list_functions.list = function(list) {
return list;
};
proto.list_functions.join = function(list, str) {
return list.join(str);
};
proto.list_functions.sort = function(list,key) {
if( typeof(key) != 'undefined' && key != "" ) {
// we probably have a list of hashes
// and need to sort based on hash key
return list.sort(
function(a,b) {
if( a[key] == b[key] ) {
return 0;
}
else if( a[key] > b[key] ) {
return 1;
}
else {
return -1;
}
}
);
}
return list.sort();
}
proto.list_functions.nsort = function(list) {
return list.sort(function(a, b) { return (a-b) });
}
proto.list_functions.grep = function(list, re) {
var regexp = new RegExp(re);
var result = [];
for (var i = 0; i < list.length; i++) {
if (list[i].match(regexp))
result.push(list[i]);
}
return result;
}
proto.list_functions.unique = function(list) {
var result = [];
var seen = {};
for (var i = 0; i < list.length; i++) {
var elem = list[i];
if (! seen[elem])
result.push(elem);
seen[elem] = true;
}
return result;
}
proto.list_functions.reverse = function(list) {
var result = [];
for (var i = list.length - 1; i >= 0; i--) {
result.push(list[i]);
}
return result;
}
proto.list_functions.merge = function(list /*, ... args */) {
var result = [];
var push_all = function(elem) {
if (elem instanceof Array) {
for (var j = 0; j < elem.length; j++) {
result.push(elem[j]);
}
}
else {
result.push(elem);
}
}
push_all(list);
for (var i = 1; i < arguments.length; i++) {
push_all(arguments[i]);
}
return result;
}
proto.list_functions.slice = function(list, start, end) {
// To make it like slice in TT
// See rt53453
if ( end == -1 ) {
return list.slice( start );
}
return list.slice( start, end + 1 );
}
proto.list_functions.splice = function(list /*, ... args */ ) {
var args = Array.prototype.slice.call(arguments);
args.shift();
return list.splice.apply(list,args);
}
proto.list_functions.push = function(list, value) {
list.push(value);
return list;
}
proto.list_functions.pop = function(list) {
return list.pop();
}
proto.list_functions.unshift = function(list, value) {
list.unshift(value);
return list;
}
proto.list_functions.shift = function(list) {
return list.shift();
}
proto.list_functions.first = function(list) {
return list[0];
}
proto.list_functions.size = function(list) {
return list.length;
}
proto.list_functions.max = function(list) {
return list.length - 1;
}
proto.list_functions.last = function(list) {
return list.slice(-1);
}
proto.hash_functions = {};
// typeof
proto.hash_functions['typeof'] = function(hash) {
return 'object';
};
// each list of alternating keys/values
proto.hash_functions.each = function(hash) {
var list = new Array();
for ( var key in hash )
list.push(key, hash[key]);
return list;
}
// exists(key) does key exist?
proto.hash_functions.exists = function(hash, key) {
return ( typeof( hash[key] ) == "undefined" ) ? 0 : 1;
}
// import(hash2) import contents of hash2
// import import into current namespace hash
proto.hash_functions['import'] = function(hash, hash2) {
for ( var key in hash2 )
hash[key] = hash2[key];
return '';
}
// keys list of keys
proto.hash_functions.keys = function(hash) {
var list = new Array();
for ( var key in hash )
list.push(key);
return list;
}
// list returns alternating key, value
proto.hash_functions.list = function(hash, what) {
//var what = '';
//if ( args )
//what = args[0];
var list = new Array();
var key;
if (what == 'keys')
for ( key in hash )
list.push(key);
else if (what == 'values')
for ( key in hash )
list.push(hash[key]);
else if (what == 'each')
for ( key in hash )
list.push(key, hash[key]);
else
for ( key in hash )
list.push({ 'key': key, 'value': hash[key] });
return list;
}
// nsort keys sorted numerically
proto.hash_functions.nsort = function(hash) {
var list = new Array();
for (var key in hash)
list.push(key);
return list.sort(function(a, b) { return (a-b) });
}
// item return a value by key
proto.hash_functions.item = function(hash, key) {
return hash[key];
}
// size number of pairs
proto.hash_functions.size = function(hash) {
var size = 0;
for (var key in hash)
size++;
return size;
}
// sort keys sorted alphabetically
proto.hash_functions.sort = function(hash) {
var list = new Array();
for (var key in hash)
list.push(key);
return list.sort();
}
// values list of values
proto.hash_functions.values = function(hash) {
var list = new Array();
for ( var key in hash )
list.push(hash[key]);
return list;
}
proto.hash_functions.pairs = function(hash) {
var list = new Array();
var keys = new Array();
for ( var key in hash ) {
keys.push( key );
}
keys.sort();
for ( var key in keys ) {
key = keys[key]
list.push( { 'key': key, 'value': hash[key] } );
}
return list;
}
// delete
proto.hash_functions.remove = function(hash, key) {
return delete hash[key];
}
proto.hash_functions['delete'] = proto.hash_functions.remove;
//------------------------------------------------------------------------------
// Jemplate.Iterator class
//------------------------------------------------------------------------------
if (typeof Jemplate.Iterator == 'undefined') {
Jemplate.Iterator = function(object) {
if( object instanceof Array ) {
this.object = object;
this.size = object.length;
this.max = this.size -1;
}
else if ( object instanceof Object ) {
this.object = object;
var object_keys = new Array;
for( var key in object ) {
object_keys[object_keys.length] = key;
}
this.object_keys = object_keys.sort();
this.size = object_keys.length;
this.max = this.size -1;
} else if (typeof object == 'undefined' || object == null || object == '') {
this.object = null;
this.max = -1;
}
}
}
proto = Jemplate.Iterator.prototype;
proto.get_first = function() {
this.index = 0;
this.first = 1;
this.last = 0;
this.count = 1;
return this.get_next(1);
}
proto.get_next = function(should_init) {
var object = this.object;
var index;
if( typeof(should_init) != 'undefined' && should_init ) {
index = this.index;
} else {
index = ++this.index;
this.first = 0;
this.count = this.index + 1;
if( this.index == this.size -1 ) {
this.last = 1;
}
}
if (typeof object == 'undefined')
throw('No object to iterate');
if( this.object_keys ) {
if (index < this.object_keys.length) {
this.prev = index > 0 ? this.object_keys[index - 1] : "";
this.next = index < this.max ? this.object_keys[index + 1] : "";
return [this.object_keys[index], false];
}
} else {
if (index <= this.max) {
this.prev = index > 0 ? object[index - 1] : "";
this.next = index < this.max ? object[index +1] : "";
return [object[index], false];
}
}
return [null, true];
}
var stubExplanation = "stub that doesn't do anything. Try including the jQuery, YUI, or XHR option when building the runtime";
Jemplate.Ajax = {
get: function(url, callback) {
throw("This is a Jemplate.Ajax.get " + stubExplanation);
},
processGet: function(url, callback) {
throw("This is a Jemplate.Ajax.processGet " + stubExplanation);
},
post: function(url, callback) {
throw("This is a Jemplate.Ajax.post " + stubExplanation);
}
};
Jemplate.JSON = {
parse: function(decodeValue) {
throw("This is a Jemplate.JSON.parse " + stubExplanation);
},
stringify: function(encodeValue) {
throw("This is a Jemplate.JSON.stringify " + stubExplanation);
}
};
}());
...
}
sub ajax_jquery {
<<'...';
;(function(){
Jemplate.Ajax = {
get: function(url, callback) {
jQuery.get(url, null, callback);
},
processGet: function(url, processor) {
jQuery.getJSON(url, null, processor);
},
post: function(url, data, callback) {
jQuery.post(url, data, callback);
}
};
}());
...
}
sub ajax_xhr {
<<'...';
;(function(){
Jemplate.Ajax = {
get: function(url, callback) {
var request = new XMLHttpRequest();
request.open('GET', url, Boolean(callback));
request.setRequestHeader('Accept', 'text/json; text/x-json; application/json');
return this.request(request, null, callback);
},
processGet: function(url, processor) {
this.get(url, function(responseText){
processor(Jemplate.JSON.parse(responseText));
});
},
post: function(url, data, callback) {
var request = new XMLHttpRequest();
request.open('POST', url, Boolean(callback));
request.setRequestHeader('Accept', 'text/json; text/x-json; application/json');
request.setRequestHeader(
'Content-Type', 'application/x-www-form-urlencoded'
);
return this.request(request, data, callback);
},
request: function(request, data, callback) {
if (callback) {
request.onreadystatechange = function() {
if (request.readyState == 4) {
if(request.status == 200)
callback(request.responseText);
}
};
}
request.send(data);
if (!callback) {
if (request.status != 200)
throw('Request for "' + url +
'" failed with status: ' + request.status);
return request.responseText;
}
return null;
}
};
}());
...
}
sub ajax_yui {
<<'...';
;(function(){
Jemplate.Ajax = {
get: function(url, callback) {
if (typeof callback == "function") {
callback = { success: callback };
}
YAHOO.connect.asyncRequest("GET", url, callback);
},
processGet: function(url, processor) {
this.get(url, function(responseText){
processor(YAHOO.lang.JSON.parse(responseText));
});
},
post: function(url, data, callback) {
if (typeof callback == "function") {
callback = { success: callback };
}
YAHOO.connect.asyncRequest("POST", url, callback, data);
}
};
}());
...
}
sub json_json2 {
<<'...';
;(function(){
Jemplate.JSON = {
parse: function(encoded) {
return JSON.parse(encoded);
},
stringify: function(decoded) {
return JSON.stringify(decoded);
}
};
}());
...
}
sub json_json2_internal {
<<'...';
;(function(){
var JSON;
/*
http://www.JSON.org/json2.js
2009-04-16
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See http://www.JSON.org/js.html
This file creates a global JSON object containing two methods: stringify
and parse.
JSON.stringify(value, replacer, space)
value any JavaScript value, usually an object or array.
replacer an optional parameter that determines how object
values are stringified for objects. It can be a
function or an array of strings.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as '\t' or ' '),
it contains the characters used to indent at each level.
This method produces a JSON text from a JavaScript value.
When an object value is found, if the object contains a toJSON
method, its toJSON method will be called and the result will be
stringified. A toJSON method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The toJSON method
will be passed the key associated with the value, and this will be
bound to the object holding the key.
For example, this would serialize Dates as ISO strings.
Date.prototype.toJSON = function (key) {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
You can provide an optional replacer method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
If the replacer parameter is an array of strings, then it will be
used to select the members to be serialized. It filters the results
such that only members with keys listed in the replacer array are
stringified.
Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
Example:
text = JSON.stringify(['e', {pluribus: 'unum'}]);
// text is '["e",{"pluribus":"unum"}]'
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
text = JSON.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
});
// text is '["Date(---current time---)"]'
JSON.parse(text, reviver)
This method parses a JSON text to produce an object or array.
It can throw a SyntaxError exception.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
Example:
// Parse the text. Values that look like ISO date strings will
// be converted to Date objects.
myData = JSON.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
});
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
}
}
return value;
});
This is a reference implementation. You are free to copy, modify, or
redistribute.
This code should be minified before deployment.
See http://javascript.crockford.com/jsmin.html
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
NOT CONTROL.
*/
/*jslint evil: true */
/*global JSON */
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
lastIndex, length, parse, prototype, push, replace, slice, stringify,
test, toJSON, toString, valueOf
*/
// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.
if (!this.JSON) {
this.JSON = {};
}
(function () {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
if (typeof Date.prototype.toJSON !== 'function') {
Date.prototype.toJSON = function (key) {
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function (key) {
return this.valueOf();
};
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap,
indent,
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep;
function quote(string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
escapable.lastIndex = 0;
return escapable.test(string) ?
'"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string' ? c :
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' :
'"' + string + '"';
}
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0 ? '[]' :
gap ? '[\n' + gap +
partial.join(',\n' + gap) + '\n' +
mind + ']' :
'[' + partial.join(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
k = rep[i];
if (typeof k === 'string') {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0 ? '{}' :
gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
mind + '}' : '{' + partial.join(',') + '}';
gap = mind;
return v;
}
return '';
}
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
JSON.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var i;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
// If the space parameter is a string, it will be used as the indent string.
} else if (typeof space === 'string') {
indent = space;
}
// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', {'': value});
};
}
// If the JSON object does not yet have a parse method, give it one.
if (typeof JSON.parse !== 'function') {
JSON.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.
var j;
function walk(holder, key) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return typeof reviver === 'function' ?
walk({'': j}, '') : j;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.
throw new SyntaxError('JSON.parse');
};
}
}());
Jemplate.JSON = {
parse: function(encoded) {
return JSON.parse(encoded);
},
stringify: function(decoded) {
return JSON.stringify(decoded);
}
};
}());
...
}
sub json_yui {
<<'...';
;(function(){
Jemplate.JSON = {
parse: function(encoded) {
return YAHOO.lang.JSON.parse(encoded);
},
stringify: function(decoded) {
return YAHOO.lang.JSON.stringify(decoded);
}
};
}());
...
}
sub json2 {
<<'...';
/*
http://www.JSON.org/json2.js
2009-04-16
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See http://www.JSON.org/js.html
This file creates a global JSON object containing two methods: stringify
and parse.
JSON.stringify(value, replacer, space)
value any JavaScript value, usually an object or array.
replacer an optional parameter that determines how object
values are stringified for objects. It can be a
function or an array of strings.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as '\t' or ' '),
it contains the characters used to indent at each level.
This method produces a JSON text from a JavaScript value.
When an object value is found, if the object contains a toJSON
method, its toJSON method will be called and the result will be
stringified. A toJSON method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The toJSON method
will be passed the key associated with the value, and this will be
bound to the object holding the key.
For example, this would serialize Dates as ISO strings.
Date.prototype.toJSON = function (key) {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
You can provide an optional replacer method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
If the replacer parameter is an array of strings, then it will be
used to select the members to be serialized. It filters the results
such that only members with keys listed in the replacer array are
stringified.
Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
Example:
text = JSON.stringify(['e', {pluribus: 'unum'}]);
// text is '["e",{"pluribus":"unum"}]'
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
text = JSON.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
});
// text is '["Date(---current time---)"]'
JSON.parse(text, reviver)
This method parses a JSON text to produce an object or array.
It can throw a SyntaxError exception.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
Example:
// Parse the text. Values that look like ISO date strings will
// be converted to Date objects.
myData = JSON.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
});
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
}
}
return value;
});
This is a reference implementation. You are free to copy, modify, or
redistribute.
This code should be minified before deployment.
See http://javascript.crockford.com/jsmin.html
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
NOT CONTROL.
*/
/*jslint evil: true */
/*global JSON */
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
lastIndex, length, parse, prototype, push, replace, slice, stringify,
test, toJSON, toString, valueOf
*/
// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.
if (!this.JSON) {
this.JSON = {};
}
(function () {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
if (typeof Date.prototype.toJSON !== 'function') {
Date.prototype.toJSON = function (key) {
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function (key) {
return this.valueOf();
};
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap,
indent,
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep;
function quote(string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
escapable.lastIndex = 0;
return escapable.test(string) ?
'"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string' ? c :
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' :
'"' + string + '"';
}
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0 ? '[]' :
gap ? '[\n' + gap +
partial.join(',\n' + gap) + '\n' +
mind + ']' :
'[' + partial.join(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
k = rep[i];
if (typeof k === 'string') {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0 ? '{}' :
gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
mind + '}' : '{' + partial.join(',') + '}';
gap = mind;
return v;
}
return '';
}
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
JSON.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var i;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
// If the space parameter is a string, it will be used as the indent string.
} else if (typeof space === 'string') {
indent = space;
}
// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', {'': value});
};
}
// If the JSON object does not yet have a parse method, give it one.
if (typeof JSON.parse !== 'function') {
JSON.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.
var j;
function walk(holder, key) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return typeof reviver === 'function' ?
walk({'': j}, '') : j;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.
throw new SyntaxError('JSON.parse');
};
}
}());
...
}
sub xhr_gregory {
<<'...';
/*
Cross-Browser XMLHttpRequest v1.2
=================================
Emulate Gecko 'XMLHttpRequest()' functionality in IE and Opera. Opera requires
the Sun Java Runtime Environment <http://www.java.com/>.
by Andrew Gregory
http://www.scss.com.au/family/andrew/webdesign/xmlhttprequest/
This work is licensed under the Creative Commons Attribution License. To view a
copy of this license, visit http://creativecommons.org/licenses/by-sa/2.5/ or
send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California
94305, USA.
Attribution: Leave my name and web address in this script intact.
Not Supported in Opera
----------------------
* user/password authentication
* responseXML data member
Not Fully Supported in Opera
----------------------------
* async requests
* abort()
* getAllResponseHeaders(), getAllResponseHeader(header)
*/
// IE support
if (window.ActiveXObject && !window.XMLHttpRequest) {
window.XMLHttpRequest = function() {
var msxmls = new Array(
'Msxml2.XMLHTTP.5.0',
'Msxml2.XMLHTTP.4.0',
'Msxml2.XMLHTTP.3.0',
'Msxml2.XMLHTTP',
'Microsoft.XMLHTTP');
for (var i = 0; i < msxmls.length; i++) {
try {
return new ActiveXObject(msxmls[i]);
} catch (e) {
}
}
return null;
};
}
// Gecko support
/* ;-) */
// Opera support
if (window.opera && !window.XMLHttpRequest) {
window.XMLHttpRequest = function() {
this.readyState = 0; // 0=uninitialized,1=loading,2=loaded,3=interactive,4=complete
this.status = 0; // HTTP status codes
this.statusText = '';
this._headers = [];
this._aborted = false;
this._async = true;
this._defaultCharset = 'ISO-8859-1';
this._getCharset = function() {
var charset = _defaultCharset;
var contentType = this.getResponseHeader('Content-type').toUpperCase();
val = contentType.indexOf('CHARSET=');
if (val != -1) {
charset = contentType.substring(val);
}
val = charset.indexOf(';');
if (val != -1) {
charset = charset.substring(0, val);
}
val = charset.indexOf(',');
if (val != -1) {
charset = charset.substring(0, val);
}
return charset;
};
this.abort = function() {
this._aborted = true;
};
this.getAllResponseHeaders = function() {
return this.getAllResponseHeader('*');
};
this.getAllResponseHeader = function(header) {
var ret = '';
for (var i = 0; i < this._headers.length; i++) {
if (header == '*' || this._headers[i].h == header) {
ret += this._headers[i].h + ': ' + this._headers[i].v + '\n';
}
}
return ret;
};
this.getResponseHeader = function(header) {
var ret = getAllResponseHeader(header);
var i = ret.indexOf('\n');
if (i != -1) {
ret = ret.substring(0, i);
}
return ret;
};
this.setRequestHeader = function(header, value) {
this._headers[this._headers.length] = {h:header, v:value};
};
this.open = function(method, url, async, user, password) {
this.method = method;
this.url = url;
this._async = true;
this._aborted = false;
this._headers = [];
if (arguments.length >= 3) {
this._async = async;
}
if (arguments.length > 3) {
opera.postError('XMLHttpRequest.open() - user/password not supported');
}
this.readyState = 1;
if (this.onreadystatechange) {
this.onreadystatechange();
}
};
this.send = function(data) {
if (!navigator.javaEnabled()) {
alert("XMLHttpRequest.send() - Java must be installed and enabled.");
return;
}
if (this._async) {
setTimeout(this._sendasync, 0, this, data);
// this is not really asynchronous and won't execute until the current
// execution context ends
} else {
this._sendsync(data);
}
}
this._sendasync = function(req, data) {
if (!req._aborted) {
req._sendsync(data);
}
};
this._sendsync = function(data) {
this.readyState = 2;
if (this.onreadystatechange) {
this.onreadystatechange();
}
// open connection
var url = new java.net.URL(new java.net.URL(window.location.href), this.url);
var conn = url.openConnection();
for (var i = 0; i < this._headers.length; i++) {
conn.setRequestProperty(this._headers[i].h, this._headers[i].v);
}
this._headers = [];
if (this.method == 'POST') {
// POST data
conn.setDoOutput(true);
var wr = new java.io.OutputStreamWriter(conn.getOutputStream(), this._getCharset());
wr.write(data);
wr.flush();
wr.close();
}
// read response headers
// NOTE: the getHeaderField() methods always return nulls for me :(
var gotContentEncoding = false;
var gotContentLength = false;
var gotContentType = false;
var gotDate = false;
var gotExpiration = false;
var gotLastModified = false;
for (var i = 0; ; i++) {
var hdrName = conn.getHeaderFieldKey(i);
var hdrValue = conn.getHeaderField(i);
if (hdrName == null && hdrValue == null) {
break;
}
if (hdrName != null) {
this._headers[this._headers.length] = {h:hdrName, v:hdrValue};
switch (hdrName.toLowerCase()) {
case 'content-encoding': gotContentEncoding = true; break;
case 'content-length' : gotContentLength = true; break;
case 'content-type' : gotContentType = true; break;
case 'date' : gotDate = true; break;
case 'expires' : gotExpiration = true; break;
case 'last-modified' : gotLastModified = true; break;
}
}
}
// try to fill in any missing header information
var val;
val = conn.getContentEncoding();
if (val != null && !gotContentEncoding) this._headers[this._headers.length] = {h:'Content-encoding', v:val};
val = conn.getContentLength();
if (val != -1 && !gotContentLength) this._headers[this._headers.length] = {h:'Content-length', v:val};
val = conn.getContentType();
if (val != null && !gotContentType) this._headers[this._headers.length] = {h:'Content-type', v:val};
val = conn.getDate();
if (val != 0 && !gotDate) this._headers[this._headers.length] = {h:'Date', v:(new Date(val)).toUTCString()};
val = conn.getExpiration();
if (val != 0 && !gotExpiration) this._headers[this._headers.length] = {h:'Expires', v:(new Date(val)).toUTCString()};
val = conn.getLastModified();
if (val != 0 && !gotLastModified) this._headers[this._headers.length] = {h:'Last-modified', v:(new Date(val)).toUTCString()};
// read response data
var reqdata = '';
var stream = conn.getInputStream();
if (stream) {
var reader = new java.io.BufferedReader(new java.io.InputStreamReader(stream, this._getCharset()));
var line;
while ((line = reader.readLine()) != null) {
if (this.readyState == 2) {
this.readyState = 3;
if (this.onreadystatechange) {
this.onreadystatechange();
}
}
reqdata += line + '\n';
}
reader.close();
this.status = 200;
this.statusText = 'OK';
this.responseText = reqdata;
this.readyState = 4;
if (this.onreadystatechange) {
this.onreadystatechange();
}
if (this.onload) {
this.onload();
}
} else {
// error
this.status = 404;
this.statusText = 'Not Found';
this.responseText = '';
this.readyState = 4;
if (this.onreadystatechange) {
this.onreadystatechange();
}
if (this.onerror) {
this.onerror();
}
}
};
};
}
// ActiveXObject emulation
if (!window.ActiveXObject && window.XMLHttpRequest) {
window.ActiveXObject = function(type) {
switch (type.toLowerCase()) {
case 'microsoft.xmlhttp':
case 'msxml2.xmlhttp':
case 'msxml2.xmlhttp.3.0':
case 'msxml2.xmlhttp.4.0':
case 'msxml2.xmlhttp.5.0':
return new XMLHttpRequest();
}
return null;
};
}
...
}
sub xhr_ilinsky {
<<'...';
// Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
(function () {
// Save reference to earlier defined object implementation (if any)
var oXMLHttpRequest = window.XMLHttpRequest;
// Define on browser type
var bGecko = !!window.controllers,
bIE = window.document.all && !window.opera;
// Constructor
function cXMLHttpRequest() {
this._object = oXMLHttpRequest ? new oXMLHttpRequest : new window.ActiveXObject('Microsoft.XMLHTTP');
};
// BUGFIX: Firefox with Firebug installed would break pages if not executed
if (bGecko && oXMLHttpRequest.wrapped)
cXMLHttpRequest.wrapped = oXMLHttpRequest.wrapped;
// Constants
cXMLHttpRequest.UNSENT = 0;
cXMLHttpRequest.OPENED = 1;
cXMLHttpRequest.HEADERS_RECEIVED = 2;
cXMLHttpRequest.LOADING = 3;
cXMLHttpRequest.DONE = 4;
// Public Properties
cXMLHttpRequest.prototype.readyState = cXMLHttpRequest.UNSENT;
cXMLHttpRequest.prototype.responseText = "";
cXMLHttpRequest.prototype.responseXML = null;
cXMLHttpRequest.prototype.status = 0;
cXMLHttpRequest.prototype.statusText = "";
// Instance-level Events Handlers
cXMLHttpRequest.prototype.onreadystatechange = null;
// Class-level Events Handlers
cXMLHttpRequest.onreadystatechange = null;
cXMLHttpRequest.onopen = null;
cXMLHttpRequest.onsend = null;
cXMLHttpRequest.onabort = null;
// Public Methods
cXMLHttpRequest.prototype.open = function(sMethod, sUrl, bAsync, sUser, sPassword) {
// Save async parameter for fixing Gecko bug with missing readystatechange in synchronous requests
this._async = bAsync;
// Set the onreadystatechange handler
var oRequest = this,
nState = this.readyState;
// BUGFIX: IE - memory leak on page unload (inter-page leak)
if (bIE) {
var fOnUnload = function() {
if (oRequest._object.readyState != cXMLHttpRequest.DONE)
fCleanTransport(oRequest);
};
if (bAsync)
window.attachEvent("onunload", fOnUnload);
}
this._object.onreadystatechange = function() {
if (bGecko && !bAsync)
return;
// Synchronize state
oRequest.readyState = oRequest._object.readyState;
//
fSynchronizeValues(oRequest);
// BUGFIX: Firefox fires unneccesary DONE when aborting
if (oRequest._aborted) {
// Reset readyState to UNSENT
oRequest.readyState = cXMLHttpRequest.UNSENT;
// Return now
return;
}
if (oRequest.readyState == cXMLHttpRequest.DONE) {
//
fCleanTransport(oRequest);
// Uncomment this block if you need a fix for IE cache
/*
// BUGFIX: IE - cache issue
if (!oRequest._object.getResponseHeader("Date")) {
// Save object to cache
oRequest._cached = oRequest._object;
// Instantiate a new transport object
cXMLHttpRequest.call(oRequest);
// Re-send request
oRequest._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
oRequest._object.setRequestHeader("If-Modified-Since", oRequest._cached.getResponseHeader("Last-Modified") || new window.Date(0));
// Copy headers set
if (oRequest._headers)
for (var sHeader in oRequest._headers)
if (typeof oRequest._headers[sHeader] == "string") // Some frameworks prototype objects with functions
oRequest._object.setRequestHeader(sHeader, oRequest._headers[sHeader]);
oRequest._object.onreadystatechange = function() {
// Synchronize state
oRequest.readyState = oRequest._object.readyState;
if (oRequest._aborted) {
//
oRequest.readyState = cXMLHttpRequest.UNSENT;
// Return
return;
}
if (oRequest.readyState == cXMLHttpRequest.DONE) {
// Clean Object
fCleanTransport(oRequest);
// get cached request
if (oRequest.status == 304)
oRequest._object = oRequest._cached;
//
delete oRequest._cached;
//
fSynchronizeValues(oRequest);
//
fReadyStateChange(oRequest);
// BUGFIX: IE - memory leak in interrupted
if (bIE && bAsync)
window.detachEvent("onunload", fOnUnload);
}
};
oRequest._object.send(null);
// Return now - wait untill re-sent request is finished
return;
};
*/
// BUGFIX: IE - memory leak in interrupted
if (bIE && bAsync)
window.detachEvent("onunload", fOnUnload);
}
// BUGFIX: Some browsers (Internet Explorer, Gecko) fire OPEN readystate twice
if (nState != oRequest.readyState)
fReadyStateChange(oRequest);
nState = oRequest.readyState;
};
// Add method sniffer
if (cXMLHttpRequest.onopen)
cXMLHttpRequest.onopen.apply(this, arguments);
this._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
// BUGFIX: Gecko - missing readystatechange calls in synchronous requests
if (!bAsync && bGecko) {
this.readyState = cXMLHttpRequest.OPENED;
fReadyStateChange(this);
}
};
cXMLHttpRequest.prototype.send = function(vData) {
// Add method sniffer
if (cXMLHttpRequest.onsend)
cXMLHttpRequest.onsend.apply(this, arguments);
// BUGFIX: Safari - fails sending documents created/modified dynamically, so an explicit serialization required
// BUGFIX: IE - rewrites any custom mime-type to "text/xml" in case an XMLNode is sent
// BUGFIX: Gecko - fails sending Element (this is up to the implementation either to standard)
if (vData && vData.nodeType) {
vData = window.XMLSerializer ? new window.XMLSerializer().serializeToString(vData) : vData.xml;
if (!this._headers["Content-Type"])
this._object.setRequestHeader("Content-Type", "application/xml");
}
this._object.send(vData);
// BUGFIX: Gecko - missing readystatechange calls in synchronous requests
if (bGecko && !this._async) {
this.readyState = cXMLHttpRequest.OPENED;
// Synchronize state
fSynchronizeValues(this);
// Simulate missing states
while (this.readyState < cXMLHttpRequest.DONE) {
this.readyState++;
fReadyStateChange(this);
// Check if we are aborted
if (this._aborted)
return;
}
}
};
cXMLHttpRequest.prototype.abort = function() {
// Add method sniffer
if (cXMLHttpRequest.onabort)
cXMLHttpRequest.onabort.apply(this, arguments);
// BUGFIX: Gecko - unneccesary DONE when aborting
if (this.readyState > cXMLHttpRequest.UNSENT)
this._aborted = true;
this._object.abort();
// BUGFIX: IE - memory leak
fCleanTransport(this);
};
cXMLHttpRequest.prototype.getAllResponseHeaders = function() {
return this._object.getAllResponseHeaders();
};
cXMLHttpRequest.prototype.getResponseHeader = function(sName) {
return this._object.getResponseHeader(sName);
};
cXMLHttpRequest.prototype.setRequestHeader = function(sName, sValue) {
// BUGFIX: IE - cache issue
if (!this._headers)
this._headers = {};
this._headers[sName] = sValue;
return this._object.setRequestHeader(sName, sValue);
};
cXMLHttpRequest.prototype.toString = function() {
return '[' + "object" + ' ' + "XMLHttpRequest" + ']';
};
cXMLHttpRequest.toString = function() {
return '[' + "XMLHttpRequest" + ']';
};
// Helper function
function fReadyStateChange(oRequest) {
// Execute onreadystatechange
if (oRequest.onreadystatechange)
oRequest.onreadystatechange.apply(oRequest);
// Sniffing code
if (cXMLHttpRequest.onreadystatechange)
cXMLHttpRequest.onreadystatechange.apply(oRequest);
};
function fGetDocument(oRequest) {
var oDocument = oRequest.responseXML;
// Try parsing responseText
if (bIE && oDocument && !oDocument.documentElement && oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)) {
oDocument = new ActiveXObject('Microsoft.XMLDOM');
oDocument.loadXML(oRequest.responseText);
}
// Check if there is no error in document
if (oDocument)
if ((bIE && oDocument.parseError != 0) || (oDocument.documentElement && oDocument.documentElement.tagName == "parsererror"))
return null;
return oDocument;
};
function fSynchronizeValues(oRequest) {
try { oRequest.responseText = oRequest._object.responseText; } catch (e) {}
try { oRequest.responseXML = fGetDocument(oRequest._object); } catch (e) {}
try { oRequest.status = oRequest._object.status; } catch (e) {}
try { oRequest.statusText = oRequest._object.statusText; } catch (e) {}
};
function fCleanTransport(oRequest) {
// BUGFIX: IE - memory leak (on-page leak)
oRequest._object.onreadystatechange = new window.Function;
// Delete private properties
delete oRequest._headers;
};
// Internet Explorer 5.0 (missing apply)
if (!window.Function.prototype.apply) {
window.Function.prototype.apply = function(oRequest, oArguments) {
if (!oArguments)
oArguments = [];
oRequest.__func = this;
oRequest.__func(oArguments[0], oArguments[1], oArguments[2], oArguments[3], oArguments[4]);
delete oRequest.__func;
};
};
// Register new object with window
window.XMLHttpRequest = cXMLHttpRequest;
})();
...
}
sub xxx {
<<'...';
//------------------------------------------------------------------------------
// Debugging Support
//------------------------------------------------------------------------------
function XXX(msg) {
if (! confirm(msg))
throw("terminated...");
return msg;
}
function JJJ(obj) {
return XXX(JSON.stringify(obj));
}
...
}
1;
}
#
# Inline include of Jemplate/Runtime/Compact.pm
#
BEGIN { $INC{'Jemplate/Runtime/Compact.pm'} = 'dummy/Jemplate/Runtime/Compact.pm'; }
BEGIN {
#line 0 "Jemplate/Runtime/Compact.pm"
package Jemplate::Runtime::Compact;
use strict;
use warnings;
sub main { return &kernel }
sub kernel {
<<'...';
if(typeof Jemplate=="undefined"){var Jemplate=function(){this.init.apply(this,arguments)}}Jemplate.VERSION="0.22";Jemplate.process=function(){var A=new Jemplate(Jemplate.prototype.config);return A.process.apply(A,arguments)};(function(){if(!Jemplate.templateMap){Jemplate.templateMap={}}var proto=Jemplate.prototype={};proto.config={AUTO_RESET:true,BLOCKS:{},CONTEXT:null,DEBUG_UNDEF:false,DEFAULT:null,ERROR:null,EVAL_JAVASCRIPT:false,GLOBAL:true,SCOPE:this,FILTERS:{},INCLUDE_PATH:[""],INTERPOLATE:false,OUTPUT:null,PLUGINS:{},POST_PROCESS:[],PRE_PROCESS:[],PROCESS:null,RECURSION:false,STASH:null,TOLERANT:null,VARIABLES:{},WRAPPER:[]};proto.defaults={AUTO_RESET:true,BLOCKS:{},CONTEXT:null,DEBUG_UNDEF:false,DEFAULT:null,ERROR:null,EVAL_JAVASCRIPT:false,GLOBAL:true,SCOPE:this,INCLUDE_PATH:[""],INTERPOLATE:false,OUTPUT:null,PLUGINS:{},POST_PROCESS:[],PRE_PROCESS:[],PROCESS:null,RECURSION:false,STASH:null,TOLERANT:null,VARIABLES:{},WRAPPER:[]};Jemplate.init=function(config){Jemplate.prototype.config=config||{};for(var i in Jemplate.prototype.defaults){if(typeof Jemplate.prototype.config[i]=="undefined"){Jemplate.prototype.config[i]=Jemplate.prototype.defaults[i]}}};proto.init=function(config){this.config=config||{};for(var i in Jemplate.prototype.defaults){if(typeof this.config[i]=="undefined"){this.config[i]=Jemplate.prototype.defaults[i]}}};proto.process=function(template,data,output){var context=this.config.CONTEXT||new Jemplate.Context();context.config=this.config;context.stash=new Jemplate.Stash(this.config.STASH,this.config);context.__filter__=new Jemplate.Filter();context.__filter__.config=this.config;context.__plugin__=new Jemplate.Plugin();context.__plugin__.config=this.config;var result;var proc=function(input){try{if(typeof context.config.PRE_PROCESS=="string"){context.config.PRE_PROCESS=[context.config.PRE_PROCESS]}for(var i=0;i<context.config.PRE_PROCESS.length;i++){context.process(context.config.PRE_PROCESS[i])}result=context.process(template,input);if(typeof context.config.POST_PROCESS=="string"){context.config.PRE_PROCESS=[context.config.POST_PROCESS]}for(i=0;i<context.config.POST_PROCESS.length;i++){context.process(context.config.POST_PROCESS[i])}}catch(e){if(!String(e).match(/Jemplate\.STOP\n/)){throw (e)}result=e.toString().replace(/Jemplate\.STOP\n/,"")}if(typeof output=="undefined"){return result}if(typeof output=="function"){output(result);return null}if(typeof (output)=="string"||output instanceof String){if(output.match(/^#[\w\-]+$/)){var id=output.replace(/^#/,"");var element=document.getElementById(id);if(typeof element=="undefined"){throw ('No element found with id="'+id+'"')}element.innerHTML=result;return null}}else{output.innerHTML=result;return null}throw ("Invalid arguments in call to Jemplate.process");return 1};if(typeof data=="function"){data=data()}else{if(typeof data=="string"){var url=data;Jemplate.Ajax.processGet(url,function(data){proc(data)});return null}}return proc(data)};if(typeof Jemplate.Context=="undefined"){Jemplate.Context=function(){}}proto=Jemplate.Context.prototype;proto.include=function(template,args){return this.process(template,args,true)};proto.process=function(template,args,localise){if(localise){this.stash.clone(args)}else{this.stash.update(args)}var func=Jemplate.templateMap[template];if(typeof func=="undefined"){throw ('No Jemplate template named "'+template+'" available')}var output=func(this);if(localise){this.stash.declone()}return output};proto.set_error=function(error,output){this._error=[error,output];return error};proto.plugin=function(name,args){if(typeof name=="undefined"){throw"Unknown plugin name ':"+name+"'"}var func=eval(name);return new func(this,args)};proto.filter=function(text,name,args){if(name=="null"){name="null_filter"}if(typeof this.__filter__.filters[name]=="function"){return this.__filter__.filters[name](text,args,this)}else{throw"Unknown filter name ':"+name+"'"}};if(typeof Jemplate.Plugin=="undefined"){Jemplate.Plugin=function(){}}proto=Jemplate.Plugin.prototype;proto.plugins={};if(typeof Jemplate.Filter=="undefined"){Jemplate.Filter=function(){}}proto=Jemplate.Filter.prototype;proto.filters={};proto.filters.null_filter=function(text){return""};proto.filters.upper=function(text){return text.toUpperCase()};proto.filters.lower=function(text){return text.toLowerCase()};proto.filters.ucfirst=function(text){var first=text.charAt(0);var rest=text.substr(1);return first.toUpperCase()+rest};proto.filters.lcfirst=function(text){var first=text.charAt(0);var rest=text.substr(1);return first.toLowerCase()+rest};proto.filters.trim=function(text){return text.replace(/^\s+/g,"").replace(/\s+$/g,"")};proto.filters.collapse=function(text){return text.replace(/^\s+/g,"").replace(/\s+$/g,"").replace(/\s+/," ")};proto.filters.html=function(text){text=text.replace(/&/g,"&");text=text.replace(/</g,"<");text=text.replace(/>/g,">");text=text.replace(/"/g,""");return text};proto.filters.html_para=function(text){var lines=text.split(/(?:\r?\n){2,}/);return"<p>\n"+lines.join("\n</p>\n\n<p>\n")+"</p>\n"};proto.filters.html_break=function(text){return text.replace(/(\r?\n){2,}/g,"$1<br />$1<br />$1")};proto.filters.html_line_break=function(text){return text.replace(/(\r?\n)/g,"$1<br />$1")};proto.filters.uri=function(text){return encodeURIComponent(text)};proto.filters.url=function(text){return encodeURI(text)};proto.filters.indent=function(text,args){var pad=args[0];if(!text){return null}if(typeof pad=="undefined"){pad=4}var finalpad="";if(typeof pad=="number"||String(pad).match(/^\d$/)){for(var i=0;i<pad;i++){finalpad+=" "}}else{finalpad=pad}var output=text.replace(/^/gm,finalpad);return output};proto.filters.truncate=function(text,args){var len=args[0];if(!text){return null}if(!len){len=32}if(text.length<len){return text}var newlen=len-3;return text.substr(0,newlen)+"..."};proto.filters.repeat=function(text,iter){if(!text){return null}if(!iter||iter==0){iter=1}if(iter==1){return text}var output=text;for(var i=1;i<iter;i++){output+=text}return output};proto.filters.replace=function(text,args){if(!text){return null}var re_search=args[0];var text_replace=args[1];if(!re_search){re_search=""}if(!text_replace){text_replace=""}var re=new RegExp(re_search,"g");return text.replace(re,text_replace)};if(typeof Jemplate.Stash=="undefined"){Jemplate.Stash=function(stash,config){this.__config__=config;this.data={GLOBAL:this.__config__.SCOPE};this.LOCAL_ANCHOR={};this.data.LOCAL=this.LOCAL_ANCHOR;this.update(stash)}}proto=Jemplate.Stash.prototype;proto.clone=function(args){var data=this.data;this.data={GLOBAL:this.__config__.SCOPE};this.data.LOCAL=this.LOCAL_ANCHOR;this.update(data);this.update(args);this.data._PARENT=data};proto.declone=function(args){this.data=this.data._PARENT||this.data};proto.update=function(args){if(typeof args=="undefined"){return }for(var key in args){if(key!="GLOBAL"&&key!="LOCAL"){this.set(key,args[key])}}};proto.get=function(ident,args){var root=this.data;var value;if((ident instanceof Array)||(typeof ident=="string"&&/\./.test(ident))){if(typeof ident=="string"){ident=ident.split(".");var newIdent=[];for(var i=0;i<ident.length;i++){newIdent.push(ident.replace(/\(.*$/,""));newIdent.push(0)}ident=newIdent}for(var i=0;i<ident.length;i+=2){var dotopArgs=ident.slice(i,i+2);dotopArgs.unshift(root);value=this._dotop.apply(this,dotopArgs);if(typeof value=="undefined"){break}root=value}}else{value=this._dotop(root,ident,args)}if(typeof value=="undefined"||value==null){if(this.__config__.DEBUG_UNDEF){throw ("undefined value found while using DEBUG_UNDEF")}value=""}return value};proto.set=function(ident,value,set_default){var root,result,error;root=this.data;while(true){if((ident instanceof Array)||(typeof ident=="string"&&/\./.test(ident))){if(typeof ident=="string"){ident=ident.split(".");var newIdent=[];for(var i=0;i<ident.length;i++){newIdent.push(ident.replace(/\(.*$/,""));newIdent.push(0)}ident=newIdent}for(var i=0;i<ident.length-2;i+=2){var dotopArgs=ident.slice(i,i+2);dotopArgs.unshift(root);dotopArgs.push(1);result=this._dotop.apply(this,dotopArgs);if(typeof value=="undefined"){break}root=result}var assignArgs=ident.slice(ident.length-2,ident.length);assignArgs.unshift(root);assignArgs.push(value);assignArgs.push(set_default);result=this._assign.apply(this,assignArgs)}else{result=this._assign(root,ident,0,value,set_default)}break}return(typeof result!="undefined")?result:""};proto._dotop=function(root,item,args,lvalue){if(root==this.LOCAL_ANCHOR){root=this.data}var atroot=root==this.data;var value,result=undefined;var is_function_call=args instanceof Array;args=args||[];if(typeof root=="undefined"||typeof item=="undefined"||typeof item=="string"&&item.match(/^[\._]/)){return undefined}if(atroot||(root instanceof Object&&!(root instanceof Array))||root==this.data.GLOBAL){if(typeof root[item]!="undefined"&&root[item]!=null&&(!is_function_call||!this.hash_functions[item])){if(typeof root[item]=="function"){result=root[item].apply(root,args)}else{return root[item]}}else{if(lvalue){return root[item]={}}else{if(this.hash_functions[item]&&!atroot||item=="import"){args.unshift(root);result=this.hash_functions[item].apply(this,args)}else{if(item instanceof Array){result={};for(var i=0;i<item.length;i++){result[item[i]]=root[item[i]]}return result}}}}}else{if(root instanceof Array){if(this.list_functions[item]){args.unshift(root);result=this.list_functions[item].apply(this,args)}else{if(typeof item=="string"&&/^-?\d+$/.test(item)||typeof item=="number"){if(typeof root[item]!="function"){return root[item]}result=root[item].apply(this,args)}else{if(item instanceof Array){for(var i=0;i<item.length;i++){result.push(root[item[i]])}return result}}}}else{if(this.string_functions[item]&&!lvalue){args.unshift(root);result=this.string_functions[item].apply(this,args)}else{if(this.list_functions[item]&&!lvalue){args.unshift([root]);result=this.list_functions[item].apply(this,args)}else{result=undefined}}}}if(result instanceof Array){if(typeof result[0]=="undefined"&&typeof result[1]!="undefined"){throw result[1]}}return result};proto._assign=function(root,item,args,value,set_default){var atroot=root==this.data;var result;args=args||[];if(typeof root=="undefined"||typeof item=="undefined"||typeof item=="string"&&item.match(/^[\._]/)){return undefined}if(atroot||root.constructor==Object||root==this.data.GLOBAL){if(root==this.LOCAL_ANCHOR){root=this.data}if(!(set_default&&typeof root[item]!="undefined")){if(atroot&&item=="GLOBAL"){throw"Attempt to modify GLOBAL access modifier"}if(atroot&&item=="LOCAL"){throw"Attempt to modify LOCAL access modifier"}return root[item]=value}}else{if((root instanceof Array)&&(typeof item=="string"&&/^-?\d+$/.test(item)||typeof item=="number")){if(!(set_default&&typeof root[item]!="undefined")){return root[item]=value}}else{if((root.constructor!=Object)&&(root instanceof Object)){try{result=root[item].apply(root,args)}catch(e){}}else{throw"dont know how to assign to ["+root+"."+item+"]"}}}return undefined};proto.string_functions={};proto.string_functions["typeof"]=function(value){return typeof value};proto.string_functions.chunk=function(string,size){var list=new Array();if(!size){size=1}if(size<0){size=0-size;for(var i=string.length-size;i>=0;i=i-size){list.unshift(string.substr(i,size))}if(string.length%size){list.unshift(string.substr(0,string.length%size))}}else{for(i=0;i<string.length;i=i+size){list.push(string.substr(i,size))}}return list};proto.string_functions.defined=function(string){return 1};proto.string_functions.hash=function(string){return{"value":string}};proto.string_functions.length=function(string){return string.length};proto.string_functions.list=function(string){return[string]};proto.string_functions.match=function(string,re,modifiers){var regexp=new RegExp(re,modifiers==undefined?"g":modifiers);var list=string.match(regexp);return list};proto.string_functions.repeat=function(string,args){var n=args||1;var output="";for(var i=0;i<n;i++){output+=string}return output};proto.string_functions.replace=function(string,re,sub,modifiers){var regexp=new RegExp(re,modifiers==undefined?"g":modifiers);if(!sub){sub=""}return string.replace(regexp,sub)};proto.string_functions.search=function(string,re){var regexp=new RegExp(re);return(string.search(regexp)>=0)?1:0};proto.string_functions.size=function(string){return 1};proto.string_functions.split=function(string,re){var regexp=new RegExp(re);var list=string.split(regexp);return list};proto.list_functions={};proto.list_functions["typeof"]=function(list){return"array"};proto.list_functions.list=function(list){return list};proto.list_functions.join=function(list,str){return list.join(str)};proto.list_functions.sort=function(list,key){if(typeof (key)!="undefined"&&key!=""){return list.sort(function(a,b){if(a[key]==b[key]){return 0}else{if(a[key]>b[key]){return 1}else{return -1}}})}return list.sort()};proto.list_functions.nsort=function(list){return list.sort(function(a,b){return(a-b)})};proto.list_functions.grep=function(list,re){var regexp=new RegExp(re);var result=[];for(var i=0;i<list.length;i++){if(list[i].match(regexp)){result.push(list[i])}}return result};proto.list_functions.unique=function(list){var result=[];var seen={};for(var i=0;i<list.length;i++){var elem=list[i];if(!seen[elem]){result.push(elem)}seen[elem]=true}return result};proto.list_functions.reverse=function(list){var result=[];for(var i=list.length-1;i>=0;i--){result.push(list[i])}return result};proto.list_functions.merge=function(list){var result=[];var push_all=function(elem){if(elem instanceof Array){for(var j=0;j<elem.length;j++){result.push(elem[j])}}else{result.push(elem)}};push_all(list);for(var i=1;i<arguments.length;i++){push_all(arguments[i])}return result};proto.list_functions.slice=function(list,start,end){if(end==-1){return list.slice(start)}return list.slice(start,end+1)};proto.list_functions.splice=function(list){var args=Array.prototype.slice.call(arguments);args.shift();return list.splice.apply(list,args)};proto.list_functions.push=function(list,value){list.push(value);return list};proto.list_functions.pop=function(list){return list.pop()};proto.list_functions.unshift=function(list,value){list.unshift(value);return list};proto.list_functions.shift=function(list){return list.shift()};proto.list_functions.first=function(list){return list[0]};proto.list_functions.size=function(list){return list.length};proto.list_functions.max=function(list){return list.length-1};proto.list_functions.last=function(list){return list.slice(-1)};proto.hash_functions={};proto.hash_functions["typeof"]=function(hash){return"object"};proto.hash_functions.each=function(hash){var list=new Array();for(var key in hash){list.push(key,hash[key])}return list};proto.hash_functions.exists=function(hash,key){return(typeof (hash[key])=="undefined")?0:1};proto.hash_functions["import"]=function(hash,hash2){for(var key in hash2){hash[key]=hash2[key]}return""};proto.hash_functions.keys=function(hash){var list=new Array();for(var key in hash){list.push(key)}return list};proto.hash_functions.list=function(hash,what){var list=new Array();var key;if(what=="keys"){for(key in hash){list.push(key)}}else{if(what=="values"){for(key in hash){list.push(hash[key])}}else{if(what=="each"){for(key in hash){list.push(key,hash[key])}}else{for(key in hash){list.push({"key":key,"value":hash[key]})}}}}return list};proto.hash_functions.nsort=function(hash){var list=new Array();for(var key in hash){list.push(key)}return list.sort(function(a,b){return(a-b)})};proto.hash_functions.item=function(hash,key){return hash[key]};proto.hash_functions.size=function(hash){var size=0;for(var key in hash){size++}return size};proto.hash_functions.sort=function(hash){var list=new Array();for(var key in hash){list.push(key)}return list.sort()};proto.hash_functions.values=function(hash){var list=new Array();for(var key in hash){list.push(hash[key])}return list};proto.hash_functions.pairs=function(hash){var list=new Array();var keys=new Array();for(var key in hash){keys.push(key)}keys.sort();for(var key in keys){key=keys[key];list.push({"key":key,"value":hash[key]})}return list};proto.hash_functions.remove=function(hash,key){return delete hash[key]};proto.hash_functions["delete"]=proto.hash_functions.remove;if(typeof Jemplate.Iterator=="undefined"){Jemplate.Iterator=function(object){if(object instanceof Array){this.object=object;this.size=object.length;this.max=this.size-1}else{if(object instanceof Object){this.object=object;var object_keys=new Array;for(var key in object){object_keys[object_keys.length]=key}this.object_keys=object_keys.sort();this.size=object_keys.length;this.max=this.size-1}else{if(typeof object=="undefined"||object==null||object==""){this.object=null;this.max=-1}}}}}proto=Jemplate.Iterator.prototype;proto.get_first=function(){this.index=0;this.first=1;this.last=0;this.count=1;return this.get_next(1)};proto.get_next=function(should_init){var object=this.object;var index;if(typeof (should_init)!="undefined"&&should_init){index=this.index}else{index=++this.index;this.first=0;this.count=this.index+1;if(this.index==this.size-1){this.last=1}}if(typeof object=="undefined"){throw ("No object to iterate")}if(this.object_keys){if(index<this.object_keys.length){this.prev=index>0?this.object_keys[index-1]:"";this.next=index<this.max?this.object_keys[index+1]:"";return[this.object_keys[index],false]}}else{if(index<=this.max){this.prev=index>0?object[index-1]:"";this.next=index<this.max?object[index+1]:"";return[object[index],false]}}return[null,true]};var stubExplanation="stub that doesn't do anything. Try including the jQuery, YUI, or XHR option when building the runtime";Jemplate.Ajax={get:function(url,callback){throw ("This is a Jemplate.Ajax.get "+stubExplanation)},processGet:function(url,callback){throw ("This is a Jemplate.Ajax.processGet "+stubExplanation)},post:function(url,callback){throw ("This is a Jemplate.Ajax.post "+stubExplanation)}};Jemplate.JSON={parse:function(decodeValue){throw ("This is a Jemplate.JSON.parse "+stubExplanation)},stringify:function(encodeValue){throw ("This is a Jemplate.JSON.stringify "+stubExplanation)}}}())
...
}
sub ajax_jquery {
<<'...';
(function(){Jemplate.Ajax={get:function(A,B){jQuery.get(A,null,B)},processGet:function(A,B){jQuery.getJSON(A,null,B)},post:function(A,B,C){jQuery.post(A,B,C)}}}())
...
}
sub ajax_xhr {
<<'...';
(function(){Jemplate.Ajax={get:function(A,C){var B=new XMLHttpRequest();B.open("GET",A,Boolean(C));B.setRequestHeader("Accept","text/json; text/x-json; application/json");return this.request(B,null,C)},processGet:function(A,B){this.get(A,function(C){B(Jemplate.JSON.parse(C))})},post:function(A,C,D){var B=new XMLHttpRequest();B.open("POST",A,Boolean(D));B.setRequestHeader("Accept","text/json; text/x-json; application/json");B.setRequestHeader("Content-Type","application/x-www-form-urlencoded");return this.request(B,C,D)},request:function(A,B,C){if(C){A.onreadystatechange=function(){if(A.readyState==4){if(A.status==200){C(A.responseText)}}}}A.send(B);if(!C){if(A.status!=200){throw ('Request for "'+url+'" failed with status: '+A.status)}return A.responseText}return null}}}())
...
}
sub ajax_yui {
<<'...';
(function(){Jemplate.Ajax={get:function(A,B){if(typeof B=="function"){B={success:B}}YAHOO.connect.asyncRequest("GET",A,B)},processGet:function(A,B){this.get(A,function(C){B(YAHOO.lang.JSON.parse(C))})},post:function(A,B,C){if(typeof C=="function"){C={success:C}}YAHOO.connect.asyncRequest("POST",A,C,B)}}}())
...
}
sub json_json2 {
<<'...';
(function(){Jemplate.JSON={parse:function(A){return JSON.parse(A)},stringify:function(A){return JSON.stringify(A)}}}())
...
}
sub json_json2_internal {
<<'...';
;(function(){
var JSON;
if(!this.JSON){this.JSON={}}(function(){function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(key){return this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z"};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf()}}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||"null"}v=partial.length===0?"[]":gap?"[\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"]":"["+partial.join(",")+"]";gap=mind;return v}if(rep&&typeof rep==="object"){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==="string"){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}v=partial.length===0?"{}":gap?"{\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"}":"{"+partial.join(",")+"}";gap=mind;return v}return""}if(typeof JSON.stringify!=="function"){JSON.stringify=function(value,replacer,space){var i;gap="";indent="";if(typeof space==="number"){for(i=0;i<space;i+=1){indent+=" "}}else{if(typeof space==="string"){indent=space}}rep=replacer;if(replacer&&typeof replacer!=="function"&&(typeof replacer!=="object"||typeof replacer.length!=="number")){throw new Error("JSON.stringify")}return str("",{"":value})}}if(typeof JSON.parse!=="function"){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==="object"){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v}else{delete value[k]}}}}return reviver.call(holder,key,value)}cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}}}())
Jemplate.JSON={parse:function(A){return JSON.parse(A)},stringify:function(A){return JSON.stringify(A)}}
}());
...
}
sub json_yui {
<<'...';
(function(){Jemplate.JSON={parse:function(A){return YAHOO.lang.JSON.parse(A)},stringify:function(A){return YAHOO.lang.JSON.stringify(A)}}}())
...
}
sub json2 {
<<'...';
if(!this.JSON){this.JSON={}}(function(){function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(key){return this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z"};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf()}}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||"null"}v=partial.length===0?"[]":gap?"[\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"]":"["+partial.join(",")+"]";gap=mind;return v}if(rep&&typeof rep==="object"){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==="string"){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}v=partial.length===0?"{}":gap?"{\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"}":"{"+partial.join(",")+"}";gap=mind;return v}return""}if(typeof JSON.stringify!=="function"){JSON.stringify=function(value,replacer,space){var i;gap="";indent="";if(typeof space==="number"){for(i=0;i<space;i+=1){indent+=" "}}else{if(typeof space==="string"){indent=space}}rep=replacer;if(replacer&&typeof replacer!=="function"&&(typeof replacer!=="object"||typeof replacer.length!=="number")){throw new Error("JSON.stringify")}return str("",{"":value})}}if(typeof JSON.parse!=="function"){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==="object"){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v}else{delete value[k]}}}}return reviver.call(holder,key,value)}cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}}}())
...
}
sub xhr_gregory {
<<'...';
if(window.ActiveXObject&&!window.XMLHttpRequest){window.XMLHttpRequest=function(){var C=new Array("Msxml2.XMLHTTP.5.0","Msxml2.XMLHTTP.4.0","Msxml2.XMLHTTP.3.0","Msxml2.XMLHTTP","Microsoft.XMLHTTP");for(var A=0;A<C.length;A++){try{return new ActiveXObject(C[A])}catch(B){}}return null}}if(window.opera&&!window.XMLHttpRequest){window.XMLHttpRequest=function(){this.readyState=0;this.status=0;this.statusText="";this._headers=[];this._aborted=false;this._async=true;this._defaultCharset="ISO-8859-1";this._getCharset=function(){var B=_defaultCharset;var A=this.getResponseHeader("Content-type").toUpperCase();val=A.indexOf("CHARSET=");if(val!=-1){B=A.substring(val)}val=B.indexOf(";");if(val!=-1){B=B.substring(0,val)}val=B.indexOf(",");if(val!=-1){B=B.substring(0,val)}return B};this.abort=function(){this._aborted=true};this.getAllResponseHeaders=function(){return this.getAllResponseHeader("*")};this.getAllResponseHeader=function(C){var A="";for(var B=0;B<this._headers.length;B++){if(C=="*"||this._headers[B].h==C){A+=this._headers[B].h+": "+this._headers[B].v+"\n"}}return A};this.getResponseHeader=function(C){var A=getAllResponseHeader(C);var B=A.indexOf("\n");if(B!=-1){A=A.substring(0,B)}return A};this.setRequestHeader=function(B,A){this._headers[this._headers.length]={h:B,v:A}};this.open=function(E,C,D,A,B){this.method=E;this.url=C;this._async=true;this._aborted=false;this._headers=[];if(arguments.length>=3){this._async=D}if(arguments.length>3){opera.postError("XMLHttpRequest.open() - user/password not supported")}this.readyState=1;if(this.onreadystatechange){this.onreadystatechange()}};this.send=function(A){if(!navigator.javaEnabled()){alert("XMLHttpRequest.send() - Java must be installed and enabled.");return }if(this._async){setTimeout(this._sendasync,0,this,A)}else{this._sendsync(A)}};this._sendasync=function(A,B){if(!A._aborted){A._sendsync(B)}};this._sendsync=function(Q){this.readyState=2;if(this.onreadystatechange){this.onreadystatechange()}var F=new java.net.URL(new java.net.URL(window.location.href),this.url);var I=F.openConnection();for(var O=0;O<this._headers.length;O++){I.setRequestProperty(this._headers[O].h,this._headers[O].v)}this._headers=[];if(this.method=="POST"){I.setDoOutput(true);var B=new java.io.OutputStreamWriter(I.getOutputStream(),this._getCharset());B.write(Q);B.flush();B.close()}var L=false;var J=false;var E=false;var C=false;var H=false;var P=false;for(var O=0;;O++){var N=I.getHeaderFieldKey(O);var K=I.getHeaderField(O);if(N==null&&K==null){break}if(N!=null){this._headers[this._headers.length]={h:N,v:K};switch(N.toLowerCase()){case"content-encoding":L=true;break;case"content-length":J=true;break;case"content-type":E=true;break;case"date":C=true;break;case"expires":H=true;break;case"last-modified":P=true;break}}}var R;R=I.getContentEncoding();if(R!=null&&!L){this._headers[this._headers.length]={h:"Content-encoding",v:R}}R=I.getContentLength();if(R!=-1&&!J){this._headers[this._headers.length]={h:"Content-length",v:R}}R=I.getContentType();if(R!=null&&!E){this._headers[this._headers.length]={h:"Content-type",v:R}}R=I.getDate();if(R!=0&&!C){this._headers[this._headers.length]={h:"Date",v:(new Date(R)).toUTCString()}}R=I.getExpiration();if(R!=0&&!H){this._headers[this._headers.length]={h:"Expires",v:(new Date(R)).toUTCString()}}R=I.getLastModified();if(R!=0&&!P){this._headers[this._headers.length]={h:"Last-modified",v:(new Date(R)).toUTCString()}}var D="";var G=I.getInputStream();if(G){var A=new java.io.BufferedReader(new java.io.InputStreamReader(G,this._getCharset()));var M;while((M=A.readLine())!=null){if(this.readyState==2){this.readyState=3;if(this.onreadystatechange){this.onreadystatechange()}}D+=M+"\n"}A.close();this.status=200;this.statusText="OK";this.responseText=D;this.readyState=4;if(this.onreadystatechange){this.onreadystatechange()}if(this.onload){this.onload()}}else{this.status=404;this.statusText="Not Found";this.responseText="";this.readyState=4;if(this.onreadystatechange){this.onreadystatechange()}if(this.onerror){this.onerror()}}}}}if(!window.ActiveXObject&&window.XMLHttpRequest){window.ActiveXObject=function(A){switch(A.toLowerCase()){case"microsoft.xmlhttp":case"msxml2.xmlhttp":case"msxml2.xmlhttp.3.0":case"msxml2.xmlhttp.4.0":case"msxml2.xmlhttp.5.0":return new XMLHttpRequest()}return null}}
...
}
sub xhr_ilinsky {
<<'...';
(function(){var D=window.XMLHttpRequest;var H=!!window.controllers,E=window.document.all&&!window.opera;function C(){this._object=D?new D:new window.ActiveXObject("Microsoft.XMLHTTP")}if(H&&D.wrapped){C.wrapped=D.wrapped}C.UNSENT=0;C.OPENED=1;C.HEADERS_RECEIVED=2;C.LOADING=3;C.DONE=4;C.prototype.readyState=C.UNSENT;C.prototype.responseText="";C.prototype.responseXML=null;C.prototype.status=0;C.prototype.statusText="";C.prototype.onreadystatechange=null;C.onreadystatechange=null;C.onopen=null;C.onsend=null;C.onabort=null;C.prototype.open=function(L,O,K,P,J){this._async=K;var N=this,M=this.readyState;if(E){var I=function(){if(N._object.readyState!=C.DONE){A(N)}};if(K){window.attachEvent("onunload",I)}}this._object.onreadystatechange=function(){if(H&&!K){return }N.readyState=N._object.readyState;G(N);if(N._aborted){N.readyState=C.UNSENT;return }if(N.readyState==C.DONE){A(N);if(E&&K){window.detachEvent("onunload",I)}}if(M!=N.readyState){F(N)}M=N.readyState};if(C.onopen){C.onopen.apply(this,arguments)}this._object.open(L,O,K,P,J);if(!K&&H){this.readyState=C.OPENED;F(this)}};C.prototype.send=function(I){if(C.onsend){C.onsend.apply(this,arguments)}if(I&&I.nodeType){I=window.XMLSerializer?new window.XMLSerializer().serializeToString(I):I.xml;if(!this._headers["Content-Type"]){this._object.setRequestHeader("Content-Type","application/xml")}}this._object.send(I);if(H&&!this._async){this.readyState=C.OPENED;G(this);while(this.readyState<C.DONE){this.readyState++;F(this);if(this._aborted){return }}}};C.prototype.abort=function(){if(C.onabort){C.onabort.apply(this,arguments)}if(this.readyState>C.UNSENT){this._aborted=true}this._object.abort();A(this)};C.prototype.getAllResponseHeaders=function(){return this._object.getAllResponseHeaders()};C.prototype.getResponseHeader=function(I){return this._object.getResponseHeader(I)};C.prototype.setRequestHeader=function(I,J){if(!this._headers){this._headers={}}this._headers[I]=J;return this._object.setRequestHeader(I,J)};C.prototype.toString=function(){return"[object XMLHttpRequest]"};C.toString=function(){return"[XMLHttpRequest]"};function F(I){if(I.onreadystatechange){I.onreadystatechange.apply(I)}if(C.onreadystatechange){C.onreadystatechange.apply(I)}}function B(J){var I=J.responseXML;if(E&&I&&!I.documentElement&&J.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)){I=new ActiveXObject("Microsoft.XMLDOM");I.loadXML(J.responseText)}if(I){if((E&&I.parseError!=0)||(I.documentElement&&I.documentElement.tagName=="parsererror")){return null}}return I}function G(I){try{I.responseText=I._object.responseText}catch(J){}try{I.responseXML=B(I._object)}catch(J){}try{I.status=I._object.status}catch(J){}try{I.statusText=I._object.statusText}catch(J){}}function A(I){I._object.onreadystatechange=new window.Function;delete I._headers}if(!window.Function.prototype.apply){window.Function.prototype.apply=function(I,J){if(!J){J=[]}I.__func=this;I.__func(J[0],J[1],J[2],J[3],J[4]);delete I.__func}}window.XMLHttpRequest=C})()
...
}
sub xxx {
<<'...';
function XXX(A){if(!confirm(A)){throw ("terminated...")}return A}function JJJ(A){return XXX(JSON.stringify(A))}
...
}
1;
}
#
# Inline include of Jemplate.pm
#
BEGIN { $INC{'Jemplate.pm'} = 'dummy/Jemplate.pm'; }
BEGIN {
#line 0 "Jemplate.pm"
package Jemplate;
use 5.006001;
use strict;
use warnings;
use Template 2.14;
use Getopt::Long;
our $VERSION = '0.260';
use Jemplate::Parser;
sub usage {
<<'...';
Usage:
jemplate --runtime [runtime-opt]
jemplate --compile [compile-opt] <template-list>
jemplate --runtime [runtime-opt] --compile [compile-opt] <template-list>
jemplate --list <template-list>
Where "--runtime" and "runtime-opt" can include:
--runtime Equivalent to --ajax=ilinsky --json=json2
--runtime=standard
--runtime=lite Same as --ajax=none --json=none
--runtime=jquery Same as --ajax=jquery --json=none
--runtime=yui Same as --ajax=yui --json=yui
--runtime=legacy Same as --ajax=gregory --json=json2
--json By itself, equivalent to --json=json2
--json=json2 Include http://www.json.org/json2.js for parsing/stringifying
--json=yui Use YUI: YAHOO.lang.JSON (requires external YUI)
--json=none Doesn't provide any JSON functionality except a warning
--ajax By itself, equivalent to --ajax=xhr
--ajax=jquery Use jQuery for Ajax get and post (requires external jQuery)
--ajax=yui Use YUI: yui/connection/connection.js (requires external YUI)
--ajax=xhr Use XMLHttpRequest (will automatically use --xhr=ilinsky if --xhr is not set)
--ajax=none Doesn't provide any Ajax functionality except a warning
--xhr By itself, equivalent to --xhr=ilinsky
--xhr=ilinsky Include http://code.google.com/p/xmlhttprequest/
--xhr=gregory Include http://www.scss.com.au/family/andrew/webdesign/xmlhttprequest/
--xxx Include XXX and JJJ helper functions
--compact Use the YUICompressor compacted version of the runtime
Where "compile-opt" can include:
--start-tag
--end-tag
--pre-chomp
--post-chomp
--trim
--any-case
--eval
--noeval
-s, --source
For more information use:
perldoc jemplate
...
}
sub main {
my $class = shift;
my @argv = @_;
my ($template_options, $jemplate_options) = get_options(@argv);
my ($runtime, $compile, $list) = @$jemplate_options{qw/runtime compile list/};
if ($runtime) {
print runtime_source_code(@$jemplate_options{qw/runtime ajax json xhr xxx compact/});
return unless $compile;
}
my $templates = make_file_list(@argv);
print_usage_and_exit() unless @$templates;
if ($list) {
foreach (@$templates) {
print STDOUT $_->{short} . "\n";
}
return;
}
if ($compile) {
my $jemplate = Jemplate->new(%$template_options);
print STDOUT $jemplate->_preamble;
foreach my $template (@$templates) {
my $content = slurp($template->{full});
if ($content) {
print STDOUT $jemplate->compile_template_content(
$content,
$template->{short},
);
}
}
return;
}
print_usage_and_exit();
}
sub get_options {
local @ARGV = @_;
my $runtime;
my $compile = 0;
my $list = 0;
my $start_tag = exists $ENV{JEMPLATE_START_TAG}
? $ENV{JEMPLATE_START_TAG}
: undef;
my $end_tag = exists $ENV{JEMPLATE_END_TAG}
? $ENV{JEMPLATE_END_TAG}
: undef;
my $pre_chomp = exists $ENV{JEMPLATE_PRE_CHOMP}
? $ENV{JEMPLATE_PRE_CHOMP}
: undef;
my $post_chomp = exists $ENV{JEMPLATE_POST_CHOMP}
? $ENV{JEMPLATE_POST_CHOMP}
: undef;
my $trim = exists $ENV{JEMPLATE_TRIM}
? $ENV{JEMPLATE_TRIM}
: undef;
my $anycase = exists $ENV{JEMPLATE_ANYCASE}
? $ENV{JEMPLATE_ANYCASE}
: undef;
my $eval_javascript = exists $ENV{JEMPLATE_EVAL_JAVASCRIPT}
? $ENV{JEMPLATE_EVAL_JAVASCRIPT}
: 1;
my $source = 0;
my ($ajax, $json, $xxx, $xhr, $compact, $minify);
my $help = 0;
GetOptions(
"compile|c" => \$compile,
"list|l" => \$list,
"runtime|r:s" => \$runtime,
"start-tag=s" => \$start_tag,
"end-tag=s" => \$end_tag,
"trim=s" => \$trim,
"pre-chomp" => \$pre_chomp,
"post-chomp" => \$post_chomp,
"any-case" => \$anycase,
"eval!" => \$eval_javascript,
"source|s" => \$source,
"ajax:s" => \$ajax,
"json:s" => \$json,
"xxx" => \$xxx,
"xhr:s" => \$xhr,
"compact" => \$compact,
"minify:s" => \$minify,
"help|?" => \$help,
) or print_usage_and_exit();
if ($help) {
print_usage_and_exit();
}
($runtime, $ajax, $json, $xxx, $xhr, $minify) = map { defined $_ && ! length $_ ? 1 : $_ } ($runtime, $ajax, $json, $xxx, $xhr, $minify);
$runtime = "standard" if $runtime && $runtime eq 1;
print_usage_and_exit("Don't understand '--runtime $runtime'") if defined $runtime && ! grep { $runtime =~ m/$_/ } qw/standard lite jquery yui legacy/;
print_usage_and_exit("Can't specify --list with a --runtime and/or the --compile option") if $list && ($runtime || $compile);
print_usage_and_exit() unless $list || $runtime || $compile;
my $command =
$runtime ? 'runtime' :
$compile ? 'compile' :
$list ? 'list' :
print_usage_and_exit();
my $options = {};
$options->{START_TAG} = $start_tag if defined $start_tag;
$options->{END_TAG} = $end_tag if defined $end_tag;
$options->{PRE_CHOMP} = $pre_chomp if defined $pre_chomp;
$options->{POST_CHOMP} = $post_chomp if defined $post_chomp;
$options->{TRIM} = $trim if defined $trim;
$options->{ANYCASE} = $anycase if defined $anycase;
$options->{EVAL_JAVASCRIPT} = $eval_javascript if defined $eval_javascript;
return (
$options,
{ compile => $compile, runtime => $runtime, list => $list,
source => $source,
ajax => $ajax, json => $json, xxx => $xxx, xhr => $xhr,
compact => $compact, minify => $minify },
);
}
sub slurp {
my $filepath = shift;
open(F, '<', $filepath) or die "Can't open '$filepath' for input:\n$!";
my $contents = do {local $/; <F>};
close(F);
return $contents;
}
sub recurse_dir {
require File::Find::Rule;
my $dir = shift;
my @files;
foreach ( File::Find::Rule->file->in( $dir ) ) {
if ( m{/\.[^\.]+} ) {} # Skip ".hidden" files or directories
else {
push @files, $_;
}
}
return @files;
}
sub make_file_list {
my @args = @_;
my @list;
foreach my $arg (@args) {
unless (-e $arg) { next; } # file exists
unless (-s $arg or -d $arg) { next; } # file size > 0 or directory (for Win platform)
if (-d $arg) {
foreach my $full ( recurse_dir($arg) ) {
$full =~ /$arg(\/|)(.*)/;
my $short = $2;
push(@list, {full=>$full, short=>$short} );
}
}
else {
my $full = $arg;
my $short = $full;
$short =~ s/.*[\/\\]//;
push(@list, {full=>$arg, short=>$short} );
}
}
return [ sort { $a->{short} cmp $b->{short} } @list ];
}
sub print_usage_and_exit {
print STDOUT join "\n", "", @_, "Aborting!", "\n" if @_;
print STDOUT usage();
exit;
}
sub runtime_source_code {
require Jemplate::Runtime;
require Jemplate::Runtime::Compact;
unshift @_, "standard" unless @_;
my ($runtime, $ajax, $json, $xhr, $xxx, $compact) = map { defined $_ ? lc $_ : "" } @_[0 .. 5];
my $Jemplate_Runtime = $compact ? "Jemplate::Runtime::Compact" : "Jemplate::Runtime";
if ($runtime eq "standard") {
$ajax ||= "xhr";
$json ||= "json2";
$xhr ||= "ilinsky";
}
elsif ($runtime eq "jquery") {
$ajax ||= "jquery";
}
elsif ($runtime eq "yui") {
$ajax ||= "yui";
$json ||= "yui";
}
elsif ($runtime eq "legacy") {
$ajax ||= "xhr";
$json ||= "json2";
$xhr ||= "gregory";
$xxx = 1;
}
elsif ($runtime eq "lite") {
}
$ajax = "xhr" if $ajax eq 1;
$xhr ||= 1 if $ajax eq "xhr";
$json = "json2" if $json eq 1;
$xhr = "ilinsky" if $xhr eq 1;
my @runtime;
push @runtime, $Jemplate_Runtime->kernel if $runtime;
push @runtime, $Jemplate_Runtime->json2 if $json =~ m/^json2?$/i;
push @runtime, $Jemplate_Runtime->ajax_xhr if $ajax eq "xhr";
push @runtime, $Jemplate_Runtime->ajax_jquery if $ajax eq "jquery";
push @runtime, $Jemplate_Runtime->ajax_yui if $ajax eq "yui";
push @runtime, $Jemplate_Runtime->json_json2 if $json =~ m/^json2?$/i;
push @runtime, $Jemplate_Runtime->json_json2_internal if $json =~ m/^json2?[_-]?internal$/i;
push @runtime, $Jemplate_Runtime->json_yui if $json eq "yui";
push @runtime, $Jemplate_Runtime->xhr_ilinsky if $xhr eq "ilinsky";
push @runtime, $Jemplate_Runtime->xhr_gregory if $xhr eq "gregory";
push @runtime, $Jemplate_Runtime->xxx if $xxx;
return join ";", @runtime;
}
sub new {
my $class = shift;
return bless { @_ }, $class;
}
sub compile_module {
my ($self, $module_path, $template_file_paths) = @_;
my $result = $self->compile_template_files(@$template_file_paths)
or return;
open MODULE, "> $module_path"
or die "Can't open '$module_path' for output:\n$!";
print MODULE $result;
close MODULE;
return 1;
}
sub compile_module_cached {
my ($self, $module_path, $template_file_paths) = @_;
my $m = -M $module_path;
return 0 unless grep { -M($_) < $m } @$template_file_paths;
return $self->compile_module($module_path, $template_file_paths);
}
sub compile_template_files {
my $self = shift;
my $output = $self->_preamble;
for my $filepath (@_) {
my $filename = $filepath;
$filename =~ s/.*[\/\\]//;
open FILE, $filepath
or die "Can't open '$filepath' for input:\n$!";
my $template_input = do {local $/; <FILE>};
close FILE;
$output .=
$self->compile_template_content($template_input, $filename);
}
return $output;
}
sub compile_template_content {
die "Invalid arguments in call to Jemplate->compile_template_content"
unless @_ == 3;
my ($self, $template_content, $template_name) = @_;
my $parser = Jemplate::Parser->new( ref($self) ? %$self : () );
my $parse_tree = $parser->parse(
$template_content, {name => $template_name}
) or die $parser->error;
my $output =
"Jemplate.templateMap['$template_name'] = " .
$parse_tree->{BLOCK} .
"\n";
for my $function_name (sort keys %{$parse_tree->{DEFBLOCKS}}) {
$output .=
"Jemplate.templateMap['$function_name'] = " .
$parse_tree->{DEFBLOCKS}{$function_name} .
"\n";
}
return $output;
}
sub _preamble {
return <<'...';
/*
This JavaScript code was generated by Jemplate, the JavaScript
Template Toolkit. Any changes made to this file will be lost the next
time the templates are compiled.
Copyright 2006-2008 - Ingy döt Net - All rights reserved.
*/
if (typeof(Jemplate) == 'undefined')
throw('Jemplate.js must be loaded before any Jemplate template files');
...
}
1;
}
#BOOTSTRAP-END
Jemplate->main(@ARGV);
=head1 Usage:
jemplate --runtime [runtime-opt]
jemplate --compile [compile-opt] template-list
jemplate --runtime [runtime-opt] --compile [compile-opt] template-list
jemplate --list template-list
Where C<--runtime> and C<runtime-opt> can include:
--runtime Equivalent to --ajax=ilinsky --json=json2
--runtime=standard
--runtime=lite Same as --ajax=none --json=none
--runtime=jquery Same as --ajax=jquery --json=none
--runtime=yui Same as --ajax=yui --json=yui
--runtime=legacy Same as --ajax=gregory --json=json2
--json By itself, equivalent to --json=json2
--json=json2 Include http://www.json.org/json2.js for parsing/stringifying
--json=yui Use YUI: YAHOO.lang.JSON (requires external YUI)
--json=none Doesn't provide any JSON functionality except a warning
--ajax By itself, equivalent to --ajax=xhr
--ajax=jquery Use jQuery for Ajax get and post (requires external jQuery)
--ajax=yui Use YUI: yui/connection/connection.js (requires external YUI)
--ajax=xhr Use XMLHttpRequest (will automatically use --xhr=ilinsky if --xhr is not set)
--ajax=none Doesn't provide any Ajax functionality except a warning
--xhr By itself, equivalent to --xhr=ilinsky
--xhr=ilinsky Include http://code.google.com/p/xmlhttprequest/
--xhr=gregory Include http://www.scss.com.au/family/andrew/webdesign/xmlhttprequest/
--xxx Include XXX and JJJ helper functions
--compact Use the YUICompressor compacted version of the runtime
Where C<compile-opt> can include:
--start-tag
--end-tag
--pre-chomp
--post-chomp
--trim
--any-case
--eval
--noeval
-s, --source
See below for more information
=head2 Example:
Write the Jemplate runtime code into Jemplate.js, then
compile all the template files in the templates/ directory and put
the output in my-jemplate.js.
jemplate --runtime > Jemplate.js
jemplate --compile templates/* > my-jemplate.js
Do the same thing, but put the output into one file.
jemplate --runtime > my-jemplate.js
jemplate --compile templates/* >> my-jemplate.js
=head2 template-list:
The template-list is the list of template files that will be compiled.
If something in the list is a file, then the template name will be just
the file name. If it is a directory, then all the files under that
directory will be found, and the relative paths to those files will be
the template name.
So 'template/foo/bar.tt2' will be named 'bar.tt2', but 'template/' will
find a template named 'foo/bar.tt2'.
It is important to know what Jemplate thinks the template name will be
when you are writing templates or code that refers to other templates.
Use the --list option to check this.
=head1 Commands:
-r, --runtime
This flag tells Jemplate to print the Jemplate JavaScript
runtime code to STDOUT. You should redirect this output into
a .js file.
-c, --compile
The --compile flag tells Jemplate to actually compile templates.
The output is written to STDOUT.
-l, --list
Just print (STDOUT) the template names that Jemplate would use
from the template-list.
=head1 Template Toolkit Compile Options:
Jemplate allows you to specify the following Template Toolkit compile
time options. Full descriptions of these options are available at
L<http://www.template-toolkit.org/docs/plain/Manual/Config.html>.
These options may either be set as JEMPLATE_* environment variables or as
command line switches.
--start-tag (JEMPLATE_START_TAG)
Specify the starting template delimiter to use. Default is '[%'.
--end-tag (JEMPLATE_END_TAG)
Specify the ending template delimiter to use. Default is '%]'.
--pre-chomp (JEMPLATE_PRE_CHOMP)
Chomp leading whitespace automatically. Default is off.
--post-chomp (JEMPLATE_POST_CHOMP)
Chomp trailing whitespace automatically. Default is off.
--trim (JEMPLATE_TRIM)
Trim leading and trailing whitespace. Default is off.
--any-case (JEMPLATE_ANYCASE)
Allow lower or mixed case for template directives. Default is off.
--eval (--noeval) (JEMPLATE_EVAL_JAVASCRIPT)
Allow the execution of raw JavaScript. Default is on.
Use --noeval to disallow it.
=head1 Jemplate Options:
These compile time options are specific to Jemplate.
-s, --source
Include the original template source code as a JavaScript
comment next to each compiled template.
=cut