text: /**
   * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system.
   * @extends {Actor}
   */
  export class SimpleActor extends Actor {
  
    /** @override */
    getRollData() {
      const data = super.getRollData();
      const shorthand = game.settings.get("eij", "macroShorthand");
      const formulaAttributes = [];
  
      //@TODO: Commented out to allow roll functionality, figure this nonesense out
      //Handle formula attributes when the short syntax is disabled.
      //this._applyShorthand(data, formulaAttributes, shorthand);
  
      // Map all items data using their slugified names
      this._applyItems(data, shorthand);
  
      // Evaluate formula attributes after all other attributes have been handled,
      // including items.
      this._applyFormulaReplacements(data, formulaAttributes, shorthand);
  
      // Remove the attributes if necessary.
      if ( !!shorthand ) {
        delete data.attributes;
        delete data.attr;
        delete data.abil;
      }
  
      return data;
    }
  
    /**
     * @TODO: Commented out to allow roll functionality, figure this nonesense out
     * Apply shorthand syntax to actor roll data.
     * @param {Object} data The actor's data object.
     * @param {Array} formulaAttributes Array of attributes that are derived formulas.
     * @param {Boolean} shorthand Whether or not the shorthand syntax is used.
     */
  /*   _applyShorthand(data, formulaAttributes, shorthand) {
      // Handle formula attributes when the short syntax is disabled.
      for ( let [k, v] of Object.entries(data.attributes) ) {
        // Make an array of formula attributes for later reference.
        if ( v.dtype == "Formula" ) formulaAttributes.push(k);
        // Add shortened version of the attributes.
        if ( !!shorthand ) {
          if ( !(k in data) ) {
            data[k] = v.value;
          }
        }
      }
    } */
  
    /**
     * Add items to the actor roll data object. Handles regular and shorthand
     * syntax, and calculates derived formula attributes on the items.
     * @param {Object} data The actor's data object.
     * @param {Boolean} shorthand Whether or not the shorthand syntax is used.
     */
    _applyItems(data, shorthand) {
      // Map all items data using their slugified names
      data.items = this.data.items.reduce((obj, i) => {
        let key = i.name.slugify({strict: true});
        let itemData = duplicate(i.data);
        const itemAttributes = [];
  
        // Add items to shorthand and note which ones are formula attributes.
        for ( let [k, v] of Object.entries(itemData.attributes) ) {
          if ( v.dtype == "Formula" ) itemAttributes.push(k);
          // Add shortened version of the attributes.
          if ( !!shorthand ) {
            if ( !(k in itemData) ) {
              itemData[k] = v.value;
            }
          }
        }
  
        // Evaluate formula attributes after all other attributes have been handled.
        for ( let k of itemAttributes ) {
          if ( itemData.attributes[k].value ) {
            itemData.attributes[k].value = this._replaceData(itemData.attributes[k].value, itemData);
            itemData.attributes[k].value = this._replaceData(itemData.attributes[k].value, data, {missing: "0"});
            // TODO: Replace with:
            // itemData.attributes[k].value = Roll.replaceFormulaData(itemData.attributes[k].value, itemData);
            // itemData.attributes[k].value = Roll.replaceFormulaData(itemData.attributes[k].value, data, {missing: "0"});
          }
  
          // Duplicate values to shorthand.
          if ( !!shorthand ) {
            itemData[k] = itemData.attributes[k].value;
          }
        }
  
        // Delete the original attributes key if using the shorthand syntax.
        if ( !!shorthand ) {
          delete itemData.attributes;
        }
  
        obj[key] = itemData;
        return obj;
      }, {});
    }
  
    /**
     * Apply replacements for derived formula attributes.
     * @param {Object} data The actor's data object.
     * @param {Array} formulaAttributes Array of attributes that are derived formulas.
     * @param {Boolean} shorthand Whether or not the shorthand syntax is used.
     */
    _applyFormulaReplacements(data, formulaAttributes, shorthand) {
      // Evaluate formula attributes after all other attributes have been handled,
      // including items.
      for ( let k of formulaAttributes ) {
        if ( data.attributes[k].value ) {
          data.attributes[k].value = this._replaceData(data.attributes[k].value, data, {missing: "0"});
          // TODO: Replace with:
          // data.attributes[k].value = Roll.replaceFormulaData(data.attributes[k].value, data, {missing: "0"});
        }
  
        // Duplicate values to shorthand.
        if ( !!shorthand ) {
          data[k] = data.attributes[k].value;
        }
      }
    }
  
    /**
     * Replace referenced data attributes in the roll formula with the syntax `@attr` with the corresponding key from
     * the provided `data` object. This is a temporary helper function that will be replaced with Roll.replaceFormulaData()
     * in Foundry 0.7.1.
     *
     * @param {String} formula    The original formula within which to replace.
     * @param {Object} data       Data object to use for value replacements.
     * @param {Object} missing    Value to use as missing replacements, such as {missing: "0"}.
     * @return {String} The formula with attributes replaced with values.
     */
    _replaceData(formula, data, {missing=null}={}) {
      // Exit early if the formula is invalid.
      if ( typeof formula != "string" ) {
        return 0;
      }
  
      // Replace attributes with their numeric equivalents.
      let dataRgx = new RegExp(/@([a-z.0-9_\-]+)/gi);
      let rollFormula = formula.replace(dataRgx, (match, term) => {
        // Replace matches with the value, or the missing value.
        let value = getProperty(data, term);
        return value ? String(value).trim() : (missing != null ? missing : `@${term}`);
      });
  
      return rollFormula;
    }
  }
  