five-star 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 408c38478386dfd30afac94401ef9f609a4102c1
4
- data.tar.gz: ce73a704c2f2ef208f45d5ab95759e05f30f19be
3
+ metadata.gz: f0ec61a85ec090995b6030203a9b8808e85ff27e
4
+ data.tar.gz: a21d6768ecb083c34b4b103d78100f2095d726dc
5
5
  SHA512:
6
- metadata.gz: f8fb0c43adac3af9fd729f1326ab1e3b8dfc0e18ea1e72f4a7065582cdfc5ece24ca2b7b7c5d867380ca6919d06ab1d80a8f3037ab973b1fcee873962c9af6ee
7
- data.tar.gz: f988375e92f8224ae05b7d5956da34134fe47080ea74d5d1510631017760ad8e184e3bd81d57e17fc2682fb3a272aee7b80e3110ca57fd7642f1238715070355
6
+ metadata.gz: ca8a6fdb9c2f2fd00d25ea31ca507fafa6cd69c0c9eb3bbe7d3509f368b67a35329012be76909f56a71defb91be16a3d35358eed729e8623a7d586466f810aa2
7
+ data.tar.gz: b1734c47ace30591629843cc41dfda108c2671e13cf2c15831972659db6b55025a5c5f74b869e76dfd815f4438a539e250bf1cf7bc9d202799836d054d4595f1
data/README.md CHANGED
@@ -1,21 +1,19 @@
1
1
  # FiveStar
2
- ### A generic rating library :star:
3
2
 
