docs: function rangeFromDetail(set) {
    const pairs = new Map()
    const suiteds = new Map()
    const offsuits = new Map()
  
    function updateMap(map, key, val) {
      if (!map.has(key)) map.set(key, new Set())
      map.get(key).add(val)
    }
  
    for (const cards of set) {
      var [ r1, s1, r2, s2 ] = cards
      if (r1 === r2) {
        updateMap(pairs, r1 + r2, cards)
        continue
      }
  
      if (ranks.indexOf(r1) > ranks.indexOf(r2)) {
        const tmp = r1; r1 = r2; r2 = tmp
      }
      if (s1 === s2) {
        updateMap(suiteds, r1 + r2 + 's', cards)
        continue
      }
      updateMap(offsuits, r1 + r2 + 'o', cards)
    }
  
    const complete = new Set()
    const incomplete = new Set()
    const all = new Set()
    for (const [ k, v ] of pairs) {
      if (v.size < 6) incomplete.add(k); else complete.add(k)
      all.add(k)
    }
    for (const [ k, v ] of suiteds) {
      if (v.size < 4) incomplete.add(k); else complete.add(k)
      all.add(k)
    }
    for (const [ k, v ] of offsuits) {
      if (v.size < 12) incomplete.add(k); else complete.add(k)
      all.add(k)
    }
  
    return { pairs, suiteds, offsuits, complete, incomplete, all }
  }