func (s *Spinner) UpdateCharSet(cs []string) {
	s.lock.Lock()
	defer s.lock.Unlock()
	s.chars = cs
}
UpdateCharSet will change the current character set to the given one
package spinner
import (
	"errors"
	"fmt"
	"io"
	"strconv"
	"sync"
	"time"
	"unicode/utf8"
	"github.com/fatih/color"
)
var errInvalidColor = errors.New("invalid color")
var validColors = map[string]bool{
	"red":     true,
	"green":   true,
	"yellow":  true,
	"blue":    true,
	"magenta": true,
	"cyan":    true,
	"white":   true,
}
var colorAttributeMap = map[string]color.Attribute{
	"red":     color.FgRed,
	"green":   color.FgGreen,
	"yellow":  color.FgYellow,
	"blue":    color.FgBlue,
	"magenta": color.FgMagenta,
	"cyan":    color.FgCyan,
	"white":   color.FgWhite,
}
func validColor(c string) bool {
	valid := false
	if validColors[c] {
		valid = true
	}
	return valid
}
type Spinner struct {
	Delay      time.Duration                  
	chars      []string                       
	Prefix     string                         
	Suffix     string                         
	FinalMSG   string                         
	lastOutput string                         
	color      func(a ...interface{}) string  
	lock       *sync.RWMutex                  
	Writer     io.Writer                      
	active     bool                           
	stopChan   chan struct{}                  
}
func New(cs []string, d time.Duration) *Spinner {
	return &Spinner{
		Delay:    d,
		chars:    cs,
		color:    color.New(color.FgWhite).SprintFunc(),
		lock:     &sync.RWMutex{},
		Writer:   color.Output,
		active:   false,
		stopChan: make(chan struct{}, 1),
	}
}
func (s *Spinner) Start() {
	if s.active {
		return
	}
	s.active = true
	go func() {
		for {
			for i := 0; i < len(s.chars); i++ {
				select {
				case <-s.stopChan:
					return
				default:
					s.lock.Lock()
					s.erase()
					outColor := fmt.Sprintf("%s%s%s ", s.Prefix, s.color(s.chars[i]), s.Suffix)
					outPlain := fmt.Sprintf("%s%s%s ", s.Prefix, s.chars[i], s.Suffix)
					fmt.Fprint(s.Writer, outColor)
					s.lastOutput = outPlain
					delay := s.Delay
					s.lock.Unlock()
					time.Sleep(delay)
				}
			}
		}
	}()
}
func (s *Spinner) Stop() {
	s.lock.Lock()
	defer s.lock.Unlock()
	if s.active {
		s.active = false
		s.erase()
		if s.FinalMSG != "" {
			fmt.Fprintf(s.Writer, s.FinalMSG)
		}
		s.stopChan <- struct{}{}
	}
}
func (s *Spinner) Restart() {
	s.Stop()
	s.Start()
}
func (s *Spinner) Reverse() {
	s.lock.Lock()
	defer s.lock.Unlock()
	for i, j := 0, len(s.chars)-1; i < j; i, j = i+1, j-1 {
		s.chars[i], s.chars[j] = s.chars[j], s.chars[i]
	}
}
func (s *Spinner) Color(c string) error {
	if !validColor(c) {
		return errInvalidColor
	}
	s.color = color.New(colorAttributeMap[c]).SprintFunc()
	s.Restart()
	return nil
}
func (s *Spinner) UpdateSpeed(d time.Duration) {
	s.lock.Lock()
	defer s.lock.Unlock()
	s.Delay = d
}