LINUX.ORG.RU

112
Всего сообщений: 1143

Я дико извиняюсь, но вопрос про javascript: binary input stream?

Всем привет. Вижу примеры jquery ajax, возвращающие ArrayBuffer, вижу DataView, но это всё какая-то убогая низкоуровневщина. А хочется любви такого:

$.ajax(...).done(function (binaryData) {
    let is = new ByteArrayInputStream(binaryData);  // так в жаве класс называеццо
    is.readChar();
    is.readInt8();
    is.readInt16();
    is.readInt32();
    is.readString();  // это и сам нарисую: e.g. int16 длина + chars
});

Может есть чё готовое на эту тему? Только маленькое, не хочу монструозные фреймворки в зависимости пихать.

 ,

dimgel ()

Грамотная архитектура фронта на vue

Встала задача переписать достаточно крупный легаси проект, работающий сейчас на angular 1.4.9 и sails (порядка 170к строк в сумме, в базе сотни тысяч записей).

Проект - админка компании, которая производит gps устройства. Каждый модуль призван автоматизировать работу разных отделов, будь то бухгалтерия, логистика, техподдержка и т.д.

В качестве фреймворка на фронт выбран Vue ввиду того, что есть достаточный опыт и несколько предвзятая симпатия.

Сейчас остро стоит вопрос архитектуры. Я выступаю за монолит, но я крупных приложений пока и не разрабатывал.

Коллеги за разбитие модулей на отдельные приложения, эдакие микросервисы, или микрофронтенды, как их чаще называют.

Камни преткновения в следующем: -В случае архитектурных ошибок или выходов новых технологий, будет проще переписать каждый модуль по отдельности. Монолит этого не позволит сделать.

-Есть внутренняя бизнес-логика, а есть модули, которыми пользуются сторонние компании. Любая утечка кода не в те руки, может обернуться крахом для компании. Доступ к этим модулям будет по правам, но на выходе ведь в любом случае имеется один собранный js файл. Из этого так же вытекает проблема подгрузки большого количества ненужного кода клиентом, которому доступен только один модуль.

Что касается последнего момента, я пока нашел варианты с асинхронными компонентами и конфигурацией вебпак. Но пока не имею ни малейшего представления о том, как это нужно применять на практике (да, я совершенно не притрагивался к настройке вебпака прежде).

Из решений, на которые упал глаз это Nuxt и single-spa, но эти же решения, в свою очередь, являются утяжелением и усложнением проекта, на мой взгляд.

Сразу оговорюсь, что опыта разработки у меня едва ли будет год. Почти весь этот год я работал над этим же легаси и знаю всю кухню изнутри. Сейчас подвернулась такая замечательная возможность, которой я бы хотел воспользоваться, и хочется сделать всё как можно ближе к идеалу.

 ,

russelcrow ()

Full stack javascript разработчик

Удаленная работа.

Требования:

  • иметь представление о разработке фронтэнда на React, либо возможность быстро в этом разобраться;
  • хорошее знание экосистемы nodejs (т.е. использовали nodejs в реальной разработке, имеете опыт и знания по этой теме);

Задачи:

  • часто: разрабатывать микросервисы на nodejs;
  • редко: разрабатывать фронтэнд на React

Будет плюсом знание linux и Docker.

Зарплата 80000 руб.

Телеграмм для связи в профиле.

 , ,

ostin ()

Как запретить заморозку фоновых вкладок в Google Chrome / Chromium / Opera?

Написал небольшое расширение для браузера, которое автоматически отвечает на сообщения в группе ВКонтакте. Все бы хорошо, но Chrome имеет привычку замораживать фоновые вкладки, а вместе с ними и все процессы в них, как результат, время от времени мой бот дохнет.

Нет ли способов запретить браузеру замораживать фоновые вкладки?

Буду признателен за помощь.

 , , ,

nadim ()

Ищу пример Network First service worker

Вот на гугле есть такой пример

self.addEventListener('fetch', function(event) {
  event.respondWith(
    fetch(event.request).catch(function() {
      return caches.match(event.request);
    })
  );
});

Но они там говорят

you'll most-likely want to update the cache entry.

Что мол cache-ом сам занимайся. Хотелось бы увидеть пример с кэшем, как я понимаю это должно работать

