/* процедурник Дима */ /*------------ вертикальный мувер --------- */ $('.mov-v').on("movestart",null,function(e){ $(this).css('border','dashed 1px red'); let lencolumns = $(this).parent().css('grid-template-columns').split(' '); // длины всех столбцов grid $(this).data("pozvert",lencolumns[0]); // длинна первого столбца в px в момент moverStart }); $('.mov-v').on("move",null,function(e){ let offsetX = Number($(this).data("pozvert").replace('px','')); let pozX = offsetX + e.distX; let css = pozX+'px 10px minmax(250px,2fr) 100px'; // меняем длинну первого столбца, остальные grid расчитывает сам $(this).parent().css('grid-template-columns',css); $(this).css('border','dashed 1px red'); e.stopPropagation(); // отменяем дальнейшее всплытие события, что бы не вызывался click на тач-устройствах e.preventDefault(); // ибо нех. $('#show-side-navigation1').css('width',pozX); // переставляем правы край меню if (pozX > 0) { $('#show-side-navigation1').data('side-hide', false ); } }); $('.mov-v').on("moveend",null,function(e){ $(this).css('border','solid 1px #d0d0d0'); }); function empty( v ) { // функция empty() - это самоструг НЕ ПУТАТЬ с jquery $('xxx').empty(), которая прикручена к объекту который она очищает, // а эта empty(value) проверяет не пустое ли значение return ( v===undefined || v==='' || v===0 || v==='0' || v===null || v===false || (Array.isArray(v) && v.length == 0)); } function formatDate(date) { return ''+date.getFullYear()+'-'+(''+(date.getMonth()+1)).padStart(2,'0')+'-'+(''+date.getDate()).padStart(2,'0'); } function formatDateTime(date) { return ''+date.getFullYear()+'-'+(''+(date.getMonth()+1)).padStart(2,'0')+'-'+(''+date.getDate()).padStart(2,'0')+ 'T'+(''+date.getHours()).padStart(2,'0')+':'+(''+date.getMinutes()).padStart(2,'0'); } function get_time() // возвращает число UNIXTIME { let d = new Date(); return d.getTime(); } function daysInMonth( d ) // d-дата в формате js, возвращает длинну месяца в днях { return 33 - new Date(d.getFullYear(), d.getMonth(), 33).getDate(); } function wait( sel , message, timeout , top, left , height, width, fontsize, bcolor , fcolor, border, blink ) // message - текст // timeout - время показа (необязательный параметр) если пусто , то убирается по wait_close() // top, left , width, height - координаты окна (можно с %) (необязательный параметр) если пусто, то центруется // bcolor - цвет фона (необязательный параметр) // fcolor - цвет текста (необязательный параметр) // border - параметры рамки (необязательный параметр) строка передается как есть в CSS // blink - мигание рамки (необязательный параметр) // wait( sel , 'блабла!', 5000 , 100,100, 50, 150, 15, '#000000' , '#ff0000', 'solid 1px #d0d0d0', 0 ) { if (empty(sel)) sel='#wait'; if ( ! $("div").is(sel) ) { $("body").append('
' ); $(sel).css('position','absolute'); $(sel).css('text-align','center'); $(sel).css('z-index',9999999); } if (! empty(top)) { $(sel).css('top',top); } if (! empty(left)) { $(sel).css('left',left); } if (! empty(width)) { $(sel).css('width',width); } if (! empty(height)) { $(sel).css('height',height); } if (! empty(fontsize)) { $(sel).css('font-size',fontsize); } if (! empty(fcolor)) { $(sel).css('color',fcolor); } if (! empty(bcolor)) { $(sel).css('background-color',bcolor); } if (! empty(border)) { $(sel).css('border',border); } $(sel).html(message); $(sel).css('display','block'); if (! empty(timeout)) { window.wait_mess = setTimeout(function(){ wait_close(sel); },timeout); } if (! empty(blink)) { window.wait_mess_blink = setInterval(function(){ if ($(sel).attr('wait')==1) { // читаем флаг $(sel).css('display','block'); $(sel).attr('wait','0') // меняем флаг } else { $(sel).css('display','none'); $(sel).attr('wait','1') // меняем флаг } }, blink); } } function wait_close(sel) { $(sel).css('display','none'); $(sel).remove(); clearInterval(window.wait_mess_blink); clearTimeout(window.wait_mess); } function copyToClipboard(s) { var $temp = $(""); $("body").append($temp); $temp.val(s).select(); document.execCommand("copy"); $temp.remove(); } function messbox( text , type , title , after , width , height ) { let uniq_win_id = rndString(10); // практически случайная строка let content = "
"+text+"
"; var id_cmd_ok = rndString(10); var id_cmd_cancel = rndString(10); switch (type) { case 1: content += '
Да
'; break; case 2: content += '
Да
Нет
'; break; } if (empty(width)) { width = '200px'; } if (empty(height)) { height = '150px'; } defi_window( uniq_win_id , title , '30%', '30%', width , height , content ,"div" , 0, function(){ $('#'+id_cmd_ok).on('click',function(){ $('body #'+uniq_win_id).remove(); after(); }); $('#'+id_cmd_cancel).on("click", function(){ $('body #'+uniq_win_id).remove(); }); }); } function defi_window( uniq_win_id , window_title , left, top, width , height, content , class_content , resize, my_func , on_close ) { if (empty(uniq_win_id)) { var uniq_win_id = 'win'+Date.now(); } let win_content ='
'+ '
'+ '
'+ '
'+window_title+'
'+ '
'+ '
'+ '
'+ '
'; if ($('div').is('#'+uniq_win_id)) { $('body').remove('#'+uniq_win_id); } $('body').append(win_content).ready( function(){ $('#'+uniq_win_id+' .header-win .close-win').click( function(){ // закрыть крестиком $('body #'+uniq_win_id).remove(); if (typeof(on_close) == 'function') { on_close(); } }); $('#'+uniq_win_id+' .'+class_content).append(content).ready( function() { $('#'+uniq_win_id).css('left', left); $('#'+uniq_win_id).css('top', top ); $('#'+uniq_win_id).css('width', width); $('#'+uniq_win_id).css('height', height); //$(this).css('height','350px'); if (resize) { $('#'+uniq_win_id).css('resize','none'); // убираем стандартный мовер-уголок $('#'+uniq_win_id+' .mover-win').css('display', 'inline-block'); // создаем свой $('#'+uniq_win_id+' .mover-win').css('top', Number(height.replace('px',''))- 18 +'px' ); $('#'+uniq_win_id+' .mover-win').css('left', Number(width.replace('px','')) - 18 +'px' ); $('#'+uniq_win_id).css('border-bottom-right-radius',0); // убираем закругление нижнего правого уголка окна // изменение размеров окна с зацепом за уголок $('#'+uniq_win_id+' .mover-win').on("movestart",null,function(e){ // старт resize window $(this).parent().css('border','dashed 1px red'); $('#'+uniq_win_id).data("offsetX",Number($('#'+uniq_win_id).css('left').replace('px',''))); // положение верхнего угла окна на момент зацепа $('#'+uniq_win_id).data("offsetY",Number($('#'+uniq_win_id).css('top').replace('px',''))); // относительно главного окна }); $('#'+uniq_win_id+' .mover-win').on("move",null,function(e){ // resize window let offset_x = $('#'+uniq_win_id).data("offsetX"); let offset_y = $('#'+uniq_win_id).data("offsetY"); let pozX = e.startX + e.distX - offset_x; let pozY = e.startY + e.distY - offset_y; $('#'+uniq_win_id).css('height', pozY ); // изменение размера всего окна $('#'+uniq_win_id).css('width', pozX ); let hheader = $('#'+uniq_win_id+' .header-win').css('height').replace('px',''); // высота заголовка $('#'+uniq_win_id+' .'+class_content).css('height',(pozY-hheader)+'px'); // изменение высоты контента $(this).parent().css('border','dashed 2px red'); // тащим заголовок окна а метим все окно e.stopPropagation(); // отменяем дальнейшее всплытие события, что бы не вызывался click на тач-устройствах e.preventDefault(); // ибо нех. $('#'+uniq_win_id+' .mover-win').css('top',(pozY-18)+'px'); // уголок перемещаем по размеру окна $('#'+uniq_win_id+' .mover-win').css('left',(pozX-18)+'px'); }); $('#'+uniq_win_id+' .mover-win').on("moveend",null,function(e){ // окончание resize window $(this).parent().css('border','solid 1px #FF8080'); // снимаем пометку окна которое resize-ли }); } // перетскивание окна с зацепом за заголовок $('#'+uniq_win_id+' .header-win .title-win').on("movestart",null,function(e){ // старт move window $(this).parent().parent().css('border','dashed 1px red'); let offset_x = e.startX - Number( $('#'+uniq_win_id).css('left').replace('px','')); let offset_y = e.startY - Number( $('#'+uniq_win_id).css('top').replace('px','')); $('#'+uniq_win_id).data("offsetX",offset_x); $('#'+uniq_win_id).data("offsetY",offset_y); }); $('#'+uniq_win_id+' .header-win .title-win').on("move",null,function(e){ // move window let pozX = e.startX + e.distX; let pozY = e.startY + e.distY; let offset_x = $('#'+uniq_win_id).data("offsetX"); let offset_y = $('#'+uniq_win_id).data("offsetY"); $('#'+uniq_win_id).css('top',pozY - offset_y ); $('#'+uniq_win_id).css('left',pozX - offset_x ); $(this).parent().parent().css('border','dashed 2px red'); // тащим заголовок окна а метим все окно e.stopPropagation(); // отменяем дальнейшее всплытие события, что бы не вызывался click на тач-устройствах e.preventDefault(); // ибо нех. }); $('#'+uniq_win_id+' .header-win .title-win').on("moveend",null,function(e){ // окончание move window $(this).parent().parent().css('border','solid 1px #FF8080'); // снимаем пометку окна которое таскали }); // двойной клик по заголовку расширяет окно до максимальных размеров, либо вспоминает прежнее положение // которое запоминает при предыдущем расширении до максимума $('#'+uniq_win_id+' .header-win .title-win').dblclick(function(e){ if ( $('#'+uniq_win_id).data('win_maximized')) { // читаем координаты окна из атрибутов data (схраненных при прошлом dblclick) $('#'+uniq_win_id).css('left', $('#'+uniq_win_id).data('win_left')); $('#'+uniq_win_id).css('top', $('#'+uniq_win_id).data('win_top')); $('#'+uniq_win_id).css('width', $('#'+uniq_win_id).data('win_width')); $('#'+uniq_win_id).css('height', $('#'+uniq_win_id).data('win_height')); // переставляем статус максимизации $('#'+uniq_win_id).data('win_maximized',false); } else { // запоминаем координаты окна в атрибуты data $('#'+uniq_win_id).data('win_left',$('#'+uniq_win_id).css('left') ); $('#'+uniq_win_id).data('win_top',$('#'+uniq_win_id).css('top')); $('#'+uniq_win_id).data('win_width',$('#'+uniq_win_id).css('width') ); $('#'+uniq_win_id).data('win_height',$('#'+uniq_win_id).css('height')) // максимизируем окно на весь экран $('#'+uniq_win_id).css('top','0px'); $('#'+uniq_win_id).css('left','0px'); $('#'+uniq_win_id).css('width',$(window).width()); $('#'+uniq_win_id).css('height',$(window).height()); // переставляем статус максимизации $('#'+uniq_win_id).data('win_maximized',true); } if (resize) { // если окно с resize , не забываем уголок поставить на место pozX = $('#'+uniq_win_id).css('width').replace('px',''); pozY = $('#'+uniq_win_id).css('height').replace('px',''); $('#'+uniq_win_id+' .mover-win').css('top',(pozY-18)+'px'); // уголок перемещаем по размеру окна $('#'+uniq_win_id+' .mover-win').css('left',(pozX-18)+'px'); } }); my_func(); // выполняем действия после создания окна let hheader = $('#'+uniq_win_id+' .header-win').css('height').replace('px',''); $('#'+uniq_win_id+' .'+class_content).css('height',(Number(height.replace('px',''))-hheader)+'px'); }); $('#'+uniq_win_id+' .header-win .close-win').on("touchstart",null, function(){ // обработка первого сенсорного клика $('body #'+uniq_win_id).remove(); }); }); return uniq_win_id; } function set_autosave( tag ,value) { $.post('query_update.php', { qswitch:"set_autosave", user_key: window.user_key, p1: tag, p2:value }).done( function(data){ if (data) { let ret = jQuery.parseJSON(data); return (ret.ok == 'ok'); } }); } function componentToHex(c) { var hex = c.toString(16); return hex.length == 1 ? "0" + hex : hex; } function rgbToHex(r, g, b) { console.log('r=',r,' g=',g,' b=', b); return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b); } function rgb_to_hex(color){ var rgb = color.replace(/\s/g,'').match(/^rgba?\((\d+),(\d+),(\d+)/i); return (rgb && rgb.length === 4) ? "#" + ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) + ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) + ("0" + parseInt(rgb[3],10).toString(16)).slice(-2) : color; } function rndString(n) { var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (var i = 0; i < n; i++) text += possible.charAt(Math.floor(Math.random() * possible.length)); return text; } function day_of_week_ru( n, fv ) { var value = '-', full_value = 'не указано'; switch (n) { case '0': value = "вс"; full_value = "Воскресенье"; break; case '1': value = "пон"; full_value = "Понедельник"; break; case '2': value = "вт"; full_value = "Вторник"; break; case '3': value = "ср"; full_value = "Среда"; break; case '4': value = "чт"; full_value = "Четверг"; break; case '5': value = "птн"; full_value = "Пятница"; break; case '6': value = "сб"; full_value = "Суббота"; break; default : value = "хз"; full_value = "хто знает"; break; } if (fv) { return full_value; } else { return value; } } function b64EncodeUnicode(str) { // first we use encodeURIComponent to get percent-encoded UTF-8, // then we convert the percent encodings into raw bytes which // can be fed into btoa. return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function toSolidBytes(match, p1) { return String.fromCharCode('0x' + p1); })); } function b64DecodeUnicode(str) { // Going backwards: from bytestream, to percent-encoding, to original string. return decodeURIComponent(atob(str).split('').map(function(c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')); } function on_click_module(module_id) { console.log('protocol: module_id=',module_id); return true; } bin2hex = function(bin){ // UTF-8 string -> ASCII hex var hex = ''; for(var i = 0; i0xFF) c -= 0x350; // UTF-8 -> ASCII hex += c.toString(16); } return hex; } hex2bin = function(hex) { // ASCII hex-> UTF-8 string var bin = ''; for (var i=0; i0x7F) c += 0x350; // ASCII -> UTF-8 bin += String.fromCharCode(c); } return bin; } /*--- Эта функция создана ИИ Google модель gemini-2.0-flash ---*/ // Примеры использования /* console.log(translate(1234.56)); // Одна тысяча двести тридцать четыре рубля, пятьдесят шесть копеек console.log(translate(11.01)); // Одиннадцать рублей, одна копейка console.log(translate(22.22)); // Двадцать два рубля, двадцать две копейки console.log(translate(5)); // Пять рублей, ноль копеек console.log(translate(100.00)); // Сто рублей, ноль копеек console.log(translate(1000)); // Одна тысяча рублей, ноль копеек console.log(translate(2001)); // Две тысячи один рубль, ноль копеек console.log(translate(1234567.89)); // Один миллион двести тридцать четыре тысячи пятьсот шестьдесят семь рублей, восемьдесят девять копеек */ function translate(amount) { const rubles = Math.floor(amount); const kopecks = Math.round((amount - rubles) * 100); const rublesText = numberToWords(rubles, "рубль", "рубля", "рублей"); let kopecksText=0; if (kopecks>0) { kopecksText = numberToWords(kopecks, "копейка", "копейки", "копеек"); return `${rublesText}, ${kopecksText}`; } else { return `${rublesText}`; } } function numberToWords(number, form1, form2, form5) { const numberStr = String(number); const lastDigit = number % 10; const lastTwoDigits = number % 100; if (lastTwoDigits >= 11 && lastTwoDigits <= 19) { return `${numberToText(numberStr)} ${form5}`; } if (lastDigit === 1) { return `${numberToText(numberStr)} ${form1}`; } if (lastDigit >= 2 && lastDigit <= 4) { return `${numberToText(numberStr)} ${form2}`; } return `${numberToText(numberStr)} ${form5}`; } function numberToText(numberStr) { const units = ["", "один", "два", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять"]; const teens = ["", "одиннадцать", "двенадцать", "тринадцать", "четырнадцать", "пятнадцать", "шестнадцать", "семнадцать", "восемнадцать", "девятнадцать"]; const tens = ["", "десять", "двадцать", "тридцать", "сорок", "пятьдесят", "шестьдесят", "семьдесят", "восемьдесят", "девяносто"]; const hundreds = ["", "сто", "двести", "триста", "четыреста", "пятьсот", "шестьсот", "семьсот", "восемьсот", "девятьсот"]; const thousands = ["", "тысяча", "тысячи", "тысяч"]; const millions = ["", "миллион", "миллиона", "миллионов"]; const billions = ["", "миллиард", "миллиарда", "миллиардов"]; if (numberStr === "0") { return "ноль"; } let result = ""; const parts = []; let number = parseInt(numberStr); if (isNaN(number)) { return ""; // или обработать ошибку } // Разбить число на группы по три цифры справа налево const groups = []; while (number > 0) { groups.push(number % 1000); number = Math.floor(number / 1000); } //Обработка каждой группы от младшей к старшей for (let i = 0; i < groups.length; i++) { const group = groups[i]; if (group === 0) continue; // Пропускаем нулевые группы let groupText = ""; const hundredsDigit = Math.floor(group / 100); const tensAndUnits = group % 100; if (hundredsDigit > 0) { groupText += hundreds[hundredsDigit] + " "; } if (tensAndUnits >= 11 && tensAndUnits <= 19) { groupText += teens[tensAndUnits - 10] + " "; } else { const tensDigit = Math.floor(tensAndUnits / 10); const unitsDigit = tensAndUnits % 10; if (tensDigit > 0) { groupText += tens[tensDigit] + " "; } if (unitsDigit > 0) { groupText += units[unitsDigit] + " "; } } let unitName = ""; switch (i) { case 1: // Тысячи if(group % 10 === 1 && group % 100 !== 11){ groupText = groupText.replace(/один$/, 'одна'); } else if ((group % 10 === 2 || group % 10 === 3 || group % 10 === 4 ) && (group % 100 < 10 || group % 100 > 20)){ groupText = groupText.replace(/один$/, 'одна'); groupText = groupText.replace(/два$/, 'две'); } unitName = " " + getForm(group, "тысяча", "тысячи", "тысяч"); break; case 2: // Миллионы unitName = " " + getForm(group, "миллион", "миллиона", "миллионов"); break; case 3: // Миллиарды unitName = " " + getForm(group, "миллиард", "миллиарда", "миллиардов"); break; default: // Единицы break; } parts.unshift(groupText + unitName); } result = parts.join(" ").trim(); // убираем лишние пробелы return result; } function getForm(number, form1, form2, form5) { const lastDigit = number % 10; const lastTwoDigits = number % 100; if (lastTwoDigits >= 11 && lastTwoDigits <= 19) { return form5; } if (lastDigit === 1) { return form1; } if (lastDigit >= 2 && lastDigit <= 4) { return form2; } return form5; }