ims_caliper 0.9.3.15 → 1.0.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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -5
  3. data/lib/caliper/{profiles/annotation_profile.rb → actions/annotation_actions.rb} +3 -41
  4. data/lib/caliper/{profiles/assessment_profile.rb → actions/assessment_actions.rb} +3 -19
  5. data/lib/caliper/actions/assessment_item_actions.rb +31 -0
  6. data/lib/caliper/{profiles/assignable_profile.rb → actions/assignable_actions.rb} +3 -28
  7. data/lib/caliper/{profiles/media_profile.rb → actions/media_actions.rb} +4 -29
  8. data/lib/caliper/{event/view_event.rb → actions/navigation_actions.rb} +5 -11
  9. data/lib/caliper/{validators/event_validator_context.rb → actions/outcome_actions.rb} +7 -15
  10. data/lib/caliper/{event/navigation_event.rb → actions/reading_actions.rb} +6 -14
  11. data/lib/caliper/actions/session_actions.rb +30 -0
  12. data/lib/caliper/context/context.rb +31 -0
  13. data/lib/caliper/entities/agent/organization.rb +4 -3
  14. data/lib/caliper/entities/agent/person.rb +4 -3
  15. data/lib/caliper/entities/agent/software_application.rb +4 -3
  16. data/lib/caliper/entities/annotation/annotation.rb +4 -12
  17. data/lib/caliper/entities/annotation/annotation_type.rb +32 -0
  18. data/lib/caliper/entities/annotation/bookmark_annotation.rb +3 -1
  19. data/lib/caliper/entities/annotation/highlight_annotation.rb +4 -4
  20. data/lib/caliper/entities/annotation/shared_annotation.rb +3 -1
  21. data/lib/caliper/entities/annotation/tag_annotation.rb +3 -1
  22. data/lib/caliper/entities/assessment/assessment.rb +1 -1
  23. data/lib/caliper/entities/assessment/assessment_item.rb +2 -0
  24. data/lib/caliper/entities/assignable/assignable_digital_resource.rb +3 -13
  25. data/lib/caliper/{event/session_event.rb → entities/assignable/assignable_digital_resource_type.rb} +7 -11
  26. data/lib/caliper/entities/assignable/attempt.rb +8 -9
  27. data/lib/caliper/entities/digital_resource.rb +5 -22
  28. data/lib/caliper/entities/digital_resource_type.rb +33 -0
  29. data/lib/caliper/entities/entity.rb +7 -37
  30. data/lib/caliper/entities/{learning_context.rb → entity_base.rb} +19 -15
  31. data/lib/caliper/entities/entity_type.rb +39 -0
  32. data/lib/caliper/entities/foaf/agent.rb +0 -2
  33. data/lib/caliper/entities/jsonable.rb +14 -3
  34. data/lib/caliper/entities/learning_objective.rb +4 -3
  35. data/lib/caliper/entities/lis/course_offering.rb +9 -6
  36. data/lib/caliper/entities/lis/course_section.rb +3 -1
  37. data/lib/caliper/entities/lis/group.rb +5 -3
  38. data/lib/caliper/entities/lis/membership.rb +5 -7
  39. data/lib/caliper/entities/media/audio_object.rb +2 -1
  40. data/lib/caliper/entities/media/image_object.rb +2 -1
  41. data/lib/caliper/entities/media/media_location.rb +2 -1
  42. data/lib/caliper/entities/media/media_object.rb +2 -9
  43. data/lib/caliper/entities/media/media_object_type.rb +31 -0
  44. data/lib/caliper/entities/media/video_object.rb +2 -1
  45. data/lib/caliper/entities/outcome/result.rb +23 -16
  46. data/lib/caliper/entities/reading/epub_chapter.rb +2 -1
  47. data/lib/caliper/entities/reading/epub_part.rb +2 -1
  48. data/lib/caliper/entities/reading/epub_sub_chapter.rb +2 -1
  49. data/lib/caliper/entities/reading/epub_volume.rb +2 -1
  50. data/lib/caliper/entities/reading/frame.rb +4 -3
  51. data/lib/caliper/entities/reading/web_page.rb +3 -2
  52. data/lib/caliper/entities/response/fillin_blank_response.rb +3 -3
  53. data/lib/caliper/entities/response/multiple_choice_response.rb +3 -3
  54. data/lib/caliper/entities/response/multiple_response_response.rb +3 -3
  55. data/lib/caliper/entities/response/response.rb +8 -10
  56. data/lib/caliper/entities/response/response_type.rb +5 -5
  57. data/lib/caliper/entities/response/select_type_response.rb +3 -3
  58. data/lib/caliper/entities/response/true_false_response.rb +2 -3
  59. data/lib/caliper/entities/session/session.rb +8 -7
  60. data/lib/caliper/{event → events}/annotation_event.rb +11 -3
  61. data/lib/caliper/{event → events}/assessment_event.rb +11 -8
  62. data/lib/caliper/{event → events}/assessment_item_event.rb +11 -8
  63. data/lib/caliper/{event → events}/assignable_event.rb +11 -8
  64. data/lib/caliper/{profiles/profile.rb → events/event.rb} +15 -15
  65. data/lib/caliper/events/event_context.rb +24 -0
  66. data/lib/caliper/events/event_type.rb +33 -0
  67. data/lib/caliper/{event → events}/jsonable.rb +2 -2
  68. data/lib/caliper/{event → events}/media_event.rb +11 -8
  69. data/lib/caliper/events/navigation_event.rb +47 -0
  70. data/lib/caliper/events/outcome_event.rb +44 -0
  71. data/lib/caliper/{event/outcome_event.rb → events/reading_event.rb} +13 -10
  72. data/lib/caliper/events/session_event.rb +42 -0
  73. data/lib/caliper/events/view_event.rb +44 -0
  74. data/lib/caliper/request/envelope.rb +4 -15
  75. data/lib/caliper/request/event_store_requestor.rb +1 -1
  76. data/lib/caliper/request/{envelope_jsonable.rb → jsonable.rb} +9 -11
  77. data/lib/caliper/sensor.rb +1 -1
  78. data/lib/caliper/version.rb +1 -1
  79. data/lib/caliper.rb +1 -1
  80. data/spec/lib/entities/agent/{student.json → person.json} +4 -3
  81. data/spec/lib/entities/agent/person_spec.rb +5 -6
  82. data/spec/lib/entities/assessment/assessment.json +23 -0
  83. data/spec/lib/entities/assessment/assessment_spec.rb +54 -0
  84. data/spec/lib/event_helper.rb +33 -41
  85. data/spec/lib/{event/annotation_event_bookmark_spec.rb → events/annotation_bookmarked_event_spec.rb} +36 -46
  86. data/spec/lib/{event/annotation_event_highlight_spec.rb → events/annotation_highlighted_event_spec.rb} +36 -46
  87. data/spec/lib/{event/annotation_event_shared_spec.rb → events/annotation_shared_event_spec.rb} +42 -52
  88. data/spec/lib/{event/annotation_event_tag_spec.rb → events/annotation_tagged_event_spec.rb} +36 -46
  89. data/spec/lib/{event → events}/assessment_item_completed_event_spec.rb +41 -65
  90. data/spec/lib/{event → events}/assessment_item_started_event_spec.rb +38 -56
  91. data/spec/lib/{event/assessment_event_spec.rb → events/assessment_started_event_spec.rb} +36 -51
  92. data/spec/lib/{event/assignable_event_spec.rb → events/assignable_activated_event_spec.rb} +37 -52
  93. data/spec/lib/{event/media_event_spec.rb → events/media_paused_video_event_spec.rb} +33 -43
  94. data/spec/lib/{event/navigated_event_spec.rb → events/navigation_navigated_to_event_spec.rb} +36 -45
  95. data/spec/lib/events/outcome_graded_event_spec.rb +163 -0
  96. data/spec/lib/{event/session_event_login_spec.rb → events/session_logged_in_event_spec.rb} +38 -46
  97. data/spec/lib/{event/session_event_logout_spec.rb → events/session_logged_out-event_spec.rb} +28 -37
  98. data/spec/lib/{event/session_event_timeout_spec.rb → events/session_timed_out_event_spec.rb} +24 -34
  99. data/spec/lib/{event/viewed_event_spec.rb → events/view_viewed_event_spec.rb} +33 -41
  100. data/spec/lib/request/{http_requestor_spec.rb → http_requestor_single_event_spec.rb} +46 -47
  101. data/spec/lib/request/http_requestor_single_minimal_event_spec.rb +84 -0
  102. data/spec/lib/sensor_spec.rb +1 -1
  103. metadata +77 -70
  104. data/lib/caliper/event/event.rb +0 -114
  105. data/lib/caliper/profiles/assessment_item_profile.rb +0 -48
  106. data/lib/caliper/profiles/reading_profile.rb +0 -56
  107. data/lib/caliper/profiles/session_profile.rb +0 -46
  108. data/lib/caliper/validators/error_message.rb +0 -63
  109. data/lib/caliper/validators/event_validator.rb +0 -57
  110. data/lib/caliper/validators/property_type_check.rb +0 -33
  111. data/lib/caliper/validators/session_login_event_validator.rb +0 -121
  112. data/lib/caliper/validators/session_logout_event_validator.rb +0 -120
  113. data/lib/caliper/validators/time_check.rb +0 -50
  114. data/spec/lib/entities/entity.json +0 -9
  115. data/spec/lib/entities/entity_spec.rb +0 -52
