import { Match , ParticipantResult } from 'brackets-model' ; import { RankingHeader , Ranking , RankingFormula , RankingItem , RankingMap , BracketType , Side } from './types' ; import { t } from './lang' ; param array param key export function splitBy < T > ( array , key ) { const obj = Object ( ) ; for ( const value of array ) { if ( ! obj [ value [ key ] ] ) obj [ value [ key ] ] = [ ] ; obj [ value [ key ] ] . push ( value ) ; } return Object . values ( obj ) ; } param selector export function findRoot ( selector ? ) { const queryResult = document . querySelectorAll ( selector || '.brackets-viewer' ) ; if ( queryResult . length === 0 ) throw Error ( 'Root not found. You must have at least one root element.' ) ; if ( queryResult . length > 1 ) throw Error ( 'Multiple possible roots were found. Please use `config.selector` to choose a specific root.' ) ; const root = queryResult [ 0 ] as HTMLElement ; if ( ! root . classList . contains ( 'brackets-viewer' ) ) throw Error ( 'The selected root must have a `.brackets-viewer` class.' ) ; return root ; } param bracketType param matches param nextMatches export function completeWithBlankMatches ( bracketType , matches , nextMatches ? ) { if ( ! nextMatches ) return { matches , fromToornament : false } ; let sources = [ ] ; if ( bracketType === 'single-bracket' || bracketType === 'winner-bracket' ) sources = nextMatches . map ( match => [ match . opponent1 ?. position || null , match . opponent2 ?. position || null ] ) . flat ( ) ; if ( bracketType === 'loser-bracket' ) sources = nextMatches . map ( match => match . opponent2 ?. position || null ) ; if ( sources . filter ( source => source !== null ) . length === 0 ) return { matches , fromToornament : false } ; return { matches : sources . map ( source => source && matches . find ( match => match . number === source ) || null ) , fromToornament : true , } ; } param matchLocation param skipFirstRound param roundNumber param side export function getOriginAbbreviation ( matchLocation , skipFirstRound , roundNumber ? , side ? ) { roundNumber = roundNumber || - 1 ; if ( skipFirstRound && matchLocation === 'loser-bracket' && roundNumber === 1 ) return t ( 'abbreviations.seed' ) ; if ( matchLocation === 'single-bracket' || matchLocation === 'winner-bracket' && roundNumber === 1 ) return t ( 'abbreviations.seed' ) ; if ( matchLocation === 'loser-bracket' && roundNumber % 2 === 0 && side === 'opponent1' ) return t ( 'abbreviations.position' ) ; return null ; } param roundNumber export function isMajorRound ( roundNumber ) { return roundNumber === 1 || roundNumber % 2 === 0 ; } param itemName export function rankingHeader ( itemName ) { return t ( `ranking.${ itemName }` , { returnObjects : true } ) as RankingHeader ; } param matches param formula export function getRanking ( matches , formula ? ) { formula = formula || ( ( item ) : number => 3 * item . wins + 1 * item . draws + 0 * item . losses ) ; const rankingMap = { } ; for ( const match of matches ) { processParticipant ( rankingMap , formula , match . opponent1 , match . opponent2 ) ; processParticipant ( rankingMap , formula , match . opponent2 , match . opponent1 ) ; } return createRanking ( rankingMap ) ; } param rankingMap param formula param current param other function processParticipant ( rankingMap , formula , current , other ) { if ( ! current || current . id === null ) return ; const state = rankingMap [ current . id ] || { rank : 0 , id : 0 , played : 0 , wins : 0 , draws : 0 , losses : 0 , forfeits : 0 , scoreFor : 0 , scoreAgainst : 0 , scoreDifference : 0 , points : 0 , } ; state . id = current . id ; if ( current . forfeit || current . result ) state . played ++ ; if ( current . result === 'win' ) state . wins ++ ; if ( current . result === 'draw' ) state . draws ++ ; if ( current . result === 'loss' ) state . losses ++ ; if ( current . forfeit ) state . forfeits ++ ; state . scoreFor += current . score || 0 ; state . scoreAgainst += other && other . score || 0 ; state . scoreDifference = state . scoreFor - state . scoreAgainst ; state . points = formula ( state ) ; rankingMap [ current . id ] = state ; } param rankingMap function createRanking ( rankingMap ) { const ranking = Object . values ( rankingMap ) . sort ( ( a , b ) => a . points !== b . points ? b . points - a . points : b . played - a . played ) ; const rank = { value : 0 , lastPoints : - 1 , } ; for ( const item of ranking ) { item . rank = rank . lastPoints !== item . points ? ++ rank . value : rank . value ; rank . lastPoints = item . points ; } return ranking ; }