<commit_before>package swgohgg

import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"sort"
	"strconv"
)

func (c *Client) Roster() (roster Roster, err error) {
	for page := 1; page <= 5; page++ {
		url := fmt.Sprintf("https://swgoh.gg/u/%s/collection/?page=%d", c.profile, page)
		resp, err := c.hc.Get(url)
		if err != nil {
			return nil, err
		}
		defer resp.Body.Close()
		if resp.StatusCode == 404 {
			break
		}
		if resp.StatusCode != 200 {
			return nil, fmt.Errorf("swgohgg: unexpected status code %d", resp.StatusCode)
		}
		doc, err := goquery.NewDocumentFromReader(resp.Body)
		if err != nil {
			return nil, err
		}
		doc.Find(".collection-char-list .collection-char").Each(func(i int, s *goquery.Selection) {
			char := parseChar(s)
			if !roster.Contains(char.Name) {
				roster = append(roster, char)
			}
		})
	}
	sort.Sort(ByStars(roster, false))
	return roster, nil
}

type Roster []*Char

func (r Roster) Contains(char string) bool {
	for i := range r {
		if r[i].Name == char {
			return true
		}
	}
	return false
}

func (r Roster) ContainsAll(chars ...string) bool {
	for _, char := range chars {
		if !r.Contains(char) {
			return false
		}
	}
	return true
}

type Char struct {
	Name  string
	Stars int
	Level int
	Gear  int
}

func (c *Char) String() string {
	if c == nil {
		return "nil"
	}
	return fmt.Sprintf("%s %d* G%d Lvl%d", c.Name, c.Stars, c.Gear, c.Level)
}

func parseChar(s *goquery.Selection) *Char {
	var char Char
	char.Name = s.Find(".collection-char-name-link").Text()<commit_msg>Renamed Roster type to Collection<commit_after>package swgohgg

import (
	"fmt"
	"sort"
	"strconv"

	"github.com/PuerkitoBio/goquery"
)

func (c *Client) Collection() (roster Collection, err error) {
	for page := 1; page <= 5; page++ {
		url := fmt.Sprintf("https://swgoh.gg/u/%s/collection/?page=%d", c.profile, page)
		resp, err := c.hc.Get(url)
		if err != nil {
			return nil, err
		}
		defer resp.Body.Close()
		if resp.StatusCode == 404 {
			break
		}
		if resp.StatusCode != 200 {
			return nil, fmt.Errorf("swgohgg: unexpected status code %d", resp.StatusCode)
		}
		doc, err := goquery.NewDocumentFromReader(resp.Body)
		if err != nil {
			return nil, err
		}
		doc.Find(".collection-char-list .collection-char").Each(func(i int, s *goquery.Selection) {
			char := parseChar(s)
			if !roster.Contains(char.Name) {
				roster = append(roster, char)
			}
		})
	}
	sort.Sort(ByStars(roster, false))
	return roster, nil
}

type Collection []*Char

func (r Collection) Contains(char string) bool {
	for i := range r {
		if r[i].Name == char {
			return true
		}
	}
	return false
}

func (r Collection) ContainsAll(chars ...string) bool {
	for _, char := range chars {
		if !r.Contains(char) {
			return false
		}
	}
	return true
}

type Char struct {
	Name  string
	Stars int
	Level int
	Gear  int
}

func (c *Char) String() string {
	if c == nil {
		return "nil"
	}
	return fmt.Sprintf("%s %d* G%d Lvl%d", c.Name, c.Stars, c.Gear, c.Level)
}

func parseChar(s *goquery.Selection) *Char {
	var char Char
	char.Name = s.Find(".collection-char-name-link").Text()
{'fraction_non_alphanumeric': 0.1561386459345643, 'fraction_numerical': 0.0051830255911888565, 'mean_word_length': 3.2770083102493075, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 2, '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': '4394637', 'n_tokens_mistral': 1286, 'n_tokens_neox': 1183, 'n_words': 307}