@@ -16,6 +16,7 @@
16
16
  # with this program. If not, see http://www.gnu.org/licenses/.
17
17
 
18
18
  require_relative '../digital_resource'
19
+ require_relative '../digital_resource_type'
19
20
 
20
21
  #
21
22
  # Representation of an EPUB 3 Chapter. A major structural division of a piece of writing.
@@ -28,7 +29,7 @@ module Caliper
28
29
 
29
30
  def initialize()
30
31
  super
31
- @type = DigitalResourceType::EPUB_CHAPTER
32
+ @type = Caliper::Entities::DigitalResourceType::EPUB_CHAPTER
32
33
  end
33
34
  end
34
35
  end
@@ -16,6 +16,7 @@
16
16
  # with this program. If not, see http://www.gnu.org/licenses/.
17
17
 
18
18
  require_relative '../digital_resource'
19
+ require_relative '../digital_resource_type'
19
20
 
20
21
  #
21
22
  # Representation of an EPUB 3 Part. A major structural division of a piece of writing, typically
@@ -28,7 +29,7 @@ module Caliper
28
29
 
29
30
  def initialize()
30
31
  super
31
- @type = DigitalResourceType::EPUB_PART
32
+ @type = Caliper::Entities::DigitalResourceType::EPUB_PART
32
33
  end
