-
-
Save barbmarcio/0af1f85b634522f0168cea6ad7f472bd to your computer and use it in GitHub Desktop.
ts.js Diff 0.3.1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function (f) { | |
typeof define == "function" && define.amd ? define(f) : f(); | |
})(function () { | |
"use strict"; | |
var f = Object.defineProperty, | |
d = (e, t) => f(e, "name", { value: t, configurable: !0 }), | |
H = "https://api.topsort.com", | |
S = { auctions: "v2/auctions", events: "v2/events" }, | |
I = "0.3.1", | |
E = class { | |
constructor(t, s, r, n = !1) { | |
(this.status = t), | |
(this.statusText = s), | |
(this.body = r), | |
(this.retry = n); | |
} | |
}; | |
d(E, "AppError"); | |
var j = E, | |
u = j, | |
b = class { | |
async handleResponse(t) { | |
let s; | |
if ((t.status !== 204 && (s = await t.json()), !t.ok)) { | |
let r = t.status === 429 || t.status >= 500; | |
throw new u(t.status, t.statusText, s, r); | |
} | |
return s; | |
} | |
async request(t, s) { | |
try { | |
let r = this.sanitizeUrl(t), | |
n = await fetch(r, s); | |
return this.handleResponse(n); | |
} catch (r) { | |
let n = r instanceof Error ? r.message : "Unknown error"; | |
throw new u(500, "Internal Server Error", n); | |
} | |
} | |
setupTimeoutSignal(t) { | |
if (t.timeout != null) { | |
let s = new AbortController(); | |
return setTimeout(() => s.abort(), t.timeout), s.signal; | |
} | |
} | |
async post(t, s, r) { | |
let n = this.setupTimeoutSignal(r); | |
return this.request(t, { | |
method: "POST", | |
headers: { | |
"Content-Type": "application/json", | |
Accept: "application/json", | |
"X-UA": r.userAgent | |
? @topsort/sdk ${I} ${r.userAgent} | |
: @topsort/sdk ${I}, | |
Authorization: Bearer ${r.apiKey}, | |
}, | |
body: JSON.stringify(s), | |
signal: n, | |
}); | |
} | |
sanitizeUrl(t) { | |
try { | |
return new URL(t).href.replace(/\/+$/, ""); | |
} catch (s) { | |
throw new u(400, "Invalid URL", { error: Invalid URL: ${s} }); | |
} | |
} | |
}; | |
d(b, "APIClient"); | |
var B = b, | |
T = new B(); | |
function v(e) { | |
var t; | |
if (!((t = e == null ? void 0 : e.apiKey) != null && t.length)) | |
throw new u(401, "API Key is required.", {}); | |
} | |
d(v, "validateConfig"); | |
function y(e) { | |
return async (...t) => { | |
let s = t[t.length - 1]; | |
return v(s), e(...t); | |
}; | |
} | |
d(y, "withValidation"); | |
async function k(e, t) { | |
let s = ${t.host}/${S.auctions}; | |
return await T.post(s.toString(), e, t); | |
} | |
d(k, "handler"); | |
var D = y(k); | |
async function O(e, t) { | |
try { | |
let s = ${t.host}/${S.events}; | |
return await T.post(s, e, t), { ok: !0, retry: !1 }; | |
} catch (s) { | |
if (s instanceof u && s.retry) return { ok: !1, retry: !0 }; | |
throw s; | |
} | |
} | |
d(O, "handler"); | |
var K = y(O), | |
A = class { | |
constructor(t) { | |
(this.config = t), (this.config.host = this.config.host ?? H); | |
} | |
async reportEvent(t) { | |
return K(t, this.config); | |
} | |
async createAuction(t) { | |
return D(t, this.config); | |
} | |
}; | |
d(A, "TopsortClient"); | |
var X = A, | |
z = X; | |
const J = "2.3.1"; | |
class P { | |
constructor() { | |
this._data = []; | |
} | |
get() { | |
return this._data; | |
} | |
set(t) { | |
this._data = t; | |
} | |
} | |
class M { | |
constructor(t) { | |
(this._key = t), (this._storage = window.localStorage); | |
} | |
get() { | |
const t = this._storage.getItem(this._key); | |
return t ? JSON.parse(t) : []; | |
} | |
set(t) { | |
this._storage.setItem(this._key, JSON.stringify(t)); | |
} | |
} | |
class Y { | |
constructor(t) { | |
(this._key = t), | |
(this._storage = window.sessionStorage), | |
(this._bid = void 0); | |
} | |
get() { | |
try { | |
return this._storage.getItem(this._key) ?? void 0; | |
} catch { | |
return this._bid; | |
} | |
} | |
set(t) { | |
this._bid = t; | |
try { | |
this._storage.setItem(this._key, t); | |
} catch {} | |
} | |
} | |
const G = "ts-t", | |
Z = "ts-q", | |
V = 250, | |
W = 3, | |
F = 25, | |
Q = 250, | |
C = 9, | |
tt = 0; | |
function et(e, t) { | |
return t > 0 ? e + (Math.random() + Math.pow(2, t)) * 1e3 : 0; | |
} | |
function st() { | |
var t; | |
const e = new M(G); | |
try { | |
const s = "3"; | |
if ((e.set([{ x: s }]), ((t = e.get()[0]) == null ? void 0 : t.x) === s)) | |
return new M(Z); | |
} catch {} | |
return new P(); | |
} | |
class rt { | |
constructor(t) { | |
(this._store = st()), | |
(this._processing = new Set()), | |
(this._scheduled = !1), | |
(this._processor = t); | |
} | |
append(t, s) { | |
let r = this._store.get(); | |
r.push({ e: t, r: 0, p: s != null && s.highPriority ? C : tt }), | |
(r = r.slice(-V)), | |
this._setEntries(r); | |
} | |
async _processNow(t) { | |
if (!t.length) return; | |
const s = []; | |
for (let i = t.length - 1; i >= 0 && s.length < F; i--) { | |
const a = t[i], | |
h = a == null ? void 0 : a.e; | |
h && | |
!this._processing.has(h.id) && | |
et(h.t, a.r) <= Date.now() && | |
(s.push(h), this._processing.add(h.id)); | |
} | |
if (!s.length) { | |
this._scheduleProcessing(); | |
return; | |
} | |
let r = { done: new Set(), retry: new Set() }; | |
try { | |
r = await this._processor(s); | |
} catch { | |
for (const a of s) r.done.add(a.id); | |
} | |
const n = []; | |
for (const i of this._processing) s.find((a) => a.id === i) || n.push(i); | |
this._processing = new Set(n); | |
const o = this._store.get(), | |
c = []; | |
for (const i of o) | |
r.done.has(i.e.id) || | |
(r.retry.has(i.e.id) | |
? i.r < W && ((i.r += 1), c.push(i)) | |
: c.push(i)); | |
this._setEntries(c); | |
} | |
_setEntries(t) { | |
this._store.set(t), | |
t.length && | |
(t.some((s) => s.p === C) || this._store instanceof P | |
? this._processNow(t) | |
: this._scheduleProcessing()); | |
} | |
_scheduleProcessing() { | |
this._scheduled || | |
((this._scheduled = !0), | |
setTimeout(() => { | |
(this._scheduled = !1), this._processNow(this._store.get()); | |
}, Q)); | |
} | |
} | |
function nt(e, t) { | |
if (e.size <= t) return e; | |
const s = e.values(); | |
for (let r = 0; r < e.size - t; ++r) s.next(); | |
return new Set(s); | |
} | |
const ot = 2500, | |
it = 0.5; | |
let p = new Set(); | |
const N = new Y("ts-b"); | |
function R() { | |
var e, t; | |
return ( | |
((t = (e = window.URL).createObjectURL) == null | |
? void 0 | |
: t.call(e, new Blob()).split("/").pop()) || Math.random() + "" | |
); | |
} | |
let l; | |
function _() { | |
if (l) return l; | |
const e = at(); | |
if (e) return (l = e), e; | |
const t = R(); | |
return U(t), t; | |
} | |
function U(e) { | |
const t = window.TS.cookieName || "tsuid"; | |
(l = e), (document.cookie = t + "=" + e + ";max-age=31536000"); | |
} | |
function ct() { | |
return (l = void 0), (document.cookie = "tsuid="), _(); | |
} | |
(window.TS.setUserId = U), | |
(window.TS.getUserId = _), | |
(window.TS.resetUserId = ct); | |
function at() { | |
var s; | |
const e = window.TS.cookieName || "tsuid"; | |
return (s = new RegExp("(^|;)\\s*" + e + "\\s*=\\s*([^;]+)").exec( | |
document.cookie | |
)) == null | |
? void 0 | |
: s.pop(); | |
} | |
function dt(e) { | |
const t = e.type, | |
s = { path: e.page }; | |
let r; | |
e.product && (r = { type: "product", id: e.product }); | |
let n; | |
e.additionalProduct && (n = { type: "product", id: e.additionalProduct }); | |
const o = new Date(e.t).toISOString(); | |
switch (t) { | |
case "Click": | |
return { | |
clicks: [ | |
{ | |
resolvedBidId: e.bid, | |
entity: r, | |
additionalAttribution: n, | |
placement: s, | |
occurredAt: o, | |
opaqueUserId: e.uid, | |
id: e.id, | |
}, | |
], | |
}; | |
case "Impression": | |
return { | |
impressions: [ | |
{ | |
resolvedBidId: e.bid, | |
entity: r, | |
additionalAttribution: n, | |
placement: s, | |
occurredAt: o, | |
opaqueUserId: e.uid, | |
id: e.id, | |
}, | |
], | |
}; | |
case "Purchase": | |
return { | |
purchases: [ | |
{ | |
occurredAt: o, | |
opaqueUserId: e.uid, | |
items: (e.items || []).map((c) => ({ | |
productId: c.product, | |
quantity: c.quantity, | |
unitPrice: c.price, | |
})), | |
id: e.id, | |
}, | |
], | |
}; | |
} | |
} | |
async function ut(e) { | |
const t = { done: new Set(), retry: new Set() }, | |
s = [], | |
r = { | |
apiKey: window.TS.token, | |
host: window.TS.url, | |
userAgent: ts.js/${J}, | |
}, | |
n = new z(r); | |
for (const o of e) | |
s.push( | |
n | |
.reportEvent(dt(o)) | |
.then((c) => { | |
(c.retry ? t.retry : t.done).add(o.id); | |
}) | |
.catch(() => { | |
t.done.add(o.id); | |
}) | |
); | |
return await Promise.all(s), t; | |
} | |
const lt = new rt(ut); | |
function w(e, t) { | |
const s = ht(e); | |
if (p.has(s)) return; | |
p.add(s), (p = nt(p, ot)), lt.append(e); | |
const r = new CustomEvent("topsort", { bubbles: !0, detail: e }); | |
t.dispatchEvent(r); | |
} | |
function ht(e) { | |
const t = JSON.stringify(e.items || []); | |
return [e.page, e.type, e.product ?? e.additionalProduct, e.bid, t].join( | |
"-" | |
); | |
} | |
function ft() { | |
const e = window.location, | |
t = e.hash; | |
return t[1] === "/" ? t : ${e.pathname}${e.search}; | |
} | |
function g(e, t) { | |
let s = t.dataset.tsProduct, | |
r = t.dataset.tsResolvedBid, | |
n; | |
r == "inherit" && | |
s && | |
(e == "Click" || e == "Impression") && | |
((r = N.get()), (n = s), (s = void 0)); | |
const o = { | |
type: e, | |
product: s, | |
additionalProduct: n, | |
bid: r, | |
t: Date.now(), | |
page: ft(), | |
id: R(), | |
uid: _(), | |
}; | |
return ( | |
e === "Purchase" && (o.items = JSON.parse(t.dataset.tsItems || "[]")), o | |
); | |
} | |
function pt(e) { | |
if (!(e.currentTarget instanceof HTMLElement)) return; | |
const t = e.currentTarget.closest(L); | |
if (t && t instanceof HTMLElement) { | |
const s = g("Click", t); | |
w(s, t), s.bid && N.set(s.bid); | |
} | |
} | |
const m = window.IntersectionObserver | |
? new IntersectionObserver( | |
(e) => { | |
for (const t of e) | |
if (t.isIntersecting) { | |
const s = t.target; | |
s instanceof HTMLElement && | |
(w(g("Impression", s), s), m && m.unobserve(s)); | |
} | |
}, | |
{ threshold: it } | |
) | |
: void 0, | |
L = | |
"[data-ts-product],[data-ts-action],[data-ts-items],[data-ts-resolved-bid]"; | |
function wt(e) { | |
const t = e.querySelectorAll("[data-ts-clickable]"); | |
(t.length === 0 ? [e] : t).forEach((r) => r.addEventListener("click", pt)); | |
} | |
function q(e) { | |
gt(e) | |
? w(g("Purchase", e), e) | |
: (m ? m.observe(e) : w(g("Impression", e), e), wt(e)); | |
} | |
function $(e) { | |
const t = e.querySelectorAll(L); | |
for (let s = 0; s < t.length; s++) { | |
const r = t[s]; | |
r instanceof HTMLElement && q(r); | |
} | |
} | |
function gt(e) { | |
return e.dataset.tsAction === "purchase"; | |
} | |
function mt(e) { | |
for (const t of e) | |
if (t.type === "childList") { | |
const s = new Set(); | |
for (let r = 0; r < t.addedNodes.length; r++) { | |
const n = t.addedNodes[r]; | |
if ((n == null ? void 0 : n.nodeType) === Node.ELEMENT_NODE) { | |
const o = n.parentElement; | |
o && !s.has(o) && s.add(o); | |
} | |
for (const o of s) $(o); | |
} | |
} else if (t.type === "attributes") { | |
if (!(t.target instanceof HTMLElement)) continue; | |
q(t.target); | |
} | |
} | |
function x() { | |
var s, r; | |
if ((s = window.TS) != null && s.loaded) return; | |
if (((window.TS.loaded = !0), !((r = window.TS) != null && r.token))) { | |
console.error("Missing TS token"); | |
return; | |
} | |
$(document); | |
const e = | |
window.MutationObserver || | |
window.WebKitMutationObserver || | |
window.MozMutationObserver; | |
new e(mt).observe(document, { | |
attributes: !0, | |
childList: !0, | |
subtree: !0, | |
attributeFilter: [ | |
"data-ts-product", | |
"data-ts-action", | |
"data-ts-items", | |
"data-ts-resolved-bid", | |
], | |
}); | |
} | |
/complete|interactive|loaded/.test(document.readyState) | |
? x() | |
: window.addEventListener("DOMContentLoaded", x); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function (p) { | |
typeof define == "function" && define.amd ? define(p) : p(); | |
})(function () { | |
"use strict"; | |
var p = Object.defineProperty, | |
d = (e, t) => p(e, "name", { value: t, configurable: !0 }), | |
l = "https://api.topsort.com", | |
w = { auctions: "v2/auctions", events: "v2/events" }, | |
I = "0.2.0", | |
E = class { | |
constructor(t, s, n, r = !1) { | |
(this.status = t), | |
(this.statusText = s), | |
(this.body = n), | |
(this.retry = r); | |
} | |
}; | |
d(E, "AppError"); | |
var x = E, | |
u = x, | |
b = class { | |
constructor(t) { | |
this.baseUrl = t; | |
} | |
async handleResponse(t) { | |
let s = t.headers.get("Content-Type") || "", | |
n; | |
if ( | |
(s.includes("application/json") | |
? (n = await t.json()) | |
: (n = await t.text()), | |
!t.ok) | |
) { | |
let r = t.status === 429 || t.status >= 500; | |
throw new u(t.status, t.statusText, n, r); | |
} | |
return n; | |
} | |
async request(t, s) { | |
try { | |
let n = await fetch(`${t ?? this.baseUrl}`, s); | |
return this.handleResponse(n); | |
} catch (n) { | |
let r = n instanceof Error ? n.message : "Unknown error"; | |
throw new u(500, "Internal Server Error", r); | |
} | |
} | |
async post(t, s, n) { | |
return this.request(t, { | |
method: "POST", | |
headers: { | |
"Content-Type": "application/json", | |
Accept: "application/json", | |
"X-UA": n.userAgent | |
? `@topsort/sdk ${I} ${n.userAgent}` | |
: `@topsort/sdk ${I}`, | |
Authorization: `Bearer ${n.apiKey}`, | |
}, | |
body: JSON.stringify(s), | |
}); | |
} | |
}; | |
d(b, "APIClient"); | |
var H = b, | |
T = new H(`${l}`); | |
function v(e) { | |
var t; | |
if (!((t = e == null ? void 0 : e.apiKey) != null && t.length)) | |
throw new u(401, "API Key is required.", {}); | |
} | |
d(v, "validateConfig"); | |
function k(e) { | |
return async (t, ...s) => (v(t), e(t, ...s)); | |
} | |
d(k, "withValidation"); | |
async function j(e, t) { | |
let s; | |
try { | |
s = new URL(`${e.host || l}/${w.auctions}`); | |
} catch { | |
throw new u(400, "Invalid URL", { | |
error: `Invalid URL: ${e.host || l}/${w.auctions}`, | |
}); | |
} | |
return await T.post(s.toString(), t, e); | |
} | |
d(j, "handler"); | |
async function O(e, t) { | |
let s; | |
try { | |
s = new URL(`${e.host || l}/${w.events}`); | |
} catch { | |
throw new u(400, "Invalid URL", { | |
error: `Invalid URL: ${e.host || l}/${w.events}`, | |
}); | |
} | |
try { | |
return await T.post(s.toString(), t, e), { ok: !0, retry: !1 }; | |
} catch (n) { | |
if (n instanceof u && n.retry) return { ok: !1, retry: !0 }; | |
throw n; | |
} | |
} | |
d(O, "handler"); | |
var B = k(O); | |
const D = "2.3.1"; | |
class P { | |
constructor() { | |
this._data = []; | |
} | |
get() { | |
return this._data; | |
} | |
set(t) { | |
this._data = t; | |
} | |
} | |
class A { | |
constructor(t) { | |
(this._key = t), (this._storage = window.localStorage); | |
} | |
get() { | |
const t = this._storage.getItem(this._key); | |
return t ? JSON.parse(t) : []; | |
} | |
set(t) { | |
this._storage.setItem(this._key, JSON.stringify(t)); | |
} | |
} | |
class K { | |
constructor(t) { | |
(this._key = t), | |
(this._storage = window.sessionStorage), | |
(this._bid = void 0); | |
} | |
get() { | |
try { | |
return this._storage.getItem(this._key) ?? void 0; | |
} catch { | |
return this._bid; | |
} | |
} | |
set(t) { | |
this._bid = t; | |
try { | |
this._storage.setItem(this._key, t); | |
} catch {} | |
} | |
} | |
const X = "ts-t", | |
J = "ts-q", | |
Y = 250, | |
z = 3, | |
G = 25, | |
Z = 250, | |
M = 9, | |
F = 0; | |
function V(e, t) { | |
return t > 0 ? e + (Math.random() + Math.pow(2, t)) * 1e3 : 0; | |
} | |
function W() { | |
var t; | |
const e = new A(X); | |
try { | |
const s = "3"; | |
if ((e.set([{ x: s }]), ((t = e.get()[0]) == null ? void 0 : t.x) === s)) | |
return new A(J); | |
} catch {} | |
return new P(); | |
} | |
class Q { | |
constructor(t) { | |
(this._store = W()), | |
(this._processing = new Set()), | |
(this._scheduled = !1), | |
(this._processor = t); | |
} | |
append(t, s) { | |
let n = this._store.get(); | |
n.push({ e: t, r: 0, p: s != null && s.highPriority ? M : F }), | |
(n = n.slice(-Y)), | |
this._setEntries(n); | |
} | |
async _processNow(t) { | |
if (!t.length) return; | |
const s = []; | |
for (let i = t.length - 1; i >= 0 && s.length < G; i--) { | |
const a = t[i], | |
f = a == null ? void 0 : a.e; | |
f && | |
!this._processing.has(f.id) && | |
V(f.t, a.r) <= Date.now() && | |
(s.push(f), this._processing.add(f.id)); | |
} | |
if (!s.length) { | |
this._scheduleProcessing(); | |
return; | |
} | |
let n = { done: new Set(), retry: new Set() }; | |
try { | |
n = await this._processor(s); | |
} catch { | |
for (const a of s) n.done.add(a.id); | |
} | |
const r = []; | |
for (const i of this._processing) s.find((a) => a.id === i) || r.push(i); | |
this._processing = new Set(r); | |
const o = this._store.get(), | |
c = []; | |
for (const i of o) | |
n.done.has(i.e.id) || | |
(n.retry.has(i.e.id) | |
? i.r < z && ((i.r += 1), c.push(i)) | |
: c.push(i)); | |
this._setEntries(c); | |
} | |
_setEntries(t) { | |
this._store.set(t), | |
t.length && | |
(t.some((s) => s.p === M) || this._store instanceof P | |
? this._processNow(t) | |
: this._scheduleProcessing()); | |
} | |
_scheduleProcessing() { | |
this._scheduled || | |
((this._scheduled = !0), | |
setTimeout(() => { | |
(this._scheduled = !1), this._processNow(this._store.get()); | |
}, Z)); | |
} | |
} | |
function tt(e, t) { | |
if (e.size <= t) return e; | |
const s = e.values(); | |
for (let n = 0; n < e.size - t; ++n) s.next(); | |
return new Set(s); | |
} | |
const et = 2500, | |
st = 0.5; | |
let g = new Set(); | |
const R = new K("ts-b"); | |
function U() { | |
var e, t; | |
return ( | |
((t = (e = window.URL).createObjectURL) == null | |
? void 0 | |
: t.call(e, new Blob()).split("/").pop()) || Math.random() + "" | |
); | |
} | |
let h; | |
function S() { | |
if (h) return h; | |
const e = rt(); | |
if (e) return (h = e), e; | |
const t = U(); | |
return L(t), t; | |
} | |
function L(e) { | |
const t = window.TS.cookieName || "tsuid"; | |
(h = e), (document.cookie = t + "=" + e + ";max-age=31536000"); | |
} | |
function nt() { | |
return (h = void 0), (document.cookie = "tsuid="), S(); | |
} | |
(window.TS.setUserId = L), | |
(window.TS.getUserId = S), | |
(window.TS.resetUserId = nt); | |
function rt() { | |
var s; | |
const e = window.TS.cookieName || "tsuid"; | |
return (s = new RegExp("(^|;)\\s*" + e + "\\s*=\\s*([^;]+)").exec( | |
document.cookie | |
)) == null | |
? void 0 | |
: s.pop(); | |
} | |
function ot(e) { | |
const t = e.type, | |
s = { path: e.page }; | |
let n; | |
e.product && (n = { type: "product", id: e.product }); | |
let r; | |
e.additionalProduct && (r = { type: "product", id: e.additionalProduct }); | |
const o = new Date(e.t).toISOString(); | |
switch (t) { | |
case "Click": | |
return { | |
clicks: [ | |
{ | |
resolvedBidId: e.bid, | |
entity: n, | |
additionalAttribution: r, | |
placement: s, | |
occurredAt: o, | |
opaqueUserId: e.uid, | |
id: e.id, | |
}, | |
], | |
}; | |
case "Impression": | |
return { | |
impressions: [ | |
{ | |
resolvedBidId: e.bid, | |
entity: n, | |
additionalAttribution: r, | |
placement: s, | |
occurredAt: o, | |
opaqueUserId: e.uid, | |
id: e.id, | |
}, | |
], | |
}; | |
case "Purchase": | |
return { | |
purchases: [ | |
{ | |
occurredAt: o, | |
opaqueUserId: e.uid, | |
items: (e.items || []).map((c) => ({ | |
productId: c.product, | |
quantity: c.quantity, | |
unitPrice: c.price, | |
})), | |
id: e.id, | |
}, | |
], | |
}; | |
} | |
} | |
async function it(e) { | |
const t = { done: new Set(), retry: new Set() }, | |
s = [], | |
n = { | |
apiKey: window.TS.token, | |
host: window.TS.url, | |
userAgent: `ts.js/${D}`, | |
}; | |
for (const r of e) | |
s.push( | |
B(n, ot(r)) | |
.then((o) => { | |
(o.retry ? t.retry : t.done).add(r.id); | |
}) | |
.catch(() => { | |
t.done.add(r.id); | |
}) | |
); | |
return await Promise.all(s), t; | |
} | |
const ct = new Q(it); | |
function y(e, t) { | |
const s = at(e); | |
if (g.has(s)) return; | |
g.add(s), (g = tt(g, et)), ct.append(e); | |
const n = new CustomEvent("topsort", { bubbles: !0, detail: e }); | |
t.dispatchEvent(n); | |
} | |
function at(e) { | |
const t = JSON.stringify(e.items || []); | |
return [e.page, e.type, e.product ?? e.additionalProduct, e.bid, t].join( | |
"-" | |
); | |
} | |
function dt() { | |
const e = window.location, | |
t = e.hash; | |
return t[1] === "/" ? t : `${e.pathname}${e.search}`; | |
} | |
function _(e, t) { | |
let s = t.dataset.tsProduct, | |
n = t.dataset.tsResolvedBid, | |
r; | |
n == "inherit" && | |
s && | |
(e == "Click" || e == "Impression") && | |
((n = R.get()), (r = s), (s = void 0)); | |
const o = { | |
type: e, | |
product: s, | |
additionalProduct: r, | |
bid: n, | |
t: Date.now(), | |
page: dt(), | |
id: U(), | |
uid: S(), | |
}; | |
return ( | |
e === "Purchase" && (o.items = JSON.parse(t.dataset.tsItems || "[]")), o | |
); | |
} | |
function ut(e) { | |
if (!(e.currentTarget instanceof HTMLElement)) return; | |
const t = e.currentTarget.closest(N); | |
if (t && t instanceof HTMLElement) { | |
const s = _("Click", t); | |
y(s, t), s.bid && R.set(s.bid); | |
} | |
} | |
const m = window.IntersectionObserver | |
? new IntersectionObserver( | |
(e) => { | |
for (const t of e) | |
if (t.isIntersecting) { | |
const s = t.target; | |
s instanceof HTMLElement && | |
(y(_("Impression", s), s), m && m.unobserve(s)); | |
} | |
}, | |
{ threshold: st } | |
) | |
: void 0, | |
N = | |
"[data-ts-product],[data-ts-action],[data-ts-items],[data-ts-resolved-bid]"; | |
function lt(e) { | |
const t = e.querySelectorAll("[data-ts-clickable]"); | |
(t.length === 0 ? [e] : t).forEach((n) => n.addEventListener("click", ut)); | |
} | |
function C(e) { | |
ht(e) | |
? y(_("Purchase", e), e) | |
: (m ? m.observe(e) : y(_("Impression", e), e), lt(e)); | |
} | |
function $(e) { | |
const t = e.querySelectorAll(N); | |
for (let s = 0; s < t.length; s++) { | |
const n = t[s]; | |
n instanceof HTMLElement && C(n); | |
} | |
} | |
function ht(e) { | |
return e.dataset.tsAction === "purchase"; | |
} | |
function ft(e) { | |
for (const t of e) | |
if (t.type === "childList") { | |
const s = new Set(); | |
for (let n = 0; n < t.addedNodes.length; n++) { | |
const r = t.addedNodes[n]; | |
if ((r == null ? void 0 : r.nodeType) === Node.ELEMENT_NODE) { | |
const o = r.parentElement; | |
o && !s.has(o) && s.add(o); | |
} | |
for (const o of s) $(o); | |
} | |
} else if (t.type === "attributes") { | |
if (!(t.target instanceof HTMLElement)) continue; | |
C(t.target); | |
} | |
} | |
function q() { | |
var s, n; | |
if ((s = window.TS) != null && s.loaded) return; | |
if (((window.TS.loaded = !0), !((n = window.TS) != null && n.token))) { | |
console.error("Missing TS token"); | |
return; | |
} | |
$(document); | |
const e = | |
window.MutationObserver || | |
window.WebKitMutationObserver || | |
window.MozMutationObserver; | |
new e(ft).observe(document, { | |
attributes: !0, | |
childList: !0, | |
subtree: !0, | |
attributeFilter: [ | |
"data-ts-product", | |
"data-ts-action", | |
"data-ts-items", | |
"data-ts-resolved-bid", | |
], | |
}); | |
} | |
/complete|interactive|loaded/.test(document.readyState) | |
? q() | |
: window.addEventListener("DOMContentLoaded", q); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment