PageSourceSearch

https://nezhno.space/wp-content/themes/my-theme/assets/js/survey.js?1790243586

js nezhno.space collected 2026-09-24 09:53:43 UTC 29,240 bytes, 499 lines download raw bytes

1
2
3// Создать опрос
4function generateSurvey(data, surveyContainer, id, nameSurvey) {
5    document.querySelector('.survey_opening-text').style.display = 'none';
6    let btnSurvey = document.querySelector('.button-survey');
7    btnSurvey.onclick = null;
8  
9    // Создаем форму
10    const formSection = `<form id="form-survey">
11    <div class='survey-form_header'>
12        <div class='survey-form_header__text'>
13            <button type="button" class="survey_prev-btn"></button>
14            <div class='survey-form_header__progress'>
15                <span class='progress_passed'>1</span>
16                <span>/</span>
17                <span class='progress_all'>32</span>
18            </div>
19        </div>
20        <div class="progress-bar">
21            <div data-size="10" class="progress"></div>
22        </div>
23    </div>
24  </form>`;
25  
26    surveyContainer.insertAdjacentHTML('beforeend', formSection);
27    const form = document.querySelector('#form-survey');
28  
29    //выставление начального прогресса прохождения опроса
30    let passedProgress = form.querySelector('.progress_passed');
31    let countQuestion = form.querySelector('.progress_all');
32    countQuestion.textContent = `${Object.keys(data).length + 1}`;
33    let progressBar = form.querySelector('.progress');
34  
35    function sizeProgress(num) {
36      passedProgress.textContent = num;
37      let size = 100 / (Object.keys(data).length + 1);
38      size *= num;
39      progressBar.style.width = 0;
40      progressBar.style.width = `${size}%`;
41    }
42    sizeProgress(1)
43  
44    //создаем кнопку назад
45    const prevBtn = document.querySelector('.survey_prev-btn');
46  
47    // Создаем вопросы
48    for (let keyData in data) {
49      // Создаем контейнер для вопроса
50      const questionContainer = document.createElement('div');
51      questionContainer.classList.add(`question-container`);
52      questionContainer.classList.add(`question-container_${data[keyData]['type']}`);
53      form.appendChild(questionContainer);
54  
55      // Добавляем заголовок вопроса
56      const questionTitle = document.createElement('h3');
57      questionTitle.innerText = `${decodeURI(data[keyData]['title'])}`;
58      questionTitle.className = 'question-title';
59      questionContainer.appendChild(questionTitle);
60  
61      if (data[keyData]['type'] === 'sex') {
62        questionTitle.innerText = `Ваш пол`;
63  
64        const container = document.createElement('div');
65        container.classList.add('container-sex');
66        questionContainer.appendChild(container);
67  
68        ['Женщина', 'Мужчина'].forEach((sex) => {
69          const answerContainer = document.createElement('div');
70          answerContainer.classList.add('answer-container');
71          container.appendChild(answerContainer);
72  
73          const label = document.createElement('label');
74          label.innerText = sex;
75          label.className = 'label-sex';
76          answerContainer.appendChild(label);
77  
78          const input = document.createElement('input');
79          input.type = 'radio';
80          input.name = 'sex';
81          input.value = sex;
82          label.appendChild(input);
83  
84          let checkmark = document.createElement('span');
85          checkmark.className = 'checkmark';
86          label.appendChild(checkmark);
87        })
88  
89      }
90  
91      if (data[keyData]['type'] === 'age') {
92        questionContainer.classList.add(`question-container_textarea`);
93  
94        questionTitle.innerText = `Сколько вам лет?`;
95  
96        const answerContainer = document.createElement('div');
97        answerContainer.classList.add('answer-container');
98        questionContainer.appendChild(answerContainer);
99  
100        const input = document.createElement('input');
101        input.type = 'text';
102        input.placeholder = 'ДД.ММ.ГГГГ';
103        input.min = "1900-01-01";
104        input.max = "2022-12-31";
105        input.addEventListener('focus', (e) => e.target.type = 'date');
106        input.addEventListener('blur', (e) => e.target.value == '' ? e.target.type = 'text' : e.target.type = 'date')
107  
108        answerContainer.appendChild(input);
109      }
110  
111      // Функция для создания информационного блока
112      function createInfoBlock(data, keyData) {
113        const infoContainer = document.createElement('div');
114        infoContainer.className = 'question-info';
115
116        // Определите информацию в зависимости от индекса
117        let info;
118        let question_number = data[keyData]['index'] + 1;
119        if (question_number === 12) {
120            info = [
121                "Мы все знаем, как делать НАДО.",
122                "Как правильно питаться, принимать себя такой/таким как есть, не залипать в ленте соцсетей, не прокрастинировать, сократить количество быстрых углеводов, планировать день, дышать и медитировать. И не нервничать.",
123                "Мы живем в реальном мире, в нем иногда не оправдываются ожидания, случаются свадьбы и разводы, падение курса валют, много неопределенности и стресса. Еда, шопинг, листание ленты новостей, сериалы, прокрастинация и очень-очень много работы — стратегии справляться со стрессом. Эти стратегии из разряда «никогда такого не было и вот опять». Примеры:",
124                "1. Девушка, 30 лет, каждое утро просыпается с мыслью \"мне нужно худеть, я вчера слишком много себе позволила\", утро начинается с составления списка того, что было съедено вечером в предыдущий день, строго подсчитываются калории. Весь день превращается в наказание за переедание с большими физическими нагрузками и жесткими ограничениями в еде. Вечером эмоциональное напряжение доходит до пика, и снова случается пищевой срыв. А дальше по кругу.",
125                "2. Мужчина, 39 лет, замечает, что весь день проходит достаточно стабильно и ровно, он может справляться с задачами и стрессом, прекрасно чувствует сигналы тела и свои эмоции. Но всегда после 17-18 часов у него поднимается уровень тревоги, которую ничем невозможно унять, без явной на то причины. Чтобы заглушить это он ест нон-стоп.",
126                "3. Девушка, 21 год, совмещает учебу и работу, активно проводит свободное время с другими людьми, есть большая потребность в отдыхе и тишине, но девушка не привыкла расслабляться. Если не друзья и активности, то фоном сериалы под сладости и \"надуманные\" домашние дела.",
127                "4. Мужчина, 45 лет, есть телесное ощущение черной дыры в груди и постоянно \"сосет под ложечкой\" от этой пустоты. Мужчина льет в нее кофе, книги, идеи, работу и все вокруг."
128            ];
129        } else if (question_number === 13) {
130            info = [
131                "Авторитарный стиль — все решения принимают родители, ребенок во всем должен подчиняться их воле. Родители ограничивают самостоятельность ребенка, не обосновывают свои требования, сопровождая их жестким Ð
131ºÐ¾Ð½Ñ‚ролем, суровыми запретами, наказаниями.",
132                "Демократический стиль — родители поощряют личную ответственность и самостоятельность детей в соответствии с их возрастными возможностями. Родители требуют от детей осмысленного поведения и стараются помочь им, чутко относясь к их запросам. При этом проявляют твердость, заботятся о справедливости и последовательном соблюдении дисциплины.",
133                "Попустительский стиль — ребенок должным образом не направляется, практически не знает запретов и ограничений со стороны родителей или не выполняет указаний родителей, для которых характерно неумение, неспособность или нежелание руководить детьми.",
134                "Хаотический стиль — это отсутствие единого подхода к воспитанию, когда нет ясно выраженных, определенных, конкретных требований к ребенку или наблюдаются противоречия, разногласия в выборе воспитательных средств между родителями.",
135                "Опекающий стиль — стремление постоянно быть с ребенком, решать за него все возникающие проблемы. Родители бдительно следят за поведением подростка, ограничивают его самостоятельное поведение, тревожатся, что с ним может что-то произойти."
136            ];
137        } else {
138            info = data[keyData]['info'];
139        }
140
141        const infoIcon = `<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
142            <path d="M18 22C17.4477 22 17 21.5523 17 21V15C17 14.4477 16.5523 14 16 14H14C13.4477 14 13 14.4477 13 15C13 15.5523 13.4477 16 14 16C14.5523 16 15 16.4477 15 17V21C15 21.5523 14.5523 22 14 22H13C12.4477 22 12 22.4477 12 23C12 23.5523 12.4477 24 13 24H19C19.5523 24 20 23.5523 20 23C20 22.4477 19.5523 22 19 22H18ZM16 8C15.7033 8 15.4133 8.08797 15.1666 8.2528C14.92 8.41762 14.7277 8.65189 14.6142 8.92597C14.5006 9.20006 14.4709 9.50166 14.5288 9.79264C14.5867 10.0836 14.7296 10.3509 14.9393 10.5607C15.1491 10.7704 15.4164 10.9133 15.7074 10.9712C15.9983 11.0291 16.2999 10.9994 16.574 10.8858C16.8481 10.7723 17.0824 10.58 17.2472 10.3334C17.412 10.0867 17.5 9.79667 17.5 9.5C17.5 9.10218 17.342 8.72064 17.0607 8.43934C16.7794 8.15804 16.3978 8 16 8Z" fill="#7264AA"/>
143            <path d="M16 30C13.2311 30 10.5243 29.1789 8.22202 27.6406C5.91973 26.1022 4.12532 23.9157 3.06569 21.3576C2.00607 18.7994 1.72882 15.9845 2.26901 13.2687C2.80921 10.553 4.14258 8.05845 6.10051 6.10051C8.05845 4.14258 10.553 2.80921 13.2687 2.26901C15.9845 1.72882 18.7994 2.00607 21.3576 3.06569C23.9157 4.12532 26.1022 5.91973 27.6406 8.22202C29.1789 10.5243 30 13.2311 30 16C30 19.713 28.525 23.274 25.8995 25.8995C23.274 28.525 19.713 30 16 30ZM16 4.00001C13.6266 4.00001 11.3066 4.70379 9.33316 6.02237C7.35977 7.34095 5.8217 9.21509 4.91345 11.4078C4.0052 13.6005 3.76756 16.0133 4.23058 18.3411C4.69361 20.6689 5.83649 22.8071 7.51472 24.4853C9.19296 26.1635 11.3312 27.3064 13.6589 27.7694C15.9867 28.2325 18.3995 27.9948 20.5922 27.0866C22.7849 26.1783 24.6591 24.6402 25.9776 22.6668C27.2962 20.6935 28 18.3734 28 16C28 12.8174 26.7357 9.76516 24.4853 7.51472C22.2348 5.26429 19.1826 4.00001 16 4.00001Z" fill="#7264AA"/>
144        </svg>`;
145        infoContainer.innerHTML = infoIcon;
146
147        infoContainer.addEventListener('click', () => displayInfo(info));
148        return infoContainer;
149      }
150
151      // Функция для отображения информации
152      function displayInfo(info) {
153        const modalText = document.querySelector('.survey_modal-text');
154        if (Array.isArray(info)) {
155            const paragraphs = info.map(item => `<p>${decodeURI(item)}</p>`);
156            modalText.innerHTML = paragraphs.join('');
157        } else {
158            modalText.innerHTML = decodeURI(info);
159        }
160        document.querySelector('.survey_modal-info').style.display = 'block';
161      }
162
163      // Использование функции для создания информационных блоков
164      if (data[keyData]['info']) {
165        const questionInfo = createInfoBlock(data, keyData);
166        questionTitle.appendChild(questionInfo);
167      }
168  
169      // Добавляем описание вопроса
170      if (data[keyData]['description']) {
171        const questionDescription = document.createElement('p');
172        questionDescription.innerText = `${decodeURI(data[keyData]['description'])}`;
173        questionDescription.className = 'question-description';
174        questionContainer.appendChild(questionDescription);
175      }
176  
177      function inputRange(length, array, questionContainer) {
178        const answerContainer = document.createElement('div');
179        answerContainer.classList.add('answer-container');
180        questionContainer.appendChild(answerContainer);
181  
182        answerContainer.insertAdjacentHTML('beforeend', `
183          <div class="slidecontainer">
184            <input type="range" min="1" max="" value="" class="slider-range">
185            <div class="slidecontainer_range-wrp">
186              <div class="slide-delimeter_wrp"></div>
187            </div>
188            <div class="slide-delimeter_wrp"></div>
189            <input class="slidecontainer-checked" value='' type='radio' checked>
190          </div>`);
191  
192        let slideContainer = answerContainer.querySelector('.slidecontainer');
193  
194        //расстановка штифтов
195        for (let i = 0; i < length; i++) {
196          slideContainer.querySelector('.slide-delimeter_wrp').innerHTML += `<span class='slide-delimeter'></span>`;
197        }
198        let styles = window.getComputedStyle(slideContainer.querySelector('.slide-delimeter_wrp'));
199        let widthSlide = parseFloat(styles.width);
200        let left = 0;
201        slideContainer.querySelector('.slide-delimeter_wrp').querySelectorAll('.slide-delimeter').forEach((elem, ind) => {
202          elem.style.left = left + 'px';
203          left += (widthSlide / (length - 1));
204          elem.innerHTML += `<span class='slide-delimeter_text'>${decodeURI(array[ind])}</span>`;
205          elem.querySelector('.slide-delimeter_text').style.left = '-' + parseFloat(window.getComputedStyle(elem.querySelector('.slide-delimeter_text')).width) / 2 + 'px';
206        });
207        let checkedValue = array[0];
208        let widthInput = window.getComputedStyle(slideContainer).width;
209        widthInput = parseFloat(widthInput);
210        answerContainer.querySelector('.slidecontainer input[type="range"]').style.width = widthInput + 22 + 'px';
211        let inputRange = answerContainer.querySelector('.slider-range');
212        inputRange.max = widthInput;
213        let paddingSize = ((widthInput - widthSlide) / 2);
214        let pieceLength = widthInput / length;
215        inputRange.value = paddingSize + ((widthSlide / (length - 1)) * 0);
216        slideContainer.querySelector('.slidecontainer-checked').value = decodeURI(checkedValue);
217        // console.log(slideContainer.querySelector('.slidecontainer-checked').value);
218        inputRange.addEventListener('change', function (e) {
219          let value = e.target.value;
220          for (let i = 0; i < length; i++) {
221            if ((value > pieceLength * i - (pieceLength / 2 - paddingSize)) && (value <= (pieceLength * (i + 1) - (pieceLength / 2 - paddingSize)))) {
222              e.target.value = paddingSize + ((widthSlide / (length - 1)) * i);
223              checkedValue = array[i];
224              break;
225            } else {
226              e.target.value = paddingSize + ((widthSlide / (length - 1)) * (length - 1));
227              checkedValue = array[i];
228            }
229  
230          }
231          slideContainer.querySelector('.slidecontainer-checked').value = decodeURI(checkedValue);
232          // console.log(slideContainer.querySelector('.slidecontainer-checked').value)
233        })
234      }
235  
236      // Тип ответа - RADIO-кнопки
237      if (data[keyData]['type'] === 'radio') {
238        inputRange(Object.keys(data[keyData]['answers']).length, data[keyData]['answers'], questionContainer);
239  
240        // window.addEventListener('resize', inputRange(Object.keys(data[keyData]['answers']).length, data[keyData]['answers'], questionContainer));
241      }
242      // Тип ответа - чекбокс-кнопки
243      if (data[keyData]['type'] === 'checkbox') {
244        const answersContainer = document.createElement('div');
245        answersContainer.classList.add('answers-container');
246        questionContainer.appendChild(answersContainer);
247  
248        for (let keyAnswer in data[keyData]['answers']) {
249          // Создаем контейнер для ответов
250          const answerContainer = document.createElement('div');
251          answerContainer.classList.add('answer-container');
252          answersContainer.appendChild(answerContainer);
253  
254          const label = document.createElement('label');
255          label.innerText = decodeURI(data[keyData]['answers'][keyAnswer]);
256          answerContainer.appendChild(label);
257  
258          const input = document.createElement('input');
259          input.type = 'checkbox';
260          // input.name = `question-${keyAnswer}-answer`;
261          input.value = decodeURI(data[keyData]['answers'][keyAnswer]);
262          label.appendChild(input);
263          let checkmark = document.createElement('span');
264          checkmark.className = 'checkmark';
265          label.appendChild(checkmark);
266        }
267      }
268  
269      // Тип ответа - текстовое поле
270      if (data[keyData]['type'] === 'textarea') {
271        for (let keyAnswer in data[keyData]['answers']) {
272          // Создаем контейнер для ответов
273          const answerContainer = document.createElement('div');
274          answerContainer.classList.add('answer-container');
275          questionContainer.appendChild(answerContainer);
276  
277          const label = document.createElement('label');
278          label.innerText = decodeURI(data[keyData]['answers'][keyAnswer]);
279          answerContainer.appendChild(label);
280          const input = document.createElement('input');
281          input.type = 'text';
282          input.placeholder = 'Развернутый ответ';
283          // input.name = `question-${keyAnswer}-answer`;
284          label.appendChild(input);
285        }
286      }
287    }
288  
289    //последний вопрос про стресс 
290    const questionContainer = document.createElement('div');
291    questionContainer.classList.add(`question-container`);
292    questionContainer.classList.add(`question-container_stress`);
293    form.appendChild(questionContainer);
294  
295    // Добавляем заголовок вопроса
296    const questionTitle = document.createElement('h3');
297    questionTitle.innerText = 'Укажите ваш уровень стресса';
298    questionTitle.className = 'question-title';
299    questionContainer.appendChild(questionTitle);
300  
301    questionContainer.innerHTML += `  <div class='question-container_stress-description'>
302    <p>1 — у меня нет стресса, я легко концентрируюсь, чувствую себя физически хорошо;</p>
303    <p>2 - в целом все идет хорошо, но иногда я легко раздражаюсь;</p>
304    <p>3 - я нервничаю и тревожусь чаще. Хуже концентрируюсь, но могу выполнять все личные и рабочие задачи;</p>
305    <p>4 - мне сложно выносить неопределенность и сюрпризы. Чувствую себя взвинченным, часто бываю уставшим и подавленным;</p>
306    <p>5 - мне кажется, что сложности и проблемы только наваливаются, и я уже не могу ничего с ними сделать. Не могу сконцентрироваться или расслабиться, плохо сплю.</p>
307    </div>`;
308  
309    function inputStressRange() {
310      inputRange(5, ['1', '2', '3', '4', '5'], questionContainer);
311    }
312    inputStressRange()
313  
314    let indexQuestion = 0;
315    let questions = document.querySelectorAll('.question-container');
316    //кнопка назад
317    prevBtn.addEventListener('click', function () {
318      if (indexQuestion > 0) {
319        questions[indexQuestion].style.display = 'none';
320        indexQuestion--;
321        questions[indexQuestion].style.display = 'block';
322        sizeProgress(indexQuestion + 1)
323  
324        // если нажата кнопка назад на последнем вопросе
325        if (btnSurvey.textContent !== 'Далее') {
326          btnSurvey.textContent = 'Далее';
327          btnSurvey.removeEventListener('click', resultsClick);
328          btnSurvey.addEventListener('click', prevAnswer);
329        }
330      }
331    })
332  
333    //кнопка далее
334    btnSurvey.textContent = 'Далее';
335    questions[0].style.display = 'block';
336    for (let i = 1; i < questions.length; i++) {
337      questions[i].style.display = 'none';
338  
339    }
340    function prevAnswer() {
341      questions[indexQuestion].style.display = 'none';
342      if (!((indexQuestion + 1) < questions.length - 1)) {
343        //кнопка завершения опроса
344        btnSurvey.removeEventListener('click', prevAnswer);
345        results(btnSurvey);
346      }
347      //записать ответ на вопрос в хранилище
348      if (questions[indexQuestion].classList.contains('question-container_textarea')) {
349        let answerValue = questions[indexQuestion].querySelector('input').value;
350        if (localStorage.getItem('survey')) {
351          let array = JSON.parse(localStorage.getItem('survey'))
352          array[indexQuestion] = answerValue
353          localStorage.setItem('survey', JSON.stringify(array))
354        } else {
355          localStorage.setItem('survey', JSON.stringify({indexQuestion: answerValue}))
356        }
357      } else {
358        let arrayAnswers = [];
359        questions[indexQuestion].querySelectorAll('input').forEach((answer) => {
360          if (answer.checked) {
361            arrayAnswers.push(answer.value);
362          }
363        })
364        let array = JSON.parse(localStorage.getItem('survey'))
365        if (array) {
366          array[indexQuestion] = arrayAnswers
367          localStorage.setItem('survey', JSON.stringify(array))
368        } else {
369          let arr = {
370            [indexQuestion]: arrayAnswers
371          }
372          localStorage.setItem('survey', JSON.stringify(arr))
373        }
374      }
375  
376      indexQuestion++;
377      questions[indexQuestion].style.display = 'block';
378      sizeProgress(indexQuestion + 1)
379    }
380    btnSurvey.addEventListener('click', prevAnswer);
381  
382    //заполнение опроса, если были сохраненные в хранилище ответы
383    if (localStorage.getItem('survey')) {
384      let local = JSON.parse(localStorage.getItem('survey'))
385      Object.keys(local).map((item) => {
386        if (questions[indexQuestion].classList.contains('question-container_textarea')) {
387          questions[indexQuestion].querySelector('input').value = local[item]
388        } else if (questions[indexQuestion].classList.contains('question-container_radio')) {
389          let valueLocal = local[item][0];
390          let value;
391  
392          let length = questions[indexQuestion].querySelectorAll('.slide-delimeter').length
393          let slideContainer = questions[indexQuestion].querySelector('.slidecontainer');
394          let styles = window.getComputedStyle(slideContainer.querySelector('.slide-delimeter_wrp'));
395          let widthSlide = parseFloat(styles.width);
396          let widthInput = window.getComputedStyle(slideContainer).width;
397          widthInput = parseFloat(widthInput);
398          let inputRange = questions[indexQuestion].querySelector('.slider-range');
399          inputRange.max = widthInput;
400          let paddingSize = ((widthInput - widthSlide) / 2);
401          let pieceLength = widthInput / length;
402  
403          questions[indexQuestion].querySelectorAll('.slide-delimeter_text').forEach((text, ind) => {
404            if (text.textContent === valueLocal) {
405              value = widthInput / questions[indexQuestion].querySelectorAll('.slide-delimeter_text').length * ind
406            }
407          })
408  
409          for (let i = 0; i < length; i++) {
410            if ((value > pieceLength * i - (pieceLength / 2 - paddingSize)) && (value <= (pieceLength * (i + 1) - (pieceLength / 2 - paddingSize)))) {
411              inputRange.value = paddingSize + ((widthSlide / (length - 1)) * i);
412              break;
413            } else {
414              inputRange.value = paddingSize + ((widthSlide / (length - 1)) * (length - 1));
415            }
416          }
417          slideContainer.querySelector('.slidecontainer-checked').value = valueLocal;
418        } else {
419          questions[indexQuestion].querySelectorAll('input').forEach((input) => {
420            local[item].forEach((it) => {
421              if (input.value === it) {
422                input.checked = true
423              }
424            })
425          })
426        }
427        questions[indexQuestion].style.display = 'none';
428        indexQuestion++
429        questions[indexQuestion].style.display = 'block';
430        sizeProgress(indexQuestion + 1)
431      })
432    }
433  
434    // получение результата
435    function results(btnSurvey) {
436      btnSurvey.innerText = 'Получить результаты';
437      btnSurvey.type = 'submit';
438      btnSurvey.addEventListener('click', resultsClick);
439    }
440  
441    function resultsClick(e) {
442      getSurveyResults(e, id, nameSurvey, data);
443    }
444  }
445  
446  // Получить данные с опроса
447  function getSurveyResults(e, id, nameSurvey, data) {
448    e.preventDefault();
449    // Получаем все ответы на опрос в виде массива
450    const questions = document.querySelectorAll('.question-container');
451    // Создаем объект для хранения результатов опроса
452    const ID = id;
453    const NAME = nameSurvey;
454    const results = {};
455  
456    // Итерируемся по массиву ответов
457    questions.forEach((question, ind) => {
458      let questionId = ind + 1;
459      if (question.classList.contains('question-container_textarea')) {
460        let answerValue = question.querySelector('input').value;
461  
462        results[questionId] = answerValue;
463      } else {
464        results[questionId] = [];
465        question.querySelectorAll('input').forEach((answer) => {
466          if (answer.checked) {
467            results[questionId].push(answer.value);
468          }
469        })
470      }
471    })
472  
473    // Отправляем данные на сервер
474    // console.log(results);
475    const DATA = {
476      id: ID,
477      survey_questions: data,
478      survey_name: NAME,
479      user_result: results
480    };
481    $.ajax({
482      url: "add_survey_check",
483      type: "POST",
484      dataType: "json",
485      data: { user_answers: DATA },
486      success: function (data) {
487        localStorage.removeItem('survey')
488        document.querySelector('.survey_modal-info').style.display = 'block';
489        document.querySelector('.survey_modal-info').querySelector('.survey_modal_btn-close').style.display = 'none';
490        document.querySelector('.survey_modal-info').querySelector('.survey_modal-text').innerHTML = `
491          <p style='text-align: center; margin-top: 10px; margin-bottom: 10px;'>Теперь рекомендации будут более персонализированными и эф
491фективными для вас.</p>
492          <a href="/subscription" class='blue_btn account_analytics_survey-link'>перейти к практикам</a>
493        `;
494      },
495      error: function (jqxhr, status, errorMsg) {
496        console.log(errorMsg)
497      },
498    });
499  }

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.