arclight 0.4.0 → 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintrc +11 -4
- data/.github/workflows/ruby.yml +24 -8
- data/.rspec +0 -1
- data/.rubocop.yml +289 -3
- data/.rubocop_todo.yml +64 -76
- data/CONTRIBUTING.md +5 -5
- data/Gemfile +15 -10
- data/README.md +18 -12
- data/app/assets/javascripts/arclight/arclight.js +3 -7
- data/app/assets/javascripts/arclight/oembed_viewer.js +64 -39
- data/app/assets/javascripts/arclight/truncate_controller.js +27 -0
- data/app/assets/stylesheets/arclight/application.scss +1 -5
- data/app/assets/stylesheets/arclight/modules/hierarchy_and_online_contents.scss +104 -130
- data/app/assets/stylesheets/arclight/modules/icons.scss +14 -3
- data/app/assets/stylesheets/arclight/modules/layout.scss +121 -100
- data/app/assets/stylesheets/arclight/modules/mastheads.scss +15 -57
- data/app/assets/stylesheets/arclight/modules/repositories.scss +2 -2
- data/app/assets/stylesheets/arclight/modules/repository_card.scss +4 -48
- data/app/assets/stylesheets/arclight/modules/search_results.scss +86 -35
- data/app/assets/stylesheets/arclight/modules/show_collection.scss +5 -32
- data/app/assets/stylesheets/arclight/modules/truncator.scss +56 -0
- data/app/assets/stylesheets/arclight/variables.scss +7 -4
- data/app/components/arclight/access_component.html.erb +14 -0
- data/app/components/arclight/access_component.rb +25 -0
- data/app/components/arclight/bookmark_component.html.erb +25 -0
- data/app/components/arclight/bookmark_component.rb +9 -0
- data/app/components/arclight/breadcrumb_component.rb +40 -0
- data/app/components/arclight/breadcrumbs_hierarchy_component.html.erb +34 -0
- data/app/components/arclight/breadcrumbs_hierarchy_component.rb +25 -0
- data/app/components/arclight/collection_context_component.html.erb +12 -0
- data/app/components/arclight/collection_context_component.rb +27 -0
- data/app/components/arclight/collection_info_component.html.erb +28 -0
- data/app/components/arclight/collection_info_component.rb +26 -0
- data/app/components/arclight/collection_sidebar_component.html.erb +15 -0
- data/app/components/arclight/collection_sidebar_component.rb +41 -0
- data/app/{views/catalog/_search_results_repository.html.erb → components/arclight/constraints_component.html.erb} +2 -1
- data/app/components/arclight/constraints_component.rb +17 -0
- data/app/components/arclight/document_collection_context_component.html.erb +29 -0
- data/app/components/arclight/document_collection_context_component.rb +28 -0
- data/app/components/arclight/document_collection_hierarchy_component.html.erb +46 -0
- data/app/components/arclight/document_collection_hierarchy_component.rb +62 -0
- data/app/components/arclight/document_component.html.erb +39 -0
- data/app/components/arclight/document_component.rb +49 -0
- data/app/components/arclight/document_components_hierarchy_component.html.erb +32 -0
- data/app/components/arclight/document_components_hierarchy_component.rb +28 -0
- data/app/components/arclight/document_download_component.html.erb +24 -0
- data/app/components/arclight/document_download_component.rb +71 -0
- data/app/components/arclight/embed_component.html.erb +10 -0
- data/app/components/arclight/embed_component.rb +43 -0
- data/app/components/arclight/group_component.html.erb +30 -0
- data/app/components/arclight/group_component.rb +23 -0
- data/app/components/arclight/header_component.html.erb +5 -0
- data/app/components/arclight/header_component.rb +10 -0
- data/app/components/arclight/index_metadata_field_component.html.erb +17 -0
- data/app/components/arclight/index_metadata_field_component.rb +20 -0
- data/app/components/arclight/masthead_component.html.erb +15 -0
- data/app/components/arclight/masthead_component.rb +10 -0
- data/app/components/arclight/metadata_section_component.html.erb +13 -0
- data/app/components/arclight/metadata_section_component.rb +22 -0
- data/app/components/arclight/oembed_viewer_component.html.erb +5 -0
- data/app/components/arclight/oembed_viewer_component.rb +16 -0
- data/app/components/arclight/online_content_filter_component.html.erb +15 -0
- data/app/components/arclight/online_content_filter_component.rb +19 -0
- data/app/components/arclight/online_status_indicator_component.rb +19 -0
- data/app/components/arclight/repository_breadcrumb_component.html.erb +10 -0
- data/app/components/arclight/repository_breadcrumb_component.rb +17 -0
- data/app/components/arclight/repository_location_component.html.erb +20 -0
- data/app/components/arclight/repository_location_component.rb +10 -0
- data/app/components/arclight/search_bar_component.html.erb +25 -0
- data/app/components/arclight/search_bar_component.rb +32 -0
- data/app/components/arclight/search_result_breadcrumbs_component.html.erb +3 -0
- data/app/components/arclight/search_result_breadcrumbs_component.rb +37 -0
- data/app/components/arclight/search_result_component.html.erb +20 -0
- data/app/components/arclight/search_result_component.rb +24 -0
- data/app/components/arclight/search_result_title_component.html.erb +13 -0
- data/app/components/arclight/search_result_title_component.rb +15 -0
- data/app/components/arclight/sidebar_component.html.erb +9 -0
- data/app/components/arclight/sidebar_component.rb +19 -0
- data/app/components/arclight/upper_metadata_layout_component.rb +10 -0
- data/app/components/blacklight/icons/bookmark_component.rb +12 -0
- data/app/components/blacklight/icons/collection_component.rb +14 -0
- data/app/components/blacklight/icons/compact_component.rb +12 -0
- data/app/components/blacklight/icons/container_component.rb +14 -0
- data/app/components/blacklight/icons/ead_component.rb +12 -0
- data/app/components/blacklight/icons/file_component.rb +14 -0
- data/app/components/blacklight/icons/folder_component.rb +12 -0
- data/app/components/blacklight/icons/online_component.rb +15 -0
- data/app/components/blacklight/icons/pdf_component.rb +12 -0
- data/app/components/blacklight/icons/repository_component.rb +12 -0
- data/app/controllers/arclight/repositories_controller.rb +4 -4
- data/app/{controllers/concerns → helpers}/arclight/ead_format_helpers.rb +4 -7
- data/app/helpers/arclight/field_config_helpers.rb +26 -0
- data/app/helpers/arclight_helper.rb +16 -254
- data/app/models/arclight/document_downloads.rb +12 -15
- data/app/models/arclight/parent.rb +5 -0
- data/app/models/arclight/parents.rb +2 -1
- data/app/models/arclight/requests/aeon_external_request.rb +1 -1
- data/app/models/arclight/requests/aeon_web_ead.rb +8 -3
- data/app/models/arclight/requests/google_form.rb +8 -3
- data/app/models/concerns/arclight/catalog.rb +25 -15
- data/app/models/concerns/arclight/search_behavior.rb +12 -26
- data/app/models/concerns/arclight/solr_document.rb +70 -73
- data/app/presenters/arclight/show_presenter.rb +34 -7
- data/app/views/arclight/_requests.html.erb +2 -2
- data/app/views/arclight/repositories/_repository.html.erb +21 -40
- data/app/views/arclight/repositories/index.html.erb +3 -1
- data/app/views/arclight/repositories/show.html.erb +4 -6
- data/app/views/arclight/requests/_aeon_external_request_endpoint.html.erb +4 -5
- data/app/views/arclight/requests/_aeon_web_ead.html.erb +3 -4
- data/app/views/arclight/requests/_google_form.html.erb +4 -6
- data/app/views/catalog/_group.html.erb +1 -18
- data/app/views/catalog/_group_toggle.html.erb +1 -1
- data/app/views/catalog/_search_results_header.html.erb +3 -0
- data/app/views/catalog/hierarchy.html.erb +19 -0
- data/app/views/catalog/index.html.erb +16 -7
- data/app/views/shared/_breadcrumbs.html.erb +2 -14
- data/app/views/shared/_main_menu_links.html.erb +1 -1
- data/arclight.gemspec +13 -11
- data/config/breadcrumbs.rb +24 -0
- data/config/i18n-tasks.yml +9 -8
- data/config/importmap.rb +3 -0
- data/config/locales/arclight.en.yml +31 -30
- data/config/routes.rb +1 -1
- data/docker-compose.yml +16 -0
- data/lib/arclight/digital_object.rb +2 -1
- data/lib/arclight/engine.rb +18 -37
- data/lib/arclight/exceptions.rb +1 -0
- data/lib/arclight/hash_absolute_xpath.rb +2 -1
- data/lib/arclight/normalized_id.rb +2 -0
- data/lib/arclight/normalized_title.rb +2 -0
- data/lib/arclight/repository.rb +45 -56
- data/lib/arclight/routes/hierarchy.rb +19 -0
- data/lib/arclight/routes.rb +8 -0
- data/lib/arclight/traject/ead2_component_config.rb +292 -0
- data/lib/arclight/traject/ead2_config.rb +66 -287
- data/lib/arclight/version.rb +1 -1
- data/lib/arclight/year_range.rb +4 -3
- data/lib/arclight.rb +6 -1
- data/lib/generators/arclight/install_generator.rb +59 -21
- data/lib/generators/arclight/templates/arclight.scss +4 -3
- data/lib/generators/arclight/templates/catalog_controller.rb +150 -165
- data/lib/generators/arclight/templates/config/locales/arclight.en.yml +53 -0
- data/lib/generators/arclight/templates/config/repositories.yml +20 -27
- data/lib/tasks/index.rake +14 -17
- data/package.json +11 -13
- data/solr/conf/schema.xml +42 -38
- data/solr/conf/solrconfig.xml +34 -31
- data/tasks/arclight.rake +8 -7
- data/template.rb +1 -2
- metadata +147 -120
- data/.babelrc +0 -3
- data/app/assets/javascripts/arclight/collection_navigation.js +0 -100
- data/app/assets/javascripts/arclight/collection_scrollspy.js +0 -6
- data/app/assets/javascripts/arclight/context_navigation.js +0 -351
- data/app/assets/javascripts/arclight/truncator.js.erb +0 -29
- data/app/assets/stylesheets/arclight/bootstrap_overrides.scss +0 -26
- data/app/assets/stylesheets/arclight/modules/context_navigation.scss +0 -75
- data/app/controllers/concerns/arclight/field_config_helpers.rb +0 -102
- data/app/factories/blacklight_field_configuration_factory.rb +0 -30
- data/app/views/arclight/repositories/_in_person_repository.html.erb +0 -19
- data/app/views/arclight/repositories/_repository_contact.html.erb +0 -9
- data/app/views/arclight/viewers/_oembed.html.erb +0 -8
- data/app/views/catalog/_access_contents.html.erb +0 -15
- data/app/views/catalog/_arclight_abstract_or_scope.html.erb +0 -5
- data/app/views/catalog/_arclight_bookmark_control.html.erb +0 -38
- data/app/views/catalog/_arclight_document_header_icon.html.erb +0 -1
- data/app/views/catalog/_arclight_document_index_header.html.erb +0 -13
- data/app/views/catalog/_arclight_document_index_header_hierarchy_default.html.erb +0 -0
- data/app/views/catalog/_arclight_document_index_header_online_contents_default.html.erb +0 -0
- data/app/views/catalog/_arclight_index_compact_default.html.erb +0 -22
- data/app/views/catalog/_arclight_index_default.html.erb +0 -45
- data/app/views/catalog/_arclight_index_group_document_compact_default.html.erb +0 -19
- data/app/views/catalog/_arclight_index_group_document_default.html.erb +0 -18
- data/app/views/catalog/_arclight_online_content_indicator.html.erb +0 -3
- data/app/views/catalog/_arclight_rangelimit.html.erb +0 -24
- data/app/views/catalog/_arclight_viewer_default.html.erb +0 -1
- data/app/views/catalog/_collection_contents.html.erb +0 -4
- data/app/views/catalog/_collection_context.html.erb +0 -15
- data/app/views/catalog/_collection_context_nav.html.erb +0 -12
- data/app/views/catalog/_collection_online_contents.html.erb +0 -17
- data/app/views/catalog/_component_context.html.erb +0 -5
- data/app/views/catalog/_containers.html.erb +0 -3
- data/app/views/catalog/_context_card.html.erb +0 -27
- data/app/views/catalog/_context_sidebar.html.erb +0 -8
- data/app/views/catalog/_custom_metadata.html.erb +0 -16
- data/app/views/catalog/_document_downloads.html.erb +0 -14
- data/app/views/catalog/_group_header_compact_default.html.erb +0 -15
- data/app/views/catalog/_group_header_default.html.erb +0 -20
- data/app/views/catalog/_home.html.erb +0 -1
- data/app/views/catalog/_index_breadcrumb_default.html.erb +0 -6
- data/app/views/catalog/_index_collection_context_default.html.erb +0 -53
- data/app/views/catalog/_index_default.html.erb +0 -17
- data/app/views/catalog/_index_header.html.erb +0 -7
- data/app/views/catalog/_index_header_online_contents_default.html.erb +0 -1
- data/app/views/catalog/_index_online_contents_default.html.erb +0 -6
- data/app/views/catalog/_online_content_label.html.erb +0 -5
- data/app/views/catalog/_search_form.html.erb +0 -34
- data/app/views/catalog/_search_results.html.erb +0 -28
- data/app/views/catalog/_show_actions_box_default.html.erb +0 -27
- data/app/views/catalog/_show_breadcrumbs_default.html.erb +0 -6
- data/app/views/catalog/_show_collection.html.erb +0 -66
- data/app/views/catalog/_show_default.html.erb +0 -70
- data/app/views/catalog/_show_upper_metadata_collection.html.erb +0 -1
- data/app/views/catalog/_show_upper_metadata_default.html.erb +0 -14
- data/app/views/catalog/_sort_and_per_page.html.erb +0 -8
- data/app/views/catalog/_within_collection_dropdown.html.erb +0 -26
- data/app/views/layouts/catalog_result.html.erb +0 -7
- data/app/views/shared/_context_sidebar.html.erb +0 -8
- data/app/views/shared/_header_navbar.html.erb +0 -61
- data/app/views/shared/_show_breadcrumbs.html.erb +0 -27
- data/lib/arclight/viewer.rb +0 -45
- data/lib/arclight/viewers/oembed.rb +0 -57
- data/solr/conf/scripts.conf +0 -24
- data/vendor/assets/javascripts/responsiveTruncator.js +0 -69
- data/vendor/assets/javascripts/stickyfill.js +0 -480
@@ -5,7 +5,6 @@ require 'traject'
|
|
5
5
|
require 'traject/nokogiri_reader'
|
6
6
|
require 'traject_plus'
|
7
7
|
require 'traject_plus/macros'
|
8
|
-
require 'arclight/exceptions'
|
9
8
|
require 'arclight/level_label'
|
10
9
|
require 'arclight/normalized_date'
|
11
10
|
require 'arclight/normalized_title'
|
@@ -14,7 +13,6 @@ require 'active_support/core_ext/array/wrap'
|
|
14
13
|
require 'arclight/digital_object'
|
15
14
|
require 'arclight/year_range'
|
16
15
|
require 'arclight/repository'
|
17
|
-
require 'arclight/missing_id_strategy'
|
18
16
|
require 'arclight/traject/nokogiri_namespaceless_reader'
|
19
17
|
|
20
18
|
# rubocop:disable Style/MixinUsage
|
@@ -55,8 +53,9 @@ DID_SEARCHABLE_NOTES_FIELDS = %w[
|
|
55
53
|
settings do
|
56
54
|
provide 'reader_class_name', 'Arclight::Traject::NokogiriNamespacelessReader'
|
57
55
|
provide 'solr_writer.commit_on_close', 'true'
|
58
|
-
provide 'repository', ENV
|
56
|
+
provide 'repository', ENV.fetch('REPOSITORY_ID', nil)
|
59
57
|
provide 'logger', Logger.new($stderr)
|
58
|
+
provide 'component_traject_config', File.join(__dir__, 'ead2_component_config.rb')
|
60
59
|
end
|
61
60
|
|
62
61
|
each_record do |_record, context|
|
@@ -69,12 +68,14 @@ end
|
|
69
68
|
|
70
69
|
# ==================
|
71
70
|
# Top level document
|
71
|
+
#
|
72
|
+
# NOTE: All fields should be stored in Solr
|
72
73
|
# ==================
|
73
74
|
|
74
75
|
to_field 'id', extract_xpath('/ead/eadheader/eadid'), strip, gsub('.', '-')
|
75
|
-
to_field '
|
76
|
+
to_field 'title_filing_ssi', extract_xpath('/ead/eadheader/filedesc/titlestmt/titleproper[@type="filing"]')
|
76
77
|
to_field 'title_ssm', extract_xpath('/ead/archdesc/did/unittitle')
|
77
|
-
to_field '
|
78
|
+
to_field 'title_tesim', extract_xpath('/ead/archdesc/did/unittitle')
|
78
79
|
to_field 'ead_ssi', extract_xpath('/ead/eadheader/eadid')
|
79
80
|
|
80
81
|
to_field 'unitdate_ssm', extract_xpath('/ead/archdesc/did/unitdate')
|
@@ -88,7 +89,7 @@ to_field 'level_ssm' do |_record, accumulator|
|
|
88
89
|
end
|
89
90
|
|
90
91
|
# Keep the original top-level archdesc/@level for Level facet in addition to 'Collection'
|
91
|
-
to_field '
|
92
|
+
to_field 'level_ssim' do |record, accumulator|
|
92
93
|
level = record.at_xpath('/ead/archdesc').attribute('level')&.value
|
93
94
|
other_level = record.at_xpath('/ead/archdesc').attribute('otherlevel')&.value
|
94
95
|
|
@@ -97,8 +98,7 @@ to_field 'level_sim' do |record, accumulator|
|
|
97
98
|
end
|
98
99
|
|
99
100
|
to_field 'unitid_ssm', extract_xpath('/ead/archdesc/did/unitid')
|
100
|
-
to_field '
|
101
|
-
to_field 'collection_unitid_ssm', extract_xpath('/ead/archdesc/did/unitid')
|
101
|
+
to_field 'unitid_tesim', extract_xpath('/ead/archdesc/did/unitid')
|
102
102
|
|
103
103
|
to_field 'normalized_title_ssm' do |_record, accumulator, context|
|
104
104
|
dates = Arclight::NormalizedDate.new(
|
@@ -118,16 +118,11 @@ to_field 'normalized_date_ssm' do |_record, accumulator, context|
|
|
118
118
|
).to_s
|
119
119
|
end
|
120
120
|
|
121
|
-
to_field '
|
122
|
-
accumulator.concat context.output_hash.fetch('normalized_title_ssm', [])
|
123
|
-
end
|
124
|
-
to_field 'collection_sim' do |_record, accumulator, context|
|
125
|
-
accumulator.concat context.output_hash.fetch('normalized_title_ssm', [])
|
126
|
-
end
|
127
|
-
to_field 'collection_ssi' do |_record, accumulator, context|
|
121
|
+
to_field 'collection_title_tesim' do |_record, accumulator, context|
|
128
122
|
accumulator.concat context.output_hash.fetch('normalized_title_ssm', [])
|
129
123
|
end
|
130
|
-
|
124
|
+
|
125
|
+
to_field 'collection_ssim' do |_record, accumulator, context|
|
131
126
|
accumulator.concat context.output_hash.fetch('normalized_title_ssm', [])
|
132
127
|
end
|
133
128
|
|
@@ -135,39 +130,30 @@ to_field 'repository_ssm' do |_record, accumulator, context|
|
|
135
130
|
accumulator << context.clipboard[:repository]
|
136
131
|
end
|
137
132
|
|
138
|
-
to_field '
|
133
|
+
to_field 'repository_ssim' do |_record, accumulator, context|
|
139
134
|
accumulator << context.clipboard[:repository]
|
140
135
|
end
|
141
136
|
|
142
137
|
to_field 'geogname_ssm', extract_xpath('/ead/archdesc/controlaccess/geogname')
|
143
|
-
to_field '
|
138
|
+
to_field 'geogname_ssim', extract_xpath('/ead/archdesc/controlaccess/geogname')
|
144
139
|
|
145
140
|
to_field 'creator_ssm', extract_xpath('/ead/archdesc/did/origination')
|
146
|
-
to_field 'creator_sim', extract_xpath('/ead/archdesc/did/origination')
|
147
141
|
to_field 'creator_ssim', extract_xpath('/ead/archdesc/did/origination')
|
148
142
|
to_field 'creator_sort' do |record, accumulator|
|
149
143
|
accumulator << record.xpath('/ead/archdesc/did/origination').map { |c| c.text.strip }.join(', ')
|
150
144
|
end
|
151
145
|
|
152
|
-
to_field 'creator_persname_ssm', extract_xpath('/ead/archdesc/did/origination/persname')
|
153
146
|
to_field 'creator_persname_ssim', extract_xpath('/ead/archdesc/did/origination/persname')
|
154
|
-
to_field 'creator_corpname_ssm', extract_xpath('/ead/archdesc/did/origination/corpname')
|
155
|
-
to_field 'creator_corpname_sim', extract_xpath('/ead/archdesc/did/origination/corpname')
|
156
147
|
to_field 'creator_corpname_ssim', extract_xpath('/ead/archdesc/did/origination/corpname')
|
157
|
-
to_field 'creator_famname_ssm', extract_xpath('/ead/archdesc/did/origination/famname')
|
158
148
|
to_field 'creator_famname_ssim', extract_xpath('/ead/archdesc/did/origination/famname')
|
159
149
|
|
160
|
-
to_field 'persname_sim', extract_xpath('//persname')
|
161
|
-
|
162
150
|
to_field 'creators_ssim' do |_record, accumulator, context|
|
163
|
-
accumulator.concat context.output_hash['
|
164
|
-
accumulator.concat context.output_hash['
|
165
|
-
accumulator.concat context.output_hash['
|
151
|
+
accumulator.concat context.output_hash['creator_persname_ssim'] if context.output_hash['creator_persname_ssim']
|
152
|
+
accumulator.concat context.output_hash['creator_corpname_ssim'] if context.output_hash['creator_corpname_ssim']
|
153
|
+
accumulator.concat context.output_hash['creator_famname_ssim'] if context.output_hash['creator_famname_ssim']
|
166
154
|
end
|
167
155
|
|
168
|
-
to_field 'places_sim', extract_xpath('/ead/archdesc/controlaccess/geogname')
|
169
156
|
to_field 'places_ssim', extract_xpath('/ead/archdesc/controlaccess/geogname')
|
170
|
-
to_field 'places_ssm', extract_xpath('/ead/archdesc/controlaccess/geogname')
|
171
157
|
|
172
158
|
to_field 'access_terms_ssm', extract_xpath('/ead/archdesc/userestrict/*[local-name()!="head"]')
|
173
159
|
|
@@ -200,11 +186,10 @@ to_field 'digital_objects_ssm', extract_xpath('/ead/archdesc/did/dao|/ead/archde
|
|
200
186
|
end
|
201
187
|
|
202
188
|
to_field 'extent_ssm', extract_xpath('/ead/archdesc/did/physdesc/extent')
|
203
|
-
to_field '
|
204
|
-
to_field '
|
205
|
-
to_field 'genreform_ssm', extract_xpath('/ead/archdesc/controlaccess/genreform')
|
189
|
+
to_field 'extent_tesim', extract_xpath('/ead/archdesc/did/physdesc/extent')
|
190
|
+
to_field 'genreform_ssim', extract_xpath('/ead/archdesc/controlaccess/genreform')
|
206
191
|
|
207
|
-
to_field '
|
192
|
+
to_field 'date_range_ssim', extract_xpath('/ead/archdesc/did/unitdate/@normal', to_text: false) do |_record, accumulator|
|
208
193
|
range = Arclight::YearRange.new
|
209
194
|
next range.years if accumulator.blank?
|
210
195
|
|
@@ -214,282 +199,76 @@ to_field 'date_range_sim', extract_xpath('/ead/archdesc/did/unitdate/@normal', t
|
|
214
199
|
end
|
215
200
|
|
216
201
|
SEARCHABLE_NOTES_FIELDS.map do |selector|
|
217
|
-
to_field "#{selector}
|
202
|
+
to_field "#{selector}_html_tesm", extract_xpath("/ead/archdesc/#{selector}/*[local-name()!='head']", to_text: false) do |_record, accumulator|
|
203
|
+
accumulator.map!(&:to_html)
|
204
|
+
end
|
218
205
|
to_field "#{selector}_heading_ssm", extract_xpath("/ead/archdesc/#{selector}/head") unless selector == 'prefercite'
|
219
|
-
to_field "#{selector}
|
206
|
+
to_field "#{selector}_tesim", extract_xpath("/ead/archdesc/#{selector}/*[local-name()!='head']")
|
220
207
|
end
|
221
208
|
|
222
209
|
DID_SEARCHABLE_NOTES_FIELDS.map do |selector|
|
223
|
-
to_field "#{selector}
|
210
|
+
to_field "#{selector}_html_tesm", extract_xpath("/ead/archdesc/did/#{selector}", to_text: false)
|
224
211
|
end
|
225
212
|
|
226
213
|
NAME_ELEMENTS.map do |selector|
|
227
214
|
to_field 'names_coll_ssim', extract_xpath("/ead/archdesc/controlaccess/#{selector}")
|
228
|
-
to_field 'names_ssim', extract_xpath("//#{selector}")
|
229
|
-
to_field "#{selector}
|
215
|
+
to_field 'names_ssim', extract_xpath("//#{selector}"), unique
|
216
|
+
to_field "#{selector}_ssim", extract_xpath("//#{selector}"), unique
|
230
217
|
end
|
231
218
|
|
232
|
-
to_field '
|
233
|
-
|
234
|
-
to_field 'language_sim', extract_xpath('/ead/archdesc/did/langmaterial')
|
235
|
-
to_field 'language_ssm', extract_xpath('/ead/archdesc/did/langmaterial')
|
219
|
+
to_field 'language_ssim', extract_xpath('/ead/archdesc/did/langmaterial')
|
236
220
|
|
237
221
|
to_field 'descrules_ssm', extract_xpath('/ead/eadheader/profiledesc/descrules')
|
238
222
|
|
239
|
-
#
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
compose 'components', ->(record, accumulator, _context) { accumulator.concat record.xpath('//*[is_component(.)]', NokogiriXpathExtensions.new) } do
|
245
|
-
to_field 'ref_ssi' do |record, accumulator, context|
|
246
|
-
accumulator << if record.attribute('id').blank?
|
247
|
-
strategy = Arclight::MissingIdStrategy.selected
|
248
|
-
hexdigest = strategy.new(record).to_hexdigest
|
249
|
-
parent_id = context.clipboard[:parent].output_hash['id'].first
|
250
|
-
logger.warn('MISSING ID WARNING') do
|
251
|
-
[
|
252
|
-
"A component in #{parent_id} did not have an ID so one was minted using the #{strategy} strategy.",
|
253
|
-
"The ID of this document will be #{parent_id}#{hexdigest}."
|
254
|
-
].join(' ')
|
255
|
-
end
|
256
|
-
record['id'] = hexdigest
|
257
|
-
hexdigest
|
258
|
-
else
|
259
|
-
record.attribute('id')&.value&.strip&.gsub('.', '-')
|
260
|
-
end
|
261
|
-
end
|
262
|
-
to_field 'ref_ssm' do |_record, accumulator, context|
|
263
|
-
accumulator.concat context.output_hash['ref_ssi']
|
264
|
-
end
|
265
|
-
|
266
|
-
to_field 'id' do |_record, accumulator, context|
|
267
|
-
accumulator << [
|
268
|
-
context.clipboard[:parent].output_hash['id'],
|
269
|
-
context.output_hash['ref_ssi']
|
270
|
-
].join('')
|
271
|
-
end
|
272
|
-
|
273
|
-
to_field 'ead_ssi' do |_record, accumulator, context|
|
274
|
-
accumulator << context.clipboard[:parent].output_hash['ead_ssi'].first
|
275
|
-
end
|
276
|
-
|
277
|
-
to_field 'title_filing_si', extract_xpath('./did/unittitle'), first_only
|
278
|
-
to_field 'title_ssm', extract_xpath('./did/unittitle')
|
279
|
-
to_field 'title_teim', extract_xpath('./did/unittitle')
|
280
|
-
|
281
|
-
to_field 'unitdate_bulk_ssim', extract_xpath('./did/unitdate[@type="bulk"]')
|
282
|
-
to_field 'unitdate_inclusive_ssm', extract_xpath('./did/unitdate[@type="inclusive"]')
|
283
|
-
to_field 'unitdate_other_ssim', extract_xpath('./did/unitdate[not(@type)]')
|
284
|
-
|
285
|
-
to_field 'normalized_title_ssm' do |_record, accumulator, context|
|
286
|
-
dates = Arclight::NormalizedDate.new(
|
287
|
-
context.output_hash['unitdate_inclusive_ssm'],
|
288
|
-
context.output_hash['unitdate_bulk_ssim'],
|
289
|
-
context.output_hash['unitdate_other_ssim']
|
290
|
-
).to_s
|
291
|
-
title = context.output_hash['title_ssm']&.first
|
292
|
-
accumulator << Arclight::NormalizedTitle.new(title, dates).to_s
|
293
|
-
end
|
294
|
-
|
295
|
-
to_field 'normalized_date_ssm' do |_record, accumulator, context|
|
296
|
-
accumulator << Arclight::NormalizedDate.new(
|
297
|
-
context.output_hash['unitdate_inclusive_ssm'],
|
298
|
-
context.output_hash['unitdate_bulk_ssim'],
|
299
|
-
context.output_hash['unitdate_other_ssim']
|
300
|
-
).to_s
|
301
|
-
end
|
302
|
-
|
303
|
-
to_field 'component_level_isim' do |record, accumulator|
|
304
|
-
accumulator << 1 + NokogiriXpathExtensions.new.is_component(record.ancestors).count
|
305
|
-
end
|
306
|
-
|
307
|
-
to_field 'parent_ssim' do |record, accumulator, context|
|
308
|
-
accumulator << context.clipboard[:parent].output_hash['id'].first
|
309
|
-
accumulator.concat NokogiriXpathExtensions.new.is_component(record.ancestors).reverse.map { |n| n.attribute('id')&.value }
|
310
|
-
end
|
311
|
-
|
312
|
-
to_field 'parent_ssi' do |_record, accumulator, context|
|
313
|
-
accumulator << context.output_hash['parent_ssim'].last
|
314
|
-
end
|
315
|
-
|
316
|
-
to_field 'parent_unittitles_ssm' do |_rec, accumulator, context|
|
317
|
-
# top level document
|
318
|
-
accumulator.concat context.clipboard[:parent].output_hash['normalized_title_ssm']
|
319
|
-
parent_ssim = context.output_hash['parent_ssim']
|
320
|
-
components = context.clipboard[:parent].output_hash['components']
|
321
|
-
|
322
|
-
# other components
|
323
|
-
if parent_ssim && components
|
324
|
-
ancestors = parent_ssim.drop(1).map { |x| [x] }
|
325
|
-
accumulator.concat components.select { |c| ancestors.include? c['ref_ssi'] }.flat_map { |c| c['normalized_title_ssm'] }
|
326
|
-
end
|
327
|
-
end
|
328
|
-
|
329
|
-
to_field 'parent_unittitles_teim' do |_record, accumulator, context|
|
330
|
-
accumulator.concat context.output_hash['parent_unittitles_ssm']
|
331
|
-
end
|
332
|
-
|
333
|
-
to_field 'parent_levels_ssm' do |_record, accumulator, context|
|
334
|
-
## Top level document
|
335
|
-
accumulator.concat context.clipboard[:parent].output_hash['level_ssm']
|
336
|
-
## Other components
|
337
|
-
context.output_hash['parent_ssim']&.drop(1)&.each do |id|
|
338
|
-
accumulator.concat Array
|
339
|
-
.wrap(context.clipboard[:parent].output_hash['components'])
|
340
|
-
.select { |c| c['ref_ssi'] == [id] }.map { |c| c['level_ssm'] }.flatten
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
|
-
to_field 'unitid_ssm', extract_xpath('./did/unitid')
|
345
|
-
to_field 'collection_unitid_ssm' do |_record, accumulator, context|
|
346
|
-
accumulator.concat Array.wrap(context.clipboard[:parent].output_hash['unitid_ssm'])
|
347
|
-
end
|
348
|
-
to_field 'repository_ssm' do |_record, accumulator, context|
|
349
|
-
accumulator << context.clipboard[:parent].clipboard[:repository]
|
350
|
-
end
|
351
|
-
to_field 'repository_sim' do |_record, accumulator, context|
|
352
|
-
accumulator << context.clipboard[:parent].clipboard[:repository]
|
353
|
-
end
|
354
|
-
to_field 'collection_ssm' do |_record, accumulator, context|
|
355
|
-
accumulator.concat context.clipboard[:parent].output_hash['normalized_title_ssm']
|
356
|
-
end
|
357
|
-
to_field 'collection_sim' do |_record, accumulator, context|
|
358
|
-
accumulator.concat context.clipboard[:parent].output_hash['normalized_title_ssm']
|
359
|
-
end
|
360
|
-
to_field 'collection_ssi' do |_record, accumulator, context|
|
361
|
-
accumulator.concat context.clipboard[:parent].output_hash['normalized_title_ssm']
|
362
|
-
end
|
363
|
-
|
364
|
-
to_field 'extent_ssm', extract_xpath('./did/physdesc/extent')
|
365
|
-
to_field 'extent_teim', extract_xpath('./did/physdesc/extent')
|
366
|
-
|
367
|
-
to_field 'creator_ssm', extract_xpath('./did/origination')
|
368
|
-
to_field 'creator_ssim', extract_xpath('./did/origination')
|
369
|
-
to_field 'creators_ssim', extract_xpath('./did/origination')
|
370
|
-
to_field 'creator_sort' do |record, accumulator|
|
371
|
-
accumulator << record.xpath('./did/origination').map(&:text).join(', ')
|
372
|
-
end
|
373
|
-
to_field 'collection_creator_ssm' do |_record, accumulator, context|
|
374
|
-
accumulator.concat Array.wrap(context.clipboard[:parent].output_hash['creator_ssm'])
|
375
|
-
end
|
376
|
-
to_field 'has_online_content_ssim', extract_xpath('.//dao') do |_record, accumulator|
|
377
|
-
accumulator.replace([accumulator.any?])
|
378
|
-
end
|
379
|
-
to_field 'child_component_count_isim' do |record, accumulator|
|
380
|
-
accumulator << NokogiriXpathExtensions.new.is_component(record.children).count
|
381
|
-
end
|
382
|
-
|
383
|
-
to_field 'ref_ssm' do |record, accumulator|
|
384
|
-
accumulator << record.attribute('id')
|
385
|
-
end
|
386
|
-
|
387
|
-
to_field 'level_ssm' do |record, accumulator|
|
388
|
-
level = record.attribute('level')&.value
|
389
|
-
other_level = record.attribute('otherlevel')&.value
|
390
|
-
accumulator << Arclight::LevelLabel.new(level, other_level).to_s
|
391
|
-
end
|
223
|
+
# count all descendant components from the top-level
|
224
|
+
to_field 'total_component_count_is', first_only do |record, accumulator|
|
225
|
+
accumulator << record.xpath('//c|//c01|//c02|//c03|//c04|//c05|//c06|//c07|//c08|//c09|//c10|//c11|//c12').count
|
226
|
+
end
|
392
227
|
|
393
|
-
|
394
|
-
|
228
|
+
# count all digital objects from the top-level
|
229
|
+
to_field 'online_item_count_is', first_only do |record, accumulator|
|
230
|
+
accumulator << record.xpath('//dao').count
|
231
|
+
end
|
395
232
|
|
396
|
-
|
397
|
-
|
233
|
+
to_field 'component_level_isim' do |_record, accumulator, _context|
|
234
|
+
accumulator << 0
|
235
|
+
end
|
398
236
|
|
399
|
-
|
400
|
-
|
401
|
-
|
237
|
+
to_field 'sort_isi' do |_record, accumulator, _context|
|
238
|
+
accumulator << 0
|
239
|
+
end
|
402
240
|
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
.map(&:text))
|
408
|
-
end
|
241
|
+
# =============================
|
242
|
+
# Each component child document
|
243
|
+
# <c> <c01> <c12>
|
244
|
+
# =============================
|
409
245
|
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
.wrap(record.xpath('(./ancestor-or-self::*/userestrict)[last()]/*[local-name()!="head"]')
|
414
|
-
.map(&:text))
|
415
|
-
end
|
246
|
+
to_field 'components' do |record, accumulator, context|
|
247
|
+
child_components = record.xpath("/ead/archdesc/dsc/c|#{('/ead/archdesc/dsc/c01'..'/ead/archdesc/dsc/c12').to_a.join('|')}")
|
248
|
+
next unless child_components.any?
|
416
249
|
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
href = (dao.attributes['href'] || dao.attributes['xlink:href'])&.value
|
422
|
-
Arclight::DigitalObject.new(label: label, href: href).to_json
|
250
|
+
counter = Class.new do
|
251
|
+
def increment
|
252
|
+
@counter ||= 0
|
253
|
+
@counter += 1
|
423
254
|
end
|
424
|
-
end
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
NAME_ELEMENTS.map do |selector|
|
436
|
-
to_field 'names_ssim', extract_xpath("./controlaccess/#{selector}")
|
437
|
-
to_field "#{selector}_ssm", extract_xpath(".//#{selector}")
|
438
|
-
end
|
439
|
-
|
440
|
-
to_field 'geogname_sim', extract_xpath('./controlaccess/geogname')
|
441
|
-
to_field 'geogname_ssm', extract_xpath('./controlaccess/geogname')
|
442
|
-
to_field 'places_ssim', extract_xpath('./controlaccess/geogname')
|
443
|
-
|
444
|
-
to_field 'access_subjects_ssim', extract_xpath('./controlaccess', to_text: false) do |_record, accumulator|
|
445
|
-
accumulator.map! do |element|
|
446
|
-
%w[subject function occupation genreform].map do |selector|
|
447
|
-
element.xpath(".//#{selector}").map(&:text)
|
448
|
-
end
|
449
|
-
end.flatten!
|
450
|
-
end
|
451
|
-
|
452
|
-
to_field 'access_subjects_ssm' do |_record, accumulator, context|
|
453
|
-
accumulator.concat(context.output_hash.fetch('access_subjects_ssim', []))
|
454
|
-
end
|
455
|
-
|
456
|
-
to_field 'acqinfo_ssim', extract_xpath('/ead/archdesc/acqinfo/*[local-name()!="head"]')
|
457
|
-
to_field 'acqinfo_ssim', extract_xpath('/ead/archdesc/descgrp/acqinfo/*[local-name()!="head"]')
|
458
|
-
to_field 'acqinfo_ssim', extract_xpath('./acqinfo/*[local-name()!="head"]')
|
459
|
-
to_field 'acqinfo_ssim', extract_xpath('./descgrp/acqinfo/*[local-name()!="head"]')
|
460
|
-
|
461
|
-
to_field 'language_ssm', extract_xpath('./did/langmaterial')
|
462
|
-
to_field 'containers_ssim' do |record, accumulator|
|
463
|
-
record.xpath('./did/container').each do |node|
|
464
|
-
accumulator << [node.attribute('type'), node.text].join(' ').strip
|
255
|
+
end.new
|
256
|
+
|
257
|
+
component_indexer = Traject::Indexer::NokogiriIndexer.new.tap do |i|
|
258
|
+
i.settings do
|
259
|
+
provide :parent, context
|
260
|
+
provide :root, context
|
261
|
+
provide :counter, counter
|
262
|
+
provide :depth, 1
|
263
|
+
provide :logger, context.settings[:logger]
|
264
|
+
provide :component_traject_config, context.settings[:component_traject_config]
|
465
265
|
end
|
466
|
-
end
|
467
266
|
|
468
|
-
|
469
|
-
to_field "#{selector}_ssm", extract_xpath("./#{selector}/*[local-name()!='head']", to_text: false)
|
470
|
-
to_field "#{selector}_heading_ssm", extract_xpath("./#{selector}/head")
|
471
|
-
to_field "#{selector}_teim", extract_xpath("./#{selector}/*[local-name()!='head']")
|
472
|
-
end
|
473
|
-
DID_SEARCHABLE_NOTES_FIELDS.map do |selector|
|
474
|
-
to_field "#{selector}_ssm", extract_xpath("./did/#{selector}", to_text: false)
|
267
|
+
i.load_config_file(context.settings[:component_traject_config])
|
475
268
|
end
|
476
|
-
to_field 'did_note_ssm', extract_xpath('./did/note')
|
477
|
-
end
|
478
269
|
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
##
|
484
|
-
# Used for evaluating xpath components to find
|
485
|
-
class NokogiriXpathExtensions
|
486
|
-
# rubocop:disable Naming/PredicateName, Style/FormatString
|
487
|
-
def is_component(node_set)
|
488
|
-
node_set.find_all do |node|
|
489
|
-
component_elements = (1..12).map { |i| "c#{'%02d' % i}" }
|
490
|
-
component_elements.push 'c'
|
491
|
-
component_elements.include? node.name
|
492
|
-
end
|
270
|
+
child_components.each do |child_component|
|
271
|
+
output = component_indexer.map_record(child_component)
|
272
|
+
accumulator << output if output.keys.any?
|
493
273
|
end
|
494
|
-
# rubocop:enable Naming/PredicateName, Style/FormatString
|
495
274
|
end
|
data/lib/arclight/version.rb
CHANGED
data/lib/arclight/year_range.rb
CHANGED
@@ -18,7 +18,6 @@ module Arclight
|
|
18
18
|
def initialize(dates = nil)
|
19
19
|
@years = []
|
20
20
|
self << parse_ranges(dates) if dates.present?
|
21
|
-
self
|
22
21
|
end
|
23
22
|
|
24
23
|
# @return [String] a concise, human-readable version of the year range, including gaps
|
@@ -77,13 +76,14 @@ module Arclight
|
|
77
76
|
# Deals with making a human-readable range for years with 1 or more gaps.
|
78
77
|
# It involves detection of streaks between the gaps.
|
79
78
|
# @return [String] 1999-2000, 2002 for 1999, 2000, 2002
|
80
|
-
|
79
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
80
|
+
def to_s_with_gaps
|
81
81
|
raise ArgumentError if years.blank? || years.length < 2
|
82
82
|
|
83
83
|
results = []
|
84
84
|
streak = [years[0]]
|
85
85
|
i = streak.first
|
86
|
-
years[1
|
86
|
+
years[1..].each do |j|
|
87
87
|
i += 1
|
88
88
|
if i == j
|
89
89
|
streak << j
|
@@ -100,6 +100,7 @@ module Arclight
|
|
100
100
|
results << to_s_for_streak(streak)
|
101
101
|
results.join(', ')
|
102
102
|
end
|
103
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
103
104
|
|
104
105
|
def to_s_for_streak(streak)
|
105
106
|
return streak.min.to_s if streak.min == streak.max
|
data/lib/arclight.rb
CHANGED
@@ -5,6 +5,11 @@ require 'arclight/engine'
|
|
5
5
|
require 'arclight/repository'
|
6
6
|
require 'arclight/year_range'
|
7
7
|
|
8
|
+
# :nodoc:
|
8
9
|
module Arclight
|
9
|
-
|
10
|
+
autoload :Routes, 'arclight/routes'
|
11
|
+
|
12
|
+
def self.deprecation
|
13
|
+
@deprecation ||= ActiveSupport::Deprecation.new('2.0', 'Arclight')
|
14
|
+
end
|
10
15
|
end
|
@@ -33,32 +33,17 @@ module Arclight
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def install_blacklight_range_limit
|
37
|
-
generate 'blacklight_range_limit:install'
|
38
|
-
end
|
39
|
-
|
40
36
|
def add_custom_routes
|
41
37
|
inject_into_file 'config/routes.rb', after: "mount Blacklight::Engine => '/'" do
|
42
|
-
"\n
|
38
|
+
"\n mount Arclight::Engine => '/'\n"
|
43
39
|
end
|
40
|
+
|
41
|
+
gsub_file 'config/routes.rb', 'root to: "catalog#index"', 'root to: "arclight/repositories#index"'
|
44
42
|
end
|
45
43
|
|
46
44
|
def copy_styles
|
47
45
|
copy_file 'arclight.scss', 'app/assets/stylesheets/arclight.scss'
|
48
|
-
|
49
|
-
|
50
|
-
def inject_js
|
51
|
-
inject_into_file 'app/assets/javascripts/application.js', after: '//= require blacklight/blacklight' do
|
52
|
-
"\n// Required by Arclight" \
|
53
|
-
"\n//= require arclight/arclight" \
|
54
|
-
"\n//= require stickyfill"
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def install_webpacker
|
59
|
-
return unless Rails.version.to_i == 6
|
60
|
-
|
61
|
-
rake 'webpacker:install'
|
46
|
+
remove_file 'app/assets/stylesheets/blacklight.scss' # Avoid two copies of bootstrap
|
62
47
|
end
|
63
48
|
|
64
49
|
def add_arclight_search_behavior
|
@@ -79,12 +64,65 @@ module Arclight
|
|
79
64
|
copy_file 'config/downloads.yml' unless File.exist?('config/downloads.yml')
|
80
65
|
end
|
81
66
|
|
67
|
+
def add_i18n_config
|
68
|
+
copy_file 'config/locales/arclight.en.yml'
|
69
|
+
end
|
70
|
+
|
82
71
|
def modify_blacklight_yml
|
83
72
|
gsub_file 'config/locales/blacklight.en.yml', "application_name: 'Blacklight'", "application_name: 'Arclight'"
|
84
73
|
end
|
85
74
|
|
86
|
-
def
|
87
|
-
|
75
|
+
def assets
|
76
|
+
if using_importmap?
|
77
|
+
pin_javascript_dependencies
|
78
|
+
import_arclight_javascript
|
79
|
+
else
|
80
|
+
install_javascript_dependencies
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def inject_arclight_routes
|
85
|
+
inject_into_file 'config/routes.rb',
|
86
|
+
" concern :hierarchy, Arclight::Routes::Hierarchy.new\n",
|
87
|
+
after: /concern :exportable.*\n/
|
88
|
+
inject_into_file 'config/routes.rb',
|
89
|
+
" concerns :hierarchy\n",
|
90
|
+
after: /resources :solr_documents.*\n/
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def root
|
96
|
+
@root ||= Pathname(destination_root)
|
97
|
+
end
|
98
|
+
|
99
|
+
def using_importmap?
|
100
|
+
@using_importmap ||= root.join('config/importmap.rb').exist?
|
101
|
+
end
|
102
|
+
|
103
|
+
# This is the last step because any failure here wouldn't prevent the other steps from running
|
104
|
+
def install_javascript_dependencies
|
105
|
+
inject_into_file 'app/assets/javascripts/application.js', after: '//= require blacklight/blacklight' do
|
106
|
+
"\n// Required by Arclight" \
|
107
|
+
"\n//= require arclight/arclight"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def pin_javascript_dependencies
|
112
|
+
say 'Arclight Importmap asset generation'
|
113
|
+
|
114
|
+
append_to_file 'config/importmap.rb', <<~RUBY
|
115
|
+
pin "arclight", to: "arclight/arclight.js"
|
116
|
+
# TODO: We may be able to move these to a single importmap for arclight.
|
117
|
+
pin "arclight/oembed_viewer", to: "arclight/oembed_viewer.js"
|
118
|
+
pin "arclight/truncate_controller", to: "arclight/truncate_controller.js"
|
119
|
+
RUBY
|
120
|
+
end
|
121
|
+
|
122
|
+
def import_arclight_javascript
|
123
|
+
inject_into_file 'app/javascript/application.js', after: 'import "blacklight"' do
|
124
|
+
"\nimport \"arclight\""
|
125
|
+
end
|
88
126
|
end
|
89
127
|
end
|
90
128
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
$breadcrumb-divider: quote("»");
|
2
|
+
@import 'bootstrap';
|
3
|
+
@import 'blacklight/blacklight';
|
4
|
+
@import 'arclight/application';
|