Gros progrès, statistiques 80%, reste à faire le school-info
This commit is contained in:
		| @@ -9,32 +9,127 @@ | ||||
|             <p>Moyenne des admis<span class="is-pulled-right">{state.average}</span></p> | ||||
|             <p>Nombre de formations<span class="is-pulled-right">{state.courseNumber}</span></p> | ||||
|             <p>Capacité<span class="is-pulled-right">{state.capacity}</span></p> | ||||
|             <p>Sélectivité</p> | ||||
|             <title-progress title={"Sélectivité"} value={state.selectivity} max="100"></title-progress> | ||||
|         </div> | ||||
|         <div class="m-4"> | ||||
|             <line-graph title="Répartition par genre" style="height: 6rem;"></line-graph> | ||||
|             <line-graph title="Répartition par genre" data={state.genreStats} style="height: 6rem;"></line-graph> | ||||
|         </div> | ||||
|         <div class="m-4"> | ||||
|             <line-graph title="Répartition par bac" style="height: 6rem;"></line-graph> | ||||
|             <line-graph title="Répartition par bac" data={state.bacStats} style="height: 6rem;"></line-graph> | ||||
|         </div> | ||||
|         <div class="m-4"> | ||||
|             <line-graph title="Répartition par mention au bac" style="height: 6rem;"></line-graph> | ||||
|             <line-graph title="Répartition par mention au bac" data={state.mentionStats} style="height: 6rem;"></line-graph> | ||||
|         </div> | ||||
|     </div> | ||||
|  | ||||
|     <script> | ||||
|         export default { | ||||
|             onBeforeMount(props, state) { | ||||
|                 this.state = { | ||||
|                 state = { | ||||
|                     average: 0, | ||||
|                     capacity: 0, | ||||
|                     selectivity: 0, | ||||
|                     courseNumber: 0 | ||||
|                     courseNumber: 0, | ||||
|                     bacStats: [], | ||||
|                     genreStats: [], | ||||
|                     mentionStats: [] | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             onUpdated(props, state) { | ||||
|             onBeforeUpdate(props, state) { | ||||
|                 if (!props.schoolList || !props.schoolList.length) return | ||||
|  | ||||
|                 let list = props.schoolList | ||||
|  | ||||
|                 let avg = list.reduce((s, e) => s + e.fields.moyenne, 0) / list.length | ||||
|                 let avgCap = list.reduce((s, e) => s + e.fields.capa_fin, 0) / list.length | ||||
|                 let avgSlc = list.reduce((s, e) => s + (e.fields.taux_acces_ens || 0), 0) / list.filter((e) => e.fields.taux_acces_ens).length | ||||
|  | ||||
|                 state.courseNumber = list.length | ||||
|                 state.average = Math.round(avg * 100) / 100 | ||||
|                 state.capacity = Math.floor(avgCap) | ||||
|                 state.selectivity = Math.floor(avgSlc) | ||||
|  | ||||
|                 let pctFemmes = Math.round(list.reduce((s, e) => s + (e.fields.pct_f || 0), 0) / list.filter((e) => e.fields.pct_f).length) | ||||
|                 console.log(pctFemmes) | ||||
|                 state.genreStats = [ | ||||
|                     { | ||||
|                         name: "Hommes", | ||||
|                         short: "H", | ||||
|                         value: (100 - pctFemmes) | ||||
|                     }, | ||||
|                     { | ||||
|                         name: "Femmes", | ||||
|                         short: "F", | ||||
|                         value: pctFemmes | ||||
|                     }, | ||||
|                 ] | ||||
|  | ||||
|                 let pctBG = Math.round(list.reduce((s, e) => s + (e.fields.part_acces_gen || 0), 0) / list.filter((e) => e.fields.part_acces_gen).length) | ||||
|                 let pctBT = Math.round(list.reduce((s, e) => s + (e.fields.part_acces_tec || 0), 0) / list.filter((e) => e.fields.part_acces_tec).length) | ||||
|                 let pctBP = Math.round(list.reduce((s, e) => s + (e.fields.part_acces_pro || 0), 0) / list.filter((e) => e.fields.part_acces_pro).length) | ||||
|  | ||||
|                 state.bacStats = [ | ||||
|                     { | ||||
|                         name: "Général", | ||||
|                         short: "Gen.", | ||||
|                         value: pctBG | ||||
|                     }, | ||||
|                     { | ||||
|                         name: "Technologique", | ||||
|                         short: "Tech.", | ||||
|                         value: pctBT | ||||
|                     }, | ||||
|                     { | ||||
|                         name: "Professionnel", | ||||
|                         short: "Pro.", | ||||
|                         value: pctBP | ||||
|                     }, | ||||
|                     { | ||||
|                         name: "Autre", | ||||
|                         short: "Au.", | ||||
|                         value: 100 - (pctBG + pctBT + pctBP) | ||||
|                     } | ||||
|                 ] | ||||
|  | ||||
|                 let pctSM  = Math.round(list.reduce((s, e) => s + e.fields.pct_sansmention, 0) / list.length) | ||||
|                 let pctAB  = Math.round(list.reduce((s, e) => s + e.fields.pct_ab, 0) / list.length) | ||||
|                 let pctB   = Math.round(list.reduce((s, e) => s + e.fields.pct_b, 0) / list.length) | ||||
|                 let pctTB  = Math.round(list.reduce((s, e) => s + e.fields.pct_tb, 0) / list.length) | ||||
|                 let pctTBF = Math.round(list.reduce((s, e) => s + e.fields.pct_tbf, 0) / list.length) | ||||
|  | ||||
|                 state.mentionStats = [ | ||||
|                     { | ||||
|                         name: "Sans Mention", | ||||
|                         short: "SM", | ||||
|                         value: pctSM | ||||
|                     }, | ||||
|                     { | ||||
|                         name: "Assez Bien", | ||||
|                         short: "AB", | ||||
|                         value: pctAB | ||||
|                     }, | ||||
|                     { | ||||
|                         name: "Bien", | ||||
|                         short: "B", | ||||
|                         value: pctB | ||||
|                     }, | ||||
|                     { | ||||
|                         name: "Très Bien", | ||||
|                         short: "TB", | ||||
|                         value: pctTB | ||||
|                     }, | ||||
|                     { | ||||
|                         name: "Très Bien + Félicitations", | ||||
|                         short: "TBF", | ||||
|                         value: pctTBF | ||||
|                     }, | ||||
|                     { | ||||
|                         name: "Non Spécifié", | ||||
|                         short: "NS", | ||||
|                         value: 100 - (pctSM + pctAB + pctB + pctTB + pctTBF) | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         } | ||||
|     </script> | ||||
|   | ||||
| @@ -10,7 +10,7 @@ | ||||
|  | ||||
|             updateCanvas() { | ||||
|                 let canvas = this.$("canvas") | ||||
|                 if (!canvas) return | ||||
|                 if (!canvas || !this.props.data || !this.props.title) return | ||||
|  | ||||
|                 canvas.width = canvas.clientWidth | ||||
|                 canvas.height = canvas.clientHeight | ||||
| @@ -23,13 +23,14 @@ | ||||
|                 let height = canvas.height | ||||
|                 let spacing = 1 | ||||
|  | ||||
|                 let data = this.state.data | ||||
|                 let data = this.props.data | ||||
|                 let colors = [ | ||||
|                     "#003F5C", | ||||
|                     "#2F4B7C", | ||||
|                     "#665191", | ||||
|                     "#A05195", | ||||
|                     "#D45087" | ||||
|                     "#D45087", | ||||
|                     "#D47150" | ||||
|                 ] | ||||
|                  | ||||
|                 cx.clearRect(0, 0, width, height) | ||||
| @@ -48,9 +49,10 @@ | ||||
|                 let counter = 0 | ||||
|                 let legendWidth = 0 | ||||
|                 for (let field of data) { | ||||
|                     if (field.value == 0) continue | ||||
|                     let start = curr + spacing | ||||
|                     let barWidth = field.value / total * width - spacing * 2 | ||||
|                     let text = `${Math.round(field.value / total * 1000) / 10}% (${field.name})` | ||||
|                     let text = `${Math.round(field.value / total * 1000) / 10}% (${field.short || field.name})` | ||||
|  | ||||
|                     cx.fillStyle = colors[counter] | ||||
|                     cx.fillRect(start, 0, barWidth, height / 3) | ||||
| @@ -58,14 +60,15 @@ | ||||
|                     cx.fillStyle = "#FFFFFF" | ||||
|                     if (cx.measureText(text).width < barWidth) { | ||||
|                         cx.fillText(text, start + barWidth / 2, height / 6) | ||||
|                     } else if (cx.measureText("...").width < barWidth) { | ||||
|                         cx.fillText("...", start + barWidth / 2, height / 6) | ||||
|                     } else if (cx.measureText(`${Math.round(field.value / total * 1000) / 10}%`).width < barWidth) { | ||||
|                         cx.fillText(`${Math.round(field.value / total * 1000) / 10}%`, start + barWidth / 2, height / 6) | ||||
|                     } | ||||
|  | ||||
|                     curr += field.value / total * width | ||||
|                     counter++ | ||||
|  | ||||
|                     legendWidth += cx.measureText(field.name).width + 25 + 15 // += textWidth + squareWidth + margin | ||||
|                      | ||||
|                     let legendText = field.name + (field.short ? ` (${field.short})` : "") | ||||
|                     legendWidth += cx.measureText(legendText).width + 25 + 15 | ||||
|                 } | ||||
|  | ||||
|                 cx.textAlign = "left" | ||||
| @@ -74,20 +77,18 @@ | ||||
|  | ||||
|                 counter = 0 | ||||
|                 for (let field of data) { | ||||
|                     if (field.value == 0) continue | ||||
|                     cx.fillStyle = colors[counter] | ||||
|                     cx.fillRect(0, 0, 25, 25) | ||||
|                     cx.fillStyle = "#707070" | ||||
|                     cx.fillText(field.name, 30, 12.5) | ||||
|                     cx.translate(cx.measureText(field.name).width + 25 + 15, 0) | ||||
|  | ||||
|                     let legendText = field.name + (field.short ? ` (${field.short})` : "") | ||||
|                     cx.fillText(legendText, 30, 12.5) | ||||
|                     cx.translate(cx.measureText(legendText).width + 25 + 15, 0) | ||||
|                     counter++ | ||||
|                 } | ||||
|             }, | ||||
|  | ||||
|             state: { | ||||
|                 data: [], | ||||
|                 title: "Example" | ||||
|             }, | ||||
|  | ||||
|             onMounted() { | ||||
|                 let canvas = this.$("canvas") | ||||
|                 this.updateCanvas() | ||||
|   | ||||
| @@ -8,28 +8,96 @@ | ||||
| 		</div> | ||||
|  | ||||
| 		<div class="column"> | ||||
| 			<fili-info course={state.course} shouldShowInfos={state.shouldShowInfos}></fili-info> | ||||
| 			<school parentUpdate={state.updating} course={state.course} shouldShowInfos={state.shouldShowInfos}></school> | ||||
| 			<fili-info schoolList={state.schoolList} course={state.course} shouldShowInfos={state.shouldShowInfos}></fili-info> | ||||
| 			<school sortList={sortList} schoolList={state.schoolList} sortFields={state.sortFields} course={state.course} shouldShowInfos={state.shouldShowInfos}></school> | ||||
| 		</div> | ||||
| 	</div> | ||||
|  | ||||
| 	<school-info></school-info> | ||||
|  | ||||
|     <script> | ||||
|          export default { | ||||
|             onBeforeMount(props, state) { | ||||
|                 //Initial state | ||||
|                 this.state = { | ||||
|                     course: null, | ||||
|                     updating: false, | ||||
| 					shouldShowInfos: false | ||||
|  | ||||
|         import PAPI from '../javascript/parcoursup-link.js' | ||||
|  | ||||
|         const SORT_TABLE = [ | ||||
|             {name: "Nom", id: "g_ea_lib_vx"}, | ||||
|             {name: "Ville", id: "ville_etab"}, | ||||
|             {name: "Département", id: "dep"}, | ||||
|             {name: "Moyenne", id: "moyenne"}, | ||||
|             {name: "Sélectivité", id: "taux_acces_ens"} | ||||
|         ] | ||||
|  | ||||
|         export default { | ||||
|             sortList(sortBy) { | ||||
|                 //Si la liste est déjà triée par la bonne catégorie, on l'inverse | ||||
|                 if (sortBy == this.state.sortBy) { | ||||
|                     this.state.schoolList.reverse() | ||||
|                 }  | ||||
|                 //Sinon on l'ordonne par la nouvelle catégorie (ascendant par défaut) | ||||
|                 else {  | ||||
|                     this.state.sortBy = sortBy | ||||
|  | ||||
|                     switch (sortBy) { | ||||
|                         case SORT_TABLE[3].id: | ||||
|                         case SORT_TABLE[4].id: { | ||||
|                             this.state.schoolList.sort((a, b) => { | ||||
|                                 if (a.fields[sortBy] > b.fields[sortBy]) return 1 | ||||
|                                 else return -1 | ||||
|                             }) | ||||
|                             break | ||||
|                         } | ||||
|  | ||||
|                         default: { | ||||
|                             this.state.schoolList.sort((a, b) => { | ||||
|                                 return (a.fields[sortBy]).localeCompare(b.fields[sortBy]) | ||||
|                             }) | ||||
|                             break | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 this.update({ | ||||
|                     schoolList: this.state.schoolList | ||||
|                 }) | ||||
|             }, | ||||
|             updateList(course) { | ||||
|                 course = course || this.state.course | ||||
|                 PAPI.fetchEtablissement(course.fili, course.sousfili, course.soussousfili).then((response) => { | ||||
|                     response.forEach(etablissement => { | ||||
|                         // calcul la moyenne | ||||
|                         let pct_sansmention = etablissement.fields.pct_sansmention | ||||
|                         let pct_AB = etablissement.fields.pct_ab | ||||
|                         let pct_B = etablissement.fields.pct_b | ||||
|                         let pct_TB = etablissement.fields.pct_tb | ||||
|                         let pct_TBF = etablissement.fields.pct_tbf | ||||
|                          | ||||
|                         // On prend la moyenne des moyennes comprises dans la mention | ||||
|                         // Exemple : Assez bien est entre 12 et 14 donc 13. | ||||
|                         etablissement.fields.moyenne = ((pct_TBF*19)+(pct_TB*17)+(pct_B*15)+(pct_AB*13)+(pct_sansmention*11))/100 | ||||
|                     })  | ||||
|  | ||||
|                     this.update({ | ||||
|                         schoolList: response | ||||
|                     })                   | ||||
|                 }) | ||||
|             }, | ||||
|             updateCourse(course){ | ||||
|                 this.updateList(course) | ||||
|  | ||||
|                 this.update({ | ||||
|                     course: course, | ||||
|                     sortFields: SORT_TABLE, | ||||
| 					shouldShowInfos: course != null, | ||||
|                     updating: !this.state.updating | ||||
|                 }) | ||||
|             }, | ||||
|  | ||||
|             onMounted(props, state) { | ||||
|                 this.update({ | ||||
|                     course: null, | ||||
|                     sortBy: null, | ||||
|                     schoolList: null, | ||||
|                     sortFields: SORT_TABLE, | ||||
| 					shouldShowInfos: false | ||||
|                 }) | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <school> | ||||
|     <div if={props.shouldShowInfos} class="box p-2 m-2"> | ||||
|         <iframe width="100%" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"  | ||||
|     <div if={props.shouldShowInfos} class="box p-2 m-2" disabled="true"> | ||||
|         <iframe if={false} width="100%" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"  | ||||
|         src="https://www.openstreetmap.org/export/embed.html?bbox=-14.655761718750002%2C40.56389453066509%2C13.601074218750002%2C51.754240074033525&layer=mapnik"  | ||||
|         style="border-radius: 5px;"></iframe> | ||||
|         <br> | ||||
| @@ -13,115 +13,23 @@ | ||||
| 		<table class="table is-fullwidth is-hoverable"> | ||||
| 			<thead> | ||||
| 				<tr> | ||||
| 					<th each={sortField in state.sortFields}> | ||||
| 					<th each={sortField in props.sortFields}> | ||||
|                         {sortField.name} | ||||
|                         <a id={sortField.id} onclick={() => sortList(sortField.id)}> | ||||
|                         <a id={sortField.id} onclick={() => props.sortList(sortField.id)}> | ||||
|                             <span class="icon"><i class="fas fa-sort"></i></span> | ||||
|                         </a> | ||||
|                     </th> | ||||
| 				</tr> | ||||
| 			</thead> | ||||
|             <tbody> | ||||
|                 <tr each={etablissement in state.items}> | ||||
|                     <td>{etablissement.fields.g_ea_lib_vx}</td> | ||||
|                     <td>{etablissement.fields.ville_etab}</td> | ||||
|                     <td>{etablissement.fields.dep}</td> | ||||
|                     <td>{etablissement.fields.moyenne}</td> | ||||
|                     <td>{etablissement.fields.taux_acces_ens}</td> | ||||
|                 <tr each={school in props.schoolList}> | ||||
|                     <td>{school.fields.g_ea_lib_vx}</td> | ||||
|                     <td>{school.fields.ville_etab}</td> | ||||
|                     <td>{school.fields.dep}</td> | ||||
|                     <td>{school.fields.moyenne}</td> | ||||
|                     <td><title-progress value={school.fields.taux_acces_ens} max="100" style="margin: auto"></title-progress></td> | ||||
|                 </tr> | ||||
|             </tbody> | ||||
|         </table> | ||||
|     </div> | ||||
|  | ||||
|     <script> | ||||
|         import PAPI from '../javascript/parcoursup-link.js' | ||||
|  | ||||
|         async function fetchEtablissement(course) { | ||||
|             return PAPI.fetchEtablissement(course.fili, course.sousfili, course.soussousfili); | ||||
|         } | ||||
|  | ||||
|         const SORT_TABLE = [ | ||||
|             {name: "Nom", id: "g_ea_lib_vx"}, | ||||
|             {name: "Ville", id: "ville_etab"}, | ||||
|             {name: "Département", id: "dep"}, | ||||
|             {name: "Moyenne", id: "moyenne"}, | ||||
|             {name: "Sélectivité", id: "taux_acces_ens"} | ||||
|         ] | ||||
|  | ||||
|         export default function search() { | ||||
|             return { | ||||
|                 updateList() { | ||||
|                     fetchEtablissement(this.props.course).then((response) => { | ||||
|                         response.forEach(etablissement => { | ||||
|                             // calcul la moyenne | ||||
|                             let pct_sansmention = etablissement.fields.pct_sansmention | ||||
|                             let pct_AB = etablissement.fields.pct_ab | ||||
|                             let pct_B = etablissement.fields.pct_b | ||||
|                             let pct_TB = etablissement.fields.pct_tb | ||||
|                             let pct_TBF = etablissement.fields.pct_tbf | ||||
|                              | ||||
|                             // On prend la moyenne des moyennes comprises dans la mention | ||||
|                             // Exemple : Assez bien est entre 12 et 14 donc 13. | ||||
|                             etablissement.fields.moyenne = ((pct_TBF*19)+(pct_TB*17)+(pct_B*15)+(pct_AB*13)+(pct_sansmention*11))/100 | ||||
|                         }) | ||||
|  | ||||
|                         this.update({ | ||||
|                             items: response, | ||||
|                             parentUpdate: this.props.parentUpdate | ||||
|                         }) | ||||
|                     }) | ||||
|                 }, | ||||
|                 sortList(sortBy) { | ||||
|                     //Si la liste est déjà triée par la bonne catégorie, on l'inverse | ||||
|                     if (sortBy == this.state.sortBy) { | ||||
|                         this.state.items.reverse() | ||||
|                     }  | ||||
|                     //Sinon on l'ordonne par la nouvelle catégorie (ascendant par défaut) | ||||
|                     else {  | ||||
|                         this.state.sortBy = sortBy | ||||
|  | ||||
|                         switch (sortBy) { | ||||
|                             case SORT_TABLE[3].id: | ||||
|                             case SORT_TABLE[4].id: { | ||||
|                                 this.state.items.sort((a, b) => { | ||||
|                                     if (a.fields[sortBy] > b.fields[sortBy]) return 1 | ||||
|                                     else return -1 | ||||
|                                 }) | ||||
|                                 break | ||||
|                             } | ||||
|  | ||||
|                             default: { | ||||
|                                 this.state.items.sort((a, b) => { | ||||
|                                     return (a.fields[sortBy]).localeCompare(b.fields[sortBy]) | ||||
|                                 }) | ||||
|                                 break | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     this.update({ | ||||
|                         items: this.state.items | ||||
|                     }) | ||||
|                 }, | ||||
|                 onBeforeMount(props, state) { | ||||
|                     state = { | ||||
|                         items: null, | ||||
|                         breakCycle: false, | ||||
|                         sortBy: null, | ||||
|                         parentUpdate: null, | ||||
|                         sortFields: null | ||||
|                     } | ||||
|                 }, | ||||
|                 onMounted(props, state) { | ||||
|                     this.update({ | ||||
|                         sortFields: SORT_TABLE | ||||
|                     }) | ||||
|                 }, | ||||
|                 onUpdated(props, state) { | ||||
|                     if (!props.shouldShowInfos || state.parentUpdate == props.parentUpdate) return | ||||
|                     this.updateList() | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     </script> | ||||
| </school> | ||||
| @@ -38,7 +38,7 @@ | ||||
|                         promise = PAPI.fetchFiliere(this.state.course.fili) | ||||
|                         break | ||||
|                     case 2: | ||||
|                         promise = PAPI.fetchSpecialites(this.state.course.sousfili) | ||||
|                         promise = PAPI.fetchSpecialites(this.state.course.fili, this.state.course.sousfili) | ||||
|                         break | ||||
|  | ||||
|                     default: | ||||
|   | ||||
							
								
								
									
										49
									
								
								components/title-progress.riot
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								components/title-progress.riot
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| <title-progress> | ||||
|  | ||||
| <div style="display: flex;"> | ||||
|     <span if={props.title}>{props.title}</span> | ||||
|     <span class="ml-1">{calcPct()}</span> | ||||
|     <progress value={props.value} max={props.max} class={state.class} style="box-shadow: 0 0.5em 1em -0.125em rgb(10 10 10 / 10%), 0 0 0 1px rgb(10 10 10 / 2%);"></progress> | ||||
| </div> | ||||
|  | ||||
| <script> | ||||
|     const DEFAULT_CLASSES = "progress is-small m-2 mt-auto mb-auto" | ||||
|     const COLOR_CLASSES = [ | ||||
|         "is-link", | ||||
|         "is-info", | ||||
|         "is-success", | ||||
|         "is-warning", | ||||
|         "is-danger" | ||||
|     ] | ||||
|  | ||||
|  | ||||
|     export default { | ||||
|         computeClasses() { | ||||
|             if (!this.props.value) return DEFAULT_CLASSES | ||||
|             let n = Math.floor(this.props.value / 20) | ||||
|             if (n == 5) n = 4 | ||||
|  | ||||
|             return DEFAULT_CLASSES + " " + COLOR_CLASSES[n] | ||||
|         }, | ||||
|  | ||||
|         calcPct() { | ||||
|             if (!this.props.value) { | ||||
|                 return "???" | ||||
|             } else { | ||||
|                 return Math.round(this.props.value / this.props.max * 100) + "%" | ||||
|             } | ||||
|         }, | ||||
|  | ||||
|         onMounted(props, state) { | ||||
|             this.update({ | ||||
|                 class: this.computeClasses() | ||||
|             }) | ||||
|         }, | ||||
|  | ||||
|         onBeforeUpdate(props, state) { | ||||
|             state.class = this.computeClasses() | ||||
|         } | ||||
|     } | ||||
| </script> | ||||
|  | ||||
| </title-progress> | ||||
							
								
								
									
										
											BIN
										
									
								
								favicon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								favicon.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 188 KiB | 
| @@ -1,11 +1,12 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
| 	<head> | ||||
| 		<title>Parcoursup</title> | ||||
| 		<title>Parcourplus | Accueil</title> | ||||
| 		<meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||||
| 		<link rel="stylesheet" href="style/parcoursup.css"> | ||||
| 		<script src="riot.min.js"></script> | ||||
| 		<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css"> | ||||
| 		<meta name="viewport" content="width=device-width, initial-scale=1"> | ||||
| 		<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" integrity="sha512-q3eWabyZPc1XTCmF+8/LuE1ozpg5xxn7iO89yfSOd5/oKvyqLngoNGsx8jq92Y8eXJ/IRxQbEC+FGSYxtk2oiw==" crossorigin="anonymous" referrerpolicy="no-referrer" /> | ||||
| 		<script src="loader.js" type="module"></script> | ||||
| 		<script src="https://cdnjs.cloudflare.com/ajax/libs/riot/7.1.0/riot+compiler.min.js" integrity="sha512-sSGKGR9MvL0bUx3CScaBb56crXwspwDkL/JnB0IrLFQfw3uvSUlITQtsTtDZctshhv5wdwIt+qZeN8zThRF4Dw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> | ||||
|   | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -3,7 +3,7 @@ var lineGraph = { | ||||
|   exports: { | ||||
|     updateCanvas() { | ||||
|       let canvas = this.$("canvas"); | ||||
|       if (!canvas) return; | ||||
|       if (!canvas || !this.props.data || !this.props.title) return; | ||||
|       canvas.width = canvas.clientWidth; | ||||
|       canvas.height = canvas.clientHeight; | ||||
|       let cx = canvas.getContext("2d"); | ||||
| @@ -12,8 +12,8 @@ var lineGraph = { | ||||
|       let width = canvas.width; | ||||
|       let height = canvas.height; | ||||
|       let spacing = 1; | ||||
|       let data = this.state.data; | ||||
|       let colors = ["#003F5C", "#2F4B7C", "#665191", "#A05195", "#D45087"]; | ||||
|       let data = this.props.data; | ||||
|       let colors = ["#003F5C", "#2F4B7C", "#665191", "#A05195", "#D45087", "#D47150"]; | ||||
|       cx.clearRect(0, 0, width, height); | ||||
|       cx.resetTransform(); | ||||
|       if (!data) return; | ||||
| @@ -27,39 +27,38 @@ var lineGraph = { | ||||
|       let counter = 0; | ||||
|       let legendWidth = 0; | ||||
|       for (let field of data) { | ||||
|         if (field.value == 0) continue; | ||||
|         let start = curr + spacing; | ||||
|         let barWidth = field.value / total * width - spacing * 2; | ||||
|         let text = `${Math.round(field.value / total * 1000) / 10}% (${field.name})`; | ||||
|         let text = `${Math.round(field.value / total * 1000) / 10}% (${field.short || field.name})`; | ||||
|         cx.fillStyle = colors[counter]; | ||||
|         cx.fillRect(start, 0, barWidth, height / 3); | ||||
|         cx.fillStyle = "#FFFFFF"; | ||||
|         if (cx.measureText(text).width < barWidth) { | ||||
|           cx.fillText(text, start + barWidth / 2, height / 6); | ||||
|         } else if (cx.measureText("...").width < barWidth) { | ||||
|           cx.fillText("...", start + barWidth / 2, height / 6); | ||||
|         } else if (cx.measureText(`${Math.round(field.value / total * 1000) / 10}%`).width < barWidth) { | ||||
|           cx.fillText(`${Math.round(field.value / total * 1000) / 10}%`, start + barWidth / 2, height / 6); | ||||
|         } | ||||
|         curr += field.value / total * width; | ||||
|         counter++; | ||||
|         legendWidth += cx.measureText(field.name).width + 25 + 15; // += textWidth + squareWidth + margin | ||||
|         let legendText = field.name + (field.short ? ` (${field.short})` : ""); | ||||
|         legendWidth += cx.measureText(legendText).width + 25 + 15; | ||||
|       } | ||||
|  | ||||
|       cx.textAlign = "left"; | ||||
|       legendWidth -= 15; //On enlève la dernière marge | ||||
|       cx.translate(width / 2 - legendWidth / 2, height / 4 + 20); | ||||
|       counter = 0; | ||||
|       for (let field of data) { | ||||
|         if (field.value == 0) continue; | ||||
|         cx.fillStyle = colors[counter]; | ||||
|         cx.fillRect(0, 0, 25, 25); | ||||
|         cx.fillStyle = "#707070"; | ||||
|         cx.fillText(field.name, 30, 12.5); | ||||
|         cx.translate(cx.measureText(field.name).width + 25 + 15, 0); | ||||
|         let legendText = field.name + (field.short ? ` (${field.short})` : ""); | ||||
|         cx.fillText(legendText, 30, 12.5); | ||||
|         cx.translate(cx.measureText(legendText).width + 25 + 15, 0); | ||||
|         counter++; | ||||
|       } | ||||
|     }, | ||||
|     state: { | ||||
|       data: [], | ||||
|       title: "Example" | ||||
|     }, | ||||
|     onMounted() { | ||||
|       let canvas = this.$("canvas"); | ||||
|       this.updateCanvas(); | ||||
|   | ||||
| @@ -1,23 +1,134 @@ | ||||
| /* | ||||
|     Parcoursup API (PAPI) | ||||
|     Comprend un set de wrapper afin d'accéder plus aisément aux informations de l'API parcoursup | ||||
| */ | ||||
|  | ||||
| class PAPI { | ||||
|   static dataset = "fr-esr-parcoursup"; | ||||
|   static timezone = "Europe%2FBerlin"; | ||||
|   static searchURL = `https://data.enseignementsup-recherche.gouv.fr/api/records/1.0/search/?dataset=${PAPI.dataset}&timezone=${PAPI.timezone}`; | ||||
|   static async fetchFilieres() { | ||||
|     if (localStorage.getItem("filis")) return JSON.parse(localStorage.getItem("filis")); | ||||
|     let request = await fetch(`${PAPI.searchURL}&rows=0&sort=tri&facet=fili`); | ||||
|     let result = await request.json(); | ||||
|     let response = result["facet_groups"][0]["facets"]; | ||||
|     localStorage.setItem("filis", JSON.stringify(response)); | ||||
|     return response; | ||||
|   } | ||||
|   static async fetchFiliere(filiere) { | ||||
|     if (localStorage.getItem("fili." + filiere)) return JSON.parse(localStorage.getItem("fili." + filiere)); | ||||
|     let request = await fetch(`${PAPI.searchURL}&rows=0&sort=tri&facet=form_lib_voe_acc&refine.fili=${filiere}`); | ||||
|     let result = await request.json(); | ||||
|     let response = result["facet_groups"][0]["facets"]; | ||||
|     localStorage.setItem("fili." + filiere, JSON.stringify(response)); | ||||
|     return response; | ||||
|   } | ||||
|   static async fetchSpecialites(filiere, specialite) { | ||||
|     if (localStorage.getItem(`spe.${filiere}.${specialite}`)) return JSON.parse(localStorage.getItem(`spe.${filiere}.${specialite}`)); | ||||
|     let request = await fetch(`${PAPI.searchURL}&rows=0&sort=tri&facet=fil_lib_voe_acc&refine.form_lib_voe_acc=${specialite}&refine.fili=${filiere}`); | ||||
|     let result = await request.json(); | ||||
|     let response = result["facet_groups"][0]["facets"]; | ||||
|     localStorage.setItem(`spe.${filiere}.${specialite}`, JSON.stringify(response)); | ||||
|     return response; | ||||
|   } | ||||
|   static async fetchEtablissement(filiere, sousfiliere, soussousfiliere) { | ||||
|     if (localStorage.getItem(`eta.${filiere}.${sousfiliere}.${soussousfiliere}`)) return JSON.parse(localStorage.getItem(`eta.${filiere}.${sousfiliere}.${soussousfiliere}`)); | ||||
|     let request = await fetch(`${PAPI.searchURL}&rows=10000&refine.fil_lib_voe_acc=${soussousfiliere}&refine.form_lib_voe_acc=${sousfiliere}&refine.fili=${filiere}`); | ||||
|     let result = await request.json(); | ||||
|     let response = result["records"]; | ||||
|     localStorage.setItem(`eta.${filiere}.${sousfiliere}.${soussousfiliere}`, JSON.stringify(response)); | ||||
|     return response; | ||||
|   } | ||||
| } | ||||
|  | ||||
| const SORT_TABLE = [{ | ||||
|   name: "Nom", | ||||
|   id: "g_ea_lib_vx" | ||||
| }, { | ||||
|   name: "Ville", | ||||
|   id: "ville_etab" | ||||
| }, { | ||||
|   name: "Département", | ||||
|   id: "dep" | ||||
| }, { | ||||
|   name: "Moyenne", | ||||
|   id: "moyenne" | ||||
| }, { | ||||
|   name: "Sélectivité", | ||||
|   id: "taux_acces_ens" | ||||
| }]; | ||||
| var mainController = { | ||||
|   css: null, | ||||
|   exports: { | ||||
|     onBeforeMount(props, state) { | ||||
|       //Initial state | ||||
|       this.state = { | ||||
|         course: null, | ||||
|         updating: false, | ||||
|         shouldShowInfos: false | ||||
|       }; | ||||
|     sortList(sortBy) { | ||||
|       //Si la liste est déjà triée par la bonne catégorie, on l'inverse | ||||
|       if (sortBy == this.state.sortBy) { | ||||
|         this.state.schoolList.reverse(); | ||||
|       } | ||||
|       //Sinon on l'ordonne par la nouvelle catégorie (ascendant par défaut) | ||||
|       else { | ||||
|         this.state.sortBy = sortBy; | ||||
|         switch (sortBy) { | ||||
|           case SORT_TABLE[3].id: | ||||
|           case SORT_TABLE[4].id: | ||||
|             { | ||||
|               this.state.schoolList.sort((a, b) => { | ||||
|                 if (a.fields[sortBy] > b.fields[sortBy]) return 1;else return -1; | ||||
|               }); | ||||
|               break; | ||||
|             } | ||||
|           default: | ||||
|             { | ||||
|               this.state.schoolList.sort((a, b) => { | ||||
|                 return a.fields[sortBy].localeCompare(b.fields[sortBy]); | ||||
|               }); | ||||
|               break; | ||||
|             } | ||||
|         } | ||||
|       } | ||||
|       this.update({ | ||||
|         schoolList: this.state.schoolList | ||||
|       }); | ||||
|     }, | ||||
|     updateList(course) { | ||||
|       course = course || this.state.course; | ||||
|       PAPI.fetchEtablissement(course.fili, course.sousfili, course.soussousfili).then(response => { | ||||
|         response.forEach(etablissement => { | ||||
|           // calcul la moyenne | ||||
|           let pct_sansmention = etablissement.fields.pct_sansmention; | ||||
|           let pct_AB = etablissement.fields.pct_ab; | ||||
|           let pct_B = etablissement.fields.pct_b; | ||||
|           let pct_TB = etablissement.fields.pct_tb; | ||||
|           let pct_TBF = etablissement.fields.pct_tbf; | ||||
|  | ||||
|           // On prend la moyenne des moyennes comprises dans la mention | ||||
|           // Exemple : Assez bien est entre 12 et 14 donc 13. | ||||
|           etablissement.fields.moyenne = (pct_TBF * 19 + pct_TB * 17 + pct_B * 15 + pct_AB * 13 + pct_sansmention * 11) / 100; | ||||
|         }); | ||||
|         this.update({ | ||||
|           schoolList: response | ||||
|         }); | ||||
|       }); | ||||
|     }, | ||||
|     updateCourse(course) { | ||||
|       this.updateList(course); | ||||
|       this.update({ | ||||
|         course: course, | ||||
|         shouldShowInfos: course != null, | ||||
|         updating: !this.state.updating | ||||
|         sortFields: SORT_TABLE, | ||||
|         shouldShowInfos: course != null | ||||
|       }); | ||||
|     }, | ||||
|     onMounted(props, state) { | ||||
|       this.update({ | ||||
|         course: null, | ||||
|         sortBy: null, | ||||
|         schoolList: null, | ||||
|         sortFields: SORT_TABLE, | ||||
|         shouldShowInfos: false | ||||
|       }); | ||||
|     } | ||||
|   }, | ||||
|   template: (template, expressionTypes, bindingTypes, getComponent) => template('<div class="columns"><div class="column is-one-third"><div class="box p-3 m-2"><img class="mt-1 ml-5 mr-auto" style="margin: auto;" src="../resources/logo-parcoursup.svg"/></div><search expr125="expr125"></search></div><div class="column"><fili-info expr126="expr126"></fili-info><school expr127="expr127"></school></div></div><school-info expr128="expr128"></school-info>', [{ | ||||
|   template: (template, expressionTypes, bindingTypes, getComponent) => template('<div class="columns"><div class="column is-one-third"><div class="box p-3 m-2"><img class="mt-1 ml-5 mr-auto" style="margin: auto;" src="../resources/logo-parcoursup.svg"/></div><search expr0="expr0"></search></div><div class="column"><fili-info expr1="expr1"></fili-info><school expr2="expr2"></school></div></div><school-info expr3="expr3"></school-info>', [{ | ||||
|     type: bindingTypes.TAG, | ||||
|     getComponent: getComponent, | ||||
|     evaluate: _scope => 'search', | ||||
| @@ -27,14 +138,18 @@ var mainController = { | ||||
|       name: 'updateCourse', | ||||
|       evaluate: _scope => _scope.updateCourse | ||||
|     }], | ||||
|     redundantAttribute: 'expr125', | ||||
|     selector: '[expr125]' | ||||
|     redundantAttribute: 'expr0', | ||||
|     selector: '[expr0]' | ||||
|   }, { | ||||
|     type: bindingTypes.TAG, | ||||
|     getComponent: getComponent, | ||||
|     evaluate: _scope => 'fili-info', | ||||
|     slots: [], | ||||
|     attributes: [{ | ||||
|       type: expressionTypes.ATTRIBUTE, | ||||
|       name: 'schoolList', | ||||
|       evaluate: _scope => _scope.state.schoolList | ||||
|     }, { | ||||
|       type: expressionTypes.ATTRIBUTE, | ||||
|       name: 'course', | ||||
|       evaluate: _scope => _scope.state.course | ||||
| @@ -43,8 +158,8 @@ var mainController = { | ||||
|       name: 'shouldShowInfos', | ||||
|       evaluate: _scope => _scope.state.shouldShowInfos | ||||
|     }], | ||||
|     redundantAttribute: 'expr126', | ||||
|     selector: '[expr126]' | ||||
|     redundantAttribute: 'expr1', | ||||
|     selector: '[expr1]' | ||||
|   }, { | ||||
|     type: bindingTypes.TAG, | ||||
|     getComponent: getComponent, | ||||
| @@ -52,8 +167,16 @@ var mainController = { | ||||
|     slots: [], | ||||
|     attributes: [{ | ||||
|       type: expressionTypes.ATTRIBUTE, | ||||
|       name: 'parentUpdate', | ||||
|       evaluate: _scope => _scope.state.updating | ||||
|       name: 'sortList', | ||||
|       evaluate: _scope => _scope.sortList | ||||
|     }, { | ||||
|       type: expressionTypes.ATTRIBUTE, | ||||
|       name: 'schoolList', | ||||
|       evaluate: _scope => _scope.state.schoolList | ||||
|     }, { | ||||
|       type: expressionTypes.ATTRIBUTE, | ||||
|       name: 'sortFields', | ||||
|       evaluate: _scope => _scope.state.sortFields | ||||
|     }, { | ||||
|       type: expressionTypes.ATTRIBUTE, | ||||
|       name: 'course', | ||||
| @@ -63,16 +186,16 @@ var mainController = { | ||||
|       name: 'shouldShowInfos', | ||||
|       evaluate: _scope => _scope.state.shouldShowInfos | ||||
|     }], | ||||
|     redundantAttribute: 'expr127', | ||||
|     selector: '[expr127]' | ||||
|     redundantAttribute: 'expr2', | ||||
|     selector: '[expr2]' | ||||
|   }, { | ||||
|     type: bindingTypes.TAG, | ||||
|     getComponent: getComponent, | ||||
|     evaluate: _scope => 'school-info', | ||||
|     slots: [], | ||||
|     attributes: [], | ||||
|     redundantAttribute: 'expr128', | ||||
|     selector: '[expr128]' | ||||
|     redundantAttribute: 'expr3', | ||||
|     selector: '[expr3]' | ||||
|   }]), | ||||
|   name: 'main-controller' | ||||
| }; | ||||
|   | ||||
| @@ -35,15 +35,15 @@ class PAPI { | ||||
|         return response | ||||
|     } | ||||
|  | ||||
|     static async fetchSpecialites(specialite) { | ||||
|     static async fetchSpecialites(filiere, specialite) { | ||||
|  | ||||
|         if (localStorage.getItem("spe." + specialite)) return JSON.parse(localStorage.getItem("spe." + specialite)) | ||||
|         if (localStorage.getItem(`spe.${filiere}.${specialite}`)) return JSON.parse(localStorage.getItem(`spe.${filiere}.${specialite}`)) | ||||
|  | ||||
|         let request = await fetch(`${PAPI.searchURL}&rows=0&sort=tri&facet=fil_lib_voe_acc&refine.form_lib_voe_acc=${specialite}`) | ||||
|         let request = await fetch(`${PAPI.searchURL}&rows=0&sort=tri&facet=fil_lib_voe_acc&refine.form_lib_voe_acc=${specialite}&refine.fili=${filiere}`) | ||||
|         let result  = await request.json() | ||||
|         let response = result["facet_groups"][0]["facets"] | ||||
|  | ||||
|         localStorage.setItem("spe." + specialite, JSON.stringify(response)) | ||||
|         localStorage.setItem(`spe.${filiere}.${specialite}`, JSON.stringify(response)) | ||||
|  | ||||
|         return response | ||||
|     } | ||||
| @@ -52,7 +52,7 @@ class PAPI { | ||||
|  | ||||
|         if (localStorage.getItem(`eta.${filiere}.${sousfiliere}.${soussousfiliere}`)) return JSON.parse(localStorage.getItem(`eta.${filiere}.${sousfiliere}.${soussousfiliere}`)) | ||||
|  | ||||
|         let request = await fetch(`${PAPI.searchURL}&refine.fil_lib_voe_acc=${soussousfiliere}&refine.form_lib_voe_acc=${sousfiliere}&refine.fili=${filiere}`) | ||||
|         let request = await fetch(`${PAPI.searchURL}&rows=10000&refine.fil_lib_voe_acc=${soussousfiliere}&refine.form_lib_voe_acc=${sousfiliere}&refine.fili=${filiere}`) | ||||
|         let result  = await request.json() | ||||
|         let response = result["records"] | ||||
|  | ||||
|   | ||||
| @@ -10,14 +10,14 @@ var schoolInfo = { | ||||
|       this.update(); | ||||
|     } | ||||
|   }, | ||||
|   template: (template, expressionTypes, bindingTypes, getComponent) => template('<div expr10="expr10" style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; background: #000000DD;"></div>', [{ | ||||
|   template: (template, expressionTypes, bindingTypes, getComponent) => template('<div expr29="expr29" style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; background: #000000DD;"></div>', [{ | ||||
|     type: bindingTypes.IF, | ||||
|     evaluate: _scope => _scope.state.enabled, | ||||
|     redundantAttribute: 'expr10', | ||||
|     selector: '[expr10]', | ||||
|     template: template('<div style="position: absolute; top: 10%; left: 10%; width: 80%; height: 80%; background: #FFFFFF"><button expr11="expr11" class="delete is-medium">X</button><p><h2></h2></p><line-graph expr12="expr12" style="height: 90px; margin: 10px;"></line-graph></div>', [{ | ||||
|       redundantAttribute: 'expr11', | ||||
|       selector: '[expr11]', | ||||
|     redundantAttribute: 'expr29', | ||||
|     selector: '[expr29]', | ||||
|     template: template('<div style="position: absolute; top: 10%; left: 10%; width: 80%; height: 80%; background: #FFFFFF"><button expr30="expr30" class="delete is-medium">X</button><p><h2></h2></p><line-graph expr31="expr31" style="height: 90px; margin: 10px;"></line-graph></div>', [{ | ||||
|       redundantAttribute: 'expr30', | ||||
|       selector: '[expr30]', | ||||
|       expressions: [{ | ||||
|         type: expressionTypes.EVENT, | ||||
|         name: 'onclick', | ||||
| @@ -29,8 +29,8 @@ var schoolInfo = { | ||||
|       evaluate: _scope => 'line-graph', | ||||
|       slots: [], | ||||
|       attributes: [], | ||||
|       redundantAttribute: 'expr12', | ||||
|       selector: '[expr12]' | ||||
|       redundantAttribute: 'expr31', | ||||
|       selector: '[expr31]' | ||||
|     }]) | ||||
|   }]), | ||||
|   name: 'school-info' | ||||
|   | ||||
| @@ -1,150 +1,30 @@ | ||||
| /* | ||||
|     Parcoursup API (PAPI) | ||||
|     Comprend un set de wrapper afin d'accéder plus aisément aux informations de l'API parcoursup | ||||
| */ | ||||
|  | ||||
| class PAPI { | ||||
|   static dataset = "fr-esr-parcoursup"; | ||||
|   static timezone = "Europe%2FBerlin"; | ||||
|   static searchURL = `https://data.enseignementsup-recherche.gouv.fr/api/records/1.0/search/?dataset=${PAPI.dataset}&timezone=${PAPI.timezone}`; | ||||
|   static async fetchFilieres() { | ||||
|     if (localStorage.getItem("filis")) return JSON.parse(localStorage.getItem("filis")); | ||||
|     let request = await fetch(`${PAPI.searchURL}&rows=0&sort=tri&facet=fili`); | ||||
|     let result = await request.json(); | ||||
|     let response = result["facet_groups"][0]["facets"]; | ||||
|     localStorage.setItem("filis", JSON.stringify(response)); | ||||
|     return response; | ||||
|   } | ||||
|   static async fetchFiliere(filiere) { | ||||
|     if (localStorage.getItem("fili." + filiere)) return JSON.parse(localStorage.getItem("fili." + filiere)); | ||||
|     let request = await fetch(`${PAPI.searchURL}&rows=0&sort=tri&facet=form_lib_voe_acc&refine.fili=${filiere}`); | ||||
|     let result = await request.json(); | ||||
|     let response = result["facet_groups"][0]["facets"]; | ||||
|     localStorage.setItem("fili." + filiere, JSON.stringify(response)); | ||||
|     return response; | ||||
|   } | ||||
|   static async fetchSpecialites(specialite) { | ||||
|     if (localStorage.getItem("spe." + specialite)) return JSON.parse(localStorage.getItem("spe." + specialite)); | ||||
|     let request = await fetch(`${PAPI.searchURL}&rows=0&sort=tri&facet=fil_lib_voe_acc&refine.form_lib_voe_acc=${specialite}`); | ||||
|     let result = await request.json(); | ||||
|     let response = result["facet_groups"][0]["facets"]; | ||||
|     localStorage.setItem("spe." + specialite, JSON.stringify(response)); | ||||
|     return response; | ||||
|   } | ||||
|   static async fetchEtablissement(filiere, sousfiliere, soussousfiliere) { | ||||
|     if (localStorage.getItem(`eta.${filiere}.${sousfiliere}.${soussousfiliere}`)) return JSON.parse(localStorage.getItem(`eta.${filiere}.${sousfiliere}.${soussousfiliere}`)); | ||||
|     let request = await fetch(`${PAPI.searchURL}&refine.fil_lib_voe_acc=${soussousfiliere}&refine.form_lib_voe_acc=${sousfiliere}&refine.fili=${filiere}`); | ||||
|     let result = await request.json(); | ||||
|     let response = result["records"]; | ||||
|     localStorage.setItem(`eta.${filiere}.${sousfiliere}.${soussousfiliere}`, JSON.stringify(response)); | ||||
|     return response; | ||||
|   } | ||||
| } | ||||
|  | ||||
| async function fetchEtablissement(course) { | ||||
|   return PAPI.fetchEtablissement(course.fili, course.sousfili, course.soussousfili); | ||||
| } | ||||
| const SORT_TABLE = [{ | ||||
|   name: "Nom", | ||||
|   id: "g_ea_lib_vx" | ||||
| }, { | ||||
|   name: "Ville", | ||||
|   id: "ville_etab" | ||||
| }, { | ||||
|   name: "Département", | ||||
|   id: "dep" | ||||
| }, { | ||||
|   name: "Moyenne", | ||||
|   id: "moyenne" | ||||
| }, { | ||||
|   name: "Sélectivité", | ||||
|   id: "taux_acces_ens" | ||||
| }]; | ||||
| var school = { | ||||
|   css: null, | ||||
|   exports: function search() { | ||||
|     return { | ||||
|       updateList() { | ||||
|         fetchEtablissement(this.props.course).then(response => { | ||||
|           response.forEach(etablissement => { | ||||
|             // calcul la moyenne | ||||
|             let pct_sansmention = etablissement.fields.pct_sansmention; | ||||
|             let pct_AB = etablissement.fields.pct_ab; | ||||
|             let pct_B = etablissement.fields.pct_b; | ||||
|             let pct_TB = etablissement.fields.pct_tb; | ||||
|             let pct_TBF = etablissement.fields.pct_tbf; | ||||
|  | ||||
|             // On prend la moyenne des moyennes comprises dans la mention | ||||
|             // Exemple : Assez bien est entre 12 et 14 donc 13. | ||||
|             etablissement.fields.moyenne = (pct_TBF * 19 + pct_TB * 17 + pct_B * 15 + pct_AB * 13 + pct_sansmention * 11) / 100; | ||||
|           }); | ||||
|           this.update({ | ||||
|             items: response, | ||||
|             parentUpdate: this.props.parentUpdate | ||||
|           }); | ||||
|         }); | ||||
|       }, | ||||
|       sortList(sortBy) { | ||||
|         //Si la liste est déjà triée par la bonne catégorie, on l'inverse | ||||
|         if (sortBy == this.state.sortBy) { | ||||
|           this.state.items.reverse(); | ||||
|         } | ||||
|         //Sinon on l'ordonne par la nouvelle catégorie (ascendant par défaut) | ||||
|         else { | ||||
|           this.state.sortBy = sortBy; | ||||
|           switch (sortBy) { | ||||
|             case SORT_TABLE[3].id: | ||||
|             case SORT_TABLE[4].id: | ||||
|               { | ||||
|                 this.state.items.sort((a, b) => { | ||||
|                   if (a.fields[sortBy] > b.fields[sortBy]) return 1;else return -1; | ||||
|                 }); | ||||
|                 break; | ||||
|               } | ||||
|             default: | ||||
|               { | ||||
|                 this.state.items.sort((a, b) => { | ||||
|                   return a.fields[sortBy].localeCompare(b.fields[sortBy]); | ||||
|                 }); | ||||
|                 break; | ||||
|               } | ||||
|           } | ||||
|         } | ||||
|         this.update({ | ||||
|           items: this.state.items | ||||
|         }); | ||||
|       }, | ||||
|       onBeforeMount(props, state) { | ||||
|       }, | ||||
|       onMounted(props, state) { | ||||
|         this.update({ | ||||
|           sortFields: SORT_TABLE | ||||
|         }); | ||||
|       }, | ||||
|       onUpdated(props, state) { | ||||
|         if (!props.shouldShowInfos || state.parentUpdate == props.parentUpdate) return; | ||||
|         this.updateList(); | ||||
|       } | ||||
|     }; | ||||
|   }, | ||||
|   template: (template, expressionTypes, bindingTypes, getComponent) => template('<div expr336="expr336" class="box p-2 m-2"></div>', [{ | ||||
|   exports: null, | ||||
|   template: (template, expressionTypes, bindingTypes, getComponent) => template('<div expr345="expr345" class="box p-2 m-2" disabled></div>', [{ | ||||
|     type: bindingTypes.IF, | ||||
|     evaluate: _scope => _scope.props.shouldShowInfos, | ||||
|     redundantAttribute: 'expr336', | ||||
|     selector: '[expr336]', | ||||
|     template: template('<iframe width="100%" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://www.openstreetmap.org/export/embed.html?bbox=-14.655761718750002%2C40.56389453066509%2C13.601074218750002%2C51.754240074033525&layer=mapnik" style="border-radius: 5px;"></iframe><br/><div class="block control has-icons-left is-inline-block is-pulled-right"><input class="input" type="search" placeholder="Établissement"/><span class="icon is-small is-left"><i class="fas fa-search"></i></span></div><table class="table is-fullwidth is-hoverable"><thead><tr><th expr337="expr337"></th></tr></thead><tbody><tr expr339="expr339"></tr></tbody></table>', [{ | ||||
|     redundantAttribute: 'expr345', | ||||
|     selector: '[expr345]', | ||||
|     template: template('<iframe expr346="expr346" width="100%" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://www.openstreetmap.org/export/embed.html?bbox=-14.655761718750002%2C40.56389453066509%2C13.601074218750002%2C51.754240074033525&layer=mapnik" style="border-radius: 5px;"></iframe><br/><div class="block control has-icons-left is-inline-block is-pulled-right"><input class="input" type="search" placeholder="Établissement"/><span class="icon is-small is-left"><i class="fas fa-search"></i></span></div><table class="table is-fullwidth is-hoverable"><thead><tr><th expr347="expr347"></th></tr></thead><tbody><tr expr349="expr349"></tr></tbody></table>', [{ | ||||
|       type: bindingTypes.IF, | ||||
|       evaluate: _scope => false, | ||||
|       redundantAttribute: 'expr346', | ||||
|       selector: '[expr346]', | ||||
|       template: template(null, []) | ||||
|     }, { | ||||
|       type: bindingTypes.EACH, | ||||
|       getKey: null, | ||||
|       condition: null, | ||||
|       template: template(' <a expr338="expr338"><span class="icon"><i class="fas fa-sort"></i></span></a>', [{ | ||||
|       template: template(' <a expr348="expr348"><span class="icon"><i class="fas fa-sort"></i></span></a>', [{ | ||||
|         expressions: [{ | ||||
|           type: expressionTypes.TEXT, | ||||
|           childNodeIndex: 0, | ||||
|           evaluate: _scope => [_scope.sortField.name].join('') | ||||
|         }] | ||||
|       }, { | ||||
|         redundantAttribute: 'expr338', | ||||
|         selector: '[expr338]', | ||||
|         redundantAttribute: 'expr348', | ||||
|         selector: '[expr348]', | ||||
|         expressions: [{ | ||||
|           type: expressionTypes.ATTRIBUTE, | ||||
|           name: 'id', | ||||
| @@ -152,64 +32,68 @@ var school = { | ||||
|         }, { | ||||
|           type: expressionTypes.EVENT, | ||||
|           name: 'onclick', | ||||
|           evaluate: _scope => () => _scope.sortList(_scope.sortField.id) | ||||
|           evaluate: _scope => () => _scope.props.sortList(_scope.sortField.id) | ||||
|         }] | ||||
|       }]), | ||||
|       redundantAttribute: 'expr337', | ||||
|       selector: '[expr337]', | ||||
|       redundantAttribute: 'expr347', | ||||
|       selector: '[expr347]', | ||||
|       itemName: 'sortField', | ||||
|       indexName: null, | ||||
|       evaluate: _scope => _scope.state.sortFields | ||||
|       evaluate: _scope => _scope.props.sortFields | ||||
|     }, { | ||||
|       type: bindingTypes.EACH, | ||||
|       getKey: null, | ||||
|       condition: null, | ||||
|       template: template('<td expr340="expr340"> </td><td expr341="expr341"> </td><td expr342="expr342"> </td><td expr343="expr343"> </td><td expr344="expr344"> </td>', [{ | ||||
|         redundantAttribute: 'expr340', | ||||
|         selector: '[expr340]', | ||||
|       template: template('<td expr350="expr350"> </td><td expr351="expr351"> </td><td expr352="expr352"> </td><td expr353="expr353"> </td><td><title-progress expr354="expr354" max="100" style="margin: auto"></title-progress></td>', [{ | ||||
|         redundantAttribute: 'expr350', | ||||
|         selector: '[expr350]', | ||||
|         expressions: [{ | ||||
|           type: expressionTypes.TEXT, | ||||
|           childNodeIndex: 0, | ||||
|           evaluate: _scope => _scope.etablissement.fields.g_ea_lib_vx | ||||
|           evaluate: _scope => _scope.school.fields.g_ea_lib_vx | ||||
|         }] | ||||
|       }, { | ||||
|         redundantAttribute: 'expr341', | ||||
|         selector: '[expr341]', | ||||
|         redundantAttribute: 'expr351', | ||||
|         selector: '[expr351]', | ||||
|         expressions: [{ | ||||
|           type: expressionTypes.TEXT, | ||||
|           childNodeIndex: 0, | ||||
|           evaluate: _scope => _scope.etablissement.fields.ville_etab | ||||
|           evaluate: _scope => _scope.school.fields.ville_etab | ||||
|         }] | ||||
|       }, { | ||||
|         redundantAttribute: 'expr342', | ||||
|         selector: '[expr342]', | ||||
|         redundantAttribute: 'expr352', | ||||
|         selector: '[expr352]', | ||||
|         expressions: [{ | ||||
|           type: expressionTypes.TEXT, | ||||
|           childNodeIndex: 0, | ||||
|           evaluate: _scope => _scope.etablissement.fields.dep | ||||
|           evaluate: _scope => _scope.school.fields.dep | ||||
|         }] | ||||
|       }, { | ||||
|         redundantAttribute: 'expr343', | ||||
|         selector: '[expr343]', | ||||
|         redundantAttribute: 'expr353', | ||||
|         selector: '[expr353]', | ||||
|         expressions: [{ | ||||
|           type: expressionTypes.TEXT, | ||||
|           childNodeIndex: 0, | ||||
|           evaluate: _scope => _scope.etablissement.fields.moyenne | ||||
|           evaluate: _scope => _scope.school.fields.moyenne | ||||
|         }] | ||||
|       }, { | ||||
|         redundantAttribute: 'expr344', | ||||
|         selector: '[expr344]', | ||||
|         expressions: [{ | ||||
|           type: expressionTypes.TEXT, | ||||
|           childNodeIndex: 0, | ||||
|           evaluate: _scope => _scope.etablissement.fields.taux_acces_ens | ||||
|         }] | ||||
|         type: bindingTypes.TAG, | ||||
|         getComponent: getComponent, | ||||
|         evaluate: _scope => 'title-progress', | ||||
|         slots: [], | ||||
|         attributes: [{ | ||||
|           type: expressionTypes.ATTRIBUTE, | ||||
|           name: 'value', | ||||
|           evaluate: _scope => _scope.school.fields.taux_acces_ens | ||||
|         }], | ||||
|         redundantAttribute: 'expr354', | ||||
|         selector: '[expr354]' | ||||
|       }]), | ||||
|       redundantAttribute: 'expr339', | ||||
|       selector: '[expr339]', | ||||
|       itemName: 'etablissement', | ||||
|       redundantAttribute: 'expr349', | ||||
|       selector: '[expr349]', | ||||
|       itemName: 'school', | ||||
|       indexName: null, | ||||
|       evaluate: _scope => _scope.state.items | ||||
|       evaluate: _scope => _scope.props.schoolList | ||||
|     }]) | ||||
|   }]), | ||||
|   name: 'school' | ||||
|   | ||||
| @@ -23,17 +23,17 @@ class PAPI { | ||||
|     localStorage.setItem("fili." + filiere, JSON.stringify(response)); | ||||
|     return response; | ||||
|   } | ||||
|   static async fetchSpecialites(specialite) { | ||||
|     if (localStorage.getItem("spe." + specialite)) return JSON.parse(localStorage.getItem("spe." + specialite)); | ||||
|     let request = await fetch(`${PAPI.searchURL}&rows=0&sort=tri&facet=fil_lib_voe_acc&refine.form_lib_voe_acc=${specialite}`); | ||||
|   static async fetchSpecialites(filiere, specialite) { | ||||
|     if (localStorage.getItem(`spe.${filiere}.${specialite}`)) return JSON.parse(localStorage.getItem(`spe.${filiere}.${specialite}`)); | ||||
|     let request = await fetch(`${PAPI.searchURL}&rows=0&sort=tri&facet=fil_lib_voe_acc&refine.form_lib_voe_acc=${specialite}&refine.fili=${filiere}`); | ||||
|     let result = await request.json(); | ||||
|     let response = result["facet_groups"][0]["facets"]; | ||||
|     localStorage.setItem("spe." + specialite, JSON.stringify(response)); | ||||
|     localStorage.setItem(`spe.${filiere}.${specialite}`, JSON.stringify(response)); | ||||
|     return response; | ||||
|   } | ||||
|   static async fetchEtablissement(filiere, sousfiliere, soussousfiliere) { | ||||
|     if (localStorage.getItem(`eta.${filiere}.${sousfiliere}.${soussousfiliere}`)) return JSON.parse(localStorage.getItem(`eta.${filiere}.${sousfiliere}.${soussousfiliere}`)); | ||||
|     let request = await fetch(`${PAPI.searchURL}&refine.fil_lib_voe_acc=${soussousfiliere}&refine.form_lib_voe_acc=${sousfiliere}&refine.fili=${filiere}`); | ||||
|     let request = await fetch(`${PAPI.searchURL}&rows=10000&refine.fil_lib_voe_acc=${soussousfiliere}&refine.form_lib_voe_acc=${sousfiliere}&refine.fili=${filiere}`); | ||||
|     let result = await request.json(); | ||||
|     let response = result["records"]; | ||||
|     localStorage.setItem(`eta.${filiere}.${sousfiliere}.${soussousfiliere}`, JSON.stringify(response)); | ||||
| @@ -55,7 +55,7 @@ var search = { | ||||
|           promise = PAPI.fetchFiliere(this.state.course.fili); | ||||
|           break; | ||||
|         case 2: | ||||
|           promise = PAPI.fetchSpecialites(this.state.course.sousfili); | ||||
|           promise = PAPI.fetchSpecialites(this.state.course.fili, this.state.course.sousfili); | ||||
|           break; | ||||
|         default: | ||||
|           return; | ||||
| @@ -144,9 +144,9 @@ var search = { | ||||
|       this.updateList(); | ||||
|     } | ||||
|   }, | ||||
|   template: (template, expressionTypes, bindingTypes, getComponent) => template('<div class="box p-1 m-2"><div class="columns m-1"><input expr27="expr27" class="input" type="input"/><button expr28="expr28" class="button ml-1"><</button></div><div id="list-formations"><ul><li expr29="expr29" class="m-1"></li></ul></div></div>', [{ | ||||
|     redundantAttribute: 'expr27', | ||||
|     selector: '[expr27]', | ||||
|   template: (template, expressionTypes, bindingTypes, getComponent) => template('<div class="box p-1 m-2"><div class="columns m-1"><input expr23="expr23" class="input" type="input"/><button expr24="expr24" class="button ml-1"><</button></div><div id="list-formations"><ul><li expr25="expr25" class="m-1"></li></ul></div></div>', [{ | ||||
|     redundantAttribute: 'expr23', | ||||
|     selector: '[expr23]', | ||||
|     expressions: [{ | ||||
|       type: expressionTypes.EVENT, | ||||
|       name: 'onkeyup', | ||||
| @@ -157,8 +157,8 @@ var search = { | ||||
|       evaluate: _scope => _scope.state.placeholder | ||||
|     }] | ||||
|   }, { | ||||
|     redundantAttribute: 'expr28', | ||||
|     selector: '[expr28]', | ||||
|     redundantAttribute: 'expr24', | ||||
|     selector: '[expr24]', | ||||
|     expressions: [{ | ||||
|       type: expressionTypes.ATTRIBUTE, | ||||
|       name: 'disabled', | ||||
| @@ -172,9 +172,9 @@ var search = { | ||||
|     type: bindingTypes.EACH, | ||||
|     getKey: null, | ||||
|     condition: null, | ||||
|     template: template('<button expr30="expr30" class="button is-fullwidth p-2"><span style="font-size: .75em; max-size: 90%"><strong expr31="expr31"> </strong></span><div style="margin-left: auto;"></div><span expr32="expr32" class="tag is-primary"> </span></button>', [{ | ||||
|       redundantAttribute: 'expr30', | ||||
|       selector: '[expr30]', | ||||
|     template: template('<button expr26="expr26" class="button is-fullwidth p-2"><span style="font-size: .75em; max-size: 90%"><strong expr27="expr27"> </strong></span><div style="margin-left: auto;"></div><span expr28="expr28" class="tag is-primary"> </span></button>', [{ | ||||
|       redundantAttribute: 'expr26', | ||||
|       selector: '[expr26]', | ||||
|       expressions: [{ | ||||
|         type: expressionTypes.ATTRIBUTE, | ||||
|         name: 'disabled', | ||||
| @@ -185,24 +185,24 @@ var search = { | ||||
|         evaluate: _scope => () => _scope.cruiseForward(_scope.item.name) | ||||
|       }] | ||||
|     }, { | ||||
|       redundantAttribute: 'expr31', | ||||
|       selector: '[expr31]', | ||||
|       redundantAttribute: 'expr27', | ||||
|       selector: '[expr27]', | ||||
|       expressions: [{ | ||||
|         type: expressionTypes.TEXT, | ||||
|         childNodeIndex: 0, | ||||
|         evaluate: _scope => _scope.item.name | ||||
|       }] | ||||
|     }, { | ||||
|       redundantAttribute: 'expr32', | ||||
|       selector: '[expr32]', | ||||
|       redundantAttribute: 'expr28', | ||||
|       selector: '[expr28]', | ||||
|       expressions: [{ | ||||
|         type: expressionTypes.TEXT, | ||||
|         childNodeIndex: 0, | ||||
|         evaluate: _scope => _scope.item.count | ||||
|       }] | ||||
|     }]), | ||||
|     redundantAttribute: 'expr29', | ||||
|     selector: '[expr29]', | ||||
|     redundantAttribute: 'expr25', | ||||
|     selector: '[expr25]', | ||||
|     itemName: 'item', | ||||
|     indexName: null, | ||||
|     evaluate: _scope => _scope.state.items | ||||
|   | ||||
							
								
								
									
										68
									
								
								javascript/title-progress.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								javascript/title-progress.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| const DEFAULT_CLASSES = "progress is-small m-2 mt-auto mb-auto"; | ||||
| const COLOR_CLASSES = ["is-link", "is-info", "is-success", "is-warning", "is-danger"]; | ||||
| var titleProgress = { | ||||
|   css: null, | ||||
|   exports: { | ||||
|     computeClasses() { | ||||
|       if (!this.props.value) return DEFAULT_CLASSES; | ||||
|       let n = Math.floor(this.props.value / 20); | ||||
|       if (n == 5) n = 4; | ||||
|       return DEFAULT_CLASSES + " " + COLOR_CLASSES[n]; | ||||
|     }, | ||||
|     calcPct() { | ||||
|       if (!this.props.value) { | ||||
|         return "???"; | ||||
|       } else { | ||||
|         return Math.round(this.props.value / this.props.max * 100) + "%"; | ||||
|       } | ||||
|     }, | ||||
|     onMounted(props, state) { | ||||
|       this.update({ | ||||
|         class: this.computeClasses() | ||||
|       }); | ||||
|     }, | ||||
|     onBeforeUpdate(props, state) { | ||||
|       state.class = this.computeClasses(); | ||||
|     } | ||||
|   }, | ||||
|   template: (template, expressionTypes, bindingTypes, getComponent) => template('<div style="display: flex;"><span expr493="expr493"></span><span expr494="expr494" class="ml-1"> </span><progress expr495="expr495" style="box-shadow: 0 0.5em 1em -0.125em rgb(10 10 10 / 10%), 0 0 0 1px rgb(10 10 10 / 2%);"></progress></div>', [{ | ||||
|     type: bindingTypes.IF, | ||||
|     evaluate: _scope => _scope.props.title, | ||||
|     redundantAttribute: 'expr493', | ||||
|     selector: '[expr493]', | ||||
|     template: template(' ', [{ | ||||
|       expressions: [{ | ||||
|         type: expressionTypes.TEXT, | ||||
|         childNodeIndex: 0, | ||||
|         evaluate: _scope => _scope.props.title | ||||
|       }] | ||||
|     }]) | ||||
|   }, { | ||||
|     redundantAttribute: 'expr494', | ||||
|     selector: '[expr494]', | ||||
|     expressions: [{ | ||||
|       type: expressionTypes.TEXT, | ||||
|       childNodeIndex: 0, | ||||
|       evaluate: _scope => _scope.calcPct() | ||||
|     }] | ||||
|   }, { | ||||
|     redundantAttribute: 'expr495', | ||||
|     selector: '[expr495]', | ||||
|     expressions: [{ | ||||
|       type: expressionTypes.ATTRIBUTE, | ||||
|       name: 'value', | ||||
|       evaluate: _scope => _scope.props.value | ||||
|     }, { | ||||
|       type: expressionTypes.ATTRIBUTE, | ||||
|       name: 'max', | ||||
|       evaluate: _scope => _scope.props.max | ||||
|     }, { | ||||
|       type: expressionTypes.ATTRIBUTE, | ||||
|       name: 'class', | ||||
|       evaluate: _scope => _scope.state.class | ||||
|     }] | ||||
|   }]), | ||||
|   name: 'title-progress' | ||||
| }; | ||||
|  | ||||
| export { titleProgress as default }; | ||||
| @@ -3,6 +3,7 @@ | ||||
| */ | ||||
|  | ||||
| import MainController from './javascript/main-controller.js' | ||||
| import TitleProgress from './javascript/title-progress.js' | ||||
| import SchoolInfo from './javascript/school-info.js' | ||||
| import LineGraph from './javascript/line-graph.js' | ||||
| import FiliInfo from './javascript/fili-info.js' | ||||
| @@ -10,6 +11,7 @@ import Search from './javascript/search.js' | ||||
| import School from './javascript/school.js' | ||||
|  | ||||
| riot.register("main-controller", MainController) | ||||
| riot.register("title-progress", TitleProgress) | ||||
| riot.register("school-info", SchoolInfo) | ||||
| riot.register("line-graph", LineGraph) | ||||
| riot.register("fili-info", FiliInfo) | ||||
| @@ -17,6 +19,7 @@ riot.register("search", Search) | ||||
| riot.register("school", School) | ||||
|  | ||||
|  | ||||
| riot.mount("title-progress") | ||||
| riot.mount("line-graph") | ||||
| riot.mount("search") | ||||
| riot.mount("school-info") | ||||
|   | ||||
| @@ -6,11 +6,11 @@ | ||||
|    id="Calque_1" | ||||
|    x="0px" | ||||
|    y="0px" | ||||
|    viewBox="0 0 360.50001 58.400003" | ||||
|    viewBox="0 0 409.00221 69.400003" | ||||
|    xml:space="preserve" | ||||
|    sodipodi:docname="logo-parcoursup.svg" | ||||
|    width="360.5" | ||||
|    height="58.400002" | ||||
|    width="409.0022" | ||||
|    height="69.400002" | ||||
|    inkscape:version="1.2.2 (732a01da63, 2022-12-09)" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
| @@ -26,13 +26,13 @@ | ||||
|    inkscape:pagecheckerboard="0" | ||||
|    inkscape:deskcolor="#d1d1d1" | ||||
|    showgrid="false" | ||||
|    inkscape:zoom="3.8800706" | ||||
|    inkscape:cx="177.83182" | ||||
|    inkscape:cy="71.519317" | ||||
|    inkscape:zoom="2.7436242" | ||||
|    inkscape:cx="225.61399" | ||||
|    inkscape:cy="45.195694" | ||||
|    inkscape:window-width="1920" | ||||
|    inkscape:window-height="1051" | ||||
|    inkscape:window-x="-9" | ||||
|    inkscape:window-y="-9" | ||||
|    inkscape:window-height="1057" | ||||
|    inkscape:window-x="1912" | ||||
|    inkscape:window-y="-5" | ||||
|    inkscape:window-maximized="1" | ||||
|    inkscape:current-layer="Calque_1" /> | ||||
| <style | ||||
| @@ -43,180 +43,55 @@ | ||||
| </style> | ||||
| <path | ||||
|    class="st0" | ||||
|    d="M 70.7,33.3 C 68.9,35.1 66,36.2 62.8,36.2 59.5,36.2 57.1,35.3 55,33 V 47.7 H 46.9 V 3.4999995 h 7.8 v 3 c 2.2,-2.5 4.7,-3.4 8.1,-3.4 3.2,0 6.1,1.1 7.9,2.9 C 73.9,9.2 74,14.8 74,19.6 74,24.5 73.9,30.1 70.7,33.3 Z M 60.4,10.4 c -4.8,0 -5.5,4 -5.5,9.3 0,5.3 0.6,9.3 5.5,9.3 4.9,0 5.5,-4 5.5,-9.3 0,-5.3 -0.6,-9.3 -5.5,-9.3 z" | ||||
|    d="m 70.7,46.9 c -1.8,1.8 -4.7,2.9 -7.9,2.9 -3.3,0 -5.7,-0.9 -7.8,-3.2 V 61.3 H 46.9 V 17.1 h 7.8 v 3 c 2.2,-2.5 4.7,-3.400001 8.1,-3.400001 3.2,0 6.1,1.100001 7.9,2.900001 3.2,3.2 3.3,8.8 3.3,13.6 0,4.9 -0.1,10.5 -3.3,13.7 z M 60.4,24 c -4.8,0 -5.5,4 -5.5,9.3 0,5.3 0.6,9.3 5.5,9.3 4.9,0 5.5,-4 5.5,-9.3 C 65.9,28 65.3,24 60.4,24 Z" | ||||
|    id="path4" /> | ||||
| <path | ||||
|    class="st0" | ||||
|    d="M 98.2,35.8 V 33 C 96,35.2 94,36.1 90.3,36.1 86.6,36.1 84,35.2 82,33.2 80.3,31.5 79.4,28.9 79.4,26 c 0,-5.2 3.5,-9.4 11.1,-9.4 h 7.6 V 15 c 0,-3.5 -1.7,-5.1 -6,-5.1 -3.1,0 -4.5,0.7 -6.2,2.7 L 80.7,7.5999995 c 3.2,-3.5 6.3,-4.5 11.7,-4.5 9.1,0 13.8,3.8 13.8,11.4000005 V 35.8 Z M 98,22.2 h -6.4 c -2.9,0 -4.5,1.4 -4.5,3.7 0,2.2 1.5,3.7 4.7,3.7 2.2,0 3.7,-0.2 5.1,-1.6 0.9,-0.8 1.2,-2.1 1.2,-4.1 v -1.7 z" | ||||
|    d="m 98.2,49.4 v -2.8 c -2.2,2.2 -4.2,3.1 -7.9,3.1 -3.7,0 -6.3,-0.9 -8.3,-2.9 -1.7,-1.7 -2.6,-4.3 -2.6,-7.2 0,-5.2 3.5,-9.4 11.1,-9.4 h 7.6 v -1.6 c 0,-3.5 -1.7,-5.1 -6,-5.1 -3.1,0 -4.5,0.7 -6.2,2.7 l -5.2,-5.000001 c 3.2,-3.5 6.3,-4.5 11.7,-4.5 9.1,0 13.8,3.800001 13.8,11.400001 V 49.4 Z M 98,35.8 h -6.4 c -2.9,0 -4.5,1.4 -4.5,3.7 0,2.2 1.5,3.7 4.7,3.7 2.2,0 3.7,-0.2 5.1,-1.6 0.9,-0.8 1.2,-2.1 1.2,-4.1 v -1.7 z" | ||||
|    id="path6" /> | ||||
| <path | ||||
|    class="st0" | ||||
|    d="m 132.4,12.3 c -1.2,-1.2 -2.3,-1.9 -4.3,-1.9 -2.5,0 -5.2,1.9 -5.2,6 v 19.5 h -8.1 V 3.4999995 h 7.9 v 3.1 c 1.6,-1.9 4.7,-3.5 8.1,-3.5 3.2,0 5.4,0.8 7.6,3 z" | ||||
|    d="m 132.4,25.9 c -1.2,-1.2 -2.3,-1.9 -4.3,-1.9 -2.5,0 -5.2,1.9 -5.2,6 v 19.5 h -8.1 V 17.1 h 7.9 v 3.099999 c 1.6,-1.899999 4.7,-3.5 8.1,-3.5 3.2,0 5.4,0.800001 7.6,3 z" | ||||
|    id="path8" /> | ||||
| <path | ||||
|    class="st0" | ||||
|    d="m 154,36.2 c -6.5,0 -14.5,-3.5 -14.5,-16.6 0,-13.1000005 8,-16.5000005 14.5,-16.5000005 4.5,0 7.8,1.4 10.7,4.3 L 159.2,12.9 c -1.7,-1.8 -3.1,-2.5 -5.2,-2.5 -1.9,0 -3.4,0.7 -4.6,2.1 -1.2,1.6 -1.8,3.7 -1.8,7.1 0,3.4 0.6,5.7 1.8,7.2 1.2,1.4 2.7,2.1 4.6,2.1 2.1,0 3.5,-0.7 5.2,-2.5 l 5.5,5.4 c -2.9,3 -6.2,4.4 -10.7,4.4 z" | ||||
|    d="m 154,49.8 c -6.5,0 -14.5,-3.5 -14.5,-16.6 0,-13.1 8,-16.5 14.5,-16.5 4.5,0 7.8,1.4 10.7,4.3 l -5.5,5.5 C 157.5,24.7 156.1,24 154,24 c -1.9,0 -3.4,0.7 -4.6,2.1 -1.2,1.6 -1.8,3.7 -1.8,7.1 0,3.4 0.6,5.7 1.8,7.2 1.2,1.4 2.7,2.1 4.6,2.1 2.1,0 3.5,-0.7 5.2,-2.5 l 5.5,5.4 c -2.9,3 -6.2,4.4 -10.7,4.4 z" | ||||
|    id="path10" /> | ||||
| <path | ||||
|    class="st0" | ||||
|    d="m 192.2,32.2 c -2,2.1 -5.3,4 -10.1,4 -4.8,0 -8,-1.9 -10,-4 -2.9,-3 -3.7,-6.7 -3.7,-12.6 0,-5.8 0.7,-9.5 3.7,-12.5000005 2,-2.1 5.2,-4 10,-4 4.8,0 8.1,1.9 10.1,4 C 195.1,10.1 195.9,13.8 195.9,19.6 c -0.1,5.9 -0.8,9.6 -3.7,12.6 z m -6.3,-20.4 c -0.9,-0.9 -2.2,-1.4 -3.8,-1.4 -1.6,0 -2.8,0.5 -3.7,1.4 -1.7,1.7 -1.9,4.5 -1.9,7.8 0,3.4 0.2,6.2 1.9,7.9 0.9,0.9 2.1,1.4 3.7,1.4 1.6,0 2.9,-0.5 3.8,-1.4 1.7,-1.7 1.9,-4.5 1.9,-7.9 0,-3.3 -0.2,-6.1 -1.9,-7.8 z" | ||||
|    d="m 192.2,45.8 c -2,2.1 -5.3,4 -10.1,4 -4.8,0 -8,-1.9 -10,-4 -2.9,-3 -3.7,-6.7 -3.7,-12.6 0,-5.8 0.7,-9.5 3.7,-12.5 2,-2.1 5.2,-4 10,-4 4.8,0 8.1,1.9 10.1,4 2.9,3 3.7,6.7 3.7,12.5 -0.1,5.9 -0.8,9.6 -3.7,12.6 z M 185.9,25.4 C 185,24.5 183.7,24 182.1,24 c -1.6,0 -2.8,0.5 -3.7,1.4 -1.7,1.7 -1.9,4.5 -1.9,7.8 0,3.4 0.2,6.2 1.9,7.9 0.9,0.9 2.1,1.4 3.7,1.4 1.6,0 2.9,-0.5 3.8,-1.4 1.7,-1.7 1.9,-4.5 1.9,-7.9 0,-3.3 -0.2,-6.1 -1.9,-7.8 z" | ||||
|    id="path12" /> | ||||
| <path | ||||
|    class="st0" | ||||
|    d="m 222.1,35.8 v -3 c -2.1,2.2 -5.1,3.4 -8.1,3.4 -3.2,0 -5.8,-1.1 -7.6,-2.9 -2.6,-2.6 -3.3,-5.6 -3.3,-9.2 V 3.4999995 h 8.1 V 23.1 c 0,4.4 2.8,5.9 5.3,5.9 2.5,0 5.4,-1.5 5.4,-5.9 V 3.4999995 H 230 V 35.8 Z" | ||||
|    d="m 222.1,49.4 v -3 c -2.1,2.2 -5.1,3.4 -8.1,3.4 -3.2,0 -5.8,-1.1 -7.6,-2.9 -2.6,-2.6 -3.3,-5.6 -3.3,-9.2 V 17.1 h 8.1 v 19.6 c 0,4.4 2.8,5.9 5.3,5.9 2.5,0 5.4,-1.5 5.4,-5.9 V 17.1 h 8.1 v 32.3 z" | ||||
|    id="path14" /> | ||||
| <path | ||||
|    class="st0" | ||||
|    d="m 256.7,12.3 c -1.2,-1.2 -2.3,-1.9 -4.3,-1.9 -2.5,0 -5.2,1.9 -5.2,6 v 19.5 h -8.1 V 3.4999995 h 7.9 v 3.1 c 1.6,-1.9 4.7,-3.5 8.1,-3.5 3.2,0 5.4,0.8 7.6,3 z" | ||||
|    d="m 256.7,25.9 c -1.2,-1.2 -2.3,-1.9 -4.3,-1.9 -2.5,0 -5.2,1.9 -5.2,6 v 19.5 h -8.1 V 17.1 h 7.9 v 3.099999 c 1.6,-1.899999 4.7,-3.5 8.1,-3.5 3.2,0 5.4,0.800001 7.6,3 z" | ||||
|    id="path16" /> | ||||
| <path | ||||
|    class="st1" | ||||
|    d="m 316.4,35.8 v -3 c -2.1,2.2 -5.1,3.4 -8.1,3.4 -3.2,0 -5.8,-1.1 -7.6,-2.9 -2.6,-2.6 -3.3,-5.6 -3.3,-9.2 V 3.4999995 h 8.1 V 23.1 c 0,4.4 2.8,5.9 5.3,5.9 2.5,0 5.4,-1.5 5.4,-5.9 V 3.4999995 h 8.1 V 35.8 Z" | ||||
|    id="path18" | ||||
|    inkscape:label="path18" /> | ||||
| <path | ||||
|    class="st1" | ||||
|    d="m 357.2,33.3 c -1.8,1.8 -4.7,2.9 -7.9,2.9 -3.3,0 -5.7,-0.9 -7.8,-3.2 v 14.7 h -8.1 V 3.4999995 h 7.8 v 3 c 2.2,-2.5 4.7,-3.4 8.1,-3.4 3.2,0 6.1,1.1 7.9,2.9 C 360.4,9.2 360.5,14.8 360.5,19.6 c 0,4.9 -0.1,10.5 -3.3,13.7 z M 346.9,10.4 c -4.8,0 -5.5,4 -5.5,9.3 0,5.3 0.6,9.3 5.5,9.3 4.9,0 5.5,-4 5.5,-9.3 0,-5.3 -0.6,-9.3 -5.5,-9.3 z" | ||||
|    id="path20" /> | ||||
| <g | ||||
|    id="g88" | ||||
|    transform="translate(-17.6,-46.1)"> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 91,101.6 v -10 h 6.4 V 93 h -4.9 v 2.9 h 4.1 v 1.3 h -4.1 v 3 h 4.9 v 1.4 z" | ||||
|    id="path22" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 103.8,101.6 v -4.3 c 0,-1.1 -0.6,-1.6 -1.4,-1.6 -0.8,0 -1.5,0.5 -1.5,1.6 v 4.3 h -1.4 v -7.1 h 1.4 v 0.7 c 0.5,-0.5 1.2,-0.8 1.9,-0.8 0.7,0 1.3,0.2 1.8,0.6 0.5,0.5 0.7,1.2 0.7,2 v 4.5 h -1.5 z" | ||||
|    id="path24" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 109.6,101.6 c -1.3,0 -1.9,-1 -1.9,-2 v -3.9 h -0.8 v -1.1 h 0.8 v -2.2 h 1.4 v 2.2 h 1.4 v 1.1 h -1.4 v 3.8 c 0,0.5 0.3,0.8 0.8,0.8 h 0.6 v 1.2 h -0.9 z" | ||||
|    id="path26" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 116.4,96.2 c -0.3,-0.3 -0.6,-0.5 -1.1,-0.5 -0.8,0 -1.4,0.6 -1.4,1.6 v 4.3 h -1.4 v -7.1 h 1.4 v 0.8 c 0.4,-0.5 1.1,-0.9 1.9,-0.9 0.7,0 1.2,0.2 1.7,0.7 z" | ||||
|    id="path28" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 119.3,98.5 c 0,1.2 0.6,2 1.8,2 0.8,0 1.2,-0.2 1.7,-0.7 l 0.9,0.9 c -0.7,0.7 -1.4,1.1 -2.7,1.1 -1.8,0 -3.2,-0.9 -3.2,-3.6 0,-2.3 1.2,-3.6 3,-3.6 1.9,0 3,1.4 3,3.4 v 0.6 h -4.5 z m 3,-2 c -0.2,-0.5 -0.7,-0.9 -1.4,-0.9 -0.7,0 -1.2,0.4 -1.4,0.9 -0.1,0.3 -0.2,0.5 -0.2,1 h 3.2 c 0,-0.5 0,-0.7 -0.2,-1 z" | ||||
|    id="path30" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 125.4,101.6 v -1.1 l 3.5,-4.7 h -3.3 v -1.3 h 5.1 v 1.1 l -3.6,4.7 h 3.6 v 1.3 z" | ||||
|    id="path32" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 140.3,101.6 v -0.8 c -0.5,0.6 -1.1,0.8 -1.9,0.8 -0.7,0 -1.3,-0.2 -1.7,-0.6 -0.7,-0.7 -0.8,-1.9 -0.8,-3 0,-1.1 0.1,-2.3 0.8,-3 0.4,-0.4 1,-0.6 1.7,-0.6 0.8,0 1.3,0.2 1.9,0.8 v -3.6 h 1.4 v 10 z m -1.5,-5.9 c -1.3,0 -1.5,1.1 -1.5,2.4 0,1.3 0.2,2.4 1.5,2.4 1.3,0 1.5,-1.1 1.5,-2.4 0,-1.3 -0.3,-2.4 -1.5,-2.4 z" | ||||
|    id="path34" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="M 147.9,101.6 V 101 c -0.5,0.5 -1,0.7 -1.9,0.7 -0.9,0 -1.5,-0.2 -1.9,-0.6 -0.4,-0.4 -0.6,-0.9 -0.6,-1.5 0,-1.2 0.8,-2 2.5,-2 h 1.9 V 97 c 0,-0.9 -0.4,-1.3 -1.6,-1.3 -0.8,0 -1.2,0.2 -1.6,0.7 l -0.9,-0.9 c 0.7,-0.8 1.4,-1 2.5,-1 1.9,0 2.9,0.8 2.9,2.4 v 4.7 z m 0,-3.1 h -1.7 c -0.8,0 -1.3,0.4 -1.3,1 0,0.6 0.4,1 1.3,1 0.5,0 1,0 1.3,-0.4 0.2,-0.2 0.3,-0.5 0.3,-1.1 v -0.5 z" | ||||
|    id="path36" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 155.9,101.6 v -4.3 c 0,-1.1 -0.6,-1.6 -1.4,-1.6 -0.8,0 -1.5,0.5 -1.5,1.6 v 4.3 h -1.4 v -7.1 h 1.4 v 0.7 c 0.5,-0.5 1.2,-0.8 1.9,-0.8 0.7,0 1.3,0.2 1.8,0.6 0.5,0.5 0.7,1.2 0.7,2 v 4.5 h -1.5 z" | ||||
|    id="path38" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 162,101.7 c -1.2,0 -2.1,-0.2 -3,-1 l 0.9,-0.9 c 0.6,0.6 1.3,0.7 2,0.7 0.9,0 1.6,-0.3 1.6,-1 0,-0.5 -0.3,-0.8 -1,-0.8 l -1.1,-0.1 c -1.3,-0.1 -2.1,-0.7 -2.1,-2 0,-1.4 1.2,-2.2 2.7,-2.2 1.1,0 2,0.2 2.6,0.8 l -0.9,0.9 c -0.4,-0.4 -1.1,-0.5 -1.8,-0.5 -0.9,0 -1.3,0.4 -1.3,0.9 0,0.4 0.2,0.7 1,0.8 l 1.1,0.1 c 1.3,0.1 2.1,0.7 2.1,2 0.2,1.5 -1.1,2.3 -2.8,2.3 z" | ||||
|    id="path40" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 172.2,101.6 c -1.4,0 -1.9,-0.9 -1.9,-2 v -8 h 1.4 v 7.9 c 0,0.5 0.2,0.8 0.8,0.8 h 0.6 v 1.2 h -0.9 z" | ||||
|    id="path42" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 173.9,94.4 v -2.7 h 1.6 v 1.5 z" | ||||
|    id="path44" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 178.9,98.5 c 0,1.2 0.6,2 1.8,2 0.8,0 1.2,-0.2 1.7,-0.7 l 0.9,0.9 c -0.7,0.7 -1.4,1.1 -2.7,1.1 -1.8,0 -3.2,-0.9 -3.2,-3.6 0,-2.3 1.2,-3.6 3,-3.6 1.9,0 3,1.4 3,3.4 v 0.6 h -4.5 z m 3,-2 c -0.2,-0.5 -0.7,-0.9 -1.4,-0.9 -0.7,0 -1.2,0.4 -1.4,0.9 -0.1,0.3 -0.2,0.5 -0.2,1 h 3.2 c 0,-0.5 0,-0.7 -0.2,-1 z" | ||||
|    id="path46" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 189.9,101.6 v -4.3 c 0,-1.1 -0.6,-1.6 -1.4,-1.6 -0.8,0 -1.5,0.5 -1.5,1.6 v 4.3 h -1.4 v -7.1 h 1.4 v 0.7 c 0.5,-0.5 1.2,-0.8 1.9,-0.8 0.7,0 1.3,0.2 1.8,0.6 0.5,0.5 0.7,1.2 0.7,2 v 4.5 h -1.5 z" | ||||
|    id="path48" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 196,101.7 c -1.2,0 -2.1,-0.2 -3,-1 l 0.9,-0.9 c 0.6,0.6 1.3,0.7 2,0.7 0.9,0 1.6,-0.3 1.6,-1 0,-0.5 -0.3,-0.8 -1,-0.8 l -1.1,-0.1 c -1.3,-0.1 -2.1,-0.7 -2.1,-2 0,-1.4 1.2,-2.2 2.7,-2.2 1.1,0 2,0.2 2.6,0.8 l -0.9,0.9 c -0.4,-0.4 -1.1,-0.5 -1.8,-0.5 -0.9,0 -1.3,0.4 -1.3,0.9 0,0.4 0.2,0.7 1,0.8 l 1.1,0.1 c 1.3,0.1 2.1,0.7 2.1,2 0.1,1.5 -1.1,2.3 -2.8,2.3 z" | ||||
|    id="path50" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 201.8,98.5 c 0,1.2 0.6,2 1.8,2 0.8,0 1.2,-0.2 1.7,-0.7 l 0.9,0.9 c -0.7,0.7 -1.4,1.1 -2.7,1.1 -1.8,0 -3.2,-0.9 -3.2,-3.6 0,-2.3 1.2,-3.6 3,-3.6 1.9,0 3,1.4 3,3.4 v 0.6 h -4.5 z m 3,-2 c -0.2,-0.5 -0.7,-0.9 -1.4,-0.9 -0.7,0 -1.2,0.4 -1.4,0.9 -0.1,0.3 -0.2,0.5 -0.2,1 h 3.2 c 0,-0.5 0,-0.7 -0.2,-1 z" | ||||
|    id="path52" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 208.4,93.1 v -1.5 h 1.5 v 1.5 z m 0.1,8.5 v -7.1 h 1.4 v 7.1 z" | ||||
|    id="path54" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 214.7,104.5 c -1.1,0 -1.8,-0.3 -2.5,-0.9 l 0.9,-0.9 c 0.4,0.4 0.8,0.6 1.5,0.6 1.2,0 1.7,-0.9 1.7,-1.8 v -0.9 c -0.5,0.6 -1.1,0.8 -1.8,0.8 -0.7,0 -1.3,-0.2 -1.7,-0.6 -0.7,-0.7 -0.8,-1.7 -0.8,-2.9 0,-1.2 0.1,-2.2 0.8,-2.9 0.4,-0.4 1,-0.6 1.7,-0.6 0.8,0 1.3,0.2 1.9,0.8 v -0.8 h 1.4 v 7.1 c -0.1,1.8 -1.2,3 -3.1,3 z m 0.2,-8.8 c -1.3,0 -1.5,1.1 -1.5,2.2 0,1.1 0.2,2.2 1.5,2.2 1.3,0 1.4,-1.1 1.4,-2.2 0,-1.1 -0.2,-2.2 -1.4,-2.2 z" | ||||
|    id="path56" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 224.5,101.6 v -4.3 c 0,-1.1 -0.6,-1.6 -1.4,-1.6 -0.8,0 -1.5,0.5 -1.5,1.6 v 4.3 h -1.4 v -7.1 h 1.4 v 0.7 c 0.5,-0.5 1.2,-0.8 1.9,-0.8 0.7,0 1.3,0.2 1.8,0.6 0.5,0.5 0.7,1.2 0.7,2 v 4.5 h -1.5 z" | ||||
|    id="path58" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 229.3,98.5 c 0,1.2 0.6,2 1.8,2 0.8,0 1.2,-0.2 1.7,-0.7 l 0.9,0.9 c -0.7,0.7 -1.4,1.1 -2.7,1.1 -1.8,0 -3.2,-0.9 -3.2,-3.6 0,-2.3 1.2,-3.6 3,-3.6 1.9,0 3,1.4 3,3.4 v 0.6 h -4.5 z m 3,-2 c -0.2,-0.5 -0.7,-0.9 -1.4,-0.9 -0.7,0 -1.2,0.4 -1.4,0.9 -0.1,0.3 -0.2,0.5 -0.2,1 h 3.2 c 0,-0.5 -0.1,-0.7 -0.2,-1 z" | ||||
|    id="path60" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 244.6,101.6 v -4.3 c 0,-1.1 -0.6,-1.6 -1.4,-1.6 -0.8,0 -1.5,0.5 -1.5,1.5 v 4.4 h -1.4 v -4.3 c 0,-1.1 -0.6,-1.6 -1.4,-1.6 -0.8,0 -1.5,0.5 -1.5,1.6 v 4.3 H 236 v -7.1 h 1.4 v 0.7 c 0.5,-0.5 1.2,-0.8 1.9,-0.8 0.9,0 1.6,0.3 2,1 0.6,-0.7 1.3,-1 2.2,-1 0.7,0 1.4,0.2 1.8,0.6 0.5,0.5 0.8,1.2 0.8,2 v 4.5 h -1.5 z" | ||||
|    id="path62" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 249.4,98.5 c 0,1.2 0.6,2 1.8,2 0.8,0 1.2,-0.2 1.7,-0.7 l 0.9,0.9 c -0.7,0.7 -1.4,1.1 -2.7,1.1 -1.8,0 -3.2,-0.9 -3.2,-3.6 0,-2.3 1.2,-3.6 3,-3.6 1.9,0 3,1.4 3,3.4 v 0.6 h -4.5 z m 3,-2 c -0.2,-0.5 -0.7,-0.9 -1.4,-0.9 -0.7,0 -1.2,0.4 -1.4,0.9 -0.1,0.3 -0.2,0.5 -0.2,1 h 3.2 c 0,-0.5 -0.1,-0.7 -0.2,-1 z" | ||||
|    id="path64" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 260.3,101.6 v -4.3 c 0,-1.1 -0.6,-1.6 -1.4,-1.6 -0.8,0 -1.5,0.5 -1.5,1.6 v 4.3 H 256 v -7.1 h 1.4 v 0.7 c 0.5,-0.5 1.2,-0.8 1.9,-0.8 0.7,0 1.3,0.2 1.8,0.6 0.5,0.5 0.7,1.2 0.7,2 v 4.5 h -1.5 z" | ||||
|    id="path66" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 266.2,101.6 c -1.3,0 -1.9,-1 -1.9,-2 v -3.9 h -0.8 v -1.1 h 0.8 v -2.2 h 1.4 v 2.2 h 1.4 v 1.1 h -1.4 v 3.8 c 0,0.5 0.3,0.8 0.8,0.8 h 0.6 v 1.2 h -0.9 z" | ||||
|    id="path68" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 274.8,101.7 c -1.2,0 -2.1,-0.2 -3,-1 l 0.9,-0.9 c 0.6,0.6 1.3,0.7 2,0.7 0.9,0 1.6,-0.3 1.6,-1 0,-0.5 -0.3,-0.8 -1,-0.8 l -1.1,-0.1 c -1.3,-0.1 -2.1,-0.7 -2.1,-2 0,-1.4 1.2,-2.2 2.7,-2.2 1.1,0 2,0.2 2.6,0.8 l -0.9,0.9 c -0.4,-0.4 -1.1,-0.5 -1.8,-0.5 -0.9,0 -1.3,0.4 -1.3,0.9 0,0.4 0.2,0.7 1,0.8 l 1.1,0.1 c 1.3,0.1 2.1,0.7 2.1,2 0.2,1.5 -1.1,2.3 -2.8,2.3 z" | ||||
|    id="path70" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 283.9,101.6 v -0.7 c -0.5,0.5 -1.2,0.8 -1.9,0.8 -0.7,0 -1.3,-0.2 -1.8,-0.6 -0.5,-0.5 -0.7,-1.2 -0.7,-2 v -4.5 h 1.4 v 4.3 c 0,1.1 0.6,1.6 1.4,1.6 0.8,0 1.5,-0.5 1.5,-1.6 v -4.3 h 1.4 v 7.1 h -1.3 z" | ||||
|    id="path72" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 292.8,101 c -0.4,0.4 -1,0.6 -1.7,0.6 -0.8,0 -1.3,-0.2 -1.9,-0.8 v 3.6 h -1.4 v -10 h 1.4 v 0.8 c 0.5,-0.6 1.1,-0.8 1.9,-0.8 0.7,0 1.3,0.2 1.7,0.6 0.7,0.7 0.8,1.9 0.8,3 0,1.1 -0.1,2.3 -0.8,3 z m -2.1,-5.3 c -1.3,0 -1.5,1.1 -1.5,2.4 0,1.3 0.2,2.4 1.5,2.4 1.3,0 1.5,-1.1 1.5,-2.4 0,-1.3 -0.2,-2.4 -1.5,-2.4 z" | ||||
|    id="path74" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 296.7,98.5 c 0,1.2 0.6,2 1.8,2 0.8,0 1.2,-0.2 1.7,-0.7 l 0.9,0.9 c -0.7,0.7 -1.4,1.1 -2.7,1.1 -1.8,0 -3.2,-0.9 -3.2,-3.6 0,-2.3 1.2,-3.6 3,-3.6 1.9,0 3,1.4 3,3.4 v 0.6 h -4.5 z m 3,-2 c -0.2,-0.5 -0.7,-0.9 -1.4,-0.9 -0.7,0 -1.2,0.4 -1.4,0.9 -0.1,0.3 -0.2,0.5 -0.2,1 h 3.2 c 0,-0.5 -0.1,-0.7 -0.2,-1 z m -1,-3.3 h -1.1 l 1.1,-2.3 h 1.6 z" | ||||
|    id="path76" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 307.2,96.2 c -0.3,-0.3 -0.6,-0.5 -1.1,-0.5 -0.8,0 -1.4,0.6 -1.4,1.6 v 4.3 h -1.4 v -7.1 h 1.4 v 0.8 c 0.4,-0.5 1.1,-0.9 1.9,-0.9 0.7,0 1.2,0.2 1.7,0.7 z" | ||||
|    id="path78" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 309.6,93.1 v -1.5 h 1.5 v 1.5 z m 0,8.5 v -7.1 h 1.4 v 7.1 z" | ||||
|    id="path80" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 314.5,98.5 c 0,1.2 0.6,2 1.8,2 0.8,0 1.2,-0.2 1.7,-0.7 l 0.9,0.9 c -0.7,0.7 -1.4,1.1 -2.7,1.1 -1.8,0 -3.2,-0.9 -3.2,-3.6 0,-2.3 1.2,-3.6 3,-3.6 1.9,0 3,1.4 3,3.4 v 0.6 h -4.5 z m 3,-2 c -0.2,-0.5 -0.7,-0.9 -1.4,-0.9 -0.7,0 -1.2,0.4 -1.4,0.9 -0.1,0.3 -0.2,0.5 -0.2,1 h 3.2 c 0,-0.5 -0.1,-0.7 -0.2,-1 z" | ||||
|    id="path82" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 325.4,101.6 v -0.7 c -0.5,0.5 -1.2,0.8 -1.9,0.8 -0.7,0 -1.3,-0.2 -1.8,-0.6 -0.5,-0.5 -0.7,-1.2 -0.7,-2 v -4.5 h 1.4 v 4.3 c 0,1.1 0.6,1.6 1.4,1.6 0.8,0 1.5,-0.5 1.5,-1.6 v -4.3 h 1.4 v 7.1 h -1.3 z" | ||||
|    id="path84" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="m 333.1,96.2 c -0.3,-0.3 -0.6,-0.5 -1.1,-0.5 -0.8,0 -1.4,0.6 -1.4,1.6 v 4.3 h -1.4 v -7.1 h 1.4 v 0.8 c 0.4,-0.5 1.1,-0.9 1.9,-0.9 0.7,0 1.2,0.2 1.7,0.7 z" | ||||
|    id="path86" /> | ||||
| </g> | ||||
|    transform="matrix(0.00979287,0,0,-0.00979287,263.62278,68.749182)" | ||||
|    fill="#000000" | ||||
|    stroke="none" | ||||
|    id="g354" | ||||
|    style="fill:#ff3333;fill-opacity:1"><path | ||||
|      d="m 6697,6592 c -16,-17 -17,-163 -17,-1903 0,-2023 -1,-1981 51,-2168 11,-42 41,-119 67,-171 37,-77 61,-110 127,-176 66,-67 97,-89 175,-128 182,-89 353,-116 738,-116 208,0 251,2 270,16 l 22,15 v 373 c 0,349 -1,374 -18,389 -15,14 -40,17 -128,17 -232,0 -316,54 -344,221 -6,42 -10,665 -10,1840 0,1708 -1,1777 -18,1792 -17,15 -63,17 -459,17 -413,0 -441,-1 -456,-18 z" | ||||
|      id="path344" | ||||
|      style="fill:#ff3333;fill-opacity:1" /><path | ||||
|      d="m 4568,5340 c -164,-20 -293,-63 -410,-134 -96,-58 -169,-119 -220,-182 l -43,-54 -5,141 c -4,124 -7,142 -24,155 -16,12 -96,14 -458,14 -425,0 -439,-1 -458,-20 -20,-20 -20,-33 -20,-2250 0,-2217 0,-2230 20,-2250 19,-19 33,-20 458,-20 363,0 442,2 458,14 18,14 19,37 24,765 l 5,752 40,-51 c 48,-61 147,-144 230,-192 148,-85 300,-125 520,-134 583,-27 1002,241 1183,756 73,209 107,414 123,741 13,262 2,610 -26,794 -33,217 -91,416 -163,560 -158,319 -407,508 -762,580 -89,18 -376,27 -472,15 z m 25,-814 c 208,-40 331,-170 393,-413 53,-210 55,-760 4,-973 -29,-120 -87,-234 -151,-298 -119,-119 -325,-169 -524,-127 -242,51 -374,232 -415,565 -13,109 -13,571 0,680 24,199 83,350 171,440 117,118 313,166 522,126 z" | ||||
|      id="path346" | ||||
|      style="fill:#ff3333;fill-opacity:1" /><path | ||||
|      d="m 8747,5262 c -16,-17 -17,-111 -17,-1152 0,-971 2,-1147 16,-1237 91,-615 495,-973 1099,-973 330,0 584,102 782,314 l 62,65 3,-140 c 3,-126 5,-142 22,-155 16,-12 96,-14 458,-14 425,0 439,1 458,20 20,20 20,33 20,1635 0,1602 0,1615 -20,1635 -19,19 -33,20 -458,20 -363,0 -442,-2 -458,-14 -19,-14 -19,-40 -24,-1073 l -5,-1058 -31,-85 c -82,-231 -235,-340 -473,-340 -242,1 -401,131 -474,388 -21,77 -22,83 -25,1112 -2,936 -4,1036 -19,1052 -15,17 -46,18 -458,18 -415,0 -443,-1 -458,-18 z" | ||||
|      id="path350" | ||||
|      style="fill:#ff3333;fill-opacity:1" /><path | ||||
|      d="m 127,4172 c -15,-17 -17,-59 -17,-399 0,-355 1,-381 18,-396 17,-16 103,-17 1030,-17 999,0 1012,0 1032,20 19,19 20,33 20,395 0,362 -1,376 -20,395 -20,20 -33,20 -1033,20 -970,0 -1015,-1 -1030,-18 z" | ||||
|      id="path352" | ||||
|      style="fill:#ff3333;fill-opacity:1" /></g> | ||||
|  | ||||
|  | ||||
| <g | ||||
|    id="g102" | ||||
|    transform="translate(-17.6,-46.1)"> | ||||
|    transform="translate(100.4,-32.5)"> | ||||
| 	<g | ||||
|    id="g94"> | ||||
| 		<path | ||||
| @@ -242,7 +117,7 @@ | ||||
| </g> | ||||
| <g | ||||
|    id="g110" | ||||
|    transform="translate(-17.6,-46.1)"> | ||||
|    transform="translate(-17.6,-32.5)"> | ||||
| 	<path | ||||
|    class="st1" | ||||
|    d="M 35.4,79.9 H 21.7 c -2.2,0 -4.1,1.8 -4.1,4.1 0,2.2 1.8,4.1 4.1,4.1 h 9.7 v 9.7 c 0,2.2 1.8,4.1 4.1,4.1 1.1,0 2.1,-0.5 2.9,-1.2 0.7,-0.7 1.2,-1.8 1.2,-2.9 V 84.1 c 0,-1.1 -0.5,-2.1 -1.2,-2.9 -0.9,-0.9 -1.9,-1.3 -3,-1.3" | ||||
| @@ -250,7 +125,11 @@ | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="M 52,63 H 38.3 c -2.2,0 -4.1,1.8 -4.1,4.1 0,2.2 1.8,4.1 4.1,4.1 H 48 v 9.7 c 0,2.2 1.8,4.1 4.1,4.1 1.1,0 2.1,-0.5 2.9,-1.2 0.7,-0.7 1.2,-1.8 1.2,-2.9 V 67.2 C 56.2,66.1 55.7,65.1 55,64.3 54.1,63.5 53.1,63 52,63" | ||||
|    id="path106" /> | ||||
|    id="path106" /><path | ||||
|    class="st1" | ||||
|    d="m 68.7,54.5 h 13.7 c 2.2,0 4.1,-1.8 4.1,-4.100001 0,-2.200001 -1.8,-4.1 -4.1,-4.1 H 72.7 V 36.6 c 0,-2.200001 -1.8,-4.1 -4.1,-4.1 -1.1,0 -2.1,0.5 -2.9,1.2 -0.7,0.7 -1.2,1.8 -1.2,2.9 v 13.7 c 0,1.1 0.5,2.1 1.2,2.9 0.9,0.899999 1.9,1.3 3,1.3" | ||||
|    id="path104-6" | ||||
|    style="fill:#ff3333" /> | ||||
| 	<path | ||||
|    class="st1" | ||||
|    d="M 68.5,46.1 H 54.8 c -2.2,0 -4.1,1.8 -4.1,4.1 0,2.2 1.8,4.1 4.1,4.1 h 9.7 V 64 c 0,2.2 1.8,4.1 4.1,4.1 1.1,0 2.1,-0.5 2.9,-1.2 0.7,-0.7 1.2,-1.8 1.2,-2.9 V 50.3 c 0,-1.1 -0.5,-2.1 -1.2,-2.9 -0.7,-0.8 -1.8,-1.3 -3,-1.3" | ||||
|   | ||||
| Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 7.6 KiB | 
							
								
								
									
										75
									
								
								resources/logo.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								resources/logo.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> | ||||
|  | ||||
| <svg | ||||
|    version="1.1" | ||||
|    id="Calque_1" | ||||
|    x="0px" | ||||
|    y="0px" | ||||
|    viewBox="0 0 68.900004 69.400003" | ||||
|    xml:space="preserve" | ||||
|    sodipodi:docname="logo.svg" | ||||
|    width="68.900002" | ||||
|    height="69.400002" | ||||
|    inkscape:version="1.2.2 (732a01da63, 2022-12-09)" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg"><defs | ||||
|    id="defs115" /><sodipodi:namedview | ||||
|    id="namedview113" | ||||
|    pagecolor="#ffffff" | ||||
|    bordercolor="#000000" | ||||
|    borderopacity="0.25" | ||||
|    inkscape:showpageshadow="2" | ||||
|    inkscape:pageopacity="0.0" | ||||
|    inkscape:pagecheckerboard="0" | ||||
|    inkscape:deskcolor="#d1d1d1" | ||||
|    showgrid="false" | ||||
|    inkscape:zoom="2.7436242" | ||||
|    inkscape:cx="225.61399" | ||||
|    inkscape:cy="45.195694" | ||||
|    inkscape:window-width="1920" | ||||
|    inkscape:window-height="1057" | ||||
|    inkscape:window-x="1912" | ||||
|    inkscape:window-y="-5" | ||||
|    inkscape:window-maximized="1" | ||||
|    inkscape:current-layer="Calque_1" /> | ||||
| <style | ||||
|    type="text/css" | ||||
|    id="style2"> | ||||
| 	.st0{fill:#3D566E;} | ||||
| 	.st1{fill:#FF3333;} | ||||
| </style> | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| <g | ||||
|    id="g110" | ||||
|    transform="translate(-17.6,-32.5)"> | ||||
| 	<path | ||||
|    class="st1" | ||||
|    d="M 35.4,79.9 H 21.7 c -2.2,0 -4.1,1.8 -4.1,4.1 0,2.2 1.8,4.1 4.1,4.1 h 9.7 v 9.7 c 0,2.2 1.8,4.1 4.1,4.1 1.1,0 2.1,-0.5 2.9,-1.2 0.7,-0.7 1.2,-1.8 1.2,-2.9 V 84.1 c 0,-1.1 -0.5,-2.1 -1.2,-2.9 -0.9,-0.9 -1.9,-1.3 -3,-1.3" | ||||
|    id="path104" /> | ||||
| 	<path | ||||
|    class="st0" | ||||
|    d="M 52,63 H 38.3 c -2.2,0 -4.1,1.8 -4.1,4.1 0,2.2 1.8,4.1 4.1,4.1 H 48 v 9.7 c 0,2.2 1.8,4.1 4.1,4.1 1.1,0 2.1,-0.5 2.9,-1.2 0.7,-0.7 1.2,-1.8 1.2,-2.9 V 67.2 C 56.2,66.1 55.7,65.1 55,64.3 54.1,63.5 53.1,63 52,63" | ||||
|    id="path106" /><path | ||||
|    class="st1" | ||||
|    d="m 68.7,54.5 h 13.7 c 2.2,0 4.1,-1.8 4.1,-4.100001 0,-2.200001 -1.8,-4.1 -4.1,-4.1 H 72.7 V 36.6 c 0,-2.200001 -1.8,-4.1 -4.1,-4.1 -1.1,0 -2.1,0.5 -2.9,1.2 -0.7,0.7 -1.2,1.8 -1.2,2.9 v 13.7 c 0,1.1 0.5,2.1 1.2,2.9 0.9,0.899999 1.9,1.3 3,1.3" | ||||
|    id="path104-6" | ||||
|    style="fill:#ff3333" /> | ||||
| 	<path | ||||
|    class="st1" | ||||
|    d="M 68.5,46.1 H 54.8 c -2.2,0 -4.1,1.8 -4.1,4.1 0,2.2 1.8,4.1 4.1,4.1 h 9.7 V 64 c 0,2.2 1.8,4.1 4.1,4.1 1.1,0 2.1,-0.5 2.9,-1.2 0.7,-0.7 1.2,-1.8 1.2,-2.9 V 50.3 c 0,-1.1 -0.5,-2.1 -1.2,-2.9 -0.7,-0.8 -1.8,-1.3 -3,-1.3" | ||||
|    id="path108" /> | ||||
| </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.4 KiB | 
| @@ -1,8 +1,5 @@ | ||||
| body, html { | ||||
|     width: 100vw; | ||||
|     height: 100vh; | ||||
|     background-color: gainsboro; | ||||
|     min-height: 100vh; | ||||
|     top: 0px; | ||||
|     left: 0px; | ||||
|     background-color: #EFEFEF; | ||||
|     padding-bottom: 0px; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user