func (lm *ListInfoMap) FlattenAndGenUniqueDomainList() error {
	inclusionLevel := make([]map[fileName]bool, 0, 20)
	okayList := make(map[fileName]bool)
	inclusionLevelAllLength, loopTimes := 0, 0
	for inclusionLevelAllLength < len(*lm) {
		inclusionMap := make(map[fileName]bool)
		if loopTimes == 0 {
			for _, listinfo := range *lm {
				if listinfo.HasInclusion {
					continue
				}
				inclusionMap[listinfo.Name] = true
			}
		} else {
			for _, listinfo := range *lm {
				if !listinfo.HasInclusion || okayList[listinfo.Name] {
					continue
				}
				var passTimes int
				for filename := range listinfo.InclusionAttributeMap {
					if !okayList[filename] {
						break
					}
					passTimes++
				}
				if passTimes == len(listinfo.InclusionAttributeMap) {
					inclusionMap[listinfo.Name] = true
				}
			}
		}
		for filename := range inclusionMap {
			okayList[filename] = true
		}
		inclusionLevel = append(inclusionLevel, inclusionMap)
		inclusionLevelAllLength += len(inclusionMap)
		loopTimes++
	}
	for idx, inclusionMap := range inclusionLevel {
		fmt.Printf("Level %d:\n", idx+1)
		fmt.Println(inclusionMap)
		fmt.Println()
		for inclusionFilename := range inclusionMap {
			if err := (*lm)[inclusionFilename].Flatten(lm); err != nil {
				return err
			}
		}
	}
	return nil
}
FlattenAndGenUniqueDomainList flattens the included lists and
generates a domain trie for each file in data directory to
make the items of domain type list unique.
package main
import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"github.com/v2fly/v2ray-core/v4/app/router"
)
type ListInfoMap map[fileName]*ListInfo
func (lm *ListInfoMap) Marshal(path string) error {
	file, err := os.Open(path)
	if err != nil {
		return err
	}
	defer file.Close()
	list := NewListInfo()
	listName := fileName(strings.ToUpper(filepath.Base(path)))
	list.Name = listName
	if err := list.ProcessList(file); err != nil {
		return err
	}
	(*lm)[listName] = list
	return nil
}