if (window.location.pathname === '/gpt') { setTimeout(() => { window.history.replaceState(null, '', '/') }, 1e3) } let img, kofi = false const session = { clicks: 0, spaces: 0, 'untrusted-clicks': 0, 'untrusted-spaces': 0, get farts() { return this.clicks + this.spaces }, get 'untrusted-farts'() { return this['unstrusted-clicks'] + this['untrusted-spaces'] }, } window.addEventListener('load', event => { bump('visits', { event }) console.log(' /\\_/\\ (\n ( ^.^ ) _)\n \\"/ (\n ( | | )\n(__d b__)') if (!('miaou' in window)) { Object.defineProperty(window, 'miaou', { get: () => { bump('miaous') console.log( ' _________\n ( PROUT ! )\n /¨¨¨¨¨¨¨¨¨\n /\\_/\\ (\n ( °.° ) _)\n \\"/ (\n ( | | )\n(__d b__)' ) }, }) } document.querySelectorAll('a').forEach(a => { a.addEventListener('click', event => event.stopPropagation()) }) img = document.querySelector('img') if (img != null) { img.addEventListener('contextmenu', e => e.preventDefault()) } window.addEventListener('click', event => { bump('clicks', { event }) fart(event) }) document.addEventListener('keydown', event => { if (!event.repeat && event.key === ' ') { bump('spaces', { event }) fart(event) } }) if (getCookie('hacked')) { bump('hacks') deleteCookie('hacked') } let firstVisitCookie = getCookie('firstVisit') let firstVisit = firstVisitCookie && new Date(firstVisitCookie) const lastVisitCookie = getCookie('lastVisit') const lastVisit = lastVisitCookie && new Date(lastVisitCookie) if (firstVisit == null) { firstVisit = new Date() firstVisitCookie = firstVisit.toISOString() setCookie('firstVisit', firstVisitCookie) } if (lastVisit && Date.now() - lastVisit < 24 * 60 * 60 * 1e3) { document .querySelectorAll('.hidden') .forEach(el => el.classList.remove('hidden')) } setCookie('lastVisit', new Date().toISOString()) if (!('share' in navigator) && !('clipboard' in navigator)) { document.querySelector('.share').style.display = 'none' } if (firstVisitCookie.at(-2) === '6') { Object.assign(document.querySelector('.btn.donate').style, { color: 'purple', backgroundColor: '#ffe9e9', }) _paq && _paq.push(['trackEvent', 'Seen', 'kofiButton', 'variant1']) } }) window.addEventListener('beforeunload', () => { if (session.farts) { _paq && _paq.push([ 'trackEvent', 'Interaction', 'farts', 'end session', session.farts, ]) } _paq && _paq.push([ 'trackEvent', 'Interaction', 'farts', 'end total', getTotal('farts'), ]) const totalUntrustedFarts = getTotal('untrusted-farts') if (totalUntrustedFarts > 0) { _paq && _paq.push([ 'trackEvent', 'Interaction', 'untrusted-farts', 'end total', totalUntrustedFarts, ]) } }) const SOUNDS = {} const ANIMATIONS = { fart: { cssAnimation: 'gelatine 0.5s', sound: 'jaipete.mp3', weight: 400, }, barrelRoll: { cssAnimation: 'barrelroll 1s', sound: 'meow.mp3', trackEvent: 'barrelRolls', blockAnimation: true, weight: 2, }, greg: { cssAnimation: 'gelatine 0.5s', sound: 'ouais-cest-greg.mp3', trackEvent: 'gregs', blockSound: true, weight: 2, }, bien: { cssAnimation: 'bien 1.5s', sound: 'je-suis-bien.mp3', trackEvent: 'biens', blockSound: true, weight: 1, }, } const TOTAL_WEIGHT = Object.values(ANIMATIONS).reduce( (sum, animation) => sum + animation.weight, 0 ) let blocked = false function fart(event) { if (blocked) { return } setTimeout(() => { document .querySelectorAll('.hidden') .forEach(el => el.classList.remove('hidden')) }, 4e3) let animation if (session.farts < 20) { animation = ANIMATIONS.fart } else { const r = Math.random() * TOTAL_WEIGHT let partialWeights = 0 for (const [key, _animation] of Object.entries(ANIMATIONS)) { partialWeights += _animation.weight if (r < partialWeights) { animation = _animation animation.key = key break } } } if (animation.blockAnimation || animation.blockSound) { blocked = true } let sound = SOUNDS[animation.key] if (sound === undefined) { sound = SOUNDS[animation.key] = new Audio(animation.sound) sound.load() } sound.currentTime = 0 sound.play() img.style.animation = 'none' img.offsetHeight /* trigger reflow */ img.style.animation = animation.cssAnimation if (animation.blockAnimation) { img.onanimationend = () => (blocked = false) } else if (animation.blockSound) { sound.onended = () => (blocked = false) } if (animation.trackEvent) { bump(animation.trackEvent, { event }) } } async function stats(event) { const getStats = async () => { const totalFarts = getTotal('farts') if (totalFarts === 0) { return 'Cliquez sur le chat au moins une fois !' } const totalUntrustedFarts = getTotal('untrusted-farts') const barrelRolls = getTotal('barrelRolls') const gregs = getTotal('gregs') const biens = getTotal('biens') const cgus = getTotal('CGU') const nStats = getTotal('stats') const miaous = getTotal('miaous') const hacks = getTotal('hacks') const kofis = getTotal('kofi') + getTotal('kofiButton') let stats = `Statistiques :\n- Il y a un total de ${ miaous > 0 ? 2 : 1 } chat${ miaous > 0 ? 's' : '' } sur cette page\n- Vous avez cliqué ${totalFarts} fois sur le chat` if (totalFarts > 1000) { stats += " (C'est beaucoup !)" } if (barrelRolls > 0) { stats += `\n- Le chat a fait ${barrelRolls} backflip${ barrelRolls > 1 ? 's' : '' }` } if (gregs > 0) { stats += `\n- Greg a appelé ${gregs} fois` } if (biens > 0) { stats += `\n- Le chat s'est senti bieeeng ${biens} fois` } if (cgus > 0) { stats += `\n- Vous avez lu les Conditions Générales d'Utilisation ${cgus} fois (C'est bien !)` } if (totalUntrustedFarts > 0) { stats += `\n- Vous avez triché ${totalUntrustedFarts} fois (C'est pas bien !)` } if (hacks > 0) { stats += `\n- Vous avez essayé de hacker le chat ${hacks} fois (C'est pas bien !)` } try { if (typeof navigator.getBattery === 'function') { const batteryLevel = (await navigator.getBattery()).level if (batteryLevel < 0.1) { stats += `\n- Il vous reste ${Math.floor( batteryLevel * 100 )}% de batterie` } } } catch (err) {} if (miaous > 0) { stats += `\n- Vous avez dit bonjour au chat ${miaous} fois` } if (kofis > 0) { stats += `\n- Vous avez essayé de faire un don ${kofis} fois` } if (nStats > 20) { stats += `\n- Vous avez lu vos stats ${nStats} fois` if (nStats > 50) { stats += ' (Pourquoi ?)' } } const day = new Date().getDay() if (day > 0 && day < 6 && Math.random() < 1 / 40) { stats += `\n- Il reste environ ${6 - day} jour${ day < 5 ? 's' : '' } avant le week-end (C'est trop !)` } return stats } bump('stats', { event }) alert(await getStats()) } function isMilestone(n) { return [ 1, 2, 10, 20, 50, 100, 200, 1e3, 5e3, 10e3, 20e3, 50e3, 100e3, 500e3, 1e6, 2e6, 10e6, 100e6, 500e6, 1e9, ].includes(n) } function getTotal(key) { if (key.endsWith('farts')) { return ( getTotal(key.replace('farts', 'clicks')) + getTotal(key.replace('farts', 'spaces')) ) } return +(getCookie(key) || 0) } function bump(key, { event, days, aliases = [] } = {}) { if (event && event.isTrusted === false) { key = `untrusted-${key}` aliases = aliases.map(alias => `untrusted-${alias}`) } // Total const total = [key, ...aliases].reduce((max, key) => Math.max(getTotal(key), max), 0) + 1 setCookie(key, total, days) aliases.forEach(deleteCookie) if (isMilestone(total)) { _paq && _paq.push(['trackEvent', 'Interaction', key, 'total', total]) } // Session if (session[key] === undefined) { session[key] = 0 } session[key]++ return total } let shareTimeout function share() { const url = 'https://chat-jai-pete.fr?utm_source=share' if ('share' in navigator) { navigator.share({ title: "Chat J'ai Pété", url, }) } else if ('clipboard' in navigator) { navigator.clipboard.writeText(url).then( () => { const btn = document.querySelector('.btn.share') if (shareTimeout === undefined) { btn.dataset.originalContent = btn.textContent btn.textContent = 'Lien copié' btn.style.borderStyle = 'none' } clearTimeout(shareTimeout) shareTimeout = setTimeout(() => { btn.textContent = btn.dataset.originalContent btn.style.borderStyle = 'solid' delete btn.dataset.originalContent shareTimeout = undefined }, 3e3) }, () => { alert( 'Impossible de copier le lien dans le presse-papiers :\n\nhttps://chat-jai-pete.fr' ) } ) } else { alert('Impossible de partager') } } function getCookie(name) { const nameEq = name + '=' const ca = document.cookie.split(';') for (let i = 0; i < ca.length; i++) { let c = ca[i] while (c.charAt(0) == ' ') { c = c.substring(1, c.length) } if (c.indexOf(nameEq) == 0) { return c.substring(nameEq.length, c.length) } } return null } function setCookie(name, value, days = 365) { const date = new Date() date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000) const expires = '; expires=' + date.toUTCString() document.cookie = name + '=' + (value || '') + expires + '; path=/' } function deleteCookie(name) { document.cookie = `${name}=; Max-Age=0` }