33
34
  end
34
35
  end
@@ -16,6 +16,7 @@
16
16
  # with this program. If not, see http://www.gnu.org/licenses/.
17
17
 
18
18
  require_relative '../digital_resource'
19
+ require_relative '../digital_resource_type'
19
20
 
20
21
  #
21
22
  # Representation of an EPUB 3 subchapter. A major sub-division of a chapter.
@@ -28,7 +29,7 @@ module Caliper
28
29
 
29
30
  def initialize()
30
31
  super
31
- @type = DigitalResourceType::EPUB_SUB_CHAPTER
32
+ @type = Caliper::Entities::DigitalResourceType::EPUB_SUB_CHAPTER
32
33
  end
33
34
  end
34
35
  end
@@ -16,6 +16,7 @@
16
16
  # with this program. If not, see http://www.gnu.org/licenses/.
17
17
 
18
18
  require_relative '../digital_resource'
19
+ require_relative '../digital_resource_type'
19
20
 
20
21
  #
21
22
  # Public: Representation of an EPUB 3 Volume. A component of a collection.
@@ -28,7 +29,7 @@ module Caliper
28
29
 
29
30
  def initialize()
30
31
  super
31
- @type = DigitalResourceType::EPUB_VOLUME
32
+ @type = Caliper::Entities::DigitalResourceType::EPUB_VOLUME
32
33
  end
33
34
  end
34
35
  end
@@ -15,8 +15,9 @@
15
15
  # You should have received a copy of the GNU Lesser General Public License along
16
16
  # with this program. If not, see http://www.gnu.org/licenses/.
17
17
 
18
- require_relative '../../entities/digital_resource'
19
- require_relative '../../entities/targetable'
18
+ require_relative '../digital_resource'
19
+ require_relative '../digital_resource_type'
20
+ require_relative '../targetable'
20
21
 
21
22
  #
