/* процедурник Дима */
/*------------ вертикальный мувер --------- */
$('.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 ='';
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;
}