<commit_before>import forEach from 'lodash/forEach'
import map from 'lodash/map'
import isString from 'lodash/isString'
import DocumentSchema from '../model/DocumentSchema'
import EditingBehavior from '../model/EditingBehavior'
import Registry from '../util/Registry'
import ComponentRegistry from '../ui/ComponentRegistry'
import FontAwesomeIconProvider from '../ui/FontAwesomeIconProvider'
import LabelProvider from '../ui/DefaultLabelProvider'

/**
  Default Configurator for Substance editors. It provides an API for
  adding nodes to the schema, components, commands and tools etc.

  @class

  @example

  ```js
  let configurator = new Configurator()

  configurator.addNode(Heading)
  configurator.addComponent('heading', HeadingComponent)
  ```

  To modularize configuration, package definitions can be imported.

  ```js
  configurator.import(ParagraphPackage)
  ```

  You can create your own extensions that way.

  ```js

  const AlienPackage = {
    name: 'alien'
    configure: function(config) {
      config.addNode(AlienNode)
      config.addComponent('alien', AlienComponent)
      config.addCommand('add-alien', AddAlienCommand)
      config.addTool('add-alien', AddAlienTool)
    }
  }

  ```

  From within a package, another package can be imported. This provides
  a simple mechanism to model dependencies between packages. Just make
  sure you don't run into cyclic dependencies as there is no checking for
  that at the moment.
*/

/** INCLUDE_IN_API_DOCS */
class Configurator {
  constructor() {
    this.config = {
      schema: {},
      nodes: {},
      components: {},
      converters: {},
      importers: {},
      exporters: {},
      commands: {},
      tools: new Map(),
      textTypes: [],
      editingBehaviors: [],
      macros: [],
      dndHandlers: [],
      icons: {},
      labels: {}
    }
  }

  // Record phase API
  // ------------------------

  defineSchema(schema) {
    this.config.schema = schema
  }

  /**
   * @param {String} NodeClass node class name.
   */
  addNode(NodeClass) {
    var type = NodeClass.type
    if (!type) {
      throw new Error('A NodeClass must have a type.')
    }
    if (this.config.nodes[type]) {
      throw new Error('NodeClass with this type name is already registered: ' + name)
    }
    this.config.nodes[type] = NodeClass
  }

  addConverter(type, converter) {
    var converters = this.config.converters[type]
    if (!converters) {
      converters = {}
      this.config.converters[type] = converters
    }
    if (!converter.type) {
      throw new Error('A converter needs an associated type.')
    }
    converters[converter.type] = converter
  }

  addImporter(type, ImporterClass) {<commit_msg>Fix bug in generation of error message<commit_after>import forEach from 'lodash/forEach'
import map from 'lodash/map'
import isString from 'lodash/isString'
import DocumentSchema from '../model/DocumentSchema'
import EditingBehavior from '../model/EditingBehavior'
import Registry from '../util/Registry'
import ComponentRegistry from '../ui/ComponentRegistry'
import FontAwesomeIconProvider from '../ui/FontAwesomeIconProvider'
import LabelProvider from '../ui/DefaultLabelProvider'

/**
  Default Configurator for Substance editors. It provides an API for
  adding nodes to the schema, components, commands and tools etc.

  @class

  @example

  ```js
  let configurator = new Configurator()

  configurator.addNode(Heading)
  configurator.addComponent('heading', HeadingComponent)
  ```

  To modularize configuration, package definitions can be imported.

  ```js
  configurator.import(ParagraphPackage)
  ```

  You can create your own extensions that way.

  ```js

  const AlienPackage = {
    name: 'alien'
    configure: function(config) {
      config.addNode(AlienNode)
      config.addComponent('alien', AlienComponent)
      config.addCommand('add-alien', AddAlienCommand)
      config.addTool('add-alien', AddAlienTool)
    }
  }

  ```

  From within a package, another package can be imported. This provides
  a simple mechanism to model dependencies between packages. Just make
  sure you don't run into cyclic dependencies as there is no checking for
  that at the moment.
*/

/** INCLUDE_IN_API_DOCS */
class Configurator {
  constructor() {
    this.config = {
      schema: {},
      nodes: {},
      components: {},
      converters: {},
      importers: {},
      exporters: {},
      commands: {},
      tools: new Map(),
      textTypes: [],
      editingBehaviors: [],
      macros: [],
      dndHandlers: [],
      icons: {},
      labels: {}
    }
  }

  // Record phase API
  // ------------------------

  defineSchema(schema) {
    this.config.schema = schema
  }

  /**
   * @param {String} NodeClass node class name.
   */
  addNode(NodeClass) {
    var type = NodeClass.type
    if (!type) {
      throw new Error('A NodeClass must have a type.')
    }
    if (this.config.nodes[type]) {
      throw new Error('NodeClass with this type name is already registered: ' + type)
    }
    this.config.nodes[type] = NodeClass
  }

  addConverter(type, converter) {
    var converters = this.config.converters[type]
    if (!converters) {
      converters = {}
      this.config.converters[type] = converters
    }
    if (!converter.type) {
      throw new Error('A converter needs an associated type.')
    }
    converters[converter.type] = converter
  }

  addImporter(type, ImporterClass) {
{'fraction_non_alphanumeric': 0.11990407673860912, 'fraction_numerical': 0.0, 'mean_word_length': 2.966349670811997, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '6919732', 'n_tokens_mistral': 1617, 'n_tokens_neox': 1556, 'n_words': 450}