func (g *GameNode) copy() *GameNode {
	if g == nil {
		return nil
	}
	result := &GameNode{}
	if g.Mids != nil {
		mids := make(map[string]*GameNode, len(g.Mids))
		for key, val := range g.Mids {
			mids[key] = val.copy()
		}
		result.Mids = mids
	}
	if g.Leafs != nil {
		leafs := make([]string, len(g.Leafs))
		for i, leaf := range g.Leafs {
			leafs[i] = leaf
		}
		result.Leafs = leafs
	}
	return result
}
copy returns a fresh, deep copy of gameNode.
package config
import (
	"encoding/json"
	"errors"
	"path/filepath"
	"sort"
	"strings"
)
type GameNode struct {
	Leafs []string
	Mids  map[string]*GameNode
}
func NewGameNode(paths ...string) *GameNode {
	if len(paths) == 0 {
		return nil
	}
	result := newGameNodeItem()
	for _, path := range paths {
		splitPath := strings.Split(path, string(filepath.Separator))
		result.addPath(splitPath)
	}
	result.clipSuperTerminals()
	result.reduceTerminals()
	result = result.elideSimpleMids()
	return result
}
func newGameNodeItem() *GameNode {
	return &GameNode{
		Mids: make(map[string]*GameNode),
	}
}
func (g *GameNode) addPath(path []string) {
	if len(path) == 0 {
		return
	}
	item := g.Mids[path[0]]
	if item == nil {
		item = newGameNodeItem()
		g.Mids[path[0]] = item
	}
	if len(path) == 1 {
		item.Mids[""] = newGameNodeItem()
		return
	}
	item.addPath(path[1:])
}
func (g *GameNode) clipSuperTerminals() {
	if len(g.Mids) == 1 && g.Mids[""] != nil {
		child := g.Mids[""]
		if len(child.Leafs) == 0 && len(child.Mids) == 0 {
			g.Leafs = []string{""}
			g.Mids = nil
			return
		}
	}
	for _, mid := range g.Mids {
		mid.clipSuperTerminals()
	}
	return
}
func (g *GameNode) reduceTerminals() {
	if len(g.Mids) == 0 {
		g.Leafs = []string{""}
		g.Mids = nil
		return
	}
	nonLeafFound := false
	for _, node := range g.Mids {
		if len(node.Mids) != 0 {
			nonLeafFound = true
		}
	}
	if !nonLeafFound {
		var leafs []string
		for key := range g.Mids {
			leafs = append(leafs, key)
		}
		g.Leafs = leafs
		sort.Strings(g.Leafs)
		g.Mids = nil
		return
	}
	for _, node := range g.Mids {
		node.reduceTerminals()
	}
}
func (g *GameNode) addPrefix(prefix string) {
	if len(g.Mids) > 0 {
		newMids := make(map[string]*GameNode, len(g.Mids))
		for key, node := range g.Mids {
			newMids[filepath.Join(prefix, key)] = node
		}
		g.Mids = newMids
	}
	if len(g.Leafs) > 0 {
		newLeafs := make([]string, len(g.Leafs))
		for i, leaf := range g.Leafs {
			newLeafs[i] = filepath.Join(prefix, leaf)
		}
		g.Leafs = newLeafs
	}
}
func (g *GameNode) elideSimpleMids() *GameNode {
	var childKey string
	var child *GameNode
	newMids := make(map[string]*GameNode)
	for key, node := range g.Mids {
		childKey = key
		child = node.elideSimpleMids()
		if len(child.Mids) == 1 {
			var childSingleKey string
			var childSingleChild *GameNode
			for subKey, subNode := range child.Mids {
				childSingleKey = subKey
				childSingleChild = subNode
			}
			childKey = filepath.Join(childKey, childSingleKey)
			child = childSingleChild
		}
		newMids[childKey] = child
	}
	if len(newMids) > 0 {
		g.Mids = newMids
	}
	if len(g.Mids) != 1 {
		return g
	}
	if len(child.Leafs) > 1 {
		return g
	}
	if len(child.Mids) > 1 {
		return g
	}
	child.addPrefix(childKey)
	return child
}
func (g *GameNode) UnmarshalJSON(raw []byte) error {
	var strs []string
	var mids map[string]*GameNode
	if err := json.Unmarshal(raw, &strs); err == nil {
		g.Leafs = strs
		return nil
	}
	if err := json.Unmarshal(raw, &mids); err == nil {
		g.Mids = mids
		return nil
	}
	return errors.New("Node didn't appear to be either Mids or Leafs")
}
func (g *GameNode) List() []string {
	if g == nil {
		return nil
	}
	return alphabetizeUnique(g.listRecursive(""))
}
func alphabetizeUnique(in []string) []string {
	if in == nil {
		return nil
	}
	set := make(map[string]bool, len(in))
	for _, str := range in {
		set[str] = true
	}
	result := make([]string, len(set))
	i := 0
	for str := range set {
		result[i] = str
		i++
	}
	sort.Strings(result)
	return result
}
func (g *GameNode) listRecursive(prior string) []string {
	if g == nil {
		return nil
	}
	var result []string
	if len(g.Leafs) > 0 {
		for _, leaf := range g.Leafs {
			result = append(result, filepath.Join(prior, leaf))
		}
	}
	for name, node := range g.Mids {
		result = append(result, node.listRecursive(filepath.Join(prior, name))...)
	}
	return result
}
func (g *GameNode) MarshalJSON() ([]byte, error) {
	if g.Leafs != nil {
		return json.Marshal(g.Leafs)
	}
	if g.Mids != nil {
		return json.Marshal(g.Mids)
	}
	return nil, nil
}