<commit_before>import React from 'react';

import Analyzer from 'Parser/Core/Analyzer';
import Combatants from 'Parser/Core/Modules/Combatants';

import SPELLS from 'common/SPELLS';
import StatisticBox from 'Main/StatisticBox';
import SpellIcon from 'common/SpellIcon';
import { formatPercentage } from 'common/format';

/*
 * Your Sentinel watches over the target area for 18 sec, applying Hunter's Mark to all enemies every 6 sec.
 */
const MS_BUFFER = 100;

const TICKS_PER_CAST = 4;

class Sentinel extends Analyzer {
  static dependencies = {
    combatants: Combatants,

  };
  damage = 0;
  applyDebuffTimestamp = null;
  sentinelCasts = 0;
  sentinelTicks = 0;
  appliedDebuffsFromSentinel = 0;
  wastedApplications = 0;
  wastedTicks = 0;
  lastBadTickTimestamp = 0;

  on_initialized() {
    this.active = this.combatants.selected.hasTalent(SPELLS.SENTINEL_TALENT.id);
  }

  on_byPlayer_cast(event) {
    const spellId = event.ability.guid;
    if (spellId !== SPELLS.SENTINEL_TICK.id && spellId !== SPELLS.SENTINEL_TALENT.id) {
      return;
    }
    if (spellId === SPELLS.SENTINEL_TALENT.id) {
      this.sentinelCasts++;
    }
    if (spellId === SPELLS.SENTINEL_TICK.id) {
      this.applyDebuffTimestamp = event.timestamp;
      this.sentinelTicks++;
    }
  }
  on_byPlayer_applydebuff(event) {
    const spellId = event.ability.guid;
    if (spellId !== SPELLS.HUNTERS_MARK_DEBUFF.id) {
      return;
    }
    if (event.timestamp < this.applyDebuffTimestamp + MS_BUFFER && event.timestamp >= this.applyDebuffTimestamp) {
      this.appliedDebuffsFromSentinel++;
    }
  }
  on_byPlayer_refreshdebuff(event) {
    const spellId = event.ability.guid;
    if (spellId !== SPELLS.HUNTERS_MARK_DEBUFF.id) {
      return;
    }
    if (event.timestamp < this.applyDebuffTimestamp + MS_BUFFER && event.timestamp >= this.applyDebuffTimestamp) {
      this.wastedApplications++;
      if (this.lastBadTickTimestamp !== event.timestamp) {
        this.wastedTicks++;
        this.lastBadTickTimestamp = event.timestamp;
      }
    }
  }

  get debuffsPerCast() {
    return (this.appliedDebuffsFromSentinel / this.sentinelCasts).toFixed(1);
  }
  get totalPossibleTicks() {
    return this.sentinelCasts * TICKS_PER_CAST;
  }
  get buggedTicks() {
    return this.totalPossibleTicks - this.sentinelTicks;
  }
  get goodTicks() {
    return this.totalPossibleTicks - this.buggedTicks - this.wastedTicks;
  }

