PageSourceSearch

https://2-ua.com/assets/js/core/script.js?v=1.3.98

js 2-ua.com collected 2026-09-24 10:43:11 UTC 21,404 bytes, 597 lines download raw bytes

1function isMobile()
2{
3    if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i
4        .test(navigator.userAgent)) {
5
6        return true;
7    }
8
9    return false;
10}
11if (document.querySelector('.js-add-regx')) {
12    document.querySelector('.js-add-regx').addEventListener('click', function () {
13        console.log(
14            'add'
15        )
16        let block = document.querySelector('.js-regx_hidden');
17        block.classList.remove('hide');
18        block.classList.remove('js-regx_hidden');
19    }, false);
20}
21
22if (document.querySelector('.js-data_table') && need_compare) {
23    let table = document.querySelector('.js-data_table tbody');
24    let flag;
25
26    for (var i = 0; i < table.rows.length; i++) {
27        for (var j = 0; j < table.rows[0].cells.length; j++) {
28            let prew = i > 0 ? i - 1 : i;
29            if (
30                table.rows[i].cells[j].innerText !== table.rows[prew].cells[j].innerText
31            )
32                table.rows[i].cells[j].classList.add('js-diff')
33        }
34    }
35}
36if (document.querySelector('.js-site-url')) {
37    document.querySelector('.js-site-url').onkeyup = function (event) {
38        let val = this.value;
39        let count = val.split('/');
40        if(count.length > 3){
41            this.value = this.value.replace(/\/+$/, '')
42        }
43    }
44}
45
46function deleteTrailingSlash(str) {
47    return str.replace(/\/+$/, '');
48}
49
50function InsertViaAjax() {
51
52    let form = document.querySelector('.js-review__form');
53    insertSpinner('.js-review__result');
54    fetch(document.querySelector('.js-review__result').dataset.url, {
55        method: 'post',
56        headers: {
57            'Accept': 'application/json',
58            'Content-Type': 'application/x-www-form-urlencoded',
59            'X-CSRF-TOKEN': document.querySelector('.js-review__form input[name="_token"]').getAttribute('value')
60        },
61        //make sure to serialize your JSON body
62        body: new URLSearchParams(new FormData(form))
63    })
64        .then(response => {
65            if (!response.ok) {
66                return Promise.reject(response);
67            }
68            return response.json();
69        })
70        .then(data => {
71            console.log("Success");
72            console.log(data);
73            buildCheckResult('.js-review__result', data)
74        })
75        .catch(error => {
76            if (typeof error.json === "function") {
77                error.json().then(jsonError => {
78                    console.log("Json error from API");
79                    console.log(jsonError);
80                    buildAlert('.js-review__result', 'warning', jsonError.message)
81                }).catch(genericError => {
82                    console.log("Generic error from API");
83                    console.log(error.statusText);
84                });
85            } else {
86                console.log("Fetch error");
87                console.log(error);
88            }
89        });
90
91
92}
93
94if (document.querySelector('.js-review')) {
95    document.querySelector('.js-review').addEventListener('click', function (e) {
96        e.preventDefault();
97        InsertViaAjax();
98    });
99}
100
101function buildAlert(selector, type, text) {
102    document.querySelector(selector).innerHTML = '<div class="alert alert-' + type + ' alert-dismissible" role="alert">\n' +
103        '            ' + text + '\n' +
104        '            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">\n' +
105        '                <span aria-hidden="true">&times;</span>\n' +
106        '            </button>\n' +
107        '        </div>';
108
109}
110
111function insertSpinner(selector) {
112    document.querySelector(selector).innerHTML = '<div class="text-center justify-content-center"><div class="spinner-border text-primary" role="status">\n' +
113        '  <span class="sr-only">Loading...</span>\n' +
114        '</div></div>';
115}
116
117
118function buildCheckResult(selector, json) {
119    let data = '<div class="card">\n' +
120        '  <div class="table-responsive">' +
121        '<table class="table align-items-center mb-0 no-nowrap">' +
122        '<thead>\n' +
123        '        <tr>\n' +
124        '          <th class="text-uppercase text-secondary text-xxs font-weight-bolder">Field</th>\n' +
125        '          <th class="text-uppercase text-secondary text-xxs font-weight-bolder ps-2">Desktop</th>\n' +
126        '          <th class="text-uppercase text-secondary text-xxs font-weight-bolder ps-2">Mobile</th>\n' +
127        '        </tr>\n' +
128        '      </thead>' +
129        '<tbody>';
130    Object.entries(json).forEach((entry) => {
131        const [key, value] = entry;
132
133        data += '<tr><td><div class="d-flex px-2 py-1">' + key + '</div></td>' +
134            '<td class="align-middle text-sm text-break">' + (null === value[0] ? '' : value[0]) + '</td>' +
135            '<td class="align-middle text-sm text-break">' + (null === value[1] ? '' : value[1]) + '</td>' +
136            '</tr>';
137
138    });
139    data += '</tbody></table></div></div>';
140    document.querySelector(selector).innerHTML = data;
141}
142
143if (document.querySelector('.js-user-agent-switch')) {
144    document.querySelectorAll('.js-ua-trigger').forEach((item) => {
145        item.addEventListener('click', function (e) {
146            e.preventDefault();
147            let active = item.dataset.value;
148            document.querySelector('.js-' + active).checked = true;
149        });
150    });
151}
152
153if (document.querySelector('.js-user-agent-switch')) {
154    const checkbox = document.querySelector('.js-user-agent-switch')
155    checkbox.addEventListener('change', (event) => {
156        if (event.currentTarget.checked) {
157            document.querySelector('.js-check_with_desktop_headers').checked = false;
158            document.querySelector('.js-check_with_mobile_headers').checked = true;
159        } else {
160            document.querySelector('.js-check_with_desktop_headers').checked = true;
161            document.querySelector('.js-check_with_mobile_headers').checked = false;
162        }
163    })
164}
165
166if (document.querySelector('.js-execute_javascript')) {
167    const checkbox = document.querySelector('.js-execute_javascript')
168    checkbox.addEventListener('change', (event) => {
169        if (event.currentTarget.checked) {
170            document.querySelector('.js-devices').classList.remove('d-none');
171            document.querySelector('.js-devices').classList.add('show');
172        } else {
173            document.querySelector('.js-devices').classList.remove('show');
174            document.querySelector('.js-devices').classList.add('d-none');
175            document.querySelector('#is_mobile').checked = false;
176            document.querySelector('#is_desktop').checked = true;
177        }
178    });
179
180    const checkboxMobile = document.querySelector('#is_mobile')
181    checkboxMobile.addEventListener('change', (event) => {
182        if (event.currentTarget.checked) {
183            document.querySelector('#is_desktop').checked = false;
184        } else {
185            document.querySelector('#is_desktop').checked = true;
186        }
187    })
188
189    const checkboxDesktop = document.querySelector('#is_desktop')
190    checkboxDesktop.addEventListener('change', (event) => {
191        if (event.currentTarget.checked) {
192            document.querySelector('#is_mobile').checked = false;
193        } else {
194            document.querySelector('#is_mobile').checked = true;
195        }
196    })
197}
198
199function initSearch() {
200    let search_input = document.querySelector('.js-search__form');
201    search_input.addEventListener('keyup', function () {
202        let words = search_input.value;
203        if (words.length < 2)
204            return;
205
206        console.log(words);
207
208        fetch('/search', {
209            method: 'post',
210            headers: {
211                'Accept': 'application/json',
212                'Content-Type': 'application/json',
213                'X-Requested-With': 'XMLHttpRequest',
214                'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
215            },
216            //make sure to serialize your JSON body
217            body: JSON.stringify({
218                q: words
219            })
220        })
221            .then(response => {
222                if (!response.ok) {
223                    return Promise.reject(response);
224                }
225                return response.json();
226            })
227            .then(data => {
228                console.log('Success');
229                console.log(data);
230                buildSearchResults('.js-search__result', data)
231            })
232            .catch(error => {
233                if (typeof error.json === 'function') {
234                    error.json().then(jsonError => {
235                        console.log('Json error from API');
236                        console.log(jsonError);
237                    }).catch(genericError => {
238                        console.log('Generic error from API');
239                        console.log(error.statusText);
240                    });
241                } else {
242                    console.log('Fetch error');
243                    console.log(error);
244                }
245            });
246    });
247}
248
249function buildSearchResults(selector, json){
250    let data = '<ul class="dropdown-menu show">\n';
251
252    if (json.sites.length > 0){
253        data += '<li class="px-2">Projects:</li>';
254        Object.entries(json.sites).forEach((entry) => {
255            const [key, value] = entry;
256            data += '<li><a class="dropdown-item" href="/site/'+value.id+'/link">' + value.url + '</a></li>';
257
258        });
259    }
260    if (json.links_data.length > 0) {
261        data += '<li class="px-2">Links:</li>';
262        Object.entries(json.links_data).forEach((entry) => {
263            const [key, value] = entry;
264            let sim = value.check_with_mobile_headers ? '<i class="ni ni-mobile-button text-sm"></i> ' : '<i class="ni ni-laptop text-sm"></i> ';
265            data += '<li><a class="dropdown-item" href="/site/' + value.site_id + '/link/view/' + value.id + '">' +sim+ value.url + '</li>';
266
267        });
268        data += '</div>';
269    }
270    if (json.sites.length > 0 || json.links_data.length > 0) {
271        document.querySelector(selector).innerHTML = data;
272        document.addEventListener('click', function(event) {
273            var e=document.querySelector(selector);
274            if (!e.contains(event.target)) e.innerHTML = '';
275        });
276        console.log('asdasdasdas asd asd asd' + document.querySelector(selector).innerWidth);
277        document.querySelector(selector).style.right = document.querySelector(selector + ' ul').clientWidth + 'px';
278    } else{
279        document.querySelector(selector).innerHTML = '';
280    }
281}
282
283if (document.querySelector('.js-search__form')){
284    initSearch();
285}
286
287if (document.querySelector('.js-status_norma')) {
288    const select = document.querySelector('.js-status_norma')
289    select.addEventListener('change', (event) => {
290        let url =  document.querySelector('.js-301-redirect-to');
291        if (event.currentTarget.value === '301' || event.currentTarget.value === '302' || event.currentTarget.value === '307') {
292            url.classList.remove('d-none');
293            setTimeout( function (){
294                url.classList.add('show');
295            },300);
296        } else {
297            setTimeout( function (){
298                url.classList.remove('show');
299            },300);
300            url.classList.add('d-none');
301        }
302    })
303}
304
305if (document.querySelector('.js-plan-alert')) {
306    document.querySelectorAll('.js-plan-alert').forEach((item) => {
307        item.addEventListener('click', function (e) {
308            e.preventDefault();
309            showBuildingInfoModal(item.dataset.action)
310        });
311    });
312}
313
314
315function showBuildingInfoModal(action){
316    fetch('/payments/alert?action=' + action, {
317        method: 'get',
318        headers: {
319            'Accept': 'application/json',
320            'Content-Type': 'application/json',
321            'X-Requested-With': 'XMLHttpRequest',
322            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
323        }
324    })
325        .then(response => {
326            if (!response.ok) {
327                return Promise.reject(response);
328            }
329            return response.json();
330        })
331        .then(data => {
332            console.log('Success');
333            console.log(data);
334            buildPlanInfoImModal(data);
335            $('.js-modal').modal('show');
336        })
337        .catch(error => {
338            if (typeof error.json === 'function') {
339                error.json().then(jsonError => {
340                    console.log('Json error from API');
341                    console.log(jsonError);
342                }).catch(genericError => {
343                    console.log('Generic error from API');
344                    console.log(error.statusText);
345                });
346            } else {
347                console.log('Fetch error');
348                console.log(error);
349            }
350        });
351}
352
353function buildPlanInfoImModal(data)
354{
355    document.querySelector('.js-modal-title').innerHTML = data.title;
356    body_text = data.text;
357    document.querySelector('.js-modal-body').innerHTML = body_text;
358}
359
360if (document.querySelector('.js-show-artifact')) {
361    document.querySelectorAll('.js-show-artifact').forEach((item) => {
362        item.addEventListener('click', function (e) {
363            e.preventDefault();
364            showArtifactInModal(item.dataset.link_id, item.dataset.site_id)
365        });
366    });
367}
368
369function showArtifactInModal(link_id, site_id){
370
371    fetch('/site/'+site_id+'/link_data/'+link_id+'/artifact', {
372        method: 'get',
373        headers: {
374            'Accept': 'application/json',
375            'Content-Type': 'application/json',
376            'X-Requested-With': 'XMLHttpRequest',
377            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
378        }
379    })
380    .then(response => {
381        if (!response.ok) {
382            return Promise.reject(response);
383        }
384        return response.json();
385    })
386    .then(data => {
387        console.log('Success');
388        console.log(data);
389        buildArtifact(data);
390        $('.js-modal').modal('show');
391    })
392    .catch(error => {
393        if (typeof error.json === 'function') {
394            error.json().then(jsonError => {
395                console.log('Json error from API');
396                console.log(jsonError);
397            }).catch(genericError => {
398                console.log('Generic error from API');
399                console.log(error.statusText);
400            });
401        } else {
402            console.log('Fetch error');
403            console.log(error);
404        }
405    });
406}
407
408function buildArtifact(content){
409    document.querySelector('.js-modal-title').innerHTML = content.title;
410    let data = '<ul class="list-unstyled">';
411    data += '<li><h6>URL</h6></li>';
412    data += '<li>'+content.url+'</li>';
413    data += '<li><h6>Request headers</h6></li>';
414    Object.entries(content.data.request_headers).forEach((entry) => {
415        const [key, value] = entry;
416        data += '<li class="artifact-code">'+value+'</li>';
417    });
418    data += '<li><h6>Response headers</h6></li>';
419    Object.entries(content.data.headers).forEach((entry) => {
420        const [key, value] = entry;
421        data += '<li class="artifact-code">'+escape(key)+': '+escape(value)+'</li>';
422    });
423    data += '<li><h6>Body</h6></li>';
424
425    data += '<li class="artifact-code"><span class="text-space-pre small js-code terminal"><ol>';
426
427    let split = content.data.body.split('\n') //split up
428    split.forEach(function(item){
429        data += '<li>' + item + '</li>';
430    })
431
432    data += '</ol></span></li>';
433    data += '</ul>';
434    document.querySelector('.js-modal-body').innerHTML = data;
435
436}
437
438function escape(htmlStr) {
439    return htmlStr.replace(/&/g, "&amp;")
440        .replace(/</g, "&lt;")
441        .replace(/>/g, "&gt;")
442        .replace(/"/g, "&quot;")
443        .replace(/'/g, "&#39;");
444
445}
446
447if (document.querySelector('.js-payment-history')) {
448    document.querySelector('.js-payment-history').addEventListener('click', function (e) {
449        e.preventDefault();
450        $.ajaxSetup({
451            headers: {
452                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
453                'Accept': 'application/json',
454                'Content-Type': 'application/json',
455            }
456        });
457        $.ajax({
458            type: 'GET',
459            url: '/profile?history=1',
460            success: function(data) {
461                $('.js-payment_history').html(data)
462            }
463        });
464    });
465}
466
467
468if (document.querySelector('.js-download-report')){
469    document.querySelector('.js-download-report').addEventListener('click', function (e) {
470        e.preventDefault();
471        let input = document.createElement('input'),
472        form = document.querySelector('.js-report-form');
473        input.type = 'hidden';
474        input.value = '1';
475        input.name = 'export';
476        if (form && /\/site\/\d+\/crawling\/\d+\/report\/?$/.test(window.location.pathname)) {
477            form.action = window.location.pathname.replace(/\/$/, '') + '/export';
478        }
479        form.append(input);
480        form.submit();
481        input.remove();
482    });
483}
484if (document.querySelector('.js-mass-links-save')) {
485    document.querySelector('.js-mass-add__form').addEventListener('submit', function (e) {
486        if (e.submitter?.hasAttribute('formaction')) return;
487        e.preventDefault();
488        const button = this.querySelector('.js-mass-links-save');
489        if (button.disabled) return;
490        const result = $('.js-mass-links-save__result').empty();
491        button.disabled = true;
492        $.ajax({
493            type: 'POST',
494            url: '/site/' + document.querySelector('.js-site_id').value + '/link/bulk-create',
495            data: $('.js-mass-add__form').serialize(),
496            headers: {'Accept': 'application/json'},
497            success: function (data) {
498                $('<p class="alert-success p-3 text-white">').text(
499                    data.created + ' created, ' + data.restored + ' restored, ' +
500                    data.skipped + ' skipped. ' + data.remaining + ' slots remaining.'
501                ).appendTo(result);
502                $('.js-links__textarea').val('');
503            },
504            error: function (request) {
505                $('<p class="alert-warning p-3 text-white" role="alert">').text(
506                    request.responseJSON?.message || request.responseJSON?.error || 'Unable to save URLs. Please try again.'
507                ).appendTo(result);
508            },
509            complete: function () { button.disabled = false; }
510        });
511    });
512}
513let body = document.getElementsByTagName('body')[0];
514if(document.querySelector('.js-sidebar-toggle')){
515    document.querySelector('.js-sidebar-toggle').addEventListener('click', function (e) {
516        if (body.classList.contains('g-sidenav-pinned')) {
517            body.classList.remove('g-sidenav-pinned');
518        } else {
519            body.classList.add('g-sidenav-pinned');
520        }
521    });
522}
523if(document.querySelector('.js-desktop-sidebar-toggle')){
524    document.querySelector('.js-desktop-sidebar-toggle').addEventListener('click', function (e) {
525        if (body.classList.contains('no-left-menu')) {
526            body.classList.remove('no-left-menu');
527            document.cookie = "menu=;path=/;";
528        } else {
529            body.classList.add('no-left-menu');
530            document.cookie = "menu=no-left;path=/;";
531        }
532    });
533}
534
535function showModal(title, text, size = null){
536    if(size){
537        $('.js-modal-container').removeClass('modal-xl').addClass(size);
538    }
539    $('.js-modal-title').html(title);
540    $('.js-modal-body').html(text);
541    $('.js-modal').modal('show');
542}
543$(function($){
544
545    $('.form-anti-bot, .form-anti-bot-2').hide(); // hide inputs from users
546    var answer = $('.a-bt-form #anti-bot-a').val(); // get answer
547    $('.a-bt-form #anti-bot-q').val( answer ); // set answer into other input
548
549    if ( $('.a-bt-form').length == 0 ) {
550        var current_date = new Date();
551        var current_year = current_date.getFullYear();
552        $('.a-bt-form').append('<input type="hidden" name="anti-bot-q" id="anti-bot-q" value="'+current_year+'" />');
552 // add whole input with answer via javascript to form
553    }
554
555});
556$(function($){
557$('.js-page_speed_audits-heading').click( function(){
558    let button = $(this);
559    console.log('asdasdasdasd');
560    if(!button.hasClass('text-add')){
561        button.addClass('text-add');
562        $.ajaxSetup({
563            headers: {
564                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
565            }
566        });
567        $.ajax({
568            type: 'get',
569            url: '/pagespeed-audits',
570            data: $('.js-mass-add__form').serialize(), // serializes the form's elements.
571            success: function(data)
572            {
573                $('.js-page_speed_audits').html(data);
574            }
575        })
576    }
577});
578});
579
580function deleteTgChat(site_id, chat_id){
581    event.preventDefault();
582    $.ajaxSetup({
583        headers: {
584            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
585        }
586    });
587    $.ajax({
588        type: 'post',
589        url: '/site/'+site_id+'/deleteTg/'+chat_id,
590        data: {}, // serializes the form's elements.
591        success: function(data)
592        {
593            if(data.success === true)
594                $('.tg_chat_'+chat_id).remove();
595        }
596    })
597}

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.