;(function () {
'use strict';
var UMAMI_URL = 'https://monitor.kulik.uz/script.js';
var UMAMI_WEBSITE_ID = '003c40bf-9e87-4a54-9b27-a99a3c0c9a80';
function umamiEvent(name, data) {
try {
if (window.umami && typeof window.umami.track === 'function') {
window.umami.track(name, data || {});
}
} catch (e) {}
}
function initUmami() {
try {
if (document.querySelector('script[data-kulik-umami]')) return;
var script = document.createElement('script');
script.src = UMAMI_URL;
script.async = true;
script.setAttribute('data-kulik-umami', '1');
script.setAttribute('data-website-id', UMAMI_WEBSITE_ID);
// Не считать всю Lampa одной веб-страницей.
// Отправляем только нужные события вручную.
script.setAttribute('data-auto-track', 'false');
script.onload = function () {
umamiEvent('plugin_open', {
plugin: 'kulik_tv',
style: 'rootu'
});
};
document.head.appendChild(script);
} catch (e) {}
}
initUmami();
var plugin = {
component: 'kuliklite_iptv',
icon: "",
name: 'Кулик TV'
};
var AUTO_PLAYLIST_URL = "https://live.kulik.uz/playlist.m3u?email=";
var isSNG = false;
var lists = [];
var curListId = -1;
var defaultGroup = 'Other';
var catalog = {};
var listCfg = {};
var EPG = {};
var layerInterval;
var epgInterval;
var UID = '';
var chNumber = '';
var chTimeout = null;
var stopRemoveChElement = false;
var chPanel = $((
"
").replace(/PLUGIN/g, plugin.component)
).hide().fadeOut(0);
var chHelper = $((
"").replace(/PLUGIN/g, plugin.component)
).hide().fadeOut(0);
var epgTemplate = $(('\n' +
'
\n' +
'
\n' +
'
Сейчас
\n' +
'
' +
'
\n' +
'
XX:XX
\n' +
'
\n' +
'
' +
'
\n' +
'
'+
'
' +
'
\n' +
'
Потом
\n' +
'
' +
'
\n' +
'
' +
'
').replace(/PLUGIN/g, plugin.component)
);
function epgListView(isView) {
var scroll = $('.' + plugin.component + '.category-full').parents('.scroll');
if (scroll.length) {
if (isView) {
scroll.css({float: "left", width: '70%'});
scroll.parent().append(epgTemplate);
} else {
scroll.css({float: "none", width: '100%'});
$('#' + plugin.component + '_epg').remove();
}
}
}
var epgItemTeplate = $((
'\n' +
'
XX:XX
\n' +
'
\n' +
'
').replace(/PLUGIN/g, plugin.component)
);
var chHelpEl = chHelper.find('.tv-helper');
var chNumEl = chPanel.find('.player-info__name');
var encoder = $('');
function isPluginPlaylist(playlist) {
return !(!playlist.length || !playlist[0].tv
|| !playlist[0].plugin || playlist[0].plugin !== plugin.component);
}
Lampa.PlayerPlaylist.listener.follow('select', function(e) {
if (e.item.plugin && e.item.plugin === plugin.component && Lampa.Player.runas)
Lampa.Player.runas(Lampa.Storage.field('player_iptv'));
});
function channelSwitch(dig, isChNum) {
if (!Lampa.Player.opened()) return false;
var playlist = Lampa.PlayerPlaylist.get();
if (!isPluginPlaylist(playlist)) return false;
if (!$('body>.js-ch-' + plugin.component).length) $('body').append(chPanel).append(chHelper);
var cnt = playlist.length;
var prevChNumber = chNumber;
chNumber += dig;
var number = parseInt(chNumber);
if (number && number <= cnt) {
if (!!chTimeout) clearTimeout(chTimeout);
stopRemoveChElement = true; // fix removing element in callback on animate.finish()
chNumEl.text(playlist[number - 1].title);
if (isChNum || parseInt(chNumber + '0') > cnt) {
chHelper.finish().hide().fadeOut(0);
} else {
var help = [];
var chHelpMax = 9;
var start = parseInt(chNumber + '0');
for (var i = start; i <= cnt && i <= (start + Math.min(chHelpMax, 9)); i++) {
help.push(encoder.text(playlist[i - 1].title).html());
}
chHelpEl.html(help.join('
'));
chHelper.finish().show().fadeIn(0);
}
if (number < 10 || isChNum) {
chPanel.finish().show().fadeIn(0);
}
stopRemoveChElement = false;
var chSwitch = function () {
var pos = number - 1;
if (Lampa.PlayerPlaylist.position() !== pos) {
Lampa.PlayerPlaylist.listener.send('select', {
playlist: playlist,
position: pos,
item: playlist[pos]
});
Lampa.Player.runas && Lampa.Player.runas(Lampa.Storage.field('player_iptv'));
}
chPanel.delay(1000).fadeOut(500,function(){stopRemoveChElement || chPanel.remove()});
chHelper.delay(1000).fadeOut(500,function(){stopRemoveChElement || chHelper.remove()});
chNumber = "";
}
if (isChNum === true) {
chTimeout = setTimeout(chSwitch, 1000);
chNumber = "";
} else if (parseInt(chNumber + '0') > cnt) {
// Ещё одна цифра невозможна - переключаем
chSwitch();
} else {
// Ждём следующую цифру или переключаем
chTimeout = setTimeout(chSwitch, 3000);
}
} else {
chNumber = prevChNumber;
}
return true;
}
var cacheVal = {};
function cache(name, value, timeout) {
var time = (new Date()) * 1;
if (!!timeout && timeout > 0) {
cacheVal[name] = [(time + timeout), value];
return;
}
if (!!cacheVal[name] && cacheVal[name][0] > time) {
return cacheVal[name][1];
}
delete (cacheVal[name]);
return value;
}
var timeOffset = 0;
var timeOffsetSet = false;
function unixtime() {
return Math.floor((new Date().getTime() + timeOffset)/1000);
}
function toLocaleTimeString(time) {
var date = new Date(),
ofst = parseInt(Lampa.Storage.get('time_offset', 'n0').replace('n',''));
time = time || date.getTime();
date = new Date(time + (ofst * 1000 * 60 * 60));
return ('0' + date.getHours()).substr(-2) + ':' + ('0' + date.getMinutes()).substr(-2);
}
function toLocaleDateString(time) {
var date = new Date(),
ofst = parseInt(Lampa.Storage.get('time_offset', 'n0').replace('n',''));
time = time || date.getTime();
date = new Date(time + (ofst * 1000 * 60 * 60));
return date.toLocaleDateString();
}
var utils = {
uid: function() {return UID},
timestamp: unixtime,
token: function() {return generateSigForString(Lampa.Storage.field('account_email').toLowerCase())},
hash: Lampa.Utils.hash,
hash36: function(s) {return (this.hash(s) * 1).toString(36)}
};
function generateSigForString(string) {
var sigTime = unixtime();
return sigTime.toString(36) + ':' + utils.hash36((string || '') + sigTime + utils.uid());
}
function strReplace(str, key2val) {
for (var key in key2val) {
str = str.replace(
new RegExp(key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'),
key2val[key]
);
}
return str;
}
function tf(t, format, u, tz) {
format = format || '';
tz = parseInt(tz || '0');
var thisOffset = 0;
thisOffset += tz * 60;
if (!u) thisOffset += parseInt(Lampa.Storage.get('time_offset', 'n0').replace('n','')) * 60 - new Date().getTimezoneOffset();
var d = new Date((t + thisOffset) * 6e4);
var r = {yyyy:d.getUTCFullYear(),MM:('0'+(d.getUTCMonth()+1)).substr(-2),dd:('0'+d.getUTCDate()).substr(-2),HH:('0'+d.getUTCHours()).substr(-2),mm:('0'+d.getUTCMinutes()).substr(-2),ss:('0'+d.getUTCSeconds()).substr(-2),UTF:t*6e4};
return strReplace(format, r);
}
function prepareUrl(url, epg) {
var m = [], val = '', r = {start:unixtime,offset:0};
if (epg && epg.length) {
r = {
start: epg[0] * 60,
utc: epg[0] * 60,
end: (epg[0] + epg[1]) * 60,
utcend: (epg[0] + epg[1]) * 60,
offset: unixtime() - epg[0] * 60,
duration: epg[1] * 60,
now: unixtime,
lutc: unixtime,
d: function(m){return strReplace(m[6]||'',{M:epg[1],S:epg[1]*60,h:Math.floor(epg[1]/60),m:('0'+(epg[1] % 60)).substr(-2),s:'00'})},
b: function(m){return tf(epg[0], m[6], m[4], m[5])},
e: function(m){return tf(epg[0] + epg[1], m[6], m[4], m[5])},
n: function(m){return tf(unixtime() / 60, m[6], m[4], m[5])}
};
}
while (!!(m = url.match(/\${(\((([a-zA-Z\d]+?)(u)?)([+-]\d+)?\))?([^${}]+)}/))) {
if (!!m[2] && typeof r[m[2]] === "function") val = r[m[2]](m);
else if (!!m[3] && typeof r[m[3]] === "function") val = r[m[3]](m);
else if (m[6] in r) val = typeof r[m[6]] === "function" ? r[m[6]]() : r[m[6]];
else if (!!m[2] && typeof utils[m[2]] === "function") val = utils[m[2]](m[6]);
else if (m[6] in utils) val = typeof utils[m[6]] === "function" ? utils[m[6]]() : utils[m[6]];
else val = m[1];
url = url.replace(m[0], encodeURIComponent(val));
}
return url;
}
function catchupUrl(url, type, source) {
type = (type || '').toLowerCase();
source = source || '';
if (!type) {
if (!!source) {
if (source.search(/^https?:\/\//i) === 0) type = 'default';
else if (source.search(/^[?&/][^/]/) === 0) type = 'append';
else type = 'default';
}
else if (url.indexOf('${') < 0) type = 'shift';
else type = 'default';
console.log(plugin.name, 'Autodetect catchup-type "' + type + '"');
}
var newUrl = '';
switch (type) {
case 'append':
if (source) {
newUrl = (source.search(/^https?:\/\//i) === 0 ? '' : url) + source;
break; // так и задумано
}
case 'timeshift': // @deprecated
case 'shift': // + append
newUrl = (source || url);
newUrl += (newUrl.indexOf('?') >= 0 ? '&' : '?') + 'utc=${start}&lutc=${timestamp}';
return newUrl;
case 'flussonic':
case 'flussonic-hls':
case 'flussonic-ts':
case 'fs':
// Example stream and catchup URLs
// stream: http://ch01.spr24.net/151/mpegts?token=my_token
// catchup: http://ch01.spr24.net/151/timeshift_abs-{utc}.ts?token=my_token
// stream: http://list.tv:8888/325/index.m3u8?token=secret
// catchup: http://list.tv:8888/325/timeshift_rel-{offset:1}.m3u8?token=secret
// stream: http://list.tv:8888/325/mono.m3u8?token=secret
// catchup: http://list.tv:8888/325/mono-timeshift_rel-{offset:1}.m3u8?token=secret
// stream: http://list.tv:8888/325/live?token=my_token
// catchup: http://list.tv:8888/325/{utc}.ts?token=my_token
return url
.replace(/\/(video|mono)\.(m3u8|ts)/, '/$1-\${start}-\${duration}.$2')
.replace(/\/(index|playlist)\.(m3u8|ts)/, '/archive-\${start}-\${duration}.$2')
.replace(/\/mpegts/, '/timeshift_abs-\${start}.ts')
;
case 'xc':
// Example stream and catchup URLs
// stream: http://list.tv:8080/my@account.xc/my_password/1477
// catchup: http://list.tv:8080/timeshift/my@account.xc/my_password/{duration}/{Y}-{m}-{d}:{H}-{M}/1477.ts
// stream: http://list.tv:8080/live/my@account.xc/my_password/1477.m3u8
// catchup: http://list.tv:8080/timeshift/my@account.xc/my_password/{duration}/{Y}-{m}-{d}:{H}-{M}/1477.m3u8
newUrl = url
.replace(
/^(https?:\/\/[^/]+)(\/live)?(\/[^/]+\/[^/]+\/)([^/.]+)\.m3u8?$/,
'$1/timeshift$3\${(d)M}/\${(b)yyyy-MM-dd:HH-mm}/$4.m3u8'
)
.replace(
/^(https?:\/\/[^/]+)(\/live)?(\/[^/]+\/[^/]+\/)([^/.]+)(\.ts|)$/,
'$1/timeshift$3\${(d)M}/\${(b)yyyy-MM-dd:HH-mm}/$4.ts'
)
;
break;
case 'default':
newUrl = source || url;
break;
case 'disabled':
return false;
default:
console.log(plugin.name, 'Err: no support catchup-type="' + type + '"');
return false;
}
if (newUrl.indexOf('${') < 0) return catchupUrl(newUrl,'shift');
return newUrl;
}
/* ***********************************
* Управление плеером клавишами пульта
* ***********************************
* Поддержка переключения каналов (возможно не все устройства):
* - цифровыми клавишами (по номеру канала)
* - клавишами влево-вправо
* - клавиши Pg+ и Pg-
*/
function keydown(e) {
var code = e.code;
if (Lampa.Activity.active().component === plugin.component
&& Lampa.Player.opened()
&& !$('body.selectbox--open').length
) {
var playlist = Lampa.PlayerPlaylist.get();
if (!isPluginPlaylist(playlist)) return;
var isStopEvent = false;
var curCh = cache('curCh') || (Lampa.PlayerPlaylist.position() + 1);
if (code === 428 || code === 34 // Pg-
//4 - Samsung orsay
|| ((code === 37 || code === 4) // left
&& !$('.player.tv .panel--visible .focus').length
&& !$('.player.tv .player-footer.open .focus').length
)
) {
curCh = curCh === 1 ? playlist.length : curCh - 1; // зацикливаем
cache('curCh', curCh, 1000);
isStopEvent = channelSwitch(curCh, true);
} else if (code === 427 || code === 33 // Pg+
// 5 - Samsung orsay right
|| ((code === 39 || code === 5) // right
&& !$('.player.tv .panel--visible .focus').length
&& !$('.player.tv .player-footer.open .focus').length
)
) {
curCh = curCh === playlist.length ? 1 : curCh + 1; // зацикливаем
cache('curCh', curCh, 1000);
isStopEvent = channelSwitch(curCh, true);
} else if (code >= 48 && code <= 57) { // numpad
isStopEvent = channelSwitch(code - 48);
} else if (code >= 96 && code <= 105) { // numpad
isStopEvent = channelSwitch(code - 96);
}
//29460 - Samsung orsay
if (code === 38 || code === 29460) { // Controller.move('up')
// this.selectGroup();
// isStopEvent = true;
}
if (isStopEvent) {
e.event.preventDefault();
e.event.stopPropagation();
}
}
}
function bulkWrapper(func, bulk) {
var bulkCnt = 1, timeout = 1, queueEndCallback, queueStepCallback, emptyFn = function(){};
if (typeof bulk === 'object') {
timeout = bulk.timeout || timeout;
queueStepCallback = bulk.onBulk || emptyFn;
queueEndCallback = bulk.onEnd || emptyFn;
bulkCnt = bulk.bulk || bulkCnt;
} else if (typeof bulk === 'number') {
bulkCnt = bulk;
if (typeof arguments[2] === "number") timeout = arguments[2];
} else if (typeof bulk === 'function') {
queueStepCallback = bulk;
if (typeof arguments[2] === "number") bulkCnt = arguments[2];
if (typeof arguments[3] === "number") timeout = arguments[3];
}
if (!bulkCnt || bulkCnt < 1) bulkCnt = 1;
if (typeof queueEndCallback !== 'function') queueEndCallback = emptyFn;
if (typeof queueStepCallback !== 'function') queueStepCallback = emptyFn;
var context = this;
var queue = [];
var interval;
var cnt = 0;
var runner = function() {
if (!!queue.length && !interval) {
interval = setInterval(
function() {
var i = 0;
while (queue.length && ++i <= bulkCnt) func.apply(context, queue.shift());
i = queue.length ? i : i-1;
cnt += i;
queueStepCallback.apply(context, [i, cnt, queue.length])
if (!queue.length) {
clearInterval(interval);
interval = null;
queueEndCallback.apply(context, [i, cnt, queue.length]);
}
},
timeout || 0
);
}
}
return function() {
queue.push(arguments);
runner();
}
}
function getEpgSessCache(epgId, t) {
var key = getEpgSessKey(epgId);
var epg = sessionStorage.getItem(key);
if (epg) {
epg = JSON.parse(epg);
if (t) {
if (epg.length
&& (
t < epg[0][0]
|| t > (epg[epg.length - 1][0] + epg[epg.length - 1][1])
)
) return false;
while (epg.length && t >= (epg[0][0] + epg[0][1])) epg.shift();
}
}
return epg;
}
function setEpgSessCache(epgId, epg) {
var key = getEpgSessKey(epgId);
sessionStorage.setItem(key, JSON.stringify(epg));
}
function getEpgSessKey(epgId) {
return ['epg', epgId].join('\t');
}
function networkSilentSessCache(url, success, fail, param) {
var context = this;
var urlForKey = url.replace(/([&?])sig=[^&]+&?/, '$1');
var key = ['cache', urlForKey, param ? utils.hash36(JSON.stringify(param)) : ''].join('\t');
var data = sessionStorage.getItem(key);
if (data) {
data = JSON.parse(data);
if (data[0]) typeof success === 'function' && success.apply(context, [data[1]]);
else typeof fail === 'function' && fail.apply(context, [data[1]]);
} else {
var network = new Lampa.Reguest();
network.silent(
url,
function (data) {
sessionStorage.setItem(key, JSON.stringify([true, data]));
typeof success === 'function' && success.apply(context, [data]);
},
function (data) {
sessionStorage.setItem(key, JSON.stringify([false, data]));
typeof fail === 'function' && fail.apply(context, [data]);
},
param
);
}
}
//Стиль
Lampa.Template.add(plugin.component + '_style', ''.replace(/PLUGIN/g, plugin.component));
$('body').append(Lampa.Template.get(plugin.component + '_style', {}, true));
function pluginPage(object) {
if (object.id !== curListId) {
catalog = {};
listCfg = {};
curListId = object.id;
}
EPG = {};
var epgIdCurrent = '';
var epgPath = '';
var favorite = getStorage('favorite' + object.id, '[]');
var network = new Lampa.Reguest();
var scroll = new Lampa.Scroll({
mask: true,
over: true,
step: 250
});
// var items = [];
var html = $('');
var body = $('');
body.toggleClass('square_icons', getSettings('square_icons'));
body.toggleClass('contain_icons', getSettings('contain_icons'));
var info;
var last;
if (epgInterval) clearInterval(epgInterval);
epgInterval = setInterval(function() {
for (var epgId in EPG) {
epgRender(epgId);
}
}, 10000);
var layerCards, layerMinPrev = 0, layerMaxPrev = 0, layerFocusI = 0, layerCnt = 24;
if (layerInterval) clearInterval(layerInterval);
layerInterval = setInterval(function() {
if (!layerCards) return;
var minI = Math.max(layerFocusI - layerCnt, 0);
var maxI = Math.min(layerFocusI + layerCnt, layerCards.length - 1);
if (layerMinPrev > maxI || layerMaxPrev < minI) {
layerCards.slice(layerMinPrev, layerMaxPrev + 1).removeClass('js-layer--visible');
cardsEpgRender(layerCards.slice(minI, maxI + 1).addClass('js-layer--visible'));
} else {
if (layerMinPrev < minI) layerCards.slice(layerMinPrev, minI + 1).removeClass('js-layer--visible');
if (layerMaxPrev > maxI) layerCards.slice(maxI, layerMaxPrev + 1).removeClass('js-layer--visible');
if (layerMinPrev > minI) cardsEpgRender(layerCards.slice(minI, layerMinPrev + 1).addClass('js-layer--visible'));
if (layerMaxPrev < maxI) cardsEpgRender(layerCards.slice(layerMaxPrev, maxI + 1).addClass('js-layer--visible'));
}
layerMinPrev = minI;
layerMaxPrev = maxI;
}, 50);
this.create = function () {
var _this = this;
this.activity.loader(true);
var emptyResult = function () {
var empty = new Lampa.Empty();
html.append(empty.render());
_this.start = empty.start;
_this.activity.loader(false);
_this.activity.toggle();
};
if (Object.keys(catalog).length) {
_this.build(catalog);
} else if(!lists[object.id] || !object.url) {
emptyResult();
return;
} else {
var load = 1, data;
var compileList = function (dataList) {
data = dataList;
if (!--load) parseListHeader();
};
if (!timeOffsetSet) {
load++;
(function () {
var ts = new Date().getTime();
network.silent(Lampa.Utils.protocol() + 'epg.rootu.top/api/time',
function (serverTime) {
var te = new Date().getTime();
timeOffset = (serverTime < ts || serverTime > te) ? serverTime - te : 0;
timeOffsetSet = true;
compileList(data);
},
function () {
timeOffsetSet = true;
compileList(data);
}
);
})();
}
var parseListHeader = function () {
if (typeof data != 'string'
|| data.substr(0, 7).toUpperCase() !== "#EXTM3U"
) {
emptyResult();
return;
}
var m, mm, channelsUri = 'channels';
var l = data.split(/\r?\n/, 2)[0];
if (!!(m = l.match(/([^\s=]+)=((["'])(.*?)\3|\S+)/g))) {
// listCfg
for (var jj = 0; jj < m.length; jj++) {
if (!!(mm = m[jj].match(/([^\s=]+)=((["'])(.*?)\3|\S+)/))) {
listCfg[mm[1].toLowerCase()] = mm[4] || (mm[3] ? '' : mm[2]);
}
}
}
listCfg['epgUrl'] = listCfg['url-tvg'] || listCfg['x-tvg-url'] || '';
listCfg['epgCode'] = utils.hash36(listCfg['epgUrl'].toLowerCase().replace(/https:\/\//g, 'http://'));
console.log(plugin.name, 'epgCode', listCfg['epgCode']);
/* epg.it999.ru epgCode [def epg2.xml.gz epg.xml.gz epg2.xml epg2xml ru2.xml.gz ru.xml.gz] */
listCfg['isEpgIt999'] = ["0", "4v7a2u", "skza0s", "oj8j5z", "sab9bx", "rv7awh", "2blr83"].indexOf(listCfg['epgCode']) >= 0;
listCfg['isYosso'] = ["godxcd"].indexOf(listCfg['epgCode']) >= 0;
if (/^https?:\/\/.+/i.test(listCfg['epgUrl']) && listCfg['epgUrl'].length < 8000) {
channelsUri = listCfg['epgCode'] + '/' + channelsUri + '?url=' + encodeURIComponent(listCfg['epgUrl'])
+ '&uid=' + utils.uid() + '&sig=' + generateSigForString(listCfg['epgUrl']);
}
listCfg['epgApiChUrl'] = Lampa.Utils.protocol() + 'epg.rootu.top/api/' + channelsUri;
networkSilentSessCache(listCfg['epgApiChUrl'], parseList, parseList);
}
var parseList = function () {
if (typeof data != 'string'
|| data.substr(0, 7).toUpperCase() !== "#EXTM3U"
) {
emptyResult();
return;
}
catalog = {
'': {
title: langGet('favorites'),
setEpgId: false,
channels: []
}
};
lists[object.id].groups = [{
title: langGet('favorites'),
key: ''
}];
var l = data.split(/\r?\n/);
var cnt = 0, i = 1, chNum = 0, m, mm, defGroup = defaultGroup, chInGroupCnt = {}, maxChInGroup = getSettings('max_ch_in_group');
while (i < l.length) {
chNum = cnt + 1;
var channel = {
ChNum: chNum,
Title: "Ch " + chNum,
isYouTube: false,
Url: '',
Group: '',
Options: {}
};
for (; cnt < chNum && i < l.length; i++) {
if (!!(m = l[i].match(/^#EXTGRP:\s*(.+?)\s*$/i))
&& m[1].trim() !== ''
) {
defGroup = m[1].trim();
} else if (!!(m = l[i].match(/^#EXTINF:\s*-?\d+(\s+\S.*?\s*)?,(.+)$/i))) {
channel.Title = m[2].trim();
if (!!m[1]
&& !!(m = m[1].match(/([^\s=]+)=((["'])(.*?)\3|\S+)/g))
) {
for (var j = 0; j < m.length; j++) {
if (!!(mm = m[j].match(/([^\s=]+)=((["'])(.*?)\3|\S+)/))) {
channel[mm[1].toLowerCase()] = mm[4] || (mm[3] ? '' : mm[2]);
}
}
}
} else if (!!(m = l[i].match(/^#EXTVLCOPT:\s*([^\s=]+)=(.+)$/i))) {
channel.Options[m[1].trim().toLowerCase()] = m[2].trim();
}
// else if (!!(m = l[i].match(/^(https?|udp|rt[ms]?p|mms|acestream):\/\/(.+)$/i))) {
else if (!!(m = l[i].match(/^(https?):\/\/(.+)$/i))) {
channel.Url = m[0].trim();
channel.isYouTube = !!(m[2].match(/^(www\.)?youtube\.com/));
channel.Group = (channel['group-title'] || defGroup) + "";
cnt++;
}
}
if (!!channel.Url && !channel.isYouTube) {
chInGroupCnt[channel.Group] = (chInGroupCnt[channel.Group] || 0) + 1;
var groupPage = maxChInGroup ? Math.floor((chInGroupCnt[channel.Group] - 1) / maxChInGroup) : 0;
if (groupPage) channel.Group += ' #' + (groupPage + 1);
if (!catalog[channel.Group]) {
catalog[channel.Group] = {
title: channel.Group,
setEpgId: false,
channels: []
};
lists[object.id].groups.push({
title: channel.Group,
key: channel.Group
});
}
channel['Title'] = channel['Title'].replace(/\s+(\s|ⓢ|ⓖ|ⓥ|ⓞ|Ⓢ|Ⓖ|Ⓥ|Ⓞ)/g, ' ').trim();
catalog[channel.Group].channels.push(channel);
var favI = favorite.indexOf(favID(channel.Title));
if (favI !== -1) {
catalog[''].channels[favI] = channel;
}
}
}
for (i = 0; i < lists[object.id].groups.length; i++) {
var group = lists[object.id].groups[i];
group.title += ' [' + catalog[group.key].channels.length + ']';
}
for (i = 0; i < favorite.length; i++) {
if (!catalog[''].channels[i]) {
catalog[''].channels[i] = {
ChNum: -1,
Title: "#" + favorite[i],
isYouTube: false,
Url: Lampa.Utils.protocol() + 'epg.rootu.top/empty/_.m3u8',
Group: '',
Options: {},
'tvg-logo': Lampa.Utils.protocol() + 'epg.rootu.top/empty/_.gif'
};
}
}
_this.build(catalog);
}
var listUrl = prepareUrl(object.url);
network.native(
listUrl,
compileList,
function () {
// Возможно ошибка из-за CORS пробуем silent запрос через CORS прокси
network.silent(
Lampa.Utils.protocol() + 'epg.rootu.top/cors.php?url=' + encodeURIComponent(listUrl)
+ '&uid=' + utils.uid() + '&sig=' + generateSigForString(listUrl),
compileList,
emptyResult,
false,
{dataType: 'text'}
);
},
false,
{dataType: 'text'}
)
}
return this.render();
};
function epgUpdateData(epgId) {
var lt = Math.floor(unixtime()/60);
var t = Math.floor(lt/60), ed, ede;
if (!!EPG[epgId] && t >= EPG[epgId][0] && t <= EPG[epgId][1]) {
ed = EPG[epgId][2];
if (!ed || !ed.length || ed.length >= 3) return;
ede = ed[ed.length - 1];
lt = (ede[0] + ede[1]);
var t2 = Math.floor(lt / 60);
if ((t2 - t) > 6 || t2 <= EPG[epgId][1]) return;
t = t2;
}
if (!!EPG[epgId]) {
ed = EPG[epgId][2];
if (typeof ed !== 'object') return;
if (ed.length) {
ede = ed[ed.length - 1];
lt = (ede[0] + ede[1]);
var t3 = Math.max(t, Math.floor(lt / 60));
if (t < t3 && ed.length >= 3) return;
t = t3;
}
EPG[epgId][1] = t;
} else {
EPG[epgId] = [t, t, false];
}
var success = function(epg) {
if (EPG[epgId][2] === false) EPG[epgId][2] = [];
for (var i = 0; i < epg.length; i++) {
if (lt < (epg[i][0] + epg[i][1])) {
EPG[epgId][2].push.apply(EPG[epgId][2], epg.slice(i));
break;
}
}
setEpgSessCache(epgId + epgPath, EPG[epgId][2]);
epgRender(epgId);
};
var fail = function () {
if (EPG[epgId][2] === false) EPG[epgId][2] = [];
setEpgSessCache(epgId + epgPath, EPG[epgId][2]);
epgRender(epgId);
};
if (EPG[epgId][2] === false) {
var epg = getEpgSessCache(epgId + epgPath, lt);
if (!!epg) return success(epg);
}
network.silent(
Lampa.Utils.protocol() + 'epg.rootu.top/api' + epgPath + '/epg/' + epgId + '/hour/' + t,
success,
fail
);
}
function cardsEpgRender(cards) {
cards.filter('.js-epgNoRender[data-epg-id]').each(function(){epgRender($(this).attr('data-epg-id'))});
}
function epgRender(epgId) {
var epg = (EPG[epgId] || [0, 0, []])[2];
var card = body.find('.js-layer--visible[data-epg-id="' + epgId + '"]').removeClass('js-epgNoRender');
if (epg === false || !card.length) return;
var epgEl = card.find('.card__age');
if (!epgEl.length) return;
var t = Math.floor(unixtime() / 60), enableCardEpg = false, i = 0, e, p, cId, cIdEl;
while (epg.length && t >= (epg[0][0] + epg[0][1])) epg.shift();
if (epg.length) {
e = epg[0];
if (t >= e[0] && t < (e[0] + e[1])) {
i++;
enableCardEpg = true;
p = Math.round((unixtime() - e[0] * 60) * 100 / (e[1] * 60 || 60));
cId = e[0] + '_' +epgEl.length;
cIdEl = epgEl.data('cId') || '';
if (cIdEl !== cId) {
epgEl.data('cId', cId);
epgEl.data('progress', p);
epgEl.find('.js-epgTitle').text(e[2]);
epgEl.find('.js-epgProgress').css('width', p + '%');
epgEl.show();
} else if (epgEl.data('progress') !== p) {
epgEl.data('progress', p);
epgEl.find('.js-epgProgress').css('width', p + '%');
}
}
}
if (epgIdCurrent === epgId) {
var ec = $('#' + plugin.component + '_epg');
var epgNow = ec.find('.js-epgNow');
cId = epgId + '_' + epg.length + (epg.length ? '_' + epg[0][0] : '');
cIdEl = ec.data('cId') || '';
if (cIdEl !== cId) {
ec.data('cId', cId);
var epgAfter = ec.find('.js-epgAfter');
if (i) {
var slt = toLocaleTimeString(e[0] * 60000);
var elt = toLocaleTimeString((e[0] + e[1]) * 60000);
epgNow.data('progress', p);
epgNow.find('.js-epgProgress').css('width', p + '%');
epgNow.find('.js-epgTime').text(slt);
epgNow.find('.js-epgTitle').text(e[2]);
var desc = e[3] ? ('' + encoder.text(e[3]).html() + '
') : '';
epgNow.find('.js-epgDesc').html(desc.replace(/\n/g,''));
epgNow.show();
info.find('.info__create').html(slt + '-' + elt + ' • ' + encoder.text(e[2]).html());
} else {
info.find('.info__create').html('');
epgNow.hide();
}
if (epg.length > i) {
var list = epgAfter.find('.js-epgList');
list.empty();
var iEnd = Math.min(epg.length, 8);
for (; i < iEnd; i++) {
e = epg[i];
var item = epgItemTeplate.clone();
item.find('.js-epgTime').text(toLocaleTimeString(e[0] * 60000));
item.find('.js-epgTitle').text(e[2]);
list.append(item);
}
epgAfter.show();
} else {
epgAfter.hide();
}
} else if (i && epgNow.data('progress') !== p) {
epgNow.data('progress', p);
epgNow.find('.js-epgProgress').css('width', p + '%');
}
}
if (!enableCardEpg) epgEl.hide();
if (epg.length < 3) epgUpdateData(epgId);
}
this.append = function (data) {
var catEpg = [];
var chIndex = 0;
var _this2 = this;
var lazyLoadImg = ('loading' in HTMLImageElement.prototype);
layerCards = null;
var bulkFn = bulkWrapper(function (channel) {
var chI = chIndex++;
var card = Lampa.Template.get('card', {
title: channel.Title,
release_year: ''
});
card.addClass('card--collection')
.removeClass('layer--visible')
.removeClass('layer--render')
.addClass('js-layer--hidden')
;
if (chI < layerCnt) card.addClass('js-layer--visible');
var img = card.find('.card__img')[0];
if (lazyLoadImg) img.loading = (chI < 18 ? 'eager' : 'lazy');
img.onload = function () {
card.addClass('card--loaded');
};
img.onerror = function (e) {
var name = channel.Title
.replace(/\s+\(([+-]?\d+)\)/, ' $1').replace(/[-.()\s]+/g, ' ').replace(/(^|\s+)(TV|ТВ)(\s+|$)/i, '$3');
var fl = name.replace(/\s+/g, '').length > 5
? name.split(/\s+/).map(function(v) {return v.match(/^(\+?\d+|[UF]?HD|4K)$/i) ? v : v.substring(0,1).toUpperCase()}).join('').substring(0,6)
: name.replace(/\s+/g, '')
;
fl = fl.replace(/([UF]?HD|4k|\+\d+)$/i, '$1');
var hex = (Lampa.Utils.hash(channel.Title) * 1).toString(16);
while (hex.length < 6) hex+=hex;
hex = hex.substring(0,6);
var r = parseInt(hex.slice(0, 2), 16),
g = parseInt(hex.slice(2, 4), 16),
b = parseInt(hex.slice(4, 6), 16);
var hexText = (r * 0.299 + g * 0.587 + b * 0.114) > 186 ? '#000000' : '#FFFFFF';
card.find('.card__img').replaceWith('
' + fl + '
');
card.find('.card__view').css({'background-color': '#' + hex, 'color': hexText});
channel['tvg-logo'] = '';
card.addClass('card--loaded');
};
if (channel['tvg-logo']) img.src = channel['tvg-logo'];else img.onerror();
var favIcon = $('');
card.find('.card__icons-inner').append(favIcon);
var tvgDay = parseInt(
channel['catchup-days'] || channel['tvg-rec'] || channel['timeshift']
|| listCfg['catchup-days'] || listCfg['tvg-rec'] || listCfg['timeshift']
|| '0' // todo вынести в настройки?
);
if (parseInt('catchup-enable' in channel ? channel['catchup-enable'] : tvgDay) > 0) {
card.find('.card__icons-inner').append('');
if (tvgDay === 0) tvgDay = 1;
} else {
tvgDay = 0;
}
card.find('.card__age').html('')
if (object.currentGroup !== '' && favorite.indexOf(favID(channel.Title)) !== -1) {
favIcon.toggleClass('hide', false);
}
card.playThis = function(){
layerFocusI = chI;
var video = {
title: channel.Title,
url: prepareUrl(channel.Url),
thumbnail: channel['tvg-logo'],
plugin: plugin.component,
iptv: true,
tv: true
};
var playlist = [];
var playlistForExtrnalPlayer = [];
var i = 0;
data.forEach(function (elem) {
// Изменяем порядок для внешнего плейлиста (плейлист начинается с текущего элемента)
var j = i < chI ? data.length - chI + i : i - chI;
var videoUrl = i === chI ? video.url : prepareUrl(elem.Url);
playlistForExtrnalPlayer[j] = {
title: elem.Title,
url: videoUrl,
thumbnail: elem['tvg-logo'],
iptv: true,
tv: true
};
playlist.push({
title: ++i + '. ' + elem.Title,
url: videoUrl,
thumbnail: elem['tvg-logo'],
plugin: plugin.component,
iptv: true,
tv: true
});
});
video['playlist'] = playlistForExtrnalPlayer;
Lampa.Keypad.listener.destroy()
Lampa.Keypad.listener.follow('keydown', keydown.bind(_this2));
Lampa.Player.runas && Lampa.Player.runas(Lampa.Storage.field('player_iptv'));
Lampa.Player.play(video);
Lampa.Player.runas && Lampa.Player.runas(Lampa.Storage.field('player_iptv'));
Lampa.Player.playlist(playlist);
};
card.on('hover:focus hover:hover touchstart', function (event) {
layerFocusI = chI;
if (event.type && event.type !== 'touchstart' && event.type !== 'hover:hover') scroll.update(card, true);
last = card[0];
// info.find('.info__title-original').text(channel['Group']);
info.find('.info__title').text(channel.Title);
var ec = $('#' + plugin.component + '_epg');
ec.find('.js-epgChannel').text(channel.Title);
if (!channel['epgId']) {
info.find('.info__create').empty();
epgIdCurrent = '';
ec.find('.js-epgNow').hide();
ec.find('.js-epgAfter').hide();
}
else {
epgIdCurrent = channel['epgId'];
epgRender(channel['epgId']);
}
}).on('hover:enter', function() {
getStorage('launch_menu', 'false') ? card.trigger('hover:long') : card.playThis();
}).on('hover:long', function () {
layerFocusI = chI;
var favI = favorite.indexOf(favID(channel.Title));
var isFavoriteGroup = object.currentGroup === '';
var menu = [];
if (getStorage('launch_menu', 'false')) {
menu.push({
title: Lampa.Lang.translate('player_lauch'),
startPlay: true
});
}
if (tvgDay > 0) {
if (!!channel['epgId'] && !!EPG[channel['epgId']] && EPG[channel['epgId']][2].length) {
menu.push({
title: 'Смотреть сначала',
restartProgram: true
});
}
menu.push({
title: 'Архив',
archive: true
});
}
if (!!channel['epgId'] && !!EPG[channel['epgId']] && EPG[channel['epgId']][2].length) {
menu.push({
title: Lampa.Lang.translate('search_start'),
search: EPG[channel['epgId']][2][0][2]
});
}
menu.push({
title: favI === -1 ? langGet('favorites_add') : langGet('favorites_del'),
favToggle: true
});
if (isFavoriteGroup && favorite.length) {
if (favI !== 0) {
menu.push({
title: langGet('favorites_move_top'),
favMove: true,
i: 0
});
menu.push({
title: langGet('favorites_move_up'),
favMove: true,
i: favI - 1
});
}
if ((favI + 1) !== favorite.length) {
menu.push({
title: langGet('favorites_move_down'),
favMove: true,
i: favI + 1
});
menu.push({
title: langGet('favorites_move_end'),
favMove: true,
i: favorite.length - 1
});
}
menu.push({
title: langGet('favorites_clear'),
favClear: true
});
}
menu.push({
title: getStorage('epg', 'false') ? langGet('epg_off') : langGet('epg_on'),
epgToggle: true
});
Lampa.Select.show({
title: Lampa.Lang.translate('title_action'),
items: menu,
onSelect: function (sel) {
if (!!sel.startPlay) {
card.playThis();
} else if (!!sel.archive) {
var t = unixtime();
var m = Math.floor(t/60);
var d = Math.floor(t/86400);
var di = (tvgDay + 1), load = di;
var ms = m - tvgDay * 1440;
var tvgData = [];
var playlist = [];
var playlistMenu = [];
var archiveMenu = [];
var ps = 0;
var prevDate = '';
var d0 = toLocaleDateString(unixtime() * 1e3);
var d1 = toLocaleDateString((unixtime() - 86400) * 1e3);
var d2 = toLocaleDateString((unixtime() - 2 * 86400) * 1e3);
var txtD = {};
txtD[d0] = 'Сегодня - ' + d0;
txtD[d1] = 'Вчера - ' + d1;
txtD[d2] = 'Позавчера - ' + d2;
var onEpgLoad = function() {
if (--load) return;
for (var i=tvgData.length - 1; i >= 0; i--) {
if (tvgData[i].length === 0) {
var dt = (d - i) * 1440;
for (var dm = 0; dm < 1440; dm+=30)
tvgData[i].push([dt + dm, 30, toLocaleDateString((dt + dm) * 6e4), '']);
}
for (var j=0; j < tvgData[i].length; j++) {
var epg = tvgData[i][j];
if (epg[0] === ps || epg[0] > m || epg[0] + epg[1] < ms) continue;
ps = epg[0];
var url = catchupUrl(
channel.Url,
(channel['catchup'] || channel['catchup-type'] || listCfg['catchup'] || listCfg['catchup-type']),
(channel['catchup-source'] || listCfg['catchup-source'])
);
var item = {
title: toLocaleTimeString(epg[0] * 6e4) + ' - ' + epg[2],
url: prepareUrl(url, epg),
catchupUrl: url,
plugin: plugin.component,
epg: epg
};
var newDate = toLocaleDateString(epg[0] * 6e4);
newDate = txtD[newDate] || newDate;
if (newDate !== prevDate) {
if (prevDate) {
archiveMenu.unshift({
title: prevDate,
separator: true
});
}
playlistMenu.push({
title: newDate,
separator: true,
plugin: plugin.component,
url: item.url
});
prevDate = newDate;
}
archiveMenu.unshift(item);
playlistMenu.push(item);
playlist.push(item);
}
}
if (prevDate) {
archiveMenu.unshift({
title: prevDate,
separator: true
});
}
tvgData = [];
Lampa.Select.show({
title: 'Архив',
items: archiveMenu,
onSelect: function (sel) {
console.log(plugin.name, 'catchupUrl: ' + sel.catchupUrl, epg.slice(0,2));
var video = {
title: sel.title,
url: sel.url,
iptv: true,
playlist: playlist
}
Lampa.Controller.toggle('content');
Lampa.Player.runas && Lampa.Player.runas(Lampa.Storage.field('player_iptv'));
Lampa.Player.play(video);
Lampa.Player.runas && Lampa.Player.runas(Lampa.Storage.field('player_iptv'));
Lampa.Player.playlist(playlistMenu);
},
onBack: function () {
Lampa.Controller.toggle('content');
}
})
};
while (di--) {
tvgData[di] = [];
(function() {
var dd = di;
networkSilentSessCache(Lampa.Utils.protocol() + 'epg.rootu.top/api' + epgPath + '/epg/' + channel['epgId'] + '/day/' + (d - dd) ,
function (data) {
tvgData[dd] = data;
onEpgLoad()
},
onEpgLoad
);
})();
}
} else if (!!sel.search) {
var search = sel.search
.replace(/^«([^»]+)».*$/, '$1')
.replace(/^"([^"]+)".*$/, '$1')
.replace(/\s*\((19\d\d|20[01]\d|202[0-4])\)\s*(\*\s.+)?$/, '')
.replace(/[.,]\s*(\d+(-й)?\s+(с-н|сезон)|(с-н|сезон)\s+\d+|[s][-.\s]*\d+(-й)?)?[-.,\s]*(\d+(-\d+|-я)?\s*(сери.|эпизоды?|episode|[cс]|ep?)\.?|(сери.|эпизоды?|episode|[cс]|ep?)[-.]?\s*\d+).*$/i,'')
.replace(/\s*(\d+(-й)?\s+(с-н|сезон)|(с-н|сезон)\s+\d+|[s][-.\s]*\d+(-й)?)?[-.,\s]*(\d+(-\d+|-я)?\s*(сери.|эпизоды?|episode|[cс]|ep?)\.?|(сери.|эпизоды?|episode|[cс]|ep?)[-.]?\s*\d+)\.?/i,'')
.replace(/\.\s+Дайджест\s*$/i, '')
.replace(/\.?\s*\(([cCсСeE](ерия|pisode)?[-.]?\s*\d+|\d+(-[^)\s]+)?\s+[Сс]ерия)\)/,'')
.replace(/\.[^.:]+:\s*[Чч](асть|\.)\s+\d+\S*$/,'')
.replace(/\.\s*Сборник\s+\d+\S*\s*$/i,'')
.replace(/\s*[\[(]?(\d|1\d|2[0-5])\+[\])]?[.\s]*$/, '')
.replace(/\s*(\(\)|\[])/, '')
;
// Lampa.Controller.toContent();
Lampa.Search.open({input: search});
} else if (!!sel.restartProgram) {
var epg = EPG[channel['epgId']][2][0];
var type = (channel['catchup'] || channel['catchup-type'] || listCfg['catchup'] || listCfg['catchup-type'] || '');
var url = catchupUrl(
channel.Url,
type,
(channel['catchup-source'] || listCfg['catchup-source'])
);
var flussonic = type.search(/^flussonic/i) === 0;
if (flussonic) {
url = url.replace('${(d)S}', 'now');
}
console.log(plugin.name, 'catchupUrl: ' + url, epg.slice(0,2));
var video = {
title: channel.Title,
url: prepareUrl(url, epg),
plugin: plugin.component,
catchupUrl: url,
iptv: true,
epg: epg
}
if (flussonic) video['timeline'] = {
time: 11,
percent: 0,
handler: function(){},
//hash: '',
duration: (epg[1] * 60)
};
Lampa.Controller.toggle('content');
Lampa.Player.runas && Lampa.Player.runas(Lampa.Storage.field('player_iptv'));
Lampa.Player.play(video);//Lampa.PlayerVideo.to(0)
Lampa.Player.runas && Lampa.Player.runas(Lampa.Storage.field('player_iptv'));
} else if (!!sel.epgToggle) {
var isView = !getStorage('epg', false);
setStorage('epg', isView);
epgListView(isView);
Lampa.Controller.toggle('content');
} else {
var favGroup = lists[object.id].groups[0];
if (!!sel.favToggle) {
if (favI === -1) {
favI = favorite.length
favorite[favI] = favID(channel.Title);
catalog[favGroup.key].channels[favI] = channel;
} else {
favorite.splice(favI, 1);
catalog[favGroup.key].channels.splice(favI, 1);
}
} else if (!!sel.favClear) {
favorite = [];
catalog[favGroup.key].channels = [];
} else if (!!sel.favMove) {
favorite.splice(favI, 1);
favorite.splice(sel.i, 0, favID(channel.Title));
catalog[favGroup.key].channels.splice(favI, 1);
catalog[favGroup.key].channels.splice(sel.i, 0, channel);
}
setStorage('favorite' + object.id, favorite);
favGroup.title = catalog[favGroup.key].title
+ ' [' + catalog[favGroup.key].channels.length + ']';
if (isFavoriteGroup) {
Lampa.Activity.replace(Lampa.Arrays.clone(lists[object.id].activity));
} else {
favIcon.toggleClass('hide', favorite.indexOf(favID(channel.Title)) === -1);
Lampa.Controller.toggle('content');
}
}
},
onBack: function () {
Lampa.Controller.toggle('content');
}
});
});
body.append(card);
if (!!channel['epgId']) {
card.attr('data-epg-id', channel['epgId']).addClass('js-epgNoRender');
epgRender(channel['epgId']);
}
},
{
bulk: 18,
onEnd: function (last, total, left) {
// body.find('.layer--render').removeClass('layer--render');
_this2.activity.loader(false);
_this2.activity.toggle();
if (chIndex > layerCnt) {
layerFocusI = 0;
layerCards = body.find('.js-layer--hidden');
}
// Lampa.Layer.visible(scroll.render(true));
}
});
data.forEach(function (channel) {
bulkFn(channel);
if (!!channel['epgId'] && catEpg.indexOf(channel['epgId']) === -1) catEpg.push(channel['epgId']);
});
// var catEpgString = catEpg.sort(function(a,b){return a-b}).join('-');
// var catEpgHash = utils.hash36(catEpgString);
// console.log('Epg', catEpgHash, catEpgString, data);
};
function setEpgId(channelGroup) {
if (channelGroup.setEpgId || !channelGroup.channels || !listCfg['epgApiChUrl']) return;
var chIDs = {id2epg: {}, piconUrl: '', id2picon: []}, i=0, channel;
networkSilentSessCache(listCfg['epgApiChUrl'], function(d){
chIDs = d;
if (!chIDs['id2epg']) chIDs['id2epg'] = {};
epgPath = !chIDs['epgPath'] ? '' : ('/' + chIDs['epgPath']);
});
var chShortName = function(chName){
return chName
.toLowerCase()
.replace(/\s+\(архив\)$/, '')
.replace(/\s+\((\+\d+)\)/g, ' $1')
.replace(/^телеканал\s+/, '')
.replace(/([!\s.,()–-]+|ⓢ|ⓖ|ⓥ|ⓞ|Ⓢ|Ⓖ|Ⓥ|Ⓞ)/g, ' ').trim()
.replace(/\s(канал|тв)(\s.+|\s*)$/, '$2')
.replace(/\s(50|orig|original)$/, '')
.replace(/\s(\d+)/g, '$1')
;
};
var trW = {"ё":"e","у":"y","к":"k","е":"e","н":"h","ш":"w","з":"3","х":"x","ы":"bl","в":"b","а":"a","р":"p","о":"o","ч":"4","с":"c","м":"m","т":"t","ь":"b","б":"6"};
var trName = function(word) {
return word.split('').map(function (char) {
return trW[char] || char;
}).join("");
};
var epgIdByName = function(v, find, epgId) {
var n = chShortName(v), fw, key;
if (n === '' || (!chIDs[n[0]] && !find)) return 0;
fw = n[0];
if (!!chIDs[fw]) {
if (!!chIDs[fw][n]) return chIDs[fw][n];
n = trName(n);
if (!!chIDs[fw][n]) return chIDs[fw][n];
if (find) {
for (key in chIDs[fw]) {
if (chIDs[fw][key] == epgId) {
return epgId;
} else if (n === trName(key)) {
return chIDs[fw][key];
}
}
}
}
if (n[0] !== fw && !!chIDs[n[0]]) {
fw = n[0];
if (!!chIDs[fw][n]) return chIDs[fw][n];
if (find) {
for (key in chIDs[fw]) {
if (chIDs[fw][key] == epgId) {
return epgId;
} else if (n === trName(key)) {
return chIDs[fw][key];
}
}
}
} else if (find) {
for(var keyW in trW) {
if (trW[keyW] === fw && !!chIDs[keyW]) {
for (key in chIDs[keyW]) {
if (chIDs[keyW][key] == epgId) {
return epgId;
} else if (n === trName(key)){
return chIDs[keyW][key];
}
}
}
}
}
return 0;
};
for (;i < channelGroup.channels.length;i++) {
channel = channelGroup.channels[i];
channel['epgId'] = (listCfg['isEpgIt999'] || listCfg['isYosso'])
? (channel['tvg-id'] && /^\d{1,4}$/.test(channel['tvg-id']) ? channel['tvg-id'] : epgIdByName(channel['Title'], true, channel['tvg-id']))
: (chIDs.id2epg[channel['tvg-id'] || ''] || epgIdByName(channel['Title'], isSNG, channel['tvg-id']) || channel['tvg-id']);
/*if (isSNG && !/^\d+$/.test(channel['epgId'])) {
channel['epgId'] = epgIdByName(channel['Title'], isSNG) || channel['epgId'];
}*/
if (!channel['tvg-logo'] && channel['epgId'] && !!chIDs.piconUrl) {
channel['tvg-logo'] = Lampa.Utils.protocol() + chIDs.piconUrl.replace('{picon}', (chIDs.id2picon && chIDs.id2picon[channel['epgId']]) ? chIDs.id2picon[channel['epgId']] : channel['epgId']);
}
if (!channel['tvg-logo']) {
if (channel['epgId'] && (listCfg['isEpgIt999'] || isSNG) && /^\d{1,4}$/.test(channel['epgId'])) {
channel['tvg-logo'] = Lampa.Utils.protocol() + 'epg.one/img2/' + channel['epgId'] + '.png'
} else if (isSNG && !/^Ch \d+$/.test(channel['Title'])) {
channel['tvg-logo'] = Lampa.Utils.protocol() + 'epg.rootu.top/picon/'
+ encodeURIComponent(channel['Title']) + '.png';
}
}
}
}
this.build = function (catalog) {
var channelGroup = !catalog[object.currentGroup]
? (lists[object.id].groups.length > 1 && !!catalog[lists[object.id].groups[1].key]
? catalog[lists[object.id].groups[1].key]
: {'channels': []}
)
: catalog[object.currentGroup];
var _this2 = this;
Lampa.Background.change();
Lampa.Template.add(plugin.component + '_button_category', "" + langGet('categories') + "\n
");
Lampa.Template.add(plugin.component + '_info_radio', '');
var btn = Lampa.Template.get(plugin.component + '_button_category');
info = Lampa.Template.get(plugin.component + '_info_radio');
info.find('#stantion_filtr').append(btn);
info.find('.view--category').on('hover:enter hover:click', function () {
_this2.selectGroup();
});
info.find('.info__title-original').text(!catalog[object.currentGroup] ? '' : catalog[object.currentGroup].title);
info.find('.info__title').text('');
html.append(info.append());
if (channelGroup.channels.length) {
setEpgId(channelGroup);
scroll.render().addClass('layer--wheight').data('mheight', info);
html.append(scroll.render());
this.append(channelGroup.channels);
if (getStorage('epg', false)) {
scroll.render().css({float: "left", width: '70%'});
scroll.render().parent().append(epgTemplate);
}
scroll.append(body);
setStorage('last_catalog' + object.id, object.currentGroup ? object.currentGroup : '!!');
lists[object.id].activity.currentGroup = object.currentGroup;
} else {
var empty = new Lampa.Empty();
html.append(empty.render());
this.activity.loader(false);
Lampa.Controller.collectionSet(info);
Navigator.move('right');
}
};
this.selectGroup = function () {
var activity = Lampa.Arrays.clone(lists[object.id].activity);
var groups = Lampa.Arrays.clone(lists[object.id].groups).map(function(group){
group.selected = object.currentGroup === group.key;
return group;
});
Lampa.Select.show({
title: langGet('categories'),
items: groups,
onSelect: function(group) {
if (object.currentGroup !== group.key) {
activity.currentGroup = group.key;
Lampa.Activity.replace(activity);
} else {
Lampa.Player.opened() || Lampa.Controller.toggle('content');
}
},
onBack: function() {
Lampa.Player.opened() || Lampa.Controller.toggle('content');
}
});
};
this.start = function () {
if (Lampa.Activity.active().activity !== this.activity) return; //обязательно, иначе наблюдается баг, активность создается но не стартует, в то время как компонент загружается и стартует самого себя.
var _this = this;
Lampa.Controller.add('content', {
toggle: function toggle() {
Lampa.Controller.collectionSet(scroll.render());
Lampa.Controller.collectionFocus(last || false, scroll.render());
},
left: function left() {
if (Navigator.canmove('left')) Navigator.move('left');
else Lampa.Controller.toggle('menu');
},
right: function right() {
if (Navigator.canmove('right')) Navigator.move('right');
else _this.selectGroup();
},
up: function up() {
if (Navigator.canmove('up')) {
Navigator.move('up');
} else {
if (!info.find('.view--category').hasClass('focus')) {
Lampa.Controller.collectionSet(info);
Navigator.move('right')
} else Lampa.Controller.toggle('head');
}
},
down: function down() {
if (Navigator.canmove('down')) Navigator.move('down');
else if (info.find('.view--category').hasClass('focus')) {
Lampa.Controller.toggle('content');
}
},
back: function back() {
Lampa.Activity.backward();
}
});
Lampa.Controller.toggle('content');
};
this.pause = function () {
Lampa.Player.runas && Lampa.Player.runas('');
};
this.stop = function () {
Lampa.Player.runas && Lampa.Player.runas('');
};
this.render = function () {
return html;
};
this.destroy = function () {
Lampa.Player.runas && Lampa.Player.runas('');
network.clear();
scroll.destroy();
if (info) info.remove();
layerCards = null;
if (layerInterval) clearInterval(layerInterval);
if (epgInterval) clearInterval(epgInterval);
html.remove();
body.remove();
favorite = null;
network = null;
html = null;
body = null;
info = null;
};
}
if (!Lampa.Lang) {
var lang_data = {};
Lampa.Lang = {
add: function add(data) {
lang_data = data;
},
translate: function translate(key) {
return lang_data[key] ? lang_data[key].ru : key;
}
};
}
var langData = {};
function langAdd(name, values) {
langData[plugin.component + '_' + name] = values;
}
function langGet(name) {
return Lampa.Lang.translate(plugin.component + '_' + name);
}
langAdd('max_ch_in_group',
{
ru: 'Количество каналов в категории',
uk: 'Кількість каналів у категорії',
be: 'Колькасць каналаў у катэгорыі',
en: 'Number of channels in category',
zh: '分类中的频道数量'
}
);
langAdd('max_ch_in_group_desc',
{
ru: 'Если количество превышено, категория разбивается на несколько. Уменьшите количество на слабых устройствах',
uk: 'Якщо кількість перевищена, категорія розбивається на кілька. Зменшіть кількість на слабких пристроях',
be: 'Калі колькасць перавышана, катэгорыя разбіваецца на некалькі. Паменшыце колькасць на слабых прыладах',
en: 'If the quantity is exceeded, it splits the category into several. Reduce the number on weak devices',
zh: '如果超出数量,则将分类拆分为多个。在弱设备上减少数量。'
}
);
langAdd('default_playlist',
{
ru: 'https://tsynik.github.io/tv.m3u',
uk: 'https://raw.githubusercontent.com/Free-TV/IPTV/master/playlist.m3u8',
be: 'https://raw.githubusercontent.com/Free-TV/IPTV/master/playlist.m3u8',
en: 'https://raw.githubusercontent.com/Free-TV/IPTV/master/playlist.m3u8',
zh: 'https://raw.iqiq.io/Free-TV/IPTV/master/playlist.m3u8'
}
);
langAdd('default_playlist_cat',
{
ru: 'Russia',
uk: 'Ukraine',
be: 'Belarus',
en: 'VOD Movies (EN)',
zh: 'China'
}
);
langAdd('settings_playlist_num_group',
{
ru: 'Плейлист ',
uk: 'Плейлист ',
be: 'Плэйліст ',
en: 'Playlist ',
zh: '播放列表 '
}
);
langAdd('settings_list_name',
{
ru: 'Название',
uk: 'Назва',
be: 'Назва',
en: 'Name',
zh: '名称'
}
);
langAdd('settings_list_name_desc',
{
ru: 'Название плейлиста в левом меню',
uk: 'Назва плейлиста у лівому меню',
be: 'Назва плэйліста ў левым меню',
en: 'Playlist name in the left menu',
zh: '左侧菜单中的播放列表名称'
}
);
langAdd('settings_list_url',
{
ru: 'URL-адрес',
uk: 'URL-адреса',
be: 'URL-адрас',
en: 'URL',
zh: '网址'
}
);
langAdd('settings_list_url_desc0',
{
ru: 'По умолчанию используется плейлист из проекта https://github.com/Free-TV/IPTV
Вы можете заменить его на свой.',
uk: 'За замовчуванням використовується плейлист із проекту https://github.com/Free-TV/IPTV
Ви можете замінити його на свій.',
be: 'Па змаўчанні выкарыстоўваецца плэйліст з праекта https://github.com/Free-TV/IPTV
Вы можаце замяніць яго на свой.',
en: 'The default playlist is from the project https://github.com/Free-TV/IPTV
You can replace it with your own.',
zh: '默认播放列表来自项目 https://github.com/Free-TV/IPTV
您可以将其替换为您自己的。'
}
);
langAdd('settings_list_url_desc1',
{
ru: 'Вы можете добавить еще один плейлист здесь. Ссылки на плейлисты обычно заканчиваются на .m3u или .m3u8',
uk: 'Ви можете додати ще один плейлист суду. Посилання на плейлисти зазвичай закінчуються на .m3u або .m3u8',
be: 'Вы можаце дадаць яшчэ адзін плэйліст суда. Спасылкі на плэйлісты звычайна заканчваюцца на .m3u або .m3u8',
en: 'You can add another trial playlist. Playlist links usually end with .m3u or .m3u8',
zh: '您可以添加另一个播放列表。 播放列表链接通常以 .m3u 或 .m3u8 结尾'
}
);
langAdd('categories',
{
ru: 'Категории',
uk: 'Категорія',
be: 'Катэгорыя',
en: 'Categories',
zh: '分类'
}
);
langAdd('uid',
{
ru: 'UID',
uk: 'UID',
be: 'UID',
en: 'UID',
zh: 'UID'
}
);
langAdd('unique_id',
{
ru: 'уникальный идентификатор (нужен для некоторых ссылок на плейлисты)',
uk: 'унікальний ідентифікатор (необхідний для деяких посилань на списки відтворення)',
be: 'унікальны ідэнтыфікатар (неабходны для некаторых спасылак на спіс прайгравання)',
en: 'unique identifier (needed for some playlist links)',
zh: '唯一 ID(某些播放列表链接需要)'
}
);
langAdd('launch_menu',
{
ru: 'Запуск через меню',
uk: 'Запуск через меню',
be: 'Запуск праз меню',
en: 'Launch via menu',
zh: '通过菜单启动'
}
);
langAdd('favorites',
{
ru: 'Избранное',
uk: 'Вибране',
be: 'Выбранае',
en: 'Favorites',
zh: '收藏夹'
}
);
langAdd('favorites_add',
{
ru: 'Добавить в избранное',
uk: 'Додати в обране',
be: 'Дадаць у абранае',
en: 'Add to favorites',
zh: '添加到收藏夹'
}
);
langAdd('favorites_del',
{
ru: 'Удалить из избранного',
uk: 'Видалити з вибраного',
be: 'Выдаліць з абранага',
en: 'Remove from favorites',
zh: '从收藏夹中删除'
}
);
langAdd('favorites_clear',
{
ru: 'Очистить избранное',
uk: 'Очистити вибране',
be: 'Ачысціць выбранае',
en: 'Clear favorites',
zh: '清除收藏夹'
}
);
langAdd('favorites_move_top',
{
ru: 'В начало списка',
uk: 'На початок списку',
be: 'Да пачатку спісу',
en: 'To the top of the list',
zh: '到列表顶部'
}
);
langAdd('favorites_move_up',
{
ru: 'Сдвинуть вверх',
uk: 'Зрушити вгору',
be: 'Ссунуць уверх',
en: 'Move up',
zh: '上移'
}
);
langAdd('favorites_move_down',
{
ru: 'Сдвинуть вниз',
uk: 'Зрушити вниз',
be: 'Ссунуць уніз',
en: 'Move down',
zh: '下移'
}
);
langAdd('favorites_move_end',
{
ru: 'В конец списка',
uk: 'В кінець списку',
be: 'У канец спісу',
en: 'To the end of the list',
zh: '到列表末尾'
}
);
langAdd('epg_on',
{
ru: 'Включить телепрограмму',
uk: 'Увімкнути телепрограму',
be: 'Уключыць тэлепраграму',
en: 'TV Guide: On',
zh: '電視指南:開'
}
);
langAdd('epg_off',
{
ru: 'Отключить телепрограмму',
uk: 'Вимкнути телепрограму',
be: 'Адключыць тэлепраграму',
en: 'TV Guide: Off',
zh: '電視指南:關閉'
}
);
langAdd('epg_title',
{
ru: 'Телепрограмма',
uk: 'Телепрограма',
be: 'Тэлепраграма',
en: 'TV Guide',
zh: '電視指南'
}
);
langAdd('square_icons', {
ru: 'Квадратные лого каналов',
uk: 'Квадратні лого каналів',
be: 'Квадратныя лога каналаў',
en: 'Square channel logos',
zh: '方形通道標誌'
});
langAdd('contain_icons', {
ru: 'Коррекция размера логотипа телеканала',
uk: 'Виправлення розміру логотипу телеканалу',
be: 'Карэкцыя памеру лагатыпа тэлеканала',
en: 'TV channel logo size correction',
zh: '電視頻道標誌尺寸校正'
});
langAdd('contain_icons_desc', {
ru: 'Может некорректно работать на старых устройствах',
uk: 'Може некоректно працювати на старих пристроях',
be: 'Можа некарэктна працаваць на старых прыладах',
en: 'May not work correctly on older devices.',
zh: '可能无法在较旧的设备上正常工作。'
});
Lampa.Lang.add(langData);
function favID(title) {
return title.toLowerCase().replace(/[\s!-\/:-@\[-`{-~]+/g, '')
}
function getStorage(name, defaultValue) {
return Lampa.Storage.get(plugin.component + '_' + name, defaultValue);
}
function setStorage(name, val, noListen) {
return Lampa.Storage.set(plugin.component + '_' + name, val, noListen);
}
function getSettings(name) {
return Lampa.Storage.field(plugin.component + '_' + name);
}
function addSettings(type, param) {
var data = {
component: plugin.component,
param: {
name: plugin.component + '_' + param.name,
type: type, // select|trigger|input|title|static
values: !param.values ? '' : param.values,
placeholder: !param.placeholder ? '' : param.placeholder,
default: (typeof param.default === 'undefined') ? '' : param.default
},
field: {
name: !param.title ? (!param.name ? '' : param.name) : param.title
}
}
if (!!param.name) data.param.name = plugin.component + '_' + param.name;
if (!!param.description) data.field.description = param.description;
if (!!param.onChange) data.onChange = param.onChange;
if (!!param.onRender) data.onRender = param.onRender;
Lampa.SettingsApi.addParam(data);
}
function configurePlaylist(i) {
if (i > 0) return i;
var title = plugin.name;
var url = (typeof AUTO_PLAYLIST_URL === 'string') ? AUTO_PLAYLIST_URL : '';
var activity = {
id: 0,
url: '',
title: title,
groups: [],
currentGroup: getStorage('last_catalog0', langGet('default_playlist_cat')),
component: plugin.component,
page: 1
};
if (activity.currentGroup === '!!') activity.currentGroup = '';
var menuEl = $('')
.hide()
.on('hover:enter', function(){
if (Lampa.Activity.active().component === plugin.component) {
Lampa.Activity.replace(Lampa.Arrays.clone(activity));
} else {
Lampa.Activity.push(Lampa.Arrays.clone(activity));
}
});
if (/^https?:\/\/./i.test(url)) {
activity.url = url;
menuEl.show();
}
lists.push({activity: activity, menuEl: menuEl, groups: []});
return 0;
}
Lampa.Component.add(plugin.component, pluginPage);
// Готовим настройки
Lampa.SettingsApi.addComponent(plugin);
addSettings(
'trigger',
{
title: langGet('square_icons'),
name: 'square_icons',
default: false,
onChange: function(v){
$('.' + plugin.component + '.category-full').toggleClass('square_icons', v === 'true');
}
}
);
addSettings(
'trigger',
{
title: langGet('contain_icons'),
description: langGet('contain_icons_desc'),
name: 'contain_icons',
default: true,
onChange: function(v){
$('.' + plugin.component + '.category-full').toggleClass('contain_icons', v === 'true');
}
}
);
addSettings(
'trigger',
{
title: langGet('epg_on'),
name: 'epg',
default: false,
onChange: function(v){
epgListView(v === 'true');
}
}
);
addSettings(
'trigger',
{
title: langGet('launch_menu'),
name: 'launch_menu',
default: false
}
);
addSettings(
'select',
{
title: langGet('max_ch_in_group'),
description: langGet('max_ch_in_group_desc'),
name: 'max_ch_in_group',
values: {
0: '#{settings_param_card_view_all}',
60: '60',
120: '120',
180: '180',
240: '240',
300: '300'
},
default: 300
}
);
configurePlaylist(0);
UID = getStorage('uid', '');
if (!UID) {
UID = Lampa.Utils.uid(10).toUpperCase().replace(/(.{4})/g, '$1-');
setStorage('uid', UID);
} else if (UID.length > 12) {
UID = UID.substring(0, 12);
setStorage('uid', UID);
}
addSettings('title', {title: langGet('uid')});
addSettings('static', {title: UID, description: langGet('unique_id')});
//~ Готовим настройки
function pluginStart() {
if (!!window['plugin_' + plugin.component + '_ready']) {
console.log(plugin.name, 'plugin already start');
return;
}
window['plugin_' + plugin.component + '_ready'] = true;
var menu = $('.menu .menu__list').eq(0);
for (var i=0; i < lists.length; i++) menu.append(lists[i].menuEl);
isSNG = ['uk', 'ru', 'be'].indexOf(Lampa.Storage.field('language')) >= 0;
console.log(plugin.name, 'plugin start', menu.length, lists.length, isSNG);
}
console.log(plugin.name, 'plugin ready start', !!window.appready ? 'now' : 'waiting event ready');
if (!!window.appready) pluginStart();
else Lampa.Listener.follow('app', function(e){if (e.type === 'ready') pluginStart()});
})();