jekyll 3.2.0.pre.beta1 → 3.2.0.pre.beta2

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.

Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +17 -95
  3. data/README.markdown +6 -4
  4. data/{bin → exe}/jekyll +18 -14
  5. data/lib/jekyll.rb +79 -76
  6. data/lib/jekyll/collection.rb +32 -16
  7. data/lib/jekyll/command.rb +17 -13
  8. data/lib/jekyll/commands/build.rb +7 -2
  9. data/lib/jekyll/commands/doctor.rb +3 -1
  10. data/lib/jekyll/commands/new.rb +3 -0
  11. data/lib/jekyll/commands/new_theme.rb +7 -4
  12. data/lib/jekyll/commands/serve.rb +2 -0
  13. data/lib/jekyll/commands/serve/servlet.rb +2 -2
  14. data/lib/jekyll/configuration.rb +187 -125
  15. data/lib/jekyll/converters/markdown.rb +19 -9
  16. data/lib/jekyll/converters/markdown/kramdown_parser.rb +12 -5
  17. data/lib/jekyll/converters/markdown/rdiscount_parser.rb +4 -4
  18. data/lib/jekyll/converters/markdown/redcarpet_parser.rb +90 -84
  19. data/lib/jekyll/convertible.rb +34 -21
  20. data/lib/jekyll/deprecator.rb +11 -6
  21. data/lib/jekyll/document.rb +52 -50
  22. data/lib/jekyll/drops/document_drop.rb +40 -5
  23. data/lib/jekyll/drops/drop.rb +49 -10
  24. data/lib/jekyll/drops/excerpt_drop.rb +15 -0
  25. data/lib/jekyll/drops/jekyll_drop.rb +12 -0
  26. data/lib/jekyll/drops/site_drop.rb +4 -2
  27. data/lib/jekyll/drops/url_drop.rb +4 -4
  28. data/lib/jekyll/entry_filter.rb +9 -6
  29. data/lib/jekyll/errors.rb +4 -3
  30. data/lib/jekyll/excerpt.rb +4 -6
  31. data/lib/jekyll/external.rb +4 -4
  32. data/lib/jekyll/filters.rb +67 -34
  33. data/lib/jekyll/frontmatter_defaults.rb +45 -38
  34. data/lib/jekyll/hooks.rb +21 -21
  35. data/lib/jekyll/layout.rb +3 -1
  36. data/lib/jekyll/liquid_renderer.rb +7 -3
  37. data/lib/jekyll/liquid_renderer/file.rb +1 -1
  38. data/lib/jekyll/liquid_renderer/table.rb +11 -11
  39. data/lib/jekyll/log_adapter.rb +2 -2
  40. data/lib/jekyll/page.rb +10 -10
  41. data/lib/jekyll/plugin.rb +5 -5
  42. data/lib/jekyll/plugin_manager.rb +12 -8
  43. data/lib/jekyll/publisher.rb +1 -1
  44. data/lib/jekyll/reader.rb +11 -7
  45. data/lib/jekyll/readers/data_reader.rb +9 -9
  46. data/lib/jekyll/readers/layout_reader.rb +7 -7
  47. data/lib/jekyll/readers/page_reader.rb +3 -1
  48. data/lib/jekyll/readers/post_reader.rb +9 -10
  49. data/lib/jekyll/readers/static_file_reader.rb +3 -1
  50. data/lib/jekyll/regenerator.rb +50 -28
  51. data/lib/jekyll/related_posts.rb +1 -1
  52. data/lib/jekyll/renderer.rb +29 -20
  53. data/lib/jekyll/site.rb +92 -50
  54. data/lib/jekyll/static_file.rb +33 -26
  55. data/lib/jekyll/stevenson.rb +6 -5
  56. data/lib/jekyll/tags/highlight.rb +50 -35
  57. data/lib/jekyll/tags/include.rb +42 -31
  58. data/lib/jekyll/tags/link.rb +11 -4
  59. data/lib/jekyll/tags/post_url.rb +8 -7
  60. data/lib/jekyll/theme.rb +4 -3
  61. data/lib/jekyll/theme_builder.rb +18 -6
  62. data/lib/jekyll/url.rb +21 -14
  63. data/lib/jekyll/utils.rb +57 -28
  64. data/lib/jekyll/utils/ansi.rb +9 -9
  65. data/lib/jekyll/utils/platforms.rb +2 -2
  66. data/lib/jekyll/version.rb +1 -1
  67. data/lib/site_template/_config.yml +2 -0
  68. data/lib/site_template/css/main.scss +3 -17
  69. data/lib/theme_template/_layouts/default.html +1 -0
  70. data/lib/theme_template/_layouts/page.html +5 -0
  71. data/lib/theme_template/_layouts/post.html +5 -0
  72. data/lib/theme_template/example/_post.md +1 -2
  73. data/lib/theme_template/example/index.html +2 -2
  74. data/lib/theme_template/gitignore.erb +4 -0
  75. data/lib/theme_template/theme.gemspec.erb +2 -6
  76. metadata +10 -18
  77. data/lib/site_template/_includes/footer.html +0 -38
  78. data/lib/site_template/_includes/head.html +0 -12
  79. data/lib/site_template/_includes/header.html +0 -27
  80. data/lib/site_template/_includes/icon-github.html +0 -1
  81. data/lib/site_template/_includes/icon-github.svg +0 -1
  82. data/lib/site_template/_includes/icon-twitter.html +0 -1
  83. data/lib/site_template/_includes/icon-twitter.svg +0 -1
  84. data/lib/site_template/_layouts/default.html +0 -20
  85. data/lib/site_template/_layouts/page.html +0 -14
  86. data/lib/site_template/_layouts/post.html +0 -15
  87. data/lib/site_template/_sass/_base.scss +0 -200
  88. data/lib/site_template/_sass/_layout.scss +0 -242
  89. data/lib/site_template/_sass/_syntax-highlighting.scss +0 -71
