UNPKG

crust-brackets-viewer

Version:

A simple library to display tournament brackets (round-robin, single elimination, double elimination)

1 lines 13.2 kB
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var r in n)("object"==typeof exports?exports:e)[r]=n[r]}}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getRanking=t.rankingHeader=t.isMajorRound=t.splitBy=void 0,t.splitBy=function(e,t){const n=Object();for(const r of e)n[r[t]]||(n[r[t]]=[]),n[r[t]].push(r);return Object.values(n)},t.isMajorRound=function(e){return 1===e||e%2==0};const r={rank:{value:"#",tooltip:"Rank"},id:{value:"Name",tooltip:"Name"},played:{value:"P",tooltip:"Played"},wins:{value:"W",tooltip:"Wins"},draws:{value:"D",tooltip:"Draws"},losses:{value:"L",tooltip:"Losses"},forfeits:{value:"F",tooltip:"Forfeits"},scoreFor:{value:"SF",tooltip:"Score For"},scoreAgainst:{value:"SA",tooltip:"Score Against"},scoreDifference:{value:"+/-",tooltip:"Score Difference"},points:{value:"Pts",tooltip:"Points"}};function o(e,t,n,r){if(!n||null===n.id)return;const o=e[n.id]||{rank:0,id:0,played:0,wins:0,draws:0,losses:0,forfeits:0,scoreFor:0,scoreAgainst:0,scoreDifference:0,points:0};o.id=n.id,o.played++,"win"===n.result&&o.wins++,"draw"===n.result&&o.draws++,"loss"===n.result&&o.losses++,n.forfeit&&o.forfeits++,o.scoreFor+=n.score||0,o.scoreAgainst+=r&&r.score||0,o.scoreDifference=o.scoreFor-o.scoreAgainst,o.points=t(o),e[n.id]=o}t.rankingHeader=function(e){return r[e]},t.getRanking=function(e,t){t=t||(e=>3*e.wins+1*e.draws+0*e.losses);const n={};for(const r of e)o(n,t,r.opponent1,r.opponent2),o(n,t,r.opponent2,r.opponent1);return function(e){const t=Object.values(e).sort((e,t)=>t.points-e.points),n={value:0,lastPoints:-1};for(const e of t)e.rank=n.lastPoints!==e.points?++n.value:n.value,n.lastPoints=e.points;return t}(n)}},function(e,t,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.hasOwnProperty.call(e,n)&&r(t,e,n);return o(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),n(2);const a=n(0),c=i(n(3)),s=i(n(4));t.default=class{constructor(){this.teamRefsDOM={}}render(e,t,n){const r=document.querySelector(e);if(!r)throw Error('Root not found. You must have a root element with id "root"');this.config={participantOriginPlacement:n&&n.participantOriginPlacement||"before",showSlotsOrigin:!n||void 0===n.showSlotsOrigin||n.showSlotsOrigin,showLowerBracketSlotsOrigin:!n||void 0===n.showLowerBracketSlotsOrigin||n.showLowerBracketSlotsOrigin,highlightParticipantOnHover:!n||void 0===n.highlightParticipantOnHover||n.highlightParticipantOnHover},this.participants=t.participants,t.participants.forEach(e=>this.teamRefsDOM[e.id]=[]);const o=a.splitBy(t.matches,"group_id");switch(t.stage.type){case"round_robin":this.renderRoundRobin(r,t.stage.name,o);break;case"single_elimination":case"double_elimination":this.renderElimination(r,t.stage.name,t.stage.type,o);break;default:throw Error("Unknown bracket type: "+t.stage.type)}}renderRoundRobin(e,t,n){const r=c.createRoundRobinContainer();let o=1;for(const e of n){const t=c.createGroupContainer(s.getGroupName(o++)),n=a.splitBy(e,"round_id");let i=1;for(const e of n){const n=c.createRoundContainer(s.getRoundName(i++));for(const t of e)n.append(this.createMatch(t));t.append(n)}t.append(this.createRanking(e)),r.append(t)}e.append(c.createTitle(t),r)}renderElimination(e,t,n,r){if(e.append(c.createTitle(t)),"single_elimination"===n)return this.renderSingleElimination(e,r);this.renderDoubleElimination(e,r)}renderSingleElimination(e,t){const n=void 0!==t[1];this.renderBracket(e,a.splitBy(t[0],"round_id"),s.getRoundName),n&&this.renderFinal("consolation_final",t[1])}renderDoubleElimination(e,t){const n=void 0!==t[2];this.renderBracket(e,a.splitBy(t[0],"round_id"),s.getWinnerBracketRoundName,!1,n),this.renderBracket(e,a.splitBy(t[1],"round_id"),s.getLoserBracketRoundName,!0),n&&this.renderFinal("grand_final",t[2])}renderBracket(e,t,n,r,o){const i=c.createBracketContainer(),a=t.length;let s=1;for(const e of t){const u=c.createRoundContainer(n(s));for(const n of e)u.append(this.createBracketMatch(s,t,n,a,r,o));i.append(u),s++}e.append(i)}renderFinal(e,t){const n=document.querySelector(".bracket");if(!n)throw Error("Upper bracket not found.");const r=s.getGrandFinalName(t);for(let o=0;o<t.length;o++){const i=c.createRoundContainer(s.getFinalMatchLabel(e,r,o));i.append(this.createFinalMatch(e,r,t,o)),n.append(i)}}createRanking(e){const t=c.createTable(),n=a.getRanking(e);t.append(c.createHeaders(n));for(const e of n)t.append(this.createRankingItem(e));return t}createRankingItem(e){const t=c.createRow();for(const n in e){let r=e[n];if("id"===n){const e=this.participants.find(e=>e.id===r);if(void 0!==e){const n=c.createCell(e.name);this.setupMouseHover(e.id,n),t.append(n);continue}}t.append(c.createCell(r))}return t}createBracketMatch(e,t,n,r,o,i){const a=c.getBracketConnection(e,t,o,i),u=s.getMatchLabel(n,e,r,o),d=s.getMatchHint(e,r,o);return this.createMatch(n,a,u,d,o)}createFinalMatch(e,t,n,r){const o=c.getFinalConnection(e,r,n),i=s.getFinalMatchLabel(e,t,r),a=s.getFinalMatchHint(e,r);return this.createMatch(n[r],o,i,a)}createMatch(e,t,n,r,o){o=o||!1;const i=c.createMatchContainer(),a=c.createTeamsContainer(),u=this.createTeam(e.opponent1,r,o),d=this.createTeam(e.opponent2,r,o);return n&&a.append(c.createMatchLabel(n,s.getMatchStatus(e.status))),a.append(u,d),i.append(a),t?(c.setupConnection(a,i,t),i):i}createTeam(e,t,n){const r=c.createTeamContainer(),o=c.createNameContainer(),i=c.createResultContainer();return null===e?o.innerText="BYE":this.renderParticipant(o,i,e,t,n),r.append(o,i),e&&null!==e.id&&this.setupMouseHover(e.id,r),r}renderParticipant(e,t,n,r,o){const i=this.participants.find(e=>e.id===n.id);i?(e.innerText=i.name,this.renderTeamOrigin(e,n,o)):this.renderHint(e,n,r,o),t.innerText=""+(n.score||"-"),c.setupWin(e,t,n),c.setupLoss(e,t,n)}renderHint(e,t,n,r){void 0!==n&&void 0!==t.position&&this.config.showSlotsOrigin&&(!this.config.showLowerBracketSlotsOrigin&&r||c.setupHint(e,n(t.position)))}renderTeamOrigin(e,t,n){if(void 0===t.position)return;if("none"===this.config.participantOriginPlacement)return;if(!this.config.showSlotsOrigin)return;if(!this.config.showLowerBracketSlotsOrigin&&n)return;const r=n?"P"+t.position:"#"+t.position;c.addTeamOrigin(e,r,this.config.participantOriginPlacement)}setupMouseHover(e,t){this.config.highlightParticipantOnHover&&(this.teamRefsDOM[e].push(t),t.addEventListener("mouseover",()=>{this.teamRefsDOM[e].forEach(e=>e.classList.add("hover"))}),t.addEventListener("mouseleave",()=>{this.teamRefsDOM[e].forEach(e=>e.classList.remove("hover"))}))}}},function(e,t,n){},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.setupConnection=t.getFinalConnection=t.getBracketConnection=t.addTeamOrigin=t.setupLoss=t.setupWin=t.setupHint=t.createGroupContainer=t.createRoundRobinContainer=t.createRoundContainer=t.createTitle=t.createTable=t.createHeaders=t.createRow=t.createCell=t.createBracketContainer=t.createTeamsContainer=t.createMatchLabel=t.createMatchContainer=t.createTeamContainer=t.createNameContainer=t.createResultContainer=void 0;const r=n(0);t.createResultContainer=function(){const e=document.createElement("div");return e.classList.add("result"),e},t.createNameContainer=function(){const e=document.createElement("div");return e.classList.add("name"),e},t.createTeamContainer=function(){const e=document.createElement("div");return e.classList.add("team"),e},t.createMatchContainer=function(){const e=document.createElement("div");return e.classList.add("match"),e},t.createMatchLabel=function(e,t){const n=document.createElement("span");return n.innerText=e,n.title=t,n},t.createTeamsContainer=function(){const e=document.createElement("div");return e.classList.add("teams"),e},t.createBracketContainer=function(){const e=document.createElement("section");return e.classList.add("bracket"),e},t.createCell=function(e){const t=document.createElement("td");return t.innerText=String(e),t},t.createRow=function(){return document.createElement("tr")},t.createHeaders=function(e){const t=document.createElement("tr"),n=e[0];for(const e in n){const n=r.rankingHeader(e),o=document.createElement("th");o.innerText=n.value,o.setAttribute("title",n.tooltip),t.append(o)}return t},t.createTable=function(){return document.createElement("table")},t.createTitle=function(e){const t=document.createElement("h1");return t.innerText=e,t},t.createRoundContainer=function(e){const t=document.createElement("h3");t.innerText=e;const n=document.createElement("article");return n.classList.add("round"),n.append(t),n},t.createRoundRobinContainer=function(){const e=document.createElement("div");return e.classList.add("round-robin"),e},t.createGroupContainer=function(e){const t=document.createElement("h2");t.innerText=e;const n=document.createElement("section");return n.classList.add("group"),n.append(t),n},t.setupHint=function(e,t){e.classList.add("hint"),e.innerText=t},t.setupWin=function(e,t,n){n.result&&"win"===n.result&&(e.classList.add("win"),t.classList.add("win"),void 0===n.score&&(t.innerText="W"))},t.setupLoss=function(e,t,n){(n.result&&"loss"===n.result||n.forfeit)&&(e.classList.add("loss"),t.classList.add("loss"),n.forfeit?t.innerText="F":void 0===n.score&&(t.innerText="L"))},t.addTeamOrigin=function(e,t,n){const r=document.createElement("span");"before"===n?(r.innerText=t+" ",e.prepend(r)):"after"===n&&(r.innerText=` (${t})`,e.append(r))},t.getBracketConnection=function(e,t,n,r){return n?{connectPrevious:e>1&&(e%2==1?"square":"straight"),connectNext:e<t.length&&(e%2==0?"square":"straight")}:{connectPrevious:e>1&&"square",connectNext:e<t.length?"square":!!r&&"straight"}},t.getFinalConnection=function(e,t,n){return{connectPrevious:"grand_final"===e&&0===t&&"straight",connectNext:2===n.length&&0===t&&"straight"}},t.setupConnection=function(e,t,n){n.connectPrevious&&e.classList.add("connect-previous"),n.connectNext&&t.classList.add("connect-next"),"straight"===n.connectPrevious&&e.classList.add("straight"),"straight"===n.connectNext&&t.classList.add("straight")}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getLoserBracketRoundName=t.getWinnerBracketRoundName=t.getRoundName=t.getGroupName=t.getGrandFinalName=t.getMatchStatus=t.getFinalMatchHint=t.getFinalMatchLabel=t.getMatchLabel=t.getMatchHint=void 0;const r=n(5),o=n(0);t.getMatchHint=function(e,t,n){if(!n&&1===e)return e=>"Seed "+e;if(n&&o.isMajorRound(e)){const n=Math.ceil((e+1)/2);let r=e=>`Loser of WB ${n}.${e}`;return e===t-2&&(r=e=>"Loser of WB Semi "+e),e===t&&(r=()=>"Loser of WB Final"),r}},t.getMatchLabel=function(e,t,n,r){let o="M";r?o="LB":!1===r&&(o="WB");const i=t===n-1,a=t===n;let c=`${o} ${t}.${e.number}`;return!r&&i&&(c="Semi "+e.number),a&&(c="Final"),c},t.getFinalMatchLabel=function(e,t,n){return"consolation_final"===e?"Consolation Final":t(n)},t.getFinalMatchHint=function(e,t){return"consolation_final"===e?e=>"Loser of Semi "+e:0===t?()=>"Winner of LB Final":void 0},t.getMatchStatus=function(e){switch(e){case r.Status.Locked:return"Locked";case r.Status.Waiting:return"Waiting";case r.Status.Ready:return"Ready";case r.Status.Running:return"Running";case r.Status.Completed:return"Completed";case r.Status.Archived:return"Archived"}},t.getGrandFinalName=function(e){return 1===e.length?()=>"Grand Final":e=>"GF Round "+(e+1)},t.getGroupName=function(e){return"Round "+e},t.getRoundName=function(e){return"Round "+e},t.getWinnerBracketRoundName=function(e){return"WB Round "+e},t.getLoserBracketRoundName=function(e){return"LB Round "+e}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Status=void 0,function(e){e[e.Locked=0]="Locked",e[e.Waiting=1]="Waiting",e[e.Ready=2]="Ready",e[e.Running=3]="Running",e[e.Completed=4]="Completed",e[e.Archived=5]="Archived"}(t.Status||(t.Status={}))}])}));