swerling-cosell 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,2 +1,4 @@
1
1
  pkg/
2
2
  doc/
3
+ rdoc/
4
+ *.swp
@@ -1,11 +1,14 @@
1
1
  cosell
2
- by Steven Swerling
3
- http://tab-a.slot-z.net
2
+
3
+ by {Steven Swerling}[http://tab-a.slot-z.net]
4
+
5
+ {rdoc}[http://tab-a.slot-z.net] | {github}[http://www.github.com/swerling/cosell]
6
+
4
7
 
5
8
  == DESCRIPTION:
6
9
 
7
10
  Cosell is a minimal implementation of the 'Announcements' observer
8
- framework, originally introduced in VisualWorks Smalltalk 7.4 as a
11
+ framework, originally introduced in VisualWorks Smalltalk as a
9
12
  replacement for 'triggerEvent' style of event notification. Instead of
10
13
  triggering events identified by symbols, the events are first class
11
14
  objects. For rationale, please see the original blog posting by Vassili
@@ -40,7 +43,7 @@ b. Googling for 'Ruby Announcements', 'Ruby Event Announcements', etc., produced
40
43
  == FEATURE
41
44
 
42
45
  * Announcements-style event observer framework
43
- * Easy way to queue events in background
46
+ * Synchronous announcements and asynchronous announcements (using a background thread with a queue)
44
47
 
45
48
  == PROBLEMS
46
49
 
data/Rakefile CHANGED
@@ -24,18 +24,42 @@ PROJ.email = 'sswerling@yahoo.com'
24
24
  PROJ.url = 'http://github.com/swerling/TODO'
25
25
  PROJ.version = Cosell::VERSION
26
26
  PROJ.rubyforge.name = 'cosell'
27
+ PROJ.readme_file = 'README.rdoc'
27
28
 
28
29
  PROJ.spec.opts << '--color'
29
30
 
30
- PROJ.rdoc.opts = ["--inline-source"]
31
+ PROJ.rdoc.opts = ["--inline-source", "-o rdoc", "--format=html", "-T hanna"]
31
32
 
32
- namespace :my do
33
- namespace :gem do
34
- task :package => [:clobber] do
35
- sh "rm -rf #{File.join(File.dirname(__FILE__), 'pkg')}"
36
- sh "rm -rf #{File.join(File.dirname(__FILE__), 'doc')}"
37
- Rake::Task['gem:package'].invoke
38
- end
39
- end
33
+
34
+
35
+ require 'fileutils'
36
+ def this_dir; File.join(File.dirname(__FILE__)); end
37
+ def doc_dir; File.join(this_dir, 'rdoc'); end
38
+ def tab_a_doc_dir; File.join(this_dir, '../tab-a/public/cosell/rdoc'); end
39
+ task :myclobber => [:clobber] do
40
+ mydir = File.join(File.dirname(__FILE__))
41
+ sh "rm -rf #{File.join(mydir, 'pkg')}"
42
+ sh "rm -rf #{File.join(mydir, 'doc')}"
43
+ sh "rm -rf #{File.join(mydir, 'rdoc')}"
44
+ sh "rm -rf #{File.join(mydir, 'ext/*.log')}"
45
+ sh "rm -rf #{File.join(mydir, 'ext/*.o')}"
46
+ sh "rm -rf #{File.join(mydir, 'ext/*.so')}"
47
+ sh "rm -rf #{File.join(mydir, 'ext/Makefile')}"
48
+ sh "rm -rf #{File.join(mydir, 'ext/Makefile')}"
49
+ end
50
+ task :mypackage => [:myclobber] do
51
+ Rake::Task['gem:package'].invoke
52
+ end
53
+ task :mydoc => [:myclobber] do
54
+ FileUtils.rm_f doc_dir()
55
+ sh "cd #{this_dir()} && rdoc -o rdoc --inline-source --format=html -T hanna README.rdoc lib/**/*.rb"
56
+ end
57
+ task :taba => [:mydoc] do
58
+ this_dir = File.join(File.dirname(__FILE__))
59
+ FileUtils.rm_rf tab_a_doc_dir
60
+ FileUtils.cp_r doc_dir, tab_a_doc_dir
40
61
  end
41
62
 
63
+ task :mygemspec => [:myclobber] do
64
+ Rake::Task['gem:spec'].invoke
65
+ end
@@ -2,13 +2,13 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{cosell}
5
- s.version = "0.0.1"
5
+ s.version = "0.0.2"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Steven Swerling"]
9
- s.date = %q{2009-07-18}
9
+ s.date = %q{2009-08-09}
10
10
  s.description = %q{Cosell is a minimal implementation of the 'Announcements' observer
11
- framework, originally introduced in VisualWorks Smalltalk 7.4 as a
11
+ framework, originally introduced in VisualWorks Smalltalk as a
12
12
  replacement for 'triggerEvent' style of event notification. Instead of
13
13
  triggering events identified by symbols, the events are first class
14
14
  objects. For rationale, please see the original blog posting by Vassili
@@ -40,25 +40,26 @@ b. Googling for 'Ruby Announcements', 'Ruby Event Announcements', etc., produced
40
40
  * {Original blog posting describing Announcments by Vassili Bykov}[http://www.cincomsmalltalk.com/userblogs/vbykov/blogView?entry=3310034894]
41
41
  * {More info on the Announcements Framework}[http://wiki.squeak.org/squeak/5734]}
42
42
  s.email = %q{sswerling@yahoo.com}
43
- s.extra_rdoc_files = ["History.txt", "README.rdoc", "README.txt"]
44
- s.files = [".gitignore", "History.txt", "README.rdoc", "README.txt", "Rakefile", "cosell.gemspec", "example/basic_example.rb", "example/cat_whisperer.rb", "lib/cosell.rb", "lib/cosell/announcer.rb", "lib/cosell/monkey.rb", "spec/cosell_spec.rb", "spec/spec_helper.rb"]
43
+ s.extra_rdoc_files = ["History.txt", "README.rdoc"]
44
+ s.files = [".gitignore", "History.txt", "README.rdoc", "Rakefile", "cosell.gemspec", "example/basic_example.rb", "example/cat_whisperer.rb", "lib/cosell.rb", "lib/cosell/announcer.rb", "lib/cosell/monkey.rb", "spec/cosell_spec.rb", "spec/spec_helper.rb"]
45
+ s.has_rdoc = true
45
46
  s.homepage = %q{http://github.com/swerling/TODO}
46
- s.rdoc_options = ["--inline-source", "--main", "README.txt"]
47
+ s.rdoc_options = ["--inline-source", "-o rdoc", "--format=html", "-T hanna", "--main", "README.rdoc"]
47
48
  s.require_paths = ["lib"]
48
49
  s.rubyforge_project = %q{cosell}
49
- s.rubygems_version = %q{1.3.3}
50
- s.summary = %q{Cosell is a minimal implementation of the 'Announcements' observer framework, originally introduced in VisualWorks Smalltalk 7}
50
+ s.rubygems_version = %q{1.3.2}
51
+ s.summary = %q{Cosell is a minimal implementation of the 'Announcements' observer framework, originally introduced in VisualWorks Smalltalk as a replacement for 'triggerEvent' style of event notification}
51
52
 
52
53
  if s.respond_to? :specification_version then
53
54
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
54
55
  s.specification_version = 3
55
56
 
56
57
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
57
- s.add_development_dependency(%q<bones>, [">= 2.4.0"])
58
+ s.add_development_dependency(%q<bones>, [">= 2.5.1"])
58
59
  else
59
- s.add_dependency(%q<bones>, [">= 2.4.0"])
60
+ s.add_dependency(%q<bones>, [">= 2.5.1"])
60
61
  end
61
62
  else
62
- s.add_dependency(%q<bones>, [">= 2.4.0"])
63
+ s.add_dependency(%q<bones>, [">= 2.5.1"])
63
64
  end
64
65
  end
@@ -1,7 +1,7 @@
1
1
  module Cosell
2
2
 
3
3
  # :stopdoc:
4
- VERSION = '0.0.1'
4
+ VERSION = '0.0.2'
5
5
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
6
6
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
7
7
 
@@ -15,12 +15,18 @@ module Cosell
15
15
 
16
16
  # Place all announcments in a queue, and make announcements in a background thread.
17
17
  #
18
- # Options:
18
+ # Arguments:
19
+ # :logger => a logger. Where to log exceptions and warnings.
20
+ # This argument is mandatory -- it is too hard to debug exceptions in announcement
21
+ # handler code without a logger. If you _really_ want your code to fail silently,
22
+ # you will have to create a logger on /dev/null.
19
23
  # :sleep_time => how long to sleep (in seconds) after making a batch of announchements
20
- # default: 0.01
24
+ # optional arg, default: 0.01
21
25
  # :announcements_per_cycle => how many announcements to make before sleeping for sleep_time
22
- # default: 25
23
- # :logger => a logger. Where to log exceptions and warnings.
26
+ # optional arg, default: 25
27
+ #
28
+ # WARNING: If you do not pass in a logger, announcement code will fail silently (the queue
29
+ # is in a background thread).
24
30
  #
25
31
  # Note: at the moment, this method may only be called once, and cannot be undone. There is
26
32
  # no way to interrupt the thread.
@@ -29,6 +35,13 @@ module Cosell
29
35
 
30
36
  self.initialize_cosell_if_needed
31
37
 
38
+ # The logger in mandatory
39
+ if opts[:logger]
40
+ self.queue_logger = opts[:logger]
41
+ else
42
+ raise "Cosell error: You have to provide a logger, otherwise failures in announcement handler code are to hard to debug"
43
+ end
44
+
32
45
  # kill off the last queue first
33
46
  if self.announcements_thread
34
47
  kill_queue!
@@ -41,18 +54,17 @@ module Cosell
41
54
 
42
55
  how_many_per_cycle = opts[:announcements_per_cycle] || 25
43
56
  cycle_duration = opts[:sleep_time] || 0.01
44
- self.queue_logger = opts[:logger]
45
57
  count = 0
46
58
 
47
59
  self.announcements_thread = Thread.new do
48
- begin
49
- loop do
50
- if queue_killed?
51
- self.kill_announcement_queue = false
52
- self.announcements_thread = nil
53
- log "Announcement queue killed with #{self.announcements_queue.size} announcements still queued", :info
54
- break
55
- else
60
+ loop do
61
+ if queue_killed?
62
+ self.kill_announcement_queue = false
63
+ self.announcements_thread = nil
64
+ log "Announcement queue killed with #{self.announcements_queue.size} announcements still queued", :info
65
+ break
66
+ else
67
+ begin
56
68
  self.announce_now! self.announcements_queue.pop
57
69
  count += 1
58
70
  if (count%how_many_per_cycle).eql?(0)
@@ -60,10 +72,10 @@ module Cosell
60
72
  count = 0
61
73
  sleep cycle_duration
62
74
  end
75
+ rescue Exception => x
76
+ log "Exception: #{x}, trace: \n\t#{x.backtrace.join("\n\t")}", :error
63
77
  end
64
78
  end
65
- rescue Exception => x
66
- log "Exception: #{x}, trace: \n\t#{x.backtrace.join("\n\t")}", :error
67
79
  end
68
80
  end
69
81
 
@@ -148,7 +160,7 @@ module Cosell
148
160
  # :on => Which class of announcements to spy on. Default is Object (ie. all announcements)
149
161
  # :logger => The log to log to. Default is a logger on STDOUT
150
162
  # :level => The log level to log with. Default is :info
151
- # :preface => A message to prepend to all log messages. Default is "Announcement Spy: "
163
+ # :preface_with => A message to prepend to all log messages. Default is "Announcement Spy: "
152
164
  def spy!(opts = {})
153
165
  on = opts[:on] || Object
154
166
  logger = opts[:logger] || Logger.new(STDOUT)
@@ -190,6 +202,9 @@ module Cosell
190
202
  return @__queue_announcements.eql?(true)
191
203
  end
192
204
 
205
+ def subscriptions= x; @__subscriptions = x; end
206
+ def subscriptions; @__subscriptions ||= []; end
207
+
193
208
  protected
194
209
 
195
210
  #:stopdoc:
@@ -211,8 +226,6 @@ module Cosell
211
226
  def announcements_thread= x; @__announcements_thread = x; end
212
227
  def kill_announcement_queue= x; @__kill_announcement_queue = x; end
213
228
  def should_queue_announcements= x; @__queue_announcements = x; end
214
- def subscriptions= x; @__subscriptions = x; end
215
- def subscriptions; @__subscriptions; end
216
229
 
217
230
  #:startdoc:
218
231
  public
@@ -15,7 +15,7 @@ class Object
15
15
  # When cosell is configured to "spy!", the result of announement.as_announcement_trace is what
16
16
  # is sent to the spy log. By default just calls 'to_s'.
17
17
  def as_announcement_trace
18
- self.to_s
18
+ self.to_s rescue "(Warning: could not create announcement trace)"
19
19
  end
20
20
 
21
21
  # When a class is used as an announcment, an empty new instance is created using #allocate.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swerling-cosell
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Swerling
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-18 00:00:00 -07:00
12
+ date: 2009-08-09 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,9 +20,9 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 2.4.0
23
+ version: 2.5.1
24
24
  version:
25
- description: Cosell is a minimal implementation of the 'Announcements' observer framework, originally introduced in VisualWorks Smalltalk 7.4 as a replacement for 'triggerEvent' style of event notification. Instead of triggering events identified by symbols, the events are first class objects. For rationale, please see the original blog posting by Vassili Bykov (refs below). *Lineage* This implementation is loosely based on Lukas Renggli's tweak of Colin Putney's Squeak implementation of Vassili Bykov's Announcements framework for VisualWorks Smalltalk. (Specifically Announcements-lr.13.mcz was used as a reference.) Liberties where taken during the port. In particular, the Announcer class in the Smalltalk version is implemented here as a ruby module which can be mixed into any object. Also, in this implementation any object (or class) can serve as an announcement, so no Announcement class is implemented. The ability to queue announcements in the background is built into cosell. <b>The Name 'Cosell'</b> I chose the name 'Cosell' because a. Howard Cosell is an iconic event announcer b. Googling for 'Ruby Announcements', 'Ruby Event Announcements', etc., produced scads of results about ruby meetups, conferences, and the like. So I went with something a bit cryptic but hopefully a little more searchable. *See* * {Original blog posting describing Announcments by Vassili Bykov}[http://www.cincomsmalltalk.com/userblogs/vbykov/blogView?entry=3310034894] * {More info on the Announcements Framework}[http://wiki.squeak.org/squeak/5734]
25
+ description: Cosell is a minimal implementation of the 'Announcements' observer framework, originally introduced in VisualWorks Smalltalk as a replacement for 'triggerEvent' style of event notification. Instead of triggering events identified by symbols, the events are first class objects. For rationale, please see the original blog posting by Vassili Bykov (refs below). *Lineage* This implementation is loosely based on Lukas Renggli's tweak of Colin Putney's Squeak implementation of Vassili Bykov's Announcements framework for VisualWorks Smalltalk. (Specifically Announcements-lr.13.mcz was used as a reference.) Liberties where taken during the port. In particular, the Announcer class in the Smalltalk version is implemented here as a ruby module which can be mixed into any object. Also, in this implementation any object (or class) can serve as an announcement, so no Announcement class is implemented. The ability to queue announcements in the background is built into cosell. <b>The Name 'Cosell'</b> I chose the name 'Cosell' because a. Howard Cosell is an iconic event announcer b. Googling for 'Ruby Announcements', 'Ruby Event Announcements', etc., produced scads of results about ruby meetups, conferences, and the like. So I went with something a bit cryptic but hopefully a little more searchable. *See* * {Original blog posting describing Announcments by Vassili Bykov}[http://www.cincomsmalltalk.com/userblogs/vbykov/blogView?entry=3310034894] * {More info on the Announcements Framework}[http://wiki.squeak.org/squeak/5734]
26
26
  email: sswerling@yahoo.com
27
27
  executables: []
28
28
 
@@ -31,12 +31,10 @@ extensions: []
31
31
  extra_rdoc_files:
32
32
  - History.txt
33
33
  - README.rdoc
34
- - README.txt
35
34
  files:
36
35
  - .gitignore
37
36
  - History.txt
38
37
  - README.rdoc
39
- - README.txt
40
38
  - Rakefile
41
39
  - cosell.gemspec
42
40
  - example/basic_example.rb
@@ -46,13 +44,17 @@ files:
46
44
  - lib/cosell/monkey.rb
47
45
  - spec/cosell_spec.rb
48
46
  - spec/spec_helper.rb
49
- has_rdoc: false
47
+ has_rdoc: true
50
48
  homepage: http://github.com/swerling/TODO
49
+ licenses:
51
50
  post_install_message:
52
51
  rdoc_options:
53
52
  - --inline-source
53
+ - -o rdoc
54
+ - --format=html
55
+ - -T hanna
54
56
  - --main
55
- - README.txt
57
+ - README.rdoc
56
58
  require_paths:
57
59
  - lib
58
60
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -70,9 +72,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
72
  requirements: []
71
73
 
72
74
  rubyforge_project: cosell
73
- rubygems_version: 1.2.0
75
+ rubygems_version: 1.3.5
74
76
  signing_key:
75
77
  specification_version: 3
76
- summary: Cosell is a minimal implementation of the 'Announcements' observer framework, originally introduced in VisualWorks Smalltalk 7
78
+ summary: Cosell is a minimal implementation of the 'Announcements' observer framework, originally introduced in VisualWorks Smalltalk as a replacement for 'triggerEvent' style of event notification
77
79
  test_files: []
78
80
 
data/README.txt DELETED
@@ -1,187 +0,0 @@
1
- cosell
2
- by Steven Swerling
3
- http://tab-a.slot-z.net
4
-
5
- == DESCRIPTION:
6
-
7
- Cosell is a minimal implementation of the 'Announcements' observer
8
- framework, originally introduced in VisualWorks Smalltalk 7.4 as a
9
- replacement for 'triggerEvent' style of event notification. Instead of
10
- triggering events identified by symbols, the events are first class
11
- objects. For rationale, please see the original blog posting by Vassili
12
- Bykov (refs below).
13
-
14
- *Lineage*
15
-
16
- This implementation is loosely based on Lukas Renggli's tweak of Colin Putney's
17
- Squeak implementation of Vassili Bykov's Announcements framework for
18
- VisualWorks Smalltalk. (Specifically Announcements-lr.13.mcz was used as
19
- a reference.)
20
-
21
- Liberties where taken during the port. In particular, the Announcer class
22
- in the Smalltalk version is implemented here as a ruby module which can be
23
- mixed into any object. Also, in this implementation any object (or class)
24
- can serve as an announcement, so no Announcement class is implemented.
25
-
26
- The ability to queue announcements in the background is built into cosell.
27
-
28
- <b>The Name 'Cosell'</b>
29
-
30
- I chose the name 'Cosell' because
31
-
32
- a. Howard Cosell is an iconic event announcer
33
- b. Googling for 'Ruby Announcements', 'Ruby Event Announcements', etc., produced scads of results about ruby meetups, conferences, and the like. So I went with something a bit cryptic but hopefully a little more searchable.
34
-
35
- *See*
36
-
37
- * {Original blog posting describing Announcments by Vassili Bykov}[http://www.cincomsmalltalk.com/userblogs/vbykov/blogView?entry=3310034894]
38
- * {More info on the Announcements Framework}[http://wiki.squeak.org/squeak/5734]
39
-
40
- == FEATURE
41
-
42
- * Announcements-style event observer framework
43
- * Easy way to queue events in background
44
-
45
- == PROBLEMS
46
-
47
- * None known. Should work in ruby 1.8 and 1.9.
48
-
49
- == SYNOPSIS:
50
-
51
-
52
- (this example is in the [gem]/example/basic_example.rb file)
53
-
54
- #
55
- # Will produce the following output:
56
- #
57
- # And now a word from our sponsor: 'the'
58
- # End of round 1
59
- # End of round 2
60
- # End of round 3
61
- # End of round 4
62
- # End of round 5
63
- # End of round 6
64
- # End of round 7
65
- # End of round 8
66
- # End of round 9
67
- # End of round 10
68
- # End of round 11
69
- # End of round 12
70
- # End of round 13
71
- # End of round 14
72
- # TKO!
73
-
74
- require 'rubygems'
75
- require 'cosell'
76
-
77
- # An announcer
78
- class Howard
79
- include Cosell
80
- end
81
-
82
- # a receiver of the announcements
83
- class Television
84
- def show(ann, opts={})
85
- puts ann.to_s(opts)
86
- end
87
- end
88
-
89
- # Some announcements
90
- class Announcement
91
- def to_s(opts={})
92
- self.class.to_s + '!'
93
- end
94
- end
95
- class WordFromOurSponsor < Announcement
96
- attr_accessor :word
97
- def to_s(opts={})
98
- "And now a word from our sponsor: '#{word}'"
99
- end
100
- end
101
- class EndOfRound < Announcement
102
- def to_s(opts={})
103
- "End of round #{opts[:round]}"
104
- end
105
- end
106
- class KnockOut < Announcement; end
107
- class TKO < KnockOut; end
108
-
109
-
110
- # ------- Start announcing -------
111
-
112
- # Create an announcer, and a subscriber
113
- round = 1
114
- howard = Howard.new
115
- tv = Television.new
116
- howard.when_announcing(WordFromOurSponsor, KnockOut) { |ann| tv.show(ann) }
117
-
118
- # Make an announcement
119
- announcement = WordFromOurSponsor.new
120
- announcement.word = 'the'
121
- howard.announce(announcement)
122
- # => And know a word from our sponsors: 'the'
123
-
124
- # Make another announcement
125
- howard.announce(EndOfRound)
126
- # => nothing, you haven't subscribed yet to EndOfRound. Tree fell, nobody heard. Didn't happen.
127
-
128
- # Create a second subscription
129
- eor_subscription = lambda do |ann|
130
- tv.show(ann, :round => round)
131
- round += 1
132
- end
133
- howard.when_announcing(EndOfRound, &eor_subscription)
134
-
135
- # Tell the announcer to use a background announcments queue
136
- # Only allow the announcer to broadcast 5 announcments at a time
137
- # before going to sleep for 0.05 seconds
138
- howard.queue_announcements!(:sleep_time => 0.05, :announcements_per_cycle => 5)
139
-
140
- # Start making announcments (they will be queueud in the background)
141
- 14.times {howard.announce(EndOfRound)}
142
-
143
- sleep 0.05 # announcements for the first 5 rounds appear
144
- sleep 0.05 # announcements for the next 5 rounds
145
- sleep 0.05 # announcements for end of the next 4 rounds (there is not 15th round
146
- sleep 0.05 # no announcements, all the announcements have been announced
147
-
148
- # queue the final announcment
149
- howard.announce(TKO)
150
- # => TKO!
151
-
152
- sleep 0.05 # the TKO is broadcast
153
-
154
- == REQUIREMENTS:
155
-
156
- * ruby, rubygems
157
-
158
- == INSTALL:
159
-
160
-
161
- gem install swerling-cosell --source http://gems.github.com
162
-
163
-
164
- == LICENSE:
165
-
166
- (The MIT License)
167
-
168
- Copyright (c) 2009
169
-
170
- Permission is hereby granted, free of charge, to any person obtaining
171
- a copy of this software and associated documentation files (the
172
- 'Software'), to deal in the Software without restriction, including
173
- without limitation the rights to use, copy, modify, merge, publish,
174
- distribute, sublicense, and/or sell copies of the Software, and to
175
- permit persons to whom the Software is furnished to do so, subject to
176
- the following conditions:
177
-
178
- The above copyright notice and this permission notice shall be
179
- included in all copies or substantial portions of the Software.
180
-
181
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
182
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
183
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
184
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
185
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
186
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
187
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.