@@ -4,38 +4,38 @@ module Jekyll
4
4
 
5
5
  # compatibility layer for octopress-hooks users
6
6
  PRIORITY_MAP = {
7
- :low => 10,
7
+ :low => 10,
8
8
  :normal => 20,
9
- :high => 30
9
+ :high => 30
10
10
  }.freeze
11
11
 
12
12
  # initial empty hooks
13
13
  @registry = {
14
- :site => {
15
- :after_init => [],
14
+ :site => {
15
+ :after_init => [],
16
16
  :after_reset => [],
17
- :post_read => [],
18
- :pre_render => [],
17
+ :post_read => [],
18
+ :pre_render => [],
19
19
  :post_render => [],
20
- :post_write => []
20
+ :post_write => []
21
21
  },
22
- :pages => {
23
- :post_init => [],
24
- :pre_render => [],
22
+ :pages => {
23
+ :post_init => [],
24
+ :pre_render => [],
25
25
  :post_render => [],
26
- :post_write => []
26
+ :post_write => []
27
27
  },
28
- :posts => {
29
- :post_init => [],
30
- :pre_render => [],
28
+ :posts => {
29
+ :post_init => [],
30
+ :pre_render => [],
31
31
  :post_render => [],
32
- :post_write => []
32
+ :post_write => []
33
33
  },
34
34
  :documents => {
35
- :post_init => [],
36
- :pre_render => [],
35
+ :post_init => [],
36
+ :pre_render => [],
37
37
  :post_render => [],
38
- :post_write => []
38
+ :post_write => []
39
39
  }
40
40
  }
41
41
 
@@ -61,10 +61,10 @@ module Jekyll
61
61
  # register a single hook to be called later, internal API
62
62
  def self.register_one(owner, event, priority, &block)
63
63
  @registry[owner] ||={
64
- :post_init => [],
65
- :pre_render => [],
64
+ :post_init => [],
65
+ :pre_render => [],
66
66
  :post_render => [],
67
- :post_write => []
67
+ :post_write => []
68
68
  }
69
69
 
70
70
  unless @registry[owner][event]
@@ -58,7 +58,9 @@ module Jekyll
58
58
  # Returns a String path which represents the relative path
59
59
  # from the site source to this layout
60
60
  def relative_path
61
- @relative_path ||= Pathname.new(path).relative_path_from(Pathname.new(@base_dir)).to_s
61
+ @relative_path ||= Pathname.new(path).relative_path_from(
62
+ Pathname.new(@base_dir)
63
+ ).to_s
62
64
  end
63
65
  end
64
66
  end
@@ -1,10 +1,11 @@
1
- require 'jekyll/liquid_renderer/file'
2
- require 'jekyll/liquid_renderer/table'
1
+ require "jekyll/liquid_renderer/file"
2
+ require "jekyll/liquid_renderer/table"
3
3
 
4
4
  module Jekyll
5
5
  class LiquidRenderer
6
6
  def initialize(site)
7
7
  @site = site
8
+ Liquid::Template.error_mode = @site.config["liquid"]["error_mode"].to_sym
8
9
  reset
9
10
  end
10
11
 
@@ -13,7 +14,10 @@ module Jekyll
13
14
  end
14
15
 
15
16
  def file(filename)
16
- filename = @site.in_source_dir(filename).sub(/\A#{Regexp.escape(@site.source)}\//, '')
17
+ filename = @site.in_source_dir(filename).sub(
18
+ %r!\A#{Regexp.escape(@site.source)}/!,
19
+ ""
20
+ )
17
21
 
18
22
  LiquidRenderer::File.new(self, filename).tap do
19
23
  @stats[filename] ||= {}
@@ -8,7 +8,7 @@ module Jekyll
8
8
 
9
9
  def parse(content)
10
10
  measure_time do
11
- @template = Liquid::Template.parse(content, line_numbers: true)
11
+ @template = Liquid::Template.parse(content, :line_numbers => true)
12
12
  end
13
13
 
14
14
  self
@@ -31,8 +31,8 @@ module Jekyll
31
31
  str = ""
32
32
 
33
33
  row_data.each_index do |cell_index|
34
- str << '-' * widths[cell_index]
35
- str << '-+-' unless cell_index == row_data.length-1
34
+ str << "-" * widths[cell_index]
35
+ str << "-+-" unless cell_index == row_data.length-1
36
36
  end
37
37
 
38
38
  str << "\n"
@@ -40,16 +40,16 @@ module Jekyll
40
40
  end
41
41
 
42
42
  def generate_row(row_data, widths)
43
- str = ''
43
+ str = ""
44
44
 
45
45
  row_data.each_with_index do |cell_data, cell_index|
46
- if cell_index == 0
47
- str << cell_data.ljust(widths[cell_index], ' ')
48
- else
49
- str << cell_data.rjust(widths[cell_index], ' ')
50
- end
46
+ str << if cell_index == 0
47
+ cell_data.ljust(widths[cell_index], " ")
48
+ else
49
+ cell_data.rjust(widths[cell_index], " ")
50
+ end
51
51
 
52
- str << ' | ' unless cell_index == row_data.length-1
52
+ str << " | " unless cell_index == row_data.length-1
53
53
  end
54
54
 
55
55
  str << "\n"
@@ -79,7 +79,7 @@ module Jekyll
79
79
  row << filename
80
80
  row << file_stats[:count].to_s
81
81
  row << format_bytes(file_stats[:bytes])
82
- row << "%.3f" % file_stats[:time]
82
+ row << format("%.3f", file_stats[:time])
83
83
  table << row
84
84
  end
85
85
 
@@ -88,7 +88,7 @@ module Jekyll
88
88
 
89
89
  def format_bytes(bytes)
90
90
  bytes /= 1024.0
91
- "%.2fK" % bytes
91
+ format("%.2fK", bytes)
92
92
  end
93
93
  end
94
94
  end
@@ -7,7 +7,7 @@ module Jekyll
7
7
  :info => ::Logger::INFO,
8
8
  :warn => ::Logger::WARN,
9
9
  :error => ::Logger::ERROR
10
- }
10
+ }.freeze
11
11
 
12
12
  # Public: Create a new instance of a log writer
13
13
  #
@@ -98,7 +98,7 @@ module Jekyll
98
98
  #
99
99
  # Returns the formatted message
100
100
  def message(topic, message)
101
- msg = formatted_topic(topic) + message.to_s.gsub(/\s+/, ' ')
101
+ msg = formatted_topic(topic) + message.to_s.gsub(%r!\s+!, " ")
102
102
  messages << msg
103
103
  msg
104
104
  end
@@ -9,7 +9,7 @@ module Jekyll
9
9
 
10
10
  alias_method :extname, :ext
11
11
 
12
- FORWARD_SLASH = '/'.freeze
12
+ FORWARD_SLASH = "/".freeze
13
13
 
14
14
  # Attributes for Liquid templates
15
15
  ATTRIBUTES_FOR_LIQUID = %w(
@@ -18,16 +18,16 @@ module Jekyll
18
18
  name
19
19
  path
20
20
  url
21
- )
21
+ ).freeze
22
22
 
23
23
  # A set of extensions that are considered HTML or HTML-like so we
24
24
  # should not alter them, this includes .xhtml through XHTM5.
25
25
 
26
- HTML_EXTENSIONS = %W(
26
+ HTML_EXTENSIONS = %w(
27
27
  .html
28
28
  .xhtml
29
29
  .htm
30
- )
30
+ ).freeze
31
31
 
32
32
  # Initialize a new Page.
33
33
  #
@@ -71,7 +71,7 @@ module Jekyll
71
71
  #
72
72
  # Returns the String permalink or nil if none has been set.
73
73
  def permalink
74
- data.nil? ? nil : data['permalink']
74
+ data.nil? ? nil : data["permalink"]
75
75
  end
76
76
 
77
77
  # The template of the permalink.
@@ -92,9 +92,9 @@ module Jekyll
92
92
  # Returns the String url.
93
93
  def url
94
94
  @url ||= URL.new({
95
- :template => template,
95
+ :template => template,
96
96
  :placeholders => url_placeholders,
97
- :permalink => permalink
97
+ :permalink => permalink
98
98
  }).to_s
99
99
  end
100
100
 
@@ -135,12 +135,12 @@ module Jekyll
135
135
  #
136
136
  # Returns the path to the source file
137
137
  def path
138
- data.fetch('path') { relative_path.sub(/\A\//, '') }
138
+ data.fetch("path") { relative_path }
139
139
  end
140
140
 
141
141
  # The path to the page source file, relative to the site source
142
142
  def relative_path
143
- File.join(*[@dir, @name].map(&:to_s).reject(&:empty?))
143
+ File.join(*[@dir, @name].map(&:to_s).reject(&:empty?)).sub(%r!\A\/!, "")
144
144
  end
145
145
 
146
146
  # Obtain destination path.
@@ -167,7 +167,7 @@ module Jekyll
167
167
 
168
168
  # Returns the Boolean of whether this Page is an index file or not.
169
169
  def index?
170
- basename == 'index'
170
+ basename == "index"
171
171
  end
172
172
 
173
173
  def trigger_hooks(hook_name, *args)
@@ -1,12 +1,12 @@
1
1
  module Jekyll
2
2
  class Plugin
3
3
  PRIORITIES = {
4
- :low => -10,
4
+ :low => -10,
5
5
  :highest => 100,
6
- :lowest => -100,
7
- :normal => 0,
8
- :high => 10
9
- }
6
+ :lowest => -100,
7
+ :normal => 0,
8
+ :high => 10
9
+ }.freeze
10
10
 
11
11
  #
12
12
 
@@ -24,7 +24,9 @@ module Jekyll
24
24
  #
25
25
  # Returns nothing.
26
26
  def require_gems
27
- Jekyll::External.require_with_graceful_fail(site.gems.select { |gem| plugin_allowed?(gem) })
27
+ Jekyll::External.require_with_graceful_fail(
28
+ site.gems.select { |gem| plugin_allowed?(gem) }
29
+ )
28
30
  end
29
31
 
30
32
  def self.require_from_bundler
@@ -33,7 +35,8 @@ module Jekyll
33
35
 
34
36
  Bundler.setup
35
37
  required_gems = Bundler.require(:jekyll_plugins)
36
- Jekyll.logger.debug("PluginManager:", "Required #{required_gems.map(&:name).join(', ')}")
38
+ message = "Required #{required_gems.map(&:name).join(", ")}"
39
+ Jekyll.logger.debug("PluginManager:", message)
37
40
  ENV["JEKYLL_NO_BUNDLER_REQUIRE"] = "true"
38
41
 
39
42
  true
@@ -57,7 +60,7 @@ module Jekyll
57
60
  # Returns an array of strings, each string being the name of a gem name
58
61
  # that is allowed to be used.
59
62
  def whitelist
60
- @whitelist ||= Array[site.config['whitelist']].flatten
63
+ @whitelist ||= Array[site.config["whitelist"]].flatten
61
64
  end
62
65
 
63
66
  # Require all .rb files if safe mode is off
@@ -76,16 +79,17 @@ module Jekyll
76
79
  #
77
80
  # Returns an Array of plugin search paths
78
81
  def plugins_path
79
- if site.config['plugins_dir'] == Jekyll::Configuration::DEFAULTS['plugins_dir']
80
- [site.in_source_dir(site.config['plugins_dir'])]
82
+ if site.config["plugins_dir"].eql? Jekyll::Configuration::DEFAULTS["plugins_dir"]
83
+ [site.in_source_dir(site.config["plugins_dir"])]
81
84
  else
82
- Array(site.config['plugins_dir']).map { |d| File.expand_path(d) }
85
+ Array(site.config["plugins_dir"]).map { |d| File.expand_path(d) }
83
86
  end
84
87
  end
85
88
 
86
89
  def deprecation_checks
87
- pagination_included = (site.config['gems'] || []).include?('jekyll-paginate') || defined?(Jekyll::Paginate)
88
- if site.config['paginate'] && !pagination_included
90
+ pagination_included = (site.config["gems"] || []).include?("jekyll-paginate") ||
91
+ defined?(Jekyll::Paginate)
92
+ if site.config["paginate"] && !pagination_included
89
93
  Jekyll::Deprecator.deprecation_message "You appear to have pagination " \
90
94
  "turned on, but you haven't included the `jekyll-paginate` gem. " \
91
95
  "Ensure you have `gems: [jekyll-paginate]` in your configuration file."
@@ -15,7 +15,7 @@ module Jekyll
15
15
  private
16
16
 
17
17
  def can_be_published?(thing)
18
- thing.data.fetch('published', true) || @site.unpublished
18
+ thing.data.fetch("published", true) || @site.unpublished
19
19
  end
20
20
  end
21
21
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
- require 'csv'
2
+ require "csv"
3
3
 
4
4
  module Jekyll
5
5
  class Reader
@@ -16,7 +16,7 @@ module Jekyll
16
16
  @site.layouts = LayoutReader.new(site).read
17
17
  read_directories
18
18
  sort_files!
19
- @site.data = DataReader.new(site).read(site.config['data_dir'])
19
+ @site.data = DataReader.new(site).read(site.config["data_dir"])
20
20
  CollectionReader.new(site).read
21
21
  end
22
22
 
@@ -34,13 +34,15 @@ module Jekyll
34
34
  # dir - The String relative path of the directory to read. Default: ''.
35
35
  #
36
36
  # Returns nothing.
37
- def read_directories(dir = '')
37
+ def read_directories(dir = "")
38
38
  base = site.in_source_dir(dir)
39
39
 
40
- dot = Dir.chdir(base) { filter_entries(Dir.entries('.'), base) }
40
+ dot = Dir.chdir(base) { filter_entries(Dir.entries("."), base) }
41
41
  dot_dirs = dot.select { |file| File.directory?(@site.in_source_dir(base, file)) }
42
42
  dot_files = (dot - dot_dirs)
43
- dot_pages = dot_files.select { |file| Utils.has_yaml_header?(@site.in_source_dir(base, file)) }
43
+ dot_pages = dot_files.select do |file|
44
+ Utils.has_yaml_header?(@site.in_source_dir(base, file))
45
+ end
44
46
  dot_static_files = dot_files - dot_pages
45
47
 
46
48
  retrieve_posts(dir)
@@ -71,7 +73,9 @@ module Jekyll
71
73
  dot_dirs.map do |file|
72
74
  dir_path = site.in_source_dir(dir, file)
73
75
  rel_path = File.join(dir, file)
74
- @site.reader.read_directories(rel_path) unless @site.dest.sub(/\/$/, '') == dir_path
76
+ unless @site.dest.sub(%r!/$!, "") == dir_path
77
+ @site.reader.read_directories(rel_path)
78
+ end
75
79
  end
76
80
  end
77
81
 
@@ -119,7 +123,7 @@ module Jekyll
119
123
  def get_entries(dir, subfolder)
120
124
  base = site.in_source_dir(dir, subfolder)
121
125
  return [] unless File.exist?(base)
122
- entries = Dir.chdir(base) { filter_entries(Dir['**/*'], base) }
126
+ entries = Dir.chdir(base) { filter_entries(Dir["**/*"], base) }
123
127
  entries.delete_if { |e| File.directory?(site.in_source_dir(base, e)) }
124
128
  end
125
129
  end
@@ -30,14 +30,14 @@ module Jekyll
30
30
  return unless File.directory?(dir) && !@entry_filter.symlink?(dir)
31
31
 
32
32
  entries = Dir.chdir(dir) do
33
- Dir['*.{yaml,yml,json,csv}'] + Dir['*'].select { |fn| File.directory?(fn) }
33
+ Dir["*.{yaml,yml,json,csv}"] + Dir["*"].select { |fn| File.directory?(fn) }
34
34
  end
35
35
 
36
36
  entries.each do |entry|
37
37
  path = @site.in_source_dir(dir, entry)
38
38
  next if @entry_filter.symlink?(path)
39
39
 
40
- key = sanitize_filename(File.basename(entry, '.*'))
40
+ key = sanitize_filename(File.basename(entry, ".*"))
41
41
  if File.directory?(path)
42
42
  read_data_to(path, data[key] = {})
43
43
  else
@@ -51,20 +51,20 @@ module Jekyll
51
51
  # Returns the contents of the data file.
52
52
  def read_data_file(path)
53
53
  case File.extname(path).downcase
54
- when '.csv'
54
+ when ".csv"
55
55
  CSV.read(path, {
56
- :headers => true,
57
- :encoding => site.config['encoding']
58
- }).map(&:to_hash)
56
+ :headers => true,
57
+ :encoding => site.config["encoding"]
58
+ }).map(&:to_hash)
59
59
  else
