jekyll_picture_tag 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/.travis.yml +11 -0
  4. data/Gemfile +2 -2
  5. data/Rakefile +28 -0
  6. data/contributing.md +67 -0
  7. data/docs/examples/_config.yml +10 -0
  8. data/{examples → docs/examples}/_data/picture.yml +39 -19
  9. data/docs/examples/post.md +46 -0
  10. data/docs/global_configuration.md +115 -0
  11. data/docs/installation.md +30 -0
  12. data/docs/migration.md +178 -0
  13. data/docs/notes.md +85 -0
  14. data/docs/presets.md +407 -0
  15. data/docs/readme.md +23 -0
  16. data/docs/usage.md +131 -0
  17. data/jekyll-picture-tag.gemspec +3 -12
  18. data/jekyll_picture_tag.gemspec +8 -3
  19. data/lib/jekyll-picture-tag.rb +5 -3
  20. data/lib/jekyll_picture_tag.rb +45 -42
  21. data/lib/jekyll_picture_tag/defaults/global.yml +0 -3
  22. data/lib/jekyll_picture_tag/defaults/presets.yml +1 -0
  23. data/lib/jekyll_picture_tag/generated_image.rb +60 -39
  24. data/lib/jekyll_picture_tag/img_uri.rb +55 -0
  25. data/lib/jekyll_picture_tag/instructions.rb +1 -102
  26. data/lib/jekyll_picture_tag/instructions/configuration.rb +30 -74
  27. data/lib/jekyll_picture_tag/instructions/html_attributes.rb +18 -27
  28. data/lib/jekyll_picture_tag/instructions/preset.rb +14 -3
  29. data/lib/jekyll_picture_tag/instructions/set.rb +61 -0
  30. data/lib/jekyll_picture_tag/instructions/tag_parser.rb +80 -23
  31. data/lib/jekyll_picture_tag/output_formats.rb +1 -1
  32. data/lib/jekyll_picture_tag/output_formats/{basics.rb → basic.rb} +24 -19
  33. data/lib/jekyll_picture_tag/output_formats/data_attributes.rb +2 -2
  34. data/lib/jekyll_picture_tag/output_formats/direct_url.rb +1 -3
  35. data/lib/jekyll_picture_tag/output_formats/img.rb +4 -4
  36. data/lib/jekyll_picture_tag/output_formats/naked_srcset.rb +5 -4
  37. data/lib/jekyll_picture_tag/output_formats/picture.rb +6 -16
  38. data/lib/jekyll_picture_tag/output_formats/readme.md +8 -15
  39. data/lib/jekyll_picture_tag/router.rb +98 -0
  40. data/lib/jekyll_picture_tag/source_image.rb +15 -23
  41. data/lib/jekyll_picture_tag/srcsets.rb +1 -1
  42. data/lib/jekyll_picture_tag/srcsets/{basics.rb → basic.rb} +22 -13
  43. data/lib/jekyll_picture_tag/srcsets/pixel_ratio.rb +6 -11
  44. data/lib/jekyll_picture_tag/srcsets/width.rb +3 -11
  45. data/lib/jekyll_picture_tag/utils.rb +32 -49
  46. data/lib/jekyll_picture_tag/version.rb +1 -1
  47. data/readme.md +70 -70
  48. metadata +97 -16
  49. data/bin/console +0 -14
  50. data/bin/setup +0 -7
  51. data/examples/_config.yml +0 -4
  52. data/examples/post.md +0 -18
@@ -1,21 +1,23 @@
1
1
  module PictureTag
2
2
  # Handles a given source image file and its properties. Provides a speed
3
3
  # advantage by storing expensive file reads and writes in instance variables,
4
- # to be reused by many different source images.
4
+ # to be reused by many different generated images.
5
5
  class SourceImage
6
- attr_reader :name, :shortname, :missing
6
+ attr_reader :name, :shortname, :missing, :media_preset
7
+ include MiniMagick
7
8
 
8
- def initialize(relative_filename)
9
+ def initialize(relative_filename, media_preset = nil)
9
10
  @shortname = relative_filename
10
11
  @name = grab_file relative_filename
11
- end
12
-
13
- def size
14
- @size ||= build_size
12
+ @media_preset = media_preset
15
13
  end
16
14
 
