5 Commits
0.4.0 ... 1.0.0

Author SHA1 Message Date
5a7edafee2 created 2026-04-19 12:39:16 +05:00
c631428699 dots replaced with three.js shader 2026-01-08 18:04:40 +05:00
d26b0ca9ea популярные заказы 2026-01-02 00:27:47 +05:00
7fb037d155 footer 2025-12-01 00:11:20 +07:00
db3a515aaa icons and started on description section 2025-11-24 01:37:35 +07:00
327 changed files with 9669 additions and 1577 deletions

3
.gitmodules vendored Normal file → Executable file
View File

@@ -10,3 +10,6 @@
path = icons
url = https://git.svoboda.works/mirzaev/icons
branch = stable
[submodule "three.js"]
path = three.js
url = https://github.com/mrdoob/three.js.git

View File

@@ -17,11 +17,6 @@
"email": "arsen@mirzaev.sexy",
"homepage": "https://mirzaev.sexy",
"role": "Programmer"
},
{
"name": "Hollspae",
"email": "ksena.vilkova79@gmail.om",
"role": "Creator-Programmer"
}
],
"support": {
@@ -29,13 +24,15 @@
"issues": "https://git.svoboda.works/kodorvan/perm/issues"
},
"require": {
"php": "^8.4",
"php": "^8.5",
"ext-blake3": "^0.1",
"mirzaev/minimal": "^3.8",
"mirzaev/baza": "^3.4",
"mirzaev/languages": "^1",
"twig/twig": "^3.2",
"twig/extra-bundle": "^3.7",
"twig/intl-extra": "^3.10"
"twig/intl-extra": "^3.10",
"phpmailer/phpmailer": "^7.0"
},
"suggest": {
"mirzaev/files": "Easy working with files",

994
composer.lock generated Normal file → Executable file

File diff suppressed because it is too large Load Diff

1
damper.mjs Submodule

Submodule damper.mjs added at 81d208b964

2
icons

Submodule icons updated: cae2ed1a6c...c4dedad538

View File

@@ -8,16 +8,22 @@ if [ -d author ]; then
mv author kodorvan
fi
if [ -e kodorvan/perm/system/settings/*.sample ]; then
for i in kodorvan/perm/system/settings/*.sample; do
cp "$i" "${i/.sample/}";
done
fi
for i in kodorvan/perm/system/settings/*.sample; do
echo $i;
if [ ! -f "${i/.sample/}" ]; then
cp -n "$i" "${i/.sample/}";
echo ${i/.sample/};
fi
done
if ! [ -d kodorvan/perm/system/public/js/modules ]; then
mkdir kodorvan/perm/system/public/js/modules -p
fi
if ! [ -L kodorvan/perm/system/public/js/modules/damper.mjs ]; then
ln -s ../../../../../../damper.mjs/damper.mjs kodorvan/perm/system/public/js/modules/damper.mjs;
fi
if ! [ -L kodorvan/perm/system/public/js/modules/hotline.mjs ]; then
ln -s ../../../../../../hotline.mjs/hotline.mjs kodorvan/perm/system/public/js/modules/hotline.mjs;
fi

View File

@@ -9,7 +9,7 @@ use kodorvan\perm\controllers\core;
// Framework for PHP
use mirzaev\minimal\http\enumerations\content,
mirzaev\minimal\http\enumerations\status;
mirzaev\minimal\http\enumerations\status;
/**
* Index
@@ -47,11 +47,231 @@ final class index extends core
// Initializing the team workload
$this->view->workload = (string) ($_COOKIE['workload'] ?? rand(20, 80));
// Initializing services
$this->view->services = [
[
'class' => 'telegram voronka',
'title' => 'Телеграм воронка',
'icon_left' => '',
/* 'icon_center' => 'import', */
'icon_center' => 'crown',
'icon_right' => '',
'description' => <<<TXT
Поступательно запросит данные пользователя, скомпонует, запишет в базу данных и синхронизирует в CRM
<br><br>
Используя иммерсивные технологии и многофакторный сбор обеспечивает максимальное удержание пользователя
TXT,
'howto' => 'Направьте к нему клиентов и ждите новых заказов в вашей CRM, на сайте или в чате',
'buttons' => [
[
'icon' => 'comment',
'href' => 'https://t.me/' . TELEGRAM_ROBOT['domain'] . '?start=telegram voronka'
]
],
'theses' => [
[
'class' => 'yellow',
'characteristic' => '-80%',
'text' => 'НАГРУЗКА'
],
[
'class' => 'blue',
'colored' => true,
'characteristic' => '+5%',
'text' => 'КОНВЕРСИИ'
],
[
'class' => 'green',
'characteristic' => '0₽',
'text' => 'НИКАКОЙ АРЕНДЫ'
]
],
'background_image_src' => '/themes/default/images/telegram_voronka.png',
'background_image_alt' => 'Телеграм воронка КОДОРВАНЬ',
'cost' => '2000',
'canceled' => 'ЗАБЛОКИРОВАН'
],
[
'class' => 'parser',
'title' => 'Парсер',
'icon_left' => '',
'icon_center' => 'search',
'icon_right' => '',
'description' => <<<TXT
Любая работа за компьютером может быть автоматизирована
<br><br>
Парсер берёт данные с сайтов через API, либо эмулируя пользователя, а так же из excel-документов, CRM и бухгалтерии, затем просчитывает, анализирует и записывает результат
TXT,
'howto' => 'Подключите источники и снизьте нагрузку на операторов, оптимизируйте процессы',
'extra' => [
'Wildberries',
'OZON',
'Yandex Market',
'Avito',
'CDEK',
'1C',
'Bitrix',
'Мой Склад'
],
'buttons' => [
[
'icon' => 'comment',
/* 'href' => 'https://t.me/' . TELEGRAM_ROBOT['domain'] . '?start=parser' */
'href' => 'https://t.me/' . TELEGRAM_ROBOT['domain'] . '?start=parser'
]
],
'theses' => [
[
'class' => 'yellow',
'colored' => true,
'characteristic' => '-100%',
'text' => 'НАГРУЗКА'
],
[
'class' => 'cyan',
'icon' => 'infinity',
'text' => 'ВЕЧНАЯ ПОДДЕРЖКА'
],
[
'class' => 'green',
'icon' => 'play forwards',
'text' => 'РЕКОРД СКОРОСТИ'
]
],
'background_image_src' => '/themes/default/images/excel_small_compressed.jpg',
'background_image_alt' => 'Парсеры КОДОРВАНЬ',
'cost' => '3000'
],
[
'class' => 'calculator',
'title' => 'Калькулятор',
'icon_left' => '',
'icon_center' => 'calculator',
'icon_right' => '',
'description' => <<<TXT
Составление алгоритма обработки большого объёма данных с использованием нейросетей и грамотно выбранной сортировки
<br><br>
Оператор вводит данные, нажимает на кнопки, двигает ползунки и мгновенно получает точный результат вычислений
TXT,
'howto' => 'Настройте параметры в панели управления и в долгосрочной перспективе сэкономьте тысячи часов рабочего времени',
'extra' => [],
'buttons' => [
[
'icon' => 'comment',
'href' => 'https://t.me/' . TELEGRAM_ROBOT['domain'] . '?start=calculator'
]
],
'theses' => [
[
'class' => 'yellow',
'characteristic' => '-95%',
'text' => 'НАГРУЗКА'
],
[
'class' => 'green',
'characteristic' => '-80%',
'text' => 'ОШИБОК ВЫЧИСЛЕНИЙ'
],
[
'class' => 'red',
'colored' => true,
'characteristic' => '+20%',
'text' => 'ОБУЧАЕМОСТЬ'
]
],
'background_image_src' => '/themes/default/images/tordv_compressed.jpg',
'background_image_alt' => 'Калькулятор КОДОРВАНЬ',
'cost' => '10 000'
]
];
// Sending the cookie with the team workload (1800 = 30min)
setcookie('workload', $this->view->workload, time() + 1800, '/');
// Initializing the project constructor data
$this->view->project = [
'architectures' => [
'site' => 'Сайт',
'chat_robot' => 'Чат-робот',
'program' => 'Программа',
'module' => 'Модуль',
'parser' => 'Парсер',
'script' => 'Скрипт',
'game' => 'Видеоигра',
/* 'site' => 'Сайты и браузерные расширения',
'chat_robot' => 'Чат-роботы (любой мессенджер)',
'program' => 'Программа (Android, iOS, Windows)',
'module' => 'Модуль для любой программы',
'parser' => 'Парсер данных API, HTTP и эмуляция',
'script' => 'Скрипт (автоматизация процессов)',
'game' => 'Видеоигра (Android, iOS, Windows)' */
],
'purposes' => [
'funnel' => 'Воронка',
'contacts' => 'Контакты',
'neural_network' => 'Нейросети',
'gallery' => 'Галерея',
'crm' => 'CRM',
'landing' => 'Лендинг',
'marketplace' => 'Маркетплейс',
'search' => 'Поиск',
'calculate' => 'Расчёты',
'logic' => 'Логика',
'game' => 'Игра',
'special' => 'Особенный',
],
'integrations' => [
'one_c' => '1C',
'bitrix24' => 'Битрикс24',
'moy_sklad' => 'Мой Склад',
'telegram' => 'Телеграм',
'mail' => 'Почта',
'excel' => 'Excel'
]
];
// Initializing contacts data
$this->view->contacts = [
'sim' => [
'requests' => [
'full' => PROJECT_CONTACTS_SIM_REQUESTS ?? 'Ошибка',
'country' => PROJECT_CONTACTS_SIM_REQUESTS_COUNTRY ?? 'Ошибка',
'operator' => PROJECT_CONTACTS_SIM_REQUESTS_OPERATOR ?? 'Ошибка',
'number' => [
PROJECT_CONTACTS_SIM_REQUESTS_NUMBER_1 ?? 'Ошибка',
PROJECT_CONTACTS_SIM_REQUESTS_NUMBER_2 ?? 'Ошибка',
PROJECT_CONTACTS_SIM_REQUESTS_NUMBER_3 ?? 'Ошибка'
]
]
]
];
// Initializing contacts data
$this->view->integrations = [
'Мой Склад' => 'moy_sklad',
'1С Предприятие' => '1c',
'Битрикс 24' => 'bitrix24',
'ВКонтакте' => 'vk',
'МАКС' => 'max',
/* 'yandex_direct', */
'Яндекс Директ' => 'yandex_market',
'ОЗОН' => 'ozon',
'Вайлдберриз' => 'wildberries',
'Авито' => 'avito',
'YClients' => 'yclients',
'ЮКасса' => 'yookassa',
'OpenAI' => 'openai'
];
// Render page
$page = $this->view->render('main/index.html');
$page = $this->view->render(
'main/index.html',
[
'smartphone' => $this->request->smartphone,
'tablet' => $this->request->tablet
]
);
// Sending response
$this->response

