PageSourceSearch

https://www.bangordailynews.com/wp-content/plugins/bdn-prosperstac…/prosperstack-logic.js?ver=1790237818

js bangordailynews.com collected 2026-09-24 08:24:42 UTC 6,170 bytes, 206 lines download raw bytes

1(function () {
2    console.log("BDN Prosperstack: Script loaded and monitoring for buttons...");
3    const CLIENT_ID = "acct_l7PMT7JDhrIem4NhpPsKML55";
4    const SRC = "https://cdn.prosperstack.com/flow/latest/flow.min.js";
5    const BUTTON_SELECTOR = ".pelcro-dashboard-sub-cancel-button";
6    const DEBUG = false;
7
8    function loadProsperStack() {
9        console.log("LOAD Prosperstack");
10        if (window.ProsperStack?.flow) {
11            return Promise.resolve(window.ProsperStack.flow);
12        }
13
14        if (window.__psLoad) {
15            return window.__psLoad;
16        }
17
18        window.__psLoad = new Promise((resolve, reject) => {
19            const s = document.createElement("script");
20            s.src = SRC;
21            s.async = true;
22            s.onload = function () {
23                if (window.ProsperStack?.flow) {
24                    resolve(window.ProsperStack.flow);
25                } else {
26                    reject(new Error("ProsperStack flow failed to load"));
27                }
28            };
29            s.onerror = reject;
30            document.head.appendChild(s);
31        });
32
33        return window.__psLoad;
34    }
35
36    function getPelcroUser() {
37        return window.Pelcro?.user?.read?.() || null;
38    }
39
40    function buildPayload(subscriptionId) {
41        const user = getPelcroUser();
42        if (!user || !subscriptionId) return null;
43
44        const sub = (user.subscriptions || []).find(function (s) {
45            return String(s?.id) === String(subscriptionId);
46        });
47
48        if (!sub) return null;
49
50        const name =
51            user.name ||
52            user.full_name ||
53            [user.first_name, user.last_name].filter(Boolean).join(" ");
54
55        const internalId = String(user.id || "").trim();
56        const trimmedName = String(name || "").trim();
57        const email = String(user.email || "").trim();
58
59        if (!internalId || !trimmedName || !email) return null;
60
61        return {
62            clientId: CLIENT_ID,
63            subscriber: {
64                internalId: internalId,
65                name: trimmedName,
66                email: email,
67            },
68            subscription: {
69                platformId: String(sub.id),
70                properties: {
71                    pelcro_status: sub.status,
72                    pelcro_plan_nickname: sub.plan?.nickname,
73                    pelcro_plan_interval: sub.plan?.interval,
74                    pelcro_plan_interval_count: sub.plan?.interval_count,
75                    pelcro_product_name: sub.plan?.product?.name,
76                    pelcro_current_period_end: sub.current_period_end,
77                },
78            },
79        };
80    }
81
82    function cloneAndReplaceButton(btn) {
83        const cleanBtn = btn.cloneNode(true);
84        cleanBtn.dataset.psBound = "true";
85        cleanBtn.dataset.psFallbackReady = "true";
86        btn.replaceWith(cleanBtn);
87        return cleanBtn;
88    }
89
90    function restoreOriginalBehavior(btn) {
91        if (!btn || btn.dataset.psFallbackReady !== "true") return btn;
92
93        const restoredBtn = btn.cloneNode(true);
94        delete restoredBtn.dataset.psBound;
95        delete restoredBtn.dataset.psFallbackReady;
96        restoredBtn.dataset.psRestoreBypass = "true";
97
98        btn.replaceWith(restoredBtn);
99
100        setTimeout(function () {
101            delete restoredBtn.dataset.psRestoreBypass;
102        }, 0);
103
104        return restoredBtn;
105    }
106
107    async function handleCancelClick(e, btn) {
108        const subscriptionId = btn.getAttribute("data-key");
109        const payload = buildPayload(subscriptionId);
110
111        // DEBUG MODE: log and allow normal behavior
112        if (DEBUG) {
113            console.log("ProsperStack DEBUG payload:", payload);
114            return true; // do not block default behavior
115        }
116
117        // Normal mode: intercept
118        e.preventDefault();
119        e.stopPropagation();
120        e.stopImmediatePropagation();
121
122        if (!subscriptionId) {
123            const restoredBtn = restoreOriginalBehavior(btn);
124            restoredBtn.click();
125            return false;
126        }
127
128        if (!payload) {
129            console.error("Could not construct valid ProsperStack payload");
130            const restoredBtn = restoreOriginalBehavior(btn);
131            restoredBtn.click();
132            return false;
133        }
134
135        try {
136            const flow = await loadProsperStack();
137            if (!flow) {
138                const restoredBtn = restoreOriginalBehavior(btn);
139                restoredBtn.click();
140                return false;
141            }
142
143            flow(payload, { displayMode: "modal" });
144            return true;
145        } catch (err) {
146            console.error("ProsperStack launch failed", err);
147            const restoredBtn = restoreOriginalBehavior(btn);
148            restoredBtn.click();
149            return false;
150        }
151    }
152
153    function wireButton(btn) {
154        if (!btn || btn.dataset.psBound === "true") return btn;
155
156        const cleanBtn = cloneAndReplaceButton(btn);
157
158        cleanBtn.addEventListener("click", function (e) {
159            if (cleanBtn.dataset.psRestoreBypass === "true") {
160                return;
161            }
162
163            handleCancelClick(e, cleanBtn);
164        });
165
166        return cleanBtn;
167    }
168
169    function wireAllButtons() {
170        document.querySelectorAll(BUTTON_SELECTOR).forEach(wireButton);
171    }
172
173    function startObserver() {
174        const observer = new MutationObserver(function () {
175            wireAllButtons();
176        });
177
178        observer.observe(document.body, {
179            childList: true,
180            subtree: true,
181        });
182    }
183
184    wireAllButtons();
185
186    if (document.body) {
187        startObserver();
188    } else {
189        document.addEventListener("DOMContentLoaded", startObserver, {
190            once: true,
191        });
192    }
193
194    document.addEventListener(
195        "click",
196        function (e) {
197            const btn = e.target.closest(BUTTON_SELECTOR);
198            if (!btn) return;
199            if (btn.dataset.psRestoreBypass === "true") return;
200            if (btn.dataset.psBound === "true") return;
201
202            handleCancelClick(e, btn);
203        },
204        true,
205    );
206})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.