2024-04-29 00:17:15 +02:00
|
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
2023-11-06 15:15:51 +01:00
|
|
|
|
describe 'The routing with rules', js: true do
|
2024-09-03 17:45:37 +02:00
|
|
|
|
let(:password) { SECURE_PASSWORD }
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
|
|
|
|
let(:procedure) do
|
2024-01-23 09:52:20 +01:00
|
|
|
|
create(:procedure, :with_service, :for_individual, :with_zone, types_de_champ_public: [
|
2024-06-25 17:17:51 +02:00
|
|
|
|
{ type: :text, libelle: 'un premier champ text', mandatory: false },
|
|
|
|
|
{ type: :drop_down_list, libelle: 'Spécialité', options: ["", "littéraire", "scientifique", "artistique"], mandatory: false }
|
2024-01-23 09:52:20 +01:00
|
|
|
|
])
|
2023-03-30 12:31:48 +02:00
|
|
|
|
end
|
|
|
|
|
let(:administrateur) { create(:administrateur, procedures: [procedure]) }
|
|
|
|
|
let(:scientifique_user) { create(:user, password: password) }
|
|
|
|
|
let(:litteraire_user) { create(:user, password: password) }
|
2023-05-25 14:53:51 +02:00
|
|
|
|
let(:artistique_user) { create(:user, password: password) }
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
|
|
|
|
before do
|
|
|
|
|
procedure.defaut_groupe_instructeur.instructeurs << administrateur.instructeur
|
|
|
|
|
end
|
|
|
|
|
|
2023-04-26 17:29:47 +02:00
|
|
|
|
scenario 'Routage à partir d’un champ' do
|
|
|
|
|
steps_to_routing_configuration
|
|
|
|
|
|
|
|
|
|
choose('À partir d’un champ', allow_label_click: true)
|
|
|
|
|
click_on 'Continuer'
|
|
|
|
|
|
|
|
|
|
expect(page).to have_text('Routage à partir d’un champ')
|
|
|
|
|
|
|
|
|
|
choose('Spécialité', allow_label_click: true)
|
|
|
|
|
click_on 'Créer les groupes'
|
|
|
|
|
|
|
|
|
|
expect(page).to have_text('Gestion des groupes')
|
2023-05-25 14:53:51 +02:00
|
|
|
|
expect(page).to have_text('3 groupes')
|
2023-06-16 15:11:33 +02:00
|
|
|
|
expect(page).not_to have_text('à configurer')
|
2023-04-26 17:29:47 +02:00
|
|
|
|
|
2024-11-08 15:08:12 +01:00
|
|
|
|
within("#routing-mode-modal") { click_on "Fermer" }
|
|
|
|
|
|
2023-04-26 17:29:47 +02:00
|
|
|
|
click_on 'littéraire'
|
2023-10-18 18:44:52 +02:00
|
|
|
|
expect(page).to have_select("groupe_instructeur[condition_form][rows][][targeted_champ]", selected: "Spécialité")
|
|
|
|
|
expect(page).to have_select("groupe_instructeur[condition_form][rows][][value]", selected: "littéraire")
|
2023-04-26 17:29:47 +02:00
|
|
|
|
|
2023-05-25 14:53:51 +02:00
|
|
|
|
click_on '3 groupes'
|
2023-04-26 17:29:47 +02:00
|
|
|
|
click_on 'scientifique'
|
|
|
|
|
|
2023-10-18 18:44:52 +02:00
|
|
|
|
expect(page).to have_select("groupe_instructeur[condition_form][rows][][targeted_champ]", selected: "Spécialité")
|
|
|
|
|
expect(page).to have_select("groupe_instructeur[condition_form][rows][][value]", selected: "scientifique")
|
2023-04-26 17:29:47 +02:00
|
|
|
|
end
|
|
|
|
|
|
2023-05-16 11:16:35 +02:00
|
|
|
|
scenario 'Routage avancé' do
|
2023-04-26 17:29:47 +02:00
|
|
|
|
steps_to_routing_configuration
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
2023-04-26 17:29:47 +02:00
|
|
|
|
choose('Avancé', allow_label_click: true)
|
|
|
|
|
click_on 'Continuer'
|
|
|
|
|
|
|
|
|
|
expect(page).to have_text('Gestion des groupes')
|
2023-06-16 15:11:33 +02:00
|
|
|
|
expect(page).to have_text('règle invalide')
|
2023-04-26 17:29:47 +02:00
|
|
|
|
|
2024-10-17 09:20:52 +02:00
|
|
|
|
# close modal
|
|
|
|
|
expect(page).to have_selector("#routing-mode-modal", visible: true)
|
|
|
|
|
within("#routing-mode-modal") { click_on "Fermer" }
|
|
|
|
|
expect(page).to have_selector("#routing-mode-modal", visible: false)
|
|
|
|
|
|
2023-04-26 17:29:47 +02:00
|
|
|
|
# update defaut groupe
|
2024-10-17 09:44:58 +02:00
|
|
|
|
click_on 'Groupe 1 (à renommer et configurer)'
|
2023-06-07 11:00:38 +02:00
|
|
|
|
expect(page).to have_text('Paramètres du groupe')
|
2023-04-26 17:29:47 +02:00
|
|
|
|
fill_in 'Nom du groupe', with: 'littéraire'
|
|
|
|
|
click_on 'Renommer'
|
|
|
|
|
expect(page).to have_text('Le nom est à présent « littéraire ». ')
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
|
|
|
|
# add victor to littéraire groupe
|
2023-07-10 14:55:20 +02:00
|
|
|
|
fill_in 'Emails', with: 'victor@gouv.fr'
|
2023-03-30 12:31:48 +02:00
|
|
|
|
perform_enqueued_jobs { click_on 'Affecter' }
|
2023-07-10 14:55:20 +02:00
|
|
|
|
expect(page).to have_text("L’instructeur victor@gouv.fr a été affecté")
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
2023-07-10 14:55:20 +02:00
|
|
|
|
victor = User.find_by(email: 'victor@gouv.fr').instructeur
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
2023-07-10 14:55:20 +02:00
|
|
|
|
# add alain to littéraire groupe
|
|
|
|
|
fill_in 'Emails', with: 'alain@gouv.fr'
|
2023-03-30 12:31:48 +02:00
|
|
|
|
perform_enqueued_jobs { click_on 'Affecter' }
|
2023-07-10 14:55:20 +02:00
|
|
|
|
expect(page).to have_text("L’instructeur alain@gouv.fr a été affecté")
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
2023-07-10 14:55:20 +02:00
|
|
|
|
alain = User.find_by(email: 'alain@gouv.fr').instructeur
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
|
|
|
|
# add inactive groupe
|
2024-09-30 16:25:20 +02:00
|
|
|
|
visit ajout_admin_procedure_groupe_instructeurs_path(procedure)
|
2023-04-26 17:29:47 +02:00
|
|
|
|
fill_in 'Nouveau groupe', with: 'non visible car inactif'
|
|
|
|
|
click_on 'Ajouter'
|
|
|
|
|
expect(page).to have_text('Le groupe d’instructeurs « non visible car inactif » a été créé. ')
|
|
|
|
|
check("Groupe inactif", allow_label_click: true)
|
|
|
|
|
|
|
|
|
|
# # add scientifique groupe
|
|
|
|
|
click_on '3 groupes'
|
2024-10-17 09:44:58 +02:00
|
|
|
|
click_on 'Groupe 2 (à renommer et configurer)'
|
2023-04-26 17:29:47 +02:00
|
|
|
|
fill_in 'Nom du groupe', with: 'scientifique'
|
|
|
|
|
click_on 'Renommer'
|
|
|
|
|
expect(page).to have_text('Le nom est à présent « scientifique ». ')
|
2023-05-25 14:53:51 +02:00
|
|
|
|
|
2023-03-30 12:31:48 +02:00
|
|
|
|
# add marie to scientifique groupe
|
2023-07-10 14:55:20 +02:00
|
|
|
|
fill_in 'Emails', with: 'marie@gouv.fr'
|
2023-03-30 12:31:48 +02:00
|
|
|
|
perform_enqueued_jobs { click_on 'Affecter' }
|
2023-07-10 14:55:20 +02:00
|
|
|
|
expect(page).to have_text("L’instructeur marie@gouv.fr a été affecté")
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
2023-07-10 14:55:20 +02:00
|
|
|
|
marie = User.find_by(email: 'marie@gouv.fr').instructeur
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
|
|
|
|
# add superwoman to scientifique groupe
|
2023-07-10 14:55:20 +02:00
|
|
|
|
fill_in 'Emails', with: 'alain@gouv.fr'
|
2023-03-30 12:31:48 +02:00
|
|
|
|
perform_enqueued_jobs { click_on 'Affecter' }
|
2023-07-10 14:55:20 +02:00
|
|
|
|
expect(page).to have_text("L’instructeur alain@gouv.fr a été affecté")
|
2023-05-25 14:53:51 +02:00
|
|
|
|
|
2023-03-30 12:31:48 +02:00
|
|
|
|
# add routing rules
|
2023-10-18 18:44:52 +02:00
|
|
|
|
within('.target select') { select('Spécialité') }
|
|
|
|
|
within('.value select') { select('scientifique') }
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
2023-04-26 17:29:47 +02:00
|
|
|
|
click_on '3 groupes'
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
2023-04-26 17:29:47 +02:00
|
|
|
|
click_on 'littéraire'
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
2023-10-18 18:44:52 +02:00
|
|
|
|
within('.target select') { select('Spécialité') }
|
|
|
|
|
within('.value select') { select('scientifique') }
|
2023-05-16 11:16:35 +02:00
|
|
|
|
|
|
|
|
|
expect(page).to have_text('règle déjà attribuée à scientifique')
|
|
|
|
|
|
2023-10-18 18:44:52 +02:00
|
|
|
|
within('.target select') { select('Spécialité') }
|
|
|
|
|
within('.value select') { select('littéraire') }
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
2023-05-16 11:16:35 +02:00
|
|
|
|
expect(page).not_to have_text('règle déjà attribuée à scientifique')
|
|
|
|
|
|
2023-04-26 17:29:47 +02:00
|
|
|
|
procedure.groupe_instructeurs.where(closed: false).each { |gi| wait_until { gi.reload.routing_rule.present? } }
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
2023-05-25 14:53:51 +02:00
|
|
|
|
# add a group without routing rules
|
2024-09-30 16:25:20 +02:00
|
|
|
|
visit ajout_admin_procedure_groupe_instructeurs_path(procedure)
|
2023-05-25 14:53:51 +02:00
|
|
|
|
fill_in 'Nouveau groupe', with: 'artistique'
|
|
|
|
|
click_on 'Ajouter'
|
|
|
|
|
expect(page).to have_text('Le groupe d’instructeurs « artistique » a été créé. ')
|
|
|
|
|
expect(procedure.groupe_instructeurs.count).to eq(4)
|
|
|
|
|
|
2024-06-07 09:54:21 +02:00
|
|
|
|
# add contact_information to all groupes instructeur
|
|
|
|
|
procedure.groupe_instructeurs.each { |gi| gi.update!(contact_information: create(:contact_information)) }
|
|
|
|
|
|
2023-03-30 12:31:48 +02:00
|
|
|
|
# publish
|
|
|
|
|
publish_procedure(procedure)
|
|
|
|
|
log_out
|
|
|
|
|
|
2023-05-25 14:53:51 +02:00
|
|
|
|
# 3 users fill a dossier in each group
|
2023-03-30 12:31:48 +02:00
|
|
|
|
user_send_dossier(scientifique_user, 'scientifique')
|
|
|
|
|
user_send_dossier(litteraire_user, 'littéraire')
|
2023-05-25 14:53:51 +02:00
|
|
|
|
user_send_dossier(artistique_user, 'artistique')
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
2024-04-25 17:57:55 +02:00
|
|
|
|
perform_enqueued_jobs(only: DossierIndexSearchTermsJob)
|
2024-04-03 10:21:50 +02:00
|
|
|
|
|
2023-03-30 12:31:48 +02:00
|
|
|
|
# the litteraires instructeurs only manage the litteraires dossiers
|
|
|
|
|
register_instructeur_and_log_in(victor.email)
|
|
|
|
|
click_on procedure.libelle
|
|
|
|
|
expect(page).to have_text(litteraire_user.email)
|
|
|
|
|
expect(page).not_to have_text(scientifique_user.email)
|
|
|
|
|
|
|
|
|
|
# the search only show litteraires dossiers
|
|
|
|
|
fill_in 'q', with: scientifique_user.email
|
|
|
|
|
find('.fr-search-bar .fr-btn').click
|
|
|
|
|
expect(page).to have_text('0 dossier trouvé')
|
|
|
|
|
|
|
|
|
|
# weird bug, capabary appends text instead of replaces it
|
|
|
|
|
# see https://github.com/redux-form/redux-form/issues/686
|
|
|
|
|
fill_in('q', with: litteraire_user.email, fill_options: { clear: :backspace })
|
|
|
|
|
find('.fr-search-bar .fr-btn').click
|
|
|
|
|
expect(page).to have_text('1 dossier trouvé')
|
|
|
|
|
|
|
|
|
|
## and the result is clickable
|
|
|
|
|
click_on litteraire_user.email
|
|
|
|
|
expect(page).to have_current_path(instructeur_dossier_path(procedure, litteraire_user.dossiers.first))
|
|
|
|
|
|
|
|
|
|
# follow the dossier
|
|
|
|
|
click_on 'Suivre le dossier'
|
|
|
|
|
|
|
|
|
|
log_out
|
|
|
|
|
|
|
|
|
|
# the scientifiques instructeurs only manage the scientifiques dossiers
|
|
|
|
|
register_instructeur_and_log_in(marie.email)
|
|
|
|
|
click_on procedure.libelle
|
|
|
|
|
expect(page).not_to have_text(litteraire_user.email)
|
|
|
|
|
expect(page).to have_text(scientifique_user.email)
|
|
|
|
|
|
|
|
|
|
# follow the dossier
|
|
|
|
|
click_on scientifique_user.email
|
|
|
|
|
click_on 'Suivre le dossier'
|
|
|
|
|
|
|
|
|
|
log_out
|
|
|
|
|
|
|
|
|
|
# litteraire_user change its dossier
|
|
|
|
|
visit new_user_session_path
|
|
|
|
|
sign_in_with litteraire_user.email, password
|
|
|
|
|
|
2023-07-10 14:55:20 +02:00
|
|
|
|
click_on litteraire_user.dossiers.first.procedure.libelle
|
2023-03-30 12:31:48 +02:00
|
|
|
|
click_on 'Modifier mon dossier'
|
|
|
|
|
|
2024-09-27 15:37:11 +02:00
|
|
|
|
fill_in litteraire_user.dossiers.first.project_champs_public.first.libelle, with: 'some value'
|
2023-08-29 15:47:28 +02:00
|
|
|
|
wait_for_autosave
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
2023-03-21 18:24:39 +01:00
|
|
|
|
click_on 'Déposer les modifications'
|
|
|
|
|
|
2023-03-30 12:31:48 +02:00
|
|
|
|
log_out
|
|
|
|
|
|
|
|
|
|
# the litteraires instructeurs should have a notification
|
|
|
|
|
visit new_user_session_path
|
|
|
|
|
sign_in_with victor.user.email, password
|
|
|
|
|
|
|
|
|
|
## on the procedures list
|
|
|
|
|
expect(page).to have_current_path(instructeur_procedures_path)
|
|
|
|
|
expect(find('.procedure-stats')).to have_css('span.notifications')
|
|
|
|
|
|
|
|
|
|
## on the dossiers list
|
|
|
|
|
click_on procedure.libelle
|
|
|
|
|
expect(page).to have_current_path(instructeur_procedure_path(procedure))
|
2024-10-25 14:50:51 +02:00
|
|
|
|
expect(find('nav.fr-tabs')).to have_css('span.notifications')
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
|
|
|
|
## on the dossier itself
|
|
|
|
|
click_on 'suivi'
|
|
|
|
|
click_on litteraire_user.email
|
|
|
|
|
expect(page).to have_current_path(instructeur_dossier_path(procedure, litteraire_user.dossiers.first))
|
|
|
|
|
expect(page).to have_text('Annotations privées')
|
2023-11-09 15:02:43 +01:00
|
|
|
|
expect(find('.fr-tabs')).to have_css('span.notifications')
|
2023-03-30 12:31:48 +02:00
|
|
|
|
log_out
|
|
|
|
|
|
|
|
|
|
# the scientifiques instructeurs should not have a notification
|
|
|
|
|
visit new_user_session_path
|
|
|
|
|
sign_in_with marie.user.email, password
|
|
|
|
|
|
|
|
|
|
expect(page).to have_current_path(instructeur_procedures_path)
|
|
|
|
|
expect(find('.procedure-stats')).not_to have_css('span.notifications')
|
|
|
|
|
log_out
|
|
|
|
|
|
2023-04-26 17:29:47 +02:00
|
|
|
|
# the instructeurs who belong to scientifique AND litteraire groups manage scientifique and litteraire dossiers
|
2023-07-10 14:55:20 +02:00
|
|
|
|
register_instructeur_and_log_in(alain.email)
|
2023-03-30 12:31:48 +02:00
|
|
|
|
visit instructeur_procedure_path(procedure, params: { statut: 'tous' })
|
|
|
|
|
expect(page).to have_text(litteraire_user.email)
|
|
|
|
|
expect(page).to have_text(scientifique_user.email)
|
|
|
|
|
|
|
|
|
|
# follow the dossier
|
|
|
|
|
click_on scientifique_user.email
|
|
|
|
|
click_on 'Suivre le dossier'
|
|
|
|
|
|
|
|
|
|
visit instructeur_procedure_path(procedure, params: { statut: 'tous' })
|
|
|
|
|
click_on litteraire_user.email
|
|
|
|
|
click_on 'Suivre le dossier'
|
|
|
|
|
log_out
|
|
|
|
|
|
|
|
|
|
# scientifique_user updates its group
|
|
|
|
|
user_update_group(scientifique_user, 'littéraire')
|
|
|
|
|
|
|
|
|
|
# the instructeurs who belong to scientifique AND litteraire groups should have a notification
|
|
|
|
|
visit new_user_session_path
|
2023-07-10 14:55:20 +02:00
|
|
|
|
sign_in_with alain.user.email, password
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
|
|
|
|
expect(page).to have_current_path(instructeur_procedures_path)
|
|
|
|
|
expect(find('.procedure-stats')).to have_css('span.notifications')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def publish_procedure(procedure)
|
|
|
|
|
click_on procedure.libelle
|
|
|
|
|
find('#publish-procedure-link').click
|
|
|
|
|
fill_in 'lien_site_web', with: 'http://some.website'
|
2023-10-10 16:51:06 +02:00
|
|
|
|
within('form') { click_on 'Publier' }
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
2023-11-06 17:46:22 +01:00
|
|
|
|
expect(page).to have_text('Votre démarche est désormais publiée !')
|
2023-03-30 12:31:48 +02:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def user_send_dossier(user, groupe)
|
|
|
|
|
login_as user, scope: :user
|
|
|
|
|
visit commencer_path(path: procedure.reload.path)
|
|
|
|
|
click_on 'Commencer la démarche'
|
|
|
|
|
|
2023-09-05 14:42:56 +02:00
|
|
|
|
find('label', text: 'Monsieur').click
|
2023-11-23 16:38:01 +01:00
|
|
|
|
fill_in('Prénom', with: 'prenom', visible: true)
|
|
|
|
|
fill_in('Nom', with: 'Nom', visible: true)
|
2024-04-12 17:59:50 +02:00
|
|
|
|
within "#identite-form" do
|
|
|
|
|
click_button('Continuer')
|
|
|
|
|
end
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
|
|
|
|
# the old system should not be present
|
|
|
|
|
expect(page).not_to have_selector("#dossier_groupe_instructeur_id")
|
|
|
|
|
|
2024-06-07 09:54:21 +02:00
|
|
|
|
dossier = user.dossiers.first
|
|
|
|
|
|
|
|
|
|
expect(dossier.groupe_instructeur_id).to be_nil
|
|
|
|
|
expect(page).to have_text(procedure.service.nom)
|
|
|
|
|
|
2023-03-30 12:31:48 +02:00
|
|
|
|
choose(groupe)
|
|
|
|
|
wait_for_autosave
|
|
|
|
|
|
2024-06-07 09:54:21 +02:00
|
|
|
|
expect(dossier.reload.groupe_instructeur_id).not_to be_nil
|
|
|
|
|
expect(page).to have_text(dossier.service.nom)
|
|
|
|
|
expect(page).not_to have_text(procedure.service.nom)
|
|
|
|
|
|
2023-03-30 12:31:48 +02:00
|
|
|
|
click_on 'Déposer le dossier'
|
|
|
|
|
expect(page).to have_text('Merci')
|
|
|
|
|
|
|
|
|
|
log_out
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def user_update_group(user, new_group)
|
|
|
|
|
login_as user, scope: :user
|
|
|
|
|
visit dossiers_path
|
2023-07-10 14:55:20 +02:00
|
|
|
|
click_on user.dossiers.first.procedure.libelle
|
2023-03-30 12:31:48 +02:00
|
|
|
|
click_on "Modifier mon dossier"
|
|
|
|
|
|
|
|
|
|
choose(new_group)
|
2023-08-29 15:47:28 +02:00
|
|
|
|
wait_for_autosave
|
2023-03-30 12:31:48 +02:00
|
|
|
|
|
|
|
|
|
expect(page).to have_text(new_group)
|
|
|
|
|
|
2023-03-21 18:24:39 +01:00
|
|
|
|
click_on 'Déposer les modifications'
|
|
|
|
|
|
2023-03-30 12:31:48 +02:00
|
|
|
|
log_out
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def register_instructeur_and_log_in(email)
|
2024-06-25 15:56:37 +02:00
|
|
|
|
confirmation_email = emails_sent_to(email).reverse
|
|
|
|
|
.find { |m| m.subject.starts_with?('Vous avez été ajouté(e) au groupe') }
|
2023-03-30 12:31:48 +02:00
|
|
|
|
token_params = confirmation_email.body.match(/token=[^"]+/)
|
|
|
|
|
|
|
|
|
|
visit "users/activate?#{token_params}"
|
|
|
|
|
fill_in :user_password, with: password
|
|
|
|
|
click_button 'Définir le mot de passe'
|
|
|
|
|
|
|
|
|
|
expect(page).to have_text('Mot de passe enregistré')
|
|
|
|
|
end
|
2023-04-26 17:29:47 +02:00
|
|
|
|
|
|
|
|
|
def steps_to_routing_configuration
|
|
|
|
|
login_as administrateur.user, scope: :user
|
|
|
|
|
visit admin_procedure_path(procedure.id)
|
|
|
|
|
find('#groupe-instructeurs').click
|
|
|
|
|
|
|
|
|
|
click_on 'Options'
|
|
|
|
|
expect(page).to have_text('Options concernant l’instruction')
|
|
|
|
|
click_on 'Configurer le routage'
|
|
|
|
|
expect(page).to have_text('Choix du type de routage')
|
|
|
|
|
end
|
2023-03-30 12:31:48 +02:00
|
|
|
|
end
|