View File

@@ -0,0 +1,92 @@
<?php
declare(strict_types=1);
namespace kodorvan\perm\controllers;
// Files of the project
use kodorvan\perm\controllers\core;
// Framework for PHP
use mirzaev\minimal\http\enumerations\content,
mirzaev\minimal\http\enumerations\status;
/**
* Offer
*
* @package kodorvan\perm\controllers
*
* @param array $errors Registry of errors
*
* @method null index() Main page
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class offer extends core
{
/**
* Errors
*
* @var array $errors Registry of errors
*/
protected array $errors = [
'system' => []
];
/**
* Page: offer
*
* @return null
*/
public function index(): null
{
if (str_contains($this->request->headers['accept'] ?? '', content::html->value)) {
// Request for HTML response
// Initializing contacts data
$this->view->contacts = [
'sim' => [
'requests' => [
'full' => PROJECT_CONTACTS_SIM_REQUESTS ?? 'Ошибка',
'country' => PROJECT_CONTACTS_SIM_REQUESTS_COUNTRY ?? 'Ошибка',
'operator' => PROJECT_CONTACTS_SIM_REQUESTS_OPERATOR ?? 'Ошибка',
'number' => [
PROJECT_CONTACTS_SIM_REQUESTS_NUMBER_1 ?? 'Ошибка',
PROJECT_CONTACTS_SIM_REQUESTS_NUMBER_2 ?? 'Ошибка',
PROJECT_CONTACTS_SIM_REQUESTS_NUMBER_3 ?? 'Ошибка'
]
]
]
];
// Render page
$page = $this->view->render(
'main/offer.html',
[
'smartphone' => $this->request->smartphone,
'tablet' => $this->request->tablet
]
);
// Sending response
$this->response
->start()
->clean()
->sse()
->write($page)
->validate($this->request)
?->body()
->end();
// Deinitializing rendered page
unset($page);
// Exit (success)
return null;
}
// Exit (fail)
return null;
}
}

