<commit_before>import React from 'react';
import Analyzer from 'parser/core/Analyzer';
import SpellUsable from 'parser/shared/modules/SpellUsable';
import SPELLS from 'common/SPELLS';
import RESOURCE_TYPES from 'game/RESOURCE_TYPES';
import { STATISTIC_ORDER } from 'interface/others/StatisticBox';
import SpellIcon from 'common/SpellIcon';
import { formatNumber, formatPercentage } from 'common/format';
import SpellLink from 'common/SpellLink';
import ResourceIcon from 'common/ResourceIcon';
import StatisticBox from 'interface/others/StatisticBox';

const COOLDOWN_REDUCTION_MS = 12000;
const BESTIAL_WRATH_BASE_CD = 90000;

/**
 * Sends you and your pet into a rage, increasing all damage you both deal by 25% for 15 sec.
 * Bestial Wrath's remaining cooldown is reduced by 12 sec each time you use Barbed Shot
 *
 * Example log: https://www.warcraftlogs.com/reports/pdm6qYNZ2ktMXDRr#fight=7&type=damage-done&source=8
 */
class BestialWrath extends Analyzer {
  static dependencies = {
    spellUsable: SpellUsable,
  };

  effectiveBWReduction = 0;
  wastedBWReduction = 0;
  casts = 0;
  accumulatedFocusAtBWCast = 0;
  prepullBW = 0;
  startFocusForCombatant = 0;

  on_byPlayer_cast(event) {
    const spellId = event.ability.guid;
    if (this.prepullBW > 0 && this.startFocusForCombatant === 0) {
      event.classResources.forEach(classResource => {
        if (classResource.type === RESOURCE_TYPES.FOCUS.id && classResource.amount > this.startFocusForCombatant) {
          this.startFocusForCombatant += classResource.amount;
          this.accumulatedFocusAtBWCast += this.startFocusForCombatant;
        }
      });
    }
    if (spellId === SPELLS.BESTIAL_WRATH.id) {
      this.casts += 1;
      this.accumulatedFocusAtBWCast += event.classResources[0].amount || 0;
      return;
    }
    if (spellId !== SPELLS.BARBED_SHOT.id) {
      return;
    }
    const bestialWrathIsOnCooldown = this.spellUsable.isOnCooldown(SPELLS.BESTIAL_WRATH.id);
    if (bestialWrathIsOnCooldown) {
      const reductionMs = this.spellUsable.reduceCooldown(SPELLS.BESTIAL_WRATH.id, COOLDOWN_REDUCTION_MS);
      this.effectiveBWReduction += reductionMs;
      this.wastedBWReduction += (COOLDOWN_REDUCTION_MS - reductionMs);
    } else {
      this.wastedBWReduction += COOLDOWN_REDUCTION_MS;
    }
  }

  on_byPlayer_applybuff(event) {
    const buffId = event.ability.guid;
    if (buffId !== SPELLS.BESTIAL_WRATH.id || !event.prepull) {
      return;
    }
    this.casts += 1;
    this.prepullBW += 1;
    this.spellUsable.beginCooldown(SPELLS.BESTIAL_WRATH.id, this.owner.fight.start_time);
  }

  get percentUptime() {
    return formatPercentage(this.selectedCombatant.getBuffUptime(SPELLS.BESTIAL_WRATH.id) / this.owner.fightDuration);
  }

  get gainedBestialWraths() {
    return (this.effectiveBWReduction / BESTIAL_WRATH_BASE_CD).toFixed(1);
  }

  get averageFocusAtBestialWrathCast() {
    return formatNumber(this.accumulatedFocusAtBWCast / this.casts);
  }

  get totalPossibleCDR() {
    return (this.wastedBWReduction + this.effectiveBWReduction);
  }

  get effectiveBestialWrathCDRPercent() {
    return this.effectiveBWReduction / this.totalPossibleCDR;
  }