сервис воркер который будет делать запрос, если за X (400 мс) он
  | отвечает - вернуть ответ, и положить в кэш
  | не отвечает - проверить если ли он в кеше
     |  есть в кеше - дать ответ, запрос не прерывать, по завершению положить в кеш
     |  нет в кеше - продолжает ждать ответ от сервера - когда прийдет вернуть его и положить в кеш

 ,

abs ()

Выбор блочного редактора для админки сайта

Всем привет! Подскажите, пожалуйста, есть ли какие-то аналоги блочного редактора Gutenberg (который в Wordpress), но которые можно юзать в своих проектах? Есть вообще EditorJS, но хотелось бы иметь какую-то альтернативу, на которую, если что, можно будет перескочить. Гугл не помогает. Такое ощущение, что кроме EditorJS и Gutenberg редакторов такого типа больше и не существует вовсе.

P.s. сразу же поясню, чем привлекают именно блочные редакторы:

  • Контент отдается не в html, а в json, что позволяет для каждого блока определять свои правила и особенности рендеринга при отрисовке страницы потом. Грубо говоря, при рендеринге страницы json-контент статьи в js объекты (блоки) декодируешь, потом по ним циклом идешь и отрисовываешь в зависимости от типа блока так, как хочешь, html-теги убираешь или добавляешь, если надо.
  • Возможность создавать свои блоки (например, блок с калькулятором ипотеки или рекламный блок, которые можно размещать между абзацами статей - в обычных редакторах, отдающих html, придется парсить html для того, чтобы это реализовать)
  • Нет лишних html-тегов

 , , ,

dimuska139 ()

webpack + jquery + backbone

Всем привет.

Начал тыкать палкой вебпак. Пытаюсь собрать начальное клиентское приложения на базе backbone.js. Есть вот такой вот конфиг:

var webpack = require('webpack');

const { resolve } = require('path');
const SRC_PATH = resolve(__dirname, 'src');
const STATIC_PATH = resolve(__dirname, '../static/admin/');

var ExtractTextPlugin = require('extract-text-webpack-plugin');


module.exports = {
    entry: [
        `${SRC_PATH}/js/main.js`,
        `${SRC_PATH}/css/style.css`
    ],
    output: {
        filename: 'js/[name].js',
        path: resolve(__dirname, 'dist'),
    },
    resolve: {
        modules: ['node_modules']
    },
    module: {
        rules: [
            {
                test: /\.(js)$/,
                exclude: /node_modules/
            },
            {
                test: /\.(jst)$/,
                use: 'underscore-template-loader'
            },
            {
                test: /\.css$/,
                loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader'}),
            }
        ]
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            _: "underscore",
            "window.jQuery": 'jquery',
        }),
        new ExtractTextPlugin('styles.css', {
            allChunks: true
        })
    ]
};

main.js

'use strict';

window.$ = window.jQuery = require('jquery');
import 'bootstrap/dist/css/bootstrap.min.css';
import '../css/style.css';
require("bootstrap");

var Backbone = require('backbone');
var Router = require('./routers/router');

Backbone.$(function() {
    new Router();
    Backbone.history.start();
});

После сборки и подключения бандла. В консоле получаю ошибку:

TypeError: e.replace is not a function

Ошибка эта в кишках библиотеки sizzle (которую, как я понял, юзает jquery).

Сталкивался ли кто-нибудь с такой фигней? В чем может быть проблема?

 , , ,

djnoob ()

webpack + jquery + backbone

Всем привет.

Начал тыкать палкой вебпак. Пытаюсь собрать начальное клиентское приложения на базе backbone.js. Есть вот такой вот конфиг:

var webpack = require('webpack');

const { resolve } = require('path');
const SRC_PATH = resolve(__dirname, 'src');
const STATIC_PATH = resolve(__dirname, '../static/admin/');

var ExtractTextPlugin = require('extract-text-webpack-plugin');


