jekyll 2.0.0.rc1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of jekyll might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/History.markdown +40 -0
- data/README.markdown +3 -3
- data/features/collections.feature +24 -0
- data/features/embed_filters.feature +32 -0
- data/features/site_configuration.feature +9 -0
- data/features/step_definitions/jekyll_steps.rb +2 -2
- data/features/support/env.rb +5 -1
- data/jekyll.gemspec +3 -3
- data/lib/jekyll/commands/build.rb +3 -3
- data/lib/jekyll/commands/doctor.rb +1 -1
- data/lib/jekyll/commands/new.rb +1 -1
- data/lib/jekyll/commands/serve.rb +45 -23
- data/lib/jekyll/configuration.rb +1 -2
- data/lib/jekyll/converters/markdown/redcarpet_parser.rb +1 -1
- data/lib/jekyll/convertible.rb +2 -2
- data/lib/jekyll/document.rb +10 -0
- data/lib/jekyll/entry_filter.rb +1 -3
- data/lib/jekyll/filters.rb +34 -0
- data/lib/jekyll/post.rb +1 -0
- data/lib/jekyll/site.rb +9 -10
- data/lib/jekyll/stevenson.rb +23 -10
- data/lib/jekyll/tags/highlight.rb +24 -48
- data/lib/jekyll/utils.rb +10 -10
- data/lib/jekyll/version.rb +1 -1
- data/lib/site_template/_config.yml +9 -4
- data/lib/site_template/_includes/footer.html +9 -9
- data/lib/site_template/_includes/head.html +3 -3
- data/lib/site_template/_includes/header.html +5 -4
- data/lib/site_template/{about/index.md → about.md} +2 -1
- data/lib/site_template/css/main.css +6 -1
- data/lib/site_template/feed.xml +5 -5
- data/lib/site_template/index.html +6 -3
- data/site/_config.yml +1 -1
- data/site/_includes/css/style.css +180 -120
- data/site/_includes/footer.html +1 -1
- data/site/_includes/top.html +1 -1
- data/site/_posts/2014-05-06-jekyll-turns-2-0-0.markdown +31 -0
- data/site/docs/assets.md +0 -8
- data/site/docs/collections.md +11 -9
- data/site/docs/configuration.md +28 -10
- data/site/docs/deployment-methods.md +1 -1
- data/site/docs/history.md +227 -0
- data/site/docs/permalinks.md +8 -0
- data/site/docs/plugins.md +2 -1
- data/site/docs/templates.md +43 -0
- data/site/docs/variables.md +8 -3
- data/site/js/html5shiv.min.js +4 -0
- data/test/helper.rb +10 -0
- data/test/source/+/foo.md +1 -1
- data/test/test_collections.rb +2 -2
- data/test/test_configuration.rb +2 -2
- data/test/test_convertible.rb +3 -3
- data/test/test_entry_filter.rb +16 -0
- data/test/test_filters.rb +25 -0
- data/test/test_new_command.rb +1 -1
- data/test/test_redcarpet.rb +3 -3
- data/test/test_sass.rb +0 -41
- data/test/test_tags.rb +4 -4
- metadata +19 -19
- data/lib/site_template/projects/index.md +0 -14
- data/site/js/html5shiv.js +0 -8
data/lib/jekyll/entry_filter.rb
CHANGED
@@ -65,9 +65,7 @@ module Jekyll
|
|
65
65
|
entry = ensure_leading_slash(e)
|
66
66
|
enum.any? do |exp|
|
67
67
|
item = ensure_leading_slash(exp)
|
68
|
-
|
69
|
-
Jekyll.logger.debug " ==> File.fnmatch?(#{item}, #{entry}) == #{File.fnmatch?(item, entry)}"
|
70
|
-
File.fnmatch?(item, entry)
|
68
|
+
File.fnmatch?(item, entry) || entry.start_with?(item)
|
71
69
|
end
|
72
70
|
end
|
73
71
|
end
|
data/lib/jekyll/filters.rb
CHANGED
@@ -190,6 +190,40 @@ module Jekyll
|
|
190
190
|
input.select { |object| object[key] == value }
|
191
191
|
end
|
192
192
|
|
193
|
+
# Sort an array of objects
|
194
|
+
#
|
195
|
+
# input - the object array
|
196
|
+
# key - key within each object to filter by
|
197
|
+
# nils ('first' | 'last') - nils appear before or after non-nil values
|
198
|
+
#
|
199
|
+
# Returns the filtered array of objects
|
200
|
+
def sort(input, key = nil, nils = "first")
|
201
|
+
if key.nil?
|
202
|
+
input.sort
|
203
|
+
else
|
204
|
+
case
|
205
|
+
when nils == "first"
|
206
|
+
order = - 1
|
207
|
+
when nils == "last"
|
208
|
+
order = + 1
|
209
|
+
else
|
210
|
+
Jekyll.logger.error "Invalid nils order:",
|
211
|
+
"'#{nils}' is not a valid nils order. It must be 'first' or 'last'."
|
212
|
+
exit(1)
|
213
|
+
end
|
214
|
+
|
215
|
+
input.sort { |a, b|
|
216
|
+
if !a[key].nil? && b[key].nil?
|
217
|
+
- order
|
218
|
+
elsif a[key].nil? && !b[key].nil?
|
219
|
+
+ order
|
220
|
+
else
|
221
|
+
a[key] <=> b[key]
|
222
|
+
end
|
223
|
+
}
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
193
227
|
private
|
194
228
|
def time(input)
|
195
229
|
case input
|
data/lib/jekyll/post.rb
CHANGED
@@ -225,6 +225,7 @@ module Jekyll
|
|
225
225
|
:i_month => date.strftime("%m").to_i.to_s,
|
226
226
|
:categories => (categories || []).map { |c| c.to_s }.join('/'),
|
227
227
|
:short_month => date.strftime("%b"),
|
228
|
+
:short_year => date.strftime("%y"),
|
228
229
|
:y_day => date.strftime("%j"),
|
229
230
|
:output_ext => output_ext
|
230
231
|
}
|
data/lib/jekyll/site.rb
CHANGED
@@ -325,6 +325,7 @@ module Jekyll
|
|
325
325
|
"categories" => post_attr_hash('categories'),
|
326
326
|
"tags" => post_attr_hash('tags'),
|
327
327
|
"collections" => collections,
|
328
|
+
"documents" => documents,
|
328
329
|
"data" => site_data
|
329
330
|
}))
|
330
331
|
}
|
@@ -395,28 +396,26 @@ module Jekyll
|
|
395
396
|
|
396
397
|
def relative_permalinks_deprecation_method
|
397
398
|
if config['relative_permalinks'] && has_relative_page?
|
398
|
-
$stderr.puts # Places newline after "Generating..."
|
399
399
|
Jekyll.logger.warn "Deprecation:", "Starting in 2.0, permalinks for pages" +
|
400
400
|
" in subfolders must be relative to the" +
|
401
401
|
" site source directory, not the parent" +
|
402
402
|
" directory. Check http://jekyllrb.com/docs/upgrading/"+
|
403
403
|
" for more info."
|
404
|
-
$stderr.print Jekyll.logger.formatted_topic("") + "..." # for "done."
|
405
404
|
end
|
406
405
|
end
|
407
406
|
|
407
|
+
def docs_to_write
|
408
|
+
documents.select(&:write?)
|
409
|
+
end
|
410
|
+
|
408
411
|
def documents
|
409
412
|
collections.reduce(Set.new) do |docs, (_, collection)|
|
410
|
-
|
411
|
-
|
412
|
-
else
|
413
|
-
docs
|
414
|
-
end
|
415
|
-
end
|
413
|
+
docs.merge(collection.docs)
|
414
|
+
end.to_a
|
416
415
|
end
|
417
416
|
|
418
417
|
def each_site_file
|
419
|
-
%w(posts pages static_files
|
418
|
+
%w(posts pages static_files docs_to_write).each do |type|
|
420
419
|
send(type).each do |item|
|
421
420
|
yield item
|
422
421
|
end
|
@@ -434,7 +433,7 @@ module Jekyll
|
|
434
433
|
end
|
435
434
|
|
436
435
|
def has_yaml_header?(file)
|
437
|
-
!!(File.open(file,
|
436
|
+
!!(File.open(file, 'rb') { |f| f.read(5) } =~ /\A---\r?\n/)
|
438
437
|
end
|
439
438
|
|
440
439
|
def limit_posts!
|
data/lib/jekyll/stevenson.rb
CHANGED
@@ -2,17 +2,19 @@ module Jekyll
|
|
2
2
|
class Stevenson
|
3
3
|
attr_accessor :log_level
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
LOG_LEVELS = {
|
6
|
+
debug: 0,
|
7
|
+
info: 1,
|
8
|
+
warn: 2,
|
9
|
+
error: 3
|
10
|
+
}
|
9
11
|
|
10
12
|
# Public: Create a new instance of Stevenson, Jekyll's logger
|
11
13
|
#
|
12
|
-
# level - (optional,
|
14
|
+
# level - (optional, symbol) the log level
|
13
15
|
#
|
14
16
|
# Returns nothing
|
15
|
-
def initialize(level =
|
17
|
+
def initialize(level = :info)
|
16
18
|
@log_level = level
|
17
19
|
end
|
18
20
|
|
@@ -23,7 +25,7 @@ module Jekyll
|
|
23
25
|
#
|
24
26
|
# Returns nothing
|
25
27
|
def debug(topic, message = nil)
|
26
|
-
$stdout.puts(message(topic, message)) if
|
28
|
+
$stdout.puts(message(topic, message)) if should_log(:debug)
|
27
29
|
end
|
28
30
|
|
29
31
|
# Public: Print a jekyll message to stdout
|
@@ -33,7 +35,7 @@ module Jekyll
|
|
33
35
|
#
|
34
36
|
# Returns nothing
|
35
37
|
def info(topic, message = nil)
|
36
|
-
$stdout.puts(message(topic, message)) if
|
38
|
+
$stdout.puts(message(topic, message)) if should_log(:info)
|
37
39
|
end
|
38
40
|
|
39
41
|
# Public: Print a jekyll message to stderr
|
@@ -43,7 +45,7 @@ module Jekyll
|
|
43
45
|
#
|
44
46
|
# Returns nothing
|
45
47
|
def warn(topic, message = nil)
|
46
|
-
$stderr.puts(message(topic, message).yellow) if
|
48
|
+
$stderr.puts(message(topic, message).yellow) if should_log(:warn)
|
47
49
|
end
|
48
50
|
|
49
51
|
# Public: Print a jekyll error message to stderr
|
@@ -53,7 +55,7 @@ module Jekyll
|
|
53
55
|
#
|
54
56
|
# Returns nothing
|
55
57
|
def error(topic, message = nil)
|
56
|
-
$stderr.puts(message(topic, message).red) if
|
58
|
+
$stderr.puts(message(topic, message).red) if should_log(:error)
|
57
59
|
end
|
58
60
|
|
59
61
|
# Public: Print a Jekyll error message to stderr and immediately abort the process
|
@@ -85,5 +87,16 @@ module Jekyll
|
|
85
87
|
def formatted_topic(topic)
|
86
88
|
"#{topic} ".rjust(20)
|
87
89
|
end
|
90
|
+
|
91
|
+
# Public: Determine whether the current log level warrants logging at the
|
92
|
+
# proposed level.
|
93
|
+
#
|
94
|
+
# level_of_message - the log level of the message (symbol)
|
95
|
+
#
|
96
|
+
# Returns true if the log level of the message is greater than or equal to
|
97
|
+
# this logger's log level.
|
98
|
+
def should_log(level_of_message)
|
99
|
+
LOG_LEVELS.fetch(log_level) <= LOG_LEVELS.fetch(level_of_message)
|
100
|
+
end
|
88
101
|
end
|
89
102
|
end
|
@@ -5,10 +5,7 @@ module Jekyll
|
|
5
5
|
|
6
6
|
# The regular expression syntax checker. Start with the language specifier.
|
7
7
|
# Follow that by zero or more space separated options that take one of two
|
8
|
-
# forms:
|
9
|
-
#
|
10
|
-
# 1. name
|
11
|
-
# 2. name=value
|
8
|
+
# forms: name or name=value
|
12
9
|
SYNTAX = /^([a-zA-Z0-9.+#-]+)((\s+\w+(=\w+)?)*)$/
|
13
10
|
|
14
11
|
def initialize(tag_name, markup, tokens)
|
@@ -19,16 +16,10 @@ module Jekyll
|
|
19
16
|
if defined?($2) && $2 != ''
|
20
17
|
$2.split.each do |opt|
|
21
18
|
key, value = opt.split('=')
|
22
|
-
|
23
|
-
if key == 'linenos'
|
24
|
-
value = 'inline'
|
25
|
-
else
|
26
|
-
value = true
|
27
|
-
end
|
28
|
-
end
|
29
|
-
@options[key] = value
|
19
|
+
@options[key.to_sym] = value || true
|
30
20
|
end
|
31
21
|
end
|
22
|
+
@options[:linenos] = "inline" if @options.key?(:linenos) and @options[:linenos] == true
|
32
23
|
else
|
33
24
|
raise SyntaxError.new <<-eos
|
34
25
|
Syntax Error in tag 'highlight' while parsing the following markup:
|
@@ -41,20 +32,25 @@ eos
|
|
41
32
|
end
|
42
33
|
|
43
34
|
def render(context)
|
35
|
+
prefix = context["highlighter_prefix"] || ""
|
36
|
+
suffix = context["highlighter_suffix"] || ""
|
44
37
|
code = super.to_s.strip
|
45
|
-
|
38
|
+
|
39
|
+
output = case context.registers[:site].highlighter
|
46
40
|
when 'pygments'
|
47
|
-
render_pygments(
|
41
|
+
render_pygments(code)
|
48
42
|
when 'rouge'
|
49
|
-
render_rouge(
|
43
|
+
render_rouge(code)
|
50
44
|
else
|
51
|
-
render_codehighlighter(
|
52
|
-
end
|
45
|
+
render_codehighlighter(code)
|
46
|
+
end
|
47
|
+
|
48
|
+
rendered_output = add_code_tag(output)
|
49
|
+
prefix + rendered_output + suffix
|
53
50
|
end
|
54
51
|
|
55
|
-
def render_pygments(
|
52
|
+
def render_pygments(code)
|
56
53
|
require 'pygments'
|
57
|
-
|
58
54
|
@options[:encoding] = 'utf-8'
|
59
55
|
|
60
56
|
highlighted_code = Pygments.highlight(code, :lexer => @lang, :options => @options)
|
@@ -70,44 +66,24 @@ eos
|
|
70
66
|
raise ArgumentError.new("Pygments.rb returned an unacceptable value when attempting to highlight some code.")
|
71
67
|
end
|
72
68
|
|
73
|
-
|
74
|
-
|
75
|
-
output = context["highlighter_prefix"] + output if context["highlighter_prefix"]
|
76
|
-
output << context["highlighter_suffix"] if context["highlighter_suffix"]
|
77
|
-
|
78
|
-
return output
|
69
|
+
highlighted_code
|
79
70
|
end
|
80
71
|
|
81
|
-
def render_rouge(
|
72
|
+
def render_rouge(code)
|
82
73
|
require 'rouge'
|
83
|
-
|
84
|
-
linenos = @options.keys.include?('linenos')
|
74
|
+
formatter = Rouge::Formatters::HTML.new(line_numbers: @options[:linenos], wrap: false)
|
85
75
|
lexer = Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText
|
86
|
-
|
87
|
-
|
88
|
-
pre = "<pre>#{formatter.format(lexer.lex(code))}</pre>"
|
89
|
-
|
90
|
-
output = context["highlighter_prefix"] || ""
|
91
|
-
output << "<div class=\"highlight\">"
|
92
|
-
output << add_code_tags(pre, @lang)
|
93
|
-
output << "</div>"
|
94
|
-
output << context["highlighter_suffix"] if context["highlighter_suffix"]
|
95
|
-
|
96
|
-
return output
|
76
|
+
code = formatter.format(lexer.lex(code))
|
77
|
+
"<div class=\"highlight\"><pre>#{code}</pre></div>"
|
97
78
|
end
|
98
79
|
|
99
|
-
def render_codehighlighter(
|
100
|
-
|
101
|
-
<<-HTML
|
102
|
-
<div>
|
103
|
-
<pre><code class='#{@lang.to_s.gsub("+", "-")}'>#{h(code).strip}</code></pre>
|
104
|
-
</div>
|
105
|
-
HTML
|
80
|
+
def render_codehighlighter(code)
|
81
|
+
"<div class=\"highlight\"><pre>#{h(code).strip}</pre></div>"
|
106
82
|
end
|
107
83
|
|
108
|
-
def
|
84
|
+
def add_code_tag(code)
|
109
85
|
# Add nested <code> tags to code blocks
|
110
|
-
code = code.sub(/<pre>\n*/,'<pre><code class="' + lang.to_s.gsub("+", "-") + '">')
|
86
|
+
code = code.sub(/<pre>\n*/,'<pre><code class="' + @lang.to_s.gsub("+", "-") + '">')
|
111
87
|
code = code.sub(/\n*<\/pre>/,"</code></pre>")
|
112
88
|
code.strip
|
113
89
|
end
|
data/lib/jekyll/utils.rb
CHANGED
@@ -48,17 +48,21 @@ module Jekyll
|
|
48
48
|
array || []
|
49
49
|
end
|
50
50
|
|
51
|
+
def transform_keys(hash)
|
52
|
+
result = {}
|
53
|
+
hash.each_key do |key|
|
54
|
+
result[yield(key)] = hash[key]
|
55
|
+
end
|
56
|
+
result
|
57
|
+
end
|
58
|
+
|
51
59
|
# Apply #to_sym to all keys in the hash
|
52
60
|
#
|
53
61
|
# hash - the hash to which to apply this transformation
|
54
62
|
#
|
55
63
|
# Returns a new hash with symbolized keys
|
56
64
|
def symbolize_hash_keys(hash)
|
57
|
-
|
58
|
-
target.keys.each do |key|
|
59
|
-
target[(key.to_sym rescue key) || key] = target.delete(key)
|
60
|
-
end
|
61
|
-
target
|
65
|
+
transform_keys(hash) { |key| key.to_sym rescue key }
|
62
66
|
end
|
63
67
|
|
64
68
|
# Apply #to_s to all keys in the Hash
|
@@ -67,11 +71,7 @@ module Jekyll
|
|
67
71
|
#
|
68
72
|
# Returns a new hash with stringified keys
|
69
73
|
def stringify_hash_keys(hash)
|
70
|
-
|
71
|
-
target.keys.each do |key|
|
72
|
-
target[(key.to_s rescue key) || key] = target.delete(key)
|
73
|
-
end
|
74
|
-
target
|
74
|
+
transform_keys(hash) { |key| key.to_s rescue key }
|
75
75
|
end
|
76
76
|
|
77
77
|
end
|
data/lib/jekyll/version.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
+
# Site settings
|
1
2
|
name: Dat site title tho
|
2
|
-
|
3
|
-
|
4
|
-
description: "Write an awesome description for your new site here. It will appear in your document head meta (for Google search results) and in your feed.xml site description."
|
5
|
-
|
3
|
+
title: Your awesome title
|
4
|
+
email: your-email@domain.com
|
5
|
+
description: "Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description."
|
6
|
+
baseurl: "http://yourdomain.com"
|
7
|
+
|
8
|
+
# Build settings
|
9
|
+
markdown: kramdown
|
10
|
+
permalinks: pretty
|
@@ -2,19 +2,19 @@
|
|
2
2
|
|
3
3
|
<div class="wrap">
|
4
4
|
|
5
|
-
<h2 class="footer-heading">
|
5
|
+
<h2 class="footer-heading">{{ site.name }}</h2>
|
6
6
|
|
7
7
|
<div class="footer-col-1 column">
|
8
8
|
<ul>
|
9
|
-
<li>
|
10
|
-
<li><a href="mailto:
|
9
|
+
<li>{{ site.title }}</li>
|
10
|
+
<li><a href="mailto:{{ site.email }}">{{ site.email }}</a></li>
|
11
11
|
</ul>
|
12
12
|
</div>
|
13
13
|
|
14
14
|
<div class="footer-col-2 column">
|
15
15
|
<ul>
|
16
16
|
<li>
|
17
|
-
<a href="https://github.com/
|
17
|
+
<a href="https://github.com/{{ site.username }}">
|
18
18
|
<span class="icon github">
|
19
19
|
<svg version="1.1" class="github-icon-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
20
20
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
@@ -29,11 +29,11 @@
|
|
29
29
|
c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z"/>
|
30
30
|
</svg>
|
31
31
|
</span>
|
32
|
-
<span class="username">
|
32
|
+
<span class="username">{{ site.username }}</span>
|
33
33
|
</a>
|
34
34
|
</li>
|
35
35
|
<li>
|
36
|
-
<a href="https://twitter.com/
|
36
|
+
<a href="https://twitter.com/{{ site.username }}">
|
37
37
|
<span class="icon twitter">
|
38
38
|
<svg version="1.1" class="twitter-icon-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
39
39
|
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
@@ -46,16 +46,16 @@
|
|
46
46
|
c6.015,0,9.304-4.983,9.304-9.304c0-0.142-0.003-0.283-0.009-0.423C14.976,4.29,15.531,3.714,15.969,3.058z"/>
|
47
47
|
</svg>
|
48
48
|
</span>
|
49
|
-
<span class="username">
|
49
|
+
<span class="username">{{ site.username }}</span>
|
50
50
|
</a>
|
51
51
|
</li>
|
52
52
|
</ul>
|
53
53
|
</div>
|
54
54
|
|
55
55
|
<div class="footer-col-3 column">
|
56
|
-
<p class="text">
|
56
|
+
<p class="text">{{ site.description }}</p>
|
57
57
|
</div>
|
58
58
|
|
59
59
|
</div>
|
60
60
|
|
61
|
-
</footer>
|
61
|
+
</footer>
|
@@ -4,9 +4,9 @@
|
|
4
4
|
<title>{% if page.title %}{{ page.title }}{% else %}{{ site.name }}{% endif %}</title>
|
5
5
|
<meta name="viewport" content="width=device-width">
|
6
6
|
<meta name="description" content="{{ site.description }}">
|
7
|
-
<link rel="canonical" href="{{
|
7
|
+
<link rel="canonical" href="{{ page.url | replace:'index.html','' | prepend: site.baseurl }}">
|
8
8
|
|
9
9
|
<!-- Custom CSS -->
|
10
|
-
<link rel="stylesheet" href="/css/main.css">
|
10
|
+
<link rel="stylesheet" href="{{ "/css/main.css" | prepend: site.baseurl }}">
|
11
11
|
|
12
|
-
</head>
|
12
|
+
</head>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
<div class="wrap">
|
4
4
|
|
5
|
-
<a class="site-title" href="
|
5
|
+
<a class="site-title" href="{{ site.baseurl }}">{{ site.name }}</a>
|
6
6
|
|
7
7
|
<nav class="site-nav">
|
8
8
|
<a href="#" class="menu-icon">
|
@@ -17,11 +17,12 @@
|
|
17
17
|
</svg>
|
18
18
|
</a>
|
19
19
|
<div class="trigger">
|
20
|
-
|
21
|
-
|
20
|
+
{% for page in site.pages %}
|
21
|
+
<a class="page-link" href="{{ page.url | prepend: site.baseurl }}">{{ page.title }}</a>
|
22
|
+
{% endfor %}
|
22
23
|
</div>
|
23
24
|
</nav>
|
24
25
|
|
25
26
|
</div>
|
26
27
|
|
27
|
-
</header>
|
28
|
+
</header>
|