!function() { "use strict"; const e = "cacheSharedState" , t = "__REQUESTLY__"; var r, s, o, n, i, a, u, c, l, h, p, d; !function(e) { e.GROUP = "group", e.RULE = "rule" }(r || (r = {})), function(e) { e.ACTIVE = "Active", e.INACTIVE = "Inactive" }(s || (s = {})), function(e) { e.REDIRECT = "Redirect", e.CANCEL = "Cancel", e.REPLACE = "Replace", e.HEADERS = "Headers", e.USERAGENT = "UserAgent", e.SCRIPT = "Script", e.QUERYPARAM = "QueryParam", e.RESPONSE = "Response", e.REQUEST = "Request", e.DELAY = "Delay" }(o || (o = {})), function(e) { e.URL = "Url", e.HOST = "host", e.PATH = "path" }(n || (n = {})), function(e) { e.EQUALS = "Equals", e.CONTAINS = "Contains", e.MATCHES = "Matches", e.WILDCARD_MATCHES = "Wildcard_Matches" }(i || (i = {})), function(e) { e.PAGE_DOMAINS = "pageDomains", e.REQUEST_METHOD = "requestMethod", e.RESOURCE_TYPE = "resourceType", e.REQUEST_PAYLOAD = "requestPayload" }(a || (a = {})), function(e) { e.XHR = "xmlhttprequest", e.JS = "script", e.CSS = "stylesheet", e.Image = "image", e.Media = "media", e.Font = "font", e.WebSocket = "websocket", e.MainDocument = "main_frame", e.IFrameDocument = "sub_frame" }(u || (u = {})), function(e) { e.GET = "GET", e.POST = "POST", e.PUT = "PUT", e.DELETE = "DELETE", e.PATCH = "PATCH", e.OPTIONS = "OPTIONS", e.CONNECT = "CONNECT", e.HEAD = "HEAD" }(c || (c = {})), function(e) { e.CUSTOM = "custom", e.ALL_PAGES = "allPages" }(l || (l = {})), function(e) { e.SESSION_RECORDING_CONFIG = "sessionRecordingConfig" }(h || (h = {})), function(e) { e.JS = "js", e.CSS = "css" }(p || (p = {})), function(e) { e.URL = "url", e.CODE = "code" }(d || (d = {})); var y, f, E = { browser: "chrome", storageType: "local", contextMenuContexts: ["browser_action"], env: "prod", WEB_URL: "https://app.requestly.io", SESSIONS_URL: "https://app.requestly.io/sessions", OTHER_WEB_URLS: ["https://app.requestly.com"], logLevel: "info" }; !function(e) { e[e.MODIFIED = 0] = "MODIFIED", e[e.CREATED = 1] = "CREATED", e[e.DELETED = 2] = "DELETED" }(y || (y = {})), function(e) { e.IS_EXTENSION_ENABLED = "isExtensionEnabled", e.EXTENSION_RULES_COUNT = "extensionRulesCount", e.TEST_SCRIPT = "testScript" }(f || (f = {})); const R = e => [...[...new Set([E.WEB_URL, ...E.OTHER_WEB_URLS])].map((e => ({ key: n.URL, operator: i.CONTAINS, value: e }))), { key: n.URL, operator: i.CONTAINS, value: "__rq" }].some((t => g(t, e))) , q = e => { const t = e.match(new RegExp("^/(.+)/(|i|g|ig|gi)$")); if (!t) return null; try { return new RegExp(t[1],t[2]) } catch (e) { return null } } , m = (e, t) => { e.startsWith("/") || (e = `/${e}/`); const r = q(e); return r?.test(t) } , S = e => "/^" + e.replace(/([?.-])/g, "\\$1").replace(/(\*)/g, "(.*)") + "$/" , g = (e, t) => { const r = ( (e, t) => { let r = null; try { r = new URL(e) } catch (e) {} if (r) switch (t) { case n.URL: return e; case n.HOST: return r.host; case n.PATH: return r.pathname } } )(t, e.key) , s = e.value; if (!(e.isActive ?? !0)) return !1; if (!r) return !1; switch (e.operator) { case i.EQUALS: if (s === r) return !0; break; case i.CONTAINS: if (-1 !== r.indexOf(s)) return !0; break; case i.MATCHES: return m(s, r); case i.WILDCARD_MATCHES: return ( (e, t) => { const r = S(e); return m(r, t) } )(s, r) } return !1 } , w = function(e, t) { if (!e || !t || Array.isArray(e) && 0 === e?.length) return !0; const r = Array.isArray(e) ? e[0] : e; return Object.entries(r).every(( ([e,r]) => { switch (e) { case a.PAGE_DOMAINS: return r.some((e => { const r = (e => { try { return new URL(e) } catch (e) { return null } } )(t.initiator); return (r?.hostname || "").endsWith(e) } )); case a.REQUEST_METHOD: return r.includes(t.method); case a.RESOURCE_TYPE: return r.includes(t.type); case a.REQUEST_PAYLOAD: return P(r, t.requestData); default: return !0 } } )) } , P = (e, t) => { if (!e) return !0; if ("object" == typeof e && 0 === Object.keys(e).length) return !0; if (!t || "object" != typeof t) return !1; if (0 === Object.keys(t).length) return !1; const r = e?.key , s = e?.value; if (r && void 0 !== typeof s) { const o = _(t, r) , n = e?.operator; let i = ""; if ("object" == typeof o || (i = o?.toString()), !n || "Equals" === n) return i === s; if ("Contains" === n) return i.includes(s) } return !1 } , D = function(e, t) { if (R(t.initiator) || R(t.url)) return {}; const r = e?.pairs?.find((e => g(e.source, t.url) && w(e.source.filters, t))); if (!r) return { isApplied: !1 }; return { isApplied: !0, matchedPair: r, destinationUrl: T(r, e.ruleType, t) } } , x = function(e, t) { return t.forEach((function(t, r) { 0 !== r && (t = t || "", e = e.replace(new RegExp("[$]" + r,"g"), t)) } )), e } , T = (e, t, r) => { switch (t) { case o.REPLACE: const t = r.url.replace(e.from, e.to); return t === r.url ? null : t; case o.REDIRECT: if (e.source.operator === i.MATCHES) { const t = q(e.source.value)?.exec(r.url); return t ? x(e.destination, t) : e.destination } if (e.source.operator === i.WILDCARD_MATCHES) { const t = e.source.value , s = S(t) , o = q(s)?.exec(r.url); return o ? x(e.destination, o) : e.destination } return e.destination; default: return null } } , _ = (e, t) => { if (!t) return; const r = t.split("."); try { for (let t = 0; t < r.length - 1; t++) e = e[r[t]]; return e[r[r.length - 1]] } catch (e) {} } ; let L = !1; const A = (e, t) => { try { return O(e) } catch (e) { return X({ initiator: location.origin, url: location.href }).then(( () => { L || (L = !0, console.log(`%cRequestly%c Please reload the page for ${t} rule to take effect`, "color: #3c89e8; padding: 1px 5px; border-radius: 4px; border: 1px solid #91caff;", "color: red; font-style: italic")) } )), () => {} } } , O = function(e) { const r = "$sharedState"; let s; try { s = window.top[t]?.sharedState ?? {} } catch (e) { s = window[t]?.sharedState ?? {} } const {func: o, updatedSharedState: n} = new Function(`${r}`,`return { func: ${e}, updatedSharedState: ${r}}`)(s); return o } , b = (e, t) => { const r = e.pairs[0].request; let s; return s = "static" === r.type ? r.value : A(r.value, "request")(t), "object" != typeof s || (o = s, [Blob, ArrayBuffer, Object.getPrototypeOf(Uint8Array), DataView, FormData, URLSearchParams].some((e => o instanceof e))) ? s : JSON.stringify(s); var o } , C = async (e, t) => { let r; window.postMessage({ ...e, action: t, source: "requestly:client" }, window.location.href); const s = `${t}:processed`; return Promise.race([new Promise((e => setTimeout(e, 2e3))), new Promise((e => { r = t => { t.data.action === s && e() } , window.addEventListener("message", r) } ))]).finally(( () => { window.removeEventListener("message", r) } )) } , H = async e => C({ requestDetails: e }, "onBeforeAjaxRequest") , X = async e => C({ requestDetails: e }, "onErrorOccurred") , U = e => !!e && ("object" == typeof e || "function" == typeof e) && "function" == typeof e.then , v = (e, t) => { const r = t ? {} : e; if ("string" != typeof e) return r; try { return JSON.parse(e) } catch (e) {} return r } , I = e => v(e) !== e , N = e => { window.top.postMessage({ source: "requestly:client", action: "response_rule_applied", rule: e.ruleDetails, requestDetails: e.requestDetails }, window.location.href) } , M = e => { window.top.postMessage({ source: "requestly:client", action: "request_rule_applied", rule: e.ruleDetails, requestDetails: e.requestDetails }, window.location.href) } , j = e => { const t = document.createElement("a"); return t.href = e, t.href } , Q = e => window[t]?.requestRules?.findLast((t => !0 === D(t, e)?.isApplied)) , W = e => window[t]?.responseRules?.findLast((t => !0 === D(t, e)?.isApplied)) , k = e => { if (!window[t]?.delayRules) return null; for (const r of window[t]?.delayRules) { const {isApplied: t, matchedPair: s} = D(r, e); return s } return null } , $ = e => { const t = e.pairs[0].response; return "static" === t.type && t.serveWithoutRequest } , G = e => !!e?.includes("application/json") , B = async e => new Promise((t => setTimeout(t, e))) , J = e => { const t = (e, t) => { Object.defineProperty(e, "readyState", { writable: !0 }), e.readyState = t, e.dispatchEvent(new CustomEvent("readystatechange")) } , r = XMLHttpRequest , s = function() { const s = this , o = (t, r) => { e && console.log("[RQ]", `on${t}`, r), s.dispatchEvent(new ProgressEvent(t,{ lengthComputable: r?.lengthComputable, loaded: r?.loaded, total: r?.total })) } , n = e => { t(s, e) } , i = new r; i.addEventListener("readystatechange", async function() { if (e && console.log("[RQ]", "onReadyStateChange", { state: this.readyState, status: this.status, response: this.response, xhr: this, url: this._requestURL }), !this.responseRule) return; const t = this.responseRule.pairs[0].response; if (this.readyState === this.HEADERS_RECEIVED) { const e = parseInt(t.statusCode || this.status) || 200 , r = t.statusText || this.statusText; Object.defineProperties(s, { status: { get: () => e }, statusText: { get: () => r }, getResponseHeader: { value: this.getResponseHeader.bind(this) }, getAllResponseHeaders: { value: this.getAllResponseHeaders.bind(this) } }), n(this.HEADERS_RECEIVED) } else if (this.readyState === this.DONE) { const r = this.responseType , i = this.getResponseHeader("content-type"); let a; if ("code" === t.type) { const e = { method: this._method, url: this._requestURL, requestHeaders: this._requestHeaders, requestData: v(this._requestData), responseType: i, response: this.response, responseJSON: v(this.response, !0) }; a = A(t.value, "response")(e) } else a = t.value; if (void 0 === a) return; U(a) && (a = await a), e && console.log("[RQ]", "Rule Applied - customResponse", { customResponse: a, responseType: r, contentType: i }); const u = r && !["json", "text"].includes(r); "static" === t.type && u && (a = this.response), u || "object" != typeof a || a instanceof Blob || "json" !== r && !G(i) || (a = JSON.stringify(a)), Object.defineProperty(s, "response", { get: function() { return "static" === t.type && "json" === r ? "object" == typeof a ? a : v(a) : a } }), "" !== r && "text" !== r || Object.defineProperty(s, "responseText", { get: function() { return a } }); const c = this.responseURL , l = this.responseXML; Object.defineProperties(s, { responseType: { get: function() { return r } }, responseURL: { get: function() { return c } }, responseXML: { get: function() { return l } } }); const h = { url: this._requestURL, method: this._method, type: "xmlhttprequest", timeStamp: Date.now() }; this._abort ? (o("abort"), o("loadend")) : (n(this.DONE), o("load"), o("loadend")), N({ ruleDetails: this.responseRule, requestDetails: h }) } else n(this.readyState) } .bind(i), !1), i.addEventListener("abort", o.bind(i, "abort"), !1), i.addEventListener("error", o.bind(i, "error"), !1), i.addEventListener("timeout", o.bind(i, "timeout"), !1), i.addEventListener("loadstart", o.bind(i, "loadstart"), !1), i.addEventListener("progress", o.bind(i, "progress"), !1); const a = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(this), "timeout"); a && Object.defineProperty(s, "timeout", { get: function() { return a.get.call(this) }, set: function(e) { i.timeout = e, a.set.call(this, e) } }), this.rqProxyXhr = i }; XMLHttpRequest = function() { const e = new r; return s.call(e), e } , XMLHttpRequest.prototype = r.prototype, Object.entries(r).map(( ([e,t]) => { XMLHttpRequest[e] = t } )); const o = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(t, r, s=!0) { o.apply(this, arguments); try { this.rqProxyXhr._method = t, this.rqProxyXhr._requestURL = j(r), this.rqProxyXhr._async = s, o.apply(this.rqProxyXhr, arguments) } catch (t) { e && console.log("[rqProxyXhr.open] error", t) } } ; const n = XMLHttpRequest.prototype.abort; XMLHttpRequest.prototype.abort = function() { e && console.log("abort called"), n.apply(this, arguments); try { this.rqProxyXhr._abort = !0, n.apply(this.rqProxyXhr, arguments) } catch (t) { e && console.log("[rqProxyXhr.abort] error", t) } } ; let i = XMLHttpRequest.prototype.setRequestHeader; XMLHttpRequest.prototype.setRequestHeader = function(t, r) { i.apply(this, arguments); try { this.rqProxyXhr._requestHeaders = this.rqProxyXhr._requestHeaders || {}, this.rqProxyXhr._requestHeaders[t] = r, i.apply(this.rqProxyXhr, arguments) } catch (t) { e && console.log("[rqProxyXhr.setRequestHeader] error", t) } } ; const a = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.send = async function(r) { try { if (!this.rqProxyXhr._async) return e && console.log("Async disabled"), a.call(this, r); this.rqProxyXhr._requestData = r; const s = k({ url: this.rqProxyXhr._requestURL, method: this.rqProxyXhr._method, type: "xmlhttprequest", initiator: location.origin }); s && (e && console.log("[xhrInterceptor] matchedDelayRulePair", { matchedDelayRulePair: s }), await B(s.delay)); const o = Q({ url: this.rqProxyXhr._requestURL, method: this.rqProxyXhr._method, type: "xmlhttprequest", initiator: location.origin }); if (o && (e && console.log("[xhrInterceptor] matchedRequestRule", { requestRule: o }), this.rqProxyXhr._requestData = b(o, { method: this.rqProxyXhr._method, url: this.rqProxyXhr._requestURL, body: r, bodyAsJson: v(r, !0) }), M({ ruleDetails: o, requestDetails: { url: this.rqProxyXhr._requestURL, method: this.rqProxyXhr._method, type: "xmlhttprequest", timeStamp: Date.now() } })), await H({ url: this.rqProxyXhr._requestURL, method: this.rqProxyXhr._method, type: "xmlhttprequest", initiator: location.origin, requestHeaders: this.rqProxyXhr._requestHeaders ?? {} }), this.responseRule = W({ url: this.rqProxyXhr._requestURL, requestData: v(this.rqProxyXhr._requestData), method: this.rqProxyXhr._method }), this.rqProxyXhr.responseRule = this.responseRule, this.responseRule) return e && console.log("[xhrInterceptor]", "send and response rule matched", this.responseRule), void ($(this.responseRule) ? (e && console.log("[xhrInterceptor]", "send and response rule matched and serveWithoutRequest is true"), ( (e, r) => { e.dispatchEvent(new ProgressEvent("loadstart")); const s = I(r) ? "application/json" : "text/plain"; e.getResponseHeader = e => "content-type" === e.toLowerCase() ? s : null, t(e, e.HEADERS_RECEIVED), t(e, e.LOADING), t(e, e.DONE) } )(this.rqProxyXhr, this.responseRule.pairs[0].response.value)) : a.call(this.rqProxyXhr, this.rqProxyXhr._requestData)); a.call(this, this.rqProxyXhr._requestData) } catch (t) { e && console.log("[rqProxyXhr.send] error", t), a.call(this, r) } } } ; ( () => { let r; try { r = window && window.localStorage && localStorage.isDebugMode } catch (e) {} J(r), (e => { const t = fetch; fetch = async (...r) => { const [s,o={}] = r , n = () => t(...r); try { let r; r = s instanceof Request ? s.clone() : new Request(s.toString(),o); const i = j(r.url) , a = r.method , u = k({ url: i, method: a, type: "fetch", initiator: location.origin }); u && await B(u.delay); const c = !["GET", "HEAD"].includes(a) , l = c && Q({ url: i, method: a, type: "fetch", initiator: location.origin }); if (l) { const e = await r.text() , t = b(l, { method: r.method, url: i, body: e, bodyAsJson: v(e, !0) }) || {}; r = new Request(r.url,{ method: a, body: t, headers: r.headers, referrer: r.referrer, referrerPolicy: r.referrerPolicy, mode: r.mode, credentials: r.credentials, cache: r.cache, redirect: r.redirect, integrity: r.integrity }), M({ ruleDetails: l, requestDetails: { url: i, method: r.method, type: "fetch", timeStamp: Date.now() } }) } let h; c && (h = v(await r.clone().text())); const p = W({ url: i, requestData: h, method: a }); let d, y, f; if (p && $(p)) { const e = I(p.pairs[0].response.value) ? "application/json" : "text/plain"; d = new Headers({ "content-type": e }) } else try { const e = {}; if (r?.headers?.forEach(( (t, r) => { e[r] = t } )), await H({ url: i, method: a, type: "xmlhttprequest", initiator: location.origin, requestHeaders: e }), y = l ? await t(r) : await n(), !p) return y; d = y?.headers } catch (e) { if (!p) return Promise.reject(e) } e && console.log("RQ", "Inside the fetch block for url", { url: i, resource: s, initOptions: o, fetchedResponse: y }); const E = p.pairs[0].response; if ("code" === E.type) { let e = { method: a, url: i, requestHeaders: r.headers && Array.from(r.headers).reduce(( (e, [t,r]) => (e[t] = r, e)), {}), requestData: h }; if (y) { const t = await y.text() , r = y.headers.get("content-type") , s = v(t, !0); e = { ...e, responseType: r, response: t, responseJSON: s } } if (f = A(E.value, "response")(e), void 0 === f) return y; U(f) && (f = await f), "object" == typeof f && G(e?.responseType) && (f = JSON.stringify(f)) } else f = E.value; const R = { url: i, method: a, type: "fetch", timeStamp: Date.now() }; N({ ruleDetails: p, requestDetails: R }); const q = parseInt(E.statusCode || y?.status) || 200 , m = [204, 205, 304].includes(q); return new Response(m ? null : new Blob([f]),{ status: q, statusText: E.statusText || y?.statusText, headers: d }) } catch (t) { return e && console.log("[RQ.fetch] Error in fetch", t), await n() } } } )(r), window.top === window.self && window.addEventListener("beforeunload", ( () => { window.top.postMessage({ source: "requestly:client", action: e, sharedState: window[t]?.sharedState }, window.location.href) } )) } )() }();