ddr-models 3.0.0.beta.3 → 3.0.0.beta.4

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -3
  3. data/config/locales/ddr-models.en.yml +74 -0
  4. data/ddr-models.gemspec +3 -2
  5. data/lib/ddr/auth.rb +5 -2
  6. data/lib/ddr/auth/roles.rb +0 -2
  7. data/lib/ddr/auth/roles/role_set.rb +1 -0
  8. data/lib/ddr/derivatives/generators/png_generator.rb +1 -1
  9. data/lib/ddr/index.rb +6 -2
  10. data/lib/ddr/index/abstract_query_result.rb +1 -1
  11. data/lib/ddr/index/csv_options.rb +14 -0
  12. data/lib/ddr/index/csv_query_result.rb +39 -32
  13. data/lib/ddr/index/field.rb +11 -1
  14. data/lib/ddr/index/field_attribute.rb +22 -0
  15. data/lib/ddr/index/fields.rb +29 -20
  16. data/lib/ddr/index/filter.rb +81 -30
  17. data/lib/ddr/index/filters.rb +15 -10
  18. data/lib/ddr/index/query.rb +34 -13
  19. data/lib/ddr/index/query_builder.rb +150 -30
  20. data/lib/ddr/index/query_clause.rb +64 -19
  21. data/lib/ddr/index/query_params.rb +40 -0
  22. data/lib/ddr/index/solr_csv_options.rb +18 -0
  23. data/lib/ddr/index/sort_order.rb +28 -0
  24. data/lib/ddr/jobs.rb +5 -1
  25. data/lib/ddr/jobs/fits_file_characterization.rb +3 -41
  26. data/lib/ddr/jobs/fixity_check.rb +13 -0
  27. data/lib/ddr/jobs/job.rb +36 -0
  28. data/lib/ddr/jobs/queue.rb +27 -0
  29. data/lib/ddr/jobs/update_index.rb +13 -0
  30. data/lib/ddr/models.rb +20 -3
  31. data/lib/ddr/models/admin_set.rb +7 -3
  32. data/lib/ddr/models/contact.rb +19 -0
  33. data/lib/ddr/models/error.rb +3 -0
  34. data/lib/ddr/models/file_characterization.rb +37 -0
  35. data/lib/ddr/models/finding_aid.rb +35 -2
  36. data/lib/ddr/models/has_admin_metadata.rb +5 -1
  37. data/lib/ddr/models/has_content.rb +4 -2
  38. data/lib/ddr/models/indexing.rb +7 -0
  39. data/lib/ddr/models/licenses/license.rb +7 -3
  40. data/lib/ddr/models/solr_document.rb +2 -2
  41. data/lib/ddr/models/version.rb +1 -1
  42. data/lib/ddr/models/with_content_file.rb +37 -0
  43. data/lib/ddr/vocab/asset.rb +3 -0
  44. data/spec/derivatives/png_generator_spec.rb +8 -1
  45. data/spec/fixtures/arrow1rightred_e0.gif +0 -0
  46. data/spec/index/fields_spec.rb +197 -0
  47. data/spec/index/filter_spec.rb +155 -30
  48. data/spec/index/query_builder_spec.rb +116 -0
  49. data/spec/index/query_clause_spec.rb +58 -0
  50. data/spec/index/query_spec.rb +39 -10
  51. data/spec/jobs/fits_file_characterization_spec.rb +7 -43
  52. data/spec/jobs/fixity_check_spec.rb +22 -0
  53. data/spec/jobs/job_spec.rb +40 -0
  54. data/spec/jobs/update_index_spec.rb +22 -0
  55. data/spec/managers/derivatives_manager_spec.rb +15 -11
  56. data/spec/models/admin_set_spec.rb +28 -10
  57. data/spec/models/contact_spec.rb +42 -0
  58. data/spec/models/effective_license_spec.rb +17 -7
  59. data/spec/models/file_characterization_spec.rb +38 -0
  60. data/spec/models/finding_aid_spec.rb +31 -8
  61. data/spec/models/has_admin_metadata_spec.rb +8 -5
  62. data/spec/models/indexing_spec.rb +2 -0
  63. data/spec/models/license_spec.rb +31 -10
  64. data/spec/models/solr_document_spec.rb +23 -3
  65. data/spec/models/with_content_file_spec.rb +32 -0
  66. data/spec/spec_helper.rb +2 -0
  67. metadata +66 -28
  68. data/lib/ddr/contacts.rb +0 -25
  69. data/lib/ddr/index/query_value.rb +0 -18
  70. data/lib/ddr/models/access_controllable.rb +0 -12
  71. data/spec/auth/ldap_gateway_spec.rb +0 -9
  72. data/spec/contacts/contacts_spec.rb +0 -26
  73. data/spec/index/filters_spec.rb +0 -17
