licensee 9.12.0 → 9.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/bin/licensee +3 -3
  3. data/lib/licensee/commands/detect.rb +5 -5
  4. data/lib/licensee/content_helper.rb +53 -8
  5. data/lib/licensee/hash_helper.rb +5 -5
  6. data/lib/licensee/license.rb +16 -20
  7. data/lib/licensee/matchers/dice.rb +3 -3
  8. data/lib/licensee/projects/git_project.rb +3 -3
  9. data/lib/licensee/projects/project.rb +3 -3
  10. data/lib/licensee/version.rb +1 -1
  11. data/licensee.gemspec +47 -0
  12. data/spec/bin_spec.rb +1 -1
  13. data/spec/fixture_spec.rb +5 -5
  14. data/spec/fixtures/cc0-cal2013/LICENSE +116 -0
  15. data/spec/fixtures/cc0-cc/LICENSE +121 -0
  16. data/spec/fixtures/detect.json +1 -1
  17. data/spec/fixtures/fixtures.yml +12 -0
  18. data/spec/fixtures/license-hashes.json +5 -4
  19. data/spec/fixtures/unlicense-noinfo/LICENSE +22 -0
  20. data/spec/integration_spec.rb +30 -2
  21. data/spec/licensee/commands/detect_spec.rb +4 -4
  22. data/spec/licensee/commands/license_path_spec.rb +1 -1
  23. data/spec/licensee/commands/version_spec.rb +1 -1
  24. data/spec/licensee/content_helper_spec.rb +43 -42
  25. data/spec/licensee/hash_helper_spec.rb +1 -1
  26. data/spec/licensee/license_field_spec.rb +3 -3
  27. data/spec/licensee/license_meta_spec.rb +13 -11
  28. data/spec/licensee/license_rules_spec.rb +4 -2
  29. data/spec/licensee/license_spec.rb +33 -33
  30. data/spec/licensee/matchers/cabal_matcher_spec.rb +4 -2
  31. data/spec/licensee/matchers/cargo_matcher_spec.rb +3 -2
  32. data/spec/licensee/matchers/copyright_matcher_spec.rb +3 -3
  33. data/spec/licensee/matchers/cran_matcher_spec.rb +3 -2
  34. data/spec/licensee/matchers/dice_matcher_spec.rb +11 -10
  35. data/spec/licensee/matchers/dist_zilla_matcher_spec.rb +3 -2
  36. data/spec/licensee/matchers/exact_matcher_spec.rb +3 -2
  37. data/spec/licensee/matchers/gemspec_matcher_spec.rb +3 -2
  38. data/spec/licensee/matchers/matcher_spec.rb +4 -2
  39. data/spec/licensee/matchers/npm_bower_matcher_spec.rb +3 -3
  40. data/spec/licensee/matchers/package_matcher_spec.rb +4 -2
  41. data/spec/licensee/matchers/reference_matcher_spec.rb +2 -2
  42. data/spec/licensee/matchers/spdx_matcher_spec.rb +3 -2
  43. data/spec/licensee/project_files/license_file_spec.rb +15 -15
  44. data/spec/licensee/project_files/package_info_spec.rb +3 -1
  45. data/spec/licensee/project_files/project_file_spec.rb +5 -2
  46. data/spec/licensee/project_files/readme_file_spec.rb +2 -1
  47. data/spec/licensee/project_spec.rb +22 -17
  48. data/spec/licensee/projects/github_project_spec.rb +6 -5
  49. data/spec/licensee/rule_spec.rb +4 -3
  50. data/spec/licensee_spec.rb +10 -9
  51. data/spec/spec_helper.rb +2 -2
  52. data/spec/vendored_license_spec.rb +3 -3
  53. data/vendor/choosealicense.com/_data/rules.yml +3 -0
  54. data/vendor/choosealicense.com/_licenses/bsd-3-clause-clear.txt +1 -0
  55. data/vendor/choosealicense.com/_licenses/bsd-4-clause.txt +61 -0
  56. data/vendor/choosealicense.com/_licenses/bsl-1.0.txt +4 -1
  57. data/vendor/choosealicense.com/_licenses/cc-by-4.0.txt +3 -0
  58. data/vendor/choosealicense.com/_licenses/cc-by-sa-4.0.txt +3 -0
  59. data/vendor/choosealicense.com/_licenses/cc0-1.0.txt +112 -103
  60. data/vendor/choosealicense.com/_licenses/ofl-1.1.txt +3 -0
  61. data/vendor/choosealicense.com/_licenses/zlib.txt +4 -1
  62. metadata +37 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7dc009b0467cfb305e8dac051ed4e78d2f35d0454f2e14cef0952338540f8ae