View File

@@ -0,0 +1,126 @@
<?php
declare(strict_types=1);
namespace kodorvan\perm\controllers;
// Files of the project
use kodorvan\perm\controllers\core;
// PHP framework
use mirzaev\minimal\http\enumerations\content,
mirzaev\minimal\http\enumerations\status;
// Mail server
use PHPMailer\PHPMailer\PHPMailer as mail,
PHPMailer\PHPMailer\SMTP as smtp,
PHPMailer\PHPMailer\Exception as mail_exception;
/**
* Index
*
* @package kodorvan\perm\controllers
*
* @param array $errors Registry of errors
*
* @method null index() Main page
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class project extends core
{
/**
* Errors
*
* @var array $errors Registry of errors
*/
protected array $errors = [
'system' => []
];
/**
*
*
* @return null
*/
public function request(string $request): null
{
// Initializing the project identifier (temporary solution)
$identifier = blake3($request, 20);
// Initializing the project storage path
$path = STORAGE . DIRECTORY_SEPARATOR . 'projects' . DIRECTORY_SEPARATOR . $identifier;
// Initializing the project storage directory in the storage
if (!file_exists($path)) mkdir($path, 0775, true);
// Declaring the project storage files registry
$files = [];
foreach ($this->request->files as $file) {
// Iterating over files
// Initializing the file destination path
$destination = $path . DIRECTORY_SEPARATOR . $file['name'];
// Writing the file into the project storage
copy($file['tmp_name'], $destination);
// Writing the file destination path into the project storage files registry
$files[$file['name']] = $destination;
}
// Decoding the request JSON argument
$request = json_decode(json: $request, associative: true, depth: 5);
// Initializing the mail server
$mail = new mail(true);
try {
// Writing the mail server parameters
/* $mail->SMTPDebug = smtp::DEBUG_SERVER; */
$mail->setLanguage('ru');
$mail->CharSet = mail::CHARSET_UTF8;
$mail->isSMTP();
$mail->Host = 'smtp.mail.ru';
$mail->SMTPAuth = true;
$mail->Username = 'system@kodorvan.tech';
$mail->Password = 'c6oQF2nY0javI312eDS0';
$mail->SMTPSecure = mail::ENCRYPTION_SMTPS;
$mail->Port = 465;
$mail->setFrom('system@kodorvan.tech', 'Система');
$mail->addAddress('request@kodorvan.tech', 'Заявки');
// The message
$mail->isHTML(true);
$mail->Subject = empty($request['project']['name']) ? 'Заказ' : 'Заказ: ' . $request['project']['name'];
$mail->Body = $this->view->render('messages/request.html', $request);
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
// Attachments
foreach ($files as $name => $file) {
// Iterating of project storage files registry
// Writing the attachment into the message
$mail->addAttachment($file, $name);
}
// Sending the message
$mail->send();
} catch (mail_exception $exception) {
}
// Sending response
$this->response
->start()
->clean()
->sse()
->validate($this->request)
?->body()
->end();
// Exit (fail)
return null;
}
}