@@ -128,9 +128,12 @@ RSpec.describe SolrDocument, type: :model, contacts: true do
128
128
 
129
129
  describe "contacts" do
130
130
  before do
131
- allow(YAML).to receive(:load_file) { { 'xa' => { 'name' => 'Contact A', 'short_name' => 'A' },
132
- 'yb' => { 'name' => 'Contact B', 'short_name' => 'B' } } }
133
- Ddr::Contacts.load_contacts
131
+ allow(Ddr::Models::Contact).to receive(:get).with(:find, slug: 'xa') do
132
+ {'id'=>1, 'slug'=>'xa', 'name'=>'Contact A', 'short_name'=>'A'}
133
+ end
134
+ allow(Ddr::Models::Contact).to receive(:get).with(:find, slug: 'yb') do
135
+ {'id'=>1, 'slug'=>'yb', 'name'=>'Contact B', 'short_name'=>'B'}
136
+ end
134
137
  end
135
138
  describe "#research_help" do
136
139
  context "object has research help contact" do
@@ -192,4 +195,21 @@ RSpec.describe SolrDocument, type: :model, contacts: true do
192
195
  end
193
196
  end
194
197
  end
198
+
199
+ describe "#has_datastream?" do
200
+ before do
201
+ allow(subject).to receive(:attached_files) { {"thumbnail"=>{"size"=>nil}, "content"=>{"size"=>987654} }}
202
+ end
203
+ context "when there is no content for the datastream" do
204
+ it "should return false" do
205
+ expect(subject.has_datastream?("thumbnail")).to be false
206
+ end
207
+ end
208
+ context "when there is content for the datastream" do
209
+ it "should return true" do
210
+ expect(subject.has_datastream?("content")).to be true
211
+ end
212
+ end
213
+ end
214
+
195
215
  end
@@ -0,0 +1,32 @@
1
+ module Ddr::Models
2
+ RSpec.describe WithContentFile do
3
+
4
+ let(:obj) { FactoryGirl.create(:component) }
5
+
6
+ it "yields a temp file path to the block and deletes the temp file afterwards" do
7
+ WithContentFile.new(obj) do |path|
8
+ @path = path
9
+ expect(File.exist?(path)).to be true
10
+ end
11
+ expect(File.exist?(@path)).to be false
12
+ end
13
+
14
+ it "deletes the temp file even when an exception is raised in the block" do
15
+ begin
16
+ WithContentFile.new(obj) do |path|
17
+ @path = path
18
+ expect(File.exist?(path)).to be true
19
+ raise Error, "error"
20
+ end
21
+ rescue Error
22
+ expect(File.exist?(@path)).to be false
23
+ end
24
+ end
25
+
26
+ it "raises an exception when the checksum verification fails" do
27
+ allow(obj.content).to receive(:checksum) { double(value: "foo", algorithm: "SHA1") }
28
+ expect { WithContentFile.new(obj) { |p| nil } }.to raise_error(ChecksumInvalid)
29
+ end
30
+
31
+ end
32
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  ENV['RAILS_ENV'] ||= "test"
2
2
 
3
+ ENV['DDR_AUX_API_URL'] ||= "http://localhost:3000/api"
4
+
3
5
  require File.expand_path("../dummy/config/environment.rb", __FILE__)