module.exports = {
    entry: [
        `${SRC_PATH}/js/main.js`,
        `${SRC_PATH}/css/style.css`
    ],
    output: {
        filename: 'js/[name].js',
        path: resolve(__dirname, 'dist'),
    },
    resolve: {
        modules: ['node_modules']
    },
    module: {
        rules: [
            {
                test: /\.(js)$/,
                exclude: /node_modules/
            },
            {
                test: /\.(jst)$/,
                use: 'underscore-template-loader'
            },
            {
                test: /\.css$/,
                loader: ExtractTextPlugin.extract({fallback: 'style-loader', use: 'css-loader'}),
            }
        ]
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            _: "underscore",
            "window.jQuery": 'jquery',
        }),
        new ExtractTextPlugin('styles.css', {
            allChunks: true
        })
    ]
};


main.js

'use strict';

window.$ = window.jQuery = require('jquery');
import 'bootstrap/dist/css/bootstrap.min.css';
import '../css/style.css';
require("bootstrap");

var Backbone = require('backbone');
var Router = require('./routers/router');

Backbone.$(function() {
    new Router();
    Backbone.history.start();
});


После сборки и подключения бандла. В консоле получаю ошибку:

TypeError: e.replace is not a function


Ошибка эта в кишках библиотеки sizzle (которую, как я понял, юзает jquery).

Сталкивался ли кто-нибудь с такой фигней? В чем может быть проблема?

 , , ,

djnoob ()

JavaScript developer в офис в Польше, г. Гданьск

Orion Alliance B.V., международная аутсорсинговая IT-компания, приглашает специалистов на позицию JavaScript developer в офис в Польше, г. Гданьск. Предоставляем услуги разработки ПО и технической поддержки клиентов в банковском и финансовом секторах.

Чем предстоит заниматься: Разработка RIA на NodeJs и React сопровождение существующих UI ExtJS, jQuery командная работа с коллегами (на русском языке) участие в деловой переписке и телефонных конференциях с коллегами из американского офиса компании (на английском языке)

Требования к знаниям и опыту: Уверенные знания ES6, HTML, CSS/LESS Опыт работы с ReactJS, Redux, NodeJS, Webpack Опыт работы с системами контроля версий Владение английским языком на уровне Intermediate и выше

Желательно: Опыт тестирования кода (TDD, BDD) Знание Java (ExtGWT) Знание ActionScript3, Adobe Flex Знание ExtJS 3

Условия трудоустройства и переезда: Релокация в Польшу, г. Гданьск спонсирование затрат на переезд (оформление визы для сотрудника и его семьи, билеты, предоставление жилья на 2 недели, помощь в поиске жилья) официальное трудоустройство по полному трудовому договору заработная плата по результатам собеседования от 2000 $ возможность получить вид на жительство в Польше, помощь в оформлении документов гибкий график работы русскоговорящий коллектив офис в новом бизнес-центре в деловом квартале Гданьска Доступно соискателям с инвалидностью

Ключевые навыки: Java JavaScript HTML CSS Flex ActionScript React ExtJS Flux

Адрес: Гданьск, aleja Grunwaldzka, 184

 , , , ,

AndreyKha ()

Разработчик приложений на SmarT TV / Frontend Разработчик (JavaScript)

Требуемый опыт работы: 1–3 года Полная занятость, полный день

Вам предстоит интересная работа над созданием приложения на Smart TV для устройств Sumsung, LG, Philips, Panasonic, Toshiba и Sony. Приветствуется креативный подход и нестандартное мышление.

Обязанности: • Разработка приложений для SmartTV. • Разработка архитектуры приложений. • Взаимодействие с другими подразделениями компании.

Требования: • Умение работать с 'чистым' JavaScript. • Большим плюсом, будет опыт применения и наличие реализованных проектов, с использованием библиотеки knockout.js. • Практический опыт работы: spa, es5, less/sass, git, node/npm, requirejs, grunt/webpack. • Webstorm. • Понимание js patterns, ооп. • Аккуратность, самостоятельность, способность решать комплексные задачи и находить решения. • Умение пользоваться англоязычной документацией. • Опыт работы не менее 2х лет.

Условия: - Работа в стабильной развивающейся ИТ-Компании, одной из лидеров рынка онлайн-телевидения. - Зарплата на испытательном сроке 20 тыс.руб, после испытательного срока - до 80 тыс.руб - Трудоустройство по ТК - Офис в центре города