17
15
  def width
18
- size[:width]
16
+ @width ||= if @missing
17
+ 999_999
18
+ else
19
+ image.width
20
+ end
19
21
  end
20
22
 
21
23
  def digest
@@ -39,33 +41,23 @@ module PictureTag
39
41
 
40
42
  private
41
43
 
42
- def build_size
43
- if @missing
44
- width = 999_999
45
- height = 999_999
46
- else
47
- width, height = FastImage.size(@name)
48
- end
49
-
50
- {
51
- width: width,
52
- height: height
53
- }
44
+ def image
45
+ @image ||= Image.open(@name)
54
46
  end
55
47
 
56
48
  # Turn a relative filename into an absolute one, and make sure it exists.
57
49
  def grab_file(source_file)
58
- source_name = File.join(PictureTag.config.source_dir, source_file)
50
+ source_name = File.join(PictureTag.source_dir, source_file)
59
51
 
60
52
  if File.exist? source_name
61
53
  @missing = false
62
54
 
63
- elsif PictureTag.config.continue_on_missing?
55
+ elsif PictureTag.continue_on_missing?
64
56
  @missing = true
65
57
  Utils.warning missing_image_warning(source_name)
66
58
 
67
59
  else
68
- raise missing_image_error(source_name)
60
+ raise ArgumentError, missing_image_error(source_name)
69
61
  end
70
62
 
71
63
  source_name
@@ -1,3 +1,3 @@
1
- require_relative 'srcsets/basics'
1
+ require_relative 'srcsets/basic'
2
2
  require_relative 'srcsets/pixel_ratio'
3
3
  require_relative 'srcsets/width'
@@ -1,3 +1,4 @@
1
+ require 'mime-types'
1
2
  module PictureTag
2
3
  # Handles srcset generation, which also handles file generation.
3
4
  module Srcsets
@@ -7,18 +8,27 @@ module PictureTag
7
8
  # - Return an array of srcset entries.
8
9
  # - Call generate_file for each entry, giving it the desired width in
9
10
  # pixels.
10
- module Basics
11
- require 'fastimage'
12
- require 'mime-types'
13
- attr_reader :media, :source_image
11
+ class Basic
12
+ attr_reader :source_image, :media
14
13
 
15
- def initialize(media:, format:)
16
- @media = media # Associated Media Query, can be nil
14
+ def initialize(source_image, input_format)
15
+ @source_image = source_image
16
+ @input_format = input_format
17
+ @media = source_image.media_preset
18
+ end
17
19
 
18
- # Output format:
19
- @format = Utils.process_format(format, media)
20
+ def format
21
+ # Input format might be 'original', which is handled by the generated
22
+ # image.
23
+ @format ||= files.first.format
24
+ end
20
25
 
21
- @source_image = PictureTag.source_images[@media]
26
+ def files
27
+ @files ||= widths.collect { |w| generate_file(w) }
28
+ end
29
+
30
+ def to_a
31
+ files.collect { |f| build_srcset_entry(f) }
22
32
  end
23
33
 
24
34
  def to_s
@@ -28,7 +38,7 @@ module PictureTag
28
38
  # Allows us to add a type attribute to whichever element contains this
29
39
  # srcset.
30
40
  def mime_type
31
- MIME::Types.type_for(@format).first.to_s
41
+ MIME::Types.type_for(format).first.to_s
32
42
  end
33
43
 
34
44
  # Some srcsets have them, for those that don't return nil.
@@ -53,7 +63,7 @@ module PictureTag
53
63
  private
54
64
 
55
65
  def handle_small_source(targets, image_width)
