cocina-models 0.84.4 → 0.85.0

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
  SHA256:
3
- metadata.gz: ec3a00a348ca9a851ee3455b7b0208628ca9590556ad76b0f536c4da3e1b6079
4
- data.tar.gz: 156105d8055745c353db2690e2c39b72a043243272fddc72fb80e5e9a42b81c4
3
+ metadata.gz: f3e8bdc15327c32a4d90a32780285048b947d799816e30ce9c47feb328f7deaf
4
+ data.tar.gz: d3a3b4e03410cad650555b2a085dd85e429029465d0ddf5e950a2c9231e27d73
5
5
  SHA512:
6
- metadata.gz: ff595ddde9a4729ed1e77239d78b7d1729798708bb44a407a6019d98943b50d8f14a3ad12fa06f17085294d499a32b82ece50f7ca6f23a30ce857bcd12a2de87
7
- data.tar.gz: 3bdb368b93e0ba0fc8f865cbb2888045589c2169af810f3380f18e2c8511fafea30fc088980a4503f6f0405a1b60daf575c1df07ac7463830058e9517827d97a
6
+ metadata.gz: 18af72ea7b0ff5ce24800694b2a29d519d975c05e99d6124660fce6a78f66f274513914ee7763ef05d60bb1beac194aa6d77db610879f829b827dfccf88ef0cd
7
+ data.tar.gz: cb1837cdb6f1b78640ef91c8efae91e0dbe9d872525bf87beb9a5b345e59fff3156f6c7d9fdb98e9e713964cfc98094ae373c897fffb2e4469faf6bde37e8a6b
data/.rubocop.yml CHANGED
@@ -6,8 +6,7 @@ require:
6
6
  - rubocop-rake
7
7
 
8
8
  AllCops:
9
- # dor-services-app is stuck at ruby 2 until we get off Fedora3
10
- TargetRubyVersion: 2.7
9
+ TargetRubyVersion: 3.0
11
10
 
12
11
  # ----- Layout ------
13
12
 
@@ -336,3 +335,10 @@ RSpec/Capybara/SpecificMatcher: # new in 2.12
336
335
  Enabled: false
337
336
  RSpec/Rails/HaveHttpStatus: # new in 2.12
338
337
  Enabled: false
338
+
339
+ RSpec/ClassCheck: # new in 2.13
340
+ Enabled: true
341
+ RSpec/NoExpectationExample: # new in 2.13
342
+ Enabled: true
343
+ RSpec/Capybara/SpecificFinders: # new in 2.13
344
+ Enabled: true
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cocina-models (0.84.4)
4
+ cocina-models (0.85.0)
5
5
  activesupport
6
6
  deprecation
7
7
  dry-struct (~> 1.0)
@@ -20,7 +20,7 @@ PATH
20
20
  GEM
21
21
  remote: https://rubygems.org/
22
22
  specs:
23
- activesupport (7.0.3.1)
23
+ activesupport (7.0.4)
24
24
  concurrent-ruby (~> 1.0, >= 1.0.2)
25
25
  i18n (>= 1.6, < 2)
26
26
  minitest (>= 5.1)
@@ -32,13 +32,13 @@ GEM
32
32
  json_schema (~> 0.14, >= 0.14.3)
33
33
  openapi_parser (>= 0.11.1, < 1.0)
34
34
  rack (>= 1.5)
35
- commonmarker (0.23.5)
35
+ commonmarker (0.23.6)
36
36
  concurrent-ruby (1.1.10)
37
37
  deprecation (1.1.0)
38
38
  activesupport
39
39
  diff-lcs (1.5.0)
40
40
  docile (1.4.0)
41
- dry-container (0.10.1)
41
+ dry-container (0.11.0)
42
42
  concurrent-ruby (~> 1.0)
43
43
  dry-core (0.8.1)
44
44
  concurrent-ruby (~> 1.0)
@@ -83,7 +83,7 @@ GEM
83
83
  patience_diff (1.2.0)
84
84
  optimist (~> 3.0)