Для резюме: mv.vasilieva@limehd.tv Тел.: ( 8352 )22-00-06 Марина Валерьевна г. Чебоксары, ул. Карла Маркса, д. 60 а

 ,

infiniti13 ()

Не работает strings.includes и пр?

Туториал https://www.youtube.com/watch?v=NQ2i...i8o-_c-9Vva_W0 где чувак црм делает на вуе и огнебазе. Прошел половину. Вроде все нормэ, но то и дело наталкиваюсь на непонятные ерроры при компиляции

Сроки кода типа

console.log("1234 5678".includes("1234"))
или
Object.keys(_r).length

выводит :

 WAIT  Compiling...                                                                                                                           21:36:20
 98% after emitting CopyPlugin

 ERROR  Failed to compile with 2 errors                                                                                                       21:36:22
These dependencies were not found:

* core-js/modules/es6.string.includes in ./src/main.js
* core-js/modules/es7.array.includes in ./src/main.js

To install them, you can run: npm install --save core-js/modules/es6.string.includes core-js/modules/es7.array.includes  

Попытка последовать совету выдает :

npm install --save core-js/modules/es6.string.includes core-js/modules/es7.array.includes
npm ERR! code ENOLOCAL
npm ERR! Could not install from "core-js\modules\es6.string.includes" as it does not contain a package.json file.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\user\AppData\Roaming\npm-cache\_logs\2019-07-07T18_46_12_187Z-debug.log

что это? Бабизм бабеля? как с этим бороться? package.json :

{
  "name": "vuecrm",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build"
  },
  "dependencies": {
    "core-js": "^3.1.4",
    "es6": "^0.0.7",
    "firebase": "^6.2.4",
    "materialize-css": "^1.0.0-rc.2",
    "register-service-worker": "^1.6.2",
    "vue": "^2.6.10",
    "vue-router": "^3.0.3",
    "vuex": "^3.0.1"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^3.8.0",
    "@vue/cli-plugin-pwa": "^3.8.0",
    "@vue/cli-service": "^3.8.0",
    "node-sass": "^4.9.0",
    "sass-loader": "^7.1.0",
    "vue-template-compiler": "^2.6.10",
    "vuelidate": "^0.7.4"
  }
}

 , ,

dwarfadelic ()

Регулярка по замене hex

Есть hex последовательность символов E2808c(utf-8 ZERO WIDTH NON-JOINER) в строке, их надо удалять. Как написать регулярку по их замене?
Пробую

text.replace(/\xe2\x80\x8c/gm, "")
не заменяет
text.match(/\xe2\x80\x8c/gm)
null

Ничего не заменяет

 , ,

gobot ()

Проблемы с текстурами в babylon.js

Добрый день, может кто-то сможет помочь мне.
Я хочу использовать babylon.js для отображения wrl модели в браузере.
Загружаю я её так:

var ground = BABYLON.SceneLoader.ImportMesh("", "", "test.wrl", scene, function() {});
https://imgur.com/a/YJ2KHIr
С этим проблем нет.
Но если я накладываю на свою модель текстуру, то вместо наложенной текстуры вижу усреднённый цвет текстуру. Например если на текстуре белые и красные квадраты, то моя модель будет просто розового цвета.
Текстура https://imgur.com/a/gSlsSNT
Что получается при наложении https://imgur.com/a/NIFkUmp
Модель у меня такая:
#VRML V2.0 utf8
Transform {
    children[
    Shape {
        appearance Appearance {
        texture ImageTexture { url "stone.jpg" }
        material Material {
            diffuseColor 0 1 0
            ambientIntensity 1
            transparency 0
        }
        }
        geometry IndexedFaceSet {
			coord Coordinate {
				point [
					0 1 0 #0
					.951 .5 -.309 #1
					.587 .5 .809 #2
					-.587 .5 .809 #3
					-.951 .5 -.309 #4
					0 .5 -1 #5
					.951 -.5 .309 #6
					0 -.5 1 #7
					-.951 -.5 .309 #8
					-.587 -.5 -.809 #9
					.587 -.5 -.809 #10
					0 -1 0 #11
				]
			}
			coordIndex [
				0 2 1 -1  0 3 2 -1  0 4 3 -1  0 5 4 -1   0 1 5 -1
				1 2 6 -1  2 7 6 -1  2 3 7 -1  3 8 7 -1   3 4 8 -1
				4 9 8 -1  4 5 9 -1  5 10 9 -1 5 1 10 -1  1 6 10 -1
				7 11 6 -1 7 8 11 -1 9 11 8 -1 9 10 11 -1 10 6 11 -1
				]
		}

    }
    ]
    }