  get focusOnBestialWrathCastThreshold() {
    if (this.selectedCombatant.hasTalent(SPELLS.KILLER_COBRA_TALENT.id)) {
      return {
        actual: this.averageFocusAtBestialWrathCast,
        isLessThan: {
          minor: 95,
          average: 85,
          major: 75,
        },<commit_msg>Fix BM BW cooldown error due to double counting prepull BW<commit_after>import React from 'react';
import Analyzer from 'parser/core/Analyzer';
import SpellUsable from 'parser/shared/modules/SpellUsable';
import SPELLS from 'common/SPELLS';
import RESOURCE_TYPES from 'game/RESOURCE_TYPES';
import { STATISTIC_ORDER } from 'interface/others/StatisticBox';
import SpellIcon from 'common/SpellIcon';
import { formatNumber, formatPercentage } from 'common/format';
import SpellLink from 'common/SpellLink';
import ResourceIcon from 'common/ResourceIcon';
import StatisticBox from 'interface/others/StatisticBox';

const COOLDOWN_REDUCTION_MS = 12000;
const BESTIAL_WRATH_BASE_CD = 90000;

/**
 * Sends you and your pet into a rage, increasing all damage you both deal by 25% for 15 sec.
 * Bestial Wrath's remaining cooldown is reduced by 12 sec each time you use Barbed Shot
 *
 * Example log: https://www.warcraftlogs.com/reports/pdm6qYNZ2ktMXDRr#fight=7&type=damage-done&source=8
 */
class BestialWrath extends Analyzer {
  static dependencies = {
    spellUsable: SpellUsable,
  };

  effectiveBWReduction = 0;
  wastedBWReduction = 0;
  casts = 0;
  accumulatedFocusAtBWCast = 0;

  on_byPlayer_cast(event) {
    const spellId = event.ability.guid;
    if (spellId === SPELLS.BESTIAL_WRATH.id) {
      this.casts += 1;
      this.accumulatedFocusAtBWCast += event.classResources[0].amount || 0;
      return;
    }
    if (spellId !== SPELLS.BARBED_SHOT.id) {
      return;
    }
    const bestialWrathIsOnCooldown = this.spellUsable.isOnCooldown(SPELLS.BESTIAL_WRATH.id);
    if (bestialWrathIsOnCooldown) {
      const reductionMs = this.spellUsable.reduceCooldown(SPELLS.BESTIAL_WRATH.id, COOLDOWN_REDUCTION_MS);
      this.effectiveBWReduction += reductionMs;
      this.wastedBWReduction += (COOLDOWN_REDUCTION_MS - reductionMs);
    } else {
      this.wastedBWReduction += COOLDOWN_REDUCTION_MS;
    }
  }

  get percentUptime() {
    return formatPercentage(this.selectedCombatant.getBuffUptime(SPELLS.BESTIAL_WRATH.id) / this.owner.fightDuration);
  }

  get gainedBestialWraths() {
    return (this.effectiveBWReduction / BESTIAL_WRATH_BASE_CD).toFixed(1);
  }

  get averageFocusAtBestialWrathCast() {
    return formatNumber(this.accumulatedFocusAtBWCast / this.casts);
  }

  get totalPossibleCDR() {
    return (this.wastedBWReduction + this.effectiveBWReduction);
  }

  get effectiveBestialWrathCDRPercent() {
    return this.effectiveBWReduction / this.totalPossibleCDR;
  }

  get focusOnBestialWrathCastThreshold() {
    if (this.selectedCombatant.hasTalent(SPELLS.KILLER_COBRA_TALENT.id)) {
      return {
        actual: this.averageFocusAtBestialWrathCast,
        isLessThan: {
          minor: 95,
          average: 85,
          major: 75,
        },
{'fraction_non_alphanumeric': 0.09931233008156085, 'fraction_numerical': 0.011834319526627219, 'mean_word_length': 3.9674344718030183, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 6, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7390393', 'n_tokens_mistral': 2238, 'n_tokens_neox': 2136, 'n_words': 398}