4
6
 
5
7
  require "ddr-models"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ddr-models
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.beta.3
4
+ version: 3.0.0.beta.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Coble
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-12-18 00:00:00.000000000 Z
12
+ date: 2016-01-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -25,6 +25,20 @@ dependencies:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
27
  version: 4.1.13
28
+ - !ruby/object:Gem::Dependency
29
+ name: activeresource
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
28
42
  - !ruby/object:Gem::Dependency
29
43
  name: active-triples
30
44
  requirement: !ruby/object:Gem::Requirement
@@ -186,67 +200,67 @@ dependencies:
186
200
  - !ruby/object:Gem::Version
187
201
  version: '1.12'
188
202
  - !ruby/object:Gem::Dependency
189
- name: ddr-aux-client
203
+ name: ddr-antivirus
190
204
  requirement: !ruby/object:Gem::Requirement
191
205
  requirements:
192
206
  - - "~>"
193
207
  - !ruby/object:Gem::Version
194
- version: '1.2'
195
- - - ">="
196
- - !ruby/object:Gem::Version
197
- version: 1.2.2
208
+ version: 2.1.1
198
209
  type: :runtime
199
210
  prerelease: false
200
211
  version_requirements: !ruby/object:Gem::Requirement
201
212
  requirements:
202
213
  - - "~>"
203
214
  - !ruby/object:Gem::Version
204
- version: '1.2'
205
- - - ">="
206
- - !ruby/object:Gem::Version
207
- version: 1.2.2
215
+ version: 2.1.1
208
216
  - !ruby/object:Gem::Dependency
209
- name: ddr-antivirus
217
+ name: virtus
210
218
  requirement: !ruby/object:Gem::Requirement
211
219
  requirements:
212
220
  - - "~>"
213
221
  - !ruby/object:Gem::Version
214
- version: 2.1.1
222
+ version: 1.0.5
215
223
  type: :runtime
216
224
  prerelease: false
217
225
  version_requirements: !ruby/object:Gem::Requirement
218
226
  requirements:
219
227
  - - "~>"
220
228
  - !ruby/object:Gem::Version
221
- version: 2.1.1
229
+ version: 1.0.5
222
230
  - !ruby/object:Gem::Dependency
223
- name: virtus
231
+ name: hashie
224
232
  requirement: !ruby/object:Gem::Requirement
225
233
  requirements:
226
234
  - - "~>"
227
235
  - !ruby/object:Gem::Version
228
- version: 1.0.5
236
+ version: 3.4.3
229
237
  type: :runtime
230
238
  prerelease: false
231
239
  version_requirements: !ruby/object:Gem::Requirement
232
240
  requirements:
233
241
  - - "~>"
234
242
  - !ruby/object:Gem::Version
235
- version: 1.0.5
243
+ version: 3.4.3
236
244
  - !ruby/object:Gem::Dependency
237
245
  name: bundler
238
246
  requirement: !ruby/object:Gem::Requirement
239
247
  requirements:
240
248
  - - "~>"
241
249
  - !ruby/object:Gem::Version
242
- version: '1.10'
250
+ version: '1.11'
251
+ - - ">="
252
+ - !ruby/object:Gem::Version
253
+ version: 1.11.2
243
254
  type: :development
244
255
  prerelease: false
245
256
  version_requirements: !ruby/object:Gem::Requirement
246
257
  requirements:
247
258
  - - "~>"
248
259
  - !ruby/object:Gem::Version
249
- version: '1.10'
260
+ version: '1.11'
261
+ - - ">="
262
+ - !ruby/object:Gem::Version
263
+ version: 1.11.2
250
264
  - !ruby/object:Gem::Dependency
251
265
  name: rake
252
266
  requirement: !ruby/object:Gem::Requirement
@@ -389,6 +403,7 @@ files:
389
403
  - config/initializers/active_fedora_file.rb
390
404
  - config/initializers/devise.rb
391
405
  - config/initializers/subscriptions.rb
406
+ - config/locales/ddr-models.en.yml
392
407
  - config/routes.rb
