summaryrefslogtreecommitdiff
path: root/src/view
diff options
context:
space:
mode:
Diffstat (limited to 'src/view')
-rw-r--r--src/view/FooterBuilder.php8
-rw-r--r--src/view/LoginBuilder.php41
-rw-r--r--src/view/MainBuilder.php2
-rw-r--r--src/view/UserEditBuilder.php58
-rw-r--r--src/view/ViewBuilder.php18
-rw-r--r--src/view/password.php155
-rw-r--r--src/view/templates/login.php28
-rw-r--r--src/view/templates/user_create.php52
-rw-r--r--src/view/templates/user_edit.php62
9 files changed, 243 insertions, 181 deletions
diff --git a/src/view/FooterBuilder.php b/src/view/FooterBuilder.php
index 14f9cd7..8a519f8 100644
--- a/src/view/FooterBuilder.php
+++ b/src/view/FooterBuilder.php
@@ -28,7 +28,7 @@ class FooterBuilder extends AbstractBuilder
28 if($_SESSION['admin']) 28 if($_SESSION['admin'])
29 { 29 {
30 $empty_admin_zone = 'empty_admin_zone'; 30 $empty_admin_zone = 'empty_admin_zone';
31 $link_edit_page = new URL(['page' => CURRENT_PAGE]); 31 $link_edit_page = CURRENT_PAGE === 'article' ? new URL(['page' => 'accueil']) : new URL(['page' => CURRENT_PAGE]);
32 if(MainBuilder::$modif_mode){ 32 if(MainBuilder::$modif_mode){
33 $mode = 'modification de page'; 33 $mode = 'modification de page';
34 $div_admin = 'logged_in modif_mode'; 34 $div_admin = 'logged_in modif_mode';
@@ -43,10 +43,10 @@ class FooterBuilder extends AbstractBuilder
43 $link_new_page = new URL(['page' => 'nouvelle_page']); 43 $link_new_page = new URL(['page' => 'nouvelle_page']);
44 $link_change_paths = new URL(['page' => 'menu_chemins']); 44 $link_change_paths = new URL(['page' => 'menu_chemins']);
45 45
46 $link_change_password = new URL(['from' => CURRENT_PAGE, 'action' => 'modif_mdp']); 46 $link_change_password = new URL(['page' => 'user_edit', 'from' => CURRENT_PAGE]);
47 isset($_GET['id']) ? $link_change_password->addParams(['id' => $_GET['id']]) : ''; 47 isset($_GET['id']) ? $link_change_password->addParams(['id' => $_GET['id']]) : '';
48 48
49 $link_logout = new URL(['page' => CURRENT_PAGE, 'action' => 'deconnexion']); 49 $link_logout = new URL(['action' => 'deconnection', 'from' => CURRENT_PAGE]);
50 isset($_GET['id']) ? $link_logout->addParams(['id' => $_GET['id']]) : ''; 50 isset($_GET['id']) ? $link_logout->addParams(['id' => $_GET['id']]) : '';
51 51
52 $zone_admin = '<div class="admin_buttons_zone"> 52 $zone_admin = '<div class="admin_buttons_zone">
@@ -54,7 +54,7 @@ class FooterBuilder extends AbstractBuilder
54 '<div><a href="' . $link_new_page . '"><button>Nouvelle page</button></a></div>' . "\n" . 54 '<div><a href="' . $link_new_page . '"><button>Nouvelle page</button></a></div>' . "\n" .
55 '<div><a href="' . $link_edit_page . '"><button>' . $link_edit_label . '</button></a></div>' . "\n" . 55 '<div><a href="' . $link_edit_page . '"><button>' . $link_edit_label . '</button></a></div>' . "\n" .
56 '<div><a href="' . $link_change_paths . '"><button>Menu et chemins</button></a></div>' . "\n" . 56 '<div><a href="' . $link_change_paths . '"><button>Menu et chemins</button></a></div>' . "\n" .
57 '<div><a href="' . $link_change_password . '"><button>Changer de mot de passe</button></a></div>' . "\n" . 57 '<div><a href="' . $link_change_password . '"><button>Mon compte</button></a></div>' . "\n" .
58 '<div><a href="' . $link_logout . '"><button>Déconnexion</button></a></div>' . "\n" . 58 '<div><a href="' . $link_logout . '"><button>Déconnexion</button></a></div>' . "\n" .
59 '</div>' . "\n"; 59 '</div>' . "\n";
60 } 60 }
diff --git a/src/view/LoginBuilder.php b/src/view/LoginBuilder.php
index 532f054..567c93d 100644
--- a/src/view/LoginBuilder.php
+++ b/src/view/LoginBuilder.php
@@ -9,9 +9,44 @@ class LoginBuilder extends AbstractBuilder
9{ 9{
10 public function __construct(Node $node) 10 public function __construct(Node $node)
11 { 11 {
12 global $entityManager; 12 // déjà connecté?
13 if($_SESSION['admin'])
14 {
15 header('Location: ' . new URL);
16 die;
17 }
13 18
14 // une classe Password ce serait pas mal!! 19 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
15 connect($this, $entityManager); 20
21 $captcha = new Captcha;
22 $_SESSION['captcha'] = $captcha->getSolution(); // enregistrement de la réponse du captcha pour vérification
23
24 //$this->html .= $header;
25
26 $error_messages = [
27 'error_non_valid_captcha' => 'Erreur au test anti-robot, veuillez saisir un nombre entier.',
28 'captcha_server_error' => 'captcha_server_error',
29 'bad_solution_captcha' => 'Erreur au test anti-robot, veuillez réessayer.',
30 'bad_login_or_password' => 'Mauvais identifiant ou mot de passe, veuillez réessayer.', // ne pas indiquer où est l'erreur
31 'forbidden_characters' => 'Caractères interdits: espaces, tabulations, sauts CR/LF.'
32 ];
33
34 $link_form = new URL(['action' => 'connection']);
35 isset($_GET['from']) ? $link_form->addParams(['from' => $_GET['from']]) : '';
36 isset($_GET['id']) ? $link_form->addParams(['id' => $_GET['id']]) : '';
37
38 $link_exit = new URL;
39 isset($_GET['from']) ? $link_exit->addParams(['page' => $_GET['from'] ]) : '';
40 isset($_GET['id']) ? $link_exit->addParams(['id' => $_GET['id']]) : '';
41
42 $error = isset($_GET['error']) ? $error_messages[$_GET['error']] : '';
43
44 ob_start();
45 require $viewFile;
46 $this->html = ob_get_clean(); // nouveau contenu
47
48 //$this->html .= <p class='connexionP' style='color: red;'>Ce site utilise un cookie « obligatoire » lorsque vous êtes connecté ainsi que sur cette page.<br>Il sera supprimé à votre déconnexion ou dès que vous aurez quitté le site.</p>;
49
50 //$this->html .= $footer;
16 } 51 }
17} 52}
diff --git a/src/view/MainBuilder.php b/src/view/MainBuilder.php
index 7f3a0f0..889df37 100644
--- a/src/view/MainBuilder.php
+++ b/src/view/MainBuilder.php
@@ -86,7 +86,7 @@ class MainBuilder extends AbstractBuilder
86 86
87 //$page_id = Director::$page_path->getLast()->getId(); 87 //$page_id = Director::$page_path->getLast()->getId();
88 $head_node = null; 88 $head_node = null;
89 foreach(ViewBuilder::$root_node->getChildren() as $first_level_node){ 89 foreach(ViewController::$root_node->getChildren() as $first_level_node){
90 if($first_level_node->getName() === 'head'){ 90 if($first_level_node->getName() === 'head'){
91 $head_node = $first_level_node; // normallement c'est le 1er enfant 91 $head_node = $first_level_node; // normallement c'est le 1er enfant
92 break; 92 break;
diff --git a/src/view/UserEditBuilder.php b/src/view/UserEditBuilder.php
new file mode 100644
index 0000000..63bbfad
--- /dev/null
+++ b/src/view/UserEditBuilder.php
@@ -0,0 +1,58 @@
1<?php
2// src/view/UserEditBuilder.php
3//
4// fonctionne avec UserController
5
6declare(strict_types=1);
7
8use App\Entity\Node;
9
10class UserEditBuilder extends AbstractBuilder
11{
12 public function __construct(Node $node)
13 {
14 // pour éviter les arnaques
15 if(!$_SESSION['admin'])
16 {
17 header('Location: ' . new URL);
18 die;
19 }
20
21 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
22
23 $error_messages = [
24 'error_non_valid_captcha' => 'Erreur au test anti-robot, veuillez saisir un nombre entier.',
25 'captcha_server_error' => 'captcha_server_error',
26
27 'bad_login_or_password' => 'Mauvais identifiant ou mot de passe, veuillez réessayer.', // ne pas indiquer où est l'erreur
28 'bad_solution_captcha' => 'Erreur au test anti-robot, veuillez réessayer.',
29 'forbidden_characters' => 'Caractères interdits: espaces, tabulations, sauts CR/LF.',
30 'same_username_as_before' => 'Nouveau nom identique au précédent.',
31 'same_password_as_before' => 'Nouveau mot de passe identique au précédent.'
32 ];
33
34 $error_username = isset($_GET['error_login']) ? $error_messages[$_GET['error_login']] : '';
35 $success_username = (isset($_GET['success_login']) && $_GET['success_login']) ? 'Identifiant modifié avec succès.' : '';
36 $error_password = isset($_GET['error_password']) ? $error_messages[$_GET['error_password']] : '';
37 $success_password = (isset($_GET['success_password']) && $_GET['success_password']) ? 'Mot de passe modifié avec succès.' : '';
38
39 $captcha = new Captcha;
40 $_SESSION['captcha'] = $captcha->getSolution(); // enregistrement de la réponse du captcha pour vérification
41
42 $link_user_form = new URL(['action' => 'update_username']);
43 isset($_GET['from']) ? $link_user_form->addParams(['from' => $_GET['from']]) : '';
44 isset($_GET['id']) ? $link_user_form->addParams(['id' => $_GET['id']]) : '';
45
46 $link_password_form = new URL(['action' => 'update_password']);
47 isset($_GET['from']) ? $link_password_form->addParams(['from' => $_GET['from']]) : '';
48 isset($_GET['id']) ? $link_password_form->addParams(['id' => $_GET['id']]) : '';
49
50 $link_exit = new URL;
51 isset($_GET['from']) ? $link_exit->addParams(['page' => $_GET['from'] ]) : '';
52 isset($_GET['id']) ? $link_exit->addParams(['id' => $_GET['id']]) : '';
53
54 ob_start();
55 require $viewFile;
56 $this->html = ob_get_clean(); // nouveau contenu
57 }
58} \ No newline at end of file
diff --git a/src/view/ViewBuilder.php b/src/view/ViewBuilder.php
deleted file mode 100644
index 2e2fea6..0000000
--- a/src/view/ViewBuilder.php
+++ /dev/null
@@ -1,18 +0,0 @@
1<?php
2// src/view/ViewBuilder.php
3//
4// appelle les autres Builder
5
6declare(strict_types=1);
7
8use App\Entity\Node;
9
10class ViewBuilder extends AbstractBuilder
11{
12 static public Node $root_node;
13 public function __construct(Node $root_node)
14 {
15 self::$root_node = $root_node;
16 $this->useChildrenBuilder($root_node);
17 }
18}
diff --git a/src/view/password.php b/src/view/password.php
deleted file mode 100644
index 77f8736..0000000
--- a/src/view/password.php
+++ /dev/null
@@ -1,155 +0,0 @@
1<?php
2// src/view/password.php
3//
4// ce fichier contient le HTML de deux pages du site:
5// - connexion au mode admin
6// - changement de mot de passe
7//
8// rajouter la page "créationn du mot de passe"?
9
10declare(strict_types=1);
11
12// insertion du captcha
13$captchaHtml = '';
14if(isset($captcha)) // instance de Captcha?
15{
16 ob_start();
17 ?>
18 <p>Montrez que vous n'êtes pas un robot.<br>
19 <label for="captcha" >Combien font <?= $captcha->getA() ?> fois <?= $captcha->getB() ?>?</label>
20 <input required type="text" id="captcha" name="captcha" autocomplete="off" size="1">
21 </p>
22 <?php
23 $captchaHtml = ob_get_clean();
24}
25
26
27// formulaire connexion
28$link = new URL(['page' => 'connexion']);
29isset($_GET['from']) ? $link->addParams(['from' => $_GET['from']]) : '';
30isset($_GET['id']) ? $link->addParams(['id' => $_GET['id']]) : '';
31ob_start();
32?>
33 <form class="connexionFormulaire" method="post" action="<?= $link ?>" >
34 <p><label for="login" >Identifiant (E-mail):</label>
35 <input id="login" type="text" name="login" autofocus required></p>
36 <p><label for="password" >Mot de passe:</label>
37 <input id="password" type="password" name="password" required></p>
38
39 <?= $captchaHtml ?>
40
41 <input type="submit" value="Valider">
42 </form>
43<?php
44$formulaireConnexion = ob_get_clean();
45
46// formulaire création du mot de passe
47ob_start();
48?>
49 <form class="connexionFormulaire" method="post" action="index.php" >
50 <p><label for="login" >Identifiant (e-mail):</label>
51 <input id="login" type="text" name="login" autofocus required></p>
52 <p><label for="password" >Mot de passe:</label>
53 <input id="password" type="password" name="password" required></p>
54
55 <?= $captchaHtml ?>
56
57 <input type="submit" value="Valider">
58 </form>
59<?php
60$formulaireNouveauMDP = ob_get_clean();
61
62// formulaire changement de mot de passe
63$link = new URL(['action' => 'modif_mdp']);
64isset($_GET['from']) ? $link->addParams(['from' => $_GET['from']]) : '';
65isset($_GET['id']) ? $link->addParams(['id' => $_GET['id']]) : '';
66ob_start();
67?>
68 <form class="connexionFormulaire" method="post" action="<?= $link ?>" >
69 <label for="login" >Identifiant (e-mail):</label>
70 <input id="login" type="login" name="login" autofocus required ><br><br>
71 <label for="old_password" >Ancien mot de passe:</label>
72 <input id="old_password" type="password" name="old_password" required ><br><br>
73 <label for="new_password" >Nouveau mot de passe:</label>
74 <input id="new_password" type="password" name="new_password" required autocomplete="off">
75 <input type="hidden" name="modify_password_hidden">
76 <br><br>
77 <input type="submit" value="Valider" >
78 </form>
79<?php
80$formulaireModifMDP = ob_get_clean();
81
82// en-tête
83ob_start();
84?>
85<!DOCTYPE html>
86
87<html lang="fr">
88 <head>
89 <meta charset="utf-8">
90 <title><?= $title ?></title>
91
92 <link rel="icon" type="image/png" href="assets/favicon48x48.png">
93 <script src="js/main.js" ></script>
94 <meta name="viewport" content="width=device-width, initial-scale=1.0">
95 <style>
96 body{background-color: #E3F3FF;}
97 #bloc_page{text-align: center;}
98 .avertissement{color: red;}
99 </style>
100 </head>
101
102 <body>
103 <div id="bloc_page" >
104 <h2 class="connexionTitre" ><?= $title ?></h2>
105 <p class="connexionP" ><?= $subHeading ?></p>
106<?php
107$header = ob_get_clean();
108
109
110$error_messages = [
111 'error_non_valid_captcha' => '<p class="avertissement" >Erreur au test anti-robot, veuillez saisir un nombre entier.</p>',
112 'bad_solution_captcha' => '<p class="avertissement" >Erreur au test anti-robot, veuillez réessayer.</p>',
113 'bad_login_or_password' => '<p class="avertissement" >Mauvais identifiant ou mot de passe, veuillez réessayer.</p>', // ne pas indiquer où est l'erreur
114 'forbidden_characters' => '<p class="avertissement" >Caractères interdits: espaces, tabulations, sauts CR/LF.</p>'
115];
116
117$warning_messages = [
118 'message_disconnect' => "<p class='connexionP' ><i>N'oubliez de cliquer sur 'déconnexion' quand vous aurez fini.</i></p>",
119 //'message_cookie' => "<p class='connexionP' style='color: red;'>Ce site utilise un cookie « obligatoire » lorsque vous êtes connecté ainsi que sur cette page.<br>Il sera supprimé à votre déconnexion ou dès que vous aurez quitté le site.</p>",
120 'private_browsing' =>"<p class='connexionP' >Au fait? Vous n'utilisez pas votre propre ordinateur ou téléphone?<br/>
121 Utilisez la navigation privée.</p>"
122];
123
124
125// confirmation modification du mot de passe
126$page = isset($_GET['from']) ? $_GET['from'] : 'accueil';
127$id = isset($_GET['id']) ? ', \'' . $_GET['id'] . '\'' : '';
128$js = "newPassword('" . $page . "'" . $id . ");";
129ob_start();
130?>
131<script><?= $js ?></script>
132<noscript>
133 <p class="avertissement" >Le mot de passe a été modifié<br>
134 <a href="<?= $link ?>" ><button>Retour au site.</button></a></p>
135</noscript>
136<?php
137$alertJSNewPassword = ob_get_clean();
138
139
140// bas de la page
141$link = new URL();
142isset($_GET['from']) ? $link->addParams(['page' => $_GET['from'] ]) : '';
143isset($_GET['id']) ? $link->addParams(['id' => $_GET['id']]) : '';
144ob_start();
145if(isset($_GET['from'])) // exclue la "création du mot de passe"
146{
147?>
148 <p class="connexionP connexionFooter" >
149 <a href="<?= $link ?>" >
150 <button>Retour au site.</button>
151 </a>
152 </p>
153<?php
154}
155$footer = ob_get_clean(); \ No newline at end of file
diff --git a/src/view/templates/login.php b/src/view/templates/login.php
new file mode 100644
index 0000000..766c114
--- /dev/null
+++ b/src/view/templates/login.php
@@ -0,0 +1,28 @@
1<?php declare(strict_types=1); ?>
2 <section>
3 <h3 class="connexionTitre" >Connexion à l'espace d'administration</h3>
4 <div class="login_form">
5 <p class="connexionP" >Veuillez saisir votre identifiant et votre mot de passe.</p>
6 <p style="color: red; font-style: italic;"><?= $error ?></p>
7 <form class="connexionFormulaire" method="post" action="<?= $link_form ?>" >
8 <p><label for="login" >Identifiant:</label>
9 <input id="login" type="text" name="login" autofocus required></p>
10 <p><label for="password" >Mot de passe:</label>
11 <input id="password" type="password" name="password" required></p>
12
13 <p>Montrez que vous n'êtes pas un robot.<br>
14 <label for="captcha" >Combien font <?= $captcha->getA() ?> fois <?= $captcha->getB() ?>?</label>
15 <input required type="text" id="captcha" name="captcha" autocomplete="off" size="1">
16 </p>
17
18 <input type="submit" value="Valider">
19 </form>
20 <p class='connexionP' >Au fait? Vous n'utilisez pas votre propre ordinateur ou téléphone?<br/>
21 Utilisez la navigation privée.</p>
22 <p class="connexionP connexionFooter" >
23 <a href="<?= $link_exit ?>" >
24 <button>Retour au site</button>
25 </a>
26 </p>
27 </div>
28 </section> \ No newline at end of file
diff --git a/src/view/templates/user_create.php b/src/view/templates/user_create.php
new file mode 100644
index 0000000..dd17547
--- /dev/null
+++ b/src/view/templates/user_create.php
@@ -0,0 +1,52 @@
1<?php
2declare(strict_types=1);
3
4$error_messages = [
5 'error_non_valid_captcha' => 'Erreur au test anti-robot, veuillez saisir un nombre entier.',
6 'captcha_server_error' => 'captcha_server_error',
7 'bad_solution_captcha' => 'Erreur au test anti-robot, veuillez réessayer.',
8 'different_passwords' => 'Les deux mots de passe saisis sont différents',
9 'forbidden_characters' => 'Caractères interdits: espaces, tabulations, sauts CR/LF.'
10];
11$error = isset($_GET['error']) ? $error_messages[$_GET['error']] : '';
12
13$captcha = new Captcha;
14$_SESSION['captcha'] = $captcha->getSolution(); // enregistrement de la réponse du captcha pour vérification
15?>
16<!DOCTYPE html>
17<html lang="fr">
18 <head>
19 <meta charset="utf-8">
20 <title>Bienvenue</title>
21 <link rel="icon" type="image/png" href="assets/favicon48x48.png">
22 <link rel="stylesheet" href="css/body.css">
23 <meta name="viewport" content="width=device-width, initial-scale=1.0">
24 </head>
25 <body>
26 <main>
27 <section>
28 <h3>Bienvenue.</h3>
29 <p style="text-align: center;">Veuillez choisir les codes que vous utiliserez pour gérer le site.</p>
30 <div class="login_form">
31 <p style="color: red; font-style: italic;"><?= $error ?></p>
32 <form method="post" action="index.php?action=create_user" >
33 <p><label for="login" >Identifiant:</label>
34 <input id="login" type="text" name="login" autofocus required></p>
35 <p><label for="password" >Mot de passe:</label>
36 <input id="password" type="password" name="password" required></p>
37 <p><label for="password_confirmation" >Confirmer le mot de passe:</label>
38 <input id="password_confirmation" type="password" name="password_confirmation" required></p>
39 <input type="hidden" name="create_user_hidden">
40
41 <p>Montrez que vous n'êtes pas un robot.<br>
42 <label for="captcha" >Combien font <?= $captcha->getA() ?> fois <?= $captcha->getB() ?>?</label>
43 <input required type="text" id="captcha" name="captcha" autocomplete="off" size="1">
44 </p>
45
46 <input type="submit" value="Valider">
47 </form>
48 </div>
49 </section>
50 </main>
51 </body>
52</html> \ No newline at end of file
diff --git a/src/view/templates/user_edit.php b/src/view/templates/user_edit.php
new file mode 100644
index 0000000..b4b35ed
--- /dev/null
+++ b/src/view/templates/user_edit.php
@@ -0,0 +1,62 @@
1<?php declare(strict_types=1); ?>
2 <section>
3 <div class="user_edit_header">
4 <div class="empty_column"></div>
5 <h3 class="connexionTitre" >Mon compte</h3>
6 <div>
7 <img class="user_icon" src="assets/user_hollow.svg">
8 <div><?= $_SESSION['user'] ?></div>
9 </div>
10 </div>
11 <div class="user_edit_flex">
12 <div class="login_form">
13 <p class="connexionP" >Modifier mon nom d'utilisateur.</p>
14 <p style="color: red; font-style: italic;"><?= $error_username ?></p>
15 <p style="color: green; font-style: italic;"><?= $success_username ?></p>
16 <form class="connexionFormulaire" method="post" action="<?= $link_user_form ?>" >
17 <p><label for="old_login" >Ancien nom:</label>
18 <input id="old_login" type="text" name="old_login" required></p>
19 <p><label for="password" >Mot de passe:</label>
20 <input id="password" type="password" name="password" required ></p>
21 <p><label for="new_login" >Nouveau nom:</label>
22 <input id="new_login" type="text" name="new_login" required></p>
23 <input type="hidden" name="modify_username_hidden">
24
25 <p>Montrez que vous n'êtes pas un robot.<br>
26 <label for="captcha" >Combien font <?= $captcha->getA() ?> fois <?= $captcha->getB() ?>?</label>
27 <input required type="text" id="captcha" name="captcha" autocomplete="off" size="1">
28 </p>
29
30 <input type="submit" value="Valider">
31 </form>
32 </div>
33 <div class="login_form">
34 <p class="connexionP" >Modifier mon mot de passe.</p>
35 <p style="color: red; font-style: italic;"><?= $error_password ?></p>
36 <p style="color: green; font-style: italic;"><?= $success_password ?></p>
37 <form class="connexionFormulaire" method="post" action="<?= $link_password_form ?>" >
38 <p><label for="login" >Nom:</label>
39 <input id="login" type="text" name="login" required></p>
40 <p><label for="old_password" >Ancien mot de passe:</label>
41 <input id="old_password" type="password" name="old_password" required ></p>
42 <p><label for="new_password" >Nouveau mot de passe:</label>
43 <input id="new_password" type="password" name="new_password" required autocomplete="off"></p>
44 <input type="hidden" name="modify_password_hidden">
45
46 <p>Montrez que vous n'êtes pas un robot.<br>
47 <label for="captcha" >Combien font <?= $captcha->getA() ?> fois <?= $captcha->getB() ?>?</label>
48 <input required type="text" id="captcha" name="captcha" autocomplete="off" size="1">
49 </p>
50
51 <input type="submit" value="Valider">
52 </form>
53 </div>
54 </div>
55 <div class="login_form">
56 <p class="connexionP connexionFooter" >
57 <a href="<?= $link_exit ?>" >
58 <button>Retour au site</button>
59 </a>
60 </p>
61 </div>
62 </section> \ No newline at end of file