  statistic() {
    return (
      <StatisticBox
        icon={<SpellIcon id={SPELLS.SENTINEL_TALENT.id} />}
        value={`${this.goodTicks}/${this.totalPossibleTicks}`}
        label={`flawless ticks + ${this.buggedTicks} bugged`}
        tooltip={`You applied Hunter's Mark with Sentinel ${this.appliedDebuffsFromSentinel} times spread over ${this.sentinelCasts} casts of Sentinel. This gives an average of ${this.debuffsPerCast} debuffs per cast. </br> Out of ${this.totalPossibleTicks} possible ticks: <ul><li>${this.goodTicks} ticks were good ticks where no target already had Hunter's Mark when it ticked.</li><li>${this.wastedTicks} ticks had one or more targets already with Hunter's Mark on them.</li><li>${this.buggedTicks} ticks bugged and didn't happen.</li></ul>`}
        footer={(
          <div className="statistic-bar">
            <div<commit_msg>add wasted applications to tooltip<commit_after>import React from 'react';

import Analyzer from 'Parser/Core/Analyzer';
import Combatants from 'Parser/Core/Modules/Combatants';

import SPELLS from 'common/SPELLS';
import StatisticBox from 'Main/StatisticBox';
import SpellIcon from 'common/SpellIcon';
import { formatPercentage } from 'common/format';

/*
 * Your Sentinel watches over the target area for 18 sec, applying Hunter's Mark to all enemies every 6 sec.
 */
const MS_BUFFER = 100;

const TICKS_PER_CAST = 4;

class Sentinel extends Analyzer {
  static dependencies = {
    combatants: Combatants,

  };
  damage = 0;
  applyDebuffTimestamp = null;
  sentinelCasts = 0;
  sentinelTicks = 0;
  appliedDebuffsFromSentinel = 0;
  wastedApplications = 0;
  wastedTicks = 0;
  lastBadTickTimestamp = 0;

  on_initialized() {
    this.active = this.combatants.selected.hasTalent(SPELLS.SENTINEL_TALENT.id);
  }

  on_byPlayer_cast(event) {
    const spellId = event.ability.guid;
    if (spellId !== SPELLS.SENTINEL_TICK.id && spellId !== SPELLS.SENTINEL_TALENT.id) {
      return;
    }
    if (spellId === SPELLS.SENTINEL_TALENT.id) {
      this.sentinelCasts++;
    }
    if (spellId === SPELLS.SENTINEL_TICK.id) {
      this.applyDebuffTimestamp = event.timestamp;
      this.sentinelTicks++;
    }
  }
  on_byPlayer_applydebuff(event) {
    const spellId = event.ability.guid;
    if (spellId !== SPELLS.HUNTERS_MARK_DEBUFF.id) {
      return;
    }
    if (event.timestamp < this.applyDebuffTimestamp + MS_BUFFER && event.timestamp >= this.applyDebuffTimestamp) {
      this.appliedDebuffsFromSentinel++;
    }
  }
  on_byPlayer_refreshdebuff(event) {
    const spellId = event.ability.guid;
    if (spellId !== SPELLS.HUNTERS_MARK_DEBUFF.id) {
      return;
    }
    if (event.timestamp < this.applyDebuffTimestamp + MS_BUFFER && event.timestamp >= this.applyDebuffTimestamp) {
      this.wastedApplications++;
      if (this.lastBadTickTimestamp !== event.timestamp) {
        this.wastedTicks++;
        this.lastBadTickTimestamp = event.timestamp;
      }
    }
  }

  get debuffsPerCast() {
    return (this.appliedDebuffsFromSentinel / this.sentinelCasts).toFixed(1);
  }
  get totalPossibleTicks() {
    return this.sentinelCasts * TICKS_PER_CAST;
  }
  get buggedTicks() {
    return this.totalPossibleTicks - this.sentinelTicks;
  }
  get goodTicks() {
    return this.totalPossibleTicks - this.buggedTicks - this.wastedTicks;
  }

  statistic() {
    return (
      <StatisticBox
        icon={<SpellIcon id={SPELLS.SENTINEL_TALENT.id} />}
        value={`${this.goodTicks}/${this.totalPossibleTicks}`}
        label={`flawless ticks + ${this.buggedTicks} bugged`}
        tooltip={`You applied Hunter's Mark with Sentinel ${this.appliedDebuffsFromSentinel} times spread over ${this.sentinelCasts} casts of Sentinel. This gives an average of ${this.debuffsPerCast} debuffs per cast. <br/> You wasted ${this.wastedApplications} possible applications with Sentinel ticking on targets who already had Hunter's Mark debuff. </br> Out of ${this.totalPossibleTicks} possible ticks: <ul><li>${this.goodTicks} ticks were good ticks where no target already had Hunter's Mark when it ticked.</li><li>${this.wastedTicks} ticks had one or more targets already with Hunter's Mark on them.</li><li>${this.buggedTicks} ticks bugged and didn't happen.</li></ul>`}
        footer={(
          <div className="statistic-bar">
            <div
{'fraction_non_alphanumeric': 0.1147906147906148, 'fraction_numerical': 0.004455004455004455, 'mean_word_length': 3.648033126293996, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '5281460', 'n_tokens_mistral': 2359, 'n_tokens_neox': 2231, 'n_words': 484}