<commit_before>declare var google: any;

import { Injectable, EventEmitter, LOCALE_ID, Inject, Optional } from '@angular/core';
import { GoogleChartsSettings } from './google-charts-interfaces';

interface InternalGoogleChartsSettings extends GoogleChartsSettings {
  callback?(): any;
}

@Injectable({
  providedIn: 'root'
})
export class GoogleChartsLoaderService {

  private googleScriptLoadingNotifier: EventEmitter<boolean>;
  private googleChartLoadingNotifier: EventEmitter<void>;
  private googleScriptIsLoading: boolean;
  private googleChartIsLoading: boolean;
  private localeId: string;
  private loadGoogleChartsScriptPromise: Promise<void>;
  private loadedPackages: string[] = [];
  private loaded = false;

  public constructor(
    @Inject(LOCALE_ID) localeId: string,
    @Inject('googleChartsSettings') @Optional() private googleChartsSettings?: GoogleChartsSettings,
  ) {
    this.googleScriptLoadingNotifier = new EventEmitter();
    this.googleChartLoadingNotifier = new EventEmitter();
    this.googleScriptIsLoading = false;
    this.googleChartIsLoading = false;
    this.localeId = localeId;

    this.loadGoogleChartsScriptPromise = new Promise((resolve, reject) => {
      if (typeof google !== 'undefined' && google.charts) {
        resolve();
      } else if (!this.googleScriptIsLoading) {

        this.googleScriptIsLoading = true;

        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = 'https://www.gstatic.com/charts/loader.js';
        script.async = true;
        script.defer = true;
        script.onload = () => {
          this.googleScriptIsLoading = false;
          this.googleScriptLoadingNotifier.emit(true);
          resolve();
        };
        script.onerror = () => {
          this.googleScriptIsLoading = false;
          this.googleScriptLoadingNotifier.emit(false);
          reject();
        };
        document.getElementsByTagName('head')[0].appendChild(script);

      } else {
        this.googleScriptLoadingNotifier.subscribe((loaded: boolean) => {
          if (loaded) {
            resolve();
          } else {
            reject();
          }
        });
      }
    });
  }

  public async load(settings?: GoogleChartsSettings): Promise<void> {
    await this.loadGoogleChartsScriptPromise;

    await new Promise((resolve) => {

      if (this.googleChartIsLoading) {
        this.googleChartLoadingNotifier.subscribe(() => {
          this.doLoad(resolve, settings);
        });

        return;
      }

      this.doLoad(resolve, settings);

    });
  }

  private doLoad(resolve: (value?: unknown) => void, settings?: GoogleChartsSettings) {
    if (!settings) {
      settings = Object.create(this.googleChartsSettings);
    }
    if (!settings) {
      settings = {};
    }

    if (!settings.language) {
      settings.language = this.localeId;
    }

    if (!settings.googleChartsVersion) {
      settings.googleChartsVersion = '47';
    }

    if (!settings.packages && this.loaded) {
      resolve();
      return;
    }

    if (settings.packages) {
      let pkgs = settings.packages.filter(p => this.loadedPackages.indexOf(p) < 0);

      if (pkgs.length == 0 && this.loaded) {
        resolve();
        return;
      }<commit_msg>loader service: fix custom GoogleChartsSettings<commit_after>declare var google: any;

import { Injectable, EventEmitter, LOCALE_ID, Inject, Optional } from '@angular/core';
import { GoogleChartsSettings } from './google-charts-interfaces';

interface InternalGoogleChartsSettings extends GoogleChartsSettings {
  callback?(): any;
}

@Injectable({
  providedIn: 'root'
})
export class GoogleChartsLoaderService {

  private googleScriptLoadingNotifier: EventEmitter<boolean>;
  private googleChartLoadingNotifier: EventEmitter<void>;
  private googleScriptIsLoading: boolean;
  private googleChartIsLoading: boolean;
  private loadGoogleChartsScriptPromise: Promise<void>;
  private loadedPackages: string[] = [];
  private loaded = false;

  public constructor(
    @Inject(LOCALE_ID) localeId: string,
    @Inject('googleChartsSettings') @Optional() private googleChartsSettings: GoogleChartsSettings,
  ) {
    const defaultSettings: GoogleChartsSettings = {
      googleChartsVersion: '47',
      language: localeId,
    };
    this.googleChartsSettings = {...defaultSettings, ...this.googleChartsSettings};

    this.googleScriptLoadingNotifier = new EventEmitter();
    this.googleChartLoadingNotifier = new EventEmitter();
    this.googleScriptIsLoading = false;
    this.googleChartIsLoading = false;

    this.loadGoogleChartsScriptPromise = new Promise((resolve, reject) => {
      if (typeof google !== 'undefined' && google.charts) {
        resolve();
      } else if (!this.googleScriptIsLoading) {

        this.googleScriptIsLoading = true;

        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = 'https://www.gstatic.com/charts/loader.js';
        script.async = true;
        script.defer = true;
        script.onload = () => {
          this.googleScriptIsLoading = false;
          this.googleScriptLoadingNotifier.emit(true);
          resolve();
        };
        script.onerror = () => {
          this.googleScriptIsLoading = false;
          this.googleScriptLoadingNotifier.emit(false);
          reject();
        };
        document.getElementsByTagName('head')[0].appendChild(script);

      } else {
        this.googleScriptLoadingNotifier.subscribe((loaded: boolean) => {
          if (loaded) {
            resolve();
          } else {
            reject();
          }
        });
      }
    });
  }

  public async load(settings?: GoogleChartsSettings): Promise<void> {
    await this.loadGoogleChartsScriptPromise;

    await new Promise((resolve) => {

      if (this.googleChartIsLoading) {
        this.googleChartLoadingNotifier.subscribe(() => {
          this.doLoad(resolve, settings);
        });

        return;
      }

      this.doLoad(resolve, settings);

    });
  }

  private doLoad(resolve: (value?: unknown) => void, settings?: GoogleChartsSettings) {
    settings = {...this.googleChartsSettings, ...settings}

    if (!settings.packages && this.loaded) {
      resolve();
      return;
    }

    if (settings.packages) {
      let pkgs = settings.packages.filter(p => this.loadedPackages.indexOf(p) < 0);

      if (pkgs.length == 0 && this.loaded) {
        resolve();
        return;
      }
{'fraction_non_alphanumeric': 0.12035044574239163, 'fraction_numerical': 0.001537042729787888, 'mean_word_length': 2.9364791288566243, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 27, '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': '6100698', 'n_tokens_mistral': 1810, 'n_tokens_neox': 1775, 'n_words': 351}