56
- PictureTag::Utils.warning(
66
+ Utils.warning(
57
67
  " #{@source_image.shortname} is #{image_width}px wide, smaller than" \
58
68
  " at least one size in the set #{targets}. Will not enlarge."
59
69
  )
@@ -69,10 +79,9 @@ module PictureTag
69
79
  GeneratedImage.new(
70
80
  source_file: @source_image,
71
81
  width: width,
72
- format: @format
82
+ format: @input_format
73
83
  )
74
84
  end
75
-
76
85
  end
77
86
  end
78
87
  end
@@ -2,13 +2,7 @@ module PictureTag
2
2
  module Srcsets
3
3
  # Creates a srcset in the "(filename) (pixel_ratio)x" format.
4
4
  # Example: "img.jpg 1x, img2.jpg 1.5x, img3.jpg 2x"
5
- class PixelRatio
6
- include Basics
7
-
8
- def to_a
9
- widths.collect { |w| build_srcset_entry(w) }
10
- end
11
-
5
+ class PixelRatio < Basic
12
6
  private
13
7
 
14
8
  def widths
@@ -19,13 +13,14 @@ module PictureTag
19
13
  check_widths target
20
14
  end
21
15
 
22
- def build_srcset_entry(width)
16
+ def build_srcset_entry(file)
23
17
  # We have to recalculate the pixel ratio after verifying our source
24
18
  # image is large enough.
25
- pixel_ratio = (width.to_f / PictureTag.preset['base_width']).round(2)
26
- file = generate_file(width)
19
+ pixel_ratio = (
20
+ file.width.to_f / PictureTag.preset['base_width']
21
+ ).round(2)
27
22
 
28
- "#{PictureTag.build_url(file.name)} #{pixel_ratio}x"
23
+ "#{file.uri} #{pixel_ratio}x"
29
24
  end
30
25
  end
31
26
  end
@@ -2,13 +2,7 @@ module PictureTag
2
2
  module Srcsets
3
3
  # Creates a srcset in the "(filename) (width)w, (...)" format.
4
4
  # Example: "img.jpg 400w, img2.jpg 600w, img3.jpg 800w"
5
- class Width
6
- include Basics
7
-
8
- def to_a
9
- widths.collect { |w| build_srcset_entry(w) }
10
- end
11
-
5
+ class Width < Basic
12
6
  # Sizes html attribute. Since it's intimately related to srcset, we
13
7
  # generate it at the same time.
14
8
  def sizes
@@ -31,10 +25,8 @@ module PictureTag
31
25
  check_widths PictureTag.widths(@media)
32
26
  end
33
27
 
34
- def build_srcset_entry(width)
35
- file = generate_file(width)
36
-
37
- "#{PictureTag.build_url(file.name)} #{file.width}w"
28
+ def build_srcset_entry(file)
29
+ "#{file.uri} #{file.width}w"
38
30
  end
39
31
 
40
32
  def build_size_entry(media, size)
@@ -2,66 +2,49 @@ module PictureTag
2
2
  # This is a little module to hold logic that doesn't fit other places. If it
3
3
  # starts getting big, refactor.
4
4
  module Utils
5
- # Configure Jekyll to keep our generated files
6
- def self.keep_files
7
- dest_dir = PictureTag.config['picture']['output']
5
+ class << self
6
+ # Configure Jekyll to keep our generated files
7
+ def keep_files
8
+ dest_dir = PictureTag.config['picture']['output']
8
9
 
9
- # Chop a slash off the end, if it's there. Doesn't work otherwise.
10
- dest_dir = dest_dir[0..-2] if dest_dir =~ %r{/\z}
10
+ # Chop a slash off the end, if it's there. Doesn't work otherwise.
11
+ dest_dir = dest_dir[0..-2] if dest_dir =~ %r{/\z}
11
12
 
12
- return if PictureTag.site.config['keep_files'].include?(dest_dir)
13
+ return if PictureTag.site.config['keep_files'].include?(dest_dir)
13
14
 
14
- PictureTag.site.config['keep_files'] << dest_dir
15
- end
16
-
17
- # Print a warning to the console
18
- def self.warning(message)
19
- return if PictureTag.config['picture']['suppress_warnings']
20
-
21
- warn 'Jekyll Picture Tag Warning: '.yellow + message
22
- end
23
-
24
- # Parse a liquid template; allows liquid variables to be included as tag
25
- # params.
26
- def self.liquid_lookup(params)
27
- Liquid::Template.parse(params).render(PictureTag.context)
15
+ PictureTag.site.config['keep_files'] << dest_dir
16
+ end
28
17
 
29
- # This gsub allows people to include template code for javascript
30
- # libraries such as handlebar.js. It adds complication and I'm not sure
31
- # it has much value now, so I'm commenting it out. If someone has a use
32
- # case for it we can add it back in.
33
- # .gsub(/\\\{\\\{|\\\{\\%/, '\{\{' => '{{', '\{\%' => '{%')
34
- end
18
+ # Print a warning to the console
19
+ def warning(message)
20
+ return if PictureTag.config['picture']['suppress_warnings']
35
21
 
36
- # Allows us to use 'original' as a format name.
37
- def self.process_format(format, media)
38
- if format.casecmp('original').zero?
39
- PictureTag.source_images[media].ext
40
- else
41
- format.downcase
22
+ warn 'Jekyll Picture Tag Warning: '.yellow + message
42
23
  end
43
- end
44
24
 
45
- # Used for auto markup configuration and such
46
- def self.count_srcsets
47
- formats = PictureTag.preset['formats'].length
48
- source_images = PictureTag.source_images.length
25
+ # Parse a liquid template; allows liquid variables to be included as tag
26
+ # params.
27
+ def liquid_lookup(params)
28
+ Liquid::Template.parse(params).render(PictureTag.context)
29
+ end
49
30
 
50
- formats * source_images
51
- end
31
+ # Used for auto markup configuration and such
32
+ def count_srcsets
33
+ PictureTag.formats.length * PictureTag.source_images.length
34
+ end
52
35
 
53
- # Returns whether or not the current page is a markdown file.
54
- def self.markdown_page?
55
- page_name = PictureTag.page['name']
56
- page_ext = PictureTag.page['ext']
57
- ext = page_ext ? page_ext : File.extname(page_name)
36
+ # Returns whether or not the current page is a markdown file.
37
+ def markdown_page?
38
+ page_name = PictureTag.page['name']
39
+ page_ext = PictureTag.page['ext']
40
+ ext = page_ext || File.extname(page_name)
58
41
 
59
- ext.casecmp('.md').zero? || ext.casecmp('.markdown').zero?
60
- end
42
+ ext.casecmp('.md').zero? || ext.casecmp('.markdown').zero?
43
+ end
61
44
 
62
- # Returns the widest source image
63
- def self.biggest_source
64
- PictureTag.source_images.values.max_by(&:width)
45
+ def titleize(input)
46
+ input.split('_').map(&:capitalize).join
47
+ end
65
48
  end
66
49
  end
67
50
  end
@@ -1,3 +1,3 @@
1
1
  module PictureTag
2
- VERSION = '1.6.0'.freeze
2
+ VERSION = '1.7.0'.freeze
3
3
  end
data/readme.md CHANGED
@@ -2,67 +2,61 @@
2
2
 
3
3
  **Easy responsive images for Jekyll.**
4
4
 
5
- It's easy to throw an image on a webpage and call it a day. Doing justice to your users by serving it
6
- efficiently on all screen sizes is tedious and tricky. Tedious, tricky things should be automated.
7
-
8
- Jekyll Picture Tag is a liquid tag that adds responsive images to your
9
- [Jekyll](http://jekyllrb.com) static site. It automatically creates resized,
10
- reformatted source images, is fully configurable, implements sensible defaults,
11
- and solves both the art direction and resolution switching problems, with a
12
- little YAML configuration and a simple template tag. It can be configured to
13
- work with JavaScript libraries such as
5
+ It's easy to throw an image on a webpage and call it a day. Doing justice to your users by serving
6
+ it efficiently on all browsers and screen sizes is tedious and tricky. Tedious, tricky things should be
7
+ automated.
8
+
9
+ Jekyll Picture Tag is a liquid tag that adds responsive images to your [Jekyll](http://jekyllrb.com)
10
+ static site. It automatically creates resized, reformatted source images, is fully configurable,
11
+ implements sensible defaults, and solves both the art direction and resolution switching problems,
12
+ with a little YAML configuration and a simple template tag. It offers several different output
13
+ formats, and can be configured to work with JavaScript libraries such as
14
14
  [LazyLoad](https://github.com/verlok/lazyload).
15
15
 
16
+ ## Documentation
17
+
18
+ It's all in the [`docs`](docs/) folder:
19
+
20
+ * [Installation](docs/installation.md)
21
+ * [Usage](docs/usage.md)
22
+ * [Global settings](docs/global_configuration.md)
23
+ * [Presets](docs/presets.md)
24
+ * [Other notes](docs/notes.md)
25
+ * [Contribute](contributing.md)
26
+ * [Release History](#release-history)
27
+ * [License](LICENSE.txt)
28
+
16
29
  ## Why use Jekyll Picture Tag?
17
30
 
18
- **Performance:** The fastest sites are static sites. If we're not using responsive images we're
19
- throwing those performance gains away by serving kilobytes of pixels a user will never see.
31
+ **Performance:** The fastest sites are static sites, but when you plonk a 2mb picture of your dog at
32
+ the top of a blog post you're throwing it all away.
20
33
 
21
34
  **Design:** Your desktop image may not work well on mobile, regardless of its resolution. We often
22
- want to do more than just resize images for different screen sizes.
35
+ want to do more than just resize images for different screen sizes, we want to crop them or use a
36
+ different image entirely.
23
37
 
24
38
  **Developer Sanity:** Image downloading starts before the browser has parsed your CSS and
25
39
  JavaScript; this gets them on the page *fast*, but it leads to some ridiculously verbose markup.
26
- Ultimately, to serve responsive images correctly, we must:
40
+ To serve responsive images correctly, we must:
27
41
 
28
- - Generate, name, and organize the required images (formats \* resolutions, for each source image)
29
- - Inform the browser about the image itself-- format, size, URI, and the screen sizes where it
30
- should be used.
31
- - Inform the browser how large the space for that image on the page will be (which also probably has associated media
32
- queries).
42
+ - Generate, name, and organize the required images (formats \* resolutions \* source images)
43
+ - Inform the browser about the image itself-- format, size, URI, and the screen sizes where it
44
+ should be used.
45
+ - Inform the browser how large the space for that image on the page will be (which also probably
46
+ has associated media queries).
33
47
 
34
- It's a lot. It's tedious and complicated. Jekyll Picture Tag automates it.
48
+ It's a lot. It's tedious and complicated. Jekyll Picture Tag makes it easy.
35
49
 
36
50
  ## Features
37
51
 
38
52
  * Automatic generation of resized, converted image files.
39
- * Automatic generation of complex markup in one of several different formats.
53
+ * Automatic generation of complex markup in several different formats.
40
54
  * No configuration required, extensive configuration available.
41
- * Auto-select between `<picture>` or lone `<img>` as necessary.
42
- * Support for both width based and pixel ratio based srcsets.
43
- * Webp conversion.
44
55
  * `sizes` attribute assistance.
45
- * named media queries so you don't have to remember them.
46
- * Optional `<noscript>` tag with a basic fallback image, so you can lazy load without excluding your
47
- javascript-impaired users.
48
56
  * Optionally, automatically link to the source image. Or manually link to anywhere else, with just a
49
- tag parameter!
57
+ tag parameter!
50
58
 
51
-
52
- # Documentation
53
-
54
- It's mostly in the wiki.
55
-
56
- * [Installation](https://github.com/rbuchberger/jekyll-picture-tag/wiki/Installation)
57
- * [Usage](https://github.com/rbuchberger/jekyll-picture-tag/wiki/Liquid-Tag-Usage)
58
- * [Global settings](https://github.com/rbuchberger/jekyll-picture-tag/wiki/Global-Configuration)
59
- * [Presets](https://github.com/rbuchberger/jekyll-picture-tag/wiki/Writing-Presets)
60
- * [Other notes](https://github.com/rbuchberger/jekyll-picture-tag/wiki/Miscellaneous-notes-and-FAQ)
61
- * [Contribute](#contribute)
62
- * [Release History](#release-history)
63
- * [License](#license)
64
-
65
- # Quick start / Demo
59
+ ## Quick start / Demo
66
60
 
67
61
  **All configuration is optional.** Here's the simplest possible use case:
68
62
 
@@ -74,6 +68,8 @@ group :jekyll_plugins do
74
68
  end
75
69
  ```
76
70
 
71
+ Run `bundle install`
72
+
77
73
  Put this liquid tag somewhere:
78
74
 
79
75
  `{% picture test.jpg %}`
@@ -81,21 +77,32 @@ Put this liquid tag somewhere:
81
77
  Get this in your generated site:
82
78
 
83
79
  ```html
84
- <!-- Line breaks added for readability, the actual markup will not have them. -->
80
+ <!-- Formatted for readability -->
85
81
 
86
82
  <img src="/generated/test-800-195f7d.jpg"
87
- srcset="/generated/test-400-195f7d.jpg 400w,
88
- /generated/test-600-195f7d.jpg 600w,
89
- /generated/test-800-195f7d.jpg 800w,
90
- /generated/test-1000-195f7d.jpg 1000w">
83
+ srcset="
84
+ /generated/test-400-195f7d.jpg 400w,
85
+ /generated/test-600-195f7d.jpg 600w,
86
+ /generated/test-800-195f7d.jpg 800w,
87
+ /generated/test-1000-195f7d.jpg 1000w
88
+ ">
91
89
  ```
92
90
 
93
- ### Here's a more complete example:
91
+ ### Look man, that's cool and all but I just want webp.
94
92
 
95
- With this configuration:
93
+ Create `_data/picture.yml`, add the following:
96
94
 
97
95
  ```yml
96
+ markup_presets:
97
+ default:
98
+ formats: [webp, original]
99
+ ```
100
+
101
+ If you get errors, make sure you have imagemagick installed with a webp delegate.
102
+
103
+ ### Here's a more complex example:
98
104
 
105
+ ```yml
99
106
  # _data/picture.yml
100
107
 
101
108
  media_presets:
@@ -108,7 +115,6 @@ markup_presets:
108
115
  sizes:
109
116
  mobile: 80vw
110
117
  size: 500px
111
-
112
118
  ```
113
119
 
114
120
  Write this:
@@ -164,20 +170,19 @@ for image conversions, so it must be installed on your system. There's a very go
164
170
  already have it. If you want to build webp images, you will need to install a webp delegate for it
165
171
  as well.
166
172
 
167
- # Contribute
168
-
169
- Report bugs and feature proposals in the
170
- [Github issue tracker](https://github.com/robwierzbowski/jekyll-picture-tag/issues).
171
-
172
- Pull requests are encouraged. With a few exceptions, this plugin is written to follow the Rubocop
173
- default settings (except the frozen string literal comment).
174
-
175
- If you add a new setting, it is helpful to add a default value (look under `lib/defaults/`) and
176
- relevant documentation. Don't let that stop you from submitting a pull request, though! Just allow
177
- modifications and I'll take care of it.
178
-
179
- # Release History
180
-
173
+ ## Release History
174
+
175
+ * 1.7.0 Aug 12, 2019
176
+ * Add support for setting generated image quality, either generally or specific to given
177
+ formats.
178
+ * Add support for spaces and other url-encoded characters in filenames
179
+ * Documentation restructure - Moved it out of the wiki, into the `docs` folder.
180
+ * Bugfix: Fallback image width will now be checked against source image width.
181
+ * Bugfix: Minor fix to nomarkdown wrapper output
182
+ * link_source will now target the base source image, rather than finding the biggest one.
183
+ * Remove fastimage dependency, add addressable dependency.
184
+ * Moderately significant refactoring and code cleanup
185
+ * Decent set of tests added
181
186
  * 1.6.0 Jul 2, 2019:
182
187
  * Missing Preset warning respects `data_dir` setting
183
188
  * Add `continue_on_missing` option
@@ -203,14 +208,9 @@ modifications and I'll take care of it.
203
208
  * auto-orient images before stripping metadata
204
209
  * 1.0.2 Jan 18, 2019: Fix ruby version specification
205
210
  * 1.0.1 Jan 13, 2019: Added ruby version checking
206
- * **1.0.0** Nov 27, 2018: Rewrite from the ground up. See [the migration
207
- guide](https://github.com/rbuchberger/jekyll-picture-tag/wiki/Migrating-from-versions-prior-to-1.0).
211
+ * **1.0.0** Nov 27, 2018: Rewrite from the ground up. See the [migration guide](docs/migration.md).
208
212
  * 0.2.2 Aug 2, 2013: Bugfixes
209
213
  * 0.2.1 Jul 17, 2013: Refactor again, add Liquid parsing.
210
214
  * 0.2.0 Jul 14, 2013: Rewrite code base, bring in line with Jekyll Image Tag.
211
215
  * 0.1.1 Jul 5, 2013: Quick round of code improvements.
212
216
  * 0.1.0 Jul 5, 2013: Initial release.
213
-
214
- # License
215
-
216
- [BSD-NEW](http://en.wikipedia.org/wiki/BSD_License)