Showing 153 changed files with 3207 additions and 2785 deletions
+1
.gitignore
... ...
@@ -29,3 +29,4 @@ db/*
29 29
 !db/.gitignore
30 30
 extlib/*
31 31
 rep/*
32
+gitprep.my.ini
+3
cpanfile
... ...
@@ -2,3 +2,6 @@ requires 'DBI', '== 1.621';
2 2
 requires 'DBD::SQLite', '== 1.37';
3 3
 requires 'Object::Simple', '== 3.08';
4 4
 requires 'DBIx::Custom', '== 0.28';
5
+requires 'Mojolicious::Plugin::INIConfig', '== 0.02';
6
+requires 'Mojolicious', '== 3.91';
7
+requires 'Config::Tiny', '== 2.14';
+6
gitprep.conf
... ...
@@ -0,0 +1,6 @@
1
+[basic]
2
+;;; SSH port
3
+;ssh_port=55555
4
+
5
+[hypnotoad]
6
+listen=http://*:10020
+6
gitprep.my.conf
... ...
@@ -0,0 +1,6 @@
1
+[basic]
2
+;;; SSH port
3
+ssh_port=55555
4
+
5
+[hypnotoad]
6
+listen=http://*:10020
+6 -3
lib/Gitprep.pm
... ...
@@ -20,9 +20,12 @@ sub startup {
20 20
   my $self = shift;
21 21
   
22 22
   # Config
23
-  #my $conf_file = $ENV{GITPREP_CONFIG_FILE}
24
-  #  || $self->home->rel_file('gitprep.conf');
25
-  #$self->plugin('JSONConfigLoose', {file => $conf_file}) if -f $conf_file;
23
+  $self->plugin('INIConfig', {ext => 'conf'});
24
+  
25
+  # My Config(Development)
26
+  my $my_conf_file = $self->home->rel_file('gitprep.my.conf');
27
+  $self->plugin('INIConfig', {file => $my_conf_file}) if -f $my_conf_file;
28
+  
26 29
   my $conf = $self->config;
27 30
   $conf->{root} = $self->home->rel_file('rep');
28 31
   $conf->{hypnotoad} ||= {listen => ["http://*:10020"]};
-3
mojolegacy/README.txt
... ...
@@ -1,3 +0,0 @@
1
-This is Mojolicious v3.70 back porting to perl 5.8.7
2
-
3
-  https://github.com/jamadam/mojo-legacy
+9 -12
mojolegacy/lib/Mojo.pm
... ...
@@ -15,10 +15,9 @@ has log  => sub { Mojo::Log->new };
15 15
 has ua   => sub {
16 16
   my $self = shift;
17 17
 
18
-  # Fresh user agent
19 18
   my $ua = Mojo::UserAgent->new->app($self);
20 19
   weaken $self;
21
-  $ua->on(error => sub { $self->log->error(pop) });
20
+  $ua->on(error => sub { $self->log->error($_[1]) });
22 21
   weaken $ua->{app};
23 22
 
24 23
   return $ua;
... ...
@@ -27,10 +26,8 @@ has ua   => sub {
27 26
 sub new {
28 27
   my $self = shift->SUPER::new(@_);
29 28
 
30
-  # Detect home directory
29
+  # Check if we have a log directory
31 30
   my $home = $self->home->detect(ref $self);
32
-
33
-  # Log directory
34 31
   $self->log->path($home->rel_file('log/mojo.log'))
35 32
     if -w $home->rel_file('log');
36 33
 
... ...
@@ -101,7 +98,7 @@ See L<Mojolicious> for more!
101 98
 
102 99
 L<Mojo> implements the following attributes.
103 100
 
104
-=head2 C<home>
101
+=head2 home
105 102
 
106 103
   my $home = $app->home;
107 104
   $app     = $app->home(Mojo::Home->new);
... ...
@@ -112,7 +109,7 @@ which stringifies to the actual path.
112 109
   # Generate portable path relative to home directory
113 110
   my $path = $app->home->rel_file('data/important.txt');
114 111
 
115
-=head2 C<log>
112
+=head2 log
116 113
 
117 114
   my $log = $app->log;
118 115
   $app    = $app->log(Mojo::Log->new);
... ...
@@ -122,7 +119,7 @@ The logging layer of your application, defaults to a L<Mojo::Log> object.
122 119
   # Log debug message
123 120
   $app->log->debug('It works!');
124 121
 
125
-=head2 C<ua>
122
+=head2 ua
126 123
 
127 124
   my $ua = $app->ua;
128 125
   $app   = $app->ua(Mojo::UserAgent->new);
... ...
@@ -140,21 +137,21 @@ interfere with new blocking ones.
140 137
 L<Mojo> inherits all methods from L<Mojo::Base> and implements the following
141 138
 new ones.
142 139
 
143
-=head2 C<new>
140
+=head2 new
144 141
 
145 142
   my $app = Mojo->new;
146 143
 
147 144
 Construct a new L<Mojo> application. Will automatically detect your home
148 145
 directory and set up logging to C<log/mojo.log> if there's a C<log> directory.
149 146
 
150
-=head2 C<build_tx>
147
+=head2 build_tx
151 148
 
152 149
   my $tx = $app->build_tx;
153 150
 
154 151
 Transaction builder, defaults to building a L<Mojo::Transaction::HTTP>
155 152
 object.
156 153
 
157
-=head2 C<config>
154
+=head2 config
158 155
 
159 156
   my $config = $app->config;
160 157
   my $foo    = $app->config('foo');
... ...
@@ -168,7 +165,7 @@ Application configuration.
168 165
   my $foo = $app->config->{foo};
169 166
   delete $app->config->{foo};
170 167
 
171
-=head2 C<handler>
168
+=head2 handler
172 169
 
173 170
   $app->handler(Mojo::Transaction::HTTP->new);
174 171
 
+16 -12
mojolegacy/lib/Mojo/Asset.pm
... ...
@@ -40,18 +40,22 @@ Mojo::Asset - HTTP content storage base class
40 40
 
41 41
 L<Mojo::Asset> is an abstract base class for HTTP content storage.
42 42
 
43
+=head1 EVENTS
44
+
45
+L<Mojo::Asset> inherits all events from L<Mojo::EventEmitter>.
46
+
43 47
 =head1 ATTRIBUTES
44 48
 
45 49
 L<Mojo::Asset> implements the following attributes.
46 50
 
47
-=head2 C<end_range>
51
+=head2 end_range
48 52
 
49 53
   my $end = $asset->end_range;
50 54
   $asset  = $asset->end_range(8);
51 55
 
52 56
 Pretend file ends earlier.
53 57
 
54
-=head2 C<start_range>
58
+=head2 start_range
55 59
 
56 60
   my $start = $asset->start_range;
57 61
   $asset    = $asset->start_range(0);
... ...
@@ -63,53 +67,53 @@ Pretend file starts later.
63 67
 L<Mojo::Asset> inherits all methods from L<Mojo::EventEmitter> and implements
64 68
 the following new ones.
65 69
 
66
-=head2 C<add_chunk>
70
+=head2 add_chunk
67 71
 
68 72
   $asset = $asset->add_chunk('foo bar baz');
69 73
 
70 74
 Add chunk of data to asset. Meant to be overloaded in a subclass.
71 75
 
72
-=head2 C<contains>
76
+=head2 contains
73 77
 
74 78
   my $position = $asset->contains('bar');
75 79
 
76 80
 Check if asset contains a specific string. Meant to be overloaded in a
77 81
 subclass.
78 82
 
79
-=head2 C<get_chunk>
83
+=head2 get_chunk
80 84
 
81
-  my $chunk = $asset->get_chunk($offset);
85
+  my $bytes = $asset->get_chunk($offset);
82 86
 
83 87
 Get chunk of data starting from a specific position. Meant to be overloaded
84 88
 in a subclass.
85 89
 
86
-=head2 C<is_file>
90
+=head2 is_file
87 91
 
88 92
   my $false = $asset->is_file;
89 93
 
90 94
 False.
91 95
 
92
-=head2 C<is_range>
96
+=head2 is_range
93 97
 
94 98
   my $success = $asset->is_range;
95 99
 
96 100
 Check if asset has a C<start_range> or C<end_range>.
97 101
 
98
-=head2 C<move_to>
102
+=head2 move_to
99 103
 
100 104
   $asset = $asset->move_to('/home/sri/foo.txt');
101 105
 
102 106
 Move asset data into a specific file. Meant to be overloaded in a subclass.
103 107
 
104
-=head2 C<size>
108
+=head2 size
105 109
 
106 110
   my $size = $asset->size;
107 111
 
108 112
 Size of asset data in bytes. Meant to be overloaded in a subclass.
109 113
 
110
-=head2 C<slurp>
114
+=head2 slurp
111 115
 
112
-  my $string = $asset->slurp;
116
+  my $bytes = $asset->slurp;
113 117
 
114 118
 Read all asset data at once. Meant to be overloaded in a subclass.
115 119
 
+21 -20
mojolegacy/lib/Mojo/Asset/File.pm
... ...
@@ -5,7 +5,7 @@ use Carp 'croak';
5 5
 use Errno 'EEXIST';
6 6
 use Fcntl qw(O_CREAT O_EXCL O_RDWR);
7 7
 use File::Copy 'move';
8
-use File::Spec;
8
+use File::Spec::Functions 'catfile';
9 9
 use IO::File;
10 10
 use Mojo::Util 'md5_sum';
11 11
 
... ...
@@ -17,12 +17,12 @@ has handle => sub {
17 17
   my $handle = IO::File->new;
18 18
   my $path   = $self->path;
19 19
   if (defined $path && -f $path) {
20
-    $handle->open("< $path") or croak qq{Can't open file "$path": $!};
20
+    $handle->open($path, '<') or croak qq{Can't open file "$path": $!};
21 21
     return $handle;
22 22
   }
23 23
 
24 24
   # Open new or temporary file
25
-  my $base = File::Spec->catfile($self->tmpdir, 'mojo.tmp');
25
+  my $base = catfile File::Spec::Functions::tmpdir, 'mojo.tmp';
26 26
   my $name = defined $path ? $path : $base;
27 27
   until ($handle->open($name, O_CREAT | O_EXCL | O_RDWR)) {
28 28
     croak qq{Can't open file "$name": $!} if defined $path || $! != $!{EEXIST};
... ...
@@ -35,7 +35,7 @@ has handle => sub {
35 35
 
36 36
   return $handle;
37 37
 };
38
-has tmpdir => sub { $ENV{MOJO_TMPDIR} || File::Spec->tmpdir };
38
+has tmpdir => sub { $ENV{MOJO_TMPDIR} || File::Spec::Functions::tmpdir };
39 39
 
40 40
 sub DESTROY {
41 41
   my $self = shift;
... ...
@@ -59,7 +59,6 @@ sub add_chunk {
59 59
 sub contains {
60 60
   my ($self, $string) = @_;
61 61
 
62
-  # Seek to start
63 62
   my $handle = $self->handle;
64 63
   $handle->sysseek($self->start_range, SEEK_SET);
65 64
 
... ...
@@ -95,12 +94,10 @@ sub contains {
95 94
 sub get_chunk {
96 95
   my ($self, $start) = @_;
97 96
 
98
-  # Seek to start
99 97
   $start += $self->start_range;
100 98
   my $handle = $self->handle;
101 99
   $handle->sysseek($start, SEEK_SET);
102 100
 
103
-  # Range support
104 101
   my $buffer;
105 102
   if (defined(my $end = $self->end_range)) {
106 103
     my $chunk = $end + 1 - $start;
... ...
@@ -165,26 +162,30 @@ Mojo::Asset::File - File storage for HTTP content
165 162
 
166 163
 L<Mojo::Asset::File> is a file storage backend for HTTP content.
167 164
 
165
+=head1 EVENTS
166
+
167
+L<Mojo::Asset::File> inherits all events from L<Mojo::Asset>.
168
+
168 169
 =head1 ATTRIBUTES
169 170
 
170 171
 L<Mojo::Asset::File> inherits all attributes from L<Mojo::Asset> and
171 172
 implements the following new ones.
172 173
 
173
-=head2 C<cleanup>
174
+=head2 cleanup
174 175
 
175 176
   my $cleanup = $file->cleanup;
176 177
   $file       = $file->cleanup(1);
177 178
 
178 179
 Delete file automatically once it's not used anymore.
179 180
 
180
-=head2 C<handle>
181
+=head2 handle
181 182
 
182 183
   my $handle = $file->handle;
183 184
   $file      = $file->handle(IO::File->new);
184 185
 
185 186
 File handle, created on demand.
186 187
 
187
-=head2 C<path>
188
+=head2 path
188 189
 
189 190
   my $path = $file->path;
190 191
   $file    = $file->path('/home/sri/foo.txt');
... ...
@@ -192,7 +193,7 @@ File handle, created on demand.
192 193
 File path used to create C<handle>, can also be automatically generated if
193 194
 necessary.
194 195
 
195
-=head2 C<tmpdir>
196
+=head2 tmpdir
196 197
 
197 198
   my $tmpdir = $file->tmpdir;
198 199
   $file      = $file->tmpdir('/tmp');
... ...
@@ -205,45 +206,45 @@ C<MOJO_TMPDIR> environment variable or auto detection.
205 206
 L<Mojo::Asset::File> inherits all methods from L<Mojo::Asset> and implements
206 207
 the following new ones.
207 208
 
208
-=head2 C<add_chunk>
209
+=head2 add_chunk
209 210
 
210 211
   $file = $file->add_chunk('foo bar baz');
211 212
 
212 213
 Add chunk of data.
213 214
 
214
-=head2 C<contains>
215
+=head2 contains
215 216
 
216 217
   my $position = $file->contains('bar');
217 218
 
218 219
 Check if asset contains a specific string.
219 220
 
220
-=head2 C<get_chunk>
221
+=head2 get_chunk
221 222
 
222
-  my $chunk = $file->get_chunk($start);
223
+  my $bytes = $file->get_chunk($start);
223 224
 
224 225
 Get chunk of data starting from a specific position.
225 226
 
226
-=head2 C<is_file>
227
+=head2 is_file
227 228
 
228 229
   my $true = $file->is_file;
229 230
 
230 231
 True.
231 232
 
232
-=head2 C<move_to>
233
+=head2 move_to
233 234
 
234 235
   $file = $file->move_to('/home/sri/bar.txt');
235 236
 
236 237
 Move asset data into a specific file and disable C<cleanup>.
237 238
 
238
-=head2 C<size>
239
+=head2 size
239 240
 
240 241
   my $size = $file->size;
241 242
 
242 243
 Size of asset data in bytes.
243 244
 
244
-=head2 C<slurp>
245
+=head2 slurp
245 246
 
246
-  my $string = $file->slurp;
247
+  my $bytes = $file->slurp;
247 248
 
248 249
 Read all asset data at once.
249 250
 
+14 -13
mojolegacy/lib/Mojo/Asset/Memory.pm
... ...
@@ -73,9 +73,10 @@ L<Mojo::Asset::Memory> is an in-memory storage backend for HTTP content.
73 73
 
74 74
 =head1 EVENTS
75 75
 
76
-L<Mojo::Asset::Memory> can emit the following events.
76
+L<Mojo::Asset::Memory> inherits all events from L<Mojo::Asset> and can emit
77
+the following new ones.
77 78
 
78
-=head2 C<upgrade>
79
+=head2 upgrade
79 80
 
80 81
   $mem->on(upgrade => sub {
81 82
     my ($mem, $file) = @_;
... ...
@@ -94,7 +95,7 @@ Emitted when asset gets upgraded to a L<Mojo::Asset::File> object.
94 95
 L<Mojo::Asset::Memory> inherits all attributes from L<Mojo::Asset> and
95 96
 implements the following new ones.
96 97
 
97
-=head2 C<auto_upgrade>
98
+=head2 auto_upgrade
98 99
 
99 100
   my $upgrade = $mem->auto_upgrade;
100 101
   $mem        = $mem->auto_upgrade(1);
... ...
@@ -102,7 +103,7 @@ implements the following new ones.
102 103
 Try to detect if content size exceeds C<max_memory_size> limit and
103 104
 automatically upgrade to a L<Mojo::Asset::File> object.
104 105
 
105
-=head2 C<max_memory_size>
106
+=head2 max_memory_size
106 107
 
107 108
   my $size = $mem->max_memory_size;
108 109
   $mem     = $mem->max_memory_size(1024);
... ...
@@ -116,46 +117,46 @@ C<MOJO_MAX_MEMORY_SIZE> environment variable or C<262144>.
116 117
 L<Mojo::Asset::Memory> inherits all methods from L<Mojo::Asset> and implements
117 118
 the following new ones.
118 119
 
119
-=head2 C<new>
120
+=head2 new
120 121
 
121 122
   my $mem = Mojo::Asset::Memory->new;
122 123
 
123 124
 Construct a new L<Mojo::Asset::Memory> object.
124 125
 
125
-=head2 C<add_chunk>
126
+=head2 add_chunk
126 127
 
127 128
   $mem     = $mem->add_chunk('foo bar baz');
128 129
   my $file = $mem->add_chunk('abc' x 262144);
129 130
 
130 131
 Add chunk of data and upgrade to L<Mojo::Asset::File> object if necessary.
131 132
 
132
-=head2 C<contains>
133
+=head2 contains
133 134
 
134 135
   my $position = $mem->contains('bar');
135 136
 
136 137
 Check if asset contains a specific string.
137 138
 
138
-=head2 C<get_chunk>
139
+=head2 get_chunk
139 140
 
140
-  my $chunk = $mem->get_chunk($offset);
141
+  my $bytes = $mem->get_chunk($offset);
141 142
 
142 143
 Get chunk of data starting from a specific position.
143 144
 
144
-=head2 C<move_to>
145
+=head2 move_to
145 146
 
146 147
   $mem = $mem->move_to('/home/sri/foo.txt');
147 148
 
148 149
 Move asset data into a specific file.
149 150
 
150
-=head2 C<size>
151
+=head2 size
151 152
 
152 153
   my $size = $mem->size;
153 154
 
154 155
 Size of asset data in bytes.
155 156
 
156
-=head2 C<slurp>
157
+=head2 slurp
157 158
 
158
-  my $string = mem->slurp;
159
+  my $bytes = mem->slurp;
159 160
 
160 161
 Read all asset data at once.
161 162
 
+8 -16
mojolegacy/lib/Mojo/Base.pm
... ...
@@ -2,8 +2,6 @@ package Mojo::Base;
2 2
 
3 3
 use strict;
4 4
 use warnings;
5
-
6
-# Mojo modules are modern!
7 5
 use utf8;
8 6
 
9 7
 # No imports because we get subclassed, a lot!
... ...
@@ -16,8 +14,6 @@ use IO::Handle ();
16 14
 sub import {
17 15
   my $class = shift;
18 16
   return unless my $flag = shift;
19
-
20
-  # No limits!
21 17
   no strict 'refs';
22 18
 
23 19
   # Base
... ...
@@ -37,8 +33,6 @@ sub import {
37 33
   if ($flag) {
38 34
     my $caller = caller;
39 35
     push @{"${caller}::ISA"}, $flag;
40
-
41
-    # Can haz?
42 36
     *{"${caller}::has"} = sub { attr($caller, @_) };
43 37
   }
44 38
   
... ...
@@ -64,14 +58,12 @@ sub attr {
64 58
   my ($class, $attrs, $default) = @_;
65 59
   return unless ($class = ref $class || $class) && $attrs;
66 60
 
67
-  # Check default
68
-  Carp::croak('Default has to be a code reference or constant value')
61
+  Carp::croak 'Default has to be a code reference or constant value'
69 62
     if ref $default && ref $default ne 'CODE';
70 63
 
71
-  # Create attributes
64
+  # Compile attributes
72 65
   for my $attr (@{ref $attrs eq 'ARRAY' ? $attrs : [$attrs]}) {
73
-    Carp::croak(qq{Attribute "$attr" invalid})
74
-      unless $attr =~ /^[a-zA-Z_]\w*$/;
66
+    Carp::croak qq{Attribute "$attr" invalid} unless $attr =~ /^[a-zA-Z_]\w*$/;
75 67
 
76 68
     # Header (check arguments)
77 69
     my $code = "package $class;\nsub $attr {\n  if (\@_ == 1) {\n";
... ...
@@ -100,7 +92,7 @@ sub attr {
100 92
     # We compile custom attribute code for speed
101 93
     no strict 'refs';
102 94
     warn "-- Attribute $attr in $class\n$code\n\n" if $ENV{MOJO_BASE_DEBUG};
103
-    Carp::croak("Mojo::Base error: $@") unless eval "$code;1";
95
+    Carp::croak "Mojo::Base error: $@" unless eval "$code;1";
104 96
   }
105 97
 }
106 98
 
... ...
@@ -184,7 +176,7 @@ All three forms save a lot of typing.
184 176
 L<Mojo::Base> exports the following functions if imported with the C<-base>
185 177
 flag or a base class.
186 178
 
187
-=head2 C<has>
179
+=head2 has
188 180
 
189 181
   has 'name';
190 182
   has [qw(name1 name2 name3)];
... ...
@@ -199,7 +191,7 @@ Create attributes for hash-based objects, just like the C<attr> method.
199 191
 
200 192
 L<Mojo::Base> implements the following methods.
201 193
 
202
-=head2 C<new>
194
+=head2 new
203 195
 
204 196
   my $object = BaseSubClass->new;
205 197
   my $object = BaseSubClass->new(name => 'value');
... ...
@@ -208,7 +200,7 @@ L<Mojo::Base> implements the following methods.
208 200
 This base class provides a basic constructor for hash-based objects. You can
209 201
 pass it either a hash or a hash reference with attribute values.
210 202
 
211
-=head2 C<attr>
203
+=head2 attr
212 204
 
213 205
   $object->attr('name');
214 206
   BaseSubClass->attr('name');
... ...
@@ -225,7 +217,7 @@ be excuted at accessor read time if there's no set value. Accessors can be
225 217
 chained, that means they return their invocant when they are called with an
226 218
 argument.
227 219
 
228
-=head2 C<tap>
220
+=head2 tap
229 221
 
230 222
   $object = $object->tap(sub {...});
231 223
 
+39 -47
mojolegacy/lib/Mojo/ByteStream.pm
... ...
@@ -11,10 +11,11 @@ our @EXPORT_OK = ('b');
11 11
 # Turn most functions from Mojo::Util into methods
12 12
 my @UTILS = (
13 13
   qw(b64_decode b64_encode camelize decamelize hmac_md5_sum hmac_sha1_sum),
14
-  qw(html_escape html_unescape md5_bytes md5_sum punycode_decode),
15
-  qw(punycode_encode quote sha1_bytes sha1_sum slurp spurt squish trim),
16
-  qw(unquote url_escape url_unescape xml_escape xor_encode)
14
+  qw(html_unescape md5_bytes md5_sum punycode_decode punycode_encode quote),
15
+  qw(sha1_bytes sha1_sum slurp spurt squish trim unquote url_escape),
16
+  qw(url_unescape xml_escape xor_encode)
17 17
 );
18
+push @UTILS, 'html_escape';    # DEPRECATED in Rainbow!
18 19
 for my $name (@UTILS) {
19 20
   my $sub = Mojo::Util->can($name);
20 21
   Mojo::Util::monkey_patch __PACKAGE__, $name, sub {
... ...
@@ -85,7 +86,7 @@ Mojo::ByteStream - ByteStream
85 86
 
86 87
   # Use the alternative constructor
87 88
   use Mojo::ByteStream 'b';
88
-  my $stream = b('foobarbaz')->html_escape;
89
+  my $stream = b('foobarbaz')->b64_encode('')->say;
89 90
 
90 91
 =head1 DESCRIPTION
91 92
 
... ...
@@ -96,7 +97,7 @@ manipulation functions in L<Mojo::Util>.
96 97
 
97 98
 L<Mojo::ByteStream> implements the following functions.
98 99
 
99
-=head2 C<b>
100
+=head2 b
100 101
 
101 102
   my $stream = b('test123');
102 103
 
... ...
@@ -107,19 +108,19 @@ Construct a new scalar-based L<Mojo::ByteStream> object.
107 108
 L<Mojo::ByteStream> inherits all methods from L<Mojo::Base> and implements the
108 109
 following new ones.
109 110
 
110
-=head2 C<new>
111
+=head2 new
111 112
 
112 113
   my $stream = Mojo::ByteStream->new('test123');
113 114
 
114 115
 Construct a new scalar-based L<Mojo::ByteStream> object.
115 116
 
116
-=head2 C<b64_decode>
117
+=head2 b64_decode
117 118
 
118 119
   $stream = $stream->b64_decode;
119 120
 
120 121
 Base64 decode bytestream with L<Mojo::Util/"b64_decode">.
121 122
 
122
-=head2 C<b64_encode>
123
+=head2 b64_encode
123 124
 
124 125
   $stream = $stream->b64_encode;
125 126
   $stream = $stream->b64_encode("\n");
... ...
@@ -128,25 +129,25 @@ Base64 encode bytestream with L<Mojo::Util/"b64_encode">.
128 129
 
129 130
   b('foo bar baz')->b64_encode('')->say;
130 131
 
131
-=head2 C<camelize>
132
+=head2 camelize
132 133
 
133 134
   $stream = $stream->camelize;
134 135
 
135 136
 Camelize bytestream with L<Mojo::Util/"camelize">.
136 137
 
137
-=head2 C<clone>
138
+=head2 clone
138 139
 
139 140
   my $stream2 = $stream->clone;
140 141
 
141 142
 Clone bytestream.
142 143
 
143
-=head2 C<decamelize>
144
+=head2 decamelize
144 145
 
145 146
   $stream = $stream->decamelize;
146 147
 
147 148
 Decamelize bytestream with L<Mojo::Util/"decamelize">.
148 149
 
149
-=head2 C<decode>
150
+=head2 decode
150 151
 
151 152
   $stream = $stream->decode;
152 153
   $stream = $stream->decode('iso-8859-1');
... ...
@@ -155,7 +156,7 @@ Decode bytestream with L<Mojo::Util/"decode">, defaults to C<UTF-8>.
155 156
 
156 157
   $stream->decode('UTF-16LE')->unquote->trim->say;
157 158
 
158
-=head2 C<encode>
159
+=head2 encode
159 160
 
160 161
   $stream = $stream->encode;
161 162
   $stream = $stream->encode('iso-8859-1');
... ...
@@ -164,13 +165,13 @@ Encode bytestream with L<Mojo::Util/"encode">, defaults to C<UTF-8>.
164 165
 
165 166
   $stream->trim->quote->encode->say;
166 167
 
167
-=head2 C<hmac_md5_sum>
168
+=head2 hmac_md5_sum
168 169
 
169 170
   $stream = $stream->hmac_md5_sum('passw0rd');
170 171
 
171 172
 Generate HMAC-MD5 checksum for bytestream with L<Mojo::Util/"hmac_md5_sum">.
172 173
 
173
-=head2 C<hmac_sha1_sum>
174
+=head2 hmac_sha1_sum
174 175
 
175 176
   $stream = $stream->hmac_sha1_sum('passw0rd');
176 177
 
... ...
@@ -178,16 +179,7 @@ Generate HMAC-SHA1 checksum for bytestream with L<Mojo::Util/"hmac_sha1_sum">.
178 179
 
179 180
   b('foo bar baz')->hmac_sha1_sum('secr3t')->quote->say;
180 181
 
181
-=head2 C<html_escape>
182
-
183
-  $stream = $stream->html_escape;
184
-  $stream = $stream->html_escape('^\n\r\t !#$%(-;=?-~');
185
-
186
-Escape unsafe characters in bytestream with L<Mojo::Util/"html_escape">.
187
-
188
-  b('<html>')->html_escape->say;
189
-
190
-=head2 C<html_unescape>
182
+=head2 html_unescape
191 183
 
192 184
   $stream = $stream->html_unescape;
193 185
 
... ...
@@ -195,44 +187,44 @@ Unescape all HTML entities in bytestream with L<Mojo::Util/"html_unescape">.
195 187
 
196 188
   b('&lt;html&gt;')->html_unescape->url_escape->say;
197 189
 
198
-=head2 C<md5_bytes>
190
+=head2 md5_bytes
199 191
 
200 192
   $stream = $stream->md5_bytes;
201 193
 
202 194
 Generate binary MD5 checksum for bytestream with L<Mojo::Util/"md5_bytes">.
203 195
 
204
-=head2 C<md5_sum>
196
+=head2 md5_sum
205 197
 
206 198
   $stream = $stream->md5_sum;
207 199
 
208 200
 Generate MD5 checksum for bytestream with L<Mojo::Util/"md5_sum">.
209 201
 
210
-=head2 C<punycode_decode>
202
+=head2 punycode_decode
211 203
 
212 204
   $stream = $stream->punycode_decode;
213 205
 
214 206
 Punycode decode bytestream with L<Mojo::Util/"punycode_decode">.
215 207
 
216
-=head2 C<punycode_encode>
208
+=head2 punycode_encode
217 209
 
218 210
   $stream = $stream->punycode_encode;
219 211
 
220 212
 Punycode encode bytestream with L<Mojo::Util/"punycode_encode">.
221 213
 
222
-=head2 C<quote>
214
+=head2 quote
223 215
 
224 216
   $stream = $stream->quote;
225 217
 
226 218
 Quote bytestream with L<Mojo::Util/"quote">.
227 219
 
228
-=head2 C<say>
220
+=head2 say
229 221
 
230 222
   $stream->say;
231 223
   $stream->say(*STDERR);
232 224
 
233 225
 Print bytestream to handle and append a newline, defaults to C<STDOUT>.
234 226
 
235
-=head2 C<secure_compare>
227
+=head2 secure_compare
236 228
 
237 229
   my $success = $stream->secure_compare($string);
238 230
 
... ...
@@ -240,25 +232,25 @@ Compare bytestream with L<Mojo::Util/"secure_compare">.
240 232
 
241 233
   say 'Match!' if b('foo')->secure_compare('foo');
242 234
 
243
-=head2 C<sha1_bytes>
235
+=head2 sha1_bytes
244 236
 
245 237
   $stream = $stream->sha1_bytes;
246 238
 
247 239
 Generate binary SHA1 checksum for bytestream with L<Mojo::Util/"sha1_bytes">.
248 240
 
249
-=head2 C<sha1_sum>
241
+=head2 sha1_sum
250 242
 
251 243
   $stream = $stream->sha1_sum;
252 244
 
253 245
 Generate SHA1 checksum for bytestream with L<Mojo::Util/"sha1_sum">.
254 246
 
255
-=head2 C<size>
247
+=head2 size
256 248
 
257 249
   my $size = $stream->size;
258 250
 
259 251
 Size of bytestream.
260 252
 
261
-=head2 C<slurp>
253
+=head2 slurp
262 254
 
263 255
   $stream = $stream->slurp;
264 256
 
... ...
@@ -266,7 +258,7 @@ Read all data at once from file into bytestream with L<Mojo::Util/"slurp">.
266 258
 
267 259
   b('/home/sri/myapp.pl')->slurp->split("\n")->shuffle->join("\n")->say;
268 260
 
269
-=head2 C<spurt>
261
+=head2 spurt
270 262
 
271 263
   $stream = $stream->spurt('/home/sri/myapp.pl');
272 264
 
... ...
@@ -274,7 +266,7 @@ Write all data from bytestream at once to file with L<Mojo::Util/"spurt">.
274 266
 
275 267
   b('/home/sri/foo.txt')->slurp->squish->spurt('/home/sri/bar.txt');
276 268
 
277
-=head2 C<split>
269
+=head2 split
278 270
 
279 271
   my $collection = $stream->split(',');
280 272
 
... ...
@@ -282,7 +274,7 @@ Turn bytestream into L<Mojo::Collection>.
282 274
 
283 275
   b('a,b,c')->split(',')->pluck('quote')->join(',')->say;
284 276
 
285
-=head2 C<squish>
277
+=head2 squish
286 278
 
287 279
   $stream = $stream->squish;
288 280
 
... ...
@@ -290,27 +282,27 @@ Trim whitespace characters from both ends of bytestream and then change all
290 282
 consecutive groups of whitespace into one space each with
291 283
 L<Mojo::Util/"squish">.
292 284
 
293
-=head2 C<to_string>
285
+=head2 to_string
294 286
 
295 287
   my $string = $stream->to_string;
296 288
   my $string = "$stream";
297 289
 
298 290
 Stringify bytestream.
299 291
 
300
-=head2 C<trim>
292
+=head2 trim
301 293
 
302 294
   $stream = $stream->trim;
303 295
 
304 296
 Trim whitespace characters from both ends of bytestream with
305 297
 L<Mojo::Util/"trim">.
306 298
 
307
-=head2 C<unquote>
299
+=head2 unquote
308 300
 
309 301
   $stream = $stream->unquote;
310 302
 
311 303
 Unquote bytestream with L<Mojo::Util/"unquote">.
312 304
 
313
-=head2 C<url_escape>
305
+=head2 url_escape
314 306
 
315 307
   $stream = $stream->url_escape;
316 308
   $stream = $stream->url_escape('^A-Za-z0-9\-._~');
... ...
@@ -320,23 +312,23 @@ L<Mojo::Util/"url_escape">.
320 312
 
321 313
   b('foo bar baz')->url_escape->say;
322 314
 
323
-=head2 C<url_unescape>
315
+=head2 url_unescape
324 316
 
325 317
   $stream = $stream->url_unescape;
326 318
 
327 319
 Decode percent encoded characters in bytestream with
328 320
 L<Mojo::Util/"url_unescape">.
329 321
 
330
-  b('%3Chtml%3E')->url_unescape->html_escape->say;
322
+  b('%3Chtml%3E')->url_unescape->xml_escape->say;
331 323
 
332
-=head2 C<xml_escape>
324
+=head2 xml_escape
333 325
 
334 326
   $stream = $stream->xml_escape;
335 327
 
336 328
 Escape only the characters C<&>, C<E<lt>>, C<E<gt>>, C<"> and C<'> in
337 329
 bytestream with L<Mojo::Util/"xml_escape">.
338 330
 
339
-=head2 C<xor_encode>
331
+=head2 xor_encode
340 332
 
341 333
   $stream = $stream->xor_encode($key);
342 334
 
+3 -4
mojolegacy/lib/Mojo/Cache.pm
... ...
@@ -8,7 +8,6 @@ sub get { (shift->{cache} || {})->{shift()} }
8 8
 sub set {
9 9
   my ($self, $key, $value) = @_;
10 10
 
11
-  # Cache with size limit
12 11
   my $cache = $self->{cache} ||= {};
13 12
   my $queue = $self->{queue} ||= [];
14 13
   delete $cache->{shift @$queue} if @$queue >= $self->max_keys;
... ...
@@ -40,7 +39,7 @@ L<Mojo::Cache> is a naive in-memory cache with size limits.
40 39
 
41 40
 L<Mojo::Cache> implements the following attributes.
42 41
 
43
-=head2 C<max_keys>
42
+=head2 max_keys
44 43
 
45 44
   my $max = $cache->max_keys;
46 45
   $cache  = $cache->max_keys(50);
... ...
@@ -52,13 +51,13 @@ Maximum number of cache keys, defaults to C<100>.
52 51
 L<Mojo::Cache> inherits all methods from L<Mojo::Base> and implements the
53 52
 following new ones.
54 53
 
55
-=head2 C<get>
54
+=head2 get
56 55
 
57 56
   my $value = $cache->get('foo');
58 57
 
59 58
 Get cached value.
60 59
 
61
-=head2 C<set>
60
+=head2 set
62 61
 
63 62
   $cache = $cache->set(foo => 'bar');
64 63
 
+14 -14
mojolegacy/lib/Mojo/Collection.pm
... ...
@@ -112,7 +112,7 @@ L<Mojo::Collection> is a container for collections.
112 112
 
113 113
 L<Mojo::Collection> implements the following functions.
114 114
 
115
-=head2 C<c>
115
+=head2 c
116 116
 
117 117
   my $collection = c(1, 2, 3);
118 118
 
... ...
@@ -123,13 +123,13 @@ Construct a new array-based L<Mojo::Collection> object.
123 123
 L<Mojo::Collection> inherits all methods from L<Mojo::Base> and implements the
124 124
 following new ones.
125 125
 
126
-=head2 C<new>
126
+=head2 new
127 127
 
128 128
   my $collection = Mojo::Collection->new(1, 2, 3);
129 129
 
130 130
 Construct a new array-based L<Mojo::Collection> object.
131 131
 
132
-=head2 C<each>
132
+=head2 each
133 133
 
134 134
   my @elements = $collection->each;
135 135
   $collection  = $collection->each(sub {...});
... ...
@@ -141,7 +141,7 @@ Evaluate callback for each element in collection.
141 141
     say "$count: $e";
142 142
   });
143 143
 
144
-=head2 C<first>
144
+=head2 first
145 145
 
146 146
   my $first = $collection->first;
147 147
   my $first = $collection->first(qr/foo/);
... ...
@@ -153,7 +153,7 @@ callback returned true.
153 153
 
154 154
   my $five = $collection->first(sub { $_ == 5 });
155 155
 
156
-=head2 C<grep>
156
+=head2 grep
157 157
 
158 158
   my $new = $collection->grep(qr/foo/);
159 159
   my $new = $collection->grep(sub {...});
... ...
@@ -164,7 +164,7 @@ or for which the callback returned true.
164 164
 
165 165
   my $interesting = $collection->grep(qr/mojo/i);
166 166
 
167
-=head2 C<join>
167
+=head2 join
168 168
 
169 169
   my $stream = $collection->join("\n");
170 170
 
... ...
@@ -172,7 +172,7 @@ Turn collection into L<Mojo::ByteStream>.
172 172
 
173 173
   $collection->join("\n")->say;
174 174
 
175
-=head2 C<map>
175
+=head2 map
176 176
 
177 177
   my $new = $collection->map(sub {...});
178 178
 
... ...
@@ -181,7 +181,7 @@ from the results.
181 181
 
182 182
   my $doubled = $collection->map(sub { $_ * 2 });
183 183
 
184
-=head2 C<pluck>
184
+=head2 pluck
185 185
 
186 186
   my $new = $collection->pluck($method);
187 187
   my $new = $collection->pluck($method, @args);
... ...
@@ -192,31 +192,31 @@ results.
192 192
   # Equal to but more convenient than
193 193
   my $new = $collection->map(sub { $_->$method(@args) });
194 194
 
195
-=head2 C<reverse>
195
+=head2 reverse
196 196
 
197 197
   my $new = $collection->reverse;
198 198
 
199 199
 Create a new collection with all elements in reverse order.
200 200
 
201
-=head2 C<slice>
201
+=head2 slice
202 202
 
203 203
   my $new = $collection->slice(4 .. 7);
204 204
 
205 205
 Create a new collection with all selected elements.
206 206
 
207
-=head2 C<shuffle>
207
+=head2 shuffle
208 208
 
209 209
   my $new = $collection->shuffle;
210 210
 
211 211
 Create a new collection with all elements in random order.
212 212
 
213
-=head2 C<size>
213
+=head2 size
214 214
 
215 215
   my $size = $collection->size;
216 216
 
217 217
 Number of elements in collection.
218 218
 
219
-=head2 C<sort>
219
+=head2 sort
220 220
 
221 221
   my $new = $collection->sort;
222 222
   my $new = $collection->sort(sub {...});
... ...
@@ -226,7 +226,7 @@ from the results.
226 226
 
227 227
   my $insensitive = $collection->sort(sub { uc(shift) cmp uc(shift) });
228 228
 
229
-=head2 C<uniq>
229
+=head2 uniq
230 230
 
231 231
   my $new = $collection->uniq;
232 232
 
+56 -89
mojolegacy/lib/Mojo/Content.pm
... ...
@@ -40,14 +40,9 @@ sub clone {
40 40
 sub generate_body_chunk {
41 41
   my ($self, $offset) = @_;
42 42
 
43
-  # Drain
44 43
   $self->emit(drain => $offset)
45 44
     if !delete $self->{delay} && !length(defined $self->{body_buffer} ? $self->{body_buffer} : '');
46
-
47
-  # Get chunk
48
-  my $chunk = do { my $tmp = (delete $self->{body_buffer}); defined $tmp ? $tmp : '' };
49
-
50
-  # EOF or delay
45
+  my $chunk = do { my $tmp = delete $self->{body_buffer}; defined $tmp ? $tmp : '' };
51 46
   return $self->{eof} ? '' : undef unless length $chunk;
52 47
 
53 48
   return $chunk;
... ...
@@ -92,12 +87,12 @@ sub leftovers { shift->{buffer} }
92 87
 sub parse {
93 88
   my $self = shift;
94 89
 
95
-  # Parse headers
90
+  # Headers
96 91
   $self->_parse_until_body(@_);
97 92
   return $self if $self->{state} eq 'headers';
98 93
   $self->emit('body') unless $self->{body}++;
99 94
 
100
-  # Parse chunked content
95
+  # Chunked content
101 96
   $self->{real_size} = defined $self->{real_size} ? $self->{real_size} : 0;
102 97
   if ($self->is_chunked && $self->{state} ne 'headers') {
103 98
     $self->_parse_chunked;
... ...
@@ -130,7 +125,7 @@ sub parse {
130 125
 
131 126
   # Chunked or relaxed content
132 127
   if ($self->is_chunked || $self->relaxed) {
133
-    $self->{size} += length(defined $self->{buffer} ? $self->{buffer} : '');
128
+    $self->{size} += length($self->{buffer} = defined $self->{buffer} ? $self->{buffer} : '');
134 129
     $self->_uncompress($self->{buffer});
135 130
     $self->{buffer} = '';
136 131
   }
... ...
@@ -140,12 +135,11 @@ sub parse {
140 135
     my $len = $headers->content_length || 0;
141 136
     $self->{size} ||= 0;
142 137
     if ((my $need = $len - $self->{size}) > 0) {
143
-      my $chunk = substr $self->{buffer}, 0, $need, '';
138
+      my $len = length $self->{buffer};
139
+      my $chunk = substr $self->{buffer}, 0, $need > $len ? $len : $need, '';
144 140
       $self->_uncompress($chunk);
145 141
       $self->{size} += length $chunk;
146 142
     }
147
-
148
-    # Finished
149 143
     $self->{state} = 'finished' if $len <= $self->progress;
150 144
   }
151 145
 
... ...
@@ -168,19 +162,10 @@ sub progress {
168 162
 sub write {
169 163
   my ($self, $chunk, $cb) = @_;
170 164
 
171
-  # Dynamic content
172 165
   $self->{dynamic} = 1;
173
-
174
-  # Add chunk
175 166
   if (defined $chunk) { $self->{body_buffer} .= $chunk }
176
-
177
-  # Delay
178
-  else { $self->{delay} = 1 }
179
-
180
-  # Drain
167
+  else                { $self->{delay} = 1 }
181 168
   $self->once(drain => $cb) if $cb;
182
-
183
-  # Finish
184 169
   $self->{eof} = 1 if defined $chunk && $chunk eq '';
185 170
 
186 171
   return $self;
... ...
@@ -188,23 +173,15 @@ sub write {
188 173
 
189 174
 sub write_chunk {
190 175
   my ($self, $chunk, $cb) = @_;
191
-
192
-  # Chunked transfer encoding
193 176
   $self->headers->transfer_encoding('chunked') unless $self->is_chunked;
194
-
195
-  # Write
196 177
   $self->write(defined $chunk ? $self->_build_chunk($chunk) : $chunk, $cb);
197
-
198
-  # Finish
199 178
   $self->{eof} = 1 if defined $chunk && $chunk eq '';
200
-
201 179
   return $self;
202 180
 }
203 181
 
204 182
 sub _build {
205 183
   my ($self, $method) = @_;
206 184
 
207
-  # Build part from chunks
208 185
   my $buffer = '';
209 186
   my $offset = 0;
210 187
   while (1) {
... ...
@@ -215,7 +192,6 @@ sub _build {
215 192
     # End of part
216 193
     last unless my $len = length $chunk;
217 194
 
218
-    # Part
219 195
     $offset += $len;
220 196
     $buffer .= $chunk;
221 197
   }
... ...
@@ -241,7 +217,6 @@ sub _parse_chunked {
241 217
   return $self->_parse_chunked_trailing_headers
242 218
     if (defined $self->{chunk_state} ? $self->{chunk_state} : '') eq 'trailing_headers';
243 219
 
244
-  # Parse chunks
245 220
   while (my $len = length $self->{pre_buffer}) {
246 221
 
247 222
     # Start new chunk (ignore the chunk extension)
... ...
@@ -274,7 +249,6 @@ sub _parse_chunked {
274 249
 sub _parse_chunked_trailing_headers {
275 250
   my $self = shift;
276 251
 
277
-  # Parse
278 252
   my $headers = $self->headers->parse(delete $self->{pre_buffer});
279 253
   return unless $headers->is_finished;
280 254
   $self->{chunk_state} = 'finished';
... ...
@@ -287,7 +261,6 @@ sub _parse_chunked_trailing_headers {
287 261
 sub _parse_headers {
288 262
   my $self = shift;
289 263
 
290
-  # Parse
291 264
   my $headers = $self->headers->parse(delete $self->{pre_buffer});
292 265
   return unless $headers->is_finished;
293 266
   $self->{state} = 'body';
... ...
@@ -301,21 +274,13 @@ sub _parse_headers {
301 274
 sub _parse_until_body {
302 275
   my ($self, $chunk) = @_;
303 276
 
304
-  # Add chunk
305 277
   $self->{raw_size} += length($chunk = defined $chunk ? $chunk : '');
306 278
   $self->{pre_buffer} .= $chunk;
307 279
 
308
-  # Parser started
309 280
   unless ($self->{state}) {
310
-
311
-    # Update size
312 281
     $self->{header_size} = $self->{raw_size} - length $self->{pre_buffer};
313
-
314
-    # Headers
315
-    $self->{state} = 'headers';
282
+    $self->{state}       = 'headers';
316 283
   }
317
-
318
-  # Parse headers
319 284
   $self->_parse_headers if (defined $self->{state} ? $self->{state} : '') eq 'headers';
320 285
 }
321 286
 
... ...
@@ -363,9 +328,10 @@ RFC 2616.
363 328
 
364 329
 =head1 EVENTS
365 330
 
366
-L<Mojo::Content> can emit the following events.
331
+L<Mojo::Content> inherits all events from L<Mojo::EventEmitter> and can emit
332
+the following new ones.
367 333
 
368
-=head2 C<body>
334
+=head2 body
369 335
 
370 336
   $content->on(body => sub {
371 337
     my $content = shift;
... ...
@@ -379,7 +345,7 @@ Emitted once all headers have been parsed and the body starts.
379 345
     $content->auto_upgrade(0) if $content->headers->header('X-No-MultiPart');
380 346
   });
381 347
 
382
-=head2 C<drain>
348
+=head2 drain
383 349
 
384 350
   $content->on(drain => sub {
385 351
     my ($content, $offset) = @_;
... ...
@@ -393,10 +359,10 @@ Emitted once all data has been written.
393 359
     $content->write_chunk(time);
394 360
   });
395 361
 
396
-=head2 C<read>
362
+=head2 read
397 363
 
398 364
   $content->on(read => sub {
399
-    my ($content, $chunk) = @_;
365
+    my ($content, $bytes) = @_;
400 366
     ...
401 367
   });
402 368
 
... ...
@@ -404,29 +370,29 @@ Emitted when a new chunk of content arrives.
404 370
 
405 371
   $content->unsubscribe('read');
406 372
   $content->on(read => sub {
407
-    my ($content, $chunk) = @_;
408
-    say "Streaming: $chunk";
373
+    my ($content, $bytes) = @_;
374
+    say "Streaming: $bytes";
409 375
   });
410 376
 
411 377
 =head1 ATTRIBUTES
412 378
 
413 379
 L<Mojo::Content> implements the following attributes.
414 380
 
415
-=head2 C<auto_relax>
381
+=head2 auto_relax
416 382
 
417 383
   my $relax = $content->auto_relax;
418 384
   $content  = $content->auto_relax(1);
419 385
 
420 386
 Try to detect when relaxed parsing is necessary.
421 387
 
422
-=head2 C<headers>
388
+=head2 headers
423 389
 
424 390
   my $headers = $content->headers;
425 391
   $content    = $content->headers(Mojo::Headers->new);
426 392
 
427 393
 Content headers, defaults to a L<Mojo::Headers> object.
428 394
 
429
-=head2 C<max_buffer_size>
395
+=head2 max_buffer_size
430 396
 
431 397
   my $size = $content->max_buffer_size;
432 398
   $content = $content->max_buffer_size(1024);
... ...
@@ -434,7 +400,7 @@ Content headers, defaults to a L<Mojo::Headers> object.
434 400
 Maximum size in bytes of buffer for content parser, defaults to the value of
435 401
 the C<MOJO_MAX_BUFFER_SIZE> environment variable or C<262144>.
436 402
 
437
-=head2 C<max_leftover_size>
403
+=head2 max_leftover_size
438 404
 
439 405
   my $size = $content->max_leftover_size;
440 406
   $content = $content->max_leftover_size(1024);
... ...
@@ -442,7 +408,7 @@ the C<MOJO_MAX_BUFFER_SIZE> environment variable or C<262144>.
442 408
 Maximum size in bytes of buffer for pipelined HTTP requests, defaults to the
443 409
 value of the C<MOJO_MAX_LEFTOVER_SIZE> environment variable or C<262144>.
444 410
 
445
-=head2 C<relaxed>
411
+=head2 relaxed
446 412
 
447 413
   my $relaxed = $content->relaxed;
448 414
   $content    = $content->relaxed(1);
... ...
@@ -450,7 +416,7 @@ value of the C<MOJO_MAX_LEFTOVER_SIZE> environment variable or C<262144>.
450 416
 Activate relaxed parsing for responses that are terminated with a connection
451 417
 close.
452 418
 
453
-=head2 C<skip_body>
419
+=head2 skip_body
454 420
 
455 421
   my $skip = $content->skip_body;
456 422
   $content = $content->skip_body(1);
... ...
@@ -462,159 +428,160 @@ Skip body parsing and finish after headers.
462 428
 L<Mojo::Content> inherits all methods from L<Mojo::EventEmitter> and
463 429
 implements the following new ones.
464 430
 
465
-=head2 C<body_contains>
431
+=head2 body_contains
466 432
 
467 433
   my $success = $content->body_contains('foo bar baz');
468 434
 
469 435
 Check if content contains a specific string. Meant to be overloaded in a
470 436
 subclass.
471 437
 
472
-=head2 C<body_size>
438
+=head2 body_size
473 439
 
474 440
   my $size = $content->body_size;
475 441
 
476 442
 Content size in bytes. Meant to be overloaded in a subclass.
477 443
 
478
-=head2 C<boundary>
444
+=head2 boundary
479 445
 
480 446
   my $boundary = $content->boundary;
481 447
 
482 448
 Extract multipart boundary from C<Content-Type> header.
483 449
 
484
-=head2 C<build_body>
450
+=head2 build_body
485 451
 
486 452
   my $string = $content->build_body;
487 453
 
488 454
 Render whole body.
489 455
 
490
-=head2 C<build_headers>
456
+=head2 build_headers
491 457
 
492 458
   my $string = $content->build_headers;
493 459
 
494 460
 Render all headers.
495 461
 
496
-=head2 C<charset>
462
+=head2 charset
497 463
 
498 464
   my $charset = $content->charset;
499 465
 
500 466
 Extract charset from C<Content-Type> header.
501 467
 
502
-=head2 C<clone>
468
+=head2 clone
503 469
 
504 470
   my $clone = $content->clone;
505 471
 
506 472
 Clone content if possible, otherwise return C<undef>.
507 473
 
508
-=head2 C<generate_body_chunk>
474
+=head2 generate_body_chunk
509 475
 
510
-  my $chunk = $content->generate_body_chunk(0);
476
+  my $bytes = $content->generate_body_chunk(0);
511 477
 
512 478
 Generate dynamic content.
513 479
 
514
-=head2 C<get_body_chunk>
480
+=head2 get_body_chunk
515 481
 
516
-  my $chunk = $content->get_body_chunk(0);
482
+  my $bytes = $content->get_body_chunk(0);
517 483
 
518 484
 Get a chunk of content starting from a specfic position. Meant to be
519 485
 overloaded in a subclass.
520 486
 
521
-=head2 C<get_header_chunk>
487
+=head2 get_header_chunk
522 488
 
523
-  my $chunk = $content->get_header_chunk(13);
489
+  my $bytes = $content->get_header_chunk(13);
524 490
 
525 491
 Get a chunk of the headers starting from a specfic position.
526 492
 
527
-=head2 C<has_leftovers>
493
+=head2 has_leftovers
528 494
 
529 495
   my $success = $content->has_leftovers;
530 496
 
531 497
 Check if there are leftovers.
532 498
 
533
-=head2 C<header_size>
499
+=head2 header_size
534 500
 
535 501
   my $size = $content->header_size;
536 502
 
537 503
 Size of headers in bytes.
538 504
 
539
-=head2 C<is_chunked>
505
+=head2 is_chunked
540 506
 
541 507
   my $success = $content->is_chunked;
542 508
 
543 509
 Check if content is chunked.
544 510
 
545
-=head2 C<is_compressed>
511
+=head2 is_compressed
546 512
 
547 513
   my $success = $content->is_compressed;
548 514
 
549 515
 Check if content is C<gzip> compressed.
550 516
 
551
-=head2 C<is_dynamic>
517
+=head2 is_dynamic
552 518
 
553 519
   my $success = $content->is_dynamic;
554 520
 
555 521
 Check if content will be dynamically generated, which prevents C<clone> from
556 522
 working.
557 523
 
558
-=head2 C<is_finished>
524
+=head2 is_finished
559 525
 
560 526
   my $success = $content->is_finished;
561 527
 
562 528
 Check if parser is finished.
563 529
 
564
-=head2 C<is_limit_exceeded>
530
+=head2 is_limit_exceeded
565 531
 
566 532
   my $success = $content->is_limit_exceeded;
567 533
 
568 534
 Check if buffer has exceeded C<max_buffer_size>.
569 535
 
570
-=head2 C<is_multipart>
536
+=head2 is_multipart
571 537
 
572 538
   my $false = $content->is_multipart;
573 539
 
574 540
 False.
575 541
 
576
-=head2 C<is_parsing_body>
542
+=head2 is_parsing_body
577 543
 
578 544
   my $success = $content->is_parsing_body;
579 545
 
580 546
 Check if body parsing started yet.
581 547
 
582
-=head2 C<leftovers>
548
+=head2 leftovers
583 549
 
584 550
   my $bytes = $content->leftovers;
585 551
 
586 552
 Get leftover data from content parser.
587 553
 
588
-=head2 C<parse>
554
+=head2 parse
589 555
 
590
-  $content = $content->parse("Content-Length: 12\r\n\r\nHello World!");
556
+  $content
557
+    = $content->parse("Content-Length: 12\x0d\x0a\x0d\x0aHello World!");
591 558
 
592 559
 Parse content chunk.
593 560
 
594
-=head2 C<parse_body>
561
+=head2 parse_body
595 562
 
596 563
   $content = $content->parse_body('Hi!');
597 564
 
598 565
 Parse body chunk and skip headers.
599 566
 
600
-=head2 C<progress>
567
+=head2 progress
601 568
 
602 569
   my $size = $content->progress;
603 570
 
604 571
 Size of content already received from message in bytes.
605 572
 
606
-=head2 C<write>
573
+=head2 write
607 574
 
608
-  $content = $content->write('Hello!');
609
-  $content = $content->write('Hello!' => sub {...});
575
+  $content = $content->write($bytes);
576
+  $content = $content->write($bytes => sub {...});
610 577
 
611 578
 Write dynamic content non-blocking, the optional drain callback will be
612 579
 invoked once all data has been written.
613 580
 
614
-=head2 C<write_chunk>
581
+=head2 write_chunk
615 582
 
616
-  $content = $content->write_chunk('Hello!');
617
-  $content = $content->write_chunk('Hello!' => sub {...});
583
+  $content = $content->write_chunk($bytes);
584
+  $content = $content->write_chunk($bytes => sub {...});
618 585
 
619 586
 Write dynamic content non-blocking with C<chunked> transfer encoding, the
620 587
 optional drain callback will be invoked once all data has been written.
+12 -15
mojolegacy/lib/Mojo/Content/MultiPart.pm
... ...
@@ -23,7 +23,7 @@ sub body_contains {
23 23
 sub body_size {
24 24
   my $self = shift;
25 25
 
26
-  # Check for Content-Lenght header
26
+  # Check for existing Content-Lenght header
27 27
   my $content_len = $self->headers->content_length;
28 28
   return $content_len if $content_len;
29 29
 
... ...
@@ -78,7 +78,7 @@ sub get_body_chunk {
78 78
   my $len          = $boundary_len - 2;
79 79
   return substr "--$boundary\x0d\x0a", $offset if $len > $offset;
80 80
 
81
-  # Parts
81
+  # Prepare content part by part
82 82
   my $parts = $self->parts;
83 83
   for (my $i = 0; $i < @$parts; $i++) {
84 84
     my $part = $parts->[$i];
... ...
@@ -150,8 +150,6 @@ sub _parse_multipart_boundary {
150 150
   my $end = "\x0d\x0a--$boundary--";
151 151
   if ((index $self->{multipart}, $end) == 0) {
152 152
     substr $self->{multipart}, 0, length $end, '';
153
-
154
-    # Finished
155 153
     $self->{multi_state} = 'finished';
156 154
   }
157 155
 
... ...
@@ -174,7 +172,6 @@ sub _parse_multipart_preamble {
174 172
 sub _read {
175 173
   my ($self, $chunk) = @_;
176 174
 
177
-  # Parse
178 175
   $self->{multipart} .= $chunk;
179 176
   my $boundary = $self->boundary;
180 177
   until (($self->{multi_state} = defined $self->{multi_state} ? $self->{multi_state} : 'multipart_preamble') eq 'finished') {
... ...
@@ -224,7 +221,7 @@ described in RFC 2616.
224 221
 L<Mojo::Content::Multipart> inherits all events from L<Mojo::Content> and can
225 222
 emit the following new ones.
226 223
 
227
-=head2 C<part>
224
+=head2 part
228 225
 
229 226
   $multi->on(part => sub {
230 227
     my ($multi, $single) = @_;
... ...
@@ -244,7 +241,7 @@ Emitted when a new L<Mojo::Content::Single> part starts.
244 241
 L<Mojo::Content::MultiPart> inherits all attributes from L<Mojo::Content> and
245 242
 implements the following new ones.
246 243
 
247
-=head2 C<parts>
244
+=head2 parts
248 245
 
249 246
   my $parts = $multi->parts;
250 247
   $multi    = $multi->parts([]);
... ...
@@ -257,44 +254,44 @@ L<Mojo::Content::Single> objects.
257 254
 L<Mojo::Content::MultiPart> inherits all methods from L<Mojo::Content> and
258 255
 implements the following new ones.
259 256
 
260
-=head2 C<new>
257
+=head2 new
261 258
 
262 259
   my $multi = Mojo::Content::MultiPart->new;
263 260
 
264 261
 Construct a new L<Mojo::Content::MultiPart> object and subscribe to C<read>
265 262
 event with default content parser.
266 263
 
267
-=head2 C<body_contains>
264
+=head2 body_contains
268 265
 
269 266
   my $success = $multi->body_contains('foobarbaz');
270 267
 
271 268
 Check if content parts contain a specific string.
272 269
 
273
-=head2 C<body_size>
270
+=head2 body_size
274 271
 
275 272
   my $size = $multi->body_size;
276 273
 
277 274
 Content size in bytes.
278 275
 
279
-=head2 C<build_boundary>
276
+=head2 build_boundary
280 277
 
281 278
   my $boundary = $multi->build_boundary;
282 279
 
283 280
 Generate a suitable boundary for content and add it to C<Content-Type> header.
284 281
 
285
-=head2 C<clone>
282
+=head2 clone
286 283
 
287 284
   my $clone = $multi->clone;
288 285
 
289 286
 Clone content if possible, otherwise return C<undef>.
290 287
 
291
-=head2 C<get_body_chunk>
288
+=head2 get_body_chunk
292 289
 
293
-  my $chunk = $multi->get_body_chunk(0);
290
+  my $bytes = $multi->get_body_chunk(0);
294 291
 
295 292
 Get a chunk of content starting from a specfic position.
296 293
 
297
-=head2 C<is_multipart>
294
+=head2 is_multipart
298 295
 
299 296
   my $true = $multi->is_multipart;
300 297
 
+16 -23
mojolegacy/lib/Mojo/Content/Single.pm
... ...
@@ -9,7 +9,8 @@ has auto_upgrade => 1;
9 9
 
10 10
 sub new {
11 11
   my $self = shift->SUPER::new(@_);
12
-  $self->{read} = $self->on(read => \&_read);
12
+  $self->{read}
13
+    = $self->on(read => sub { $_[0]->asset($_[0]->asset->add_chunk($_[1])) });
13 14
   return $self;
14 15
 }
15 16
 
... ...
@@ -29,11 +30,7 @@ sub clone {
29 30
 
30 31
 sub get_body_chunk {
31 32
   my ($self, $offset) = @_;
32
-
33
-  # Body generator
34 33
   return $self->generate_body_chunk($offset) if $self->{dynamic};
35
-
36
-  # Normal content
37 34
   return $self->asset->get_chunk($offset);
38 35
 }
39 36
 
... ...
@@ -54,11 +51,6 @@ sub parse {
54 51
   return $multi->parse;
55 52
 }
56 53
 
57
-sub _read {
58
-  my ($self, $chunk) = @_;
59
-  $self->asset($self->asset->add_chunk($chunk));
60
-}
61
-
62 54
 1;
63 55
 
64 56
 =head1 NAME
... ...
@@ -70,7 +62,7 @@ Mojo::Content::Single - HTTP content
70 62
   use Mojo::Content::Single;
71 63
 
72 64
   my $single = Mojo::Content::Single->new;
73
-  $single->parse("Content-Length: 12\r\n\r\nHello World!");
65
+  $single->parse("Content-Length: 12\x0d\x0a\x0d\x0aHello World!");
74 66
   say $single->headers->content_length;
75 67
 
76 68
 =head1 DESCRIPTION
... ...
@@ -83,7 +75,7 @@ L<Mojo::Content::Single> is a container for HTTP content as described in RFC
83 75
 L<Mojo::Content::Single> inherits all events from L<Mojo::Content> and can
84 76
 emit the following new ones.
85 77
 
86
-=head2 C<upgrade>
78
+=head2 upgrade
87 79
 
88 80
   $single->on(upgrade => sub {
89 81
     my ($single, $multi) = @_;
... ...
@@ -103,7 +95,7 @@ Emitted when content gets upgraded to a L<Mojo::Content::MultiPart> object.
103 95
 L<Mojo::Content::Single> inherits all attributes from L<Mojo::Content> and
104 96
 implements the following new ones.
105 97
 
106
-=head2 C<asset>
98
+=head2 asset
107 99
 
108 100
   my $asset = $single->asset;
109 101
   $single   = $single->asset(Mojo::Asset::Memory->new);
... ...
@@ -111,7 +103,7 @@ implements the following new ones.
111 103
 The actual content, defaults to a L<Mojo::Asset::Memory> object with
112 104
 C<auto_upgrade> enabled.
113 105
 
114
-=head2 C<auto_upgrade>
106
+=head2 auto_upgrade
115 107
 
116 108
   my $upgrade = $single->auto_upgrade;
117 109
   $single     = $single->auto_upgrade(0);
... ...
@@ -124,41 +116,42 @@ L<Mojo::Content::MultiPart> object, defaults to C<1>.
124 116
 L<Mojo::Content::Single> inherits all methods from L<Mojo::Content> and
125 117
 implements the following new ones.
126 118
 
127
-=head2 C<new>
119
+=head2 new
128 120
 
129 121
   my $single = Mojo::Content::Single->new;
130 122
 
131 123
 Construct a new L<Mojo::Content::Single> object and subscribe to C<read> event
132 124
 with default content parser.
133 125
 
134
-=head2 C<body_contains>
126
+=head2 body_contains
135 127
 
136 128
   my $success = $single->body_contains('1234567');
137 129
 
138 130
 Check if content contains a specific string.
139 131
 
140
-=head2 C<body_size>
132
+=head2 body_size
141 133
 
142 134
   my $size = $single->body_size;
143 135
 
144 136
 Content size in bytes.
145 137
 
146
-=head2 C<clone>
138
+=head2 clone
147 139
 
148 140
   my $clone = $single->clone;
149 141
 
150 142
 Clone content if possible, otherwise return C<undef>.
151 143
 
152
-=head2 C<get_body_chunk>
144
+=head2 get_body_chunk
153 145
 
154
-  my $chunk = $single->get_body_chunk(0);
146
+  my $bytes = $single->get_body_chunk(0);
155 147
 
156 148
 Get a chunk of content starting from a specfic position.
157 149
 
158
-=head2 C<parse>
150
+=head2 parse
159 151
 
160
-  $single   = $single->parse("Content-Length: 12\r\n\r\nHello World!");
161
-  my $multi = $single->parse("Content-Type: multipart/form-data\r\n\r\n");
152
+  $single = $single->parse("Content-Length: 12\x0d\x0a\x0d\x0aHello World!");
153
+  my $multi
154
+    = $single->parse("Content-Type: multipart/form-data\x0d\x0a\x0d\x0a");
162 155
 
163 156
 Parse content chunk and upgrade to L<Mojo::Content::MultiPart> object if
164 157
 possible.
+4 -6
mojolegacy/lib/Mojo/Cookie.pm
... ...
@@ -30,8 +30,6 @@ sub _tokenize {
30 30
     # Value
31 31
     my $value;
32 32
     $value = unquote $1 if $string =~ s/^("(?:\\\\|\\"|[^"])+"|[^;,]+)\s*//;
33
-
34
-    # Token
35 33
     push @token, [$name, $value];
36 34
 
37 35
     # Separator
... ...
@@ -68,14 +66,14 @@ L<Mojo::Cookie> is an abstract base class for HTTP cookies.
68 66
 
69 67
 L<Mojo::Cookie> implements the following attributes.
70 68
 
71
-=head2 C<name>
69
+=head2 name
72 70
 
73 71
   my $name = $cookie->name;
74 72
   $cookie  = $cookie->name('foo');
75 73
 
76 74
 Cookie name.
77 75
 
78
-=head2 C<value>
76
+=head2 value
79 77
 
80 78
   my $value = $cookie->value;
81 79
   $cookie   = $cookie->value('/test');
... ...
@@ -87,13 +85,13 @@ Cookie value.
87 85
 L<Mojo::Cookie> inherits all methods from L<Mojo::Base> and implements the
88 86
 following new ones.
89 87
 
90
-=head2 C<parse>
88
+=head2 parse
91 89
 
92 90
   my $cookies = $cookie->parse($string);
93 91
 
94 92
 Parse cookies. Meant to be overloaded in a subclass.
95 93
 
96
-=head2 C<to_string>
94
+=head2 to_string
97 95
 
98 96
   my $string = $cookie->to_string;
99 97
   my $string = "$cookie";
+2 -3
mojolegacy/lib/Mojo/Cookie/Request.pm
... ...
@@ -6,7 +6,6 @@ use Mojo::Util 'quote';
6 6
 sub parse {
7 7
   my ($self, $string) = @_;
8 8
 
9
-  # Walk tree
10 9
   my @cookies;
11 10
   for my $token (map {@$_} $self->_tokenize($string)) {
12 11
     my ($name, $value) = @$token;
... ...
@@ -54,13 +53,13 @@ L<Mojo::Cookie::Request> inherits all attributes from L<Mojo::Cookie>.
54 53
 L<Mojo::Cookie::Request> inherits all methods from L<Mojo::Cookie> and
55 54
 implements the following new ones.
56 55
 
57
-=head2 C<parse>
56
+=head2 parse
58 57
 
59 58
   my $cookies = $cookie->parse('f=b; g=a');
60 59
 
61 60
 Parse cookies.
62 61
 
63
-=head2 C<to_string>
62
+=head2 to_string
64 63
 
65 64
   my $string = $cookie->to_string;
66 65
 
+8 -11
mojolegacy/lib/Mojo/Cookie/Response.pm
... ...
@@ -15,8 +15,6 @@ sub expires {
15 15
     ? Mojo::Date->new($self->{expires})
16 16
     : $self->{expires}
17 17
     unless @_;
18
-
19
-  # New expires value
20 18
   $self->{expires} = shift;
21 19
 
22 20
   return $self;
... ...
@@ -25,7 +23,6 @@ sub expires {
25 23
 sub parse {
26 24
   my ($self, $string) = @_;
27 25
 
28
-  # Walk tree
29 26
   my @cookies;
30 27
   for my $token ($self->_tokenize($string)) {
31 28
     for my $i (0 .. $#$token) {
... ...
@@ -104,14 +101,14 @@ L<Mojo::Cookie::Response> is a container for HTTP response cookies.
104 101
 L<Mojo::Cookie::Response> inherits all attributes from L<Mojo::Cookie> and
105 102
 implements the followign new ones.
106 103
 
107
-=head2 C<domain>
104
+=head2 domain
108 105
 
109 106
   my $domain = $cookie->domain;
110 107
   $cookie    = $cookie->domain('localhost');
111 108
 
112 109
 Cookie domain.
113 110
 
114
-=head2 C<httponly>
111
+=head2 httponly
115 112
 
116 113
   my $httponly = $cookie->httponly;
117 114
   $cookie      = $cookie->httponly(1);
... ...
@@ -119,21 +116,21 @@ Cookie domain.
119 116
 HttpOnly flag, which can prevent client-side scripts from accessing this
120 117
 cookie.
121 118
 
122
-=head2 C<max_age>
119
+=head2 max_age
123 120
 
124 121
   my $max_age = $cookie->max_age;
125 122
   $cookie     = $cookie->max_age(60);
126 123
 
127 124
 Max age for cookie.
128 125
 
129
-=head2 C<path>
126
+=head2 path
130 127
 
131 128
   my $path = $cookie->path;
132 129
   $cookie  = $cookie->path('/test');
133 130
 
134 131
 Cookie path.
135 132
 
136
-=head2 C<secure>
133
+=head2 secure
137 134
 
138 135
   my $secure = $cookie->secure;
139 136
   $cookie    = $cookie->secure(1);
... ...
@@ -146,7 +143,7 @@ connections.
146 143
 L<Mojo::Cookie::Response> inherits all methods from L<Mojo::Cookie> and
147 144
 implements the following new ones.
148 145
 
149
-=head2 C<expires>
146
+=head2 expires
150 147
 
151 148
   my $expires = $cookie->expires;
152 149
   $cookie     = $cookie->expires(time + 60);
... ...
@@ -154,13 +151,13 @@ implements the following new ones.
154 151
 
155 152
 Expiration for cookie.
156 153
 
157
-=head2 C<parse>
154
+=head2 parse
158 155
 
159 156
   my $cookies = $cookie->parse('f=b; path=/');
160 157
 
161 158
 Parse cookies.
162 159
 
163
-=head2 C<to_string>
160
+=head2 to_string
164 161
 
165 162
   my $string = $cookie->to_string;
166 163
 
+66 -100
mojolegacy/lib/Mojo/DOM.pm
... ...
@@ -71,24 +71,21 @@ sub attrs {
71 71
   return $self;
72 72
 }
73 73
 
74
-sub charset { shift->_parser(charset => @_) }
74
+sub charset { shift->_html(charset => @_) }
75 75
 
76 76
 sub children {
77 77
   my ($self, $type) = @_;
78 78
 
79
-  # Walk tree
80 79
   my @children;
81
-  my $tree = $self->tree;
82
-  my $start = $tree->[0] eq 'root' ? 1 : 4;
83
-  for my $e (@$tree[$start .. $#$tree]) {
80
+  my $charset = $self->charset;
81
+  my $xml     = $self->xml;
82
+  my $tree    = $self->tree;
83
+  for my $e (@$tree[($tree->[0] eq 'root' ? 1 : 4) .. $#$tree]) {
84 84
 
85
-    # Make sure child is a tag
85
+    # Make sure child is the right type
86 86
     next unless $e->[0] eq 'tag';
87 87
     next if defined $type && $e->[1] ne $type;
88
-
89
-    # Add child
90
-    push @children,
91
-      $self->new->charset($self->charset)->tree($e)->xml($self->xml);
88
+    push @children, $self->new->charset($charset)->tree($e)->xml($xml);
92 89
   }
93 90
 
94 91
   return Mojo::Collection->new(@children);
... ...
@@ -97,43 +94,31 @@ sub children {
97 94
 sub content_xml {
98 95
   my $self = shift;
99 96
 
100
-  # Walk tree
101
-  my $result = '';
102
-  my $tree   = $self->tree;
103
-  my $start  = $tree->[0] eq 'root' ? 1 : 4;
104
-  for my $e (@$tree[$start .. $#$tree]) {
105
-    $result .= Mojo::DOM::HTML->new(
106
-      charset => $self->charset,
107
-      tree    => $e,
108
-      xml     => $self->xml
109
-    )->render;
110
-  }
111
-
112
-  return $result;
97
+  # Render children
98
+  my $tree    = $self->tree;
99
+  my $charset = $self->charset;
100
+  my $xml     = $self->xml;
101
+  return join '', map {
102
+    Mojo::DOM::HTML->new(charset => $charset, tree => $_, xml => $xml)->render
103
+  } @$tree[($tree->[0] eq 'root' ? 1 : 4) .. $#$tree];
113 104
 }
114 105
 
115 106
 sub find {
116 107
   my ($self, $selector) = @_;
117 108
 
118
-  # Match selector against tree
119
-  my $results = Mojo::DOM::CSS->new(tree => $self->tree)->select($selector);
120
-
121
-  # Upgrade results
122
-  @$results
123
-    = map { $self->new->charset($self->charset)->tree($_)->xml($self->xml) }
124
-    @$results;
125
-
126
-  return Mojo::Collection->new(@$results);
109
+  my $charset = $self->charset;
110
+  my $xml     = $self->xml;
111
+  return Mojo::Collection->new(
112
+    map { $self->new->charset($charset)->tree($_)->xml($xml) }
113
+      @{Mojo::DOM::CSS->new(tree => $self->tree)->select($selector)});
127 114
 }
128 115
 
129 116
 sub namespace {
130 117
   my $self = shift;
131 118
 
132
-  # Namespace prefix
119
+  # Extract namespace prefix and search parents
133 120
   return '' if (my $current = $self->tree)->[0] eq 'root';
134 121
   my $ns = $current->[1] =~ /^(.*?):/ ? "xmlns:$1" : undef;
135
-
136
-  # Walk tree
137 122
   while ($current) {
138 123
     last if $current->[0] eq 'root';
139 124
 
... ...
@@ -155,11 +140,7 @@ sub next { shift->_sibling(1) }
155 140
 
156 141
 sub parent {
157 142
   my $self = shift;
158
-
159
-  # Not a tag
160 143
   return undef if (my $tree = $self->tree)->[0] eq 'root';
161
-
162
-  # Parent
163 144
   return $self->new->charset($self->charset)->tree($tree->[3])
164 145
     ->xml($self->xml);
165 146
 }
... ...
@@ -206,29 +187,15 @@ sub replace {
206 187
 
207 188
 sub replace_content {
208 189
   my ($self, $new) = @_;
209
-
210
-  # Parse
211
-  $new = $self->_parse("$new");
212
-
213
-  # Replacements
214 190
   my $tree = $self->tree;
215
-  my @new;
216
-  for my $e (@$new[1 .. $#$new]) {
217
-    $e->[3] = $tree if $e->[0] eq 'tag';
218
-    push @new, $e;
219
-  }
220
-
221
-  # Replace
222
-  my $start = $tree->[0] eq 'root' ? 1 : 4;
223
-  splice @$tree, $start, $#$tree, @new;
224
-
191
+  splice @$tree, $tree->[0] eq 'root' ? 1 : 4, $#$tree,
192
+    @{_parent($self->_parse("$new"), $tree)};
225 193
   return $self;
226 194
 }
227 195
 
228 196
 sub root {
229 197
   my $self = shift;
230 198
 
231
-  # Find root
232 199
   my $root = $self->tree;
233 200
   while ($root->[0] eq 'tag') {
234 201
     last unless my $parent = $root->[3];
... ...
@@ -277,7 +244,7 @@ sub text_before {
277 244
 
278 245
 sub to_xml { shift->[0]->render }
279 246
 
280
-sub tree { shift->_parser(tree => @_) }
247
+sub tree { shift->_html(tree => @_) }
281 248
 
282 249
 sub type {
283 250
   my ($self, $type) = @_;
... ...
@@ -292,18 +259,15 @@ sub type {
292 259
   return $self;
293 260
 }
294 261
 
295
-sub xml { shift->_parser(xml => @_) }
262
+sub xml { shift->_html(xml => @_) }
296 263
 
297 264
 sub _add {
298 265
   my ($self, $offset, $new) = @_;
299 266
 
300
-  # Parse
301
-  $new = $self->_parse("$new");
302
-
303 267
   # Not a tag
304 268
   return $self if (my $tree = $self->tree)->[0] eq 'root';
305 269
 
306
-  # Find
270
+  # Find parent
307 271
   my $parent = $tree->[3];
308 272
   my $i = $parent->[0] eq 'root' ? 1 : 4;
309 273
   for my $e (@$parent[$i .. $#$parent]) {
... ...
@@ -311,8 +275,8 @@ sub _add {
311 275
     $i++;
312 276
   }
313 277
 
314
-  # Add
315
-  splice @$parent, $i + $offset, 0, @{_parent($new, $parent)};
278
+  # Add children
279
+  splice @$parent, $i + $offset, 0, @{_parent($self->_parse("$new"), $parent)};
316 280
 
317 281
   return $self;
318 282
 }
... ...
@@ -322,8 +286,17 @@ sub _elements {
322 286
   return [@$e[($e->[0] eq 'root' ? 1 : 4) .. $#$e]];
323 287
 }
324 288
 
289
+sub _html {
290
+  my ($self, $method) = (shift, shift);
291
+  return $self->[0]->$method unless @_;
292
+  $self->[0]->$method(@_);
293
+  return $self;
294
+}
295
+
325 296
 sub _parent {
326 297
   my ($children, $parent) = @_;
298
+
299
+  # Link parent to children
327 300
   my @new;
328 301
   for my $e (@$children[1 .. $#$children]) {
329 302
     if ($e->[0] eq 'tag') {
... ...
@@ -332,6 +305,7 @@ sub _parent {
332 305
     }
333 306
     push @new, $e;
334 307
   }
308
+
335 309
   return \@new;
336 310
 }
337 311
 
... ...
@@ -341,17 +315,10 @@ sub _parse {
341 315
     ->parse(shift)->tree;
342 316
 }
343 317
 
344
-sub _parser {
345
-  my ($self, $method) = (shift, shift);
346
-  return $self->[0]->$method unless @_;
347
-  $self->[0]->$method(@_);
348
-  return $self;
349
-}
350
-
351 318
 sub _sibling {
352 319
   my ($self, $next) = @_;
353 320
 
354
-  # Root
321
+  # Make sure we have a parent
355 322
   return undef unless my $parent = $self->parent;
356 323
 
357 324
   # Find previous or next sibling
... ...
@@ -369,7 +336,6 @@ sub _sibling {
369 336
 sub _text {
370 337
   my ($elements, $recurse, $trim) = @_;
371 338
 
372
-  # Walk tree
373 339
   my $text = '';
374 340
   for my $e (@$elements) {
375 341
     my $type = $e->[0];
... ...
@@ -481,14 +447,14 @@ XML detection can also be disabled with the C<xml> method.
481 447
 L<Mojo::DOM> inherits all methods from L<Mojo::Base> and implements the
482 448
 following new ones.
483 449
 
484
-=head2 C<new>
450
+=head2 new
485 451
 
486 452
   my $dom = Mojo::DOM->new;
487 453
   my $dom = Mojo::DOM->new('<foo bar="baz">test</foo>');
488 454
 
489 455
 Construct a new array-based L<Mojo::DOM> object.
490 456
 
491
-=head2 C<all_text>
457
+=head2 all_text
492 458
 
493 459
   my $trimmed   = $dom->all_text;
494 460
   my $untrimmed = $dom->all_text(0);
... ...
@@ -502,7 +468,7 @@ enabled by default.
502 468
   # "foo\nbarbaz\n"
503 469
   $dom->parse("<div>foo\n<p>bar</p>baz\n</div>")->div->all_text(0);
504 470
 
505
-=head2 C<append>
471
+=head2 append
506 472
 
507 473
   $dom = $dom->append('<p>Hi!</p>');
508 474
 
... ...
@@ -511,7 +477,7 @@ Append to element.
511 477
   # "<div><h1>A</h1><h2>B</h2></div>"
512 478
   $dom->parse('<div><h1>A</h1></div>')->at('h1')->append('<h2>B</h2>')->root;
513 479
 
514
-=head2 C<append_content>
480
+=head2 append_content
515 481
 
516 482
   $dom = $dom->append_content('<p>Hi!</p>');
517 483
 
... ...
@@ -520,7 +486,7 @@ Append to element content.
520 486
   # "<div><h1>AB</h1></div>"
521 487
   $dom->parse('<div><h1>A</h1></div>')->at('h1')->append_content('B')->root;
522 488
 
523
-=head2 C<at>
489
+=head2 at
524 490
 
525 491
   my $result = $dom->at('html title');
526 492
 
... ...
@@ -530,7 +496,7 @@ are supported.
530 496
   # Find first element with "svg" namespace definition
531 497
   my $namespace = $dom->at('[xmlns\:svg]')->{'xmlns:svg'};
532 498
 
533
-=head2 C<attrs>
499
+=head2 attrs
534 500
 
535 501
   my $attrs = $dom->attrs;
536 502
   my $foo   = $dom->attrs('foo');
... ...
@@ -539,14 +505,14 @@ are supported.
539 505
 
540 506
 Element attributes.
541 507
 
542
-=head2 C<charset>
508
+=head2 charset
543 509
 
544 510
   my $charset = $dom->charset;
545 511
   $dom        = $dom->charset('UTF-8');
546 512
 
547 513
 Charset used for decoding and encoding HTML/XML.
548 514
 
549
-=head2 C<children>
515
+=head2 children
550 516
 
551 517
   my $collection = $dom->children;
552 518
   my $collection = $dom->children('div');
... ...
@@ -557,7 +523,7 @@ similar to C<find>.
557 523
   # Show type of random child element
558 524
   say $dom->children->shuffle->first->type;
559 525
 
560
-=head2 C<content_xml>
526
+=head2 content_xml
561 527
 
562 528
   my $xml = $dom->content_xml;
563 529
 
... ...
@@ -567,7 +533,7 @@ C<charset> has been defined.
567 533
   # "<b>test</b>"
568 534
   $dom->parse('<div><b>test</b></div>')->div->content_xml;
569 535
 
570
-=head2 C<find>
536
+=head2 find
571 537
 
572 538
   my $collection = $dom->find('html title');
573 539
 
... ...
@@ -580,7 +546,7 @@ selectors from L<Mojo::DOM::CSS> are supported.
580 546
   # Extract information from multiple elements
581 547
   my @headers = $dom->find('h1, h2, h3')->pluck('text')->each;
582 548
 
583
-=head2 C<namespace>
549
+=head2 namespace
584 550
 
585 551
   my $namespace = $dom->namespace;
586 552
 
... ...
@@ -592,7 +558,7 @@ Find element namespace.
592 558
   # Find namespace for an element that may or may not have a namespace prefix
593 559
   my $namespace = $dom->at('svg > circle')->namespace;
594 560
 
595
-=head2 C<next>
561
+=head2 next
596 562
 
597 563
   my $sibling = $dom->next;
598 564
 
... ...
@@ -601,13 +567,13 @@ Next sibling of element.
601 567
   # "<h2>B</h2>"
602 568
   $dom->parse('<div><h1>A</h1><h2>B</h2></div>')->at('h1')->next;
603 569
 
604
-=head2 C<parent>
570
+=head2 parent
605 571
 
606 572
   my $parent = $dom->parent;
607 573
 
608 574
 Parent of element.
609 575
 
610
-=head2 C<parse>
576
+=head2 parse
611 577
 
612 578
   $dom = $dom->parse('<foo bar="baz">test</foo>');
613 579
 
... ...
@@ -616,7 +582,7 @@ Parse HTML/XML document with L<Mojo::DOM::HTML>.
616 582
   # Parse UTF-8 encoded XML
617 583
   my $dom = Mojo::DOM->new->charset('UTF-8')->xml(1)->parse($xml);
618 584
 
619
-=head2 C<prepend>
585
+=head2 prepend
620 586
 
621 587
   $dom = $dom->prepend('<p>Hi!</p>');
622 588
 
... ...
@@ -625,7 +591,7 @@ Prepend to element.
625 591
   # "<div><h1>A</h1><h2>B</h2></div>"
626 592
   $dom->parse('<div><h2>B</h2></div>')->at('h2')->prepend('<h1>A</h1>')->root;
627 593
 
628
-=head2 C<prepend_content>
594
+=head2 prepend_content
629 595
 
630 596
   $dom = $dom->prepend_content('<p>Hi!</p>');
631 597
 
... ...
@@ -634,7 +600,7 @@ Prepend to element content.
634 600
   # "<div><h2>AB</h2></div>"
635 601
   $dom->parse('<div><h2>B</h2></div>')->at('h2')->prepend_content('A')->root;
636 602
 
637
-=head2 C<previous>
603
+=head2 previous
638 604
 
639 605
   my $sibling = $dom->previous;
640 606
 
... ...
@@ -643,7 +609,7 @@ Previous sibling of element.
643 609
   # "<h1>A</h1>"
644 610
   $dom->parse('<div><h1>A</h1><h2>B</h2></div>')->at('h2')->previous;
645 611
 
646
-=head2 C<remove>
612
+=head2 remove
647 613
 
648 614
   my $old = $dom->remove;
649 615
 
... ...
@@ -652,7 +618,7 @@ Remove element.
652 618
   # "<div></div>"
653 619
   $dom->parse('<div><h1>A</h1></div>')->at('h1')->remove->root;
654 620
 
655
-=head2 C<replace>
621
+=head2 replace
656 622
 
657 623
   my $old = $dom->replace('<div>test</div>');
658 624
 
... ...
@@ -664,7 +630,7 @@ Replace element.
664 630
   # "<div></div>"
665 631
   $dom->parse('<div><h1>A</h1></div>')->at('h1')->replace('')->root;
666 632
 
667
-=head2 C<replace_content>
633
+=head2 replace_content
668 634
 
669 635
   $dom = $dom->replace_content('test');
670 636
 
... ...
@@ -676,13 +642,13 @@ Replace element content.
676 642
   # "<div><h1></h1></div>"
677 643
   $dom->parse('<div><h1>A</h1></div>')->at('h1')->replace_content('')->root;
678 644
 
679
-=head2 C<root>
645
+=head2 root
680 646
 
681 647
   my $root = $dom->root;
682 648
 
683 649
 Find root node.
684 650
 
685
-=head2 C<text>
651
+=head2 text
686 652
 
687 653
   my $trimmed   = $dom->text;
688 654
   my $untrimmed = $dom->text(0);
... ...
@@ -696,7 +662,7 @@ whitespace trimming is enabled by default.
696 662
   # "foo\nbaz\n"
697 663
   $dom->parse("<div>foo\n<p>bar</p>baz\n</div>")->div->text(0);
698 664
 
699
-=head2 C<text_after>
665
+=head2 text_after
700 666
 
701 667
   my $trimmed   = $dom->text_after;
702 668
   my $untrimmed = $dom->text_after(0);
... ...
@@ -710,7 +676,7 @@ is enabled by default.
710 676
   # "baz\n"
711 677
   $dom->parse("<div>foo\n<p>bar</p>baz\n</div>")->div->p->text_after(0);
712 678
 
713
-=head2 C<text_before>
679
+=head2 text_before
714 680
 
715 681
   my $trimmed   = $dom->text_before;
716 682
   my $untrimmed = $dom->text_before(0);
... ...
@@ -724,7 +690,7 @@ is enabled by default.
724 690
   # "foo\n"
725 691
   $dom->parse("<div>foo\n<p>bar</p>baz\n</div>")->div->p->text_before(0);
726 692
 
727
-=head2 C<to_xml>
693
+=head2 to_xml
728 694
 
729 695
   my $xml = $dom->to_xml;
730 696
   my $xml = "$dom";
... ...
@@ -735,14 +701,14 @@ if a C<charset> has been defined.
735 701
   # "<b>test</b>"
736 702
   $dom->parse('<div><b>test</b></div>')->div->b->to_xml;
737 703
 
738
-=head2 C<tree>
704
+=head2 tree
739 705
 
740 706
   my $tree = $dom->tree;
741 707
   $dom     = $dom->tree(['root', [qw(text lalala)]]);
742 708
 
743 709
 Document Object Model.
744 710
 
745
-=head2 C<type>
711
+=head2 type
746 712
 
747 713
   my $type = $dom->type;
748 714
   $dom     = $dom->type('div');
... ...
@@ -752,7 +718,7 @@ Element type.
752 718
   # List types of child elements
753 719
   say $dom->children->pluck('type');
754 720
 
755
-=head2 C<xml>
721
+=head2 xml
756 722
 
757 723
   my $xml = $dom->xml;
758 724
   $dom    = $dom->xml(1);
+35 -41
mojolegacy/lib/Mojo/DOM/CSS.pm
... ...
@@ -36,13 +36,10 @@ my $TOKEN_RE        = qr/
36 36
 sub select {
37 37
   my $self = shift;
38 38
 
39
-  # Compile selectors
40
-  my $pattern = $self->_compile(shift);
41
-
42
-  # Walk tree
43 39
   my @results;
44
-  my $tree  = $self->tree;
45
-  my @queue = ($tree);
40
+  my $pattern = $self->_compile(shift);
41
+  my $tree    = $self->tree;
42
+  my @queue   = ($tree);
46 43
   while (my $current = shift @queue) {
47 44
     my $type = $current->[0];
48 45
 
... ...
@@ -123,7 +120,6 @@ sub _combinator {
123 120
 sub _compile {
124 121
   my ($self, $css) = @_;
125 122
 
126
-  # Tokenize
127 123
   my $pattern = [[]];
128 124
   while ($css =~ /$TOKEN_RE/g) {
129 125
     my ($separator, $element, $pc, $attrs, $combinator)
... ...
@@ -321,7 +317,6 @@ sub _regex {
321 317
 sub _selector {
322 318
   my ($self, $selector, $current) = @_;
323 319
 
324
-  # Selectors
325 320
   for my $s (@$selector[1 .. $#$selector]) {
326 321
     my $type = $s->[0];
327 322
 
... ...
@@ -348,7 +343,6 @@ sub _selector {
348 343
 sub _sibling {
349 344
   my ($self, $selectors, $current, $tree, $immediate) = @_;
350 345
 
351
-  # Find preceding elements
352 346
   my $parent = $current->[3];
353 347
   my $found;
354 348
   my $start = $parent->[0] eq 'root' ? 1 : 4;
... ...
@@ -403,77 +397,77 @@ L<Mojo::DOM::CSS> is the CSS selector engine used by L<Mojo::DOM>.
403 397
 
404 398
 All CSS selectors that make sense for a standalone parser are supported.
405 399
 
406
-=head2 C<*>
400
+=head2 *
407 401
 
408 402
 Any element.
409 403
 
410 404
   my $all = $css->select('*');
411 405
 
412
-=head2 C<E>
406
+=head2 E
413 407
 
414 408
 An element of type C<E>.
415 409
 
416 410
   my $title = $css->select('title');
417 411
 
418
-=head2 C<E[foo]>
412
+=head2 E[foo]
419 413
 
420 414
 An C<E> element with a C<foo> attribute.
421 415
 
422 416
   my $links = $css->select('a[href]');
423 417
 
424
-=head2 C<E[foo="bar"]>
418
+=head2 E[foo="bar"]
425 419
 
426 420
 An C<E> element whose C<foo> attribute value is exactly equal to C<bar>.
427 421
 
428 422
   my $fields = $css->select('input[name="foo"]');
429 423
 
430
-=head2 C<E[foo~="bar"]>
424
+=head2 E[foo~="bar"]
431 425
 
432 426
 An C<E> element whose C<foo> attribute value is a list of
433 427
 whitespace-separated values, one of which is exactly equal to C<bar>.
434 428
 
435 429
   my $fields = $css->select('input[name~="foo"]');
436 430
 
437
-=head2 C<E[foo^="bar"]>
431
+=head2 E[foo^="bar"]
438 432
 
439 433
 An C<E> element whose C<foo> attribute value begins exactly with the string
440 434
 C<bar>.
441 435
 
442 436
   my $fields = $css->select('input[name^="f"]');
443 437
 
444
-=head2 C<E[foo$="bar"]>
438
+=head2 E[foo$="bar"]
445 439
 
446 440
 An C<E> element whose C<foo> attribute value ends exactly with the string
447 441
 C<bar>.
448 442
 
449 443
   my $fields = $css->select('input[name$="o"]');
450 444
 
451
-=head2 C<E[foo*="bar"]>
445
+=head2 E[foo*="bar"]
452 446
 
453 447
 An C<E> element whose C<foo> attribute value contains the substring C<bar>.
454 448
 
455 449
   my $fields = $css->select('input[name*="fo"]');
456 450
 
457
-=head2 C<E:root>
451
+=head2 E:root
458 452
 
459 453
 An C<E> element, root of the document.
460 454
 
461 455
   my $root = $css->select(':root');
462 456
 
463
-=head2 C<E:checked>
457
+=head2 E:checked
464 458
 
465 459
 A user interface element C<E> which is checked (for instance a radio-button or
466 460
 checkbox).
467 461
 
468 462
   my $input = $css->select(':checked');
469 463
 
470
-=head2 C<E:empty>
464
+=head2 E:empty
471 465
 
472 466
 An C<E> element that has no children (including text nodes).
473 467
 
474 468
   my $empty = $css->select(':empty');
475 469
 
476
-=head2 C<E:nth-child(n)>
470
+=head2 E:nth-child(n)
477 471
 
478 472
 An C<E> element, the C<n-th> child of its parent.
479 473
 
... ...
@@ -482,7 +476,7 @@ An C<E> element, the C<n-th> child of its parent.
482 476
   my $even  = $css->select('div:nth-child(even)');
483 477
   my $top3  = $css->select('div:nth-child(-n+3)');
484 478
 
485
-=head2 C<E:nth-last-child(n)>
479
+=head2 E:nth-last-child(n)
486 480
 
487 481
 An C<E> element, the C<n-th> child of its parent, counting from the last one.
488 482
 
... ...
@@ -491,7 +485,7 @@ An C<E> element, the C<n-th> child of its parent, counting from the last one.
491 485
   my $even     = $css->select('div:nth-last-child(even)');
492 486
   my $bottom3  = $css->select('div:nth-last-child(-n+3)');
493 487
 
494
-=head2 C<E:nth-of-type(n)>
488
+=head2 E:nth-of-type(n)
495 489
 
496 490
 An C<E> element, the C<n-th> sibling of its type.
497 491
 
... ...
@@ -500,7 +494,7 @@ An C<E> element, the C<n-th> sibling of its type.
500 494
   my $even  = $css->select('div:nth-of-type(even)');
501 495
   my $top3  = $css->select('div:nth-of-type(-n+3)');
502 496
 
503
-=head2 C<E:nth-last-of-type(n)>
497
+=head2 E:nth-last-of-type(n)
504 498
 
505 499
 An C<E> element, the C<n-th> sibling of its type, counting from the last one.
506 500
 
... ...
@@ -509,91 +503,91 @@ An C<E> element, the C<n-th> sibling of its type, counting from the last one.
509 503
   my $even     = $css->select('div:nth-last-of-type(even)');
510 504
   my $bottom3  = $css->select('div:nth-last-of-type(-n+3)');
511 505
 
512
-=head2 C<E:first-child>
506
+=head2 E:first-child
513 507
 
514 508
 An C<E> element, first child of its parent.
515 509
 
516 510
   my $first = $css->select('div p:first-child');
517 511
 
518
-=head2 C<E:last-child>
512
+=head2 E:last-child
519 513
 
520 514
 An C<E> element, last child of its parent.
521 515
 
522 516
   my $last = $css->select('div p:last-child');
523 517
 
524
-=head2 C<E:first-of-type>
518
+=head2 E:first-of-type
525 519
 
526 520
 An C<E> element, first sibling of its type.
527 521
 
528 522
   my $first = $css->select('div p:first-of-type');
529 523
 
530
-=head2 C<E:last-of-type>
524
+=head2 E:last-of-type
531 525
 
532 526
 An C<E> element, last sibling of its type.
533 527
 
534 528
   my $last = $css->select('div p:last-of-type');
535 529
 
536
-=head2 C<E:only-child>
530
+=head2 E:only-child
537 531
 
538 532
 An C<E> element, only child of its parent.
539 533
 
540 534
   my $lonely = $css->select('div p:only-child');
541 535
 
542
-=head2 C<E:only-of-type>
536
+=head2 E:only-of-type
543 537
 
544 538
 An C<E> element, only sibling of its type.
545 539
 
546 540
   my $lonely = $css->select('div p:only-of-type');
547 541
 
548
-=head2 C<E.warning>
542
+=head2 E.warning
549 543
 
550 544
   my $warning = $css->select('div.warning');
551 545
 
552 546
 An C<E> element whose class is "warning".
553 547
 
554
-=head2 C<E#myid>
548
+=head2 E#myid
555 549
 
556 550
   my $foo = $css->select('div#foo');
557 551
 
558 552
 An C<E> element with C<ID> equal to "myid".
559 553
 
560
-=head2 C<E:not(s)>
554
+=head2 E:not(s)
561 555
 
562 556
 An C<E> element that does not match simple selector C<s>.
563 557
 
564 558
   my $others = $css->select('div p:not(:first-child)');
565 559
 
566
-=head2 C<E F>
560
+=head2 E F
567 561
 
568 562
 An C<F> element descendant of an C<E> element.
569 563
 
570 564
   my $headlines = $css->select('div h1');
571 565
 
572
-=head2 C<E E<gt> F>
566
+=head2 E E<gt> F
573 567
 
574 568
 An C<F> element child of an C<E> element.
575 569
 
576 570
   my $headlines = $css->select('html > body > div > h1');
577 571
 
578
-=head2 C<E + F>
572
+=head2 E + F
579 573
 
580 574
 An C<F> element immediately preceded by an C<E> element.
581 575
 
582 576
   my $second = $css->select('h1 + h2');
583 577
 
584
-=head2 C<E ~ F>
578
+=head2 E ~ F
585 579
 
586 580
 An C<F> element preceded by an C<E> element.
587 581
 
588 582
   my $second = $css->select('h1 ~ h2');
589 583
 
590
-=head2 C<E, F, G>
584
+=head2 E, F, G
591 585
 
592 586
 Elements of type C<E>, C<F> and C<G>.
593 587
 
594 588
   my $headlines = $css->select('h1, h2, h3');
595 589
 
596
-=head2 C<E[foo=bar][bar=baz]>
590
+=head2 E[foo=bar][bar=baz]
597 591
 
598 592
 An C<E> element whose attributes match all following attribute selectors.
599 593
 
... ...
@@ -603,7 +597,7 @@ An C<E> element whose attributes match all following attribute selectors.
603 597
 
604 598
 L<Mojo::DOM::CSS> implements the following attributes.
605 599
 
606
-=head2 C<tree>
600
+=head2 tree
607 601
 
608 602
   my $tree = $css->tree;
609 603
   $css     = $css->tree(['root', [qw(text lalala)]]);
... ...
@@ -615,7 +609,7 @@ Document Object Model.
615 609
 L<Mojo::DOM::CSS> inherits all methods from L<Mojo::Base> and implements the
616 610
 following new ones.
617 611
 
618
-=head2 C<select>
612
+=head2 select
619 613
 
620 614
   my $results = $css->select('head > title');
621 615
 
+8 -14
mojolegacy/lib/Mojo/DOM/HTML.pm
... ...
@@ -76,11 +76,9 @@ my %INLINE = map { $_ => 1 } (
76 76
 sub parse {
77 77
   my ($self, $html) = @_;
78 78
 
79
-  # Try to decode
80 79
   my $charset = $self->charset;
81 80
   defined ($html = decode($charset, $html)) || return $self->charset(undef) if $charset;
82 81
 
83
-  # Tokenize
84 82
   my $tree    = ['root'];
85 83
   my $current = $tree;
86 84
   while ($html =~ m/\G$TOKEN_RE/gcs) {
... ...
@@ -269,14 +267,10 @@ sub _render {
269 267
   # Processing instruction
270 268
   return "<?" . $tree->[1] . "?>" if $e eq 'pi';
271 269
 
272
-  # Offset
273
-  my $start = $e eq 'root' ? 1 : 2;
274
-
275 270
   # Start tag
271
+  my $start = $e eq 'root' ? 1 : 2;
276 272
   my $content = '';
277 273
   if ($e eq 'tag') {
278
-
279
-    # Offset
280 274
     $start = 4;
281 275
 
282 276
     # Open tag
... ...
@@ -305,7 +299,7 @@ sub _render {
305 299
     $content .= '>';
306 300
   }
307 301
 
308
-  # Walk tree
302
+  # Render whole tree
309 303
   $content .= $self->_render($tree->[$_]) for $start .. $#$tree;
310 304
 
311 305
   # End tag
... ...
@@ -362,7 +356,7 @@ sub _start {
362 356
     }
363 357
   }
364 358
 
365
-  # New
359
+  # New tag
366 360
   my $new = ['tag', $start, $attrs, $$current];
367 361
   weaken $new->[3];
368 362
   push @$$current, $new;
... ...
@@ -397,21 +391,21 @@ L<Mojo::DOM::HTML> is the HTML/XML engine used by L<Mojo::DOM>.
397 391
 
398 392
 L<Mojo::DOM::HTML> implements the following attributes.
399 393
 
400
-=head2 C<charset>
394
+=head2 charset
401 395
 
402 396
   my $charset = $html->charset;
403 397
   $html       = $html->charset('UTF-8');
404 398
 
405 399
 Charset used for decoding and encoding HTML/XML.
406 400
 
407
-=head2 C<tree>
401
+=head2 tree
408 402
 
409 403
   my $tree = $html->tree;
410 404
   $html    = $html->tree(['root', [qw(text lalala)]]);
411 405
 
412 406
 Document Object Model.
413 407
 
414
-=head2 C<xml>
408
+=head2 xml
415 409
 
416 410
   my $xml = $html->xml;
417 411
   $html   = $html->xml(1);
... ...
@@ -424,13 +418,13 @@ auto detection based on processing instructions.
424 418
 L<Mojo::DOM::HTML> inherits all methods from L<Mojo::Base> and implements the
425 419
 following new ones.
426 420
 
427
-=head2 C<parse>
421
+=head2 parse
428 422
 
429 423
   $html = $html->parse('<foo bar="baz">test</foo>');
430 424
 
431 425
 Parse HTML/XML document.
432 426
 
433
-=head2 C<render>
427
+=head2 render
434 428
 
435 429
   my $xml = $html->render;
436 430
 
+4 -5
mojolegacy/lib/Mojo/Date.pm
... ...
@@ -9,7 +9,6 @@ use Time::Local 'timegm';
9 9
 
10 10
 has 'epoch';
11 11
 
12
-# Days and months
13 12
 my @DAYS   = qw(Sun Mon Tue Wed Thu Fri Sat);
14 13
 my @MONTHS = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
15 14
 my %MONTHS;
... ...
@@ -93,7 +92,7 @@ L<Mojo::Date> implements HTTP date and time functions as described in RFC
93 92
 
94 93
 L<Mojo::Date> implements the following attributes.
95 94
 
96
-=head2 C<epoch>
95
+=head2 epoch
97 96
 
98 97
   my $epoch = $date->epoch;
99 98
   $date     = $date->epoch(784111777);
... ...
@@ -105,14 +104,14 @@ Epoch seconds.
105 104
 L<Mojo::Date> inherits all methods from L<Mojo::Base> and implements the
106 105
 following new ones.
107 106
 
108
-=head2 C<new>
107
+=head2 new
109 108
 
110 109
   my $date = Mojo::Date->new;
111 110
   my $date = Mojo::Date->new('Sun Nov  6 08:49:37 1994');
112 111
 
113 112
 Construct a new L<Mojo::Date> object.
114 113
 
115
-=head2 C<parse>
114
+=head2 parse
116 115
 
117 116
   $date = $date->parse('Sun Nov  6 08:49:37 1994');
118 117
 
... ...
@@ -130,7 +129,7 @@ Parse date.
130 129
   # Ansi C asctime()
131 130
   say Mojo::Date->new('Sun Nov  6 08:49:37 1994')->epoch;
132 131
 
133
-=head2 C<to_string>
132
+=head2 to_string
134 133
 
135 134
   my $string = $date->to_string;
136 135
   my $string = "$date";
+34 -14
mojolegacy/lib/Mojo/EventEmitter.pm
... ...
@@ -12,7 +12,10 @@ sub emit {
12 12
     warn "-- Emit $name in @{[blessed($self)]} (@{[scalar(@$s)]})\n" if DEBUG;
13 13
     for my $cb (@$s) { $self->$cb(@_) }
14 14
   }
15
-  elsif (DEBUG) { warn "-- Emit $name in @{[blessed($self)]} (0)\n" }
15
+  else {
16
+    warn "-- Emit $name in @{[blessed($self)]} (0)\n" if DEBUG;
17
+    warn $_[0] if $name eq 'error';
18
+  }
16 19
 
17 20
   return $self;
18 21
 }
... ...
@@ -30,15 +33,14 @@ sub emit_safe {
30 33
         if ($name eq 'error') { warn qq{Event "error" failed: $@} }
31 34
 
32 35
         # Normal event failed
33
-        else {
34
-          $self->once(error => sub { warn $_[1] })
35
-            unless $self->has_subscribers('error');
36
-          $self->emit_safe('error', qq{Event "$name" failed: $@});
37
-        }
36
+        else { $self->emit_safe('error', qq{Event "$name" failed: $@}) }
38 37
       }
39 38
     }
40 39
   }
41
-  elsif (DEBUG) { warn "-- Emit $name in @{[blessed($self)]} safely (0)\n" }
40
+  else {
41
+    warn "-- Emit $name in @{[blessed($self)]} safely (0)\n" if DEBUG;
42
+    warn $_[0] if $name eq 'error';
43
+  }
42 44
 
43 45
   return $self;
44 46
 }
... ...
@@ -113,32 +115,50 @@ Mojo::EventEmitter - Event emitter base class
113 115
 
114 116
 L<Mojo::EventEmitter> is a simple base class for event emitting objects.
115 117
 
118
+=head1 EVENTS
119
+
120
+L<Mojo::EventEmitter> can emit the following events.
121
+
122
+=head2 error
123
+
124
+  $e->on(error => sub {
125
+    my ($e, $err) = @_;
126
+    ...
127
+  });
128
+
129
+Emitted safely for event errors.
130
+
131
+  $e->on(error => sub {
132
+    my ($e, $err) = @_;
133
+    say "This looks bad: $err";
134
+  });
135
+
116 136
 =head1 METHODS
117 137
 
118 138
 L<Mojo::EventEmitter> inherits all methods from L<Mojo::Base> and
119 139
 implements the following new ones.
120 140
 
121
-=head2 C<emit>
141
+=head2 emit
122 142
 
123 143
   $e = $e->emit('foo');
124 144
   $e = $e->emit('foo', 123);
125 145
 
126 146
 Emit event.
127 147
 
128
-=head2 C<emit_safe>
148
+=head2 emit_safe
129 149
 
130 150
   $e = $e->emit_safe('foo');
131 151
   $e = $e->emit_safe('foo', 123);
132 152
 
133 153
 Emit event safely and emit C<error> event on failure.
134 154
 
135
-=head2 C<has_subscribers>
155
+=head2 has_subscribers
136 156
 
137 157
   my $success = $e->has_subscribers('foo');
138 158
 
139 159
 Check if event has subscribers.
140 160
 
141
-=head2 C<on>
161
+=head2 on
142 162
 
143 163
   my $cb = $e->on(foo => sub {...});
144 164
 
... ...
@@ -149,7 +169,7 @@ Subscribe to event.
149 169
     ...
150 170
   });
151 171
 
152
-=head2 C<once>
172
+=head2 once
153 173
 
154 174
   my $cb = $e->once(foo => sub {...});
155 175
 
... ...
@@ -160,7 +180,7 @@ Subscribe to event and unsubscribe again after it has been emitted once.
160 180
     ...
161 181
   });
162 182
 
163
-=head2 C<subscribers>
183
+=head2 subscribers
164 184
 
165 185
   my $subscribers = $e->subscribers('foo');
166 186
 
... ...
@@ -169,7 +189,7 @@ All subscribers for event.
169 189
   # Unsubscribe last subscriber
170 190
   $e->unsubscribe(foo => $e->subscribers('foo')->[-1]);
171 191
 
172
-=head2 C<unsubscribe>
192
+=head2 unsubscribe
173 193
 
174 194
   $e = $e->unsubscribe('foo');
175 195
   $e = $e->unsubscribe(foo => $cb);
+12 -20
mojolegacy/lib/Mojo/Exception.pm
... ...
@@ -16,18 +16,11 @@ sub new {
16 16
   return @_ ? $self->_detect(@_) : $self;
17 17
 }
18 18
 
19
-# DEPRECATED in Rainbow!
20
-sub raw_message {
21
-  warn "Mojo::Exception->raw_message has been DEPRECATED!\n";
22
-  shift->message(@_);
23
-}
24
-
25 19
 sub throw { die shift->new->trace(2)->_detect(@_) }
26 20
 
27 21
 sub to_string {
28 22
   my $self = shift;
29 23
 
30
-  # Message
31 24
   return $self->message unless $self->verbose;
32 25
   my $string = $self->message ? $self->message : '';
33 26
 
... ...
@@ -94,7 +87,6 @@ sub _context {
94 87
 sub _detect {
95 88
   my ($self, $msg, $files) = @_;
96 89
 
97
-  # Message
98 90
   return $msg if blessed $msg && $msg->isa('Mojo::Exception');
99 91
   $self->message($msg);
100 92
 
... ...
@@ -144,76 +136,76 @@ L<Mojo::Exception> is a container for exceptions with context information.
144 136
 
145 137
 L<Mojo::Exception> implements the following attributes.
146 138
 
147
-=head2 C<frames>
139
+=head2 frames
148 140
 
149 141
   my $frames = $e->frames;
150 142
   $e         = $e->frames($frames);
151 143
 
152 144
 Stacktrace.
153 145
 
154
-=head2 C<line>
146
+=head2 line
155 147
 
156 148
   my $line = $e->line;
157 149
   $e       = $e->line([3 => 'foo']);
158 150
 
159 151
 The line where the exception occured.
160 152
 
161
-=head2 C<lines_after>
153
+=head2 lines_after
162 154
 
163 155
   my $lines = $e->lines_after;
164 156
   $e        = $e->lines_after([[1 => 'bar'], [2 => 'baz']]);
165 157
 
166 158
 Lines after the line where the exception occured.
167 159
 
168
-=head2 C<lines_before>
160
+=head2 lines_before
169 161
 
170 162
   my $lines = $e->lines_before;
171 163
   $e        = $e->lines_before([[4 => 'bar'], [5 => 'baz']]);
172 164
 
173 165
 Lines before the line where the exception occured.
174 166
 
175
-=head2 C<message>
167
+=head2 message
176 168
 
177 169
   my $msg = $e->message;
178 170
   $e      = $e->message('Oops!');
179 171
 
180 172
 Exception message.
181 173
 
182
-=head2 C<verbose>
174
+=head2 verbose
183 175
 
184 176
   my $verbose = $e->verbose;
185 177
   $e          = $e->verbose(1);
186 178
 
187
-Activate verbose rendering, defaults to the value of
188
-C<MOJO_EXCEPTION_VERBOSE> or C<0>.
179
+Activate verbose rendering, defaults to the value of the
180
+C<MOJO_EXCEPTION_VERBOSE> environment variable or C<0>.
189 181
 
190 182
 =head1 METHODS
191 183
 
192 184
 L<Mojo::Exception> inherits all methods from L<Mojo::Base> and implements the
193 185
 following new ones.
194 186
 
195
-=head2 C<new>
187
+=head2 new
196 188
 
197 189
   my $e = Mojo::Exception->new('Oops!');
198 190
   my $e = Mojo::Exception->new('Oops!', $files);
199 191
 
200 192
 Construct a new L<Mojo::Exception> object.
201 193
 
202
-=head2 C<throw>
194
+=head2 throw
203 195
 
204 196
   Mojo::Exception->throw('Oops!');
205 197
   Mojo::Exception->throw('Oops!', $files);
206 198
 
207 199
 Throw exception with stacktrace.
208 200
 
209
-=head2 C<to_string>
201
+=head2 to_string
210 202
 
211 203
   my $string = $e->to_string;
212 204
   my $string = "$e";
213 205
 
214 206
 Render exception.
215 207
 
216
-=head2 C<trace>
208
+=head2 trace
217 209
 
218 210
   $e = $e->trace;
219 211
   $e = $e->trace(2);
+58 -61
mojolegacy/lib/Mojo/Headers.pm
... ...
@@ -89,7 +89,6 @@ sub names {
89 89
 sub parse {
90 90
   my $self = shift;
91 91
 
92
-  # Parse headers with size limit
93 92
   $self->{state} = 'headers';
94 93
   $self->{buffer} .= do {my $buffer = shift; defined $buffer ? $buffer : ''};
95 94
   my $headers = $self->{cache} ||= [];
... ...
@@ -134,7 +133,6 @@ sub remove {
134 133
 sub to_hash {
135 134
   my ($self, $multi) = @_;
136 135
 
137
-  # Build
138 136
   my %hash;
139 137
   for my $header (@{$self->names}) {
140 138
     my @headers = $self->header($header);
... ...
@@ -163,7 +161,6 @@ sub to_string {
163 161
     push @headers, "$name: " . join("\x0d\x0a ", @$_) for $self->header($name);
164 162
   }
165 163
 
166
-  # Format headers
167 164
   return join "\x0d\x0a", @headers;
168 165
 }
169 166
 
... ...
@@ -179,8 +176,8 @@ Mojo::Headers - Headers
179 176
 
180 177
   # Parse
181 178
   my $headers = Mojo::Headers->new;
182
-  $headers->parse("Content-Length: 42\r\n");
183
-  $headers->parse("Content-Type: text/html\r\n\r\n");
179
+  $headers->parse("Content-Length: 42\x0d\x0a");
180
+  $headers->parse("Content-Type: text/html\x0d\x0a\x0d\x0a");
184 181
   say $headers->content_length;
185 182
   say $headers->content_type;
186 183
 
... ...
@@ -198,7 +195,7 @@ L<Mojo::Headers> is a container for HTTP headers as described in RFC 2616.
198 195
 
199 196
 L<Mojo::Headers> implements the following attributes.
200 197
 
201
-=head2 C<max_line_size>
198
+=head2 max_line_size
202 199
 
203 200
   my $size = $headers->max_line_size;
204 201
   $headers = $headers->max_line_size(1024);
... ...
@@ -211,124 +208,124 @@ C<MOJO_MAX_LINE_SIZE> environment variable or C<10240>.
211 208
 L<Mojo::Headers> inherits all methods from L<Mojo::Base> and implements the
212 209
 following new ones.
213 210
 
214
-=head2 C<accept>
211
+=head2 accept
215 212
 
216 213
   my $accept = $headers->accept;
217 214
   $headers   = $headers->accept('application/json');
218 215
 
219 216
 Shortcut for the C<Accept> header.
220 217
 
221
-=head2 C<accept_charset>
218
+=head2 accept_charset
222 219
 
223 220
   my $charset = $headers->accept_charset;
224 221
   $headers    = $headers->accept_charset('UTF-8');
225 222
 
226 223
 Shortcut for the C<Accept-Charset> header.
227 224
 
228
-=head2 C<accept_encoding>
225
+=head2 accept_encoding
229 226
 
230 227
   my $encoding = $headers->accept_encoding;
231 228
   $headers     = $headers->accept_encoding('gzip');
232 229
 
233 230
 Shortcut for the C<Accept-Encoding> header.
234 231
 
235
-=head2 C<accept_language>
232
+=head2 accept_language
236 233
 
237 234
   my $language = $headers->accept_language;
238 235
   $headers     = $headers->accept_language('de, en');
239 236
 
240 237
 Shortcut for the C<Accept-Language> header.
241 238
 
242
-=head2 C<accept_ranges>
239
+=head2 accept_ranges
243 240
 
244 241
   my $ranges = $headers->accept_ranges;
245 242
   $headers   = $headers->accept_ranges('bytes');
246 243
 
247 244
 Shortcut for the C<Accept-Ranges> header.
248 245
 
249
-=head2 C<add>
246
+=head2 add
250 247
 
251 248
   $headers = $headers->add('Content-Type', 'text/plain');
252 249
 
253 250
 Add one or more header lines.
254 251
 
255
-=head2 C<authorization>
252
+=head2 authorization
256 253
 
257 254
   my $authorization = $headers->authorization;
258 255
   $headers          = $headers->authorization('Basic Zm9vOmJhcg==');
259 256
 
260 257
 Shortcut for the C<Authorization> header.
261 258
 
262
-=head2 C<cache_control>
259
+=head2 cache_control
263 260
 
264 261
   my $cache_control = $headers->cache_control;
265 262
   $headers          = $headers->cache_control('max-age=1, no-cache');
266 263
 
267 264
 Shortcut for the C<Cache-Control> header.
268 265
 
269
-=head2 C<clone>
266
+=head2 clone
270 267
 
271 268
   my $clone = $headers->clone;
272 269
 
273 270
 Clone headers.
274 271
 
275
-=head2 C<connection>
272
+=head2 connection
276 273
 
277 274
   my $connection = $headers->connection;
278 275
   $headers       = $headers->connection('close');
279 276
 
280 277
 Shortcut for the C<Connection> header.
281 278
 
282
-=head2 C<content_disposition>
279
+=head2 content_disposition
283 280
 
284 281
   my $disposition = $headers->content_disposition;
285 282
   $headers        = $headers->content_disposition('foo');
286 283
 
287 284
 Shortcut for the C<Content-Disposition> header.
288 285
 
289
-=head2 C<content_encoding>
286
+=head2 content_encoding
290 287
 
291 288
   my $encoding = $headers->content_encoding;
292 289
   $headers     = $headers->content_encoding('gzip');
293 290
 
294 291
 Shortcut for the C<Content-Encoding> header.
295 292
 
296
-=head2 C<content_length>
293
+=head2 content_length
297 294
 
298 295
   my $len  = $headers->content_length;
299 296
   $headers = $headers->content_length(4000);
300 297
 
301 298
 Shortcut for the C<Content-Length> header.
302 299
 
303
-=head2 C<content_range>
300
+=head2 content_range
304 301
 
305 302
   my $range = $headers->content_range;
306 303
   $headers  = $headers->content_range('bytes 2-8/100');
307 304
 
308 305
 Shortcut for the C<Content-Range> header.
309 306
 
310
-=head2 C<content_type>
307
+=head2 content_type
311 308
 
312 309
   my $type = $headers->content_type;
313 310
   $headers = $headers->content_type('text/plain');
314 311
 
315 312
 Shortcut for the C<Content-Type> header.
316 313
 
317
-=head2 C<cookie>
314
+=head2 cookie
318 315
 
319 316
   my $cookie = $headers->cookie;
320 317
   $headers   = $headers->cookie('f=b');
321 318
 
322 319
 Shortcut for the C<Cookie> header from RFC 6265.
323 320
 
324
-=head2 C<date>
321
+=head2 date
325 322
 
326 323
   my $date = $headers->date;
327 324
   $headers = $headers->date('Sun, 17 Aug 2008 16:27:35 GMT');
328 325
 
329 326
 Shortcut for the C<Date> header.
330 327
 
331
-=head2 C<dnt>
328
+=head2 dnt
332 329
 
333 330
   my $dnt  = $headers->dnt;
334 331
   $headers = $headers->dnt(1);
... ...
@@ -336,35 +333,35 @@ Shortcut for the C<Date> header.
336 333
 Shortcut for the C<DNT> (Do Not Track) header, which has no specification yet,
337 334
 but is very commonly used.
338 335
 
339
-=head2 C<etag>
336
+=head2 etag
340 337
 
341 338
   my $etag = $headers->etag;
342 339
   $headers = $headers->etag('abc321');
343 340
 
344 341
 Shortcut for the C<ETag> header.
345 342
 
346
-=head2 C<expect>
343
+=head2 expect
347 344
 
348 345
   my $expect = $headers->expect;
349 346
   $headers   = $headers->expect('100-continue');
350 347
 
351 348
 Shortcut for the C<Expect> header.
352 349
 
353
-=head2 C<expires>
350
+=head2 expires
354 351
 
355 352
   my $expires = $headers->expires;
356 353
   $headers    = $headers->expires('Thu, 01 Dec 1994 16:00:00 GMT');
357 354
 
358 355
 Shortcut for the C<Expires> header.
359 356
 
360
-=head2 C<from_hash>
357
+=head2 from_hash
361 358
 
362 359
   $headers = $headers->from_hash({'Content-Type' => 'text/html'});
363 360
   $headers = $headers->from_hash({});
364 361
 
365 362
 Parse headers from a hash reference.
366 363
 
367
-=head2 C<header>
364
+=head2 header
368 365
 
369 366
   my $string = $headers->header('Content-Type');
370 367
   my @lines  = $headers->header('Content-Type');
... ...
@@ -380,93 +377,93 @@ Get or replace the current header values.
380 377
     say for @$header;
381 378
   }
382 379
 
383
-=head2 C<host>
380
+=head2 host
384 381
 
385 382
   my $host = $headers->host;
386 383
   $headers = $headers->host('127.0.0.1');
387 384
 
388 385
 Shortcut for the C<Host> header.
389 386
 
390
-=head2 C<if_modified_since>
387
+=head2 if_modified_since
391 388
 
392 389
   my $date = $headers->if_modified_since;
393 390
   $headers = $headers->if_modified_since('Sun, 17 Aug 2008 16:27:35 GMT');
394 391
 
395 392
 Shortcut for the C<If-Modified-Since> header.
396 393
 
397
-=head2 C<is_finished>
394
+=head2 is_finished
398 395
 
399 396
   my $success = $headers->is_finished;
400 397
 
401 398
 Check if header parser is finished.
402 399
 
403
-=head2 C<is_limit_exceeded>
400
+=head2 is_limit_exceeded
404 401
 
405 402
   my $success = $headers->is_limit_exceeded;
406 403
 
407 404
 Check if a header has exceeded C<max_line_size>.
408 405
 
409
-=head2 C<last_modified>
406
+=head2 last_modified
410 407
 
411 408
   my $date = $headers->last_modified;
412 409
   $headers = $headers->last_modified('Sun, 17 Aug 2008 16:27:35 GMT');
413 410
 
414 411
 Shortcut for the C<Last-Modified> header.
415 412
 
416
-=head2 C<leftovers>
413
+=head2 leftovers
417 414
 
418 415
   my $bytes = $headers->leftovers;
419 416
 
420 417
 Get leftover data from header parser.
421 418
 
422
-=head2 C<location>
419
+=head2 location
423 420
 
424 421
   my $location = $headers->location;
425 422
   $headers     = $headers->location('http://127.0.0.1/foo');
426 423
 
427 424
 Shortcut for the C<Location> header.
428 425
 
429
-=head2 C<names>
426
+=head2 names
430 427
 
431 428
   my $names = $headers->names;
432 429
 
433 430
 Generate a list of all currently defined headers.
434 431
 
435
-=head2 C<origin>
432
+=head2 origin
436 433
 
437 434
   my $origin = $headers->origin;
438 435
   $headers   = $headers->origin('http://example.com');
439 436
 
440 437
 Shortcut for the C<Origin> header from RFC 6454.
441 438
 
442
-=head2 C<parse>
439
+=head2 parse
443 440
 
444
-  $headers = $headers->parse("Content-Type: text/plain\r\n\r\n");
441
+  $headers = $headers->parse("Content-Type: text/plain\x0d\x0a\x0d\x0a");
445 442
 
446 443
 Parse formatted headers.
447 444
 
448
-=head2 C<proxy_authenticate>
445
+=head2 proxy_authenticate
449 446
 
450 447
   my $authenticate = $headers->proxy_authenticate;
451 448
   $headers         = $headers->proxy_authenticate('Basic "realm"');
452 449
 
453 450
 Shortcut for the C<Proxy-Authenticate> header.
454 451
 
455
-=head2 C<proxy_authorization>
452
+=head2 proxy_authorization
456 453
 
457 454
   my $authorization = $headers->proxy_authorization;
458 455
   $headers          = $headers->proxy_authorization('Basic Zm9vOmJhcg==');
459 456
 
460 457
 Shortcut for the C<Proxy-Authorization> header.
461 458
 
462
-=head2 C<range>
459
+=head2 range
463 460
 
464 461
   my $range = $headers->range;
465 462
   $headers  = $headers->range('bytes=2-8');
466 463
 
467 464
 Shortcut for the C<Range> header.
468 465
 
469
-=head2 C<referrer>
466
+=head2 referrer
470 467
 
471 468
   my $referrer = $headers->referrer;
472 469
   $headers     = $headers->referrer('http://mojolicio.us');
... ...
@@ -474,76 +471,76 @@ Shortcut for the C<Range> header.
474 471
 Shortcut for the C<Referer> header, there was a typo in RFC 2068 which
475 472
 resulted in C<Referer> becoming an official header.
476 473
 
477
-=head2 C<remove>
474
+=head2 remove
478 475
 
479 476
   $headers = $headers->remove('Content-Type');
480 477
 
481 478
 Remove a header.
482 479
 
483
-=head2 C<sec_websocket_accept>
480
+=head2 sec_websocket_accept
484 481
 
485 482
   my $accept = $headers->sec_websocket_accept;
486 483
   $headers   = $headers->sec_websocket_accept('s3pPLMBiTxaQ9kYGzzhZRbK+xOo=');
487 484
 
488 485
 Shortcut for the C<Sec-WebSocket-Accept> header from RFC 6455.
489 486
 
490
-=head2 C<sec_websocket_extensions>
487
+=head2 sec_websocket_extensions
491 488
 
492 489
   my $extensions = $headers->sec_websocket_extensions;
493 490
   $headers       = $headers->sec_websocket_extensions('foo');
494 491
 
495 492
 Shortcut for the C<Sec-WebSocket-Extensions> header from RFC 6455.
496 493
 
497
-=head2 C<sec_websocket_key>
494
+=head2 sec_websocket_key
498 495
 
499 496
   my $key  = $headers->sec_websocket_key;
500 497
   $headers = $headers->sec_websocket_key('dGhlIHNhbXBsZSBub25jZQ==');
501 498
 
502 499
 Shortcut for the C<Sec-WebSocket-Key> header from RFC 6455.
503 500
 
504
-=head2 C<sec_websocket_protocol>
501
+=head2 sec_websocket_protocol
505 502
 
506 503
   my $protocol = $headers->sec_websocket_protocol;
507 504
   $headers     = $headers->sec_websocket_protocol('sample');
508 505
 
509 506
 Shortcut for the C<Sec-WebSocket-Protocol> header from RFC 6455.
510 507
 
511
-=head2 C<sec_websocket_version>
508
+=head2 sec_websocket_version
512 509
 
513 510
   my $version = $headers->sec_websocket_version;
514 511
   $headers    = $headers->sec_websocket_version(13);
515 512
 
516 513
 Shortcut for the C<Sec-WebSocket-Version> header from RFC 6455.
517 514
 
518
-=head2 C<server>
515
+=head2 server
519 516
 
520 517
   my $server = $headers->server;
521 518
   $headers   = $headers->server('Mojo');
522 519
 
523 520
 Shortcut for the C<Server> header.
524 521
 
525
-=head2 C<set_cookie>
522
+=head2 set_cookie
526 523
 
527 524
   my $cookie = $headers->set_cookie;
528 525
   $headers   = $headers->set_cookie('f=b; path=/');
529 526
 
530 527
 Shortcut for the C<Set-Cookie> header from RFC 6265.
531 528
 
532
-=head2 C<status>
529
+=head2 status
533 530
 
534 531
   my $status = $headers->status;
535 532
   $headers   = $headers->status('200 OK');
536 533
 
537 534
 Shortcut for the C<Status> header from RFC 3875.
538 535
 
539
-=head2 C<te>
536
+=head2 te
540 537
 
541 538
   my $te   = $headers->te;
542 539
   $headers = $headers->te('chunked');
543 540
 
544 541
 Shortcut for the C<TE> header.
545 542
 
546
-=head2 C<to_hash>
543
+=head2 to_hash
547 544
 
548 545
   my $single = $headers->to_hash;
549 546
   my $multi  = $headers->to_hash(1);
... ...
@@ -553,41 +550,41 @@ line values are disabled by default.
553 550
 
554 551
   say $headers->to_hash->{DNT};
555 552
 
556
-=head2 C<to_string>
553
+=head2 to_string
557 554
 
558 555
   my $string = $headers->to_string;
559 556
 
560 557
 Turn headers into a string, suitable for HTTP messages.
561 558
 
562
-=head2 C<trailer>
559
+=head2 trailer
563 560
 
564 561
   my $trailer = $headers->trailer;
565 562
   $headers    = $headers->trailer('X-Foo');
566 563
 
567 564
 Shortcut for the C<Trailer> header.
568 565
 
569
-=head2 C<transfer_encoding>
566
+=head2 transfer_encoding
570 567
 
571 568
   my $encoding = $headers->transfer_encoding;
572 569
   $headers     = $headers->transfer_encoding('chunked');
573 570
 
574 571
 Shortcut for the C<Transfer-Encoding> header.
575 572
 
576
-=head2 C<upgrade>
573
+=head2 upgrade
577 574
 
578 575
   my $upgrade = $headers->upgrade;
579 576
   $headers    = $headers->upgrade('websocket');
580 577
 
581 578
 Shortcut for the C<Upgrade> header.
582 579
 
583
-=head2 C<user_agent>
580
+=head2 user_agent
584 581
 
585 582
   my $agent = $headers->user_agent;
586 583
   $headers  = $headers->user_agent('Mojo/1.0');
587 584
 
588 585
 Shortcut for the C<User-Agent> header.
589 586
 
590
-=head2 C<www_authenticate>
587
+=head2 www_authenticate
591 588
 
592 589
   my $authenticate = $headers->www_authenticate;
593 590
   $headers         = $headers->www_authenticate('Basic realm="realm"');
+16 -18
mojolegacy/lib/Mojo/Home.pm
... ...
@@ -80,7 +80,13 @@ sub parse {
80 80
 sub rel_dir { catdir(@{shift->{parts} || []}, split '/', shift) }
81 81
 sub rel_file { catfile(@{shift->{parts} || []}, split '/', shift) }
82 82
 
83
-sub slurp_rel_file { slurp shift->rel_file(@_) }
83
+# DEPRECATED in Rainbow!
84
+sub slurp_rel_file {
85
+  warn <<EOF;
86
+Mojo::Home->slurp_rel_file is DEPRECATED in favor of Mojo::Util->slurp!!!
87
+EOF
88
+  slurp shift->rel_file(@_);
89
+}
84 90
 
85 91
 sub to_string { catdir(@{shift->{parts} || []}) }
86 92
 
... ...
@@ -110,14 +116,14 @@ L<Mojo::Home> is a container for home directories.
110 116
 L<Mojo::Home> inherits all methods from L<Mojo::Base> and implements the
111 117
 following new ones.
112 118
 
113
-=head2 C<new>
119
+=head2 new
114 120
 
115 121
   my $home = Mojo::Home->new;
116 122
   my $home = Mojo::Home->new('/home/sri/myapp');
117 123
 
118 124
 Construct a new L<Mojo::Home> object.
119 125
 
120
-=head2 C<detect>
126
+=head2 detect
121 127
 
122 128
   $home = $home->detect;
123 129
   $home = $home->detect('My::App');
... ...
@@ -125,13 +131,13 @@ Construct a new L<Mojo::Home> object.
125 131
 Detect home directory from the value of the C<MOJO_HOME> environment variable
126 132
 or application class.
127 133
 
128
-=head2 C<lib_dir>
134
+=head2 lib_dir
129 135
 
130 136
   my $path = $home->lib_dir;
131 137
 
132 138
 Path to C<lib> directory of application.
133 139
 
134
-=head2 C<list_files>
140
+=head2 list_files
135 141
 
136 142
   my $files = $home->list_files;
137 143
   my $files = $home->list_files('foo/bar');
... ...
@@ -141,40 +147,32 @@ diectory.
141 147
 
142 148
   $home->rel_file($home->list_files('templates/layouts')->[1]);
143 149
 
144
-=head2 C<mojo_lib_dir>
150
+=head2 mojo_lib_dir
145 151
 
146 152
   my $path = $home->mojo_lib_dir;
147 153
 
148 154
 Path to C<lib> directory in which L<Mojolicious> is installed.
149 155
 
150
-=head2 C<parse>
156
+=head2 parse
151 157
 
152 158
   $home = $home->parse('/home/sri/myapp');
153 159
 
154 160
 Parse home directory.
155 161
 
156
-=head2 C<rel_dir>
162
+=head2 rel_dir
157 163
 
158 164
   my $path = $home->rel_dir('foo/bar');
159 165
 
160 166
 Portably generate an absolute path for a directory relative to the home
161 167
 directory.
162 168
 
163
-=head2 C<rel_file>
169
+=head2 rel_file
164 170
 
165 171
   my $path = $home->rel_file('foo/bar.html');
166 172
 
167 173
 Portably generate an absolute path for a file relative to the home directory.
168 174
 
169
-=head2 C<slurp_rel_file>
170
-
171
-  my $content = $home->slurp_rel_file('foo/bar.html');
172
-
173
-Portably read all data at once from file relative to the home directory.
174
-
175
-  my $content = $home->slurp_rel_file($home->list_files('public')->[1]);
176
-
177
-=head2 C<to_string>
175
+=head2 to_string
178 176
 
179 177
   my $string = $home->to_string;
180 178
   my $string = "$home";
+36 -41
mojolegacy/lib/Mojo/IOLoop.pm
... ...
@@ -42,13 +42,13 @@ sub acceptor {
42 42
   # Make sure connection manager is running
43 43
   $self->_manager;
44 44
 
45
-  # New acceptor
45
+  # Connect acceptor with reactor
46 46
   my $id = $self->_id;
47 47
   $self->{acceptors}{$id} = $acceptor;
48 48
   weaken $acceptor->reactor($self->reactor)->{reactor};
49 49
   $self->{accepts} = $self->max_accepts if $self->max_accepts;
50 50
 
51
-  # Stop accepting
51
+  # Stop accepting so new acceptor can get picked up
52 52
   $self->_not_accepting;
53 53
 
54 54
   return $id;
... ...
@@ -61,25 +61,22 @@ sub client {
61 61
   # Make sure connection manager is running
62 62
   $self->_manager;
63 63
 
64
-  # New client
65 64
   my $id     = $self->_id;
66 65
   my $c      = $self->{connections}{$id} ||= {};
67 66
   my $client = $c->{client} = Mojo::IOLoop::Client->new;
68 67
   weaken $client->reactor($self->reactor)->{reactor};
69 68
 
70
-  # Connect
71 69
   weaken $self;
72 70
   $client->on(
73 71
     connect => sub {
74 72
       my $handle = pop;
75 73
 
76
-      # New stream
74
+      # Turn handle into stream
77 75
       my $c = $self->{connections}{$id};
78 76
       delete $c->{client};
79 77
       my $stream = $c->{stream} = Mojo::IOLoop::Stream->new($handle);
80 78
       $self->_stream($stream => $id);
81 79
 
82
-      # Connected
83 80
       $self->$cb(undef, $stream);
84 81
     }
85 82
   );
... ...
@@ -128,14 +125,13 @@ sub server {
128 125
   my ($self, $cb) = (shift, pop);
129 126
   $self = $self->singleton unless ref $self;
130 127
 
131
-  # New server
132 128
   my $server = Mojo::IOLoop::Server->new;
133 129
   weaken $self;
134 130
   $server->on(
135 131
     accept => sub {
136 132
       my $handle = pop;
137 133
 
138
-      # Accept
134
+      # Turn handle into stream
139 135
       my $stream = Mojo::IOLoop::Stream->new($handle);
140 136
       $self->$cb($stream, $self->stream($stream));
141 137
 
... ...
@@ -144,7 +140,7 @@ sub server {
144 140
         if defined $self->{accepts}
145 141
         && ($self->{accepts} -= int(rand 2) + 1) <= 0;
146 142
 
147
-      # Stop accepting
143
+      # Stop accepting to release accept mutex
148 144
       $self->_not_accepting;
149 145
     }
150 146
   );
... ...
@@ -214,7 +210,7 @@ sub _id {
214 210
 sub _manage {
215 211
   my $self = shift;
216 212
 
217
-  # Start accepting if possible
213
+  # Try to acquire accept mutex
218 214
   $self->_accepting;
219 215
 
220 216
   # Close connections gracefully
... ...
@@ -241,9 +237,8 @@ sub _not_accepting {
241 237
   # Release accept mutex
242 238
   return unless delete $self->{accepting};
243 239
   return unless my $cb = $self->unlock;
244
-  $self->$cb();
240
+  $self->$cb;
245 241
 
246
-  # Stop accepting
247 242
   $_->stop for values %{$self->{acceptors} || {}};
248 243
 }
249 244
 
... ...
@@ -274,7 +269,7 @@ sub _stream {
274 269
   $self->{connections}{$id}{stream} = $stream;
275 270
   weaken $stream->reactor($self->reactor)->{reactor};
276 271
 
277
-  # Stream
272
+  # Start streaming
278 273
   weaken $self;
279 274
   $stream->on(close => sub { $self->{connections}{$id}{finish} = 1 });
280 275
   $stream->start;
... ...
@@ -297,12 +292,12 @@ Mojo::IOLoop - Minimalistic event loop
297 292
     my ($loop, $stream) = @_;
298 293
 
299 294
     $stream->on(read => sub {
300
-      my ($stream, $chunk) = @_;
295
+      my ($stream, $bytes) = @_;
301 296
 
302
-      # Process input
303
-      say $chunk;
297
+      # Process input chunk
298
+      say $bytes;
304 299
 
305
-      # Got some data, time to write
300
+      # Write response
306 301
       $stream->write('HTTP/1.1 200 OK');
307 302
     });
308 303
   });
... ...
@@ -312,14 +307,14 @@ Mojo::IOLoop - Minimalistic event loop
312 307
     my ($loop, $err, $stream) = @_;
313 308
 
314 309
     $stream->on(read => sub {
315
-      my ($stream, $chunk) = @_;
310
+      my ($stream, $bytes) = @_;
316 311
 
317 312
       # Process input
318
-      say "Input: $chunk";
313
+      say "Input: $bytes";
319 314
     });
320 315
 
321 316
     # Write request
322
-    $stream->write("GET / HTTP/1.1\r\n\r\n");
317
+    $stream->write("GET / HTTP/1.1\x0d\x0a\x0d\x0a");
323 318
   });
324 319
 
325 320
   # Add a timer
... ...
@@ -352,7 +347,7 @@ See L<Mojolicious::Guides::Cookbook> for more.
352 347
 
353 348
 L<Mojo::IOLoop> implements the following attributes.
354 349
 
355
-=head2 C<accept_interval>
350
+=head2 accept_interval
356 351
 
357 352
   my $interval = $loop->accept_interval;
358 353
   $loop        = $loop->accept_interval(0.5);
... ...
@@ -361,7 +356,7 @@ Interval in seconds for trying to reacquire the accept mutex and connection
361 356
 management, defaults to C<0.025>. Note that changing this value can affect
362 357
 performance and idle CPU usage.
363 358
 
364
-=head2 C<lock>
359
+=head2 lock
365 360
 
366 361
   my $cb = $loop->lock;
367 362
   $loop  = $loop->lock(sub {...});
... ...
@@ -377,7 +372,7 @@ this callback are not captured.
377 372
     return 1;
378 373
   });
379 374
 
380
-=head2 C<max_accepts>
375
+=head2 max_accepts
381 376
 
382 377
   my $max = $loop->max_accepts;
383 378
   $loop   = $loop->max_accepts(1000);
... ...
@@ -388,7 +383,7 @@ to C<0>. Setting the value to C<0> will allow this event loop to accept new
388 383
 connections indefinitely. Note that up to half of this value can be subtracted
389 384
 randomly to improve load balancing between multiple server processes.
390 385
 
391
-=head2 C<max_connections>
386
+=head2 max_connections
392 387
 
393 388
   my $max = $loop->max_connections;
394 389
   $loop   = $loop->max_connections(1000);
... ...
@@ -399,14 +394,14 @@ C<1000>. Setting the value to C<0> will make this event loop stop accepting
399 394
 new connections and allow it to shut down gracefully without interrupting
400 395
 existing connections.
401 396
 
402
-=head2 C<multi_accept>
397
+=head2 multi_accept
403 398
 
404 399
   my $multi = $loop->multi_accept;
405 400
   $loop     = $loop->multi_accept(100);
406 401
 
407 402
 Number of connections to accept at once, defaults to C<50>.
408 403
 
409
-=head2 C<reactor>
404
+=head2 reactor
410 405
 
411 406
   my $reactor = $loop->reactor;
412 407
   $loop       = $loop->reactor(Mojo::Reactor->new);
... ...
@@ -423,7 +418,7 @@ L<Mojo::Reactor::EV> object.
423 418
   # Change to watching only if handle becomes writable
424 419
   $loop->reactor->watch($handle, 0, 1);
425 420
 
426
-=head2 C<unlock>
421
+=head2 unlock
427 422
 
428 423
   my $cb = $loop->unlock;
429 424
   $loop  = $loop->unlock(sub {...});
... ...
@@ -436,7 +431,7 @@ processes. Note that exceptions in this callback are not captured.
436 431
 L<Mojo::IOLoop> inherits all methods from L<Mojo::Base> and implements the
437 432
 following new ones.
438 433
 
439
-=head2 C<acceptor>
434
+=head2 acceptor
440 435
 
441 436
   my $server = Mojo::IOLoop->acceptor($id);
442 437
   my $server = $loop->acceptor($id);
... ...
@@ -444,7 +439,7 @@ following new ones.
444 439
 
445 440
 Get L<Mojo::IOLoop::Server> object for id or turn object into an acceptor.
446 441
 
447
-=head2 C<client>
442
+=head2 client
448 443
 
449 444
   my $id
450 445
     = Mojo::IOLoop->client(address => '127.0.0.1', port => 3000, sub {...});
... ...
@@ -460,7 +455,7 @@ L<Mojo::IOLoop::Client/"connect">.
460 455
     ...
461 456
   });
462 457
 
463
-=head2 C<delay>
458
+=head2 delay
464 459
 
465 460
   my $delay = Mojo::IOLoop->delay;
466 461
   my $delay = $loop->delay;
... ...
@@ -506,14 +501,14 @@ ones as a chain of steps.
506 501
   # Wait for events if necessary
507 502
   $delay->wait unless Mojo::IOLoop->is_running;
508 503
 
509
-=head2 C<generate_port>
504
+=head2 generate_port
510 505
 
511 506
   my $port = Mojo::IOLoop->generate_port;
512 507
   my $port = $loop->generate_port;
513 508
 
514 509
 Find a free TCP port, this is a utility function primarily used for tests.
515 510
 
516
-=head2 C<is_running>
511
+=head2 is_running
517 512
 
518 513
   my $success = Mojo::IOLoop->is_running;
519 514
   my $success = $loop->is_running;
... ...
@@ -522,7 +517,7 @@ Check if event loop is running.
522 517
 
523 518
   exit unless Mojo::IOLoop->is_running;
524 519
 
525
-=head2 C<one_tick>
520
+=head2 one_tick
526 521
 
527 522
   Mojo::IOLoop->one_tick;
528 523
   $loop->one_tick;
... ...
@@ -530,7 +525,7 @@ Check if event loop is running.
530 525
 Run event loop until an event occurs. Note that this method can recurse back
531 526
 into the reactor, so you need to be careful.
532 527
 
533
-=head2 C<recurring>
528
+=head2 recurring
534 529
 
535 530
   my $id = Mojo::IOLoop->recurring(0.5 => sub {...});
536 531
   my $id = $loop->recurring(3 => sub {...});
... ...
@@ -541,7 +536,7 @@ amount of time in seconds.
541 536
   # Invoke as soon as possible
542 537
   Mojo::IOLoop->recurring(0 => sub { say 'Reactor tick.' });
543 538
 
544
-=head2 C<remove>
539
+=head2 remove
545 540
 
546 541
   Mojo::IOLoop->remove($id);
547 542
   $loop->remove($id);
... ...
@@ -549,7 +544,7 @@ amount of time in seconds.
549 544
 Remove anything with an id, connections will be dropped gracefully by allowing
550 545
 them to finish writing all data in their write buffers.
551 546
 
552
-=head2 C<server>
547
+=head2 server
553 548
 
554 549
   my $id = Mojo::IOLoop->server(port => 3000, sub {...});
555 550
   my $id = $loop->server(port => 3000, sub {...});
... ...
@@ -564,7 +559,7 @@ as L<Mojo::IOLoop::Server/"listen">.
564 559
     ...
565 560
   });
566 561
 
567
-=head2 C<singleton>
562
+=head2 singleton
568 563
 
569 564
   my $loop = Mojo::IOLoop->singleton;
570 565
 
... ...
@@ -575,7 +570,7 @@ loop object from everywhere inside the process.
575 570
   Mojo::IOLoop->timer(2 => sub { Mojo::IOLoop->stop });
576 571
   Mojo::IOLoop->start;
577 572
 
578
-=head2 C<start>
573
+=head2 start
579 574
 
580 575
   Mojo::IOLoop->start;
581 576
   $loop->start;
... ...
@@ -586,7 +581,7 @@ reactors stop automatically if there are no events being watched anymore.
586 581
   # Start event loop only if it is not running already
587 582
   Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
588 583
 
589
-=head2 C<stop>
584
+=head2 stop
590 585
 
591 586
   Mojo::IOLoop->stop;
592 587
   $loop->stop;
... ...
@@ -594,7 +589,7 @@ reactors stop automatically if there are no events being watched anymore.
594 589
 Stop the event loop, this will not interrupt any existing connections and the
595 590
 event loop can be restarted by running C<start> again.
596 591
 
597
-=head2 C<stream>
592
+=head2 stream
598 593
 
599 594
   my $stream = Mojo::IOLoop->stream($id);
600 595
   my $stream = $loop->stream($id);
... ...
@@ -605,7 +600,7 @@ Get L<Mojo::IOLoop::Stream> object for id or turn object into a connection.
605 600
   # Increase inactivity timeout for connection to 300 seconds
606 601
   Mojo::IOLoop->stream($id)->timeout(300);
607 602
 
608
-=head2 C<timer>
603
+=head2 timer
609 604
 
610 605
   my $id = Mojo::IOLoop->timer(5 => sub {...});
611 606
   my $id = $loop->timer(5 => sub {...});
+15 -19
mojolegacy/lib/Mojo/IOLoop/Client.pm
... ...
@@ -43,7 +43,6 @@ sub _cleanup {
43 43
 sub _connect {
44 44
   my ($self, $args) = @_;
45 45
 
46
-  # New socket
47 46
   my $handle;
48 47
   my $reactor = $self->reactor;
49 48
   my $address = $args->{address} ||= 'localhost';
... ...
@@ -83,7 +82,6 @@ sub _tls {
83 82
     return;
84 83
   }
85 84
 
86
-  # Connected
87 85
   $self->_cleanup->emit_safe(connect => $handle);
88 86
 }
89 87
 
... ...
@@ -102,8 +100,6 @@ sub _try {
102 100
 
103 101
   # TLS
104 102
   if ($args->{tls} && !$handle->isa('IO::Socket::SSL')) {
105
-
106
-    # No TLS support
107 103
     return $self->emit_safe(
108 104
       error => 'IO::Socket::SSL 1.75 required for TLS support')
109 105
       unless TLS;
... ...
@@ -130,7 +126,6 @@ sub _try {
130 126
     return $reactor->io($handle => sub { $self->_tls })->watch($handle, 0, 1);
131 127
   }
132 128
 
133
-  # Connected
134 129
   $self->_cleanup->emit_safe(connect => $handle);
135 130
 }
136 131
 
... ...
@@ -165,9 +160,10 @@ L<Mojo::IOLoop::Client> opens TCP connections for L<Mojo::IOLoop>.
165 160
 
166 161
 =head1 EVENTS
167 162
 
168
-L<Mojo::IOLoop::Client> can emit the following events.
163
+L<Mojo::IOLoop::Client> inherits all events from L<Mojo::EventEmitter> and can
164
+emit the following new ones.
169 165
 
170
-=head2 C<connect>
166
+=head2 connect
171 167
 
172 168
   $client->on(connect => sub {
173 169
     my ($client, $handle) = @_;
... ...
@@ -176,7 +172,7 @@ L<Mojo::IOLoop::Client> can emit the following events.
176 172
 
177 173
 Emitted safely once the connection is established.
178 174
 
179
-=head2 C<error>
175
+=head2 error
180 176
 
181 177
   $client->on(error => sub {
182 178
     my ($client, $err) = @_;
... ...
@@ -189,7 +185,7 @@ Emitted safely if an error occurs on the connection.
189 185
 
190 186
 L<Mojo::IOLoop::Client> implements the following attributes.
191 187
 
192
-=head2 C<reactor>
188
+=head2 reactor
193 189
 
194 190
   my $reactor = $client->reactor;
195 191
   $client     = $client->reactor(Mojo::Reactor::Poll->new);
... ...
@@ -202,7 +198,7 @@ global L<Mojo::IOLoop> singleton.
202 198
 L<Mojo::IOLoop::Client> inherits all methods from L<Mojo::EventEmitter> and
203 199
 implements the following new ones.
204 200
 
205
-=head2 C<connect>
201
+=head2 connect
206 202
 
207 203
   $client->connect(address => '127.0.0.1', port => 3000);
208 204
 
... ...
@@ -213,40 +209,40 @@ These options are currently available:
213 209
 
214 210
 =over 2
215 211
 
216
-=item C<address>
212
+=item address
217 213
 
218 214
 Address or host name of the peer to connect to, defaults to C<localhost>.
219 215
 
220
-=item C<handle>
216
+=item handle
221 217
 
222 218
 Use an already prepared handle.
223 219
 
224
-=item C<local_address>
220
+=item local_address
225 221
 
226 222
 Local address to bind to.
227 223
 
228
-=item C<port>
224
+=item port
229 225
 
230 226
 Port to connect to.
231 227
 
232
-=item C<timeout>
228
+=item timeout
233 229
 
234 230
 Maximum amount of time in seconds establishing connection may take before
235 231
 getting canceled, defaults to C<10>.
236 232
 
237
-=item C<tls>
233
+=item tls
238 234
 
239 235
 Enable TLS.
240 236
 
241
-=item C<tls_ca>
237
+=item tls_ca
242 238
 
243 239
 Path to TLS certificate authority file. Also activates hostname verification.
244 240
 
245
-=item C<tls_cert>
241
+=item tls_cert
246 242
 
247 243
 Path to the TLS certificate file.
248 244
 
249
-=item C<tls_key>
245
+=item tls_key
250 246
 
251 247
 Path to the TLS key file.
252 248
 
+8 -7
mojolegacy/lib/Mojo/IOLoop/Delay.pm
... ...
@@ -109,9 +109,10 @@ L<Mojo::IOLoop::Delay> controls the flow of events for L<Mojo::IOLoop>.
109 109
 
110 110
 =head1 EVENTS
111 111
 
112
-L<Mojo::IOLoop::Delay> can emit the following events.
112
+L<Mojo::IOLoop::Delay> inherits all events from L<Mojo::EventEmitter> and can
113
+emit the following new ones.
113 114
 
114
-=head2 C<finish>
115
+=head2 finish
115 116
 
116 117
   $delay->on(finish => sub {
117 118
     my ($delay, @args) = @_;
... ...
@@ -125,7 +126,7 @@ steps.
125 126
 
126 127
 L<Mojo::IOLoop::Delay> implements the following attributes.
127 128
 
128
-=head2 C<ioloop>
129
+=head2 ioloop
129 130
 
130 131
   my $ioloop = $delay->ioloop;
131 132
   $delay     = $delay->ioloop(Mojo::IOLoop->new);
... ...
@@ -138,7 +139,7 @@ singleton.
138 139
 L<Mojo::IOLoop::Delay> inherits all methods from L<Mojo::EventEmitter> and
139 140
 implements the following new ones.
140 141
 
141
-=head2 C<begin>
142
+=head2 begin
142 143
 
143 144
   my $cb = $delay->begin;
144 145
 
... ...
@@ -150,7 +151,7 @@ that the first argument passed to the callback will be ignored.
150 151
   Mojo::UserAgent->new->get('mojolicio.us' => $delay->begin);
151 152
   my $tx = $delay->wait;
152 153
 
153
-=head2 C<end>
154
+=head2 end
154 155
 
155 156
   my $remaining = $delay->end;
156 157
   my $remaining = $delay->end(@args);
... ...
@@ -158,7 +159,7 @@ that the first argument passed to the callback will be ignored.
158 159
 Decrement active event counter, all arguments are queued for the next step or
159 160
 C<finish> event and C<wait> method.
160 161
 
161
-=head2 C<steps>
162
+=head2 steps
162 163
 
163 164
   $delay = $delay->steps(sub {...}, sub {...});
164 165
 
... ...
@@ -166,7 +167,7 @@ Sequentialize multiple events, the first callback will run right away, and the
166 167
 next one once the active event counter reaches zero, this chain will continue
167 168
 until there are no more callbacks left.
168 169
 
169
-=head2 C<wait>
170
+=head2 wait
170 171
 
171 172
   my @args = $delay->wait;
172 173
 
+17 -18
mojolegacy/lib/Mojo/IOLoop/Server.pm
... ...
@@ -78,7 +78,6 @@ sub listen {
78 78
   $handle->blocking(0);
79 79
   $self->{handle} = $handle;
80 80
 
81
-  # TLS
82 81
   return unless $args->{tls};
83 82
   croak "IO::Socket::SSL 1.75 required for TLS support" unless TLS;
84 83
 
... ...
@@ -115,7 +114,6 @@ sub stop { $_[0]->reactor->remove($_[0]->{handle}) }
115 114
 sub _accept {
116 115
   my $self = shift;
117 116
 
118
-  # Accept
119 117
   return unless my $handle = $self->{handle}->accept;
120 118
   $handle->blocking(0);
121 119
 
... ...
@@ -182,9 +180,10 @@ L<Mojo::IOLoop::Server> accepts TCP connections for L<Mojo::IOLoop>.
182 180
 
183 181
 =head1 EVENTS
184 182
 
185
-L<Mojo::IOLoop::Server> can emit the following events.
183
+L<Mojo::IOLoop::Server> inherits all events from L<Mojo::EventEmitter> and can
184
+emit the following new ones.
186 185
 
187
-=head2 C<accept>
186
+=head2 accept
188 187
 
189 188
   $server->on(accept => sub {
190 189
     my ($server, $handle) = @_;
... ...
@@ -197,14 +196,14 @@ Emitted safely for each accepted connection.
197 196
 
198 197
 L<Mojo::IOLoop::Server> implements the following attributes.
199 198
 
200
-=head2 C<multi_accept>
199
+=head2 multi_accept
201 200
 
202 201
   my $multi = $server->multi_accept;
203 202
   $server   = $server->multi_accept(100);
204 203
 
205 204
 Number of connections to accept at once, defaults to C<50>.
206 205
 
207
-=head2 C<reactor>
206
+=head2 reactor
208 207
 
209 208
   my $reactor = $server->reactor;
210 209
   $server     = $server->reactor(Mojo::Reactor::Poll->new);
... ...
@@ -217,7 +216,7 @@ global L<Mojo::IOLoop> singleton.
217 216
 L<Mojo::IOLoop::Server> inherits all methods from L<Mojo::EventEmitter> and
218 217
 implements the following new ones.
219 218
 
220
-=head2 C<listen>
219
+=head2 listen
221 220
 
222 221
   $server->listen(port => 3000);
223 222
 
... ...
@@ -228,53 +227,53 @@ These options are currently available:
228 227
 
229 228
 =over 2
230 229
 
231
-=item C<address>
230
+=item address
232 231
 
233 232
 Local address to listen on, defaults to all.
234 233
 
235
-=item C<backlog>
234
+=item backlog
236 235
 
237 236
 Maximum backlog size, defaults to C<SOMAXCONN>.
238 237
 
239
-=item C<port>
238
+=item port
240 239
 
241 240
 Port to listen on.
242 241
 
243
-=item C<tls>
242
+=item tls
244 243
 
245 244
 Enable TLS.
246 245
 
247
-=item C<tls_ca>
246
+=item tls_ca
248 247
 
249 248
 Path to TLS certificate authority file.
250 249
 
251
-=item C<tls_cert>
250
+=item tls_cert
252 251
 
253 252
 Path to the TLS cert file, defaults to a built-in test certificate.
254 253
 
255
-=item C<tls_key>
254
+=item tls_key
256 255
 
257 256
 Path to the TLS key file, defaults to a built-in test key.
258 257
 
259
-=item C<tls_verify>
258
+=item tls_verify
260 259
 
261 260
 TLS verification mode, defaults to C<0x03>.
262 261
 
263 262
 =back
264 263
 
265
-=head2 C<generate_port>
264
+=head2 generate_port
266 265
 
267 266
   my $port = $server->generate_port;
268 267
 
269 268
 Find a free TCP port, this is a utility function primarily used for tests.
270 269
 
271
-=head2 C<start>
270
+=head2 start
272 271
 
273 272
   $server->start;
274 273
 
275 274
 Start accepting connections.
276 275
 
277
-=head2 C<stop>
276
+=head2 stop
278 277
 
279 278
   $server->stop;
280 279
 
+24 -41
mojolegacy/lib/Mojo/IOLoop/Stream.pm
... ...
@@ -24,7 +24,6 @@ sub close {
24 24
   return unless my $handle = delete $self->{handle};
25 25
   $reactor->remove($handle);
26 26
 
27
-  # Close
28 27
   close $handle;
29 28
   $self->emit_safe('close');
30 29
 }
... ...
@@ -65,14 +64,9 @@ sub steal_handle {
65 64
 sub write {
66 65
   my ($self, $chunk, $cb) = @_;
67 66
 
68
-  # Prepare chunk for writing
69 67
   $self->{buffer} .= $chunk;
70
-
71
-  # Write with roundtrip
72 68
   if ($cb) { $self->once(drain => $cb) }
73 69
   else     { return $self unless length $self->{buffer} }
74
-
75
-  # Start writing
76 70
   $self->reactor->watch($self->{handle}, !$self->{paused}, 1)
77 71
     if $self->{handle};
78 72
 
... ...
@@ -82,10 +76,7 @@ sub write {
82 76
 sub _read {
83 77
   my $self = shift;
84 78
 
85
-  # Read
86 79
   my $read = $self->{handle}->sysread(my $buffer, 131072, 0);
87
-
88
-  # Error
89 80
   unless (defined $read) {
90 81
 
91 82
     # Retry
... ...
@@ -101,7 +92,6 @@ sub _read {
101 92
   # EOF
102 93
   return $self->close if $read == 0;
103 94
 
104
-  # Handle read
105 95
   $self->emit_safe(read => $buffer)->{active} = time;
106 96
 }
107 97
 
... ...
@@ -118,19 +108,15 @@ sub _startup {
118 108
     }
119 109
   );
120 110
 
121
-  # Start streaming
122 111
   $reactor->io($self->{handle}, sub { pop() ? $self->_write : $self->_read });
123 112
 }
124 113
 
125 114
 sub _write {
126 115
   my $self = shift;
127 116
 
128
-  # Write as much as possible
129 117
   my $handle = $self->{handle};
130 118
   if (length $self->{buffer}) {
131 119
     my $written = $handle->syswrite($self->{buffer});
132
-
133
-    # Error
134 120
     unless (defined $written) {
135 121
 
136 122
       # Retry
... ...
@@ -143,15 +129,11 @@ sub _write {
143 129
       return $self->emit_safe(error => $!)->close;
144 130
     }
145 131
 
146
-    # Remove written chunk from buffer
147 132
     $self->emit_safe(write => substr($self->{buffer}, 0, $written, ''));
148 133
     $self->{active} = time;
149 134
   }
150 135
 
151
-  # Handle drain
152 136
   $self->emit_safe('drain') if !length $self->{buffer};
153
-
154
-  # Stop writing
155 137
   return if $self->is_writing;
156 138
   $self->reactor->watch($handle, !$self->{paused}, 0);
157 139
 }
... ...
@@ -169,7 +151,7 @@ Mojo::IOLoop::Stream - Non-blocking I/O stream
169 151
   # Create stream
170 152
   my $stream = Mojo::IOLoop::Stream->new($handle);
171 153
   $stream->on(read => sub {
172
-    my ($stream, $chunk) = @_;
154
+    my ($stream, $bytes) = @_;
173 155
     ...
174 156
   });
175 157
   $stream->on(close => sub {
... ...
@@ -195,9 +177,10 @@ L<Mojo::IOLoop>.
195 177
 
196 178
 =head1 EVENTS
197 179
 
198
-L<Mojo::IOLoop::Stream> can emit the following events.
180
+L<Mojo::IOLoop::Stream> inherits all events from L<Mojo::EventEmitter> and can
181
+emit the following new ones.
199 182
 
200
-=head2 C<close>
183
+=head2 close
201 184
 
202 185
   $stream->on(close => sub {
203 186
     my $stream = shift;
... ...
@@ -206,7 +189,7 @@ L<Mojo::IOLoop::Stream> can emit the following events.
206 189
 
207 190
 Emitted safely if the stream gets closed.
208 191
 
209
-=head2 C<drain>
192
+=head2 drain
210 193
 
211 194
   $stream->on(drain => sub {
212 195
     my $stream = shift;
... ...
@@ -215,7 +198,7 @@ Emitted safely if the stream gets closed.
215 198
 
216 199
 Emitted safely once all data has been written.
217 200
 
218
-=head2 C<error>
201
+=head2 error
219 202
 
220 203
   $stream->on(error => sub {
221 204
     my ($stream, $err) = @_;
... ...
@@ -224,16 +207,16 @@ Emitted safely once all data has been written.
224 207
 
225 208
 Emitted safely if an error occurs on the stream.
226 209
 
227
-=head2 C<read>
210
+=head2 read
228 211
 
229 212
   $stream->on(read => sub {
230
-    my ($stream, $chunk) = @_;
213
+    my ($stream, $bytes) = @_;
231 214
     ...
232 215
   });
233 216
 
234 217
 Emitted safely if new data arrives on the stream.
235 218
 
236
-=head2 C<timeout>
219
+=head2 timeout
237 220
 
238 221
   $stream->on(timeout => sub {
239 222
     my $stream = shift;
... ...
@@ -243,10 +226,10 @@ Emitted safely if new data arrives on the stream.
243 226
 Emitted safely if the stream has been inactive for too long and will get
244 227
 closed automatically.
245 228
 
246
-=head2 C<write>
229
+=head2 write
247 230
 
248 231
   $stream->on(write => sub {
249
-    my ($stream, $chunk) = @_;
232
+    my ($stream, $bytes) = @_;
250 233
     ...
251 234
   });
252 235
 
... ...
@@ -256,7 +239,7 @@ Emitted safely if new data has been written to the stream.
256 239
 
257 240
 L<Mojo::IOLoop::Stream> implements the following attributes.
258 241
 
259
-=head2 C<reactor>
242
+=head2 reactor
260 243
 
261 244
   my $reactor = $stream->reactor;
262 245
   $stream     = $stream->reactor(Mojo::Reactor::Poll->new);
... ...
@@ -264,7 +247,7 @@ L<Mojo::IOLoop::Stream> implements the following attributes.
264 247
 Low level event reactor, defaults to the C<reactor> attribute value of the
265 248
 global L<Mojo::IOLoop> singleton.
266 249
 
267
-=head2 C<timeout>
250
+=head2 timeout
268 251
 
269 252
   my $timeout = $stream->timeout;
270 253
   $stream     = $stream->timeout(45);
... ...
@@ -278,59 +261,59 @@ stream to be inactive indefinitely.
278 261
 L<Mojo::IOLoop::Stream> inherits all methods from L<Mojo::EventEmitter> and
279 262
 implements the following new ones.
280 263
 
281
-=head2 C<new>
264
+=head2 new
282 265
 
283 266
   my $stream = Mojo::IOLoop::Stream->new($handle);
284 267
 
285 268
 Construct a new L<Mojo::IOLoop::Stream> object.
286 269
 
287
-=head2 C<close>
270
+=head2 close
288 271
 
289 272
   $stream->close;
290 273
 
291 274
 Close stream immediately.
292 275
 
293
-=head2 C<handle>
276
+=head2 handle
294 277
 
295 278
   my $handle = $stream->handle;
296 279
 
297 280
 Get handle for stream.
298 281
 
299
-=head2 C<is_readable>
282
+=head2 is_readable
300 283
 
301 284
   my $success = $stream->is_readable;
302 285
 
303 286
 Quick non-blocking check if stream is readable, useful for identifying tainted
304 287
 sockets.
305 288
 
306
-=head2 C<is_writing>
289
+=head2 is_writing
307 290
 
308 291
   my $success = $stream->is_writing;
309 292
 
310 293
 Check if stream is writing.
311 294
 
312
-=head2 C<start>
295
+=head2 start
313 296
 
314 297
   $stream->start;
315 298
 
316 299
 Start watching for new data on the stream.
317 300
 
318
-=head2 C<stop>
301
+=head2 stop
319 302
 
320 303
   $stream->stop;
321 304
 
322 305
 Stop watching for new data on the stream.
323 306
 
324
-=head2 C<steal_handle>
307
+=head2 steal_handle
325 308
 
326 309
   my $handle = $stream->steal_handle;
327 310
 
328 311
 Steal handle from stream and prevent it from getting closed automatically.
329 312
 
330
-=head2 C<write>
313
+=head2 write
331 314
 
332
-  $stream = $stream->write('Hello!');
333
-  $stream = $stream->write('Hello!' => sub {...});
315
+  $stream = $stream->write($bytes);
316
+  $stream = $stream->write($bytes => sub {...});
334 317
 
335 318
 Write data to stream, the optional drain callback will be invoked once all
336 319
 data has been written.
+45 -19
mojolegacy/lib/Mojo/JSON.pm
... ...
@@ -2,11 +2,14 @@ package Mojo::JSON;
2 2
 use Mojo::Base -base;
3 3
 
4 4
 use B;
5
+use Exporter 'import';
5 6
 use Mojo::Util;
6 7
 use Scalar::Util 'blessed';
7 8
 
8 9
 has 'error';
9 10
 
11
+our @EXPORT_OK = ('j');
12
+
10 13
 # Literal names
11 14
 my $FALSE = bless \(my $false = 0), 'Mojo::JSON::_Bool';
12 15
 my $TRUE  = bless \(my $true  = 1), 'Mojo::JSON::_Bool';
... ...
@@ -40,7 +43,7 @@ my $WHITESPACE_RE = qr/[\x20\x09\x0a\x0d]*/;
40 43
 sub decode {
41 44
   my ($self, $bytes) = @_;
42 45
 
43
-  # Cleanup
46
+  # Clean start
44 47
   $self->error(undef);
45 48
 
46 49
   # Missing input
... ...
@@ -99,7 +102,14 @@ sub encode {
99 102
 }
100 103
 
101 104
 sub false {$FALSE}
102
-sub true  {$TRUE}
105
+
106
+sub j {
107
+  my $d = shift;
108
+  return __PACKAGE__->new->encode($d) if ref $d eq 'ARRAY' || ref $d eq 'HASH';
109
+  return __PACKAGE__->new->decode($d);
110
+}
111
+
112
+sub true {$TRUE}
103 113
 
104 114
 sub _decode_array {
105 115
   my @array;
... ...
@@ -246,22 +256,14 @@ sub _encode_array {
246 256
 
247 257
 sub _encode_object {
248 258
   my $object = shift;
249
-
250
-  # Encode pairs
251 259
   my @pairs = map { _encode_string($_) . ':' . _encode_values($object->{$_}) }
252 260
     keys %$object;
253
-
254
-  # Stringify
255 261
   return '{' . join(',', @pairs) . '}';
256 262
 }
257 263
 
258 264
 sub _encode_string {
259 265
   my $string = shift;
260
-
261
-  # Escape string
262 266
   $string =~ s!([\x00-\x1F\x7F\x{2028}\x{2029}\\"/\b\f\n\r\t])!$REVERSE{$1}!gs;
263
-
264
-  # Stringify
265 267
   return "\"$string\"";
266 268
 }
267 269
 
... ...
@@ -312,7 +314,6 @@ sub _exception {
312 314
     $context .= ' at line ' . @lines . ', offset ' . length(pop @lines || '');
313 315
   }
314 316
 
315
-  # Throw
316 317
   die "$context\n";
317 318
 }
318 319
 
... ...
@@ -328,12 +329,22 @@ Mojo::JSON - Minimalistic JSON
328 329
 
329 330
 =head1 SYNOPSIS
330 331
 
332
+  # Encode and decode JSON
331 333
   use Mojo::JSON;
332
-
333 334
   my $json  = Mojo::JSON->new;
334 335
   my $bytes = $json->encode({foo => [1, 2], bar => 'hello!', baz => \1});
335 336
   my $hash  = $json->decode($bytes);
336 337
 
338
+  # Check for errors
339
+  my $json = Mojo::JSON->new;
340
+  if (defined(my $hash = $json->decode($bytes))) { say $hash->{message} }
341
+  else { say 'Error: ', $json->error }
342
+
343
+  # Use the alternative interface
344
+  use Mojo::JSON 'j';
345
+  my $bytes = j({foo => [1, 2], bar => 'hello!', baz => \1});
346
+  my $hash  = j($bytes);
347
+
337 348
 =head1 DESCRIPTION
338 349
 
339 350
 L<Mojo::JSON> is a minimalistic and relaxed implementation of RFC 4627. While
... ...
@@ -359,11 +370,25 @@ Decoding UTF-16 (LE/BE) and UTF-32 (LE/BE) will be handled transparently,
359 370
 encoding will only generate UTF-8. The two Unicode whitespace characters
360 371
 C<u2028> and C<u2029> will always be escaped to make JSONP easier.
361 372
 
373
+=head1 FUNCTIONS
374
+
375
+L<Mojo::JSON> implements the following functions.
376
+
377
+=head2 j
378
+
379
+  my $bytes = j([1, 2, 3]);
380
+  my $bytes = j({foo => 'bar'});
381
+  my $array = j($bytes);
382
+  my $hash  = j($bytes);
383
+
384
+Encode Perl data structure or decode JSON and return C<undef> if decoding
385
+fails.
386
+
362 387
 =head1 ATTRIBUTES
363 388
 
364 389
 L<Mojo::JSON> implements the following attributes.
365 390
 
366
-=head2 C<error>
391
+=head2 error
367 392
 
368 393
   my $err = $json->error;
369 394
   $json   = $json->error('Parser error');
... ...
@@ -375,27 +400,28 @@ Parser errors.
375 400
 L<Mojo::JSON> inherits all methods from L<Mojo::Base> and implements the
376 401
 following new ones.
377 402
 
378
-=head2 C<decode>
403
+=head2 decode
379 404
 
380 405
   my $array = $json->decode($bytes);
381 406
   my $hash  = $json->decode($bytes);
382 407
 
383
-Decode JSON.
408
+Decode JSON to Perl data structure and return C<undef> if decoding fails.
384 409
 
385
-=head2 C<encode>
410
+=head2 encode
386 411
 
412
+  my $bytes = $json->encode([1, 2, 3]);
387 413
   my $bytes = $json->encode({foo => 'bar'});
388 414
 
389
-Encode Perl data structure.
415
+Encode Perl data structure to JSON.
390 416
 
391
-=head2 C<false>
417
+=head2 false
392 418
 
393 419
   my $false = Mojo::JSON->false;
394 420
   my $false = $json->false;
395 421
 
396 422
 False value, used because Perl has no native equivalent.
397 423
 
398
-=head2 C<true>
424
+=head2 true
399 425
 
400 426
   my $true = Mojo::JSON->true;
401 427
   my $true = $json->true;
+2 -3
mojolegacy/lib/Mojo/JSON/Pointer.pm
... ...
@@ -10,7 +10,6 @@ sub get      { shift->_pointer(0, @_) }
10 10
 sub _pointer {
11 11
   my ($self, $contains, $data, $pointer) = @_;
12 12
 
13
-  # Parse pointer and walk data structure
14 13
   $pointer = decode('UTF-8', url_unescape $pointer);
15 14
   return $data unless $pointer =~ s!^/!!;
16 15
   for my $p (split '/', $pointer) {
... ...
@@ -52,7 +51,7 @@ L<Mojo::JSON::Pointer> implements JSON Pointers.
52 51
 
53 52
 =head1 METHODS
54 53
 
55
-=head2 C<contains>
54
+=head2 contains
56 55
 
57 56
   my $success = $pointer->contains($data, '/foo/1');
58 57
 
... ...
@@ -67,7 +66,7 @@ JSON Pointer.
67 66
   $pointer->contains({foo => 'bar', baz => [4, 5, 6]}, '/bar');
68 67
   $pointer->contains({foo => 'bar', baz => [4, 5, 6]}, '/baz/9');
69 68
 
70
-=head2 C<get>
69
+=head2 get
71 70
 
72 71
   my $value = $pointer->get($data, '/foo/bar');
73 72
 
+4 -8
mojolegacy/lib/Mojo/Loader.pm
... ...
@@ -6,7 +6,6 @@ use File::Spec::Functions qw(catdir catfile splitdir);
6 6
 use Mojo::Exception;
7 7
 use Mojo::Util qw(b64_decode class_to_path);
8 8
 
9
-# Cache
10 9
 my %CACHE;
11 10
 
12 11
 sub data {
... ...
@@ -34,7 +33,6 @@ sub load {
34 33
 sub search {
35 34
   my ($self, $namespace) = @_;
36 35
 
37
-  # Check all directories
38 36
   my (@modules, %found);
39 37
   for my $directory (@INC) {
40 38
     next unless -d (my $path = catdir $directory, split(/::|'/, $namespace));
... ...
@@ -43,8 +41,6 @@ sub search {
43 41
     opendir(my $dir, $path);
44 42
     for my $file (grep /\.pm$/, readdir $dir) {
45 43
       next if -d catfile splitdir($path), $file;
46
-
47
-      # Module found
48 44
       my $class = "${namespace}::" . fileparse $file, qr/\.pm/;
49 45
       push @modules, $class unless $found{$class}++;
50 46
     }
... ...
@@ -69,7 +65,7 @@ sub _all {
69 65
   # Ignore everything after __END__
70 66
   $content =~ s/\n__END__\r?\n.*$/\n/s;
71 67
 
72
-  # Split
68
+  # Split files
73 69
   my @data = split /^@@\s*(.+?)\s*\r?\n/m, $content;
74 70
   shift @data;
75 71
 
... ...
@@ -115,7 +111,7 @@ L<Mojo::Loader> is a class loader and plugin framework.
115 111
 L<Mojo::Loader> inherits all methods from L<Mojo::Base> and implements the
116 112
 following new ones.
117 113
 
118
-=head2 C<data>
114
+=head2 data
119 115
 
120 116
   my $all   = $loader->data('Foo::Bar');
121 117
   my $index = $loader->data('Foo::Bar', 'index.html');
... ...
@@ -124,7 +120,7 @@ Extract embedded file from the C<DATA> section of a class.
124 120
 
125 121
   say for keys %{$loader->data('Foo::Bar')};
126 122
 
127
-=head2 C<load>
123
+=head2 load
128 124
 
129 125
   my $e = $loader->load('Foo::Bar');
130 126
 
... ...
@@ -135,7 +131,7 @@ method to see if they are already loaded.
135 131
     die ref $e ? "Exception: $e" : 'Already loaded!';
136 132
   }
137 133
 
138
-=head2 C<search>
134
+=head2 search
139 135
 
140 136
   my $modules = $loader->search('MyApp::Namespace');
141 137
 
+25 -26
mojolegacy/lib/Mojo/Log.pm
... ...
@@ -59,10 +59,8 @@ sub warn { shift->log(warn => @_) }
59 59
 sub _message {
60 60
   my ($self, $level, @lines) = @_;
61 61
 
62
-  # Check level
63 62
   return unless $self->is_level($level) && (my $handle = $self->handle);
64 63
 
65
-  # Format lines and write to handle
66 64
   flock $handle, LOCK_EX;
67 65
   croak "Can't write to log: $!"
68 66
     unless defined $handle->syswrite($self->format($level, @lines));
... ...
@@ -98,9 +96,10 @@ L<Mojo::Log> is a simple logger for L<Mojo> projects.
98 96
 
99 97
 =head1 EVENTS
100 98
 
101
-L<Mojo::Log> can emit the following events.
99
+L<Mojo::Log> inherits all events from L<Mojo::EventEmitter> and can emit the
100
+following new ones.
102 101
 
103
-=head2 C<message>
102
+=head2 message
104 103
 
105 104
   $log->on(message => sub {
106 105
     my ($log, $level, @lines) = @_;
... ...
@@ -119,7 +118,7 @@ Emitted when a new message gets logged.
119 118
 
120 119
 L<Mojo::Log> implements the following attributes.
121 120
 
122
-=head2 C<handle>
121
+=head2 handle
123 122
 
124 123
   my $handle = $log->handle;
125 124
   $log       = $log->handle(IO::Handle->new);
... ...
@@ -127,7 +126,7 @@ L<Mojo::Log> implements the following attributes.
127 126
 Log file handle used by default C<message> event, defaults to opening C<path>
128 127
 or C<STDERR>.
129 128
 
130
-=head2 C<level>
129
+=head2 level
131 130
 
132 131
   my $level = $log->level;
133 132
   $log      = $log->level('debug');
... ...
@@ -139,19 +138,19 @@ These levels are currently available:
139 138
 
140 139
 =over 2
141 140
 
142
-=item C<debug>
141
+=item debug
143 142
 
144
-=item C<info>
143
+=item info
145 144
 
146
-=item C<warn>
145
+=item warn
147 146
 
148
-=item C<error>
147
+=item error
149 148
 
150
-=item C<fatal>
149
+=item fatal
151 150
 
152 151
 =back
153 152
 
154
-=head2 C<path>
153
+=head2 path
155 154
 
156 155
   my $path = $log->path
157 156
   $log     = $log->path('/var/log/mojo.log');
... ...
@@ -163,87 +162,87 @@ Log file path used by C<handle>.
163 162
 L<Mojo::Log> inherits all methods from L<Mojo::EventEmitter> and implements
164 163
 the following new ones.
165 164
 
166
-=head2 C<new>
165
+=head2 new
167 166
 
168 167
   my $log = Mojo::Log->new;
169 168
 
170 169
 Construct a new L<Mojo::Log> object and subscribe to C<message> event with
171 170
 default logger.
172 171
 
173
-=head2 C<debug>
172
+=head2 debug
174 173
 
175 174
   $log = $log->debug('You screwed up, but that is ok');
176 175
 
177 176
 Log debug message.
178 177
 
179
-=head2 C<error>
178
+=head2 error
180 179
 
181 180
   $log = $log->error('You really screwed up this time');
182 181
 
183 182
 Log error message.
184 183
 
185
-=head2 C<fatal>
184
+=head2 fatal
186 185
 
187 186
   $log = $log->fatal('Its over...');
188 187
 
189 188
 Log fatal message.
190 189
 
191
-=head2 C<format>
190
+=head2 format
192 191
 
193 192
   my $msg = $log->format('debug', 'Hi there!');
194 193
   my $msg = $log->format('debug', 'Hi', 'there!');
195 194
 
196 195
 Format log message.
197 196
 
198
-=head2 C<info>
197
+=head2 info
199 198
 
200 199
   $log = $log->info('You are bad, but you prolly know already');
201 200
 
202 201
 Log info message.
203 202
 
204
-=head2 C<is_level>
203
+=head2 is_level
205 204
 
206 205
   my $success = $log->is_level('debug');
207 206
 
208 207
 Check log level.
209 208
 
210
-=head2 C<is_debug>
209
+=head2 is_debug
211 210
 
212 211
   my $success = $log->is_debug;
213 212
 
214 213
 Check for debug log level.
215 214
 
216
-=head2 C<is_error>
215
+=head2 is_error
217 216
 
218 217
   my $success = $log->is_error;
219 218
 
220 219
 Check for error log level.
221 220
 
222
-=head2 C<is_fatal>
221
+=head2 is_fatal
223 222
 
224 223
   my $success = $log->is_fatal;
225 224
 
226 225
 Check for fatal log level.
227 226
 
228
-=head2 C<is_info>
227
+=head2 is_info
229 228
 
230 229
   my $success = $log->is_info;
231 230
 
232 231
 Check for info log level.
233 232
 
234
-=head2 C<is_warn>
233
+=head2 is_warn
235 234
 
236 235
   my $success = $log->is_warn;
237 236
 
238 237
 Check for warn log level.
239 238
 
240
-=head2 C<log>
239
+=head2 log
241 240
 
242 241
   $log = $log->log(debug => 'This should work');
243 242
 
244 243
 Emit C<message> event.
245 244
 
246
-=head2 C<warn>
245
+=head2 warn
247 246
 
248 247
   $log = $log->warn('Dont do that Dave...');
249 248
 
+66 -88
mojolegacy/lib/Mojo/Message.pm
... ...
@@ -43,10 +43,7 @@ sub body {
43 43
 sub body_params {
44 44
   my $self = shift;
45 45
 
46
-  # Cached
47 46
   return $self->{body_params} if $self->{body_params};
48
-
49
-  # Charset
50 47
   my $params = $self->{body_params} = Mojo::Parameters->new;
51 48
   $params->charset($self->content->charset || $self->default_charset);
52 49
 
... ...
@@ -59,15 +56,9 @@ sub body_params {
59 56
   # "multipart/formdata"
60 57
   elsif ($type =~ m!multipart/form-data!i) {
61 58
     my $formdata = $self->_parse_formdata;
62
-
63
-    # Formdata
64 59
     for my $data (@$formdata) {
65 60
       my ($name, $filename, $value) = @$data;
66
-
67
-      # File
68 61
       next if defined $filename;
69
-
70
-      # Form value
71 62
       $params->append($name, $value);
72 63
     }
73 64
   }
... ...
@@ -143,14 +134,9 @@ sub fix_headers {
143 134
 sub get_body_chunk {
144 135
   my ($self, $offset) = @_;
145 136
 
146
-  # Progress
147 137
   $self->emit('progress', 'body', $offset);
148
-
149
-  # Chunk
150 138
   my $chunk = $self->content->get_body_chunk($offset);
151 139
   return $chunk if !defined $chunk || length $chunk;
152
-
153
-  # Finish
154 140
   $self->finish;
155 141
 
156 142
   return $chunk;
... ...
@@ -197,9 +183,10 @@ sub param { shift->body_params->param(@_) }
197 183
 sub parse {
198 184
   my ($self, $chunk) = @_;
199 185
 
200
-  # Check message size and add chunk
186
+  # Check message size
201 187
   return $self->error('Maximum message size exceeded', 413)
202 188
     if ($self->{raw_size} += length($chunk = defined $chunk ? $chunk : '')) > $self->max_message_size;
189
+
203 190
   $self->{buffer} .= $chunk;
204 191
 
205 192
   # Start line
... ...
@@ -211,7 +198,6 @@ sub parse {
211 198
     return $self->error('Maximum line size exceeded', 431)
212 199
       if $len > $self->max_line_size;
213 200
 
214
-    # Extract
215 201
     $self->{state} = 'content' if $self->extract_start_line(\$self->{buffer});
216 202
   }
217 203
 
... ...
@@ -227,7 +213,6 @@ sub parse {
227 213
   return $self->error('Maximum buffer size exceeded', 400)
228 214
     if $self->content->is_limit_exceeded;
229 215
 
230
-  # Progress
231 216
   return $self->emit('progress')->content->is_finished ? $self->finish : $self;
232 217
 }
233 218
 
... ...
@@ -249,11 +234,7 @@ sub upload {
249 234
 sub uploads {
250 235
   my $self = shift;
251 236
 
252
-  # Only multipart messages have uploads
253 237
   my @uploads;
254
-  return \@uploads unless $self->is_multipart;
255
-
256
-  # Extract formdata
257 238
   my $formdata = $self->_parse_formdata;
258 239
   for my $data (@$formdata) {
259 240
     my ($name, $filename, $part) = @$data;
... ...
@@ -280,7 +261,6 @@ sub write_chunk { shift->_write(write_chunk => @_) }
280 261
 sub _build {
281 262
   my ($self, $method) = @_;
282 263
 
283
-  # Build part from chunks
284 264
   my $buffer = '';
285 265
   my $offset = 0;
286 266
   while (1) {
... ...
@@ -291,7 +271,6 @@ sub _build {
291 271
     # End of part
292 272
     last unless my $len = length $chunk;
293 273
 
294
-    # Part
295 274
     $offset += $len;
296 275
     $buffer .= $chunk;
297 276
   }
... ...
@@ -323,37 +302,35 @@ sub _nest {
323 302
 sub _parse_formdata {
324 303
   my $self = shift;
325 304
 
326
-  # Check content
305
+  # Check for multipart content
327 306
   my @formdata;
328 307
   my $content = $self->content;
329 308
   return \@formdata unless $content->is_multipart;
330 309
   my $charset = $content->charset || $self->default_charset;
331 310
 
332
-  # Walk the tree
311
+  # Check all parts for form data
333 312
   my @parts;
334 313
   push @parts, $content;
335 314
   while (my $part = shift @parts) {
336 315
 
337
-    # Multipart
316
+    # Nested multipart content
338 317
     if ($part->is_multipart) {
339 318
       unshift @parts, @{$part->parts};
340 319
       next;
341 320
     }
342 321
 
343
-    # Content-Disposition header
322
+    # Extract information from Content-Disposition header
344 323
     my $disposition = $part->headers->content_disposition;
345 324
     next unless $disposition;
346 325
     my ($name)     = $disposition =~ /[; ]name="?([^";]+)"?/;
347 326
     my ($filename) = $disposition =~ /[; ]filename="?([^"]*)"?/;
348
-    my $value      = $part;
349
-
350
-    # Decode
351 327
     if ($charset) {
352 328
       $name     = do {my $tmp = decode($charset, $name); defined $tmp ? $tmp : $name} if $name;
353 329
       $filename = do {my $tmp = decode($charset, $filename); defined $tmp ? $tmp : $filename} if $filename;
354 330
     }
355 331
 
356
-    # Form value
332
+    # Check for file upload
333
+    my $value = $part;
357 334
     unless (defined $filename) {
358 335
       $value = $part->asset->slurp;
359 336
       $value = do {my $tmp = decode($charset, $value); defined $tmp ? $tmp : $value} if $charset;
... ...
@@ -394,9 +371,10 @@ RFC 2616 and RFC 2388.
394 371
 
395 372
 =head1 EVENTS
396 373
 
397
-L<Mojo::Message> can emit the following events.
374
+L<Mojo::Message> inherits all events from L<Mojo::EventEmitter> and can emit
375
+the following new ones.
398 376
 
399
-=head2 C<finish>
377
+=head2 finish
400 378
 
401 379
   $msg->on(finish => sub {
402 380
     my $msg = shift;
... ...
@@ -411,7 +389,7 @@ Emitted after message building or parsing is finished.
411 389
     $msg->headers->header('X-Parser-Time' => time - $before);
412 390
   });
413 391
 
414
-=head2 C<progress>
392
+=head2 progress
415 393
 
416 394
   $msg->on(progress => sub {
417 395
     my $msg = shift;
... ...
@@ -438,21 +416,21 @@ Emitted when message building or parsing makes progress.
438 416
 
439 417
 L<Mojo::Message> implements the following attributes.
440 418
 
441
-=head2 C<content>
419
+=head2 content
442 420
 
443 421
   my $msg = $msg->content;
444 422
   $msg    = $msg->content(Mojo::Content::Single->new);
445 423
 
446 424
 Message content, defaults to a L<Mojo::Content::Single> object.
447 425
 
448
-=head2 C<default_charset>
426
+=head2 default_charset
449 427
 
450 428
   my $charset = $msg->default_charset;
451 429
   $msg        = $msg->default_charset('UTF-8');
452 430
 
453 431
 Default charset used for form data parsing, defaults to C<UTF-8>.
454 432
 
455
-=head2 C<max_line_size>
433
+=head2 max_line_size
456 434
 
457 435
   my $size = $msg->max_line_size;
458 436
   $msg     = $msg->max_line_size(1024);
... ...
@@ -460,7 +438,7 @@ Default charset used for form data parsing, defaults to C<UTF-8>.
460 438
 Maximum start line size in bytes, defaults to the value of the
461 439
 C<MOJO_MAX_LINE_SIZE> environment variable or C<10240>.
462 440
 
463
-=head2 C<max_message_size>
441
+=head2 max_message_size
464 442
 
465 443
   my $size = $msg->max_message_size;
466 444
   $msg     = $msg->max_message_size(1024);
... ...
@@ -471,7 +449,7 @@ increasing this value can also drastically increase memory usage, should you
471 449
 for example attempt to parse an excessively large message body with the
472 450
 C<body_params>, C<dom> or C<json> methods.
473 451
 
474
-=head2 C<version>
452
+=head2 version
475 453
 
476 454
   my $version = $msg->version;
477 455
   $msg        = $msg->version('1.1');
... ...
@@ -483,20 +461,20 @@ HTTP version of message, defaults to C<1.1>.
483 461
 L<Mojo::Message> inherits all methods from L<Mojo::EventEmitter> and
484 462
 implements the following new ones.
485 463
 
486
-=head2 C<body>
464
+=head2 body
487 465
 
488
-  my $string = $msg->body;
489
-  $msg       = $msg->body('Hello!');
490
-  my $cb     = $msg->body(sub {...});
466
+  my $bytes = $msg->body;
467
+  $msg      = $msg->body('Hello!');
468
+  my $cb    = $msg->body(sub {...});
491 469
 
492 470
 Access C<content> data or replace all subscribers of the C<read> event.
493 471
 
494 472
   $msg->body(sub {
495
-    my ($msg, $chunk) = @_;
496
-    say "Streaming: $chunk";
473
+    my ($msg, $bytes) = @_;
474
+    say "Streaming: $bytes";
497 475
   });
498 476
 
499
-=head2 C<body_params>
477
+=head2 body_params
500 478
 
501 479
   my $params = $msg->body_params;
502 480
 
... ...
@@ -508,31 +486,31 @@ so it should not be called before the entire message body has been received.
508 486
   # Get POST parameter value
509 487
   say $msg->body_params->param('foo');
510 488
 
511
-=head2 C<body_size>
489
+=head2 body_size
512 490
 
513 491
   my $size = $msg->body_size;
514 492
 
515 493
 Content size in bytes.
516 494
 
517
-=head2 C<build_body>
495
+=head2 build_body
518 496
 
519
-  my $string = $msg->build_body;
497
+  my $bytes = $msg->build_body;
520 498
 
521 499
 Render whole body.
522 500
 
523
-=head2 C<build_headers>
501
+=head2 build_headers
524 502
 
525
-  my $string = $msg->build_headers;
503
+  my $bytes = $msg->build_headers;
526 504
 
527 505
 Render all headers.
528 506
 
529
-=head2 C<build_start_line>
507
+=head2 build_start_line
530 508
 
531
-  my $string = $msg->build_start_line;
509
+  my $bytes = $msg->build_start_line;
532 510
 
533 511
 Render start line.
534 512
 
535
-=head2 C<cookie>
513
+=head2 cookie
536 514
 
537 515
   my $cookie  = $msg->cookie('foo');
538 516
   my @cookies = $msg->cookie('foo');
... ...
@@ -544,13 +522,13 @@ it should not be called before all headers have been received.
544 522
   # Get cookie value
545 523
   say $msg->cookie('foo')->value;
546 524
 
547
-=head2 C<cookies>
525
+=head2 cookies
548 526
 
549 527
   my $cookies = $msg->cookies;
550 528
 
551 529
 Access message cookies. Meant to be overloaded in a subclass.
552 530
 
553
-=head2 C<dom>
531
+=head2 dom
554 532
 
555 533
   my $dom        = $msg->dom;
556 534
   my $collection = $msg->dom('a[href]');
... ...
@@ -567,7 +545,7 @@ before the entire message body has been received.
567 545
   say $msg->dom->at('title')->text;
568 546
   say $msg->dom->html->body->children->pluck('type')->uniq;
569 547
 
570
-=head2 C<error>
548
+=head2 error
571 549
 
572 550
   my $err          = $msg->error;
573 551
   my ($err, $code) = $msg->error;
... ...
@@ -576,93 +554,93 @@ before the entire message body has been received.
576 554
 
577 555
 Error and code.
578 556
 
579
-=head2 C<extract_start_line>
557
+=head2 extract_start_line
580 558
 
581 559
   my $success = $msg->extract_start_line(\$string);
582 560
 
583 561
 Extract start line from string. Meant to be overloaded in a subclass.
584 562
 
585
-=head2 C<finish>
563
+=head2 finish
586 564
 
587 565
   $msg = $msg->finish;
588 566
 
589 567
 Finish message parser/generator.
590 568
 
591
-=head2 C<fix_headers>
569
+=head2 fix_headers
592 570
 
593 571
   $msg = $msg->fix_headers;
594 572
 
595 573
 Make sure message has all required headers.
596 574
 
597
-=head2 C<get_body_chunk>
575
+=head2 get_body_chunk
598 576
 
599
-  my $string = $msg->get_body_chunk($offset);
577
+  my $bytes = $msg->get_body_chunk($offset);
600 578
 
601 579
 Get a chunk of body data starting from a specific position.
602 580
 
603
-=head2 C<get_header_chunk>
581
+=head2 get_header_chunk
604 582
 
605
-  my $string = $msg->get_header_chunk($offset);
583
+  my $bytes = $msg->get_header_chunk($offset);
606 584
 
607 585
 Get a chunk of header data, starting from a specific position.
608 586
 
609
-=head2 C<get_start_line_chunk>
587
+=head2 get_start_line_chunk
610 588
 
611
-  my $string = $msg->get_start_line_chunk($offset);
589
+  my $bytes = $msg->get_start_line_chunk($offset);
612 590
 
613 591
 Get a chunk of start line data starting from a specific position. Meant to be
614 592
 overloaded in a subclass.
615 593
 
616
-=head2 C<has_leftovers>
594
+=head2 has_leftovers
617 595
 
618 596
   my $success = $msg->has_leftovers;
619 597
 
620 598
 Check if there are leftovers.
621 599
 
622
-=head2 C<header_size>
600
+=head2 header_size
623 601
 
624 602
   my $size = $msg->header_size;
625 603
 
626 604
 Size of headers in bytes.
627 605
 
628
-=head2 C<headers>
606
+=head2 headers
629 607
 
630 608
   my $headers = $msg->headers;
631 609
 
632 610
 Message headers, usually a L<Mojo::Headers> object.
633 611
 
634
-=head2 C<is_chunked>
612
+=head2 is_chunked
635 613
 
636 614
   my $success = $msg->is_chunked;
637 615
 
638 616
 Check if content is chunked.
639 617
 
640
-=head2 C<is_dynamic>
618
+=head2 is_dynamic
641 619
 
642 620
   my $success = $msg->is_dynamic;
643 621
 
644 622
 Check if content will be dynamically generated, which prevents C<clone> from
645 623
 working.
646 624
 
647
-=head2 C<is_finished>
625
+=head2 is_finished
648 626
 
649 627
   my $success = $msg->is_finished;
650 628
 
651 629
 Check if message parser/generator is finished.
652 630
 
653
-=head2 C<is_limit_exceeded>
631
+=head2 is_limit_exceeded
654 632
 
655 633
   my $success = $msg->is_limit_exceeded;
656 634
 
657 635
 Check if message has exceeded C<max_line_size> or C<max_message_size>.
658 636
 
659
-=head2 C<is_multipart>
637
+=head2 is_multipart
660 638
 
661 639
   my $success = $msg->is_multipart;
662 640
 
663 641
 Check if content is a L<Mojo::Content::MultiPart> object.
664 642
 
665
-=head2 C<json>
643
+=head2 json
666 644
 
667 645
   my $hash  = $msg->json;
668 646
   my $array = $msg->json;
... ...
@@ -677,13 +655,13 @@ it should not be called before the entire message body has been received.
677 655
   say $msg->json->{foo}{bar}[23];
678 656
   say $msg->json('/foo/bar/23');
679 657
 
680
-=head2 C<leftovers>
658
+=head2 leftovers
681 659
 
682 660
   my $bytes = $msg->leftovers;
683 661
 
684 662
 Get leftover data from content parser.
685 663
 
686
-=head2 C<param>
664
+=head2 param
687 665
 
688 666
   my @names = $msg->param;
689 667
   my $foo   = $msg->param('foo');
... ...
@@ -692,25 +670,25 @@ Get leftover data from content parser.
692 670
 Access C<POST> parameters. Note that this method caches all data, so it should
693 671
 not be called before the entire message body has been received.
694 672
 
695
-=head2 C<parse>
673
+=head2 parse
696 674
 
697 675
   $msg = $msg->parse('HTTP/1.1 200 OK...');
698 676
 
699 677
 Parse message chunk.
700 678
 
701
-=head2 C<start_line_size>
679
+=head2 start_line_size
702 680
 
703 681
   my $size = $msg->start_line_size;
704 682
 
705 683
 Size of the start line in bytes.
706 684
 
707
-=head2 C<to_string>
685
+=head2 to_string
708 686
 
709 687
   my $string = $msg->to_string;
710 688
 
711 689
 Render whole message.
712 690
 
713
-=head2 C<upload>
691
+=head2 upload
714 692
 
715 693
   my $upload  = $msg->upload('foo');
716 694
   my @uploads = $msg->upload('foo');
... ...
@@ -722,24 +700,24 @@ entire message body has been received.
722 700
   # Get content of uploaded file
723 701
   say $msg->upload('foo')->asset->slurp;
724 702
 
725
-=head2 C<uploads>
703
+=head2 uploads
726 704
 
727 705
   my $uploads = $msg->uploads;
728 706
 
729 707
 All C<multipart/form-data> file uploads, usually L<Mojo::Upload> objects.
730 708
 
731
-=head2 C<write>
709
+=head2 write
732 710
 
733
-  $msg = $msg->write('Hello!');
734
-  $msg = $msg->write('Hello!' => sub {...});
711
+  $msg = $msg->write($bytes);
712
+  $msg = $msg->write($bytes => sub {...});
735 713
 
736 714
 Write dynamic content non-blocking, the optional drain callback will be
737 715
 invoked once all data has been written.
738 716
 
739
-=head2 C<write_chunk>
717
+=head2 write_chunk
740 718
 
741
-  $msg = $msg->write_chunk('Hello!');
742
-  $msg = $msg->write_chunk('Hello!' => sub {...});
719
+  $msg = $msg->write_chunk($bytes);
720
+  $msg = $msg->write_chunk($bytes => sub {...});
743 721
 
744 722
 Write dynamic content non-blocking with C<chunked> transfer encoding, the
745 723
 optional drain callback will be invoked once all data has been written.
+19 -23
mojolegacy/lib/Mojo/Message/Request.pm
... ...
@@ -55,11 +55,11 @@ sub cookies {
55 55
 }
56 56
 
57 57
 sub extract_start_line {
58
-  my ($self, $bufferref) = @_;
58
+  my ($self, $bufref) = @_;
59 59
 
60 60
   # Ignore any leading empty lines
61
-  $$bufferref =~ s/^\s+//;
62
-  return undef unless defined(my $line = get_line $bufferref);
61
+  $$bufref =~ s/^\s+//;
62
+  return undef unless defined(my $line = get_line $bufref);
63 63
 
64 64
   # We have a (hopefully) full request line
65 65
   $self->error('Bad request start line', 400) and return undef
... ...
@@ -100,7 +100,6 @@ sub fix_headers {
100 100
 sub get_start_line_chunk {
101 101
   my ($self, $offset) = @_;
102 102
 
103
-  # Request line
104 103
   unless (defined $self->{start_buffer}) {
105 104
 
106 105
     # Path
... ...
@@ -128,10 +127,7 @@ sub get_start_line_chunk {
128 127
     $self->{start_buffer} = "$method $path HTTP/@{[$self->version]}\x0d\x0a";
129 128
   }
130 129
 
131
-  # Progress
132 130
   $self->emit(progress => 'start_line', $offset);
133
-
134
-  # Chunk
135 131
   return substr $self->{start_buffer}, $offset, 131072;
136 132
 }
137 133
 
... ...
@@ -306,7 +302,7 @@ L<Mojo::Message::Request> inherits all events from L<Mojo::Message>.
306 302
 L<Mojo::Message::Request> inherits all attributes from L<Mojo::Message> and
307 303
 implements the following new ones.
308 304
 
309
-=head2 C<env>
305
+=head2 env
310 306
 
311 307
   my $env = $req->env;
312 308
   $req    = $req->env({});
... ...
@@ -319,14 +315,14 @@ Direct access to the C<CGI> or C<PSGI> environment hash if available.
319 315
   # Check PSGI version
320 316
   my $version = $req->env->{'psgi.version'};
321 317
 
322
-=head2 C<method>
318
+=head2 method
323 319
 
324 320
   my $method = $req->method;
325 321
   $req       = $req->method('POST');
326 322
 
327 323
 HTTP request method, defaults to C<GET>.
328 324
 
329
-=head2 C<url>
325
+=head2 url
330 326
 
331 327
   my $url = $req->url;
332 328
   $req    = $req->url(Mojo::URL->new);
... ...
@@ -341,13 +337,13 @@ HTTP request URL, defaults to a L<Mojo::URL> object.
341 337
 L<Mojo::Message::Request> inherits all methods from L<Mojo::Message> and
342 338
 implements the following new ones.
343 339
 
344
-=head2 C<clone>
340
+=head2 clone
345 341
 
346 342
   my $clone = $req->clone;
347 343
 
348 344
 Clone request if possible, otherwise return C<undef>.
349 345
 
350
-=head2 C<cookies>
346
+=head2 cookies
351 347
 
352 348
   my $cookies = $req->cookies;
353 349
   $req        = $req->cookies(Mojo::Cookie::Request->new);
... ...
@@ -355,37 +351,37 @@ Clone request if possible, otherwise return C<undef>.
355 351
 
356 352
 Access request cookies, usually L<Mojo::Cookie::Request> objects.
357 353
 
358
-=head2 C<extract_start_line>
354
+=head2 extract_start_line
359 355
 
360 356
   my $success = $req->extract_start_line(\$string);
361 357
 
362 358
 Extract request line from string.
363 359
 
364
-=head2 C<fix_headers>
360
+=head2 fix_headers
365 361
 
366 362
   $req = $req->fix_headers;
367 363
 
368 364
 Make sure request has all required headers.
369 365
 
370
-=head2 C<get_start_line_chunk>
366
+=head2 get_start_line_chunk
371 367
 
372
-  my $string = $req->get_start_line_chunk($offset);
368
+  my $bytes = $req->get_start_line_chunk($offset);
373 369
 
374 370
 Get a chunk of request line data starting from a specific position.
375 371
 
376
-=head2 C<is_secure>
372
+=head2 is_secure
377 373
 
378 374
   my $success = $req->is_secure;
379 375
 
380 376
 Check if connection is secure.
381 377
 
382
-=head2 C<is_xhr>
378
+=head2 is_xhr
383 379
 
384 380
   my $success = $req->is_xhr;
385 381
 
386 382
 Check C<X-Requested-With> header for C<XMLHttpRequest> value.
387 383
 
388
-=head2 C<param>
384
+=head2 param
389 385
 
390 386
   my @names = $req->param;
391 387
   my $foo   = $req->param('foo');
... ...
@@ -394,7 +390,7 @@ Check C<X-Requested-With> header for C<XMLHttpRequest> value.
394 390
 Access C<GET> and C<POST> parameters. Note that this method caches all data,
395 391
 so it should not be called before the entire request body has been received.
396 392
 
397
-=head2 C<params>
393
+=head2 params
398 394
 
399 395
   my $params = $req->params;
400 396
 
... ...
@@ -405,7 +401,7 @@ request body has been received.
405 401
   # Get parameter value
406 402
   say $req->params->param('foo');
407 403
 
408
-=head2 C<parse>
404
+=head2 parse
409 405
 
410 406
   $req = $req->parse('GET /foo/bar HTTP/1.1');
411 407
   $req = $req->parse(REQUEST_METHOD => 'GET');
... ...
@@ -413,7 +409,7 @@ request body has been received.
413 409
 
414 410
 Parse HTTP request chunks or environment hash.
415 411
 
416
-=head2 C<proxy>
412
+=head2 proxy
417 413
 
418 414
   my $proxy = $req->proxy;
419 415
   $req      = $req->proxy('http://foo:bar@127.0.0.1:3000');
... ...
@@ -424,7 +420,7 @@ Proxy URL for request.
424 420
   # Disable proxy
425 421
   $req->proxy(0);
426 422
 
427
-=head2 C<query_params>
423
+=head2 query_params
428 424
 
429 425
   my $params = $req->query_params;
430 426
 
+12 -16
mojolegacy/lib/Mojo/Message/Response.pm
... ...
@@ -92,10 +92,10 @@ sub cookies {
92 92
 sub default_message { $MESSAGES{$_[1] || $_[0]->code || 404} || '' }
93 93
 
94 94
 sub extract_start_line {
95
-  my ($self, $bufferref) = @_;
95
+  my ($self, $bufref) = @_;
96 96
 
97 97
   # We have a full response line
98
-  return undef unless defined(my $line = get_line $bufferref);
98
+  return undef unless defined(my $line = get_line $bufref);
99 99
   $self->error('Bad response start line') and return undef
100 100
     unless $line =~ m!^\s*HTTP/(\d\.\d)\s+(\d\d\d)\s*(.+)?$!;
101 101
   $self->content->skip_body(1) if $self->code($2)->is_empty;
... ...
@@ -116,17 +116,13 @@ sub fix_headers {
116 116
 sub get_start_line_chunk {
117 117
   my ($self, $offset) = @_;
118 118
 
119
-  # Status line
120 119
   unless (defined $self->{start_buffer}) {
121 120
     my $code = $self->code    || 404;
122 121
     my $msg  = $self->message || $self->default_message;
123 122
     $self->{start_buffer} = "HTTP/@{[$self->version]} $code $msg\x0d\x0a";
124 123
   }
125 124
 
126
-  # Progress
127 125
   $self->emit(progress => 'start_line', $offset);
128
-
129
-  # Chunk
130 126
   return substr $self->{start_buffer}, $offset, 131072;
131 127
 }
132 128
 
... ...
@@ -183,14 +179,14 @@ L<Mojo::Message::Response> inherits all events from L<Mojo::Message>.
183 179
 L<Mojo::Message::Response> inherits all attributes from L<Mojo::Message> and
184 180
 implements the following new ones.
185 181
 
186
-=head2 C<code>
182
+=head2 code
187 183
 
188 184
   my $code = $res->code;
189 185
   $res     = $res->code(200);
190 186
 
191 187
 HTTP response code.
192 188
 
193
-=head2 C<message>
189
+=head2 message
194 190
 
195 191
   my $msg = $res->message;
196 192
   $res    = $res->message('OK');
... ...
@@ -202,7 +198,7 @@ HTTP response message.
202 198
 L<Mojo::Message::Response> inherits all methods from L<Mojo::Message> and
203 199
 implements the following new ones.
204 200
 
205
-=head2 C<cookies>
201
+=head2 cookies
206 202
 
207 203
   my $cookies = $res->cookies;
208 204
   $res        = $res->cookies(Mojo::Cookie::Response->new);
... ...
@@ -210,37 +206,37 @@ implements the following new ones.
210 206
 
211 207
 Access response cookies, usually L<Mojo::Cookie::Response> objects.
212 208
 
213
-=head2 C<default_message>
209
+=head2 default_message
214 210
 
215 211
   my $msg = $res->default_message;
216 212
 
217 213
 Generate default response message for code.
218 214
 
219
-=head2 C<extract_start_line>
215
+=head2 extract_start_line
220 216
 
221 217
   my $success = $req->extract_start_line(\$string);
222 218
 
223 219
 Extract status line from string.
224 220
 
225
-=head2 C<fix_headers>
221
+=head2 fix_headers
226 222
 
227 223
   $res = $res->fix_headers;
228 224
 
229 225
 Make sure response has all required headers.
230 226
 
231
-=head2 C<get_start_line_chunk>
227
+=head2 get_start_line_chunk
232 228
 
233
-  my $string = $res->get_start_line_chunk($offset);
229
+  my $bytes = $res->get_start_line_chunk($offset);
234 230
 
235 231
 Get a chunk of status line data starting from a specific position.
236 232
 
237
-=head2 C<is_empty>
233
+=head2 is_empty
238 234
 
239 235
   my $success = $res->is_empty;
240 236
 
241 237
 Check if this is a C<1xx>, C<204> or C<304> response.
242 238
 
243
-=head2 C<is_status_class>
239
+=head2 is_status_class
244 240
 
245 241
   my $success = $res->is_status_class(200);
246 242
 
+13 -20
mojolegacy/lib/Mojo/Parameters.pm
... ...
@@ -88,16 +88,12 @@ sub params {
88 88
     # W3C suggests to also accept ";" as a separator
89 89
     my $charset = $self->charset;
90 90
     for my $pair (split /[\&\;]+/, $string) {
91
-
92
-      # Parse
93 91
       $pair =~ /^([^=]*)(?:=(.*))?$/;
94 92
       my $name  = defined $1 ? $1 : '';
95 93
       my $value = defined $2 ? $2 : '';
96 94
 
97
-      # Replace "+" with whitespace
95
+      # Replace "+" with whitespace, unescape and decode
98 96
       s/\+/ /g for $name, $value;
99
-
100
-      # Unescape
101 97
       $name  = url_unescape $name;
102 98
       $name  = do { my $tmp = decode($charset, $name); defined $tmp ? $tmp : $name } if $charset;
103 99
       $value = url_unescape $value;
... ...
@@ -126,7 +122,6 @@ sub remove {
126 122
   my $self = shift;
127 123
   my $name = do {my $tmp = shift; defined $tmp ? $tmp : ''};
128 124
 
129
-  # Remove
130 125
   my $params = $self->params;
131 126
   for (my $i = 0; $i < @$params;) {
132 127
     if ($params->[$i] eq $name) { splice @$params, $i, 2 }
... ...
@@ -139,7 +134,6 @@ sub remove {
139 134
 sub to_hash {
140 135
   my $self = shift;
141 136
 
142
-  # Format
143 137
   my $params = $self->params;
144 138
   my %hash;
145 139
   for (my $i = 0; $i < @$params; $i += 2) {
... ...
@@ -188,7 +182,6 @@ sub to_string {
188 182
     push @pairs, defined $value ? "$name=$value" : $name;
189 183
   }
190 184
 
191
-  # Concatenate pairs
192 185
   return join $self->pair_separator, @pairs;
193 186
 }
194 187
 
... ...
@@ -218,7 +211,7 @@ L<Mojo::Parameters> is a container for form parameters.
218 211
 
219 212
 L<Mojo::Parameters> implements the following attributes.
220 213
 
221
-=head2 C<charset>
214
+=head2 charset
222 215
 
223 216
   my $charset = $params->charset;
224 217
   $params     = $params->charset('UTF-8');
... ...
@@ -228,7 +221,7 @@ Charset used for encoding and decoding parameters, defaults to C<UTF-8>.
228 221
   # Disable encoding and decoding
229 222
   $params->charset(undef);
230 223
 
231
-=head2 C<pair_separator>
224
+=head2 pair_separator
232 225
 
233 226
   my $separator = $params->pair_separator;
234 227
   $params       = $params->pair_separator(';');
... ...
@@ -240,7 +233,7 @@ Separator for parameter pairs, defaults to C<&>.
240 233
 L<Mojo::Parameters> inherits all methods from L<Mojo::Base> and implements the
241 234
 following new ones.
242 235
 
243
-=head2 C<new>
236
+=head2 new
244 237
 
245 238
   my $params = Mojo::Parameters->new;
246 239
   my $params = Mojo::Parameters->new('foo=b%3Bar&baz=23');
... ...
@@ -250,7 +243,7 @@ following new ones.
250 243
 
251 244
 Construct a new L<Mojo::Parameters> object.
252 245
 
253
-=head2 C<append>
246
+=head2 append
254 247
 
255 248
   $params = $params->append(foo => 'ba;r');
256 249
   $params = $params->append(foo => ['ba;r', 'b;az']);
... ...
@@ -267,19 +260,19 @@ Append parameters.
267 260
   # "foo=bar&foo=baz&foo=yada&bar=23"
268 261
   Mojo::Parameters->new('foo=bar')->append(foo => ['baz', 'yada'], bar => 23);
269 262
 
270
-=head2 C<clone>
263
+=head2 clone
271 264
 
272 265
   my $params2 = $params->clone;
273 266
 
274 267
 Clone parameters.
275 268
 
276
-=head2 C<merge>
269
+=head2 merge
277 270
 
278 271
   $params = $params->merge(Mojo::Parameters->new(foo => 'b;ar', baz => 23));
279 272
 
280 273
 Merge L<Mojo::Parameters> objects.
281 274
 
282
-=head2 C<param>
275
+=head2 param
283 276
 
284 277
   my @names = $params->param;
285 278
   my $foo   = $params->param('foo');
... ...
@@ -289,20 +282,20 @@ Merge L<Mojo::Parameters> objects.
289 282
 
290 283
 Check and replace parameter values.
291 284
 
292
-=head2 C<params>
285
+=head2 params
293 286
 
294 287
   my $array = $params->params;
295 288
   $params   = $params->params([foo => 'b;ar', baz => 23]);
296 289
 
297 290
 Parsed parameters.
298 291
 
299
-=head2 C<parse>
292
+=head2 parse
300 293
 
301 294
   $params = $params->parse('foo=b%3Bar&baz=23');
302 295
 
303 296
 Parse parameters.
304 297
 
305
-=head2 C<remove>
298
+=head2 remove
306 299
 
307 300
   $params = $params->remove('foo');
308 301
 
... ...
@@ -311,7 +304,7 @@ Remove parameters.
311 304
   # "bar=yada"
312 305
   Mojo::Parameters->new('foo=bar&foo=baz&bar=yada')->remove('foo');
313 306
 
314
-=head2 C<to_hash>
307
+=head2 to_hash
315 308
 
316 309
   my $hash = $params->to_hash;
317 310
 
... ...
@@ -320,7 +313,7 @@ Turn parameters into a hash reference.
320 313
   # "baz"
321 314
   Mojo::Parameters->new('foo=bar&foo=baz')->to_hash->{foo}[1];
322 315
 
323
-=head2 C<to_string>
316
+=head2 to_string
324 317
 
325 318
   my $string = $params->to_string;
326 319
   my $string = "$params";
+49 -17
mojolegacy/lib/Mojo/Path.pm
... ...
@@ -16,7 +16,6 @@ sub new { shift->SUPER::new->parse(@_) }
16 16
 sub canonicalize {
17 17
   my $self = shift;
18 18
 
19
-  # Resolve path
20 19
   my @parts;
21 20
   for my $part (@{$self->parts}) {
22 21
 
... ...
@@ -30,7 +29,6 @@ sub canonicalize {
30 29
     # "."
31 30
     next if grep { $_ eq $part } '.', '';
32 31
 
33
-    # Part
34 32
     push @parts, $part;
35 33
   }
36 34
   $self->trailing_slash(undef) unless @parts;
... ...
@@ -83,9 +81,17 @@ sub parse {
83 81
   return $self->parts([split '/', $path, -1]);
84 82
 }
85 83
 
86
-sub to_abs_string {
84
+sub to_abs_string { $_[0]->leading_slash ? "$_[0]" : "/$_[0]" }
85
+
86
+sub to_dir {
87
+  my $clone = shift->clone;
88
+  pop @{$clone->parts} unless $clone->trailing_slash;
89
+  return $clone->trailing_slash(@{$clone->parts} ? 1 : 0);
90
+}
91
+
92
+sub to_route {
87 93
   my $self = shift;
88
-  return $self->leading_slash ? "$self" : "/$self";
94
+  return '/' . join('/', @{$self->parts}) . ($self->trailing_slash ? '/' : '');
89 95
 }
90 96
 
91 97
 sub to_string {
... ...
@@ -104,6 +110,8 @@ sub to_string {
104 110
 
105 111
 1;
106 112
 
113
+=encoding utf8
114
+
107 115
 =head1 NAME
108 116
 
109 117
 Mojo::Path - Path
... ...
@@ -124,7 +132,7 @@ L<Mojo::Path> is a container for URL paths.
124 132
 
125 133
 L<Mojo::Path> implements the following attributes.
126 134
 
127
-=head2 C<charset>
135
+=head2 charset
128 136
 
129 137
   my $charset = $path->charset;
130 138
   $path       = $path->charset('UTF-8');
... ...
@@ -134,14 +142,14 @@ Charset used for encoding and decoding, defaults to C<UTF-8>.
134 142
   # Disable encoding and decoding
135 143
   $path->charset(undef);
136 144
 
137
-=head2 C<leading_slash>
145
+=head2 leading_slash
138 146
 
139 147
   my $leading_slash = $path->leading_slash;
140 148
   $path             = $path->leading_slash(1);
141 149
 
142 150
 Path has a leading slash.
143 151
 
144
-=head2 C<parts>
152
+=head2 parts
145 153
 
146 154
   my $parts = $path->parts;
147 155
   $path     = $path->parts([qw(foo bar baz)]);
... ...
@@ -151,7 +159,7 @@ The path parts.
151 159
   # Part with slash
152 160
   push @{$path->parts}, 'foo/bar';
153 161
 
154
-=head2 C<trailing_slash>
162
+=head2 trailing_slash
155 163
 
156 164
   my $trailing_slash = $path->trailing_slash;
157 165
   $path              = $path->trailing_slash(1);
... ...
@@ -163,14 +171,14 @@ Path has a trailing slash.
163 171
 L<Mojo::Path> inherits all methods from L<Mojo::Base> and implements the
164 172
 following new ones.
165 173
 
166
-=head2 C<new>
174
+=head2 new
167 175
 
168 176
   my $path = Mojo::Path->new;
169 177
   my $path = Mojo::Path->new('/foo%2Fbar%3B/baz.html');
170 178
 
171 179
 Construct a new L<Mojo::Path> object.
172 180
 
173
-=head2 C<canonicalize>
181
+=head2 canonicalize
174 182
 
175 183
   $path = $path->canonicalize;
176 184
 
... ...
@@ -179,15 +187,15 @@ Canonicalize path.
179 187
   # "/foo/baz"
180 188
   Mojo::Path->new('/foo/bar/../baz')->canonicalize;
181 189
 
182
-=head2 C<clone>
190
+=head2 clone
183 191
 
184 192
   my $clone = $path->clone;
185 193
 
186 194
 Clone path.
187 195
 
188
-=head2 C<contains>
196
+=head2 contains
189 197
 
190
-  my $success = $path->contains('/foo');
198
+  my $success = $path->contains('/i/♥/mojolicious');
191 199
 
192 200
 Check if path contains given prefix.
193 201
 
... ...
@@ -201,7 +209,7 @@ Check if path contains given prefix.
201 209
   Mojo::Path->new('/foo/bar')->contains('/bar');
202 210
   Mojo::Path->new('/foo/bar')->contains('/whatever');
203 211
 
204
-=head2 C<merge>
212
+=head2 merge
205 213
 
206 214
   $path = $path->merge('/foo/bar');
207 215
   $path = $path->merge('foo/bar');
... ...
@@ -218,25 +226,49 @@ Merge paths.
218 226
   # "/foo/bar/baz/yada"
219 227
   Mojo::Path->new('/foo/bar/')->merge('baz/yada');
220 228
 
221
-=head2 C<parse>
229
+=head2 parse
222 230
 
223 231
   $path = $path->parse('/foo%2Fbar%3B/baz.html');
224 232
 
225 233
 Parse path. Note that C<%2F> will be treated as C</> for security reasons.
226 234
 
227
-=head2 C<to_abs_string>
235
+=head2 to_abs_string
228 236
 
229 237
   my $string = $path->to_abs_string;
230 238
 
231 239
 Turn path into an absolute string.
232 240
 
233
-=head2 C<to_string>
241
+  # "/i/%E2%99%A5/mojolicious"
242
+  Mojo::Path->new('i/%E2%99%A5/mojolicious')->to_abs_string;
243
+
244
+=head2 to_dir
245
+
246
+  my $dir = $route->to_dir;
247
+
248
+Clone path and remove everything after the right-most slash.
249
+
250
+  # "/i/%E2%99%A5/"
251
+  Mojo::Path->new('i/%E2%99%A5/mojolicious')->to_dir->to_abs_string;
252
+
253
+=head2 to_route
254
+
255
+  my $route = $path->to_route;
256
+
257
+Turn path into a route.
258
+
259
+  # "/i/♥/mojolicious"
260
+  Mojo::Path->new('i/%E2%99%A5/mojolicious')->to_route;
261
+
262
+=head2 to_string
234 263
 
235 264
   my $string = $path->to_string;
236 265
   my $string = "$path";
237 266
 
238 267
 Turn path into a string.
239 268
 
269
+  # "i/%E2%99%A5/mojolicious"
270
+  Mojo::Path->new('i/%E2%99%A5/mojolicious')->to_string;
271
+
240 272
 =head1 SEE ALSO
241 273
 
242 274
 L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
+14 -13
mojolegacy/lib/Mojo/Reactor.pm
... ...
@@ -62,9 +62,10 @@ L<Mojo::Reactor> is an abstract base class for low level event reactors.
62 62
 
63 63
 =head1 EVENTS
64 64
 
65
-L<Mojo::Reactor> can emit the following events.
65
+L<Mojo::Reactor> inherits all events from L<Mojo::EventEmitter> and can emit
66
+the following new ones.
66 67
 
67
-=head2 C<error>
68
+=head2 error
68 69
 
69 70
   $reactor->on(error => sub {
70 71
     my ($reactor, $err) = @_;
... ...
@@ -83,7 +84,7 @@ Emitted safely for exceptions caught in callbacks.
83 84
 L<Mojo::Reactor> inherits all methods from L<Mojo::EventEmitter> and
84 85
 implements the following new ones.
85 86
 
86
-=head2 C<detect>
87
+=head2 detect
87 88
 
88 89
   my $class = Mojo::Reactor->detect;
89 90
 
... ...
@@ -94,7 +95,7 @@ L<Mojo::Reactor::Poll>.
94 95
   # Instantiate best reactor implementation available
95 96
   my $reactor = Mojo::Reactor->detect->new;
96 97
 
97
-=head2 C<io>
98
+=head2 io
98 99
 
99 100
   $reactor = $reactor->io($handle => sub {...});
100 101
 
... ...
@@ -107,20 +108,20 @@ readable or writable. Meant to be overloaded in a subclass.
107 108
     say $writable ? 'Handle is writable' : 'Handle is readable';
108 109
   });
109 110
 
110
-=head2 C<is_readable>
111
+=head2 is_readable
111 112
 
112 113
   my $success = $reactor->is_readable($handle);
113 114
 
114 115
 Quick non-blocking check if a handle is readable, useful for identifying
115 116
 tainted sockets.
116 117
 
117
-=head2 C<is_running>
118
+=head2 is_running
118 119
 
119 120
   my $success = $reactor->is_running;
120 121
 
121 122
 Check if reactor is running. Meant to be overloaded in a subclass.
122 123
 
123
-=head2 C<one_tick>
124
+=head2 one_tick
124 125
 
125 126
   $reactor->one_tick;
126 127
 
... ...
@@ -132,7 +133,7 @@ the reactor, so you need to be careful. Meant to be overloaded in a subclass.
132 133
   $reactor->one_tick;
133 134
   $reactor->remove($id);
134 135
 
135
-=head2 C<recurring>
136
+=head2 recurring
136 137
 
137 138
   my $id = $reactor->recurring(0.25 => sub {...});
138 139
 
... ...
@@ -142,14 +143,14 @@ amount of time in seconds. Meant to be overloaded in a subclass.
142 143
   # Invoke as soon as possible
143 144
   $reactor->recurring(0 => sub { say 'Reactor tick.' });
144 145
 
145
-=head2 C<remove>
146
+=head2 remove
146 147
 
147 148
   my $success = $reactor->remove($handle);
148 149
   my $success = $reactor->remove($id);
149 150
 
150 151
 Remove handle or timer. Meant to be overloaded in a subclass.
151 152
 
152
-=head2 C<start>
153
+=head2 start
153 154
 
154 155
   $reactor->start;
155 156
 
... ...
@@ -157,13 +158,13 @@ Start watching for I/O and timer events, this will block until C<stop> is
157 158
 called. Note that some reactors stop automatically if there are no events
158 159
 being watched anymore. Meant to be overloaded in a subclass.
159 160
 
160
-=head2 C<stop>
161
+=head2 stop
161 162
 
162 163
   $reactor->stop;
163 164
 
164 165
 Stop watching for I/O and timer events. Meant to be overloaded in a subclass.
165 166
 
166
-=head2 C<timer>
167
+=head2 timer
167 168
 
168 169
   my $id = $reactor->timer(0.5 => sub {...});
169 170
 
... ...
@@ -173,7 +174,7 @@ seconds. Meant to be overloaded in a subclass.
173 174
   # Invoke as soon as possible
174 175
   $reactor->timer(0 => sub { say 'Next tick.' });
175 176
 
176
-=head2 C<watch>
177
+=head2 watch
177 178
 
178 179
   $reactor = $reactor->watch($handle, $readable, $writable);
179 180
 
+8 -8
mojolegacy/lib/Mojo/Reactor/EV.pm
... ...
@@ -111,53 +111,53 @@ L<Mojo::Reactor::EV> inherits all events from L<Mojo::Reactor::Poll>.
111 111
 L<Mojo::Reactor::EV> inherits all methods from L<Mojo::Reactor::Poll> and
112 112
 implements the following new ones.
113 113
 
114
-=head2 C<new>
114
+=head2 new
115 115
 
116 116
   my $reactor = Mojo::Reactor::EV->new;
117 117
 
118 118
 Construct a new L<Mojo::Reactor::EV> object.
119 119
 
120
-=head2 C<is_running>
120
+=head2 is_running
121 121
 
122 122
   my $success = $reactor->is_running;
123 123
 
124 124
 Check if reactor is running.
125 125
 
126
-=head2 C<one_tick>
126
+=head2 one_tick
127 127
 
128 128
   $reactor->one_tick;
129 129
 
130 130
 Run reactor until an event occurs or no events are being watched anymore. Note
131 131
 that this method can recurse back into the reactor, so you need to be careful.
132 132
 
133
-=head2 C<recurring>
133
+=head2 recurring
134 134
 
135 135
   my $id = $reactor->recurring(0.25 => sub {...});
136 136
 
137 137
 Create a new recurring timer, invoking the callback repeatedly after a given
138 138
 amount of time in seconds.
139 139
 
140
-=head2 C<start>
140
+=head2 start
141 141
 
142 142
   $reactor->start;
143 143
 
144 144
 Start watching for I/O and timer events, this will block until C<stop> is
145 145
 called or no events are being watched anymore.
146 146
 
147
-=head2 C<stop>
147
+=head2 stop
148 148
 
149 149
   $reactor->stop;
150 150
 
151 151
 Stop watching for I/O and timer events.
152 152
 
153
-=head2 C<timer>
153
+=head2 timer
154 154
 
155 155
   my $id = $reactor->timer(0.5 => sub {...});
156 156
 
157 157
 Create a new timer, invoking the callback after a given amount of time in
158 158
 seconds.
159 159
 
160
-=head2 C<watch>
160
+=head2 watch
161 161
 
162 162
   $reactor = $reactor->watch($handle, $readable, $writable);
163 163
 
+13 -15
mojolegacy/lib/Mojo/Reactor/Poll.pm
... ...
@@ -17,7 +17,7 @@ sub is_running { !!shift->{running} }
17 17
 sub one_tick {
18 18
   my $self = shift;
19 19
 
20
-  # Remember state
20
+  # Remember state for later
21 21
   my $running = $self->{running};
22 22
   $self->{running} = 1;
23 23
 
... ...
@@ -56,7 +56,6 @@ sub one_tick {
56 56
       # Normal timer
57 57
       else { $self->remove($id) }
58 58
 
59
-      # Handle timer
60 59
       ++$i and $self->_sandbox("Timer $id", $t->{cb}) if $t->{cb};
61 60
     }
62 61
   }
... ...
@@ -100,18 +99,17 @@ sub _poll { shift->{poll} ||= IO::Poll->new }
100 99
 
101 100
 sub _sandbox {
102 101
   my ($self, $desc, $cb) = (shift, shift, shift);
103
-  return if eval { $self->$cb(@_); 1 };
104
-  $self->once(error => sub { warn $_[1] })
105
-    unless $self->has_subscribers('error');
106
-  $self->emit_safe(error => "$desc failed: $@");
102
+  eval { $self->$cb(@_); 1 } or $self->emit_safe(error => "$desc failed: $@");
107 103
 }
108 104
 
109 105
 sub _timer {
110 106
   my ($self, $recurring, $after, $cb) = @_;
107
+
111 108
   my $id;
112 109
   do { $id = md5_sum('t' . time . rand 999) } while $self->{timers}{$id};
113 110
   my $t = $self->{timers}{$id} = {cb => $cb, time => time + $after};
114 111
   $t->{recurring} = $after if $recurring;
112
+
115 113
   return $id;
116 114
 }
117 115
 
... ...
@@ -160,61 +158,61 @@ L<Mojo::Reactor::Poll> inherits all events from L<Mojo::Reactor>.
160 158
 L<Mojo::Reactor::Poll> inherits all methods from L<Mojo::Reactor> and
161 159
 implements the following new ones.
162 160
 
163
-=head2 C<io>
161
+=head2 io
164 162
 
165 163
   $reactor = $reactor->io($handle => sub {...});
166 164
 
167 165
 Watch handle for I/O events, invoking the callback whenever handle becomes
168 166
 readable or writable.
169 167
 
170
-=head2 C<is_running>
168
+=head2 is_running
171 169
 
172 170
   my $success = $reactor->is_running;
173 171
 
174 172
 Check if reactor is running.
175 173
 
176
-=head2 C<one_tick>
174
+=head2 one_tick
177 175
 
178 176
   $reactor->one_tick;
179 177
 
180 178
 Run reactor until an event occurs or no events are being watched anymore. Note
181 179
 that this method can recurse back into the reactor, so you need to be careful.
182 180
 
183
-=head2 C<recurring>
181
+=head2 recurring
184 182
 
185 183
   my $id = $reactor->recurring(0.25 => sub {...});
186 184
 
187 185
 Create a new recurring timer, invoking the callback repeatedly after a given
188 186
 amount of time in seconds.
189 187
 
190
-=head2 C<remove>
188
+=head2 remove
191 189
 
192 190
   my $success = $reactor->remove($handle);
193 191
   my $success = $reactor->remove($id);
194 192
 
195 193
 Remove handle or timer.
196 194
 
197
-=head2 C<start>
195
+=head2 start
198 196
 
199 197
   $reactor->start;
200 198
 
201 199
 Start watching for I/O and timer events, this will block until C<stop> is
202 200
 called or no events are being watched anymore.
203 201
 
204
-=head2 C<stop>
202
+=head2 stop
205 203
 
206 204
   $reactor->stop;
207 205
 
208 206
 Stop watching for I/O and timer events.
209 207
 
210
-=head2 C<timer>
208
+=head2 timer
211 209
 
212 210
   my $id = $reactor->timer(0.5 => sub {...});
213 211
 
214 212
 Create a new timer, invoking the callback after a given amount of time in
215 213
 seconds.
216 214
 
217
-=head2 C<watch>
215
+=head2 watch
218 216
 
219 217
   $reactor = $reactor->watch($handle, $readable, $writable);
220 218
 
+9 -9
mojolegacy/lib/Mojo/Server.pm
... ...
@@ -18,7 +18,6 @@ sub new {
18 18
 sub build_app {
19 19
   my ($self, $app) = @_;
20 20
   local $ENV{MOJO_EXE};
21
-  local $ENV{MOJO_APP} = $app;
22 21
   return $app->new unless my $e = Mojo::Loader->new->load($app);
23 22
   die ref $e ? $e : qq{Couldn't find application class "$app".\n};
24 23
 }
... ...
@@ -80,9 +79,10 @@ L<Mojo::Server> is an abstract HTTP server base class.
80 79
 
81 80
 =head1 EVENTS
82 81
 
83
-L<Mojo::Server> can emit the following events.
82
+L<Mojo::Server> inherits all events from L<Mojo::EventEmitter> and can emit
83
+the following new ones.
84 84
 
85
-=head2 C<request>
85
+=head2 request
86 86
 
87 87
   $server->on(request => sub {
88 88
     my ($server, $tx) = @_;
... ...
@@ -104,7 +104,7 @@ Emitted when a request is ready and needs to be handled.
104 104
 
105 105
 L<Mojo::Server> implements the following attributes.
106 106
 
107
-=head2 C<app>
107
+=head2 app
108 108
 
109 109
   my $app = $server->app;
110 110
   $server = $server->app(MojoSubclass->new);
... ...
@@ -116,26 +116,26 @@ Application this server handles, defaults to a L<Mojo::HelloWorld> object.
116 116
 L<Mojo::Server> inherits all methods from L<Mojo::EventEmitter> and implements
117 117
 the following new ones.
118 118
 
119
-=head2 C<new>
119
+=head2 new
120 120
 
121 121
   my $server = Mojo::Server->new;
122 122
 
123 123
 Construct a new L<Mojo::Server> object and subscribe to C<request> event with
124 124
 default request handling.
125 125
 
126
-=head2 C<build_app>
126
+=head2 build_app
127 127
 
128 128
   my $app = $server->build_app('Mojo::HelloWorld');
129 129
 
130 130
 Build application from class.
131 131
 
132
-=head2 C<build_tx>
132
+=head2 build_tx
133 133
 
134 134
   my $tx = $server->build_tx;
135 135
 
136 136
 Let application build a transaction.
137 137
 
138
-=head2 C<load_app>
138
+=head2 load_app
139 139
 
140 140
   my $app = $server->load_app('/home/sri/myapp.pl');
141 141
 
... ...
@@ -143,7 +143,7 @@ Load application from script.
143 143
 
144 144
   say Mojo::Server->new->load_app('./myapp.pl')->home;
145 145
 
146
-=head2 C<run>
146
+=head2 run
147 147
 
148 148
   $server->run;
149 149
 
+4 -8
mojolegacy/lib/Mojo/Server/CGI.pm
... ...
@@ -6,11 +6,8 @@ has 'nph';
6 6
 sub run {
7 7
   my $self = shift;
8 8
 
9
-  # Environment
10 9
   my $tx  = $self->build_tx;
11 10
   my $req = $tx->req->parse(\%ENV);
12
-
13
-  # Store connection information
14 11
   $tx->local_port($ENV{SERVER_PORT})->remote_address($ENV{REMOTE_ADDR});
15 12
 
16 13
   # Request body
... ...
@@ -20,7 +17,7 @@ sub run {
20 17
     $req->parse($buffer);
21 18
   }
22 19
 
23
-  # Handle
20
+  # Handle request
24 21
   $self->emit(request => $tx);
25 22
 
26 23
   # Response start line
... ...
@@ -48,7 +45,6 @@ sub run {
48 45
 sub _write {
49 46
   my ($res, $method) = @_;
50 47
 
51
-  # Write chunks to STDOUT
52 48
   my $offset = 0;
53 49
   while (1) {
54 50
 
... ...
@@ -58,7 +54,7 @@ sub _write {
58 54
     # End of part
59 55
     last unless my $len = length $chunk;
60 56
 
61
-    # Part
57
+    # Make sure we can still write
62 58
     $offset += $len;
63 59
     return undef unless STDOUT->opened;
64 60
     print STDOUT $chunk;
... ...
@@ -111,7 +107,7 @@ L<Mojo::Server::CGI> inherits all events from L<Mojo::Server>.
111 107
 L<Mojo::Server::CGI> inherits all attributes from L<Mojo::Server> and
112 108
 implements the following new ones.
113 109
 
114
-=head2 C<nph>
110
+=head2 nph
115 111
 
116 112
   my $nph = $cgi->nph;
117 113
   $cgi    = $cgi->nph(1);
... ...
@@ -123,7 +119,7 @@ Activate non parsed header mode.
123 119
 L<Mojo::Server::CGI> inherits all methods from L<Mojo::Server> and implements
124 120
 the following new ones.
125 121
 
126
-=head2 C<run>
122
+=head2 run
127 123
 
128 124
   my $status = $cgi->run;
129 125
 
+21 -44
mojolegacy/lib/Mojo/Server/Daemon.pm
... ...
@@ -25,11 +25,7 @@ sub DESTROY {
25 25
 
26 26
 sub run {
27 27
   my $self = shift;
28
-
29
-  # Signals
30
-  $SIG{INT} = $SIG{TERM} = sub { exit 0 };
31
-
32
-  # Change user/group and start accepting connections
28
+  local $SIG{INT} = local $SIG{TERM} = sub { $self->ioloop->stop };
33 29
   $self->start->setuidgid->ioloop->start;
34 30
 }
35 31
 
... ...
@@ -73,7 +69,7 @@ sub start {
73 69
 sub stop {
74 70
   my $self = shift;
75 71
 
76
-  # Pause accepting connections
72
+  # Suspend accepting connections but keep listen sockets open
77 73
   my $loop = $self->ioloop;
78 74
   while (my $id = shift @{$self->{acceptors}}) {
79 75
     my $server = $self->{servers}{$id} = $loop->acceptor($id);
... ...
@@ -87,18 +83,11 @@ sub stop {
87 83
 sub _build_tx {
88 84
   my ($self, $id, $c) = @_;
89 85
 
90
-  # Build transaction
91 86
   my $tx = $self->build_tx->connection($id);
92
-
93
-  # Identify
94 87
   $tx->res->headers->server('Mojolicious (Perl)');
95
-
96
-  # Store connection information
97 88
   my $handle = $self->ioloop->stream($id)->handle;
98 89
   $tx->local_address($handle->sockhost)->local_port($handle->sockport);
99 90
   $tx->remote_address($handle->peerhost)->remote_port($handle->peerport);
100
-
101
-  # TLS
102 91
   $tx->req->url->base->scheme('https') if $c->{tls};
103 92
 
104 93
   # Handle upgrades and requests
... ...
@@ -130,7 +119,6 @@ sub _close {
130 119
   # Finish gracefully
131 120
   if (my $tx = $self->{connections}{$id}{tx}) { $tx->server_close }
132 121
 
133
-  # Remove connection
134 122
   delete $self->{connections}{$id};
135 123
 }
136 124
 
... ...
@@ -173,7 +161,6 @@ sub _finish {
173 161
 sub _listen {
174 162
   my ($self, $listen) = @_;
175 163
 
176
-  # Options
177 164
   my $url     = Mojo::URL->new($listen);
178 165
   my $query   = $url->query;
179 166
   my $options = {
... ...
@@ -189,20 +176,15 @@ sub _listen {
189 176
   delete $options->{address} if $options->{address} eq '*';
190 177
   my $tls = $options->{tls} = $url->protocol eq 'https' ? 1 : undef;
191 178
 
192
-  # Listen
193 179
   weaken $self;
194 180
   my $id = $self->ioloop->server(
195 181
     $options => sub {
196 182
       my ($loop, $stream, $id) = @_;
197 183
 
198
-      # Add new connection
199 184
       my $c = $self->{connections}{$id} = {tls => $tls};
200 185
       warn "-- Accept (@{[$stream->handle->peerhost]})\n" if DEBUG;
201
-
202
-      # Inactivity timeout
203 186
       $stream->timeout($self->inactivity_timeout);
204 187
 
205
-      # Events
206 188
       $stream->on(close => sub { $self->_close($id) });
207 189
       $stream->on(
208 190
         error => sub {
... ...
@@ -218,7 +200,6 @@ sub _listen {
218 200
   );
219 201
   push @{$self->{acceptors} ||= []}, $id;
220 202
 
221
-  # Friendly message
222 203
   return if $self->silent;
223 204
   $self->app->log->info(qq{Listening at "$listen".});
224 205
   $listen =~ s!//\*!//127.0.0.1!i;
... ...
@@ -228,11 +209,9 @@ sub _listen {
228 209
 sub _read {
229 210
   my ($self, $id, $chunk) = @_;
230 211
 
231
-  # Make sure we have a transaction
212
+  # Make sure we have a transaction and parse chunk
232 213
   my $c = $self->{connections}{$id};
233 214
   my $tx = $c->{tx} ||= $self->_build_tx($id, $c);
234
-
235
-  # Parse chunk
236 215
   warn "-- Server <<< Client (@{[$tx->req->url->to_abs]})\n$chunk\n" if DEBUG;
237 216
   $tx->server_read($chunk);
238 217
 
... ...
@@ -259,13 +238,11 @@ sub _write {
259 238
   return unless my $tx = $c->{tx};
260 239
   return unless $tx->is_writing;
261 240
 
262
-  # Get chunk
241
+  # Get chunk and write
263 242
   return if $c->{writing}++;
264 243
   my $chunk = $tx->server_write;
265 244
   delete $c->{writing};
266 245
   warn "-- Server >>> Client (@{[$tx->req->url->to_abs]})\n$chunk\n" if DEBUG;
267
-
268
-  # Write chunk
269 246
   my $stream = $self->ioloop->stream($id)->write($chunk);
270 247
 
271 248
   # Finish or continue writing
... ...
@@ -334,21 +311,21 @@ L<Mojo::Server::Daemon> inherits all events from L<Mojo::Server>.
334 311
 L<Mojo::Server::Daemon> inherits all attributes from L<Mojo::Server> and
335 312
 implements the following new ones.
336 313
 
337
-=head2 C<backlog>
314
+=head2 backlog
338 315
 
339 316
   my $backlog = $daemon->backlog;
340 317
   $daemon     = $daemon->backlog(128);
341 318
 
342 319
 Listen backlog size, defaults to C<SOMAXCONN>.
343 320
 
344
-=head2 C<group>
321
+=head2 group
345 322
 
346 323
   my $group = $daemon->group;
347 324
   $daemon   = $daemon->group('users');
348 325
 
349 326
 Group for server process.
350 327
 
351
-=head2 C<inactivity_timeout>
328
+=head2 inactivity_timeout
352 329
 
353 330
   my $timeout = $daemon->inactivity_timeout;
354 331
   $daemon     = $daemon->inactivity_timeout(5);
... ...
@@ -358,7 +335,7 @@ closed, defaults to the value of the C<MOJO_INACTIVITY_TIMEOUT> environment
358 335
 variable or C<15>. Setting the value to C<0> will allow connections to be
359 336
 inactive indefinitely.
360 337
 
361
-=head2 C<ioloop>
338
+=head2 ioloop
362 339
 
363 340
   my $loop = $daemon->ioloop;
364 341
   $daemon  = $daemon->ioloop(Mojo::IOLoop->new);
... ...
@@ -366,7 +343,7 @@ inactive indefinitely.
366 343
 Event loop object to use for I/O operations, defaults to the global
367 344
 L<Mojo::IOLoop> singleton.
368 345
 
369
-=head2 C<listen>
346
+=head2 listen
370 347
 
371 348
   my $listen = $daemon->listen;
372 349
   $daemon    = $daemon->listen(['https://localhost:3000']);
... ...
@@ -391,46 +368,46 @@ These parameters are currently available:
391 368
 
392 369
 =over 4
393 370
 
394
-=item C<ca>
371
+=item ca
395 372
 
396 373
 Path to TLS certificate authority file.
397 374
 
398
-=item C<cert>
375
+=item cert
399 376
 
400 377
 Path to the TLS cert file, defaults to a built-in test certificate.
401 378
 
402
-=item C<key>
379
+=item key
403 380
 
404 381
 Path to the TLS key file, defaults to a built-in test key.
405 382
 
406
-=item C<verify>
383
+=item verify
407 384
 
408 385
 TLS verification mode, defaults to C<0x03>.
409 386
 
410 387
 =back
411 388
 
412
-=head2 C<max_clients>
389
+=head2 max_clients
413 390
 
414 391
   my $max = $daemon->max_clients;
415 392
   $daemon = $daemon->max_clients(1000);
416 393
 
417 394
 Maximum number of parallel client connections, defaults to C<1000>.
418 395
 
419
-=head2 C<max_requests>
396
+=head2 max_requests
420 397
 
421 398
   my $max = $daemon->max_requests;
422 399
   $daemon = $daemon->max_requests(100);
423 400
 
424 401
 Maximum number of keep alive requests per connection, defaults to C<25>.
425 402
 
426
-=head2 C<silent>
403
+=head2 silent
427 404
 
428 405
   my $silent = $daemon->silent;
429 406
   $daemon    = $daemon->silent(1);
430 407
 
431 408
 Disable console messages.
432 409
 
433
-=head2 C<user>
410
+=head2 user
434 411
 
435 412
   my $user = $daemon->user;
436 413
   $daemon  = $daemon->user('web');
... ...
@@ -442,25 +419,25 @@ User for the server process.
442 419
 L<Mojo::Server::Daemon> inherits all methods from L<Mojo::Server> and
443 420
 implements the following new ones.
444 421
 
445
-=head2 C<run>
422
+=head2 run
446 423
 
447 424
   $daemon->run;
448 425
 
449 426
 Run server.
450 427
 
451
-=head2 C<setuidgid>
428
+=head2 setuidgid
452 429
 
453 430
   $daemon = $daemon->setuidgid;
454 431
 
455 432
 Set user and group for process.
456 433
 
457
-=head2 C<start>
434
+=head2 start
458 435
 
459 436
   $daemon = $daemon->start;
460 437
 
461 438
 Start accepting connections.
462 439
 
463
-=head2 C<stop>
440
+=head2 stop
464 441
 
465 442
   $daemon = $daemon->stop;
466 443
 
+67 -258
mojolegacy/lib/Mojo/Server/Hypnotoad.pm
... ...
@@ -4,26 +4,11 @@ use Mojo::Base -base;
4 4
 # "Bender: I was God once.
5 5
 #  God: Yes, I saw. You were doing well, until everyone died."
6 6
 use Cwd 'abs_path';
7
-use Fcntl ':flock';
8 7
 use File::Basename 'dirname';
9
-use File::Spec::Functions qw(catfile tmpdir);
10
-use IO::Poll 'POLLIN';
11
-use List::Util 'shuffle';
12
-use Mojo::Server::Daemon;
13
-use POSIX qw(setsid WNOHANG);
8
+use File::Spec::Functions 'catfile';
9
+use Mojo::Server::Prefork;
10
+use POSIX 'setsid';
14 11
 use Scalar::Util 'weaken';
15
-use Time::HiRes 'ualarm';
16
-
17
-sub DESTROY {
18
-  my $self = shift;
19
-
20
-  # Worker or command
21
-  return unless $self->{finished};
22
-
23
-  # Manager
24
-  if (my $file = $self->{config}{pid_file})  { unlink $file if -w $file }
25
-  if (my $file = $self->{config}{lock_file}) { unlink $file if -w $file }
26
-}
27 12
 
28 13
 sub run {
29 14
   my ($self, $path) = @_;
... ...
@@ -31,13 +16,13 @@ sub run {
31 16
   # No Windows support
32 17
   _exit('Hypnotoad not available for Windows.') if $^O eq 'MSWin32';
33 18
 
34
-  # Application
19
+  # Remember application for later
35 20
   $ENV{HYPNOTOAD_APP} ||= abs_path $path;
36 21
 
37 22
   # This is a production server
38 23
   $ENV{MOJO_MODE} ||= 'production';
39 24
 
40
-  # Executable
25
+  # Remember executable for later
41 26
   $ENV{HYPNOTOAD_EXE} ||= $0;
42 27
   $0 = $ENV{HYPNOTOAD_APP};
43 28
 
... ...
@@ -45,9 +30,13 @@ sub run {
45 30
   die "Can't exec: $!" if !$ENV{HYPNOTOAD_REV}++ && !exec $ENV{HYPNOTOAD_EXE};
46 31
 
47 32
   # Preload application and configure server
48
-  my $daemon = $self->{daemon} = Mojo::Server::Daemon->new;
49
-  my $app = $daemon->load_app($ENV{HYPNOTOAD_APP});
33
+  my $prefork = $self->{prefork} = Mojo::Server::Prefork->new;
34
+  my $app = $prefork->load_app($ENV{HYPNOTOAD_APP});
50 35
   $self->_config($app);
36
+  weaken $self;
37
+  $prefork->on(wait   => sub { $self->_manage });
38
+  $prefork->on(reap   => sub { $self->_reap(pop) });
39
+  $prefork->on(finish => sub { $self->{finished} = 1 });
51 40
 
52 41
   # Testing
53 42
   _exit('Everything looks good!') if $ENV{HYPNOTOAD_TEST};
... ...
@@ -73,87 +62,38 @@ sub run {
73 62
   }
74 63
 
75 64
   # Start accepting connections
76
-  my $log = $self->{log} = $app->log;
77
-  $log->info(qq[Hypnotoad server $$ started for "$ENV{HYPNOTOAD_APP}".]);
78
-  $daemon->start;
79
-
80
-  # Pipe for worker communication
81
-  pipe($self->{reader}, $self->{writer}) or die "Can't create pipe: $!";
82
-  $self->{poll} = IO::Poll->new;
83
-  $self->{poll}->mask($self->{reader}, POLLIN);
84
-
85
-  # Clean manager environment
86
-  my $c = $self->{config};
87
-  $SIG{INT} = $SIG{TERM} = sub { $self->{finished} = 1 };
88
-  $SIG{CHLD} = sub {
89
-    while ((my $pid = waitpid -1, WNOHANG) > 0) { $self->_reap($pid) }
90
-  };
91
-  $SIG{QUIT} = sub { $self->{finished} = $self->{graceful} = 1 };
92
-  $SIG{USR2} = sub { $self->{upgrade} ||= time };
93
-  $SIG{TTIN} = sub { $c->{workers}++ };
94
-  $SIG{TTOU} = sub {
95
-    return unless $c->{workers} && $c->{workers}--;
96
-    $self->{workers}{shuffle keys %{$self->{workers}}}{graceful} ||= time;
97
-  };
98
-
99
-  # Mainloop
100
-  $self->_manage while 1;
65
+  local $SIG{USR2} = sub { $self->{upgrade} ||= time };
66
+  $prefork->run;
101 67
 }
102 68
 
103 69
 sub _config {
104 70
   my ($self, $app) = @_;
105 71
 
106 72
   # Hypnotoad settings
107
-  my $c = $self->{config} = $app->config('hypnotoad') || {};
108
-  $c->{graceful_timeout}   ||= 20;
109
-  $c->{heartbeat_interval} ||= 5;
110
-  $c->{heartbeat_timeout}  ||= 20;
111
-  $c->{lock_file}          ||= catfile tmpdir, 'hypnotoad.lock';
112
-  $c->{lock_file} .= ".$$";
113
-  $c->{lock_timeout} ||= 0.5;
114
-  $c->{pid_file} ||= catfile dirname($ENV{HYPNOTOAD_APP}), 'hypnotoad.pid';
115
-  $c->{upgrade_timeout} ||= 60;
116
-  $c->{workers}         ||= 4;
117
-
118
-  # Daemon settings
73
+  my $c = $app->config('hypnotoad') || {};
74
+  $self->{upgrade_timeout} = $c->{upgrade_timeout} || 60;
75
+
76
+  # Prefork settings
119 77
   $ENV{MOJO_REVERSE_PROXY} = $c->{proxy} if defined $c->{proxy};
120
-  my $daemon = $self->{daemon};
121
-  defined $c->{$_} and $daemon->$_($c->{$_}) for qw(backlog group user);
122
-  $daemon->max_clients($c->{clients}              || 1000);
123
-  $daemon->max_requests($c->{keep_alive_requests} || 25);
124
-  $daemon->inactivity_timeout(defined $c->{inactivity_timeout} ? $c->{inactivity_timeout} : 15);
125
-  $daemon->listen($c->{listen} || ['http://*:8080']);
126
-
127
-  # Event loop settings
128
-  my $loop = $daemon->ioloop;
129
-  $loop->max_accepts(defined $c->{accepts} ? $c->{accepts} : 1000);
130
-  defined $c->{$_} and $loop->$_($c->{$_})
131
-    for qw(accept_interval multi_accept);
78
+  my $prefork = $self->{prefork}->listen($c->{listen} || ['http://*:8080']);
79
+  my $file = catfile dirname($ENV{HYPNOTOAD_APP}), 'hypnotoad.pid';
80
+  $prefork->pid_file($c->{pid_file} || $file);
81
+  $prefork->max_clients($c->{clients}) if $c->{clients};
82
+  $prefork->max_requests($c->{keep_alive_requests})
83
+    if $c->{keep_alive_requests};
84
+  defined $c->{$_} and $prefork->$_($c->{$_})
85
+    for qw(accept_interval accepts backlog graceful_timeout group),
86
+    qw(heartbeat_interval heartbeat_timeout inactivity_timeout lock_file),
87
+    qw(lock_timeout multi_accept user workers);
132 88
 }
133 89
 
134 90
 sub _exit { say shift and exit 0 }
135 91
 
136
-sub _heartbeat {
137
-  my $self = shift;
138
-
139
-  # Poll for heartbeats
140
-  my $poll = $self->{poll};
141
-  $poll->poll(1);
142
-  return unless $poll->handles(POLLIN);
143
-  return unless $self->{reader}->sysread(my $chunk, 4194304);
144
-
145
-  # Update heartbeats
146
-  $self->{workers}{$1} and $self->{workers}{$1}{time} = time
147
-    while $chunk =~ /(\d+)\n/g;
148
-}
149
-
150 92
 sub _hot_deploy {
151 93
   my $self = shift;
152 94
 
153
-  # Make sure server is running and clean up PID file if necessary
154
-  return unless defined(my $pid = $self->_pid);
155
-  my $file = $self->{config}{pid_file};
156
-  return -w $file ? unlink $file : undef unless $pid && kill 0, $pid;
95
+  # Make sure server is running
96
+  return unless my $pid = $self->{prefork}->check_pid;
157 97
 
158 98
   # Start hot deployment
159 99
   kill 'USR2', $pid;
... ...
@@ -163,173 +103,42 @@ sub _hot_deploy {
163 103
 sub _manage {
164 104
   my $self = shift;
165 105
 
166
-  # Housekeeping
167
-  my $c = $self->{config};
168
-  if (!$self->{finished}) {
169
-
170
-    # Spawn more workers
171
-    $self->_spawn while keys %{$self->{workers}} < $c->{workers};
172
-
173
-    # Check PID file
174
-    $self->_pid_file;
175
-  }
176
-
177
-  # Shutdown
178
-  elsif (!keys %{$self->{workers}}) { exit 0 }
179
-
180 106
   # Upgraded
107
+  my $log = $self->{prefork}->app->log;
181 108
   if ($ENV{HYPNOTOAD_PID} && $ENV{HYPNOTOAD_PID} ne $$) {
182
-    $self->{log}->info("Upgrade successful, stopping $ENV{HYPNOTOAD_PID}.");
109
+    $log->info("Upgrade successful, stopping $ENV{HYPNOTOAD_PID}.");
183 110
     kill 'QUIT', $ENV{HYPNOTOAD_PID};
184 111
   }
185
-  $ENV{HYPNOTOAD_PID} = $$;
186
-
187
-  # Check heartbeat
188
-  $self->_heartbeat;
112
+  $ENV{HYPNOTOAD_PID} = $$ unless (defined $ENV{HYPNOTOAD_PID} ? $ENV{HYPNOTOAD_PID} : '') eq $$;
189 113
 
190 114
   # Upgrade
191 115
   if ($self->{upgrade} && !$self->{finished}) {
192 116
 
193 117
     # Fresh start
194 118
     unless ($self->{new}) {
195
-      $self->{log}->info('Starting zero downtime software upgrade.');
119
+      $log->info('Starting zero downtime software upgrade.');
196 120
       die "Can't fork: $!" unless defined(my $pid = $self->{new} = fork);
197 121
       exec($ENV{HYPNOTOAD_EXE}) or die("Can't exec: $!") unless $pid;
198 122
     }
199 123
 
200 124
     # Timeout
201 125
     kill 'KILL', $self->{new}
202
-      if $self->{upgrade} + $c->{upgrade_timeout} <= time;
126
+      if $self->{upgrade} + $self->{upgrade_timeout} <= time;
203 127
   }
204
-
205
-  # Workers
206
-  while (my ($pid, $w) = each %{$self->{workers}}) {
207
-
208
-    # No heartbeat (graceful stop)
209
-    my $interval = $c->{heartbeat_interval};
210
-    my $timeout  = $c->{heartbeat_timeout};
211
-    if (!$w->{graceful} && ($w->{time} + $interval + $timeout <= time)) {
212
-      $self->{log}->info("Worker $pid has no heartbeat, restarting.");
213
-      $w->{graceful} = time;
214
-    }
215
-
216
-    # Graceful stop with timeout
217
-    $w->{graceful} ||= time if $self->{graceful};
218
-    if ($w->{graceful}) {
219
-      $self->{log}->debug("Trying to stop worker $pid gracefully.");
220
-      kill 'QUIT', $pid;
221
-      $w->{force} = 1 if $w->{graceful} + $c->{graceful_timeout} <= time;
222
-    }
223
-
224
-    # Normal stop
225
-    if (($self->{finished} && !$self->{graceful}) || $w->{force}) {
226
-      $self->{log}->debug("Stopping worker $pid.");
227
-      kill 'KILL', $pid;
228
-    }
229
-  }
230
-}
231
-
232
-sub _pid {
233
-  return undef unless open my $file, '<', shift->{config}{pid_file};
234
-  my $pid = <$file>;
235
-  chomp $pid;
236
-  return $pid;
237
-}
238
-
239
-sub _pid_file {
240
-  my $self = shift;
241
-
242
-  # Don't need a PID file anymore
243
-  return if $self->{finished};
244
-
245
-  # Check if PID file already exists
246
-  return if -e (my $file = $self->{config}{pid_file});
247
-
248
-  # Create PID file
249
-  $self->{log}->info(qq{Creating process id file "$file".});
250
-  die qq{Can't create process id file "$file": $!}
251
-    unless open my $pid, '>', $file;
252
-  chmod 0644, $pid;
253
-  print $pid $$;
254 128
 }
255 129
 
256 130
 sub _reap {
257 131
   my ($self, $pid) = @_;
258 132
 
259 133
   # Clean up failed upgrade
260
-  if (($self->{new} || '') eq $pid) {
261
-    $self->{log}->info('Zero downtime software upgrade failed.');
262
-    delete $self->{$_} for qw(new upgrade);
263
-  }
264
-
265
-  # Clean up worker
266
-  else {
267
-    $self->{log}->debug("Worker $pid stopped.");
268
-    delete $self->{workers}{$pid};
269
-  }
270
-}
271
-
272
-sub _spawn {
273
-  my $self = shift;
274
-
275
-  # Manager
276
-  die "Can't fork: $!" unless defined(my $pid = fork);
277
-  return $self->{workers}{$pid} = {time => time} if $pid;
278
-
279
-  # Prepare lock file
280
-  my $c    = $self->{config};
281
-  my $file = $c->{lock_file};
282
-  die qq{Can't open lock file "$file": $!} unless open my $lock, '>', $file;
283
-
284
-  # Change user/group
285
-  my $loop = $self->{daemon}->setuidgid->ioloop;
286
-
287
-  # Accept mutex
288
-  $loop->lock(
289
-    sub {
290
-
291
-      # Blocking
292
-      my $l;
293
-      if ($_[1]) {
294
-        eval {
295
-          local $SIG{ALRM} = sub { die "alarm\n" };
296
-          my $old = ualarm $c->{lock_timeout} * 1000000;
297
-          $l = flock $lock, LOCK_EX;
298
-          ualarm $old;
299
-        };
300
-        if ($@) { $l = $@ eq "alarm\n" ? 0 : die($@) }
301
-      }
302
-
303
-      # Non blocking
304
-      else { $l = flock $lock, LOCK_EX | LOCK_NB }
305
-
306
-      return $l;
307
-    }
308
-  );
309
-  $loop->unlock(sub { flock $lock, LOCK_UN });
310
-
311
-  # Heartbeat messages (stop sending during graceful stop)
312
-  weaken $self;
313
-  $loop->recurring(
314
-    $c->{heartbeat_interval} => sub {
315
-      return unless shift->max_connections;
316
-      $self->{writer}->syswrite("$$\n") or exit 0;
317
-    }
318
-  );
319
-
320
-  # Clean worker environment
321
-  $SIG{$_} = 'DEFAULT' for qw(INT TERM CHLD USR2 TTIN TTOU);
322
-  $SIG{QUIT} = sub { $loop->max_connections(0) };
323
-  delete $self->{$_} for qw(poll reader);
324
-
325
-  # Start
326
-  $self->{log}->debug("Worker $$ started.");
327
-  $loop->start;
328
-  exit 0;
134
+  return unless ($self->{new} || '') eq $pid;
135
+  $self->{prefork}->app->log->info('Zero downtime software upgrade failed.');
136
+  delete $self->{$_} for qw(new upgrade);
329 137
 }
330 138
 
331 139
 sub _stop {
332
-  _exit('Hypnotoad server not running.') unless my $pid = shift->_pid;
140
+  _exit('Hypnotoad server not running.')
141
+    unless my $pid = shift->{prefork}->check_pid;
333 142
   kill 'QUIT', $pid;
334 143
   _exit("Stopping Hypnotoad server $pid gracefully.");
335 144
 }
... ...
@@ -351,7 +160,7 @@ Mojo::Server::Hypnotoad - ALL GLORY TO THE HYPNOTOAD!
351 160
 
352 161
 L<Mojo::Server::Hypnotoad> is a full featured, UNIX optimized, preforking
353 162
 non-blocking I/O HTTP and WebSocket server, built around the very well tested
354
-and reliable L<Mojo::Server::Daemon>, with C<IPv6>, C<TLS>, C<Comet> (long
163
+and reliable L<Mojo::Server::Prefork>, with C<IPv6>, C<TLS>, C<Comet> (long
355 164
 polling), multiple event loop and hot deployment support that just works. Note
356 165
 that the server uses signals for process management, so you should avoid
357 166
 modifying signal handlers in your applications.
... ...
@@ -385,23 +194,23 @@ signals.
385 194
 
386 195
 =over 2
387 196
 
388
-=item C<INT>, C<TERM>
197
+=item INT, TERM
389 198
 
390 199
 Shutdown server immediately.
391 200
 
392
-=item C<QUIT>
201
+=item QUIT
393 202
 
394 203
 Shutdown server gracefully.
395 204
 
396
-=item C<TTIN>
205
+=item TTIN
397 206
 
398 207
 Increase worker pool by one.
399 208
 
400
-=item C<TTOU>
209
+=item TTOU
401 210
 
402 211
 Decrease worker pool by one.
403 212
 
404
-=item C<USR2>
213
+=item USR2
405 214
 
406 215
 Attempt zero downtime software upgrade (hot deployment) without losing any
407 216
 incoming connections.
... ...
@@ -426,11 +235,11 @@ and take over serving requests after starting up successfully.
426 235
 
427 236
 =over 2
428 237
 
429
-=item C<INT>, C<TERM>
238
+=item INT, TERM
430 239
 
431 240
 Stop worker immediately.
432 241
 
433
-=item C<QUIT>
242
+=item QUIT
434 243
 
435 244
 Stop worker gracefully.
436 245
 
... ...
@@ -441,7 +250,7 @@ Stop worker gracefully.
441 250
 L<Mojo::Server::Hypnotoad> can be configured with the following settings, see
442 251
 L<Mojolicious::Guides::Cookbook/"Hypnotoad"> for examples.
443 252
 
444
-=head2 C<accept_interval>
253
+=head2 accept_interval
445 254
 
446 255
   accept_interval => 0.5
447 256
 
... ...
@@ -449,7 +258,7 @@ Interval in seconds for trying to reacquire the accept mutex and connection
449 258
 management, defaults to C<0.025>. Note that changing this value can affect
450 259
 performance and idle CPU usage.
451 260
 
452
-=head2 C<accepts>
261
+=head2 accepts
453 262
 
454 263
   accepts => 100
455 264
 
... ...
@@ -459,13 +268,13 @@ to accept new connections indefinitely. Note that up to half of this value can
459 268
 be subtracted randomly to improve load balancing, and that worker processes
460 269
 will stop sending heartbeat messages once the limit has been reached.
461 270
 
462
-=head2 C<backlog>
271
+=head2 backlog
463 272
 
464 273
   backlog => 128
465 274
 
466 275
 Listen backlog size, defaults to C<SOMAXCONN>.
467 276
 
468
-=head2 C<clients>
277
+=head2 clients
469 278
 
470 279
   clients => 100
471 280
 
... ...
@@ -474,33 +283,33 @@ C<1000>. Note that depending on how much your application may block, you might
474 283
 want to decrease this value and increase C<workers> instead for better
475 284
 performance.
476 285
 
477
-=head2 C<graceful_timeout>
286
+=head2 graceful_timeout
478 287
 
479 288
   graceful_timeout => 15
480 289
 
481 290
 Maximum amount of time in seconds stopping a worker gracefully may take before
482 291
 being forced, defaults to C<20>.
483 292
 
484
-=head2 C<group>
293
+=head2 group
485 294
 
486 295
   group => 'staff'
487 296
 
488 297
 Group name for worker processes.
489 298
 
490
-=head2 C<heartbeat_interval>
299
+=head2 heartbeat_interval
491 300
 
492 301
   heartbeat_interval => 3
493 302
 
494 303
 Heartbeat interval in seconds, defaults to C<5>.
495 304
 
496
-=head2 C<heartbeat_timeout>
305
+=head2 heartbeat_timeout
497 306
 
498 307
   heartbeat_timeout => 2
499 308
 
500 309
 Maximum amount of time in seconds before a worker without a heartbeat will be
501 310
 stopped gracefully, defaults to C<20>.
502 311
 
503
-=head2 C<inactivity_timeout>
312
+=head2 inactivity_timeout
504 313
 
505 314
   inactivity_timeout => 10
506 315
 
... ...
@@ -508,40 +317,40 @@ Maximum amount of time in seconds a connection can be inactive before getting
508 317
 closed, defaults to C<15>. Setting the value to C<0> will allow connections to
509 318
 be inactive indefinitely.
510 319
 
511
-=head2 C<keep_alive_requests>
320
+=head2 keep_alive_requests
512 321
 
513 322
   keep_alive_requests => 50
514 323
 
515 324
 Number of keep alive requests per connection, defaults to C<25>.
516 325
 
517
-=head2 C<listen>
326
+=head2 listen
518 327
 
519 328
   listen => ['http://*:80']
520 329
 
521 330
 List of one or more locations to listen on, defaults to C<http://*:8080>. See
522 331
 also L<Mojo::Server::Daemon/"listen"> for more examples.
523 332
 
524
-=head2 C<lock_file>
333
+=head2 lock_file
525 334
 
526 335
   lock_file => '/tmp/hypnotoad.lock'
527 336
 
528 337
 Full path of accept mutex lock file prefix, to which the process id will be
529 338
 appended, defaults to a random temporary path.
530 339
 
531
-=head2 C<lock_timeout>
340
+=head2 lock_timeout
532 341
 
533 342
   lock_timeout => 1
534 343
 
535 344
 Maximum amount of time in seconds a worker may block when waiting for the
536 345
 accept mutex, defaults to C<0.5>.
537 346
 
538
-=head2 C<multi_accept>
347
+=head2 multi_accept
539 348
 
540 349
   multi_accept => 100
541 350
 
542 351
 Number of connections to accept at once, defaults to C<50>.
543 352
 
544
-=head2 C<pid_file>
353
+=head2 pid_file
545 354
 
546 355
   pid_file => '/var/run/hypnotoad.pid'
547 356
 
... ...
@@ -549,7 +358,7 @@ Full path to process id file, defaults to C<hypnotoad.pid> in the same
549 358
 directory as the application. Note that this value can only be changed after
550 359
 the server has been stopped.
551 360
 
552
-=head2 C<proxy>
361
+=head2 proxy
553 362
 
554 363
   proxy => 1
555 364
 
... ...
@@ -557,20 +366,20 @@ Activate reverse proxy support, which allows for the C<X-Forwarded-For> and
557 366
 C<X-Forwarded-HTTPS> headers to be picked up automatically, defaults to the
558 367
 value of the C<MOJO_REVERSE_PROXY> environment variable.
559 368
 
560
-=head2 C<upgrade_timeout>
369
+=head2 upgrade_timeout
561 370
 
562 371
   upgrade_timeout => 45
563 372
 
564 373
 Maximum amount of time in seconds a zero downtime software upgrade may take
565 374
 before getting canceled, defaults to C<60>.
566 375
 
567
-=head2 C<user>
376
+=head2 user
568 377
 
569 378
   user => 'sri'
570 379
 
571 380
 Username for worker processes.
572 381
 
573
-=head2 C<workers>
382
+=head2 workers
574 383
 
575 384
   workers => 10
576 385
 
... ...
@@ -582,7 +391,7 @@ worker processes per CPU core.
582 391
 L<Mojo::Server::Hypnotoad> inherits all methods from L<Mojo::Base> and
583 392
 implements the following new ones.
584 393
 
585
-=head2 C<run>
394
+=head2 run
586 395
 
587 396
   $toad->run('script/myapp');
588 397
 
+5 -6
mojolegacy/lib/Mojo/Server/Morbo.pm
... ...
@@ -26,8 +26,8 @@ sub run {
26 26
   my ($self, $app) = @_;
27 27
 
28 28
   # Prepare environment
29
-  $SIG{CHLD} = sub { $self->_reap };
30
-  $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = sub {
29
+  local $SIG{CHLD} = sub { $self->_reap };
30
+  local $SIG{INT} = local $SIG{TERM} = local $SIG{QUIT} = sub {
31 31
     $self->{finished} = 1;
32 32
     kill 'TERM', $self->{running} if $self->{running};
33 33
   };
... ...
@@ -63,7 +63,6 @@ sub _manage {
63 63
     $self->{modified} = 1;
64 64
   }
65 65
 
66
-  # Housekeeping
67 66
   $self->_reap;
68 67
   delete $self->{running} if $self->{running} && !kill 0, $self->{running};
69 68
   $self->_spawn if !$self->{running} && delete $self->{modified};
... ...
@@ -136,7 +135,7 @@ See L<Mojolicious::Guides::Cookbook> for more.
136 135
 
137 136
 L<Mojo::Server::Morbo> implements the following attributes.
138 137
 
139
-=head2 C<watch>
138
+=head2 watch
140 139
 
141 140
   my $watch = $morbo->watch;
142 141
   $morbo    = $morbo->watch(['/home/sri/myapp']);
... ...
@@ -150,13 +149,13 @@ directory.
150 149
 L<Mojo::Server::Morbo> inherits all methods from L<Mojo::Base> and implements
151 150
 the following new ones.
152 151
 
153
-=head2 C<check_file>
152
+=head2 check_file
154 153
 
155 154
   my $success = $morbo->check_file('/home/sri/lib/MyApp.pm');
156 155
 
157 156
 Check if file has been modified since last check.
158 157
 
159
-=head2 C<run>
158
+=head2 run
160 159
 
161 160
   $morbo->run('script/myapp');
162 161
 
+4 -7
mojolegacy/lib/Mojo/Server/PSGI.pm
... ...
@@ -4,11 +4,8 @@ use Mojo::Base 'Mojo::Server';
4 4
 sub run {
5 5
   my ($self, $env) = @_;
6 6
 
7
-  # Environment
8 7
   my $tx  = $self->build_tx;
9 8
   my $req = $tx->req->parse($env);
10
-
11
-  # Store connection information
12 9
   $tx->local_port($env->{SERVER_PORT})->remote_address($env->{REMOTE_ADDR});
13 10
 
14 11
   # Request body
... ...
@@ -20,7 +17,7 @@ sub run {
20 17
     last if ($len -= $read) <= 0;
21 18
   }
22 19
 
23
-  # Handle
20
+  # Handle request
24 21
   $self->emit(request => $tx);
25 22
 
26 23
   # Response headers
... ...
@@ -47,6 +44,7 @@ sub to_psgi_app {
47 44
 package Mojo::Server::PSGI::_IO;
48 45
 use Mojo::Base -base;
49 46
 
47
+# Finish transaction
50 48
 sub close { shift->{tx}->server_close }
51 49
 
52 50
 sub getline {
... ...
@@ -59,7 +57,6 @@ sub getline {
59 57
   # End of content
60 58
   return undef unless length $chunk;
61 59
 
62
-  # Content
63 60
   $self->{offset} += length $chunk;
64 61
   return $chunk;
65 62
 }
... ...
@@ -109,13 +106,13 @@ L<Mojo::Server::PSGI> inherits all events from L<Mojo::Server>.
109 106
 L<Mojo::Server::PSGI> inherits all methods from L<Mojo::Server> and implements
110 107
 the following new ones.
111 108
 
112
-=head2 C<run>
109
+=head2 run
113 110
 
114 111
   my $res = $psgi->run($env);
115 112
 
116 113
 Run L<PSGI>.
117 114
 
118
-=head2 C<to_psgi_app>
115
+=head2 to_psgi_app
119 116
 
120 117
   my $app = $psgi->to_psgi_app;
121 118
 
+495
mojolegacy/lib/Mojo/Server/Prefork.pm
... ...
@@ -0,0 +1,495 @@
1
+package Mojo::Server::Prefork;
2
+use Mojo::Base 'Mojo::Server::Daemon';
3
+
4
+use Fcntl ':flock';
5
+use File::Spec::Functions qw(catfile tmpdir);
6
+use IO::Poll 'POLLIN';
7
+use List::Util 'shuffle';
8
+use POSIX 'WNOHANG';
9
+use Scalar::Util 'weaken';
10
+use Time::HiRes ();
11
+
12
+has accepts         => 1000;
13
+has accept_interval => 0.025;
14
+has [qw(graceful_timeout heartbeat_timeout)] => 20;
15
+has heartbeat_interval => 5;
16
+has lock_file          => sub { catfile tmpdir, 'prefork.lock' };
17
+has lock_timeout       => 0.5;
18
+has multi_accept       => 50;
19
+has pid_file           => sub { catfile tmpdir, 'prefork.pid' };
20
+has workers            => 4;
21
+
22
+sub DESTROY {
23
+  my $self = shift;
24
+
25
+  # Worker
26
+  return unless $self->{finished};
27
+
28
+  # Manager
29
+  if (my $file = $self->{lock_file}) { unlink $file if -w $file }
30
+  if (my $file = $self->pid_file)    { unlink $file if -w $file }
31
+}
32
+
33
+sub check_pid {
34
+  my $file = shift->pid_file;
35
+  return undef unless open my $handle, '<', $file;
36
+  my $pid = <$handle>;
37
+  chomp $pid;
38
+
39
+  # Running
40
+  return $pid if $pid && kill 0, $pid;
41
+
42
+  # Not running
43
+  unlink $file if -w $file;
44
+  return undef;
45
+}
46
+
47
+sub run {
48
+  my $self = shift;
49
+
50
+  # No Windows support
51
+  say 'Preforking not available for Windows.' and exit 0 if $^O eq 'MSWin32';
52
+
53
+  # Prepare lock file and event loop
54
+  $self->{lock_file} = $self->lock_file . ".$$";
55
+  my $loop = $self->ioloop->max_accepts($self->accepts);
56
+  $loop->$_($self->$_) for qw(accept_interval multi_accept);
57
+
58
+  # Pipe for worker communication
59
+  pipe($self->{reader}, $self->{writer}) or die "Can't create pipe: $!";
60
+  $self->{poll} = IO::Poll->new;
61
+  $self->{poll}->mask($self->{reader}, POLLIN);
62
+
63
+  # Clean manager environment
64
+  local $SIG{INT} = local $SIG{TERM} = sub { $self->_term };
65
+  local $SIG{CHLD} = sub {
66
+    while ((my $pid = waitpid -1, WNOHANG) > 0) { $self->_reap($pid) }
67
+  };
68
+  local $SIG{QUIT} = sub { $self->_term(1) };
69
+  local $SIG{TTIN} = sub { $self->workers($self->workers + 1) };
70
+  local $SIG{TTOU} = sub {
71
+    $self->workers($self->workers - 1) if $self->workers > 0;
72
+    return unless $self->workers;
73
+    $self->{pool}{shuffle keys %{$self->{pool}}}{graceful} ||= time;
74
+  };
75
+
76
+  # Preload application and start accepting connections
77
+  $self->start->app->log->info("Manager $$ started.");
78
+  $self->{running} = 1;
79
+  $self->_manage while $self->{running};
80
+}
81
+
82
+sub _heartbeat {
83
+  my $self = shift;
84
+
85
+  # Poll for heartbeats
86
+  my $poll = $self->{poll};
87
+  $poll->poll(1);
88
+  return unless $poll->handles(POLLIN);
89
+  return unless $self->{reader}->sysread(my $chunk, 4194304);
90
+
91
+  # Update heartbeats
92
+  $self->{pool}{$1} and $self->emit(heartbeat => $1)->{pool}{$1}{time} = time
93
+    while $chunk =~ /(\d+)\n/g;
94
+}
95
+
96
+sub _manage {
97
+  my $self = shift;
98
+
99
+  # Spawn more workers and check PID file
100
+  if (!$self->{finished}) {
101
+    $self->_spawn while keys %{$self->{pool}} < $self->workers;
102
+    $self->_pid_file;
103
+  }
104
+
105
+  # Shutdown
106
+  elsif (!keys %{$self->{pool}}) { return delete $self->{running} }
107
+
108
+  # Manage workers
109
+  $self->emit('wait')->_heartbeat;
110
+  my $log = $self->app->log;
111
+  while (my ($pid, $w) = each %{$self->{pool}}) {
112
+
113
+    # No heartbeat (graceful stop)
114
+    my $interval = $self->heartbeat_interval;
115
+    my $timeout  = $self->heartbeat_timeout;
116
+    if (!$w->{graceful} && ($w->{time} + $interval + $timeout <= time)) {
117
+      $log->info("Worker $pid has no heartbeat, restarting.");
118
+      $w->{graceful} = time;
119
+    }
120
+
121
+    # Graceful stop with timeout
122
+    $w->{graceful} ||= time if $self->{graceful};
123
+    if ($w->{graceful}) {
124
+      $log->debug("Trying to stop worker $pid gracefully.");
125
+      kill 'QUIT', $pid;
126
+      $w->{force} = 1 if $w->{graceful} + $self->graceful_timeout <= time;
127
+    }
128
+
129
+    # Normal stop
130
+    if (($self->{finished} && !$self->{graceful}) || $w->{force}) {
131
+      $log->debug("Stopping worker $pid.");
132
+      kill 'KILL', $pid;
133
+    }
134
+  }
135
+}
136
+
137
+sub _pid_file {
138
+  my $self = shift;
139
+
140
+  # Check if PID file already exists
141
+  return if -e (my $file = $self->pid_file);
142
+
143
+  # Create PID file
144
+  $self->app->log->info(qq{Creating process id file "$file".});
145
+  die qq{Can't create process id file "$file": $!}
146
+    unless open my $handle, '>', $file;
147
+  chmod 0644, $handle;
148
+  print $handle $$;
149
+}
150
+
151
+sub _reap {
152
+  my ($self, $pid) = @_;
153
+
154
+  # CLean up dead worker
155
+  $self->app->log->debug("Worker $pid stopped.")
156
+    if delete $self->emit(reap => $pid)->{pool}{$pid};
157
+}
158
+
159
+sub _spawn {
160
+  my $self = shift;
161
+
162
+  # Manager
163
+  die "Can't fork: $!" unless defined(my $pid = fork);
164
+  return $self->emit(spawn => $pid)->{pool}{$pid} = {time => time} if $pid;
165
+
166
+  # Prepare lock file
167
+  my $file = $self->{lock_file};
168
+  die qq{Can't open lock file "$file": $!} unless open my $handle, '>', $file;
169
+
170
+  # Change user/group
171
+  my $loop = $self->setuidgid->ioloop;
172
+
173
+  # Accept mutex
174
+  $loop->lock(
175
+    sub {
176
+
177
+      # Blocking ("ualarm" can't be imported on Windows)
178
+      my $l;
179
+      if ($_[1]) {
180
+        eval {
181
+          local $SIG{ALRM} = sub { die "alarm\n" };
182
+          my $old = Time::HiRes::ualarm $self->lock_timeout * 1000000;
183
+          $l = flock $handle, LOCK_EX;
184
+          Time::HiRes::ualarm $old;
185
+        };
186
+        if ($@) { $l = $@ eq "alarm\n" ? 0 : die($@) }
187
+      }
188
+
189
+      # Non blocking
190
+      else { $l = flock $handle, LOCK_EX | LOCK_NB }
191
+
192
+      return $l;
193
+    }
194
+  );
195
+  $loop->unlock(sub { flock $handle, LOCK_UN });
196
+
197
+  # Heartbeat messages (stop sending during graceful stop)
198
+  weaken $self;
199
+  $loop->recurring(
200
+    $self->heartbeat_interval => sub {
201
+      return unless shift->max_connections;
202
+      $self->{writer}->syswrite("$$\n") or exit 0;
203
+    }
204
+  );
205
+
206
+  # Clean worker environment
207
+  $SIG{$_} = 'DEFAULT' for qw(INT TERM CHLD TTIN TTOU);
208
+  $SIG{QUIT} = sub { $loop->max_connections(0) };
209
+  delete $self->{$_} for qw(poll reader);
210
+
211
+  # Start event loop
212
+  $self->app->log->debug("Worker $$ started.");
213
+  $loop->start;
214
+  exit 0;
215
+}
216
+
217
+sub _term {
218
+  my ($self, $graceful) = @_;
219
+  $self->emit(finish => $graceful)->{finished} = 1;
220
+  $self->{graceful} = 1 if $graceful;
221
+}
222
+
223
+1;
224
+
225
+=head1 NAME
226
+
227
+Mojo::Server::Prefork - Preforking non-blocking I/O HTTP and WebSocket server
228
+
229
+=head1 SYNOPSIS
230
+
231
+  use Mojo::Server::Prefork;
232
+
233
+  my $prefork = Mojo::Server::Prefork->new(listen => ['http://*:8080']);
234
+  $prefork->unsubscribe('request');
235
+  $prefork->on(request => sub {
236
+    my ($prefork, $tx) = @_;
237
+
238
+    # Request
239
+    my $method = $tx->req->method;
240
+    my $path   = $tx->req->url->path;
241
+
242
+    # Response
243
+    $tx->res->code(200);
244
+    $tx->res->headers->content_type('text/plain');
245
+    $tx->res->body("$method request for $path!");
246
+
247
+    # Resume transaction
248
+    $tx->resume;
249
+  });
250
+  $prefork->run;
251
+
252
+=head1 DESCRIPTION
253
+
254
+L<Mojo::Server::Prefork> is a full featured, UNIX optimized, preforking
255
+non-blocking I/O HTTP and WebSocket server, built around the very well tested
256
+and reliable L<Mojo::Server::Daemon>, with C<IPv6>, C<TLS>, C<Comet> (long
257
+polling) and multiple event loop support. Note that the server uses signals
258
+for process management, so you should avoid modifying signal handlers in your
259
+applications.
260
+
261
+Optional modules L<EV> (4.0+), L<IO::Socket::IP> (0.16+) and
262
+L<IO::Socket::SSL> (1.75+) are supported transparently through
263
+L<Mojo::IOLoop>, and used if installed. Individual features can also be
264
+disabled with the C<MOJO_NO_IPV6> and C<MOJO_NO_TLS> environment variables.
265
+
266
+See L<Mojolicious::Guides::Cookbook> for more.
267
+
268
+=head1 SIGNALS
269
+
270
+L<Mojo::Server::Prefork> can be controlled at runtime with the following
271
+signals.
272
+
273
+=head2 Manager
274
+
275
+=over 2
276
+
277
+=item INT, TERM
278
+
279
+Shutdown server immediately.
280
+
281
+=item QUIT
282
+
283
+Shutdown server gracefully.
284
+
285
+=item TTIN
286
+
287
+Increase worker pool by one.
288
+
289
+=item TTOU
290
+
291
+Decrease worker pool by one.
292
+
293
+=back
294
+
295
+=head2 Worker
296
+
297
+=over 2
298
+
299
+=item INT, TERM
300
+
301
+Stop worker immediately.
302
+
303
+=item QUIT
304
+
305
+Stop worker gracefully.
306
+
307
+=back
308
+
309
+=head1 EVENTS
310
+
311
+L<Mojo::Server::Prefork> inherits all events from L<Mojo::Server::Daemon> and
312
+can emit the following new ones.
313
+
314
+=head2 finish
315
+
316
+  $prefork->on(finish => sub {
317
+    my ($prefork, $graceful) = @_;
318
+    ...
319
+  });
320
+
321
+Emitted when the server shuts down.
322
+
323
+  $prefork->on(finish => sub {
324
+    my ($prefork, $graceful) = @_;
325
+    say $graceful ? 'Graceful server shutdown' : 'Server shutdown';
326
+  });
327
+
328
+=head2 heartbeat
329
+
330
+  $prefork->on(heartbeat => sub {
331
+    my ($prefork, $pid) = @_;
332
+    ...
333
+  });
334
+
335
+Emitted when a heartbeat message has been received from a worker.
336
+
337
+  $prefork->on(heartbeat => sub {
338
+    my ($prefork, $pid) = @_;
339
+    say "Worker $pid has a heartbeat";
340
+  });
341
+
342
+=head2 reap
343
+
344
+  $prefork->on(reap => sub {
345
+    my ($prefork, $pid) = @_;
346
+    ...
347
+  });
348
+
349
+Emitted when a child process dies.
350
+
351
+  $prefork->on(reap => sub {
352
+    my ($prefork, $pid) = @_;
353
+    say "Worker $pid stopped";
354
+  });
355
+
356
+=head2 spawn
357
+
358
+  $prefork->on(spawn => sub {
359
+    my ($prefork, $pid) = @_;
360
+    ...
361
+  });
362
+
363
+Emitted when a worker process is spawned.
364
+
365
+  $prefork->on(spawn => sub {
366
+    my ($prefork, $pid) = @_;
367
+    say "Worker $pid started";
368
+  });
369
+
370
+=head2 wait
371
+
372
+  $prefork->on(wait => sub {
373
+    my $prefork = shift;
374
+    ...
375
+  });
376
+
377
+Emitted when the manager starts waiting for new heartbeat messages.
378
+
379
+  $prefork->on(wait => sub {
380
+    my $prefork = shift;
381
+    my $workers = $prefork->workers;
382
+    say "Waiting for heartbeat messages from $workers workers";
383
+  });
384
+
385
+=head1 ATTRIBUTES
386
+
387
+L<Mojo::Server::Prefork> inherits all attributes from L<Mojo::Server::Daemon>
388
+and implements the following new ones.
389
+
390
+=head2 accept_interval
391
+
392
+  my $interval = $prefork->accept_interval;
393
+  $prefork     = $prefork->accept_interval(0.5);
394
+
395
+Interval in seconds for trying to reacquire the accept mutex and connection
396
+management, defaults to C<0.025>. Note that changing this value can affect
397
+performance and idle CPU usage.
398
+
399
+=head2 accepts
400
+
401
+  my $accepts = $prefork->accepts;
402
+  $prefork    = $prefork->accepts(100);
403
+
404
+Maximum number of connections a worker is allowed to accept before stopping
405
+gracefully, defaults to C<1000>. Setting the value to C<0> will allow workers
406
+to accept new connections indefinitely. Note that up to half of this value can
407
+be subtracted randomly to improve load balancing, and that worker processes
408
+will stop sending heartbeat messages once the limit has been reached.
409
+
410
+=head2 graceful_timeout
411
+
412
+  my $timeout = $prefork->graceful_timeout;
413
+  $prefork    = $prefork->graceful_timeout(15);
414
+
415
+Maximum amount of time in seconds stopping a worker gracefully may take before
416
+being forced, defaults to C<20>.
417
+
418
+=head2 heartbeat_interval
419
+
420
+  my $interval = $prefork->heartbeat_intrval;
421
+  $prefork     = $prefork->heartbeat_interval(3);
422
+
423
+Heartbeat interval in seconds, defaults to C<5>.
424
+
425
+=head2 heartbeat_timeout
426
+
427
+  my $timeout = $prefork->heartbeat_timeout;
428
+  $prefork    = $prefork->heartbeat_timeout(2);
429
+
430
+Maximum amount of time in seconds before a worker without a heartbeat will be
431
+stopped gracefully, defaults to C<20>.
432
+
433
+=head2 lock_file
434
+
435
+  my $file = $prefork->lock_file;
436
+  $prefork = $prefork->lock_file('/tmp/prefork.lock');
437
+
438
+Full path of accept mutex lock file prefix, to which the process id will be
439
+appended, defaults to a random temporary path.
440
+
441
+=head2 lock_timeout
442
+
443
+  my $timeout = $prefork->lock_timeout;
444
+  $prefork    = $prefork->lock_timeout(1);
445
+
446
+Maximum amount of time in seconds a worker may block when waiting for the
447
+accept mutex, defaults to C<0.5>.
448
+
449
+=head2 multi_accept
450
+
451
+  my $multi = $prefork->multi_accept;
452
+  $prefork  = $prefork->multi_accept(100);
453
+
454
+Number of connections to accept at once, defaults to C<50>.
455
+
456
+=head2 pid_file
457
+
458
+  my $file = $prefork->pid_file;
459
+  $prefork = $prefork->pid_file('/tmp/prefork.pid');
460
+
461
+Full path of process id file, defaults to a random temporary path.
462
+
463
+=head2 workers
464
+
465
+  my $workers = $prefork->workers;
466
+  $prefork    = $prefork->workers(10);
467
+
468
+Number of worker processes, defaults to C<4>. A good rule of thumb is two
469
+worker processes per CPU core.
470
+
471
+=head1 METHODS
472
+
473
+L<Mojo::Server::Prefork> inherits all methods from L<Mojo::Server::Daemon> and
474
+implements the following new ones.
475
+
476
+=head2 check_pid
477
+
478
+  my $pid = $prefork->check_pid;
479
+
480
+Get process id for running server from C<pid_file> or delete it if server is
481
+not running.
482
+
483
+  say 'Server is not running' unless $prefork->check_pid;
484
+
485
+=head2 run
486
+
487
+  $prefork->run;
488
+
489
+Run server.
490
+
491
+=head1 SEE ALSO
492
+
493
+L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
494
+
495
+=cut
+35 -42
mojolegacy/lib/Mojo/Template.pm
... ...
@@ -26,11 +26,8 @@ has tree      => sub { [] };
26 26
 sub build {
27 27
   my $self = shift;
28 28
 
29
-  # Lines
30 29
   my (@lines, $cpst, $multi);
31 30
   for my $line (@{$self->tree}) {
32
-
33
-    # New line
34 31
     push @lines, '';
35 32
     for (my $j = 0; $j < @{$line}; $j += 2) {
36 33
       my $type    = $line->[$j];
... ...
@@ -118,12 +115,11 @@ sub interpret {
118 115
     Mojo::Exception->throw(shift, [$self->template, $self->code]);
119 116
   };
120 117
 
121
-  # Interpret
122 118
   return undef unless my $compiled = $self->compiled;
123 119
   my $output = eval { $compiled->(@_) };
124 120
   return $output unless $@;
125 121
 
126
-  # Exception
122
+  # Exception with template context
127 123
   return Mojo::Exception->new($@, [$self->template])->verbose(1);
128 124
 }
129 125
 
... ...
@@ -133,7 +129,6 @@ sub parse {
133 129
   # Clean start
134 130
   delete $self->template($tmpl)->{tree};
135 131
 
136
-  # Token
137 132
   my $tag     = $self->tag_start;
138 133
   my $replace = $self->replace_mark;
139 134
   my $expr    = $self->expression_mark;
... ...
@@ -202,7 +197,7 @@ sub parse {
202 197
     # Normal line ending
203 198
     else { $line .= "\n" }
204 199
 
205
-    # Tokenize
200
+    # Mixed line
206 201
     my @token;
207 202
     for my $token (split $token_re, $line) {
208 203
 
... ...
@@ -270,14 +265,12 @@ sub render {
270 265
 sub render_file {
271 266
   my ($self, $path) = (shift, shift);
272 267
 
273
-  # Slurp file
274 268
   $self->name($path) unless defined $self->{name};
275
-  my $tmpl = slurp $path;
276
-
277
-  # Decode and render
269
+  my $tmpl     = slurp $path;
278 270
   my $encoding = $self->encoding;
279 271
   croak qq{Template "$path" has invalid encoding.}
280 272
     if $encoding && !defined($tmpl = decode $encoding, $tmpl);
273
+
281 274
   return $self->render($tmpl, @_);
282 275
 }
283 276
 
... ...
@@ -310,7 +303,7 @@ sub _wrap {
310 303
 
311 304
   # Escape function
312 305
   my $escape = $self->escape;
313
-  monkey_patch $self->namespace, '_escape', sub {
306
+  monkey_patch $self->namespace, _escape => sub {
314 307
     no warnings 'uninitialized';
315 308
     ref $_[0] eq 'Mojo::ByteStream' ? $_[0] : $escape->("$_[0]");
316 309
   };
... ...
@@ -321,7 +314,6 @@ sub _wrap {
321 314
   $lines->[0]  .= "sub { my \$_M = ''; @{[$self->prepend]}; do { $first";
322 315
   $lines->[-1] .= "@{[$self->append]}; \$_M } };";
323 316
 
324
-  # Code
325 317
   my $code = join "\n", @$lines;
326 318
   warn "-- Code for @{[$self->name]}\n@{[encode 'UTF-8', $code]}\n\n" if DEBUG;
327 319
   return $code;
... ...
@@ -402,7 +394,8 @@ the default in L<Mojolicious> C<.ep> templates for example.
402 394
 
403 395
 L<Mojo::ByteStream> objects are always excluded from automatic escaping.
404 396
 
405
-  <%= Mojo::ByteStream->new('<div>excluded!</div>') %>
397
+  % use Mojo::ByteStream 'b';
398
+  <%= b('<div>excluded!</div>') %>
406 399
 
407 400
 Newline characters can be escaped with a backslash.
408 401
 
... ...
@@ -461,14 +454,14 @@ error messages with context.
461 454
 
462 455
 L<Mojo::Template> implements the following attributes.
463 456
 
464
-=head2 C<auto_escape>
457
+=head2 auto_escape
465 458
 
466 459
   my $escape = $mt->auto_escape;
467 460
   $mt        = $mt->auto_escape(1);
468 461
 
469 462
 Activate automatic escaping.
470 463
 
471
-=head2 C<append>
464
+=head2 append
472 465
 
473 466
   my $code = $mt->append;
474 467
   $mt      = $mt->append('warn "Processed template"');
... ...
@@ -477,7 +470,7 @@ Append Perl code to compiled template. Note that this code should not contain
477 470
 newline characters, or line numbers in error messages might end up being
478 471
 wrong.
479 472
 
480
-=head2 C<capture_end>
473
+=head2 capture_end
481 474
 
482 475
   my $end = $mt->capture_end;
483 476
   $mt     = $mt->capture_end('end');
... ...
@@ -488,7 +481,7 @@ Keyword indicating the end of a capture block, defaults to C<end>.
488 481
     Some data!
489 482
   <% end %>
490 483
 
491
-=head2 C<capture_start>
484
+=head2 capture_start
492 485
 
493 486
   my $start = $mt->capture_start;
494 487
   $mt       = $mt->capture_start('begin');
... ...
@@ -499,14 +492,14 @@ Keyword indicating the start of a capture block, defaults to C<begin>.
499 492
     Some data!
500 493
   <% end %>
501 494
 
502
-=head2 C<code>
495
+=head2 code
503 496
 
504 497
   my $code = $mt->code;
505 498
   $mt      = $mt->code($code);
506 499
 
507 500
 Perl code for template.
508 501
 
509
-=head2 C<comment_mark>
502
+=head2 comment_mark
510 503
 
511 504
   my $mark = $mt->comment_mark;
512 505
   $mt      = $mt->comment_mark('#');
... ...
@@ -515,21 +508,21 @@ Character indicating the start of a comment, defaults to C<#>.
515 508
 
516 509
   <%# This is a comment %>
517 510
 
518
-=head2 C<compiled>
511
+=head2 compiled
519 512
 
520 513
   my $compiled = $mt->compiled;
521 514
   $mt          = $mt->compiled($compiled);
522 515
 
523 516
 Compiled template code.
524 517
 
525
-=head2 C<encoding>
518
+=head2 encoding
526 519
 
527 520
   my $encoding = $mt->encoding;
528 521
   $mt          = $mt->encoding('UTF-8');
529 522
 
530 523
 Encoding used for template files.
531 524
 
532
-=head2 C<escape>
525
+=head2 escape
533 526
 
534 527
   my $cb = $mt->escape;
535 528
   $mt    = $mt->escape(sub { reverse $_[0] });
... ...
@@ -537,7 +530,7 @@ Encoding used for template files.
537 530
 A callback used to escape the results of escaped expressions, defaults to
538 531
 L<Mojo::Util/"xml_escape">.
539 532
 
540
-=head2 C<escape_mark>
533
+=head2 escape_mark
541 534
 
542 535
   my $mark = $mt->escape_mark;
543 536
   $mt      = $mt->escape_mark('=');
... ...
@@ -546,7 +539,7 @@ Character indicating the start of an escaped expression, defaults to C<=>.
546 539
 
547 540
   <%== $foo %>
548 541
 
549
-=head2 C<expression_mark>
542
+=head2 expression_mark
550 543
 
551 544
   my $mark = $mt->expression_mark;
552 545
   $mt      = $mt->expression_mark('=');
... ...
@@ -555,7 +548,7 @@ Character indicating the start of an expression, defaults to C<=>.
555 548
 
556 549
   <%= $foo %>
557 550
 
558
-=head2 C<line_start>
551
+=head2 line_start
559 552
 
560 553
   my $start = $mt->line_start;
561 554
   $mt       = $mt->line_start('%');
... ...
@@ -564,7 +557,7 @@ Character indicating the start of a code line, defaults to C<%>.
564 557
 
565 558
   % $foo = 23;
566 559
 
567
-=head2 C<name>
560
+=head2 name
568 561
 
569 562
   my $name = $mt->name;
570 563
   $mt      = $mt->name('foo.mt');
... ...
@@ -573,7 +566,7 @@ Name of template currently being processed, defaults to C<template>. Note that
573 566
 this value should not contain quotes or newline characters, or error messages
574 567
 might end up being wrong.
575 568
 
576
-=head2 C<namespace>
569
+=head2 namespace
577 570
 
578 571
   my $namespace = $mt->namespace;
579 572
   $mt           = $mt->namespace('main');
... ...
@@ -582,7 +575,7 @@ Namespace used to compile templates, defaults to C<Mojo::Template::SandBox>.
582 575
 Note that namespaces should only be shared very carefully between templates,
583 576
 since functions and global variables will not be cleared automatically.
584 577
 
585
-=head2 C<prepend>
578
+=head2 prepend
586 579
 
587 580
   my $code = $mt->prepend;
588 581
   $mt      = $mt->prepend('my $self = shift;');
... ...
@@ -591,7 +584,7 @@ Prepend Perl code to compiled template. Note that this code should not contain
591 584
 newline characters, or line numbers in error messages might end up being
592 585
 wrong.
593 586
 
594
-=head2 C<replace_mark>
587
+=head2 replace_mark
595 588
 
596 589
   my $mark = $mt->replace_mark;
597 590
   $mt      = $mt->replace_mark('%');
... ...
@@ -600,7 +593,7 @@ Character used for escaping the start of a tag or line, defaults to C<%>.
600 593
 
601 594
   <%% my $foo = 23; %>
602 595
 
603
-=head2 C<tag_start>
596
+=head2 tag_start
604 597
 
605 598
   my $start = $mt->tag_start;
606 599
   $mt       = $mt->tag_start('<%');
... ...
@@ -609,7 +602,7 @@ Characters indicating the start of a tag, defaults to C<E<lt>%>.
609 602
 
610 603
   <% $foo = 23; %>
611 604
 
612
-=head2 C<tag_end>
605
+=head2 tag_end
613 606
 
614 607
   my $end = $mt->tag_end;
615 608
   $mt     = $mt->tag_end('%>');
... ...
@@ -618,21 +611,21 @@ Characters indicating the end of a tag, defaults to C<%E<gt>>.
618 611
 
619 612
   <%= $foo %>
620 613
 
621
-=head2 C<template>
614
+=head2 template
622 615
 
623 616
   my $template = $mt->template;
624 617
   $mt          = $mt->template($template);
625 618
 
626 619
 Raw template.
627 620
 
628
-=head2 C<tree>
621
+=head2 tree
629 622
 
630 623
   my $tree = $mt->tree;
631 624
   $mt      = $mt->tree($tree);
632 625
 
633 626
 Parsed tree.
634 627
 
635
-=head2 C<trim_mark>
628
+=head2 trim_mark
636 629
 
637 630
   my $mark = $mt->trim_mark;
638 631
   $mt      = $mt->trim_mark('-');
... ...
@@ -646,25 +639,25 @@ Character activating automatic whitespace trimming, defaults to C<=>.
646 639
 L<Mojo::Template> inherits all methods from L<Mojo::Base> and implements the
647 640
 following new ones.
648 641
 
649
-=head2 C<new>
642
+=head2 new
650 643
 
651 644
   my $mt = Mojo::Template->new;
652 645
 
653 646
 Construct a new L<Mojo::Template> object.
654 647
 
655
-=head2 C<build>
648
+=head2 build
656 649
 
657 650
   $mt = $mt->build;
658 651
 
659 652
 Build Perl code from tree.
660 653
 
661
-=head2 C<compile>
654
+=head2 compile
662 655
 
663 656
   my $exception = $mt->compile;
664 657
 
665 658
 Compile Perl code for template.
666 659
 
667
-=head2 C<interpret>
660
+=head2 interpret
668 661
 
669 662
   my $output = $mt->interpret;
670 663
   my $output = $mt->interpret(@args);
... ...
@@ -676,13 +669,13 @@ Interpret compiled template code.
676 669
   say $mt->interpret('Fry');
677 670
   say $mt->interpret('Leela');
678 671
 
679
-=head2 C<parse>
672
+=head2 parse
680 673
 
681 674
   $mt = $mt->parse($template);
682 675
 
683 676
 Parse template into tree.
684 677
 
685
-=head2 C<render>
678
+=head2 render
686 679
 
687 680
   my $output = $mt->render($template);
688 681
   my $output = $mt->render($template, @args);
... ...
@@ -691,7 +684,7 @@ Render template.
691 684
 
692 685
   say $mt->render('Hello <%= $_[0] %>!', 'Bender');
693 686
 
694
-=head2 C<render_file>
687
+=head2 render_file
695 688
 
696 689
   my $output = $mt->render_file('/tmp/foo.mt');
697 690
   my $output = $mt->render_file('/tmp/foo.mt', @args);
+30 -29
mojolegacy/lib/Mojo/Transaction.pm
... ...
@@ -101,9 +101,10 @@ L<Mojo::Transaction> is an abstract base class for transactions.
101 101
 
102 102
 =head1 EVENTS
103 103
 
104
-L<Mojo::Transaction> can emit the following events.
104
+L<Mojo::Transaction> inherits all events from L<Mojo::EventEmitter> and can
105
+emit the following new ones.
105 106
 
106
-=head2 C<connection>
107
+=head2 connection
107 108
 
108 109
   $tx->on(connection => sub {
109 110
     my ($tx, $connection) = @_;
... ...
@@ -112,7 +113,7 @@ L<Mojo::Transaction> can emit the following events.
112 113
 
113 114
 Emitted when a connection has been assigned to transaction.
114 115
 
115
-=head2 C<finish>
116
+=head2 finish
116 117
 
117 118
   $tx->on(finish => sub {
118 119
     my $tx = shift;
... ...
@@ -121,7 +122,7 @@ Emitted when a connection has been assigned to transaction.
121 122
 
122 123
 Emitted when transaction is finished.
123 124
 
124
-=head2 C<resume>
125
+=head2 resume
125 126
 
126 127
   $tx->on(resume => sub {
127 128
     my $tx = shift;
... ...
@@ -134,28 +135,28 @@ Emitted when transaction is resumed.
134 135
 
135 136
 L<Mojo::Transaction> implements the following attributes.
136 137
 
137
-=head2 C<kept_alive>
138
+=head2 kept_alive
138 139
 
139 140
   my $kept_alive = $tx->kept_alive;
140 141
   $tx            = $tx->kept_alive(1);
141 142
 
142 143
 Connection has been kept alive.
143 144
 
144
-=head2 C<local_address>
145
+=head2 local_address
145 146
 
146 147
   my $address = $tx->local_address;
147 148
   $tx         = $tx->local_address('127.0.0.1');
148 149
 
149 150
 Local interface address.
150 151
 
151
-=head2 C<local_port>
152
+=head2 local_port
152 153
 
153 154
   my $port = $tx->local_port;
154 155
   $tx      = $tx->local_port(8080);
155 156
 
156 157
 Local interface port.
157 158
 
158
-=head2 C<previous>
159
+=head2 previous
159 160
 
160 161
   my $previous = $tx->previous;
161 162
   $tx          = $tx->previous(Mojo::Transaction->new);
... ...
@@ -165,21 +166,21 @@ Previous transaction that triggered this followup transaction.
165 166
   # Path of previous request
166 167
   say $tx->previous->req->url->path;
167 168
 
168
-=head2 C<remote_port>
169
+=head2 remote_port
169 170
 
170 171
   my $port = $tx->remote_port;
171 172
   $tx      = $tx->remote_port(8081);
172 173
 
173 174
 Remote interface port.
174 175
 
175
-=head2 C<req>
176
+=head2 req
176 177
 
177 178
   my $req = $tx->req;
178 179
   $tx     = $tx->req(Mojo::Message::Request->new);
179 180
 
180 181
 HTTP request, defaults to a L<Mojo::Message::Request> object.
181 182
 
182
-=head2 C<res>
183
+=head2 res
183 184
 
184 185
   my $res = $tx->res;
185 186
   $tx     = $tx->res(Mojo::Message::Response->new);
... ...
@@ -191,92 +192,92 @@ HTTP response, defaults to a L<Mojo::Message::Response> object.
191 192
 L<Mojo::Transaction> inherits all methods from L<Mojo::EventEmitter> and
192 193
 implements the following new ones.
193 194
 
194
-=head2 C<client_close>
195
+=head2 client_close
195 196
 
196 197
   $tx->client_close;
197 198
 
198 199
 Transaction closed client-side, used to implement user agents.
199 200
 
200
-=head2 C<client_read>
201
+=head2 client_read
201 202
 
202
-  $tx->client_read($chunk);
203
+  $tx->client_read($bytes);
203 204
 
204 205
 Read data client-side, used to implement user agents. Meant to be overloaded
205 206
 in a subclass.
206 207
 
207
-=head2 C<client_write>
208
+=head2 client_write
208 209
 
209
-  my $chunk = $tx->client_write;
210
+  my $bytes = $tx->client_write;
210 211
 
211 212
 Write data client-side, used to implement user agents. Meant to be overloaded
212 213
 in a subclass.
213 214
 
214
-=head2 C<connection>
215
+=head2 connection
215 216
 
216 217
   my $connection = $tx->connection;
217 218
   $tx            = $tx->connection($connection);
218 219
 
219 220
 Connection identifier or socket.
220 221
 
221
-=head2 C<error>
222
+=head2 error
222 223
 
223 224
   my $err          = $tx->error;
224 225
   my ($err, $code) = $tx->error;
225 226
 
226 227
 Error and code.
227 228
 
228
-=head2 C<is_finished>
229
+=head2 is_finished
229 230
 
230 231
   my $success = $tx->is_finished;
231 232
 
232 233
 Check if transaction is finished.
233 234
 
234
-=head2 C<is_websocket>
235
+=head2 is_websocket
235 236
 
236 237
   my $false = $tx->is_websocket;
237 238
 
238 239
 False.
239 240
 
240
-=head2 C<is_writing>
241
+=head2 is_writing
241 242
 
242 243
   my $success = $tx->is_writing;
243 244
 
244 245
 Check if transaction is writing.
245 246
 
246
-=head2 C<resume>
247
+=head2 resume
247 248
 
248 249
   $tx = $tx->resume;
249 250
 
250 251
 Resume transaction.
251 252
 
252
-=head2 C<remote_address>
253
+=head2 remote_address
253 254
 
254 255
   my $address = $tx->remote_address;
255 256
   $tx         = $tx->remote_address('127.0.0.1');
256 257
 
257 258
 Remote interface address.
258 259
 
259
-=head2 C<server_close>
260
+=head2 server_close
260 261
 
261 262
   $tx->server_close;
262 263
 
263 264
 Transaction closed server-side, used to implement web servers.
264 265
 
265
-=head2 C<server_read>
266
+=head2 server_read
266 267
 
267
-  $tx->server_read($chunk);
268
+  $tx->server_read($bytes);
268 269
 
269 270
 Read data server-side, used to implement web servers. Meant to be overloaded
270 271
 in a subclass.
271 272
 
272
-=head2 C<server_write>
273
+=head2 server_write
273 274
 
274
-  my $chunk = $tx->server_write;
275
+  my $bytes = $tx->server_write;
275 276
 
276 277
 Write data server-side, used to implement web servers. Meant to be overloaded
277 278
 in a subclass.
278 279
 
279
-=head2 C<success>
280
+=head2 success
280 281
 
281 282
   my $res = $tx->success;
282 283
 
+15 -15
mojolegacy/lib/Mojo/Transaction/HTTP.pm
... ...
@@ -57,7 +57,7 @@ sub server_write { shift->_write(1) }
57 57
 sub _body {
58 58
   my ($self, $msg, $finish) = @_;
59 59
 
60
-  # Chunk
60
+  # Prepare chunk
61 61
   my $buffer = $msg->get_body_chunk($self->{offset});
62 62
   my $written = defined $buffer ? length $buffer : 0;
63 63
   $self->{write} = $msg->is_dynamic ? 1 : ($self->{write} - $written);
... ...
@@ -80,7 +80,7 @@ sub _body {
80 80
 sub _headers {
81 81
   my ($self, $msg, $head) = @_;
82 82
 
83
-  # Chunk
83
+  # Prepare chunk
84 84
   my $buffer = $msg->get_header_chunk($self->{offset});
85 85
   my $written = defined $buffer ? length $buffer : 0;
86 86
   $self->{write}  = $self->{write} - $written;
... ...
@@ -107,7 +107,7 @@ sub _headers {
107 107
 sub _start_line {
108 108
   my ($self, $msg) = @_;
109 109
 
110
-  # Chunk
110
+  # Prepare chunk
111 111
   my $buffer = $msg->get_start_line_chunk($self->{offset});
112 112
   my $written = defined $buffer ? length $buffer : 0;
113 113
   $self->{write}  = $self->{write} - $written;
... ...
@@ -195,7 +195,7 @@ in RFC 2616.
195 195
 L<Mojo::Transaction::HTTP> inherits all events from L<Mojo::Transaction> and
196 196
 can emit the following new ones.
197 197
 
198
-=head2 C<request>
198
+=head2 request
199 199
 
200 200
   $tx->on(request => sub {
201 201
     my $tx = shift;
... ...
@@ -209,7 +209,7 @@ Emitted when a request is ready and needs to be handled.
209 209
     $tx->res->headers->header('X-Bender' => 'Bite my shiny metal ass!');
210 210
   });
211 211
 
212
-=head2 C<unexpected>
212
+=head2 unexpected
213 213
 
214 214
   $tx->on(unexpected => sub {
215 215
     my ($tx, $res) = @_;
... ...
@@ -223,7 +223,7 @@ Emitted for unexpected C<1xx> responses that will be ignored.
223 223
     $tx->res->on(finish => sub { say 'Followup response is finished.' });
224 224
   });
225 225
 
226
-=head2 C<upgrade>
226
+=head2 upgrade
227 227
 
228 228
   $tx->on(upgrade => sub {
229 229
     my ($tx, $ws) = @_;
... ...
@@ -247,33 +247,33 @@ L<Mojo::Transaction::HTTP> inherits all attributes from L<Mojo::Transaction>.
247 247
 L<Mojo::Transaction::HTTP> inherits all methods from L<Mojo::Transaction> and
248 248
 implements the following new ones.
249 249
 
250
-=head2 C<client_read>
250
+=head2 client_read
251 251
 
252
-  $tx->client_read($chunk);
252
+  $tx->client_read($bytes);
253 253
 
254 254
 Read data client-side, used to implement user agents.
255 255
 
256
-=head2 C<client_write>
256
+=head2 client_write
257 257
 
258
-  my $chunk = $tx->client_write;
258
+  my $bytes = $tx->client_write;
259 259
 
260 260
 Write data client-side, used to implement user agents.
261 261
 
262
-=head2 C<keep_alive>
262
+=head2 keep_alive
263 263
 
264 264
   my $success = $tx->keep_alive;
265 265
 
266 266
 Check if connection can be kept alive.
267 267
 
268
-=head2 C<server_read>
268
+=head2 server_read
269 269
 
270
-  $tx->server_read($chunk);
270
+  $tx->server_read($bytes);
271 271
 
272 272
 Read data server-side, used to implement web servers.
273 273
 
274
-=head2 C<server_write>
274
+=head2 server_write
275 275
 
276
-  my $chunk = $tx->server_write;
276
+  my $bytes = $tx->server_write;
277 277
 
278 278
 Write data server-side, used to implement web servers.
279 279
 
+66 -41
mojolegacy/lib/Mojo/Transaction/WebSocket.pm
... ...
@@ -88,7 +88,6 @@ sub client_challenge {
88 88
 sub client_handshake {
89 89
   my $self = shift;
90 90
 
91
-  # Default headers
92 91
   my $headers = $self->req->headers;
93 92
   $headers->upgrade('websocket')  unless $headers->upgrade;
94 93
   $headers->connection('Upgrade') unless $headers->connection;
... ...
@@ -205,12 +204,10 @@ sub send {
205 204
   # Text
206 205
   elsif (!ref $frame) { $frame = [1, 0, 0, 0, TEXT, encode('UTF-8', $frame)] }
207 206
 
208
-  # Prepare frame
209 207
   $self->once(drain => $cb) if $cb;
210 208
   $self->{write} .= $self->build_frame(@$frame);
211 209
   $self->{state} = 'write';
212 210
 
213
-  # Resume
214 211
   return $self->emit('resume');
215 212
 }
216 213
 
... ...
@@ -230,28 +227,23 @@ sub server_handshake {
230 227
 sub server_read {
231 228
   my ($self, $chunk) = @_;
232 229
 
233
-  # Parse frames
234 230
   $self->{read} .= defined $chunk ? $chunk : '';
235 231
   while (my $frame = $self->parse_frame(\$self->{read})) {
236 232
     $self->emit(frame => $frame);
237 233
   }
238 234
 
239
-  # Resume
240 235
   $self->emit('resume');
241 236
 }
242 237
 
243 238
 sub server_write {
244 239
   my $self = shift;
245 240
 
246
-  # Drain
247 241
   unless (length(defined $self->{write} ? $self->{write} : '')) {
248 242
     $self->{state} = $self->{finished} ? 'finished' : 'read';
249 243
     $self->emit('drain');
250 244
   }
251 245
 
252
-  # Empty buffer
253
-  my $chunk = delete $self->{write};
254
-  return $chunk ? $chunk : '';
246
+  return do { my $tmp = delete $self->{write}; defined $tmp ? $tmp : '' };
255 247
 }
256 248
 
257 249
 sub _challenge { b64_encode(sha1_bytes(($_[0] || '') . GUID), '') }
... ...
@@ -280,7 +272,11 @@ sub _message {
280 272
 
281 273
   # Message
282 274
   my $msg = delete $self->{message};
283
-  $msg = decode 'UTF-8', $msg if $msg && delete $self->{op} == TEXT;
275
+  if (delete $self->{op} == TEXT) {
276
+    $self->emit(text => $msg);
277
+    $msg = decode 'UTF-8', $msg if $msg;
278
+  }
279
+  else { $self->emit(binary => $msg); }
284 280
   $self->emit(message => $msg);
285 281
 }
286 282
 
... ...
@@ -317,7 +313,21 @@ integer support, or they are limited to 32bit.
317 313
 L<Mojo::Transaction::WebSocket> inherits all events from L<Mojo::Transaction>
318 314
 and can emit the following new ones.
319 315
 
320
-=head2 C<drain>
316
+=head2 binary
317
+
318
+  $ws->on(binary => sub {
319
+    my ($ws, $bytes) = @_;
320
+    ...
321
+  });
322
+
323
+Emitted when a complete WebSocket binary message has been received.
324
+
325
+  $ws->on(binary => sub {
326
+    my ($ws, $bytes) = @_;
327
+    say "Binary: $bytes";
328
+  });
329
+
330
+=head2 drain
321 331
 
322 332
   $ws->on(drain => sub {
323 333
     my $ws = shift;
... ...
@@ -331,7 +341,7 @@ Emitted once all data has been sent.
331 341
     $ws->send(time);
332 342
   });
333 343
 
334
-=head2 C<frame>
344
+=head2 frame
335 345
 
336 346
   $ws->on(frame => sub {
337 347
     my ($ws, $frame) = @_;
... ...
@@ -351,26 +361,41 @@ Emitted when a WebSocket frame has been received.
351 361
     say "Payload: $frame->[5]";
352 362
   });
353 363
 
354
-=head2 C<message>
364
+=head2 message
355 365
 
356 366
   $ws->on(message => sub {
357 367
     my ($ws, $msg) = @_;
358 368
     ...
359 369
   });
360 370
 
361
-Emitted when a complete WebSocket message has been received.
371
+Emitted when a complete WebSocket message has been received, text messages
372
+will be automatically decoded.
362 373
 
363 374
   $ws->on(message => sub {
364 375
     my ($ws, $msg) = @_;
365 376
     say "Message: $msg";
366 377
   });
367 378
 
379
+=head2 text
380
+
381
+  $ws->on(text => sub {
382
+    my ($ws, $bytes) = @_;
383
+    ...
384
+  });
385
+
386
+Emitted when a complete WebSocket text message has been received.
387
+
388
+  $ws->on(text => sub {
389
+    my ($ws, $bytes) = @_;
390
+    say "Text: $bytes";
391
+  });
392
+
368 393
 =head1 ATTRIBUTES
369 394
 
370 395
 L<Mojo::Transaction::WebSocket> inherits all attributes from
371 396
 L<Mojo::Transaction> and implements the following new ones.
372 397
 
373
-=head2 C<handshake>
398
+=head2 handshake
374 399
 
375 400
   my $handshake = $ws->handshake;
376 401
   $ws           = $ws->handshake(Mojo::Transaction::HTTP->new);
... ...
@@ -378,14 +403,14 @@ L<Mojo::Transaction> and implements the following new ones.
378 403
 The original handshake transaction, defaults to a L<Mojo::Transaction::HTTP>
379 404
 object.
380 405
 
381
-=head2 C<masked>
406
+=head2 masked
382 407
 
383 408
   my $masked = $ws->masked;
384 409
   $ws        = $ws->masked(1);
385 410
 
386 411
 Mask outgoing frames with XOR cipher and a random 32bit key.
387 412
 
388
-=head2 C<max_websocket_size>
413
+=head2 max_websocket_size
389 414
 
390 415
   my $size = $ws->max_websocket_size;
391 416
   $ws      = $ws->max_websocket_size(1024);
... ...
@@ -398,7 +423,7 @@ C<MOJO_MAX_WEBSOCKET_SIZE> environment variable or C<262144>.
398 423
 L<Mojo::Transaction::WebSocket> inherits all methods from
399 424
 L<Mojo::Transaction> and implements the following new ones.
400 425
 
401
-=head2 C<new>
426
+=head2 new
402 427
 
403 428
   my $multi = Mojo::Content::MultiPart->new;
404 429
 
... ...
@@ -406,7 +431,7 @@ Construct a new L<Mojo::Transaction::WebSocket> object and subscribe to
406 431
 C<frame> event with default message parser, which also handles C<PING> and
407 432
 C<CLOSE> frames automatically.
408 433
 
409
-=head2 C<build_frame>
434
+=head2 build_frame
410 435
 
411 436
   my $bytes = $ws->build_frame($fin, $rsv1, $rsv2, $rsv3, $op, $payload);
412 437
 
... ...
@@ -430,68 +455,68 @@ Build WebSocket frame.
430 455
   # Pong frame with FIN bit and payload
431 456
   say $ws->build_frame(1, 0, 0, 0, 10, 'Test 123');
432 457
 
433
-=head2 C<client_challenge>
458
+=head2 client_challenge
434 459
 
435 460
   my $success = $ws->client_challenge;
436 461
 
437 462
 Check WebSocket handshake challenge client-side, used to implement user
438 463
 agents.
439 464
 
440
-=head2 C<client_handshake>
465
+=head2 client_handshake
441 466
 
442 467
   $ws->client_handshake;
443 468
 
444 469
 Perform WebSocket handshake client-side, used to implement user agents.
445 470
 
446
-=head2 C<client_read>
471
+=head2 client_read
447 472
 
448 473
   $ws->client_read($data);
449 474
 
450 475
 Read data client-side, used to implement user agents.
451 476
 
452
-=head2 C<client_write>
477
+=head2 client_write
453 478
 
454
-  my $chunk = $ws->client_write;
479
+  my $bytes = $ws->client_write;
455 480
 
456 481
 Write data client-side, used to implement user agents.
457 482
 
458
-=head2 C<connection>
483
+=head2 connection
459 484
 
460 485
   my $connection = $ws->connection;
461 486
 
462 487
 Connection identifier or socket.
463 488
 
464
-=head2 C<finish>
489
+=head2 finish
465 490
 
466 491
   $ws = $ws->finish;
467 492
 
468 493
 Finish the WebSocket connection gracefully.
469 494
 
470
-=head2 C<is_websocket>
495
+=head2 is_websocket
471 496
 
472 497
   my $true = $ws->is_websocket;
473 498
 
474 499
 True.
475 500
 
476
-=head2 C<kept_alive>
501
+=head2 kept_alive
477 502
 
478 503
   my $kept_alive = $ws->kept_alive;
479 504
 
480 505
 Connection has been kept alive.
481 506
 
482
-=head2 C<local_address>
507
+=head2 local_address
483 508
 
484 509
   my $address = $ws->local_address;
485 510
 
486 511
 Local interface address.
487 512
 
488
-=head2 C<local_port>
513
+=head2 local_port
489 514
 
490 515
   my $port = $ws->local_port;
491 516
 
492 517
 Local interface port.
493 518
 
494
-=head2 C<parse_frame>
519
+=head2 parse_frame
495 520
 
496 521
   my $frame = $ws->parse_frame(\$bytes);
497 522
 
... ...
@@ -506,37 +531,37 @@ Parse WebSocket frame.
506 531
   say "Opcode: $frame->[4]";
507 532
   say "Payload: $frame->[5]";
508 533
 
509
-=head2 C<remote_address>
534
+=head2 remote_address
510 535
 
511 536
   my $address = $ws->remote_address;
512 537
 
513 538
 Remote interface address.
514 539
 
515
-=head2 C<remote_port>
540
+=head2 remote_port
516 541
 
517 542
   my $port = $ws->remote_port;
518 543
 
519 544
 Remote interface port.
520 545
 
521
-=head2 C<req>
546
+=head2 req
522 547
 
523 548
   my $req = $ws->req;
524 549
 
525 550
 Handshake request, usually a L<Mojo::Message::Request> object.
526 551
 
527
-=head2 C<res>
552
+=head2 res
528 553
 
529 554
   my $res = $ws->res;
530 555
 
531 556
 Handshake response, usually a L<Mojo::Message::Response> object.
532 557
 
533
-=head2 C<resume>
558
+=head2 resume
534 559
 
535 560
   $ws = $ws->resume;
536 561
 
537 562
 Resume C<handshake> transaction.
538 563
 
539
-=head2 C<send>
564
+=head2 send
540 565
 
541 566
   $ws = $ws->send({binary => $bytes});
542 567
   $ws = $ws->send({text   => $bytes});
... ...
@@ -550,21 +575,21 @@ will be invoked once all data has been written.
550 575
   # Send "Ping" frame
551 576
   $ws->send([1, 0, 0, 0, 9, 'Hello World!']);
552 577
 
553
-=head2 C<server_handshake>
578
+=head2 server_handshake
554 579
 
555 580
   $ws->server_handshake;
556 581
 
557 582
 Perform WebSocket handshake server-side, used to implement web servers.
558 583
 
559
-=head2 C<server_read>
584
+=head2 server_read
560 585
 
561 586
   $ws->server_read($data);
562 587
 
563 588
 Read data server-side, used to implement web servers.
564 589
 
565
-=head2 C<server_write>
590
+=head2 server_write
566 591
 
567
-  my $chunk = $ws->server_write;
592
+  my $bytes = $ws->server_write;
568 593
 
569 594
 Write data server-side, used to implement web servers.
570 595
 
+19 -21
mojolegacy/lib/Mojo/URL.pm
... ...
@@ -31,7 +31,7 @@ sub authority {
31 31
     return $host =~ /[^\x00-\x7f]/ ? $self->ihost($host) : $self->host($host);
32 32
   }
33 33
 
34
-  # Format
34
+  # Build authority
35 35
   my $userinfo = $self->userinfo;
36 36
   $authority .= url_escape($userinfo, '^A-Za-z0-9\-._~!$&\'()*+,;=:') . '@'
37 37
     if $userinfo;
... ...
@@ -137,7 +137,6 @@ sub query {
137 137
 sub to_abs {
138 138
   my $self = shift;
139 139
 
140
-  # Already absolute
141 140
   my $abs = $self->clone;
142 141
   return $abs if $abs->is_abs;
143 142
 
... ...
@@ -173,7 +172,6 @@ sub to_abs {
173 172
 sub to_rel {
174 173
   my $self = shift;
175 174
 
176
-  # Already relative
177 175
   my $rel = $self->clone;
178 176
   return $rel unless $rel->is_abs;
179 177
 
... ...
@@ -274,42 +272,42 @@ Resource Locators with support for IDNA and IRIs.
274 272
 
275 273
 L<Mojo::URL> implements the following attributes.
276 274
 
277
-=head2 C<base>
275
+=head2 base
278 276
 
279 277
   my $base = $url->base;
280 278
   $url     = $url->base(Mojo::URL->new);
281 279
 
282 280
 Base of this URL.
283 281
 
284
-=head2 C<fragment>
282
+=head2 fragment
285 283
 
286 284
   my $fragment = $url->fragment;
287 285
   $url         = $url->fragment('foo');
288 286
 
289 287
 Fragment part of this URL.
290 288
 
291
-=head2 C<host>
289
+=head2 host
292 290
 
293 291
   my $host = $url->host;
294 292
   $url     = $url->host('127.0.0.1');
295 293
 
296 294
 Host part of this URL.
297 295
 
298
-=head2 C<port>
296
+=head2 port
299 297
 
300 298
   my $port = $url->port;
301 299
   $url     = $url->port(8080);
302 300
 
303 301
 Port part of this URL.
304 302
 
305
-=head2 C<scheme>
303
+=head2 scheme
306 304
 
307 305
   my $scheme = $url->scheme;
308 306
   $url       = $url->scheme('http');
309 307
 
310 308
 Scheme part of this URL.
311 309
 
312
-=head2 C<userinfo>
310
+=head2 userinfo
313 311
 
314 312
   my $userinfo = $url->userinfo;
315 313
   $url         = $url->userinfo('root:pass%3Bw0rd');
... ...
@@ -321,27 +319,27 @@ Userinfo part of this URL.
321 319
 L<Mojo::URL> inherits all methods from L<Mojo::Base> and implements the
322 320
 following new ones.
323 321
 
324
-=head2 C<new>
322
+=head2 new
325 323
 
326 324
   my $url = Mojo::URL->new;
327 325
   my $url = Mojo::URL->new('http://127.0.0.1:3000/foo?f=b&baz=2#foo');
328 326
 
329 327
 Construct a new L<Mojo::URL> object.
330 328
 
331
-=head2 C<authority>
329
+=head2 authority
332 330
 
333 331
   my $authority = $url->authority;
334 332
   $url          = $url->authority('root:pass%3Bw0rd@localhost:8080');
335 333
 
336 334
 Authority part of this URL.
337 335
 
338
-=head2 C<clone>
336
+=head2 clone
339 337
 
340 338
   my $url2 = $url->clone;
341 339
 
342 340
 Clone this URL.
343 341
 
344
-=head2 C<ihost>
342
+=head2 ihost
345 343
 
346 344
   my $ihost = $url->ihost;
347 345
   $url      = $url->ihost('xn--bcher-kva.ch');
... ...
@@ -351,19 +349,19 @@ Host part of this URL in punycode format.
351 349
   # "xn--da5b0n.net"
352 350
   Mojo::URL->new('http://☃.net')->ihost;
353 351
 
354
-=head2 C<is_abs>
352
+=head2 is_abs
355 353
 
356 354
   my $success = $url->is_abs;
357 355
 
358 356
 Check if URL is absolute.
359 357
 
360
-=head2 C<parse>
358
+=head2 parse
361 359
 
362 360
   $url = $url->parse('http://127.0.0.1:3000/foo/bar?fo=o&baz=23#foo');
363 361
 
364 362
 Parse URL.
365 363
 
366
-=head2 C<path>
364
+=head2 path
367 365
 
368 366
   my $path = $url->path;
369 367
   $url     = $url->path('/foo/bar');
... ...
@@ -382,7 +380,7 @@ defaults to a L<Mojo::Path> object.
382 380
   # "http://mojolicio.us/perldoc/Mojo/DOM/HTML"
383 381
   Mojo::URL->new('http://mojolicio.us/perldoc/Mojo/')->path('DOM/HTML');
384 382
 
385
-=head2 C<protocol>
383
+=head2 protocol
386 384
 
387 385
   my $proto = $url->protocol;
388 386
 
... ...
@@ -391,7 +389,7 @@ Normalized version of C<scheme>.
391 389
   # "http"
392 390
   Mojo::URL->new('HtTp://mojolicio.us')->protocol;
393 391
 
394
-=head2 C<query>
392
+=head2 query
395 393
 
396 394
   my $query = $url->query;
397 395
   $url      = $url->query(replace => 'with');
... ...
@@ -419,21 +417,21 @@ Query part of this URL, defaults to a L<Mojo::Parameters> object.
419 417
   # "http://mojolicio.us?a=1&b=2&a=2&c=3"
420 418
   Mojo::URL->new('http://mojolicio.us?a=1&b=2')->query({a => 2, c => 3});
421 419
 
422
-=head2 C<to_abs>
420
+=head2 to_abs
423 421
 
424 422
   my $abs = $url->to_abs;
425 423
   my $abs = $url->to_abs(Mojo::URL->new('http://kraih.com/foo'));
426 424
 
427 425
 Clone relative URL and turn it into an absolute one.
428 426
 
429
-=head2 C<to_rel>
427
+=head2 to_rel
430 428
 
431 429
   my $rel = $url->to_rel;
432 430
   my $rel = $url->to_rel(Mojo::URL->new('http://kraih.com/foo'));
433 431
 
434 432
 Clone absolute URL and turn it into a relative one.
435 433
 
436
-=head2 C<to_string>
434
+=head2 to_string
437 435
 
438 436
   my $string = $url->to_string;
439 437
   my $string = "$url";
+8 -8
mojolegacy/lib/Mojo/Upload.pm
... ...
@@ -40,28 +40,28 @@ L<Mojo::Upload> is a container for uploaded files.
40 40
 
41 41
 L<Mojo::Upload> implements the following attributes.
42 42
 
43
-=head2 C<asset>
43
+=head2 asset
44 44
 
45 45
   my $asset = $upload->asset;
46 46
   $upload   = $upload->asset(Mojo::Asset::File->new);
47 47
 
48 48
 Asset containing the uploaded data, defaults to a L<Mojo::Asset::File> object.
49 49
 
50
-=head2 C<filename>
50
+=head2 filename
51 51
 
52 52
   my $filename = $upload->filename;
53 53
   $upload      = $upload->filename('foo.txt');
54 54
 
55 55
 Name of the uploaded file.
56 56
 
57
-=head2 C<headers>
57
+=head2 headers
58 58
 
59 59
   my $headers = $upload->headers;
60 60
   $upload     = $upload->headers(Mojo::Headers->new);
61 61
 
62 62
 Headers for upload, defaults to a L<Mojo::Headers> object.
63 63
 
64
-=head2 C<name>
64
+=head2 name
65 65
 
66 66
   my $name = $upload->name;
67 67
   $upload  = $upload->name('foo');
... ...
@@ -73,21 +73,21 @@ Name of the upload.
73 73
 L<Mojo::Upload> inherits all methods from L<Mojo::Base> and implements the
74 74
 following new ones.
75 75
 
76
-=head2 C<move_to>
76
+=head2 move_to
77 77
 
78 78
   $upload = $upload->move_to('/home/sri/foo.txt');
79 79
 
80 80
 Move uploaded data into a specific file.
81 81
 
82
-=head2 C<size>
82
+=head2 size
83 83
 
84 84
   my $size = $upload->size;
85 85
 
86 86
 Size of uploaded data in bytes.
87 87
 
88
-=head2 C<slurp>
88
+=head2 slurp
89 89
 
90
-  my $string = $upload->slurp;
90
+  my $bytes = $upload->slurp;
91 91
 
92 92
 Read all uploaded data at once.
93 93
 
+51 -54
mojolegacy/lib/Mojo/UserAgent.pm
... ...
@@ -99,18 +99,19 @@ sub start {
99 99
     unless ($self->{nb}) {
100 100
       croak 'Blocking request in progress' if keys %{$self->{connections}};
101 101
       warn "-- Switching to non-blocking mode\n" if DEBUG;
102
+      $self->_cleanup;
102 103
       $self->{nb}++;
103
-      $self->_cleanup(1);
104 104
     }
105 105
     return $self->_start($tx, $cb);
106 106
   }
107 107
 
108 108
   # Start blocking
109 109
   warn "-- Blocking request (@{[$tx->req->url->to_abs]})\n" if DEBUG;
110
-  if (delete $self->{nb}) {
110
+  if ($self->{nb}) {
111 111
     croak 'Non-blocking requests in progress' if keys %{$self->{connections}};
112 112
     warn "-- Switching to blocking mode\n" if DEBUG;
113
-    $self->_cleanup(1);
113
+    $self->_cleanup;
114
+    delete $self->{nb};
114 115
   }
115 116
   $self->_start($tx => sub { $tx = pop });
116 117
 
... ...
@@ -159,7 +160,7 @@ sub _cache {
159 160
 }
160 161
 
161 162
 sub _cleanup {
162
-  my ($self, $restart) = @_;
163
+  my $self = shift;
163 164
   return unless my $loop = $self->_loop;
164 165
 
165 166
   # Clean up active connections (by closing them)
... ...
@@ -168,15 +169,13 @@ sub _cleanup {
168 169
   # Clean up keep alive connections
169 170
   $loop->remove($_->[1]) for @{delete $self->{cache} || []};
170 171
 
171
-  # Stop or restart server
172
+  # Stop server
172 173
   delete $self->{server};
173
-  $self->_server if $restart;
174 174
 }
175 175
 
176 176
 sub _connect {
177 177
   my ($self, $proto, $host, $port, $handle, $cb) = @_;
178 178
 
179
-  # Open connection
180 179
   weaken $self;
181 180
   my $id;
182 181
   return $id = $self->_loop->client(
... ...
@@ -301,7 +300,6 @@ sub _finish {
301 300
   my $res = $tx->res;
302 301
   if (my $err = $res->error) { $res->error($err) }
303 302
 
304
-  # Common errors
305 303
   else {
306 304
 
307 305
     # Premature connection close
... ...
@@ -335,6 +333,7 @@ sub _handle {
335 333
 
336 334
   # Upgrade connection to WebSocket
337 335
   elsif ($old && (my $new = $self->_upgrade($id))) {
336
+    if (my $jar = $self->cookie_jar) { $jar->extract($old) }
338 337
     $old->client_close;
339 338
     $self->_finish($new, $c->{cb});
340 339
     $new->client_read($old->res->leftovers);
... ...
@@ -387,13 +386,12 @@ sub _remove {
387 386
 sub _redirect {
388 387
   my ($self, $c, $old) = @_;
389 388
 
390
-  # Try to build followup transaction
391
-  return undef unless my $new = $self->transactor->redirect($old);
392
-
393 389
   # Follow redirect unless the maximum has been reached already
390
+  return undef unless my $new = $self->transactor->redirect($old);
394 391
   my $redirects = delete $c->{redirects} || 0;
395 392
   return undef unless $redirects < $self->max_redirects;
396 393
   my $id = $self->_start($new, delete $c->{cb});
394
+
397 395
   return $self->{connections}{$id}{redirects} = $redirects + 1;
398 396
 }
399 397
 
... ...
@@ -444,7 +442,7 @@ sub _start {
444 442
   # We identify ourselves and accept gzip compression
445 443
   my $headers = $req->headers;
446 444
   $headers->user_agent($self->name) unless $headers->user_agent;
447
-  $headers->accept_encoding('gzip') unless $headers->accept_encoding && $Compress::Raw::Zlib::VERSION;
445
+  $headers->accept_encoding('gzip') if (! $headers->accept_encoding && $Compress::Raw::Zlib::VERSION);
448 446
   if (my $jar = $self->cookie_jar) { $jar->inject($tx) }
449 447
 
450 448
   # Connect and add request timeout if necessary
... ...
@@ -461,18 +459,18 @@ sub _start {
461 459
 sub _upgrade {
462 460
   my ($self, $id) = @_;
463 461
 
464
-  # Try to upgrade transaction
465 462
   my $c = $self->{connections}{$id};
466 463
   return undef unless my $new = $self->transactor->upgrade($c->{tx});
467 464
   weaken $self;
468 465
   $new->on(resume => sub { $self->_write($id) });
466
+
469 467
   return $c->{tx} = $new;
470 468
 }
471 469
 
472 470
 sub _write {
473 471
   my ($self, $id) = @_;
474 472
 
475
-  # Get chunk
473
+  # Get and write chunk
476 474
   return unless my $c  = $self->{connections}{$id};
477 475
   return unless my $tx = $c->{tx};
478 476
   return unless $tx->is_writing;
... ...
@@ -480,8 +478,6 @@ sub _write {
480 478
   my $chunk = $tx->client_write;
481 479
   delete $c->{writing};
482 480
   warn "-- Client >>> Server (@{[$tx->req->url->to_abs]})\n$chunk\n" if DEBUG;
483
-
484
-  # Write chunk
485 481
   my $stream = $self->_loop->stream($id)->write($chunk);
486 482
   $self->_handle($id) if $tx->is_finished;
487 483
 
... ...
@@ -596,9 +592,10 @@ See L<Mojolicious::Guides::Cookbook> for more.
596 592
 
597 593
 =head1 EVENTS
598 594
 
599
-L<Mojo::UserAgent> can emit the following events.
595
+L<Mojo::UserAgent> inherits all events from L<Mojo::EventEmitter> and can emit
596
+the following new ones.
600 597
 
601
-=head2 C<error>
598
+=head2 error
602 599
 
603 600
   $ua->on(error => sub {
604 601
     my ($ua, $err) = @_;
... ...
@@ -612,7 +609,7 @@ Emitted if an error occurs that can't be associated with a transaction.
612 609
     say "This looks bad: $err";
613 610
   });
614 611
 
615
-=head2 C<start>
612
+=head2 start
616 613
 
617 614
   $ua->on(start => sub {
618 615
     my ($ua, $tx) = @_;
... ...
@@ -631,7 +628,7 @@ automatically prepared proxy C<CONNECT> requests and followed redirects.
631 628
 
632 629
 L<Mojo::UserAgent> implements the following attributes.
633 630
 
634
-=head2 C<ca>
631
+=head2 ca
635 632
 
636 633
   my $ca = $ua->ca;
637 634
   $ua    = $ua->ca('/etc/tls/ca.crt');
... ...
@@ -643,7 +640,7 @@ C<MOJO_CA_FILE> environment variable. Also activates hostname verification.
643 640
   IO::Socket::SSL::set_defaults(
644 641
     SSL_verify_callback => sub { say "Authority: $_[2]" and return $_[0] });
645 642
 
646
-=head2 C<cert>
643
+=head2 cert
647 644
 
648 645
   my $cert = $ua->cert;
649 646
   $ua      = $ua->cert('/etc/tls/client.crt');
... ...
@@ -651,7 +648,7 @@ C<MOJO_CA_FILE> environment variable. Also activates hostname verification.
651 648
 Path to TLS certificate file, defaults to the value of the C<MOJO_CERT_FILE>
652 649
 environment variable.
653 650
 
654
-=head2 C<connect_timeout>
651
+=head2 connect_timeout
655 652
 
656 653
   my $timeout = $ua->connect_timeout;
657 654
   $ua         = $ua->connect_timeout(5);
... ...
@@ -660,7 +657,7 @@ Maximum amount of time in seconds establishing a connection may take before
660 657
 getting canceled, defaults to the value of the C<MOJO_CONNECT_TIMEOUT>
661 658
 environment variable or C<10>.
662 659
 
663
-=head2 C<cookie_jar>
660
+=head2 cookie_jar
664 661
 
665 662
   my $cookie_jar = $ua->cookie_jar;
666 663
   $ua            = $ua->cookie_jar(Mojo::UserAgent::CookieJar->new);
... ...
@@ -671,21 +668,21 @@ L<Mojo::UserAgent::CookieJar> object.
671 668
   # Disable cookie jar
672 669
   $ua->cookie_jar(0);
673 670
 
674
-=head2 C<http_proxy>
671
+=head2 http_proxy
675 672
 
676 673
   my $proxy = $ua->http_proxy;
677 674
   $ua       = $ua->http_proxy('http://sri:secret@127.0.0.1:8080');
678 675
 
679 676
 Proxy server to use for HTTP and WebSocket requests.
680 677
 
681
-=head2 C<https_proxy>
678
+=head2 https_proxy
682 679
 
683 680
   my $proxy = $ua->https_proxy;
684 681
   $ua       = $ua->https_proxy('http://sri:secret@127.0.0.1:8080');
685 682
 
686 683
 Proxy server to use for HTTPS and WebSocket requests.
687 684
 
688
-=head2 C<inactivity_timeout>
685
+=head2 inactivity_timeout
689 686
 
690 687
   my $timeout = $ua->inactivity_timeout;
691 688
   $ua         = $ua->inactivity_timeout(15);
... ...
@@ -695,7 +692,7 @@ closed, defaults to the value of the C<MOJO_INACTIVITY_TIMEOUT> environment
695 692
 variable or C<20>. Setting the value to C<0> will allow connections to be
696 693
 inactive indefinitely.
697 694
 
698
-=head2 C<ioloop>
695
+=head2 ioloop
699 696
 
700 697
   my $loop = $ua->ioloop;
701 698
   $ua      = $ua->ioloop(Mojo::IOLoop->new);
... ...
@@ -703,7 +700,7 @@ inactive indefinitely.
703 700
 Event loop object to use for blocking I/O operations, defaults to a
704 701
 L<Mojo::IOLoop> object.
705 702
 
706
-=head2 C<key>
703
+=head2 key
707 704
 
708 705
   my $key = $ua->key;
709 706
   $ua     = $ua->key('/etc/tls/client.crt');
... ...
@@ -711,14 +708,14 @@ L<Mojo::IOLoop> object.
711 708
 Path to TLS key file, defaults to the value of the C<MOJO_KEY_FILE>
712 709
 environment variable.
713 710
 
714
-=head2 C<local_address>
711
+=head2 local_address
715 712
 
716 713
   my $address = $ua->local_address;
717 714
   $ua         = $ua->local_address('127.0.0.1');
718 715
 
719 716
 Local address to bind to.
720 717
 
721
-=head2 C<max_connections>
718
+=head2 max_connections
722 719
 
723 720
   my $max = $ua->max_connections;
724 721
   $ua     = $ua->max_connections(5);
... ...
@@ -726,7 +723,7 @@ Local address to bind to.
726 723
 Maximum number of keep alive connections that the user agent will retain
727 724
 before it starts closing the oldest cached ones, defaults to C<5>.
728 725
 
729
-=head2 C<max_redirects>
726
+=head2 max_redirects
730 727
 
731 728
   my $max = $ua->max_redirects;
732 729
   $ua     = $ua->max_redirects(3);
... ...
@@ -735,21 +732,21 @@ Maximum number of redirects the user agent will follow before it fails,
735 732
 defaults to the value of the C<MOJO_MAX_REDIRECTS> environment variable or
736 733
 C<0>.
737 734
 
738
-=head2 C<name>
735
+=head2 name
739 736
 
740 737
   my $name = $ua->name;
741 738
   $ua      = $ua->name('Mojolicious');
742 739
 
743 740
 Value for C<User-Agent> request header, defaults to C<Mojolicious (Perl)>.
744 741
 
745
-=head2 C<no_proxy>
742
+=head2 no_proxy
746 743
 
747 744
   my $no_proxy = $ua->no_proxy;
748 745
   $ua          = $ua->no_proxy([qw(localhost intranet.mojolicio.us)]);
749 746
 
750 747
 Domains that don't require a proxy server to be used.
751 748
 
752
-=head2 C<request_timeout>
749
+=head2 request_timeout
753 750
 
754 751
   my $timeout = $ua->request_timeout;
755 752
   $ua         = $ua->request_timeout(5);
... ...
@@ -763,7 +760,7 @@ indefinitely. The timeout will reset for every followed redirect.
763 760
   # Total limit of 5 seconds, of which 3 seconds may be spent connecting
764 761
   $ua->max_redirects(0)->connect_timeout(3)->request_timeout(5);
765 762
 
766
-=head2 C<transactor>
763
+=head2 transactor
767 764
 
768 765
   my $t = $ua->transactor;
769 766
   $ua   = $ua->transactor(Mojo::UserAgent::Transactor->new);
... ...
@@ -775,7 +772,7 @@ Transaction builder, defaults to a L<Mojo::UserAgent::Transactor> object.
775 772
 L<Mojo::UserAgent> inherits all methods from L<Mojo::EventEmitter> and
776 773
 implements the following new ones.
777 774
 
778
-=head2 C<app>
775
+=head2 app
779 776
 
780 777
   my $app = Mojo::UserAgent->app;
781 778
             Mojo::UserAgent->app(MyApp->new);
... ...
@@ -794,7 +791,7 @@ applications override the global default.
794 791
   # Change application behavior
795 792
   $ua->app->defaults(testing => 'oh yea!');
796 793
 
797
-=head2 C<app_url>
794
+=head2 app_url
798 795
 
799 796
   my $url = $ua->app_url;
800 797
   my $url = $ua->app_url('http');
... ...
@@ -805,7 +802,7 @@ Get absolute L<Mojo::URL> object for C<app> and switch protocol if necessary.
805 802
   # Port currently used for processing relative URLs
806 803
   say $ua->app_url->port;
807 804
 
808
-=head2 C<build_form_tx>
805
+=head2 build_form_tx
809 806
 
810 807
   my $tx = $ua->build_form_tx('http://kraih.com' => {a => 'b'});
811 808
   my $tx = $ua->build_form_tx('kraih.com', 'UTF-8', {a => 'b'}, {DNT => 1});
... ...
@@ -813,7 +810,7 @@ Get absolute L<Mojo::URL> object for C<app> and switch protocol if necessary.
813 810
 Generate L<Mojo::Transaction::HTTP> object with
814 811
 L<Mojo::UserAgent::Transactor/"form">.
815 812
 
816
-=head2 C<build_json_tx>
813
+=head2 build_json_tx
817 814
 
818 815
   my $tx = $ua->build_json_tx('http://kraih.com' => {a => 'b'});
819 816
   my $tx = $ua->build_json_tx('kraih.com' => {a => 'b'} => {DNT => 1});
... ...
@@ -821,7 +818,7 @@ L<Mojo::UserAgent::Transactor/"form">.
821 818
 Generate L<Mojo::Transaction::HTTP> object with
822 819
 L<Mojo::UserAgent::Transactor/"json">.
823 820
 
824
-=head2 C<build_tx>
821
+=head2 build_tx
825 822
 
826 823
   my $tx = $ua->build_tx(GET => 'kraih.com');
827 824
   my $tx = $ua->build_tx(PUT => 'http://kraih.com' => {DNT => 1} => 'Hi!');
... ...
@@ -834,7 +831,7 @@ L<Mojo::UserAgent::Transactor/"tx">.
834 831
   $tx->req->cookies({name => 'foo', value => 'bar'});
835 832
   $ua->start($tx);
836 833
 
837
-=head2 C<build_websocket_tx>
834
+=head2 build_websocket_tx
838 835
 
839 836
   my $tx = $ua->build_websocket_tx('ws://localhost:3000');
840 837
   my $tx = $ua->build_websocket_tx('ws://localhost:3000' => {DNT => 1});
... ...
@@ -842,7 +839,7 @@ L<Mojo::UserAgent::Transactor/"tx">.
842 839
 Generate L<Mojo::Transaction::HTTP> object with
843 840
 L<Mojo::UserAgent::Transactor/"websocket">.
844 841
 
845
-=head2 C<delete>
842
+=head2 delete
846 843
 
847 844
   my $tx = $ua->delete('kraih.com');
848 845
   my $tx = $ua->delete('http://kraih.com' => {DNT => 1} => 'Hi!');
... ...
@@ -858,7 +855,7 @@ append a callback to perform requests non-blocking.
858 855
   });
859 856
   Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
860 857
 
861
-=head2 C<detect_proxy>
858
+=head2 detect_proxy
862 859
 
863 860
   $ua = $ua->detect_proxy;
864 861
 
... ...
@@ -866,7 +863,7 @@ Check environment variables C<HTTP_PROXY>, C<http_proxy>, C<HTTPS_PROXY>,
866 863
 C<https_proxy>, C<NO_PROXY> and C<no_proxy> for proxy information. Automatic
867 864
 proxy detection can be enabled with the C<MOJO_PROXY> environment variable.
868 865
 
869
-=head2 C<get>
866
+=head2 get
870 867
 
871 868
   my $tx = $ua->get('kraih.com');
872 869
   my $tx = $ua->get('http://kraih.com' => {DNT => 1} => 'Hi!');
... ...
@@ -882,7 +879,7 @@ append a callback to perform requests non-blocking.
882 879
   });
883 880
   Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
884 881
 
885
-=head2 C<head>
882
+=head2 head
886 883
 
887 884
   my $tx = $ua->head('kraih.com');
888 885
   my $tx = $ua->head('http://kraih.com' => {DNT => 1} => 'Hi!');
... ...
@@ -898,13 +895,13 @@ append a callback to perform requests non-blocking.
898 895
   });
899 896
   Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
900 897
 
901
-=head2 C<need_proxy>
898
+=head2 need_proxy
902 899
 
903 900
   my $success = $ua->need_proxy('intranet.mojolicio.us');
904 901
 
905 902
 Check if request for domain would use a proxy server.
906 903
 
907
-=head2 C<options>
904
+=head2 options
908 905
 
909 906
   my $tx = $ua->options('kraih.com');
910 907
   my $tx = $ua->options('http://kraih.com' => {DNT => 1} => 'Hi!');
... ...
@@ -920,7 +917,7 @@ append a callback to perform requests non-blocking.
920 917
   });
921 918
   Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
922 919
 
923
-=head2 C<patch>
920
+=head2 patch
924 921
 
925 922
   my $tx = $ua->patch('kraih.com');
926 923
   my $tx = $ua->patch('http://kraih.com' => {DNT => 1} => 'Hi!');
... ...
@@ -936,7 +933,7 @@ append a callback to perform requests non-blocking.
936 933
   });
937 934
   Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
938 935
 
939
-=head2 C<post>
936
+=head2 post
940 937
 
941 938
   my $tx = $ua->post('kraih.com');
942 939
   my $tx = $ua->post('http://kraih.com' => {DNT => 1} => 'Hi!');
... ...
@@ -952,7 +949,7 @@ append a callback to perform requests non-blocking.
952 949
   });
953 950
   Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
954 951
 
955
-=head2 C<post_form>
952
+=head2 post_form
956 953
 
957 954
   my $tx = $ua->post_form('http://kraih.com' => {a => 'b'});
958 955
   my $tx = $ua->post_form('kraih.com', 'UTF-8', {a => 'b'}, {DNT => 1});
... ...
@@ -968,7 +965,7 @@ perform requests non-blocking.
968 965
   });
969 966
   Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
970 967
 
971
-=head2 C<post_json>
968
+=head2 post_json
972 969
 
973 970
   my $tx = $ua->post_json('http://kraih.com' => {a => 'b'});
974 971
   my $tx = $ua->post_json('kraih.com' => {a => 'b'} => {DNT => 1});
... ...
@@ -984,7 +981,7 @@ perform requests non-blocking.
984 981
   });
985 982
   Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
986 983
 
987
-=head2 C<put>
984
+=head2 put
988 985
 
989 986
   my $tx = $ua->put('kraih.com');
990 987
   my $tx = $ua->put('http://kraih.com' => {DNT => 1} => 'Hi!');
... ...
@@ -1000,7 +997,7 @@ append a callback to perform requests non-blocking.
1000 997
   });
1001 998
   Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
1002 999
 
1003
-=head2 C<start>
1000
+=head2 start
1004 1001
 
1005 1002
   my $tx = $ua->start(Mojo::Transaction::HTTP->new);
1006 1003
 
... ...
@@ -1014,7 +1011,7 @@ non-blocking.
1014 1011
   });
1015 1012
   Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
1016 1013
 
1017
-=head2 C<websocket>
1014
+=head2 websocket
1018 1015
 
1019 1016
   $ua->websocket('ws://localhost:3000' => sub {...});
1020 1017
   $ua->websocket('ws://localhost:3000' => {DNT => 1} => sub {...});
+27 -15
mojolegacy/lib/Mojo/UserAgent/CookieJar.pm
... ...
@@ -2,13 +2,13 @@ package Mojo::UserAgent::CookieJar;
2 2
 use Mojo::Base -base;
3 3
 
4 4
 use Mojo::Cookie::Request;
5
+use Mojo::Path;
5 6
 
6 7
 has max_cookie_size => 4096;
7 8
 
8 9
 sub add {
9 10
   my ($self, @cookies) = @_;
10 11
 
11
-  # Add cookies
12 12
   my $size = $self->max_cookie_size;
13 13
   for my $cookie (@cookies) {
14 14
 
... ...
@@ -41,18 +41,28 @@ sub extract {
41 41
   my ($self, $tx) = @_;
42 42
   my $url = $tx->req->url;
43 43
   for my $cookie (@{$tx->res->cookies}) {
44
-    $cookie->domain($url->host) unless $cookie->domain;
45
-    $cookie->path($url->path)   unless $cookie->path;
46
-    $self->add($cookie);
44
+
45
+    # Validate domain
46
+    my $host = lc $url->ihost;
47
+    my $domain = lc(defined $cookie->domain ? $cookie->domain : $host);
48
+    $domain =~ s/^\.//;
49
+    next unless $host eq $domain || $host =~ /\Q.$domain\E$/;
50
+    next if $host =~ /\.\d+$/;
51
+    $cookie->domain($domain);
52
+
53
+    # Validate path
54
+    my $path = defined $cookie->path ? $cookie->path : $url->path->to_dir->to_abs_string;
55
+    $path = Mojo::Path->new($path)->trailing_slash(0)->to_abs_string;
56
+    next unless _path($path, $url->path->to_abs_string);
57
+    $self->add($cookie->path($path));
47 58
   }
48 59
 }
49 60
 
50 61
 sub find {
51 62
   my ($self, $url) = @_;
52 63
 
53
-  # Look through the jar
54
-  return unless my $domain = $url->host;
55
-  my $path = $url->path->to_string || '/';
64
+  return unless my $domain = lc(defined $url->ihost ? $url->ihost : '');
65
+  my $path = $url->path->to_abs_string;
56 66
   my @found;
57 67
   while ($domain =~ /[^.]+\.[^.]+|localhost$/) {
58 68
     next unless my $old = $self->{jar}{$domain};
... ...
@@ -68,7 +78,7 @@ sub find {
68 78
 
69 79
       # Taste cookie
70 80
       next if $cookie->secure && $url->protocol ne 'https';
71
-      next unless $path =~ /^\Q@{[$cookie->path]}/;
81
+      next unless _path($cookie->path, $path);
72 82
       my $name  = $cookie->name;
73 83
       my $value = $cookie->value;
74 84
       push @found, Mojo::Cookie::Request->new(name => $name, value => $value);
... ...
@@ -88,6 +98,8 @@ sub inject {
88 98
   $req->cookies($self->find($req->url));
89 99
 }
90 100
 
101
+sub _path { $_[0] eq '/' || $_[0] eq $_[1] || $_[1] =~ m!^\Q$_[0]/! }
102
+
91 103
 1;
92 104
 
93 105
 =head1 NAME
... ...
@@ -124,7 +136,7 @@ L<Mojo::UserAgent>.
124 136
 
125 137
 L<Mojo::UserAgent::CookieJar> implements the following attributes.
126 138
 
127
-=head2 C<max_cookie_size>
139
+=head2 max_cookie_size
128 140
 
129 141
   my $size = $jar->max_cookie_size;
130 142
   $jar     = $jar->max_cookie_size(4096);
... ...
@@ -136,38 +148,38 @@ Maximum cookie size in bytes, defaults to C<4096>.
136 148
 L<Mojo::UserAgent::CookieJar> inherits all methods from L<Mojo::Base> and
137 149
 implements the following new ones.
138 150
 
139
-=head2 C<add>
151
+=head2 add
140 152
 
141 153
   $jar = $jar->add(@cookies);
142 154
 
143 155
 Add multiple L<Mojo::Cookie::Response> objects to the jar.
144 156
 
145
-=head2 C<all>
157
+=head2 all
146 158
 
147 159
   my @cookies = $jar->all;
148 160
 
149 161
 Return all L<Mojo::Cookie::Response> objects that are currently stored in the
150 162
 jar.
151 163
 
152
-=head2 C<empty>
164
+=head2 empty
153 165
 
154 166
   $jar->empty;
155 167
 
156 168
 Empty the jar.
157 169
 
158
-=head2 C<extract>
170
+=head2 extract
159 171
 
160 172
   $jar->extract($tx);
161 173
 
162 174
 Extract response cookies from transaction.
163 175
 
164
-=head2 C<find>
176
+=head2 find
165 177
 
166 178
   my @cookies = $jar->find($url);
167 179
 
168 180
 Find L<Mojo::Cookie::Request> objects in the jar for L<Mojo::URL> object.
169 181
 
170
-=head2 C<inject>
182
+=head2 inject
171 183
 
172 184
   $jar->inject($tx);
173 185
 
+60 -76
mojolegacy/lib/Mojo/UserAgent/Transactor.pm
... ...
@@ -1,7 +1,7 @@
1 1
 package Mojo::UserAgent::Transactor;
2 2
 use Mojo::Base -base;
3 3
 
4
-use File::Spec::Functions 'splitpath';
4
+use File::Basename 'basename';
5 5
 use Mojo::Asset::File;
6 6
 use Mojo::Asset::Memory;
7 7
 use Mojo::Content::MultiPart;
... ...
@@ -31,57 +31,25 @@ sub endpoint {
31 31
 }
32 32
 
33 33
 sub form {
34
-  my ($self, $url) = (shift, shift);
35
-
36
-  # Form
37
-  my $encoding = shift;
34
+  my ($self, $url, $encoding) = (shift, shift, shift);
38 35
   my $form = ref $encoding ? $encoding : shift;
39 36
   $encoding = undef if ref $encoding;
40 37
 
41
-  # Parameters
42
-  my $params = Mojo::Parameters->new;
43
-  $params->charset($encoding) if defined $encoding;
44
-  my $multipart;
45
-  for my $name (sort keys %$form) {
46
-    my $value = $form->{$name};
47
-
48
-    # Array
49
-    if (ref $value eq 'ARRAY') { $params->append($name, $_) for @$value }
50
-
51
-    # Hash
52
-    elsif (ref $value eq 'HASH') {
53
-
54
-      # Enforce "multipart/form-data"
55
-      $multipart++;
56
-
57
-      # File
58
-      if (my $file = $value->{file}) {
59
-        $value->{file} = Mojo::Asset::File->new(path => $file) if !ref $file;
60
-        $value->{filename} ||= (splitpath($value->{file}->path))[2]
61
-          if $value->{file}->isa('Mojo::Asset::File');
62
-      }
63
-
64
-      # Memory
65
-      elsif (defined(my $content = delete $value->{content})) {
66
-        $value->{file} = Mojo::Asset::Memory->new->add_chunk($content);
67
-      }
68
-
69
-      push @{$params->params}, $name, $value;
70
-    }
71
-
72
-    # Single value
73
-    else { $params->append($name, $value) }
74
-  }
75
-
76
-  # New transaction
38
+  # Start with normal POST transaction
77 39
   my $tx = $self->tx(POST => $url, @_);
78 40
 
79
-  # Multipart
41
+  # Check for uploads and force multipart if necessary
42
+  my $multipart;
43
+  for my $value (map { ref $_ eq 'ARRAY' ? @$_ : $_ } values %$form) {
44
+    ++$multipart and last if ref $value eq 'HASH';
45
+  }
80 46
   my $req     = $tx->req;
81 47
   my $headers = $req->headers;
82 48
   $headers->content_type('multipart/form-data') if $multipart;
49
+
50
+  # Multipart
83 51
   if ((defined $headers->content_type ? $headers->content_type : '') eq 'multipart/form-data') {
84
-    my $parts = $self->_multipart($encoding, $params->to_hash);
52
+    my $parts = $self->_multipart($encoding, $form);
85 53
     $req->content(
86 54
       Mojo::Content::MultiPart->new(headers => $headers, parts => $parts));
87 55
   }
... ...
@@ -89,7 +57,9 @@ sub form {
89 57
   # Urlencoded
90 58
   else {
91 59
     $headers->content_type('application/x-www-form-urlencoded');
92
-    $req->body($params->to_string);
60
+    my $p = Mojo::Parameters->new(map { $_ => $form->{$_} } sort keys %$form);
61
+    $p->charset($encoding) if defined $encoding;
62
+    $req->body($p->to_string);
93 63
   }
94 64
 
95 65
   return $tx;
... ...
@@ -203,36 +173,48 @@ sub websocket {
203 173
 sub _multipart {
204 174
   my ($self, $encoding, $form) = @_;
205 175
 
206
-  # Parts
207 176
   my @parts;
208 177
   for my $name (sort keys %$form) {
209 178
     my $values = $form->{$name};
210
-    my $part   = Mojo::Content::Single->new;
211
-
212
-    # File
213
-    my $filename;
214
-    my $headers = $part->headers;
215
-    if (ref $values eq 'HASH') {
216
-      $filename = delete $values->{filename} || $name;
217
-      $filename = encode $encoding, $filename if $encoding;
218
-      push @parts, $part->asset(delete $values->{file});
219
-      $headers->from_hash($values);
220
-    }
179
+    for my $value (ref $values eq 'ARRAY' ? @$values : ($values)) {
180
+      push @parts, my $part = Mojo::Content::Single->new;
181
+
182
+      # Upload
183
+      my $filename;
184
+      my $headers = $part->headers;
185
+      if (ref $value eq 'HASH') {
186
+
187
+        # File
188
+        if (my $file = delete $value->{file}) {
189
+          $file = Mojo::Asset::File->new(path => $file) unless ref $file;
190
+          $part->asset($file);
191
+          $value->{filename} ||= basename $file->path
192
+            if $file->isa('Mojo::Asset::File');
193
+        }
194
+
195
+        # Memory
196
+        elsif (defined(my $content = delete $value->{content})) {
197
+          $part->asset(Mojo::Asset::Memory->new->add_chunk($content));
198
+        }
199
+
200
+        # Filename and headers
201
+        $filename = delete $value->{filename} || $name;
202
+        $filename = encode $encoding, $filename if $encoding;
203
+        $headers->from_hash($value);
204
+      }
221 205
 
222
-    # Fields
223
-    else {
224
-      for my $value (ref $values ? @$values : ($values)) {
225
-        push @parts, $part = Mojo::Content::Single->new(headers => $headers);
206
+      # Field
207
+      else {
226 208
         $value = encode $encoding, $value if $encoding;
227
-        $part->asset->add_chunk($value);
209
+        $part->asset(Mojo::Asset::Memory->new->add_chunk($value));
228 210
       }
229
-    }
230 211
 
231
-    # Content-Disposition
232
-    $name = encode $encoding, $name if $encoding;
233
-    my $disposition = qq{form-data; name="$name"};
234
-    $disposition .= qq{; filename="$filename"} if $filename;
235
-    $headers->content_disposition($disposition);
212
+      # Content-Disposition
213
+      $name = encode $encoding, $name if $encoding;
214
+      my $disposition = qq{form-data; name="$name"};
215
+      $disposition .= qq{; filename="$filename"} if $filename;
216
+      $headers->content_disposition($disposition);
217
+    }
236 218
   }
237 219
 
238 220
   return \@parts;
... ...
@@ -284,19 +266,21 @@ framework used by L<Mojo::UserAgent>.
284 266
 L<Mojo::UserAgent::Transactor> inherits all methods from L<Mojo::Base> and
285 267
 implements the following new ones.
286 268
 
287
-=head2 C<endpoint>
269
+=head2 endpoint
288 270
 
289 271
   my ($proto, $host, $port) = $t->endpoint(Mojo::Transaction::HTTP->new);
290 272
 
291 273
 Actual endpoint for transaction.
292 274
 
293
-=head2 C<form>
275
+=head2 form
294 276
 
295 277
   my $tx = $t->form('kraih.com' => {a => 'b'});
296 278
   my $tx = $t->form('http://kraih.com' => {a => 'b'});
297 279
   my $tx = $t->form('http://kraih.com' => {a => [qw(b c d)]});
298 280
   my $tx = $t->form('http://kraih.com' => {mytext => {file => '/foo.txt'}});
299 281
   my $tx = $t->form('http://kraih.com' => {mytext => {content => 'lalala'}});
282
+  my $tx = $t->form('http://kraih.com' =>
283
+    {mytexts => [{content => 'first'}, {content => 'second'}]});
300 284
   my $tx = $t->form('http://kraih.com' => {
301 285
     myzip => {
302 286
       file     => Mojo::Asset::Memory->new->add_chunk('lalala'),
... ...
@@ -329,7 +313,7 @@ enforce it by setting the header manually.
329 313
     {'Content-Type' => 'multipart/form-data'}
330 314
   );
331 315
 
332
-=head2 C<json>
316
+=head2 json
333 317
 
334 318
   my $tx = $t->json('kraih.com' => {a => 'b'});
335 319
   my $tx = $t->json('http://kraih.com' => [1, 2, 3]);
... ...
@@ -343,27 +327,27 @@ with JSON data.
343 327
   my $tx = $t->json('mojolicio.us/hello', {hello => 'world'});
344 328
   $tx->req->method('PATCH');
345 329
 
346
-=head2 C<peer>
330
+=head2 peer
347 331
 
348 332
   my ($proto, $host, $port) = $t->peer(Mojo::Transaction::HTTP->new);
349 333
 
350 334
 Actual peer for transaction.
351 335
 
352
-=head2 C<proxy_connect>
336
+=head2 proxy_connect
353 337
 
354 338
   my $tx = $t->proxy_connect(Mojo::Transaction::HTTP->new);
355 339
 
356 340
 Build L<Mojo::Transaction::HTTP> proxy connect request for transaction if
357 341
 possible.
358 342
 
359
-=head2 C<redirect>
343
+=head2 redirect
360 344
 
361 345
   my $tx = $t->redirect(Mojo::Transaction::HTTP->new);
362 346
 
363 347
 Build L<Mojo::Transaction::HTTP> followup request for C<301>, C<302>, C<303>,
364 348
 C<307> or C<308> redirect response if possible.
365 349
 
366
-=head2 C<tx>
350
+=head2 tx
367 351
 
368 352
   my $tx = $t->tx(GET  => 'kraih.com');
369 353
   my $tx = $t->tx(POST => 'http://kraih.com');
... ...
@@ -385,14 +369,14 @@ requests.
385 369
   my $tx = $t->tx(GET => 'http://mojolicio.us');
386 370
   $tx->connection($sock);
387 371
 
388
-=head2 C<upgrade>
372
+=head2 upgrade
389 373
 
390 374
   my $tx = $t->upgrade(Mojo::Transaction::HTTP->new);
391 375
 
392 376
 Build L<Mojo::Transaction::WebSocket> followup transaction for WebSocket
393 377
 handshake if possible.
394 378
 
395
-=head2 C<websocket>
379
+=head2 websocket
396 380
 
397 381
   my $tx = $t->websocket('ws://localhost:3000');
398 382
   my $tx = $t->websocket('ws://localhost:3000' => {DNT => 1});
+71 -80
mojolegacy/lib/Mojo/Util.pm
... ...
@@ -20,18 +20,18 @@ use constant {
20 20
   PC_INITIAL_N    => 128
21 21
 };
22 22
 
23
-# Punycode delimiter
24
-my $DELIMITER = chr 0x2D;
25
-
26 23
 # To update HTML5 entities run this command
27 24
 # perl examples/entities.pl > lib/Mojo/entities.txt
28 25
 my %ENTITIES;
29 26
 {
30 27
   open my $entities, '<', catfile(dirname(__FILE__), 'entities.txt');
31
-  /^(\S+)\s+U\+(\S+)/ and $ENTITIES{$1} = chr hex($2) for <$entities>;
28
+  for my $entity (<$entities>) {
29
+    next unless $entity =~ /^(\S+)\s+U\+(\S+)(?:\s+U\+(\S+))?/;
30
+    $ENTITIES{$1} = defined $3 ? (chr(hex $2) . chr(hex $3)) : chr(hex $2);
31
+  }
32 32
 }
33 33
 
34
-# Reverse entities for html_escape (without "apos")
34
+# DEPRECATED in Rainbow!
35 35
 my %REVERSE = ("\x{0027}" => '#39;');
36 36
 $REVERSE{$ENTITIES{$_}} = defined $REVERSE{$ENTITIES{$_}} ? $REVERSE{$ENTITIES{$_}} : $_
37 37
   for sort  { @{[$a =~ /[A-Z]/g]} <=> @{[$b =~ /[A-Z]/g]} }
... ...
@@ -42,12 +42,15 @@ my %CACHE;
42 42
 
43 43
 our @EXPORT_OK = (
44 44
   qw(b64_decode b64_encode camelize class_to_file class_to_path decamelize),
45
-  qw(decode encode get_line hmac_md5_sum hmac_sha1_sum html_escape),
46
-  qw(html_unescape md5_bytes md5_sum monkey_patch punycode_decode),
47
-  qw(punycode_encode quote secure_compare sha1_bytes sha1_sum slurp spurt),
48
-  qw(squish trim unquote url_escape url_unescape xml_escape xor_encode)
45
+  qw(decode encode get_line hmac_md5_sum hmac_sha1_sum html_unescape),
46
+  qw(md5_bytes md5_sum monkey_patch punycode_decode punycode_encode quote),
47
+  qw(secure_compare sha1_bytes sha1_sum slurp spurt squish trim unquote),
48
+  qw(url_escape url_unescape xml_escape xor_encode)
49 49
 );
50 50
 
51
+# DEPRECATED in Rainbow!
52
+push @EXPORT_OK, 'html_escape';
53
+
51 54
 sub b64_decode { decode_base64($_[0]) }
52 55
 
53 56
 sub b64_encode { encode_base64($_[0], $_[1]) }
... ...
@@ -112,7 +115,11 @@ sub get_line {
112 115
 sub hmac_md5_sum  { _hmac(\&md5,  @_) }
113 116
 sub hmac_sha1_sum { _hmac(\&sha1, @_) }
114 117
 
118
+# DEPRECATED in Rainbow!
115 119
 sub html_escape {
120
+  warn <<EOF;
121
+Mojo::Util->html_escape is DEPRECATED in favor of Mojo::Util->xml_escape!!!
122
+EOF
116 123
   my ($string, $pattern) = @_;
117 124
   $pattern ||= '^\n\r\t !#$%(-;=?-~';
118 125
   return $string unless $string =~ /[^$pattern]/;
... ...
@@ -131,26 +138,24 @@ sub md5_bytes { md5(@_) }
131 138
 sub md5_sum   { md5_hex(@_) }
132 139
 
133 140
 sub monkey_patch {
134
-  my ($class, $name, $cb) = @_;
141
+  my ($class, %patch) = @_;
135 142
   no strict 'refs';
136 143
   no warnings 'redefine';
137
-  *{"${class}::$name"} = $cb;
144
+  *{"${class}::$_"} = $patch{$_} for keys %patch;
138 145
 }
139 146
 
147
+# Direct translation of RFC 3492
140 148
 sub punycode_decode {
141 149
   my $input = shift;
142 150
   use integer;
143 151
 
144
-  # Defaults
152
+  # Delimiter
153
+  my @output;
154
+  push @output, split //, $1 if $input =~ s/(.*)\x2d//s;
155
+
145 156
   my $n    = PC_INITIAL_N;
146 157
   my $i    = 0;
147 158
   my $bias = PC_INITIAL_BIAS;
148
-  my @output;
149
-
150
-  # Delimiter
151
-  if ($input =~ s/(.*)$DELIMITER//s) { push @output, split //, $1 }
152
-
153
-  # Decode (direct translation of RFC 3492)
154 159
   while (length $input) {
155 160
     my $oldi = $i;
156 161
     my $w    = 1;
... ...
@@ -174,47 +179,37 @@ sub punycode_decode {
174 179
     $n += $i / (@output + 1);
175 180
     $i = $i % (@output + 1);
176 181
 
177
-    # Insert
178
-    splice @output, $i, 0, chr($n);
179
-    $i++;
182
+    splice @output, $i++, 0, chr $n;
180 183
   }
181 184
 
182 185
   return join '', @output;
183 186
 }
184 187
 
188
+# Direct translation of RFC 3492
185 189
 sub punycode_encode {
186
-  use integer;
187
-
188
-  # Defaults
189 190
   my $output = shift;
190
-  my $len    = length $output;
191
+  use integer;
191 192
 
192 193
   # Split input
193
-  my @input = map ord, split //, $output;
194
+  my $len   = length $output;
195
+  my @input = map {ord} split //, $output;
194 196
   my @chars = sort grep { $_ >= PC_INITIAL_N } @input;
195 197
 
196
-  # Remove non basic characters
198
+  # Handle non basic characters
197 199
   $output =~ s/[^\x00-\x7f]+//gs;
198
-
199
-  # Non basic characters in input
200 200
   my $h = my $b = length $output;
201
-  $output .= $DELIMITER if $b > 0;
201
+  $output .= "\x2d" if $b > 0;
202 202
 
203
-  # Defaults
204 203
   my $n     = PC_INITIAL_N;
205 204
   my $delta = 0;
206 205
   my $bias  = PC_INITIAL_BIAS;
207
-
208
-  # Encode (direct translation of RFC 3492)
209 206
   for my $m (@chars) {
210 207
 
211 208
     # Basic character
212 209
     next if $m < $n;
213 210
 
214
-    # Delta
215
-    $delta += ($m - $n) * ($h + 1);
216
-
217 211
     # Walk all code points in order
212
+    $delta += ($m - $n) * ($h + 1);
218 213
     $n = $m;
219 214
     for (my $i = 0; $i < $len; $i++) {
220 215
       my $c = $input[$i];
... ...
@@ -376,6 +371,7 @@ sub _decode {
376 371
   return "&$_[1]";
377 372
 }
378 373
 
374
+# DEPRECATED in Rainbow!
379 375
 sub _encode {
380 376
   return exists $REVERSE{$_[0]} ? "&$REVERSE{$_[0]}" : "&#@{[ord($_[0])]};";
381 377
 }
... ...
@@ -420,20 +416,20 @@ L<Mojo::Util> provides portable utility functions for L<Mojo>.
420 416
 
421 417
 L<Mojo::Util> implements the following functions.
422 418
 
423
-=head2 C<b64_decode>
419
+=head2 b64_decode
424 420
 
425 421
   my $string = b64_decode $b64;
426 422
 
427 423
 Base64 decode string.
428 424
 
429
-=head2 C<b64_encode>
425
+=head2 b64_encode
430 426
 
431 427
   my $b64 = b64_encode $string;
432 428
   my $b64 = b64_encode $string, "\n";
433 429
 
434 430
 Base64 encode string, the line ending defaults to a newline.
435 431
 
436
-=head2 C<camelize>
432
+=head2 camelize
437 433
 
438 434
   my $camelcase = camelize $snakecase;
439 435
 
... ...
@@ -448,7 +444,7 @@ Convert snake case string to camel case and replace C<-> with C<::>.
448 444
   # "FooBar::Baz"
449 445
   camelize 'FooBar::Baz';
450 446
 
451
-=head2 C<class_to_file>
447
+=head2 class_to_file
452 448
 
453 449
   my $file = class_to_file 'Foo::Bar';
454 450
 
... ...
@@ -459,7 +455,7 @@ Convert a class name to a file.
459 455
   FooBar   -> foo_bar
460 456
   FOOBar   -> foobar
461 457
 
462
-=head2 C<class_to_path>
458
+=head2 class_to_path
463 459
 
464 460
   my $path = class_to_path 'Foo::Bar';
465 461
 
... ...
@@ -468,7 +464,7 @@ Convert class name to path.
468 464
   Foo::Bar -> Foo/Bar.pm
469 465
   FooBar   -> FooBar.pm
470 466
 
471
-=head2 C<decamelize>
467
+=head2 decamelize
472 468
 
473 469
   my $snakecase = decamelize $camelcase;
474 470
 
... ...
@@ -483,139 +479,135 @@ Convert camel case string to snake case and replace C<::> with C<->.
483 479
   # "foo_bar-baz"
484 480
   decamelize 'foo_bar-baz';
485 481
 
486
-=head2 C<decode>
482
+=head2 decode
487 483
 
488 484
   my $chars = decode 'UTF-8', $bytes;
489 485
 
490 486
 Decode bytes to characters and return C<undef> if decoding failed.
491 487
 
492
-=head2 C<encode>
488
+=head2 encode
493 489
 
494 490
   my $bytes = encode 'UTF-8', $chars;
495 491
 
496 492
 Encode characters to bytes.
497 493
 
498
-=head2 C<get_line>
494
+=head2 get_line
499 495
 
500 496
   my $line = get_line \$string;
501 497
 
502 498
 Extract whole line from string or return C<undef>. Lines are expected to end
503 499
 with C<0x0d 0x0a> or C<0x0a>.
504 500
 
505
-=head2 C<hmac_md5_sum>
501
+=head2 hmac_md5_sum
506 502
 
507 503
   my $checksum = hmac_md5_sum $string, 'passw0rd';
508 504
 
509 505
 Generate HMAC-MD5 checksum for string.
510 506
 
511
-=head2 C<hmac_sha1_sum>
507
+=head2 hmac_sha1_sum
512 508
 
513 509
   my $checksum = hmac_sha1_sum $string, 'passw0rd';
514 510
 
515 511
 Generate HMAC-SHA1 checksum for string.
516 512
 
517
-=head2 C<html_escape>
518
-
519
-  my $escaped = html_escape $string;
520
-  my $escaped = html_escape $string, '^\n\r\t !#$%(-;=?-~';
521
-
522
-Escape unsafe characters in string with HTML entities, the pattern used
523
-defaults to C<^\n\r\t !#$%(-;=?-~>.
524
-
525
-=head2 C<html_unescape>
513
+=head2 html_unescape
526 514
 
527 515
   my $string = html_unescape $escaped;
528 516
 
529 517
 Unescape all HTML entities in string.
530 518
 
531
-=head2 C<md5_bytes>
519
+=head2 md5_bytes
532 520
 
533 521
   my $checksum = md5_bytes $string;
534 522
 
535 523
 Generate binary MD5 checksum for string.
536 524
 
537
-=head2 C<md5_sum>
525
+=head2 md5_sum
538 526
 
539 527
   my $checksum = md5_sum $string;
540 528
 
541 529
 Generate MD5 checksum for string.
542 530
 
543
-=head2 C<monkey_patch>
531
+=head2 monkey_patch
544 532
 
545
-  monkey_patch $package, $name, sub {...};
533
+  monkey_patch $package, foo => sub {...};
534
+  monkey_patch $package, foo => sub {...}, bar => sub {...};
546 535
 
547
-Monkey patch function into package.
536
+Monkey patch functions into package.
548 537
 
549
-  monkey_patch 'MyApp', 'hello', sub { say 'Hello!' };
538
+  monkey_patch 'MyApp',
539
+    one   => sub { say 'One!' },
540
+    two   => sub { say 'Two!' },
541
+    three => sub { say 'Three!' };
550 542
 
551
-=head2 C<punycode_decode>
543
+=head2 punycode_decode
552 544
 
553 545
   my $string = punycode_decode $punycode;
554 546
 
555 547
 Punycode decode string.
556 548
 
557
-=head2 C<punycode_encode>
549
+=head2 punycode_encode
558 550
 
559 551
   my $punycode = punycode_encode $string;
560 552
 
561 553
 Punycode encode string.
562 554
 
563
-=head2 C<quote>
555
+=head2 quote
564 556
 
565 557
   my $quoted = quote $string;
566 558
 
567 559
 Quote string.
568 560
 
569
-=head2 C<secure_compare>
561
+=head2 secure_compare
570 562
 
571 563
   my $success = secure_compare $string1, $string2;
572 564
 
573 565
 Constant time comparison algorithm to prevent timing attacks.
574 566
 
575
-=head2 C<sha1_bytes>
567
+=head2 sha1_bytes
576 568
 
577 569
   my $checksum = sha1_bytes $string;
578 570
 
579 571
 Generate binary SHA1 checksum for string.
580 572
 
581
-=head2 C<sha1_sum>
573
+=head2 sha1_sum
582 574
 
583 575
   my $checksum = sha1_sum $string;
584 576
 
585 577
 Generate SHA1 checksum for string.
586 578
 
587
-=head2 C<slurp>
579
+=head2 slurp
588 580
 
589 581
   my $content = slurp '/etc/passwd';
590 582
 
591 583
 Read all data at once from file.
592 584
 
593
-=head2 C<spurt>
585
+=head2 spurt
594 586
 
595 587
   $content = spurt $content, '/etc/passwd';
596 588
 
597 589
 Write all data at once to file.
598 590
 
599
-=head2 C<squish>
591
+=head2 squish
600 592
 
601 593
   my $squished = squish $string;
602 594
 
603 595
 Trim whitespace characters from both ends of string and then change all
604 596
 consecutive groups of whitespace into one space each.
605 597
 
606
-=head2 C<trim>
598
+=head2 trim
607 599
 
608 600
   my $trimmed = trim $string;
609 601
 
610 602
 Trim whitespace characters from both ends of string.
611 603
 
612
-=head2 C<unquote>
604
+=head2 unquote
613 605
 
614 606
   my $string = unquote $quoted;
615 607
 
616 608
 Unquote string.
617 609
 
618
-=head2 C<url_escape>
610
+=head2 url_escape
619 611
 
620 612
   my $escaped = url_escape $string;
621 613
   my $escaped = url_escape $string, '^A-Za-z0-9\-._~';
... ...
@@ -623,24 +615,23 @@ Unquote string.
623 615
 Percent encode unsafe characters in string, the pattern used defaults to
624 616
 C<^A-Za-z0-9\-._~>.
625 617
 
626
-=head2 C<url_unescape>
618
+=head2 url_unescape
627 619
 
628 620
   my $string = url_unescape $escaped;
629 621
 
630 622
 Decode percent encoded characters in string.
631 623
 
632
-=head2 C<xml_escape>
624
+=head2 xml_escape
633 625
 
634 626
   my $escaped = xml_escape $string;
635 627
 
636
-Escape only the characters C<&>, C<E<lt>>, C<E<gt>>, C<"> and C<'> in string,
637
-this is a much faster version of C<html_escape>.
628
+Escape unsafe characters C<&>, C<E<lt>>, C<E<gt>>, C<"> and C<'> in string.
638 629
 
639
-=head2 C<xor_encode>
630
+=head2 xor_encode
640 631
 
641 632
   my $encoded = xor_encode $string, $key;
642 633
 
643
-XOR encode string.
634
+XOR encode string with variable length key.
644 635
 
645 636
 =head1 SEE ALSO
646 637
 
+111 -142
mojolegacy/lib/Mojolicious.pm
... ...
@@ -4,6 +4,7 @@ use Mojo::Base 'Mojo';
4 4
 # "Fry: Shut up and take my money!"
5 5
 use Carp 'croak';
6 6
 use Mojo::Exception;
7
+use Mojo::Util 'decamelize';
7 8
 use Mojolicious::Commands;
8 9
 use Mojolicious::Controller;
9 10
 use Mojolicious::Plugins;
... ...
@@ -21,6 +22,7 @@ has commands => sub {
21 22
 };
22 23
 has controller_class => 'Mojolicious::Controller';
23 24
 has mode => sub { $ENV{MOJO_MODE} || 'development' };
25
+has moniker  => sub { decamelize ref shift };
24 26
 has plugins  => sub { Mojolicious::Plugins->new };
25 27
 has renderer => sub { Mojolicious::Renderer->new };
26 28
 has routes   => sub { Mojolicious::Routes->new };
... ...
@@ -38,7 +40,7 @@ has static   => sub { Mojolicious::Static->new };
38 40
 has types    => sub { Mojolicious::Types->new };
39 41
 
40 42
 our $CODENAME = 'Rainbow';
41
-our $VERSION  = '3.70';
43
+our $VERSION  = '3.84';
42 44
 
43 45
 sub AUTOLOAD {
44 46
   my $self = shift;
... ...
@@ -61,7 +63,6 @@ sub DESTROY { }
61 63
 sub new {
62 64
   my $self = shift->SUPER::new(@_);
63 65
 
64
-  # Paths
65 66
   my $home = $self->home;
66 67
   push @{$self->renderer->paths}, $home->rel_dir('templates');
67 68
   push @{$self->static->paths},   $home->rel_dir('public');
... ...
@@ -76,25 +77,22 @@ sub new {
76 77
   $r->hide(qw(rendered req res respond_to send session signed_cookie stash));
77 78
   $r->hide(qw(tx ua url_for write write_chunk));
78 79
 
79
-  # Prepare log
80
+  # Check if we have a log directory
80 81
   my $mode = $self->mode;
81 82
   $self->log->path($home->rel_file("log/$mode.log"))
82 83
     if -w $home->rel_file('log');
83 84
 
84
-  # Load default plugins
85 85
   $self->plugin($_) for qw(HeaderCondition DefaultHelpers TagHelpers);
86 86
   $self->plugin($_) for qw(EPLRenderer EPRenderer RequestTimer PoweredBy);
87 87
 
88
-  # Exception handling
88
+  # Exception handling should be first in chain
89 89
   $self->hook(around_dispatch => \&_exception);
90 90
 
91 91
   # Reduced log output outside of development mode
92 92
   $self->log->level('info') unless $mode eq 'development';
93 93
 
94
-  # Run mode
94
+  # Run mode before startup
95 95
   if (my $sub = $self->can("${mode}_mode")) { $self->$sub(@_) }
96
-
97
-  # Startup
98 96
   $self->startup(@_);
99 97
 
100 98
   return $self;
... ...
@@ -119,10 +117,18 @@ sub dispatch {
119 117
   my $plugins = $self->plugins->emit_hook(before_dispatch => $c);
120 118
 
121 119
   # Try to find a static file
122
-  $self->static->dispatch($c) unless $tx->res->code;
123
-  $plugins->emit_hook_reverse(after_static_dispatch => $c);
120
+  $self->static->dispatch($c) and $plugins->emit_hook(after_static => $c)
121
+    unless $tx->res->code;
122
+
123
+  # DEPRECATED in Rainbow!
124
+  if ($plugins->has_subscribers('after_static_dispatch')) {
125
+    warn <<EOF and $plugins->emit_hook_reverse(after_static_dispatch => $c);
126
+after_static_dispatch hook is DEPRECATED in favor of before_routes!!!
127
+EOF
128
+  }
124 129
 
125 130
   # Routes
131
+  $plugins->emit_hook(before_routes => $c);
126 132
   my $res = $tx->res;
127 133
   return if $res->code;
128 134
   if (my $code = ($tx->req->error)[1]) { $res->code($code) }
... ...
@@ -145,18 +151,19 @@ sub handler {
145 151
     = $self->controller_class->new(app => $self, stash => $stash, tx => $tx);
146 152
   weaken $c->{$_} for qw(app tx);
147 153
 
148
-  # Dispatcher
149
-  ++$self->{dispatch} and $self->hook(around_dispatch => \&_dispatch)
154
+  # Dispatcher has to be last in the chain
155
+  ++$self->{dispatch}
156
+    and $self->hook(around_dispatch => sub { $_[1]->app->dispatch($_[1]) })
150 157
     unless $self->{dispatch};
151 158
 
152
-  # Process
159
+  # Process with chain
153 160
   unless (eval { $self->plugins->emit_chain(around_dispatch => $c) }) {
154 161
     $self->log->fatal("Processing request failed: $@");
155 162
     $tx->res->code(500);
156 163
     $tx->resume;
157 164
   }
158 165
 
159
-  # Delayed
166
+  # Delayed response
160 167
   $self->log->debug('Nothing has been rendered, expecting delayed response.')
161 168
     unless $stash->{'mojo.rendered'} || $tx->is_writing;
162 169
 }
... ...
@@ -180,11 +187,6 @@ sub start { shift->commands->run(@_ ? @_ : @ARGV) }
180 187
 
181 188
 sub startup { }
182 189
 
183
-sub _dispatch {
184
-  my ($next, $c) = @_;
185
-  $c->app->dispatch($c);
186
-}
187
-
188 190
 sub _exception {
189 191
   my ($next, $c) = @_;
190 192
   local $SIG{__DIE__}
... ...
@@ -229,7 +231,7 @@ Take a look at our excellent documentation in L<Mojolicious::Guides>!
229 231
 L<Mojolicious> inherits all attributes from L<Mojo> and implements the
230 232
 following new ones.
231 233
 
232
-=head2 C<commands>
234
+=head2 commands
233 235
 
234 236
   my $commands = $app->commands;
235 237
   $app         = $app->commands(Mojolicious::Commands->new);
... ...
@@ -240,7 +242,7 @@ L<Mojolicious::Commands> object.
240 242
   # Add another namespace to load commands from
241 243
   push @{$app->commands->namespaces}, 'MyApp::Command';
242 244
 
243
-=head2 C<controller_class>
245
+=head2 controller_class
244 246
 
245 247
   my $class = $app->controller_class;
246 248
   $app      = $app->controller_class('Mojolicious::Controller');
... ...
@@ -248,7 +250,7 @@ L<Mojolicious::Commands> object.
248 250
 Class to be used for the default controller, defaults to
249 251
 L<Mojolicious::Controller>.
250 252
 
251
-=head2 C<mode>
253
+=head2 mode
252 254
 
253 255
   my $mode = $app->mode;
254 256
   $app     = $app->mode('production');
... ...
@@ -272,7 +274,16 @@ Right before calling C<startup> and mode specific methods, L<Mojolicious>
272 274
 will pick up the current mode, name the log file after it and raise the log
273 275
 level from C<debug> to C<info> if it has a value other than C<development>.
274 276
 
275
-=head2 C<plugins>
277
+=head2 moniker
278
+
279
+  my $moniker = $app->moniker;
280
+  $app        = $app->moniker('foo_bar');
281
+
282
+Moniker of this application, often used as default filename for configuration
283
+files and the like, defaults to decamelizing the application class with
284
+L<Mojo::Util/"decamelize">.
285
+
286
+=head2 plugins
276 287
 
277 288
   my $plugins = $app->plugins;
278 289
   $app        = $app->plugins(Mojolicious::Plugins->new);
... ...
@@ -283,7 +294,7 @@ C<plugin> method below if you want to load a plugin.
283 294
   # Add another namespace to load plugins from
284 295
   push @{$app->plugins->namespaces}, 'MyApp::Plugin';
285 296
 
286
-=head2 C<renderer>
297
+=head2 renderer
287 298
 
288 299
   my $renderer = $app->renderer;
289 300
   $app         = $app->renderer(Mojolicious::Renderer->new);
... ...
@@ -299,7 +310,7 @@ contain more information.
299 310
   # Add another class with templates in DATA section
300 311
   push @{$app->renderer->classes}, 'Mojolicious::Plugin::Fun';
301 312
 
302
-=head2 C<routes>
313
+=head2 routes
303 314
 
304 315
   my $routes = $app->routes;
305 316
   $app       = $app->routes(Mojolicious::Routes->new);
... ...
@@ -307,14 +318,15 @@ contain more information.
307 318
 The router, defaults to a L<Mojolicious::Routes> object. You use this in your
308 319
 startup method to define the url endpoints for your application.
309 320
 
310
-  sub startup {
311
-    my $self = shift;
321
+  # Add routes
322
+  my $r = $app->routes;
323
+  $r->get('/foo/bar')->to('test#foo', title => 'Hello Mojo!');
324
+  $r->post('/baz')->to('test#baz');
312 325
 
313
-    my $r = $self->routes;
314
-    $r->get('/:controller/:action')->to('test#welcome');
315
-  }
326
+  # Add another namespace to load controllers from
327
+  push @{$app->routes->namespaces}, 'MyApp::Controller';
316 328
 
317
-=head2 C<secret>
329
+=head2 secret
318 330
 
319 331
   my $secret = $app->secret;
320 332
   $app       = $app->secret('passw0rd');
... ...
@@ -324,7 +336,7 @@ application name which is not very secure, so you should change it!!! As long
324 336
 as you are using the insecure default there will be debug messages in the log
325 337
 file reminding you to change your passphrase.
326 338
 
327
-=head2 C<sessions>
339
+=head2 sessions
328 340
 
329 341
   my $sessions = $app->sessions;
330 342
   $app         = $app->sessions(Mojolicious::Sessions->new);
... ...
@@ -334,7 +346,7 @@ object. You can usually leave this alone, see
334 346
 L<Mojolicious::Controller/"session"> for more information about working with
335 347
 session data.
336 348
 
337
-=head2 C<static>
349
+=head2 static
338 350
 
339 351
   my $static = $app->static;
340 352
   $app       = $app->static(Mojolicious::Static->new);
... ...
@@ -348,7 +360,7 @@ L<Mojolicious::Static> object.
348 360
   # Add another class with static files in DATA section
349 361
   push @{$app->static->classes}, 'Mojolicious::Plugin::Fun';
350 362
 
351
-=head2 C<types>
363
+=head2 types
352 364
 
353 365
   my $types = $app->types;
354 366
   $app      = $app->types(Mojolicious::Types->new);
... ...
@@ -363,23 +375,23 @@ L<Mojolicious::Types> object.
363 375
 L<Mojolicious> inherits all methods from L<Mojo> and implements the following
364 376
 new ones.
365 377
 
366
-=head2 C<new>
378
+=head2 new
367 379
 
368 380
   my $app = Mojolicious->new;
369 381
 
370 382
 Construct a new L<Mojolicious> application, calling C<${mode}_mode> and
371 383
 C<startup> in the process. Will automatically detect your home directory and
372 384
 set up logging based on your current operating mode. Also sets up the
373
-renderer, static dispatcher and a default set of plugins.
385
+renderer, static file server and a default set of plugins.
374 386
 
375
-=head2 C<build_tx>
387
+=head2 build_tx
376 388
 
377 389
   my $tx = $app->build_tx;
378 390
 
379 391
 Transaction builder, defaults to building a L<Mojo::Transaction::HTTP>
380 392
 object.
381 393
 
382
-=head2 C<defaults>
394
+=head2 defaults
383 395
 
384 396
   my $defaults = $app->defaults;
385 397
   my $foo      = $app->defaults('foo');
... ...
@@ -394,7 +406,7 @@ request.
394 406
   my $foo = $app->defaults->{foo};
395 407
   delete $app->defaults->{foo};
396 408
 
397
-=head2 C<dispatch>
409
+=head2 dispatch
398 410
 
399 411
   $app->dispatch(Mojolicious::Controller->new);
400 412
 
... ...
@@ -402,14 +414,14 @@ The heart of every Mojolicious application, calls the C<static> and C<routes>
402 414
 dispatchers for every request and passes them a L<Mojolicious::Controller>
403 415
 object.
404 416
 
405
-=head2 C<handler>
417
+=head2 handler
406 418
 
407 419
   $app->handler(Mojo::Transaction::HTTP->new);
408 420
   $app->handler(Mojolicious::Controller->new);
409 421
 
410 422
 Sets up the default controller and calls process for every request.
411 423
 
412
-=head2 C<helper>
424
+=head2 helper
413 425
 
414 426
   $app->helper(foo => sub {...});
415 427
 
... ...
@@ -427,7 +439,7 @@ and the application object, as well as a function in C<ep> templates.
427 439
   % cache->{foo} = 'bar';
428 440
   %= cache->{foo}
429 441
 
430
-=head2 C<hook>
442
+=head2 hook
431 443
 
432 444
   $app->hook(after_dispatch => sub {...});
433 445
 
... ...
@@ -438,14 +450,14 @@ requests indiscriminately.
438 450
   $app->hook(before_dispatch => sub {
439 451
     my $c = shift;
440 452
     $c->render(text => 'Skipped dispatchers!')
441
-      if $c->req->url->path->contains('/do_not_dispatch');
453
+      if $c->req->url->path->to_route =~ /do_not_dispatch/;
442 454
   });
443 455
 
444 456
 These hooks are currently available and are emitted in the listed order:
445 457
 
446 458
 =over 2
447 459
 
448
-=item C<after_build_tx>
460
+=item after_build_tx
449 461
 
450 462
 Emitted right after the transaction is built and before the HTTP request gets
451 463
 parsed.
... ...
@@ -460,9 +472,9 @@ rather advanced features such as upload progress bars possible. Note that this
460 472
 hook will not work for embedded applications. (Passed the transaction and
461 473
 application object)
462 474
 
463
-=item C<before_dispatch>
475
+=item before_dispatch
464 476
 
465
-Emitted right before the static dispatcher and router start their work.
477
+Emitted right before the static file server and router start their work.
466 478
 
467 479
   $app->hook(before_dispatch => sub {
468 480
     my $c = shift;
... ...
@@ -472,25 +484,51 @@ Emitted right before the static dispatcher and router start their work.
472 484
 Very useful for rewriting incoming requests and other preprocessing tasks.
473 485
 (Passed the default controller object)
474 486
 
475
-=item C<after_static_dispatch>
487
+=item after_static
476 488
 
477
-Emitted in reverse order after the static dispatcher determined if a static
478
-file should be served and before the router starts its work.
489
+Emitted after the static file server decided to serve a static file.
479 490
 
480
-  $app->hook(after_static_dispatch => sub {
491
+  $app->hook(after_static => sub {
481 492
     my $c = shift;
482 493
     ...
483 494
   });
484 495
 
485
-Mostly used for custom dispatchers and post-processing static file responses.
486
-(Passed the default controller object)
496
+Mostly used for post-processing static file responses. (Passed the default
497
+controller object)
498
+
499
+=item before_routes
500
+
501
+Emitted after the static file server decided if a static file should be served
502
+and before the router starts its work.
503
+
504
+  $app->hook(before_routes => sub {
505
+    my $c = shift;
506
+    ...
507
+  });
508
+
509
+Mostly used for custom dispatchers and collecting metrics. (Passed the default
510
+controller object)
511
+
512
+=item after_render
487 513
 
488
-=item C<after_dispatch>
514
+Emitted after content has been generated by the renderer that is not partial.
515
+Note that this hook can trigger out of order due to its dynamic nature, and
516
+with embedded applications will only work for the application that is
517
+rendering.
518
+
519
+  $app->hook(after_render => sub {
520
+    my ($c, $output, $format) = @_;
521
+    ...
522
+  });
523
+
524
+Mostly used for post-processing dynamically generated content. (Passed the
525
+current controller object, a reference to the content and the format)
526
+
527
+=item after_dispatch
489 528
 
490 529
 Emitted in reverse order after a response has been rendered. Note that this
491
-hook can trigger before C<after_static_dispatch> due to its dynamic nature,
492
-and with embedded applications will only work for the application rendering
493
-the response.
530
+hook can trigger out of order due to its dynamic nature, and with embedded
531
+applications will only work for the application that is rendering.
494 532
 
495 533
   $app->hook(after_dispatch => sub {
496 534
     my $c = shift;
... ...
@@ -500,7 +538,7 @@ the response.
500 538
 Useful for rewriting outgoing responses and other post-processing tasks.
501 539
 (Passed the current controller object)
502 540
 
503
-=item C<around_dispatch>
541
+=item around_dispatch
504 542
 
505 543
 Emitted right before the C<before_dispatch> hook and wraps around the whole
506 544
 dispatch process, so you have to manually forward to the next hook if you want
... ...
@@ -522,7 +560,7 @@ the default controller object)
522 560
 
523 561
 =back
524 562
 
525
-=head2 C<plugin>
563
+=head2 plugin
526 564
 
527 565
   $app->plugin('some_thing');
528 566
   $app->plugin('some_thing', foo => 23);
... ...
@@ -534,76 +572,21 @@ the default controller object)
534 572
   $app->plugin('MyApp::Plugin::SomeThing', foo => 23);
535 573
   $app->plugin('MyApp::Plugin::SomeThing', {foo => 23});
536 574
 
537
-Load a plugin with L<Mojolicious::Plugins/"register_plugin">.
538
-
539
-These plugins are included in the L<Mojolicious> distribution as examples:
540
-
541
-=over 2
542
-
543
-=item L<Mojolicious::Plugin::Charset>
544
-
545
-Change the application charset.
546
-
547
-=item L<Mojolicious::Plugin::Config>
548
-
549
-Perl-ish configuration files.
550
-
551
-=item L<Mojolicious::Plugin::DefaultHelpers>
552
-
553
-General purpose helper collection, loaded automatically.
575
+Load a plugin, for a full list of example plugins included in the
576
+L<Mojolicious> distribution see L<Mojolicious::Plugins/"PLUGINS">.
554 577
 
555
-=item L<Mojolicious::Plugin::EPLRenderer>
556
-
557
-Renderer for plain embedded Perl templates, loaded automatically.
558
-
559
-=item L<Mojolicious::Plugin::EPRenderer>
560
-
561
-Renderer for more sophisiticated embedded Perl templates, loaded
562
-automatically.
563
-
564
-=item L<Mojolicious::Plugin::HeaderCondition>
565
-
566
-Route condition for all kinds of headers, loaded automatically.
567
-
568
-=item L<Mojolicious::Plugin::JSONConfig>
569
-
570
-JSON configuration files.
571
-
572
-=item L<Mojolicious::Plugin::Mount>
573
-
574
-Mount whole L<Mojolicious> applications.
575
-
576
-=item L<Mojolicious::Plugin::PODRenderer>
577
-
578
-Renderer for turning POD into HTML and documentation browser for
579
-L<Mojolicious::Guides>.
580
-
581
-=item L<Mojolicious::Plugin::PoweredBy>
582
-
583
-Add an C<X-Powered-By> header to outgoing responses, loaded automatically.
584
-
585
-=item L<Mojolicious::Plugin::RequestTimer>
586
-
587
-Log timing information, loaded automatically.
588
-
589
-=item L<Mojolicious::Plugin::TagHelpers>
590
-
591
-Template specific helper collection, loaded automatically.
592
-
593
-=back
594
-
595
-=head2 C<start>
578
+=head2 start
596 579
 
597 580
   $app->start;
598 581
   $app->start(@ARGV);
599 582
 
600
-Start the command line interface for your application with
601
-L<Mojolicious::Commands/"start">.
583
+Start the command line interface for your application, for a full list of
584
+commands available by default see L<Mojolicious::Commands/"COMMANDS">.
602 585
 
603 586
   # Always start daemon and ignore @ARGV
604 587
   $app->start('daemon', '-l', 'http://*:8080');
605 588
 
606
-=head2 C<startup>
589
+=head2 startup
607 590
 
608 591
   $app->startup;
609 592
 
... ...
@@ -626,26 +609,6 @@ request, response and stash.
626 609
 
627 610
   $app->log->debug($app->dumper({foo => 'bar'}));
628 611
 
629
-=head1 SUPPORT
630
-
631
-=head2 Web
632
-
633
-L<http://mojolicio.us>
634
-
635
-=head2 IRC
636
-
637
-C<#mojo> on C<irc.perl.org>
638
-
639
-=head2 Mailing-List
640
-
641
-L<http://groups.google.com/group/mojolicious>
642
-
643
-=head1 DEVELOPMENT
644
-
645
-=head2 Repository
646
-
647
-L<http://github.com/kraih/mojo>
648
-
649 612
 =head1 BUNDLED FILES
650 613
 
651 614
 The L<Mojolicious> distribution includes a few files with different licenses
... ...
@@ -653,14 +616,14 @@ that have been bundled for internal use.
653 616
 
654 617
 =head2 Mojolicious Artwork
655 618
 
656
-  Copyright (C) 2010-2012, Sebastian Riedel.
619
+  Copyright (C) 2010-2013, Sebastian Riedel.
657 620
 
658 621
 Licensed under the CC-SA License, Version 3.0
659 622
 L<http://creativecommons.org/licenses/by-sa/3.0>.
660 623
 
661 624
 =head2 jQuery
662 625
 
663
-  Copyright (C) 2011, John Resig.
626
+  Copyright (C) 2005, 2012 jQuery Foundation, Inc.
664 627
 
665 628
 Licensed under the MIT License, L<http://creativecommons.org/licenses/MIT>.
666 629
 
... ...
@@ -810,6 +773,8 @@ James Duncan
810 773
 
811 774
 Jan Jona Javorsek
812 775
 
776
+Jan Schmidt
777
+
813 778
 Jaroslav Muhin
814 779
 
815 780
 Jesse Vincent
... ...
@@ -940,9 +905,13 @@ Zak B. Elep
940 905
 
941 906
 =head1 COPYRIGHT AND LICENSE
942 907
 
943
-Copyright (C) 2008-2012, Sebastian Riedel.
908
+Copyright (C) 2008-2013, Sebastian Riedel.
944 909
 
945 910
 This program is free software, you can redistribute it and/or modify it under
946 911
 the terms of the Artistic License version 2.0.
947 912
 
913
+=head1 SEE ALSO
914
+
915
+L<Mojolicious::Guides>, L<http://mojolicio.us>.
916
+
948 917
 =cut
+17 -20
mojolegacy/lib/Mojolicious/Command.pm
... ...
@@ -32,10 +32,7 @@ sub chmod_rel_file {
32 32
 sub create_dir {
33 33
   my ($self, $path) = @_;
34 34
 
35
-  # Exists
36 35
   if (-d $path) { say "  [exist] $path" unless $self->quiet }
37
-
38
-  # Create
39 36
   else {
40 37
     mkpath $path or croak qq{Can't make directory "$path": $!};
41 38
     say "  [mkdir] $path" unless $self->quiet;
... ...
@@ -129,7 +126,7 @@ default.
129 126
 
130 127
 L<Mojolicious::Command> implements the following attributes.
131 128
 
132
-=head2 C<app>
129
+=head2 app
133 130
 
134 131
   my $app  = $command->app;
135 132
   $command = $command->app(MyApp->new);
... ...
@@ -139,21 +136,21 @@ Application for command, defaults to a L<Mojo::HelloWorld> object.
139 136
   # Introspect
140 137
   say "Template path: $_" for @{$command->app->renderer->paths};
141 138
 
142
-=head2 C<description>
139
+=head2 description
143 140
 
144 141
   my $description = $command->description;
145 142
   $command        = $command->description('Foo!');
146 143
 
147 144
 Short description of command, used for the command list.
148 145
 
149
-=head2 C<quiet>
146
+=head2 quiet
150 147
 
151 148
   my $quiet = $command->quiet;
152 149
   $command  = $command->quiet(1);
153 150
 
154 151
 Limited command output.
155 152
 
156
-=head2 C<usage>
153
+=head2 usage
157 154
 
158 155
   my $usage = $command->usage;
159 156
   $command  = $command->usage('Foo!');
... ...
@@ -165,51 +162,51 @@ Usage information for command, used for the help screen.
165 162
 L<Mojolicious::Command> inherits all methods from L<Mojo::Base> and implements
166 163
 the following new ones.
167 164
 
168
-=head2 C<chmod_file>
165
+=head2 chmod_file
169 166
 
170 167
   $command = $command->chmod_file('/home/sri/foo.txt', 0644);
171 168
 
172 169
 Change mode of a file.
173 170
 
174
-=head2 C<chmod_rel_file>
171
+=head2 chmod_rel_file
175 172
 
176 173
   $command = $command->chmod_rel_file('foo/foo.txt', 0644);
177 174
 
178 175
 Portably change mode of a file relative to the current working directory.
179 176
 
180
-=head2 C<create_dir>
177
+=head2 create_dir
181 178
 
182 179
   $command = $command->create_dir('/home/sri/foo/bar');
183 180
 
184 181
 Create a directory.
185 182
 
186
-=head2 C<create_rel_dir>
183
+=head2 create_rel_dir
187 184
 
188 185
   $command = $command->create_rel_dir('foo/bar/baz');
189 186
 
190 187
 Portably create a directory relative to the current working directory.
191 188
 
192
-=head2 C<help>
189
+=head2 help
193 190
 
194 191
   $command->help;
195 192
 
196 193
 Print usage information for command.
197 194
 
198
-=head2 C<rel_dir>
195
+=head2 rel_dir
199 196
 
200 197
   my $path = $command->rel_dir('foo/bar');
201 198
 
202 199
 Portably generate an absolute path for a directory relative to the current
203 200
 working directory.
204 201
 
205
-=head2 C<rel_file>
202
+=head2 rel_file
206 203
 
207 204
   my $path = $command->rel_file('foo/bar.txt');
208 205
 
209 206
 Portably generate an absolute path for a file relative to the current working
210 207
 directory.
211 208
 
212
-=head2 C<render_data>
209
+=head2 render_data
213 210
 
214 211
 
215 212
   my $data = $command->render_data('foo_bar');
... ...
@@ -218,7 +215,7 @@ directory.
218 215
 Render a template from the C<DATA> section of the command class with
219 216
 L<Mojo::Template>.
220 217
 
221
-=head2 C<render_to_file>
218
+=head2 render_to_file
222 219
 
223 220
   $command = $command->render_to_file('foo_bar', '/home/sri/foo.txt');
224 221
   $command = $command->render_to_file('foo_bar', '/home/sri/foo.txt', @args);
... ...
@@ -226,7 +223,7 @@ L<Mojo::Template>.
226 223
 Render a template from the C<DATA> section of the command class with
227 224
 L<Mojo::Template> to a file and create directory if necessary.
228 225
 
229
-=head2 C<render_to_rel_file>
226
+=head2 render_to_rel_file
230 227
 
231 228
   $command = $command->render_to_rel_file('foo_bar', 'foo/bar.txt');
232 229
   $command = $command->render_to_rel_file('foo_bar', 'foo/bar.txt', @args);
... ...
@@ -235,20 +232,20 @@ Portably render a template from the C<DATA> section of the command class with
235 232
 L<Mojo::Template> to a file relative to the current working directory and
236 233
 create directory if necessary.
237 234
 
238
-=head2 C<run>
235
+=head2 run
239 236
 
240 237
   $command->run;
241 238
   $command->run(@ARGV);
242 239
 
243 240
 Run command. Meant to be overloaded in a subclass.
244 241
 
245
-=head2 C<write_file>
242
+=head2 write_file
246 243
 
247 244
   $command = $command->write_file('/home/sri/foo.txt', 'Hello World!');
248 245
 
249 246
 Write text to a file and create directory if necessary.
250 247
 
251
-=head2 C<write_rel_file>
248
+=head2 write_rel_file
252 249
 
253 250
   $command = $command->write_rel_file('foo/bar.txt', 'Hello World!');
254 251
 
+3 -3
mojolegacy/lib/Mojolicious/Command/cgi.pm
... ...
@@ -45,14 +45,14 @@ example for learning to build new commands, you're welcome to fork it.
45 45
 L<Mojolicious::Command::cgi> inherits all attributes from
46 46
 L<Mojolicious::Command> and implements the following new ones.
47 47
 
48
-=head2 C<description>
48
+=head2 description
49 49
 
50 50
   my $description = $cgi->description;
51 51
   $cgi            = $cgi->description('Foo!');
52 52
 
53 53
 Short description of this command, used for the command list.
54 54
 
55
-=head2 C<usage>
55
+=head2 usage
56 56
 
57 57
   my $usage = $cgi->usage;
58 58
   $cgi      = $cgi->usage('Foo!');
... ...
@@ -64,7 +64,7 @@ Usage information for this command, used for the help screen.
64 64
 L<Mojolicious::Command::cgi> inherits all methods from L<Mojolicious::Command>
65 65
 and implements the following new ones.
66 66
 
67
-=head2 C<run>
67
+=head2 run
68 68
 
69 69
   $cgi->run(@ARGV);
70 70
 
+4 -6
mojolegacy/lib/Mojolicious/Command/cpanify.pm
... ...
@@ -19,13 +19,11 @@ EOF
19 19
 sub run {
20 20
   my ($self, @args) = @_;
21 21
 
22
-  # Options
23 22
   GetOptionsFromArray \@args,
24 23
     'p|password=s' => \(my $password = ''),
25 24
     'u|user=s'     => \(my $user     = '');
26 25
   die $self->usage unless my $file = shift @args;
27 26
 
28
-  # Upload
29 27
   my $tx = Mojo::UserAgent->new->detect_proxy->post_form(
30 28
     "https://$user:$password\@pause.perl.org/pause/authenquery" => {
31 29
       HIDDENNAME                        => $user,
... ...
@@ -37,7 +35,6 @@ sub run {
37 35
     }
38 36
   );
39 37
 
40
-  # Error
41 38
   unless ($tx->success) {
42 39
     my $code = $tx->res->code || '';
43 40
     my $msg = $tx->error;
... ...
@@ -45,6 +42,7 @@ sub run {
45 42
     elsif ($code eq '409') { $msg = 'File already exists on CPAN.' }
46 43
     die qq{Problem uploading file "$file". ($msg)\n};
47 44
   }
45
+
48 46
   say 'Upload successful!';
49 47
 }
50 48
 
... ...
@@ -73,14 +71,14 @@ example for learning to build new commands, you're welcome to fork it.
73 71
 L<Mojolicious::Command::cpanify> inherits all attributes from
74 72
 L<Mojolicious::Command> and implements the following new ones.
75 73
 
76
-=head2 C<description>
74
+=head2 description
77 75
 
78 76
   my $description = $cpanify->description;
79 77
   $cpanify        = $cpanify->description('Foo!');
80 78
 
81 79
 Short description of this command, used for the command list.
82 80
 
83
-=head2 C<usage>
81
+=head2 usage
84 82
 
85 83
   my $usage = $cpanify->usage;
86 84
   $cpanify  = $cpanify->usage('Foo!');
... ...
@@ -92,7 +90,7 @@ Usage information for this command, used for the help screen.
92 90
 L<Mojolicious::Command::cpanify> inherits all methods from
93 91
 L<Mojolicious::Command> and implements the following new ones.
94 92
 
95
-=head2 C<run>
93
+=head2 run
96 94
 
97 95
   $cpanify->run(@ARGV);
98 96
 
+13 -16
mojolegacy/lib/Mojolicious/Command/daemon.pm
... ...
@@ -9,27 +9,25 @@ has usage       => <<"EOF";
9 9
 usage: $0 daemon [OPTIONS]
10 10
 
11 11
 These options are available:
12
-  -b, --backlog <size>         Set listen backlog size, defaults to
13
-                               SOMAXCONN.
14
-  -c, --clients <number>       Set maximum number of concurrent clients,
15
-                               defaults to 1000.
16
-  -g, --group <name>           Set group name for process.
17
-  -i, --inactivity <seconds>   Set inactivity timeout, defaults to the value
18
-                               of MOJO_INACTIVITY_TIMEOUT or 15.
19
-  -l, --listen <location>      Set one or more locations you want to listen
20
-                               on, defaults to the value of MOJO_LISTEN or
12
+  -b, --backlog <size>         Listen backlog size, defaults to SOMAXCONN.
13
+  -c, --clients <number>       Maximum number of concurrent clients, defaults
14
+                               to 1000.
15
+  -g, --group <name>           Group name for process.
16
+  -i, --inactivity <seconds>   Inactivity timeout, defaults to the value of
17
+                               MOJO_INACTIVITY_TIMEOUT or 15.
18
+  -l, --listen <location>      One or more locations you want to listen on,
19
+                               defaults to the value of MOJO_LISTEN or
21 20
                                "http://*:3000".
22 21
   -p, --proxy                  Activate reverse proxy support, defaults to
23 22
                                the value of MOJO_REVERSE_PROXY.
24
-  -r, --requests <number>      Set maximum number of requests per keep-alive
23
+  -r, --requests <number>      Maximum number of requests per keep-alive
25 24
                                connection, defaults to 25.
26
-  -u, --user <name>            Set username for process.
25
+  -u, --user <name>            Username for process.
27 26
 EOF
28 27
 
29 28
 sub run {
30 29
   my ($self, @args) = @_;
31 30
 
32
-  # Options
33 31
   my $daemon = Mojo::Server::Daemon->new(app => $self->app);
34 32
   GetOptionsFromArray \@args,
35 33
     'b|backlog=i'    => sub { $daemon->backlog($_[1]) },
... ...
@@ -41,7 +39,6 @@ sub run {
41 39
     'r|requests=i' => sub { $daemon->max_requests($_[1]) },
42 40
     'u|user=s'     => sub { $daemon->user($_[1]) };
43 41
 
44
-  # Start
45 42
   $daemon->listen(\@listen) if @listen;
46 43
   $daemon->run;
47 44
 }
... ...
@@ -72,14 +69,14 @@ example for learning to build new commands, you're welcome to fork it.
72 69
 L<Mojolicious::Command::daemon> inherits all attributes from
73 70
 L<Mojolicious::Command> and implements the following new ones.
74 71
 
75
-=head2 C<description>
72
+=head2 description
76 73
 
77 74
   my $description = $daemon->description;
78 75
   $daemon         = $daemon->description('Foo!');
79 76
 
80 77
 Short description of this command, used for the command list.
81 78
 
82
-=head2 C<usage>
79
+=head2 usage
83 80
 
84 81
   my $usage = $daemon->usage;
85 82
   $daemon   = $daemon->usage('Foo!');
... ...
@@ -91,7 +88,7 @@ Usage information for this command, used for the help screen.
91 88
 L<Mojolicious::Command::daemon> inherits all methods from
92 89
 L<Mojolicious::Command> and implements the following new ones.
93 90
 
94
-=head2 C<run>
91
+=head2 run
95 92
 
96 93
   $daemon->run(@ARGV);
97 94
 
+3 -4
mojolegacy/lib/Mojolicious/Command/eval.pm
... ...
@@ -17,7 +17,6 @@ EOF
17 17
 sub run {
18 18
   my ($self, @args) = @_;
19 19
 
20
-  # Options
21 20
   GetOptionsFromArray \@args, 'v|verbose' => \my $verbose;
22 21
   my $code = shift @args || '';
23 22
 
... ...
@@ -54,14 +53,14 @@ example for learning to build new commands, you're welcome to fork it.
54 53
 L<Mojolicious::Command::eval> inherits all attributes from
55 54
 L<Mojolicious::Command> and implements the following new ones.
56 55
 
57
-=head2 C<description>
56
+=head2 description
58 57
 
59 58
   my $description = $eval->description;
60 59
   $eval           = $eval->description('Foo!');
61 60
 
62 61
 Short description of this command, used for the command list.
63 62
 
64
-=head2 C<usage>
63
+=head2 usage
65 64
 
66 65
   my $usage = $eval->usage;
67 66
   $eval     = $eval->usage('Foo!');
... ...
@@ -73,7 +72,7 @@ Usage information for this command, used for the help screen.
73 72
 L<Mojolicious::Command::eval> inherits all methods from
74 73
 L<Mojolicious::Command> and implements the following new ones.
75 74
 
76
-=head2 C<run>
75
+=head2 run
77 76
 
78 77
   $eval->run(@ARGV);
79 78
 
+6 -6
mojolegacy/lib/Mojolicious/Command/generate.pm
... ...
@@ -41,35 +41,35 @@ example for learning to build new commands, you're welcome to fork it.
41 41
 L<Mojolicious::Command::generate> inherits all attributes from
42 42
 L<Mojolicious::Commands> and implements the following new ones.
43 43
 
44
-=head2 C<description>
44
+=head2 description
45 45
 
46 46
   my $description = $generator->description;
47 47
   $generator      = $generator->description('Foo!');
48 48
 
49 49
 Short description of this command, used for the command list.
50 50
 
51
-=head2 C<hint>
51
+=head2 hint
52 52
 
53 53
   my $hint   = $generator->hint;
54 54
   $generator = $generator->hint('Foo!');
55 55
 
56 56
 Short hint shown after listing available generator commands.
57 57
 
58
-=head2 C<usage>
58
+=head2 usage
59 59
 
60 60
   my $usage  = $generator->usage;
61 61
   $generator = $generator->usage('Foo!');
62 62
 
63 63
 Usage information for this command, used for the help screen.
64 64
 
65
-=head2 C<message>
65
+=head2 message
66 66
 
67 67
   my $msg    = $generator->message;
68 68
   $generator = $generator->message('Bar!');
69 69
 
70 70
 Short usage message shown before listing available generator commands.
71 71
 
72
-=head2 C<namespaces>
72
+=head2 namespaces
73 73
 
74 74
   my $namespaces = $generator->namespaces;
75 75
   $generator     = $generator->namespaces(['MyApp::Command::generate']);
... ...
@@ -82,7 +82,7 @@ L<Mojolicious::Command::generate>.
82 82
 L<Mojolicious::Command::generate> inherits all methods from
83 83
 L<Mojolicious::Commands> and implements the following new ones.
84 84
 
85
-=head2 C<help>
85
+=head2 help
86 86
 
87 87
   $generator->help('app');
88 88
 
+4 -4
mojolegacy/lib/Mojolicious/Command/generate/app.pm
... ...
@@ -59,7 +59,7 @@ use warnings;
59 59
 use FindBin;
60 60
 use lib "$FindBin::Bin/../lib";
61 61
 
62
-# Start commands for application
62
+# Start command line interface for application
63 63
 require Mojolicious::Commands;
64 64
 Mojolicious::Commands->start_app('<%= $class %>');
65 65
 
... ...
@@ -166,14 +166,14 @@ example for learning to build new commands, you're welcome to fork it.
166 166
 L<Mojolicious::Command::generate::app> inherits all attributes from
167 167
 L<Mojolicious::Command> and implements the following new ones.
168 168
 
169
-=head2 C<description>
169
+=head2 description
170 170
 
171 171
   my $description = $app->description;
172 172
   $app            = $app->description('Foo!');
173 173
 
174 174
 Short description of this command, used for the command list.
175 175
 
176
-=head2 C<usage>
176
+=head2 usage
177 177
 
178 178
   my $usage = $app->usage;
179 179
   $app      = $app->usage('Foo!');
... ...
@@ -185,7 +185,7 @@ Usage information for this command, used for the help screen.
185 185
 L<Mojolicious::Command::generate::app> inherits all methods from
186 186
 L<Mojolicious::Command> and implements the following new ones.
187 187
 
188
-=head2 C<run>
188
+=head2 run
189 189
 
190 190
   $app->run(@ARGV);
191 191
 
+3 -3
mojolegacy/lib/Mojolicious/Command/generate/lite_app.pm
... ...
@@ -66,14 +66,14 @@ example for learning to build new commands, you're welcome to fork it.
66 66
 L<Mojolicious::Command::generate::lite_app> inherits all attributes from
67 67
 L<Mojolicious::Command> and implements the following new ones.
68 68
 
69
-=head2 C<description>
69
+=head2 description
70 70
 
71 71
   my $description = $app->description;
72 72
   $app            = $app->description('Foo!');
73 73
 
74 74
 Short description of this command, used for the command list.
75 75
 
76
-=head2 C<usage>
76
+=head2 usage
77 77
 
78 78
   my $usage = $app->usage;
79 79
   $app      = $app->usage('Foo!');
... ...
@@ -85,7 +85,7 @@ Usage information for this command, used for the help screen.
85 85
 L<Mojolicious::Command::generate::lite_app> inherits all methods from
86 86
 L<Mojolicious::Command> and implements the following new ones.
87 87
 
88
-=head2 C<run>
88
+=head2 run
89 89
 
90 90
   $app->run(@ARGV);
91 91
 
+3 -3
mojolegacy/lib/Mojolicious/Command/generate/makefile.pm
... ...
@@ -48,14 +48,14 @@ example for learning to build new commands, you're welcome to fork it.
48 48
 L<Mojolicious::Command::generate::makefile> inherits all attributes from
49 49
 L<Mojolicious::Command> and implements the following new ones.
50 50
 
51
-=head2 C<description>
51
+=head2 description
52 52
 
53 53
   my $description = $makefile->description;
54 54
   $makefile       = $makefile->description('Foo!');
55 55
 
56 56
 Short description of this command, used for the command list.
57 57
 
58
-=head2 C<usage>
58
+=head2 usage
59 59
 
60 60
   my $usage = $makefile->usage;
61 61
   $makefile = $makefile->usage('Foo!');
... ...
@@ -67,7 +67,7 @@ Usage information for this command, used for the help screen.
67 67
 L<Mojolicious::Command::generate::makefile> inherits all methods from
68 68
 L<Mojolicious::Command> and implements the following new ones.
69 69
 
70
-=head2 C<run>
70
+=head2 run
71 71
 
72 72
   $makefile->run(@ARGV);
73 73
 
+4 -4
mojolegacy/lib/Mojolicious/Command/generate/plugin.pm
... ...
@@ -62,7 +62,7 @@ L<<%= $class %>> is a L<Mojolicious> plugin.
62 62
 L<<%= $class %>> inherits all methods from
63 63
 L<Mojolicious::Plugin> and implements the following new ones.
64 64
 
65
-<% %>=head2 C<register>
65
+<% %>=head2 register
66 66
 
67 67
   $plugin->register(Mojolicious->new);
68 68
 
... ...
@@ -134,14 +134,14 @@ example for learning to build new commands, you're welcome to fork it.
134 134
 L<Mojolicious::Command::generate::plugin> inherits all attributes from
135 135
 L<Mojolicious::Command> and implements the following new ones.
136 136
 
137
-=head2 C<description>
137
+=head2 description
138 138
 
139 139
   my $description = $plugin->description;
140 140
   $plugin         = $plugin->description('Foo!');
141 141
 
142 142
 Short description of this command, used for the command list.
143 143
 
144
-=head2 C<usage>
144
+=head2 usage
145 145
 
146 146
   my $usage = $plugin->usage;
147 147
   $plugin   = $plugin->usage('Foo!');
... ...
@@ -153,7 +153,7 @@ Usage information for this command, used for the help screen.
153 153
 L<Mojolicious::Command::generate::plugin> inherits all methods from
154 154
 L<Mojolicious::Command> and implements the following new ones.
155 155
 
156
-=head2 C<run>
156
+=head2 run
157 157
 
158 158
   $plugin->run(@ARGV);
159 159
 
+20 -37
mojolegacy/lib/Mojolicious/Command/get.pm
... ...
@@ -38,7 +38,6 @@ EOF
38 38
 sub run {
39 39
   my ($self, @args) = @_;
40 40
 
41
-  # Options
42 41
   GetOptionsFromArray \@args,
43 42
     'C|charset=s' => \my $charset,
44 43
     'c|content=s' => \(my $content = ''),
... ...
@@ -46,37 +45,28 @@ sub run {
46 45
     'M|method=s'  => \(my $method = 'GET'),
47 46
     'r|redirect'  => \my $redirect,
48 47
     'v|verbose'   => \my $verbose;
49
-  $verbose = 1 if $method eq 'HEAD';
50
-
51
-  # Headers
52
-  my %headers;
53
-  /^\s*([^:]+)\s*:\s*(.+)$/ and $headers{$1} = $2 for @headers;
54 48
 
55
-  # URL and selector
56 49
   die $self->usage unless my $url = decode 'UTF-8', do {my $tmp = shift @args; defined $tmp ? $tmp : ''};
57 50
   my $selector = shift @args;
58 51
 
59
-  # Fresh user agent
52
+  # Parse header pairs
53
+  my %headers;
54
+  /^\s*([^:]+)\s*:\s*(.+)$/ and $headers{$1} = $2 for @headers;
55
+
56
+  # Use global event loop singleton
60 57
   my $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
61 58
   $ua->max_redirects(10) if $redirect;
62 59
 
63
-  # Absolute URL
64
-  if ($url !~ m!/!) { $ua->detect_proxy }
65
-
66
-  # Application
67
-  else { $ua->app($self->app) }
60
+  # Detect proxy for absolute URLs
61
+  if   ($url !~ m!/!) { $ua->detect_proxy }
62
+  else                { $ua->app($self->app) }
68 63
 
69
-  # Start
64
+  # Do the real work with "start" event
70 65
   my $v = my $buffer = '';
71 66
   $ua->on(
72 67
     start => sub {
73 68
       my $tx = pop;
74 69
 
75
-      # Prepare request information
76
-      my $req         = $tx->req;
77
-      my $startline   = $req->build_start_line;
78
-      my $req_headers = $req->build_headers;
79
-
80 70
       # Verbose callback
81 71
       my $v  = $verbose;
82 72
       my $cb = sub {
... ...
@@ -84,22 +74,21 @@ sub run {
84 74
 
85 75
         # Wait for headers
86 76
         return unless $v && $res->headers->is_finished;
77
+        $v = undef;
87 78
 
88
-        # Request
79
+        # Show request
80
+        my $req         = $tx->req;
81
+        my $startline   = $req->build_start_line;
82
+        my $req_headers = $req->build_headers;
89 83
         warn "$startline$req_headers";
90 84
 
91
-        # Response
85
+        # Show response
92 86
         my $version     = $res->version;
93 87
         my $code        = $res->code;
94 88
         my $msg         = $res->message;
95 89
         my $res_headers = $res->headers->to_string;
96 90
         warn "HTTP/$version $code $msg\n$res_headers\n\n";
97
-
98
-        # Finished
99
-        $v = undef;
100 91
       };
101
-
102
-      # Progress
103 92
       $tx->res->on(progress => $cb);
104 93
 
105 94
       # Stream content
... ...
@@ -109,19 +98,16 @@ sub run {
109 98
 
110 99
           # Ignore intermediate content
111 100
           return if $redirect && $res->is_status_class(300);
112
-
113
-          # Chunk
114 101
           $selector ? ($buffer .= pop) : print(pop);
115 102
         }
116 103
       );
117 104
     }
118 105
   );
119 106
 
120
-  # Get
107
+  # Switch to verbose for HEAD requests
108
+  $verbose = 1 if $method eq 'HEAD';
121 109
   STDOUT->autoflush(1);
122 110
   my $tx = $ua->start($ua->build_tx($method, $url, \%headers, $content));
123
-
124
-  # Error
125 111
   my ($err, $code) = $tx->error;
126 112
   $url = encode 'UTF-8', $url;
127 113
   warn qq{Problem loading URL "$url". ($err)\n} if $err && !$code;
... ...
@@ -151,11 +137,9 @@ sub _say {
151 137
 sub _select {
152 138
   my ($buffer, $selector, $charset, @args) = @_;
153 139
 
154
-  # Find
155 140
   my $dom     = Mojo::DOM->new->charset($charset)->parse($buffer);
156 141
   my $results = $dom->find($selector);
157 142
 
158
-  # Commands
159 143
   my $finished;
160 144
   while (defined(my $command = shift @args)) {
161 145
 
... ...
@@ -182,7 +166,6 @@ sub _select {
182 166
     $finished++;
183 167
   }
184 168
 
185
-  # Render
186 169
   unless ($finished) { _say($_) for @$results }
187 170
 }
188 171
 
... ...
@@ -211,14 +194,14 @@ example for learning to build new commands, you're welcome to fork it.
211 194
 L<Mojolicious::Command::get> performs requests to remote hosts or local
212 195
 applications.
213 196
 
214
-=head2 C<description>
197
+=head2 description
215 198
 
216 199
   my $description = $get->description;
217 200
   $get            = $get->description('Foo!');
218 201
 
219 202
 Short description of this command, used for the command list.
220 203
 
221
-=head2 C<usage>
204
+=head2 usage
222 205
 
223 206
   my $usage = $get->usage;
224 207
   $get      = $get->usage('Foo!');
... ...
@@ -230,7 +213,7 @@ Usage information for this command, used for the help screen.
230 213
 L<Mojolicious::Command::get> inherits all methods from L<Mojolicious::Command>
231 214
 and implements the following new ones.
232 215
 
233
-=head2 C<run>
216
+=head2 run
234 217
 
235 218
   $get->run(@ARGV);
236 219
 
+3 -3
mojolegacy/lib/Mojolicious/Command/inflate.pm
... ...
@@ -51,14 +51,14 @@ example for learning to build new commands, you're welcome to fork it.
51 51
 L<Mojolicious::Command::inflate> inherits all attributes from
52 52
 L<Mojolicious::Command> and implements the following new ones.
53 53
 
54
-=head2 C<description>
54
+=head2 description
55 55
 
56 56
   my $description = $inflate->description;
57 57
   $inflate        = $inflate->description('Foo!');
58 58
 
59 59
 Short description of this command, used for the command list.
60 60
 
61
-=head2 C<usage>
61
+=head2 usage
62 62
 
63 63
   my $usage = $inflate->usage;
64 64
   $inflate  = $inflate->usage('Foo!');
... ...
@@ -70,7 +70,7 @@ Usage information for this command, used for the help screen.
70 70
 L<Mojolicious::Command::inflate> inherits all methods from
71 71
 L<Mojolicious::Command> and implements the following new ones.
72 72
 
73
-=head2 C<run>
73
+=head2 run
74 74
 
75 75
   $inflate->run(@ARGV);
76 76
 
+128
mojolegacy/lib/Mojolicious/Command/prefork.pm
... ...
@@ -0,0 +1,128 @@
1
+package Mojolicious::Command::prefork;
2
+use Mojo::Base 'Mojolicious::Command';
3
+
4
+use Getopt::Long qw(GetOptionsFromArray :config no_auto_abbrev no_ignore_case);
5
+use Mojo::Server::Prefork;
6
+
7
+has description =>
8
+  "Start application with preforking HTTP and WebSocket server.\n";
9
+has usage => <<"EOF";
10
+usage: $0 prefork [OPTIONS]
11
+
12
+These options are available:
13
+  -A, --accepts <number>               Number of connections for workers to
14
+                                       accept, defaults to 1000.
15
+  -a, --accept-interval <seconds>      Accept interval, defaults to 0.025.
16
+  -b, --backlog <size>                 Listen backlog size, defaults to
17
+                                       SOMAXCONN.
18
+  -c, --clients <number>               Maximum number of concurrent clients,
19
+                                       defaults to 1000.
20
+  -G, --graceful-timeout <seconds>     Graceful timeout, defaults to 20.
21
+  -g, --group <name>                   Group name for process.
22
+      --heartbeat-interval <seconds>   Heartbeat interval, defaults to 5.
23
+  -H, --heartbeat-timeout <seconds>    Heartbeat timeout, defaults to 20.
24
+  -i, --inactivity <seconds>           Inactivity timeout, defaults to the
25
+                                       value of MOJO_INACTIVITY_TIMEOUT or 15.
26
+      --lock-file <path>               Path to lock file, defaults to a random
27
+                                       file.
28
+  -L, --lock-timeout <seconds>         Lock timeout, defaults to 0.5.
29
+  -l, --listen <location>              One or more locations you want to
30
+                                       listen on, defaults to the value of
31
+                                       MOJO_LISTEN or "http://*:3000".
32
+      --multi-accept <number>          Number of connection to accept at once,
33
+                                       defaults to 50.
34
+  -P, --pid-file <path>                Path to process id file, defaults to a
35
+                                       random file.
36
+  -p, --proxy                          Activate reverse proxy support,
37
+                                       defaults to the value of
38
+                                       MOJO_REVERSE_PROXY.
39
+  -r, --requests <number>              Maximum number of requests per
40
+                                       keep-alive connection, defaults to 25.
41
+  -u, --user <name>                    Username for process.
42
+  -w, --workers <number>               Number of workers, defaults to 4.
43
+EOF
44
+
45
+sub run {
46
+  my ($self, @args) = @_;
47
+
48
+  my $prefork = Mojo::Server::Prefork->new(app => $self->app);
49
+  GetOptionsFromArray \@args,
50
+    'A|accepts=i'           => sub { $prefork->accepts($_[1]) },
51
+    'a|accept-interval=i'   => sub { $prefork->accept_interval($_[1]) },
52
+    'b|backlog=i'           => sub { $prefork->backlog($_[1]) },
53
+    'c|clients=i'           => sub { $prefork->max_clients($_[1]) },
54
+    'G|graceful-timeout=i'  => sub { $prefork->graceful_timeout($_[1]) },
55
+    'g|group=s'             => sub { $prefork->group($_[1]) },
56
+    'heartbeat-interval=i'  => sub { $prefork->heartbeat_interval($_[1]) },
57
+    'H|heartbeat-timeout=i' => sub { $prefork->heartbeat_timeout($_[1]) },
58
+    'i|inactivity=i'        => sub { $prefork->inactivity_timeout($_[1]) },
59
+    'lock-file=s'           => sub { $prefork->lock_file($_[1]) },
60
+    'L|lock-timeout=i'      => sub { $prefork->lock_timeout($_[1]) },
61
+    'l|listen=s'     => \my @listen,
62
+    'multi-accept=i' => sub { $prefork->multi_accept($_[1]) },
63
+    'P|pid-file=s'   => sub { $prefork->pid_file($_[1]) },
64
+    'p|proxy'        => sub { $ENV{MOJO_REVERSE_PROXY} = 1 },
65
+    'r|requests=i' => sub { $prefork->max_requests($_[1]) },
66
+    'u|user=s'     => sub { $prefork->user($_[1]) },
67
+    'w|workers=i'  => sub { $prefork->workers($_[1]) };
68
+
69
+  $prefork->listen(\@listen) if @listen;
70
+  $prefork->run;
71
+}
72
+
73
+1;
74
+
75
+=head1 NAME
76
+
77
+Mojolicious::Command::prefork - Prefork command
78
+
79
+=head1 SYNOPSIS
80
+
81
+  use Mojolicious::Command::prefork;
82
+
83
+  my $prefork = Mojolicious::Command::prefork->new;
84
+  $prefork->run(@ARGV);
85
+
86
+=head1 DESCRIPTION
87
+
88
+L<Mojolicious::Command::prefork> starts applications with
89
+L<Mojo::Server::Prefork> backend.
90
+
91
+This is a core command, that means it is always enabled and its code a good
92
+example for learning to build new commands, you're welcome to fork it.
93
+
94
+=head1 ATTRIBUTES
95
+
96
+L<Mojolicious::Command::prefork> inherits all attributes from
97
+L<Mojolicious::Command> and implements the following new ones.
98
+
99
+=head2 description
100
+
101
+  my $description = $prefork->description;
102
+  $prefork        = $prefork->description('Foo!');
103
+
104
+Short description of this command, used for the command list.
105
+
106
+=head2 usage
107
+
108
+  my $usage = $prefork->usage;
109
+  $prefork  = $prefork->usage('Foo!');
110
+
111
+Usage information for this command, used for the help screen.
112
+
113
+=head1 METHODS
114
+
115
+L<Mojolicious::Command::prefork> inherits all methods from
116
+L<Mojolicious::Command> and implements the following new ones.
117
+
118
+=head2 run
119
+
120
+  $prefork->run(@ARGV);
121
+
122
+Run this command.
123
+
124
+=head1 SEE ALSO
125
+
126
+L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
127
+
128
+=cut
+3 -3
mojolegacy/lib/Mojolicious/Command/psgi.pm
... ...
@@ -34,14 +34,14 @@ example for learning to build new commands, you're welcome to fork it.
34 34
 L<Mojolicious::Command::psgi> inherits all attributes from
35 35
 L<Mojolicious::Command> and implements the following new ones.
36 36
 
37
-=head2 C<description>
37
+=head2 description
38 38
 
39 39
   my $description = $psgi->description;
40 40
   $psgi           = $psgi->description('Foo!');
41 41
 
42 42
 Short description of this command, used for the command list.
43 43
 
44
-=head2 C<usage>
44
+=head2 usage
45 45
 
46 46
   my $usage = $psgi->usage;
47 47
   $psgi     = $psgi->usage('Foo!');
... ...
@@ -53,7 +53,7 @@ Usage information for this command, used for the help screen.
53 53
 L<Mojolicious::Command::psgi> inherits all methods from
54 54
 L<Mojolicious::Command> and implements the following new ones.
55 55
 
56
-=head2 C<run>
56
+=head2 run
57 57
 
58 58
   my $app = $psgi->run;
59 59
 
+5 -10
mojolegacy/lib/Mojolicious/Command/routes.pm
... ...
@@ -15,10 +15,8 @@ EOF
15 15
 sub run {
16 16
   my ($self, @args) = @_;
17 17
 
18
-  # Options
19 18
   GetOptionsFromArray \@args, 'v|verbose' => \my $verbose;
20 19
 
21
-  # Walk and draw
22 20
   my $routes = [];
23 21
   $self->_walk($_, 0, $routes) for @{$self->app->routes->children};
24 22
   $self->_draw($routes, $verbose);
... ...
@@ -27,7 +25,7 @@ sub run {
27 25
 sub _draw {
28 26
   my ($self, $routes, $verbose) = @_;
29 27
 
30
-  # Length
28
+  # Calculate column widths
31 29
   my @length = (0, 0, 0);
32 30
   for my $node (@$routes) {
33 31
 
... ...
@@ -46,7 +44,7 @@ sub _draw {
46 44
     $length[2] = $len if $len > $length[2];
47 45
   }
48 46
 
49
-  # Draw
47
+  # Draw all routes
50 48
   for my $node (@$routes) {
51 49
     my @parts;
52 50
 
... ...
@@ -75,7 +73,6 @@ sub _draw {
75 73
     $format .= '?' if $format && $optional;
76 74
     push @parts, $format ? "$regex$format" : $regex if $verbose;
77 75
 
78
-    # Route
79 76
     say join('  ', @parts);
80 77
   }
81 78
 }
... ...
@@ -83,12 +80,10 @@ sub _draw {
83 80
 sub _walk {
84 81
   my ($self, $node, $depth, $routes) = @_;
85 82
 
86
-  # Pattern
87 83
   my $prefix = '';
88 84
   if (my $i = $depth * 2) { $prefix .= ' ' x $i . '+' }
89 85
   push @$routes, [$prefix . ($node->pattern->pattern || '/'), $node];
90 86
 
91
-  # Walk
92 87
   $depth++;
93 88
   $self->_walk($_, $depth, $routes) for @{$node->children};
94 89
   $depth--;
... ...
@@ -119,14 +114,14 @@ example for learning to build new commands, you're welcome to fork it.
119 114
 L<Mojolicious::Command::routes> inherits all attributes from
120 115
 L<Mojolicious::Command> and implements the following new ones.
121 116
 
122
-=head2 C<description>
117
+=head2 description
123 118
 
124 119
   my $description = $routes->description;
125 120
   $routes         = $routes->description('Foo!');
126 121
 
127 122
 Short description of this command, used for the command list.
128 123
 
129
-=head2 C<usage>
124
+=head2 usage
130 125
 
131 126
   my $usage = $routes->usage;
132 127
   $routes   = $routes->usage('Foo!');
... ...
@@ -138,7 +133,7 @@ Usage information for this command, used for the help screen.
138 133
 L<Mojolicious::Command::routes> inherits all methods from
139 134
 L<Mojolicious::Command> and implements the following new ones.
140 135
 
141
-=head2 C<run>
136
+=head2 run
142 137
 
143 138
   $routes->run(@ARGV);
144 139
 
+5 -10
mojolegacy/lib/Mojolicious/Command/test.pm
... ...
@@ -18,28 +18,23 @@ EOF
18 18
 sub run {
19 19
   my ($self, @args) = @_;
20 20
 
21
-  # Options
22 21
   GetOptionsFromArray \@args, 'v|verbose' => sub { $ENV{HARNESS_VERBOSE} = 1 };
23 22
 
24
-  # Search tests
25 23
   unless (@args) {
26 24
     my @base = splitdir(abs2rel $FindBin::Bin);
27 25
 
28
-    # Test directory in the same directory as "mojo" (t)
26
+    # "./t"
29 27
     my $path = catdir @base, 't';
30 28
 
31
-    # Test dirctory in the directory above "mojo" (../t)
29
+    # "../t"
32 30
     $path = catdir @base, '..', 't' unless -d $path;
33 31
     die "Can't find test directory.\n" unless -d $path;
34 32
 
35
-    # List test files
36 33
     my $home = Mojo::Home->new($path);
37 34
     /\.t$/ and push(@args, $home->rel_file($_)) for @{$home->list_files};
38
-
39 35
     say "Running tests from '", realpath($path), "'.";
40 36
   }
41 37
 
42
-  # Run tests
43 38
   $ENV{HARNESS_OPTIONS} = defined $ENV{HARNESS_OPTIONS} ? $ENV{HARNESS_OPTIONS} : 'c';
44 39
   require Test::Harness;
45 40
   Test::Harness::runtests(sort @args);
... ...
@@ -70,14 +65,14 @@ example for learning to build new commands, you're welcome to fork it.
70 65
 L<Mojolicious::Command::test> inherits all attributes from
71 66
 L<Mojolicious::Command> and implements the following new ones.
72 67
 
73
-=head2 C<description>
68
+=head2 description
74 69
 
75 70
   my $description = $test->description;
76 71
   $test           = $test->description('Foo!');
77 72
 
78 73
 Short description of this command, used for the command list.
79 74
 
80
-=head2 C<usage>
75
+=head2 usage
81 76
 
82 77
   my $usage = $test->usage;
83 78
   $test     = $test->usage('Foo!');
... ...
@@ -89,7 +84,7 @@ Usage information for this command, used for the help screen.
89 84
 L<Mojolicious::Command::test> inherits all methods from
90 85
 L<Mojolicious::Command> and implements the following new ones.
91 86
 
92
-=head2 C<run>
87
+=head2 run
93 88
 
94 89
   $test->run(@ARGV);
95 90
 
+4 -10
mojolegacy/lib/Mojolicious/Command/version.pm
... ...
@@ -11,14 +11,9 @@ has usage       => "usage: $0 version\n";
11 11
 sub run {
12 12
   my $self = shift;
13 13
 
14
-  # EV
15 14
   my $ev = eval 'use Mojo::Reactor::EV; 1' ? $EV::VERSION : 'not installed';
16
-
17
-  # IPv6
18 15
   my $ipv6
19 16
     = Mojo::IOLoop::Server::IPV6 ? $IO::Socket::IP::VERSION : 'not installed';
20
-
21
-  # TLS
22 17
   my $tls
23 18
     = Mojo::IOLoop::Server::TLS ? $IO::Socket::SSL::VERSION : 'not installed';
24 19
 
... ...
@@ -34,13 +29,12 @@ OPTIONAL
34 29
 
35 30
 EOF
36 31
 
37
-  # Latest version
32
+  # Check latest version on CPAN
38 33
   my $latest = eval {
39 34
     my $ua = Mojo::UserAgent->new(max_redirects => 10)->detect_proxy;
40 35
     $ua->get('api.metacpan.org/v0/release/Mojolicious')->res->json->{version};
41 36
   };
42 37
 
43
-  # Message
44 38
   return unless $latest;
45 39
   my $msg = 'This version is up to date, have fun!';
46 40
   $msg = 'Thanks for testing a development release, you are awesome!'
... ...
@@ -76,14 +70,14 @@ example for learning to build new commands, you're welcome to fork it.
76 70
 L<Mojolicious::Command::version> inherits all attributes from
77 71
 L<Mojolicious::Command> and implements the following new ones.
78 72
 
79
-=head2 C<description>
73
+=head2 description
80 74
 
81 75
   my $description = $v->description;
82 76
   $v              = $v->description('Foo!');
83 77
 
84 78
 Short description of this command, used for the command list.
85 79
 
86
-=head2 C<usage>
80
+=head2 usage
87 81
 
88 82
   my $usage = $v->usage;
89 83
   $v        = $v->usage('Foo!');
... ...
@@ -95,7 +89,7 @@ Usage information for this command, used for the help screen.
95 89
 L<Mojolicious::Command::version> inherits all methods from
96 90
 L<Mojolicious::Command> and implements the following new ones.
97 91
 
98
-=head2 C<run>
92
+=head2 run
99 93
 
100 94
   $v->run(@ARGV);
101 95
 
+47 -53
mojolegacy/lib/Mojolicious/Commands.pm
... ...
@@ -1,8 +1,8 @@
1 1
 package Mojolicious::Commands;
2 2
 use Mojo::Base 'Mojolicious::Command';
3 3
 
4
-use Getopt::Long
5
-  qw(GetOptions :config no_auto_abbrev no_ignore_case pass_through);
4
+use Getopt::Long 'GetOptions';
5
+use List::Util 'max';
6 6
 use Mojo::Server;
7 7
 
8 8
 has hint => <<"EOF";
... ...
@@ -41,11 +41,13 @@ sub detect {
41 41
 
42 42
 # Command line options for MOJO_HELP, MOJO_HOME and MOJO_MODE
43 43
 BEGIN {
44
+  Getopt::Long::Configure(qw(no_auto_abbrev no_ignore_case pass_through));
44 45
   GetOptions(
45 46
     'h|help'   => sub { $ENV{MOJO_HELP} = 1 },
46 47
     'home=s'   => sub { $ENV{MOJO_HOME} = $_[1] },
47 48
     'm|mode=s' => sub { $ENV{MOJO_MODE} = $_[1] }
48 49
   ) unless __PACKAGE__->detect;
50
+  Getopt::Long::Configure('default');
49 51
 }
50 52
 
51 53
 sub run {
... ...
@@ -64,7 +66,6 @@ sub run {
64 66
     $name = shift @args if my $help = $name eq 'help';
65 67
     $help = $ENV{MOJO_HELP} = $ENV{MOJO_HELP} ? 1 : $help;
66 68
 
67
-    # Try all namespaces
68 69
     my $module;
69 70
     $module = _command("${_}::$name", 1) and last for @{$self->namespaces};
70 71
 
... ...
@@ -72,15 +73,15 @@ sub run {
72 73
     die qq{Unknown command "$name", maybe you need to install it?\n}
73 74
       unless $module;
74 75
 
75
-    # Run
76
+    # Run command
76 77
     my $command = $module->new(app => $self->app);
77 78
     return $help ? $command->help(@args) : $command->run(@args);
78 79
   }
79 80
 
80
-  # Test
81
+  # Hide list for tests
81 82
   return 1 if $ENV{HARNESS_ACTIVE};
82 83
 
83
-  # Try all namespaces
84
+  # Find all available commands
84 85
   my (@commands, %seen);
85 86
   my $loader = Mojo::Loader->new;
86 87
   for my $namespace (@{$self->namespaces}) {
... ...
@@ -91,25 +92,23 @@ sub run {
91 92
     }
92 93
   }
93 94
 
94
-  # Make list
95
-  my @list;
96
-  my $max = 0;
97
-  for my $command (@commands) {
98
-    my $len = length $command->[0];
99
-    $max = $len if $len > $max;
100
-    push @list, [$command->[0], $command->[1]->new->description];
101
-  }
102
-
103
-  # Print list
95
+  # Print list of all available commands
96
+  my $max = max map { length $_->[0] } @commands;
104 97
   print $self->message;
105
-  for my $command (@list) {
106
-    my ($name, $description) = @$command;
107
-    print "  $name" . (' ' x ($max - length $name)) . "   $description";
98
+  for my $command (@commands) {
99
+    my $name        = $command->[0];
100
+    my $description = $command->[1]->new->description;
101
+    print "  $name", (' ' x ($max - length $name)), "   $description";
108 102
   }
109 103
   return print $self->hint;
110 104
 }
111 105
 
106
+# DEPRECATED in Rainbow!
112 107
 sub start {
108
+  warn <<EOF;
109
+Mojolicious::Commands->start is DEPRECATED in favor of
110
+Mojolicious::Commands->start_app!!!
111
+EOF
113 112
   my $self = shift;
114 113
   return $self->start_app($ENV{MOJO_APP} => @_) if $ENV{MOJO_APP};
115 114
   return $self->new->app->start(@_);
... ...
@@ -151,7 +150,7 @@ the C<Mojolicious::Command> namespace.
151 150
 
152 151
 These commands are available by default.
153 152
 
154
-=head2 C<help>
153
+=head2 help
155 154
 
156 155
   $ mojo
157 156
   $ mojo help
... ...
@@ -164,31 +163,31 @@ List available commands with short descriptions.
164 163
 
165 164
 List available options for the command with short descriptions.
166 165
 
167
-=head2 C<cgi>
166
+=head2 cgi
168 167
 
169 168
   $ ./myapp.pl cgi
170 169
 
171 170
 Start application with CGI backend, usually auto detected.
172 171
 
173
-=head2 C<cpanify>
172
+=head2 cpanify
174 173
 
175 174
   $ mojo cpanify -u sri -p secr3t Mojolicious-Plugin-Fun-0.1.tar.gz
176 175
 
177 176
 Upload files to CPAN.
178 177
 
179
-=head2 C<daemon>
178
+=head2 daemon
180 179
 
181 180
   $ ./myapp.pl daemon
182 181
 
183
-Start application with standalone HTTP server backend.
182
+Start application with standalone HTTP and WebSocket server server.
184 183
 
185
-=head2 C<eval>
184
+=head2 eval
186 185
 
187 186
   $ ./myapp.pl eval 'say app->home'
188 187
 
189 188
 Run code against application.
190 189
 
191
-=head2 C<generate>
190
+=head2 generate
192 191
 
193 192
   $ mojo generate
194 193
   $ mojo generate help
... ...
@@ -201,66 +200,72 @@ List available generator commands with short descriptions.
201 200
 
202 201
 List available options for generator command with short descriptions.
203 202
 
204
-=head2 C<generate app>
203
+=head2 generate app
205 204
 
206 205
   $ mojo generate app <AppName>
207 206
 
208 207
 Generate application directory structure for a fully functional L<Mojolicious>
209 208
 application.
210 209
 
211
-=head2 C<generate lite_app>
210
+=head2 generate lite_app
212 211
 
213 212
   $ mojo generate lite_app
214 213
 
215 214
 Generate a fully functional L<Mojolicious::Lite> application.
216 215
 
217
-=head2 C<generate makefile>
216
+=head2 generate makefile
218 217
 
219 218
   $ mojo generate makefile
220 219
   $ ./myapp.pl generate makefile
221 220
 
222 221
 Generate C<Makefile.PL> file for application.
223 222
 
224
-=head2 C<generate plugin>
223
+=head2 generate plugin
225 224
 
226 225
   $ mojo generate plugin <PluginName>
227 226
 
228 227
 Generate directory structure for a fully functional L<Mojolicious> plugin.
229 228
 
230
-=head2 C<get>
229
+=head2 get
231 230
 
232 231
   $ mojo get http://mojolicio.us
233 232
   $ ./myapp.pl get /foo
234 233
 
235 234
 Perform requests to remote host or local application.
236 235
 
237
-=head2 C<inflate>
236
+=head2 inflate
238 237
 
239 238
   $ ./myapp.pl inflate
240 239
 
241 240
 Turn templates and static files embedded in the C<DATA> sections of your
242 241
 application into real files.
243 242
 
244
-=head2 C<psgi>
243
+=head2 prefork
244
+
245
+  $ ./myapp.pl prefork
246
+
247
+Start application with standalone preforking HTTP and WebSocket server.
248
+
249
+=head2 psgi
245 250
 
246 251
   $ ./myapp.pl psgi
247 252
 
248 253
 Start application with PSGI backend, usually auto detected.
249 254
 
250
-=head2 C<routes>
255
+=head2 routes
251 256
 
252 257
   $ ./myapp.pl routes
253 258
 
254 259
 List application routes.
255 260
 
256
-=head2 C<test>
261
+=head2 test
257 262
 
258 263
   $ ./myapp.pl test
259 264
   $ ./myapp.pl test t/fun.t
260 265
 
261 266
 Runs application tests from the C<t> directory.
262 267
 
263
-=head2 C<version>
268
+=head2 version
264 269
 
265 270
   $ mojo version
266 271
   $ ./myapp.pl version
... ...
@@ -273,21 +278,21 @@ for debugging.
273 278
 L<Mojolicious::Commands> inherits all attributes from L<Mojolicious::Command>
274 279
 and implements the following new ones.
275 280
 
276
-=head2 C<hint>
281
+=head2 hint
277 282
 
278 283
   my $hint  = $commands->hint;
279 284
   $commands = $commands->hint('Foo!');
280 285
 
281 286
 Short hint shown after listing available commands.
282 287
 
283
-=head2 C<message>
288
+=head2 message
284 289
 
285 290
   my $msg   = $commands->message;
286 291
   $commands = $commands->message('Hello World!');
287 292
 
288 293
 Short usage message shown before listing available commands.
289 294
 
290
-=head2 C<namespaces>
295
+=head2 namespaces
291 296
 
292 297
   my $namespaces = $commands->namespaces;
293 298
   $commands      = $commands->namespaces(['MyApp::Command']);
... ...
@@ -302,14 +307,14 @@ Namespaces to load commands from, defaults to C<Mojolicious::Command>.
302 307
 L<Mojolicious::Commands> inherits all methods from L<Mojolicious::Command> and
303 308
 implements the following new ones.
304 309
 
305
-=head2 C<detect>
310
+=head2 detect
306 311
 
307 312
   my $env = $commands->detect;
308 313
   my $env = $commands->detect($guess);
309 314
 
310 315
 Try to detect environment.
311 316
 
312
-=head2 C<run>
317
+=head2 run
313 318
 
314 319
   $commands->run;
315 320
   $commands->run(@ARGV);
... ...
@@ -317,18 +322,7 @@ Try to detect environment.
317 322
 Load and run commands. Automatic deployment environment detection can be
318 323
 disabled with the C<MOJO_NO_DETECT> environment variable.
319 324
 
320
-=head2 C<start>
321
-
322
-  Mojolicious::Commands->start;
323
-  Mojolicious::Commands->start(@ARGV);
324
-
325
-Start the command line interface for application from the value of the
326
-C<MOJO_APP> environment variable or L<Mojo::HelloWorld>.
327
-
328
-  # Always start daemon and ignore @ARGV
329
-  Mojolicious::Commands->start('daemon', '-l', 'http://*:8080');
330
-
331
-=head2 C<start_app>
325
+=head2 start_app
332 326
 
333 327
   Mojolicious::Commands->start_app('MyApp');
334 328
   Mojolicious::Commands->start_app(MyApp => @ARGV);
+86 -67
mojolegacy/lib/Mojolicious/Controller.pm
... ...
@@ -1,6 +1,7 @@
1 1
 package Mojolicious::Controller;
2 2
 use Mojo::Base -base;
3 3
 
4
+# No imports, for security reasons!
4 5
 use Carp ();
5 6
 use Mojo::ByteStream;
6 7
 use Mojo::Cookie::Response;
... ...
@@ -29,11 +30,11 @@ sub AUTOLOAD {
29 30
 
30 31
   # Method
31 32
   my ($package, $method) = our $AUTOLOAD =~ /^([\w:]+)::(\w+)$/;
32
-  Carp::croak("Undefined subroutine &${package}::$method called")
33
-    unless Scalar::Util::blessed($self) && $self->isa(__PACKAGE__);
33
+  Carp::croak "Undefined subroutine &${package}::$method called"
34
+    unless Scalar::Util::blessed $self && $self->isa(__PACKAGE__);
34 35
 
35 36
   # Call helper
36
-  Carp::croak(qq{Can't locate object method "$method" via package "$package"})
37
+  Carp::croak qq{Can't locate object method "$method" via package "$package"}
37 38
     unless my $helper = $self->app->renderer->helpers->{$method};
38 39
   return $self->$helper(@_);
39 40
 }
... ...
@@ -59,8 +60,6 @@ sub cookie {
59 60
 
60 61
   # Request cookies
61 62
   return map { $_->value } $self->req->cookie($name) if wantarray;
62
-
63
-  # Request cookie
64 63
   return undef unless my $cookie = $self->req->cookie($name);
65 64
   return $cookie->value;
66 65
 }
... ...
@@ -133,9 +132,8 @@ sub param {
133 132
     return ref $value eq 'ARRAY' ? wantarray ? @$value : $$value[0] : $value;
134 133
   }
135 134
 
136
-  # Upload
137
-  my $upload = $req->upload($name);
138
-  return $upload if $upload;
135
+  # Uploads
136
+  return $req->upload($name) if $req->upload($name);
139 137
 
140 138
   # Param values
141 139
   return $req->param($name);
... ...
@@ -158,7 +156,7 @@ sub render {
158 156
   my $args = ref $_[0] ? $_[0] : {@_};
159 157
   $args->{template} = $template if $template;
160 158
 
161
-  # Template
159
+  # Detect template name
162 160
   my $stash = $self->stash;
163 161
   unless ($args->{template} || $stash->{template}) {
164 162
 
... ...
@@ -177,13 +175,16 @@ sub render {
177 175
   }
178 176
 
179 177
   # Render
180
-  my ($output, $type) = $self->app->renderer->render($self, $args);
178
+  my $app = $self->app;
179
+  my ($output, $format) = $app->renderer->render($self, $args);
181 180
   return undef unless defined $output;
182 181
   return Mojo::ByteStream->new($output) if $args->{partial};
183 182
 
184 183
   # Prepare response
184
+  $app->plugins->emit_hook(after_render => $self, \$output, $format);
185 185
   my $headers = $self->res->body($output)->headers;
186
-  $headers->content_type($type) unless $headers->content_type;
186
+  $headers->content_type($app->types->type($format) || 'text/plain')
187
+    unless $headers->content_type;
187 188
   return !!$self->rendered($stash->{status});
188 189
 }
189 190
 
... ...
@@ -192,7 +193,6 @@ sub render_data { shift->render(data => @_) }
192 193
 sub render_exception {
193 194
   my ($self, $e) = @_;
194 195
 
195
-  # Log exception
196 196
   my $app = $self->app;
197 197
   $app->log->error($e = Mojo::Exception->new($e));
198 198
 
... ...
@@ -310,7 +310,7 @@ sub respond_to {
310 310
 sub send {
311 311
   my ($self, $msg, $cb) = @_;
312 312
   my $tx = $self->tx;
313
-  Carp::croak('No WebSocket connection to send message to')
313
+  Carp::croak 'No WebSocket connection to send message to'
314 314
     unless $tx->is_websocket;
315 315
   $tx->send($msg => sub { shift and $self->$cb(@_) if $cb });
316 316
   return $self->rendered(101);
... ...
@@ -395,8 +395,7 @@ sub url_for {
395 395
   my $target = shift; $target = defined $target ? $target : '';
396 396
 
397 397
   # Absolute URL
398
-  return $target
399
-    if Scalar::Util::blessed($target) && $target->isa('Mojo::URL');
398
+  return $target if Scalar::Util::blessed $target && $target->isa('Mojo::URL');
400 399
   return Mojo::URL->new($target) if $target =~ m!^\w+://!;
401 400
 
402 401
   # Base
... ...
@@ -408,8 +407,7 @@ sub url_for {
408 407
   my $path = $url->path;
409 408
   if ($target =~ m!^/!) {
410 409
     if (my $prefix = $self->stash->{path}) {
411
-      my $real = Mojo::Util::url_unescape($req->url->path->to_abs_string);
412
-      $real = do {my $tmp = Mojo::Util::decode('UTF-8', $real); defined $tmp ? $tmp : $real};
410
+      my $real = $req->url->path->to_route;
413 411
       $real =~ s!/?$prefix$!$target!;
414 412
       $target = $real;
415 413
     }
... ...
@@ -457,7 +455,7 @@ sub _fallbacks {
457 455
   # Mode specific template
458 456
   return 1 if $self->render($options);
459 457
 
460
-  # Template
458
+  # Normal template
461 459
   $options->{template} = $template;
462 460
   return 1 if $self->render($options);
463 461
 
... ...
@@ -471,6 +469,8 @@ sub _fallbacks {
471 469
 
472 470
 1;
473 471
 
472
+=encoding utf8
473
+
474 474
 =head1 NAME
475 475
 
476 476
 Mojolicious::Controller - Controller base class
... ...
@@ -500,7 +500,7 @@ unless you set C<controller_class> in your application.
500 500
 L<Mojolicious::Controller> inherits all attributes from L<Mojo::Base> and
501 501
 implements the following new ones.
502 502
 
503
-=head2 C<app>
503
+=head2 app
504 504
 
505 505
   my $app = $c->app;
506 506
   $c      = $c->app(Mojolicious->new);
... ...
@@ -511,7 +511,7 @@ defaults to a L<Mojolicious> object.
511 511
   # Use application logger
512 512
   $c->app->log->debug('Hello Mojo!');
513 513
 
514
-=head2 C<match>
514
+=head2 match
515 515
 
516 516
   my $m = $c->match;
517 517
   $c    = $c->match(Mojolicious::Routes::Match->new);
... ...
@@ -522,7 +522,7 @@ L<Mojolicious::Routes::Match> object.
522 522
   # Introspect
523 523
   my $foo = $c->match->endpoint->pattern->defaults->{foo};
524 524
 
525
-=head2 C<tx>
525
+=head2 tx
526 526
 
527 527
   my $tx = $c->tx;
528 528
   $c     = $c->tx(Mojo::Transaction::HTTP->new);
... ...
@@ -538,7 +538,7 @@ L<Mojo::Transaction::HTTP> or L<Mojo::Transaction::WebSocket> object.
538 538
 L<Mojolicious::Controller> inherits all methods from L<Mojo::Base> and
539 539
 implements the following new ones.
540 540
 
541
-=head2 C<cookie>
541
+=head2 cookie
542 542
 
543 543
   my $value  = $c->cookie('foo');
544 544
   my @values = $c->cookie('foo');
... ...
@@ -547,17 +547,17 @@ implements the following new ones.
547 547
 
548 548
 Access request cookie values and create new response cookies.
549 549
 
550
-  # Create response cookie with domain
551
-  $c->cookie(name => 'sebastian', {domain => 'mojolicio.us'});
550
+  # Create response cookie with domain and expiration date
551
+  $c->cookie(user => 'sri', {domain => 'mojolicio.us', expires => time + 60});
552 552
 
553
-=head2 C<finish>
553
+=head2 finish
554 554
 
555 555
   $c = $c->finish;
556 556
   $c = $c->finish('Bye!');
557 557
 
558 558
 Gracefully end WebSocket connection or long poll stream.
559 559
 
560
-=head2 C<flash>
560
+=head2 flash
561 561
 
562 562
   my $foo = $c->flash('foo');
563 563
   $c      = $c->flash({foo => 'bar'});
... ...
@@ -569,26 +569,42 @@ Data storage persistent only for the next request, stored in the C<session>.
569 569
   $c->flash(message => 'User created successfully!');
570 570
   $c->redirect_to('show_user', id => 23);
571 571
 
572
-=head2 C<on>
572
+=head2 on
573 573
 
574 574
   my $cb = $c->on(finish => sub {...});
575 575
 
576 576
 Subscribe to events of C<tx>, which is usually a L<Mojo::Transaction::HTTP> or
577 577
 L<Mojo::Transaction::WebSocket> object.
578 578
 
579
-  # Emitted when the transaction has been finished
579
+  # Do something after the transaction has been finished
580 580
   $c->on(finish => sub {
581 581
     my $c = shift;
582 582
     $c->app->log->debug('We are done!');
583 583
   });
584 584
 
585
-  # Emitted when new WebSocket messages arrive
585
+  # Receive WebSocket message
586 586
   $c->on(message => sub {
587 587
     my ($c, $msg) = @_;
588 588
     $c->app->log->debug("Message: $msg");
589 589
   });
590 590
 
591
-=head2 C<param>
591
+  # Receive JSON object via WebSocket "Text" message
592
+  use Mojo::JSON 'j';
593
+  $c->on(text => sub {
594
+    my ($c, $bytes) = @_;
595
+    my $test = j($bytes)->{test};
596
+    $c->app->log->debug("Test: $test");
597
+  });
598
+
599
+  # Receive JSON object via WebSocket "Binary" message
600
+  use Mojo::JSON 'j';
601
+  $c->on(binary => sub {
602
+    my ($c, $bytes) = @_;
603
+    my $test = j($bytes)->{test};
604
+    $c->app->log->debug("Test: $test");
605
+  });
606
+
607
+=head2 param
592 608
 
593 609
   my @names       = $c->param;
594 610
   my $foo         = $c->param('foo');
... ...
@@ -622,7 +638,7 @@ For more control you can also access request information directly.
622 638
   # Only file uploads
623 639
   my $foo = $c->req->upload('foo');
624 640
 
625
-=head2 C<redirect_to>
641
+=head2 redirect_to
626 642
 
627 643
   $c = $c->redirect_to('named');
628 644
   $c = $c->redirect_to('named', foo => 'bar');
... ...
@@ -638,7 +654,7 @@ Prepare a C<302> redirect response, takes the same arguments as C<url_for>.
638 654
   $c->res->code(301);
639 655
   $c->redirect_to('some_route');
640 656
 
641
-=head2 C<render>
657
+=head2 render
642 658
 
643 659
   my $success = $c->render;
644 660
   my $success = $c->render(controller => 'foo', action => 'bar');
... ...
@@ -652,11 +668,12 @@ Prepare a C<302> redirect response, takes the same arguments as C<url_for>.
652 668
   my $success = $c->render('foo/index');
653 669
   my $output  = $c->render('foo/index', partial => 1);
654 670
 
655
-Render content using L<Mojolicious::Renderer/"render">, if no template is
671
+Render content using L<Mojolicious::Renderer/"render"> and emit
672
+C<after_render> hook unless the result is C<partial>. If no template is
656 673
 provided a default one based on controller and action or route name will be
657
-generated. All additional values get merged into the C<stash>.
674
+generated, all additional values get merged into the C<stash>.
658 675
 
659
-=head2 C<render_data>
676
+=head2 render_data
660 677
 
661 678
   $c->render_data($bytes);
662 679
   $c->render_data($bytes, format => 'png');
... ...
@@ -667,7 +684,7 @@ not be encoded. All additional values get merged into the C<stash>.
667 684
   # Longer version
668 685
   $c->render(data => $bytes);
669 686
 
670
-=head2 C<render_exception>
687
+=head2 render_exception
671 688
 
672 689
   $c->render_exception('Oops!');
673 690
   $c->render_exception(Mojo::Exception->new('Oops!'));
... ...
@@ -675,7 +692,7 @@ not be encoded. All additional values get merged into the C<stash>.
675 692
 Render the exception template C<exception.$mode.$format.*> or
676 693
 C<exception.$format.*> and set the response status code to C<500>.
677 694
 
678
-=head2 C<render_json>
695
+=head2 render_json
679 696
 
680 697
   $c->render_json({foo => 'bar'});
681 698
   $c->render_json([1, 2, -3], status => 201);
... ...
@@ -686,7 +703,7 @@ C<stash>.
686 703
   # Longer version
687 704
   $c->render(json => {foo => 'bar'});
688 705
 
689
-=head2 C<render_later>
706
+=head2 render_later
690 707
 
691 708
   $c = $c->render_later;
692 709
 
... ...
@@ -699,14 +716,14 @@ automatic rendring would result in a response.
699 716
     $c->render(text => 'Delayed by 2 seconds!');
700 717
   });
701 718
 
702
-=head2 C<render_not_found>
719
+=head2 render_not_found
703 720
 
704 721
   $c->render_not_found;
705 722
 
706 723
 Render the not found template C<not_found.$mode.$format.*> or
707 724
 C<not_found.$format.*> and set the response status code to C<404>.
708 725
 
709
-=head2 C<render_partial>
726
+=head2 render_partial
710 727
 
711 728
   my $output = $c->render_partial('menubar');
712 729
   my $output = $c->render_partial('menubar', format => 'txt');
... ...
@@ -717,7 +734,7 @@ Same as C<render> but returns the rendered result.
717 734
   # Longer version
718 735
   my $output = $c->render('menubar', partial => 1);
719 736
 
720
-=head2 C<render_static>
737
+=head2 render_static
721 738
 
722 739
   my $success = $c->render_static('images/logo.png');
723 740
   my $success = $c->render_static('../lib/MyApp.pm');
... ...
@@ -726,7 +743,7 @@ Render a static file using L<Mojolicious::Static/"serve">, usually from the
726 743
 C<public> directories or C<DATA> sections of your application. Note that this
727 744
 method does not protect from traversing to parent directories.
728 745
 
729
-=head2 C<render_text>
746
+=head2 render_text
730 747
 
731 748
   $c->render_text('Hello World!');
732 749
   $c->render_text('Hello World!', layout => 'green');
... ...
@@ -742,15 +759,15 @@ of the response, which is C<text/html;charset=UTF-8> by default.
742 759
   # Render "text/plain" response
743 760
   $c->render_text('Hello World!', format => 'txt');
744 761
 
745
-=head2 C<rendered>
762
+=head2 rendered
746 763
 
747 764
   $c = $c->rendered;
748 765
   $c = $c->rendered(302);
749 766
 
750
-Finalize response and emit C<after_dispatch> plugin hook, defaults to using a
751
-C<200> response code.
767
+Finalize response and emit C<after_dispatch> hook, defaults to using a C<200>
768
+response code.
752 769
 
753
-=head2 C<req>
770
+=head2 req
754 771
 
755 772
   my $req = $c->req;
756 773
 
... ...
@@ -766,7 +783,7 @@ Get L<Mojo::Message::Request> object from L<Mojo::Transaction/"req">.
766 783
   my $foo      = $c->req->json('/23/foo');
767 784
   my $bar      = $c->req->dom('div.bar')->first->text;
768 785
 
769
-=head2 C<res>
786
+=head2 res
770 787
 
771 788
   my $res = $c->res;
772 789
 
... ...
@@ -778,7 +795,7 @@ Get L<Mojo::Message::Response> object from L<Mojo::Transaction/"res">.
778 795
   # Force file download by setting a custom response header
779 796
   $c->res->headers->content_disposition('attachment; filename=foo.png;');
780 797
 
781
-=head2 C<respond_to>
798
+=head2 respond_to
782 799
 
783 800
   $c->respond_to(
784 801
     json => {json => {message => 'Welcome!'}},
... ...
@@ -799,7 +816,7 @@ is set to the value C<XMLHttpRequest>.
799 816
     any  => {data => '', status => 204}
800 817
   );
801 818
 
802
-=head2 C<send>
819
+=head2 send
803 820
 
804 821
   $c = $c->send({binary => $bytes});
805 822
   $c = $c->send({text   => $bytes});
... ...
@@ -810,14 +827,16 @@ is set to the value C<XMLHttpRequest>.
810 827
 Send message or frame non-blocking via WebSocket, the optional drain callback
811 828
 will be invoked once all data has been written.
812 829
 
813
-  # Send "Text" frame
814
-  $c->send('Hello World!');
830
+  # Send "Text" message
831
+  $c->send('I ♥ Mojolicious!');
815 832
 
816
-  # Send JSON object as "Text" frame
817
-  $c->send({text => Mojo::JSON->new->encode({hello => 'world'})});
833
+  # Send JSON object as "Text" message
834
+  use Mojo::JSON 'j';
835
+  $c->send({text => j({test => 'I ♥ Mojolicious!'})});
818 836
 
819
-  # Send JSON object as "Binary" frame
820
-  $c->send({binary => Mojo::JSON->new->encode({hello => 'world'})});
837
+  # Send JSON object as "Binary" message
838
+  use Mojo::JSON 'j';
839
+  $c->send({binary => j({test => 'I ♥ Mojolicious!'})});
821 840
 
822 841
   # Send "Ping" frame
823 842
   $c->send([1, 0, 0, 0, 9, 'Hello World!']);
... ...
@@ -828,7 +847,7 @@ timeout, which usually defaults to C<15> seconds.
828 847
   # Increase inactivity timeout for connection to 300 seconds
829 848
   Mojo::IOLoop->stream($c->tx->connection)->timeout(300);
830 849
 
831
-=head2 C<session>
850
+=head2 session
832 851
 
833 852
   my $session = $c->session;
834 853
   my $foo     = $c->session('foo');
... ...
@@ -853,7 +872,7 @@ usually have a 4096 byte limit, depending on browser.
853 872
   # Delete whole session by setting an expiration date in the past
854 873
   $c->session(expires => 1);
855 874
 
856
-=head2 C<signed_cookie>
875
+=head2 signed_cookie
857 876
 
858 877
   my $value  = $c->signed_cookie('foo');
859 878
   my @values = $c->signed_cookie('foo');
... ...
@@ -864,7 +883,7 @@ Access signed request cookie values and create new signed response cookies.
864 883
 Cookies failing C<HMAC-SHA1> signature verification will be automatically
865 884
 discarded.
866 885
 
867
-=head2 C<stash>
886
+=head2 stash
868 887
 
869 888
   my $stash = $c->stash;
870 889
   my $foo   = $c->stash('foo');
... ...
@@ -883,7 +902,7 @@ that all stash values with a C<mojo.*> prefix are reserved for internal use.
883 902
   my $foo = $c->stash->{foo};
884 903
   delete $c->stash->{foo};
885 904
 
886
-=head2 C<ua>
905
+=head2 ua
887 906
 
888 907
   my $ua = $c->ua;
889 908
 
... ...
@@ -915,7 +934,7 @@ Get L<Mojo::UserAgent> object from L<Mojo/"ua">.
915 934
     });
916 935
   }
917 936
 
918
-=head2 C<url_for>
937
+=head2 url_for
919 938
 
920 939
   my $url = $c->url_for;
921 940
   my $url = $c->url_for(name => 'sebastian');
... ...
@@ -937,12 +956,12 @@ to inherit query parameters from the current request.
937 956
   # "/list?q=mojo&page=2" if current request was for "/list?q=mojo&page=1"
938 957
   $c->url_with->query([page => 2]);
939 958
 
940
-=head2 C<write>
959
+=head2 write
941 960
 
942 961
   $c = $c->write;
943
-  $c = $c->write('Hello!');
962
+  $c = $c->write($bytes);
944 963
   $c = $c->write(sub {...});
945
-  $c = $c->write('Hello!' => sub {...});
964
+  $c = $c->write($bytes => sub {...});
946 965
 
947 966
 Write dynamic content non-blocking, the optional drain callback will be
948 967
 invoked once all data has been written.
... ...
@@ -963,18 +982,18 @@ invoked once all data has been written.
963 982
     });
964 983
   });
965 984
 
966
-For Comet (C<long polling>) you might also want to increase the inactivity
985
+For Comet (long polling) you might also want to increase the inactivity
967 986
 timeout, which usually defaults to C<15> seconds.
968 987
 
969 988
   # Increase inactivity timeout for connection to 300 seconds
970 989
   Mojo::IOLoop->stream($c->tx->connection)->timeout(300);
971 990
 
972
-=head2 C<write_chunk>
991
+=head2 write_chunk
973 992
 
974 993
   $c = $c->write_chunk;
975
-  $c = $c->write_chunk('Hello!');
994
+  $c = $c->write_chunk($bytes);
976 995
   $c = $c->write_chunk(sub {...});
977
-  $c = $c->write_chunk('Hello!' => sub {...});
996
+  $c = $c->write_chunk($bytes => sub {...});
978 997
 
979 998
 Write dynamic content non-blocking with C<chunked> transfer encoding, the
980 999
 optional drain callback will be invoked once all data has been written.
+20 -10
mojolegacy/lib/Mojolicious/Guides.pod
... ...
@@ -20,6 +20,12 @@ available in many formats. Both are excellent introductions to the language.
20 20
 For more books and documentation, check out
21 21
 L<learn.perl.org|http://learn.perl.org/>.
22 22
 
23
+=head1 SCREENCASTS
24
+
25
+Before starting with the tutorial below, you should take a look at the
26
+wonderful L<Mojocasts|http://mojocasts.com/e1>, they will give you a general
27
+overview of what L<Mojolicious> is all about.
28
+
23 29
 =head1 TUTORIAL
24 30
 
25 31
 =over 2
... ...
@@ -90,26 +96,23 @@ Full featured, highly portable non-blocking I/O HTTP and WebSocket server,
90 96
 with self-restart support through L<Mojo::Server::Morbo>, perfect for
91 97
 development and testing.
92 98
 
93
-=item L<Mojo::Server::Hypnotoad>
99
+=item L<Mojo::Server::Prefork>
94 100
 
95 101
 Full featured, UNIX optimized, preforking non-blocking I/O HTTP and WebSocket
96
-server with support for zero downtime software upgrades (hot deployment).
102
+server with support for zero downtime software upgrades (hot deployment)
103
+through L<Mojo::Server::Hypnotoad>.
97 104
 
98 105
 =item L<Mojo::Server::CGI>, L<Mojo::Server::PSGI>
99 106
 
100 107
 Transparent CGI and L<PSGI> support out of the box.
101 108
 
102
-=item L<Mojo::Template>
103
-
104
-Very Perl-ish and minimalistic template system.
105
-
106
-=item L<Mojo::ByteStream>
109
+=item L<Mojo::IOLoop>
107 110
 
108
-Countless portable and very convenient bytestream manipulation methods.
111
+A minimalistic event loop with support for multiple reactor backends.
109 112
 
110
-=item L<Mojolicious::Commands>
113
+=item L<Mojo::Template>
111 114
 
112
-Pluggable command line system and the backbone of the L<mojo> script.
115
+Very Perl-ish and minimalistic template system.
113 116
 
114 117
 =item L<Test::Mojo>
115 118
 
... ...
@@ -126,4 +129,11 @@ Fun oneliners using everything above.
126 129
 A lot more documentation and examples by many different authors can be found
127 130
 in the L<Mojolicious wiki|http://github.com/kraih/mojo/wiki>.
128 131
 
132
+=head1 SUPPORT
133
+
134
+If you have any questions the documentation might not yet answer, don't
135
+hesitate to ask on the
136
+L<mailing-list|http://groups.google.com/group/mojolicious> or the official IRC
137
+channel C<#mojo> on C<irc.perl.org>.
138
+
129 139
 =cut
+8 -3
mojolegacy/lib/Mojolicious/Guides/Contributing.pod
... ...
@@ -164,9 +164,7 @@ feature branches for actual development.
164 164
 Code has to be run through L<Perl::Tidy> with the included C<.perltidyrc>, and
165 165
 everything should look like it was written by a single person.
166 166
 
167
-Code should be organized in blocks and those blocks should be commented.
168
-
169
-No spaghetti code.
167
+Methods and functions should be as short as possible, no spaghetti code.
170 168
 
171 169
 Comments should be correctly capitalized, and funny if possible, punctuation
172 170
 is optional if it doesn't increase readability.
... ...
@@ -185,4 +183,11 @@ You can continue with L<Mojolicious::Guides> now or take a look at the
185 183
 L<Mojolicious wiki|http://github.com/kraih/mojo/wiki>, which contains a lot
186 184
 more documentation and examples by many different authors.
187 185
 
186
+=head1 SUPPORT
187
+
188
+If you have any questions the documentation might not yet answer, don't
189
+hesitate to ask on the
190
+L<mailing-list|http://groups.google.com/group/mojolicious> or the official IRC
191
+channel C<#mojo> on C<irc.perl.org>.
192
+
188 193
 =cut
+33 -27
mojolegacy/lib/Mojolicious/Guides/Cookbook.pod
... ...
@@ -5,7 +5,7 @@ Mojolicious::Guides::Cookbook - Cookbook
5 5
 
6 6
 =head1 OVERVIEW
7 7
 
8
-This document cotains many fun recipes for cooking with L<Mojolicious>.
8
+This document contains many fun recipes for cooking with L<Mojolicious>.
9 9
 
10 10
 =head1 DEPLOYMENT
11 11
 
... ...
@@ -30,13 +30,17 @@ works on.
30 30
   $ ./script/myapp daemon -h
31 31
   ...List of available options...
32 32
 
33
-Another huge advantage is that it supports TLS and WebSockets out of the box.
33
+Another huge advantage is that it supports TLS and WebSockets out of the box,
34
+a development certificate for testing purposes is built right in, so it just
35
+works.
34 36
 
35 37
   $ ./script/myapp daemon -l https://*:3000
36 38
   Server available at https://127.0.0.1:3000.
37 39
 
38
-A development certificate for testing purposes is built right in, so it just
39
-works.
40
+On UNIX platforms you can also add preforking with L<Mojo::Server::Prefork>.
41
+
42
+  $ ./script/myapp prefork
43
+  Server available at http://127.0.0.1:3000.
40 44
 
41 45
 =head2 Morbo
42 46
 
... ...
@@ -65,8 +69,9 @@ multiple CPU cores and copy-on-write.
65 69
   |- Mojo::Server::Daemon [3]
66 70
   +- Mojo::Server::Daemon [4]
67 71
 
68
-It is also based on the L<Mojo::Server::Daemon> web server, but optimized
69
-specifically for production environments out of the box.
72
+It is based on the L<Mojo::Server::Prefork> web server, which adds preforking
73
+to L<Mojo::Server::Daemon>, but optimized specifically for production
74
+environments out of the box.
70 75
 
71 76
   $ hypnotoad script/myapp
72 77
   Server available at http://127.0.0.1:8080.
... ...
@@ -512,6 +517,7 @@ L<Test::Mojo> API to be used.
512 517
   my $t = Test::Mojo->new;
513 518
   $t->websocket_ok('/echo')
514 519
     ->send_ok('Hello Mojo!')
520
+    ->message_ok
515 521
     ->message_is('echo: Hello Mojo!')
516 522
     ->finish_ok;
517 523
 
... ...
@@ -611,10 +617,10 @@ which can be combined to solve some of hardest problems in web development.
611 617
         # Make sure we have the right part and replace "read" event
612 618
         return unless $single->headers->content_disposition =~ /example/;
613 619
         $single->unsubscribe('read')->on(read => sub {
614
-          my ($single, $chunk) = @_;
620
+          my ($single, $bytes) = @_;
615 621
 
616 622
           # Log size of every chunk we receive
617
-          $self->app->log->debug(length($chunk) . ' bytes uploaded.');
623
+          $self->app->log->debug(length($bytes) . ' bytes uploaded.');
618 624
         });
619 625
       });
620 626
     }) unless $self->req->is_finished;
... ...
@@ -734,30 +740,23 @@ sense for a standalone parser.
734 740
   say 'Title: ', $tx->res->dom->at('head > title')->text;
735 741
 
736 742
   # Extract headings
737
-  $tx->res->dom('h1, h2, h3')->each(sub {
738
-    say 'Heading: ', shift->all_text;
739
-  });
743
+  $tx->res->dom('h1, h2, h3')->each(sub { say 'Heading: ', shift->all_text });
740 744
 
741
-  # Recurse through children manually to extract more than just text
742
-  sub text_and_images {
743
-    my $elements = shift;
744
-    for my $e ($elements->each) {
745
+  # Visit all elements recursively to extract more than just text
746
+  for my $e ($tx->res->dom('*')->each) {
745 747
 
746
-      # Text before this element
747
-      print $e->text_before(0);
748
+    # Text before this element
749
+    print $e->text_before(0);
748 750
 
749
-      # Also include alternate text for images
750
-      print $e->{alt} if $e->type eq 'img';
751
+    # Also include alternate text for images
752
+    print $e->{alt} if $e->type eq 'img';
751 753
 
752
-      # Text from children
753
-      my $children = $e->children;
754
-      $children->size ? text_and_images($children) : print $e->text(0);
755
-    }
754
+    # Text for elements without children
755
+    print $e->text(0) unless $e->children->size;
756 756
 
757 757
     # Text after last element
758
-    print $elements->[-1]->text_after(0);
758
+    print $e->text_after(0) unless $e->next;
759 759
   }
760
-  text_and_images($tx->res->dom->children);
761 760
 
762 761
 Especially for unit testing your L<Mojolicious> applications this can be a
763 762
 very powerful tool.
... ...
@@ -834,8 +833,8 @@ L<Mojo::UserAgent> makes it actually easy.
834 833
 
835 834
   # Replace "read" events to disable default content parser
836 835
   $tx->res->content->unsubscribe('read')->on(read => sub {
837
-    my ($content, $chunk) = @_;
838
-    say "Streaming: $chunk";
836
+    my ($content, $bytes) = @_;
837
+    say "Streaming: $bytes";
839 838
   });
840 839
 
841 840
   # Process transaction
... ...
@@ -1179,4 +1178,11 @@ You can continue with L<Mojolicious::Guides> now or take a look at the
1179 1178
 L<Mojolicious wiki|http://github.com/kraih/mojo/wiki>, which contains a lot
1180 1179
 more documentation and examples by many different authors.
1181 1180
 
1181
+=head1 SUPPORT
1182
+
1183
+If you have any questions the documentation might not yet answer, don't
1184
+hesitate to ask on the
1185
+L<mailing-list|http://groups.google.com/group/mojolicious> or the official IRC
1186
+channel C<#mojo> on C<irc.perl.org>.
1187
+
1182 1188
 =cut
+10 -3
mojolegacy/lib/Mojolicious/Guides/FAQ.pod
... ...
@@ -69,9 +69,9 @@ variable to change this value.
69 69
 
70 70
 This is a very similar protection mechanism to the one described in the
71 71
 previous answer, but a little more specific. It limits the maximum length of
72
-any C<\r\n> terminated part of a HTTP message, such as request line, status
73
-line and headers. This limit is around C<10KB> by default, you can use the
74
-C<MOJO_MAX_LINE_SIZE> environment variable to change this value.
72
+any C<\x0d\x0a> terminated part of a HTTP message, such as request line,
73
+status line and headers. This limit is around C<10KB> by default, you can use
74
+the C<MOJO_MAX_LINE_SIZE> environment variable to change this value.
75 75
 
76 76
 =head2 What does the error "Maximum buffer size exceeded" mean?
77 77
 
... ...
@@ -140,4 +140,11 @@ You can continue with L<Mojolicious::Guides> now or take a look at the
140 140
 L<Mojolicious wiki|http://github.com/kraih/mojo/wiki>, which contains a lot
141 141
 more documentation and examples by many different authors.
142 142
 
143
+=head1 SUPPORT
144
+
145
+If you have any questions the documentation might not yet answer, don't
146
+hesitate to ask on the
147
+L<mailing-list|http://groups.google.com/group/mojolicious> or the official IRC
148
+channel C<#mojo> on C<irc.perl.org>.
149
+
143 150
 =cut
+9 -2
mojolegacy/lib/Mojolicious/Guides/Growing.pod
... ...
@@ -551,7 +551,7 @@ allow running unit tests again.
551 551
   use lib 'lib';
552 552
   use Mojolicious::Commands;
553 553
 
554
-  # Start commands for application
554
+  # Start command line interface for application
555 555
   Mojolicious::Commands->start_app('MyApp');
556 556
 
557 557
 =head2 Controller class
... ...
@@ -651,7 +651,7 @@ Only a few small details change.
651 651
   use FindBin;
652 652
   use lib "$FindBin::Bin/../lib";
653 653
 
654
-  # Start commands for application
654
+  # Start command line interface for application
655 655
   require Mojolicious::Commands;
656 656
   Mojolicious::Commands->start_app('MyApp');
657 657
 
... ...
@@ -694,4 +694,11 @@ You can continue with L<Mojolicious::Guides> now or take a look at the
694 694
 L<Mojolicious wiki|http://github.com/kraih/mojo/wiki>, which contains a lot
695 695
 more documentation and examples by many different authors.
696 696
 
697
+=head1 SUPPORT
698
+
699
+If you have any questions the documentation might not yet answer, don't
700
+hesitate to ask on the
701
+L<mailing-list|http://groups.google.com/group/mojolicious> or the official IRC
702
+channel C<#mojo> on C<irc.perl.org>.
703
+
697 704
 =cut
+77 -66
mojolegacy/lib/Mojolicious/Guides/Rendering.pod
... ...
@@ -114,7 +114,8 @@ which is the default to prevent XSS attacks against your application.
114 114
 
115 115
 Only L<Mojo::ByteStream> objects are excluded from automatic escaping.
116 116
 
117
-  <%= Mojo::ByteStream->new('<p>test</p>') %>
117
+  % use Mojo::ByteStream 'b';
118
+  <%= b('<p>test</p>') %>
118 119
 
119 120
 Newline characters can be escaped with a backslash.
120 121
 
... ...
@@ -186,7 +187,7 @@ shortcut.
186 187
 
187 188
 Some renderers such as C<ep> allow templates to be passed inline.
188 189
 
189
-  $self->render(inline => 'The result is <%= 1 + 1%>.');
190
+  $self->render(inline => 'The result is <%= 1 + 1 %>.');
190 191
 
191 192
 Since auto detection depends on a path you might have to supply a C<handler>
192 193
 too.
... ...
@@ -489,7 +490,7 @@ the partial template.
489 490
 =head2 Reusable template blocks
490 491
 
491 492
 It's never fun to repeat yourself, that's why you can build reusable template
492
-blocks in C<ep> that work very similar normal Perl functions.
493
+blocks in C<ep> that work very similar to normal Perl functions.
493 494
 
494 495
   @@ welcome.html.ep
495 496
   <% my $block = begin %>
... ...
@@ -605,14 +606,14 @@ everything.
605 606
 
606 607
   get '/' => sub {
607 608
     my $self = shift;
608
-    $self->debug('action');
609
+    $self->debug('Hello from an action!');
609 610
   } => 'index';
610 611
 
611 612
   app->start;
612 613
   __DATA__
613 614
 
614 615
   @@ index.html.ep
615
-  % debug 'template';
616
+  % debug 'Hello from a template!';
616 617
 
617 618
 Helpers can also accept template blocks as last argument, this for example
618 619
 allows very pleasant to use tag helpers and filters.
... ...
@@ -674,14 +675,14 @@ The C<register> method will be called when you load the plugin.
674 675
 
675 676
   app->start;
676 677
 
677
-A skeleton for a full C<CPAN> compatible plugin distribution can be
678
-automatically generated.
678
+A skeleton for a full CPAN compatible plugin distribution can be automatically
679
+generated.
679 680
 
680 681
   $ mojo generate plugin DebugHelper
681 682
 
682 683
 And if you have a C<PAUSE> account (which can be requested at
683 684
 L<http://pause.perl.org>), you are only a few commands away from relasing it
684
-to C<CPAN>.
685
+to CPAN.
685 686
 
686 687
   $ perl Makefile.PL
687 688
   $ make test
... ...
@@ -692,7 +693,7 @@ to C<CPAN>.
692 693
 =head2 Bundling assets with plugins
693 694
 
694 695
 Assets such as templates and static files can be easily bundled with your
695
-plugins, even if you plan to release them to C<CPAN>.
696
+plugins, even if you plan to release them to CPAN.
696 697
 
697 698
   $ mojo generate plugin AlertAssets
698 699
   $ mkdir AlertAssets/lib/Mojolicious/Plugin/AlertAssets
... ...
@@ -790,10 +791,46 @@ that a response has been generated.
790 791
   $self->res->content->asset(Mojo::Asset::File->new(path => '/etc/passwd'));
791 792
   $self->rendered(200);
792 793
 
794
+=head2 Post-processing dynamic content
795
+
796
+While post-processing tasks are generally very easy with the C<after_dispatch>
797
+hook, for content generated by the renderer it is a lot more efficient to use
798
+C<after_render>.
799
+
800
+  use Mojolicious::Lite;
801
+  use IO::Compress::Gzip 'gzip';
802
+
803
+  hook after_render => sub {
804
+    my ($self, $output, $format) = @_;
805
+
806
+    # Check if "gzip => 1" has been set in the stash
807
+    return unless $self->stash->{gzip};
808
+
809
+    # Check if user agent accepts GZip compression
810
+    return unless ($self->req->headers->accept_encoding // '') =~ /gzip/i;
811
+
812
+    # Compress content with GZip
813
+    $self->res->headers->content_encoding('gzip');
814
+    gzip $output, \my $compressed;
815
+    $$output = $compressed;
816
+  };
817
+
818
+  get '/' => {template => 'hello', title => 'Hello', gzip => 1};
819
+
820
+  app->start;
821
+  __DATA__
822
+
823
+  @@ hello.html.ep
824
+  <!DOCTYPE html>
825
+  <html>
826
+    <head><title><%= title %></title></head>
827
+    <body>Compressed content.</body>
828
+  </html>
829
+
793 830
 =head2 Chunked transfer encoding
794 831
 
795
-For very dynamic content you might not know the response C<Content-Length> in
796
-advance, that's where the C<chunked> C<Transfer-Encoding> comes in handy. A
832
+For very dynamic content you might not know the response content length in
833
+advance, that's where the C<chunked> transfer encoding comes in handy. A
797 834
 common use would be to send the C<head> section of an HTML document to the
798 835
 browser in advance and speed up preloading of referenced images and
799 836
 stylesheets.
... ...
@@ -814,8 +851,8 @@ L<Mojolicious::Controller/"finish"> marks the end of the stream.
814 851
   0
815 852
 
816 853
 Especially in combination with long inactivity timeouts this can be very
817
-useful for Comet (C<long polling>). Due to limitations in some web servers
818
-this might not work perfectly in all deployment environments.
854
+useful for Comet (long polling). Due to limitations in some web servers this
855
+might not work perfectly in all deployment environments.
819 856
 
820 857
 =head2 Encoding
821 858
 
... ...
@@ -893,23 +930,28 @@ L<Mojo::Template> contains the whole list of available options.
893 930
 
894 931
 =head2 Adding your favorite template system
895 932
 
896
-Maybe you would prefer a different template system than C<ep>, all you have to
897
-do is add a new C<handler>.
933
+Maybe you would prefer a different template system than C<ep>, and there is
934
+not already a plugin on CPAN for your favorite one, all you have to do is add
935
+a new C<handler> when C<register> is called.
898 936
 
899
-  use Mojolicious::Lite;
937
+  package Mojolicious::Plugin::MyRenderer;
938
+  use Mojo::Base 'Mojolicious::Plugin';
939
+
940
+  sub register {
941
+    my ($self, $app) = @_;
900 942
 
901
-  app->renderer->add_handler(
902
-    mine => sub {
943
+    # Add "mine" handler
944
+    $app->renderer->add_handler(mine => sub {
903 945
       my ($renderer, $c, $output, $options) = @_;
904 946
 
905
-      # Check for one time use inline template
947
+      # Check for one-time use inline template
906 948
       my $inline = $options->{inline};
907 949
 
908 950
       # Check for absolute template path
909
-      my $path = $r->template_path($options);
951
+      my $path = $renderer->template_path($options);
910 952
 
911 953
       # Check for appropriate template in DATA section
912
-      my $data = $r->get_data_template($options);
954
+      my $data = $renderer->get_data_template($options);
913 955
 
914 956
       # This part is up to you and your template system :)
915 957
       ...
... ...
@@ -922,63 +964,25 @@ do is add a new C<handler>.
922 964
 
923 965
       # And return true if something has been rendered or false otherwise
924 966
       return 1;
925
-    }
926
-  );
927
-
928
-  get '/' => 'index';
929
-
930
-  app->start;
931
-  __DATA__
967
+    });
968
+  }
932 969
 
933
-  @@ index.html.mine
934
-  ...
970
+  1;
935 971
 
936 972
 Since most template systems don't support templates in the C<DATA> section,
937 973
 the renderer provides methods to help you with that.
938 974
 
939
-=head2 Post-processing content
940
-
941
-While post-processing tasks are generally very easy with the C<after_dispatch>
942
-hook, especially for content generated by the renderer, there are a few things
943
-you need to watch out for, such as multipart content, dynamically generated
944
-content, content that is streamed directly from files and content with range
945
-constraints.
946
-
947 975
   use Mojolicious::Lite;
948
-  use IO::Compress::Gzip 'gzip';
949 976
 
950
-  hook after_dispatch => sub {
951
-    my $self = shift;
977
+  plugin 'MyRenderer';
952 978
 
953
-    # Check if "gzip => 1" has been set in the stash
954
-    return unless $self->stash->{gzip};
955
-
956
-    # Check if user agent accepts GZip compression
957
-    return unless ($self->req->headers->accept_encoding // '') =~ /gzip/i;
958
-
959
-    # Check for multipart content or if content will be dynamically generated
960
-    return if $self->res->is_multipart || $self->res->is_dynamic;
961
-
962
-    # Check if content is streamed from a file or has a range constraint
963
-    my $asset = $self->res->content->asset;
964
-    return if $asset->is_file || $asset->is_range;
965
-
966
-    # Compress content
967
-    gzip \(my $dummy = $asset->slurp), \my $compressed;
968
-    $self->res->body($compressed)->headers->content_encoding('gzip');
969
-  };
970
-
971
-  get '/' => {template => 'hello', title => 'Hello', gzip => 1};
979
+  get '/' => 'index';
972 980
 
973 981
   app->start;
974 982
   __DATA__
975 983
 
976
-  @@ hello.html.ep
977
-  <!DOCTYPE html>
978
-  <html>
979
-    <head><title><%= title %></title></head>
980
-    <body>Compressed content.</body>
981
-  </html>
984
+  @@ index.html.mine
985
+  ...
982 986
 
983 987
 =head1 MORE
984 988
 
... ...
@@ -986,4 +990,11 @@ You can continue with L<Mojolicious::Guides> now or take a look at the
986 990
 L<Mojolicious wiki|http://github.com/kraih/mojo/wiki>, which contains a lot
987 991
 more documentation and examples by many different authors.
988 992
 
993
+=head1 SUPPORT
994
+
995
+If you have any questions the documentation might not yet answer, don't
996
+hesitate to ask on the
997
+L<mailing-list|http://groups.google.com/group/mojolicious> or the official IRC
998
+channel C<#mojo> on C<irc.perl.org>.
999
+
989 1000
 =cut
+16 -12
mojolegacy/lib/Mojolicious/Guides/Routing.pod
... ...
@@ -623,10 +623,9 @@ Post-processing tasks such as setting additional response headers are a very
623 623
 common use.
624 624
 
625 625
   # Make sure static files are cached
626
-  $self->hook(after_static_dispatch => sub {
626
+  $self->hook(after_static => sub {
627 627
     my $self = shift;
628
-    $self->res->headers->cache_control('max-age=3600, must-revalidate')
629
-      if $self->res->code;
628
+    $self->res->headers->cache_control('max-age=3600, must-revalidate');
630 629
   });
631 630
 
632 631
 Same for monitoring tasks.
... ...
@@ -746,17 +745,15 @@ You can also package your conditions as reusable plugins.
746 745
     my ($self, $app) = @_;
747 746
 
748 747
     # Add "werewolf" condition
749
-    $app->routes->add_condition(
750
-      werewolf => sub {
751
-        my ($route, $c, $captures, $days) = @_;
748
+    $app->routes->add_condition(werewolf => sub {
749
+      my ($route, $c, $captures, $days) = @_;
752 750
 
753
-        # Keep the werewolfs out!
754
-        return undef if abs(14 - (phase(time))[2]) > ($days / 2);
751
+      # Keep the werewolfs out!
752
+      return undef if abs(14 - (phase(time))[2]) > ($days / 2);
755 753
 
756
-        # It's ok, no werewolf
757
-        return 1;
758
-      }
759
-    );
754
+      # It's ok, no werewolf
755
+      return 1;
756
+    });
760 757
   }
761 758
 
762 759
   1;
... ...
@@ -885,4 +882,11 @@ You can continue with L<Mojolicious::Guides> now or take a look at the
885 882
 L<Mojolicious wiki|http://github.com/kraih/mojo/wiki>, which contains a lot
886 883
 more documentation and examples by many different authors.
887 884
 
885
+=head1 SUPPORT
886
+
887
+If you have any questions the documentation might not yet answer, don't
888
+hesitate to ask on the
889
+L<mailing-list|http://groups.google.com/group/mojolicious> or the official IRC
890
+channel C<#mojo> on C<irc.perl.org>.
891
+
888 892
 =cut
+34 -29
mojolegacy/lib/Mojolicious/Lite.pm
... ...
@@ -2,50 +2,55 @@ package Mojolicious::Lite;
2 2
 use Mojo::Base 'Mojolicious';
3 3
 
4 4
 # "Bender: Bite my shiny metal ass!"
5
-use File::Basename 'dirname';
5
+use File::Basename qw(basename dirname);
6 6
 use File::Spec::Functions 'catdir';
7 7
 use Mojo::UserAgent;
8 8
 use Mojo::Util 'monkey_patch';
9 9
 
10 10
 sub import {
11
-  my $class = shift;
12 11
 
13
-  # Executable
12
+  # Remember executable for later
14 13
   $ENV{MOJO_EXE} ||= (caller)[1];
15 14
 
16
-  # Home
17
-  local $ENV{MOJO_HOME} = catdir(split '/', dirname($ENV{MOJO_EXE}))
15
+  # Reuse home directory if possible
16
+  local $ENV{MOJO_HOME} = catdir(split '/', dirname $ENV{MOJO_EXE})
18 17
     unless $ENV{MOJO_HOME};
19 18
 
20
-  # Initialize app
19
+  # Initialize application class
21 20
   my $caller = caller;
22 21
   no strict 'refs';
23 22
   push @{"${caller}::ISA"}, 'Mojo';
24
-  my $app = $class->new;
23
+  my $app = shift->new;
25 24
 
26
-  # Initialize routes
25
+  # Generate moniker based on filename
26
+  my $moniker = basename $ENV{MOJO_EXE};
27
+  $moniker =~ s/\.(?:pl|pm|t)$//i;
28
+  $app->moniker($moniker);
29
+
30
+  # Initialize routes without namespaces
27 31
   my $routes = $app->routes->namespaces([]);
28 32
 
29 33
   # Default static and template class
30 34
   $app->static->classes->[0] = $app->renderer->classes->[0] = $caller;
31 35
 
32
-  # Export
36
+  # The Mojolicious::Lite DSL
33 37
   my $root = $routes;
34 38
   for my $name (qw(any get options patch post put websocket)) {
35 39
     monkey_patch $caller, $name, sub { $routes->$name(@_) };
36 40
   }
37 41
   monkey_patch $caller, $_, sub {$app}
38 42
     for qw(new app);
39
-  monkey_patch $caller, 'del', sub { $routes->delete(@_) };
40
-  monkey_patch $caller, 'group', sub (&) {
43
+  monkey_patch $caller, del => sub { $routes->delete(@_) };
44
+  monkey_patch $caller, group => sub (&) {
41 45
     my $old = $root;
42 46
     $_[0]->($root = $routes);
43 47
     ($routes, $root) = ($root, $old);
44 48
   };
45
-  monkey_patch $caller, 'helper', sub { $app->helper(@_) };
46
-  monkey_patch $caller, 'hook',   sub { $app->hook(@_) };
47
-  monkey_patch $caller, 'plugin', sub { $app->plugin(@_) };
48
-  monkey_patch $caller, 'under',  sub { $routes = $root->under(@_) };
49
+  monkey_patch $caller,
50
+    helper => sub { $app->helper(@_) },
51
+    hook   => sub { $app->hook(@_) },
52
+    plugin => sub { $app->plugin(@_) },
53
+    under  => sub { $routes = $root->under(@_) };
49 54
 
50 55
   # Make sure there's a default application for testing
51 56
   Mojo::UserAgent->app($app) unless Mojo::UserAgent->app;
... ...
@@ -929,7 +934,7 @@ fun!
929 934
 
930 935
 L<Mojolicious::Lite> implements the following functions.
931 936
 
932
-=head2 C<any>
937
+=head2 any
933 938
 
934 939
   my $route = any '/:foo' => sub {...};
935 940
   my $route = any [qw(GET POST)] => '/:foo' => sub {...};
... ...
@@ -938,45 +943,45 @@ Generate route with L<Mojolicious::Routes::Route/"any">, matching any of the
938 943
 listed HTTP request methods or all. See also the tutorial above for more
939 944
 argument variations.
940 945
 
941
-=head2 C<app>
946
+=head2 app
942 947
 
943 948
   my $app = app;
944 949
 
945 950
 The L<Mojolicious::Lite> application.
946 951
 
947
-=head2 C<del>
952
+=head2 del
948 953
 
949 954
   my $route = del '/:foo' => sub {...};
950 955
 
951 956
 Generate route with L<Mojolicious::Routes::Route/"delete">, matching only
952 957
 C<DELETE> requests. See also the tutorial above for more argument variations.
953 958
 
954
-=head2 C<get>
959
+=head2 get
955 960
 
956 961
   my $route = get '/:foo' => sub {...};
957 962
 
958 963
 Generate route with L<Mojolicious::Routes::Route/"get">, matching only C<GET>
959 964
 requests. See also the tutorial above for more argument variations.
960 965
 
961
-=head2 C<group>
966
+=head2 group
962 967
 
963 968
   group {...};
964 969
 
965 970
 Start a new route group.
966 971
 
967
-=head2 C<helper>
972
+=head2 helper
968 973
 
969 974
   helper foo => sub {...};
970 975
 
971 976
 Add a new helper with L<Mojolicious/"helper">.
972 977
 
973
-=head2 C<hook>
978
+=head2 hook
974 979
 
975 980
   hook after_dispatch => sub {...};
976 981
 
977 982
 Share code with L<Mojolicious/"hook">.
978 983
 
979
-=head2 C<options>
984
+=head2 options
980 985
 
981 986
   my $route = options '/:foo' => sub {...};
982 987
 
... ...
@@ -984,34 +989,34 @@ Generate route with L<Mojolicious::Routes::Route/"options">, matching only
984 989
 C<OPTIONS> requests. See also the tutorial above for more argument
985 990
 variations.
986 991
 
987
-=head2 C<patch>
992
+=head2 patch
988 993
 
989 994
   my $route = patch '/:foo' => sub {...};
990 995
 
991 996
 Generate route with L<Mojolicious::Routes::Route/"patch">, matching only
992 997
 C<PATCH> requests. See also the tutorial above for more argument variations.
993 998
 
994
-=head2 C<plugin>
999
+=head2 plugin
995 1000
 
996 1001
   plugin SomePlugin => {foo => 23};
997 1002
 
998 1003
 Load a plugin with L<Mojolicious/"plugin">.
999 1004
 
1000
-=head2 C<post>
1005
+=head2 post
1001 1006
 
1002 1007
   my $route = post '/:foo' => sub {...};
1003 1008
 
1004 1009
 Generate route with L<Mojolicious::Routes::Route/"post">, matching only
1005 1010
 C<POST> requests. See also the tutorial above for more argument variations.
1006 1011
 
1007
-=head2 C<put>
1012
+=head2 put
1008 1013
 
1009 1014
   my $route = put '/:foo' => sub {...};
1010 1015
 
1011 1016
 Generate route with L<Mojolicious::Routes::Route/"put">, matching only C<PUT>
1012 1017
 requests. See also the tutorial above for more argument variations.
1013 1018
 
1014
-=head2 C<under>
1019
+=head2 under
1015 1020
 
1016 1021
   my $route = under sub {...};
1017 1022
   my $route = under '/:foo';
... ...
@@ -1020,7 +1025,7 @@ Generate bridge route with L<Mojolicious::Routes::Route/"under">, to which all
1020 1025
 following routes are automatically appended. See also the tutorial above for
1021 1026
 more argument variations.
1022 1027
 
1023
-=head2 C<websocket>
1028
+=head2 websocket
1024 1029
 
1025 1030
   my $route = websocket '/:foo' => sub {...};
1026 1031
 
+1 -1
mojolegacy/lib/Mojolicious/Plugin.pm
... ...
@@ -32,7 +32,7 @@ L<Mojolicious::Plugin> is an abstract base class for L<Mojolicious> plugins.
32 32
 L<Mojolicious::Plugin> inherits all methods from L<Mojo::Base> and implements
33 33
 the following new ones.
34 34
 
35
-=head2 C<register>
35
+=head2 register
36 36
 
37 37
   $plugin->register(Mojolicious->new);
38 38
   $plugin->register(Mojolicious->new, {foo => 'bar'});
+3 -4
mojolegacy/lib/Mojolicious/Plugin/Charset.pm
... ...
@@ -4,7 +4,6 @@ use Mojo::Base 'Mojolicious::Plugin';
4 4
 sub register {
5 5
   my ($self, $app, $conf) = @_;
6 6
 
7
-  # Change default charset on all layers
8 7
   return unless my $c = $conf->{charset};
9 8
   $app->types->type(html => "text/html;charset=$c");
10 9
   $app->renderer->encoding($c);
... ...
@@ -38,7 +37,7 @@ you're welcome to fork it.
38 37
 
39 38
 L<Mojolicious::Plugin::Charset> supports the following options.
40 39
 
41
-=head2 C<charset>
40
+=head2 charset
42 41
 
43 42
   # Mojolicious::Lite
44 43
   plugin Charset => {charset => 'Shift_JIS'};
... ...
@@ -50,11 +49,11 @@ Application charset.
50 49
 L<Mojolicious::Plugin::Charset> inherits all methods from
51 50
 L<Mojolicious::Plugin> and implements the following new ones.
52 51
 
53
-=head2 C<register>
52
+=head2 register
54 53
 
55 54
   $plugin->register(Mojolicious->new, {charset => 'Shift_JIS'});
56 55
 
57
-Register plugin hooks in L<Mojolicious> application.
56
+Register hooks in L<Mojolicious> application.
58 57
 
59 58
 =head1 SEE ALSO
60 59
 
+10 -29
mojolegacy/lib/Mojolicious/Plugin/Config.pm
... ...
@@ -1,21 +1,13 @@
1 1
 package Mojolicious::Plugin::Config;
2 2
 use Mojo::Base 'Mojolicious::Plugin';
3 3
 
4
-use File::Basename 'basename';
5 4
 use File::Spec::Functions 'file_name_is_absolute';
6
-use Mojo::Util 'decamelize';
5
+use Mojo::Util qw(decode slurp);
7 6
 
8 7
 sub load {
9 8
   my ($self, $file, $conf, $app) = @_;
10 9
   $app->log->debug(qq{Reading config file "$file".});
11
-
12
-  # Slurp UTF-8 file
13
-  open my $handle, "<:encoding(UTF-8)", $file
14
-    or die qq{Couldn't open config file "$file": $!};
15
-  my $content = do { local $/; <$handle> };
16
-
17
-  # Process
18
-  return $self->parse($content, $file, $conf, $app);
10
+  return $self->parse(decode('UTF-8', slurp $file), $file, $conf, $app);
19 11
 }
20 12
 
21 13
 sub parse {
... ...
@@ -36,21 +28,11 @@ sub register {
36 28
 
37 29
   # Config file
38 30
   my $file = $conf->{file} || $ENV{MOJO_CONFIG};
39
-  unless ($file) {
40
-
41
-    # Class or executable
42
-    $file
43
-      = $ENV{MOJO_APP} ? decamelize($ENV{MOJO_APP}) : basename($ENV{MOJO_EXE});
44
-
45
-    # Replace ".pl" and ".t" with default extension
46
-    $file =~ s/\.(?:pl|t)$//i;
47
-    $file .= '.' . ($conf->{ext} || 'conf');
48
-  }
31
+  $file ||= $app->moniker . '.' . ($conf->{ext} || 'conf');
49 32
 
50 33
   # Mode specific config file
51 34
   my $mode = $file =~ /^(.*)\.([^.]+)$/ ? join('.', $1, $app->mode, $2) : '';
52 35
 
53
-  # Absolute paths
54 36
   my $home = $app->home;
55 37
   $file = $home->rel_file($file) unless file_name_is_absolute $file;
56 38
   $mode = $home->rel_file($mode) if $mode && !file_name_is_absolute $mode;
... ...
@@ -111,8 +93,7 @@ The application object can be accessed via C<$app> or the C<app> function,
111 93
 L<strict>, L<warnings>, L<utf8> and Perl 5.10 features are automatically
112 94
 enabled. You can extend the normal configuration file C<myapp.conf> with
113 95
 C<mode> specific ones like C<myapp.$mode.conf>. A default configuration
114
-filename will be generated by decamelizing the application class with
115
-L<Mojo::Util/"decamelize"> or from the application filename.
96
+filename will be generated from the value of L<Mojolicious/"moniker">.
116 97
 
117 98
 The code of this plugin is a good example for learning to build new plugins,
118 99
 you're welcome to fork it.
... ...
@@ -121,21 +102,21 @@ you're welcome to fork it.
121 102
 
122 103
 L<Mojolicious::Plugin::Config> supports the following options.
123 104
 
124
-=head2 C<default>
105
+=head2 default
125 106
 
126 107
   # Mojolicious::Lite
127 108
   plugin Config => {default => {foo => 'bar'}};
128 109
 
129 110
 Default configuration, making configuration files optional.
130 111
 
131
-=head2 C<ext>
112
+=head2 ext
132 113
 
133 114
   # Mojolicious::Lite
134 115
   plugin Config => {ext => 'stuff'};
135 116
 
136 117
 File extension for generated configuration filenames, defaults to C<conf>.
137 118
 
138
-=head2 C<file>
119
+=head2 file
139 120
 
140 121
   # Mojolicious::Lite
141 122
   plugin Config => {file => 'myapp.conf'};
... ...
@@ -149,7 +130,7 @@ environment variable or C<myapp.conf> in the application home directory.
149 130
 L<Mojolicious::Plugin::Config> inherits all methods from
150 131
 L<Mojolicious::Plugin> and implements the following new ones.
151 132
 
152
-=head2 C<load>
133
+=head2 load
153 134
 
154 135
   $plugin->load($file, $conf, $app);
155 136
 
... ...
@@ -161,7 +142,7 @@ Loads configuration file and passes the content to C<parse>.
161 142
     return $self->parse($content, $file, $conf, $app);
162 143
   }
163 144
 
164
-=head2 C<parse>
145
+=head2 parse
165 146
 
166 147
   $plugin->parse($content, $file, $conf, $app);
167 148
 
... ...
@@ -173,7 +154,7 @@ Parse configuration file.
173 154
     return $hash;
174 155
   }
175 156
 
176
-=head2 C<register>
157
+=head2 register
177 158
 
178 159
   my $config = $plugin->register(Mojolicious->new);
179 160
   my $config = $plugin->register(Mojolicious->new, {file => '/etc/app.conf'});
+22 -35
mojolegacy/lib/Mojolicious/Plugin/DefaultHelpers.pm
... ...
@@ -25,25 +25,13 @@ sub register {
25 25
     );
26 26
   }
27 27
 
28
-  # Add "config" helper
29 28
   $app->helper(config => sub { shift->app->config(@_) });
30
-
31
-  # Add "content" helper
32
-  $app->helper(content => \&_content);
33
-
34
-  # Add "content_for" helper
35
-  $app->helper(content_for => \&_content_for);
36
-
37
-  # Add "current_route" helper
29
+  $app->helper(content       => \&_content);
30
+  $app->helper(content_for   => \&_content_for);
38 31
   $app->helper(current_route => \&_current_route);
32
+  $app->helper(dumper        => \&_dumper);
33
+  $app->helper(include       => \&_include);
39 34
 
40
-  # Add "dumper" helper
41
-  $app->helper(dumper => \&_dumper);
42
-
43
-  # Add "include" helper
44
-  $app->helper(include => \&_include);
45
-
46
-  # Add "memorize" helper
47 35
   my %mem;
48 36
   $app->helper(
49 37
     memorize => sub {
... ...
@@ -77,7 +65,6 @@ sub register {
77 65
     }
78 66
   );
79 67
 
80
-  # Add "url_with" helper
81 68
   $app->helper(url_with => \&_url_with);
82 69
 }
83 70
 
... ...
@@ -157,19 +144,19 @@ example for learning to build new plugins, you're welcome to fork it.
157 144
 
158 145
 L<Mojolicious::Plugin::DefaultHelpers> implements the following helpers.
159 146
 
160
-=head2 C<app>
147
+=head2 app
161 148
 
162 149
   %= app->secret
163 150
 
164 151
 Alias for L<Mojolicious::Controller/"app">.
165 152
 
166
-=head2 C<config>
153
+=head2 config
167 154
 
168 155
   %= config 'something'
169 156
 
170 157
 Alias for L<Mojo/"config">.
171 158
 
172
-=head2 C<content>
159
+=head2 content
173 160
 
174 161
   %= content foo => begin
175 162
     test
... ...
@@ -181,7 +168,7 @@ Alias for L<Mojo/"config">.
181 168
 
182 169
 Store partial rendered content in named buffer and retrieve it.
183 170
 
184
-=head2 C<content_for>
171
+=head2 content_for
185 172
 
186 173
   % content_for foo => begin
187 174
     test
... ...
@@ -198,7 +185,7 @@ Append partial rendered content to named buffer and retrieve it.
198 185
   % end
199 186
   %= content_for 'message'
200 187
 
201
-=head2 C<current_route>
188
+=head2 current_route
202 189
 
203 190
   % if (current_route 'login') {
204 191
     Welcome to Mojolicious!
... ...
@@ -207,26 +194,26 @@ Append partial rendered content to named buffer and retrieve it.
207 194
 
208 195
 Check or get name of current route.
209 196
 
210
-=head2 C<dumper>
197
+=head2 dumper
211 198
 
212 199
   %= dumper {some => 'data'}
213 200
 
214 201
 Dump a Perl data structure with L<Data::Dumper>.
215 202
 
216
-=head2 C<extends>
203
+=head2 extends
217 204
 
218 205
   % extends 'blue';
219 206
   % extends 'blue', title => 'Blue!';
220 207
 
221 208
 Extend a template. All additional values get merged into the C<stash>.
222 209
 
223
-=head2 C<flash>
210
+=head2 flash
224 211
 
225 212
   %= flash 'foo'
226 213
 
227 214
 Alias for L<Mojolicious::Controller/"flash">.
228 215
 
229
-=head2 C<include>
216
+=head2 include
230 217
 
231 218
   %= include 'menubar'
232 219
   %= include 'menubar', format => 'txt'
... ...
@@ -234,7 +221,7 @@ Alias for L<Mojolicious::Controller/"flash">.
234 221
 Include a partial template, all arguments get localized automatically and are
235 222
 only available in the partial template.
236 223
 
237
-=head2 C<layout>
224
+=head2 layout
238 225
 
239 226
   % layout 'green';
240 227
   % layout 'green', title => 'Green!';
... ...
@@ -242,7 +229,7 @@ only available in the partial template.
242 229
 Render this template with a layout. All additional values get merged into the
243 230
 C<stash>.
244 231
 
245
-=head2 C<memorize>
232
+=head2 memorize
246 233
 
247 234
   %= memorize begin
248 235
     %= time
... ...
@@ -259,19 +246,19 @@ C<stash>.
259 246
 
260 247
 Memorize block result in memory and prevent future execution.
261 248
 
262
-=head2 C<param>
249
+=head2 param
263 250
 
264 251
   %= param 'foo'
265 252
 
266 253
 Alias for L<Mojolicious::Controller/"param">.
267 254
 
268
-=head2 C<session>
255
+=head2 session
269 256
 
270 257
   %= session 'foo'
271 258
 
272 259
 Alias for L<Mojolicious::Controller/"session">.
273 260
 
274
-=head2 C<stash>
261
+=head2 stash
275 262
 
276 263
   %= stash 'foo'
277 264
   % stash foo => 'bar';
... ...
@@ -280,7 +267,7 @@ Alias for L<Mojolicious::Controller/"stash">.
280 267
 
281 268
   %= stash 'name' // 'Somebody'
282 269
 
283
-=head2 C<title>
270
+=head2 title
284 271
 
285 272
   % title 'Welcome!';
286 273
   % title 'Welcome!', foo => 'bar';
... ...
@@ -288,13 +275,13 @@ Alias for L<Mojolicious::Controller/"stash">.
288 275
 
289 276
 Page title. All additional values get merged into the C<stash>.
290 277
 
291
-=head2 C<url_for>
278
+=head2 url_for
292 279
 
293 280
   %= url_for 'named', controller => 'bar', action => 'baz'
294 281
 
295 282
 Alias for L<Mojolicious::Controller/"url_for">.
296 283
 
297
-=head2 C<url_with>
284
+=head2 url_with
298 285
 
299 286
   %= url_with 'named', controller => 'bar', action => 'baz'
300 287
 
... ...
@@ -308,7 +295,7 @@ request.
308 295
 L<Mojolicious::Plugin::DefaultHelpers> inherits all methods from
309 296
 L<Mojolicious::Plugin> and implements the following new ones.
310 297
 
311
-=head2 C<register>
298
+=head2 register
312 299
 
313 300
   $plugin->register(Mojolicious->new);
314 301
 
+2 -7
mojolegacy/lib/Mojolicious/Plugin/EPLRenderer.pm
... ...
@@ -4,12 +4,7 @@ use Mojo::Base 'Mojolicious::Plugin';
4 4
 use Mojo::Template;
5 5
 use Mojo::Util qw(encode md5_sum);
6 6
 
7
-sub register {
8
-  my ($self, $app) = @_;
9
-
10
-  # Add "epl" handler
11
-  $app->renderer->add_handler(epl => \&_epl);
12
-}
7
+sub register { $_[1]->renderer->add_handler(epl => \&_epl) }
13 8
 
14 9
 sub _epl {
15 10
   my ($renderer, $c, $output, $options) = @_;
... ...
@@ -96,7 +91,7 @@ example for learning to build new plugins, you're welcome to fork it.
96 91
 L<Mojolicious::Plugin::EPLRenderer> inherits all methods from
97 92
 L<Mojolicious::Plugin> and implements the following new ones.
98 93
 
99
-=head2 C<register>
94
+=head2 register
100 95
 
101 96
   $plugin->register(Mojolicious->new);
102 97
 
+6 -9
mojolegacy/lib/Mojolicious/Plugin/EPRenderer.pm
... ...
@@ -11,8 +11,8 @@ sub register {
11 11
   # Auto escape by default to prevent XSS attacks
12 12
   my $template = {auto_escape => 1, %{$conf->{template} || {}}};
13 13
 
14
-  # Add "ep" handler
15
-  $app->renderer->add_handler(
14
+  # Add "ep" handler and make it the default
15
+  $app->renderer->default_handler('ep')->add_handler(
16 16
     $conf->{name} || 'ep' => sub {
17 17
       my ($renderer, $c, $output, $options) = @_;
18 18
 
... ...
@@ -39,7 +39,7 @@ sub register {
39 39
         # Be less relaxed for everything else
40 40
         $prepend .= 'use strict;';
41 41
 
42
-        # Stash
42
+        # Stash values
43 43
         $prepend .= 'my $_S = $self->stash;';
44 44
         $prepend .= " my \$$_ = \$_S->{'$_'};"
45 45
           for grep {/^\w+$/} keys %{$c->stash};
... ...
@@ -52,9 +52,6 @@ sub register {
52 52
       return $renderer->handlers->{epl}->($renderer, $c, $output, $options);
53 53
     }
54 54
   );
55
-
56
-  # Set default handler
57
-  $app->renderer->default_handler('ep');
58 55
 }
59 56
 
60 57
 1;
... ...
@@ -92,14 +89,14 @@ example for learning to build new plugins, you're welcome to fork it.
92 89
 
93 90
 L<Mojolicious::Plugin::EPRenderer> supports the following options.
94 91
 
95
-=head2 C<name>
92
+=head2 name
96 93
 
97 94
   # Mojolicious::Lite
98 95
   plugin EPRenderer => {name => 'foo'};
99 96
 
100 97
 Handler name, defaults to C<ep>.
101 98
 
102
-=head2 C<template>
99
+=head2 template
103 100
 
104 101
   # Mojolicious::Lite
105 102
   plugin EPRenderer => {template => {line_start => '.'}};
... ...
@@ -111,7 +108,7 @@ Attribute values passed to L<Mojo::Template> object used to render templates.
111 108
 L<Mojolicious::Plugin::EPRenderer> inherits all methods from
112 109
 L<Mojolicious::Plugin> and implements the following new ones.
113 110
 
114
-=head2 C<register>
111
+=head2 register
115 112
 
116 113
   $plugin->register(Mojolicious->new);
117 114
   $plugin->register(Mojolicious->new, {name => 'foo'});
+1 -6
mojolegacy/lib/Mojolicious/Plugin/HeaderCondition.pm
... ...
@@ -4,14 +4,9 @@ use Mojo::Base 'Mojolicious::Plugin';
4 4
 sub register {
5 5
   my ($self, $app) = @_;
6 6
 
7
-  # "headers" condition
8 7
   $app->routes->add_condition(headers => \&_headers);
9
-
10
-  # "agent" condition
11 8
   $app->routes->add_condition(
12 9
     agent => sub { _headers(@_[0 .. 2], {'User-Agent' => $_[3]}) });
13
-
14
-  # "host" condition
15 10
   $app->routes->add_condition(
16 11
     host => sub { _check($_[1]->req->url->to_abs->host, $_[3]) });
17 12
 }
... ...
@@ -77,7 +72,7 @@ example for learning to build new plugins, you're welcome to fork it.
77 72
 L<Mojolicious::Plugin::HeaderCondition> inherits all methods from
78 73
 L<Mojolicious::Plugin> and implements the following new ones.
79 74
 
80
-=head2 C<register>
75
+=head2 register
81 76
 
82 77
   $plugin->register(Mojolicious->new);
83 78
 
+7 -12
mojolegacy/lib/Mojolicious/Plugin/JSONConfig.pm
... ...
@@ -8,12 +8,8 @@ use Mojo::Util 'encode';
8 8
 sub parse {
9 9
   my ($self, $content, $file, $conf, $app) = @_;
10 10
 
11
-  # Render
12
-  $content = $self->render($content, $file, $conf, $app);
13
-
14
-  # Parse
15 11
   my $json   = Mojo::JSON->new;
16
-  my $config = $json->decode($content);
12
+  my $config = $json->decode($self->render($content, $file, $conf, $app));
17 13
   my $err    = $json->error;
18 14
   die qq{Couldn't parse config "$file": $err} if !$config && $err;
19 15
   die qq{Invalid config "$file".} if !$config || ref $config ne 'HASH';
... ...
@@ -30,7 +26,7 @@ sub render {
30 26
   my $prepend = q[my $app = shift; no strict 'refs'; no warnings 'redefine';];
31 27
   $prepend .= q[sub app; *app = sub { $app }; use Mojo::Base -strict;];
32 28
 
33
-  # Render
29
+  # Render and encode for JSON decoding
34 30
   my $mt = Mojo::Template->new($conf->{template} || {})->name($file);
35 31
   my $json = $mt->prepend($prepend . $mt->prepend)->render($content, $app);
36 32
   return ref $json ? die $json : encode 'UTF-8', $json;
... ...
@@ -73,8 +69,7 @@ preprocesses its input with L<Mojo::Template>.
73 69
 The application object can be accessed via C<$app> or the C<app> function. You
74 70
 can extend the normal config file C<myapp.json> with C<mode> specific ones
75 71
 like C<myapp.$mode.json>. A default configuration filename will be generated
76
-by decamelizing the application class with L<Mojo::Util/"decamelize"> or from
77
-the application filename.
72
+from the value of L<Mojolicious/"moniker">.
78 73
 
79 74
 The code of this plugin is a good example for learning to build new plugins,
80 75
 you're welcome to fork it.
... ...
@@ -84,7 +79,7 @@ you're welcome to fork it.
84 79
 L<Mojolicious::Plugin::JSONConfig> inherits all options from
85 80
 L<Mojolicious::Plugin::Config> and supports the following new ones.
86 81
 
87
-=head2 C<template>
82
+=head2 template
88 83
 
89 84
   # Mojolicious::Lite
90 85
   plugin JSONConfig => {template => {line_start => '.'}};
... ...
@@ -97,7 +92,7 @@ configuration files.
97 92
 L<Mojolicious::Plugin::JSONConfig> inherits all methods from
98 93
 L<Mojolicious::Plugin::Config> and implements the following new ones.
99 94
 
100
-=head2 C<parse>
95
+=head2 parse
101 96
 
102 97
   $plugin->parse($content, $file, $conf, $app);
103 98
 
... ...
@@ -111,14 +106,14 @@ Process content with C<render> and parse it with L<Mojo::JSON>.
111 106
     return $hash;
112 107
   }
113 108
 
114
-=head2 C<register>
109
+=head2 register
115 110
 
116 111
   my $config = $plugin->register(Mojolicious->new);
117 112
   my $config = $plugin->register(Mojolicious->new, {file => '/etc/foo.conf'});
118 113
 
119 114
 Register plugin in L<Mojolicious> application.
120 115
 
121
-=head2 C<render>
116
+=head2 render
122 117
 
123 118
   $plugin->render($content, $file, $conf, $app);
124 119
 
+1 -3
mojolegacy/lib/Mojolicious/Plugin/Mount.pm
... ...
@@ -6,7 +6,6 @@ use Mojo::Server;
6 6
 sub register {
7 7
   my ($self, $app, $conf) = @_;
8 8
 
9
-  # Load application
10 9
   my $path  = (keys %$conf)[0];
11 10
   my $embed = Mojo::Server->new->load_app($conf->{$path});
12 11
 
... ...
@@ -17,7 +16,6 @@ sub register {
17 16
     $path = $3;
18 17
   }
19 18
 
20
-  # Generate route
21 19
   my $route = $app->routes->route($path)->detour(app => $embed);
22 20
   $route->over(host => $host) if $host;
23 21
 
... ...
@@ -64,7 +62,7 @@ you're welcome to fork it.
64 62
 L<Mojolicious::Plugin::Mount> inherits all methods from L<Mojolicious::Plugin>
65 63
 and implements the following new ones.
66 64
 
67
-=head2 C<register>
65
+=head2 register
68 66
 
69 67
   my $route = $plugin->register(Mojolicious->new, {'/foo' => '/some/app.pl'});
70 68
 
+8 -15
mojolegacy/lib/Mojolicious/Plugin/PODRenderer.pm
... ...
@@ -8,13 +8,12 @@ use Mojo::Util 'url_escape';
8 8
 BEGIN {eval {require Pod::Simple::HTML; import Pod::Simple::HTML}}
9 9
 BEGIN {eval {require Pod::Simple::Search; import Pod::Simple::Search}}
10 10
 
11
-# Paths
11
+# Paths to search
12 12
 my @PATHS = map { $_, "$_/pods" } @INC;
13 13
 
14 14
 sub register {
15 15
   my ($self, $app, $conf) = @_;
16 16
 
17
-  # Add "pod" handler
18 17
   my $preprocess = $conf->{preprocess} || 'ep';
19 18
   $app->renderer->add_handler(
20 19
     $conf->{name} || 'pod' => sub {
... ...
@@ -28,10 +27,9 @@ sub register {
28 27
     }
29 28
   );
30 29
 
31
-  # Add "pod_to_html" helper
32 30
   $app->helper(pod_to_html => sub { shift; b(_pod_to_html(@_)) });
33 31
 
34
-  # Perldoc
32
+  # Perldoc browser
35 33
   return if $conf->{no_perldoc};
36 34
   return $app->routes->any(
37 35
     '/perldoc/*module' => {module => 'Mojolicious/Guides'} => \&_perldoc);
... ...
@@ -40,12 +38,10 @@ sub register {
40 38
 sub _perldoc {
41 39
   my $self = shift;
42 40
 
43
-  # Find module
41
+  # Find module or redirect to CPAN
44 42
   my $module = $self->param('module');
45 43
   $module =~ s!/!::!g;
46 44
   my $path = Pod::Simple::Search->new->find($module, @PATHS);
47
-
48
-  # Redirect to CPAN
49 45
   return $self->redirect_to("http://metacpan.org/module/$module")
50 46
     unless $path && -r $path;
51 47
 
... ...
@@ -120,14 +116,11 @@ sub _pod_to_html {
120 116
   # Block
121 117
   $pod = $pod->() if ref $pod eq 'CODE';
122 118
 
123
-  # Parser
124 119
   my $parser = Pod::Simple::HTML->new;
125 120
   $parser->force_title('');
126 121
   $parser->html_header_before_title('');
127 122
   $parser->html_header_after_title('');
128 123
   $parser->html_footer('');
129
-
130
-  # Parse
131 124
   $parser->output_string(\(my $output));
132 125
   return $@ unless eval { $parser->parse_string_document("$pod"); 1 };
133 126
 
... ...
@@ -170,14 +163,14 @@ you're welcome to fork it.
170 163
 
171 164
 L<Mojolicious::Plugin::PODRenderer> supports the following options.
172 165
 
173
-=head2 C<name>
166
+=head2 name
174 167
 
175 168
   # Mojolicious::Lite
176 169
   plugin PODRenderer => {name => 'foo'};
177 170
 
178 171
 Handler name, defaults to C<pod>.
179 172
 
180
-=head2 C<no_perldoc>
173
+=head2 no_perldoc
181 174
 
182 175
   # Mojolicious::Lite
183 176
   plugin PODRenderer => {no_perldoc => 1};
... ...
@@ -185,7 +178,7 @@ Handler name, defaults to C<pod>.
185 178
 Disable L<Mojolicious::Guides> documentation browser that will otherwise be
186 179
 available under C</perldoc>.
187 180
 
188
-=head2 C<preprocess>
181
+=head2 preprocess
189 182
 
190 183
   # Mojolicious::Lite
191 184
   plugin PODRenderer => {preprocess => 'epl'};
... ...
@@ -196,7 +189,7 @@ Name of handler used to preprocess POD, defaults to C<ep>.
196 189
 
197 190
 L<Mojolicious::Plugin::PODRenderer> implements the following helpers.
198 191
 
199
-=head2 C<pod_to_html>
192
+=head2 pod_to_html
200 193
 
201 194
   %= pod_to_html '=head2 lalala'
202 195
   <%= pod_to_html begin %>=head2 lalala<% end %>
... ...
@@ -208,7 +201,7 @@ Render POD to HTML without preprocessing.
208 201
 L<Mojolicious::Plugin::PODRenderer> inherits all methods from
209 202
 L<Mojolicious::Plugin> and implements the following new ones.
210 203
 
211
-=head2 C<register>
204
+=head2 register
212 205
 
213 206
   my $route = $plugin->register(Mojolicious->new);
214 207
   my $route = $plugin->register(Mojolicious->new, {name => 'foo'});
+3 -3
mojolegacy/lib/Mojolicious/Plugin/PoweredBy.pm
... ...
@@ -36,7 +36,7 @@ example for learning to build new plugins, you're welcome to fork it.
36 36
 
37 37
 L<Mojolicious::Plugin::PoweredBy> supports the following options.
38 38
 
39
-=head2 C<name>
39
+=head2 name
40 40
 
41 41
   plugin PoweredBy => (name => 'MyApp 1.0');
42 42
 
... ...
@@ -47,12 +47,12 @@ Value for C<X-Powered-By> header, defaults to C<Mojolicious (Perl)>.
47 47
 L<Mojolicious::Plugin::PoweredBy> inherits all methods from
48 48
 L<Mojolicious::Plugin> and implements the following new ones.
49 49
 
50
-=head2 C<register>
50
+=head2 register
51 51
 
52 52
   $plugin->register(Mojolicious->new);
53 53
   $plugin->register(Mojolicious->new, {name => 'MyFramework 1.0'});
54 54
 
55
-Register plugin hooks in L<Mojolicious> application.
55
+Register hooks in L<Mojolicious> application.
56 56
 
57 57
 =head1 SEE ALSO
58 58
 
+3 -7
mojolegacy/lib/Mojolicious/Plugin/RequestTimer.pm
... ...
@@ -5,11 +5,7 @@ use Time::HiRes qw(gettimeofday tv_interval);
5 5
 
6 6
 sub register {
7 7
   my ($self, $app) = @_;
8
-
9
-  # Start timer
10
-  $app->hook(after_static_dispatch => \&_start);
11
-
12
-  # End timer
8
+  $app->hook(before_routes  => \&_start);
13 9
   $app->hook(after_dispatch => \&_end);
14 10
 }
15 11
 
... ...
@@ -70,11 +66,11 @@ example for learning to build new plugins, you're welcome to fork it.
70 66
 L<Mojolicious::Plugin::RequestTimer> inherits all methods from
71 67
 L<Mojolicious::Plugin> and implements the following new ones.
72 68
 
73
-=head2 C<register>
69
+=head2 register
74 70
 
75 71
   $plugin->register(Mojolicious->new);
76 72
 
77
-Register plugin hooks in L<Mojolicious> application.
73
+Register hooks in L<Mojolicious> application.
78 74
 
79 75
 =head1 SEE ALSO
80 76
 
+43 -76
mojolegacy/lib/Mojolicious/Plugin/TagHelpers.pm
... ...
@@ -13,57 +13,38 @@ sub register {
13 13
     $app->helper("${name}_field" => sub { _input(@_, type => $name) });
14 14
   }
15 15
 
16
-  # Add "base_tag" helper
16
+  # DEPRECATED in Rainbow!
17 17
   $app->helper(
18
-    base_tag => sub { _tag('base', href => shift->req->url->base, @_) });
18
+    base_tag => sub {
19
+      warn "base_tag is DEPRECATED!!!\n";
20
+      _tag('base', href => shift->req->url->base, @_);
21
+    }
22
+  );
19 23
 
20
-  # Add "checkbox" helper
21 24
   $app->helper(check_box =>
22 25
       sub { _input(shift, shift, value => shift, @_, type => 'checkbox') });
23
-
24
-  # Add "file_field" helper
25 26
   $app->helper(file_field =>
26 27
       sub { shift; _tag('input', name => shift, @_, type => 'file') });
27 28
 
28
-  # Add "form_for" helper
29
-  $app->helper(form_for => \&_form_for);
30
-
31
-  # Add "hidden_field" helper
29
+  $app->helper(form_for     => \&_form_for);
32 30
   $app->helper(hidden_field => \&_hidden_field);
33
-
34
-  # Add "image" helper
35 31
   $app->helper(image => sub { _tag('img', src => shift->url_for(shift), @_) });
36
-
37
-  # Add "input_tag" helper
38 32
   $app->helper(input_tag => sub { _input(@_) });
39
-
40
-  # Add "javascript" helper
41 33
   $app->helper(javascript => \&_javascript);
34
+  $app->helper(link_to    => \&_link_to);
42 35
 
43
-  # Add "link_to" helper
44
-  $app->helper(link_to => \&_link_to);
45
-
46
-  # Add "password_field" helper
47 36
   $app->helper(password_field =>
48 37
       sub { shift; _tag('input', name => shift, @_, type => 'password') });
49
-
50
-  # Add "radio_button" helper
51 38
   $app->helper(radio_button =>
52 39
       sub { _input(shift, shift, value => shift, @_, type => 'radio') });
53 40
 
54
-  # Add "select_field" helper
55
-  $app->helper(select_field => \&_select_field);
56
-
57
-  # Add "stylesheet" helper
58
-  $app->helper(stylesheet => \&_stylesheet);
59
-
60
-  # Add "submit_button" helper
41
+  $app->helper(select_field  => \&_select_field);
42
+  $app->helper(stylesheet    => \&_stylesheet);
61 43
   $app->helper(submit_button => \&_submit_button);
62 44
 
63
-  # Add "t" and "tag" helpers
45
+  # "t" is just a shortcut for the "tag" helper
64 46
   $app->helper($_ => sub { shift; _tag(@_) }) for qw(t tag);
65 47
 
66
-  # Add "text_area" helper
67 48
   $app->helper(text_area => \&_text_area);
68 49
 }
69 50
 
... ...
@@ -93,14 +74,10 @@ sub _hidden_field {
93 74
 
94 75
 sub _input {
95 76
   my ($self, $name) = (shift, shift);
96
-
97
-  # Attributes
98 77
   my %attrs = @_ % 2 ? (value => shift, @_) : @_;
99 78
 
100
-  # Values
101
-  my @values = $self->param($name);
102
-
103 79
   # Special selection value
80
+  my @values = $self->param($name);
104 81
   my $type = $attrs{type} || '';
105 82
   if (@values && $type ne 'submit') {
106 83
 
... ...
@@ -206,10 +183,8 @@ sub _stylesheet {
206 183
     $cb = sub { "/*<![CDATA[*/\n" . $old->() . "\n/*]]>*/" }
207 184
   }
208 185
 
209
-  # URL
210
-  my $href = @_ % 2 ? $self->url_for(shift) : undef;
211
-
212 186
   # "link" or "style" tag
187
+  my $href = @_ % 2 ? $self->url_for(shift) : undef;
213 188
   return $href
214 189
     ? _tag('link', rel => 'stylesheet', href => $href, media => 'screen', @_)
215 190
     : _tag('style', @_, $cb);
... ...
@@ -299,15 +274,7 @@ example for learning how to build new plugins, you're welcome to fork it.
299 274
 
300 275
 L<Mojolicious::Plugin::TagHelpers> implements the following helpers.
301 276
 
302
-=head2 C<base_tag>
303
-
304
-  %= base_tag
305
-
306
-Generate portable C<base> tag refering to the current base URL.
307
-
308
-  <base href="http://localhost/cgi-bin/myapp.pl" />
309
-
310
-=head2 C<check_box>
277
+=head2 check_box
311 278
 
312 279
   %= check_box employed => 1
313 280
   %= check_box employed => 1, id => 'foo'
... ...
@@ -318,7 +285,7 @@ picked up and shown as default.
318 285
   <input name="employed" type="checkbox" value="1" />
319 286
   <input id="foo" name="employed" type="checkbox" value="1" />
320 287
 
321
-=head2 C<color_field>
288
+=head2 color_field
322 289
 
323 290
   %= color_field 'background'
324 291
   %= color_field background => '#ffffff'
... ...
@@ -331,7 +298,7 @@ picked up and shown as default.
331 298
   <input name="background" type="color" value="#ffffff" />
332 299
   <input id="foo" name="background" type="color" value="#ffffff" />
333 300
 
334
-=head2 C<date_field>
301
+=head2 date_field
335 302
 
336 303
   %= date_field 'end'
337 304
   %= date_field end => '2012-12-21'
... ...
@@ -344,7 +311,7 @@ picked up and shown as default.
344 311
   <input name="end" type="date" value="2012-12-21" />
345 312
   <input id="foo" name="end" type="date" value="2012-12-21" />
346 313
 
347
-=head2 C<datetime_field>
314
+=head2 datetime_field
348 315
 
349 316
   %= datetime_field 'end'
350 317
   %= datetime_field end => '2012-12-21T23:59:59Z'
... ...
@@ -357,7 +324,7 @@ picked up and shown as default.
357 324
   <input name="end" type="datetime" value="2012-12-21T23:59:59Z" />
358 325
   <input id="foo" name="end" type="datetime" value="2012-12-21T23:59:59Z" />
359 326
 
360
-=head2 C<email_field>
327
+=head2 email_field
361 328
 
362 329
   %= email_field 'notify'
363 330
   %= email_field notify => 'nospam@example.com'
... ...
@@ -370,7 +337,7 @@ picked up and shown as default.
370 337
   <input name="notify" type="email" value="nospam@example.com" />
371 338
   <input id="foo" name="notify" type="email" value="nospam@example.com" />
372 339
 
373
-=head2 C<file_field>
340
+=head2 file_field
374 341
 
375 342
   %= file_field 'avatar'
376 343
   %= file_field 'avatar', id => 'foo'
... ...
@@ -380,7 +347,7 @@ Generate file input element.
380 347
   <input name="avatar" type="file" />
381 348
   <input id="foo" name="avatar" type="file" />
382 349
 
383
-=head2 C<form_for>
350
+=head2 form_for
384 351
 
385 352
   %= form_for login => begin
386 353
     %= text_field 'first_name'
... ...
@@ -419,7 +386,7 @@ but not C<GET>, a C<method> attribute will be automatically added.
419 386
     <input value="Ok" type="submit" />
420 387
   </form>
421 388
 
422
-=head2 C<hidden_field>
389
+=head2 hidden_field
423 390
 
424 391
   %= hidden_field foo => 'bar'
425 392
   %= hidden_field foo => 'bar', id => 'bar'
... ...
@@ -429,7 +396,7 @@ Generate hidden input element.
429 396
   <input name="foo" type="hidden" value="bar" />
430 397
   <input id="bar" name="foo" type="hidden" value="bar" />
431 398
 
432
-=head2 C<image>
399
+=head2 image
433 400
 
434 401
   %= image '/images/foo.png'
435 402
   %= image '/images/foo.png', alt => 'Foo'
... ...
@@ -439,7 +406,7 @@ Generate image tag.
439 406
   <img src="/images/foo.png" />
440 407
   <img alt="Foo" src="/images/foo.png" />
441 408
 
442
-=head2 C<input_tag>
409
+=head2 input_tag
443 410
 
444 411
   %= input_tag 'first_name'
445 412
   %= input_tag first_name => 'Default name'
... ...
@@ -452,7 +419,7 @@ picked up and shown as default.
452 419
   <input name="first_name" value="Default name" />
453 420
   <input name="employed" type="checkbox" />
454 421
 
455
-=head2 C<javascript>
422
+=head2 javascript
456 423
 
457 424
   %= javascript '/script.js'
458 425
   %= javascript begin
... ...
@@ -466,7 +433,7 @@ Generate portable script tag for C<Javascript> asset.
466 433
     var a = 'b';
467 434
   ]]></script>
468 435
 
469
-=head2 C<link_to>
436
+=head2 link_to
470 437
 
471 438
   %= link_to Home => 'index'
472 439
   %= link_to Home => 'index' => {format => 'txt'} => (class => 'links')
... ...
@@ -491,7 +458,7 @@ capitalized link target as content.
491 458
   <a href="http://mojolicio.us">Mojolicious</a>
492 459
   <a href="http://127.0.0.1:3000/current/path?foo=bar">Retry</a>
493 460
 
494
-=head2 C<month_field>
461
+=head2 month_field
495 462
 
496 463
   %= month_field 'vacation'
497 464
   %= month_field vacation => '2012-12'
... ...
@@ -504,7 +471,7 @@ picked up and shown as default.
504 471
   <input name="vacation" type="month" value="2012-12" />
505 472
   <input id="foo" name="vacation" type="month" value="2012-12" />
506 473
 
507
-=head2 C<number_field>
474
+=head2 number_field
508 475
 
509 476
   %= number_field 'age'
510 477
   %= number_field age => 25
... ...
@@ -517,7 +484,7 @@ picked up and shown as default.
517 484
   <input name="age" type="number" value="25" />
518 485
   <input id="foo" max="200" min="0" name="age" type="number" value="25" />
519 486
 
520
-=head2 C<password_field>
487
+=head2 password_field
521 488
 
522 489
   %= password_field 'pass'
523 490
   %= password_field 'pass', id => 'foo'
... ...
@@ -527,7 +494,7 @@ Generate password input element.
527 494
   <input name="pass" type="password" />
528 495
   <input id="foo" name="pass" type="password" />
529 496
 
530
-=head2 C<radio_button>
497
+=head2 radio_button
531 498
 
532 499
   %= radio_button country => 'germany'
533 500
   %= radio_button country => 'germany', id => 'foo'
... ...
@@ -538,7 +505,7 @@ picked up and shown as default.
538 505
   <input name="country" type="radio" value="germany" />
539 506
   <input id="foo" name="country" type="radio" value="germany" />
540 507
 
541
-=head2 C<range_field>
508
+=head2 range_field
542 509
 
543 510
   %= range_field 'age'
544 511
   %= range_field age => 25
... ...
@@ -551,7 +518,7 @@ picked up and shown as default.
551 518
   <input name="age" type="range" value="25" />
552 519
   <input id="foo" max="200" min="200" name="age" type="range" value="25" />
553 520
 
554
-=head2 C<search_field>
521
+=head2 search_field
555 522
 
556 523
   %= search_field 'q'
557 524
   %= search_field q => 'perl'
... ...
@@ -564,7 +531,7 @@ picked up and shown as default.
564 531
   <input name="q" type="search" value="perl" />
565 532
   <input id="foo" name="q" type="search" value="perl" />
566 533
 
567
-=head2 C<select_field>
534
+=head2 select_field
568 535
 
569 536
   %= select_field language => [qw(de en)]
570 537
   %= select_field language => [qw(de en)], id => 'lang'
... ...
@@ -598,7 +565,7 @@ automatically get picked up and shown as default.
598 565
     <option value="en">en</option>
599 566
   </select>
600 567
 
601
-=head2 C<stylesheet>
568
+=head2 stylesheet
602 569
 
603 570
   %= stylesheet '/foo.css'
604 571
   %= stylesheet begin
... ...
@@ -612,7 +579,7 @@ Generate portable style or link tag for C<CSS> asset.
612 579
     body {color: #000}
613 580
   ]]></style>
614 581
 
615
-=head2 C<submit_button>
582
+=head2 submit_button
616 583
 
617 584
   %= submit_button
618 585
   %= submit_button 'Ok!', id => 'foo'
... ...
@@ -622,7 +589,7 @@ Generate submit input element.
622 589
   <input type="submit" value="Ok" />
623 590
   <input id="foo" type="submit" value="Ok!" />
624 591
 
625
-=head2 C<t>
592
+=head2 t
626 593
 
627 594
   %=t div => 'some & content'
628 595
 
... ...
@@ -630,7 +597,7 @@ Alias for C<tag>.
630 597
 
631 598
   <div>some &amp; content</div>
632 599
 
633
-=head2 C<tag>
600
+=head2 tag
634 601
 
635 602
   %= tag 'div'
636 603
   %= tag 'div', id => 'foo'
... ...
@@ -653,7 +620,7 @@ Very useful for reuse in more specific tag helpers.
653 620
 Results are automatically wrapped in L<Mojo::ByteStream> objects to prevent
654 621
 accidental double escaping.
655 622
 
656
-=head2 C<tel_field>
623
+=head2 tel_field
657 624
 
658 625
   %= tel_field 'work'
659 626
   %= tel_field work => '123456789'
... ...
@@ -666,7 +633,7 @@ picked up and shown as default.
666 633
   <input name="work" type="tel" value="123456789" />
667 634
   <input id="foo" name="work" type="tel" value="123456789" />
668 635
 
669
-=head2 C<text_area>
636
+=head2 text_area
670 637
 
671 638
   %= text_area 'foo'
672 639
   %= text_area 'foo', cols => 40
... ...
@@ -685,7 +652,7 @@ up and shown as default.
685 652
     Default!
686 653
   </textarea>
687 654
 
688
-=head2 C<text_field>
655
+=head2 text_field
689 656
 
690 657
   %= text_field 'first_name'
691 658
   %= text_field first_name => 'Default name'
... ...
@@ -698,7 +665,7 @@ picked up and shown as default.
698 665
   <input name="first_name" type="text" value="Default name" />
699 666
   <input class="user" name="first_name" type="text" value="Default name" />
700 667
 
701
-=head2 C<time_field>
668
+=head2 time_field
702 669
 
703 670
   %= time_field 'start'
704 671
   %= time_field start => '23:59:59'
... ...
@@ -711,7 +678,7 @@ picked up and shown as default.
711 678
   <input name="start" type="time" value="23:59:59" />
712 679
   <input id="foo" name="start" type="time" value="23:59:59" />
713 680
 
714
-=head2 C<url_field>
681
+=head2 url_field
715 682
 
716 683
   %= url_field 'address'
717 684
   %= url_field address => 'http://mojolicio.us'
... ...
@@ -724,7 +691,7 @@ picked up and shown as default.
724 691
   <input name="address" type="url" value="http://mojolicio.us" />
725 692
   <input id="foo" name="address" type="url" value="http://mojolicio.us" />
726 693
 
727
-=head2 C<week_field>
694
+=head2 week_field
728 695
 
729 696
   %= week_field 'vacation'
730 697
   %= week_field vacation => '2012-W17'
... ...
@@ -742,7 +709,7 @@ picked up and shown as default.
742 709
 L<Mojolicious::Plugin::TagHelpers> inherits all methods from
743 710
 L<Mojolicious::Plugin> and implements the following new ones.
744 711
 
745
-=head2 C<register>
712
+=head2 register
746 713
 
747 714
   $plugin->register(Mojolicious->new);
748 715
 
+72 -13
mojolegacy/lib/Mojolicious/Plugins.pm
... ...
@@ -37,11 +37,11 @@ sub load_plugin {
37 37
   my $class = $name =~ /^[a-z]/ ? camelize($name) : $name;
38 38
   for my $namespace (@{$self->namespaces}) {
39 39
     my $module = "${namespace}::$class";
40
-    return $module->new if $self->_load($module);
40
+    return $module->new if _load($module);
41 41
   }
42 42
 
43 43
   # Full module name
44
-  return $name->new if $self->_load($name);
44
+  return $name->new if _load($name);
45 45
 
46 46
   # Not found
47 47
   die qq{Plugin "$name" missing, maybe you need to install it?\n};
... ...
@@ -52,14 +52,10 @@ sub register_plugin {
52 52
 }
53 53
 
54 54
 sub _load {
55
-  my ($self, $module) = @_;
56
-
57
-  # Load
55
+  my $module = shift;
58 56
   if (my $e = Mojo::Loader->new->load($module)) {
59 57
     ref $e ? die $e : return undef;
60 58
   }
61
-
62
-  # Module is a plugin
63 59
   return $module->isa('Mojolicious::Plugin') ? 1 : undef;
64 60
 }
65 61
 
... ...
@@ -80,11 +76,74 @@ Mojolicious::Plugins - Plugin manager
80 76
 
81 77
 L<Mojolicious::Plugins> is the plugin manager of L<Mojolicious>.
82 78
 
79
+=head1 PLUGINS
80
+
81
+The following plugins are included in the L<Mojolicious> distribution as
82
+examples.
83
+
84
+=over 2
85
+
86
+=item L<Mojolicious::Plugin::Charset>
87
+
88
+Change the application charset.
89
+
90
+=item L<Mojolicious::Plugin::Config>
91
+
92
+Perl-ish configuration files.
93
+
94
+=item L<Mojolicious::Plugin::DefaultHelpers>
95
+
96
+General purpose helper collection, loaded automatically.
97
+
98
+=item L<Mojolicious::Plugin::EPLRenderer>
99
+
100
+Renderer for plain embedded Perl templates, loaded automatically.
101
+
102
+=item L<Mojolicious::Plugin::EPRenderer>
103
+
104
+Renderer for more sophisiticated embedded Perl templates, loaded
105
+automatically.
106
+
107
+=item L<Mojolicious::Plugin::HeaderCondition>
108
+
109
+Route condition for all kinds of headers, loaded automatically.
110
+
111
+=item L<Mojolicious::Plugin::JSONConfig>
112
+
113
+JSON configuration files.
114
+
115
+=item L<Mojolicious::Plugin::Mount>
116
+
117
+Mount whole L<Mojolicious> applications.
118
+
119
+=item L<Mojolicious::Plugin::PODRenderer>
120
+
121
+Renderer for turning POD into HTML and documentation browser for
122
+L<Mojolicious::Guides>.
123
+
124
+=item L<Mojolicious::Plugin::PoweredBy>
125
+
126
+Add an C<X-Powered-By> header to outgoing responses, loaded automatically.
127
+
128
+=item L<Mojolicious::Plugin::RequestTimer>
129
+
130
+Log timing information, loaded automatically.
131
+
132
+=item L<Mojolicious::Plugin::TagHelpers>
133
+
134
+Template specific helper collection, loaded automatically.
135
+
136
+=back
137
+
138
+=head1 EVENTS
139
+
140
+L<Mojolicious::Plugins> inherits all events from L<Mojo::EventEmitter>.
141
+
83 142
 =head1 ATTRIBUTES
84 143
 
85 144
 L<Mojolicious::Plugins> implements the following attributes.
86 145
 
87
-=head2 C<namespaces>
146
+=head2 namespaces
88 147
 
89 148
   my $namespaces = $plugins->namespaces;
90 149
   $plugins       = $plugins->namespaces(['Mojolicious::Plugin']);
... ...
@@ -99,28 +158,28 @@ Namespaces to load plugins from, defaults to L<Mojolicious::Plugin>.
99 158
 L<Mojolicious::Plugins> inherits all methods from L<Mojo::EventEmitter> and
100 159
 implements the following new ones.
101 160
 
102
-=head2 C<emit_chain>
161
+=head2 emit_chain
103 162
 
104 163
   $plugins = $plugins->emit_chain('foo');
105 164
   $plugins = $plugins->emit_chain(foo => 123);
106 165
 
107 166
 Emit events as chained hooks.
108 167
 
109
-=head2 C<emit_hook>
168
+=head2 emit_hook
110 169
 
111 170
   $plugins = $plugins->emit_hook('foo');
112 171
   $plugins = $plugins->emit_hook(foo => 123);
113 172
 
114 173
 Emit events as hooks.
115 174
 
116
-=head2 C<emit_hook_reverse>
175
+=head2 emit_hook_reverse
117 176
 
118 177
   $plugins = $plugins->emit_hook_reverse('foo');
119 178
   $plugins = $plugins->emit_hook_reverse(foo => 123);
120 179
 
121 180
 Emit events as hooks in reverse order.
122 181
 
123
-=head2 C<load_plugin>
182
+=head2 load_plugin
124 183
 
125 184
   my $plugin = $plugins->load_plugin('some_thing');
126 185
   my $plugin = $plugins->load_plugin('SomeThing');
... ...
@@ -128,7 +187,7 @@ Emit events as hooks in reverse order.
128 187
 
129 188
 Load a plugin from the configured namespaces or by full module name.
130 189
 
131
-=head2 C<register_plugin>
190
+=head2 register_plugin
132 191
 
133 192
   $plugins->register_plugin('some_thing', Mojolicious->new);
134 193
   $plugins->register_plugin('some_thing', Mojolicious->new, foo => 23);
+38 -53
mojolegacy/lib/Mojolicious/Renderer.pm
... ...
@@ -6,7 +6,7 @@ use Mojo::Cache;
6 6
 use Mojo::JSON;
7 7
 use Mojo::Home;
8 8
 use Mojo::Loader;
9
-use Mojo::Util 'encode';
9
+use Mojo::Util qw(encode slurp);
10 10
 
11 11
 has cache   => sub { Mojo::Cache->new };
12 12
 has classes => sub { ['main'] };
... ...
@@ -20,25 +20,22 @@ has paths => sub { [] };
20 20
 my $HOME = Mojo::Home->new;
21 21
 $HOME->parse(
22 22
   $HOME->parse($HOME->mojo_lib_dir)->rel_dir('Mojolicious/templates'));
23
-my %TEMPLATES = map { $_ => $HOME->slurp_rel_file($_) } @{$HOME->list_files};
23
+my %TEMPLATES = map { $_ => slurp $HOME->rel_file($_) } @{$HOME->list_files};
24 24
 
25 25
 sub new {
26
-  my $self = shift->SUPER::new(@_)->add_handler(json => \&_json);
27
-  return $self->add_handler(data => \&_data)->add_handler(text => \&_text);
28
-}
26
+  my $self = shift->SUPER::new(@_);
29 27
 
30
-sub add_handler {
31
-  my ($self, $name, $cb) = @_;
32
-  $self->handlers->{$name} = $cb;
33
-  return $self;
34
-}
28
+  $self->add_handler(
29
+    json => sub { ${$_[2]} = Mojo::JSON->new->encode($_[3]->{json}) });
30
+  $self->add_handler(data => sub { ${$_[2]} = $_[3]->{data} });
31
+  $self->add_handler(text => sub { ${$_[2]} = $_[3]->{text} });
35 32
 
36
-sub add_helper {
37
-  my ($self, $name, $cb) = @_;
38
-  $self->helpers->{$name} = $cb;
39 33
   return $self;
40 34
 }
41 35
 
36
+sub add_handler { shift->_add(handlers => @_) }
37
+sub add_helper  { shift->_add(helpers  => @_) }
38
+
42 39
 sub get_data_template {
43 40
   my ($self, $options) = @_;
44 41
 
... ...
@@ -131,7 +128,7 @@ sub render {
131 128
       if !$partial && $options->{encoding} && $output;
132 129
   }
133 130
 
134
-  return $output, $c->app->types->type($format) || 'text/plain';
131
+  return $output, $format;
135 132
 }
136 133
 
137 134
 sub template_name {
... ...
@@ -158,13 +155,14 @@ sub template_path {
158 155
   return catfile($self->paths->[0], split '/', $name);
159 156
 }
160 157
 
161
-sub _bundled { $TEMPLATES{"@{[pop]}.html.ep"} }
162
-
163
-sub _data {
164
-  my ($self, $c, $output, $options) = @_;
165
-  $$output = $options->{data};
158
+sub _add {
159
+  my ($self, $attr, $name, $cb) = @_;
160
+  $self->$attr->{$name} = $cb;
161
+  return $self;
166 162
 }
167 163
 
164
+sub _bundled { $TEMPLATES{"@{[pop]}.html.ep"} }
165
+
168 166
 sub _detect_handler {
169 167
   my ($self, $options) = @_;
170 168
 
... ...
@@ -196,11 +194,6 @@ sub _extends {
196 194
   return delete $stash->{extends};
197 195
 }
198 196
 
199
-sub _json {
200
-  my ($self, $c, $output, $options) = @_;
201
-  $$output = Mojo::JSON->new->encode($options->{json});
202
-}
203
-
204 197
 sub _render_template {
205 198
   my ($self, $c, $output, $options) = @_;
206 199
 
... ...
@@ -216,16 +209,11 @@ sub _render_template {
216 209
   return undef;
217 210
 }
218 211
 
219
-sub _text {
220
-  my ($self, $c, $output, $options) = @_;
221
-  $$output = $options->{text};
222
-}
223
-
224 212
 1;
225 213
 
226 214
 =head1 NAME
227 215
 
228
-Mojolicious::Renderer - MIME type based renderer
216
+Mojolicious::Renderer - Generate dynamic content
229 217
 
230 218
 =head1 SYNOPSIS
231 219
 
... ...
@@ -245,14 +233,14 @@ See L<Mojolicious::Guides::Rendering> for more.
245 233
 
246 234
 L<Mojolicious::Renderer> implements the following attributes.
247 235
 
248
-=head2 C<cache>
236
+=head2 cache
249 237
 
250 238
   my $cache = $renderer->cache;
251 239
   $renderer = $renderer->cache(Mojo::Cache->new);
252 240
 
253 241
 Renderer cache, defaults to a L<Mojo::Cache> object.
254 242
 
255
-=head2 C<classes>
243
+=head2 classes
256 244
 
257 245
   my $classes = $renderer->classes;
258 246
   $renderer   = $renderer->classes(['main']);
... ...
@@ -263,15 +251,14 @@ highest precedence, defaults to C<main>.
263 251
   # Add another class with templates in DATA section
264 252
   push @{$renderer->classes}, 'Mojolicious::Plugin::Fun';
265 253
 
266
-=head2 C<default_format>
254
+=head2 default_format
267 255
 
268 256
   my $default = $renderer->default_format;
269 257
   $renderer   = $renderer->default_format('html');
270 258
 
271
-The default format to render if C<format> is not set in the stash. The
272
-renderer will use L<Mojolicious/"types"> to look up the content MIME type.
259
+The default format to render if C<format> is not set in the stash.
273 260
 
274
-=head2 C<default_handler>
261
+=head2 default_handler
275 262
 
276 263
   my $default = $renderer->default_handler;
277 264
   $renderer   = $renderer->default_handler('ep');
... ...
@@ -279,28 +266,28 @@ renderer will use L<Mojolicious/"types"> to look up the content MIME type.
279 266
 The default template handler to use for rendering in cases where auto
280 267
 detection doesn't work, like for C<inline> templates.
281 268
 
282
-=head2 C<encoding>
269
+=head2 encoding
283 270
 
284 271
   my $encoding = $renderer->encoding;
285 272
   $renderer    = $renderer->encoding('koi8-r');
286 273
 
287 274
 Will encode the content if set, defaults to C<UTF-8>.
288 275
 
289
-=head2 C<handlers>
276
+=head2 handlers
290 277
 
291 278
   my $handlers = $renderer->handlers;
292 279
   $renderer    = $renderer->handlers({epl => sub {...}});
293 280
 
294 281
 Registered handlers.
295 282
 
296
-=head2 C<helpers>
283
+=head2 helpers
297 284
 
298 285
   my $helpers = $renderer->helpers;
299 286
   $renderer   = $renderer->helpers({url_for => sub {...}});
300 287
 
301 288
 Registered helpers.
302 289
 
303
-=head2 C<paths>
290
+=head2 paths
304 291
 
305 292
   my $paths = $renderer->paths;
306 293
   $renderer = $renderer->paths(['/home/sri/templates']);
... ...
@@ -313,28 +300,28 @@ Directories to look for templates in, first one has the highest precedence.
313 300
 =head1 METHODS
314 301
 
315 302
 L<Mojolicious::Renderer> inherits all methods from L<Mojo::Base> and
316
-implements the following ones.
303
+implements the following new ones.
317 304
 
318
-=head2 C<new>
305
+=head2 new
319 306
 
320 307
   my $renderer = Mojolicious::Renderer->new;
321 308
 
322 309
 Construct a new renderer and register C<data>, C<json> as well as C<text>
323 310
 handlers.
324 311
 
325
-=head2 C<add_handler>
312
+=head2 add_handler
326 313
 
327 314
   $renderer = $renderer->add_handler(epl => sub {...});
328 315
 
329 316
 Register a new handler.
330 317
 
331
-=head2 C<add_helper>
318
+=head2 add_helper
332 319
 
333 320
   $renderer = $renderer->add_helper(url_for => sub {...});
334 321
 
335 322
 Register a new helper.
336 323
 
337
-=head2 C<get_data_template>
324
+=head2 get_data_template
338 325
 
339 326
   my $template = $renderer->get_data_template({
340 327
     template       => 'foo/bar',
... ...
@@ -344,20 +331,18 @@ Register a new helper.
344 331
 
345 332
 Get a C<DATA> section template by name, usually used by handlers.
346 333
 
347
-=head2 C<render>
334
+=head2 render
348 335
 
349
-  my ($output, $type) = $renderer->render(Mojolicious::Controller->new);
350
-  my ($output, $type) = $renderer->render(Mojolicious::Controller->new, {
336
+  my ($output, $format) = $renderer->render(Mojolicious::Controller->new);
337
+  my ($output, $format) = $renderer->render(Mojolicious::Controller->new, {
351 338
     template => 'foo/bar',
352 339
     foo      => 'bar'
353 340
   });
354 341
 
355
-Render output through one of the Mojo renderers. This renderer requires some
356
-configuration, at the very least you will need to have a default C<format> and
357
-a default C<handler> as well as a C<template> or C<text>/C<json>. See
342
+Render output through one of the renderers. See
358 343
 L<Mojolicious::Controller/"render"> for a more user-friendly interface.
359 344
 
360
-=head2 C<template_name>
345
+=head2 template_name
361 346
 
362 347
   my $template = $renderer->template_name({
363 348
     template => 'foo/bar',
... ...
@@ -368,7 +353,7 @@ L<Mojolicious::Controller/"render"> for a more user-friendly interface.
368 353
 Builds a template name based on an options hash reference with C<template>,
369 354
 C<format> and C<handler>, usually used by handlers.
370 355
 
371
-=head2 C<template_path>
356
+=head2 template_path
372 357
 
373 358
   my $path = $renderer->template_path({
374 359
     template => 'foo/bar',
+38 -29
mojolegacy/lib/Mojolicious/Routes.pm
... ...
@@ -14,17 +14,8 @@ has [qw(conditions shortcuts)] => sub { {} };
14 14
 has hidden     => sub { [qw(attr has new tap)] };
15 15
 has namespaces => sub { [] };
16 16
 
17
-sub add_condition {
18
-  my ($self, $name, $cb) = @_;
19
-  $self->conditions->{$name} = $cb;
20
-  return $self;
21
-}
22
-
23
-sub add_shortcut {
24
-  my ($self, $name, $cb) = @_;
25
-  $self->shortcuts->{$name} = $cb;
26
-  return $self;
27
-}
17
+sub add_condition { shift->_add(conditions => @_) }
18
+sub add_shortcut  { shift->_add(shortcuts  => @_) }
28 19
 
29 20
 sub auto_render {
30 21
   my ($self, $c) = @_;
... ...
@@ -40,7 +31,7 @@ sub dispatch {
40 31
   my $req  = $c->req;
41 32
   my $path = $c->stash->{path};
42 33
   if (defined $path) { $path = "/$path" if $path !~ m!^/! }
43
-  else               { $path = $req->url->path->to_abs_string }
34
+  else               { $path = $req->url->path->to_route }
44 35
 
45 36
   # Prepare match
46 37
   my $method = $req->method;
... ...
@@ -71,10 +62,8 @@ sub dispatch {
71 62
     }
72 63
   }
73 64
 
74
-  # No match
75
-  return undef unless $m && @{$m->stack};
76
-
77 65
   # Dispatch
66
+  return undef unless $m && @{$m->stack};
78 67
   return undef if $self->_walk($c);
79 68
   $self->auto_render($c);
80 69
   return 1;
... ...
@@ -82,6 +71,14 @@ sub dispatch {
82 71
 
83 72
 sub hide { push @{shift->hidden}, @_ }
84 73
 
74
+sub lookup {
75
+  my ($self, $name) = @_;
76
+  my $reverse = $self->{reverse} ||= {};
77
+  return $reverse->{$name} if exists $reverse->{$name};
78
+  return undef unless my $route = $self->find($name);
79
+  return $reverse->{$name} = $route;
80
+}
81
+
85 82
 # DEPRECATED in Rainbow!
86 83
 sub namespace {
87 84
   warn <<EOF;
... ...
@@ -98,6 +95,12 @@ sub route {
98 95
   shift->add_child(Mojolicious::Routes::Route->new(@_))->children->[-1];
99 96
 }
100 97
 
98
+sub _add {
99
+  my ($self, $attr, $name, $cb) = @_;
100
+  $self->$attr->{$name} = $cb;
101
+  return $self;
102
+}
103
+
101 104
 sub _callback {
102 105
   my ($self, $c, $field, $staging) = @_;
103 106
   $c->stash->{'mojo.routed'}++;
... ...
@@ -217,7 +220,6 @@ sub _method {
217 220
 sub _walk {
218 221
   my ($self, $c) = @_;
219 222
 
220
-  # Walk the stack
221 223
   my $stack   = $c->match->stack;
222 224
   my $stash   = $c->stash;
223 225
   my $staging = @$stack;
... ...
@@ -296,7 +298,7 @@ See L<Mojolicious::Guides::Routing> for more.
296 298
 L<Mojolicious::Routes> inherits all attributes from
297 299
 L<Mojolicious::Routes::Route> and implements the following new ones.
298 300
 
299
-=head2 C<base_classes>
301
+=head2 base_classes
300 302
 
301 303
   my $classes = $r->base_classes;
302 304
   $r          = $r->base_classes(['MyApp::Controller']);
... ...
@@ -304,7 +306,7 @@ L<Mojolicious::Routes::Route> and implements the following new ones.
304 306
 Base classes used to identify controllers, defaults to
305 307
 L<Mojolicious::Controller> and L<Mojo>.
306 308
 
307
-=head2 C<cache>
309
+=head2 cache
308 310
 
309 311
   my $cache = $r->cache;
310 312
   $r        = $r->cache(Mojo::Cache->new);
... ...
@@ -314,14 +316,14 @@ Routing cache, defaults to a L<Mojo::Cache> object.
314 316
   # Disable caching
315 317
   $r->cache(0);
316 318
 
317
-=head2 C<conditions>
319
+=head2 conditions
318 320
 
319 321
   my $conditions = $r->conditions;
320 322
   $r             = $r->conditions({foo => sub {...}});
321 323
 
322 324
 Contains all available conditions.
323 325
 
324
-=head2 C<hidden>
326
+=head2 hidden
325 327
 
326 328
   my $hidden = $r->hidden;
327 329
   $r         = $r->hidden([qw(attr has new)]);
... ...
@@ -329,7 +331,7 @@ Contains all available conditions.
329 331
 Controller methods and attributes that are hidden from routes, defaults to
330 332
 C<attr>, C<has>, C<new> and C<tap>.
331 333
 
332
-=head2 C<namespaces>
334
+=head2 namespaces
333 335
 
334 336
   my $namespaces = $r->namespaces;
335 337
   $r             = $r->namespaces(['Foo::Bar::Controller']);
... ...
@@ -339,7 +341,7 @@ Namespaces to load controllers from.
339 341
   # Add another namespace to load controllers from
340 342
   push @{$r->namespaces}, 'MyApp::Controller';
341 343
 
342
-=head2 C<shortcuts>
344
+=head2 shortcuts
343 345
 
344 346
   my $shortcuts = $r->shortcuts;
345 347
   $r            = $r->shortcuts({foo => sub {...}});
... ...
@@ -349,39 +351,46 @@ Contains all available shortcuts.
349 351
 =head1 METHODS
350 352
 
351 353
 L<Mojolicious::Routes> inherits all methods from
352
-L<Mojolicious::Routes::Route> and implements the following ones.
354
+L<Mojolicious::Routes::Route> and implements the following new ones.
353 355
 
354
-=head2 C<add_condition>
356
+=head2 add_condition
355 357
 
356 358
   $r = $r->add_condition(foo => sub {...});
357 359
 
358 360
 Add a new condition.
359 361
 
360
-=head2 C<add_shortcut>
362
+=head2 add_shortcut
361 363
 
362 364
   $r = $r->add_shortcut(foo => sub {...});
363 365
 
364 366
 Add a new shortcut.
365 367
 
366
-=head2 C<auto_render>
368
+=head2 auto_render
367 369
 
368 370
   $r->auto_render(Mojolicious::Controller->new);
369 371
 
370 372
 Automatic rendering.
371 373
 
372
-=head2 C<dispatch>
374
+=head2 dispatch
373 375
 
374 376
   my $success = $r->dispatch(Mojolicious::Controller->new);
375 377
 
376 378
 Match routes with L<Mojolicious::Routes::Match> and dispatch.
377 379
 
378
-=head2 C<hide>
380
+=head2 hide
379 381
 
380 382
   $r = $r->hide(qw(foo bar));
381 383
 
382 384
 Hide controller methods and attributes from routes.
383 385
 
384
-=head2 C<route>
386
+=head2 lookup
387
+
388
+  my $route = $r->lookup('foo');
389
+
390
+Find route by name with L<Mojolicious::Routes::Route/"find"> and cache all
391
+results for future lookups.
392
+
393
+=head2 route
385 394
 
386 395
   my $route = $r->route;
387 396
   my $route = $r->route('/:action');
+12 -18
mojolegacy/lib/Mojolicious/Routes/Match.pm
... ...
@@ -1,27 +1,22 @@
1 1
 package Mojolicious::Routes::Match;
2 2
 use Mojo::Base -base;
3 3
 
4
-use Mojo::Util qw(decode url_unescape);
5
-
6 4
 has captures => sub { {} };
7 5
 has [qw(endpoint root)];
8 6
 has stack => sub { [] };
9 7
 
10 8
 sub new {
11 9
   my $self = shift->SUPER::new;
12
-
13
-  $self->{method} = uc shift;
14
-  my $path = url_unescape shift;
15
-  $self->{path} = do { my $tmp = decode('UTF-8', $path); defined $tmp ? $tmp : $path};
10
+  $self->{method}    = uc shift;
11
+  $self->{path}      = shift;
16 12
   $self->{websocket} = shift;
17
-
18 13
   return $self;
19 14
 }
20 15
 
21 16
 sub match {
22 17
   my ($self, $r, $c) = @_;
23 18
 
24
-  # Match
19
+  # Pattern
25 20
   $self->root($r) unless $self->root;
26 21
   my $path    = $self->{path};
27 22
   my $pattern = $r->pattern;
... ...
@@ -120,7 +115,7 @@ sub path_for {
120 115
   }
121 116
 
122 117
   # Find endpoint
123
-  else { return $name unless $endpoint = $self->root->find($name) }
118
+  else { return $name unless $endpoint = $self->root->lookup($name) }
124 119
 
125 120
   # Merge values
126 121
   my $captures = $self->captures;
... ...
@@ -134,7 +129,6 @@ sub path_for {
134 129
 
135 130
   # Render
136 131
   my $path = $endpoint->render('', \%values);
137
-  utf8::downgrade $path, 1;
138 132
   return wantarray ? ($path, $endpoint->has_websocket) : $path;
139 133
 }
140 134
 
... ...
@@ -170,28 +164,28 @@ structures.
170 164
 
171 165
 L<Mojolicious::Routes::Match> implements the following attributes.
172 166
 
173
-=head2 C<captures>
167
+=head2 captures
174 168
 
175 169
   my $captures = $m->captures;
176 170
   $m           = $m->captures({foo => 'bar'});
177 171
 
178 172
 Captured parameters.
179 173
 
180
-=head2 C<endpoint>
174
+=head2 endpoint
181 175
 
182 176
   my $endpoint = $m->endpoint;
183 177
   $m           = $m->endpoint(Mojolicious::Routes->new);
184 178
 
185 179
 The route endpoint that actually matched.
186 180
 
187
-=head2 C<root>
181
+=head2 root
188 182
 
189 183
   my $root = $m->root;
190 184
   $m       = $m->root($routes);
191 185
 
192 186
 The root of the route tree.
193 187
 
194
-=head2 C<stack>
188
+=head2 stack
195 189
 
196 190
   my $stack = $m->stack;
197 191
   $m        = $m->stack([{foo => 'bar'}]);
... ...
@@ -201,22 +195,22 @@ Captured parameters with nesting history.
201 195
 =head1 METHODS
202 196
 
203 197
 L<Mojolicious::Routes::Match> inherits all methods from L<Mojo::Base> and
204
-implements the following ones.
198
+implements the following new ones.
205 199
 
206
-=head2 C<new>
200
+=head2 new
207 201
 
208 202
   my $m = Mojolicious::Routes::Match->new(GET => '/foo');
209 203
   my $m = Mojolicious::Routes::Match->new(GET => '/foo', $ws);
210 204
 
211 205
 Construct a new L<Mojolicious::Routes::Match> object.
212 206
 
213
-=head2 C<match>
207
+=head2 match
214 208
 
215 209
   $m->match(Mojolicious::Routes->new, Mojolicious::Controller->new);
216 210
 
217 211
 Match against a route tree.
218 212
 
219
-=head2 C<path_for>
213
+=head2 path_for
220 214
 
221 215
   my $path        = $m->path_for;
222 216
   my $path        = $m->path_for(foo => 'bar');
+18 -26
mojolegacy/lib/Mojolicious/Routes/Pattern.pm
... ...
@@ -24,11 +24,8 @@ sub parse {
24 24
   # Make sure we have a viable pattern
25 25
   my $pattern = @_ % 2 ? (shift || '/') : '/';
26 26
   $pattern = "/$pattern" unless $pattern =~ m!^/!;
27
-
28
-  # Constraints
29 27
   $self->constraints({@_});
30 28
 
31
-  # Tokenize
32 29
   return $pattern eq '/' ? $self : $self->pattern($pattern)->_tokenize;
33 30
 }
34 31
 
... ...
@@ -39,7 +36,6 @@ sub render {
39 36
   my $format = ($values ||= {})->{format};
40 37
   $values = {%{$self->defaults}, %$values};
41 38
 
42
-  # Turn pattern into path
43 39
   my $string   = '';
44 40
   my $optional = 1;
45 41
   for my $token (reverse @{$self->tree}) {
... ...
@@ -104,7 +100,6 @@ sub shape_match {
104 100
 sub _compile {
105 101
   my $self = shift;
106 102
 
107
-  # Compile tree to regex
108 103
   my $block = my $regex = '';
109 104
   my $constraints = $self->constraints;
110 105
   my $optional    = 1;
... ...
@@ -152,7 +147,6 @@ sub _compile {
152 147
       $compiled .= '?' if $optional;
153 148
     }
154 149
 
155
-    # Add to block
156 150
     $block = "$compiled$block";
157 151
   }
158 152
 
... ...
@@ -188,14 +182,12 @@ sub _compile_req {
188 182
 sub _tokenize {
189 183
   my $self = shift;
190 184
 
191
-  # Token
192 185
   my $quote_end   = $self->quote_end;
193 186
   my $quote_start = $self->quote_start;
194 187
   my $placeholder = $self->placeholder_start;
195 188
   my $relaxed     = $self->relaxed_start;
196 189
   my $wildcard    = $self->wildcard_start;
197 190
 
198
-  # Parse the pattern character wise
199 191
   my $pattern = $self->pattern;
200 192
   my $state   = 'text';
201 193
   my (@tree, $quoted);
... ...
@@ -278,84 +270,84 @@ L<Mojolicious::Routes::Pattern> is the core of L<Mojolicious::Routes>.
278 270
 
279 271
 L<Mojolicious::Routes::Pattern> implements the following attributes.
280 272
 
281
-=head2 C<constraints>
273
+=head2 constraints
282 274
 
283 275
   my $constraints = $pattern->constraints;
284 276
   $pattern        = $pattern->constraints({foo => qr/\w+/});
285 277
 
286 278
 Regular expression constraints.
287 279
 
288
-=head2 C<defaults>
280
+=head2 defaults
289 281
 
290 282
   my $defaults = $pattern->defaults;
291 283
   $pattern     = $pattern->defaults({foo => 'bar'});
292 284
 
293 285
 Default parameters.
294 286
 
295
-=head2 C<format_regex>
287
+=head2 format_regex
296 288
 
297 289
   my $regex = $pattern->format_regex;
298 290
   $pattern  = $pattern->format_regex($regex);
299 291
 
300 292
 Compiled regular expression for format matching.
301 293
 
302
-=head2 C<pattern>
294
+=head2 pattern
303 295
 
304 296
   my $pattern = $pattern->pattern;
305 297
   $pattern    = $pattern->pattern('/(foo)/(bar)');
306 298
 
307 299
 Raw unparsed pattern.
308 300
 
309
-=head2 C<placeholder_start>
301
+=head2 placeholder_start
310 302
 
311 303
   my $start = $pattern->placeholder_start;
312 304
   $pattern  = $pattern->placeholder_start(':');
313 305
 
314 306
 Character indicating a placeholder, defaults to C<:>.
315 307
 
316
-=head2 C<placeholders>
308
+=head2 placeholders
317 309
 
318 310
   my $placeholders = $pattern->placeholders;
319 311
   $pattern         = $pattern->placeholders(['foo', 'bar']);
320 312
 
321 313
 Placeholder names.
322 314
 
323
-=head2 C<quote_end>
315
+=head2 quote_end
324 316
 
325 317
   my $end  = $pattern->quote_end;
326 318
   $pattern = $pattern->quote_end(']');
327 319
 
328 320
 Character indicating the end of a quoted placeholder, defaults to C<)>.
329 321
 
330
-=head2 C<quote_start>
322
+=head2 quote_start
331 323
 
332 324
   my $start = $pattern->quote_start;
333 325
   $pattern  = $pattern->quote_start('[');
334 326
 
335 327
 Character indicating the start of a quoted placeholder, defaults to C<(>.
336 328
 
337
-=head2 C<regex>
329
+=head2 regex
338 330
 
339 331
   my $regex = $pattern->regex;
340 332
   $pattern  = $pattern->regex($regex);
341 333
 
342 334
 Pattern in compiled regular expression form.
343 335
 
344
-=head2 C<relaxed_start>
336
+=head2 relaxed_start
345 337
 
346 338
   my $start = $pattern->relaxed_start;
347 339
   $pattern  = $pattern->relaxed_start('*');
348 340
 
349 341
 Character indicating a relaxed placeholder, defaults to C<#>.
350 342
 
351
-=head2 C<tree>
343
+=head2 tree
352 344
 
353 345
   my $tree = $pattern->tree;
354 346
   $pattern = $pattern->tree([ ... ]);
355 347
 
356 348
 Pattern in parsed form.
357 349
 
358
-=head2 C<wildcard_start>
350
+=head2 wildcard_start
359 351
 
360 352
   my $start = $pattern->wildcard_start;
361 353
   $pattern  = $pattern->wildcard_start('*');
... ...
@@ -365,9 +357,9 @@ Character indicating the start of a wildcard placeholder, defaults to C<*>.
365 357
 =head1 METHODS
366 358
 
367 359
 L<Mojolicious::Routes::Pattern> inherits all methods from L<Mojo::Base> and
368
-implements the following ones.
360
+implements the following new ones.
369 361
 
370
-=head2 C<new>
362
+=head2 new
371 363
 
372 364
   my $pattern = Mojolicious::Routes::Pattern->new('/:action');
373 365
   my $pattern
... ...
@@ -376,14 +368,14 @@ implements the following ones.
376 368
 
377 369
 Construct a new L<Mojolicious::Routes::Pattern> object.
378 370
 
379
-=head2 C<match>
371
+=head2 match
380 372
 
381 373
   my $result = $pattern->match('/foo/bar');
382 374
   my $result = $pattern->match('/foo/bar', 1);
383 375
 
384 376
 Match pattern against entire path, format detection is disabled by default.
385 377
 
386
-=head2 C<parse>
378
+=head2 parse
387 379
 
388 380
   $pattern = $pattern->parse('/:action');
389 381
   $pattern = $pattern->parse('/:action', action => qr/\w+/);
... ...
@@ -391,7 +383,7 @@ Match pattern against entire path, format detection is disabled by default.
391 383
 
392 384
 Parse a raw pattern.
393 385
 
394
-=head2 C<render>
386
+=head2 render
395 387
 
396 388
   my $path = $pattern->render({action => 'foo'});
397 389
   my $path = $pattern->render({action => 'foo'}, 1);
... ...
@@ -399,7 +391,7 @@ Parse a raw pattern.
399 391
 Render pattern into a path with parameters, format rendering is disabled by
400 392
 default.
401 393
 
402
-=head2 C<shape_match>
394
+=head2 shape_match
403 395
 
404 396
   my $result = $pattern->shape_match(\$path);
405 397
   my $result = $pattern->shape_match(\$path, 1);
+37 -40
mojolegacy/lib/Mojolicious/Routes/Route.pm
... ...
@@ -45,7 +45,6 @@ sub detour { shift->partial(1)->to(@_) }
45 45
 sub find {
46 46
   my ($self, $name) = @_;
47 47
 
48
-  # Check all children
49 48
   my @children = (@{$self->children});
50 49
   my $candidate;
51 50
   while (my $child = shift @children) {
... ...
@@ -102,6 +101,7 @@ sub over {
102 101
   return $self unless @$conditions;
103 102
   $self->{over} = $conditions;
104 103
   $self->root->cache(0);
104
+
105 105
   return $self;
106 106
 }
107 107
 
... ...
@@ -159,8 +159,6 @@ sub to {
159 159
   # Single argument
160 160
   my ($shortcut, $defaults);
161 161
   if (@_ == 1) {
162
-
163
-    # Hash
164 162
     $defaults = shift if ref $_[0] eq 'HASH';
165 163
     $shortcut = shift if $_[0];
166 164
   }
... ...
@@ -229,7 +227,6 @@ sub websocket {
229 227
 sub _generate_route {
230 228
   my ($self, $methods, @args) = @_;
231 229
 
232
-  # Route information
233 230
   my ($cb, @conditions, @constraints, %defaults, $name, $pattern);
234 231
   while (defined(my $arg = shift @args)) {
235 232
 
... ...
@@ -286,35 +283,35 @@ L<Mojolicious::Routes>.
286 283
 
287 284
 L<Mojolicious::Routes::Route> implements the following attributes.
288 285
 
289
-=head2 C<children>
286
+=head2 children
290 287
 
291 288
   my $children = $r->children;
292 289
   $r           = $r->children([Mojolicious::Routes::Route->new]);
293 290
 
294 291
 The children of this route, used for nesting routes.
295 292
 
296
-=head2 C<inline>
293
+=head2 inline
297 294
 
298 295
   my $inline = $r->inline;
299 296
   $r         = $r->inline(1);
300 297
 
301 298
 Allow C<bridge> semantics for this route.
302 299
 
303
-=head2 C<parent>
300
+=head2 parent
304 301
 
305 302
   my $parent = $r->parent;
306 303
   $r         = $r->parent(Mojolicious::Routes::Route->new);
307 304
 
308 305
 The parent of this route, used for nesting routes.
309 306
 
310
-=head2 C<partial>
307
+=head2 partial
311 308
 
312 309
   my $partial = $r->partial;
313 310
   $r          = $r->partial(1);
314 311
 
315 312
 Route has no specific end, remaining characters will be captured in C<path>.
316 313
 
317
-=head2 C<pattern>
314
+=head2 pattern
318 315
 
319 316
   my $pattern = $r->pattern;
320 317
   $r          = $r->pattern(Mojolicious::Routes::Pattern->new);
... ...
@@ -324,16 +321,16 @@ Pattern for this route, defaults to a L<Mojolicious::Routes::Pattern> object.
324 321
 =head1 METHODS
325 322
 
326 323
 L<Mojolicious::Routes::Route> inherits all methods from L<Mojo::Base> and
327
-implements the following ones.
324
+implements the following new ones.
328 325
 
329
-=head2 C<new>
326
+=head2 new
330 327
 
331 328
   my $r = Mojolicious::Routes::Route->new;
332 329
   my $r = Mojolicious::Routes::Route->new('/:controller/:action');
333 330
 
334 331
 Construct a new L<Mojolicious::Routes::Route> object.
335 332
 
336
-=head2 C<add_child>
333
+=head2 add_child
337 334
 
338 335
   $r = $r->add_child(Mojolicious::Route->new);
339 336
 
... ...
@@ -343,7 +340,7 @@ current parent if necessary.
343 340
   # Reattach route
344 341
   $r->add_child($r->find('foo'));
345 342
 
346
-=head2 C<any>
343
+=head2 any
347 344
 
348 345
   my $route = $r->any('/:foo' => sub {...});
349 346
   my $route = $r->any([qw(GET POST)] => '/:foo' => sub {...});
... ...
@@ -353,7 +350,7 @@ also the L<Mojolicious::Lite> tutorial for more argument variations.
353 350
 
354 351
   $r->any('/user')->to('user#whatever');
355 352
 
356
-=head2 C<bridge>
353
+=head2 bridge
357 354
 
358 355
   my $bridge = $r->bridge;
359 356
   my $bridge = $r->bridge('/:action');
... ...
@@ -366,7 +363,7 @@ Generate bridge route.
366 363
   $auth->get('/show')->to('#show');
367 364
   $auth->post('/create')->to('#create');
368 365
 
369
-=head2 C<delete>
366
+=head2 delete
370 367
 
371 368
   my $route = $r->delete('/:foo' => sub {...});
372 369
 
... ...
@@ -375,7 +372,7 @@ L<Mojolicious::Lite> tutorial for more argument variations.
375 372
 
376 373
   $r->delete('/user')->to('user#remove');
377 374
 
378
-=head2 C<detour>
375
+=head2 detour
379 376
 
380 377
   $r = $r->detour(action => 'foo');
381 378
   $r = $r->detour({action => 'foo'});
... ...
@@ -392,7 +389,7 @@ L<Mojolicious::Lite> tutorial for more argument variations.
392 389
 Set default parameters for this route and allow partial matching to simplify
393 390
 application embedding.
394 391
 
395
-=head2 C<find>
392
+=head2 find
396 393
 
397 394
   my $route = $r->find('foo');
398 395
 
... ...
@@ -401,7 +398,7 @@ generated ones.
401 398
 
402 399
   $r->find('show_user')->to(foo => 'bar');
403 400
 
404
-=head2 C<get>
401
+=head2 get
405 402
 
406 403
   my $route = $r->get('/:foo' => sub {...});
407 404
 
... ...
@@ -410,48 +407,48 @@ L<Mojolicious::Lite> tutorial for more argument variations.
410 407
 
411 408
   $r->get('/user')->to('user#show');
412 409
 
413
-=head2 C<has_conditions>
410
+=head2 has_conditions
414 411
 
415 412
   my $success = $r->has_conditions;
416 413
 
417 414
 Check if this route has active conditions.
418 415
 
419
-=head2 C<has_custom_name>
416
+=head2 has_custom_name
420 417
 
421 418
   my $success = $r->has_custom_name;
422 419
 
423 420
 Check if this route has a custom name.
424 421
 
425
-=head2 C<has_websocket>
422
+=head2 has_websocket
426 423
 
427 424
   my $success = $r->has_websocket;
428 425
 
429 426
 Check if this route has a WebSocket ancestor.
430 427
 
431
-=head2 C<is_endpoint>
428
+=head2 is_endpoint
432 429
 
433 430
   my $success = $r->is_endpoint;
434 431
 
435 432
 Check if this route qualifies as an endpoint.
436 433
 
437
-=head2 C<is_websocket>
434
+=head2 is_websocket
438 435
 
439 436
   my $success = $r->is_websocket;
440 437
 
441 438
 Check if this route is a WebSocket.
442 439
 
443
-=head2 C<name>
440
+=head2 name
444 441
 
445 442
   my $name = $r->name;
446 443
   $r       = $r->name('foo');
447 444
 
448 445
 The name of this route, defaults to an automatically generated name based on
449
-the route pattern. Note that the name C<current> is reserved for refering to
446
+the route pattern. Note that the name C<current> is reserved for referring to
450 447
 the current route.
451 448
 
452 449
   $r->get('/user')->to('user#show')->name('show_user');
453 450
 
454
-=head2 C<options>
451
+=head2 options
455 452
 
456 453
   my $route = $r->options('/:foo' => sub {...});
457 454
 
... ...
@@ -460,7 +457,7 @@ L<Mojolicious::Lite> tutorial for more argument variations.
460 457
 
461 458
   $r->options('/user')->to('user#overview');
462 459
 
463
-=head2 C<over>
460
+=head2 over
464 461
 
465 462
   my $over = $r->over;
466 463
   $r       = $r->over(foo => 1);
... ...
@@ -472,7 +469,7 @@ routing cache, since conditions are too complex for caching.
472 469
 
473 470
   $r->get('/foo')->over(host => qr/mojolicio\.us/)->to('foo#bar');
474 471
 
475
-=head2 C<parse>
472
+=head2 parse
476 473
 
477 474
   $r = $r->parse('/:action');
478 475
   $r = $r->parse('/:action', action => qr/\w+/);
... ...
@@ -480,7 +477,7 @@ routing cache, since conditions are too complex for caching.
480 477
 
481 478
 Parse a pattern.
482 479
 
483
-=head2 C<patch>
480
+=head2 patch
484 481
 
485 482
   my $route = $r->patch('/:foo' => sub {...});
486 483
 
... ...
@@ -489,7 +486,7 @@ L<Mojolicious::Lite> tutorial for more argument variations.
489 486
 
490 487
   $r->patch('/user')->to('user#update');
491 488
 
492
-=head2 C<post>
489
+=head2 post
493 490
 
494 491
   my $route = $r->post('/:foo' => sub {...});
495 492
 
... ...
@@ -498,7 +495,7 @@ L<Mojolicious::Lite> tutorial for more argument variations.
498 495
 
499 496
   $r->post('/user')->to('user#create');
500 497
 
501
-=head2 C<put>
498
+=head2 put
502 499
 
503 500
   my $route = $r->put('/:foo' => sub {...});
504 501
 
... ...
@@ -507,7 +504,7 @@ L<Mojolicious::Lite> tutorial for more argument variations.
507 504
 
508 505
   $r->put('/user')->to('user#replace');
509 506
 
510
-=head2 C<remove>
507
+=head2 remove
511 508
 
512 509
   $r = $r->remove;
513 510
 
... ...
@@ -519,14 +516,14 @@ Remove route from parent.
519 516
   # Reattach route to new parent
520 517
   $r->route('/foo')->add_child($r->find('bar')->remove);
521 518
 
522
-=head2 C<render>
519
+=head2 render
523 520
 
524 521
   my $path = $r->render($suffix);
525 522
   my $path = $r->render($suffix, {foo => 'bar'});
526 523
 
527 524
 Render route with parameters into a path.
528 525
 
529
-=head2 C<root>
526
+=head2 root
530 527
 
531 528
   my $root = $r->root;
532 529
 
... ...
@@ -534,7 +531,7 @@ The L<Mojolicious::Routes> object this route is an descendent of.
534 531
 
535 532
   $r->root->cache(0);
536 533
 
537
-=head2 C<route>
534
+=head2 route
538 535
 
539 536
   my $route = $r->route;
540 537
   my $route = $r->route('/:action');
... ...
@@ -543,7 +540,7 @@ The L<Mojolicious::Routes> object this route is an descendent of.
543 540
 
544 541
 Generate route matching all HTTP request methods.
545 542
 
546
-=head2 C<to>
543
+=head2 to
547 544
 
548 545
   my $defaults = $r->to;
549 546
   $r           = $r->to(action => 'foo');
... ...
@@ -560,13 +557,13 @@ Generate route matching all HTTP request methods.
560 557
 
561 558
 Set default parameters for this route.
562 559
 
563
-=head2 C<to_string>
560
+=head2 to_string
564 561
 
565 562
   my $string = $r->to_string;
566 563
 
567 564
 Stringify the whole route.
568 565
 
569
-=head2 C<under>
566
+=head2 under
570 567
 
571 568
   my $route = $r->under(sub {...});
572 569
   my $route = $r->under('/:foo');
... ...
@@ -578,7 +575,7 @@ argument variations.
578 575
   $auth->get('/show')->to('#show');
579 576
   $auth->post('/create')->to('#create');
580 577
 
581
-=head2 C<via>
578
+=head2 via
582 579
 
583 580
   my $methods = $r->via;
584 581
   $r          = $r->via('GET');
... ...
@@ -590,7 +587,7 @@ restrictions.
590 587
 
591 588
   $r->route('/foo')->via(qw(GET POST))->to('foo#bar');
592 589
 
593
-=head2 C<websocket>
590
+=head2 websocket
594 591
 
595 592
   my $websocket = $r->websocket('/:foo' => sub {...});
596 593
 
+11 -20
mojolegacy/lib/Mojolicious/Sessions.pm
... ...
@@ -12,52 +12,43 @@ has default_expiration => 3600;
12 12
 sub load {
13 13
   my ($self, $c) = @_;
14 14
 
15
-  # Session cookie
16 15
   return unless my $value = $c->signed_cookie($self->cookie_name);
17
-
18
-  # Deserialize
19 16
   $value =~ s/-/=/g;
20 17
   return unless my $session = Mojo::JSON->new->decode(b64_decode $value);
21 18
 
22
-  # Expiration
19
+  # "expiration" value is inherited
23 20
   my $expiration = defined $session->{expiration} ? $session->{expiration} : $self->default_expiration;
24 21
   return if !(my $expires = delete $session->{expires}) && $expiration;
25 22
   return if defined $expires && $expires <= time;
26 23
 
27
-  # Content
28 24
   my $stash = $c->stash;
29 25
   return unless $stash->{'mojo.active_session'} = keys %$session;
30 26
   $stash->{'mojo.session'} = $session;
31
-
32
-  # Flash
33 27
   $session->{flash} = delete $session->{new_flash} if $session->{new_flash};
34 28
 }
35 29
 
36 30
 sub store {
37 31
   my ($self, $c) = @_;
38 32
 
39
-  # Session
33
+  # Make sure session was active
40 34
   my $stash = $c->stash;
41 35
   return unless my $session = $stash->{'mojo.session'};
42 36
   return unless keys %$session || $stash->{'mojo.active_session'};
43 37
 
44
-  # Flash
38
+  # Don't reset flash for static files
45 39
   my $old = delete $session->{flash};
46 40
   @{$session->{new_flash}}{keys %$old} = values %$old
47 41
     if $stash->{'mojo.static'};
48 42
   delete $session->{new_flash} unless keys %{$session->{new_flash}};
49 43
 
50
-  # Expiration
44
+  # Generate "expires" value from "expiration" if necessary
51 45
   my $expiration = defined $session->{expiration} ? $session->{expiration} : $self->default_expiration;
52 46
   my $default = delete $session->{expires};
53 47
   $session->{expires} = $default || time + $expiration
54 48
     if $expiration || $default;
55 49
 
56
-  # Serialize
57 50
   my $value = b64_encode(Mojo::JSON->new->encode($session), '');
58 51
   $value =~ s/=/-/g;
59
-
60
-  # Session cookie
61 52
   my $options = {
62 53
     domain   => $self->cookie_domain,
63 54
     expires  => $session->{expires},
... ...
@@ -93,28 +84,28 @@ with a C<HMAC-SHA1> signature.
93 84
 
94 85
 L<Mojolicious::Sessions> implements the following attributes.
95 86
 
96
-=head2 C<cookie_domain>
87
+=head2 cookie_domain
97 88
 
98 89
   my $domain = $sessions->cookie_domain;
99 90
   $sessions  = $sessions->cookie_domain('.example.com');
100 91
 
101 92
 Domain for session cookies, not defined by default.
102 93
 
103
-=head2 C<cookie_name>
94
+=head2 cookie_name
104 95
 
105 96
   my $name  = $sessions->cookie_name;
106 97
   $sessions = $sessions->cookie_name('session');
107 98
 
108 99
 Name for session cookies, defaults to C<mojolicious>.
109 100
 
110
-=head2 C<cookie_path>
101
+=head2 cookie_path
111 102
 
112 103
   my $path  = $sessions->cookie_path;
113 104
   $sessions = $sessions->cookie_path('/foo');
114 105
 
115 106
 Path for session cookies, defaults to C</>.
116 107
 
117
-=head2 C<default_expiration>
108
+=head2 default_expiration
118 109
 
119 110
   my $time  = $sessions->default_expiration;
120 111
   $sessions = $sessions->default_expiration(3600);
... ...
@@ -134,7 +125,7 @@ C<expiration> and C<expires> session values.
134 125
   # Delete whole session by setting an expiration date in the past
135 126
   $c->session(expires => 1);
136 127
 
137
-=head2 C<secure>
128
+=head2 secure
138 129
 
139 130
   my $secure = $sessions->secure;
140 131
   $sessions  = $sessions->secure(1);
... ...
@@ -147,13 +138,13 @@ over HTTPS connections.
147 138
 L<Mojolicious::Sessions> inherits all methods from L<Mojo::Base> and
148 139
 implements the following ones.
149 140
 
150
-=head2 C<load>
141
+=head2 load
151 142
 
152 143
   $sessions->load(Mojolicious::Controller->new);
153 144
 
154 145
 Load session data from signed cookie.
155 146
 
156
-=head2 C<store>
147
+=head2 store
157 148
 
158 149
   $sessions->store(Mojolicious::Controller->new);
159 150
 
+8 -11
mojolegacy/lib/Mojolicious/Static.pm
... ...
@@ -24,8 +24,6 @@ sub dispatch {
24 24
   # Canonical path
25 25
   my $stash = $c->stash;
26 26
   my $path = $stash->{path} || $c->req->url->path->clone->canonicalize;
27
-
28
-  # Split parts
29 27
   return undef unless my @parts = @{Mojo::Path->new("$path")->parts};
30 28
 
31 29
   # Serve static file and prevent directory traversal
... ...
@@ -91,7 +89,6 @@ sub serve_asset {
91 89
       ->content_range("bytes $start-$end/$size");
92 90
   }
93 91
 
94
-  # Serve asset
95 92
   return $res->content->asset($asset->start_range($start)->end_range($end));
96 93
 }
97 94
 
... ...
@@ -138,14 +135,14 @@ Mojolicious::Static - Serve static files
138 135
 
139 136
 =head1 DESCRIPTION
140 137
 
141
-L<Mojolicious::Static> is a dispatcher for static files with C<Range> and
138
+L<Mojolicious::Static> is a static file server with C<Range> and
142 139
 C<If-Modified-Since> support.
143 140
 
144 141
 =head1 ATTRIBUTES
145 142
 
146 143
 L<Mojolicious::Static> implements the following attributes.
147 144
 
148
-=head2 C<classes>
145
+=head2 classes
149 146
 
150 147
   my $classes = $static->classes;
151 148
   $static     = $static->classes(['main']);
... ...
@@ -156,7 +153,7 @@ highest precedence, defaults to C<main>.
156 153
   # Add another class with static files in DATA section
157 154
   push @{$static->classes}, 'Mojolicious::Plugin::Fun';
158 155
 
159
-=head2 C<paths>
156
+=head2 paths
160 157
 
161 158
   my $paths = $static->paths;
162 159
   $static   = $static->paths(['/home/sri/public']);
... ...
@@ -169,15 +166,15 @@ Directories to serve static files from, first one has the highest precedence.
169 166
 =head1 METHODS
170 167
 
171 168
 L<Mojolicious::Static> inherits all methods from L<Mojo::Base> and implements
172
-the following ones.
169
+the following new ones.
173 170
 
174
-=head2 C<dispatch>
171
+=head2 dispatch
175 172
 
176 173
   my $success = $static->dispatch(Mojolicious::Controller->new);
177 174
 
178 175
 Serve static file for L<Mojolicious::Controller> object.
179 176
 
180
-=head2 C<file>
177
+=head2 file
181 178
 
182 179
   my $asset = $static->file('foo/bar.html');
183 180
 
... ...
@@ -186,13 +183,13 @@ to C<paths> or from C<classes>.
186 183
 
187 184
   my $content = $static->file('foo/bar.html')->slurp;
188 185
 
189
-=head2 C<serve>
186
+=head2 serve
190 187
 
191 188
   my $success = $static->serve(Mojolicious::Controller->new, 'foo/bar.html');
192 189
 
193 190
 Serve a specific file, relative to C<paths> or from C<classes>.
194 191
 
195
-=head2 C<serve_asset>
192
+=head2 serve_asset
196 193
 
197 194
   $static->serve_asset(Mojolicious::Controller->new, Mojo::Asset::File->new);
198 195
 
+4 -4
mojolegacy/lib/Mojolicious/Types.pm
... ...
@@ -112,7 +112,7 @@ The most common ones are already defined.
112 112
 
113 113
 L<Mojolicious::Types> implements the following attributes.
114 114
 
115
-=head2 C<types>
115
+=head2 types
116 116
 
117 117
   my $map = $types->types;
118 118
   $types  = $types->types({png => 'image/png'});
... ...
@@ -122,9 +122,9 @@ List of MIME types.
122 122
 =head1 METHODS
123 123
 
124 124
 L<Mojolicious::Types> inherits all methods from L<Mojo::Base> and implements
125
-the following ones.
125
+the following new ones.
126 126
 
127
-=head2 C<detect>
127
+=head2 detect
128 128
 
129 129
   my $exts = $types->detect('application/json;q=9');
130 130
   my $exts = $types->detect('text/html, application/json;q=9', 1);
... ...
@@ -135,7 +135,7 @@ unspecific values that contain more than one MIME type is disabled by default.
135 135
   # List detected extensions prioritized
136 136
   say for @{$types->detect('application/json, text/xml;q=0.1', 1)};
137 137
 
138
-=head2 C<type>
138
+=head2 type
139 139
 
140 140
   my $type = $types->type('png');
141 141
   $types   = $types->type(png => 'image/png');
BIN
mojolegacy/lib/Mojolicious/public/mojo/failraptor.png
+4
mojolegacy/lib/Mojolicious/public/mojo/jquery/jquery.js
... ...
@@ -0,0 +1,4 @@
1
+/*! jQuery v1.9.0 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license */(function(e,t){"use strict";function n(e){var t=e.length,n=st.type(e);return st.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}function r(e){var t=Tt[e]={};return st.each(e.match(lt)||[],function(e,n){t[n]=!0}),t}function i(e,n,r,i){if(st.acceptData(e)){var o,a,s=st.expando,u="string"==typeof n,l=e.nodeType,c=l?st.cache:e,f=l?e[s]:e[s]&&s;if(f&&c[f]&&(i||c[f].data)||!u||r!==t)return f||(l?e[s]=f=K.pop()||st.guid++:f=s),c[f]||(c[f]={},l||(c[f].toJSON=st.noop)),("object"==typeof n||"function"==typeof n)&&(i?c[f]=st.extend(c[f],n):c[f].data=st.extend(c[f].data,n)),o=c[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[st.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[st.camelCase(n)])):a=o,a}}function o(e,t,n){if(st.acceptData(e)){var r,i,o,a=e.nodeType,u=a?st.cache:e,l=a?e[st.expando]:st.expando;if(u[l]){if(t&&(r=n?u[l]:u[l].data)){st.isArray(t)?t=t.concat(st.map(t,st.camelCase)):t in r?t=[t]:(t=st.camelCase(t),t=t in r?[t]:t.split(" "));for(i=0,o=t.length;o>i;i++)delete r[t[i]];if(!(n?s:st.isEmptyObject)(r))return}(n||(delete u[l].data,s(u[l])))&&(a?st.cleanData([e],!0):st.support.deleteExpando||u!=u.window?delete u[l]:u[l]=null)}}}function a(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(Nt,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:wt.test(r)?st.parseJSON(r):r}catch(o){}st.data(e,n,r)}else r=t}return r}function s(e){var t;for(t in e)if(("data"!==t||!st.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function u(){return!0}function l(){return!1}function c(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function f(e,t,n){if(t=t||0,st.isFunction(t))return st.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return st.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=st.grep(e,function(e){return 1===e.nodeType});if(Wt.test(t))return st.filter(t,r,!n);t=st.filter(t,r)}return st.grep(e,function(e){return st.inArray(e,t)>=0===n})}function p(e){var t=zt.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function d(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function h(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function g(e){var t=nn.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function m(e,t){for(var n,r=0;null!=(n=e[r]);r++)st._data(n,"globalEval",!t||st._data(t[r],"globalEval"))}function y(e,t){if(1===t.nodeType&&st.hasData(e)){var n,r,i,o=st._data(e),a=st._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)st.event.add(t,n,s[n][r])}a.data&&(a.data=st.extend({},a.data))}}function v(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!st.support.noCloneEvent&&t[st.expando]){r=st._data(t);for(i in r.events)st.removeEvent(t,i,r.handle);t.removeAttribute(st.expando)}"script"===n&&t.text!==e.text?(h(t).text=e.text,g(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),st.support.html5Clone&&e.innerHTML&&!st.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Zt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}function b(e,n){var r,i,o=0,a=e.getElementsByTagName!==t?e.getElementsByTagName(n||"*"):e.querySelectorAll!==t?e.querySelectorAll(n||"*"):t;if(!a)for(a=[],r=e.childNodes||e;null!=(i=r[o]);o++)!n||st.nodeName(i,n)?a.push(i):st.merge(a,b(i,n));return n===t||n&&st.nodeName(e,n)?st.merge([e],a):a}function x(e){Zt.test(e.type)&&(e.defaultChecked=e.checked)}function T(e,t){if(t in e)return t;for(var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Nn.length;i--;)if(t=Nn[i]+n,t in e)return t;return r}function w(e,t){return e=t||e,"none"===st.css(e,"display")||!st.contains(e.ownerDocument,e)}function N(e,t){for(var n,r=[],i=0,o=e.length;o>i;i++)n=e[i],n.style&&(r[i]=st._data(n,"olddisplay"),t?(r[i]||"none"!==n.style.display||(n.style.display=""),""===n.style.display&&w(n)&&(r[i]=st._data(n,"olddisplay",S(n.nodeName)))):r[i]||w(n)||st._data(n,"olddisplay",st.css(n,"display")));for(i=0;o>i;i++)n=e[i],n.style&&(t&&"none"!==n.style.display&&""!==n.style.display||(n.style.display=t?r[i]||"":"none"));return e}function C(e,t,n){var r=mn.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function k(e,t,n,r,i){for(var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;4>o;o+=2)"margin"===n&&(a+=st.css(e,n+wn[o],!0,i)),r?("content"===n&&(a-=st.css(e,"padding"+wn[o],!0,i)),"margin"!==n&&(a-=st.css(e,"border"+wn[o]+"Width",!0,i))):(a+=st.css(e,"padding"+wn[o],!0,i),"padding"!==n&&(a+=st.css(e,"border"+wn[o]+"Width",!0,i)));return a}function E(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=ln(e),a=st.support.boxSizing&&"border-box"===st.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=un(e,t,o),(0>i||null==i)&&(i=e.style[t]),yn.test(i))return i;r=a&&(st.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+k(e,t,n||(a?"border":"content"),r,o)+"px"}function S(e){var t=V,n=bn[e];return n||(n=A(e,t),"none"!==n&&n||(cn=(cn||st("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(cn[0].contentWindow||cn[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=A(e,t),cn.detach()),bn[e]=n),n}function A(e,t){var n=st(t.createElement(e)).appendTo(t.body),r=st.css(n[0],"display");return n.remove(),r}function j(e,t,n,r){var i;if(st.isArray(t))st.each(t,function(t,i){n||kn.test(e)?r(e,i):j(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==st.type(t))r(e,t);else for(i in t)j(e+"["+i+"]",t[i],n,r)}function D(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(lt)||[];if(st.isFunction(n))for(;r=o[i++];)"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function L(e,n,r,i){function o(u){var l;return a[u]=!0,st.each(e[u]||[],function(e,u){var c=u(n,r,i);return"string"!=typeof c||s||a[c]?s?!(l=c):t:(n.dataTypes.unshift(c),o(c),!1)}),l}var a={},s=e===$n;return o(n.dataTypes[0])||!a["*"]&&o("*")}function H(e,n){var r,i,o=st.ajaxSettings.flatOptions||{};for(r in n)n[r]!==t&&((o[r]?e:i||(i={}))[r]=n[r]);return i&&st.extend(!0,e,i),e}function M(e,n,r){var i,o,a,s,u=e.contents,l=e.dataTypes,c=e.responseFields;for(o in c)o in r&&(n[c[o]]=r[o]);for(;"*"===l[0];)l.shift(),i===t&&(i=e.mimeType||n.getResponseHeader("Content-Type"));if(i)for(o in u)if(u[o]&&u[o].test(i)){l.unshift(o);break}if(l[0]in r)a=l[0];else{for(o in r){if(!l[0]||e.converters[o+" "+l[0]]){a=o;break}s||(s=o)}a=a||s}return a?(a!==l[0]&&l.unshift(a),r[a]):t}function q(e,t){var n,r,i,o,a={},s=0,u=e.dataTypes.slice(),l=u[0];if(e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u[1])for(n in e.converters)a[n.toLowerCase()]=e.converters[n];for(;i=u[++s];)if("*"!==i){if("*"!==l&&l!==i){if(n=a[l+" "+i]||a["* "+i],!n)for(r in a)if(o=r.split(" "),o[1]===i&&(n=a[l+" "+o[0]]||a["* "+o[0]])){n===!0?n=a[r]:a[r]!==!0&&(i=o[0],u.splice(s--,0,i));break}if(n!==!0)if(n&&e["throws"])t=n(t);else try{t=n(t)}catch(c){return{state:"parsererror",error:n?c:"No conversion from "+l+" to "+i}}}l=i}return{state:"success",data:t}}function _(){try{return new e.XMLHttpRequest}catch(t){}}function F(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function O(){return setTimeout(function(){Qn=t}),Qn=st.now()}function B(e,t){st.each(t,function(t,n){for(var r=(rr[t]||[]).concat(rr["*"]),i=0,o=r.length;o>i;i++)if(r[i].call(e,t,n))return})}function P(e,t,n){var r,i,o=0,a=nr.length,s=st.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=Qn||O(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;u>a;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),1>o&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:st.extend({},t),opts:st.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Qn||O(),duration:n.duration,tweens:[],createTween:function(t,n){var r=st.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?s.resolveWith(e,[l,t]):s.rejectWith(e,[l,t]),this}}),c=l.props;for(R(c,l.opts.specialEasing);a>o;o++)if(r=nr[o].call(l,e,c,l.opts))return r;return B(l,c),st.isFunction(l.opts.start)&&l.opts.start.call(e,l),st.fx.timer(st.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function R(e,t){var n,r,i,o,a;for(n in e)if(r=st.camelCase(n),i=t[r],o=e[n],st.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=st.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function W(e,t,n){var r,i,o,a,s,u,l,c,f,p=this,d=e.style,h={},g=[],m=e.nodeType&&w(e);n.queue||(c=st._queueHooks(e,"fx"),null==c.unqueued&&(c.unqueued=0,f=c.empty.fire,c.empty.fire=function(){c.unqueued||f()}),c.unqueued++,p.always(function(){p.always(function(){c.unqueued--,st.queue(e,"fx").length||c.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],"inline"===st.css(e,"display")&&"none"===st.css(e,"float")&&(st.support.inlineBlockNeedsLayout&&"inline"!==S(e.nodeName)?d.zoom=1:d.display="inline-block")),n.overflow&&(d.overflow="hidden",st.support.shrinkWrapBlocks||p.done(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]}));for(r in t)if(o=t[r],Zn.exec(o)){if(delete t[r],u=u||"toggle"===o,o===(m?"hide":"show"))continue;g.push(r)}if(a=g.length){s=st._data(e,"fxshow")||st._data(e,"fxshow",{}),"hidden"in s&&(m=s.hidden),u&&(s.hidden=!m),m?st(e).show():p.done(function(){st(e).hide()}),p.done(function(){var t;st._removeData(e,"fxshow");for(t in h)st.style(e,t,h[t])});for(r=0;a>r;r++)i=g[r],l=p.createTween(i,m?s[i]:0),h[i]=s[i]||st.style(e,i),i in s||(s[i]=l.start,m&&(l.end=l.start,l.start="width"===i||"height"===i?1:0))}}function $(e,t,n,r,i){return new $.prototype.init(e,t,n,r,i)}function I(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=wn[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function z(e){return st.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}var X,U,V=e.document,Y=e.location,J=e.jQuery,G=e.$,Q={},K=[],Z="1.9.0",et=K.concat,tt=K.push,nt=K.slice,rt=K.indexOf,it=Q.toString,ot=Q.hasOwnProperty,at=Z.trim,st=function(e,t){return new st.fn.init(e,t,X)},ut=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,lt=/\S+/g,ct=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,ft=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,pt=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,dt=/^[\],:{}\s]*$/,ht=/(?:^|:|,)(?:\s*\[)+/g,gt=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,mt=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,yt=/^-ms-/,vt=/-([\da-z])/gi,bt=function(e,t){return t.toUpperCase()},xt=function(){V.addEventListener?(V.removeEventListener("DOMContentLoaded",xt,!1),st.ready()):"complete"===V.readyState&&(V.detachEvent("onreadystatechange",xt),st.ready())};st.fn=st.prototype={jquery:Z,constructor:st,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:ft.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof st?n[0]:n,st.merge(this,st.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:V,!0)),pt.test(i[1])&&st.isPlainObject(n))for(i in n)st.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=V.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=V,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):st.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),st.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return nt.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=st.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return st.each(this,e,t)},ready:function(e){return st.ready.promise().done(e),this},slice:function(){return this.pushStack(nt.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(st.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:tt,sort:[].sort,splice:[].splice},st.fn.init.prototype=st.fn,st.extend=st.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||st.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(e=arguments[u]))for(n in e)r=s[n],i=e[n],s!==i&&(c&&i&&(st.isPlainObject(i)||(o=st.isArray(i)))?(o?(o=!1,a=r&&st.isArray(r)?r:[]):a=r&&st.isPlainObject(r)?r:{},s[n]=st.extend(c,a,i)):i!==t&&(s[n]=i));return s},st.extend({noConflict:function(t){return e.$===st&&(e.$=G),t&&e.jQuery===st&&(e.jQuery=J),st},isReady:!1,readyWait:1,holdReady:function(e){e?st.readyWait++:st.ready(!0)},ready:function(e){if(e===!0?!--st.readyWait:!st.isReady){if(!V.body)return setTimeout(st.ready);st.isReady=!0,e!==!0&&--st.readyWait>0||(U.resolveWith(V,[st]),st.fn.trigger&&st(V).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===st.type(e)},isArray:Array.isArray||function(e){return"array"===st.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?Q[it.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==st.type(e)||e.nodeType||st.isWindow(e))return!1;try{if(e.constructor&&!ot.call(e,"constructor")&&!ot.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||ot.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||V;var r=pt.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=st.buildFragment([e],t,i),i&&st(i).remove(),st.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=st.trim(n),n&&dt.test(n.replace(gt,"@").replace(mt,"]").replace(ht,"")))?Function("return "+n)():(st.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||st.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&st.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(yt,"ms-").replace(vt,bt)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,r){var i,o=0,a=e.length,s=n(e);if(r){if(s)for(;a>o&&(i=t.apply(e[o],r),i!==!1);o++);else for(o in e)if(i=t.apply(e[o],r),i===!1)break}else if(s)for(;a>o&&(i=t.call(e[o],o,e[o]),i!==!1);o++);else for(o in e)if(i=t.call(e[o],o,e[o]),i===!1)break;return e},trim:at&&!at.call("\ufeff\u00a0")?function(e){return null==e?"":at.call(e)}:function(e){return null==e?"":(e+"").replace(ct,"")},makeArray:function(e,t){var r=t||[];return null!=e&&(n(Object(e))?st.merge(r,"string"==typeof e?[e]:e):tt.call(r,e)),r},inArray:function(e,t,n){var r;if(t){if(rt)return rt.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else for(;n[o]!==t;)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,r){var i,o=0,a=e.length,s=n(e),u=[];if(s)for(;a>o;o++)i=t(e[o],o,r),null!=i&&(u[u.length]=i);else for(o in e)i=t(e[o],o,r),null!=i&&(u[u.length]=i);return et.apply([],u)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(r=e[n],n=e,e=r),st.isFunction(e)?(i=nt.call(arguments,2),o=function(){return e.apply(n||this,i.concat(nt.call(arguments)))},o.guid=e.guid=e.guid||st.guid++,o):t},access:function(e,n,r,i,o,a,s){var u=0,l=e.length,c=null==r;if("object"===st.type(r)){o=!0;for(u in r)st.access(e,n,u,r[u],!0,a,s)}else if(i!==t&&(o=!0,st.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(st(e),n)})),n))for(;l>u;u++)n(e[u],r,s?i:i.call(e[u],u,n(e[u],r)));return o?e:c?n.call(e):l?n(e[0],r):a},now:function(){return(new Date).getTime()}}),st.ready.promise=function(t){if(!U)if(U=st.Deferred(),"complete"===V.readyState)setTimeout(st.ready);else if(V.addEventListener)V.addEventListener("DOMContentLoaded",xt,!1),e.addEventListener("load",st.ready,!1);else{V.attachEvent("onreadystatechange",xt),e.attachEvent("onload",st.ready);var n=!1;try{n=null==e.frameElement&&V.documentElement}catch(r){}n&&n.doScroll&&function i(){if(!st.isReady){try{n.doScroll("left")}catch(e){return setTimeout(i,50)}st.ready()}}()}return U.promise(t)},st.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){Q["[object "+t+"]"]=t.toLowerCase()}),X=st(V);var Tt={};st.Callbacks=function(e){e="string"==typeof e?Tt[e]||r(e):st.extend({},e);var n,i,o,a,s,u,l=[],c=!e.once&&[],f=function(t){for(n=e.memory&&t,i=!0,u=a||0,a=0,s=l.length,o=!0;l&&s>u;u++)if(l[u].apply(t[0],t[1])===!1&&e.stopOnFalse){n=!1;break}o=!1,l&&(c?c.length&&f(c.shift()):n?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function r(t){st.each(t,function(t,n){var i=st.type(n);"function"===i?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==i&&r(n)})})(arguments),o?s=l.length:n&&(a=t,f(n))}return this},remove:function(){return l&&st.each(arguments,function(e,t){for(var n;(n=st.inArray(t,l,n))>-1;)l.splice(n,1),o&&(s>=n&&s--,u>=n&&u--)}),this},has:function(e){return st.inArray(e,l)>-1},empty:function(){return l=[],this},disable:function(){return l=c=n=t,this},disabled:function(){return!l},lock:function(){return c=t,n||p.disable(),this},locked:function(){return!c},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!l||i&&!c||(o?c.push(t):f(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},st.extend({Deferred:function(e){var t=[["resolve","done",st.Callbacks("once memory"),"resolved"],["reject","fail",st.Callbacks("once memory"),"rejected"],["notify","progress",st.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return st.Deferred(function(n){st.each(t,function(t,o){var a=o[0],s=st.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&st.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?st.extend(e,r):r}},i={};return r.pipe=r.then,st.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t,n,r,i=0,o=nt.call(arguments),a=o.length,s=1!==a||e&&st.isFunction(e.promise)?a:0,u=1===s?e:st.Deferred(),l=function(e,n,r){return function(i){n[e]=this,r[e]=arguments.length>1?nt.call(arguments):i,r===t?u.notifyWith(n,r):--s||u.resolveWith(n,r)}};if(a>1)for(t=Array(a),n=Array(a),r=Array(a);a>i;i++)o[i]&&st.isFunction(o[i].promise)?o[i].promise().done(l(i,r,o)).fail(u.reject).progress(l(i,n,t)):--s;return s||u.resolveWith(r,o),u.promise()}}),st.support=function(){var n,r,i,o,a,s,u,l,c,f,p=V.createElement("div");if(p.setAttribute("className","t"),p.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",r=p.getElementsByTagName("*"),i=p.getElementsByTagName("a")[0],!r||!i||!r.length)return{};o=V.createElement("select"),a=o.appendChild(V.createElement("option")),s=p.getElementsByTagName("input")[0],i.style.cssText="top:1px;float:left;opacity:.5",n={getSetAttribute:"t"!==p.className,leadingWhitespace:3===p.firstChild.nodeType,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(i.getAttribute("style")),hrefNormalized:"/a"===i.getAttribute("href"),opacity:/^0.5/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:!!s.value,optSelected:a.selected,enctype:!!V.createElement("form").enctype,html5Clone:"<:nav></:nav>"!==V.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===V.compatMode,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},s.checked=!0,n.noCloneChecked=s.cloneNode(!0).checked,o.disabled=!0,n.optDisabled=!a.disabled;try{delete p.test}catch(d){n.deleteExpando=!1}s=V.createElement("input"),s.setAttribute("value",""),n.input=""===s.getAttribute("value"),s.value="t",s.setAttribute("type","radio"),n.radioValue="t"===s.value,s.setAttribute("checked","t"),s.setAttribute("name","t"),u=V.createDocumentFragment(),u.appendChild(s),n.appendChecked=s.checked,n.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,p.attachEvent&&(p.attachEvent("onclick",function(){n.noCloneEvent=!1}),p.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})p.setAttribute(l="on"+f,"t"),n[f+"Bubbles"]=l in e||p.attributes[l].expando===!1;return p.style.backgroundClip="content-box",p.cloneNode(!0).style.backgroundClip="",n.clearCloneStyle="content-box"===p.style.backgroundClip,st(function(){var r,i,o,a="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",s=V.getElementsByTagName("body")[0];s&&(r=V.createElement("div"),r.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",s.appendChild(r).appendChild(p),p.innerHTML="<table><tr><td></td><td>t</td></tr></table>",o=p.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",c=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",n.reliableHiddenOffsets=c&&0===o[0].offsetHeight,p.innerHTML="",p.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",n.boxSizing=4===p.offsetWidth,n.doesNotIncludeMarginInBodyOffset=1!==s.offsetTop,e.getComputedStyle&&(n.pixelPosition="1%"!==(e.getComputedStyle(p,null)||{}).top,n.boxSizingReliable="4px"===(e.getComputedStyle(p,null)||{width:"4px"}).width,i=p.appendChild(V.createElement("div")),i.style.cssText=p.style.cssText=a,i.style.marginRight=i.style.width="0",p.style.width="1px",n.reliableMarginRight=!parseFloat((e.getComputedStyle(i,null)||{}).marginRight)),p.style.zoom!==t&&(p.innerHTML="",p.style.cssText=a+"width:1px;padding:1px;display:inline;zoom:1",n.inlineBlockNeedsLayout=3===p.offsetWidth,p.style.display="block",p.innerHTML="<div></div>",p.firstChild.style.width="5px",n.shrinkWrapBlocks=3!==p.offsetWidth,s.style.zoom=1),s.removeChild(r),r=p=o=i=null)}),r=o=u=a=i=s=null,n}();var wt=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,Nt=/([A-Z])/g;st.extend({cache:{},expando:"jQuery"+(Z+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?st.cache[e[st.expando]]:e[st.expando],!!e&&!s(e)},data:function(e,t,n){return i(e,t,n,!1)},removeData:function(e,t){return o(e,t,!1)},_data:function(e,t,n){return i(e,t,n,!0)},_removeData:function(e,t){return o(e,t,!0)},acceptData:function(e){var t=e.nodeName&&st.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),st.fn.extend({data:function(e,n){var r,i,o=this[0],s=0,u=null;if(e===t){if(this.length&&(u=st.data(o),1===o.nodeType&&!st._data(o,"parsedAttrs"))){for(r=o.attributes;r.length>s;s++)i=r[s].name,i.indexOf("data-")||(i=st.camelCase(i.substring(5)),a(o,i,u[i]));st._data(o,"parsedAttrs",!0)}return u}return"object"==typeof e?this.each(function(){st.data(this,e)}):st.access(this,function(n){return n===t?o?a(o,e,st.data(o,e)):null:(this.each(function(){st.data(this,e,n)}),t)},null,n,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){st.removeData(this,e)})}}),st.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=st._data(e,n),r&&(!i||st.isArray(r)?i=st._data(e,n,st.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=st.queue(e,t),r=n.length,i=n.shift(),o=st._queueHooks(e,t),a=function(){st.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return st._data(e,n)||st._data(e,n,{empty:st.Callbacks("once memory").add(function(){st._removeData(e,t+"queue"),st._removeData(e,n)})})}}),st.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?st.queue(this[0],e):n===t?this:this.each(function(){var t=st.queue(this,e,n);st._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&st.dequeue(this,e)})},dequeue:function(e){return this.each(function(){st.dequeue(this,e)})},delay:function(e,t){return e=st.fx?st.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=st.Deferred(),a=this,s=this.length,u=function(){--i||o.resolveWith(a,[a])};for("string"!=typeof e&&(n=e,e=t),e=e||"fx";s--;)r=st._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(u));return u(),o.promise(n)}});var Ct,kt,Et=/[\t\r\n]/g,St=/\r/g,At=/^(?:input|select|textarea|button|object)$/i,jt=/^(?:a|area)$/i,Dt=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,Lt=/^(?:checked|selected)$/i,Ht=st.support.getSetAttribute,Mt=st.support.input;st.fn.extend({attr:function(e,t){return st.access(this,st.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){st.removeAttr(this,e)})},prop:function(e,t){return st.access(this,st.prop,e,t,arguments.length>1)},removeProp:function(e){return e=st.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,u="string"==typeof e&&e;if(st.isFunction(e))return this.each(function(t){st(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(lt)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(Et," "):" ")){for(o=0;i=t[o++];)0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=st.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,u=0===arguments.length||"string"==typeof e&&e;if(st.isFunction(e))return this.each(function(t){st(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(lt)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(Et," "):"")){for(o=0;i=t[o++];)for(;r.indexOf(" "+i+" ")>=0;)r=r.replace(" "+i+" "," ");n.className=e?st.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return st.isFunction(e)?this.each(function(n){st(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n)for(var i,o=0,a=st(this),s=t,u=e.match(lt)||[];i=u[o++];)s=r?s:!a.hasClass(i),a[s?"addClass":"removeClass"](i);else("undefined"===n||"boolean"===n)&&(this.className&&st._data(this,"__className__",this.className),this.className=this.className||e===!1?"":st._data(this,"__className__")||"")})},hasClass:function(e){for(var t=" "+e+" ",n=0,r=this.length;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(Et," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=st.isFunction(e),this.each(function(r){var o,a=st(this);1===this.nodeType&&(o=i?e.call(this,r,a.val()):e,null==o?o="":"number"==typeof o?o+="":st.isArray(o)&&(o=st.map(o,function(e){return null==e?"":e+""})),n=st.valHooks[this.type]||st.valHooks[this.nodeName.toLowerCase()],n&&"set"in n&&n.set(this,o,"value")!==t||(this.value=o))});if(o)return n=st.valHooks[o.type]||st.valHooks[o.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(o,"value"))!==t?r:(r=o.value,"string"==typeof r?r.replace(St,""):null==r?"":r)}}}),st.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){for(var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,u=0>i?s:o?i:0;s>u;u++)if(n=r[u],!(!n.selected&&u!==i||(st.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&st.nodeName(n.parentNode,"optgroup"))){if(t=st(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n=st.makeArray(t);return st(e).find("option").each(function(){this.selected=st.inArray(st(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attr:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return e.getAttribute===t?st.prop(e,n,r):(a=1!==s||!st.isXMLDoc(e),a&&(n=n.toLowerCase(),o=st.attrHooks[n]||(Dt.test(n)?kt:Ct)),r===t?o&&a&&"get"in o&&null!==(i=o.get(e,n))?i:(e.getAttribute!==t&&(i=e.getAttribute(n)),null==i?t:i):null!==r?o&&a&&"set"in o&&(i=o.set(e,r,n))!==t?i:(e.setAttribute(n,r+""),r):(st.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(lt);if(o&&1===e.nodeType)for(;n=o[i++];)r=st.propFix[n]||n,Dt.test(n)?!Ht&&Lt.test(n)?e[st.camelCase("default-"+n)]=e[r]=!1:e[r]=!1:st.attr(e,n,""),e.removeAttribute(Ht?n:r)},attrHooks:{type:{set:function(e,t){if(!st.support.radioValue&&"radio"===t&&st.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!st.isXMLDoc(e),a&&(n=st.propFix[n]||n,o=st.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):At.test(e.nodeName)||jt.test(e.nodeName)&&e.href?0:t}}}}),kt={get:function(e,n){var r=st.prop(e,n),i="boolean"==typeof r&&e.getAttribute(n),o="boolean"==typeof r?Mt&&Ht?null!=i:Lt.test(n)?e[st.camelCase("default-"+n)]:!!i:e.getAttributeNode(n);return o&&o.value!==!1?n.toLowerCase():t},set:function(e,t,n){return t===!1?st.removeAttr(e,n):Mt&&Ht||!Lt.test(n)?e.setAttribute(!Ht&&st.propFix[n]||n,n):e[st.camelCase("default-"+n)]=e[n]=!0,n}},Mt&&Ht||(st.attrHooks.value={get:function(e,n){var r=e.getAttributeNode(n);return st.nodeName(e,"input")?e.defaultValue:r&&r.specified?r.value:t
2
+},set:function(e,n,r){return st.nodeName(e,"input")?(e.defaultValue=n,t):Ct&&Ct.set(e,n,r)}}),Ht||(Ct=st.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&("id"===n||"name"===n||"coords"===n?""!==r.value:r.specified)?r.value:t},set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},st.attrHooks.contenteditable={get:Ct.get,set:function(e,t,n){Ct.set(e,""===t?!1:t,n)}},st.each(["width","height"],function(e,n){st.attrHooks[n]=st.extend(st.attrHooks[n],{set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}})})),st.support.hrefNormalized||(st.each(["href","src","width","height"],function(e,n){st.attrHooks[n]=st.extend(st.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null==r?t:r}})}),st.each(["href","src"],function(e,t){st.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})),st.support.style||(st.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),st.support.optSelected||(st.propHooks.selected=st.extend(st.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),st.support.enctype||(st.propFix.enctype="encoding"),st.support.checkOn||st.each(["radio","checkbox"],function(){st.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),st.each(["radio","checkbox"],function(){st.valHooks[this]=st.extend(st.valHooks[this],{set:function(e,n){return st.isArray(n)?e.checked=st.inArray(st(e).val(),n)>=0:t}})});var qt=/^(?:input|select|textarea)$/i,_t=/^key/,Ft=/^(?:mouse|contextmenu)|click/,Ot=/^(?:focusinfocus|focusoutblur)$/,Bt=/^([^.]*)(?:\.(.+)|)$/;st.event={global:{},add:function(e,n,r,i,o){var a,s,u,l,c,f,p,d,h,g,m,y=3!==e.nodeType&&8!==e.nodeType&&st._data(e);if(y){for(r.handler&&(a=r,r=a.handler,o=a.selector),r.guid||(r.guid=st.guid++),(l=y.events)||(l=y.events={}),(s=y.handle)||(s=y.handle=function(e){return st===t||e&&st.event.triggered===e.type?t:st.event.dispatch.apply(s.elem,arguments)},s.elem=e),n=(n||"").match(lt)||[""],c=n.length;c--;)u=Bt.exec(n[c])||[],h=m=u[1],g=(u[2]||"").split(".").sort(),p=st.event.special[h]||{},h=(o?p.delegateType:p.bindType)||h,p=st.event.special[h]||{},f=st.extend({type:h,origType:m,data:i,handler:r,guid:r.guid,selector:o,needsContext:o&&st.expr.match.needsContext.test(o),namespace:g.join(".")},a),(d=l[h])||(d=l[h]=[],d.delegateCount=0,p.setup&&p.setup.call(e,i,g,s)!==!1||(e.addEventListener?e.addEventListener(h,s,!1):e.attachEvent&&e.attachEvent("on"+h,s))),p.add&&(p.add.call(e,f),f.handler.guid||(f.handler.guid=r.guid)),o?d.splice(d.delegateCount++,0,f):d.push(f),st.event.global[h]=!0;e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,m=st.hasData(e)&&st._data(e);if(m&&(u=m.events)){for(t=(t||"").match(lt)||[""],l=t.length;l--;)if(s=Bt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){for(f=st.event.special[d]||{},d=(r?f.delegateType:f.bindType)||d,p=u[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;o--;)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&f.teardown.call(e,h,m.handle)!==!1||st.removeEvent(e,d,m.handle),delete u[d])}else for(d in u)st.event.remove(e,d+t[l],n,r,!0);st.isEmptyObject(u)&&(delete m.handle,st._removeData(e,"events"))}},trigger:function(n,r,i,o){var a,s,u,l,c,f,p,d=[i||V],h=n.type||n,g=n.namespace?n.namespace.split("."):[];if(s=u=i=i||V,3!==i.nodeType&&8!==i.nodeType&&!Ot.test(h+st.event.triggered)&&(h.indexOf(".")>=0&&(g=h.split("."),h=g.shift(),g.sort()),c=0>h.indexOf(":")&&"on"+h,n=n[st.expando]?n:new st.Event(h,"object"==typeof n&&n),n.isTrigger=!0,n.namespace=g.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:st.makeArray(r,[n]),p=st.event.special[h]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!st.isWindow(i)){for(l=p.delegateType||h,Ot.test(l+h)||(s=s.parentNode);s;s=s.parentNode)d.push(s),u=s;u===(i.ownerDocument||V)&&d.push(u.defaultView||u.parentWindow||e)}for(a=0;(s=d[a++])&&!n.isPropagationStopped();)n.type=a>1?l:p.bindType||h,f=(st._data(s,"events")||{})[n.type]&&st._data(s,"handle"),f&&f.apply(s,r),f=c&&s[c],f&&st.acceptData(s)&&f.apply&&f.apply(s,r)===!1&&n.preventDefault();if(n.type=h,!(o||n.isDefaultPrevented()||p._default&&p._default.apply(i.ownerDocument,r)!==!1||"click"===h&&st.nodeName(i,"a")||!st.acceptData(i)||!c||!i[h]||st.isWindow(i))){u=i[c],u&&(i[c]=null),st.event.triggered=h;try{i[h]()}catch(m){}st.event.triggered=t,u&&(i[c]=u)}return n.result}},dispatch:function(e){e=st.event.fix(e);var n,r,i,o,a,s=[],u=nt.call(arguments),l=(st._data(this,"events")||{})[e.type]||[],c=st.event.special[e.type]||{};if(u[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){for(s=st.event.handlers.call(this,e,l),n=0;(o=s[n++])&&!e.isPropagationStopped();)for(e.currentTarget=o.elem,r=0;(a=o.handlers[r++])&&!e.isImmediatePropagationStopped();)(!e.namespace_re||e.namespace_re.test(a.namespace))&&(e.handleObj=a,e.data=a.data,i=((st.event.special[a.origType]||{}).handle||a.handler).apply(o.elem,u),i!==t&&(e.result=i)===!1&&(e.preventDefault(),e.stopPropagation()));return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],u=n.delegateCount,l=e.target;if(u&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(l.disabled!==!0||"click"!==e.type){for(i=[],r=0;u>r;r++)a=n[r],o=a.selector+" ",i[o]===t&&(i[o]=a.needsContext?st(o,this).index(l)>=0:st.find(o,this,null,[l]).length),i[o]&&i.push(a);i.length&&s.push({elem:l,handlers:i})}return n.length>u&&s.push({elem:this,handlers:n.slice(u)}),s},fix:function(e){if(e[st.expando])return e;var t,n,r=e,i=st.event.fixHooks[e.type]||{},o=i.props?this.props.concat(i.props):this.props;for(e=new st.Event(r),t=o.length;t--;)n=o[t],e[n]=r[n];return e.target||(e.target=r.srcElement||V),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,i.filter?i.filter(e,r):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,a=n.button,s=n.fromElement;return null==e.pageX&&null!=n.clientX&&(r=e.target.ownerDocument||V,i=r.documentElement,o=r.body,e.pageX=n.clientX+(i&&i.scrollLeft||o&&o.scrollLeft||0)-(i&&i.clientLeft||o&&o.clientLeft||0),e.pageY=n.clientY+(i&&i.scrollTop||o&&o.scrollTop||0)-(i&&i.clientTop||o&&o.clientTop||0)),!e.relatedTarget&&s&&(e.relatedTarget=s===e.target?n.toElement:s),e.which||a===t||(e.which=1&a?1:2&a?3:4&a?2:0),e}},special:{load:{noBubble:!0},click:{trigger:function(){return st.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t}},focus:{trigger:function(){if(this!==V.activeElement&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===V.activeElement&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=st.extend(new st.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?st.event.trigger(i,null,t):st.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},st.removeEvent=V.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,n,r){var i="on"+n;e.detachEvent&&(e[i]===t&&(e[i]=null),e.detachEvent(i,r))},st.Event=function(e,n){return this instanceof st.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?u:l):this.type=e,n&&st.extend(this,n),this.timeStamp=e&&e.timeStamp||st.now(),this[st.expando]=!0,t):new st.Event(e,n)},st.Event.prototype={isDefaultPrevented:l,isPropagationStopped:l,isImmediatePropagationStopped:l,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=u,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=u,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u,this.stopPropagation()}},st.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){st.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!st.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),st.support.submitBubbles||(st.event.special.submit={setup:function(){return st.nodeName(this,"form")?!1:(st.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=st.nodeName(n,"input")||st.nodeName(n,"button")?n.form:t;r&&!st._data(r,"submitBubbles")&&(st.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),st._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&st.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return st.nodeName(this,"form")?!1:(st.event.remove(this,"._submit"),t)}}),st.support.changeBubbles||(st.event.special.change={setup:function(){return qt.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(st.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),st.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),st.event.simulate("change",this,e,!0)})),!1):(st.event.add(this,"beforeactivate._change",function(e){var t=e.target;qt.test(t.nodeName)&&!st._data(t,"changeBubbles")&&(st.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||st.event.simulate("change",this.parentNode,e,!0)}),st._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return st.event.remove(this,"._change"),!qt.test(this.nodeName)}}),st.support.focusinBubbles||st.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){st.event.simulate(t,e.target,st.event.fix(e),!0)};st.event.special[t]={setup:function(){0===n++&&V.addEventListener(e,r,!0)},teardown:function(){0===--n&&V.removeEventListener(e,r,!0)}}}),st.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(s in e)this.on(s,n,r,e[s],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=l;else if(!i)return this;return 1===o&&(a=i,i=function(e){return st().off(e),a.apply(this,arguments)},i.guid=a.guid||(a.guid=st.guid++)),this.each(function(){st.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,st(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=l),this.each(function(){st.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){st.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?st.event.trigger(e,n,r,!0):t},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),st.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){st.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)},_t.test(t)&&(st.event.fixHooks[t]=st.event.keyHooks),Ft.test(t)&&(st.event.fixHooks[t]=st.event.mouseHooks)}),function(e,t){function n(e){return ht.test(e+"")}function r(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>C.cacheLength&&delete e[t.shift()],e[n]=r}}function i(e){return e[P]=!0,e}function o(e){var t=L.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}}function a(e,t,n,r){var i,o,a,s,u,l,c,d,h,g;if((t?t.ownerDocument||t:R)!==L&&D(t),t=t||L,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(!M&&!r){if(i=gt.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&O(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return Q.apply(n,K.call(t.getElementsByTagName(e),0)),n;if((a=i[3])&&W.getByClassName&&t.getElementsByClassName)return Q.apply(n,K.call(t.getElementsByClassName(a),0)),n}if(W.qsa&&!q.test(e)){if(c=!0,d=P,h=t,g=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){for(l=f(e),(c=t.getAttribute("id"))?d=c.replace(vt,"\\$&"):t.setAttribute("id",d),d="[id='"+d+"'] ",u=l.length;u--;)l[u]=d+p(l[u]);h=dt.test(e)&&t.parentNode||t,g=l.join(",")}if(g)try{return Q.apply(n,K.call(h.querySelectorAll(g),0)),n}catch(m){}finally{c||t.removeAttribute("id")}}}return x(e.replace(at,"$1"),t,n,r)}function s(e,t){for(var n=e&&t&&e.nextSibling;n;n=n.nextSibling)if(n===t)return-1;return e?1:-1}function u(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function l(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function c(e){return i(function(t){return t=+t,i(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function f(e,t){var n,r,i,o,s,u,l,c=X[e+" "];if(c)return t?0:c.slice(0);for(s=e,u=[],l=C.preFilter;s;){(!n||(r=ut.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),u.push(i=[])),n=!1,(r=lt.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(at," ")}),s=s.slice(n.length));for(o in C.filter)!(r=pt[o].exec(s))||l[o]&&!(r=l[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?a.error(e):X(e,u).slice(0)}function p(e){for(var t=0,n=e.length,r="";n>t;t++)r+=e[t].value;return r}function d(e,t,n){var r=t.dir,i=n&&"parentNode"===t.dir,o=I++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||i)return e(t,n,o)}:function(t,n,a){var s,u,l,c=$+" "+o;if(a){for(;t=t[r];)if((1===t.nodeType||i)&&e(t,n,a))return!0}else for(;t=t[r];)if(1===t.nodeType||i)if(l=t[P]||(t[P]={}),(u=l[r])&&u[0]===c){if((s=u[1])===!0||s===N)return s===!0}else if(u=l[r]=[c],u[1]=e(t,n,a)||N,u[1]===!0)return!0}}function h(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function g(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;u>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),l&&t.push(s));return a}function m(e,t,n,r,o,a){return r&&!r[P]&&(r=m(r)),o&&!o[P]&&(o=m(o,a)),i(function(i,a,s,u){var l,c,f,p=[],d=[],h=a.length,m=i||b(t||"*",s.nodeType?[s]:s,[]),y=!e||!i&&t?m:g(m,p,e,s,u),v=n?o||(i?e:h||r)?[]:a:y;if(n&&n(y,v,s,u),r)for(l=g(v,d),r(l,[],s,u),c=l.length;c--;)(f=l[c])&&(v[d[c]]=!(y[d[c]]=f));if(i){if(o||e){if(o){for(l=[],c=v.length;c--;)(f=v[c])&&l.push(y[c]=f);o(null,v=[],l,u)}for(c=v.length;c--;)(f=v[c])&&(l=o?Z.call(i,f):p[c])>-1&&(i[l]=!(a[l]=f))}}else v=g(v===a?v.splice(h,v.length):v),o?o(null,a,v,u):Q.apply(a,v)})}function y(e){for(var t,n,r,i=e.length,o=C.relative[e[0].type],a=o||C.relative[" "],s=o?1:0,u=d(function(e){return e===t},a,!0),l=d(function(e){return Z.call(t,e)>-1},a,!0),c=[function(e,n,r){return!o&&(r||n!==j)||((t=n).nodeType?u(e,n,r):l(e,n,r))}];i>s;s++)if(n=C.relative[e[s].type])c=[d(h(c),n)];else{if(n=C.filter[e[s].type].apply(null,e[s].matches),n[P]){for(r=++s;i>r&&!C.relative[e[r].type];r++);return m(s>1&&h(c),s>1&&p(e.slice(0,s-1)).replace(at,"$1"),n,r>s&&y(e.slice(s,r)),i>r&&y(e=e.slice(r)),i>r&&p(e))}c.push(n)}return h(c)}function v(e,t){var n=0,r=t.length>0,o=e.length>0,s=function(i,s,u,l,c){var f,p,d,h=[],m=0,y="0",v=i&&[],b=null!=c,x=j,T=i||o&&C.find.TAG("*",c&&s.parentNode||s),w=$+=null==x?1:Math.E;for(b&&(j=s!==L&&s,N=n);null!=(f=T[y]);y++){if(o&&f){for(p=0;d=e[p];p++)if(d(f,s,u)){l.push(f);break}b&&($=w,N=++n)}r&&((f=!d&&f)&&m--,i&&v.push(f))}if(m+=y,r&&y!==m){for(p=0;d=t[p];p++)d(v,h,s,u);if(i){if(m>0)for(;y--;)v[y]||h[y]||(h[y]=G.call(l));h=g(h)}Q.apply(l,h),b&&!i&&h.length>0&&m+t.length>1&&a.uniqueSort(l)}return b&&($=w,j=x),v};return r?i(s):s}function b(e,t,n){for(var r=0,i=t.length;i>r;r++)a(e,t[r],n);return n}function x(e,t,n,r){var i,o,a,s,u,l=f(e);if(!r&&1===l.length){if(o=l[0]=l[0].slice(0),o.length>2&&"ID"===(a=o[0]).type&&9===t.nodeType&&!M&&C.relative[o[1].type]){if(t=C.find.ID(a.matches[0].replace(xt,Tt),t)[0],!t)return n;e=e.slice(o.shift().value.length)}for(i=pt.needsContext.test(e)?-1:o.length-1;i>=0&&(a=o[i],!C.relative[s=a.type]);i--)if((u=C.find[s])&&(r=u(a.matches[0].replace(xt,Tt),dt.test(o[0].type)&&t.parentNode||t))){if(o.splice(i,1),e=r.length&&p(o),!e)return Q.apply(n,K.call(r,0)),n;break}}return S(e,l)(r,t,M,n,dt.test(e)),n}function T(){}var w,N,C,k,E,S,A,j,D,L,H,M,q,_,F,O,B,P="sizzle"+-new Date,R=e.document,W={},$=0,I=0,z=r(),X=r(),U=r(),V=typeof t,Y=1<<31,J=[],G=J.pop,Q=J.push,K=J.slice,Z=J.indexOf||function(e){for(var t=0,n=this.length;n>t;t++)if(this[t]===e)return t;return-1},et="[\\x20\\t\\r\\n\\f]",tt="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",nt=tt.replace("w","w#"),rt="([*^$|!~]?=)",it="\\["+et+"*("+tt+")"+et+"*(?:"+rt+et+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+nt+")|)|)"+et+"*\\]",ot=":("+tt+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+it.replace(3,8)+")*)|.*)\\)|)",at=RegExp("^"+et+"+|((?:^|[^\\\\])(?:\\\\.)*)"+et+"+$","g"),ut=RegExp("^"+et+"*,"+et+"*"),lt=RegExp("^"+et+"*([\\x20\\t\\r\\n\\f>+~])"+et+"*"),ct=RegExp(ot),ft=RegExp("^"+nt+"$"),pt={ID:RegExp("^#("+tt+")"),CLASS:RegExp("^\\.("+tt+")"),NAME:RegExp("^\\[name=['\"]?("+tt+")['\"]?\\]"),TAG:RegExp("^("+tt.replace("w","w*")+")"),ATTR:RegExp("^"+it),PSEUDO:RegExp("^"+ot),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+et+"*(even|odd|(([+-]|)(\\d*)n|)"+et+"*(?:([+-]|)"+et+"*(\\d+)|))"+et+"*\\)|)","i"),needsContext:RegExp("^"+et+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+et+"*((?:-\\d)?\\d*)"+et+"*\\)|)(?=[^-]|$)","i")},dt=/[\x20\t\r\n\f]*[+~]/,ht=/\{\s*\[native code\]\s*\}/,gt=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,mt=/^(?:input|select|textarea|button)$/i,yt=/^h\d$/i,vt=/'|\\/g,bt=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,xt=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,Tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{K.call(H.childNodes,0)[0].nodeType}catch(wt){K=function(e){for(var t,n=[];t=this[e];e++)n.push(t);return n}}E=a.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},D=a.setDocument=function(e){var r=e?e.ownerDocument||e:R;return r!==L&&9===r.nodeType&&r.documentElement?(L=r,H=r.documentElement,M=E(r),W.tagNameNoComments=o(function(e){return e.appendChild(r.createComment("")),!e.getElementsByTagName("*").length}),W.attributes=o(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),W.getByClassName=o(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),W.getByName=o(function(e){e.id=P+0,e.innerHTML="<a name='"+P+"'></a><div name='"+P+"'></div>",H.insertBefore(e,H.firstChild);var t=r.getElementsByName&&r.getElementsByName(P).length===2+r.getElementsByName(P+0).length;return W.getIdNotName=!r.getElementById(P),H.removeChild(e),t}),C.attrHandle=o(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==V&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},W.getIdNotName?(C.find.ID=function(e,t){if(typeof t.getElementById!==V&&!M){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},C.filter.ID=function(e){var t=e.replace(xt,Tt);return function(e){return e.getAttribute("id")===t}}):(C.find.ID=function(e,n){if(typeof n.getElementById!==V&&!M){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==V&&r.getAttributeNode("id").value===e?[r]:t:[]}},C.filter.ID=function(e){var t=e.replace(xt,Tt);return function(e){var n=typeof e.getAttributeNode!==V&&e.getAttributeNode("id");return n&&n.value===t}}),C.find.TAG=W.tagNameNoComments?function(e,n){return typeof n.getElementsByTagName!==V?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i];i++)1===n.nodeType&&r.push(n);return r}return o},C.find.NAME=W.getByName&&function(e,n){return typeof n.getElementsByName!==V?n.getElementsByName(name):t},C.find.CLASS=W.getByClassName&&function(e,n){return typeof n.getElementsByClassName===V||M?t:n.getElementsByClassName(e)},_=[],q=[":focus"],(W.qsa=n(r.querySelectorAll))&&(o(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||q.push("\\["+et+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||q.push(":checked")}),o(function(e){e.innerHTML="<input type='hidden' i=''/>",e.querySelectorAll("[i^='']").length&&q.push("[*^$]="+et+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),q.push(",.*:")})),(W.matchesSelector=n(F=H.matchesSelector||H.mozMatchesSelector||H.webkitMatchesSelector||H.oMatchesSelector||H.msMatchesSelector))&&o(function(e){W.disconnectedMatch=F.call(e,"div"),F.call(e,"[s!='']:x"),_.push("!=",ot)}),q=RegExp(q.join("|")),_=RegExp(_.join("|")),O=n(H.contains)||H.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},B=H.compareDocumentPosition?function(e,t){var n;return e===t?(A=!0,0):(n=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t))?1&n||e.parentNode&&11===e.parentNode.nodeType?e===r||O(R,e)?-1:t===r||O(R,t)?1:0:4&n?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var n,i=0,o=e.parentNode,a=t.parentNode,u=[e],l=[t];if(e===t)return A=!0,0;if(e.sourceIndex&&t.sourceIndex)return(~t.sourceIndex||Y)-(O(R,e)&&~e.sourceIndex||Y);if(!o||!a)return e===r?-1:t===r?1:o?-1:a?1:0;if(o===a)return s(e,t);for(n=e;n=n.parentNode;)u.unshift(n);for(n=t;n=n.parentNode;)l.unshift(n);for(;u[i]===l[i];)i++;return i?s(u[i],l[i]):u[i]===R?-1:l[i]===R?1:0},A=!1,[0,0].sort(B),W.detectDuplicates=A,L):L},a.matches=function(e,t){return a(e,null,null,t)},a.matchesSelector=function(e,t){if((e.ownerDocument||e)!==L&&D(e),t=t.replace(bt,"='$1']"),!(!W.matchesSelector||M||_&&_.test(t)||q.test(t)))try{var n=F.call(e,t);if(n||W.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return a(t,L,null,[e]).length>0},a.contains=function(e,t){return(e.ownerDocument||e)!==L&&D(e),O(e,t)},a.attr=function(e,t){var n;return(e.ownerDocument||e)!==L&&D(e),M||(t=t.toLowerCase()),(n=C.attrHandle[t])?n(e):M||W.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},a.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},a.uniqueSort=function(e){var t,n=[],r=1,i=0;if(A=!W.detectDuplicates,e.sort(B),A){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));for(;i--;)e.splice(n[i],1)}return e},k=a.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=k(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=k(t);return n},C=a.selectors={cacheLength:50,createPseudo:i,match:pt,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(xt,Tt),e[3]=(e[4]||e[5]||"").replace(xt,Tt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||a.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&a.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return pt.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&ct.test(n)&&(t=f(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(xt,Tt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=z[e+" "];return t||(t=RegExp("(^|"+et+")"+e+"("+et+"|$)"))&&z(e,function(e){return t.test(e.className||typeof e.getAttribute!==V&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=a.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.substr(i.length-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s;if(m){if(o){for(;g;){for(f=t;f=f[g];)if(s?f.nodeName.toLowerCase()===y:1===f.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){for(c=m[P]||(m[P]={}),l=c[e]||[],d=l[0]===$&&l[1],p=l[0]===$&&l[2],f=d&&m.childNodes[d];f=++d&&f&&f[g]||(p=d=0)||h.pop();)if(1===f.nodeType&&++p&&f===t){c[e]=[$,d,p];break}}else if(v&&(l=(t[P]||(t[P]={}))[e])&&l[0]===$)p=l[1];else for(;(f=++d&&f&&f[g]||(p=d=0)||h.pop())&&((s?f.nodeName.toLowerCase()!==y:1!==f.nodeType)||!++p||(v&&((f[P]||(f[P]={}))[e]=[$,p]),f!==t)););return p-=i,p===r||0===p%r&&p/r>=0}}},PSEUDO:function(e,t){var n,r=C.pseudos[e]||C.setFilters[e.toLowerCase()]||a.error("unsupported pseudo: "+e);return r[P]?r(t):r.length>1?(n=[e,e,"",t],C.setFilters.hasOwnProperty(e.toLowerCase())?i(function(e,n){for(var i,o=r(e,t),a=o.length;a--;)i=Z.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:i(function(e){var t=[],n=[],r=S(e.replace(at,"$1"));return r[P]?i(function(e,t,n,i){for(var o,a=r(e,null,i,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:i(function(e){return function(t){return a(e,t).length>0}}),contains:i(function(e){return function(t){return(t.textContent||t.innerText||k(t)).indexOf(e)>-1}}),lang:i(function(e){return ft.test(e||"")||a.error("unsupported lang: "+e),e=e.replace(xt,Tt).toLowerCase(),function(t){var n;do if(n=M?t.getAttribute("xml:lang")||t.getAttribute("lang"):t.lang)return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===H},focus:function(e){return e===L.activeElement&&(!L.hasFocus||L.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!C.pseudos.empty(e)},header:function(e){return yt.test(e.nodeName)},input:function(e){return mt.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:c(function(){return[0]}),last:c(function(e,t){return[t-1]}),eq:c(function(e,t,n){return[0>n?n+t:n]}),even:c(function(e,t){for(var n=0;t>n;n+=2)e.push(n);return e}),odd:c(function(e,t){for(var n=1;t>n;n+=2)e.push(n);return e}),lt:c(function(e,t,n){for(var r=0>n?n+t:n;--r>=0;)e.push(r);return e}),gt:c(function(e,t,n){for(var r=0>n?n+t:n;t>++r;)e.push(r);return e})}};for(w in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})C.pseudos[w]=u(w);for(w in{submit:!0,reset:!0})C.pseudos[w]=l(w);S=a.compile=function(e,t){var n,r=[],i=[],o=U[e+" "];if(!o){for(t||(t=f(e)),n=t.length;n--;)o=y(t[n]),o[P]?r.push(o):i.push(o);o=U(e,v(i,r))}return o},C.pseudos.nth=C.pseudos.eq,C.filters=T.prototype=C.pseudos,C.setFilters=new T,D(),a.attr=st.attr,st.find=a,st.expr=a.selectors,st.expr[":"]=st.expr.pseudos,st.unique=a.uniqueSort,st.text=a.getText,st.isXMLDoc=a.isXML,st.contains=a.contains}(e);var Pt=/Until$/,Rt=/^(?:parents|prev(?:Until|All))/,Wt=/^.[^:#\[\.,]*$/,$t=st.expr.match.needsContext,It={children:!0,contents:!0,next:!0,prev:!0};st.fn.extend({find:function(e){var t,n,r;if("string"!=typeof e)return r=this,this.pushStack(st(e).filter(function(){for(t=0;r.length>t;t++)if(st.contains(r[t],this))return!0}));for(n=[],t=0;this.length>t;t++)st.find(e,this[t],n);return n=this.pushStack(st.unique(n)),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t,n=st(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(st.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(f(this,e,!1))},filter:function(e){return this.pushStack(f(this,e,!0))},is:function(e){return!!e&&("string"==typeof e?$t.test(e)?st(e,this.context).index(this[0])>=0:st.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){for(var n,r=0,i=this.length,o=[],a=$t.test(e)||"string"!=typeof e?st(e,t||this.context):0;i>r;r++)for(n=this[r];n&&n.ownerDocument&&n!==t&&11!==n.nodeType;){if(a?a.index(n)>-1:st.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}return this.pushStack(o.length>1?st.unique(o):o)},index:function(e){return e?"string"==typeof e?st.inArray(this[0],st(e)):st.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?st(e,t):st.makeArray(e&&e.nodeType?[e]:e),r=st.merge(this.get(),n);return this.pushStack(st.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),st.fn.andSelf=st.fn.addBack,st.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return st.dir(e,"parentNode")},parentsUntil:function(e,t,n){return st.dir(e,"parentNode",n)},next:function(e){return c(e,"nextSibling")},prev:function(e){return c(e,"previousSibling")
3
+},nextAll:function(e){return st.dir(e,"nextSibling")},prevAll:function(e){return st.dir(e,"previousSibling")},nextUntil:function(e,t,n){return st.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return st.dir(e,"previousSibling",n)},siblings:function(e){return st.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return st.sibling(e.firstChild)},contents:function(e){return st.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:st.merge([],e.childNodes)}},function(e,t){st.fn[e]=function(n,r){var i=st.map(this,t,n);return Pt.test(e)||(r=n),r&&"string"==typeof r&&(i=st.filter(r,i)),i=this.length>1&&!It[e]?st.unique(i):i,this.length>1&&Rt.test(e)&&(i=i.reverse()),this.pushStack(i)}}),st.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?st.find.matchesSelector(t[0],e)?[t[0]]:[]:st.find.matches(e,t)},dir:function(e,n,r){for(var i=[],o=e[n];o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!st(o).is(r));)1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});var zt="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",Xt=/ jQuery\d+="(?:null|\d+)"/g,Ut=RegExp("<(?:"+zt+")[\\s/>]","i"),Vt=/^\s+/,Yt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,Jt=/<([\w:]+)/,Gt=/<tbody/i,Qt=/<|&#?\w+;/,Kt=/<(?:script|style|link)/i,Zt=/^(?:checkbox|radio)$/i,en=/checked\s*(?:[^=]|=\s*.checked.)/i,tn=/^$|\/(?:java|ecma)script/i,nn=/^true\/(.*)/,rn=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,on={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:st.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},an=p(V),sn=an.appendChild(V.createElement("div"));on.optgroup=on.option,on.tbody=on.tfoot=on.colgroup=on.caption=on.thead,on.th=on.td,st.fn.extend({text:function(e){return st.access(this,function(e){return e===t?st.text(this):this.empty().append((this[0]&&this[0].ownerDocument||V).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(st.isFunction(e))return this.each(function(t){st(this).wrapAll(e.call(this,t))});if(this[0]){var t=st(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstChild&&1===e.firstChild.nodeType;)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return st.isFunction(e)?this.each(function(t){st(this).wrapInner(e.call(this,t))}):this.each(function(){var t=st(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=st.isFunction(e);return this.each(function(n){st(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){st.nodeName(this,"body")||st(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){for(var n,r=0;null!=(n=this[r]);r++)(!e||st.filter(e,[n]).length>0)&&(t||1!==n.nodeType||st.cleanData(b(n)),n.parentNode&&(t&&st.contains(n.ownerDocument,n)&&m(b(n,"script")),n.parentNode.removeChild(n)));return this},empty:function(){for(var e,t=0;null!=(e=this[t]);t++){for(1===e.nodeType&&st.cleanData(b(e,!1));e.firstChild;)e.removeChild(e.firstChild);e.options&&st.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return st.clone(this,e,t)})},html:function(e){return st.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(Xt,""):t;if(!("string"!=typeof e||Kt.test(e)||!st.support.htmlSerialize&&Ut.test(e)||!st.support.leadingWhitespace&&Vt.test(e)||on[(Jt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(Yt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(st.cleanData(b(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){var t=st.isFunction(e);return t||"string"==typeof e||(e=st(e).not(this).detach()),this.domManip([e],!0,function(e){var t=this.nextSibling,n=this.parentNode;(n&&1===this.nodeType||11===this.nodeType)&&(st(this).remove(),t?t.parentNode.insertBefore(e,t):n.appendChild(e))})},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=et.apply([],e);var i,o,a,s,u,l,c=0,f=this.length,p=this,m=f-1,y=e[0],v=st.isFunction(y);if(v||!(1>=f||"string"!=typeof y||st.support.checkClone)&&en.test(y))return this.each(function(i){var o=p.eq(i);v&&(e[0]=y.call(this,i,n?o.html():t)),o.domManip(e,n,r)});if(f&&(i=st.buildFragment(e,this[0].ownerDocument,!1,this),o=i.firstChild,1===i.childNodes.length&&(i=o),o)){for(n=n&&st.nodeName(o,"tr"),a=st.map(b(i,"script"),h),s=a.length;f>c;c++)u=i,c!==m&&(u=st.clone(u,!0,!0),s&&st.merge(a,b(u,"script"))),r.call(n&&st.nodeName(this[c],"table")?d(this[c],"tbody"):this[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,st.map(a,g),c=0;s>c;c++)u=a[c],tn.test(u.type||"")&&!st._data(u,"globalEval")&&st.contains(l,u)&&(u.src?st.ajax({url:u.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):st.globalEval((u.text||u.textContent||u.innerHTML||"").replace(rn,"")));i=o=null}return this}}),st.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){st.fn[e]=function(e){for(var n,r=0,i=[],o=st(e),a=o.length-1;a>=r;r++)n=r===a?this:this.clone(!0),st(o[r])[t](n),tt.apply(i,n.get());return this.pushStack(i)}}),st.extend({clone:function(e,t,n){var r,i,o,a,s,u=st.contains(e.ownerDocument,e);if(st.support.html5Clone||st.isXMLDoc(e)||!Ut.test("<"+e.nodeName+">")?s=e.cloneNode(!0):(sn.innerHTML=e.outerHTML,sn.removeChild(s=sn.firstChild)),!(st.support.noCloneEvent&&st.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||st.isXMLDoc(e)))for(r=b(s),i=b(e),a=0;null!=(o=i[a]);++a)r[a]&&v(o,r[a]);if(t)if(n)for(i=i||b(e),r=r||b(s),a=0;null!=(o=i[a]);a++)y(o,r[a]);else y(e,s);return r=b(s,"script"),r.length>0&&m(r,!u&&b(e,"script")),r=i=o=null,s},buildFragment:function(e,t,n,r){for(var i,o,a,s,u,l,c,f=e.length,d=p(t),h=[],g=0;f>g;g++)if(o=e[g],o||0===o)if("object"===st.type(o))st.merge(h,o.nodeType?[o]:o);else if(Qt.test(o)){for(s=s||d.appendChild(t.createElement("div")),a=(Jt.exec(o)||["",""])[1].toLowerCase(),u=on[a]||on._default,s.innerHTML=u[1]+o.replace(Yt,"<$1></$2>")+u[2],c=u[0];c--;)s=s.lastChild;if(!st.support.leadingWhitespace&&Vt.test(o)&&h.push(t.createTextNode(Vt.exec(o)[0])),!st.support.tbody)for(o="table"!==a||Gt.test(o)?"<table>"!==u[1]||Gt.test(o)?0:s:s.firstChild,c=o&&o.childNodes.length;c--;)st.nodeName(l=o.childNodes[c],"tbody")&&!l.childNodes.length&&o.removeChild(l);for(st.merge(h,s.childNodes),s.textContent="";s.firstChild;)s.removeChild(s.firstChild);s=d.lastChild}else h.push(t.createTextNode(o));for(s&&d.removeChild(s),st.support.appendChecked||st.grep(b(h,"input"),x),g=0;o=h[g++];)if((!r||-1===st.inArray(o,r))&&(i=st.contains(o.ownerDocument,o),s=b(d.appendChild(o),"script"),i&&m(s),n))for(c=0;o=s[c++];)tn.test(o.type||"")&&n.push(o);return s=null,d},cleanData:function(e,n){for(var r,i,o,a,s=0,u=st.expando,l=st.cache,c=st.support.deleteExpando,f=st.event.special;null!=(o=e[s]);s++)if((n||st.acceptData(o))&&(i=o[u],r=i&&l[i])){if(r.events)for(a in r.events)f[a]?st.event.remove(o,a):st.removeEvent(o,a,r.handle);l[i]&&(delete l[i],c?delete o[u]:o.removeAttribute!==t?o.removeAttribute(u):o[u]=null,K.push(i))}}});var un,ln,cn,fn=/alpha\([^)]*\)/i,pn=/opacity\s*=\s*([^)]*)/,dn=/^(top|right|bottom|left)$/,hn=/^(none|table(?!-c[ea]).+)/,gn=/^margin/,mn=RegExp("^("+ut+")(.*)$","i"),yn=RegExp("^("+ut+")(?!px)[a-z%]+$","i"),vn=RegExp("^([+-])=("+ut+")","i"),bn={BODY:"block"},xn={position:"absolute",visibility:"hidden",display:"block"},Tn={letterSpacing:0,fontWeight:400},wn=["Top","Right","Bottom","Left"],Nn=["Webkit","O","Moz","ms"];st.fn.extend({css:function(e,n){return st.access(this,function(e,n,r){var i,o,a={},s=0;if(st.isArray(n)){for(i=ln(e),o=n.length;o>s;s++)a[n[s]]=st.css(e,n[s],!1,i);return a}return r!==t?st.style(e,n,r):st.css(e,n)},e,n,arguments.length>1)},show:function(){return N(this,!0)},hide:function(){return N(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:w(this))?st(this).show():st(this).hide()})}}),st.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=un(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":st.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=st.camelCase(n),l=e.style;if(n=st.cssProps[u]||(st.cssProps[u]=T(l,u)),s=st.cssHooks[n]||st.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=vn.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(st.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||st.cssNumber[u]||(r+="px"),st.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=st.camelCase(n);return n=st.cssProps[u]||(st.cssProps[u]=T(e.style,u)),s=st.cssHooks[n]||st.cssHooks[u],s&&"get"in s&&(o=s.get(e,!0,r)),o===t&&(o=un(e,n,i)),"normal"===o&&n in Tn&&(o=Tn[n]),r?(a=parseFloat(o),r===!0||st.isNumeric(a)?a||0:o):o},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(ln=function(t){return e.getComputedStyle(t,null)},un=function(e,n,r){var i,o,a,s=r||ln(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||st.contains(e.ownerDocument,e)||(u=st.style(e,n)),yn.test(u)&&gn.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):V.documentElement.currentStyle&&(ln=function(e){return e.currentStyle},un=function(e,n,r){var i,o,a,s=r||ln(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),yn.test(u)&&!dn.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u}),st.each(["height","width"],function(e,n){st.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&hn.test(st.css(e,"display"))?st.swap(e,xn,function(){return E(e,n,i)}):E(e,n,i):t},set:function(e,t,r){var i=r&&ln(e);return C(e,t,r?k(e,n,r,st.support.boxSizing&&"border-box"===st.css(e,"boxSizing",!1,i),i):0)}}}),st.support.opacity||(st.cssHooks.opacity={get:function(e,t){return pn.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=st.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===st.trim(o.replace(fn,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=fn.test(o)?o.replace(fn,i):o+" "+i)}}),st(function(){st.support.reliableMarginRight||(st.cssHooks.marginRight={get:function(e,n){return n?st.swap(e,{display:"inline-block"},un,[e,"marginRight"]):t}}),!st.support.pixelPosition&&st.fn.position&&st.each(["top","left"],function(e,n){st.cssHooks[n]={get:function(e,r){return r?(r=un(e,n),yn.test(r)?st(e).position()[n]+"px":r):t}}})}),st.expr&&st.expr.filters&&(st.expr.filters.hidden=function(e){return 0===e.offsetWidth&&0===e.offsetHeight||!st.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||st.css(e,"display"))},st.expr.filters.visible=function(e){return!st.expr.filters.hidden(e)}),st.each({margin:"",padding:"",border:"Width"},function(e,t){st.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];4>r;r++)i[e+wn[r]+t]=o[r]||o[r-2]||o[0];return i}},gn.test(e)||(st.cssHooks[e+t].set=C)});var Cn=/%20/g,kn=/\[\]$/,En=/\r?\n/g,Sn=/^(?:submit|button|image|reset)$/i,An=/^(?:input|select|textarea|keygen)/i;st.fn.extend({serialize:function(){return st.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=st.prop(this,"elements");return e?st.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!st(this).is(":disabled")&&An.test(this.nodeName)&&!Sn.test(e)&&(this.checked||!Zt.test(e))}).map(function(e,t){var n=st(this).val();return null==n?null:st.isArray(n)?st.map(n,function(e){return{name:t.name,value:e.replace(En,"\r\n")}}):{name:t.name,value:n.replace(En,"\r\n")}}).get()}}),st.param=function(e,n){var r,i=[],o=function(e,t){t=st.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=st.ajaxSettings&&st.ajaxSettings.traditional),st.isArray(e)||e.jquery&&!st.isPlainObject(e))st.each(e,function(){o(this.name,this.value)});else for(r in e)j(r,e[r],n,o);return i.join("&").replace(Cn,"+")};var jn,Dn,Ln=st.now(),Hn=/\?/,Mn=/#.*$/,qn=/([?&])_=[^&]*/,_n=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Fn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,On=/^(?:GET|HEAD)$/,Bn=/^\/\//,Pn=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Rn=st.fn.load,Wn={},$n={},In="*/".concat("*");try{Dn=Y.href}catch(zn){Dn=V.createElement("a"),Dn.href="",Dn=Dn.href}jn=Pn.exec(Dn.toLowerCase())||[],st.fn.load=function(e,n,r){if("string"!=typeof e&&Rn)return Rn.apply(this,arguments);var i,o,a,s=this,u=e.indexOf(" ");return u>=0&&(i=e.slice(u,e.length),e=e.slice(0,u)),st.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(o="POST"),s.length>0&&st.ajax({url:e,type:o,dataType:"html",data:n}).done(function(e){a=arguments,s.html(i?st("<div>").append(st.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,a||[e.responseText,t,e])}),this},st.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){st.fn[t]=function(e){return this.on(t,e)}}),st.each(["get","post"],function(e,n){st[n]=function(e,r,i,o){return st.isFunction(r)&&(o=o||i,i=r,r=t),st.ajax({url:e,type:n,dataType:o,data:r,success:i})}}),st.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Dn,type:"GET",isLocal:Fn.test(jn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":In,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":st.parseJSON,"text xml":st.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?H(H(e,st.ajaxSettings),t):H(st.ajaxSettings,e)},ajaxPrefilter:D(Wn),ajaxTransport:D($n),ajax:function(e,n){function r(e,n,r,s){var l,f,v,b,T,N=n;2!==x&&(x=2,u&&clearTimeout(u),i=t,a=s||"",w.readyState=e>0?4:0,r&&(b=M(p,w,r)),e>=200&&300>e||304===e?(p.ifModified&&(T=w.getResponseHeader("Last-Modified"),T&&(st.lastModified[o]=T),T=w.getResponseHeader("etag"),T&&(st.etag[o]=T)),304===e?(l=!0,N="notmodified"):(l=q(p,b),N=l.state,f=l.data,v=l.error,l=!v)):(v=N,(e||!N)&&(N="error",0>e&&(e=0))),w.status=e,w.statusText=(n||N)+"",l?g.resolveWith(d,[f,N,w]):g.rejectWith(d,[w,N,v]),w.statusCode(y),y=t,c&&h.trigger(l?"ajaxSuccess":"ajaxError",[w,p,l?f:v]),m.fireWith(d,[w,N]),c&&(h.trigger("ajaxComplete",[w,p]),--st.active||st.event.trigger("ajaxStop")))}"object"==typeof e&&(n=e,e=t),n=n||{};var i,o,a,s,u,l,c,f,p=st.ajaxSetup({},n),d=p.context||p,h=p.context&&(d.nodeType||d.jquery)?st(d):st.event,g=st.Deferred(),m=st.Callbacks("once memory"),y=p.statusCode||{},v={},b={},x=0,T="canceled",w={readyState:0,getResponseHeader:function(e){var t;if(2===x){if(!s)for(s={};t=_n.exec(a);)s[t[1].toLowerCase()]=t[2];t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===x?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return x||(e=b[n]=b[n]||e,v[e]=t),this},overrideMimeType:function(e){return x||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>x)for(t in e)y[t]=[y[t],e[t]];else w.always(e[w.status]);return this},abort:function(e){var t=e||T;return i&&i.abort(t),r(0,t),this}};if(g.promise(w).complete=m.add,w.success=w.done,w.error=w.fail,p.url=((e||p.url||Dn)+"").replace(Mn,"").replace(Bn,jn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=st.trim(p.dataType||"*").toLowerCase().match(lt)||[""],null==p.crossDomain&&(l=Pn.exec(p.url.toLowerCase()),p.crossDomain=!(!l||l[1]===jn[1]&&l[2]===jn[2]&&(l[3]||("http:"===l[1]?80:443))==(jn[3]||("http:"===jn[1]?80:443)))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=st.param(p.data,p.traditional)),L(Wn,p,n,w),2===x)return w;c=p.global,c&&0===st.active++&&st.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!On.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(Hn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=qn.test(o)?o.replace(qn,"$1_="+Ln++):o+(Hn.test(o)?"&":"?")+"_="+Ln++)),p.ifModified&&(st.lastModified[o]&&w.setRequestHeader("If-Modified-Since",st.lastModified[o]),st.etag[o]&&w.setRequestHeader("If-None-Match",st.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&w.setRequestHeader("Content-Type",p.contentType),w.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+In+"; q=0.01":""):p.accepts["*"]);for(f in p.headers)w.setRequestHeader(f,p.headers[f]);if(p.beforeSend&&(p.beforeSend.call(d,w,p)===!1||2===x))return w.abort();T="abort";for(f in{success:1,error:1,complete:1})w[f](p[f]);if(i=L($n,p,n,w)){w.readyState=1,c&&h.trigger("ajaxSend",[w,p]),p.async&&p.timeout>0&&(u=setTimeout(function(){w.abort("timeout")},p.timeout));try{x=1,i.send(v,r)}catch(N){if(!(2>x))throw N;r(-1,N)}}else r(-1,"No Transport");return w},getScript:function(e,n){return st.get(e,t,n,"script")},getJSON:function(e,t,n){return st.get(e,t,n,"json")}}),st.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return st.globalEval(e),e}}}),st.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),st.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=V.head||st("head")[0]||V.documentElement;return{send:function(t,i){n=V.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var Xn=[],Un=/(=)\?(?=&|$)|\?\?/;st.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xn.pop()||st.expando+"_"+Ln++;return this[e]=!0,e}}),st.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,u=n.jsonp!==!1&&(Un.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Un.test(n.data)&&"data");return u||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=st.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,u?n[u]=n[u].replace(Un,"$1"+o):n.jsonp!==!1&&(n.url+=(Hn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||st.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,Xn.push(o)),s&&st.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Vn,Yn,Jn=0,Gn=e.ActiveXObject&&function(){var e;for(e in Vn)Vn[e](t,!0)};st.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&_()||F()}:_,Yn=st.ajaxSettings.xhr(),st.support.cors=!!Yn&&"withCredentials"in Yn,Yn=st.support.ajax=!!Yn,Yn&&st.ajaxTransport(function(n){if(!n.crossDomain||st.support.cors){var r;return{send:function(i,o){var a,s,u=n.xhr();if(n.username?u.open(n.type,n.url,n.async,n.username,n.password):u.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)u[s]=n.xhrFields[s];n.mimeType&&u.overrideMimeType&&u.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)u.setRequestHeader(s,i[s])}catch(l){}u.send(n.hasContent&&n.data||null),r=function(e,i){var s,l,c,f,p;try{if(r&&(i||4===u.readyState))if(r=t,a&&(u.onreadystatechange=st.noop,Gn&&delete Vn[a]),i)4!==u.readyState&&u.abort();else{f={},s=u.status,p=u.responseXML,c=u.getAllResponseHeaders(),p&&p.documentElement&&(f.xml=p),"string"==typeof u.responseText&&(f.text=u.responseText);try{l=u.statusText}catch(d){l=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=f.text?200:404}}catch(h){i||o(-1,h)}f&&o(s,l,f,c)},n.async?4===u.readyState?setTimeout(r):(a=++Jn,Gn&&(Vn||(Vn={},st(e).unload(Gn)),Vn[a]=r),u.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Qn,Kn,Zn=/^(?:toggle|show|hide)$/,er=RegExp("^(?:([+-])=|)("+ut+")([a-z%]*)$","i"),tr=/queueHooks$/,nr=[W],rr={"*":[function(e,t){var n,r,i=this.createTween(e,t),o=er.exec(t),a=i.cur(),s=+a||0,u=1,l=20;if(o){if(n=+o[2],r=o[3]||(st.cssNumber[e]?"":"px"),"px"!==r&&s){s=st.css(i.elem,e,!0)||n||1;do u=u||".5",s/=u,st.style(i.elem,e,s+r);while(u!==(u=i.cur()/a)&&1!==u&&--l)}i.unit=r,i.start=s,i.end=o[1]?s+(o[1]+1)*n:n}return i}]};st.Animation=st.extend(P,{tweener:function(e,t){st.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");for(var n,r=0,i=e.length;i>r;r++)n=e[r],rr[n]=rr[n]||[],rr[n].unshift(t)},prefilter:function(e,t){t?nr.unshift(e):nr.push(e)}}),st.Tween=$,$.prototype={constructor:$,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(st.cssNumber[n]?"":"px")},cur:function(){var e=$.propHooks[this.prop];return e&&e.get?e.get(this):$.propHooks._default.get(this)},run:function(e){var t,n=$.propHooks[this.prop];return this.pos=t=this.options.duration?st.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):$.propHooks._default.set(this),this}},$.prototype.init.prototype=$.prototype,$.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=st.css(e.elem,e.prop,"auto"),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){st.fx.step[e.prop]?st.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[st.cssProps[e.prop]]||st.cssHooks[e.prop])?st.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},$.propHooks.scrollTop=$.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},st.each(["toggle","show","hide"],function(e,t){var n=st.fn[t];st.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(I(t,!0),e,r,i)}}),st.fn.extend({fadeTo:function(e,t,n,r){return this.filter(w).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=st.isEmptyObject(e),o=st.speed(t,n,r),a=function(){var t=P(this,st.extend({},e),o);a.finish=function(){t.stop(!0)},(i||st._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=st.timers,a=st._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&tr.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&st.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=st._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=st.timers,a=r?r.length:0;for(n.finish=!0,st.queue(this,e,[]),i&&i.cur&&i.cur.finish&&i.cur.finish.call(this),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),st.each({slideDown:I("show"),slideUp:I("hide"),slideToggle:I("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){st.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),st.speed=function(e,t,n){var r=e&&"object"==typeof e?st.extend({},e):{complete:n||!n&&t||st.isFunction(e)&&e,duration:e,easing:n&&t||t&&!st.isFunction(t)&&t};return r.duration=st.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in st.fx.speeds?st.fx.speeds[r.duration]:st.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){st.isFunction(r.old)&&r.old.call(this),r.queue&&st.dequeue(this,r.queue)},r},st.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},st.timers=[],st.fx=$.prototype.init,st.fx.tick=function(){var e,n=st.timers,r=0;for(Qn=st.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||st.fx.stop(),Qn=t},st.fx.timer=function(e){e()&&st.timers.push(e)&&st.fx.start()},st.fx.interval=13,st.fx.start=function(){Kn||(Kn=setInterval(st.fx.tick,st.fx.interval))},st.fx.stop=function(){clearInterval(Kn),Kn=null},st.fx.speeds={slow:600,fast:200,_default:400},st.fx.step={},st.expr&&st.expr.filters&&(st.expr.filters.animated=function(e){return st.grep(st.timers,function(t){return e===t.elem}).length}),st.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){st.offset.setOffset(this,e,t)});var n,r,i={top:0,left:0},o=this[0],a=o&&o.ownerDocument;if(a)return n=a.documentElement,st.contains(n,o)?(o.getBoundingClientRect!==t&&(i=o.getBoundingClientRect()),r=z(a),{top:i.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:i.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):i},st.offset={setOffset:function(e,t,n){var r=st.css(e,"position");"static"===r&&(e.style.position="relative");var i,o,a=st(e),s=a.offset(),u=st.css(e,"top"),l=st.css(e,"left"),c=("absolute"===r||"fixed"===r)&&st.inArray("auto",[u,l])>-1,f={},p={};c?(p=a.position(),i=p.top,o=p.left):(i=parseFloat(u)||0,o=parseFloat(l)||0),st.isFunction(t)&&(t=t.call(e,n,s)),null!=t.top&&(f.top=t.top-s.top+i),null!=t.left&&(f.left=t.left-s.left+o),"using"in t?t.using.call(e,f):a.css(f)}},st.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===st.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),st.nodeName(e[0],"html")||(n=e.offset()),n.top+=st.css(e[0],"borderTopWidth",!0),n.left+=st.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-st.css(r,"marginTop",!0),left:t.left-n.left-st.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent||V.documentElement;e&&!st.nodeName(e,"html")&&"static"===st.css(e,"position");)e=e.offsetParent;return e||V.documentElement})}}),st.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);st.fn[e]=function(i){return st.access(this,function(e,i,o){var a=z(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?st(a).scrollLeft():o,r?o:st(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}}),st.each({Height:"height",Width:"width"},function(e,n){st.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){st.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return st.access(this,function(n,r,i){var o;return st.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?st.css(n,r,s):st.style(n,r,i,s)},n,a?i:t,a,null)}})}),e.jQuery=e.$=st,"function"==typeof define&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return st})})(window);
4
+//@ sourceMappingURL=jquery.min.map
BIN
mojolegacy/lib/Mojolicious/public/mojo/logo-black.png
BIN
mojolegacy/lib/Mojolicious/public/mojo/logo-white.png
BIN
mojolegacy/lib/Mojolicious/public/mojo/noraptor.png
BIN
mojolegacy/lib/Mojolicious/public/mojo/notfound.png
BIN
mojolegacy/lib/Mojolicious/public/mojo/pinstripe.gif
+2
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-apollo.js
... ...
@@ -0,0 +1,2 @@
1
+PR.registerLangHandler(PR.createSimpleLexer([["com",/^#[^\n\r]*/,null,"#"],["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r �\xa0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,null,'"']],[["kwd",/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/,
2
+null],["typ",/^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[ES]?BANK=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null],["lit",/^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[!-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["apollo","agc","aea"]);
+18
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-clj.js
... ...
@@ -0,0 +1,18 @@
1
+/*
2
+ Copyright (C) 2011 Google Inc.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+*/
16
+var a=null;
17
+PR.registerLangHandler(PR.createSimpleLexer([["opn",/^[([{]+/,a,"([{"],["clo",/^[)\]}]+/,a,")]}"],["com",/^;[^\n\r]*/,a,";"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \xa0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:def|if|do|let|quote|var|fn|loop|recur|throw|try|monitor-enter|monitor-exit|defmacro|defn|defn-|macroexpand|macroexpand-1|for|doseq|dosync|dotimes|and|or|when|not|assert|doto|proxy|defstruct|first|rest|cons|defprotocol|deftype|defrecord|reify|defmulti|defmethod|meta|with-meta|ns|in-ns|create-ns|import|intern|refer|alias|namespace|resolve|ref|deref|refset|new|set!|memfn|to-array|into-array|aset|gen-class|reduce|map|filter|find|nil?|empty?|hash-map|hash-set|vec|vector|seq|flatten|reverse|assoc|dissoc|list|list?|disj|get|union|difference|intersection|extend|extend-type|extend-protocol|prn)\b/,a],
18
+["typ",/^:[\dA-Za-z-]+/]]),["clj"]);
+2
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-css.js
... ...
@@ -0,0 +1,2 @@
1
+PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com",
2
+/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);
+1
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-go.js
... ...
@@ -0,0 +1 @@
1
+PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r �\xa0"],["pln",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])+(?:'|$)|`[^`]*(?:`|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\n\r]*|\/\*[\S\s]*?\*\/)/],["pln",/^(?:[^"'/`]|\/(?![*/]))+/]]),["go"]);
+2
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-hs.js
... ...
@@ -0,0 +1,2 @@
1
+PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t-\r ]+/,null,"\t\n\r "],["str",/^"(?:[^\n\f\r"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["str",/^'(?:[^\n\f\r'\\]|\\[^&])'?/,null,"'"],["lit",/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,null,"0123456789"]],[["com",/^(?:--+[^\n\f\r]*|{-(?:[^-]|-+[^}-])*-})/],["kwd",/^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^\d'A-Za-z]|$)/,
2
+null],["pln",/^(?:[A-Z][\w']*\.)*[A-Za-z][\w']*/],["pun",/^[^\d\t-\r "'A-Za-z]+/]]),["hs"]);
+3
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-lisp.js
... ...
@@ -0,0 +1,3 @@
1
+var a=null;
2
+PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,a,"("],["clo",/^\)+/,a,")"],["com",/^;[^\n\r]*/,a,";"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \xa0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,a],
3
+["lit",/^[+-]?(?:[#0]x[\da-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[de][+-]?\d+)?)/i],["lit",/^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[_a-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/i],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["cl","el","lisp","scm"]);
+2
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-lua.js
... ...
@@ -0,0 +1,2 @@
1
+PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r �\xa0"],["str",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$))/,null,"\"'"]],[["com",/^--(?:\[(=*)\[[\S\s]*?(?:]\1]|$)|[^\n\r]*)/],["str",/^\[(=*)\[[\S\s]*?(?:]\1]|$)/],["kwd",/^(?:and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,null],["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i],
2
+["pln",/^[_a-z]\w*/i],["pun",/^[^\w\t\n\r \xa0][^\w\t\n\r "'+=\xa0-]*/]]),["lua"]);
+2
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-ml.js
... ...
@@ -0,0 +1,2 @@
1
+PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r �\xa0"],["com",/^#(?:if[\t\n\r \xa0]+(?:[$_a-z][\w']*|``[^\t\n\r`]*(?:``|$))|else|endif|light)/i,null,"#"],["str",/^(?:"(?:[^"\\]|\\[\S\s])*(?:"|$)|'(?:[^'\\]|\\[\S\s])(?:'|$))/,null,"\"'"]],[["com",/^(?:\/\/[^\n\r]*|\(\*[\S\s]*?\*\))/],["kwd",/^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/],
2
+["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i],["pln",/^(?:[_a-z][\w']*[!#?]?|``[^\t\n\r`]*(?:``|$))/i],["pun",/^[^\w\t\n\r "'\xa0]+/]]),["fs","ml"]);
+4
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-n.js
... ...
@@ -0,0 +1,4 @@
1
+var a=null;
2
+PR.registerLangHandler(PR.createSimpleLexer([["str",/^(?:'(?:[^\n\r'\\]|\\.)*'|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,a,'"'],["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,a,"#"],["pln",/^\s+/,a," \r\n\t\xa0"]],[["str",/^@"(?:[^"]|"")*(?:"|$)/,a],["str",/^<#[^#>]*(?:#>|$)/,a],["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,a],["com",/^\/\/[^\n\r]*/,a],["com",/^\/\*[\S\s]*?(?:\*\/|$)/,
3
+a],["kwd",/^(?:abstract|and|as|base|catch|class|def|delegate|enum|event|extern|false|finally|fun|implements|interface|internal|is|macro|match|matches|module|mutable|namespace|new|null|out|override|params|partial|private|protected|public|ref|sealed|static|struct|syntax|this|throw|true|try|type|typeof|using|variant|virtual|volatile|when|where|with|assert|assert2|async|break|checked|continue|do|else|ensures|for|foreach|if|late|lock|new|nolate|otherwise|regexp|repeat|requires|return|surroundwith|unchecked|unless|using|while|yield)\b/,
4
+a],["typ",/^(?:array|bool|byte|char|decimal|double|float|int|list|long|object|sbyte|short|string|ulong|uint|ufloat|ulong|ushort|void)\b/,a],["lit",/^@[$_a-z][\w$@]*/i,a],["typ",/^@[A-Z]+[a-z][\w$@]*/,a],["pln",/^'?[$_a-z][\w$@]*/i,a],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,a,"0123456789"],["pun",/^.[^\s\w"-$'./@`]*/,a]]),["n","nemerle"]);
+1
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-proto.js
... ...
@@ -0,0 +1 @@
1
+PR.registerLangHandler(PR.sourceDecorator({keywords:"bytes,default,double,enum,extend,extensions,false,group,import,max,message,option,optional,package,repeated,required,returns,rpc,service,syntax,to,true",types:/^(bool|(double|s?fixed|[su]?int)(32|64)|float|string)\b/,cStyleComments:!0}),["proto"]);
+2
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-scala.js
... ...
@@ -0,0 +1,2 @@
1
+PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r �\xa0"],["str",/^"(?:""(?:""?(?!")|[^"\\]|\\.)*"{0,3}|(?:[^\n\r"\\]|\\.)*"?)/,null,'"'],["lit",/^`(?:[^\n\r\\`]|\\.)*`?/,null,"`"],["pun",/^[!#%&(--:-@[-^{-~]+/,null,"!#%&()*+,-:;<=>?@[\\]^{|}~"]],[["str",/^'(?:[^\n\r'\\]|\\(?:'|[^\n\r']+))'/],["lit",/^'[$A-Z_a-z][\w$]*(?![\w$'])/],["kwd",/^(?:abstract|case|catch|class|def|do|else|extends|final|finally|for|forSome|if|implicit|import|lazy|match|new|object|override|package|private|protected|requires|return|sealed|super|throw|trait|try|type|val|var|while|with|yield)\b/],
2
+["lit",/^(?:true|false|null|this)\b/],["lit",/^(?:0(?:[0-7]+|x[\da-f]+)l?|(?:0|[1-9]\d*)(?:(?:\.\d+)?(?:e[+-]?\d+)?f?|l?)|\\.\d+(?:e[+-]?\d+)?f?)/i],["typ",/^[$_]*[A-Z][\d$A-Z_]*[a-z][\w$]*/],["pln",/^[$A-Z_a-z][\w$]*/],["com",/^\/(?:\/.*|\*(?:\/|\**[^*/])*(?:\*+\/?)?)/],["pun",/^(?:\.+|\/)/]]),["scala"]);
+2
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-sql.js
... ...
@@ -0,0 +1,2 @@
1
+PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r �\xa0"],["str",/^(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')/,null,"\"'"]],[["com",/^(?:--[^\n\r]*|\/\*[\S\s]*?(?:\*\/|$))/],["kwd",/^(?:add|all|alter|and|any|as|asc|authorization|backup|begin|between|break|browse|bulk|by|cascade|case|check|checkpoint|close|clustered|coalesce|collate|column|commit|compute|constraint|contains|containstable|continue|convert|create|cross|current|current_date|current_time|current_timestamp|current_user|cursor|database|dbcc|deallocate|declare|default|delete|deny|desc|disk|distinct|distributed|double|drop|dummy|dump|else|end|errlvl|escape|except|exec|execute|exists|exit|fetch|file|fillfactor|for|foreign|freetext|freetexttable|from|full|function|goto|grant|group|having|holdlock|identity|identitycol|identity_insert|if|in|index|inner|insert|intersect|into|is|join|key|kill|left|like|lineno|load|match|merge|national|nocheck|nonclustered|not|null|nullif|of|off|offsets|on|open|opendatasource|openquery|openrowset|openxml|option|or|order|outer|over|percent|plan|precision|primary|print|proc|procedure|public|raiserror|read|readtext|reconfigure|references|replication|restore|restrict|return|revoke|right|rollback|rowcount|rowguidcol|rule|save|schema|select|session_user|set|setuser|shutdown|some|statistics|system_user|table|textsize|then|to|top|tran|transaction|trigger|truncate|tsequal|union|unique|update|updatetext|use|user|using|values|varying|view|waitfor|when|where|while|with|writetext)(?=[^\w-]|$)/i,
2
+null],["lit",/^[+-]?(?:0x[\da-f]+|(?:\.\d+|\d+(?:\.\d*)?)(?:e[+-]?\d+)?)/i],["pln",/^[_a-z][\w-]*/i],["pun",/^[^\w\t\n\r "'\xa0][^\w\t\n\r "'+\xa0-]*/]]),["sql"]);
+1
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-tex.js
... ...
@@ -0,0 +1 @@
1
+PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r �\xa0"],["com",/^%[^\n\r]*/,null,"%"]],[["kwd",/^\\[@-Za-z]+/],["kwd",/^\\./],["typ",/^[$&]/],["lit",/[+-]?(?:\.\d+|\d+(?:\.\d*)?)(cm|em|ex|in|pc|pt|bp|mm)/i],["pun",/^[()=[\]{}]+/]]),["latex","tex"]);
+2
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-vb.js
... ...
@@ -0,0 +1,2 @@
1
+PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0\u2028\u2029]+/,null,"\t\n\r �\xa0

"],["str",/^(?:["\u201c\u201d](?:[^"\u201c\u201d]|["\u201c\u201d]{2})(?:["\u201c\u201d]c|$)|["\u201c\u201d](?:[^"\u201c\u201d]|["\u201c\u201d]{2})*(?:["\u201c\u201d]|$))/i,null,'"“”'],["com",/^['\u2018\u2019].*/,null,"'‘’"]],[["kwd",/^(?:addhandler|addressof|alias|and|andalso|ansi|as|assembly|auto|boolean|byref|byte|byval|call|case|catch|cbool|cbyte|cchar|cdate|cdbl|cdec|char|cint|class|clng|cobj|const|cshort|csng|cstr|ctype|date|decimal|declare|default|delegate|dim|directcast|do|double|each|else|elseif|end|endif|enum|erase|error|event|exit|finally|for|friend|function|get|gettype|gosub|goto|handles|if|implements|imports|in|inherits|integer|interface|is|let|lib|like|long|loop|me|mod|module|mustinherit|mustoverride|mybase|myclass|namespace|new|next|not|notinheritable|notoverridable|object|on|option|optional|or|orelse|overloads|overridable|overrides|paramarray|preserve|private|property|protected|public|raiseevent|readonly|redim|removehandler|resume|return|select|set|shadows|shared|short|single|static|step|stop|string|structure|sub|synclock|then|throw|to|try|typeof|unicode|until|variant|wend|when|while|with|withevents|writeonly|xor|endif|gosub|let|variant|wend)\b/i,
2
+null],["com",/^rem.*/i],["lit",/^(?:true\b|false\b|nothing\b|\d+(?:e[+-]?\d+[dfr]?|[dfilrs])?|(?:&h[\da-f]+|&o[0-7]+)[ils]?|\d*\.\d+(?:e[+-]?\d+)?[dfr]?|#\s+(?:\d+[/-]\d+[/-]\d+(?:\s+\d+:\d+(?::\d+)?(\s*(?:am|pm))?)?|\d+:\d+(?::\d+)?(\s*(?:am|pm))?)\s+#)/i],["pln",/^(?:(?:[a-z]|_\w)\w*|\[(?:[a-z]|_\w)\w*])/i],["pun",/^[^\w\t\n\r "'[\]\xa0\u2018\u2019\u201c\u201d\u2028\u2029]+/],["pun",/^(?:\[|])/]]),["vb","vbs"]);
+3
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-vhdl.js
... ...
@@ -0,0 +1,3 @@
1
+PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xa0]+/,null,"\t\n\r �\xa0"]],[["str",/^(?:[box]?"(?:[^"]|"")*"|'.')/i],["com",/^--[^\n\r]*/],["kwd",/^(?:abs|access|after|alias|all|and|architecture|array|assert|attribute|begin|block|body|buffer|bus|case|component|configuration|constant|disconnect|downto|else|elsif|end|entity|exit|file|for|function|generate|generic|group|guarded|if|impure|in|inertial|inout|is|label|library|linkage|literal|loop|map|mod|nand|new|next|nor|not|null|of|on|open|or|others|out|package|port|postponed|procedure|process|pure|range|record|register|reject|rem|report|return|rol|ror|select|severity|shared|signal|sla|sll|sra|srl|subtype|then|to|transport|type|unaffected|units|until|use|variable|wait|when|while|with|xnor|xor)(?=[^\w-]|$)/i,
2
+null],["typ",/^(?:bit|bit_vector|character|boolean|integer|real|time|string|severity_level|positive|natural|signed|unsigned|line|text|std_u?logic(?:_vector)?)(?=[^\w-]|$)/i,null],["typ",/^'(?:active|ascending|base|delayed|driving|driving_value|event|high|image|instance_name|last_active|last_event|last_value|left|leftof|length|low|path_name|pos|pred|quiet|range|reverse_range|right|rightof|simple_name|stable|succ|transaction|val|value)(?=[^\w-]|$)/i,null],["lit",/^\d+(?:_\d+)*(?:#[\w.\\]+#(?:[+-]?\d+(?:_\d+)*)?|(?:\.\d+(?:_\d+)*)?(?:e[+-]?\d+(?:_\d+)*)?)/i],
3
+["pln",/^(?:[a-z]\w*|\\[^\\]*\\)/i],["pun",/^[^\w\t\n\r "'\xa0][^\w\t\n\r "'\xa0-]*/]]),["vhdl","vhd"]);
+2
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-wiki.js
... ...
@@ -0,0 +1,2 @@
1
+PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\d\t a-gi-z\xa0]+/,null,"\t �\xa0abcdefgijklmnopqrstuvwxyz0123456789"],["pun",/^[*=[\]^~]+/,null,"=*~^[]"]],[["lang-wiki.meta",/(?:^^|\r\n?|\n)(#[a-z]+)\b/],["lit",/^[A-Z][a-z][\da-z]+[A-Z][a-z][^\W_]+\b/],["lang-",/^{{{([\S\s]+?)}}}/],["lang-",/^`([^\n\r`]+)`/],["str",/^https?:\/\/[^\s#/?]*(?:\/[^\s#?]*)?(?:\?[^\s#]*)?(?:#\S*)?/i],["pln",/^(?:\r\n|[\S\s])[^\n\r#*=A-[^`h{~]*/]]),["wiki"]);
2
+PR.registerLangHandler(PR.createSimpleLexer([["kwd",/^#[a-z]+/i,null,"#"]],[]),["wiki.meta"]);
+3
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-xq.js
... ...
@@ -0,0 +1,3 @@
1
+PR.registerLangHandler(PR.createSimpleLexer([["var pln",/^\$[\w-]+/,null,"$"]],[["pln",/^[\s=][<>][\s=]/],["lit",/^@[\w-]+/],["tag",/^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["com",/^\(:[\S\s]*?:\)/],["pln",/^[(),/;[\]{}]$/],["str",/^(?:"(?:[^"\\{]|\\[\S\s])*(?:"|$)|'(?:[^'\\{]|\\[\S\s])*(?:'|$))/,null,"\"'"],["kwd",/^(?:xquery|where|version|variable|union|typeswitch|treat|to|then|text|stable|sortby|some|self|schema|satisfies|returns|return|ref|processing-instruction|preceding-sibling|preceding|precedes|parent|only|of|node|namespace|module|let|item|intersect|instance|in|import|if|function|for|follows|following-sibling|following|external|except|every|else|element|descending|descendant-or-self|descendant|define|default|declare|comment|child|cast|case|before|attribute|assert|ascending|as|ancestor-or-self|ancestor|after|eq|order|by|or|and|schema-element|document-node|node|at)\b/],
2
+["typ",/^(?:xs:yearMonthDuration|xs:unsignedLong|xs:time|xs:string|xs:short|xs:QName|xs:Name|xs:long|xs:integer|xs:int|xs:gYearMonth|xs:gYear|xs:gMonthDay|xs:gDay|xs:float|xs:duration|xs:double|xs:decimal|xs:dayTimeDuration|xs:dateTime|xs:date|xs:byte|xs:boolean|xs:anyURI|xf:yearMonthDuration)\b/,null],["fun pln",/^(?:xp:dereference|xinc:node-expand|xinc:link-references|xinc:link-expand|xhtml:restructure|xhtml:clean|xhtml:add-lists|xdmp:zip-manifest|xdmp:zip-get|xdmp:zip-create|xdmp:xquery-version|xdmp:word-convert|xdmp:with-namespaces|xdmp:version|xdmp:value|xdmp:user-roles|xdmp:user-last-login|xdmp:user|xdmp:url-encode|xdmp:url-decode|xdmp:uri-is-file|xdmp:uri-format|xdmp:uri-content-type|xdmp:unquote|xdmp:unpath|xdmp:triggers-database|xdmp:trace|xdmp:to-json|xdmp:tidy|xdmp:subbinary|xdmp:strftime|xdmp:spawn-in|xdmp:spawn|xdmp:sleep|xdmp:shutdown|xdmp:set-session-field|xdmp:set-response-encoding|xdmp:set-response-content-type|xdmp:set-response-code|xdmp:set-request-time-limit|xdmp:set|xdmp:servers|xdmp:server-status|xdmp:server-name|xdmp:server|xdmp:security-database|xdmp:security-assert|xdmp:schema-database|xdmp:save|xdmp:role-roles|xdmp:role|xdmp:rethrow|xdmp:restart|xdmp:request-timestamp|xdmp:request-status|xdmp:request-cancel|xdmp:request|xdmp:redirect-response|xdmp:random|xdmp:quote|xdmp:query-trace|xdmp:query-meters|xdmp:product-edition|xdmp:privilege-roles|xdmp:privilege|xdmp:pretty-print|xdmp:powerpoint-convert|xdmp:platform|xdmp:permission|xdmp:pdf-convert|xdmp:path|xdmp:octal-to-integer|xdmp:node-uri|xdmp:node-replace|xdmp:node-kind|xdmp:node-insert-child|xdmp:node-insert-before|xdmp:node-insert-after|xdmp:node-delete|xdmp:node-database|xdmp:mul64|xdmp:modules-root|xdmp:modules-database|xdmp:merging|xdmp:merge-cancel|xdmp:merge|xdmp:md5|xdmp:logout|xdmp:login|xdmp:log-level|xdmp:log|xdmp:lock-release|xdmp:lock-acquire|xdmp:load|xdmp:invoke-in|xdmp:invoke|xdmp:integer-to-octal|xdmp:integer-to-hex|xdmp:http-put|xdmp:http-post|xdmp:http-options|xdmp:http-head|xdmp:http-get|xdmp:http-delete|xdmp:hosts|xdmp:host-status|xdmp:host-name|xdmp:host|xdmp:hex-to-integer|xdmp:hash64|xdmp:hash32|xdmp:has-privilege|xdmp:groups|xdmp:group-serves|xdmp:group-servers|xdmp:group-name|xdmp:group-hosts|xdmp:group|xdmp:get-session-field-names|xdmp:get-session-field|xdmp:get-response-encoding|xdmp:get-response-code|xdmp:get-request-username|xdmp:get-request-user|xdmp:get-request-url|xdmp:get-request-protocol|xdmp:get-request-path|xdmp:get-request-method|xdmp:get-request-header-names|xdmp:get-request-header|xdmp:get-request-field-names|xdmp:get-request-field-filename|xdmp:get-request-field-content-type|xdmp:get-request-field|xdmp:get-request-client-certificate|xdmp:get-request-client-address|xdmp:get-request-body|xdmp:get-current-user|xdmp:get-current-roles|xdmp:get|xdmp:function-name|xdmp:function-module|xdmp:function|xdmp:from-json|xdmp:forests|xdmp:forest-status|xdmp:forest-restore|xdmp:forest-restart|xdmp:forest-name|xdmp:forest-delete|xdmp:forest-databases|xdmp:forest-counts|xdmp:forest-clear|xdmp:forest-backup|xdmp:forest|xdmp:filesystem-file|xdmp:filesystem-directory|xdmp:exists|xdmp:excel-convert|xdmp:eval-in|xdmp:eval|xdmp:estimate|xdmp:email|xdmp:element-content-type|xdmp:elapsed-time|xdmp:document-set-quality|xdmp:document-set-property|xdmp:document-set-properties|xdmp:document-set-permissions|xdmp:document-set-collections|xdmp:document-remove-properties|xdmp:document-remove-permissions|xdmp:document-remove-collections|xdmp:document-properties|xdmp:document-locks|xdmp:document-load|xdmp:document-insert|xdmp:document-get-quality|xdmp:document-get-properties|xdmp:document-get-permissions|xdmp:document-get-collections|xdmp:document-get|xdmp:document-forest|xdmp:document-delete|xdmp:document-add-properties|xdmp:document-add-permissions|xdmp:document-add-collections|xdmp:directory-properties|xdmp:directory-locks|xdmp:directory-delete|xdmp:directory-create|xdmp:directory|xdmp:diacritic-less|xdmp:describe|xdmp:default-permissions|xdmp:default-collections|xdmp:databases|xdmp:database-restore-validate|xdmp:database-restore-status|xdmp:database-restore-cancel|xdmp:database-restore|xdmp:database-name|xdmp:database-forests|xdmp:database-backup-validate|xdmp:database-backup-status|xdmp:database-backup-purge|xdmp:database-backup-cancel|xdmp:database-backup|xdmp:database|xdmp:collection-properties|xdmp:collection-locks|xdmp:collection-delete|xdmp:collation-canonical-uri|xdmp:castable-as|xdmp:can-grant-roles|xdmp:base64-encode|xdmp:base64-decode|xdmp:architecture|xdmp:apply|xdmp:amp-roles|xdmp:amp|xdmp:add64|xdmp:add-response-header|xdmp:access|trgr:trigger-set-recursive|trgr:trigger-set-permissions|trgr:trigger-set-name|trgr:trigger-set-module|trgr:trigger-set-event|trgr:trigger-set-description|trgr:trigger-remove-permissions|trgr:trigger-module|trgr:trigger-get-permissions|trgr:trigger-enable|trgr:trigger-disable|trgr:trigger-database-online-event|trgr:trigger-data-event|trgr:trigger-add-permissions|trgr:remove-trigger|trgr:property-content|trgr:pre-commit|trgr:post-commit|trgr:get-trigger-by-id|trgr:get-trigger|trgr:document-scope|trgr:document-content|trgr:directory-scope|trgr:create-trigger|trgr:collection-scope|trgr:any-property-content|thsr:set-entry|thsr:remove-term|thsr:remove-synonym|thsr:remove-entry|thsr:query-lookup|thsr:lookup|thsr:load|thsr:insert|thsr:expand|thsr:add-synonym|spell:suggest-detailed|spell:suggest|spell:remove-word|spell:make-dictionary|spell:load|spell:levenshtein-distance|spell:is-correct|spell:insert|spell:double-metaphone|spell:add-word|sec:users-collection|sec:user-set-roles|sec:user-set-password|sec:user-set-name|sec:user-set-description|sec:user-set-default-permissions|sec:user-set-default-collections|sec:user-remove-roles|sec:user-privileges|sec:user-get-roles|sec:user-get-description|sec:user-get-default-permissions|sec:user-get-default-collections|sec:user-doc-permissions|sec:user-doc-collections|sec:user-add-roles|sec:unprotect-collection|sec:uid-for-name|sec:set-realm|sec:security-version|sec:security-namespace|sec:security-installed|sec:security-collection|sec:roles-collection|sec:role-set-roles|sec:role-set-name|sec:role-set-description|sec:role-set-default-permissions|sec:role-set-default-collections|sec:role-remove-roles|sec:role-privileges|sec:role-get-roles|sec:role-get-description|sec:role-get-default-permissions|sec:role-get-default-collections|sec:role-doc-permissions|sec:role-doc-collections|sec:role-add-roles|sec:remove-user|sec:remove-role-from-users|sec:remove-role-from-role|sec:remove-role-from-privileges|sec:remove-role-from-amps|sec:remove-role|sec:remove-privilege|sec:remove-amp|sec:protect-collection|sec:privileges-collection|sec:privilege-set-roles|sec:privilege-set-name|sec:privilege-remove-roles|sec:privilege-get-roles|sec:privilege-add-roles|sec:priv-doc-permissions|sec:priv-doc-collections|sec:get-user-names|sec:get-unique-elem-id|sec:get-role-names|sec:get-role-ids|sec:get-privilege|sec:get-distinct-permissions|sec:get-collection|sec:get-amp|sec:create-user-with-role|sec:create-user|sec:create-role|sec:create-privilege|sec:create-amp|sec:collections-collection|sec:collection-set-permissions|sec:collection-remove-permissions|sec:collection-get-permissions|sec:collection-add-permissions|sec:check-admin|sec:amps-collection|sec:amp-set-roles|sec:amp-remove-roles|sec:amp-get-roles|sec:amp-doc-permissions|sec:amp-doc-collections|sec:amp-add-roles|search:unparse|search:suggest|search:snippet|search:search|search:resolve-nodes|search:resolve|search:remove-constraint|search:parse|search:get-default-options|search:estimate|search:check-options|prof:value|prof:reset|prof:report|prof:invoke|prof:eval|prof:enable|prof:disable|prof:allowed|ppt:clean|pki:template-set-request|pki:template-set-name|pki:template-set-key-type|pki:template-set-key-options|pki:template-set-description|pki:template-in-use|pki:template-get-version|pki:template-get-request|pki:template-get-name|pki:template-get-key-type|pki:template-get-key-options|pki:template-get-id|pki:template-get-description|pki:need-certificate|pki:is-temporary|pki:insert-trusted-certificates|pki:insert-template|pki:insert-signed-certificates|pki:insert-certificate-revocation-list|pki:get-trusted-certificate-ids|pki:get-template-ids|pki:get-template-certificate-authority|pki:get-template-by-name|pki:get-template|pki:get-pending-certificate-requests-xml|pki:get-pending-certificate-requests-pem|pki:get-pending-certificate-request|pki:get-certificates-for-template-xml|pki:get-certificates-for-template|pki:get-certificates|pki:get-certificate-xml|pki:get-certificate-pem|pki:get-certificate|pki:generate-temporary-certificate-if-necessary|pki:generate-temporary-certificate|pki:generate-template-certificate-authority|pki:generate-certificate-request|pki:delete-template|pki:delete-certificate|pki:create-template|pdf:make-toc|pdf:insert-toc-headers|pdf:get-toc|pdf:clean|p:status-transition|p:state-transition|p:remove|p:pipelines|p:insert|p:get-by-id|p:get|p:execute|p:create|p:condition|p:collection|p:action|ooxml:runs-merge|ooxml:package-uris|ooxml:package-parts-insert|ooxml:package-parts|msword:clean|mcgm:polygon|mcgm:point|mcgm:geospatial-query-from-elements|mcgm:geospatial-query|mcgm:circle|math:tanh|math:tan|math:sqrt|math:sinh|math:sin|math:pow|math:modf|math:log10|math:log|math:ldexp|math:frexp|math:fmod|math:floor|math:fabs|math:exp|math:cosh|math:cos|math:ceil|math:atan2|math:atan|math:asin|math:acos|map:put|map:map|map:keys|map:get|map:delete|map:count|map:clear|lnk:to|lnk:remove|lnk:insert|lnk:get|lnk:from|lnk:create|kml:polygon|kml:point|kml:interior-polygon|kml:geospatial-query-from-elements|kml:geospatial-query|kml:circle|kml:box|gml:polygon|gml:point|gml:interior-polygon|gml:geospatial-query-from-elements|gml:geospatial-query|gml:circle|gml:box|georss:point|georss:geospatial-query|georss:circle|geo:polygon|geo:point|geo:interior-polygon|geo:geospatial-query-from-elements|geo:geospatial-query|geo:circle|geo:box|fn:zero-or-one|fn:years-from-duration|fn:year-from-dateTime|fn:year-from-date|fn:upper-case|fn:unordered|fn:true|fn:translate|fn:trace|fn:tokenize|fn:timezone-from-time|fn:timezone-from-dateTime|fn:timezone-from-date|fn:sum|fn:subtract-dateTimes-yielding-yearMonthDuration|fn:subtract-dateTimes-yielding-dayTimeDuration|fn:substring-before|fn:substring-after|fn:substring|fn:subsequence|fn:string-to-codepoints|fn:string-pad|fn:string-length|fn:string-join|fn:string|fn:static-base-uri|fn:starts-with|fn:seconds-from-time|fn:seconds-from-duration|fn:seconds-from-dateTime|fn:round-half-to-even|fn:round|fn:root|fn:reverse|fn:resolve-uri|fn:resolve-QName|fn:replace|fn:remove|fn:QName|fn:prefix-from-QName|fn:position|fn:one-or-more|fn:number|fn:not|fn:normalize-unicode|fn:normalize-space|fn:node-name|fn:node-kind|fn:nilled|fn:namespace-uri-from-QName|fn:namespace-uri-for-prefix|fn:namespace-uri|fn:name|fn:months-from-duration|fn:month-from-dateTime|fn:month-from-date|fn:minutes-from-time|fn:minutes-from-duration|fn:minutes-from-dateTime|fn:min|fn:max|fn:matches|fn:lower-case|fn:local-name-from-QName|fn:local-name|fn:last|fn:lang|fn:iri-to-uri|fn:insert-before|fn:index-of|fn:in-scope-prefixes|fn:implicit-timezone|fn:idref|fn:id|fn:hours-from-time|fn:hours-from-duration|fn:hours-from-dateTime|fn:floor|fn:false|fn:expanded-QName|fn:exists|fn:exactly-one|fn:escape-uri|fn:escape-html-uri|fn:error|fn:ends-with|fn:encode-for-uri|fn:empty|fn:document-uri|fn:doc-available|fn:doc|fn:distinct-values|fn:distinct-nodes|fn:default-collation|fn:deep-equal|fn:days-from-duration|fn:day-from-dateTime|fn:day-from-date|fn:data|fn:current-time|fn:current-dateTime|fn:current-date|fn:count|fn:contains|fn:concat|fn:compare|fn:collection|fn:codepoints-to-string|fn:codepoint-equal|fn:ceiling|fn:boolean|fn:base-uri|fn:avg|fn:adjust-time-to-timezone|fn:adjust-dateTime-to-timezone|fn:adjust-date-to-timezone|fn:abs|feed:unsubscribe|feed:subscription|feed:subscribe|feed:request|feed:item|feed:description|excel:clean|entity:enrich|dom:set-pipelines|dom:set-permissions|dom:set-name|dom:set-evaluation-context|dom:set-domain-scope|dom:set-description|dom:remove-pipeline|dom:remove-permissions|dom:remove|dom:get|dom:evaluation-context|dom:domains|dom:domain-scope|dom:create|dom:configuration-set-restart-user|dom:configuration-set-permissions|dom:configuration-set-evaluation-context|dom:configuration-set-default-domain|dom:configuration-get|dom:configuration-create|dom:collection|dom:add-pipeline|dom:add-permissions|dls:retention-rules|dls:retention-rule-remove|dls:retention-rule-insert|dls:retention-rule|dls:purge|dls:node-expand|dls:link-references|dls:link-expand|dls:documents-query|dls:document-versions-query|dls:document-version-uri|dls:document-version-query|dls:document-version-delete|dls:document-version-as-of|dls:document-version|dls:document-update|dls:document-unmanage|dls:document-set-quality|dls:document-set-property|dls:document-set-properties|dls:document-set-permissions|dls:document-set-collections|dls:document-retention-rules|dls:document-remove-properties|dls:document-remove-permissions|dls:document-remove-collections|dls:document-purge|dls:document-manage|dls:document-is-managed|dls:document-insert-and-manage|dls:document-include-query|dls:document-history|dls:document-get-permissions|dls:document-extract-part|dls:document-delete|dls:document-checkout-status|dls:document-checkout|dls:document-checkin|dls:document-add-properties|dls:document-add-permissions|dls:document-add-collections|dls:break-checkout|dls:author-query|dls:as-of-query|dbk:convert|dbg:wait|dbg:value|dbg:stopped|dbg:stop|dbg:step|dbg:status|dbg:stack|dbg:out|dbg:next|dbg:line|dbg:invoke|dbg:function|dbg:finish|dbg:expr|dbg:eval|dbg:disconnect|dbg:detach|dbg:continue|dbg:connect|dbg:clear|dbg:breakpoints|dbg:break|dbg:attached|dbg:attach|cvt:save-converted-documents|cvt:part-uri|cvt:destination-uri|cvt:basepath|cvt:basename|cts:words|cts:word-query-weight|cts:word-query-text|cts:word-query-options|cts:word-query|cts:word-match|cts:walk|cts:uris|cts:uri-match|cts:train|cts:tokenize|cts:thresholds|cts:stem|cts:similar-query-weight|cts:similar-query-nodes|cts:similar-query|cts:shortest-distance|cts:search|cts:score|cts:reverse-query-weight|cts:reverse-query-nodes|cts:reverse-query|cts:remainder|cts:registered-query-weight|cts:registered-query-options|cts:registered-query-ids|cts:registered-query|cts:register|cts:query|cts:quality|cts:properties-query-query|cts:properties-query|cts:polygon-vertices|cts:polygon|cts:point-longitude|cts:point-latitude|cts:point|cts:or-query-queries|cts:or-query|cts:not-query-weight|cts:not-query-query|cts:not-query|cts:near-query-weight|cts:near-query-queries|cts:near-query-options|cts:near-query-distance|cts:near-query|cts:highlight|cts:geospatial-co-occurrences|cts:frequency|cts:fitness|cts:field-words|cts:field-word-query-weight|cts:field-word-query-text|cts:field-word-query-options|cts:field-word-query-field-name|cts:field-word-query|cts:field-word-match|cts:entity-highlight|cts:element-words|cts:element-word-query-weight|cts:element-word-query-text|cts:element-word-query-options|cts:element-word-query-element-name|cts:element-word-query|cts:element-word-match|cts:element-values|cts:element-value-ranges|cts:element-value-query-weight|cts:element-value-query-text|cts:element-value-query-options|cts:element-value-query-element-name|cts:element-value-query|cts:element-value-match|cts:element-value-geospatial-co-occurrences|cts:element-value-co-occurrences|cts:element-range-query-weight|cts:element-range-query-value|cts:element-range-query-options|cts:element-range-query-operator|cts:element-range-query-element-name|cts:element-range-query|cts:element-query-query|cts:element-query-element-name|cts:element-query|cts:element-pair-geospatial-values|cts:element-pair-geospatial-value-match|cts:element-pair-geospatial-query-weight|cts:element-pair-geospatial-query-region|cts:element-pair-geospatial-query-options|cts:element-pair-geospatial-query-longitude-name|cts:element-pair-geospatial-query-latitude-name|cts:element-pair-geospatial-query-element-name|cts:element-pair-geospatial-query|cts:element-pair-geospatial-boxes|cts:element-geospatial-values|cts:element-geospatial-value-match|cts:element-geospatial-query-weight|cts:element-geospatial-query-region|cts:element-geospatial-query-options|cts:element-geospatial-query-element-name|cts:element-geospatial-query|cts:element-geospatial-boxes|cts:element-child-geospatial-values|cts:element-child-geospatial-value-match|cts:element-child-geospatial-query-weight|cts:element-child-geospatial-query-region|cts:element-child-geospatial-query-options|cts:element-child-geospatial-query-element-name|cts:element-child-geospatial-query-child-name|cts:element-child-geospatial-query|cts:element-child-geospatial-boxes|cts:element-attribute-words|cts:element-attribute-word-query-weight|cts:element-attribute-word-query-text|cts:element-attribute-word-query-options|cts:element-attribute-word-query-element-name|cts:element-attribute-word-query-attribute-name|cts:element-attribute-word-query|cts:element-attribute-word-match|cts:element-attribute-values|cts:element-attribute-value-ranges|cts:element-attribute-value-query-weight|cts:element-attribute-value-query-text|cts:element-attribute-value-query-options|cts:element-attribute-value-query-element-name|cts:element-attribute-value-query-attribute-name|cts:element-attribute-value-query|cts:element-attribute-value-match|cts:element-attribute-value-geospatial-co-occurrences|cts:element-attribute-value-co-occurrences|cts:element-attribute-range-query-weight|cts:element-attribute-range-query-value|cts:element-attribute-range-query-options|cts:element-attribute-range-query-operator|cts:element-attribute-range-query-element-name|cts:element-attribute-range-query-attribute-name|cts:element-attribute-range-query|cts:element-attribute-pair-geospatial-values|cts:element-attribute-pair-geospatial-value-match|cts:element-attribute-pair-geospatial-query-weight|cts:element-attribute-pair-geospatial-query-region|cts:element-attribute-pair-geospatial-query-options|cts:element-attribute-pair-geospatial-query-longitude-name|cts:element-attribute-pair-geospatial-query-latitude-name|cts:element-attribute-pair-geospatial-query-element-name|cts:element-attribute-pair-geospatial-query|cts:element-attribute-pair-geospatial-boxes|cts:document-query-uris|cts:document-query|cts:distance|cts:directory-query-uris|cts:directory-query-depth|cts:directory-query|cts:destination|cts:deregister|cts:contains|cts:confidence|cts:collections|cts:collection-query-uris|cts:collection-query|cts:collection-match|cts:classify|cts:circle-radius|cts:circle-center|cts:circle|cts:box-west|cts:box-south|cts:box-north|cts:box-east|cts:box|cts:bearing|cts:arc-intersection|cts:and-query-queries|cts:and-query-options|cts:and-query|cts:and-not-query-positive-query|cts:and-not-query-negative-query|cts:and-not-query|css:get|css:convert|cpf:success|cpf:failure|cpf:document-set-state|cpf:document-set-processing-status|cpf:document-set-last-updated|cpf:document-set-error|cpf:document-get-state|cpf:document-get-processing-status|cpf:document-get-last-updated|cpf:document-get-error|cpf:check-transition|alert:spawn-matching-actions|alert:rule-user-id-query|alert:rule-set-user-id|alert:rule-set-query|alert:rule-set-options|alert:rule-set-name|alert:rule-set-description|alert:rule-set-action|alert:rule-remove|alert:rule-name-query|alert:rule-insert|alert:rule-id-query|alert:rule-get-user-id|alert:rule-get-query|alert:rule-get-options|alert:rule-get-name|alert:rule-get-id|alert:rule-get-description|alert:rule-get-action|alert:rule-action-query|alert:remove-triggers|alert:make-rule|alert:make-log-action|alert:make-config|alert:make-action|alert:invoke-matching-actions|alert:get-my-rules|alert:get-all-rules|alert:get-actions|alert:find-matching-rules|alert:create-triggers|alert:config-set-uri|alert:config-set-trigger-ids|alert:config-set-options|alert:config-set-name|alert:config-set-description|alert:config-set-cpf-domain-names|alert:config-set-cpf-domain-ids|alert:config-insert|alert:config-get-uri|alert:config-get-trigger-ids|alert:config-get-options|alert:config-get-name|alert:config-get-id|alert:config-get-description|alert:config-get-cpf-domain-names|alert:config-get-cpf-domain-ids|alert:config-get|alert:config-delete|alert:action-set-options|alert:action-set-name|alert:action-set-module-root|alert:action-set-module-db|alert:action-set-module|alert:action-set-description|alert:action-remove|alert:action-insert|alert:action-get-options|alert:action-get-name|alert:action-get-module-root|alert:action-get-module-db|alert:action-get-module|alert:action-get-description|zero-or-one|years-from-duration|year-from-dateTime|year-from-date|upper-case|unordered|true|translate|trace|tokenize|timezone-from-time|timezone-from-dateTime|timezone-from-date|sum|subtract-dateTimes-yielding-yearMonthDuration|subtract-dateTimes-yielding-dayTimeDuration|substring-before|substring-after|substring|subsequence|string-to-codepoints|string-pad|string-length|string-join|string|static-base-uri|starts-with|seconds-from-time|seconds-from-duration|seconds-from-dateTime|round-half-to-even|round|root|reverse|resolve-uri|resolve-QName|replace|remove|QName|prefix-from-QName|position|one-or-more|number|not|normalize-unicode|normalize-space|node-name|node-kind|nilled|namespace-uri-from-QName|namespace-uri-for-prefix|namespace-uri|name|months-from-duration|month-from-dateTime|month-from-date|minutes-from-time|minutes-from-duration|minutes-from-dateTime|min|max|matches|lower-case|local-name-from-QName|local-name|last|lang|iri-to-uri|insert-before|index-of|in-scope-prefixes|implicit-timezone|idref|id|hours-from-time|hours-from-duration|hours-from-dateTime|floor|false|expanded-QName|exists|exactly-one|escape-uri|escape-html-uri|error|ends-with|encode-for-uri|empty|document-uri|doc-available|doc|distinct-values|distinct-nodes|default-collation|deep-equal|days-from-duration|day-from-dateTime|day-from-date|data|current-time|current-dateTime|current-date|count|contains|concat|compare|collection|codepoints-to-string|codepoint-equal|ceiling|boolean|base-uri|avg|adjust-time-to-timezone|adjust-dateTime-to-timezone|adjust-date-to-timezone|abs)\b/],
3
+["pln",/^[\w:-]+/],["pln",/^[\t\n\r \xa0]+/]]),["xq","xquery"]);
+2
mojolegacy/lib/Mojolicious/public/mojo/prettify/lang-yaml.js
... ...
@@ -0,0 +1,2 @@
1
+var a=null;
2
+PR.registerLangHandler(PR.createSimpleLexer([["pun",/^[:>?|]+/,a,":|>?"],["dec",/^%(?:YAML|TAG)[^\n\r#]+/,a,"%"],["typ",/^&\S+/,a,"&"],["typ",/^!\S*/,a,"!"],["str",/^"(?:[^"\\]|\\.)*(?:"|$)/,a,'"'],["str",/^'(?:[^']|'')*(?:'|$)/,a,"'"],["com",/^#[^\n\r]*/,a,"#"],["pln",/^\s+/,a," \t\r\n"]],[["dec",/^(?:---|\.\.\.)(?:[\n\r]|$)/],["pun",/^-/],["kwd",/^\w+:[\n\r ]/],["pln",/^\w+/]]),["yaml","yml"]);
+1
mojolegacy/lib/Mojolicious/public/mojo/prettify/prettify-mojo.css
... ...
@@ -0,0 +1 @@
1
+.str{color:#9daa7e}.kwd{color:#d5b57c}.com{color:#726d73}.typ{color:#dd7e5e}.lit{color:#fcf0a4}.pun,.opn,.clo{color:#a78353}.pln{color:#889dbc}.tag{color:#d5b57c}.atn{color:#dd7e5e}.atv{color:#9daa7e}.dec{color:#dd7e5e}
+1
mojolegacy/lib/Mojolicious/public/mojo/prettify/prettify.css
... ...
@@ -0,0 +1 @@
1
+.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
+28
mojolegacy/lib/Mojolicious/public/mojo/prettify/prettify.js
... ...
@@ -0,0 +1,28 @@
1
+var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
2
+(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
3
+[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<
4
+f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&
5
+(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=
6
+{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,
7
+t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===
8
+"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
9
+l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
10
+q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
11
+q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
12
+"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
13
+a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
14
+for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",
15
+m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=
16
+a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=
17
+j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
18
+"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
19
+H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
20
+J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
21
+I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
22
+["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
23
+/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
24
+["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
25
+hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=
26
+!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,
27
+250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",
28
+PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
+5 -5
mojolegacy/lib/Mojolicious/templates/exception.development.html.ep
... ...
@@ -4,9 +4,9 @@
4 4
     <title>Server error</title>
5 5
     <meta http-equiv="Pragma" content="no-cache">
6 6
     <meta http-equiv="Expires" content="-1">
7
-    %= javascript '/js/jquery.js'
8
-    %= stylesheet '/css/prettify-mojo.css'
9
-    %= javascript '/js/prettify.js'
7
+    %= javascript '/mojo/jquery/jquery.js'
8
+    %= stylesheet '/mojo/prettify/prettify-mojo.css'
9
+    %= javascript '/mojo/prettify/prettify.js'
10 10
     %= stylesheet begin
11 11
       a img { border: 0 }
12 12
       body {
... ...
@@ -39,7 +39,7 @@
39 39
       }
40 40
       .code {
41 41
         background-color: #1a1a1a;
42
-        background: url(<%= url_for '/mojolicious-pinstripe.gif' %>);
42
+        background: url(<%= url_for '/mojo/pinstripe.gif' %>);
43 43
         color: #eee;
44 44
         text-shadow: #333 0 1px 0;
45 45
       }
... ...
@@ -219,7 +219,7 @@
219 219
     </div>
220 220
     <div id="footer">
221 221
       %= link_to 'http://mojolicio.us' => begin
222
-        %= image '/mojolicious-black.png', alt => 'Mojolicious logo'
222
+        %= image '/mojo/logo-black.png', alt => 'Mojolicious logo'
223 223
       % end
224 224
     </div>
225 225
     %= javascript begin
+1 -1
mojolegacy/lib/Mojolicious/templates/exception.html.ep
... ...
@@ -4,7 +4,7 @@
4 4
    %= stylesheet begin
5 5
       body { background-color: #caecf6 }
6 6
       #raptor {
7
-        background: url(<%= url_for '/mojolicious-failraptor.png' %>);
7
+        background: url(<%= url_for '/mojo/failraptor.png' %>);
8 8
         height: 488px;
9 9
         left: 50%;
10 10
         margin-left: -371px;
+2 -2
mojolegacy/lib/Mojolicious/templates/mojobar.html.ep
... ...
@@ -1,4 +1,4 @@
1
-%= javascript '/js/jquery.js'
1
+%= javascript '/mojo/jquery/jquery.js'
2 2
 <div id="mojobar">
3 3
   %= stylesheet scoped => 'scoped', begin
4 4
     #mojobar {
... ...
@@ -56,7 +56,7 @@
56 56
   % end
57 57
   <div id="mojobar-logo">
58 58
     %= link_to 'http://mojolicio.us' => begin
59
-      %= image '/mojolicious-white.png', alt => 'Mojolicious logo'
59
+      %= image '/mojo/logo-white.png', alt => 'Mojolicious logo'
60 60
     % end
61 61
   </div>
62 62
   <div id="mojobar-links">
+3 -3
mojolegacy/lib/Mojolicious/templates/not_found.development.html.ep
... ...
@@ -2,8 +2,8 @@
2 2
 <html>
3 3
   <head>
4 4
     <title>Page not found</title>
5
-    %= stylesheet '/css/prettify-mojo.css'
6
-    %= javascript '/js/prettify.js'
5
+    %= stylesheet '/mojo/prettify/prettify-mojo.css'
6
+    %= javascript '/mojo/prettify/prettify.js'
7 7
     %= stylesheet begin
8 8
       body {
9 9
         background-color: #f5f6f8;
... ...
@@ -117,7 +117,7 @@
117 117
     </div>
118 118
     <div id="footer">
119 119
       %= link_to 'http://mojolicio.us' => begin
120
-        %= image '/mojolicious-black.png', alt => 'Mojolicious logo'
120
+        %= image '/mojo/logo-black.png', alt => 'Mojolicious logo'
121 121
       % end
122 122
     </div>
123 123
   </body>
+2 -2
mojolegacy/lib/Mojolicious/templates/not_found.html.ep
... ...
@@ -10,7 +10,7 @@
10 10
         top: 60%;
11 11
       }
12 12
       #notfound {
13
-        background: url(<%= url_for '/mojolicious-notfound.png' %>);
13
+        background: url(<%= url_for '/mojo/notfound.png' %>);
14 14
         height: 62px;
15 15
         left: 50%;
16 16
         margin-left: -153px;
... ...
@@ -22,7 +22,7 @@
22 22
     % end
23 23
   <body>
24 24
     %= link_to url_for->base => begin
25
-      %= image '/mojolicious-noraptor.png', alt => 'Bye!', id => 'noraptor'
25
+      %= image '/mojo/noraptor.png', alt => 'Bye!', id => 'noraptor'
26 26
     % end
27 27
     <div id="notfound"></div>
28 28
   </body>
+4 -4
mojolegacy/lib/Mojolicious/templates/perldoc.html.ep
... ...
@@ -2,8 +2,8 @@
2 2
 <html>
3 3
   <head>
4 4
     <title><%= $title %></title>
5
-    %= stylesheet '/css/prettify-mojo.css'
6
-    %= javascript '/js/prettify.js'
5
+    %= stylesheet '/mojo/prettify/prettify-mojo.css'
6
+    %= javascript '/mojo/prettify/prettify.js'
7 7
     %= stylesheet begin
8 8
       a { color: inherit }
9 9
       a:hover { color: #2a2a2a }
... ...
@@ -24,7 +24,7 @@
24 24
       h1 a, h2 a, h3 a { text-decoration: none }
25 25
       pre {
26 26
         background-color: #eee;
27
-        background: url(<%= url_for '/mojolicious-pinstripe.gif' %>);
27
+        background: url(<%= url_for '/mojo/pinstripe.gif' %>);
28 28
         -moz-border-radius: 5px;
29 29
         border-radius: 5px;
30 30
         color: #eee;
... ...
@@ -88,7 +88,7 @@
88 88
     </div>
89 89
     <div id="footer">
90 90
       %= link_to 'http://mojolicio.us' => begin
91
-        %= image '/mojolicious-black.png', alt => 'Mojolicious logo'
91
+        %= image '/mojo/logo-black.png', alt => 'Mojolicious logo'
92 92
       % end
93 93
     </div>
94 94
   </body>
+191 -76
mojolegacy/lib/Test/Mojo.pm
... ...
@@ -9,12 +9,14 @@ use Mojo::Base -base;
9 9
 #  Bender: You're better off dead, I'm telling you, dude.
10 10
 #  Fry: Santa Claus is gunning you down!"
11 11
 use Mojo::IOLoop;
12
+use Mojo::JSON;
13
+use Mojo::JSON::Pointer;
12 14
 use Mojo::Server;
13 15
 use Mojo::UserAgent;
14 16
 use Mojo::Util qw(decode encode);
15 17
 use Test::More ();
16 18
 
17
-has 'tx';
19
+has [qw(message tx)];
18 20
 has ua => sub { Mojo::UserAgent->new->ioloop(Mojo::IOLoop->singleton) };
19 21
 
20 22
 # Silent or loud tests
... ...
@@ -142,12 +144,6 @@ sub json_content_is {
142 144
   return $self->_test('is_deeply', $self->tx->res->json, $data, $desc);
143 145
 }
144 146
 
145
-sub json_is {
146
-  my ($self, $p, $data, $desc) = @_;
147
-  $desc ||= qq{exact match for JSON Pointer "$p"};
148
-  return $self->_test('is_deeply', $self->tx->res->json($p), $data, $desc);
149
-}
150
-
151 147
 sub json_has {
152 148
   my ($self, $p, $desc) = @_;
153 149
   $desc ||= qq{has value for JSON Pointer "$p"};
... ...
@@ -162,28 +158,53 @@ sub json_hasnt {
162 158
     !Mojo::JSON::Pointer->new->contains($self->tx->res->json, $p), $desc);
163 159
 }
164 160
 
161
+sub json_is {
162
+  my ($self, $p, $data, $desc) = @_;
163
+  $desc ||= qq{exact match for JSON Pointer "$p"};
164
+  return $self->_test('is_deeply', $self->tx->res->json($p), $data, $desc);
165
+}
166
+
167
+sub json_message_has {
168
+  my ($self, $p, $desc) = @_;
169
+  $desc ||= qq{has value for JSON Pointer "$p"};
170
+  return $self->_test('ok', $self->_json(contains => $p), $desc);
171
+}
172
+
173
+sub json_message_hasnt {
174
+  my ($self, $p, $desc) = @_;
175
+  $desc ||= qq{has no value for JSON Pointer "$p"};
176
+  return $self->_test('ok', !$self->_json(contains => $p), $desc);
177
+}
178
+
179
+sub json_message_is {
180
+  my ($self, $p, $data, $desc) = @_;
181
+  $desc ||= qq{exact match for JSON Pointer "$p"};
182
+  return $self->_test('is_deeply', $self->_json(get => $p), $data, $desc);
183
+}
184
+
165 185
 sub message_is {
166 186
   my ($self, $value, $desc) = @_;
167
-  $desc ||= 'exact match for message';
168
-  return $self->_test('is', $self->_message, $value, $desc);
187
+  return $self->_message('is', $value, $desc || 'exact match for message');
169 188
 }
170 189
 
171 190
 sub message_isnt {
172 191
   my ($self, $value, $desc) = @_;
173
-  $desc ||= 'no match for message';
174
-  return $self->_test('isnt', $self->_message, $value, $desc);
192
+  return $self->_message('isnt', $value, $desc || 'no match for message');
175 193
 }
176 194
 
177 195
 sub message_like {
178 196
   my ($self, $regex, $desc) = @_;
179
-  $desc ||= 'message is similar';
180
-  return $self->_test('like', $self->_message, $regex, $desc);
197
+  return $self->_message('like', $regex, $desc || 'message is similar');
198
+}
199
+
200
+sub message_ok {
201
+  my ($self, $desc) = @_;
202
+  return $self->_test('ok', !!$self->_wait(1), $desc, 'message received');
181 203
 }
182 204
 
183 205
 sub message_unlike {
184 206
   my ($self, $regex, $desc) = @_;
185
-  $desc ||= 'message is not similar';
186
-  return $self->_test('unlike', $self->_message, $regex, $desc);
207
+  return $self->_message('unlike', $regex, $desc || 'message is not similar');
187 208
 }
188 209
 
189 210
 sub options_ok { shift->_request_ok(options => @_) }
... ...
@@ -278,7 +299,8 @@ sub websocket_ok {
278 299
       my $tx = pop;
279 300
       $self->tx($tx);
280 301
       $tx->on(finish => sub { $self->{finished} = 1 });
281
-      $tx->on(message => sub { push @{$self->{messages}}, pop });
302
+      $tx->on(binary => sub { push @{$self->{messages}}, [binary => pop] });
303
+      $tx->on(text   => sub { push @{$self->{messages}}, [text   => pop] });
282 304
       Mojo::IOLoop->stop;
283 305
     }
284 306
   );
... ...
@@ -295,10 +317,28 @@ sub _get_content {
295 317
   return $charset ? decode($charset, $content) : $content;
296 318
 }
297 319
 
320
+sub _json {
321
+  my ($self, $method, $p) = @_;
322
+  return Mojo::JSON::Pointer->new->$method(
323
+    Mojo::JSON->new->decode(@{$self->_wait || []}[1]), $p);
324
+}
325
+
298 326
 sub _message {
299
-  my $self = shift;
300
-  Mojo::IOLoop->one_tick while !$self->{finished} && !@{$self->{messages}};
301
-  return shift @{$self->{messages}};
327
+  my ($self, $name, $value, $desc) = @_;
328
+  local $Test::Builder::Level = $Test::Builder::Level + 1;
329
+  my ($type, $msg) = @{$self->_wait || ['']};
330
+
331
+  # Type check
332
+  if (ref $value eq 'HASH') {
333
+    my $expect = exists $value->{text} ? 'text' : 'binary';
334
+    $value = $value->{$expect};
335
+    $msg = '' unless $type eq $expect;
336
+  }
337
+
338
+  # Decode text frame if there is no type check
339
+  else { $msg = decode 'UTF-8', $msg if $type eq 'text' }
340
+
341
+  return $self->_test($name, defined $msg ? $msg : '', $value, $desc);
302 342
 }
303 343
 
304 344
 sub _request_ok {
... ...
@@ -326,6 +366,21 @@ sub _text {
326 366
   return $e->text;
327 367
 }
328 368
 
369
+sub _wait {
370
+  my ($self, $wait) = @_;
371
+
372
+  # DEPRECATED in Rainbow!
373
+  my $new = $self->{new} = defined $self->{new} ? $self->{new} : $wait;
374
+  warn <<EOF unless $new;
375
+Testing WebSocket messages without Test::Mojo->message_ok is DEPRECATED!!!
376
+EOF
377
+  return $self->message if $new && !$wait;
378
+
379
+  # Wait for message
380
+  Mojo::IOLoop->one_tick while !$self->{finished} && !@{$self->{messages}};
381
+  return $self->message(shift @{$self->{messages}})->message;
382
+}
383
+
329 384
 1;
330 385
 
331 386
 =head1 NAME
... ...
@@ -352,6 +407,7 @@ Test::Mojo - Testing Mojo!
352 407
   # WebSocket
353 408
   $t->websocket_ok('/echo')
354 409
     ->send_ok('hello')
410
+    ->message_ok
355 411
     ->message_is('echo: hello')
356 412
     ->finish_ok;
357 413
 
... ...
@@ -366,7 +422,20 @@ L<Mojo> and L<Mojolicious> applications.
366 422
 
367 423
 L<Test::Mojo> implements the following attributes.
368 424
 
369
-=head2 C<tx>
425
+=head2 message
426
+
427
+  my $msg = $t->message;
428
+  $t      = $t->message([text => $bytes]);
429
+
430
+Current WebSocket message.
431
+
432
+  # Test custom message
433
+  $t->message([binary => $bytes])
434
+    ->json_message_has('/foo/bar')
435
+    ->json_message_hasnt('/bar')
436
+    ->json_message_is('/foo/baz' => {yada => [1, 2, 3]});
437
+
438
+=head2 tx
370 439
 
371 440
   my $tx = $t->tx;
372 441
   $t     = $t->tx(Mojo::Transaction::HTTP->new);
... ...
@@ -380,7 +449,7 @@ Current transaction, usually a L<Mojo::Transaction::HTTP> object.
380 449
   # Test custom transactions
381 450
   $t->tx($t->tx->previous)->status_is(302)->header_like(Location => qr/foo/);
382 451
 
383
-=head2 C<ua>
452
+=head2 ua
384 453
 
385 454
   my $ua = $t->ua;
386 455
   $t     = $t->ua(Mojo::UserAgent->new);
... ...
@@ -404,7 +473,7 @@ User agent used for testing, defaults to a L<Mojo::UserAgent> object.
404 473
 L<Test::Mojo> inherits all methods from L<Mojo::Base> and implements the
405 474
 following new ones.
406 475
 
407
-=head2 C<new>
476
+=head2 new
408 477
 
409 478
   my $t = Test::Mojo->new;
410 479
   my $t = Test::Mojo->new('MyApp');
... ...
@@ -412,7 +481,7 @@ following new ones.
412 481
 
413 482
 Construct a new L<Test::Mojo> object.
414 483
 
415
-=head2 C<app>
484
+=head2 app
416 485
 
417 486
   my $app = $t->app;
418 487
   $t      = $t->app(MyApp->new);
... ...
@@ -437,63 +506,63 @@ Access application with L<Mojo::UserAgent/"app">.
437 506
   my $stash;
438 507
   $t->app->hook(after_dispatch => sub { $stash = shift->stash });
439 508
 
440
-=head2 C<content_is>
509
+=head2 content_is
441 510
 
442 511
   $t = $t->content_is('working!');
443 512
   $t = $t->content_is('working!', 'right content');
444 513
 
445 514
 Check response content for exact match.
446 515
 
447
-=head2 C<content_isnt>
516
+=head2 content_isnt
448 517
 
449 518
   $t = $t->content_isnt('working!');
450 519
   $t = $t->content_isnt('working!', 'different content');
451 520
 
452 521
 Opposite of C<content_is>.
453 522
 
454
-=head2 C<content_like>
523
+=head2 content_like
455 524
 
456 525
   $t = $t->content_like(qr/working!/);
457 526
   $t = $t->content_like(qr/working!/, 'right content');
458 527
 
459 528
 Check response content for similar match.
460 529
 
461
-=head2 C<content_unlike>
530
+=head2 content_unlike
462 531
 
463 532
   $t = $t->content_unlike(qr/working!/);
464 533
   $t = $t->content_unlike(qr/working!/, 'different content');
465 534
 
466 535
 Opposite of C<content_like>.
467 536
 
468
-=head2 C<content_type_is>
537
+=head2 content_type_is
469 538
 
470 539
   $t = $t->content_type_is('text/html');
471 540
   $t = $t->content_type_is('text/html', 'right content type');
472 541
 
473 542
 Check response C<Content-Type> header for exact match.
474 543
 
475
-=head2 C<content_type_isnt>
544
+=head2 content_type_isnt
476 545
 
477 546
   $t = $t->content_type_isnt('text/html');
478 547
   $t = $t->content_type_isnt('text/html', 'different content type');
479 548
 
480 549
 Opposite of C<content_type_is>.
481 550
 
482
-=head2 C<content_type_like>
551
+=head2 content_type_like
483 552
 
484 553
   $t = $t->content_type_like(qr/text/);
485 554
   $t = $t->content_type_like(qr/text/, 'right content type');
486 555
 
487 556
 Check response C<Content-Type> header for similar match.
488 557
 
489
-=head2 C<content_type_unlike>
558
+=head2 content_type_unlike
490 559
 
491 560
   $t = $t->content_type_unlike(qr/text/);
492 561
   $t = $t->content_type_unlike(qr/text/, 'different content type');
493 562
 
494 563
 Opposite of C<content_type_like>.
495 564
 
496
-=head2 C<delete_ok>
565
+=head2 delete_ok
497 566
 
498 567
   $t = $t->delete_ok('/foo');
499 568
   $t = $t->delete_ok('/foo' => {DNT => 1} => 'Hi!');
... ...
@@ -501,7 +570,7 @@ Opposite of C<content_type_like>.
501 570
 Perform a C<DELETE> request and check for transport errors, takes the same
502 571
 arguments as L<Mojo::UserAgent/"delete">.
503 572
 
504
-=head2 C<element_exists>
573
+=head2 element_exists
505 574
 
506 575
   $t = $t->element_exists('div.foo[x=y]');
507 576
   $t = $t->element_exists('html head title', 'has a title');
... ...
@@ -509,21 +578,21 @@ arguments as L<Mojo::UserAgent/"delete">.
509 578
 Checks for existence of the CSS selectors first matching HTML/XML element with
510 579
 L<Mojo::DOM>.
511 580
 
512
-=head2 C<element_exists_not>
581
+=head2 element_exists_not
513 582
 
514 583
   $t = $t->element_exists_not('div.foo[x=y]');
515 584
   $t = $t->element_exists_not('html head title', 'has no title');
516 585
 
517 586
 Opposite of C<element_exists>.
518 587
 
519
-=head2 C<finish_ok>
588
+=head2 finish_ok
520 589
 
521 590
   $t = $t->finish_ok;
522 591
   $t = $t->finish_ok('finished successfully');
523 592
 
524 593
 Finish C<WebSocket> connection.
525 594
 
526
-=head2 C<get_ok>
595
+=head2 get_ok
527 596
 
528 597
   $t = $t->get_ok('/foo');
529 598
   $t = $t->get_ok('/foo' => {DNT => 1} => 'Hi!');
... ...
@@ -531,7 +600,7 @@ Finish C<WebSocket> connection.
531 600
 Perform a C<GET> request and check for transport errors, takes the same
532 601
 arguments as L<Mojo::UserAgent/"get">.
533 602
 
534
-=head2 C<head_ok>
603
+=head2 head_ok
535 604
 
536 605
   $t = $t->head_ok('/foo');
537 606
   $t = $t->head_ok('/foo' => {DNT => 1} => 'Hi!');
... ...
@@ -539,35 +608,35 @@ arguments as L<Mojo::UserAgent/"get">.
539 608
 Perform a C<HEAD> request and check for transport errors, takes the same
540 609
 arguments as L<Mojo::UserAgent/"head">.
541 610
 
542
-=head2 C<header_is>
611
+=head2 header_is
543 612
 
544 613
   $t = $t->header_is(Expect => 'fun');
545 614
   $t = $t->header_is(Expect => 'fun', 'right header');
546 615
 
547 616
 Check response header for exact match.
548 617
 
549
-=head2 C<header_isnt>
618
+=head2 header_isnt
550 619
 
551 620
   $t = $t->header_isnt(Expect => 'fun');
552 621
   $t = $t->header_isnt(Expect => 'fun', 'different header');
553 622
 
554 623
 Opposite of C<header_is>.
555 624
 
556
-=head2 C<header_like>
625
+=head2 header_like
557 626
 
558 627
   $t = $t->header_like(Expect => qr/fun/);
559 628
   $t = $t->header_like(Expect => qr/fun/, 'right header');
560 629
 
561 630
 Check response header for similar match.
562 631
 
563
-=head2 C<header_unlike>
632
+=head2 header_unlike
564 633
 
565 634
   $t = $t->header_like(Expect => qr/fun/);
566 635
   $t = $t->header_like(Expect => qr/fun/, 'different header');
567 636
 
568 637
 Opposite of C<header_like>.
569 638
 
570
-=head2 C<json_content_is>
639
+=head2 json_content_is
571 640
 
572 641
   $t = $t->json_content_is([1, 2, 3]);
573 642
   $t = $t->json_content_is([1, 2, 3], 'right content');
... ...
@@ -575,16 +644,7 @@ Opposite of C<header_like>.
575 644
 
576 645
 Check response content for JSON data.
577 646
 
578
-=head2 C<json_is>
579
-
580
-  $t = $t->json_is('/foo' => {bar => [1, 2, 3]});
581
-  $t = $t->json_is('/foo/bar' => [1, 2, 3]);
582
-  $t = $t->json_is('/foo/bar/1' => 2, 'right value');
583
-
584
-Check the value extracted from JSON response using the given JSON Pointer with
585
-L<Mojo::JSON::Pointer>.
586
-
587
-=head2 C<json_has>
647
+=head2 json_has
588 648
 
589 649
   $t = $t->json_has('/foo');
590 650
   $t = $t->json_has('/minibar', 'has a minibar');
... ...
@@ -592,42 +652,97 @@ L<Mojo::JSON::Pointer>.
592 652
 Check if JSON response contains a value that can be identified using the given
593 653
 JSON Pointer with L<Mojo::JSON::Pointer>.
594 654
 
595
-=head2 C<json_hasnt>
655
+=head2 json_hasnt
596 656
 
597 657
   $t = $t->json_hasnt('/foo');
598 658
   $t = $t->json_hasnt('/minibar', 'no minibar');
599 659
 
600 660
 Opposite of C<json_has>.
601 661
 
602
-=head2 C<message_is>
662
+=head2 json_is
663
+
664
+  $t = $t->json_is('/' => {foo => [1, 2, 3]});
665
+  $t = $t->json_is('/foo' => [1, 2, 3]);
666
+  $t = $t->json_is('/foo/1' => 2, 'right value');
667
+
668
+Check the value extracted from JSON response using the given JSON Pointer with
669
+L<Mojo::JSON::Pointer>.
670
+
671
+=head2 json_message_has
672
+
673
+  $t = $t->json_message_has('/foo');
674
+  $t = $t->json_message_has('/minibar', 'has a minibar');
675
+
676
+Check if JSON WebSocket message contains a value that can be identified using
677
+the given JSON Pointer with L<Mojo::JSON::Pointer>.
678
+
679
+=head2 json_message_hasnt
680
+
681
+  $t = $t->json_message_hasnt('/foo');
682
+  $t = $t->json_message_hasnt('/minibar', 'no minibar');
683
+
684
+Opposite of C<json_message_has>.
685
+
686
+=head2 json_message_is
603 687
 
688
+  $t = $t->json_message_is('/' => {foo => [1, 2, 3]});
689
+  $t = $t->json_message_is('/foo' => [1, 2, 3]);
690
+  $t = $t->json_message_is('/foo/1' => 2, 'right value');
691
+
692
+Check the value extracted from JSON WebSocket message using the given JSON
693
+Pointer with L<Mojo::JSON::Pointer>.
694
+
695
+=head2 message_is
696
+
697
+  $t = $t->message_is({binary => $bytes});
698
+  $t = $t->message_is({text   => $bytes});
604 699
   $t = $t->message_is('working!');
605 700
   $t = $t->message_is('working!', 'right message');
606 701
 
607 702
 Check WebSocket message for exact match.
608 703
 
609
-=head2 C<message_isnt>
704
+=head2 message_isnt
610 705
 
706
+  $t = $t->message_isnt({binary => $bytes});
707
+  $t = $t->message_isnt({text   => $bytes});
611 708
   $t = $t->message_isnt('working!');
612 709
   $t = $t->message_isnt('working!', 'different message');
613 710
 
614 711
 Opposite of C<message_is>.
615 712
 
616
-=head2 C<message_like>
713
+=head2 message_like
617 714
 
715
+  $t = $t->message_like({binary => qr/$bytes/});
716
+  $t = $t->message_like({text   => qr/$bytes/});
618 717
   $t = $t->message_like(qr/working!/);
619 718
   $t = $t->message_like(qr/working!/, 'right message');
620 719
 
621 720
 Check WebSocket message for similar match.
622 721
 
623
-=head2 C<message_unlike>
722
+=head2 message_ok
723
+
724
+  $t = $t->message_ok;
725
+  $t = $t->message_ok('got a message');
726
+
727
+Wait for next WebSocket message to arrive.
728
+
729
+  # Wait for message and perform multiple tests on it
730
+  $t->websocket_ok('/time')
731
+    ->message_ok
732
+    ->message_like(qr/\d+/)
733
+    ->message_unlike(qr/\w+/)
734
+    ->finish_ok;
735
+
736
+=head2 message_unlike
624 737
 
738
+  $t = $t->message_unlike({binary => qr/$bytes/});
739
+  $t = $t->message_unlike({text   => qr/$bytes/});
625 740
   $t = $t->message_unlike(qr/working!/);
626 741
   $t = $t->message_unlike(qr/working!/, 'different message');
627 742
 
628 743
 Opposite of C<message_like>.
629 744
 
630
-=head2 C<options_ok>
745
+=head2 options_ok
631 746
 
632 747
   $t = $t->options_ok('/foo');
633 748
   $t = $t->options_ok('/foo' => {DNT => 1} => 'Hi!');
... ...
@@ -635,7 +750,7 @@ Opposite of C<message_like>.
635 750
 Perform a C<OPTIONS> request and check for transport errors, takes the same
636 751
 arguments as L<Mojo::UserAgent/"options">.
637 752
 
638
-=head2 C<or>
753
+=head2 or
639 754
 
640 755
   $t = $t->or(sub {...});
641 756
 
... ...
@@ -645,7 +760,7 @@ Invoke callback if previous test failed.
645 760
   $t->get_ok('/bad')->or(sub { diag 'Must have been Glen!' })
646 761
     ->status_is(200)->or(sub { diag $t->tx->res->dom->at('title')->text });
647 762
 
648
-=head2 C<patch_ok>
763
+=head2 patch_ok
649 764
 
650 765
   $t = $t->patch_ok('/foo');
651 766
   $t = $t->patch_ok('/foo' => {DNT => 1} => 'Hi!');
... ...
@@ -653,7 +768,7 @@ Invoke callback if previous test failed.
653 768
 Perform a C<PATCH> request and check for transport errors, takes the same
654 769
 arguments as L<Mojo::UserAgent/"patch">.
655 770
 
656
-=head2 C<post_ok>
771
+=head2 post_ok
657 772
 
658 773
   $t = $t->post_ok('/foo');
659 774
   $t = $t->post_ok('/foo' => {DNT => 1} => 'Hi!');
... ...
@@ -661,7 +776,7 @@ arguments as L<Mojo::UserAgent/"patch">.
661 776
 Perform a C<POST> request and check for transport errors, takes the same
662 777
 arguments as L<Mojo::UserAgent/"post">.
663 778
 
664
-=head2 C<post_form_ok>
779
+=head2 post_form_ok
665 780
 
666 781
   $t = $t->post_form_ok('/foo' => {a => 'b'});
667 782
   $t = $t->post_form_ok('/foo' => 'UTF-8' => {a => 'b'} => {DNT => 1});
... ...
@@ -672,7 +787,7 @@ the same arguments as L<Mojo::UserAgent/"post_form">.
672 787
   # Test file upload
673 788
   $t->post_form_ok('/upload' => {foo => {content => 'bar'}})->status_is(200);
674 789
 
675
-=head2 C<post_json_ok>
790
+=head2 post_json_ok
676 791
 
677 792
   $t = $t->post_json_ok('/foo' => {a => 'b'});
678 793
   $t = $t->post_json_ok('/foo' => {a => 'b'} => {DNT => 1});
... ...
@@ -685,7 +800,7 @@ the same arguments as L<Mojo::UserAgent/"post_json">.
685 800
     ->status_is(200)
686 801
     ->json_content_is({bye => 'world'});
687 802
 
688
-=head2 C<put_ok>
803
+=head2 put_ok
689 804
 
690 805
   $t = $t->put_ok('/foo');
691 806
   $t = $t->put_ok('/foo' => {DNT => 1} => 'Hi!');
... ...
@@ -693,7 +808,7 @@ the same arguments as L<Mojo::UserAgent/"post_json">.
693 808
 Perform a C<PUT> request and check for transport errors, takes the same
694 809
 arguments as L<Mojo::UserAgent/"put">.
695 810
 
696
-=head2 C<request_ok>
811
+=head2 request_ok
697 812
 
698 813
   $t = $t->request_ok(Mojo::Transaction::HTTP->new);
699 814
   $t = $t->request_ok(Mojo::Transaction::HTTP->new, 'request successful');
... ...
@@ -707,37 +822,37 @@ Perform request and check for transport errors.
707 822
     ->status_is(200)
708 823
     ->json_is('/message' => 'User has been replaced.');
709 824
 
710
-=head2 C<reset_session>
825
+=head2 reset_session
711 826
 
712 827
   $t = $t->reset_session;
713 828
 
714 829
 Reset user agent session.
715 830
 
716
-=head2 C<send_ok>
831
+=head2 send_ok
717 832
 
718 833
   $t = $t->send_ok({binary => $bytes});
719 834
   $t = $t->send_ok({text   => $bytes});
720 835
   $t = $t->send_ok([$fin, $rsv1, $rsv2, $rsv3, $op, $payload]);
721
-  $t = $t->send_ok('hello');
722
-  $t = $t->send_ok('hello', 'sent successfully');
836
+  $t = $t->send_ok($chars);
837
+  $t = $t->send_ok($chars, 'sent successfully');
723 838
 
724 839
 Send message or frame via WebSocket.
725 840
 
726
-=head2 C<status_is>
841
+=head2 status_is
727 842
 
728 843
   $t = $t->status_is(200);
729 844
   $t = $t->status_is(200, 'right status');
730 845
 
731 846
 Check response status for exact match.
732 847
 
733
-=head2 C<status_isnt>
848
+=head2 status_isnt
734 849
 
735 850
   $t = $t->status_isnt(200);
736 851
   $t = $t->status_isnt(200, 'different status');
737 852
 
738 853
 Opposite of C<status_is>.
739 854
 
740
-=head2 C<text_is>
855
+=head2 text_is
741 856
 
742 857
   $t = $t->text_is('div.foo[x=y]' => 'Hello!');
743 858
   $t = $t->text_is('html head title' => 'Hello!', 'right title');
... ...
@@ -745,14 +860,14 @@ Opposite of C<status_is>.
745 860
 Checks text content of the CSS selectors first matching HTML/XML element for
746 861
 exact match with L<Mojo::DOM>.
747 862
 
748
-=head2 C<text_isnt>
863
+=head2 text_isnt
749 864
 
750 865
   $t = $t->text_isnt('div.foo[x=y]' => 'Hello!');
751 866
   $t = $t->text_isnt('html head title' => 'Hello!', 'different title');
752 867
 
753 868
 Opposite of C<text_is>.
754 869
 
755
-=head2 C<text_like>
870
+=head2 text_like
756 871
 
757 872
   $t = $t->text_like('div.foo[x=y]' => qr/Hello/);
758 873
   $t = $t->text_like('html head title' => qr/Hello/, 'right title');
... ...
@@ -760,14 +875,14 @@ Opposite of C<text_is>.
760 875
 Checks text content of the CSS selectors first matching HTML/XML element for
761 876
 similar match with L<Mojo::DOM>.
762 877
 
763
-=head2 C<text_unlike>
878
+=head2 text_unlike
764 879
 
765 880
   $t = $t->text_unlike('div.foo[x=y]' => qr/Hello/);
766 881
   $t = $t->text_unlike('html head title' => qr/Hello/, 'different title');
767 882
 
768 883
 Opposite of C<text_like>.
769 884
 
770
-=head2 C<websocket_ok>
885
+=head2 websocket_ok
771 886
 
772 887
   $t = $t->websocket_ok('/echo');
773 888
   $t = $t->websocket_ok('/echo' => {DNT => 1});
+35 -45
mojolegacy/lib/ojo.pm
... ...
@@ -4,14 +4,14 @@ use Mojo::Base -strict;
4 4
 use Mojo::ByteStream 'b';
5 5
 use Mojo::Collection 'c';
6 6
 use Mojo::DOM;
7
-use Mojo::JSON;
7
+use Mojo::JSON 'j';
8 8
 use Mojo::UserAgent;
9 9
 use Mojo::Util 'monkey_patch';
10 10
 
11 11
 # Silent oneliners
12 12
 $ENV{MOJO_LOG_LEVEL} ||= 'fatal';
13 13
 
14
-# User agent
14
+# Singleton user agent for oneliners
15 15
 my $UA = Mojo::UserAgent->new;
16 16
 
17 17
 sub import {
... ...
@@ -19,38 +19,28 @@ sub import {
19 19
   # Mojolicious::Lite
20 20
   my $caller = caller;
21 21
   eval "package $caller; use Mojolicious::Lite;";
22
+  $UA->app($caller->app);
22 23
 
23
-  # Allow redirects
24 24
   $UA->max_redirects(10) unless defined $ENV{MOJO_MAX_REDIRECTS};
25
-
26
-  # Detect proxy
27 25
   $UA->detect_proxy unless defined $ENV{MOJO_PROXY};
28 26
 
29
-  # Application
30
-  $UA->app($caller->app);
31
-
32
-  # Functions
33
-  monkey_patch $caller, 'a',
34
-    sub { $caller->can('any')->(@_) and return $UA->app };
35
-  monkey_patch $caller, 'b', \&b;
36
-  monkey_patch $caller, 'c', \&c;
37
-  monkey_patch $caller, 'd', sub { _request($UA->build_tx(DELETE => @_)) };
38
-  monkey_patch $caller, 'f', sub { _request($UA->build_form_tx(@_)) };
39
-  monkey_patch $caller, 'g', sub { _request($UA->build_tx(GET => @_)) };
40
-  monkey_patch $caller, 'h', sub { _request($UA->build_tx(HEAD => @_)) };
41
-  monkey_patch $caller, 'j', sub {
42
-    my $d = shift;
43
-    my $j = Mojo::JSON->new;
44
-    return $j->encode($d) if ref $d eq 'ARRAY' || ref $d eq 'HASH';
45
-    return $j->decode($d);
46
-  };
47
-  monkey_patch $caller, 'n', sub { _request($UA->build_json_tx(@_)) };
48
-  monkey_patch $caller, 'o', sub { _request($UA->build_tx(OPTIONS => @_)) };
49
-  monkey_patch $caller, 'p', sub { _request($UA->build_tx(POST => @_)) };
50
-  monkey_patch $caller, 'r', sub { $UA->app->dumper(@_) };
51
-  monkey_patch $caller, 't', sub { _request($UA->build_tx(PATCH => @_)) };
52
-  monkey_patch $caller, 'u', sub { _request($UA->build_tx(PUT => @_)) };
53
-  monkey_patch $caller, 'x', sub { Mojo::DOM->new(@_) };
27
+  # The ojo DSL
28
+  monkey_patch $caller,
29
+    a => sub { $caller->can('any')->(@_) and return $UA->app },
30
+    b => \&b,
31
+    c => \&c,
32
+    d => sub { _request($UA->build_tx(DELETE => @_)) },
33
+    f => sub { _request($UA->build_form_tx(@_)) },
34
+    g => sub { _request($UA->build_tx(GET    => @_)) },
35
+    h => sub { _request($UA->build_tx(HEAD   => @_)) },
36
+    j => \&j,
37
+    n => sub { _request($UA->build_json_tx(@_)) },
38
+    o => sub { _request($UA->build_tx(OPTIONS => @_)) },
39
+    p => sub { _request($UA->build_tx(POST => @_)) },
40
+    r => sub { $UA->app->dumper(@_) },
41
+    t => sub { _request($UA->build_tx(PATCH => @_)) },
42
+    u => sub { _request($UA->build_tx(PUT => @_)) },
43
+    x => sub { Mojo::DOM->new(@_) };
54 44
 }
55 45
 
56 46
 sub _request {
... ...
@@ -88,7 +78,7 @@ C<MOJO_PROXY> environment variable.
88 78
 
89 79
 L<ojo> implements the following functions.
90 80
 
91
-=head2 C<a>
81
+=head2 a
92 82
 
93 83
   my $app = a('/hello' => sub { shift->render(json => {hello => 'world'}) });
94 84
 
... ...
@@ -98,7 +88,7 @@ more argument variations.
98 88
 
99 89
   $ perl -Mojo -E 'a("/hello" => {text => "Hello Mojo!"})->start' daemon
100 90
 
101
-=head2 C<b>
91
+=head2 b
102 92
 
103 93
   my $stream = b('lalala');
104 94
 
... ...
@@ -106,13 +96,13 @@ Turn string into a L<Mojo::ByteStream> object.
106 96
 
107 97
   $ perl -Mojo -E 'b(g("mojolicio.us")->body)->html_unescape->say'
108 98
 
109
-=head2 C<c>
99
+=head2 c
110 100
 
111 101
   my $collection = c(1, 2, 3);
112 102
 
113 103
 Turn list into a L<Mojo::Collection> object.
114 104
 
115
-=head2 C<d>
105
+=head2 d
116 106
 
117 107
   my $res = d('mojolicio.us');
118 108
   my $res = d('http://mojolicio.us' => {DNT => 1} => 'Hi!');
... ...
@@ -120,7 +110,7 @@ Turn list into a L<Mojo::Collection> object.
120 110
 Perform C<DELETE> request with L<Mojo::UserAgent/"delete"> and return
121 111
 resulting L<Mojo::Message::Response> object.
122 112
 
123
-=head2 C<f>
113
+=head2 f
124 114
 
125 115
   my $res = f('http://kraih.com' => {a => 'b'});
126 116
   my $res = f('kraih.com' => 'UTF-8' => {a => 'b'} => {DNT => 1});
... ...
@@ -128,7 +118,7 @@ resulting L<Mojo::Message::Response> object.
128 118
 Perform C<POST> request with L<Mojo::UserAgent/"post_form"> and return
129 119
 resulting L<Mojo::Message::Response> object.
130 120
 
131
-=head2 C<g>
121
+=head2 g
132 122
 
133 123
   my $res = g('mojolicio.us');
134 124
   my $res = g('http://mojolicio.us' => {DNT => 1} => 'Hi!');
... ...
@@ -138,7 +128,7 @@ L<Mojo::Message::Response> object.
138 128
 
139 129
   $ perl -Mojo -E 'say g("mojolicio.us")->dom("h1, h2, h3")->pluck("text")'
140 130
 
141
-=head2 C<h>
131
+=head2 h
142 132
 
143 133
   my $res = h('mojolicio.us');
144 134
   my $res = h('http://mojolicio.us' => {DNT => 1} => 'Hi!');
... ...
@@ -146,7 +136,7 @@ L<Mojo::Message::Response> object.
146 136
 Perform C<HEAD> request with L<Mojo::UserAgent/"head"> and return resulting
147 137
 L<Mojo::Message::Response> object.
148 138
 
149
-=head2 C<j>
139
+=head2 j
150 140
 
151 141
   my $bytes = j({foo => 'bar'});
152 142
   my $array = j($bytes);
... ...
@@ -156,7 +146,7 @@ Encode Perl data structure or decode JSON with L<Mojo::JSON>.
156 146
 
157 147
   $ perl -Mojo -E 'b(j({hello => "world!"}))->spurt("hello.json")'
158 148
 
159
-=head2 C<n>
149
+=head2 n
160 150
 
161 151
   my $res = n('http://kraih.com' => {a => 'b'});
162 152
   my $res = n('kraih.com' => {a => 'b'} => {DNT => 1});
... ...
@@ -164,7 +154,7 @@ Encode Perl data structure or decode JSON with L<Mojo::JSON>.
164 154
 Perform C<POST> request with L<Mojo::UserAgent/"post_json"> and return
165 155
 resulting L<Mojo::Message::Response> object.
166 156
 
167
-=head2 C<o>
157
+=head2 o
168 158
 
169 159
   my $res = o('mojolicio.us');
170 160
   my $res = o('http://mojolicio.us' => {DNT => 1} => 'Hi!');
... ...
@@ -172,7 +162,7 @@ resulting L<Mojo::Message::Response> object.
172 162
 Perform C<OPTIONS> request with L<Mojo::UserAgent/"options"> and return
173 163
 resulting L<Mojo::Message::Response> object.
174 164
 
175
-=head2 C<p>
165
+=head2 p
176 166
 
177 167
   my $res = p('mojolicio.us');
178 168
   my $res = p('http://mojolicio.us' => {DNT => 1} => 'Hi!');
... ...
@@ -180,7 +170,7 @@ resulting L<Mojo::Message::Response> object.
180 170
 Perform C<POST> request with L<Mojo::UserAgent/"post"> and return resulting
181 171
 L<Mojo::Message::Response> object.
182 172
 
183
-=head2 C<r>
173
+=head2 r
184 174
 
185 175
   my $perl = r({data => 'structure'});
186 176
 
... ...
@@ -188,7 +178,7 @@ Dump a Perl data structure with L<Data::Dumper>.
188 178
 
189 179
   perl -Mojo -E 'say r(g("mojolicio.us")->headers->to_hash)'
190 180
 
191
-=head2 C<t>
181
+=head2 t
192 182
 
193 183
   my $res = t('mojolicio.us');
194 184
   my $res = t('http://mojolicio.us' => {DNT => 1} => 'Hi!');
... ...
@@ -196,7 +186,7 @@ Dump a Perl data structure with L<Data::Dumper>.
196 186
 Perform C<PATCH> request with L<Mojo::UserAgent/"patch"> and return resulting
197 187
 L<Mojo::Message::Response> object.
198 188
 
199
-=head2 C<u>
189
+=head2 u
200 190
 
201 191
   my $res = u('mojolicio.us');
202 192
   my $res = u('http://mojolicio.us' => {DNT => 1} => 'Hi!');
... ...
@@ -204,7 +194,7 @@ L<Mojo::Message::Response> object.
204 194
 Perform C<PUT> request with L<Mojo::UserAgent/"put"> and return resulting
205 195
 L<Mojo::Message::Response> object.
206 196
 
207
-=head2 C<x>
197
+=head2 x
208 198
 
209 199
   my $dom = x('<div>Hello!</div>');
210 200
 
-1
mojolegacy/script/hypnotoad
... ...
@@ -15,7 +15,6 @@ GetOptions(
15 15
   't|test'       => sub { $ENV{HYPNOTOAD_TEST}       = 1 }
16 16
 );
17 17
 
18
-# Usage
19 18
 die <<"EOF" if $help || !(my $app = shift || $ENV{HYPNOTOAD_APP});
20 19
 usage: $0 [OPTIONS] [APPLICATION]
21 20
 
+1 -1
mojolegacy/script/mojo
... ...
@@ -7,7 +7,7 @@ use FindBin;
7 7
 use lib "$FindBin::Bin/../lib";
8 8
 
9 9
 require Mojolicious::Commands;
10
-Mojolicious::Commands->start;
10
+Mojolicious::Commands->start_app('Mojo::HelloWorld');
11 11
 
12 12
 =head1 NAME
13 13
 
-1
mojolegacy/script/morbo
... ...
@@ -15,7 +15,6 @@ GetOptions(
15 15
   'w|watch=s'  => \my @watch
16 16
 );
17 17
 
18
-# Usage
19 18
 die <<"EOF" if $help || !(my $app = shift);
20 19
 usage: $0 [OPTIONS] [APPLICATION]
21 20
 
+1 -4
script/gitprep
... ...
@@ -16,8 +16,5 @@ Please visit http://mojolicio.us for detailed installation instructions.
16 16
 
17 17
 EOF
18 18
 
19
-# Application
20
-$ENV{MOJO_APP} ||= 'Gitprep';
21
-
22 19
 # Start commands
23
-Mojolicious::Commands->start;
20
+Mojolicious::Commands->start_app('Gitprep');
+13 -4
templates/main/project.html.ep
... ...
@@ -64,12 +64,20 @@
64 64
 
65 65
 % layout 'common';
66 66
 
67
+  % my $logined = $api->logined;
68
+
67 69
   %= javascript begin
68 70
     $(document).ready(function () {
69 71
       var http_rep_url = '<%= url_for("$user/$project.git")->to_abs %>';
70 72
       % my $execute_user = getpwuid($>);
71 73
       % my $rep = $git->rep($user, $project);
72
-      var ssh_rep_url = '<%= url_for($rep)->to_abs->scheme('ssh')->userinfo($execute_user)->port('') %>';
74
+      % my $ssh_port = config->{basic}{ssh_port} || '';
75
+      
76
+      var logined = <%= $logined ? 'true' : 'false' %>;
77
+      var ssh_rep_url = '';
78
+      if (logined) {
79
+        ssh_rep_url = '<%= url_for($rep)->to_abs->scheme('ssh')->userinfo($execute_user)->port($ssh_port) %>';
80
+      }
73 81
       
74 82
       // Click HTTP button
75 83
       $('#btn_http').on('click', function () {
... ...
@@ -84,7 +92,6 @@
84 92
       });
85 93
 
86 94
       // Initialize
87
-      var logined = <%= $api->logined ? 'true' : 'false' %>;
88 95
       if (logined) {
89 96
         $('#btn_ssh').trigger('click');
90 97
       }
... ...
@@ -111,7 +118,9 @@
111 118
         <div class="input-append" style="margin-top:10px">
112 119
           <div class="btn-group" data-toggle="buttons-radio">
113 120
             <button class="btn" id="btn_http" style="border-radius:0">HTTP</button>
114
-            <button class="btn" id="btn_ssh" style="border-radius:0">SSH</button>
121
+            % if ($logined) {
122
+              <button class="btn" id="btn_ssh" style="border-radius:0">SSH</button>
123
+            % }
115 124
           </div>
116 125
           <input class="span8" id="rep_url" type="text" style="border-radius:0;">
117 126
         </div>
... ...
@@ -144,7 +153,7 @@
144 153
       </div>
145 154
       
146 155
       % my $url = url_for->to_abs;
147
-      % my $ssh_port = config->{ssh_port};
156
+      % my $ssh_port = config->{basic}{ssh_port};
148 157
       % my $rep_home = app->git->rep_home;
149 158
       % my $ssh_url = 'ssh://kimoto@' . $url->host
150 159
       %   . ($ssh_port ? ":$ssh_port" : '') . "$rep_home/$user/$project.git";