4
- data.tar.gz: 3c27bb3dd3cea6d62fab826b81fab93d9152893851b541c91d69406cdf9fcbd8
3
+ metadata.gz: 7aeb33320898c7e64f31f6ea15708f4e4c23a6856e10c54e004054ee6997200a
4
+ data.tar.gz: dcbac4f8b08ff1d55e0ac7de2b603c67ce4f9a2b7d9486fbfccae3fa0dc6d304
5
5
  SHA512:
6
- metadata.gz: 07f19b33f70b0b73611d34e474f2aa4e4d7f62c7451cdf70f76774beceac2c75ab3d1cc5048061a848b979a54032aad6dd1ba278c79cd798029efd6873d54425
7
- data.tar.gz: 96c5e66f65307e7feb2c00b3f06661b093c60995d049f7fd19cc27b76881965a1d33768a16b0a3a3b085e9392ef828dce9cf692ee04255dd9ea2c6d22da38da6
6
+ metadata.gz: d92bb1d7662b504e92ad6a2fa3f0c8fa23716fa3825715333f8483085a8662d94d61032ec2e4155ae93b9bc0e71627f9e841268e1c7b2229078f13da216d0394
7
+ data.tar.gz: 364fe3f78e38f703a1e7c9317453b598e4a4bc0b8db773efd4e6e701e7f3a730426698c3a4561e34ba09e839a35a24d4526d87595de31f687a7e83c932bf4ae2
@@ -16,9 +16,9 @@ class LicenseeCLI < Thor
16
16
 
17
17
  def path
