(()=>{ let dermObj = dml_fmc; let initialized = false; dermObj.urlObj = new URL(window.location.href); dermObj.urlObj.searchParams.delete('cnst'); dermObj.urlObj.searchParams.delete('imupld'); dermObj.newUrl = dermObj.urlObj.toString(); history.replaceState({}, '', dermObj.newUrl); dermObj.config = { chat: { enabled: false, key: 'none', depId: '' }, forcedPage: '', forcedCountry: '', forcedLanguage: '', histFmcObj: true, percMatchFolder: '', useDioxideStaging: false, maxConcerns: 6, showQniConsentButton: true, qniChoiceFromLanding: false, quizNoImage: false, quizAfterImage: false, userImgOnly: false, crm: { enabled: false, country: '' }, badges: {}, pageDict:{ 'loading' : 'fmc_loading_page_default', 'landing' : 'fmc_landing_page_default', 'onboarding' : 'fmc_onboarding_page_default', 'capture' : 'fmc_capture_page_default', "quiz_after_image" : 'fmc_qai_page_default', 'waiting' : 'fmc_waiting_page_default', 'results' : 'fmc_results_prep_treat_glow' }, useTreatmentBanners : false, blogs_file : '', useShopify: false, use2FA: false, requestEmailForResults : false, showSaveEmailMobile: false, hideEmailButtons: false, emailDoubleCheckbox : false, emailSubjectOverride: '', langForBackends: '', skipMasks : false, shopButton : { textOverride : "", showPrices : false, hide: false }, storeLocator: { extraParameters: "", regexFilter: "", showStores: false }, brandingLogoUrl : '', brandingLogoUrlGrey : '', brandingLogoScale : 1 , useAgGeFaceApiFeature : false, useLightening: true, sentrySampleRate: 0.01, useSentry: true } if (dermObj.isPercMatchMiniPage == undefined){ dermObj.isPercMatchMiniPage = false; } // adding url parameter for face model or age bucket question const fmAgGeVer = window.localStorage.getItem('fmAgGeVer'); if (fmAgGeVer == '0'){ dermObj.config.useAgGeFaceApiFeature = false; }else if (fmAgGeVer == '1'){ dermObj.config.useAgGeFaceApiFeature = true; }else{ dermObj.config.useAgGeFaceApiFeature = Math.random() < 0.5; } if (dermObj.isPercMatchMiniPage == true){ dermObj.config.useAgGeFaceApiFeature = false; } (async ()=>{ let consInt = setInterval(async ()=>{ if (typeof dermObj.checkCookieConsent == 'function'){ clearInterval(consInt); await dermObj.checkCookieConsent() if (dermObj.config.allowCookies){ if (dermObj.config.useAgGeFaceApiFeature){ window.localStorage.setItem('fmAgGeVer','1'); }else{ window.localStorage.setItem('fmAgGeVer','0'); } } } },500) })(); dermObj.addUrlParameter = (key, value) => { let urlObject = new URL(window.location.href); let params = urlObject.searchParams; params.set(key, value); // This will automatically handle existing parameters return urlObject.toString(); } if (dermObj.isPercMatchMiniPage != true){ let newUrl; if (dermObj.config.useAgGeFaceApiFeature){ newUrl = dermObj.addUrlParameter('4gD3v',1) }else{ newUrl = dermObj.addUrlParameter('4gD3v',0) } window.history.replaceState({}, '', newUrl); } dermObj.referrer = window.location.href.split('?')[0] if (window.location.search.indexOf('forced_page=') > -1){ try{ dermObj.config.forcedPage = decodeURIComponent(window.location.search.split('forced_page=')[1].split('&')[0]); }catch(err){console.error(err)} } if (window.location.search.indexOf('forced_country=') > -1){ dermObj.config.forcedCountry = window.location.search.split('forced_country=')[1].split('&')[0]; } if (window.location.search.indexOf("forced_lang=") >-1 ){ dermObj.config.forcedLanguage = window.location.search.split("forced_lang=")[1].split("&")[0]; } if (window.location.search.indexOf("rspg=") >-1 ){ try{ const forcedResultsPage = window.location.search.split("rspg=")[1].split("&")[0]; if (dermObj.body.querySelectorAll('.fmc_page').map((fmcPage) => {return fmcPage.id}).includes(forcedResultsPage)){ dermObj.config.pageDict.results = forcedResultsPage; } }catch(err){} } if (window.location.search.indexOf("qni=1") >-1 ){ dermObj.config.quizNoImage = true; } if (window.location.search.indexOf('force_qai=1') > -1){ localStorage.removeItem('fmc_qai'); dermObj.config.quizAfterImage = true; } if (window.location.search.indexOf('force_qai=0') > -1){ localStorage.removeItem('fmc_qai'); dermObj.config.quizAfterImage = false; } dermObj.getGDPR = ()=>{ return new Promise(async (resolve, reject)=>{ const backends = { us_v2 : "https://global.facemapping.me", stg_v2 : "https://staging.facemapping.me", eu_v2 : "https://eu.facemapping.me", ca_v2 : "https://ca.facemapping.me", us : "https://fmc-backend-production.herokuapp.com", eu : "https://imb-backend-eu.herokuapp.com", ca : "https://imb-backend-ca.herokuapp.com", stg : "https://fmc-backend-staging.herokuapp.com" } const countriesUsingBackendEU = ["BE", "EL", "LT", "PT", "BG", "ES", "LU", "RO", "CZ", "FR", "HU", "SI", "DK", "HR", "MT", "SK", "DE", "IT", "NL", "FI", "EE", "CY", "AT", "SE", "IE", "LV", "PL", "IS", "NO", "LI", "CH", "GB"]; const lang_code = dermObj.config.langForBackends == '' ? dermObj.lang_code : dermObj.config.langForBackends; const xhr = new XMLHttpRequest(); let endpointUsed = ''; let endpointLabel = ''; if (Math.random() < 0.5){ endpointUsed = `https://gdpr.facemapping.me/get_country_gdpr/?lang_code=${lang_code}`; endpointLabel = 'gdpr.facemapping.me'; }else{ endpointUsed = `https://fmc-backend-production.herokuapp.com/get_country_gdpr/?lang_code=${lang_code}`; endpointLabel = 'fmc-backend-production.herokuapp.com'; } let fetchRepObj={} fetch(endpointUsed, { method: 'GET', headers: { 'Content-Type' : 'application/x-www-form-urlencoded' } }) .then(response => { fetchRepObj = { 'status': response.status, 'statusText': response.statusText, 'requestedURL': response.url, 'endpoint_used': endpointUsed }; if (!response.ok) { throw new Error(`Error in reaching the GDPR endpoint - ${endpointLabel}`); } return response.json(); }) .then(gdprRes => { dermObj.debug("success GDPR call", gdprRes); dermObj.gdprLegalCopy = gdprRes.legal_copy; if (dermObj.config.forcedCountry){ dermObj.countryCode = dermObj.config.forcedCountry; }else{ dermObj.countryCode = gdprRes.country_code; } if (dermObj.countryCode == 'IT'){ dermObj.body.querySelector('#fmc_legal_scroll_container_italy').style.display = 'block'; dermObj.body.querySelector('#fmc_legal_container_default').style.display = 'none'; } let be_code="us"; if (dermObj.countryCode == 'US'){ dermObj.config.use2FA = true; //console.log(gdprRes) if (gdprRes.state == 'IL'){ //be_code="us"; } if (gdprRes.state == 'OR' && gdprRes.city == 'Portland'){ dermObj.config.quizNoImage = true; } if (gdprRes.state == 'MD' && gdprRes.city == 'Baltimore'){ dermObj.config.quizNoImage = true; } } if (window.location.search.indexOf("forced_be=") > -1){ be_code = window.location.search.split("forced_be=")[1].split("&")[0]; }else{ if (countriesUsingBackendEU.includes(dermObj.countryCode)) be_code = "eu"; if (dermObj.countryCode == "CA") be_code="ca"; } if (countriesUsingBackendEU.includes(dermObj.countryCode)){ dermObj.body.querySelector('#fmc_manageCookiebotLink').style.opacity = 1; dermObj.body.querySelector('#fmc_manageCookiebotLink').style.pointerEvents = 'all'; } if (["eu", "ca"].includes(be_code)){ try{ dermObj.body.querySelectorAll('.fmc_subscribe_checkbox_label').forEach((checkBox)=>{ checkBox.checked=false; }) }catch(err){ console.warn(err) } }else{ dermObj.body.querySelectorAll('.fmc_subscribe_checkbox_label').forEach((checkBox)=>{ checkBox.checked=true; }) } if (dermObj.config.useLightening === true) { be_code += '_v2'; //dermObj.config.sendAlsoToNewEmailEndpoint = false; } if ('https://fmc-backend-production.herokuapp.com'=='https://staging.facemapping.me'){ be_code = 'stg_v2' } if ('https://fmc-backend-production.herokuapp.com'=='https://fmc-backend-staging.herokuapp.com'){ be_code = 'stg' } if (window.location.search.indexOf('be=') > -1 && window.location.search.indexOf('forced_be=') < 0){ be_code = window.location.search.split("be=")[1].split("&")[0]; } if (be_code.indexOf('_v2') > -1){ dermObj.config.sendAlsoToNewEmailEndpoint = false; dermObj.config.useLightening = true; } dermObj.backend = backends[be_code] || backends["us"]; dermObj.sendGA360("main flow",`backend used - ${dermObj.backend}`); dermObj.sendGAFlowEvent(`backend used - ${dermObj.backend}`); resolve(); }) .catch(error => { const extraContext = { 'function_info':{ 'file':'gdpr_controls.ejs', 'function':'getGDPR', 'context': `error in calling the GDPR endpoint - ${error.name} - ${error.message}` }, 'fetch': fetchRepObj } const err = new Error(`Error in reaching the GDPR endpoint - ${endpointLabel} - ${error.name} - ${error.message}`); err.event = error; dermObj.sentry.errorWrapper(err, extraContext) reject(); }); }); } dermObj.applyLegalText = ()=>{ const legalTextFields = ["legal_text_top", "legal_text_consent", "legal_text_bottom", "legal_text_extra_statement"]; legalTextFields.forEach((legalTextField)=>{ document.querySelectorAll(`[data-widget-legal-term=${legalTextField}]`).forEach((htmlEl)=>{ try{ htmlEl.innerHTML = dermObj.gdprLegalCopy[legalTextField]; }catch(e){ console.error(e); } }); }); setTimeout(()=>{ const extraToggleButton = document.getElementById("dml_fmc_privacy_statment"); if (extraToggleButton != null){ extraToggleButton.addEventListener('click',dermObj.toggleLegalExtraText); } },200) /* // TODO - REMOVE IN CASE OF MORE TRANSLATIONS if (["en-US","en-NZ","en-GB"].indexOf(dermObj.lang_code) < 0 ){ document.querySelectorAll("#fmc_consent_accept_text").forEach((consentButtonText)=>{ consentButtonText.style.display = "none"; }) document.querySelectorAll("#fmc_consent_accept_icon").forEach((consentButtonIcon)=>{ consentButtonIcon.style.display = "block"; }) } */ } dermObj.toggleLegalExtraText = ()=>{ document.querySelector('#fmc_legal_overlay .fmc_legal_content_collapsable').classList.toggle('fmc_legal_content_hidden'); document.querySelector('#fmc_legal_overlay .fmc_legal_content_collapsable').scrollIntoView({'behavior':'smooth'}); document.querySelector('#fmc_legal_overlay .fmc_legal_scroll_container').classList.toggle('fmc_show_scrollbar'); } dermObj.showConsent = ()=>{ document.getElementById('fmc_legal_overlay').style.display = "flex"; dermObj.sendGA360("main flow","open consent with CTA"); dermObj.sendGAFlowEvent("open consent with CTA"); } dermObj.consentClicked = ()=>{ document.getElementById('fmc_legal_overlay').style.display = "none"; dermObj.sendGA360("main flow","consent clicked"); dermObj.sendGAFlowEvent("consent clicked"); if (dermObj.permissionBeforeFormerResults){ dermObj.loadingFormerResultAfterPermission(); }else{ dermObj.gotoPage("capture"); const urlObj = new URL(window.location.href); if (!urlObj.searchParams.has('cnst')) { urlObj.searchParams.set('cnst', 1); const newUrl = urlObj.toString(); history.pushState({}, '', newUrl); } } } dermObj.consentCanceled = ()=>{ document.getElementById('fmc_legal_overlay').style.display = "none"; dermObj.sendGA360("main flow","consent canceled"); dermObj.sendGAFlowEvent("consent canceled"); } dermObj.checkLegalCheckboxesIT = async ()=>{ const italyCheckboxes = Array.from(dermObj.body.querySelectorAll('#fmc_legal_scroll_container_italy input[type=checkbox]')); let activateConsentButton = true; italyCheckboxes.forEach((checkBox) => { activateConsentButton = activateConsentButton && checkBox.checked; }) if (activateConsentButton){ dermObj.body.querySelector('#fmc_consent_accept_button_italy').classList.remove('fmc_inactive'); }else{ dermObj.body.querySelector('#fmc_consent_accept_button_italy').classList.add('fmc_inactive'); } } dermObj.sendGAFlowEvent = (actionString) => { const eventParameters = { action : actionString, page_location: window.location.hostname, page_path: window.location.pathname, page_title: dermObj.currentPage } dermObj.sendGA4("user_flow",eventParameters); } dermObj.sendGAUserClickEvent = (actionString) => { const eventParameters = { action : actionString, page_location: window.location.hostname, page_path: window.location.pathname, page_title: dermObj.currentPage } dermObj.sendGA4("user_click",eventParameters); } dermObj.sentry = {} dermObj.sentry.loaded = false dermObj.sentry.pending = false; dermObj.sentry.sentryBtsClient dermObj.sentry.sentryBtsHub dermObj.sentry.loadScript = function() { dermObj.sentry.pending = true; let script = document.createElement('script'); script.defer = 1; script.crossorigin = "anonymous"; let sampleRate = dermObj.config.sentrySampleRate; script.onload = function(evt) { //console.log('sentry script loaded - ', evt); const defaultIntegrations = Sentry.defaultIntegrations; const integrationsToRemove = ['GlobalHandlers', 'Breadcrumbs', 'TryCatch']; const filteredIntegrations = defaultIntegrations.filter(integration => !integrationsToRemove.includes(integration.name)); dermObj.sentry.sentryBtsClient = new Sentry.BrowserClient({ dsn: "https://bb80ec4e4a764eed95a8d8582c57f6d6@o220176.ingest.sentry.io/1771446", tracesSampleRate: sampleRate, autoSessionTracking: false, transport: Sentry.makeFetchTransport, integrations: filteredIntegrations, beforeSend(event) { // Check if the error has a custom tag 'manualReport' if (event.tags && event.tags.customManualReport) { // If the tag is present, allow the error to be reported return event; } // If the tag is not present, ignore the error return null; } }); dermObj.sentry.sentryBtsHub = new Sentry.Hub(dermObj.sentry.sentryBtsClient); dermObj.sentry.loaded = true; dermObj.sentry.pending = false; }; script.onerror = function(err){ console.error(err) } script.setAttribute('type','text/javascript'); //script.integrity="sha384-5Zu44WQLIjQtAmHoeW6zq6diH9kymV7kGUaYAV1PK5LPCSGURU7y840OHlpaU8NQ" script.src = "https://browser.sentry-cdn.com/7.60.0/bundle.min.js" // error bundle only dermObj.widget_wrapper.appendChild(script); } dermObj.sentry.triggerTestError = ()=>{ try{ triggerTestDueUndefinedFunction(); }catch(err){ const extraContext = { 'function_info':{ 'file':'sentry.ejs', 'function':'triggerTestError', 'context': 'test error to manual trigger a test message' } } dermObj.sentry.errorWrapper(err, extraContext); } }; dermObj.sentry.errorWrapper = function(err, extraContext = {}){ if (dermObj.sentry.loaded === false && dermObj.sentry.pending === false) { console.error(err); return; }; if (dermObj.sentry.loaded === false && dermObj.sentry.pending === true){ setTimeout(()=>{ dermObj.sentry.errorWrapper(err,extraContext); },500) return; } console.error(err); try{ dermObj.sentry.sentryBtsHub.withScope((scope)=>{ scope.setTag('customManualReport',true); scope.setContext("browser_data", { userAgent: navigator.userAgent, url: window.location.href, }); try{ if ( Object.keys(extraContext).length > 0 ){ Object.keys(extraContext).forEach((contextName)=>{ scope.setContext(contextName, extraContext[contextName]); }) } }catch(err){} dermObj.sentry.sentryBtsHub.captureException(err); }) }catch(err){} } dermObj.processImage = async (base64image) => { return new Promise( async (resolve , reject)=>{ if (dermObj.imageUploadPending){ reject({status: 'failure', message: 'image upload pending'}) return; } dermObj.imageUploadPending = true; try{ const analyzeRes = await dermObj.uploadImage(base64image); dermObj.imageUploadPending = false; resolve(analyzeRes); }catch(err){ dermObj.imageUploadPending = false; reject(err); } }) } dermObj.uploadImage = async (base64image) => { return new Promise( async (resolve, reject) => { dermObj.analyzeRequestStatus = 'pending'; const xhr = new XMLHttpRequest(); dermObj.sendGA360("main flow","upload image submit"); dermObj.sendGAFlowEvent("upload image submit"); xhr.upload.onload = () => { console.log(`Upload completed - ${xhr.status} - ${xhr.response}`); const urlObj = new URL(window.location.href); if (!urlObj.searchParams.has('imupld')) { urlObj.searchParams.set('imupld', 1); const newUrl = urlObj.toString(); history.pushState({}, '', newUrl); } //resolve(xhr.response); } xhr.upload.onerror = () => { console.error('Upload failed - ',xhr); dermObj.analyzeRequestStatus = 'failed'; //reject("error") resolve({status: 'failed'}) } xhr.upload.onabort = () => { console.error('Upload aborted - ',xhr); dermObj.analyzeRequestStatus = 'failed'; reject("abort") } xhr.upload.onprogress = (event) => { console.log(`Uploaded ${event.loaded} of ${event.total} bytes`); } xhr.onload = async () => { //console.log(`Request completed - ${xhr.status} - ${JSON.parse(xhr.response)}`); dermObj.analyzeRequestStatus = 'finished'; const parsedResponse = JSON.parse(xhr.response); dermObj.debug('Backend Response: ', parsedResponse); if (parsedResponse.revieve_response == undefined || parsedResponse.revieve_response == null){ if (dermObj.isPercMatchMiniPage != true){ dermObj.config.pageDict.results = 'fmc_estimated_results'; }else{ dermObj.pageControls.perc_match_coll.percMatchFailed = true; } } dermObj.dioxide_data= null; /* if (parsedResponse.dioxide_data != undefined && parsedResponse.dioxide_data != null){ try{ const refinedDioxideData = await dermObj.refineAndCleanDioxideData(parsedResponse.dioxide_data) parsedResponse.dioxide_data = refinedDioxideData; dermObj.dioxideData = {...parsedResponse.dioxide_data}; }catch(err){ console.error('error in refining backend dioxide data - ',err); } }else{ if (dermObj.isPercMatchMiniPage != true){ dermObj.config.pageDict.results = 'fmc_estimated_results'; }else{ dermObj.pageControls.perc_match_coll.percMatchFailed = true; } } */ resolve(parsedResponse); } xhr.onerror = () => { console.error('Upload failed - ',xhr); dermObj.analyzeRequestStatus = 'failed'; reject("error") } const payload = {}; payload.imageBase64 = base64image; try{ payload.ldTms = {...dermObj.ldTms}; }catch(err){ console.warn(err); } let referrerUrl = dermObj.referrer /* TO REMOVE IF CURRENT SOLUTION PROOFS WORKING let referrerUrl=""; try{ referrerUrl = window.location.href; if (referrerUrl.length < 5 || referrerUrl == undefined || referrerUrl == null){ referrerUrl = document.documentURI; } }catch(e){ referrerUrl = document.documentURI; } if (referrerUrl== "" || referrerUrl == undefined || referrerUrl == null){ referrerUrl = "URL_NOT_FOUND"; } if (dermObj.config.forcedPage != ''){ referrerUrl = dermObj.config.forcedPage; } */ if (dermObj.config.useAgGeFaceApiFeature === true){ try{ dermObj.pageControls.capture.ed6d4 = dermObj.capture.ed6d4; dermObj.pageControls.capture.b83d2 = dermObj.capture.b83d2; }catch(err){ console.log(error) } } try{ payload.ed6d4 = dermObj.pageControls.capture.ed6d4; payload.b83d2 = dermObj.pageControls.capture.b83d2; }catch(err){ console.log(error) } payload.referrer = referrerUrl; payload.browser = navigator.userAgent.slice(0,30); const langCodeToSend = dermObj.config.langForBackends == '' ? dermObj.lang_code : dermObj.config.langForBackends; payload.lang_code = langCodeToSend; payload.auto_capture = true; payload.os = 'os dummy value'; payload.dark_circles_score = dermObj.masks.darkCirclesScore; payload.dehydration_score = 2; if (dermObj.klaviyo.id != ''){ payload.learnq_id = dermObj.klaviyo.id; } if (dermObj.config.userImgOnly){ payload.s_i = false; } await dermObj.checkCookieConsent(); if (dermObj.config.allowCookies){ if (window.localStorage.getItem("dmlcid") != null){ try{ dermObj.customUID = Number(window.localStorage.getItem("dmlcid")); }catch(err){ dermObj.customUID = Date.now() + Math.round(Math.random()*100000); window.localStorage.setItem("dmlcid",dermObj.customUID); } }else{ dermObj.customUID = Date.now() + Math.round(Math.random()*100000); window.localStorage.setItem("dmlcid",dermObj.customUID); } }else{ dermObj.customUID = Date.now() + Math.round(Math.random()*100000); } payload.custom_uid = dermObj.customUID; xhr.open('POST', `${dermObj.backend}/fmc/analyze-v3?new_json=1&lang_code=${langCodeToSend}&custom_uid=${dermObj.customUID}`, true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.send(JSON.stringify(payload)); }) } dermObj.sendNoImageQuizResults = async (quizResults, revVals = {})=>{ return new Promise( async (resolve, reject) => { const xhr = new XMLHttpRequest(); dermObj.sendGA360("main flow","send no image quiz results"); dermObj.sendGAFlowEvent("send no image quiz results"); xhr.onload = async () => { //console.log(xhr.response) console.log(`Request completed - ${xhr.status} - ${JSON.parse(xhr.response)}`); const parsedResponse = JSON.parse(xhr.response); dermObj.debug('Backend Response: ', parsedResponse); if (parsedResponse.dioxide_data != undefined && parsedResponse.dioxide_data != null){ try{ //const refinedDioxideData = await dermObj.refineAndCleanDioxideData(parsedResponse.dioxide_data, 'prep_treat_glow'); //parsedResponse.dioxide_data = refinedDioxideData; }catch(err){ console.error('error in refining backend dioxide data - ',err); } } resolve(parsedResponse); } xhr.onerror = () => { console.error('Upload failed - ',xhr); reject("error") } const payload = {}; let referrerUrl= dermObj.referrer; /* TODO - remove if current solution proofs to be working let referrerUrl=""; try{ referrerUrl = window.location.href; if (referrerUrl.length < 5 || referrerUrl == undefined || referrerUrl == null){ referrerUrl = document.documentURI; } }catch(e){ referrerUrl = document.documentURI; } if (referrerUrl== "" || referrerUrl == undefined || referrerUrl == null){ referrerUrl = "URL_NOT_FOUND"; } if (dermObj.config.forcedPage != ''){ referrerUrl = dermObj.config.forcedPage; } */ payload.host_site = referrerUrl; payload.browser = navigator.userAgent.slice(0,30); payload.lang_code = dermObj.lang_code; payload.quiz_results = dml_dmlqz.surveyResults; payload.mapped_revieve_vals = revVals; await dermObj.checkCookieConsent(); if (dermObj.config.allowCookies){ if (window.localStorage.getItem("dmlcid") != null){ try{ dermObj.customUID = Number(window.localStorage.getItem("dmlcid")); }catch(err){ dermObj.customUID = Date.now() + Math.round(Math.random()*100000); window.localStorage.setItem("dmlcid",dermObj.customUID); } }else{ dermObj.customUID = Date.now() + Math.round(Math.random()*100000); window.localStorage.setItem("dmlcid",dermObj.customUID); } }else{ dermObj.customUID = Date.now() + Math.round(Math.random()*100000); } payload.custom_uid = dermObj.customUID; xhr.open('POST', `${dermObj.backend}/fmc/fmc_quiz_products`, true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.send(JSON.stringify(payload)); }) } dermObj.getFormerfmcResult = async(hashId, useLegacyBe = false)=>{ return new Promise( async(resolve, reject)=>{ if (dermObj.config.use2FA && dermObj.twofa.code == ''){ await dermObj.twofa.prompt(); } let backendLabel = "us"; if (window.location.search.indexOf("be=") > - 1){ backendLabel = window.location.search.split("be=")[1].split("&")[0]; }else{ backendLabel = dermObj.getBackendLabel(); } let urlParamString = ''; if (dermObj.twofa.code != ''){ urlParamString = `?access_code=${dermObj.twofa.code}`; } dermObj.twofa.code != ''; const xhr = new XMLHttpRequest(); xhr.open('GET', `${dermObj.backend}/fmc/get-skin-io/${hashId}${urlParamString}`,true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = async () => { //console.log(`Request completed - ${xhr.status} - ${JSON.parse(xhr.response)}`); let rawResponseData; try{ rawResponseData = JSON.parse(xhr.response); delete rawResponseData.concerns; delete rawResponseData.cropped_image; delete rawResponseData.skin_io_response; delete rawResponseData.skin_io_response_time; delete rawResponseData.recommendedProducts; delete rawResponseData.product_ids; }catch(err){ console.error(err); reject(err); return } if (rawResponseData.status == '400' || rawResponseData.status == 400 || rawResponseData.status == '404' || rawResponseData.status == 404){ if (rawResponseData.message.indexOf('Please supply the correct access code') > -1){ console.error(rawResponseData.message); reject(rawResponseData.message); } } if (rawResponseData.status == '500' || rawResponseData.status == 500 ){ console.error(rawResponseData.message); reject(rawResponseData.message); } if (rawResponseData.success == false){ if (!useLegacyBe){ rawResponseData = await dermObj.getFormerfmcResult(hashId, true); if (rawResponseData.status == 'failure'){ reject(rawResponseData); } }else{ resolve({status:'failure',reason:'id not found'}); } } let refinedResponseData; try{ refinedResponseData = await dermObj.refineData(rawResponseData); }catch(err){ console.error(err); reject(err); } if (refinedResponseData.dioxide_data != undefined && refinedResponseData.dioxide_data != null && window.location.search.indexOf('qni=1') < 0 ){ try{ const refinedDioxideData = await dermObj.refineAndCleanDioxideData(refinedResponseData.dioxide_data) refinedResponseData.dioxide_data = refinedDioxideData; }catch(err){ console.error('error in refining backend dioxide data - ',err); } } resolve(refinedResponseData); } xhr.onerror = (err) =>{ console.error(err); reject(err); } xhr.send(); }) } dermObj.refineData = async (rawData)=>{ const refinedData = {... rawData}; dermObj.rawData = rawData; //console.log(rawData) try{ refinedData.azure_age = Number(refinedData.azure_age); }catch(err){ refinedData.azure_age = null; } if (typeof refinedData.azure_response == 'string'){ refinedData.azure_response = JSON.parse(refinedData.azure_response.replace(/\'/g,'"').replace(/True/g,'true').replace(/False/g,'false')) } if (typeof refinedData.revieve_response == 'string'){ refinedData.revieve_response = JSON.parse(refinedData.revieve_response.replace(/w\'s/g,'w_s').replace(/\'/g,'"').replace(/True/g,'true').replace(/False/g,'false').replace(/None/g,'null')) } Object.keys(refinedData).forEach((key)=>{ if (key.indexOf('revieve_') > -1 && key.indexOf('_value') > -1){ refinedData[key] = refinedData[key] === null ? null : Number(refinedData[key]); } }); return refinedData; } dermObj.submitEmail = async ()=>{ if (dermObj.submitEmailPending){ return; } dermObj.submitEmailPending = true; setTimeout(()=>{ dermObj.submitEmailPending = false; },500) const usrEmail = document.getElementById('fmc_email_popup_input').value; const emailValid = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(usrEmail) if (emailValid){ dermObj.submitEmailToBackend(); document.getElementById("fmc_email_popup_hint").style.opacity = 0; document.getElementById("fmc_email_popup").style.display = 'none'; try{ const fmcSnapShot = await dermObj.getRevSnapShot(dermObj.backendData); dermObj.addUrlParameters(fmcSnapShot); await dermObj.checkCookieConsent(); if (dermObj.config.allowCookies){ dermObj.updateLocalStorage(fmcSnapShot); } }catch(err){ console.error(err) } dermObj.gotoPage('results'); }else{ document.getElementById("fmc_email_popup_hint").style.opacity = 1; } } dermObj.submitEmailToBackend = async () => { let subscribeChecked = false; if (dermObj.config.emailDoubleCheckbox == true){ subscribeChecked = dermObj.body.querySelector('#fmc_email_checkbox_gdpr1').checked; }else{ subscribeChecked = document.getElementById("fmc_email_checkbox").checked; } //if (dermObj.lang_code == 'en-US' || dermObj.lang_code == 'en-GB' || dermObj.lang_code == 'en-NZ' || dermObj.countryCode == 'US'){ //if ( ['en-US', 'en-GB', 'en-NZ', 'fr', 'ja-np'].includes(dermObj.lang_code) || dermObj.countryCode == 'US'){ if (dermObj.config.pageDict.results == 'fmc_results_prep_treat_glow'){ dermObj.debug('SEND PREP TREAT GLOW EMAIL'); try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "prep_treat_glow" ); }catch(err){ console.warn(err); } if (dermObj.config.sendAlsoToNewEmailEndpoint === true){ try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "prep_treat_glow", true ); }catch(err){ console.warn(err); } } }else if (dermObj.config.pageDict.results == 'fmc_estimated_results'){ dermObj.debug('SEND ESTIMATED RESULTS WITH PREP TREAT GLOW EMAIL TEMPLATE'); try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "estimated_results" ); }catch(err){ console.warn(err); } if (dermObj.config.sendAlsoToNewEmailEndpoint === true){ try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "estimated_results", true ); }catch(err){ console.warn(err); } } }else if (dermObj.config.pageDict.results == 'fmc_results_brand_campaign'){ dermObj.debug('BRAND CAMPAIGN EMAIL'); try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "brand_campaign" ); }catch(err){ console.warn(err); } if (dermObj.config.sendAlsoToNewEmailEndpoint === true){ try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "brand_campaign", true ); }catch(err){ console.warn(err); } } }else if (dermObj.config.pageDict.results == 'fmc_results_quiz_no_image'){ dermObj.debug('QUIZ NO IMAGE EMAIL'); try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "quiz_no_image" ); }catch(err){ console.warn(err); } if (dermObj.config.sendAlsoToNewEmailEndpoint === true){ try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "quiz_no_image", true ); }catch(err){ console.warn(err); } } }else{ dermObj.debug('DEFAULT EMAIL'); try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "results_default" ); }catch(err){ console.warn(err); } if (dermObj.config.sendAlsoToNewEmailEndpoint === true){ try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "results_default", true ); }catch(err){ console.warn(err); } } } } dermObj.getBackendLabel = ()=>{ let backendLabel; switch(dermObj.backend){ case "https://global.facemapping.me": backendLabel = "us_v2"; break; case "https://staging.facemapping.me": backendLabel = "stg_v2"; break; case "https://eu.facemapping.me": backendLabel = "eu_v2"; break; case "https://ca.facemapping.me": backendLabel = "ca_v2"; break; case "https://fmc-backend-staging.herokuapp.com": backendLabel = "stg"; break; case "https://imb-backend-eu.herokuapp.com": backendLabel = "eu"; break; case "https://imb-backend-ca.herokuapp.com": backendLabel = "ca"; break; default: backendLabel = "us" } return backendLabel; } dermObj.backendUrlFromLabel = (backendLabel)=>{ let backendUrl; switch(backendLabel){ case "us_v2": backendUrl = "https://global.facemapping.me"; break; case "stg_v2": backendUrl = "https://staging.facemapping.me"; break; case "eu_v2": backendUrl = "https://eu.facemapping.me"; break; case "ca_v2": backendUrl = "https://ca.facemapping.me"; break; case "stg": backendUrl = "https://fmc-backend-staging.herokuapp.com"; break; case "eu": backendUrl = "https://imb-backend-eu.herokuapp.com"; break; case "ca": backendUrl = "https://imb-backend-ca.herokuapp.com"; break; default: backendUrl = "https://fmc-backend-production.herokuapp.com" } return backendUrl; } dermObj.email = {}; dermObj.email.send = async (email, emailConsent, emailType = "results_default", useNewEndpoint = false) => { return new Promise( async (resolve, reject) => { let createdKlavPro = false; if (emailConsent == true && dermObj.config.klavyioId != '' && dermObj.config.klavyioId != undefined && dermObj.config.klavyioListId != '' && dermObj.config.klavyioListId != undefined ){ try{ await fetch(`https://a.klaviyo.com/client/profiles/?company_id=${dermObj.config.klavyioId}`,{ method: 'POST', headers: {revision: '2023-08-15', 'content-type': 'application/json'}, body: JSON.stringify({ data: { type: 'profile', //attributes: { //custom_source: 'FMC email form', //profile: { //data: { //type: 'profile', attributes: { email: email, properties: { FMC: "yes", FMC_created_at: Date.now(), FMC_uid: dermObj.backendData.hashid } } //} //} //} //relationships: {list: {data: {type: 'list', id: dermObj.config.klavyioListId}}} } }) }) await fetch(`https://a.klaviyo.com/client/subscriptions/?company_id=${dermObj.config.klavyioId}`,{ method: 'POST', headers: {revision: '2023-08-15', 'content-type': 'application/json'}, body: JSON.stringify({ data: { type: 'subscription', attributes: { custom_source: 'FMC email form', profile: { data: { type: 'profile', attributes: { email: email } } } }, relationships: {list: {data: {type: 'list', id: dermObj.config.klavyioListId}}} } }) }) createdKlavPro = true; }catch(err){ console.error(err) } } const xhr = new XMLHttpRequest(); xhr.upload.onload = () => { console.log(`Upload completed - ${xhr.status} - ${xhr.response}`); //resolve(xhr.response); } xhr.upload.onerror = () => { console.error('Upload failed - ',xhr); reject("error") } xhr.upload.onabort = () => { console.error('Upload aborted - ',xhr); reject("abort") } xhr.upload.onprogress = (event) => { console.log(`Uploaded ${event.loaded} of ${event.total} bytes`); } xhr.onload = () => { console.log(`Request completed - ${xhr.status} - ${JSON.parse(xhr.response)}`); resolve(JSON.parse(xhr.response)); if (emailConsent && dermObj.config.crm.enabled == true) { dermObj.crm.send(emailType, email); } } const payload = { ed6d4: null, b83d2: null }; payload.upo = createdKlavPro; let fmcResultsUrl; const connectionChar = window.location.search == '' ? '?' : '&' if (window.location.search.indexOf('fmhid') == -1){ let backendLabel = dermObj.getBackendLabel(); fmcResultsUrl = `${window.location.href}${connectionChar}fmhid=${dml_fmc.backendData.hashid}&be=${backendLabel}`; }else{ fmcResultsUrl = `${window.location.href}`; } payload.email = email; payload.email_consent = emailConsent; payload.hashid = dermObj.backendData.hashid; try{ if (dermObj.backendData.ed6d4 != undefined && dermObj.backendData.ed6d4 != null){ payload.ed6d4 = dermObj.backendData.ed6d4; }else if(dermObj.pageControls.capture.ed6d4 != undefined && dermObj.pageControls.capture.ed6d4 != null){ payload.ed6d4 = dermObj.pageControls.capture.ed6d4; }else if(location.search.indexOf('ed6d4=') > -1){ const agIdx = Number(location.search.split('ed6d4=')[1].split('&')[0]); payload.ed6d4 = [17, 22,30,40,50, 60, 70][agIdx]; } }catch(err){ console.warn('error in adding ag to payload',err); } try{ if (dermObj.backendData.b83d2 != undefined && dermObj.backendData.b83d2 != null){ payload.b83d2 = dermObj.backendData.b83d2; }else if(dermObj.pageControls.capture.b83d2 != undefined && dermObj.pageControls.capture.b83d2 != null){ payload.b83d2 = dermObj.pageControls.capture.b83d2; }else if(location.search.indexOf('b83d2=') > -1){ payload.b83d2 = Number(location.search.split('b83d2=')[1].split('&')[0]); } }catch(err){ console.warn('error in adding ge to payload',err); } try{ payload.referrer = dermObj.referrer; }catch(err){console.error(err)} try{ payload.maxmind_country = dml_fmc.backendData.maxmind_country; }catch(err){console.error(err)} const subscribeValue = emailConsent ? "1" : "0"; payload.subscribe = subscribeValue; try{ payload.revieveData = Object.keys(dermObj.backendData) .filter(key => {return key.startsWith('revieve_') && key != 'revieve_response'}) .reduce((obj, key) => { return { ...obj, [key]: dermObj.backendData[key] }; }, {}); }catch(err){ console.error('error in extracting revieve values - ',err) } delete payload.revieveData.revieve_response_time; if (dermObj.config.use2FA){ if(dermObj.backendData.access_code != null && dermObj.backendData.access_code != undefined){ payload.access_code = { code: dermObj.backendData.access_code, copy: dermObj.textData['2fa'].email_code_copy } } } if (emailType == "prep_treat_glow"){ if (dermObj.backendData.dioxide_data.prep_treat_glow == null || dermObj.backendData.dioxide_data.prep_treat_glow == undefined){ emailType = "results_default"; } } if (emailType == "brand_campaign"){ if (dermObj.backendData.dioxide_data.brand_campaign == null || dermObj.backendData.dioxide_data.brand_campaign == undefined){ emailType = "results_default"; } } if (emailType == "estimated_results"){ try{ const estimatedDioxRes = await dermObj.getEstimatedDioxideRecommendations(); dermObj.dioxideData.prep_treat_glow = estimatedDioxRes.prep_treat_glow; }catch(err){ console.error('error in sending email at estr - ',err); return; } } if (emailType == "results_default"){ if (dermObj.config.emailSubjectOverride != ''){ payload.subject = dermObj.config.emailSubjectOverride; }else{ payload.subject = dermObj.textData['email_results_default'].email_results_default_subject; } payload.template_id = "d-94218a74bc19433ea9ba731a56bf9399"; const shopButtonText = dermObj.config.shopButton.textOverride != '' ? dermObj.config.shopButton.textOverride : dermObj.textData["product_buttons_labels"].shop; payload.intro = { "title": dermObj.textData['email_results_default'].email_results_default_intro_title, "content": dermObj.textData['email_results_default'].email_results_default_intro_content } let switchFirstTwoProducts = false; let highestConcern = dml_fmc.dioxideData.sortedConcerns[0].concern_key; if (highestConcern == "dehydration"){ switchFirstTwoProducts = true; highestConcern = dml_fmc.dioxideData.sortedConcerns[1].concern_key; } payload.concern = { "intro": dermObj.textData['email_results_default'].email_results_default_intro_concern_intro, "name": dermObj.textData['concerns'][highestConcern], "image": dermObj.backendData.cropped_image, "analysisLink": fmcResultsUrl, "analysisLinkCaption": dermObj.textData['email_results_default'].email_results_default_intro_concern_cta } payload.treatments = { "title": dermObj.textData['email_results_default'].email_results_default_treatments_title, "products": [] } let concernProdsToDisplay; if (switchFirstTwoProducts){ concernProdsToDisplay = [dermObj.dioxideData.sortedConcerns[1],dermObj.dioxideData.sortedConcerns[0],dermObj.dioxideData.sortedConcerns[2]]; }else{ concernProdsToDisplay = [dermObj.dioxideData.sortedConcerns[0],dermObj.dioxideData.sortedConcerns[1],dermObj.dioxideData.sortedConcerns[2]]; } concernProdsToDisplay.forEach((concern,index)=>{ if (concern.recommended_product.productUrl.indexOf('fmc_formPostRequest') > -1){ concern.recommended_product.productUrl = concern.recommended_product.productEmailURL; } payload.treatments.products.push({ "concern": dermObj.textData['concerns'][concern.concern_key], "productImage": concern.recommended_product.imageUrl, "productName": concern.recommended_product.name, "productTagline": concern.recommended_product.tagline, "shopLink": concern.recommended_product.productUrl, "shopLinkCaption": shopButtonText, }) }) if (dermObj.dioxideData.recommendedProducts.length == 6){ payload.regimen = { "title": dermObj.textData['email_results_default'].email_results_default_regimen_title, } dermObj.dioxideData.recommendedProducts.forEach((product,index)=>{ if (product.productUrl.indexOf('fmc_formPostRequest') > -1){ product.productUrl = product.productEmailURL; } payload.regimen[`p${product.regimen_index}`]={ "label": `0${product.regimen_index}`, "productImage": product.imageUrl, "productName": product.name, "shopLink": product.productUrl, "shopLinkCaption": shopButtonText } }) } const emailFooter = []; if (dermObj.siteLinks.contact_us_url != undefined && dermObj.siteLinks.contact_us_url != null && dermObj.siteLinks.contact_us_url != ''){ payload.chat = { "lead": dermObj.textData['email_results_default'].email_results_default_PST_footer_header, "title": dermObj.textData['email_results_default'].email_results_default_PST_footer_tagline, "chatLink": dermObj.siteLinks.contact_us_url, "chatLinkCaption": dermObj.textData['email_results_default'].email_results_default_PST_footer_cta } emailFooter.push({ "footerLink": dermObj.siteLinks.contact_us_url, "footerLinkCaption": dermObj.textData["email_footer_links"].email_footer_contact }) } if (typeof dermObj.siteLinks.privacy_policy != 'undefined' && dermObj.siteLinks.privacy_policy != ''){ emailFooter.push({ "footerLink": dermObj.siteLinks.privacy_policy, "footerLinkCaption": dermObj.textData["email_footer_links"].email_footer_privacy_policy }) } if (typeof dermObj.siteLinks.copyright != 'undefined' && dermObj.siteLinks.copyright != ''){ emailFooter.push({ "footerLink": typeof dermObj.siteLinks.copyright, "footerLinkCaption": dermObj.textData["email_footer_links"].email_footer_copyright }) } if (emailFooter.length > 0){ payload.footer = emailFooter; } } if (emailType == "prep_treat_glow" || emailType == "estimated_results" || emailType == "quiz_no_image"){ if (dermObj.config.emailSubjectOverride != ''){ payload.subject = dermObj.config.emailSubjectOverride; }else{ payload.subject = dermObj.textData['email_results_default'].email_results_default_subject; } payload.template_id = "d-94218a74bc19433ea9ba731a56bf9399"; let shopButtonText; if ("TRUE" == 'TRUE' && dermObj.config.useShopify == true){ shopButtonText = dermObj.config.shopButton.textOverride != '' ? dermObj.config.shopButton.textOverride : dermObj.textData["product_buttons_labels"].add_to_bag; }else{ shopButtonText = dermObj.config.shopButton.textOverride != '' ? dermObj.config.shopButton.textOverride : dermObj.textData["product_buttons_labels"].shop; } payload.intro = { "title": dermObj.textData['email_results_default'].email_results_default_intro_title, "content": dermObj.textData['email_results_default'].email_results_default_intro_content } let switchFirstTwoProducts = false; let highestConcern = ''; try{ if (dermObj.pageControls.prep_treat_glow.concernOrder.length == 0){ let concernOrder = dermObj.dioxideData.sortedConcerns.map((concern) => {return concern.concern_key}); highestConcern = concernOrder[0]; if (highestConcern == 'dehydration'){ highestConcern = concernOrder[1]; } }else{ highestConcern = dermObj.pageControls.prep_treat_glow.concernOrder[0]; } }catch(err){} payload.concern = { "intro": dermObj.textData['email_results_default'].email_results_default_intro_concern_intro, "name": dermObj.textData['concerns'][highestConcern], "image": dermObj.backendData.original_image, "analysisLink": fmcResultsUrl, "analysisLinkCaption": dermObj.textData['email_results_default'].email_results_default_intro_concern_cta } if (emailType == "prep_treat_glow"){ if (payload.concern.analysisLink.indexOf('rspg=prep_treat_glow') < 0){ payload.concern.analysisLink += '&rspg=prep_treat_glow'; } } if (emailType == "quiz_no_image"){ payload.concern.image = 'http://facemapping.me/img/landing/fmc_landing_page_desktop.jpg'; payload.concern.intro= ''; payload.concern.name=''; if (payload.concern.analysisLink.indexOf('rspg=quiz_no_image') < 0){ payload.concern.analysisLink += '&rspg=quiz_no_image'; } } if (emailType == "estimated_results"){ payload.concern.image = 'http://facemapping.me/img/landing/fmc_landing_page_desktop.jpg'; payload.concern.intro= ''; payload.concern.name=''; if (payload.concern.analysisLink.indexOf('rspg=estr') < 0){ payload.concern.analysisLink += '&rspg=estr'; } } payload.treatments = { "title": dermObj.textData['exact_phrases'].we_recommend, "products": [] } const prepProd = dml_fmc.dioxideData.prep_treat_glow.prep; const treatProd = dml_fmc.dioxideData.prep_treat_glow.treat; const glowProd = dml_fmc.dioxideData.prep_treat_glow.glow; if (prepProd.productUrl.indexOf('fmc_formPostRequest') > -1){ prepProd.productUrl = prepProd.productEmailURL; } if (treatProd.productUrl.indexOf('fmc_formPostRequest') > -1){ treatProd.productUrl = treatProd.productEmailURL; } if (glowProd.productUrl.indexOf('fmc_formPostRequest') > -1){ glowProd.productUrl = glowProd.productEmailURL; } if ("TRUE" == 'TRUE' && dermObj.config.useShopify == true){ try{ let urlObj = new URL(prepProd.productUrl); let cartUrl = urlObj.protocol + "//" + urlObj.hostname + '/cart/add'; try{ prepProd.productUrl = `${cartUrl}?id=${prepProd.variants.filter((varobj)=>{return varobj.default})[0].shopify_variant_id}&quantity=1`; }catch(err){ console.error(err) } try{ treatProd.productUrl = `${cartUrl}?id=${treatProd.variants.filter((varobj)=>{return varobj.default})[0].shopify_variant_id}&quantity=1`; }catch(err){ console.error(err) } try{ glowProd.productUrl = `${cartUrl}?id=${glowProd.variants.filter((varobj)=>{return varobj.default})[0].shopify_variant_id}&quantity=1`; }catch(err){ console.error(err) } }catch(errInUrl){ console.log(`Error in new URL() - ${prepProd.productUrl}`, errInUrl) } } payload.treatments.products.push({ "concern": dermObj.textData['exact_phrases'].prep, "productImage": prepProd.imageUrl, "productName": prepProd.name, "productTagline": prepProd.tagline, "shopLink": prepProd.productUrl, "shopLinkCaption": shopButtonText, }) payload.treatments.products.push({ "concern": dermObj.textData['exact_phrases'].treat, "productImage": treatProd.imageUrl, "productName": treatProd.name, "productTagline": treatProd.tagline, "shopLink": treatProd.productUrl, "shopLinkCaption": shopButtonText, }) payload.treatments.products.push({ "concern": dermObj.textData['exact_phrases'].glow, "productImage": glowProd.imageUrl, "productName": glowProd.name, "productTagline": glowProd.tagline, "shopLink": glowProd.productUrl, "shopLinkCaption": shopButtonText, }) const emailFooter = []; if (typeof dermObj.siteLinks.contact_us_url != 'undefined' && dermObj.siteLinks.contact_us_url != ''){ payload.chat = { "lead": dermObj.textData['email_results_default'].email_results_default_PST_footer_header, "title": dermObj.textData['email_results_default'].email_results_default_PST_footer_tagline, "chatLink": dermObj.siteLinks.contact_us_url, "chatLinkCaption": dermObj.textData['email_results_default'].email_results_default_PST_footer_cta } emailFooter.push({ "footerLink": dermObj.siteLinks.contact_us_url, "footerLinkCaption": dermObj.textData["email_footer_links"].email_footer_contact }) } if (typeof dermObj.siteLinks.privacy_policy != 'undefined' && dermObj.siteLinks.privacy_policy != ''){ emailFooter.push({ "footerLink": dermObj.siteLinks.privacy_policy, "footerLinkCaption": dermObj.textData["email_footer_links"].email_footer_privacy_policy }) } if (typeof dermObj.siteLinks.copyright != 'undefined' && dermObj.siteLinks.copyright != ''){ emailFooter.push({ "footerLink": typeof dermObj.siteLinks.copyright, "footerLinkCaption": dermObj.textData["email_footer_links"].email_footer_copyright }) } if (emailFooter.length > 0){ payload.footer = emailFooter; } } if (emailType == "brand_campaign"){ if (dermObj.config.emailSubjectOverride != ''){ payload.subject = dermObj.config.emailSubjectOverride; }else{ payload.subject = dermObj.textData['email_results_default'].email_results_default_subject; } payload.template_id = "d-582ee0c9b4a24f27b81ac80077fc9570"; const shopButtonText = dermObj.config.shopButton.textOverride != '' ? dermObj.config.shopButton.textOverride : dermObj.textData["product_buttons_labels"].shop; let switchFirstTwoProducts = false; let highestConcern; if (dermObj.pageControls.brand_campaign.concernOrder.length == 0 || true){ const unsortedBrandConcerns = []; const brand_concerns = dermObj.backendData.dioxide_data.brand_campaign; dermObj.backendData.dioxide_data.brand_campaign Object.keys(brand_concerns).forEach((concernKey)=> { brand_concerns[concernKey].name = concernKey; brand_concerns[concernKey].concern_key = concernKey; switch(concernKey){ case "acne": brand_concerns[concernKey].score = dermObj.backendData.revieve_acne_value; unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dark_circles": brand_concerns[concernKey].score = dermObj.backendData.revieve_eyes_value; unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dark_spots": brand_concerns[concernKey].score = dermObj.backendData.revieve_dark_spots_value; unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dehydration": brand_concerns[concernKey].score = 0.25; unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dull_skin": brand_concerns[concernKey].score = dermObj.backendData.revieve_dull_skin_value; unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "redness": brand_concerns[concernKey].score = dermObj.backendData.revieve_redness_value; unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "wrinkles": brand_concerns[concernKey].score = dermObj.backendData.revieve_wrinkles_value; unsortedBrandConcerns.push(brand_concerns[concernKey]) break; } }) let concernOrder = unsortedBrandConcerns.sort((a,b) => {return b.score - a.score}); highestConcern = concernOrder[0].concern_key; if (highestConcern == 'dehydration'){ highestConcern = concernOrder[1]; } }else{ highestConcern = dermObj.pageControls.brand_campaign.concernOrder[0]; } const product = dermObj.backendData.dioxide_data.brand_campaign[highestConcern].one_product ; let kit = dermObj.backendData.dioxide_data.brand_campaign[highestConcern].kit; if (Array.isArray(kit)){ kit = kit[0]; } if (window.location.search.indexOf('rspg=brand_campaign') < 0){ fmcResultsUrl += '&rspg=brand_campaign'; } payload.concern = { "top_concern_header": dermObj.textData['email_results_default'].brand_campaign_my_top_concern_is, "top_concern_title": dermObj.textData['concerns'][highestConcern], "view_result_button": dermObj.textData['email_results_default'].email_results_default_intro_concern_cta, "view_result_url": fmcResultsUrl }; if (dermObj.pageControls.brand_campaign.raw_concern_header_under_eye_area == '' || dermObj.pageControls.brand_campaign.raw_concern_header_under_eye_area === undefined){ dermObj.pageControls.brand_campaign.raw_concern_header_under_eye_area = dermObj.textData.brand_campaign.brand_campaign_results_concern_header_under_eye_area; } if (dermObj.pageControls.brand_campaign.raw_concern_header == '' || dermObj.pageControls.brand_campaign.raw_concern_header === undefined){ dermObj.pageControls.brand_campaign.raw_concern_header = dermObj.textData.brand_campaign.brand_campaign_results_concern_header; } if (highestConcern == 'dark_circles'){ payload.concern.top_concern_info = dermObj.pageControls.brand_campaign.raw_concern_header_under_eye_area.replace('__CONCERN__', `${dermObj.textData.concerns.dark_circles}`); payload.concern.top_concern_info += ` ${dermObj.textData.brand_campaign.brand_campaign_results_concern_info_dark_circles}`; }else if (highestConcern == 'acne'){ payload.concern.top_concern_info = dermObj.pageControls.brand_campaign.raw_concern_header.replace('__CONCERN__', `${dermObj.textData.concerns.acne_alternative}`); payload.concern.top_concern_info += ` ${dermObj.textData.brand_campaign.brand_campaign_results_concern_info_breakouts}`; }else{ payload.concern.top_concern_info = dermObj.pageControls.brand_campaign.raw_concern_header.replace('__CONCERN__', `${dermObj.textData.concerns[highestConcern]}`); const infoCopy = dermObj.textData.brand_campaign[`brand_campaign_results_concern_info_${highestConcern}`]; payload.concern.top_concern_info += ` ${infoCopy}`; } payload.product_card = { "product_header": dermObj.textData.brand_campaign.brand_campaign_single_product_header, "product_name" : product.name, "product_info": product.mediumDescription, "product_image_url": product.imageUrl, "product_button": dml_fmc.textData.product_buttons_labels.shop } if (product.productUrl.indexOf('fmc_formPostRequest') > -1){ payload.product_card.product_url = product.productEmailURL }else{ payload.product_card.product_url = product.productUrl; } payload.kit_card = { "kit_header": dermObj.textData.brand_campaign.brand_campaign_kit_product_header, "kit_name": kit.name, "kit_info": kit.mediumDescription, "kit_image_url": kit.imageUrl, "kit_button": dml_fmc.textData.product_buttons_labels.shop } if (kit.productUrl.indexOf('fmc_formPostRequest') > -1){ payload.kit_card.product_url = kit.productEmailURL }else{ payload.kit_card.product_url = kit.productUrl; } if (dermObj.pageControls.brand_campaign.proBrightLink != ''){ payload.treatments = { "treatment_header": dermObj.textData.brand_campaign.brand_campaign_treatment_header, "treatment_title": dermObj.textData.treatments.treatment_probright_title, "treatment_image": "https://cdn.mcauto-images-production.sendgrid.net/8c98fb67ef549c42/5e100a03-21f0-471e-bd6e-07a8040c9e45/1200x1112.jpg", "treatment_url": dermObj.pageControls.brand_campaign.proBrightLink, "treatment_info": dermObj.textData.treatments.treatment_probright_desc, "treatment_button": dermObj.textData.exact_phrases.book_now } } const emailFooter = []; payload.footer = { logo_url : window.location.hostname, logo_image_url : "https://cdn.mcauto-images-production.sendgrid.net/8c98fb67ef549c42/f3d3320b-bde9-4a85-93e9-522f0d33b7e2/320x44.png" , links: [] } if (typeof dermObj.siteLinks.contact_us_url != 'undefined' && dermObj.siteLinks.contact_us_url != ''){ payload.contact = { "contact_header": `${dermObj.textData.exact_phrases.need_skin_care_advice}?`, "contact_title": `${dermObj.textData.exact_phrases.chat_with_an_expert}`, "contact_button": `${dermObj.textData.exact_phrases.chat_now}`, "contact_link": dermObj.siteLinks.contact_us_url } if (dermObj.contactOpenHours){ payload.contact.contact_open_hour = dermObj.contactOpenHours; // "contact_open_hour": "Mon - Fri, 7am - 8pm PT | Sat - Sun, 10am - 2pm PT
(excludes public holidays)" } payload.footer.links.push({ "link_url": dermObj.siteLinks.contact_us_url, "link_text": dermObj.textData["email_footer_links"].email_footer_contact }) } if (typeof dermObj.siteLinks.privacy_policy != 'undefined' && dermObj.siteLinks.privacy_policy != ''){ payload.footer.links.push({ "link_url": dermObj.siteLinks.privacy_policy, "link_text": dermObj.textData["email_footer_links"].email_footer_privacy_policy }) } if (typeof dermObj.siteLinks.copyright != 'undefined' && dermObj.siteLinks.copyright != ''){ payload.footer.links.push({ "link_url": typeof dermObj.siteLinks.copyright, "link_text": dermObj.textData["email_footer_links"].email_footer_copyright }) } } if (useNewEndpoint === true){ if ("https://global.facemapping.me" != ''){ try{ xhr.open('POST', "https://global.facemapping.me/fmc/send-sendgrid-crm",true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.send(JSON.stringify(payload)); }catch(err){ console.error(err); } }else{ reject('no NEW_EMAIL_URL'); } }else{ xhr.open('POST', `${dermObj.backend}/fmc/send-sendgrid-email`,true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.send(JSON.stringify(payload)); } }) } dermObj.getDioxideRecommendations = async (payloadObject)=>{ //dermObj.debug("PAYLOAD OBJECT:", payloadObject); return new Promise((resolve,reject)=>{ let dioxideEndpoint = dermObj.dioxide; if (dermObj.config.useDioxideStaging){ dioxideEndpoint = "https://dioxide-staging.herokuapp.com"; } let xhr = new XMLHttpRequest(); xhr.open("POST", dioxideEndpoint + "/recommendations/get_recommended_products/", true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.onload = async () => { //dermObj.debug(xhr.responseText) try{ if (String(xhr.status) == "200"){ let parsedResponse; try{ parsedResponse = JSON.parse(xhr.responseText) }catch(err){ console.error(err) parsedResponse = xhr.responseText; } try{ const refinedDioxData = await dermObj.refineAndCleanDioxideData(parsedResponse, payloadObject); resolve(refinedDioxData); }catch(err){ console.error(err); reject('failed to refine and clean dioxide data'); } }else{ if (String(xhr.status) == "500"){ /* reportDioxError({ "title": "ERROR - DIOXIDE STATUS - 500", "value": "Dioxide Payload: "+JSON.stringify(payloadObject), "targetChannel": "dioxide-500-errors" }); */ } reject("Error in dioxide call - status code: " + xhr.status); } }catch(err){ reject(err); } } xhr.send(JSON.stringify(payloadObject)); }) } dermObj.getEstimatedDioxideRecommendations = async ()=>{ return new Promise((resolve,reject)=>{ let dioxideEndpoint = dermObj.dioxide; if (dermObj.config.useDioxideStaging){ dioxideEndpoint = "https://dioxide-staging.herokuapp.com"; } let xhr = new XMLHttpRequest(); xhr.open("POST", dioxideEndpoint + "/recommendations/get_estimated_results/", true); xhr.setRequestHeader('Content-Type', 'application/json') //xhr.responseType = 'json'; xhr.onload = async () => { try{ const response = JSON.parse(xhr.responseText) dermObj.debug(response) resolve({prep_treat_glow: response.prep_treat_glow_obj}) }catch(err){ console.error(err); reject(); } } const payload = { country_code : dermObj.countryCode, lang_code : dermObj.lang_code, host_site : dermObj.referrer } xhr.send(JSON.stringify(payload)); }) } dermObj.refineAndCleanDioxideData = async (rawDioxideData, payloadObj = {}) => { return new Promise(async (resolve, reject) => { try{ rawDioxideData.concerns.forEach((concern,index)=>{ rawDioxideData.concerns[index].name = concern.concern_key; if (concern.recommended_product != undefined){ if (Array.isArray(concern.recommended_product.priceCurrency)){ rawDioxideData.concerns[index].recommended_product.priceCurrency = concern.recommended_product.priceCurrency[0] } if (Array.isArray(concern.recommended_product.price)){ rawDioxideData.concerns[index].recommended_product.price = concern.recommended_product.price[0] } if (Array.isArray(concern.recommended_product.productUrl)){ rawDioxideData.concerns[index].recommended_product.productUrl = concern.recommended_product.productUrl[0] } let formatedPriceObj = dermObj.priceFormating(rawDioxideData.concerns[index].recommended_product.price,rawDioxideData.concerns[index].recommended_product.priceCurrency); rawDioxideData.concerns[index].recommended_product.priceCurrency = formatedPriceObj.priceCurrency; rawDioxideData.concerns[index].recommended_product.price = formatedPriceObj.price; if (concern.recommended_product.productUrl && concern.recommended_product.productUrl.indexOf('fmc_formPostRequest') > -1){ rawDioxideData.concerns[index].recommended_product.productUrl = concern.recommended_product.productEmailURL; } } }) rawDioxideData.recommendedProducts.forEach((product,index)=>{ if (Array.isArray(product.priceCurrency)){ rawDioxideData.recommendedProducts[index].priceCurrency = product.priceCurrency[0] } if (Array.isArray(product.price)){ rawDioxideData.recommendedProducts[index].price = product.price[0] } if (Array.isArray(product.productUrl)){ rawDioxideData.recommendedProducts[index].productUrl = product.productUrl[0] } let formatedPriceObj = dermObj.priceFormating(rawDioxideData.recommendedProducts[index].price,rawDioxideData.recommendedProducts[index].priceCurrency); rawDioxideData.recommendedProducts[index].priceCurrency = formatedPriceObj.priceCurrency; rawDioxideData.recommendedProducts[index].price = formatedPriceObj.price; if (product.productUrl && product.productUrl.indexOf('fmc_formPostRequest') > -1){ rawDioxideData.recommendedProducts[index].productUrl = product.productEmailURL; } }) }catch(err){ reject(err); } dermObj.debug("DIOXIDE before cleaning - ", rawDioxideData) try{ const cleanedResponse = await dermObj.checkDioxideResponse(rawDioxideData, payloadObj) cleanedResponse.sortedConcerns = []; let curScore = 5; while (curScore > 0){ cleanedResponse.concerns.forEach((concern)=>{ if (concern.score == curScore){ cleanedResponse.sortedConcerns.push(concern); } }) curScore--; } dermObj.debug("DIOXIDE after cleaning - ", cleanedResponse) resolve(cleanedResponse); }catch(err){ console.error("Error in cleaning dioxide response - ",err); } }) } dermObj.prepareDioxidePayload = (facemapObj, languageCode) => { return new Promise((resolve,reject)=>{ try{ let dioxPayload = { "dehydration_score" : 2, "dark_circles_score" : 1, "redness_score" : 1, "oiliness_score" : 1, "wrinkles_score" : 1, "acne_score" : 1, "azure_age" : 25, "country_code" : "US", "host_site" : "www.dermalogica.com", "lang_code" : "en", "breezometer_air_quality_index" : null, "breezometer_humidity" : null, "revieve_acne_value": 0.2, // TODO - REMOVE TEMPORARY FALLBACK ONCE HANDLED IN DIOXIDE "revieve_dark_spots_value": null, "revieve_dull_skin_value": null, "revieve_eyes_value": null, "revieve_freckles_value": null, "revieve_hyperpigmentation_value": null, "revieve_makeup_value": null, "revieve_melasma_value": null, "revieve_radiance_value": null, "revieve_redness_value": 0.25, // TODO - REMOVE TEMPORARY FALLBACK ONCE HANDLED IN DIOXIDE "revieve_skin_shine_value": null, "revieve_smoothness_value": null, "revieve_texture_value": 0.25, // TODO - REMOVE TEMPORARY FALLBACK ONCE HANDLED IN DIOXIDE "revieve_uneven_skin_tone_value": null, "revieve_wrinkles_value": null, } //console.log(dioxPayload, facemapObj) try{ if (dermObj.masks.darkCirclesScore != undefined && dermObj.masks.darkCirclesScore != null ) dioxPayload.dark_circles_score = dermObj.masks.darkCirclesScore; }catch(err){ } // REVIEVE PARAMETERS START if (facemapObj.revieve_acne_value != undefined){ dioxPayload.revieve_acne_value = Number(facemapObj.revieve_acne_value); } if (facemapObj.revieve_dark_spots_value != undefined){ dioxPayload.revieve_dark_spots_value = Number(facemapObj.revieve_dark_spots_value); } if (facemapObj.revieve_dull_skin_value != undefined){ dioxPayload.revieve_dull_skin_value = Number(facemapObj.revieve_dull_skin_value); } if (facemapObj.revieve_eyes_value != undefined){ dioxPayload.revieve_eyes_value = Number(facemapObj.revieve_eyes_value); } if (facemapObj.revieve_freckles_value != undefined){ dioxPayload.revieve_freckles_value = Number(facemapObj.revieve_freckles_value); } if (facemapObj.revieve_hyperpigmentation_value != undefined){ dioxPayload.revieve_hyperpigmentation_value = Number(facemapObj.revieve_hyperpigmentation_value); } if (facemapObj.revieve_makeup_value != undefined){ dioxPayload.revieve_makeup_value = Number(facemapObj.revieve_makeup_value); } if (facemapObj.revieve_melasma_value != undefined){ dioxPayload.revieve_melasma_value = Number(facemapObj.revieve_melasma_value); } if (facemapObj.revieve_radiance_value != undefined){ dioxPayload.revieve_radiance_value = Number(facemapObj.revieve_radiance_value); } if (facemapObj.revieve_redness_value != undefined){ dioxPayload.revieve_redness_value = Number(facemapObj.revieve_redness_value); } if (facemapObj.revieve_skin_shine_value != undefined){ dioxPayload.revieve_skin_shine_value = Number(facemapObj.revieve_skin_shine_value); } if (facemapObj.revieve_smoothness_value != undefined){ dioxPayload.revieve_smoothness_value = Number(facemapObj.revieve_smoothness_value); } if (facemapObj.revieve_texture_value != undefined){ dioxPayload.revieve_texture_value = Number(facemapObj.revieve_texture_value); } if (facemapObj.revieve_uneven_skin_tone_value != undefined){ dioxPayload.revieve_uneven_skin_tone_value = Number(facemapObj.revieve_uneven_skin_tone_value); } if (facemapObj.revieve_wrinkles_value != undefined){ dioxPayload.revieve_wrinkles_value = Number(facemapObj.revieve_wrinkles_value); } // REVIEVE PARAMETERS END try{ dioxPayload.azure_age = Number(dermObj.backendData.ed6d4); }catch(err){ console.error(err); } if (facemapObj.country != undefined){ dioxPayload.country_code = facemapObj.country; }else if (facemapObj.maxmind_country != undefined){ dioxPayload.country_code = facemapObj.maxmind_country; } dioxPayload.host_site = dermObj.referrer; if (dermObj.referrer.indexOf("dermalogica-us-staging.myshopify.com") > -1){ dioxPayload.host_site = "www.dermalogica.com/"; } if (dermObj.config.forcedCountry != ""){ dioxPayload.country_code = dermObj.config.forcedCountry; } if (dml_fmc.lang_code != undefined){ dioxPayload.lang_code = dml_fmc.lang_code; if (dioxPayload.lang_code.indexOf('-') > 1){ let langParts = dioxPayload.lang_code.split('-'); try{ dioxPayload.lang_code = `${langParts[0]}-${langParts[1].toUpperCase()}`; }catch(err){} } if (dml_fmc.lang_code == "en"){ if (dioxPayload.country_code != "AU"){ dioxPayload.lang_code += "-US"; } } if (dioxPayload.lang_code.toLowerCase() == 'ja-np'){ dioxPayload.lang_code = 'ja'; } } if (facemapObj.breezometer_air_quality_index != undefined){ dioxPayload.breezometer_air_quality_index = facemapObj.breezometer_air_quality_index; } if (facemapObj.breezometer_humidity != undefined){ dioxPayload.breezometer_humidity = facemapObj.breezometer_humidity; } if (dermObj.config.quizAfterImage == true){ let quizAnswers = {}; try{ quizAnswers = dermObj.pageControls.qai.answerObj[dermObj.config.pageDict.quiz_after_image]; }catch(err){} try{ if (quizAnswers.looking_for != undefined && quizAnswers.looking_for != null){ dioxPayload.quiz_looking_for = quizAnswers.looking_for; } }catch(err){} try{ if (quizAnswers.dermalogica_familiar != undefined && quizAnswers.dermalogica_familiar != null){ dioxPayload.quiz_dermalogica_familiar = quizAnswers.dermalogica_familiar; } }catch(err){} try{ if (quizAnswers.skin_concern != undefined && quizAnswers.skin_concern != null && quizAnswers.skin_concern != ''){ dioxPayload.quiz_skin_concerns = quizAnswers.skin_concern.split(','); } }catch(err){} } let qaiUrlParam = (new URLSearchParams(window.location.search)).get('qai_an'); if (qaiUrlParam != undefined && qaiUrlParam != null && qaiUrlParam != ''){ try{ let lfAns = /QlfA([a-z])/g.exec(qaiUrlParam); if (lfAns != null){ let lfAnswer; switch(lfAns[1]){ case 'b': lfAnswer = 'basic'; break; case 'a': lfAnswer = 'advanced'; break; case 's': lfAnswer = 'skin_concerns'; break; default: lfAnswer = ''; } if (lfAnswer != ''){ dioxPayload.quiz_looking_for = lfAnswer; } } }catch(err){} try{ let dfAns = /QdfA([a-z])/g.exec(qaiUrlParam); if (dfAns != null){ let dfAnswer; switch(dfAns[1]){ case 'n': dfAnswer = 'new_user'; break; case 'u': dfAnswer = 'user_before'; break; case 'g': dfAnswer = 'guru'; break; default: dfAnswer = ''; } if (dfAnswer != ''){ dioxPayload.quiz_dermalogica_familiar = dfAnswer; } } }catch(err){} try{ let scAns = /Qsc([Aa-z]+)/g.exec(qaiUrlParam); if (scAns != null){ let concernSuffixArray = scAns[1].split(/A/g); let concernArray = []; if (concernSuffixArray.includes('br')) concernArray.push('breakouts'); if (concernSuffixArray.includes('dc')) concernArray.push('dark_circles'); if (concernSuffixArray.includes('ust')) concernArray.push('uneven_skin_tone'); if (concernSuffixArray.includes('el')) concernArray.push('elasticity'); if (concernSuffixArray.includes('se')) concernArray.push('sensitivity'); if (concernSuffixArray.includes('de')) concernArray.push('dehydration'); if (concernSuffixArray.includes('wr')) concernArray.push('wrinkles'); dioxPayload.quiz_skin_concerns = String(concernArray); }else{} }catch(err){} if (dioxPayload.quiz_looking_for == 'skin_concerns' && (dioxPayload.quiz_skin_concerns == undefined || dioxPayload.quiz_skin_concerns == null)){ dioxPayload.quiz_looking_for = ''; } } resolve(dioxPayload); }catch(err){ console.error(err); reject(err); } }) } dermObj.checkDioxideResponse = async (dioxObj, payloadObj) => { return new Promise((resolve,reject)=>{ let outObj = {...dioxObj}; let reducedPayload = { oiliness: payloadObj.oiliness_score, dehydation: payloadObj.dehydration_score, wrinkles: payloadObj.wrinkles_score, acne: payloadObj.acne_score, redness: payloadObj.redness_score, dark_circles: payloadObj.dark_circles_score, age: payloadObj.azure_age, country_code: payloadObj.country_code, host_site: payloadObj.host_site, lang: payloadObj.lang_code } //dermObj.debug("CHECK RESPONSE OBJECT: ",dioxObj); //dermObj.debug("WITH PAYLOAD: ",JSON.stringify(reducedPayload)); let dioxPayloadString = JSON.stringify(reducedPayload).replace(/,/g,"\n").replace("{","").replace("}",""); let missingConcerns = ""; let missingRegimenIndex = ""; if (outObj.concerns == undefined){ dermObj.reportDioxideProblem("MISSING 'concerns' FIELD", dioxPayloadString); }else{ let concernIndicesToRemove = []; let concernList = ["dehydration", "acne", "wrinkles","dark_circles","redness","oiliness"]; outObj.concerns.forEach((concern,index)=>{ concernList = concernList.filter( concernName => concernName != concern.name); let productIsGood = dermObj.checkDioxProductFields(concern,"concern",dioxPayloadString); if (!productIsGood){ concernIndicesToRemove.push(index); } }) if (concernIndicesToRemove.length > 0){ for(let ii = concernIndicesToRemove.length -1; ii > -1; ii--){ outObj.concerns.splice(concernIndicesToRemove[ii],1); } } } if (outObj.recommendedProducts == undefined){ dermObj.reportDioxideProblem("MISSING 'recommendedProducts' FIELD",dioxPayloadString); }else{ let regimenIndexList = [1,2,3,4,5,6]; let regimenIsGood = true; outObj.recommendedProducts.forEach((regimenProduct)=>{ regimenIndexList = regimenIndexList.filter( regimenIndex => regimenIndex != regimenProduct.regimen_index); //dermObj.debug("regimen product before checking - ", regimenProduct); let productIsGood = dermObj.checkDioxProductFields(regimenProduct, "regimen",dioxPayloadString) //dermObj.debug("regimen product is good: ", productIsGood); regimenIsGood = regimenIsGood && productIsGood; }) if (regimenIndexList.length > 0){ missingRegimenIndex = String(regimenIndexList); dermObj.reportDioxideProblem("MISSING REGIMEN INDEX/INDICES: " + missingRegimenIndex,dioxPayloadString); regimenIsGood = false; } if (!regimenIsGood){ outObj.recommendedProducts = []; } } resolve(outObj); }) } dermObj.checkDioxProductFields = (inObj, type, dioxPayloadString)=>{ let productIsGood = true; try{ let recommendedProd; if (type == "concern"){ recommendedProd = inObj.recommended_product; }else{ recommendedProd = inObj; } if (recommendedProd == undefined){ productIsGood = false; if (type=="concern"){ dermObj.reportDioxideProblem("MISSING PRODUCT FOR CONCERN: " + inObj.name,dioxPayloadString); } }else{ if (recommendedProd.pimcore_id == undefined){ dermObj.reportDioxideProblem("PIMCORE ID FIELD IS MISSING FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; }else if (recommendedProd.pimcore_id == 0){ dermObj.reportDioxideProblem("PIMCORE ID IS 0 FOR" + recommendedProd.name,dioxPayloadString); productIsGood = false; } if (recommendedProd.name == undefined){ dermObj.reportDioxideProblem("NAME FIELD IS MISSING FOR " + JSON.stringify(recommendedProd),dioxPayloadString); productIsGood = false; }else if (recommendedProd.name == ""){ dermObj.reportDioxideProblem("NAME IS MISSING EMPTY FOR " + JSON.stringify(recommendedProd),dioxPayloadString); productIsGood = false; } if (recommendedProd.tagline == undefined){ dermObj.reportDioxideProblem("TAGLINE FIELD IS MISSING FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; }else if (recommendedProd.tagline == ""){ dermObj.reportDioxideProblem("TAGLINE IS MISSING EMPTY FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; } if (recommendedProd.mediumDescription == undefined){ dermObj.reportDioxideProblem("MEDIUM DESCRIPTION FIELD IS MISSING FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; }else if (recommendedProd.mediumDescription == ""){ dermObj.reportDioxideProblem("MEDIUM DESCRIPTION IS MISSING EMPTY FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; } if (recommendedProd.imageUrl == undefined){ dermObj.reportDioxideProblem("IMAGE URL FIELD IS MISSING FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; }else if (recommendedProd.imageUrl == ""){ dermObj.reportDioxideProblem("IMAGE URL IS MISSING EMPTY FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; } if (recommendedProd.productUrl == undefined){ dermObj.reportDioxideProblem("PRODUCT URL FIELD IS MISSING FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; }else if (recommendedProd.productUrl == ""){ dermObj.reportDioxideProblem("PRODUCT URL IS MISSING EMPTY FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; } if (recommendedProd.price == undefined && dermObj.config.shopButton.showPrices){ dermObj.reportDioxideProblem("PRICE FIELD IS MISSING FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; } if (recommendedProd.priceCurrency == undefined && dermObj.config.shopButton.showPrices){ dermObj.reportDioxideProblem("CURRENCY FIELD IS MISSING FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; } if (type == "regimen"){ if (recommendedProd.regimen_index == undefined){ dermObj.reportDioxideProblem("REGIMEN INDEX FIELD IS MISSING FOR " + JSON.stringify(recommendedProd),dioxPayloadString); productIsGood = false; } if (recommendedProd.regimen_step == undefined){ dermObj.reportDioxideProblem("REGIMEN STEP FIELD IS MISSING FOR " + JSON.stringify(recommendedProd),dioxPayloadString); productIsGood = false; } } } }catch(err){ console.error("Error in checking dioxide product fields" ,err); productIsGood = false; } return productIsGood; } dermObj.reportDioxideProblem = (message,payloadString) => { console.warn(message); try{ /* reportDioxError({ "title": "WARN - DIOXIDE RESPONSE ERROR", "value": message + "\n"+payloadString, "color" : "warning" }); */ }catch(err){ console.error(err) } } dermObj.priceFormating = (inPrice,currency)=>{ let formatedPrice; formatedPrice = Number(String(inPrice).replace(/,/g,"")).toFixed(2); let outputFormated = { price: formatedPrice, priceCurrency: currency } if (currency == "¥"){ //dermObj.debug("price conversion yen - A: ",formatedPrice) formatedPrice = String(Number(formatedPrice)); // remove commas //dermObj.debug("price conversion yen - B: ",formatedPrice) let numDots = Math.floor(formatedPrice.length / 3) let curDotPos = (formatedPrice.length) % 3; if (curDotPos == 0){ curDotPos = 3; numDots -= 1; } let outString = ""; let dotCounter =0; for (let ii=0; ii < formatedPrice.length; ii++){ outString += formatedPrice[ii]; if (ii+1 == curDotPos && dotCounter < numDots){ curDotPos += 3; outString += ","; dotCounter++; } } formatedPrice = outString; outputFormated.price = outString; } if (currency == "$MXN"){ outputFormated.priceCurrency = "$"; outputFormated.price = formatedPrice + " MXN"; } return outputFormated; } dermObj.getDioxideLinkData = async (forcedCountryCode = "")=> { return new Promise(async (resolve, reject)=>{ let dioxLinkUrl = `${dermObj.dioxide}/recommendations/get_site_links/`; let payload = { 'country_code' : dermObj.countryCode, 'host_site' : dermObj.config.forcedPage == '' ? window.location.href : dermObj.config.forcedPage } if (forcedCountryCode != ""){ payload.country_code = forcedCountryCode; } let xhr = new XMLHttpRequest(); xhr.open("POST", dioxLinkUrl, true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.responseType = 'json'; xhr.onload = async () => { if (xhr.status === 200){ if (xhr.response.status === 200){ resolve(xhr.response.data); }else{ reject({status: xhr.status, response_status: xhr.response.status}); } }else{ reject({status: xhr.status}); } } xhr.onerror =(err)=>{ console.error("dioxide call error - ",err) reject(err); } xhr.onabort = (err)=>{ console.error("dioxide call aborted - ",err) reject(err); } try{ xhr.send(JSON.stringify(payload)); }catch(err){ console.error(err); } }) } dermObj.getAllDioxideProducts = async ()=>{ return new Promise(async (resolve,reject)=>{ try{ const fullCall = await dermObj.dioxideGetAllProducts(); if (fullCall.all_products.length === 0 ){ const countryCall = await dermObj.dioxideGetAllProducts('countryOnly'); if (countryCall.all_products.length === 0 ){ const defaultCall = await dermObj.dioxideGetAllProducts('useDefaultUS'); dermObj.dioxideAllProducts = [...defaultCall.all_products]; resolve(); }else{ dermObj.dioxideAllProducts = [...countryCall.all_products]; resolve(); } }else{ dermObj.dioxideAllProducts = [...fullCall.all_products]; resolve(); } }catch(err){ console.error(err); } }) } dermObj.dioxideGetAllProducts = async (callType = "") => { return new Promise((resolve, reject) => { let dioxideEndpoint = dermObj.dioxide; if (dermObj.config.useDioxideStaging){ dioxideEndpoint = "https://dioxide-staging.herokuapp.com"; } const country_code = dermObj.countryCode; const host_site = dermObj.referrer; let lang_code = dermObj.config.langForBackends == '' ? dermObj.lang_code : dermObj.config.langForBackends; if (lang_code.toLowerCase() == 'ja-np'){ lang_code='ja'; } const dioxProductsUrl = `${dioxideEndpoint}/recommendations/get_all_products/`; const payload = { country_code, host_site, lang_code } if (callType == "countryOnly"){ payload.host_site = "facemapping.me" } if (callType == "useDefaultUS"){ payload.host_site = "facemapping.me" payload.country_code = "US" } //dermObj.debug("Dioxide payload: ", payload) let xhr = new XMLHttpRequest(); xhr.open("POST", dioxProductsUrl, true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.onload = async () => { if (xhr.status === 200){ resolve(JSON.parse(xhr.response)); }else{ reject({status: xhr.status}); } } xhr.onerror =(err)=>{ console.error("dioxide call error - ",err) reject(err); } xhr.onabort = (err)=>{ console.error("dioxide call aborted - ",err) reject(err); } xhr.send(JSON.stringify(payload)); }) } dermObj.getAllDioxideTranslations = async () => { dermObj.dioxideAllProductTranslations = {} let dioxideEndpoint = dermObj.dioxide; if (dermObj.config.useDioxideStaging){ dioxideEndpoint = "https://dioxide-staging.herokuapp.com"; } let enUsProdTranslations = []; let langSpecTranslations = []; try { const enUsProdTranslationsRequest = await fetch(`${dioxideEndpoint}/product/get_product_translations/en-US`); if (!enUsProdTranslationsRequest.ok) { throw new Error(`HTTP error! Status: ${enUsProdTranslationsRequest.status}`); } enUsProdTranslations = await enUsProdTranslationsRequest.json(); if (dermObj.lang_code != 'en-us'){ let requestLangCode = dermObj.lang_code; const requestLangCodeArr = requestLangCode.split('-'); if (requestLangCodeArr.length > 1){ requestLangCode = `${requestLangCodeArr[0]}-${requestLangCodeArr[1].toUpperCase()}`; } if (requestLangCode.toLowerCase == 'ja-np'){ requestLangCode='ja'; } try { const langProdTranslationsRequest = await fetch(`${dioxideEndpoint}/product/get_product_translations/${requestLangCode}`); if (!langProdTranslationsRequest.ok) { throw new Error(`HTTP error! Status: ${langProdTranslationsRequest.status}`); } langSpecTranslations = await langProdTranslationsRequest.json(); }catch(errInner){ console.error('Fetch error: ', errInner); } } enUsProdTranslations.forEach((prodTrans) => { if (prodTrans.pimcore_id == undefined || prodTrans.pimcore_id == null || prodTrans.pimcore_id == 0) return; dermObj.dioxideAllProductTranslations[prodTrans.pimcore_id] = prodTrans; }) langSpecTranslations.forEach((prodTrans) => { if (prodTrans.pimcore_id == undefined || prodTrans.pimcore_id == null || prodTrans.pimcore_id == 0) return; if (dermObj.dioxideAllProductTranslations[prodTrans.pimcore_id] != undefined){ Object.keys(prodTrans).forEach((objKey) => { if (prodTrans[objKey] == '') return; dermObj.dioxideAllProductTranslations[prodTrans.pimcore_id][objKey] = prodTrans[objKey]; }) }else{ dermObj.dioxideAllProductTranslations[prodTrans.pimcore_id] = prodTrans; } }) } catch (error) { console.error('Fetch error: ', error); } } dermObj.mergeDioxideAllProdAndTranslations = () => { const missingTranslations = []; const descriptionIsTagline = []; dermObj.dioxideAllProducts.forEach((productData, index) => { const prodPimcoreId = productData.pimcoreId; if (dermObj.dioxideAllProductTranslations[prodPimcoreId] != undefined){ const prodTranslationData = dermObj.dioxideAllProductTranslations[prodPimcoreId]; dermObj.dioxideAllProducts[index].tagline = prodTranslationData.tagline; dermObj.dioxideAllProducts[index].mediumDescription = prodTranslationData.medium_description; /* if (prodTranslationData.tagline == prodTranslationData.medium_description){ dermObj.debug('TAGLINE IS DESCRIPTION') dermObj.debug(prodTranslationData.medium_description, prodTranslationData.tagline) descriptionIsTagline.push({pimcore_id: prodPimcoreId, name: productData.name}); } */ }else{ missingTranslations.push({pimcore_id: prodPimcoreId, name: productData.name}); } }) /* - this is just for debugging and finding not complete products if (missingTranslations.length > 0){ dermObj.debug('TRANSLATIONS MISSING - ',missingTranslations ); } if (descriptionIsTagline.length > 0){ dermObj.debug('Tdescription is tagline - ',descriptionIsTagline ); } */ } dermObj.getDioxideQuizNoImageRecommendation = async (quizResults) => { return new Promise(async (resolve, reject) => { const payload = { "country_code": dml_fmc.countryCode, "host_site": window.location.hostname, "lang_code": dml_fmc.lang_code, "quiz_results": quizResults } try { const xhr = new XMLHttpRequest(); xhr.open('POST',`${dermObj.dioxide}/recommendations/get_fmc_quiz_products/`); xhr.setRequestHeader('Content-type','application/json; charset=utf-8') xhr.responseType = 'json'; xhr.onload = ()=>{ if (xhr.status >= 200 && xhr.status < 300) { dermObj.debug('DIOX QUIZ NO IMAGE RESPONSE - ', xhr.response); resolve(xhr.response) } else { console.error(`HTTP request failed with status ${xhr.status}`); reject(`HTTP request failed with status ${xhr.status}`); } } xhr.send(JSON.stringify(payload)); }catch(err){ console.log(err); reject(err) } }) } dermObj.productData = {}; dermObj.dispProdArr = []; dermObj.recomProdArr = []; dermObj.collectProductData = async ()=>{ const concernProducts = dermObj.dioxideData.sortedConcerns.map((concernObj)=>{return concernObj.recommended_product}); const regimenProducts = [...dermObj.dioxideData.recommendedProducts]; concernProducts.forEach((prod)=>{ dermObj.productData[prod.pimcore_id] = {...prod}; }) regimenProducts.forEach((prod)=>{ if (!dermObj.productData[prod.pimcore_id]){ dermObj.productData[prod.pimcore_id] = {...prod}; } }) return; } dermObj.applyProductData = async (productData) => { Object.keys(productData).forEach((productId)=>{ if (productData[productId].productUrl.indexOf('fmc_formPostRequest') > -1){ productData[productId].productUrl = productData[productId].productEmailURL; } }) const productKeys = Object.keys(productData); document.querySelectorAll(`[data-widget-product-exists]`).forEach((productToDisplayElement)=>{ if (!productKeys.includes(productToDisplayElement.dataset.widgetProductExists)){ productToDisplayElement.style.pointerEvents = "none"; productToDisplayElement.style.cursor = "default"; productToDisplayElement.querySelectorAll('*').forEach((childEl)=>{ childEl.style.pointerEvents = "none"; childEl.style.cursor = "default"; childEl.style.opacity = 0; }) } }) document.querySelectorAll(`[data-widget-product-link]`).forEach((productLink)=>{ if (productData[productLink.dataset?.widgetProductLink]?.productUrl){ productLink.onclick = ()=>{window.open(productData[productLink.dataset.widgetProductLink].productUrl,'_blank');} } }) document.querySelectorAll(`[data-widget-product-image]`).forEach((productImage)=>{ if (productData[productImage.dataset?.widgetProductImage]?.imageUrl){ productImage.src = productData[productImage.dataset.widgetProductImage].imageUrl; } }) document.querySelectorAll(`[data-widget-product-background]`).forEach((productImage)=>{ if (productData[productImage.dataset?.widgetProductBackground]?.imageUrl){ productImage.style.backgroundImage = `url('${productData[productImage.dataset.widgetProductBackground].imageUrl}')`; } }) document.querySelectorAll(`[data-widget-product-name]`).forEach((productName)=>{ if (productData[productName.dataset?.widgetProductName]?.name){ productName.innerHTML = productData[productName.dataset.widgetProductName].name; if (dermObj.lang_code == 'ja'){ productName.style.textTransform = 'uppercase'; } } }) document.querySelectorAll(`[data-widget-product-tagline]`).forEach((productTagline)=>{ if (productData[productTagline.dataset?.widgetProductTagline]?.tagline){ productTagline.innerHTML = productData[productTagline.dataset.widgetProductTagline].tagline; } }) document.querySelectorAll(`[data-widget-product-description]`).forEach((productDescription)=>{ if (productData[productDescription.dataset?.widgetProductDescription]?.tagline){ productDescription.innerHTML = productData[productDescription.dataset.widgetProductDescription].mediumDescription; } }) const obsOptions = { root: null, rootMargin: '0px', threshold: 1.0 } dermObj.itemViewObserver = new IntersectionObserver((entries)=>{ entries.forEach((itemView) => { if (itemView.isIntersecting){ //console.log('Item in View - ', itemView); dermObj.itemViewObserver.unobserve(itemView.target) const pimcoreId = itemView.target.dataset.viewItemObserver; //console.log('product data:', dermObj.productData[pimcoreId]); dermObj.pimcoreIdToViewItemEvent(pimcoreId); dermObj.prodDisplayed(pimcoreId); } }); }, obsOptions); document.querySelectorAll(`[data-view-item-observer]`).forEach((observeEl)=>{ dermObj.itemViewObserver.observe(observeEl); }) document.querySelectorAll(`[data-widget-product-buy]`).forEach((productBuyButton)=>{ const pimcoreId = productBuyButton.dataset?.widgetProductBuy; if (pimcoreId){ productBuyButton.addEventListener("click",()=>{ dermObj.sendGA360("main flow",'shop button clicked - pimcore_id - '+ pimcoreId ); dermObj.sendGAFlowEvent('shop button clicked - pimcore_id - '+ pimcoreId ); dermObj.sendGA360("main flow",'shop button clicked'); dermObj.sendGAFlowEvent('shop button clicked'); }) if (!(dermObj.productData[pimcoreId]?.productUrl && dermObj.productData[pimcoreId]?.productUrl.indexOf('https://') > -1)){ console.log("COMING SOON PRODUCT - ", pimcoreId, dermObj.productData[pimcoreId]) productBuyButton.classList.add('dml_is_coming_soon_button'); return; } if (dermObj.config.useShopify){ if (dermObj.productData[pimcoreId].variants && dermObj.productData[pimcoreId].variants.length > 0){ productBuyButton.classList.add('dml_is_add_to_bag_button'); const addToBagClickHandler = async ()=>{ if (!productBuyButton.isPending){ productBuyButton.isPending = true; setTimeout(()=>{ productBuyButton.isPending = false; },500) productBuyButton.classList.add('dml_is_pending') try{ await dermObj.addToBagShopify(productBuyButton); productBuyButton.classList.add('dml_added_to_bag_button'); productBuyButton.classList.remove('dml_is_add_to_bag_button'); productBuyButton.classList.remove('dml_is_pending'); }catch(err){ console.warn(err); productBuyButton.classList.remove('dml_is_add_to_bag_button'); productBuyButton.classList.remove('dml_is_pending'); dermObj.shopButtonClick(productBuyButton); } } } productBuyButton.removeEventListener('click', addToBagClickHandler) productBuyButton.addEventListener('click', addToBagClickHandler) return; } }else{ const shopClickHandler = async()=>{ if (!productBuyButton.isPending){ productBuyButton.isPending = true; setTimeout(()=>{ productBuyButton.isPending = false; },500) dermObj.shopButtonClick(productBuyButton); } } productBuyButton.removeEventListener('click',shopClickHandler) productBuyButton.addEventListener('click',shopClickHandler) } } }) try{ if (dermObj.isPercMatchMiniPage == true) return; dermObj.sendDispProds(); }catch(err){ console.error(err); } } dermObj.shopButtonClick = async (productBuyButton) => { const prodId = productBuyButton.dataset.widgetProductBuy; window.open(dermObj.productData[prodId].productUrl,'_blank'); } dermObj.pimcoreIdToViewItemEvent = (pimcoreId) => { if (typeof dataLayer === 'undefined') return; try{ let currencyCode = ''; try{ currencyCode = Shopify.currency.active; }catch(err){} const prodData = dermObj.productData[pimcoreId]; if (prodData.shopify_id == undefined) return; let variantId, variantSize; try{ const defVariant = prodData.variants.filter((variant) => variant.default)[0]; variantId = defVariant.shopify_variant_id; variantSize = defVariant.size; }catch(errVar){ console.warn(errVar); variantId = undefined; variantSize = undefined; } const dataLayerPayload = { event : 'dl_view_item', ecommerce : { currencyCode: currencyCode, detail: { products: [ { product_id : prodData.shopify_id, price: Number(prodData.price), name: prodData.name, variant_id : variantId, item_variant: variantSize } ] } } } dataLayer.push(dataLayerPayload); }catch(err){ console.error(err); return; } } dermObj.prodDisplayed = (pimcoreId) => { try{ const prodObj = dermObj.productData[pimcoreId]; dermObj.dispProdArr.push({ name: prodObj.name, shopify_id: prodObj.shopify_id, variant_id: prodObj.variant_id }); // Debounce the send to backend clearTimeout(dermObj.sendDispProdsTimeout); dermObj.sendDispProdsTimeout = setTimeout(dermObj.sendDispProds, 1000); }catch(err){ console.log(err); } } dermObj.sendDispProds = () =>{ if (dermObj.backendData == undefined) return; if (dermObj.backendData.hashid == undefined || dermObj.backendData.hashid == '') return; const payload = { hashid : dermObj.backendData.hashid, displayed_products: [...dermObj.dispProdArr] } if (dermObj.recomProdSent != true){ if (dermObj.productData != undefined){ payload.recommended_products = [] try{ Object.values(dermObj.productData).forEach((prodData) => { const reducedProdData = { name : prodData.name, shopify_id : prodData.shopify_id } let variantIdArr = prodData.variants.filter((variantObj) => variantObj.default); if (variantIdArr.length > 0 ){ reducedProdData.variant_id = variantIdArr[0].shopify_variant_id; } payload.recommended_products.push(reducedProdData); }) }catch(errProdData){ console.error(errProdData); } } try{ let rspg = window.location.search.split('rspg=')[1].split('&')[0]; if (rspg != undefined && rspg != ''){ payload.rspg = rspg; } }catch(errRspg){ console.error(errRspg); } dermObj.recomProdSent = true; } fetch(`${dermObj.backend}/fmc/update_user_products`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }) .then(response => response.json()) .then(data => { console.log('Data sent successfully:', data); }) .catch(error => { console.error('Error sending data:', error); }); } dermObj.addToBagShopify = async (productBuyButton) => { return new Promise( async (resolve,reject)=>{ const pimcoreId = productBuyButton.dataset.widgetProductBuy; const defaultVariantObj = dermObj.productData[pimcoreId].variants.filter((variantData) => {return variantData.default}); let variantId; if (defaultVariantObj.length > 0){ variantId = defaultVariantObj[0].shopify_variant_id; }else{ variantId = dermObj.productData[pimcoreId].variants[0].shopify_variant_id; } let useShopifyFunction = false; if (Shopify != undefined && Shopify != null){ if (Shopify.derm_custom != undefined && Shopify.derm_custom != null){ if (Shopify.derm_custom.addToBagShopify != undefined && Shopify.derm_custom.addToBagShopify != null){ useShopifyFunction = true; } } } if (useShopifyFunction){ Shopify.derm_custom.addToBagShopify({},variantId).then((res)=>{ dermObj.sendGA360("main flow","add to bag - variant id="+variantId); dermObj.sendGAFlowEvent("add to bag - variant id="+variantId); dermObj.sendGA360("main flow","add to bag"); dermObj.sendGAFlowEvent("add to bag"); resolve("product added successfully"); }) .catch((err)=>{ reject("error in adding product do cart"); }); }else{ try{ const xhr = new XMLHttpRequest(); xhr.open('POST','/cart/add.js',true) xhr.setRequestHeader('Content-Type', 'application/json'); xhr.responseType = 'text'; xhr.onerror = ()=>{ console.error('Upload failed - ',xhr); reject("error") } xhr.onload = ()=>{ if(xhr.status == 200){ setTimeout(()=>{ dermObj.updateShopifyCart(); },1000) dermObj.sendGA360("main flow","add to bag - variant id="+variantId); dermObj.sendGAFlowEvent("add to bag - variant id="+variantId); dermObj.sendGA360("main flow","add to bag"); dermObj.sendGAFlowEvent("add to bag"); resolve("product added successfully"); }else{ reject("error in adding product to cart"); } } xhr.send(JSON.stringify({id:variantId})); }catch(err){ reject(err); } } }) } dermObj.updateShopifyCartDawn = async function(){ try{ fetch(window.location.pathname + "?sections=cart-drawer,cart-icon-bubble") .then(cartRes => cartRes.json()) .then(cartData => { try{ const bubbleLink = document.getElementById('cart-icon-bubble'); const bubbleDom = (new DOMParser).parseFromString(cartData['cart-icon-bubble'],'text/html'); const newBubbleSvg = bubbleDom.getElementById('shopify-section-cart-icon-bubble').innerHTML; bubbleLink.innerHTML = newBubbleSvg; }catch(bubbleErr){ console.error(bubbleErr) } try{ const cartDrawer = document.querySelector('cart-drawer'); const drawerDom = (new DOMParser).parseFromString(cartData['cart-drawer'],'text/html'); const newCartDrawerInner = drawerDom.querySelector('cart-drawer').innerHTML; cartDrawer.classList.remove('is-empty'); cartDrawer.innerHTML = newCartDrawerInner; }catch(drawerErr){ console.error(drawerErr) } }) }catch(outerErr){ console.error(outerErr); } } dermObj.updateShopifyCart = async () => { if (dermObj.customization?.updateShopifyCart){ const xhr = new XMLHttpRequest(); xhr.open('GET','/cart.js',true) xhr.setRequestHeader('Content-Type', 'application/json'); xhr.responseType = 'json'; xhr.onload = () => { const cart = xhr.response dermObj.customization.updateShopifyCart(cart); }; xhr.send(); }else{ try{ dermObj.updateShopifyCartDawn(); }catch(err){console.error(err)} } } dermObj.addMultipleToBagShopify = async ( variantIdArray) => { let useShopifyFunction = false; if (Shopify != undefined && Shopify != null){ if (Shopify.derm_custom != undefined && Shopify.derm_custom != null){ if (Shopify.derm_custom.addToBagShopifyArray != undefined && Shopify.derm_custom.addToBagShopifyArray != null){ useShopifyFunction = true; } } } return new Promise( async (resolve,reject)=>{ if (useShopifyFunction){ Shopify.derm_custom.addToBagShopifyArray(variantIdArray).then((res)=>{ dermObj.sendGA360("main flow",`add multiple products to bag - variant ids=${variantIdArray}`); dermObj.sendGAFlowEvent(`add multiple products to bag - variant ids=${variantIdArray}`); dermObj.sendGA360("main flow","add all to bag"); dermObj.sendGAFlowEvent("add all to bag"); resolve("product array added successfully"); }) .catch((err)=>{ reject("error in adding product array to cart"); }); }else{ try{ const payload = { items: [] } variantIdArray.forEach((variantId) => { payload.items.push({ id: variantId, quantity: 1 }) }) const xhr = new XMLHttpRequest(); xhr.open('POST','/cart/add.js',true) xhr.setRequestHeader('Content-Type', 'application/json'); xhr.responseType = 'json'; xhr.onerror = ()=>{ console.error('Upload failed - ',xhr); reject("error") } xhr.onload = ()=>{ dermObj.updateShopifyCart(); dermObj.sendGA360("main flow",`add multiple products to bag - variant ids=${variantIdArray}`); dermObj.sendGAFlowEvent(`add multiple products to bag - variant ids=${variantIdArray}`); dermObj.sendGA360("main flow","add all to bag"); dermObj.sendGAFlowEvent("add all to bag"); resolve("product added successfully"); } xhr.send(JSON.stringify(payload)); }catch(err){ reject(err); } } }) } if (typeof dermObj.afterTextRendering == 'undefined'){ dermObj.afterTextRendering = ()=>{}; } dermObj.getLanguageData = async()=>{ return new Promise(async (resolve, reject)=>{ if (dml_fmc.config.forcedLanguage){ dermObj.lang_code = dml_fmc.config.forcedLanguage; }else{ dermObj.lang_code = navigator.language; } if (dermObj.lang_code != 'en-US'){ await dermObj.getLanguageDataEnUs(); } let xhr = new XMLHttpRequest(); xhr.open('GET',`https://facemapping.me/lang/${dermObj.lang_code}`, true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.responseType = 'json'; xhr.onload = async (successEvent)=>{ console.log("success lang call", xhr.response); dermObj.lang_code=xhr.response.lang_code; if (dermObj.textData){ await dermObj.mergeIntoTextData(xhr.response.data); }else{ dermObj.textData = xhr.response.data; } resolve(xhr.response.data); } xhr.onerror = (errorEvent)=>{ console.error("error lang call", errorEvent); reject(); } xhr.abort = (abortEvent)=>{ console.error("abort lang call",abortEvent); reject(); } xhr.ontimeout = (timeoutEvent)=>{ console.error("timeout lang call",timeoutEvent); reject(); } xhr.send(null); }) } dermObj.getLanguageDataEnUs = async()=>{ return new Promise((resolve, reject)=>{ let xhr = new XMLHttpRequest(); xhr.open('GET',`https://facemapping.me/lang/en-US`, true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.responseType = 'json'; xhr.onload = (successEvent)=>{ console.log("success lang call", xhr.response); dermObj.textData = xhr.response.data; resolve(xhr.response.data); } xhr.onerror = (errorEvent)=>{ console.error("error lang call", errorEvent); reject(); } xhr.abort = (abortEvent)=>{ console.error("abort lang call",abortEvent); reject(); } xhr.ontimeout = (timeoutEvent)=>{ console.error("timeout lang call",timeoutEvent); reject(); } xhr.send(null); }) } dermObj.renderTextData = async (textData) => { return new Promise((resolve, reject) => { const render_jsonTextObject = (textObj)=>{ Object.keys(textObj).forEach((item,index)=>{ if (typeof textObj[item] == "object"){ render_jsonTextObject(textObj[item]); }else{ try{ if (textObj[item] != ""){ document.querySelectorAll(`[data-widget-text-term=${item}]`).forEach((htmlEl)=>{ htmlEl.innerHTML = textObj[item]; }) document.querySelectorAll(`[data-widget-attribute-text-term=${item}]`).forEach((htmlEl)=>{ if (htmlEl.dataset.widgetAttributeType && htmlEl.dataset.widgetAttributeType != ""){ htmlEl.setAttribute(htmlEl.dataset.widgetAttributeType , textObj[item]); } }) } }catch(err){ dermObj.debug('INFO - Element with id '+item+' not found - err: ',err); } } }) } render_jsonTextObject(textData); dermObj.afterTextRendering(); resolve(); }) } dermObj.mergeIntoTextData = async (updatedTextData) => { let tmpObj = {...updatedTextData}; async function scanThroughJson(currentObj, currentKeyArray){ let compareMainObj = tmpObj; currentKeyArray.forEach((pastKey)=>{ compareMainObj = compareMainObj[pastKey]; }) Object.keys(currentObj).forEach((currentKey)=>{ if ( Object.keys(compareMainObj).includes(currentKey)){ if (typeof currentObj[currentKey] == "object"){ let updatedKeyArray = [...currentKeyArray] updatedKeyArray.push(currentKey); scanThroughJson(currentObj[currentKey], updatedKeyArray); }else if(typeof currentObj[currentKey] == "string"){ if (compareMainObj[currentKey] == ""){ compareMainObj[currentKey] = currentObj[currentKey]; if (currentKey.indexOf('consent_privacy_statement_') > -1 && dermObj.lang_code.split('-')[0] != 'en'){ dermObj.uselegacyLegalCopy = true; } } } }else{ compareMainObj[currentKey] = currentObj[currentKey]; if (currentKey.indexOf('consent_privacy_statement_') > -1 && dermObj.lang_code.split('-')[0] != 'en'){ dermObj.uselegacyLegalCopy = true; } } }) } await scanThroughJson(dermObj.textData,[]); dermObj.textData = {...tmpObj} return tmpObj; } dermObj.pageControls = {} dermObj.initClassesDueWidth = async()=>{ return new Promise(async (resolve, reject)=>{ const bodyWidthCheck = setInterval(async ()=>{ if (dermObj.body.offsetWidth > 0){ clearInterval(bodyWidthCheck); await dermObj.updateClassesDueWith(); window.addEventListener('resize', dermObj.updateClassesDueWith); } resolve(); },50) const isMacLike = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform); if (isMacLike){ dermObj.body.classList.add('dml_is_os'); } }) } dermObj.updateClassesDueWith = async ()=>{ return new Promise(async (resolve, reject)=>{ if (dermObj.body.offsetWidth > 768){ dermObj.widget_wrapper.classList.remove("dml_mobile"); dermObj.body.classList.remove("dml_mobile"); }else{ dermObj.widget_wrapper.classList.add("dml_mobile"); dermObj.body.classList.add("dml_mobile"); } resolve(); }); } dermObj.pageControls.permissionsPage = {} let skipToResultsCounter = 0; dermObj.pageControls.permissionsPage.skptres = async () => { skipToResultsCounter++; if (skipToResultsCounter > 10){ dermObj.gotoPage('blmr_results_page'); } } dermObj.pageControls.landing_brand_campaign = {} dermObj.pageControls.landing_brand_campaign.runConcernCycle = () => { const textKeyArray = [ "acne_alternative", "redness_alternative", "dark_circles_alternative", "wrinkles_alternative", "dehydration_alternative", "dull_skin", "dark_spots"]; const concernCycleField = dermObj.body.querySelector('#fmc_brand_campaign_app_title_concern'); const intervalTimer = 3000; const blendTimer = 500; concernCycleField.style.transition = `${blendTimer/1000}s opacity`; let concernCurIndex = 0; let maxLength = { desktop: 0, mobile: 0 }; textKeyArray.forEach((textKey) => { maxLength.desktop = Math.max(maxLength.desktop, dermObj.textData.concerns[textKey].length * 30 + 30); maxLength.mobile = Math.max(maxLength.mobile, dermObj.textData.concerns[textKey].length * 18 + 20); }) if (dermObj.body.offsetWidth > 768){ concernCycleField.style.width = `${maxLength.desktop}px`; }else{ concernCycleField.style.width = `${maxLength.mobile}px`; } window.addEventListener('resize',()=>{ if (dermObj.body.offsetWidth > 768){ concernCycleField.style.width = `${maxLength.desktop}px`; }else{ concernCycleField.style.width = `${maxLength.mobile}px`; } }) const cicleInterval = setInterval(()=>{ if (concernCycleField.getBoundingClientRect().height > 0){ concernCurIndex++; concernCurIndex = concernCurIndex < textKeyArray.length ? concernCurIndex: 0; concernCycleField.innerHTML = dermObj.textData.concerns[textKeyArray[concernCurIndex]]; concernCycleField.style.opacity = 1; setTimeout(()=>{ concernCycleField.style.opacity = 0; },intervalTimer - blendTimer) }else{ clearInterval(cicleInterval) } },intervalTimer) concernCycleField.innerHTML = dermObj.textData.concerns[textKeyArray[concernCurIndex]]; setTimeout(()=>{ concernCycleField.style.opacity = 0; },intervalTimer - blendTimer) } dermObj.pageControls.onboarding_default = {} dermObj.pageControls.onboarding_default.currentSlideIndex = 0 let fmcOnboardingSlider = document.getElementById("fmc_onboarding_slider_container"); dermObj.pageControls.onboarding_default.nextSlide = ()=>{ dermObj.sendGA360("main flow", "onboarding next clicked"); dermObj.sendGAFlowEvent( "onboarding next clicked"); if (dermObj.pageControls.onboarding_default.currentSlideIndex < 2 ){ dermObj.pageControls.onboarding_default.currentSlideIndex++; let newPos = `-${fmcOnboardingSlider.parentElement.offsetWidth * (dermObj.pageControls.onboarding_default.currentSlideIndex)}px`; fmcOnboardingSlider.style.left = newPos; document.getElementById("fmc_onboarding_prev_button_icon").classList.remove('fmc_inactive'); document.querySelectorAll(".fmc_onboarding_bullet").forEach((bullet)=>{ bullet.classList.remove('fmc_selected'); }) document.getElementById(`fmc_onboarding_bullet_${dermObj.pageControls.onboarding_default.currentSlideIndex + 1}`).classList.add('fmc_selected'); }else{ dermObj.pageControls.onboarding_default.skipIntro(); } } dermObj.pageControls.onboarding_default.prevSlide = ()=>{ dermObj.sendGA360("main flow", "onboarding back clicked"); dermObj.sendGAFlowEvent( "onboarding back clicked"); if (dermObj.pageControls.onboarding_default.currentSlideIndex > 0 ){ dermObj.pageControls.onboarding_default.currentSlideIndex--; let newPos = `-${fmcOnboardingSlider.parentElement.offsetWidth * (dermObj.pageControls.onboarding_default.currentSlideIndex)}px`; fmcOnboardingSlider.style.left = newPos; if (dermObj.pageControls.onboarding_default.currentSlideIndex == 0){ document.getElementById("fmc_onboarding_prev_button_icon").classList.add('fmc_inactive'); } document.querySelectorAll(".fmc_onboarding_bullet").forEach((bullet)=>{ bullet.classList.remove('fmc_selected'); }) document.getElementById(`fmc_onboarding_bullet_${dermObj.pageControls.onboarding_default.currentSlideIndex + 1}`).classList.add('fmc_selected'); } } dermObj.pageControls.onboarding_default.skipToResultsCounter = 0; dermObj.pageControls.onboarding_default.skipIntro = async () => { if (dermObj.pageControls.onboarding_default.skipToResultsCounter > 5){ dermObj.gotoPage('results'); let skipHash; let be; if (dermObj.backend == "https://fmc-backend-staging.herokuapp.com"){ skipHash = "a0ef6d0190214fce992e877e2a518b36"; be = "stg"; }else if(dermObj.backend == "https://imb-backend-eu.herokuapp.com"){ skipHash = "8b139fac4f0549309feb263750c2effd"; be = "eu"; }else if(dermObj.backend == "https://imb-backend-ca.herokuapp.com"){ skipHash = "24b16e9ebf56472288eb4ee1e4a8a6f4"; be = "ca"; }else{ skipHash = "5fe15fcbbc5b403ebedd7a46b479a5ab"; be = "us"; } let urlParamString = '' if (window.location.search.indexOf('?') > - 1){ urlParamString = `&fmhid=${skipHash}&be=${be}`; }else{ urlParamString = `?fmhid=${skipHash}&be=${be}`; } window.history.pushState('fmc_results_page', '', `${window.location.href}${urlParamString}`); const analyzeData = await dermObj.getFormerfmcResult(skipHash); dermObj.debug("fmc data: ",analyzeData); dermObj.backendData = {...analyzeData} dermObj.pageControls.results_default.build(); }else{ if (dermObj.pageControls.onboarding_default.currentSlideIndex == 2){ dermObj.sendGA360("main flow","onboarding analyze clicked"); dermObj.sendGAFlowEvent("onboarding analyze clicked"); }else{ dermObj.sendGA360("main flow","skip intro clicked"); dermObj.sendGAFlowEvent("skip intro clicked"); } dml_fmc.showConsent() } } dermObj.pageControls.onboarding_default.skipToResults = () => { dermObj.pageControls.onboarding_default.skipToResultsCounter++ } dermObj.pageControls.onboarding_default.resizeSlides = ()=>{ let newPos = `-${fmcOnboardingSlider.parentElement.offsetWidth * (dermObj.pageControls.onboarding_default.currentSlideIndex)}px`; fmcOnboardingSlider.style.left = newPos; } window.addEventListener('resize',dermObj.pageControls.onboarding_default.resizeSlides) dermObj.pageControls.onboarding_quiz_no_image = {} dermObj.pageControls.onboarding_quiz_no_image.loadQuiz = async ()=>{ console.log('loading quiz') //clear potential old quiz: const quizWrapper = dermObj.body.querySelector('#fmc_quiz_no_image_page #dml_dmlqz_wrapper') const loadingSpinner = dermObj.body.querySelector('#fmc_quiz_no_image_page .fmc_quiz_loading_spinner') quizWrapper.innerHTML = ''; quizWrapper.style.display = "none"; loadingSpinner.style.display = "block"; window.dml_dmlqz = {}; dml_dmlqz.customCssUrl = 'https://facemapping.me/css/quiz_styles.min.css'; dml_dmlqz.surveyResults = {}; dml_dmlqz.surveyId = '6a5c9571-20e6-4efa-a8fc-26edb24024ef'; dml_dmlqz.postId = '7bb43cf4-8cbb-46ab-b52c-95183ae37b80'; if (typeof window.dml_dmlqz.surveyId == 'undefined') { console.error("cannot load survey data - ",err); return; } const qzembedUrl = "https://dml-quiz-production.herokuapp.com/embed.js?"+(new Date()).getTime(); const qzembedScript = document.createElement("script"); qzembedScript.src = qzembedUrl; document.getElementById("dml_dmlqz_wrapper").appendChild(qzembedScript); const surveyLoadedInterval = setInterval(()=>{ if (dml_dmlqz.surveyLoaded){ clearInterval(surveyLoadedInterval); dermObj.renderTextData(dermObj.textData); //dermObj.addClickEventsToButtons(); //dml_dmlqz.body.querySelectorAll('#dmlqz_submit_button').forEach((submitButton) => { //submitButton.innerHTML = dermObj.textData["exact phrases"].next; //}) dml_dmlqz.surveyJs.submitButton = async()=>{ dml_dmlqz.evaluateCurrentQuestion(); try{ dermObj.pageControls.onboarding_quiz_no_image.submitSurveyResults(); }catch(err){ console.error(err) } } quizWrapper.style.display = "flex"; loadingSpinner.style.display = "none"; // FIX FOR POLISH LANGUAGE - ISSUES WITH HELVETICA NEUE STD - SECOND TIME AFTER QUIZ LOADED if (['pl','cs','ro'].includes(dermObj.lang_code)){ dermObj.body.querySelectorAll('p,span,a,h1,h2,h3').forEach((textEl) => { textEl.style.fontFamily = '"Helvetica Neue", "Arial"' }); } } },100) } dermObj.pageControls.onboarding_quiz_no_image.submitSurveyResults = async ()=>{ console.log('submit survey results'); dermObj.gotoPage('waiting'); try{ let revVals = {}; try{ revVals = await dermObj.pageControls.onboarding_quiz_no_image.quizToRevieveMapping(dml_dmlqz.surveyResults); }catch(err){ revVals = {}; console.error(err); } dermObj.backendData = await dermObj.sendNoImageQuizResults(dml_dmlqz.surveyResults, revVals); //dermObj.gotoPage('results'); }catch(err){ console.error(err); } } dermObj.pageControls.onboarding_quiz_no_image.quizToRevieveMapping = async (surveyResults) => { return new Promise ((resolve,reject)=>{ try{ const revVals = {}; const survRes = {...dml_dmlqz.surveyResults}; // Q1 Mapping let q1skinShineAnswerCounter = 0; let q1isNotSure = false; let q1isSensitive = false; let q1skinShineString = ''; const q1skinShineVals = { 'normal' : 0.2, 'oily' : 0.8, 'dry' : 0, 'combination' : 0.5 } survRes.q1.forEach((answer) => { switch(answer){ case 'normal': case 'oily': case 'combination': case 'dry': q1skinShineAnswerCounter++; q1skinShineString = answer; break; case 'sensitive': q1isSensitive = true; break; case 'not_sure': q1isNotSure = true; break; } }) if (!q1isNotSure){ if (q1isSensitive){ revVals.revieve_redness_value = 0.8; } if (q1skinShineAnswerCounter > 1){ revVals.revieve_skin_shin_value = 0.5; }else if(q1skinShineAnswerCounter == 1){ try{ revVals.revieve_skin_shine_value = q1skinShineVals[ q1skinShineString ]; }catch(errInner){console.error(errInner)} } } // Q2 Mapping const q2revieveVals = { fine_lines : { key: 'revieve_wrinkles_value', val: 0.5 }, deep_lines : { key: 'revieve_wrinkles_value', val: 0.8 }, breakouts : { key: 'revieve_acne_value', val: 0.8 }, dark_circles : { key: 'revieve_eyes_value', val: 0.8 }, uneven_tone : { key: 'revieve_uneven_skin_tone_value', val: 0.8 }, elasticity : { key: 'revieve_dummy_elasticity_value', // TO BE REPLACED val: 0.33 }, sensitivity : { key: 'revieve_redness_value', val: 0.8 }, blackheads : { key: 'revieve_dummy_blackheads_value', val: 0.33 }, dehydration : { key: 'revieve_dummy_dehydration_value', val: 0.33 } } survRes.q2.forEach((answer) => { let curKey = ''; let curVal = 0.1; switch(answer){ case 'fine_lines': case 'deep_lines': if (survRes.q2.includes('deep_lines')){ curKey = q2revieveVals.deep_lines.key; curVal = q2revieveVals.deep_lines.val; }else{ curKey = q2revieveVals.fine_lines.key; curVal = q2revieveVals.deep_lines.val; } break; default: curKey = q2revieveVals[answer].key; curVal = q2revieveVals[answer].val; } revVals[curKey] = curVal; }); resolve(revVals); }catch(err){reject(err)} }); } dermObj.pageControls.capture = {}; dermObj.pageControls.capture.start = async () => { //dermObj.pageControls.waiting.isAnalyzing = false; dermObj.backendData = null; dermObj.fmcResultsUrl = ''; dermObj.masks.clearImages(); await dermObj.capture.checkFaceApi(); if (dermObj.config.useAgGeFaceApiFeature !== true){ dermObj.sendGA360("main flow","capture page - age bucket question"); dermObj.sendGAFlowEvent("capture page - age bucket question"); try{ dermObj.pageControls.capture.ed6d4 = -1; dermObj.pageControls.capture.b83d2 = -1; dermObj.pageControls.capture.getAgeBucketQuestionAnswered = false; await dermObj.pageControls.capture.getAgeBucketQuestion(); }catch(err){console.log(err)} }else{ dermObj.sendGA360("main flow","capture page - use extra face model"); dermObj.sendGAFlowEvent("capture page - use extra face model"); } try{ await dermObj.capture.startStream(); }catch(err){ console.warn("camera stream not working - ", err); } try{ dermObj.pageControls.waiting.reset(); }catch(err){console.error(err)} dermObj.emailRequestedForResults = false; try{ const capturedImage = await dermObj.capture.getImage(); await dermObj.capture.stopStream(); //console.log(capturedImage) if (dermObj.config.quizAfterImage === true){ dermObj.gotoPage('quiz_after_image'); }else{ dermObj.gotoPage('waiting'); let urlObj = new URL(window.location.href); if (!urlObj.searchParams.has('qai_ds')) { urlObj.searchParams.set('qai_ds', 0); const newUrl = urlObj.toString(); history.pushState({}, '', newUrl); } } dermObj.masks.capturedImage = capturedImage; await dermObj.masks.calcDarkCirclesScore(); try{ const startTime = Date.now(); const analyzeData = await dermObj.processImage(capturedImage) const endTime = Date.now(); dermObj.debug('analyze call time [s]: ', (endTime-startTime)/1000); dermObj.masks.obscurifyEyesFlag = false; dermObj.debug("ANALYZE DATA - ",analyzeData) // catch fmc mini collection page and route through if (dermObj.isPercMatchMiniPage == true && dermObj.pageControls.perc_match_coll.percMatchFailed == true){ dermObj.backendData = {}; dermObj.gotoPage('results'); return; } if (analyzeData.success === false || analyzeData.statusCode === 500){ if (analyzeData.code === 5002){ document.getElementById("fmc_waiting_page_default").classList.add("no_face_error"); dermObj.sendGA360("main flow","analyze image - error_no_face"); dermObj.sendGAFlowEvent("analyze image - error_no_face"); return; } if (analyzeData.code === 5003 || analyzeData.code === 202){ //document.getElementById("fmc_waiting_page_default").classList.add("multi_face_error"); //dermObj.sendGA360("main flow","analyze image - error_multi_faces"); dermObj.sendGA360("main flow","analyze image - show estimated results"); dermObj.sendGAFlowEvent("analyze image - show estimated results"); dermObj.config.pageDict.results = 'fmc_estimated_results'; if (dermObj.config.quizAfterImage !== true){ dermObj.gotoPage('results'); } return; } // general handling of old revieve errors if (analyzeData.code < 999 ){ dermObj.sendGA360("main flow","analyze image - show estimated results"); dermObj.sendGAFlowEvent("analyze image - show estimated results"); dermObj.config.pageDict.results = 'fmc_estimated_results'; if (dermObj.config.quizAfterImage !== true){ dermObj.gotoPage('results'); } return; } if (analyzeData.code === 4000 || analyzeData.code === 5001 || analyzeData.code === 5000 || analyzeData.statusCode === 500){ dermObj.sendGA360("main flow","analyze image - show estimated results"); dermObj.sendGAFlowEvent("analyze image - show estimated results"); dermObj.config.pageDict.results = 'fmc_estimated_results'; if (dermObj.config.quizAfterImage !== true){ dermObj.gotoPage('results'); } return; /* document.getElementById("fmc_waiting_page_default").classList.add("general_error"); dermObj.sendGA360("main flow","analyze image - error_general"); dermObj.sendGAFlowEvent("analyze image - error_general"); return; */ }else{ dermObj.sendGA360("main flow","analyze image - show estimated results"); dermObj.sendGAFlowEvent("analyze image - show estimated results"); dermObj.config.pageDict.results = 'fmc_estimated_results'; if (dermObj.config.quizAfterImage !== true){ dermObj.gotoPage('results'); } return; } } if (!dermObj.config.userImgOnly){ if (!analyzeData.revieve_response){ dermObj.sendGA360("main flow","analyze image - show estimated results"); dermObj.sendGAFlowEvent("analyze image - show estimated results"); dermObj.config.pageDict.results = 'fmc_estimated_results'; dermObj.gotoPage('results'); return; } if (analyzeData.revieve_response?.results === null){ dermObj.sendGA360("main flow","analyze image - show estimated results"); dermObj.sendGAFlowEvent("analyze image - show estimated results"); dermObj.config.pageDict.results = 'fmc_estimated_results'; if (dermObj.config.quizAfterImage !== true){ dermObj.gotoPage('results'); } return; } } dermObj.sendGA360("main flow","analyze image - success"); dermObj.sendGAFlowEvent("analyze image - success"); dermObj.backendData = {...analyzeData}; if (dermObj.config.userImgOnly){ /*dermObj.backendData.concerns.forEach((concern)=>{ Object.keys(concern).forEach((key)=>{ if (key.indexOf('image') > -1){ concern[key] = capturedImage; } }) })*/ dermObj.backendData.original_image = capturedImage; } }catch(err){ document.getElementById("fmc_waiting_page_default").classList.add("general_error"); dermObj.sendGA360("main flow","analyze image - general_error"); dermObj.sendGAFlowEvent("analyze image - general_error"); console.error("error in uploading image - ",err) dermObj.gotoPage('waiting'); } }catch(err){ console.error("error in capturing an image - ",err) let waitingPageEl = document.getElementById("fmc_waiting_page_default"); if (err.error === 'multi_face'){ waitingPageEl.classList.add('multi_face_error') dermObj.sendGA360("main flow","analyze image - error_multi_faces"); dermObj.sendGAFlowEvent("analyze image - error_multi_faces"); }else{ waitingPageEl.classList.add('general_error') dermObj.sendGA360("main flow","analyze image - general_error"); dermObj.sendGAFlowEvent("analyze image - general_error"); } dermObj.gotoPage('waiting'); } } dermObj.pageControls.capture.getAgeBucketQuestion = async () => { return new Promise((resolve,reject) => { let intervalStep = 500; let pendingTime = 0; let intervalTimeout = 30000; dermObj.body.querySelector('#fmc_capture_question_overlay').style.display = 'flex'; const ageBucketInterval = setInterval(()=>{ if (dermObj.pageControls.capture.getAgeBucketQuestionAnswered === true){ clearInterval(ageBucketInterval); resolve(); return; } pendingTime += intervalStep; if (pendingTime > intervalTimeout) { clearInterval(ageBucketInterval); dermObj.pageControls.capture.ed6d4 = -1; reject('timeout in age bucket question'); } },intervalStep) }) } dermObj.pageControls.capture.selectAgeBucket = async (bucketIndex) => { dermObj.body.querySelector('#fmc_capture_question_overlay').style.display = 'none'; const ageArray = [17, 22,30,40,50, 60, 70]; try{ dermObj.pageControls.capture.ed6d4 = ageArray[bucketIndex]; }catch(err){ dermObj.pageControls.capture.ed6d4 = -1 console.error(err); } dermObj.pageControls.capture.getAgeBucketQuestionAnswered = true; } dermObj.pageControls.qai = {}; dermObj.pageControls.qai.curIndex = 0; dermObj.pageControls.qai.urlParamAnswerArr = []; dermObj.pageControls.qai.answerObj = {} dermObj.pageControls.qai.init = ()=>{ dermObj.pageControls.qai.ingredientsList = [...dermObj.pageControls.qai.keyIngredientsList]; dermObj.pageControls.qai.quizPage = dermObj.body.querySelector(`#${dermObj.config.pageDict.quiz_after_image}`); dermObj.pageControls.qai.answerObj[dermObj.pageControls.qai.quizPage.id] = {}; dermObj.pageControls.qai.slider = dermObj.pageControls.qai.quizPage.querySelector('.fmc_qai_slider'); dermObj.pageControls.qai.curIndex = 0; dermObj.pageControls.qai.quizPage.querySelectorAll('button.fmc_qai_answer_button').forEach((answerBtn) => { answerBtn.removeEventListener('click', dermObj.pageControls.qai.evaluateButtonClick); answerBtn.addEventListener('click', dermObj.pageControls.qai.evaluateButtonClick); answerBtn.classList.remove('is_selected'); }); dermObj.pageControls.qai.quizPage.querySelectorAll('button.fmc_qai_answer_list_item').forEach((listItem)=>{ listItem.remove(); }); dermObj.pageControls.qai.quizPage.querySelectorAll('input.fmc_qai_input').forEach((autoCompInput) => { autoCompInput.removeEventListener('input', dermObj.pageControls.qai.triggerAutoComplete); autoCompInput.addEventListener('input', dermObj.pageControls.qai.triggerAutoComplete); autoCompInput.removeEventListener('focus', dermObj.pageControls.qai.triggerAutoComplete); autoCompInput.addEventListener('focus', dermObj.pageControls.qai.triggerAutoComplete); autoCompInput.removeEventListener('blur', dermObj.pageControls.qai.closeAutoCompleteBox); autoCompInput.addEventListener('blur', dermObj.pageControls.qai.closeAutoCompleteBox); }) dermObj.pageControls.qai.nextButton = dermObj.pageControls.qai.quizPage.querySelector('.fmc_qai_next_button'); dermObj.pageControls.qai.backButton = dermObj.pageControls.qai.quizPage.querySelector('.fmc_qai_back_button'); dermObj.pageControls.qai.update(); const urlObj = new URL(window.location.href); if (!urlObj.searchParams.has('qai_ds')) { urlObj.searchParams.set('qai_ds', 1); const newUrl = urlObj.toString(); history.pushState({}, '', newUrl); } }; dermObj.pageControls.qai.update = () => { const slidesVisibleCount = Math.max(1,dermObj.pageControls.qai.slider.querySelectorAll('.slide_visible').length); dermObj.pageControls.qai.slider.style.width = `${slidesVisibleCount}00%`; dermObj.pageControls.qai.slider.style.left = `-${dermObj.pageControls.qai.curIndex}00%`; dermObj.pageControls.qai.quizPage.querySelector('.fmc_qai_progress_bar').style.width = `${100*(dermObj.pageControls.qai.curIndex+1)/slidesVisibleCount}%`; dermObj.pageControls.qai.updateNavButtons(); } dermObj.pageControls.qai.nextSlide = () => { const currentSlide = dermObj.pageControls.qai.slider.querySelectorAll('.slide_visible')[dermObj.pageControls.qai.curIndex]; currentSlide.querySelectorAll('button.fmc_qai_answer_button:not(.is_selected)').forEach((selectedBtn)=>{ if (selectedBtn.dataset.qaiFollowUpSlide != undefined){ const followUpSlidesLabels = selectedBtn.dataset.qaiFollowUpSlide.split(','); followUpSlidesLabels.forEach((followUpSlideLabel)=>{ const followUpSlide = dermObj.pageControls.qai.slider.querySelector(`[data-qai-slide-label="${followUpSlideLabel}"]`); if (followUpSlide == undefined || followUpSlide == null) return; followUpSlide.classList.remove('slide_visible'); }) } }) currentSlide.querySelectorAll('button.fmc_qai_answer_button.is_selected').forEach((selectedBtn)=>{ if (selectedBtn.dataset.qaiFollowUpSlide != undefined){ const followUpSlidesLabels = selectedBtn.dataset.qaiFollowUpSlide.split(','); followUpSlidesLabels.forEach((followUpSlideLabel)=>{ const followUpSlide = dermObj.pageControls.qai.slider.querySelector(`[data-qai-slide-label="${followUpSlideLabel}"]`); if (followUpSlide == undefined || followUpSlide == null) return; followUpSlide.classList.add('slide_visible'); }) } }) const visibleSlides = dermObj.pageControls.qai.slider.querySelectorAll('.slide_visible') const slidesVisibleCount = Math.max(1,visibleSlides.length); dermObj.pageControls.qai.evaluateSlide(visibleSlides[dermObj.pageControls.qai.curIndex]); if (dermObj.pageControls.qai.nextButton.classList.contains('is_done_button')){ try{ dermObj.pageControls.qai.sendAnswers(); }catch(err){ console.log(err) } const urlObj = new URL(window.location.href); if (!urlObj.searchParams.has('qai_fn')) { urlObj.searchParams.set('qai_fn', 1); try{ urlObj.searchParams.set('qai_an', dermObj.pageControls.qai.urlParamAnswerArr.join('_')); }catch(err){console.error(err)} const newUrl = urlObj.toString(); history.pushState({}, '', newUrl); } dermObj.debug('QUIZ ANSWERS - ', JSON.stringify(dermObj.pageControls.qai.answerObj)); dermObj.gotoPage('waiting'); return; } dermObj.pageControls.qai.curIndex++; dermObj.pageControls.qai.curIndex = Math.min(dermObj.pageControls.qai.curIndex, slidesVisibleCount - 1 ); dermObj.pageControls.qai.update(); } dermObj.pageControls.qai.prevSlide = () => { dermObj.pageControls.qai.urlParamAnswerArr.pop(); const slidesVisibleCount = Math.max(1,dermObj.pageControls.qai.slider.querySelectorAll('.slide_visible').length); dermObj.pageControls.qai.curIndex--; dermObj.pageControls.qai.curIndex = Math.max(dermObj.pageControls.qai.curIndex,0 ); dermObj.pageControls.qai.update(); } dermObj.pageControls.qai.evaluateButtonClick = (evt)=>{ const currentBtn = evt.target; let currentSlide = currentBtn.parentElement; let generationCounter = 0; while (!currentSlide.classList.contains('fmc_qai_slide') && generationCounter < 5){ currentSlide = currentSlide.parentElement; generationCounter++; } if (generationCounter >= 5){ console.error('SLIDE NOT FOUND'); return; } const slideType = currentSlide.dataset.qaiSlideType; switch (slideType){ case "single": currentSlide.querySelectorAll('.fmc_qai_answer_button').forEach((btn)=>{ btn.classList.remove('is_selected'); }) currentBtn.classList.add('is_selected'); dermObj.pageControls.qai.updateNavButtons(); break; case "multiple": currentBtn.classList.toggle('is_selected'); dermObj.pageControls.qai.updateNavButtons(); break; case "list": dermObj.pageControls.qai.nextSlide(); break; default: console.error('TYPE NOT RECOGNIZED'); } } dermObj.pageControls.qai.updateNavButtons = ()=>{ const currentSlide = dermObj.pageControls.qai.slider.querySelectorAll('.slide_visible')[dermObj.pageControls.qai.curIndex]; const slideType = currentSlide.dataset.qaiSlideType; const slideOptional = currentSlide.dataset.qaiSlideOptional; if (dermObj.pageControls.qai.slider.querySelectorAll('.slide_visible').length - 1 == dermObj.pageControls.qai.curIndex){ dermObj.pageControls.qai.nextButton.classList.add('is_done_button'); }else{ dermObj.pageControls.qai.nextButton.classList.remove('is_done_button'); } if (dermObj.pageControls.qai.curIndex > 0){ dermObj.pageControls.qai.backButton.classList.add('is_active'); }else{ dermObj.pageControls.qai.backButton.classList.remove('is_active'); } if (slideOptional == 'true'){ dermObj.pageControls.qai.nextButton.classList.add('is_active'); return; } let selectedAnswers; let minAnswers; switch (slideType){ case 'single': selectedAnswers = currentSlide.querySelectorAll('button.fmc_qai_answer_button.is_selected').length; if (selectedAnswers > 0){ dermObj.pageControls.qai.nextButton.classList.add('is_active'); }else{ dermObj.pageControls.qai.nextButton.classList.remove('is_active'); } break; case 'multiple': selectedAnswers = currentSlide.querySelectorAll('button.fmc_qai_answer_button.is_selected').length; try{ minAnswers = Number(currentSlide.dataset.qaiAnswersMin) || 1; }catch(err){ minAnswers = 1; } if (selectedAnswers >= minAnswers){ dermObj.pageControls.qai.nextButton.classList.add('is_active'); }else{ dermObj.pageControls.qai.nextButton.classList.remove('is_active'); } break; case 'list': selectedAnswers = currentSlide.querySelectorAll('button.fmc_qai_answer_button.is_selected').length; try{ minAnswers = Number(currentSlide.dataset.qaiAnswersMin) || 1; }catch(err){ minAnswers = 1; } if (selectedAnswers >= minAnswers){ dermObj.pageControls.qai.nextButton.classList.add('is_active'); }else{ dermObj.pageControls.qai.nextButton.classList.remove('is_active'); } break; default: console.error('TYPE NOT RECOGNIZED'); } } dermObj.pageControls.qai.evaluateSlide = (slideToEval) => { let valueString = ''; let urlParamString = ''; try{ urlParamString ='Q' + slideToEval.dataset.qaiSlidePrefix; }catch(err){ console.error(err); } slideToEval.querySelectorAll('button.fmc_qai_answer_button.is_selected').forEach((selectedBtn)=>{ valueString += selectedBtn.dataset.qaiAnswerValue + ','; if (selectedBtn.dataset.qaiAnswerSuffix != undefined){ try{ urlParamString += 'A' + selectedBtn.dataset.qaiAnswerSuffix; }catch(err){ console.error(err); } } }) valueString = valueString.replace(/,$/g, ''); const slideLabel = slideToEval.dataset.qaiSlideLabel; dermObj.pageControls.qai.answerObj[dermObj.pageControls.qai.quizPage.id][slideLabel] = valueString; dermObj.pageControls.qai.urlParamAnswerArr.push(urlParamString); } dermObj.pageControls.qai.closeAutoCompleteBox = (evt) => { try{ if (evt.relatedTarget != undefined && evt.relatedTarget.classList.contains('fmc_qai_autocomplete_match')){ return; } let autoCompleteBox = dermObj.pageControls.qai.currentSlide.querySelector('.fmc_qai_auto_complete_box').innerHTML = ""; }catch(err){ console.log(err); } } dermObj.pageControls.qai.triggerAutoComplete = (evt) => { dermObj.pageControls.qai.currentSlide = evt.target.parentElement.parentElement; let autoCompleteBox = dermObj.pageControls.qai.currentSlide.querySelector('.fmc_qai_auto_complete_box'); let inputValue = event.target.value.toLowerCase(); let inputEl = event.target; // Filter the ingredientsList to only those which have a word that starts with the input value let matches = dermObj.pageControls.qai.ingredientsList.filter(item => { let words = item.toLowerCase().split(' '); return words.some(word => word.startsWith(inputValue)); }).slice(0, 12); // Generate buttons with the matching items function generateButtons(matches) { // Clear the autocomplete box autoCompleteBox.innerHTML = ''; if (matches.length > 0){ for (let i = 0; i < matches.length; i++) { // Create a new button element let btn = document.createElement('button'); btn.innerHTML = `${matches[i]}`; btn.classList.add('fmc_qai_autocomplete_match'); const ingredientName = matches[i]; btn.onclick = () => { inputEl.value = ''; autoCompleteBox.innerHTML = ''; dermObj.pageControls.qai.addIngredient(ingredientName); }; // Append the button to the auto complete box autoCompleteBox.appendChild(btn); } }else{ let btn = document.createElement('button'); btn.innerHTML = `no matching ingredient found`; btn.classList.add('fmc_qai_autocomplete_match'); autoCompleteBox.appendChild(btn); } } generateButtons(matches); } dermObj.pageControls.qai.addIngredient = (ingredientName)=>{ const answerBox = dermObj.pageControls.qai.currentSlide.querySelector('.fmc_qai_answer_container.fmc_qai_answers_list'); const btn = document.createElement('button'); const listIndex = dermObj.pageControls.qai.ingredientsList.indexOf(ingredientName); if (listIndex !== -1) { dermObj.pageControls.qai.ingredientsList.splice(listIndex, 1); } btn.classList.add('fmc_qai_answer_button','is_selected','fmc_qai_answer_list_item'); btn.dataset.qaiAnswerValue=ingredientName; btn.innerHTML = `${ingredientName}`; answerBox.appendChild(btn); if (answerBox.querySelector('.fmc_qai_display_on_emtpy_list') != undefined && answerBox.querySelector('.fmc_qai_display_on_emtpy_list') != null){ answerBox.querySelector('.fmc_qai_display_on_emtpy_list').style.display = 'none'; } btn.onclick = ()=>{ dermObj.pageControls.qai.ingredientsList.push(ingredientName); dermObj.pageControls.qai.ingredientsList = dermObj.pageControls.qai.ingredientsList.sort(); btn.remove(); const listItemsLength = answerBox.querySelectorAll('.fmc_qai_answer_list_item').length; if (listItemsLength == 0){ if (answerBox.querySelector('.fmc_qai_display_on_emtpy_list') != undefined && answerBox.querySelector('.fmc_qai_display_on_emtpy_list') != null){ answerBox.querySelector('.fmc_qai_display_on_emtpy_list').style.display = 'flex'; } } dermObj.pageControls.qai.updateNavButtons(); } dermObj.pageControls.qai.updateNavButtons(); //data-qai-answer-value } dermObj.pageControls.qai.sendAnswers = () =>{ dermObj.debug('SENDING QUIZ RESULTS CALL') if (dml_fmc.pageControls.qai == undefined) return; if (dml_fmc.pageControls.qai.answerObj == undefined) return; const beInterval = setInterval(()=>{ dermObj.debug('SENDING QUIZ RESULTS - INSIDE INTERVAL') if (dermObj.backendData == undefined || dermObj.backendData == null) return; if (dermObj.backendData.hashid == undefined || dermObj.backendData.hashid == null) return; dermObj.debug('SENDING QUIZ RESULTS FINAL') clearInterval(beInterval); const payload = { hashid : dermObj.backendData.hashid, quiz_after_image_responses: dermObj.pageControls.qai.answerObj } fetch(`${dermObj.backend}/fmc/quiz_after_image`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }) .then(response => response.json()) .then(data => { console.log('Data sent successfully:', data); }) .catch(error => { console.error('Error sending data:', error); }); },100) } dermObj.pageControls.qai.skipToResult = ()=>{ const urlObj = new URL(window.location.href); if (!urlObj.searchParams.has('qai_sk')) { urlObj.searchParams.set('qai_sk', 1); const newUrl = urlObj.toString(); history.pushState({}, '', newUrl); } dermObj.gotoPage('waiting'); } dermObj.pageControls.qai.keyIngredientsList = [ "Alpha Hydroxy Acids (AHAs)", "Antioxidants", "Ceramides", "Collagen", "Hyaluronic Acid", "Niacinamide", "Peptides", "Plant Extracts", "Retinol", "SPF", "Squalane", "Vitamin C" ]; dermObj.pageControls.waiting = {}; dermObj.pageControls.waiting.reset = ()=>{ let waitingPage = document.getElementById("fmc_waiting_page_default"); waitingPage.classList.remove("no_face_error", "multi_face_error", "resolution_error", "general_error", "too_dark_error", "overexposed_error" , "tilt_side_error", "tilt_up_down_error"); } dermObj.pageControls.waiting.buildLoadingText = async ()=>{ const loadingEl = document.getElementById("fmc_loading_results_text"); let loadingString; if (dermObj.lang_code.split('-')[0] != 'en'){ if (dermObj.textData['exact_phrases'].loading_results == 'loading results'){ loadingString = dermObj.textData.waiting_default.fmc_loading_analyze_text; }else{ loadingString = dermObj.textData['exact_phrases'].loading_results; } }else{ loadingString = dermObj.textData['exact_phrases'].loading_results; } // try with preset wave time const waveDuration = 1.5; const resetDelay = 0.5; const blueTime = (waveDuration - resetDelay) / loadingString.length; loadingEl.innerHTML = ''; for (let ii = 0; ii < loadingString.length; ii++){ const spanEl = document.createElement('span'); spanEl.innerHTML = loadingString[ii]; spanEl.style.animation = `fmcLetterBlink ${waveDuration}s ${blueTime * ii}s linear infinite`; loadingEl.appendChild(spanEl); } const bluePerc = (100*blueTime / waveDuration); const blinkStyle = document.createElement('style'); blinkStyle.innerHTML = `@keyframes fmcLetterBlink{\ 0%{color :#6BAAFF}\ ${bluePerc}%{color: #6BAAFF}\ ${bluePerc + 2}%{color: #5b6670}\ 98%{color: #5b6670}\ 100%{color :#6BAAFF}\ }` dermObj.widget_wrapper.appendChild(blinkStyle); } dermObj.pageControls.results_default = {}; dermObj.pageControls.results_default.concernIndex = 0; dermObj.pageControls.results_default.build = async ()=>{ try{ dermObj.storeLocator.updateStoreLocations().catch((err)=>{ console.warn(err); }) }catch(err){ console.warn(err); } try{ dermObj.pageControls.results_default.storeLocator.updateCarousel(); window.addEventListener('resize',dermObj.pageControls.results_default.storeLocator.updateCarousel); dermObj.swipeHandling.addSwiper(dermObj.pageControls.results_default.storeLocator.slider, dermObj.pageControls.results_default.storeLocator.nextStore, dermObj.pageControls.results_default.storeLocator.prevStore ); }catch(err){console.error("error in adding touch move events to store slider", err)} /* if (dermObj.backendData.dioxide_data != undefined && dermObj.backendData.dioxide_data != null){ dermObj.debug('using Dioxide Data from Backend'); dermObj.dioxideData = dermObj.backendData.dioxide_data; }else{ dermObj.debug('calling Dioxide for recommendations'); const dioxPayload = await dermObj.prepareDioxidePayload(dermObj.backendData, dermObj.lang_code) const dioxRes = await dermObj.getDioxideRecommendations(dioxPayload) dermObj.dioxideData = dioxRes; } */ if (dermObj.config.useTreatmentBanners && dermObj.dioxideData.skin_service != null && dermObj.countryCode == 'US' ){ dermObj.treatments.updateBanners(); } try{ dermObj.swipeHandling.addSwiper(document.querySelector("#fmc_results_page_default .fmc_results_mobile_concern_slides"), dermObj.pageControls.results_default.nextProduct, dermObj.pageControls.results_default.prevProduct ); }catch(err){console.error("error in adding touch move events to concern slider", err)} try{ dermObj.swipeHandling.addSwiper(document.querySelector("#fmc_results_page_default .fmc_regimen_product_slider"), dermObj.pageControls.results_default.regimen.next, dermObj.pageControls.results_default.regimen.back ); }catch(err){console.error("error in adding touch move events to regimen slider", err)} (async ()=>{ dermObj.masks.images = {}; try{ await dermObj.masks.getObscEyeRect(); }catch(err){ console.error(err); } try{ await dermObj.masks.getCropRect(); }catch(err){ console.error(err); } try{ await dermObj.masks.makeOriginalImages(); }catch(err){ console.error('error in making original mask images - ',err) } try{ await dermObj.masks.buildMasks(); }catch(err){ console.error('error in building masks - ',err) } dermObj.masks.applyImageData(); try{ document.querySelectorAll('.fmc_results_concerns_section.fmc_desktop_only .fmc_results_images_shift').forEach((shiftEl)=>{ const checkElementInterval = setInterval(()=>{ if (shiftEl.parentElement.offsetWidth > 0){ clearInterval(checkElementInterval); const containerWidth = shiftEl.parentElement.offsetWidth; const containerHeight = shiftEl.parentElement.offsetHeight; const scale = containerHeight / dermObj.masks.cropRect.originalImageHeight; try{ const faceCenter = scale * (dermObj.masks.cropRect.left + 0.5 * dermObj.masks.cropRect.width); shiftEl.style.left = `${Math.round(0.5*containerWidth - faceCenter)}px`; shiftEl.style.opacity = 1; }catch(err){ shiftEl.style.opacity = 1; } } },100) }) }catch(err){ console.error(err); } })(); await dermObj.pageControls.results_default.makeConcernsList(); if (dermObj.isIOS || dermObj.isMacLike){ dermObj.body.querySelectorAll('.dml_horizontally_centered_text').forEach((centerEl) => { centerEl.style.paddingTop = '0.2em'; }) } await dermObj.pageControls.results_default.regimen.build(); await dermObj.collectProductData(); await dermObj.applyProductData(dermObj.productData); dermObj.renderTextData(dermObj.textData); //dermObj.pageControls.results_default.concern.addSwipeDetection(); //dermObj.pageControls.results_default.regimen.addSwipeDetection(); window.addEventListener('resize',dermObj.pageControls.results_default.resizeElements, false); return; } dermObj.pageControls.results_default.makeConcernsList = async () => { await new Promise(async (resolve,reject)=>{ try{ await dermObj.pageControls.results_default.clearConcernLists(); }catch(err){console.error("error clearing concern lists - ",err)} try{ dermObj.dioxideData.sortedConcerns.forEach(async (concern,index)=>{ if (index < dermObj.config.maxConcerns){ await dermObj.pageControls.results_default.addConcernToConcernList(concern,index); await dermObj.pageControls.results_default.addProductToConcernProducts(concern,index); await dermObj.pageControls.results_default.addMobileConcernCard(concern,index); await dermObj.pageControls.results_default.addMobileConcernProduct(concern,index); } if ( index + 1 >= dermObj.dioxideData.sortedConcerns.length) resolve(); }) }catch(err){ console.error(err) resolve(); } }) document.querySelector("#fmc_results_concerns_products_carousel_desktop .fmc_results_products_slides").style.width = `${dermObj.dioxideData.sortedConcerns.length * 100}%`; document.querySelector("#fmc_results_page_default .fmc_results_mobile_concern_slides").style.width = `${dermObj.dioxideData.sortedConcerns.length * 100}%`; document.querySelectorAll("#fmc_results_concerns_products_carousel_desktop .fmc_results_products_slides .fmc_results_product_slide").forEach((slide)=>{ slide.style.width = `${1/dermObj.dioxideData.sortedConcerns.length * 100}%`; }) dermObj.renderTextData(dermObj.textData) const highestConcern = dermObj.dioxideData.sortedConcerns[0].name; document.querySelectorAll(`[data-widget-concern-img="${highestConcern}"]`).forEach((concernImg)=>{ concernImg.classList.add('fmc_displayed'); }) document.querySelectorAll("#fmc_results_page_default .fmc_concern_name_placeholder").forEach((placeholderEl)=>{ placeholderEl.innerHTML = ` ${dermObj.textData.results_default["fmc_concern_title_" + highestConcern]}`; }) dermObj.pageControls.results_default.focusSelectedConcern(); } dermObj.pageControls.results_default.clearConcernLists = async ()=>{ return new Promise (async (resolve, reject)=>{ document.getElementById("fmc_results_concerns_list").innerHTML = ""; document.querySelector("#fmc_results_page_default .fmc_results_products_slides").innerHTML = ""; document.querySelector('#fmc_results_page_default .fmc_results_mobile_concern_products').innerHTML = ""; document.querySelector('#fmc_results_page_default .fmc_results_mobile_concern_slides').innerHTML = ""; resolve(); }) } dermObj.pageControls.results_default.addConcernToConcernList = async (concernObj, concernIndex) => { const listContainer = document.getElementById("fmc_results_concerns_list"); let barColor = '#4caf50'; let barWidth = '30%'; const concernItem = document.createElement("div"); concernItem.classList.add(`fmc_concern_item_${concernObj.name}`, 'fmc_concern_info_item'); concernItem.dataset.widgetConcernIndex = concernIndex; try{ document.querySelector(`#fmc_results_page_default [data-widget-concern-img="${concernObj.name}"]`).dataset.widgetConcernIndex = concernIndex; }catch(err){ console.error(err) } let concernInnerHTMLString = `
`+ `

`; barWidth = `${concernObj.score * 20 - 10}%`; if (concernObj.score > 3){ barColor = '#da806e'; concernInnerHTMLString += '

'; }else if (concernObj.score > 1){ barColor = '#e9c353'; concernInnerHTMLString += '

'; } concernInnerHTMLString += '
'; concernInnerHTMLString += `

`; concernInnerHTMLString += `
`; concernItem.innerHTML = concernInnerHTMLString; listContainer.appendChild(concernItem); concernItem.addEventListener('click',dermObj.pageControls.results_default.selectThisConcern); return; } dermObj.pageControls.results_default.addProductToConcernProducts = async (concernObj, concernIndex) => { const slidesContainer = document.querySelector("#fmc_results_page_default .fmc_results_products_slides"); const pimcoreId = concernObj.recommended_product.pimcore_id; const prodImage = concernObj.recommended_product.imageUrl; const prodName = concernObj.recommended_product.name; const prodLink = concernObj.recommended_product.productUrl; const prodTagline = concernObj.recommended_product.tagline; const priceString = dermObj.makePriceString(concernObj.recommended_product); const prodCard = document.createElement("div") prodCard.classList.add("fmc_results_product_slide"); prodCard.dataset.widgetConcernIndex = concernIndex; prodCard.dataset.viewItemObserver = pimcoreId; prodCard.dataset.itemViewed = false; let cardHTMLString = ""; cardHTMLString += ``; if (dermObj.lang_code == 'ja'){ cardHTMLString += `

${prodName.toUpperCase()}

`; }else{ cardHTMLString += `

${prodName}

`; } cardHTMLString += `

${prodTagline}

`; cardHTMLString += ``; prodCard.innerHTML = cardHTMLString; slidesContainer.appendChild(prodCard); } dermObj.pageControls.results_default.addMobileConcernCard = async (concern,index) => { const slidesContainer = document.querySelector('#fmc_results_page_default .fmc_results_mobile_concern_slides'); const concernSlide = document.createElement('div'); concernSlide.classList.add('fmc_mobile_concern_slide'); concernSlide.dataset.widgetConcernIndex = index; concernSlide.style.width = `${1/dermObj.dioxideData.sortedConcerns.length * 100}%`; let slideHTMLString = ""; slideHTMLString += `
`; let indicatorColor; const concernTitle = dermObj.textData.results_default[`fmc_concern_title_${concern.name}`]; const polygonString = `polygon(100% 100%, 100% 0%, ${(concern.score - 1)* 15 + 30}% 0%, ${(concern.score - 1)* 15 + 30}% 100%)`; if (concern.score > 3){ indicatorColor = '#e21f26'; }else if (concern.score > 1){ indicatorColor = '#ff9635'; }else{ indicatorColor = '#6ea95f'; } slideHTMLString += `

${concernTitle}

`; slideHTMLString += `
`; slideHTMLString += `
`; slideHTMLString += `${dermObj.textData.product_buttons_labels.moderate}${dermObj.textData.product_buttons_labels.critical}`; slideHTMLString += `
`; slideHTMLString += `${dermObj.textData.product_buttons_labels.moderate}${dermObj.textData.product_buttons_labels.critical}`; slideHTMLString += `
`; slideHTMLString += `

`; slideHTMLString += `
`; concernSlide.innerHTML = slideHTMLString; slidesContainer.appendChild(concernSlide); } dermObj.pageControls.results_default.addMobileConcernProduct = async (concern,index) => { const productContainer = document.querySelector('#fmc_results_page_default .fmc_results_mobile_concern_products'); const productCard = document.createElement('div'); productCard.classList.add('fmc_mobile_product_card'); productCard.dataset.viewItemObserver = concern.recommended_product.pimcore_id; productCard.dataset.itemViewed = false; const pimcoreId = concern.recommended_product.pimcore_id; const prodImage = concern.recommended_product.imageUrl; const prodName = concern.recommended_product.name; const prodLink = concern.recommended_product.productUrl; const prodTagline = concern.recommended_product.tagline; const priceString = dermObj.makePriceString(concern.recommended_product); let indicatorColor; if (concern.score > 3){ indicatorColor = '#e21f26'; }else if (concern.score > 1){ indicatorColor = '#ff9635'; }else{ indicatorColor = '#6ea95f'; } let cardHTMLString = ``; if (dermObj.lang_code == 'ja'){ cardHTMLString += `

${prodName.toUpperCase()}

`; }else{ cardHTMLString += `

${prodName}

`; } cardHTMLString += `

${prodTagline}

`; cardHTMLString += ``; cardHTMLString += `

`; productCard.innerHTML = cardHTMLString; productContainer.appendChild(productCard); } dermObj.pageControls.results_default.nextProduct = ()=>{ if (dermObj.pageControls.results_default.concernIndex < Math.min(dermObj.dioxideData.sortedConcerns.length -1,dermObj.config.maxConcerns - 1) ){ dermObj.pageControls.results_default.concernIndex++; dermObj.pageControls.results_default.focusSelectedConcern(); } } dermObj.pageControls.results_default.prevProduct = ()=>{ if (dermObj.pageControls.results_default.concernIndex > 0 ){ dermObj.pageControls.results_default.concernIndex--; dermObj.pageControls.results_default.focusSelectedConcern(); } } dermObj.pageControls.results_default.focusSelectedConcern = async ()=>{ if (dermObj.pageControls.results_default.concernIndex == 0){ document.querySelectorAll('#fmc_results_page_default .fmc_carousel_back_button').forEach((backButton)=>{ backButton.classList.add("fmc_inactive"); }) }else{ document.querySelectorAll('#fmc_results_page_default .fmc_carousel_back_button').forEach((backButton)=>{ backButton.classList.remove("fmc_inactive"); }) } if (dermObj.pageControls.results_default.concernIndex == Math.min(dermObj.dioxideData.sortedConcerns.length -1,dermObj.config.maxConcerns - 1) ){ document.querySelectorAll('#fmc_results_page_default .fmc_carousel_next_button').forEach((nextButton)=>{ nextButton.classList.add("fmc_inactive"); }) }else{ document.querySelectorAll('#fmc_results_page_default .fmc_carousel_next_button').forEach((nextButton)=>{ nextButton.classList.remove("fmc_inactive"); }) } const slidesContainerDesktop = document.querySelector("#fmc_results_page_default .fmc_results_products_slides"); slidesContainerDesktop.style.left = `-${dermObj.pageControls.results_default.concernIndex * 100}%`; const slidesContainerMobile = document.querySelector("#fmc_results_page_default .fmc_results_mobile_concern_slides"); slidesContainerMobile.style.left = `-${dermObj.pageControls.results_default.concernIndex * 100}%`; document.querySelectorAll('#fmc_results_concerns_list .fmc_concern_info_item').forEach((concernItem)=>{ if (concernItem.dataset.widgetConcernIndex == dermObj.pageControls.results_default.concernIndex){ concernItem.classList.add('fmc_selected'); concernItem.parentElement.scrollTop = concernItem.offsetTop; }else{ concernItem.classList.remove('fmc_selected'); } }) document.querySelectorAll('#fmc_results_page_default .fmc_result_concern_image[data-widget-concern-index]').forEach((concernImage)=>{ if (concernImage.dataset.widgetConcernIndex == dermObj.pageControls.results_default.concernIndex){ concernImage.classList.add('fmc_displayed'); }else{ concernImage.classList.remove('fmc_displayed'); } }) dermObj.pageControls.results_default.resizeElements(); return; } dermObj.pageControls.results_default.toggleInfoCollapse = (evt)=>{ const isCollapsed = evt.target.parentElement.classList.toggle('fmc_collapsed'); } dermObj.pageControls.results_default.toggleInfoCollapseMobileCarousel = (evt)=>{ const isCollapsed = evt.target.parentElement.classList.contains('fmc_collapsed'); document.querySelectorAll('#fmc_results_page_default .fmc_results_mobile_concern_images .fmc_concern_info_wrapper').forEach((concernInfo)=>{ if (isCollapsed){ concernInfo.classList.remove('fmc_collapsed'); }else{ concernInfo.classList.add('fmc_collapsed'); } }) dermObj.pageControls.results_default.resizeElements(); } dermObj.pageControls.results_default.selectThisConcern = (evt)=>{ let cardItem; if (evt.target.classList.contains('fmc_concern_info_item')){ cardItem = evt.target; }else{ cardItem = evt.target.parentElement.parentElement; } dermObj.pageControls.results_default.concernIndex = cardItem.dataset.widgetConcernIndex; dermObj.pageControls.results_default.focusSelectedConcern(); } dermObj.pageControls.results_default.resizeElements = ()=>{ let maxHeight = Math.min(0.8*dermObj.body.offsetWidth, 400) + 160; document.querySelectorAll('#fmc_results_page_default .fmc_mobile_concern_card').forEach((concernCard)=>{ maxHeight = Math.max(maxHeight, concernCard.offsetHeight + 40); }) document.querySelector('#fmc_results_page_default .fmc_results_mobile_concern_images').style.height = `${maxHeight}px`; document.querySelectorAll('#fmc_results_page_default .fmc_result_mobile_concern_image').forEach((concernImage)=>{ concernImage.style.height = `${Math.min(0.8*dermObj.body.offsetWidth, 400)}px`; }) const nextBackArrowLeftRight = Math.max(5, 0.5*(dermObj.body.offsetWidth - Math.min(0.8*dermObj.body.offsetWidth, 400)) - 40); document.querySelector('#fmc_results_page_default .fmc_results_mobile_concern_images .fmc_carousel_next_button').style.right = `${nextBackArrowLeftRight}px`; document.querySelector('#fmc_results_page_default .fmc_results_mobile_concern_images .fmc_carousel_back_button').style.left = `${nextBackArrowLeftRight}px`; let cardWidth = 0.48*(Math.min(500,dermObj.body.offsetWidth) - 20); document.querySelectorAll('#fmc_results_page_default .fmc_results_mobile_concern_products .fmc_mobile_product_card').forEach((prodCard)=>{ prodCard.style.height = `${cardWidth * 1.4}px`; }) dermObj.pageControls.results_default.regimen.focusStep(); } dml_fmc.pageControls.results_default.restart = ()=>{ dermObj.sendGA360("main flow",'fashionplace restart button pressed'); dermObj.sendGAFlowEvent('fashionplace restart button pressed'); const urlParamsToRemove = ['ed6d4','b83d2','fmhid','be','r_ac','r_ds','r_du','r_ey','r_fr','r_hy','r_me','r_ra','r_re','r_sk','r_sm','r_te','r_un','r_wr', 'cnst','imupld', 'qni', 'qfc', 'qfl', 'fmc_shpr','qai_ds','qai_sk','qai_fn','qai_an','fmc_mnpg_d','fmc_mnpg_sc'] const urlParameters = window.location.search.replace('?','').split('&'); let urlString = '' urlParameters.forEach((parameterString)=>{ const urlParameterKey = parameterString.split('=')[0]; if (urlParamsToRemove.includes(urlParameterKey)){ // do nothing }else{ if (urlString == ''){ urlString += `?${parameterString}`; }else{ urlString += `&${parameterString}`; } } }) const baseUrl = window.location.href.split('?')[0]; window.history.replaceState('fmc_landing_page', '', `${baseUrl}${urlString}`); dermObj.backendData = undefined; dermObj.masks.images = {}; dermObj.pageControls.results_default.clearConcernLists(); dermObj.applyState(); //window.location.reload(); } dermObj.pageControls.results_default.regimen = {} dermObj.pageControls.results_default.regimen.currentIndex = 0; dermObj.pageControls.results_default.regimen.build = async ()=>{ if (dermObj.dioxideData.recommendedProducts.length == 6){ for (let regimenStep = 1; regimenStep < 7; regimenStep++){ try{ product = dermObj.dioxideData.recommendedProducts.filter((product) => {return product.regimen_index == regimenStep})[0]; productCard = document.querySelector(`#fmc_results_page_default .fmc_regimen_product_card[data-widget-regimen-index="${regimenStep-1}"]`); productCard.dataset.viewItemObserver = product.pimcore_id; productCard.dataset.itemViewed = false; productCard.querySelector('.fmc_regimen_title').dataset.widgetTextTerm = `regimen_step_${product.regimen_step}`; if (product.pimcore_id == 9211){ document.querySelector('#fmc_results_page_default .fmc_regimen_title').dataset.widgetTextTerm = `regimen_step_soothe`; } productCard.querySelector('.fmc_product_image').src = product.imageUrl; productCard.querySelector('.fmc_product_name').innerHTML = product.name; productCard.querySelector('.fmc_product_tagline').innerHTML = product.tagline; productCard.querySelector('.fmc_product_button').dataset.widgetProductBuy = product.pimcore_id; const priceString = dermObj.makePriceString(product); productCard.querySelectorAll('.fmc_price_string').forEach((priceEl)=>{ priceEl.innerHTML = ` | ${priceString}`; }) productCard.querySelectorAll('.fmc_regimen_price_only').forEach((priceOnly)=>{ priceOnly.innerHTML = `${priceString}`; }) }catch(err){ console.log(`error in building regimen at step ${regimenStep} - `,err); document.querySelector('#fmc_results_page_default .fmc_results_regimen_section').style.display ="none"; } } }else{ document.querySelector('#fmc_results_page_default .fmc_results_regimen_section').style.display ="none"; } } dermObj.pageControls.results_default.regimen.back = async ()=>{ if (dermObj.pageControls.results_default.regimen.currentIndex > 0){ dermObj.pageControls.results_default.regimen.currentIndex--; dermObj.pageControls.results_default.regimen.focusStep() } } dermObj.pageControls.results_default.regimen.next = async ()=>{ if (dermObj.pageControls.results_default.regimen.currentIndex < 5){ dermObj.pageControls.results_default.regimen.currentIndex++; dermObj.pageControls.results_default.regimen.focusStep() } } dermObj.pageControls.results_default.regimen.gotoRegimenStep = async (regimenStep) => { dermObj.pageControls.results_default.regimen.currentIndex = regimenStep; dermObj.pageControls.results_default.regimen.focusStep(); } dermObj.pageControls.results_default.regimen.focusStep = async () => { await dermObj.pageControls.results_default.regimen.resize(); document.querySelectorAll('.fmc_regimen_product_slider').forEach( async (regimenSlider)=>{ regimenSlider.querySelectorAll('.fmc_regimen_product_card').forEach((prodCard)=>{ if (prodCard.dataset.widgetRegimenIndex == dermObj.pageControls.results_default.regimen.currentIndex){ prodCard.classList.add('fmc_selected'); }else{ prodCard.classList.remove('fmc_selected'); } }) }) document.querySelectorAll('#fmc_results_page_default .fmc_regimen_carousel_container .fmc_regimen_back_button').forEach((backButton)=>{ if (dermObj.pageControls.results_default.regimen.currentIndex == 0){ backButton.classList.add('fmc_inactive'); }else{ backButton.classList.remove('fmc_inactive'); } }) document.querySelectorAll('#fmc_results_page_default .fmc_regimen_carousel_container .fmc_regimen_next_button').forEach((nextButton)=>{ if (dermObj.pageControls.results_default.regimen.currentIndex == 5){ nextButton.classList.add('fmc_inactive'); }else{ nextButton.classList.remove('fmc_inactive'); } }) } dermObj.pageControls.results_default.regimen.resize = async () => { document.querySelectorAll('.fmc_regimen_product_slider').forEach( async (regimenSlider)=>{ if (dermObj.body.classList.contains('dml_mobile')){ const cardSpace = Math.min(dermObj.body.offsetWidth * 0.85,300); const sliderWidth = cardSpace * 6; const sliderOffset = 0.5*(dermObj.body.offsetWidth - cardSpace); regimenSlider.style.width = `${sliderWidth}px`; regimenSlider.style.left = `${-dermObj.pageControls.results_default.regimen.currentIndex * cardSpace + sliderOffset }px`; }else{ regimenSlider.style.width = `200%`; regimenSlider.style.left = `${-(dermObj.pageControls.results_default.regimen.currentIndex-1) * 100 / 3 }%`; } }) return; } dermObj.pageControls.results_default.regimen.swipeHandling = { touchStartX : 0, touchCurrentX : 0, allowTouchEvent : true } dermObj.pageControls.results_default.regimen.addSwipeDetection = async ()=>{ document.querySelectorAll('.fmc_regimen_product_card').forEach((prodCard) => { prodCard.addEventListener('touchstart',(evt)=>{ try{ dermObj.pageControls.results_default.regimen.swipeHandling.touchStartX = evt.targetTouches[0].clientX; dermObj.pageControls.results_default.regimen.swipeHandling.touchCurrentX = evt.targetTouches[0].clientX; }catch(e){console.error(e)} }) prodCard.addEventListener('touchmove',(evt)=>{ try{ dermObj.pageControls.results_default.regimen.swipeHandling.touchCurrentX = evt.targetTouches[0].clientX; }catch(e){console.error(e)} }) prodCard.addEventListener('touchend',(evt)=>{ if (dermObj.pageControls.results_default.regimen.swipeHandling.allowTouchEvent && dermObj.body.classList.contains('dml_mobile')){ if (dermObj.pageControls.results_default.regimen.swipeHandling.touchCurrentX - dermObj.pageControls.results_default.regimen.swipeHandling.touchStartX > 30){ dermObj.pageControls.results_default.regimen.back(); dermObj.pageControls.results_default.regimen.swipeHandling.allowTouchEvent = false; setTimeout(()=>{ dermObj.pageControls.results_default.regimen.swipeHandling.allowTouchEvent = true; },500) } if (dermObj.pageControls.results_default.regimen.swipeHandling.touchCurrentX - dermObj.pageControls.results_default.regimen.swipeHandling.touchStartX < - 30){ dermObj.pageControls.results_default.regimen.next(); dermObj.pageControls.results_default.regimen.swipeHandling.allowTouchEvent = false; setTimeout(()=>{ dermObj.pageControls.results_default.regimen.swipeHandling.allowTouchEvent = true; },500) } } }) }) } dermObj.pageControls.results_default.storeLocator = { storeIndex : 0, storeIndexLimit : 2, slider : dermObj.body.querySelector('#fmc_results_page_default #fmc_skin_center_container') } dermObj.pageControls.results_default.storeLocator.updateCarousel = async () => { if (dermObj.body.classList.contains('dml_mobile')){ const sliderWidth = Math.min(dermObj.body.offsetWidth*2.4, 800); const cardWidth = sliderWidth * 0.31; dermObj.pageControls.results_default.storeLocator.slider.style.left = `${-dermObj.pageControls.results_default.storeLocator.storeIndex * 0.345*sliderWidth + 0.5* (0.95*dermObj.body.offsetWidth - cardWidth)}px`; }else{ dermObj.pageControls.results_default.storeLocator.slider.style.left = "0px"; } } dermObj.pageControls.results_default.storeLocator.nextStore = async () => { if (!dermObj.body.classList.contains('dml_mobile')) return; if (dermObj.pageControls.results_default.storeLocator.storeIndex >= dermObj.pageControls.results_default.storeLocator.storeIndexLimit) return; dermObj.pageControls.results_default.storeLocator.storeIndex++; dermObj.pageControls.results_default.storeLocator.updateCarousel(); } dermObj.pageControls.results_default.storeLocator.prevStore = async () => { if (!dermObj.body.classList.contains('dml_mobile')) return; if (dermObj.pageControls.results_default.storeLocator.storeIndex < 1) return; dermObj.pageControls.results_default.storeLocator.storeIndex--; dermObj.pageControls.results_default.storeLocator.updateCarousel(); } dermObj.pageControls.prep_treat_glow = {}; dermObj.pageControls.prep_treat_glow.curConcernIndex = 0; dermObj.pageControls.prep_treat_glow.concernOrder = [] dermObj.pageControls.prep_treat_glow.build = async ()=>{ /* if (dermObj.backendData.dioxide_data != undefined && dermObj.backendData.dioxide_data != null){ dermObj.debug('using Dioxide Data from Backend'); dermObj.dioxideData = dermObj.backendData.dioxide_data; }else{ dermObj.debug('calling Dioxide for recommendations'); const dioxPayload = await dermObj.prepareDioxidePayload(dermObj.backendData, dermObj.lang_code) const dioxRes = await dermObj.getDioxideRecommendations(dioxPayload) dermObj.dioxideData = dioxRes; } */ if (dermObj.dioxideData.prep_treat_glow == null || typeof dermObj.dioxideData.prep_treat_glow == 'undefined'){ dermObj.config.pageDict.results = 'fmc_results_page_default'; dermObj.gotoPage('results'); return; } dermObj.body.querySelector('#fmc_results_prep_treat_glow').style.opacity = 1; dermObj.pageControls.prep_treat_glow.updateProducts(); if (dermObj.config.useTreatmentBanners && dermObj.dioxideData.skin_service != null && dermObj.countryCode == 'US' ){ dermObj.treatments.updateBanners(); } try{ dermObj.pageControls.prep_treat_glow.concernOrder = dermObj.dioxideData.sortedConcerns.map((concern) => {return concern.concern_key}); if (dermObj.pageControls.prep_treat_glow.concernOrder[0] == 'dehydration'){ dermObj.pageControls.prep_treat_glow.concernOrder[0] = dermObj.pageControls.prep_treat_glow.concernOrder[1]; dermObj.pageControls.prep_treat_glow.concernOrder[1] = 'dehydration'; } }catch(err){ console.error(err) } try{ await dermObj.pageControls.prep_treat_glow.refineCopy(); }catch(err){ dermObj.dioxideData.prep_treat_glow.copyLogic = { breakouts : { isWellSuited : false, concernProductId: -1 }, wrinkles : { isWellSuited : false, concernProductId: -1 }, dark_circles : { isWellSuited : false, concernProductId: -1 }, dehydration : { isWellSuited : false, concernProductId: -1 }, redness : { isWellSuited : false, concernProductId: -1 }, oiliness : { isWellSuited : false, concernProductId: -1 } } console.error('error in refining prep treat glow copy - ',err); } const prepProdName = dermObj.dioxideData.prep_treat_glow.prep.name; const treatProdName = dermObj.dioxideData.prep_treat_glow.treat.name; const glowProdName = dermObj.dioxideData.prep_treat_glow.glow.name; /* DISABLED MISMATCHING COPY FOR NOW dermObj.textData.results_prep_treat_glow.prep_treat_glow_suggest = dermObj.textData.results_prep_treat_glow.prep_treat_glow_suggest .replace('__PREP__',`${prepProdName}`) .replace('__TREAT__',`${treatProdName}`) .replace('__GLOW__',`${glowProdName}`) dermObj.body.querySelector('#fmc_prep_treat_glow_suggestion_copy').innerHTML = dermObj.textData.results_prep_treat_glow.prep_treat_glow_suggest; */ try{ const topConcern = dermObj.pageControls.prep_treat_glow.concernOrder[0]; dermObj.body.querySelectorAll('#fmc_results_prep_treat_glow .fmc_top_concern_only').forEach((el)=>{el.style.display = 'none'}); dermObj.body.querySelectorAll(`#fmc_results_prep_treat_glow .fmc_prep_treat_glow_slider_label_text.fmc_concern_${topConcern} .fmc_top_concern_only`).forEach((el)=>{el.style.display = 'inline-block'}); dermObj.pageControls.prep_treat_glow.selectConcern(topConcern); if (dermObj.config.useShopify === true){ dermObj.body.querySelector('#fmc_results_prep_treat_glow button.fmc_add_all_to_cart').style.display = 'flex'; //dermObj.body.querySelector('#fmc_results_prep_treat_glow #fmc_prep_treat_glow_add_all_in_info').style.display = 'inline-block'; } }catch(err){ console.error(err) } dermObj.masks.images = {}; try{ await dermObj.masks.getObscEyeRect(); }catch(err){ console.error(err); } try{ await dermObj.masks.getCropRect(); }catch(err){ console.error(err); } try{ await dermObj.masks.makeOriginalImages(); }catch(err){ console.error('error in making original mask images - ',err) } if (dermObj.config.skipMasks){ dermObj.debug('SKIP MASKS PREP TREAT GLOW'); dermObj.masks.images.acne = dermObj.masks.images.original; dermObj.masks.images.acne_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.darkCircles = dermObj.masks.images.original; dermObj.masks.images.darkCircles_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.dehydration = dermObj.masks.images.original; dermObj.masks.images.dehydration_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.oiliness = dermObj.masks.images.original; dermObj.masks.images.oiliness_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.redness = dermObj.masks.images.original; dermObj.masks.images.redness_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.wrinkles = dermObj.masks.images.original; dermObj.masks.images.wrinkles_cropped = dermObj.masks.images.original_cropped; }else{ (async ()=>{ dermObj.masks.buildMasks(); })(); } dermObj.masks.applyImageData() } dermObj.pageControls.prep_treat_glow.updateProducts = async (concernName)=>{ let selectedProdIndices = [] for (let ii=0; ii < 3; ii++){ let stepLabel; switch (ii){ case 0: stepLabel='prep'; break; case 1: stepLabel='treat'; break; case 2: stepLabel='glow'; break; } const prodCard = document.querySelector(`#fmc_results_prep_treat_glow #fmc_prep_treat_glow_card_${stepLabel}`); const product = dermObj.dioxideData.prep_treat_glow[stepLabel]; dermObj.productData[product.pimcore_id] = product; prodCard.querySelectorAll('.fmc_product_name').forEach((prodNameEl) => {prodNameEl.innerHTML = product.name}); prodCard.querySelectorAll('.fmc_product_price').forEach((prodPriceEl) => {prodPriceEl.innerHTML = `${product.priceCurrency} ${product.price}`}); prodCard.querySelector('.fmc_product_description').innerHTML = product.mediumDescription; prodCard.querySelector('.fmc_product_button').dataset.widgetProductBuy = product.pimcore_id; prodCard.querySelector('.fmc_product_image').dataset.widgetProductBackground = product.pimcore_id; prodCard.dataset.viewItemObserver = product.pimcore_id; prodCard.dataset.itemViewed = false; if (ii == 2){ dermObj.applyProductData(dermObj.productData); } } } dermObj.pageControls.prep_treat_glow.selectConcern = (concernIdIn)=>{ const concernId = concernIdIn == 'acne' ? 'breakouts' : concernIdIn; const resultsPage = dermObj.body.querySelector('#fmc_results_prep_treat_glow'); const otherScoreLabel = resultsPage.querySelector('.fmc_other_users_label'); const yourScoreLabel = resultsPage.querySelector('.fmc_your_score_label'); const indBarGreyBlend = resultsPage.querySelector('.fmc_prep_treat_glow_indicator_bar_grey_blend'); resultsPage.classList.remove('fmc_concern_breakouts','fmc_concern_dark_circles','fmc_concern_wrinkles','fmc_concern_oiliness','fmc_concern_redness','fmc_concern_dehydration') switch (concernId){ case 'breakouts': resultsPage.classList.add('fmc_concern_breakouts'); otherScoreLabel.style.left = '18%'; if (dermObj.backendData.revieve_acne_value == 0 || dermObj.backendData.revieve_acne_value == null){ dermObj.backendData.revieve_acne_value = 0.18 } yourScoreLabel.style.left = `${100 * dermObj.backendData.revieve_acne_value}%`; indBarGreyBlend.style.width = `${100 * ( 1 - dermObj.backendData.revieve_acne_value )}%`; break; case 'dark_circles': resultsPage.classList.add('fmc_concern_dark_circles'); otherScoreLabel.style.left = '25%'; yourScoreLabel.style.left = `${100 * dermObj.backendData.dark_circles_score / 5}%`; indBarGreyBlend.style.width = `${100 * ( 1 - dermObj.backendData.dark_circles_score / 5 )}%`; break; case 'wrinkles': resultsPage.classList.add('fmc_concern_wrinkles'); otherScoreLabel.style.left = '27%'; yourScoreLabel.style.left = `${100 * dermObj.backendData.revieve_wrinkles_value}%`; indBarGreyBlend.style.width = `${100 * ( 1 - dermObj.backendData.revieve_wrinkles_value )}%`; break; case 'redness': resultsPage.classList.add('fmc_concern_redness'); otherScoreLabel.style.left = '23%'; yourScoreLabel.style.left = `${100 * dermObj.backendData.revieve_redness_value}%`; indBarGreyBlend.style.width = `${100 * ( 1 - dermObj.backendData.revieve_redness_value )}%`; break; case 'dehydration': resultsPage.classList.add('fmc_concern_dehydration'); otherScoreLabel.style.left = '30%'; yourScoreLabel.style.left = `35%`; indBarGreyBlend.style.width = `65%`; break; case 'oiliness': resultsPage.classList.add('fmc_concern_oiliness'); otherScoreLabel.style.left = '48%'; yourScoreLabel.style.left = `${100 * dermObj.backendData.revieve_skin_shine_value}%`; indBarGreyBlend.style.width = `${100 * ( 1 - dermObj.backendData.revieve_skin_shine_value )}%`; break; default: resultsPage.classList.add('fmc_concern_oiliness'); otherScoreLabel.style.left = '48%'; yourScoreLabel.style.left = `${100 * dermObj.backendData.revieve_skin_shine_value}%`; indBarGreyBlend.style.width = `${100 * ( 1 - dermObj.backendData.revieve_skin_shine_value )}%`; } /* --- DIABLED COPY CHANGE FOR NOW if (dermObj.dioxideData.prep_treat_glow.copyLogic[concernId].isWellSuited === true ){ let combinationCopy = ''; if (concernId == 'dark_circles'){ combinationCopy = dermObj.textData.results_prep_treat_glow.prep_treat_glow_combination .replace('__CURRENT_CONCERN__',`${dml_fmc.textData.concerns.dark_circles_alternative}`); }else{ combinationCopy = dermObj.textData.results_prep_treat_glow.prep_treat_glow_combination .replace('__CURRENT_CONCERN__',`${dml_fmc.textData.concerns[concernIdIn]}`); } dermObj.body.querySelector('#fmc_prep_treat_glow_concern_combination_copy').innerHTML = combinationCopy; dermObj.body.querySelector('#fmc_prep_treat_glow_concern_combination_copy').style.display = 'inline'; }else{ dermObj.body.querySelector('#fmc_prep_treat_glow_concern_combination_copy').style.display = 'none'; } if (dermObj.dioxideData.prep_treat_glow.copyLogic[concernId].concernProductId > 0){ let dioxAllCheck = setInterval(()=>{ if (dermObj.dioxideAllProducts != undefined && dermObj.dioxideAllProducts != null ){ clearInterval(dioxAllCheck); let concernProductCopy = ''; if (concernId == 'dark_circles'){ concernProductCopy = dermObj.textData.results_prep_treat_glow.prep_treat_glow_primary_concern_product .replace('__CURRENT_CONCERN__', `${dml_fmc.textData.concerns.dark_circles_alternative}`) .replace('__PRODUCT__', `${dml_fmc.dioxideAllProducts.filter((product) => product.pimcoreId == dermObj.dioxideData.prep_treat_glow.copyLogic[concernId].concernProductId)[0].name}` ) }else{ concernProductCopy = dermObj.textData.results_prep_treat_glow.prep_treat_glow_primary_concern_product .replace('__CURRENT_CONCERN__', `${dml_fmc.textData.concerns[concernIdIn]}`) .replace('__PRODUCT__', `${dml_fmc.dioxideAllProducts.filter((product) => product.pimcoreId == dermObj.dioxideData.prep_treat_glow.copyLogic[concernId].concernProductId)[0].name}` ) } dermObj.body.querySelector('#fmc_prep_treat_glow_info_copy_2').innerHTML = concernProductCopy; dermObj.body.querySelector('#fmc_prep_treat_glow_info_copy_2').style.display = 'block'; } },100) }else{ dermObj.body.querySelector('#fmc_prep_treat_glow_info_copy_2').style.display = 'none'; } */ } dermObj.pageControls.prep_treat_glow.redoAnalysis = () => { dermObj.debug('REDO ANALYSIS'); dermObj.sendGA360("main flow","redo analysis - prep treat glow"); dermObj.sendGAFlowEvent("redo analysis - prep treat glow"); dermObj.pageControls.waiting.reset(); dermObj.removeUrlParameters('capture',['rspg','be']); dermObj.gotoPage('capture'); } dermObj.pageControls.prep_treat_glow.nextConcern = ()=>{ dermObj.pageControls.prep_treat_glow.curConcernIndex++; if (dermObj.pageControls.prep_treat_glow.curConcernIndex > dermObj.pageControls.prep_treat_glow.concernOrder.length - 1 ){ dermObj.pageControls.prep_treat_glow.curConcernIndex = 0; } const nextConcern = dermObj.pageControls.prep_treat_glow.concernOrder[dermObj.pageControls.prep_treat_glow.curConcernIndex]; dermObj.pageControls.prep_treat_glow.selectConcern(nextConcern); } dermObj.pageControls.prep_treat_glow.prevConcern = ()=>{ dermObj.pageControls.prep_treat_glow.curConcernIndex--; if (dermObj.pageControls.prep_treat_glow.curConcernIndex < 0 ){ dermObj.pageControls.prep_treat_glow.curConcernIndex = dermObj.pageControls.prep_treat_glow.concernOrder.length - 1; } const prevConcern = dermObj.pageControls.prep_treat_glow.concernOrder[dermObj.pageControls.prep_treat_glow.curConcernIndex]; dermObj.pageControls.prep_treat_glow.selectConcern(prevConcern); } dermObj.pageControls.prep_treat_glow.allowAddAllToCartFlag = true; dermObj.pageControls.prep_treat_glow.addAllToCart = async ()=>{ if (dermObj.pageControls.prep_treat_glow.allowAddAllToCartFlag === true){ dermObj.pageControls.prep_treat_glow.allowAddAllToCartFlag = false; setTimeout(()=>{ dermObj.pageControls.prep_treat_glow.allowAddAllToCartFlag = true; },500) dermObj.sendGA360("main flow",'add all to cart button clicked'); dermObj.sendGAFlowEvent('add all to cart button clicked'); const variantIdArray = []; dermObj.body.querySelectorAll('#fmc_results_prep_treat_glow button.fmc_product_button').forEach(async (buyButton, index)=>{ const variantId = dermObj.productData[buyButton.dataset.widgetProductBuy].variants.filter((variantObj) => variantObj.default === true)[0].shopify_variant_id; variantIdArray.push(variantId) }) try{ await dermObj.addMultipleToBagShopify( variantIdArray); dermObj.body.querySelector('#fmc_results_prep_treat_glow #fmc_prep_treat_glow_add_all_in_info').style.display = 'none'; dermObj.body.querySelector('#fmc_results_prep_treat_glow button.fmc_add_all_to_cart').classList.add('fmc_added_to_cart'); }catch(err){ console.error(err); dermObj.debug('hiding add all to cart buttons'); dermObj.body.querySelector('#fmc_results_prep_treat_glow button.fmc_add_all_to_cart').style.display = 'none'; dermObj.body.querySelector('#fmc_results_prep_treat_glow #fmc_prep_treat_glow_add_all_in_info').style.display = 'none'; } } } dermObj.pageControls.prep_treat_glow.refineCopy = async ()=> { return new Promise((resolve, reject)=>{ const rawCopyObj = {...dml_fmc.dioxideData.prep_treat_glow.copy}; const refinedCopyObj = { breakouts : { isWellSuited : false, concernProductId: -1 }, wrinkles : { isWellSuited : false, concernProductId: -1 }, dark_circles : { isWellSuited : false, concernProductId: -1 }, dehydration : { isWellSuited : false, concernProductId: -1 }, redness : { isWellSuited : false, concernProductId: -1 }, oiliness : { isWellSuited : false, concernProductId: -1 } }; const wellSuitedArray = rawCopyObj.particularly_well_suited; if (wellSuitedArray.includes('revieve_acne_value')){ refinedCopyObj.breakouts.isWellSuited = true; } if (wellSuitedArray.includes('revieve_wrinkles_value')){ refinedCopyObj.wrinkles.isWellSuited = true; } if (wellSuitedArray.includes('revieve_eyes_value')){ refinedCopyObj.dark_circles.isWellSuited = true; } if (wellSuitedArray.includes('revieve_texture_value')){ refinedCopyObj.dehydration.isWellSuited = true; } if (wellSuitedArray.includes('revieve_redness_value')){ refinedCopyObj.redness.isWellSuited = true; } if (wellSuitedArray.includes('revieve_skin_shine_value')){ refinedCopyObj.oiliness.isWellSuited = true; } const concernProductArray = Object.keys(rawCopyObj.cluster_concern_product); if (concernProductArray.includes('revieve_acne_value')){ refinedCopyObj.breakouts.concernProductId = rawCopyObj.cluster_concern_product.revieve_acne_value; } if (concernProductArray.includes('revieve_wrinkles_value')){ refinedCopyObj.wrinkles.concernProductId = rawCopyObj.cluster_concern_product.revieve_wrinkles_value; } if (concernProductArray.includes('revieve_eyes_value')){ refinedCopyObj.dark_circles.concernProductId = rawCopyObj.cluster_concern_product.revieve_eyes_value; } if (concernProductArray.includes('revieve_texture_value')){ refinedCopyObj.dehydration.concernProductId = rawCopyObj.cluster_concern_product.revieve_texture_value; } if (concernProductArray.includes('revieve_redness_value')){ refinedCopyObj.redness.concernProductId = rawCopyObj.cluster_concern_product.revieve_redness_value; } if (concernProductArray.includes('revieve_skin_shine_value')){ refinedCopyObj.oiliness.concernProductId = rawCopyObj.cluster_concern_product.revieve_skin_shine_value; } dermObj.dioxideData.prep_treat_glow.copyLogic = {...refinedCopyObj}; resolve(); }) } dermObj.pageControls.brand_campaign = {}; dermObj.pageControls.brand_campaign.curConcernIndex = 0; dermObj.pageControls.brand_campaign.concernOrder = [] dermObj.pageControls.brand_campaign.proBrightLink = ''; dermObj.pageControls.brand_campaign.bookNowLink = ''; dermObj.pageControls.brand_campaign.cardTitleScaleFact = 1; dermObj.pageControls.brand_campaign.build = async () => { //dermObj.debug('BUILD BRAND CAMPAIGN') if (dermObj.backendData.dioxide_data != undefined && dermObj.backendData.dioxide_data != null){ dermObj.debug('using Dioxide Data from Backend'); dermObj.dioxideData ={... dermObj.backendData.dioxide_data}; } else { dermObj.debug('calling Dioxide for recommendations'); const dioxPayload = await dermObj.prepareDioxidePayload(dermObj.backendData, dermObj.lang_code) const dioxRes = await dermObj.getDioxideRecommendations(dioxPayload) dermObj.dioxideData = dioxRes; } if (dermObj.dioxideData.brand_campaign == null || typeof dermObj.dioxideData.brand_campaign == 'undefined') { dermObj.config.pageDict.results = 'fmc_results_page_default'; dermObj.gotoPage('results'); return; } dermObj.pageControls.brand_campaign.adjustDropDownWidth(); window.addEventListener('resize',dermObj.pageControls.brand_campaign.adjustDropDownWidth) window.addEventListener('resize',dermObj.pageControls.brand_campaign.resizeCardImages) window.addEventListener('resize',dermObj.pageControls.brand_campaign.resizeCardTitles) const chatEnabled = await dermObj.chat.chatEnabledCheck(); if (chatEnabled){ document.querySelector('#fmc_results_brand_campaign .fmc_contact_section').style.display = 'flex'; } dermObj.body.querySelector('#fmc_results_brand_campaign').style.opacity = 1; await dermObj.pageControls.brand_campaign.sortConcernsForBrandCampaign(); dermObj.pageControls.brand_campaign.concernOrder = dermObj.dioxideData.sortedBrandConcerns.map((concern) => {return concern.concern_key}); dermObj.debug(dermObj.pageControls.brand_campaign.concernOrder) if (dermObj.pageControls.brand_campaign.concernOrder[0] == "dehydration") { dermObj.pageControls.brand_campaign.concernOrder[0] = dermObj.pageControls.brand_campaign.concernOrder[1]; dermObj.pageControls.brand_campaign.concernOrder[1] = "dehydration"; } const topConcern = dermObj.pageControls.brand_campaign.concernOrder[0]; dermObj.dioxideData.brand_campaign.topConcern = topConcern; dermObj.body.querySelectorAll('#fmc_results_brand_campaign .fmc_top_concern_only').forEach((el)=>{el.style.display = 'none'}); dermObj.body.querySelectorAll(`#fmc_results_brand_campaign .fmc_brand_campaign_slider_label_text.fmc_concern_${topConcern} .fmc_top_concern_only`).forEach((el)=>{el.style.display = 'inline-block'}); dermObj.pageControls.brand_campaign.raw_concern_header = dermObj.textData.brand_campaign.brand_campaign_results_concern_header; dermObj.pageControls.brand_campaign.raw_concern_header_under_eye_area = dermObj.textData.brand_campaign.brand_campaign_results_concern_header_under_eye_area; dermObj.textData.brand_campaign.brand_campaign_results_concern_header = dermObj.textData.brand_campaign.brand_campaign_results_concern_header.replace('__CONCERN__', `${dermObj.textData.concerns[topConcern]}`); dermObj.textData.brand_campaign.brand_campaign_results_concern_header_under_eye_area = dermObj.textData.brand_campaign.brand_campaign_results_concern_header_under_eye_area.replace('__CONCERN__', `${dermObj.textData.concerns.dark_circles}`); dermObj.textData.brand_campaign.brand_campaign_survey_question_one_new = dermObj.textData.brand_campaign.brand_campaign_survey_question_one_new.replace('__CONCERN__', dermObj.textData.concerns[topConcern]); dermObj.renderTextData(dermObj.textData); dermObj.pageControls.brand_campaign.selectTopConcern(topConcern, true); dermObj.masks.images = {}; try { await dermObj.masks.getObscEyeRect(); } catch(err){ console.error(err); } try { await dermObj.masks.getCropRect(); } catch(err){ console.error(err); } try { await dermObj.masks.makeOriginalImages(); } catch(err){ console.error('error in making original mask images - ',err) } if (dermObj.config.skipMasks) { dermObj.debug('SKIP MASKS BRAND CAMPAIGN'); dermObj.masks.images.acne = dermObj.masks.images.original; dermObj.masks.images.acne_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.darkCircles = dermObj.masks.images.original; dermObj.masks.images.darkCircles_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.dehydration = dermObj.masks.images.original; dermObj.masks.images.dehydration_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.oiliness = dermObj.masks.images.original; dermObj.masks.images.oiliness_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.redness = dermObj.masks.images.original; dermObj.masks.images.redness_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.wrinkles = dermObj.masks.images.original; dermObj.masks.images.wrinkles_cropped = dermObj.masks.images.original_cropped; } else { (async ()=>{ dermObj.masks.buildMasks(); })(); } dermObj.masks.applyImageData(); if (dermObj.config.useTreatmentBanners && dermObj.dioxideData.skin_service != null && dermObj.countryCode == 'US' ){ dermObj.treatments.updateBanners(); } } dermObj.pageControls.brand_campaign.selectTopConcern = (concernIdIn, isAnalyzedTopConcern = false) => { const concernId = concernIdIn == 'acne' ? 'breakouts' : concernIdIn; if (concernId == 'dark_circles'){ dermObj.body.querySelector('#fmc_brand_campaign_concerns_results_desc span.fmc_desc_beginning_top_concern_under_eye_area').style.display = 'inline'; dermObj.body.querySelector('#fmc_brand_campaign_concerns_results_desc span.fmc_desc_beginning_top_concern').style.display = 'none'; }else{ dermObj.body.querySelector('#fmc_brand_campaign_concerns_results_desc span.fmc_desc_beginning_top_concern_under_eye_area').style.display = 'none'; dermObj.body.querySelector('#fmc_brand_campaign_concerns_results_desc span.fmc_desc_beginning_top_concern').style.display = 'inline'; } dermObj.body.querySelector('#fmc_brand_campaign_top_concern_selected_text').innerHTML = dermObj.textData.concerns[concernIdIn]; dermObj.pageControls.brand_campaign.recomendationControls(concernIdIn) dermObj.pageControls.brand_campaign.selectConcernImage(concernIdIn); dermObj.pageControls.brand_campaign.curConcernIndex = dermObj.pageControls.brand_campaign.concernOrder.indexOf(concernIdIn); if (isAnalyzedTopConcern){ dermObj.sendGA360("main flow",`brand_campaign top concern - analysis - ${concernId}`); dermObj.sendGAFlowEvent(`brand_campaign top concern - analysis - ${concernId}`); }else{ dermObj.sendGA360("main flow",`brand_campaign top concern - userSelect - ${concernId}`); dermObj.sendGAFlowEvent(`brand_campaign top concern - userSelect - ${concernId}`); } dermObj.body.querySelectorAll('#fmc_results_brand_campaign button.fmc_product_button').forEach((prodBtn) => { if (prodBtn.classList.contains('dml_added_to_bag_button')){ prodBtn.classList.remove('dml_added_to_bag_button'); prodBtn.classList.add('dml_is_add_to_bag_button'); } }) //console.log("top concern: " + concernId) } dermObj.pageControls.brand_campaign.selectConcernImage = (concernIdIn)=>{ const concernId = concernIdIn == 'acne' ? 'breakouts' : concernIdIn; const resultsPage = dermObj.body.querySelector('#fmc_results_brand_campaign'); const otherScoreLabel = resultsPage.querySelector('.fmc_other_users_label'); const yourScoreLabel = resultsPage.querySelector('.fmc_your_score_label'); const indBarGreyBlend = resultsPage.querySelector('.fmc_brand_campaign_indicator_bar_grey_blend'); resultsPage.querySelectorAll('img[data-widget-concern-img-cropped]').forEach((concernImage) => { if (concernImage.dataset.widgetConcernImgCropped == concernIdIn){ concernImage.style.display = 'block'; }else{ concernImage.style.display = 'none'; } }) const brandCampaignData = dermObj.dioxideData.brand_campaign; resultsPage.querySelector('#fmc_brand_campaign_concern_image_label').innerHTML = dermObj.textData.concerns[concernIdIn]; switch (concernId){ case 'breakouts': otherScoreLabel.style.left = '18%'; if (brandCampaignData.acne.score == 0 || brandCampaignData.acne.score == null) { brandCampaignData.acne.score = 0.18; } yourScoreLabel.style.left = `${100 * brandCampaignData.acne.score}%`; indBarGreyBlend.style.width = `${100 * ( 1 - brandCampaignData.acne.score )}%`; break; case 'dark_circles': otherScoreLabel.style.left = '25%'; yourScoreLabel.style.left = `${100 * brandCampaignData.dark_circles.score}%`; indBarGreyBlend.style.width = `${100 * ( 1 - brandCampaignData.dark_circles.score )}%`; break; case 'wrinkles': otherScoreLabel.style.left = '27%'; yourScoreLabel.style.left = `${100 * brandCampaignData.wrinkles.score}%`; indBarGreyBlend.style.width = `${100 * ( 1 - brandCampaignData.wrinkles.score )}%`; break; case 'redness': otherScoreLabel.style.left = '23%'; yourScoreLabel.style.left = `${100 * brandCampaignData.redness.score}%`; indBarGreyBlend.style.width = `${100 * ( 1 - brandCampaignData.redness.score )}%`; break; case 'dehydration': otherScoreLabel.style.left = '20%'; yourScoreLabel.style.left = `25%`; indBarGreyBlend.style.width = `75%`; break; case 'dull_skin': otherScoreLabel.style.left = '34%'; yourScoreLabel.style.left = `${100 * brandCampaignData.dull_skin.score}%`; indBarGreyBlend.style.width = `${100 * ( 1 - brandCampaignData.dull_skin.score )}%`; break; case 'dark_spots': otherScoreLabel.style.left = '17%'; yourScoreLabel.style.left = `${100 * brandCampaignData.dark_spots.score}%`; indBarGreyBlend.style.width = `${100 * ( 1 - brandCampaignData.dark_spots.score )}%`; break; default: otherScoreLabel.style.left = '48%'; yourScoreLabel.style.left = `${100 * brandCampaignData.dull_skin.score}%`; indBarGreyBlend.style.width = `${100 * ( 1 - brandCampaignData.dull_skin.score )}%`; } } dermObj.pageControls.brand_campaign.nextConcern = ()=>{ dermObj.pageControls.brand_campaign.curConcernIndex++; if (dermObj.pageControls.brand_campaign.curConcernIndex > dermObj.pageControls.brand_campaign.concernOrder.length - 1 ){ dermObj.pageControls.brand_campaign.curConcernIndex = 0; } const nextConcern = dermObj.pageControls.brand_campaign.concernOrder[dermObj.pageControls.brand_campaign.curConcernIndex]; dermObj.pageControls.brand_campaign.selectConcernImage(nextConcern); } dermObj.pageControls.brand_campaign.prevConcern = ()=>{ dermObj.pageControls.brand_campaign.curConcernIndex--; if (dermObj.pageControls.brand_campaign.curConcernIndex < 0 ){ dermObj.pageControls.brand_campaign.curConcernIndex = dermObj.pageControls.brand_campaign.concernOrder.length - 1; } const prevConcern = dermObj.pageControls.brand_campaign.concernOrder[dermObj.pageControls.brand_campaign.curConcernIndex]; dermObj.pageControls.brand_campaign.selectConcernImage(prevConcern); } dermObj.pageControls.brand_campaign.ingredientsToggle = (evt) => { const toggleButton = evt.target; const dropDownContent = toggleButton.parentElement.parentElement.querySelector('.fmc_ingredients_dropdown_content'); const concernContainer = toggleButton.parentElement.parentElement.parentElement; if (toggleButton.innerText == "-") { dropDownContent.style.ight = `0px`; toggleButton.innerText = "+"; } else { concernContainer.querySelectorAll('.fmc_ingredients_dropdown').forEach( (ingredientItem) => { const itemDropDownContent = ingredientItem.querySelector('.fmc_ingredients_dropdown_content'); const itemToggleButton = ingredientItem.querySelector('.fmc_ingredients_btn'); if (itemDropDownContent == dropDownContent) { const maxHeightString = `${itemDropDownContent.querySelector('p').getBoundingClientRect().height}px`; itemDropDownContent.style.maxHeight = maxHeightString; itemToggleButton.innerText = "-"; } else { itemDropDownContent.style.maxHeight = `0px`; itemToggleButton.innerText = "+"; } }); } concernContainer.querySelectorAll('.fmc_ingredients_dropdown').forEach((ingredientItem) => { const itemToggleButton = ingredientItem.querySelector('.fmc_ingredients_btn'); if (itemToggleButton.innerText == "-") { itemToggleButton.style.transform = 'scaleX(1.5)'; } else { itemToggleButton.style.transform = 'scaleX(1)'; } }) } dermObj.pageControls.brand_campaign.ingredients_OLD = (ingredient) => { const content = dermObj.body.querySelectorAll(".fmc_ingredients_dropdown_content"); const toggleBtns = dermObj.body.querySelectorAll(".fmc_ingredients_btn"); let toggle; for (let i = 0; i < content.length; i++) { if (content[i].classList.contains(ingredient)) toggle = i; } if (toggleBtns[toggle].innerText == "-") { content[toggle].style.maxHeight = `0px`; toggleBtns[toggle].innerText = "+"; } else { content.forEach( (el, index) => { if (index == toggle) { const maxHeightString = `${content[toggle].querySelector('p').getBoundingClientRect().height}px`; el.style.maxHeight = maxHeightString; toggleBtns[index].innerText = "-"; } else { el.style.maxHeight = `0px`; toggleBtns[index].innerText = "+"; } }); } } //called on load and on toggle dermObj.pageControls.brand_campaign.recomendationControls = (concern, onLoad) => { const concernDesc = document.querySelector('#fmc_brand_campaign_concerns_results_desc'); const topConcernOptions = document.querySelectorAll('.fmc_brand_campaign_top_concern_value'); const concernInfo = concernDesc.querySelectorAll('.fmc_brand_campaign_concern'); if (dml_fmc.pageControls.brand_campaign.concernOrder[0] == concern) { dermObj.body.querySelector('.brand_campaign_our_analysis_wrapper').style.display = 'inline'; dermObj.body.querySelector('.fmc_desc_beginning_user_choice').style.display = 'none'; //let concernText = document.querySelector('.fmc_desc_beginning_top_concern').innerText; //document.querySelector('.fmc_desc_beginning_top_concern').innerHTML = concernText.replace('__CONCERN__', `${concern}`); } else { document.querySelector('.fmc_desc_beginning_top_concern').style.display = 'none'; document.querySelector('.fmc_desc_beginning_user_choice').style.display = 'inline'; } concernInfo.forEach((desc) => { if (!desc.classList.contains(`fmc_concern_${concern}`)) { desc.style.display = 'none'; } else { desc.style.display = 'inline'; } }) for (let ii=0; ii < 2; ii++){ const stepLabel = ii == 0 ? 'one_product': 'kit'; const prodCard = dermObj.body.querySelector(`#fmc_results_brand_campaign #fmc_brand_campaign_card_${stepLabel}`); let product = dermObj.dioxideData.brand_campaign[concern][stepLabel]; if (Array.isArray(product) ) product = product[0]; dermObj.productData[product.pimcore_id] = product; prodCard.querySelector('.fmc_product_name').innerHTML = product.name; prodCard.querySelectorAll('.fmc_product_price').forEach((priceEl)=>{ priceEl.innerHTML = ` | ${product.priceCurrency} ${product.price}`; }) try{ prodCard.querySelector('.fmc_product_description').innerHTML = product.mediumDescription.split('.')[0]; }catch(err){ prodCard.querySelector('.fmc_product_description').innerHTML = ''; } prodCard.querySelector('.fmc_product_button').dataset.widgetProductBuy = product.pimcore_id; prodCard.querySelector('.fmc_product_image').dataset.widgetProductBackground = product.pimcore_id; prodCard.dataset.viewItemObserver = product.pimcore_id; prodCard.dataset.itemViewed = false; if (ii == 1){ dermObj.applyProductData(dermObj.productData); setTimeout(()=>{ dermObj.pageControls.brand_campaign.resizeCardImages(); dermObj.pageControls.brand_campaign.resizeCardTitles(); },50) } } const ingredientDropdowns = document.querySelectorAll(".fmc_ingredients_dropdown_list"); ingredientDropdowns.forEach(list => { if (list.classList.contains(`fmc_ingredients_dropdown_${concern}`)) { list.classList.add('fmc_active'); } else { list.classList.remove('fmc_active'); } }); if (Object.keys(dermObj.blogs.concernBlogs).indexOf(concern) > -1){ const blogCards = document.querySelectorAll('.fmc_blog_card'); blogCards.forEach((card, index) => { card.querySelector('.fmc_blog_img').style.backgroundImage = `url('${dermObj.blogs.concernBlogs[concern][index].image_url}')`; card.dataset.blogUrl = dermObj.blogs.concernBlogs[concern][index].url; card.querySelector('.fmc_blog_title').innerText = dermObj.blogs.concernBlogs[concern][index].title; }); dermObj.body.querySelector('#fmc_brand_campaign_blog_section').style.display = "flex"; }else{ dermObj.body.querySelector('#fmc_brand_campaign_blog_section').style.display = "none"; } const surveySelectConcerns = document.querySelectorAll('.brand_campaign_survey_concern'); //if (onLoad) { // surveySelectConcerns.forEach((option) => { // console.log(concern) // if (option.value == concern) { // option.selected = 'selected'; // } // }); // } } dermObj.pageControls.brand_campaign.surveyControls = async (evt) => { dermObj.body.querySelector('#fmc_results_brand_campaign #fmc_brand_campaign_survey_submit').classList.remove('fmc_disabled'); const questionTwoAns = dermObj.body.querySelectorAll('#fmc_survey_container .fmc_survey_response_btn'); const pressedButton = evt.target; questionTwoAns.forEach( (btn) => { if(btn == pressedButton) { btn.classList.add('fmc_survey_response_selected'); } else { btn.classList.remove('fmc_survey_response_selected'); } }); } dermObj.pageControls.brand_campaign.sendSurvey = async (evt) => { const questionOneVal = dermObj.body.querySelector('#fmc_results_brand_campaign #fmc_survey_container #fmc_survey_answers').value; const questionTwoVal = dermObj.body.querySelector('#fmc_results_brand_campaign .fmc_survey_response_btn.fmc_survey_response_selected').dataset.value; const xhr = new XMLHttpRequest(); let payload = { "hashid": dermObj.backendData.hashid, "feedback_data": { "surveyQuestionOne": { "question": `Our analysis highlighted ${dermObj.pageControls.brand_campaign.concernOrder[0]} as your main skin concern. What would you have said?`, // TODO questions should be replaced with keyword "response": questionOneVal }, "surveyQuestionTwo": { "question": "Did your results feel personalized and helpful?", // TODO questions should be replaced with keyword "response": questionTwoVal } } } xhr.onreadystatechange = () => { if (xhr.readyState === 4) { dermObj.body.querySelector('#fmc_results_brand_campaign #fmc_brand_campaign_survey_submit').classList.add('fmc_done'); dermObj.body.querySelector('#fmc_results_brand_campaign #fmc_survey_container #fmc_survey_answers').style.pointerEvents = 'none'; dermObj.body.querySelectorAll('#fmc_results_brand_campaign .fmc_survey_response_btn').forEach((btn)=> {btn.style.pointerEvents = 'none';}) dermObj.debug(xhr.response); } } xhr.open('POST', 'https://fmc-backend-staging.herokuapp.com/fmc/add_fmc_feedback',true); xhr.send(JSON.stringify(payload)); //document.querySelector('#fmc_brand_campaign_survey_notice').style.display = "none"; //submitBtns[0].style.display = "none"; //submitBtns[1].style.display = "block"; dermObj.pageControls.brand_campaign.hideSurveyOnSubmit(evt); } dermObj.pageControls.brand_campaign.hideSurveyOnSubmit = () => { //document.querySelector('#fmc_brand_campaign_survey_section').classList.add("fmc_brand_campaign_survey_section_closed"); document.querySelector('#fmc_brand_campaign_survey_section').style.display = 'none'; } dermObj.pageControls.brand_campaign.openConcernsDropdown = () => { function closeDropDown(){ const dropdownMenu = document.querySelector('#fmc_brand_campaign_top_concern'); const dropdownBtn = document.querySelector('#fmc_concerns_expand_arrow'); dropdownMenu.style.maxHeight = "0"; //dropdownMenu.style.transition = "max-height 0.15s ease-out;"; dropdownBtn.style.transform = "rotate(-90deg)"; dropdownMenu.style.overflow = "hidden"; window.removeEventListener('click', closeDropDown ) setTimeout(()=>{ dropdownMenu.style.border = "none"; },250) } const dropdownMenu = document.querySelector('#fmc_brand_campaign_top_concern'); const dropdownBtn = document.querySelector('#fmc_concerns_expand_arrow'); if (dropdownBtn.style.transform == "rotate(-90deg)") { dropdownMenu.style.maxHeight = `${(dermObj.pageControls.brand_campaign.concernOrder.length + 1) * 60 + document.getElementById("brand_campaign_results_dropdown_text").offsetHeight }px`; dropdownMenu.style.transition = "max-height 0.25s ease-in-out"; dropdownBtn.style.transform = "rotate(90deg)" dropdownMenu.style.border = "1px solid #5e93db"; dropdownMenu.style.borderTop = "none"; dropdownMenu.style.overflow = "scroll"; setTimeout(()=> { window.addEventListener('click', closeDropDown ) },100) } } dermObj.pageControls.brand_campaign.sortConcernsForBrandCampaign = async () => { return new Promise((resolve, reject)=>{ dermObj.dioxideData.unsortedBrandConcerns = []; const brand_concerns = dermObj.dioxideData.brand_campaign; Object.keys(brand_concerns).forEach((concernKey)=> { brand_concerns[concernKey].name = concernKey; brand_concerns[concernKey].concern_key = concernKey; switch(concernKey){ case "acne": brand_concerns[concernKey].score = dermObj.backendData.revieve_acne_value; dermObj.dioxideData.unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dark_circles": brand_concerns[concernKey].score = dermObj.backendData.revieve_eyes_value; dermObj.dioxideData.unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dark_spots": brand_concerns[concernKey].score = dermObj.backendData.revieve_dark_spots_value; dermObj.dioxideData.unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dehydration": brand_concerns[concernKey].score = 0.25; dermObj.dioxideData.unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dull_skin": brand_concerns[concernKey].score = dermObj.backendData.revieve_dull_skin_value; dermObj.dioxideData.unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "redness": brand_concerns[concernKey].score = dermObj.backendData.revieve_redness_value; dermObj.dioxideData.unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "wrinkles": brand_concerns[concernKey].score = dermObj.backendData.revieve_wrinkles_value; dermObj.dioxideData.unsortedBrandConcerns.push(brand_concerns[concernKey]) break; } }) dermObj.dioxideData.sortedBrandConcerns = dermObj.dioxideData.unsortedBrandConcerns.sort((a,b) => {return b.score - a.score}); resolve(); }) } dermObj.pageControls.brand_campaign.openBlog = (evt) => { let blogCard = evt.target; let stopCounter = 0; while (!blogCard.classList.contains('fmc_blog_card') && stopCounter < 5){ blogCard = blogCard.parentElement; stopCounter++; } const blogUrl = blogCard.dataset.blogUrl; window.open(blogUrl, '_blank'); } dermObj.pageControls.brand_campaign.openBookNow = () => { window.open(dermObj.pageControls.brand_campaign.bookNowLink, '_blank'); } dermObj.pageControls.brand_campaign.adjustDropDownWidth = ()=>{ const headerTextEl = dermObj.body.querySelector('#fmc_results_brand_campaign_subtitle'); const dropDownEl = dermObj.body.querySelector('#fmc_brand_campaign_top_concern_dropdown'); if (headerTextEl.offsetWidth > 0){ dropDownEl.style.maxWidth = `${headerTextEl.offsetWidth}px`; }else{ let counter = 0; const widthInterval = setInterval(()=>{ if (headerTextEl.offsetWidth > 0){ clearInterval(widthInterval); dropDownEl.style.maxWidth = `${headerTextEl.offsetWidth}px`; } if (counter > 50){ clearInterval(widthInterval); } counter++; },100) } } dermObj.pageControls.brand_campaign.resizeCardImages = () =>{ dermObj.body.querySelectorAll('#fmc_results_brand_campaign .fmc_brand_campaign_product_card_img').forEach((imgDiv) => { if (dermObj.body.offsetWidth > 768){ imgDiv.style.maxHeight = `${dermObj.body.offsetWidth * 0.2}px`; }else{ imgDiv.style.maxHeight = `${dermObj.body.offsetWidth * 0.5}px`; } }) } dermObj.pageControls.brand_campaign.resizeCardTitles = () =>{ let maxTitleWidth = 0; let cardWidth = 0; dermObj.body.querySelectorAll('#fmc_results_brand_campaign .fmc_brand_campaign_product_card_title').forEach((cardTitle) => { cardWidth = cardTitle.parentElement.offsetWidth; maxTitleWidth = Math.max(maxTitleWidth / dermObj.pageControls.brand_campaign.cardTitleScaleFact, cardTitle.offsetWidth) }) dermObj.pageControls.brand_campaign.cardTitleScaleFact = cardWidth/maxTitleWidth; dermObj.body.querySelectorAll('#fmc_results_brand_campaign .fmc_brand_campaign_product_card_title').forEach((cardTitle) => { cardTitle.style.transform = `scale(${dermObj.pageControls.brand_campaign.cardTitleScaleFact})`; }) } dermObj.pageControls.quiz_no_image_results = {}; dermObj.pageControls.quiz_no_image_results.build = async ()=>{ dermObj.dioxideData = dermObj.backendData.dioxide_data; /* if (dermObj.dioxide == 'http://127.0.0.1:8000' || dermObj.dioxide == 'https://dioxide-staging.herokuapp.com'){ try{ const quizRecommendations = await dermObj.getDioxideQuizNoImageRecommendation(dml_dmlqz.surveyResults); dermObj.debug('quizRecommendations: ',quizRecommendations) dermObj.dioxideData.prep_treat_glow = {...quizRecommendations.prep_treat_glow}; }catch(err){ console.error(err); } } */ dermObj.body.querySelector('#fmc_results_quiz_no_image').style.opacity = 1; dermObj.pageControls.quiz_no_image_results.updateProducts(); const prepProdName = dermObj.dioxideData.prep_treat_glow.prep.name; const treatProdName = dermObj.dioxideData.prep_treat_glow.treat.name; const glowProdName = dermObj.dioxideData.prep_treat_glow.glow.name; dermObj.productData[dermObj.dioxideData.prep_treat_glow.prep.pimcore_id] = dermObj.dioxideData.prep_treat_glow.prep; dermObj.productData[dermObj.dioxideData.prep_treat_glow.treat.pimcore_id] = dermObj.dioxideData.prep_treat_glow.treat; dermObj.productData[dermObj.dioxideData.prep_treat_glow.glow.pimcore_id] = dermObj.dioxideData.prep_treat_glow.glow; if (dermObj.config.useShopify === true){ dermObj.body.querySelector('#fmc_results_quiz_no_image button.fmc_add_all_to_cart').style.display = 'flex'; } } dermObj.pageControls.quiz_no_image_results.updateProducts = async ()=>{ let selectedProdIndices = [] for (let ii=0; ii < 3; ii++){ let stepLabel; switch (ii){ case 0: stepLabel='prep'; break; case 1: stepLabel='treat'; break; case 2: stepLabel='glow'; break; } const prodCard = document.querySelector(`#fmc_results_quiz_no_image #fmc_prep_treat_glow_card_${stepLabel}`); const product = dermObj.dioxideData.prep_treat_glow[stepLabel]; dermObj.productData[product.pimcore_id] = product; prodCard.querySelectorAll('.fmc_product_name').forEach((prodNameEl) => {prodNameEl.innerHTML = product.name}); prodCard.querySelectorAll('.fmc_product_price').forEach((prodPriceEl) => {prodPriceEl.innerHTML = `${product.priceCurrency} ${product.price}`}); prodCard.querySelector('.fmc_product_description').innerHTML = product.mediumDescription; prodCard.querySelector('.fmc_product_button').dataset.widgetProductBuy = product.pimcore_id; prodCard.querySelector('.fmc_product_image').dataset.widgetProductBackground = product.pimcore_id; prodCard.dataset.viewItemObserver = product.pimcore_id; prodCard.dataset.itemViewed = false; if (ii == 2){ dermObj.applyProductData(dermObj.productData); } } } dermObj.pageControls.quiz_no_image_results.allowAddAllToCartFlag = true; dermObj.pageControls.quiz_no_image_results.addAllToCart = async ()=>{ if (dermObj.pageControls.quiz_no_image_results.allowAddAllToCartFlag === true){ dermObj.pageControls.quiz_no_image_results.allowAddAllToCartFlag = false; setTimeout(()=>{ dermObj.pageControls.quiz_no_image_results.allowAddAllToCartFlag = true; },500) dermObj.sendGA360("main flow",'add all to cart button clicked'); dermObj.sendGAFlowEvent('add all to cart button clicked'); const variantIdArray = []; dermObj.body.querySelectorAll('#fmc_results_quiz_no_image button.fmc_product_button').forEach(async (buyButton, index)=>{ const variantId = dermObj.productData[buyButton.dataset.widgetProductBuy].variants.filter((variantObj) => variantObj.default === true)[0].shopify_variant_id; variantIdArray.push(variantId) }) try{ await dermObj.addMultipleToBagShopify( variantIdArray); dermObj.body.querySelector('#fmc_results_quiz_no_image button.fmc_add_all_to_cart').classList.add('fmc_added_to_cart'); }catch(err){ console.error(err); dermObj.debug('hiding add all to cart buttons'); dermObj.body.querySelector('#fmc_results_quiz_no_image button.fmc_add_all_to_cart').style.display = 'none'; } } } dermObj.pageControls.estimatedResults = {}; dermObj.pageControls.estimatedResults.build = async ()=>{ const dioxRes = await dermObj.getEstimatedDioxideRecommendations(); dermObj.dioxideData = dioxRes; dermObj.body.querySelector('#fmc_estimated_results').style.opacity = 1; dermObj.pageControls.estimatedResults.updateProducts(); const prepProdName = dermObj.dioxideData.prep_treat_glow.prep.name; const treatProdName = dermObj.dioxideData.prep_treat_glow.treat.name; const glowProdName = dermObj.dioxideData.prep_treat_glow.glow.name; dermObj.productData[dermObj.dioxideData.prep_treat_glow.prep.pimcore_id] = dermObj.dioxideData.prep_treat_glow.prep; dermObj.productData[dermObj.dioxideData.prep_treat_glow.treat.pimcore_id] = dermObj.dioxideData.prep_treat_glow.treat; dermObj.productData[dermObj.dioxideData.prep_treat_glow.glow.pimcore_id] = dermObj.dioxideData.prep_treat_glow.glow; if (dermObj.config.useShopify === true){ dermObj.body.querySelector('#fmc_estimated_results button.fmc_add_all_to_cart').style.display = 'flex'; } if (window.location.search == ''){ window.history.pushState('fmc_estimated_results', '', `${window.location.href}?estr=1`); }else{ if (window.location.search.indexOf('estr=') == -1 && window.location.search.indexOf('rspg=estr') == -1){ window.history.pushState('fmc_results_quiz_no_image', '', `${window.location.href}&estr=1`); } } } dermObj.pageControls.estimatedResults.updateProducts = async ()=>{ let selectedProdIndices = [] for (let ii=0; ii < 3; ii++){ let stepLabel; switch (ii){ case 0: stepLabel='prep'; break; case 1: stepLabel='treat'; break; case 2: stepLabel='glow'; break; } const prodCard = document.querySelector(`#fmc_estimated_results #fmc_prep_treat_glow_card_${stepLabel}`); const product = dermObj.dioxideData.prep_treat_glow[stepLabel]; dermObj.productData[product.pimcore_id] = product; prodCard.querySelectorAll('.fmc_product_name').forEach((prodNameEl) => {prodNameEl.innerHTML = product.name}); prodCard.querySelectorAll('.fmc_product_price').forEach((prodPriceEl) => {prodPriceEl.innerHTML = `${product.priceCurrency} ${product.price}`}); prodCard.querySelector('.fmc_product_description').innerHTML = product.mediumDescription; prodCard.querySelector('.fmc_product_button').dataset.widgetProductBuy = product.pimcore_id; prodCard.querySelector('.fmc_product_image').dataset.widgetProductBackground = product.pimcore_id; prodCard.dataset.viewItemObserver = product.pimcore_id; prodCard.dataset.itemViewed = false; if (ii == 2){ dermObj.applyProductData(dermObj.productData); } } } dermObj.pageControls.estimatedResults.allowAddAllToCartFlag = true; dermObj.pageControls.estimatedResults.addAllToCart = async ()=>{ if (dermObj.pageControls.estimatedResults.allowAddAllToCartFlag === true){ dermObj.pageControls.estimatedResults.allowAddAllToCartFlag = false; setTimeout(()=>{ dermObj.pageControls.estimatedResults.allowAddAllToCartFlag = true; },500) dermObj.sendGA360("main flow",'add all to cart button clicked'); dermObj.sendGAFlowEvent('add all to cart button clicked'); const variantIdArray = []; dermObj.body.querySelectorAll('#fmc_estimated_results button.fmc_product_button').forEach(async (buyButton, index)=>{ const variantId = dermObj.productData[buyButton.dataset.widgetProductBuy].variants.filter((variantObj) => variantObj.default === true)[0].shopify_variant_id; variantIdArray.push(variantId) }) try{ await dermObj.addMultipleToBagShopify( variantIdArray); dermObj.body.querySelector('#fmc_estimated_results button.fmc_add_all_to_cart').classList.add('fmc_added_to_cart'); }catch(err){ console.error(err); dermObj.debug('hiding add all to cart buttons'); dermObj.body.querySelector('#fmc_estimated_results button.fmc_add_all_to_cart').style.display = 'none'; } } } dermObj.pageControls.perc_match_coll = {}; dermObj.pageControls.perc_match_coll.percMatchFailed = false; dermObj.pageControls.perc_match_coll.estProdsDefault = { "cleanser" : 9125, "exfoliant" : 9137, "moisturizer" : 9142, "masque" : 13136, "toner" : 9131, "spf" : 9178, "facial_oil_or_serum" : 9297, "eye_treatment": 11322 } dermObj.pageControls.perc_match_coll.estProds= {} dermObj.pageControls.perc_match_coll.build = async () => { window.fmc_collections_complete = true; try{ if (dermObj.miniPageSettings.estProds != undefined && dermObj.miniPageSettings.estProds != null){ dermObj.pageControls.perc_match_coll.estProds = JSON.parse(dermObj.miniPageSettings.estProds); } }catch(err){} let prodTypeCopyElArr = dermObj.body.querySelectorAll('#fmc_perc_match_coll_prod_type'); let prodTypeCopy = ''; if (dermObj.miniPageSettings.collectionType != undefined){ if (dermObj.textData.exact_phrases[dermObj.miniPageSettings.collectionType] != undefined && dermObj.textData.exact_phrases[dermObj.miniPageSettings.collectionType] != null && dermObj.textData.exact_phrases[dermObj.miniPageSettings.collectionType] != ''){ prodTypeCopy = dermObj.textData.exact_phrases[dermObj.miniPageSettings.collectionType] }else{ prodTypeCopy = dermObj.textData.exact_phrases.product; } }else{ prodTypeCopy = dermObj.textData.exact_phrases.product; } prodTypeCopyElArr.forEach((copyEl) => { copyEl.innerHTML = prodTypeCopy; }) const pimcoreId = await dermObj.pageControls.perc_match_coll.getPimcoreIdToDisplay(); let miniPage = dermObj.body.querySelector('#fmc_results_page_perc_match_coll') miniPage.querySelector('.fmc_product_image').dataset.widgetProductBackground = pimcoreId; miniPage.querySelector('.fmc_product_name').dataset.widgetProductName = pimcoreId; miniPage.querySelector('.fmc_product_tagline').dataset.widgetProductTagline = pimcoreId; miniPage.querySelector('.fmc_product_description').dataset.widgetProductDescription = pimcoreId; miniPage.querySelector('button.fmc_product_button').dataset.widgetProductBuy = pimcoreId; dermObj.body.querySelector('#fmc_coll_page_info_hint').innerHTML = dermObj.textData.results_collection_mini_page.collection_mini_page_info_copy .replace(/__PRODUCTNAME__/g,``) .replace(/__PRODUCTCATEGORY__/g, prodTypeCopy); let checkFmcLinkInterval = setInterval(()=>{ if (dermObj.fmcResultsUrl != ''){ clearInterval(checkFmcLinkInterval); dermObj.body.querySelectorAll('.fmc_coll_page_fmc_link').forEach((fmcLink)=>{ fmcLink.setAttribute('href',dermObj.fmcResultsUrl); }) } },100) dermObj.productData = {} dermObj.dioxideAllProducts.forEach((dioxProd)=>{ dermObj.productData[dioxProd.pimcoreId] = dioxProd; }) try{ if (dermObj.productData[pimcoreId].mediumDescription == undefined || dermObj.productData[pimcoreId].mediumDescription == null || dermObj.productData[pimcoreId].mediumDescription == ''){ miniPage.querySelector('.fmc_product_description').style.display="none"; }else{ miniPage.querySelector('.fmc_product_description').style.display="block"; } }catch(err){console.error(err)} dermObj.applyProductData(dermObj.productData); try{ dermObj.queueUrlParameters({ptg_id:dermObj.dioxideData.prep_treat_glow.ptg_id}); }catch(err){ console.error(err) } try{ if (dermObj.pageControls.perc_match_coll.percMatchFailed == true){ dermObj.queueUrlParameters({fmc_mnpg_sc:0}); window.fmc_collections_df = true; }else{ dermObj.queueUrlParameters({fmc_mnpg_sc:1}); } }catch(err){} try{ // observe add to bag button const buyButton = miniPage.querySelector('button.fmc_product_button'); const classObserver = new MutationObserver((mutationsList, observer) => { for(var mutation of mutationsList) { if (mutation.type === 'attributes' && mutation.attributeName === 'class') { if (buyButton.classList.contains('dml_added_to_bag_button')) { try{ if (window.dsrp != undefined && window.dsrp.miniFmc != undefined && window.dsrp.miniFmc.doubleGridContainer != undefined){ window.dsrp.miniFmc.doubleGridContainer.remove(); } document.querySelectorAll('#dml_widget_wrapper').forEach((wrapperEl)=> { wrapperEl.style.transition = 'opacity 1s'; wrapperEl.style.opacity = 1; setTimeout(()=>{ wrapperEl.style.opacity = 0; },1000) setTimeout(()=>{ wrapperEl.remove(); },2500) }); }catch(err){} observer.disconnect(); } } } }) classObserver.observe(buyButton, { attributes: true, attributeOldValue: true }); //dml_added_to_bag_button ///dml_is_pending }catch(err){ console.error(err) } } dermObj.pageControls.perc_match_coll.checkForPercMatchData = () => { return new Promise((resolve,reject) => { let checkInterval = setInterval(()=>{ if (dermObj.percMatchData == undefined || dermObj.percMatchData == null) return; if (Object.keys(dermObj.percMatchData).length < 1) return; clearInterval(checkInterval); resolve(); },50); }); } dermObj.pageControls.perc_match_coll.getPimcoreIdToDisplay = async ()=> { return new Promise(async (resolve,reject)=>{ if (dermObj.pageControls.perc_match_coll.percMatchFailed == true){ try{ let pimcoreId; if (dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType] != undefined && dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType] != null && dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType] != 0){ pimcoreId = dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType]; }else{ pimcoreId = dermObj.pageControls.perc_match_coll.estProdsDefault[dermObj.miniPageSettings.collectionType]; } resolve(pimcoreId); }catch(err){ let pimcoreId = dermObj.pageControls.perc_match_coll.estProdsDefault[dermObj.miniPageSettings.collectionType]; resolve(pimcoreId); } }else{ let shopIdsOnPage; try{ shopIdsOnPage = JSON.parse(dermObj.miniPageSettings.productsOnPage); }catch(err){ console.error(err) } try{ await dermObj.pageControls.perc_match_coll.checkForPercMatchData(); }catch(err){console.error(err)} let matchingProducts = {}; shopIdsOnPage.forEach((prodId)=>{ if (dermObj.percMatchData.hasOwnProperty(prodId)){ matchingProducts[prodId] = dermObj.percMatchData[prodId]; } }) let matchingProductsSorted = {}; if (Object.keys(matchingProducts).length > 0){ matchingProductsSorted = Object.fromEntries( Object.entries(matchingProducts).sort(([, a], [, b]) => b - a) ); } if (Object.keys(matchingProductsSorted).length > 0){ let bestFitId = Object.keys(matchingProductsSorted)[0]; let pimcoreId = dermObj.dioxideAllProducts.filter((obj) => obj.shopify_id == bestFitId)[0].pimcoreId resolve(pimcoreId); }else{ try{ let pimcoreId; if (dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType] != undefined && dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType] != null && dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType] != 0){ pimcoreId = dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType]; }else{ pimcoreId = dermObj.pageControls.perc_match_coll.estProdsDefault[dermObj.miniPageSettings.collectionType]; } resolve(pimcoreId); }catch(err){ let pimcoreId = dermObj.pageControls.perc_match_coll.estProdsDefault[dermObj.miniPageSettings.collectionType]; resolve(pimcoreId); } } } }) } dermObj.gotoPage = async (pageIdKey)=>{ if (pageIdKey == 'waiting'){ if (dermObj.backendData != null && dermObj.backendData != undefined ){ if (dermObj.config.quizNoImage != true){ try{ const dioxPayload = await dermObj.prepareDioxidePayload(dermObj.backendData, dermObj.lang_code) //dermObj.debug("DIOX PAYLOAD - ",dioxPayload); const dioxRefineRecomResponse = await dermObj.getDioxideRecommendations(dioxPayload); //dermObj.debug("DIOX RECOM RESPONSE - ",dioxRefineRecomResponse); dermObj.dioxideData = {...dioxRefineRecomResponse}; }catch(err){ console.error('error in refining backend dioxide data - ',err); if (dermObj.isPercMatchMiniPage != true){ dermObj.config.pageDict.results = 'fmc_estimated_results'; }else{ dermObj.pageControls.perc_match_coll.percMatchFailed = true; } } } dermObj.gotoPage('results'); return; }else{ let resultsFinishTimeout = 40000; let intervalStep = 500; let intervalTotalTime = 0; let resultsFinishedInterval = setInterval(async ()=>{ if ((dermObj.backendData != null && dermObj.backendData != undefined)){ clearInterval(resultsFinishedInterval); if (dermObj.config.quizNoImage != true){ try{ const dioxPayload = await dermObj.prepareDioxidePayload(dermObj.backendData, dermObj.lang_code) dermObj.debug("DIOX PAYLOAD - ",dioxPayload); const dioxRefineRecomResponse = await dermObj.getDioxideRecommendations(dioxPayload); dermObj.debug("DIOX RECOM RESPONSE - ",dioxRefineRecomResponse); dermObj.dioxideData = {...dioxRefineRecomResponse}; }catch(err){ console.error('error in refining backend dioxide data - ',err); if (dermObj.isPercMatchMiniPage != true){ dermObj.config.pageDict.results = 'fmc_estimated_results'; }else{ dermObj.pageControls.perc_match_coll.percMatchFailed = true; } } } dermObj.gotoPage('results'); return; } if (dermObj.analyzeRequestStatus == 'failed' ){ clearInterval(resultsFinishedInterval); } if (intervalTotalTime >= resultsFinishTimeout ){ clearInterval(resultsFinishedInterval); } intervalTotalTime += intervalStep; },intervalStep) } } // badges logic if (dermObj.config.badges != {}){ const badgeOverlay = document.getElementById('fmc_badge_page_overlay'); try{ badgeOverlay.classList.remove(...badgeOverlay.classList); let pgId = dermObj.config.pageDict[pageIdKey]; if (dermObj.config.badges[pgId] != undefined && typeof dermObj.config.badges[pgId] == 'string'){ badgeOverlay.className = dermObj.config.badges[pgId] } }catch(err){ console.error(err); badgeOverlay.classList.remove(...badgeOverlay.classList); } } if (pageIdKey == 'results' && window.location.search.indexOf('fmhid=') == -1 && !(dermObj.isPercMatchMiniPage == true && dermObj.pageControls.perc_match_coll.percMatchFailed == true)){ dermObj.showEmailRequestPopupFlag = await dermObj.checkEmailRequirement(); //dermObj.showEmailRequestPopupFlag = true; if (dermObj.showEmailRequestPopupFlag && dermObj.emailRequestedForResults !== true){ dermObj.sendGA360("main flow","show email capture form before results") dermObj.sendGA4("show email capture form before results") dermObj.emailRequestedForResults = true; //document.getElementById("fmc_email_popup").style.display = 'flex'; dermObj.showEmailPopup(); return; } try{ if (!dermObj.config.userImgOnly){ const fmcSnapShot = await dermObj.getRevSnapShot(dermObj.backendData); dermObj.addUrlParameters(fmcSnapShot); await dermObj.checkCookieConsent(); if (dermObj.config.allowCookies){ dermObj.updateLocalStorage(fmcSnapShot); } } }catch(err){ console.error(err) } } if (dermObj.config.quizNoImage == true && dermObj.quizNoImageInitFlag != true){ dermObj.quizNoImageInitFlag = true; dermObj.config.pageDict.onboarding_orig = dermObj.config.pageDict.onboarding; dermObj.config.pageDict.onboarding = 'fmc_quiz_no_image_page'; dermObj.config.pageDict.results_orig = dermObj.config.pageDict.results; dermObj.config.pageDict.results = 'fmc_results_quiz_no_image'; dermObj.config.requestEmailForResults_orig = dermObj.config.requestEmailForResults; dermObj.config.requestEmailForResults = false; } let pageId = dermObj.config.pageDict[pageIdKey]; if (pageIdKey == 'onboarding' && dermObj.quizFromConsent == true){ pageId = 'fmc_quiz_no_image_page'; } if (pageIdKey == 'quiz_after_image' || pageId == 'fmc_qai_page_default'){ dermObj.pageControls.qai.init(); } let curPage = document.getElementById(pageId) || document.getElementById('fmc_landing_page_default'); document.querySelectorAll(".fmc_page").forEach((pageEl)=>{ pageEl.classList.remove("fmc_visible"); }) if (curPage.id != pageId) { console.warn("page id not found - ", pageId); } if (pageId == 'fmc_landing_page_brand_campaign'){ dermObj.pageControls.landing_brand_campaign.runConcernCycle(); } curPage.classList.add("fmc_visible"); dermObj.currentPage = pageId; if (pageIdKey == "landing" && pageId == 'fmc_loading_page_default'){ dermObj.showConsent(); } if (pageIdKey == "onboarding"){ if (pageId == 'fmc_onbording_default'){ try{ dermObj.pageControls.onboarding_default.skipToResultsCounter = 0; }catch(err){} } if (pageId == 'fmc_quiz_no_image_page'){ dermObj.pageControls.onboarding_quiz_no_image.loadQuiz(); } if (pageId == 'fmc_loading_page_default'){ dermObj.showConsent(); } if (window.dataLayer != undefined){ try{ dataLayer.push({'event':'visited_face_mapping'}) }catch(err){} } } if (pageIdKey == "capture") { if (!dermObj.capture.initDone){ await dermObj.capture.init({ captureContainerId : 'fmc_video_container', videoConstrains : { video: { facingMode: { ideal: 'user' }, width: { min: 720, ideal: 1080, max: 1920 }, height: {min: 720, ideal: 1080, max: 1920 } }, audio: false } }); } dermObj.pageControls.capture.start(); } if (pageId == "fmc_waiting_page_default"){ dermObj.pageControls.waiting.buildLoadingText() } if (pageIdKey == "results"){ dermObj.body.style.height = "auto"; dermObj.widget_wrapper.style.height = "auto"; }else{ if (dermObj.widgetMaxHeight != undefined){ dermObj.body.style.height = dermObj.widgetMaxHeight; dermObj.widget_wrapper.style.height = dermObj.widgetMaxHeight; }else{ dermObj.body.style.height = `${window.innerHeight}px`; dermObj.widget_wrapper.style.height = `${window.innerHeight}px`; } } if (pageIdKey == "results"){ switch (dermObj.config.pageDict.results){ case 'fmc_results_quiz_no_image': dermObj.pageControls.quiz_no_image_results.build(); break; case 'fmc_results_prep_treat_glow': dermObj.pageControls.prep_treat_glow.build(); break; case 'fmc_estimated_results': dermObj.pageControls.estimatedResults.build(); break; case 'fmc_results_brand_campaign': dermObj.pageControls.brand_campaign.build(); break; case 'fmc_results_page_perc_match_coll': dermObj.pageControls.perc_match_coll.build(); break; default: dermObj.pageControls.results_default.build(); } if (window.dataLayer != undefined){ try{ dataLayer.push({'event':'completed_face_mapping'}); }catch(err){} } if (dermObj.config.ga4dst !== undefined && dermObj.config.ga4dst !== null ){ try{ gtag('event','fmc_results_complete_ga4',{send_to: dermObj.config.ga4dst}) }catch(err){ console.error(err) } } if (dermObj.config.gtmDLArray !== undefined && dermObj.config.gtmDLArray !== null ){ try{ if (window[dermObj.config.gtmDLArray] !== undefined && window[dermObj.config.gtmDLArray] !== null){ window[dermObj.config.gtmDLArray].push({event: 'fmc_results_complete_gtm'}); } }catch(err){ console.error(err) } }; if (dermObj.config.fmcCheckoutCookie === true){ (async()=>{ await dermObj.checkCookieConsent(); if (dermObj.config.allowCookies === true){ try{ sessionStorage.setItem('fmccmpl',1); }catch(err){} } })(); } } dermObj.sendGA360("main flow",`show page - ${pageId}`); dermObj.sendGAFlowEvent(`show page - ${pageId}`); }; dermObj.requestPermissionBeforeLoadingFormerResult = async ()=>{ dermObj.permissionBeforeFormerResults = true; dermObj.gotoPage('loading'); dermObj.body.style.opacity = 1; let mpData; try{ mpData = JSON.parse(localStorage.getItem('derm_mp')) || {}; }catch(err){ mpData = {}; } let smac = mpData.smac; if (smac != '' && smac != undefined && mpData.fh != undefined){ let fhid = location.search.split('fmhid=')[1].split('&')[0]; if (fhid == mpData.fh){ dermObj.twofa.code = dermObj.clearCd(smac, fhid); } } if (dermObj.config.quizNoImage || dermObj.twofa.code != ''){ dermObj.loadingFormerResultAfterPermission(); }else{ dermObj.showConsent(); } } dermObj.loadingFormerResultAfterPermission = async ()=>{ dermObj.permissionBeforeFormerResults = false; try{ const analyzeData = await dermObj.getFormerfmcResult(dermObj.formerHash); dermObj.debug("fmc data: ",analyzeData); dermObj.backendData = analyzeData; //console.log('BACKEND DATA - ',dermObj.backendData) //dermObj.dioxideData = {...dermObj.backendData} try{ const dioxPayload = await dermObj.prepareDioxidePayload(dermObj.backendData, dermObj.lang_code) //dermObj.debug("DIOX PAYLOAD - ",dioxPayload); const dioxRefineRecomResponse = await dermObj.getDioxideRecommendations(dioxPayload); //dermObj.debug("DIOX RECOM RESPONSE - ",dioxRefineRecomResponse); dermObj.dioxideData = {...dioxRefineRecomResponse}; }catch(err){ } if (window.location.search.indexOf("dbe6412ad=1") > -1){ dermObj.masks.obscurifyEyesFlag = false; }else{ dermObj.masks.obscurifyEyesFlag = true; } await dermObj.loadExtraLibraries(); try{ await dermObj.capture.initFaceLandmarkModel(false); }catch(err){ console.error(err) } dermObj.gotoPage('results'); }catch(err){ if (err.indexOf('Please supply the correct access code') > -1 ){ dermObj.twofa.inputEl.value = ''; dermObj.gotoPage('loading'); dermObj.loadingFormerResultAfterPermission(); window.alert("Access Code wrong"); }else{ dermObj.gotoPage('landing'); } } } dermObj.openChatOrContactPage = async () => { const chatEnabled = await dermObj.chat.chatEnabledCheck(); if (chatEnabled){ dermObj.sendGA360("main flow", `chat available - trying to open a chat with message`); dermObj.sendGAFlowEvent( `chat available - trying to open a chat with message`); dermObj.chat.openChat(); }else{ dermObj.sendGA360("main flow",`no chat available - go to contact page`); dermObj.sendGAFlowEvent(`no chat available - go to contact page`); dermObj.gotoContactPage() } } dermObj.gotoContactPage = async () => { window.open(dermObj.siteLinks.contact_us_url, '_blank'); } dermObj.gotoQuizFromConsent = async () => { document.getElementById('fmc_legal_overlay').style.display = "none"; dermObj.sendGA360("main flow",`quiz from consent`); dermObj.sendGAFlowEvent(`quiz from consent`); dermObj.quizFromConsent = true; dermObj.config.quizNoImage = true; dermObj.gotoPage('onboarding'); } dermObj.gotoQuizFromLanding = async () => { dermObj.sendGA360("main flow",`quiz from landing`); dermObj.sendGAFlowEvent(`quiz from landing`); dermObj.quizFromLanding = true; dermObj.config.quizNoImage = true; dermObj.queueUrlParameters({qfl:1}); dermObj.gotoPage('onboarding'); } dermObj.exitQuizNoImage = async () => { dermObj.sendGA360("main flow",`exit quiz no image`); dermObj.sendGAFlowEvent(`exit quiz no image`); dermObj.config.quizNoImage = false; dermObj.quizFromConsent = false; dermObj.quizFromLanding = false; dermObj.quizNoImageInitFlag = false; dermObj.config.pageDict.onboarding = dermObj.config.pageDict.onboarding_orig; dermObj.config.pageDict.results = dermObj.config.pageDict.results_orig; dermObj.config.requestEmailForResults = dermObj.config.requestEmailForResults_orig; dermObj.gotoPage('landing'); } dermObj.masks = {} dermObj.masks.images = {} dermObj.masks.getObscEyeRect = async ()=>{ if (dermObj.config.quizNoImage === true) { dermObj.masks.fillWithPlaceholderImage(); return; } if (dermObj.backendData.azure_response == undefined && dermObj.capture.faceBox == undefined){ dermObj.masks.fillWithPlaceholderImage(); return; } if (dermObj.backendData.azure_response != undefined){ const azureRes = dermObj.backendData.azure_response; dermObj.masks.eyeRect = {}; dermObj.masks.eyeRect.left = azureRes.face_rectangle.left; dermObj.masks.eyeRect.width = azureRes.face_rectangle.width; const eyeTop = Math.min(azureRes.face_landmarks.eyeLeftTop.y, azureRes.face_landmarks.eyeRightTop.y ) const eyeBottom = Math.min(azureRes.face_landmarks.eyeLeftBottom.y, azureRes.face_landmarks.eyeRightBottom.y ) const eyeHeight = eyeBottom - eyeTop; dermObj.masks.eyeRect.top = eyeTop - 2* eyeHeight; dermObj.masks.eyeRect.height = 5* eyeHeight; return; }else{ dermObj.masks.eyeRect = { left: dermObj.capture.faceBox._x, width: dermObj.capture.faceBox._width, top: dermObj.capture.faceBox._y + 0.2*dermObj.capture.faceBox._height, height: 0.2*dermObj.capture.faceBox._height } return; } } dermObj.masks.fillWithPlaceholderImage = async () => { dermObj.masks.images = { original : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, original_cropped : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, darkCircles : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, darkCircles_cropped : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, redness : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, redness_cropped : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, dehydration : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, dehydration_cropped : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, oiliness : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, oiliness_cropped : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, acne : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, acne_cropped : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, wrinkles : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, wrinkles_cropped : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg` } } dermObj.masks.fillWithOriginalImage = async () => { dermObj.masks.images = { original : dermObj.backendData.original_image, original_cropped : dermObj.backendData.original_image, darkCircles : dermObj.backendData.original_image, darkCircles_cropped : dermObj.backendData.original_image, redness : dermObj.backendData.original_image, redness_cropped : dermObj.backendData.original_image, dehydration : dermObj.backendData.original_image, dehydration_cropped : dermObj.backendData.original_image, oiliness : dermObj.backendData.original_image, oiliness_cropped : dermObj.backendData.original_image, acne : dermObj.backendData.original_image, acne_cropped : dermObj.backendData.original_image, wrinkles : dermObj.backendData.original_image, wrinkles_cropped : dermObj.backendData.original_image } return; } dermObj.masks.getCropRect = async ()=>{ return new Promise(async (resolve,reject) => { if (dermObj.config.quizNoImage === true) { resolve() return; }; if (dermObj.backendData.azure_response == undefined && dermObj.capture.faceBox == undefined){ reject('azure_response undefined') return; } const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async ()=>{ let faceWidth; let faceHeight; let faceLeft; let faceTop; if (dermObj.backendData.azure_response != undefined){ const azureRes = dermObj.backendData.azure_response; faceWidth = azureRes.face_rectangle.width; faceHeight = azureRes.face_rectangle.height; faceLeft = azureRes.face_rectangle.left; faceTop = azureRes.face_rectangle.top; }else if (dermObj.capture.faceBox != undefined){ faceWidth = Math.round(dermObj.capture.faceBox._width); faceHeight = Math.round(dermObj.capture.faceBox._height); faceLeft = Math.round(dermObj.capture.faceBox._x); faceTop = Math.round(dermObj.capture.faceBox._y); }else{ reject('no face data'); return; } dermObj.masks.cropRect = {}; dermObj.masks.cropRect.originalImageWidth = img.naturalWidth; dermObj.masks.cropRect.originalImageHeight = img.naturalHeight; const cropLimitX = img.naturalWidth - 1; const cropLimitY = img.naturalHeight - 1; const cropMax = Math.max(faceWidth * 1.2, faceHeight * 1.6); let cropSize = Math.max(faceWidth, faceHeight); const cropStep = Math.round((cropMax - cropSize)/5); function evalCropAndImageSize(){ let withinImage = true; if (dermObj.masks.cropRect.left < 0){ withinImage = false; } if (dermObj.masks.cropRect.top < 0){ withinImage = false; } if (dermObj.masks.cropRect.left + dermObj.masks.cropRect.width > cropLimitX){ withinImage = false; } if (dermObj.masks.cropRect.top + dermObj.masks.cropRect.height > cropLimitY){ withinImage = false; } return withinImage; } let cropWithinImage = true; while (cropWithinImage && cropSize < cropMax){ dermObj.masks.cropRect.left = faceLeft + 0.5 * faceWidth - 0.5 * cropSize; dermObj.masks.cropRect.width = cropSize; dermObj.masks.cropRect.top = faceTop + 0.5 * faceHeight - 0.5 * cropSize; dermObj.masks.cropRect.height = cropSize; cropWithinImage = evalCropAndImageSize(); if (cropWithinImage){ cropSize += cropStep; }else{ cropSize -= cropStep; dermObj.masks.cropRect.left = faceLeft + 0.5 * faceWidth - 0.5 * cropSize; dermObj.masks.cropRect.width = cropSize; dermObj.masks.cropRect.top = faceTop + 0.5 * faceHeight - 0.5 * cropSize; dermObj.masks.cropRect.height = cropSize; } } resolve(); } img.src = dermObj.backendData.original_image; }) } dermObj.masks.makeOriginalImages = async ()=>{ return new Promise(async (resolve, reject)=>{ if (dermObj.config.quizNoImage === true) { resolve() return; }; if (dermObj.backendData.azure_response == undefined && dermObj.capture.faceBox == undefined){ await dermObj.masks.fillWithPlaceholderImage(); reject('azure_response undefined - using original image'); return; } const canvas = document.createElement("canvas"); canvas.id="fmc_original_img_obscured_canvas"; canvas.classList.add("fmc_hidden_canvas"); document.getElementById("fmc_mask_canvas_container").appendChild(canvas); const ctx = canvas.getContext('2d'); const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async ()=>{ canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img,0,0) if (dermObj.masks.obscurifyEyesFlag && dermObj.masks.eyeRect != undefined){ ctx.fillStyle = 'black'; ctx.fillRect(dermObj.masks.eyeRect.left, dermObj.masks.eyeRect.top, dermObj.masks.eyeRect.width, dermObj.masks.eyeRect.height); } dermObj.masks.images.original= canvas.toDataURL("image/jpeg") let cropOriginalCanvas = document.getElementById('fmc_original_canvas'); if (!cropOriginalCanvas){ cropOriginalCanvas= document.createElement('canvas'); cropOriginalCanvas.id = 'fmc_original_canvas'; document.getElementById("fmc_mask_canvas_container").appendChild(cropOriginalCanvas); } const ctxOriginalCanvas = cropOriginalCanvas.getContext('2d'); const originalImg = new Image(); originalImg.crossOrigin = "Anonymous"; originalImg.onload = async ()=>{ cropOriginalCanvas.width = dermObj.masks.cropRect.width; cropOriginalCanvas.height = dermObj.masks.cropRect.height; ctxOriginalCanvas.drawImage(originalImg,dermObj.masks.cropRect.left,dermObj.masks.cropRect.top,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height, 0, 0,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height ) dermObj.masks.images.original_cropped = cropOriginalCanvas.toDataURL("image/jpeg") resolve(); } originalImg.src = dermObj.masks.images.original; } img.src = dermObj.backendData.original_image; }) } dermObj.masks.buildMasks = async ()=>{ (async ()=>{ dermObj.masks.darkCircles(); })(); (async ()=>{ dermObj.masks.dehydrationAndRedness(); })(); (async ()=>{ dermObj.masks.acne(); })(); (async ()=>{ dermObj.masks.wrinkles(); })(); (async ()=>{ dermObj.masks.oiliness(); })(); } dermObj.masks.applyImageData = () => { document.querySelectorAll(`[data-widget-concern-img]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.original; }) document.querySelectorAll(`[data-widget-concern-img-cropped]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.original_cropped; }) const darkCirclesInterval = setInterval (()=>{ if (typeof dermObj.masks.images.darkCircles_cropped != 'undefined' ){ clearInterval(darkCirclesInterval); document.querySelectorAll(`[data-widget-concern-img=dark_circles]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.darkCircles; }) document.querySelectorAll(`[data-widget-concern-img-cropped=dark_circles]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.darkCircles_cropped; }) } },200); const rednessInterval = setInterval (()=>{ if (typeof dermObj.masks.images.redness_cropped != 'undefined' ){ clearInterval(rednessInterval); document.querySelectorAll(`[data-widget-concern-img=redness]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.redness; }) document.querySelectorAll(`[data-widget-concern-img-cropped=redness]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.redness_cropped; }) } },200); const dehydrInterval = setInterval (()=>{ if (typeof dermObj.masks.images.dehydration_cropped != 'undefined' ){ clearInterval(dehydrInterval); document.querySelectorAll(`[data-widget-concern-img=dehydration]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.dehydration; }) document.querySelectorAll(`[data-widget-concern-img-cropped=dehydration]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.dehydration_cropped; }) } },200); const oilinessInterval = setInterval (()=>{ if (typeof dermObj.masks.images.oiliness_cropped != 'undefined' ){ clearInterval(oilinessInterval); document.querySelectorAll(`[data-widget-concern-img=oiliness]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.oiliness; }) document.querySelectorAll(`[data-widget-concern-img-cropped=oiliness]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.oiliness_cropped; }) } },200); const acneInterval = setInterval (()=>{ if (typeof dermObj.masks.images.acne_cropped != 'undefined' ){ clearInterval(acneInterval); document.querySelectorAll(`[data-widget-concern-img=acne]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.acne; }) document.querySelectorAll(`[data-widget-concern-img-cropped=acne]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.acne_cropped; }) } },200); const wrinklesInterval = setInterval (()=>{ if (typeof dermObj.masks.images.wrinkles_cropped != 'undefined' ){ clearInterval(wrinklesInterval); document.querySelectorAll(`[data-widget-concern-img=wrinkles]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.wrinkles; }) document.querySelectorAll(`[data-widget-concern-img-cropped=wrinkles]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.wrinkles_cropped; }) } },200); } dermObj.masks.clearImages = () => { document.querySelectorAll(`[data-widget-concern-img]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img-cropped]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img=dark_circles]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img-cropped=dark_circles]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img=redness]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img-cropped=redness]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img=dehydration]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img-cropped=dehydration]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img=oiliness]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img-cropped=oiliness]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img=acne]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img-cropped=acne]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img=wrinkles]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img-cropped=wrinkles]`).forEach((imgEl)=>{ imgEl.src = ''; }) } dermObj.masks.calcDarkCirclesScore = async ()=>{ return new Promise((resolve,reject) => { if (dermObj.capture.faceApiIsLoaded){ const canvas = document.createElement('canvas'); canvas.id="fmc_dark_circles_canvas"; canvas.classList.add("fmc_hidden_canvas"); const ctx = canvas.getContext('2d'); document.getElementById("fmc_mask_canvas_container").appendChild(canvas); const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async () => { canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img,0,0) faceapi.detectAllFaces(canvas, dermObj.capture.modelOptions).withFaceLandmarks().then((landmarkDataArray)=>{ dermObj.debug("LANDMARK DATA ARRAY", landmarkDataArray); if (landmarkDataArray.length > 0){ const landmarkData = landmarkDataArray[0]; let leftEye = []; let rightEye = []; if (landmarkData.landmarks._shift._x >= 0 && landmarkData.landmarks._shift._y >= 0){ leftEye =landmarkData.landmarks.getLeftEye(); rightEye =landmarkData.landmarks.getRightEye(); }else if (landmarkData.landmarks._shift._x < 0 && landmarkData.landmarks._shift._y < 0){ leftEye =landmarkData.unshiftedLandmarks.getLeftEye(); rightEye =landmarkData.unshiftedLandmarks.getRightEye(); }else{ let unshiftedLeftEye = landmarkData.unshiftedLandmarks.getLeftEye(); let unshiftedRightEye = landmarkData.unshiftedLandmarks.getRightEye(); let shiftedLeftEye = landmarkData.landmarks.getLeftEye(); let shiftedRightEye = landmarkData.landmarks.getRightEye(); if (landmarkData.landmarks._shift._x >= 0){ shiftedLeftEye.forEach((eyePoint,index)=>{ leftEye.push({_x: shiftedLeftEye[index]._x , _y : unshiftedLeftEye[index]._y}); rightEye.push({_x: shiftedRightEye[index]._x , _y : unshiftedRightEye[index]._y}) }); }else{ shiftedLeftEye.forEach((eyePoint,index)=>{ leftEye.push({_x: unshiftedLeftEye[index]._x , _y : shiftedLeftEye[index]._y}); rightEye.push({_x: unshiftedRightEye[index]._x , _y : shiftedRightEye[index]._y}) }); } } let leftEyeBoxWidth = leftEye[3]._x - leftEye[0]._x; let rightEyeBoxWidth = rightEye[3]._x - rightEye[0]._x; let leftEyeBoxHeight = Math.max(leftEye[4]._y, leftEye[5]._y) - Math.min(leftEye[1]._y, leftEye[2]._y); let rightEyeBoxHeight = Math.max(rightEye[4]._y, rightEye[5]._y) - Math.min(rightEye[1]._y, rightEye[2]._y); let calcBoxWidth = Math.max(1.2*leftEyeBoxWidth,1.2*rightEyeBoxWidth); let calcBoxHeight = Math.max(1.2*leftEyeBoxHeight,1.2*rightEyeBoxHeight); let leftDarkCircleBox = {x : leftEye[0]._x - leftEyeBoxWidth*0.1,y : Math.max(leftEye[4]._y,leftEye[5]._y) + 0.6*leftEyeBoxHeight, w : calcBoxWidth, h : calcBoxHeight}; let rightDarkCircleBox = {x : rightEye[0]._x - rightEyeBoxWidth*0.1 ,y : Math.max(rightEye[4]._y,rightEye[5]._y)+ 0.6*rightEyeBoxHeight, w : calcBoxWidth, h : calcBoxHeight}; let leftCompareBox = { x: leftDarkCircleBox.x - 0.3*leftDarkCircleBox.w, y: leftDarkCircleBox.y + leftDarkCircleBox.h, w: leftDarkCircleBox.w, h: leftDarkCircleBox.h } let rightCompareBox = { x: rightDarkCircleBox.x + 0.3*leftDarkCircleBox.w, y: rightDarkCircleBox.y + rightDarkCircleBox.h, w: rightDarkCircleBox.w, h: rightDarkCircleBox.h } let darkCircleImgDataLeft = ctx.getImageData(leftDarkCircleBox.x, leftDarkCircleBox.y, leftDarkCircleBox.w , leftDarkCircleBox.h); let compareImgDataLeft = ctx.getImageData(leftCompareBox.x, leftCompareBox.y, leftCompareBox.w , leftCompareBox.h); let darkCircleImgDataRight = ctx.getImageData(rightDarkCircleBox.x, rightDarkCircleBox.y, rightDarkCircleBox.w , rightDarkCircleBox.h); let compareImgDataRight = ctx.getImageData(rightCompareBox.x, rightCompareBox.y, rightCompareBox.w , rightCompareBox.h); let darkCircleR = 0; let darkCircleG = 0; let darkCircleB = 0; let compareR = 0; let compareG = 0; let compareB = 0; for (let ii = 0; ii < darkCircleImgDataLeft.data.length/4; ii++){ darkCircleR += darkCircleImgDataLeft.data[4*ii]/255 + darkCircleImgDataRight.data[4*ii]/255 ; darkCircleG += darkCircleImgDataLeft.data[4*ii+1]/255 + darkCircleImgDataRight.data[4*ii+1]/255 ; darkCircleB += darkCircleImgDataLeft.data[4*ii+2]/255 + darkCircleImgDataRight.data[4*ii+2]/255 ; compareR += compareImgDataLeft.data[4*ii]/255 + compareImgDataRight.data[4*ii]/255 ; compareG += compareImgDataLeft.data[4*ii+1]/255 + compareImgDataRight.data[4*ii+1]/255 ; compareB += compareImgDataLeft.data[4*ii+2]/255 + compareImgDataRight.data[4*ii+2]/255 ; } let darkCircleLight = 0.2126 * darkCircleR + 0.7152 * darkCircleG + 0.0722 * darkCircleB; let compareLight = 0.2126 * compareR + 0.7152 * compareG + 0.0722 * compareB; dermObj.masks.darkCirclesScore = Math.max(1,Math.min(5,Math.floor(-50/3 * darkCircleLight/compareLight + 52/3))); if (isNaN(dermObj.masks.darkCirclesScore)){ dermObj.masks.darkCirclesScore =2; } }else{ dermObj.masks.darkCirclesImage = dermObj.masks.capturedImage; dermObj.masks.darkCirclesScore = 2; } resolve(); }); } img.src = dermObj.masks.capturedImage; }else{ dermObj.masks.images.darkCircles = dermObj.masks.capturedImage; dermObj.masks.darkCirclesScore = 2; resolve(); } }) } dermObj.masks.darkCircles = async ()=>{ dermObj.debug('darkCircles call'); return new Promise(async (resolve,reject) => { if (dermObj.config.quizNoImage === true) { resolve() return; }; let canvas; if (document.getElementById("fmc_dark_circles_canvas")){ canvas = document.getElementById("fmc_dark_circles_canvas"); }else{ canvas = document.createElement("canvas"); canvas.id="fmc_dark_circles_canvas"; canvas.classList.add("fmc_hidden_canvas"); document.getElementById("fmc_mask_canvas_container").appendChild(canvas); } const ctx = canvas.getContext('2d'); const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async ()=>{ canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img,0,0) faceapi.detectAllFaces(canvas, dermObj.capture.modelOptions).withFaceLandmarks().then( async (landmarkDataArray)=>{ //dermObj.debug("LANDMARK DATA ARRAY", landmarkDataArray); if (landmarkDataArray.length > 0){ const landmarkData = landmarkDataArray[0]; let leftEye = []; let rightEye = []; if (landmarkData.landmarks._shift._x >= 0 && landmarkData.landmarks._shift._y >= 0){ leftEye =landmarkData.landmarks.getLeftEye(); rightEye =landmarkData.landmarks.getRightEye(); }else if (landmarkData.landmarks._shift._x < 0 && landmarkData.landmarks._shift._y < 0){ leftEye =landmarkData.unshiftedLandmarks.getLeftEye(); rightEye =landmarkData.unshiftedLandmarks.getRightEye(); }else{ let unshiftedLeftEye = landmarkData.unshiftedLandmarks.getLeftEye(); let unshiftedRightEye = landmarkData.unshiftedLandmarks.getRightEye(); let shiftedLeftEye = landmarkData.landmarks.getLeftEye(); let shiftedRightEye = landmarkData.landmarks.getRightEye(); if (landmarkData.landmarks._shift._x >= 0){ shiftedLeftEye.forEach((eyePoint,index)=>{ leftEye.push({_x: shiftedLeftEye[index]._x , _y : unshiftedLeftEye[index]._y}); rightEye.push({_x: shiftedRightEye[index]._x , _y : unshiftedRightEye[index]._y}) }); }else{ shiftedLeftEye.forEach((eyePoint,index)=>{ leftEye.push({_x: unshiftedLeftEye[index]._x , _y : shiftedLeftEye[index]._y}); rightEye.push({_x: unshiftedRightEye[index]._x , _y : shiftedRightEye[index]._y}) }); } } let leftEyeBoxWidth = leftEye[3]._x - leftEye[0]._x; let rightEyeBoxWidth = rightEye[3]._x - rightEye[0]._x; let leftEyeBoxHeight = Math.max(leftEye[4]._y, leftEye[5]._y) - Math.min(leftEye[1]._y, leftEye[2]._y); let rightEyeBoxHeight = Math.max(rightEye[4]._y, rightEye[5]._y) - Math.min(rightEye[1]._y, rightEye[2]._y); let leftDarkCircleBox = {x : leftEye[0]._x - leftEyeBoxWidth*0.1,y : Math.max(leftEye[4]._y,leftEye[5]._y) + 0.6*leftEyeBoxHeight, w : 1.2*leftEyeBoxWidth, h : 1.2*leftEyeBoxHeight}; let rightDarkCircleBox = {x : rightEye[0]._x - rightEyeBoxWidth*0.1 ,y : Math.max(rightEye[4]._y,rightEye[5]._y)+ 0.6*rightEyeBoxHeight, w : 1.2*rightEyeBoxWidth, h : 1.2*rightEyeBoxHeight}; await dermObj.masks.drawWhiteEllipseInRect(leftDarkCircleBox.x,leftDarkCircleBox.y,leftDarkCircleBox.w,leftDarkCircleBox.h, ctx); await dermObj.masks.drawWhiteEllipseInRect (rightDarkCircleBox.x,rightDarkCircleBox.y,rightDarkCircleBox.w,rightDarkCircleBox.h, ctx); if (dermObj.masks.obscurifyEyesFlag){ ctx.fillStyle = 'black'; ctx.fillRect(dermObj.masks.eyeRect.left, dermObj.masks.eyeRect.top, dermObj.masks.eyeRect.width, dermObj.masks.eyeRect.height); } dermObj.masks.images.darkCircles = await canvas.toDataURL("image/jpeg") const croppedImage = new Image(); croppedImage.crossOrigin = "Anonymous"; croppedImage.onload = async ()=>{ canvas.width = dermObj.masks.cropRect.width; canvas.height = dermObj.masks.cropRect.height; ctx.drawImage(croppedImage,dermObj.masks.cropRect.left,dermObj.masks.cropRect.top,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height, 0, 0,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height ) dermObj.masks.images.darkCircles_cropped = canvas.toDataURL("image/jpeg") resolve(); } croppedImage.src = dermObj.masks.images.darkCircles } }) } img.src = dml_fmc.backendData.original_image; }) } dermObj.masks.drawWhiteEllipseInRect = async (coordsX,coordsY,width,height,ctx) => { let scaleFact = 1.2; let scaledWidth = width*1.2; let scaledHeight = height*1.2; let centerX = coordsX + 0.5*width; let centerY = coordsY + 0.5*height; ctx.beginPath(); ctx.moveTo(centerX - scaledWidth/2, centerY); // A1 ctx.bezierCurveTo( centerX - scaledWidth/2, centerY - scaledHeight/2, // C1 centerX + scaledWidth/2, centerY - scaledHeight/2, // C2 centerX + scaledWidth/2, centerY); // A2 ctx.bezierCurveTo( centerX + scaledWidth/2, centerY + scaledHeight/2, // C3 centerX - scaledWidth/2, centerY + scaledHeight/2, // C4 centerX - scaledWidth/2, centerY); // A1 let lineWidth; try{ lineWidth = Math.max(2, Math.ceil(Math.max(dermObj.masks.cropRect.width, dermObj.masks.cropRect.height)/400) ); }catch(err){ lineWidth = 2; } //dermObj.debug('LINE WIDTH: ', lineWidth) ctx.lineWidth = lineWidth; ctx.strokeStyle = "white"; ctx.stroke(); ctx.closePath(); return; } dermObj.masks.dehydrationAndRedness = async ()=>{ return new Promise(async (resolve, reject) => { if (dermObj.config.quizNoImage === true) { resolve() return; }; let imgScaleFactor = 1; const canvasDehydr = document.createElement("canvas"); canvasDehydr.id="fmc_dehydration_canvas"; canvasDehydr.classList.add("fmc_hidden_canvas"); document.getElementById("fmc_mask_canvas_container").appendChild(canvasDehydr); const ctxDehydr = canvasDehydr.getContext('2d'); const canvasRed = document.createElement("canvas"); canvasRed.id="fmc_redness_canvas"; canvasRed.classList.add("fmc_hidden_canvas"); document.getElementById("fmc_mask_canvas_container").appendChild(canvasRed); const ctxRed = canvasRed.getContext('2d'); const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async ()=>{ const maxFaceDim = Math.max(dermObj.masks.cropRect.width, dermObj.masks.cropRect.height); if (maxFaceDim > 500 ){ imgScaleFactor = 500 / maxFaceDim; } //dermObj.debug('Dehydration mask Scale Factor: ', imgScaleFactor); const imgUsedWidth = Math.ceil(img.naturalWidth * imgScaleFactor); const imgUsedHeight = Math.ceil(img.naturalHeight * imgScaleFactor); canvasDehydr.width = imgUsedWidth; canvasDehydr.height = imgUsedHeight; ctxDehydr.drawImage(img,0,0,img.naturalWidth,img.naturalHeight,0,0,imgUsedWidth,imgUsedHeight) canvasRed.width = imgUsedWidth; canvasRed.height = imgUsedHeight; ctxRed.drawImage(img,0,0,img.naturalWidth,img.naturalHeight,0,0,imgUsedWidth,imgUsedHeight) faceapi.detectAllFaces(canvasDehydr, dermObj.capture.modelOptions).withFaceLandmarks().then( async (landmarkDataArray)=>{ //dermObj.debug("LANDMARK DATA ARRAY", landmarkDataArray); if (landmarkDataArray.length > 0){ const landmarkData = landmarkDataArray[0]; let leftEye = []; let rightEye = []; let leftEyeBrow = []; let rightEyeBrow = []; let jaw = []; let mouth = []; let nose = []; if (landmarkData.landmarks._shift._x >= 0 && landmarkData.landmarks._shift._y >= 0){ leftEye =landmarkData.landmarks.getLeftEye(); rightEye =landmarkData.landmarks.getRightEye(); leftEyeBrow = landmarkData.landmarks.getLeftEyeBrow(); rightEyeBrow = landmarkData.landmarks.getRightEyeBrow(); jaw = landmarkData.landmarks.getJawOutline(); mouth = landmarkData.landmarks.getMouth(); nose = landmarkData.landmarks.getNose(); }else if (landmarkData.landmarks._shift._x < 0 && landmarkData.landmarks._shift._y < 0){ leftEye =landmarkData.unshiftedLandmarks.getLeftEye(); rightEye =landmarkData.unshiftedLandmarks.getRightEye(); leftEyeBrow = landmarkData.unshiftedLandmarks.getLeftEyeBrow(); rightEyeBrow = landmarkData.unshiftedLandmarks.getRightEyeBrow(); jaw = landmarkData.unshiftedLandmarks.getJawOutline(); mouth = landmarkData.unshiftedLandmarks.getMouth(); nose = landmarkData.unshiftedLandmarks.getNose(); }else{ let unshiftedLeftEye = landmarkData.unshiftedLandmarks.getLeftEye(); let unshiftedRightEye = landmarkData.unshiftedLandmarks.getRightEye(); let shiftedLeftEye = landmarkData.landmarks.getLeftEye(); let shiftedRightEye = landmarkData.landmarks.getRightEye(); let unshiftedLeftEyeBrow = landmarkData.unshiftedLandmarks.getLeftEyeBrow(); let unshiftedRightEyeBrow = landmarkData.unshiftedLandmarks.getRightEyeBrow(); let shiftedLeftEyeBrow = landmarkData.landmarks.getLeftEyeBrow(); let shiftedRightEyeBrow = landmarkData.landmarks.getRightEyeBrow(); let shiftedJaw = landmarkData.landmarks.getJawOutline(); let unshiftedJaw = landmarkData.unshiftedLandmarks.getJawOutline(); let shiftedMouth = landmarkData.landmarks.getMouth(); let unshiftedMouth = landmarkData.unshiftedLandmarks.getMouth(); let shiftedNose = landmarkData.landmarks.getMouth(); let unshiftedNose = landmarkData.unshiftedLandmarks.getNose(); if (landmarkData.landmarks._shift._x >= 0){ shiftedLeftEye.forEach((eyePoint,index)=>{ leftEye.push({_x: shiftedLeftEye[index]._x , _y : unshiftedLeftEye[index]._y}); rightEye.push({_x: shiftedRightEye[index]._x , _y : unshiftedRightEye[index]._y}) }); shiftedLeftEyeBrow.forEach((eyeBrowPoint,index)=>{ leftEyeBrow.push({_x: shiftedLeftEyeBrow[index]._x , _y : unshiftedLeftEyeBrow[index]._y}); rightEyeBrow.push({_x: shiftedRightEyeBrow[index]._x , _y : unshiftedRightEyeBrow[index]._y}) }); shiftedJaw.forEach((jawPoint,index)=>{ jaw.push({_x: shiftedJaw[index]._x , _y : unshiftedJaw[index]._y}); }); shiftedMouth.forEach((mouthPoint,index)=>{ mouth.push({_x: shiftedMouth[index]._x , _y : unshiftedMouth[index]._y}); }); shiftedNose.forEach((nosePoint,index)=>{ try{ nose.push({_x: shiftedNose[index]._x , _y : unshiftedNose[index]._y}); }catch(err){ nose.push({_x: shiftedNose[index]._x , _y : shiftedNose[index]._y}); } }); }else{ shiftedLeftEye.forEach((eyePoint,index)=>{ leftEye.push({_x: unshiftedLeftEye[index]._x , _y : shiftedLeftEye[index]._y}); rightEye.push({_x: unshiftedRightEye[index]._x , _y : shiftedRightEye[index]._y}) }); shiftedLeftEyeBrow.forEach((eyeBrowPoint,index)=>{ leftEyeBrow.push({_x: unshiftedLeftEyeBrow[index]._x , _y : shiftedLeftEyeBrow[index]._y}); rightEyeBrow.push({_x: unshiftedRightEyeBrow[index]._x , _y : shiftedRightEyeBrow[index]._y}) }); shiftedJaw.forEach((jawPoint,index)=>{ jaw.push({_x: unshiftedJaw[index]._x , _y : shiftedJaw[index]._y}); }); shiftedMouth.forEach((mouthPoint,index)=>{ mouth.push({_x: unshiftedMouth[index]._x , _y : shiftedMouth[index]._y}); }); shiftedNose.forEach((nosePoint,index)=>{ try{ nose.push({_x: unshiftedNose[index]._x , _y : shiftedNose[index]._y}); }catch(err){ nose.push({_x: shiftedNose[index]._x , _y : shiftedNose[index]._y}); } }); } } let topLeftEyeBrowY = leftEyeBrow[2]._y; let topRightEyeBrowY = rightEyeBrow[2]._y; let lowLeftEyeY = Math.max(leftEye[4]._y,leftEye[5]._y); let lowRightEyeY = Math.max(rightEye[4]._y,rightEye[5]._y); let faceRectToScan = { x: Math.round(jaw[2]._x) + 0.0*(jaw[14]._x - jaw[2]._x) , y: Math.round(2.0 * Math.min(topLeftEyeBrowY,topRightEyeBrowY) - 1.0*Math.min(lowLeftEyeY,lowRightEyeY) - 0.05*(jaw[8]._y - 2.0 * Math.min(topLeftEyeBrowY,topRightEyeBrowY) + 1.0*Math.min(lowLeftEyeY,lowRightEyeY))), w: Math.round(1.0*(jaw[14]._x - jaw[2]._x)), //w: Math.round(1.0*(rightEyeBrow[4]._x - leftEyeBrow[0]._x)), h: Math.round(1.1*(jaw[8]._y - 2.0 * Math.min(topLeftEyeBrowY,topRightEyeBrowY) + 1.0*Math.min(lowLeftEyeY,lowRightEyeY))) } let leftEyeBlankRect = { x: Math.round(jaw[0]._x), y: Math.round(topLeftEyeBrowY - 0.2*(lowLeftEyeY - topLeftEyeBrowY)), w: Math.round( 0.5*leftEye[3]._x + 0.5*rightEye[0]._x -jaw[0]._x ), h: Math.round(1.7*(lowLeftEyeY - topLeftEyeBrowY)) } let rightEyeBlankRect = { x: Math.round( leftEye[3]._x + 0.5*(rightEye[0]._x - leftEye[3]._x )), y: Math.round(topRightEyeBrowY - 0.2*(lowRightEyeY - topRightEyeBrowY)), w: Math.round( jaw[16]._x - leftEye[3]._x - 0.5*(rightEye[0]._x - leftEye[3]._x ) ), h: Math.round(1.7*(lowRightEyeY - topRightEyeBrowY)) } let mouthBlankRect = { x: Math.round( mouth[0]._x - 0.2 * (mouth[6]._x - mouth[0]._x)), y: Math.round(mouth[2]._y - 0.2* (mouth[9]._y - mouth[2]._y)), w: Math.round( 1.4*(mouth[6]._x - mouth[0]._x) ), h: Math.round( 1.4* (mouth[9]._y - mouth[2]._y)) } let noseBlankRect = { x: Math.round( nose[4]._x - 0.5*(nose[8]._x - nose[4]._x)), y: Math.round( nose[3]._y - 0.7*(nose[6]._y - nose[3]._y)), w: Math.round( 2*(nose[8]._x - nose[4]._x) ), h: Math.round( 2* (nose[6]._y - nose[3]._y)) } let imageData = ctxDehydr.getImageData(faceRectToScan.x ,faceRectToScan.y , faceRectToScan.w, faceRectToScan.h ); let dehydrationImgData = ctxDehydr.createImageData(imageData.width, imageData.height) let rednessImgData = ctxDehydr.createImageData(imageData.width, imageData.height) let y=0; let x=0; const modTarget = Math.ceil(imageData.height / 100) //dermObj.debug(`estimated pixels per block: ${modTarget * imageData.width}`); //dermObj.debug(`image width: ${imageData.width}`); //dermObj.debug(`image height: ${imageData.height}`); //dermObj.debug(`modTarget: ${modTarget}`); //const dehydrationStartTime = (new Date).getTime(); async function processImageBlocks(){ return new Promise( async (imgRes,imgRej)=>{ //logOnLocalHostFrontEnd("processing image block - cur y = ",y); let initBlockCall = true; while( y< imageData.height && ( y % modTarget != 0) || initBlockCall){ initBlockCall = false; while( x< imageData.width ){ let ii = y* imageData.width + x; let minBlue = 255; let maxBlue = 0; let avRed = 0; let avCounter = 0; const calcLimit = 10; for (var scan_x = - calcLimit; scan_x < calcLimit + 1; scan_x++ ){ for (var scan_y = - calcLimit; scan_y < calcLimit + 1; scan_y++ ){ let idx = (ii-scan_x + scan_y*imageData.width ); while (idx < 0){ idx += imageData.data.length/4; } while (idx >= imageData.data.length/4){ idx -= imageData.data.length/4; } minBlue = Math.min(minBlue, imageData.data[idx*4+2]); maxBlue = Math.max(maxBlue, imageData.data[idx*4+2]); avRed += imageData.data[idx*4+0] / (imageData.data[idx*4+0]+imageData.data[idx*4+1]+imageData.data[idx*4+2]); avCounter++; } } let curColorObj = dermObj.masks.getColorFromGradient(Math.min(Math.max(Math.round((imageData.data[ii*4+2]-minBlue)/(maxBlue - minBlue)*255),0),255)); dehydrationImgData.data[ii*4+0] = curColorObj.r; dehydrationImgData.data[ii*4+1] = curColorObj.g; dehydrationImgData.data[ii*4+2] = curColorObj.b; let faceAlpha = dermObj.masks.calcOpacityEllipse(ii % imageData.width,Math.floor(ii/imageData.width), {x:0,y:0,w:imageData.width,h:imageData.height}, 0.2 ); let leftEyeAlpha = 255-dermObj.masks.calcOpacityEllipse(ii % imageData.width,Math.floor(ii/imageData.width), {x:Math.round(leftEyeBlankRect.x-faceRectToScan.x),y:Math.round(leftEyeBlankRect.y-faceRectToScan.y),w:leftEyeBlankRect.w,h:leftEyeBlankRect.h}, 0.4 ); let rightEyeAlpha = 255-dermObj.masks.calcOpacityEllipse(ii % imageData.width,Math.floor(ii/imageData.width), {x:Math.round(rightEyeBlankRect.x-faceRectToScan.x),y:Math.round(rightEyeBlankRect.y-faceRectToScan.y),w:rightEyeBlankRect.w,h:rightEyeBlankRect.h}, 0.4 ); let mouthAlpha = 255-dermObj.masks.calcOpacityEllipse(ii % imageData.width,Math.floor(ii/imageData.width), {x:Math.round(mouthBlankRect.x-faceRectToScan.x),y:Math.round(mouthBlankRect.y-faceRectToScan.y),w:mouthBlankRect.w,h:mouthBlankRect.h}, 0.4 ); let noseAlpha = 255-dermObj.masks.calcOpacityEllipse(ii % imageData.width,Math.floor(ii/imageData.width), {x:Math.round(noseBlankRect.x-faceRectToScan.x),y:Math.round(noseBlankRect.y-faceRectToScan.y),w:noseBlankRect.w,h:noseBlankRect.h}, 0.4 ); let maskAlpha = 1*Math.min(faceAlpha,leftEyeAlpha,rightEyeAlpha,mouthAlpha,noseAlpha)/255; dehydrationImgData.data[ii*4+0] = Math.round(maskAlpha * dehydrationImgData.data[ii*4+0] + (1-maskAlpha) * imageData.data[ii*4+0]); dehydrationImgData.data[ii*4+1] = Math.round(maskAlpha * dehydrationImgData.data[ii*4+1] + (1-maskAlpha) * imageData.data[ii*4+1]); dehydrationImgData.data[ii*4+2] = Math.round(maskAlpha * dehydrationImgData.data[ii*4+2] + (1-maskAlpha) * imageData.data[ii*4+2]); dehydrationImgData.data[ii*4+3] = 255; avRed /= avCounter; let curRedRatio = imageData.data[ii*4+0] / (imageData.data[ii*4+0]+imageData.data[ii*4+1]+imageData.data[ii*4+2]); if ( curRedRatio + 0.005 > avRed){ rednessImgData.data[ii*4+0] = imageData.data[ii*4+0]; rednessImgData.data[ii*4+1] = Math.round(imageData.data[ii*4+1] * (1 - 10*(curRedRatio + 0.005 - avRed))); rednessImgData.data[ii*4+2] = Math.round(imageData.data[ii*4+2] * (1 - 10*(curRedRatio + 0.005 - avRed))); }else{ rednessImgData.data[ii*4+0] = imageData.data[ii*4+0]; rednessImgData.data[ii*4+1] = imageData.data[ii*4+1]; rednessImgData.data[ii*4+2] = imageData.data[ii*4+2]; } rednessImgData.data[ii*4+0] = Math.round(maskAlpha * rednessImgData.data[ii*4+0] + (1-maskAlpha) * imageData.data[ii*4+0]); rednessImgData.data[ii*4+1] = Math.round(maskAlpha * rednessImgData.data[ii*4+1] + (1-maskAlpha) * imageData.data[ii*4+1]); rednessImgData.data[ii*4+2] = Math.round(maskAlpha * rednessImgData.data[ii*4+2] + (1-maskAlpha) * imageData.data[ii*4+2]); rednessImgData.data[ii*4+3] = 255; x++; } x=0; y++; } ctxDehydr.putImageData(dehydrationImgData,faceRectToScan.x, faceRectToScan.y); ctxRed.putImageData(rednessImgData,faceRectToScan.x, faceRectToScan.y); if (y < imageData.height){ setTimeout(async ()=>{ processImageBlocks() },10) }else{ //const dehydrationEndTime = (new Date).getTime(); //dermObj.debug('total pixels: ', imageData.data.length/4) //dermObj.debug('total process time [s]: ', (dehydrationEndTime - dehydrationStartTime)/1000); //dermObj.debug('block pixels: ', imageData.width * modTarget) //dermObj.debug('av block process time [ms]: ', (dehydrationEndTime - dehydrationStartTime)/Math.ceil(imageData.height / modTarget)); if (dermObj.masks.obscurifyEyesFlag){ ctxDehydr.fillStyle = 'black'; ctxDehydr.fillRect(dermObj.masks.eyeRect.left * imgScaleFactor, dermObj.masks.eyeRect.top * imgScaleFactor, dermObj.masks.eyeRect.width * imgScaleFactor, dermObj.masks.eyeRect.height * imgScaleFactor); ctxRed.fillStyle = 'black'; ctxRed.fillRect(dermObj.masks.eyeRect.left * imgScaleFactor, dermObj.masks.eyeRect.top * imgScaleFactor, dermObj.masks.eyeRect.width * imgScaleFactor, dermObj.masks.eyeRect.height * imgScaleFactor); } dermObj.masks.images.dehydration = canvasDehydr.toDataURL("image/jpeg"); dermObj.masks.images.redness = canvasRed.toDataURL("image/jpeg"); imageData = null; dehydrationImgData = null; rednessImgData = null; const cropDehyPromise = new Promise((resCrop,rejCrop)=>{ const croppedImageDehy = new Image(); croppedImageDehy.crossOrigin = "Anonymous"; croppedImageDehy.onload = async ()=>{ canvasDehydr.width = dermObj.masks.cropRect.width; canvasDehydr.height = dermObj.masks.cropRect.height; ctxDehydr.drawImage(croppedImageDehy,dermObj.masks.cropRect.left * imgScaleFactor,dermObj.masks.cropRect.top * imgScaleFactor,dermObj.masks.cropRect.width * imgScaleFactor,dermObj.masks.cropRect.height * imgScaleFactor, 0, 0,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height); dermObj.masks.images.dehydration_cropped = canvasDehydr.toDataURL("image/jpeg") resCrop(); } croppedImageDehy.src = dermObj.masks.images.dehydration }) const cropRedPromise = new Promise((resCrop,rejCrop)=>{ const croppedImageRed = new Image(); croppedImageRed.crossOrigin = "Anonymous"; croppedImageRed.onload = async ()=>{ canvasRed.width = dermObj.masks.cropRect.width; canvasRed.height = dermObj.masks.cropRect.height; ctxRed.drawImage(croppedImageRed,dermObj.masks.cropRect.left * imgScaleFactor,dermObj.masks.cropRect.top * imgScaleFactor,dermObj.masks.cropRect.width * imgScaleFactor,dermObj.masks.cropRect.height * imgScaleFactor, 0, 0,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height); dermObj.masks.images.redness_cropped = canvasRed.toDataURL("image/jpeg") resCrop(); } croppedImageRed.src = dermObj.masks.images.redness }) Promise.all([cropDehyPromise,cropRedPromise]).then(()=>{ resolve(); }); } }) } processImageBlocks() } }); } img.src = dml_fmc.backendData.original_image; }) } dermObj.masks.getColorFromGradient = (gradientPoint) => { let colorObj = {r:0,g:0,b:0} if (gradientPoint > 210){ colorObj.r = 225 + Math.round(30 * ( (gradientPoint - 210 )/ 45)); colorObj.g = 141 - Math.round(141 * ( (gradientPoint - 210 )/ 45)); colorObj.b = 0; } else if (gradientPoint > 160){ colorObj.r = 242 - Math.round(13 * ( (gradientPoint - 160 )/ 50)); colorObj.g = 226 - Math.round(85 * ( (gradientPoint - 160 )/ 50)); colorObj.b = 0; }else{ colorObj.r = 55 - Math.round(44 * (gradientPoint / 160)); colorObj.g = 192 - Math.round(50 * (gradientPoint / 160)) ; colorObj.b = 176 + Math.round(16 * (gradientPoint / 160)); } return colorObj; } dermObj.masks.calcOpacityEllipse = (point_x, point_y, ellRectObj, fullAlphaFact = 0.05 ) => { let scaleDimensions = 0.9; let aSqu = (ellRectObj.w/2*scaleDimensions)*(ellRectObj.w/2*scaleDimensions); let bSqu = (ellRectObj.h/2*scaleDimensions)*(ellRectObj.h/2*scaleDimensions); let centX = ellRectObj.x + 0.5*ellRectObj.w; let centY = ellRectObj.y + 0.5*ellRectObj.h; let ellVal = (point_x-centX)*(point_x-centX)/aSqu + (point_y - centY)*(point_y-centY)/bSqu - 1; let alpha255 = Math.round(Math.min(1,Math.max(0,-ellVal/fullAlphaFact))*255); return alpha255; } dermObj.masks.acne = async ()=>{ //console.log('- ACNE MASK -') return new Promise(async (resolve,reject) => { if (dermObj.config.quizNoImage === true) { resolve() return; }; let canvas; if (document.getElementById("fmc_acne_canvas")){ canvas = document.getElementById("fmc_acne_canvas"); }else{ canvas = document.createElement("canvas"); canvas.id="fmc_acne_canvas"; canvas.classList.add("fmc_hidden_canvas"); document.getElementById("fmc_mask_canvas_container").appendChild(canvas); } const ctx = canvas.getContext('2d'); const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async ()=>{ canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img,0,0) let acneData; try{ acneData = dermObj.backendData.revieve_response.results.filter(item => item.description == 'acne')[0]; }catch(err){ console.error('error in getting acne data - ',err); } //console.log(' ACNE DATA: ',acneData) acneData.measurement_locations.forEach(async (faceLocation) => { if (faceLocation.visualization_data != null && faceLocation.visualization_data != undefined){ faceLocation.visualization_data.forEach(async (detailLocation) => { const radius = Math.max(5,Math.min(detailLocation.length_weighted_intensity/15,30)); const opacity = Math.max(0.05,Math.min(detailLocation.length_weighted_intensity/300,0.5)); /* console.log('INTENSITY Length Weightened: ', detailLocation.length_weighted_intensity); console.log(radius, opacity) console.log('---------------'); */ if (detailLocation.length_weighted_intensity > 5){ await dermObj.masks.drawAcneCircle(detailLocation.x,detailLocation.y,radius,opacity,ctx); } }) } }) if (dermObj.masks.obscurifyEyesFlag){ ctx.fillStyle = 'black'; ctx.fillRect(dermObj.masks.eyeRect.left, dermObj.masks.eyeRect.top, dermObj.masks.eyeRect.width, dermObj.masks.eyeRect.height); } //console.log('FINISH ACNE IMAGE') dermObj.masks.images.acne = await canvas.toDataURL("image/jpeg") const croppedImage = new Image(); croppedImage.crossOrigin = "Anonymous"; croppedImage.onload = async ()=>{ canvas.width = dermObj.masks.cropRect.width; canvas.height = dermObj.masks.cropRect.height; ctx.drawImage(croppedImage,dermObj.masks.cropRect.left,dermObj.masks.cropRect.top,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height, 0, 0,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height ) dermObj.masks.images.acne_cropped = canvas.toDataURL("image/jpeg") resolve(); } croppedImage.src = dermObj.masks.images.acne } img.src = dml_fmc.backendData.original_image; }) } dermObj.masks.drawAcneCircle = async (coordsX,coordsY,radius,opacity,ctx) => { let scaleFact = 1.2; let lineWidth; try{ lineWidth = Math.max(2, Math.ceil(Math.max(dermObj.masks.cropRect.width, dermObj.masks.cropRect.height)/400) ); }catch(err){ lineWidth = 2; } //dermObj.debug('LINE WIDTH: ', lineWidth) ctx.beginPath(); ctx.lineWidth = lineWidth; ctx.arc(coordsX,coordsY,radius, 0, 2*Math.PI); ctx.strokeStyle = `rgba(255,255,255,${opacity})`; ctx.fillStyle = `rgba(200,55,55,${opacity/5})`; ctx.fill(); ctx.stroke(); ctx.closePath(); return; } dermObj.masks.wrinkles = async ()=>{ return new Promise(async (resolve,reject) => { if (dermObj.config.quizNoImage === true) { resolve() return; }; let canvas; if (document.getElementById("fmc_wrinkles_canvas")){ canvas = document.getElementById("fmc_wrinkles_canvas"); }else{ canvas = document.createElement("canvas"); canvas.id="fmc_wrinkles_canvas"; canvas.classList.add("fmc_hidden_canvas"); document.getElementById("fmc_mask_canvas_container").appendChild(canvas); } const ctx = canvas.getContext('2d'); const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async ()=>{ canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img,0,0) let wrinklesData; try{ wrinklesData = dermObj.backendData.revieve_response.results.filter(item => item.description == 'wrinkles')[0]; //console.log(' wrinkles DATA: ',wrinklesData) wrinklesData.measurement_locations.forEach(async (faceLocation) => { if (faceLocation.visualization_data != null && faceLocation.visualization_data != undefined){ faceLocation.visualization_data.forEach(async (detailLocation) => { //console.log(detailLocation.length_weighted_intensity, detailLocation.x.length) if (detailLocation.length_weighted_intensity > 0.2 && detailLocation.x.length > 15){ const scaleFact = Math.max(1, Math.ceil(Math.max(dermObj.masks.cropRect.width, dermObj.masks.cropRect.height)/400) ); detailLocation.x.forEach((xCoord, coordIndex) => { const radius = scaleFact * Math.max(1,detailLocation.intensity[coordIndex]*2); dermObj.masks.drawWrinkle(xCoord,detailLocation.y[coordIndex],radius,Math.max(0.05,0.5*detailLocation.intensity[coordIndex]),ctx) }) } }) } }) }catch(err){ console.error('error in getting wrinkles data - ',err); } if (dermObj.masks.obscurifyEyesFlag){ ctx.fillStyle = 'black'; ctx.fillRect(dermObj.masks.eyeRect.left, dermObj.masks.eyeRect.top, dermObj.masks.eyeRect.width, dermObj.masks.eyeRect.height); } //console.log('FINISH wrinkles IMAGE') dermObj.masks.images.wrinkles = await canvas.toDataURL("image/jpeg") const croppedImage = new Image(); croppedImage.crossOrigin = "Anonymous"; croppedImage.onload = async ()=>{ canvas.width = dermObj.masks.cropRect.width; canvas.height = dermObj.masks.cropRect.height; ctx.drawImage(croppedImage,dermObj.masks.cropRect.left,dermObj.masks.cropRect.top,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height, 0, 0,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height ) dermObj.masks.images.wrinkles_cropped = canvas.toDataURL("image/jpeg") resolve(); } croppedImage.src = dermObj.masks.images.wrinkles } img.src = dml_fmc.backendData.original_image; }) } dermObj.masks.drawWrinkle = async (coordsX,coordsY,radius,opacity,ctx) => { ctx.beginPath(); ctx.arc(coordsX,coordsY,radius, 0, 2*Math.PI); ctx.fillStyle = `rgba(255, 0, 0,${opacity})`; ctx.fill(); ctx.closePath(); return; } dermObj.masks.oiliness = async ()=>{ return new Promise(async (resolve,reject) => { if (dermObj.config.quizNoImage === true) { resolve() return; }; let canvas; if (document.getElementById("fmc_oiliness_canvas")){ canvas = document.getElementById("fmc_oiliness_canvas"); }else{ canvas = document.createElement("canvas"); canvas.id="fmc_oiliness_canvas"; canvas.classList.add("fmc_hidden_canvas"); document.getElementById("fmc_mask_canvas_container").appendChild(canvas); } const ctx = canvas.getContext('2d'); const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async ()=>{ canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img,0,0) let oilinessData; try{ oilinessData = dermObj.backendData.revieve_response.results.filter(item => item.description == 'Skin shine')[0]; //console.log(' oiliness DATA: ',oilinessData) oilinessData.measurement_locations.forEach(async (faceLocation) => { if (faceLocation.visualization_data != null && faceLocation.visualization_data != undefined){ faceLocation.visualization_data.forEach(async (detailLocation) => { if (detailLocation.length_weighted_intensity > 0.1 && detailLocation.x.length > 1){ dermObj.masks.drawOiliness(detailLocation,ctx) } }) } }) }catch(err){ console.error('error in getting oiliness data - ',err); } if (dermObj.masks.obscurifyEyesFlag){ ctx.fillStyle = 'black'; ctx.fillRect(dermObj.masks.eyeRect.left, dermObj.masks.eyeRect.top, dermObj.masks.eyeRect.width, dermObj.masks.eyeRect.height); } //console.log('FINISH oiliness IMAGE') dermObj.masks.images.oiliness = await canvas.toDataURL("image/jpeg") const croppedImage = new Image(); croppedImage.crossOrigin = "Anonymous"; croppedImage.onload = async ()=>{ canvas.width = dermObj.masks.cropRect.width; canvas.height = dermObj.masks.cropRect.height; ctx.drawImage(croppedImage,dermObj.masks.cropRect.left,dermObj.masks.cropRect.top,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height, 0, 0,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height ) dermObj.masks.images.oiliness_cropped = canvas.toDataURL("image/jpeg") resolve(); } croppedImage.src = dermObj.masks.images.oiliness } img.src = dml_fmc.backendData.original_image; }) } dermObj.masks.drawOiliness = async (visData,ctx) => { const opacity = 0.15; //visData.length_weighted_intensity * 0.1; ctx.beginPath(); visData.x.forEach((xCoord, index) => { if (index == 0){ ctx.moveTo(xCoord,visData.y[index]); }else{ ctx.lineTo(xCoord,visData.y[index]); } }) //ctx.lineTo(xCoord,visData.y[index]); ctx.fillStyle = `rgba(255, 0, 0,${Math.min(1,4*opacity)})`; ctx.closePath(); ctx.fill(); return; } dermObj.makePriceString =(productObj) => { const price = productObj.price; const currency = productObj.priceCurrency; let priceString = `${currency}${price}`; //default if (currency == "¥"){ const priceAsString = String(Number(price)); // remove commas let numDots = Math.floor(priceAsString.length / 3) let curDotPos = (priceAsString.length) % 3; if (curDotPos == 0){ curDotPos = 3; numDots--; } let outString = ""; let dotCounter = 0; for (let ii=0; ii < priceAsString.length; ii++){ outString += priceAsString[ii]; if (ii+1 == curDotPos && dotCounter < numDots){ curDotPos += 3; outString += ","; dotCounter++; } } priceString = `${currency}${outString}`; } if (currency == "$MXN"){ priceString = `${price} MXN`; } return priceString; } dermObj.storeLocator = {} dermObj.storeLocator.updateStoreLocations = async() => { return new Promise(async (resolve, reject)=>{ if (dermObj.config.storeLocator.showStores){ dermObj.body.querySelectorAll('.fmc_results_store_location_section').forEach((storeLocationSection)=>{ storeLocationSection.style.display = "none"; }); try{ const storesArr = await dermObj.storeLocator.getStoreLocations() if (storesArr.length < 2){ resolve(); }else{ dermObj.body.querySelectorAll('.fmc_results_store_location_section').forEach((storeLocationSection)=>{ storeLocationSection.style.display = "flex"; }); dermObj.debug("STORES: ", storesArr); storesArr.pop(); while(storesArr.length > 3){ storesArr.pop(); } dermObj.body.querySelectorAll('.fmc_results_store_location_section').forEach((storeSection)=>{ storeSection.querySelectorAll('.fmc_skin_center_card').forEach((storeCard,index)=>{ if (storesArr.length > index){ storeCard.querySelector('.fmc_skin_center_name').innerHTML = storesArr[index].LocationName; storeCard.querySelector('.fmc_skin_center_distance').innerHTML = `${Number(storesArr[index].Distance.trim())} miles`; storeCard.querySelector('.fmc_skin_center_address_street').innerHTML = storesArr[index].AddressLine.trim(); storeCard.querySelector('.fmc_skin_center_address_zip_city').innerHTML = `${storesArr[index].PrimaryCity.trim()}, ${storesArr[index].SubDivision.trim()} ${storesArr[index].PostalCode.trim()}`; storeCard.querySelector('.fmc_skin_center_address_phone').innerHTML = storesArr[index].Phone.trim().replace(")",") ").replace(" "," "); storeCard.querySelector('.fmc_skin_center_call_button').setAttribute('href', `tel:${storesArr[index].Phone.trim().replace(")","").replace("(","").replace(" ","-")}`) storeCard.querySelector('.fmc_skin_center_directions_button').setAttribute('href', `https://www.google.com/maps?daddr=${storesArr[index].AddressLine.trim().replace(" ","+")}+${storesArr[index].PostalCode.trim()}+${storesArr[index].PrimaryCity.trim().replace(" ","+")}`) }else{ storeCard.style.display = "none"; } }); }) resolve(); } }catch(err){ reject(err); } }else{ dermObj.body.querySelectorAll('.fmc_results_store_location_section').forEach((storeLocationSection)=>{ storeLocationSection.style.display = "none"; }); resolve(); } }) } dermObj.storeLocator.getStoreLocations = async ()=>{ return new Promise(async(resolve,reject)=>{ const navigatorOptions = { enableHighAccuracy: true, timeout: 60000, maximumAge: 10*60*1000 // 10 mins ... 10 * 60s * 1000ms } try{ navigator.geolocation.getCurrentPosition((position)=>{ dermObj.storeLocator.lat = position.coords.latitude; dermObj.storeLocator.lng = position.coords.longitude; dermObj.debug("geolocation coords: ",{lat:dermObj.storeLocator.lat,lng:dermObj.storeLocator.lng}) let xhr = new XMLHttpRequest(); xhr.open("GET", `https://facemapping.me/getStoreLocations?lat=${dermObj.storeLocator.lat}&lng=${dermObj.storeLocator.lng}${dermObj.config.storeLocator.extraParameters}`,true); xhr.onload = async()=>{ try{ let response = xhr.responseText; if (typeof response == "string"){ response = JSON.parse(response); } if (dermObj.config.storeLocator.regexFilter != ""){ if (typeof response == "object"){ let storesToDisplay = []; response.forEach((store)=>{ console.log(store.LocationName) if (dermObj.config.storeLocator.regexFilter.test(store.LocationName)){ storesToDisplay.push(store); } }); storesToDisplay.push({"TotalCount" : String(storesToDisplay.length)}); resolve(storesToDisplay) } }else{ resolve(response); } }catch(err){ reject('error in store locator call'); } } xhr.onerror = ()=>{ reject('error in store locator call') } xhr.ontimeout = ()=>{ reject('timeout in store locator call') } xhr.send(); }); }catch(err){ console.log(err); reject(err); } }) } dermObj.twofa = {} dermObj.twofa.promptFinished = false; dermObj.twofa.code = ''; dermObj.twofa.inputEl = dermObj.body.querySelector('#fmc_2fa_input'); dermObj.twofa.popupEl = dermObj.body.querySelector('#fmc_2fa_prompt') dermObj.twofa.buttonEl = dermObj.body.querySelector('#fmc_2fa_submit') dermObj.twofa.prompt = async ()=>{ return new Promise(async (resolve, reject)=>{ dermObj.twofa.promptFinished = false; dermObj.twofa.code = ''; dermObj.twofa.showCodePrompt(); const promptInterval = setInterval(()=>{ if (dermObj.twofa.promptFinished){ clearInterval(promptInterval) resolve(); } },100) }) } dermObj.twofa.showCodePrompt = async () => { dermObj.twofa.popupEl.style.display = 'flex'; } dermObj.twofa.submit = async ()=>{ dermObj.twofa.code = dermObj.twofa.inputEl.value; dermObj.twofa.promptFinished = true; dermObj.twofa.popupEl.style.display = 'none'; } dermObj.twofa.checkInput = async ()=>{ if (dermObj.twofa.inputEl.value.length > 6){ dermObj.twofa.inputEl.value = dermObj.twofa.inputEl.value.substring(0,6); } if (dermObj.twofa.inputEl.value.length == 6){ dermObj.twofa.buttonEl.classList.remove('fmc_inactive'); }else{ dermObj.twofa.buttonEl.classList.add('fmc_inactive'); } } dermObj.swipeHandling = {}; dermObj.swipeHandling.swiperCollection = {}; dermObj.swipeHandling.addSwiper = async (swiperElement,leftSwipeFunction, rightSwipeFunction)=>{ let swiperId = swiperElement.id; if (swiperId == ''){ swiperId = `swiper_${Object.keys(dermObj.swipeHandling.swiperCollection).length + 1}`; swiperElement.id = swiperId; } swiperElement.style.pointerEvents = 'all'; swiperElement.addEventListener('touchstart', dermObj.swipeHandling.touchStart, false) swiperElement.addEventListener('mousedown', dermObj.swipeHandling.mouseStart, false) swiperElement.addEventListener('mouseup', (evt)=>{ swiperElement.style.cursor = 'grab' }, false) dermObj.swipeHandling.swiperCollection[swiperId] = { swiperElement : swiperElement, startX : 0, moveX : 0, swipePending : false, leftSwipeFunction: ()=>{leftSwipeFunction()}, rightSwipeFunction: ()=>{rightSwipeFunction()} }; dermObj.swipeHandling.swiperCollection[swiperId].swiperElement.style.cursor = 'grab' } dermObj.swipeHandling.touchStart = async (evt)=>{ const swiperObj = dermObj.swipeHandling.swiperCollection[evt.target.id]; swiperObj.swiperElement.addEventListener('touchmove', dermObj.swipeHandling.touchMove, false); swiperObj.swipePending = true; swiperObj.startX = evt.touches[0].clientX; } dermObj.swipeHandling.mouseStart = async (evt)=>{ const swiperObj = dermObj.swipeHandling.swiperCollection[evt.target.id]; swiperObj.swiperElement.addEventListener('mousemove', dermObj.swipeHandling.mouseMove, false); swiperObj.swipePending = true; swiperObj.startX = evt.clientX; dermObj.swipeHandling.swiperCollection[evt.target.id].swiperElement.style.cursor = 'grabbing' } dermObj.swipeHandling.touchMove = async (evt)=>{ const swiperObj = dermObj.swipeHandling.swiperCollection[evt.target.id]; swiperObj.moveX = evt.touches[0].clientX - swiperObj.startX; if (swiperObj.moveX < -50 && swiperObj.swipePending){ swiperObj.swipePending = false; swiperObj.swiperElement.removeEventListener('touchmove', dermObj.swipeHandling.touchMove, false); swiperObj.leftSwipeFunction(); } if (swiperObj.moveX > 50 && swiperObj.swipePending){ swiperObj.swipePending = false; swiperObj.swiperElement.removeEventListener('touchmove', dermObj.swipeHandling.touchMove, false); swiperObj.rightSwipeFunction(); } } dermObj.swipeHandling.mouseMove = async (evt)=>{ const swiperObj = dermObj.swipeHandling.swiperCollection[evt.target.id]; swiperObj.moveX = evt.clientX - swiperObj.startX; if (swiperObj.moveX < -50 && swiperObj.swipePending){ swiperObj.swipePending = false; swiperObj.swiperElement.removeEventListener('mousemove', dermObj.swipeHandling.touchMove, false); swiperObj.leftSwipeFunction(); } if (swiperObj.moveX > 50 && swiperObj.swipePending){ swiperObj.swipePending = false; swiperObj.swiperElement.removeEventListener('mousemove', dermObj.swipeHandling.touchMove, false); swiperObj.rightSwipeFunction(); } } dermObj.checkEmailRequirement = async () => { if (!dermObj.config.requestEmailForResults){ return false; } if (window.localStorage.getItem('fmc_emsbflg') == 1){ return false; } if (dermObj.klaviyo.id != ''){ return false; } return true; } dermObj.emailDoubleCheckboxChanged = (evt) => { dermObj.checkEmailInput(); if (evt.target.checked == false) return; if (evt.target.id == 'fmc_email_checkbox_gdpr1' ){ evt.target.parentElement.parentElement.querySelector('#fmc_email_checkbox_gdpr2').checked = false; }else{ evt.target.parentElement.parentElement.querySelector('#fmc_email_checkbox_gdpr1').checked = false; } } dermObj.checkEmailInput = async ()=>{ clearTimeout(dermObj.checkEmailTimeout); dermObj.checkEmailTimeout = setTimeout(()=>{ let sendButton = document.getElementById("fmc_email_submit_button"); if (/^\w+([\.-]?\w+)*(\+[^@]+)?@\w+([\.-]?\w+)*(\.\w{2,})+$/.test(document.getElementById("fmc_email_input").value)){ dermObj.debug("activating send button"); document.getElementById("fmc_email_hint").style.opacity=0; if (dermObj.config.emailDoubleCheckbox == true){ let oneCheckboxChecked = false; sendButton.parentElement.querySelectorAll('#fmc_email_checkbox_gdpr1, #fmc_email_checkbox_gdpr2').forEach((checkbox)=>{ oneCheckboxChecked = oneCheckboxChecked || checkbox.checked; }) if (oneCheckboxChecked){ document.getElementById("fmc_email_submit_button").classList.remove("fmc_inactive"); document.getElementById("fmc_email_submit_button").classList.remove("fmc_disabled"); }else{ console.log("deactivating send button"); document.getElementById("fmc_email_submit_button").classList.add("fmc_inactive"); document.getElementById("fmc_email_submit_button").classList.add("fmc_disabled"); } }else{ document.getElementById("fmc_email_submit_button").classList.remove("fmc_inactive"); document.getElementById("fmc_email_submit_button").classList.remove("fmc_disabled"); } }else{ console.log("deactivating send button"); document.getElementById("fmc_email_submit_button").classList.add("fmc_inactive"); document.getElementById("fmc_email_submit_button").classList.add("fmc_disabled"); document.getElementById("fmc_email_hint").style.opacity=1; } },100) } dermObj.submitEmailForResults = async ()=>{ dermObj.submitEmailToBackend(); dermObj.hideEmailPopup(); if (dermObj.config.requestEmailForResults){ if (dermObj.showEmailRequestPopupFlag){ dermObj.sendGA360("main flow","request email for results - email submited") dermObj.sendGAFlowEvent("request email for results - email submited"); }else{ dermObj.sendGA360("main flow","send results - email submited"); dermObj.sendGAFlowEvent("send results - email submited"); } document.getElementById('fmc_email_input').value = ''; await dermObj.checkCookieConsent(); if (dermObj.config.allowCookies){ window.localStorage.setItem("fmc_emsbflg",1); } if (dermObj.resultsBuilt) return; dermObj.gotoPage('results'); } } dermObj.skipEmailToResults = async () => { dermObj.sendGA360("main flow","skip email to results"); dermObj.sendGAFlowEvent("skip email to results"); dermObj.body.querySelector('#fmc_email_skip_button').style.display = 'none'; dermObj.hideEmailPopup(); dermObj.gotoPage('waiting'); } dermObj.showClosableEmailPopup = () => { dermObj.resultsBuilt = true; const emailPopup = document.getElementById("fmc_email_popup"); const contentCard = emailPopup.querySelector('#fmc_email_content_card'); emailPopup.style.pointerEvents = "all"; emailPopup.style.display = "flex"; dermObj.sendGA360("main flow","save results clicked") dermObj.sendGAFlowEvent("save results clicked"); if (dermObj.body.offsetHeight > window.innerHeight * 1.1){ emailPopup.style.alignItems = "flex-start"; contentCard.style.marginTop = `${Math.round((window.innerHeight - contentCard.offsetHeight))*0.5}px`; }else{ emailPopup.style.alignItems = "center"; contentCard.style.marginTop = "unset"; } } dermObj.showEmailPopup = () => { dermObj.resultsBuilt = false; const emailPopup = document.getElementById("fmc_email_popup"); const contentCard = emailPopup.querySelector('#fmc_email_content_card'); emailPopup.style.display = "flex"; if (dermObj.currentPage.indexOf('fmc_results_') < 0){ dermObj.body.querySelector('#fmc_email_skip_button').style.display = 'block'; }else{ dermObj.body.querySelector('#fmc_email_skip_button').style.display = 'none'; } if (dermObj.body.offsetHeight > window.innerHeight * 1.1){ emailPopup.style.alignItems = "flex-start"; contentCard.style.marginTop = `${Math.round((window.innerHeight - contentCard.offsetHeight))*0.5}px`; }else{ emailPopup.style.alignItems = "center"; contentCard.style.marginTop = "unset"; } } dermObj.clickOutEmailPopup = (evt)=>{ if (evt.target.id == "fmc_email_popup"){ dermObj.hideEmailPopup(); } } dermObj.hideEmailPopup = () => { document.getElementById("fmc_email_popup").style.display = "none"; } //window.dermObj = window.dermObj || {}; dermObj.loadedLibs = dermObj.loadedLibs || []; dermObj.loadExtraLibraries = async () =>{ return new Promise((resolve, reject)=>{ const libsToLoad = ['face-api.js' , 'exif.js' , 'derm_capture.js'] if (!dermObj.loadedLibs.includes('face-api.js')){ const loadStartTimeFaceApi = Date.now(); dermObj.getScript('https://facemapping.me/face-api.js',function(){ dermObj.sendGA4Time('face_api_js' , Date.now() - loadStartTimeFaceApi); dermObj.loadedLibs.push('face-api.js'); }); } if (!dermObj.loadedLibs.includes('exif.js')){ const loadStartTimeExif = Date.now(); dermObj.getScript('https://facemapping.me/vendor/exif.js',function(){ dermObj.sendGA4Time('exif' , Date.now() - loadStartTimeExif); dermObj.loadedLibs.push('exif.js'); }); } if (!dermObj.loadedLibs.includes('derm_capture.js')){ const loadStartTimeDermCapture = Date.now(); dermObj.getScript('https://facemapping.me/derm_capture.js',function(){ dermObj.sendGA4Time('derm_capture' , Date.now() - loadStartTimeDermCapture); dermObj.loadedLibs.push('derm_capture.js'); }); } let extraLibsCheck = setInterval(async ()=>{ let extraLibsLoaded = true; libsToLoad.forEach((libToLoad ) => { extraLibsLoaded = extraLibsLoaded && dermObj.loadedLibs.includes(libToLoad); }) if (extraLibsLoaded){ clearInterval(extraLibsCheck); resolve({status : "success", message:"extra libraries loaded"}); } },50) }) } dermObj.chat = {} dermObj.chat.chatEnabledCheck = async () => { return new Promise(async (resolve,reject)=>{ if (!dermObj.config.chat.enabled || dermObj.config.chat.depId=='') { resolve(false); return; } if (typeof window.zE != 'function'){ resolve(false); return; } const skinCareChatDeps = zE('webWidget:get', 'chat:departments').filter((department) => {return department.id==dermObj.config.chat.depId}) if (skinCareChatDeps.length == 0){ resolve(false); return; }else{ if (skinCareChatDeps[0].status != 'online'){ resolve(false); return; } } if (dermObj.lang_code.split('-')[0] != 'en'){ resolve(false); return; } resolve(true); }) } dermObj.chat.openChat = async ()=>{ const chatEnabled = await dermObj.chat.chatEnabledCheck(); if (!chatEnabled){ return; } if (zE('webWidget:get', 'chat:isChatting')){ return; } window.zE('webWidget','show'); window.$zopim.livechat.window.show(); window.zE('webWidget','open'); zE('webWidget:on', 'chat:connected', function() { dermObj.sendGA360("main flow", `chat opened`); dermObj.sendGAFlowEvent( `chat opened`); console.log('successfully connected to Zendesk Chat!'); }); let currentlyChatting = zE('webWidget:get', 'chat:isChatting'); if (typeof dermObj.backendData != 'undefined'){ if (!currentlyChatting){ zE('webWidget', 'chat:send', dermObj.textData.chat_copy.withResult + ": " + window.location.href); } }else{ if (!currentlyChatting){ zE('webWidget', 'chat:send', dermObj.textData.chat_copy.withoutResult); } } } dermObj.urlParameterQueue = []; dermObj.urlParameterQueuePending = false; dermObj.addUrlParameters = async(fmcSnapshot) => { if (dermObj.isPercMatchMiniPage) return; //dermObj.debug(window.location.search, fmcSnapshot); let urlParamString=""; Object.keys(fmcSnapshot).forEach((key,index)=>{ if ( key == "fh"){ urlParamString += `&fmhid=${fmcSnapshot[key]}`; return; } if ( ['ts','fmc'].includes(key)){ return; } if (urlParamString.indexOf(key) == -1 && window.location.search.indexOf(key) == -1){ urlParamString += `&${key}=${fmcSnapshot[key]}`; } }) if (window.location.search == ""){ urlParamString = "?" + urlParamString.substring(1); } if (window.location.hostname.indexOf('dermalogica.com.au') > -1){ try{ urlParamString += `&fmc_hid=${fmcSnapshot['fh']}`; }catch(err){} } if (dermObj.config.shopButton.showPrices == true){ urlParamString += '&fmc_shpr=1'; }else{ urlParamString += '&fmc_shpr=0'; } window.history.pushState(dermObj.config.pageDict.results, '', `${window.location.href}${urlParamString}`); return; }; dermObj.checkCookieConsent = async () =>{ if (dermObj.config.allowCookies === true) return; if (dermObj.backend == "https://imb-backend-eu.herokuapp.com" || dermObj.backend == "https://eu.facemapping.me"){ if (typeof CookieConsent != 'undefined'){ dermObj.config.allowCookies = CookieConsent.consented; }else if (typeof Cookiebot != 'undefined'){ dermObj.config.allowCookies = Cookiebot.consented; }else if (typeof __axeptioSDK != 'undefined'){ try{ dermObj.config.allowCookies = __axeptioSDK.userPreferencesManager.choices.google_analytics; }catch(err){ dermObj.config.allowCookies = false; } }else{ dermObj.config.allowCookies = false; } }else{ dermObj.config.allowCookies = true; } return; }; dermObj.removeUrlParameters = async(targetPage = 'landing', remainingParameters = []) => { const parametersToRemove = [ 'ed6d4', 'b83d2', 'fmhid', 'ptg_id', 'be', 'r_ac', 'r_ds', 'r_du', 'r_ey', 'r_fr', 'r_hy', 'r_me', 'r_ra', 'r_re', 'r_sk', 'r_sm', 'r_te', 'r_un', 'r_wr', 'cnst', 'imupld', 'qni', 'qfc', 'qfl', 'fmc_shpr','qai_ds','qai_sk','qai_fn','qai_an', 'fmc_mnpg_d', 'fmc_mnpg_sc'] let url = new URL(window.location.href); let qniOnStart = url.searchParams.has('qni') && !url.searchParams.has('fmhid'); parametersToRemove.forEach(param => { if (qniOnStart && param == qni) return; if (remainingParameters.includes(param)) return; url.searchParams.delete(param); }); // Use history.replaceState() to update the URL without adding a new history entry history.replaceState(dermObj.config.pageDict[targetPage], '', url); /* old code if (window.location.search != ''){ const urlParameterArray = window.location.search.replace('?','').split('&'); let remainingParameterString = ''; urlParameterArray.forEach((parameterString)=>{ const paramKey = parameterString.split('=')[0]; if (!parametersToRemove.includes(paramKey)){ if (remainingParameterString == ''){ remainingParameterString = `?${parameterString}`; }else{ remainingParameterString += `&${parameterString}`; } } }) window.history.pushState(dermObj.config.pageDict[targetPage], '', `${window.location.href.split('?')[0]}${remainingParameterString}`); } */ } const mapRevieveToNumber = (revValue) => { if (typeof revValue != "number") return -1; let revNum; if (revValue < 0.3){ revNum = 0; }else if (revValue <= 0.7 ){ revNum = 1; }else{ revNum = 2; } return revNum; } dermObj.getRevSnapShot = async(facemap) => { return new Promise(async(resolve, reject) => { try{ let backendLabel = dermObj.getBackendLabel(); let genNum = dermObj.pageControls.capture.b83d2; let aNum; if (dermObj.pageControls.capture.ed6d4 < 18){ aNum = 0; }else if (dermObj.pageControls.capture.ed6d4 < 25){ aNum = 1; }else if (dermObj.pageControls.capture.ed6d4 < 35){ aNum = 2; }else if (dermObj.pageControls.capture.ed6d4 < 45){ aNum = 3; }else if (dermObj.pageControls.capture.ed6d4 < 55){ aNum = 4; }else if (dermObj.pageControls.capture.ed6d4 < 65){ aNum = 5; }else{ aNum = 6; } const fmcSnapshot = { ed6d4: aNum, b83d2 : genNum, fh : facemap.hashid, be: backendLabel, ts: Date.now(), r_ac : mapRevieveToNumber(facemap.revieve_acne_value), r_ds : mapRevieveToNumber(facemap.revieve_dark_spots_value), r_du : mapRevieveToNumber(facemap.revieve_dull_skin_value), r_ey : mapRevieveToNumber(facemap.revieve_eyes_value), r_fr : mapRevieveToNumber(facemap.revieve_freckles_value), r_hy : mapRevieveToNumber(facemap.revieve_hyperpigmentation_value), r_me : mapRevieveToNumber(facemap.revieve_melasma_value), r_ra : mapRevieveToNumber(facemap.revieve_radiance_value), r_re : mapRevieveToNumber(facemap.revieve_redness_value), r_sk : mapRevieveToNumber(facemap.revieve_skin_shine_value), r_sm : mapRevieveToNumber(facemap.revieve_smoothness_value), r_te : mapRevieveToNumber(facemap.revieve_texture_value), r_un : mapRevieveToNumber(facemap.revieve_uneven_skin_tone_value), r_wr : mapRevieveToNumber(facemap.revieve_wrinkles_value), fmc : 1 } fmcSnapshot.rspg = 'default'; try{ if (facemap.dioxide_data == undefined || facemap.dioxide_data == null){ facemap.dioxide_data = {...dermObj.dioxideData}; } }catch(errInner){} try{ if (dermObj.config.pageDict.results == 'fmc_results_prep_treat_glow' && facemap.dioxide_data.prep_treat_glow != null){ fmcSnapshot.rspg = 'prep_treat_glow'; } if (dermObj.config.pageDict.results == 'fmc_results_brand_campaign' && facemap.dioxide_data.brand_campaign != null){ fmcSnapshot.rspg = 'brand_campaign'; } }catch(errInner){} if (dermObj.config.pageDict.results == 'fmc_results_quiz_no_image'){ fmcSnapshot.rspg = 'quiz_no_image'; if (dml_fmc.config.quizNoImage == true){ fmcSnapshot.qni = 1; } if (dermObj.quizFromConsent == true){ fmcSnapshot.qfc = 1; } } if (dermObj.config.qniChoiceFromLanding == true){ if (dermObj.quizFromLanding == true){ fmcSnapshot.qfl = 1; }else{ fmcSnapshot.qfl = 0; } } if (dermObj.config.pageDict.results == 'fmc_estimated_results'){ fmcSnapshot.rspg = 'estr'; } if (dermObj.backendData.dioxide_data != undefined && dermObj.backendData.dioxide_data != null){ try{ fmcSnapshot.ptg_id = dermObj.backendData.dioxide_data.prep_treat_glow.ptg_id; }catch(err){ console.warn(err) } } resolve(fmcSnapshot); }catch(err){ reject(err); } }) } dermObj.updateLocalStorage = async (fmcSnapshot)=>{ //dermObj.debug('UPDATE LOCAL STORAGE CALL') if (dermObj.config.histFmcObj !== true) return; try{ let rSum = 0; Object.keys(fmcSnapshot).forEach((snapKey) => { if (snapKey.indexOf("r_")>-1){ if (typeof fmcSnapshot[snapKey] == "number"){ rSum += fmcSnapshot[snapKey] } } }); if (rSum > 0){ let localFmcData = window.localStorage.getItem("derm_fmh1"); if (!localFmcData){ localFmcData = []; }else{ localFmcData = JSON.parse(localFmcData); } localFmcData.push(fmcSnapshot) if (localFmcData.length > 10){ localFmcData.shift(); } window.localStorage.setItem("derm_fmh1",JSON.stringify(localFmcData)); } }catch(e){ console.error(e); } // match percentage storage object try{ if (fmcSnapshot.ptg_id != undefined && fmcSnapshot.ptg_id != null && dermObj.config.percMatchFolder != ''){ const date = new Date(fmcSnapshot.ts); const months = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september','october', 'november' , 'december']; const day = date.getDate(); const month = dermObj.textData.perc_match[months[date.getMonth()]]; const fullYeah = date.getFullYear(); const dateString = `${month} ${day}, ${fullYeah}`; let clusterId; if (fmcSnapshot.ptg_id < 59){ clusterId = Math.ceil(fmcSnapshot.ptg_id / 2 - 0.1); }else{ switch(String(fmcSnapshot.ptg_id)){ case '59': case '60': clusterId = 11; break; case '61': case '62': clusterId = 16; break; case '63': case '64': clusterId = 23; break; case '65': case '66': clusterId = 25; break; default: clusterId = -1; console.error(`no cluster found for ptg_id ${fmcSnapshot.ptg_id}`) } } //dermObj.debug('fmc SNAPSHOT: ',fmcSnapshot); if (clusterId > 0){ fetch(`https://facemapping.me/clstr/${dermObj.config.percMatchFolder}/${clusterId}.json`) .then(async (res)=>{ try{ const percMatchDict = await res.json(); dermObj.percMatchData = percMatchDict; //dermObj.debug('percMatchDict: ',percMatchDict);; let fmcLink; if (dermObj.isPercMatchMiniPage){ let urlParams = `?fmhid=${fmcSnapshot.fh}&rspg=prep_treat_glow&be=${dml_fmc.getBackendLabel()}`; if (dermObj.miniPageSettings.fmcPageUrl != undefined && dermObj.miniPageSettings.fmcPageUrl != ''){ fmcLink = dermObj.miniPageSettings.fmcPageUrl + urlParams; }else{ fmcLink = 'https://facemapping.me' + urlParams; } }else{ fmcLink = window.location.href; } dermObj.fmcResultsUrl = fmcLink; let smac = dermObj.smearCd(dermObj.backendData.access_code, fmcSnapshot.fh); window.localStorage.setItem('derm_mp',JSON.stringify({percent_matches : percMatchDict, ttcopy: dermObj.textData.perc_match.based_on_copy.replace('__DATE__',dateString), ctacopy: dermObj.textData.perc_match.view_results_cta, fmc_link: fmcLink, fh: fmcSnapshot.fh, ts: fmcSnapshot.ts, date_string:dateString, smac: smac})); try{ if (dermObj.isPercMatchMiniPage == true && window.dsrp && window.dsrp.showPercMatches != undefined){ window.dsrp.showPercMatches(); } }catch(badgeErr){console.error(badgeErr)} }catch(parseErr){ console.error(parseErr) } }) .catch((err) => { console.error(err); }); } }else{ return; } }catch(err){ console.error(err); } } dermObj.queueUrlParameters = (paramObj)=>{ clearTimeout(dermObj.urlParameterQueueTimeout); dermObj.urlParameterQueue.push(paramObj); dermObj.urlParameterQueueTimeout = setTimeout(()=>{ dermObj.workUrlParameterQueue() },200) } dermObj.workUrlParameterQueue = ()=> { if (dermObj.urlParameterQueuePending == true) return; try{ dermObj.urlParameterQueuePending = true; const curUrl = new URL(window.location.href); const params = new URLSearchParams(curUrl.search); // Add new parameters while (dermObj.urlParameterQueue.length > 0){ let curParamPairs = dermObj.urlParameterQueue.pop(); for (const [parKey, parVal] of Object.entries(curParamPairs)){ params.set(parKey, parVal); } } // Update URL with new parameters const newUrl = `${curUrl.protocol}//${curUrl.host}${curUrl.pathname}?${params.toString()}`; // Push new URL to history history.pushState({}, '', newUrl); }catch(err){ console.log(err) }finally{ dermObj.urlParameterQueuePending = false; } } dml_fmc.smearCd = (num, pattern)=>{ let newStr = ''; let patUsed = [...new Set(pattern.split(''))]; if (patUsed.length < 10){ patUsed.push(...['!','%','&','#','=','?','$','+','€','µ']).slice(0,10-patUsed.length); } try{ String(num).split('').forEach((digit) => { newStr += patUsed[Number(digit)]; }) return newStr; }catch(err){ console.error(err); return num; } } dml_fmc.clearCd = (smearedCd, pattern)=>{ let newStr = ''; let patUsed = [...new Set(pattern.split(''))]; if (patUsed.length < 10){ patUsed.push(...['!','%','&','#','=','?','$','+','€','µ']).slice(0,10-patUsed.length); } try{ String(smearedCd).split('').forEach((char) => { newStr += String(patUsed.indexOf(char)); }) return newStr; }catch(err){ console.error(err); } } dermObj.crm = {}; dermObj.crm.send = (emailType, email) => { const revieveData = {} Object.keys(dermObj.backendData).forEach((key)=>{ if (/revieve_.+_value$/.test(key) ){ revieveData[key] = dermObj.backendData[key]; } }) let payload = { "dioxideData": dermObj.dioxideData, "revieveData": revieveData, "emailType": emailType, "email": email, //"topConcern": topConcern, "countryCode": dermObj.config.crm.country } delete payload.dioxideData.email_html; delete payload.dioxideData.email_subject; let xhr = new XMLHttpRequest(); xhr.open("POST", "https://facemapping.me/handleCrmRequest", true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(JSON.stringify(payload)); //console.log(payload) } dermObj.klaviyo = {} dermObj.klaviyo.id = ''; dermObj.klaviyo.getId = async () => { return new Promise((resolve,reject)=>{ dermObj.klaviyo.id = '' let intervalCounter = 0; let klaviyoInterval = setInterval(()=>{ if (typeof window._learnq == 'undefined'){ if (intervalCounter > 10){ clearInterval(klaviyoInterval); resolve('no klaviyo object'); } }else{ clearInterval(klaviyoInterval); try{ if (_learnq.isIdentified()){ dermObj.klaviyo.id = _learnq.push(['_getIdentifiers']).$exchange_id; resolve(dermObj.klaviyo.id); } }catch(err){ console.log(err); dermObj.klaviyo.id = ''; reject(err); } } intervalCounter++; },500); }) } dermObj.blogs = {} dermObj.blogs.loaded = false; dermObj.blogs.concernBlogs = {}; dermObj.blogs.load = ()=>{ if (dermObj.config.blogs_file == '') { dermObj.blogs.concernBlogs = {}; dermObj.blogs.loaded = true; return; } const xhr = new XMLHttpRequest(); xhr.open('GET', `https://facemapping.me/blogs/${dermObj.config.blogs_file}`, true); xhr.responseType = 'json'; xhr.onload = () => { if (xhr.status == 200){ dermObj.debug('blog request response: ', xhr.response); dermObj.blogs.concernBlogs = xhr.response; }else{ dermObj.blogs.concernBlogs = {}; console.error(`Could not load blogfile ${dermObj.config.blogs_file} - Status: ${xhr.status} - ${xhr.statusText}`); } dermObj.blogs.loaded = true; }; xhr.send(); } dermObj.treatments = {} dermObj.treatments.bookNowDict = {} dermObj.treatments.updateBanners = ()=>{ try{ const skinServ = {...dermObj.dioxideData.skin_service} const skinServContainers = dermObj.body.querySelectorAll('.fmc_results_treatment_section .fmc_treatment_card'); skinServContainers.forEach((skinServContainer) => { skinServContainer.classList.remove( 'fmc_pro_bright', 'fmc_pro_calm', 'fmc_pro_clear', 'fmc_pro_eye_flash', 'fmc_pro_firm_neck', 'fmc_pro_microneedling', 'fmc_pro_nanoneedling', 'fmc_pro_power_peel', 'fmc_pro_skin' ) skinServContainer.classList.add(`fmc_${skinServ.name.replace(/\s/g, '_')}`); skinServContainer.querySelector('.fmc_treatment_name_type').innerHTML = skinServ.name.replace('pro ', ''); skinServContainer.querySelector('.fmc_treatment_description').innerHTML = skinServ.description; skinServContainer.querySelector('button#fmc_treatment_cta').onclick = () => { dermObj.sendGA360("main flow",`treatment cta clicked - ${skinServ.name}`); dermObj.sendGAFlowEvent(`treatment cta clicked - ${skinServ.name}`); window.open(skinServ.url,'_blank'); } if (Object.keys(dermObj.treatments.bookNowDict).includes(skinServ.name)){ const treatKey = skinServ.name; skinServContainer.querySelector('button#fmc_treatment_cta').style.display = "none"; skinServContainer.querySelector('button#fmc_treatment_cta_book_now').style.display = "flex"; skinServContainer.querySelector('button#fmc_treatment_cta_book_now').onclick = () => { dermObj.sendGA360("main flow",`treatment cta book now clicked - ${skinServ.name}`); dermObj.sendGAFlowEvent(`treatment cta book now clicked - ${skinServ.name}`); window.open(dermObj.treatments.bookNowDict[treatKey],'_blank'); } } dermObj.body.querySelectorAll('.fmc_results_treatment_section').forEach((treatmentSection)=> treatmentSection.style.display = 'flex'); }) dermObj.sendGA360("main flow",`treatment displayed - ${skinServ.name}`); dermObj.sendGAFlowEvent(`treatment displayed - ${skinServ.name}`); }catch(err){ try{ dermObj.body.querySelectorAll('.fmc_results_treatment_section').forEach((treatmentSection)=> treatmentSection.style.display = 'none'); }catch(err2){ console.err(err2) } console.warn(err) } } dermObj.customizationCheck = (domainToCheck, microPagePath) => { const regex = new RegExp(`${domainToCheck}(:|$)`,'g') if (dermObj.config.forcedPage != ''){ try{ let forcedHostName = dermObj.config.forcedPage.replace('https://','').replace('http://','').split('/')[0] if (regex.test(forcedHostName) || dermObj.config.forcedPage.indexOf(`/${microPagePath}`) > -1){ return true; }else{ return false; } }catch(err){ console.error(err); return false; } } if (regex.test(window.location.hostname)){ return true; } if (window.location.pathname.indexOf(`/${microPagePath}`) > -1){ return true; } return false; } dermObj.customization = {} // GENERAL DERMALOGICA AND FACEMAPPING.ME RULES if ( /dermalogica\./g.test(window.location.hostname) || /dermalogica./g.test(dermObj.config.forcedPage) || ( /facemapping.me/g.test(window.location.hostname) && window.location.pathname == '/' ) || /facemapping.me[^\/]?/g.test(dermObj.config.forcedPage)){ if (dermObj.config.forcedPage == '' || /dermalogica./g.test(dermObj.config.forcedPage) || /facemapping.me[^\/]?/g.test(dermObj.config.forcedPage)){ dermObj.debug("CUSTOMIZE FOR dermalogica pages and facemapping.me without 3rd parties"); dermObj.config.requestEmailForResults = true; dermObj.config.histFmcObj = true; dermObj.config.storeLocator.showStores = true; } } //for facemapping.me and localhost only if (/facemapping.me/g.test(window.location.hostname) || /facemapping.me/g.test(dermObj.config.forcedPage) || /localhost/g.test(window.location.hostname)){ try{ document.getElementById("fmc_manageCookiebotLink").style.display="block"; }catch(err){ console.warn(err); } if ( (/facemapping.me/g.test(window.location.hostname) || /facemapping.me/g.test(dermObj.config.forcedPage)) && window.location.pathname == '/'){ dermObj.config.useTreatmentBanners = true; } } dermObj.applyCustomizations = async ()=>{ if (dermObj.isPercMatchMiniPage){ dermObj.config.pageDict.landing = 'fmc_loading_page_default'; dermObj.config.pageDict.results = 'fmc_results_page_perc_match_coll'; dermObj.config.quizAfterImage = false; dermObj.config.showQniConsentButton = false; dermObj.config.requestEmailForResults = false; dermObj.config.allowCookies = true; dermObj.config.percMatchFolder = dermObj.miniPageSettings.percMatchFolder; dermObj.config.useShopify = true; if (dermObj.miniPageSettings.forcedCountry != undefined){ dermObj.config.forcedCountry = dermObj.miniPageSettings.forcedCountry; } } if (dermObj.config.shopButton.showPrices){ dermObj.body.classList.add('dml_show_prices'); } if (dermObj.config.hideEmailButtons){ dermObj.config.requestEmailForResults = false; dermObj.body.classList.add('dml_no_email_buttons') } if (dermObj.config.shopButton.hide){ dermObj.body.classList.add('dml_hide_store_buttons') } if (dermObj.config.shopButton.textOverride != ''){ dermObj.afterTextRendering = ()=>{ document.querySelectorAll(`[data-widget-text-term=shop]`).forEach((htmlEl)=>{ htmlEl.innerHTML = dermObj.config.shopButton.textOverride; }) } } if (dermObj.config.showQniConsentButton){ if (window.location.search.indexOf('fmhid=') < 0){ dermObj.body.querySelector('#fmc_consent_quiz_button').style.display = 'block'; } } if (dermObj.config.showSaveEmailMobile){ document.querySelector('#fmc_results_page_default #fmc_save_email_results.fmc_email_button_tag').classList.add('fmc_display_mobile'); document.querySelector('#fmc_results_page_default .fmc_branding_logo_white').classList.add('fmc_hide_mobile'); } if (dermObj.config.ga4dst !== undefined && dermObj.config.ga4dst !== null ){ try{ gtag('config',dermObj.config.ga4dst); }catch(err){console.error()}; } if (dermObj.config.brandingLogoUrl != ''){ dermObj.body.querySelectorAll('.fmc_branding_logo_white').forEach((brandingLogoDiv)=>{ brandingLogoDiv.style.backgroundImage = `url('${dermObj.config.brandingLogoUrl}')`; if (dermObj.config.brandingLogoScale != 1){ brandingLogoDiv.style.transform = `scale(${dermObj.config.brandingLogoScale})`; } }) dermObj.body.querySelectorAll('.fmc_branding_logo_grey').forEach((brandingLogoDiv)=>{ brandingLogoDiv.style.backgroundImage = `url('${dermObj.config.brandingLogoUrlGrey}')`; if (dermObj.config.brandingLogoScale != 1){ brandingLogoDiv.style.transform = `scale(${dermObj.config.brandingLogoScale})`; } }) } if (window.location.search.indexOf('qni=1') < 0 && window.location.search.indexOf('rspg') > -1){ dermObj.config.quizNoImage = false; } if (dermObj.config.qniChoiceFromLanding ){ dermObj.body.querySelectorAll('.fmc_landing_default_flow').forEach((defEl) => {defEl.style.display='none'}); dermObj.body.querySelectorAll('.fmc_landing_ai_qni_flow').forEach((aiQniEl) => {aiQniEl.style.display='flex'}); } if (dermObj.config.forcedLang != undefined && dermObj.config.forcedLang != ''){ dermObj.lang_code = dermObj.config.forcedLang; } try{ dermObj.referrer = dermObj.config.forcedPage != '' ? dermObj.config.forcedPage : dermObj.referrer; }catch(err){console.log(err)} await dermObj.checkCookieConsent() if (dermObj.config.allowCookies){ if (dermObj.isPercMatchMiniPage != true){ let qaiFlagStItem = window.localStorage.getItem("fmc_qai"); if (window.location.search.indexOf('force_qai=1') > -1){ qaiFlagStItem = '1_'+Date.now(); }else{ qaiFlagStItem = '0_'+Date.now(); } if (qaiFlagStItem != null && qaiFlagStItem != undefined){ try{ let qaiFlagVal = qaiFlagStItem.split('_')[0]; let qaiFlagExp = qaiFlagStItem.split('_')[1]; if (qaiFlagExp - Date.now() > 0 ){ if (qaiFlagVal == 1){ dermObj.config.quizAfterImage = true; }else if (qaiFlagVal == 0){ dermObj.config.quizAfterImage = false; } } }catch(qaierr){console.log(qaierr)}; } let qaiFlagNewExp = Date.now() + 2 * 3600 * 1000; // 2 hours valid let qaiFlagNewVal = dermObj.config.quizAfterImage == true ? 1 : 0; window.localStorage.setItem("fmc_qai",`${qaiFlagNewVal}_${qaiFlagNewExp}`); } if ("TRUE"=='TRUE' && dermObj.config.useSentry === true){ dermObj.sentry.loadScript(); } } } // single pages if (dermObj.customizationCheck('arcstore.co.za')){ // update logo at landing page dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/arcstore.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/arcstore_grey.png"; dermObj.config.brandingLogoScale = 2; dermObj.config.hideEmailButtons = true; } if (dermObj.customizationCheck('beautyboxpangbourne.co.uk') || dermObj.customizationCheck('www-beautyboxpangbourne-co-uk.filesusr.com')){ dermObj.config.forcedPage = "https://www-beautyboxpangbourne-co-uk.filesusr.com/"; dermObj.config.hideEmailButtons = true; } if (dermObj.customizationCheck('beautybrands.com', 'beautybrands')){ // update logo at landing page dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/beautybrands.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/beautybrands_grey.png"; dermObj.config.brandingLogoScale = 5; dermObj.config.hideEmailButtons = true; } if (dermObj.customizationCheck('beautyfeatures.ie')){ // change "shop" button text dermObj.config.shopButton.textOverride = "shop now"; } // // uses default settings // // uses default settings if (dermObj.customizationCheck('bluemercury.com','bluemercury')){ dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/derm_bluemercury_logo.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/derm_bluemercury_logo_grey.png"; dermObj.config.brandingLogoScale = 3; } // // uses default settings // uses default settings // // NOT EMBED ANYMORE? https://www.cosmania.nl/nl/blog/artikel/doe-de-dermalogica-face-mapping/ if (dermObj.customizationCheck('dermalogica.ae')){ dermObj.config.sendAlsoToNewEmailEndpoint = true; try{ dermObj.config.klavyioId = "Vm3bBM"; dermObj.config.klavyioListId = "U5gh2B"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.ca')){ dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.qniChoiceFromLanding = true; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; try{ dermObj.config.klavyioId = "WQ7Ua9"; dermObj.config.klavyioListId = "WbV7jf"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.co.nz')){ dermObj.config.shopButton.showPrices = true; dermObj.config.chat.enabled = true; dermObj.config.chat.key = 'derm_nz'; dermObj.config.sendAlsoToNewEmailEndpoint = true; dermObj.config.qniChoiceFromLanding = true; try{ dermObj.config.klavyioId = "PcLf2F"; dermObj.config.klavyioListId = "MyH4aY"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.co.uk')){ dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.emailDoubleCheckbox = true; dermObj.config.percMatchFolder = 'GB'; try{ dermObj.config.klavyioId = "WcNx8p"; dermObj.config.klavyioListId = "Xkj7Rc"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } dermObj.config.chat.enabled = false; dermObj.config.chat.key = 'gb_and_ie'; dermObj.config.chat.depId = ''; dermObj.config.qniChoiceFromLanding = true; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; dermObj.config.pageDict.onboarding = 'fmc_loading_page_default'; dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; //badges - to enable we also need to change the landing page to the default one /* const fastCompanyBadgeVariations = ['fastcompany-variation-round-dark-bg','fastcompany-variation-round-white-bg', 'fastcompany-variation-stamp-dark' ,'fastcompany-variation-banner-dark']; const urlParamShort = ['fc-var-l-rd','fc-var-l-rw', 'fc-var-l-sd' ,'fc-var-l-bd']; const fastCompanyBadgeIndex = Math.min(Math.floor(Math.random()*fastCompanyBadgeVariations.length + 1),fastCompanyBadgeVariations.length ); if (fastCompanyBadgeIndex <= fastCompanyBadgeVariations.length - 1){ dermObj.config.badges.fmc_landing_page_default = `badge-for-landing-default ${fastCompanyBadgeVariations[fastCompanyBadgeIndex]}`; dermObj.queueUrlParameters({'bdge_var':urlParamShort[fastCompanyBadgeIndex]}); }else{ dermObj.queueUrlParameters({'bdge_var':'blank'}) } */ /* const abcTestResultsPageArray = ['fmc_results_page_default','fmc_results_prep_treat_glow'] const resultsPageIndex = Math.max(0,Math.min(1,Math.floor(Math.random()*2))); dermObj.config.pageDict.results = abcTestResultsPageArray[resultsPageIndex]; */ //dermObj.pageControls.brand_campaign.proBrightLink = 'https://www.dermalogica.co.uk/pages/our-dermalogica-stores-uk'; dermObj.config.blogs_file = 'blogs_GB.json'; dml_fmc.customization.updateShopifyCart = (cart) => { const itemBubble = document.getElementById('cart-icon-bubble'); if (!itemBubble.querySelector('div.cart-count-bubble')){ const bubbleBadge = document.createElement('div'); bubbleBadge.classList.add('cart-count-bubble'); const hiddenItemString = cart.item_count > 1 ? `${cart.item_count} items` : '1 item'; bubbleBadge.innerHTML = `${hiddenItemString}`; itemBubble.appendChild(bubbleBadge); }else{ itemBubble.querySelector('div.cart-count-bubble span[aria-hidden="true"]').innerHTML = cart.item_count; } } dermObj.config.gtmDLArray = "dataLayer"; dermObj.config.ga4dst = "G-DJ1Q2Q6JW0"; } if (dermObj.customizationCheck('dermalogica.co.za')){ dermObj.config.crm.enabled = true; dermObj.config.crm.country = 'ZA'; } if (dermObj.customizationCheck('dermalogica.com.au')){ dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.showQniConsentButton = true; dermObj.config.qniChoiceFromLanding = true; try{ dermObj.config.klavyioId = "VhhRMj"; dermObj.config.klavyioListId = "WdX2Xm"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.com')){ dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.chat.enabled = true; dermObj.config.chat.depId = 2148428841; dermObj.config.chat.key = 'en'; dermObj.config.useTreatmentBanners = true; dermObj.config.showQniConsentButton = true; if (window.location.search.indexOf('force_qai=') == -1){ dermObj.config.quizAfterImage = Math.random() < 0.5; } dermObj.config.qniChoiceFromLanding = true; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; dermObj.config.pageDict.onboarding = 'fmc_loading_page_default'; try{ dermObj.config.klavyioId = "JvUywn"; dermObj.config.klavyioListId = "VfNfk3"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } /* const abTestResultsPageArray = ['fmc_results_page_default','fmc_results_prep_treat_glow'] const resultsPageIndex = Math.max(0,Math.min(1,Math.floor(Math.random()*2))); try{ dermObj.config.pageDict.results = abTestResultsPageArray[resultsPageIndex]; }catch(err){ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; } */ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; // ptg - legacy AB test for organic traffic 50% split try{ if (document.referrer.indexOf('google.com') > -1 ){ if (window.location.search.indexOf('rspg=') < 0 ){ if (Math.random() < 0.5){ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; }else{ dermObj.config.pageDict.results = 'fmc_results_page_default'; } } } }catch(err){ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; } dermObj.treatments.bookNowDict = { "pro bright" : "https://dermalogica.com/pages/book-a-service?code=PBD50", "luminfusion" : "https://www.dermalogica.com/pages/book-a-service?code=LUMD50" } dermObj.config.blogs_file = 'blogs_US.json'; dermObj.contactOpenHours = "Mon - Fri, 7am - 8pm PT | Sat - Sun, 10am - 2pm PT
(excludes public holidays)"; dermObj.config.gtmDLArray = "dataLayer"; dermObj.config.ga4dst = "G-7BHWEMK9Q3"; dermObj.config.fmcCheckoutCookie = true; dermObj.config.crm.enabled = true; dermObj.config.crm.country = 'US'; dermObj.config.percMatchFolder = 'US'; dermObj.config.allowCookies = true; } if (dermObj.customizationCheck('dermalogica.de')){ dermObj.config.requestEmailForResults = false; try{ dermObj.body.querySelectorAll('#fmc_save_email_results').forEach((emBut)=>emBut.style.display= 'flex'); }catch(err){console.log(err)} dermObj.config.forcedLanguage = 'de'; dermObj.config.showQniConsentButton = true; // button text to "more info" dermObj.config.shopButton.textOverride = "Mehr Infos"; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; dermObj.config.pageDict.onboarding = 'fmc_loading_page_default'; if (Math.random() < 0.5){ dermObj.config.quizNoImage = true; }else{ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow' } try{ dermObj.config.klavyioId = "SPekEq"; dermObj.config.klavyioListId = "RcLs2N"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } //const abTestResultsPageArray = ['fmc_results_page_default','fmc_results_prep_treat_glow'] //const resultsPageIndex = Math.max(0,Math.min(1,Math.floor(Math.random()*2))); //full width on desktop try{ const pageWidthEl = dermObj.widget_wrapper.parentElement.parentElement; pageWidthEl.style.maxWidth = "100%"; pageWidthEl.style.paddingLeft = 0; pageWidthEl.style.paddingRight = 0; pageWidthEl.style.marginLeft = 0; pageWidthEl.style.marginRight = 0; }catch(err){ console.log(err) } // show coupon on results page - disabled, was not working in old version if (window.location.search.indexOf("dekp=") == 1 && false ){ let couponCont = document.getElementById("fmc_coupon_container"); let couponText = document.getElementById("fmc_coupon_text"); couponText.innerHTML = "20% Face Mapping Rabatt mit Code FM20 auf dermalogica.de" couponCont.style.display = "block"; } // DISABLED - LINK IS NOT WORKING ANYMORE if (window.location.search.indexOf("dekp=1") > -1 && false){ window.fmcCustomizations.afterBuildResultsPageCall = ()=>{ if (window.facemap.germany_samples){ try{ let bannerCont = document.getElementById("fmc_extra_banner_container"); bannerCont.style.display = "block"; bannerCont.style.cursor = "pointer"; bannerCont.style.backgroundPosition = "center"; bannerCont.style.backgroundRepeat = "no-repeat"; bannerCont.style.backgroundImage = "url('https://facemapping.me/img/fmc_germany_samples_banner.jpg')"; bannerCont.style.boxShadow = "0px 0px 30px rgba(55,143,219,0.2)"; bannerCont.style.marginBottom = "50px"; bannerCont.style.backgroundColor = "white"; let textPadTop; if (document.getElementById("fmcBody").offsetWidth > 768){ bannerCont.style.height = "250px"; bannerCont.style.backgroundSize = "contain"; textPadTop = "80px"; }else{ bannerCont.style.height = "300px"; bannerCont.style.backgroundSize = "cover"; textPadTop = "100px"; } bannerCont.innerHTML = "

Jetzt passende Gratis-Proben aussuchen

"; bannerCont.innerHTML += "

Kostenlos bestellen

"; let sampleLink = "https://fmderma.rheinmail.de/?" window.facemap.germany_samples.forEach((prodId,index)=>{ if (index > 0){ sampleLink += "&"; } sampleLink += "products[]="+prodId; }) bannerCont.onclick = ()=>{ window.open(sampleLink,'_blank'); } }catch(err){ console.error("error in germany's sample kit preparation - ",err); document.getElementById("fmc_extra_banner_container").style.display = "none"; } } } } } dermObj.afterGDPRCall = ()=>{ if (dermObj.countryCode == "DE" && (/facemapping.me($|:)/g.test(window.location.hostname) || /facemappingconsumer-staging.herokuapp.com($|:)/g.test(window.location.hostname) || /localhost($|:)/g.test(window.location.hostname) ) ){ let pathElements = window.location.pathname.split("/"); try{ if ((pathElements[1] == "" || pathElements[1] == "results" ) && dermObj.config.forcedPage == ""){ dermObj.config.chat.enabled = true; dermObj.config.requestEmailForResults = false; // button text to "more info" if (dermObj.lang_code == "de"){ dermObj.config.shopButton.textOverride = "Mehr Infos"; } dermObj.applyCustomizations(); //console.log("APPLY GERMAN CUSTOMIZATIONS") } }catch(err){ console.error("Error in getting facemapping.me path elements - ",err) } } } // TODO - needs more work - coupons and DE facemapping.me requirements if (dermObj.customizationCheck('dermalogica.dk')){ dermObj.config.forcedCountry = "DK"; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; } if (dermObj.customizationCheck('dermalogica.ee')){ // show a different background image on landing page try{ dermObj.body.querySelector("#fmc_landing_page_default").classList.add("fmc-background-estonia"); }catch(err){} } if (dermObj.customizationCheck('dermalogica.es')){ dermObj.config.forcedCountry = "ES"; dermObj.config.shopButton.showPrices = true; } if (dermObj.customizationCheck('dermalogica.fi')){ dermObj.config.sendAlsoToNewEmailEndpoint = true; try{ dermObj.config.klavyioId = "VjVjYj"; dermObj.config.klavyioListId = "Tpnpdf"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.fr')){ dermObj.config.shopButton.showPrices = true; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; //dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; try{ dermObj.config.klavyioId = "VHKS5B"; dermObj.config.klavyioListId = "XR4ab5"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } try{ let resultsFlow = Math.floor(Math.random()*3); if (resultsFlow == 0){ dermObj.config.quizNoImage = true; }else if (resultsFlow == 1){ dermObj.config.pageDict.results = 'fmc_results_page_default'; }else{ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; } }catch(err){ console.log(err) dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; } try{ document.querySelector('[data-widget-regimen-index="5"]').style.display = "none"; }catch(err){console.error(err)} } if (dermObj.customizationCheck('dermalogica.ie')){ dermObj.config.shopButton.showPrices = true; dermObj.config.chat.enabled = true; dermObj.config.chat.key = 'gb_and_ie'; dermObj.config.qniChoiceFromLanding = true; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; dermObj.config.pageDict.onboarding = 'fmc_loading_page_default'; try{ dermObj.config.klavyioId = "Vm3bBM"; dermObj.config.klavyioListId = "TtCxDX"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.it')){ dermObj.config.forcedCountry = "IT"; dermObj.config.chat.enabled = true; dermObj.config.chat.key = 'it'; dermObj.config.shopButton.showPrices = true; try{ dermObj.config.klavyioId = "Xie7pk"; dermObj.config.klavyioListId = "WTub4C"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.jp')){ dermObj.config.forcedLanguage = 'ja-np'; dermObj.config.langForBackends = 'ja'; try{ dermObj.config.klavyioId = "SfJVhQ"; dermObj.config.klavyioListId = "TKnxu9"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.nl')){ dermObj.config.requestEmailForResults = false; dermObj.config.showSaveEmailMobile = true; } if (dermObj.customizationCheck('dermalogica-ru.ru')){ dermObj.config.requestEmailForResults = true; dermObj.config.histFmcObj = true; dermObj.config.storeLocator.showStores = true; } if (dermObj.customizationCheck('dermalogica.ro') || dermObj.customizationCheck('demo.voitin.com')){ dermObj.config.forcedLanguage='ro'; } if (dermObj.customizationCheck('dermalogica.se')){ //dermObj.config.crm.enabled = true; //dermObj.config.crm.country = 'SE'; try{ dermObj.config.klavyioId = "YmZuN7"; dermObj.config.klavyioListId = "TBw7rn"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica-us-staging.myshopify.com')){ dermObj.config.requestEmailForResults = true; dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.chat.enabled = true; dermObj.config.storeLocator.showStores = true; dermObj.config.histFmcObj = true; dermObj.config.useDioxideStaging = true; dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; dermObj.config.useTreatmentBanners = true; dermObj.config.usePrepTreatGlowTreatmentBanners = false; dermObj.config.skipMasks = true; //dermObj.body.querySelector('#fmc_treatment_cta').style.display = "none"; //dermObj.body.querySelector('#fmc_treatment_cta_demo').style.display = "flex"; } if (dermObj.customizationCheck('dermalogicaindia.com') || dermObj.customizationCheck('dermalogica.in')){ dermObj.config.forcedPage = "https://dermalogica.in" dermObj.config.requestEmailForResults = true; dermObj.config.histFmcObj = true; dermObj.config.storeLocator.showStores = true; // only display the top 3 concerns dermObj.config.maxConcerns = 3; // show a different background image on landing page dermObj.body.querySelector("#fmc_landing_page_default").classList.add("fmc-background-ind"); } if (dermObj.customizationCheck('douglas.es')){ dermObj.config.hideEmailButtons = true; } if (dermObj.customizationCheck('dpharmacy.ie')){ try{ document.getElementById("fmc_submit_form").style.marginBottom = "30px"; document.querySelectorAll(".fmc-main-button").forEach((buttonEl)=>{ buttonEl.style.cssText = "color: white !important; font-size: 1em !important; text-transform: uppercase !important; border-radius: 1px !important; font-weight: 400 !important; padding: 10px 40px; !important" }); let fontBlock = " font-family: 'Helvetica Neue',Helvetica, Arial !important;" let fontBlockCaslon = " font-family: 'BigCaslon !important;" document.getElementById("fmc_app_title").style.cssText = "color: white !important; font-size: 5em !important;" + fontBlockCaslon; document.getElementById("fmc_app_tagline").style.cssText = "color: white !important; font-weight: 400 !important; font-size: 1.1em !important; text-transform:uppercase !important;" + fontBlock; let legalContainer = document.querySelector(".fmc-legaltext-container"); legalContainer.querySelector("#legal_text_top").style.cssText = "font-weight: 300 !important; line-height: 1.2 !important; color: #ddd !important;" + fontBlock; legalContainer.querySelector("#legal_text_consent").style.cssText = "font-weight: 300 !important; line-height: 1.2 !important; color: #ddd !important;" + fontBlock; legalContainer.querySelector("#legal_text_bottom").style.cssText = "font-size: 10px !important; color: #ccc !important;" + fontBlock; legalContainer.querySelector("#fmc_consent_accept_button").style.cssText = "font-size: 12px !important; color: white !important; text-transform: uppercase !important; font-weight: 500 !important; letter-spacing: 0.2em !important; padding: 0 !important; margin: 0 !important;" + fontBlock; document.querySelectorAll(".fmc_onboarding_slide_title").forEach((slideTitle)=>{ slideTitle.style.cssText = 'color: #5B6670 !important; font-family: "BigCaslon" !important; font-size: 32px !important; margin: 0 !important; line-height: 1 !important;'; }); document.querySelectorAll("#fmcBody #fmc_screen3 p, #fmcBody #fmc_screen3 span,#fmcBody #fmc_screen4 p, #fmcBody #fmc_screen4 span").forEach((elem)=>{ elem.style.cssText = "color: white !important;"+fontBlock; }) document.getElementById("fmc_frozen_glass_text_bar").style.display = "none"; fmcCustomizations.afterBuildResultsPageCall = ()=>{ document.querySelectorAll(".fmc-ind-word").forEach((elem)=>{ elem.style.cssText = "font-weight: 300 !important; color: white !important;"+fontBlock; }) document.querySelectorAll(".fmc-product-image img").forEach((elem)=>{ elem.style.cssText = "height: 100% !important;" }) document.querySelectorAll(".fmc-product-name").forEach((elem)=>{ elem.style.cssText = "font-weight: bold !important; font-size: 1.2em !important; color: #999 !important;"+fontBlock; }) document.querySelectorAll(".fmc-product-subtitle").forEach((elem)=>{ elem.style.cssText = "font-weight: 300 !important; font-size: 1em !important; color: #999 !important;"+fontBlock; }) document.querySelectorAll(".fmc_price_separator").forEach((elem)=>{ elem.style.cssText = "font-weight: 500 !important; font-size: 1.3em !important; color: white !important; text-transform: uppercase !important;"+fontBlock; }) if (document.getElementById("fmcBody").classList.contains("fmc_768")){ document.querySelectorAll(".fmc-product-price").forEach((elem)=>{ elem.style.cssText = "font-weight: 500 !important; font-size: 11px !important; color: white !important; text-transform: uppercase !important;"+fontBlock; }) }else{ document.querySelectorAll(".fmc-product-price").forEach((elem)=>{ elem.style.cssText = "font-weight: bold !important; font-size: 1.3em !important; color: white !important; text-transform: uppercase !important;"+fontBlock; }) } document.querySelectorAll(".fmc_mobile_results_indicator_bar .fmc_mobile_indicator_word").forEach((elem)=>{ elem.style.cssText = "font-weight: 300 !important; font-size: 11px !important; color: white !important; text-transform: uppercase !important; "+fontBlock; }) document.querySelectorAll(".fmc_mobile_results_indicator_background .fmc_mobile_indicator_word").forEach((elem)=>{ elem.style.cssText = "font-weight: 300 !important; font-size: 11px !important; color: grey !important; text-transform: uppercase !important; "+fontBlock; }) document.querySelectorAll(".fmc_carousel_mobile_results_text").forEach((elem)=>{ elem.style.cssText ="font-weight: 300 !important;"+fontBlock; }) document.querySelectorAll(".fmc_prod_cont_indicator ").forEach((elem)=>{ elem.style.cssText ="font-size: 10px !important; color: white !important; text-transform: lowercase !important; font-weight: 300 !important;"+fontBlock; }) document.querySelectorAll(".fmc_prod_cont_title ").forEach((elem)=>{ elem.style.cssText ="font-size: 10px !important; color: #999 !important; font-weight: bold !important;"+fontBlock; }) document.querySelectorAll(".fmc_prod_cont_tagline ").forEach((elem)=>{ elem.style.cssText ="font-size: 9px !important; color: #999 !important; font-weight: 300 !important;"+fontBlock; }) } }catch(err){ console.error("Error in overwriting faulty host css - ",err) } } // WILL NOT WORK - NEEDS TO BE DONE ONCE FMC IS RELAUNCHED if (dermObj.customizationCheck('fashionplace.com','fashionplace')){ dermObj.config.shopButton.hide = true; dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/fashionplace.svg"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/fashionplace_grey.svg"; dermObj.config.brandingLogoScale = 2; const couponSection = dermObj.body.querySelector('#fmc_results_page_default .fmc_results_coupon_section'); couponSection.innerHTML = '

' couponSection.style.display = "flex"; const redoButton = document.createElement('button'); redoButton.id="fmc_fashionplace_redo"; redoButton.classList.add('fmc_centered_text_box','fmc_fashonplace_redo_button'); redoButton.setAttribute('data-widget-text-term','fashionplace_restart_analysis'); redoButton.setAttribute('onclick',"dml_fmc.pageControls.results_default.restart()"); dermObj.body.querySelector('#fmc_results_page_default .fmc_results_head_section').appendChild(redoButton); dermObj.afterLanguageCall = ()=>{ document.getElementById('fmc_onboarding_slide_3_start').innerHTML = dermObj.textData['fashionplace customization'].fashionplace_onboarding_cta; dermObj.config.emailSubjectOverride = dermObj.textData["fashionplace customization"].fashionplace_email_subject; } } if (dermObj.customizationCheck('fragrancedirect.co.uk')){ // change "shop" button text dermObj.config.shopButton.textOverride = "shop now"; } // // uses default settings // // uses default settings // // TODO - needs more work if (dermObj.customizationCheck('pinalli.it')){ dermObj.config.hideEmailButtons = true; } if (dermObj.customizationCheck('planetbeauty.com','planetbeauty')){ // update logo at landing page dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/planet_beauty.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/planet_beauty_grey.png"; dermObj.config.brandingLogoScale = 3; dermObj.config.hideEmailButtons = true; } // PRODUCT LINKS SEEM TO BE ALL WRONG !!! if (dermObj.customizationCheck('pure-beauty.co.uk')){ // change "shop" button text dermObj.config.shopButton.textOverride = "shop now"; } if (dermObj.customizationCheck('saloncentric.com','saloncentric')){ // update logo at landing page dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/dermalogica_saloncentric_logos.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/dermalogica_saloncentric_logos_grey.png"; dermObj.config.brandingLogoScale = 3; // extra parameters on the store locator endpoint dermObj.config.storeLocator.extraParameters = "&maxStores=200&maxRadius=30"; dermObj.config.storeLocator.regexFilter = new RegExp(/(S|s)aloncentric/, 'g'); dermObj.config.storeLocator.showStores = true; } // cannot find any stores - but customized regex had been added if (dermObj.customizationCheck('salonservicespro.com','salonservices')){ //fmcForcedPage= "https://www.salonservicespro.com"; dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/logo_dermalogica_salonservices_white.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/logo_dermalogica_salonservices_grey.png"; dermObj.config.brandingLogoScale = 3; } if (dermObj.customizationCheck('sephora.com','sephora')){ dermObj.debug('CUSTOMIZATION FOR SEPHORA') if (/sephora.com\/ca\//g.test(window.location.hostname) || window.location.pathname.indexOf("sephoracanada") > -1 || /sephora\/ca\//g.test(dermObj.config.forcedPage)){ dermObj.config.forcedPage= "sephora/ca/en/"; }else{ dermObj.config.forcedPage= "https://www.sephora.com"; } // remove title and subtitle from "Therapist Section (store locator)" try{ dermObj.body.querySelectorAll('[data-widget-text-term=fmc_skin_therapist_tagline_1],[data-widget-text-term=fmc_skin_therapist_tagline_2]').forEach((htmlEl)=>{ htmlEl.style.display = "none"; }) }catch(err){ } // update logo at landing page dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/dermalogica_sephora_logos.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/dermalogica_sephora_logos_grey.png"; dermObj.config.brandingLogoScale = 3; dermObj.config.storeLocator.extraParameters = "&maxStores=200&maxRadius=30"; dermObj.config.storeLocator.regexFilter = new RegExp(/(S|s)ephora/, 'g'); dermObj.config.storeLocator.showStores = true; } // Customization for Canada might need to be revieweed - but was already not working for the old FMC anymore if (dermObj.customizationCheck('sephora.com.br', 'Sephora_BR')){ dermObj.debug('CUSTOMIZATION FOR SEPHORA BR') dermObj.config.userImgOnly = true; dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; dermObj.config.hideEmailButtons = true; dermObj.config.forcedLanguage = 'pt-br'; dermObj.config.forcedPage = 'https://sephora.com.br/'; dermObj.afterLanguageCall = ()=>{ dermObj.body.querySelectorAll('[data-widget-text-term="constent_we_care"]').forEach((textEl)=>{ textEl.innerHTML = "Nós, da Dermalogica LCC, nos preocupamos com a sua privacidade" }) dermObj.body.querySelectorAll('[data-widget-text-term="consent_legal_text_2"]').forEach((textEl)=>{ textEl.innerHTML = "Ao clicar \"EU CONCORDO\", você autoriza a Dermalogica, LCC e seus fornecedores de confiança a captar e processar a sua selfie para preparar relatórios faciais detalhados (incluindo geometria facial) e fornecer uma avaliação personalizada de pele e recomendações de produtos, assim como aprimorar as ferramentas, tecnologias e serviços de mapeamento facial e de pele. Para mais informações, por favor acesse Aviso de Privacidade e consulte Face Mapping® Privacy Statement.

*Nenhum dado ou informação capturados pelo FaceMapping serão compartilhados ou tratados pela Sephora." }) dermObj.body.querySelectorAll('[data-widget-text-term="consent_privacy_statement_7"]').forEach((textEl)=>{ textEl.innerHTML = "Para obter mais informações sobre nossas práticas de privacidade e outras informações pessoais que podemos coletar ou processar em relação a nossa plataforma, acesse Aviso de Privacidade." }) } } if (dermObj.customizationCheck('state-rda.com','stateRDA')){ // update logo at landing page dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/logo_dermalogica_state_rda_white.svg"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/logo_dermalogica_state_rda_grey.svg"; dermObj.config.brandingLogoScale = 3; dermObj.config.hideEmailButtons = true; dermObj.config.shopButton.hide = true; } if (dermObj.customizationCheck('therabeauticonline.co.uk') || dermObj.customizationCheck('www-therabeauticonline-co-uk.filesusr.com')){ dermObj.config.forcedPage = "therabeauticonline.co.uk"; dermObj.config.hideEmailButtons = true; } // // uses default settings if (dermObj.customizationCheck('ulta.com', 'ulta')){ // change "shop" button text dermObj.config.shopButton.textOverride = "shop now + free gift" dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/derm_ulta_logo.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/derm_ulta_logo_grey.png"; dermObj.config.brandingLogoScale = 4; dermObj.config.storeLocator.extraParameters = "&maxStores=100&maxRadius=50"; dermObj.config.storeLocator.regexFilter = new RegExp(/(U|u)lta/, 'g'); dermObj.config.storeLocator.showStores = true; } // // TODO special coupon task if (dermObj.customizationCheck('yourskinexpert.ie')){ //remove email button dermObj.config.hideEmailButtons = true; dermObj.widget_wrapper.style.width = "100%" const pageContainer = dermObj.widget_wrapper.parentElement try{ pageContainer.classList.remove('PageContent--narrow','PageContent','Rte') }catch(err){} //dermObj.updateClassesDueWith() // not working here, since it is not defined yet } // TODO - needs to be checked once it is live. some adjustments had to be made to their site if (dermObj.customizationCheck('demo.just.the.microsite','demo')){ dermObj.config.useTreatmentBanners = true; dermObj.afterGDPRCall = () => { dermObj.backend = 'https://fmc-backend-staging.herokuapp.com'; } } if (dermObj.customizationCheck('lastfacemap.just.the.microsite','lastfacemap')){ dermObj.config.useTreatmentBanners = true; if (window.location.search.indexOf('fmhid') == -1){ const xhr = new XMLHttpRequest(); xhr.open('GET', `https://fmc-backend-staging.herokuapp.com/fmc/get_most_recent_face_map`, true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.responseType = 'json'; xhr.onload = () => { dermObj.backendData = xhr.response; if (window.location.search == ''){ window.history.pushState('fmc_results_page', '', `${window.location.href}?fmhid=${xhr.response.hashid}&be=stg`); }else{ window.history.pushState('fmc_results_page', '', `${window.location.href}&fmhid=${xhr.response.hashid}&be=stg`); } dermObj.applyState(); } xhr.send(); } } if (dermObj.customizationCheck('dev_variables.com')){ dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.chat.enabled = true; dermObj.config.chat.depId = 2148428841; dermObj.config.chat.key = 'en'; dermObj.config.klavyioId = 'Kju9Kg'; dermObj.config.klavyioListId = 'Vbmiym'; dermObj.config.useTreatmentBanners = true; //dermObj.config.quizAfterImage = true; dermObj.config.showQniConsentButton = true; dermObj.config.qniChoiceFromLanding = true; //dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; //dermObj.config.pageDict.landing = 'fmc_qai_page_default'; dermObj.config.pageDict.onboarding = 'fmc_loading_page_default'; //dermObj.config.pageDict.results = 'fmc_results_brand_campaign'; //dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; const fastCompanyBadgeVariations = ['fastcompany-variation-round-dark-bg','fastcompany-variation-round-white-bg', 'fastcompany-variation-stamp-dark' ,'fastcompany-variation-banner-dark']; const urlParamShort = ['fc-var-l-rd','fc-var-l-rw', 'fc-var-l-sd' ,'fc-var-l-bd']; const fastCompanyBadgeIndex = Math.min(Math.floor(Math.random()*fastCompanyBadgeVariations.length + 1),fastCompanyBadgeVariations.length ); if (fastCompanyBadgeIndex <= fastCompanyBadgeVariations.length - 1){ dermObj.config.badges.fmc_landing_page_default = `badge-for-landing-default ${fastCompanyBadgeVariations[fastCompanyBadgeIndex]}`; dermObj.queueUrlParameters({'bdge_var':urlParamShort[fastCompanyBadgeIndex]}); }else{ dermObj.queueUrlParameters({'bdge_var':'blank'}) } //const abcTestResultsPageArray = ['fmc_results_page_default','fmc_results_prep_treat_glow','fmc_results_brand_campaign'] //const resultsPageIndex = Math.max(0,Math.min(2,Math.floor(Math.random()*3))); const abTestResultsPageArray = ['fmc_results_page_default','fmc_results_prep_treat_glow'] const resultsPageIndex = Math.max(0,Math.min(1,Math.floor(Math.random()*2))); try{ dermObj.config.pageDict.results = abTestResultsPageArray[resultsPageIndex]; }catch(err){ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; } dermObj.treatments.bookNowDict = { "pro bright" : "https://dermalogica.com/pages/book-a-service?code=PBD50", "luminfusion" : "https://www.dermalogica.com/pages/book-a-service?code=LUMD50" } dermObj.config.blogs_file = 'blogs_US.json'; dermObj.contactOpenHours = "Mon - Fri, 7am - 8pm PT | Sat - Sun, 10am - 2pm PT
(excludes public holidays)"; dermObj.config.crm.enabled = true; dermObj.config.crm.country = 'US'; dermObj.config.percMatchFolder = 'US'; dermObj.config.histFmcObj = true; dermObj.config.requestEmailForResults = true; } dermObj.configLoaded = true; dermObj.applyCustomizations(); try{ dermObj.referrer = dermObj.config.forcedPage != '' ? dermObj.config.forcedPage : dermObj.referrer; }catch(err){console.log(err)} try{ dermObj.dioxide = "https://dioxide.herokuapp.com"; if (window.location.search.indexOf('dx_ep=') > -1){ const dxLabel = window.location.search.split('dx_ep=')[1].split('&')[0]; switch(dxLabel){ case 'stable': dermObj.dioxide = 'https://dioxide-stable-563944234795.herokuapp.com' break; case 'stg': dermObj.dioxide = 'https://dioxide-staging.herokuapp.com' break; default: dermObj.dioxide = 'https://dioxide.herokuapp.com' } } }catch(err){ dermObj.dioxide = 'https://dioxide.herokuapp.com'; console.log(err) } if (window.location.href.indexOf("http://localhost:5000") > -1 || window.location.href.indexOf("http://192.168.0.150:5000") > -1){ } dermObj.applyState = async () => { let isResultsPage = false; let needsToBuildResults = true; if (window.location.search.indexOf('fmhid=') > -1 ){ isResultsPage = true; if (typeof dermObj.backendData == 'undefined'){ try{ if (window.location.search.indexOf('qni=1') > -1){ dermObj.config.quizNoImage = true; dermObj.config.use2FA = false; } dermObj.formerHash = window.location.search.split('fmhid=')[1].split('&')[0]; dermObj.requestPermissionBeforeLoadingFormerResult(); }catch(err){ console.warn("not a valid old fmc result",err); } }else{ needsToBuildResults = false; } } if (isResultsPage){ if (window.location.search.indexOf('rspg=') > -1 ){ let rspg = window.location.search.split('rspg=')[1].split('&')[0]; if (rspg == 'prep_treat_glow'){ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; } if (rspg == 'default'){ dermObj.config.pageDict.results = 'fmc_results_page_default'; } if (rspg == 'brand_campaign'){ dermObj.config.pageDict.results = 'fmc_results_brand_campaign'; } if (rspg == 'estr'){ dermObj.config.pageDict.results = 'fmc_estimated_results'; } if (rspg == 'quiz_no_image'){ dermObj.config.pageDict.results = 'fmc_results_quiz_no_image'; } } if (typeof dermObj.backendData != 'undefined'){ dermObj.gotoPage('results'); dermObj.body.style.opacity = 1; await dermObj.loadExtraLibraries(); try{ await dermObj.capture.initFaceLandmarkModel(false); }catch(err){ console.error(err) } if (dml_fmc.config.pageDict.results == 'fmc_results_page_default'){ if (needsToBuildResults || dermObj.body.querySelectorAll("#fmc_results_concerns_list .fmc_concern_info_item ").length == 0){ dermObj.pageControls.results_default.build(); } } } }else{ if (window.location.search.indexOf('rspg=') > -1 ){ let rspg = window.location.search.split('rspg=')[1].split('&')[0]; if (rspg == 'prep_treat_glow'){ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; } if (rspg == 'default'){ dermObj.config.pageDict.results = 'fmc_results_page_default'; } if (rspg == 'brand_campaign'){ dermObj.config.pageDict.results = 'fmc_results_brand_campaign'; } } dermObj.removeUrlParameters('landing',['be','rspg']); if (dermObj.isPercMatchMiniPage == true){ dermObj.queueUrlParameters({fmc_mnpg_d:1}); window.fmc_collections_complete = false; window.fmc_collections_df = false; } dermObj.gotoPage("landing"); dermObj.body.style.opacity = 1; await dermObj.loadExtraLibraries(); // prepare capture page and init landmark model try{ await dermObj.capture.init({ captureContainerId : 'fmc_video_container', videoConstrains : { video: { facingMode: { ideal: 'user' }, width: { min: 720, ideal: 1080, max: 1920 }, height: {min: 720, ideal: 1080, max: 1920 } }, audio: false } }); }catch(err){ console.error(err) } try{ document.querySelector('.derm_manual_button').addEventListener('click',()=>{ dermObj.sendGA360("main flow","manual capture button clicked"); dermObj.sendGAFlowEvent("manual capture button clicked") }) }catch(err){ console.error(err) } let facemarkModelLoaded = false; try{ facemarkModelLoaded = await dermObj.capture.initFaceLandmarkModel(); }catch(err){ console.error(err) } if (window.location.href.indexOf("http://localhost:5000") > -1 || window.location.href.indexOf("http://192.168.0.150:5000") > -1){ //dermObj.gotoPage("onboarding"); //dermObj.gotoPage("capture"); //dermObj.gotoPage("waiting"); //dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; //dermObj.gotoPage('results'); } } } dermObj.init = async () => { await dermObj.getLanguageData(); await dermObj.renderTextData(dermObj.textData); // FIX FOR POLISH LANGUAGE - ISSUES WITH HELVETICA NEUE STD - SECOND TIME AFTER QUIZ LOADED if (['pl','cs','ro'].includes(dermObj.lang_code)){ dermObj.body.querySelectorAll('p,span,a,h1,h2,h3').forEach((textEl) => { textEl.style.fontFamily = '"Helvetica Neue", "Arial"' }); } if (typeof dermObj.afterLanguageCall != 'undefined'){ try{ dermObj.afterLanguageCall(); }catch(err){console.error("error in afterLanguageCall - ",err)} } if (dermObj.isIOS || dermObj.isMacLike){ dermObj.body.querySelectorAll('.dml_horizontally_centered_text').forEach((centerEl) => { centerEl.style.paddingTop = '0.2em'; }) } (()=>{ dermObj.blogs.load(); })(); (async ()=>{ try{ await dermObj.getGDPR(); }catch(err){ console.log(err); } dermObj.applyState(); dermObj.applyLegalText(); if (dermObj.countryCode != 'IT'){ if (dermObj.uselegacyLegalCopy){ dermObj.body.querySelector('#fmc_legal_container_default').style.display = 'none'; dermObj.body.querySelector('#fmc_legal_container_legacy').style.display = 'block'; }else{ dermObj.body.querySelector('#fmc_legal_container_default').style.display = 'block'; dermObj.body.querySelector('#fmc_legal_container_legacy').style.display = 'none'; } } try{ dermObj.siteLinks = await dermObj.getDioxideLinkData(); }catch(err){ dermObj.siteLinks = {}; console.warn('error in getting site links - ',err); } (async ()=>{ try{ await dermObj.getAllDioxideProducts(); try{ await dermObj.getAllDioxideTranslations(); dermObj.mergeDioxideAllProdAndTranslations(); }catch(errInner){ console.error(errInner) } }catch(err){ dermObj.dioxideAllProducts = {}; console.warn('error in getting dioxide Products - ',err); } })() if (dermObj.siteLinks.contact_us_url === null || dermObj.siteLinks.contact_us_url === '' || dermObj.siteLinks.contact_us_url === undefined){ dermObj.body.querySelectorAll('.fmc_contact_section').forEach((contactSection) => { contactSection.style.display = 'none'; }) } if (dermObj.config.emailDoubleCheckbox == true){ document.querySelector('#fmc_email_popup .fmc_email_form_wrapper').classList.add('fmc_double_check_box'); } if (typeof dermObj.afterGDPRCall != 'undefined'){ try{ dermObj.afterGDPRCall(); }catch(err){console.error("error in afterGDPRCall - ",err)} } try{ dermObj.chat.setUpZendesk(); }catch(err){} })() dermObj.klaviyo.getId(); await dermObj.initClassesDueWidth(); try{ if (typeof dermObj.capture == 'object'){ dermObj.capture.initDone = false; } }catch(err){ console.error("error in reseting init variable for catpure script", err); } if (!initialized){ initialized = true; dermObj.loadedAppTS = Date.now(); dermObj.sendGA4Time('app_loading_time' , dermObj.loadedAppTS - dermObj.openAppTS); dermObj.debug('app loading time [ms]: ', dermObj.loadedAppTS - dermObj.openAppTS); } } dermObj.init(); window.onpopstate = ()=>{ if (dml_fmc.widget_wrapper.querySelector(`#fmc_body`) == null ) return; dermObj.applyState(); } })()