85
85
  racc (1.6.0)
86
- rack (2.2.4)
86
+ rack (3.0.0)
87
87
  rainbow (3.1.1)
88
88
  rake (13.0.6)
89
89
  regexp_parser (2.5.0)
@@ -94,18 +94,18 @@ GEM
94
94
  rspec-mocks (~> 3.11.0)
95
95
  rspec-core (3.11.0)
96
96
  rspec-support (~> 3.11.0)
97
- rspec-expectations (3.11.0)
97
+ rspec-expectations (3.11.1)
98
98
  diff-lcs (>= 1.2.0, < 2.0)
99
99
  rspec-support (~> 3.11.0)
100
100
  rspec-mocks (3.11.1)
101
101
  diff-lcs (>= 1.2.0, < 2.0)
102
102
  rspec-support (~> 3.11.0)
103
- rspec-support (3.11.0)
103
+ rspec-support (3.11.1)
104
104
  rspec_junit_formatter (0.5.1)
105
105
  rspec-core (>= 2, < 4, != 2.12.0)
106
106
  rss (0.2.9)
107
107
  rexml
108
- rubocop (1.35.1)
108
+ rubocop (1.36.0)
109
109
  json (~> 2.3)
110
110
  parallel (~> 1.10)
111
111
  parser (>= 3.1.2.1)
@@ -119,8 +119,8 @@ GEM
119
119
  parser (>= 3.1.1.0)
120
120
  rubocop-rake (0.6.0)
121
121
  rubocop (~> 1.0)
122
- rubocop-rspec (2.12.1)
123
- rubocop (~> 1.31)
122
+ rubocop-rspec (2.13.2)
123
+ rubocop (~> 1.33)
124
124
  ruby-progressbar (1.11.0)
125
125
  simplecov (0.21.2)
126
126
  docile (~> 1.1)
@@ -135,7 +135,7 @@ GEM
135
135
  thor (1.2.1)
136
136
  tzinfo (2.0.5)
137
137
  concurrent-ruby (~> 1.0)
138
- unicode-display_width (2.2.0)
138
+ unicode-display_width (2.3.0)
139
139
  zeitwerk (2.6.0)
140
140
 
141
141
  PLATFORMS
data/README.md CHANGED
@@ -55,7 +55,8 @@ If there is a possibility that a model or validation change will conflict with s
55
55
 
56
56
  1. Create a cocina-models branch containing the proposed change and push to GitHub.
57
57
  2. On sdr-infra, check out `main`, update the `Gemfile` so that cocina-models references the branch, and `bundle install`.
58
- 3. Select the appropriate database.
58
+ 3. Select the appropriate environment vars below - they are set to values in puppet. (first 2 lines are the same; last two lines use different variables)
59
+
59
60
  For QA:
