<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import strings from 'lang';
import {
  formatSeconds,
  getHeroesById,
  translateBuildings as tb,
} from 'utility';
import ReactTooltip from 'react-tooltip';
import Table from 'components/Table';
import heroes from 'dotaconstants/build/heroes.json';
import FormField from 'components/Form/FormField';
import { IconRadiant, IconDire } from 'components/Icons';
import {
  heroTdColumn,
} from './matchColumns';
import { StyledLogFilterForm } from './StyledMatch';

const heroNames = getHeroesById();
const typeConfig = {
  kills: 0,
  objectives: 1,
  runes: 2,
};
const getObjectiveDesc = objective => (objective.key && objective.type === 'CHAT_MESSAGE_BARRACKS_KILL' ? strings[`barracks_value_${objective.key}`] : '');
const getObjectiveBase = (objective) => {
  if (objective.type === 'building_kill') {
    const desc = objective.key.indexOf('<KEY>') === 0 ? strings.general_dire : strings.general_radiant;
    return `${desc} ${(objective.key.split('guys_') || [])[1]}`;
  }
  return strings[objective.subtype || objective.type] || objective.subtype || objective.type;
};
const generateLog = (match, { types, players }) => {
  let log = [];
  const matchPlayers = !players.length
    ? match.players
    : match.players.filter((p, i) => players.includes(i));

  if (types.includes(typeConfig.objectives)) {
    log = (match.objectives || []).reduce((objectivesLog, objective) => {
      if (!players.length || players.includes(objective.slot)) {
        /*
        let name;
        if (objective.slot === -1) {
          if (objective.team === 2) {
            name = strings.general_radiant;
          } else if (objective.team === 3) {
            name = strings.general_dire;
          }
        }
        */
        objectivesLog.push({
          ...objective,
          ...matchPlayers[objective.slot],
          type: 'objectives',
          detail: `${getObjectiveDesc(objective)} ${getObjectiveBase(objective)}`,
        });
      }
      return objectivesLog;
    }, log);
  }

  matchPlayers.forEach((player) => {
    if (types.includes(typeConfig.kills)) {
      log = log.concat((player.kills_log || []).map(entry => ({
        ...entry,
        ...player,
        type: 'kills',
        detail: `${entry.key}`,
      })));
    }

    if (types.includes(typeConfig.runes)) {
      log = log.concat((player.runes_log || []).map(entry => ({
        ...entry,
        ...player,
        type: 'runes',
        detail: `${entry.key}`,
      })));
    }
    /*
    log = log.concat((player.obs_log || []).map(entry => ({
      ...entry,
      ...player,
      type: 'obs_ward',
      detail: `${entry.key}`,
    })));
    */
  });
  log = log.sort((a, b) => a.time - b.time);
  return log;
};

