<commit_before>import type Highcharts from 'highcharts';

import AnalyseCtrl from './ctrl';
import { baseUrl } from './util';
import modal from 'common/modal';
import { textRaw as xhrTextRaw } from 'common/xhr';
import { AnalyseData } from './interfaces';

interface HighchartsHTMLElement extends HTMLElement {
  highcharts: Highcharts.ChartObject;
}

interface PlyChart extends Highcharts.ChartObject {
  lastPly?: Ply | false;
  selectPly(ply: number): void;
}

export default function (element: HTMLElement, ctrl: AnalyseCtrl) {
  $(element).replaceWith(ctrl.opts.$underboard!);

  $('#adv-chart').attr('id', 'acpl-chart');

  const data = ctrl.data,
    $panels = $('.analyse__underboard__panels > div'),
    $menu = $('.analyse__underboard__menu'),
    $timeChart = $('#movetimes-chart'),
    inputFen = document.querySelector('.analyse__underboard__fen') as HTMLInputElement,
    unselect = (chart: Highcharts.ChartObject) => chart.getSelectedPoints().forEach(point => point.select(false));
  let lastFen: string;

  if (!lichess.AnalyseNVUI) {
    lichess.pubsub.on('analysis.comp.toggle', (v: boolean) => {
      setTimeout(function () {
        (v ? $menu.find('[data-panel="computer-analysis"]') : $menu.find('span:eq(1)')).trigger('mousedown');
      }, 50);
      if (v) $('#acpl-chart').each((_, e) => (e as HighchartsHTMLElement).highcharts.reflow());
    });
    lichess.pubsub.on('analysis.change', (fen: Fen, _, mainlinePly: Ply | false) => {
      const $chart = $('#acpl-chart');
      if (fen && fen !== lastFen) {
        inputFen.value = fen;
        lastFen = fen;
      }
      if ($chart.length) {
        const chart = ($chart[0] as HighchartsHTMLElement).highcharts as PlyChart;
        if (chart) {
          if (mainlinePly != chart.lastPly) {
            if (mainlinePly === false) unselect(chart);
            else chart.selectPly(mainlinePly);
          }
          chart.lastPly = mainlinePly;
        }
      }
      if ($timeChart.length) {
        const chart = ($timeChart[0] as HighchartsHTMLElement).highcharts as PlyChart;
        if (chart) {
          if (mainlinePly != chart.lastPly) {
            if (mainlinePly === false) unselect(chart);
            else chart.selectPly(mainlinePly);
          }
          chart.lastPly = mainlinePly;
        }
      }
    });
    lichess.pubsub.on('analysis.server.progress', (d: AnalyseData) => {
      if (!lichess.advantageChart) startAdvantageChart();
      else if (lichess.advantageChart.update) lichess.advantageChart.update(d);
      if (d.analysis && !d.analysis.partial) $('#acpl-chart-loader').remove();
    });
  }

  function chartLoader() {
    return `<div id="acpl-chart-loader"><span>Stockfish 14+<br>server analysis</span>${lichess.spinnerHtml}</div>`;
  }
  function startAdvantageChart() {
    if (lichess.advantageChart || lichess.AnalyseNVUI) return;
    const loading = !data.treeParts[0].eval || !Object.keys(data.treeParts[0].eval).length;
    const $panel = $panels.filter('.computer-analysis');
    if (!$('#acpl-chart').length) $panel.html('<div id="acpl-chart"></div>' + (loading ? chartLoader() : ''));
    else if (loading && !$('#acpl-chart-loader').length) $panel.append(chartLoader());
    lichess.loadScript('javascripts/chart/acpl.js').then(function () {
      lichess.advantageChart!(data, ctrl.trans, $('#acpl-chart')[0] as HTMLElement);
    });
  }

  const storage = lichess.storage.make('analysis.panel');
  const setPanel = function (panel: string) {
    $menu.children('.active').removeClass('active');
    $menu.find(`[data-panel="${panel}"]`).addClass('active');
    $panels
      .removeClass('active')
      .filter('.' + panel)
      .addClass('active');
    if ((panel == 'move-times' || ctrl.opts.hunter) && !lichess.movetimeChart)
      lichess
        .loadScript('javascripts/chart/movetime.js')
        .then(() => lichess.movetimeChart(data, ctrl.trans, ctrl.opts.hunter));
    if ((panel == 'computer-analysis' || ctrl.opts.hunter) && $('#acpl-chart').length)
      setTimeout(startAdvantageChart, 200);
  };
  $menu.on('mousedown', 'span', function (this: HTMLElement) {
    const panel = $(this).data('panel');
    storage.set(panel);
    setPanel(panel);
  });
  const stored = storage.get();
  const foundStored =
    stored &&
    $menu.children(`[data-panel="${stored}"]`).filter(function (this: HTMLElement) {
      const display = window.getComputedStyle(this).display;
      return !!display && display != 'none';
    }).length;
  if (foundStored) setPanel(stored!);
  else {
    const $menuCt = $menu.children('[data-panel="ctable"]');
    ($menuCt.length ? $menuCt : $menu.children(':first-child')).trigger('mousedown');
  }
  if (!data.analysis) {
    $panels.find('form.future-game-analysis').on('submit', function (this: HTMLFormElement) {
      if ($(this).hasClass('must-login')) {
        if (confirm(ctrl.trans('youNeedAnAccountToDoThat'))) location.href = '/signup';
        return false;
      }
      xhrTextRaw(this.action, { method: this.method }).then(res => {
        if (res.ok) startAdvantageChart();
        else
          res.text().then(t => {
            alert(t);
            lichess.reload();
          });
      });
      return false;
    });
  }

  $panels.on('click', '.pgn', function (this: HTMLElement) {<commit_msg>Don't alert HTML error pages<commit_after>import type Highcharts from 'highcharts';

import AnalyseCtrl from './ctrl';
import { baseUrl } from './util';
import modal from 'common/modal';
import { textRaw as xhrTextRaw } from 'common/xhr';
import { AnalyseData } from './interfaces';

interface HighchartsHTMLElement extends HTMLElement {
  highcharts: Highcharts.ChartObject;
}

interface PlyChart extends Highcharts.ChartObject {
  lastPly?: Ply | false;
  selectPly(ply: number): void;
}

export default function (element: HTMLElement, ctrl: AnalyseCtrl) {
  $(element).replaceWith(ctrl.opts.$underboard!);

  $('#adv-chart').attr('id', 'acpl-chart');

  const data = ctrl.data,
    $panels = $('.analyse__underboard__panels > div'),
    $menu = $('.analyse__underboard__menu'),
    $timeChart = $('#movetimes-chart'),
    inputFen = document.querySelector('.analyse__underboard__fen') as HTMLInputElement,
    unselect = (chart: Highcharts.ChartObject) => chart.getSelectedPoints().forEach(point => point.select(false));
  let lastFen: string;

  if (!lichess.AnalyseNVUI) {
    lichess.pubsub.on('analysis.comp.toggle', (v: boolean) => {
      setTimeout(function () {
        (v ? $menu.find('[data-panel="computer-analysis"]') : $menu.find('span:eq(1)')).trigger('mousedown');
      }, 50);
      if (v) $('#acpl-chart').each((_, e) => (e as HighchartsHTMLElement).highcharts.reflow());
    });
    lichess.pubsub.on('analysis.change', (fen: Fen, _, mainlinePly: Ply | false) => {
      const $chart = $('#acpl-chart');
      if (fen && fen !== lastFen) {
        inputFen.value = fen;
        lastFen = fen;
      }
      if ($chart.length) {
        const chart = ($chart[0] as HighchartsHTMLElement).highcharts as PlyChart;
        if (chart) {
          if (mainlinePly != chart.lastPly) {
            if (mainlinePly === false) unselect(chart);
            else chart.selectPly(mainlinePly);
          }
          chart.lastPly = mainlinePly;
        }
      }
      if ($timeChart.length) {
        const chart = ($timeChart[0] as HighchartsHTMLElement).highcharts as PlyChart;
        if (chart) {
          if (mainlinePly != chart.lastPly) {
            if (mainlinePly === false) unselect(chart);
            else chart.selectPly(mainlinePly);
          }
          chart.lastPly = mainlinePly;
        }
      }
    });
    lichess.pubsub.on('analysis.server.progress', (d: AnalyseData) => {
      if (!lichess.advantageChart) startAdvantageChart();
      else if (lichess.advantageChart.update) lichess.advantageChart.update(d);
      if (d.analysis && !d.analysis.partial) $('#acpl-chart-loader').remove();
    });
  }

  function chartLoader() {
    return `<div id="acpl-chart-loader"><span>Stockfish 14+<br>server analysis</span>${lichess.spinnerHtml}</div>`;
  }
  function startAdvantageChart() {
    if (lichess.advantageChart || lichess.AnalyseNVUI) return;
    const loading = !data.treeParts[0].eval || !Object.keys(data.treeParts[0].eval).length;
    const $panel = $panels.filter('.computer-analysis');
    if (!$('#acpl-chart').length) $panel.html('<div id="acpl-chart"></div>' + (loading ? chartLoader() : ''));
    else if (loading && !$('#acpl-chart-loader').length) $panel.append(chartLoader());
    lichess.loadScript('javascripts/chart/acpl.js').then(function () {
      lichess.advantageChart!(data, ctrl.trans, $('#acpl-chart')[0] as HTMLElement);
    });
  }

  const storage = lichess.storage.make('analysis.panel');
  const setPanel = function (panel: string) {
    $menu.children('.active').removeClass('active');
    $menu.find(`[data-panel="${panel}"]`).addClass('active');
    $panels
      .removeClass('active')
      .filter('.' + panel)
      .addClass('active');
    if ((panel == 'move-times' || ctrl.opts.hunter) && !lichess.movetimeChart)
      lichess
        .loadScript('javascripts/chart/movetime.js')
        .then(() => lichess.movetimeChart(data, ctrl.trans, ctrl.opts.hunter));
    if ((panel == 'computer-analysis' || ctrl.opts.hunter) && $('#acpl-chart').length)
      setTimeout(startAdvantageChart, 200);
  };
  $menu.on('mousedown', 'span', function (this: HTMLElement) {
    const panel = $(this).data('panel');
    storage.set(panel);
    setPanel(panel);
  });
  const stored = storage.get();
  const foundStored =
    stored &&
    $menu.children(`[data-panel="${stored}"]`).filter(function (this: HTMLElement) {
      const display = window.getComputedStyle(this).display;
      return !!display && display != 'none';
    }).length;
  if (foundStored) setPanel(stored!);
  else {
    const $menuCt = $menu.children('[data-panel="ctable"]');
    ($menuCt.length ? $menuCt : $menu.children(':first-child')).trigger('mousedown');
  }
  if (!data.analysis) {
    $panels.find('form.future-game-analysis').on('submit', function (this: HTMLFormElement) {
      if ($(this).hasClass('must-login')) {
        if (confirm(ctrl.trans('youNeedAnAccountToDoThat'))) location.href = '/signup';
        return false;
      }
      xhrTextRaw(this.action, { method: this.method }).then(res => {
        if (res.ok) startAdvantageChart();
        else
          res.text().then(t => {
            if (t && !t.startsWith('<!DOCTYPE html>')) alert(t);
            lichess.reload();
          });
      });
      return false;
    });
  }

  $panels.on('click', '.pgn', function (this: HTMLElement) {
{'fraction_non_alphanumeric': 0.17843726521412473, 'fraction_numerical': 0.002441773102930128, 'mean_word_length': 3.3200811359026368, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 38, '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': '1544984', 'n_tokens_mistral': 3490, 'n_tokens_neox': 3415, 'n_words': 620}