Как видите у меня для здания геометрии используется IndexedFaceSet, если мне вместо своей фигуры сделать просто объект типо шара или квадрата, то на них текстура нормально ложится. https://imgur.com/a/8q8PTmM Не понимаю даже в какую сторону копать.

 ,

sany0k ()

Выявление утечек в приложениях

Добрый день, расскажите, как можно выявить куда проваливается память в жаваскрипте?

Я пытаюсь прогонять софтину под отладчиком, но оно мне ничего не говорит. Я подозреваю что дело в кривых плагинах и несовместымых версиях хромиума, но как тогда выяснить где совместимая?

Софтина — игрушка на rpgmakermv (тысячи их, практически любая), причём, легаси билд nwjs (0.14.7) нормально работает — память всегда в районе 200 мб, нет кучи процессов, сборщик всё очищает. Более новые показывают в отладчике занятыми какую-то сотню мегабайт, но имеют кучу процессов которые быстро разрастаются на гигабайты, память кончается и линукс зависает (полностью). Такое ощущение, что gc не работает корректно, иногда при смене сцен прибавляет сразу по сотке мегабайт (что даже не отражено в отладчике?).

Помимо последних 3, были проверены также 0.27.3 0.24.4 0.23.7 0.22.3 и все они текут хоть и меньше 0.38 0.39. Я ориентируюсь по версиям хромиума в вендовом экзешнике, там допустим 17 год. Всё равно течёт. В 0.14.7 не текла несмотря на то что нужна была совсем уж древняя версия хромиума и 0.14.7 сильно свежее.

Что можно сделать?

Алсо, добавьте тег nwjs? У электрона есть свой тег, несправедливость!

 , , , ,

linuxnewbie ()

AngularJs добавление отдельного скрипта

Есть код с со всеми известного AngularJS Phonecat В который я бы хотел добавить свой код:

const queryInput = document.getElementById('query_input');
const searhForm  = document.getElementById('query_form');
const queryUlSearch = document.getElementById('query_ul_search');

// При начале поиска дождно появляться окно выбора
document.getElementById('query_form').addEventListener('keydown', function(e){
    if (e.target.id == 'query_input') {
        console.log('alksdjflasdkjf');
    }
});
код был подключен обычным
 <script src="my_js.js"></script> 

И он не видит форму которая из phone-list.template.html Запускается через npm start Выдаёт ошибку

Uncaught TypeError: Cannot read property 'addEventListener' of null

Подскажите, что я делаю не так и как это исправить. Спасибо

 ,

q13 ()

Как на javascript сделать горячие клавиши на сайте?

Добрый день товарищи программисты! Дайте пожалуйста совет, как вообще реализовывают горячие клавиши на сайте? Я конечно пробовал много вариантов, но так и не нашел подходящего момента. Как вообще правильно эту функцию реализовывают? В справочнике MDN я нашел некий интерфейс, но все равно результаты не увенчались.

Я хочу такую горячую клавишу, когда посетитель заходит на сайт и он смог горячей клавишей «пробела» затемнить цветовую схему сайта. Удобно все же согласитесь?

Набросал немного говнокода, но когда нажимаю «пробел» код не работает. Браузер Chrome.

'use strict';

document.addEventListener('keydown', (event) => {
  const keyName = event.key;

  if (keyName === 'Space')
    alert('это alert только для теста')
    return;
});

 , , ,

dimcoin ()

Vue.js как добавление реактивности

Привет.

Решил я сделать свой мини сайт на vps для лично своих заметок и прочих нужд. Т.к. в основном работаю с django, на ней и решил остановиться. Примерная концепция — отдельные приложения для реализации каких-то своих функций. Для упрощения восприятия положим, что это блог, какое-то приложение для учёта каких-то действий, может аналог pastebin, прочее.

