function conditionallyAdvanceDrawPosition(params) {
  const {
    inContextDrawMatchUps,
    tournamentRecord,
    drawDefinition,
    sourceMatchUp,
    winnerMatchUp,
    matchUpsMap,
    structure,
  } = params;

  const DOUBLE_EXIT =
    params.matchUpStatus === DOUBLE_DEFAULT ? DOUBLE_DEFAULT : DOUBLE_WALKOVER;
  const EXIT = params.matchUpStatus === DOUBLE_DEFAULT ? DEFAULTED : WALKOVER;

  const stack = 'conditionallyAdvanceDrawPosition';

  const noContextWinnerMatchUp = matchUpsMap.drawMatchUps.find(
    (matchUp) => matchUp.matchUpId === winnerMatchUp.matchUpId
  );
  if (!noContextWinnerMatchUp) return { error: MISSING_MATCHUP };

  const sourceDrawPositions = sourceMatchUp?.drawPositions || [];
  let winnerMatchUpDrawPositions =
    noContextWinnerMatchUp.drawPositions?.filter(Boolean);

  // ensure winnerMatchUp.drawPositions does not contain sourceMatchUp.drawPositions
  // this covers the case where a pre-existing advancement was made
  if (overlap(sourceDrawPositions, winnerMatchUpDrawPositions)) {
    winnerMatchUpDrawPositions = winnerMatchUpDrawPositions.filter(
      (drawPosition) => !sourceDrawPositions.includes(drawPosition)
    );
  }

  // if there are 2 drawPositions in winnerMatchUp, something is wrong
  if (winnerMatchUpDrawPositions.length > 1)
    return decorateResult({ result: { error: DRAW_POSITION_ASSIGNED }, stack });

  const { pairedPreviousMatchUpIsDoubleExit } =
    getPairedPreviousMatchUpIsDoubleExit(params);

  // get the targets for the winnerMatchUp
  const targetData = positionTargets({
    matchUpId: winnerMatchUp.matchUpId,
    inContextDrawMatchUps,
    drawDefinition,
    structure,
  });
  const { targetMatchUps, targetLinks } = targetData;

  const {
    loserTargetDrawPosition: nextLoserTargetDrawPosition,
    winnerMatchUp: nextWinnerMatchUp,
    loserMatchUp: nextLoserMatchUp,
  } = targetMatchUps;

  if (nextLoserMatchUp) {
    const { loserTargetLink } = targetLinks;
    const result = advanceByeToLoserMatchUp({
      loserTargetDrawPosition: nextLoserTargetDrawPosition,
      loserMatchUp: nextLoserMatchUp,
      tournamentRecord,
      loserTargetLink,
      drawDefinition,
      matchUpsMap,
    });
    if (result.error) return decorateResult({ result, stack });
  }

  const drawPositions =
    noContextWinnerMatchUp.drawPositions?.filter(Boolean) || [];

  const hasDrawPosition = drawPositions.length === 1;
  const walkoverWinningSide =
    (hasDrawPosition &&
      getExitWinningSide({
        drawPosition: drawPositions[0],
        matchUpId: winnerMatchUp.matchUpId,
        inContextDrawMatchUps,
      })) ||
    undefined;

  // assign the WALKOVER status to winnerMatchUp
  const existingExit =
    [WALKOVER, DEFAULTED].includes(noContextWinnerMatchUp.matchUpStatus) &&
    !drawPositions.length;
  const isFinal = noContextWinnerMatchUp.finishingRound === 1;

  const matchUpStatus = existingExit && !isFinal ? DOUBLE_EXIT : EXIT;

  const result = modifyMatchUpScore({
    ...params,
    matchUp: noContextWinnerMatchUp,
    winningSide: walkoverWinningSide,
    matchUpStatusCodes: [],
    matchUpStatus,
  });
  if (result.error) return decorateResult({ result, stack });

  // when there is an existing 'Double Exit", the created "Exit" is replaced
  // with a "Double Exit" and move on to advancing from this position
  if (existingExit) {
    return doubleExitAdvancement({
      ...params,
      matchUpStatusCodes: [],
      targetData,
    });
  }

  if (!nextWinnerMatchUp)
    return decorateResult({ result: { ...SUCCESS }, stack });

  // any remaining drawPosition in winnerMatchUp should be advanced
  const drawPositionToAdvance = winnerMatchUpDrawPositions[0];
  const { positionAssignments } = getPositionAssignments({ structure });
  const assignment = positionAssignments.find(
    (assignment) => assignment.drawPosition === drawPositionToAdvance
  );

  const noContextNextWinnerMatchUp = matchUpsMap.drawMatchUps.find(
    (matchUp) => matchUp.matchUpId === nextWinnerMatchUp.matchUpId
  );
  const nextWinnerMatchUpDrawPositions =
    noContextNextWinnerMatchUp?.drawPositions?.filter(Boolean);
  const nextWinnerMatchUpHasDrawPosition =
    nextWinnerMatchUpDrawPositions.length === 1;

  if (drawPositionToAdvance) {
    if (assignment.bye) {
      // WO/WO advanced by BYE
      const targetData = positionTargets({
        matchUpId: noContextNextWinnerMatchUp.matchUpId,
        inContextDrawMatchUps,
        drawDefinition,
        structure,
      });

      if (nextWinnerMatchUpHasDrawPosition) {
        const nextDrawPositionToAdvance =
          nextWinnerMatchUpDrawPositions.filter(Boolean)[0];

        // if the next winnerMatchUp already has a drawPosition
        const winningSide = getExitWinningSide({
          drawPosition: nextDrawPositionToAdvance,
          matchUpId: noContextNextWinnerMatchUp.matchUpId,
          inContextDrawMatchUps,
        });

        const result = modifyMatchUpScore({
          matchUpId: noContextNextWinnerMatchUp.matchUpId,
          matchUp: noContextNextWinnerMatchUp,
          matchUpStatus: EXIT,
          matchUpStatusCodes: [],
          removeScore: true,
          drawDefinition,
          winningSide,
        });
        if (result.error) return decorateResult({ result, stack });

        return advanceDrawPosition({
          drawPositionToAdvance: nextDrawPositionToAdvance,
          matchUpId: noContextNextWinnerMatchUp.matchUpId,
          inContextDrawMatchUps,
          drawDefinition,
          matchUpsMap,
        });
      } else if (
        [WALKOVER, DEFAULTED].includes(nextWinnerMatchUp.matchUpStatus)
      ) {
        // if the next winnerMatchUp is a double walkover or double default
        const result = doubleExitAdvancement({
          ...params,
          matchUpId: noContextNextWinnerMatchUp.matchUpId,
          matchUpStatusCodes: [], // don't propagate matchUpStatusCodes
          targetData,
        });
        if (result.error) return decorateResult({ result, stack });
      }

      return decorateResult({ result: { ...SUCCESS }, stack });
    }

    return assignMatchUpDrawPosition({
      matchUpId: nextWinnerMatchUp.matchUpId,
      drawPosition: drawPositionToAdvance,
      inContextDrawMatchUps,
      drawDefinition,
    });
  } else if (pairedPreviousMatchUpIsDoubleExit) {
    if (!noContextNextWinnerMatchUp) return { error: MISSING_MATCHUP };

    if (nextWinnerMatchUpHasDrawPosition) {
      const drawPosition = nextWinnerMatchUpDrawPositions[0];
      const walkoverWinningSide = getExitWinningSide({
        matchUpId: winnerMatchUp.matchUpId,
        inContextDrawMatchUps,
        drawPosition,
      });
      console.log('existing drawPosition is winningSide', {
        walkoverWinningSide,
      });
    }

    const matchUpStatus = [WALKOVER, DEFAULTED].includes(
      noContextNextWinnerMatchUp.matchUpStatus
    )
      ? EXIT
      : DOUBLE_EXIT;

    /*
    const matchUpStatus =
      noContextNextWinnerMatchUp.matchUpStatus === EXIT ? EXIT : DOUBLE_EXIT;
      */

    const result = modifyMatchUpScore({
      matchUpId: noContextNextWinnerMatchUp.matchUpId,
      matchUp: noContextNextWinnerMatchUp,
      matchUpStatusCodes: [],
      removeScore: true,
      drawDefinition,
      matchUpStatus,
    });

    if (result.error) return decorateResult({ result, stack });

    if (matchUpStatus === DOUBLE_EXIT) {
      const advancementResult = doubleExitAdvancement({
        ...params,
        matchUpStatusCodes: [], // don't propagate matchUpStatusCodes
        matchUpId: winnerMatchUp.matchUpId,
        targetData,
      });
      if (advancementResult.error) return advancementResult;
    }
  }
  return decorateResult({ result: { ...SUCCESS }, stack });
}
// 2. Advances any drawPosition that is already present
2. Advances any drawPosition that is already present
2 . Advances any drawPosition that is already present
function conditionallyAdvanceDrawPosition(params) {
  const {
    inContextDrawMatchUps,
    tournamentRecord,
    drawDefinition,
    sourceMatchUp,
    winnerMatchUp,
    matchUpsMap,
    structure,
  } = params;
  const DOUBLE_EXIT =
    params.matchUpStatus === DOUBLE_DEFAULT ? DOUBLE_DEFAULT : DOUBLE_WALKOVER;
  const EXIT = params.matchUpStatus === DOUBLE_DEFAULT ? DEFAULTED : WALKOVER;
  const stack = 'conditionallyAdvanceDrawPosition';
  const noContextWinnerMatchUp = matchUpsMap.drawMatchUps.find(
    (matchUp) => matchUp.matchUpId === winnerMatchUp.matchUpId
  );
  if (!noContextWinnerMatchUp) return { error: MISSING_MATCHUP };
  const sourceDrawPositions = sourceMatchUp?.drawPositions || [];
  let winnerMatchUpDrawPositions =
    noContextWinnerMatchUp.drawPositions?.filter(Boolean);
  if (overlap(sourceDrawPositions, winnerMatchUpDrawPositions)) {
    winnerMatchUpDrawPositions = winnerMatchUpDrawPositions.filter(
      (drawPosition) => !sourceDrawPositions.includes(drawPosition)
    );
  }
  if (winnerMatchUpDrawPositions.length > 1)
    return decorateResult({ result: { error: DRAW_POSITION_ASSIGNED }, stack });
  const { pairedPreviousMatchUpIsDoubleExit } =
    getPairedPreviousMatchUpIsDoubleExit(params);
  const targetData = positionTargets({
    matchUpId: winnerMatchUp.matchUpId,
    inContextDrawMatchUps,
    drawDefinition,
    structure,
  });
  const { targetMatchUps, targetLinks } = targetData;
  const {
    loserTargetDrawPosition: nextLoserTargetDrawPosition,
    winnerMatchUp: nextWinnerMatchUp,
    loserMatchUp: nextLoserMatchUp,
  } = targetMatchUps;
  if (nextLoserMatchUp) {
    const { loserTargetLink } = targetLinks;
    const result = advanceByeToLoserMatchUp({
      loserTargetDrawPosition: nextLoserTargetDrawPosition,
      loserMatchUp: nextLoserMatchUp,
      tournamentRecord,
      loserTargetLink,
      drawDefinition,
      matchUpsMap,
    });
    if (result.error) return decorateResult({ result, stack });
  }
  const drawPositions =
    noContextWinnerMatchUp.drawPositions?.filter(Boolean) || [];
  const hasDrawPosition = drawPositions.length === 1;
  const walkoverWinningSide =
    (hasDrawPosition &&
      getExitWinningSide({
        drawPosition: drawPositions[0],
        matchUpId: winnerMatchUp.matchUpId,
        inContextDrawMatchUps,
      })) ||
    undefined;
  const existingExit =
    [WALKOVER, DEFAULTED].includes(noContextWinnerMatchUp.matchUpStatus) &&
    !drawPositions.length;
  const isFinal = noContextWinnerMatchUp.finishingRound === 1;
  const matchUpStatus = existingExit && !isFinal ? DOUBLE_EXIT : EXIT;
  const result = modifyMatchUpScore({
    ...params,
    matchUp: noContextWinnerMatchUp,
    winningSide: walkoverWinningSide,
    matchUpStatusCodes: [],
    matchUpStatus,
  });
  if (result.error) return decorateResult({ result, stack });
  if (existingExit) {
    return doubleExitAdvancement({
      ...params,
      matchUpStatusCodes: [],
      targetData,
    });
  }
  if (!nextWinnerMatchUp)
    return decorateResult({ result: { ...SUCCESS }, stack });
  const drawPositionToAdvance = winnerMatchUpDrawPositions[0];
  const { positionAssignments } = getPositionAssignments({ structure });
  const assignment = positionAssignments.find(
    (assignment) => assignment.drawPosition === drawPositionToAdvance
  );
  const noContextNextWinnerMatchUp = matchUpsMap.drawMatchUps.find(
    (matchUp) => matchUp.matchUpId === nextWinnerMatchUp.matchUpId
  );
  const nextWinnerMatchUpDrawPositions =
    noContextNextWinnerMatchUp?.drawPositions?.filter(Boolean);
  const nextWinnerMatchUpHasDrawPosition =
    nextWinnerMatchUpDrawPositions.length === 1;
  if (drawPositionToAdvance) {
    if (assignment.bye) {
      const targetData = positionTargets({
        matchUpId: noContextNextWinnerMatchUp.matchUpId,
        inContextDrawMatchUps,
        drawDefinition,
        structure,
      });
      if (nextWinnerMatchUpHasDrawPosition) {
        const nextDrawPositionToAdvance =
          nextWinnerMatchUpDrawPositions.filter(Boolean)[0];
        const winningSide = getExitWinningSide({
          drawPosition: nextDrawPositionToAdvance,
          matchUpId: noContextNextWinnerMatchUp.matchUpId,
          inContextDrawMatchUps,
        });
        const result = modifyMatchUpScore({
          matchUpId: noContextNextWinnerMatchUp.matchUpId,
          matchUp: noContextNextWinnerMatchUp,
          matchUpStatus: EXIT,
          matchUpStatusCodes: [],
          removeScore: true,
          drawDefinition,
          winningSide,
        });
        if (result.error) return decorateResult({ result, stack });
        return advanceDrawPosition({
          drawPositionToAdvance: nextDrawPositionToAdvance,
          matchUpId: noContextNextWinnerMatchUp.matchUpId,
          inContextDrawMatchUps,
          drawDefinition,
          matchUpsMap,
        });
      } else if (
        [WALKOVER, DEFAULTED].includes(nextWinnerMatchUp.matchUpStatus)
      ) {
        const result = doubleExitAdvancement({
          ...params,
          matchUpId: noContextNextWinnerMatchUp.matchUpId,
          matchUpStatusCodes: [], 
          targetData,
        });
        if (result.error) return decorateResult({ result, stack });
      }
      return decorateResult({ result: { ...SUCCESS }, stack });
    }
    return assignMatchUpDrawPosition({
      matchUpId: nextWinnerMatchUp.matchUpId,
      drawPosition: drawPositionToAdvance,
      inContextDrawMatchUps,
      drawDefinition,
    });
  } else if (pairedPreviousMatchUpIsDoubleExit) {
    if (!noContextNextWinnerMatchUp) return { error: MISSING_MATCHUP };
    if (nextWinnerMatchUpHasDrawPosition) {
      const drawPosition = nextWinnerMatchUpDrawPositions[0];
      const walkoverWinningSide = getExitWinningSide({
        matchUpId: winnerMatchUp.matchUpId,
        inContextDrawMatchUps,
        drawPosition,
      });
      console.log('existing drawPosition is winningSide', {
        walkoverWinningSide,
      });
    }
    const matchUpStatus = [WALKOVER, DEFAULTED].includes(
      noContextNextWinnerMatchUp.matchUpStatus
    )
      ? EXIT
      : DOUBLE_EXIT;
    const result = modifyMatchUpScore({
      matchUpId: noContextNextWinnerMatchUp.matchUpId,
      matchUp: noContextNextWinnerMatchUp,
      matchUpStatusCodes: [],
      removeScore: true,
      drawDefinition,
      matchUpStatus,
    });
    if (result.error) return decorateResult({ result, stack });
    if (matchUpStatus === DOUBLE_EXIT) {
      const advancementResult = doubleExitAdvancement({
        ...params,
        matchUpStatusCodes: [], 
        matchUpId: winnerMatchUp.matchUpId,
        targetData,
      });
      if (advancementResult.error) return advancementResult;
    }
  }
  return decorateResult({ result: { ...SUCCESS }, stack });
}
function conditionallyAdvanceDrawPosition ( params ) { const { inContextDrawMatchUps , tournamentRecord , drawDefinition , sourceMatchUp , winnerMatchUp , matchUpsMap , structure , } = params ; const DOUBLE_EXIT = params . matchUpStatus === DOUBLE_DEFAULT ? DOUBLE_DEFAULT : DOUBLE_WALKOVER ; const EXIT = params . matchUpStatus === DOUBLE_DEFAULT ? DEFAULTED : WALKOVER ; const stack = 'conditionallyAdvanceDrawPosition' ; const noContextWinnerMatchUp = matchUpsMap . drawMatchUps . find ( ( matchUp ) => matchUp . matchUpId === winnerMatchUp . matchUpId ) ; if ( ! noContextWinnerMatchUp ) return { error : MISSING_MATCHUP } ; const sourceDrawPositions = sourceMatchUp ?. drawPositions || [ ] ; let winnerMatchUpDrawPositions = noContextWinnerMatchUp . drawPositions ?. filter ( Boolean ) ; if ( overlap ( sourceDrawPositions , winnerMatchUpDrawPositions ) ) { winnerMatchUpDrawPositions = winnerMatchUpDrawPositions . filter ( ( drawPosition ) => ! sourceDrawPositions . includes ( drawPosition ) ) ; } if ( winnerMatchUpDrawPositions . length > 1 ) return decorateResult ( { result : { error : DRAW_POSITION_ASSIGNED } , stack } ) ; const { pairedPreviousMatchUpIsDoubleExit } = getPairedPreviousMatchUpIsDoubleExit ( params ) ; const targetData = positionTargets ( { matchUpId : winnerMatchUp . matchUpId , inContextDrawMatchUps , drawDefinition , structure , } ) ; const { targetMatchUps , targetLinks } = targetData ; const { loserTargetDrawPosition : nextLoserTargetDrawPosition , winnerMatchUp : nextWinnerMatchUp , loserMatchUp : nextLoserMatchUp , } = targetMatchUps ; if ( nextLoserMatchUp ) { const { loserTargetLink } = targetLinks ; const result = advanceByeToLoserMatchUp ( { loserTargetDrawPosition : nextLoserTargetDrawPosition , loserMatchUp : nextLoserMatchUp , tournamentRecord , loserTargetLink , drawDefinition , matchUpsMap , } ) ; if ( result . error ) return decorateResult ( { result , stack } ) ; } const drawPositions = noContextWinnerMatchUp . drawPositions ?. filter ( Boolean ) || [ ] ; const hasDrawPosition = drawPositions . length === 1 ; const walkoverWinningSide = ( hasDrawPosition && getExitWinningSide ( { drawPosition : drawPositions [ 0 ] , matchUpId : winnerMatchUp . matchUpId , inContextDrawMatchUps , } ) ) || undefined ; const existingExit = [ WALKOVER , DEFAULTED ] . includes ( noContextWinnerMatchUp . matchUpStatus ) && ! drawPositions . length ; const isFinal = noContextWinnerMatchUp . finishingRound === 1 ; const matchUpStatus = existingExit && ! isFinal ? DOUBLE_EXIT : EXIT ; const result = modifyMatchUpScore ( { ... params , matchUp : noContextWinnerMatchUp , winningSide : walkoverWinningSide , matchUpStatusCodes : [ ] , matchUpStatus , } ) ; if ( result . error ) return decorateResult ( { result , stack } ) ; if ( existingExit ) { return doubleExitAdvancement ( { ... params , matchUpStatusCodes : [ ] , targetData , } ) ; } if ( ! nextWinnerMatchUp ) return decorateResult ( { result : { ... SUCCESS } , stack } ) ; const drawPositionToAdvance = winnerMatchUpDrawPositions [ 0 ] ; const { positionAssignments } = getPositionAssignments ( { structure } ) ; const assignment = positionAssignments . find ( ( assignment ) => assignment . drawPosition === drawPositionToAdvance ) ; const noContextNextWinnerMatchUp = matchUpsMap . drawMatchUps . find ( ( matchUp ) => matchUp . matchUpId === nextWinnerMatchUp . matchUpId ) ; const nextWinnerMatchUpDrawPositions = noContextNextWinnerMatchUp ?. drawPositions ?. filter ( Boolean ) ; const nextWinnerMatchUpHasDrawPosition = nextWinnerMatchUpDrawPositions . length === 1 ; if ( drawPositionToAdvance ) { if ( assignment . bye ) { const targetData = positionTargets ( { matchUpId : noContextNextWinnerMatchUp . matchUpId , inContextDrawMatchUps , drawDefinition , structure , } ) ; if ( nextWinnerMatchUpHasDrawPosition ) { const nextDrawPositionToAdvance = nextWinnerMatchUpDrawPositions . filter ( Boolean ) [ 0 ] ; const winningSide = getExitWinningSide ( { drawPosition : nextDrawPositionToAdvance , matchUpId : noContextNextWinnerMatchUp . matchUpId , inContextDrawMatchUps , } ) ; const result = modifyMatchUpScore ( { matchUpId : noContextNextWinnerMatchUp . matchUpId , matchUp : noContextNextWinnerMatchUp , matchUpStatus : EXIT , matchUpStatusCodes : [ ] , removeScore : true , drawDefinition , winningSide , } ) ; if ( result . error ) return decorateResult ( { result , stack } ) ; return advanceDrawPosition ( { drawPositionToAdvance : nextDrawPositionToAdvance , matchUpId : noContextNextWinnerMatchUp . matchUpId , inContextDrawMatchUps , drawDefinition , matchUpsMap , } ) ; } else if ( [ WALKOVER , DEFAULTED ] . includes ( nextWinnerMatchUp . matchUpStatus ) ) { const result = doubleExitAdvancement ( { ... params , matchUpId : noContextNextWinnerMatchUp . matchUpId , matchUpStatusCodes : [ ] , targetData , } ) ; if ( result . error ) return decorateResult ( { result , stack } ) ; } return decorateResult ( { result : { ... SUCCESS } , stack } ) ; } return assignMatchUpDrawPosition ( { matchUpId : nextWinnerMatchUp . matchUpId , drawPosition : drawPositionToAdvance , inContextDrawMatchUps , drawDefinition , } ) ; } else if ( pairedPreviousMatchUpIsDoubleExit ) { if ( ! noContextNextWinnerMatchUp ) return { error : MISSING_MATCHUP } ; if ( nextWinnerMatchUpHasDrawPosition ) { const drawPosition = nextWinnerMatchUpDrawPositions [ 0 ] ; const walkoverWinningSide = getExitWinningSide ( { matchUpId : winnerMatchUp . matchUpId , inContextDrawMatchUps , drawPosition , } ) ; console . log ( 'existing drawPosition is winningSide' , { walkoverWinningSide , } ) ; } const matchUpStatus = [ WALKOVER , DEFAULTED ] . includes ( noContextNextWinnerMatchUp . matchUpStatus ) ? EXIT : DOUBLE_EXIT ; const result = modifyMatchUpScore ( { matchUpId : noContextNextWinnerMatchUp . matchUpId , matchUp : noContextNextWinnerMatchUp , matchUpStatusCodes : [ ] , removeScore : true , drawDefinition , matchUpStatus , } ) ; if ( result . error ) return decorateResult ( { result , stack } ) ; if ( matchUpStatus === DOUBLE_EXIT ) { const advancementResult = doubleExitAdvancement ( { ... params , matchUpStatusCodes : [ ] , matchUpId : winnerMatchUp . matchUpId , targetData , } ) ; if ( advancementResult . error ) return advancementResult ; } } return decorateResult ( { result : { ... SUCCESS } , stack } ) ; }
2.
2 .
// ensure winnerMatchUp.drawPositions does not contain sourceMatchUp.drawPositions // this covers the case where a pre-existing advancement was made // if there are 2 drawPositions in winnerMatchUp, something is wrong // get the targets for the winnerMatchUp // assign the WALKOVER status to winnerMatchUp // when there is an existing 'Double Exit", the created "Exit" is replaced // with a "Double Exit" and move on to advancing from this position // any remaining drawPosition in winnerMatchUp should be advanced // WO/WO advanced by BYE // if the next winnerMatchUp already has a drawPosition // if the next winnerMatchUp is a double walkover or double default // don't propagate matchUpStatusCodes /*
    const matchUpStatus =
      noContextNextWinnerMatchUp.matchUpStatus === EXIT ? EXIT : DOUBLE_EXIT;
      */ // don't propagate matchUpStatusCodes