0
kodorvan/perm/system/databases/.gitignore vendored Normal file → Executable file
View File

0
kodorvan/perm/system/localizations/english.php Normal file → Executable file
View File

0
kodorvan/perm/system/localizations/russian.php Normal file → Executable file
View File

View File

@@ -0,0 +1,8 @@
@charset "UTF-8";
@font-face {
font-family: 'Akony';
src: url("/fonts/akony/AKONY.ttf");
font-weight: normal;
font-style: normal;
}

View File

@@ -28,7 +28,7 @@
font-style: normal;
}
@font-face {
@font-face {
font-family: 'Bahnschrift';
src: url("/fonts/bahnschrift/BAHNSCHRIFT 5.TTF");
font-weight: 500;

View File

@@ -0,0 +1,50 @@
@charset "UTF-8";
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-ExtraLight.woff2");
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-Light.woff2");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-SemiLight.woff2");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-Regular.woff2");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-Regular.woff2");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-SemiBold.woff2");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-Bold.woff2");
font-weight: 700;
font-style: normal;
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Commissioner';
src: url('/fonts/commissioner.ttf');
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Compacta';
src: url("/fonts/compacta/compacta_lt_light_compress.otf");
}

View File

@@ -0,0 +1,8 @@
@charset "UTF-8";
@font-face {
font-family: 'Eitai';
src: url("/fonts/eitai/eitai.otf");
font-weight: normal;
font-style: normal;
}

