const totalElementsToLoad = 2; var totalElementsLoaded = 0; var mainIndex = {}; var productPathUri = ''; var indexValues = {}; var contactPageBottomContent = ''; var productIdFound = {}; var searchResults = {}; var productInfo = {}; var indexMenu = {}; var announcementsContent = {}; var announcementToShow = false; var synthesisActiveVoice = null; var playbackType = null; var playbackLang = 'pt-BR'; var leafletStatus = { patient: true, healthcare: true } var playbackStatus = { patient: false, healthcare: false }; var synthesisLeafletTexts = { patient: null, healthcare: null }; const init = () => { console.log('[RIEP] Initializing the RIEP data'); if (indexValues.length === 0) { showNotPageError(403, '[RIEP] Missing setup information'); return; } document.getElementById('contact-content').innerHTML = contactPageBottomContent; document.getElementById('footer-year').innerHTML = new Date().getFullYear(); mainIndex = lunr(function () { this.ref('id') this.field('url') this.field('name') this.field('id') indexValues.forEach((product) => { this.add(product) }, this) }) showIndexMenuWith(indexValues); if (!productPathUri) { return showSearchPage(); } searchResults = mainIndex.search(productPathUri); if (searchResults.length === 0) { return showSearchPage(); } productIdFound = searchResults[0]['ref']; let productJsonPath = window.indexJsonPath.replace('index.json', `products/${productIdFound}.json`); console.log('[RIEP] Fechting product information...') fetchJson(productJsonPath) .then(json => { productInfo = json; setupProductPage(); setupDebugBar(); }); } const displayPageWarn = (message) => { document.getElementById('warning').innerHTML = `${message}`; } const showIndexMenuWith = (index) => { document.getElementById('products-list').innerHTML = index.filter((e) => e.name !== undefined).map((el) => { return `
  • ${el.name}
  • `; }).join(''); } const search = (e) => { e.preventDefault(); let value = e.target.querySelector('input').value; let results = mainIndex.search(value); showIndexMenuWith(results.map((result) => { return indexValues.find((e) => e.id === parseInt(result.ref)); })); } const loadedElementsCheck = () => { totalElementsLoaded++ console.log(`[RIEP] Loaded ${totalElementsLoaded}/${totalElementsToLoad} elements`); if (totalElementsLoaded === totalElementsToLoad) { init(); } } const showNotPageError = (errorCode, errorMessage) => { document.getElementsByTagName('body')[0].classList.add('show-error'); let errorBlock = document.getElementById('error-content'); errorBlock.querySelector('.error-code').innerHTML = errorCode; errorBlock.querySelector('.error-message').innerHTML = errorMessage; } const setupProductPage = async () => { console.log('[RIEP] Setup start ID:', productInfo.id) document.title = `${window.siteName} Bulas - ${productInfo.title}` let tagElement = document.querySelector('.tag-type'); if (productInfo.tags.length > 0) { tagElement.innerHTML = productInfo.tags[0].name tagElement.className = `tag-type ${productInfo.tags[0].slug}`; } else { tagElement.style.display = 'none'; } let metadataValues = productInfo.metadata; let pathReference = location.href.indexOf('/preview') !== -1 ? '/' : ''; leafletStatus.patient = !(!productInfo.metadata.patientLeaflet || productInfo.metadata.patientLeaflet === ""); leafletStatus.healthcare = !(!productInfo.metadata.healthcareLeaflet || productInfo.metadata.healthcareLeaflet === ""); if (!leafletStatus.patient || !leafletStatus.healthcare) { document.querySelector(".btn.leaflet-modal-btn").remove(); if (productInfo.metadata.patientLeaflet && productInfo.metadata.patientLeaflet !== "") { document.querySelector("#btn-ler-bula-paciente").classList.remove('hidden') } if (productInfo.metadata.healthcareLeaflet && productInfo.metadata.healthcareLeaflet !== "") { document.querySelector("#btn-ler-bula-profissional-saude").classList.remove('hidden') } } document.querySelectorAll('.fill').forEach((element) => { let className = element.className; if (className.indexOf('title') !== -1) { element.innerHTML = productInfo.title return; } if (className.indexOf('published_at') !== -1) { element.innerHTML = productInfo.published_at return; } if (className.indexOf('packageImage') !== -1) { let imageElement = element.querySelector('img'); let packageImageReference = location.href.indexOf('/preview') !== -1 ? '' : ''; imageElement.setAttribute('src', `${packageImageReference}${productInfo.metadata.packageImage}`); let altText = productInfo.metadata.packageImageAlt ? productInfo.metadata.packageImageAlt : 'Foto da caixa do produto'; imageElement.setAttribute('alt', altText); return; } if (className.indexOf('patientLeaflet') !== -1 && productInfo.metadata.patientLeaflet !== '') { let leafletPath = window.indexJsonPath.replace(`${pathReference}index.json`, productInfo.metadata.patientLeaflet); const hrefValue = (location.href.indexOf('/preview') !== -1 ? '' : '.') + leafletPath; element.setAttribute('href', hrefValue); document.querySelector('#btn-ler-bula-paciente').setAttribute('href', hrefValue); return; } if (className.indexOf('patientLeaflet') !== -1 && productInfo.metadata.patientLeaflet === '') { element.remove(); return; } if (className.indexOf('healthcareLeaflet') !== -1 && productInfo.metadata.healthcareLeaflet !== '') { let leafletPath = window.indexJsonPath.replace(`${pathReference}index.json`, productInfo.metadata.healthcareLeaflet); const hrefValue = (location.href.indexOf('/preview') !== -1 ? '' : '.') + leafletPath; element.setAttribute('href', hrefValue); document.querySelector('#btn-ler-bula-profissional-saude').setAttribute('href', hrefValue); return; } if (className.indexOf('healthcareLeaflet') !== -1 && productInfo.metadata.healthcareLeaflet === '') { element.remove(); return; } if (className.indexOf('announcementPagesRelated') !== -1) { let now = new Date(); let announcementModalElement = document.querySelector('.modal.announcement-modal'); let announcementUrls = Object.values(productInfo.metadata.announcementPagesRelated).filter((announcement) => { if (announcement.date === '') return true; let parts = announcement.date.split('/'); let date = new Date(`${parts[2]}-${parts[1]}-${parts[0]}`); date.setDate(date.getDate() + 1); return date > now; }).map((announcement) => { let path = document.URL.slice(0, document.URL.indexOf('?path=')) + `${pathReference}announcements/${announcement.id}.html`; if (location.href.indexOf('/preview') !== false) { path = path.replace('/preview', '/file-preview'); } return path; }); if (announcementUrls.length === 0) { document.querySelector('.announcement-modal-btn').remove(); } else { Promise.all(announcementUrls.map((u) => fetch(u).then((e) => { return e.text(); }))).then((contentsArray) => { announcementsContent = contentsArray.map((content, index) => { let parts = announcementUrls[index].substring(announcementUrls[index].indexOf('/announcements/') + 15).split('.'); let date = productInfo.metadata.announcementPagesRelated[index].date; let title = content.match(/

    (.*?)<\/h1>/); if (title) { title = title[1]; } return { id: parts[0], title: title, date: date, content: content, } }).filter((a) => a.title) announcementModalElement.querySelector('ul.announcementPagesRelated') .innerHTML = announcementsContent.map((a) => { return `
  • ${a.title} Clique aqui para conferir este comunicado na íntegra.
  • `; }).join(''); announcementModalElement.classList.add('show'); announcementModalElement.querySelectorAll('a.announcement-link').forEach((e) => { e.addEventListener('click', showAnnouncementPage); }) }) } return; } className = className.split(' '); let fieldName = className.pop(); let valueElement = element.querySelector('.value'); if (!valueElement) { console.warn('Field not found', fieldName); return } valueElement.innerHTML = metadataValues[fieldName]; }) console.log('[Synthesis] checking Synthesis browser feature...'); if (!'speechSynthesis' in window) { displayPageWarn('[Synthesis] Text-to-speech not supported.'); console.error('[Synthesis] Text-to-speech not supported.'); return } else { console.info('[Synthesis] Text-to-speech supported.'); } if (speechSynthesis.getVoices().length === 0) { window.speechSynthesis.addEventListener("voiceschanged", () => { setupSynthesis(() => { console.log('[RIEP] Setup done for product ID:', productInfo.id) }); }); } else { setupSynthesis(() => { console.log('[RIEP] Setup done for product ID:', productInfo.id) }); } } const showSearchPage = () => { setupDebugBar(); document.getElementsByTagName('body')[0].classList.add('show-search') } const goBackToProduct = () => { document.getElementsByTagName('body')[0].classList.remove('show-announcement') } const showAnnouncementPage = (event) => { let announcementId = event.target.getAttribute('ref'); let announcement = announcementsContent.find((c) => c.id === announcementId); if (!announcement) { console.error('[RIEP] Missing announcement file'); return } ; document.getElementsByTagName('body')[0].classList.add('show-announcement'); document.getElementById('announcements-content').querySelector('.content').innerHTML = announcement.content; } const setupDebugBar = () => { console.log('[DEBUG] Setup debug bar'); let debugbar = document.getElementById('debug-bar'); if (!debugbar) return; debugbar.querySelector('.toggle-debug').addEventListener('click', () => debugbar.classList.toggle('hidden')); document.getElementById('index-values').innerHTML = JSON.stringify(indexValues, null, 2); debugbar.querySelector('.show-index').addEventListener('click', () => document.getElementById('index-values').classList.toggle('show')); document.getElementById('search-debug').innerHTML = JSON.stringify(searchResults, null, 2); debugbar.querySelector('.show-results').addEventListener('click', () => document.getElementById('search-debug').classList.toggle('show')); document.getElementById('product-debug').innerHTML = JSON.stringify(productInfo, null, 2); debugbar.querySelector('.show-product').addEventListener('click', () => document.getElementById('product-debug').classList.toggle('show')); debugbar.querySelector('.product-path').innerHTML = productPathUri; debugbar.querySelector('.product-id').innerHTML = productIdFound; debugbar.querySelector('.index-status').innerHTML = `total of indexed values [${indexValues.length}]`; debugbar.querySelector('.active-route-name').innerHTML = productPathUri ? 'product' : 'search'; } const fetchJson = async (path) => { if (!path) return false; return fetch(path) .then((response) => { if (!response.ok) { console.error(response.status); if (response.status === 404) { showNotPageError(404, 'Produto não encontrado'); } else { showNotPageError(500, 'Erro desconhecido'); } throw new Error("HTTP error " + response.status); } return response.json(); }); } const setPlaybackStatus = (type, status, turnOff) => { if (turnOff === true) { window.speechSynthesis.pause(); Object.keys(playbackStatus).forEach((t) => { document.querySelectorAll(`.${t}LeafletHear i.play-state`).forEach((e) => e.classList.remove('playing')); playbackStatus[t] = false }); return; } playbackStatus[type] = status; let iconSelector = document.querySelectorAll(`.${type}LeafletHear i.play-state`); if (status) { iconSelector.forEach(e => e.classList.add('playing')); } if (!status) { iconSelector.forEach(e => e.classList.remove('playing')); } let other = Object.keys(playbackStatus).filter((t) => t !== type).join(''); iconSelector = document.querySelectorAll(`.${other}LeafletHear i.play-state`); if (playbackStatus[other]) { iconSelector.forEach(e => e.classList.remove('playing')); } } const hearLeaflet = async (type) => { if (!type) { console.error('[RIEP] Hear leaflet no type', type); return; } else { console.info('[RIEP] leaflet type: ', type); } if (playbackType === type && playbackStatus[type]) { console.log('|| pause', type) setPlaybackStatus(type, false); if (window.innerWidth < 768) { return window.speechSynthesis.cancel(); } return window.speechSynthesis.pause(); } if (playbackType === type && !playbackStatus[type]) { console.log('|> resume', type) setPlaybackStatus(type, true); if (window.innerWidth > 768) { return window.speechSynthesis.resume(); } } if (playbackType && playbackType !== type) { console.log('[] cancel', type) setPlaybackStatus(type, false); window.speechSynthesis.cancel(); } playbackType = type; for (let i in synthesisLeafletTexts[type]) { let utterance = new SpeechSynthesisUtterance(); utterance.lang = playbackLang; utterance.pitch = 1; utterance.rate = 1; utterance.volume = 1; utterance.text = synthesisLeafletTexts[type][i].trim(); window.speechSynthesis.speak(utterance); if (i === synthesisLeafletTexts[type].length - 1) { setPlaybackStatus(type, true); } } if (window.speechSynthesis.pending) { console.warn('pending browser readings, force resume...'); window.speechSynthesis.pause(); window.speechSynthesis.resume(); } setPlaybackStatus(type, true); console.log('[> play', type); } const setupSynthesis = async (callback) => { console.log('[Synthesis] Setup Text-to-speech...'); document.querySelector("a.patientLeafletHear").classList.add("loading"); document.querySelector("a.healthcareLeafletHear").classList.add("loading"); synthesisActiveVoice = window.speechSynthesis.getVoices().find((voice) => voice.lang === "pt-BR"); if (!synthesisActiveVoice) { console.warn("[Synthesis] cant find tts voice using default language pt-BR"); } else { console.log("[Synthesis] Selected voice", { name: synthesisActiveVoice.name, lang: synthesisActiveVoice.lang, uri: synthesisActiveVoice.voiceURI, local: synthesisActiveVoice.localService, default: synthesisActiveVoice.default, }); } let imageReference = location.href.indexOf('/preview') !== -1 ? '/' : ''; let imageReferenceLocal = location.href.indexOf('/preview') !== -1 ? '' : '.'; let fetchArray = []; console.log('[Synthesis] Listing leaflet texts...'); const patientUrlToTxt = window.indexJsonPath.replace(`${imageReference}index.json`, `${imageReferenceLocal}/storage/leaflets/${productInfo.id}-patient.txt`); fetchArray.push(fetch(patientUrlToTxt).then((c) => { if (c.status !== 200) return ''; return c.text(); })); const healthcareToTxt = window.indexJsonPath.replace(`${imageReference}index.json`, `${imageReferenceLocal}/storage/leaflets/${productInfo.id}-healthcare.txt`); fetchArray.push(fetch(healthcareToTxt).then((c) => { if (c.status !== 200) return ''; return c.text(); })); if (fetchArray.length === 0) { callback(); } await Promise.all(fetchArray).then(([patientText, healthcareText]) => { console.warn('[Synthesis] leaflet status - patient:', leafletStatus.patient, ' healthcare:', leafletStatus.healthcare); console.warn('[Synthesis] Text Status - patient :', !!patientText, ' healthcare:', !!healthcareText); synthesisLeafletTexts.patient = leafletStatus.patient && !!patientText; synthesisLeafletTexts.healthcare = leafletStatus.healthcare && !!healthcareText; let patientBtnDirectElement = document.querySelector(".btn.btn-ouvir-bula-paciente-direct-riep"); let patientButtons = document.querySelectorAll(".btn.patientLeafletHear"); if (synthesisLeafletTexts.patient && !synthesisLeafletTexts.healthcare) { patientBtnDirectElement.classList.remove("hidden"); patientBtnDirectElement.classList.remove('loading'); } if (!synthesisLeafletTexts.patient) { patientButtons.forEach(el => el.remove()) } else { patientButtons.forEach(el => el.addEventListener("click", (event) => hearLeaflet("patient", event))) } let healthcareBtnDirectElement = document.querySelector(".btn.btn-ouvir-bula-profissional-saude-direct-riep"); let healthcareButtons = document.querySelectorAll(".btn.healthcareLeafletHear"); if (!synthesisLeafletTexts.patient && synthesisLeafletTexts.healthcare) { healthcareBtnDirectElement.classList.remove("hidden"); healthcareBtnDirectElement.classList.remove('loading'); } if (!synthesisLeafletTexts.healthcare) { healthcareButtons.forEach(el => el.remove()) } else { healthcareButtons.forEach(el => el.addEventListener("click", (event) => hearLeaflet("healthcare", event))) } if (!synthesisLeafletTexts.patient && !synthesisLeafletTexts.healthcare) { console.log('Both leaflets has text version, hiding both buttons'); document.querySelector(".btn-group .btn-ouvir-bula-profissional-saude-riep")?.remove(); document.querySelector(".btn-group .btn-ouvir-bula-paciente-riep")?.remove(); } if (!synthesisLeafletTexts.patient || !synthesisLeafletTexts.healthcare) { console.log('One of leaflets doesnt has text version, hiding modal button'); document.querySelector(".btn-group .btn-ouvir-bula-modal-riep")?.remove(); } Object.keys(synthesisLeafletTexts).filter((type) => synthesisLeafletTexts[type]).forEach((type) => { const content = type === 'patient' ? patientText : healthcareText let text = content.replace(/<\/?[^>]+(>|$)/g, ""); synthesisLeafletTexts[type] = text.split(/\. |\n|, |:|!/).filter(line => line.trim().length > 0); }) }) } const setupRequirements = () => { let urlParts = Object.values(location.search.substring(1).split('&')).find((param) => param.indexOf('path=') !== -1); if (urlParts) { productPathUri = urlParts.replace('path=', ''); } let libScript = document.createElement('script'); libScript.onload = loadedElementsCheck; libScript.src = window.lunrPath; document.getElementsByTagName('body')[0].appendChild(libScript); document.querySelector('.leaflet-modal-btn').addEventListener('click', () => { document.querySelector('.modal.leaflet-modal').classList.add('show'); }) document.querySelector('.audio-modal-btn').addEventListener('click', () => { document.querySelector('.modal.audio-modal').classList.add('show'); }) document.querySelector('.announcement-modal-btn').addEventListener('click', () => { document.querySelector('.modal.announcement-modal').classList.add('show'); }) document.querySelectorAll('.modal .backdrop').forEach((modalElement) => { modalElement.addEventListener('click', (event) => { event.target.parentNode.classList.remove('show'); setPlaybackStatus(null, null, true); }) }) document.querySelectorAll('.modal .close-btn').forEach((modalElement) => { modalElement.addEventListener('click', (event) => { event.target.parentNode.parentNode.parentNode.classList.remove('show'); setPlaybackStatus(null, null, true); }) }) document.getElementById('search-form').addEventListener('submit', search); document.querySelector('.nav-bar .back-btn').addEventListener('click', goBackToProduct); Promise.all([ fetchJson(window.indexJsonPath) .then(json => { return json }), fetch(window.indexJsonPath.replace('index.json', 'contact.html')) .then(content => { return content.text(); }) ]).then(([indexJson, contactHtml]) => { contactPageBottomContent = contactHtml indexValues = indexJson; loadedElementsCheck(); }) .catch((res) => { console.error(res); }) } window.addEventListener('DOMContentLoaded', () => setupRequirements()) if (document.getElementsByName('robots').length === 0) { let noIndexElement = document.createElement('meta'); noIndexElement.name = "robots" noIndexElement.content = "noindex"; document.head.appendChild(noIndexElement); }