Как сделать «Избранное» средствами Laravel и Vue.js

Как сделать "Избранное" средствами Laravel и Vue.js

В наше время большинство сайтов используют функционал избранного/лайков/рекомендаций. В том числе такие крупные ресурсы, как Medium, Facebook, Вконтакте и т.д.

Мы рассмотрим как реализовать такой функционал с Vue.js в приложении Laravel. Это приложение будет типа персонального блога, в нём будут пользователи и статьи. Пользователи смогут создавать статьи и добавлять их в избранное. А также пользователи смогут видеть полный список избранных статей.

В приложении будут модель User (Пользователь) и модель Post (Статья), в нём будет система авторизации, которая позволит добавлять статьи в Избранное (и удалять из него) только авторизованным пользователям. Мы сделаем динамическую пометку в избранное средствами VueJs и Axios, т.е. без перезагрузки страницы.

Перед началом работы посмотрите как это будет выглядеть:

Как сделать "Избранное" средствами Laravel и Vue.js

Итак, приступим.

Мы начнём с создания нового проекта Laravel:

laravel new laravel-vue-favorite
В результате будет создан проект с именем «laravel-vue-favorite»

С Laravel идут дополнительные библиотеки, такие как Bootstrap, VueJs и Axios, однако нужно их установить с помощью npm:

npm install
Также эта команда установит Laravel Mix, с помощью которого мы будем компилировать и собирать наши CSS и JavaScript.

Модели, миграции

Итак, нам необходима модель User (она идёт с Laravel), модель Post и модель Favorite, а также файлы миграции для них.

php artisan make:model Post -m
php artisan make:model Favorite -m

Эти команды создадут нужные нам модели вместе с миграциями. Откроем файл миграции таблицы posts и обновим метод up():

/**
* Define posts table schema
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('title');
$table->text('body');
$table->timestamps();
});
}

Таблица posts будет содержать id, user_id (ID пользователя, создавшего статью), title, body и колонки с отметками времени.

Теперь откроем файл миграций таблицы favorites и обновим up():

/**
* Define favorites table schema
*/
public function up()
{
Schema::create('favorites', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('post_id')->unsigned();
$table->timestamps();
});
}

Таблица favorites будет сводной. В ней будет две колонки:
user_id, в которой будет храниться ID пользователя, добавившего статью в избранное и post_id, в которой будет ID отмеченной статьи.

Файл миграции таблицы users оставим без изменений.

Перед запуском миграций настроим базу данных. Для этого добавим соответствующие настройки в файл .env:

DB_DATABASE=laravue
DB_USERNAME=root
DB_PASSWORD=root

Здесь нужно указать свои параметры базы.

Теперь запустим миграции:

php artisan migrate

Для тестирования работы приложения нам необходимо внести в него какие-либо данные. Для их генерации воспользуемся Laravel Model Factories, они же в свою очередь используют Faker PHP library.

Сгенерируем данные по Пользователям и Статьям. Добавим немного кода в конец файла database/factories/ModelFactory.php:

// database/factories/ModelFactory.php

$factory->define(App\Post::class, function (Faker\Generator $faker) {
// Get a random user
$user = \App\User::inRandomOrder()->first();

// generate fake data for post
return [
'user_id' => $user->id,
'title' => $faker->sentence,
'body' => $faker->text,
];
});

После этого перейдём к созданию классов заполнения базы:

php artisan make:seeder UsersTableSeeder
php artisan make:seeder PostsTableSeeder

Теперь откроем database/seeds/UsersTableSeeder.php и обновим метод run():

// database/seeds/UsersTableSeeder.php

/**
* Run the database seeds to create users.
*
* @return void
*/
public function run()
{
factory(App\User::class, 5)->create();
}

В результате будут созданы 5 различных пользователей. Сделаем то же самое со статьями. Откроем database/seeds/PostsTableSeeder.php и обновим run():

// database/seeds/PostsTableSeeder.php

/**
* Run the database seeds to create posts.
*
* @return void
*/
public function run()
{
factory(App\Post::class, 10)->create();
}

В результате будут созданы 10 различных статей по окончании работы скрипта.

Перед запуском генераторов данных обновим файл database/seeds/DatabaseSeeder.php:

// database/seeds/DatabaseSeeder.php

/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$this->call(UsersTableSeeder::class);
$this->call(PostsTableSeeder::class);
}

И запустим генерацию данных:

php artisan db:seed
Готово.

Авторизация

К счастью, в Laravel уже есть встроенная система авторизации. Нужно только запустить соответствующего мастера:

php artisan make:auth
Будут созданы необходимые роуты и представления для авторизации и нам остаётся только зарегистрироваться в системе.

Роуты

Откроем файл routes/web.php и изменим маршруты:

// routes/web.php

Auth::routes();

Route::get('/', 'PostsController@index');

Route::post('favorite/{post}', 'PostsController@favoritePost');
Route::post('unfavorite/{post}', 'PostsController@unFavoritePost');

Route::get('my_favorites', 'UsersController@myFavorites')->middleware('auth');
После регистрации или авторизации пользователя Laravel перенаправит его на роут /home по-умолчанию. Мы удалили роут /home, созданный при запуске make:auth и поэтому нужно обновить свойство redirectTo в обоих файлах app/Http/Controllers/Auth/LoginController.php и app/Http/Controllers/Auth/RegisterController.php на:

protected $redirectTo = '/';

Отношения Пользователь-Избранное

Пользователь может добавить много статей в избранное, а статья может быть добавлена в избранное многими пользователями, поэтому отношения между этими таблицами будут многие-ко-многим. Для этого откроем модель User и добавим favorites():

// app/User.php

/**
* Get all of favorite posts for the user.
*/
public function favorites()
{
return $this->belongsToMany(Post::class, 'favorites', 'user_id', 'post_id')->withTimeStamps();
}

Laravel считает сводной таблицей post_user, но так как мы её переименовали (в favorites), нам нужно передать дополнительные параметры. Вторым параметром идёт имя сводной таблицы. Третьим — внешний ключ (user_id) модели, с которой создаётся связь (User), а четвёртым — внешний ключ (post_id) модели, к которой мы присоединяем (Post).