22
23
  # A Frame
@@ -31,7 +32,7 @@ module Caliper
31
32
 
32
33
  def initialize
33
34
  super
34
- @type = DigitalResourceType::FRAME
35
+ @type = Caliper::Entities::DigitalResourceType::FRAME
35
36
  @index = 0
36
37
  end
37
38
  end
@@ -15,8 +15,9 @@
15
15
  # You should have received a copy of the GNU Lesser General Public License along
16
16
  # with this program. If not, see http://www.gnu.org/licenses/.
17
17
 
18
- require_relative "../../entities/digital_resource"
19
- require_relative "../../entities/schemadotorg/web_page"
18
+ require_relative '../digital_resource'
19
+ require_relative '../digital_resource_type'
20
+ require_relative '../schemadotorg/web_page'
20
21
 
21
22
  #
22
23
  # Web Page
@@ -26,12 +26,12 @@ module Caliper
26
26
  module Entities
27
27
  module Response
28
28
  class FillinBlankResponse < Response
29
- attr_accessor :type,
30
- :values
29
+
30
+ attr_accessor :values
31
31
 
32
32
  def initialize
33
33
  super
34
- @type = ResponseType::FILLINBLANK
34
+ @type = Caliper::Entities::Response::ResponseType::FILLINBLANK
35
35
  end
36
36
  end
37
37
  end
@@ -25,12 +25,12 @@ module Caliper
25
25
  module Entities
26
26
  module Response
27
27
  class MultipleChoiceResponse < Response
28
- attr_accessor :type,
29
- :values
28
+
29
+ attr_accessor :values
30
30
 
31
31
  def initialize
32
32
  super
33
- @type = ResponseType::MULTIPLECHOICE
33
+ @type = Caliper::Entities::Response::ResponseType::MULTIPLECHOICE
34
34
  end
35
35
  end
36
36
  end
@@ -25,12 +25,12 @@ module Caliper
25
25
  module Entities
26
26
  module Response
27
27
  class MultipleResponseResponse < Response
28
- attr_accessor :type,
29
- :values
28
+
29
+ attr_accessor :values
30
30
 
31
31
  def initialize
32
32
  super
33
- @type = ResponseType::MULTIPLERESPONSE
33
+ @type = Caliper::Entities::Response::ResponseType::MULTIPLERESPONSE
34
34
  end
35
35
  end
36
36
  end
@@ -15,7 +15,8 @@
15
15
  # You should have received a copy of the GNU Lesser General Public License along
16
16
  # with this program. If not, see http://www.gnu.org/licenses/.
17
17
 
18
- require_relative '../entity'
18
+ require_relative '../entity_base'
19
+ require_relative '../entity_type'
19
20
  require_relative '../generatable'
20
21
 
21
22
  #
@@ -24,20 +25,17 @@ require_relative '../generatable'
24
25
  module Caliper
25
26
  module Entities
26
27
  module Response
27
- class Response < Entity
28
+ class Response < EntityBase
28
29
  include Caliper::Entities::Generatable
29
30
 
30
- attr_accessor :type,
31
- :assignable,
32
- :actor,
33
- :attempt,
34
- :startedAtTime,
35
- :endedAtTime,
36
- :duration
31
+ attr_accessor :assignable, :actor, :attempt, :startedAtTime, :endedAtTime, :duration
37
32
 
38
33
  def initialize
39
34
  super
40
- @type = EntityType::RESPONSE
35
+ @type = Caliper::Entities::EntityType::RESPONSE
36
+ @startedAtTime = nil
37
+ @endedAtTime = nil
38
+ @duration = nil
41
39
  end
42
40
  end
43
41
  end
@@ -22,11 +22,11 @@ module Caliper
22
22
  module Entities
23
23
  module Response
24
24
  module ResponseType