393
408
  - db/migrate/20141021233359_create_events.rb
394
409
  - db/migrate/20141021234156_create_minted_ids.rb
@@ -452,7 +467,6 @@ files:
452
467
  - lib/ddr/auth/test_helpers.rb
453
468
  - lib/ddr/auth/user.rb
454
469
  - lib/ddr/auth/web_auth_context.rb
455
- - lib/ddr/contacts.rb
456
470
  - lib/ddr/datastreams.rb
457
471
  - lib/ddr/datastreams/datastream_behavior.rb
458
472
  - lib/ddr/datastreams/descriptive_metadata_datastream.rb
@@ -481,22 +495,30 @@ files:
481
495
  - lib/ddr/index.rb
482
496
  - lib/ddr/index/abstract_query_result.rb
483
497
  - lib/ddr/index/connection.rb
498
+ - lib/ddr/index/csv_options.rb
484
499
  - lib/ddr/index/csv_query_result.rb
485
500
  - lib/ddr/index/document_builder.rb
486
501
  - lib/ddr/index/field.rb
502
+ - lib/ddr/index/field_attribute.rb
487
503
  - lib/ddr/index/fields.rb
488
504
  - lib/ddr/index/filter.rb
489
505
  - lib/ddr/index/filters.rb
490
506
  - lib/ddr/index/query.rb
491
507
  - lib/ddr/index/query_builder.rb
492
508
  - lib/ddr/index/query_clause.rb
509
+ - lib/ddr/index/query_params.rb
493
510
  - lib/ddr/index/query_result.rb
494
- - lib/ddr/index/query_value.rb
495
511
  - lib/ddr/index/response.rb
512
+ - lib/ddr/index/solr_csv_options.rb
513
+ - lib/ddr/index/sort_order.rb
496
514
  - lib/ddr/index/unique_key_field.rb
497
515
  - lib/ddr/jobs.rb
498
516
  - lib/ddr/jobs/fits_file_characterization.rb
517
+ - lib/ddr/jobs/fixity_check.rb
518
+ - lib/ddr/jobs/job.rb
499
519
  - lib/ddr/jobs/permanent_id.rb
520
+ - lib/ddr/jobs/queue.rb
521
+ - lib/ddr/jobs/update_index.rb
500
522
  - lib/ddr/managers.rb
501
523
  - lib/ddr/managers/derivatives_manager.rb
502
524
  - lib/ddr/managers/manager.rb
@@ -506,14 +528,15 @@ files:
506
528
  - lib/ddr/metadata.rb
507
529
  - lib/ddr/metadata/premis_event.rb
508
530
  - lib/ddr/models.rb
509
- - lib/ddr/models/access_controllable.rb
510
531
  - lib/ddr/models/admin_set.rb
511
532
  - lib/ddr/models/attached_file_profile.rb
512
533
  - lib/ddr/models/attached_files_profile.rb
513
534
  - lib/ddr/models/base.rb
535
+ - lib/ddr/models/contact.rb
514
536
  - lib/ddr/models/engine.rb
515
537
  - lib/ddr/models/error.rb
516
538
  - lib/ddr/models/event_loggable.rb
539
+ - lib/ddr/models/file_characterization.rb
517
540
  - lib/ddr/models/file_management.rb
518
541
  - lib/ddr/models/finding_aid.rb
519
542
  - lib/ddr/models/fixity_checkable.rb
@@ -547,6 +570,7 @@ files:
547
570
  - lib/ddr/models/validatable.rb
548
571
  - lib/ddr/models/validator.rb
549
572
  - lib/ddr/models/version.rb
573
+ - lib/ddr/models/with_content_file.rb
550
574
  - lib/ddr/models/year_facet.rb
551
575
  - lib/ddr/notifications.rb
552
576
  - lib/ddr/utils.rb
@@ -568,7 +592,6 @@ files:
568
592
  - spec/auth/effective_roles_spec.rb
569
593
  - spec/auth/group_spec.rb
570
594
  - spec/auth/groups_spec.rb
