1// Firebase 2const firebaseConfig = { 3 apiKey: "AIzaSyDbwiKT2tKrAGgH9RI6l57Uq982HgJGG38", 4 authDomain: "auto-therapy.firebaseapp.com", 5 databaseURL: "https://auto-therapy.firebaseio.com", 6 projectId: "auto-therapy", 7 storageBucket: "auto-therapy.appspot.com", 8 messagingSenderId: "708209119869", 9 appId: "1:708209119869:web:d035c0c9e9b2c61f8d5714", 10 measurementId: "G-LZM03NR12Y", 11}; 12 13firebase.initializeApp(firebaseConfig); 14 15// analytics 16firebase.analytics(); 17 18// Utiliser le cache 19firebase 20 .firestore() 21 .enablePersistence() 22 .catch((err) => {}); 23 24// Cloud messaging 25// async function requestPermission() { 26// const permission = await Notification.requestPermission(); 27// if (permission === "granted") { 28// } else { 29// } 30// } 31 32// try { 33// firebase.auth().onAuthStateChanged((user) => { 34// if (user) { 35// const messaging = firebase.messaging(); 36// messaging.usePublicVapidKey( 37// "BOpU1z4m0xhNcVTBI_pV8ibkFnEHAMEMeYe4gBeTw_475IyJhYV2X3A_O1_Vo-rtR2xP1xWEZveirHqgi_hbJ1k" 38// ); 39 40// messaging 41// .getToken() 42// .then((currentToken) => { 43// if (currentToken) { 44// // sendTokenToServer(currentToken); 45// // updateUIForPushEnabled(currentToken); 46// console.log("currentToken", currentToken); 47// } else { 48// // Show permission request. 49// console.log("No Instance ID token available. Request permission to generate one."); 50// // Show permission UI. 51// // updateUIForPushPermissionRequired(); 52// // setTokenSentToServer(false); 53// requestPermission(); 54// } 55// }) 56// .catch((err) => { 57// console.log("An error occurred while retrieving token. ", err); 58// // showToken("Error retrieving Instance ID token. ", err); 59// // setTokenSentToServer(false); 60// }); 61 62// messaging.onTokenRefresh(() => { 63// messaging 64// .getToken() 65// .then((refreshedToken) => { 66// console.log("Token refreshed."); 67// // Indicate that the new Instance ID token has not yet been sent to the 68// // app server.
69// // setTokenSentToServer(false); 70// // Send Instance ID token to app server. 71// // sendTokenToServer(refreshedToken); 72// console.log("refreshedToken", refreshedToken); 73// }) 74// .catch((err) => { 75// console.log("Unable to retrieve refreshed token ", err); 76// // showToken("Unable to retrieve refreshed token ", err); 77// }); 78// }); 79// } 80// }); 81// } catch (e) {} 82 83/** 84 * Check if serviceWorker 85 */ 86if ("serviceWorker" in navigator) { 87 navigator.serviceWorker.register("service-worker.js").then((reg) => {}); 88} 89 90document.addEventListener("DOMContentLoaded", () => { 91 loadInstallPromotion(); 92 93 document.querySelector(".menu-button").addEventListener("click", (e) => toggleMenu()); 94 95 toggleHeader(); 96}); 97 98/** 99 * PWA install 100 */ 101function loadInstallPromotion() { 102 window.addEventListener("appinstalled", (event) => {}); 103 104 let deferredPrompt; 105 window.addEventListener("beforeinstallprompt", (e) => { 106 e.preventDefault(); 107 deferredPrompt = e; 108 showInstallPromotion(); 109 }); 110 111 try { 112 document.getElementById("install-button").addEventListener("click", () => { 113 const promptEvent = deferredPrompt; 114 115 if (!promptEvent) { 116 return; 117 } 118 promptEvent.prompt(); 119 120 promptEvent.userChoice.then((result) => { 121 window.deferredPrompt = null; 122 hideInstallPromotion(); 123 }); 124 }); 125 } catch (e) {} 126} 127 128export function showInstallPromotion() { 129 try { 130 document.querySelector(".install-app").classList.toggle("hidden", false); 131 } catch (e) {} 132} 133 134export function hideInstallPromotion() { 135 try { 136 document.querySelector(".install-app").classList.toggle("hidden", true); 137 } catch (e) {} 138} 139 140/** 141 * Check if the user is connected 142 */ 143export function checkUserConnected() { 144 greeting(); 145 146 firebase.auth().onAuthStateChanged((user) => { 147 if (!user) { 148 showNotification( 149 "<p class='center'>Vous n'êtes pas connecté</p>", 150 "Connexion", 151 () => (window.location.href = "#!login") 152 ); 153 } else { 154 let userName = document.getElementById("username"); 155 if (userName) { 156 userName.innerHTML = user.displayName; 157 } 158 } 159 }); 160} 161 162/** 163 * Sign out user 164 */ 165export function signOut() { 166 firebase 167 .auth() 168 .signOut() 169 .then(function () { 170 window.location.href = "./fr/"; 171 showNotification( 172 `<p class="center">Vous êtes maintenant déconnecté</p>`, 173 "Ok", 174 () => (window.location.href = "./fr/") 175 ); 176 }) 177 .catch(function (error) { 178 // An error happened. 179 }); 180} 181 182/** 183 * Personalise la formule de salutation 184 */ 185export function greeting() { 186 let greeting = document.getElementById("greeting"); 187 188 if (greeting) { 189 let heures = new Date().getHours(); 190 let formule = "Bonjour"; 191 192 if (heures < 18) { 193 formule = "Bonjour"; 194 } else { 195 formule = "Bonsoir"; 196 } 197 198 greeting.innerHTML = formule; 199 } 200} 201 202/** 203 * Notification 204 * @param {HTMLElement} message 205 * @param {String} buttonLabel 206 * @param {CallableFunction} callback 207 */ 208export function showNotification(message, buttonLabel = "Fermer", callback) { 209 let bg = document.querySelector(".modal-bg"); 210 let modal = document.querySelector(".modal-notification"); 211 let btn = modal.querySelector(".btn-modal"); 212 213 [bg, modal].map((element) => element.classList.remove("hidden")); 214 215 modal.querySelector(".modal-content").innerHTML = message; 216 217 btn.innerHTML = buttonLabel; 218 219 document.body.classList.add("noscroll"); 220 221 btn.addEventListener("click", (e) => { 222 [bg, modal].map((element) => element.classList.add("hidden")); 223 224 document.body.classList.remove("noscroll"); 225 226 callback(); 227 }); 228} 229 230/** 231 * Import le modèle 232 * @param {String} id 233 */ 234export function page(id) { 235 const file = "templates/" + id + ".html"; 236 const req = new XMLHttpRequest(); 237 req.open("GET", file, false); 238 req.send(); 239 240 document.getElementById("page").innerHTML = req.responseText; 241} 242 243/** 244 * Affiche/cache le menu 245 */ 246export function toggleMenu() { 247 const menu = document.getElementById("menu"); 248 menu.classList.toggle("show"); 249 document.body.classList.toggle("noscroll"); 250 251 menu.querySelectorAll("li a").forEach((element) => element.addEventListener("click", (e) => toggleMenu())); 252 253 menu.addEventListener("swiped-left", (e) => toggleMenu()); 254 255 return false; 256} 257 258/** 259 * Help modal 260 * @param {URL} URL 261 */ 262export function showHelp(URL) { 263 let bg = document.querySelector(".modal-bg"); 264 let modal = document.querySelector(".modal-help"); 265 266 document.querySelectorAll("[data-help]").forEach((element) => { 267 element.addEventListener("click", (e) => { 268 modal.querySelector("#help-frame").src = URL + "#" + element.dataset.help; 269 270 [bg, modal].map((element) => element.classList.remove("hidden")); 271 272 document.body.classList.add("noscroll"); 273 });
274 }); 275 276 modal.querySelector(".btn-modal").addEventListener("click", (e) => { 277 [bg, modal].map((element) => element.classList.add("hidden")); 278 document.body.classList.remove("noscroll"); 279 }); 280} 281 282/** 283 * Libère le focus 284 */ 285export function blurTextarea() { 286 document.querySelectorAll("textarea, input").forEach((element) => element.blur()); 287} 288 289/** 290 * Autoreize textarea with data-autoresize 291 */ 292export function autoResizeTextarea() { 293 document.querySelectorAll("[data-autoresize]").forEach((element) => { 294 element.style.boxSizing = "border-box"; 295 let offset = element.offsetHeight - element.clientHeight; 296 element.addEventListener("input", (event) => { 297 event.target.style.height = "auto"; 298 event.target.style.height = event.target.scrollHeight + offset + "px"; 299 }); 300 301 element.addEventListener("focus", (event) => { 302 event.target.style.height = "auto"; 303 event.target.style.height = event.target.scrollHeight + offset + "px"; 304 }); 305 306 element.removeAttribute("data-autoresize"); 307 }); 308} 309 310/** 311 * Masque/affiche le menu 312 */ 313export function toggleHeader() { 314 // console.log("toggleHeader"); 315 const hash = window.location.hash; 316 317 try { 318 const header = document.querySelector(".header"); 319 const install = document.querySelector(".install-app"); 320 const body = document.body; 321 322 header.style.visibility = "hidden"; 323 install.style.visibility = "hidden"; 324 body.classList.add("no-background"); 325 326 if (hash !== "#!login" && hash !== "#!login/retrieve" && hash !== "#!register" && hash !== "#!coherence/create") { 327 header.style.visibility = "visible"; 328 install.style.visibility = "visible"; 329 body.classList.remove("no-background"); 330 } 331 } catch (e) {} 332 333 window.addEventListener("hashchange", () => toggleHeader(), { once: true }); 334} 335 336/** 337 * Trace le graphique 338 * 339 * @param {Array} arrLabels 340 * @param {Array} arrScores 341 */ 342export function drawChart(arrLabels, arrScores) { 343 try { 344 const ctx = document.getElementById("progression").getContext("2d"); 345 346 // Chart.defaults.scale.gridLines.display = false; 347 348 const chart = new Chart(ctx, { 349 type: "line", 350 351 // The data for our dataset 352 data: { 353 labels: arrLabels, 354 datasets: [ 355 { 356 label: "Score", 357 backgroundColor: "rgba(255, 99, 132, .5)", // "rgb(243, 156, 203)" 358 borderColor: "rgb(255, 99, 132)", 359 data: arrScores, 360 }, 361 ], 362 }, 363 364 options: { 365 responsive: true, 366 maintainAspectRatio: true, 367 legend: { 368 display: false, 369 }, 370 scales: { 371 xAxes: [ 372 { 373 display: false, 374 }, 375 ], 376 yAxes: [ 377 { 378 display: false, 379 ticks: { 380 beginAtZero: true, 381 max: 70, 382 }, 383 }, 384 ], 385 }, 386 }, 387 }); 388 } catch (e) {} 389} 390 391/** 392 * Number days in current month 393 */ 394export function daysInThisMonth() { 395 var now = new Date(); 396 return new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate(); 397} 398 399/** 400 * Shuffle array 401 * @param {Array} a 402 */ 403export function shuffle(a) { 404 for (let i = a.length - 1; i > 0; i--) { 405 const j = Math.floor(Math.random() * (i + 1)); 406 [a[i], a[j]] = [a[j], a[i]]; 407 } 408 return a; 409}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.