PageSourceSearch

https://xoigac.top/dist/js/match-chat-info.js?v=ShVaD9gRVQis7Qgnv2M5b4JRPW-FEG036pOuUcEztP4

js xoigac.top collected 2026-10-10 02:21:49 UTC 22,044 bytes, 1 lines download raw bytes

1!function(){"use strict";var I18N={empty:"Chưa có dữ liệu",loading:"Đang tải...",possession:"TL kiểm soát bóng",corners:"Phạt góc",goals:"Bàn thắng",yellow:"Thẻ vàng",red:"Thẻ đỏ",shots:"Sút bóng",shotsOnTarget:"Sút cầu môn",fouls:"Phạm lỗi",offsides:"Việt vị",passes:"Chuyền bóng",passAccuracy:"Độ chính xác chuyền",substitutes:"Dự bị",h2h:"Các trận đối đầu",others:"Trận khác",upcoming:"Trận sắp tới",league:"Giải đấu",matchTime:"Thời gian thi đấu",venue:"Sân vận động",referee:"Trọng tài",round:"Vòng đấu",ht:"HT",rank:"#",team:"Đội",p:"Tr",w:"T",d:"H",l:"B",pts:"Đ",ah:"Châu Á",eu:"Châu Âu",ou:"Tài Xỉu",cr:"Phạt góc",oddsLine:"Kèo",oddsHome:"Chủ",oddsAway:"Khách",oddsDraw:"Hòa",oddsOver:"Tài",oddsUnder:"Xỉu",htFull:"Hiệp 1",ftFull:"Cả trận",htFtHint:"HT = Hiệp 1 · FT = Cả trận",oddsPrematch:"Kèo trước trận",oddsPrematchLive:"Kèo trước trận · không phải kèo live",oddsUpdatedAt:"Cập nhật"},pageI18n=null;function t(key){var fromPage=function loadPageI18n(){if(pageI18n)return pageI18n;try{var el=document.getElementById("matchSidebarI18n");el&&el.textContent&&(pageI18n=JSON.parse(el.textContent))}catch(_){}return pageI18n||{}}()[key];if(fromPage)return fromPage;try{if(window.i18n&&"function"==typeof window.i18n.t){var v=window.i18n.t("match.sidebar."+key);if(v&&v!=="match.sidebar."+key)return v}}catch(_){}return I18N[key]||key}function esc(s){return null==s?"":String(s).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function img(src,alt){return'<img src="'+esc(src||"/images/placeholder-team.svg")+'" alt="'+esc(alt||"")+'" loading="lazy" onerror="this.onerror=null; this.src=\'/images/placeholder-team.svg\';">'}function emptyHtml(){return'<div class="ms-empty"><div class="ms-empty-icon" aria-hidden="true"></div><p>'+esc(t("empty"))+"</p></div>"}function loadingHtml(){return'<div class="ms-loading"><i class="fas fa-spinner fa-spin"></i><span>'+esc(t("loading"))+"</span></div>"}function formatLocal(iso){if(!iso)return"";try{var d=new Date(iso);return isNaN(d.getTime())?iso:String(d.getDate()).padStart(2,"0")+"/"+String(d.getMonth()+1).padStart(2,"0")+"/"+d.getFullYear()+" "+String(d.getHours()).padStart(2,"0")+":"+String(d.getMinutes()).padStart(2,"0")}catch(_){return iso}}function formatShort(iso){if(!iso)return"";try{var d=new Date(iso);if(isNaN(d.getTime()))return iso;var dd=String(d.getDate()).padStart(2,"0"),mm=String(d.getMonth()+1).padStart(2,"0");return String(d.getHours()).padStart(2,"0")+":"+String(d.getMinutes()).padStart(2,"0")+" "+dd+"/"+mm}catch(_){return iso}}function leadClass(a,b){return a>b?"lead":""}function statRow(label,home,away,isPct){var total=(home=Number(home)||0)+(away=Number(away)||0),hw=total>0?home/total*100:50,aw=total>0?away/total*100:50,suffix=isPct?"%":"";return'<div class="ms-stat-row"><div class="ms-stat-label">'+esc(label)+'</div><div class="ms-stat-val '+leadClass(home,away)+'">'+home+suffix+'</div><div class="ms-stat-bar dual"><i class="home" style="width:'+hw+'%"></i><i class="away" style="width:'+aw+'%"></i></div><div class="ms-stat-val '+leadClass(away,home)+'">'+away+suffix+"</div></div>"}function eventIcon(type){return"Goal"===type?"⚽":"Yellow"===type?"🟨":"Red"===type?"🟥":"Var"===type?"VAR":"🔄"}function playerList(players){return players&&players.length?players.map(function(p){return'<div class="ms-player"><span class="ms-player-num">'+esc(p.number)+"</span><span>"+esc(p.name)+(p.isCaptain?" (C)":"")+"</span></div>"}).join(""):""}function renderMatchList(payload,titleKey){var d=payload.data;if(!d||!d.matches||!d.matches.length)return emptyHtml();var html='<div class="ms-info-scroll"><div class="ms-section-title">'+esc(t(titleKey))+"</div>";return d.matches.forEach(function(m){var tag=m.isLive?'<span class="ms-match-status">'+(m.minute?"'"+m.minute:m.status||"LIVE")+"</span>":"<span>"+esc(formatShort(m.matchDate))+"</span>",score=null!=m.homeScore&&m.status&&"NS"!==m.status?esc(m.homeScore)+" : "+esc(m.awayScore):"VS",open=m.matchUrl?'<a class="ms-match-card" href="'+esc(m.matchUrl)+'">':'<div class="ms-match-card">',close=m.matchUrl?"</a>":"</div>";html+=open,html+='<div class="ms-match-meta"><span>'+esc(m.league||"")+"</span>"+tag+"</div>",html+='<div class="ms-match-teams">',html+='<div class="ms-match-team">'+img(m.homeTeamLogo,m.homeTeam)+"<span>"+esc(m.homeTeam)+"</span></div>",html+='<div class="ms-match-score">'+score+"</div>",html+='<div class="ms-match-team away">'+img(m.awayTeamLogo,m.awayTeam)+"<span>"+esc(m.awayTeam)+"</span></div>",html+="</div>"+close}),html+="</div>"}function oddsCellText(v){return null==v||""===v?"-":String(v)}function parseOddsNum(v){if(null==v||""===v||"-"===v)return null;var n=parseFloat(String(v).replace(",","."));return isNaN(n)?null:n}function oddsMoveClass(curr,prev){var a=parseOddsNum(curr),b=parseOddsNum(prev);return null==a||null==b?"":a>b?"ms-odds-up":a<b?"ms-odds-down":""}function oddsColLabels(key){return"eu"===key?[t("oddsHome"),t("oddsDraw"),t("oddsAway")]:"ou"===key||"cr"===key?[t("oddsOver"),t("oddsLine"),t("oddsUnder")]:"ah"===key?[t("oddsHome"),t("oddsLine"),t("oddsAway")]:null}function oddsGridRow(row,prevRow,key){for(var cells=Array.isArray(row)&&row.length>=3?row:["-","-","-"],prev=Array.isArray(prevRow)&&prevRow.length>=3?prevRow:null,order=function oddsDisplayOrder(key){return"eu"===key?[0,1,2]:[1,0,2]}(key),html='<div class="ms-odds-grid-row">',n=0;n<3;n++){var i=order[n],text=oddsCellText(cells[i]),move=prev?oddsMoveClass(cells[i],prev[i]):"";
1html+='<span class="ms-odds-val'+("eu"!==key&&1===n?" is-line":"")+(move?" "+move:"")+'">'+esc(text)+("ms-odds-up"===move?'<i aria-hidden="true">↑</i>':"")+("ms-odds-down"===move?'<i aria-hidden="true">↓</i>':"")+"</span>"}return html+="</div>"}function renderOdds(payload,prevPayload,mode){var d=payload&&payload.data?payload.data:null,prevD=prevPayload&&prevPayload.data?prevPayload.data:null,hasData=!!(payload&&payload.hasData&&d),blocks="eu"===(mode="eu"===mode?"eu":"ah")?[{cls:"eu",title:t("eu"),key:"eu"},{cls:"ou",title:t("ou"),key:"ou"},{cls:"cr",title:t("cr"),key:"cr"}]:[{cls:"ah",title:t("ah"),key:"ah"},{cls:"ou",title:t("ou"),key:"ou"},{cls:"cr",title:t("cr"),key:"cr"}],html='<div class="ms-info-scroll">';return hasData?(html+='<div class="ms-odds-toolbar">',html+='<span class="ms-odds-brand is-static" title="AB77">',html+='<img class="ms-odds-logo" src="'+esc("/images/ab77-logo.png?v=5")+'" alt="AB77" loading="lazy">',html+="</span>",html+='<div class="ms-odds-mode" role="tablist" aria-label="odds mode">',html+='<button type="button" class="ms-odds-mode-btn'+("ah"===mode?" active":"")+'" data-odds-mode="ah" role="tab" aria-selected="'+("ah"===mode?"true":"false")+'">'+esc(t("ah"))+"</button>",html+='<button type="button" class="ms-odds-mode-btn'+("eu"===mode?" active":"")+'" data-odds-mode="eu" role="tab" aria-selected="'+("eu"===mode?"true":"false")+'">'+esc(t("eu"))+"</button>",html+="</div></div>",html+='<div class="ms-odds-hint">'+esc(t("htFtHint"))+"</div>",html+=function oddsMetaHtml(payload,data){var marketLabel=t(payload&&payload.isLive?"oddsPrematchLive":"oddsPrematch"),updateRaw=data&&data.update||payload&&payload.update||"",updateText=formatShort(updateRaw)||formatLocal(updateRaw),html='<div class="ms-odds-meta">';return html+='<span class="ms-odds-meta-market">'+esc(marketLabel)+"</span>",updateText&&(html+='<span class="ms-odds-meta-sep" aria-hidden="true">·</span>',html+='<span class="ms-odds-meta-updated">'+esc(t("oddsUpdatedAt"))+" "+esc(updateText)+"</span>"),html+"</div>"}(payload,d),html+='<div class="ms-odds-sponsor is-static">',blocks.forEach(function(b){var m=d[b.key]||null,pm=prevD&&prevD[b.key]?prevD[b.key]:null,hasCols=!!oddsColLabels(b.key);html+='<section class="ms-odds-block '+b.cls+'">',html+='<div class="ms-odds-title">'+esc(b.title)+"</div>",html+='<div class="ms-odds-body">',html+='<div class="ms-odds-periods">',hasCols&&(html+='<span class="ms-odds-period-pad" aria-hidden="true"></span>'),html+='<span title="'+esc(t("htFull"))+'" aria-label="'+esc(t("htFull"))+'">HT</span>',html+='<span title="'+esc(t("ftFull"))+'" aria-label="'+esc(t("ftFull"))+'">FT</span>',html+="</div>",html+='<div class="ms-odds-grid">',html+=function oddsColsHtml(key){var labels=oddsColLabels(key);if(!labels)return"";for(var html='<div class="ms-odds-cols" aria-hidden="true">',i=0;i<labels.length;i++)html+="<span>"+esc(labels[i])+"</span>";return html+"</div>"}(b.key),html+=oddsGridRow(m&&m.ht,pm&&pm.ht,b.key),html+=oddsGridRow(m&&m.ft,pm&&pm.ft,b.key),html+="</div></div></section>"}),html+="</div></div>"):(html+=emptyHtml(),html+="</div>")}function render(tab,payload,oddsMode){if("odds"===tab)return renderOdds(payload,null,oddsMode);if(!payload||!1===payload.hasData||payload.isManual)return'<div class="ms-info-scroll">'+emptyHtml()+"</div>";
1switch(tab){case"stats":return function renderStats(payload){var d=payload.data;if(!d)return emptyHtml();var html='<div class="ms-info-scroll">';return html+=statRow(t("possession"),d.possession?.home,d.possession?.away,!0),html+=statRow(t("corners"),d.corners?.home,d.corners?.away,!1),html+=statRow(t("goals"),d.goals?.home,d.goals?.away,!1),html+=statRow(t("yellow"),d.yellowCards?.home,d.yellowCards?.away,!1),html+=statRow(t("red"),d.redCards?.home,d.redCards?.away,!1),html+=statRow(t("shots"),d.shots?.home,d.shots?.away,!1),html+=statRow(t("shotsOnTarget"),d.shotsOnTarget?.home,d.shotsOnTarget?.away,!1),html+=statRow(t("fouls"),d.fouls?.home,d.fouls?.away,!1),html+=statRow(t("offsides"),d.offsides?.home,d.offsides?.away,!1),html+=statRow(t("passes"),d.passes?.home,d.passes?.away,!1),html+=statRow(t("passAccuracy"),d.passAccuracy?.home,d.passAccuracy?.away,!0),html+"</div>"}(payload);case"events":return function renderEvents(payload){var d=payload.data;if(!d||!d.events||!d.events.length)return emptyHtml();var html='<div class="ms-info-scroll">';return null!=d.htHome&&null!=d.htAway&&(html+='<div class="ms-ht-wrap"><span class="ms-ht-badge">'+esc(t("ht"))+" "+d.htHome+" : "+d.htAway+"</span></div>"),d.events.forEach(function(e){var isHome="home"===(e.team||"").toLowerCase();html+='<div class="ms-event">',html+='<div class="ms-event-side home">'+(isHome?esc(eventIcon(e.type))+" "+esc(e.player||e.detail||""):"")+"</div>",html+='<div class="ms-event-min">'+esc(e.minute)+"'</div>",html+='<div class="ms-event-side away">'+(isHome?"":esc(eventIcon(e.type))+" "+esc(e.player||e.detail||""))+"</div>",html+="</div>"}),html+="</div>"}(payload);case"lineup":return function renderLineup(payload){var d=payload.data;if(!d)return emptyHtml();var html='<div class="ms-info-scroll">';return html+='<div class="ms-lineup-team"><div class="ms-lineup-head">'+img(d.homeTeamLogo,d.homeTeam)+"<span>"+esc(d.homeTeam)+"</span>",d.homeFormation&&(html+='<span class="ms-formation">'+esc(d.homeFormation)+"</span>"),html+="</div>"+playerList(d.home),d.homeSubs&&d.homeSubs.length&&(html+='<div class="ms-subs-title">'+esc(t("substitutes"))+"</div>"+playerList(d.homeSubs)),html+="</div>",html+='<div class="ms-lineup-team"><div class="ms-lineup-head">'+img(d.awayTeamLogo,d.awayTeam)+"<span>"+esc(d.awayTeam)+"</span>",d.awayFormation&&(html+='<span class="ms-formation">'+esc(d.awayFormation)+"</span>"),html+="</div>"+playerList(d.away),d.awaySubs&&d.awaySubs.length&&(html+='<div class="ms-subs-title">'+esc(t("substitutes"))+"</div>"+playerList(d.awaySubs)),html+"</div></div>"}(payload);
1case"standings":return function renderStandings(payload){var d=payload.data;if(!d||!d.rows||!d.rows.length)return emptyHtml();var html='<div class="ms-info-scroll"><div class="ms-section-title">'+esc(d.league||"")+" "+esc(d.season||"")+"</div>";return html+='<table class="ms-table"><thead><tr>',html+="<th>"+esc(t("rank"))+"</th><th>"+esc(t("team"))+"</th><th>"+esc(t("p"))+"</th><th>"+esc(t("w"))+"</th><th>"+esc(t("d"))+"</th><th>"+esc(t("l"))+"</th><th>"+esc(t("pts"))+"</th>",html+="</tr></thead><tbody>",d.rows.forEach(function(r){var hl=r.teamId===d.homeTeamId||r.teamId===d.awayTeamId?" highlight":"";html+='<tr class="'+hl+'">',html+="<td>"+esc(r.rank)+"</td>",html+='<td><span class="team-cell">'+img(r.logo,r.team)+"<span>"+esc(r.team)+"</span></span></td>",html+="<td>"+esc(r.played)+"</td><td>"+esc(r.won)+"</td><td>"+esc(r.drawn)+"</td><td>"+esc(r.lost)+"</td><td><strong>"+esc(r.points)+"</strong></td>",html+="</tr>"}),html+="</tbody></table></div>"}(payload);case"h2h":return function renderH2h(payload){var d=payload.data;if(!d||!d.matches||!d.matches.length)return emptyHtml();var html='<div class="ms-info-scroll"><div class="ms-section-title">'+esc(t("h2h"))+"</div>";return d.matches.forEach(function(m){html+='<div class="ms-match-card">',html+='<div class="ms-match-meta"><span>'+esc(m.competition||"")+"</span><span>"+esc(formatShort(m.date))+"</span></div>",html+='<div class="ms-match-teams">',html+='<div class="ms-match-team"><span>'+esc(m.homeTeam)+"</span></div>",html+='<div class="ms-match-score">'+esc(m.homeScore)+" : "+esc(m.awayScore)+"</div>",html+='<div class="ms-match-team away"><span>'+esc(m.awayTeam)+"</span></div>",html+="</div></div>"}),html+="</div>"}(payload);case"others":return renderMatchList(payload,"others");case"upcoming":return renderMatchList(payload,"upcoming");case"info":return function renderInfo(payload){var d=payload.data;if(!d)return emptyHtml();var html='<div class="ms-info-scroll">';return html+='<div class="ms-info-row">'+img(d.leagueLogo,d.league)+'<div><span class="ms-info-label">'+esc(t("league"))+'</span><span class="ms-info-value">'+esc(d.league||"-")+"</span></div></div>",html+='<div class="ms-info-row"><div class="ms-info-icon"><i class="fas fa-calendar-alt"></i></div><div><span class="ms-info-label">'+esc(t("matchTime"))+'</span><span class="ms-info-value">'+esc(formatLocal(d.matchDate))+"</span></div></div>",d.round&&(html+='<div class="ms-info-row"><div class="ms-info-icon"><i class="fas fa-flag"></i></div><div><span class="ms-info-label">'+esc(t("round"))+'</span><span class="ms-info-value">'+esc(d.round)+"</span></div></div>"),d.venue&&(html+='<div class="ms-info-row"><div class="ms-info-icon"><i class="fas fa-map-marker-alt"></i></div><div><span class="ms-info-label">'+esc(t("venue"))+'</span><span class="ms-info-value">'+esc(d.venue)+(d.venueCity?", "+esc(d.venueCity):"")+"</span></div></div>"),d.referee&&(html+='<div class="ms-info-row"><div class="ms-info-icon"><i class="fas fa-gavel"></i></div><div><span class="ms-info-label">'+esc(t("referee"))+'</span><span class="ms-info-value">'+esc(d.referee)+"</span></div></div>"),null!=d.htHome&&null!=d.htAway&&(html+='<div class="ms-info-row"><div class="ms-info-icon"><i class="fas fa-clock"></i></div><div><span class="ms-info-label">'+esc(t("ht"))+'</span><span class="ms-info-value">'+d.htHome+" : "+d.htAway+"</span></div></div>"),html+"</div>"}(payload);default:return emptyHtml()}}function MatchSidebarInfo(root){this.root=root,this.matchId=parseInt(root.getAttribute("data-match-id")||"0",10),this.hasApi="true"===root.getAttribute("data-has-api"),this.cache={},this.loading={},this.bound=!1,this.currentTab="chat",this._oddsTimer=null,this._oddsFetching=!1,this._onVisChange=null,this.oddsMode="ah"}function boot(){var root=document.getElementById("matchSidebarShell")||document.getElementById("focusChatWrapper");if(root&&root.querySelector(".ms-tab")){var app=new MatchSidebarInfo(root);app.init(),window.MatchSidebarInfoApp=app}}MatchSidebarInfo.prototype.init=function(){if(!this.bound){this.bound=!0;var self=this;
1this.root.querySelectorAll(".ms-tab").forEach(function(btn){btn.addEventListener("click",function(){self.activate(btn.getAttribute("data-tab"))})}),this.root.addEventListener("click",function(e){var btn=e.target&&e.target.closest?e.target.closest(".ms-odds-mode-btn"):null;if(btn&&self.root.contains(btn)){e.preventDefault(),e.stopPropagation();var mode=btn.getAttribute("data-odds-mode");if(("ah"===mode||"eu"===mode)&&mode!==self.oddsMode){self.oddsMode=mode;var panel=self.root.querySelector('.match-sidebar-panel[data-panel="odds"]');panel&&self.cache.odds&&(panel.innerHTML=renderOdds(self.cache.odds,null,self.oddsMode))}}}),this._onVisChange=function(){document.hidden?self.stopOddsPoll():"odds"===self.currentTab&&self.startOddsPoll()},document.addEventListener("visibilitychange",this._onVisChange),this.setChatOnly(!this.hasApi||this.matchId<=0)}},MatchSidebarInfo.prototype.stopOddsPoll=function(){this._oddsTimer&&(clearInterval(this._oddsTimer),this._oddsTimer=null)},MatchSidebarInfo.prototype.startOddsPoll=function(){var self=this;this.stopOddsPoll(),!this.hasApi||this.matchId<=0||"odds"===this.currentTab&&(document.hidden||(this._oddsTimer=setInterval(function(){self.refreshOdds(!0)},6e5)))},MatchSidebarInfo.prototype.refreshOdds=function(silent){var self=this;if(this.hasApi&&!(this.matchId<=0)&&"odds"===this.currentTab&&!this._oddsFetching){var panel=this.root.querySelector('.match-sidebar-panel[data-panel="odds"]');if(panel){this._oddsFetching=!0,silent||(panel.innerHTML=loadingHtml());var ctrl="undefined"!=typeof AbortController?new AbortController:null,timedOut=!1,timer=setTimeout(function(){timedOut=!0;try{ctrl&&ctrl.abort()}catch(_){}},12e3),opts={headers:{Accept:"application/json"},credentials:"same-origin",cache:"no-store"};ctrl&&(opts.signal=ctrl.signal),fetch("/api/match/"+this.matchId+"/chat-info/odds",opts).then(function(r){return r.json()}).then(function(data){if("odds"===self.currentTab){var prev=self.cache.odds,comparePrev=silent&&prev&&prev.hasData?prev:null;self.cache.odds=data,panel.innerHTML=renderOdds(data,comparePrev,self.oddsMode)}}).catch(function(){"odds"!==self.currentTab||silent||(panel.innerHTML='<div class="ms-info-scroll">'+emptyHtml()+"</div>")}).finally(function(){clearTimeout(timer),self._oddsFetching=!1,!timedOut||silent||"odds"!==self.currentTab||self.cache.odds||(panel.innerHTML='<div class="ms-info-scroll">'+emptyHtml()+"</div>")})}}},MatchSidebarInfo.prototype.setChatOnly=function(chatOnly){var only=!!chatOnly;this.root.classList.toggle("ms-chat-only",only);var tabsNav=this.root.querySelector(".match-sidebar-tabs");tabsNav&&(only?(tabsNav.setAttribute("hidden",""),tabsNav.setAttribute("aria-hidden","true")):(tabsNav.removeAttribute("hidden"),tabsNav.removeAttribute("aria-hidden"))),only&&this.activate("chat")},MatchSidebarInfo.prototype.getChatTabBtn=function(){return this.root.querySelector('.ms-tab[data-tab="chat"]')},MatchSidebarInfo.prototype.isChatActive=function(){return"chat"===this.currentTab},MatchSidebarInfo.prototype.notifyNewChatMessage=function(message){if(!this.isChatActive()&&(!message||"system"!==message.type&&"system"!==message.Type)){try{var name=message&&(message.userName||message.UserName)||"",me=(window.currentUserName||"").trim().toLowerCase();if(name&&me&&name.trim().toLowerCase()===me)return}catch(_){}var btn=this.getChatTabBtn();btn&&btn.classList.add("has-unread")}},MatchSidebarInfo.prototype.clearChatUnread=function(){var btn=this.getChatTabBtn();btn&&btn.classList.remove("has-unread")},MatchSidebarInfo.prototype.setMatch=function(matchId,hasApi){var id=parseInt(matchId,10)||0,api=!!hasApi&&id>0;this.stopOddsPoll(),this.matchId=id,this.hasApi=api,this.root.setAttribute("data-match-id",String(id)),this.root.setAttribute("data-has-api",api?"true":"false"),this.cache={},this.loading={},this.clearChatUnread(),this.root.querySelectorAll(".match-sidebar-panel").forEach(function(panel){var key=panel.getAttribute("data-panel");key&&"chat"!==key&&(panel.innerHTML="")}),this.setChatOnly(!api),this.activate("chat")},MatchSidebarInfo.prototype.activate=function(tab){if(tab){var self=this,prevTab=this.currentTab;this.currentTab=tab,"odds"===prevTab&&"odds"!==tab&&this.stopOddsPoll();var activeBtn=null;
1if(this.root.querySelectorAll(".ms-tab").forEach(function(btn){var on=btn.getAttribute("data-tab")===tab;btn.classList.toggle("active",on),on&&(activeBtn=btn)}),activeBtn){var tabsNav=activeBtn.closest(".match-sidebar-tabs");if(tabsNav){var btnLeft=activeBtn.offsetLeft,btnWidth=activeBtn.offsetWidth,navWidth=tabsNav.clientWidth,target=btnLeft-(navWidth-btnWidth)/2,maxScroll=Math.max(0,tabsNav.scrollWidth-navWidth);target=Math.max(0,Math.min(target,maxScroll));try{tabsNav.scrollTo({left:target,behavior:"smooth"})}catch(_){tabsNav.scrollLeft=target}}}if(this.root.querySelectorAll(".match-sidebar-panel").forEach(function(panel){var on=panel.getAttribute("data-panel")===tab;panel.classList.toggle("active",on),on?panel.removeAttribute("hidden"):panel.setAttribute("hidden","")}),"chat"===tab)return this.clearChatUnread(),void this.root.classList.remove("ms-info-active");this.root.classList.add("ms-info-active");try{var active=document.activeElement;(active&&active.closest&&active.closest('.match-sidebar-panel[data-panel="chat"]')||active&&("focusChatInput"===active.id||active.classList.contains("chat-input-field")))&&active.blur()}catch(_){}var panel=this.root.querySelector('.match-sidebar-panel[data-panel="'+tab+'"]');if(panel){if(this.hasApi&&!(this.matchId<=0))return"odds"===tab?this.cache.odds?(panel.innerHTML=renderOdds(this.cache.odds,null,this.oddsMode),void this.startOddsPoll()):(this.refreshOdds(!1),void this.startOddsPoll()):void(this.cache[tab]?panel.innerHTML=render(tab,this.cache[tab]):this.loading[tab]||(panel.innerHTML=loadingHtml(),this.loading[tab]=!0,fetch("/api/match/"+this.matchId+"/chat-info/"+encodeURIComponent(tab),{headers:{Accept:"application/json"},credentials:"same-origin"}).then(function(r){return r.json()}).then(function(data){self.cache[tab]=data,self.currentTab===tab&&(panel.innerHTML=render(tab,data))}).catch(function(){self.currentTab===tab&&(panel.innerHTML='<div class="ms-info-scroll">'+emptyHtml()+"</div>")}).finally(function(){self.loading[tab]=!1})));panel.innerHTML='<div class="ms-info-scroll">'+emptyHtml()+"</div>"}}},"loading"===document.readyState?document.addEventListener("DOMContentLoaded",boot):boot()}();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.