571
- - spec/auth/ldap_gateway_spec.rb
572
595
  - spec/auth/roles/role_set_manager_spec.rb
573
596
  - spec/auth/roles/role_set_query_spec.rb
574
597
  - spec/auth/roles/role_set_spec.rb
@@ -577,7 +600,6 @@ files:
577
600
  - spec/auth/superuser_ability_spec.rb
578
601
  - spec/auth/user_spec.rb
579
602
  - spec/auth/web_auth_context_spec.rb
580
- - spec/contacts/contacts_spec.rb
581
603
  - spec/controllers/application_controller_spec.rb
582
604
  - spec/controllers/users/sessions_controller_spec.rb
583
605
  - spec/datastreams/fits_datastream_spec.rb
@@ -643,6 +665,7 @@ files:
643
665
  - spec/factories/user_factories.rb
644
666
  - spec/fixtures/16bit.tif
645
667
  - spec/fixtures/8bit.tif
668
+ - spec/fixtures/arrow1rightred_e0.gif
646
669
  - spec/fixtures/bird.jpg
647
670
  - spec/fixtures/fits/document.xml
648
671
  - spec/fixtures/fits/image.xml
@@ -653,10 +676,15 @@ files:
653
676
  - spec/fixtures/sample.pdf
654
677
  - spec/fixtures/target.png
655
678
  - spec/helpers/models_helper_spec.rb
679
+ - spec/index/fields_spec.rb
656
680
  - spec/index/filter_spec.rb
657
- - spec/index/filters_spec.rb
681
+ - spec/index/query_builder_spec.rb
682
+ - spec/index/query_clause_spec.rb
658
683
  - spec/index/query_spec.rb
659
684
  - spec/jobs/fits_file_characterization_spec.rb
685
+ - spec/jobs/fixity_check_spec.rb
686
+ - spec/jobs/job_spec.rb
687
+ - spec/jobs/update_index_spec.rb
660
688
  - spec/managers/derivatives_manager_spec.rb
661
689
  - spec/managers/technical_metadata_manager_spec.rb
662
690
  - spec/models/active_fedora_base_spec.rb
@@ -665,9 +693,11 @@ files:
665
693
  - spec/models/attachment_spec.rb
666
694
  - spec/models/collection_spec.rb
667
695
  - spec/models/component_spec.rb
696
+ - spec/models/contact_spec.rb
668
697
  - spec/models/descriptive_metadata_spec.rb
669
698
  - spec/models/effective_license_spec.rb
670
699
  - spec/models/events_spec.rb
700
+ - spec/models/file_characterization_spec.rb
671
701
  - spec/models/file_management_spec.rb
672
702
  - spec/models/finding_aid_spec.rb
673
703
  - spec/models/has_admin_metadata_spec.rb
@@ -681,6 +711,7 @@ files:
681
711
  - spec/models/struct_div_spec.rb
682
712
  - spec/models/structure_spec.rb
683
713
  - spec/models/target_spec.rb
714
+ - spec/models/with_content_file_spec.rb
684
715
  - spec/models/year_facet_spec.rb
685
716
  - spec/routing/user_routing_spec.rb
686
717
  - spec/spec_helper.rb
@@ -732,7 +763,6 @@ test_files:
732
763
  - spec/auth/effective_roles_spec.rb
733
764
  - spec/auth/group_spec.rb
734
765
  - spec/auth/groups_spec.rb
735
- - spec/auth/ldap_gateway_spec.rb
736
766
  - spec/auth/roles/role_set_manager_spec.rb
737
767
  - spec/auth/roles/role_set_query_spec.rb
738
768
  - spec/auth/roles/role_set_spec.rb
@@ -741,7 +771,6 @@ test_files:
741
771
  - spec/auth/superuser_ability_spec.rb
742
772
  - spec/auth/user_spec.rb
743
773
  - spec/auth/web_auth_context_spec.rb
744
- - spec/contacts/contacts_spec.rb
745
774
  - spec/controllers/application_controller_spec.rb
746
775
  - spec/controllers/users/sessions_controller_spec.rb