18
18
  @path ||= if !options[:remote] || args.first =~ %r{^https://}
19
- args.first || Dir.pwd
20
- else
21
- "https://github.com/#{args.first}"
19
+ args.first || Dir.pwd
20
+ else
21
+ "https://github.com/#{args.first}"
22
22
  end
23
23
  end
24
24
 
@@ -23,11 +23,11 @@ class LicenseeCLI < Thor
23
23
 
24
24
  rows = []
25
25
  rows << if project.license
26
- ['License:', project.license.spdx_id]
27
- elsif !project.licenses.empty?
28
- ['Licenses:', project.licenses.map(&:spdx_id)]
29
- else
30
- ['License:', set_color('None', :red)]
26
+ ['License:', project.license.spdx_id]
27
+ elsif !project.licenses.empty?
28
+ ['Licenses:', project.licenses.map(&:spdx_id)]
29
+ else
30
+ ['License:', set_color('None', :red)]
31
31
  end
32
32
 
33
33
  unless project.matched_files.empty?
@@ -8,7 +8,6 @@ module Licensee
8
8
  DIGEST = Digest::SHA1
9
9
  START_REGEX = /\A\s*/.freeze
10
10
  END_OF_TERMS_REGEX = /^[\s#*_]*end of terms and conditions\s*$/i.freeze
11
- ALT_TITLE_REGEX = License::ALT_TITLE_REGEX
12
11
  REGEXES = {
13
12
  hrs: /^\s*[=\-\*]{3,}\s*$/,
14
13
  all_rights_reserved: /#{START_REGEX}all rights reserved\.?$/i,
@@ -25,6 +24,10 @@ module Licensee
25
24
  developed_by: /#{START_REGEX}developed by:.*?\n\n/im,
26
25
  quote_begin: /[`'"‘“]/,
27
26
  quote_end: /[`'"’”]/,
27
+ cc_legal_code: /^\s*Creative Commons Legal Code\s*$/i,
28
+ cc0_info: /For more information, please see\s*\S+zero\S+/im,
29
+ cc0_disclaimer: /CREATIVE COMMONS CORPORATION.*?\n\n/im,
30
+ unlicense_info: /For more information, please.*\S+unlicense\S+/im,
28
31
  mit_optional: /\(including the next paragraph\)/i
29
32
  }.freeze
30
33
  NORMALIZATIONS = {
@@ -85,9 +88,23 @@ module Licensee
85
88
  'owner' => 'holder'
86
89
  }.freeze
87
90
  STRIP_METHODS = %i[
88
- hrs markdown_headings borders title version url copyright
89
- block_markup span_markup link_markup
90
- all_rights_reserved developed_by end_of_terms whitespace
91
+ cc0_optional
92
+ unlicense_optional
93
+ hrs
94
+ markdown_headings
95
+ borders
96
+ title
97
+ version
98
+ url
99
+ copyright
100
+ title
101
+ block_markup
102
+ span_markup
103
+ link_markup
104
+ all_rights_reserved
105
+ developed_by
106
+ end_of_terms
107
+ whitespace
91
108
  mit_optional
92
109
  ].freeze
93
110
 
@@ -106,7 +123,8 @@ module Licensee
106
123
  # Number of characters that could be added/removed to still be
107
124
  # considered a potential match
108
125
  def max_delta
109
- @max_delta ||= (length * Licensee.inverse_confidence_threshold).to_i
126
+ @max_delta ||= fields_normalized.size * 10 +
127
+ (length * Licensee.inverse_confidence_threshold).to_i
110
128
  end
111
129
 
112
130
  # Given another license or project file, calculates the difference in length
@@ -117,10 +135,9 @@ module Licensee
117
135
  # Given another license or project file, calculates the similarity
118
136
  # as a percentage of words in common
119
137
  def similarity(other)
120
- wordset_fieldless = wordset - LicenseField.keys
121
- fields_removed = wordset.size - wordset_fieldless.size
122
138
  overlap = (wordset_fieldless & other.wordset).size
123
- total = wordset_fieldless.size + other.wordset.size - fields_removed
139
+ total = wordset_fieldless.size + other.wordset.size -
140
+ fields_normalized_set.size
124
141
  100.0 * (overlap * 2.0 / total)
125
142
  end
126
143
 
@@ -254,6 +271,20 @@ module Licensee
254
271
  strip(regex) while _content =~ regex
255
272
  end
256
273
 
274
+ def strip_cc0_optional
275
+ return unless _content.include? 'associating cc0'
276
+
277
+ strip(REGEXES[:cc_legal_code])
278
+ strip(REGEXES[:cc0_info])
279
+ strip(REGEXES[:cc0_disclaimer])
280
+ end
281
+
282
+ def strip_unlicense_optional
283
+ return unless _content.include? 'unlicense'
284
+
285
+ strip(REGEXES[:unlicense_info])
286
+ end
287
+
257
288
  def strip_end_of_terms
258
289
  body, _partition, _instructions = _content.partition(END_OF_TERMS_REGEX)
259
290
  @_content = body
@@ -296,5 +327,19 @@ module Licensee
296
327
  normalize(REGEXES[:bullet], "\n\n* ")
297
328
  normalize(/\)\s+\(/, ')(')
298
329
  end
330
+
331
+ def wordset_fieldless
332
+ @wordset_fieldless ||= wordset - fields_normalized_set
333
+ end
334
+
335
+ # Returns an array of strings of substitutable fields in normalized content
336
+ def fields_normalized
337
+ @fields_normalized ||=
338
+ content_normalized.scan(LicenseField::FIELD_REGEX).flatten
339
+ end
340
+
341
+ def fields_normalized_set
342
+ @fields_normalized_set ||= fields_normalized.to_set
343
+ end
299
344
  end
300
345
  end
@@ -8,11 +8,11 @@ module Licensee
8
8
  key = method.to_s.delete('?').to_sym
9
9
  value = public_send(method)
10
10
  hash[key] = if value.is_a?(Array)
11
- value.map { |v| v.respond_to?(:to_h) ? v.to_h : v }
12
- elsif value.respond_to?(:to_h) && !value.nil?
13
- value.to_h
14
- else
15
- value
11
+ value.map { |v| v.respond_to?(:to_h) ? v.to_h : v }
12
+ elsif value.respond_to?(:to_h) && !value.nil?
13
+ value.to_h
14
+ else
15
+ value
16
16
  end
17
17
  end
18
18
 
@@ -92,12 +92,6 @@ module Licensee
92
92
  pseudo: true
93
93
  }.freeze
94
94
 
95
- ALT_TITLE_REGEX = {
96
- 'bsd-2-clause' => /bsd 2-clause(?: \"simplified\")?/i,
97
- 'bsd-3-clause' => /bsd 3-clause(?: \"new\" or \"revised\")?/i,
98
- 'bsd-3-clause-clear' => /(?:clear bsd|bsd 3-clause(?: clear)?)/i
99
- }.freeze
100
-
101
95
  SOURCE_PREFIX = %r{https?://(?:www\.)?}i.freeze
102
96
  SOURCE_SUFFIX = %r{(?:\.html?|\.txt|\/)(?:\?[^\s]*)?}i.freeze
103
97
 
@@ -144,20 +138,22 @@ module Licensee
144
138
  def title_regex
145
139
  return @title_regex if defined? @title_regex
146
140
 
147
- title_regex = ALT_TITLE_REGEX[key]
148
- title_regex ||= begin
149
- string = name.downcase.sub('*', 'u')
150
- string.sub!(/\Athe /i, '')
151
- string.sub!(/,? version /, ' ')
152
- string.sub!(/v(\d+\.\d+)/, '\1')
153
- string = Regexp.escape(string)
154
- string = string.sub(/\\ licen[sc]e/i, '(?:\ licen[sc]e)?')
155
- string = string.sub(/\\ (\d+\\.\d+)/, ',?\s+(?:version\ |v(?:\. )?)?\1')
156
- string = string.sub(/\bgnu\\ /, '(?:GNU )?')
157
- Regexp.new string, 'i'
158
- end
159
-
160
- parts = [title_regex, key]
141
+ string = name.downcase.sub('*', 'u')
142
+ string.sub!(/\Athe /i, '')
143
+ string.sub!(/,? version /, ' ')
144
+ string.sub!(/v(\d+\.\d+)/, '\1')
145
+ string = Regexp.escape(string)
146
+ string = string.sub(/\\ licen[sc]e/i, '(?:\ licen[sc]e)?')
147
+ string = string.sub(/\\ (\d+\\.\d+)/, ',?\s+(?:version\ |v(?:\. )?)?\1')
148
+ string = string.sub(/\bgnu\\ /, '(?:GNU )?')
149
+ title_regex = Regexp.new string, 'i'
150
+
151
+ string = key.sub('-', '[- ]')
152
+ string.sub!('.', '\.')
153
+ string << '(?:\ licen[sc]e)?'
154
+ key_regex = Regexp.new string, 'i'
155
+
156
+ parts = [title_regex, key_regex]
161
157
  if meta.nickname
162
158
  parts.push Regexp.new meta.nickname.sub(/\bGNU /i, '(?:GNU )?')
163
159
  end
@@ -7,9 +7,9 @@ module Licensee
7
7
  # than the confidence threshold
8
8
  def match
9
9
  @match ||= if matches.empty?
10
- nil
11
- else
12
- matches.first[0]
10
+ nil
11
+ else
12
+ matches.first[0]
13
13
  end
14
14
  end
15
15
 
@@ -44,9 +44,9 @@ module Licensee
44
44
 
45
45
  def commit
46
46
  @commit ||= if revision
47
- repository.lookup(revision)
48
- else
49
- repository.last_commit
47
+ repository.lookup(revision)
48
+ else
49
+ repository.last_commit
50
50
  end
51
51
  end
52
52
 
@@ -25,9 +25,9 @@ module Licensee
25
25
  return @license if defined? @license
26
26
 
27
27
  @license = if licenses_without_copyright.count == 1 || lgpl?
28
- licenses_without_copyright.first
29
- elsif licenses_without_copyright.count > 1
30
- Licensee::License.find('other')
28
+ licenses_without_copyright.first
29
+ elsif licenses_without_copyright.count > 1
30
+ Licensee::License.find('other')
31
31
  end
32
32
  end
33
33
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Licensee
4
- VERSION = '9.12.0'
4
+ VERSION = '9.13.0'
5
5
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('lib/licensee/version', __dir__)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = 'licensee'
7
+ gem.version = Licensee::VERSION
8
+
9
+ gem.summary = 'A Ruby Gem to detect open source project licenses'
10
+ gem.description = <<-DESC
11
+ Licensee automates the process of reading LICENSE files and
12
+ compares their contents to known licenses using a fancy maths.
13
+ DESC
14
+
15
+ gem.authors = ['Ben Balter']
16
+ gem.email = 'ben.balter@github.com'
17
+ gem.homepage = 'https://github.com/benbalter/licensee'
18
+ gem.license = 'MIT'
19
+
20
+ gem.bindir = 'bin'
21
+ gem.executables << 'licensee'
22
+
23
+ gem.add_dependency('dotenv', '~> 2.0')
24
+ gem.add_dependency('octokit', '~> 4.8')
25
+ gem.add_dependency('reverse_markdown', '~> 1.0')
26
+ gem.add_dependency('rugged', '~> 0.24')
27
+ gem.add_dependency('thor', '~> 0.19')
28
+
29
+ gem.add_development_dependency('mustache', '>= 0.9', '< 2.0')
30
+ gem.add_development_dependency('pry', '~> 0.9')
31
+ gem.add_development_dependency('rake', '~> 10.3')
32
+ gem.add_development_dependency('rspec', '~> 3.5')
33
+ gem.add_development_dependency('rubocop', '~> 0.76')
34
+ gem.add_development_dependency('rubocop-performance', '~> 1.5')
35
+ gem.add_development_dependency('rubocop-rspec', '~> 1.36')
36
+ gem.add_development_dependency('simplecov', '~> 0.16')
37
+ gem.add_development_dependency('webmock', '~> 3.1')
38
+
39
+ gem.required_ruby_version = '> 2.3'
40
+
41
+ # ensure the gem is built out of versioned files
42
+ gem.files = Dir[
43
+ 'Rakefile',
44
+ '{bin,lib,man,test,vendor,spec}/**/*',
45
+ 'README*', 'LICENSE*'
46
+ ] & `git ls-files -z`.split("\0")
47
+ end
@@ -14,7 +14,7 @@ RSpec.describe 'command line invocation' do
14
14
  let(:status) { output[2] }
15
15
 
16
16
  it 'Returns a zero exit code' do
17
- expect(status.exitstatus).to eql(0)
17
+ expect(status.exitstatus).to be(0)
18
18
  end
19
19
 
20
20
  it 'returns the help text' do
@@ -5,6 +5,8 @@ RSpec.describe 'fixture test' do
5
5
  let(:options) { { detect_packages: true, detect_readme: true } }
6
6
 
7
7
  context "the #{fixture} fixture" do
8
+ subject { Licensee.project(path, options) }
9
+
8
10
  let(:path) { fixture_path(fixture) }
9
11
  let(:other) { Licensee::License.find('other') }
10
12
  let(:none) { Licensee::License.find('none') }
@@ -12,8 +14,6 @@ RSpec.describe 'fixture test' do
12
14
  let(:license_file) { subject.license_file }
13
15
  let(:matcher) { license_file&.matcher }
14
16
 
15
- subject { Licensee.project(path, options) }
16
-
17
17
  it 'has an expected license in fixtures-licenses.yml' do
18
18
  msg = 'Expected an entry in `'.dup
19
19
  msg << fixture_path('fixtures-licenses.yml')
@@ -24,9 +24,9 @@ RSpec.describe 'fixture test' do
24
24
 
25
25
  it 'detects the license' do
26
26
  expected = if expectations['key']
27
- Licensee::License.find(expectations['key'])
28
- else
29
- none
27
+ Licensee::License.find(expectations['key'])
28
+ else
29
+ none
30
30
  end
31
31
 
32
32
  expect(subject.license).to eql(expected)
@@ -0,0 +1,116 @@
1
+ CC0 1.0 Universal
2
+
3
+ Statement of Purpose
4
+
5
+ The laws of most jurisdictions throughout the world automatically confer
6
+ exclusive Copyright and Related Rights (defined below) upon the creator and
7
+ subsequent owner(s) (each and all, an "owner") of an original work of
8
+ authorship and/or a database (each, a "Work").
9
+
10
+ Certain owners wish to permanently relinquish those rights to a Work for the
11
+ purpose of contributing to a commons of creative, cultural and scientific
12
+ works ("Commons") that the public can reliably and without fear of later
13
+ claims of infringement build upon, modify, incorporate in other works, reuse
14
+ and redistribute as freely as possible in any form whatsoever and for any
15
+ purposes, including without limitation commercial purposes. These owners may
16
+ contribute to the Commons to promote the ideal of a free culture and the
17
+ further production of creative, cultural and scientific works, or to gain
18
+ reputation or greater distribution for their Work in part through the use and
19
+ efforts of others.
20
+
21
+ For these and/or other purposes and motivations, and without any expectation
22
+ of additional consideration or compensation, the person associating CC0 with a
23
+ Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
24
+ and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
25
+ and publicly distribute the Work under its terms, with knowledge of his or her
26
+ Copyright and Related Rights in the Work and the meaning and intended legal
27
+ effect of CC0 on those rights.
28
+
29
+ 1. Copyright and Related Rights. A Work made available under CC0 may be
30
+ protected by copyright and related or neighboring rights ("Copyright and
31
+ Related Rights"). Copyright and Related Rights include, but are not limited
32
+ to, the following:
33
+
34
+ i. the right to reproduce, adapt, distribute, perform, display, communicate,
35
+ and translate a Work;
36
+
37
+ ii. moral rights retained by the original author(s) and/or performer(s);
38
+
39
+ iii. publicity and privacy rights pertaining to a person's image or likeness
40
+ depicted in a Work;
41
+
42
+ iv. rights protecting against unfair competition in regards to a Work,
43
+ subject to the limitations in paragraph 4(a), below;
44
+
45
+ v. rights protecting the extraction, dissemination, use and reuse of data in
46
+ a Work;
47
+
48
+ vi. database rights (such as those arising under Directive 96/9/EC of the
49
+ European Parliament and of the Council of 11 March 1996 on the legal
50
+ protection of databases, and under any national implementation thereof,
51
+ including any amended or successor version of such directive); and
52
+
53
+ vii. other similar, equivalent or corresponding rights throughout the world
54
+ based on applicable law or treaty, and any national implementations thereof.
55
+
56
+ 2. Waiver. To the greatest extent permitted by, but not in contravention of,
57
+ applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
58
+ unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
59
+ and Related Rights and associated claims and causes of action, whether now
60
+ known or unknown (including existing as well as future claims and causes of
61
+ action), in the Work (i) in all territories worldwide, (ii) for the maximum
62
+ duration provided by applicable law or treaty (including future time
63
+ extensions), (iii) in any current or future medium and for any number of
64
+ copies, and (iv) for any purpose whatsoever, including without limitation
65
+ commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
66
+ the Waiver for the benefit of each member of the public at large and to the
67
+ detriment of Affirmer's heirs and successors, fully intending that such Waiver
68
+ shall not be subject to revocation, rescission, cancellation, termination, or
69
+ any other legal or equitable action to disrupt the quiet enjoyment of the Work
70
+ by the public as contemplated by Affirmer's express Statement of Purpose.
71
+
72
+ 3. Public License Fallback. Should any part of the Waiver for any reason be
73
+ judged legally invalid or ineffective under applicable law, then the Waiver
74
+ shall be preserved to the maximum extent permitted taking into account
75
+ Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
76
+ is so judged Affirmer hereby grants to each affected person a royalty-free,
77
+ non transferable, non sublicensable, non exclusive, irrevocable and
78
+ unconditional license to exercise Affirmer's Copyright and Related Rights in
79
+ the Work (i) in all territories worldwide, (ii) for the maximum duration
80
+ provided by applicable law or treaty (including future time extensions), (iii)
81
+ in any current or future medium and for any number of copies, and (iv) for any
82
+ purpose whatsoever, including without limitation commercial, advertising or
83
+ promotional purposes (the "License"). The License shall be deemed effective as
84
+ of the date CC0 was applied by Affirmer to the Work. Should any part of the
85
+ License for any reason be judged legally invalid or ineffective under
86
+ applicable law, such partial invalidity or ineffectiveness shall not
87
+ invalidate the remainder of the License, and in such case Affirmer hereby
88
+ affirms that he or she will not (i) exercise any of his or her remaining
89
+ Copyright and Related Rights in the Work or (ii) assert any associated claims
90
+ and causes of action with respect to the Work, in either case contrary to
91
+ Affirmer's express Statement of Purpose.
92
+
93
+ 4. Limitations and Disclaimers.
94
+
95
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
96
+ surrendered, licensed or otherwise affected by this document.
97
+
98
+ b. Affirmer offers the Work as-is and makes no representations or warranties
99
+ of any kind concerning the Work, express, implied, statutory or otherwise,
100
+ including without limitation warranties of title, merchantability, fitness
101
+ for a particular purpose, non infringement, or the absence of latent or
102
+ other defects, accuracy, or the present or absence of errors, whether or not
103
+ discoverable, all to the greatest extent permissible under applicable law.
104
+
105
+ c. Affirmer disclaims responsibility for clearing rights of other persons
106
+ that may apply to the Work or any use thereof, including without limitation
107
+ any person's Copyright and Related Rights in the Work. Further, Affirmer
108
+ disclaims responsibility for obtaining any necessary consents, permissions
109
+ or other rights required for any use of the Work.
110
+
111
+ d. Affirmer understands and acknowledges that Creative Commons is not a
112
+ party to this document and has no duty or obligation with respect to this
113
+ CC0 or use of the Work.
114
+
115
+ For more information, please see
116
+ <http://creativecommons.org/publicdomain/zero/1.0/>