View File

@@ -0,0 +1,15 @@
@charset "UTF-8";
@font-face {
font-family: 'GOST';
src: url("/fonts/gost/GOST 2.304-81 type A.ttf");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'GOST';
src: url("/fonts/gost/GOST 2.304-81 type B.ttf");
font-weight: 400;
font-style: normal;
}

View File

@@ -0,0 +1,8 @@
@charset "UTF-8";
@font-face {
font-family: 'Industry';
src: url("/fonts/industry/Industry-Bold_RUS.ttf");
font-weight: normal;
font-style: normal;
}

View File

@@ -0,0 +1,63 @@
@charset "UTF-8";
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-LightCondensed.ttf");
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-LightCondensed.ttf");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-LightCondensed.ttf");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-RegularCondensed.ttf");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-RegularCondensed.ttf");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-Bold.ttf");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-BoldCondensed.ttf");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-BlackCondensed.ttf");
font-weight: 800;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-BlackExtended.ttf");
font-weight: 900;
font-style: normal;
}

View File

@@ -0,0 +1,64 @@
@charset "UTF-8";
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-ExtraLight.ttf");
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Light.ttf");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Regular.ttf");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Regular.ttf");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Medium.ttf");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Bold.ttf");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-ExtraBold.ttf");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Black.ttf");
font-weight: 800;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Black.ttf");
font-weight: 900;
font-style: normal;
}

View File

@@ -0,0 +1,8 @@
@charset "UTF-8";
@font-face {
font-family: 'Palui';
src: url("/fonts/palui/PaluiSPDemo-Bold.otf");
font-weight: normal;
font-style: normal;
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Slifted';
src: url("/fonts/slifted/slifted.otf");
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Urban Slavic';
src: url("/fonts/urban_slavic/UrbanSlavic.otf");
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Vredina';
src: url("/fonts/vredina/SAVredina-ThinUltraCondensed.woff");
}

Binary file not shown.

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

Some files were not shown because too many files have changed in this diff Show More