747
776
  - spec/datastreams/fits_datastream_spec.rb
@@ -807,6 +836,7 @@ test_files:
807
836
  - spec/factories/user_factories.rb
808
837
  - spec/fixtures/16bit.tif
809
838
  - spec/fixtures/8bit.tif
839
+ - spec/fixtures/arrow1rightred_e0.gif
810
840
  - spec/fixtures/bird.jpg
811
841
  - spec/fixtures/fits/document.xml
812
842
  - spec/fixtures/fits/image.xml
@@ -817,10 +847,15 @@ test_files:
817
847
  - spec/fixtures/sample.pdf
818
848
  - spec/fixtures/target.png
819
849
  - spec/helpers/models_helper_spec.rb
850
+ - spec/index/fields_spec.rb
820
851
  - spec/index/filter_spec.rb
821
- - spec/index/filters_spec.rb
852
+ - spec/index/query_builder_spec.rb
853
+ - spec/index/query_clause_spec.rb
822
854
  - spec/index/query_spec.rb
823
855
  - spec/jobs/fits_file_characterization_spec.rb
856
+ - spec/jobs/fixity_check_spec.rb
857
+ - spec/jobs/job_spec.rb
858
+ - spec/jobs/update_index_spec.rb
824
859
  - spec/managers/derivatives_manager_spec.rb
825
860
  - spec/managers/technical_metadata_manager_spec.rb
826
861
  - spec/models/active_fedora_base_spec.rb
@@ -829,9 +864,11 @@ test_files:
829
864
  - spec/models/attachment_spec.rb
830
865
  - spec/models/collection_spec.rb
831
866
  - spec/models/component_spec.rb
867
+ - spec/models/contact_spec.rb
832
868
  - spec/models/descriptive_metadata_spec.rb
833
869
  - spec/models/effective_license_spec.rb
834
870
  - spec/models/events_spec.rb
871
+ - spec/models/file_characterization_spec.rb
835
872
  - spec/models/file_management_spec.rb
836
873
  - spec/models/finding_aid_spec.rb
837
874
  - spec/models/has_admin_metadata_spec.rb
@@ -845,6 +882,7 @@ test_files:
845
882
  - spec/models/struct_div_spec.rb
846
883
  - spec/models/structure_spec.rb
847
884
  - spec/models/target_spec.rb
885
+ - spec/models/with_content_file_spec.rb
848
886
  - spec/models/year_facet_spec.rb
849
887
  - spec/routing/user_routing_spec.rb
850
888
  - spec/spec_helper.rb
data/lib/ddr/contacts.rb DELETED
@@ -1,25 +0,0 @@
1
- module Ddr
2
- module Contacts
3
- extend ActiveSupport::Autoload
4
-
5
- class << self
6
- attr_accessor :contacts
7
- end
8
-
9
- def self.get(contact_slug)
10
- load_contacts unless contacts
11
- contacts[contact_slug]
12
- end
13
-
14
- def self.load_contacts
15
- self.contacts = OpenStruct.new
16
- contacts_file = File.join(Rails.root, 'config', 'contacts.yml')
17
- YAML.load_file(contacts_file).each do |key, value|
18
- contacts[key] = OpenStruct.new(value.merge('slug' => key))
19
- end
20
- rescue SystemCallError
21
- Rails.logger.warn("Unable to load Contacts file: #{contacts_file}")
22
- end
23
-
24
- end
25
- end
@@ -1,18 +0,0 @@
1
- require "rsolr"
2
-
3
- module Ddr::Index
4
- class QueryValue
5
-
6
- class << self
7
- def build(value)
8
- RSolr.solr_escape(value)
9
- end
10
-
11
- def or_values(*values)
12
- value = values.map { |v| build(v) }.join(" OR ")
13
- "(#{value})"
14
- end
15
- end
16
-
17
- end
18
- end
@@ -1,12 +0,0 @@
1
- module Ddr
2
- module Models
3
- module AccessControllable
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- include Hydra::AccessControls::Permissions
8
- end
9
-
10
- end
11
- end
12
- end