const logColumns = [heroTdColumn, {
  displayName: strings.heading_is_radiant,
  tooltip: strings.heading_is_radiant,
  field: 'isRadiant',
  sortFn: true,
  displayFn: (row, col, field) =>
    (
      <span>
        {field && <IconRadiant height="30" />}
        {!field && <IconDire height="30" />}
      </span>
    ),
},
{
  displayName: strings.th_time,
  field: 'time',
  displayFn: (row, col, field) => formatSeconds(field),
}, {
  displayName: strings.ward_log_type,
  field: 'type',
}, {
  displayName: strings.log_detail,
  field: 'detail',
  displayFn: (row) => {
    switch (row.type) {
      case 'kills': {
        const hero = heroNames[row.detail] || {};
        return <img src={`${process.env.REACT_APP_API_HOST}${hero.img}`} style={{ height: '30px' }} alt="" />;
      }
      case 'runes': {
        const runeType = row.detail;
        const runeString = strings[`rune_${runeType}`];
        return (
          <img
            src={`/assets/images/dota2/runes/${runeType}.png`}
            alt=""
            style={{ height: '30px' }}
            data-tip
            data-for={runeString}
          />
        );
      }
      case 'objectives': {
        if (row.detail === ' First Blood') {
          return (
            <span>
              <img
                src="/assets/images/dota2/bloodsplattersmall.png"
                alt=""
                style={{ height: '30px', float: 'left', paddingTop: '7px' }}
              />
              <p>{strings.th_firstblood_claimed}</p>
            </span>
          );
        }
        if (tb.radiant[row.key]) {
          return (
            <span>
              <IconRadiant
                style={{ height: '30px', float: 'left', paddingTop: '7px' }}
              />
              <p>{tb.radiant[row.key]} {row.isRadiant ? `(${strings.building_denied})` : ''}</p>
            </span>
          );
        }
        if (tb.dire[row.key]) {
          return (
            <span>
              <IconDire
                style={{ height: '30px', float: 'left', paddingTop: '7px' }}
              />
              <p>{tb.dire[row.key]} {!row.isRadiant ? `(${strings.building_denied})` : ''}</p>
            </span>
          );
        }
        if (row.detail === ' Picked up the Aegis') {
          return (
            <span>
              <img
                src="/assets/images/dota2/aegis_icon.png"
                alt=""
                style={{ height: '30px', float: 'left', paddingTop: '7px' }}
              />
              <p>{strings.CHAT_MESSAGE_AEGIS}</p>
            </span>
          );
        }
        if (row.detail === ' Roshan') {
          return (
            <span>
              <img
                src="/assets/images/dota2/deadroshan.png"
                alt=""
                style={{ height: '30px', float: 'left', paddingTop: '7px' }}
              />
              <p>{strings.th_roshan}</p>
            </span>
          );
        }
        return row.detail;
      }<commit_msg>improved match log<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import strings from 'lang';
import {
  formatSeconds,
  getHeroesById,
  translateBuildings as tb,
} from 'utility';
import ReactTooltip from 'react-tooltip';
import Table from 'components/Table';
import heroes from 'dotaconstants/build/heroes.json';
import FormField from 'components/Form/FormField';
import { IconRadiant, IconDire } from 'components/Icons';
import {
  heroTdColumn,
} from './matchColumns';
import { StyledLogFilterForm } from './StyledMatch';

const logDetailIconStyle = { height: '30px', float: 'left', paddingTop: '7px' };
const heroNames = getHeroesById();
const typeConfig = {
  kills: 0,
  objectives: 1,
  runes: 2,
};
const getObjectiveDesc = objective => (objective.key && objective.type === 'CHAT_MESSAGE_BARRACKS_KILL' ? strings[`barracks_value_${objective.key}`] : '');
const getObjectiveBase = (objective) => {
  if (objective.type === 'building_kill') {
    const desc = objective.key.indexOf('<KEY>') === 0 ? strings.general_dire : strings.general_radiant;
    return `${desc} ${(objective.key.split('guys_') || [])[1]}`;
  }
  return strings[objective.subtype || objective.type] || objective.subtype || objective.type;
};
const generateLog = (match, { types, players }) => {
  let log = [];
  const matchPlayers = !players.length
    ? match.players
    : match.players.filter((p, i) => players.includes(i));

  if (types.includes(typeConfig.objectives)) {
    log = (match.objectives || []).reduce((objectivesLog, objective) => {
      if (!players.length || players.includes(objective.slot)) {
        /*
        let name;
        if (objective.slot === -1) {
          if (objective.team === 2) {
            name = strings.general_radiant;
          } else if (objective.team === 3) {
            name = strings.general_dire;
          }
        }
        */
        objectivesLog.push({
          ...objective,
          ...matchPlayers[objective.slot],
          type: 'objectives',
          detail: `${getObjectiveDesc(objective)} ${getObjectiveBase(objective)}`,
        });
      }
      return objectivesLog;
    }, log);
  }

  matchPlayers.forEach((player) => {
    if (types.includes(typeConfig.kills)) {
      log = log.concat((player.kills_log || []).map(entry => ({
        ...entry,
        ...player,
        type: 'kills',
        detail: `${entry.key}`,
      })));
    }

    if (types.includes(typeConfig.runes)) {
      log = log.concat((player.runes_log || []).map(entry => ({
        ...entry,
        ...player,
        type: 'runes',
        detail: `${entry.key}`,
      })));
    }
    /*
    log = log.concat((player.obs_log || []).map(entry => ({
      ...entry,
      ...player,
      type: 'obs_ward',
      detail: `${entry.key}`,
    })));
    */
  });
  log = log.sort((a, b) => a.time - b.time);
  return log;
};

const logColumns = [heroTdColumn, {
  displayName: strings.heading_is_radiant,
  tooltip: strings.heading_is_radiant,
  field: 'isRadiant',
  sortFn: true,
  displayFn: (row, col, field) =>
    (
      <span>
        {field && <IconRadiant height="30" />}
        {!field && <IconDire height="30" />}
      </span>
    ),
},
{
  displayName: strings.th_time,
  field: 'time',
  displayFn: (row, col, field) => formatSeconds(field),
}, {
  displayName: strings.ward_log_type,
  field: 'type',
}, {
  displayName: strings.log_detail,
  field: 'detail',
  displayFn: (row) => {
    switch (row.type) {
      case 'kills': {
        const hero = heroNames[row.detail] || {};
        return <img src={`${process.env.REACT_APP_API_HOST}${hero.img}`} style={{ height: '30px' }} alt="" />;
      }
      case 'runes': {
        const runeType = row.detail;
        const runeString = strings[`rune_${runeType}`];
        return (
          <img
            src={`/assets/images/dota2/runes/${runeType}.png`}
            alt=""
            style={{ height: '30px' }}
            data-tip
            data-for={runeString}
          />
        );
      }
      case 'objectives': {
        if (row.detail === ' First Blood') {
          return (
            <span>
              <img
                src="/assets/images/dota2/bloodsplattersmall.png"
                alt=""
                style={logDetailIconStyle}
              />
              <p>{strings.th_firstblood_claimed}</p>
            </span>
          );
        }
        if (tb.radiant[row.key]) {
          return (
            <span>
              <IconRadiant
                style={logDetailIconStyle}
              />
              <p>{tb.radiant[row.key]} {row.isRadiant ? `(${strings.building_denied})` : ''}</p>
            </span>
          );
        }
        if (tb.dire[row.key]) {
          return (
            <span>
              <IconDire
                style={logDetailIconStyle}
              />
              <p>{tb.dire[row.key]} {!row.isRadiant ? `(${strings.building_denied})` : ''}</p>
            </span>
          );
        }
        if (row.detail === ' Picked up the Aegis') {
          return (
            <span>
              <img
                src="/assets/images/dota2/aegis_icon.png"
                alt=""
                style={logDetailIconStyle}
              />
              <p>{strings.CHAT_MESSAGE_AEGIS}</p>
            </span>
          );
        }
        if (row.detail === ' Roshan') {
          return (
            <span>
              <img
                src="/assets/images/dota2/deadroshan.png"
                alt=""
                style={logDetailIconStyle}
              />
              <p>{strings.th_roshan}</p>
            </span>
          );
        }
        return row.detail;
      }
{'fraction_non_alphanumeric': 0.16721883173496077, 'fraction_numerical': 0.005056669572798605, 'mean_word_length': 1.9047860217776653, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 93, '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': '1988138', 'n_tokens_mistral': 3662, 'n_tokens_neox': 3632, 'n_words': 666}