<commit_before>validObject  = require "../../object/validate.coffee"
uniqueValues = require "../../util/uniques.coffee"

#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Finds a given variable by searching through the data and attrs
#------------------------------------------------------------------------------
fetch = (vars, node, variable, depth) ->

  return null unless variable
  return variable node, vars if typeof variable is "function"
  return variable if typeof variable is "number"

  depth      = vars.id.value unless depth
  nodeObject = validObject node

  # Filters a given array of data based on the current node ID.
  filterArray = (arr) ->
    if node instanceof Array
      arr.filter (d) -> node.indexOf(d[depth]) >= 0
    else
      arr.filter (d) -> d[depth] is node

  # Checks inside the "node" variable if it is an object. If the variable is not
  # avaiable inside of the object, "node" gets reset to it's ID value to help
  # searching through the data and attributes lists.
  if nodeObject

    if variable of node
      return node[variable]

    # Checks if the variable has already been fetched.
    if "d3plus" of node and "data" of node.d3plus and variable of node.d3plus.data
      return node.d3plus.data[variable]

    node = node[depth]

  node = uniqueValues(node, depth) if node instanceof Array

  # Checks for unique values inside of the "node" variable if it is an Array and
  # the first item inside of the object is a keyed Object.
  if node instanceof Array and validObject node[0]
    val = uniqueValues node, variable
    return val if val.length

  # Checks inside of the visualization data array, if available, for the needed
  # variable (given the node ID).
  if vars.data.viz instanceof Array
    val = uniqueValues filterArray(vars.data.viz), variable
    return val if val.length

  # Checks inside of the attribute list, if available.
  if "attrs" of vars and vars.attrs.value

    if validObject(vars.attrs.value) and depth of vars.attrs.value
      attrList = vars.attrs.value[depth]
    else
      attrList = vars.attrs.value

    if attrList instanceof Array
      val = uniqueValues filterArray(attrList), variable
      return val if val.length
    else if node instanceof Array
      attrList = [attrList[n] for n in node if n of attrList]
      if attrList.length
        vals = uniqueValues(attrList, variable)
        return vals if vals.length
    else if node of attrList
      return attrList[node][variable]

  null

module.exports = (vars, node, variable, depth) ->

  nodeObject = validObject node

  if nodeObject and node.values instanceof Array
    for item in node.values
      val = fetch vars, item, variable, depth
      break if val
  else
    val = fetch vars, node, variable, depth

  if (nodeObject and typeof variable is "string" and
      variable not of node and "d3plus" of node)
    node.d3plus.data = {} unless "data" of node.d3plus
    node.d3plus.data[variable] = val

  if val instanceof Array and val.length is 1 then val[0] else val<commit_msg>sped up value fetching even more<commit_after>validObject  = require "../../object/validate.coffee"
uniqueValues = require "../../util/uniques.coffee"

#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Finds a given variable by searching through the data and attrs
#------------------------------------------------------------------------------
fetch = (vars, node, variable, depth) ->

  return null unless variable
  return variable node, vars if typeof variable is "function"
  return variable if typeof variable is "number"

  depth      = vars.id.value unless depth
  nodeObject = validObject node

  # Checks inside the "node" variable if it is an object. If the variable is not
  # avaiable inside of the object, "node" gets reset to it's ID value to help
  # searching through the data and attributes lists.
  if nodeObject

    if variable of node
      return node[variable]

    # Checks if the variable has already been fetched.
    if "d3plus" of node and
       "data" of node.d3plus and
       variable of node.d3plus.data
      return node.d3plus.data[variable]

    node = node[depth]

  node = uniqueValues(node, depth) if node instanceof Array

  # Checks for unique values inside of the "node" variable if it is an Array and
  # the first item inside of the object is a keyed Object.
  if node instanceof Array and validObject node[0]
    val = uniqueValues node, variable
    return val if val.length

  # Checks inside of the visualization data array, if available, for the needed
  # variable (given the node ID).
  if vars.data.viz instanceof Array
    val = uniqueValues filterArray(vars.data.viz, node, depth), variable
    return val if val.length

  # Checks inside of the attribute list, if available
  if "attrs" of vars and vars.attrs.value

    if validObject(vars.attrs.value) and depth of vars.attrs.value
      attrList = vars.attrs.value[depth]
    else
      attrList = vars.attrs.value

    if attrList instanceof Array
      val = uniqueValues filterArray(attrList, node, depth), variable
      return val if val.length
    else if node instanceof Array
      attrList = [attrList[n] for n in node if n of attrList]
      if attrList.length
        vals = uniqueValues(attrList, variable)
        return vals if vals.length
    else if node of attrList
      return attrList[node][variable]

  null

# Filters a given array of data based on the current node ID.
filterArray = (arr, node, depth) ->
  if node instanceof Array
    arr.filter (d) -> node.indexOf(d[depth]) >= 0
  else
    arr.filter (d) -> d[depth] is node

module.exports = (vars, node, variable, depth) ->

  nodeObject = validObject node

  if nodeObject and node.values instanceof Array
    for item in node.values
      val = fetch vars, item, variable, depth
      break if val
  else
    val = fetch vars, node, variable, depth

  if nodeObject and typeof variable is "string" and variable not of node
    node.d3plus = {} unless "d3plus" of node
    node.d3plus.data = {} unless "data" of node.d3plus
    node.d3plus.data[variable] = val

  if val instanceof Array and val.length is 1 then val[0] else val
{'fraction_non_alphanumeric': 0.119755666291593, 'fraction_numerical': 0.0040186465198521135, 'mean_word_length': 2.8621973929236497, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, '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': '636526', 'n_tokens_mistral': 1740, 'n_tokens_neox': 1694, 'n_words': 731}