// Generated by Haxe 4.3.3 (function ($hx_exports, $global) { "use strict"; $hx_exports["client"] = $hx_exports["client"] || {}; $hx_exports["client"]["JsApi"] = $hx_exports["client"]["JsApi"] || {}; var $estr = function() { return js_Boot.__string_rec(this,''); },$hxEnums = $hxEnums || {},$_; function $extend(from, fields) { var proto = Object.create(from); for (var name in fields) proto[name] = fields[name]; if( fields.toString !== Object.prototype.toString ) proto.toString = fields.toString; return proto; } var ClientGroup = $hxEnums["ClientGroup"] = { __ename__:true,__constructs__:null ,Banned: {_hx_name:"Banned",_hx_index:0,__enum__:"ClientGroup",toString:$estr} ,User: {_hx_name:"User",_hx_index:1,__enum__:"ClientGroup",toString:$estr} ,Leader: {_hx_name:"Leader",_hx_index:2,__enum__:"ClientGroup",toString:$estr} ,Admin: {_hx_name:"Admin",_hx_index:3,__enum__:"ClientGroup",toString:$estr} }; ClientGroup.__constructs__ = [ClientGroup.Banned,ClientGroup.User,ClientGroup.Leader,ClientGroup.Admin]; var Client = function(name,group) { this.name = name; var i = group; if(group == null) { i = 0; } this.group = i; }; Client.__name__ = true; Client.fromData = function(data) { return new Client(data.name,data.group); }; Client.prototype = { hasPermission: function(permission,permissions) { if((this.group & 1) != 0) { return permissions.banned.indexOf(permission) != -1; } if((this.group & 8) != 0) { return permissions.admin.indexOf(permission) != -1; } if((this.group & 4) != 0) { return permissions.leader.indexOf(permission) != -1; } if((this.group & 2) != 0) { return permissions.user.indexOf(permission) != -1; } return permissions.guest.indexOf(permission) != -1; } ,setGroupFlag: function(type,flag) { if(flag) { this.group |= 1 << type._hx_index; } else { this.group &= -1 - (1 << type._hx_index); } return flag; } }; var ClientTools = function() { }; ClientTools.__name__ = true; ClientTools.setLeader = function(clients,name) { var _g = 0; while(_g < clients.length) { var client = clients[_g]; ++_g; if(client.name == name) { client.setGroupFlag(ClientGroup.Leader,true); } else if((client.group & 4) != 0) { client.setGroupFlag(ClientGroup.Leader,false); } } }; ClientTools.hasLeader = function(clients) { return ClientTools.getLeader(clients) != null; }; ClientTools.getLeader = function(clients) { var _g = 0; while(_g < clients.length) { var client = clients[_g]; ++_g; if((client.group & 4) != 0) { return client; } } return null; }; ClientTools.getByName = function(clients,name,def) { var _g = 0; while(_g < clients.length) { var client = clients[_g]; ++_g; if(client.name == name) { return client; } } return def; }; var EReg = function(r,opt) { this.r = new RegExp(r,opt.split("u").join("")); }; EReg.__name__ = true; EReg.prototype = { match: function(s) { if(this.r.global) { this.r.lastIndex = 0; } this.r.m = this.r.exec(s); this.r.s = s; return this.r.m != null; } ,matched: function(n) { if(this.r.m != null && n >= 0 && n < this.r.m.length) { return this.r.m[n]; } else { throw haxe_Exception.thrown("EReg::matched"); } } ,matchedPos: function() { if(this.r.m == null) { throw haxe_Exception.thrown("No string matched"); } return { pos : this.r.m.index, len : this.r.m[0].length}; } ,matchSub: function(s,pos,len) { if(len == null) { len = -1; } if(this.r.global) { this.r.lastIndex = pos; this.r.m = this.r.exec(len < 0 ? s : HxOverrides.substr(s,0,pos + len)); var b = this.r.m != null; if(b) { this.r.s = s; } return b; } else { var b = this.match(len < 0 ? HxOverrides.substr(s,pos,null) : HxOverrides.substr(s,pos,len)); if(b) { this.r.s = s; this.r.m.index += pos; } return b; } } ,split: function(s) { return s.replace(this.r,"#__delim__#").split("#__delim__#"); } ,map: function(s,f) { var offset = 0; var buf_b = ""; do { if(offset >= s.length) { break; } else if(!this.matchSub(s,offset)) { buf_b += Std.string(HxOverrides.substr(s,offset,null)); break; } var p = this.matchedPos(); buf_b += Std.string(HxOverrides.substr(s,offset,p.pos - offset)); buf_b += Std.string(f(this)); if(p.len == 0) { buf_b += Std.string(HxOverrides.substr(s,p.pos,1)); offset = p.pos + 1; } else { offset = p.pos + p.len; } } while(this.r.global); if(!this.r.global && offset > 0 && offset < s.length) { buf_b += Std.string(HxOverrides.substr(s,offset,null)); } return buf_b; } }; var HxOverrides = function() { }; HxOverrides.__name__ = true; HxOverrides.dateStr = function(date) { var m = date.getMonth() + 1; var d = date.getDate(); var h = date.getHours(); var mi = date.getMinutes(); var s = date.getSeconds(); return date.getFullYear() + "-" + (m < 10 ? "0" + m : "" + m) + "-" + (d < 10 ? "0" + d : "" + d) + " " + (h < 10 ? "0" + h : "" + h) + ":" + (mi < 10 ? "0" + mi : "" + mi) + ":" + (s < 10 ? "0" + s : "" + s); }; HxOverrides.strDate = function(s) { switch(s.length) { case 8: var k = s.split(":"); var d = new Date(); d["setTime"](0); d["setUTCHours"](k[0]); d["setUTCMinutes"](k[1]); d["setUTCSeconds"](k[2]); return d; case 10: var k = s.split("-"); return new Date(k[0],k[1] - 1,k[2],0,0,0); case 19: var k = s.split(" "); var y = k[0].split("-"); var t = k[1].split(":"); return new Date(y[0],y[1] - 1,y[2],t[0],t[1],t[2]); default: throw haxe_Exception.thrown("Invalid date format : " + s); } }; HxOverrides.cca = function(s,index) { var x = s.charCodeAt(index); if(x != x) { return undefined; } return x; }; HxOverrides.substr = function(s,pos,len) { if(len == null) { len = s.length; } else if(len < 0) { if(pos == 0) { len = s.length + len; } else { return ""; } } return s.substr(pos,len); }; HxOverrides.remove = function(a,obj) { var i = a.indexOf(obj); if(i == -1) { return false; } a.splice(i,1); return true; }; HxOverrides.now = function() { return Date.now(); }; var Lambda = function() { }; Lambda.__name__ = true; Lambda.exists = function(it,f) { var x = $getIterator(it); while(x.hasNext()) if(f(x.next())) { return true; } return false; }; Lambda.find = function(it,f) { var v = $getIterator(it); while(v.hasNext()) { var v1 = v.next(); if(f(v1)) { return v1; } } return null; }; Lambda.findIndex = function(it,f) { var i = 0; var v = $getIterator(it); while(v.hasNext()) { if(f(v.next())) { return i; } ++i; } return -1; }; var Lang = function() { }; Lang.__name__ = true; Lang.request = function(path,callback) { var http = new haxe_http_HttpJs(path); http.onData = callback; http.request(); }; Lang.init = function(folderPath,callback) { var _this = Lang.ids; var _g = []; var _g1 = 0; while(_g1 < _this.length) { var v = _this[_g1]; ++_g1; if(v == Lang.lang || v == Lang.ids[0]) { _g.push(v); } } Lang.ids = _g; Lang.langs.h = Object.create(null); var count = 0; var _g = 0; var _g1 = Lang.ids; while(_g < _g1.length) { var name = [_g1[_g]]; ++_g; Lang.request("" + folderPath + "/" + name[0] + ".json",(function(name) { return function(data) { var data1 = JSON.parse(data); var lang = new haxe_ds_StringMap(); var _g = 0; var _g1 = Reflect.fields(data1); while(_g < _g1.length) { var key = _g1[_g]; ++_g; lang.h[key] = Reflect.field(data1,key); } var id = haxe_io_Path.withoutExtension(name[0]); Lang.langs.h[id] = lang; count += 1; if(count == Lang.ids.length && callback != null) { callback(); } }; })(name)); } }; Lang.get = function(key) { if(Lang.langs.h[Lang.lang] == null) { Lang.lang = Lang.ids[0]; } var text = Lang.langs.h[Lang.lang].h[key]; if(text != null) { return text; } else { return key; } }; Math.__name__ = true; var PathTools = function() { }; PathTools.__name__ = true; PathTools.urlExtension = function(url) { return StringTools.trim(haxe_io_Path.extension(new EReg("[#?]","").split(url)[0])).toLowerCase(); }; var Reflect = function() { }; Reflect.__name__ = true; Reflect.field = function(o,field) { try { return o[field]; } catch( _g ) { return null; } }; Reflect.fields = function(o) { var a = []; if(o != null) { var hasOwnProperty = Object.prototype.hasOwnProperty; for( var f in o ) { if(f != "__id__" && f != "hx__closures__" && hasOwnProperty.call(o,f)) { a.push(f); } } } return a; }; Reflect.copy = function(o) { if(o == null) { return null; } var o2 = { }; var _g = 0; var _g1 = Reflect.fields(o); while(_g < _g1.length) { var f = _g1[_g]; ++_g; o2[f] = Reflect.field(o,f); } return o2; }; var Std = function() { }; Std.__name__ = true; Std.string = function(s) { return js_Boot.__string_rec(s,""); }; Std.parseInt = function(x) { var v = parseInt(x); if(isNaN(v)) { return null; } return v; }; var StringTools = function() { }; StringTools.__name__ = true; StringTools.htmlEscape = function(s,quotes) { var buf_b = ""; var _g_offset = 0; var _g_s = s; while(_g_offset < _g_s.length) { var s = _g_s; var index = _g_offset++; var c = s.charCodeAt(index); if(c >= 55296 && c <= 56319) { c = c - 55232 << 10 | s.charCodeAt(index + 1) & 1023; } var c1 = c; if(c1 >= 65536) { ++_g_offset; } var code = c1; switch(code) { case 34: if(quotes) { buf_b += """; } else { buf_b += String.fromCodePoint(code); } break; case 38: buf_b += "&"; break; case 39: if(quotes) { buf_b += "'"; } else { buf_b += String.fromCodePoint(code); } break; case 60: buf_b += "<"; break; case 62: buf_b += ">"; break; default: buf_b += String.fromCodePoint(code); } } return buf_b; }; StringTools.startsWith = function(s,start) { if(s.length >= start.length) { return s.lastIndexOf(start,0) == 0; } else { return false; } }; StringTools.endsWith = function(s,end) { var elen = end.length; var slen = s.length; if(slen >= elen) { return s.indexOf(end,slen - elen) == slen - elen; } else { return false; } }; StringTools.isSpace = function(s,pos) { var c = HxOverrides.cca(s,pos); if(!(c > 8 && c < 14)) { return c == 32; } else { return true; } }; StringTools.ltrim = function(s) { var l = s.length; var r = 0; while(r < l && StringTools.isSpace(s,r)) ++r; if(r > 0) { return HxOverrides.substr(s,r,l - r); } else { return s; } }; StringTools.rtrim = function(s) { var l = s.length; var r = 0; while(r < l && StringTools.isSpace(s,l - r - 1)) ++r; if(r > 0) { return HxOverrides.substr(s,0,l - r); } else { return s; } }; StringTools.trim = function(s) { return StringTools.ltrim(StringTools.rtrim(s)); }; StringTools.lpad = function(s,c,l) { if(c.length <= 0) { return s; } var buf_b = ""; l -= s.length; while(buf_b.length < l) buf_b += c == null ? "null" : "" + c; buf_b += s == null ? "null" : "" + s; return buf_b; }; StringTools.rpad = function(s,c,l) { if(c.length <= 0) { return s; } var buf_b = ""; buf_b = "" + (s == null ? "null" : "" + s); while(buf_b.length < l) buf_b += c == null ? "null" : "" + c; return buf_b; }; StringTools.replace = function(s,sub,by) { return s.split(sub).join(by); }; StringTools.hex = function(n,digits) { var s = ""; do { s = "0123456789ABCDEF".charAt(n & 15) + s; n >>>= 4; } while(n > 0); if(digits != null) { while(s.length < digits) s = "0" + s; } return s; }; var _$Types_VideoItemTools = function() { }; _$Types_VideoItemTools.__name__ = true; _$Types_VideoItemTools.isPlayable = function(item) { if(item.isIncomplete == true && item.doCache) { return false; } return true; }; _$Types_VideoItemTools.withUrl = function(item,url) { return { url : url, title : item.title, author : item.author, duration : item.duration, subs : item.subs, voiceOverTrack : item.voiceOverTrack, isTemp : item.isTemp, doCache : item.doCache, isIncomplete : item.isIncomplete, playerType : item.playerType}; }; var VideoList = function() { this.items = []; this.pos = 0; }; VideoList.__name__ = true; VideoList.prototype = { setPos: function(i) { if(i < 0 || i > this.items.length - 1) { i = 0; } this.pos = i; } ,findIndex: function(f) { return Lambda.findIndex(this.items,f); } ,addItem: function(item,atEnd) { if(atEnd) { this.items.push(item); } else { this.items.splice(this.pos + 1,0,item); } } ,setNextItem: function(nextPos) { var next = this.items[nextPos]; HxOverrides.remove(this.items,next); if(nextPos < this.pos) { this.pos--; } this.items.splice(this.pos + 1,0,next); } ,toggleItemType: function(pos) { this.items[pos].isTemp = !this.items[pos].isTemp; } ,removeItem: function(index) { if(index < this.pos) { this.pos--; } HxOverrides.remove(this.items,this.items[index]); if(this.pos >= this.items.length) { this.pos = 0; } } ,skipItem: function() { var item = this.items[this.pos]; if(!item.isTemp) { this.pos++; } else { HxOverrides.remove(this.items,item); } if(this.pos >= this.items.length) { this.pos = 0; } } }; var client_Buttons = function() { }; client_Buttons.__name__ = true; client_Buttons.init = function(main) { client_Buttons.settings = main.settings; if(client_Buttons.settings.isSwapped) { client_Buttons.swapPlayerAndChat(); } var tmp = client_Buttons.split; if(tmp != null) { tmp.destroy(); } client_Buttons.split = new client_Split(client_Buttons.settings); client_Buttons.split.setSize(client_Buttons.settings.chatSize); client_Buttons.initInputs(main); var _g = 0; var _g1 = client_Buttons.settings.checkboxes; while(_g < _g1.length) { var item = _g1[_g]; ++_g; if(item.checked == null) { continue; } var id = "#" + item.id; var tmp = window.document.querySelector(id); if(tmp == null) { continue; } tmp.checked = item.checked; } var passIcon = window.document.querySelector("#guestpass_icon"); passIcon.onclick = function(e) { var icon = passIcon.firstElementChild; var isOpen = icon.getAttribute("name") == "eye-off"; var pass = window.document.querySelector("#guestpass"); if(isOpen) { pass.type = "password"; icon.setAttribute("name","eye"); } else { pass.type = "text"; icon.setAttribute("name","eye-off"); } }; var smilesBtn = window.document.querySelector("#smilesbtn"); smilesBtn.onclick = function(e) { var wrap = window.document.querySelector("#smiles-wrap"); var list = window.document.querySelector("#smiles-list"); if(list.children.length == 0) { return; } var isActive = smilesBtn.classList.toggle("active"); if(isActive) { wrap.style.display = ""; var tmp = client_Utils.outerHeight(list); wrap.style.height = tmp + "px"; } else { wrap.style.height = "0"; var onTransitionEnd = null; onTransitionEnd = function(e) { if(e.propertyName != "height") { return; } wrap.style.display = "none"; wrap.removeEventListener("transitionend",onTransitionEnd); }; } if(list.firstElementChild.dataset.src == null) { return; } var _g = 0; var _g1 = list.children; while(_g < _g1.length) { var child = _g1[_g]; ++_g; child.src = child.dataset.src; child.removeAttribute("data-src"); } }; window.document.querySelector("#scroll-to-chat-end").onclick = function(e) { main.scrollChatToEnd(); main.hideScrollToChatEndBtn(); }; window.document.querySelector("#messagebuffer").onscroll = function(e) { if(!main.isInChatEnd(1)) { return; } main.hideScrollToChatEndBtn(); }; window.document.querySelector("#clearchatbtn").onclick = function(e) { if((main.personal.group & 8) != 0) { main.send({ type : "ClearChat"}); } }; var userList = window.document.querySelector("#userlist"); userList.onclick = function(e) { if((main.personal.group & 8) == 0) { return; } var el = e.target; if(userList == el) { return; } if(!el.classList.contains("userlist_item")) { el = el.parentElement; } var name = ""; if(el.children.length == 1) { name = el.lastElementChild.innerText; } main.send({ type : "SetLeader", setLeader : { clientName : name}}); }; var userlistToggle = window.document.querySelector("#userlisttoggle"); userlistToggle.onclick = function(e) { var icon = userlistToggle.firstElementChild; var isHidden = icon.getAttribute("name") == "chevron-forward"; var wrap = window.document.querySelector("#userlist-wrap"); var style = window.document.querySelector("#userlist").style; if(isHidden) { icon.setAttribute("name","chevron-down"); style.display = ""; wrap.style.height = "15vh"; wrap.style.marginBottom = "1rem"; } else { icon.setAttribute("name","chevron-forward"); style.display = "none"; wrap.style.height = "0"; wrap.style.marginBottom = "0rem"; } client_Buttons.settings.isUserListHidden = !isHidden; client_Settings.write(client_Buttons.settings); }; window.document.querySelector("#usercount").onclick = userlistToggle.onclick; if(client_Buttons.settings.isUserListHidden) { userlistToggle.onclick(); } else { window.document.querySelector("#userlist-wrap").style.height = "15vh"; } haxe_Timer.delay(function() { window.document.querySelector("#userlist-wrap").style.transition = "200ms"; },0); var playlistMenuBtn = window.document.querySelector("#playlist-menu-btn"); var playlistMenuDropdown = window.document.querySelector("#playlist-menu-dropdown"); var toggleSynch = window.document.querySelector("#togglesynch"); toggleSynch.onclick = function(e) { playlistMenuDropdown.style.display = "none"; playlistMenuBtn.classList.remove("active"); var icon = toggleSynch.firstElementChild; if(main.isSyncActive) { if(!window.confirm(Lang.get("toggleSynchConfirm"))) { return; } main.isSyncActive = false; icon.style.color = "rgba(238, 72, 67, 0.75)"; playlistMenuBtn.classList.add("danger"); } else { main.isSyncActive = true; icon.style.color = ""; playlistMenuBtn.classList.remove("danger"); main.send({ type : "UpdatePlaylist"}); } client_Buttons.updateToggleSynchBtn(main); }; window.document.querySelector("#mediarefresh").onclick = function(e) { main.refreshPlayer(); }; window.document.querySelector("#fullscreenbtn").onclick = function(e) { return client_Utils.toggleFullscreen(window.document.querySelector("#ytapiplayer")); }; window.document.querySelector("#fullscreen-chat-btn").onclick = function(e) { e.stopPropagation(); e.preventDefault(); client_Buttons.clearUnreadChatMessages(); if(client_Buttons.settings.pageFullscreen) { client_Utils.switchToPageFullscreen(); } else { client_Utils.cancelFullscreen(); } }; client_Buttons.initPageFullscreen(); var getPlaylist = window.document.querySelector("#getplaylist"); getPlaylist.onclick = function(e) { client_Utils.copyToClipboard(main.getPlaylistLinks().join(",")); var icon = getPlaylist.firstElementChild; icon.setAttribute("name","checkmark"); return haxe_Timer.delay(function() { icon.setAttribute("name","link"); },2000); }; playlistMenuBtn.onclick = function(e) { e.stopPropagation(); var isOpen = playlistMenuDropdown.style.display != "none"; if(isOpen) { playlistMenuDropdown.style.display = "none"; playlistMenuBtn.classList.remove("active"); } else { main.hasSeenSkipVote = true; playlistMenuDropdown.style.display = ""; playlistMenuBtn.classList.add("active"); window.document.querySelector("#playlist-menu-indicator").style.display = "none"; } }; window.document.addEventListener("click",function(e) { var target = e.target; if(!playlistMenuBtn.contains(target) && !playlistMenuDropdown.contains(target)) { playlistMenuDropdown.style.display = "none"; playlistMenuBtn.classList.remove("active"); } }); window.document.querySelector("#voteskip").addEventListener("click",function() { playlistMenuDropdown.style.display = "none"; playlistMenuBtn.classList.remove("active"); }); window.document.querySelector("#clearplaylist").onclick = function(e) { playlistMenuDropdown.style.display = "none"; playlistMenuBtn.classList.remove("active"); if(!window.confirm(Lang.get("clearPlaylistConfirm"))) { return; } main.send({ type : "ClearPlaylist"}); }; window.document.querySelector("#shuffleplaylist").onclick = function(e) { playlistMenuDropdown.style.display = "none"; playlistMenuBtn.classList.remove("active"); if(!window.confirm(Lang.get("shufflePlaylistConfirm"))) { return; } main.send({ type : "ShufflePlaylist"}); }; window.document.querySelector("#lockplaylist").onclick = function(e) { if(!main.hasPermission("lockPlaylist")) { return; } if(main.isPlaylistOpen) { if(!window.confirm(Lang.get("lockPlaylistConfirm"))) { return; } } main.send({ type : "TogglePlaylistLock"}); }; var showMediaUrl = window.document.querySelector("#showmediaurl"); showMediaUrl.onclick = function(e) { playlistMenuDropdown.style.display = "none"; playlistMenuBtn.classList.remove("active"); if(client_Buttons.showPlayerGroup(showMediaUrl)) { haxe_Timer.delay(function() { window.document.querySelector("#addfromurl").scrollIntoView(); window.document.querySelector("#mediaurl").focus(); },100); } }; var showCustomEmbed = window.document.querySelector("#showcustomembed"); showCustomEmbed.onclick = function(e) { playlistMenuDropdown.style.display = "none"; playlistMenuBtn.classList.remove("active"); if(client_Buttons.showPlayerGroup(showCustomEmbed)) { haxe_Timer.delay(function() { window.document.querySelector("#customembed").scrollIntoView(); window.document.querySelector("#customembed-title").focus(); },100); } }; var mediaUrl = window.document.querySelector("#mediaurl"); var checkboxCache = window.document.querySelector("#cache-on-server"); mediaUrl.oninput = function() { var url = mediaUrl.value; var playerType = main.getLinkPlayerType(url); var isSingle = main.isSingleVideoUrl(url); var isSingleRawVideo = url != "" && playerType == "RawType" && isSingle; window.document.querySelector("#mediatitleblock").style.display = isSingleRawVideo ? "" : "none"; window.document.querySelector("#subsurlblock").style.display = isSingleRawVideo ? "" : "none"; var tmp = url.length > 0 && isSingle; window.document.querySelector("#voiceoverblock").style.display = tmp ? "" : "none"; var isExternal = main.isExternalVideoUrl(url); checkboxCache.parentElement.style.display = (main.personal.group & 8) != 0 && isSingle && isExternal && main.playersCacheSupport.indexOf(playerType) != -1 ? "" : "none"; checkboxCache.checked = client_Buttons.settings.checkedCache.indexOf(playerType) != -1; var panel = window.document.querySelector("#addfromurl"); var oldH = panel.style.height; panel.style.height = ""; var newH = client_Utils.outerHeight(panel) + "px"; panel.style.height = oldH; return haxe_Timer.delay(function() { panel.style.height = newH; },0); }; mediaUrl.onfocus = mediaUrl.oninput; checkboxCache.addEventListener("change",function() { var url = mediaUrl.value; var playerType = main.getLinkPlayerType(url); var checked = checkboxCache.checked; HxOverrides.remove(client_Buttons.settings.checkedCache,playerType); if(checked) { client_Buttons.settings.checkedCache.push(playerType); } client_Settings.write(client_Buttons.settings); }); window.document.querySelector("#insert_template").onclick = function(e) { mediaUrl.value = main.getTemplateUrl(); mediaUrl.focus(); }; window.document.querySelector("#mediaurl-upload").onclick = function(e) { if((main.personal.group & 8) == 0) { main.serverMessage("Only admins may upload files.",true,false); return; } client_Utils.browseJsFile(function(file) { new client_FileUploader(main).uploadFile(file); }); }; var showOptions = window.document.querySelector("#showoptions"); showOptions.onclick = function(e) { var isActive = client_Buttons.toggleGroup(showOptions); var tmp = isActive ? "1" : "0"; window.document.querySelector("#optionsPanel").style.opacity = tmp; return haxe_Timer.delay(function() { if(showOptions.classList.contains("active") != isActive) { return; } window.document.querySelector("#optionsPanel").classList.toggle("collapse",!isActive); },isActive ? 0 : 200); }; window.document.querySelector("#exitBtn").onclick = function(e) { showOptions.onclick(); if((main.personal.group & 2) != 0) { main.send({ type : "Logout"}); } else { window.document.querySelector("#guestname").focus(); } }; window.document.querySelector("#swapLayoutBtn").onclick = function(e) { client_Buttons.swapPlayerAndChat(); client_Settings.write(client_Buttons.settings); }; }; client_Buttons.showPlayerGroup = function(el) { var groups = window.document.querySelectorAll("[data-target]"); var _g = 0; while(_g < groups.length) { var group = groups[_g]; ++_g; if(el == group) { continue; } if(group.classList.contains("collapsed")) { continue; } client_Buttons.toggleGroup(group); } return client_Buttons.toggleGroup(el); }; client_Buttons.toggleGroup = function(el) { el.classList.toggle("collapsed"); var id = el.dataset.target; var target = window.document.querySelector(id); var isClosed = target.classList.toggle("collapse"); if(isClosed) { target.style.height = "0"; } else { var list = target.firstElementChild; if(target.style.height == "") { target.style.height = "0"; } haxe_Timer.delay(function() { var tmp = client_Utils.outerHeight(list); target.style.height = tmp + "px"; },0); } return el.classList.toggle("active"); }; client_Buttons.swapPlayerAndChat = function() { client_Buttons.settings.isSwapped = window.document.querySelector("body").classList.toggle("swap"); var sizes = window.document.body.style.gridTemplateColumns.split(" "); sizes.reverse(); window.document.body.style.gridTemplateColumns = sizes.join(" "); }; client_Buttons.initTextButtons = function(main) { window.document.querySelector("#synchThresholdBtn").onclick = function(e) { var secs = client_Buttons.settings.synchThreshold + 1; if(secs > 5) { secs = 1; } main.setSynchThreshold(secs); client_Buttons.updateSynchThresholdBtn(); }; client_Buttons.updateSynchThresholdBtn(); window.document.querySelector("#hotkeysBtn").onclick = function(e) { client_Buttons.settings.hotkeysEnabled = !client_Buttons.settings.hotkeysEnabled; client_Settings.write(client_Buttons.settings); client_Buttons.updateHotkeysBtn(); }; client_Buttons.updateHotkeysBtn(); window.document.querySelector("#pageFullscreenBtn").onclick = function(e) { client_Buttons.settings.pageFullscreen = !client_Buttons.settings.pageFullscreen; client_Settings.write(client_Buttons.settings); client_Buttons.updatePageFullscreenBtn(); if(client_Buttons.settings.pageFullscreen) { client_Utils.switchToPageFullscreen(); } else { client_Utils.cancelFullscreen(); } }; client_Buttons.updatePageFullscreenBtn(); var fullscreenActionBtn = window.document.querySelector("#fullscreenActionBtn"); if(fullscreenActionBtn != null) { fullscreenActionBtn.onclick = function(e) { client_Buttons.settings.fullscreenAction = !client_Buttons.settings.fullscreenAction; client_Settings.write(client_Buttons.settings); client_Buttons.updateFullscreenActionBtn(); }; client_Buttons.updateFullscreenActionBtn(); } window.document.body.addEventListener("click",function(e) { if(!client_Buttons.settings.pageFullscreen) { return; } if(client_Utils.hasFullscreen()) { return; } var target = e.target; if(target != null && target.closest("button, input, a, textarea, select, #optionsPanel, #chatline, #userlist, .queue_sortable, .nav") != null) { return; } client_Utils.requestFullscreen(window.document.documentElement); }); var removeBtn = window.document.querySelector("#removePlayerBtn"); removeBtn.onclick = function(e) { if(main.toggleVideoElement()) { return removeBtn.innerText = Lang.get("removePlayer"); } else { return removeBtn.innerText = Lang.get("restorePlayer"); } }; window.document.querySelector("#setVideoUrlBtn").onclick = function(e) { var src = window.prompt(Lang.get("setVideoUrlPrompt")); if(StringTools.trim(src) == "") { main.refreshPlayer(); return; } client_JsApi.setVideoSrc(src); }; window.document.querySelector("#selectLocalVideoBtn").onclick = function(e) { client_Utils.browseFileUrl(function(url,name) { client_JsApi.setVideoSrc(url); }); }; client_Buttons.updateToggleSynchBtn(main); }; client_Buttons.initHotkeys = function(main,player) { window.document.querySelector("#mediarefresh").title += " (Alt-R)"; window.document.querySelector("#voteskip").title += " (Alt-S)"; window.document.querySelector("#getplaylist").title += " (Alt-C)"; window.document.querySelector("#fullscreenbtn").title += " (Alt-F)"; window.document.querySelector("#leader_btn").title += " (Alt-L)"; window.onkeydown = function(e) { if(!client_Buttons.settings.hotkeysEnabled) { return; } var target = e.target; if(client_Buttons.isElementEditable(target)) { return; } var key = e.keyCode; if(key == 8) { e.preventDefault(); } if(!e.altKey) { return; } switch(key) { case 67: window.document.querySelector("#getplaylist").onclick(); break; case 70: window.document.querySelector("#fullscreenbtn").onclick(); break; case 76: main.toggleLeader(); break; case 80: main.toggleLeaderAndPause(); break; case 82: window.document.querySelector("#mediarefresh").onclick(); break; case 83: window.document.querySelector("#voteskip").onclick(); break; case 85: window.document.querySelector("#togglesynch").onclick(); break; default: return; } e.preventDefault(); }; }; client_Buttons.isElementEditable = function(target) { if(target == null) { return false; } if(target.isContentEditable) { return true; } var tagName = target.tagName; if(tagName == "INPUT" || tagName == "TEXTAREA") { return true; } return false; }; client_Buttons.updateSynchThresholdBtn = function() { var tmp = "" + Lang.get("synchThreshold") + ": " + client_Buttons.settings.synchThreshold; window.document.querySelector("#synchThresholdBtn").innerText = tmp + "s"; }; client_Buttons.updateHotkeysBtn = function() { var btn = window.document.querySelector("#hotkeysBtn"); var switchEl = btn.querySelector(".toggle-switch"); if(switchEl == null) { btn.innerHTML = "" + Lang.get("hotkeys") + "
"; switchEl = btn.querySelector(".toggle-switch"); } switchEl.classList.toggle("on",client_Buttons.settings.hotkeysEnabled); window.document.body.classList.toggle("hotkeys-disabled",!client_Buttons.settings.hotkeysEnabled); }; client_Buttons.updatePageFullscreenBtn = function() { var btn = window.document.querySelector("#pageFullscreenBtn"); var switchEl = btn.querySelector(".toggle-switch"); if(switchEl == null) { btn.innerHTML = "" + Lang.get("pageFullscreen") + ""; switchEl = btn.querySelector(".toggle-switch"); } switchEl.classList.toggle("on",client_Buttons.settings.pageFullscreen); }; client_Buttons.updateFullscreenActionBtn = function() { var btn = window.document.querySelector("#fullscreenActionBtn"); var switchEl = btn.querySelector(".toggle-switch"); if(switchEl == null) { btn.innerHTML = "" + Lang.get(client_Utils.isTouch() ? "fullscreenActionTouch" : "fullscreenActionDesktop") + ""; switchEl = btn.querySelector(".toggle-switch"); } switchEl.classList.toggle("on",client_Buttons.settings.fullscreenAction); }; client_Buttons.updateToggleSynchBtn = function(main) { var toggleSynch = window.document.querySelector("#togglesynch"); var span = toggleSynch.querySelector("span"); var text = Lang.get(main.isSyncActive ? "disableVideoSync" : "enableVideoSync"); toggleSynch.title = "" + text + " (Alt-U)"; if(span != null) { span.innerHTML = "" + text + " (Alt-U)"; } }; client_Buttons.initInputs = function(main) { var guestName = window.document.querySelector("#guestname"); guestName.onkeydown = function(e) { if(e.keyCode == 13) { main.guestLogin(guestName.value); if(client_Utils.isTouch()) { guestName.blur(); } } }; var guestPass = window.document.querySelector("#guestpass"); guestPass.onkeydown = function(e) { if(e.keyCode == 13) { main.userLogin(guestName.value,guestPass.value); guestPass.value = ""; if(client_Utils.isTouch()) { guestPass.blur(); } } }; var viewport = window.visualViewport; if(viewport != null) { viewport.addEventListener("resize",function(e) { client_Buttons.onViewportResize(); }); client_Buttons.onViewportResize(); } var checkboxes = [window.document.querySelector("#add-temp")]; var _g = 0; while(_g < checkboxes.length) { var checkbox = [checkboxes[_g]]; ++_g; checkbox[0].addEventListener("change",(function(checkbox) { return function() { var checked = checkbox[0].checked; var item = Lambda.find(client_Buttons.settings.checkboxes,(function(checkbox) { return function(item) { return item.id == checkbox[0].id; }; })(checkbox)); HxOverrides.remove(client_Buttons.settings.checkboxes,item); client_Buttons.settings.checkboxes.push({ id : checkbox[0].id, checked : checked}); client_Settings.write(client_Buttons.settings); }; })(checkbox)); } }; client_Buttons.onViewportResize = function() { var tmp = window.visualViewport; if(tmp == null) { return; } var isPortrait = window.innerHeight > window.innerWidth; var playerH = window.document.querySelector("#ytapiplayer").offsetHeight; var h = tmp.height - playerH; if(!isPortrait) { h = tmp.height; } window.document.querySelector("#chat").style.height = "" + h + "px"; }; client_Buttons.onNewChatMessage = function() { client_Buttons.hasUnreadChatMessages = true; client_Buttons.updateFullscreenChatBtn(); }; client_Buttons.clearUnreadChatMessages = function() { client_Buttons.hasUnreadChatMessages = false; client_Buttons.updateFullscreenChatBtn(); }; client_Buttons.updateFullscreenChatBtn = function() { var chatBtn = window.document.querySelector("#fullscreen-chat-btn"); if(client_Utils.hasFullscreen() && client_Buttons.hasUnreadChatMessages) { chatBtn.classList.add("has-unread"); } else { chatBtn.classList.remove("has-unread"); } }; client_Buttons.initPageFullscreen = function() { window.document.onfullscreenchange = function(e) { client_Buttons.clearUnreadChatMessages(); client_Buttons.updateFullscreenChatBtn(); }; }; var client_ChatInput = function(main) { this.selectedCommandIndex = -1; this.filteredCommands = []; this.main = main; this.chatline = window.document.querySelector("#chatline"); this.commandsWrap = window.document.querySelector("#chat-commands-wrap"); this.commandsList = window.document.querySelector("#chat-commands-list"); this.setupFocusHandler(); this.setupAutocomplete(); this.inputWithHistory = new client_InputWithHistory(this.chatline,null,50,$bind(this,this.onEnter),$bind(this,this.onInterceptKeyDown)); }; client_ChatInput.__name__ = true; client_ChatInput.prototype = { setupFocusHandler: function() { var _gthis = this; this.chatline.onfocus = function(e) { if(client_Utils.isIOS()) { var startY = 0; haxe_Timer.delay(function() { window.scrollBy(0,-(window.scrollY - startY)); window.document.querySelector("#video").scrollTop = 0; _gthis.main.scrollChatToEnd(); },100); } else if(client_Utils.isTouch()) { _gthis.main.scrollChatToEnd(); } }; } ,setupAutocomplete: function() { var _gthis = this; this.commandsList.addEventListener("mousemove",function(e) { _gthis.commandsList.classList.remove("keyboard-nav"); }); this.chatline.addEventListener("input",function(e) { var val = _gthis.chatline.value; if(StringTools.startsWith(val,"/")) { _gthis.filteredCommands = client_Commands.filterForAutocomplete(val); _gthis.selectedCommandIndex = _gthis.filteredCommands.length > 0 ? 0 : -1; _gthis.renderCommands(); } else { _gthis.commandsWrap.style.display = "none"; _gthis.selectedCommandIndex = -1; } }); this.chatline.addEventListener("blur",function(e) { return _gthis.commandsWrap.style.display = "none"; }); } ,renderCommands: function() { var _gthis = this; this.commandsList.innerHTML = ""; if(this.filteredCommands.length == 0) { this.commandsWrap.style.display = "none"; return; } var parsed = client_Commands.parse(this.chatline.value); var currentArgIndex = parsed.currentArgIndex; var _g = 0; var _g1 = this.filteredCommands.length; while(_g < _g1) { var i = [_g++]; var cmd = [this.filteredCommands[i[0]]]; var item = window.document.createElement("div"); item.className = "chat-command-item" + (i[0] == this.selectedCommandIndex ? " active" : ""); item.onclick = (function(cmd) { return function(e) { _gthis.chatline.value = (cmd[0].name == null ? "null" : cmd[0].name) + (cmd[0].args > 0 ? " " : ""); _gthis.chatline.focus(); if(cmd[0].args == 0) { _gthis.commandsWrap.style.display = "none"; _gthis.selectedCommandIndex = -1; } else { _gthis.chatline.dispatchEvent(new Event("input")); } }; })(cmd); item.onmouseenter = (function(i) { return function(e) { if(!_gthis.commandsList.classList.contains("keyboard-nav")) { _gthis.selectedCommandIndex = i[0]; var _g = 0; var _g1 = _gthis.commandsList.children.length; while(_g < _g1) { var j = _g++; var child = _gthis.commandsList.children[j]; if(j == i[0]) { child.classList.add("active"); } else { child.classList.remove("active"); } } } }; })(i); var nameDiv = window.document.createElement("div"); nameDiv.className = "chat-command-item-name"; nameDiv.innerText = cmd[0].name; var descDiv = window.document.createElement("div"); descDiv.className = "chat-command-item-desc"; descDiv.innerHTML = client_Commands.formatDescWithHighlight(Lang.get(cmd[0].lang),currentArgIndex); item.appendChild(nameDiv); item.appendChild(descDiv); this.commandsList.appendChild(item); } this.commandsWrap.style.display = ""; if(this.selectedCommandIndex >= 0 && this.commandsList.children.length > this.selectedCommandIndex) { var selectedEl = this.commandsList.children[this.selectedCommandIndex]; selectedEl.scrollIntoView({ block : "center"}); } } ,onEnter: function(value) { if(this.main.handleCommands(value)) { return true; } this.main.send({ type : "Message", message : { clientName : "", text : value}}); if(client_Utils.isTouch()) { this.chatline.blur(); } this.commandsWrap.style.display = "none"; return true; } ,onInterceptKeyDown: function(e) { if(this.commandsWrap.style.display == "none") { return false; } var key = e.keyCode; switch(key) { case 9:case 13: if(this.selectedCommandIndex < 0 || this.selectedCommandIndex >= this.filteredCommands.length) { return false; } var selectedCmd = this.filteredCommands[this.selectedCommandIndex]; var val = this.chatline.value; var hasSpace = val.indexOf(" ") >= 0; if(key == 13) { if(hasSpace || selectedCmd.args == 0 && StringTools.trim(val).toLowerCase() == selectedCmd.name) { return false; } } if(!hasSpace) { this.chatline.value = (selectedCmd.name == null ? "null" : selectedCmd.name) + (selectedCmd.args > 0 ? " " : ""); } e.preventDefault(); this.chatline.dispatchEvent(new Event("input")); return true; case 27: this.commandsWrap.style.display = "none"; return false; case 38: this.commandsList.classList.add("keyboard-nav"); if(this.selectedCommandIndex > 0) { this.selectedCommandIndex--; } else { this.selectedCommandIndex = this.filteredCommands.length - 1; } this.renderCommands(); e.preventDefault(); return true; case 40: this.commandsList.classList.add("keyboard-nav"); if(this.selectedCommandIndex < this.filteredCommands.length - 1) { this.selectedCommandIndex++; } else { this.selectedCommandIndex = 0; } this.renderCommands(); e.preventDefault(); return true; default: return false; } } }; var client_CommandInfo = function(name,args,aliases) { if(args == null) { args = 0; } this.name = name; this.args = args; this.aliases = aliases != null ? aliases : []; this.lang = this.getLangId(); }; client_CommandInfo.__name__ = true; client_CommandInfo.prototype = { getLangId: function() { var withoutSlash = HxOverrides.substr(this.name,1,null); return "cmd" + withoutSlash.charAt(0).toUpperCase() + HxOverrides.substr(withoutSlash,1,null); } }; var client_Commands = function() { }; client_Commands.__name__ = true; client_Commands.find = function(name) { var lower = name.toLowerCase(); var _g = 0; var _g1 = client_Commands.list; while(_g < _g1.length) { var c = _g1[_g]; ++_g; if(c.name == lower) { return c; } var _g2 = 0; var _g3 = c.aliases; while(_g2 < _g3.length) if(_g3[_g2++].toLowerCase() == lower) { return c; } } return null; }; client_Commands.parse = function(input) { if(!StringTools.startsWith(input,"/")) { return { cmd : null, rawCmd : "", args : [], currentArgIndex : -1}; } var parts = input.split(" "); var rawCmd = parts[0]; var args = parts.slice(1); var currentArgIndex = args.length > 0 ? args.length - 1 : -1; return { cmd : client_Commands.find(rawCmd), rawCmd : rawCmd, args : args, currentArgIndex : currentArgIndex}; }; client_Commands.filterForAutocomplete = function(val) { if(!StringTools.startsWith(val,"/")) { return []; } var parts = val.toLowerCase().split(" "); var searchCmd = parts[0]; var spaceCount = parts.length - 1; var result = []; var _g = 0; var _g1 = client_Commands.list; while(_g < _g1.length) { var c = _g1[_g]; ++_g; if(spaceCount == 0) { if(StringTools.startsWith(c.name,searchCmd)) { result.push(c); } else { var _g2 = 0; var _g3 = c.aliases; while(_g2 < _g3.length) if(StringTools.startsWith(_g3[_g2++].toLowerCase(),searchCmd)) { result.push(c); break; } } } else if(spaceCount <= c.args) { if(c.name == searchCmd) { result.push(c); } else { var _g4 = 0; var _g5 = c.aliases; while(_g4 < _g5.length) if(_g5[_g4++].toLowerCase() == searchCmd) { result.push(c); break; } } } } return result; }; client_Commands.formatDescWithHighlight = function(desc,activeArgIndex) { desc = StringTools.htmlEscape(desc); var argCounter = 0; desc = new EReg("<[^&]+>","g").map(desc,function(reg) { var token = reg.matched(0); var isCurrent = argCounter == activeArgIndex; argCounter += 1; if(isCurrent) { return "" + token + ""; } else { return token; } }); return new EReg("`([^`]+)`","g").map(desc,function(reg) { return "" + reg.matched(1) + ""; }); }; var client_FileUploader = function(main) { this.main = main; }; client_FileUploader.__name__ = true; client_FileUploader.prototype = { uploadFile: function(file) { var _gthis = this; if((this.main.personal.group & 8) == 0) { this.main.serverMessage("Only admins may upload files.",true,false); return; } var _this_r = new RegExp("[?#%/\\\\]","g".split("u").join("")); var title = StringTools.trim(file.name.replace(_this_r,"")); if(title.length == 0) { title = "video"; } var name = window.encodeURIComponent(title); var isTemp = client_Main.isTempChecked(window.document.querySelector("#addfromurl .add-temp")); this.uploadLastChunk(file,name,function(data) { if(data.errorId != null) { _gthis.main.serverMessage(data.info,true,false); return; } var url = data.url; _gthis.getFileDuration(file,function(duration) { if(duration == 0 || isNaN(duration) || !isFinite(duration)) { _gthis.main.serverMessage(Lang.get("addVideoError"),true,false); return; } _gthis.uploadFullFile(name,file,url,function() { _gthis.main.addUploadedVideo(url,title,duration,true,isTemp); }); }); }); } ,getFileDuration: function(file,callback) { var objUrl = URL.createObjectURL(file); var video = window.document.createElement("video"); video.preload = "metadata"; video.muted = true; video.onloadedmetadata = function() { var duration = video.duration; URL.revokeObjectURL(objUrl); callback(duration); }; video.onerror = function(e) { URL.revokeObjectURL(objUrl); callback(0); }; video.src = objUrl; } ,uploadFullFile: function(name,file,url,onStarted) { var _gthis = this; var request = new XMLHttpRequest(); request.open("POST","/upload",true); request.setRequestHeader("content-name",name); var tmp = this.main.settings.uuid; request.setRequestHeader("x-client-uuid",tmp != null ? tmp : ""); var added = false; var ensureAdded = function() { if(added) { return; } added = true; onStarted(); _gthis.main.registerUpload(url,function() { request.abort(); }); }; var sendProgress = function(type,ratio) { _gthis.main.send({ type : "Progress", progress : { type : type, ratio : ratio, url : url}}); }; var lastSentRatio = 0.0; request.upload.onprogress = function(event) { ensureAdded(); var ratio = 0.0; if(event.lengthComputable) { var v = event.loaded / event.total; ratio = v < 0 ? 0 : v > 1 ? 1 : v; } if(ratio - lastSentRatio < 0.01 && ratio < 1) { return; } lastSentRatio = ratio; sendProgress("Uploading",ratio); }; request.onload = function(e) { _gthis.main.unregisterUpload(url); var data; try { data = JSON.parse(request.responseText); } catch( _g ) { haxe_Log.trace(haxe_Exception.caught(_g),{ fileName : "src/client/FileUploader.hx", lineNumber : 112, className : "client.FileUploader", methodName : "uploadFullFile"}); sendProgress("Canceled",0); return; } if(data.errorId != null) { _gthis.main.serverMessage(data.info,true,false); sendProgress("Canceled",0); return; } ensureAdded(); sendProgress("Completed",1); }; request.onerror = function(e) { _gthis.main.unregisterUpload(url); sendProgress("Canceled",0); }; request.onabort = function(e) { _gthis.main.unregisterUpload(url); }; request.send(file); } ,uploadLastChunk: function(file,name,callback) { var a = file.size - 5242880; var lastChunk = file.slice(a < 0 ? 0 : a); var tmp = this.main.settings.uuid; var chunkReq = window.fetch("/upload-last-chunk",{ method : "POST", headers : { "content-name" : name, "x-client-uuid" : tmp != null ? tmp : ""}, body : lastChunk}); chunkReq.then(function(e) { return e.json().then(function(data) { callback(data); }); }); } }; var client_InputWithHistory = function(element,history,maxItems,onEnter,onInterceptKeyDown) { this.historyId = -1; this.element = element; if(history != null) { this.history = history; } else { this.history = []; } this.maxItems = maxItems; this.onEnter = onEnter; this.onInterceptKeyDown = onInterceptKeyDown; element.onkeydown = $bind(this,this.onKeyDown); }; client_InputWithHistory.__name__ = true; client_InputWithHistory.pushIfNotLast = function(arr,item) { var len = arr.length; if(len == 0 || arr[len - 1] != item) { arr.push(item); } }; client_InputWithHistory.prototype = { onKeyDown: function(e) { if(this.onInterceptKeyDown != null && this.onInterceptKeyDown(e)) { return; } var key = e.keyCode; switch(key) { case 13: var value = StringTools.trim(this.element.value); if(value.length == 0) { return; } if(this.onEnter(value)) { client_InputWithHistory.pushIfNotLast(this.history,value); } if(this.history.length > this.maxItems) { this.history.shift(); } this.historyId = -1; this.element.value = ""; this.onInput(); break; case 27: e.preventDefault(); break; case 38: this.historyId--; if(this.historyId == -2) { this.historyId = this.history.length - 1; if(this.historyId == -1) { return; } } else if(this.historyId == -1) { this.historyId++; } this.element.value = this.history[this.historyId]; this.onInput(); break; case 40: if(this.historyId == -1) { return; } this.historyId++; if(this.historyId > this.history.length - 1) { this.historyId = -1; this.element.value = ""; } else { this.element.value = this.history[this.historyId]; } this.onInput(); break; default: } } ,onInput: function() { this.element.dispatchEvent(new Event("input")); } }; var client_JsApi = function() { }; client_JsApi.__name__ = true; client_JsApi.init = function(main,player) { client_JsApi.main = main; client_JsApi.player = player; client_JsApi.initPluginsSpace(); }; client_JsApi.initPluginsSpace = function() { var w = window; w.synctube = w.synctube != null ? w.synctube : { }; }; client_JsApi.addPlugin = $hx_exports["client"]["JsApi"]["addPlugin"] = function(id,onLoaded) { client_JsApi.addScriptToHead("/plugins/" + id + "/index.js",function() { var obj = { api : client.JsApi, id : id, path : "/plugins/" + id}; if(window.synctube[id] == null) { window.console.error("Plugin \"" + id + "\" not found"); } else { new synctube[id](obj); if(onLoaded != null) { onLoaded(); } } }); }; client_JsApi.addScriptToHead = $hx_exports["client"]["JsApi"]["addScriptToHead"] = function(url,onLoaded) { var script = window.document.createElement("script"); script.type = "text/javascript"; script.onload = onLoaded; script.src = url; window.document.head.appendChild(script); }; client_JsApi.hasScriptInHead = $hx_exports["client"]["JsApi"]["hasScriptInHead"] = function(url) { var abs = new URL(url,window.document.baseURI).href; var _g = 0; var _g1 = window.document.getElementsByTagName("head")[0].children; while(_g < _g1.length) if(_g1[_g++].src == abs) { return true; } return false; }; client_JsApi.getVideoItems = $hx_exports["client"]["JsApi"]["getVideoItems"] = function() { var items = client_JsApi.player.getItems(); var _g = []; var _g1 = 0; while(_g1 < items.length) _g.push(Reflect.copy(items[_g1++])); return _g; }; client_JsApi.addVideoItem = $hx_exports["client"]["JsApi"]["addVideoItem"] = function(url,atEnd,isTemp,afterSend,doCache) { if(doCache == null) { doCache = false; } client_JsApi.main.addVideo(url,atEnd,isTemp,doCache,afterSend); }; client_JsApi.removeVideoItem = $hx_exports["client"]["JsApi"]["removeVideoItem"] = function(url) { client_JsApi.main.removeVideoItem(url); }; client_JsApi.getTime = $hx_exports["client"]["JsApi"]["getTime"] = function() { return client_JsApi.player.getTime(); }; client_JsApi.setTime = $hx_exports["client"]["JsApi"]["setTime"] = function(time) { client_JsApi.player.setTime(time); }; client_JsApi.isLeader = $hx_exports["client"]["JsApi"]["isLeader"] = function() { return (client_JsApi.main.personal.group & 4) != 0; }; client_JsApi.forceSyncNextTick = $hx_exports["client"]["JsApi"]["forceSyncNextTick"] = function(flag) { client_JsApi.main.forceSyncNextTick = flag; }; client_JsApi.setVideoSrc = $hx_exports["client"]["JsApi"]["setVideoSrc"] = function(url) { client_JsApi.player.changeVideoSrc(url); }; client_JsApi.getLocalIp = $hx_exports["client"]["JsApi"]["getLocalIp"] = function() { return client_JsApi.main.host; }; client_JsApi.getGlobalIp = $hx_exports["client"]["JsApi"]["getGlobalIp"] = function() { return client_JsApi.main.globalIp; }; client_JsApi.addSubtitleSupport = $hx_exports["client"]["JsApi"]["addSubtitleSupport"] = function(format) { format = StringTools.trim(format).toLowerCase(); if(client_JsApi.subtitleFormats.indexOf(format) != -1) { return; } client_JsApi.subtitleFormats.push(format); }; client_JsApi.hasSubtitleSupport = $hx_exports["client"]["JsApi"]["hasSubtitleSupport"] = function(format) { if(format == null) { return client_JsApi.subtitleFormats.length > 0; } return client_JsApi.subtitleFormats.indexOf(format) != -1; }; client_JsApi.once = $hx_exports["client"]["JsApi"]["once"] = function(type,callback) { client_JsApi.onceListeners.unshift({ type : type, callback : callback}); }; client_JsApi.fireEvents = function(event) { var listeners = client_JsApi.onListeners.slice(); var _g_i = listeners.length - 1; while(_g_i > -1) { var listener = listeners[_g_i--]; if(listener.type != event.type) { continue; } listener.callback(event); } var onces = client_JsApi.onceListeners.slice(); var _g_i = onces.length - 1; while(_g_i > -1) { var listener = onces[_g_i--]; if(listener.type != event.type) { continue; } HxOverrides.remove(client_JsApi.onceListeners,listener); listener.callback(event); } }; client_JsApi.notifyOnVideoChange = $hx_exports["client"]["JsApi"]["notifyOnVideoChange"] = function(callback) { client_JsApi.videoChange.push(callback); }; client_JsApi.removeFromVideoChange = $hx_exports["client"]["JsApi"]["removeFromVideoChange"] = function(callback) { HxOverrides.remove(client_JsApi.videoChange,callback); }; client_JsApi.fireVideoChangeEvents = function(item) { var _g = 0; var _g1 = client_JsApi.videoChange; while(_g < _g1.length) _g1[_g++](item); }; client_JsApi.notifyOnVideoRemove = $hx_exports["client"]["JsApi"]["notifyOnVideoRemove"] = function(callback) { client_JsApi.videoRemove.push(callback); }; client_JsApi.removeFromVideoRemove = $hx_exports["client"]["JsApi"]["removeFromVideoRemove"] = function(callback) { HxOverrides.remove(client_JsApi.videoRemove,callback); }; client_JsApi.fireVideoRemoveEvents = function(item) { var _g = 0; var _g1 = client_JsApi.videoRemove; while(_g < _g1.length) _g1[_g++](item); }; var client_Main = function() { this.matchSimpleDate = new EReg("^-?([0-9]+d)?([0-9]+h)?([0-9]+m)?([0-9]+s?)?$",""); this.activeUploads = new haxe_ds_StringMap(); this.urlMask = new EReg("\\${([0-9]+)-([0-9]+)}","g"); this.isPageVisible = true; this.isPageUnloading = false; this.msgBuf = window.document.querySelector("#messagebuffer"); this.gotFirstPageInteraction = false; this.disabledReconnection = false; this.gotInitialConnection = false; this.isConnected = false; this.personal = new Client("Unknown",0); this.filters = []; this.pageTitle = window.document.title; this.clients = []; this.lastStateTimeStamp = 0.0; this.lastState = { time : 0, rate : 1.0, paused : false, pausedByServer : false}; this.timeFromLastState = 0.0; this.skipVoteRequired = 0; this.skipVoteCount = 0; this.hasSeenSkipVote = false; this.showingServerPause = false; this.playersCacheSupport = []; this.isPlaylistOpen = true; this.globalIp = ""; this.isVideoEnabled = true; this.forceSyncNextTick = false; this.isSyncActive = true; var _gthis = this; client_Main.instance = this; haxe_Log.trace = client_Utils.nativeTrace; this.player = new client_Player(this); this.host = $global.location.hostname; if(this.host == "") { this.host = "localhost"; } client_Settings.init({ version : 7, uuid : null, name : "", hash : "", chatSize : 300, synchThreshold : 1, isSwapped : false, isUserListHidden : true, latestLinks : [], latestSubs : [], hotkeysEnabled : true, pageFullscreen : false, fullscreenAction : client_Utils.isTouch(), showHintList : true, checkboxes : [], checkedCache : []},$bind(this,this.settingsPatcher)); this.settings = client_Settings.read(); this.initListeners(); this.onTimeGet = new haxe_Timer(this.settings.synchThreshold * 1000); this.onTimeGet.run = $bind(this,this.requestTime); window.document.onvisibilitychange = function() { if(!window.document.hidden && _gthis.onBlinkTab != null) { window.document.title = _gthis.getPageTitle(); _gthis.onBlinkTab.stop(); _gthis.onBlinkTab = null; } }; Lang.init("langs",function() { client_Buttons.initTextButtons(_gthis); client_Buttons.initHotkeys(_gthis,_gthis.player); _gthis.openWebSocket(); }); client_JsApi.init(this,this.player); window.document.addEventListener("click",$bind(this,this.onFirstInteraction)); window.addEventListener("beforeunload",function() { return _gthis.isPageUnloading = true; }); window.addEventListener("blur",function() { var tmp = window.document.activeElement; if((tmp != null ? tmp.tagName : null) == "IFRAME") { return; } _gthis.isPageVisible = false; }); window.addEventListener("focus",function() { return _gthis.isPageVisible = true; }); window.document.addEventListener("visibilitychange",function() { return _gthis.isPageVisible = window.document.visibilityState == "visible"; }); }; client_Main.__name__ = true; client_Main.main = function() { new client_Main(); }; client_Main.isTempChecked = function(checkbox) { if(checkbox == null) { return true; } var isHidden = checkbox.style.display == "none"; if(isHidden) { return true; } else { return checkbox.checked; } }; client_Main.prototype = { onFirstInteraction: function() { if(this.gotFirstPageInteraction) { return; } if(!this.player.isVideoLoaded()) { return; } this.gotFirstPageInteraction = true; this.player.unmute(); if(!this.hasLeader() && !this.showingServerPause && !this.player.inUserInteraction) { this.player.play(); } window.document.removeEventListener("click",$bind(this,this.onFirstInteraction)); } ,settingsPatcher: function(data,version) { switch(version) { case 1:case 2:case 3:case 4: break; case 5: client_Settings.reset(); data = client_Settings.read(); break; case 6: var data1 = data; data1.pageFullscreen = false; data1.fullscreenAction = client_Utils.isTouch(); break; case 7: throw haxe_Exception.thrown("skipped version " + version); default: throw haxe_Exception.thrown("skipped version " + version); } return data; } ,requestTime: function() { if(!this.isSyncActive) { return; } if(this.player.isListEmpty()) { return; } if(!_$Types_VideoItemTools.isPlayable(this.player.getCurrentItem())) { return; } this.send({ type : "GetTime"}); } ,openWebSocket: function() { var _gthis = this; var protocol = "ws:"; if($global.location.protocol == "https:") { protocol = "wss:"; } var port = $global.location.port; var colonPort = port.length > 0 ? ":" + port : port; var path = $global.location.pathname; this.ws = new WebSocket("" + protocol + "//" + this.host + colonPort + path + (this.settings.uuid == null ? "" : "?uuid=" + this.settings.uuid)); this.ws.onmessage = $bind(this,this.onMessage); this.ws.onopen = function() { var tmp = _gthis.disconnectNotification; if(tmp != null) { tmp.stop(); } _gthis.disconnectNotification = null; _gthis.chatMessageConnected(); _gthis.gotInitialConnection = true; return _gthis.isConnected = true; }; this.ws.onclose = function() { _gthis.isConnected = false; var notificationDelay = _gthis.gotInitialConnection ? 5000 : 0; if(_gthis.disabledReconnection) { notificationDelay = 0; } if(_gthis.disconnectNotification == null) { _gthis.disconnectNotification = haxe_Timer.delay(function() { if(_gthis.isConnected) { return; } _gthis.chatMessageDisconnected(); _gthis.player.pause(); },notificationDelay); } if(_gthis.disabledReconnection) { return; } haxe_Timer.delay($bind(_gthis,_gthis.openWebSocket),_gthis.gotInitialConnection ? 1000 : 2000); }; } ,initListeners: function() { var _gthis = this; this.chatInput = new client_ChatInput(this); client_Buttons.init(this); var openBtn = window.document.getElementById("openChatBtn"); var openBtnFadeTimer = null; if(openBtn == null) { openBtn = window.document.createElement("button"); openBtn.id = "openChatBtn"; openBtn.innerText = "Expand"; openBtn.setAttribute("style","position: fixed; right: 0; top: 50%; transform: translateY(-50%); z-index: 10000; display: none; padding: .5rem; background: rgba(0,0,0,0.4); color: var(--foreground); border: none; border-radius: .25rem 0 0 .25rem; transition: opacity 200ms; opacity: 1;"); window.document.body.appendChild(openBtn); } var toggleChatBtn = window.document.querySelector("#togglechat"); openBtn.onclick = function(e) { toggleChatBtn.click(); }; openBtn.onmouseenter = function(e) { openBtn.style.opacity = "1"; if(openBtnFadeTimer != null) { openBtnFadeTimer.stop(); } }; openBtn.onmouseleave = function(e) { if(openBtnFadeTimer != null) { openBtnFadeTimer.stop(); } openBtnFadeTimer = haxe_Timer.delay(function() { openBtn.style.opacity = "0.25"; },2000); return openBtnFadeTimer; }; window.document.querySelector("#togglechat").onclick = function(e) { var chat = window.document.querySelector("#chat"); var bodyEl = window.document.querySelector("body"); var sizes = bodyEl.style.gridTemplateColumns; if(sizes == null || sizes == "") { sizes = "1fr 4px 300px"; } var parts = sizes.split(" "); var chatIndex = _gthis.settings.isSwapped ? 0 : parts.length - 1; if(chat.style.display == "none") { chat.style.display = ""; var prev = bodyEl.getAttribute("data-prev-grid"); if(prev != null) { bodyEl.style.gridTemplateColumns = prev; bodyEl.removeAttribute("data-prev-grid"); } else { parts[chatIndex] = "" + _gthis.settings.chatSize + "px"; if(parts.length > 1) { parts[1] = "4px"; } bodyEl.style.gridTemplateColumns = parts.join(" "); } openBtn.style.display = "none"; if(openBtnFadeTimer != null) { openBtnFadeTimer.stop(); } } else { bodyEl.setAttribute("data-prev-grid",bodyEl.style.gridTemplateColumns); parts[chatIndex] = "0px"; if(parts.length > 1) { parts[1] = "0px"; } bodyEl.style.gridTemplateColumns = parts.join(" "); chat.style.display = "none"; openBtn.style.display = ""; openBtn.style.opacity = "1"; if(openBtnFadeTimer != null) { openBtnFadeTimer.stop(); } openBtnFadeTimer = haxe_Timer.delay(function() { openBtn.style.opacity = "0.25"; },2000); } }; var leaderBtn = window.document.querySelector("#leader_btn"); leaderBtn.onclick = $bind(this,this.toggleLeader); leaderBtn.oncontextmenu = function(e) { _gthis.toggleLeaderAndPause(); e.preventDefault(); }; window.document.querySelector("#voteskip").onclick = function(e) { _gthis.hasSeenSkipVote = true; if(_gthis.player.isListEmpty()) { return; } var items = _gthis.player.getItems(); var pos = _gthis.player.getItemPos(); _gthis.send({ type : "SkipVideo", skipVideo : { url : items[pos].url}}); }; window.document.querySelector("#queue_next").onclick = function(e) { _gthis.addVideoUrl(false); }; window.document.querySelector("#queue_end").onclick = function(e) { _gthis.addVideoUrl(true); }; new client_InputWithHistory(window.document.querySelector("#mediaurl"),this.settings.latestLinks,10,function(value) { _gthis.addVideoUrl(true); return false; }); window.document.querySelector("#mediatitle").onkeydown = function(e) { if(e.keyCode == 13) { _gthis.addVideoUrl(true); } }; new client_InputWithHistory(window.document.querySelector("#subsurl"),this.settings.latestSubs,10,function(value) { _gthis.addVideoUrl(true); return false; }); window.document.querySelector("#ce_queue_next").onclick = function(e) { _gthis.addIframe(false); }; window.document.querySelector("#ce_queue_end").onclick = function(e) { _gthis.addIframe(true); }; window.document.querySelector("#customembed-title").onkeydown = function(e) { if(e.keyCode == 13) { _gthis.addIframe(true); e.preventDefault(); } }; window.document.querySelector("#customembed-content").onkeydown = window.document.querySelector("#customembed-title").onkeydown; } ,hasPermission: function(permission) { return this.personal.hasPermission(permission,this.config.permissions); } ,handleUrlMasks: function(links) { var _g = 0; while(_g < links.length) { var link = links[_g]; ++_g; if(!this.urlMask.match(link)) { continue; } var start = Std.parseInt(this.urlMask.matched(1)); var end = Std.parseInt(this.urlMask.matched(2)); if(Math.abs(start - end) > 100) { continue; } var step = end > start ? -1 : 1; var i = links.indexOf(link); HxOverrides.remove(links,link); while(end != start + step) { var x = link.replace(this.urlMask.r,"" + end); links.splice(i,0,x); end += step; } } } ,addVideoUrl: function(atEnd) { var mediaUrl = window.document.querySelector("#mediaurl"); var subsUrl = window.document.querySelector("#subsurl"); var isTemp = client_Main.isTempChecked(window.document.querySelector("#addfromurl .add-temp")); var checkboxCache = window.document.querySelector("#cache-on-server"); var doCache = (this.personal.group & 8) != 0 && checkboxCache.checked && checkboxCache.parentElement.style.display != "none"; var url = mediaUrl.value; var subs = subsUrl.value; if(url.length == 0) { return; } mediaUrl.value = ""; client_InputWithHistory.pushIfNotLast(this.settings.latestLinks,url); if(subs.length != 0) { client_InputWithHistory.pushIfNotLast(this.settings.latestSubs,subs); } client_Settings.write(this.settings); var _this_r = new RegExp(", ?(https?)","g".split("u").join("")); var links = url.replace(_this_r,"|$1").split("|"); this.handleUrlMasks(links); if(!atEnd) { this.sortItemsForQueueNext(links); } this.addVideoArray(links,atEnd,isTemp,doCache); } ,getLinkPlayerType: function(url) { return this.player.getLinkPlayerType(url); } ,isSingleVideoUrl: function(url) { return this.player.isSingleVideoUrl(url); } ,isExternalVideoUrl: function(url) { url = StringTools.ltrim(url); if(StringTools.startsWith(url,"/")) { return false; } var host = $global.location.hostname; if(url.indexOf(host) != -1) { return false; } return true; } ,sortItemsForQueueNext: function(items) { if(items.length == 0) { return; } var first = null; if(this.player.isListEmpty()) { first = items.shift(); } items.reverse(); if(first != null) { items.unshift(first); } } ,addVideoArray: function(links,atEnd,isTemp,doCache) { var _gthis = this; if(links.length == 0) { return; } this.addVideo(links.shift(),atEnd,isTemp,doCache,function() { _gthis.addVideoArray(links,atEnd,isTemp,doCache); }); } ,addVideo: function(url,atEnd,isTemp,doCache,afterSend) { var _gthis = this; var protocol = $global.location.protocol; if(StringTools.startsWith(url,"/")) { var host = $global.location.hostname; var port = $global.location.port; url = "" + protocol + "//" + host + (port.length > 0 ? ":" + port : port) + url; } if(!StringTools.startsWith(url,"pt:")) { if(!StringTools.startsWith(url,"http")) { url = "" + protocol + "//" + url; } } var sendItem = function(data) { var tmp = data.url; var tmp1 = data.title; _gthis.send({ type : "AddVideo", addVideo : { item : { url : tmp != null ? tmp : url, title : tmp1 != null ? tmp1 : "", author : _gthis.personal.name, duration : data.duration, isTemp : isTemp, doCache : doCache, subs : data.subs, voiceOverTrack : data.voiceOverTrack, playerType : data.playerType}, atEnd : atEnd}}); if(afterSend != null) { afterSend(); } }; var isServerResolvesMeta = doCache && this.isServerCacheServiceEnabled(); var linkPlayerType = this.getLinkPlayerType(url); if(isServerResolvesMeta && (linkPlayerType == "VkType" || linkPlayerType == "VimeoType")) { sendItem({ duration : 0, title : "", url : url, playerType : linkPlayerType}); return; } this.player.getVideoData({ url : url, atEnd : atEnd},function(data) { if(data.duration == 0) { if(!isServerResolvesMeta) { _gthis.serverMessage(Lang.get("addVideoError")); return; } } else { data.title = data.title != null ? data.title : Lang.get("rawVideo"); } sendItem(data); }); } ,isServerCacheServiceEnabled: function() { return Lambda.exists(this.playersCacheSupport,function(type) { return type != "RawType"; }); } ,registerUpload: function(url,cancel) { this.activeUploads.h[url] = cancel; } ,unregisterUpload: function(url) { var _this = this.activeUploads; if(Object.prototype.hasOwnProperty.call(_this.h,url)) { delete(_this.h[url]); } } ,cancelUpload: function(url) { var tmp = this.activeUploads.h[url]; if(tmp == null) { return; } var _this = this.activeUploads; if(Object.prototype.hasOwnProperty.call(_this.h,url)) { delete(_this.h[url]); } tmp(); } ,addUploadedVideo: function(url,title,duration,atEnd,isTemp) { this.send({ type : "AddVideo", addVideo : { item : { url : url, title : title, author : this.personal.name, duration : duration, isTemp : isTemp, doCache : false, isIncomplete : true, playerType : "RawType"}, atEnd : atEnd}}); } ,addIframe: function(atEnd) { var _gthis = this; var iframeCode = window.document.querySelector("#customembed-content"); var iframe = iframeCode.value; if(iframe.length == 0) { return; } iframeCode.value = ""; var mediaTitle = window.document.querySelector("#customembed-title"); var title = mediaTitle.value; mediaTitle.value = ""; this.player.getIframeData({ url : iframe, atEnd : atEnd},function(data) { if(data.duration == 0) { _gthis.serverMessage(Lang.get("addVideoError")); return; } if(title.length > 0) { data.title = title; } data.title = data.title != null ? data.title : "Custom Media"; data.url = data.url != null ? data.url : iframe; _gthis.send({ type : "AddVideo", addVideo : { item : { url : data.url, title : data.title, author : _gthis.personal.name, duration : data.duration, isTemp : true, doCache : false, playerType : "IframeType"}, atEnd : atEnd}}); }); } ,removeVideoItem: function(url) { this.send({ type : "RemoveVideo", removeVideo : { url : url}}); } ,toggleVideoElement: function() { this.isVideoEnabled = !this.isVideoEnabled; if(!this.isVideoEnabled && this.player.hasVideo()) { this.player.removeVideo(); } else if(this.isVideoEnabled && !this.player.isListEmpty()) { this.player.setVideo(this.player.getItemPos()); } return this.isVideoEnabled; } ,refreshPlayer: function() { this.player.refresh(); } ,getPlaylistLinks: function() { var items = this.player.getItems(); var _g = []; var _g1 = 0; while(_g1 < items.length) _g.push(items[_g1++].url); return _g; } ,tryLocalIp: function(url) { if(this.host == this.globalIp) { return url; } try { var url1 = new URL(url); url1.hostname = StringTools.replace(url1.hostname,this.globalIp,this.host); return "" + Std.string(url1); } catch( _g ) { return url; } } ,onMessage: function(e) { var data = JSON.parse(e.data); if(this.config != null && this.config.isVerbose) { var t = data.type; haxe_Log.trace("Event: " + data.type,{ fileName : "src/client/Main.hx", lineNumber : 599, className : "client.Main", methodName : "onMessage", customParams : [Reflect.field(data,t.charAt(0).toLowerCase() + HxOverrides.substr(t,1,null))]}); } client_JsApi.fireEvents(data); switch(data.type) { case "AddVideo": this.player.addVideoItem(data.addVideo.item,data.addVideo.atEnd); if(this.player.itemsLength() == 1) { this.player.setVideo(0); } break; case "BanClient": break; case "ClearChat": this.clearChat(); break; case "ClearPlaylist": this.resetSkipVoteUi(); this.player.clearItems(); this.updateServerPauseUi(); if(this.player.isListEmpty()) { this.player.pause(); } break; case "Connected": this.onConnected(data); this.onTimeGet.run(); break; case "CrashTest": break; case "Disconnected": break; case "Dump": client_Utils.saveFile("dump.json","application/json",data.dump.data); break; case "Flashback": break; case "GetTime": data.getTime.paused = data.getTime.paused != null && data.getTime.paused; data.getTime.pausedByServer = data.getTime.pausedByServer != null && data.getTime.pausedByServer; data.getTime.rate = data.getTime.rate != null ? data.getTime.rate : 1; this.lastState.time = data.getTime.time; this.lastState.rate = data.getTime.rate; this.updateLastStateTime(); this.updatePauseState(data.getTime.paused,data.getTime.pausedByServer); if(this.player.getPlaybackRate() != data.getTime.rate) { this.player.setPlaybackRate(data.getTime.rate); } var synchThreshold = this.settings.synchThreshold; var newTime = data.getTime.time; var time = this.player.getTime(); if((this.personal.group & 4) != 0 && !this.forceSyncNextTick) { if(Math.abs(time - newTime) < synchThreshold) { return; } this.player.setTime(time,false); return; } if(this.player.isVideoLoaded()) { this.forceSyncNextTick = false; } if(this.player.getDuration() <= this.player.getTime() + synchThreshold) { return; } if(this.player.isPaused()) { if(!data.getTime.paused) { this.player.play(); } } else if(data.getTime.paused) { this.player.pause(); } this.player.setPauseIndicator(data.getTime.paused); if(Math.abs(time - newTime) < synchThreshold) { return; } if(!data.getTime.paused) { this.player.setTime(newTime + 0.5); } else { this.player.setTime(newTime); } break; case "KickClient": var tmp = "*" + Lang.get("kicked"); window.document.title = tmp + "*"; this.disabledReconnection = true; this.ws.close(); break; case "Login": this.onLogin(data.login.clients,data.login.clientName); break; case "LoginError": this.settings.name = ""; this.settings.hash = ""; client_Settings.write(this.settings); this.showGuestLoginPanel(); break; case "Logout": this.updateClients(data.logout.clients); this.personal = new Client(data.logout.clientName,0); this.onUserGroupChanged(); this.showGuestLoginPanel(); this.settings.name = ""; this.settings.hash = ""; client_Settings.write(this.settings); break; case "Message": this.addMessage(data.message.clientName,data.message.text); break; case "PasswordRequest": this.showGuestPasswordPanel(); break; case "Pause": this.lastState.time = data.pause.time; this.updateLastStateTime(); this.updatePauseState(true,this.lastState.pausedByServer); if((this.personal.group & 4) != 0) { return; } this.player.pause(); this.player.setTime(data.pause.time); break; case "Play": this.lastState.time = data.play.time; this.updateLastStateTime(); this.updatePauseState(false); if((this.personal.group & 4) != 0) { return; } var synchThreshold = this.settings.synchThreshold; var newTime = data.play.time; if(Math.abs(this.player.getTime() - newTime) >= synchThreshold) { this.player.setTime(newTime); } this.player.play(); break; case "PlayItem": this.resetSkipVoteUi(); this.player.setVideo(data.playItem.pos); break; case "Progress": this.onProgressEvent(data); break; case "RemoveVideo": var tmp = this.player.getCurrentItem(); var isCurrent = (tmp != null ? tmp.url : null) == data.removeVideo.url; this.cancelUpload(data.removeVideo.url); this.player.removeItem(data.removeVideo.url); if(isCurrent) { this.resetSkipVoteUi(); } this.updateServerPauseUi(); if(this.player.isListEmpty()) { this.player.pause(); } break; case "Rewind": this.lastState.time = data.rewind.time; this.updateLastStateTime(); this.player.setTime(data.rewind.time + 0.5); break; case "ServerMessage": var id = data.serverMessage.textId; var text; if(id == "usernameError") { text = StringTools.replace(Lang.get(id),"$MAX","" + this.config.maxLoginLength); } else if(StringTools.startsWith(id,"accessError")) { var args = id.split("|"); var err = Lang.get(args[0]); text = args[1] == null ? "" + err + "." : "" + err + ": " + StringTools.replace(Lang.get("noPermission"),"$PERMISSION",args[1]); } else { text = Lang.get(id); } this.serverMessage(text); break; case "SetLeader": ClientTools.setLeader(this.clients,data.setLeader.clientName); this.updateUserList(); this.setLeaderButton((this.personal.group & 4) != 0); if((this.personal.group & 4) != 0) { this.player.onSetTime(); } if(!this.hasLeader()) { this.updatePauseState(this.lastState.paused); } break; case "SetNextItem": this.player.setNextItem(data.setNextItem.pos); break; case "SetRate": if((this.personal.group & 4) != 0) { return; } this.player.setPlaybackRate(data.setRate.rate); break; case "SetTime": this.lastState.time = data.setTime.time; this.updateLastStateTime(); var synchThreshold = this.settings.synchThreshold; var newTime = data.setTime.time; if(Math.abs(this.player.getTime() - newTime) < synchThreshold) { return; } this.player.setTime(newTime); break; case "ShufflePlaylist": break; case "SkipVideo": this.resetSkipVoteUi(); this.player.skipItem(data.skipVideo.url); this.updateServerPauseUi(); if(this.player.isListEmpty()) { this.player.pause(); } break; case "SkipVideoStats": if(data.skipVideoStats.voted == 1 && this.skipVoteCount == 0) { this.serverMessage(Lang.get("skipVoteInitiated")); } this.skipVoteCount = data.skipVideoStats.voted; this.skipVoteRequired = data.skipVideoStats.required; var tmp = "" + ("(" + this.skipVoteCount + "/" + this.skipVoteRequired + ")") + " "; var tmp1 = Lang.get("voteForSkip"); window.document.querySelector("#voteskip-text").textContent = tmp + tmp1; var indicator = window.document.querySelector("#playlist-menu-indicator"); var dropdown = window.document.querySelector("#playlist-menu-dropdown"); if(!this.hasSeenSkipVote && dropdown.style.display == "none") { indicator.style.display = ""; } break; case "ToggleItemType": this.player.toggleItemType(data.toggleItemType.pos); break; case "TogglePlaylistLock": this.setPlaylistLock(data.togglePlaylistLock.isOpen); break; case "UpdateClients": this.updateClients(data.updateClients.clients); var oldGroup = this.personal.group; this.personal = ClientTools.getByName(this.clients,this.personal.name,this.personal); if(this.personal.group != oldGroup) { this.onUserGroupChanged(); } break; case "UpdatePlaylist": this.player.setItems(data.updatePlaylist.videoList); break; case "VideoLoaded": this.resetSkipVoteUi(); this.lastState.time = 0; this.updateLastStateTime(); this.updatePauseState(false); this.player.setTime(0); this.player.play(); if((this.personal.group & 4) != 0 && !this.player.isVideoLoaded()) { this.forceSyncNextTick = true; } break; } } ,onProgressEvent: function(data) { var data1 = data.progress; var tmp = data1.url; if(tmp == null) { return; } switch(data1.type) { case "Canceled": this.player.removeItem(tmp); break; case "Completed": this.player.completeItem(tmp); break; case "Caching":case "Downloading":case "Uploading": this.player.setItemProgress(tmp,data1.ratio); break; } } ,updateLastStateTime: function() { if(this.lastStateTimeStamp == 0) { this.lastStateTimeStamp = HxOverrides.now() / 1000; } this.timeFromLastState = HxOverrides.now() / 1000 - this.lastStateTimeStamp; this.lastStateTimeStamp = HxOverrides.now() / 1000; } ,onConnected: function(data) { var connected = data.connected; this.settings.uuid = connected.uuid; client_Settings.write(this.settings); this.globalIp = connected.globalIp; this.playersCacheSupport = connected.playersCacheSupport; this.setConfig(connected.config); if(connected.isUnknownClient) { this.updateClients(connected.clients); this.personal = ClientTools.getByName(this.clients,connected.clientName,this.personal); this.showGuestLoginPanel(); } else { this.onLogin(connected.clients,connected.clientName); } var guestName = window.document.querySelector("#guestname"); var name = this.settings.name; if(name.length == 0) { name = guestName.value; } var hash = this.settings.hash; if(hash.length > 0) { this.loginRequest(name,hash); } else { this.guestLogin(name); } this.setLeaderButton((this.personal.group & 4) != 0); this.setPlaylistLock(connected.isPlaylistOpen); this.clearChat(); this.chatMessageConnected(); var _g = 0; var _g1 = connected.history; while(_g < _g1.length) { var message = _g1[_g]; ++_g; this.addMessage(message.name,message.text,message.time); } this.player.setItems(connected.videoList,connected.itemPos); this.onUserGroupChanged(); if(this.settings.showHintList) { this.showChatHintList(); } } ,showChatHintList: function() { var _gthis = this; var text = Lang.get("hintListStart"); var addVideos = ""; text += "" + StringTools.replace(Lang.get("hintListAddVideo"),"$addVideos",addVideos); var requestLeader = ""; text += "" + StringTools.replace(Lang.get("hintListRequestLeader"),"$requestLeader",requestLeader); if(client_Utils.isTouch()) { text += " " + Lang.get("hintListRequestLeaderTouch"); } else { text += " " + Lang.get("hintListRequestLeaderMouse"); } if(client_Utils.isAndroid()) { var openInAppLink = ""; text += "" + StringTools.replace(Lang.get("hintListOpenInApp"),"$openInApp",openInAppLink); } var hideThisMessage = ""; text += "" + StringTools.replace(Lang.get("hintListHide"),"$hideThisMessage",hideThisMessage); this.serverMessage(text,false,false); window.document.querySelector("#addVideosHintButton").onclick = function(e) { var addBtn = window.document.querySelector("#showmediaurl"); addBtn.scrollIntoView(); return haxe_Timer.delay(function() { if(!window.document.querySelector("#addfromurl").classList.contains("collapse")) { window.document.querySelector("#mediaurl").focus(); return; } addBtn.onclick(); },300); }; window.document.querySelector("#requestLeaderHintButton").onclick = function(e) { window.scrollTo(0,0); if(client_Utils.isTouch()) { _gthis.blinkLeaderButton(); } }; window.document.querySelector("#requestLeaderHintButton").onpointerenter = function(e) { if(client_Utils.isTouch()) { return; } window.document.querySelector("#leader_btn").classList.add("hint"); }; window.document.querySelector("#requestLeaderHintButton").onpointerleave = function(e) { window.document.querySelector("#leader_btn").classList.remove("hint"); }; if(client_Utils.isAndroid()) { window.document.querySelector("#openInApp").onclick = function(e) { var isRedirected = false; window.addEventListener("blur",function(e) { isRedirected = true; return isRedirected; },{ once : true}); window.setTimeout(function() { if(isRedirected || window.document.hidden) { return; } window.location.href = "https://github.com/RblSb/SyncTubeApp#readme"; },500); window.location.href = "synctube://" + $global.location.href; return false; }; } window.document.querySelector("#hideHintList").onclick = function(e) { window.document.querySelector("#hideHintList").parentElement.remove(); _gthis.settings.showHintList = false; client_Settings.write(_gthis.settings); }; } ,blinkLeaderButton: function() { window.document.querySelector("#leader_btn").classList.add("hint"); haxe_Timer.delay(function() { window.document.querySelector("#leader_btn").classList.remove("hint"); },500); } ,onUserGroupChanged: function() { var button = window.document.querySelector("#queue_next"); if(this.personal.hasPermission("changeOrder",this.config.permissions)) { button.disabled = false; } else { button.disabled = true; } var adminMenu = window.document.querySelector("#adminMenu"); if((this.personal.group & 8) != 0) { adminMenu.style.display = ""; } else { adminMenu.style.display = "none"; } window.document.querySelector("#mediaurl-upload").style.display = (this.personal.group & 8) != 0 ? "" : "none"; var checkboxCache = window.document.querySelector("#cache-on-server"); checkboxCache.checked = (this.personal.group & 8) != 0 && checkboxCache.checked; checkboxCache.parentElement.style.display = (this.personal.group & 8) != 0 ? "" : "none"; } ,guestLogin: function(name) { if(name.length == 0) { return; } this.send({ type : "Login", login : { clientName : name}}); this.settings.name = name; client_Settings.write(this.settings); } ,userLogin: function(name,password) { if(this.config.salt == null) { return; } if(password.length == 0) { return; } if(name.length == 0) { name = this.settings.name; } var hash = haxe_crypto_Sha256.encode(password + this.config.salt); this.loginRequest(name,hash); this.settings.hash = hash; client_Settings.write(this.settings); } ,loginRequest: function(name,hash) { this.send({ type : "Login", login : { clientName : name, passHash : hash}}); } ,setConfig: function(config) { this.config = config; if(client_Utils.isTouch()) { config.requestLeaderOnPause = false; config.unpauseWithoutLeader = false; } this.pageTitle = config.channelName; window.document.querySelector("#guestname").maxLength = config.maxLoginLength; window.document.querySelector("#chatline").maxLength = config.maxMessageLength; this.filters.length = 0; var _g = 0; var _g1 = config.filters; while(_g < _g1.length) { var filter = _g1[_g]; ++_g; this.filters.push({ regex : new EReg(filter.regex,filter.flags), replace : filter.replace}); } var _g = 0; var _g1 = config.emotes; while(_g < _g1.length) { var emote = _g1[_g]; ++_g; var tag = StringTools.endsWith(emote.image,"mp4") || StringTools.endsWith(emote.image,"webm") ? "video autoplay=\"\" loop=\"\" muted=\"\"" : "img"; this.filters.push({ regex : new EReg("(^| )" + this.escapeRegExp(emote.name) + "(?!\\S)","g"), replace : "$1<" + tag + " class=\"channel-emote\" src=\"" + emote.image + "\" title=\"" + emote.name + "\"/>"}); } window.document.querySelector("#smilesbtn").classList.remove("active"); window.document.querySelector("#smiles-wrap").style.display = "none"; var smilesList = window.document.querySelector("#smiles-list"); smilesList.onclick = function(e) { var el = e.target; if(el == smilesList) { return; } var form = window.document.querySelector("#chatline"); form.value += " " + el.title; form.focus(); }; smilesList.textContent = ""; var _g = 0; var _g1 = config.emotes; while(_g < _g1.length) { var emote = _g1[_g]; ++_g; var tag = StringTools.endsWith(emote.image,"mp4") || StringTools.endsWith(emote.image,"webm") ? "video" : "img"; var el = window.document.createElement(tag); el.className = "smile-preview"; el.dataset.src = emote.image; el.title = emote.name; smilesList.appendChild(el); } } ,onLogin: function(data,clientName) { this.updateClients(data); var tmp = ClientTools.getByName(this.clients,clientName); if(tmp == null) { return; } this.personal = tmp; this.onUserGroupChanged(); this.hideGuestLoginPanel(); } ,showGuestLoginPanel: function() { window.document.querySelector("#guestlogin").style.display = ""; window.document.querySelector("#guestpassword").style.display = "none"; window.document.querySelector("#chatbox").style.display = "none"; window.document.querySelector("#exitBtn").textContent = Lang.get("login"); } ,hideGuestLoginPanel: function() { window.document.querySelector("#guestlogin").style.display = "none"; window.document.querySelector("#guestpassword").style.display = "none"; window.document.querySelector("#chatbox").style.display = ""; window.document.querySelector("#exitBtn").textContent = Lang.get("exit"); } ,showGuestPasswordPanel: function() { window.document.querySelector("#guestlogin").style.display = "none"; window.document.querySelector("#chatbox").style.display = "none"; window.document.querySelector("#guestpassword").style.display = ""; window.document.querySelector("#guestpass").type = "password"; window.document.querySelector("#guestpass_icon").setAttribute("name","eye"); } ,updateClients: function(newClients) { this.clients.length = 0; var _g = 0; while(_g < newClients.length) this.clients.push(Client.fromData(newClients[_g++])); this.updateUserList(); } ,send: function(data) { if(!this.isConnected) { return; } this.ws.send(JSON.stringify(data)); } ,chatMessageConnected: function() { if(this.isLastMessageConnectionStatus()) { this.msgBuf.removeChild(this.getLastMessageDiv()); } var div = window.document.createElement("div"); div.className = "server-msg-reconnect"; div.textContent = Lang.get("msgConnected"); this.addMessageDiv(div); this.scrollChatToEnd(); } ,chatMessageDisconnected: function() { if(this.isLastMessageConnectionStatus()) { this.msgBuf.removeChild(this.getLastMessageDiv()); } var div = window.document.createElement("div"); div.className = "server-msg-disconnect"; div.textContent = Lang.get("msgDisconnected"); this.addMessageDiv(div); this.scrollChatToEnd(); } ,isLastMessageConnectionStatus: function() { var tmp = this.getLastMessageDiv(); if(tmp != null) { return StringTools.startsWith(tmp.className,"server-msg"); } else { return null; } } ,serverMessage: function(text,isText,withTimestamp) { if(withTimestamp == null) { withTimestamp = true; } if(isText == null) { isText = true; } var div = window.document.createElement("div"); var time = HxOverrides.dateStr(new Date()).split(" ")[1]; div.className = "server-whisper"; div.innerHTML = "