25
- FILLINBLANK = "http://purl.imsglobal.org/caliper/v1/Response/FillinBlank"
26
- MULTIPLECHOICE = "http://purl.imsglobal.org/caliper/v1/Response/MultipleChoice"
27
- MULTIPLERESPONSE = "http://purl.imsglobal.org/caliper/v1/Response/MultipleResponse"
28
- SELECTTEXT = "http://purl.imsglobal.org/caliper/v1/Response/SelectText"
29
- TRUEFALSE = "http://purl.imsglobal.org/caliper/v1/Response/TrueFalse"
25
+ FILLINBLANK = "http://purl.imsglobal.org/caliper/v1/FillinBlankResponse"
26
+ MULTIPLECHOICE = "http://purl.imsglobal.org/caliper/v1/MultipleChoiceResponse"
27
+ MULTIPLERESPONSE = "http://purl.imsglobal.org/caliper/v1/MultipleResponseResponse"
28
+ SELECTTEXT = "http://purl.imsglobal.org/caliper/v1/SelectTextResponse"
29
+ TRUEFALSE = "http://purl.imsglobal.org/caliper/v1/TrueFalseResponse"
30
30
  end
31
31
  end
32
32
  end
@@ -26,12 +26,12 @@ module Caliper
26
26
  module Entities
27
27
  module Response
28
28
  class SelectTextResponse < Response
29
- attr_accessor :type,
30
- :values
29
+
30
+ attr_accessor :values
31
31
 
32
32
  def initialize
33
33
  super
34
- @type = ResponseType::SELECTTEXT
34
+ @type = Caliper::Entities::Response::ResponseType::SELECTTEXT
35
35
  end
36
36
  end
37
37
  end
@@ -26,12 +26,11 @@ module Caliper
26
26
  module Entities
27
27
  module Response
28
28
  class TrueFalseResponse < Response
29
- attr_accessor :type,
30
- :values
29
+ attr_accessor :values
31
30
 
32
31
  def initialize
33
32
  super
34
- @type = ResponseType::TRUEFALSE
33
+ @type = Caliper::Entities::Response::ResponseType::TRUEFALSE
35
34
  end
36
35
  end
37
36
  end
@@ -15,7 +15,8 @@
15
15
  # You should have received a copy of the GNU Lesser General Public License along
16
16
  # with this program. If not, see http://www.gnu.org/licenses/.
17
17
 
18
- require_relative '../entity'
18
+ require_relative '../entity_base'
19
+ require_relative '../entity_type'
19
20
  require_relative '../generatable'
20
21
  require_relative '../targetable'
21
22
 
@@ -25,18 +26,18 @@ require_relative '../targetable'
25
26
  module Caliper
26
27
  module Entities
27
28
  module Session
28
- class Session < Entity
29
+ class Session < EntityBase
29
30
  include Caliper::Entities::Generatable,
30
31
  Caliper::Entities::Targetable
31
32
 
32
- attr_accessor :actor,
33
- :startedAtTime,
34
- :endedAtTime,
35
- :duration
33
+ attr_accessor :actor, :startedAtTime, :endedAtTime, :duration
36
34
 
37
35
  def initialize
38
36
  super
39
- @type = EntityType::SESSION
37
+ @type = Caliper::Entities::EntityType::SESSION
38
+ @startedAtTime = nil
39
+ @endedAtTime = nil
40
+ @duration = nil
40
41
  end
41
42
  end
42
43
  end
@@ -16,18 +16,26 @@
16
16
  # with this program. If not, see http://www.gnu.org/licenses/.
17
17
 
18
18
  require_relative './event'
19
+ require_relative './event_context'
20
+ require_relative './event_type'
19
21
 
20
22
  #
21
23
  # Annotation Event per Caliper Annotation Profile.
22
24
  #
23
25
  module Caliper
24
- module Event
26
+ module Events
25
27
  class AnnotationEvent < Event
28
+ include Caliper::Events::EventContext
26
29
 
27
30
  def initialize
28
31
  super
29
- @context = Caliper::Event::EventContext::ANNOTATION
30
- @type = Caliper::Event::EventType::ANNOTATION
32
+ @type = Caliper::Events::EventType::ANNOTATION
33
+ @target = nil
34
+ @generated = nil
35
+ @edApp = nil
36
+ @group = nil
37
+ @membership = nil
38
+ @federatedSession = nil
31
39
  end
32
40
  end
33
41
  end
@@ -16,23 +16,26 @@
16
16
  # with this program. If not, see http://www.gnu.org/licenses/.
17
17
 
18
18
  require_relative './event'
19
+ require_relative './event_context'
20
+ require_relative './event_type'
19
21
 
20
22
  #
21
23
  # Assessment Event.
