PageSourceSearch

https://emailtracking.ru/logic.js

js emailtracking.ru collected 2026-10-08 17:52:36 UTC 21,468 bytes, 484 lines download raw bytes

1(async function () {
2    'use strict';
3
4    window.at = window.at || {};
5    window.at.version = '0.1.13';
6    window.at.startTime = new Date().getTime();
7
8    const months = {
9        one: 1, three: 3, six: 6, twelve: 12,
10    };
11    at.price = {
12        basic: {
13            bonus: {
14                one: 0, three: 5, six: 10, twelve: 25,
15            },
16            RUB: { cost: 2500, desc: '₽/мес.' },
17            UAH: { cost: 1250, desc: '₴/мес.' },
18            USD: { cost: 50, desc: '$/мес.' },
19        },
20        standart: {
21            bonus: {
22                one: 0, three: 6.5, six: 15, twelve: 30,
23            },
24            RUB: { cost: 5000, desc: '₽/мес.' },
25            UAH: { cost: 2500, desc: '₴/мес.' },
26            USD: { cost: 100, desc: '$/мес.' },
27        },
28    };
29
30    at.price2026 = {
31        basic: {
32            bonus: {
33                one: 0, three: 5, six: 10, twelve: 20,
34            },
35            RUB: { cost: 4000, desc: '₽/мес.' },
36            UAH: { cost: 2500, desc: '₴/мес.' },
37            USD: { cost: 90, desc: '$/мес.' },
38        },
39        standart: {
40            bonus: {
41                one: 0, three: 6, six: 12, twelve: 24,
42            },
43            RUB: { cost: 8000, desc: '₽/мес.' },
44            UAH: { cost: 4000, desc: '₴/мес.' },
45            USD: { cost: 180, desc: '$/мес.' },
46        },
47    };
48
49    const now = new Date();
50    const switchDate = new Date(2026, 2, 1); // 1 марта 2026 (месяц 2 = март)
51    if (now >= switchDate) at.price = at.price2026;
52
53
54
55
56    jQuery(document).ready(async function() {
57        $('.curr-year').text(new Date().getFullYear());
58        const url = new URL(window.location.href);
59        const category = url.searchParams.get("c");
60
61        $('.blog-all-right .button').click(categoriesFilter);
62        $(`.blog-all-right .button [data-category="${category}"]`).click();
63
64        pricing();
65        hrefParameterS();
66
67        $('#domain-email').on('keyup', emailValidator);
68        $("#email-generator").click(emailGenerator);
69
70        $('#top-domain-email').on('keyup', emailValidator);
71        $('#top-email-generator').click(aliasesGenerator);
72
73        $('#email-service-input').on('keyup', emailValidator);
74        $('#email-service-button').click(defineEmailService);
75
76        $('#email-count-button').click(calcTrakingEmails);
77
78        $('.contacts_form_wrap > form .send').click(async (...args) => await asyncWrapper(sendMsg, ...args));
79        //dima
80        const headerHeight = $('header').outerHeight() + 2;
81        if(window.location.hash) {
82            $('html, body').animate({
83                scrollTop: $(window.location.hash).offset().top - headerHeight
84            });
85        }
86        //dima end
87
88        await countUsers();
89
90        const answer = url.searchParams.get("answer"); // для раскрытия fak меню
91        const el = $(`#answer-${answer}`);
92        if (el.length) {
93            el.addClass('active').closest('.faq__block').addClass('active');
94            el[0].scrollIntoView({block: 'center'});
95        }
96
97        $('#instructions_index .instructions_nav_item:first').hide();
98        $('#instructions_index .instructions_nav_h1').hide();
99        $('#instructions_index .instructions_nav_item').addClass('active');
100        $('#instructions_index .instructions_nav_item_more').addClass('active');
101
102        const begin = new Date('2020-01-01').getTime() / 1000 / 3600 / 24;
103        const current = new Date().getTime() / 1000 / 3600 / 24;
104        $('.customers_trust').text(Math.ceil((current - begin) / 365 * 100 + 500));
105        $('.leads_tracked').text(Math.ceil((current - begin) / 365 * 140000 + 700000));
106        $('.years_of_experience').text(new Date().getFullYear() - 2015);
107    });
108
109    const ALIASES = await loadData('/download/alias-template.json') || console.log('disable downloading error of alias-template.json');
110    /////////////////////////////////////////////////
111
112
113    function priceCalc() {
114        const currencyProp = $('.price_currency_wrap :radio:checked')[0].dataset.currency;
115        const monthProp = $('.price_time_wrap :radio:checked')[0].dataset.month;
116        const monthValue = months[monthProp];
117
118        let tarif = 'basic';
119        let bonus = at.price[tarif].bonus[monthProp];
120        let pricePerMonth = at.price[tarif][currencyProp].cost - at.price[tarif][currencyProp].cost * (bonus / 100);
121        let pricePerMonthWithoutBonus = at.price[tarif][currencyProp].cost;
122        $(`.price_body [data-tarif=${tarif}] .price_h1 p > span`).html(bonus ? '-' + bonus + '%' : '');
123        if (bonus === 0) {
124            $(`.price_body [data-tarif=${tarif}] .price_price .old_price`).hide();
125        } else {
126            $(`.price_body [data-tarif=${tarif}] .price_price .old_price`).html(`${pricePerMonthWithoutBonus.toFixed(0)} ${at.price[tarif][currencyProp].desc}`).show();
127        }
128        $(`.price_body [data-tarif=${tarif}] .price_price .new_price`).html(`${pricePerMonth.toFixed(0)} ${at.price[tarif][currencyProp].desc}`);
129        $(`.price_body [data-base-leads]`).each(function (i, el) {
130            el.innerHTML = +(el.dataset.baseLeads) * monthValue; 
131        });          
132
133        tarif = 'standart';
134        bonus = at.price[tarif].bonus[monthProp];
135        pricePerMonth = at.price[tarif][currencyProp].cost - at.price[tarif][currencyProp].cost * (bonus / 100);
136        pricePerMonthWithoutBonus = at.price[tarif][currencyProp].cost;
137        $(`.price_body [data-tarif=${tarif}] .price_h1 p > span`).html(bonus ? '-' + bonus + '%' : '');
138        if (bonus === 0) {
139            $(`.price_body [data-tarif=${tarif}] .price_price .old_price`).hide();
140        } else {
141            $(`.price_body [data-tarif=${tarif}] .price_price .old_price`).html(`${pricePerMonthWithoutBonus.toFixed(0)} ${at.price[tarif][currencyProp].desc}`).show();
142        }
143        $(`.price_body [data-tarif=${tarif}] .price_price .new_price`).html(`${pricePerMonth.toFixed(0)} ${at.price[tarif][currencyProp].desc}`);
144
145        // var month = parseInt(this.value, 10);
146        // var basicBonus = parseFloat(this.dataset.currency);
147        // var standartBonus = parseFloat(this.dataset.standartBonus);
148        //
149        // var currencyDom = jQuery('input[name="selector1"]:checked');
150        // currencyDom = currencyDom.length ? currencyDom : jQuery('input[name="selector1"]:first')
151        // var basicCost = parseFloat(currencyDom.data("cost-price-basic"));
152        // var standartCost = parseFloat(currencyDom.data("cost-price-standart"));
153        // var cur = currencyDom.val();
154        // jQuery(".rpt_price.rpt_price_1").html('<span class="rpt_currency">' + cur + '</span>' + (month * basicCost - (month * basicCost * basicBonus / 100)).toFixed(0));
155        // jQuery(".rpt_price.rpt_price_2").html('<span class="rpt_currency">' + cur + '</span>' + (month * standartCost - (month * standartCost * standartBonus / 100)).toFixed(0));
156        // jQuery(".rpt_subtitle.rpt_subtitle_1").html(basicBonus ? '-' + basicBonus + '%' : '');
157        // jQuery(".rpt_subtitle.rpt_subtitle_2").html(standartBonus ? '-' + standartBonus + '%' : '');
158    }
159
160    function pricing() {
161        $('.price_currency_wrap :radio').change(priceCalc);
162        $('.price_time_wrap :radio').change(priceCalc);
163        $('[data-month="twelve"]').click();
164    }
165    function hrefParameterS() {
166        // переключаем слайд если есть параметр s в url
167        const href = new URL(window.location.href);
168        const slideIndex = href.searchParams.get('s');
169        $(`#instructions_button${slideIndex}`).click();
170    }
171    function emailGenerator() {
172        const domainEmail = $('#domain-email').val();
173        const length = +$('#select-drop').val();
174        if (!validateEmail(domainEmail)) {
175            $.fancybox.open(`<div class="message"><h2>Ошибка!</h2><p>Поле должно содержать емейл</p></div>`);
176            return false
177        }
178        const name = domainEmail.split('@')[0];
179        const domain = domainEmail.split('@')[1];
180        let data = [];
181        for (let i = 1; i <= length; i++) {
182            data.push(`${name + i.toFixed()}@${domain};`);
183        }
184        const filename = 'aliases.txt'; // Utils.uuidv4() + "-" + key + ".html";
185        singleLoad(data.join('\n'), filename);
186        return false;
187    }
188    function aliasesGenerator() {
189        const domainEmail = $('#top-domain-email').val();
190        const length = +$('#select-top-drop').val();
191        if (!validateEmail(domainEmail)) {
192            $.fancybox.open(`<div class="message"><h2>Ошибка!</h2><p>Поле должно содержать емейл</p></div>`);
193            return false
194        }
195        if (!(ALIASES && ALIASES.length)) {
196            console.log('Не загрузились  алиасы', ALIASES);
197            return false;
198        }
199        const domain = domainEmail.split('@')[1];
200        let data = [];
201        for (let i = 0; i < ALIASES.length; i++) {
202            data.push(`${ALIASES[i]}@${domain};`);
203            if (i >= length - 1) break;
204        }
205        const filename = 'aliases.txt'; // Utils.uuidv4() + "-" + key + ".html";
206        singleLoad(data.join('\n'), filename);
207        return false;
208    }
209
210    async function defineEmailService() {
211        const email = $('#email-service-input').val();
212        const length = +$('#select-top-drop').val();
213        const borderCss = $('#email-service-input').css('border');
214        if (!validateEmail(email)) {
215            $.fancybox.open('<div class="message"><h2>Ошибка!</h2><p>Поле должно содержать емейл</p></div>');
216            return false
217        }
218        $('#email-service-button').parent().addClass('active').blur(); // добавляем класс загрузки в кнопку
219
220        const url = `https://api.mxtoolbox.com/api/v1/Lookup/mx/?argument=${email.split('@')[1]}&Authorization=0feb5c74-4f09-4392-ba7c-221d33d53886`;
221        const response = await fetch(url);
222        if (response.ok) { // если HTTP-статус в диапазоне 200-299
223            const json = await response.json();
224            $('#email-service-button').parent().removeClass('active').blur();
225            const hostname = json.Information && json.Information.length && json.Information[0].Hostname || '';
226            let asn = json.Information && json.Information.length && json.Information[0].Asn || null;
227            asn = asn && JSON.parse(asn);
228            asn = asn && asn.length ? asn[0] : asn;
229            if (hostname || asn ) {
230                $.fancybox.open(`<div class="message"><h2>Ваша почта работает на:</h2><p>${asn.asname} ${hostname}</p></div>`);
231            } else {
232                $.fancybox.open(`<div class="message"><h2>Ваша почта работает на:</h2><p>Не удалось определить ваш почтовый сервис</p></div>`);
233            }
234        } else {
235            $.fancybox.open(`<div class="message"><h2>Ваша почта работает на:</h2><p>Не удалось определить ваш почтовый сервис</p></div>`);
236            console.log(`Ошибка HTTP: ${response.status} для url: ${url}`);
237            $('#email-service-button').parent().removeClass('active').blur();
238        }
239        return false;
240    }
241
242    function calcTrakingEmails() {
243        const countUsersVisitBySite = +$('#email-count-input').val();
244        const count = Math.ceil(countUsersVisitBySite / 4);
245        const c = Math.max(count, 20).toFixed(0);
246        $.fancybox.open(`<div class="message"><h2>Количество подменных ящиков должно быть не менее:</h2><p>${c}</p></div>`);
247    }
248
249    function getCookie(cname) {
250        var name = cname + '=';
251        var ca = document.cookie.split(';');
252        for(var i = 0; i < ca.length; i++) {
253            var c = ca[i];
254            while (c.charAt(0) === ' ') {
255                c = c.substring(1);
256            }
257            if (c.indexOf(name) === 0) {
258                return c.substring(name.length, c.length);
259            }
260        }
261        return '';
262    }
263
264    async function sendMsg(event) {
265        event.preventDefault();
266        const selector = '.contacts_form_wrap > form';
267        const name = $(`${selector} .name`).val();
268        const email = $(`${selector} .email`).val();
269        const message = $(`${selector} .msg`).val();
270        const customerEmail = getCookie('customerEmail');
271
272
273        // чекбокс политики
274        const policyChecked = document.getElementById('policyCheckbox').checked;
275        if (!policyChecked) {
276            $.fancybox.open('<div class="message"><h2>Ошибка!</h2><p>Вы должны согласиться с политикой конфиденциальности.</p></div>');
277            return false;
278        }
279
280
281        // honeypot (безопасно: если отсутствует — проигнорируем)
282        const honeypotEl = document.querySelector('.honeypot');
283        const honeypotValue = honeypotEl ? (honeypotEl.value || '') : '';
284
285        // Токен
286        const token = generateToken();
287
288        if (!validateEmail(email)) {
289            $.fancybox.open('<div class="message"><h2>Ошибка!</h2><p>Неверный формат поля емейл</p></div>');
290            return false
291        }
292        if (!message || !message.trim().length) {
293            $.fancybox.open('<div class="message"><h2>Ошибка!</h2><p>Поле с сообщением не должно быть пустым</p></div>');
294            return false
295        }
296        $(`${selector} .send`).parent().addClass('active').blur(); // добавляем класс загрузки в кнопку
297
298        const url = `https://alfa-track.com/user/open/support/form`;
299        // !!! включаем token и website
300        const data = { email, name, message, customerEmail, website: honeypotValue, token };
301
302        try {
303            const response = await fetch(url, {
304                method: 'POST',
305                headers: {
306                    'Content-Type': 'application/json;charset=utf-8'
307                },
308                body: JSON.stringify(data),
309            });
310
311            if (response.ok) {
312                const json = await response.json();
313                console.log('Fetch response: ', json);
314                $(`${selector} .send`).parent().removeClass('active').blur();
315                $.fancybox.open(`<div class="message"><h2>Ваше сообщение успешно отправлено. Мы с Вами свяжемся в ближайшее время</h2></div>`);
316                $(`${selector} .name`).val('');
317                $(`${selector} .email`).val('');
318                $(`${selector} .msg`).val('');
319                if (honeypotEl) honeypotEl.value = '';
320            } else {
321                $.fancybox.open(`<div class="message"><h2>
321Что-то пошло не так, попробуйте отправить позже...</h2></div>`);
322                $(`${selector} .send`).parent().removeClass('active').blur();
323                console.log(`Ошибка HTTP: ${response.status} для url: ${url}`);
324            }
325        } catch (err) {
326            console.error('Ошибка fetch:', err);
327            $.fancybox.open(`<div class="message"><h2>Ошибка сети. Попробуйте позже.</h2></div>`);
328            $(`${selector} .send`).parent().removeClass('active').blur();
329        }
330
331        return false;
332    }
333
334    async function asyncWrapper(func, ...args) {
335        try {
336            return await func.apply(this, args);
337        } catch (error) {
338            console.log('Fetch error: ', error);
339            return false;
340        }
341    }
342
343    async function countUsers() {
344        const selector = '#count-members';
345
346        const url = `https://alfa-track.com/user/open/telegram/user_count`;
347        const response = await fetch(url);
348        if (response.ok) {
349            const json = await response.json();
350            $(`${selector}`).html(`${json.object.toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, ' ')} участников`);
351        } else {
352            console.log(`Ошибка HTTP: ${response.status} для url: ${url}`);
353        }
354        return false;
355    }
356    /////////////////////////////////////////////////
357
358    var cancelSetter;
359    function emailValidator(event) {
360        const input = $(event.target);
361        const email = input.val(); //+ event.key;
362        let borderCss = input.data('def-border-css');
363        if (!borderCss) {
364            borderCss = input.css('border');
365            input.data('def-border-css', borderCss);
366        }
367        if (!validateEmail(email)) {
368            // $("#email-service-input").css("color", "red");
369            input.css('border', '2px solid red');
370            input.focus();
371            clearTimeout(cancelSetter);
372            return;
373        }
374        input.css('border', '2px solid green');
375        cancelSetter = setTimeout(function () {
376            input.css('border', borderCss);
377        }, 1500);
378    }
379
380    async function loadData(url) {
381        return new Promise(function (resolve, reject) {
382            $.ajax({
383                type: 'GET',
384                url,
385            }).done(function (data) {
386                console.log('================= loaded content by url', url);
387                resolve(data);
388            }).fail(function (error) {
389                console.log('================= [error] loaded content by url', url, error);
390                resolve();
391            });
392        });
393    }
394
395    function download(blob, filename) {
396        if (typeof window.navigator.msSaveBlob !== 'undefined') { // IE 10+
397            window.navigator.msSaveBlob(blob, filename);
398        } else {
399            var URL = window.URL || window.webkitURL;
400            var downloadUrl = URL.createObjectURL(blob);
401            if (filename) {
402                // use HTML5 a[download] attribute to specify filename
403                var downloadLink = window.document.createElement("a");
404                // safari doesn't support this yet
405                if (typeof downloadLink.download === 'undefined') {
406                    window.location = downloadUrl;
407                } else {
408                    downloadLink.href = downloadUrl;
409                    downloadLink.download = filename;
410                    window.document.body.appendChild(downloadLink);
411                    downloadLink.click();
412                }
413            } else {
414                window.location = downloadUrl;
415            }
416
417            setTimeout(function () {
418                URL.revokeObjectURL(downloadUrl);
419            }, 500); // cleanup
420        }
421    }
422    function singleLoad(text, filename) {
423        var blob = new Blob([text], { type: "text/plain;charset=utf-8;" });
424        download(blob, filename);
425    }
426
427    function validateEmail(email) {
428        const re = /(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})/i;
429        return re.test(String(email).toLowerCase());
430    }
431
432// --- 1. Генерация токена (время + секрет) ---
433    function generateToken() {
434        const ts = Math.floor(Date.now() / 1000 / 300); // интервал 5 минут
435        const secret = "Bx8!2adK"; // ДОЛЖЕН совпадать с SECRET на бэке
436        const raw = ts + ":" + secret;
437        return btoa(raw); // base64
438    }
439
440    function categoriesFilter(el) {
441        let category = $(el.target).data('category');
442        if (!category) return;
443        const active = $(el.target).is('.active');
444        $('.blog-all-right .button > a').removeClass('active');
445        if (active) {
446            category = '';
447        } else {
448            $(el.target).addClass('active');
449        }
450        updateHrefParameter('c', category);
451        $('.blog-all__item').each(function (i, article) { // all article
452            const selected = $(article).find(`.blog-all__tegs [data-category="${category}"]`);
453            if (selected.length || category === 'all' || category === '') {
454                $(this).show();
455            } else {
456                $(this).hide();
457            }
458        });
459        // $([document.documentElement, document.body]).animate({
460        //     scrollTop: $("#blog-all").offset().top,
461        // }, 1000);
462        if ($(el.target).prop('href').indexOf(location.pathname) === -1) return true;
463        return false;
464    }
465    function updateHrefParameter(paramName, paramValue) {
466        var url = window.location.href;
467        var hash = location.hash;
468        url = url.replace(hash, '');
469        if (url.indexOf(`${paramName}=`) >= 0) {
470            var prefix = url.substring(0, url.indexOf(`${paramName}=`));
471            var suffix = url.substring(url.indexOf(`${paramName}=`));
472            suffix = suffix.substring(suffix.indexOf('=') + 1);
473            suffix = suffix.indexOf('&') >= 0 ? suffix.substring(suffix.indexOf('&')) : '';
474            url = `${prefix + paramName}=${paramValue}${suffix}`;
475        } else {
476            if (url.indexOf('?') < 0) {
477                url += `?${paramName}=${paramValue}`;
478            } else {
479                url += `&${paramName}=${paramValue}`;
480            }
481        }
482        window.history.pushState({}, null, url + hash);
483    }
484})();

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.