Делать SPA я не собираюсь, равно как и использовать какие-либо route, т.е. классическая схема обычного веб приложения. Но! Хочется добавить какой-то реактивности, например, логин форма xhr запросом логинит. Так же в бложике может быть markdown редактор, например. Т.е. в некоторых местах могут быть какие-то сущности, которые работают исключительно с api бекенда. Такая примерно идея.

Понимая, что уже 2к19 и использовать jQuery как минимум странно, я решил заюзать vue. Написал конфиг для webpack, чтобы удобно собирать это всё вместе с scss стилями по разным файлам и хочу интегрировать это в страницы обычного django.

Собственно вопрос. Я ознакомился с документацией и разными решениями и что я понял:

  • почти всегда vue позиционируется как SPA. Типа вот тебе #app и тут делай что тебе надо. Но мне надо не это.
  • да, есть решение, когда тебе нужно не это и это — portal-vue — типа всё так же регистрируешь один #app, но магией работы с DOM из инициализированного приложения можно достучаться до элементов извне. Как мне кажется, это довольно костыльный метод.
  • сделать несколько инстансов vue App. Например в подключаемом файле js пишем конструкции типа: if element.exists => new vue.App... — несколько костыльно, но в общем мне решение подходит, т.к. я могу при нахождении какого-то элемента на странице сделать его реактивным.

Собственно вопрос — неужели всё так печально? Ладно, я могу создать несколько элементов, но, вдруг, мне понадобится шарить между ними какие-то данные? Скидывать всё в localStorage и добавлять кругом разных eventListener чтобы всё это отслеживать? Так это очень похоже на jQuery подход.

Если у кого есть пример решения подобной проблемы и как с этим боролись — заранее благодарен.

 , , ,

conformist ()

Chrome custom tabs JavaScript

Добрый день. Сейчас в веб-приложении реализованном на компоненте webview частенько использую вызов функций из js-java. Хотела попробовать использовать chrome custom tabs вместо webview, но не могу разобраться как тогда из js выполнять java функции

 , ,

jessgt ()

Как считаете, годный ли видеоконтент по javascript?

Нашел тут ролик один. И что-то закрались некоторые сомнения, хочу спросить у Уважаемой общественности.

Кто в программировании и Javascript разбирается, можете подсказать, годное ли видео? Автор в вопросе разбирается, нормально тему дает?
Или это все прогон полный и не стоит его слушать?

[Пример разработки простой функции на JavaScript]

Update: Уважаемая общественность это не видео уроки и не желание продвинуть чей-то продукт. Продукта там нет и никаких курсов никто не впаривает (у автора ролика их даже нет).

Мой уровень не полный ноль, гуглом пользоваться умею, как писать JS базово знаю.

Фишка видео в том, что автор пытается донести мысль, как писать функцию с заделом на расширение и при это еще учитывать требования. Мне видео показалось интересным, но не однозначным. Поэтому и уточняю, кто что думает по поводу этого видео и годный ли это контент? Стоит ли прислушаться к рекомендациям?

 , ,

bonzaza ()

Devery Global Online Hackathon 2.0

Приветствуем всех. Devery приглашает всех желающих принять участие в предстоящем глобальном онлайн хакатоне 2.0 для js разработчиков. Хакатон стартует 13 мая, продолжительность - 2 недели. Первый приз - $2,000 (долл США) Второй приз - $1,000(долл США), Третий приз - $500(долл США). Целью хакатона является создание дополнительного стимула для использования продуктов, разработанных Devery. Ознакомиться с проектами победителей предыдущего хакатона можно перейдя по ссылке: https://github.com/devery/hackathon_entries Мы учли все поступившие пожелания и советы, и надеемся создали еще более комфортные условия для плодотворной работы участников. Узнать больше о хакатоне, javascript библиотеке и продуктах Devery можно перейдя по ссылкам: Slack канал хакатона: https://join.slack.com/t/deveryhackathon/shared_invite/enQtNjExOTE1ODkzNDEwLTA0ZDhhZWNhZjk0MTY0MDQzYmZiZGY4ZjMxNTk1NTIyNzU1MTBlYjBiNzA2NDE2YWVhMmU3YWZkYmY4NDAwODM https://link.medium.com/CqkfcWrhXV https://devery.io/ https://github.com/devery

 

petushka ()