60
61
  ```
61
62
  export DATABASE_NAME="dor_services"
@@ -135,24 +136,34 @@ which pushes the gem to rubygems.org. Next write up the release notes: https://
135
136
 
136
137
  ### Step 2: Update client gems coupled to the models
137
138
 
138
- **NOTE**: You can skip this step if the new release is a patch-level bump only.
139
-
140
- Next, you should release versions of [sdr-client](https://github.com/sul-dlss/sdr-client) and [dor-services-client](https://github.com/sul-dlss/dor-services-client/) pinned to this version because applications such as [Argo](https://github.com/sul-dlss/argo) depend on both of these gems using the same models.
139
+ **NOTE**: You may skip this step if the new release is a patch-level bump only, as the client gems are pinned to a minor release of cocina-models. However, a PR to update Gemfile.lock with the new cocina-models version is welcome ... and not a blocker.
141
140
 
142
- ### Step 3: Update service API specifications and gems
141
+ If this is a minor or major cocina-models version change, release new versions of [sdr-client](https://github.com/sul-dlss/sdr-client) and [dor-services-client](https://github.com/sul-dlss/dor-services-client/) pinned to use the new cocina-models version because applications such as [Argo](https://github.com/sul-dlss/argo) depend on both of these gems using the same models.
143
142
 
144
- **NOTE**: You can skip this first half of the step if there have not been any changes to the `cocina-models` OpenAPI spec since the prior release.
143
+ ### Step 3: Update services directly coupled to the models
145
144
 
146
- The cocina-models gem is used in applications that have an API specification that accepts Cocina models. Next, make sure that the `openapi.yml` for these applications include the `openapi.yml` schema changes made in cocina-models. This list of services is known to include:
145
+ This list of services is known to include:
147
146
 
148
147
  * [sul-dlss/sdr-api](https://github.com/sul-dlss/sdr-api)
149
148
  * [sul-dlss/dor-services-app](https://github.com/sul-dlss/dor-services-app/)
150
149
 
151
- This can be accomplished by copying and pasting these schemas. By convention, these schemas are listed first in the `openapi.yml` of the associated projects, followed by the application-specific schemas.
150
+ **NOTE**: You can skip step 3A if there have not been any changes to the `cocina-models` OpenAPI spec since the prior release.
151
+
152
+ #### Step 3A: Update API specifications
153
+
154
+ The cocina-models gem is used in applications that have an API specification that accepts Cocina models. Make sure that the `openapi.yml` for these applications include the `openapi.yml` schema changes made in cocina-models.
155
+
156
+ This can be accomplished by copying and pasting the cocina-models schemas to the openapi.yml of the associated project. By convention, these schemas are listed first in the `openapi.yml` of the associated projects, followed by the application-specific schemas.
157
+
158
+ #### Step 3B: Bump gems and create the PRs
159
+
160
+ If step 3A was needed, use the same PRs to also bump the versions of cocina-models, sdr-client, and dor-services-client in these applications/services. Why? When [dor-services-app](https://github.com/sul-dlss/dor-services-app), for example, is updated to use the new models (via the auto-update script), these clients should be updated at the same time or there is risk of models produced by dor-services-app not being acceptable to the clients.
161
+
162
+ With or without step 3A, perform `bundle update` for cocina-models, sdr-client, and dor-services-client gems in the listed services and then make PRs for those repos.
152
163
 
153
- #### Step 3b: Bump gems
164
+ #### Step 3C: Merge 'em
154
165
 
155
- At the same, we have found it convenient to use these PRs to also bump the versions of cocina-models, sdr-client, and dor-services-client in these applications/services. Why? When [dor-services-app](https://github.com/sul-dlss/dor-services-app), for example, is updated to use the new models (via the auto-update script), these clients should be updated at the same time or there is risk of models produced by dor-services-app not being acceptable to the clients.
166
+ Get the directly coupled services PRs merged before the deploy in step 5.
156
167
 
157
168
  ### Step 4: Update other dependent applications
158
169
 
@@ -160,19 +171,19 @@ Once the above listed steps have been completed, all applications that use cocin
160
171
 
161
172
  There are scripts to help with updating other dependent applications:
162
173
 
163
- #### Step 4A: Create the PRs
174
+ #### Step 4A: Create the Cocina Level 2 PRs
164
175
 
165
176
  There is a Jenkins CI job that you can run manually to create all the PRs you need. Head to https://sul-ci-prod.stanford.edu/job/SUL-DLSS/job/access-update-scripts/job/cocina-level2-updates/ and then click `Build Now`. Click the new build that is created and then `Console Output` to watch the build. Once it has completed, you can proceed with the next step.
166
177
 
167
178
  If for some reason the above method does not work, the sul-dlss/access-update-scripts repo has a script for this: `cocina_level2_prs.rb`. You will need a github access token with scopes of "read:org" and "repo" (see https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) to run it, as noted in the comments at the top of that script.
168
179
 
169
- #### Step 4B: Merge the PRs
180
+ #### Step 4B: Merge the Cocina Level 2 PRs
170
181
 
171
182
  [sul-dlss/access-update-scripts](https://github.com/sul-dlss/access-update-scripts) has a switch in the `merge-all.rb` script for this, as noted in the comments at the top of that script. (`REPOS_PATH=infrastructure GH_ACCESS_TOKEN=abc123 COCINA_LEVEL2= ./merge-all.rb`)
172
183
 
173
184
  ### Step 5: Deploy all affected applications together
174
185
 
175
- [sul-dlss/sdr-deploy](https://github.com/sul-dlss/sdr-deploy) has a flag in the deploy script to limit deploys to cocina dependent applications. Refer to instructions in the [sdr-deploy/README](https://github.com/sul-dlss/sdr-deploy/blob/main/README.md#only-deploy-repos-related-to-cocina-models-update).
186
+ [sul-dlss/sdr-deploy](https://github.com/sul-dlss/sdr-deploy) has a flag (-c) in the deploy script to limit deploys to cocina dependent applications. Refer to instructions in the [sdr-deploy/README](https://github.com/sul-dlss/sdr-deploy/blob/main/README.md#only-deploy-repos-related-to-cocina-models-update).
176
187
 
177
188
  Note that running the integration tests is currently the best way we have to check for unintended effects and/or bugs when rolling out cocina-models changes.
178
189
 
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.bindir = 'exe'
23
23
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
24
  spec.require_paths = ['lib']
25
- spec.required_ruby_version = '>= 2.7'
25
+ spec.required_ruby_version = '>= 3.0'
26
26
 
27
27
  spec.add_dependency 'activesupport'
28
28
  spec.add_dependency 'deprecation'
@@ -14,7 +14,6 @@ module Cocina
14
14
  attribute :note, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
15
15
  # URL or other pointer to the location of the contributor information.
16
16
  attribute? :valueAt, Types::Strict::String
17
- attribute :parallelContributor, Types::Strict::Array.of(DescriptiveParallelContributor).default([].freeze)
18
17
  end
19
18
  end
20
19
  end
@@ -20,7 +20,7 @@ module Cocina
20
20
  attribute? :adminMetadata, DescriptiveAdminMetadata.optional
21
21
  # URL or other pointer to the location of the resource description.
22
22
  attribute? :valueAt, Types::Strict::String
23
- # Stanford persistent URL associated with the related resource. Note this is http, not https.
23
+ # Stanford persistent URL associated with the related resource.
24
24
  attribute :purl, Types::Strict::String
25
25
  end
26
26
  end
@@ -34,7 +34,7 @@ module Cocina
34
34
  values.concat(extent_values.flatten)
35
35
  values.concat(part_note_value_for(part_element, 'text'))
36
36
  values.concat(part_note_value_for(part_element, 'date'))
37
- values.reject!(&:blank?)
37
+ values.compact_blank!
38
38
 
39
39
  return if values.empty?
40
40
 
@@ -50,7 +50,7 @@ module Cocina
50
50
  values.concat(extent_values)
51
51
  values.concat(part_note_value_for(part_element, 'text'))
52
52
  values.concat(part_note_value_for(part_element, 'date'))
53
- values.reject!(&:blank?)
53
+ values.compact_blank!
54
54
 
55
55
  return if values.empty?
56
56
 
@@ -83,7 +83,7 @@ module Cocina
83
83
  detail_values.concat(part_note_value_for(detail_node, 'number'))
84
84
  detail_values.concat(part_note_value_for(detail_node, 'caption'))
85
85
  detail_values.concat(part_note_value_for(detail_node, 'title'))
86
- detail_values.reject!(&:blank?)
86
+ detail_values.compact_blank!
87
87
  if detail_values.present?
88
88
  detail_values.concat(part_note_value_for(detail_node, 'detail type',
89
89
  xpath: '@type'))
@@ -101,7 +101,7 @@ module Cocina
101
101
  extent_values = []
102
102
  extent_values.concat(part_note_value_for(extent_node, 'list'))
103
103
  extent_values << pages_for(extent_node)
104
- extent_values.reject!(&:blank?)
104
+ extent_values.compact_blank!
105
105
  if extent_values.present?
106
106
  extent_values.concat(part_note_value_for(extent_node, 'extent unit',
107
107
  xpath: '@unit'))
@@ -6,9 +6,9 @@ module Cocina
6
6
  module ToMods
7
7
  # Maps geo extension from cocina to MODS
8
8
  class Geographic # rubocop:disable Metrics/ClassLength
9
- TYPE_REGEX = /^type$/.freeze
10
- MEDIA_REGEX = /^media type$/.freeze
11
- DATA_FORMAT_REGEX = /^data format$/.freeze
9
+ TYPE_REGEX = /^type$/
10
+ MEDIA_REGEX = /^media type$/
11
+ DATA_FORMAT_REGEX = /^data format$/
12
12
 
13
13
  ABOUT_URI_PREFIX = 'http://purl.stanford.edu/'
14
14
 
@@ -12,7 +12,7 @@ module Cocina
12
12
  'genre' => :genre,
13
13
  'occupation' => :occupation
14
14
  }.freeze
15
- DEORDINAL_REGEX = /(?<=[0-9])(?:st|nd|rd|th)/.freeze
15
+ DEORDINAL_REGEX = /(?<=[0-9])(?:st|nd|rd|th)/
16
16
 
17
17
  # @params [Nokogiri::XML::Builder] xml
18
18
  # @params [Array<Cocina::Models::DescriptiveValue>] subjects
@@ -19,7 +19,7 @@ module Cocina
19
19
  attribute :identifier, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
20
20
  attribute? :standard, Standard.optional
21
21
  attribute :subject, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
22
- # Stanford persistent URL associated with the related resource. Note this is http, not https.
22
+ # Stanford persistent URL associated with the related resource.
23
23
  attribute? :purl, Types::Strict::String
24
24
  attribute? :access, DescriptiveAccessMetadata.optional
25
25
  attribute :relatedResource, Types::Strict::Array.of(RelatedResource).default([].freeze)
@@ -76,8 +76,7 @@ module Cocina
76
76
  #
77
77
  # So we catch the false positives from the upstream gem and allow
78
78
  # this pattern to validate
79
- /\AY-?\d{5,}\Z/.match?(value) ||
80
- /\A-?\d{1,3}\Z/.match?(value) # temporarily allow format violations
79
+ /\AY-?\d{5,}\Z/.match?(value)
81
80
  end
82
81
 
83
82
  def valid_iso8601?(value)
@@ -71,7 +71,7 @@ module Cocina
71
71
  # Some part of the path are ignored for the purpose of matching.
72
72
  def clean_path(path)
73
73
  new_path = path.reject do |part|
74
- part.is_a?(Integer) || %i[parallelValue parallelContributor parallelEvent].include?(part)
74
+ part.is_a?(Integer) || %i[parallelValue parallelEvent].include?(part)
75
75
  end
76
76
  # This needs to happen after parallelValue is removed
77
77
  # to handle structuredValue > parallelValue > structuredValue
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Cocina
4
4
  module Models
5
- VERSION = '0.84.4'
5
+ VERSION = '0.85.0'
6
6
  end
7
7
  end
data/openapi.yml CHANGED
@@ -549,11 +549,6 @@ components:
549
549
  valueAt:
550
550
  description: URL or other pointer to the location of the contributor information.
551
551
  type: string
552
- parallelContributor:
553
- description: For multiple representations of information about the same contributor (e.g. in different languages).
554
- type: array
555
- items:
556
- $ref: "#/components/schemas/DescriptiveParallelContributor"
557
552
  ControlledDigitalLendingAccess:
558
553
  type: object
559
554
  properties:
@@ -777,44 +772,6 @@ components:
777
772
  type: array
778
773
  items:
779
774
  $ref: "#/components/schemas/DescriptiveValue"
780
- DescriptiveParallelContributor:
781
- description: Value model for multiple representations of information about the same contributor (e.g. in different languages).
782
- deprecated: true
783
- type: object
784
- additionalProperties: false
785
- properties:
786
- name:
787
- description: Names associated with a contributor.
788
- type: array
789
- items:
790
- $ref: "#/components/schemas/DescriptiveValue"
791
- type:
792
- description: Entity type of the contributor (person, organization, etc.). See https://github.com/sul-dlss/cocina-models/blob/main/docs/description_types.md for valid types.
793
- type: string
794
- status:
795
- description: Status of the contributor relative to other parallel contributors (e.g. the primary author among a group of contributors).
796
- type: string
797
- role:
798
- description: Relationships of the contributor to the resource or to an event in its history.
799
- type: array
800
- items:
801
- $ref: "#/components/schemas/DescriptiveValue"
802
- identifier:
803
- description: Identifiers and URIs associated with the contributor entity.
804
- type: array
805
- items:
806
- $ref: "#/components/schemas/DescriptiveValue"
807
- note:
808
- description: Other information associated with the contributor.
809
- type: array
810
- items:
811
- $ref: "#/components/schemas/DescriptiveValue"
812
- valueAt:
813
- description: URL or other pointer to the location of the contributor information.
814
- type: string
815
- valueLanguage:
816
- # description: Language of the descriptive element value
817
- $ref: "#/components/schemas/DescriptiveValueLanguage"
818
775
  DescriptiveParallelEvent:
819
776
  description: Value model for multiple representations of information about the same event (e.g. in different languages).
820
777
  type: object
@@ -1459,7 +1416,7 @@ components:
1459
1416
  description: Width in pixels
1460
1417
  type: integer
1461
1418
  Purl:
1462
- description: Stanford persistent URL associated with the related resource. Note this is http, not https.
1419
+ description: Stanford persistent URL associated with the related resource.
1463
1420
  type: string
1464
1421
  format: uri
1465
1422
  # Canonical URI is https
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocina-models
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.84.4
4
+ version: 0.85.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-01 00:00:00.000000000 Z
11
+ date: 2022-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -392,7 +392,6 @@ files:
392
392
  - lib/cocina/models/descriptive_basic_value.rb
393
393
  - lib/cocina/models/descriptive_geographic_metadata.rb
394
394
  - lib/cocina/models/descriptive_grouped_value.rb
395
- - lib/cocina/models/descriptive_parallel_contributor.rb
396
395
  - lib/cocina/models/descriptive_parallel_event.rb
397
396
  - lib/cocina/models/descriptive_parallel_value.rb
398
397
  - lib/cocina/models/descriptive_structured_value.rb
@@ -531,14 +530,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
531
530
  requirements:
532
531
  - - ">="
533
532
  - !ruby/object:Gem::Version
534
- version: '2.7'
533
+ version: '3.0'
535
534
  required_rubygems_version: !ruby/object:Gem::Requirement
536
535
  requirements:
537
536
  - - ">="
538
537
  - !ruby/object:Gem::Version
539
538
  version: '0'
540
539
  requirements: []
541
- rubygems_version: 3.3.7
540
+ rubygems_version: 3.2.32
542
541
  signing_key:
543
542
  specification_version: 4
544
543
  summary: Data models for the SDR
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Cocina
4
- module Models
5
- # DEPRECATED
6
- # Value model for multiple representations of information about the same contributor (e.g. in different languages).
7
- class DescriptiveParallelContributor < Struct
8
- attribute :name, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
9
- # Entity type of the contributor (person, organization, etc.). See https://github.com/sul-dlss/cocina-models/blob/main/docs/description_types.md for valid types.
10
- attribute? :type, Types::Strict::String
11
- # Status of the contributor relative to other parallel contributors (e.g. the primary author among a group of contributors).
12
- attribute? :status, Types::Strict::String
13
- attribute :role, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
14
- attribute :identifier, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
15
- attribute :note, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
16
- # URL or other pointer to the location of the contributor information.
17
- attribute? :valueAt, Types::Strict::String
18
- attribute? :valueLanguage, DescriptiveValueLanguage.optional
19
- end
20
- end
21
- end