60
60
  SafeYAML.load_file(path)
61
61
  end
62
62
  end
63
63
 
64
64
  def sanitize_filename(name)
65
- name.gsub!(/[^\w\s-]+/, '')
66
- name.gsub!(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2')
67
- name.gsub(/\s+/, '_')
65
+ name.gsub!(%r![^\w\s-]+!, "")
66
+ name.gsub!(%r!(^|\b\s)\s+($|\s?\b)!, '\\1\\2')
67
+ name.gsub(%r!\s+!, "_")
68
68
  end
69
69
  end
70
70
  end
@@ -8,11 +8,13 @@ module Jekyll
8
8
 
9
9
  def read
10
10
  layout_entries.each do |layout_file|
11
- @layouts[layout_name(layout_file)] = Layout.new(site, layout_directory, layout_file)
11
+ @layouts[layout_name(layout_file)] = \
12
+ Layout.new(site, layout_directory, layout_file)
12
13
  end
13
14
 
14
15
  theme_layout_entries.each do |layout_file|
15
- @layouts[layout_name(layout_file)] ||= Layout.new(site, theme_layout_directory, layout_file)
16
+ @layouts[layout_name(layout_file)] ||= \
17
+ Layout.new(site, theme_layout_directory, layout_file)
16
18
  end
17
19
 
18
20
  @layouts
@@ -39,7 +41,7 @@ module Jekyll
39
41
  def entries_in(dir)
40
42
  entries = []
41
43
  within(dir) do
42
- entries = EntryFilter.new(site).filter(Dir['**/*.*'])
44
+ entries = EntryFilter.new(site).filter(Dir["**/*.*"])
43
45
  end
44
46
  entries
45
47
  end
@@ -54,15 +56,13 @@ module Jekyll
54
56
  end
55
57
 
56
58
  def layout_directory_inside_source
57
- site.in_source_dir(site.config['layouts_dir'])
59
+ site.in_source_dir(site.config["layouts_dir"])
58
60
  end
59
61
 
60
62
  def layout_directory_in_cwd
61
- dir = Jekyll.sanitized_path(Dir.pwd, site.config['layouts_dir'])
63
+ dir = Jekyll.sanitized_path(Dir.pwd, site.config["layouts_dir"])
62
64
  if File.directory?(dir) && !site.safe
63
65
  dir
64
- else
65
- nil
66
66
  end
67
67
  end
68
68
  end