This media is not supported in your browser
VIEW IN TELEGRAM
#статья дня
Вы (да и я) могли раньше не обращать внимания, но animation-timing-function применяется к каждому ключевому кадру, описанному в блоке keyframes.
Т. е. имея такую анимацию:
и
Такое поведение описал Бен Нэйдл (Ben Nadel) в своей статье https://www.bennadel.com/blog/3885-animation-timing-functions-get-applied-per-keyframe-in-css.htm
#css #animation #keyframes #бородач
Вы (да и я) могли раньше не обращать внимания, но animation-timing-function применяется к каждому ключевому кадру, описанному в блоке keyframes.
Т. е. имея такую анимацию:
box-animation {
from, 5% {
left: 10px ;
}
25%, 40% {
left: 30% ;
}
60%, 75% {
left: 70% ;
}
95%, to {
left: calc( 100% - 90px ) ;
}
}
и
animation-timing-function
равный cubic-bezier(.55, -0.64, .42, 1.63)
мы получим результат, изображённый на иллюстрации. Т. е. функция анимации будет применена на каждый временной отрезок, а не на всё время проигрывания. Думайте об этом как о color-stop в градиентах.Такое поведение описал Бен Нэйдл (Ben Nadel) в своей статье https://www.bennadel.com/blog/3885-animation-timing-functions-get-applied-per-keyframe-in-css.htm
#css #animation #keyframes #бородач
👍9❤2
#такое дня
Прежде чем волноваться о плохо пройденном собесе, помни: некий разработчик Facebook прошёл алгоритмы, лайвкодинг, калча фит... и всё ради того, чтобы при каждом нажатии клавиши в поле ввода поста прогонять регулярку на поиск ссылок по всему тексту.
Да, вы не ослышались. В итоге, на сообщение в 10000 символов задержка может составить две-три секунды.
Не надо так, котаны.
Ссылка на тред: тут. В треде народ развлекается разным профайлингом, очень интересно: React Scan, Chrome Profile, немного реверс-инжиниринга...
Как же решать такую задачу? Ну, например, debounce или throttle, зависит от условий. Или предсказание по первому символу.
#js #react
Прежде чем волноваться о плохо пройденном собесе, помни: некий разработчик Facebook прошёл алгоритмы, лайвкодинг, калча фит... и всё ради того, чтобы при каждом нажатии клавиши в поле ввода поста прогонять регулярку на поиск ссылок по всему тексту.
Да, вы не ослышались. В итоге, на сообщение в 10000 символов задержка может составить две-три секунды.
Не надо так, котаны.
Ссылка на тред: тут. В треде народ развлекается разным профайлингом, очень интересно: React Scan, Chrome Profile, немного реверс-инжиниринга...
Как же решать такую задачу? Ну, например, debounce или throttle, зависит от условий. Или предсказание по первому символу.
#js #react
🤡14❤3👍2
#ссылка дня
Всеобъемлющее руководство по созданию приложения адресной книги от создателей React Router: https://reactrouter.com/tutorials/address-book
Клиентский и серверный рендеринг, фильтрация данных, добавление. И даже немного о кодах ответов.
Для полноценного приложения останется добавить только работу с базой данных :) Но... не здесь.
Прекрасный туториал, начинающим и тем, кто ещё не знаком с реакт-роутером или некоторыми его аспектами должно очень зайти.
#react #router #ssr #tutorial
Всеобъемлющее руководство по созданию приложения адресной книги от создателей React Router: https://reactrouter.com/tutorials/address-book
Клиентский и серверный рендеринг, фильтрация данных, добавление. И даже немного о кодах ответов.
Для полноценного приложения останется добавить только работу с базой данных :) Но... не здесь.
Прекрасный туториал, начинающим и тем, кто ещё не знаком с реакт-роутером или некоторыми его аспектами должно очень зайти.
#react #router #ssr #tutorial
👍12❤1
#инструмент дня
Примерно пять раз в секунду где-то в мире очередному разработчику приходит в голову идея: «А что если я этот виджет сделаю независимо от основного приложения, на каком-нибудь миниатюрном фреймворке, чтобы быломодно, молодежно переносимо?»
Когда такая идея приходила мне, я взял Preact, а потом Van. А тут недавно на собеседовании кандидат рассказал, что тоже сталкивался с подобной задачей и решил её через µhtml.
Микрохатээмэль
Сразу ссылка: https://github.com/WebReflection/uhtml
JSX там нет, вся работа через шаблонные литералы. Что, впрочем, выглядит вполне нормально:
И да, ваши глаза вас не обманывают: сигналы! И SSR.
В общем, глаза кандидата так светились, что мне тоже надо будет попробовать.
А ваши варианты, котаны?
#uhtml #js #framework
Примерно пять раз в секунду где-то в мире очередному разработчику приходит в голову идея: «А что если я этот виджет сделаю независимо от основного приложения, на каком-нибудь миниатюрном фреймворке, чтобы было
Когда такая идея приходила мне, я взял Preact, а потом Van. А тут недавно на собеседовании кандидат рассказал, что тоже сталкивался с подобной задачей и решил её через µhtml.
Микрохатээмэль
Сразу ссылка: https://github.com/WebReflection/uhtml
JSX там нет, вся работа через шаблонные литералы. Что, впрочем, выглядит вполне нормально:
import { render, html, signal, detach } from 'uhtml/preactive';
const count = signal(0);
render(document.body, () => html`
<button onclick=${() => { count.value++ }}>
Clicks: ${count.value}
</button>
`);
// stop reacting to signals in the future
setTimeout(() => {
detach(document.body);
}, 10000);
И да, ваши глаза вас не обманывают: сигналы! И SSR.
В общем, глаза кандидата так светились, что мне тоже надо будет попробовать.
А ваши варианты, котаны?
#uhtml #js #framework
👍7❤2
This media is not supported in your browser
VIEW IN TELEGRAM
#фишка дня
Продолжим тему ответов на ваши вопросы на собеседованиях.
Почему ваши? Ну потому что вы их предлагали! Вот тут: https://t.iss.one/htmlshit/3290
Итак, вопрос: как показать спиннер загрузки прямо в кнопке, сохранив размер кнопки и её доступность?
То есть, не делать такое:
Очевидный ответ: абсолютом спиннер сверху навернуть. Но мы же не в 2009 году, в самом деле!
А что, если нам больше одного наслоения надо? А что, если на разных устройствах нужен разный порядок отображения, например, спиннер и текст одновременно? А что, если текст состояния загрузки на самом деле длиннее, чем основной? Мы же не хотим, чтоб интерфейс прыгал.
Когда-то давно мы сделали табло, в котором меняли строки на разных языках: https://t.iss.one/htmlshit/2814
И там как раз применили такую фишку CSS Grid, как стек. Т. е. накладывание блоков друг на друга без изменения их позиционной модели.
Самое время это применить и тут!
Только на сей раз мы воспользуемся именованными зонами грида, вместо
Итого:
Ну и как-то так вышло: https://codepen.io/alinaki/pen/ogvBMLv
#css #grid
Продолжим тему ответов на ваши вопросы на собеседованиях.
Почему ваши? Ну потому что вы их предлагали! Вот тут: https://t.iss.one/htmlshit/3290
Итак, вопрос: как показать спиннер загрузки прямо в кнопке, сохранив размер кнопки и её доступность?
То есть, не делать такое:
‹button>{ isLoading ? <LoadingSpinner/> : "Save" }</button>
Очевидный ответ: абсолютом спиннер сверху навернуть. Но мы же не в 2009 году, в самом деле!
А что, если нам больше одного наслоения надо? А что, если на разных устройствах нужен разный порядок отображения, например, спиннер и текст одновременно? А что, если текст состояния загрузки на самом деле длиннее, чем основной? Мы же не хотим, чтоб интерфейс прыгал.
Когда-то давно мы сделали табло, в котором меняли строки на разных языках: https://t.iss.one/htmlshit/2814
И там как раз применили такую фишку CSS Grid, как стек. Т. е. накладывание блоков друг на друга без изменения их позиционной модели.
Самое время это применить и тут!
Только на сей раз мы воспользуемся именованными зонами грида, вместо
grid-area: 1/1
как в прошлом примере.Итого:
.button {
display: grid;
grid-template-areas: "stack";
.spinner,
.text {
grid-area: stack;
justify-self: center;
}
}
Ну и как-то так вышло: https://codepen.io/alinaki/pen/ogvBMLv
#css #grid
2👍29❤9
#видео дня
Раз уж я позаимствовал сегодняшнюю фишку дня у Веса Боса (хотя давайте честно, у него была ненастоящая демонстрация), придётся уважить.
Тем более, что в его подкасте был гость, который мне дико интересен! Точнее, компания и их методы работы.
И говорю я о ByteDance, авторах TikTok, CapCut, Mars (альтернативы Cursot) и Lark (альтернатива Google Workspace).
Почему мне так интересно? Потому что я люблю позалипать в ТикТоке. Шутка. Потому что я пользуюсь бандлером RSPack с первых дней выхода. Пруф: https://t.iss.one/htmlshit/1868
А Зак Джексон как раз его ментейнер :) И автор идеи Module Federation.
И, собственно, беседа о нём в том числе и пойдёт, а ещё о микрофронтендах и Module Federation.
К слову, когда автор React Scan начал свой спам видео с ререндерами всего и вся, именно ребята из ByteDance наиболее адекватно среагировали на проблему, а не стали орать: «Да кому это интересно, господи!»
В общем, хоть я и не фанат подкастов, моя дикая рекомендация: https://www.youtube.com/watch?v=aFhysuTUoQY
#podcast #rspack #bytedance
Раз уж я позаимствовал сегодняшнюю фишку дня у Веса Боса (хотя давайте честно, у него была ненастоящая демонстрация), придётся уважить.
Тем более, что в его подкасте был гость, который мне дико интересен! Точнее, компания и их методы работы.
И говорю я о ByteDance, авторах TikTok, CapCut, Mars (альтернативы Cursot) и Lark (альтернатива Google Workspace).
Почему мне так интересно? Потому что я люблю позалипать в ТикТоке. Шутка. Потому что я пользуюсь бандлером RSPack с первых дней выхода. Пруф: https://t.iss.one/htmlshit/1868
А Зак Джексон как раз его ментейнер :) И автор идеи Module Federation.
И, собственно, беседа о нём в том числе и пойдёт, а ещё о микрофронтендах и Module Federation.
К слову, когда автор React Scan начал свой спам видео с ререндерами всего и вся, именно ребята из ByteDance наиболее адекватно среагировали на проблему, а не стали орать: «Да кому это интересно, господи!»
В общем, хоть я и не фанат подкастов, моя дикая рекомендация: https://www.youtube.com/watch?v=aFhysuTUoQY
#podcast #rspack #bytedance
1👍3❤2
This media is not supported in your browser
VIEW IN TELEGRAM
#инструмент дня
Ну что, вы уже сделали свой сервис для удаления фона с изображения?
Нет? А почему?
Даже Эдди Османи не удержался: https://bg.addy.ie/
Ведь, как мы уже писали, с помощью библиотеки Transformers.js можно с лёгкостью реализовать множество применений ИИ-моделей прямо в браузере! Да, без отправки на сервер. Пусть комп клиента старается :)
Гитхаб: https://github.com/addyosmani/bg-remove
Больше сервисов богу сервисов!
#ai #webgpu #image
Ну что, вы уже сделали свой сервис для удаления фона с изображения?
Нет? А почему?
Даже Эдди Османи не удержался: https://bg.addy.ie/
Ведь, как мы уже писали, с помощью библиотеки Transformers.js можно с лёгкостью реализовать множество применений ИИ-моделей прямо в браузере! Да, без отправки на сервер. Пусть комп клиента старается :)
Гитхаб: https://github.com/addyosmani/bg-remove
Больше сервисов богу сервисов!
#ai #webgpu #image
👍18
This media is not supported in your browser
VIEW IN TELEGRAM
#codepen дня
Итак, вашему вниманию самый популярный в октябре кодпен небезызвестной Аны Тюдор.
Переливающийся всеми цветами радуги светящийся текст!
Вот: https://codepen.io/thebabydino/pen/rNPOpJK
Реализовано на SVG-фильтре gaussian blur: фон обрезается по контенту текста через -webkit-background-clip: text и размывается.
Жаль, я не знал об этой технике когда много лет назад делал сайт школе стриптиза. Там было много эффектов а-ля неоновое свечение. Фоток не будет.
#css #svg #filter #бородач
Итак, вашему вниманию самый популярный в октябре кодпен небезызвестной Аны Тюдор.
Переливающийся всеми цветами радуги светящийся текст!
Вот: https://codepen.io/thebabydino/pen/rNPOpJK
Реализовано на SVG-фильтре gaussian blur: фон обрезается по контенту текста через -webkit-background-clip: text и размывается.
Жаль, я не знал об этой технике когда много лет назад делал сайт школе стриптиза. Там было много эффектов а-ля неоновое свечение. Фоток не будет.
#css #svg #filter #бородач
❤11🤩5
#фишка дня
Надоело читать это: «To push the current branch and set the remote as upstream, use
А всё потому что git на сервере не знает ничего о ветках на вашей машине. Нужно явно указать: «Хочу создать ветку на удаленном сервере с указанным названием и связать её с локальной». Названия даже могут отличаться, но чаще всего — совпадают. Ну, у меня, во всяком случае.
Поэтому, глядите чо: https://git-scm.com/docs/git-config#Documentation/git-config.txt-pushautoSetupRemote
Ну или просто взгляните на КДПВ.
Завезли с версии 2.37.0, так что проверьте сначала. Спасибо за уточнение подписчику :)
#git #remote #бородач
Надоело читать это: «To push the current branch and set the remote as upstream, use
git push --set-upstream origin fix/bug-1359
»?А всё потому что git на сервере не знает ничего о ветках на вашей машине. Нужно явно указать: «Хочу создать ветку на удаленном сервере с указанным названием и связать её с локальной». Названия даже могут отличаться, но чаще всего — совпадают. Ну, у меня, во всяком случае.
Поэтому, глядите чо: https://git-scm.com/docs/git-config#Documentation/git-config.txt-pushautoSetupRemote
Ну или просто взгляните на КДПВ.
Завезли с версии 2.37.0, так что проверьте сначала. Спасибо за уточнение подписчику :)
#git #remote #бородач
❤12👍3
#баг дня
Если вы тут утром решили развернуть новый проект на Vite, и у вас ничего не вышло, это нормально.
esuild, на котором Vite и основана, в версии 0.24.1 принёс ломающее конфиги изменение.
И на данный момент лучшее решение — запинить зависимость esbuild на 0.24.0: https://github.com/vitejs/vite/issues/19018
Ну или использовать пятую ветку Vite.
Повторяется на всех пакетных менеджерах: и npm, и pnpm и bun и, прости господи, yarn.
Осторожнее там, котаны :)
#vite #esbuild #bug
Если вы тут утром решили развернуть новый проект на Vite, и у вас ничего не вышло, это нормально.
esuild, на котором Vite и основана, в версии 0.24.1 принёс ломающее конфиги изменение.
И на данный момент лучшее решение — запинить зависимость esbuild на 0.24.0: https://github.com/vitejs/vite/issues/19018
Ну или использовать пятую ветку Vite.
Повторяется на всех пакетных менеджерах: и npm, и pnpm и bun и, прости господи, yarn.
Осторожнее там, котаны :)
#vite #esbuild #bug
❤7👍5
#инструмент дня
Помните, как на Новый год нужно было срочно найти подарок для младшего брата, и вы отдали ему пылившийся на полке DVD с фильмом, который вы даже не смотрели?
Возможно, он до сих пор это помнит... А вы с тех пор понимаете, что такое повторное использование.
А вот ребята из Material UI aka MUI решили переработать подход к таким ситуациям.
Они только что выпустили публичную альфу Base UI 1.0 — библиотеку нестилизованных React-компонентов, выделенных из большого пакета Material UI и доступных теперь как отдельный продукт.
Помимо готовых компонентов в ней есть и низкоуровневые хуки, дающие всю мощь Material UI, но без необходимости реализовывать Material Design в приложении.
Полная свобода в стилях
Base UI не навязывает собственное решение для CSS. Вы сами выбираете, как работать: Tailwind, CSS-in-JS или любой другой способ.
Доступность (A11Y) по умолчанию
Компоненты соблюдают лучшие практики доступности. Это значит, что ваш проект будет удобен для всех, и никто не скажет, что вы плохой человек (кроме младшего брата).
Композиция
API компонентов открыто полностью. У вас есть доступ к каждому узлу, что позволяет легко добавлять, удалять или оборачивать элементы под свои нужды.
Base UI сохраняет лучшие части Material UI, не привязывая вас к "гугловскому" дизайну.
Вот это переиспользование, за которое не стыдно, котаны. Можно и младшему брату оставить.
Лучший подарок на Новый год!
#react #mui #ui #widgets
Помните, как на Новый год нужно было срочно найти подарок для младшего брата, и вы отдали ему пылившийся на полке DVD с фильмом, который вы даже не смотрели?
Возможно, он до сих пор это помнит... А вы с тех пор понимаете, что такое повторное использование.
А вот ребята из Material UI aka MUI решили переработать подход к таким ситуациям.
Они только что выпустили публичную альфу Base UI 1.0 — библиотеку нестилизованных React-компонентов, выделенных из большого пакета Material UI и доступных теперь как отдельный продукт.
Помимо готовых компонентов в ней есть и низкоуровневые хуки, дающие всю мощь Material UI, но без необходимости реализовывать Material Design в приложении.
Полная свобода в стилях
Base UI не навязывает собственное решение для CSS. Вы сами выбираете, как работать: Tailwind, CSS-in-JS или любой другой способ.
Доступность (A11Y) по умолчанию
Компоненты соблюдают лучшие практики доступности. Это значит, что ваш проект будет удобен для всех, и никто не скажет, что вы плохой человек (кроме младшего брата).
Композиция
API компонентов открыто полностью. У вас есть доступ к каждому узлу, что позволяет легко добавлять, удалять или оборачивать элементы под свои нужды.
Base UI сохраняет лучшие части Material UI, не привязывая вас к "гугловскому" дизайну.
Вот это переиспользование, за которое не стыдно, котаны. Можно и младшему брату оставить.
Лучший подарок на Новый год!
#react #mui #ui #widgets
❤16👍5
#инструмент дня
Лучший API — это тот, который не пришлось писать самому! Потому так популярны и фреймворки, и сервисы вроде Firebase.
Но если охота чуть больше контроля над базой данных и своими ресурсами вообще, а писать код всё ещё неохота, рекомендую взглянуть на PostgREST. Это инструмент, который превращает вашу базу данных в полноценный REST API.
Почему это круто?
Мгновенный API Не нужно писать кучу эндпоинтов — PostgREST автоматически генерирует их на основе структуры вашей базы данных.
SQL вместо ORM Работаете напрямую с SQL-запросами, что дает максимальную гибкость и контроль над данными.
Авторизация и безопасность PostgREST использует роли PostgreSQL для управления доступом, избавляя от необходимости вручную прописывать логику авторизации. А процессы аутентификации и авторизации выстроены вокруг JWT.
Производительность Оптимизирован для работы с большими объемами данных, включая фильтрацию, пагинацию и сортировку.
Легкая интеграция
Подходит как для простых CRUD-операций, так и для сложной бизнес-логики через SQL-вьюхи или хранимые процедуры.
Возможно, он не решит всех проблем, но уж точно можно будет сильно сократить время разработки.
#postgres #api #service
Лучший API — это тот, который не пришлось писать самому! Потому так популярны и фреймворки, и сервисы вроде Firebase.
Но если охота чуть больше контроля над базой данных и своими ресурсами вообще, а писать код всё ещё неохота, рекомендую взглянуть на PostgREST. Это инструмент, который превращает вашу базу данных в полноценный REST API.
Почему это круто?
Мгновенный API Не нужно писать кучу эндпоинтов — PostgREST автоматически генерирует их на основе структуры вашей базы данных.
SQL вместо ORM Работаете напрямую с SQL-запросами, что дает максимальную гибкость и контроль над данными.
Авторизация и безопасность PostgREST использует роли PostgreSQL для управления доступом, избавляя от необходимости вручную прописывать логику авторизации. А процессы аутентификации и авторизации выстроены вокруг JWT.
Производительность Оптимизирован для работы с большими объемами данных, включая фильтрацию, пагинацию и сортировку.
Легкая интеграция
Подходит как для простых CRUD-операций, так и для сложной бизнес-логики через SQL-вьюхи или хранимые процедуры.
Возможно, он не решит всех проблем, но уж точно можно будет сильно сократить время разработки.
#postgres #api #service
🤩7❤4👍4👎2
This media is not supported in your browser
VIEW IN TELEGRAM
#фишка дня
Сейчас в CSS присутствует 54 разных единицы измерения (units).
Пятьдесят четыре!
А ты до сих пор используешь одни только пиксели aka px.
Так вот, используя единицу измерения
Прям как тут: https://codepen.io/alinaki/pen/xxMJXaV
Поиграйтесь с настройками и шириной блока, получается очень интересно. Автор красоты — Jhey.
А чтобы не запутаться — есть прекрасный ресурс https://whatunit.com/
На нём имеется диаграмма принятия решений, когда какую единицу брать. Если всё ещё непонятно, посмотрите видео от Kevin Powell: https://www.youtube.com/watch?v=Utc_uhvTluk
Он, кстати, автор диаграммы.
В общем, просыпаемся, котаны. Будущее здесь.
#css #rem #lh #vh #measure #бородач
Сейчас в CSS присутствует 54 разных единицы измерения (units).
Пятьдесят четыре!
А ты до сих пор используешь одни только пиксели aka px.
Так вот, используя единицу измерения
lh —
привязанную к line-height — и свойство background-clip,
можно, например, красиво подсветить нужное число строк в любом тексте.Прям как тут: https://codepen.io/alinaki/pen/xxMJXaV
Поиграйтесь с настройками и шириной блока, получается очень интересно. Автор красоты — Jhey.
А чтобы не запутаться — есть прекрасный ресурс https://whatunit.com/
На нём имеется диаграмма принятия решений, когда какую единицу брать. Если всё ещё непонятно, посмотрите видео от Kevin Powell: https://www.youtube.com/watch?v=Utc_uhvTluk
Он, кстати, автор диаграммы.
В общем, просыпаемся, котаны. Будущее здесь.
#css #rem #lh #vh #measure #бородач
1❤18👍7
Что ж, котаны. Пока я тут устраиваю себе некоторый отпуск, пришло время поблагодарить всех вас за то, что вы со мной и были со мной всё это время.
Особенно тех, кто посты читает
С наступающим Новым годом! Больше постов совсем скоро :)
К слову, вот тот самый популярный пост: https://t.iss.one/htmlshit/3049
Особенно тех, кто посты читает
С наступающим Новым годом! Больше постов совсем скоро :)
К слову, вот тот самый популярный пост: https://t.iss.one/htmlshit/3049
7❤38👍6
#статья дня
Так получилось, что я использовал матрицы преобразований — осмысленно — всего раз в жизни. Правда, в итоге перешёл на решение попроще: https://t.iss.one/htmlshit/1580
Но это не значит, что они не нужны :) Просто не у всех есть под них задачи.
А вот у Ивана Шубина — автора редактора диаграмм Schemio — такая задача возникла. Правда, осознал он это не сразу :)
Ну кто бы мог подумать, что тебе понадобятся матрицы преобразований, когда ты разрабатываешь векторный редактор, правда?
Прекрасная статья для тех, кто говорит, что программисту математика не нужна: https://itnext.io/how-i-used-linear-algebra-to-build-an-interactive-diagramming-editor-and-why-matrix-math-is-d5bd552f2e8d
Ну, точнее, линейная алгебра.
Есть перевод на русский: https://habr.com/ru/articles/870462/
Не, кроме шуток, просто шикарнейшая статья, после которой очень многое в работе с векторной (и не только) графикой станет понятно.
#svg #math #matrix #transform
Так получилось, что я использовал матрицы преобразований — осмысленно — всего раз в жизни. Правда, в итоге перешёл на решение попроще: https://t.iss.one/htmlshit/1580
Но это не значит, что они не нужны :) Просто не у всех есть под них задачи.
А вот у Ивана Шубина — автора редактора диаграмм Schemio — такая задача возникла. Правда, осознал он это не сразу :)
Ну кто бы мог подумать, что тебе понадобятся матрицы преобразований, когда ты разрабатываешь векторный редактор, правда?
Прекрасная статья для тех, кто говорит, что программисту математика не нужна: https://itnext.io/how-i-used-linear-algebra-to-build-an-interactive-diagramming-editor-and-why-matrix-math-is-d5bd552f2e8d
Ну, точнее, линейная алгебра.
Есть перевод на русский: https://habr.com/ru/articles/870462/
Не, кроме шуток, просто шикарнейшая статья, после которой очень многое в работе с векторной (и не только) графикой станет понятно.
#svg #math #matrix #transform
❤10🤩1
This media is not supported in your browser
VIEW IN TELEGRAM
#codepen дня
Что-то у меня чувство, что я с линейной алгеброй да на 29 декабря малость переборщил...
Давайте я вам две новогодние ёлочки, а вы мне всё простите?
🎄 Ксения Кондрашова подарила нам интерактивную ёлку на Three.js, вынесена в иллюстрацию: https://codepen.io/ksenia-k/pen/yyBYVyd
🎄 А Ана Тюдор — на чистом CSS: https://codepen.io/thebabydino/pen/bGwYVOm
На стороне какой ёлки вы?
#3d #threejs
Что-то у меня чувство, что я с линейной алгеброй да на 29 декабря малость переборщил...
Давайте я вам две новогодние ёлочки, а вы мне всё простите?
На стороне какой ёлки вы?
#3d #threejs
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍2
#инструмент дня
Когда вы последний раз дизассемблировали React Native приложение?
А я вчера.
Вот так вот решил закончить череду постов этото года лёгким хардкором. На полшишечки.
Давайте по порядку. Как вы все, должно быть, помните, я уже довольно давно пишу свой пульт для телевизора Samsung на Flutter.
Почему Samsung? Ну потому что он дома стоит.
И да, хоть это всё и происходит крайне медленно, минимальный набор функций имеется. Я постоянно им пользуюсь, когда нужно что-то переключить ребёнку или мне, а настоящий пульт искать лень.
Но у пары конкурентных приложений были функции, которые кажутся весьма уместными. И речь даже не о DLNA-стриминге фотографий и видео с телефона на телевизор, это-то как раз понятно и хорошо документированно.
А вот, например, такая простая штука, как получение списка всех приложений. Ну или, например, иные методы поиска телевизоров. В моём-то приложении список приложений и иконок к ним тупо захардкожен.
И не сказать, что я их не знаю — в начале разработки провёл огромную работу по поиску нужных API, но руки всё равно чесались.
И тут очень к месту пришлась возможность использования приложений для iPhone на макбуках с м-процессорами. Запускаешь приложение параллельно с Wireshark и мониторишь запросы. Очень удобно (на иллюстрации).
Но я не учёл такой простой вещи, как шифрование.
Да-да, практически все вебсокет-запросы оказались зашифрованы протоколом TLS 1.2 (
Кто бы мог подумать, а. Ведь я сам обходил это в своей имплементации: сертификаты на телевизорах свои, и, зачастую, протухшие давно.
Пусть это и не самый надёжный в 2024 году протокол, но всё же опыта расшифровки у меня нет. На самом-то деле в телевизорах есть и несекьюрные API, позволяющие даже запустить приложение, но они не всегда доступны без dev-режима. Да и нужного среди них не оказалось. А я так надеялся, что есть что-то простое.
Впрочем, строки поиска SSDP я себе выписал. LG, ты следующий.
Итак, но приложение же вот оно, лежит в каталоге Applications. А это что значит?
А это значит, можно посмотреть содержимое пакета! Да, если вы не знали, приложения в macOS и iOS (и на Android) это, по факту, просто архив.
Распаковав, я обнаружил подозрительный каталог node_modules и нечто под названием main.jsbundle.
Надо же, самый крутой конкурент оказался ни чем иным, как приложением на React Native!
А что я с ним делал дальше — напишу через несколько часов, иначе как-то длинно получается. Оставайтесь на связи :)
#remote #flutter #reactnative
Когда вы последний раз дизассемблировали React Native приложение?
А я вчера.
Вот так вот решил закончить череду постов этото года лёгким хардкором. На полшишечки.
Давайте по порядку. Как вы все, должно быть, помните, я уже довольно давно пишу свой пульт для телевизора Samsung на Flutter.
Почему Samsung? Ну потому что он дома стоит.
И да, хоть это всё и происходит крайне медленно, минимальный набор функций имеется. Я постоянно им пользуюсь, когда нужно что-то переключить ребёнку или мне, а настоящий пульт искать лень.
Но у пары конкурентных приложений были функции, которые кажутся весьма уместными. И речь даже не о DLNA-стриминге фотографий и видео с телефона на телевизор, это-то как раз понятно и хорошо документированно.
А вот, например, такая простая штука, как получение списка всех приложений. Ну или, например, иные методы поиска телевизоров. В моём-то приложении список приложений и иконок к ним тупо захардкожен.
И не сказать, что я их не знаю — в начале разработки провёл огромную работу по поиску нужных API, но руки всё равно чесались.
И тут очень к месту пришлась возможность использования приложений для iPhone на макбуках с м-процессорами. Запускаешь приложение параллельно с Wireshark и мониторишь запросы. Очень удобно (на иллюстрации).
Но я не учёл такой простой вещи, как шифрование.
Да-да, практически все вебсокет-запросы оказались зашифрованы протоколом TLS 1.2 (
wss://
).Кто бы мог подумать, а. Ведь я сам обходил это в своей имплементации: сертификаты на телевизорах свои, и, зачастую, протухшие давно.
Пусть это и не самый надёжный в 2024 году протокол, но всё же опыта расшифровки у меня нет. На самом-то деле в телевизорах есть и несекьюрные API, позволяющие даже запустить приложение, но они не всегда доступны без dev-режима. Да и нужного среди них не оказалось. А я так надеялся, что есть что-то простое.
Впрочем, строки поиска SSDP я себе выписал. LG, ты следующий.
Итак, но приложение же вот оно, лежит в каталоге Applications. А это что значит?
А это значит, можно посмотреть содержимое пакета! Да, если вы не знали, приложения в macOS и iOS (и на Android) это, по факту, просто архив.
Распаковав, я обнаружил подозрительный каталог node_modules и нечто под названием main.jsbundle.
Надо же, самый крутой конкурент оказался ни чем иным, как приложением на React Native!
А что я с ним делал дальше — напишу через несколько часов, иначе как-то длинно получается. Оставайтесь на связи :)
#remote #flutter #reactnative
👍19❤4🤩4
#инструмент дня
Несколько часов превратились в пару дней. Новый год, а что вы хотели.
Итак, мы остановились на том что конкуренты писали свой проект на React Native, с говорящим за себя файлом
И тут начинается самое интересное: этот бандл может оказаться как просто минифицированным JS-кодом, так и... байт-кодом Hermes!
Немного истории: React Native начинался с движка JSC aka JavaScriptCore. Но в Facebook решили, что производительности его JIT для замены нативных приложений явно недостаточно, и с 2019 года предложили альтернативу: виртуальную машину Hermes, в код которой и собирается ваш JavaScript.
Это ускоряет запуск приложений, особенно больших. В статье по ссылке много интересных подробностей.
Первым делом убеждаемся, что это именно Hermes:
Поиск по строкам внутри бинарника, прямо в mc, даёт нам искомое sendGetInstalledApps. Пришло время для дизассемблирования!
Идём в гугл, наверняка кто-то уже озадачился вопросом. И таки да! Встречайте: hermes-dec. Буквально, описание: «A reverse engineering tool for decompiling and disassembling the React Native Hermes bytecode». Звучит как нечто, нужное нам.
Забираем, пробуем установить:
...и получаем отлуп по
$ python3 hbc_disassembler.py ../../main.jsbundle bundle.hasm
И вот, красиво оформленный вывод ассемблера HASM, в котором все строковые данные и названия функций разнесены по блокам и расшифрованы!
И что же мы (внимание на иллюстрацию к посту) можем увидеть из такого вывода, даже не зная ассемблера?
Ну, достаточно много. Например, что тут формируется JSON для отправки телевизору, в котором присутствует метод
Не то, чтоб я об этом не знал! Но все эти API достаются обходными путями. Например, из SDK Tizen или из официальных приложений от Samsung и вендоров. Зачастую, очень важен формат: где-то
Что же дальше? А дальше я обратил внимание на метод
Впрочем, всегда можно просто бандлить иконки с собой.
Но давайте попробуем воспользоваться ещё одной возможностью hermes-dec: декомпиляцией. Ага, получаем JS-код обратно:
Ну и на самом деле что-то получили, вот только, выглядит оно как-то так:
Не сильно больше информации, чем в дизассемблированной версии :( Всё дело в том, что утилита пока не продвинулась дальше «плоских» вызовов и не разворачивает не то, что замыкания, но даже циклы. Впрочем, не мне жаловаться!
Итак, выводы: у разработчиков неофициальных клиентов под телевизоры не больше информации чем у меня или любого из вас, потому любое начинание — стоит того. Как минимум, это интересно! Иногда брутфорс реально рабочий метод, и его применение не должно вас смущать так, как смутило когда-то меня настолько, что я решил использовать захардкоженный список приложений.
Дерзайте, котаны! С Новым годом :)
Несколько часов превратились в пару дней. Новый год, а что вы хотели.
Итак, мы остановились на том что конкуренты писали свой проект на React Native, с говорящим за себя файлом
main.jsbundle
.И тут начинается самое интересное: этот бандл может оказаться как просто минифицированным JS-кодом, так и... байт-кодом Hermes!
Немного истории: React Native начинался с движка JSC aka JavaScriptCore. Но в Facebook решили, что производительности его JIT для замены нативных приложений явно недостаточно, и с 2019 года предложили альтернативу: виртуальную машину Hermes, в код которой и собирается ваш JavaScript.
Это ускоряет запуск приложений, особенно больших. В статье по ссылке много интересных подробностей.
Первым делом убеждаемся, что это именно Hermes:
$ file main.jsbundle
main.jsbundle: Hermes JavaScript bytecode, version 96
Поиск по строкам внутри бинарника, прямо в mc, даёт нам искомое sendGetInstalledApps. Пришло время для дизассемблирования!
Идём в гугл, наверняка кто-то уже озадачился вопросом. И таки да! Встречайте: hermes-dec. Буквально, описание: «A reverse engineering tool for decompiling and disassembling the React Native Hermes bytecode». Звучит как нечто, нужное нам.
Забираем, пробуем установить:
$ git clone [email protected]:P1sec/hermes-dec.git
$ cd hermes-dec/
$ python3 setup.py install
...и получаем отлуп по
python-installtools
. Впрочем, это быстро решается через brew
. Едем дальше, дизассемблируем:$ python3 hbc_disassembler.py ../../main.jsbundle bundle.hasm
И вот, красиво оформленный вывод ассемблера HASM, в котором все строковые данные и названия функций разнесены по блокам и расшифрованы!
И что же мы (внимание на иллюстрацию к посту) можем увидеть из такого вывода, даже не зная ассемблера?
Ну, достаточно много. Например, что тут формируется JSON для отправки телевизору, в котором присутствует метод
ms.channel.emit
и передаются данные: {'data': '', 'event': 'ed.installedApp.get', 'to': 'host'}
.Не то, чтоб я об этом не знал! Но все эти API достаются обходными путями. Например, из SDK Tizen или из официальных приложений от Samsung и вендоров. Зачастую, очень важен формат: где-то
data
должна быть null
, где-то — пустой объект или строка. Поиски нужных комбинаций откровенно раздражают.Что же дальше? А дальше я обратил внимание на метод
sendGetAppIcon
, который тоже виден на скриншоте. И до меня дошло: они реально отправляют запрос на список всех приложений, а потом — бомбят телевизор запросами об иконках. Не самый оптимальный способ получения информации, но другого нет. Впрочем, всегда можно просто бандлить иконки с собой.
Но давайте попробуем воспользоваться ещё одной возможностью hermes-dec: декомпиляцией. Ага, получаем JS-код обратно:
$ python3 hbc_decompiler.py ../../main.jsbundle main.js
Ну и на самом деле что-то получили, вот только, выглядит оно как-то так:
r4 = function() { // Original name: sendGetInstalledApps, environment: r3
r0 = global;
r2 = r0.JSON;
r1 = r2.stringify;
r0 = {};
r3 = 'ms.channel.emit';
r0['method'] = r3;
r3 = {'data': '', 'event': 'ed.installedApp.get', 'to': 'host'};
r0['params'] = r3;
r2 = r1.bind(r2)(r0);
r1 = _closure1_slot4;
r0 = r1.send;
r0 = r0.bind(r1)(r2);
r0 = undefined;
return r0;
};
Не сильно больше информации, чем в дизассемблированной версии :( Всё дело в том, что утилита пока не продвинулась дальше «плоских» вызовов и не разворачивает не то, что замыкания, но даже циклы. Впрочем, не мне жаловаться!
Итак, выводы: у разработчиков неофициальных клиентов под телевизоры не больше информации чем у меня или любого из вас, потому любое начинание — стоит того. Как минимум, это интересно! Иногда брутфорс реально рабочий метод, и его применение не должно вас смущать так, как смутило когда-то меня настолько, что я решил использовать захардкоженный список приложений.
Дерзайте, котаны! С Новым годом :)
❤12👍4🤩2
This media is not supported in your browser
VIEW IN TELEGRAM
#инструмент дня
Я вот просто оставлю это здесь и не буду говорить, сколько попыток у меня заняло прохождение, ок? :)
Вообще, конечно, максимально угарная тема. DOOM-Captcha! Когда хорошему разработчику делать нечего — он DOOM портирует.
Сразу ссылка для нетерпеливых: https://doom-captcha.vercel.app/
Ну и на GitHub: https://github.com/rauchg/doom-captcha
Скомпилировано из C в WebAssembly с помощью Emscripten. Ну, кто первый добавит возможность управления не только стрелочками, но и WASD, котаны?
#doom
Я вот просто оставлю это здесь и не буду говорить, сколько попыток у меня заняло прохождение, ок? :)
Вообще, конечно, максимально угарная тема. DOOM-Captcha! Когда хорошему разработчику делать нечего — он DOOM портирует.
Сразу ссылка для нетерпеливых: https://doom-captcha.vercel.app/
Ну и на GitHub: https://github.com/rauchg/doom-captcha
Скомпилировано из C в WebAssembly с помощью Emscripten. Ну, кто первый добавит возможность управления не только стрелочками, но и WASD, котаны?
#doom
👍14🤩3❤1