@givefreely/adunit 1.17.5-dev.0 → 1.17.5-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- "use strict";function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var t={exports:{}};"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self&&self,function(e){if(!(globalThis.chrome&&globalThis.chrome.runtime&&globalThis.chrome.runtime.id))throw new Error("This script should only be loaded in a browser extension.");if(globalThis.browser&&globalThis.browser.runtime&&globalThis.browser.runtime.id)e.exports=globalThis.browser;else{const t="The message port closed before a response was received.",r=e=>{const r={alarms:{clear:{minArgs:0,maxArgs:1},clearAll:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getAll:{minArgs:0,maxArgs:0}},bookmarks:{create:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},getChildren:{minArgs:1,maxArgs:1},getRecent:{minArgs:1,maxArgs:1},getSubTree:{minArgs:1,maxArgs:1},getTree:{minArgs:0,maxArgs:0},move:{minArgs:2,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeTree:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}},browserAction:{disable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},enable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},getBadgeBackgroundColor:{minArgs:1,maxArgs:1},getBadgeText:{minArgs:1,maxArgs:1},getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},openPopup:{minArgs:0,maxArgs:0},setBadgeBackgroundColor:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setBadgeText:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},browsingData:{remove:{minArgs:2,maxArgs:2},removeCache:{minArgs:1,maxArgs:1},removeCookies:{minArgs:1,maxArgs:1},removeDownloads:{minArgs:1,maxArgs:1},removeFormData:{minArgs:1,maxArgs:1},removeHistory:{minArgs:1,maxArgs:1},removeLocalStorage:{minArgs:1,maxArgs:1},removePasswords:{minArgs:1,maxArgs:1},removePluginData:{minArgs:1,maxArgs:1},settings:{minArgs:0,maxArgs:0}},commands:{getAll:{minArgs:0,maxArgs:0}},contextMenus:{remove:{minArgs:1,maxArgs:1},removeAll:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},cookies:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:1,maxArgs:1},getAllCookieStores:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},devtools:{inspectedWindow:{eval:{minArgs:1,maxArgs:2,singleCallbackArg:!1}},panels:{create:{minArgs:3,maxArgs:3,singleCallbackArg:!0},elements:{createSidebarPane:{minArgs:1,maxArgs:1}}}},downloads:{cancel:{minArgs:1,maxArgs:1},download:{minArgs:1,maxArgs:1},erase:{minArgs:1,maxArgs:1},getFileIcon:{minArgs:1,maxArgs:2},open:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},pause:{minArgs:1,maxArgs:1},removeFile:{minArgs:1,maxArgs:1},resume:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},extension:{isAllowedFileSchemeAccess:{minArgs:0,maxArgs:0},isAllowedIncognitoAccess:{minArgs:0,maxArgs:0}},history:{addUrl:{minArgs:1,maxArgs:1},deleteAll:{minArgs:0,maxArgs:0},deleteRange:{minArgs:1,maxArgs:1},deleteUrl:{minArgs:1,maxArgs:1},getVisits:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1}},i18n:{detectLanguage:{minArgs:1,maxArgs:1},getAcceptLanguages:{minArgs:0,maxArgs:0}},identity:{launchWebAuthFlow:{minArgs:1,maxArgs:1}},idle:{queryState:{minArgs:1,maxArgs:1}},management:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},getSelf:{minArgs:0,maxArgs:0},setEnabled:{minArgs:2,maxArgs:2},uninstallSelf:{minArgs:0,maxArgs:1}},notifications:{clear:{minArgs:1,maxArgs:1},create:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:0},getPermissionLevel:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},pageAction:{getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},hide:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},permissions:{contains:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},request:{minArgs:1,maxArgs:1}},runtime:{getBackgroundPage:{minArgs:0,maxArgs:0},getPlatformInfo:{minArgs:0,maxArgs:0},openOptionsPage:{minArgs:0,maxArgs:0},requestUpdateCheck:{minArgs:0,maxArgs:0},sendMessage:{minArgs:1,maxArgs:3},sendNativeMessage:{minArgs:2,maxArgs:2},setUninstallURL:{minArgs:1,maxArgs:1}},sessions:{getDevices:{minArgs:0,maxArgs:1},getRecentlyClosed:{minArgs:0,maxArgs:1},restore:{minArgs:0,maxArgs:1}},storage:{local:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},managed:{get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1}},sync:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}}},tabs:{captureVisibleTab:{minArgs:0,maxArgs:2},create:{minArgs:1,maxArgs:1},detectLanguage:{minArgs:0,maxArgs:1},discard:{minArgs:0,maxArgs:1},duplicate:{minArgs:1,maxArgs:1},executeScript:{minArgs:1,maxArgs:2},get:{minArgs:1,maxArgs:1},getCurrent:{minArgs:0,maxArgs:0},getZoom:{minArgs:0,maxArgs:1},getZoomSettings:{minArgs:0,maxArgs:1},goBack:{minArgs:0,maxArgs:1},goForward:{minArgs:0,maxArgs:1},highlight:{minArgs:1,maxArgs:1},insertCSS:{minArgs:1,maxArgs:2},move:{minArgs:2,maxArgs:2},query:{minArgs:1,maxArgs:1},reload:{minArgs:0,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeCSS:{minArgs:1,maxArgs:2},sendMessage:{minArgs:2,maxArgs:3},setZoom:{minArgs:1,maxArgs:2},setZoomSettings:{minArgs:1,maxArgs:2},update:{minArgs:1,maxArgs:2}},topSites:{get:{minArgs:0,maxArgs:0}},webNavigation:{getAllFrames:{minArgs:1,maxArgs:1},getFrame:{minArgs:1,maxArgs:1}},webRequest:{handlerBehaviorChanged:{minArgs:0,maxArgs:0}},windows:{create:{minArgs:0,maxArgs:1},get:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:1},getCurrent:{minArgs:0,maxArgs:1},getLastFocused:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}}};if(0===Object.keys(r).length)throw new Error("api-metadata.json has not been included in browser-polyfill");class i extends WeakMap{constructor(e,t=void 0){super(t),this.createItem=e}get(e){return this.has(e)||this.set(e,this.createItem(e)),super.get(e)}}const s=(t,r)=>(...i)=>{e.runtime.lastError?t.reject(new Error(e.runtime.lastError.message)):r.singleCallbackArg||i.length<=1&&!1!==r.singleCallbackArg?t.resolve(i[0]):t.resolve(i)},n=e=>1==e?"argument":"arguments",a=(e,t,r)=>new Proxy(t,{apply:(t,i,s)=>r.call(i,e,...s)});let o=Function.call.bind(Object.prototype.hasOwnProperty);const c=(e,t={},r={})=>{let i=Object.create(null),l={has:(t,r)=>r in e||r in i,get(l,g,h){if(g in i)return i[g];if(!(g in e))return;let d=e[g];if("function"==typeof d)if("function"==typeof t[g])d=a(e,e[g],t[g]);else if(o(r,g)){let t=((e,t)=>function(r,...i){if(i.length<t.minArgs)throw new Error(`Expected at least ${t.minArgs} ${n(t.minArgs)} for ${e}(), got ${i.length}`);if(i.length>t.maxArgs)throw new Error(`Expected at most ${t.maxArgs} ${n(t.maxArgs)} for ${e}(), got ${i.length}`);return new Promise(((n,a)=>{if(t.fallbackToNoCallback)try{r[e](...i,s({resolve:n,reject:a},t))}catch(s){console.warn(`${e} API method doesn't seem to support the callback parameter, falling back to call it without a callback: `,s),r[e](...i),t.fallbackToNoCallback=!1,t.noCallback=!0,n()}else t.noCallback?(r[e](...i),n()):r[e](...i,s({resolve:n,reject:a},t))}))})(g,r[g]);d=a(e,e[g],t)}else d=d.bind(e);else if("object"==typeof d&&null!==d&&(o(t,g)||o(r,g)))d=c(d,t[g],r[g]);else{if(!o(r,"*"))return Object.defineProperty(i,g,{configurable:!0,enumerable:!0,get:()=>e[g],set(t){e[g]=t}}),d;d=c(d,t[g],r["*"])}return i[g]=d,d},set:(t,r,s,n)=>(r in i?i[r]=s:e[r]=s,!0),defineProperty:(e,t,r)=>Reflect.defineProperty(i,t,r),deleteProperty:(e,t)=>Reflect.deleteProperty(i,t)},g=Object.create(e);return new Proxy(g,l)},l=e=>({addListener(t,r,...i){t.addListener(e.get(r),...i)},hasListener:(t,r)=>t.hasListener(e.get(r)),removeListener(t,r){t.removeListener(e.get(r))}}),g=new i((e=>"function"!=typeof e?e:function(t){const r=c(t,{},{getContent:{minArgs:0,maxArgs:0}});e(r)})),h=new i((e=>"function"!=typeof e?e:function(t,r,i){let s,n,a=!1,o=new Promise((e=>{s=function(t){a=!0,e(t)}}));try{n=e(t,r,s)}catch(e){n=Promise.reject(e)}const c=!0!==n&&((l=n)&&"object"==typeof l&&"function"==typeof l.then);var l;if(!0!==n&&!c&&!a)return!1;return(c?n:o).then((e=>{i(e)}),(e=>{let t;t=e&&(e instanceof Error||"string"==typeof e.message)?e.message:"An unexpected error occurred",i({__mozWebExtensionPolyfillReject__:!0,message:t})})).catch((e=>{console.error("Failed to send onMessage rejected reply",e)})),!0})),d=({reject:r,resolve:i},s)=>{e.runtime.lastError?e.runtime.lastError.message===t?i():r(new Error(e.runtime.lastError.message)):s&&s.__mozWebExtensionPolyfillReject__?r(new Error(s.message)):i(s)},u=(e,t,r,...i)=>{if(i.length<t.minArgs)throw new Error(`Expected at least ${t.minArgs} ${n(t.minArgs)} for ${e}(), got ${i.length}`);if(i.length>t.maxArgs)throw new Error(`Expected at most ${t.maxArgs} ${n(t.maxArgs)} for ${e}(), got ${i.length}`);return new Promise(((e,t)=>{const s=d.bind(null,{resolve:e,reject:t});i.push(s),r.sendMessage(...i)}))},f={devtools:{network:{onRequestFinished:l(g)}},runtime:{onMessage:l(h),onMessageExternal:l(h),sendMessage:u.bind(null,"sendMessage",{minArgs:1,maxArgs:3})},tabs:{sendMessage:u.bind(null,"sendMessage",{minArgs:2,maxArgs:3})}},m={clear:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}};return r.privacy={network:{"*":m},services:{"*":m},websites:{"*":m}},c(e,f,r)};e.exports=r(chrome)}}(t);var r,i,browser=e(t.exports);class s{constructor(){this.isLocal=!0}log({level:e,message:t,timestamp:r,data:i,title:n}){let a;switch(e){case"debug":default:a="log";break;case"info":a="info";break;case"warn":a="warn";break;case"error":case"critical":case"fatal":a="error"}const o=n?`[${n}]`:"";void 0!==i?console[a](`[${r}] - ${s.LOGGER_PREFIX} ${o} ${t}`,i):console[a](`[${r}] - ${s.LOGGER_PREFIX} ${o} ${t}`)}}s.LOGGER_PREFIX="[GFAdUnit] -",function(e){e.checkoutPopupShown="CHECKOUT-POPUP-SHOWN",e.checkoutPopupNotShown="CHECKOUT-POPUP-NOT-SHOWN",e.checkoutPopupSupressed="CHECKOUT-POPUP-SUPRESSED",e.checkoutPopupDonation="CHECKOUT-POPUP-DONATION",e.checkoutPopupFailedActivation="CHECKOUT-POPUP-FAILED-ACTIVATION",e.checkoutPopupPurchaseConfirmed="CHECKOUT-POPUP-PURCHASE-CONFIRMED",e.checkoutPopupHealthCheck="CHECKOUT-POPUP-HEALTH-CHECK",e.checkouPopupActivationFailed="CHECKOUT-POPUP-ACTIVATION-FAILED",e.checkoutPopupOfferDetailsClicked="CHECKOUT-POPUP-OFFER-DETAILS-CLICKED",e.checkoutPopupWhyAmISeeingThisClicked="CHECKOUT-POPUP-WHY-AM-I-SEEING-THIS-CLICKED",e.checkoutPopupLooserExtension="CHECKOUT-POPUP-LOOSER-EXTENSION",e.checkoutPopupActiveDomain="CHECKOUT-POPUP-ACTIVE-DOMAIN",e.checkoutPopupSiteMatches="CHECKOUT-POPUP-SITE-MATCHES",e.checkoutPopupMerchantInResultsFound="CHECKOUT-MERCHANT-IN-RESULTS-FOUND"}(r||(r={})),function(e){e.adUnitLog="ADUNIT-LOG"}(i||(i={}));class n{constructor(e){this.isLocal=!1,this.backgroundService=e}log({level:e,message:t,data:r,title:s}){this.backgroundService.trackEvent(i.adUnitLog,{log:{level:e,message:t,data:r,title:s}})}}const a=["debug","info","warn","error","critical","fatal"];class o{constructor(e){this.config={minLevel:e?.minLevel??"debug",enabled:e?.enabled??!1,transports:e?.transports??[new s],title:e?.title??""}}static getInstance(e){return o.instance||(o.instance=new o(e)),o.instance}configure(e){this.config={...this.config,...e}}shouldLog(e){return!!this.config.enabled&&a.indexOf(e)>=a.indexOf(this.config.minLevel)}createLogMessage(e,t,r){return{level:e,version:"1.17.4",message:t,timestamp:(new Date).toISOString(),data:r,title:this.config.title}}log(e,t,r,i){if(!this.shouldLog(e))return;const s=this.createLogMessage(e,t,i);this.config.transports.filter((e=>!r||e.isLocal)).forEach((e=>e.log(s)))}debug(e,t,r=!1){this.log("debug",e,r,t)}info(e,t,r=!1){this.log("info",e,r,t)}warn(e,t,r=!1){this.log("warn",e,r,t)}error(e,t,r=!1){this.log("error",e,r,t)}critical(e,t,r=!1){this.log("critical",e,r,t)}fatal(e,t,r=!1){this.log("fatal",e,r,t)}addTransport(e){this.config.transports.push(e)}clearTransports(){this.config.transports=[]}disable(){this.config.enabled=!1}enable(){this.config.enabled=!0}}const c=3,l=e=>1e3*e;async function g(e,t={},r){const{maxAttempts:i=c,delayFn:s=l}=t;let n=null;for(let t=1;t<=i;t+=1)try{return await e()}catch(e){n=e,t<i&&await new Promise((e=>{setTimeout(e,s(t))}))}if(n&&t.logger&&t.operationName&&t.logger.error(`Operation ${t.operationName} failed after ${i} attempts.`,n,!0),void 0!==r)return r;throw n||new Error("Operation failed after multiple attempts")}const h=browser,d={TRACK_EVENT:"GF_TRACK_EVENT",HIDE_POPUP:"GF_HIDE_POPUP",GET_POPUP_CONFIG:"GF_GET_POPUP_CONFIG",IS_ACTIVE_DOMAIN:"GF_IS_ACTIVE_DOMAIN",LOG_MERCHANTS_IN_SEARCH_RESULTS:"GF_LOG_MERCHANTS_IN_SEARCH_RESULTS",SHOULD_STAND_DOWN:"GF_SHOULD_STAND_DOWN",ACTIVATE_OFFER:"GF_ACTIVATE_OFFER",STORE_SHOPIFY_SHOP_ID:"GF_STORE_SHOPIFY_SHOP_ID",GET_DOMAIN_BY_SHOP_ID:"GF_GET_DOMAIN_BY_SHOP_ID",GET_LANGUAGE_CONTENT:"GF_GET_LANGUAGE_CONTENT"},u="shopify_shop_ids",f="gf_last_health_check",m="gf_partner_config",p="gf_global_config",A="countryCode",y="version",w="gf_anonymous_user_info",v="gf_anonymous_encrypted_token",C="gf_ad_event_history",S="wfDevice",b="wfDomains",E="wfStanddownPolicy",I="wfStanddownHistory",T="wfMerchantRates",x="en",_="GIVE_FREELY_",O={async get(e){const t=`${_}${e}`;return(await browser.storage.local.get(t))[t]||null},async set(e,t){const r=`${_}${e}`;await browser.storage.local.set({[r]:t})},async remove(e){const t=Array.isArray(e)?e.map((e=>`${_}${e}`)):`${_}${e}`;await browser.storage.local.remove(t)}},P=()=>String("1.17.4"),D=async(e=!0)=>{const t=await O.get(y),r=await P(),i=t!==r;var s;return e&&i&&await(s=r,O.set(y,s)),i},F=o.getInstance(),U={async get(e,t,r,i=!1,s){let n=await O.get(e);const a=n;let o=!1,c=r??n?.retentionInSeconds??600;if(n&&Date.now()<=n.lastFetch+1e3*c&&!i)return{content:n.content,isStale:o};try{const r=await t(),i=s?s(r):null;null!=i&&(c=i),n=await this.set(e,r,c)}catch(e){F.error("Error getting cached value",{error:e}),o=!0}return{content:n?.content??a?.content,isStale:o}},async set(e,t,r){const i=r??600,s={content:t,lastFetch:Date.now(),retentionInSeconds:i};return await O.set(e,s),s},async clear(e){await O.remove(e)}};class k{constructor(){this.listeners=new Map,this.wildcardListeners=new Set}on(e,t){return this.addListener(e,t,!1)}once(e,t){return this.addListener(e,t,!0)}off(e,t){if(!t)return this.listeners.delete(e),void(this.wildcardListeners=new Set(Array.from(this.wildcardListeners).filter((t=>t.pattern!==e))));if(e.includes("*"))this.wildcardListeners=new Set(Array.from(this.wildcardListeners).filter((r=>!(r.pattern===e&&r.callback===t))));else{const r=this.listeners.get(e);if(r){const i=Array.from(r).filter((e=>e.callback!==t));i.length>0?this.listeners.set(e,new Set(i)):this.listeners.delete(e)}}}emit(e){const t=this.listeners.get(e.path)||new Set,r=new Set;for(const e of t)r.add(e);for(const t of this.wildcardListeners)this.matchesPattern(e.path,t.pattern)&&r.add(t);for(const t of r)t.callback(e),t.once&&this.removeListener(t)}clear(){this.listeners.clear(),this.wildcardListeners.clear()}addListener(e,t,r){const i={pattern:e,callback:t,once:r};if(e.includes("*"))this.wildcardListeners.add(i);else{const t=this.listeners.get(e);t?t.add(i):this.listeners.set(e,new Set([i]))}return()=>this.off(e,t)}removeListener(e){if(e.pattern.includes("*"))this.wildcardListeners.delete(e);else{const t=this.listeners.get(e.pattern);t&&(t.delete(e),0===t.size&&this.listeners.delete(e.pattern))}}matchesPattern(e,t){if("*"===t)return!0;const r=t.split(".").map((e=>"*"===e?"[^.]+":"**"===e?".*":e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"))).join("\\.");return new RegExp(`^${r}$`).test(e)}}function L(e,t,r=""){const i=[];if(e===t)return i;if(R(e)||R(t))return e!==t&&i.push({path:r||"root",oldValue:e,newValue:t}),i;if(Array.isArray(e)&&Array.isArray(t))return JSON.stringify(e)!==JSON.stringify(t)&&i.push({path:r||"root",oldValue:e,newValue:t}),i;if(N(e)&&N(t)){const s=e,n=t,a=new Set([...Object.keys(s),...Object.keys(n)]);for(const e of a){const t=r?`${r}.${e}`:e,a=s[e],o=n[e];if(e in s)if(e in n){const e=L(a,o,t);i.push(...e)}else i.push({path:t,oldValue:a,newValue:void 0});else i.push({path:t,oldValue:void 0,newValue:o})}}else e!==t&&i.push({path:r||"root",oldValue:e,newValue:t});return i}function R(e){return null==e||"object"!=typeof e}function N(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}var $;!function(e){e.CLOSED="CLOSED",e.OPEN="OPEN",e.HALF_OPEN="HALF_OPEN"}($||($={}));class M{constructor(e={}){this.state=$.CLOSED,this.failures=[],this.lastFailureTime=0,this.halfOpenCalls=0,this.logger=o.getInstance({minLevel:"warn"}),this.options={failureThreshold:5,recoveryTimeout:6e4,monitoringWindow:3e5,halfOpenMaxCalls:3,storageKey:"circuit_breaker_state",...e},this.storageKey=this.options.storageKey}async initialize(){await this.loadFromStorage()}static async create(e={}){const t=new M(e);return await t.initialize(),t}async loadFromStorage(){try{if("undefined"!=typeof chrome&&chrome.storage&&chrome.storage.local){const e=(await chrome.storage.local.get(this.storageKey))[this.storageKey];e&&(this.state=e.state,this.failures=e.failures||[],this.lastFailureTime=e.lastFailureTime||0,this.halfOpenCalls=e.halfOpenCalls||0,this.cleanupOldFailures())}else if("undefined"!=typeof localStorage){const e=localStorage.getItem(this.storageKey);if(e){const t=JSON.parse(e);this.state=t.state,this.failures=t.failures||[],this.lastFailureTime=t.lastFailureTime||0,this.halfOpenCalls=t.halfOpenCalls||0,this.cleanupOldFailures()}}}catch(e){this.logger.warn("Failed to load circuit breaker state from storage:",e)}}async saveToStorage(){try{const e={state:this.state,failures:this.failures,lastFailureTime:this.lastFailureTime,halfOpenCalls:this.halfOpenCalls};"undefined"!=typeof chrome&&chrome.storage&&chrome.storage.local?await chrome.storage.local.set({[this.storageKey]:e}):"undefined"!=typeof localStorage&&localStorage.setItem(this.storageKey,JSON.stringify(e))}catch(e){this.logger.warn("Failed to save circuit breaker state to storage:",e)}}cleanupOldFailures(){const e=Date.now();this.failures=this.failures.filter((t=>e-t.timestamp<=this.options.monitoringWindow))}async execute(e,t){if(this.state===$.OPEN){if(!this.shouldAttemptRecovery()){if(t)return t();throw new Error("Circuit breaker is OPEN - service temporarily unavailable")}this.state=$.HALF_OPEN,this.halfOpenCalls=0,await this.saveToStorage()}if(this.state===$.HALF_OPEN){if(this.halfOpenCalls>=this.options.halfOpenMaxCalls)throw new Error("Circuit breaker HALF_OPEN call limit exceeded");this.halfOpenCalls+=1,await this.saveToStorage()}try{const t=await e();return await this.onSuccess(),t}catch(e){throw await this.onFailure(e),e}}async onSuccess(){this.state===$.HALF_OPEN&&(this.state=$.CLOSED,this.failures=[],await this.saveToStorage())}async onFailure(e){const t=Date.now();this.lastFailureTime=t,this.failures.push({timestamp:t,error:e.message}),this.failures=this.failures.filter((e=>t-e.timestamp<=this.options.monitoringWindow)),this.failures.length>=this.options.failureThreshold&&(this.state=$.OPEN),await this.saveToStorage()}shouldAttemptRecovery(){return Date.now()-this.lastFailureTime>=this.options.recoveryTimeout}getState(){return this.state}getFailureCount(){const e=Date.now();return this.failures.filter((t=>e-t.timestamp<=this.options.monitoringWindow)).length}async reset(){this.state=$.CLOSED,this.failures=[],this.lastFailureTime=0,this.halfOpenCalls=0,await this.saveToStorage()}async clearStorage(){"undefined"!=typeof chrome&&chrome.storage&&chrome.storage.local?await chrome.storage.local.remove(this.storageKey):"undefined"!=typeof localStorage&&localStorage.removeItem(this.storageKey)}getStatus(){return{state:this.state,failureCount:this.getFailureCount(),nextAttemptTime:this.state===$.OPEN?this.lastFailureTime+this.options.recoveryTimeout:null}}}const H="https://cdn.givefreely.com/adunit/behavioral/";class G{constructor(e){this.partnerApiKey=e,this.partnerConfig=null,this.globalConfig=null,this.mergedConfig=null,this.globalConfigRefreshInterval=null,this.partnerConfigRefreshInterval=null,this.eventEmitter=new k,this.isInitialized=!1,this.partnerCircuitBreaker=new M({failureThreshold:3,recoveryTimeout:6e4,monitoringWindow:3e5,storageKey:`gf_partner_circuit_breaker_${e}`}),this.globalCircuitBreaker=new M({failureThreshold:3,recoveryTimeout:6e4,monitoringWindow:3e5,storageKey:"gf_global_circuit_breaker"})}async initialize(){this.isInitialized||(await Promise.all([this.partnerCircuitBreaker.initialize(),this.globalCircuitBreaker.initialize()]),this.isInitialized=!0)}ensureInitialized(){if(!this.isInitialized)throw new Error("GiveFreelyConfigService must be initialized before use. Call initialize() or use create() method.")}getRetryOptions(){return{delayFn:e=>1e3*e,maxAttempts:3}}async fetchPartnerConfig(){const e=await g((async()=>{const e=await fetch(`${H}${this.partnerApiKey}.json`,{cache:"no-store"});if(!e.ok)throw new Error(`Failed to fetch partner config: ${e.statusText}`);return e.json()}),this.getRetryOptions());if(!e)throw new Error("Failed to fetch or get from cache partner config");return this.partnerConfigRefreshInterval=e.configRefreshInterval||this.partnerConfigRefreshInterval,e}async fetchGlobalConfig(){const e=await g((async()=>{const e=await fetch(`${H}global.json`,{cache:"no-store"});if(!e.ok)throw new Error(`Failed to fetch global config => Status code: ${e.status} .${e.statusText}`);return e.json()}),this.getRetryOptions());if(!e)throw new Error("Failed to fetch or get from cache global config",e);return this.globalConfigRefreshInterval=e.configRefreshInterval||this.globalConfigRefreshInterval,e}async getCachedConfig(){return this.mergedConfig}async getConfig(e=!1){this.ensureInitialized();let t=!1;e&&(t=await D());const[r,i]=await Promise.all([U.get(m,this.fetchPartnerConfig.bind(this),this.partnerConfigRefreshInterval,t,(e=>e?.configRefreshInterval??null)),U.get(p,this.fetchGlobalConfig.bind(this),this.globalConfigRefreshInterval,t,(e=>e?.configRefreshInterval??null))]);if(!i.content)throw new Error("Global config is required");if(!r.content)throw new Error("Partner config is required");this.partnerConfig=r.content,this.globalConfig=i.content;const s=this.mergeConfigs(JSON.parse(JSON.stringify(this.globalConfig)),JSON.parse(JSON.stringify(this.partnerConfig)));if(!s)throw new Error("Was not able to merge configs");return((e,t,r)=>{const i=[...t.merchantExclusions??[],...r.merchantExclusions??[]];e.merchantExclusions=i})(s,this.globalConfig,this.partnerConfig),this.emitConfigChanges(s),s}async clearCache(){this.ensureInitialized(),await Promise.all([U.clear(m),U.clear(p)]),this.partnerConfig=null,this.globalConfig=null,this.mergedConfig=null,this.eventEmitter.clear(),await Promise.all([this.partnerCircuitBreaker.reset(),this.globalCircuitBreaker.reset()])}getCircuitBreakerStatus(){return this.ensureInitialized(),{partner:this.partnerCircuitBreaker.getStatus(),global:this.globalCircuitBreaker.getStatus()}}mergeConfigs(e,t){if(!t)return e;if(!e)return t;const r={...e};return Object.keys(t).forEach((i=>{if(!Object.prototype.hasOwnProperty.call(t,i))return;const s=e[i],n=t[i];void 0!==n&&(Array.isArray(n)?r[i]=[...n]:r[i]=null===n||"object"!=typeof n||null===s||"object"!=typeof s?n:this.mergeConfigs(s,n))})),r}on(e,t){return this.eventEmitter.on(e,t)}once(e,t){return this.eventEmitter.once(e,t)}off(e,t){this.eventEmitter.off(e,t)}emitConfigChanges(e){if(!this.mergedConfig)return this.mergedConfig=e,void this.eventEmitter.emit({path:"root",oldValue:null,newValue:e,config:e});const t=L(this.mergedConfig,e);for(const r of t)this.eventEmitter.emit({path:r.path,oldValue:r.oldValue,newValue:r.newValue,config:e});this.mergedConfig=e}}class z{constructor(e,t,r,i=60){this.track=async(e,t,r,i=!1,s=!1)=>{const n={partner:`adUnit_${this._partnerApiKey}`,eventType:e,eventData:{userId:i?void 0:this._userService?.user?.id,libVersion:P(),wfDeviceId:t,...r}};try{const e=JSON.stringify(n,((e,t)=>t instanceof Error?{name:t.name,message:t.message,stack:t.stack}:t)),t=await this.getEventsUrl();return t?await this.BroadcastEvent(t,e,n,s):(this._logger.info("Cant broadcast event. eventsUrl cant be retrieved from config",n,!0),!1)}catch(e){return this._logger.error("Something unexpected happened when dispatching a gf event",{error:e,event:n},!0),!1}},this.getEventsHistory=async()=>{const e=await O.get(C),t=(e=>{const t=new Date;return t.setTime(t.getTime()+60*e*1e3),t.getTime()})(-this._debounceWindowInMinutes),r=(e||[]).filter((e=>e.createdAt>t));return await O.set(C,r),r},this.shouldBroadcastEvent=async(e,t)=>!!t||!(await this.getEventsHistory()).some((t=>t.payload===e)),this.pushEventToHistory=async e=>{const t=await this.getEventsHistory();t.push({createdAt:Date.now(),payload:e}),await O.set(C,t)},this._partnerApiKey=e,this._userService=t,this._debounceWindowInMinutes=i,this._logger=o.getInstance({title:"Analytics"}),this._configService=r}async BroadcastEvent(e,t,r,i){if(await this.shouldBroadcastEvent(t,i)){const i=await fetch(e,{headers:{"Content-Type":"application/json"},method:"POST",body:t,cache:"no-store"});return i.ok?(await this.pushEventToHistory(t),!0):(this._logger.error("Something unexpected happened when dispatching an event",{status:i.status,statusText:i.statusText,event:r},!0),!1)}return this._logger.info("This event has already been broadcasted during the past hour",r,!0),!1}async getEventsUrl(){const e=await this._configService.getCachedConfig();return e?.eventsUrl}}z.trackEvent=async(e,t,r=!1,i=!1)=>{await async function(e){return await h.runtime.sendMessage(e)}({type:d.TRACK_EVENT,payload:{eventType:e,eventData:t,anonymous:r,skipThrottling:i}})};class j{constructor(e,t){this.lastCheck=null,this.trackEvent=e,this.logger=t}async initialize(){const e=await O.get(f);e&&(this.lastCheck=e)}getToday(){return(new Date).toISOString().split("T")[0]}async check(){try{const e=this.lastCheck??0,t=this.getToday();(e?new Date(e).toISOString().split("T")[0]:null)!==t&&(this.lastCheck=Date.now(),await O.set(f,this.lastCheck),await this.trackEvent(r.checkoutPopupHealthCheck,{language:browser.i18n.getUILanguage()}))}catch(e){this.logger.error("Health check failed",{error:e instanceof Error?e.message:"Unknown error"},!0)}}}var W;!function(e){e[e.Pending=0]="Pending",e[e.Ready=1]="Ready",e[e.Received=2]="Received",e[e.Donated=3]="Donated",e[e.Disqualified=4]="Disqualified"}(W||(W={}));class K{constructor(e,t,r){this.adUnitId=e,this.config=t,this.logger=r}async getAnonymousUserCommissions(e,t){try{const r=new URLSearchParams(t).toString(),i=await fetch(`${this.config.apiConfig.baseUri}/${this.config.apiConfig.getAnonymousUserComissionsPath}?${r}`,{method:"GET",headers:{"Content-Type":"application/json","X-AnonymousUserToken":e}});if(!i.ok)throw new Error(`Failed to fetch commissions. Status code: ${i.status} .${i.statusText}`);return await i.json()}catch(e){throw this.logger.error("[GiveFreelyApiClient] Error fetching anonymous user's commissions:",{error:e}),e}}async createOrUpdateAnonymousUser(e,t){try{const r=await fetch(`${this.config.apiConfig.baseUri}/${this.config.apiConfig.createAnonymousUserPath}?adUnitId=${this.adUnitId}`,{method:"PUT",headers:{"Content-Type":"application/json","X-GF-Platform":"adUnitLibrary","X-AnonymousUserToken":t??""},body:JSON.stringify(e)});if(!r.ok)throw this.logger.error(`Failed to create/update anonymous user. Status code: ${r.status}. ${r.statusText}`),new Error(`Failed to create/update anonymous user. Status code: ${r.status}. ${r.statusText}`);this.logger.info("[GiveFreelyApiClient] anonymous user created/updated successfully.");const i=await r.json(),s=r.headers.get("X-AnonymousUserToken");return{resultUser:{...i,charity:{ein:i.selectedCharity,thirdPartyId:i.selectedCharityThirdPartyIdentifier,name:void 0}},resultToken:s}}catch(e){throw this.logger.error("[GiveFreelyApiClient] Error creating anonymous user:",{error:e},!0),e}}}class B{constructor(e,t){this._giveFreelyApiClient=e,this._logger=t,this.user=null}async resetUser(){await O.remove(v),await O.remove(w)}async upsertUser(e,t){let r=await this.fetchUser();try{const i={selectedCharity:e?.ein,selectedCharityThirdPartyIdentifier:e?.thirdPartyId,deviceId:t};if(!await this.shouldCreateOrUpdateUser(r,i))return r;const s=await O.get(v),{resultUser:n,resultToken:a}=await this._giveFreelyApiClient.createOrUpdateAnonymousUser(i,s);a&&await O.set(v,a),n&&(await O.set(w,n),r=n)}catch(e){this._logger.error("Error creating/updating anonymous user:",e)}return this.user=r,r}async fetchUser(){const e=await O.get(w);return this.user=e,e}async shouldCreateOrUpdateUser(e,t){return!e||e.charity?.ein!==t.selectedCharity||e.charity?.thirdPartyId!==t.selectedCharityThirdPartyIdentifier||e.deviceId!==t.deviceId}}class V{constructor(e,t,r,i,s){this.wfSecret=e,this.wfAppId=t,this.deviceUrl=r,this.dataUrl=i,this._logger=s}async getWildfireDevice(){try{const e=await fetch(this.deviceUrl,{method:"POST",body:JSON.stringify({}),headers:{"Content-Type":"application/json","WF-Secret":this.wfSecret,"WF-App-ID":this.wfAppId}});if(e.ok)return e.json();throw new Error(`Failed to fetch Wildfire device from ${this.deviceUrl}. Status ${e.status}. ${e.statusText}`)}catch(e){throw this._logger.error("Failed to fetch the Wildfire device",{err:e}),e}}async getActiveDomains(){try{const e=`${this.dataUrl}/${this.wfAppId}/active-domain/1`,t=await fetch(e);if(t.ok)return t.json();throw new Error(`Failed to fetch active domains from ${e}. Status ${t.status}. ${t.statusText}`)}catch(e){throw this._logger.error("Failed to fetch the active domains",{err:e}),e}}async getStanddownPolicy(){const e=`${this.dataUrl}/${this.wfAppId}/stand-down-policy/1`;try{const t=await fetch(e);if(t.ok)return t.json();throw new Error(`Failed to fetch standdown policy from ${e}. Status ${t.status}. ${t.statusText}`)}catch(t){throw this._logger.error("Failed to fetch the standdown policy",{err:t,url:e}),t}}async getMerchantRates(){const e=`${this.dataUrl}/${this.wfAppId}/merchant-rate/1`;try{const t=await fetch(e);if(this._logger.debug("Merchant rates response",{response:t}),!t.ok)throw new Error(`Failed to fetch merchant rates from ${e}. Status ${t.status}. ${t.statusText}`);const r=t.json();return this._logger.debug("Merchant rates",{rates:r}),r}catch(t){throw this._logger.error("Failed to fetch the merchant rates",{err:t,url:e}),t}}}async function q(e,t,r){try{const i=(await J())?.[t];if(i&&i>Date.now())return e.info("Standing down because current affiliate stand down session has not expired"),X(t),!0;await this.refreshCache();const s=await this.getStanddownPolicy();if(Q(s,new URL(r).search))return e.info("Standing down because url has affiliate params"),X(t),!0;e.info("No need to stand down.")}catch(t){e.error("Exception produced when trying to determine if it should stand down",t)}return!1}function Y(e,t){if(!this.standDownPolicy)return this.logger.warn("Couldnt check affilliation. No stand down policy found"),this.getStanddownPolicy().then((e=>{this.standDownPolicy=e})),!1;const r=e.some((e=>Z(this.standDownPolicy,e)))||Q(this.standDownPolicy,t);return this.logger.info("Affilliation result:",r),r}const J=async()=>O.get(I),X=async(e,t=1)=>{const r=await J()??{};r[e]=Date.now()+60*t*60*1e3,await O.set(I,r)},Z=(e,t)=>{if(!t)return!1;const{Domains:r}=e;return r.some((e=>t.includes(e)))},Q=(e,t)=>{if(!t)return!1;const{Params:r}=e;return r.some((e=>t.toLowerCase().includes(`?${e.toLowerCase()}`)))||r.some((e=>t.toLowerCase().includes(`&${e.toLowerCase()}`)))};class ee{constructor(e,t,r,i){this.userId=e,this.charityEin=t,this.charityThirdPartyIdentifier=r,this.partnerId=i}toString(){return`userId=${this.encodeUserId(this.userId)},charityEin=${this.charityEin},charityThirdPartyIdentifier=${this.charityThirdPartyIdentifier},partnerId=${this.partnerId}`}encodeUserId(e){return btoa(e).replace(/_/g,"/").replace(/-/g,"+")}}class te{constructor(e,t,r,i=21600){if(this.standDownPolicy=null,this.shouldStandDown=q.bind(this),this.hasAffilliation=Y.bind(this),!e||!r)throw new Error("WildfireService requires wildfireClient and vanityBaseUrl");this.wildfireClient=e,this.vanityBaseUrl=r.replace(/\/$/,""),this.refreshInterval=i,this.logger=t}async getActiveDomains(e=!1){try{const t=(await U.get(b,(async()=>this.fetchActiveDomains()),this.refreshInterval,e)).content;if(!t)throw Error("Failed to retrieve active domains");return t}catch(e){throw this.logger.error("Failed to get active domains:",e),new Error("Failed to retrieve active domains")}}async getMerchantRates(e,t=!1){try{const r=await U.get(T,(async()=>this.fetchMerchantRates()),this.refreshInterval,t);if(!r.content)throw new Error("Failed to retrieve merchant rates from cache");return r.content[e]}catch(e){throw this.logger.error("Failed to retrieve merchant rates:",e),new Error("Failed to retrieve merchant rates")}}async generateAffiliateUrl(e,t,r,i){if(!e||!t||!i)throw new Error("Missing required parameters for affiliate URL generation");try{const s=await this.getDevice(),n=await this.generateTrackingCode(r,i,s),a=encodeURIComponent(t),o=encodeURIComponent(n);return`${this.vanityBaseUrl}/e?d=${s.DeviceID}&c=${e.ID}&tc=${o}&url=${a}`}catch(e){throw this.logger.error("Failed to generate affiliate URL:",e),new Error("Failed to generate affiliate URL")}}async clearCache(){try{await Promise.all([U.clear(b),U.clear(E),U.clear(T)])}catch(e){throw this.logger.error("Failed to clear cache:",e),new Error("Failed to clear cache")}}async clearDevice(){try{await O.remove(S),this.logger.info("Cleared wildfire device ID")}catch(e){throw this.logger.error("Failed to clear wildfire device:",e),new Error("Failed to clear wildfire device")}}async refreshCache(e=!1){try{const[,t]=await Promise.all([U.get(b,(()=>this.fetchActiveDomains()),this.refreshInterval,e),U.get(E,(()=>this.fetchStanddownPolicy()),this.refreshInterval,e),U.get(T,(()=>this.fetchMerchantRates()),this.refreshInterval,e)]);t?.content&&(this.standDownPolicy=t.content)}catch(e){throw this.logger.error("Failed to refresh cache:",e),new Error("Failed to refresh cache")}}async getStanddownPolicy(){try{const e=await U.get(E,(async()=>this.fetchStanddownPolicy()),this.refreshInterval);if(!e.content)throw new Error("Failed to retrieve standdown policy from cache");return this.logger.info("Retrieved standdown policy from cache",e.content),this.standDownPolicy=e.content,this.standDownPolicy}catch(e){throw this.logger.error("Failed to get standdown policy from cache:",e),new Error("Failed to retrieve standdown policy")}}getRetryOptions(e){return{delayFn:e=>1e3*e,maxAttempts:3,logger:this.logger,operationName:e}}async getDevice(){try{const e=await O.get(S);return e?.DeviceID?e:g((()=>this.fetchAndStoreDevice()),this.getRetryOptions("Get Device"))}catch(e){throw this.logger.error("Failed to get device:",e),new Error("Failed to retrieve device information")}}async fetchAndStoreDevice(){const e=await this.wildfireClient.getWildfireDevice();if(!e?.DeviceID)throw new Error("Failed to retrieve device information");return await O.set(S,e),e}async generateTrackingCode(e,t,r){if(!(e?.id&&e?.charity&&e?.charity.ein&&e?.charity.thirdPartyId)){const e=`notregistered-${r.DeviceID}`;return this.logger.info("User not provided. Using GF's default bucket instead.",e),e}return new ee(e.id,e.charity.ein,e.charity.thirdPartyId,t).toString()}async fetchActiveDomains(){const e=await g((()=>this.wildfireClient.getActiveDomains()),this.getRetryOptions("Fetch Active Domains"));return this.logger.info("Updated active domains"),e}async fetchStanddownPolicy(){const e=await g((()=>this.wildfireClient.getStanddownPolicy()),this.getRetryOptions("Get Standdown policy"),{Domains:[],LostAttribution:[],Params:[],Serp:[]});return this.logger.info("Updated standdown policy"),e}async fetchMerchantRates(){const e=await g((()=>this.wildfireClient.getMerchantRates()),this.getRetryOptions("Fetch Merchant Rates"),{});return this.logger.debug("Updated Merchant rates"),e}static async createWildfireService(e,t){e.debug("Initializing wildfire service with config",t);const r=new V(t.wfSecret,t.wfAppId,t.deviceUrl,t.dataUrl,e),i=new te(r,e,t.vanityBaseUrl,t.refreshInterval),s=await D();return await i.refreshCache(s),i}}const re=e=>{try{return new URL(e),!0}catch{return!1}},ie=new Set,se=new Set,ne={urls:["<all_urls>"],types:["main_frame"]};class ae extends Error{constructor(e="Service not initialized"){super(e),this.name="UninitializedServiceError"}}const oe=e=>{if(!e)throw new ae};class ce{static register(e,t){this.strategies.set(e,t)}static get(e){return this.strategies.get(e)}static exists(e){return!!function(e){return"object"==typeof e&&null!==e&&"type"in e&&"payload"in e&&"string"==typeof e.type}(e)&&this.knownMessageTypes.has(e.type)}}ce.strategies=new Map,ce.knownMessageTypes=new Set([...Object.values(d)]);const le=e=>{let t;if(browser.webRequest){const r=(e=>{const t=e.getLogger();return({requestId:r,url:i,initiator:s})=>{try{if(ie.has(r)||se.has(r)||!re(i))return;const{hostname:n,search:a}=new URL(i);if(n.includes("wild.link"))return t.info("Cashback activation request identified, ignoring affiliate check for request"),void se.add(r);let o;s&&re(s)&&(o=new URL(s).hostname),(e.hasAffiliation([n,o],a)||e.isCustomStandownMatch([i,s]))&&(t.info("Affiliation found or custom standown match on url, adding request id to track"),ie.add(r))}catch(e){t.error("Error on handleAffiliateOnBeforeRequest",e)}}})(e);browser.webRequest.onBeforeRequest.addListener(r,ne);const i=(e=>{const t=e.getLogger();return async({requestId:r,redirectUrl:i})=>{try{if(!ie.has(r))return;t.info("Attempting to find active domain");const{hostname:s}=new URL(i),n=(await e.getActiveDomains()).find((e=>s===e.Domain||s.endsWith(`.${e.Domain}`)));if(!n)return;t.info("Found active domain. Updating standdown state"),await X(n.Domain)}catch(e){t.error("Error on handleAffiliateOnBeforeRedirect",e)}}})(e);browser.webRequest.onBeforeRedirect.addListener(i,ne);const s=(e=>{const t=e.getLogger();return({requestId:e})=>{try{ie.has(e)&&(t.info("Tracking request completed. Request Id:",e),ie.delete(e))}catch(e){t.error("Error on handleAffiliateOnCompleted",e)}}})(e);browser.webRequest.onCompleted.addListener(s,ne),t=()=>{browser.webRequest.onBeforeRequest.removeListener(r),browser.webRequest.onBeforeRedirect.removeListener(i),browser.webRequest.onCompleted.removeListener(s)}}const r=function(){const t=o.getInstance(),r=(r,i,s)=>{function n(e){s(e)}const a=(async t=>(e.getLogger().debug("Received message",{type:t.type,payload:t.payload}),ge(e,t)))(r,0);return a instanceof Promise?(a.then((e=>{e&&n(e)})).catch((e=>{t.warn("Async message callback error:",e)})),!0):!0===a||void 0};return h.runtime.onMessage.addListener(r),r}();return function(){t&&t(),browser.runtime.onMessage.removeListener(r)}},ge=async(e,t)=>{oe(e.isInitialized());const r=ce.get(t.type);if(!r)return;const i={giveFreelyService:e};return r.handle(t,i)};class he{async handle(e,t){const{activeDomain:i,originalUrl:s,selectedCharity:n}=e.payload,{giveFreelyService:a}=t,o=a.getLogger();o.debug("Activating offer",{activeDomain:i,selectedCharity:n});try{if(!n?.ein||!n?.thirdPartyId)throw new Error("Missing charity information");const e=await a.initializeWfDeviceId();if(!e)throw new Error("Failed to initialize Wildfire device ID");const t=await a.upsertUser(n,e);o.debug("Upserted user",{currentUser:t}),t||o.info("Failed to create user. Using default bucket's user");const r=await a.generateAffiliateUrl(i,s,t);return o.debug("Generated affiliate URL",{affiliateUrl:r}),(async e=>{const t=h.tabs.getCurrent(),r=await t,i=await h.tabs.create({url:e,openerTabId:r?.id,active:!1,pinned:!0});await(async e=>new Promise((t=>{h.tabs.onUpdated.addListener((async function r(i,s){if(i===e&&"complete"===s.status){if(h.tabs.onUpdated.removeListener(r),!(await h.tabs.get(e)).url)return void t(!1);t(!0)}}))})))(i.id)&&setTimeout((()=>{i?.id&&h.tabs.remove(i.id)}),3e4)})(r),await a.updateStanddownHistory(i.Domain),o.debug("Activated offer",{activeDomain:i,selectedCharity:n}),{type:d.ACTIVATE_OFFER,payload:{response:!0}}}catch(e){return o.error("Error activating offer",{activeDomain:i,error:e}),a.trackEvent(r.checkoutPopupFailedActivation,{activeDomain:i,error:e}),{type:d.ACTIVATE_OFFER,payload:{response:!1}}}}}class de{async handle(e,t){const{shopId:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger();try{const e=u,t=(await O.get(e)||[]).find((e=>e.shopId===r));return t?(s.debug("Found domain for shop ID",{shopId:r,domain:t.domain}),{type:d.GET_DOMAIN_BY_SHOP_ID,payload:{found:!0,domain:t.domain,shopInfo:t}}):(s.debug("No domain found for shop ID",{shopId:r}),{type:d.GET_DOMAIN_BY_SHOP_ID,payload:{found:!1}})}catch(e){return s.error("Error getting domain for shop ID",{shopId:r,error:e}),{type:d.GET_DOMAIN_BY_SHOP_ID,payload:{found:!1}}}}}class ue{async handle(e,t){const{lang:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger();s.debug("Getting language strings",{lang:r});try{const e=await i.getLanguage(r);return s.debug("Language strings fetched",{language:e}),{type:d.GET_LANGUAGE_CONTENT,payload:{translations:e.translations,charities:e.charities}}}catch(e){return s.error("Error getting language strings",{error:e}),{type:d.GET_LANGUAGE_CONTENT,payload:{translations:null,charities:null}}}}}class fe{async handle(e,t){const{giveFreelyService:r}=t,i=r.getLogger(),s=await r.getCachedConfig();try{return i.debug("Fetching popup config"),{type:d.GET_POPUP_CONFIG,payload:{config:s}}}catch(e){return i.error("Error fetching popup config",{error:e}),{type:d.GET_POPUP_CONFIG,payload:{config:null}}}}}class me{async handle(e,t){const{days:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger();try{const e=new Date;return e.setDate(e.getDate()+r),await O.set("popup_hide",{popupHide:e.getTime()}),s.debug("Popup hidden",{days:r,expiry:e}),{type:d.HIDE_POPUP,payload:{ack:!0}}}catch(e){return s.error("Error hiding popup",{days:r,error:e}),{type:d.HIDE_POPUP,payload:{ack:!1}}}}}class pe{async handle(e,t){const{hostname:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger(),n=await i.getConfig().merchantExclusions,a=await i.getActiveDomains();s.debug("Checking hostname",{hostname:r});try{if(i.healthCheck(),n.some((e=>e.disableDomain&&(r===e.domain||r.endsWith(`.${e.domain}`)))))return s.debug("Hostname is in merchant exclusions",{hostname:r}),{type:d.IS_ACTIVE_DOMAIN,payload:{isActive:!1,domain:void 0,rates:[]}};if(!a||0===a.length)throw new Error("No active domains");s.debug("Retrieved active domains",{count:a.length});const e=a.find((e=>r===e.Domain||r.endsWith(`.${e.Domain}`)));s.debug("Domain check result",{hostname:r,isActive:!!e});let t=[];if(e?.ID){const r=await i.getMerchantRates(e.Merchant.ID);r&&(s.debug("Retrieved merchant rates",{merchantRates:r}),t=r)}return{type:d.IS_ACTIVE_DOMAIN,payload:{isActive:!!e,domain:e,rates:t}}}catch(e){return s.error("Error checking domain",{hostname:r,error:e}),{type:d.IS_ACTIVE_DOMAIN,payload:{isActive:!1,domain:void 0,rates:[]}}}}}class Ae{async handle(e,t){const{currentUrl:i,searchResults:s,source:n}=e.payload,{giveFreelyService:a}=t,o=a.getLogger(),c=await a.getActiveDomains();o.debug("Finding merchants in search results",{currentUrl:i});try{const e=s.filter((e=>{try{const{hostname:t}=new URL(e.url);return c.some((e=>e.Domain===t||t.endsWith(`.${e.Domain}`)))}catch{return o.debug("Couldn't parse the following search result url",{x:e}),!1}}));if(o.info("Number of merchants identified in the search result",{number:e.length}),e.length>0){const s=Math.floor(Math.random()*Date.now());for(const a of e)t.giveFreelyService.trackEvent(r.checkoutPopupMerchantInResultsFound,{source:n,searchResultsId:s,currentUrl:i,searchResultUrl:a.url,sponsored:a.isSponsored},!0)}return{type:d.LOG_MERCHANTS_IN_SEARCH_RESULTS,payload:{result:!0}}}catch(e){return o.error("Error sending logs for merchants in search results",{currentUrl:i,error:e}),{type:d.LOG_MERCHANTS_IN_SEARCH_RESULTS,payload:{result:!1}}}}}class ye{async handle(e,t){const r=e.payload,{giveFreelyService:i}=t,s=i.getLogger();try{const e=u,t=await O.get(e)||[],i=t.findIndex((e=>e.shopId===r.shopId));return i>=0?t[i]=r:t.push(r),await O.set(e,t),s.debug("Stored Shopify shop ID",{shopInfo:r}),{type:d.STORE_SHOPIFY_SHOP_ID,payload:{success:!0}}}catch(e){return s.error("Error storing Shopify shop ID",{shopInfo:r,error:e}),{type:d.STORE_SHOPIFY_SHOP_ID,payload:{success:!1}}}}}class we{async handle(e,t){const{activeDomain:r,url:i}=e.payload,{giveFreelyService:s}=t,n=s.getLogger();n.debug("Checking if we should stand down",{activeDomain:r});try{const e=await s.shouldStandDown(r,i);return{type:d.SHOULD_STAND_DOWN,payload:{result:e}}}catch(e){return n.error("Error checking if we should stand down. Returning false",{activeDomain:r,error:e}),{type:d.SHOULD_STAND_DOWN,payload:{result:!1}}}}}class ve{async handle(e,t){const{eventType:r,eventData:i,anonymous:s,skipThrottling:n}=e.payload,{giveFreelyService:a}=t,o=a.getLogger();o.debug("Broadcasting event",{eventType:r,eventData:i,anonymous:s,skipThrottling:n});try{const e=await a.trackEvent(r,i,s,n);return{type:d.TRACK_EVENT,payload:{result:e}}}catch(e){return o.error("Error broadcasting event. Returning false",{eventType:r,eventData:i,error:e}),{type:d.TRACK_EVENT,payload:{result:!1}}}}}const Ce=o.getInstance(),Se=async()=>await O.get(A)||(async()=>{Ce.debug("detecting country");const e={method:"GET",headers:{"Content-Type":"application/json",Authorization:"Basic OTEzOTkxOnFlYmpaWF9DOGNRY0lxSHA4WTVjNGxzU1pRSlM2VW9MMExzTF9tbWs="}};try{const t=await fetch("https://geoip.maxmind.com/geoip/v2.1/country/me",e);if(Ce.debug("Received geolocation response",{status:t.status}),!t.ok)return void Ce.error("Failed to get geolocation data",{status:t.status,statusText:t.statusText});const r=await t.json();if(!r)throw new Error("There was an error fetching geoip look up");return await O.set(A,r.country.iso_code),r.country.iso_code}catch(e){return void Ce.error("Failed to get geolocation data",{error:e},!0)}})(),be="https://cdn.givefreely.com/adunit/language",Ee=async(e,t,r,i,s=[],n=!1)=>{const a=(s??[]).includes(r)?x:r;e.debug(`Requested lang ${r} and current lang ${a}`);const o=`lang-${x}`,c=await U.get(o,(async()=>(e.debug(`Fetching default language ${x} for partner ${t}`),Ie(t,x))),i||600,n);if(!c.content)throw new Error(`Failed to fetch default language ${x} and no cache version available`);if(x===a)return c.content;const l=`lang-${a}`,g=await U.get(l,(async()=>(e.debug(`Fetching language ${a} for partner ${t}`),Ie(t,a))),i||600,n);if(!g.content)return c.content;const h=_e(c.content,g.content);return await U.set(l,h,i||600),h},Ie=async(e,t)=>{const r=`/global-${t}.json`,i=`/${e}/${t}.json`,[s,n]=await Promise.allSettled([Te(`${be}${r}`),Te(`${be}${i}`)]);let a,o;"fulfilled"===s.status&&(a=s.value),"fulfilled"===n.status&&(o=n.value);const c=xe(a,o);return{translations:c.translations,charities:c.charities}},Te=async e=>{const t=await fetch(e,{cache:"no-store"});if(!t.ok)throw new Error(`Failed to fetch partner language file ${e}. Status: ${t.status}. Reason: ${t.statusText}`);return t.json()},xe=(e,t)=>({translations:{...e?.translations??{},...t??{}},charities:{...e?.charities??{}}}),_e=(e,t)=>({translations:{...e.translations,...t.translations},charities:{...e.charities,...t.charities}});async function Oe(e=async()=>(this.logger.debug("Using default partnerFilter."),!0)){if(!this.state.initialized){this.logger.info("Starting initialization with mutex protection");try{await this.dependencies.configService.initialize();const t=await this.dependencies.configService.getConfig(!0);this.logger.configure({enabled:t.loggingEnabled??!0,minLevel:t.backgroundMinLogLevel??"error"}),this.logger.info("Initializing GiveFreelyService",{partnerApiKey:this.partnerApiKey});const r=await te.createWildfireService(this.logger,t);this.state.healthCheck=new j(this.trackEvent.bind(this),this.logger),await this.state.healthCheck.initialize();const i=new K(this.partnerApiKey,t,this.logger);this.state.giveFreelyUserService=new B(i,this.logger),await this.state.giveFreelyUserService.fetchUser(),this.state.giveFreelyUserService.user?.id||await this.state.giveFreelyUserService.upsertUser(),this.state.analytics=new z(this.partnerApiKey,this.state.giveFreelyUserService,this.dependencies.configService);try{const e=await O.get(S);e?.DeviceID?(this.state.wfDeviceId=e,this.logger.info("Loaded existing wfDeviceId from storage",{deviceId:e.DeviceID})):this.logger.debug("No existing wfDeviceId found in storage - will be created on first offer activation")}catch(e){this.logger.debug("Could not check for existing wfDeviceId in storage",e)}ce.register(d.IS_ACTIVE_DOMAIN,new pe),ce.register(d.GET_POPUP_CONFIG,new fe),ce.register(d.HIDE_POPUP,new me),ce.register(d.SHOULD_STAND_DOWN,new we),ce.register(d.TRACK_EVENT,new ve),ce.register(d.ACTIVATE_OFFER,new he),ce.register(d.STORE_SHOPIFY_SHOP_ID,new ye),ce.register(d.GET_DOMAIN_BY_SHOP_ID,new de),ce.register(d.GET_LANGUAGE_CONTENT,new ue),ce.register(d.LOG_MERCHANTS_IN_SEARCH_RESULTS,new Ae),await(async e=>{try{await Se()}catch(t){e.debug("Failed to get geolocation data",{error:t})}})(this.logger),await(async(e,t,r)=>{t.purgeLanguages&&t.purgeLanguages.length>0&&await Promise.all(t.purgeLanguages.flatMap((e=>[U.clear(`lang-${e}`),U.clear(`global-${e}`)]))),g((async()=>{e.debug("Initializing default language with partner API key",{partnerApiKey:r}),await Ee(e,r,x,t.configRefreshInterval)}))})(this.logger,t,this.partnerApiKey),this.state=((e,t)=>{const{wildfireService:r,partnerFilter:i,config:s}=t;return{...e,initialized:!0,wildfireService:r,partnerFilter:i,config:s}})(this.state,{wildfireService:r,partnerFilter:e,config:t}),this.logger.addTransport(new n(this)),this.cleanupListeners=le(this),De.call(this),this.logger.info("GiveFreelyService initialized successfully")}catch(e){const t=e instanceof Error?e.message:"Unknown error";throw this.logger.error("Failed to initialize GiveFreelyService",{error:t}),new Error(`Failed to initialize GiveFreelyService: ${t}`)}}}function Pe(){return this.state.initialized}function De(){this.onConfigChange("wfAppId",(async e=>{this.logger.info(`Wildfire App ID changed from ${e.oldValue} to ${e.newValue} - clearing device`),await Fe.call(this)})),this.onConfigChange("wfSecret",(async e=>{this.logger.info("Wildfire Secret changed - clearing device"),await Fe.call(this)}))}async function Fe(){try{this.state.wildfireService&&(await this.state.wildfireService.clearDevice(),this.state.wfDeviceId=null,this.logger.info("Wildfire device cleared due to config change"))}catch(e){this.logger.error("Failed to clear wildfire device:",e)}}var Ue={config:Object.freeze({__proto__:null,getCachedConfig:async function(){return oe(this.state.initialized),this.state.config=await this.dependencies.configService.getConfig(),this.logger.configure({minLevel:this.state.config.backgroundMinLogLevel??"error"}),this.state.config},getConfig:function(){return oe(this.state.initialized),this.state.config},offConfigChange:function(e,t){oe(this.state.initialized),this.dependencies.configService.off(e,t)},onConfigChange:function(e,t){return oe(this.state.initialized),this.dependencies.configService.on(e,t)},onceConfigChange:function(e,t){return oe(this.state.initialized),this.dependencies.configService.once(e,t)}}),merchants:Object.freeze({__proto__:null,generateAffiliateUrl:async function(e,t,r){return oe(this.state.initialized),this.state.wildfireService.generateAffiliateUrl(e,t,r,this.state.partnerApiKey)},getActiveDomains:async function(){return oe(this.state.initialized),this.state.wildfireService.getActiveDomains()},getMerchantRates:async function(e){if(oe(this.state.initialized),!this.state.wildfireService)throw new Error("Wildfire service not initialized");return this.state.wildfireService.getMerchantRates(e)}}),observability:Object.freeze({__proto__:null,getLogger:function(){return oe(this.state.initialized),this.logger},healthCheck:async function(){oe(this.state.initialized),await this.state.healthCheck.check()},trackEvent:function(e,t,r=!1,i=!1){return oe(this.state.initialized),this.state.analytics.track(e,this.state.wfDeviceId?.DeviceID,t,r,i)}}),standdown:Object.freeze({__proto__:null,hasAffiliation:function(e,t){if(!this.state.wildfireService)return this.logger.warn("Wildfire service not initialized yet"),!1;const r=this.state.wildfireService.hasAffilliation(e,t);return r&&this.logger.info("WF Affiliation identified"),r},isCustomStandownMatch:function(e){const t=e.some((e=>this.getConfig().customStandownPolicy?.urlRegex?.some((t=>!!e&&function(e,t){return new RegExp(t).test(e)}(e,t)))));return t&&this.logger.info("Custom Standown identified"),t},shouldStandDown:async function(e,t){oe(this.state.initialized);const r=new URL(t);if(!await this.state.partnerFilter(r.hostname))return this.logger.info("Should standdown due to partner filter."),!0;if(this.getConfig().merchantExclusions.some((t=>t.mutePopups&&e===t.domain)))return this.logger.info("Should standdown due to merchant exclusions"),!0;const i=await this.state.wildfireService.shouldStandDown(this.logger,e,t);return i&&this.logger.info("Should standdown due to vendor policy"),i},updateStanddownHistory:function(e){return oe(this.state.initialized),X(e)}}),identity:Object.freeze({__proto__:null,getCurrentUser:function(){return oe(this.state.initialized),this.state.giveFreelyUserService.user},getLanguage:async function(e){return oe(this.state.initialized),Ee(this.logger,this.state.partnerApiKey,e,this.state.config?.configRefreshInterval,this.state.config?.ignoredLanguages)},initializeWfDeviceId:async function(){if(oe(this.state.initialized),this.state.wfDeviceId=await this.state.wildfireService.getDevice(),!this.state.wfDeviceId)throw new Error("Failed to initialize Wildfire device ID");return this.state.wfDeviceId.DeviceID},upsertUser:function(e,t){return oe(this.state.initialized),this.state.giveFreelyUserService.upsertUser(e,t)}})};class ke{constructor(e){this.partnerApiKey=e,this.cleanupListeners=null,this.initialize=Oe.bind(this),this.isInitialized=Pe.bind(this),this.getConfig=Ue.config.getConfig.bind(this),this.getCachedConfig=Ue.config.getCachedConfig.bind(this),this.onConfigChange=Ue.config.onConfigChange.bind(this),this.onceConfigChange=Ue.config.onceConfigChange.bind(this),this.offConfigChange=Ue.config.offConfigChange.bind(this),this.getLogger=Ue.observability.getLogger.bind(this),this.healthCheck=Ue.observability.healthCheck.bind(this),this.trackEvent=Ue.observability.trackEvent.bind(this),this.initializeWfDeviceId=Ue.identity.initializeWfDeviceId.bind(this),this.upsertUser=Ue.identity.upsertUser.bind(this),this.getCurrentUser=Ue.identity.getCurrentUser.bind(this),this.getLanguage=Ue.identity.getLanguage.bind(this),this.getActiveDomains=Ue.merchants.getActiveDomains.bind(this),this.generateAffiliateUrl=Ue.merchants.generateAffiliateUrl.bind(this),this.getMerchantRates=Ue.merchants.getMerchantRates.bind(this),this.shouldStandDown=Ue.standdown.shouldStandDown.bind(this),this.updateStanddownHistory=Ue.standdown.updateStanddownHistory.bind(this),this.hasAffiliation=Ue.standdown.hasAffiliation.bind(this),this.isCustomStandownMatch=Ue.standdown.isCustomStandownMatch.bind(this),this.dependencies={configService:new G(e)},this.logger=o.getInstance(),this.logger.configure({enabled:!0,title:"Background - GiveFreelyService"}),this.state=(e=>({initialized:!1,wildfireService:null,partnerFilter:null,config:null,wfDeviceId:null,analytics:null,giveFreelyUserService:null,partnerApiKey:e,healthCheck:null}))(e)}async destroy(){var e;this.logger.info("Destroying GiveFreelyService"),await Promise.all([this.dependencies.configService.clearCache(),this.state.wildfireService?.clearCache(),this.state.giveFreelyUserService?.resetUser()]),this.cleanupListeners&&(this.cleanupListeners(),this.logger.info("Event listeners cleared."),this.cleanupListeners=null),this.state=(e=this.state,{...e,initialized:!1,wildfireService:null,partnerFilter:null,analytics:null,config:null})}}exports.GiveFreelyService=class{constructor(e){this.partnerApiKey=e,this.initialize=e=>this._adUnitService.initialize(e),this.destroy=()=>this._adUnitService.destroy(),this._adUnitService=new ke(e)}},exports.browser=browser,exports.isAdUnitMessage=e=>ce.exists(e);
1
+ "use strict";function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var t={exports:{}};"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self&&self,function(e){if(!(globalThis.chrome&&globalThis.chrome.runtime&&globalThis.chrome.runtime.id))throw new Error("This script should only be loaded in a browser extension.");if(globalThis.browser&&globalThis.browser.runtime&&globalThis.browser.runtime.id)e.exports=globalThis.browser;else{const t="The message port closed before a response was received.",r=e=>{const r={alarms:{clear:{minArgs:0,maxArgs:1},clearAll:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getAll:{minArgs:0,maxArgs:0}},bookmarks:{create:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},getChildren:{minArgs:1,maxArgs:1},getRecent:{minArgs:1,maxArgs:1},getSubTree:{minArgs:1,maxArgs:1},getTree:{minArgs:0,maxArgs:0},move:{minArgs:2,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeTree:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}},browserAction:{disable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},enable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},getBadgeBackgroundColor:{minArgs:1,maxArgs:1},getBadgeText:{minArgs:1,maxArgs:1},getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},openPopup:{minArgs:0,maxArgs:0},setBadgeBackgroundColor:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setBadgeText:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},browsingData:{remove:{minArgs:2,maxArgs:2},removeCache:{minArgs:1,maxArgs:1},removeCookies:{minArgs:1,maxArgs:1},removeDownloads:{minArgs:1,maxArgs:1},removeFormData:{minArgs:1,maxArgs:1},removeHistory:{minArgs:1,maxArgs:1},removeLocalStorage:{minArgs:1,maxArgs:1},removePasswords:{minArgs:1,maxArgs:1},removePluginData:{minArgs:1,maxArgs:1},settings:{minArgs:0,maxArgs:0}},commands:{getAll:{minArgs:0,maxArgs:0}},contextMenus:{remove:{minArgs:1,maxArgs:1},removeAll:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},cookies:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:1,maxArgs:1},getAllCookieStores:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},devtools:{inspectedWindow:{eval:{minArgs:1,maxArgs:2,singleCallbackArg:!1}},panels:{create:{minArgs:3,maxArgs:3,singleCallbackArg:!0},elements:{createSidebarPane:{minArgs:1,maxArgs:1}}}},downloads:{cancel:{minArgs:1,maxArgs:1},download:{minArgs:1,maxArgs:1},erase:{minArgs:1,maxArgs:1},getFileIcon:{minArgs:1,maxArgs:2},open:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},pause:{minArgs:1,maxArgs:1},removeFile:{minArgs:1,maxArgs:1},resume:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},extension:{isAllowedFileSchemeAccess:{minArgs:0,maxArgs:0},isAllowedIncognitoAccess:{minArgs:0,maxArgs:0}},history:{addUrl:{minArgs:1,maxArgs:1},deleteAll:{minArgs:0,maxArgs:0},deleteRange:{minArgs:1,maxArgs:1},deleteUrl:{minArgs:1,maxArgs:1},getVisits:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1}},i18n:{detectLanguage:{minArgs:1,maxArgs:1},getAcceptLanguages:{minArgs:0,maxArgs:0}},identity:{launchWebAuthFlow:{minArgs:1,maxArgs:1}},idle:{queryState:{minArgs:1,maxArgs:1}},management:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},getSelf:{minArgs:0,maxArgs:0},setEnabled:{minArgs:2,maxArgs:2},uninstallSelf:{minArgs:0,maxArgs:1}},notifications:{clear:{minArgs:1,maxArgs:1},create:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:0},getPermissionLevel:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},pageAction:{getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},hide:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},permissions:{contains:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},request:{minArgs:1,maxArgs:1}},runtime:{getBackgroundPage:{minArgs:0,maxArgs:0},getPlatformInfo:{minArgs:0,maxArgs:0},openOptionsPage:{minArgs:0,maxArgs:0},requestUpdateCheck:{minArgs:0,maxArgs:0},sendMessage:{minArgs:1,maxArgs:3},sendNativeMessage:{minArgs:2,maxArgs:2},setUninstallURL:{minArgs:1,maxArgs:1}},sessions:{getDevices:{minArgs:0,maxArgs:1},getRecentlyClosed:{minArgs:0,maxArgs:1},restore:{minArgs:0,maxArgs:1}},storage:{local:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},managed:{get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1}},sync:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}}},tabs:{captureVisibleTab:{minArgs:0,maxArgs:2},create:{minArgs:1,maxArgs:1},detectLanguage:{minArgs:0,maxArgs:1},discard:{minArgs:0,maxArgs:1},duplicate:{minArgs:1,maxArgs:1},executeScript:{minArgs:1,maxArgs:2},get:{minArgs:1,maxArgs:1},getCurrent:{minArgs:0,maxArgs:0},getZoom:{minArgs:0,maxArgs:1},getZoomSettings:{minArgs:0,maxArgs:1},goBack:{minArgs:0,maxArgs:1},goForward:{minArgs:0,maxArgs:1},highlight:{minArgs:1,maxArgs:1},insertCSS:{minArgs:1,maxArgs:2},move:{minArgs:2,maxArgs:2},query:{minArgs:1,maxArgs:1},reload:{minArgs:0,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeCSS:{minArgs:1,maxArgs:2},sendMessage:{minArgs:2,maxArgs:3},setZoom:{minArgs:1,maxArgs:2},setZoomSettings:{minArgs:1,maxArgs:2},update:{minArgs:1,maxArgs:2}},topSites:{get:{minArgs:0,maxArgs:0}},webNavigation:{getAllFrames:{minArgs:1,maxArgs:1},getFrame:{minArgs:1,maxArgs:1}},webRequest:{handlerBehaviorChanged:{minArgs:0,maxArgs:0}},windows:{create:{minArgs:0,maxArgs:1},get:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:1},getCurrent:{minArgs:0,maxArgs:1},getLastFocused:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}}};if(0===Object.keys(r).length)throw new Error("api-metadata.json has not been included in browser-polyfill");class i extends WeakMap{constructor(e,t=void 0){super(t),this.createItem=e}get(e){return this.has(e)||this.set(e,this.createItem(e)),super.get(e)}}const s=(t,r)=>(...i)=>{e.runtime.lastError?t.reject(new Error(e.runtime.lastError.message)):r.singleCallbackArg||i.length<=1&&!1!==r.singleCallbackArg?t.resolve(i[0]):t.resolve(i)},n=e=>1==e?"argument":"arguments",a=(e,t,r)=>new Proxy(t,{apply:(t,i,s)=>r.call(i,e,...s)});let o=Function.call.bind(Object.prototype.hasOwnProperty);const c=(e,t={},r={})=>{let i=Object.create(null),l={has:(t,r)=>r in e||r in i,get(l,g,h){if(g in i)return i[g];if(!(g in e))return;let d=e[g];if("function"==typeof d)if("function"==typeof t[g])d=a(e,e[g],t[g]);else if(o(r,g)){let t=((e,t)=>function(r,...i){if(i.length<t.minArgs)throw new Error(`Expected at least ${t.minArgs} ${n(t.minArgs)} for ${e}(), got ${i.length}`);if(i.length>t.maxArgs)throw new Error(`Expected at most ${t.maxArgs} ${n(t.maxArgs)} for ${e}(), got ${i.length}`);return new Promise(((n,a)=>{if(t.fallbackToNoCallback)try{r[e](...i,s({resolve:n,reject:a},t))}catch(s){console.warn(`${e} API method doesn't seem to support the callback parameter, falling back to call it without a callback: `,s),r[e](...i),t.fallbackToNoCallback=!1,t.noCallback=!0,n()}else t.noCallback?(r[e](...i),n()):r[e](...i,s({resolve:n,reject:a},t))}))})(g,r[g]);d=a(e,e[g],t)}else d=d.bind(e);else if("object"==typeof d&&null!==d&&(o(t,g)||o(r,g)))d=c(d,t[g],r[g]);else{if(!o(r,"*"))return Object.defineProperty(i,g,{configurable:!0,enumerable:!0,get:()=>e[g],set(t){e[g]=t}}),d;d=c(d,t[g],r["*"])}return i[g]=d,d},set:(t,r,s,n)=>(r in i?i[r]=s:e[r]=s,!0),defineProperty:(e,t,r)=>Reflect.defineProperty(i,t,r),deleteProperty:(e,t)=>Reflect.deleteProperty(i,t)},g=Object.create(e);return new Proxy(g,l)},l=e=>({addListener(t,r,...i){t.addListener(e.get(r),...i)},hasListener:(t,r)=>t.hasListener(e.get(r)),removeListener(t,r){t.removeListener(e.get(r))}}),g=new i((e=>"function"!=typeof e?e:function(t){const r=c(t,{},{getContent:{minArgs:0,maxArgs:0}});e(r)})),h=new i((e=>"function"!=typeof e?e:function(t,r,i){let s,n,a=!1,o=new Promise((e=>{s=function(t){a=!0,e(t)}}));try{n=e(t,r,s)}catch(e){n=Promise.reject(e)}const c=!0!==n&&((l=n)&&"object"==typeof l&&"function"==typeof l.then);var l;if(!0!==n&&!c&&!a)return!1;return(c?n:o).then((e=>{i(e)}),(e=>{let t;t=e&&(e instanceof Error||"string"==typeof e.message)?e.message:"An unexpected error occurred",i({__mozWebExtensionPolyfillReject__:!0,message:t})})).catch((e=>{console.error("Failed to send onMessage rejected reply",e)})),!0})),d=({reject:r,resolve:i},s)=>{e.runtime.lastError?e.runtime.lastError.message===t?i():r(new Error(e.runtime.lastError.message)):s&&s.__mozWebExtensionPolyfillReject__?r(new Error(s.message)):i(s)},u=(e,t,r,...i)=>{if(i.length<t.minArgs)throw new Error(`Expected at least ${t.minArgs} ${n(t.minArgs)} for ${e}(), got ${i.length}`);if(i.length>t.maxArgs)throw new Error(`Expected at most ${t.maxArgs} ${n(t.maxArgs)} for ${e}(), got ${i.length}`);return new Promise(((e,t)=>{const s=d.bind(null,{resolve:e,reject:t});i.push(s),r.sendMessage(...i)}))},f={devtools:{network:{onRequestFinished:l(g)}},runtime:{onMessage:l(h),onMessageExternal:l(h),sendMessage:u.bind(null,"sendMessage",{minArgs:1,maxArgs:3})},tabs:{sendMessage:u.bind(null,"sendMessage",{minArgs:2,maxArgs:3})}},m={clear:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}};return r.privacy={network:{"*":m},services:{"*":m},websites:{"*":m}},c(e,f,r)};e.exports=r(chrome)}}(t);var r,i,browser=e(t.exports);class s{constructor(){this.isLocal=!0}log({level:e,message:t,timestamp:r,data:i,title:n}){let a;switch(e){case"debug":default:a="log";break;case"info":a="info";break;case"warn":a="warn";break;case"error":case"critical":case"fatal":a="error"}const o=n?`[${n}]`:"";void 0!==i?console[a](`[${r}] - ${s.LOGGER_PREFIX} ${o} ${t}`,i):console[a](`[${r}] - ${s.LOGGER_PREFIX} ${o} ${t}`)}}s.LOGGER_PREFIX="[GFAdUnit] -",function(e){e.checkoutPopupShown="CHECKOUT-POPUP-SHOWN",e.checkoutPopupNotShown="CHECKOUT-POPUP-NOT-SHOWN",e.checkoutPopupSupressed="CHECKOUT-POPUP-SUPRESSED",e.checkoutPopupDonation="CHECKOUT-POPUP-DONATION",e.checkoutPopupFailedActivation="CHECKOUT-POPUP-FAILED-ACTIVATION",e.checkoutPopupPurchaseConfirmed="CHECKOUT-POPUP-PURCHASE-CONFIRMED",e.checkoutPopupHealthCheck="CHECKOUT-POPUP-HEALTH-CHECK",e.checkouPopupActivationFailed="CHECKOUT-POPUP-ACTIVATION-FAILED",e.checkoutPopupOfferDetailsClicked="CHECKOUT-POPUP-OFFER-DETAILS-CLICKED",e.checkoutPopupWhyAmISeeingThisClicked="CHECKOUT-POPUP-WHY-AM-I-SEEING-THIS-CLICKED",e.checkoutPopupLooserExtension="CHECKOUT-POPUP-LOOSER-EXTENSION",e.checkoutPopupActiveDomain="CHECKOUT-POPUP-ACTIVE-DOMAIN",e.checkoutPopupSiteMatches="CHECKOUT-POPUP-SITE-MATCHES",e.checkoutPopupMerchantInResultsFound="CHECKOUT-MERCHANT-IN-RESULTS-FOUND"}(r||(r={})),function(e){e.adUnitLog="ADUNIT-LOG"}(i||(i={}));class n{constructor(e){this.isLocal=!1,this.backgroundService=e}log({level:e,message:t,data:r,title:s}){this.backgroundService.trackEvent(i.adUnitLog,{log:{level:e,message:t,data:r,title:s}})}}const a=["debug","info","warn","error","critical","fatal"];class o{constructor(e){this.config={minLevel:e?.minLevel??"debug",enabled:e?.enabled??!1,transports:e?.transports??[new s],title:e?.title??""}}static getInstance(e){return o.instance||(o.instance=new o(e)),o.instance}configure(e){this.config={...this.config,...e}}shouldLog(e){return!!this.config.enabled&&a.indexOf(e)>=a.indexOf(this.config.minLevel)}createLogMessage(e,t,r){return{level:e,version:"1.17.5",message:t,timestamp:(new Date).toISOString(),data:r,title:this.config.title}}log(e,t,r,i){if(!this.shouldLog(e))return;const s=this.createLogMessage(e,t,i);this.config.transports.filter((e=>!r||e.isLocal)).forEach((e=>e.log(s)))}debug(e,t,r=!1){this.log("debug",e,r,t)}info(e,t,r=!1){this.log("info",e,r,t)}warn(e,t,r=!1){this.log("warn",e,r,t)}error(e,t,r=!1){this.log("error",e,r,t)}critical(e,t,r=!1){this.log("critical",e,r,t)}fatal(e,t,r=!1){this.log("fatal",e,r,t)}addTransport(e){this.config.transports.push(e)}clearTransports(){this.config.transports=[]}disable(){this.config.enabled=!1}enable(){this.config.enabled=!0}}const c=3,l=e=>1e3*e;async function g(e,t={},r){const{maxAttempts:i=c,delayFn:s=l}=t;let n=null;for(let t=1;t<=i;t+=1)try{return await e()}catch(e){n=e,t<i&&await new Promise((e=>{setTimeout(e,s(t))}))}if(n&&t.logger&&t.operationName&&t.logger.error(`Operation ${t.operationName} failed after ${i} attempts.`,n,!0),void 0!==r)return r;throw n||new Error("Operation failed after multiple attempts")}const h=browser,d={TRACK_EVENT:"GF_TRACK_EVENT",HIDE_POPUP:"GF_HIDE_POPUP",GET_POPUP_CONFIG:"GF_GET_POPUP_CONFIG",IS_ACTIVE_DOMAIN:"GF_IS_ACTIVE_DOMAIN",LOG_MERCHANTS_IN_SEARCH_RESULTS:"GF_LOG_MERCHANTS_IN_SEARCH_RESULTS",SHOULD_STAND_DOWN:"GF_SHOULD_STAND_DOWN",ACTIVATE_OFFER:"GF_ACTIVATE_OFFER",STORE_SHOPIFY_SHOP_ID:"GF_STORE_SHOPIFY_SHOP_ID",GET_DOMAIN_BY_SHOP_ID:"GF_GET_DOMAIN_BY_SHOP_ID",GET_LANGUAGE_CONTENT:"GF_GET_LANGUAGE_CONTENT"},u="shopify_shop_ids",f="gf_last_health_check",m="gf_partner_config",p="gf_global_config",A="countryCode",y="version",w="gf_anonymous_user_info",v="gf_anonymous_encrypted_token",C="gf_ad_event_history",S="wfDevice",b="wfDomains",E="wfStanddownPolicy",I="wfStanddownHistory",T="wfMerchantRates",x="en",_="GIVE_FREELY_",O={async get(e){const t=`${_}${e}`;return(await browser.storage.local.get(t))[t]||null},async set(e,t){const r=`${_}${e}`;await browser.storage.local.set({[r]:t})},async remove(e){const t=Array.isArray(e)?e.map((e=>`${_}${e}`)):`${_}${e}`;await browser.storage.local.remove(t)}},P=()=>String("1.17.5"),D=async(e=!0)=>{const t=await O.get(y),r=await P(),i=t!==r;var s;return e&&i&&await(s=r,O.set(y,s)),i},F=o.getInstance(),U={async get(e,t,r,i=!1,s){let n=await O.get(e);const a=n;let o=!1,c=r??n?.retentionInSeconds??600;if(n&&Date.now()<=n.lastFetch+1e3*c&&!i)return{content:n.content,isStale:o};try{const r=await t(),i=s?s(r):null;null!=i&&(c=i),n=await this.set(e,r,c)}catch(e){F.error("Error getting cached value",{error:e}),o=!0}return{content:n?.content??a?.content,isStale:o}},async set(e,t,r){const i=r??600,s={content:t,lastFetch:Date.now(),retentionInSeconds:i};return await O.set(e,s),s},async clear(e){await O.remove(e)}};class k{constructor(){this.listeners=new Map,this.wildcardListeners=new Set}on(e,t){return this.addListener(e,t,!1)}once(e,t){return this.addListener(e,t,!0)}off(e,t){if(!t)return this.listeners.delete(e),void(this.wildcardListeners=new Set(Array.from(this.wildcardListeners).filter((t=>t.pattern!==e))));if(e.includes("*"))this.wildcardListeners=new Set(Array.from(this.wildcardListeners).filter((r=>!(r.pattern===e&&r.callback===t))));else{const r=this.listeners.get(e);if(r){const i=Array.from(r).filter((e=>e.callback!==t));i.length>0?this.listeners.set(e,new Set(i)):this.listeners.delete(e)}}}emit(e){const t=this.listeners.get(e.path)||new Set,r=new Set;for(const e of t)r.add(e);for(const t of this.wildcardListeners)this.matchesPattern(e.path,t.pattern)&&r.add(t);for(const t of r)t.callback(e),t.once&&this.removeListener(t)}clear(){this.listeners.clear(),this.wildcardListeners.clear()}addListener(e,t,r){const i={pattern:e,callback:t,once:r};if(e.includes("*"))this.wildcardListeners.add(i);else{const t=this.listeners.get(e);t?t.add(i):this.listeners.set(e,new Set([i]))}return()=>this.off(e,t)}removeListener(e){if(e.pattern.includes("*"))this.wildcardListeners.delete(e);else{const t=this.listeners.get(e.pattern);t&&(t.delete(e),0===t.size&&this.listeners.delete(e.pattern))}}matchesPattern(e,t){if("*"===t)return!0;const r=t.split(".").map((e=>"*"===e?"[^.]+":"**"===e?".*":e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"))).join("\\.");return new RegExp(`^${r}$`).test(e)}}function L(e,t,r=""){const i=[];if(e===t)return i;if(R(e)||R(t))return e!==t&&i.push({path:r||"root",oldValue:e,newValue:t}),i;if(Array.isArray(e)&&Array.isArray(t))return JSON.stringify(e)!==JSON.stringify(t)&&i.push({path:r||"root",oldValue:e,newValue:t}),i;if(N(e)&&N(t)){const s=e,n=t,a=new Set([...Object.keys(s),...Object.keys(n)]);for(const e of a){const t=r?`${r}.${e}`:e,a=s[e],o=n[e];if(e in s)if(e in n){const e=L(a,o,t);i.push(...e)}else i.push({path:t,oldValue:a,newValue:void 0});else i.push({path:t,oldValue:void 0,newValue:o})}}else e!==t&&i.push({path:r||"root",oldValue:e,newValue:t});return i}function R(e){return null==e||"object"!=typeof e}function N(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}var $;!function(e){e.CLOSED="CLOSED",e.OPEN="OPEN",e.HALF_OPEN="HALF_OPEN"}($||($={}));class M{constructor(e={}){this.state=$.CLOSED,this.failures=[],this.lastFailureTime=0,this.halfOpenCalls=0,this.logger=o.getInstance({minLevel:"warn"}),this.options={failureThreshold:5,recoveryTimeout:6e4,monitoringWindow:3e5,halfOpenMaxCalls:3,storageKey:"circuit_breaker_state",...e},this.storageKey=this.options.storageKey}async initialize(){await this.loadFromStorage()}static async create(e={}){const t=new M(e);return await t.initialize(),t}async loadFromStorage(){try{if("undefined"!=typeof chrome&&chrome.storage&&chrome.storage.local){const e=(await chrome.storage.local.get(this.storageKey))[this.storageKey];e&&(this.state=e.state,this.failures=e.failures||[],this.lastFailureTime=e.lastFailureTime||0,this.halfOpenCalls=e.halfOpenCalls||0,this.cleanupOldFailures())}else if("undefined"!=typeof localStorage){const e=localStorage.getItem(this.storageKey);if(e){const t=JSON.parse(e);this.state=t.state,this.failures=t.failures||[],this.lastFailureTime=t.lastFailureTime||0,this.halfOpenCalls=t.halfOpenCalls||0,this.cleanupOldFailures()}}}catch(e){this.logger.warn("Failed to load circuit breaker state from storage:",e)}}async saveToStorage(){try{const e={state:this.state,failures:this.failures,lastFailureTime:this.lastFailureTime,halfOpenCalls:this.halfOpenCalls};"undefined"!=typeof chrome&&chrome.storage&&chrome.storage.local?await chrome.storage.local.set({[this.storageKey]:e}):"undefined"!=typeof localStorage&&localStorage.setItem(this.storageKey,JSON.stringify(e))}catch(e){this.logger.warn("Failed to save circuit breaker state to storage:",e)}}cleanupOldFailures(){const e=Date.now();this.failures=this.failures.filter((t=>e-t.timestamp<=this.options.monitoringWindow))}async execute(e,t){if(this.state===$.OPEN){if(!this.shouldAttemptRecovery()){if(t)return t();throw new Error("Circuit breaker is OPEN - service temporarily unavailable")}this.state=$.HALF_OPEN,this.halfOpenCalls=0,await this.saveToStorage()}if(this.state===$.HALF_OPEN){if(this.halfOpenCalls>=this.options.halfOpenMaxCalls)throw new Error("Circuit breaker HALF_OPEN call limit exceeded");this.halfOpenCalls+=1,await this.saveToStorage()}try{const t=await e();return await this.onSuccess(),t}catch(e){throw await this.onFailure(e),e}}async onSuccess(){this.state===$.HALF_OPEN&&(this.state=$.CLOSED,this.failures=[],await this.saveToStorage())}async onFailure(e){const t=Date.now();this.lastFailureTime=t,this.failures.push({timestamp:t,error:e.message}),this.failures=this.failures.filter((e=>t-e.timestamp<=this.options.monitoringWindow)),this.failures.length>=this.options.failureThreshold&&(this.state=$.OPEN),await this.saveToStorage()}shouldAttemptRecovery(){return Date.now()-this.lastFailureTime>=this.options.recoveryTimeout}getState(){return this.state}getFailureCount(){const e=Date.now();return this.failures.filter((t=>e-t.timestamp<=this.options.monitoringWindow)).length}async reset(){this.state=$.CLOSED,this.failures=[],this.lastFailureTime=0,this.halfOpenCalls=0,await this.saveToStorage()}async clearStorage(){"undefined"!=typeof chrome&&chrome.storage&&chrome.storage.local?await chrome.storage.local.remove(this.storageKey):"undefined"!=typeof localStorage&&localStorage.removeItem(this.storageKey)}getStatus(){return{state:this.state,failureCount:this.getFailureCount(),nextAttemptTime:this.state===$.OPEN?this.lastFailureTime+this.options.recoveryTimeout:null}}}const H="https://cdn.givefreely.com/adunit/behavioral/";class G{constructor(e){this.partnerApiKey=e,this.partnerConfig=null,this.globalConfig=null,this.mergedConfig=null,this.globalConfigRefreshInterval=null,this.partnerConfigRefreshInterval=null,this.eventEmitter=new k,this.isInitialized=!1,this.partnerCircuitBreaker=new M({failureThreshold:3,recoveryTimeout:6e4,monitoringWindow:3e5,storageKey:`gf_partner_circuit_breaker_${e}`}),this.globalCircuitBreaker=new M({failureThreshold:3,recoveryTimeout:6e4,monitoringWindow:3e5,storageKey:"gf_global_circuit_breaker"})}async initialize(){this.isInitialized||(await Promise.all([this.partnerCircuitBreaker.initialize(),this.globalCircuitBreaker.initialize()]),this.isInitialized=!0)}ensureInitialized(){if(!this.isInitialized)throw new Error("GiveFreelyConfigService must be initialized before use. Call initialize() or use create() method.")}getRetryOptions(){return{delayFn:e=>1e3*e,maxAttempts:3}}async fetchPartnerConfig(){const e=await g((async()=>{const e=await fetch(`${H}${this.partnerApiKey}.json`,{cache:"no-store"});if(!e.ok)throw new Error(`Failed to fetch partner config: ${e.statusText}`);return e.json()}),this.getRetryOptions());if(!e)throw new Error("Failed to fetch or get from cache partner config");return this.partnerConfigRefreshInterval=e.configRefreshInterval||this.partnerConfigRefreshInterval,e}async fetchGlobalConfig(){const e=await g((async()=>{const e=await fetch(`${H}global.json`,{cache:"no-store"});if(!e.ok)throw new Error(`Failed to fetch global config => Status code: ${e.status} .${e.statusText}`);return e.json()}),this.getRetryOptions());if(!e)throw new Error("Failed to fetch or get from cache global config",e);return this.globalConfigRefreshInterval=e.configRefreshInterval||this.globalConfigRefreshInterval,e}async getCachedConfig(){return this.mergedConfig}async getConfig(e=!1){this.ensureInitialized();let t=!1;e&&(t=await D());const[r,i]=await Promise.all([U.get(m,this.fetchPartnerConfig.bind(this),this.partnerConfigRefreshInterval,t,(e=>e?.configRefreshInterval??null)),U.get(p,this.fetchGlobalConfig.bind(this),this.globalConfigRefreshInterval,t,(e=>e?.configRefreshInterval??null))]);if(!i.content)throw new Error("Global config is required");if(!r.content)throw new Error("Partner config is required");this.partnerConfig=r.content,this.globalConfig=i.content;const s=this.mergeConfigs(JSON.parse(JSON.stringify(this.globalConfig)),JSON.parse(JSON.stringify(this.partnerConfig)));if(!s)throw new Error("Was not able to merge configs");return((e,t,r)=>{const i=[...t.merchantExclusions??[],...r.merchantExclusions??[]];e.merchantExclusions=i})(s,this.globalConfig,this.partnerConfig),this.emitConfigChanges(s),s}async clearCache(){this.ensureInitialized(),await Promise.all([U.clear(m),U.clear(p)]),this.partnerConfig=null,this.globalConfig=null,this.mergedConfig=null,this.eventEmitter.clear(),await Promise.all([this.partnerCircuitBreaker.reset(),this.globalCircuitBreaker.reset()])}getCircuitBreakerStatus(){return this.ensureInitialized(),{partner:this.partnerCircuitBreaker.getStatus(),global:this.globalCircuitBreaker.getStatus()}}mergeConfigs(e,t){if(!t)return e;if(!e)return t;const r={...e};return Object.keys(t).forEach((i=>{if(!Object.prototype.hasOwnProperty.call(t,i))return;const s=e[i],n=t[i];void 0!==n&&(Array.isArray(n)?r[i]=[...n]:r[i]=null===n||"object"!=typeof n||null===s||"object"!=typeof s?n:this.mergeConfigs(s,n))})),r}on(e,t){return this.eventEmitter.on(e,t)}once(e,t){return this.eventEmitter.once(e,t)}off(e,t){this.eventEmitter.off(e,t)}emitConfigChanges(e){if(!this.mergedConfig)return this.mergedConfig=e,void this.eventEmitter.emit({path:"root",oldValue:null,newValue:e,config:e});const t=L(this.mergedConfig,e);for(const r of t)this.eventEmitter.emit({path:r.path,oldValue:r.oldValue,newValue:r.newValue,config:e});this.mergedConfig=e}}class z{constructor(e,t,r,i=60){this.track=async(e,t,r,i=!1,s=!1)=>{const n={partner:`adUnit_${this._partnerApiKey}`,eventType:e,eventData:{userId:i?void 0:this._userService?.user?.id,libVersion:P(),wfDeviceId:t,...r}};try{const e=JSON.stringify(n,((e,t)=>t instanceof Error?{name:t.name,message:t.message,stack:t.stack}:t)),t=await this.getEventsUrl();return t?await this.BroadcastEvent(t,e,n,s):(this._logger.info("Cant broadcast event. eventsUrl cant be retrieved from config",n,!0),!1)}catch(e){return this._logger.error("Something unexpected happened when dispatching a gf event",{error:e,event:n},!0),!1}},this.getEventsHistory=async()=>{const e=await O.get(C),t=(e=>{const t=new Date;return t.setTime(t.getTime()+60*e*1e3),t.getTime()})(-this._debounceWindowInMinutes),r=(e||[]).filter((e=>e.createdAt>t));return await O.set(C,r),r},this.shouldBroadcastEvent=async(e,t)=>!!t||!(await this.getEventsHistory()).some((t=>t.payload===e)),this.pushEventToHistory=async e=>{const t=await this.getEventsHistory();t.push({createdAt:Date.now(),payload:e}),await O.set(C,t)},this._partnerApiKey=e,this._userService=t,this._debounceWindowInMinutes=i,this._logger=o.getInstance({title:"Analytics"}),this._configService=r}async BroadcastEvent(e,t,r,i){if(await this.shouldBroadcastEvent(t,i)){const i=await fetch(e,{headers:{"Content-Type":"application/json"},method:"POST",body:t,cache:"no-store"});return i.ok?(await this.pushEventToHistory(t),!0):(this._logger.error("Something unexpected happened when dispatching an event",{status:i.status,statusText:i.statusText,event:r},!0),!1)}return this._logger.info("This event has already been broadcasted during the past hour",r,!0),!1}async getEventsUrl(){const e=await this._configService.getCachedConfig();return e?.eventsUrl}}z.trackEvent=async(e,t,r=!1,i=!1)=>{await async function(e){return await h.runtime.sendMessage(e)}({type:d.TRACK_EVENT,payload:{eventType:e,eventData:t,anonymous:r,skipThrottling:i}})};class j{constructor(e,t){this.lastCheck=null,this.trackEvent=e,this.logger=t}async initialize(){const e=await O.get(f);e&&(this.lastCheck=e)}getToday(){return(new Date).toISOString().split("T")[0]}async check(){try{const e=this.lastCheck??0,t=this.getToday();(e?new Date(e).toISOString().split("T")[0]:null)!==t&&(this.lastCheck=Date.now(),await O.set(f,this.lastCheck),await this.trackEvent(r.checkoutPopupHealthCheck,{language:browser.i18n.getUILanguage()}))}catch(e){this.logger.error("Health check failed",{error:e instanceof Error?e.message:"Unknown error"},!0)}}}var W;!function(e){e[e.Pending=0]="Pending",e[e.Ready=1]="Ready",e[e.Received=2]="Received",e[e.Donated=3]="Donated",e[e.Disqualified=4]="Disqualified"}(W||(W={}));class K{constructor(e,t,r){this.adUnitId=e,this.config=t,this.logger=r}async getAnonymousUserCommissions(e,t){try{const r=new URLSearchParams(t).toString(),i=await fetch(`${this.config.apiConfig.baseUri}/${this.config.apiConfig.getAnonymousUserComissionsPath}?${r}`,{method:"GET",headers:{"Content-Type":"application/json","X-AnonymousUserToken":e}});if(!i.ok)throw new Error(`Failed to fetch commissions. Status code: ${i.status} .${i.statusText}`);return await i.json()}catch(e){throw this.logger.error("[GiveFreelyApiClient] Error fetching anonymous user's commissions:",{error:e}),e}}async createOrUpdateAnonymousUser(e,t){try{const r=await fetch(`${this.config.apiConfig.baseUri}/${this.config.apiConfig.createAnonymousUserPath}?adUnitId=${this.adUnitId}`,{method:"PUT",headers:{"Content-Type":"application/json","X-GF-Platform":"adUnitLibrary","X-AnonymousUserToken":t??""},body:JSON.stringify(e)});if(!r.ok)throw this.logger.error(`Failed to create/update anonymous user. Status code: ${r.status}. ${r.statusText}`),new Error(`Failed to create/update anonymous user. Status code: ${r.status}. ${r.statusText}`);this.logger.info("[GiveFreelyApiClient] anonymous user created/updated successfully.");const i=await r.json(),s=r.headers.get("X-AnonymousUserToken");return{resultUser:{...i,charity:{ein:i.selectedCharity,thirdPartyId:i.selectedCharityThirdPartyIdentifier,name:void 0}},resultToken:s}}catch(e){throw this.logger.error("[GiveFreelyApiClient] Error creating anonymous user:",{error:e},!0),e}}}class B{constructor(e,t){this._giveFreelyApiClient=e,this._logger=t,this.user=null}async resetUser(){await O.remove(v),await O.remove(w)}async upsertUser(e,t){let r=await this.fetchUser();try{const i={selectedCharity:e?.ein,selectedCharityThirdPartyIdentifier:e?.thirdPartyId,deviceId:t};if(!await this.shouldCreateOrUpdateUser(r,i))return r;const s=await O.get(v),{resultUser:n,resultToken:a}=await this._giveFreelyApiClient.createOrUpdateAnonymousUser(i,s);a&&await O.set(v,a),n&&(await O.set(w,n),r=n)}catch(e){this._logger.error("Error creating/updating anonymous user:",e)}return this.user=r,r}async fetchUser(){const e=await O.get(w);return this.user=e,e}async shouldCreateOrUpdateUser(e,t){return!e||e.charity?.ein!==t.selectedCharity||e.charity?.thirdPartyId!==t.selectedCharityThirdPartyIdentifier||e.deviceId!==t.deviceId}}class V{constructor(e,t,r,i,s){this.wfSecret=e,this.wfAppId=t,this.deviceUrl=r,this.dataUrl=i,this._logger=s}async getWildfireDevice(){try{const e=await fetch(this.deviceUrl,{method:"POST",body:JSON.stringify({}),headers:{"Content-Type":"application/json","WF-Secret":this.wfSecret,"WF-App-ID":this.wfAppId}});if(e.ok)return e.json();throw new Error(`Failed to fetch Wildfire device from ${this.deviceUrl}. Status ${e.status}. ${e.statusText}`)}catch(e){throw this._logger.error("Failed to fetch the Wildfire device",{err:e}),e}}async getActiveDomains(){try{const e=`${this.dataUrl}/${this.wfAppId}/active-domain/1`,t=await fetch(e);if(t.ok)return t.json();throw new Error(`Failed to fetch active domains from ${e}. Status ${t.status}. ${t.statusText}`)}catch(e){throw this._logger.error("Failed to fetch the active domains",{err:e}),e}}async getStanddownPolicy(){const e=`${this.dataUrl}/${this.wfAppId}/stand-down-policy/1`;try{const t=await fetch(e);if(t.ok)return t.json();throw new Error(`Failed to fetch standdown policy from ${e}. Status ${t.status}. ${t.statusText}`)}catch(t){throw this._logger.error("Failed to fetch the standdown policy",{err:t,url:e}),t}}async getMerchantRates(){const e=`${this.dataUrl}/${this.wfAppId}/merchant-rate/1`;try{const t=await fetch(e);if(this._logger.debug("Merchant rates response",{response:t}),!t.ok)throw new Error(`Failed to fetch merchant rates from ${e}. Status ${t.status}. ${t.statusText}`);const r=t.json();return this._logger.debug("Merchant rates",{rates:r}),r}catch(t){throw this._logger.error("Failed to fetch the merchant rates",{err:t,url:e}),t}}}async function q(e,t,r){try{const i=(await J())?.[t];if(i&&i>Date.now())return e.info("Standing down because current affiliate stand down session has not expired"),X(t),!0;await this.refreshCache();const s=await this.getStanddownPolicy();if(Q(s,new URL(r).search))return e.info("Standing down because url has affiliate params"),X(t),!0;e.info("No need to stand down.")}catch(t){e.error("Exception produced when trying to determine if it should stand down",t)}return!1}function Y(e,t){if(!this.standDownPolicy)return this.logger.warn("Couldnt check affilliation. No stand down policy found"),this.getStanddownPolicy().then((e=>{this.standDownPolicy=e})),!1;const r=e.some((e=>Z(this.standDownPolicy,e)))||Q(this.standDownPolicy,t);return this.logger.info("Affilliation result:",r),r}const J=async()=>O.get(I),X=async(e,t=1)=>{const r=await J()??{};r[e]=Date.now()+60*t*60*1e3,await O.set(I,r)},Z=(e,t)=>{if(!t)return!1;const{Domains:r}=e;return r.some((e=>t.includes(e)))},Q=(e,t)=>{if(!t)return!1;const{Params:r}=e;return r.some((e=>t.toLowerCase().includes(`?${e.toLowerCase()}`)))||r.some((e=>t.toLowerCase().includes(`&${e.toLowerCase()}`)))};class ee{constructor(e,t,r,i){this.userId=e,this.charityEin=t,this.charityThirdPartyIdentifier=r,this.partnerId=i}toString(){return`userId=${this.encodeUserId(this.userId)},charityEin=${this.charityEin},charityThirdPartyIdentifier=${this.charityThirdPartyIdentifier},partnerId=${this.partnerId}`}encodeUserId(e){return btoa(e).replace(/_/g,"/").replace(/-/g,"+")}}class te{constructor(e,t,r,i=21600){if(this.standDownPolicy=null,this.shouldStandDown=q.bind(this),this.hasAffilliation=Y.bind(this),!e||!r)throw new Error("WildfireService requires wildfireClient and vanityBaseUrl");this.wildfireClient=e,this.vanityBaseUrl=r.replace(/\/$/,""),this.refreshInterval=i,this.logger=t}async getActiveDomains(e=!1){try{const t=(await U.get(b,(async()=>this.fetchActiveDomains()),this.refreshInterval,e)).content;if(!t)throw Error("Failed to retrieve active domains");return t}catch(e){throw this.logger.error("Failed to get active domains:",e),new Error("Failed to retrieve active domains")}}async getMerchantRates(e,t=!1){try{const r=await U.get(T,(async()=>this.fetchMerchantRates()),this.refreshInterval,t);if(!r.content)throw new Error("Failed to retrieve merchant rates from cache");return r.content[e]}catch(e){throw this.logger.error("Failed to retrieve merchant rates:",e),new Error("Failed to retrieve merchant rates")}}async generateAffiliateUrl(e,t,r,i){if(!e||!t||!i)throw new Error("Missing required parameters for affiliate URL generation");try{const s=await this.getDevice(),n=await this.generateTrackingCode(r,i,s),a=encodeURIComponent(t),o=encodeURIComponent(n);return`${this.vanityBaseUrl}/e?d=${s.DeviceID}&c=${e.ID}&tc=${o}&url=${a}`}catch(e){throw this.logger.error("Failed to generate affiliate URL:",e),new Error("Failed to generate affiliate URL")}}async clearCache(){try{await Promise.all([U.clear(b),U.clear(E),U.clear(T)])}catch(e){throw this.logger.error("Failed to clear cache:",e),new Error("Failed to clear cache")}}async clearDevice(){try{await O.remove(S),this.logger.info("Cleared wildfire device ID")}catch(e){throw this.logger.error("Failed to clear wildfire device:",e),new Error("Failed to clear wildfire device")}}async refreshCache(e=!1){try{const[,t]=await Promise.all([U.get(b,(()=>this.fetchActiveDomains()),this.refreshInterval,e),U.get(E,(()=>this.fetchStanddownPolicy()),this.refreshInterval,e),U.get(T,(()=>this.fetchMerchantRates()),this.refreshInterval,e)]);t?.content&&(this.standDownPolicy=t.content)}catch(e){throw this.logger.error("Failed to refresh cache:",e),new Error("Failed to refresh cache")}}async getStanddownPolicy(){try{const e=await U.get(E,(async()=>this.fetchStanddownPolicy()),this.refreshInterval);if(!e.content)throw new Error("Failed to retrieve standdown policy from cache");return this.logger.info("Retrieved standdown policy from cache",e.content),this.standDownPolicy=e.content,this.standDownPolicy}catch(e){throw this.logger.error("Failed to get standdown policy from cache:",e),new Error("Failed to retrieve standdown policy")}}getRetryOptions(e){return{delayFn:e=>1e3*e,maxAttempts:3,logger:this.logger,operationName:e}}async getDevice(){try{const e=await O.get(S);return e?.DeviceID?e:g((()=>this.fetchAndStoreDevice()),this.getRetryOptions("Get Device"))}catch(e){throw this.logger.error("Failed to get device:",e),new Error("Failed to retrieve device information")}}async fetchAndStoreDevice(){const e=await this.wildfireClient.getWildfireDevice();if(!e?.DeviceID)throw new Error("Failed to retrieve device information");return await O.set(S,e),e}async generateTrackingCode(e,t,r){if(!(e?.id&&e?.charity&&e?.charity.ein&&e?.charity.thirdPartyId)){const e=`notregistered-${r.DeviceID}`;return this.logger.info("User not provided. Using GF's default bucket instead.",e),e}return new ee(e.id,e.charity.ein,e.charity.thirdPartyId,t).toString()}async fetchActiveDomains(){const e=await g((()=>this.wildfireClient.getActiveDomains()),this.getRetryOptions("Fetch Active Domains"));return this.logger.info("Updated active domains"),e}async fetchStanddownPolicy(){const e=await g((()=>this.wildfireClient.getStanddownPolicy()),this.getRetryOptions("Get Standdown policy"),{Domains:[],LostAttribution:[],Params:[],Serp:[]});return this.logger.info("Updated standdown policy"),e}async fetchMerchantRates(){const e=await g((()=>this.wildfireClient.getMerchantRates()),this.getRetryOptions("Fetch Merchant Rates"),{});return this.logger.debug("Updated Merchant rates"),e}static async createWildfireService(e,t){e.debug("Initializing wildfire service with config",t);const r=new V(t.wfSecret,t.wfAppId,t.deviceUrl,t.dataUrl,e),i=new te(r,e,t.vanityBaseUrl,t.refreshInterval),s=await D();return await i.refreshCache(s),i}}const re=e=>{try{return new URL(e),!0}catch{return!1}},ie=new Set,se=new Set,ne={urls:["<all_urls>"],types:["main_frame"]};class ae extends Error{constructor(e="Service not initialized"){super(e),this.name="UninitializedServiceError"}}const oe=e=>{if(!e)throw new ae};class ce{static register(e,t){this.strategies.set(e,t)}static get(e){return this.strategies.get(e)}static exists(e){return!!function(e){return"object"==typeof e&&null!==e&&"type"in e&&"payload"in e&&"string"==typeof e.type}(e)&&this.knownMessageTypes.has(e.type)}}ce.strategies=new Map,ce.knownMessageTypes=new Set([...Object.values(d)]);const le=e=>{let t;if(browser.webRequest){const r=(e=>{const t=e.getLogger();return({requestId:r,url:i,initiator:s})=>{try{if(ie.has(r)||se.has(r)||!re(i))return;const{hostname:n,search:a}=new URL(i);if(n.includes("wild.link"))return t.info("Cashback activation request identified, ignoring affiliate check for request"),void se.add(r);let o;s&&re(s)&&(o=new URL(s).hostname),(e.hasAffiliation([n,o],a)||e.isCustomStandownMatch([i,s]))&&(t.info("Affiliation found or custom standown match on url, adding request id to track"),ie.add(r))}catch(e){t.error("Error on handleAffiliateOnBeforeRequest",e)}}})(e);browser.webRequest.onBeforeRequest.addListener(r,ne);const i=(e=>{const t=e.getLogger();return async({requestId:r,redirectUrl:i})=>{try{if(!ie.has(r))return;t.info("Attempting to find active domain");const{hostname:s}=new URL(i),n=(await e.getActiveDomains()).find((e=>s===e.Domain||s.endsWith(`.${e.Domain}`)));if(!n)return;t.info("Found active domain. Updating standdown state"),await X(n.Domain)}catch(e){t.error("Error on handleAffiliateOnBeforeRedirect",e)}}})(e);browser.webRequest.onBeforeRedirect.addListener(i,ne);const s=(e=>{const t=e.getLogger();return({requestId:e})=>{try{ie.has(e)&&(t.info("Tracking request completed. Request Id:",e),ie.delete(e))}catch(e){t.error("Error on handleAffiliateOnCompleted",e)}}})(e);browser.webRequest.onCompleted.addListener(s,ne),t=()=>{browser.webRequest.onBeforeRequest.removeListener(r),browser.webRequest.onBeforeRedirect.removeListener(i),browser.webRequest.onCompleted.removeListener(s)}}const r=function(){const t=o.getInstance(),r=(r,i,s)=>{function n(e){s(e)}const a=(async t=>(e.getLogger().debug("Received message",{type:t.type,payload:t.payload}),ge(e,t)))(r,0);return a instanceof Promise?(a.then((e=>{e&&n(e)})).catch((e=>{t.warn("Async message callback error:",e)})),!0):!0===a||void 0};return h.runtime.onMessage.addListener(r),r}();return function(){t&&t(),browser.runtime.onMessage.removeListener(r)}},ge=async(e,t)=>{oe(e.isInitialized());const r=ce.get(t.type);if(!r)return;const i={giveFreelyService:e};return r.handle(t,i)};class he{async handle(e,t){const{activeDomain:i,originalUrl:s,selectedCharity:n}=e.payload,{giveFreelyService:a}=t,o=a.getLogger();o.debug("Activating offer",{activeDomain:i,selectedCharity:n});try{if(!n?.ein||!n?.thirdPartyId)throw new Error("Missing charity information");const e=await a.initializeWfDeviceId();if(!e)throw new Error("Failed to initialize Wildfire device ID");const t=await a.upsertUser(n,e);o.debug("Upserted user",{currentUser:t}),t||o.info("Failed to create user. Using default bucket's user");const r=await a.generateAffiliateUrl(i,s,t);return o.debug("Generated affiliate URL",{affiliateUrl:r}),(async e=>{const t=h.tabs.getCurrent(),r=await t,i=await h.tabs.create({url:e,openerTabId:r?.id,active:!1,pinned:!0});await(async e=>new Promise((t=>{h.tabs.onUpdated.addListener((async function r(i,s){if(i===e&&"complete"===s.status){if(h.tabs.onUpdated.removeListener(r),!(await h.tabs.get(e)).url)return void t(!1);t(!0)}}))})))(i.id)&&setTimeout((()=>{i?.id&&h.tabs.remove(i.id)}),3e4)})(r),await a.updateStanddownHistory(i.Domain),o.debug("Activated offer",{activeDomain:i,selectedCharity:n}),{type:d.ACTIVATE_OFFER,payload:{response:!0}}}catch(e){return o.error("Error activating offer",{activeDomain:i,error:e}),a.trackEvent(r.checkoutPopupFailedActivation,{activeDomain:i,error:e}),{type:d.ACTIVATE_OFFER,payload:{response:!1}}}}}class de{async handle(e,t){const{shopId:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger();try{const e=u,t=(await O.get(e)||[]).find((e=>e.shopId===r));return t?(s.debug("Found domain for shop ID",{shopId:r,domain:t.domain}),{type:d.GET_DOMAIN_BY_SHOP_ID,payload:{found:!0,domain:t.domain,shopInfo:t}}):(s.debug("No domain found for shop ID",{shopId:r}),{type:d.GET_DOMAIN_BY_SHOP_ID,payload:{found:!1}})}catch(e){return s.error("Error getting domain for shop ID",{shopId:r,error:e}),{type:d.GET_DOMAIN_BY_SHOP_ID,payload:{found:!1}}}}}class ue{async handle(e,t){const{lang:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger();s.debug("Getting language strings",{lang:r});try{const e=await i.getLanguage(r);return s.debug("Language strings fetched",{language:e}),{type:d.GET_LANGUAGE_CONTENT,payload:{translations:e.translations,charities:e.charities}}}catch(e){return s.error("Error getting language strings",{error:e}),{type:d.GET_LANGUAGE_CONTENT,payload:{translations:null,charities:null}}}}}class fe{async handle(e,t){const{giveFreelyService:r}=t,i=r.getLogger(),s=await r.getCachedConfig();try{return i.debug("Fetching popup config"),{type:d.GET_POPUP_CONFIG,payload:{config:s}}}catch(e){return i.error("Error fetching popup config",{error:e}),{type:d.GET_POPUP_CONFIG,payload:{config:null}}}}}class me{async handle(e,t){const{days:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger();try{const e=new Date;return e.setDate(e.getDate()+r),await O.set("popup_hide",{popupHide:e.getTime()}),s.debug("Popup hidden",{days:r,expiry:e}),{type:d.HIDE_POPUP,payload:{ack:!0}}}catch(e){return s.error("Error hiding popup",{days:r,error:e}),{type:d.HIDE_POPUP,payload:{ack:!1}}}}}class pe{async handle(e,t){const{hostname:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger(),n=await i.getConfig().merchantExclusions,a=await i.getActiveDomains();s.debug("Checking hostname",{hostname:r});try{if(i.healthCheck(),n.some((e=>e.disableDomain&&(r===e.domain||r.endsWith(`.${e.domain}`)))))return s.debug("Hostname is in merchant exclusions",{hostname:r}),{type:d.IS_ACTIVE_DOMAIN,payload:{isActive:!1,domain:void 0,rates:[]}};if(!a||0===a.length)throw new Error("No active domains");s.debug("Retrieved active domains",{count:a.length});const e=a.find((e=>r===e.Domain||r.endsWith(`.${e.Domain}`)));s.debug("Domain check result",{hostname:r,isActive:!!e});let t=[];if(e?.ID){const r=await i.getMerchantRates(e.Merchant.ID);r&&(s.debug("Retrieved merchant rates",{merchantRates:r}),t=r)}return{type:d.IS_ACTIVE_DOMAIN,payload:{isActive:!!e,domain:e,rates:t}}}catch(e){return s.error("Error checking domain",{hostname:r,error:e}),{type:d.IS_ACTIVE_DOMAIN,payload:{isActive:!1,domain:void 0,rates:[]}}}}}class Ae{async handle(e,t){const{currentUrl:i,searchResults:s,source:n}=e.payload,{giveFreelyService:a}=t,o=a.getLogger(),c=await a.getActiveDomains();o.debug("Finding merchants in search results",{currentUrl:i});try{const e=s.filter((e=>{try{const{hostname:t}=new URL(e.url);return c.some((e=>e.Domain===t||t.endsWith(`.${e.Domain}`)))}catch{return o.debug("Couldn't parse the following search result url",{x:e}),!1}}));if(o.info("Number of merchants identified in the search result",{number:e.length}),e.length>0){const s=Math.floor(Math.random()*Date.now());for(const a of e)t.giveFreelyService.trackEvent(r.checkoutPopupMerchantInResultsFound,{source:n,searchResultsId:s,currentUrl:i,searchResultUrl:a.url,sponsored:a.isSponsored},!0)}return{type:d.LOG_MERCHANTS_IN_SEARCH_RESULTS,payload:{result:!0}}}catch(e){return o.error("Error sending logs for merchants in search results",{currentUrl:i,error:e}),{type:d.LOG_MERCHANTS_IN_SEARCH_RESULTS,payload:{result:!1}}}}}class ye{async handle(e,t){const r=e.payload,{giveFreelyService:i}=t,s=i.getLogger();try{const e=u,t=await O.get(e)||[],i=t.findIndex((e=>e.shopId===r.shopId));return i>=0?t[i]=r:t.push(r),await O.set(e,t),s.debug("Stored Shopify shop ID",{shopInfo:r}),{type:d.STORE_SHOPIFY_SHOP_ID,payload:{success:!0}}}catch(e){return s.error("Error storing Shopify shop ID",{shopInfo:r,error:e}),{type:d.STORE_SHOPIFY_SHOP_ID,payload:{success:!1}}}}}class we{async handle(e,t){const{activeDomain:r,url:i}=e.payload,{giveFreelyService:s}=t,n=s.getLogger();n.debug("Checking if we should stand down",{activeDomain:r});try{const e=await s.shouldStandDown(r,i);return{type:d.SHOULD_STAND_DOWN,payload:{result:e}}}catch(e){return n.error("Error checking if we should stand down. Returning false",{activeDomain:r,error:e}),{type:d.SHOULD_STAND_DOWN,payload:{result:!1}}}}}class ve{async handle(e,t){const{eventType:r,eventData:i,anonymous:s,skipThrottling:n}=e.payload,{giveFreelyService:a}=t,o=a.getLogger();o.debug("Broadcasting event",{eventType:r,eventData:i,anonymous:s,skipThrottling:n});try{const e=await a.trackEvent(r,i,s,n);return{type:d.TRACK_EVENT,payload:{result:e}}}catch(e){return o.error("Error broadcasting event. Returning false",{eventType:r,eventData:i,error:e}),{type:d.TRACK_EVENT,payload:{result:!1}}}}}const Ce=o.getInstance(),Se=async()=>await O.get(A)||(async()=>{Ce.debug("detecting country");const e={method:"GET",headers:{"Content-Type":"application/json",Authorization:"Basic OTEzOTkxOnFlYmpaWF9DOGNRY0lxSHA4WTVjNGxzU1pRSlM2VW9MMExzTF9tbWs="}};try{const t=await fetch("https://geoip.maxmind.com/geoip/v2.1/country/me",e);if(Ce.debug("Received geolocation response",{status:t.status}),!t.ok)return void Ce.error("Failed to get geolocation data",{status:t.status,statusText:t.statusText});const r=await t.json();if(!r)throw new Error("There was an error fetching geoip look up");return await O.set(A,r.country.iso_code),r.country.iso_code}catch(e){return void Ce.error("Failed to get geolocation data",{error:e},!0)}})(),be="https://cdn.givefreely.com/adunit/language",Ee=async(e,t,r,i,s=[],n=!1)=>{const a=(s??[]).includes(r)?x:r;e.debug(`Requested lang ${r} and current lang ${a}`);const o=`lang-${x}`,c=await U.get(o,(async()=>(e.debug(`Fetching default language ${x} for partner ${t}`),Ie(t,x))),i||600,n);if(!c.content)throw new Error(`Failed to fetch default language ${x} and no cache version available`);if(x===a)return c.content;const l=`lang-${a}`,g=await U.get(l,(async()=>(e.debug(`Fetching language ${a} for partner ${t}`),Ie(t,a))),i||600,n);if(!g.content)return c.content;const h=_e(c.content,g.content);return await U.set(l,h,i||600),h},Ie=async(e,t)=>{const r=`/global-${t}.json`,i=`/${e}/${t}.json`,[s,n]=await Promise.allSettled([Te(`${be}${r}`),Te(`${be}${i}`)]);let a,o;"fulfilled"===s.status&&(a=s.value),"fulfilled"===n.status&&(o=n.value);const c=xe(a,o);return{translations:c.translations,charities:c.charities}},Te=async e=>{const t=await fetch(e,{cache:"no-store"});if(!t.ok)throw new Error(`Failed to fetch partner language file ${e}. Status: ${t.status}. Reason: ${t.statusText}`);return t.json()},xe=(e,t)=>({translations:{...e?.translations??{},...t??{}},charities:{...e?.charities??{}}}),_e=(e,t)=>({translations:{...e.translations,...t.translations},charities:{...e.charities,...t.charities}});async function Oe(e=async()=>(this.logger.debug("Using default partnerFilter."),!0)){if(!this.state.initialized){this.logger.info("Starting initialization with mutex protection");try{await this.dependencies.configService.initialize();const t=await this.dependencies.configService.getConfig(!0);this.logger.configure({enabled:t.loggingEnabled??!0,minLevel:t.backgroundMinLogLevel??"error"}),this.logger.info("Initializing GiveFreelyService",{partnerApiKey:this.partnerApiKey});const r=await te.createWildfireService(this.logger,t);this.state.healthCheck=new j(this.trackEvent.bind(this),this.logger),await this.state.healthCheck.initialize();const i=new K(this.partnerApiKey,t,this.logger);this.state.giveFreelyUserService=new B(i,this.logger),await this.state.giveFreelyUserService.fetchUser(),this.state.giveFreelyUserService.user?.id||await this.state.giveFreelyUserService.upsertUser(),this.state.analytics=new z(this.partnerApiKey,this.state.giveFreelyUserService,this.dependencies.configService);try{const e=await O.get(S);e?.DeviceID?(this.state.wfDeviceId=e,this.logger.info("Loaded existing wfDeviceId from storage",{deviceId:e.DeviceID})):this.logger.debug("No existing wfDeviceId found in storage - will be created on first offer activation")}catch(e){this.logger.debug("Could not check for existing wfDeviceId in storage",e)}ce.register(d.IS_ACTIVE_DOMAIN,new pe),ce.register(d.GET_POPUP_CONFIG,new fe),ce.register(d.HIDE_POPUP,new me),ce.register(d.SHOULD_STAND_DOWN,new we),ce.register(d.TRACK_EVENT,new ve),ce.register(d.ACTIVATE_OFFER,new he),ce.register(d.STORE_SHOPIFY_SHOP_ID,new ye),ce.register(d.GET_DOMAIN_BY_SHOP_ID,new de),ce.register(d.GET_LANGUAGE_CONTENT,new ue),ce.register(d.LOG_MERCHANTS_IN_SEARCH_RESULTS,new Ae),await(async e=>{try{await Se()}catch(t){e.debug("Failed to get geolocation data",{error:t})}})(this.logger),await(async(e,t,r)=>{t.purgeLanguages&&t.purgeLanguages.length>0&&await Promise.all(t.purgeLanguages.flatMap((e=>[U.clear(`lang-${e}`),U.clear(`global-${e}`)]))),g((async()=>{e.debug("Initializing default language with partner API key",{partnerApiKey:r}),await Ee(e,r,x,t.configRefreshInterval)}))})(this.logger,t,this.partnerApiKey),this.state=((e,t)=>{const{wildfireService:r,partnerFilter:i,config:s}=t;return{...e,initialized:!0,wildfireService:r,partnerFilter:i,config:s}})(this.state,{wildfireService:r,partnerFilter:e,config:t}),this.logger.addTransport(new n(this)),this.cleanupListeners=le(this),De.call(this),this.logger.info("GiveFreelyService initialized successfully")}catch(e){const t=e instanceof Error?e.message:"Unknown error";throw this.logger.error("Failed to initialize GiveFreelyService",{error:t}),new Error(`Failed to initialize GiveFreelyService: ${t}`)}}}function Pe(){return this.state.initialized}function De(){this.onConfigChange("wfAppId",(async e=>{this.logger.info(`Wildfire App ID changed from ${e.oldValue} to ${e.newValue} - clearing device`),await Fe.call(this)})),this.onConfigChange("wfSecret",(async e=>{this.logger.info("Wildfire Secret changed - clearing device"),await Fe.call(this)}))}async function Fe(){try{this.state.wildfireService&&(await this.state.wildfireService.clearDevice(),this.state.wfDeviceId=null,this.logger.info("Wildfire device cleared due to config change"))}catch(e){this.logger.error("Failed to clear wildfire device:",e)}}var Ue={config:Object.freeze({__proto__:null,getCachedConfig:async function(){return oe(this.state.initialized),this.state.config=await this.dependencies.configService.getConfig(),this.logger.configure({minLevel:this.state.config.backgroundMinLogLevel??"error"}),this.state.config},getConfig:function(){return oe(this.state.initialized),this.state.config},offConfigChange:function(e,t){oe(this.state.initialized),this.dependencies.configService.off(e,t)},onConfigChange:function(e,t){return oe(this.state.initialized),this.dependencies.configService.on(e,t)},onceConfigChange:function(e,t){return oe(this.state.initialized),this.dependencies.configService.once(e,t)}}),merchants:Object.freeze({__proto__:null,generateAffiliateUrl:async function(e,t,r){return oe(this.state.initialized),this.state.wildfireService.generateAffiliateUrl(e,t,r,this.state.partnerApiKey)},getActiveDomains:async function(){return oe(this.state.initialized),this.state.wildfireService.getActiveDomains()},getMerchantRates:async function(e){if(oe(this.state.initialized),!this.state.wildfireService)throw new Error("Wildfire service not initialized");return this.state.wildfireService.getMerchantRates(e)}}),observability:Object.freeze({__proto__:null,getLogger:function(){return oe(this.state.initialized),this.logger},healthCheck:async function(){oe(this.state.initialized),await this.state.healthCheck.check()},trackEvent:function(e,t,r=!1,i=!1){return oe(this.state.initialized),this.state.analytics.track(e,this.state.wfDeviceId?.DeviceID,t,r,i)}}),standdown:Object.freeze({__proto__:null,hasAffiliation:function(e,t){if(!this.state.wildfireService)return this.logger.warn("Wildfire service not initialized yet"),!1;const r=this.state.wildfireService.hasAffilliation(e,t);return r&&this.logger.info("WF Affiliation identified"),r},isCustomStandownMatch:function(e){const t=e.some((e=>this.getConfig().customStandownPolicy?.urlRegex?.some((t=>!!e&&function(e,t){return new RegExp(t).test(e)}(e,t)))));return t&&this.logger.info("Custom Standown identified"),t},shouldStandDown:async function(e,t){oe(this.state.initialized);const r=new URL(t);if(!await this.state.partnerFilter(r.hostname))return this.logger.info("Should standdown due to partner filter."),!0;if(this.getConfig().merchantExclusions.some((t=>t.mutePopups&&e===t.domain)))return this.logger.info("Should standdown due to merchant exclusions"),!0;const i=await this.state.wildfireService.shouldStandDown(this.logger,e,t);return i&&this.logger.info("Should standdown due to vendor policy"),i},updateStanddownHistory:function(e){return oe(this.state.initialized),X(e)}}),identity:Object.freeze({__proto__:null,getCurrentUser:function(){return oe(this.state.initialized),this.state.giveFreelyUserService.user},getLanguage:async function(e){return oe(this.state.initialized),Ee(this.logger,this.state.partnerApiKey,e,this.state.config?.configRefreshInterval,this.state.config?.ignoredLanguages)},initializeWfDeviceId:async function(){if(oe(this.state.initialized),this.state.wfDeviceId=await this.state.wildfireService.getDevice(),!this.state.wfDeviceId)throw new Error("Failed to initialize Wildfire device ID");return this.state.wfDeviceId.DeviceID},upsertUser:function(e,t){return oe(this.state.initialized),this.state.giveFreelyUserService.upsertUser(e,t)}})};class ke{constructor(e){this.partnerApiKey=e,this.cleanupListeners=null,this.initialize=Oe.bind(this),this.isInitialized=Pe.bind(this),this.getConfig=Ue.config.getConfig.bind(this),this.getCachedConfig=Ue.config.getCachedConfig.bind(this),this.onConfigChange=Ue.config.onConfigChange.bind(this),this.onceConfigChange=Ue.config.onceConfigChange.bind(this),this.offConfigChange=Ue.config.offConfigChange.bind(this),this.getLogger=Ue.observability.getLogger.bind(this),this.healthCheck=Ue.observability.healthCheck.bind(this),this.trackEvent=Ue.observability.trackEvent.bind(this),this.initializeWfDeviceId=Ue.identity.initializeWfDeviceId.bind(this),this.upsertUser=Ue.identity.upsertUser.bind(this),this.getCurrentUser=Ue.identity.getCurrentUser.bind(this),this.getLanguage=Ue.identity.getLanguage.bind(this),this.getActiveDomains=Ue.merchants.getActiveDomains.bind(this),this.generateAffiliateUrl=Ue.merchants.generateAffiliateUrl.bind(this),this.getMerchantRates=Ue.merchants.getMerchantRates.bind(this),this.shouldStandDown=Ue.standdown.shouldStandDown.bind(this),this.updateStanddownHistory=Ue.standdown.updateStanddownHistory.bind(this),this.hasAffiliation=Ue.standdown.hasAffiliation.bind(this),this.isCustomStandownMatch=Ue.standdown.isCustomStandownMatch.bind(this),this.dependencies={configService:new G(e)},this.logger=o.getInstance(),this.logger.configure({enabled:!0,title:"Background - GiveFreelyService"}),this.state=(e=>({initialized:!1,wildfireService:null,partnerFilter:null,config:null,wfDeviceId:null,analytics:null,giveFreelyUserService:null,partnerApiKey:e,healthCheck:null}))(e)}async destroy(){var e;this.logger.info("Destroying GiveFreelyService"),await Promise.all([this.dependencies.configService.clearCache(),this.state.wildfireService?.clearCache(),this.state.giveFreelyUserService?.resetUser()]),this.cleanupListeners&&(this.cleanupListeners(),this.logger.info("Event listeners cleared."),this.cleanupListeners=null),this.state=(e=this.state,{...e,initialized:!1,wildfireService:null,partnerFilter:null,analytics:null,config:null})}}exports.GiveFreelyService=class{constructor(e){this.partnerApiKey=e,this.initialize=e=>this._adUnitService.initialize(e),this.destroy=()=>this._adUnitService.destroy(),this._adUnitService=new ke(e)}},exports.browser=browser,exports.isAdUnitMessage=e=>ce.exists(e);
2
2
  //# sourceMappingURL=GiveFreely-background.cjs.js.map
@@ -1,2 +1,2 @@
1
- function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var t={exports:{}};"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self&&self,function(e){if(!(globalThis.chrome&&globalThis.chrome.runtime&&globalThis.chrome.runtime.id))throw new Error("This script should only be loaded in a browser extension.");if(globalThis.browser&&globalThis.browser.runtime&&globalThis.browser.runtime.id)e.exports=globalThis.browser;else{const t="The message port closed before a response was received.",r=e=>{const r={alarms:{clear:{minArgs:0,maxArgs:1},clearAll:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getAll:{minArgs:0,maxArgs:0}},bookmarks:{create:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},getChildren:{minArgs:1,maxArgs:1},getRecent:{minArgs:1,maxArgs:1},getSubTree:{minArgs:1,maxArgs:1},getTree:{minArgs:0,maxArgs:0},move:{minArgs:2,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeTree:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}},browserAction:{disable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},enable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},getBadgeBackgroundColor:{minArgs:1,maxArgs:1},getBadgeText:{minArgs:1,maxArgs:1},getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},openPopup:{minArgs:0,maxArgs:0},setBadgeBackgroundColor:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setBadgeText:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},browsingData:{remove:{minArgs:2,maxArgs:2},removeCache:{minArgs:1,maxArgs:1},removeCookies:{minArgs:1,maxArgs:1},removeDownloads:{minArgs:1,maxArgs:1},removeFormData:{minArgs:1,maxArgs:1},removeHistory:{minArgs:1,maxArgs:1},removeLocalStorage:{minArgs:1,maxArgs:1},removePasswords:{minArgs:1,maxArgs:1},removePluginData:{minArgs:1,maxArgs:1},settings:{minArgs:0,maxArgs:0}},commands:{getAll:{minArgs:0,maxArgs:0}},contextMenus:{remove:{minArgs:1,maxArgs:1},removeAll:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},cookies:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:1,maxArgs:1},getAllCookieStores:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},devtools:{inspectedWindow:{eval:{minArgs:1,maxArgs:2,singleCallbackArg:!1}},panels:{create:{minArgs:3,maxArgs:3,singleCallbackArg:!0},elements:{createSidebarPane:{minArgs:1,maxArgs:1}}}},downloads:{cancel:{minArgs:1,maxArgs:1},download:{minArgs:1,maxArgs:1},erase:{minArgs:1,maxArgs:1},getFileIcon:{minArgs:1,maxArgs:2},open:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},pause:{minArgs:1,maxArgs:1},removeFile:{minArgs:1,maxArgs:1},resume:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},extension:{isAllowedFileSchemeAccess:{minArgs:0,maxArgs:0},isAllowedIncognitoAccess:{minArgs:0,maxArgs:0}},history:{addUrl:{minArgs:1,maxArgs:1},deleteAll:{minArgs:0,maxArgs:0},deleteRange:{minArgs:1,maxArgs:1},deleteUrl:{minArgs:1,maxArgs:1},getVisits:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1}},i18n:{detectLanguage:{minArgs:1,maxArgs:1},getAcceptLanguages:{minArgs:0,maxArgs:0}},identity:{launchWebAuthFlow:{minArgs:1,maxArgs:1}},idle:{queryState:{minArgs:1,maxArgs:1}},management:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},getSelf:{minArgs:0,maxArgs:0},setEnabled:{minArgs:2,maxArgs:2},uninstallSelf:{minArgs:0,maxArgs:1}},notifications:{clear:{minArgs:1,maxArgs:1},create:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:0},getPermissionLevel:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},pageAction:{getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},hide:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},permissions:{contains:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},request:{minArgs:1,maxArgs:1}},runtime:{getBackgroundPage:{minArgs:0,maxArgs:0},getPlatformInfo:{minArgs:0,maxArgs:0},openOptionsPage:{minArgs:0,maxArgs:0},requestUpdateCheck:{minArgs:0,maxArgs:0},sendMessage:{minArgs:1,maxArgs:3},sendNativeMessage:{minArgs:2,maxArgs:2},setUninstallURL:{minArgs:1,maxArgs:1}},sessions:{getDevices:{minArgs:0,maxArgs:1},getRecentlyClosed:{minArgs:0,maxArgs:1},restore:{minArgs:0,maxArgs:1}},storage:{local:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},managed:{get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1}},sync:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}}},tabs:{captureVisibleTab:{minArgs:0,maxArgs:2},create:{minArgs:1,maxArgs:1},detectLanguage:{minArgs:0,maxArgs:1},discard:{minArgs:0,maxArgs:1},duplicate:{minArgs:1,maxArgs:1},executeScript:{minArgs:1,maxArgs:2},get:{minArgs:1,maxArgs:1},getCurrent:{minArgs:0,maxArgs:0},getZoom:{minArgs:0,maxArgs:1},getZoomSettings:{minArgs:0,maxArgs:1},goBack:{minArgs:0,maxArgs:1},goForward:{minArgs:0,maxArgs:1},highlight:{minArgs:1,maxArgs:1},insertCSS:{minArgs:1,maxArgs:2},move:{minArgs:2,maxArgs:2},query:{minArgs:1,maxArgs:1},reload:{minArgs:0,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeCSS:{minArgs:1,maxArgs:2},sendMessage:{minArgs:2,maxArgs:3},setZoom:{minArgs:1,maxArgs:2},setZoomSettings:{minArgs:1,maxArgs:2},update:{minArgs:1,maxArgs:2}},topSites:{get:{minArgs:0,maxArgs:0}},webNavigation:{getAllFrames:{minArgs:1,maxArgs:1},getFrame:{minArgs:1,maxArgs:1}},webRequest:{handlerBehaviorChanged:{minArgs:0,maxArgs:0}},windows:{create:{minArgs:0,maxArgs:1},get:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:1},getCurrent:{minArgs:0,maxArgs:1},getLastFocused:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}}};if(0===Object.keys(r).length)throw new Error("api-metadata.json has not been included in browser-polyfill");class i extends WeakMap{constructor(e,t=void 0){super(t),this.createItem=e}get(e){return this.has(e)||this.set(e,this.createItem(e)),super.get(e)}}const s=(t,r)=>(...i)=>{e.runtime.lastError?t.reject(new Error(e.runtime.lastError.message)):r.singleCallbackArg||i.length<=1&&!1!==r.singleCallbackArg?t.resolve(i[0]):t.resolve(i)},n=e=>1==e?"argument":"arguments",a=(e,t,r)=>new Proxy(t,{apply:(t,i,s)=>r.call(i,e,...s)});let o=Function.call.bind(Object.prototype.hasOwnProperty);const c=(e,t={},r={})=>{let i=Object.create(null),l={has:(t,r)=>r in e||r in i,get(l,g,h){if(g in i)return i[g];if(!(g in e))return;let d=e[g];if("function"==typeof d)if("function"==typeof t[g])d=a(e,e[g],t[g]);else if(o(r,g)){let t=((e,t)=>function(r,...i){if(i.length<t.minArgs)throw new Error(`Expected at least ${t.minArgs} ${n(t.minArgs)} for ${e}(), got ${i.length}`);if(i.length>t.maxArgs)throw new Error(`Expected at most ${t.maxArgs} ${n(t.maxArgs)} for ${e}(), got ${i.length}`);return new Promise(((n,a)=>{if(t.fallbackToNoCallback)try{r[e](...i,s({resolve:n,reject:a},t))}catch(s){console.warn(`${e} API method doesn't seem to support the callback parameter, falling back to call it without a callback: `,s),r[e](...i),t.fallbackToNoCallback=!1,t.noCallback=!0,n()}else t.noCallback?(r[e](...i),n()):r[e](...i,s({resolve:n,reject:a},t))}))})(g,r[g]);d=a(e,e[g],t)}else d=d.bind(e);else if("object"==typeof d&&null!==d&&(o(t,g)||o(r,g)))d=c(d,t[g],r[g]);else{if(!o(r,"*"))return Object.defineProperty(i,g,{configurable:!0,enumerable:!0,get:()=>e[g],set(t){e[g]=t}}),d;d=c(d,t[g],r["*"])}return i[g]=d,d},set:(t,r,s,n)=>(r in i?i[r]=s:e[r]=s,!0),defineProperty:(e,t,r)=>Reflect.defineProperty(i,t,r),deleteProperty:(e,t)=>Reflect.deleteProperty(i,t)},g=Object.create(e);return new Proxy(g,l)},l=e=>({addListener(t,r,...i){t.addListener(e.get(r),...i)},hasListener:(t,r)=>t.hasListener(e.get(r)),removeListener(t,r){t.removeListener(e.get(r))}}),g=new i((e=>"function"!=typeof e?e:function(t){const r=c(t,{},{getContent:{minArgs:0,maxArgs:0}});e(r)})),h=new i((e=>"function"!=typeof e?e:function(t,r,i){let s,n,a=!1,o=new Promise((e=>{s=function(t){a=!0,e(t)}}));try{n=e(t,r,s)}catch(e){n=Promise.reject(e)}const c=!0!==n&&((l=n)&&"object"==typeof l&&"function"==typeof l.then);var l;if(!0!==n&&!c&&!a)return!1;return(c?n:o).then((e=>{i(e)}),(e=>{let t;t=e&&(e instanceof Error||"string"==typeof e.message)?e.message:"An unexpected error occurred",i({__mozWebExtensionPolyfillReject__:!0,message:t})})).catch((e=>{console.error("Failed to send onMessage rejected reply",e)})),!0})),d=({reject:r,resolve:i},s)=>{e.runtime.lastError?e.runtime.lastError.message===t?i():r(new Error(e.runtime.lastError.message)):s&&s.__mozWebExtensionPolyfillReject__?r(new Error(s.message)):i(s)},u=(e,t,r,...i)=>{if(i.length<t.minArgs)throw new Error(`Expected at least ${t.minArgs} ${n(t.minArgs)} for ${e}(), got ${i.length}`);if(i.length>t.maxArgs)throw new Error(`Expected at most ${t.maxArgs} ${n(t.maxArgs)} for ${e}(), got ${i.length}`);return new Promise(((e,t)=>{const s=d.bind(null,{resolve:e,reject:t});i.push(s),r.sendMessage(...i)}))},f={devtools:{network:{onRequestFinished:l(g)}},runtime:{onMessage:l(h),onMessageExternal:l(h),sendMessage:u.bind(null,"sendMessage",{minArgs:1,maxArgs:3})},tabs:{sendMessage:u.bind(null,"sendMessage",{minArgs:2,maxArgs:3})}},m={clear:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}};return r.privacy={network:{"*":m},services:{"*":m},websites:{"*":m}},c(e,f,r)};e.exports=r(chrome)}}(t);var r,i,browser=e(t.exports);class s{constructor(){this.isLocal=!0}log({level:e,message:t,timestamp:r,data:i,title:n}){let a;switch(e){case"debug":default:a="log";break;case"info":a="info";break;case"warn":a="warn";break;case"error":case"critical":case"fatal":a="error"}const o=n?`[${n}]`:"";void 0!==i?console[a](`[${r}] - ${s.LOGGER_PREFIX} ${o} ${t}`,i):console[a](`[${r}] - ${s.LOGGER_PREFIX} ${o} ${t}`)}}s.LOGGER_PREFIX="[GFAdUnit] -",function(e){e.checkoutPopupShown="CHECKOUT-POPUP-SHOWN",e.checkoutPopupNotShown="CHECKOUT-POPUP-NOT-SHOWN",e.checkoutPopupSupressed="CHECKOUT-POPUP-SUPRESSED",e.checkoutPopupDonation="CHECKOUT-POPUP-DONATION",e.checkoutPopupFailedActivation="CHECKOUT-POPUP-FAILED-ACTIVATION",e.checkoutPopupPurchaseConfirmed="CHECKOUT-POPUP-PURCHASE-CONFIRMED",e.checkoutPopupHealthCheck="CHECKOUT-POPUP-HEALTH-CHECK",e.checkouPopupActivationFailed="CHECKOUT-POPUP-ACTIVATION-FAILED",e.checkoutPopupOfferDetailsClicked="CHECKOUT-POPUP-OFFER-DETAILS-CLICKED",e.checkoutPopupWhyAmISeeingThisClicked="CHECKOUT-POPUP-WHY-AM-I-SEEING-THIS-CLICKED",e.checkoutPopupLooserExtension="CHECKOUT-POPUP-LOOSER-EXTENSION",e.checkoutPopupActiveDomain="CHECKOUT-POPUP-ACTIVE-DOMAIN",e.checkoutPopupSiteMatches="CHECKOUT-POPUP-SITE-MATCHES",e.checkoutPopupMerchantInResultsFound="CHECKOUT-MERCHANT-IN-RESULTS-FOUND"}(r||(r={})),function(e){e.adUnitLog="ADUNIT-LOG"}(i||(i={}));class n{constructor(e){this.isLocal=!1,this.backgroundService=e}log({level:e,message:t,data:r,title:s}){this.backgroundService.trackEvent(i.adUnitLog,{log:{level:e,message:t,data:r,title:s}})}}const a=["debug","info","warn","error","critical","fatal"];class o{constructor(e){this.config={minLevel:e?.minLevel??"debug",enabled:e?.enabled??!1,transports:e?.transports??[new s],title:e?.title??""}}static getInstance(e){return o.instance||(o.instance=new o(e)),o.instance}configure(e){this.config={...this.config,...e}}shouldLog(e){return!!this.config.enabled&&a.indexOf(e)>=a.indexOf(this.config.minLevel)}createLogMessage(e,t,r){return{level:e,version:"1.17.4",message:t,timestamp:(new Date).toISOString(),data:r,title:this.config.title}}log(e,t,r,i){if(!this.shouldLog(e))return;const s=this.createLogMessage(e,t,i);this.config.transports.filter((e=>!r||e.isLocal)).forEach((e=>e.log(s)))}debug(e,t,r=!1){this.log("debug",e,r,t)}info(e,t,r=!1){this.log("info",e,r,t)}warn(e,t,r=!1){this.log("warn",e,r,t)}error(e,t,r=!1){this.log("error",e,r,t)}critical(e,t,r=!1){this.log("critical",e,r,t)}fatal(e,t,r=!1){this.log("fatal",e,r,t)}addTransport(e){this.config.transports.push(e)}clearTransports(){this.config.transports=[]}disable(){this.config.enabled=!1}enable(){this.config.enabled=!0}}const c=3,l=e=>1e3*e;async function g(e,t={},r){const{maxAttempts:i=c,delayFn:s=l}=t;let n=null;for(let t=1;t<=i;t+=1)try{return await e()}catch(e){n=e,t<i&&await new Promise((e=>{setTimeout(e,s(t))}))}if(n&&t.logger&&t.operationName&&t.logger.error(`Operation ${t.operationName} failed after ${i} attempts.`,n,!0),void 0!==r)return r;throw n||new Error("Operation failed after multiple attempts")}const h=browser,d={TRACK_EVENT:"GF_TRACK_EVENT",HIDE_POPUP:"GF_HIDE_POPUP",GET_POPUP_CONFIG:"GF_GET_POPUP_CONFIG",IS_ACTIVE_DOMAIN:"GF_IS_ACTIVE_DOMAIN",LOG_MERCHANTS_IN_SEARCH_RESULTS:"GF_LOG_MERCHANTS_IN_SEARCH_RESULTS",SHOULD_STAND_DOWN:"GF_SHOULD_STAND_DOWN",ACTIVATE_OFFER:"GF_ACTIVATE_OFFER",STORE_SHOPIFY_SHOP_ID:"GF_STORE_SHOPIFY_SHOP_ID",GET_DOMAIN_BY_SHOP_ID:"GF_GET_DOMAIN_BY_SHOP_ID",GET_LANGUAGE_CONTENT:"GF_GET_LANGUAGE_CONTENT"},u="shopify_shop_ids",f="gf_last_health_check",m="gf_partner_config",p="gf_global_config",A="countryCode",y="version",w="gf_anonymous_user_info",v="gf_anonymous_encrypted_token",C="gf_ad_event_history",S="wfDevice",b="wfDomains",E="wfStanddownPolicy",I="wfStanddownHistory",T="wfMerchantRates",x="en",_="GIVE_FREELY_",O={async get(e){const t=`${_}${e}`;return(await browser.storage.local.get(t))[t]||null},async set(e,t){const r=`${_}${e}`;await browser.storage.local.set({[r]:t})},async remove(e){const t=Array.isArray(e)?e.map((e=>`${_}${e}`)):`${_}${e}`;await browser.storage.local.remove(t)}},P=()=>String("1.17.4"),D=async(e=!0)=>{const t=await O.get(y),r=await P(),i=t!==r;var s;return e&&i&&await(s=r,O.set(y,s)),i},F=o.getInstance(),U={async get(e,t,r,i=!1,s){let n=await O.get(e);const a=n;let o=!1,c=r??n?.retentionInSeconds??600;if(n&&Date.now()<=n.lastFetch+1e3*c&&!i)return{content:n.content,isStale:o};try{const r=await t(),i=s?s(r):null;null!=i&&(c=i),n=await this.set(e,r,c)}catch(e){F.error("Error getting cached value",{error:e}),o=!0}return{content:n?.content??a?.content,isStale:o}},async set(e,t,r){const i=r??600,s={content:t,lastFetch:Date.now(),retentionInSeconds:i};return await O.set(e,s),s},async clear(e){await O.remove(e)}};class k{constructor(){this.listeners=new Map,this.wildcardListeners=new Set}on(e,t){return this.addListener(e,t,!1)}once(e,t){return this.addListener(e,t,!0)}off(e,t){if(!t)return this.listeners.delete(e),void(this.wildcardListeners=new Set(Array.from(this.wildcardListeners).filter((t=>t.pattern!==e))));if(e.includes("*"))this.wildcardListeners=new Set(Array.from(this.wildcardListeners).filter((r=>!(r.pattern===e&&r.callback===t))));else{const r=this.listeners.get(e);if(r){const i=Array.from(r).filter((e=>e.callback!==t));i.length>0?this.listeners.set(e,new Set(i)):this.listeners.delete(e)}}}emit(e){const t=this.listeners.get(e.path)||new Set,r=new Set;for(const e of t)r.add(e);for(const t of this.wildcardListeners)this.matchesPattern(e.path,t.pattern)&&r.add(t);for(const t of r)t.callback(e),t.once&&this.removeListener(t)}clear(){this.listeners.clear(),this.wildcardListeners.clear()}addListener(e,t,r){const i={pattern:e,callback:t,once:r};if(e.includes("*"))this.wildcardListeners.add(i);else{const t=this.listeners.get(e);t?t.add(i):this.listeners.set(e,new Set([i]))}return()=>this.off(e,t)}removeListener(e){if(e.pattern.includes("*"))this.wildcardListeners.delete(e);else{const t=this.listeners.get(e.pattern);t&&(t.delete(e),0===t.size&&this.listeners.delete(e.pattern))}}matchesPattern(e,t){if("*"===t)return!0;const r=t.split(".").map((e=>"*"===e?"[^.]+":"**"===e?".*":e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"))).join("\\.");return new RegExp(`^${r}$`).test(e)}}function L(e,t,r=""){const i=[];if(e===t)return i;if(R(e)||R(t))return e!==t&&i.push({path:r||"root",oldValue:e,newValue:t}),i;if(Array.isArray(e)&&Array.isArray(t))return JSON.stringify(e)!==JSON.stringify(t)&&i.push({path:r||"root",oldValue:e,newValue:t}),i;if(N(e)&&N(t)){const s=e,n=t,a=new Set([...Object.keys(s),...Object.keys(n)]);for(const e of a){const t=r?`${r}.${e}`:e,a=s[e],o=n[e];if(e in s)if(e in n){const e=L(a,o,t);i.push(...e)}else i.push({path:t,oldValue:a,newValue:void 0});else i.push({path:t,oldValue:void 0,newValue:o})}}else e!==t&&i.push({path:r||"root",oldValue:e,newValue:t});return i}function R(e){return null==e||"object"!=typeof e}function N(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}var $;!function(e){e.CLOSED="CLOSED",e.OPEN="OPEN",e.HALF_OPEN="HALF_OPEN"}($||($={}));class H{constructor(e={}){this.state=$.CLOSED,this.failures=[],this.lastFailureTime=0,this.halfOpenCalls=0,this.logger=o.getInstance({minLevel:"warn"}),this.options={failureThreshold:5,recoveryTimeout:6e4,monitoringWindow:3e5,halfOpenMaxCalls:3,storageKey:"circuit_breaker_state",...e},this.storageKey=this.options.storageKey}async initialize(){await this.loadFromStorage()}static async create(e={}){const t=new H(e);return await t.initialize(),t}async loadFromStorage(){try{if("undefined"!=typeof chrome&&chrome.storage&&chrome.storage.local){const e=(await chrome.storage.local.get(this.storageKey))[this.storageKey];e&&(this.state=e.state,this.failures=e.failures||[],this.lastFailureTime=e.lastFailureTime||0,this.halfOpenCalls=e.halfOpenCalls||0,this.cleanupOldFailures())}else if("undefined"!=typeof localStorage){const e=localStorage.getItem(this.storageKey);if(e){const t=JSON.parse(e);this.state=t.state,this.failures=t.failures||[],this.lastFailureTime=t.lastFailureTime||0,this.halfOpenCalls=t.halfOpenCalls||0,this.cleanupOldFailures()}}}catch(e){this.logger.warn("Failed to load circuit breaker state from storage:",e)}}async saveToStorage(){try{const e={state:this.state,failures:this.failures,lastFailureTime:this.lastFailureTime,halfOpenCalls:this.halfOpenCalls};"undefined"!=typeof chrome&&chrome.storage&&chrome.storage.local?await chrome.storage.local.set({[this.storageKey]:e}):"undefined"!=typeof localStorage&&localStorage.setItem(this.storageKey,JSON.stringify(e))}catch(e){this.logger.warn("Failed to save circuit breaker state to storage:",e)}}cleanupOldFailures(){const e=Date.now();this.failures=this.failures.filter((t=>e-t.timestamp<=this.options.monitoringWindow))}async execute(e,t){if(this.state===$.OPEN){if(!this.shouldAttemptRecovery()){if(t)return t();throw new Error("Circuit breaker is OPEN - service temporarily unavailable")}this.state=$.HALF_OPEN,this.halfOpenCalls=0,await this.saveToStorage()}if(this.state===$.HALF_OPEN){if(this.halfOpenCalls>=this.options.halfOpenMaxCalls)throw new Error("Circuit breaker HALF_OPEN call limit exceeded");this.halfOpenCalls+=1,await this.saveToStorage()}try{const t=await e();return await this.onSuccess(),t}catch(e){throw await this.onFailure(e),e}}async onSuccess(){this.state===$.HALF_OPEN&&(this.state=$.CLOSED,this.failures=[],await this.saveToStorage())}async onFailure(e){const t=Date.now();this.lastFailureTime=t,this.failures.push({timestamp:t,error:e.message}),this.failures=this.failures.filter((e=>t-e.timestamp<=this.options.monitoringWindow)),this.failures.length>=this.options.failureThreshold&&(this.state=$.OPEN),await this.saveToStorage()}shouldAttemptRecovery(){return Date.now()-this.lastFailureTime>=this.options.recoveryTimeout}getState(){return this.state}getFailureCount(){const e=Date.now();return this.failures.filter((t=>e-t.timestamp<=this.options.monitoringWindow)).length}async reset(){this.state=$.CLOSED,this.failures=[],this.lastFailureTime=0,this.halfOpenCalls=0,await this.saveToStorage()}async clearStorage(){"undefined"!=typeof chrome&&chrome.storage&&chrome.storage.local?await chrome.storage.local.remove(this.storageKey):"undefined"!=typeof localStorage&&localStorage.removeItem(this.storageKey)}getStatus(){return{state:this.state,failureCount:this.getFailureCount(),nextAttemptTime:this.state===$.OPEN?this.lastFailureTime+this.options.recoveryTimeout:null}}}const M="https://cdn.givefreely.com/adunit/behavioral/";class G{constructor(e){this.partnerApiKey=e,this.partnerConfig=null,this.globalConfig=null,this.mergedConfig=null,this.globalConfigRefreshInterval=null,this.partnerConfigRefreshInterval=null,this.eventEmitter=new k,this.isInitialized=!1,this.partnerCircuitBreaker=new H({failureThreshold:3,recoveryTimeout:6e4,monitoringWindow:3e5,storageKey:`gf_partner_circuit_breaker_${e}`}),this.globalCircuitBreaker=new H({failureThreshold:3,recoveryTimeout:6e4,monitoringWindow:3e5,storageKey:"gf_global_circuit_breaker"})}async initialize(){this.isInitialized||(await Promise.all([this.partnerCircuitBreaker.initialize(),this.globalCircuitBreaker.initialize()]),this.isInitialized=!0)}ensureInitialized(){if(!this.isInitialized)throw new Error("GiveFreelyConfigService must be initialized before use. Call initialize() or use create() method.")}getRetryOptions(){return{delayFn:e=>1e3*e,maxAttempts:3}}async fetchPartnerConfig(){const e=await g((async()=>{const e=await fetch(`${M}${this.partnerApiKey}.json`,{cache:"no-store"});if(!e.ok)throw new Error(`Failed to fetch partner config: ${e.statusText}`);return e.json()}),this.getRetryOptions());if(!e)throw new Error("Failed to fetch or get from cache partner config");return this.partnerConfigRefreshInterval=e.configRefreshInterval||this.partnerConfigRefreshInterval,e}async fetchGlobalConfig(){const e=await g((async()=>{const e=await fetch(`${M}global.json`,{cache:"no-store"});if(!e.ok)throw new Error(`Failed to fetch global config => Status code: ${e.status} .${e.statusText}`);return e.json()}),this.getRetryOptions());if(!e)throw new Error("Failed to fetch or get from cache global config",e);return this.globalConfigRefreshInterval=e.configRefreshInterval||this.globalConfigRefreshInterval,e}async getCachedConfig(){return this.mergedConfig}async getConfig(e=!1){this.ensureInitialized();let t=!1;e&&(t=await D());const[r,i]=await Promise.all([U.get(m,this.fetchPartnerConfig.bind(this),this.partnerConfigRefreshInterval,t,(e=>e?.configRefreshInterval??null)),U.get(p,this.fetchGlobalConfig.bind(this),this.globalConfigRefreshInterval,t,(e=>e?.configRefreshInterval??null))]);if(!i.content)throw new Error("Global config is required");if(!r.content)throw new Error("Partner config is required");this.partnerConfig=r.content,this.globalConfig=i.content;const s=this.mergeConfigs(JSON.parse(JSON.stringify(this.globalConfig)),JSON.parse(JSON.stringify(this.partnerConfig)));if(!s)throw new Error("Was not able to merge configs");return((e,t,r)=>{const i=[...t.merchantExclusions??[],...r.merchantExclusions??[]];e.merchantExclusions=i})(s,this.globalConfig,this.partnerConfig),this.emitConfigChanges(s),s}async clearCache(){this.ensureInitialized(),await Promise.all([U.clear(m),U.clear(p)]),this.partnerConfig=null,this.globalConfig=null,this.mergedConfig=null,this.eventEmitter.clear(),await Promise.all([this.partnerCircuitBreaker.reset(),this.globalCircuitBreaker.reset()])}getCircuitBreakerStatus(){return this.ensureInitialized(),{partner:this.partnerCircuitBreaker.getStatus(),global:this.globalCircuitBreaker.getStatus()}}mergeConfigs(e,t){if(!t)return e;if(!e)return t;const r={...e};return Object.keys(t).forEach((i=>{if(!Object.prototype.hasOwnProperty.call(t,i))return;const s=e[i],n=t[i];void 0!==n&&(Array.isArray(n)?r[i]=[...n]:r[i]=null===n||"object"!=typeof n||null===s||"object"!=typeof s?n:this.mergeConfigs(s,n))})),r}on(e,t){return this.eventEmitter.on(e,t)}once(e,t){return this.eventEmitter.once(e,t)}off(e,t){this.eventEmitter.off(e,t)}emitConfigChanges(e){if(!this.mergedConfig)return this.mergedConfig=e,void this.eventEmitter.emit({path:"root",oldValue:null,newValue:e,config:e});const t=L(this.mergedConfig,e);for(const r of t)this.eventEmitter.emit({path:r.path,oldValue:r.oldValue,newValue:r.newValue,config:e});this.mergedConfig=e}}class z{constructor(e,t,r,i=60){this.track=async(e,t,r,i=!1,s=!1)=>{const n={partner:`adUnit_${this._partnerApiKey}`,eventType:e,eventData:{userId:i?void 0:this._userService?.user?.id,libVersion:P(),wfDeviceId:t,...r}};try{const e=JSON.stringify(n,((e,t)=>t instanceof Error?{name:t.name,message:t.message,stack:t.stack}:t)),t=await this.getEventsUrl();return t?await this.BroadcastEvent(t,e,n,s):(this._logger.info("Cant broadcast event. eventsUrl cant be retrieved from config",n,!0),!1)}catch(e){return this._logger.error("Something unexpected happened when dispatching a gf event",{error:e,event:n},!0),!1}},this.getEventsHistory=async()=>{const e=await O.get(C),t=(e=>{const t=new Date;return t.setTime(t.getTime()+60*e*1e3),t.getTime()})(-this._debounceWindowInMinutes),r=(e||[]).filter((e=>e.createdAt>t));return await O.set(C,r),r},this.shouldBroadcastEvent=async(e,t)=>!!t||!(await this.getEventsHistory()).some((t=>t.payload===e)),this.pushEventToHistory=async e=>{const t=await this.getEventsHistory();t.push({createdAt:Date.now(),payload:e}),await O.set(C,t)},this._partnerApiKey=e,this._userService=t,this._debounceWindowInMinutes=i,this._logger=o.getInstance({title:"Analytics"}),this._configService=r}async BroadcastEvent(e,t,r,i){if(await this.shouldBroadcastEvent(t,i)){const i=await fetch(e,{headers:{"Content-Type":"application/json"},method:"POST",body:t,cache:"no-store"});return i.ok?(await this.pushEventToHistory(t),!0):(this._logger.error("Something unexpected happened when dispatching an event",{status:i.status,statusText:i.statusText,event:r},!0),!1)}return this._logger.info("This event has already been broadcasted during the past hour",r,!0),!1}async getEventsUrl(){const e=await this._configService.getCachedConfig();return e?.eventsUrl}}z.trackEvent=async(e,t,r=!1,i=!1)=>{await async function(e){return await h.runtime.sendMessage(e)}({type:d.TRACK_EVENT,payload:{eventType:e,eventData:t,anonymous:r,skipThrottling:i}})};class j{constructor(e,t){this.lastCheck=null,this.trackEvent=e,this.logger=t}async initialize(){const e=await O.get(f);e&&(this.lastCheck=e)}getToday(){return(new Date).toISOString().split("T")[0]}async check(){try{const e=this.lastCheck??0,t=this.getToday();(e?new Date(e).toISOString().split("T")[0]:null)!==t&&(this.lastCheck=Date.now(),await O.set(f,this.lastCheck),await this.trackEvent(r.checkoutPopupHealthCheck,{language:browser.i18n.getUILanguage()}))}catch(e){this.logger.error("Health check failed",{error:e instanceof Error?e.message:"Unknown error"},!0)}}}var W;!function(e){e[e.Pending=0]="Pending",e[e.Ready=1]="Ready",e[e.Received=2]="Received",e[e.Donated=3]="Donated",e[e.Disqualified=4]="Disqualified"}(W||(W={}));class K{constructor(e,t,r){this.adUnitId=e,this.config=t,this.logger=r}async getAnonymousUserCommissions(e,t){try{const r=new URLSearchParams(t).toString(),i=await fetch(`${this.config.apiConfig.baseUri}/${this.config.apiConfig.getAnonymousUserComissionsPath}?${r}`,{method:"GET",headers:{"Content-Type":"application/json","X-AnonymousUserToken":e}});if(!i.ok)throw new Error(`Failed to fetch commissions. Status code: ${i.status} .${i.statusText}`);return await i.json()}catch(e){throw this.logger.error("[GiveFreelyApiClient] Error fetching anonymous user's commissions:",{error:e}),e}}async createOrUpdateAnonymousUser(e,t){try{const r=await fetch(`${this.config.apiConfig.baseUri}/${this.config.apiConfig.createAnonymousUserPath}?adUnitId=${this.adUnitId}`,{method:"PUT",headers:{"Content-Type":"application/json","X-GF-Platform":"adUnitLibrary","X-AnonymousUserToken":t??""},body:JSON.stringify(e)});if(!r.ok)throw this.logger.error(`Failed to create/update anonymous user. Status code: ${r.status}. ${r.statusText}`),new Error(`Failed to create/update anonymous user. Status code: ${r.status}. ${r.statusText}`);this.logger.info("[GiveFreelyApiClient] anonymous user created/updated successfully.");const i=await r.json(),s=r.headers.get("X-AnonymousUserToken");return{resultUser:{...i,charity:{ein:i.selectedCharity,thirdPartyId:i.selectedCharityThirdPartyIdentifier,name:void 0}},resultToken:s}}catch(e){throw this.logger.error("[GiveFreelyApiClient] Error creating anonymous user:",{error:e},!0),e}}}class B{constructor(e,t){this._giveFreelyApiClient=e,this._logger=t,this.user=null}async resetUser(){await O.remove(v),await O.remove(w)}async upsertUser(e,t){let r=await this.fetchUser();try{const i={selectedCharity:e?.ein,selectedCharityThirdPartyIdentifier:e?.thirdPartyId,deviceId:t};if(!await this.shouldCreateOrUpdateUser(r,i))return r;const s=await O.get(v),{resultUser:n,resultToken:a}=await this._giveFreelyApiClient.createOrUpdateAnonymousUser(i,s);a&&await O.set(v,a),n&&(await O.set(w,n),r=n)}catch(e){this._logger.error("Error creating/updating anonymous user:",e)}return this.user=r,r}async fetchUser(){const e=await O.get(w);return this.user=e,e}async shouldCreateOrUpdateUser(e,t){return!e||e.charity?.ein!==t.selectedCharity||e.charity?.thirdPartyId!==t.selectedCharityThirdPartyIdentifier||e.deviceId!==t.deviceId}}class V{constructor(e,t,r,i,s){this.wfSecret=e,this.wfAppId=t,this.deviceUrl=r,this.dataUrl=i,this._logger=s}async getWildfireDevice(){try{const e=await fetch(this.deviceUrl,{method:"POST",body:JSON.stringify({}),headers:{"Content-Type":"application/json","WF-Secret":this.wfSecret,"WF-App-ID":this.wfAppId}});if(e.ok)return e.json();throw new Error(`Failed to fetch Wildfire device from ${this.deviceUrl}. Status ${e.status}. ${e.statusText}`)}catch(e){throw this._logger.error("Failed to fetch the Wildfire device",{err:e}),e}}async getActiveDomains(){try{const e=`${this.dataUrl}/${this.wfAppId}/active-domain/1`,t=await fetch(e);if(t.ok)return t.json();throw new Error(`Failed to fetch active domains from ${e}. Status ${t.status}. ${t.statusText}`)}catch(e){throw this._logger.error("Failed to fetch the active domains",{err:e}),e}}async getStanddownPolicy(){const e=`${this.dataUrl}/${this.wfAppId}/stand-down-policy/1`;try{const t=await fetch(e);if(t.ok)return t.json();throw new Error(`Failed to fetch standdown policy from ${e}. Status ${t.status}. ${t.statusText}`)}catch(t){throw this._logger.error("Failed to fetch the standdown policy",{err:t,url:e}),t}}async getMerchantRates(){const e=`${this.dataUrl}/${this.wfAppId}/merchant-rate/1`;try{const t=await fetch(e);if(this._logger.debug("Merchant rates response",{response:t}),!t.ok)throw new Error(`Failed to fetch merchant rates from ${e}. Status ${t.status}. ${t.statusText}`);const r=t.json();return this._logger.debug("Merchant rates",{rates:r}),r}catch(t){throw this._logger.error("Failed to fetch the merchant rates",{err:t,url:e}),t}}}async function q(e,t,r){try{const i=(await J())?.[t];if(i&&i>Date.now())return e.info("Standing down because current affiliate stand down session has not expired"),X(t),!0;await this.refreshCache();const s=await this.getStanddownPolicy();if(Q(s,new URL(r).search))return e.info("Standing down because url has affiliate params"),X(t),!0;e.info("No need to stand down.")}catch(t){e.error("Exception produced when trying to determine if it should stand down",t)}return!1}function Y(e,t){if(!this.standDownPolicy)return this.logger.warn("Couldnt check affilliation. No stand down policy found"),this.getStanddownPolicy().then((e=>{this.standDownPolicy=e})),!1;const r=e.some((e=>Z(this.standDownPolicy,e)))||Q(this.standDownPolicy,t);return this.logger.info("Affilliation result:",r),r}const J=async()=>O.get(I),X=async(e,t=1)=>{const r=await J()??{};r[e]=Date.now()+60*t*60*1e3,await O.set(I,r)},Z=(e,t)=>{if(!t)return!1;const{Domains:r}=e;return r.some((e=>t.includes(e)))},Q=(e,t)=>{if(!t)return!1;const{Params:r}=e;return r.some((e=>t.toLowerCase().includes(`?${e.toLowerCase()}`)))||r.some((e=>t.toLowerCase().includes(`&${e.toLowerCase()}`)))};class ee{constructor(e,t,r,i){this.userId=e,this.charityEin=t,this.charityThirdPartyIdentifier=r,this.partnerId=i}toString(){return`userId=${this.encodeUserId(this.userId)},charityEin=${this.charityEin},charityThirdPartyIdentifier=${this.charityThirdPartyIdentifier},partnerId=${this.partnerId}`}encodeUserId(e){return btoa(e).replace(/_/g,"/").replace(/-/g,"+")}}class te{constructor(e,t,r,i=21600){if(this.standDownPolicy=null,this.shouldStandDown=q.bind(this),this.hasAffilliation=Y.bind(this),!e||!r)throw new Error("WildfireService requires wildfireClient and vanityBaseUrl");this.wildfireClient=e,this.vanityBaseUrl=r.replace(/\/$/,""),this.refreshInterval=i,this.logger=t}async getActiveDomains(e=!1){try{const t=(await U.get(b,(async()=>this.fetchActiveDomains()),this.refreshInterval,e)).content;if(!t)throw Error("Failed to retrieve active domains");return t}catch(e){throw this.logger.error("Failed to get active domains:",e),new Error("Failed to retrieve active domains")}}async getMerchantRates(e,t=!1){try{const r=await U.get(T,(async()=>this.fetchMerchantRates()),this.refreshInterval,t);if(!r.content)throw new Error("Failed to retrieve merchant rates from cache");return r.content[e]}catch(e){throw this.logger.error("Failed to retrieve merchant rates:",e),new Error("Failed to retrieve merchant rates")}}async generateAffiliateUrl(e,t,r,i){if(!e||!t||!i)throw new Error("Missing required parameters for affiliate URL generation");try{const s=await this.getDevice(),n=await this.generateTrackingCode(r,i,s),a=encodeURIComponent(t),o=encodeURIComponent(n);return`${this.vanityBaseUrl}/e?d=${s.DeviceID}&c=${e.ID}&tc=${o}&url=${a}`}catch(e){throw this.logger.error("Failed to generate affiliate URL:",e),new Error("Failed to generate affiliate URL")}}async clearCache(){try{await Promise.all([U.clear(b),U.clear(E),U.clear(T)])}catch(e){throw this.logger.error("Failed to clear cache:",e),new Error("Failed to clear cache")}}async clearDevice(){try{await O.remove(S),this.logger.info("Cleared wildfire device ID")}catch(e){throw this.logger.error("Failed to clear wildfire device:",e),new Error("Failed to clear wildfire device")}}async refreshCache(e=!1){try{const[,t]=await Promise.all([U.get(b,(()=>this.fetchActiveDomains()),this.refreshInterval,e),U.get(E,(()=>this.fetchStanddownPolicy()),this.refreshInterval,e),U.get(T,(()=>this.fetchMerchantRates()),this.refreshInterval,e)]);t?.content&&(this.standDownPolicy=t.content)}catch(e){throw this.logger.error("Failed to refresh cache:",e),new Error("Failed to refresh cache")}}async getStanddownPolicy(){try{const e=await U.get(E,(async()=>this.fetchStanddownPolicy()),this.refreshInterval);if(!e.content)throw new Error("Failed to retrieve standdown policy from cache");return this.logger.info("Retrieved standdown policy from cache",e.content),this.standDownPolicy=e.content,this.standDownPolicy}catch(e){throw this.logger.error("Failed to get standdown policy from cache:",e),new Error("Failed to retrieve standdown policy")}}getRetryOptions(e){return{delayFn:e=>1e3*e,maxAttempts:3,logger:this.logger,operationName:e}}async getDevice(){try{const e=await O.get(S);return e?.DeviceID?e:g((()=>this.fetchAndStoreDevice()),this.getRetryOptions("Get Device"))}catch(e){throw this.logger.error("Failed to get device:",e),new Error("Failed to retrieve device information")}}async fetchAndStoreDevice(){const e=await this.wildfireClient.getWildfireDevice();if(!e?.DeviceID)throw new Error("Failed to retrieve device information");return await O.set(S,e),e}async generateTrackingCode(e,t,r){if(!(e?.id&&e?.charity&&e?.charity.ein&&e?.charity.thirdPartyId)){const e=`notregistered-${r.DeviceID}`;return this.logger.info("User not provided. Using GF's default bucket instead.",e),e}return new ee(e.id,e.charity.ein,e.charity.thirdPartyId,t).toString()}async fetchActiveDomains(){const e=await g((()=>this.wildfireClient.getActiveDomains()),this.getRetryOptions("Fetch Active Domains"));return this.logger.info("Updated active domains"),e}async fetchStanddownPolicy(){const e=await g((()=>this.wildfireClient.getStanddownPolicy()),this.getRetryOptions("Get Standdown policy"),{Domains:[],LostAttribution:[],Params:[],Serp:[]});return this.logger.info("Updated standdown policy"),e}async fetchMerchantRates(){const e=await g((()=>this.wildfireClient.getMerchantRates()),this.getRetryOptions("Fetch Merchant Rates"),{});return this.logger.debug("Updated Merchant rates"),e}static async createWildfireService(e,t){e.debug("Initializing wildfire service with config",t);const r=new V(t.wfSecret,t.wfAppId,t.deviceUrl,t.dataUrl,e),i=new te(r,e,t.vanityBaseUrl,t.refreshInterval),s=await D();return await i.refreshCache(s),i}}const re=e=>{try{return new URL(e),!0}catch{return!1}},ie=new Set,se=new Set,ne={urls:["<all_urls>"],types:["main_frame"]};class ae extends Error{constructor(e="Service not initialized"){super(e),this.name="UninitializedServiceError"}}const oe=e=>{if(!e)throw new ae};class ce{static register(e,t){this.strategies.set(e,t)}static get(e){return this.strategies.get(e)}static exists(e){return!!function(e){return"object"==typeof e&&null!==e&&"type"in e&&"payload"in e&&"string"==typeof e.type}(e)&&this.knownMessageTypes.has(e.type)}}ce.strategies=new Map,ce.knownMessageTypes=new Set([...Object.values(d)]);const le=e=>{let t;if(browser.webRequest){const r=(e=>{const t=e.getLogger();return({requestId:r,url:i,initiator:s})=>{try{if(ie.has(r)||se.has(r)||!re(i))return;const{hostname:n,search:a}=new URL(i);if(n.includes("wild.link"))return t.info("Cashback activation request identified, ignoring affiliate check for request"),void se.add(r);let o;s&&re(s)&&(o=new URL(s).hostname),(e.hasAffiliation([n,o],a)||e.isCustomStandownMatch([i,s]))&&(t.info("Affiliation found or custom standown match on url, adding request id to track"),ie.add(r))}catch(e){t.error("Error on handleAffiliateOnBeforeRequest",e)}}})(e);browser.webRequest.onBeforeRequest.addListener(r,ne);const i=(e=>{const t=e.getLogger();return async({requestId:r,redirectUrl:i})=>{try{if(!ie.has(r))return;t.info("Attempting to find active domain");const{hostname:s}=new URL(i),n=(await e.getActiveDomains()).find((e=>s===e.Domain||s.endsWith(`.${e.Domain}`)));if(!n)return;t.info("Found active domain. Updating standdown state"),await X(n.Domain)}catch(e){t.error("Error on handleAffiliateOnBeforeRedirect",e)}}})(e);browser.webRequest.onBeforeRedirect.addListener(i,ne);const s=(e=>{const t=e.getLogger();return({requestId:e})=>{try{ie.has(e)&&(t.info("Tracking request completed. Request Id:",e),ie.delete(e))}catch(e){t.error("Error on handleAffiliateOnCompleted",e)}}})(e);browser.webRequest.onCompleted.addListener(s,ne),t=()=>{browser.webRequest.onBeforeRequest.removeListener(r),browser.webRequest.onBeforeRedirect.removeListener(i),browser.webRequest.onCompleted.removeListener(s)}}const r=function(){const t=o.getInstance(),r=(r,i,s)=>{function n(e){s(e)}const a=(async t=>(e.getLogger().debug("Received message",{type:t.type,payload:t.payload}),ge(e,t)))(r,0);return a instanceof Promise?(a.then((e=>{e&&n(e)})).catch((e=>{t.warn("Async message callback error:",e)})),!0):!0===a||void 0};return h.runtime.onMessage.addListener(r),r}();return function(){t&&t(),browser.runtime.onMessage.removeListener(r)}},ge=async(e,t)=>{oe(e.isInitialized());const r=ce.get(t.type);if(!r)return;const i={giveFreelyService:e};return r.handle(t,i)};class he{async handle(e,t){const{activeDomain:i,originalUrl:s,selectedCharity:n}=e.payload,{giveFreelyService:a}=t,o=a.getLogger();o.debug("Activating offer",{activeDomain:i,selectedCharity:n});try{if(!n?.ein||!n?.thirdPartyId)throw new Error("Missing charity information");const e=await a.initializeWfDeviceId();if(!e)throw new Error("Failed to initialize Wildfire device ID");const t=await a.upsertUser(n,e);o.debug("Upserted user",{currentUser:t}),t||o.info("Failed to create user. Using default bucket's user");const r=await a.generateAffiliateUrl(i,s,t);return o.debug("Generated affiliate URL",{affiliateUrl:r}),(async e=>{const t=h.tabs.getCurrent(),r=await t,i=await h.tabs.create({url:e,openerTabId:r?.id,active:!1,pinned:!0});await(async e=>new Promise((t=>{h.tabs.onUpdated.addListener((async function r(i,s){if(i===e&&"complete"===s.status){if(h.tabs.onUpdated.removeListener(r),!(await h.tabs.get(e)).url)return void t(!1);t(!0)}}))})))(i.id)&&setTimeout((()=>{i?.id&&h.tabs.remove(i.id)}),3e4)})(r),await a.updateStanddownHistory(i.Domain),o.debug("Activated offer",{activeDomain:i,selectedCharity:n}),{type:d.ACTIVATE_OFFER,payload:{response:!0}}}catch(e){return o.error("Error activating offer",{activeDomain:i,error:e}),a.trackEvent(r.checkoutPopupFailedActivation,{activeDomain:i,error:e}),{type:d.ACTIVATE_OFFER,payload:{response:!1}}}}}class de{async handle(e,t){const{shopId:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger();try{const e=u,t=(await O.get(e)||[]).find((e=>e.shopId===r));return t?(s.debug("Found domain for shop ID",{shopId:r,domain:t.domain}),{type:d.GET_DOMAIN_BY_SHOP_ID,payload:{found:!0,domain:t.domain,shopInfo:t}}):(s.debug("No domain found for shop ID",{shopId:r}),{type:d.GET_DOMAIN_BY_SHOP_ID,payload:{found:!1}})}catch(e){return s.error("Error getting domain for shop ID",{shopId:r,error:e}),{type:d.GET_DOMAIN_BY_SHOP_ID,payload:{found:!1}}}}}class ue{async handle(e,t){const{lang:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger();s.debug("Getting language strings",{lang:r});try{const e=await i.getLanguage(r);return s.debug("Language strings fetched",{language:e}),{type:d.GET_LANGUAGE_CONTENT,payload:{translations:e.translations,charities:e.charities}}}catch(e){return s.error("Error getting language strings",{error:e}),{type:d.GET_LANGUAGE_CONTENT,payload:{translations:null,charities:null}}}}}class fe{async handle(e,t){const{giveFreelyService:r}=t,i=r.getLogger(),s=await r.getCachedConfig();try{return i.debug("Fetching popup config"),{type:d.GET_POPUP_CONFIG,payload:{config:s}}}catch(e){return i.error("Error fetching popup config",{error:e}),{type:d.GET_POPUP_CONFIG,payload:{config:null}}}}}class me{async handle(e,t){const{days:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger();try{const e=new Date;return e.setDate(e.getDate()+r),await O.set("popup_hide",{popupHide:e.getTime()}),s.debug("Popup hidden",{days:r,expiry:e}),{type:d.HIDE_POPUP,payload:{ack:!0}}}catch(e){return s.error("Error hiding popup",{days:r,error:e}),{type:d.HIDE_POPUP,payload:{ack:!1}}}}}class pe{async handle(e,t){const{hostname:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger(),n=await i.getConfig().merchantExclusions,a=await i.getActiveDomains();s.debug("Checking hostname",{hostname:r});try{if(i.healthCheck(),n.some((e=>e.disableDomain&&(r===e.domain||r.endsWith(`.${e.domain}`)))))return s.debug("Hostname is in merchant exclusions",{hostname:r}),{type:d.IS_ACTIVE_DOMAIN,payload:{isActive:!1,domain:void 0,rates:[]}};if(!a||0===a.length)throw new Error("No active domains");s.debug("Retrieved active domains",{count:a.length});const e=a.find((e=>r===e.Domain||r.endsWith(`.${e.Domain}`)));s.debug("Domain check result",{hostname:r,isActive:!!e});let t=[];if(e?.ID){const r=await i.getMerchantRates(e.Merchant.ID);r&&(s.debug("Retrieved merchant rates",{merchantRates:r}),t=r)}return{type:d.IS_ACTIVE_DOMAIN,payload:{isActive:!!e,domain:e,rates:t}}}catch(e){return s.error("Error checking domain",{hostname:r,error:e}),{type:d.IS_ACTIVE_DOMAIN,payload:{isActive:!1,domain:void 0,rates:[]}}}}}class Ae{async handle(e,t){const{currentUrl:i,searchResults:s,source:n}=e.payload,{giveFreelyService:a}=t,o=a.getLogger(),c=await a.getActiveDomains();o.debug("Finding merchants in search results",{currentUrl:i});try{const e=s.filter((e=>{try{const{hostname:t}=new URL(e.url);return c.some((e=>e.Domain===t||t.endsWith(`.${e.Domain}`)))}catch{return o.debug("Couldn't parse the following search result url",{x:e}),!1}}));if(o.info("Number of merchants identified in the search result",{number:e.length}),e.length>0){const s=Math.floor(Math.random()*Date.now());for(const a of e)t.giveFreelyService.trackEvent(r.checkoutPopupMerchantInResultsFound,{source:n,searchResultsId:s,currentUrl:i,searchResultUrl:a.url,sponsored:a.isSponsored},!0)}return{type:d.LOG_MERCHANTS_IN_SEARCH_RESULTS,payload:{result:!0}}}catch(e){return o.error("Error sending logs for merchants in search results",{currentUrl:i,error:e}),{type:d.LOG_MERCHANTS_IN_SEARCH_RESULTS,payload:{result:!1}}}}}class ye{async handle(e,t){const r=e.payload,{giveFreelyService:i}=t,s=i.getLogger();try{const e=u,t=await O.get(e)||[],i=t.findIndex((e=>e.shopId===r.shopId));return i>=0?t[i]=r:t.push(r),await O.set(e,t),s.debug("Stored Shopify shop ID",{shopInfo:r}),{type:d.STORE_SHOPIFY_SHOP_ID,payload:{success:!0}}}catch(e){return s.error("Error storing Shopify shop ID",{shopInfo:r,error:e}),{type:d.STORE_SHOPIFY_SHOP_ID,payload:{success:!1}}}}}class we{async handle(e,t){const{activeDomain:r,url:i}=e.payload,{giveFreelyService:s}=t,n=s.getLogger();n.debug("Checking if we should stand down",{activeDomain:r});try{const e=await s.shouldStandDown(r,i);return{type:d.SHOULD_STAND_DOWN,payload:{result:e}}}catch(e){return n.error("Error checking if we should stand down. Returning false",{activeDomain:r,error:e}),{type:d.SHOULD_STAND_DOWN,payload:{result:!1}}}}}class ve{async handle(e,t){const{eventType:r,eventData:i,anonymous:s,skipThrottling:n}=e.payload,{giveFreelyService:a}=t,o=a.getLogger();o.debug("Broadcasting event",{eventType:r,eventData:i,anonymous:s,skipThrottling:n});try{const e=await a.trackEvent(r,i,s,n);return{type:d.TRACK_EVENT,payload:{result:e}}}catch(e){return o.error("Error broadcasting event. Returning false",{eventType:r,eventData:i,error:e}),{type:d.TRACK_EVENT,payload:{result:!1}}}}}const Ce=o.getInstance(),Se=async()=>await O.get(A)||(async()=>{Ce.debug("detecting country");const e={method:"GET",headers:{"Content-Type":"application/json",Authorization:"Basic OTEzOTkxOnFlYmpaWF9DOGNRY0lxSHA4WTVjNGxzU1pRSlM2VW9MMExzTF9tbWs="}};try{const t=await fetch("https://geoip.maxmind.com/geoip/v2.1/country/me",e);if(Ce.debug("Received geolocation response",{status:t.status}),!t.ok)return void Ce.error("Failed to get geolocation data",{status:t.status,statusText:t.statusText});const r=await t.json();if(!r)throw new Error("There was an error fetching geoip look up");return await O.set(A,r.country.iso_code),r.country.iso_code}catch(e){return void Ce.error("Failed to get geolocation data",{error:e},!0)}})(),be="https://cdn.givefreely.com/adunit/language",Ee=async(e,t,r,i,s=[],n=!1)=>{const a=(s??[]).includes(r)?x:r;e.debug(`Requested lang ${r} and current lang ${a}`);const o=`lang-${x}`,c=await U.get(o,(async()=>(e.debug(`Fetching default language ${x} for partner ${t}`),Ie(t,x))),i||600,n);if(!c.content)throw new Error(`Failed to fetch default language ${x} and no cache version available`);if(x===a)return c.content;const l=`lang-${a}`,g=await U.get(l,(async()=>(e.debug(`Fetching language ${a} for partner ${t}`),Ie(t,a))),i||600,n);if(!g.content)return c.content;const h=_e(c.content,g.content);return await U.set(l,h,i||600),h},Ie=async(e,t)=>{const r=`/global-${t}.json`,i=`/${e}/${t}.json`,[s,n]=await Promise.allSettled([Te(`${be}${r}`),Te(`${be}${i}`)]);let a,o;"fulfilled"===s.status&&(a=s.value),"fulfilled"===n.status&&(o=n.value);const c=xe(a,o);return{translations:c.translations,charities:c.charities}},Te=async e=>{const t=await fetch(e,{cache:"no-store"});if(!t.ok)throw new Error(`Failed to fetch partner language file ${e}. Status: ${t.status}. Reason: ${t.statusText}`);return t.json()},xe=(e,t)=>({translations:{...e?.translations??{},...t??{}},charities:{...e?.charities??{}}}),_e=(e,t)=>({translations:{...e.translations,...t.translations},charities:{...e.charities,...t.charities}});async function Oe(e=async()=>(this.logger.debug("Using default partnerFilter."),!0)){if(!this.state.initialized){this.logger.info("Starting initialization with mutex protection");try{await this.dependencies.configService.initialize();const t=await this.dependencies.configService.getConfig(!0);this.logger.configure({enabled:t.loggingEnabled??!0,minLevel:t.backgroundMinLogLevel??"error"}),this.logger.info("Initializing GiveFreelyService",{partnerApiKey:this.partnerApiKey});const r=await te.createWildfireService(this.logger,t);this.state.healthCheck=new j(this.trackEvent.bind(this),this.logger),await this.state.healthCheck.initialize();const i=new K(this.partnerApiKey,t,this.logger);this.state.giveFreelyUserService=new B(i,this.logger),await this.state.giveFreelyUserService.fetchUser(),this.state.giveFreelyUserService.user?.id||await this.state.giveFreelyUserService.upsertUser(),this.state.analytics=new z(this.partnerApiKey,this.state.giveFreelyUserService,this.dependencies.configService);try{const e=await O.get(S);e?.DeviceID?(this.state.wfDeviceId=e,this.logger.info("Loaded existing wfDeviceId from storage",{deviceId:e.DeviceID})):this.logger.debug("No existing wfDeviceId found in storage - will be created on first offer activation")}catch(e){this.logger.debug("Could not check for existing wfDeviceId in storage",e)}ce.register(d.IS_ACTIVE_DOMAIN,new pe),ce.register(d.GET_POPUP_CONFIG,new fe),ce.register(d.HIDE_POPUP,new me),ce.register(d.SHOULD_STAND_DOWN,new we),ce.register(d.TRACK_EVENT,new ve),ce.register(d.ACTIVATE_OFFER,new he),ce.register(d.STORE_SHOPIFY_SHOP_ID,new ye),ce.register(d.GET_DOMAIN_BY_SHOP_ID,new de),ce.register(d.GET_LANGUAGE_CONTENT,new ue),ce.register(d.LOG_MERCHANTS_IN_SEARCH_RESULTS,new Ae),await(async e=>{try{await Se()}catch(t){e.debug("Failed to get geolocation data",{error:t})}})(this.logger),await(async(e,t,r)=>{t.purgeLanguages&&t.purgeLanguages.length>0&&await Promise.all(t.purgeLanguages.flatMap((e=>[U.clear(`lang-${e}`),U.clear(`global-${e}`)]))),g((async()=>{e.debug("Initializing default language with partner API key",{partnerApiKey:r}),await Ee(e,r,x,t.configRefreshInterval)}))})(this.logger,t,this.partnerApiKey),this.state=((e,t)=>{const{wildfireService:r,partnerFilter:i,config:s}=t;return{...e,initialized:!0,wildfireService:r,partnerFilter:i,config:s}})(this.state,{wildfireService:r,partnerFilter:e,config:t}),this.logger.addTransport(new n(this)),this.cleanupListeners=le(this),De.call(this),this.logger.info("GiveFreelyService initialized successfully")}catch(e){const t=e instanceof Error?e.message:"Unknown error";throw this.logger.error("Failed to initialize GiveFreelyService",{error:t}),new Error(`Failed to initialize GiveFreelyService: ${t}`)}}}function Pe(){return this.state.initialized}function De(){this.onConfigChange("wfAppId",(async e=>{this.logger.info(`Wildfire App ID changed from ${e.oldValue} to ${e.newValue} - clearing device`),await Fe.call(this)})),this.onConfigChange("wfSecret",(async e=>{this.logger.info("Wildfire Secret changed - clearing device"),await Fe.call(this)}))}async function Fe(){try{this.state.wildfireService&&(await this.state.wildfireService.clearDevice(),this.state.wfDeviceId=null,this.logger.info("Wildfire device cleared due to config change"))}catch(e){this.logger.error("Failed to clear wildfire device:",e)}}var Ue={config:Object.freeze({__proto__:null,getCachedConfig:async function(){return oe(this.state.initialized),this.state.config=await this.dependencies.configService.getConfig(),this.logger.configure({minLevel:this.state.config.backgroundMinLogLevel??"error"}),this.state.config},getConfig:function(){return oe(this.state.initialized),this.state.config},offConfigChange:function(e,t){oe(this.state.initialized),this.dependencies.configService.off(e,t)},onConfigChange:function(e,t){return oe(this.state.initialized),this.dependencies.configService.on(e,t)},onceConfigChange:function(e,t){return oe(this.state.initialized),this.dependencies.configService.once(e,t)}}),merchants:Object.freeze({__proto__:null,generateAffiliateUrl:async function(e,t,r){return oe(this.state.initialized),this.state.wildfireService.generateAffiliateUrl(e,t,r,this.state.partnerApiKey)},getActiveDomains:async function(){return oe(this.state.initialized),this.state.wildfireService.getActiveDomains()},getMerchantRates:async function(e){if(oe(this.state.initialized),!this.state.wildfireService)throw new Error("Wildfire service not initialized");return this.state.wildfireService.getMerchantRates(e)}}),observability:Object.freeze({__proto__:null,getLogger:function(){return oe(this.state.initialized),this.logger},healthCheck:async function(){oe(this.state.initialized),await this.state.healthCheck.check()},trackEvent:function(e,t,r=!1,i=!1){return oe(this.state.initialized),this.state.analytics.track(e,this.state.wfDeviceId?.DeviceID,t,r,i)}}),standdown:Object.freeze({__proto__:null,hasAffiliation:function(e,t){if(!this.state.wildfireService)return this.logger.warn("Wildfire service not initialized yet"),!1;const r=this.state.wildfireService.hasAffilliation(e,t);return r&&this.logger.info("WF Affiliation identified"),r},isCustomStandownMatch:function(e){const t=e.some((e=>this.getConfig().customStandownPolicy?.urlRegex?.some((t=>!!e&&function(e,t){return new RegExp(t).test(e)}(e,t)))));return t&&this.logger.info("Custom Standown identified"),t},shouldStandDown:async function(e,t){oe(this.state.initialized);const r=new URL(t);if(!await this.state.partnerFilter(r.hostname))return this.logger.info("Should standdown due to partner filter."),!0;if(this.getConfig().merchantExclusions.some((t=>t.mutePopups&&e===t.domain)))return this.logger.info("Should standdown due to merchant exclusions"),!0;const i=await this.state.wildfireService.shouldStandDown(this.logger,e,t);return i&&this.logger.info("Should standdown due to vendor policy"),i},updateStanddownHistory:function(e){return oe(this.state.initialized),X(e)}}),identity:Object.freeze({__proto__:null,getCurrentUser:function(){return oe(this.state.initialized),this.state.giveFreelyUserService.user},getLanguage:async function(e){return oe(this.state.initialized),Ee(this.logger,this.state.partnerApiKey,e,this.state.config?.configRefreshInterval,this.state.config?.ignoredLanguages)},initializeWfDeviceId:async function(){if(oe(this.state.initialized),this.state.wfDeviceId=await this.state.wildfireService.getDevice(),!this.state.wfDeviceId)throw new Error("Failed to initialize Wildfire device ID");return this.state.wfDeviceId.DeviceID},upsertUser:function(e,t){return oe(this.state.initialized),this.state.giveFreelyUserService.upsertUser(e,t)}})};class ke{constructor(e){this.partnerApiKey=e,this.cleanupListeners=null,this.initialize=Oe.bind(this),this.isInitialized=Pe.bind(this),this.getConfig=Ue.config.getConfig.bind(this),this.getCachedConfig=Ue.config.getCachedConfig.bind(this),this.onConfigChange=Ue.config.onConfigChange.bind(this),this.onceConfigChange=Ue.config.onceConfigChange.bind(this),this.offConfigChange=Ue.config.offConfigChange.bind(this),this.getLogger=Ue.observability.getLogger.bind(this),this.healthCheck=Ue.observability.healthCheck.bind(this),this.trackEvent=Ue.observability.trackEvent.bind(this),this.initializeWfDeviceId=Ue.identity.initializeWfDeviceId.bind(this),this.upsertUser=Ue.identity.upsertUser.bind(this),this.getCurrentUser=Ue.identity.getCurrentUser.bind(this),this.getLanguage=Ue.identity.getLanguage.bind(this),this.getActiveDomains=Ue.merchants.getActiveDomains.bind(this),this.generateAffiliateUrl=Ue.merchants.generateAffiliateUrl.bind(this),this.getMerchantRates=Ue.merchants.getMerchantRates.bind(this),this.shouldStandDown=Ue.standdown.shouldStandDown.bind(this),this.updateStanddownHistory=Ue.standdown.updateStanddownHistory.bind(this),this.hasAffiliation=Ue.standdown.hasAffiliation.bind(this),this.isCustomStandownMatch=Ue.standdown.isCustomStandownMatch.bind(this),this.dependencies={configService:new G(e)},this.logger=o.getInstance(),this.logger.configure({enabled:!0,title:"Background - GiveFreelyService"}),this.state=(e=>({initialized:!1,wildfireService:null,partnerFilter:null,config:null,wfDeviceId:null,analytics:null,giveFreelyUserService:null,partnerApiKey:e,healthCheck:null}))(e)}async destroy(){var e;this.logger.info("Destroying GiveFreelyService"),await Promise.all([this.dependencies.configService.clearCache(),this.state.wildfireService?.clearCache(),this.state.giveFreelyUserService?.resetUser()]),this.cleanupListeners&&(this.cleanupListeners(),this.logger.info("Event listeners cleared."),this.cleanupListeners=null),this.state=(e=this.state,{...e,initialized:!1,wildfireService:null,partnerFilter:null,analytics:null,config:null})}}class GiveFreelyService{constructor(e){this.partnerApiKey=e,this.initialize=e=>this._adUnitService.initialize(e),this.destroy=()=>this._adUnitService.destroy(),this._adUnitService=new ke(e)}}const Le=e=>ce.exists(e);export{GiveFreelyService,browser,Le as isAdUnitMessage};
1
+ function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var t={exports:{}};"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self&&self,function(e){if(!(globalThis.chrome&&globalThis.chrome.runtime&&globalThis.chrome.runtime.id))throw new Error("This script should only be loaded in a browser extension.");if(globalThis.browser&&globalThis.browser.runtime&&globalThis.browser.runtime.id)e.exports=globalThis.browser;else{const t="The message port closed before a response was received.",r=e=>{const r={alarms:{clear:{minArgs:0,maxArgs:1},clearAll:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getAll:{minArgs:0,maxArgs:0}},bookmarks:{create:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},getChildren:{minArgs:1,maxArgs:1},getRecent:{minArgs:1,maxArgs:1},getSubTree:{minArgs:1,maxArgs:1},getTree:{minArgs:0,maxArgs:0},move:{minArgs:2,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeTree:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}},browserAction:{disable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},enable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},getBadgeBackgroundColor:{minArgs:1,maxArgs:1},getBadgeText:{minArgs:1,maxArgs:1},getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},openPopup:{minArgs:0,maxArgs:0},setBadgeBackgroundColor:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setBadgeText:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},browsingData:{remove:{minArgs:2,maxArgs:2},removeCache:{minArgs:1,maxArgs:1},removeCookies:{minArgs:1,maxArgs:1},removeDownloads:{minArgs:1,maxArgs:1},removeFormData:{minArgs:1,maxArgs:1},removeHistory:{minArgs:1,maxArgs:1},removeLocalStorage:{minArgs:1,maxArgs:1},removePasswords:{minArgs:1,maxArgs:1},removePluginData:{minArgs:1,maxArgs:1},settings:{minArgs:0,maxArgs:0}},commands:{getAll:{minArgs:0,maxArgs:0}},contextMenus:{remove:{minArgs:1,maxArgs:1},removeAll:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},cookies:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:1,maxArgs:1},getAllCookieStores:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},devtools:{inspectedWindow:{eval:{minArgs:1,maxArgs:2,singleCallbackArg:!1}},panels:{create:{minArgs:3,maxArgs:3,singleCallbackArg:!0},elements:{createSidebarPane:{minArgs:1,maxArgs:1}}}},downloads:{cancel:{minArgs:1,maxArgs:1},download:{minArgs:1,maxArgs:1},erase:{minArgs:1,maxArgs:1},getFileIcon:{minArgs:1,maxArgs:2},open:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},pause:{minArgs:1,maxArgs:1},removeFile:{minArgs:1,maxArgs:1},resume:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},extension:{isAllowedFileSchemeAccess:{minArgs:0,maxArgs:0},isAllowedIncognitoAccess:{minArgs:0,maxArgs:0}},history:{addUrl:{minArgs:1,maxArgs:1},deleteAll:{minArgs:0,maxArgs:0},deleteRange:{minArgs:1,maxArgs:1},deleteUrl:{minArgs:1,maxArgs:1},getVisits:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1}},i18n:{detectLanguage:{minArgs:1,maxArgs:1},getAcceptLanguages:{minArgs:0,maxArgs:0}},identity:{launchWebAuthFlow:{minArgs:1,maxArgs:1}},idle:{queryState:{minArgs:1,maxArgs:1}},management:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},getSelf:{minArgs:0,maxArgs:0},setEnabled:{minArgs:2,maxArgs:2},uninstallSelf:{minArgs:0,maxArgs:1}},notifications:{clear:{minArgs:1,maxArgs:1},create:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:0},getPermissionLevel:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},pageAction:{getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},hide:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},permissions:{contains:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},request:{minArgs:1,maxArgs:1}},runtime:{getBackgroundPage:{minArgs:0,maxArgs:0},getPlatformInfo:{minArgs:0,maxArgs:0},openOptionsPage:{minArgs:0,maxArgs:0},requestUpdateCheck:{minArgs:0,maxArgs:0},sendMessage:{minArgs:1,maxArgs:3},sendNativeMessage:{minArgs:2,maxArgs:2},setUninstallURL:{minArgs:1,maxArgs:1}},sessions:{getDevices:{minArgs:0,maxArgs:1},getRecentlyClosed:{minArgs:0,maxArgs:1},restore:{minArgs:0,maxArgs:1}},storage:{local:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},managed:{get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1}},sync:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}}},tabs:{captureVisibleTab:{minArgs:0,maxArgs:2},create:{minArgs:1,maxArgs:1},detectLanguage:{minArgs:0,maxArgs:1},discard:{minArgs:0,maxArgs:1},duplicate:{minArgs:1,maxArgs:1},executeScript:{minArgs:1,maxArgs:2},get:{minArgs:1,maxArgs:1},getCurrent:{minArgs:0,maxArgs:0},getZoom:{minArgs:0,maxArgs:1},getZoomSettings:{minArgs:0,maxArgs:1},goBack:{minArgs:0,maxArgs:1},goForward:{minArgs:0,maxArgs:1},highlight:{minArgs:1,maxArgs:1},insertCSS:{minArgs:1,maxArgs:2},move:{minArgs:2,maxArgs:2},query:{minArgs:1,maxArgs:1},reload:{minArgs:0,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeCSS:{minArgs:1,maxArgs:2},sendMessage:{minArgs:2,maxArgs:3},setZoom:{minArgs:1,maxArgs:2},setZoomSettings:{minArgs:1,maxArgs:2},update:{minArgs:1,maxArgs:2}},topSites:{get:{minArgs:0,maxArgs:0}},webNavigation:{getAllFrames:{minArgs:1,maxArgs:1},getFrame:{minArgs:1,maxArgs:1}},webRequest:{handlerBehaviorChanged:{minArgs:0,maxArgs:0}},windows:{create:{minArgs:0,maxArgs:1},get:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:1},getCurrent:{minArgs:0,maxArgs:1},getLastFocused:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}}};if(0===Object.keys(r).length)throw new Error("api-metadata.json has not been included in browser-polyfill");class i extends WeakMap{constructor(e,t=void 0){super(t),this.createItem=e}get(e){return this.has(e)||this.set(e,this.createItem(e)),super.get(e)}}const s=(t,r)=>(...i)=>{e.runtime.lastError?t.reject(new Error(e.runtime.lastError.message)):r.singleCallbackArg||i.length<=1&&!1!==r.singleCallbackArg?t.resolve(i[0]):t.resolve(i)},n=e=>1==e?"argument":"arguments",a=(e,t,r)=>new Proxy(t,{apply:(t,i,s)=>r.call(i,e,...s)});let o=Function.call.bind(Object.prototype.hasOwnProperty);const c=(e,t={},r={})=>{let i=Object.create(null),l={has:(t,r)=>r in e||r in i,get(l,g,h){if(g in i)return i[g];if(!(g in e))return;let d=e[g];if("function"==typeof d)if("function"==typeof t[g])d=a(e,e[g],t[g]);else if(o(r,g)){let t=((e,t)=>function(r,...i){if(i.length<t.minArgs)throw new Error(`Expected at least ${t.minArgs} ${n(t.minArgs)} for ${e}(), got ${i.length}`);if(i.length>t.maxArgs)throw new Error(`Expected at most ${t.maxArgs} ${n(t.maxArgs)} for ${e}(), got ${i.length}`);return new Promise(((n,a)=>{if(t.fallbackToNoCallback)try{r[e](...i,s({resolve:n,reject:a},t))}catch(s){console.warn(`${e} API method doesn't seem to support the callback parameter, falling back to call it without a callback: `,s),r[e](...i),t.fallbackToNoCallback=!1,t.noCallback=!0,n()}else t.noCallback?(r[e](...i),n()):r[e](...i,s({resolve:n,reject:a},t))}))})(g,r[g]);d=a(e,e[g],t)}else d=d.bind(e);else if("object"==typeof d&&null!==d&&(o(t,g)||o(r,g)))d=c(d,t[g],r[g]);else{if(!o(r,"*"))return Object.defineProperty(i,g,{configurable:!0,enumerable:!0,get:()=>e[g],set(t){e[g]=t}}),d;d=c(d,t[g],r["*"])}return i[g]=d,d},set:(t,r,s,n)=>(r in i?i[r]=s:e[r]=s,!0),defineProperty:(e,t,r)=>Reflect.defineProperty(i,t,r),deleteProperty:(e,t)=>Reflect.deleteProperty(i,t)},g=Object.create(e);return new Proxy(g,l)},l=e=>({addListener(t,r,...i){t.addListener(e.get(r),...i)},hasListener:(t,r)=>t.hasListener(e.get(r)),removeListener(t,r){t.removeListener(e.get(r))}}),g=new i((e=>"function"!=typeof e?e:function(t){const r=c(t,{},{getContent:{minArgs:0,maxArgs:0}});e(r)})),h=new i((e=>"function"!=typeof e?e:function(t,r,i){let s,n,a=!1,o=new Promise((e=>{s=function(t){a=!0,e(t)}}));try{n=e(t,r,s)}catch(e){n=Promise.reject(e)}const c=!0!==n&&((l=n)&&"object"==typeof l&&"function"==typeof l.then);var l;if(!0!==n&&!c&&!a)return!1;return(c?n:o).then((e=>{i(e)}),(e=>{let t;t=e&&(e instanceof Error||"string"==typeof e.message)?e.message:"An unexpected error occurred",i({__mozWebExtensionPolyfillReject__:!0,message:t})})).catch((e=>{console.error("Failed to send onMessage rejected reply",e)})),!0})),d=({reject:r,resolve:i},s)=>{e.runtime.lastError?e.runtime.lastError.message===t?i():r(new Error(e.runtime.lastError.message)):s&&s.__mozWebExtensionPolyfillReject__?r(new Error(s.message)):i(s)},u=(e,t,r,...i)=>{if(i.length<t.minArgs)throw new Error(`Expected at least ${t.minArgs} ${n(t.minArgs)} for ${e}(), got ${i.length}`);if(i.length>t.maxArgs)throw new Error(`Expected at most ${t.maxArgs} ${n(t.maxArgs)} for ${e}(), got ${i.length}`);return new Promise(((e,t)=>{const s=d.bind(null,{resolve:e,reject:t});i.push(s),r.sendMessage(...i)}))},f={devtools:{network:{onRequestFinished:l(g)}},runtime:{onMessage:l(h),onMessageExternal:l(h),sendMessage:u.bind(null,"sendMessage",{minArgs:1,maxArgs:3})},tabs:{sendMessage:u.bind(null,"sendMessage",{minArgs:2,maxArgs:3})}},m={clear:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}};return r.privacy={network:{"*":m},services:{"*":m},websites:{"*":m}},c(e,f,r)};e.exports=r(chrome)}}(t);var r,i,browser=e(t.exports);class s{constructor(){this.isLocal=!0}log({level:e,message:t,timestamp:r,data:i,title:n}){let a;switch(e){case"debug":default:a="log";break;case"info":a="info";break;case"warn":a="warn";break;case"error":case"critical":case"fatal":a="error"}const o=n?`[${n}]`:"";void 0!==i?console[a](`[${r}] - ${s.LOGGER_PREFIX} ${o} ${t}`,i):console[a](`[${r}] - ${s.LOGGER_PREFIX} ${o} ${t}`)}}s.LOGGER_PREFIX="[GFAdUnit] -",function(e){e.checkoutPopupShown="CHECKOUT-POPUP-SHOWN",e.checkoutPopupNotShown="CHECKOUT-POPUP-NOT-SHOWN",e.checkoutPopupSupressed="CHECKOUT-POPUP-SUPRESSED",e.checkoutPopupDonation="CHECKOUT-POPUP-DONATION",e.checkoutPopupFailedActivation="CHECKOUT-POPUP-FAILED-ACTIVATION",e.checkoutPopupPurchaseConfirmed="CHECKOUT-POPUP-PURCHASE-CONFIRMED",e.checkoutPopupHealthCheck="CHECKOUT-POPUP-HEALTH-CHECK",e.checkouPopupActivationFailed="CHECKOUT-POPUP-ACTIVATION-FAILED",e.checkoutPopupOfferDetailsClicked="CHECKOUT-POPUP-OFFER-DETAILS-CLICKED",e.checkoutPopupWhyAmISeeingThisClicked="CHECKOUT-POPUP-WHY-AM-I-SEEING-THIS-CLICKED",e.checkoutPopupLooserExtension="CHECKOUT-POPUP-LOOSER-EXTENSION",e.checkoutPopupActiveDomain="CHECKOUT-POPUP-ACTIVE-DOMAIN",e.checkoutPopupSiteMatches="CHECKOUT-POPUP-SITE-MATCHES",e.checkoutPopupMerchantInResultsFound="CHECKOUT-MERCHANT-IN-RESULTS-FOUND"}(r||(r={})),function(e){e.adUnitLog="ADUNIT-LOG"}(i||(i={}));class n{constructor(e){this.isLocal=!1,this.backgroundService=e}log({level:e,message:t,data:r,title:s}){this.backgroundService.trackEvent(i.adUnitLog,{log:{level:e,message:t,data:r,title:s}})}}const a=["debug","info","warn","error","critical","fatal"];class o{constructor(e){this.config={minLevel:e?.minLevel??"debug",enabled:e?.enabled??!1,transports:e?.transports??[new s],title:e?.title??""}}static getInstance(e){return o.instance||(o.instance=new o(e)),o.instance}configure(e){this.config={...this.config,...e}}shouldLog(e){return!!this.config.enabled&&a.indexOf(e)>=a.indexOf(this.config.minLevel)}createLogMessage(e,t,r){return{level:e,version:"1.17.5",message:t,timestamp:(new Date).toISOString(),data:r,title:this.config.title}}log(e,t,r,i){if(!this.shouldLog(e))return;const s=this.createLogMessage(e,t,i);this.config.transports.filter((e=>!r||e.isLocal)).forEach((e=>e.log(s)))}debug(e,t,r=!1){this.log("debug",e,r,t)}info(e,t,r=!1){this.log("info",e,r,t)}warn(e,t,r=!1){this.log("warn",e,r,t)}error(e,t,r=!1){this.log("error",e,r,t)}critical(e,t,r=!1){this.log("critical",e,r,t)}fatal(e,t,r=!1){this.log("fatal",e,r,t)}addTransport(e){this.config.transports.push(e)}clearTransports(){this.config.transports=[]}disable(){this.config.enabled=!1}enable(){this.config.enabled=!0}}const c=3,l=e=>1e3*e;async function g(e,t={},r){const{maxAttempts:i=c,delayFn:s=l}=t;let n=null;for(let t=1;t<=i;t+=1)try{return await e()}catch(e){n=e,t<i&&await new Promise((e=>{setTimeout(e,s(t))}))}if(n&&t.logger&&t.operationName&&t.logger.error(`Operation ${t.operationName} failed after ${i} attempts.`,n,!0),void 0!==r)return r;throw n||new Error("Operation failed after multiple attempts")}const h=browser,d={TRACK_EVENT:"GF_TRACK_EVENT",HIDE_POPUP:"GF_HIDE_POPUP",GET_POPUP_CONFIG:"GF_GET_POPUP_CONFIG",IS_ACTIVE_DOMAIN:"GF_IS_ACTIVE_DOMAIN",LOG_MERCHANTS_IN_SEARCH_RESULTS:"GF_LOG_MERCHANTS_IN_SEARCH_RESULTS",SHOULD_STAND_DOWN:"GF_SHOULD_STAND_DOWN",ACTIVATE_OFFER:"GF_ACTIVATE_OFFER",STORE_SHOPIFY_SHOP_ID:"GF_STORE_SHOPIFY_SHOP_ID",GET_DOMAIN_BY_SHOP_ID:"GF_GET_DOMAIN_BY_SHOP_ID",GET_LANGUAGE_CONTENT:"GF_GET_LANGUAGE_CONTENT"},u="shopify_shop_ids",f="gf_last_health_check",m="gf_partner_config",p="gf_global_config",A="countryCode",y="version",w="gf_anonymous_user_info",v="gf_anonymous_encrypted_token",C="gf_ad_event_history",S="wfDevice",b="wfDomains",E="wfStanddownPolicy",I="wfStanddownHistory",T="wfMerchantRates",x="en",_="GIVE_FREELY_",O={async get(e){const t=`${_}${e}`;return(await browser.storage.local.get(t))[t]||null},async set(e,t){const r=`${_}${e}`;await browser.storage.local.set({[r]:t})},async remove(e){const t=Array.isArray(e)?e.map((e=>`${_}${e}`)):`${_}${e}`;await browser.storage.local.remove(t)}},P=()=>String("1.17.5"),D=async(e=!0)=>{const t=await O.get(y),r=await P(),i=t!==r;var s;return e&&i&&await(s=r,O.set(y,s)),i},F=o.getInstance(),U={async get(e,t,r,i=!1,s){let n=await O.get(e);const a=n;let o=!1,c=r??n?.retentionInSeconds??600;if(n&&Date.now()<=n.lastFetch+1e3*c&&!i)return{content:n.content,isStale:o};try{const r=await t(),i=s?s(r):null;null!=i&&(c=i),n=await this.set(e,r,c)}catch(e){F.error("Error getting cached value",{error:e}),o=!0}return{content:n?.content??a?.content,isStale:o}},async set(e,t,r){const i=r??600,s={content:t,lastFetch:Date.now(),retentionInSeconds:i};return await O.set(e,s),s},async clear(e){await O.remove(e)}};class k{constructor(){this.listeners=new Map,this.wildcardListeners=new Set}on(e,t){return this.addListener(e,t,!1)}once(e,t){return this.addListener(e,t,!0)}off(e,t){if(!t)return this.listeners.delete(e),void(this.wildcardListeners=new Set(Array.from(this.wildcardListeners).filter((t=>t.pattern!==e))));if(e.includes("*"))this.wildcardListeners=new Set(Array.from(this.wildcardListeners).filter((r=>!(r.pattern===e&&r.callback===t))));else{const r=this.listeners.get(e);if(r){const i=Array.from(r).filter((e=>e.callback!==t));i.length>0?this.listeners.set(e,new Set(i)):this.listeners.delete(e)}}}emit(e){const t=this.listeners.get(e.path)||new Set,r=new Set;for(const e of t)r.add(e);for(const t of this.wildcardListeners)this.matchesPattern(e.path,t.pattern)&&r.add(t);for(const t of r)t.callback(e),t.once&&this.removeListener(t)}clear(){this.listeners.clear(),this.wildcardListeners.clear()}addListener(e,t,r){const i={pattern:e,callback:t,once:r};if(e.includes("*"))this.wildcardListeners.add(i);else{const t=this.listeners.get(e);t?t.add(i):this.listeners.set(e,new Set([i]))}return()=>this.off(e,t)}removeListener(e){if(e.pattern.includes("*"))this.wildcardListeners.delete(e);else{const t=this.listeners.get(e.pattern);t&&(t.delete(e),0===t.size&&this.listeners.delete(e.pattern))}}matchesPattern(e,t){if("*"===t)return!0;const r=t.split(".").map((e=>"*"===e?"[^.]+":"**"===e?".*":e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"))).join("\\.");return new RegExp(`^${r}$`).test(e)}}function L(e,t,r=""){const i=[];if(e===t)return i;if(R(e)||R(t))return e!==t&&i.push({path:r||"root",oldValue:e,newValue:t}),i;if(Array.isArray(e)&&Array.isArray(t))return JSON.stringify(e)!==JSON.stringify(t)&&i.push({path:r||"root",oldValue:e,newValue:t}),i;if(N(e)&&N(t)){const s=e,n=t,a=new Set([...Object.keys(s),...Object.keys(n)]);for(const e of a){const t=r?`${r}.${e}`:e,a=s[e],o=n[e];if(e in s)if(e in n){const e=L(a,o,t);i.push(...e)}else i.push({path:t,oldValue:a,newValue:void 0});else i.push({path:t,oldValue:void 0,newValue:o})}}else e!==t&&i.push({path:r||"root",oldValue:e,newValue:t});return i}function R(e){return null==e||"object"!=typeof e}function N(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}var $;!function(e){e.CLOSED="CLOSED",e.OPEN="OPEN",e.HALF_OPEN="HALF_OPEN"}($||($={}));class H{constructor(e={}){this.state=$.CLOSED,this.failures=[],this.lastFailureTime=0,this.halfOpenCalls=0,this.logger=o.getInstance({minLevel:"warn"}),this.options={failureThreshold:5,recoveryTimeout:6e4,monitoringWindow:3e5,halfOpenMaxCalls:3,storageKey:"circuit_breaker_state",...e},this.storageKey=this.options.storageKey}async initialize(){await this.loadFromStorage()}static async create(e={}){const t=new H(e);return await t.initialize(),t}async loadFromStorage(){try{if("undefined"!=typeof chrome&&chrome.storage&&chrome.storage.local){const e=(await chrome.storage.local.get(this.storageKey))[this.storageKey];e&&(this.state=e.state,this.failures=e.failures||[],this.lastFailureTime=e.lastFailureTime||0,this.halfOpenCalls=e.halfOpenCalls||0,this.cleanupOldFailures())}else if("undefined"!=typeof localStorage){const e=localStorage.getItem(this.storageKey);if(e){const t=JSON.parse(e);this.state=t.state,this.failures=t.failures||[],this.lastFailureTime=t.lastFailureTime||0,this.halfOpenCalls=t.halfOpenCalls||0,this.cleanupOldFailures()}}}catch(e){this.logger.warn("Failed to load circuit breaker state from storage:",e)}}async saveToStorage(){try{const e={state:this.state,failures:this.failures,lastFailureTime:this.lastFailureTime,halfOpenCalls:this.halfOpenCalls};"undefined"!=typeof chrome&&chrome.storage&&chrome.storage.local?await chrome.storage.local.set({[this.storageKey]:e}):"undefined"!=typeof localStorage&&localStorage.setItem(this.storageKey,JSON.stringify(e))}catch(e){this.logger.warn("Failed to save circuit breaker state to storage:",e)}}cleanupOldFailures(){const e=Date.now();this.failures=this.failures.filter((t=>e-t.timestamp<=this.options.monitoringWindow))}async execute(e,t){if(this.state===$.OPEN){if(!this.shouldAttemptRecovery()){if(t)return t();throw new Error("Circuit breaker is OPEN - service temporarily unavailable")}this.state=$.HALF_OPEN,this.halfOpenCalls=0,await this.saveToStorage()}if(this.state===$.HALF_OPEN){if(this.halfOpenCalls>=this.options.halfOpenMaxCalls)throw new Error("Circuit breaker HALF_OPEN call limit exceeded");this.halfOpenCalls+=1,await this.saveToStorage()}try{const t=await e();return await this.onSuccess(),t}catch(e){throw await this.onFailure(e),e}}async onSuccess(){this.state===$.HALF_OPEN&&(this.state=$.CLOSED,this.failures=[],await this.saveToStorage())}async onFailure(e){const t=Date.now();this.lastFailureTime=t,this.failures.push({timestamp:t,error:e.message}),this.failures=this.failures.filter((e=>t-e.timestamp<=this.options.monitoringWindow)),this.failures.length>=this.options.failureThreshold&&(this.state=$.OPEN),await this.saveToStorage()}shouldAttemptRecovery(){return Date.now()-this.lastFailureTime>=this.options.recoveryTimeout}getState(){return this.state}getFailureCount(){const e=Date.now();return this.failures.filter((t=>e-t.timestamp<=this.options.monitoringWindow)).length}async reset(){this.state=$.CLOSED,this.failures=[],this.lastFailureTime=0,this.halfOpenCalls=0,await this.saveToStorage()}async clearStorage(){"undefined"!=typeof chrome&&chrome.storage&&chrome.storage.local?await chrome.storage.local.remove(this.storageKey):"undefined"!=typeof localStorage&&localStorage.removeItem(this.storageKey)}getStatus(){return{state:this.state,failureCount:this.getFailureCount(),nextAttemptTime:this.state===$.OPEN?this.lastFailureTime+this.options.recoveryTimeout:null}}}const M="https://cdn.givefreely.com/adunit/behavioral/";class G{constructor(e){this.partnerApiKey=e,this.partnerConfig=null,this.globalConfig=null,this.mergedConfig=null,this.globalConfigRefreshInterval=null,this.partnerConfigRefreshInterval=null,this.eventEmitter=new k,this.isInitialized=!1,this.partnerCircuitBreaker=new H({failureThreshold:3,recoveryTimeout:6e4,monitoringWindow:3e5,storageKey:`gf_partner_circuit_breaker_${e}`}),this.globalCircuitBreaker=new H({failureThreshold:3,recoveryTimeout:6e4,monitoringWindow:3e5,storageKey:"gf_global_circuit_breaker"})}async initialize(){this.isInitialized||(await Promise.all([this.partnerCircuitBreaker.initialize(),this.globalCircuitBreaker.initialize()]),this.isInitialized=!0)}ensureInitialized(){if(!this.isInitialized)throw new Error("GiveFreelyConfigService must be initialized before use. Call initialize() or use create() method.")}getRetryOptions(){return{delayFn:e=>1e3*e,maxAttempts:3}}async fetchPartnerConfig(){const e=await g((async()=>{const e=await fetch(`${M}${this.partnerApiKey}.json`,{cache:"no-store"});if(!e.ok)throw new Error(`Failed to fetch partner config: ${e.statusText}`);return e.json()}),this.getRetryOptions());if(!e)throw new Error("Failed to fetch or get from cache partner config");return this.partnerConfigRefreshInterval=e.configRefreshInterval||this.partnerConfigRefreshInterval,e}async fetchGlobalConfig(){const e=await g((async()=>{const e=await fetch(`${M}global.json`,{cache:"no-store"});if(!e.ok)throw new Error(`Failed to fetch global config => Status code: ${e.status} .${e.statusText}`);return e.json()}),this.getRetryOptions());if(!e)throw new Error("Failed to fetch or get from cache global config",e);return this.globalConfigRefreshInterval=e.configRefreshInterval||this.globalConfigRefreshInterval,e}async getCachedConfig(){return this.mergedConfig}async getConfig(e=!1){this.ensureInitialized();let t=!1;e&&(t=await D());const[r,i]=await Promise.all([U.get(m,this.fetchPartnerConfig.bind(this),this.partnerConfigRefreshInterval,t,(e=>e?.configRefreshInterval??null)),U.get(p,this.fetchGlobalConfig.bind(this),this.globalConfigRefreshInterval,t,(e=>e?.configRefreshInterval??null))]);if(!i.content)throw new Error("Global config is required");if(!r.content)throw new Error("Partner config is required");this.partnerConfig=r.content,this.globalConfig=i.content;const s=this.mergeConfigs(JSON.parse(JSON.stringify(this.globalConfig)),JSON.parse(JSON.stringify(this.partnerConfig)));if(!s)throw new Error("Was not able to merge configs");return((e,t,r)=>{const i=[...t.merchantExclusions??[],...r.merchantExclusions??[]];e.merchantExclusions=i})(s,this.globalConfig,this.partnerConfig),this.emitConfigChanges(s),s}async clearCache(){this.ensureInitialized(),await Promise.all([U.clear(m),U.clear(p)]),this.partnerConfig=null,this.globalConfig=null,this.mergedConfig=null,this.eventEmitter.clear(),await Promise.all([this.partnerCircuitBreaker.reset(),this.globalCircuitBreaker.reset()])}getCircuitBreakerStatus(){return this.ensureInitialized(),{partner:this.partnerCircuitBreaker.getStatus(),global:this.globalCircuitBreaker.getStatus()}}mergeConfigs(e,t){if(!t)return e;if(!e)return t;const r={...e};return Object.keys(t).forEach((i=>{if(!Object.prototype.hasOwnProperty.call(t,i))return;const s=e[i],n=t[i];void 0!==n&&(Array.isArray(n)?r[i]=[...n]:r[i]=null===n||"object"!=typeof n||null===s||"object"!=typeof s?n:this.mergeConfigs(s,n))})),r}on(e,t){return this.eventEmitter.on(e,t)}once(e,t){return this.eventEmitter.once(e,t)}off(e,t){this.eventEmitter.off(e,t)}emitConfigChanges(e){if(!this.mergedConfig)return this.mergedConfig=e,void this.eventEmitter.emit({path:"root",oldValue:null,newValue:e,config:e});const t=L(this.mergedConfig,e);for(const r of t)this.eventEmitter.emit({path:r.path,oldValue:r.oldValue,newValue:r.newValue,config:e});this.mergedConfig=e}}class z{constructor(e,t,r,i=60){this.track=async(e,t,r,i=!1,s=!1)=>{const n={partner:`adUnit_${this._partnerApiKey}`,eventType:e,eventData:{userId:i?void 0:this._userService?.user?.id,libVersion:P(),wfDeviceId:t,...r}};try{const e=JSON.stringify(n,((e,t)=>t instanceof Error?{name:t.name,message:t.message,stack:t.stack}:t)),t=await this.getEventsUrl();return t?await this.BroadcastEvent(t,e,n,s):(this._logger.info("Cant broadcast event. eventsUrl cant be retrieved from config",n,!0),!1)}catch(e){return this._logger.error("Something unexpected happened when dispatching a gf event",{error:e,event:n},!0),!1}},this.getEventsHistory=async()=>{const e=await O.get(C),t=(e=>{const t=new Date;return t.setTime(t.getTime()+60*e*1e3),t.getTime()})(-this._debounceWindowInMinutes),r=(e||[]).filter((e=>e.createdAt>t));return await O.set(C,r),r},this.shouldBroadcastEvent=async(e,t)=>!!t||!(await this.getEventsHistory()).some((t=>t.payload===e)),this.pushEventToHistory=async e=>{const t=await this.getEventsHistory();t.push({createdAt:Date.now(),payload:e}),await O.set(C,t)},this._partnerApiKey=e,this._userService=t,this._debounceWindowInMinutes=i,this._logger=o.getInstance({title:"Analytics"}),this._configService=r}async BroadcastEvent(e,t,r,i){if(await this.shouldBroadcastEvent(t,i)){const i=await fetch(e,{headers:{"Content-Type":"application/json"},method:"POST",body:t,cache:"no-store"});return i.ok?(await this.pushEventToHistory(t),!0):(this._logger.error("Something unexpected happened when dispatching an event",{status:i.status,statusText:i.statusText,event:r},!0),!1)}return this._logger.info("This event has already been broadcasted during the past hour",r,!0),!1}async getEventsUrl(){const e=await this._configService.getCachedConfig();return e?.eventsUrl}}z.trackEvent=async(e,t,r=!1,i=!1)=>{await async function(e){return await h.runtime.sendMessage(e)}({type:d.TRACK_EVENT,payload:{eventType:e,eventData:t,anonymous:r,skipThrottling:i}})};class j{constructor(e,t){this.lastCheck=null,this.trackEvent=e,this.logger=t}async initialize(){const e=await O.get(f);e&&(this.lastCheck=e)}getToday(){return(new Date).toISOString().split("T")[0]}async check(){try{const e=this.lastCheck??0,t=this.getToday();(e?new Date(e).toISOString().split("T")[0]:null)!==t&&(this.lastCheck=Date.now(),await O.set(f,this.lastCheck),await this.trackEvent(r.checkoutPopupHealthCheck,{language:browser.i18n.getUILanguage()}))}catch(e){this.logger.error("Health check failed",{error:e instanceof Error?e.message:"Unknown error"},!0)}}}var W;!function(e){e[e.Pending=0]="Pending",e[e.Ready=1]="Ready",e[e.Received=2]="Received",e[e.Donated=3]="Donated",e[e.Disqualified=4]="Disqualified"}(W||(W={}));class K{constructor(e,t,r){this.adUnitId=e,this.config=t,this.logger=r}async getAnonymousUserCommissions(e,t){try{const r=new URLSearchParams(t).toString(),i=await fetch(`${this.config.apiConfig.baseUri}/${this.config.apiConfig.getAnonymousUserComissionsPath}?${r}`,{method:"GET",headers:{"Content-Type":"application/json","X-AnonymousUserToken":e}});if(!i.ok)throw new Error(`Failed to fetch commissions. Status code: ${i.status} .${i.statusText}`);return await i.json()}catch(e){throw this.logger.error("[GiveFreelyApiClient] Error fetching anonymous user's commissions:",{error:e}),e}}async createOrUpdateAnonymousUser(e,t){try{const r=await fetch(`${this.config.apiConfig.baseUri}/${this.config.apiConfig.createAnonymousUserPath}?adUnitId=${this.adUnitId}`,{method:"PUT",headers:{"Content-Type":"application/json","X-GF-Platform":"adUnitLibrary","X-AnonymousUserToken":t??""},body:JSON.stringify(e)});if(!r.ok)throw this.logger.error(`Failed to create/update anonymous user. Status code: ${r.status}. ${r.statusText}`),new Error(`Failed to create/update anonymous user. Status code: ${r.status}. ${r.statusText}`);this.logger.info("[GiveFreelyApiClient] anonymous user created/updated successfully.");const i=await r.json(),s=r.headers.get("X-AnonymousUserToken");return{resultUser:{...i,charity:{ein:i.selectedCharity,thirdPartyId:i.selectedCharityThirdPartyIdentifier,name:void 0}},resultToken:s}}catch(e){throw this.logger.error("[GiveFreelyApiClient] Error creating anonymous user:",{error:e},!0),e}}}class B{constructor(e,t){this._giveFreelyApiClient=e,this._logger=t,this.user=null}async resetUser(){await O.remove(v),await O.remove(w)}async upsertUser(e,t){let r=await this.fetchUser();try{const i={selectedCharity:e?.ein,selectedCharityThirdPartyIdentifier:e?.thirdPartyId,deviceId:t};if(!await this.shouldCreateOrUpdateUser(r,i))return r;const s=await O.get(v),{resultUser:n,resultToken:a}=await this._giveFreelyApiClient.createOrUpdateAnonymousUser(i,s);a&&await O.set(v,a),n&&(await O.set(w,n),r=n)}catch(e){this._logger.error("Error creating/updating anonymous user:",e)}return this.user=r,r}async fetchUser(){const e=await O.get(w);return this.user=e,e}async shouldCreateOrUpdateUser(e,t){return!e||e.charity?.ein!==t.selectedCharity||e.charity?.thirdPartyId!==t.selectedCharityThirdPartyIdentifier||e.deviceId!==t.deviceId}}class V{constructor(e,t,r,i,s){this.wfSecret=e,this.wfAppId=t,this.deviceUrl=r,this.dataUrl=i,this._logger=s}async getWildfireDevice(){try{const e=await fetch(this.deviceUrl,{method:"POST",body:JSON.stringify({}),headers:{"Content-Type":"application/json","WF-Secret":this.wfSecret,"WF-App-ID":this.wfAppId}});if(e.ok)return e.json();throw new Error(`Failed to fetch Wildfire device from ${this.deviceUrl}. Status ${e.status}. ${e.statusText}`)}catch(e){throw this._logger.error("Failed to fetch the Wildfire device",{err:e}),e}}async getActiveDomains(){try{const e=`${this.dataUrl}/${this.wfAppId}/active-domain/1`,t=await fetch(e);if(t.ok)return t.json();throw new Error(`Failed to fetch active domains from ${e}. Status ${t.status}. ${t.statusText}`)}catch(e){throw this._logger.error("Failed to fetch the active domains",{err:e}),e}}async getStanddownPolicy(){const e=`${this.dataUrl}/${this.wfAppId}/stand-down-policy/1`;try{const t=await fetch(e);if(t.ok)return t.json();throw new Error(`Failed to fetch standdown policy from ${e}. Status ${t.status}. ${t.statusText}`)}catch(t){throw this._logger.error("Failed to fetch the standdown policy",{err:t,url:e}),t}}async getMerchantRates(){const e=`${this.dataUrl}/${this.wfAppId}/merchant-rate/1`;try{const t=await fetch(e);if(this._logger.debug("Merchant rates response",{response:t}),!t.ok)throw new Error(`Failed to fetch merchant rates from ${e}. Status ${t.status}. ${t.statusText}`);const r=t.json();return this._logger.debug("Merchant rates",{rates:r}),r}catch(t){throw this._logger.error("Failed to fetch the merchant rates",{err:t,url:e}),t}}}async function q(e,t,r){try{const i=(await J())?.[t];if(i&&i>Date.now())return e.info("Standing down because current affiliate stand down session has not expired"),X(t),!0;await this.refreshCache();const s=await this.getStanddownPolicy();if(Q(s,new URL(r).search))return e.info("Standing down because url has affiliate params"),X(t),!0;e.info("No need to stand down.")}catch(t){e.error("Exception produced when trying to determine if it should stand down",t)}return!1}function Y(e,t){if(!this.standDownPolicy)return this.logger.warn("Couldnt check affilliation. No stand down policy found"),this.getStanddownPolicy().then((e=>{this.standDownPolicy=e})),!1;const r=e.some((e=>Z(this.standDownPolicy,e)))||Q(this.standDownPolicy,t);return this.logger.info("Affilliation result:",r),r}const J=async()=>O.get(I),X=async(e,t=1)=>{const r=await J()??{};r[e]=Date.now()+60*t*60*1e3,await O.set(I,r)},Z=(e,t)=>{if(!t)return!1;const{Domains:r}=e;return r.some((e=>t.includes(e)))},Q=(e,t)=>{if(!t)return!1;const{Params:r}=e;return r.some((e=>t.toLowerCase().includes(`?${e.toLowerCase()}`)))||r.some((e=>t.toLowerCase().includes(`&${e.toLowerCase()}`)))};class ee{constructor(e,t,r,i){this.userId=e,this.charityEin=t,this.charityThirdPartyIdentifier=r,this.partnerId=i}toString(){return`userId=${this.encodeUserId(this.userId)},charityEin=${this.charityEin},charityThirdPartyIdentifier=${this.charityThirdPartyIdentifier},partnerId=${this.partnerId}`}encodeUserId(e){return btoa(e).replace(/_/g,"/").replace(/-/g,"+")}}class te{constructor(e,t,r,i=21600){if(this.standDownPolicy=null,this.shouldStandDown=q.bind(this),this.hasAffilliation=Y.bind(this),!e||!r)throw new Error("WildfireService requires wildfireClient and vanityBaseUrl");this.wildfireClient=e,this.vanityBaseUrl=r.replace(/\/$/,""),this.refreshInterval=i,this.logger=t}async getActiveDomains(e=!1){try{const t=(await U.get(b,(async()=>this.fetchActiveDomains()),this.refreshInterval,e)).content;if(!t)throw Error("Failed to retrieve active domains");return t}catch(e){throw this.logger.error("Failed to get active domains:",e),new Error("Failed to retrieve active domains")}}async getMerchantRates(e,t=!1){try{const r=await U.get(T,(async()=>this.fetchMerchantRates()),this.refreshInterval,t);if(!r.content)throw new Error("Failed to retrieve merchant rates from cache");return r.content[e]}catch(e){throw this.logger.error("Failed to retrieve merchant rates:",e),new Error("Failed to retrieve merchant rates")}}async generateAffiliateUrl(e,t,r,i){if(!e||!t||!i)throw new Error("Missing required parameters for affiliate URL generation");try{const s=await this.getDevice(),n=await this.generateTrackingCode(r,i,s),a=encodeURIComponent(t),o=encodeURIComponent(n);return`${this.vanityBaseUrl}/e?d=${s.DeviceID}&c=${e.ID}&tc=${o}&url=${a}`}catch(e){throw this.logger.error("Failed to generate affiliate URL:",e),new Error("Failed to generate affiliate URL")}}async clearCache(){try{await Promise.all([U.clear(b),U.clear(E),U.clear(T)])}catch(e){throw this.logger.error("Failed to clear cache:",e),new Error("Failed to clear cache")}}async clearDevice(){try{await O.remove(S),this.logger.info("Cleared wildfire device ID")}catch(e){throw this.logger.error("Failed to clear wildfire device:",e),new Error("Failed to clear wildfire device")}}async refreshCache(e=!1){try{const[,t]=await Promise.all([U.get(b,(()=>this.fetchActiveDomains()),this.refreshInterval,e),U.get(E,(()=>this.fetchStanddownPolicy()),this.refreshInterval,e),U.get(T,(()=>this.fetchMerchantRates()),this.refreshInterval,e)]);t?.content&&(this.standDownPolicy=t.content)}catch(e){throw this.logger.error("Failed to refresh cache:",e),new Error("Failed to refresh cache")}}async getStanddownPolicy(){try{const e=await U.get(E,(async()=>this.fetchStanddownPolicy()),this.refreshInterval);if(!e.content)throw new Error("Failed to retrieve standdown policy from cache");return this.logger.info("Retrieved standdown policy from cache",e.content),this.standDownPolicy=e.content,this.standDownPolicy}catch(e){throw this.logger.error("Failed to get standdown policy from cache:",e),new Error("Failed to retrieve standdown policy")}}getRetryOptions(e){return{delayFn:e=>1e3*e,maxAttempts:3,logger:this.logger,operationName:e}}async getDevice(){try{const e=await O.get(S);return e?.DeviceID?e:g((()=>this.fetchAndStoreDevice()),this.getRetryOptions("Get Device"))}catch(e){throw this.logger.error("Failed to get device:",e),new Error("Failed to retrieve device information")}}async fetchAndStoreDevice(){const e=await this.wildfireClient.getWildfireDevice();if(!e?.DeviceID)throw new Error("Failed to retrieve device information");return await O.set(S,e),e}async generateTrackingCode(e,t,r){if(!(e?.id&&e?.charity&&e?.charity.ein&&e?.charity.thirdPartyId)){const e=`notregistered-${r.DeviceID}`;return this.logger.info("User not provided. Using GF's default bucket instead.",e),e}return new ee(e.id,e.charity.ein,e.charity.thirdPartyId,t).toString()}async fetchActiveDomains(){const e=await g((()=>this.wildfireClient.getActiveDomains()),this.getRetryOptions("Fetch Active Domains"));return this.logger.info("Updated active domains"),e}async fetchStanddownPolicy(){const e=await g((()=>this.wildfireClient.getStanddownPolicy()),this.getRetryOptions("Get Standdown policy"),{Domains:[],LostAttribution:[],Params:[],Serp:[]});return this.logger.info("Updated standdown policy"),e}async fetchMerchantRates(){const e=await g((()=>this.wildfireClient.getMerchantRates()),this.getRetryOptions("Fetch Merchant Rates"),{});return this.logger.debug("Updated Merchant rates"),e}static async createWildfireService(e,t){e.debug("Initializing wildfire service with config",t);const r=new V(t.wfSecret,t.wfAppId,t.deviceUrl,t.dataUrl,e),i=new te(r,e,t.vanityBaseUrl,t.refreshInterval),s=await D();return await i.refreshCache(s),i}}const re=e=>{try{return new URL(e),!0}catch{return!1}},ie=new Set,se=new Set,ne={urls:["<all_urls>"],types:["main_frame"]};class ae extends Error{constructor(e="Service not initialized"){super(e),this.name="UninitializedServiceError"}}const oe=e=>{if(!e)throw new ae};class ce{static register(e,t){this.strategies.set(e,t)}static get(e){return this.strategies.get(e)}static exists(e){return!!function(e){return"object"==typeof e&&null!==e&&"type"in e&&"payload"in e&&"string"==typeof e.type}(e)&&this.knownMessageTypes.has(e.type)}}ce.strategies=new Map,ce.knownMessageTypes=new Set([...Object.values(d)]);const le=e=>{let t;if(browser.webRequest){const r=(e=>{const t=e.getLogger();return({requestId:r,url:i,initiator:s})=>{try{if(ie.has(r)||se.has(r)||!re(i))return;const{hostname:n,search:a}=new URL(i);if(n.includes("wild.link"))return t.info("Cashback activation request identified, ignoring affiliate check for request"),void se.add(r);let o;s&&re(s)&&(o=new URL(s).hostname),(e.hasAffiliation([n,o],a)||e.isCustomStandownMatch([i,s]))&&(t.info("Affiliation found or custom standown match on url, adding request id to track"),ie.add(r))}catch(e){t.error("Error on handleAffiliateOnBeforeRequest",e)}}})(e);browser.webRequest.onBeforeRequest.addListener(r,ne);const i=(e=>{const t=e.getLogger();return async({requestId:r,redirectUrl:i})=>{try{if(!ie.has(r))return;t.info("Attempting to find active domain");const{hostname:s}=new URL(i),n=(await e.getActiveDomains()).find((e=>s===e.Domain||s.endsWith(`.${e.Domain}`)));if(!n)return;t.info("Found active domain. Updating standdown state"),await X(n.Domain)}catch(e){t.error("Error on handleAffiliateOnBeforeRedirect",e)}}})(e);browser.webRequest.onBeforeRedirect.addListener(i,ne);const s=(e=>{const t=e.getLogger();return({requestId:e})=>{try{ie.has(e)&&(t.info("Tracking request completed. Request Id:",e),ie.delete(e))}catch(e){t.error("Error on handleAffiliateOnCompleted",e)}}})(e);browser.webRequest.onCompleted.addListener(s,ne),t=()=>{browser.webRequest.onBeforeRequest.removeListener(r),browser.webRequest.onBeforeRedirect.removeListener(i),browser.webRequest.onCompleted.removeListener(s)}}const r=function(){const t=o.getInstance(),r=(r,i,s)=>{function n(e){s(e)}const a=(async t=>(e.getLogger().debug("Received message",{type:t.type,payload:t.payload}),ge(e,t)))(r,0);return a instanceof Promise?(a.then((e=>{e&&n(e)})).catch((e=>{t.warn("Async message callback error:",e)})),!0):!0===a||void 0};return h.runtime.onMessage.addListener(r),r}();return function(){t&&t(),browser.runtime.onMessage.removeListener(r)}},ge=async(e,t)=>{oe(e.isInitialized());const r=ce.get(t.type);if(!r)return;const i={giveFreelyService:e};return r.handle(t,i)};class he{async handle(e,t){const{activeDomain:i,originalUrl:s,selectedCharity:n}=e.payload,{giveFreelyService:a}=t,o=a.getLogger();o.debug("Activating offer",{activeDomain:i,selectedCharity:n});try{if(!n?.ein||!n?.thirdPartyId)throw new Error("Missing charity information");const e=await a.initializeWfDeviceId();if(!e)throw new Error("Failed to initialize Wildfire device ID");const t=await a.upsertUser(n,e);o.debug("Upserted user",{currentUser:t}),t||o.info("Failed to create user. Using default bucket's user");const r=await a.generateAffiliateUrl(i,s,t);return o.debug("Generated affiliate URL",{affiliateUrl:r}),(async e=>{const t=h.tabs.getCurrent(),r=await t,i=await h.tabs.create({url:e,openerTabId:r?.id,active:!1,pinned:!0});await(async e=>new Promise((t=>{h.tabs.onUpdated.addListener((async function r(i,s){if(i===e&&"complete"===s.status){if(h.tabs.onUpdated.removeListener(r),!(await h.tabs.get(e)).url)return void t(!1);t(!0)}}))})))(i.id)&&setTimeout((()=>{i?.id&&h.tabs.remove(i.id)}),3e4)})(r),await a.updateStanddownHistory(i.Domain),o.debug("Activated offer",{activeDomain:i,selectedCharity:n}),{type:d.ACTIVATE_OFFER,payload:{response:!0}}}catch(e){return o.error("Error activating offer",{activeDomain:i,error:e}),a.trackEvent(r.checkoutPopupFailedActivation,{activeDomain:i,error:e}),{type:d.ACTIVATE_OFFER,payload:{response:!1}}}}}class de{async handle(e,t){const{shopId:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger();try{const e=u,t=(await O.get(e)||[]).find((e=>e.shopId===r));return t?(s.debug("Found domain for shop ID",{shopId:r,domain:t.domain}),{type:d.GET_DOMAIN_BY_SHOP_ID,payload:{found:!0,domain:t.domain,shopInfo:t}}):(s.debug("No domain found for shop ID",{shopId:r}),{type:d.GET_DOMAIN_BY_SHOP_ID,payload:{found:!1}})}catch(e){return s.error("Error getting domain for shop ID",{shopId:r,error:e}),{type:d.GET_DOMAIN_BY_SHOP_ID,payload:{found:!1}}}}}class ue{async handle(e,t){const{lang:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger();s.debug("Getting language strings",{lang:r});try{const e=await i.getLanguage(r);return s.debug("Language strings fetched",{language:e}),{type:d.GET_LANGUAGE_CONTENT,payload:{translations:e.translations,charities:e.charities}}}catch(e){return s.error("Error getting language strings",{error:e}),{type:d.GET_LANGUAGE_CONTENT,payload:{translations:null,charities:null}}}}}class fe{async handle(e,t){const{giveFreelyService:r}=t,i=r.getLogger(),s=await r.getCachedConfig();try{return i.debug("Fetching popup config"),{type:d.GET_POPUP_CONFIG,payload:{config:s}}}catch(e){return i.error("Error fetching popup config",{error:e}),{type:d.GET_POPUP_CONFIG,payload:{config:null}}}}}class me{async handle(e,t){const{days:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger();try{const e=new Date;return e.setDate(e.getDate()+r),await O.set("popup_hide",{popupHide:e.getTime()}),s.debug("Popup hidden",{days:r,expiry:e}),{type:d.HIDE_POPUP,payload:{ack:!0}}}catch(e){return s.error("Error hiding popup",{days:r,error:e}),{type:d.HIDE_POPUP,payload:{ack:!1}}}}}class pe{async handle(e,t){const{hostname:r}=e.payload,{giveFreelyService:i}=t,s=i.getLogger(),n=await i.getConfig().merchantExclusions,a=await i.getActiveDomains();s.debug("Checking hostname",{hostname:r});try{if(i.healthCheck(),n.some((e=>e.disableDomain&&(r===e.domain||r.endsWith(`.${e.domain}`)))))return s.debug("Hostname is in merchant exclusions",{hostname:r}),{type:d.IS_ACTIVE_DOMAIN,payload:{isActive:!1,domain:void 0,rates:[]}};if(!a||0===a.length)throw new Error("No active domains");s.debug("Retrieved active domains",{count:a.length});const e=a.find((e=>r===e.Domain||r.endsWith(`.${e.Domain}`)));s.debug("Domain check result",{hostname:r,isActive:!!e});let t=[];if(e?.ID){const r=await i.getMerchantRates(e.Merchant.ID);r&&(s.debug("Retrieved merchant rates",{merchantRates:r}),t=r)}return{type:d.IS_ACTIVE_DOMAIN,payload:{isActive:!!e,domain:e,rates:t}}}catch(e){return s.error("Error checking domain",{hostname:r,error:e}),{type:d.IS_ACTIVE_DOMAIN,payload:{isActive:!1,domain:void 0,rates:[]}}}}}class Ae{async handle(e,t){const{currentUrl:i,searchResults:s,source:n}=e.payload,{giveFreelyService:a}=t,o=a.getLogger(),c=await a.getActiveDomains();o.debug("Finding merchants in search results",{currentUrl:i});try{const e=s.filter((e=>{try{const{hostname:t}=new URL(e.url);return c.some((e=>e.Domain===t||t.endsWith(`.${e.Domain}`)))}catch{return o.debug("Couldn't parse the following search result url",{x:e}),!1}}));if(o.info("Number of merchants identified in the search result",{number:e.length}),e.length>0){const s=Math.floor(Math.random()*Date.now());for(const a of e)t.giveFreelyService.trackEvent(r.checkoutPopupMerchantInResultsFound,{source:n,searchResultsId:s,currentUrl:i,searchResultUrl:a.url,sponsored:a.isSponsored},!0)}return{type:d.LOG_MERCHANTS_IN_SEARCH_RESULTS,payload:{result:!0}}}catch(e){return o.error("Error sending logs for merchants in search results",{currentUrl:i,error:e}),{type:d.LOG_MERCHANTS_IN_SEARCH_RESULTS,payload:{result:!1}}}}}class ye{async handle(e,t){const r=e.payload,{giveFreelyService:i}=t,s=i.getLogger();try{const e=u,t=await O.get(e)||[],i=t.findIndex((e=>e.shopId===r.shopId));return i>=0?t[i]=r:t.push(r),await O.set(e,t),s.debug("Stored Shopify shop ID",{shopInfo:r}),{type:d.STORE_SHOPIFY_SHOP_ID,payload:{success:!0}}}catch(e){return s.error("Error storing Shopify shop ID",{shopInfo:r,error:e}),{type:d.STORE_SHOPIFY_SHOP_ID,payload:{success:!1}}}}}class we{async handle(e,t){const{activeDomain:r,url:i}=e.payload,{giveFreelyService:s}=t,n=s.getLogger();n.debug("Checking if we should stand down",{activeDomain:r});try{const e=await s.shouldStandDown(r,i);return{type:d.SHOULD_STAND_DOWN,payload:{result:e}}}catch(e){return n.error("Error checking if we should stand down. Returning false",{activeDomain:r,error:e}),{type:d.SHOULD_STAND_DOWN,payload:{result:!1}}}}}class ve{async handle(e,t){const{eventType:r,eventData:i,anonymous:s,skipThrottling:n}=e.payload,{giveFreelyService:a}=t,o=a.getLogger();o.debug("Broadcasting event",{eventType:r,eventData:i,anonymous:s,skipThrottling:n});try{const e=await a.trackEvent(r,i,s,n);return{type:d.TRACK_EVENT,payload:{result:e}}}catch(e){return o.error("Error broadcasting event. Returning false",{eventType:r,eventData:i,error:e}),{type:d.TRACK_EVENT,payload:{result:!1}}}}}const Ce=o.getInstance(),Se=async()=>await O.get(A)||(async()=>{Ce.debug("detecting country");const e={method:"GET",headers:{"Content-Type":"application/json",Authorization:"Basic OTEzOTkxOnFlYmpaWF9DOGNRY0lxSHA4WTVjNGxzU1pRSlM2VW9MMExzTF9tbWs="}};try{const t=await fetch("https://geoip.maxmind.com/geoip/v2.1/country/me",e);if(Ce.debug("Received geolocation response",{status:t.status}),!t.ok)return void Ce.error("Failed to get geolocation data",{status:t.status,statusText:t.statusText});const r=await t.json();if(!r)throw new Error("There was an error fetching geoip look up");return await O.set(A,r.country.iso_code),r.country.iso_code}catch(e){return void Ce.error("Failed to get geolocation data",{error:e},!0)}})(),be="https://cdn.givefreely.com/adunit/language",Ee=async(e,t,r,i,s=[],n=!1)=>{const a=(s??[]).includes(r)?x:r;e.debug(`Requested lang ${r} and current lang ${a}`);const o=`lang-${x}`,c=await U.get(o,(async()=>(e.debug(`Fetching default language ${x} for partner ${t}`),Ie(t,x))),i||600,n);if(!c.content)throw new Error(`Failed to fetch default language ${x} and no cache version available`);if(x===a)return c.content;const l=`lang-${a}`,g=await U.get(l,(async()=>(e.debug(`Fetching language ${a} for partner ${t}`),Ie(t,a))),i||600,n);if(!g.content)return c.content;const h=_e(c.content,g.content);return await U.set(l,h,i||600),h},Ie=async(e,t)=>{const r=`/global-${t}.json`,i=`/${e}/${t}.json`,[s,n]=await Promise.allSettled([Te(`${be}${r}`),Te(`${be}${i}`)]);let a,o;"fulfilled"===s.status&&(a=s.value),"fulfilled"===n.status&&(o=n.value);const c=xe(a,o);return{translations:c.translations,charities:c.charities}},Te=async e=>{const t=await fetch(e,{cache:"no-store"});if(!t.ok)throw new Error(`Failed to fetch partner language file ${e}. Status: ${t.status}. Reason: ${t.statusText}`);return t.json()},xe=(e,t)=>({translations:{...e?.translations??{},...t??{}},charities:{...e?.charities??{}}}),_e=(e,t)=>({translations:{...e.translations,...t.translations},charities:{...e.charities,...t.charities}});async function Oe(e=async()=>(this.logger.debug("Using default partnerFilter."),!0)){if(!this.state.initialized){this.logger.info("Starting initialization with mutex protection");try{await this.dependencies.configService.initialize();const t=await this.dependencies.configService.getConfig(!0);this.logger.configure({enabled:t.loggingEnabled??!0,minLevel:t.backgroundMinLogLevel??"error"}),this.logger.info("Initializing GiveFreelyService",{partnerApiKey:this.partnerApiKey});const r=await te.createWildfireService(this.logger,t);this.state.healthCheck=new j(this.trackEvent.bind(this),this.logger),await this.state.healthCheck.initialize();const i=new K(this.partnerApiKey,t,this.logger);this.state.giveFreelyUserService=new B(i,this.logger),await this.state.giveFreelyUserService.fetchUser(),this.state.giveFreelyUserService.user?.id||await this.state.giveFreelyUserService.upsertUser(),this.state.analytics=new z(this.partnerApiKey,this.state.giveFreelyUserService,this.dependencies.configService);try{const e=await O.get(S);e?.DeviceID?(this.state.wfDeviceId=e,this.logger.info("Loaded existing wfDeviceId from storage",{deviceId:e.DeviceID})):this.logger.debug("No existing wfDeviceId found in storage - will be created on first offer activation")}catch(e){this.logger.debug("Could not check for existing wfDeviceId in storage",e)}ce.register(d.IS_ACTIVE_DOMAIN,new pe),ce.register(d.GET_POPUP_CONFIG,new fe),ce.register(d.HIDE_POPUP,new me),ce.register(d.SHOULD_STAND_DOWN,new we),ce.register(d.TRACK_EVENT,new ve),ce.register(d.ACTIVATE_OFFER,new he),ce.register(d.STORE_SHOPIFY_SHOP_ID,new ye),ce.register(d.GET_DOMAIN_BY_SHOP_ID,new de),ce.register(d.GET_LANGUAGE_CONTENT,new ue),ce.register(d.LOG_MERCHANTS_IN_SEARCH_RESULTS,new Ae),await(async e=>{try{await Se()}catch(t){e.debug("Failed to get geolocation data",{error:t})}})(this.logger),await(async(e,t,r)=>{t.purgeLanguages&&t.purgeLanguages.length>0&&await Promise.all(t.purgeLanguages.flatMap((e=>[U.clear(`lang-${e}`),U.clear(`global-${e}`)]))),g((async()=>{e.debug("Initializing default language with partner API key",{partnerApiKey:r}),await Ee(e,r,x,t.configRefreshInterval)}))})(this.logger,t,this.partnerApiKey),this.state=((e,t)=>{const{wildfireService:r,partnerFilter:i,config:s}=t;return{...e,initialized:!0,wildfireService:r,partnerFilter:i,config:s}})(this.state,{wildfireService:r,partnerFilter:e,config:t}),this.logger.addTransport(new n(this)),this.cleanupListeners=le(this),De.call(this),this.logger.info("GiveFreelyService initialized successfully")}catch(e){const t=e instanceof Error?e.message:"Unknown error";throw this.logger.error("Failed to initialize GiveFreelyService",{error:t}),new Error(`Failed to initialize GiveFreelyService: ${t}`)}}}function Pe(){return this.state.initialized}function De(){this.onConfigChange("wfAppId",(async e=>{this.logger.info(`Wildfire App ID changed from ${e.oldValue} to ${e.newValue} - clearing device`),await Fe.call(this)})),this.onConfigChange("wfSecret",(async e=>{this.logger.info("Wildfire Secret changed - clearing device"),await Fe.call(this)}))}async function Fe(){try{this.state.wildfireService&&(await this.state.wildfireService.clearDevice(),this.state.wfDeviceId=null,this.logger.info("Wildfire device cleared due to config change"))}catch(e){this.logger.error("Failed to clear wildfire device:",e)}}var Ue={config:Object.freeze({__proto__:null,getCachedConfig:async function(){return oe(this.state.initialized),this.state.config=await this.dependencies.configService.getConfig(),this.logger.configure({minLevel:this.state.config.backgroundMinLogLevel??"error"}),this.state.config},getConfig:function(){return oe(this.state.initialized),this.state.config},offConfigChange:function(e,t){oe(this.state.initialized),this.dependencies.configService.off(e,t)},onConfigChange:function(e,t){return oe(this.state.initialized),this.dependencies.configService.on(e,t)},onceConfigChange:function(e,t){return oe(this.state.initialized),this.dependencies.configService.once(e,t)}}),merchants:Object.freeze({__proto__:null,generateAffiliateUrl:async function(e,t,r){return oe(this.state.initialized),this.state.wildfireService.generateAffiliateUrl(e,t,r,this.state.partnerApiKey)},getActiveDomains:async function(){return oe(this.state.initialized),this.state.wildfireService.getActiveDomains()},getMerchantRates:async function(e){if(oe(this.state.initialized),!this.state.wildfireService)throw new Error("Wildfire service not initialized");return this.state.wildfireService.getMerchantRates(e)}}),observability:Object.freeze({__proto__:null,getLogger:function(){return oe(this.state.initialized),this.logger},healthCheck:async function(){oe(this.state.initialized),await this.state.healthCheck.check()},trackEvent:function(e,t,r=!1,i=!1){return oe(this.state.initialized),this.state.analytics.track(e,this.state.wfDeviceId?.DeviceID,t,r,i)}}),standdown:Object.freeze({__proto__:null,hasAffiliation:function(e,t){if(!this.state.wildfireService)return this.logger.warn("Wildfire service not initialized yet"),!1;const r=this.state.wildfireService.hasAffilliation(e,t);return r&&this.logger.info("WF Affiliation identified"),r},isCustomStandownMatch:function(e){const t=e.some((e=>this.getConfig().customStandownPolicy?.urlRegex?.some((t=>!!e&&function(e,t){return new RegExp(t).test(e)}(e,t)))));return t&&this.logger.info("Custom Standown identified"),t},shouldStandDown:async function(e,t){oe(this.state.initialized);const r=new URL(t);if(!await this.state.partnerFilter(r.hostname))return this.logger.info("Should standdown due to partner filter."),!0;if(this.getConfig().merchantExclusions.some((t=>t.mutePopups&&e===t.domain)))return this.logger.info("Should standdown due to merchant exclusions"),!0;const i=await this.state.wildfireService.shouldStandDown(this.logger,e,t);return i&&this.logger.info("Should standdown due to vendor policy"),i},updateStanddownHistory:function(e){return oe(this.state.initialized),X(e)}}),identity:Object.freeze({__proto__:null,getCurrentUser:function(){return oe(this.state.initialized),this.state.giveFreelyUserService.user},getLanguage:async function(e){return oe(this.state.initialized),Ee(this.logger,this.state.partnerApiKey,e,this.state.config?.configRefreshInterval,this.state.config?.ignoredLanguages)},initializeWfDeviceId:async function(){if(oe(this.state.initialized),this.state.wfDeviceId=await this.state.wildfireService.getDevice(),!this.state.wfDeviceId)throw new Error("Failed to initialize Wildfire device ID");return this.state.wfDeviceId.DeviceID},upsertUser:function(e,t){return oe(this.state.initialized),this.state.giveFreelyUserService.upsertUser(e,t)}})};class ke{constructor(e){this.partnerApiKey=e,this.cleanupListeners=null,this.initialize=Oe.bind(this),this.isInitialized=Pe.bind(this),this.getConfig=Ue.config.getConfig.bind(this),this.getCachedConfig=Ue.config.getCachedConfig.bind(this),this.onConfigChange=Ue.config.onConfigChange.bind(this),this.onceConfigChange=Ue.config.onceConfigChange.bind(this),this.offConfigChange=Ue.config.offConfigChange.bind(this),this.getLogger=Ue.observability.getLogger.bind(this),this.healthCheck=Ue.observability.healthCheck.bind(this),this.trackEvent=Ue.observability.trackEvent.bind(this),this.initializeWfDeviceId=Ue.identity.initializeWfDeviceId.bind(this),this.upsertUser=Ue.identity.upsertUser.bind(this),this.getCurrentUser=Ue.identity.getCurrentUser.bind(this),this.getLanguage=Ue.identity.getLanguage.bind(this),this.getActiveDomains=Ue.merchants.getActiveDomains.bind(this),this.generateAffiliateUrl=Ue.merchants.generateAffiliateUrl.bind(this),this.getMerchantRates=Ue.merchants.getMerchantRates.bind(this),this.shouldStandDown=Ue.standdown.shouldStandDown.bind(this),this.updateStanddownHistory=Ue.standdown.updateStanddownHistory.bind(this),this.hasAffiliation=Ue.standdown.hasAffiliation.bind(this),this.isCustomStandownMatch=Ue.standdown.isCustomStandownMatch.bind(this),this.dependencies={configService:new G(e)},this.logger=o.getInstance(),this.logger.configure({enabled:!0,title:"Background - GiveFreelyService"}),this.state=(e=>({initialized:!1,wildfireService:null,partnerFilter:null,config:null,wfDeviceId:null,analytics:null,giveFreelyUserService:null,partnerApiKey:e,healthCheck:null}))(e)}async destroy(){var e;this.logger.info("Destroying GiveFreelyService"),await Promise.all([this.dependencies.configService.clearCache(),this.state.wildfireService?.clearCache(),this.state.giveFreelyUserService?.resetUser()]),this.cleanupListeners&&(this.cleanupListeners(),this.logger.info("Event listeners cleared."),this.cleanupListeners=null),this.state=(e=this.state,{...e,initialized:!1,wildfireService:null,partnerFilter:null,analytics:null,config:null})}}class GiveFreelyService{constructor(e){this.partnerApiKey=e,this.initialize=e=>this._adUnitService.initialize(e),this.destroy=()=>this._adUnitService.destroy(),this._adUnitService=new ke(e)}}const Le=e=>ce.exists(e);export{GiveFreelyService,browser,Le as isAdUnitMessage};
2
2
  //# sourceMappingURL=GiveFreely-background.esm.js.map