4
3
  [![Build Status](https://travis-ci.org/rob-murray/five-star.svg?branch=master)](https://travis-ci.org/rob-murray/five-star)
5
- [![Code Climate](https://codeclimate.com/github/rob-murray/five-star.png)](https://codeclimate.com/github/rob-murray/five-star)
6
- [![Coverage Status](https://coveralls.io/repos/rob-murray/five-star/badge.png)](https://coveralls.io/r/rob-murray/five-star)
7
- [![Dependency Status](https://gemnasium.com/rob-murray/five-star.svg)](https://gemnasium.com/rob-murray/five-star)
4
+ [![Code Climate](https://codeclimate.com/github/rob-murray/five-star.svg)](https://codeclimate.com/github/rob-murray/five-star)
5
+ [![Coverage Status](https://coveralls.io/repos/rob-murray/five-star/badge.svg?branch=master&service=github)](https://coveralls.io/github/rob-murray/five-star?branch=master)
8
6
  [![Gem Version](https://badge.fury.io/rb/five-star.svg)](http://badge.fury.io/rb/five-star)
9
7
 
10
- :star: **FiveStar** :star: is a library to build a rating system - it allows you to rate *something* in your domain by classification or criteria you define. This library gives you the structure to rate your object with as many of these different classifications as you like with the overall rating as a weighted average.
11
8
 
12
- This uses Plain Old Ruby Objects so can be used in any project. Implement or use whatever persistence layer you want.
9
+ :star: **FiveStar** :star: is a library to build a rating system - it allows you to rate *something* in your domain by various classification or criteria you define. This library gives you the structure to rate your object with as many of these different classifications as you like with the overall rating calculated from the weighted average.
10
+
11
+ This uses *Plain Old Ruby Objects* so can be used in any project.
13
12
 
14
- > Not sure if this is a gem or just a code design pattern :/
15
13
 
16
14
  ## Example
17
15
 
18
- Say you implemented a film rating system, you have lots of `Film` objects each with different attributes and you would like to show an overall rating for each film based on classifications below.
16
+ Say you implemented a film rating system, you have lots of `Film` objects each with different attributes and you would like to show an overall rating for each film based on classifications below. You might give the amount of swearing in the film slightly less weighting that the amount of sex and violence.
19
17
 
20
18
  * Gore - Amount of blood in the movie - weighting: 40%
21
19
  * Sex - Number of references to sex in the movie - weighting: 40%
@@ -29,18 +27,32 @@ class Film
29
27
 
30
28
  rate_with GoreRater, SwearingRater, SexRater
31
29
 
32
- # rest of you implementation
30
+ # rest of your implementation
31
+ def blood_spilt
32
+ # ...
33
+ end
34
+
35
+ def number_of_swear_words
36
+ # ...
37
+ end
33
38
  end
34
39
 
35
40
  class GoreRater < FiveStar.base_rater
36
41
  rating_weight 0.4
37
42
 
38
43
  def description
39
- "This Film was rated #{rating} for gore"
44
+ "The film #{film.title} was rated #{rating} for gore"
40
45
  end
41
46
 
42
47
  def rating
43
- # count the pints of blood spilt in the film
48
+ # count the pints of blood spilt in the film and return a rating
49
+ if film.blood_spilt == :a_lot
50
+ 10
51
+ elsif film.blood_spilt == :a_little
52
+ 5
53
+ else
54
+ 0
55
+ end
44
56
  end
45
57
  end
46
58
 
@@ -48,17 +60,18 @@ class SwearingRater < FiveStar.base_rater
48
60
  rating_weight 0.2
49
61
 
50
62
  def description
51
- "This Film was has #{number_of_swear_words} and was rated at #{rating}"
63
+ "The film #{film.title} has #{film.number_of_swear_words} and was rated at #{rating}"
52
64
  end
53
65
 
54
66
  def rating
55
- # count the number of swear words in the film
67
+ # count the number of swear words in the film & convert to our rating scale
68
+ linear_conversion(film.number_of_swear_words)
56
69
  end
57
70
  end
58
71
 
59
72
  film = Film.new
60
73
  film.rating # => 6
61
- film.rating_descriptions # => ["This Film was rated 8 for gore", ...]
74
+ film.rating_descriptions # => ["The film Alien was rated 8 for gore", ...]
62
75
 
63
76
  ```
64
77
 
@@ -81,21 +94,23 @@ Or install it yourself as:
81
94
 
82
95
  ## Usage
83
96
 
84
- There are two components required, the thing being rated and how it is rated - the thing you want rated is defined as being rateable and you can have one or more "raters" to give it a rating. You must implement your these raters and provide the classes to the item being rated, this library takes care of the rest.
97
+ There are two components required, the thing being rated and how it is rated - the thing you want rated is defined as being rateable and you can have one or more rating classes to give it a rating. You must implement your these raters and provide the classes to the item being rated, this library takes care of the rest.
98
+
99
+ * `rateable` - This is the object that can be rated - this is your domain model that has various attributes that you need rated.
100
+ * `rater` - A class that knows how to give a rating to the object being rated based on classification of the rateable's attributes.
85
101
 
86
- * `Rateable` - This is the object that can be rated based on
87
- * `Rater` - A class that knows how to give a rating to the object being rated
102
+ Each `rater` must return a rating within the scale given and a weighting which will be used to calculate the overall rating.
88
103
 
89
- Each `Rater` must return a rating within the scale given and a weighting which will be used to calculate the overall rating.
104
+ The default rating scale used is 0 - 10 as floating point numbers although this can be overriden and customised.
90
105
 
91
- The current rating scale used is 0 - 10 as floating point numbers that can be rounded as you require.
106
+ The rating calculation will take the rating value from each rater along with the weighting to calculate the overall average rating.
92
107
 
93
108
  ### Rateable
94
109
 
95
110
  This module when included gives the object the following interface on the instance.
96
111
 
97
- * `rating` - `[Float]` - The overall rating calculated
98
- * `rating_descriptions` - `[Array]` - A list of the description from each rater class
112
+ * `rating` - `@return [Float]` - The overall rating calculated for the rateable object.
113
+ * `rating_descriptions` - `@return [Array]` - A list of description from each raters. This is delegated to the rater.
99
114
 
100
115
  The classes used to rate the object can be specified using the class method `rate_with(*class_names)` and passing in one or more rating classes.
101
116
 
@@ -104,29 +119,31 @@ class Film
104
119
  include FiveStar.rateable
105
120
 
106
121
  rate_with GoreRater, SwearingRater, SexRater
107
- ...
122
+ # ...
123
+ end
108
124
 
109
125
  film = Film.new
110
126
  film.rating # => 6
111
- film.rating_descriptions # => ["This Film was rated 8 for gore", ...]
127
+ film.rating_descriptions # => ["The film Alien was rated 8 for gore", ...]
112
128
  ```
113
129
 
114
130
  ### Rater
115
131
 
116
132
  You can create your own rating classes however you like but they should respond to the following methods;
117
133
 
118
- * `rating` - `[Float]` - The rating for the object being rated
119
- * `description` - `[String]` - A description of the rating, eg reason it was rated at that value
120
- * `weighting` - `[Float]` - The weighting for this classification
134
+ * `build` - `@param [Rateable], @return [instance of rater]` - Create a new instance of rater with rateable as argument.
135
+ * `rating` - `@return [Float]` - The rating for the object being rated. Calculate this by your own classification.
136
+ * `description` - `@return [String]` - A description of the rating, eg reason it was rated at that value.
137
+ * `weighting` - `@return [Float]` - The weighting for this classification. Withing range 0.0 - 1.0
121
138
 
122
- The **FiveStar** will call `build` method on the `Rater` with the argument of the instance of class being rated which should do any setup and return an instance of the rater.
139
+ The **FiveStar** library will call the `build` method on the `Rater` with the argument of the instance of class being rated which should do any setup and return an instance of the rater.
123
140
 
124
- For simplicity you can subclass `FiveStar.base_rater` and get the following for free.
141
+ For simplicity you can subclass `FiveStar.base_rater` and get the following for free. If the above methods are not overriden then the default implementation will be used.
125
142
 
126
- * `rating_weight` - Class method to set the weighting for this rater
127
- * `rateable` - Instance method referencing the object being rated
128
- * `min_rating` - Instance method returning the minimum rating value
129
- * `max_rating` - Instance method returning the maximum rating value
143
+ * `rating_weight` - `@param [Float]` - Class method to set the weighting for this rater
144
+ * `rateable` - `@return [Rateable]` - Instance method referencing the object being rated
145
+ * `min_rating` - `@return [Float]` - Instance method returning the minimum rating value
146
+ * `max_rating` - `@return [Float]` - Instance method returning the maximum rating value
130
147
 
131
148
  For example a basic version could be something like this;
132
149
 
@@ -135,7 +152,7 @@ class GoreRater < FiveStar.base_rater
135
152
  rating_weight 0.4
136
153
 
137
154
  def description
138
- "This Film was rated #{rating} for gore"
155
+ "The film #{film.title} has #{film.number_of_swear_words} and was rated at #{rating}"
139
156
  end
140
157
 
141
158
  def rating
@@ -146,9 +163,9 @@ end
146
163
 
147
164
  ### Rating calculation
148
165
 
149
- The calculation used will be a weighted average based on each rating and the weighting. If weighting is not required then all will be use the default value and therefore be weighted the same which is just a normal mean average calculation.
166
+ The calculation used will be a weighted average based on each rating and the weighting defined in that class. If weighting is not required then all will be use the default value (of 1.0) and therefore be weighted the same, this being just a normal mean average calculation.
150
167
 
151
- The minimum rating is 0.0 and the maximum is 10.0
168
+ The default rating scale used is 0 - 10 as floating point numbers although this can be overriden and customised.
152
169
 
153
170
 
154
171
  ## Development
@@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency "pry"
28
28
  spec.add_development_dependency "coveralls"
29
29
  spec.add_development_dependency "codeclimate-test-reporter"
30
+ spec.add_development_dependency "byebug" if RUBY_PLATFORM != 'java'
30
31
  end
@@ -3,12 +3,59 @@ require "five-star/base_rater"
3
3
  require "five-star/rateable"
4
4
  require "five-star/rating_calculator"
5
5
 
6
+ # Base module for library interface
6
7
  module FiveStar
7
8
  class << self
9
+ # Include this in your class that can be rated - this is your domain model
10
+ # object that has various attributes that you need rated.
11
+ # Being +rateable+ is defined as an object that has attributes on which a
12
+ # rating can be calculated based on varying attributes of that model.
13
+ #
14
+ # This adds the public class and instance methods from the Rateable module.
15
+ # See FiveStar::Rateable
16
+ #
17
+ # @example
18
+ # class Film
19
+ # include FiveStar.rateable
20
+ #
21
+ # rate_with GoreRater, SwearingRater, SexRater
22
+ # # ...
23
+ # end
24
+ #
25
+ # @return [Class]
26
+ #
27
+ # @api public
8
28
  def rateable
9
29
  Rateable
10
30
  end
11
31
 
32
+ # The base class of a class that gives a rating and weighting to something
33
+ # that is rateable. See FiveStar.rateable.
34
+ #
35
+ # This implements the interface necessary to calculate a rating for the
36
+ # rateable instance. At a minium this must be +build+, +rating+,
37
+ # +description+ and +weighting+.
38
+ #
39
+ # The method +build+ *will* be called on each class with the argument of
40
+ # the instance being rated.
41
+ # See FiveStar::BaseRater
42
+ #
43
+ # @example
44
+ # class GoreRater < FiveStar.base_rater
45
+ # rating_weight 0.4
46
+ #
47
+ # def description
48
+ # "The Film #{film.title} has #{film.number_of_swear_words} and was rated at #{rating}"
49
+ # end
50
+ #
51
+ # def rating
52
+ # # calculate rating somehow
53
+ # end
54
+ # end
55
+ #
56
+ # @return [Class]
57
+ #
58
+ # @api public
12
59
  def base_rater
13
60
  BaseRater
14
61
  end
@@ -1,29 +1,123 @@
1
1
  module FiveStar
2
+ # Base implementation of a class to give a rating, weighting and description
3
+ # to a +rateable+ instance.
4
+ #
5
+ # Default implementation is defined below, users should override methods
6
+ # with their own implementation.
2
7
  class BaseRater
8
+ # Called to build a new instance of the rater with the given object
9
+ # being rated.
10
+ #
11
+ # @param [Object] rateable
12
+ # the instance of the Object being rated
13
+ #
14
+ # @return [Object] the instance created ready to rate
15
+ #
16
+ # @api public
3
17
  def self.build(rateable)
4
18
  new(rateable)
5
19
  end
6
20
 
21
+ # Set the weighting for this rating classifcation class. This can be any
22
+ # valid floating point number at present, the weighting system is up to
23
+ # the user to ensure correct.
24
+ #
25
+ # @example
26
+ # class GoreRater < FiveStar.base_rater
27
+ # rating_weight 0.4
28
+ # # ...
29
+ # end
30
+ #
31
+ # @param [Float] weighting
32
+ # the weighting value
33
+ #
34
+ # @return [undefined]
35
+ #
36
+ # @api public
7
37
  def self.rating_weight(weighting)
8
38
  @weighting = weighting
9
39
  end
10
40
 
41
+ # Return the weighting value for this rating classifcation class.
42
+ #
43
+ # @return [Float]
44
+ # the weighting value
45
+ #
46
+ # @api public
11
47
  def self.weighting
12
48
  @weighting ||= 1.0
13
49
  end
14
50
 
51
+ # Create a new instance of rater
52
+ #
53
+ # @param [Object] rateable
54
+ # the instance of the Object being rated
55
+ #
56
+ # @api private
15
57
  def initialize(rateable)
16
58
  @rateable = rateable
17
59
  end
18
60
 
61
+ # Return the rating description for the rater given to the `rateable`
62
+ # object.
63
+ # Override to customise this message.
64
+ #
65
+ # @example
66
+ # class GoreRater < FiveStar.base_rater
67
+ # rating_weight 0.4
68
+ #
69
+ # def description
70
+ # "The film #{film.title} has #{film.number_of_swear_words} and was rated at #{rating}"
71
+ # end
72
+ # end
73
+ #
74
+ # rater.description # => "The film Alien was rated 8 for gore"
75
+ #
76
+ # @return [String] the description
77
+ #
78
+ # @api public
19
79
  def description
20
- "#{self.class} rated #{rateable.class} at #{rating} with weighting of #{weighting}"
80
+ "#{self.class} rated #{rateable_name} at #{rating} with weighting of #{weighting}"
21
81
  end
22
82
 
83
+ # Return the rating for the rater given to the `rateable` object.
84
+ # Override this method to perform your own calculation for the rating based
85
+ # on your own criteria. If this is an expensive operation then the result
86
+ # should be cached as this method *can* be called more than once, for
87
+ # example by the +description+ method.
88
+ #
89
+ # @example
90
+ # class GoreRater < FiveStar.base_rater
91
+ # rating_weight 0.4
92
+ #
93
+ # def rating
94
+ # # count the pints of blood spilt in the film and return a rating
95
+ # if film.blood_spilt == :a_lot
96
+ # 10
97
+ # elsif film.blood_spilt == :a_little
98
+ # 5
99
+ # else
100
+ # 0
101
+ # end
102
+ # end
103
+ # end
104
+ #
105
+ # rater.rating # => 6
106
+ #
107
+ # @return [Float] the rating value
108
+ # defaults to 0 unless overridden
109
+ #
110
+ # @api public
23
111
  def rating
24
112
  0
25
113
  end
26
114
 
115
+ # Return the weighting value for this rating classifcation class.
116
+ #
117
+ # @return [Float]
118
+ # the weighting value
119
+ #
120
+ # @api public
27
121
  def weighting
28
122
  self.class.weighting
29
123
  end
@@ -32,12 +126,38 @@ module FiveStar
32
126
 
33
127
  attr_reader :rateable
34
128
 
129
+ # Return the maximum weighting value for this rating classifcation class.
130
+ #
131
+ # Override if required - this should be the same for each rater class.
132
+ #
133
+ # @return [Fixnum]
134
+ # the maximum rating value.
135
+ #
136
+ # @api protected
35
137
  def max_rating
36
138
  10
37
139
  end
38
140
 
141
+ # Return the minimum weighting value for this rating classifcation class.
142
+ #
143
+ # Override if required - this should be the same for each rater class.
144
+ #
145
+ # @return [Fixnum]
146
+ # the minimum rating value.
147
+ #
148
+ # @api protected
39
149
  def min_rating
40
150
  0
41
151
  end
152
+
153
+ # Return the name of the given rateable instance.
154
+ #
155
+ # @return [String]
156
+ # the name of the object being rated.
157
+ #
158
+ # @api protected
159
+ def rateable_name
160
+ rateable.name
161
+ end
42
162
  end
43
163
  end
@@ -1,29 +1,105 @@
1
1
  module FiveStar
2
+ # A module to be included to enhance an object with the interface below
2
3
  module Rateable
4
+ # Extends base class or a module with Rateable methods
5
+ #
6
+ # @param [Object] object
7
+ # the object to mix in this +Rateable+ module
8
+ #
9
+ # @return [undefined]
10
+ #
11
+ # @api private
3
12
  def self.included(base)
4
13
  base.extend(ClassMethods)
5
14
  end
6
15
 
7
16
  module ClassMethods
17
+ # Set which rating classes will be used to rate the object
18
+ # using this module.
19
+ # Each class must implement the rater methods, see FiveStar::BaseRater
20
+ #
21
+ # @example
22
+ # class Film
23
+ # include FiveStar.rateable
24
+ #
25
+ # rate_with GoreRater, SwearingRater, SexRater
26
+ # # ...
27
+ # end
28
+ #
29
+ # @param [Class] *klasses
30
+ # constants referencing classes to rate object included with
31
+ #
32
+ # @return [undefined]
33
+ #
34
+ # @see FiveStar.rateable
35
+ #
36
+ # @api public
8
37
  def rate_with(*klasses)
9
38
  @rating_klasses = Array(klasses)
10
39
  end
11
40
 
41
+ # Define which rating classes will be used to rate the object
42
+ # using this module.
43
+ #
44
+ # @return [Array] list of classes to rate with
45
+ #
46
+ # @see FiveStar.rateable
47
+ #
48
+ # @api private
12
49
  def rating_klasses
13
50
  @rating_klasses ||= []
14
51
  end
15
52
  end
16
53
 
54
+ # Return the rating given to the `rateable` object by calculating based on
55
+ # set raters and their configuration.
56
+ #
57
+ # @example
58
+ # film = Film.new
59
+ # film.rating # => 6
60
+ #
61
+ # @return [Float] rating calculated by set raters for the object
62
+ #
63
+ # @api public
17
64
  def rating
18
65
  rating_calculator.rate(raters)
19
66
  end
20
67
 
68
+ # Return the rating description for each rater given to the `rateable`
69
+ # object.
70
+ # These are returned in the order in which the rating classes were
71
+ # defined in `rate_with`.
72
+ #
73
+ # @example
74
+ # film = Film.new
75
+ # film.rating_descriptions # => ["The film Alien was rated 8 for gore", ...]
76
+ #
77
+ # @return [Array] list of descriptions from each rater
78
+ #
79
+ # @api public
21
80
  def rating_descriptions
22
81
  raters.map { |rater| rater.description }
23
82
  end
24
83
 
84
+ # The name of the object that is rateable. This may be used by raters
85
+ # when generating descriptions.
86
+ # This can be overridden to provide a better response, otherwise is the class
87
+ # name.
88
+ #
89
+ # @return [String] name of the class
90
+ #
91
+ # @api public
92
+ def name
93
+ self.class.name
94
+ end
95
+
25
96
  protected
26
97
 
98
+ # The instance that included this module
99
+ #
100
+ # @return [Object] self
101
+ #
102
+ # @api protected
27
103
  def rateable
28
104
  self
29
105
  end
@@ -1,4 +1,7 @@
1
1
  module FiveStar
2
+ # Calculate overall rating for the rateable object from each rater.
3
+ # Each instance must implement `rating` and `weighting`.
4
+ # @api private
2
5
  class RatingCalculator
3
6
  def self.rate(raters)
4
7
  new(raters).calculate_rating
@@ -8,17 +11,27 @@ module FiveStar
8
11
  @raters = raters
9
12
  end
10
13
 
14
+ # Calculate the overall weighting from each rating class
15
+ #
16
+ # @return [Float] the calculated rating
17
+ #
18
+ # @api private
11
19
  def calculate_rating
12
20
  return 0 unless raters.any?
13
21
 
14
- sum_total = raters.map { |rater| rater.rating * rater.weighting }.inject(&:+)
15
- weights_total = raters.map(&:weighting).inject(&:+)
16
-
17
22
  sum_total / weights_total.to_f
18
23
  end
19
24
 
20
25
  private
21
26
 
22
27
  attr_reader :raters
28
+
29
+ def sum_total
30
+ raters.map { |rater| rater.rating * rater.weighting }.inject(&:+)
31
+ end
32
+
33
+ def weights_total
34
+ raters.map(&:weighting).inject(&:+)
35
+ end
23
36
  end
24
37
  end
@@ -1,3 +1,3 @@
1
1
  module FiveStar
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: five-star
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob Murray
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-11-14 00:00:00.000000000 Z
11
+ date: 2015-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: byebug
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  description: A Rating system for your Ruby objects; Rate an object with one or more
98
112
  rating classifications.
99
113
  email:
@@ -108,7 +122,6 @@ files:
108
122
  - CODE_OF_CONDUCT.md
109
123
  - Gemfile
110
124
  - LICENSE
111
- - LICENSE.txt
112
125
  - README.md
113
126
  - Rakefile
114
127
  - bin/console
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2015 Rob Murray
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.