NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name ShikiAirTime
// @version 2.13
// @description Добавляет на главную страницу блок "Ваше аниме", в котором отображается таймер до выхода новых серий онгоингов пользователя (заменяет собой блок "Сейчас выходит")
// @author AniOleg
// @match https://shikimori.one/*
// @match https://shikimori.org/*
// @match https://shikimori.me/*
// @match https://shiki.one/*
// @match http://shikimori.one/*
// @match http://shikimori.org/*
// @match http://shikimori.me/*
// @match http://shiki.one/*
// @icon https://www.google.com/s2/favicons?domain=shikimori.me
// @homepageURL https://openuserjs.org/scripts/AniOleg/ShikiAirTime
// @updateURL https://openuserjs.org/meta/AniOleg/ShikiAirTime.meta.js
// @license MIT
// @grant none
// ==/UserScript==
//НАСТРАИВАЕМЫЕ ПАРАМЕТРЫ
const cGap = 11.4, //отступ между обложками аниме (px)
cGridItemWidth = 96, //ширина обложки аниме (px)
clOngoing = 'GreenYellow', //цвет линии просматриваемого онгоинга
clOngoingLaze = 'red', //цвет линии просматриваемого онгоинга (есть отставание по сериям)
clOngoingPlanned = 'orange', //цвет линии запланированного онгоинга
bSize = 2, //толщина линии подчёркивания тайтла (px)
cTooltip = true, //включить отображение карточек при наведении на обложку аниме
showAiredAnime = true, //отображать уже вышедшее аниме, или аниме для которого неизвестна дата выхода эпизода
showPlannedAirAnime = false, //отображать онгоинги из списка "Запланировано"
finalEpisodeDate = true, //подсчитывать предполагаемую дату окончания онгоинга и отображать во всплывающей карточке (при наведении)
gDebul = false; //выводить отладочную информацию в консоль DevTools
//
const host = location.protocol + '//' + location.host;
const lang_data = {ru: {header: 'Ваше аниме',
episode: 'Эпизод',
progress: 'Прогресс:',
day: 'д',
hour: 'ч',
min: 'м',
emptyList: 'Список аниме пуст',
errorCatch: 'При обработке данных произошла ошибка. Попробуйте обновить страницу',
episodeIncrementProgress: 'Отправка...',
cacheResetAlert: 'Кэш расписания сброшен. Обновите страницу',
finalEpisode: 'Финальный эпизод'
},
en: {header: 'Your anime',
episode: 'Ep',
progress: 'Progress:',
day: 'd',
hour: 'h',
min: 'm',
emptyList: 'Anime list is empty',
errorCatch: 'An error occurred while processing the data. Try refreshing the page',
episodeIncrementProgress: 'Sending...',
cacheResetAlert: 'Schedule cache was reset. Please, refresh page',
finalEpisode: 'Final episode'
},
};
var CalendarList = [], AnimeList = [],
GlobalServerTime = null, SiteLang, TitleLang;
function InitScript(fn) {
document.addEventListener('page:load', fn);
document.addEventListener('turbolinks:load', fn);
if (document.attachEvent ? document.readyState === 'complete' : document.readyState !== 'loading') {
fn();
var ctrlDown = false,
shiftDown = false,
ctrlKey = 17,
cmdKey = 91,
shiftKey = 16,
fKey = 70,
prevKey = 0;
$(document).keydown(function(e) {
if (e.keyCode == ctrlKey || e.keyCode == cmdKey) ctrlDown = true;
if (e.keyCode == shiftKey) shiftDown = true;
if (ctrlDown && shiftDown && e.keyCode == fKey && location.pathname == '/' && GetUserId() != null) {
localStorage.setItem('__AniListCalendar', '[]');
alert(lang_data[SiteLang].cacheResetAlert);
if (gDebul) console.log('ShikiAirTime: Кэш календаря сброшен пользователем');
}
}).keyup(function(e) {
if (e.keyCode == ctrlKey || e.keyCode == cmdKey) ctrlDown = false;
if (e.keyCode == shiftKey) shiftDown = false;
});
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
function InitListFetch() {
if (localStorage.getItem('__AniListCalendar') == null) {
localStorage.setItem('__AniListCalendar', '[]');
}
if (location.pathname == '/' && GetUserId() != null) {
GlobalServerTime = GetServerTime();
SiteLang = $('body')[0].attributes['data-locale'].nodeValue;
TitleLang = $('body')[0].attributes['data-localized_names'].nodeValue;
if (gDebul) console.log('ShikiAirTime: Запрос списка пользователя...');
InitListGrid();
AnimeList = [];
if (!showPlannedAirAnime) {
GrabShiki(1, "watching", false, () => {
GrabShiki(1, "rewatching", false);
});
} else {
GrabShiki(1, "watching", false, () => {
GrabShiki(1, "rewatching", false, () => {
GrabShiki(1, "planned", true);
});
});
}
}
}
function InitListGrid() {
if (gDebul) console.log('ShikiAirTime: InitListGrid');
if (location.pathname == '/') {
if ($("._ShikiAirTime__CustomStyles").length < 1) {
var d = document.createElement('style');
d.classList = "_ShikiAirTime__CustomStyles";
d.innerHTML = `._ShikiAirTime__CalendarGridEntry .cover .image-decor>.text:before {background: none !important}
._ShikiAirTime__CalendarGridEntry .cover .image-decor>.text {text-align: center !important}
._ShikiAirTime__PreAirDate {display: none !important;}
._ShikiAirTime__PreAirDate.Show {display: block !important;}
._ShikiAirTime__AddEpisode {display: none !important; padding-top: 5px !important; padding-bottom: 5px; font-size: 14px !important;}
._ShikiAirTime__AddEpisode:hover > .plus {font-weight: bold !important;}
._ShikiAirTime__AddEpisode.Show {display: block !important}
._ShikiAirTime__CalendarGridContainer {display: grid; gap: ` + cGap + `px; grid-template-columns: repeat(auto-fill, ` + cGridItemWidth + `px);}`;
$('body')[0].appendChild(d);
}
if ($("._ShikiAirTime__CalendarTooltip").length < 1) {
var g = document.createElement('div');
g.classList = '_ShikiAirTime__CalendarTooltip';
g.style = 'display: none; position: absolute; left: 0px; top: 0px; pointer-events: none !important; margin: 0';
g.innerHTML = '<div class="tooltip-inner" style="width: 240px !important; min-height: 50px !important; box-shadow: none !important; margin: 0px !important"></div>';
$('body')[0].appendChild(g);
}
$('.block2')[0].childNodes[1].style = '';
$('.block2')[0].childNodes[1].innerHTML = '<div style="text-align: center"><div class="b-ajax"></div>';
$('.block2')[0].childNodes[1].classList = '';
$('.block2')[0].classList.add("_ShikiAirTime__MainContainer");
$("._ShikiAirTime__MainContainer").find(".subheadline").addClass("_ShikiAirTime__HeaderLinkContainer");
$('.block2')[0].childNodes[0].childNodes[0].childNodes[0].nodeValue = lang_data[SiteLang].header;
$('.block2')[0].childNodes[0].childNodes[0].href = GetUserLink() + '/list/anime?mylist=watching,rewatching';
HideCustomTooltip();
}
}
function InitDataFetch() {
try{
AnimeList.sort(compareNames); //2.9 сортируем по названию
CalendarList = [];
CalendarList = JSON.parse(localStorage.getItem('__AniListCalendar'));
var Queue = [];
if (CalendarList != null && CalendarList.length > 0) {
if (gDebul) console.log('ShikiAirTime: В localStorage обнаружены данные календаря');
for (var a = 0; a < AnimeList.length; a++) {
if (AnimeList[a].anime.status == 'ongoing' || AnimeList[a].anime.status == 'anons') {
var IsFinded = false;
for (var b = CalendarList.length - 1; b >= 0; b--) { //перебор календаря (сохранённого)
if (AnimeList[a].anime.id == CalendarList[b].data.Media.idMal) { //2.2
IsFinded = true;
if (CalendarList[b].data.Media.nextAiringEpisode.airingAt - GlobalServerTime < 0) { //если у аниме эпизод уже вышел, то обновляем информацию
CalendarList.splice(b, 1);
Queue.push(AnimeList[a].anime.id);
}
}
}
if (!IsFinded) //если не нашли нужного аниме, то запрашиваем инфу
Queue.push(AnimeList[a].anime.id);
}
}
} else { //если календарь не был сохранён, то запрашиваем инфу по всем своим онгоингам
if (gDebul) console.log('ShikiAirTime: Запрос новых данных по всему списку...')
CalendarList = [];
if (AnimeList.length > 0) {
for (var i = 0; i < AnimeList.length; i++) {
if (AnimeList[i].anime.status == 'ongoing' || AnimeList[i].anime.status == 'anons') {
Queue.push(AnimeList[i].anime.id);
}
}
}
}
if (Queue.length > 0) {
GrabAniList(Queue, 1);
} else {
CalendarList.sort(compareNumeric);
DrawListGrid();
}
} catch(e) {
if (gDebul) console.log('ShikiAirTime: Ошибка ' + e + '. Кэш календаря будет сброшен')
$('.block2')[0].childNodes[1].innerHTML = '<div style="text-align: center"><span>' + lang_data[SiteLang].errorCatch + '</span></div>';
localStorage.setItem('__AniListCalendar', '[]');
}
}
function GrabShiki(Page, Status, onlyOngoings = false, callback = () => {InitDataFetch()}) {
const ApiUrl = host + '/api/graphql';
const QueryStruct = `
{
userRates(
userId: ${GetUserId()}
page: ${Page}
limit: 50
targetType: Anime
status: ${Status}
order: { field: updated_at, order: desc }
) {
id
episodes
anime {
id
name
russian
status
episodes
episodesAired
url
poster {
previewUrl
}
}
}
}
`;
var xhr = new XMLHttpRequest();
xhr.open('POST', ApiUrl);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status == 200) {
try {
data = JSON.parse(xhr.responseText);
for (var i = 0; i < data.data.userRates.length; i++) {
if (!onlyOngoings || data.data.userRates[i].anime.status == "ongoing") {
AnimeList.push(data.data.userRates[i]);
}
}
if (data.data.userRates.length >= 50) {
GrabShiki(Page + 1, Status, onlyOngoings, callback);
} else {
callback();
}
} catch (e) {
$('.block2')[0].childNodes[1].innerHTML = '<div style="text-align: center"><span>' + lang_data[SiteLang].errorCatch + '</span></div>';
}
} else {
$('.block2')[0].childNodes[1].innerHTML = '<div style="text-align: center"><span>' + lang_data[SiteLang].errorCatch + '</span></div>';
}
}
};
var data = JSON.stringify({
query: QueryStruct
});
xhr.send(data);
}
function GrabAniList(Queue, Page) {
const ApiUrl = 'https://graphql.anilist.co';
const QueryStruct = `
query($idMal_in: [Int], $page: Int) {
Page(page: $page) {
media(idMal_in: $idMal_in) {
idMal
nextAiringEpisode {
airingAt
episode
}
}
pageInfo {
perPage
hasNextPage
total
}
}
}`;
var xhr = new XMLHttpRequest();
xhr.open('POST', ApiUrl);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status == 200) {
try {
data = JSON.parse(xhr.responseText);
for (var i = 0; i < data.data.Page.media.length; i++) {
if (data.data.Page.media[i].nextAiringEpisode != null) {
CalendarList.push({data: {Media:data.data.Page.media[i]}});
}
}
localStorage.setItem('__AniListCalendar', JSON.stringify(CalendarList)); //сохраняем календарь в локальное хранилище
if (data.data.Page.pageInfo.hasNextPage == true) {
GrabAniList(Queue, Page + 1)
} else {
CalendarList.sort(compareNumeric);
DrawListGrid();
}
} catch (e) {
$('.block2')[0].childNodes[1].innerHTML = '<div style="text-align: center"><span>' + lang_data[SiteLang].errorCatch + '</span></div>';
}
} else {
$('.block2')[0].childNodes[1].innerHTML = '<div style="text-align: center"><span>' + lang_data[SiteLang].errorCatch + '</span></div>';
}
}
};
var data = JSON.stringify({
query: QueryStruct,
variables: {idMal_in: Queue}
});
xhr.send(data);
}
function DrawListGrid() {
if (location.pathname == '/') {
var tInner = '';
var allCount = 0;
var findedArray = [];
for (var a = 0; a < CalendarList.length; a++) {
for (var b = 0; b < AnimeList.length; b++) {
if (CalendarList[a].data.Media.idMal == AnimeList[b].anime.id && (AnimeList[b].anime.status == 'ongoing' || AnimeList[b].anime.status == 'anons')) {
findedArray.push(b);
var tTime = CalendarList[a].data.Media.nextAiringEpisode.airingAt - GlobalServerTime;
if (tTime > -60) { //придерживаем серию ещё минуту после её выхода
allCount++;
var bColor = AnimeList[b].episodes + 1 < CalendarList[a].data.Media.nextAiringEpisode.episode ? clOngoingLaze : clOngoing;
if (AnimeList[b].episodes == 0) bColor = clOngoingPlanned;
tInner += `
<article class="b-catalog_entry _ShikiAirTime__CalendarGridEntry" itemtype="http://schema.org/Movie" style="border-bottom: ` + bSize + `px solid ` + bColor + `; position: relative" title_name="`
+ AnimeList[b].anime.name.replace(/["]/g, '"') + `" title_ru="` + AnimeList[b].anime.russian.replace(/["]/g, '"') + `" ` +
`episodes_watched="` + AnimeList[b].episodes + `" episodes="` + AnimeList[b].anime.episodes + `" episodes_aired="` +
(CalendarList[a].data.Media.nextAiringEpisode.episode != null ? (CalendarList[a].data.Media.nextAiringEpisode.episode - 1) : 10000) + `" next_episode_airing_at="` +
(CalendarList[a].data.Media.nextAiringEpisode.airingAt != null ? (CalendarList[a].data.Media.nextAiringEpisode.airingAt - 1) : 0) +`"
anime_rate_id="` + AnimeList[b].id + `" clOngoing="` + clOngoing + `" clOngoingLaze="` + clOngoingLaze + `" is_ongoing=true>
<a class="cover anime-tooltip-processed" href="` + AnimeList[b].anime.url + `">
<span class="image-decor">
<span class="image-cutter _ShikiAirTime__CalendatGridEntryImageContainer">
<img alt="` + (TitleLang == 'ru' ? AnimeList[b].anime.russian.replace(/["]/g, '"') : AnimeList[b].anime.name.replace(/["]/g, '"')) + `" src="` + AnimeList[b].anime.poster.previewUrl + `">
</span>
<div class="text _ShikiAirTime__PreAirDate Show">` + lang_data[SiteLang].episode + ` ` + CalendarList[a].data.Media.nextAiringEpisode.episode + `<br>` + CalcEndTime(tTime) + `</div>
<div class="text _ShikiAirTime__AddEpisode">` + AnimeList[b].episodes + ` <span class="plus">+</span></div>
</span>
</a>
</article>
`;
}
}
}
}
if (showAiredAnime) {
for (var c = 0; c < AnimeList.length; c++) {
if (findedArray.indexOf(c) == -1) {
allCount++;
//2.7
var episodes_aired = 0;
if (AnimeList[c].anime.status == 'ongoing') {
episodes_aired = AnimeList[c].anime.episodesAired == null ? 0 : AnimeList[c].anime.episodesAired;
} else {
episodes_aired = AnimeList[c].anime.episodes == 0 ? '?' : AnimeList[c].anime.episodes;
}
tInner += `
<article class="b-catalog_entry _ShikiAirTime__CalendarGridEntry" itemtype="http://schema.org/Movie" style=" position: relative" title_name="`
+ AnimeList[c].anime.name.replace(/["]/g, '"') + `" title_ru="` + AnimeList[c].anime.russian.replace(/["]/g, '"') + `" ` +
`episodes_watched="` + AnimeList[c].episodes + `" episodes="` + AnimeList[c].anime.episodes + `" episodes_aired="` + episodes_aired + `"
anime_rate_id="` + AnimeList[c].id + `" clOngoing="` + clOngoing + `" clOngoingLaze="` + clOngoingLaze + `" is_ongoing=false>
<a class="cover anime-tooltip-processed" data-delay="150" href="` + AnimeList[c].anime.url + `">
<span class="image-decor">
<span class="image-cutter">
<img alt="` + (TitleLang == 'ru' ? AnimeList[c].anime.russian.replace(/["]/g, '"') : AnimeList[c].anime.name.replace(/["]/g, '"')) + `" src="` + AnimeList[c].anime.poster.previewUrl+ `">
</span>
<div class="text _ShikiAirTime__AddEpisode">` + AnimeList[c].episodes + ` <span class="plus">+</span></div>
</span>
</a>
</article>
`;
}
}
}
if (allCount > 0) {
$('.block2')[0].childNodes[1].classList = '_ShikiAirTime__CalendarGridContainer';
$('.block2')[0].childNodes[1].innerHTML = tInner;
} else {
$('.block2')[0].childNodes[1].innerHTML = '<div style="text-align: center"><span>' + lang_data[SiteLang].emptyList + '</span></div>';
}
//очистка завершенных онгоингов из кэша календаря
for (var x = CalendarList.length - 1; x >= 0; x--) {
var IsFinded = false;
for (var d = 0; d < AnimeList.length; d++) {
if (CalendarList[x].data.Media.idMal == AnimeList[d].anime.id) {
IsFinded = true;
}
}
if (!IsFinded) {
CalendarList.splice(x, 1);
}
}
localStorage.setItem('__AniListCalendar', JSON.stringify(CalendarList)); //сохраняем календарь в локальное хранилище
if (cTooltip) {
var elements = $('._ShikiAirTime__CalendarGridEntry');
for (var i = 0; i < elements.length; i++) {
$(elements[i].childNodes[1].childNodes[1]).hover(
function (e) {
ShowCustomTooltip(e.target);
$(e.target.parentElement.parentElement).find('._ShikiAirTime__AddEpisode').addClass('Show');
$(e.target.parentElement.parentElement).find('._ShikiAirTime__PreAirDate').removeClass('Show');
},
function (e) {
HideCustomTooltip();
$(e.target.parentElement.parentElement).find('._ShikiAirTime__AddEpisode').removeClass('Show');
$(e.target.parentElement.parentElement).find('._ShikiAirTime__PreAirDate').addClass('Show');
}
)
}
}
$('._ShikiAirTime__AddEpisode').click(function (e) {
e.preventDefault();
incEpisode($(e.target.parentElement.parentElement).find('._ShikiAirTime__AddEpisode')[0].parentElement.parentElement.parentElement.getAttribute('anime_rate_id'), $(e.target.parentElement.parentElement).find('._ShikiAirTime__AddEpisode')[0]);
})
}
}
function ShowCustomTooltip(e) {
var AnimeElement = e.tagName == 'IMG' ? e.parentElement.parentElement.parentElement.parentElement : e.parentElement.parentElement.parentElement;
var TooltipElement = $('._ShikiAirTime__CalendarTooltip')[0];
TooltipElement.style.display = 'block';
TooltipElement.style.top = AnimeElement.getBoundingClientRect().y + document.documentElement.scrollTop + 'px';
TooltipElement.childNodes[0].innerHTML = (TitleLang == 'ru' ? AnimeElement.attributes.title_ru.nodeValue : AnimeElement.attributes.title_name.nodeValue) + '<br><br>';
var EpisodesBehind = AnimeElement.attributes.episodes_aired.nodeValue - AnimeElement.attributes.episodes_watched.nodeValue;
if (EpisodesBehind > 0) {
TooltipElement.childNodes[0].innerHTML += (SiteLang == 'ru' ?
'Отставание на ' + EpisodesBehind + ' ' + GetLocalizedEpisodeHint(EpisodesBehind)
: EpisodesBehind + ' episode' + (EpisodesBehind > 1 ? 's' : '') + ' behind') + '<br><br>';
}
TooltipElement.childNodes[0].innerHTML += lang_data[SiteLang].progress + ' ' + AnimeElement.attributes.episodes_watched.nodeValue + '/' + (AnimeElement.attributes.episodes.nodeValue != 0 ? AnimeElement.attributes.episodes.nodeValue : '?');
if (AnimeElement.getBoundingClientRect().x + AnimeElement.getBoundingClientRect().width + 2 + TooltipElement.childNodes[0].getBoundingClientRect().width + 10 < $(window).width()) {
TooltipElement.style.left = AnimeElement.getBoundingClientRect().x + AnimeElement.getBoundingClientRect().width + 2 + 'px';
} else {
TooltipElement.style.left = AnimeElement.getBoundingClientRect().x - 2 - TooltipElement.childNodes[0].getBoundingClientRect().width + 'px';
}
//2.8
if (finalEpisodeDate && AnimeElement.attributes.episodes.nodeValue != 0 && AnimeElement.attributes.is_ongoing.nodeValue == "true") {
var endDate = new Date(
(
GlobalServerTime + (60 * 60 * 24 * 7 * (AnimeElement.attributes.episodes.nodeValue - AnimeElement.attributes.episodes_aired.nodeValue - 1) + parseInt(AnimeElement.attributes.next_episode_airing_at.nodeValue) - GlobalServerTime)
) * 1000
);
TooltipElement.childNodes[0].innerHTML += "<br><br>" + lang_data[SiteLang].finalEpisode + " " + endDate.getDate() + "." + (endDate.getMonth() + 1).toString().padStart(2, "0") + "." + endDate.getFullYear();
}
}
function GetLocalizedEpisodeHint(e) {
var variants = ['эпизод', 'эпизода', 'эпизодов'];
e = Math.abs(e) % 100;
var n1 = e % 10;
if (e > 10 && e < 20) { return variants[2]; }
if (n1 > 1 && n1 < 5) { return variants[1]; }
if (n1 == 1) { return variants[0]; }
return variants[2];
}
function HideCustomTooltip() {
$('._ShikiAirTime__CalendarTooltip')[0].style.display = 'none';
}
function GetUserId() {
return JSON.parse($('body')[0].attributes['data-user'].value).id;
}
function GetUserLink() {
return JSON.parse($('body')[0].attributes['data-user'].value).url;
}
function GetServerTime() {
try {
return new Date($('body')[0].attributes['data-server_time'].nodeValue).getTime() / 1000;
} catch(e) {
if (gDebul) console.log('ShikiAirTime: Ошибка запроса серверного времени');
return null;
}
}
function compareNumeric(a, b) { //сортировка AniList по времени до выхода эпизода
a = a.data.Media.nextAiringEpisode.airingAt;
b = b.data.Media.nextAiringEpisode.airingAt;
if (a > b) return 1;
if (a == b) return 0;
if (a < b) return -1;
}
function compareNames(a, b) { //2.9 сортировка списка аниме по имени (для неонгоингов или без даты след. серии)
a = (TitleLang == 'ru' ? a.anime.russian : a.anime.name);
b = (TitleLang == 'ru' ? b.anime.russian : b.anime.name);
if (a > b) return 1;
if (a == b) return 0;
if (a < b) return -1;
}
function CalcEndTime(tUTime) {
var t = parseInt(tUTime);
if (t<60) {
return '<1' + lang_data[SiteLang].min;
} else {
var days = parseInt(t / 86400);
t = t - (days * 86400);
var hours = parseInt(t / 3600);
t = t - (hours * 3600);
var minutes = parseInt(t / 60);
var content = '';
if (days) {
content += days + lang_data[SiteLang].day;
}
if (hours > 0) {
if (hours || days) {
if (content) {
content += ' ';
}
content += hours + lang_data[SiteLang].hour;
}
}
if (minutes) {
if (content) {
content += ' ';
}
content += minutes + lang_data[SiteLang].min;
}
return content;
}
}
function incEpisode(rate_id, addEpisodeElement) {
var prevHTML = addEpisodeElement.innerHTML;
addEpisodeElement.innerHTML = lang_data[SiteLang].episodeIncrementProgress;
fetch(host + '/api/v2/user_rates/' + rate_id + '/increment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
}
})
.then(r => r.json())
.then(data => {
if (gDebul) console.log('ShikiAirTime: Количество просмотренных эпизодов увеличено на 1');
addEpisodeElement.innerHTML = data.episodes + ' <span class="plus">+</span>';
addEpisodeElement.parentElement.parentElement.parentElement.setAttribute('episodes_watched', data.episodes);
HideCustomTooltip();
if (addEpisodeElement.parentElement.parentElement.parentElement.getAttribute('is_ongoing') == 'true') {
var bColor = data.episodes < addEpisodeElement.parentElement.parentElement.parentElement.getAttribute('episodes_aired') ? clOngoingLaze : clOngoing;
addEpisodeElement.parentElement.parentElement.parentElement.style.borderBottom = bSize + `px solid ` + bColor;
}
if (addEpisodeElement.parentElement.parentElement.parentElement.getAttribute('episodes') > 0 &&
addEpisodeElement.parentElement.parentElement.parentElement.getAttribute('episodes') == data.episodes) {
addEpisodeElement.parentElement.parentElement.parentElement.remove();
}
})
.catch(error => {
if (gDebul) console.log('ShikiAirTime: Ошибка увеличения кол-ва эпизодов');
addEpisodeElement.innerHTML = prevHTML;
})
}
InitScript(InitListFetch)