22
24
  #
23
25
  module Caliper
24
- module Event
26
+ module Events
25
27
  class AssessmentEvent < Event
26
- attr_accessor :context,
27
- :type,
28
- :action,
29
- :object,
30
- :target
28
+ include Caliper::Events::EventContext
31
29
 
32
30
  def initialize
33
31
  super
34
- @context = EventContext::ASSESSMENT
35
- @type = EventType::ASSESSMENT
32
+ @type = Caliper::Events::EventType::ASSESSMENT
33
+ @target = nil
34
+ @generated = nil
35
+ @edApp = nil
36
+ @group = nil
37
+ @membership = nil
38
+ @federatedSession = nil
36
39
  end
37
40
  end
38
41
  end
@@ -16,23 +16,26 @@
16
16
  # with this program. If not, see http://www.gnu.org/licenses/.
17
17
 
18
18
  require_relative './event'
19
+ require_relative './event_context'
20
+ require_relative './event_type'
19
21
 
20
22
  #
21
23
  # AssessmentItem Event.
22
24
  #
23
25
  module Caliper
24
- module Event
26
+ module Events
25
27
  class AssessmentItemEvent < Event
26
- attr_accessor :context,
27
- :type,
28
- :action,
29
- :object,
30
- :target
28
+ include Caliper::Events::EventContext
31
29
 
32
30
  def initialize
33
31
  super
34
- @context = EventContext::ASSESSMENT_ITEM
35
- @type = EventType::ASSESSMENT_ITEM
32
+ @type = Caliper::Events::EventType::ASSESSMENT_ITEM
33
+ @target = nil
34
+ @generated = nil
35
+ @edApp = nil
36
+ @group = nil
37
+ @membership = nil
38
+ @federatedSession = nil
36
39
  end
37
40
  end
38
41
  end
@@ -16,23 +16,26 @@
16
16
  # with this program. If not, see http://www.gnu.org/licenses/.
17
17
 
18
18
  require_relative './event'
19
+ require_relative './event_context'
20
+ require_relative './event_type'
19
21
 
20
22
  #
21
23
  # Assignable Event.
22
24
  #
23
25
  module Caliper
24
- module Event
26
+ module Events
25
27
  class AssignableEvent < Event
26
- attr_accessor :context,
27
- :type,
28
- :action,
29
- :object,
30
- :target
28
+ include Caliper::Events::EventContext
31
29
 
32
30
  def initialize
33
31
  super
34
- @context = EventContext::ASSIGNABLE
35
- @type = EventType::ASSIGNABLE
32
+ @type = Caliper::Events::EventType::ASSIGNABLE
33
+ @target = nil
34
+ @generated = nil
35
+ @edApp = nil
36
+ @group = nil
37
+ @membership = nil
38
+ @federatedSession = nil
36
39
  end
37
40
  end
38
41
  end
@@ -15,28 +15,28 @@
15
15
  # You should have received a copy of the GNU Lesser General Public License along
16
16
  # with this program. If not, see http://www.gnu.org/licenses/.
17
17
 
18
- require 'i18n'
18
+ require 'json'
19
+ require_relative './event_type'
20
+ require_relative './jsonable'
19
21
 
20
22
  #
21
- # Base Profile.
23
+ # Base event.
22
24
  #
23
25
  module Caliper
24
- module Profiles
25
- module ProfileActions
26
- NAVIGATED_TO = "http://purl.imsglobal.org/vocab/caliper/v1/action#NavigatedTo"
27
- end
26
+ module Events
27
+ class Event
28
+ include Caliper::Events::Jsonable
28
29
 
29
- class Profile
30
- include ProfileActions
30
+ attr_accessor :context, :type, :actor, :action, :object, :eventTime
31
31
 
32
32
  def initialize()
33
- end
34
-
35
- def get_navigated_to_action_from_bundle(key)
36
- if key.equal? ProfileActions::NAVIGATED_TO
37
- return I18n.translate :action
38
- end
33
+ @context = Caliper::Context::Context::CONTEXT
34
+ @type = Caliper::Events::EventType::EVENT
35
+ @actor = nil
36
+ @action = nil
37
+ @object = nil
38
+ @eventTime = nil
39
39
  end
40
40
  end
41
41
  end
42
- end
42
+ end