text: export const GENERIC_NAV = 'default'
  export const UI_ORDER = 'ui:order'
  export const UI_NAV_ID = 'nav'
  
  export function findFieldNavs(field, uiSchema) {
    const navs =
      uiSchema[field] && uiSchema[field][UI_NAV_ID]
        ? uiSchema[field][UI_NAV_ID]
        : []
    return toArray(navs)
  }
  
  export function getNavAliases({ navConf: { aliases = {} } = {} }) {
    return aliases
  }
  
  export function isDevelopment() {
    return process.env.NODE_ENV !== 'production'
  }
  
  export const toError = message => {
    if (isDevelopment()) {
      throw new ReferenceError(message)
    } else {
      console.error(message)
    }
  }
  
  export function toArray(val) {
    if (Array.isArray(val)) {
      return val
    } else {
      return [val]
    }
  }
  
  export function isEmptySchema(schema) {
    return (
      !schema || !schema.properties || Object.keys(schema.properties).length === 0
    )
  }
  
  function isArguments(object) {
    return Object.prototype.toString.call(object) === '[object Arguments]'
  }
  
  export function deepEquals(a, b, ca = [], cb = []) {
    // Partially extracted from node-deeper and adapted to exclude comparison
    // checks for functions.
    // https://github.com/othiym23/node-deeper
    if (a === b) {
      return true
    } else if (typeof a === 'function' || typeof b === 'function') {
      // Assume all functions are equivalent
      // see https://github.com/mozilla-services/react-jsonschema-form/issues/255
      return true
    } else if (typeof a !== 'object' || typeof b !== 'object') {
      return false
    } else if (a === null || b === null) {
      return false
    } else if (a instanceof Date && b instanceof Date) {
      return a.getTime() === b.getTime()
    } else if (a instanceof RegExp && b instanceof RegExp) {
      return (
        a.source === b.source &&
        a.global === b.global &&
        a.multiline === b.multiline &&
        a.lastIndex === b.lastIndex &&
        a.ignoreCase === b.ignoreCase
      )
    } else if (isArguments(a) || isArguments(b)) {
      if (!(isArguments(a) && isArguments(b))) {
        return false
      }
      const slice = Array.prototype.slice
      return deepEquals(slice.call(a), slice.call(b), ca, cb)
    } else {
      if (a.constructor !== b.constructor) {
        return false
      }
  
      const ka = Object.keys(a)
      const kb = Object.keys(b)
      // don't bother with stack acrobatics if there's nothing there
      if (ka.length === 0 && kb.length === 0) {
        return true
      }
      if (ka.length !== kb.length) {
        return false
      }
  
      let cal = ca.length
      while (cal--) {
        if (ca[cal] === a) {
          return cb[cal] === b
        }
      }
      ca.push(a)
      cb.push(b)
  
      ka.sort()
      kb.sort()
      for (let j = ka.length - 1; j >= 0; j--) {
        if (ka[j] !== kb[j]) {
          return false
        }
      }
  
      let key
      for (let k = ka.length - 1; k >= 0; k--) {
        key = ka[k]
        if (!deepEquals(a[key], b[key], ca, cb)) {
          return false
        }
      }
  
      ca.pop()
      cb.pop()
  
      return true
    }
  }
  