From 65221f247ceee734a342c927ad606d7e134135be Mon Sep 17 00:00:00 2001 From: root Date: Mon, 3 May 2021 13:43:11 +0200 Subject: [PATCH 01/21] =?UTF-8?q?test=20des=20fonctions=20li=C3=A9=20aux?= =?UTF-8?q?=20abs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scotests/test_absence.py | 184 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100755 scotests/test_absence.py diff --git a/scotests/test_absence.py b/scotests/test_absence.py new file mode 100755 index 00000000..7a9bf95d --- /dev/null +++ b/scotests/test_absence.py @@ -0,0 +1,184 @@ +""" creation de 10 étudiants, formation, semestre, ue, module, absences le matin, l'apres midi, la journée compléte et justification +d'absences, supression d'absences, création d'une liste etat absences, creation d'un groupe afin de tester la fonction EtatAbsencesGroupes + +Fonctions de l'API utilisé : + - doSignaleAbsence + - doAnnuleAbsence + - doJustifAbsence + - getAbsSemEtud + - get_partition_groups + - get_partitions_list + - CountAbs + - CountAbsJust + - ListeAbsEtud + - partition_create + - createGroup + - set_group + + """ + + +import random + +# La variable context est définie par le script de lancement +# l'affecte ainsi pour évietr les warnins pylint: +context = context # pylint: disable=undefined-variable +REQUEST = REQUEST # pylint: disable=undefined-variable +import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error +import sco_abs +import sco_abs_views +import sco_abs_notification + +G = sco_fake_gen.ScoFake(context.Notes) +G.verbose = False + +# --- Création d'étudiants +etuds = [G.create_etud(code_nip=None) for _ in range(10)] + +# --- Création d'une formation +f = G.create_formation(acronyme="") +ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test") +mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test") +mod = G.create_module( + matiere_id=mat["matiere_id"], + code="TSM1", + coefficient=1.0, + titre="module test", + ue_id=ue["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + +# --- Mise place d'un semestre +sem = G.create_formsemestre( + formation_id=f["formation_id"], + semestre_id=1, + date_debut="01/01/2021", + date_fin="30/06/2021", +) + +mi = G.create_moduleimpl( + module_id=mod["module_id"], + formsemestre_id=sem["formsemestre_id"], + responsable_id="bach", +) + +# --- Inscription des étudiants +for etud in etuds: + G.inscrit_etudiant(sem, etud) + + +# --- Saisie absences +etudid = etuds[0]["etudid"] + +_ = sco_abs_views.doSignaleAbsence( + context.Absences, + "15/01/2021", + "15/01/2021", + demijournee=1, + etudid=etudid, + REQUEST=REQUEST, +) + +_ = sco_abs_views.doSignaleAbsence( + context.Absences, + "18/01/2021", + "18/01/2021", + demijournee=0, + etudid=etudid, + REQUEST=REQUEST, +) + +_ = sco_abs_views.doSignaleAbsence( + context.Absences, + "19/01/2021", + "19/01/2021", + demijournee=2, + etudid=etudid, + REQUEST=REQUEST, +) + +_ = sco_abs_views.doSignaleAbsence( + context.Absences, + "22/01/2021", + "22/01/2021", + demijournee=1, + etudid=etudid, + REQUEST=REQUEST, +) + +# --- Justification de certaines absences + +_ = sco_abs_views.doJustifAbsence( + context.Absences, + "15/01/2021", + "15/01/2021", + demijournee=1, + etudid=etudid, + REQUEST=REQUEST, +) + +_ = sco_abs_views.doJustifAbsence( + context.Absences, + "18/01/2021", + "18/01/2021", + demijournee=0, + etudid=etudid, + REQUEST=REQUEST, +) + +_ = sco_abs_views.doJustifAbsence( + context.Absences, + "19/01/2021", + "19/01/2021", + demijournee=2, + etudid=etudid, + REQUEST=REQUEST, +) + +# --- Test + +b = sco_abs.is_work_saturday(context.Absences) +assert b == 0 #samedi ne sont pas compris +a = sco_abs.getAbsSemEtud(context.Absences, sem, etudid) +assert a.CountAbs() == 5 #l'étudiant a été absent le 15 (apres midi) , (16 et 17 we), 18 (matin) et 19 janvier (matin et apres midi), et 22 (matin) +assert a.CountAbsJust() == 4 #l'étudiant justifie ses abs du 15, 18 et 19 + + +# + vérification à l'aide de ScoDoc WEB : ok! + +# --- Supression d'une absence et d'une justification + +_ = sco_abs_views.doAnnuleAbsence(context.Absences, "19/01/2021", "19/01/2021", 2, etudid=etudid, REQUEST=REQUEST) +a = sco_abs.getAbsSemEtud(context.Absences, sem, etudid) +print(a.CountAbs()) #lors du print cela affiche 5 or cela devrait afficher 3 + +#assert a.CountAbs() == 3 +# + vérification à l'aide de ScoDoc WEB : il y a bien plus que 3 abs, 2 justifiés et 1 non justifié. + + + +# --- supression d'une justification pas encore disponible à l'aide de python. + + +# --- Création d'une liste d'abs + +liste_abs = sco_abs_views.ListeAbsEtud(context.Absences, etudid, format='text', REQUEST=REQUEST) +print(liste_abs) +#toutes les absences figurent (bien evidemment pas celle qui a été supprimé alors pq CountAbs indique toujours le même nombre d'abs) + +# --- Création d'un groupe + +_ = sco_groups.partition_create(context.Scolarite, formsemestre_id=sem["formsemestre_id"], partition_name="Eleve", REQUEST=REQUEST) +li1 = sco_groups.get_partitions_list(context.Scolarite, sem["formsemestre_id"]) +_ = sco_groups.createGroup(context.Scolarite, li1[0]["partition_id"], "Groupe 1", REQUEST=REQUEST) + +# --- Affectation des élèves dans des groupes + +li_grp1 = sco_groups.get_partition_groups(context.Scolarite, li1[0]) +for etud in etuds : + sco_groups.set_group(context.Scolarite, etud["etudid"], li_grp1[0]["group_id"]) + +# --- Test de EtatAbsencesGroupes + +# Fonction introuvable. + From 34e34b188ce3ed381df44ab04c9eeeb72f7107db Mon Sep 17 00:00:00 2001 From: root Date: Mon, 3 May 2021 14:29:40 +0200 Subject: [PATCH 02/21] =?UTF-8?q?test=20bas=C3=A9=20sur=20les=20groupes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scotests/test_groupes.py | 385 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 385 insertions(+) create mode 100755 scotests/test_groupes.py diff --git a/scotests/test_groupes.py b/scotests/test_groupes.py new file mode 100755 index 00000000..8ffa5d60 --- /dev/null +++ b/scotests/test_groupes.py @@ -0,0 +1,385 @@ +""" 1) Création de 20 étudiants, création d’une formation, inscription de 10 étudiants dans un semestre (1ere année), + 10 dans un autre (2eme année), création de module, ue, + matière et affectation des étudiants dans deux groupes : A et B pour chaque semestre. + créer 2 évaluations, + affecter des notes dans chaque évaluation et donner la liste des étudiants inscrits à l’évaluation pour chaque groupe. + Donner la liste des groupes auxquels des étudiants inscrits appartiennent à cette évaluation. + Pour une raison quelquonque un élève souhaite changer de groupe. + Changer le nom d'un groupe et d'une partition (à l'aide de fonction) + + + +- Vérification du bon nombres d’étudiants dans chaque chaque groupe (5) + +- Vérification des noms de la formations (acro = DUTI, titre = DUT Info, titre_officiel = DUT Informatique), + UE (acr = UE11/UE31, titre = UE1S1/UE1S3), modules (code = M1S1/M1S3, titre = mod1/mod2), matières (ue_id=ue1/2[ue_id], titre = mat1/mat2) + +- Vérification des listes de groupes et de partitions + +- Vérification du changement de groupe des étudiants + +- Teste d'autres fonctions de l'API correspondant aux groupes + +Fonctions de l’API utilisé : + - create_formation + - create_ue + - create_module + - create_matiere + - create_formsemestre + - create_moduleimpl + - inscrit_etudiant + - partition_create + - get_default_partition + - createGroupe + - partition_create + - get_partitions_list + - get_partition_groups + - set_group + - get_etud_groups + - change_etud_group_in_partition + - get_group + - group_delete + - get_partition + - get_default_group + - get_default_partition + - get_sem_groups + - get_group_members + - do_evaluation_listeetuds_groups + - do_evaluation_listegroupes + - formsemestre_partition_list + +""" + +import random + +# La variable context est définie par le script de lancement +# l'affecte ainsi pour évietr les warnins pylint: +context = context # pylint: disable=undefined-variable +REQUEST = REQUEST # pylint: disable=undefined-variable +import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error +import sco_groups + + +G = sco_fake_gen.ScoFake(context.Notes) +G.verbose = False + +# --- Création d'étudiants +etuds = [G.create_etud(code_nip=None) for _ in range(20)] +assert len(etuds) == 20 + +# --- Création d'une formation + +f = G.create_formation( + acronyme="DUTI", + titre="DUT Info", + titre_officiel="DUT Informatique", + ) + +assert f["acronyme"]=="DUTI" +assert f["titre"]=="DUT Info" +assert f["titre_officiel"]=="DUT Informatique" + + +# --- Création d'UE, matière, module pour les premieres années + +ue1 = G.create_ue(formation_id=f["formation_id"], acronyme="UE11", titre="UE1S1") + +mat1 = G.create_matiere(ue_id=ue1["ue_id"], titre="mat1") +mod1 = G.create_module( + matiere_id=mat1["matiere_id"], + code="M1S1", + coefficient=1.0, + titre="mod1", + ue_id=ue1["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + +assert ue1["formation_id"] == f["formation_id"] +assert ue1["acronyme"]=="UE11" +assert ue1["titre"]=="UE1S1" + +assert mod1["matiere_id"]==mat1["matiere_id"] +assert mod1["code"]=="M1S1" +assert mod1["titre"]=="mod1" +assert mod1["ue_id"]==ue1["ue_id"] +assert mod1["formation_id"]==f["formation_id"] + +# --- Création d'UE, matière, module pour les deuxieme années + +ue2 = G.create_ue(formation_id=f["formation_id"], acronyme="UE31", titre="UE1S1") + +mat2 = G.create_matiere(ue_id=ue2["ue_id"], titre="mat2") +mod2 = G.create_module( + matiere_id=mat2["matiere_id"], + code="M1S3", + coefficient=1.0, + titre="mod2", + ue_id=ue2["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + +# --- Mise place des semestres + +sem1 = G.create_formsemestre( + formation_id=f["formation_id"], + semestre_id=1, + date_debut="01/09/2020", + date_fin="01/02/2021", +) + +assert sem1["formation_id"]==f["formation_id"] +assert sem1["semestre_id"]==1 +assert sem1["date_debut"]=="01/09/2020" +assert sem1["date_fin"]=="01/02/2021" + +sem2 = G.create_formsemestre( + formation_id=f["formation_id"], + semestre_id=2, + date_debut="01/09/2020", + date_fin="01/02/2021", +) + + +mi1 = G.create_moduleimpl( + module_id=mod1["module_id"], + formsemestre_id=sem1["formsemestre_id"], + responsable_id="bach", +) + +assert mi1["module_id" ]==mod1["module_id"] +assert mi1["formsemestre_id"]==sem1["formsemestre_id"] +assert mi1["responsable_id"]=="bach" + +mi2 = G.create_moduleimpl( + module_id=mod2["module_id"], + formsemestre_id=sem2["formsemestre_id"], + responsable_id="bach", +) + + +# --- Inscription des étudiants + +for etud in etuds[:10] : + G.inscrit_etudiant(sem1, etud) + +for etud in etuds [10:] : + G.inscrit_etudiant(sem2, etud) + +# --- Création de 2 partitions + +_ = sco_groups.partition_create(context.Scolarite, formsemestre_id=sem1["formsemestre_id"], partition_name="Eleve 1ere annee", REQUEST=REQUEST) +_ = sco_groups.partition_create(context.Scolarite, formsemestre_id=sem2["formsemestre_id"], partition_name="Eleve 2eme annee", REQUEST=REQUEST) + + +li1 = sco_groups.get_partitions_list(context.Scolarite, sem1["formsemestre_id"]) +li2 = sco_groups.get_partitions_list(context.Scolarite, sem2["formsemestre_id"]) + + +# --- Création des groupes + +_ = sco_groups.createGroup(context.Scolarite, li1[0]["partition_id"], "Groupe S1A", REQUEST=REQUEST) +_ = sco_groups.createGroup(context.Scolarite, li1[0]["partition_id"], "Groupe S1B", REQUEST=REQUEST) +_ = sco_groups.createGroup(context.Scolarite, li2[0]["partition_id"], "Groupe S3A", REQUEST=REQUEST) +_ = sco_groups.createGroup(context.Scolarite, li2[0]["partition_id"], "Groupe S3B", REQUEST=REQUEST) +_ = sco_groups.createGroup(context.Scolarite, li2[0]["partition_id"], "Groupe TEST", REQUEST=REQUEST) + +li_grp1 = sco_groups.get_partition_groups(context.Scolarite, li1[0]) +li_grp2 = sco_groups.get_partition_groups(context.Scolarite, li2[0]) +li_grp3 = sco_groups.get_partition_groups(context.Scolarite, li1[1]) #liste groupe defaut + +assert len(li_grp1) == 2 #test de get_partition_groups # 2 +assert len(li_grp2) == 3 #test de get_partition_groups # 3 +assert li_grp1[0]["group_name"] == "Groupe S1A" + + +# --- Affectation des élèves dans les groupes + +for etud in etuds[:5] : + sco_groups.set_group(context.Scolarite, etud["etudid"], li_grp1[0]["group_id"]) + +for etud in etuds[5:10] : + sco_groups.set_group(context.Scolarite, etud["etudid"], li_grp1[1]["group_id"]) + +for etud in etuds[10:15] : + sco_groups.set_group(context.Scolarite, etud["etudid"], li_grp2[0]["group_id"]) + +for etud in etuds[15:] : + sco_groups.set_group(context.Scolarite, etud["etudid"], li_grp2[1]["group_id"]) + +# --- Vérification si les élèves sont bien dans les bons groupes + +for etud in etuds[:5] : + grp = sco_groups.get_etud_groups(context.Scolarite, etud["etudid"], sem1, exclude_default=True) + assert grp[0]["group_name"] == "Groupe S1A" + +for etud in etuds[5:10] : + grp = sco_groups.get_etud_groups(context.Scolarite, etud["etudid"], sem1, exclude_default=True) + assert grp[0]["group_name"] == "Groupe S1B" + +for etud in etuds[10:15] : + grp = sco_groups.get_etud_groups(context.Scolarite, etud["etudid"], sem2, exclude_default=True) + assert grp[0]["group_name"] == "Groupe S3A" + +for etud in etuds[15:] : + grp = sco_groups.get_etud_groups(context.Scolarite, etud["etudid"], sem2, exclude_default=True) + assert grp[0]["group_name"] == "Groupe S3B" + +# --- Création d'une évaluation + +e1 = G.create_evaluation( + moduleimpl_id=mi1["moduleimpl_id"], + jour="01/10/2020", + description="evaluation test", + coefficient=1.0, +) + +e2 = G.create_evaluation( + moduleimpl_id=mi2["moduleimpl_id"], + jour="01/11/2020", + description="evaluation test2", + coefficient=1.0, +) + +# --- Saisie des notes + +for etud in etuds[10:] : + nb_changed, nb_suppress, existing_decisions = G.create_note( + evaluation=e1, etud=etud, note=float(random.randint(0, 20)) + ) + + +for etud in etuds[:10] : + nb_changed, nb_suppress, existing_decisions = G.create_note( + evaluation=e2, etud=etud, note=float(random.randint(0, 20)) + ) + +# --- Liste des étudiants inscrits aux evaluations + +lie1 = sco_groups.do_evaluation_listeetuds_groups(context.Scolarite, e1["evaluation_id"], groups = li_grp1) +lie2 = sco_groups.do_evaluation_listeetuds_groups(context.Scolarite, e2["evaluation_id"], groups = li_grp2) + +for etud in etuds[:10] : + assert etud["etudid"] in lie1 # test de do_evaluation_listeetuds_groups + +for etud in etuds[10:] : + assert etud["etudid"] in lie2 # test de do_evaluation_listeetuds_groups + + +# --- Liste des groupes présents aux évaluation + +lig1 = sco_groups.do_evaluation_listegroupes(context.Scolarite, e1["evaluation_id"], include_default=False) +lig2 = sco_groups.do_evaluation_listegroupes(context.Scolarite, e2["evaluation_id"], include_default=False) + + +assert len(lig1) == 2 +assert len(lig2) == 2 +assert li_grp1[0] and li_grp1[1] in lig1 # test do_evaluation_listegroupes +assert li_grp2[0] and li_grp2[1] in lig2 # test do_evaluation_listegroupes + + + +# --- Changement de groupe d'un élève + +grp1 = sco_groups.get_etud_groups(context.Scolarite, etuds[0]["etudid"], sem1, exclude_default = True) +sco_groups.change_etud_group_in_partition(context.Scolarite, etuds[0]["etudid"], li_grp1[1]["group_id"], li1[0], REQUEST=REQUEST) +grp2 = sco_groups.get_etud_groups(context.Scolarite, etuds[0]["etudid"], sem1, exclude_default = True) +assert grp1 != grp2 +assert grp1[0] == li_grp1[0] # test get_etud_groups +assert grp2[0]["group_name"] == "Groupe S1B" #test du changement de groupe + + +# --- Liste des partitions en format json + +lijson_s1 = sco_groups.formsemestre_partition_list(context.Scolarite, formsemestre_id=sem1["formsemestre_id"], format = "json", REQUEST=REQUEST) +load_lijson_s1 = json.loads(lijson_s1) + +assert len(load_lijson_s1) == 2 # 2 partition (defaut et eleve 1ere annee) +assert load_lijson_s1[0]["formsemestre_id"] == sem1["formsemestre_id"] +assert len(load_lijson_s1[0]["group"]) == 2 # 2 groupes S1A et S1B +assert load_lijson_s1[0]["group"][0]["group_name"] == "Groupe S1A" +assert load_lijson_s1[0]["group"][0]["group_id"] == li_grp1[0]["group_id"] +assert load_lijson_s1[0]["partition_id"] == load_lijson_s1[0]["group"][0]["partition_id"] == li1[0]["partition_id"] +assert load_lijson_s1[0]["partition_name"] == "Eleve 1ere annee" + + + +# --- Vue d'un groupes (liste d'élève en format json ou xml) + + + + + + +# --- Test des fonctions dans sco_groups + +#_ = sco_groups.checkGroupName(li_grp1[0]["group_name"]) +#_ = sco_groups.checkGroupName("Groupe S1B") +#_ = sco_groups.checkGroupName("Groupe S3A") +#_ = sco_groups.checkGroupName("Groupe S3B") + +assert li_grp1[0] == sco_groups.get_group(context.Scolarite, li_grp1[0]["group_id"]) #test get_group + +assert len(li_grp2) == 3 +sco_groups.group_delete(context.Scolarite, li_grp2[2]) +#assert len(li_grp2) == 2 #TESTE DE group_delete, aucun changement sur la console mais se supprime sur scodoc web + # mais pas dans la console comme pour countAbs() + +assert sco_groups.get_partition(context.Scolarite, li1[0]["partition_id"])== li1[0] # test de get_partition +assert sco_groups.get_partition(context.Scolarite, li2[0]["partition_id"])== li2[0] # test de get_partition + + + +li1 = sco_groups.get_partitions_list(context.Scolarite, sem1["formsemestre_id"]) +#assert p1 in li1 #test de get_partitions_list +assert len(li1) == 2 #eleve de 1ere annee + la partition defaut + +li2 = sco_groups.get_partitions_list(context.Scolarite, sem2["formsemestre_id"]) +#assert p2 in li2 #test de get_partitions_list +assert len(li2) == 2 #eleve de 2eme annee + la partition defaut + + +dp1 = sco_groups.get_default_partition(context.Scolarite, sem1["formsemestre_id"]) +dp2 = sco_groups.get_default_partition(context.Scolarite, sem2["formsemestre_id"]) + +assert dp1 in li1 # test si dp1 est bien dans li1 et par consequent teste la fonction get_default_partition +assert dp2 in li2 # test si dp2 est bien dans li1 et par consequent teste la fonction get_default_partition + + +dg1 = sco_groups.get_default_group(context.Scolarite, sem1["formsemestre_id"], REQUEST=REQUEST) +assert li_grp3[0]["group_id"] == dg1 #test de get_default_group + + +sg = sco_groups.get_sem_groups(context.Scolarite, sem1["formsemestre_id"]) +assert len(sg) == 3 #test de get_sem_groups +assert li_grp1[0] and li_grp1[1] in sg +assert li_grp3[0] in sg # test de get_sem_groups + +limembre = sco_groups.get_group_members(context.Scolarite, li_grp1[0]["group_id"]) +assert len(limembre) == 4 # car on a changé de groupe un etudiant de ce groupe donc 5-1=4 + + + +# --- Changement de nom des partitions, groupes + +# Le changement de nom des groupes et des partitions n'est pas possible en python car la fonction est une fonction d'envoie de formulaire. + + + + + + + + + + + + + + + + + + + + + From 699b482c30510c07c30aa3daf2d3f580a91fa069 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 3 May 2021 14:57:58 +0200 Subject: [PATCH 03/21] mini test parametre demijournee --- scotests/test_abs_demijournee.py | 106 +++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100755 scotests/test_abs_demijournee.py diff --git a/scotests/test_abs_demijournee.py b/scotests/test_abs_demijournee.py new file mode 100755 index 00000000..14c86b45 --- /dev/null +++ b/scotests/test_abs_demijournee.py @@ -0,0 +1,106 @@ +import random + +# La variable context est définie par le script de lancement +# l'affecte ainsi pour évietr les warnins pylint: +context = context # pylint: disable=undefined-variable +REQUEST = REQUEST # pylint: disable=undefined-variable +import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error +import sco_abs +import sco_abs_views +import sco_abs_notification + +G = sco_fake_gen.ScoFake(context.Notes) +G.verbose = False + +# --- Création d'étudiants +etud = G.create_etud(code_nip=None) + +# --- Création d'une formation +f = G.create_formation(acronyme="") +ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test") +mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test") +mod = G.create_module( + matiere_id=mat["matiere_id"], + code="TSM1", + coefficient=1.0, + titre="module test", + ue_id=ue["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + +# --- Mise place d'un semestre +sem = G.create_formsemestre( + formation_id=f["formation_id"], + semestre_id=1, + date_debut="01/01/2021", + date_fin="30/06/2021", +) + +mi = G.create_moduleimpl( + module_id=mod["module_id"], + formsemestre_id=sem["formsemestre_id"], + responsable_id="bach", +) + +# --- Inscription des étudiants +G.inscrit_etudiant(sem, etud) + + +# --- Saisie absences +etudid = etud["etudid"] + +_ = sco_abs_views.doSignaleAbsence( + context.Absences, + "15/01/2021", + "15/01/2021", + demijournee=2, + etudid=etudid, + REQUEST=REQUEST, +) + + +_ = sco_abs_views.doSignaleAbsence( + context.Absences, + "18/01/2021", + "18/01/2021", + demijournee=1, + etudid=etudid, + REQUEST=REQUEST, +) + +_ = sco_abs_views.doSignaleAbsence( + context.Absences, + "19/01/2021", + "19/01/2021", + demijournee=0, + etudid=etudid, + REQUEST=REQUEST, +) + +# --- Justification de certaines absences + +_ = sco_abs_views.doJustifAbsence( + context.Absences, + "18/01/2021", + "18/01/2021", + demijournee=1, + etudid=etudid, + REQUEST=REQUEST, +) + +_ = sco_abs_views.doJustifAbsence( + context.Absences, + "19/01/2021", + "19/01/2021", + demijournee=2, + etudid=etudid, + REQUEST=REQUEST, +) + +# NE JUSTIFIE QUE LE MATIN MALGRES LE PARAMETRE demijournee = 2 + +# --- Test + +a = sco_abs.getAbsSemEtud(context.Absences, sem, etudid) +assert a.CountAbs() == 4 #l'étudiant a été absent le 15 journée compléte (2 abs : 1 matin, 1 apres midi) et le 18 (1 matin), et le 19 (1 apres midi). +assert a.CountAbsJust() == 2 # Justifie abs du matin + abs après midi \ No newline at end of file From 600016d1e0118000c94cc4f9327336316de45e48 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 18 May 2021 11:31:39 +0200 Subject: [PATCH 04/21] ajout de nouveaux tests --- scotests/export_formation1.xml | 205 ++++ scotests/formation_export.json | 1352 +++++++++++++++++++++ scotests/test_absence.py | 50 +- scotests/test_create_etud.py | 47 + scotests/test_etudiant1.py | 98 ++ scotests/test_evaluation.py | 235 ++++ scotests/test_evaluation_suppress_alln.py | 70 ++ scotests/test_formations.py | 321 +++++ scotests/test_groupes.py | 25 +- scotests/test_scenario1_app.py | 117 ++ scotests/test_scenario1_formation.py | 72 ++ scotests/test_scenario2_formation.py | 105 ++ scotests/test_scenario3_formation.py | 135 ++ scotests/test_scenario4_formation.py | 172 +++ scotests/test_user.py | 49 + static/formation_export.json | 1352 +++++++++++++++++++++ 16 files changed, 4395 insertions(+), 10 deletions(-) create mode 100755 scotests/export_formation1.xml create mode 100755 scotests/formation_export.json create mode 100755 scotests/test_create_etud.py create mode 100755 scotests/test_etudiant1.py create mode 100755 scotests/test_evaluation.py create mode 100755 scotests/test_evaluation_suppress_alln.py create mode 100755 scotests/test_formations.py create mode 100755 scotests/test_scenario1_app.py create mode 100755 scotests/test_scenario1_formation.py create mode 100755 scotests/test_scenario2_formation.py create mode 100755 scotests/test_scenario3_formation.py create mode 100755 scotests/test_scenario4_formation.py create mode 100755 scotests/test_user.py create mode 100755 static/formation_export.json diff --git a/scotests/export_formation1.xml b/scotests/export_formation1.xml new file mode 100755 index 00000000..8baf7a6b --- /dev/null +++ b/scotests/export_formation1.xml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scotests/formation_export.json b/scotests/formation_export.json new file mode 100755 index 00000000..1c13dc0b --- /dev/null +++ b/scotests/formation_export.json @@ -0,0 +1,1352 @@ +{ + "acronyme": "DUT Info", + "code_specialite": "", + "type_parcours": 100, + "titre_officiel": "DUT Informatique", + "formation_code": "FCOD2", + "version": 1, + "ue": [ + { + "acronyme": "UE11", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Architecture mat\u00e9rielle - Syst\u00e8mes d\u2019exploitation - R\u00e9seaux", + "module": [ + { + "coefficient": 2.0, + "code": "M1101", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 30.0, + "abbrev": "", + "numero": 1, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Introduction aux syst\u00e8mes informatiques", + "heures_td": 20.0 + } + ], + "numero": 1 + }, + { + "titre": "Algorithmique - Programmation - Langages", + "module": [ + { + "coefficient": 2.0, + "code": "M1102", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 30.0, + "abbrev": "Algorithmique", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Introduction \u00e0 l\u2019algorithmique et \u00e0 la programmation", + "heures_td": 20.0 + } + ], + "numero": 2 + }, + { + "titre": "Algorithmique - Programmation - Langages Avanc\u00e9", + "module": [ + { + "coefficient": 2.0, + "code": "M1103", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 20.0, + "abbrev": "Structure de donn\u00e9es", + "numero": 3, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Structure de donn\u00e9es et algorithmes fondamentaux", + "heures_td": 15.0 + } + ], + "numero": 3 + }, + { + "titre": "Syst\u00e8mes de gestion de bases de donn\u00e9es", + "module": [ + { + "coefficient": 3.0, + "code": "M1104", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 25.0, + "abbrev": "BDD", + "numero": 4, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Introduction aux bases de donn\u00e9es", + "heures_td": 25.0 + } + ], + "numero": 4 + }, + { + "titre": "Web - Internet - Mobilit\u00e9 Expression - Communication", + "module": [ + { + "coefficient": 2.0, + "code": "M1105", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 25.0, + "abbrev": "CDIN", + "numero": 5, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Conception de documents et d\u2019interfaces num\u00e9riques", + "heures_td": 20.0 + } + ], + "numero": 5 + }, + { + "titre": "Projets tutor\u00e9s", + "module": [ + { + "coefficient": 3.0, + "code": "M1106", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "Projet", + "numero": 6, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Projet tutor\u00e9 : d\u00e9couverte", + "heures_td": 0.0 + } + ], + "numero": 6 + } + ], + "ue_code": "UE11", + "numero": 1, + "titre": "Base de l'informatique", + "type": 0 + }, + { + "acronyme": "UE21", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Architecture mat\u00e9rielle - Syst\u00e8mes d\u2019exploitation - R\u00e9seaux", + "module": [ + { + "coefficient": 2.0, + "code": "M2101", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Architecture et Programmation des m\u00e9canismes de base d\u2019un syst\u00e8me informatique", + "heures_td": 10.0 + } + ], + "numero": 1 + }, + { + "titre": "Architecture mat\u00e9rielle - Syst\u00e8mes d\u2019exploitation - R\u00e9seaux avanc\u00e9", + "module": [ + { + "coefficient": 2.0, + "code": "M2102", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Architecture des r\u00e9seaux", + "heures_td": 10.0 + } + ], + "numero": 2 + }, + { + "titre": "Algorithmique - Programmation - Langages Analyse, conception et d\u00e9veloppement d\u2019applications", + "module": [ + { + "coefficient": 2.0, + "code": "M2103", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 30.0, + "abbrev": "", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Bases de la programmation orient\u00e9e objet", + "heures_td": 20.0 + } + ], + "numero": 3 + }, + { + "titre": "Analyse, conception et d\u00e9veloppement d\u2019applications", + "module": [ + { + "coefficient": 2.0, + "code": "M2104", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 20.0, + "abbrev": "COO", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Bases de la conception orient\u00e9e objet", + "heures_td": 15.0 + } + ], + "numero": 4 + }, + { + "titre": "Interface homme-machine", + "module": [ + { + "coefficient": 2.0, + "code": "M2105", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 20.0, + "abbrev": "", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Introduction aux interfaces homme-machine", + "heures_td": 15.0 + } + ], + "numero": 5 + }, + { + "titre": "Syst\u00e8mes de gestion de bases de donn\u00e9es", + "module": [ + { + "coefficient": 2.0, + "code": "M2106", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 20.0, + "abbrev": "", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Programmation et administration des bases de donn\u00e9es", + "heures_td": 15.0 + } + ], + "numero": 6 + }, + { + "titre": "Projets tutor\u00e9s", + "module": [ + { + "coefficient": 3.0, + "code": "M2107", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Projet tutor\u00e9 : Description et planification de projet", + "heures_td": 0.0 + } + ], + "numero": 7 + } + ], + "ue_code": "UE21", + "numero": 1, + "titre": "Informatique approfondie", + "type": 0 + }, + { + "acronyme": "UE31", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Architectures mat\u00e9rielles - Syst\u00e8mes d\u2019exploitation - R\u00e9seaux", + "module": [ + { + "coefficient": 2.0, + "code": "M3101", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 16.0, + "abbrev": "", + "numero": 10, + "heures_cours": 15.0, + "module_type": 0, + "titre": "Principes des syst\u00e8mes d\u2019exploitation", + "heures_td": 14.0 + } + ], + "numero": 1 + }, + { + "titre": "Architectures mat\u00e9rielles - Syst\u00e8mes d\u2019exploitation, R\u00e9seaux", + "module": [ + { + "coefficient": 2.0, + "code": "M3102", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Services r\u00e9seaux", + "heures_td": 10.0 + } + ], + "numero": 2 + }, + { + "titre": "Algorithmique - Programmation - Langages avanc\u00e9", + "module": [ + { + "coefficient": 2.0, + "code": "M3103", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Algorithmique avanc\u00e9e", + "heures_td": 10.0 + } + ], + "numero": 3 + }, + { + "titre": "Web - Internet - Mobilit\u00e9", + "module": [ + { + "coefficient": 2.0, + "code": "M3104", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 16.0, + "abbrev": "", + "numero": 10, + "heures_cours": 15.0, + "module_type": 0, + "titre": "Programmation Web c\u00f4t\u00e9 serveur", + "heures_td": 14.0 + } + ], + "numero": 4 + }, + { + "titre": "Analyse, conception et d\u00e9veloppement d\u2019applications", + "module": [ + { + "coefficient": 16.0, + "code": "M3105", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 14.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Conception et programmation objet avanc\u00e9es", + "heures_td": 15.0 + } + ], + "numero": 5 + }, + { + "titre": "Syst\u00e8mes de gestion de bases de donn\u00e9es", + "module": [ + { + "coefficient": 2.0, + "code": "M3106C", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Bases de donn\u00e9es avanc\u00e9es", + "heures_td": 10.0 + } + ], + "numero": 6 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS1", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 16 + } + ], + "ue_code": "UCOD5", + "numero": 1, + "titre": "Informatique avanc\u00e9e", + "type": 0 + }, + { + "acronyme": "UE41", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Architectures mat\u00e9rielles - Syst\u00e8mes d\u2019exploitation - R\u00e9seaux", + "module": [ + { + "coefficient": 2.0, + "code": "M4101C", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Administration syst\u00e8me et r\u00e9seau", + "heures_td": 10.0 + } + ], + "numero": 1 + }, + { + "titre": "Architectures mat\u00e9rielles - Syst\u00e8mes d\u2019exploitation \u2013 R\u00e9seaux Analyse, conception et d\u00e9veloppement d\u2019applications", + "module": [ + { + "coefficient": 2.0, + "code": "M4102C", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Programmation r\u00e9partie", + "heures_td": 10.0 + } + ], + "numero": 2 + }, + { + "titre": "Web \u2013 Internet - Mobilit\u00e9", + "module": [ + { + "coefficient": 2.0, + "code": "M4103C", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Programmation Web \u2013 client riche", + "heures_td": 10.0 + } + ], + "numero": 3 + }, + { + "titre": "Web - Internet - Mobilit\u00e9 - Mobile", + "module": [ + { + "coefficient": 3.0, + "code": "M4104C", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Conception et d\u00e9veloppement d\u2019applications mobiles", + "heures_td": 10.0 + } + ], + "numero": 4 + }, + { + "titre": "Analyse, conception et d\u00e9veloppement d\u2019applications", + "module": [ + { + "coefficient": 2.0, + "code": "M4105C", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Compl\u00e9ments d\u2019informatique en vue d\u2019une insertion imm\u00e9diate", + "heures_td": 10.0 + } + ], + "numero": 5 + }, + { + "titre": "Projets tutor\u00e9s", + "module": [ + { + "coefficient": 3.0, + "code": "M4106", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Projet tutor\u00e9 \u2013 Compl\u00e9ments", + "heures_td": 0.0 + } + ], + "numero": 6 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS1", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 16 + } + ], + "ue_code": "UCOD8", + "numero": 1, + "titre": "Compl\u00e9ments en informatique", + "type": 0 + }, + { + "acronyme": "UE12", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Math\u00e9matiques", + "module": [ + { + "coefficient": 2.0, + "code": "M1201", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 17.0, + "abbrev": "", + "numero": 1, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Math\u00e9matiques discr\u00e8tes", + "heures_td": 18.0 + } + ], + "numero": 1 + }, + { + "titre": "Math\u00e9matiques avanc\u00e9es", + "module": [ + { + "coefficient": 2.0, + "code": "M1202", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 6.0, + "module_type": 0, + "titre": "Alg\u00e8bre lin\u00e9aire", + "heures_td": 12.0 + } + ], + "numero": 2 + }, + { + "titre": "\u00c9conomie - Gestion - Organisation - Droit", + "module": [ + { + "coefficient": 2.0, + "code": "M1203", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Environnement \u00e9conomique", + "heures_td": 10.0 + } + ], + "numero": 3 + }, + { + "titre": "Organisation", + "module": [ + { + "coefficient": 1.0, + "code": "M1204", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Fonctionnement des organisations", + "heures_td": 20.0 + } + ], + "numero": 4 + }, + { + "titre": "Expression - Communication", + "module": [ + { + "coefficient": 2.0, + "code": "M1205", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Fondamentaux de la communication", + "heures_td": 15.0 + } + ], + "numero": 5 + }, + { + "titre": "Anglais", + "module": [ + { + "coefficient": 2.0, + "code": "M1206", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Anglais et Informatique", + "heures_td": 15.0 + } + ], + "numero": 6 + }, + { + "titre": "PPP Expression - Communication", + "module": [ + { + "coefficient": 1.0, + "code": "M1207", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Conna\u00eetre le monde professionnel", + "heures_td": 10.0 + } + ], + "numero": 7 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS2", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 17 + } + ], + "ue_code": "UE12", + "numero": 2, + "titre": "Bases de culture scientifique, sociale et humaine", + "type": 0 + }, + { + "acronyme": "UE22", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Math\u00e9matiques", + "module": [ + { + "coefficient": 2.0, + "code": "M2201", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 18.0, + "abbrev": "", + "numero": 10, + "heures_cours": 11.0, + "module_type": 0, + "titre": "Graphes et langages", + "heures_td": 16.0 + } + ], + "numero": 1 + }, + { + "titre": "Math\u00e9matiques avanc\u00e9es", + "module": [ + { + "coefficient": 2.0, + "code": "M2202", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Analyse et m\u00e9thodes num\u00e9riques", + "heures_td": 12.0 + } + ], + "numero": 2 + }, + { + "titre": "\u00c9conomie - Gestion - Droit - Organisation", + "module": [ + { + "coefficient": 2.0, + "code": "M2203", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 12.0, + "module_type": 0, + "titre": "Environnement comptable, financier, juridique et social", + "heures_td": 18.0 + } + ], + "numero": 3 + }, + { + "titre": "\u00c9conomie - Gestion - Organisation - Droit Analyse, conception et d\u00e9veloppement d\u2019applications", + "module": [ + { + "coefficient": 2.0, + "code": "M2204", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Gestion de projet informatique", + "heures_td": 12.0 + } + ], + "numero": 4 + }, + { + "titre": "Expression - Communication", + "module": [ + { + "coefficient": 1.0, + "code": "M2205", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Communication, information et argumentation", + "heures_td": 15.0 + } + ], + "numero": 5 + }, + { + "titre": "Anglais", + "module": [ + { + "coefficient": 2.0, + "code": "M2206", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 22.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Communiquer en anglais", + "heures_td": 23.0 + } + ], + "numero": 6 + }, + { + "titre": "PPP", + "module": [ + { + "coefficient": 1.0, + "code": "M2207", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "PPP - Identifier ses comp\u00e9tences", + "heures_td": 10.0 + } + ], + "numero": 7 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS2", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 17 + } + ], + "ue_code": "UCOD4", + "numero": 2, + "titre": "Approfondissements en culture scientifique, sociale et humaine", + "type": 0 + }, + { + "acronyme": "UE32", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Math\u00e9matiques", + "module": [ + { + "coefficient": 2.0, + "code": "M3201", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 14.0, + "abbrev": "", + "numero": 10, + "heures_cours": 15.0, + "module_type": 0, + "titre": "Probabilit\u00e9s et statistique", + "heures_td": 16.0 + } + ], + "numero": 1 + }, + { + "titre": "Math\u00e9matiques avanc\u00e9es", + "module": [ + { + "coefficient": 2.0, + "code": "M3202C", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 14.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Mod\u00e9lisations math\u00e9matiques", + "heures_td": 16.0 + } + ], + "numero": 2 + }, + { + "titre": "\u00c9conomie - Gestion - Organisation - Droit", + "module": [ + { + "coefficient": 2.0, + "code": "M3203", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Droit des technologies de l\u2019information et de la communication", + "heures_td": 10.0 + } + ], + "numero": 3 + }, + { + "titre": "Gestion", + "module": [ + { + "coefficient": 2.0, + "code": "M3204", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 15.0, + "module_type": 0, + "titre": "Gestion des syst\u00e8mes d\u2019information", + "heures_td": 15.0 + } + ], + "numero": 4 + }, + { + "titre": "Expression - Communication", + "module": [ + { + "coefficient": 2.0, + "code": "M3205", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Communication professionnelle", + "heures_td": 15.0 + } + ], + "numero": 5 + }, + { + "titre": "Anglais", + "module": [ + { + "coefficient": 2.0, + "code": "M3206", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 22.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Collaborer en anglais", + "heures_td": 23.0 + } + ], + "numero": 6 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS2", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 16 + } + ], + "ue_code": "UCOD6", + "numero": 2, + "titre": "Culture scientifique, sociale et humaine avanc\u00e9es", + "type": 0 + }, + { + "acronyme": "UE33", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Analyse, conception et d\u00e9veloppement d\u2019applications \u00c9conomie - gestion - Organisation - Droit", + "module": [ + { + "coefficient": 2.0, + "code": "M3301", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 24.0, + "abbrev": "", + "numero": 10, + "heures_cours": 14.0, + "module_type": 0, + "titre": "M\u00e9thodologie de la production d\u2019applications", + "heures_td": 22.0 + } + ], + "numero": 1 + }, + { + "titre": "Projets tutor\u00e9s", + "module": [ + { + "coefficient": 3.0, + "code": "M3302", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Projet tutor\u00e9 - Mise en situation professionnelle", + "heures_td": 0.0 + } + ], + "numero": 2 + }, + { + "titre": "PPP", + "module": [ + { + "coefficient": 2.0, + "code": "M3303", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "PPP - Pr\u00e9ciser son projet", + "heures_td": 10.0 + } + ], + "numero": 3 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS2", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 13 + } + ], + "ue_code": "UCOD7", + "numero": 2, + "titre": "M\u00e9thodologie et projets", + "type": 0 + }, + { + "acronyme": "UE42", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "\u00c9conomie - Gestion - Organisation - Droit", + "module": [ + { + "coefficient": 2.0, + "code": "M4201C", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Ateliers de cr\u00e9ation d\u2019entreprise", + "heures_td": 12.0 + } + ], + "numero": 1 + }, + { + "titre": "Math\u00e9matiques", + "module": [ + { + "coefficient": 2.0, + "code": "M4202C", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Introduction \u00e0 la recherche op\u00e9rationnelle et aide \u00e0 la d\u00e9cision", + "heures_td": 12.0 + } + ], + "numero": 2 + }, + { + "titre": "Expression \u2013 Communication", + "module": [ + { + "coefficient": 2.0, + "code": "M4203", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Communication dans les organisations", + "heures_td": 15.0 + } + ], + "numero": 3 + }, + { + "titre": "Anglais", + "module": [ + { + "coefficient": 2.0, + "code": "M4204", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Travailler en anglais", + "heures_td": 15.0 + } + ], + "numero": 4 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS2", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 14 + } + ], + "ue_code": "UCOD9", + "numero": 2, + "titre": "Compl\u00e9ments de culture scientifique, sociale et humaine", + "type": 0 + }, + { + "acronyme": "UE43", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "STAGE", + "module": [ + { + "coefficient": 12.0, + "code": "M4301", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Stage professionnel", + "heures_td": 0.0 + } + ], + "numero": 1 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS3", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 11 + } + ], + "ue_code": "UCOD10", + "numero": 3, + "titre": "Mise en situation professionnelle", + "type": 0 + } + ], + "titre": "DUT Informatique", + "formation_id": "FORM234" +} \ No newline at end of file diff --git a/scotests/test_absence.py b/scotests/test_absence.py index 7a9bf95d..5a9ba1a3 100755 --- a/scotests/test_absence.py +++ b/scotests/test_absence.py @@ -28,6 +28,7 @@ import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error import sco_abs import sco_abs_views import sco_abs_notification +import ZAbsences G = sco_fake_gen.ScoFake(context.Notes) G.verbose = False @@ -66,6 +67,14 @@ mi = G.create_moduleimpl( for etud in etuds: G.inscrit_etudiant(sem, etud) +#--- Création d'une évaluation +e = G.create_evaluation( + moduleimpl_id=mi["moduleimpl_id"], + jour="22/01/2021", + description="evaluation test", + coefficient=1.0, +) + # --- Saisie absences etudid = etuds[0]["etudid"] @@ -162,9 +171,21 @@ print(a.CountAbs()) #lors du print cela affiche 5 or cela devrait afficher 3 # --- Création d'une liste d'abs -liste_abs = sco_abs_views.ListeAbsEtud(context.Absences, etudid, format='text', REQUEST=REQUEST) -print(liste_abs) -#toutes les absences figurent (bien evidemment pas celle qui a été supprimé alors pq CountAbs indique toujours le même nombre d'abs) +liste_abs = sco_abs_views.ListeAbsEtud(context.Absences, etudid, format='json', absjust_only=1, REQUEST=REQUEST) +liste_abs2 = sco_abs_views.ListeAbsEtud(context.Absences, etudid, format='json', REQUEST=REQUEST) + +load_liste_abs = json.loads(liste_abs) +load_liste_abs2 = json.loads(liste_abs2) + +assert len(load_liste_abs2) == 1 +assert len(load_liste_abs) == 2 +assert load_liste_abs2[0]["ampm"] == "1" +assert load_liste_abs2[0]["datedmy"] == "22/01/2021" +assert load_liste_abs2[0]["exams"] == mod["code"] + + +# absjust_only -> seulement les abs justifiés + # --- Création d'un groupe @@ -180,5 +201,26 @@ for etud in etuds : # --- Test de EtatAbsencesGroupes -# Fonction introuvable. +grp1_abs = context.Absences.EtatAbsencesGr(group_ids=[li_grp1[0]["group_id"]], debut="01/01/2021", fin ="30/06/2021", format="json", REQUEST=REQUEST) +load_grp1_abs = json.loads(grp1_abs) + +assert len(load_grp1_abs) == 10 + +tab_id=[] #tab des id present dans load_grp1_abs +for un_etud in load_grp1_abs : + tab_id.append(un_etud["etudid"]) + +for etud in etuds : #verification si tous les etudiants sont present dans la liste du groupe d'absence + assert etud["etudid"] in tab_id + + +for un_etud in load_grp1_abs : + if un_etud["etudid"] == etudid : + assert un_etud["nbabs"] == "3" + assert un_etud["nbjustifs_noabs"] == "2" + assert un_etud["nbabsjust"] == "2" + assert un_etud["nbabsnonjust"] == "1" + assert un_etud["nomprenom"] == etuds[0]["nomprenom"] + + diff --git a/scotests/test_create_etud.py b/scotests/test_create_etud.py new file mode 100755 index 00000000..9430538a --- /dev/null +++ b/scotests/test_create_etud.py @@ -0,0 +1,47 @@ +context = context # pylint: disable=undefined-variable +REQUEST = REQUEST # pylint: disable=undefined-variable +import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error + + +G = sco_fake_gen.ScoFake(context.Notes) +G.verbose = False + +# --- Création d'un étudiant + +etud = G.create_etud( + code_nip="", + nom="Poire", + prenom="Kevin", + code_ine="", + civilite="M", + etape="TST1", + email="test1@localhost", + emailperso="perso1@localhost", + date_naissance="01/05/2001", + lieu_naissance="Stains", + dept_naissance="93", + domicile="11, rue du test", + codepostaldomicile="93430", + villedomicile="Villetaneuse", + paysdomicile="France", + telephone="0102030405", + typeadresse="domicile", + boursier=None, + description="etudiant test", + ) + +print(etud) +print(" ") + +info = context.Scolarite.etud_info(etud["etudid"], format = "json", REQUEST=REQUEST) +load_info = json.loads(info) +print(load_info) + +#malgrè l'entrée de donnée dans les paramètres la fonction ne les prend pas en compte. Sauf pour date_naissance, +#dept_naissance, nom et prenom, lieu_naissance et civilite la fonction crée aussi un code nip et ine donc pas de pb +#pour ca. + +print(" ") +print(etud["telephone"]) +print(etud["domicile"]) +print(etud["emailperso"]) \ No newline at end of file diff --git a/scotests/test_etudiant1.py b/scotests/test_etudiant1.py new file mode 100755 index 00000000..cf2b4334 --- /dev/null +++ b/scotests/test_etudiant1.py @@ -0,0 +1,98 @@ +""" 3) Création d’étudiants, formation etc… Au cours de l’année un étudiant déménage et souhaite changer +ses informations personnelles. Un autre étudiant lui à changer de téléphone portable ainsi que d’adresse e-mail. +Changer les données + +Vérifier si les changements se sont effectués + +Fonctions de l’API utilisé : +- create_formation +- create_ue +- create_module +- create_matiere +- create_formsemestre +- create_moduleimpl +- inscrit_etudiant +- etuds_info +- getEtudInfo +- identite_edit + + """ + + +import random + +# La variable context est définie par le script de lancement +# l'affecte ainsi pour éviter les warnins pylint: +context = context # pylint: disable=undefined-variable +REQUEST = REQUEST # pylint: disable=undefined-variable +import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error +import scolars + +G = sco_fake_gen.ScoFake(context.Notes) +G.verbose = False + +# --- Création d'étudiants + +etud = G.create_etud( + code_nip="", + nom="Poire", + prenom="Kevin", + code_ine="", + civilite="M", + etape="TST1", + email="test1@localhost", + emailperso="perso1@localhost", + date_naissance="01/05/2001", + lieu_naissance="Stains", + dept_naissance="93", + domicile="11, rue du test", + codepostaldomicile="93430", + villedomicile="Villetaneuse", + paysdomicile="France", + telephone="0102030405", + typeadresse="domicile", + boursier=None, + description="etudiant test", + ) + +# --- Création d'une formation +f = G.create_formation(acronyme="") +ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test") +mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test") +mod = G.create_module( + matiere_id=mat["matiere_id"], + code="TSM1", + coefficient=1.0, + titre="module test", + ue_id=ue["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + +# --- Mise place d'un semestre +sem = G.create_formsemestre( + formation_id=f["formation_id"], + semestre_id=1, + date_debut="01/01/2020", + date_fin="30/06/2020", +) + +mi = G.create_moduleimpl( + module_id=mod["module_id"], + formsemestre_id=sem["formsemestre_id"], + responsable_id="bach", +) + + +# --- Inscription de l'étudiant + +G.inscrit_etudiant(sem, etud) + +print(etud) + +info = context.Scolarite.etud_info(etud["etudid"], format = "json", REQUEST=REQUEST) +load_info = json.loads(info) +print(load_info) + +# --- Modification des données + +scolars.adresse_edit(context.Scolarite, args = {"domicile" : "9 rue du moulin"}) \ No newline at end of file diff --git a/scotests/test_evaluation.py b/scotests/test_evaluation.py new file mode 100755 index 00000000..084fc6b0 --- /dev/null +++ b/scotests/test_evaluation.py @@ -0,0 +1,235 @@ +""" Création d'une formation, d'élève de 2 ue dans un semestre et de 6 évaluations par 3 fonction différentes : +create_eval, evaluation_create et do_evaluation_create. Saisir les notes des évaluations, lister ces evaluations, +supprimer et modifier une evaluation """ + +import sys +import random +# La variable context est définie par le script de lancement +# l'affecte ainsi pour évietr les warnins pylint: +context = context # pylint: disable=undefined-variable +REQUEST = REQUEST # pylint: disable=undefined-variable +import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error +import sco_moduleimpl +import sco_liste_notes +import sco_evaluations +import sco_undo_notes +import sco_abs_views +import sco_saisie_notes + +G = sco_fake_gen.ScoFake(context.Notes) +G.verbose = False + +# --- Création d'étudiants +etuds = [G.create_etud(code_nip=None) for _ in range(10)] + +# --- Création d'une formation et de deux UE +f = G.create_formation(acronyme="") +ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test") +mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test") +mod = G.create_module( + matiere_id=mat["matiere_id"], + code="TSM1", + coefficient=1.0, + titre="module test", + ue_id=ue["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + +ue2 = G.create_ue(formation_id=f["formation_id"], acronyme="TST2", titre="ue test2") +mat2 = G.create_matiere(ue_id=ue2["ue_id"], titre="matière test2") +mod2 = G.create_module( + matiere_id=mat2["matiere_id"], + code="TSM2", + coefficient=1.0, + titre="module test2", + ue_id=ue2["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + +# --- Mise place d'un semestre +sem = G.create_formsemestre( + formation_id=f["formation_id"], + semestre_id=1, + date_debut="01/01/2021", + date_fin="30/06/2021", +) + +mi = G.create_moduleimpl( + module_id=mod["module_id"], + formsemestre_id=sem["formsemestre_id"], + responsable_id="bach", +) + +mi2 = G.create_moduleimpl( + module_id=mod2["module_id"], + formsemestre_id=sem["formsemestre_id"], + responsable_id="bach", +) + + +# --- Inscription des étudiants +for etud in etuds: + G.inscrit_etudiant(sem, etud) + +# --- Création des évaluations + +#création d'éval avec create_evaluation +e = G.create_evaluation( + moduleimpl_id=mi["moduleimpl_id"], + jour="7/01/2021", + description="evaluation test 1", + coefficient=1.0, +) + +e2 = G.create_evaluation( + moduleimpl_id=mi2["moduleimpl_id"], + jour="11/01/2021", + description="evaluation test 2", + coefficient=1.0, +) + + + +#création d'éval avec evaluation_create +#e3 = context.Notes.evaluation_create(mi["moduleimpl_id"], REQUEST) +#e4 = context.Notes.evaluation_create(mi2["moduleimpl_id"], REQUEST) # rien ne se passe + +#création d'éval avec do_evaluation_create ! WARNING : retourne l'id de l'éval ! +e5 = context.Notes.do_evaluation_create( + moduleimpl_id=mi["moduleimpl_id"], + jour="01/02/2021", + heure_debut="9h0", + heure_fin="11h0", + description="evaluation test 5", + note_max="20.0", + coefficient="1", + REQUEST=REQUEST + ) + +e6 = context.Notes.do_evaluation_create( + moduleimpl_id=mi2["moduleimpl_id"], + jour="01/02/2021", + heure_debut="13h0", + heure_fin="15h0", + description="evaluation test 6", + note_max="20.0", + coefficient="1", + REQUEST=REQUEST + ) + + + +# --- Liste des évaluations dans le semestre + +lie = context.Notes.do_evaluation_list_in_formsemestre(formsemestre_id=sem["formsemestre_id"]) +assert len(lie) == 4 +""" print(lie[0]) +print(" ") +print(lie[1]) +print(" ") +print(lie[2]) +print(" ") +print(lie[3]) """ + +eval5 = context.Notes.do_evaluation_list({"evaluation_id" : e5})[0] +eval6 = context.Notes.do_evaluation_list({"evaluation_id" : e6})[0] + +# --- Saisie des absences aux évaluations + +_ = sco_abs_views.doSignaleAbsence( + context.Absences, + "7/01/2021", + "7/01/2021", + demijournee=1, + etudid=etuds[0]["etudid"], + REQUEST=REQUEST, +) + +_ = sco_abs_views.doSignaleAbsence( + context.Absences, + "01/02/2021", + "01/02/2021", + demijournee=1, + etudid=etuds[1]["etudid"], + REQUEST=REQUEST, +) + +_ = sco_abs_views.doJustifAbsence( + context.Absences, + "01/02/2021", + "01/02/2021", + demijournee=1, + etudid=etuds[1]["etudid"], + REQUEST=REQUEST, +) + +# --- Saisie des notes + +evals = [e,e2,eval5,eval6] + +for eval in evals : + for etud in etuds: + nb_changed, nb_suppress, existing_decisions = G.create_note( + evaluation=eval, etud=etud, note=float(random.randint(0, 20)) + ) + +# --- Check abs + +check = sco_liste_notes.evaluation_check_absences(context.Notes, evaluation_id=e["evaluation_id"]) + +check2 = sco_liste_notes.evaluation_check_absences(context.Notes, evaluation_id=e2["evaluation_id"]) + +# --- Liste de note d'une évaluation + +#lien = context.Notes.do_evaluation_listnotes(REQUEST=REQUEST) +#print (lien) pb avec les arguments. + + +cal = sco_evaluations.formsemestre_evaluations_cal(context.Notes, formsemestre_id=sem["formsemestre_id"], REQUEST=REQUEST) +#html + +delai = sco_evaluations.formsemestre_evaluations_delai_correction(context.Notes, formsemestre_id=sem["formsemestre_id"], format="json", REQUEST=REQUEST) +#html + +lio = sco_undo_notes.evaluation_list_operations(context.Notes, evaluation_id=e["evaluation_id"], REQUEST=REQUEST) +#html + + +# --- Supression de toutes les notes d'une évaluations + +etat = sco_evaluations.do_evaluation_etat(context.Notes, e2["evaluation_id"]) +assert etat["evalcomplete"] +sco_saisie_notes.evaluation_suppress_alln(context.Notes, e2["evaluation_id"], REQUEST=REQUEST) +etat2 = sco_evaluations.do_evaluation_etat(context.Notes, e2["evaluation_id"]) + +#assert not etat2["evalcomplete"] rien ne se passe... + +# --- Modification d'une évaluation + +context.Notes.do_evaluation_edit(REQUEST=REQUEST, args={"evaluation_id" : e5, "coefficient": 2.0 , +"description" : "modification", "note_max" : 20, +"heure_debut" : "8h0", "heure_fin" : "10h0", "jour" : "03/02/2021"}) +new_eval5 = context.Notes.do_evaluation_list({"evaluation_id" : e5})[0] + +assert new_eval5["description"] == "modification" +assert new_eval5["jour"] == "03/02/2021" +assert new_eval5["heure_debut"] == "08h00" +assert new_eval5["heure_fin"] == "10h00" +assert new_eval5["coefficient"] == 2.0 + +# --- Supression d'une évaluation + +e7 = G.create_evaluation( + moduleimpl_id=mi["moduleimpl_id"], + jour="7/01/2021", + description="evaluation test 7", + coefficient=1.0, +) + +lie = context.Notes.do_evaluation_list_in_formsemestre(formsemestre_id=sem["formsemestre_id"]) +assert len(lie) == 5 + +#context.Notes.evaluation_delete(REQUEST=REQUEST, evaluation_id=e7) rien ne se passe +sco_evaluations.do_evaluation_delete(context.Notes, REQUEST=REQUEST, evaluation_id=e7["evaluation_id"]) +lie2 = context.Notes.do_evaluation_list_in_formsemestre(formsemestre_id=sem["formsemestre_id"]) +assert len(lie2) == 4 diff --git a/scotests/test_evaluation_suppress_alln.py b/scotests/test_evaluation_suppress_alln.py new file mode 100755 index 00000000..5e140020 --- /dev/null +++ b/scotests/test_evaluation_suppress_alln.py @@ -0,0 +1,70 @@ +import random +# La variable context est définie par le script de lancement +# l'affecte ainsi pour évietr les warnins pylint: +context = context # pylint: disable=undefined-variable +REQUEST = REQUEST # pylint: disable=undefined-variable +import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error +import sco_saisie_notes +import sco_evaluations + + +G = sco_fake_gen.ScoFake(context.Notes) +G.verbose = False + +# --- Création d'étudiants +etuds = [G.create_etud(code_nip=None) for _ in range(10)] + +# --- Création d'une formation et de deux UE +f = G.create_formation(acronyme="") +ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test") +mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test") +mod = G.create_module( + matiere_id=mat["matiere_id"], + code="TSM1", + coefficient=1.0, + titre="module test", + ue_id=ue["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + + +# --- Mise place d'un semestre +sem = G.create_formsemestre( + formation_id=f["formation_id"], + semestre_id=1, + date_debut="01/01/2021", + date_fin="30/06/2021", +) + +mi = G.create_moduleimpl( + module_id=mod["module_id"], + formsemestre_id=sem["formsemestre_id"], + responsable_id="bach", +) + +# --- Inscription des étudiants +for etud in etuds: + G.inscrit_etudiant(sem, etud) + +# --- Création d'une évaluation +e = G.create_evaluation( + moduleimpl_id=mi["moduleimpl_id"], + jour="7/01/2021", + description="evaluation test 1", + coefficient=1.0, +) + +# --- Saisie des notes +for etud in etuds: + nb_changed, nb_suppress, existing_decisions = G.create_note( + evaluation=e, etud=etud, note=float(random.randint(0, 20)) + ) + +etat = sco_evaluations.do_evaluation_etat(context.Notes, e["evaluation_id"]) +assert etat["evalcomplete"] + +# --- Suppression des notes +sco_saisie_notes.evaluation_suppress_alln(context.Notes, e["evaluation_id"], REQUEST=REQUEST) +etat = sco_evaluations.do_evaluation_etat(context.Notes, e["evaluation_id"]) +assert not etat["evalcomplete"] + diff --git a/scotests/test_formations.py b/scotests/test_formations.py new file mode 100755 index 00000000..a3feb82d --- /dev/null +++ b/scotests/test_formations.py @@ -0,0 +1,321 @@ +""" Créer 2 formations, une test et une normale. Créer 2 semestres dans la formation normale et un +dans la formation test, créer 2 semestres dans la formation normale (un test et un normal), +2 ue (un test et un normal), 2 modules (un test et un normal) et 2 matieres (test et normal). + Et dans la formations test, un semestre, un module, un ue et une matiere. + Afficher la liste de tout ca puis supprimer les ue, mod, mat et sem test ainsi + que la formation test. Afficher la liste des UE, formations et modules restante. + + Vérification : + + - Les listes initiales comprennent bien tout les éléments créés avec les bon noms etc + - La supression s'est bien effectué au niveau de scodoc web et en python + - Vérifier que les fonctions listes font bien la mise à jour après supression + +Fonction de l'API utilisé : + +- create_formation +- create_ue +- create_matiere +- create_module +- create_formsemestre +- create_moduleimpl +- formation_list +- formation_export +- formsemestre_list +- do_moduleimpl_list +- do_module_impl_with_module_list +- do_formsemestre_delete +- do_module_list +- do_module_delete +- do_matiere_list +- do_matiere_delete +- do_ue_list +- do_ue_delete +- do_formation_delete + + + """ + + +import random + +# La variable context est définie par le script de lancement +# l'affecte ainsi pour évietr les warnins pylint: +context = context # pylint: disable=undefined-variable +REQUEST = REQUEST # pylint: disable=undefined-variable +import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error +import sco_formsemestre_status +import ZNotes +import sco_formations +import sco_moduleimpl +import sco_edit_ue +import sco_edit_matiere +import sco_edit_module +import sco_formsemestre_edit + +G = sco_fake_gen.ScoFake(context.Notes) +G.verbose = False + +# --- Création de formations + +f = G.create_formation(acronyme="F1", titre="Formation 1", titre_officiel="Titre officiel 1") + +ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test") +mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test") +mod = G.create_module( + matiere_id=mat["matiere_id"], + code="TSM1", + coefficient=1.0, + titre="module test", + ue_id=ue["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + +ue2 = G.create_ue(formation_id=f["formation_id"], acronyme="TST2", titre="ue test2") +mat2 = G.create_matiere(ue_id=ue2["ue_id"], titre="matière test2") +mod2 = G.create_module( + matiere_id=mat2["matiere_id"], + code="TSM2", + coefficient=1.0, + titre="module test", + ue_id=ue2["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + +uet = G.create_ue(formation_id=f["formation_id"], acronyme="TSTt", titre="ue testt") +matt = G.create_matiere(ue_id=uet["ue_id"], titre="matière testt") +modt = G.create_module( + matiere_id=matt["matiere_id"], + code="TSMt", + coefficient=1.0, + titre="module test", + ue_id=uet["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + + +f2 = G.create_formation(acronyme="", titre="Formation test") + +ue3 = G.create_ue(formation_id=f2["formation_id"], acronyme="TST3", titre="ue test3") +mat3 = G.create_matiere(ue_id=ue3["ue_id"], titre="matière test3") +mod3 = G.create_module( + matiere_id=mat3["matiere_id"], + code="TSM3", + coefficient=1.0, + titre="module test3", + ue_id=ue3["ue_id"], # faiblesse de l'API + formation_id=f2["formation_id"], # faiblesse de l'API +) + +# --- Création et implémentation des semestres + +sem1 = G.create_formsemestre( + formation_id=f["formation_id"], + semestre_id=1, + date_debut="01/01/2021", + date_fin="30/06/2021", +) + +sem2 = G.create_formsemestre( + formation_id=f["formation_id"], + semestre_id=2, + date_debut="01/09/2020", + date_fin="31/12/2020", +) + +mi = G.create_moduleimpl( + module_id=mod["module_id"], + formsemestre_id=sem1["formsemestre_id"], + responsable_id="bach", +) + +mi2 = G.create_moduleimpl( + module_id=mod2["module_id"], + formsemestre_id=sem1["formsemestre_id"], + responsable_id="bach", +) + +mit = G.create_moduleimpl( + module_id=modt["module_id"], + formsemestre_id=sem2["formsemestre_id"], + responsable_id="bach", +) + +semt = G.create_formsemestre( + formation_id=f2["formation_id"], + semestre_id=3, + date_debut="01/01/2021", + date_fin="30/06/2021", +) + +mi3 = G.create_moduleimpl( + module_id=mod3["module_id"], + formsemestre_id=semt["formsemestre_id"], + responsable_id="bach", +) + +# --- Affichier la liste des formations + +lif = context.Notes.formation_list(format="json", REQUEST=REQUEST, formation_id=f["formation_id"]) + +load_lif = json.loads(lif) +assert len(load_lif) == 1 +assert load_lif[0]["acronyme"] == f["acronyme"] +assert load_lif[0]["titre_officiel"] == f["titre_officiel"] +assert load_lif[0]["formation_id"] == f["formation_id"] +assert load_lif[0]["titre"] == f["titre"] + +lif2 = context.Notes.formation_list(format = 'json', REQUEST=REQUEST) + +load_lif2 = json.loads(lif2) +assert len(load_lif2) == 2 +assert load_lif2[0] == load_lif[0] +assert load_lif2[1]["titre"] == f2["titre"] + + +# --- Export de formation_id + +exp = sco_formations.formation_export(context.Notes, formation_id=f["formation_id"], format="json", REQUEST=REQUEST) + +load_exp = json.loads(exp) + +assert load_exp["acronyme"] == "F1" +assert load_exp["titre_officiel"] == "Titre officiel 1" +assert load_exp["titre"] == "Formation 1" +assert load_exp["formation_code"] == f["formation_code"] +assert len(load_exp["ue"]) == 3 +assert load_exp["ue"][0]["acronyme"] == "TST1" +assert load_exp["ue"][0]["titre"] == "ue test" +assert load_exp["formation_id"] == f["formation_id"] +assert load_exp["formation_code"] == f["formation_code"] + + +# --- Liste des semestres + +li_sem1 = context.Notes.formsemestre_list(formsemestre_id=sem1["formsemestre_id"], format = "json", REQUEST=REQUEST) +load_li_sem1 = json.loads(li_sem1) #uniquement le semestre 1 dans la liste + +assert len(load_li_sem1) == 1 +assert load_li_sem1[0]["date_fin"] == sem1["date_fin"] +assert load_li_sem1[0]["semestre_id"] == sem1["semestre_id"] +assert load_li_sem1[0]["formation_id"] ==sem1["formation_id"] + + +li_semf = context.Notes.formsemestre_list(formation_id=f["formation_id"], format = "json", REQUEST=REQUEST) +load_li_semf = json.loads(li_semf) + +assert load_li_sem1[0] in load_li_semf +assert len(load_li_semf) == 2 +assert load_li_semf[1]["semestre_id"] == sem2["semestre_id"] + + +li_sem = context.Notes.formsemestre_list(format = "json", REQUEST=REQUEST) +load_li_sem = json.loads(li_sem) + +assert len(load_li_sem) == 3 +assert load_li_semf[0] and load_li_semf[1] in load_li_sem +assert load_li_sem[0]["semestre_id"] == semt["semestre_id"] + + +# --- Liste des modules + +lim_sem1 = sco_moduleimpl.do_moduleimpl_list(context.Notes, formsemestre_id=sem1["formsemestre_id"], REQUEST=REQUEST) +load_lim_sem1 = json.loads(lim_sem1) + + +assert len(load_lim_sem1) == 2 +assert mod["module_id"] == load_lim_sem1[0]["module_id"] or load_lim_sem1[1]["module_id"] +assert mod2["module_id"] == load_lim_sem1[0]["module_id"] or load_lim_sem1[1]["module_id"] + +lim_modid = sco_moduleimpl.do_moduleimpl_list(context.Notes, module_id=mod["module_id"], REQUEST=REQUEST) +load_lim_modid = json.loads(lim_modid) #Liste avec seulement mod + +assert len(load_lim_modid) == 1 + +lim_modimpl_id = sco_moduleimpl.do_moduleimpl_list(context.Notes, moduleimpl_id=mi["moduleimpl_id"], REQUEST=REQUEST) +print(lim_modimpl_id) + +# ---- Test de do_moduleimpl_withmodule_list + +assert lim_modid == lim_modimpl_id #doit etre le meme resultat + +liimp_sem1 = sco_moduleimpl.do_moduleimpl_withmodule_list(context.Notes, formsemestre_id=sem1["formsemestre_id"], REQUEST=REQUEST) +load_liimp_sem1 = json.loads(liimp_sem1) + +assert len(load_liimp_sem1) == 2 +assert mod["module_id"] == load_liimp_sem1[0]["module_id"] or load_liimp_sem1[1]["module_id"] or load_liim_sem1[2]["module_id"] +assert mod2["module_id"] == load_liimp_sem1[0]["module_id"] or load_liimp_sem1[1]["module_id"] or load_liim_sem1[2]["module_id"] +assert modt["module_id"] == load_liimp_sem1[0]["module_id"] or load_liimp_sem1[1]["module_id"] or load_liim_sem1[2]["module_id"] + +liimp_modid = sco_moduleimpl.do_moduleimpl_withmodule_list(context.Notes, module_id=mod["module_id"], REQUEST=REQUEST) + +load_liimp_modid = json.loads(liimp_modid) +assert len(load_liimp_modid) == 1 + +liimp_modimplid = sco_moduleimpl.do_moduleimpl_withmodule_list(context.Notes, moduleimpl_id=mi["moduleimpl_id"], REQUEST=REQUEST) + +assert liimp_modid == liimp_modimplid + + +# --- Suppression du module, matiere et ue test du semestre 2 + +#on doit d'abbord supprimer le semestre + +#sco_formsemestre_edit.formsemestre_delete(context.Notes, formsemestre_id=sem2["formsemestre_id"], REQUEST=REQUEST) +#sco_formsemestre_edit.formsemestre_delete2(context.Notes, formsemestre_id=sem2["formsemestre_id"], REQUEST=REQUEST) + +# RIEN NE SE PASSE AVEC CES FONCTIONS + +sco_formsemestre_edit.do_formsemestre_delete(context.Notes, formsemestre_id=sem2["formsemestre_id"], REQUEST=REQUEST) + +#sco_edit_module.module_delete(context.Notes, module_id=modt["module_id"], REQUEST=REQUEST) +#sco_edit_matiere.matiere_delete(context.Notes, matiere_id=matt["matiere_id"], REQUEST=REQUEST) +#sco_edit_ue.ue_delete(context.Notes, ue_id=uet["ue_id"], REQUEST=REQUEST) + +# RIEN NE SE PASSE AVEC CES FONCTIONS + + +li_module = context.Notes.do_module_list() +assert len(li_module) == 4 +context.Notes.do_module_delete(oid=modt["module_id"], REQUEST=REQUEST) #on supprime le semestre +#sco_formsemestre_edit.formsemestre_delete_moduleimpls(context.Notes, formsemestre_id=sem2["formsemestre_id"], module_ids_to_del=[modt["module_id"]]) +#deuxieme methode de supression d'un module +li_module2 = context.Notes.do_module_list() + +assert len(li_module2) == 3 #verification de la suppression du module + +lim_sem2 = sco_moduleimpl.do_moduleimpl_list(context.Notes, formsemestre_id=sem2["formsemestre_id"], REQUEST=REQUEST) +load_lim_sem2 = json.loads(lim_sem2) + +assert len(load_lim_sem2) == 0 #deuxieme vérification si le module s'est bien sup + + +li_mat = context.Notes.do_matiere_list() +assert len(li_mat) == 4 +context.Notes.do_matiere_delete(oid=matt["matiere_id"], REQUEST=REQUEST) #on supprime la matiere +li_mat2 = context.Notes.do_matiere_list() +assert len(li_mat2) == 3 #verification de la suppression de la matiere + + +li_ue = context.Notes.do_ue_list() +assert len(li_ue) == 4 +sco_edit_ue.ue_delete(context.Notes, ue_id=uet["ue_id"], REQUEST=REQUEST) +li_ue2 = context.Notes.do_ue_list() +#assert len(li_ue) == 3 #verification de la suppression de l'UE #comment supprimer un ue? + + +# --- Suppression d'une formation + + +#Il faut d'abbord supprimer le semestre aussi. + +sco_formsemestre_edit.do_formsemestre_delete(context.Notes, formsemestre_id=semt["formsemestre_id"], REQUEST=REQUEST) + + +context.Notes.do_formation_delete(oid=f2["formation_id"], REQUEST=REQUEST) +lif3 = context.Notes.formation_list(format = 'json', REQUEST=REQUEST) + +load_lif3 = json.loads(lif3) +assert len(load_lif3) == 1 + + diff --git a/scotests/test_groupes.py b/scotests/test_groupes.py index 8ffa5d60..142faf4e 100755 --- a/scotests/test_groupes.py +++ b/scotests/test_groupes.py @@ -53,11 +53,12 @@ Fonctions de l’API utilisé : import random # La variable context est définie par le script de lancement -# l'affecte ainsi pour évietr les warnins pylint: +# l'affecte ainsi pour éviter les warnins pylint: context = context # pylint: disable=undefined-variable REQUEST = REQUEST # pylint: disable=undefined-variable import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error import sco_groups +import sco_groups_view G = sco_fake_gen.ScoFake(context.Notes) @@ -303,19 +304,31 @@ assert load_lijson_s1[0]["partition_name"] == "Eleve 1ere annee" -# --- Vue d'un groupes (liste d'élève en format json ou xml) +# --- Vue d'un groupes (liste d'élève en format json) +vue_g1 = sco_groups_view.groups_view(context.Scolarite, group_ids = [li_grp1[0]["group_id"]], format = "json", REQUEST=REQUEST) +load_vue_g1 = json.loads(vue_g1) +assert len(load_vue_g1) == 4 +assert load_vue_g1[0][li1[0]["partition_id"]] == li_grp1[0]["group_name"] +vue_sem = sco_groups_view.groups_view(context.Scolarite, formsemestre_id=sem1["formsemestre_id"], format = "json", REQUEST=REQUEST) +load_vue_sem = json.loads(vue_sem) +assert len(load_vue_sem) == 10 +tab=[] +val=False +for etud in etuds[:10] : + for i in range(len(load_vue_sem)) : + if etud["prenom"] == load_vue_sem[i]["prenom"] and etud["nom_disp"]==load_vue_sem[i]["nom_disp"] : + val = True + tab.append(val) + +assert not False in tab #tout mes etudiants sont present dans vue_sem. # --- Test des fonctions dans sco_groups -#_ = sco_groups.checkGroupName(li_grp1[0]["group_name"]) -#_ = sco_groups.checkGroupName("Groupe S1B") -#_ = sco_groups.checkGroupName("Groupe S3A") -#_ = sco_groups.checkGroupName("Groupe S3B") assert li_grp1[0] == sco_groups.get_group(context.Scolarite, li_grp1[0]["group_id"]) #test get_group diff --git a/scotests/test_scenario1_app.py b/scotests/test_scenario1_app.py new file mode 100755 index 00000000..1d88e9b1 --- /dev/null +++ b/scotests/test_scenario1_app.py @@ -0,0 +1,117 @@ +import random +# La variable context est définie par le script de lancement +# l'affecte ainsi pour évietr les warnins pylint: +context = context # pylint: disable=undefined-variable +REQUEST = REQUEST # pylint: disable=undefined-variable +import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error + +G = sco_fake_gen.ScoFake(context.Notes) +G.verbose = False + +# --- Création d'étudiants +etuds = [G.create_etud(code_nip=None) for _ in range(10)] + +# --- Création de l'utilisateur responsable du semestres, des modules etc.... + +arg = {"passwd": "scodocpass", "user_name" : "unutil", "roles" :"Ens,RespPe"} +user = context.Users.create_user(args=arg, REQUEST=REQUEST) +print(user) + +# --- Création formation et de deux UE +f = G.create_formation(acronyme="") +ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test") +mat11 = G.create_matiere(ue_id=ue["ue_id"], titre="matière test") +mod11 = G.create_module( + matiere_id=mat11["matiere_id"], + code="TSM11", + coefficient=1.0, + titre="module test11", + ue_id=ue["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + +mat12 = G.create_matiere(ue_id=ue["ue_id"], titre="matière test12") +mod12 = G.create_module( + matiere_id=mat12["matiere_id"], + code="TSM12", + coefficient=1.0, + titre="module test12", + ue_id=ue["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + + +ue2 = G.create_ue(formation_id=f["formation_id"], acronyme="TST2", titre="ue test2") +mat21 = G.create_matiere(ue_id=ue2["ue_id"], titre="matière test21") +mod21 = G.create_module( + matiere_id=mat21["matiere_id"], + code="TSM21", + coefficient=1.0, + titre="module test21", + ue_id=ue2["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + +mat22 = G.create_matiere(ue_id=ue2["ue_id"], titre="matière test22") +mod22 = G.create_module( + matiere_id=mat22["matiere_id"], + code="TSM22", + coefficient=1.0, + titre="module test22", + ue_id=ue2["ue_id"], # faiblesse de l'API + formation_id=f["formation_id"], # faiblesse de l'API +) + +# --- Mise place d'un semestre +sem = G.create_formsemestre( + formation_id=f["formation_id"], + semestre_id=1, + date_debut="01/01/2021", + date_fin="30/06/2021", +) + +mods = [] +for module_id, formsemestre_id, responsable_id in [ + (mod11["module_id"], sem["formsemestre_id"], "bach"), + (mod12["module_id"], sem["formsemestre_id"], "bach"), + (mod21["module_id"], sem["formsemestre_id"], "bach"), + (mod22["module_id"], sem["formsemestre_id"], "bach") +] : + mi = G.create_moduleimpl(module_id=module_id, formsemestre_id=formsemestre_id, responsable_id=responsable_id) + mods.append(mi) + + +# --- Inscription des étudiants +for etud in etuds: + G.inscrit_etudiant(sem, etud) + + +# --- Création d'évaluations (2 par modules) + +evals=[] + +for moduleimpl_id, jour, description, coefficient in [ + (mods[0]["moduleimpl_id"], "01/02/2021", "e1", 1.0), + (mods[0]["moduleimpl_id"], "02/02/2021", "e2", 1.0), + (mods[1]["moduleimpl_id"], "03/02/2021", "e3", 1.0), + (mods[1]["moduleimpl_id"], "04/02/2021", "e4", 1.0), + (mods[2]["moduleimpl_id"], "05/02/2021", "e5", 1.0), + (mods[2]["moduleimpl_id"], "06/02/2021", "e6", 1.0), + (mods[3]["moduleimpl_id"], "07/02/2021", "e7", 1.0), + (mods[3]["moduleimpl_id"], "08/02/2021", "e8", 1.0), +] : + e = G.create_evaluation(moduleimpl_id=moduleimpl_id, jour=jour, description=description, coefficient=coefficient) + evals.append(e) + + +# --- Saisie des notes aléatoires + +for eval in evals : + for etud in etuds: + nb_changed, nb_suppress, existing_decisions = G.create_note( + evaluation=eval, etud=etud, note=float(random.randint(0, 20)) + ) + + + + diff --git a/scotests/test_scenario1_formation.py b/scotests/test_scenario1_formation.py new file mode 100755 index 00000000..6adf1bd8 --- /dev/null +++ b/scotests/test_scenario1_formation.py @@ -0,0 +1,72 @@ +import sco_formations +import random +# La variable context est définie par le script de lancement +# l'affecte ainsi pour évietr les warnins pylint: +context = context # pylint: disable=undefined-variable +REQUEST = REQUEST # pylint: disable=undefined-variable +import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error +import sco_moduleimpl + +G = sco_fake_gen.ScoFake(context.Notes) +G.verbose = False + +file = open("scotests/export_formation1.xml") +doc = file.read() +file.close() + + +# --- Création de la formation + +f = sco_formations.formation_import_xml(REQUEST=REQUEST, doc=doc, context=context.Notes) + +# --- Création des semestres + +sem1 = G.create_formsemestre( + formation_id=f[0], + semestre_id=1, + date_debut="01/09/2020", + date_fin="01/02/2021", +) + +sem3 = G.create_formsemestre( + formation_id=f[0], + semestre_id=3, + date_debut="01/09/2020", + date_fin="01/02/2021", +) + +sem2 = G.create_formsemestre( + formation_id=f[0], + semestre_id=2, + date_debut="02/02/2021", + date_fin="01/06/2021", +) + +sem4 = G.create_formsemestre( + formation_id=f[0], + semestre_id=4, + date_debut="02/02/2021", + date_fin="01/06/2021", +) + + +# --- Implémentation des modules + +li_module = context.Notes.do_module_list() +mods_imp = [] +for mod in li_module : + if mod["semestre_id"] == 1 : + formsemestre_id = sem1["formsemestre_id"] + elif mod["semestre_id"] == 2 : + formsemestre_id = sem2["formsemestre_id"] + elif mod["semestre_id"] == 3 : + formsemestre_id = sem3["formsemestre_id"] + else : + formsemestre_id = sem4["formsemestre_id"] + + mi = G.create_moduleimpl( + module_id=mod["module_id"], + formsemestre_id=formsemestre_id, + responsable_id="bach", + ) + mods_imp.append(mi) \ No newline at end of file diff --git a/scotests/test_scenario2_formation.py b/scotests/test_scenario2_formation.py new file mode 100755 index 00000000..4a77544a --- /dev/null +++ b/scotests/test_scenario2_formation.py @@ -0,0 +1,105 @@ +import sco_formations +import random +# La variable context est définie par le script de lancement +# l'affecte ainsi pour évietr les warnins pylint: +context = context # pylint: disable=undefined-variable +REQUEST = REQUEST # pylint: disable=undefined-variable +import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error +import sco_moduleimpl + +G = sco_fake_gen.ScoFake(context.Notes) +G.verbose = False + +file = open("scotests/export_formation1.xml") +doc = file.read() +file.close() + + +# --- Création de la formation + +f = sco_formations.formation_import_xml(REQUEST=REQUEST, doc=doc, context=context.Notes) + +# --- Création des semestres + +sem1 = G.create_formsemestre( + formation_id=f[0], + semestre_id=1, + date_debut="01/09/2020", + date_fin="01/02/2021", +) + +sem3 = G.create_formsemestre( + formation_id=f[0], + semestre_id=3, + date_debut="01/09/2020", + date_fin="01/02/2021", +) + +sem2 = G.create_formsemestre( + formation_id=f[0], + semestre_id=2, + date_debut="02/02/2021", + date_fin="01/06/2021", +) + +sem4 = G.create_formsemestre( + formation_id=f[0], + semestre_id=4, + date_debut="02/02/2021", + date_fin="01/06/2021", +) + + +# --- Implémentation des modules + +li_module = context.Notes.do_module_list() +mods_imp = [] +for mod in li_module : + if mod["semestre_id"] == 1 : + formsemestre_id = sem1["formsemestre_id"] + elif mod["semestre_id"] == 2 : + formsemestre_id = sem2["formsemestre_id"] + elif mod["semestre_id"] == 3 : + formsemestre_id = sem3["formsemestre_id"] + else : + formsemestre_id = sem4["formsemestre_id"] + + mi = G.create_moduleimpl( + module_id=mod["module_id"], + formsemestre_id=formsemestre_id, + responsable_id="bach", + ) + mods_imp.append(mi) + +# --- Création des étudiants + +etuds=[] +for nom, prenom in [ + ("Semestre1", "EtudiantNumero1"), + ("Semestre1", "EtudiantNumero2"), + ("Semestre2", "EtudiantNumero3"), + ("Semestre2", "EtudiantNumero4"), + ("Semestre3", "EtudiantNumero5"), + ("Semestre3", "EtudiantNumero6"), + ("Semestre4", "EtudiantNumero7"), + ("Semestre4", "EtudiantNumero8") +] : + etud = G.create_etud( + nom=nom, + prenom=prenom, + ) + etuds.append(etud) + +# --- Inscription des étudiants + +for etud in etuds[0:2]: + G.inscrit_etudiant(sem1, etud) + +for etud in etuds[2:4]: + G.inscrit_etudiant(sem2, etud) + +for etud in etuds[4:6]: + G.inscrit_etudiant(sem3, etud) + +for etud in etuds[6:]: + G.inscrit_etudiant(sem4, etud) \ No newline at end of file diff --git a/scotests/test_scenario3_formation.py b/scotests/test_scenario3_formation.py new file mode 100755 index 00000000..83f6b212 --- /dev/null +++ b/scotests/test_scenario3_formation.py @@ -0,0 +1,135 @@ +import sco_formations +import json +import random +# La variable context est définie par le script de lancement +# l'affecte ainsi pour évietr les warnins pylint: +context = context # pylint: disable=undefined-variable +REQUEST = REQUEST # pylint: disable=undefined-variable +import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error +import sco_moduleimpl + +G = sco_fake_gen.ScoFake(context.Notes) +G.verbose = False + +file = open("scotests/export_formation1.xml") +doc = file.read() +file.close() + + +# --- Création de la formation + +f = sco_formations.formation_import_xml(REQUEST=REQUEST, doc=doc, context=context.Notes) + +# --- Création des semestres + +sem1 = G.create_formsemestre( + formation_id=f[0], + semestre_id=1, + date_debut="01/09/2020", + date_fin="01/02/2021", +) + +sem3 = G.create_formsemestre( + formation_id=f[0], + semestre_id=3, + date_debut="01/09/2020", + date_fin="01/02/2021", +) + +sem2 = G.create_formsemestre( + formation_id=f[0], + semestre_id=2, + date_debut="02/02/2021", + date_fin="01/06/2021", +) + +sem4 = G.create_formsemestre( + formation_id=f[0], + semestre_id=4, + date_debut="02/02/2021", + date_fin="01/06/2021", +) + + +# --- Implémentation des modules + +li_module = context.Notes.do_module_list() +mods_imp = [] +for mod in li_module : + if mod["semestre_id"] == 1 : + formsemestre_id = sem1["formsemestre_id"] + elif mod["semestre_id"] == 2 : + formsemestre_id = sem2["formsemestre_id"] + elif mod["semestre_id"] == 3 : + formsemestre_id = sem3["formsemestre_id"] + else : + formsemestre_id = sem4["formsemestre_id"] + + mi = G.create_moduleimpl( + module_id=mod["module_id"], + formsemestre_id=formsemestre_id, + responsable_id="bach", + ) + mods_imp.append(mi) + +# --- Création des étudiants + +etuds=[] +for nom, prenom in [ + ("Semestre1", "EtudiantNumero1"), + ("Semestre1", "EtudiantNumero2"), + ("Semestre2", "EtudiantNumero3"), + ("Semestre2", "EtudiantNumero4"), + ("Semestre3", "EtudiantNumero5"), + ("Semestre3", "EtudiantNumero6"), + ("Semestre4", "EtudiantNumero7"), + ("Semestre4", "EtudiantNumero8") +] : + etud = G.create_etud( + nom=nom, + prenom=prenom, + ) + etuds.append(etud) + +# --- Inscription des étudiants + +for etud in etuds[0:2]: + G.inscrit_etudiant(sem1, etud) + +for etud in etuds[2:4]: + G.inscrit_etudiant(sem2, etud) + +for etud in etuds[4:6]: + G.inscrit_etudiant(sem3, etud) + +for etud in etuds[6:]: + G.inscrit_etudiant(sem4, etud) + +# --- Création d'une évaluation pour chaque UE + +lim_sem1 = sco_moduleimpl.do_moduleimpl_list(context.Notes, formsemestre_id=sem1["formsemestre_id"], REQUEST=REQUEST) +load_lim_sem1 = json.loads(lim_sem1) + +lim_sem2 = sco_moduleimpl.do_moduleimpl_list(context.Notes, formsemestre_id=sem2["formsemestre_id"], REQUEST=REQUEST) +load_lim_sem2 = json.loads(lim_sem2) + +lim_sem3 = sco_moduleimpl.do_moduleimpl_list(context.Notes, formsemestre_id=sem3["formsemestre_id"], REQUEST=REQUEST) +load_lim_sem3 = json.loads(lim_sem3) + +lim_sem4 = sco_moduleimpl.do_moduleimpl_list(context.Notes, formsemestre_id=sem4["formsemestre_id"], REQUEST=REQUEST) +load_lim_sem4 = json.loads(lim_sem4) + + +for moduleimpl_id, jour, description, coefficient in [ + (load_lim_sem1[1]["moduleimpl_id"], "02/09/2020", "InterroTestSemestre1", 1.0), + (load_lim_sem1[2]["moduleimpl_id"], "03/09/2020", "InterroTestSemestre1", 1.0), + (load_lim_sem2[1]["moduleimpl_id"], "03/02/2021", "InterroTestSemestre2", 1.0), + (load_lim_sem2[8]["moduleimpl_id"], "04/02/2021", "InterroTestSemestre2", 1.0), + (load_lim_sem3[3]["moduleimpl_id"], "02/09/2020", "InterroTestSemestre3", 1.0), + (load_lim_sem3[9]["moduleimpl_id"], "03/09/2020", "InterroTestSemestre3", 1.0), + (load_lim_sem3[15]["moduleimpl_id"], "04/09/2020", "InterroTestSemestre3", 1.0), + (load_lim_sem4[3]["moduleimpl_id"], "03/02/2021", "InterroTestSemestre4", 1.0), + (load_lim_sem4[9]["moduleimpl_id"], "04/02/2021", "InterroTestSemestre4", 1.0), + (load_lim_sem4[13]["moduleimpl_id"], "05/02/2021", "InterroTestSemestre4", 1.0), +] : + e = G.create_evaluation(moduleimpl_id=moduleimpl_id, jour=jour, description=description, coefficient=coefficient) \ No newline at end of file diff --git a/scotests/test_scenario4_formation.py b/scotests/test_scenario4_formation.py new file mode 100755 index 00000000..b690022a --- /dev/null +++ b/scotests/test_scenario4_formation.py @@ -0,0 +1,172 @@ +import sco_formations +import json +import random +# La variable context est définie par le script de lancement +# l'affecte ainsi pour évietr les warnins pylint: +context = context # pylint: disable=undefined-variable +REQUEST = REQUEST # pylint: disable=undefined-variable +import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error +import sco_moduleimpl + +G = sco_fake_gen.ScoFake(context.Notes) +G.verbose = False + +file = open("scotests/export_formation1.xml") +doc = file.read() +file.close() + + +# --- Création de la formation + +f = sco_formations.formation_import_xml(REQUEST=REQUEST, doc=doc, context=context.Notes) + +# --- Création des semestres + +sem1 = G.create_formsemestre( + formation_id=f[0], + semestre_id=1, + date_debut="01/09/2020", + date_fin="01/02/2021", +) + +sem3 = G.create_formsemestre( + formation_id=f[0], + semestre_id=3, + date_debut="01/09/2020", + date_fin="01/02/2021", +) + +sem2 = G.create_formsemestre( + formation_id=f[0], + semestre_id=2, + date_debut="02/02/2021", + date_fin="01/06/2021", +) + +sem4 = G.create_formsemestre( + formation_id=f[0], + semestre_id=4, + date_debut="02/02/2021", + date_fin="01/06/2021", +) + + +# --- Implémentation des modules + +li_module = context.Notes.do_module_list() +mods_imp = [] +for mod in li_module : + if mod["semestre_id"] == 1 : + formsemestre_id = sem1["formsemestre_id"] + elif mod["semestre_id"] == 2 : + formsemestre_id = sem2["formsemestre_id"] + elif mod["semestre_id"] == 3 : + formsemestre_id = sem3["formsemestre_id"] + else : + formsemestre_id = sem4["formsemestre_id"] + + mi = G.create_moduleimpl( + module_id=mod["module_id"], + formsemestre_id=formsemestre_id, + responsable_id="bach", + ) + mods_imp.append(mi) + +# --- Création des étudiants + +etuds=[] +for nom, prenom in [ + ("Semestre1", "EtudiantNumero1"), + ("Semestre1", "EtudiantNumero2"), + ("Semestre2", "EtudiantNumero3"), + ("Semestre2", "EtudiantNumero4"), + ("Semestre3", "EtudiantNumero5"), + ("Semestre3", "EtudiantNumero6"), + ("Semestre4", "EtudiantNumero7"), + ("Semestre4", "EtudiantNumero8") +] : + etud = G.create_etud( + nom=nom, + prenom=prenom, + ) + etuds.append(etud) + +# --- Inscription des étudiants + +for etud in etuds[0:2]: + G.inscrit_etudiant(sem1, etud) + +for etud in etuds[2:4]: + G.inscrit_etudiant(sem2, etud) + +for etud in etuds[4:6]: + G.inscrit_etudiant(sem3, etud) + +for etud in etuds[6:]: + G.inscrit_etudiant(sem4, etud) + +# --- Création d'une évaluation pour chaque UE + +lim_sem1 = sco_moduleimpl.do_moduleimpl_list(context.Notes, formsemestre_id=sem1["formsemestre_id"], REQUEST=REQUEST) +load_lim_sem1 = json.loads(lim_sem1) + +lim_sem2 = sco_moduleimpl.do_moduleimpl_list(context.Notes, formsemestre_id=sem2["formsemestre_id"], REQUEST=REQUEST) +load_lim_sem2 = json.loads(lim_sem2) + +lim_sem3 = sco_moduleimpl.do_moduleimpl_list(context.Notes, formsemestre_id=sem3["formsemestre_id"], REQUEST=REQUEST) +load_lim_sem3 = json.loads(lim_sem3) + +lim_sem4 = sco_moduleimpl.do_moduleimpl_list(context.Notes, formsemestre_id=sem4["formsemestre_id"], REQUEST=REQUEST) +load_lim_sem4 = json.loads(lim_sem4) + + +for moduleimpl_id, jour, description, coefficient in [ + (load_lim_sem1[1]["moduleimpl_id"], "02/09/2020", "InterroTestSemestre1", 1.0), + (load_lim_sem1[2]["moduleimpl_id"], "03/09/2020", "InterroTestSemestre1", 1.0), + (load_lim_sem2[1]["moduleimpl_id"], "03/02/2021", "InterroTestSemestre2", 1.0), + (load_lim_sem2[8]["moduleimpl_id"], "04/02/2021", "InterroTestSemestre2", 1.0), + (load_lim_sem3[3]["moduleimpl_id"], "02/09/2020", "InterroTestSemestre3", 1.0), + (load_lim_sem3[9]["moduleimpl_id"], "03/09/2020", "InterroTestSemestre3", 1.0), + (load_lim_sem3[15]["moduleimpl_id"], "04/09/2020", "InterroTestSemestre3", 1.0), + (load_lim_sem4[3]["moduleimpl_id"], "03/02/2021", "InterroTestSemestre4", 1.0), + (load_lim_sem4[9]["moduleimpl_id"], "04/02/2021", "InterroTestSemestre4", 1.0), + (load_lim_sem4[13]["moduleimpl_id"], "05/02/2021", "InterroTestSemestre4", 1.0), +] : + e = G.create_evaluation(moduleimpl_id=moduleimpl_id, jour=jour, description=description, coefficient=coefficient) + + +# --- Saisie des notes des étudiants (un élève a 12, un autre a 7 pour chaque semestre) + +lie1 = context.Notes.do_evaluation_list_in_formsemestre(formsemestre_id=sem1["formsemestre_id"]) +lie2 = context.Notes.do_evaluation_list_in_formsemestre(formsemestre_id=sem2["formsemestre_id"]) +lie3 = context.Notes.do_evaluation_list_in_formsemestre(formsemestre_id=sem3["formsemestre_id"]) +lie4 = context.Notes.do_evaluation_list_in_formsemestre(formsemestre_id=sem4["formsemestre_id"]) + +for eval in lie1 : + for etud in etuds[:2] : + if etud == etuds[0] : + nb_changed, nb_suppress, existing_decisions = G.create_note(evaluation=eval, etud=etud, note=12.0) + else : + nb_changed, nb_suppress, existing_decisions = G.create_note(evaluation=eval, etud=etud, note=7.0) + +for eval in lie2 : + for etud in etuds[2:4] : + if etud == etuds[2] : + nb_changed, nb_suppress, existing_decisions = G.create_note(evaluation=eval, etud=etud, note=12.0) + else : + nb_changed, nb_suppress, existing_decisions = G.create_note(evaluation=eval, etud=etud, note=7.0) + + +for eval in lie3 : + for etud in etuds[4:6] : + if etud == etuds[4] : + nb_changed, nb_suppress, existing_decisions = G.create_note(evaluation=eval, etud=etud, note=12.0) + else : + nb_changed, nb_suppress, existing_decisions = G.create_note(evaluation=eval, etud=etud, note=7.0) + +for eval in lie4 : + for etud in etuds[6:] : + if etud == etuds[6] : + nb_changed, nb_suppress, existing_decisions = G.create_note(evaluation=eval, etud=etud, note=12.0) + else : + nb_changed, nb_suppress, existing_decisions = G.create_note(evaluation=eval, etud=etud, note=7.0) \ No newline at end of file diff --git a/scotests/test_user.py b/scotests/test_user.py new file mode 100755 index 00000000..00b47817 --- /dev/null +++ b/scotests/test_user.py @@ -0,0 +1,49 @@ +""" Créer un utilisateur, récupérer ses infos, + lister les utilisateurs, modifier le mdp, modfifier l'utilisateur (si possible), + changer d'admin, tester d'autre fonctionalités liés aux users """ + +import random +# La variable context est définie par le script de lancement +# l'affecte ainsi pour évietr les warnins pylint: +context = context # pylint: disable=undefined-variable +REQUEST = REQUEST # pylint: disable=undefined-variable +import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error +import ZScoUsers +import ZScoDoc +import ZScolar + + +nomdept = raw_input("Quel est le nom de votre département test? ATTENTION A NE PAS VOUS TROMPER : ") + +# --- Création d'un utilisateur + +arg = {"passwd": "scodocpass", "user_name" : "unutil", "nom" : "unnom", "prenom":"unprenom", "email": "unemail@mail.fr", "roles" :"Ens"+nomdept+",RespPe"+nomdept} +#user1 = context.Users.create_user(args=arg, REQUEST=REQUEST) +user_info1 = context.Users.user_info(user_name="unutil") + +assert user_info1["email"] == arg["email"] +assert user_info1["user_name"] == arg["user_name"] +assert user_info1["nom"] == "unnom" +assert user_info1["prenom"] == "unprenom" +assert user_info1["roles"] == arg["roles"] + + +# --- Récupération de la liste des Users + +liste_xml = context.Users.get_userlist_xml(REQUEST=REQUEST) + +liste_user = context.Users.get_userlist() +len_liu1 = len(liste_user) + +assert user_info1 in liste_user #le nouvel utilisateur est bien dans la liste ! + +# --- Changement du mot de passe de l'utilisateur + +#context.Users.change_password(user_name="unutil", password=) + +context.Users.do_change_password(user_name="unutil", password="scodocpass2") +#vérification du mdp changé directement sur scodoc web car je ne trouve pas comment récupérer le mdp en python +#Vérification : ok! + + + diff --git a/static/formation_export.json b/static/formation_export.json new file mode 100755 index 00000000..1c13dc0b --- /dev/null +++ b/static/formation_export.json @@ -0,0 +1,1352 @@ +{ + "acronyme": "DUT Info", + "code_specialite": "", + "type_parcours": 100, + "titre_officiel": "DUT Informatique", + "formation_code": "FCOD2", + "version": 1, + "ue": [ + { + "acronyme": "UE11", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Architecture mat\u00e9rielle - Syst\u00e8mes d\u2019exploitation - R\u00e9seaux", + "module": [ + { + "coefficient": 2.0, + "code": "M1101", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 30.0, + "abbrev": "", + "numero": 1, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Introduction aux syst\u00e8mes informatiques", + "heures_td": 20.0 + } + ], + "numero": 1 + }, + { + "titre": "Algorithmique - Programmation - Langages", + "module": [ + { + "coefficient": 2.0, + "code": "M1102", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 30.0, + "abbrev": "Algorithmique", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Introduction \u00e0 l\u2019algorithmique et \u00e0 la programmation", + "heures_td": 20.0 + } + ], + "numero": 2 + }, + { + "titre": "Algorithmique - Programmation - Langages Avanc\u00e9", + "module": [ + { + "coefficient": 2.0, + "code": "M1103", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 20.0, + "abbrev": "Structure de donn\u00e9es", + "numero": 3, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Structure de donn\u00e9es et algorithmes fondamentaux", + "heures_td": 15.0 + } + ], + "numero": 3 + }, + { + "titre": "Syst\u00e8mes de gestion de bases de donn\u00e9es", + "module": [ + { + "coefficient": 3.0, + "code": "M1104", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 25.0, + "abbrev": "BDD", + "numero": 4, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Introduction aux bases de donn\u00e9es", + "heures_td": 25.0 + } + ], + "numero": 4 + }, + { + "titre": "Web - Internet - Mobilit\u00e9 Expression - Communication", + "module": [ + { + "coefficient": 2.0, + "code": "M1105", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 25.0, + "abbrev": "CDIN", + "numero": 5, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Conception de documents et d\u2019interfaces num\u00e9riques", + "heures_td": 20.0 + } + ], + "numero": 5 + }, + { + "titre": "Projets tutor\u00e9s", + "module": [ + { + "coefficient": 3.0, + "code": "M1106", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "Projet", + "numero": 6, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Projet tutor\u00e9 : d\u00e9couverte", + "heures_td": 0.0 + } + ], + "numero": 6 + } + ], + "ue_code": "UE11", + "numero": 1, + "titre": "Base de l'informatique", + "type": 0 + }, + { + "acronyme": "UE21", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Architecture mat\u00e9rielle - Syst\u00e8mes d\u2019exploitation - R\u00e9seaux", + "module": [ + { + "coefficient": 2.0, + "code": "M2101", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Architecture et Programmation des m\u00e9canismes de base d\u2019un syst\u00e8me informatique", + "heures_td": 10.0 + } + ], + "numero": 1 + }, + { + "titre": "Architecture mat\u00e9rielle - Syst\u00e8mes d\u2019exploitation - R\u00e9seaux avanc\u00e9", + "module": [ + { + "coefficient": 2.0, + "code": "M2102", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Architecture des r\u00e9seaux", + "heures_td": 10.0 + } + ], + "numero": 2 + }, + { + "titre": "Algorithmique - Programmation - Langages Analyse, conception et d\u00e9veloppement d\u2019applications", + "module": [ + { + "coefficient": 2.0, + "code": "M2103", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 30.0, + "abbrev": "", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Bases de la programmation orient\u00e9e objet", + "heures_td": 20.0 + } + ], + "numero": 3 + }, + { + "titre": "Analyse, conception et d\u00e9veloppement d\u2019applications", + "module": [ + { + "coefficient": 2.0, + "code": "M2104", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 20.0, + "abbrev": "COO", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Bases de la conception orient\u00e9e objet", + "heures_td": 15.0 + } + ], + "numero": 4 + }, + { + "titre": "Interface homme-machine", + "module": [ + { + "coefficient": 2.0, + "code": "M2105", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 20.0, + "abbrev": "", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Introduction aux interfaces homme-machine", + "heures_td": 15.0 + } + ], + "numero": 5 + }, + { + "titre": "Syst\u00e8mes de gestion de bases de donn\u00e9es", + "module": [ + { + "coefficient": 2.0, + "code": "M2106", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 20.0, + "abbrev": "", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Programmation et administration des bases de donn\u00e9es", + "heures_td": 15.0 + } + ], + "numero": 6 + }, + { + "titre": "Projets tutor\u00e9s", + "module": [ + { + "coefficient": 3.0, + "code": "M2107", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Projet tutor\u00e9 : Description et planification de projet", + "heures_td": 0.0 + } + ], + "numero": 7 + } + ], + "ue_code": "UE21", + "numero": 1, + "titre": "Informatique approfondie", + "type": 0 + }, + { + "acronyme": "UE31", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Architectures mat\u00e9rielles - Syst\u00e8mes d\u2019exploitation - R\u00e9seaux", + "module": [ + { + "coefficient": 2.0, + "code": "M3101", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 16.0, + "abbrev": "", + "numero": 10, + "heures_cours": 15.0, + "module_type": 0, + "titre": "Principes des syst\u00e8mes d\u2019exploitation", + "heures_td": 14.0 + } + ], + "numero": 1 + }, + { + "titre": "Architectures mat\u00e9rielles - Syst\u00e8mes d\u2019exploitation, R\u00e9seaux", + "module": [ + { + "coefficient": 2.0, + "code": "M3102", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Services r\u00e9seaux", + "heures_td": 10.0 + } + ], + "numero": 2 + }, + { + "titre": "Algorithmique - Programmation - Langages avanc\u00e9", + "module": [ + { + "coefficient": 2.0, + "code": "M3103", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Algorithmique avanc\u00e9e", + "heures_td": 10.0 + } + ], + "numero": 3 + }, + { + "titre": "Web - Internet - Mobilit\u00e9", + "module": [ + { + "coefficient": 2.0, + "code": "M3104", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 16.0, + "abbrev": "", + "numero": 10, + "heures_cours": 15.0, + "module_type": 0, + "titre": "Programmation Web c\u00f4t\u00e9 serveur", + "heures_td": 14.0 + } + ], + "numero": 4 + }, + { + "titre": "Analyse, conception et d\u00e9veloppement d\u2019applications", + "module": [ + { + "coefficient": 16.0, + "code": "M3105", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 14.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Conception et programmation objet avanc\u00e9es", + "heures_td": 15.0 + } + ], + "numero": 5 + }, + { + "titre": "Syst\u00e8mes de gestion de bases de donn\u00e9es", + "module": [ + { + "coefficient": 2.0, + "code": "M3106C", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Bases de donn\u00e9es avanc\u00e9es", + "heures_td": 10.0 + } + ], + "numero": 6 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS1", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 16 + } + ], + "ue_code": "UCOD5", + "numero": 1, + "titre": "Informatique avanc\u00e9e", + "type": 0 + }, + { + "acronyme": "UE41", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Architectures mat\u00e9rielles - Syst\u00e8mes d\u2019exploitation - R\u00e9seaux", + "module": [ + { + "coefficient": 2.0, + "code": "M4101C", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Administration syst\u00e8me et r\u00e9seau", + "heures_td": 10.0 + } + ], + "numero": 1 + }, + { + "titre": "Architectures mat\u00e9rielles - Syst\u00e8mes d\u2019exploitation \u2013 R\u00e9seaux Analyse, conception et d\u00e9veloppement d\u2019applications", + "module": [ + { + "coefficient": 2.0, + "code": "M4102C", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Programmation r\u00e9partie", + "heures_td": 10.0 + } + ], + "numero": 2 + }, + { + "titre": "Web \u2013 Internet - Mobilit\u00e9", + "module": [ + { + "coefficient": 2.0, + "code": "M4103C", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Programmation Web \u2013 client riche", + "heures_td": 10.0 + } + ], + "numero": 3 + }, + { + "titre": "Web - Internet - Mobilit\u00e9 - Mobile", + "module": [ + { + "coefficient": 3.0, + "code": "M4104C", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Conception et d\u00e9veloppement d\u2019applications mobiles", + "heures_td": 10.0 + } + ], + "numero": 4 + }, + { + "titre": "Analyse, conception et d\u00e9veloppement d\u2019applications", + "module": [ + { + "coefficient": 2.0, + "code": "M4105C", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Compl\u00e9ments d\u2019informatique en vue d\u2019une insertion imm\u00e9diate", + "heures_td": 10.0 + } + ], + "numero": 5 + }, + { + "titre": "Projets tutor\u00e9s", + "module": [ + { + "coefficient": 3.0, + "code": "M4106", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Projet tutor\u00e9 \u2013 Compl\u00e9ments", + "heures_td": 0.0 + } + ], + "numero": 6 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS1", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 16 + } + ], + "ue_code": "UCOD8", + "numero": 1, + "titre": "Compl\u00e9ments en informatique", + "type": 0 + }, + { + "acronyme": "UE12", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Math\u00e9matiques", + "module": [ + { + "coefficient": 2.0, + "code": "M1201", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 17.0, + "abbrev": "", + "numero": 1, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Math\u00e9matiques discr\u00e8tes", + "heures_td": 18.0 + } + ], + "numero": 1 + }, + { + "titre": "Math\u00e9matiques avanc\u00e9es", + "module": [ + { + "coefficient": 2.0, + "code": "M1202", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 12.0, + "abbrev": "", + "numero": 10, + "heures_cours": 6.0, + "module_type": 0, + "titre": "Alg\u00e8bre lin\u00e9aire", + "heures_td": 12.0 + } + ], + "numero": 2 + }, + { + "titre": "\u00c9conomie - Gestion - Organisation - Droit", + "module": [ + { + "coefficient": 2.0, + "code": "M1203", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Environnement \u00e9conomique", + "heures_td": 10.0 + } + ], + "numero": 3 + }, + { + "titre": "Organisation", + "module": [ + { + "coefficient": 1.0, + "code": "M1204", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Fonctionnement des organisations", + "heures_td": 20.0 + } + ], + "numero": 4 + }, + { + "titre": "Expression - Communication", + "module": [ + { + "coefficient": 2.0, + "code": "M1205", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Fondamentaux de la communication", + "heures_td": 15.0 + } + ], + "numero": 5 + }, + { + "titre": "Anglais", + "module": [ + { + "coefficient": 2.0, + "code": "M1206", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Anglais et Informatique", + "heures_td": 15.0 + } + ], + "numero": 6 + }, + { + "titre": "PPP Expression - Communication", + "module": [ + { + "coefficient": 1.0, + "code": "M1207", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Conna\u00eetre le monde professionnel", + "heures_td": 10.0 + } + ], + "numero": 7 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS2", + "semestre_id": 1, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 17 + } + ], + "ue_code": "UE12", + "numero": 2, + "titre": "Bases de culture scientifique, sociale et humaine", + "type": 0 + }, + { + "acronyme": "UE22", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Math\u00e9matiques", + "module": [ + { + "coefficient": 2.0, + "code": "M2201", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 18.0, + "abbrev": "", + "numero": 10, + "heures_cours": 11.0, + "module_type": 0, + "titre": "Graphes et langages", + "heures_td": 16.0 + } + ], + "numero": 1 + }, + { + "titre": "Math\u00e9matiques avanc\u00e9es", + "module": [ + { + "coefficient": 2.0, + "code": "M2202", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Analyse et m\u00e9thodes num\u00e9riques", + "heures_td": 12.0 + } + ], + "numero": 2 + }, + { + "titre": "\u00c9conomie - Gestion - Droit - Organisation", + "module": [ + { + "coefficient": 2.0, + "code": "M2203", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 12.0, + "module_type": 0, + "titre": "Environnement comptable, financier, juridique et social", + "heures_td": 18.0 + } + ], + "numero": 3 + }, + { + "titre": "\u00c9conomie - Gestion - Organisation - Droit Analyse, conception et d\u00e9veloppement d\u2019applications", + "module": [ + { + "coefficient": 2.0, + "code": "M2204", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Gestion de projet informatique", + "heures_td": 12.0 + } + ], + "numero": 4 + }, + { + "titre": "Expression - Communication", + "module": [ + { + "coefficient": 1.0, + "code": "M2205", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Communication, information et argumentation", + "heures_td": 15.0 + } + ], + "numero": 5 + }, + { + "titre": "Anglais", + "module": [ + { + "coefficient": 2.0, + "code": "M2206", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 22.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Communiquer en anglais", + "heures_td": 23.0 + } + ], + "numero": 6 + }, + { + "titre": "PPP", + "module": [ + { + "coefficient": 1.0, + "code": "M2207", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "PPP - Identifier ses comp\u00e9tences", + "heures_td": 10.0 + } + ], + "numero": 7 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS2", + "semestre_id": 2, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 17 + } + ], + "ue_code": "UCOD4", + "numero": 2, + "titre": "Approfondissements en culture scientifique, sociale et humaine", + "type": 0 + }, + { + "acronyme": "UE32", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Math\u00e9matiques", + "module": [ + { + "coefficient": 2.0, + "code": "M3201", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 14.0, + "abbrev": "", + "numero": 10, + "heures_cours": 15.0, + "module_type": 0, + "titre": "Probabilit\u00e9s et statistique", + "heures_td": 16.0 + } + ], + "numero": 1 + }, + { + "titre": "Math\u00e9matiques avanc\u00e9es", + "module": [ + { + "coefficient": 2.0, + "code": "M3202C", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 14.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Mod\u00e9lisations math\u00e9matiques", + "heures_td": 16.0 + } + ], + "numero": 2 + }, + { + "titre": "\u00c9conomie - Gestion - Organisation - Droit", + "module": [ + { + "coefficient": 2.0, + "code": "M3203", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 10.0, + "module_type": 0, + "titre": "Droit des technologies de l\u2019information et de la communication", + "heures_td": 10.0 + } + ], + "numero": 3 + }, + { + "titre": "Gestion", + "module": [ + { + "coefficient": 2.0, + "code": "M3204", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 15.0, + "module_type": 0, + "titre": "Gestion des syst\u00e8mes d\u2019information", + "heures_td": 15.0 + } + ], + "numero": 4 + }, + { + "titre": "Expression - Communication", + "module": [ + { + "coefficient": 2.0, + "code": "M3205", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Communication professionnelle", + "heures_td": 15.0 + } + ], + "numero": 5 + }, + { + "titre": "Anglais", + "module": [ + { + "coefficient": 2.0, + "code": "M3206", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 22.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Collaborer en anglais", + "heures_td": 23.0 + } + ], + "numero": 6 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS2", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 16 + } + ], + "ue_code": "UCOD6", + "numero": 2, + "titre": "Culture scientifique, sociale et humaine avanc\u00e9es", + "type": 0 + }, + { + "acronyme": "UE33", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "Analyse, conception et d\u00e9veloppement d\u2019applications \u00c9conomie - gestion - Organisation - Droit", + "module": [ + { + "coefficient": 2.0, + "code": "M3301", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 24.0, + "abbrev": "", + "numero": 10, + "heures_cours": 14.0, + "module_type": 0, + "titre": "M\u00e9thodologie de la production d\u2019applications", + "heures_td": 22.0 + } + ], + "numero": 1 + }, + { + "titre": "Projets tutor\u00e9s", + "module": [ + { + "coefficient": 3.0, + "code": "M3302", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Projet tutor\u00e9 - Mise en situation professionnelle", + "heures_td": 0.0 + } + ], + "numero": 2 + }, + { + "titre": "PPP", + "module": [ + { + "coefficient": 2.0, + "code": "M3303", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "PPP - Pr\u00e9ciser son projet", + "heures_td": 10.0 + } + ], + "numero": 3 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS2", + "semestre_id": 3, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 13 + } + ], + "ue_code": "UCOD7", + "numero": 2, + "titre": "M\u00e9thodologie et projets", + "type": 0 + }, + { + "acronyme": "UE42", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "\u00c9conomie - Gestion - Organisation - Droit", + "module": [ + { + "coefficient": 2.0, + "code": "M4201C", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Ateliers de cr\u00e9ation d\u2019entreprise", + "heures_td": 12.0 + } + ], + "numero": 1 + }, + { + "titre": "Math\u00e9matiques", + "module": [ + { + "coefficient": 2.0, + "code": "M4202C", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 10.0, + "abbrev": "", + "numero": 10, + "heures_cours": 8.0, + "module_type": 0, + "titre": "Introduction \u00e0 la recherche op\u00e9rationnelle et aide \u00e0 la d\u00e9cision", + "heures_td": 12.0 + } + ], + "numero": 2 + }, + { + "titre": "Expression \u2013 Communication", + "module": [ + { + "coefficient": 2.0, + "code": "M4203", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Communication dans les organisations", + "heures_td": 15.0 + } + ], + "numero": 3 + }, + { + "titre": "Anglais", + "module": [ + { + "coefficient": 2.0, + "code": "M4204", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 15.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Travailler en anglais", + "heures_td": 15.0 + } + ], + "numero": 4 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS2", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 14 + } + ], + "ue_code": "UCOD9", + "numero": 2, + "titre": "Compl\u00e9ments de culture scientifique, sociale et humaine", + "type": 0 + }, + { + "acronyme": "UE43", + "coefficient": 0.0, + "is_external": 0, + "code_apogee": "", + "matiere": [ + { + "titre": "STAGE", + "module": [ + { + "coefficient": 12.0, + "code": "M4301", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 10, + "heures_cours": 0.0, + "module_type": 0, + "titre": "Stage professionnel", + "heures_td": 0.0 + } + ], + "numero": 1 + }, + { + "titre": "Malus", + "module": [ + { + "coefficient": 0.0, + "code": "MALUS3", + "semestre_id": 4, + "code_apogee": "", + "ects": "", + "heures_tp": 0.0, + "abbrev": "", + "numero": 0, + "heures_cours": 0.0, + "module_type": 1, + "titre": "", + "heures_td": 0.0 + } + ], + "numero": 11 + } + ], + "ue_code": "UCOD10", + "numero": 3, + "titre": "Mise en situation professionnelle", + "type": 0 + } + ], + "titre": "DUT Informatique", + "formation_id": "FORM234" +} \ No newline at end of file From 6110b477aa3640443f9c3b47dffb6060b2979b5c Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 31 May 2021 17:55:43 +0200 Subject: [PATCH 05/21] user_info: ajout arg format --- ZScoUsers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ZScoUsers.py b/ZScoUsers.py index 21bf8302..ec86bfa1 100644 --- a/ZScoUsers.py +++ b/ZScoUsers.py @@ -261,7 +261,7 @@ class ZScoUsers( security.declareProtected(ScoUsersAdmin, "user_info") - def user_info(self, user_name=None, user=None): + def user_info(self, user_name=None, user=None, format=None, REQUEST=None): """Donne infos sur l'utilisateur (qui peut ne pas etre dans notre base). Si user_name est specifie, interroge la BD. Sinon, user doit etre un dict. """ @@ -322,7 +322,7 @@ class ZScoUsers( # nomnoacc est le nom en minuscules sans accents info["nomnoacc"] = scu.suppress_accents(scu.strlower(info["nom"])) - return info + return scu.sendResult(REQUEST, info, name="user", format=format) def _can_handle_passwd(self, authuser, user_name, allow_admindepts=False): """true if authuser can see or change passwd of user_name. From a4bc316eead823641f6e3fef8e80244372a93dfb Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Tue, 8 Jun 2021 12:25:04 +0200 Subject: [PATCH 06/21] Mobile v1.3 --- static/mobile/asset-manifest.json | 24 +++++++++---------- static/mobile/index.html | 2 +- ....fb06b1f5.chunk.js => 2.64a47d60.chunk.js} | 6 ++--- ...SE.txt => 2.64a47d60.chunk.js.LICENSE.txt} | 0 .../mobile/static/js/2.64a47d60.chunk.js.map | 1 + .../mobile/static/js/2.fb06b1f5.chunk.js.map | 1 - ....b810fcea.chunk.js => 3.92b28fed.chunk.js} | 4 ++-- ...a.chunk.js.map => 3.92b28fed.chunk.js.map} | 2 +- .../mobile/static/js/main.1a008285.chunk.js | 2 -- .../static/js/main.1a008285.chunk.js.map | 1 - .../mobile/static/js/main.96d680e0.chunk.js | 2 ++ .../static/js/main.96d680e0.chunk.js.map | 1 + ...n.f39ba660.js => runtime-main.ca83272f.js} | 4 ++-- ...60.js.map => runtime-main.ca83272f.js.map} | 2 +- 14 files changed, 26 insertions(+), 26 deletions(-) rename static/mobile/static/js/{2.fb06b1f5.chunk.js => 2.64a47d60.chunk.js} (81%) rename static/mobile/static/js/{2.fb06b1f5.chunk.js.LICENSE.txt => 2.64a47d60.chunk.js.LICENSE.txt} (100%) create mode 100644 static/mobile/static/js/2.64a47d60.chunk.js.map delete mode 100644 static/mobile/static/js/2.fb06b1f5.chunk.js.map rename static/mobile/static/js/{3.b810fcea.chunk.js => 3.92b28fed.chunk.js} (97%) rename static/mobile/static/js/{3.b810fcea.chunk.js.map => 3.92b28fed.chunk.js.map} (99%) delete mode 100644 static/mobile/static/js/main.1a008285.chunk.js delete mode 100644 static/mobile/static/js/main.1a008285.chunk.js.map create mode 100644 static/mobile/static/js/main.96d680e0.chunk.js create mode 100644 static/mobile/static/js/main.96d680e0.chunk.js.map rename static/mobile/static/js/{runtime-main.f39ba660.js => runtime-main.ca83272f.js} (95%) rename static/mobile/static/js/{runtime-main.f39ba660.js.map => runtime-main.ca83272f.js.map} (98%) diff --git a/static/mobile/asset-manifest.json b/static/mobile/asset-manifest.json index 76eac7cc..562c2d63 100644 --- a/static/mobile/asset-manifest.json +++ b/static/mobile/asset-manifest.json @@ -1,25 +1,25 @@ { "files": { "main.css": "./static/css/main.6be5a531.chunk.css", - "main.js": "./static/js/main.1a008285.chunk.js", - "main.js.map": "./static/js/main.1a008285.chunk.js.map", - "runtime-main.js": "./static/js/runtime-main.f39ba660.js", - "runtime-main.js.map": "./static/js/runtime-main.f39ba660.js.map", + "main.js": "./static/js/main.96d680e0.chunk.js", + "main.js.map": "./static/js/main.96d680e0.chunk.js.map", + "runtime-main.js": "./static/js/runtime-main.ca83272f.js", + "runtime-main.js.map": "./static/js/runtime-main.ca83272f.js.map", "static/css/2.4c97ca4f.chunk.css": "./static/css/2.4c97ca4f.chunk.css", - "static/js/2.fb06b1f5.chunk.js": "./static/js/2.fb06b1f5.chunk.js", - "static/js/2.fb06b1f5.chunk.js.map": "./static/js/2.fb06b1f5.chunk.js.map", - "static/js/3.b810fcea.chunk.js": "./static/js/3.b810fcea.chunk.js", - "static/js/3.b810fcea.chunk.js.map": "./static/js/3.b810fcea.chunk.js.map", + "static/js/2.64a47d60.chunk.js": "./static/js/2.64a47d60.chunk.js", + "static/js/2.64a47d60.chunk.js.map": "./static/js/2.64a47d60.chunk.js.map", + "static/js/3.92b28fed.chunk.js": "./static/js/3.92b28fed.chunk.js", + "static/js/3.92b28fed.chunk.js.map": "./static/js/3.92b28fed.chunk.js.map", "index.html": "./index.html", "static/css/2.4c97ca4f.chunk.css.map": "./static/css/2.4c97ca4f.chunk.css.map", "static/css/main.6be5a531.chunk.css.map": "./static/css/main.6be5a531.chunk.css.map", - "static/js/2.fb06b1f5.chunk.js.LICENSE.txt": "./static/js/2.fb06b1f5.chunk.js.LICENSE.txt" + "static/js/2.64a47d60.chunk.js.LICENSE.txt": "./static/js/2.64a47d60.chunk.js.LICENSE.txt" }, "entrypoints": [ - "static/js/runtime-main.f39ba660.js", + "static/js/runtime-main.ca83272f.js", "static/css/2.4c97ca4f.chunk.css", - "static/js/2.fb06b1f5.chunk.js", + "static/js/2.64a47d60.chunk.js", "static/css/main.6be5a531.chunk.css", - "static/js/main.1a008285.chunk.js" + "static/js/main.96d680e0.chunk.js" ] } \ No newline at end of file diff --git a/static/mobile/index.html b/static/mobile/index.html index 606c6167..fddcbee4 100644 --- a/static/mobile/index.html +++ b/static/mobile/index.html @@ -1 +1 @@ -Scodoc Mobile
\ No newline at end of file +Scodoc Mobile
\ No newline at end of file diff --git a/static/mobile/static/js/2.fb06b1f5.chunk.js b/static/mobile/static/js/2.64a47d60.chunk.js similarity index 81% rename from static/mobile/static/js/2.fb06b1f5.chunk.js rename to static/mobile/static/js/2.64a47d60.chunk.js index 9e08a811..e2a7817a 100644 --- a/static/mobile/static/js/2.fb06b1f5.chunk.js +++ b/static/mobile/static/js/2.64a47d60.chunk.js @@ -1,3 +1,3 @@ -/*! For license information please see 2.fb06b1f5.chunk.js.LICENSE.txt */ -(this.webpackJsonpscodocmobile=this.webpackJsonpscodocmobile||[]).push([[2],[function(e,t,n){"use strict";e.exports=n(78)},function(e,t,n){"use strict";e.exports=n(82)},function(e,t,n){"use strict";function r(){return(r=Object.assign||function(e){for(var t=1;t=0||(o[n]=e[n]);return o}n.d(t,"a",(function(){return r}))},function(e,t,n){var r;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t1?t-1:0),o=1;o=0;d--){var p=i[d];"."===p?a(i,d):".."===p?(a(i,d),f++):f&&(a(i,d),f--)}if(!u)for(;f--;f)i.unshift("..");!u||""===i[0]||i[0]&&o(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};function l(e){return e.valueOf?e.valueOf():Object.prototype.valueOf.call(e)}var s=function e(t,n){if(t===n)return!0;if(null==t||null==n)return!1;if(Array.isArray(t))return Array.isArray(n)&&t.length===n.length&&t.every((function(t,r){return e(t,n[r])}));if("object"===typeof t||"object"===typeof n){var r=l(t),o=l(n);return r!==t||o!==n?e(r,o):Object.keys(Object.assign({},t,n)).every((function(r){return e(t[r],n[r])}))}return!1},u=n(22);function c(e){return"/"===e.charAt(0)?e:"/"+e}function f(e){return"/"===e.charAt(0)?e.substr(1):e}function d(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function p(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function m(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function h(e,t,n,o){var a;"string"===typeof e?(a=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var a=t.indexOf("?");return-1!==a&&(n=t.substr(a),t=t.substr(0,a)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e)).state=t:(void 0===(a=Object(r.a)({},e)).pathname&&(a.pathname=""),a.search?"?"!==a.search.charAt(0)&&(a.search="?"+a.search):a.search="",a.hash?"#"!==a.hash.charAt(0)&&(a.hash="#"+a.hash):a.hash="",void 0!==t&&void 0===a.state&&(a.state=t));try{a.pathname=decodeURI(a.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(a.key=n),o?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=i(a.pathname,o.pathname)):a.pathname=o.pathname:a.pathname||(a.pathname="/"),a}function v(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.hash===t.hash&&e.key===t.key&&s(e.state,t.state)}function b(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var a="function"===typeof e?e(t,n):e;"string"===typeof a?"function"===typeof r?r(a,o):o(!0):o(!1!==a)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,o):n.push(o),f({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=h(e,t,d(),w.location);c.confirmTransitionTo(o,r,n,(function(e){e&&(w.entries[w.index]=o,f({action:r,location:o}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}(this.props,[]);return function(e){c.forEach((function(t){return delete e[t]}))}(o),o.className=this.props.inputClassName,o.id=this.state.inputId,o.style=n,i.default.createElement("div",{className:this.props.className,style:t},this.renderStyles(),i.default.createElement("input",r({},o,{ref:this.inputRef})),i.default.createElement("div",{ref:this.sizerRef,style:u},e),this.props.placeholder?i.default.createElement("div",{ref:this.placeHolderSizerRef,style:u},this.props.placeholder):null)}}]),t}(a.Component);m.propTypes={className:l.default.string,defaultValue:l.default.any,extraWidth:l.default.oneOfType([l.default.number,l.default.string]),id:l.default.string,injectStyles:l.default.bool,inputClassName:l.default.string,inputRef:l.default.func,inputStyle:l.default.object,minWidth:l.default.oneOfType([l.default.number,l.default.string]),onAutosize:l.default.func,onChange:l.default.func,placeholder:l.default.string,placeholderIsMinWidth:l.default.bool,style:l.default.object,value:l.default.any},m.defaultProps={minWidth:1,injectStyles:!0},t.default=m},function(e,t,n){"use strict";(function(e){var r=n(0),o=n.n(r),a=n(15),i=n(6),l=n.n(i),s=1073741823,u="undefined"!==typeof globalThis?globalThis:"undefined"!==typeof window?window:"undefined"!==typeof e?e:{};function c(e){var t=[];return{on:function(e){t.push(e)},off:function(e){t=t.filter((function(t){return t!==e}))},get:function(){return e},set:function(n,r){e=n,t.forEach((function(t){return t(e,r)}))}}}var f=o.a.createContext||function(e,t){var n,o,i="__create-react-context-"+function(){var e="__global_unique_id__";return u[e]=(u[e]||0)+1}()+"__",f=function(e){function n(){var t;return(t=e.apply(this,arguments)||this).emitter=c(t.props.value),t}Object(a.a)(n,e);var r=n.prototype;return r.getChildContext=function(){var e;return(e={})[i]=this.emitter,e},r.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,o=e.value;((a=r)===(i=o)?0!==a||1/a===1/i:a!==a&&i!==i)?n=0:(n="function"===typeof t?t(r,o):s,0!==(n|=0)&&this.emitter.set(e.value,n))}var a,i},r.render=function(){return this.props.children},n}(r.Component);f.childContextTypes=((n={})[i]=l.a.object.isRequired,n);var d=function(t){function n(){var e;return(e=t.apply(this,arguments)||this).state={value:e.getValue()},e.onUpdate=function(t,n){0!==((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}Object(a.a)(n,t);var r=n.prototype;return r.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=void 0===t||null===t?s:t},r.componentDidMount=function(){this.context[i]&&this.context[i].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=void 0===e||null===e?s:e},r.componentWillUnmount=function(){this.context[i]&&this.context[i].off(this.onUpdate)},r.getValue=function(){return this.context[i]?this.context[i].get():e},r.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(r.Component);return d.contextTypes=((o={})[i]=l.a.object,o),{Provider:f,Consumer:d}};t.a=f}).call(this,n(86))},function(e,t,n){var r=n(87);e.exports=p,e.exports.parse=a,e.exports.compile=function(e,t){return l(a(e,t),t)},e.exports.tokensToFunction=l,e.exports.tokensToRegExp=d;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function a(e,t){for(var n,r=[],a=0,i=0,l="",c=t&&t.delimiter||"/";null!=(n=o.exec(e));){var f=n[0],d=n[1],p=n.index;if(l+=e.slice(i,p),i=p+f.length,d)l+=d[1];else{var m=e[i],h=n[2],v=n[3],b=n[4],g=n[5],y=n[6],w=n[7];l&&(r.push(l),l="");var O=null!=h&&null!=m&&m!==h,x="+"===y||"*"===y,E="?"===y||"*"===y,k=n[2]||c,S=b||g;r.push({name:v||a++,prefix:h||"",delimiter:k,optional:E,repeat:x,partial:O,asterisk:!!w,pattern:S?u(S):w?".*":"[^"+s(k)+"]+?"})}}return i>",l=a||n;if(null==t[n])return new Error("The "+o+" `"+l+"` is required to make `"+i+"` accessible for users of assistive technologies such as screen readers.");for(var s=arguments.length,u=Array(s>5?s-5:0),c=5;ce.length)&&(t=e.length);for(var n=0,r=new Array(t);n1&&void 0!==arguments[1]?arguments[1]:"none";return e||t},p=function(){return!("undefined"===typeof window||!window.navigator&&!navigator)&&(window.navigator||navigator)},m=function(e){var t=p();return t&&t.platform&&(-1!==t.platform.indexOf(e)||"MacIntel"===t.platform&&t.maxTouchPoints>1&&!window.MSStream)};function h(e){return(h="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function v(e,t){for(var n=0;n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function E(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}var k="mobile",S="tablet",C="smarttv",j="console",P="wearable",N=void 0,T={Chrome:"Chrome",Firefox:"Firefox",Opera:"Opera",Yandex:"Yandex",Safari:"Safari",InternetExplorer:"Internet Explorer",Edge:"Edge",Chromium:"Chromium",Ie:"IE",MobileSafari:"Mobile Safari",EdgeChromium:"Edge Chromium",MIUI:"MIUI Browser",SamsungBrowser:"Samsung Browser"},_={IOS:"iOS",Android:"Android",WindowsPhone:"Windows Phone",Windows:"Windows",MAC_OS:"Mac OS"},M={isMobile:!1,isTablet:!1,isBrowser:!1,isSmartTV:!1,isConsole:!1,isWearable:!1},I=function(e,t,n,r){return function(e){for(var t=1;t1)&&!window.MSStream}(),be=A(),ge=m("iPhone"),ye=m("iPod"),we=function(){var e=p(),t=e&&e.userAgent&&e.userAgent.toLowerCase();return"string"===typeof t&&/electron/.test(t)}(),Oe=L(),xe=F()&&!L(),Ee=c.name===_.Windows,ke=c.name===_.MAC_OS,Se=l.name===T.MIUI,Ce=l.name===T.SamsungBrowser;t.AndroidView=function(e){var t=e.renderWithFragment,n=e.children,r=e.viewClassName,i=e.style,l=x(e,["renderWithFragment","children","viewClassName","style"]);return Y?t?a.createElement(o.Fragment,null,n):a.createElement("div",g({className:r,style:i},l),n):null},t.BrowserTypes=T,t.BrowserView=function(e){var t=e.renderWithFragment,n=e.children,r=e.viewClassName,i=e.style,l=x(e,["renderWithFragment","children","viewClassName","style"]);return q?t?a.createElement(o.Fragment,null,n):a.createElement("div",g({className:r,style:i},l),n):null},t.ConsoleView=function(e){var t=e.renderWithFragment,n=e.children,r=e.viewClassName,i=e.style,l=x(e,["renderWithFragment","children","viewClassName","style"]);return z?t?a.createElement(o.Fragment,null,n):a.createElement("div",g({className:r,style:i},l),n):null},t.CustomView=function(e){var t=e.renderWithFragment,n=e.children,r=e.viewClassName,i=e.style,l=e.condition,s=x(e,["renderWithFragment","children","viewClassName","style","condition"]);return l?t?a.createElement(o.Fragment,null,n):a.createElement("div",g({className:r,style:i},s),n):null},t.IEView=function(e){var t=e.renderWithFragment,n=e.children,r=e.viewClassName,i=e.style,l=x(e,["renderWithFragment","children","viewClassName","style"]);return ne?t?a.createElement(o.Fragment,null,n):a.createElement("div",g({className:r,style:i},l),n):null},t.IOSView=function(e){var t=e.renderWithFragment,n=e.children,r=e.viewClassName,i=e.style,l=x(e,["renderWithFragment","children","viewClassName","style"]);return X?t?a.createElement(o.Fragment,null,n):a.createElement("div",g({className:r,style:i},l),n):null},t.MobileOnlyView=function(e){var t=e.renderWithFragment,n=e.children,r=e.viewClassName,i=e.style,l=x(e,["renderWithFragment","children","viewClassName","style"]);return $?t?a.createElement(o.Fragment,null,n):a.createElement("div",g({className:r,style:i},l),n):null},t.MobileView=function(e){var t=e.renderWithFragment,n=e.children,r=e.viewClassName,i=e.style,l=x(e,["renderWithFragment","children","viewClassName","style"]);return H?t?a.createElement(o.Fragment,null,n):a.createElement("div",g({className:r,style:i},l),n):null},t.OsTypes=_,t.SmartTVView=function(e){var t=e.renderWithFragment,n=e.children,r=e.viewClassName,i=e.style,l=x(e,["renderWithFragment","children","viewClassName","style"]);return V?t?a.createElement(o.Fragment,null,n):a.createElement("div",g({className:r,style:i},l),n):null},t.TabletView=function(e){var t=e.renderWithFragment,n=e.children,r=e.viewClassName,i=e.style,l=x(e,["renderWithFragment","children","viewClassName","style"]);return K?t?a.createElement(o.Fragment,null,n):a.createElement("div",g({className:r,style:i},l),n):null},t.WearableView=function(e){var t=e.renderWithFragment,n=e.children,r=e.viewClassName,i=e.style,l=x(e,["renderWithFragment","children","viewClassName","style"]);return U?t?a.createElement(o.Fragment,null,n):a.createElement("div",g({className:r,style:i},l),n):null},t.WinPhoneView=function(e){var t=e.renderWithFragment,n=e.children,r=e.viewClassName,i=e.style,l=x(e,["renderWithFragment","children","viewClassName","style"]);return G?t?a.createElement(o.Fragment,null,n):a.createElement("div",g({className:r,style:i},l),n):null},t.browserName=le,t.browserVersion=ie,t.deviceDetect=function(){var e=R.isBrowser,t=R.isMobile,n=R.isTablet,r=R.isSmartTV,o=R.isConsole,a=R.isWearable;return e?function(e,t,n,r,o){return{isBrowser:e,browserMajorVersion:d(t.major),browserFullVersion:d(t.version),browserName:d(t.name),engineName:d(n.name),engineVersion:d(n.version),osName:d(r.name),osVersion:d(r.version),userAgent:d(o)}}(e,l,u,c,f):r?function(e,t,n,r){return{isSmartTV:e,engineName:d(t.name),engineVersion:d(t.version),osName:d(n.name),osVersion:d(n.version),userAgent:d(r)}}(r,u,c,f):o?function(e,t,n,r){return{isConsole:e,engineName:d(t.name),engineVersion:d(t.version),osName:d(n.name),osVersion:d(n.version),userAgent:d(r)}}(o,u,c,f):t||n?I(R,s,c,f):a?function(e,t,n,r){return{isWearable:e,engineName:d(t.name),engineVersion:d(t.version),osName:d(n.name),osVersion:d(n.version),userAgent:d(r)}}(a,u,c,f):void 0},t.deviceType=he,t.engineName=ce,t.engineVersion=fe,t.fullBrowserVersion=ae,t.getUA=de,t.isAndroid=Y,t.isBrowser=q,t.isChrome=Z,t.isChromium=W,t.isConsole=z,t.isDesktop=Q,t.isEdge=pe,t.isEdgeChromium=Oe,t.isElectron=we,t.isFirefox=J,t.isIE=ne,t.isIOS=X,t.isIOS13=ve,t.isIPad13=be,t.isIPhone13=ge,t.isIPod13=ye,t.isLegacyEdge=xe,t.isMIUI=Se,t.isMacOs=ke,t.isMobile=H,t.isMobileOnly=$,t.isMobileSafari=B,t.isOpera=te,t.isSafari=ee,t.isSamsungBrowser=Ce,t.isSmartTV=V,t.isTablet=K,t.isWearable=U,t.isWinPhone=G,t.isWindows=Ee,t.isYandex=me,t.mobileModel=ue,t.mobileVendor=se,t.osName=oe,t.osVersion=re,t.withOrientationChange=function(e){return function(t){function n(e){var t;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n),(t=function(e,t){return!t||"object"!==typeof t&&"function"!==typeof t?E(e):t}(this,w(n).call(this,e))).isEventListenerAdded=!1,t.handleOrientationChange=t.handleOrientationChange.bind(E(t)),t.onOrientationChange=t.onOrientationChange.bind(E(t)),t.onPageLoad=t.onPageLoad.bind(E(t)),t.state={isLandscape:!1,isPortrait:!1},t}var r,o,i;return function(e,t){if("function"!==typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&O(e,t)}(n,t),r=n,(o=[{key:"handleOrientationChange",value:function(){this.isEventListenerAdded||(this.isEventListenerAdded=!0);var e=window.innerWidth>window.innerHeight?90:0;this.setState({isPortrait:0===e,isLandscape:90===e})}},{key:"onOrientationChange",value:function(){this.handleOrientationChange()}},{key:"onPageLoad",value:function(){this.handleOrientationChange()}},{key:"componentDidMount",value:function(){void 0!==("undefined"===typeof window?"undefined":h(window))&&H&&(this.isEventListenerAdded?window.removeEventListener("load",this.onPageLoad,!1):(this.handleOrientationChange(),window.addEventListener("load",this.onPageLoad,!1)),window.addEventListener("resize",this.onOrientationChange,!1))}},{key:"componentWillUnmount",value:function(){window.removeEventListener("resize",this.onOrientationChange,!1)}},{key:"render",value:function(){return a.createElement(e,g({},this.props,{isLandscape:this.state.isLandscape,isPortrait:this.state.isPortrait}))}}])&&v(r.prototype,o),i&&v(r,i),n}(a.Component)}},function(e,t,n){e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=8)}([function(e,t){e.exports=n(0)},function(e,t,n){e.exports=n(10)()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(){return"undefined"!=typeof window&&"IntersectionObserver"in window&&"isIntersecting"in window.IntersectionObserverEntry.prototype}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=0&&Number.isFinite(a.y)&&a.y>=0),n}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),r(t,[{key:"componentDidUpdate",value:function(e,t){t.visible!==this.state.visible&&this.props.afterLoad()}},{key:"onVisible",value:function(){this.props.beforeLoad(),this.setState({visible:!0})}},{key:"render",value:function(){if(this.state.visible)return this.props.children;var e=this.props,t=e.className,n=e.delayMethod,r=e.delayTime,a=e.height,u=e.placeholder,c=e.scrollPosition,f=e.style,d=e.threshold,p=e.useIntersectionObserver,m=e.width;return this.isScrollTracked||p&&(0,s.default)()?o.default.createElement(i.default,{className:t,height:a,onVisible:this.onVisible,placeholder:u,scrollPosition:c,style:f,threshold:d,useIntersectionObserver:p,width:m}):o.default.createElement(l.default,{className:t,delayMethod:n,delayTime:r,height:a,onVisible:this.onVisible,placeholder:u,style:f,threshold:d,width:m})}}]),t}(o.default.Component);c.propTypes={afterLoad:a.PropTypes.func,beforeLoad:a.PropTypes.func,useIntersectionObserver:a.PropTypes.bool,visibleByDefault:a.PropTypes.bool},c.defaultProps={afterLoad:function(){return{}},beforeLoad:function(){return{}},useIntersectionObserver:!0,visibleByDefault:!1},t.default=c},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=Object.assign||function(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:this.props.scrollPosition,t=this.placeholder.getBoundingClientRect(),n=i.default.findDOMNode(this.placeholder).style,r={left:parseInt(n.getPropertyValue("margin-left"),10)||0,top:parseInt(n.getPropertyValue("margin-top"),10)||0};return{bottom:e.y+t.bottom+r.top,left:e.x+t.left+r.left,right:e.x+t.right+r.left,top:e.y+t.top+r.top}}},{key:"isPlaceholderInViewport",value:function(){if("undefined"==typeof window||!this.placeholder)return!1;var e=this.props,t=e.scrollPosition,n=e.threshold,r=this.getPlaceholderBoundingBox(t),o=t.y+window.innerHeight,a=t.x,i=t.x+window.innerWidth,l=t.y;return Boolean(l-n<=r.bottom&&o+n>=r.top&&a-n<=r.right&&i+n>=r.left)}},{key:"updateVisibility",value:function(){this.isPlaceholderInViewport()&&this.props.onVisible()}},{key:"render",value:function(){var e=this,t=this.props,n=t.className,o=t.height,i=t.placeholder,l=t.style,s=t.width;if(i&&"function"!=typeof i.type)return a.default.cloneElement(i,{ref:function(t){return e.placeholder=t}});var u=r({display:"inline-block"},l);return void 0!==s&&(u.width=s),void 0!==o&&(u.height=o),a.default.createElement("span",{className:n,ref:function(t){return e.placeholder=t},style:u},i)}}]),t}(a.default.Component);d.propTypes={onVisible:l.PropTypes.func.isRequired,className:l.PropTypes.string,height:l.PropTypes.oneOfType([l.PropTypes.number,l.PropTypes.string]),placeholder:l.PropTypes.element,threshold:l.PropTypes.number,useIntersectionObserver:l.PropTypes.bool,scrollPosition:l.PropTypes.shape({x:l.PropTypes.number.isRequired,y:l.PropTypes.number.isRequired}),width:l.PropTypes.oneOfType([l.PropTypes.number,l.PropTypes.string])},d.defaultProps={className:"",placeholder:null,threshold:100,useIntersectionObserver:!0},t.default=d},function(e,t){e.exports=n(16)},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=Object.assign||function(e){for(var t=1;t=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}(t,["delayMethod","delayTime"])),o=this.useIntersectionObserver?null:this.state.scrollPosition;return a.default.createElement(e,r({ref:this.baseComponentRef,scrollPosition:o},n))}}]),n}(a.default.Component);return t.propTypes={delayMethod:l.PropTypes.oneOf(["debounce","throttle"]),delayTime:l.PropTypes.number,useIntersectionObserver:l.PropTypes.bool},t.defaultProps={delayMethod:"throttle",delayTime:300,useIntersectionObserver:!0},t}},function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.trackWindowScroll=t.LazyLoadComponent=t.LazyLoadImage=void 0;var r=i(n(9)),o=i(n(3)),a=i(n(6));function i(e){return e&&e.__esModule?e:{default:e}}t.LazyLoadImage=r.default,t.LazyLoadComponent=o.default,t.trackWindowScroll=a.default},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=Object.assign||function(e){for(var t=1;t=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}(e,["afterLoad","beforeLoad","delayMethod","delayTime","effect","placeholder","placeholderSrc","scrollPosition","threshold","useIntersectionObserver","visibleByDefault","wrapperClassName","wrapperProps"]));return a.default.createElement("img",r({onLoad:this.onImageLoad()},t))}},{key:"getLazyLoadImage",value:function(){var e=this.props,t=e.beforeLoad,n=e.className,r=e.delayMethod,o=e.delayTime,i=e.height,s=e.placeholder,u=e.scrollPosition,c=e.style,f=e.threshold,d=e.useIntersectionObserver,p=e.visibleByDefault,m=e.width;return a.default.createElement(l.default,{beforeLoad:t,className:n,delayMethod:r,delayTime:o,height:i,placeholder:s,scrollPosition:u,style:c,threshold:f,useIntersectionObserver:d,visibleByDefault:p,width:m},this.getImg())}},{key:"getWrappedLazyLoadImage",value:function(e){var t=this.props,n=t.effect,o=t.height,i=t.placeholderSrc,l=t.width,s=t.wrapperClassName,u=t.wrapperProps,c=this.state.loaded,f=c?" lazy-load-image-loaded":"";return a.default.createElement("span",r({className:s+" lazy-load-image-background "+n+f,style:{backgroundImage:c||!i?"":"url("+i+")",backgroundSize:c||!i?"":"100% 100%",display:"inline-block",height:o,width:l}},u),e)}},{key:"render",value:function(){var e=this.props,t=e.effect,n=e.placeholderSrc,r=e.visibleByDefault,o=e.wrapperClassName,a=e.wrapperProps,i=this.getLazyLoadImage();return(t||n)&&!r||o||a?this.getWrappedLazyLoadImage(i):i}}]),t}(a.default.Component);u.propTypes={afterLoad:i.PropTypes.func,beforeLoad:i.PropTypes.func,delayMethod:i.PropTypes.string,delayTime:i.PropTypes.number,effect:i.PropTypes.string,placeholderSrc:i.PropTypes.string,threshold:i.PropTypes.number,useIntersectionObserver:i.PropTypes.bool,visibleByDefault:i.PropTypes.bool,wrapperClassName:i.PropTypes.string,wrapperProps:i.PropTypes.object},u.defaultProps={afterLoad:function(){return{}},beforeLoad:function(){return{}},delayMethod:"throttle",delayTime:300,effect:"",placeholderSrc:null,threshold:100,useIntersectionObserver:!0,visibleByDefault:!1,wrapperClassName:""},t.default=u},function(e,t,n){"use strict";var r=n(11);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,a,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:o};return n.PropTypes=n,n}},function(e,t,n){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=t||n<0||v&&e-u>=a}function w(){var e=p();if(y(e))return O(e);l=setTimeout(w,function(e){var n=t-(e-s);return v?d(n,a-(e-u)):n}(e))}function O(e){return l=void 0,b&&r?g(e):(r=o=void 0,i)}function x(){var e=p(),n=y(e);if(r=arguments,o=this,s=e,n){if(void 0===l)return function(e){return u=e,l=setTimeout(w,t),c?g(e):i}(s);if(v)return l=setTimeout(w,t),g(s)}return void 0===l&&(l=setTimeout(w,t)),i}return t=h(t)||0,m(n)&&(c=!!n.leading,a=(v="maxWait"in n)?f(h(n.maxWait)||0,t):a,b="trailing"in n?!!n.trailing:b),x.cancel=function(){void 0!==l&&clearTimeout(l),u=0,r=s=o=l=void 0},x.flush=function(){return void 0===l?i:O(p())},x}}).call(this,n(7))},function(e,t,n){(function(t){var n="Expected a function",r=/^\s+|\s+$/g,o=/^[-+]0x[0-9a-f]+$/i,a=/^0b[01]+$/i,i=/^0o[0-7]+$/i,l=parseInt,s="object"==typeof t&&t&&t.Object===Object&&t,u="object"==typeof self&&self&&self.Object===Object&&self,c=s||u||Function("return this")(),f=Object.prototype.toString,d=Math.max,p=Math.min,m=function(){return c.Date.now()};function h(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function v(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Symbol]"==f.call(e)}(e))return NaN;if(h(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=h(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(r,"");var n=a.test(e);return n||i.test(e)?l(e.slice(2),n?2:8):o.test(e)?NaN:+e}e.exports=function(e,t,r){var o=!0,a=!0;if("function"!=typeof e)throw new TypeError(n);return h(r)&&(o="leading"in r?!!r.leading:o,a="trailing"in r?!!r.trailing:a),function(e,t,r){var o,a,i,l,s,u,c=0,f=!1,b=!1,g=!0;if("function"!=typeof e)throw new TypeError(n);function y(t){var n=o,r=a;return o=a=void 0,c=t,l=e.apply(r,n)}function w(e){var n=e-u;return void 0===u||n>=t||n<0||b&&e-c>=i}function O(){var e=m();if(w(e))return x(e);s=setTimeout(O,function(e){var n=t-(e-u);return b?p(n,i-(e-c)):n}(e))}function x(e){return s=void 0,g&&o?y(e):(o=a=void 0,l)}function E(){var e=m(),n=w(e);if(o=arguments,a=this,u=e,n){if(void 0===s)return function(e){return c=e,s=setTimeout(O,t),f?y(e):l}(u);if(b)return s=setTimeout(O,t),y(u)}return void 0===s&&(s=setTimeout(O,t)),l}return t=v(t)||0,h(r)&&(f=!!r.leading,i=(b="maxWait"in r)?d(v(r.maxWait)||0,t):i,g="trailing"in r?!!r.trailing:g),E.cancel=function(){void 0!==s&&clearTimeout(s),c=0,o=u=a=s=void 0},E.flush=function(){return void 0===s?l:x(m())},E}(e,t,{leading:o,maxWait:t,trailing:a})}}).call(this,n(7))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(e,t){return"undefined"==typeof getComputedStyle?e.style[t]:getComputedStyle(e,null).getPropertyValue(t)},o=function(e){return r(e,"overflow")+r(e,"overflow-y")+r(e,"overflow-x")};t.default=function(e){if(!(e instanceof HTMLElement))return window;for(var t=e;t&&t!==document.body&&t!==document.documentElement&&t.parentNode;){if(/(scroll|auto)/.test(o(t)))return t;t=t.parentNode}return window}}])},function(e,t,n){"use strict";var r=n(2),o=n(0),a=n.n(o);var i=function(){function e(e){var t=this;this._insertTag=function(e){var n;n=0===t.tags.length?t.prepend?t.container.firstChild:t.before:t.tags[t.tags.length-1].nextSibling,t.container.insertBefore(e,n),t.tags.push(e)},this.isSpeedy=void 0===e.speedy||e.speedy,this.tags=[],this.ctr=0,this.nonce=e.nonce,this.key=e.key,this.container=e.container,this.prepend=e.prepend,this.before=null}var t=e.prototype;return t.hydrate=function(e){e.forEach(this._insertTag)},t.insert=function(e){this.ctr%(this.isSpeedy?65e3:1)===0&&this._insertTag(function(e){var t=document.createElement("style");return t.setAttribute("data-emotion",e.key),void 0!==e.nonce&&t.setAttribute("nonce",e.nonce),t.appendChild(document.createTextNode("")),t.setAttribute("data-s",""),t}(this));var t=this.tags[this.tags.length-1];if(this.isSpeedy){var n=function(e){if(e.sheet)return e.sheet;for(var t=0;t0?g(N,--j):0,S--,10===P&&(S=1,k--),P}function I(){return P=j2||F(P)>3?"":" "}function B(e,t){for(;--t&&I()&&!(P<48||P>102||P>57&&P<65||P>70&&P<97););return D(e,L()+(t<6&&32==R()&&32==I()))}function W(e){for(;I();)switch(P){case e:return j;case 34:case 39:return W(34===e||39===e?e:P);case 40:41===e&&W(e);break;case 92:I()}return j}function H(e,t){for(;I()&&e+P!==57&&(e+P!==84||47!==R()););return"/*"+D(t,j-1)+"*"+m(47===e?e:I())}function $(e){for(;!F(R());)I();return D(e,j)}function K(e){return V(q("",null,null,null,[""],e=A(e),0,[0],e))}function q(e,t,n,r,o,a,i,l,s){for(var u=0,c=0,f=i,d=0,p=0,h=0,b=1,g=1,y=1,O=0,E="",k=o,S=a,C=r,j=E;g;)switch(h=O,O=I()){case 34:case 39:case 91:case 40:j+=z(O);break;case 9:case 10:case 13:case 32:j+=U(h);break;case 92:j+=B(L()-1,7);continue;case 47:switch(R()){case 42:case 47:x(Y(H(I(),L()),t,n),s);break;default:j+="/"}break;case 123*b:l[u++]=w(j)*y;case 125*b:case 59:case 0:switch(O){case 0:case 125:g=0;case 59+c:p>0&&w(j)-f&&x(p>32?G(j+";",r,n,f-1):G(v(j," ","")+";",r,n,f-2),s);break;case 59:j+=";";default:if(x(C=Q(j,t,n,u,c,o,l,E,k=[],S=[],f),a),123===O)if(0===c)q(j,t,C,C,k,a,f,l,S);else switch(d){case 100:case 109:case 115:q(e,C,C,r&&x(Q(e,C,C,0,0,o,l,E,o,k=[],f),S),o,S,f,l,r?k:S);break;default:q(j,C,C,C,[""],S,f,l,S)}}u=c=p=0,b=y=1,E=j="",f=i;break;case 58:f=1+w(j),p=h;default:if(b<1)if(123==O)--b;else if(125==O&&0==b++&&125==M())continue;switch(j+=m(O),O*b){case 38:y=c>0?1:(j+="\f",-1);break;case 44:l[u++]=(w(j)-1)*y,y=1;break;case 64:45===R()&&(j+=z(I())),d=R(),c=w(E=j+=$(L())),O++;break;case 45:45===h&&2==w(j)&&(b=0)}}return a}function Q(e,t,n,r,o,a,i,l,s,u,c){for(var d=o-1,m=0===o?a:[""],b=O(m),g=0,w=0,x=0;g0?m[E]+" "+k:v(k,/&\f/g,m[E])))&&(s[x++]=S);return T(e,t,n,0===o?f:l,s,u,c)}function Y(e,t,n){return T(e,t,n,c,m(P),y(e,2,-2),0)}function G(e,t,n,r){return T(e,t,n,d,y(e,0,r),y(e,r+1,-1),r)}function X(e,t){switch(function(e,t){return(((t<<2^g(e,0))<<2^g(e,1))<<2^g(e,2))<<2^g(e,3)}(e,t)){case 5103:return u+"print-"+e+e;case 5737:case 4201:case 3177:case 3433:case 1641:case 4457:case 2921:case 5572:case 6356:case 5844:case 3191:case 6645:case 3005:case 6391:case 5879:case 5623:case 6135:case 4599:case 4855:case 4215:case 6389:case 5109:case 5365:case 5621:case 3829:return u+e+e;case 5349:case 4246:case 4810:case 6968:case 2756:return u+e+s+e+l+e+e;case 6828:case 4268:return u+e+l+e+e;case 6165:return u+e+l+"flex-"+e+e;case 5187:return u+e+v(e,/(\w+).+(:[^]+)/,u+"box-$1$2"+l+"flex-$1$2")+e;case 5443:return u+e+l+"flex-item-"+v(e,/flex-|-self/,"")+e;case 4675:return u+e+l+"flex-line-pack"+v(e,/align-content|flex-|-self/,"")+e;case 5548:return u+e+l+v(e,"shrink","negative")+e;case 5292:return u+e+l+v(e,"basis","preferred-size")+e;case 6060:return u+"box-"+v(e,"-grow","")+u+e+l+v(e,"grow","positive")+e;case 4554:return u+v(e,/([^-])(transform)/g,"$1"+u+"$2")+e;case 6187:return v(v(v(e,/(zoom-|grab)/,u+"$1"),/(image-set)/,u+"$1"),e,"")+e;case 5495:case 3959:return v(e,/(image-set\([^]*)/,u+"$1$`$1");case 4968:return v(v(e,/(.+:)(flex-)?(.*)/,u+"box-pack:$3"+l+"flex-pack:$3"),/s.+-b[^;]+/,"justify")+u+e+e;case 4095:case 3583:case 4068:case 2532:return v(e,/(.+)-inline(.+)/,u+"$1$2")+e;case 8116:case 7059:case 5753:case 5535:case 5445:case 5701:case 4933:case 4677:case 5533:case 5789:case 5021:case 4765:if(w(e)-1-t>6)switch(g(e,t+1)){case 109:if(45!==g(e,t+4))break;case 102:return v(e,/(.+:)(.+)-([^]+)/,"$1"+u+"$2-$3$1"+s+(108==g(e,t+3)?"$3":"$2-$3"))+e;case 115:return~b(e,"stretch")?X(v(e,"stretch","fill-available"),t)+e:e}break;case 4949:if(115!==g(e,t+1))break;case 6444:switch(g(e,w(e)-3-(~b(e,"!important")&&10))){case 107:return v(e,":",":"+u)+e;case 101:return v(e,/(.+:)([^;!]+)(;|!.+)?/,"$1"+u+(45===g(e,14)?"inline-":"")+"box$3$1"+u+"$2$3$1"+l+"$2box$3")+e}break;case 5936:switch(g(e,t+11)){case 114:return u+e+l+v(e,/[svh]\w+-[tblr]{2}/,"tb")+e;case 108:return u+e+l+v(e,/[svh]\w+-[tblr]{2}/,"tb-rl")+e;case 45:return u+e+l+v(e,/[svh]\w+-[tblr]{2}/,"lr")+e}return u+e+l+e+e}return e}function Z(e,t){for(var n="",r=O(e),o=0;o=4;++r,o-=4)t=1540483477*(65535&(t=255&e.charCodeAt(r)|(255&e.charCodeAt(++r))<<8|(255&e.charCodeAt(++r))<<16|(255&e.charCodeAt(++r))<<24))+(59797*(t>>>16)<<16),n=1540483477*(65535&(t^=t>>>24))+(59797*(t>>>16)<<16)^1540483477*(65535&n)+(59797*(n>>>16)<<16);switch(o){case 3:n^=(255&e.charCodeAt(r+2))<<16;case 2:n^=(255&e.charCodeAt(r+1))<<8;case 1:n=1540483477*(65535&(n^=255&e.charCodeAt(r)))+(59797*(n>>>16)<<16)}return(((n=1540483477*(65535&(n^=n>>>13))+(59797*(n>>>16)<<16))^n>>>15)>>>0).toString(36)},fe={animationIterationCount:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1},de=/[A-Z]|^ms/g,pe=/_EMO_([^_]+?)_([^]*?)_EMO_/g,me=function(e){return 45===e.charCodeAt(1)},he=function(e){return null!=e&&"boolean"!==typeof e},ve=te((function(e){return me(e)?e:e.replace(de,"-$&").toLowerCase()})),be=function(e,t){switch(e){case"animation":case"animationName":if("string"===typeof t)return t.replace(pe,(function(e,t,n){return ye={name:t,styles:n,next:ye},t}))}return 1===fe[e]||me(e)||"number"!==typeof t||0===t?t:t+"px"};function ge(e,t,n){if(null==n)return"";if(void 0!==n.__emotion_styles)return n;switch(typeof n){case"boolean":return"";case"object":if(1===n.anim)return ye={name:n.name,styles:n.styles,next:ye},n.name;if(void 0!==n.styles){var r=n.next;if(void 0!==r)for(;void 0!==r;)ye={name:r.name,styles:r.styles,next:ye},r=r.next;return n.styles+";"}return function(e,t,n){var r="";if(Array.isArray(n))for(var o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function Fe(e){return(Fe="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var Ae=n(64),Ve=n.n(Ae);function ze(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function Ue(e,t){for(var n=0;n-1}function at(e){return ot(e)?window.pageYOffset:e.scrollTop}function it(e,t){ot(e)?window.scrollTo(0,t):e.scrollTop=t}function lt(e,t,n,r){return n*((e=e/r-1)*e*e+1)+t}function st(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:200,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:Je,o=at(e),a=t-o,i=10,l=0;function s(){var t=lt(l+=i,o,a,n);it(e,t),l=p)return{placement:"bottom",maxHeight:t};if(E>=p&&!i)return a&&st(s,k,C),{placement:"bottom",maxHeight:t};if(!i&&E>=r||i&&O>=r)return a&&st(s,k,C),{placement:"bottom",maxHeight:i?O-g:E-g};if("auto"===o||i){var j=t,P=i?w:x;return P>=r&&(j=Math.min(P-g-l.controlHeight,t)),{placement:"top",maxHeight:j}}if("bottom"===o)return a&&it(s,k),{placement:"bottom",maxHeight:t};break;case"top":if(w>=p)return{placement:"top",maxHeight:t};if(x>=p&&!i)return a&&st(s,S,C),{placement:"top",maxHeight:t};if(!i&&x>=r||i&&w>=r){var N=t;return(!i&&x>=r||i&&w>=r)&&(N=i?w-y:x-y),a&&st(s,S,C),{placement:"top",maxHeight:N}}return{placement:"bottom",maxHeight:t};default:throw new Error('Invalid placement provided "'.concat(o,'".'))}return u}var ht=function(e){return"auto"===e?"bottom":e},vt=Object(o.createContext)({getPortalPlacement:null}),bt=function(e){He(n,e);var t=Ze(n);function n(){var e;ze(this,n);for(var r=arguments.length,o=new Array(r),a=0;ae.length)&&(t=e.length);for(var n=0,r=new Array(t);n0,h=f-d-u,v=!1;h>t&&l.current&&(r&&r(e),l.current=!1),m&&s.current&&(i&&i(e),s.current=!1),m&&t>h?(n&&!l.current&&n(e),p.scrollTop=f,v=!0,l.current=!0):!m&&-t>u&&(a&&!s.current&&a(e),p.scrollTop=0,v=!0,s.current=!0),v&&function(e){e.preventDefault(),e.stopPropagation()}(e)}}),[]),d=Object(o.useCallback)((function(e){f(e,e.deltaY)}),[f]),p=Object(o.useCallback)((function(e){u.current=e.changedTouches[0].clientY}),[]),m=Object(o.useCallback)((function(e){var t=u.current-e.changedTouches[0].clientY;f(e,t)}),[f]),h=Object(o.useCallback)((function(e){if(e){var t=!!pt&&{passive:!1};"function"===typeof e.addEventListener&&e.addEventListener("wheel",d,t),"function"===typeof e.addEventListener&&e.addEventListener("touchstart",p,t),"function"===typeof e.addEventListener&&e.addEventListener("touchmove",m,t)}}),[m,p,d]),v=Object(o.useCallback)((function(e){e&&("function"===typeof e.removeEventListener&&e.removeEventListener("wheel",d,!1),"function"===typeof e.removeEventListener&&e.removeEventListener("touchstart",p,!1),"function"===typeof e.removeEventListener&&e.removeEventListener("touchmove",m,!1))}),[m,p,d]);return Object(o.useEffect)((function(){if(t){var e=c.current;return h(e),function(){v(e)}}}),[t,h,v]),function(e){c.current=e}}({isEnabled:void 0===r||r,onBottomArrive:e.onBottomArrive,onBottomLeave:e.onBottomLeave,onTopArrive:e.onTopArrive,onTopLeave:e.onTopLeave}),l=function(e){var t=e.isEnabled,n=e.accountForScrollbars,r=void 0===n||n,a=Object(o.useRef)({}),i=Object(o.useRef)(null),l=Object(o.useCallback)((function(e){if(vn){var t=document.body,n=t&&t.style;if(r&&cn.forEach((function(e){var t=n&&n[e];a.current[e]=t})),r&&bn<1){var o=parseInt(a.current.paddingRight,10)||0,i=document.body?document.body.clientWidth:0,l=window.innerWidth-i+o||0;Object.keys(fn).forEach((function(e){var t=fn[e];n&&(n[e]=t)})),n&&(n.paddingRight="".concat(l,"px"))}t&&hn()&&(t.addEventListener("touchmove",dn,gn),e&&(e.addEventListener("touchstart",mn,gn),e.addEventListener("touchmove",pn,gn))),bn+=1}}),[]),s=Object(o.useCallback)((function(e){if(vn){var t=document.body,n=t&&t.style;bn=Math.max(bn-1,0),r&&bn<1&&cn.forEach((function(e){var t=a.current[e];n&&(n[e]=t)})),t&&hn()&&(t.removeEventListener("touchmove",dn,gn),e&&(e.removeEventListener("touchstart",mn,gn),e.removeEventListener("touchmove",pn,gn)))}}),[]);return Object(o.useEffect)((function(){if(t){var e=i.current;return l(e),function(){s(e)}}}),[t,l,s]),function(e){i.current=e}}({isEnabled:n});return Te(a.a.Fragment,null,n&&Te("div",{onClick:yn,css:wn}),t((function(e){i(e),l(e)})))}var xn={clearIndicator:It,container:function(e){var t=e.isDisabled;return{label:"container",direction:e.isRtl?"rtl":null,pointerEvents:t?"none":null,position:"relative"}},control:function(e){var t=e.isDisabled,n=e.isFocused,r=e.theme,o=r.colors,a=r.borderRadius,i=r.spacing;return{label:"control",alignItems:"center",backgroundColor:t?o.neutral5:o.neutral0,borderColor:t?o.neutral10:n?o.primary:o.neutral20,borderRadius:a,borderStyle:"solid",borderWidth:1,boxShadow:n?"0 0 0 1px ".concat(o.primary):null,cursor:"default",display:"flex",flexWrap:"wrap",justifyContent:"space-between",minHeight:i.controlHeight,outline:"0 !important",position:"relative",transition:"all 100ms","&:hover":{borderColor:n?o.primary:o.neutral30}}},dropdownIndicator:Mt,group:function(e){var t=e.theme.spacing;return{paddingBottom:2*t.baseUnit,paddingTop:2*t.baseUnit}},groupHeading:function(e){var t=e.theme.spacing;return{label:"group",color:"#999",cursor:"default",display:"block",fontSize:"75%",fontWeight:"500",marginBottom:"0.25em",paddingLeft:3*t.baseUnit,paddingRight:3*t.baseUnit,textTransform:"uppercase"}},indicatorsContainer:function(){return{alignItems:"center",alignSelf:"stretch",display:"flex",flexShrink:0}},indicatorSeparator:function(e){var t=e.isDisabled,n=e.theme,r=n.spacing.baseUnit,o=n.colors;return{label:"indicatorSeparator",alignSelf:"stretch",backgroundColor:t?o.neutral10:o.neutral20,marginBottom:2*r,marginTop:2*r,width:1}},input:function(e){var t=e.isDisabled,n=e.theme,r=n.spacing,o=n.colors;return{margin:r.baseUnit/2,paddingBottom:r.baseUnit/2,paddingTop:r.baseUnit/2,visibility:t?"hidden":"visible",color:o.neutral80}},loadingIndicator:function(e){var t=e.isFocused,n=e.size,r=e.theme,o=r.colors,a=r.spacing.baseUnit;return{label:"loadingIndicator",color:t?o.neutral60:o.neutral20,display:"flex",padding:2*a,transition:"color 150ms",alignSelf:"center",fontSize:n,lineHeight:1,marginRight:n,textAlign:"center",verticalAlign:"middle"}},loadingMessage:wt,menu:function(e){var t,n=e.placement,r=e.theme,o=r.borderRadius,a=r.spacing,i=r.colors;return $e(t={label:"menu"},function(e){return e?{bottom:"top",top:"bottom"}[e]:"bottom"}(n),"100%"),$e(t,"backgroundColor",i.neutral0),$e(t,"borderRadius",o),$e(t,"boxShadow","0 0 0 1px hsla(0, 0%, 0%, 0.1), 0 4px 11px hsla(0, 0%, 0%, 0.1)"),$e(t,"marginBottom",a.menuGutter),$e(t,"marginTop",a.menuGutter),$e(t,"position","absolute"),$e(t,"width","100%"),$e(t,"zIndex",1),t},menuList:function(e){var t=e.maxHeight,n=e.theme.spacing.baseUnit;return{maxHeight:t,overflowY:"auto",paddingBottom:n,paddingTop:n,position:"relative",WebkitOverflowScrolling:"touch"}},menuPortal:function(e){var t=e.rect,n=e.offset,r=e.position;return{left:t.left,position:r,top:n,width:t.width,zIndex:1}},multiValue:function(e){var t=e.theme,n=t.spacing,r=t.borderRadius;return{label:"multiValue",backgroundColor:t.colors.neutral10,borderRadius:r/2,display:"flex",margin:n.baseUnit/2,minWidth:0}},multiValueLabel:function(e){var t=e.theme,n=t.borderRadius,r=t.colors,o=e.cropWithEllipsis;return{borderRadius:n/2,color:r.neutral80,fontSize:"85%",overflow:"hidden",padding:3,paddingLeft:6,textOverflow:o?"ellipsis":null,whiteSpace:"nowrap"}},multiValueRemove:function(e){var t=e.theme,n=t.spacing,r=t.borderRadius,o=t.colors;return{alignItems:"center",borderRadius:r/2,backgroundColor:e.isFocused&&o.dangerLight,display:"flex",paddingLeft:n.baseUnit,paddingRight:n.baseUnit,":hover":{backgroundColor:o.dangerLight,color:o.danger}}},noOptionsMessage:yt,option:function(e){var t=e.isDisabled,n=e.isFocused,r=e.isSelected,o=e.theme,a=o.spacing,i=o.colors;return{label:"option",backgroundColor:r?i.primary:n?i.primary25:"transparent",color:t?i.neutral20:r?i.neutral0:"inherit",cursor:"default",display:"block",fontSize:"inherit",padding:"".concat(2*a.baseUnit,"px ").concat(3*a.baseUnit,"px"),width:"100%",userSelect:"none",WebkitTapHighlightColor:"rgba(0, 0, 0, 0)",":active":{backgroundColor:!t&&(r?i.primary:i.primary50)}}},placeholder:function(e){var t=e.theme,n=t.spacing;return{label:"placeholder",color:t.colors.neutral50,marginLeft:n.baseUnit/2,marginRight:n.baseUnit/2,position:"absolute",top:"50%",transform:"translateY(-50%)"}},singleValue:function(e){var t=e.isDisabled,n=e.theme,r=n.spacing,o=n.colors;return{label:"singleValue",color:t?o.neutral40:o.neutral80,marginLeft:r.baseUnit/2,marginRight:r.baseUnit/2,maxWidth:"calc(100% - ".concat(2*r.baseUnit,"px)"),overflow:"hidden",position:"absolute",textOverflow:"ellipsis",whiteSpace:"nowrap",top:"50%",transform:"translateY(-50%)"}},valueContainer:function(e){var t=e.theme.spacing;return{alignItems:"center",display:"flex",flex:1,flexWrap:"wrap",padding:"".concat(t.baseUnit/2,"px ").concat(2*t.baseUnit,"px"),WebkitOverflowScrolling:"touch",position:"relative",overflow:"hidden"}}};var En,kn={borderRadius:4,colors:{primary:"#2684FF",primary75:"#4C9AFF",primary50:"#B2D4FF",primary25:"#DEEBFF",danger:"#DE350B",dangerLight:"#FFBDAD",neutral0:"hsl(0, 0%, 100%)",neutral5:"hsl(0, 0%, 95%)",neutral10:"hsl(0, 0%, 90%)",neutral20:"hsl(0, 0%, 80%)",neutral30:"hsl(0, 0%, 70%)",neutral40:"hsl(0, 0%, 60%)",neutral50:"hsl(0, 0%, 50%)",neutral60:"hsl(0, 0%, 40%)",neutral70:"hsl(0, 0%, 30%)",neutral80:"hsl(0, 0%, 20%)",neutral90:"hsl(0, 0%, 10%)"},spacing:{baseUnit:4,controlHeight:38,menuGutter:8}},Sn={"aria-live":"polite",backspaceRemovesValue:!0,blurInputOnSelect:ut(),captureMenuScroll:!ut(),closeMenuOnSelect:!0,closeMenuOnScroll:!1,components:{},controlShouldRenderValue:!0,escapeClearsValue:!1,filterOption:function(e,t){var n=Ye({ignoreCase:!0,ignoreAccents:!0,stringify:sn,trim:!0,matchFrom:"any"},En),r=n.ignoreCase,o=n.ignoreAccents,a=n.stringify,i=n.trim,l=n.matchFrom,s=i?ln(t):t,u=i?ln(a(e)):a(e);return r&&(s=s.toLowerCase(),u=u.toLowerCase()),o&&(s=an(s),u=on(u)),"start"===l?u.substr(0,s.length)===s:u.indexOf(s)>-1},formatGroupLabel:function(e){return e.label},getOptionLabel:function(e){return e.label},getOptionValue:function(e){return e.value},isDisabled:!1,isLoading:!1,isMulti:!1,isRtl:!1,isSearchable:!0,isOptionDisabled:function(e){return!!e.isDisabled},loadingMessage:function(){return"Loading..."},maxMenuHeight:300,minMenuHeight:140,menuIsOpen:!1,menuPlacement:"bottom",menuPosition:"absolute",menuShouldBlockScroll:!1,menuShouldScrollIntoView:!function(){try{return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}catch(l){return!1}}(),noOptionsMessage:function(){return"No options"},openMenuOnFocus:!1,openMenuOnClick:!0,options:[],pageSize:5,placeholder:"Select...",screenReaderStatus:function(e){var t=e.count;return"".concat(t," result").concat(1!==t?"s":""," available")},styles:{},tabIndex:"0",tabSelectsValue:!0};function Cn(e,t,n,r){return{type:"option",data:t,isDisabled:Mn(e,t,n),isSelected:In(e,t,n),label:Tn(e,t),value:_n(e,t),index:r}}function jn(e,t){return e.options.map((function(n,r){if(n.options){var o=n.options.map((function(n,r){return Cn(e,n,t,r)})).filter((function(t){return Nn(e,t)}));return o.length>0?{type:"group",data:n,options:o,index:r}:void 0}var a=Cn(e,n,t,r);return Nn(e,a)?a:void 0})).filter((function(e){return!!e}))}function Pn(e){return e.reduce((function(e,t){return"group"===t.type?e.push.apply(e,Ht(t.options.map((function(e){return e.data})))):e.push(t.data),e}),[])}function Nn(e,t){var n=e.inputValue,r=void 0===n?"":n,o=t.data,a=t.isSelected,i=t.label,l=t.value;return(!Ln(e)||!a)&&Rn(e,{label:i,value:l,data:o},r)}var Tn=function(e,t){return e.getOptionLabel(t)},_n=function(e,t){return e.getOptionValue(t)};function Mn(e,t,n){return"function"===typeof e.isOptionDisabled&&e.isOptionDisabled(t,n)}function In(e,t,n){if(n.indexOf(t)>-1)return!0;if("function"===typeof e.isOptionSelected)return e.isOptionSelected(t,n);var r=_n(e,t);return n.some((function(t){return _n(e,t)===r}))}function Rn(e,t,n){return!e.filterOption||e.filterOption(t,n)}var Ln=function(e){var t=e.hideSelectedOptions,n=e.isMulti;return void 0===t?n:t},Dn=1,Fn=function(e){He(n,e);var t=Ze(n);function n(e){var r;return ze(this,n),(r=t.call(this,e)).state={ariaSelection:null,focusedOption:null,focusedValue:null,inputIsHidden:!1,isFocused:!1,selectValue:[],clearFocusValueOnUpdate:!1,inputIsHiddenAfterUpdate:void 0,prevProps:void 0},r.blockOptionHover=!1,r.isComposing=!1,r.commonProps=void 0,r.initialTouchX=0,r.initialTouchY=0,r.instancePrefix="",r.openAfterFocus=!1,r.scrollToFocusedOptionOnUpdate=!1,r.userIsDragging=void 0,r.controlRef=null,r.getControlRef=function(e){r.controlRef=e},r.focusedOptionRef=null,r.getFocusedOptionRef=function(e){r.focusedOptionRef=e},r.menuListRef=null,r.getMenuListRef=function(e){r.menuListRef=e},r.inputRef=null,r.getInputRef=function(e){r.inputRef=e},r.focus=r.focusInput,r.blur=r.blurInput,r.onChange=function(e,t){var n=r.props,o=n.onChange,a=n.name;t.name=a,r.ariaOnChange(e,t),o(e,t)},r.setValue=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"set-value",n=arguments.length>2?arguments[2]:void 0,o=r.props,a=o.closeMenuOnSelect,i=o.isMulti;r.onInputChange("",{action:"set-value"}),a&&(r.setState({inputIsHiddenAfterUpdate:!i}),r.onMenuClose()),r.setState({clearFocusValueOnUpdate:!0}),r.onChange(e,{action:t,option:n})},r.selectOption=function(e){var t=r.props,n=t.blurInputOnSelect,o=t.isMulti,a=t.name,i=r.state.selectValue,l=o&&r.isOptionSelected(e,i),s=r.isOptionDisabled(e,i);if(l){var u=r.getOptionValue(e);r.setValue(i.filter((function(e){return r.getOptionValue(e)!==u})),"deselect-option",e)}else{if(s)return void r.ariaOnChange(e,{action:"select-option",name:a});o?r.setValue([].concat(Ht(i),[e]),"select-option",e):r.setValue(e,"select-option")}n&&r.blurInput()},r.removeValue=function(e){var t=r.props.isMulti,n=r.state.selectValue,o=r.getOptionValue(e),a=n.filter((function(e){return r.getOptionValue(e)!==o})),i=t?a:a[0]||null;r.onChange(i,{action:"remove-value",removedValue:e}),r.focusInput()},r.clearValue=function(){var e=r.state.selectValue;r.onChange(r.props.isMulti?[]:null,{action:"clear",removedValues:e})},r.popValue=function(){var e=r.props.isMulti,t=r.state.selectValue,n=t[t.length-1],o=t.slice(0,t.length-1),a=e?o:o[0]||null;r.onChange(a,{action:"pop-value",removedValue:n})},r.getValue=function(){return r.state.selectValue},r.cx=function(){for(var e=arguments.length,t=new Array(e),n=0;n5||a>5}},r.onTouchEnd=function(e){r.userIsDragging||(r.controlRef&&!r.controlRef.contains(e.target)&&r.menuListRef&&!r.menuListRef.contains(e.target)&&r.blurInput(),r.initialTouchX=0,r.initialTouchY=0)},r.onControlTouchEnd=function(e){r.userIsDragging||r.onControlMouseDown(e)},r.onClearIndicatorTouchEnd=function(e){r.userIsDragging||r.onClearIndicatorMouseDown(e)},r.onDropdownIndicatorTouchEnd=function(e){r.userIsDragging||r.onDropdownIndicatorMouseDown(e)},r.handleInputChange=function(e){var t=e.currentTarget.value;r.setState({inputIsHiddenAfterUpdate:!1}),r.onInputChange(t,{action:"input-change"}),r.props.menuIsOpen||r.onMenuOpen()},r.onInputFocus=function(e){r.props.onFocus&&r.props.onFocus(e),r.setState({inputIsHiddenAfterUpdate:!1,isFocused:!0}),(r.openAfterFocus||r.props.openMenuOnFocus)&&r.openMenu("first"),r.openAfterFocus=!1},r.onInputBlur=function(e){r.menuListRef&&r.menuListRef.contains(document.activeElement)?r.inputRef.focus():(r.props.onBlur&&r.props.onBlur(e),r.onInputChange("",{action:"input-blur"}),r.onMenuClose(),r.setState({focusedValue:null,isFocused:!1}))},r.onOptionHover=function(e){r.blockOptionHover||r.state.focusedOption===e||r.setState({focusedOption:e})},r.shouldHideSelectedOptions=function(){return Ln(r.props)},r.onKeyDown=function(e){var t=r.props,n=t.isMulti,o=t.backspaceRemovesValue,a=t.escapeClearsValue,i=t.inputValue,l=t.isClearable,s=t.isDisabled,u=t.menuIsOpen,c=t.onKeyDown,f=t.tabSelectsValue,d=t.openMenuOnFocus,p=r.state,m=p.focusedOption,h=p.focusedValue,v=p.selectValue;if(!s&&("function"!==typeof c||(c(e),!e.defaultPrevented))){switch(r.blockOptionHover=!0,e.key){case"ArrowLeft":if(!n||i)return;r.focusValue("previous");break;case"ArrowRight":if(!n||i)return;r.focusValue("next");break;case"Delete":case"Backspace":if(i)return;if(h)r.removeValue(h);else{if(!o)return;n?r.popValue():l&&r.clearValue()}break;case"Tab":if(r.isComposing)return;if(e.shiftKey||!u||!f||!m||d&&r.isOptionSelected(m,v))return;r.selectOption(m);break;case"Enter":if(229===e.keyCode)break;if(u){if(!m)return;if(r.isComposing)return;r.selectOption(m);break}return;case"Escape":u?(r.setState({inputIsHiddenAfterUpdate:!1}),r.onInputChange("",{action:"menu-close"}),r.onMenuClose()):l&&a&&r.clearValue();break;case" ":if(i)return;if(!u){r.openMenu("first");break}if(!m)return;r.selectOption(m);break;case"ArrowUp":u?r.focusOption("up"):r.openMenu("last");break;case"ArrowDown":u?r.focusOption("down"):r.openMenu("first");break;case"PageUp":if(!u)return;r.focusOption("pageup");break;case"PageDown":if(!u)return;r.focusOption("pagedown");break;case"Home":if(!u)return;r.focusOption("first");break;case"End":if(!u)return;r.focusOption("last");break;default:return}e.preventDefault()}},r.instancePrefix="react-select-"+(r.props.instanceId||++Dn),r.state.selectValue=nt(e.value),r}return Be(n,[{key:"componentDidMount",value:function(){this.startListeningComposition(),this.startListeningToTouch(),this.props.closeMenuOnScroll&&document&&document.addEventListener&&document.addEventListener("scroll",this.onScroll,!0),this.props.autoFocus&&this.focusInput()}},{key:"componentDidUpdate",value:function(e){var t=this.props,n=t.isDisabled,r=t.menuIsOpen,o=this.state.isFocused;(o&&!n&&e.isDisabled||o&&r&&!e.menuIsOpen)&&this.focusInput(),o&&n&&!e.isDisabled&&this.setState({isFocused:!1},this.onMenuClose),this.menuListRef&&this.focusedOptionRef&&this.scrollToFocusedOptionOnUpdate&&(!function(e,t){var n=e.getBoundingClientRect(),r=t.getBoundingClientRect(),o=t.offsetHeight/3;r.bottom+o>n.bottom?it(e,Math.min(t.offsetTop+t.clientHeight-e.offsetHeight+o,e.scrollHeight)):r.top-o-1&&(i=l)}this.scrollToFocusedOptionOnUpdate=!(o&&this.menuListRef),this.setState({inputIsHiddenAfterUpdate:!1,focusedValue:null,focusedOption:a[i]},(function(){return t.onMenuOpen()}))}},{key:"focusValue",value:function(e){var t=this.state,n=t.selectValue,r=t.focusedValue;if(this.props.isMulti){this.setState({focusedOption:null});var o=n.indexOf(r);r||(o=-1);var a=n.length-1,i=-1;if(n.length){switch(e){case"previous":i=0===o?0:-1===o?a:o-1;break;case"next":o>-1&&o0&&void 0!==arguments[0]?arguments[0]:"first",t=this.props.pageSize,n=this.state.focusedOption,r=this.getFocusableOptions();if(r.length){var o=0,a=r.indexOf(n);n||(a=-1),"up"===e?o=a>0?a-1:r.length-1:"down"===e?o=(a+1)%r.length:"pageup"===e?(o=a-t)<0&&(o=0):"pagedown"===e?(o=a+t)>r.length-1&&(o=r.length-1):"last"===e&&(o=r.length-1),this.scrollToFocusedOptionOnUpdate=!0,this.setState({focusedOption:r[o],focusedValue:null})}}},{key:"getTheme",value:function(){return this.props.theme?"function"===typeof this.props.theme?this.props.theme(kn):Ye(Ye({},kn),this.props.theme):kn}},{key:"getCommonProps",value:function(){var e=this.clearValue,t=this.cx,n=this.getStyles,r=this.getValue,o=this.selectOption,a=this.setValue,i=this.props,l=i.isMulti,s=i.isRtl,u=i.options;return{clearValue:e,cx:t,getStyles:n,getValue:r,hasValue:this.hasValue(),isMulti:l,isRtl:s,options:u,selectOption:o,selectProps:i,setValue:a,theme:this.getTheme()}}},{key:"hasValue",value:function(){return this.state.selectValue.length>0}},{key:"hasOptions",value:function(){return!!this.getFocusableOptions().length}},{key:"isClearable",value:function(){var e=this.props,t=e.isClearable,n=e.isMulti;return void 0===t?n:t}},{key:"isOptionDisabled",value:function(e,t){return Mn(this.props,e,t)}},{key:"isOptionSelected",value:function(e,t){return In(this.props,e,t)}},{key:"filterOption",value:function(e,t){return Rn(this.props,e,t)}},{key:"formatOptionLabel",value:function(e,t){if("function"===typeof this.props.formatOptionLabel){var n=this.props.inputValue,r=this.state.selectValue;return this.props.formatOptionLabel(e,{context:t,inputValue:n,selectValue:r})}return this.getOptionLabel(e)}},{key:"formatGroupLabel",value:function(e){return this.props.formatGroupLabel(e)}},{key:"startListeningComposition",value:function(){document&&document.addEventListener&&(document.addEventListener("compositionstart",this.onCompositionStart,!1),document.addEventListener("compositionend",this.onCompositionEnd,!1))}},{key:"stopListeningComposition",value:function(){document&&document.removeEventListener&&(document.removeEventListener("compositionstart",this.onCompositionStart),document.removeEventListener("compositionend",this.onCompositionEnd))}},{key:"startListeningToTouch",value:function(){document&&document.addEventListener&&(document.addEventListener("touchstart",this.onTouchStart,!1),document.addEventListener("touchmove",this.onTouchMove,!1),document.addEventListener("touchend",this.onTouchEnd,!1))}},{key:"stopListeningToTouch",value:function(){document&&document.removeEventListener&&(document.removeEventListener("touchstart",this.onTouchStart),document.removeEventListener("touchmove",this.onTouchMove),document.removeEventListener("touchend",this.onTouchEnd))}},{key:"renderInput",value:function(){var e=this.props,t=e.isDisabled,n=e.isSearchable,o=e.inputId,i=e.inputValue,l=e.tabIndex,s=e.form,u=this.getComponents().Input,c=this.state.inputIsHidden,f=this.commonProps,d=o||this.getElementId("input"),p={"aria-autocomplete":"list","aria-label":this.props["aria-label"],"aria-labelledby":this.props["aria-labelledby"]};return n?a.a.createElement(u,Object(r.a)({},f,{autoCapitalize:"none",autoComplete:"off",autoCorrect:"off",id:d,innerRef:this.getInputRef,isDisabled:t,isHidden:c,onBlur:this.onInputBlur,onChange:this.handleInputChange,onFocus:this.onInputFocus,spellCheck:"false",tabIndex:l,form:s,type:"text",value:i},p)):a.a.createElement(un,Object(r.a)({id:d,innerRef:this.getInputRef,onBlur:this.onInputBlur,onChange:Je,onFocus:this.onInputFocus,readOnly:!0,disabled:t,tabIndex:l,form:s,value:""},p))}},{key:"renderPlaceholderOrValue",value:function(){var e=this,t=this.getComponents(),n=t.MultiValue,o=t.MultiValueContainer,i=t.MultiValueLabel,l=t.MultiValueRemove,s=t.SingleValue,u=t.Placeholder,c=this.commonProps,f=this.props,d=f.controlShouldRenderValue,p=f.isDisabled,m=f.isMulti,h=f.inputValue,v=f.placeholder,b=this.state,g=b.selectValue,y=b.focusedValue,w=b.isFocused;if(!this.hasValue()||!d)return h?null:a.a.createElement(u,Object(r.a)({},c,{key:"placeholder",isDisabled:p,isFocused:w}),v);if(m)return g.map((function(t,s){var u=t===y;return a.a.createElement(n,Object(r.a)({},c,{components:{Container:o,Label:i,Remove:l},isFocused:u,isDisabled:p,key:"".concat(e.getOptionValue(t)).concat(s),index:s,removeProps:{onClick:function(){return e.removeValue(t)},onTouchEnd:function(){return e.removeValue(t)},onMouseDown:function(e){e.preventDefault(),e.stopPropagation()}},data:t}),e.formatOptionLabel(t,"value"))}));if(h)return null;var O=g[0];return a.a.createElement(s,Object(r.a)({},c,{data:O,isDisabled:p}),this.formatOptionLabel(O,"value"))}},{key:"renderClearIndicator",value:function(){var e=this.getComponents().ClearIndicator,t=this.commonProps,n=this.props,o=n.isDisabled,i=n.isLoading,l=this.state.isFocused;if(!this.isClearable()||!e||o||!this.hasValue()||i)return null;var s={onMouseDown:this.onClearIndicatorMouseDown,onTouchEnd:this.onClearIndicatorTouchEnd,"aria-hidden":"true"};return a.a.createElement(e,Object(r.a)({},t,{innerProps:s,isFocused:l}))}},{key:"renderLoadingIndicator",value:function(){var e=this.getComponents().LoadingIndicator,t=this.commonProps,n=this.props,o=n.isDisabled,i=n.isLoading,l=this.state.isFocused;if(!e||!i)return null;return a.a.createElement(e,Object(r.a)({},t,{innerProps:{"aria-hidden":"true"},isDisabled:o,isFocused:l}))}},{key:"renderIndicatorSeparator",value:function(){var e=this.getComponents(),t=e.DropdownIndicator,n=e.IndicatorSeparator;if(!t||!n)return null;var o=this.commonProps,i=this.props.isDisabled,l=this.state.isFocused;return a.a.createElement(n,Object(r.a)({},o,{isDisabled:i,isFocused:l}))}},{key:"renderDropdownIndicator",value:function(){var e=this.getComponents().DropdownIndicator;if(!e)return null;var t=this.commonProps,n=this.props.isDisabled,o=this.state.isFocused,i={onMouseDown:this.onDropdownIndicatorMouseDown,onTouchEnd:this.onDropdownIndicatorTouchEnd,"aria-hidden":"true"};return a.a.createElement(e,Object(r.a)({},t,{innerProps:i,isDisabled:n,isFocused:o}))}},{key:"renderMenu",value:function(){var e=this,t=this.getComponents(),n=t.Group,o=t.GroupHeading,i=t.Menu,l=t.MenuList,s=t.MenuPortal,u=t.LoadingMessage,c=t.NoOptionsMessage,f=t.Option,d=this.commonProps,p=this.state.focusedOption,m=this.props,h=m.captureMenuScroll,v=m.inputValue,b=m.isLoading,g=m.loadingMessage,y=m.minMenuHeight,w=m.maxMenuHeight,O=m.menuIsOpen,x=m.menuPlacement,E=m.menuPosition,k=m.menuPortalTarget,S=m.menuShouldBlockScroll,C=m.menuShouldScrollIntoView,j=m.noOptionsMessage,P=m.onMenuScrollToTop,N=m.onMenuScrollToBottom;if(!O)return null;var T,_=function(t,n){var o=t.type,i=t.data,l=t.isDisabled,s=t.isSelected,u=t.label,c=t.value,m=p===i,h=l?void 0:function(){return e.onOptionHover(i)},v=l?void 0:function(){return e.selectOption(i)},b="".concat(e.getElementId("option"),"-").concat(n),g={id:b,onClick:v,onMouseMove:h,onMouseOver:h,tabIndex:-1};return a.a.createElement(f,Object(r.a)({},d,{innerProps:g,data:i,isDisabled:l,isSelected:s,key:b,label:u,type:o,value:c,isFocused:m,innerRef:m?e.getFocusedOptionRef:void 0}),e.formatOptionLabel(t.data,"menu"))};if(this.hasOptions())T=this.getCategorizedOptions().map((function(t){if("group"===t.type){var i=t.data,l=t.options,s=t.index,u="".concat(e.getElementId("group"),"-").concat(s),c="".concat(u,"-heading");return a.a.createElement(n,Object(r.a)({},d,{key:u,data:i,options:l,Heading:o,headingProps:{id:c,data:t.data},label:e.formatGroupLabel(t.data)}),t.options.map((function(e){return _(e,"".concat(s,"-").concat(e.index))})))}if("option"===t.type)return _(t,"".concat(t.index))}));else if(b){var M=g({inputValue:v});if(null===M)return null;T=a.a.createElement(u,d,M)}else{var I=j({inputValue:v});if(null===I)return null;T=a.a.createElement(c,d,I)}var R={minMenuHeight:y,maxMenuHeight:w,menuPlacement:x,menuPosition:E,menuShouldScrollIntoView:C},L=a.a.createElement(bt,Object(r.a)({},d,R),(function(t){var n=t.ref,o=t.placerProps,s=o.placement,u=o.maxHeight;return a.a.createElement(i,Object(r.a)({},d,R,{innerRef:n,innerProps:{onMouseDown:e.onMenuMouseDown,onMouseMove:e.onMenuMouseMove},isLoading:b,placement:s}),a.a.createElement(On,{captureEnabled:h,onTopArrive:P,onBottomArrive:N,lockEnabled:S},(function(t){return a.a.createElement(l,Object(r.a)({},d,{innerRef:function(n){e.getMenuListRef(n),t(n)},isLoading:b,maxHeight:u,focusedOption:p}),T)})))}));return k||"fixed"===E?a.a.createElement(s,Object(r.a)({},d,{appendTo:k,controlElement:this.controlRef,menuPlacement:x,menuPosition:E}),L):L}},{key:"renderFormField",value:function(){var e=this,t=this.props,n=t.delimiter,r=t.isDisabled,o=t.isMulti,i=t.name,l=this.state.selectValue;if(i&&!r){if(o){if(n){var s=l.map((function(t){return e.getOptionValue(t)})).join(n);return a.a.createElement("input",{name:i,type:"hidden",value:s})}var u=l.length>0?l.map((function(t,n){return a.a.createElement("input",{key:"i-".concat(n),name:i,type:"hidden",value:e.getOptionValue(t)})})):a.a.createElement("input",{name:i,type:"hidden"});return a.a.createElement("div",null,u)}var c=l[0]?this.getOptionValue(l[0]):"";return a.a.createElement("input",{name:i,type:"hidden",value:c})}}},{key:"renderLiveRegion",value:function(){var e=this.commonProps,t=this.state,n=t.ariaSelection,o=t.focusedOption,i=t.focusedValue,l=t.isFocused,s=t.selectValue,u=this.getFocusableOptions();return a.a.createElement(Xt,Object(r.a)({},e,{ariaSelection:n,focusedOption:o,focusedValue:i,isFocused:l,selectValue:s,focusableOptions:u}))}},{key:"render",value:function(){var e=this.getComponents(),t=e.Control,n=e.IndicatorsContainer,o=e.SelectContainer,i=e.ValueContainer,l=this.props,s=l.className,u=l.id,c=l.isDisabled,f=l.menuIsOpen,d=this.state.isFocused,p=this.commonProps=this.getCommonProps();return a.a.createElement(o,Object(r.a)({},p,{className:s,innerProps:{id:u,onKeyDown:this.onKeyDown},isDisabled:c,isFocused:d}),this.renderLiveRegion(),a.a.createElement(t,Object(r.a)({},p,{innerRef:this.getControlRef,innerProps:{onMouseDown:this.onControlMouseDown,onTouchEnd:this.onControlTouchEnd},isDisabled:c,isFocused:d,menuIsOpen:f}),a.a.createElement(i,Object(r.a)({},p,{isDisabled:c}),this.renderPlaceholderOrValue(),this.renderInput()),a.a.createElement(n,Object(r.a)({},p,{isDisabled:c}),this.renderClearIndicator(),this.renderLoadingIndicator(),this.renderIndicatorSeparator(),this.renderDropdownIndicator())),this.renderMenu(),this.renderFormField())}}],[{key:"getDerivedStateFromProps",value:function(e,t){var n=t.prevProps,r=t.clearFocusValueOnUpdate,o=t.inputIsHiddenAfterUpdate,a=e.options,i=e.value,l=e.menuIsOpen,s=e.inputValue,u={};if(n&&(i!==n.value||a!==n.options||l!==n.menuIsOpen||s!==n.inputValue)){var c=nt(i),f=l?function(e,t){return Pn(jn(e,t))}(e,c):[],d=r?function(e,t){var n=e.focusedValue,r=e.selectValue.indexOf(n);if(r>-1){if(t.indexOf(n)>-1)return n;if(r-1?n:t[0]}(t,f),focusedValue:d,clearFocusValueOnUpdate:!1}}var p=null!=o&&e!==n?{inputIsHidden:o,inputIsHiddenAfterUpdate:void 0}:{};return Ye(Ye(Ye({},u),p),{},{prevProps:e})}}]),n}(o.Component);Fn.defaultProps=Sn;var An={defaultInputValue:"",defaultMenuIsOpen:!1,defaultValue:null},Vn=(n(90),n(95),n(97),n(98),n(99),o.Component,function(e){var t,n;return n=t=function(t){He(o,t);var n=Ze(o);function o(){var e;ze(this,o);for(var t=arguments.length,r=new Array(t),a=0;a1?n-1:0),o=1;o=n.length&&(a=0),a<0&&(a=n.length-1),n[a]},P=function(e,t){null!=e&&(c&&c(e,t),k&&k(e,t))};Object(l.useEffect)((function(){if(C.current&&E.current){var e=C.current.querySelector("[data-rb-event-key].active");e&&e.focus()}E.current=!1}));var N=Object(h.a)(t,C);return s.a.createElement(b.a.Provider,{value:P},s.a.createElement(v.a.Provider,{value:{role:d,activeKey:Object(b.b)(f),getControlledId:n||y,getControllerId:a||y}},s.a.createElement(u,Object(r.a)({},O,{onKeyDown:function(e){var t;switch(w&&w(e),e.key){case"ArrowLeft":case"ArrowUp":t=j(-1);break;case"ArrowRight":case"ArrowDown":t=j(1);break;default:return}t&&(e.preventDefault(),P(t.dataset.rbEventKey,e),E.current=!0,x())},ref:N,role:d}))))})),O=n(52),x=n(59),E=s.a.forwardRef((function(e,t){var n,a,p,m=Object(u.a)(e,{activeKey:"onSelect"}),h=m.as,v=void 0===h?"div":h,b=m.bsPrefix,g=m.variant,y=m.fill,O=m.justify,x=m.navbar,E=m.className,k=m.children,S=m.activeKey,C=Object(o.a)(m,["as","bsPrefix","variant","fill","justify","navbar","className","children","activeKey"]),j=Object(c.a)(b,"nav"),P=!1,N=Object(l.useContext)(f.a),T=Object(l.useContext)(d.a);return N?(a=N.bsPrefix,P=null==x||x):T&&(p=T.cardHeaderBsPrefix),s.a.createElement(w,Object(r.a)({as:v,ref:t,activeKey:S,className:i()(E,(n={},n[j]=!P,n[a+"-nav"]=P,n[p+"-"+g]=!!p,n[j+"-"+g]=!!g,n[j+"-fill"]=y,n[j+"-justified"]=O,n))},C),k)}));E.displayName="Nav",E.defaultProps={justify:!1,fill:!1},E.Item=O.a,E.Link=x.a;t.a=E},function(e,t,n){"use strict";var r=n(63),o=60103,a=60106;t.Fragment=60107,t.StrictMode=60108,t.Profiler=60114;var i=60109,l=60110,s=60112;t.Suspense=60113;var u=60115,c=60116;if("function"===typeof Symbol&&Symbol.for){var f=Symbol.for;o=f("react.element"),a=f("react.portal"),t.Fragment=f("react.fragment"),t.StrictMode=f("react.strict_mode"),t.Profiler=f("react.profiler"),i=f("react.provider"),l=f("react.context"),s=f("react.forward_ref"),t.Suspense=f("react.suspense"),u=f("react.memo"),c=f("react.lazy")}var d="function"===typeof Symbol&&Symbol.iterator;function p(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n