PageSourceSearch

https://aipsin.com/static/js/widgets/new_widgets.js

js aipsin.com collected 2026-10-02 21:45:47 UTC 170,038 bytes, 3,861 lines download raw bytes

1function changeIcon(href){
2    var link = document.querySelector("link[rel~='icon']");
3    if (!link) {
4        link = document.createElement('link');
5        link.rel = 'icon';
6        document.head.appendChild(link);
7    }
8    link.href = href;
9}
10function loadScript(src,onload=null){
11    if(hasScript(src)){
12        return findScript(src);
13    }
14    var js_script = document.createElement("script");
15    js_script.type = "text/javascript";
16    js_script.src = src;
17    js_script.onload = function() {
18        if(onload){
19            onload.call()
20        }
21    }
22    document.head.append(js_script)
23    return js_script;
24}
25function loadStyle(css_list){
26    if(typeof css_list == 'string'){
27      var cssLink = document.createElement("link");
28      cssLink.href = css_list;
29      cssLink.rel = "stylesheet";
30      cssLink.type = "text/css";
31      document.head.append(cssLink)
32    } else{
33      for (const css of css_list) {
34        var cssLink = document.createElement("link");
35        cssLink.href = css;
36        cssLink.rel = "stylesheet";
37        cssLink.type = "text/css";
38        document.head.append(cssLink)
39      }
40    }
41}
42function findScript(src){
43    return document.querySelector(`script[src="${src}"]`);
44}
45function hasScript(src){
46    return findScript(src)?true:false;
47}
48function findStyle(src){
49    return document.querySelector(`link[src="${src}"][rel="stylesheet"]`);
50}
51function hasStyle(src){
52    return findStyle(src)?true:false;
53}
54function removeScript(src){
55    if(hasScript(src)){
56        findScript(src).remove()
57        return true
58    } else{
59        return false
60    }
61}
62function removeStyle(src){
63    if(hasStyle(src)){
64        findStyle(src).remove()
65        return true
66    } else{
67        return false
68    }
69}
70function hasUrl(url) {
71    var http = new XMLHttpRequest();
72    http.open('HEAD', url, false);
73    http.send();
74    if (http.status != 404)
75        return true;
76    else
77        return false;
78}
79function inIframe() {
80    try {
81        return window.self !== window.top;
82    } catch (e) {
83        return true;
84    }
85}
86async function blobToBase64(blob) {
87    return new Promise((resolve, _) => {
88      const reader = new FileReader();
89      reader.onloadend = () => resolve(reader.result);
90      return reader.readAsDataURL(blob);
91    });
92}
93function formatDate(date){
94    var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
95    if(typeof date ==  'string'){
96        date = new Date(date)
97    }
98    return date.toLocaleDateString("ru-RU",options)
99}
100function formatDatetime(date){
101    var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
102    if(typeof date ==  'string'){
103        date = new Date(date)
104    }
105    return `${date.toLocaleDateString("ru-RU",options)} ${date.toLocaleTimeString('ru-RU')}`
106}
107function formatTime(date){
108    if(typeof date ==  'string'){
109        date = new Date(date)
110    }
111    return date.toLocaleTimeString('ru-RU')
112}
113function formatDatetimeNow(){
114    const date = new Date();
115    const options = { year: 'numeric', month: 'long', day: 'numeric' };
116    const time = date.toLocaleTimeString().replace(/:\d+ /, ' ');;
117    const res = `${date.toLocaleDateString('ru-RU', options)} ${time}`
118    return res;
119}
120var dynamicColors = function() {
121    var r = Math.floor(Math.random() * 255);
122    var g = Math.floor(Math.random() * 255);
123    var b = Math.floor(Math.random() * 255);
124    return {rgb:"rgb(" + r + "," + g + "," + b + ")",rgba:"rgba(" + r + "," + g + "," + b + ",0.2)"};
125};
126function getThemeProperty(property){
127    return getComputedStyle(document.querySelector(":root")).getPropertyValue(property)
128}
129function formatBytes(bytes, decimals = 2) {
130    if (bytes === 0) return '0 байт';
131    const k = 1024;
132    const dm = decimals < 0 ? 0 : decimals;
133    const sizes = ['байт', 'КБ', 'МБ', 'ГБ', 'ТБ', 'ПТ', 'ЕБ', 'ЗБ', 'ЮБ'];
134    const i = Math.floor(Math.log(bytes) / Math.log(k));
135    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
136}
137const truncateDecimal = (num, decimalPlaces) => {
138    const factor = Math.pow(10, decimalPlaces);
139    return Math.trunc(num * factor) / factor;
140};
141function localizedCountries(){
142    return {
143        "ac": "Остров Асенсьон","ad": "Андорра","ae": "ОАЭ","af": "Афганистан","ag": "Антигуа и Барбуда","ai": "Ангилья","al": "Албания","am": "Армения","ao": "Ангола","aq": "Антарктика","ar": "Аргентина","as": "Американское Самоа","at": "Австрия","au": "Австралия","aw": "Аруба","ax": "Аландские острова","az": "Азербайджан","ba": "Босния и Герцеговина","bb": "Барбадос","bd": "Бангладеш","be": "Бельгия","bf": "Буркина-Фасо","bg": "Болгария","bh": "Бахрейн","bi": "Бурунди","bj": "Бенин","bl": "Сен-Бартелеми","bm": "Бермуды","bn": "Бруней","bo": "Боливия","bq": "Бонайре, Синт-Эстатиус и Саба","br": "Бразилия","b
143s": "Багамские Острова","bt": "Бутан","bv": "Остров Буве","bw": "Ботсвана","by": "Беларусь","bz": "Белиз","ca": "Канада","cc": "Кокосовые острова","cd": "ДР Конго","cf": "ЦАР","cg": "Республика Конго","ch": "Швейцария","ci": "Кот-д’Ивуар","ck": "Острова Кука","cl": "Чили","cm": "Камерун","cn": "Китай (Китайская Народная Республика)","co": "Колумбия","cr": "Коста-Рика","cu": "Куба","cv": "Кабо-Верде","cw": "Кюрасао","cx": "Остров Рождества","cy": "Кипр","cz": "Чехия","de": "Германия","dj": "Джибути","dk": "Дания","dm": "Доминика","do": "Доминиканская Республика","dz": "Алжир","ec": "Эквадор","ee": "Эстония","eg": "Египет","eh": "САДР","er": "Эритрея","es": "Испания","et": "Эфиопия","fi": "Финляндия","fj": "Фиджи","fk": "Фолклендские острова","fm": "Микронезия","fo": "Фарерские острова","fr": "Франция","ga": "Габон","gb": "Великобритания","gd": "Гренада","ge": "Грузия","gf": "Гвиана","gg": "Гернси","gh": "Гана","gi": "Гибралтар","gl": "Гренландия","gm": "Гамбия","gn": "Гвинея","gp": "Гваделупа","gq": "Экваториальная Гвинея","gr": "Греция","gs": "Южная Георгия и Южные Сандвичевы Острова","gt": "Гватемала","gu": "Гуам","gw": "Гвинея-Бисау","gy": "Гайана","hk": "Гонконг","hm": "Херд и Макдональд","hn": "Гондурас","hr": "Хорватия","ht": "Гаити","hu": "Венгрия","id": "Индонезия","ie": "Ирландия","il": "Израиль","im": "Остров Мэн","in": "Индия","io": "Британская Территория в Индийском Океане","iq": "Ирак","ir": "Иран","is": "Исландия","it": "Италия","je": "Джерси","jm": "Ямайка","jo": "Иордания","jp": "Япония","ke": "Кения","kg": "Киргизия","kh": "Камбоджа","ki": "Кирибати","km": "Коморы","kn": "Сент-Китс и Невис","kp": "КНДР (Корейская Народно-Демократическая Республика)","kr": "Республика Корея","kw": "Кувейт","ky": "Острова Кайман","kz": "Казахстан","la": "Лаос","lb": "Ливан","lc": "Сент-Люсия","li": "Лихтенштейн","lk": "Шри-Ланка","lr": "Либерия","ls": "Лесото","lt": "Литва","lu": "Люксембург","lv": "Латвия","ly": "Ливия","ma": "Марокко","mc": "Монако","md": "Молдавия","me": "Черногория","mf": "Сен-Мартен","mg": "Мадагаскар","mh": "Маршалловы Острова","mk": "Северная Македония","ml": "Мали","mm": "Мьянма","mn": "Монголия","mo": "Макао","mp": "Северные Марианские Острова","mq": "Мартиника","mr": "Мавритания","ms": "Монтсеррат","mt": "Мальта","mu": "Маврикий","mv": "Мальдивы","mw": "Малави","mx": "Мексика","my": "Малайзия","mz": "Мозамбик","na": "Намибия","nc": "Новая Каледония","ne": "Нигер","nf": "Остров Норфолк","ng": "Нигерия","ni": "Никарагуа","nl": "Нидерланды","no": "Норвегия","np": "Непал","nr": "Науру","nu": "Ниуэ","nz": "Новая Зеландия","om": "Оман","pa": "Панама","pe": "Перу","pf": "Французская Полинезия","pg": "Папуа — Новая Гвинея","ph": "Филиппины","pk": "Пакистан","pl": "Польша","pm": "Сен-Пьер и Микелон","pn": "Острова Питкэрн","pr": "Пуэрто-Рико","ps": "Государство Палестина","pt": "Португалия","pw": "Палау","py": "Парагвай","qa": "Катар","re": "Реюньон","ro": "Румыния","rs": "Сербия","ru": "Россия","rw": "Руанда","sa": "Саудовская Аравия","sb": "Соломоновы Острова","sc": "Сейшельские Острова","sd": "Судан","se": "Швеция","sg": "Сингапур","sh": "Остров Святой Елены","si": "Словения","sj": "Шпицберген и Ян-Майен","sk": "Словакия","sl": "Сьерра-Леоне","
143sm": "Сан-Марино","sn": "Сенегал","so": "Сомали","sr": "Суринам","ss": "Южный Судан","st": "Сан-Томе и Принсипи","sv": "Сальвадор","sx": "Синт-Мартен","sy": "Сирия","sz": "Эсватини","tc": "Теркс и Кайкос","td": "Чад","tf": "Французские Южные и Антарктические территории","tg": "Того","th": "Таиланд","tj": "Таджикистан","tk": "Токелау","tl": "Восточный Тимор","tm": "Туркменистан","tn": "Тунис","to": "Тонга","tr": "Турция","tt": "Тринидад и Тобаго","tv": "Тувалу","tw": "Китайская Республика","tz": "Танзания","ua": "Украина","ug": "Уганда","um": "Внешние малые острова США","us": "США","uy": "Уругвай","uz": "Узбекистан","va": "Ватикан","vc": "Сент-Винсент и Гренадины","ve": "Венесуэла","vg": "Виргинские Острова (Великобритания)","vi": "Виргинские Острова (США)","vn": "Вьетнам","vu": "Вануату","wf": "Уоллис и Футуна","ws": "Самоа","xk": "Косово","ye": "Йемен","yt": "Майотта","za": "ЮАР","zm": "Замбия","zw": "Зимбабве"
144    }
145}
146const id_generator = (size=6,characters=null) => {
147    let result = '';
148    characters = characters==null?'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789':characters;
149    const charactersLength = characters.length;
150    let counter = 0;
151    while (counter < size) {
152      result += characters.charAt(Math.floor(Math.random() * charactersLength));
153      counter += 1;
154    }
155    return result;
156}
157function randomId() {
158    const uint32 = window.crypto.getRandomValues(new Uint32Array(1))[0];
159    return uint32.toString(16);
160}
161function scrollTop(){
162    $(document.querySelector('.wrapper')).scrollTop(0)
163}
164async function getCaptchaTextImage(selector,text=null){
165    if(typeof selector == 'string'){
166        selector = document.querySelector(selector)
167    } else{
168        selector = selector
169    }
170    if(selector.tagName == 'IMG'){
171        PostFile('/captcha_image/',text?{
172            'text':text
173        }:{}).then(async (blob)=>{
174            selector.src = await blobToBase64(await blob)
175        })
176    } else{
177        PostFile('/captcha_image/',text?{
178            'text':text
179        }:{}).then(async (blob)=>{
180            selector.innerHTML = `
181            <img src="${await blobToBase64(await blob)}">
182            `
183        })
184    }
185}
186function isDict(d) {
187    return !!d && typeof d==='object' && d!==null && !(d instanceof Array) && !(d instanceof Date) && isJsonable(d);
188}
189function isJsonable(d) {
190    try{
191        return JSON.stringify(d) === JSON.stringify(JSON.parse(JSON.stringify(d)));
192     } catch(e){
193        return false;
194    }
195}
196function isNumeric(str) {
197    return !isNaN(str) && !isNaN(parseFloat(str))
198}
199function CopyClipboard(copy_obj,type='text',toast_show=false){
200    if(type=='text'||type=='coord'||type.startsWith('url')){
201        var text_copy = document.createElement('textarea')
202        text_copy.value = copy_obj
203        text_copy.style.height = 0;
204        text_copy.style.position = 'absolute';
205        text_copy.style.opacity = 0;
206        text_copy.setAttribute('readonly', '');
207        document.body.appendChild(text_copy)
208        text_copy.select();
209        try {
210            document.execCommand('copy');
211            text_copy.remove()
212            if(toast_show){
213                var msg = `Текст скопирован`;
214                if(type=='coord'){msg = `Координаты скопированы`;}
215                else if(type=='url'){msg = `Ссылка скопированна`;}
216                else if(type=='url_literature'){msg = `Ссылка на литературу скопированна`;}
217                TOAST.AddToast(
218                    {
219                        text:msg,
220                        type:`info`,
221                    }
222                )
223                TOAST.ShowToasts()
224            }
225        } catch (error) {
226            console.log(error)
227            text_copy.remove()
228        }
229    } else if(type=='img'){
230
231    }
232    return copy_obj;
233}
234function ChangeTypeLang(str){
235	var keybards = {
236		lat:`qwertyuiop[]asdfghjkl;'zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>?!@#$%^&*()_+`,
237		cir:`йцукенгшщзхъфывапролджэячсмитьбю.ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,!"№;%:?*()_+`
238	}
239	var has_lat = true,has_cir = true,result = ''
240	for (var i in str) {
241		keybards.lat.indexOf(str[i])>=0?null:has_lat=false
242		keybards.cir.indexOf(str[i])>=0?null:has_cir=false
243	}
244	if(has_lat){
245		for (let i = 0; i < str.length; i++) {
246			if(keybards.lat.indexOf(str[i])>=0){
247				result+=keybards.cir[keybards.lat.indexOf(str[i])]
248			}
249		}
250	} else if(has_cir){
251		for (let i = 0; i < str.length; i++) {
252			if(keybards.cir.indexOf(str[i])>=0){
253				result+=keybards.lat[keybards.cir.indexOf(str[i])]
254			}
255		}
256	}else{result=str}
257	return result
258}
259function onlyNumberKey(evt) {
260    var ASCIICode = (evt.which) ? evt.which : evt.keyCode
261    if (ASCIICode > 31 && (ASCIICode < 48 || ASCIICode > 57))
262        return false;
263    return true;
264}
265const validateEmail = (email) => {
266    return String(email)
267      .toLowerCase()
268      .match(
269        /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
270      );
271};
272const validatePhone = (phone) => {
273    var re = /^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im;
274    return re.test(phone);
275}
276const validateUrl = (url) => {
277    var re = new RegExp('^(https?:\\/\\/)?'+ // validate protocol
278	    '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // validate domain name
279	    '((\\d{1,3}\\.){3}\\d{1,3}))'+ // validate OR ip (v4) address
280	    '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // validate port and path
281	    '(\\?[;&a-z\\d%_.~+=-]*)?'+ // validate query string
282	    '(\\#[-a-z\\d_]*)?$','i'); // validate fragment locator
283	  return re.test(url);
284}
285const GetLabel = (el) => {
286    return el.hasAttribute('label')?`: ${el.getAttribute('label')}`:''
287}
288function MiniLoaderEvent(type="load-iframe"){
289    var loader = document.querySelector('[mini_loader]');
290    if(!loader){
291        loader = document.createElement('div');
292        document.body.append(loader)
293    }
294    loader.setAttribute('mini_loader',type);
295    loader.classList.toggle('show');
296}
297function AddToltip(el,label,position="top",type="default"){
298    el.setAttribute('aria-label',label);
299    el.setAttribute('data-microtip-position',position);
300    el.setAttribute('role','tooltip');
301    if(type){
302        el.setAttribute('type',type);
303    }
304}
305function DelToltip(el){
306    el.removeAttribute('aria-label');
307    el.removeAttribute('data-microtip-position');
308    el.removeAttribute('role');
309    el.removeAttribute('type');
310}
311function DisabledEvent(el,disabled){
312    el.disabled = disabled
313}
314function ValidateInput(el,label=null,type="error",position="top"){
315    if(label){
316        AddToltip(el,label,position,type)
317        el.classList.add('no_valid')
318        el.classList.remove('valid')
319        el.classList.remove('default')
320    } else if(label==null && type=='default'){
321        el.classList.add('default')
322        el.classList.remove('valid')
323        el.classList.remove('no_valid')
324        DelToltip(el)
325    } else{
326        AddToltip(el,'Отлично',position,'success')
327        el.classList.add('valid')
328        el.classList.remove('no_valid')
329        el.classList.remove('default')
330    }
331}
332function GenerateInputFormatDatetimePicker(element=null){
333    try {
334        $.datetimepicker.setLocale('ru');
335        if(element){
336            element = $(element)
337            if(element.hasClass('input_aipsin_date')){
338                element.find('input').datetimepicker({
339                    format:'d-m-Y',
340                    timepicker: false,
341                    scrollInput : false,
342                    dayOfWeekStart: 1,
343                    onChangeDateTime:function(dp,$input){
344                        //$input.trigger("input")
345                    }
346                })
347            } else if(element.hasClass('input_aipsin_datetime')){
348                element.find('input').datetimepicker({
349                    format:'d-m-Y H:i',
350                    timepicker: true,
351                    scrollInput : false,
352                    dayOfWeekStart: 1,
353                    onChangeDateTime:function(dp,$input){
354                        //$input.trigger("input")
355                    }
356                }) 
357            }            
358        } else{
359            $('.input_aipsin_date>input').datetimepicker({
360                format:'d-m-Y',
361                timepicker: false,
362                scrollInput : false,
363                dayOfWeekStart: 1,
364                onChangeDateTime:function(dp,$input){
365                    //$input.trigger("input")
366                }
367            })
368            $('.input_aipsin_datetime>input').datetimepicker({
369                format:'d-m-Y H:i',
370                timepicker: true,
371                scrollInput : false,
372                dayOfWeekStart: 1,
373                onChangeDateTime:function(dp,$input){
374                    //$input.trigger("input")
375                }
376            }) 
377        }
378    } catch (err) {}
379}
380function GenerateInputFormatTelephone(element=null){
381    try{
382        function FormatPhoneInput(input){
383            var placeholders = {
384                by:'+375331234567',
385                ru:'+79121234567',
386                ua:'+3800501234567'
387            }
388            var iti = window.intlTelInput(input, {
389                utilsScript: "/static/intl-tel-input/utils.js",
390                preferredCountries: ["by","ru","ua"],
391                localizedCountries:localizedCountries(),
392                //separateDialCode:true,
393                formatOnDisplay: false,
394                hiddenInput: "full_phone",
395                customPlaceholder: function(selectedCountryPlaceholder, selectedCountryData) {
396                    if(placeholders[selectedCountryData.iso2]){
397                        return placeholders[selectedCountryData.iso2];
398                    } else{
399                        return selectedCountryPlaceholder;
400                    }
401                }
402            });
403            input.addEventListener("countrychange",function(event) {
404                var el = event.target.closest('.input_aipsin.validator');
405                if(el){
406                    if(iti.isValidNumber()){
407                        ValidateInput(el)
408                    } else{
409                        event.target.required?ValidateInput(el,`Заполните поле${GetLabel(el)}`):ValidateInput(el,null,'default')
410                    }
411                }
412            });
413            input.addEventListener("input",function(event){
414                if(event.target.value!=''){
415                    if(event.target.value[0]=='+'){
416                        var reg_val = event.target.value.replace(/[^\d]/g,'')
417                        event.target.value = '+'+reg_val
418                    } else{
419                        var reg_val = event.target.value.replace(/[^\d]/g,'')
420                        event.target.value = reg_val
421                    }
422                }
423                var el = event.target.closest('.input_aipsin.validator');
424                if(el){
425                    if(iti.isValidNumber()){
426                        ValidateInput(el)
427                    } else{
428                        event.target.required?ValidateInput(el,`Заполните поле${GetLabel(el)}`):ValidateInput(el,null,'default')
429                    }
430                }
431            })
432            input.closest('form').addEventListener('submit',(event)=>{
433                event.preventDefault();
434                if(input.value!=''){
435                    if(input.value[0]!='+'){
436                        input.value = '+'+iti.s.dialCode+input.value
437                    }
438                }
439            })
440        }
441        if(element){
442            if($(element).hasClass('input_aipsin_phone')&&$(element).hasClass('country_mask')){
443                FormatPhoneInput(element)
444            }
445        } else{
446            var input_country_masks = $('.input_aipsin_phone.country_mask>input');
447            for (let i = 0; i < input_country_masks.length; i++) {
448                const input = input_country_masks[i];
449                FormatPhoneInput(input)
450            }
451
452        }
453    } catch(err) {}
454}
455function GenerateInputFormatText(element=null){
456    try{
457        var property_inputmask = {
458            showMaskOnFocus: true,
459            showMaskOnHover: false,
460            autoUnmask: true,
461            clearMaskOnLostFocus: true
462        }
463        if(element){
464            element = $(element)
465            if(element.hasClass('input_aipsin_phone')){
466                element.find('input').inputmask(property_inputmask);
467            } else if(element.hasClass('input_aipsin_date')){
468                element.find('input').inputmask(property_inputmask);
469            } else if(element.hasClass('input_aipsin_datetime')){
470                element.find('input').inputmask(property_inputmask);
471            } else if(element.hasClass('input_aipsin_coordinates')){
472                element.find('input').inputmask(property_inputmask);
473            }
474        } else{
475            $(".input_aipsin_phone>input").inputmask(property_inputmask);
476            $(".input_aipsin_date>input").inputmask(property_inputmask);
477            $(".input_aipsin_datetime>input").inputmask(property_inputmask);
478            $(".input_aipsin_coordinates>input").inputmask(property_inputmask);
479        }
480    } catch(err){}
481}
482function GenerateInputFormatValidator(element=null){
483    try {
484        if(element){
485            element = $(element)
486            if(element.hasClass('input_aipsin')&&element.hasClass('validator')){
487                var event = new Event('input', {
488                    'bubbles': true
489                });
490                element.querySelector('input').dispatchEvent(event);
491            }
492        } else{
493            $('.input_aipsin.validator').each((i,el)=>{
494                var event = new Event('input', {
495                    'bubbles': true
496                });
497                el.querySelector('input').dispatchEvent(event);
498            })
499        }
500    } catch (error) {}
501}
502function GenerateInputFormatTextarea(element=null){
503    try {
504        if(element){
505            element = $(element)
506            if(element.hasClass('textarea_aipsin')){
507                var event = new Event('input', {
508                    'bubbles': true
509                });
510                element.querySelector('textarea').dispatchEvent(event);
511            }
512        } else{
513            $('.textarea_aipsin').each((i,el)=>{
514                var event = new Event('input', {
515                    'bubbles': true
516                });
517                el.querySelector('textarea').dispatchEvent(event);
518            })
519        }
520    } catch (error) {}
521}
522function GenerateSelectInputFormat(element=null){
523    if(element){
524        element = $(element)
525        if(element.hasClass('select_aipsin')){
526            SetAipsinSelectChoises(element)
527        }
528    } else{
529        $('.select_aipsin').each((i,el)=>{
530            SetAipsinSelectChoises(el);
531        })
532    }
533}
534function GenerateFilepondInputFormat(element=null){
535    if(element){
536        if(element.hasAttribute('filepond')){
537            filepondCreate(element);
538        }
539    }
540}
541function GenerateTreeTable(){
542    try {
543        if(!hasScript('/static/jquery-simple-tree-table/jquery-simple-tree-table.min.js')){
544            loadScript('/static/jquery-simple-tree-table/jquery-simple-tree-table.min.js', 
544()=>{
545                $('[tree-table]').simpleTreeTable({
546                    collapsed: true,
547                    opened:[]
548                }).on('node:open', function(e, $node) {
549                    window.dispatchEvent(new Event('resize'));
550                })
551            })
552        } else{
553            setTimeout(() => {
554                $('[tree-table]').simpleTreeTable({
555                    collapsed: true,
556                    opened:[]
557                }).on('node:open', function(e, $node) {
558                    window.dispatchEvent(new Event('resize'));
559                })
560            }, 1000);
561        }
562    } catch (error) {}
563}
564function GenerateButtonsClick(){
565    document.querySelectorAll('button.button_main:not(.no_btn), input.button_main:not(.no_btn)').forEach(el => {
566        var style = window.getComputedStyle(el)
567        if(!style.getPropertyValue('position')){
568            el.style.position = 'relative';
569        }
570        el.style.overflow = 'hidden';
571        /*var span = document.createElement('span')
572        span.classList = 'hover'
573        span.innerText = el.innerText
574        el.innerText = ''
575        el.append(span)*/
576        el.addEventListener('click', function (e) {
577           var x = e.offsetX;
578           var y = e.offsetY;
579           var ripples = document.getElementsByClassName('ripple');
580           if (ripples.length < 10) {
581              var ripple = document.createElement('span');
582              ripple.classList.add('ripple');
583              ripple.style.left = x + 'px';
584              ripple.style.top = y + 'px';
585              this.appendChild(ripple);
586              setTimeout(function () {
587                 ripple.remove();
588              }, 1000);
589           }
590        });
591        /*
592        el.onmousemove = function (e) {
593            var x = e.pageX - e.target.offsetLeft;
594            var y = e.pageY - e.target.offsetTop;
595            
596            e.target.style.setProperty('--x', x + 'px');
597            e.target.style.setProperty('--y', y + 'px');
598        };
599        */
600     })
601}
602function GenerateInputFormats(element=null){
603    GenerateInputFormatDatetimePicker(element)
604    GenerateInputFormatTelephone(element)
605    GenerateInputFormatText(element)
606    GenerateInputFormatValidator(element)
607    GenerateInputFormatTextarea(element)
608    GenerateSelectInputFormat(element)
609    GenerateFilepondInputFormat(element)
610}
611function GenerateInputReplace(element, html){
612    element.innerHTML = html
613    GenerateInputFormats(element ? element.firstElementChild : null)
614}
615function GenerateInputApiReplace(url, element){
616    if(!element.hasAttribute('input-api')||element.getAttribute('input-api')!=url){
617        element.setAttribute('input-api', url)
618        fetch(url).then((res)=>res.text()).then((text)=>GenerateInputReplace(element,text))
619    }
620}
621$( document ).ready(()=>{
622    GenerateInputFormats()
623    GenerateTreeTable()
624    GenerateButtonsClick()
625     document.querySelectorAll('.toggle_btns_menu .toggle_menu_item').forEach(el=>{
626        var input = el.querySelector('input');
627        if(input){
628            input.addEventListener('change',(event)=>{
629                ClickLoadFile(event);
630            })
631        } else{
632            el.addEventListener('click',(event)=>{
633                event.target.closest('.toggle_btns_menu').querySelector('.toggle_btns_menu_checkbox').checked = false
634                if(event.target.hasAttribute('name')){
635                    var name_cmd = event.target.getAttribute('name')
636                    if(name_cmd.indexOf('export')!=0){
637                        logo_event('export')
638                    } else if(name_cmd.indexOf('import')!=0){
639                        logo_event('import')
640                    }
641                }
642            })
643        }
644     })
645     document.querySelectorAll('input[type="hidden"][hidden_field]').forEach(el=>{
646        var aipsin_field = el.closest('.aipsin_field')
647        var grid_item = el.closest('.form_aipsin_content_item')
648        aipsin_field?aipsin_field.style.display = 'none':null
649        grid_item?grid_item.style.display = 'none':null
650     })
651     $(document).on('click','[dropdown-click]',(e)=>{
652        var dropdown_el = e.target//.closest('[dropdown-click]')
653        if(dropdown_el.hasAttribute('dropdown-click')){
654            if(dropdown_el.classList.contains('open')){
655                document.querySelectorAll('[dropdown-click]').forEach(el=>el.classList.remove('open'))
656            } else{
657                document.querySelectorAll('[dropdown-click]').forEach(el=>el.classList.remove('open'))
658                dropdown_el.classList.add('open')
659            }
660        }
661     })
662     $('.todolist_aipsin .todolist_table .todo_events button').on('click',(e)=>{
663        var inputs = e.target.closest('.todolist_aipsin').querySelectorAll('.todolist_table input[type=checkbox]')
664        inputs.forEach(inp => {
665            inp.checked = false;
666        });
667        var input = e.target.closest('.todo_events').querySelector('input[type=checkbox]');
668        if(!input){
669            return false
670        }
671        input.checked = true;
672    })
673    $('.todolist_aipsin .todolist_footer button').on('click',(e)=>{
674        var inputs = e.target.closest('.todolist_aipsin').querySelectorAll('.todolist_table input[type=checkbox]');
675        if(inputs.length == 0){
676            return false
677        }
678        for (let i = 0; i < inputs.length; i++) {
679            const input = inputs[i];
680            input.checked = true;
681        }
682    })
683    $('.select_aipsin select[name]').on('change',(e)=>{
684        //console.log(e)
685    })
686    SetAipsinSelectChoises
687    document.querySelectorAll('aipsin-captcha ').forEach((el)=>{
688        el.querySelector('.aipsin_captcha_container .checkbox_aipsin input[type=checkbox]').addEventListener('change',(event)=>{
689            var captcha = event.target.closest('aipsin-captcha')
690            var captcha_dropdown = captcha.querySelector('.captcha_dropdown')
691            if(event.target.checked){
692                captcha_dropdown.style.display = 'block';
693            } else{
694                captcha_dropdown.style.display = 'none';
695            }
696        })
697        getCaptchaTextImage(el.querySelector('[bhif9_3ugfihgihsksaifowehfierhgiheh_fuewhfierhgigiu3hgjer]'));
698    });
699    document.querySelectorAll('[suneditor_read_only]').forEach((el)=>{
700        // GenerateHTMLReadOnly(el)
701    })
702    if(window.Coloris){
703        Coloris({
704            themeMode: 'dark',
705            alpha: false,
706            onChange: (color, input) => {
707                input.setAttribute('placeholder-shown','placeholder-shown')
708                // input.dispatchEvent(new Event('input', {bubbles:true}))
709            }
710        });
711    }
712    document.querySelectorAll('.aipsin_html_content').forEach((el)=>{
713        el.querySelectorAll('a').forEach((jl)=>{
714            if(jl.href.startsWith('http://')){
715                jl.href = jl.href.replace('http://','https://')
716            }
717        })
718        el.querySelectorAll('img').forEach((img)=>{
719            img.setAttribute('style','')
720        })
721        // SUNEDITOR.create(el)
722        // var sun_editor = el.nextElementSibling;
723        // sun_editor.querySelectorAll('.se-toolbar').forEach((e)=>{
724        //     e.remove()
725        // })
726        // sun_editor.querySelectorAll('.se-resizing-bar.sun-editor-common').forEach((e)=>{
727        //     e.remove()
728        // })
729    })
730    // if(inIframe()){
731    //     document.querySelector('[id="umnico-widget-wrapper"]').style.display = 'none';
732    // }
733})
734$( document ).ready(()=>{
735    loadScript('/static/pdfjs/pdf.js',()=>{
736        var pdfjsLib = window['pdfjs-dist/build/pdf'];
737        pdfjsLib.GlobalWorkerOptions.workerSrc = '//cdn.jsdelivr.net/npm/[email protected]/build/pdf.worker.js';
738        document.querySelectorAll('[aipsin_pdf]').forEach((el)=>{
739            new AipsinPDF(el)
740        })
741    })
742});
743$(window).on('load', function () {
744    loadScript('/static/countUp/countUp.min.js')
745    if(hasScript('/static/highcharts/highstock.js')){
746        Highcharts.setOptions({
747            lang: {
748                months: [
749                    'Январь', 'Февраль', 'Март', 'Апрель',
750                    'Май', 'Июнь', 'Июль', 'Август',
751                    'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'
752                ],
753                shortMonths: [
754                    'Янв', 'Фев', 'Мар', 'Апр',
755                    'Май', 'Июн', 'Июл', 'Авг',
756                    'Сен', 'Окт', 'Ноя', 'Дек'
757                ],
758                weekdays: [
759                    'Воскресенье', 'Понедельник', 'Вторник', 'Среда',
760                    'Четверг', 'Пятница', 'Суббота'
761                ],
762                resetZoom:'Очистить масштаб',
763                resetZoomTitle:"Очистить масштаб",
764                rangeSelectorZoom:"Масштаб"
765            }
766        });
767    }
768    loadScript('/static/highcharts/highstock.js', ()=>{
769        loadScript('/static/highcharts/map.js', ()=>{
770            loadScript('/static/highcharts/data.js', ()=>{
771                loadScript('/static/highcharts/highcharts-more.js', ()=>{
772                    loadScript('/static/highcharts/exporting.js', ()=>{
773                        loadScript('/static/highcharts/offline-exporting.js', ()=>{
774                            loadScript('/static/highcharts/accessibility.js', ()=>{
775                                Highcharts.setOptions({
776                                    lang: {
777                                        months: [
778                                            'Январь', 'Февраль', 'Март', 'Апрель',
779                                            'Май', 'Июнь', 'Июль', 'Август',
780                                            'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'
781                                        ],
782                                        shortMonths: [
783                                            'Янв', 'Фев', 'Мар', 'Апр',
784                                            'Май', 'Июн', 'Июл', 'Авг',
785                                            'Сен', 'Окт', 'Ноя', 'Дек'
786                                        ],
787                                        weekdays: [
788                                            'Воскресенье', 'Понедельник', 'Вторник', 'Среда',
789                                            'Четверг', 'Пятница', 'Суббота'
790                                        ],
791                                        resetZoom:'Очистить масштаб',
792                                        resetZoomTitle:"Очистить масштаб",
793                                        rangeSelectorZoom:"Масштаб"
794                                    }
795                                });
796                            })
797                        })
798                    })
799                })
800            })
801        })
802    })
803    if(!document.querySelector('script[src="/static/filepond/filepond.min.js"]')){
804        loadScript('/static/filepond/filepond.min.js',()=>{
805            loadScript('/static/filepond/filepond-plugin-file-validate-type.min.js',()=>{
806                loadScript('/static/filepond/filepond-image-preview.min.js',()=>{
807                    loadScript('/static/filepond/filepond.jquery.js',()=>{
808                        loadScript('/static/filepond/filepond-plugin-image-edit.js',()=>{
809                            const labels_RU = {
810                                labelIdle: 'Перетащите или выберите <span class="filepond--label-action"> Изображение </span>',
811                                labelFileAdded: "Добавить",
812                                labelFileCountPlural: "Файлов в списке",
813                                labelFileCountSingular: "Файл в списке",
814                                labelInvalidField: 'Поле содержит недопустимые файлы',
815                                labelFileWaitingForSize: 'Укажите размер',
816                                labelFileSizeNotAvailable: 'Размер не поддерживается',
817                                labelFileLoading: 'Ожидание',
818                                labelFileLoadError: 'Ошибка при ожидании',
819                                labelFileProcessing: 'Загрузка',
820                                labelFileProcessingComplete: 'Загрузка завершена',
821                                labelFileProcessingAborted: 'Загрузка отменена',
822                                labelFileProcessingError: 'Ошибка при загрузке',
823                                labelFileProcessingRevertError: 'Ошибка при возврате',
824                                labelFileRemoveError: 'Ошибка при удалении',
825                                labelTapToCancel: 'нажмите для отмены',
826                                labelTapToRetry: 'нажмите, чтобы повторить попытку',
827                                labelTapToUndo: 'нажмите для отмены последнего действия',
828                                labelButtonRemoveItem: 'Удалить',
829                                labelButtonAbortItemLoad: 'Прекращено',
830                                labelButtonRetryItemLoad: 'Повторите попытку',
831                                labelButtonAbortItemProcessing: 'Отмена',
832                                labelButtonUndoItemProcessing: 'Отмена последнего действия',
833                                labelButtonRetryItemProcessing: 'Повторите попытку',
834                                labelButtonProcessItem: 'Загрузка',
835                                labelMaxFileSizeExceeded: 'Файл слишком большой',
836                                labelMaxFileSize: 'Максимальный размер файла: {filesize}',
837                                labelMaxTotalFileSizeExceeded: 'Превышен максимальный размер',
838                                labelMaxTotalFileSize: 'Максимальный размер файла: {filesize}',
839                                labelFileSizeBytes: 'байт',
840                                labelFileSizeKilobytes: 'КБ',
841                                labelFileSizeGigabytes: 'ГБ',
842                                labelFileSizeMegabytes: 'МБ',
843                                labelFileTypeNotAllowed: 'Файл неверного типа',
844                                fileValidateTypeLabelExpectedTypes: 'Tipos de arquivo suportados são {allButLastType} ou {lastType}',
845                                imageValidateSizeLabelFormatError: 'Тип изображения не поддерживается',
846                                imageValidateSizeLabelImageSizeTooSmall: 'Изображение слишком маленькое',
847                                imageValidateSizeLabelImageSizeTooBig: 'Изображение слишком большое',
848                                imageValidateSizeLabelExpectedMinSize: 'Минимальный размер: {minWidth} × {minHeight}',
849                                imageValidateSizeLabelExpectedMaxSize: 'Максимальный размер: {maxWidth} × {maxHeight}',
850                                imageValidateSizeLabelImageResolutionTooLow: 'Разрешение слишком низкое',
851                                imageValidateSizeLabelImageResolutionTooHigh: 'Разрешение слишком высокое',
852                                imageValidateSizeLabelExpectedMinResolution: 'Минимальное разрешение: {minResolution}',
853                                imageValidateSizeLabelExpectedMaxResolution: 'Максимальное разрешение: {maxResolution}'
854                            };
855                            FilePond.setOptions(labels_RU)
856                            $.fn.filepond.registerPlugin(
857                                FilePondPluginFileValidateType,
858                                FilePondPluginImagePreview,
859                                FilePondPluginImageEdit
860                            );
861                            document.querySelectorAll('[filepond]').forEach((item)=>{
862                                filepondCreate(item);
863                            })
864                        })
865                    });
866                });
867            })
868        });
869    }
870});
871$(document).on('change','.aipsin-select-colors .aipsin-select-colors-items .aipsin-select-colors-item input', (event)=>{
872    var textBox = event.target.closest('.aipsin-select-colors').querySelector('.aipsin-choice-colors-item')
873    var emBox = event.target.nextElementSibling
874    textBox.innerHTML = event.target.value
875    if(getComputedStyle(emBox).getPropertyValue('--active-widget-color')){
876        textBox.style.setProperty('--active-widget-color',getComputedStyle(emBox).getPropertyValue('--active-widget-color'))
877    } else{
878        textBox.style.removeProperty('--active-widget-color')
879    }
880})
881$(document).on('input','.todolist_aipsin .aipsin_field .input_aipsin input[type="text"]', 
881(event)=>{
882    event.preventDefault();
883    var filter_tr = event.target.closest('tr')
884    var table_trs = event.target.closest('table').querySelectorAll('body tr')
885    var inputs = filter_tr.querySelectorAll('th input[type="text"]')
886    for (let i = 0; i < table_trs.length; i++) {
887        var tr = table_trs[i];
888        for (let j = 0; j < inputs.length; j++) {
889            const input = inputs[j];
890            var txt = input.value
891            var td = tr.getElementsByTagName("td")[j]
892            if(td){
893                var td_txt = td.innerText;
894                if (td_txt.toUpperCase().indexOf(txt.toUpperCase()) > -1) {
895                    $(tr).show();
896                } else {
897                    $(tr).hide();
898                }
899            }
900        }
901    }
902})
903$(document).on('click','.todolist_aipsin .aipsin_field .input_aipsin i.clear', (event)=>{
904    var input = event.target.closest('.input_aipsin').querySelector('input[type="text"]')
905    input.value = '';
906    input.dispatchEvent(new Event('input', {bubbles:true}))
907})
908 
909$(document).on('click',(event)=>{
910    var noticle_bell = document.querySelector('.notification_bell.active');
911    if(noticle_bell && !event.target.closest('.notification_bell_content')){
912        OpenNoticle(noticle_bell)
913    }
914    var history_service = document.querySelector('[onchange="ServiceOpenHistory(event)"]')
915    if(history_service){
916        if(!event.target.closest('.content_button_list') && history_service.checked){
917            history_service.checked = false
918            history_service.dispatchEvent(new Event('change',{bubbles:true}))
919        }
920    }
921    var training_aipsin_content_show_label = event.target.closest('label#label_training_aipsin_content_show')
922    if(!training_aipsin_content_show_label){
923        var training_aipsin_content_show = document.querySelector('input#training_aipsin_content_show')
924        if(training_aipsin_content_show){
925            if(!training_aipsin_content_show.hasAttribute('is_show')&&training_aipsin_content_show.checked==true){
926                training_aipsin_content_show.removeAttribute('is_show')
927                training_aipsin_content_show.checked = false
928            } else{
929                training_aipsin_content_show.setAttribute('is_show','is_show')
930            }
931
932        }
933    }
934})
935$(document).on('click','[ketcher_editor] button',(e)=>{e.preventDefault()})
936$(document).on('input','.select_aipsin>.content_select_aipsin .input_aipsin_filter>input',(e)=>{
937    var pattern = new RegExp(e.target.value.toUpperCase())
938    var list_li = $(e.target.closest('.filter_select_aipsin')).find('li:not([pre_title])')
939    if(e.target.value != ''){
940        list_li.filter((i,el)=>{
941            if(!pattern.test(el.innerHTML.toUpperCase())||el.hasAttribute('selected')){
942                $(el).addClass('hidden')
943            } else{
944                $(el).removeClass('hidden')
945            }
946        })
947    } else{
948        list_li.each((i,el)=>{
949            $(el).removeClass('hidden')
950        })
951    }
952})
953$(document).on('click','.select_aipsin .filter_select_aipsin>ul>li:not([pre_title])',(e)=>{
954    var select_aipsin = $(e.target.closest('.select_aipsin'))
955    var select = select_aipsin.find('select')
956    select_aipsin.find('select option').each((i,el)=>el.removeAttribute('selected'));
957    select_aipsin.find('.filter_select_aipsin>ul>li').each((i,el)=>el.classList.remove('selected'));
958    if(e.target.getAttribute('value')!=''&& !e.target.getAttribute('nullable')){
959        select_aipsin.find(`select option[value="${e.target.getAttribute('value')}"]`).attr('selected', 'selected')
960        select[0].value = e.target.getAttribute('value')
961    } else{
962        select_aipsin.find(`select option[nullable]`).attr('selected', 'selected')
963    }
964    e.target.classList.add('selected');
965    /*АААААААА*/
966    $(e.target.closest('.content_select_aipsin')).find('.filter_select_aipsin').slideUp( "fast", ()=>{
967        e.target.closest('.content_select_aipsin').querySelector('select').classList.remove('active');
968        e.target.closest('.content_select_aipsin').classList.remove('active');
969    });
970    if(select_aipsin.hasClass('select_to_input')){
971        select[0].closest('td').querySelector('input[name]').value = select[0].options[select[0].selectedIndex].text
972    }
973    if(e.target.closest('.select_aipsin').classList.contains('validator')){
974        if(e.target.getAttribute('value')==''||e.target.getAttribute('value')==null){
975            e.target.closest('.select_aipsin').querySelector('select').required?ValidateInput(e.target.closest('.select_aipsin'),'Выберите значение'):ValidateInput(e.target.closest('.select_aipsin'),null,'default')
976        } else{
977            ValidateInput(e.target.closest('.select_aipsin'))
978        }
979    }
980    //var event = new Event('onchange', {'bubbles': true});
981    //select_aipsin.find('select').trigger(jQuery.Event('change', {'bubbles': true}))
982    select_aipsin.find('select')[0].dispatchEvent(new Event('change',{bubbles:true}))
983})
984
985$(document).on('click','.select_aipsin>.content_select_aipsin',(e)=>{
986    var filter_select_aipsin = $(e.target.closest('.content_select_aipsin')).find('.filter_select_aipsin')
987    if(e.target.classList.contains('content_select_aipsin') || e.target.classList.contains('select_aipsin')){
988        if(filter_select_aipsin.is(":hidden")){
989            $(document).find('.content_select_aipsin.active').click();
990            e.target.closest('.content_select_aipsin').querySelector('select').classList.add('active');
991            e.target.closest('.content_select_aipsin').classList.add('active');
992            filter_select_aipsin.slideDown( "fast", ()=>{});
993        } else{
994            filter_select_aipsin.slideUp( "fast", ()=>{
995                e.target.closest('.content_select_aipsin').querySelector('select').classList.remove('active');
996                e.target.closest('.content_select_aipsin').classList.remove('active');
997            });
998        }
999    } else{
1000        e.target.closest('.content_select_aipsin').querySelector('em').animate([
1001            { transform: 'translateY(0%)', offset:0},
1002            { transform: 'translateY(5%)', offset:0.3},
1003            { transform: 'translateY(-5%)', offset:0.7},
1004            { transform: 'translateY(0%)', offset:1},
1005        ], {
1006            easing:'ease',
1007            duration:1500,
1008        })
1009    }
1010})
1011
1012
1013$(document).on({
1014    mouseenter: function (e) {
1015        /*var filter_select_aipsin = $(e.target.closest('.select_aipsin')).find('.filter_select_aipsin')
1016        if(filter_select_aipsin.is(":hidden")){
1017            e.target.closest('.select_aipsin').querySelector('select').classList.add('active');
1018            e.target.closest('.select_aipsin').querySelector('.content_select_aipsin').classList.add('active');
1019            filter_select_aipsin.slideDown( "fast", ()=>{});
1020        }*/
1021    },
1022    mouseleave: function (e) {
1023        var filter_select_aipsin = $(e.target.closest('.select_aipsin')).find('.filter_select_aipsin')
1024        if(!filter_select_aipsin.is(":hidden")){
1025            filter_select_aipsin.slideUp( "fast", ()=>{
1026                e.target.closest('.select_aipsin').querySelector('select').classList.remove('active');
1027                e.target.closest('.select_aipsin').querySelector('.content_select_aipsin').classList.remove('active');
1028            });
1029        }
1030    }
1031}, '.select_aipsin');
1032
1033$(document).on('click','.input_aipsin>.toolbar i',(e)=>{
1034    var parrent = e.target.closest('.input_aipsin')
1035    var classList = parrent.classList
1036    var input = parrent.querySelector('input')
1037    if(e.target.classList.contains('clear')&&!input.disabled){
1038        if($(parrent).next().is('.input_aipsin')||$(parrent).prev().is('.input_aipsin')){
1039            $(parrent).remove()
1040        } else{
1041            AipsinInputClear(parrent)
1042        }
1043    } else if(e.target.classList.contains('add')&&!input.disabled){
1044        $(parrent).find('input').removeClass('active')
1045        $(parrent).find('.search_list').removeClass('active')
1046        $(parrent).find('.search_list').attr('style','display:none;')
1047        var clone = $(parrent).clone()
1048        clone.find('input').each((i,el)=>{
1049            AipsinInputClear(parrent)
1050        })
1051        $(parrent).after(clone)
1052    } else if(e.target.classList.contains('password_change_type')&&!input.disabled){
1053        var open_svg = e.target.querySelector('.open')
1054        var close_svg = e.target.querySelector('.close')
1055        if(input.type=='password'){
1056            input.type='text'
1057            close_svg.style.display = 'block'
1058            open_svg.style.display = 'none'
1059        } else{
1060            input.type='password'
1061            close_svg.style.display = 'none'
1062            open_svg.style.display = 'block'
1063        }
1064    } else if(e.target.classList.contains('map')) {
1065        if(!document.querySelector('[drogable-modal="map"]').classList.contains('open')){
1066            document.querySelector('[navbar-item="map"]').dispatchEvent(new Event('click',{bubbles:true}))
1067        }
1068    } else if(e.target.classList.contains('country_region_city')){
1069        CreateIframeModal('/country_region_city/?clear_page')
1070        if(!e.target.hasAttribute('has_event_iframe')){
1071            e.target.setAttribute('has_event_iframe','has_event_iframe')
1072            e.target.addEventListener('iframe_send', (event)=>{
1073                AipsinInputSetValue(event.target.closest('.aipsin_field').querySelector('input'), event.detail);
1074            })
1075            $(document).on('iframe_send','#dict_universal_import_content .form_aipsin_join_dict_fields button.button_main[iframe-call]',(event)=>{
1076                AipsinInputSetChoises(event.target.closest('.aipsin_field').querySelector('select'),[event.detail],true);
1077                AipsinInputSetValue(event.target.closest('.aipsin_field').querySelector('select'), event.detail[0]);
1078                AipsinInputSetValue(event.target.closest('.multi_input_aipsin').querySelector('[name="analysisDictUniversalAssignField"]'), [], true);
1079                event.target.closest('.multi_input_aipsin').querySelector('[name="analysisDictUniversalAssignField"]').value = ''
1080                GetData(`/application_mobile/dict_universal/${event.detail[0]}/field_list/?article_fields`).then((fieldList)=>{
1081                    AipsinInputSetChoises(event.target.closest('.multi_input_aipsin').querySelector('[name="analysisDictUniversalAssignField"]'), fieldList, true);
1082                })
1083            })
1084        }
1085    } else if(e.target.classList.contains('disabled')){
1086        var open_svg = e.target.querySelector('.open')
1087        var close_svg = e.target.querySelector('.close')
1088        if(input.disabled){
1089            DisabledEvent(input,false)
1090            close_svg.style.display = 'block'
1091            open_svg.style.display = 'none'
1092        } else{
1093            DisabledEvent(input,true)
1094            close_svg.style.display = 'none'
1095            open_svg.style.display = 'block'
1096        }
1097    }
1098    GenerateInputFormatDatetimePicker(input)
1099    GenerateInputFormatTelephone(input)
1100    GenerateInputFormatText(input)
1101    GenerateInputFormatValidator(input)
1102    GenerateInputFormatTextarea(input)
1103    GenerateSelectInputFormat(input)
1104    GenerateFilepondInputFormat(input)
1105    //input.dispatchEvent(new Event('input', {'bubbles': true}));
1106})
1107$(document).on('click','.multi_input_aipsin>.header_toolbar i',(e)=>{
1108    var parrent = e.target.closest('.multi_input_aipsin')
1109    var classList = parrent.classList
1110    var is_disabled = parrent.hasAttribute('disabled')
1111    if(e.target.classList.contains('clear')&&!is_disabled){
1112        if($(parrent).next().is('.multi_input_aipsin')||$(parrent).prev().is('.multi_input_aipsin')){
1113            $(parrent).remove()
1114        } else{
1115            AipsinInputClear(parrent)
1116        }
1117    } else if(e.target.classList.contains('add')&&!is_disabled){
1118        parrent.querySelectorAll('.aipsin_field').forEach(el=>{
1119            var field_el = $(el)
1120            field_el.find('input').removeClass('active')
1121            field_el.find('.search_list').removeClass('active')
1122            field_el.find('.search_list').attr('style','display:none;')
1123        })
1124        var clone = $(parrent).clone()
1125        AipsinInputClear(clone)
1126        $(parrent).after(clone)
1127    } else if(e.target.classList.contains('add_copy')&&!is_disabled){
1128        parrent.querySelectorAll('.aipsin_field').forEach(el=>{
1129            var field_el = $(el)
1130            field_el.find('input').removeClass('active')
1131            field_el.find('.search_list').removeClass('active')
1132            field_el.find('.search_list').attr('style','display:none;')
1133        })
1134        var clone = $(parrent).clone()
1135        $(parrent).after(clone)
1136    }
1137    //input.dispatchEvent(new Event('input', {'bubbles': true}));
1138})
1139$(document).on('click','.select_aipsin>.content_select_aipsin>.toolbar i',(e)=>{
1140    var parrent = e.target.closest('.select_aipsin')
1141    var classList = parrent.classList
1142    var select = parrent.querySelector('select')
1143    if(e.target.classList.contains('clear')){
1144        if($(parrent).next().is('.select_aipsin')||$(parrent).prev().is('.select_aipsin')){
1145            $(parrent).remove()
1146        } else{
1147            AipsinInputClear(parrent)
1148        }
1149    } else if(e.target.classList.contains('add')){
1150        var clone = $(parrent).clone()
1151        $(clone).find('.filter_select_aipsin').attr('style','display:none;')
1152        clone.find('select option').each((i,el)=>el.removeAttribute('selected'));
1153        clone.find('.filter_select_aipsin>ul>li').each((i,el)=>el.classList.remove('selected'));
1154        clone.find('select').removeClass('active');
1155        clone.find('.content_select_aipsin').removeClass('active');
1156        $(parrent).after(clone)
1157        
1158    }
1159})
1160$(document).on('click','.input_aipsin>.header',(event)=>{
1161    event.target.closest('.input_aipsin').querySelector('input').focus()
1162})
1163$(document).on('input','.input_aipsin>input, .textarea_aipsin>textarea, .input_aipsin.input_aipsin_range_slider>label>input',(e)=>{
1164    InputAipsin(e)
1165})
1166$(document).on('focus','.input_aipsin>input, .textarea_aipsin>textarea, .input_aipsin.input_aipsin_range_slider>label>input',(e)=>{
1167    FocusInputAipsin(e)
1168})
1169$(document).on('focusout','input, .input_aipsin>input, .textarea_aipsin>textarea, .input_aipsin.input_aipsin_range_slider>label>input',(e)=>{
1170    FocusOutInputAipsin(e)
1171})
1172function FocusInputAipsin(event){
1173    var parrent = event.target.closest('.input_aipsin, .textarea_aipsin')
1174    var classList = parrent.classList
1175    parrent.setAttribute('placeholder-shown','placeholder-shown')
1176}
1176
1177function FocusOutInputAipsin(event){
1178    var parrent = event.target.closest('.input_aipsin, .textarea_aipsin')
1179    if(parrent){
1180        var classList = parrent.classList
1181        parrent.removeAttribute('placeholder-shown')
1182    }
1183}
1184function TextAreaMessageUp(event, row_max=null){
1185    var input = event.target
1186    if(!input.hasAttribute('rows_sum')){
1187        input.setAttribute('rows_sum',input.getAttribute('rows'))
1188    }
1189    if(row_max){
1190        if(input.scrollHeight < 20*row_max){
1191            return false
1192        }
1193    }
1194    input.style.cssText = 'height:auto; padding:0';
1195    input.style.cssText = 'height:' + input.scrollHeight + 'px';
1196}
1197function AipsinInputSetChoises(selector, choises=[],nullable=false){
1198    var input = null
1199    if(typeof selector == 'string'){
1200        input = document.querySelector(selector)
1201    } else{
1202        input = selector
1203    }
1204    if(!input || typeof input == 'string'){
1205        return null
1206    }
1207    var dataList = []
1208    if(Array.isArray(choises)){
1209        for (let i = 0; i < choises.length; i++) {
1210            const item = choises[i];
1211            if(Array.isArray(item)){
1212                dataList.push([item[0],item[1]])
1213            } else if(isDict(item)){
1214                dataList.push([item.value,item.text])
1215            } else{
1216                dataList.push([item,item])
1217            }
1218        }
1219    } else if(isDict(choises)){
1220        for (const [key,val] of Object.entries(choises)) {
1221            dataList.push([key,val])
1222        }
1223    }
1224    if(input.tagName == 'SELECT'){
1225        input.querySelectorAll('option, optgroup').forEach((el)=>el.remove())
1226        if(nullable){
1227            var opt = document.createElement('option')
1228            opt.setAttribute('nullable','nullable')
1229            input.add(opt)
1230        }
1231        dataList.forEach(item => {
1232            var opt = document.createElement('option')
1233            opt.value = item[0]
1234            opt.text = item[1]
1235            input.add(opt)
1236        });
1237    }
1238    if(input.closest('.select_aipsin')){
1239        SetAipsinSelectChoises(input.closest('.select_aipsin'));
1240    }
1241}
1242function AipsinInputSetValue(selector, value){
1243    var input = null
1244    if(typeof selector == 'string'){
1245        input = document.querySelector(selector)
1246    } else{
1247        input = selector
1248    }
1249    if(!input || typeof input == 'string' || (input.value==undefined||input.value==null)){
1250        return false
1251    }
1252    if(input.tagName == 'SELECT'){
1253        var searchItem = input.closest('.select_aipsin').querySelector(`.filter_select_aipsin>ul li[value="${value}"]`)
1254        if(searchItem){
1255            searchItem.dispatchEvent(new Event('click',{'bubbles': true}))
1256        }
1257        if(value){
1258            if(Array.isArray(value)){
1259                value.forEach((v)=>{
1260                    var opt = input.querySelector(`option[value="${v}"]`)
1261                    opt.setAttribute('selected','selected')
1262                    input.value = v
1263                })
1264            } else{
1265                var opt = input.querySelector(`option[value="${value}"]`)
1266                opt.setAttribute('selected','selected')
1267                input.value = value
1268            }
1269        }
1270    } else{
1271        input.value = value
1272    }
1273    //input.dispatchEvent(new Event('input',{'bubbles': true}))
1274}
1275function AipsinInputGetValue(selector){
1276    var input = null
1277    if(typeof selector == 'string'){
1278        input = document.querySelector(selector)
1279        if(!input){
1280            input = document.querySelector(`[name="${selector}"]`)
1281        }
1282    } else{
1283        input = selector
1284    }
1285    if(!input || typeof input == 'string'){
1286        return null
1287    }
1288    return input.value
1289    //input.dispatchEvent(new Event('input',{'bubbles': true}))
1290}
1291function AipsinInputClear(parrent){
1292    parrent = $(parrent)
1293
1294    if(parrent.hasClass('select_aipsin')){
1295        parrent.find('.filter_select_aipsin').slideUp( "fast", ()=>{
1296            parrent.find('select option').each((i,el)=>el.removeAttribute('selected'));
1297            parrent.find('.filter_select_aipsin>ul>li').each((i,el)=>{el.classList.remove('selected');el.classList.remove('hidden');});
1298            parrent.find('select').removeClass('active');
1299            parrent.find('.content_select_aipsin').removeClass('active');
1300        })
1301        parrent.find('select').val('')
1302    } else if(parrent.hasClass('multi_input_aipsin')){
1303        parrent.find('input, .select_aipsin, .filepond--root, [html_editor]').each((i,field)=>{
1304            if(field.classList.contains('select_aipsin')){
1305                $(field).find('.filter_select_aipsin').slideUp( "fast", ()=>{
1306                    $(field).find('select option').each((j,el)=>el.removeAttribute('selected'));
1307                    $(field).find('.filter_select_aipsin>ul>li').each((j,el)=>{el.classList.remove('selected');el.classList.remove('hidden');});
1308                    $(field).find('select').removeClass('active');
1309                    $(field).find('.content_select_aipsin').removeClass('active');
1310                })
1311                $(field).find('select').val('')
1312            } else if(field.classList.contains('filepond--root')){
1313                var pond = FilePond.find(field)
1314                if(pond){
1315                    pond.removeFiles({ revert: true })
1316                } else{
1317                    var input_file = field.querySelector('.filepond--data input');
1318                    filepondCreate(field,input_file?input_file.getAttribute('name'):null)
1319                }
1320            } else if(field.hasAttribute('html_editor')){
1321                GenerateHTMLEditor(field,field.getAttribute('label'))
1322            } else{
1323                if(field.checked){
1324                    field.checked = false
1325                }
1326                field.value = ''
1327                if(field.closest('.input_aipsin_date')){
1328                    $(field).datetimepicker({
1329                        format:'d-m-Y',
1330                        timepicker: false,
1331                        scrollInput : false,
1332                        dayOfWeekStart: 1,
1333                        onChangeDateTime:function(dp,$input){
1334                            //$input.trigger("input")
1335                        }
1336                    })
1337                } else if(field.closest('.input_aipsin_datetime')){
1338                    $(field).datetimepicker({
1339                        format:'d-m-Y H:i',
1340                        timepicker: true,
1341                        scrollInput : false,
1342                        dayOfWeekStart: 1,
1343                        onChangeDateTime:function(dp,$input){
1344                            //$input.trigger("input")
1345                        }
1346                    }) 
1347                }
1348                if(field.closest('input_aipsin_date')||field.closest('input_aipsin_datetime')){
1349                    var property_inputmask = {
1350                        showMaskOnFocus: true,
1351                        showMaskOnHover: false,
1352                        autoUnmask: true,
1353                        clearMaskOnLostFocus: true
1354                    }
1355                    $(field).inputmask(property_inputmask);
1356                    $(field).inputmask(property_inputmask);
1357                }
1358                // var nextCntr = field.closest('label.input_aipsin')
1359                // console.log(nextCntr)
1360                // if(nextCntr){
1361                //     while (nextCntr) {
1362                //         var i_clear = nextCntr.querySelector('i.clear')
1363                //         if (i_clear) {
1364                //             i_clear.dispatchEvent(new Event('click', {bubbles: true}))
1365                //         }
1366                //         nextCntr = nextCntr.nextElementSibling;
1367                //     }
1368                // }
1369            }
1370        })
1371    } else if(parrent.hasClass('input_aipsin')){
1372        parrent.find('input').val('')
1373        if(parrent.hasClass('input_aipsin_date')){
1374            $(parrent).find('input').datetimepicker({
1375                format:'d-m-Y',
1376                timepicker: false,
1377                scrollInput : false,
1378                dayOfWeekStart: 1,
1379                onChangeDateTime:function(dp,$input){
1380                    //$input.trigger("input")
1381                }
1382            })
1383        } else if(parrent.hasClass('input_aipsin_datetime')){
1384            $(parrent).find('input').datetimepicker({
1385                format:'d-m-Y H:i',
1386                timepicker: true,
1387                scrollInput : false,
1388                dayOfWeekStart: 1,
1389                onChangeDateTime:function(dp,$input){
1390                    //$input.trigger("input")
1391                }
1392            }) 
1393        }
1394        if(parrent.hasClass('input_aipsin_date')||parrent.hasClass('input_aipsin_datetime')){
1395            var property_inputmask = {
1396                showMaskOnFocus: true,
1397                showMaskOnHover: false,
1398                autoUnmask: true,
1399                clearMaskOnLostFocus: true
1400            }
1401            $(".input_aipsin_date>input").inputmask(property_inputmask);
1402            $(".input_aipsin_datetime>input").inputmask(property_inputmask);
1403        }
1404    }
1405}
1406function AipsinInputAppend(selector, value, unique = true){
1407    var inputs = null
1408    if(typeof selector == 'string'){
1409        inputs = document.querySelectorAll(selector)
1410    } else{
1411        inputs = selector
1412    }
1413    if(!inputs || typeof inputs == 'string'){
1414        return false
1415    } else if(inputs.length==0){
1416        return false
1417    }
1418    for (let i = 0; i < inputs.length; i++) {
1419        const input = inputs[i];
1420        var multiply_field = input.closest('[multiply]')
1421        if(!multiply_field){
1422            break
1423        }
1424        if(unique){
1425            if(input.value==value){
1426                break
1427            }
1428        }
1429        if(inputs.length==1&&input.value==''){
1430            input.value = value
1431        } else{
1432            if(i==inputs.length-1){
1433                var clone = $(multiply_field).clone()
1434                AipsinInputClear(clone)
1435                $(multiply_field).after(clone)
1436                var inputs_clone = clone.find('input')
1437                for (let j = 0; j < inputs_clone.length; j++) {
1438                    const el_input = inputs_clone[j];
1439                    if(el_input.id==input.id){
1440                        el_input.value = value
1441                        break
1442                    }
1443                }
1444            }
1445        }
1446    }
1447}
1448function InputAipsin(e){
1449    var parrent = e.target.closest('.input_aipsin, .textarea_aipsin')
1450    var classList = parrent.classList
1451    if(classList.contains('input_aipsin_text')){
1452        input_aipsin_text(parrent,e)
1453    } else if(classList.contains('input_aipsin_password')){
1454        input_aipsin_password(parrent,e)
1455    } else if(classList.contains('input_aipsin_email')){
1456        input_aipsin_email(parrent,e)
1457    } else if(classList.contains('input_aipsin_number')){
1458        input_aipsin_number(parrent,e)
1459    } else if(classList.contains('input_aipsin_phone')){
1460        input_aipsin_phone(parrent,e)
1461    } else if(classList.contains('input_aipsin_coordinates')){
1462        input_aipsin_coordinates(parrent,e)
1463    } else if(classList.contains('input_aipsin_number_less')){
1464        input_aipsin_number_less(parrent,e)
1465    } else if(classList.contains('input_aipsin_number_more')){
1466        input_aipsin_number_more(parrent,e)
1467    } else if(classList.contains('input_aipsin_date')){
1468        input_aipsin_date(parrent,e)
1469    } else if(classList.contains('input_aipsin_datetime')){
1470        input_aipsin_datetime(parrent,e)
1471    } else if(classList.contains('input_aipsin_search')){
1472        input_aipsin_search(parrent,e)
1473    } else if(classList.contains('input_aipsin_filter')){
1474        input_aipsin_filter(parrent,e)
1475    } else if(classList.contains('textarea_aipsin')){
1476        input_aipsin_textarea(parrent,e)
1477    } else if(classList.contains('input_aipsin_range_slider')){
1478        input_aipsin_range_slider(parrent,e)
1479    }
1480    input_aipsin_range(parrent,e)
1481}
1482function input_aipsin_range_slider(el,e){
1483    el.querySelector('p').style.color = 'var(--theme-color-widget, #c81e1e)'
1484    el.style.border = '2px solid var(--theme-color-widget, #c81e1e)'
1485    el.style.color = 'var(--theme-color-widget, #c81e1e)'
1486    el.setAttribute('focus','focus')
1487    setTimeout(()=>{
1488        el.querySelector('p').style.color = ''
1489        el.style.border = ''
1490        el.style.color = ''
1491    },1500)
1492}
1493function input_aipsin_text(el,e){
1494    el.querySelector('em>svg').animate([
1495        { transform: 'rotate(8deg)', offset:0},
1496        { transform: 'rotate(0deg)', offset:0.2},
1497        { transform: 'rotate(8deg)', offset:0.5},
1498        { transform: 'rotate(0deg)', offset:1},
1499    ], {
1500        easing:'ease',
1501        duration:1000,
1502    })
1503    if((el.classList.contains('validator')&&!el.classList.contains('not_val
1503idate'))){
1504        if(e.target.value != ''){
1505            ValidateInput(el)
1506        } else{
1507            e.target.required?ValidateInput(el,`Заполните поле${GetLabel(el)}`):ValidateInput(el,null,'default')
1508        }
1509    }
1510}
1511function input_aipsin_password(el,e){
1512    el.querySelector('em>svg').animate([
1513        { transform: 'rotate(8deg)', offset:0},
1514        { transform: 'rotate(0deg)', offset:0.2},
1515        { transform: 'rotate(8deg)', offset:0.5},
1516        { transform: 'rotate(0deg)', offset:1},
1517    ], {
1518        easing:'ease',
1519        duration:1000,
1520    })
1521    if((el.classList.contains('validator')&&!el.classList.contains('not_validate'))){
1522        if(e.target.value != ''){
1523            if(e.target.hasAttribute('password_len')){
1524                if(e.target.value.length >= Number(e.target.getAttribute('password_len'))){
1525                    ValidateInput(el)
1526                } else{
1527                    ValidateInput(el,`Пароль не должен быть меньше ${e.target.getAttribute('password_len')}`)
1528                }
1529            } else{
1530                ValidateInput(el)
1531            }
1532            
1533        } else{
1534            e.target.required?ValidateInput(el,`Заполните поле${GetLabel(el)}`):ValidateInput(el,null,'default')
1535        }
1536    }
1537}
1538function input_aipsin_email(el,e){
1539    el.querySelector('em>svg').animate([
1540        { transform: 'rotate(8deg)', offset:0},
1541        { transform: 'rotate(0deg)', offset:0.2},
1542        { transform: 'rotate(8deg)', offset:0.5},
1543        { transform: 'rotate(0deg)', offset:1},
1544    ], {
1545        easing:'ease',
1546        duration:1000,
1547    })
1548    if((el.classList.contains('validator')&&!el.classList.contains('not_validate'))){
1549        if(validateEmail(e.target.value)){
1550            ValidateInput(el)
1551        } else{
1552            if(e.target.value == ''){
1553                e.target.required?ValidateInput(el,`Заполните поле${GetLabel(el)}`):ValidateInput(el,null,'default')
1554            } else{
1555                ValidateInput(el,`Некорректный Email`)
1556            }
1557        }
1558    }
1559}
1560function input_aipsin_coordinates(el,e){
1561    el.querySelector('em>svg').animate([
1562        { transform: 'rotate(8deg)', offset:0},
1563        { transform: 'rotate(0deg)', offset:0.2},
1564        { transform: 'rotate(8deg)', offset:0.5},
1565        { transform: 'rotate(0deg)', offset:1},
1566    ], {
1567        easing:'ease',
1568        duration:1000,
1569    })
1570    if((el.classList.contains('validator')&&!el.classList.contains('not_validate'))){
1571        if(e.target.value != ''){
1572            ValidateInput(el)
1573        } else{
1574            e.target.required?ValidateInput(el,`Заполните поле${GetLabel(el)}`):ValidateInput(el,null,'default')
1575        }
1576    }
1577}
1578function input_aipsin_number(el,e){
1579    el.querySelector('em').animate([
1580        { transform: 'rotate(0deg)', offset:0},
1581        { transform: 'rotate(360deg)', offset:1},
1582    ], {
1583        easing:'ease',
1584        duration:500,
1585    })
1586}
1587function input_aipsin_phone(el,e){
1588    var svg_icon = el.querySelector('em>svg')
1589    svg_icon?svg_icon.animate([
1590        { transform: 'rotate(0deg)', offset:0},
1591        { transform: 'rotate(35deg)', offset:0.5},
1592        { transform: 'rotate(0deg)', offset:1},
1593    ], {
1594        easing:'ease',
1595        duration:500,
1596    }):null
1597    if((el.classList.contains('validator')&&!el.classList.contains('not_validate'))&&!el.classList.contains('country_mask')){
1598        if(e.target.value != ''){
1599            if(!validatePhone(e.target.value) || e.target.value[0]!='+'){
1600                ValidateInput(el,'Укажите правильный номер')
1601            } else{
1602                ValidateInput(el)
1603            }
1604            
1605        } else{
1606            e.target.required?ValidateInput(el,`Заполните поле${GetLabel(el)}`):ValidateInput(el,null,'default')
1607        }
1608    }
1609}
1610function input_aipsin_date(el,e){
1611    el.querySelector('em').animate([
1612        { transform: 'scale(1)', offset:0},
1613        { transform: 'scale(1.2)', offset:0.5},
1614        { transform: 'scale(1)', offset:1},
1615    ], {
1616        easing:'ease',
1617        duration:500,
1618    })
1619}
1620function input_aipsin_datetime(el,e) {
1621    el.querySelector('em').animate([
1622        { transform: 'scale(1)', offset:0},
1623        { transform: 'scale(1.2)', offset:0.5},
1624        { transform: 'scale(1)', offset:1},
1625    ], {
1626        easing:'ease',
1627        duration:500,
1628    })
1629}
1630function input_aipsin_number_less(el,e){
1631    el.querySelector('em').animate([
1632        { transform: 'translateX(0%)', offset:0},
1633        { transform: 'translateX(10%)', offset:0.5},
1634        { transform: 'translateX(0%)', offset:1},
1635    ], {
1636        easing:'ease',
1637        duration:500,
1638    })
1639}
1640function input_aipsin_number_more(el,e) {
1641    el.querySelector('em').animate([
1642        { transform: 'translateX(0%)', offset:0},
1643        { transform: 'translateX(-10%)', offset:0.5},
1644        { transform: 'translateX(0%)', offset:1},
1645    ], {
1646        easing:'ease',
1647        duration:500,
1648    })
1649}
1650function input_aipsin_filter(el,e) {
1651    el.querySelector('em').animate([
1652        { transform: 'scaleX(1)', offset:0},
1653        { transform: 'scaleX(-1)', offset:0.5},
1654        { transform: 'scaleX(1)', offset:1},
1655    ], {
1656        easing:'ease',
1657        duration:1000,
1658    })
1659}
1660function input_aipsin_search(el,e) {
1661    el.querySelector('em').animate([
1662        { transform: 'translateX(0px) translateY(0px)', offset:0},
1663        { transform: 'translateX(-2px) translateY(2px)', offset:0.15},
1664        { transform: 'translateX(-3px) translateY(0px)', offset:0.25}
1664,
1665        { transform: 'translateX(0px) translateY(-3px)', offset:0.5},
1666        { transform: 'translateX(2px) translateY(-2px)', offset:0.75},
1667        { transform: 'translateX(0px) translateY(0px)', offset:1},
1668    ], {
1669        easing:'ease',
1670        duration:2000,
1671    })
1672    var parrent = e.target.closest('.input_aipsin')
1673    var classList = parrent.classList
1674    if(classList.contains('input_aipsin_search') && !parrent.querySelector('.search_custom_list')){
1675        input_aipsin_search_list(parrent,e)
1676    }
1677}
1678function input_aipsin_textarea(el,e) {
1679    if(e.target.value == ''){
1680        el.classList.remove('empty')
1681    } else{
1682        el.classList.add('empty')
1683    }
1684}
1685function input_aipsin_range(el,e){
1686    var range = el.closest('.aipsin_range')
1687    if(range){
1688        var arrows = null
1689        var is_right = true
1690        if(el.nextElementSibling){
1691            arrows = el.nextElementSibling
1692            is_right = true
1693        } else{
1694            arrows = el.previousElementSibling
1695            is_right = false
1696        }
1697        if(arrows){
1698            if(arrows.classList.contains('arrows')){
1699                if(is_right){
1700                    arrows.classList.remove('left');
1701                    arrows.classList.add('right');
1702                } else{
1703                    arrows.classList.remove('right');
1704                    arrows.classList.add('left');
1705                }
1706            }
1707            if(!arrows.classList.contains('active')){
1708                arrows.classList.add('active');
1709                setTimeout(()=>{
1710                    arrows.classList.remove('active');
1711                },1000)
1712            }
1713        }
1714    }
1715}
1716async function GetApiSearch(e,url){
1717    if(!e.target){return null}
1718    var data_list = await $.getJSON(url)
1719    var ul = $(e.target.closest('.input_aipsin_search')).find('.search_custom_list>ul')
1720    ul.html('')
1721    data_list.forEach(word => {
1722        ul.append(`<li class>${word}</li>`)
1723    });
1724    if (e.target.value.length <=2 || data_list.length == 0||e.target.value==''){
1725        $(e.target.closest('.input_aipsin_search')).find('.search_custom_list').slideUp( "fast", ()=>{
1726            e.target.classList.remove('active')
1727        });
1728    } else{
1729        e.target.classList.add('active')
1730        $(e.target.closest('.input_aipsin_search')).find('.search_custom_list').addClass('active')
1731        $(e.target.closest('.input_aipsin_search')).find('.search_custom_list').slideDown( "fast", ()=>{});
1732    }
1733}
1734function input_aipsin_search_list(parrent,e) {
1735    var value = e.target.value
1736    var pattern = new RegExp(value.toUpperCase())
1737    var list_li = $(parrent).find('.search_list>ul>li')
1738    var search_list = $(parrent).find('.search_list')
1739    if(value != ''){
1740        var count_hiden_li = list_li.filter((i,el)=>{
1741            if(!pattern.test(el.innerHTML.toUpperCase())||el.hasAttribute('selected')){
1742                $(el).addClass('hidden')
1743                return el
1744            } else{
1745                $(el).removeClass('hidden')
1746            }
1747        }).length
1748        list_li.each((i,el)=>{
1749            el.classList.remove('selected');
1750        })
1751        if(list_li.length==count_hiden_li){
1752            search_list.slideUp( "fast", ()=>{
1753                parrent.querySelector('input').classList.remove('active')
1754            });
1755        } else{
1756            if(search_list.is(":hidden")){
1757                parrent.querySelector('input').classList.add('active')
1758                search_list.slideDown( "fast", ()=>{});
1759            }
1760        }
1761    } else{
1762        search_list.slideUp( "fast", ()=>{
1763            parrent.querySelector('input').classList.remove('active')
1764            list_li.each((i,el)=>{
1765                $(el).removeClass('hidden')
1766            })
1767        });
1768    }
1769}
1770$(document).on('click','.input_aipsin_search>.search_list>ul>li',(e)=>{
1771    e.target.closest('.input_aipsin').querySelector('input').value = e.target.innerText;
1772    $(e.target.closest('.search_list')).find('ul>li').each((i,el)=>{
1773        $(el).removeClass('selected')
1774    })
1775    e.target.classList.add('selected')
1776    if(!e.target.classList || !e.target.classList.contains('input_aipsin'))
1777        var input_aipsin = $(e.target.closest('.input_aipsin'))
1778    else
1779        var input_aipsin = $(e.target)
1780    var search_list = input_aipsin.find('.search_list')
1781    if(!search_list.is(":hidden")){
1782        search_list.slideUp( "fast", ()=>{
1783            input_aipsin.find('input').removeClass('active')
1784            if(!search_list.hasClass('search_custom_list')){
1785                search_list.find('ul>li').each((i,el)=>{
1786                    $(el).removeClass('hidden')
1787                })
1788            }
1789        });
1790    }
1791})
1792$(document).on('click','.input_aipsin',(e)=>{
1793    if(!e.target.classList || !e.target.classList.contains('input_aipsin'))
1794        var input_aipsin = $(e.target.closest('.input_aipsin'))
1795    else
1796        var input_aipsin = $(e.target)
1797    var search_list = input_aipsin.find('.search_list')
1798    if(input_aipsin.find('input').val()!=''&&search_list.find('ul>li').length!=0){
1799        if(!search_list.hasClass('search_custom_list')){
1800            var pattern = new RegExp(input_aipsin.find('input').val().toUpperCase())
1801            var count_hiden_li = search_list.find('ul>li').filter((i,el)=>{
1802                if(!pattern.test(el.innerHTML.toUpperCase())||el.hasAttribute('selected')){
1803                    $(el).addClass('hidden')
1804                    return el
1805                } else{
1806                    $(el).removeClass('hidden')
1807                }
1808            }).length
1809        }
1810        if(search_list.is(":hidden")){
1811            input_aipsin.find('input').addClass('active')
1812            search_list.slideDown( "fast", ()=>{});
1813        }
1814        }
1815})
1816$(document).on({
1817    mouseenter: function (e) {
1818        /*
1819        if(!e.target.classList || !e.target.classList.contains('input_aipsin'))
1820            var input_aipsin = $(e.target.closest('.input_aipsin'))
1821        else
1822            var input_aipsin = $(e.target)
1823        var search_list = input_aipsin.find('.search_list')
1824        if(input_aipsin.find('input').val()!=''&&search_list.find('ul>li').length!=0){
1825            if(!search_list.hasClass('search_custom_list')){
1826                var pattern = new RegExp(input_aipsin.find('input').val().toUpperCase())
1827                var count_hiden_li = search_list.find('ul>li').filter((i,el)=>{
1828                    if(!pattern.test(el.innerHTML.toUpperCase())||el.hasAttribute('selected')){
1829                        $(el).addClass('hidden')
1830                        return el
1831                    } else{
1832                        $(el).removeClass('hidden')
1833                    }
1834                }).length
1835            }
1836            if(search_list.is(":hidden")){
1837                input_aipsin.find('input').addClass('active')
1838                search_list.slideDown( "fast", ()=>{});
1839            }
1840        }
1841        */
1842    },
1843    mouseleave: function (e) {
1844        if(!e.target.classList || !e.target.classList.contains('input_aipsin'))
1845            var input_aipsin = $(e.target.closest('.input_aipsin'))
1846        else
1847            var input_aipsin = $(e.target)
1848        var search_list = input_aipsin.find('.search_list')
1849        if(!search_list.is(":hidden")){
1850            search_list.slideUp( "fast", ()=>{
1851                input_aipsin.find('input').removeClass('active')
1852                if(!search_list.hasClass('search_custom_list')){
1853                    search_list.find('ul>li').each((i,el)=>{
1854                        $(el).removeClass('hidden')
1855                    })
1856                }
1857            });
1858        }
1859    }
1860}, '.input_aipsin_search');
1861$(document).on('keydown','.input_aipsin_search>input',(e)=>{
1862    var key = e.keyCode || e.charCode;
1863    if(key == 38){
1864        if ($(e.target.closest('.input_aipsin')).find('.search_list>ul>li.selected').not('.hidden').prevAll(".search_list>ul>li").not('.hidden').length > 0) {
1865            $(e.target.closest('.input_aipsin.search_list')).find('ul>li').each((i,el)=>{$(el).removeClass('selected')})
1866            var item_sel = $(e.target.closest('.input_aipsin')).find('.search_list>ul>li.selected').not('.hidden')
1867            .removeClass("selected")
1868            .prevAll(".search_list>ul>li").not('.hidden').first()
1869            .addClass("selected");
1870            item_sel[0].closest('.input_aipsin>.search_list').scrollTop = item_sel[0].closest('.input_aipsin>.search_list').scrollTop-item_sel[0].scrollHeight
1871            $(e.target.closest('.input_aipsin')).find('input').val(item_sel.text())
1872        }
1873    } else if(key == 40){
1874        if ($(e.target.closest('.input_aipsin')).find('.search_list>ul>li.selected').not('.hidden').nextAll(".search_list>ul>li").not('.hidden').length > 0) {
1875            $(e.target.closest('.input_aipsin.search_list')).find('ul>li').each((i,el)=>{$(el).removeClass('selected')})
1876            var item_sel = $(e.target.closest('.input_aipsin')).find('.search_list>ul>li.selected').not('.hidden')
1877            .removeClass("selected")
1878            .nextAll(".search_list>ul>li").not('.hidden').first()
1879            .addClass("selected");
1880            item_sel[0].closest('.input_aipsin>.search_list').scrollTop = item_sel[0].closest('.input_aipsin>.search_list').scrollTop+item_sel[0].scrollHeight
1881            $(e.target.closest('.input_aipsin')).find('input').val(item_sel.text())
1882        } 
1883    } 
1884    if($(e.target.closest('.input_aipsin')).find('.search_list>ul>li.selected').length == 0){
1885        $(e.target.closest('.input_aipsin')).find('.search_list>ul>li').not('.hidden').first().addClass("selected")
1886    }
1887    //e.target.selectionStart = e.target.value.length
1888})
1889function SetAipsinSelectChoises(el){
1890    if(!el.querySelector('.filter_select_aipsin')){
1891        return false
1892    }
1893    var select_options = $(el).find('select>*');
1894        var ul = $(el).find('.filter_select_aipsin>ul')
1895        ul.html("")
1896        var is_empty = true
1897        select_options.each((j,opt)=>{
1898            if(opt.tagName == 'OPTGROUP' ){
1899                ul.append(`<li value="" nullable pre_title>${opt.getAttribute('label')}</li>`)
1900                $(opt).find('option').each((k,optgroup_item)=>{
1901                    if(optgroup_item.value == ''){
1902                        ul.append(`<li value="" nullable ${optgroup_item.hasAttribute('selected')?'class="selected"':''}>Пустое значение</li>`)
1903                    } else{
1904                        ul.append(`<li value="${optgroup_item.value}" ${optgroup_item.hasAttribute('selected')?'class="selected"':''}>${optgroup_item.textContent}</li>`)
1905                    }
1906                    if(optgroup_item.hasAttribute('selected')){
1907                        is_empty = false
1908                    }
1909                })
1910            } else{
1911                if(opt.value == ''){
1912                    ul.append(`<li value="" nullable ${opt.hasAttribute('selected')?'class="selected"':''}>Пустое значение</li>`)
1913                } else{
1914                    ul.append(`<li value="${opt.value}" ${opt.hasAttribute('selected')?'class="selected"':''}>${opt.textContent}</li>`)
1915                }
1916                if(opt.hasAttribute('selected')){
1917                    is_empty = false
1918                }
1919            }
1920        })
1921        if(is_empty){
1922            ul.find('li').first().addClass('selected')
1923        }
1924        if((el.classList.contains('validator')&&!el.classList.contains('not_val
1924idate'))){
1925            if(is_empty){
1926                el.querySelector('select').required?ValidateInput(el,`Выберите значение поля${GetLabel(el)}`):ValidateInput(el,null,'default')
1927            } else{
1928                ValidateInput(el)
1929            }
1930        }
1931}
1932var change_select_input  = function(event){
1933    var td = event.target.closest('table').querySelector('.change_select_input')
1934    var input = td.querySelector('input[name]')
1935    var select = td.querySelector('select')
1936    if(select.options[select.selectedIndex]){
1937        select.options[select.selectedIndex].selected = false
1938    }
1939    if(event.target.checked){
1940        input.value = ''
1941        select.closest('.select_aipsin').style.display = 'none'
1942        input.closest('.input_aipsin').style.display = 'flex'
1943    } else{
1944        input.value = ''
1945        select.closest('.select_aipsin').style.display = 'flex'
1946        input.closest('.input_aipsin').style.display = 'none'
1947    }
1948}
1949function CreateInputAipsin(element,input_class,name,data={}){
1950    element = $(element)
1951    fetch(`/form/inputs/${input_class}/${name}/`,{
1952        method:'POST',
1953        body:data
1954    }).then(async (res)=>{
1955        if (res.ok){
1956            var input = $(res.text)
1957        } else{
1958            TOAST.AddToast(
1959                {
1960                    text:'Данное поле не найдено не найден',
1961                    type:`error`,
1962                }
1963            )
1964            TOAST.ShowToasts()
1965        }
1966    }).catch((err)=>{
1967        TOAST.AddToast(
1968            {
1969                text:'Ошибка добавления поля',
1970                type:`error`,
1971            }
1972        )
1973        TOAST.ShowToasts()
1974    })
1975    input.appendTo(element)
1976    return element
1977}
1978function CreateButtonMain(element,name,type=null,func=null){
1979    element = $(element)
1980    if(type){
1981        type = `type="${type}"`
1982    } else{
1983        type = ''
1984    }
1985    var button = $(`
1986        <button class="button_main" ${type}>
1987            ${name}
1988        </button>
1989    `)
1990    button.appendTo(element)
1991    return element
1992}
1993function getSelectValues(select,add_text=false) {
1994    var result = [];
1995    var options = select && select.options;
1996    var opt;
1997    for (var i=0, iLen=options.length; i<iLen; i++) {
1998      opt = options[i];
1999      if (opt.selected) {
2000        if(add_text){
2001            result.push([opt.value, opt.text]);
2002        } else{
2003            result.push(opt.value || opt.text);
2004        }
2005      }
2006    }
2007    return result;
2008}
2009function TodoAdd(event){
2010    var table = event.target.closest('table')
2011    var trs = table.querySelectorAll('tbody>tr.tr_todo_field')
2012    var clone_tr = trs[trs.length-1].cloneNode(true)
2013    trs[trs.length-1].after(clone_tr)
2014    clone_tr.querySelectorAll('input').forEach(element => {
2015        element.value = ''
2016        element.checked?element.checked=false:null
2017    });
2018    clone_tr.querySelectorAll('textarea').forEach(element => {
2019        element.value = ''
2020        element.checked?element.checked=false:null
2021    });
2022    clone_tr.querySelectorAll('select').forEach(element => {
2023        element.querySelectorAll('option').forEach(opt => {
2024            opt.checked=false
2025        });
2026        element.dispatchEvent(event)
2027    });
2028    clone_tr.querySelectorAll('.ajaximage').forEach(element => {
2029        var label = element.querySelector('label.flex-ajax-btn')
2030        var input = element.querySelector('.file-input')
2031        var link = element.querySelector('.file-link')
2032        var img = element.querySelector('.file-link>img')
2033        var dest = element.querySelector('.file-dest')
2034        var change_id = input.id.split('-')
2035        change_id.splice(-1)
2036        change_id = change_id.join('-')+'-'+id_generator(6)
2037        input.id = change_id
2038        label.htmlFor = change_id
2039        link.href = ''
2040        img.src = ''
2041        dest.value = dest.getAttribute('value')
2042        addHandlers(element)
2043        element.querySelector('.file-remove').dispatchEvent(new Event('click'))
2044        
2045    });
2046}
2047function TodoRemove(event){
2048    var table = event.target.closest('table')
2049    var trs = table.querySelectorAll('tbody>tr.tr_todo_field')
2050    if(trs.length-1 > 1){
2051        var tr = event.target.closest('tr')
2052        tr.remove()
2053    }
2054}
2055function TodoChoiseListEventAll(event){
2056    var parrent = event.target.closest('.aipsin_todo_choise_item')
2057    var val = event.target.value
2058    var inputs = parrent.querySelectorAll('input[type="checkbox"]')
2059    if(event.target.checked){
2060        if(val=='add'){
2061            parrent.classList.add('select_all')
2062            inputs.forEach(element=>element.checked=true)
2063        } else if(val=='remove'){
2064            parrent.classList.remove('select_all')
2065            inputs.forEach(element=>element.checked=false)
2066        }
2067    }
2068}
2069function TodoChoiseListEvent(event){
2070    var parrent = event.target.closest('.aipsin_todo_choise_item')
2071    var radios = parrent.querySelectorAll('input[type="radio"]')
2072    if(radios.length != 0){
2073        var inputs = parrent.querySelectorAll('input[type="checkbox"]')
2074        var checked_inputs = parrent.querySelectorAll('input[type="checkbox"]:checked')
2075        radios.forEach(element=>element.checked=false)
2076        if(inputs.length == checked_inputs.length){
2077            parrent.classList.add('select_all')
2078            parrent.querySelector('input[type="radio"][value="add"]').checked=true
2079        } else if(checked_inputs.length==0){
2080            parrent.classList.remove('select_all')
2081            parrent.querySelector('input[type="radio"][value="remove"]').checked=true
2082        } else{
2083            parrent.classList.remove('select_all')
2084        }
2085    }
2086}
2087function TodoListOpenIframeEvent(event,url){
2088    var input = event.target.closest('.todo_events').querySelector('input[type=checkbox]');
2089    url = url.replace('{%%}',input.value)
2090    CreateIframeModal(url)
2091}
2092
2093
2094$('#file_upload').on('drop', (e)=>{
2095    e.preventDefault()
2096    e.stopPropagation()
2097    uploadFile(e)
2098    if(e.originalEvent.dataTransfer){
2099        if(e.originalEvent.dataTransfer.files.length) {
2100            window['file'] = e.originalEvent.dataTransfer.files[0];
2101            $("#fileinput").prop("files", e.originalEvent.dataTransfer.files);
2102        }
2103    }
2104});
2105$('#fileinput').change((e)=>{
2106    if(e.target.files[0]){
2107        window['file'] = e.target.files[0]           
2108    }
2109})
2110function filepondCreate(element,name=null){
2111    if(element){
2112        element = $(element)
2113        var props = {
2114            storeAsFile: true,
2115            fileValidateTypeDetectType: (source, type) =>
2116            new Promise((resolve, reject) => {
2117                var types = element.attr('accepted-file-types')
2118                if (typeof types === typeof undefined || types === false) {
2119                    return resolve(type);
2120                } else {
2121                    types = types.split(',')
2122                    for (let i = 0; i < types.length; i++) {
2123                        if (source.name.toLowerCase().endsWith(types[i].toLowerCase())) return resolve(types[i].toLowerCase());
2124                    }
2125                }
2126                return reject(type)
2127            }),
2128            onaddfile:(error, file)=>{
2129                console.log(error, file)
2130            }
2131        }
2132        if(name){
2133            props['name']=name
2134        }
2135        if(typeof element.attr('server-url') !== 'undefined' && element.attr('server-url') !== false){
2136            props['server'] = {
2137                process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
2138                    const formData = new FormData();
2139                    formData.append('file', file, file.name);
2140                    
2141                    const request = new XMLHttpRequest();
2142                    request.open('POST', element.attr('server-url'));
2143                    request.setRequestHeader('X-CSRFToken', get_csrftoken('csrftoken'))
2144                    request.upload.onprogress = (e) => {
2145                        progress(e.lengthComputable, e.loaded, e.total);
2146                    };
2147                    request.onload = function () {
2148                        if (request.status >= 200 && request.status < 300) {
2149                            load(request.responseText);
2150                        } else {
2151                            error('oh no');
2152                        }
2153                    };
2154                    request.send(formData);
2155                    return {
2156                        abort: () => {
2157                            request.abort();
2158                            abort();
2159                        },
2160                    };
2161                },
2162                load: (source, load, error, progress, abort, headers) => {
2163                    console.log('attempting to load', source);
2164                },
2165            }
2166        }
2167        if(typeof element.attr('files') !== 'undefined' && element.attr('files') !== false){
2168            props['files'] = []
2169            element.attr('files').split(',').forEach(item => {
2170                if(item != ''){
2171                    props['files'].push({
2172                        source: item
2173                    });
2174                }
2175            });
2176        }
2177        var pond = element.filepond(props)
2178        element.on('FilePond:addfile', (event)=>{});
2179        return pond
2180    } else{
2181        return null;
2182    }
2183}
2184function uploadFile(e){
2185    e.preventDefault()
2186    logo_event('import')
2187    var formdata = new FormData();
2188    for (let i = 0; i < e.target.files.length; i++) {
2189        const file = e.target.files[i];
2190        formdata.append(`file_${i}`, file);
2191    }
2192    $("#progressBar").attr('style','display: block;')
2193    var ajax = new XMLHttpRequest();
2194    ajax.upload.addEventListener("progress", (event)=>progressHandler(event,e.target.files), false);
2195    ajax.addEventListener("load", (event)=>completeHandler(event,e.target.files), false);
2196    ajax.addEventListener("error", (event)=>errorHandler(event,e.target.files), false);
2197    ajax.addEventListener("abort", (event)=>abortHandler(event,e.target.files), false);
2198    ajax.open("POST", "file.php");
2199    try {
2200        ajax.send(formdata);    
2201    } catch (error) {}
2202}
2203var uploadFileApi = function(method, url, data, headers, cb) {
2204    var req = new XMLHttpRequest()
2205    req.open(method, url, true)
2206    Object.keys(headers).forEach(function(key){
2207        req.setRequestHeader(key, headers[key])
2208    })
2209    req.onload = function() {
2210        cb(req.status, req.responseText)
2211    }
2212    req.onerror = req.onabort = function() {
2213    }
2214    req.upload.onprogress = function(data) {
2215    }
2216    req.send(data)
2217}
2218function progressHandler(event,files) {
2219    event.preventDefault()
2220    var percent = (event.loaded / event.total) * 100;
2221    $("#progressBar")[0].value = Math.round(percent);
2222    $('#text_content>h4').html(`Загружено ${event.loaded} из ${event.total}</br>На ${Math.round(percent)} % загружено`);
2223}
2224function completeHandler(event,files) {
2225    event.preventDefault()
2226    $("#progressBar").attr('style','display: none;')
2227    $("#progressBar")[0].value = 0;
2228    var all_size = 0
2229    for (let i = 0; i < files.length; i++) {
2230        all_size += files[i].size
2231    }
2232    if(files.length == 0){
2233        $('#text_content>h4').html(`
2234        Выберите или переместите файл
2235        `);
2236    }
2237    else if(files.length==1){
2238        $('#text_content>h4').html(`
2239        Выбран файл: ${files[0].name}</br>
2240        Размер: ${formatBytes(all_size)}`);
2241    } else{
2242        $('#text_content>h4').html(`
2243        Выбрано ${files.length} файлов</br>
2244        Общим размером: ${formatBytes(all_size)}`);
2245    }
2246}
2247function errorHandler(event,files) {
2248    event.preventDefault()
2249    $("#progressBar").attr('style','display: none;')
2250    $("#progressBar")[0].value = 0;
2251    $('#text_content>h4').html('Ошибка загрузки!!!')
2252}
2253function abortHandler(event,files) {
2254    event.preventDefault()
2255    $("#progressBar").attr('style','display: none;')
2256    $("#progressBar")[0].value = 0;
2257    $('#text_content>h4').html('Загрузка прервана!!!')
2258}
2259function ChangeLang(event){
2260    var lang_select = event.target.closest('.lang');
2261    var selector = lang_select.closest('.aipsin_language_dropdown');
2262    var flag = selector.querySelector('label span[lang]');
2263    var f = lang_select.querySelector('span[lang]')
2264    var lang = f.getAttribute('lang')
2265    selector.querySelectorAll('.lang-list .lang').forEach(element => {element.classList.remove('selected');});
2266    lang_select.classList.add('selected');
2267    flag.setAttribute('lang',lang)
2268    selector.classList.remove('open');
2269    setTimeout(() => {
2270        window.location.href = `/localization/lang/change/${lang}`
2271    }, 250);
2272}
2273function AddLoader(element,loaderClass='loader-nb-spiner',fixed=false,show_time=100){
2274    var loader = null
2275    element = $(element)
2276    if(element.find('loader-content').length != 0){
2277        loader = element.find('loader-content')
2278        if(!loader.hasClass('show')){loader.addClass('show')}
2279    } else{
2280        loader = $(`<div class="loader-content ${fixed?'fixed':''}">
2281            <div class="${loaderClass}"></div>
2282        </div>`)
2283        loader.appendTo(element)
2284        if(show_time<=0){
2285            loader.addClass('show');
2286        } else{
2287            setTimeout(function() {
2288                loader.addClass('show');
2289            }, show_time);
2290        }
2291    }
2292    return loader
2293}
2294function RemoveLoaderAfterTimeout(loader,seconds=10){
2295    loader = $(loader)
2296    var seconds = 0
2297    var sumseconds = seconds
2298    var interVal = setInterval(()=>{
2299        seconds++
2300        if(seconds == sumseconds){
2301            RemoveLoader(loader)
2302            clearInterval(interVal)
2303        }
2304    },1000)
2305}
2306function RemoveLoader(element){
2307    element = $(element)
2308    var loader = null
2309    if(element.hasClass('loader-content')){
2310        loader = element
2311    } else {
2312        loader = element.find('.loader-content')
2313    }
2314    loader.removeClass('show')
2315    setTimeout(function() {
2316        loader.remove();
2317    }, 300);
2318}
2319function RemoveParrent(selector=null){
2320    if(selector){
2321        if(typeof selector == 'string'){
2322            selector = event.target.closest(selector)
2323        } else{
2324            selector = selector
2325        }
2326        selector.remove()
2327    } else{
2328        if(event){
2329            event.target.parentElement.remove()
2330        }
2331    }
2332}
2333function RemoveChild(selector=null){
2334    if(selector){
2335        if(typeof selector == 'string'){
2336            selector = event.target.querySelector(selector)
2337        } else{
2338            selector = selector
2339        }
2340        selectore.remove()
2341    }
2342}
2343
2344function ClickBtn(action='click',type=null,...args){
2345    var evnt = null
2346    var btn = null
2347    if(event){
2348        event.preventDefault()
2349        evnt = event
2350        btn = event.target
2351    }
2352    if(type==null){
2353        if(btn){
2354            type = btn.getAttribute('type')
2355        }
2356    } else{
2357        type = type
2358    }
2359    setTimeout(()=>{
2360        if(type=='submit'){
2361            var form = btn.closest('form');
2362            FormSubmit(form,action);
2363        } else if(type=='submit_downoload'){
2364            var form = btn.closest('form');
2365            FormSubmit(form,action,false);
2366        } else if(type=='submit_noloader'){
2367            var form = btn.closest('form');
2368            FormSubmit(form,action,false);
2369        } else if(type=='submit_iframe'){
2370            var form = btn.closest('form')
2371            FormSubmit(form,action);
2372            //window.parent.location.reload()
2373        } else if(type=='download'){
2374            const link = document.createElement('a')
2375            link.setAttribute('href', action)
2376            var filename = action.substring(action.lastIndexOf('/')+1);
2377            link.setAttribute('download', filename)
2378            link.style.display = 'none'
2379            document.body.appendChild(link)
2380            link.click()
2381            document.body.removeChild(link)
2382        } else{
2383            if(action instanceof Function || type=="function"){
2384                action.call(this,...args)
2385            } 
2386            else if((typeof action == 'string' && action != 'click') || type=="redirect"){
2387                LinkRedirect(action,evnt?evnt.ctrlKey:false)
2388            } else{
2389                console.log(action)
2390            }
2391        }
2392    },document.body.hasAttribute('animation_btn_click')?500:0)
2393}
2394function FormSubmit(selector,cmds=null,has_loader=true){
2395    var form = typeof selector == "string"?document.querySelector(selector):selector;
2396    if(selector instanceof Event){
2397        form = selector.target.closest('form');
2398    } else if(form.tagName != 'FORM'){
2399        form = form.closest('form')
2400    }
2401    if(!form){return false;}
2402    cmds = !Array.isArray(cmds)?[cmds]:cmds
2403    var loader = null;
2404    if(has_loader){
2405        loader = AddLoader(form.querySelector('.form_aipsin')?form.querySelector('.form_aipsin'):form);
2406    } 
2407    cmds.forEach(cmd => {
2408        if(isDict(cmd)){
2409            for (const [key, value] of Object.entries(cmd)) {
2410                $("<input />").attr("type", "hidden").attr("name", key).attr("value", value).appendTo($(form));
2411            }
2412        } else{
2413            $("<input />").attr("type", "hidden").attr("name", cmd).attr("value", cmd).appendTo($(form));
2414        }
2415    });
2416    form.dispatchEvent(new Event('submit',{
2417        'bubbles': true
2418    }))
2419    form.submit()
2420    if(has_loader){
2421        RemoveLoaderAfterTimeout(loader,10)
2422    }
2423}
2424function CloseModal(event){
2425    event.target.closest('[modal]').remove();
2426}
2427function OpenDetails(selector){
2428    var details = typeof selector == "string"?document.querySelectorAll(selector):selector;
2429    if(Array.isArray(details) || details instanceof NodeList){
2430        details.forEach(detail => {
2431            detail.open = true;
2432        });
2433    } else{
2434        details.open = true;
2435    }
2436}
2437function VisibilityParrent(event,parrent){
2438    var el = typeof parrent == 'string'?event.target.closest(parrent):parrent
2439    if(el.classList.contains('visible')){
2440        el.classList.remove('visible')
2441        el.classList.add('hidden')
2442    } else{
2443        el.classList.remove('hidden')
2444        el.classList.add('visible')
2445    }
2446}
2447function ToolTipClick(event,action){
2448    var el = event.target
2449    if(typeof action == 'string'){
2450        var text_el = el.getAttribute('aria-label')
2451        navigator.clipboard.writeText(action)
2452        el.setAttribute('aria-label','Скопированно')
2453        setTimeout(()=>{
2454            el.setAttribute('aria-label',text_el)
2455        },500)
2456    } else if(action instanceof Function){
2457        action.call()
2458    } else{
2459        console.log(action)
2460    }
2461}
2462function CheckShowHide(event){
2463    var element = event.target?event.target:event
2464    $('[menu-show-hide]').each((i,el)=>{
2465        el = $(el)
2466        if((el.prev().get(0) != $(element).get(0)) || element.checked == false){
2467            if(el.prev().get(0).checked==true){
2468                el.prev().get(0).checked = false
2469                el.removeClass('open')
2470                el.addClass('close')
2471            }
2472        }
2473    })
2474    if(element.checked){
2475        element.nextElementSibling.classList.remove('close')
2476        element.nextElementSibling.classList.add('open')
2477    } else{
2478        element.nextElementSibling.classList.add('close')
2479        element.nextElementSibling.classList.remove('open')
2480    }
2481}
2482function OpenClose(event){
2483    if(event.target.classList.contains('open')){
2484        event.target.classList.remove('open')
2485        event.target.classList.add('close')
2486    } else{
2487        event.target.classList.remove('close')
2488        event.target.classList.add('open')
2489    }
2490}
2491function OpenCircleMenu(event){
2492    event.preventDefault()
2493    var items = event.target.closest('.circle-menu').querySelectorAll('.circle-menu-items a');
2494    for(var i = 0, l = items.length; i < l; i++) {
2495        items[i].style.left = ((50 - 35*Math.cos(-0.5 * Math.PI - 2*(1/l)*i*Math.PI)).toFixed(4)*3.5) + "%";
2496    
2497        items[i].style.top = ((50 + 35*Math.sin(-0.5 * Math.PI - 2*(1/l)*i*Math.PI)).toFixed(4)*3.5) + "%";
2498    }
2499}
2500function ClickLoadFile(event){
2501    var input = event.target
2502    var form = input.closest('form')
2503    var action = $(input).attr('name')
2504    action = action.replace('_file','')
2505    if (form.querySelector(`input[name=${action}]`)){
2506        form.querySelectorAll(`input[name=${action}]`).forEach(element => {
2507            element.remove()
2508        });
2509    }
2510    if(input.files.length != 0){
2511        $(form).attr("enctype", "multipart/form-data");
2512        $('<input />').attr('type', 'hidden')
2513        .attr('name', action)
2514        .attr('value', action)
2515        .appendTo($(form));
2516        $(form).submit();
2517    }
2518}
2519function LinkRedirect(url='',blank=false){
2520    try {
2521        logo_event('unload')
2522    } catch (error) {
2523        
2524    }
2525    if(event){
2526        event.preventDefault()
2527        if(event.ctrlKey){
2528            blank = true
2529        }
2530    }
2531    if(blank){
2532        window.open(url, "_blank")
2533    } else{
2534        window.location.href = url
2535    }
2536}
2537
2538function html_to_pdf(element,name=null){
2539    html2pdf().from(element).save();
2540    return false
2541    if(!name){
2542        var d = new Date();
2543        name = 'export' + d.getFullYear() + "-" + (d.getMonth()+1) + "-" + d.getDate() + " " +d.getHours() + "_" + d.getMinutes() + "_" + d.getSeconds()+'.'+d.getMilliseconds();
2544    }
2545	var doc = new window.jspdf.jsPDF('l', 'mm', [1200, 1210]);
2546	doc.html(element, {
2547		callback: function(doc) {
2548			doc.save(name+".pdf");
2549		},
2550		x: 10,
2551		y: 10
2552	});
2553}
2554function ControlAipsinInputsShowHidden(event){
2555    event.preventDefault();
2556    var btn=event.target.closest('button');
2557    var lid=btn.querySelectorAll('.lid')[0];
2558    var pupil=btn.querySelectorAll('.pupil')[0];
2559    btn.disabled = true
2560    btn.style.pointerEvents = 'none'
2561    if (lid.classList.contains('lid--open')) {
2562        lid.classList.remove('lid--open');
2563        pupil.classList.remove('pupil--open');
2564        $(btn).nextAll().each((index,el)=>{
2565            $(el).animate({padding: "toggle", margin: "toggle", height: "toggle", opacity: "toggle"});
2566            $(el).hide(250)
2567        })
2568    }
2569    else {
2570        if (lid.classList.contains('lid--close')) {
2571            lid.classList.add('lid--open');
2572            pupil.classList.add('pupil--open');
2573            $(btn).nextAll().each((index,el)=>{
2574                $(el).animate({padding: "toggle", margin: "toggle", height: "toggle", opacity: "toggle"});
2575                $(el).show(250)
2576            })
2577        } else {
2578            lid.classList.add('lid--close');
2579            pupil.classList.add('pupil--close');
2580            $(btn).nextAll().each((index,el)=>{
2581                $(el).animate({padding: "toggle", margin: "toggle", height: "toggle", opacity: "toggle"});
2582                $(el).hide(250)
2583            })
2584        }
2585    }
2586    setTimeout(()=>{
2587        btn.disabled = false
2588        btn.style.pointerEvents = 'all'
2589    },250)
2590}
2591function ToggleIcon(event){
2592    var icon = event.target.closest('[icon-aipsin]') 
2593    var type = icon.getAttribute('icon-aipsin')
2594    if(type == 'eye'){
2595        var lid=icon.querySelectorAll('.lid')[0];
2596        var pupil=icon.querySelectorAll('.pupil')[0];
2597        icon.style.pointerEvents = 'none'
2598        if (lid.classList.contains('lid--open')) {
2599            lid.classList.remove('lid--open');
2600            pupil.classList.remove('pupil--open');
2601        }
2602        else {
2603            if (lid.classList.contains('lid--close')) {
2604                lid.classList.add('lid--open');
2605                pupil.classList.add('pupil--open');
2606            } else {
2607                lid.classList.add('lid--close');
2608                pupil.classList.add('pupil--close');
2609            }
2610        }
2611        setTimeout(()=>{
2612            icon.style.pointerEvents = 'all'
2613        },250)
2614    }
2615}
2616function SelectInputDictRadius(event,name, val){
2617    switch (event.target.value) {
2618        case '1':
2619            event.target.closest('.multi_input_aipsin').querySelector('.multi_input_grid_item_aipsin:nth-child(2)').outerHTML = `
2620            <div class="multi_input_grid_item_aipsin">
2621                <div class="aipsin_field">
2622                <label class="input_aipsin input_aipsin_number" label="Радиус">
2623                    <input id="radius" name="${name}_radius" class="dict_ref_radius" type="number" value="${val}">
2624                    <em>
2625                        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 47.355 47.355" style="enable-background:new 0 0 47.355 47.355;" xml:space="preserve">
2626                            <path d="M29.072,29.996c0.553,0,1-0.448,1-1c0-0.552-0.447-1-1-1h-1.516c-0.553,0-1,
26260.448-1,1c0,0.552,0.447,1,1,1H29.072z">
2627                            </path>
2628                            <path d="M20.217,27.996c-0.553,0-1,0.448-1,1c0,0.552,0.447,1,1,1h4.427c0.553,0,1-0.448,1-1V15.622   c0-0.379-0.214-0.725-0.553-0.895c-0.338-0.169-0.744-0.132-1.047,0.095l-4.427,3.32c-0.442,0.331-0.532,0.958-0.2,1.4   c0.33,0.441,0.957,0.531,1.399,0.2l2.827-2.12v10.374H20.217z">
2629                            </path>
2630                            <path d="M47.337,16.172L44.859,3.29c-0.07-0.363-0.335-0.659-0.689-0.767c-0.352-0.11-0.738-0.013-1,0.249l-4.51,4.511   C29.955-0.681,16.396-0.449,7.973,7.974c-3.998,3.998-6.304,9.309-6.492,14.955c-0.018,0.552,0.413,1.015,0.966,1.033   c0.011,0,0.023,0,0.034,0c0.536,0,0.98-0.426,0.998-0.966c0.173-5.138,2.27-9.971,5.908-13.608c7.882-7.88,20.701-7.878,28.581,0   c0.375,0.375,1.039,0.375,1.414,0l3.868-3.869l1.844,9.581l-9.581-1.843l1.304-1.304c0.391-0.391,0.391-1.023,0-1.414   c-0.391-0.391-1.024-0.391-1.414,0l-2.637,2.637c-0.262,0.262-0.358,0.646-0.249,1c0.108,0.354,0.403,0.619,0.768,0.688   l12.882,2.478c0.325,0.062,0.661-0.04,0.896-0.275C47.296,16.833,47.4,16.497,47.337,16.172z">
2631                            </path>
2632                            <path d="M44.908,23.394c-0.011,0-0.022,0-0.034,0c-0.536,0-0.98,0.426-0.998,0.966c-0.173,5.139-2.271,9.971-5.907,13.608   c-7.881,7.877-20.7,7.879-28.581,0c-0.375-0.375-1.039-0.375-1.414,0l-3.868,3.869l-1.844-9.581l9.581,1.843l-1.304,1.303   c-0.391,0.39-0.391,1.023,0,1.414c0.391,0.391,1.024,0.391,1.414,0l2.637-2.636c0.262-0.262,0.357-0.646,0.249-1   c-0.108-0.354-0.403-0.619-0.767-0.688L1.189,30.013c-0.326-0.063-0.661,0.04-0.896,0.275c-0.234,0.234-0.338,0.57-0.275,0.896   l2.478,12.882c0.07,0.363,0.335,0.659,0.69,0.767c0.352,0.109,0.738,0.012,1-0.249l4.51-4.511   c4.229,3.869,9.605,5.803,14.981,5.803c5.688,0,11.375-2.165,15.705-6.495c3.997-3.997,6.303-9.308,6.491-14.955   C45.892,23.875,45.46,23.412,44.908,23.394z">
2633                            </path>
2634                        </svg>
2635                    </em>
2636                    <p>Радиус</p>
2637                    <div class="toolbar">
2638                        <div class="display_toolbar">
2639                            <i class="clear">
2640                                <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 357 357" style="enable-background:new 0 0 357 357;" xml:space="preserve">
2641                                    <polygon points="357,35.7 321.3,0 178.5,142.8 35.7,0 0,35.7 142.8,178.5 0,321.3 35.7,357 178.5,214.2 321.3,357 357,321.3     214.2,178.5   ">
2642                                    </polygon>
2643                                </svg>
2644                            </i>
2645                        </div>
2646                    </div>
2647                </label>
2648                </div>
2649            </div>`
2650            event.target.closest('.multi_input_grid_item_aipsin').setAttribute('style','')
2651            break;
2652        case '2':
2653            event.target.closest('.multi_input_aipsin').querySelector('.multi_input_grid_item_aipsin:nth-child(2)').outerHTML = `
2654            <div class="multi_input_grid_item_aipsin" style="display:none;">
2655                <div class="aipsin_field">
2656                    <input id="radius" name="${name}_radius" style="visibility: hidden;" type="text" value="1-1">
2657                </div>
2658            </div>`
2659            event.target.closest('.multi_input_grid_item_aipsin').setAttribute('style','grid-column: span 2/auto !important;')
2660            break;
2661        case '3':
2662            event.target.closest('.multi_input_aipsin').querySelector('.multi_input_grid_item_aipsin:nth-child(2)').outerHTML = `
2663            <div class="multi_input_grid_item_aipsin" style="display:none;">
2664                <div class="aipsin_field">
2665                    <input id="radius" name="${name}_radius" style="visibility: hidden;" type="text" value="2-2">
2666                </div>
2667            </div>`
2668            event.target.closest('.multi_input_grid_item_aipsin').setAttribute('style','grid-column: span 2/auto !important;')
2669            break;
2670        default:
2671            event.target.closest('.multi_input_aipsin').querySelector('.multi_input_grid_item_aipsin:nth-child(2)').outerHTML = `
2672            <div class="multi_input_grid_item_aipsin">
2673                <div class="aipsin_field">
2674                <label class="input_aipsin input_aipsin_number" label="Радиус">
2675                    <input id="radius" name="${name}_radius" class="dict_ref_radius" type="number" value="${val}">
2676                    <em>
2677                        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 47.355 47.355" style="enable-background:new 0 0 47.355 47.355;" xml:space="preserve">
2678                            <path d="M29.072,29.996c0.553,0,1-0.448,1-1c0-0.552-0.447-1-1-1h-1.516c-0.553,0-1,
26780.448-1,1c0,0.552,0.447,1,1,1H29.072z">
2679                            </path>
2680                            <path d="M20.217,27.996c-0.553,0-1,0.448-1,1c0,0.552,0.447,1,1,1h4.427c0.553,0,1-0.448,1-1V15.622   c0-0.379-0.214-0.725-0.553-0.895c-0.338-0.169-0.744-0.132-1.047,0.095l-4.427,3.32c-0.442,0.331-0.532,0.958-0.2,1.4   c0.33,0.441,0.957,0.531,1.399,0.2l2.827-2.12v10.374H20.217z">
2681                            </path>
2682                            <path d="M47.337,16.172L44.859,3.29c-0.07-0.363-0.335-0.659-0.689-0.767c-0.352-0.11-0.738-0.013-1,0.249l-4.51,4.511   C29.955-0.681,16.396-0.449,7.973,7.974c-3.998,3.998-6.304,9.309-6.492,14.955c-0.018,0.552,0.413,1.015,0.966,1.033   c0.011,0,0.023,0,0.034,0c0.536,0,0.98-0.426,0.998-0.966c0.173-5.138,2.27-9.971,5.908-13.608c7.882-7.88,20.701-7.878,28.581,0   c0.375,0.375,1.039,0.375,1.414,0l3.868-3.869l1.844,9.581l-9.581-1.843l1.304-1.304c0.391-0.391,0.391-1.023,0-1.414   c-0.391-0.391-1.024-0.391-1.414,0l-2.637,2.637c-0.262,0.262-0.358,0.646-0.249,1c0.108,0.354,0.403,0.619,0.768,0.688   l12.882,2.478c0.325,0.062,0.661-0.04,0.896-0.275C47.296,16.833,47.4,16.497,47.337,16.172z">
2683                            </path>
2684                            <path d="M44.908,23.394c-0.011,0-0.022,0-0.034,0c-0.536,0-0.98,0.426-0.998,0.966c-0.173,5.139-2.271,9.971-5.907,13.608   c-7.881,7.877-20.7,7.879-28.581,0c-0.375-0.375-1.039-0.375-1.414,0l-3.868,3.869l-1.844-9.581l9.581,1.843l-1.304,1.303   c-0.391,0.39-0.391,1.023,0,1.414c0.391,0.391,1.024,0.391,1.414,0l2.637-2.636c0.262-0.262,0.357-0.646,0.249-1   c-0.108-0.354-0.403-0.619-0.767-0.688L1.189,30.013c-0.326-0.063-0.661,0.04-0.896,0.275c-0.234,0.234-0.338,0.57-0.275,0.896   l2.478,12.882c0.07,0.363,0.335,0.659,0.69,0.767c0.352,0.109,0.738,0.012,1-0.249l4.51-4.511   c4.229,3.869,9.605,5.803,14.981,5.803c5.688,0,11.375-2.165,15.705-6.495c3.997-3.997,6.303-9.308,6.491-14.955   C45.892,23.875,45.46,23.412,44.908,23.394z">
2685                            </path>
2686                        </svg>
2687                    </em>
2688                    <p>Радиус</p>
2689                    <div class="toolbar">
2690                        <div class="display_toolbar">
2691                            <i class="clear">
2692                                <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 357 357" style="enable-background:new 0 0 357 357;" xml:space="preserve">
2693                                    <polygon points="357,35.7 321.3,0 178.5,142.8 35.7,0 0,35.7 142.8,178.5 0,321.3 35.7,357 178.5,214.2 321.3,357 357,321.3     214.2,178.5   ">
2694                                    </polygon>
2695                                </svg>
2696                            </i>
2697                        </div>
2698                    </div>
2699                </label>
2700                </div>
2701            </div>`
2702            event.target.closest('.multi_input_grid_item_aipsin').setAttribute('style','')
2703    }
2704}
2705
2706function ServiceOpenHistory(event){
2707    var btn = event.target
2708    var grid_items = btn.nextElementSibling.querySelector('.tab-grid-content')
2709    var menu_show_hide = btn.nextElementSibling
2710
2711
2712
2713    if(menu_show_hide.classList.contains('open')){
2714        menu_show_hide.classList.add('close')
2715        menu_show_hide.classList.remove('open')
2716    }  else{
2717        grid_items.innerHTML = ''
2718        var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
2719                    
2720
2721        GetData('/services/api/search_history/').then((history_list)=>{
2722                    console.log(history_list)
2723        for (let i = 0; i < history_list.length; i++) {
2724            const item = history_list[i];
2725            item.time = new Date(item.time)
2726            grid_items.innerHTML += `
2727            <a class="tab-grid-item" href="${item.url}">
2728                ${item.keyword}
2729                <p>${item.time.toLocaleDateString("ru-RU",{ year: 'numeric', month: 'long', day: 'numeric' })} ${item.time.toLocaleTimeString('ru-RU')}</p>
2730                <p>${item.checker_name}</p>
2731            </a>
2732            `
2733            // var has_url = item.url.indexOf("drugs_checker") != -1||item.url.indexOf("synth_precursors") != -1||item.url.indexOf("synth_products") != -1||item.url.indexOf("customs_checker") != -1||item.url.indexOf("ms_checker") != -1||item.url.indexOf("structure_checker") != -1||item.url.indexOf("derivative_checker") != -1||item.url.indexOf("sim_planner") != -1||item.url.indexOf("literature") != -1||item.url.indexOf("drugs_text") != -1||item.url.indexOf("medications") != -1||item.url.indexOf("ester_finder") != -1||item.url.indexOf("image_finder") != -1||item.url.indexOf("metabolism_finder") != -1
2734            // if(has_url&&!item.url.endsWith('/log/')){
2735            //     item.time = new Date(item.time)
2736            //     grid_items.innerHTML += `
2737            //     <a class="tab-grid-item" href="${item.url}">
2738            //             ${item.name}
2739            //             <p>${item.time.toLocaleDateString("ru-RU",options)} ${item.time.toLocaleTimeString('ru-RU')}</p>
2740            //         </a>
2741            //     `
2742            // }
2743        }
2744        })
2745        menu_show_hide.classList.add('open')
2746        menu_show_hide.classList.remove('close')
2747    }
2748}
2749
2750function OpenListToggleBtn(event){
2751var btn = event.target
2752    var menu_show_hide = btn.nextElementSibling
2753    if(menu_show_hide.classList.contains('open')){
2754        menu_show_hide.classList.add('close')
2755        menu_show_hide.classList.remove('open')
2756    } else{
2757        menu_show_hide.classList.add('open')
2758        menu_show_hide.classList.remove('close')
2759    } 
2760}
2761
2762
2763
2764
2765
2766
2767
2768//-----------------multi-select--and--multi-push-----------
2769
2770
2771$( window ).on( "load", function() {
2772    async function FilterMultiSelect(element){
2773        var value = $(element).find('#multi-select-input').val()
2774        if (value==''){
2775            $(element).find(`#multi-select-list>#multi-select-list-item:not([selected])`).removeClass('hidden')
2776            return false
2777        }
2778        const data = await fetch(`${element.getAttribute('api')}?search=${value}&LIMIT=10`,{
2779            method:'GET',
2780            headers:{
2781                'Accept': 'application/json',
2782                'Content-Type': 'application/json',
2783                "X-Requested-With": "XMLHttpRequest",
2784                'X-CSRFToken':get_csrftoken('csrftoken')
2785            },
2786        }).then(async (res)=>{
2787            if (res.ok){
2788                var data = await res.json()
2789                var dataSelect = []
2790                var notVal = ''
2791                for(const [key, value] of  Object.entries(data)){
2792                    dataSelect.push({text:value,value:key})
2793                    $(element).find(`#multi-select-list>#multi-select-list-item[value="${key}"]`).removeClass('hidden')
2794                    notVal+=`:not([value="${key}"])`
2795                }
2796                $(element).find(`.multi-select-list>.multi-select-list-item${notVal}`).each((i,el)=>el.classList.add('hidden'))
2797                $(element).find(`#multi-select-list>#multi-select-list-item[selected]`).addClass('hidden')
2798                $(element).find('#multi-select-list>#multi-select-list-item.preselect').removeClass("preselect")
2799                GenerateMultiselect($(element),dataSelect)
2800            }
2801        })
2802    }
2803
2804
2805    $('.multi-select').each((i,element)=>{
2806        var select = $(element).find('#multi-select-selector')
2807        select.find(':selected').each((i,el)=>{
2808            AddOptionSelect(element,el.value,el.innerText)
2809        });
2810    })
2811    $(document).click((e)=>{
2812        if(e.target.id=='multi-select'||e.target.id=='multi-select-list'||e.target.id=='multi_select_load_api'){
2813            
2814        } else{
2815            //$('#multi-select-list').css("display", "none").fadeOut(500);
2816        }
2817    })
2818    $(document).on('click', '#multi-select',(e)=>{
2819        if(e.target.id == 'multi-select'){
2820            e.target.querySelector('#multi-select-input').focus()
2821        } else if(e.target.id == 'multi_select_load_api'){
2822            e.target.closest('#multi-select').querySelector('#multi-select-input').focus()
2823        } else if(e.target.id == 'del'){
2824            e.target.closest('#multi-select').querySelector('#multi-select-input').focus()
2825            MultiplyDeselect(e.target.closest('#multi-select'),$(e.target.closest('#item-options')).attr('value'),e.target.closest('#item-options'))
2826        }
2827    })
2828    $(document).on('click', '#multi-select>#multi-select-list #multi-select-list-item', (e)=>{
2829        var multiselect = e.target.closest('#multi-select')
2830        var opt = e.target.id == 'multi-select-list-item'?e.target:e.target.closest('#multi-select-list-item')
2831        MultiplySelect(multiselect,opt.getAttribute('text'),opt.getAttribute('value')) 
2832    })
2833    $(document).on('focusin','#multi-select #multi-select-input',(e)=>{
2834        var multiSelect = e.target.closest('#multi-select')
2835        multiSelect.classList.add('focus')
2836        var value = $(multiSelect).find('#multi-select-input').val()
2837        if (value==''){
2838            $(multiSelect).find(`#multi-select-list>#multi-select-list-item:not([selected])`).removeClass('hidden')
2839        }
2840        //$(e.target.closest('#multi-select')).find('#multi-select-list').fadeOut(500);
2841    })
2842    $(document).on('focusout','#multi-select #multi-select-input',(e)=>{
2843        var multiSelect = e.target.closest('#multi-select')
2844        multiSelect.classList.remove('focus')
2845        //$(e.target.closest('#multi-select')).find('#multi-select-list').css({"display": "flex","top":`${e.target.closest('#multi-select').offsetHeight}px`}).fadeIn(500);
2846    })
2847    var timeOurInput = null
2848    $(document).on('input','#multi-select #multi-select-input',(e)=>{
2849        e.target.nextElementSibling.innerHTML = e.target.value;
2850        if(e.target.value.length != 0){
2851            e.target.style.width = e.target.nextElementSibling.clientWidth + 'px';
2852        } else{
2853            e.target.style.width = '5px';
2854        }
2855        var multiSelectContent = e.target.closest('#multi-select')
2856        if(!multiSelectContent.hasAttribute('api')){
2857            var pattern = new RegExp(e.target.value.toUpperCase())
2858            $(e.target.closest('#multi-select')).find('#multi-select-list>#multi-select-list-item').filter((i,el)=>{
2859                if(!pattern.test(el.innerHTML.toUpperCase())||el.hasAttribute('selected')){
2860                    $(el).addClass('hidden')
2861                } else{
2862                    $(el).removeClass('hidden')
2863                }
2864            })
2865            $(e.target.closest('#multi-select')).find('#multi-select-list>#multi-select-list-item.preselect').removeClass("preselect")
2866        } else{
2867            if(timeOurInput==null){
2868                timeOurInput = setTimeout(() => { FilterMultiSelect(multiSelectContent) }, 1000);
2869            } else{
2870                clearTimeout(timeOurInput)
2871                timeOurInput = setTimeout(() => { FilterMultiSelect(multiSelectContent) }, 1000);
2872            }
2873        }
2874        /*if($(e.target).val().length >=3){
2875            $(e.target.closest('#multi-select')).find('#multi-select-list>#multi-select-list-item').not('.hidden').first().addClass('preselect')
2876            $(e.target.closest('#multi-select')).find('#multi-select-list').css({"display": "flex","top":`${e.target.closest('#multi-select').offsetHeight}px`}).fadeIn(500);
2877        } else{
2878            $(e.target.closest('#multi-select')).find('#multi-select-list').fadeOut(500);
2879        }*/
2880    })
2881    
2882    $(document).on('keydown','#multi-select #multi-select-input',(e)=>{
2883        var key = e.keyCode || e.charCode;
2884        if((key == 8 || key == 46) && e.target.value == ''){
2885            var options = e.target.closest('#multi-select').querySelectorAll("#item-options")
2886            if(options[options.length -1] != undefined){
2887                MultiplyDeselect(e.target.closest('#multi-select'),$(options[options.length -1]).attr('value'),options[options.length -1])
2888            }
2889        } else if(key == 13){
2890            e.preventDefault()
2891            if(e.target.value != ''){
2892                var first_item = $(e.target.closest('#multi-select')).find('#multi-select-list-item:not([selected]).preselect').not('.hidden')
2893                MultiplySelect(e.target.closest('#multi-select'),first_item.attr('text'),first_item.attr('value'),first_item[0])
2894            }
2895        } else if(key == 38){
2896            if ($(e.target.closest('#multi-select')).find('#multi-select-list-item:not([selected]).preselect').not('.hidden').prevAll("#multi-select-list-item:not([selected])").not('.hidden').length > 0) {
2897                var item_sel = $(e.target.closest('#multi-select')).find('#multi-select-list-item:not([selected]).preselect').not('.hidden')
2898                  .removeClass("preselect")
2899                  .prevAll("#multi-select-list-item:not([selected])").not('.hidden').first()
2900                  .addClass("preselect");
2901                  item_sel[0].closest('#multi-select-list').scrollTop = item_sel[0].closest('#multi-select-list').scrollTop-item_sel[0].scrollHeight
2902            }
2903        } else if(key == 40){
2904            if ($(e.target.closest('#multi-select')).find('#multi-select-list-item:not([selected]).preselect').not('.hidden').nextAll("#multi-select-list-item:not([selected])").not('.hidden').length > 0) {
2905                var item_sel = $(e.target.closest('#multi-select')).find('#multi-select-list-item:not([selected]).preselect').not('.hidden')
2906                  .removeClass("preselect")
2907                  .nextAll("#multi-select-list-item:not([selected])").not('.hidden').first()
2908                  .addClass("preselect");
2909                  item_sel[0].closest('#multi-select-list').scrollTop = item_sel[0].closest('#multi-select-list').scrollTop+item_sel[0].scrollHeight
2910              } 
2911        }
2912        e.target.selectionStart = e.target.value.length
2913    });
2914    //-------------------------
2915    window['lastActiveElement'] = null
2916    $(document).on('click', '#multi-push',(e)=>{
2917        if(e.target.id == 'multi-push'){
2918            e.target.querySelector('#multi-push-input').focus()
2919        }  else if(e.target.id == 'del'){
2920            e.target.closest('#multi-push').querySelector('#multi-push-input').focus()
2921            MultiplyDepush(e.target.closest('#multi-push'),$(e.target.closest('#item-options')).attr('value'),e.target.closest('#item-options'))
2922        }
2923    })
2924    $(document).on('click',(e)=>{
2925    if(document.activeElement.id == 'multi-push-input'){
2926        if(window['lastActiveElement']!=null&&(window['lastActiveElement'] != document.activeElement)){
2927            if($(window['lastActiveElement'].closest('#multi-push')).find('select>option').length==0&&$(window['lastActiveElement']).val() == ''){
2928                $(window['lastActiveElement'].closest('#multi-push')).find('#multi-push-placeholder').attr('style','display:flex;')
2929            }
2930        }
2931        window['lastActiveElement'] = document.activeElement
2932        $(document.activeElement.closest('#multi-push')).find('#multi-push-placeholder').attr('style','display:none;')
2933    } else{
2934        if(window['lastActiveElement']!=null&&$(window['lastActiveElement'].closest('#multi-push')).find('select>option').length==0&&$(window['lastActiveElement']).val() == ''){
2935            $(window['lastActiveElement'].closest('#multi-push')).find('#multi-push-placeholder').attr('style','display:flex;')
2936        }
2937    }
2938    })
2939    $(document).on('input','#multi-push>#multi-push-input',(e)=>{
2940        e.target.nextElementSibling.innerHTML = e.target.value;
2941        if(e.target.value.length != 0){
2942            e.target.style.width = e.target.nextElementSibling.clientWidth + 'px';
2943        } else{
2944            e.target.style.width = '5px';
2945        }
2946    })
2947    $(document).on('keydown','#multi-push #multi-push-input',(e)=>{
2948        
2949        var key = e.keyCode || e.charCode;
2950        if((key == 8 || key == 46) && e.target.value == ''){
2951            var options = e.target.closest('#multi-push').querySelectorAll("#item-options")
2952            if(options[options.length -1] != undefined){
2953                MultiplyDepush(e.target.closest('#multi-push'),$(options[options.length -1]).attr('value'),options[options.length -1])
2954            }
2955        } else if(key == 13){
2956            e.preventDefault()
2957            if(e.target.value != ''){
2958                MultiplyPush(e.target.closest('#multi-push'),e.target.value)
2959            }
2960        }
2961        e.target.selectionStart = e.target.value.length
2962    });    
2963});
2964function CreateMultiselect(element,name,label,data){
2965    element = $(element)
2966    $(`
2967        <div class="multi-select multi_select_aipsin" id="multi-select">
2968            <p class="multi_select_aipsin_name">${label}</p>
2969            <input class="multi-select-input" id="multi-select-input"><div class="buffer" id="buffer"></div>
2970            <select class="multi-select-selector" name="${name}" id="multi-select-selector" multiple></select>
2971            <div class="multi-select-list" id="multi-select-list"></div>
2972        </div>
2973    `).appendTo(element)
2974    GenerateMultiselect(element,data)
2975}
2976function GenerateMultiselect(element,data){
2977    var select = $(element).find('#multi-select-selector')
2978    var list = $(element).find('#multi-select-list')
2979    var sel_list=[]; 
2980    select.find('option').each((i,el)=>{
2981        sel_list.push($(el).val());
2982    });
2983    const res = data.filter(({
2984        value
2985    }) => !sel_list.includes(String(value)));
2986    for(item of res){
2987        select.append(`<option class="multi-select-selector-item" value="${item.value}">${item.text}</option>`)
2988        list.append(`
2989            <div class="multi-select-list-item" id="multi-select-list-item" value="${item.value}" text="${item.text}">
2990                <h5 class="multi-select-list-item-title" id="multi-select-list-item-title">${item.text}</h5>
2991            </div>
2992        `)
2993    }
2994}
2995function MultiplyDeselect(multiselector,value,element){
2996    $(multiselector).find('select>option').each((i,el)=>{
2997        if(el.getAttribute('value')==value){
2998            el.selected = false
2999            element.remove()
3000            var item_list = $(multiselector).find(`#multi-select-list-item[value="${value}"]`)[0]
3001            item_list.removeAttribute('selected')
3002            item_list.style.display = 'flex'
3003            //$(multiselector).find('#multi-select-list').css("display", "none").fadeOut(500);
3004        }
3005    })
3006}
3007function MultiplySelect(multiselector,text,value,element=null){
3008    $(multiselector).find(`#multi-select-list-item[value="${value}"]`).removeClass("preselect")
3009    $(multiselector).find('select>option').each((i,el)=>{
3010        if(el.getAttribute('value')==value){
3011            var item_list = $(multiselector).find(`#multi-select-list-item[value="${value}"]`)[0]
3012            if(element){
3013                item_list = element
3014            }
3015            el.selected = true
3016            item_list.style.display = 'none'
3017            item_list.setAttribute('selected','')
3018            var addopt = document.createElement('div')
3019            var h = document.createElement('h5')
3020            var span = document.createElement('span')
3021            span.id = 'del'
3022            addopt.classList = 'item-options'
3023            addopt.id = 'item-options'
3024            h.innerText = item_list.getAttribute('text')
3025            addopt.setAttribute('value',item_list.getAttribute('value'))
3026            addopt.appendChild(h)
3027            addopt.appendChild(span)
3028            multiselector.querySelector('#multi-select-input').insertAdjacentHTML('beforebegin', addopt.outerHTML);
3029            multiselector.querySelector('#multi-select-input').value = ''
3030            multiselector.querySelector('#multi-select-input').focus()
3031            multiselector.querySelector('#buffer').innerText = ''
3032            //$(multiselector).find('#multi-select-list').css("display", "none").fadeOut(500);
3033        }
3034    })
3035}
3036function CreateLoadMoreMultiplySelect(element,loader){
3037    var span = document.createElement('span')
3038    span.id = 'multi_select_load_api'
3039    span.classList = 'multi-select-list-loadmore'
3040    span.innerHTML = 'Общий поиск'
3041    element.querySelector('#multi-select-list').prepend(span)
3042    $(span).on('click',(e)=>{
3043        loader(element)
3044        //$(e.target.closest('#multi-select')).find('#multi-select-list').css({"display": "flex","top":`${e.target.closest('#multi-select').offsetHeight}px`}).fadeIn(500);
3045        e.target.closest('#multi-select').querySelector('#multi-select-input').focus()
3046    })
3047}
3048function AddOptionSelect(multiselector,value,text){
3049    var addopt = document.createElement('div')
3050    var h = document.createElement('h5')
3051    var span = document.createElement('span')
3052    span.id = 'del'
3053    addopt.classList = 'item-options'
3054    addopt.id = 'item-options'
3055    h.innerText = text
3056    addopt.setAttribute('value',value)
3057    addopt.appendChild(h)
3058    addopt.appendChild(span)
3059    multiselector.querySelector('#multi-select-input').insertAdjacentHTML('beforebegin', addopt.outerHTML);
3060    //$(multiselector).find(`#multi-select-list-item[value="${value}"][text="${text}"]`)[0].style.display = 'none'
3061}
3062function GenerateMultipusher(element,data){
3063    var select = $(element).find('#multi-push-pusher')
3064    var sel_list=[]; 
3065    select.find('option').each((i,el)=>{
3066        sel_list.push($(el).val());
3067    });
3068    const res = data.filter(({
3069        value
3070    }) => !sel_list.includes(String(value)));
3071    for(item of res){
3072        select.append(`<option class="multi-push-pusher-item" selected value="${item.value}">${item.text}</option>`)
3073    }
3074}
3075function MultiplyDepush(multipusher,value,element){
3076    $(multipusher).find('select>option').each((i,el)=>{
3077        if(el.getAttribute('value')==value){
3078            el.remove()
3079            element.remove()
3080        }
3081    })
3082    return $(multipusher).find('select>option').length
3083}
3084function MultiplyPush(multipusher,text){
3085    if(text!=''){
3086        var has_item = false
3087        var opts = $(multipusher).find('select>option')
3088        for (let i = 0; i < opts.length; i++) {
3089            const el = opts[i];
3090            if(el.getAttribute('value')==text){
3091                has_item=true
3092                break;
3093            }
3094        }
3095        if(has_item==false){
3096            var addopt = document.createElement('div')
3097            var h = document.createElement('h5')
3098            var span = document.createElement('span')
3099            span.id = 'del'
3100            addopt.classList = 'item-options'
3101            addopt.id = 'item-options'
3102            h.innerText = text
3103            addopt.setAttribute('value',text)
3104            addopt.appendChild(h)
3105            addopt.appendChild(span)
3106            multipusher.querySelector('#multi-push-input').insertAdjacentHTML('beforebegin', addopt.outerHTML);
3107            multipusher.querySelector('#multi-push-input').value = ''
3108            multipusher.querySelector('#multi-push-input').focus()
3109            multipusher.querySelector('#buffer').innerText = ''
3110            $(multipusher).find('select').append(`<option class="multi-push-pusher-item" selected value="${text}">${text}</option>`)
3111        }
3112    }
3113}
3114function AddOptionPush(multipusher,value,text){
3115    var addopt = document.createElement('div')
3116    var h = document.createElement('h5')
3117    var span = document.createElement('span')
3118    span.id = 'del'
3119    addopt.classList = 'item-options'
3120    addopt.id = 'item-options'
3121    h.innerText = text
3122    addopt.setAttribute('value',value)
3123    addopt.appendChild(h)
3124    addopt.appendChild(span)
3125    multipusher.querySelector('#multi-push-input').insertAdjacentHTML('beforebegin', addopt.outerHTML);
3126}
3127
3128class ChildIframe{
3129    constructor(iframe_id){
3130        this.iframe = document.querySelector(`[iframe-id="${iframe_id}"]`)
3131        this.iframe_call = document.querySelector(`[iframe-call="${iframe_id}"]`)
3132        this.value_send = null
3133        this.iframe_event = new window.parent.CustomEvent('iframe_send',{bubbles:true, detail: this.value_send})
3134    }
3135    send(value,close=true){
3136        if(this.iframe_call){
3137            this.value_send = value
3138        }
3139        this.iframe_event = new window.parent.CustomEvent('iframe_send',{bubbles:true, detail: this.value_send})
3140        this.iframe_call.dispatchEvent(this.iframe_event)
3141        this.iframe_call.removeAttribute('iframe-call')
3142        if(close){
3143            this.iframe.closest('[modal]').querySelector('em.close').dispatchEvent(new Event('click',{bubbles:true}))
3144        }
3145    }
3146}
3147
3148
3149class Counter{
3150    constructor(selector, end=null, start=0, time=500){
3151        if(typeof selector == 'string'){
3152            this.selector = document.querySelector(selector)
3153        } else{
3154            this.selector = selector
3155        }
3156        if(end!=null){
3157            this.value = isNumeric(end)?Number(end):0
3158        } else{
3159            this.value = isNumeric(selector.innerHTML)?Number(selector.innerHTML):0
3160        }
3161        this.start = start
3162        this.time = time
3163        this.interval = setInterval(()=>{
3164            if (this.start < this.value) {
3165                this.start++;
3166                this.selector.innerHTML = this.start;
3167            } else {
3168                clearInterval(this.interval)
3169            }
3170        }, this.time/this.value);
3171    }
3172}
3173
3174
3175
3176class MapYandexLayers{
3177    constructor(selector, lat=53.893009, lon=27.567444){
3178        this.selector = selector
3179        // if(typeof selector == 'string'){
3180        //     this.selector = document.querySelector(selector)
3181        // } else{
3182        //     this.selector = selector
3183        // }
3184        this.lat = lat
3185        this.lon = lon
3186        
3187    }
3188    init(){
3189        this.map = ymaps.Map(this.selector, {
3190            center: [this.lat, this.lon],
3191            zoom: 10
3192        });
3193        console.log(this.map)
3194    }
3195    add_placemark(lat, lon){
3196        var placemark = new ymaps.Placemark([Number(lat), Number(lon)], {
3197            balloonContent: 'AAAAAAAAAAAAAAAA'
3198        });
3199        this.map.geoObjects.add(placemark);
3200    }
3201}
3202
3203
3204
3205
3206class MapOpenlayers{
3207    constructor(selector, lat, lon){
3208        this.selector = selector
3209        this.lat = lat
3210        this.lon = lon
3211        this.time_func = 0;
3212        if(!hasScript('/static/openlayers/ol.min.js')){
3213            this.time_func = 1500
3214            loadScript('/static/openlayers/ol.min.js',()=>{
3215                loadStyle('/static/openlayers/ol.min.css');
3216                loadScript('/static/openlayers/selectclusterinteraction.js',()=>{
3217                    loadScript('/static/openlayers/animatedclusterlayer.js',()=>{
3218                        this.init()
3219                    })
3220                })
3221            })
3222        } else{
3223            this.init()
3224        }
3225    }
3226    templatePopup(obj){
3227        return `<table class="ol-popup-table">
3228                    <thead>
3229                        <tr>
3230                            <th>Ключ</th>
3231                            <th>Значение</th>
3232                        </tr>
3233                    </thead>
3234                    <tbody>
3235                        ${Object.keys(obj).map((key)=>`<tr><td>${key}</td><td>${obj[key]}</td></tr>`).join('')}
3236                    </tbody>
3237                </table>`
3238    }
3239    clickMap(lon, lat){
3240
3241    }
3242    init(){
3243        var self = this;
3244        this.layers = [ new ol.layer.Tile({
3245            source: new ol.source.OSM()
3246        })]
3247        this.selector.setAttribute('openlayersmap','openlayersmap')
3248        this.map = new ol.Map({ 
3249            renderer: 'canvas',
3250            target: this.selector,
3251            layers: this.layers, 
3252            view: new ol.View({
3253                center: ol.proj.fromLonLat([this.lon, this.lat]),
3254                zoom: 6
3255            })
3256        });
3257        
3258        this.map.on("singleclick", function(evt){
3259            var latLon = ol.proj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326');
3260            var lat     = latLon[1];
3261            var lon    = latLon[0];
3262        })
3263        var styleCache = {};
3264        function getStyle (feature, resolution){
3265            var size = feature.get('features').length;
3266            var style = styleCache[size];
3267            if (!style) {
3268            var color = size>25 ? "192,0,0" : size>8 ? "255,128,0" : "0,128,0";
3269            var radius = Math.max(8, Math.min(size*0.75, 20));
3270            var dash = 2*Math.PI*radius/6;
3271            var dash = [ 0, dash, dash, dash, dash, dash, dash ];
3272            style = styleCache[size] = new ol.style.Style({
3273            image: new ol.style.Circle({
3274                radius: radius,
3275                stroke: new ol.style.Stroke({
3276                    color: "rgba("+color+",0.5)", 
3277                    width: 15 ,
3278                    lineDash: dash,
3279                    lineCap: "butt"
3280                }),
3281                fill: new ol.style.Fill({
3282                    color:"rgba("+color+",1)"
3283                })
3284            }),
3285            text: new ol.style.Text({
3286                text: size.toString(),
3287                fill: new ol.style.Fill({
3288                    color: '#fff'
3289                })
3290            })
3291            });
3292            }
3293            return style;
3294        }
3295        this.clusterSource=new ol.source.Cluster({
3296            distance: 40,
3297            source: new ol.source.Vector()
3298        });
3299        this.clusterLayer = new ol.layer.AnimatedCluster({
3300            name: 'Cluster',
3301            source: this.clusterSource,
3302            animationDuration:50,
3303            style: getStyle
3304        });
3305        this.map.addLayer(this.clusterLayer);
3306        this.img = new ol.style.Circle({
3307            radius: 5,
3308            stroke: new ol.style.Stroke({
3309            color:getThemeProperty('--theme-color-widget'), 
3310            width:1 
3311        }),
3312            fill: new ol.style.Fill({
3313            color:getThemeProperty('--theme-color-opacity-widget')
3314        })
3315        });
3316        this.style = new ol.style.Style({
3317            image: this.img,
3318            stroke: new ol.style.Stroke({
3319                color:"#fff", 
3320                width:1 
3321            }) 
3322        });
3323        var overlay = this.setOverlay()
3324        var style_point = this.style
3325        this.selectCluster = new ol.interaction.SelectCluster({
3326            pointRadius:7,
3327            animate: true,
3328            featureStyle: function(){
3329                return [ style_point ]
3330            },
3331            style: function(f,res){
3332                var cluster = f.get('features');
3333                if (cluster.length>1){
3334                    var s = [ getStyle(f,res) ];
3335                    if(ol.coordinate.convexHull){
3336                        var coords = [];
3337                        for (i=0; i<cluster.length; i++) coords.push(cluster[i].getGeometry().getFirstCoordinate());
3338                        var chull = ol.coordinate.convexHull(coords);
3339                        s.push ( new ol.style.Style({
3340                        stroke: new ol.style.Stroke({ color: getThemeProperty('--theme-color-widget'), width:2 }),
3341                        fill: new ol.style.Fill({ color: getThemeProperty('--theme-color-opacity-widget') }),
3342                        geometry: new ol.geom.Polygon([chull]),
3343                        zIndex: 1
3344                        }));
3345                    }
3346                    return s;
3347                } else {
3348                return [
3349                new ol.style.Style({
3350                    image: new ol.style.Circle ({
3351                    stroke: new ol.style.Stroke({ color: getThemeProperty('--theme-color-widget'), width:2 }),
3352                    fill: new ol.style.Fill({ color: getThemeProperty('--theme-color-opacity-widget') }),
3353                    radius:5
3354                    })
3355                })];
3356                }
3357            }
3358        });
3359        var then = this
3360        this.map.on("singleclick", function (evt) {
3361            var lon_lat = ol.proj.toLonLat(evt.coordinate).reverse()
3362            then.clickMap(...lon_lat)
3363            this.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
3364                var features = feature.N.features
3365                var coord = `
3366                    <h6>Координаты: ${lon_lat[0].toFixed(9)}, ${lon_lat[1].toFixed(9)}</h6>
3367                `
3368                if(features){
3369                    if(features.length==1){
3370                        var feature = features[0]
3371                        var data = feature.N.data;
3372                        then.setPopup(new ol.proj.fromLonLat([data['Долгота'], data['Широта']]), then.templatePopup(data))
3373                    } else{
3374                        then.setPopup(new ol.proj.fromLonLat([lon_lat[1],lon_lat[0]]), `<div style="max-height:350px; overflow:auto; padding:0px 5px;">${features.map((feature)=>then.templatePopup(feature.N.data)).join('')}</div>`)
3375                    }
3376                }
3377            });
3378        });
3379        this.map.addInteraction(this.selectCluster);
3380        var vector = new ol.layer.Vector({ source: new ol.source.Vector() })
3381        vector.setMap(this.map);
3382    }
3383    setPopup(coordinate, html){
3384        this.popup.innerHTML = ''
3385        if(typeof html == 'string'){
3386            this.popup.innerHTML = html;
3387        } else if(Array.isArray(html)||html instanceof Object){
3388            for (let i = 0; i < html.length; i++) {
3389                const h = html[i];
3390                this.popup.append(h);
3391            }
3392        } else{
3393            this.popup.append(html);
3394        }
3395        var popup = this.selector.querySelector('.ol-popup')
3396        if($(popup).is(":visible")){
3397            $(popup).hide(250,()=>{
3398                this.overlay.setPosition(coordinate);
3399                $(popup).show(250)
3400            })
3401        } else{
3402            this.overlay.setPosition(coordinate);
3403            $(popup).show(250)
3404        }
3405    }
3406    setOverlay(){
3407        var popup = this.selector.querySelector('.ol-popup')
3408        
3409        if(!popup){
3410            var content = document.createElement('div')
3411            content.classList = 'ol-popup-content'
3412            var closer = document.createElement('div')
3413            closer.classList = 'ol-popup-closer'
3414            popup = document.createElement('div')
3415            popup.style.display = 'none';
3416            popup.classList = 'ol-popup'
3417            popup.append(content)
3418            popup.append(closer)
3419            this.selector.append(popup)
3420        } else{
3421            var content = this.selector.querySelector('.popup-content');
3422            var closer = this.selector.querySelector('.popup-closer');
3423        }
3424        
3425        this.overlay = new ol.Overlay({
3426            element: popup,
3427            autoPan: true,
3428            autoPanAnimation: {
3429                duration: 250
3430            }
3431        });
3432        this.popup = content;
3433        
3434        var overlay = this.overlay
3435        this.map.addOverlay(this.overlay);
3436        closer.onclick = function () {
3437            //overlay.setPosition(undefined);
3438            $(popup).hide(250)
3439            //closer.blur();
3440            return false;
3441        };
3442        /*this.map.on('singleclick', function (evt) {
3443            console.log(evt)
3444            const coordinate = evt.coordinate;
3445            content.innerHTML = '<p>Координаты:</p><code>' + String(coordinate) + '</code>';
3446            overlay.setPosition(coordinate);
3447        });*/
3448        return this.overlay
3449    }
3450    addFeatures(dataList){
3451        setTimeout(()=>{
3452            this.time_func = 0
3453            var features=[];
3454            for (var i=0; i<dataList.length; i++){
3455                var lat_lon = dataList[i];
3456                var el = this.setCoord(lat_lon)
3457                if(!el['Широта']||!el['Долгота']){
3458                    continue
3459                }
3460                var l = features.length
3461                features[l]=new ol.Feature(new ol.geom.Point(new ol.proj.fromLonLat([el['Долгота'], el['Широта']])));
3462                features[l].set('data',{...el});
3463            }
3464            if(features.length != 0){
3465                this.clusterSource.getSource().addFeatures(features);
3466            }
3467            return this
3468        },this.time_func)
3469    }
3470    clearFeatures(){
3471        this.clusterSource.getSource().clear();
3472    }
3473    setCoord(el){
3474        var lat = null
3475        var lon = null
3476        if(el.lon&&el.lat){
3477            lat = el.lat
3478            lon = el.lon
3479            delete el.lat
3480            delete el.lon
3481        } else if(el.lattitude&&el.longitude){
3482            lat = el.lattitude
3483            lon = el.longitude
3484            delete el.lattitude
3485            delete el.longitude
3486        } else if(el.latitude&&el.longitude){
3487            lat = el.latitude
3488            lon = el.longitude
3489            delete el.latitude
3490            delete el.longitude
3491        } else if(el.centr_lattitude&&el.centr_longitude){
3492            lat = el.centr_lattitude
3493            lon = el.centr_longitude
3494            delete el.centr_lattitude
3495            delete el.centr_longitude
3496        } else if(el.coord && typeof el.coord == 'string'){
3497            try {
3498                var s = el.coord.split(',');
3499                if(s.length==2){
3500                    lon = Number(s[1].replace(' ',''))
3501                    lat = Number(s[0].replace(' ',''))
3502                }
3503            } catch (error) {
3504                return el
3505            }
3506        }
3507        el['Долгота'] = lon
3508        el['Широта'] = lat
3509        return el;
3510    }
3511}
3512
3513
3514
3515class AipsinTodoListSearch{
3516    constructor(selector){
3517        this.count_data_send = 0
3518        if(typeof selector == 'string'){
3519            this.filter = document.querySelector(selector)
3520        } else{
3521            this.filter = selector
3522        }
3523        this.multiselect = this.filter.nextElementSibling
3524        this.fields = this.filter.querySelectorAll(this.filter.getAttribute('fields_selector'))
3525        this.recordlist = this.filter.nextElementSibling.nextElementSibling
3526        this.load_more = this.recordlist.querySelector('[load_more]')
3527        this.btn_filter = this.recordlist.querySelector('[btn_filter]')
3528        this.btn_select_all = this.recordlist.querySelector('[btn_select_all]')
3529        this.btn_load_all = this.recordlist.querySelector('[btn_load_all]')
3530        this.recordlist_ul = this.recordlist.querySelector('[recordlist_ul]')
3531        this.filter_text = this.recordlist.querySelector('.header_todo_recordlist [filter]')
3532        this.count_text = this.recordlist.querySelector('.header_todo_recordlist [count]')
3533        this.record = {
3534            '_api':this.filter.getAttribute('api'),
3535            '_filter':0,
3536            '_count':0,
3537            '_offset':0,
3538            '_limit':25,
3539            dataForm:new FormData(),
3540            '_data':{},
3541            'selected':[]
3542        }
3543        this.record.__defineGetter__('api',()=>this.record._api);
3544        this.record.__defineGetter__('filter',()=>this.record._filter);
3545        this.record.__defineGetter__('count',()=>this.record._count);
3546        this.record.__defineGetter__('offset',()=>this.record._offset);
3547        this.record.__defineGetter__('limit',()=>this.record._limit);
3548        this.record.__defineGetter__('data',()=>this.record._data);
3549        var then = this
3550        this.record.__defineSetter__('api', function (value) {
3551            then.record._api = value;
3552        });
3553        this.record.__defineSetter__('filter', function (value) {
3554            then.record._filter = value;
3555            if(then.record.filter>=then.record.count){
3556                then.load_more.style.display = 'none';
3557            } else{
3558                then.load_more.style.display = 'block';
3559            }
3560            then.filter_text.innerHTML = value;
3561        });
3562        this.record.__defineSetter__('count', function (value) {
3563            then.record._count = value;
3564            if(then.record.filter>=then.record.count){
3565                then.load_more.style.display = 'none';
3566            } else{
3567                then.load_more.style.display = 'block';
3568            }
3569            then.count_text.innerHTML = value;
3570        });
3571        this.record.__defineSetter__('offset', function (value) {
3572            then.record._offset = value;
3573        });
3574        this.record.__defineSetter__('limit', function (value) {
3575            then.record._limit = value;
3576        });
3577        this.record.__defineSetter__('data', function (value) {
3578            then.record._data = value;
3579            if(Array.isArray(then.record.data)&&then.count_data_send!=0){
3580                if(then.record.data.length){
3581                    TOAST.AddToasts({
3582                        text:`Данные отсуствуют!`,
3583                        type:`warning`,
3584                    });TOAST.ShowToasts()
3585                }
3586            } else if(isDict(then.record.data)){
3587                if(Object.keys(then.record.data).length === 0&&then.count_data_send!=0){
3588                    TOAST.AddToast({
3589                        text:`Данные отсуствуют!`,
3590                        type:`warning`,
3591                    });TOAST.ShowToasts()
3592                }
3593            }
3594            then.count_data_send+=1
3595            for (const [key, val] of Object.entries(then.record.data)) {
3596                var opt = then.multiselect.querySelector(`option[value="${key}"]`)
3597                var is_selected = false
3598                if(!opt){
3599                    opt = document.createElement('option')
3600                    opt.value = key
3601                    opt.innerHTML = val
3602                    then.multiselect.append(opt)
3603                }
3604                is_selected = opt.selected
3605                $(then.recordlist_ul).append($(
3606                    `
3607                    <label style="cursor: pointer;" class="recordlist_ul_li">
3608                        <div class="status">
3609                            <label class="checkbox_aipsin" style="flex-direction:unset;width:unset;padding:0px;">
3610                                
3611                                <em></em>
3612                            </label>
3613                            <div class="info_text_connect">
3614                                <h4>${val}</h4>
3615                            </div>
3616                        </div>
3617                    </label>
3618                `
3619                ))
3620                var li = then.recordlist_ul.querySelector('label.recordlist_ul_li:last-child')
3621                var input = document.createElement('input')
3622                input.name = `check_${then.multiselect.name}`
3623                input.value = `${key}`
3624                input.type = `checkbox`
3625                input.setAttribute('selected','selected')
3626                if(is_selected){
3627                    input.setAttribute('checked','checked')
3628                }
3629                input.setAttribute('style','flex-direction:unset;width:unset;padding:0px;')
3630                input.addEventListener('change',(event)=>{
3631                    if(event.target.checked){
3632                        then.choices.setChoiceByValue(event.target.value)
3633                    } else{
3634                        then.choices.removeActiveItemsByValue(event.target.value)
3635                    }
3636                })
3637                li.querySelector('label.checkbox_aipsin').prepend(input)
3638            }
3639            var listOptions = []
3640            then.multiselect.querySelectorAll(`option`).forEach(element => {
3641                if(then.choices._currentState){
3642                    if(!then.choices._currentState.choices.find((item)=>item.value==element.value)){
3643                        listOptions[listOptions.length] = {'value':element.value,'label':element.text,'selected':element.selected}
3644                    }
3645                }
3646            });
3647            if(listOptions.length>0){
3648                then.choices.setChoices(
3649                listOptions,
3650                'value',
3651                'label',
3652                false,
3653            );
3654            }
3655        });
3656        this.load_more.addEventListener('click',(event)=>{
3657            event.preventDefault();
3658            then.record.offset+=1
3659            then.loadData()
3660        })
3661        this.btn_filter.addEventListener('click',(event)=>{
3662            event.preventDefault();
3663            then.record.offset=0
3664            then.recordlist_ul.innerHTML = ''
3665            then.loadData()
3666        })
3667        this.btn_select_all.addEventListener('click',(event)=>{
3668            event.preventDefault();
3669            then.recordlist_ul.querySelectorAll('input[type="checkbox"]').forEach(element => {
3670                element.checked = true
3671                element.dispatchEvent(new Event('change',{bubbles:true}))
3672            });
3673        })
3674        this.btn_load_all.addEventListener('click',(event)=>{
3675            event.preventDefault();
3676            then.recordlist_ul.innerHTML = ''
3677            then.record.offset=0
3678            then.record.limit=1000000000000000
3679            then.loadData()
3680            then.record.limit = 25
3681        })
3682        this.multiselect.addEventListener('addItem', (event) => {
3683            var opt = then.recordlist_ul.querySelector(`input[value="${event.detail.value}"]`)
3684            if(opt){
3685                opt.checked = true
3686            }
3687            // console.log(event.detail.id);
3688            // console.log(event.detail.value);
3689            // console.log(event.detail.label);
3690            // console.log(event.detail.customProperties);
3691            // console.log(event.detail.groupValue);
3692        },false);
3693        this.multiselect.addEventListener('removeItem', (event) => {
3694            var opt = then.recordlist_ul.querySelector(`input[value="${event.detail.value}"]`)
3695            if(opt){
3696                opt.checked = false
3697            }
3698            // console.log(event.detail.id);
3699            // console.log(event.detail.value);
3700            // console.log(event.detail.label);
3701            // console.log(event.detail.customProperties);
3702            // console.log(event.detail.groupValue);
3703        },false);
3704        var listOptions = []
3705        for (const name of this.multiselect.getAttributeNames()) {
3706            if(name.startsWith('values-')){
3707                listOptions.push(this.multiselect.getAttribute(name));
3708            }
3709        }
3710        this.setChoices(listOptions).then((data)=>{
3711            if(loadScript('/static/choices/choices.min.js')){
3712                setTimeout(()=>{
3713                    for (const [key, val] of Object.entries(data)){
3714                        var opt = document.createElement('option')
3715                        opt.value = key
3716                        opt.innerHTML = val
3717                        opt.selected = true
3718                        then.multiselect.append(opt)
3719                    }
3720                    then.choices = new Choices(then.multiselect, { 
3721                        allowSearch: true,
3722                        removeItemButton: true,
3723                        noChoicesText: 'Ничего не выбрано',
3724                        noResultsText: 'Результаты не найдены',
3725                        itemSelectText: 'Нажмите чтобы выбрать',
3726                        customAddItemText: 'Можно добавлять только значения, соответствующие определенным условиям',
3727                        uniqueItemText: 'Можно добалвять только уникальные значения'
3728                    })
3729                    then.loadData()
3730                },1500)
3731            }
3732        })
3733    }
3734    async setChoices(values){
3735        if(values.length>0){
3736            var url = new URL(window.location.origin+this.record.api)
3737            var fData = new FormData()
3738            values.forEach(v => {
3739                fData.append("IN_url_key_name",v)
3740            });
3741            url.search = url.search?url.search+'&':url.search
3742            url.search+=new URLSearchParams(fData).toString()
3743            return await GetData(url.toString())
3744        }
3745        return await {}
3746    }
3747    async loadData(){
3748        this.fields.forEach((element) => {
3749            if(element.value){
3750                this.record.dataForm.set(element.getAttribute('name'),element.value)
3751            } else{
3752                this.record.dataForm.delete(element.getAttribute('name'))
3753            }
3754        });
3755
3756
3757        var url = new URL(window.location.origin+this.record.api)
3758        GetData(url.toString().replace('choices','count')).then((data)=>this.record.count=data.count)
3759
3760
3761        url = new URL(window.location.origin+this.record.api)
3762        this.record.dataForm.set('LIMIT',(this.record.offset+1)*this.record.limit)
3763        this.record.dataForm.delete('OFFSET')
3764        url.search = url.search?url.search+'&':url.search
3765        url.search+=new URLSearchParams(this.record.dataForm).toString()
3766        GetData(url.toString().replace('choices','count')).then((data)=>this.record.filter=data.count)
3767
3768
3769        url = new URL(window.location.origin+this.record.api)
3770        this.record.dataForm.set('LIMIT',this.record.limit)
3771        this.record.dataForm.set('OFFSET',this.record.offset*this.record.limit)
3772        url.search = url.search?url.search+'&':url.search
3773        url.search+=new URLSearchParams(this.record.dataForm).toString()
3774        this.record.data = await GetData(url.toString())
3775    }
3776}
3777
3778
3779class AipsinPDF{
3780    constructor(selector){
3781        var container = typeof selector == "string"?document.querySelector(selector):selector;
3782        this.container = container
3783        this.container.innerHTML = `
3784            <div header_aipsin_pdf>
3785                <button class="prev button_main btn_icon">
3786                    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 307.046 307.046" style="enable-background:new 0 0 307.046 307.046;transform: rotate(180deg);" xml:space="preserve">
3787                        <path d="M239.087,142.427L101.259,4.597c-6.133-6.129-16.073-6.129-22.203,0L67.955,15.698c-6.129,6.133-6.129,16.076,0,22.201     l115.621,115.626L67.955,269.135c-6.129,6.136-6.129,16.086,0,22.209l11.101,
378711.101c6.13,6.136,16.07,6.136,22.203,0     l137.828-137.831C245.222,158.487,245.222,148.556,239.087,142.427z"/>
3788                    </svg>
3789                </button>
3790                <button class="next button_main btn_icon">
3791                    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 307.046 307.046" style="enable-background:new 0 0 307.046 307.046;" xml:space="preserve">
3792                        <path d="M239.087,142.427L101.259,4.597c-6.133-6.129-16.073-6.129-22.203,0L67.955,15.698c-6.129,6.133-6.129,16.076,0,22.201     l115.621,115.626L67.955,269.135c-6.129,6.136-6.129,16.086,0,22.209l11.101,11.101c6.13,6.136,16.07,6.136,22.203,0     l137.828-137.831C245.222,158.487,245.222,148.556,239.087,142.427z"/>
3793                    </svg>
3794                </button>
3795                &nbsp; &nbsp;
3796                <span>Страница: <span class="page_num"></span> / <span class="page_count"></span></span>
3797            </div>
3798            <canvas id="pdf-canvas"></canvas>
3799        `
3800        this.pdfDoc = null,
3801        this.pageNum = 1,
3802        this.pageRendering = false,
3803        this.pageNumPending = null,
3804        this.scale = 0.8,
3805        this.canvas = this.container.querySelector('#pdf-canvas'),
3806        this.ctx = this.canvas.getContext('2d');
3807        this.url = this.container.getAttribute('aipsin_pdf')
3808        var then = this
3809        pdfjsLib.getDocument(then.url).promise.then(function(pdfDoc_) {
3810            then.pdfDoc = pdfDoc_;
3811            then.canvas.closest('[aipsin_pdf]').querySelector('.page_count').textContent = then.pdfDoc.numPages;
3812            then.renderPage(then.pageNum);
3813        });
3814    }
3815    renderPage(num) {
3816        var then = this
3817        then.pageRendering = true;
3818        then.pdfDoc.getPage(num).then(function(page) {
3819            var viewport = page.getViewport({scale: then.scale});
3820            then.canvas.height = viewport.height;
3821            then.canvas.width = viewport.width;
3822            var renderContext = {
3823            canvasContext: then.ctx,
3824            viewport: viewport
3825            };
3826            var renderTask = page.render(renderContext);
3827            renderTask.promise.then(function() {
3828                then.pageRendering = false;
3829            if (then.pageNumPending !== null) {
3830                renderPage(then.pageNumPending);
3831                then.pageNumPending = null;
3832            }
3833            });
3834        });
3835        then.canvas.closest('[aipsin_pdf]').querySelector('.page_num').textContent = num;
3836        then.canvas.closest('[aipsin_pdf]').querySelector('.prev').addEventListener('click', then.onPrevPage);
3837        then.canvas.closest('[aipsin_pdf]').querySelector('.next').addEventListener('click', then.onNextPage);
3838
3839    }
3840    queueRenderPage(num) {
3841        if (this.pageRendering) {
3842            this.pageNumPending = num;
3843        } else {
3844            this.renderPage(num);
3845        }
3846    }
3847    onPrevPage() {
3848        if (this.pageNum <= 1) {
3849            return;
3850        }
3851        this.pageNum--;
3852        this.queueRenderPage(this.pageNum);
3853    }
3854    onNextPage() {
3855        if (this.pageNum >= this.pdfDoc.numPages) {
3856            return;
3857        }
3858        this.pageNum++;
3859        this.queueRenderPage(this.pageNum);
3860    }
3861}

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.