docs: function parsecanon(str) {
    var out = {}
  
    if (_.isArray(str)) {
      return {
        zone: str[0],
        base: str[1],
        name: str[2]
      }
    }
  
    if (_.isObject(str) && !_.isFunction(str)) return str
  
    if (!_.isString(str)) return out
  
    var m = /\$?((\w+|-)\/)?((\w+|-)\/)?(\w+|-)/.exec(str)
    if (m) {
      var zi = m[4] == null ? 4 : 2
      var bi = m[4] == null ? 2 : 4
  
      out.zone = m[zi] === '-' ? void 0 : m[zi]
      out.base = m[bi] === '-' ? void 0 : m[bi]
      out.name = m[5] === '-' ? void 0 : m[5]
    } else throw error('invalid_canon', { str: str })
  
    return out
  }