Обратите внимание, мы связали withTimeStamps() с belongsToMany(). Это позволит колонкам сводной таблицы с отметками времени (create_at и updated_at) автоматически сработать при добавлении или обновлении строки.

Контроллер статей

Создадим новый контроллер, в котором будут функции вывода статей, пометки в избранное и удаление такой отметки.

php artisan make:controller PostsController
Откроем app/Http/Controllers/PostsController.php и добавим в конец такой код:

// app/Http/Controllers/PostsController.php

// remember to use the Post model
use App\Post;

/**
* Display a paginated list of posts.
*
* @return Response
*/
public function index()
{
$posts = Post::paginate(5);

return view('posts.index', compact('posts'));
}

Метод index() вернёт все статьи и разделит их по 5 на странице, а затем обработает файл представления (который мы создадим) со всеми статьями.

Добавим в файл resources/views/layouts/app.blade.php (пониже ) такой код:</p> <p><code>// resources/views/layouts/app.blade.php</p> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" /></code><br /> А затем это перед элементом списка Logout:</p> <p><code>// resources/views/layouts/app.blade.php</p> <li> <a href="{{ url('my_favorites') }}">My Favorites</a> </li> <p></code><br /> Теперь создадим представление index. Создайте папку posts внутри views и в ней файл index.blade.php. Получится resources/views/posts/index.blade.php:</p> <p><code>// resources/views/posts/index.blade.php</p> <p>@extends('layouts.app')</p> <p>@section('content')</p> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="page-header"> <h3>All Posts</h3> </p></div> <p> @forelse ($posts as $post)</p> <div class="panel panel-default"> <div class="panel-heading"> {{ $post->title }} </div> <div class="panel-body"> {{ $post->body }} </div> </p></div> <p> @empty</p> <p>No post created.</p> <p> @endforelse</p> <p> {{ $posts->links() }} </p></div> </p></div> </div> <p>@endsection</code><br /> Откройте браузер и увидите такую страничку:</p> <p><img title="Как сделать "Избранное" средствами Laravel и Vue.js" src="https://tehnojam.pro/uploads/images/00/00/24/2017/03/07/f7e0763e8d.png" class="image-center" alt="Как сделать "Избранное" средствами Laravel и Vue.js" /></p> <p>Вернёмся к PostsController и добавим недостающие методы:</p> <p><code>// app/Http/Controllers/PostsController.php</p> <p>// remember to use<br /> use Illuminate\Support\Facades\Auth;</p> <p>/**<br /> * Favorite a particular post<br /> *<br /> * @param Post $post<br /> * @return Response<br /> */<br /> public function favoritePost(Post $post)<br /> {<br /> Auth::user()->favorites()->attach($post->id);</p> <p> return back();<br /> }</p> <p>/**<br /> * Unfavorite a particular post<br /> *<br /> * @param Post $post<br /> * @return Response<br /> */<br /> public function unFavoritePost(Post $post)<br /> {<br /> Auth::user()->favorites()->detach($post->id);</p> <p> return back();<br /> }</code></p> <h5>Добавляем VueJs</h5> <p>С помощью Vue мы сделаем кнопку Избранного. По нажатию на неё, статья добавиться в избранное (или удалится из избранного) без перезагрузки страницы, используя AJAX. Здесь нам пригодится Axios — основанный на Promise HTTP-клиент для браузера и node.js.</p> <p>Создадим компонент Vue, для этого создайте файл Favorite.vue в папке resources/assets/js/components с таким содержимым:</p> <p><code>// resources/assets/js/components/Favorite.vue</p> <p><template><br /> <span><br /> <a href="#" v-if="isFavorited" @click.prevent="unFavorite(post)"><br /> <i class="fa fa-heart"></i><br /> </a><br /> <a href="#" v-else @click.prevent="favorite(post)"><br /> <i class="fa fa-heart-o"></i><br /> </a><br /> </span><br /> </template></p> <p><script> export default { props: ['post', 'favorited'],</p> <p> data: function() { return { isFavorited: '', } },</p> <p> mounted() { this.isFavorited = this.isFavorite ? true : false; },</p> <p> computed: { isFavorite() { return this.favorited; }, },</p> <p> methods: { favorite(post) { axios.post('/favorite/'+post) .then(response => this.isFavorited = true) .catch(response => console.log(response.data)); },</p> <p> unFavorite(post) { axios.post('/unfavorite/'+post) .then(response => this.isFavorited = false) .catch(response => console.log(response.data)); } } } </script></code><br /> В компоненте Favorite есть два раздела: template и script. В template мы задали разметку, которая будет обработана при вызове компонента. Мы используем обработку с условием, она нам должна вывести нужную кнопку. То есть если isFavorited равно true, кнопка должна быть отмечена как избранная и при нажатии вызвать unFavorite(). В противном случае она выглядит как не помеченная и вызывает при клике метод favorite().</p> <p>В разделе script мы задали свойства компонента — post (тут будет ID статьи) и favorited (true или false в зависимости от того, в каком он состоянии для текущего авторизованного пользователя). Также мы задали переменную isFavorited для условной обработки шаблона.</p> <p>При подключении компонента мы задаём значение isFavorited равным рассчитанному свойству isFavorite. То есть свойство isFavorite вернёт значение свойства favorited, которое может быть true или false.</p> <p>Также мы создали два метода: favorite() и unFavorite(), оба принимающие post как аргумент. С помощью Axios мы делаем POST-запрос к заданным ранее роутам. В favorite(), при успешном POST-запросе, мы задаём isFavorited в true, иначе выводим ошибку в консоль. То же самое и для unFavorite() — только меняем isFavorited на false.</p> <h5>Регистрация компонента</h5> <p>Перед использованием компонента необходимо зарегистрировать его в экземпляре Vue. Открыв resources/assets/js/app.js вы увидите, что Laravel зарегистрировал компонент Example. Заменим его на наш Favorite:</p> <p><code>// resources/assets/js/app.js</p> <p>Vue.component('favorite', require('./components/Favorite.vue'));</code><br /> Теперь скомпилируем и соберём наши стили и скрипты:</p> <p><code>npm run dev</code></p> <p>Теперь можно использовать наш компонент. Откроем resources/views/posts/index.blade.php и добавим в конец (после закрывающего div в panel-body) такой код:</p> <p><code>// resources/views/posts/index.blade.php</p> <p>@if (Auth::check())</p> <div class="panel-footer"> <favorite :post={{ $post->id }}<br /> :favorited={{ $post->favorited() ? 'true' : 'false' }}<br /> ></favorite> </div> <p>@endif</code><br /> Теперь кнопка добавления в избранное будет показана только авторизованным пользователям. А чтобы узнать, добавлена ли статья в избранное, нужен метод favorited(), который мы и создадим. Откройте app/Post.php и добавьте код:</p> <p><code>// app/Post.php</p> <p>// remember to use<br /> use App\Favorite;<br /> use Illuminate\Support\Facades\Auth;</p> <p>/**<br /> * Determine whether a post has been marked as favorite by a user.<br /> *<br /> * @return boolean<br /> */<br /> public function favorited()<br /> {<br /> return (bool) Favorite::where('user_id', Auth::id())<br /> ->where('post_id', $this->id)<br /> ->first();<br /> }</code><br /> Здесь мы получаем и приводим к булеву первую строку запроса, где user_id это идентификатор текущего пользователя, а post_id это идентификатор статьи, с которой мы работаем сейчас.</p> <p>Теперь наше приложение будет выглядеть так:</p> <p><img title="Как сделать "Избранное" средствами Laravel и Vue.js" src="https://tehnojam.pro/uploads/images/00/00/24/2017/03/07/4889091451.png" class="image-center" alt="Как сделать "Избранное" средствами Laravel и Vue.js" /></p> <h5>Вывод избранного</h5> <p>Для вывода избранных статей мы создали ранее роут my_favorites, доступный только авторизованным пользователям. </p> <p>Создадим UsersController, обрабатывающий этот роут:</p> <p><code>php artisan make:controller UsersController</code><br /> Теперь откроем app/Http/Controllers/UsersController.php и добавим код:</p> <p><code>// app/Http/Controllers/UsersController.php</p> <p>// remember to use<br /> use Illuminate\Support\Facades\Auth;</p> <p>/**<br /> * Get all favorite posts by user<br /> *<br /> * @return Response<br /> */<br /> public function myFavorites()<br /> {<br /> $myFavorites = Auth::user()->favorites;</p> <p> return view('users.my_favorites', compact('myFavorites'));<br /> }</code><br /> Теперь создадим представление. Создайте папку users в resources/views, а в ней файл my_favorites.blade.php:</p> <p><code>// resources/views/users/my_favorites.blade.php</p> <p>@extends('layouts.app')</p> <p>@section('content')</p> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="page-header"> <h3>My Favorites</h3> </p></div> <p> @forelse ($myFavorites as $myFavorite)</p> <div class="panel panel-default"> <div class="panel-heading"> {{ $myFavorite->title }} </div> <div class="panel-body"> {{ $myFavorite->body }} </div> <p> @if (Auth::check())</p> <div class="panel-footer"> <favorite :post={{ $myFavorite->id }}<br /> :favorited={{ $myFavorite->favorited() ? 'true' : 'false' }}<br /> ></favorite> </div> <p> @endif </p></div> <p> @empty</p> <p>You have no favorite posts.</p> <p> @endforelse </p></div> </p></div> </div> <p>@endsection</code></p> <p><img title="Как сделать "Избранное" средствами Laravel и Vue.js" src="https://tehnojam.pro/uploads/images/00/00/24/2017/03/08/6ee53a54ea.png" class="image-center" alt="Как сделать "Избранное" средствами Laravel и Vue.js" /></p> <p>Готово! </p> <p><a href="https://github.com/ammezie/laravel-vue-favorite" target="_blank">Полный код примера.</a></p> <p>По материалам «Implement a Favoriting Feature Using Laravel and Vue.js» by Chimezie Enyinnaya</p> <div class="flat_pm_end"></div> <div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-gravatar"><img title="Как сделать "Избранное" средствами Laravel и Vue.js" alt="Как сделать "Избранное" средствами Laravel и Vue.js" alt='' src='https://secure.gravatar.com/avatar/3c9a724edc3d5745342294aed20872a8?s=100&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/3c9a724edc3d5745342294aed20872a8?s=200&d=mm&r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://tehnojam.pro/category/author/fokusov" class="vcard author" rel="author" itemprop="url"><span class="fn" itemprop="name">Фокусов Игорь</span></a></div><div class="saboxplugin-desc"><div itemprop="description"><p>Разработчик: java, kotlin, c#, javascript, dart, 1C, python, php.</p> <p>Пишите: <a href="https://t.me/ighar">@ighar</a>. <a href="https://money.yandex.ru/to/410011020365993">Buy me a coffee, please</a> :).</p> </div></div><div class="clearfix"></div><div class="saboxplugin-socials "><a target="_self" href="mailto:igor@fokusov.com" rel="nofollow" class="saboxplugin-icon-grey"><svg aria-hidden="true" class="sab-user_email" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z"></path></svg></span></a></div></div><div class="post-views post-365 entry-meta"> <span class="post-views-icon fa fa-eye"></span> <span class="post-views-count">0</span> </div> </div><!-- .entry-content --> <div id="post-ratings-365" class="post-ratings" itemscope itemtype="http://schema.org/Article" data-nonce="c146cb8ae6"><img id="rating_365_1" src="https://tehnojam.pro/wp-content/plugins/wp-postratings/images/rating_off.svg" alt="Звёзд: 1" title="Звёзд: 1" onmouseover="current_rating(365, 1, 'Звёзд: 1');" onmouseout="ratings_off(0, 0, 0);" onclick="rate_post();" onkeypress="rate_post();" style="cursor: pointer; border: 0px;" /><img id="rating_365_2" src="https://tehnojam.pro/wp-content/plugins/wp-postratings/images/rating_off.svg" alt="Звёзд: 2" title="Звёзд: 2" onmouseover="current_rating(365, 2, 'Звёзд: 2');" onmouseout="ratings_off(0, 0, 0);" onclick="rate_post();" onkeypress="rate_post();" style="cursor: pointer; border: 0px;" /><img id="rating_365_3" src="https://tehnojam.pro/wp-content/plugins/wp-postratings/images/rating_off.svg" alt="" title="" onmouseover="current_rating(365, 3, '');" onmouseout="ratings_off(0, 0, 0);" onclick="rate_post();" onkeypress="rate_post();" style="cursor: pointer; border: 0px;" /><img id="rating_365_4" src="https://tehnojam.pro/wp-content/plugins/wp-postratings/images/rating_off.svg" alt="" title="" onmouseover="current_rating(365, 4, '');" onmouseout="ratings_off(0, 0, 0);" onclick="rate_post();" onkeypress="rate_post();" style="cursor: pointer; border: 0px;" /><img id="rating_365_5" src="https://tehnojam.pro/wp-content/plugins/wp-postratings/images/rating_off.svg" alt="" title="" onmouseover="current_rating(365, 5, '');" onmouseout="ratings_off(0, 0, 0);" onclick="rate_post();" onkeypress="rate_post();" style="cursor: pointer; border: 0px;" /> (Пока оценок нет)<br /><span class="post-ratings-text" id="ratings_365_text"></span><meta itemprop="headline" content="Как сделать «Избранное» средствами Laravel и Vue.js" /><meta itemprop="description" content=" В наше время большинство сайтов используют функционал избранного/лайков/рекомендаций. В том числе такие крупные ресурсы, как Medium, Facebook, Вконтакте и т.д. Мы рассмотрим как реализовать так..." /><meta itemprop="datePublished" content="2017-03-08T00:03:33+00:00" /><meta itemprop="dateModified" content="2018-10-18T11:44:47+00:00" /><meta itemprop="url" content="https://tehnojam.pro/category/development/kak-sdelat-izbrannoe-sredstvami-laravel-i-vue_js.html" /><meta itemprop="author" content="Фокусов Игорь" /><meta itemprop="mainEntityOfPage" content="https://tehnojam.pro/category/development/kak-sdelat-izbrannoe-sredstvami-laravel-i-vue_js.html" /><div style="display: none;" itemprop="publisher" itemscope itemtype="https://schema.org/Organization"><meta itemprop="name" content="Техноджем" /><div itemprop="logo" itemscope itemtype="https://schema.org/ImageObject"><meta itemprop="url" content="" /></div></div></div><div id="post-ratings-365-loading" class="post-ratings-loading"> <img src="https://tehnojam.pro/wp-content/plugins/wp-postratings/images/loading.gif" width="16" height="16" class="post-ratings-image" /> Загрузка...</div> <footer class="entry-meta"> <span class="cat-links"><span class="screen-reader-text">Categories </span><a href="https://tehnojam.pro/category/category/development" rel="category tag">Разработка</a></span> <nav id="nav-below" class="post-navigation"> <span class="screen-reader-text">Post navigation</span> <div class="nav-previous"><span class="prev" title="Previous"><a href="https://tehnojam.pro/category/technologies/torgovye-vojny-vokrug-nesushestvujushih-kvantovyh-kompjuterov.html" rel="prev">Торговые войны вокруг несуществующих квантовых компьютеров</a></span></div><div class="nav-next"><span class="next" title="Next"><a href="https://tehnojam.pro/category/secure/obnarodovannye-sekretnye-fajly-tsru-podrobno-opisyvajut-instrumenty-dlja-vzloma-iphone-android-smart-televizorov.html" rel="next">Обнародованные секретные файлы ЦРУ подробно описывают инструменты для взлома iPhone, Android, смарт-телевизоров</a></span></div> </nav><!-- #nav-below --> </footer><!-- .entry-meta --> </div><!-- .inside-article --> </article><!-- #post-## --> <div class="comments-area"> <div id="comments"> <div id="respond" class="comment-respond"> <h3 id="reply-title" class="comment-reply-title">Leave a Comment <small><a rel="nofollow" id="cancel-comment-reply-link" href="/category/development/kak-sdelat-izbrannoe-sredstvami-laravel-i-vue_js.html#respond" style="display:none;">Отменить ответ</a></small></h3> <form action="https://tehnojam.pro/wp-comments-post.php" method="post" id="commentform" class="comment-form" novalidate> <p class="comment-form-comment"><label for="comment" class="screen-reader-text">Comment</label><textarea id="comment" name="comment" cols="45" rows="8" aria-required="true"></textarea></p><label for="author" class="screen-reader-text">Name</label><input placeholder="Name *" id="author" name="author" type="text" value="" size="30" /> <label for="email" class="screen-reader-text">Email</label><input placeholder="Email *" id="email" name="email" type="email" value="" size="30" /> <label for="url" class="screen-reader-text">Website</label><input placeholder="Website" id="url" name="url" type="url" value="" size="30" /> <div class="gglcptch gglcptch_v2"><div id="gglcptch_recaptcha_964206724" class="gglcptch_recaptcha"></div> <noscript> <div style="width: 302px;"> <div style="width: 302px; height: 422px; position: relative;"> <div style="width: 302px; height: 422px; position: absolute;"> <iframe src="https://www.google.com/recaptcha/api/fallback?k=6LdLqnYUAAAAAKcMT7b_RIlsSEvVHpIWIBaI6X-x" frameborder="0" scrolling="no" style="width: 302px; height:422px; border-style: none;"></iframe> </div> </div> <div style="border-style: none; bottom: 12px; left: 25px; margin: 0px; padding: 0px; right: 25px; background: #f9f9f9; border: 1px solid #c1c1c1; border-radius: 3px; height: 60px; width: 300px;"> <textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px !important; height: 40px !important; border: 1px solid #c1c1c1 !important; margin: 10px 25px !important; padding: 0px !important; resize: none !important;"></textarea> </div> </div> </noscript></div><p class="form-submit"><input name="submit" type="submit" id="submit" class="submit" value="Post Comment" /> <input type='hidden' name='comment_post_ID' value='365' id='comment_post_ID' /> <input type='hidden' name='comment_parent' id='comment_parent' value='0' /> </p><p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="a5d4e278b1" /></p><p style="display: none;"><input type="hidden" id="ak_js" name="ak_js" value="44"/></p> </form> </div><!-- #respond --> </div><!-- #comments --> </div> </main><!-- #main --> </div><!-- #primary --> <div id="right-sidebar" itemtype="https://schema.org/WPSideBar" itemscope="itemscope" class="widget-area grid-25 tablet-grid-25 grid-parent sidebar"> <div class="inside-right-sidebar"> <aside id="social_icon_widget-2" class="widget inner-padding widget_social_icon_widget"><h2 class="widget-title">Подпишись на нас</h2><a title="Twitter" target="_blank" href="https://twitter.com/tehnojampro"><i class="fa fa-twitter"></i></a><a title="Facebook" target="_blank" href="https://www.facebook.com/tehnojam"><i class="fa fa-facebook"></i></a><a title="Google Plus" target="_blank" href="https://plus.google.com/communities/101049307081024540315"><i class="fa fa-google-plus"></i></a><a title="Telegram" target="_blank" href="http://t.me/tehnojam"><i class="fa fa-telegram"></i></a><a title="VK" target="_blank" href="https://vk.com/tehnojam"><i class="fa fa-vk"></i></a></aside><aside id="custom_html-4" class="widget_text widget inner-padding widget_custom_html"><h2 class="widget-title">Реклама</h2><div class="textwidget custom-html-widget"><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- Медийка справа в виджете --> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-5559417666721130" data-ad-slot="9069015476" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script></div></aside><aside id="categories-2" class="widget inner-padding widget_categories"><h2 class="widget-title">Категории</h2> <ul> <li class="cat-item cat-item-113"><a href="https://tehnojam.pro/category/category/it-comics" title="В Этой категории размещаются юморные картинки и комиксы из мира IT">IT Комиксы</a> </li> <li class="cat-item cat-item-1"><a href="https://tehnojam.pro/category/category/%d0%b1%d0%b5%d0%b7-%d1%80%d1%83%d0%b1%d1%80%d0%b8%d0%ba%d0%b8" >Без рубрики</a> </li> <li class="cat-item cat-item-12"><a href="https://tehnojam.pro/category/category/secure" title="В этой категории размещаются статьи о компьютерной и интернет безопасности">Безопасность</a> </li> <li class="cat-item cat-item-8"><a href="https://tehnojam.pro/category/category/hardware" title="Категория о компьютерном железе, презентации нового оборудования и обсуждения старого оборудования.">Железо</a> </li> <li class="cat-item cat-item-10"><a href="https://tehnojam.pro/category/category/internet-of-things" title="Интернет вещей всё плотнее входит в нашу жизнь, потому эта рубрика об этом.">Интернет вещей</a> </li> <li class="cat-item cat-item-9"><a href="https://tehnojam.pro/category/category/back-to-the-future" title="Статьи о новейших технологиях">Назад в будущее</a> </li> <li class="cat-item cat-item-6"><a href="https://tehnojam.pro/category/category/it-news" title="Здесь размещаются Новости мира информационных технологий">Новости IT</a> </li> <li class="cat-item cat-item-5"><a href="https://tehnojam.pro/category/category/development" title="Статьи так или иначе касающиеся разработки программного обеспечения. Здесь размещаются мануалы и практическое руководство мира разработки.">Разработка</a> </li> <li class="cat-item cat-item-4"><a href="https://tehnojam.pro/category/category/software" title="Категория со статьями о программном обеспечении">Софт</a> </li> <li class="cat-item cat-item-11"><a href="https://tehnojam.pro/category/category/itagregator" >Техноагрегатор</a> </li> <li class="cat-item cat-item-7"><a href="https://tehnojam.pro/category/category/technologies" title="Статьи о новых технологиях и инновациях">Технологии</a> </li> </ul> </aside><aside id="better_recent_comments-2" class="widget inner-padding widget_recent_comments"><h2 class="widget-title">Свежие комментарии</h2><ul id="better-recent-comments" class="recent-comments-list with-avatars"><li class="recentcomments recent-comment"><div class="comment-wrap" style="padding-left:50px; min-height:44px;"><span class="comment-avatar"><img alt='' src='https://secure.gravatar.com/avatar/4fd43f7a008027b5a85a9c8bb0c0b4a3?s=40&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/4fd43f7a008027b5a85a9c8bb0c0b4a3?s=80&d=mm&r=g 2x' class='avatar avatar-40 photo' height='40' width='40' /></span> <span class="comment-author-link">Владимир</span> on <span class="comment-post"><a href="https://tehnojam.pro/category/software/chuvak-kak-sdelat-dorvej.html#comment-412">Чувак, как сделать дорвей?</a></span></div></li><li class="recentcomments recent-comment"><div class="comment-wrap" style="padding-left:50px; min-height:44px;"><span class="comment-avatar"><img alt='' src='https://secure.gravatar.com/avatar/0c40ffbd3645e1b4478470fe161e91cf?s=40&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/0c40ffbd3645e1b4478470fe161e91cf?s=80&d=mm&r=g 2x' class='avatar avatar-40 photo' height='40' width='40' /></span> <span class="comment-author-link"><a href='https://t.me/Doorway4ik' rel='external nofollow' class='url'>manjarqo</a></span> on <span class="comment-post"><a href="https://tehnojam.pro/category/software/1c-dlja-mac-os-ili-kak-ja-ushel-ot-windows-i-linux.html#comment-411">1C для Mac OS или как я ушёл от Windows и Linux</a></span></div></li><li class="recentcomments recent-comment"><div class="comment-wrap" style="padding-left:50px; min-height:44px;"><span class="comment-avatar"><img alt='' src='https://secure.gravatar.com/avatar/01109dc6faaac5470d9c1955a8384c77?s=40&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/01109dc6faaac5470d9c1955a8384c77?s=80&d=mm&r=g 2x' class='avatar avatar-40 photo' height='40' width='40' /></span> <span class="comment-author-link">Сергей</span> on <span class="comment-post"><a href="https://tehnojam.pro/category/software/1c-dlja-mac-os-ili-kak-ja-ushel-ot-windows-i-linux.html#comment-410">1C для Mac OS или как я ушёл от Windows и Linux</a></span></div></li><li class="recentcomments recent-comment"><div class="comment-wrap" style="padding-left:50px; min-height:44px;"><span class="comment-avatar"><img alt='' src='https://secure.gravatar.com/avatar/638cff68bc8b1bdb02d20c74a7c9097e?s=40&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/638cff68bc8b1bdb02d20c74a7c9097e?s=80&d=mm&r=g 2x' class='avatar avatar-40 photo' height='40' width='40' /></span> <span class="comment-author-link">Andrey</span> on <span class="comment-post"><a href="https://tehnojam.pro/category/software/delaem-vyvod-zvuka-na-dva-ustrojstva-linux_windows.html#comment-406">Делаем вывод звука на два устройства (Linux,Windows, Mac OS X)</a></span></div></li><li class="recentcomments recent-comment"><div class="comment-wrap" style="padding-left:50px; min-height:44px;"><span class="comment-avatar"><img alt='' src='https://secure.gravatar.com/avatar/62fb696295b595ebfb83e4df903cf085?s=40&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/62fb696295b595ebfb83e4df903cf085?s=80&d=mm&r=g 2x' class='avatar avatar-40 photo' height='40' width='40' /></span> <span class="comment-author-link">Viktor</span> on <span class="comment-post"><a href="https://tehnojam.pro/category/software/esli-treshit-zvuk-v-hackintosh-i-speshat-chasy.html#comment-399">Eсли трещит звук в hackintosh и спешат часы</a></span></div></li><li class="recentcomments recent-comment"><div class="comment-wrap" style="padding-left:50px; min-height:44px;"><span class="comment-avatar"><img alt='' src='https://secure.gravatar.com/avatar/0cac5b32966eaea613c5c04553c315b5?s=40&d=mm&r=g' srcset='https://secure.gravatar.com/avatar/0cac5b32966eaea613c5c04553c315b5?s=80&d=mm&r=g 2x' class='avatar avatar-40 photo' height='40' width='40' /></span> <span class="comment-author-link">Nikolay</span> on <span class="comment-post"><a href="https://tehnojam.pro/category/software/delaem-krasivye-shrifty-s-novym-freetype2-v-linux.html#comment-396">Делаем красивые шрифты с новым freetype2 в Linux</a></span></div></li></ul></aside><aside id="recent-posts-widget-with-thumbnails-2" class="widget inner-padding recent-posts-widget-with-thumbnails"><div id="rpwwt-recent-posts-widget-with-thumbnails-2" class="rpwwt-widget"> <h2 class="widget-title">Свежие записи</h2> <ul> <li><a href="https://tehnojam.pro/category/%d0%b1%d0%b5%d0%b7-%d1%80%d1%83%d0%b1%d1%80%d0%b8%d0%ba%d0%b8/kuda-ja-propal.html"><img width="70" height="70" src="https://tehnojam.pro/wp-content/uploads/2019/03/ooz3njvtpb8-150x150.jpg" class="attachment-70x70 size-70x70 wp-post-image" alt="" /><span class="rpwwt-post-title">Куда я пропал</span></a></li> <li><a href="https://tehnojam.pro/category/software/3-krutie-programmy-pc.html"><img width="70" height="70" src="https://tehnojam.pro/wp-content/uploads/2019/02/musthaveprilojeniya-150x150.jpg" class="attachment-70x70 size-70x70 wp-post-image" alt="" /><span class="rpwwt-post-title">Три маст хэв программы для Windows 10 и не только</span></a></li> <li><a href="https://tehnojam.pro/category/software/chuvak-kak-sdelat-dorvej.html"><img width="70" height="70" src="https://tehnojam.pro/wp-content/uploads/2019/01/open-doors-150x150.jpg" class="attachment-70x70 size-70x70 wp-post-image" alt="Дорвеи путь к свободе" /><span class="rpwwt-post-title">Чувак, как сделать дорвей?</span></a></li> <li><a href="https://tehnojam.pro/category/software/esli-ne-podhodit-parol-k-adminke-wordpress.html"><img width="70" height="70" src="https://tehnojam.pro/wp-content/uploads/2019/01/wordpress-password-150x150.png" class="attachment-70x70 size-70x70 wp-post-image" alt="забыт парол wordpress" /><span class="rpwwt-post-title">Если не подходит пароль к админке wordpress</span></a></li> <li><a href="https://tehnojam.pro/category/software/saity-dorvei-chto-eto.html"><img width="70" height="70" src="https://tehnojam.pro/wp-content/uploads/2019/01/doorway-150x150.jpg" class="attachment-70x70 size-70x70 wp-post-image" alt="дорвеи для нищебродов" /><span class="rpwwt-post-title">Дорвеи — путь к финансовой свободе?</span></a></li> <li><a href="https://tehnojam.pro/category/software/pokazat-skritie-fayli.html"><img width="70" height="70" src="https://tehnojam.pro/wp-content/uploads/2018/12/hiddenfilesmac-150x150.jpg" class="attachment-70x70 size-70x70 wp-post-image" alt="скрытые папки mac os" /><span class="rpwwt-post-title">Отображение скрытых файлов и папок в Mac OS X</span></a></li> </ul> </div><!-- .rpwwt-widget --> </aside> </div><!-- .inside-right-sidebar --> </div><!-- #secondary --> </div><!-- #content --> </div><!-- #page --> <div class="site-footer grid-container grid-parent "> <footer class="site-info" itemtype="https://schema.org/WPFooter" itemscope="itemscope"> <div class="inside-site-info grid-container grid-parent"> <div class="copyright-bar"> © 2018 All rights reserved Tehnojam.pro </div> </div> </footer><!-- .site-info --> </div><!-- .site-footer --> <a title="Scroll back to top" rel="nofollow" href="#" class="koromo-back-to-top" style="opacity:0;visibility:hidden;" data-scroll-speed="400" data-start-scroll="300"> <span class="screen-reader-text">Scroll back to top</span> </a> <div class="koromo-side-left-cover"></div> <div class="koromo-side-right-cover"></div> </div> <link rel='stylesheet' id='hljstheme-css' href='https://tehnojam.pro/wp-content/plugins/wp-code-highlightjs/styles/default.css?ver=0.6.2' type='text/css' media='all' /> <link rel='stylesheet' id='gglcptch-css' href='https://tehnojam.pro/wp-content/plugins/google-captcha/css/gglcptch.css?ver=1.43' type='text/css' media='all' /> <script type='text/javascript'> /* <![CDATA[ */ var wpcf7 = {"apiSettings":{"root":"https:\/\/tehnojam.pro\/wp-json\/contact-form-7\/v1","namespace":"contact-form-7\/v1"}}; /* ]]> */ </script> <script type='text/javascript' src='https://tehnojam.pro/wp-content/plugins/contact-form-7/includes/js/scripts.js?ver=5.1.1'></script> <script type='text/javascript'> /* <![CDATA[ */ var PT_CV_PUBLIC = {"_prefix":"pt-cv-","page_to_show":"5","_nonce":"9cdb6b3342","is_admin":"","is_mobile":"","ajaxurl":"https:\/\/tehnojam.pro\/wp-admin\/admin-ajax.php","lang":"","loading_image_src":"data:image\/gif;base64,R0lGODlhDwAPALMPAMrKygwMDJOTkz09PZWVla+vr3p6euTk5M7OzuXl5TMzMwAAAJmZmWZmZszMzP\/\/\/yH\/C05FVFNDQVBFMi4wAwEAAAAh+QQFCgAPACwAAAAADwAPAAAEQvDJaZaZOIcV8iQK8VRX4iTYoAwZ4iCYoAjZ4RxejhVNoT+mRGP4cyF4Pp0N98sBGIBMEMOotl6YZ3S61Bmbkm4mAgAh+QQFCgAPACwAAAAADQANAAAENPDJSRSZeA418itN8QiK8BiLITVsFiyBBIoYqnoewAD4xPw9iY4XLGYSjkQR4UAUD45DLwIAIfkEBQoADwAsAAAAAA8ACQAABC\/wyVlamTi3nSdgwFNdhEJgTJoNyoB9ISYoQmdjiZPcj7EYCAeCF1gEDo4Dz2eIAAAh+QQFCgAPACwCAAAADQANAAAEM\/DJBxiYeLKdX3IJZT1FU0iIg2RNKx3OkZVnZ98ToRD4MyiDnkAh6BkNC0MvsAj0kMpHBAAh+QQFCgAPACwGAAAACQAPAAAEMDC59KpFDll73HkAA2wVY5KgiK5b0RRoI6MuzG6EQqCDMlSGheEhUAgqgUUAFRySIgAh+QQFCgAPACwCAAIADQANAAAEM\/DJKZNLND\/kkKaHc3xk+QAMYDKsiaqmZCxGVjSFFCxB1vwy2oOgIDxuucxAMTAJFAJNBAAh+QQFCgAPACwAAAYADwAJAAAEMNAs86q1yaWwwv2Ig0jUZx3OYa4XoRAfwADXoAwfo1+CIjyFRuEho60aSNYlOPxEAAAh+QQFCgAPACwAAAIADQANAAAENPA9s4y8+IUVcqaWJ4qEQozSoAzoIyhCK2NFU2SJk0hNnyEOhKR2AzAAj4Pj4GE4W0bkJQIAOw==","is_mobile_tablet":"","sf_no_post_found":"\u0417\u0430\u043f\u0438\u0441\u0435\u0439 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e."}; var PT_CV_PAGINATION = {"first":"\u00ab","prev":"\u2039","next":"\u203a","last":"\u00bb","goto_first":"\u041d\u0430 \u043f\u0435\u0440\u0432\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443","goto_prev":"\u041d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443","goto_next":"\u041d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443","goto_last":"\u041d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443","current_page":"\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430","goto_page":"\u041d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443"}; /* ]]> */ </script> <script type='text/javascript' src='https://tehnojam.pro/wp-content/plugins/content-views-query-and-display-post-page/public/assets/js/cv.js?ver=2.1.3.2'></script> <script type='text/javascript' src='https://tehnojam.pro/wp-content/plugins/pt-content-views-pro/public/assets/js/cvpro.min.js?ver=5.4.1'></script> <script type='text/javascript'> /* <![CDATA[ */ var pvcArgsFrontend = {"mode":"ajax","requestURL":"https:\/\/tehnojam.pro\/wp-content\/plugins\/post-views-counter\/includes\/ajax.php","postID":"365","nonce":"de1e3a3b79"}; /* ]]> */ </script> <script type='text/javascript' src='https://tehnojam.pro/wp-content/plugins/post-views-counter/js/frontend.js?ver=1.2.14'></script> <script type='text/javascript' src='https://tehnojam.pro/wp-content/plugins/simple-share-buttons-adder/js/ssba.js?ver=5.1.1'></script> <script type='text/javascript'> Main.boot( [] ); </script> <script type='text/javascript'> /* <![CDATA[ */ var sticky_anything_engage = {"element":".main-nav","topspace":"0","minscreenwidth":"760","maxscreenwidth":"999999","zindex":"99999999999999999","legacymode":"","dynamicmode":"","debugmode":"","pushup":"","adminbar":"1"}; /* ]]> */ </script> <script type='text/javascript' src='https://tehnojam.pro/wp-content/plugins/sticky-menu-or-anything-on-scroll/assets/js/stickThis.js?ver=2.1.1'></script> <script type='text/javascript'> /* <![CDATA[ */ var ratingsL10n = {"plugin_url":"https:\/\/tehnojam.pro\/wp-content\/plugins\/wp-postratings","ajax_url":"https:\/\/tehnojam.pro\/wp-admin\/admin-ajax.php","text_wait":"\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043d\u0435 \u0433\u043e\u043b\u043e\u0441\u0443\u0439\u0442\u0435 \u0437\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e.","image":"","image_ext":"svg","max":"5","show_loading":"1","show_fading":"1","custom":"0"}; var ratings_mouseover_image=new Image();ratings_mouseover_image.src="https://tehnojam.pro/wp-content/plugins/wp-postratings/images//rating_over.svg";; /* ]]> */ </script> <script type='text/javascript' src='https://tehnojam.pro/wp-content/plugins/wp-postratings/js/postratings-js.js?ver=1.86.2'></script> <!--[if lte IE 11]> <script type='text/javascript' src='https://tehnojam.pro/wp-content/themes/Koromo/js/classList.min.js?ver=1.0.1'></script> <![endif]--> <script type='text/javascript' src='https://tehnojam.pro/wp-content/themes/Koromo/js/menu.min.js?ver=1.0.1'></script> <script type='text/javascript' src='https://tehnojam.pro/wp-content/themes/Koromo/js/a11y.min.js?ver=1.0.1'></script> <script type='text/javascript' src='https://tehnojam.pro/wp-content/themes/Koromo/js/navigation-search.min.js?ver=1.0.1'></script> <script type='text/javascript' src='https://tehnojam.pro/wp-content/themes/Koromo/js/back-to-top.min.js?ver=1.0.1'></script> <script type='text/javascript' src='https://tehnojam.pro/wp-includes/js/comment-reply.min.js?ver=5.1.1'></script> <script type='text/javascript' src='https://tehnojam.pro/wp-content/plugins/q2w3-fixed-widget/js/q2w3-fixed-widget.min.js?ver=5.1.6'></script> <script type='text/javascript' src='https://tehnojam.pro/wp-includes/js/wp-embed.min.js?ver=5.1.1'></script> <script type='text/javascript' src='https://tehnojam.pro/wp-content/plugins/wp-code-highlightjs/highlight.common.pack.js?ver=0.6.2'></script> <script async="async" type='text/javascript' src='https://tehnojam.pro/wp-content/plugins/akismet/_inc/form.js?ver=4.1.1'></script> <script type='text/javascript' data-cfasync="false" async="async" defer="defer" src='https://www.google.com/recaptcha/api.js?render=explicit&ver=1.43'></script> <script type='text/javascript'> /* <![CDATA[ */ var gglcptch = {"options":{"version":"v2","sitekey":"6LdLqnYUAAAAAKcMT7b_RIlsSEvVHpIWIBaI6X-x","theme":"dark","error":"<strong>\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/strong>: \u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0444\u043e\u0440\u043c\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u0431\u043e\u043b\u0435\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 reCAPTCHA. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0443\u0434\u0430\u043b\u0438\u0442\u0435 \u0432\u0441\u0435 \u043b\u0438\u0448\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0438 reCAPTCHA \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b."},"vars":{"visibility":false}}; /* ]]> */ </script> <script type='text/javascript' src='https://tehnojam.pro/wp-content/plugins/google-captcha/js/script.js?ver=1.43'></script> <style>code.hljs { /*margin: 5px;*/ }</style> <script type="text/javascript"> (function($, window) { var init_fn_flag = false; var init_fn = (function() { if (init_fn_flag) return; init_fn_flag = true; hljs.configure({"tabReplace":" "}); $('pre code').each(function(i, block) { hljs.highlightBlock(block); }); }); $(document).ready(init_fn); $(window).on("load", init_fn); })(jQuery, window); </script> <ins id="adsense" class="adsbygoogle" data-tag="flat_pm" style="position:absolute;left:-9999px;top:-9999px">Adblock<br>detector</ins> <style> .arcticmodal-overlay,.arcticmodal-container{position:fixed;left:0;top:0;right:0;bottom:0;z-index:1000} .arcticmodal-container{overflow:auto;margin:0;padding:0;border:0;border-collapse:collapse} :first-child+html .arcticmodal-container{height:100%} .arcticmodal-container_i{height:100%;margin:0 auto} .arcticmodal-container_i2{vertical-align:middle!important;border:none!important} .flat_pm_modal{min-width:200px;min-height:100px;position:relative;padding:10px;background:#fff} .flat_pm_crss{transition:background .2s ease;position:absolute;top:0;right:0;width:34px;height:34px;background:#000;display:block;cursor:pointer;z-index:99999;border:none;padding:0;min-width:0;min-height:0} .flat_pm_crss:hover{background:#777} .flat_pm_crss:after,.flat_pm_crss:before{transition:transform .3s ease;content:'';display:block;position:absolute;top:0;left:0;right:0;bottom:0;width:16px;height:4px;background:#fff;transform-origin:center;transform:rotate(45deg);margin:auto} .flat_pm_crss:before{transform:rotate(-45deg)} .flat_pm_crss:hover:after{transform:rotate(225deg)} .flat_pm_crss:hover:before{transform:rotate(135deg)} .flat_pm_out{transition:transform .3s ease;position:fixed;min-width:250px;min-height:150px;z-index:999;-webkit-backface-visibility:hidden} .flat_pm_out *{max-width:none!important} .flat_pm_out.top .flat_pm_crss{top:auto;bottom:0} .flat_pm_out.right .flat_pm_crss{right:auto;left:0} .flat_pm_out.top{bottom:100%;left:50%;transform:translateY(0) translateX(-50%)} .flat_pm_out.bottom{top:100%;left:50%;transform:translateY(0) translateX(-50%)} .flat_pm_out.left{bottom:0;right:100%;transform:translateX(0)} .flat_pm_out.right{bottom:0;left:100%;transform:translateX(0)} .flat_pm_out.show{min-width:0;min-height:0} .flat_pm_out.show.top{transform:translateY(100%) translateX(-50%)} .flat_pm_out.show.bottom{transform:translateY(-100%) translateX(-50%)} .flat_pm_out.show.left{transform:translateX(100%)} .flat_pm_out.show.right{transform:translateX(-100%)} [data-flat-id]{position:relative;border-top:1px solid red} [data-flat-id]:before{content:'id: 'attr(data-flat-id);position:absolute;bottom:100%;left:0;padding:5px 10px;background:red;color:#fff;font-size:10px} </style> <script src="https://tehnojam.pro/wp-content/plugins/flat_pm/assets/front/script.js"></script><script>flat_pm_arr = [];</script><script src="https://tehnojam.pro/wp-content/plugins/flat_pm/assets/front/load.js"></script> </body> </html>