<|start_filename|>dot/sconfig.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package dot

import (
	"encoding/json"
	"github.com/scryinfo/scryg/sutils/skit"
)

const (

	//SconfigTypeID scofig dot type id
	SconfigTypeID = "484ef01d-3c04-4517-a643-2d776a9ae758"
)

//SConfig config belongs to one component Dot, but it is so basic, every Dot need it, so define it in dot.go file
//S represents scryinfo config this name is used frequently, so add s to distinguish it
type SConfig interface {
	//RootPath root path
	RootPath()
	//Config file path
	ConfigPath() string
	//Without path, only file name
	ConfigFile() string
	//Whether key existing
	Key(key string) bool
	//If no config or config is empty, return nil
	Map() (m map[string]interface{}, err error)

	//Priorly bring data from RAM and operate, if RAM is nil then check whether original config file existing
	Unmarshal(s interface{}) error
	//Analyze key is corresponding type
	UnmarshalKey(key string, obj interface{}) error

	Marshal(data []byte) error

	//If no corresponding key or data type cannot be converted, must pay attention to default value,
	//so add "Def" before function to notify default value
	DefInterface(key string, def interface{}) interface{}
	DefArray(key string, def []interface{}) []interface{}
	DefMap(key string, def map[string]interface{}) map[string]interface{}
	DefString(key string, def string) string
	DefInt32(key string, def int32) int32
	DefUint32(key string, def uint32) uint32
	DefInt64(key string, def int64) int64
	DefUint64(key string, def uint64) uint64
	DefBool(key string, def bool) bool
	DefFloat32(key string, def float32) float32
	DefFloat64(key string, def float64) float64
}

//UnMarshalConfig unmarshal config
func UnMarshalConfig(conf []byte, obj interface{}) (err error) {
	err = nil
	if conf != nil {
		err = json.Unmarshal(conf, obj)
	} else {
		err = SError.Parameter
	}
	return err
}

//MarshalConfig marshal config
func MarshalConfig(lconf *LiveConfig) (conf []byte, err error) {
	conf = nil
	err = nil

	if lconf != nil {
		if !skit.IsNil(lconf.Config) {
			return json.Marshal(lconf.Config)
		}
	}
	return conf, err
}


<|start_filename|>dots/db/tools/gmodel/gmodel.go<|end_filename|>
package main

import (
	"bytes"
	"flag"
	"fmt"
	"github.com/jinzhu/inflection"
	"github.com/scryinfo/dot/dots/db/pgs"
	"go/ast"
	"go/format"
	"go/token"
	"golang.org/x/tools/go/packages"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
	"text/template"
)

//todo bug说明 类似如下情况
/*type Token struct {
	ID string `pg:",pk,type:varchar(36)"`
	DefaultToken
}

type DefaultToken struct {
	ID 	 string
	Name string
}
gmodel result
const (
	Lock_Table      = "locks"
	Lock_ID         = "id"
	Lock_ID         = "id"
	Lock_Name       = "name"
pgs.CreateSchema result
	DefaultToken.ID	字段缺失
)*/

//DbField do not use the map, we need the order
type DbField struct {
	Name        string
	DbName      string
	HasRelation bool //has one, has many, belong to
}

type tData struct {
	TypeName     string
	TableName    string
	PkgName      string
	DbObjectName string
	MapExcludes  map[string]bool
	Fields       []DbField
	StringFields []DbField
}

var params struct {
	typeName    string
	mapExcludes string
}

func parms(data *tData) {
	flag.StringVar(&params.typeName, "typeName", "", "")
	flag.StringVar(&params.mapExcludes, "mapExcludes", "", "split ','")
	flag.Parse()

	if len(params.mapExcludes) > 0 {
		exes := strings.Split(params.mapExcludes, ",")
		data.MapExcludes = make(map[string]bool, len(exes))
		for i := range exes {
			it := pgs.CamelCased(exes[i])
			data.MapExcludes[it] = true
		}
	} else {
		data.MapExcludes = make(map[string]bool, 0)
	}

	data.TypeName = params.typeName
	data.DbObjectName = pgs.Underscore(params.typeName)
	data.TableName = tableNameInflector(data.DbObjectName)
}

var tableNameInflector = inflection.Plural

//env:   GOPACKAGE=model;GOFILE=D:\gopath\src\github.com\scryinfo\dot\sample\db\pgs\model\models.go
func main() {
	log.Println("run gmodel")
	data := &tData{}
	parms(data)
	if len(params.typeName) < 1 {
		log.Fatal("type name is null")
	}

	var src []byte = nil
	{
		makeData(data)
		src = gmodel(data)
	}

	outputName := ""
	{
		//types := strings.Split(params.typeName, ",")
		types := pgs.Underscore(data.TypeName)
		baseName := fmt.Sprintf("%s_model.go", types)
		outputName = filepath.Join(".", strings.ToLower(baseName))
	}

	if _, err := os.Stat(outputName); os.IsNotExist(err) {
		err := ioutil.WriteFile(outputName, src, 0644)
		if err != nil {
			log.Fatalf("writing output: %s", err)
		}
	} else {
		log.Println("exist the file: " + outputName)
	}
	log.Println("finished gmodel")
}

func makeData(data *tData) {
	data.PkgName = os.Getenv("GOPACKAGE")
	file := os.Getenv("GOFILE")
	fields := make([]DbField, 0)
	var pkg *packages.Package
	{
		dir := filepath.Dir(file)
		cfg := &packages.Config{
			Mode: packages.NeedName |
				//packages.NeedFiles |
				//packages.NeedCompiledGoFiles |
				packages.NeedImports |
				packages.NeedDeps |
				//packages.NeedExportsFile |
				//packages.NeedTypes |
				packages.NeedSyntax,
			//packages.NeedTypesInfo |
			//packages.NeedTypesSizes ,
			Dir:   dir,
			Tests: true,
			Env:   append(os.Environ(), "GO111MODULE=off", "GOPROXY=off"), //"GOPATH="+dir,
		}
		pkgs, err := packages.Load(cfg, file)
		if err != nil {
			log.Fatal(err)
		}
		pkg = pkgs[0]
		if len(pkg.Syntax) != 1 {
			log.Fatal("parse file not " + file)
		}
	}
	{
		f := pkg.Syntax[0]
		ast.Inspect(f, func(n ast.Node) bool {
			if n != nil {
				decl, ok := n.(*ast.GenDecl)
				// just STRUCT
				if !ok || decl.Tok != token.TYPE {
					return true
				}
				for _, spec := range decl.Specs {
					typeS, ok := spec.(*ast.TypeSpec)
					if ok && typeS.Name.Name == data.TypeName {
						structT := typeS.Type.(*ast.StructType)
						fields, _ = listFields(data, structT, fields, pkg)
					}
				}
			}

			return true
		})

	}
	data.Fields = fields
}
func listFields(data *tData, st *ast.StructType, fields []DbField, pkg *packages.Package) ([]DbField, error) {
	for _, field := range st.Fields.List {
		var subT *ast.StructType
		//|| (field.Tag != nil && strings.Contains(field.Tag.Value,"composite"))
		if field.Names == nil { //这个字段直接是类型，或者是组合
			if ident, ok := field.Type.(*ast.Ident); ok {
				if decl, ok := ident.Obj.Decl.(*ast.TypeSpec); ok {
					if subT, ok = decl.Type.(*ast.StructType); ok {
						//fields, _ = listFields(data, subT, fields, pkg)
					}
				}
			} else if expr, ok := field.Type.(*ast.SelectorExpr); ok {
				//这个字段的类型是从import中导入的，
				obj := expr.Sel.Obj
				if obj == nil {
					packageName := expr.X.(*ast.Ident).Name
					objName := expr.Sel.Name
				objLoop:
					for _, importPackage := range pkg.Imports {
						if importPackage.Name == packageName {
							for _, importFile := range importPackage.Syntax {
								if importFile.Scope != nil {
									obj = importFile.Scope.Lookup(objName)
									if obj != nil {
										break objLoop
									}
								}
							}
						}
					}
				}
				if obj == nil {
					//todo 内部错误
				} else {
					if decl, ok := obj.Decl.(*ast.TypeSpec); ok {
						if subT, ok = decl.Type.(*ast.StructType); ok {
							//fields, _ = listFields(data, subT, fields, pkg)
						}
					}
				}

			} else { //todo 内部错误

			}
		} else {
			name := field.Names[0].Name
			dbField := DbField{Name: name, DbName: pgs.Underscore(name)}
			tag := ""
			if field.Tag != nil {
				tag = field.Tag.Value
			}
			if strings.Contains(tag, `pg:"-"`) || strings.Contains(tag, "rel:has-one") || strings.Contains(tag, "rel:has-many") || strings.Contains(tag, "rel:belongs-to") {
				dbField.HasRelation = true
			}
			fields = append(fields, dbField)
			ftype, ok := field.Type.(*ast.Ident)
			if ok && ftype.Name == "string" {
				data.StringFields = append(data.StringFields, dbField)
			}
		}
		if subT != nil {
			fields, _ = listFields(data, subT, fields, pkg)
		}
	}
	return fields, nil
}

func gmodel(data *tData) []byte {

	temp := `
package {{.PkgName}}
import (
	"fmt"
	"github.com/scryinfo/dot/dots/db/pgs"
)
	const (
		{{$.TypeName}}_Table       = "{{$.TableName}}"
		{{$.TypeName}}_Struct      = "{{$.DbObjectName}}"
		{{range $.Fields}} {{$.TypeName}}_{{.Name}} = "{{.DbName}}"
		{{end}}
	)

	func (m *{{$.TypeName}}) String() string {
		//todo please change the format string
		//{{range $.Fields}}m.{{.Name}}, {{end}}
		str := fmt.Sprintf("{{$.TypeName}}<{{range $.StringFields}}%s {{end}}>",
		{{range $.StringFields}}m.{{.Name}}, {{end}}
		)
		return str
	}

	func (m *{{$.TypeName}}) ToMap() map[string]string {
		res := pgs.ToMap(m, map[string]bool{ {{range $k,$v := $.MapExcludes}}"{{$k}}":{{$v}} {{end}} })
		return res
	}

	func (m *{{$.TypeName}}) ToUpsertSet() []string {
		res := []string{ 
			{{- range $.Fields}}
			{{if .HasRelation}}{{else}}fmt.Sprintf("%s = EXCLUDED.%s", {{$.TypeName}}_{{.Name}}, {{$.TypeName}}_{{.Name}}),
			{{- end}}
			{{- end}}
		}
		return res
	}
`

	var src []byte = nil
	{
		t, err := template.New("").Parse(temp)
		if err != nil {
			log.Fatal(err)
		}
		buff := bytes.NewBufferString("")
		err = t.Execute(buff, data)
		if err != nil {
			log.Fatal(err)
		}

		src, err = format.Source(buff.Bytes())
		if err != nil {
			log.Fatal(err)
		}
	}
	return src
}


<|start_filename|>tools/dotconf/data/find_tool_test.go<|end_filename|>
//
//Created by jayce on 9:13 2021/5/6
//
package data

import "testing"

func TestFindDots(t *testing.T) {

	var dirs []string
	dirs = append(dirs, `F:\go\src\github.com\scryinfo\dot\dots`)
	dirs = append(dirs, `F:\go\src\github.com\scryinfo\dot\dots\gindot`)
	data, ndir, err := FindDots(dirs)
	_ = data
	_ = ndir
	_ = err
}


<|start_filename|>dots/gindot/router.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package gindot

import (
	"reflect"

	"github.com/gin-gonic/gin"
	"github.com/scryinfo/dot/dot"
)

const (
	//RouterTypeID for gin dot
	RouterTypeID = "6be39d0b-3f5b-47b4-818c-642c049f3166"
)

type configRouter struct {
	RelativePath string `json:"relativePath"`
}

//Router  gin router
type Router struct {
	Engine_ *Engine `dot:""`
	router  *gin.RouterGroup
	config  configRouter
	liveID  dot.LiveID
}

//construct dot
func newRouter(conf []byte) (*Router, error) {
	dconf := &configRouter{}
	err := dot.UnMarshalConfig(conf, dconf)
	if err != nil {
		return nil, err
	}

	d := &Router{config: *dconf}

	return d, err
}

//RouterTypeLives generate data for structural  dot,  include gindot.Engine
func RouterTypeLives() []*dot.TypeLives {
	lives := []*dot.TypeLives{{
		Meta: dot.Metadata{TypeID: RouterTypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
			return newRouter(conf)
		}},
		Lives: []dot.Live{
			{
				LiveID:    RouterTypeID,
				RelyLives: map[string]dot.LiveID{"Engine_": EngineLiveID},
			},
		},
	}}
	lives = append(lives, GinDotTypeLives()...)
	return lives
}

//jayce edit
//return config of Router
func RouterConfigTypeLive() *dot.ConfigTypeLive {
	return &dot.ConfigTypeLive{
		TypeIDConfig: RouterTypeID,
		ConfigInfo:   &configRouter{},
	}
}

func (c *Router) SetTypeID(_ dot.TypeID, liveID dot.LiveID) {
	c.liveID = liveID
}

func (c *Router) AfterAllInject(l dot.Line) {
	c.router = c.Engine_.GinEngine().Group(c.config.RelativePath)
}

//Start start the gin
func (c *Router) Start(ignore bool) error {

	return nil
}

func (c *Router) Router() *gin.RouterGroup {
	return c.router
}

func (c *Router) RelativePath() string {
	return c.config.RelativePath
}

//all post
func (c *Router) RouterPost(h interface{}, pre string) {
	post := reflect.ValueOf(c.router).MethodByName("POST")
	RouterSelf(h, pre, func(url string, gmethod reflect.Value) {
		vs := []reflect.Value{reflect.ValueOf(url), gmethod}
		post.Call(vs)
	})
}

//all get
func (c *Router) RouterGet(h interface{}, pre string) {
	get := reflect.ValueOf(c.router).MethodByName("GET")
	RouterSelf(h, pre, func(url string, gmethod reflect.Value) {
		vs := []reflect.Value{reflect.ValueOf(url), gmethod}
		get.Call(vs)
	})
}


<|start_filename|>tools/ende/send_signal.go<|end_filename|>
// +build !windows

package ende

import (
	"os"
	"syscall"
)

func SendSignal(s syscall.Signal) error {
	return syscall.Kill(os.Getegid(), s)
}


<|start_filename|>sample/grpc/nobl/hi_server.go<|end_filename|>
// <NAME>.  All rights reserved.
// license that can be found in the license file.

package nobl

import (
	"context"
	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/grpc/gserver"
	"github.com/scryinfo/dot/sample/grpc/go_out/hidot"
	"go.uber.org/zap"
	"io"
	"strconv"
)

const (
	HiServerTypeID = "hiserver"
)

type config struct {
	Name string `json:"name"`
}

type HiServer struct {
	ServerNobl gserver.ServerNobl `dot:""`
	conf       config

	ctx       context.Context
	cancelFun context.CancelFunc
}

func newHiServer(conf interface{}) (dot.Dot, error) {
	var err error = nil
	var bs []byte = nil
	if bt, ok := conf.([]byte); ok {
		bs = bt
	} else {
		return nil, dot.SError.Parameter
	}
	dconf := &config{}
	err = dot.UnMarshalConfig(bs, dconf)
	if err != nil {
		return nil, err
	}

	d := &HiServer{
		conf: *dconf,
	}
	d.ctx, d.cancelFun = context.WithCancel(context.Background())

	return d, err
}

func (c *HiServer) Hi(ctx context.Context, req *hidot.HiReq) (*hidot.HiRes, error) {
	dot.Logger().Infoln("HiServer", zap.String(c.conf.Name, req.Name))
	res := &hidot.HiRes{Name: c.conf.Name}
	return res, nil
}

func (c *HiServer) Write(ctx context.Context, req *hidot.WriteReq) (*hidot.WriteRes, error) {
	dot.Logger().Infoln("HiServer", zap.String(c.conf.Name, req.Data))
	res := &hidot.WriteRes{Data: "Return : " + req.Data}
	return res, nil
}

func (c *HiServer) ServerStream(req *hidot.HelloRequest, serverStream hidot.HiDot_ServerStreamServer) error {
	dot.Logger().Infoln("HiServer", zap.String(c.conf.Name, "ServerStream"))

	res := &hidot.HelloResponse{Reply: req.Greeting + " ServerStream"}
	err := serverStream.Send(res)
	if err == io.EOF {
		return nil
	} else if err != nil {
		return err
	}

	//req.Reset()
	//err = serverStream.RecvMsg(req)
	//if err == io.EOF {
	//	return nil
	//} else if err != nil {
	//	return err
	//}
	return nil
}

func (c *HiServer) ClientStream(clientStream hidot.HiDot_ClientStreamServer) error {
	dot.Logger().Infoln("HiServer", zap.String(c.conf.Name, "ClientStream"))
	count := int64(0)
	for {
		count++
		ctx := clientStream.Context()
		select {
		case <-ctx.Done():
			return nil
		case <-c.ctx.Done():
			return nil
		default:

		}
		req, err := clientStream.Recv()
		if err == io.EOF {
			return nil
		} else if err != nil {
			return err
		}
		res := &hidot.HelloResponse{Reply: req.Greeting + "  " + strconv.FormatInt(count, 10)}
		clientStream.SendMsg(res)
	}
	return nil
}

func (c *HiServer) BothSides(server hidot.HiDot_BothSidesServer) error {
	dot.Logger().Infoln("HiServer", zap.String(c.conf.Name, "BothSides"))
	count := int64(0)
	for {
		count++
		ctx := server.Context()
		select {
		case <-ctx.Done():
			return nil
		case <-c.ctx.Done():
			return nil
		default:

		}
		req, err := server.Recv()
		if err == io.EOF {
			return nil
		} else if err != nil {
			return err
		}

		res := &hidot.HelloResponse{Reply: req.Greeting + "  " + strconv.FormatInt(count, 10)}
		server.SendMsg(res)
	}
	return nil
}

func (c *HiServer) Start(ignore bool) error {
	hidot.RegisterHiDotServer(c.ServerNobl.Server(), c)
	return nil
}

//HiServerTypeLives make all type lives
func HiServerTypeLives() []*dot.TypeLives {
	lives := []*dot.TypeLives{{
		Meta: dot.Metadata{TypeID: HiServerTypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
			return newHiServer(conf)
		}},
		Lives: []dot.Live{
			dot.Live{
				LiveID:    HiServerTypeID,
				RelyLives: map[string]dot.LiveID{"ServerNobl": gserver.ServerNoblTypeID},
			},
		},
	}}
	lives = append(lives, gserver.ServerNoblTypeLives()...)
	return lives
}


<|start_filename|>upgrade.bat<|end_filename|>

@echo on

cd %~dp0
%~d0
set batPath=%cd%

go get github.com/bitly/go-simplejson
go get github.com/gin-gonic/gin
go get github.com/go-kit/kit
go get github.com/golang/mock
go get github.com/improbable-eng/grpc-web
go get github.com/jinzhu/gorm
go get github.com/pkg/errors
go get github.com/rs/cors
go get github.com/stretchr/testify
go get go.uber.org/zap

cd %batPath%



<|start_filename|>sample/grpc/proto/build_gen_ts.bat<|end_filename|>

@echo on

set batPath=%~dp0
cd %batPath%
%~d0

cd ../http/client/src/api
set out=%cd%
cd %batPath%

protoc --plugin="protoc-gen-ts=D:/lang/nodejs/protoc-gen-ts.cmd" --js_out="import_style=commonjs,binary:%out%/" --ts_out="service=grpc-web:%out%/" hi.proto

cd %batPath%


<|start_filename|>dots/db/model_base.go<|end_filename|>
package db

import "gorm.io/gorm"

type ModelBase struct {
	ID                    string `pg:",pk" json:"id"`                          //id
	UpdateTime            int64  `json:"updateTime"`                           //更新时间
	CreateTime            int64  `json:"createTime"`                           //创建时间
	OptimisticLockVersion int64  `pg:",use_zero" json:"optimisticLockVersion"` //default 0 ，not null
}

type AutoModelBase struct {
	ID          uint           `gorm:"primaryKey;autoIncrement"`
	CreatedTime int64          `gorm:"autoCreateTime"`
	UpdatedTime int64          `gorm:"autoCreateTime;autoUpdateTime"`
	DeletedTime gorm.DeletedAt `gorm:"index"`
}


<|start_filename|>tools/dotconf/ui/src/views/components/utils/schemaGenerator/type.js<|end_filename|>
'use strict';

let isObject = function (value) {
    return (null !== value && typeof value === typeof {} && !isArray(value));
};

let isNumber = function (value) {
    return !isArray(value) && (value - parseFloat(value) + 1) >= 0;
};

let isArray = function (value) {
    return (value instanceof Array);
};

let isString = function (value) {
    return (typeof value === typeof '');
};

let isNull = function (value) {
    return (null === value);
};

let isBoolean = function (value) {
    return (value === true || value === false);
};

let getType = function (data) {
    if (isObject(data)) {
        return 'object';
    } else if (isArray(data)) {
        return 'array';
    } else if (isNull(data)) {
        return null;
    } else if (isBoolean(data)) {
        return 'boolean';
    } else if (isString(data)) {
        return 'string';
    } else if (isNumber(data)) {
        return 'number';
    }
};

export {isObject, isArray, isNumber, isString, isBoolean, getType}


<|start_filename|>sample/grpc/tls/build.bat<|end_filename|>


@echo on

cd %~dp0
%~d0
set batPath=%cd%

cd ../nobl/client & go build
copy /Y client.exe "%batPath%/client_both/client_both.exe"
copy /Y client.exe "%batPath%/client_noca/client_noca.exe"

cd %batPath%
cd ../http/server & go build
copy /Y server.exe "%batPath%/http/http_noca.exe"
copy /Y server.exe "%batPath%/http/http_tls.exe"
copy /Y server.exe "%batPath%/http/https.exe"
copy /Y server.exe "%batPath%/http/https_noca.exe"
copy /Y server.exe "%batPath%/http/https_tls.exe"

cd %batPath%
cd ../nobl/server & go build
copy /Y server.exe "%batPath%/server_both/server_both.exe"
copy /Y server.exe "%batPath%/server_noca/server_noca.exe"

cd %batPath%



<|start_filename|>sample/db/tools/dao/pgs/sub_dao.go<|end_filename|>
package pgs

import (
	"time"

	"github.com/go-pg/pg/v10"
	"github.com/go-pg/pg/v10/orm"
	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/db/pgs"
	"github.com/scryinfo/dot/sample/db/tools/model"
	"github.com/scryinfo/scryg/sutils/uuid"
)

const SubDaoTypeID = "6e3e5751-a618-410b-b06a-4ca960f2f4ac"

type SubDao struct {
	*pgs.DaoBase `dot:""`
}

//SubDaoTypeLives
func SubDaoTypeLives() []*dot.TypeLives {
	tl := &dot.TypeLives{
		Meta: dot.Metadata{
			Name:   "SubDao",
			TypeID: SubDaoTypeID,
			NewDoter: func(conf []byte) (dot.Dot, error) {
				return &SubDao{}, nil
			},
		},
		Lives: []dot.Live{
			{
				LiveID: SubDaoTypeID,
				RelyLives: map[string]dot.LiveID{
					"DaoBase": pgs.DaoBaseTypeID,
				},
			},
		},
	}

	lives := pgs.DaoBaseTypeLives()
	lives = append(lives, tl)
	return lives
}

// if find nothing, return pg.ErrNoRows
func (c *SubDao) GetByIDWithLock(conn orm.DB, id string) (m *model.Sub, err error) {
	m = &model.Sub{}
	m.ID = id
	err = conn.Model(m).WherePK().For("UPDATE").Select()
	if err != nil {
		m = nil
	}
	return
}
func (c *SubDao) GetByID(conn orm.DB, id string) (m *model.Sub, err error) {
	m = &model.Sub{}
	m.ID = id
	err = conn.Model(m).WherePK().Select()
	if err != nil {
		m = nil
	}
	return
}

//update before
//you must get OptimisticLockVersion value
func (c *SubDao) GetLockByID(conn orm.DB, ids ...string) (ms []*model.Sub, err error) {
	for i, _ := range ids {
		m := &model.Sub{}
		m.ID = ids[i]
		ms = append(ms, m)
	}
	err = conn.Model(&ms).WherePK().Column(model.Sub_OptimisticLockVersion, model.Sub_ID).For("UPDATE").Select()
	if err != nil {
		ms = nil
	}
	return
}
func (c *SubDao) GetLockByModelID(conn orm.DB, ms ...*model.Sub) error {
	return conn.Model(&ms).WherePK().Column(model.Sub_OptimisticLockVersion, model.Sub_ID).For("UPDATE").Select()
}

// if find nothing, return pg.ErrNoRows
func (c *SubDao) QueryWithLock(conn orm.DB, condition string, params ...interface{}) (ms []*model.Sub, err error) {
	if len(condition) < 1 {
		err = conn.Model(&ms).For("UPDATE").Select()
	} else {
		err = conn.Model(&ms).Where(condition, params...).For("UPDATE").Select()
	}
	if err != nil { //be sure
		ms = nil
	}
	return
}
func (c *SubDao) Query(conn orm.DB, condition string, params ...interface{}) (ms []*model.Sub, err error) {
	if len(condition) < 1 {
		err = conn.Model(&ms).Select()
	} else {
		err = conn.Model(&ms).Where(condition, params...).Select()
	}
	if err != nil { //be sure
		ms = nil
	}
	return
}

// if find nothing, return pg.ErrNoRows
func (c *SubDao) ListWithLock(conn orm.DB) (ms []*model.Sub, err error) {
	err = conn.Model(&ms).For("UPDATE").Select()
	if err != nil { //be sure
		ms = nil
	}
	return
}
func (c *SubDao) List(conn orm.DB) (ms []*model.Sub, err error) {
	err = conn.Model(&ms).Select()
	if err != nil { //be sure
		ms = nil
	}
	return
}

func (c *SubDao) Count(conn orm.DB, condition string, params ...interface{}) (count int, err error) {
	if len(condition) < 1 {
		count, err = conn.Model(&model.Sub{}).Count()
	} else {
		count, err = conn.Model(&model.Sub{}).Where(condition, params...).Count()
	}
	return
}

// if find nothing, return pg.ErrNoRows
func (c *SubDao) QueryPageWithLock(conn orm.DB, pageSize int, page int, condition string, params ...interface{}) (ms []*model.Sub, err error) {
	if len(condition) < 1 {
		err = conn.Model(&ms).Limit(pageSize).Offset((page - 1) * pageSize).For("UPDATE").Select()
	} else {
		err = conn.Model(&ms).Where(condition, params...).Limit(pageSize).Offset((page - 1) * pageSize).For("UPDATE").Select()
	}
	if err != nil { //be sure
		ms = nil
	}
	return
}
func (c *SubDao) QueryPage(conn orm.DB, pageSize int, page int, condition string, params ...interface{}) (ms []*model.Sub, err error) {
	if len(condition) < 1 {
		err = conn.Model(&ms).Limit(pageSize).Offset((page - 1) * pageSize).Select()
	} else {
		err = conn.Model(&ms).Where(condition, params...).Limit(pageSize).Offset((page - 1) * pageSize).Select()
	}
	if err != nil { //be sure
		ms = nil
	}
	return
}

// count counts valid records which after conditions filter, rather than whole table's count
func (c *SubDao) QueryPageWithCount(
	conn orm.DB,
	pageSize,
	pageNum int,
	condition string,
	params ...interface{},
) (ms []*model.Sub, count int, err error) {
	if len(condition) < 1 {
		count, err = conn.Model(&ms).Limit(pageSize).Offset((pageNum - 1) * pageSize).SelectAndCount()
	} else {
		count, err = conn.Model(&ms).Where(condition, params...).Limit(pageSize).Offset((pageNum - 1) * pageSize).SelectAndCount()
	}

	if err != nil { //be sure
		ms = nil
	}
	return
}

// if find nothing, return pg.ErrNoRows
func (c *SubDao) QueryOneWithLock(conn orm.DB, condition string, params ...interface{}) (m *model.Sub, err error) {
	m = &model.Sub{}
	if len(condition) < 1 {
		err = conn.Model(m).For("UPDATE").First()
	} else {
		err = conn.Model(m).Where(condition, params...).For("UPDATE").First()
	}
	if err != nil { //be sure
		m = nil
	}
	return
}
func (c *SubDao) QueryOne(conn orm.DB, condition string, params ...interface{}) (m *model.Sub, err error) {
	m = &model.Sub{}
	if len(condition) < 1 {
		err = conn.Model(m).First()
	} else {
		err = conn.Model(m).Where(condition, params...).First()
	}
	if err != nil { //be sure
		m = nil
	}
	return
}

//if insert nothing, then return pg.ErrNoRows
func (c *SubDao) Insert(conn orm.DB, m *model.Sub) (err error) {
	if len(m.ID) < 1 {
		m.ID = uuid.GetUuid()
	}
	m.CreateTime = time.Now().Unix()
	m.UpdateTime = m.CreateTime
	_, err = conn.Model(m).Insert()
	return
}

//if insert nothing, then return pg.ErrNoRows
func (c *SubDao) InsertReturn(conn orm.DB, m *model.Sub) (mnew *model.Sub, err error) {
	if len(m.ID) < 1 {
		m.ID = uuid.GetUuid()
	}
	m.CreateTime = time.Now().Unix()
	m.UpdateTime = m.CreateTime

	mnew = &model.Sub{}
	_, err = conn.Model(m).Returning("*").Insert(mnew)
	if err != nil {
		mnew = nil
	}
	return
}

//if update nothing, then return pg.ErrNoRows
func (c *SubDao) Upsert(conn orm.DB, m *model.Sub) (err error) {
	m.UpdateTime = time.Now().Unix()
	if len(m.ID) < 1 {
		m.ID = uuid.GetUuid()
		m.CreateTime = m.UpdateTime
	} else if m.CreateTime == 0 {
		m.CreateTime = m.UpdateTime
	}
	m.OptimisticLockVersion++
	om := conn.Model(m).OnConflict("(id) DO UPDATE").Where(model.Sub_Struct+"."+model.Sub_OptimisticLockVersion+" = ?", m.OptimisticLockVersion-1)
	for _, it := range m.ToUpsertSet() {
		om.Set(it)
	}
	res, err := om.Insert()
	if res.RowsAffected() == 0 {
		//err = pg.ErrNoRows
		newm, err := c.GetLockByID(conn, m.ID)
		if err != nil {
			return err
		}
		m.OptimisticLockVersion = newm[0].OptimisticLockVersion
		err = c.Update(conn, m)
		return err
	}
	return err
}

//if update nothing, then return pg.ErrNoRows
func (c *SubDao) UpsertReturn(conn orm.DB, m *model.Sub) (mnew *model.Sub, err error) {
	m.UpdateTime = time.Now().Unix()
	if len(m.ID) < 1 {
		m.ID = uuid.GetUuid()
		m.CreateTime = m.UpdateTime
	} else if m.CreateTime == 0 {
		m.CreateTime = m.UpdateTime
	}
	m.OptimisticLockVersion++
	om := conn.Model(m).OnConflict("(id) DO UPDATE").Where(model.Sub_Struct+"."+model.Sub_OptimisticLockVersion+" = ?", m.OptimisticLockVersion-1)
	for _, it := range m.ToUpsertSet() {
		om.Set(it)
	}
	mnew = &model.Sub{}
	_, err = om.Returning("*").Insert(mnew)
	if err == pg.ErrNoRows {
		new_m, err := c.GetLockByID(conn, m.ID)
		if err != nil {
			return nil, err
		}
		m.OptimisticLockVersion = new_m[0].OptimisticLockVersion
		mnew, err = c.UpdateReturn(conn, m)
		return mnew, err
	}
	return
}

//if update nothing, then return pg.ErrNoRows
func (c *SubDao) Update(conn orm.DB, m *model.Sub) (err error) {
	m.UpdateTime = time.Now().Unix()
	m.OptimisticLockVersion++
	//err = conn.Update(m)
	res, err := conn.Model(m).Where(model.Sub_ID+" = ? and "+model.Sub_OptimisticLockVersion+" = ?", m.ID, m.OptimisticLockVersion-1).Update()
	if res.RowsAffected() == 0 {
		err = pg.ErrNoRows
	}
	return
}

//if update nothing, then return pg.ErrNoRows
func (c *SubDao) UpdateReturn(conn orm.DB, m *model.Sub) (mnew *model.Sub, err error) {
	m.UpdateTime = time.Now().Unix()
	m.OptimisticLockVersion++
	mnew = &model.Sub{}
	res, err := conn.Model(m).Where(model.Sub_ID+" = ? and "+model.Sub_OptimisticLockVersion+" = ?", m.ID, m.OptimisticLockVersion-1).Returning("*").Update(mnew)
	if err != nil {
		mnew = nil
	}
	if res.RowsAffected() == 0 {
		err = pg.ErrNoRows
	}
	return
}

//if delete nothing, then return pg.ErrNoRows
func (c *SubDao) Delete(conn orm.DB, m *model.Sub) (err error) {
	_, err = conn.Model(m).Delete()
	return
}

//if delete nothing, then return pg.ErrNoRows
func (c *SubDao) DeleteByID(conn orm.DB, id string) (err error) {
	_, err = conn.Model((*model.Sub)(nil)).Where(model.Sub_ID+" = ?", id).Delete()
	return
}

//if delete nothing, then return pg.ErrNoRows
func (c *SubDao) DeleteByIDs(conn orm.DB, ids []string, oneMax int) (err error) {
	m := (*model.Sub)(nil)
	max := oneMax
	times := len(ids) / max
	for i := 1; i < times; i++ {
		oneIDs := ids[(i-1)*max : i*max-1]
		_, err = conn.Model(m).Where(model.Sub_ID+" in (?)", pg.In(oneIDs)).Delete()
		if err != nil {
			return
		}
	}

	if max*times < len(ids) {
		oneIDs := ids[max*times:]
		_, err = conn.Model(m).Where(model.Sub_ID+" in (?)", pg.In(oneIDs)).Delete()
	}
	return
}

//if delete nothing, then return pg.ErrNoRows
func (c *SubDao) DeleteReturn(conn orm.DB, m *model.Sub) (mnew *model.Sub, err error) {
	mnew = &model.Sub{}
	_, err = conn.Model(m).WherePK().Returning("*").Delete(mnew)
	if err != nil {
		mnew = nil
	}
	return
}

//example,please edit it
//update designated column with Optimistic Lock
func (c *SubDao) UpdateSubSomeColumn(conn orm.DB, ids []string /*todo: update parameters*/) (err error) {

	ms, err := c.GetLockByID(conn, ids...)
	if err != nil {
		return
	}

	for i, _ := range ms {
		ms[i].UpdateTime = time.Now().Unix()
		ms[i].OptimisticLockVersion++
		//todo ms[i].xx=parameter
		_, err = conn.Model(ms[i]).Where(model.Sub_ID+" = ? and "+model.Sub_OptimisticLockVersion+" = ?", ms[i].ID, ms[i].OptimisticLockVersion-1).Column( /*model.Sub_xx,*/ model.Sub_OptimisticLockVersion, model.Sub_UpdateTime).Update()
		if err != nil {
			dot.Logger().Debugln(err.Error())
			return
		}
	}
	return
}


<|start_filename|>demo/redis/demo.go<|end_filename|>
package main

import (
    "fmt"
    "time"
)

// authenticate basic set and get funcs, and other demo will ignore error returned if not necessary
func basicDemo() {
    fmt.Println("-------")

    // query in cache
    v, err := getValue("demo")
    if err != nil {
        fmt.Printf("get value failed, error: %v, value is empty str?: %t\n", err, v == "")
    }

    // simulate query not find, skip save to db and update cache
    err = setValue("demo", "basic demo")
    if err != nil {
        fmt.Println("set value failed, error:", err)
    }

    v, err = getValue("demo")
    if err != nil {
        fmt.Println("get value failed, error:", err)
    }

    fmt.Println("show value after set:", v)
}

func expireDemo() {
    fmt.Println("-------")

    err := setValue("demo", "expire demo", time.Second*2)
    if err != nil {
        fmt.Println("set value failed, error:", err)
    }
    fmt.Println("expire time: 2s")

    v, err := getValue("demo")
    fmt.Printf("get value immediately, value: |%s|, error: %v\n", v, err)

    time.Sleep(time.Second)

    v, err = getValue("demo")
    fmt.Printf("get value after 2s   , value: |%s|, error: %v\n", v, err)
}

func updateDemo() {
    fmt.Println("-------")

    _ = setValue("demo", "update demo", 0)
    v, _ := getValue("demo")
    fmt.Println("value:", v)

    err := setValue("demo", "UPDATE VALUE", 0)
    if err != nil {
        fmt.Println("update value failed, error:", err)
    }

    v, _ = getValue("demo")
    fmt.Println("value(updated):", v)

    err = setValue("demo", "UPDATE VALUE ONCE AGAIN", time.Second*2)
    if err != nil {
        fmt.Println("update value or set expire time failed, error:", err)
    }

    v, _ = getValue("demo")
    fmt.Println("value(updated):", v)
}


<|start_filename|>tools/ende/send_signal_windows.go<|end_filename|>
// +build windows

package ende

import (
	"os"
	"syscall"
)

func SendSignal(s syscall.Signal) error {
	p, err := os.FindProcess(os.Getpid())

	if err != nil {
		return err
	}

	return p.Signal(s)
}


<|start_filename|>sample/db/tools/model/notice_model.go<|end_filename|>
package model

import (
	"fmt"
	"github.com/scryinfo/dot/dots/db/pgs"
)

const (
	Notice_Table                 = "notices"
	Notice_Struct                = "notice"
	Notice_ID                    = "id"
	Notice_UpdateTime            = "update_time"
	Notice_CreateTime            = "create_time"
	Notice_OptimisticLockVersion = "optimistic_lock_version"
	Notice_Data                  = "data"
	Notice_Status                = "status"
	Notice_No                    = "no"
)

func (m *Notice) String() string {
	//todo please change the format string
	//m.ID, m.UpdateTime, m.CreateTime, m.OptimisticLockVersion, m.Data, m.Status, m.No,
	str := fmt.Sprintf("Notice<%s >",
		m.ID,
	)
	return str
}

func (m *Notice) ToMap() map[string]string {
	res := pgs.ToMap(m, map[string]bool{})
	return res
}

func (m *Notice) ToUpsertSet() []string {
	res := []string{
		fmt.Sprintf("%s = EXCLUDED.%s", Notice_ID, Notice_ID),
		fmt.Sprintf("%s = EXCLUDED.%s", Notice_UpdateTime, Notice_UpdateTime),
		fmt.Sprintf("%s = EXCLUDED.%s", Notice_CreateTime, Notice_CreateTime),
		fmt.Sprintf("%s = EXCLUDED.%s", Notice_OptimisticLockVersion, Notice_OptimisticLockVersion),
		fmt.Sprintf("%s = EXCLUDED.%s", Notice_Data, Notice_Data),
		fmt.Sprintf("%s = EXCLUDED.%s", Notice_Status, Notice_Status),
	}
	return res
}


<|start_filename|>dots/db/redis_client/redis_client.go<|end_filename|>
package redis_client //nolint:golint

import (
	"context"
	"encoding/json"
	"fmt"
	"strings"
	"sync"
	"time"

	"github.com/go-redis/redis/v8"
	"github.com/pkg/errors"
	"go.uber.org/zap"

	"github.com/scryinfo/dot/dot"
)

//RedisClientTypeID type id
const RedisClientTypeID = "0ae35550-7e37-4afe-866e-b129099759b7"

type configRedis struct {
	Addr                string `json:"addr"`
	KeepMaxVersionCount int64  `json:"keepMaxVersionCount"` //分类中版本的最大数据量
	VersionFromRedis    bool   `json:"versionFromRedis"`    //get version from redis or not
}

//RedisClient redis client dot
type RedisClient struct {
	conf configRedis

	subscribe *redis.PubSub
	versions  sync.Map
	clientV8  *redis.Client
	ctx       context.Context    //用于退出程序
	cancelFun context.CancelFunc //ctx的取消
}

// Operation defines the corresponding operations
type Operation uint8

const (
	//Set set version
	Set Operation = iota
	//Clean Clean version
	Clean
)

// VersionControl defines a version edit.
type VersionControl struct {
	// Op indicates the operation of the update.
	Op      Operation `json:"op"`
	Key     string    `json:"key"`
	Version string    `json:"version"`
}

//Marshal to json string
func (c *VersionControl) Marshal() string {
	bs, err := json.Marshal(c)
	if err == nil {
		return string(bs)
	}
	return ""
}

//Unmarshal json string to VersionControl
func (c *VersionControl) Unmarshal(jsonStr string) (*VersionControl, error) {
	vc := c
	err := json.Unmarshal([]byte(jsonStr), vc)
	if err != nil {
		vc = nil
	}
	return vc, err
}

//ClientV8 return redis.Client
func (c *RedisClient) ClientV8() *redis.Client {
	return c.clientV8
}

// GetVersion get current version by category, return version and error.
func (c *RedisClient) GetVersion(category string) (string, error) {
	categoryKey := CategoryKey(category)
	if c.conf.VersionFromRedis {
		return c.clientV8.Get(c.ctx, categoryKey).Result()
	}

	versionCache, ok := c.versions.Load(categoryKey)
	if !ok {
		return "", errors.New(fmt.Sprintf("category: %s is not exist", category))
	}

	version, ok := versionCache.(string)
	if !ok {
		return "", errors.New(fmt.Sprintf("category: %s is not string type", category))
	}

	return version, nil
}

//SetVersion set version for category
func (c *RedisClient) SetVersion(category, version string) error {
	// tx: current version / all versions
	categoryKey := CategoryKey(category)
	categoriesKey := CategoriesKey(category)

	pipe := c.clientV8.TxPipeline()
	pipe.Set(c.ctx, categoryKey, version, 0)
	pipe.ZAdd(c.ctx, categoriesKey, &redis.Z{
		Score:  0,
		Member: version,
	}) //zadd will ignore the same version

	vcJSON := (&VersionControl{
		Op: Set, Key: categoryKey, Version: version,
	}).Marshal()
	pipe.Publish(c.ctx, VersionControlChannelName, vcJSON)
	_, err := pipe.Exec(c.ctx)
	if err != nil {
		dot.Logger().Errorln("redis set version failed", zap.NamedError("error", err))
		return err
	}
	if !c.conf.VersionFromRedis {
		c.versions.Store(categoryKey, version)
	}

	// limit keep versions' length
	// set version 函数本身重点不在于维护历史版本list，某一次维护失败对业务没有影响，
	// 所以维护操作没有加入事务中，且出错也只是打印日志，而不认为函数执行错误
	length, err := c.clientV8.ZCard(c.ctx, categoriesKey).Result()
	if err != nil {
		dot.Logger().Errorln("redis get list.length failed",
			zap.NamedError("error", err),
			zap.String("list name", category))
		return nil
	}
	if length > c.conf.KeepMaxVersionCount {
		if err = c.clientV8.ZRemRangeByRank(c.ctx, categoriesKey, length-c.conf.KeepMaxVersionCount, -1).Err(); err != nil {
			dot.Logger().Errorln("redis.rPop failed", zap.NamedError("error", err))
		}
	}

	return nil
}

//Get get value
func (c *RedisClient) Get(category, version, itemKey string) (string, error) {
	key := VersionItemKey(category, version, itemKey)
	return c.clientV8.Get(c.ctx, key).Result()
}

//Get get value
func (c *RedisClient) GetJsonSerialize(category, version, itemKey string, value interface{}) error {
	key := VersionItemKey(category, version, itemKey)
	str, err := c.clientV8.Get(c.ctx, key).Result()
	if err == nil {
		err = json.Unmarshal([]byte(str), value)
	}
	return err
}

//Set set value
func (c *RedisClient) Set(category, version, itemKey, value string, expiration time.Duration) (string, error) {
	key := VersionItemKey(category, version, itemKey)
	return c.clientV8.Set(c.ctx, key, value, expiration).Result()
}

//Set set value
func (c *RedisClient) SetJsonSerialize(category, version, itemKey string, value interface{}, expiration time.Duration) (string, error) {
	bs, err := json.Marshal(value)
	if err == nil {
		key := VersionItemKey(category, version, itemKey)
		jsonValue := string(bs)
		return c.clientV8.Set(c.ctx, key, jsonValue, expiration).Result()
	} else {
		return "", err
	}
}

//Del del key
func (c *RedisClient) Del(category, version, itemKey string) (int64, error) {
	key := VersionItemKey(category, version, itemKey)
	return c.clientV8.Del(c.ctx, key).Result()
}

//CleanVersion del versions in key
func (c *RedisClient) CleanVersion(category string, version string) error {
	categoryKey := CategoryKey(category)
	categoriesKey := CategoriesKey(category)
	versionKey := VersionKey(category, version)
	// re-curse del target versions
	var keys []string
	var cursor uint64
	var err error
	for {
		//scan see http://doc.redisfans.com/key/scan.html
		keys, cursor, err = c.clientV8.Scan(c.ctx, cursor, versionKey+KeySplitChar+"*", 100).Result()
		if err != nil {
			dot.Logger().Errorln("RedisClient CleanVersion", zap.NamedError("error", err))
			return err
		}
		if len(keys) > 0 {
			pipe := c.clientV8.TxPipeline()
			pipe.Del(c.ctx, keys...)
			_, err = pipe.Exec(c.ctx)
			if err != nil {
				dot.Logger().Errorln("RedisClient CleanVersion", zap.NamedError("error", err))
				return err
			}
		}
		if cursor < 1 { //scan is over
			break
		}
	}
	pipe := c.clientV8.TxPipeline()
	pipe.Del(c.ctx, categoryKey)
	pipe.ZRem(c.ctx, categoriesKey, version)
	vsJSON := (&VersionControl{
		Op: Clean, Key: categoryKey, Version: "",
	}).Marshal()
	pipe.Publish(c.ctx, VersionControlChannelName, vsJSON)
	_, err = pipe.Exec(c.ctx)
	if err != nil {
		dot.Logger().Errorln("RedisClient CleanVersion", zap.NamedError("error", err))
	}
	return err
}

//GetVersions return versions (dictionary order)
func (c *RedisClient) GetVersions(category string) ([]string, error) {
	categoryKey := CategoriesKey(category)
	versions, err := c.clientV8.ZRange(c.ctx, categoryKey, 0, -1).Result()
	if err != nil {
		dot.Logger().Errorln("redis get all versions failed", zap.NamedError("error", err))
	}

	return versions, err
}

//Create create dot
func (c *RedisClient) Create(dot.Line) error {
	c.clientV8 = redis.NewClient(&redis.Options{
		Addr: c.conf.Addr,
	})

	// directly return if not use component to manage version
	if c.conf.VersionFromRedis {
		return nil
	}

	go func() {
		//see https://redis.uptrace.dev/#pubsub the subscribe automatic reconnect
		c.subscribe = c.clientV8.Subscribe(c.ctx, VersionControlChannelName)

		for {
			select {
			case <-c.ctx.Done():
				return
			case msg, ok := <-c.subscribe.Channel(): //see
				if !ok || msg == nil {
					continue
				}
				vc := &VersionControl{}
				vc, err := vc.Unmarshal(msg.Payload)
				if err != nil {
					dot.Logger().Errorln("unmarshal key with version failed",
						zap.NamedError("error", err),
						zap.String("key with version", msg.Payload))
				} else {
					if vc.Op == Set {
						c.versions.Store(vc.Key, vc.Version)
					} else if vc.Op == Clean {
						c.versions.Delete(vc.Key)
					}
				}
			}
		}
	}()

	return nil
}

//AfterAllDestroy after all destroy
func (c *RedisClient) AfterAllDestroy(_ dot.Line) {
	if c.cancelFun != nil {
		c.cancelFun() //此方法可以调用多次
	}

	if c.subscribe != nil {
		_ = c.subscribe.Close()
		c.subscribe = nil
	}

	if c.clientV8 != nil {
		_ = c.clientV8.Close()
		c.clientV8 = nil
	}
}

//construct dot
func newRedisClient(conf []byte) (dot.Dot, error) {
	dconf := &configRedis{}

	err := dot.UnMarshalConfig(conf, dconf)
	if err != nil {
		return nil, err
	}

	d := &RedisClient{conf: *dconf}

	d.ctx, d.cancelFun = context.WithCancel(context.Background())

	return d, nil
}

//RedisClientTypeLives return type lives
func RedisClientTypeLives() []*dot.TypeLives {
	return []*dot.TypeLives{{
		Meta: dot.Metadata{TypeID: RedisClientTypeID, NewDoter: newRedisClient},
	}}
}

//RedisClientTest for test
func RedisClientTest(jsonConfig string) *RedisClient {
	d, err := newRedisClient([]byte(jsonConfig))
	if err != nil || d == nil {
		return nil
	}

	redisClient := d.(*RedisClient)
	_ = redisClient.Create(nil)
	time.Sleep(2 * time.Second)
	return redisClient
}

//RedisClientConfigTypeLive return config
func RedisClientConfigTypeLive() *dot.ConfigTypeLive {
	return &dot.ConfigTypeLive{
		TypeIDConfig: RedisClientTypeID,
		ConfigInfo:   &configRedis{},
	}
}

//GenerateKey generate key for redis
func GenerateKey(keys ...string) string {
	return strings.Join(keys, KeySplitChar)
}

//CategoryKey category key
func CategoryKey(category string) string {
	return GenerateKey(CategoryPrefix, category)
}

//CategoriesKey categories key
func CategoriesKey(category string) string {
	return GenerateKey(CategoriesPrefix, category)
}

//VersionKey version key
func VersionKey(category string, version string) string {
	return GenerateKey(CategoryPrefix, category, version)
}

//VersionItemKey use category,version,item key to generate key of redis
func VersionItemKey(category string, version string, itemKey string) string {
	return GenerateKey(CategoryPrefix, category, version, itemKey)
}


<|start_filename|>dots/certificate/ecdsa_test.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package certificate

import (
	"os"
	"path/filepath"
	"testing"
)

func TestEcdsa_GenerateCaCertKey(t *testing.T) {
	ec := &Ecdsa{}

	caPri, err := MakePriKey()
	if err != nil {
		t.Error(err)
	}

	keyFile := "ca.key"
	pemFile := "ca.pem"
	{
		exPath, _ := os.Executable()
		exPath = filepath.Dir(exPath)
		keyFile = filepath.Join(exPath, keyFile)
		pemFile = filepath.Join(exPath, pemFile)
	}
	_, err = ec.GenerateCaCertKey(caPri, keyFile, pemFile, []string{"scry"}, []string{"scry"})

	defer func() {
		_ = os.Remove(keyFile)
		_ = os.Remove(pemFile)
	}()

	if err != nil {
		t.Error(err)
	}

	caPri2, err := ec.PrivateKey(keyFile)
	if err != nil {
		t.Error(err)
	}
	if err == nil {
		if caPri.D.Cmp(caPri2.D) != 0 {
			t.Error(err)
		}
	}

	caPub, err := ec.PublicKey(pemFile)
	if err != nil {
		t.Error(err)
	}
	if err == nil {
		if caPri.PublicKey.X.Cmp(caPub.X) != 0 || caPri.PublicKey.Y.Cmp(caPub.Y) != 0 {
			t.Error(err)
		}
	}

}

func TestEcdsa_GenerateCertKey(t *testing.T) {

	ec := &Ecdsa{}

	caPri, err := MakePriKey()
	if err != nil {
		t.Error(err)
	}

	keyFile := "ca.key"
	pemFile := "ca.pem"
	keySub := "sub.key"
	pemSub := "sum.pem"
	{
		exPath, _ := os.Executable()
		exPath = filepath.Dir(exPath)
		keyFile = filepath.Join(exPath, keyFile)
		pemFile = filepath.Join(exPath, pemFile)
		keySub = filepath.Join(exPath, keySub)
		pemSub = filepath.Join(exPath, pemSub)
	}
	ca, err := ec.GenerateCaCertKey(caPri, keyFile, pemFile, []string{"scry"}, []string{"scry"})

	defer func() {
		_ = os.Remove(keyFile)
		_ = os.Remove(pemFile)
	}()

	if err != nil {
		t.Error(err)
	}

	err = ec.GenerateCertKey(ca, caPri, keySub, pemSub, []string{"scry"}, []string{"scry"})
	defer func() {
		_ = os.Remove(keySub)
		_ = os.Remove(pemSub)
	}()
	if err != nil {
		t.Error(err)
	}

	subPri, err := ec.PrivateKey(keySub)
	if err != nil {
		t.Error(err)
	}

	caPub, err := ec.PublicKey(pemSub)
	if err != nil {
		t.Error(err)
	}
	if err == nil {
		if subPri.PublicKey.X.Cmp(caPub.X) != 0 || subPri.PublicKey.Y.Cmp(caPub.Y) != 0 {
			t.Error(err)
		}
	}

}


<|start_filename|>dots/db/redis_client/redis_const.go<|end_filename|>
package redis_client //nolint:golint

const (
	//VersionControlChannelName Version Control Channel Name
	VersionControlChannelName = "version_control"

	//KeySplitChar Key Split Char
	KeySplitChar = ":"
	//CategoryPrefix Category Prefix
	CategoryPrefix = "CV"
	//CategoriesPrefix Categories Prefix
	CategoriesPrefix = "CVS"
)


<|start_filename|>tools/dotconf/data/find_tool.go<|end_filename|>
package data

import (
	"bytes"
	"errors"
	"fmt"
	"go/ast"
	"go/token"
	"golang.org/x/tools/go/packages"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"text/template"
)

//保存返回的组件通用信息
type packageInfo struct {
	absDir          string       //该目录\包的绝对路径
	packageName     string       //正在扫描的包名，需要绝对路径
	astFiles        []*ast.File  //
	ImportDir       string       //导入路径
	Alias           string       //别名
	Funcs           []*FuncOfDot //返回组件普通信息的函数
	isExist         bool         //是否存在返回dot.TypeLives的函数
	ConfigFuncNames []string     //返回组件特有配置信息的函数
	IsExistConfig   bool         //是否存在返回config的函数
}
type FuncOfDot struct {
	FuncName string    //函数名
	IsSlice  bool      //返回值是否是数组
	location token.Pos //函数位置
}

//dirs用户传入的数据
//返回组件数据、不存在的目录信息包括mod依赖目录、错误信息
func FindDots(dirs []string) (data []byte, notExistDir []string, err error) {

	var paths []string //保存有效的目录数据

	//处理目录问题
	{
		//处理掉用户输入的不存在目录
		yesDir, noDir := splitDir(dirs)
		if len(yesDir) == 0 {
			err = errors.New("please enter a valid directory")
			return
		}
		paths = append(paths, yesDir...)
		notExistDir = append(notExistDir, noDir...)
	}

	//得到绝对路径
	{
		for ix := range paths {
			if !filepath.IsAbs(paths[ix]) {
				paths[ix], err = filepath.Abs(paths[ix])
				if err != nil {
					fmt.Println("获取绝对路径出错:", err)
					return
				}
			}
		}
	}

	// 处理重复的目录，原因是多个mod中可能会重复依赖多个项目
	// a\b\c和a\b这类目录不处理
	{
		paths = removeRepByMap(paths)
	}

	// 对于每个子目录通过package.config获取包名，以及当前位置的所有ast.file
	var allInfo []*packageInfo
	{
		//获取一个项目下所有的子目录
		for i := range paths {
			//遍历获取子目录
			dirs = nil
			dirs, err = getAllSonDirs(paths[i])
			if err != nil {
				fmt.Println("获取一个项目下所有的子目录出错：", err)
				return
			}
			//加载路径获取配置信息
			cfg := &packages.Config{
				Mode: packages.LoadSyntax, //不包含依赖,尝试下面这个
				Dir:  paths[i],            //设置当前目录
			}
			var pkginfos []*packages.Package
			pkginfos, err = packages.Load(cfg, dirs...)
			if err != nil {
				fmt.Println("packages.Load err:", err)
				return
			}
			for ix := range dirs {
				pkg := pkginfos[ix]
				astFiles := make([]*ast.File, len(pkg.Syntax))
				for i, file := range pkg.Syntax {
					astFiles[i] = file
				}
				p := packageInfo{
					absDir:      dirs[ix],
					packageName: pkg.Name,
					astFiles:    astFiles,
					ImportDir:   pkg.PkgPath,
				}
				allInfo = append(allInfo, &p)
			}
		}
	}

	//查找[]*packageInfo的每一个对象，根据ast,node判断
	{
		for _, p := range allInfo {
			p.findFuncNodeOnAst(false) //查找*dot.TypeLives和[]*dot.TypeLives
			p.findFuncNodeOnAst(true)  //查找*dot.ConfigTypeLives
		}
	}

	//将满足普通条件的包筛选出来
	var exitFuncInfos []*packageInfo
	{
		//为isExist字段赋值
		{
			for _, p := range allInfo {
				if len(p.Funcs) == 0 {
					//这个目录下没有满足条件的函数
					p.isExist = false
				} else {
					p.isExist = true
				}
			}
		}
		//赋值
		{
			for _, p := range allInfo {
				if p.isExist {
					exitFuncInfos = append(exitFuncInfos, p)
				}
			}
		}

		//检测有没有结果
		{
			if len(exitFuncInfos) == 0 {
				fmt.Println("没有找到符合条件的函数")
				err = errors.New("没有找到符合条件的组件")
				return
			}
		}
	}

	//解决同名包问题-别名
	{
		//存储每个包出现的次数
		map1 := make(map[string]int)
		//赋值
		{
			for _, p := range exitFuncInfos {
				//该包是否已经放入
				if _, ok := map1[p.packageName]; ok {
					//已有
					map1[p.packageName]++
				} else {
					//没有
					map1[p.packageName] = 1
				}
			}
		}
		//利用map1构建别名，只出现一次别名默认为包名
		{
			for _, p := range exitFuncInfos {
				if v, ok := map1[p.packageName]; ok {
					if v == 1 {
						p.Alias = p.packageName
					} else {
						p.Alias = p.packageName + "_" + strconv.Itoa(v)
						map1[p.packageName]--
					}
				}
			}
		}
	}

	//为isExistConfig字段赋值
	{
		for _, p := range exitFuncInfos {
			if len(p.ConfigFuncNames) == 0 {
				//这个目录下没有满足条件的函数
				p.IsExistConfig = false
			} else {
				p.IsExistConfig = true
			}
		}
	}

	//生成代码文件
	{
		buildCode(exitFuncInfos)
	}

	//调用执行callMethod生成序列化的json文件
	{
		//运行生成的代码文件
		{
			cmd := exec.Command("go", "run", "./run_out/callMethod.go")
			err = cmd.Run()
			if err != nil {
				fmt.Printf("Error %v executing command!", err)
				return
			}
		}
		//读取组件信息
		{
			data, err = ioutil.ReadFile("./run_out/result.json")
			if err != nil {
				fmt.Println("File reading error", err)
			}
			return
		}
	}
}

//将目录集合分为两部分，分别是存在的目录和不存在的目录
func splitDir(dirs []string) (existDir, notExistDir []string) {
	for _, dir := range dirs {
		if isDirectory(dir) {
			//该目录已找到
			existDir = append(existDir, dir)
		} else {
			//该目录没找到
			notExistDir = append(notExistDir, dir)
		}
	}
	return
}

//是目录还是文件
func isDirectory(name string) bool {
	if isDirExist(name) {
		info, err := os.Stat(name) //return fileinfo
		if err != nil {
			return false
		}
		return info.IsDir() //true or false
	}
	return false
}

//存不存在
func isDirExist(paths string) bool {
	_, err := os.Stat(paths)
	return err == nil || os.IsExist(err)
}

//解决重复目录
func removeRepByMap(slc []string) []string {
	var result []string
	tempMap := map[string]struct{}{} // 存放不重复主键
	for i := range slc {
		l := len(tempMap)
		tempMap[slc[i]] = struct{}{}
		if len(tempMap) != l { // 加入map后，map长度变化，则元素不重复
			result = append(result, slc[i])
		}
	}
	return result
}

//获取指定目录下的所有子目录
func getAllSonDirs(dirpath string) ([]string, error) {
	var dirList []string
	dirErr := filepath.Walk(dirpath,
		func(path string, f os.FileInfo, err error) error {
			if f == nil {
				return err
			}
			if f.IsDir() && isTrueDir(path) {
				dirList = append(dirList, path)
				return nil
			}
			return nil
		})
	return dirList, dirErr
}

func isTrueDir(path string) bool {
	if strings.Index(path, "node_modules") == -1 {
		if strings.Index(path, ".git") == -1 {
			return true
		} else {
			return false
		}
	} else {
		return false
	}
}

//查找满足条件的函数节点
func (p *packageInfo) findFuncNodeOnAst(isConfig bool) {
	///var FuncNames []string
	for _, astFile := range p.astFiles {
		if astFile == nil {
			break
		}
		ast.Inspect(astFile, func(node ast.Node) bool {
			for {
				//must be a func
				funcNode, ok := node.(*ast.FuncDecl)
				if !ok {
					break //不是函数
				}
				if funcNode.Recv != nil {
					break //排除有接收者的函数
				}
				if !(funcNode.Type.Params.List == nil) {
					break //排除需要参数的函数
				}
				result := funcNode.Type.Results
				if result == nil {
					break //排除没有返回值的函数
				}
				resultList := result.List
				if len(resultList) != 1 {
					break //排除返回值不值一个的函数
				}
				if isConfig {
					b1, _ := returnValueJudgmentOfConfig(resultList[0])
					if !b1 {
						break //排除返回值类型不匹配的函数
					}
					//保存函数信息
					p.ConfigFuncNames = append(p.ConfigFuncNames, funcNode.Name.Name)
				} else {
					b1, b2 := returnValueJudgment(resultList[0])
					if !b1 {
						break //排除返回值类型不匹配的函数
					}
					//保存函数信息
					funcInfo := &FuncOfDot{
						FuncName: funcNode.Name.Name, //函数名
						IsSlice:  b2,
						location: funcNode.Type.Func,
					}
					p.Funcs = append(p.Funcs, funcInfo)
				}
				return true
			}
			return true
		})
	}
}

//查找通用组件信息
//第一个代表函数的返回值是否符合条件
//第二个代表返回值是否是数组
func returnValueJudgment(ret *ast.Field) (bool, bool) {
	retype, ok := (ret.Type).(*ast.StarExpr) //找到*
	if ok {                                  //是一个指针
		x, ok1 := (retype.X).(*ast.SelectorExpr) //有选择器的表达式  a.b
		if !ok1 {
			return false, false //类似*xxx
		}
		xx := x.X.(*ast.Ident)
		xsel := x.Sel.Name
		if xx.Name == "dot" {
			if xsel == "TypeLives" {
				return true, false //返回值是*dot.Typelives
			}
		}
		return false, false //指针指向的结构错误
	}

	retype2, ok := (ret.Type).(*ast.ArrayType)
	if ok { //是一个切片
		elt, ok := (retype2.Elt).(*ast.StarExpr)
		if ok { //切片存放的指针数据
			x, ok1 := (elt.X).(*ast.SelectorExpr) //有选择器的表达式  a.b
			if !ok1 {
				return false, false //类似*xxx
			}
			xx := x.X.(*ast.Ident)
			xsel := x.Sel.Name
			if xx.Name == "dot" {
				if xsel == "TypeLives" {
					return true, true //返回值是[]*dot.Typelives
				}
			}
			return false, false //指针指向的结构错误
		}
		return false, false //切片存放的数据不是指针
	}
	return false, false //返回值类型错误
}

//查找特有组件信息
//第一个代表函数的返回值是否符合条件
//第二个代表返回值是否是数组
func returnValueJudgmentOfConfig(ret *ast.Field) (bool, bool) {
	retype, ok := (ret.Type).(*ast.StarExpr) //找到*
	if ok {                                  //是一个指针
		x, ok1 := (retype.X).(*ast.SelectorExpr) //有选择器的表达式  a.b
		if !ok1 {
			return false, false //类似*xxx
		}
		xx := x.X.(*ast.Ident)
		xsel := x.Sel.Name
		if xx.Name == "dot" {
			if xsel == "ConfigTypeLive" {
				return true, false //返回值是*dot.ConfigTypelives
			}
		}
		return false, false //指针指向的结构错误
	}
	return false, false //返回值类型错误
}

//模板生成
func buildCode(e []*packageInfo) {
	buf := bytes.Buffer{}
	//使用模板
	var filepaths = "./data/file.tmpl"
	filepaths = filepath.FromSlash(filepaths)
	t, err := template.ParseFiles(filepaths)
	if err != nil {
		fmt.Println("parseFileErr err", err)
		return
	}
	err = t.Execute(&buf, e)
	if err != nil {
		fmt.Println("executing template err", err)
		return
	}
	//file
	baseName := "callMethod.go"
	baseName = filepath.Join("./run_out", baseName)
	err = ioutil.WriteFile(baseName, buf.Bytes(), 0777)
	if err != nil {
		fmt.Println("writing callMethod.go err")
		return
	}
}


<|start_filename|>dots/grpc/gserver/etcd_register.go<|end_filename|>
package gserver

//
//import (
//	"github.com/scryinfo/dot/dot"
//	"github.com/scryinfo/dot/dots/grpc/conns"
//	"go.uber.org/zap"
//	"runtime"
//)
//
//const EtcdRegisterTypeID = "c2c90392-ed06-4e7f-ac2a-662b0153ecb5"
//
//type ServerItem struct {
//	Name  string   `json:"name"`
//	Addrs []string `json:"addrs"` //可以对应多个地址
//}
//
////do not config, if the ServerNobl in the current process
//type ConfigEtcdRegister struct {
//	Items []ServerItem
//}
//type EtcdRegister struct {
//	EtcdConns *conns.EtcdConns `dot:""`
//	items     []ServerItem
//	conf      ConfigEtcdRegister
//}
//
////func (c *EtcdRegister) Create(l dot.Line) error {
////	//todo add
////}
////func (c *EtcdRegister) Injected(l dot.Line) error {
////	//todo add
////}
//func (c *EtcdRegister) AfterAllInject(l dot.Line) {
//	if l != nil {
//		var items []ServerItem
//		l.EachLives(func(live *dot.Live, metadata *dot.Metadata) bool {
//			if live == nil {
//				return true
//			}
//			if s, ok := live.Dot.(ServerNobl); ok {
//				items = append(items, s.ServerItem())
//			}
//			return true
//		})
//		nameItems := make(map[string]*ServerItem, len(items)+len(c.conf.Items))
//		putToMap := func(nameMap map[string]*ServerItem, serverItems []ServerItem) {
//			for i := range serverItems {
//				item := &serverItems[i]
//				mapItem := nameMap[item.Name]
//				if mapItem == nil {
//					mapItem = &ServerItem{Name: item.Name}
//					nameMap[item.Name] = mapItem
//				}
//				for _, addr := range item.Addrs {
//					exist := false
//					for _, old := range mapItem.Addrs { //find the new addr
//						if addr == old {
//							exist = true
//							break
//						}
//					}
//					if !exist { //if it new, append it
//						mapItem.Addrs = append(mapItem.Addrs, addr)
//					}
//				}
//			}
//		}
//		putToMap(nameItems, c.conf.Items)
//		putToMap(nameItems, items)
//
//		c.items = make([]ServerItem, 0, len(nameItems))
//		for _, item := range nameItems {
//			c.items = append(c.items, *item)
//		}
//	}
//}
//
////
////func (c *EtcdRegister) Start(ignore bool) error {
////
////}
//
//func (c *EtcdRegister) AfterAllStart() {
//	logger := dot.Logger()
//	if c.EtcdConns != nil {
//		go func() {
//			for i := range c.items {
//				item := &c.items[i]
//				for _, addr := range item.Addrs {
//					err := c.EtcdConns.RegisterServer(c.EtcdConns.Context(), item.Name, addr)
//					if err != nil {
//						logger.Infoln("EtcdRegister", zap.Error(err))
//					}
//				}
//			}
//		}()
//
//		runtime.Gosched() //给goroutine运行机会
//	}
//}
//
//func (c *EtcdRegister) Stop(ignore bool) error {
//	logger := dot.Logger()
//	var err error
//	if c.EtcdConns != nil {
//		for i := range c.items {
//			item := &c.items[i]
//			for _, addr := range item.Addrs {
//				err2 := c.EtcdConns.UnRegisterServer(c.EtcdConns.Context(), item.Name, addr)
//				if err2 != nil {
//					err = err2
//					logger.Infoln("EtcdRegister", zap.Error(err))
//				}
//			}
//		}
//	}
//	return err
//}
//
////func (c *EtcdRegister) Destroy(ignore bool) error {
////
////}
//
////construct dot
//func newEtcdRegister(conf []byte) (dot.Dot, error) {
//	dconf := &ConfigEtcdRegister{}
//	_ = dot.UnMarshalConfig(conf, dconf)
//	//if err != nil {
//	//	return nil, err
//	//}
//
//	d := &EtcdRegister{conf: *dconf}
//	return d, nil
//}
//
////NewEctcRegisterTest for test
//func NewEctcRegisterTest(config *ConfigEtcdRegister) *EtcdRegister {
//	if config == nil {
//		config = &ConfigEtcdRegister{}
//	}
//	d := &EtcdRegister{conf: *config}
//	return d
//}
//
////EtcdRegisterTypeLives
//func EtcdRegisterTypeLives() []*dot.TypeLives {
//	tl := &dot.TypeLives{
//		Meta: dot.Metadata{TypeID: EtcdRegisterTypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
//			return newEtcdRegister(conf)
//		}},
//		Lives: []dot.Live{
//			{
//				LiveID:    EtcdRegisterTypeID,
//				RelyLives: map[string]dot.LiveID{"EtcdConns": conns.EtcdConnsTypeID},
//			},
//		},
//	}
//
//	lives := []*dot.TypeLives{tl}
//	lives = append(lives, conns.EtcdConnsTypeLives()...)
//
//	return lives
//}
//
////EtcdRegisterConfigTypeLive
//func EtcdRegisterConfigTypeLive() *dot.ConfigTypeLive {
//	paths := make([]string, 0)
//	paths = append(paths, "")
//	return &dot.ConfigTypeLive{
//		TypeIDConfig: EtcdRegisterTypeID,
//		ConfigInfo: &ConfigEtcdRegister{
//			Items: []ServerItem{},
//		},
//	}
//}


<|start_filename|>dots/https/server.go<|end_filename|>
package https

import (
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"github.com/pkg/errors"
	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/utils"
	"go.uber.org/zap"
	"io/ioutil"
	"net"
	"net/http"
)

const TypeID = "a998357a-3d92-4390-bd5c-ef6fd6e2ba41"

type config struct {
	Addr string          `json:"addr"` // addr smaple:  ":8080"
	Tls  utils.TlsConfig `json:"tls"`
}

type Server struct {
	conf          config
	httpServer    *http.Server
	defaultHandle http.ServeMux
}

func (c *Server) Stop(ignore bool) (err error) {
	if c.httpServer != nil {
		err = c.httpServer.Close()
		if err != nil {
			dot.Logger().Errorln("Server", zap.Error(err))
		}
	}
	return
}

//construct dot
func newServer(conf []byte) (dot.Dot, error) {
	dconf := &config{}
	err := json.Unmarshal(conf, dconf)
	if err != nil {
		return nil, err
	}

	d := &Server{conf: *dconf}

	return d, err
}

//ServerTypeLives
func ServerTypeLives() []*dot.TypeLives {
	lives := []*dot.TypeLives{
		{
			Meta: dot.Metadata{TypeID: TypeID, NewDoter: func(conf []byte) (dot dot.Dot, err error) {
				return newServer(conf)
			}},
		},
	}
	return lives
}

func ServerConfigTypeLive() *dot.ConfigTypeLive {
	paths := make([]string, 0)
	paths = append(paths, "")
	return &dot.ConfigTypeLive{
		TypeIDConfig: TypeID,
		ConfigInfo:   &config{},
	}
}

func Test(addr string, tls *utils.TlsConfig) *Server {
	s := &Server{conf: config{
		Addr: addr,
	}}
	if tls != nil {
		s.conf.Tls = *tls
	}

	s.AfterAllStart(nil)

	return s
}

func (c *Server) RegisterHandle(pattern string, handle http.Handler) error {
	if handle == nil {
		return errors.New("service is nil")
	}
	c.defaultHandle.Handle(pattern, handle)
	return nil
}

//AfterAllStart run the function after start
func (c *Server) AfterAllStart(l dot.Line) {
	go c.startServer()
}

func (c *Server) startServer() error {
	logger := dot.Logger()

	c.httpServer = &http.Server{Handler: &c.defaultHandle}
	conn, err := net.Listen("tcp", c.conf.Addr)
	if err != nil {
		return err
	}

	var serverRun func() error

	switch {
	case len(c.conf.Tls.CaPem) > 0 && len(c.conf.Tls.Key) > 0 && len(c.conf.Tls.Pem) > 0: //both tls
		caPem := utils.GetFullPathFile(c.conf.Tls.CaPem)
		if len(caPem) < 1 {
			err = errors.New("the caPem is not empty, and can not find the file: " + c.conf.Tls.CaPem)
			logger.Errorln("Server", zap.Error(err))
			return err
		}
		key := utils.GetFullPathFile(c.conf.Tls.Key)
		if len(key) < 1 {
			err = errors.New("the Key is not empty, and can not find the file: " + c.conf.Tls.Key)
			logger.Errorln("Server", zap.Error(err))
			return err
		}

		pem := utils.GetFullPathFile(c.conf.Tls.Pem)
		if len(pem) < 1 {
			err = errors.New("the Pem is not empty, and can not find the file: " + c.conf.Tls.Pem)
			logger.Errorln("Server", zap.Error(err))
			return err
		}

		pool := x509.NewCertPool()
		{
			caCrt, err := ioutil.ReadFile(caPem)
			if err != nil {
				logger.Errorln("Server", zap.Error(err))
				return err
			}
			if !pool.AppendCertsFromPEM(caCrt) {
				err = errors.New("credentials: failed to append certificates")
				logger.Errorln("Server", zap.Error(err))
				return err
			}
		}
		cert, err := tls.LoadX509KeyPair(pem, key)
		if err != nil {
			logger.Errorln("Server", zap.Error(err))
			return err
		}

		c.httpServer.TLSConfig = &tls.Config{
			Certificates: []tls.Certificate{cert},
			ClientCAs:    pool,
			ClientAuth:   tls.RequireAndVerifyClientCert,
		}
		logger.Infoln("Server", zap.String("", "ApiService server(with ca) will start: "+c.conf.Addr))
		serverRun = func() error {
			return c.httpServer.ServeTLS(conn, "", "")
		}
	case len(c.conf.Tls.Key) > 0 && len(c.conf.Tls.Pem) > 0: //just server
		pem := utils.GetFullPathFile(c.conf.Tls.Pem)
		if len(pem) < 1 {
			err = errors.New("the pem is not empty, and can not find the file: " + c.conf.Tls.Pem)
			logger.Errorln("Server", zap.Error(err))
			return err
		}
		key := utils.GetFullPathFile(c.conf.Tls.Key)
		if len(key) < 1 {
			err = errors.New("the key is not empty, and can not find the file: " + c.conf.Tls.Key)
			logger.Errorln("Server", zap.Error(err))
			return err
		}

		c.httpServer.TLSConfig = &tls.Config{
			ClientAuth: tls.NoClientCert,
		}

		logger.Infoln("Server", zap.String("", "ApiService server(no ca) will start: "+c.conf.Addr))
		serverRun = func() error {
			return c.httpServer.ServeTLS(conn, pem, key)
		}
	default: //no tls
		logger.Infoln("Server", zap.String("", "ApiService server(no https) will start: "+c.conf.Addr))
		serverRun = func() error {
			return c.httpServer.Serve(conn)
		}
	}

	go func() {
		e := serverRun()
		if e != nil {
			logger.Infoln("Server", zap.Error(e))
		}
		conn.Close()
	}()

	return nil
}


<|start_filename|>dot/config.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package dot

//LiveConfig live config
type LiveConfig struct {
	//LiveID
	LiveID LiveID `json:"liveId" toml:"liveId" yaml:"liveId"`
	//RelyLives rely lives， If cannot confirm key value then key value is livid value
	RelyLives map[string]LiveID `json:"relyLives" toml:"relyLives" yaml:"relyLives"`
	//dot config
	//todo tag
	Config interface{} `json:"json" toml:"json" yaml:"json"`
}

//MetaLivesConfig dot config
type MetaLivesConfig struct {
	MetaData Metadata     `json:"metaData" toml:"metaData" yaml:"metaData"`
	Lives    []LiveConfig `json:"lives" toml:"lives" yaml:"lives"`
}

//Config config
type Config struct {
	Log  LogConfig         `json:"log" toml:"log" yaml:"log"`
	Dots []MetaLivesConfig `json:"dots" toml:"dots" yaml:"dots"`
}

//FindConfig find config
func (c *Config) FindConfig(typeID TypeID, liveID LiveID) *LiveConfig {
	var lcon *LiveConfig = nil

OutFor:
	for _, dotConfig := range c.Dots {
		if len(typeID.String()) > 0 && typeID != dotConfig.MetaData.TypeID {
			continue
		}

		for _, liveConfig := range dotConfig.Lives {
			if liveConfig.LiveID == liveID || (len(liveConfig.LiveID.String()) < 1 && liveID.String() == dotConfig.MetaData.TypeID.String()) {
				lcon = &liveConfig
				break OutFor
			}
		}
	}

	return lcon
}


<|start_filename|>dots/db/redis_client/redis_client_test.go<|end_filename|>
package redis_client //nolint:golint

import (
	"encoding/json"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func TestRedisClient_GetVersions(t *testing.T) {
	redisClient := GetRedisClient(false)
	assert.NotEqual(t, nil, redisClient)
	category := "test"
	version := "1.0"
	itemKey1 := "tkey"
	value1 := "value1"

	{
		redisClient.SetVersion(category, version)
		getVersion, err := redisClient.GetVersion(category)
		assert.Equal(t, nil, err)
		assert.Equal(t, version, getVersion)
		getVersions, err := redisClient.GetVersions(category)
		assert.Equal(t, nil, err)
		assert.Equal(t, version, getVersions[0])
		time.Sleep(2 * time.Second)
	}

	{
		getValue, err := redisClient.Get(category, version, itemKey1)
		assert.NotNil(t, err)
		assert.Equal(t, "", getValue)
		_, err = redisClient.Set(category, version, itemKey1, value1, 0)
		assert.Equal(t, nil, err)

		getValue, err = redisClient.Get(category, version, itemKey1)
		assert.Equal(t, nil, err)
		assert.Equal(t, value1, getValue)

		count, err := redisClient.Del(category, version, itemKey1)
		assert.Equal(t, nil, err)
		assert.Equal(t, int64(1), count)
		getValue, err = redisClient.Get(category, version, itemKey1)
		assert.NotNil(t, err)
		assert.Equal(t, "", getValue)
	}

	{
		redisClient.Set(category, version, itemKey1, value1, 0)
		err := redisClient.CleanVersion(category, version)
		assert.Equal(t, nil, err)
		getValue, err := redisClient.Get(category, version, itemKey1)
		assert.NotNil(t, err)
		assert.Equal(t, "", getValue)

		getVersion, err := redisClient.GetVersion(category)
		assert.NotNil(t, err)
		assert.Equal(t, "", getVersion)
		getVersions, err := redisClient.GetVersions(category)
		assert.Equal(t, nil, err)
		assert.Equal(t, []string{}, getVersions)
	}

	redisClient = GetRedisClient(true)
	assert.NotEqual(t, nil, redisClient)
	{
		redisClient.SetVersion(category, version)
		getVersion, err := redisClient.GetVersion(category)
		assert.Equal(t, nil, err)
		assert.Equal(t, version, getVersion)
		getVersions, err := redisClient.GetVersions(category)
		assert.Equal(t, nil, err)
		assert.Equal(t, version, getVersions[0])
	}

	{
		getValue, err := redisClient.Get(category, version, itemKey1)
		assert.NotNil(t, err)
		assert.Equal(t, "", getValue)
		_, err = redisClient.Set(category, version, itemKey1, value1, 0)
		assert.Equal(t, nil, err)

		getValue, err = redisClient.Get(category, version, itemKey1)
		assert.Equal(t, nil, err)
		assert.Equal(t, value1, getValue)

		count, err := redisClient.Del(category, version, itemKey1)
		assert.Equal(t, nil, err)
		assert.Equal(t, int64(1), count)
		getValue, err = redisClient.Get(category, version, itemKey1)
		assert.NotNil(t, err)
		assert.Equal(t, "", getValue)
	}

	{
		redisClient.Set(category, version, itemKey1, value1, 0)
		err := redisClient.CleanVersion(category, version)
		assert.Equal(t, nil, err)
		getValue, err := redisClient.Get(category, version, itemKey1)
		assert.NotNil(t, err)
		assert.Equal(t, "", getValue)

		getVersion, err := redisClient.GetVersion(category)
		assert.NotNil(t, err)
		assert.Equal(t, "", getVersion)
		getVersions, err := redisClient.GetVersions(category)
		assert.Equal(t, nil, err)
		assert.Equal(t, []string{}, getVersions)
	}
}

func GetRedisClient(versionFromRedis bool) *RedisClient {
	config := &configRedis{
		Addr:                "127.0.0.1:6379",
		KeepMaxVersionCount: 3,
		VersionFromRedis:    versionFromRedis,
	}
	bs, _ := json.Marshal(config)
	return RedisClientTest(string(bs))
}


<|start_filename|>sample/db/redis_client/redis_sample.go<|end_filename|>
package main

import (
	"fmt"
	"github.com/go-redis/redis/v8"
	"os"
	"strconv"
	"time"

	"go.uber.org/zap"

	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/db/redis_client"
)

const (
	basicDemoKey   = "basic_demo"
	basicDemoValue = "basic value"

	versionControlDemoKey        = "vcd"
	versionControlDemoVersionOne = "1"
	versionControlDemoVersionTwo = "2"
)

type RedisSample struct {
	RedisClient *redis_client.RedisClient `dot:""`
}

func (c *RedisSample) basicDemo() {
	// simulate query in cache first (no result)
	v1, err := c.RedisClient.ClientV8().Get(c.RedisClient.ClientV8().Context(), basicDemoKey).Result()
	if err != redis.Nil {
		fmt.Println("Example: get value not run as suppose, error:", err)
		os.Exit(-1)
	}

	// skip query in db, only simulate update cache
	checkError("Example: set value failed", c.RedisClient.ClientV8().Set(c.RedisClient.ClientV8().Context(), basicDemoKey, basicDemoValue, 0).Err())

	// suppose a request comes now, query in cache (has result)
	v2, err := c.RedisClient.ClientV8().Get(c.RedisClient.ClientV8().Context(), basicDemoKey).Result()
	checkError("Example: get value failed", err)

	time.Sleep(time.Second)
	fmt.Printf("v1: , v2: %s| <- suppose |\n", basicDemoValue)
	fmt.Printf("v1: %s, v2: %s\n", v1, v2)

	fmt.Println("Node: Basic demo passed.")
	fmt.Println("-------")

	return
}

func (c *RedisSample) versionControlDemo() {
	// register
	checkError("Example: set version failed", c.RedisClient.SetVersion(versionControlDemoKey, versionControlDemoVersionOne))

	// wait for subscribe goroutine
	time.Sleep(time.Second)

	// get version
	v, err := c.RedisClient.GetVersion(versionControlDemoKey)
	checkError("Example: get version failed", err)
	fmt.Printf("Version get suppose: %s, actually: %s\n", versionControlDemoVersionOne, v)

	// set(update) version
	checkError("Example: set version failed", c.RedisClient.SetVersion(versionControlDemoKey, versionControlDemoVersionTwo))

	// get version
	v, err = c.RedisClient.GetVersion(versionControlDemoKey)
	checkError("Example: get version failed", err)
	fmt.Printf("Version get suppose: %s, actually: %s\n", versionControlDemoVersionTwo, v)

	// set version 3 times
	for i := 3; i < 6; i++ {
		checkError("Example: set version failed", c.RedisClient.SetVersion(versionControlDemoKey, strconv.Itoa(i)))
	}

	// get all versions
	versions, err := c.RedisClient.GetVersions(versionControlDemoKey)
	checkError("Example: get all versions failed", err)

	fmt.Println("All versions: 5 <- 4 <- 3 <- 2| <- suppose |")
	fmt.Println("All versions:", versions)

	fmt.Println("Node: version control demo passed.")
	fmt.Println("-------")

	return
}

func checkError(msg string, err error) {
	if err != nil {
		dot.Logger().Errorln(msg, zap.NamedError("error", err))
		os.Exit(-1)
	}

	return
}


<|start_filename|>lib/scrypto/ende25519/ende25519_test.go<|end_filename|>
package ende25519

import (
	scrypto2 "github.com/scryinfo/dot/lib/scrypto"
	sx255192 "github.com/scryinfo/dot/lib/scrypto/sx25519"
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestEnde25519(t *testing.T) {
	plaintext := []byte("test data")

	ecdh := sx255192.X25519()
	privateA, publicA, err := ecdh.GenerateKey(nil)
	assert.Equal(t, nil, err)
	privateB, publicB, err := ecdh.GenerateKey(nil)
	assert.Equal(t, nil, err)

	ende := ende25519{}

	ciphertext, err := ende._ecdhEncode(privateA, publicB, plaintext)
	assert.Equal(t, nil, err)

	decodeText, err := ende._ecdhDecode(privateB, publicA, ciphertext)
	assert.Equal(t, nil, err)

	assert.Equal(t, plaintext, decodeText)
}

func TestEnde25519_EcdhDecode(t *testing.T) {

	ecdh := sx255192.X25519()
	privateA, publicA, err := ecdh.GenerateKey(nil)
	assert.Equal(t, nil, err)
	privateB, publicB, err := ecdh.GenerateKey(nil)
	assert.Equal(t, nil, err)

	ende := ende25519{}

	planData := scrypto2.EndeData{
		PublicKey: nil,
		EndeType:  "",
		Signature: nil,
		EnData:    false,
		Body:      []byte("test struct"),
	}
	cipher, err := ende.EcdhEncode(privateA, publicB, planData)
	assert.Equal(t, nil, err)
	assert.Equal(t, cipher.EndeType, endeType)
	publicABytes, err := ecdh.PublicKeyToBytes(publicA)
	assert.Equal(t, nil, err)
	assert.Equal(t, cipher.PublicKey, publicABytes)
	assert.Equal(t, true, cipher.EnData)

	planData2, err := ende.EcdhDecode(privateB, cipher)
	assert.Equal(t, nil, err)
	assert.Equal(t, planData.Body, planData2.Body)
	assert.Equal(t, planData2.EndeType, endeType)
	assert.Equal(t, planData2.PublicKey, publicABytes)
	assert.Equal(t, false, planData2.EnData)
}


<|start_filename|>demo/redis/main.go<|end_filename|>
package main

var dbClient = conn("192.168.1.65:6379")

func main() {
    basicDemo()
    expireDemo()
    updateDemo()
    pubsubDemo()
}


<|start_filename|>demo/redis/set.go<|end_filename|>
package main

import "time"

func setValue(key, value string, expiration ...time.Duration) error {
    var tim time.Duration
    if len(expiration) != 0 {
        tim = expiration[0]
    }

    return dbClient.Set(dbClient.Context(), key, value, tim).Err()
}

func setExpire(key string, expiration time.Duration) error {
    return dbClient.Expire(dbClient.Context(), key, expiration).Err()
}


<|start_filename|>dots/jsonrpc2/handle.go<|end_filename|>
package jsonrpc2

import (
	"bytes"
	"context"
	"encoding/json"
	"github.com/go-kit/kit/transport/http/jsonrpc"
	"github.com/scryinfo/dot/dot"
	"go.uber.org/zap"
	"net/http"
	"reflect"
)

type handle struct {
	service interface{}
	preName string
	handle  *jsonrpc.Server
}

func (h *handle) ServeHTTP(res http.ResponseWriter, req *http.Request) {
	h.handle.ServeHTTP(res, req)
}

func NewHandle(preName string, service interface{}) http.Handler {
	h := &handle{
		service: service,
		preName: preName,
	}
	h.handle = jsonrpc.NewServer(makeJsonrpc(preName, service), jsonrpc.ServerErrorLogger(&rpcLogger{}))
	return h
}

func NewHandles(servives map[string]interface{}) http.Handler {
	methods := jsonrpc.EndpointCodecMap{}
	for k, v := range servives {
		temp := makeJsonrpc(k, v)
		for tk, tv := range temp {
			methods[tk] = tv
		}
	}
	h := jsonrpc.NewServer(methods, jsonrpc.ServerErrorLogger(&rpcLogger{}))
	return h
}

//json rpc的解码函数
func nopDecoder(ctx context.Context, j json.RawMessage) (interface{}, error) {
	return j, nil
}

//json rpc的编码函数
func nopEncoder(ctx context.Context, req interface{}) (json.RawMessage, error) {
	bs, err := json.Marshal(req)
	return bs, err
}

func makeJsonrpc(preName string, server interface{}) jsonrpc.EndpointCodecMap {
	ecm := jsonrpc.EndpointCodecMap{}
	receiver := reflect.ValueOf(server)
	typ := receiver.Type()
	for i := 0; i < receiver.NumMethod(); i++ {
		tmethod := typ.Method(i)
		vmethod := receiver.Method(i)
		if tmethod.PkgPath != "" {
			continue // tmethod not exported
		}
		fn := tmethod.Type
		if fn.NumOut() == 1 && fn.NumIn() == 2 { //只处理单个参数
			endpointCodec := jsonrpc.EndpointCodec{
				Decode: nopDecoder,
				Encode: nopEncoder,
			}
			endpointCodec.Endpoint = func(ctx context.Context, request interface{}) (response interface{}, err error) {
				defer func() {
					if e2 := recover(); e2 != nil {
						response = nil
						err = nil //todo 不太确定 err的具体工作过程， 这里暂定
						dot.Logger().Debugln("ApiService", zap.Any("", e2))
					}
				}()
				inType := fn.In(1)
				inValue := reflect.New(inType)
				bs, ok := request.(json.RawMessage)
				if ok && !bytes.Equal(bs, []byte("[null]")) { //"[null]", 就是 nil
					err = json.Unmarshal(bs, inValue.Interface())
					if err != nil {
						dot.Logger().Errorln("ApiService", zap.Error(err))
						inValue = reflect.New(inType)
					}
				} else {
					inValue = reflect.New(inType)
				}
				rev := vmethod.Call([]reflect.Value{inValue.Elem()})

				response = rev[0].Interface()
				err = nil
				return
			}
			if len(preName) > 0 {
				ecm[preName+tmethod.Name] = endpointCodec
			} else {
				ecm[tmethod.Name] = endpointCodec
			}
		}
	}
	return ecm
}

type rpcLogger struct{}

func (rpcLogger) Log(params ...interface{}) error {
	var err interface{} = params
	if len(params) == 2 {
		err = params[1]
	}
	dot.Logger().Warnln("ApiService rpc", zap.Any("", err))
	return nil
}


<|start_filename|>dots/grpc/lb/round.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package lb

import (
	"google.golang.org/grpc/balancer"
	"google.golang.org/grpc/balancer/base"
	"google.golang.org/grpc/grpclog"
	"math/rand"
	"sync"
	"time"
)

// Name is the name of round_robin balancer.
const Name = Round

// newBuilder creates a new roundrobin balancer builder.
func newBuilder() balancer.Builder {
	return base.NewBalancerBuilder(Name, &rrPickerBuilder{r: rand.New(rand.NewSource(time.Now().UnixNano()))}, base.Config{HealthCheck: true})
}

func init() {
	balancer.Register(newBuilder())
}

type rrPickerBuilder struct {
	r         *rand.Rand
	randMutex sync.Mutex
}

// Intn implements rand.Intn on the rrPickerBuilder source.
func (c *rrPickerBuilder) Intn(n int) int {
	c.randMutex.Lock()
	res := c.r.Intn(n)
	c.randMutex.Unlock()
	return res
}

func (c *rrPickerBuilder) Build(info base.PickerBuildInfo) balancer.Picker {
	grpclog.Infof("roundrobinPicker: newPicker called with readySCs: %v", info)
	if len(info.ReadySCs) == 0 {
		return base.NewErrPickerV2(balancer.ErrNoSubConnAvailable)
	}
	var scs []balancer.SubConn
	for sc := range info.ReadySCs {
		scs = append(scs, sc)
	}
	return &rrPicker{
		subConns: scs,
		// Start at a random index, as the same RR balancer rebuilds a new
		// picker when SubConn states change, and we don't want to apply excess
		// load to the first server in the list.
		next: c.Intn(len(scs)),
	}
}

type rrPicker struct {
	// subConns is the snapshot of the roundrobin balancer when this picker was
	// created. The slice is immutable. Each Get() will do a round robin
	// selection from it and return the selected SubConn.
	subConns []balancer.SubConn

	mu   sync.Mutex
	next int
}

func (c *rrPicker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
	c.mu.Lock()
	sc := c.subConns[c.next]
	c.next = (c.next + 1) % len(c.subConns)
	c.mu.Unlock()
	return balancer.PickResult{SubConn: sc}, nil
}


<|start_filename|>dots/grpc/gserver/interceptor.go<|end_filename|>
// <NAME>.  All rights reserved.
// license that can be found in the license file.

package gserver

import (
	"github.com/scryinfo/dot/dot"
	"go.uber.org/zap"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

// UnaryServerInterceptor returns a new unary server interceptor for panic recovery.
func UnaryServerInterceptor() grpc.UnaryServerInterceptor {
	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (_ interface{}, err error) {
		defer func() {
			if e := recover(); e != nil {
				err = status.Errorf(codes.Internal, "Panic err: %v", e)
				dot.Logger().Errorln("", zap.Error(err))
			}
		}()

		return handler(ctx, req)
	}
}

// StreamServerInterceptor returns a new streaming server interceptor for panic recovery.
func StreamServerInterceptor() grpc.StreamServerInterceptor {
	return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) {
		defer func() {
			if e := recover(); e != nil {
				err = status.Errorf(codes.Internal, "Panic err: %v", e)
				dot.Logger().Errorln("", zap.Error(err))
			}
		}()
		return handler(srv, stream)
	}
}


<|start_filename|>dots/grpc/gserver/server_nobl_mock.go<|end_filename|>
// Code generated by MockGen. DO NOT EDIT.
// Source: ./server_nobl.go

// Package mock is a generated GoMock package.
package gserver

import (
	gomock "github.com/golang/mock/gomock"
	grpc "google.golang.org/grpc"
	reflect "reflect"
)

// MockServerNobl is a mock of ServerNobl interface
type MockServerNobl struct {
	ctrl     *gomock.Controller
	recorder *MockServerNoblMockRecorder
}

// MockServerNoblMockRecorder is the mock recorder for MockServerNobl
type MockServerNoblMockRecorder struct {
	mock *MockServerNobl
}

// NewMockServerNobl creates a new mock instance
func NewMockServerNobl(ctrl *gomock.Controller) *MockServerNobl {
	mock := &MockServerNobl{ctrl: ctrl}
	mock.recorder = &MockServerNoblMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockServerNobl) EXPECT() *MockServerNoblMockRecorder {
	return m.recorder
}

// Server mocks base method
func (m *MockServerNobl) Server() *grpc.Server {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "Server")
	ret0, _ := ret[0].(*grpc.Server)
	return ret0
}

// Server indicates an expected call of Server
func (mr *MockServerNoblMockRecorder) Server() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Server", reflect.TypeOf((*MockServerNobl)(nil).Server))
}

// ServerItem mocks base method
//func (m *MockServerNobl) ServerItem() ServerItem {
//	m.ctrl.T.Helper()
//	ret := m.ctrl.Call(m, "ServerItem")
//	ret0, _ := ret[0].(ServerItem)
//	return ret0
//}

// ServerItem indicates an expected call of ServerItem
//func (mr *MockServerNoblMockRecorder) ServerItem() *gomock.Call {
//	mr.mock.ctrl.T.Helper()
//	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServerItem", reflect.TypeOf((*MockServerNobl)(nil).ServerItem))
//}


<|start_filename|>lib/scrypto/sx25519/x25519_test.go<|end_filename|>
package sx25519

import (
	"encoding/hex"
	"fmt"
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestX25519_ComputeSecret(t *testing.T) {

	ecdh := X25519()

	secret := make([]byte, 32)
	for i := 0; i < 10; i++ {
		privateA, publicA, err := ecdh.GenerateKey(nil)
		assert.Equal(t, nil, err, "A key pair generation failed")

		privateB, publicB, err := ecdh.GenerateKey(nil)
		assert.Equal(t, nil, err, "B key pair generation failed")

		secA, err := ecdh.ComputeSecret(privateA, publicB)
		assert.Equal(t, nil, err, "A compute error")
		secB, err := ecdh.ComputeSecret(privateB, publicA)
		assert.Equal(t, nil, err, "B compute error")

		assert.Equal(t, secA, secB, fmt.Sprintf("DH failed: secrets are not equal:\nA got: %s\nB got: %s", hex.EncodeToString(secA), hex.EncodeToString(secB)))
		assert.NotEqual(t, secret, secA, "DH generates the same secret all the time")
		copy(secret, secA)
	}

}


<|start_filename|>tools/dotconf/data/rpc_imp.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package data

import (
	"context"
	"encoding/json"
	"go.uber.org/zap"
	"io/ioutil"
	"log"
	"os"
	"strings"

	"github.com/BurntSushi/toml"
	"gopkg.in/yaml.v2"

	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/grpc/gserver"
	"github.com/scryinfo/dot/tools/dotconf/data/rpc"
)

const (
	ServerTypeID = "rpcImplement"
)

type RpcImplement struct {
	ServerNobl gserver.ServerNobl `dot:""`
}

func (c *RpcImplement) Start(ignore bool) error {
	rpc.RegisterDotConfigFaceServer(c.ServerNobl.Server(), c)
	return nil
}

//RpcImplementTypeLives make all type lives
func RpcImplementTypeLives() []*dot.TypeLives {
	lives := []*dot.TypeLives{{
		Meta: dot.Metadata{TypeID: ServerTypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
			return &RpcImplement{}, nil
		}},
		Lives: []dot.Live{
			dot.Live{
				LiveID:    ServerTypeID,
				RelyLives: map[string]dot.LiveID{"ServerNobl": gserver.ServerNoblTypeID},
			},
		},
	}}
	lives = append(lives, gserver.ServerNoblTypeLives()...)
	return lives
}

//rpc implement

func (c *RpcImplement) FindDot(_ context.Context, in *rpc.FindReq) (*rpc.FindRes, error) {
	res := &rpc.FindRes{}

	dirs := in.Dirs
	bytes, invalidDirectory, err := FindDots(dirs)
	//删除运行时产生的中间文件
	{
		err := os.Remove("./run_out/callMethod.go")
		err = os.Remove("./run_out/result.json")
		if err != nil {
			dot.Logger().Error(err.Error)
		}
	}
	if err != nil {
		res.Error = err.Error()
	} else {
		res.DotsInfo = string(bytes)
		res.NoExistDirs = invalidDirectory
	}
	return res, nil
}

func (c *RpcImplement) ImportByDot(_ context.Context, in *rpc.ImportReq) (*rpc.ImportRes, error) {

	res := &rpc.ImportRes{}
	data, err := ioutil.ReadFile(in.Filepath)
	if err != nil {
		res.Error = err.Error()
		dot.Logger().Errorln("File reading error", zap.Error(err))
	} else {
		res.Json = string(data)
	}
	return res, nil
}

//支持三种格式json toml yaml
func (c *RpcImplement) ImportByConfig(_ context.Context, im *rpc.ImportReq) (*rpc.ImportRes, error) {
	res := &rpc.ImportRes{}
	config := NewConfig()
	_, err := config.ConfLoad(im.Filepath)
	if err != nil {
		res.Error = err.Error()
		return res, nil
	}
	value, err := config.GetJsonByte("")
	if err != nil {
		res.Error = err.Error()
		return res, nil
	}
	res.Json = string(value)
	return res, nil
}

//获取预置组件
func (c *RpcImplement) InitImport(_ context.Context, im *rpc.ImportReq) (*rpc.ImportRes, error) {
	res := &rpc.ImportRes{}
	data, err := ioutil.ReadFile("./dots.json")
	if err != nil {
		res.Error = err.Error()
		dot.Logger().Errorln("File reading error", zap.Error(err))
	} else {
		res.Json = string(data)
	}
	return res, nil
}

//导出配置信息
//支持三种格式json toml yaml
//由文件名来区分不同格式
func (c *RpcImplement) ExportConfig(_ context.Context, in *rpc.ExportReq) (*rpc.ExportRes, error) {
	var data = in.Configdata
	var target interface{}

	var fileFormat = make(map[string]string)
	{
		for _, value := range in.Filename {
			sliceF := strings.Split(value, ".")
			fileFormat[sliceF[len(sliceF)-1]] = value //[json]filename.json
		}
	}
	{
		//data->map
		if err := json.Unmarshal([]byte(data), &target); err != nil {
			log.Panic(err)
		}
		//map->file
		for key, value := range fileFormat {
			value = "./run_out/" + value
			file, err := os.OpenFile(value, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
			if err != nil {
				dot.Logger().Errorln("an error occurred with file opening or creation")
			}
			switch key {
			case "json":
				enc := json.NewEncoder(file)
				err := enc.Encode(target)
				if err != nil {
					log.Println("Error in encoding json")
				}
			case "yaml":
				enc := yaml.NewEncoder(file)
				err := enc.Encode(target)
				if err != nil {
					log.Println("Error in encoding yaml")
				}
			case "toml":
				enc := toml.NewEncoder(file)
				err := enc.Encode(target)
				if err != nil {
					log.Println("Error in encoding toml")
				}
			}
			if file != nil {
				file.Close()
			}
		}
	}

	return &rpc.ExportRes{}, nil
}

//导出组件信息
//json
func (c *RpcImplement) ExportDot(_ context.Context, in *rpc.ExportReq) (*rpc.ExportRes, error) {
	var data = in.Dotdata
	name := ""
	if in.Filename == nil || len(in.Filename) < 1 {
		//export init dot
		name = "./dots.json"
	} else {
		//normal export
		name = "./run_out/" + in.Filename[0]
	}
	file, err := os.OpenFile(name, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
	if err != nil {
		panic("An error occurred with file opening or creation\n")
	}
	defer file.Close()
	_, err = file.WriteString(data)
	if err != nil {
		panic("writeString err")
	}
	return &rpc.ExportRes{}, nil
}


<|start_filename|>dots/db/pgs/dao_base.go<|end_filename|>
package pgs

import (
	"github.com/go-pg/pg/v10"
	"github.com/go-pg/pg/v10/orm"
	"github.com/scryinfo/dot/dot"
)

const (
	//DaoBaseTypeID type id
	DaoBaseTypeID = "4d6adee7-7c10-4471-8885-a589688bac93"
)

//DaoBase doa base
type DaoBase struct {
	Wrapper *ConnWrapper `dot:""`
}

func (c *DaoBase) getConn() *pg.Conn {
	conn := c.Wrapper.db.Conn()
	return conn
}

//WithTx with transaction, if return err != nil then rollback, or commit the transaction
func (c *DaoBase) WithTx(task func(conn orm.DB) error) error {
	var err error
	if task != nil {
		conn := c.getConn()
		defer conn.Close()
		var tx *pg.Tx
		tx, err = conn.Begin()
		if err == nil {
			defer func() {
				if err == nil {
					err = tx.Commit()
				} else {
					err = tx.Rollback()
				}
			}()
			err = task(tx)
		}
	}
	return err
}

//WithNoTx no transaction
func (c *DaoBase) WithNoTx(task func(conn orm.DB) error) error {
	var err error
	if task != nil {
		conn := c.getConn()
		defer conn.Close()
		err = task(conn)
	}
	return err
}

//DaoBaseTypeLives make all type lives
func DaoBaseTypeLives() []*dot.TypeLives {
	tl := &dot.TypeLives{
		Meta: dot.Metadata{TypeID: DaoBaseTypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
			return &DaoBase{}, nil
		}},
		Lives: []dot.Live{
			{
				LiveID:    DaoBaseTypeID,
				RelyLives: map[string]dot.LiveID{"Wrapper": ConnWrapperTypeID},
			},
		},
	}
	lives := ConnWrapperTypeLives()
	lives = append(lives, tl)
	return lives
}

//GenerateDaoBase this func is for test
func GenerateDaoBase(conf string) *DaoBase {
	wrapper := GenerateConnWrapper(conf)
	base := &DaoBase{wrapper}
	return base
}

//GenerateDaoBaseByDb this func is for test
func GenerateDaoBaseByDb(db *pg.DB) *DaoBase {
	wrapper := GenerateConnWrapperByDb(db)
	base := &DaoBase{wrapper}
	return base
}


<|start_filename|>sample/grpc/proto/build_ts.bat<|end_filename|>

@echo on

set batPath=%~dp0
cd %batPath%
%~d0

cd ../http/client/src/api
set out=%cd%
cd %batPath%
#//mode=grpcwebtext  import_style=commonjs  commonjs+dts
protoc --js_out=import_style=commonjs:%out%/ --grpc-web_out=import_style=commonjs+dts,mode=grpcweb:%out%/ hi.proto

cd %batPath%


<|start_filename|>utils/config.go<|end_filename|>
package utils

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"

	"github.com/pkg/errors"
	"go.uber.org/zap"

	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/scryg/sutils/sfile"
)

func GetFullPathFile(file string) string {
	if filepath.IsAbs(file) {
		return file
	}

	res := ""
	for {
		ex, err := os.Executable()
		if err != nil {
			dot.Logger().Errorln("connsImp", zap.Error(err))
			res = ""
			break
		}

		ex = filepath.Dir(ex)
		temp := filepath.Join(ex, file)
		if sfile.ExistFile(temp) {
			res = temp
			break
		} else { //try find file from the current path
			temp, err = os.Getwd()
			if err != nil {
				dot.Logger().Errorln("connsImp", zap.Error(err))
				res = ""
				break
			}
			temp = filepath.Join(temp, file)
			if sfile.ExistFile(temp) {
				res = temp
				break
			}
		}

		break
	}

	return res
}
func GetTlsConfig(conf *TlsConfig) (*tls.Config, error) {
	if len(conf.CaPem) > 0 && len(conf.Key) > 0 && len(conf.Pem) > 0 { //both tls
		caPemFile := GetFullPathFile(conf.CaPem)
		if len(caPemFile) < 1 {
			return nil, errors.New("the caPem is not empty, and can not find the file: " + conf.CaPem)
		}
		keyFile := GetFullPathFile(conf.Key)
		if len(keyFile) < 1 {
			return nil, errors.New("the Key is not empty, and can not find the file: " + conf.Key)
		}

		pemFile := GetFullPathFile(conf.Pem)
		if len(pemFile) < 1 {
			return nil, errors.New("the Pem is not empty, and can not find the file: " + conf.Pem)
		}

		pool := x509.NewCertPool()
		{
			caCrt, err := ioutil.ReadFile(caPemFile)
			if err != nil {
				return nil, errors.WithStack(err)
			}
			if !pool.AppendCertsFromPEM(caCrt) {
				return nil, errors.New("credentials: failed to append certificates")
			}
		}
		cert, err := tls.LoadX509KeyPair(pemFile, keyFile)
		if err != nil {
			return nil, errors.WithStack(err)
		}
		return &tls.Config{
			ServerName:   conf.ServerNameOverride,
			Certificates: []tls.Certificate{cert},
			RootCAs:      pool, //ClientConn, use the RootCAs
		}, nil
	} else if len(conf.Pem) > 0 { //just server
		pemFile := GetFullPathFile(conf.Pem)
		if len(pemFile) < 1 {
			return nil, errors.New("the Pem is not empty, and can not find the file: " + conf.Pem)
		}
		b, err := ioutil.ReadFile(pemFile)
		if err != nil {
			return nil, err
		}
		cp := x509.NewCertPool()
		if !cp.AppendCertsFromPEM(b) {
			return nil, fmt.Errorf("credentials: failed to append certificates")
		}

		return &tls.Config{ServerName: conf.ServerNameOverride, RootCAs: cp}, nil
	}
	return nil, nil
}


<|start_filename|>tools/ende/decode/decode.go<|end_filename|>
package main

import (
	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/grpc/conns"
	"github.com/scryinfo/dot/dots/line"
	"github.com/scryinfo/dot/tools/ende"
	"github.com/scryinfo/scryg/sutils/ssignal"
	"go.uber.org/zap"
	"os"
)

func main() {
	l, err := line.BuildAndStart(add) //first step create line and dots
	if err != nil {
		dot.Logger().Errorln("", zap.Error(err))
		return
	}
	defer line.StopAndDestroy(l, true) //fourth step stop and destroy dots

	dot.Logger().Infoln("dot ok")
	//second step ....

	dd, _ := l.ToInjecter().GetByLiveID(dot.LiveID(conns.ConnNameTypeID))
	if dd != nil {

	}

	ssignal.WaitCtrlC(func(s os.Signal) bool { //third wait for exit
		return false
	})

}

func add(l dot.Line) error {
	var err error
	err = l.PreAdd(ende.DecodeTypeLives()...)
	return err
}


<|start_filename|>dots/db/pgs/conn_wrapper.go<|end_filename|>
package pgs

import (
	"context"
	"encoding/json"
	"github.com/go-pg/pg/v10"
	"github.com/scryinfo/dot/dot"
)

const (
	//ConnWrapperTypeID type id
	ConnWrapperTypeID = "ffc08507-dd5f-456c-84ea-cdae00b220bf"
)

type config struct {
	Addr     string `json:"addr"`
	User     string `json:"user"`
	Password string `json:"password"`
	Database string `json:"database"`
	ShowSQL  bool   `json:"showSql"`
}

//ConnWrapper connect wrapper
type ConnWrapper struct {
	db   *pg.DB
	conf config
}

func (c *ConnWrapper) Create(dot.Line) error {
	c.db = pg.Connect(&pg.Options{
		Addr:     c.conf.Addr,
		User:     c.conf.User,
		Password: c.conf.Password,
		Database: c.conf.Database,
	})
	if c.conf.ShowSQL {
		c.db.AddQueryHook(pgLogger{})
	}
	return nil
}

func (c *ConnWrapper) AfterAllDestroy(dot.Line) {
	if c.db != nil {
		_ = c.db.Close()
		c.db = nil
	}
}

//GetDb get db
func (c *ConnWrapper) GetDb() *pg.DB {
	return c.db
}

//TestConn test the connect
func (c *ConnWrapper) TestConn() bool {
	n := -1
	_, _ = c.db.QueryOne(pg.Scan(&n), "select 1")
	return n == 1
}

//construct dot
func newConnWrapper(conf []byte) (dot.Dot, error) {
	dconf := &config{}
	err := dot.UnMarshalConfig(conf, dconf)
	if err != nil {
		return nil, err
	}
	d := &ConnWrapper{conf: *dconf}
	return d, err
}

//ConnWrapperTypeLives make all type lives
func ConnWrapperTypeLives() []*dot.TypeLives {
	return []*dot.TypeLives{{
		Meta: dot.Metadata{TypeID: ConnWrapperTypeID, NewDoter: newConnWrapper},
	}}
}

//GenerateConnWrapper this func is for test
func GenerateConnWrapper(conf string) *ConnWrapper {
	conn := &ConnWrapper{}
	_ = json.Unmarshal([]byte(conf), &conn.conf)
	_ = conn.Create(nil)
	return conn
}

//GenerateConnWrapperByDb this func is for test
func GenerateConnWrapperByDb(db *pg.DB) *ConnWrapper {
	conn := &ConnWrapper{db, config{}}
	return conn
}

type pgLogger struct{}

func (d pgLogger) BeforeQuery(c context.Context, _ *pg.QueryEvent) (context.Context, error) {
	return c, nil
}

func (d pgLogger) AfterQuery(_ context.Context, q *pg.QueryEvent) error {
	dot.Logger().Debug(func() string {
		temp, _ := q.FormattedQuery()
		return string(temp)
	})
	return nil
}


<|start_filename|>sample/db/tools/dao/pgs/has_sub_dao_test.go<|end_filename|>
package pgs

import (
	"fmt"
	"github.com/go-pg/pg/v10"
	"github.com/go-pg/pg/v10/orm"
	"github.com/scryinfo/dot/dots/db/pgs"
	"github.com/scryinfo/dot/sample/db/tools/model"
	"github.com/scryinfo/scryg/sutils/uuid"
	"github.com/stretchr/testify/assert"
	"log"
	"testing"
	"time"
)

//const dbconf_test = `{
//			"addr": "localhost:5432",
//			"user": "postgres",
//			"password": "<PASSWORD>",
//			"database": "postgres",
//			"showSql": true
//		}`

func TestHasSubDao(t *testing.T) {
	hasSubDao := &HasSubDao{}
	hasSubDao.DaoBase = pgs.GenerateDaoBase(dbconf_test)
	subDao := &SubDao{DaoBase: hasSubDao.DaoBase}
	err := createHasSub(hasSubDao.DaoBase.Wrapper.GetDb())
	assert.Equal(t, nil, err)

	hasSubDao.DaoBase.WithNoTx(func(conn orm.DB) error {
		hasSub := &model.HasSub{}
		hasSub.SubData = &model.Sub{}
		mReturn, err := hasSubDao.InsertReturn(conn, hasSub)
		assert.Equal(t, nil, err)
		assert.NotEqual(t, nil, mReturn.ID)
		assert.Equal(t, "", mReturn.SubId)
		assert.Equal(t, true, mReturn.SubData == nil)
		err = hasSubDao.DeleteByID(conn, mReturn.ID)
		assert.Equal(t, nil, err)

		hasSub = &model.HasSub{}
		hasSub.SubData = &model.Sub{}
		hasSub.SubData.ID = uuid.GetUuid()
		hasSub.SubId = hasSub.SubData.ID
		mReturn, err = hasSubDao.InsertReturn(conn, hasSub)
		assert.Equal(t, nil, err)
		assert.NotEqual(t, nil, mReturn.ID)
		assert.Equal(t, hasSub.SubId, mReturn.SubId)
		assert.Equal(t, true, mReturn.SubData == nil)
		mInsertSub, err := subDao.InsertReturn(conn, hasSub.SubData)
		assert.Equal(t, nil, err)
		assert.Equal(t, hasSub.SubData.ID, mInsertSub.ID)

		mGet, err := hasSubDao.GetByID(conn, mReturn.ID)
		assert.Equal(t, nil, err)
		assert.Equal(t, mReturn.ID, mGet.ID)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.OptimisticLockVersion, mGet.OptimisticLockVersion)

		ms, err := hasSubDao.Query(conn, "")
		assert.Equal(t, nil, err)
		assert.Equal(t, 1, len(ms))
		mGet = ms[0]
		assert.Equal(t, mReturn.ID, mGet.ID)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.OptimisticLockVersion, mGet.OptimisticLockVersion)

		mGet, err = hasSubDao.QueryOne(conn, "")
		assert.Equal(t, nil, err)
		assert.Equal(t, mReturn.ID, mGet.ID)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.OptimisticLockVersion, mGet.OptimisticLockVersion)

		ms, err = hasSubDao.List(conn)
		assert.Equal(t, nil, err)
		assert.Equal(t, 1, len(ms))
		mGet = ms[0]
		assert.Equal(t, mReturn.ID, mGet.ID)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.OptimisticLockVersion, mGet.OptimisticLockVersion)

		ms, err = hasSubDao.QueryPage(conn, 10, 1, "")
		assert.Equal(t, nil, err)
		assert.Equal(t, 1, len(ms))
		mGet = ms[0]
		assert.Equal(t, mReturn.ID, mGet.ID)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.OptimisticLockVersion, mGet.OptimisticLockVersion)

		ms, count, err := hasSubDao.QueryPageWithCount(conn, 10, 1, "")
		assert.Equal(t, nil, err)
		assert.Equal(t, 1, len(ms))
		assert.Equal(t, 1, count)
		mGet = ms[0]
		assert.Equal(t, mReturn.ID, mGet.ID)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.OptimisticLockVersion, mGet.OptimisticLockVersion)

		time.Sleep(time.Second * 1) //
		err = hasSubDao.Update(conn, mGet)
		assert.Equal(t, nil, err)
		mGet, err = hasSubDao.QueryOne(conn, fmt.Sprintf(" %s = ?", model.Notice_ID), mGet.ID)
		assert.Equal(t, nil, err)
		//assert.Equal(t, 10, mGet.Status)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.NotEqual(t, mReturn.UpdateTime, mGet.UpdateTime)

		mGet.Count = 11
		time.Sleep(time.Second * 1) //
		mReturn, err = hasSubDao.UpdateReturn(conn, mGet)
		assert.Equal(t, nil, err)
		assert.Equal(t, mGet.Count, mReturn.Count)
		assert.Equal(t, 11, mReturn.Count)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)
		mReturn, err = hasSubDao.GetByID(conn, mGet.ID)
		assert.Equal(t, nil, err)
		assert.Equal(t, 11, mReturn.Count)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)

		mGet.Count = 12
		time.Sleep(time.Second * 1) //
		mReturn, err = hasSubDao.UpsertReturn(conn, mGet)
		assert.Equal(t, nil, err)
		assert.Equal(t, 12, mReturn.Count)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)
		return err
	})
}

func createHasSub(db *pg.DB) error {

	err := db.Model((*model.Sub)(nil)).DropTable(&orm.DropTableOptions{IfExists: true, Cascade: true})
	if err != nil {
		log.Print(err)
	}
	err = db.Model((*model.HasSub)(nil)).DropTable(&orm.DropTableOptions{
		IfExists: true,
	})
	if err != nil {
		log.Print(err)
	}
	err = db.Model((*model.Sub)(nil)).CreateTable(nil)
	if err != nil {
		log.Print(err)
	}
	err = db.Model((*model.HasSub)(nil)).CreateTable(nil)
	if err != nil {
		log.Print(err)
	}
	return err
}


<|start_filename|>demo/redis/pubsub.go<|end_filename|>
package main

import (
    "fmt"
    "time"
)

func pubsubDemo() {
    pubsub := dbClient.Subscribe(dbClient.Context(), "mychannel1")

    // Wait for confirmation that subscription is created before publishing anything.
    _, err := pubsub.Receive(dbClient.Context())
    if err != nil {
        panic(err)
    }

    // Go channel which receives messages.
    ch := pubsub.Channel()

    // Publish a message.
    err = dbClient.Publish(dbClient.Context(), "mychannel1", "hello").Err()
    if err != nil {
        panic(err)
    }

    time.AfterFunc(time.Second, func() {
        // When pubsub is closed channel is closed too.
        //_ = pubsub.Close()
    })

    // Consume messages. 阻塞
    for msg := range ch {
        fmt.Println(msg.Channel, msg.Payload)
    }
}


<|start_filename|>lib/scrypto/sx25519/x25519.go<|end_filename|>
package sx25519

import (
	"crypto"
	"crypto/rand"
	"github.com/pkg/errors"
	"github.com/scryinfo/dot/lib/scrypto"
	"golang.org/x/crypto/curve25519"
	"io"
)

func init() {
	scrypto.Ecdhs[string(scrypto.EndeType_X25519)] = X25519()
}

type PrivateKey []byte

func (c PrivateKey) ToBytes(key []byte, err error) {
	var bytes [32]byte
	if ok := checkType(&bytes, c); !ok {
		err = errors.New("unexpected type of public key")
	}
	key = bytes[:]
	return
}

func (c *PrivateKey) ToPrivateKey(keyBytes []byte) (err error) {
	var bytes [32]byte
	if ok := checkType(&bytes, keyBytes); !ok {
		err = errors.New("unexpected type of private keyBytes")
	} else {
		*c = bytes[:]
	}
	return
}

type PublicKey []byte

func (c PublicKey) ToBytes() (key []byte, err error) {
	var bytes [32]byte
	if ok := checkType(&bytes, c); !ok {
		err = errors.New("unexpected type of private key")
	}
	key = bytes[:]
	return
}

func (c *PublicKey) ToPublicKey(keyBytes []byte) (err error) {
	var bytes [32]byte
	if ok := checkType(&bytes, keyBytes); !ok {
		err = errors.New("unexpected type of public keyBytes")
	} else {
		*c = bytes[:]
	}
	return
}

//see: https://github.com/aead/ecdh
type ecdh25519 struct{}

var curve25519Params = scrypto.CurveParameters{
	Name:    "Curve25519",
	BitSize: 255,
}

func X25519() scrypto.Ecdh {
	return ecdh25519{}
}

func (ecdh25519) GenerateKey(random io.Reader) (privateKey crypto.PrivateKey, publicKey crypto.PublicKey, err error) {
	if random == nil {
		random = rand.Reader
	}

	var pri, pub [32]byte
	_, err = io.ReadFull(random, pri[:])
	if err != nil {
		return
	}

	// From https://cr.yp.to/ecdh.html
	pri[0] &= 248
	pri[31] &= 127
	pri[31] |= 64

	curve25519.ScalarBaseMult(&pub, &pri)

	privateKey = pri[:]
	publicKey = pub[:]
	return
}

func (ecdh25519) Parameters() scrypto.CurveParameters { return curve25519Params }

func (ecdh25519) PublicKey(private crypto.PrivateKey) (publicKey crypto.PublicKey, err error) {
	var pri, pub [32]byte
	if ok := checkType(&pri, private); !ok {
		return nil, errors.New("ecdh: unexpected type of private key")
	}

	curve25519.ScalarBaseMult(&pub, &pri)

	publicKey = pub
	return
}

func (ecdh25519) Check(peersPublic crypto.PublicKey) (err error) {
	if ok := checkType(new([32]byte), peersPublic); !ok {
		err = errors.New("unexpected type of peers public key")
	}
	return
}

func (ecdh25519) ComputeSecret(privateKey crypto.PrivateKey, peersPublic crypto.PublicKey) (secret []byte, err error) {
	var pri, pub [32]byte
	if ok := checkType(&pri, privateKey); !ok {
		err = errors.New("ecdh: unexpected type of privateKey key")
		return
	}
	if ok := checkType(&pub, peersPublic); !ok {
		err = errors.New("ecdh: unexpected type of peers public key")
		return
	}
	var sec []byte
	sec, err = curve25519.X25519(pri[:], pub[:])
	//curve25519.ScalarMult(&sec, &pri, &pub)

	secret = sec[:]
	return
}

func (ecdh25519) PublicKeyToBytes(publicKey crypto.PublicKey) (key []byte, err error) {
	var bytes [32]byte
	if ok := checkType(&bytes, publicKey); !ok {
		err = errors.New("unexpected type of public key")
	} else {
		key = bytes[:]
	}
	return
}

func (ecdh25519) PrivateKeyToBytes(privateKey crypto.PrivateKey) (key []byte, err error) {
	var bytes [32]byte
	if ok := checkType(&bytes, privateKey); !ok {
		err = errors.New("unexpected type of private key")
	} else {
		key = bytes[:]
	}
	return
}

func (e ecdh25519) BytesToPublicKey(keyBytes []byte) (publicKey crypto.PublicKey, err error) {
	var bytes [32]byte
	if ok := checkType(&bytes, keyBytes); !ok {
		err = errors.New("unexpected type of public key")
	} else {
		publicKey = bytes[:]
	}
	return
}

func (e ecdh25519) BytesToPrivateKey(keyBytes []byte) (privateKey crypto.PrivateKey, err error) {
	var bytes [32]byte
	if ok := checkType(&bytes, keyBytes); !ok {
		err = errors.New("unexpected type of private key")
	} else {
		privateKey = bytes[:]
	}
	return
}

func checkType(key *[32]byte, typeToCheck interface{}) (ok bool) {
	switch t := typeToCheck.(type) {
	case [32]byte:
		copy(key[:], t[:])
		ok = true
	case *[32]byte:
		copy(key[:], t[:])
		ok = true
	case PublicKey:
		if len(t) == 32 {
			copy(key[:], t)
			ok = true
		}
	case PrivateKey:
		if len(t) == 32 {
			copy(key[:], t)
			ok = true
		}
	case []byte:
		if len(t) == 32 {
			copy(key[:], t)
			ok = true
		}
	case *[]byte:
		if len(*t) == 32 {
			copy(key[:], *t)
			ok = true
		}
	}
	return
}


<|start_filename|>dot/lines.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package dot

var defaultLine Line

//GetDefaultLine Return default Line，general program only has one line
func GetDefaultLine() Line {
	return defaultLine
}

//SetDefaultLine Set default line
func SetDefaultLine(line Line) {
	defaultLine = line
}


<|start_filename|>lib/scrypto/ende.go<|end_filename|>
package scrypto

import (
	"crypto"
	"crypto/ed25519"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"github.com/pkg/errors"
)

type AsymmetricDecoder interface {
	// EcdhDecode
	// EndeData中已经包含peersKey，所以没有出现在参数中
	EcdhDecode(privateKey crypto.PrivateKey, cipher *EndeData) (plain EndeData, err error)
}

type AsymmetricEncoder interface {
	EcdhEncode(privateKey crypto.PrivateKey, peersKey crypto.PublicKey, plain *EndeData) (cipher EndeData, err error)
}

type EndeType string

const (
	EndeType_X25519 EndeType = "x25519"
)

//以下值只会在init中进行修改，所以认为是安全的
var (
	Encoders = make(map[EndeType]AsymmetricEncoder, 2)
	Decoders = make(map[EndeType]AsymmetricDecoder, 2)
)

type EndeData struct {
	//加密时使用的公钥
	PublicKey []byte
	EndeType  EndeType
	//对Body的签名，
	Signature []byte
	//ed25519不能从签名出计算出公钥，所以需要来验证签名。在使用中双方也可以约定公钥，并不一定要存放在字段中
	SignedPublicKey []byte
	//true数据已加密
	EnData bool
	//数据
	Body []byte
}

type endeData struct {
	PublicKey       string //hex
	EndeType        string
	Signature       string //hex
	SignedPublicKey string //hex
	EnData          bool
	Body            string //base64
}

func (c *EndeData) UnmarshalJSON(b []byte) error {
	var data endeData
	if err := json.Unmarshal(b, &data); err != nil {
		return err
	}
	return c.toEndeData(&data)
}

func (c EndeData) MarshalJSON() ([]byte, error) {
	to := toJsonEndeData(&c)
	return json.Marshal(to)
}

func toJsonEndeData(data *EndeData) (to endeData) {
	to.PublicKey = hex.EncodeToString(data.PublicKey)
	to.EndeType = string(data.EndeType)
	to.Signature = hex.EncodeToString(data.Signature)
	to.SignedPublicKey = hex.EncodeToString(data.SignedPublicKey)
	to.EnData = data.EnData
	to.Body = base64.StdEncoding.EncodeToString(data.Body)
	return
}

func (c *EndeData) toEndeData(data *endeData) (err error) {
	c.PublicKey, err = hex.DecodeString(data.PublicKey)
	if err != nil {
		return
	}
	c.EndeType = EndeType(data.EndeType)
	if err != nil {
		return
	}
	c.Signature, err = hex.DecodeString(data.Signature)
	if err != nil {
		return
	}
	c.SignedPublicKey, err = hex.DecodeString(data.SignedPublicKey)
	if err != nil {
		return
	}
	c.EnData = data.EnData
	c.Body, err = base64.StdEncoding.DecodeString(data.Body)
	if err != nil {
		return
	}
	return
}

func GetAsymmetricDecoder(data *EndeData) AsymmetricDecoder {
	var re AsymmetricDecoder = nil
	if v, ok := Decoders[data.EndeType]; ok {
		re = v
	}
	return re
}

func GetAsymmetricEncoder(data *EndeData) AsymmetricEncoder {
	var re AsymmetricEncoder = nil
	if v, ok := Encoders[data.EndeType]; ok {
		re = v
	}
	return re
}

func ToSigningHash(data []byte) (hash []byte) {
	h251 := sha256.New()
	if len(data) > 0 {
		h251.Write(data)
	}
	first := h251.Sum(nil)
	h251.Reset()
	h251.Write(first) //两次hash
	return h251.Sum(nil)
}

func SignEd25519(privateKey ed25519.PrivateKey, hash []byte) (signature []byte, publicBytes []byte) {
	signature = ed25519.Sign(privateKey, hash)
	publicBytes = privateKey.Public().(ed25519.PublicKey)
	return
}

func EncodeData(plain *EndeData, peerKey crypto.PublicKey, signedKey ed25519.PrivateKey) (cipher EndeData, err error) {
	cipher = *plain
	if signedKey != nil {
		cipher.Signature, cipher.SignedPublicKey = SignEd25519(signedKey, ToSigningHash(plain.Body))
	}
	ecdh := GetEcdh(&cipher)
	privateKey, _, err := ecdh.GenerateKey(nil)
	if err != nil {
		return
	}
	encoder := GetAsymmetricEncoder(&cipher)
	cipher, err = encoder.EcdhEncode(privateKey, peerKey, &cipher)
	if err != nil {
		return
	}

	return
}
func DecodeData(cipher *EndeData, privateKey crypto.PrivateKey, signedPublicKey ed25519.PublicKey) (plain EndeData, err error) {
	plain = *cipher
	encoder := GetAsymmetricDecoder(&plain)
	plain, err = encoder.EcdhDecode(privateKey, &plain)
	if err != nil {
		return
	}

	if signedPublicKey != nil { //verify
		hash := ToSigningHash(plain.Body)
		if !signedPublicKey.Equal(ed25519.PublicKey(plain.SignedPublicKey)) || !ed25519.Verify(plain.SignedPublicKey, hash, plain.Signature) {
			err = errors.New("failed to verify signature")
			return
		}
	}

	return
}


<|start_filename|>demo/redis/orm/main.go<|end_filename|>
package main

import (
	"fmt"
	"github.com/albrow/zoom"
)

type S struct {
	Str string `redis:"key_string"`
	I   int    `redis:"key_int"`
	zoom.RandomID
}

var (
	url = "192.168.1.65:6379"

	pool = zoom.NewPool(url)
	sc   *zoom.Collection

	err error
)

// zoom has nothing about key expire
func main() {
	defer pool.Close()

	NewCollection()

	// Attention: all demo are under collection 'sc'.

	var i int
	i, err = sc.DeleteAll()
	if err != nil {
		fmt.Println("delete all failed, error:", err)
	}
	fmt.Println("del items:", i)

	setSomeValues(3)

	// save
	sInsSave := &S{Str: "zoom demo", I: -1}
	save(sc, sInsSave)

	// update certain fields
	sInsSave.Str = "update"
	update(sInsSave)

	// find
	sInsFind := find(sInsSave.ID)
	fmt.Printf("Node: show find res, %#v\n", sInsFind)

	// find certain fields, attention on 'S.I' item, is default value
	sInsFind2 := findCertain(sInsSave.ID, []string{"Str"})
	fmt.Printf("Node: show find certain fields res, %#v\n", sInsFind2)

	// find all and count
	findAll()

	// del
	del(sInsSave.ID)

	findAll()

	// 关于zoom条件查询与事务的写法：
	// https://github.com/albrow/zoom#using-query-modifiers
	// https://github.com/albrow/zoom#transactions
}


<|start_filename|>demo/redis/get.go<|end_filename|>
package main

func getValue(key string) (string, error) {
    return dbClient.Get(dbClient.Context(), key).Result()
}


<|start_filename|>dot/dot.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package dot

import (
	"reflect"
)

//TypeID dot type guid
type TypeID string

//LiveID dot live guid
type LiveID string

//String convert typeid to string
func (c *TypeID) String() string {
	return string(*c)
}

//String convert liveid to string
func (c *LiveID) String() string {
	return string(*c)
}

//Event dot event
type Event = func(live *Live, l Line)

//Events dot events
type Events struct {
	//Before the dot create
	BeforeCreate Event
	//after the dot create
	AfterCreate Event
	//Before the dot start
	BeforeStart Event
	//After the dot start
	AfterStart Event
	//Before the dot stop
	BeforeStop Event
	//After the dot stop
	AfterStop Event
	//Before the dot destroy
	BeforeDestroy Event
	//After the dot destroy
	AfterDestroy Event
}

//TypeEvents dot events for type
type TypeEvents = Events

//LiveEvents dot events for live
type LiveEvents = Events

//Eventer event interface
type Eventer interface {
	//
	ReSetLiveEvents(lid LiveID, liveEvents *LiveEvents)
	//
	AddLiveEvents(lid LiveID, liveEvents *LiveEvents)
	//
	LiveEvents(lid LiveID) []LiveEvents
	//
	ReSetTypeEvents(tid TypeID, typeEvents *TypeEvents)
	//
	AddTypeEvents(tid TypeID, typeEvents *TypeEvents)
	//
	TypeEvents(tid TypeID) []TypeEvents
}

//Metadata dot metadata
type Metadata struct {
	TypeID      TypeID       `json:"typeId"`
	Version     string       `json:"version"`
	Name        string       `json:"name"`
	ShowName    string       `json:"showName"`
	Single      bool         `json:"single"`
	RelyTypeIDs []TypeID     `json:"relyTypeIds"`
	NewDoter    Newer        `json:"-"`
	RefType     reflect.Type `json:"-"` //if the dot is interface, set the type of interface
}

//Live live/instance
type Live struct {
	TypeID    TypeID            `json:"typeId"`
	LiveID    LiveID            `json:"liveId"`
	RelyLives map[string]LiveID `json:"relyLives"`
	Dot       Dot               `json:"-"`
}

//Clone clone Metadata
func (m *Metadata) Clone() *Metadata {
	c := *m
	c.RelyTypeIDs = append(m.RelyTypeIDs[:0:0], m.RelyTypeIDs...)
	return &c
}

//Merge merge metadata
func (m *Metadata) Merge(m2 *Metadata) {
	if len(m2.TypeID) > 0 {
		m.TypeID = m2.TypeID
	}
	if len(m2.Version) > 0 {
		m.Version = m2.Version
	}
	if len(m2.Name) > 0 {
		m.Name = m2.Name
	}
	if len(m2.ShowName) > 0 {
		m.ShowName = m2.ShowName
	}
	m.Single = m2.Single
	if len(m2.RelyTypeIDs) > 0 {
		mergeIDs := make([]TypeID, 0, len(m.RelyTypeIDs)+len(m2.RelyTypeIDs))
		mergeIDs = append(mergeIDs, m.RelyTypeIDs...)
		hasID := make(map[TypeID]bool, cap(mergeIDs))
		for i := range m.RelyTypeIDs {
			hasID[m.RelyTypeIDs[i]] = true
		}

		for _, relyTypeID := range m2.RelyTypeIDs {
			if _, ok := hasID[relyTypeID]; !ok {
				hasID[relyTypeID] = true
				mergeIDs = append(mergeIDs, relyTypeID)
			}
		}
		m.RelyTypeIDs = mergeIDs[:]
	}
	if m2.NewDoter != nil {
		m.NewDoter = m2.NewDoter
	}
	if m2.RefType != nil {
		m.RefType = m2.RefType
	}
}

//NewDot new a dot
func (m *Metadata) NewDot(args []byte) (dot Dot, err error) {
	dot = nil
	err = nil
	if m.NewDoter != nil {
		dot, err = m.NewDoter(args)
	} else if m.RefType != nil {
		v := reflect.New(m.RefType)
		dot = v.Interface()
	}
	return
}

//Newer instance for new dot
type Newer = func(args []byte) (dot Dot, err error)

//Dot component
type Dot interface{}

//Lifer life cycle
// Create, Start,Stop,Destroy
// Create and Start are separate, in order to resolve the dependencies between different dot instances,
// if there is no problem with the dependencies, then you can directly null in Start
// All methods of Lifer cannot be stucked while running, now the realization of line is sync call
type Lifer interface {
	Creator
	Starter
	Stopper
	Destroyer
}

//Creator create interface
type Creator interface {
	//Create When this method is initializing, running or monitoring same content, better to realize it in Start method
	Create(l Line) error
}

//Injected inject interface
type Injected interface {
	//Injected call the function after inject
	Injected(l Line) error
}

//Starter start interface
type Starter interface {
	//ignore When calling other Lifer, if true erred will continue, if false erred will return directly
	Start(ignore bool) error
}

//Stopper stop interface
type Stopper interface {
	//ignore When calling other Lifer, if true erred will continue, if false erred will return directly
	Stop(ignore bool) error
}

//Destroyer destroy interface
type Destroyer interface {
	//Destroy Dot
	//ignore When calling other Lifer, if true erred will continue, if false erred will return directly
	Destroy(ignore bool) error
}

//Tager dot signature data, used by dot
type Tager interface {
	//SetTag set tag
	SetTag(tag interface{})
	//GetTag get tag
	GetTag() (tag interface{})
}

//GetInterfaceType return the interface of dot
type GetInterfaceType interface {
	//get interface type
	GetInterfaceType() reflect.Type
}

//StatusType status type
type StatusType int

//Statuser Status
type Statuser interface {
	Status() StatusType
}

//HotConfig hot change config
type HotConfig interface {
	//Update Update config info, return true means successful
	HotConfig(newConf SConfig) bool
}

//Checker Check dot，run some verification or test data, return the result
type Checker interface {
	Check(args interface{}) interface{}
}

const (
	//TagDot tag dot
	TagDot = "dot"
	//CanNull allow nil, if do not find the dot , set it nil
	CanNull = "?"
)


<|start_filename|>dots/grpc/lb/etcd_service.go<|end_filename|>
package lb
//
//import (
//	"go.etcd.io/etcd/client/v3/embed"
//
//	"github.com/scryinfo/dot/dot"
//	"github.com/scryinfo/dot/utils"
//)
//
//const EtcdServiceTypeID = "59b10f33-4f8b-40b9-9912-02068f78c228"
//
//type configEtcdService struct {
//	Pears     []string        `json:"endpoints"`
//	TlsClient utils.TlsConfig `json:"tls"`
//}
//type EtcdService struct {
//	etcd *embed.Etcd
//	conf configEtcdService
//	//todo add
//}
//
////func (c *EtcdService) Create(l dot.Line) error {
////	//todo add
////}
////func (c *EtcdService) Injected(l dot.Line) error {
////	//todo add
////}
////func (c *EtcdService) AfterAllInject(l dot.Line) {
////	//todo add
////}
////
////func (c *EtcdService) Start(ignore bool) error {
////	//todo add
////}
////
////func (c *EtcdService) Stop(ignore bool) error {
////	//todo add
////}
//
//func (c *EtcdService) Destroy(ignore bool) error {
//
//	if c.etcd != nil {
//		c.etcd.Close()
//	}
//
//	return nil
//}
//
////construct dot
//func newEtcdService(conf []byte) (dot.Dot, error) {
//	dconf := &configEtcdService{}
//
//	err := dot.UnMarshalConfig(conf, dconf)
//	if err != nil {
//		return nil, err
//	}
//
//	d := &EtcdService{conf: *dconf}
//
//	cfg := embed.NewConfig()
//	cfg.Dir = "etcd"
//	d.etcd, err = embed.StartEtcd(cfg) //todo how to set the logger
//	if err != nil {
//		d.etcd = nil
//		return nil, err
//	}
//
//	return d, nil
//}
//
////EtcdServiceTypeLives
//func EtcdServiceTypeLives() []*dot.TypeLives {
//	tl := &dot.TypeLives{
//		Meta: dot.Metadata{TypeID: EtcdServiceTypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
//			return newEtcdService(conf)
//		}},
//		//Lives: []dot.Live{
//		//	{
//		//		LiveID:    EtcdServiceTypeID,
//		//		RelyLives: map[string]dot.LiveID{"some field": "some id"},
//		//	},
//		//},
//	}
//
//	lives := []*dot.TypeLives{tl}
//
//	return lives
//}
//
////EtcdServiceConfigTypeLive
//func EtcdServiceConfigTypeLive() *dot.ConfigTypeLive {
//	paths := make([]string, 0)
//	paths = append(paths, "")
//	return &dot.ConfigTypeLive{
//		TypeIDConfig: EtcdServiceTypeID,
//		ConfigInfo:   &configEtcdService{
//			//todo
//		},
//	}
//}


<|start_filename|>tools/dotcli/dotcli.go<|end_filename|>
package main

import (
	"bytes"
	"flag"
	"fmt"
	"github.com/scryinfo/dot/dots/db/pgs"
	"github.com/scryinfo/scryg/sutils/uuid"
	"go/format"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
	"text/template"
)

const templateStr = `
package {{$.Package}}
import "github.com/scryinfo/dot/dot"
const {{$.Name}}TypeID = "{{$.ID}}"
type config{{$.Name}} struct {
	//todo add
}
type {{$.Name}} struct {
	conf config{{$.Name}}
	//todo add
}
//func (c *{{$.Name}}) Create(l dot.Line) error {
//	
//}
//func (c *{{$.Name}}) Injected(l dot.Line) error {
//	
//}
//func (c *{{$.Name}}) AfterAllInject(l dot.Line) {
//	
//}
//
//func (c *{{$.Name}}) Start(ignore bool) error {
//	
//}
//
//func (c *{{$.Name}}) Stop(ignore bool) error {
//	
//}
//
//func (c *{{$.Name}}) Destroy(ignore bool) error {
//	
//}

//construct dot
func new{{$.Name}}(conf []byte) (dot.Dot, error) {
	dconf := &config{{$.Name}}{}
	
	//err := dot.UnMarshalConfig(conf, dconf)
	//if err != nil {
	//	return nil, err
	//}

	d := &{{$.Name}}{conf: *dconf}

	return d, nil
}

//{{$.Name}}TypeLives
func {{$.Name}}TypeLives() []*dot.TypeLives {
	tl := &dot.TypeLives{
		Meta: dot.Metadata{TypeID: {{$.Name}}TypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
			return new{{$.Name}}(conf)
		}},
		//Lives: []dot.Live{
		//	{
		//		LiveID:    {{$.Name}}TypeID,
		//		RelyLives: map[string]dot.LiveID{"some field": "some id"},
		//	},
		//},
	}

	lives := []*dot.TypeLives{tl}

	return lives
}

//{{$.Name}}ConfigTypeLive
func {{$.Name}}ConfigTypeLive() *dot.ConfigTypeLive {
	paths := make([]string, 0)
	paths = append(paths, "")
	return &dot.ConfigTypeLive{
		TypeIDConfig: {{$.Name}}TypeID,
		ConfigInfo: &config{{$.Name}}{
			//todo
		},
	}
}
`

type tData struct {
	Name      string
	ID        string
	Config    bool //default true
	Package   string
	BackQuote string
}

var help bool = false

func parms(data *tData) {
	flag.StringVar(&data.Name, "name", "AnyName", "struct name")
	flag.StringVar(&data.ID, "id", "", "dot id, if not set, will make a new")
	//flag.BoolVar(&data.Config, "config", true, "")
	flag.StringVar(&data.Package, "package", "", "package name")

	flag.BoolVar(&help, "h", false, "")

	flag.Parse()
	if len(data.ID) < 1 {
		data.ID = uuid.GetUuid()
	}
	if len(data.Package) < 1 {
		curPath, err := os.Getwd()
		if err == nil {
			data.Package = filepath.Base(curPath)
		}
	}

	if len(data.Package) < 1 {
		data.Package = "dot"
	}
}

func main() {
	log.Println("run dotcli")
	data := &tData{BackQuote: "`"}
	parms(data)

	if help {
		flag.PrintDefaults()
		return
	}

	src := gdao(data)

	outputName := ""
	{
		types := pgs.Underscore(data.Name)
		baseName := fmt.Sprintf("%s.go", types)
		outputName = filepath.Join(".", strings.ToLower(baseName))
	}

	if _, err := os.Stat(outputName); os.IsNotExist(err) {
		err := ioutil.WriteFile(outputName, src, 0644)
		if err != nil {
			log.Fatalf("writing output: %s", err)
		}
	} else {
		log.Println("exist the file: " + outputName)
	}

	log.Println("finished dotcli")
}

func gdao(data *tData) []byte {

	temp := templateStr
	var src []byte = nil
	{
		t, err := template.New("").Parse(temp)
		if err != nil {
			log.Fatal(err)
		}
		buff := bytes.NewBufferString("")
		err = t.Execute(buff, data)
		if err != nil {
			log.Fatal(err)
		}

		src, err = format.Source(buff.Bytes())
		if err != nil {
			log.Fatal(err)
		}
	}
	return src
}


<|start_filename|>sample/db/tools/model/sub_model.go<|end_filename|>
package model

import (
	"fmt"
	"github.com/scryinfo/dot/dots/db/pgs"
)

const (
	Sub_Table                 = "subs"
	Sub_Struct                = "sub"
	Sub_ID                    = "id"
	Sub_UpdateTime            = "update_time"
	Sub_CreateTime            = "create_time"
	Sub_OptimisticLockVersion = "optimistic_lock_version"
	Sub_Name                  = "name"
)

func (m *Sub) String() string {
	//todo please change the format string
	//m.ID, m.UpdateTime, m.CreateTime, m.OptimisticLockVersion, m.Name,
	str := fmt.Sprintf("Sub<%s %s >",
		m.ID, m.Name,
	)
	return str
}

func (m *Sub) ToMap() map[string]string {
	res := pgs.ToMap(m, map[string]bool{})
	return res
}

func (m *Sub) ToUpsertSet() []string {
	res := []string{
		fmt.Sprintf("%s = EXCLUDED.%s", Sub_ID, Sub_ID),
		fmt.Sprintf("%s = EXCLUDED.%s", Sub_UpdateTime, Sub_UpdateTime),
		fmt.Sprintf("%s = EXCLUDED.%s", Sub_CreateTime, Sub_CreateTime),
		fmt.Sprintf("%s = EXCLUDED.%s", Sub_OptimisticLockVersion, Sub_OptimisticLockVersion),
		fmt.Sprintf("%s = EXCLUDED.%s", Sub_Name, Sub_Name),
	}
	return res
}


<|start_filename|>dots/certificate/ecdsa.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package certificate

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/pem"
	"github.com/pkg/errors"
	"io/ioutil"
	"math/big"
	"os"
	"path/filepath"
	"time"

	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/scryg/sutils/sfile"
)

const (
	//EcdsaTypeID type id of dot
	EcdsaTypeID = "4b8b1751-4799-4578-af46-d9b339cf582f"
)

//Ecdsa dot
type Ecdsa struct {
}

func newEcdsa(conf []byte) (dot.Dot, error) {
	var err error = nil
	_ = conf
	d := &Ecdsa{}
	return d, err
}

//EcdsaTypeLives return type lives
func EcdsaTypeLives() []*dot.TypeLives {
	return []*dot.TypeLives{{
		Meta: dot.Metadata{TypeID: EcdsaTypeID, NewDoter: func(conf []byte) (dot dot.Dot, err error) {
			return newEcdsa(conf)
		}}},
	}
}

//GenerateCaCertKey Generate ca certificate and private key
// keyFile private key, pemFile ca certificate file
func (c *Ecdsa) GenerateCaCertKey(caPri *ecdsa.PrivateKey, keyFile string, pemFile string, dnsName []string, orgName []string) (ca *x509.Certificate, err error) {

	var serialNumber *big.Int = nil
	serialNumber, err = c.makeSerialNumber()

	ca = &x509.Certificate{
		SerialNumber: serialNumber,
		Subject: pkix.Name{
			Country:       []string{"cn"},
			Locality:      []string{"scry"},
			Province:      []string{"scry"},
			Organization:  orgName,
			StreetAddress: []string{"scry"},
			PostalCode:    []string{"scry"},
			CommonName:    "scry",
		},
		DNSNames:              dnsName,
		NotBefore:             time.Now(),
		NotAfter:              time.Now().AddDate(100, 0, 0),
		BasicConstraintsValid: true,
		IsCA:                  true,
		SignatureAlgorithm:    x509.ECDSAWithSHA256,
		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
	}

	{
		var certBytes []byte = nil
		pub := &caPri.PublicKey
		certBytes, err = x509.CreateCertificate(rand.Reader, ca, ca, pub, caPri)
		if err != nil {
			return nil, err
		}

		file := ""
		file, err = exPathFileAndMakeDirs(pemFile)
		if err != nil {
			return nil, err
		}
		certOut, err := os.Create(file)
		if err != nil {
			return nil, err
		}
		defer certOut.Close()
		if err = pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: certBytes}); err != nil {
			return nil, err
		}
	}
	{
		var privBytes []byte = nil
		if privBytes, err = x509.MarshalECPrivateKey(caPri); err != nil {
			return nil, err
		}
		file := ""
		file, err = exPathFileAndMakeDirs(keyFile)
		if err != nil {
			return nil, err
		}
		keyOut, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
		if err != nil {
			return nil, err
		}
		defer keyOut.Close()
		if err = pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: privBytes}); err != nil {
			return nil, err
		}
	}

	return ca, err
}

//GenerateCertKey Generate subcertificate and private key
// keyFile private file, pemFile subcertificate file
func (c *Ecdsa) GenerateCertKey(caParent *x509.Certificate, caPri *ecdsa.PrivateKey, keyFile string, pemFile string, dnsName []string, orgName []string) (err error) {
	var serialNumber *big.Int = nil
	serialNumber, err = c.makeSerialNumber()
	cert := &x509.Certificate{
		SerialNumber: serialNumber,
		Subject: pkix.Name{
			Country:       []string{"cn"},
			Locality:      []string{"scry"},
			Province:      []string{"scry"},
			Organization:  orgName,
			StreetAddress: []string{"scry"},
			PostalCode:    []string{"scry"},
			CommonName:    "scry",
		},
		DNSNames:           dnsName,
		NotBefore:          time.Now(),
		NotAfter:           time.Now().AddDate(100, 0, 0),
		SignatureAlgorithm: x509.ECDSAWithSHA256,
		ExtKeyUsage:        []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
		KeyUsage:           x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
	}

	priv, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)

	{
		pub := &priv.PublicKey
		certBytes, err := x509.CreateCertificate(rand.Reader, cert, caParent, pub, caPri)
		if err != nil {
			return err
		}

		file := ""
		file, err = exPathFileAndMakeDirs(pemFile)
		if err != nil {
			return err
		}
		certOut, err := os.Create(file)
		if err != nil {
			return err
		}
		defer certOut.Close()
		if err = pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: certBytes}); err != nil {
			return err
		}
	}

	{
		var privBytes []byte = nil
		if privBytes, err = x509.MarshalECPrivateKey(priv); err != nil {
			return err
		}
		file := ""
		file, err = exPathFileAndMakeDirs(keyFile)
		if err != nil {
			return err
		}
		keyOut, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
		if err != nil {
			return err
		}
		defer keyOut.Close()
		if err = pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: privBytes}); err != nil {
			return err
		}
	}

	return err
}

//PrivateKey Read private key from keyFile
func (c *Ecdsa) PrivateKey(keyFile string) (pri *ecdsa.PrivateKey, err error) {

	file, err := exPathFile(keyFile)

	if err != nil || len(file) < 1 {
		return nil, errors.New("file do not exist")
	}

	bs, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, err
	}

	block, _ := pem.Decode(bs)
	if block == nil || block.Bytes == nil {
		return nil, errors.New("do not parse the data of file")
	}

	pri, err = x509.ParseECPrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}

	return pri, err

}

//PublicKey Read public key from pemFile
func (c *Ecdsa) PublicKey(pemFile string) (pubKey *ecdsa.PublicKey, err error) {

	cer, err := c.Certificate(pemFile)
	if err != nil {
		return nil, err
	}

	tpub, ok := cer.PublicKey.(*ecdsa.PublicKey)
	if ok {
		pubKey = tpub
	} else {
		return nil, errors.New("do not ecdsa.PublicKey")
	}
	return pubKey, err
}

//Certificate Read certificate from pemFile
func (c *Ecdsa) Certificate(pemFile string) (cert *x509.Certificate, err error) {
	file, err := exPathFile(pemFile)

	if err != nil || len(file) < 1 {
		return nil, errors.New("file do not exist")
	}

	bs, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, err
	}

	block, _ := pem.Decode(bs)
	if block == nil || block.Bytes == nil {
		return nil, errors.New("do not parse the data of file")
	}

	if block.Type == "CERTIFICATE" {
		cert, err = x509.ParseCertificate(block.Bytes)
		if err != nil {
			return nil, err
		}
	} else {
		return nil, errors.New("must be CERTIFICATE")
	}
	return cert, err
}

func (c *Ecdsa) makeSerialNumber() (serial *big.Int, err error) {
	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
	serial, err = rand.Int(rand.Reader, serialNumberLimit)
	return
}

//If not absolute path, then comparing executable file path, create content where file existing
func exPathFileAndMakeDirs(file string) (nfile string, err error) {
	nfile = ""
	tfile := ""
	if filepath.IsAbs(file) {
		tfile = file
	} else {
		exPath := ""
		{
			ex, err3 := os.Executable()
			if err3 == nil {
				exPath = filepath.Dir(ex)
			} else {
				err = err3
				return
			}
		}
		tfile = filepath.Join(exPath, file)
	}

	tdir := filepath.Dir(tfile)
	if !sfile.ExistFile(tdir) {
		err = os.MkdirAll(tdir, os.ModeDir)
	}
	nfile = tfile
	return
}

//If comparing executable file do not exist, then check whether parameter file existing or not
func exPathFile(file string) (tfile string, err error) {
	tfile = ""
	if filepath.IsAbs(file) {
		tfile = file
	} else {
		exPath := ""
		{
			ex, err3 := os.Executable()
			if err3 == nil {
				exPath = filepath.Dir(ex)
			} else {
				err = err3
				return
			}
		}
		tfile = filepath.Join(exPath, file)
	}

	if !sfile.ExistFile(tfile) {
		if sfile.ExistFile(file) {
			tfile = file
		} else {
			tfile = ""
			err = errors.New("no file")
		}
	}
	return
}

//MakePriKey Generate private key
func MakePriKey() (*ecdsa.PrivateKey, error) {
	return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
}


<|start_filename|>build.bat<|end_filename|>

@echo on


cd %~dp0
%~d0
set batPath=%cd%

go mod download
cd %batPath%/tools
go mod download

setlocal
call %samplePath%/grpc/proto/build_go.bat
endlocal

cd %batPath%
go build ./...




<|start_filename|>sample/grpc/http/client/src/api/hi_pb_service.js<|end_filename|>
// package: hidot
// file: hi.proto

var hi_pb = require("./hi_pb");
var grpc = require("@improbable-eng/grpc-web").grpc;

let exports = {};

var HiDot = (function () {
  function HiDot() {}
  HiDot.serviceName = "hidot.HiDot";
  return HiDot;
}());

HiDot.Hi = {
  methodName: "Hi",
  service: HiDot,
  requestStream: false,
  responseStream: false,
  requestType: hi_pb.HiReq,
  responseType: hi_pb.HiRes
};

HiDot.Write = {
  methodName: "Write",
  service: HiDot,
  requestStream: false,
  responseStream: false,
  requestType: hi_pb.WriteReq,
  responseType: hi_pb.WriteRes
};

HiDot.ServerStream = {
  methodName: "ServerStream",
  service: HiDot,
  requestStream: false,
  responseStream: true,
  requestType: hi_pb.HelloRequest,
  responseType: hi_pb.HelloResponse
};

HiDot.ClientStream = {
  methodName: "ClientStream",
  service: HiDot,
  requestStream: true,
  responseStream: false,
  requestType: hi_pb.HelloRequest,
  responseType: hi_pb.HelloResponse
};

HiDot.BothSides = {
  methodName: "BothSides",
  service: HiDot,
  requestStream: true,
  responseStream: true,
  requestType: hi_pb.HelloRequest,
  responseType: hi_pb.HelloResponse
};

exports.HiDot = HiDot;

function HiDotClient(serviceHost, options) {
  this.serviceHost = serviceHost;
  this.options = options || {};
}

HiDotClient.prototype.hi = function hi(requestMessage, metadata, callback) {
  if (arguments.length === 2) {
    callback = arguments[1];
  }
  var client = grpc.unary(HiDot.Hi, {
    request: requestMessage,
    host: this.serviceHost,
    metadata: metadata,
    transport: this.options.transport,
    debug: this.options.debug,
    onEnd: function (response) {
      if (callback) {
        if (response.status !== grpc.Code.OK) {
          var err = new Error(response.statusMessage);
          err.code = response.status;
          err.metadata = response.trailers;
          callback(err, null);
        } else {
          callback(null, response.message);
        }
      }
    }
  });
  return {
    cancel: function () {
      callback = null;
      client.close();
    }
  };
};

HiDotClient.prototype.write = function write(requestMessage, metadata, callback) {
  if (arguments.length === 2) {
    callback = arguments[1];
  }
  var client = grpc.unary(HiDot.Write, {
    request: requestMessage,
    host: this.serviceHost,
    metadata: metadata,
    transport: this.options.transport,
    debug: this.options.debug,
    onEnd: function (response) {
      if (callback) {
        if (response.status !== grpc.Code.OK) {
          var err = new Error(response.statusMessage);
          err.code = response.status;
          err.metadata = response.trailers;
          callback(err, null);
        } else {
          callback(null, response.message);
        }
      }
    }
  });
  return {
    cancel: function () {
      callback = null;
      client.close();
    }
  };
};

HiDotClient.prototype.serverStream = function serverStream(requestMessage, metadata) {
  var listeners = {
    data: [],
    end: [],
    status: []
  };
  var client = grpc.invoke(HiDot.ServerStream, {
    request: requestMessage,
    host: this.serviceHost,
    metadata: metadata,
    transport: this.options.transport,
    debug: this.options.debug,
    onMessage: function (responseMessage) {
      listeners.data.forEach(function (handler) {
        handler(responseMessage);
      });
    },
    onEnd: function (status, statusMessage, trailers) {
      listeners.status.forEach(function (handler) {
        handler({ code: status, details: statusMessage, metadata: trailers });
      });
      listeners.end.forEach(function (handler) {
        handler({ code: status, details: statusMessage, metadata: trailers });
      });
      listeners = null;
    }
  });
  return {
    on: function (type, handler) {
      listeners[type].push(handler);
      return this;
    },
    cancel: function () {
      listeners = null;
      client.close();
    }
  };
};

HiDotClient.prototype.clientStream = function clientStream(metadata) {
  var listeners = {
    end: [],
    status: []
  };
  var client = grpc.client(HiDot.ClientStream, {
    host: this.serviceHost,
    metadata: metadata,
    transport: this.options.transport
  });
  client.onEnd(function (status, statusMessage, trailers) {
    listeners.status.forEach(function (handler) {
      handler({ code: status, details: statusMessage, metadata: trailers });
    });
    listeners.end.forEach(function (handler) {
      handler({ code: status, details: statusMessage, metadata: trailers });
    });
    listeners = null;
  });
  return {
    on: function (type, handler) {
      listeners[type].push(handler);
      return this;
    },
    write: function (requestMessage) {
      if (!client.started) {
        client.start(metadata);
      }
      client.send(requestMessage);
      return this;
    },
    end: function () {
      client.finishSend();
    },
    cancel: function () {
      listeners = null;
      client.close();
    }
  };
};

HiDotClient.prototype.bothSides = function bothSides(metadata) {
  var listeners = {
    data: [],
    end: [],
    status: []
  };
  var client = grpc.client(HiDot.BothSides, {
    host: this.serviceHost,
    metadata: metadata,
    transport: this.options.transport
  });
  client.onEnd(function (status, statusMessage, trailers) {
    listeners.status.forEach(function (handler) {
      handler({ code: status, details: statusMessage, metadata: trailers });
    });
    listeners.end.forEach(function (handler) {
      handler({ code: status, details: statusMessage, metadata: trailers });
    });
    listeners = null;
  });
  client.onMessage(function (message) {
    listeners.data.forEach(function (handler) {
      handler(message);
    })
  });
  client.start(metadata);
  return {
    on: function (type, handler) {
      listeners[type].push(handler);
      return this;
    },
    write: function (requestMessage) {
      client.send(requestMessage);
      return this;
    },
    end: function () {
      client.finishSend();
    },
    cancel: function () {
      listeners = null;
      client.close();
    }
  };
};

exports.HiDotClient = HiDotClient;

export {HiDot, HiDotClient}

<|start_filename|>demo/redis/orm/funcs.go<|end_filename|>
package main

import (
	"fmt"
	"github.com/albrow/zoom"
	"strconv"
)

func setSomeValues(num int) {
	for i := 0; i < num; i++ {
		save(sc, &S{Str: "index " + strconv.Itoa(i), I: i+1})
	}

	return
}

func NewCollection() {
	// new collection, option param is for 'find all' func
	sc, err = pool.NewCollectionWithOptions(&S{}, zoom.CollectionOptions{Index: true})
	if err != nil {
		fmt.Println("create collection failed, error:", err)
	}
}

func save(collection *zoom.Collection, model *S) {
	if err = collection.Save(model); err != nil {
		fmt.Println("set value failed, error:", err)
	}
}

func update(model *S) {
	if err = sc.SaveFields([]string{"Str"}, model); err != nil {
		fmt.Println("update value failed, error:", err)
	}
}

func find(id string) *S {
	res := &S{}
	if err = sc.Find(id, res); err != nil {
		fmt.Println("find value failed, error:", err)
	}

	return res
}

func findCertain(id string, fieldNames []string) *S {
	res := &S{}
	if err = sc.FindFields(id, fieldNames, res); err != nil {
		fmt.Println("find certain values failed, error:", err)
	}

	return res
}

func findAll() {
	res := make([]*S, 0)
	if err = sc.FindAll(&res); err != nil {
		fmt.Println("find all failed, error:", err)
	}
	var i int
	if i, err = sc.Count(); err != nil {
		fmt.Println("count summary failed, error:", err)
	}
	fmt.Printf("Node: show find all res: (total: %d)\n", i)
	for i := range res {
		fmt.Printf("index: %d, value:%#v\n", i, res[i])
	}

	return
}

func del(id string) {
	var ok bool
	if ok, err = sc.Delete(id); !ok || err != nil {
		fmt.Println("del id failed, error:", err)
	}

	return
}


<|start_filename|>dot/line.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package dot

import (
	"reflect"
)

//Injecter inject interface
type Injecter interface {
	//Inject inject
	//obj only support structure
	//dot.TagDot (dot) tag is in the field
	//If tag is empty, then input with field type, otherwise input with tag value（dot.LiveID）
	//In the process if error occurred, it will not quit, returned error is the first one occurred
	Inject(obj interface{}) error
	//GetByType get by type
	//If no related object in current container, then will call parent to search
	//type container is seperate with liveid container
	GetByType(t reflect.Type) (d Dot, err error)
	//GetByLiveID get by liveid
	//If no related object in current container, then will call parent to search
	//type container is seperate with liveid container
	GetByLiveID(id LiveID) (d Dot, err error)

	//ReplaceOrAddByType update
	//Cannot operate parent
	ReplaceOrAddByType(d Dot) error
	//Cannot operate parent
	ReplaceOrAddByParamType(d Dot, t reflect.Type) error
	//ReplaceOrAddByLiveID update
	//Cannot operate parent
	ReplaceOrAddByLiveID(d Dot, id LiveID) error
	//RemoveByType remove
	RemoveByType(t reflect.Type) error
	//RemoveByLiveID remove
	RemoveByLiveID(id LiveID) error

	//SetParent set parent injecter
	SetParent(p Injecter)
	//GetParent get parent injecter
	GetParent() Injecter
}

//Line line
type Line interface {
	//Return unique Line name
	ID() string
	//Line API
	Config() *Config
	//SConfig general config API
	SConfig() SConfig

	SLogger() SLogger

	//order
	//1,Search liveid corresponding newer
	//2,Search typid corresponding newer
	//3,Search right newer in meta
	//AddNewerByLiveID add new for liveid
	AddNewerByLiveID(liveID LiveID, newDot Newer) error
	//AddNewerByTypeID add new for type
	AddNewerByTypeID(typeID TypeID, newDot Newer) error
	//RemoveNewerByLiveID remove
	RemoveNewerByLiveID(liveID LiveID)
	//RemoveNewerByTypeID remove
	RemoveNewerByTypeID(typeID TypeID)

	//PreAdd Add dot liveid and meta info, here no dot is created, it will be generated after Computing dependence
	//If it is the single sample, don't need to point sample info, sample id is typeid
	//If config file has config sample, then it will be added automatically, if sample id already existing, then config is prior
	PreAdd(typeLives ...*TypeLives) error
	//relyOrder  Check whether dependency existing
	//relyOrder() error
	////CreateDots create dots
	//CreateDots() error
	//ToLifer to lifer
	ToLifer() Lifer
	//ToInjecter to injecter
	ToInjecter() Injecter

	//ToDotEventer to Eventer
	ToDotEventer() Eventer

	//GetDotConfig get
	GetDotConfig(liveID LiveID) *LiveConfig

	GetLineBuilder() *Builder
	//InfoAllTypeAdnLives just for debug, log info all types and lives
	InfoAllTypeAdnLives()
	//EachLives for each Lives, if the func return false, break the loop
	EachLives(func(*Live, *Metadata) bool)
	//DestroyConfigLog destroy config and log
	DestroyConfigLog() error
}

//SetterLine If component need to know current line, then realize this API, and this API Will be called before component Create
type SetterLine interface {
	SetLine(l Line)
}

//SetterTypeAndLiveID If component need to know current TypeID or LiveID, then realize this API, and this API Will be called before component Create
type SetterTypeAndLiveID interface {
	SetTypeID(typeID TypeID, liveID LiveID)
}

//AfterAllStarter After all start, before builder AfterStart
type AfterAllStarter interface {
	AfterAllStart(l Line)
}

//AfterAllInjecter After all inject, before builder AfterStart
type AfterAllInjecter interface {
	AfterAllInject(l Line)
}

//AfterAllDestroyer After all destroy, before builder AfterDestroy
type AfterAllDestroyer interface {
	AfterAllDestroy(l Line)
}

//BeforeAllStopper Call before all stop, after Builder BeforeStop
type BeforeAllStopper interface {
	BeforeAllStop(l Line)
}

//TypeLives living
type TypeLives struct {
	Meta  Metadata
	Lives []Live
}

//ConfigTypeLive config json
type ConfigTypeLive struct {
	TypeIDConfig TypeID      `json:"typeId"`
	ConfigInfo   interface{} `json:"json"`
}

//BuildNewer Add typeid, newer for dot in config file
//This function is run after line create, also you can add other initialized content
type BuildNewer func(l Line) error

//AllEvent all event
type AllEvent func(l Line)

//Builder builder line dot
type Builder struct {
	Add BuildNewer

	BeforeCreate  AllEvent //Before all dot create
	AfterCreate   AllEvent //after  all dot create
	BeforeStart   AllEvent //Before  all dot start
	AfterStart    AllEvent //After  all dot start
	BeforeStop    AllEvent //Before  all dot stop
	AfterStop     AllEvent //After  all dot stop
	BeforeDestroy AllEvent //Before  all dot destroy
	AfterDestroy  AllEvent //After  all dot destroy

	LineLiveID string //line unique id， default value is “default”
}

//NewTypeLives new living
func NewTypeLives() *TypeLives {
	live := &TypeLives{}
	live.Lives = make([]Live, 0)
	return live
}

//Clone the TypeLives, do not clone dot
func (c *TypeLives) Clone() *TypeLives {
	cc := *c
	cc.Lives = make([]Live, len(c.Lives))
	copy(cc.Lives, c.Lives)
	cc.Meta.RelyTypeIDs = make([]TypeID, len(c.Meta.RelyTypeIDs))
	copy(cc.Meta.RelyTypeIDs, c.Meta.RelyTypeIDs)
	return &cc
}


<|start_filename|>tools/ende/curve25519.go<|end_filename|>
package ende

import (
	"crypto/ed25519"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	sx255192 "github.com/scryinfo/dot/lib/scrypto/sx25519"
	"io"
	"log"
)

const (
	generate_ed25519 = "ed25519"
	generate_x25519  = "x25519"
)

func GenerateEd25519Key(rand io.Reader) (privateKey ed25519.PrivateKey, publicKey ed25519.PublicKey, err error) {
	publicKey, privateKey, err = ed25519.GenerateKey(rand)
	return
}

func GenerateX25519Key(rand io.Reader) (privateKey sx255192.PrivateKey, publicKey sx255192.PublicKey, err error) {
	x := sx255192.X25519()
	privateKey2, publicKey2, err := x.GenerateKey(rand)
	if err != nil {
		return
	}

	err = privateKey.ToPrivateKey(privateKey2.([]byte))
	if err != nil {
		return
	}

	err = publicKey.ToPublicKey(publicKey2.([]byte))
	//if err != nil {
	//	return
	//}

	return
}

func ToSigningHash(data []byte) (hash []byte) {
	h251 := sha256.New()
	if len(data) > 0 {
		h251.Write(data)
	}
	first := h251.Sum(nil)
	h251.Reset()
	h251.Write(first) //两次hash
	return h251.Sum(nil)
}

func SignEd25519(privateKey ed25519.PrivateKey, hash []byte) (signature []byte, publicBytes []byte) {
	signature = ed25519.Sign(privateKey, hash)
	publicBytes = privateKey.Public().(ed25519.PublicKey)
	return
}

func VerifyEd25519(publicKey ed25519.PublicKey, hash []byte, signature []byte) bool {
	return ed25519.Verify(publicKey, hash, signature)
}

func GenerateKey(name string) {
	switch name {
	case generate_ed25519:
		privateKey, publicKey, err := GenerateEd25519Key(nil)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("ed25519 keys\nprivate: %s\npublic: %s\n", hex.EncodeToString(privateKey), hex.EncodeToString(publicKey))
		break
	case generate_x25519:
		privateKey, publicKey, err := GenerateX25519Key(nil)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("x25519 keys\nprivate: %s\npublic: %s\n", hex.EncodeToString(privateKey), hex.EncodeToString(publicKey))
		break
	default:
		break
	}
}


<|start_filename|>sample/db/tools/dao/pgs/notice_dao_test.go<|end_filename|>
package pgs

import (
	"fmt"
	"github.com/go-pg/pg/v10"
	"github.com/go-pg/pg/v10/orm"
	"github.com/scryinfo/dot/dots/db/pgs"
	"github.com/scryinfo/dot/sample/db/tools/model"
	"github.com/stretchr/testify/assert"
	"log"
	"testing"
	"time"
)

const dbconf_test = `{
			"addr": "localhost:5432",
			"user": "postgres",
			"password": "<PASSWORD>",
			"database": "postgres",
			"showSql": true
		}`

func TestNoticeDao(t *testing.T) {
	noticeDao := &NoticeDao{}
	noticeDao.DaoBase = pgs.GenerateDaoBase(dbconf_test)
	err := createNotice(noticeDao.DaoBase.Wrapper.GetDb())
	assert.Equal(t, nil, err)
	//create table
	//createNotice(noticeDao.DaoBase.Wrapper.GetDb())
	noticeDao.DaoBase.WithNoTx(func(conn orm.DB) error {
		notice := &model.Notice{
			Status: 1,
		}
		mReturn, err := noticeDao.InsertReturn(conn, notice)
		assert.Equal(t, nil, err)
		assert.NotEqual(t, nil, mReturn.ID)
		assert.Equal(t, 1, mReturn.Status)

		mGet, err := noticeDao.GetByID(conn, mReturn.ID)
		assert.Equal(t, nil, err)
		assert.Equal(t, mReturn.ID, mGet.ID)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.OptimisticLockVersion, mGet.OptimisticLockVersion)
		assert.Equal(t, mReturn.Status, mGet.Status)

		ms, err := noticeDao.Query(conn, "")
		assert.Equal(t, nil, err)
		assert.Equal(t, 1, len(ms))
		mGet = ms[0]
		assert.Equal(t, mReturn.ID, mGet.ID)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.OptimisticLockVersion, mGet.OptimisticLockVersion)
		assert.Equal(t, mReturn.Status, mGet.Status)

		mGet, err = noticeDao.QueryOne(conn, "")
		assert.Equal(t, nil, err)
		assert.Equal(t, mReturn.ID, mGet.ID)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.OptimisticLockVersion, mGet.OptimisticLockVersion)
		assert.Equal(t, mReturn.Status, mGet.Status)

		ms, err = noticeDao.List(conn)
		assert.Equal(t, nil, err)
		assert.Equal(t, 1, len(ms))
		mGet = ms[0]
		assert.Equal(t, mReturn.ID, mGet.ID)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.OptimisticLockVersion, mGet.OptimisticLockVersion)
		assert.Equal(t, mReturn.Status, mGet.Status)

		ms, err = noticeDao.QueryPage(conn, 10, 1, "")
		assert.Equal(t, nil, err)
		assert.Equal(t, 1, len(ms))
		mGet = ms[0]
		assert.Equal(t, mReturn.ID, mGet.ID)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.OptimisticLockVersion, mGet.OptimisticLockVersion)
		assert.Equal(t, mReturn.Status, mGet.Status)

		ms, count, err := noticeDao.QueryPageWithCount(conn, 10, 1, "")
		assert.Equal(t, nil, err)
		assert.Equal(t, 1, len(ms))
		assert.Equal(t, 1, count)
		mGet = ms[0]
		assert.Equal(t, mReturn.ID, mGet.ID)
		assert.Equal(t, mReturn.UpdateTime, mGet.UpdateTime)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.Equal(t, mReturn.OptimisticLockVersion, mGet.OptimisticLockVersion)
		assert.Equal(t, mReturn.Status, mGet.Status)

		mGet.Status = 10
		time.Sleep(time.Second * 1) //
		err = noticeDao.Update(conn, mGet)
		assert.Equal(t, nil, err)
		mGet, err = noticeDao.QueryOne(conn, fmt.Sprintf(" %s = ?", model.Notice_ID), mGet.ID)
		assert.Equal(t, nil, err)
		assert.Equal(t, 10, mGet.Status)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.NotEqual(t, mReturn.UpdateTime, mGet.UpdateTime)

		mGet.Status = 11
		time.Sleep(time.Second * 1) //
		mGet, err = noticeDao.UpdateReturn(conn, mGet)
		assert.Equal(t, nil, err)
		mGet, err = noticeDao.GetByID(conn, mGet.ID)
		assert.Equal(t, nil, err)
		assert.Equal(t, 11, mGet.Status)
		assert.Equal(t, mReturn.CreateTime, mGet.CreateTime)
		assert.NotEqual(t, mReturn.UpdateTime, mGet.UpdateTime)

		mGet.Data.Name = "upsert"
		mGet.Status = 12
		time.Sleep(time.Second * 1) //
		updateTime := mGet.UpdateTime
		mUpsert, err := noticeDao.UpsertReturn(conn, mGet)
		assert.Equal(t, nil, err)
		assert.Equal(t, 12, mUpsert.Status)
		assert.Equal(t, mUpsert.CreateTime, mGet.CreateTime)
		assert.Equal(t, mUpsert.UpdateTime, mGet.UpdateTime)
		assert.NotEqual(t, updateTime, mUpsert.UpdateTime)
		assert.Equal(t, mGet.Data.Name, mUpsert.Data.Name)

		return err
	})
}

func createNotice(db *pg.DB) error {

	err := db.Model((*model.Notice)(nil)).DropTable(&orm.DropTableOptions{IfExists: true, Cascade: true})
	if err != nil {
		log.Print(err)
	}
	err = db.Model((*model.DataType)(nil)).DropComposite(&orm.DropCompositeOptions{
		IfExists: true,
	})
	if err != nil {
		log.Print(err)
	}
	err = db.Model((*model.DataType)(nil)).CreateComposite(nil)
	if err != nil {
		log.Print(err)
	}
	err = db.Model((*model.Notice)(nil)).CreateTable(nil)
	if err != nil {
		log.Print(err)
	}
	return err
}


<|start_filename|>tools/ende/encode.go<|end_filename|>
package ende

import (
	"crypto"
	"crypto/ed25519"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"syscall"

	"go.uber.org/zap"

	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/lib/scrypto"
	_ "github.com/scryinfo/dot/lib/scrypto/ende25519"
	_ "github.com/scryinfo/dot/lib/scrypto/sx25519"
	"github.com/scryinfo/dot/utils"
	"github.com/scryinfo/scryg/sutils/sfile"
)

const EncodeTypeID = "4f0d40c6-9822-4346-ae23-3a54b866b96a"

type configEncode struct {
	Help     bool   `json:"help"` //输出帮助信息
	Generate string `json:"generate"`
	File     string `json:"file"`
	OutFile  string `json:"outFile"`

	EndeType          string `json:"endeType"`          //加密的实现，现支持X25519
	Ed25519PrivateKey string `json:"ed25519PrivateKey"` //用于签名的key, hex
	X25519PeerKey     string `json:"x25519PeerKey"`     //对方的x25519的公钥， hex
}
type Encode struct {
	conf configEncode
}

//func (c *Encode) Create(l dot.Line) error {
//
//}
//func (c *Encode) Injected(l dot.Line) error {
//
//}
//func (c *Encode) AfterAllInject(l dot.Line) {
//
//}

func (c *Encode) Start(ignore bool) error {
	c.parseEnParameter()
	SendSignal(syscall.SIGKILL)
	//os.Exit(0)
	return nil
}

//func (c *Encode) Stop(ignore bool) error {
//
//}
//
//func (c *Encode) Destroy(ignore bool) error {
//
//}

//construct dot
func newEncode(conf []byte) (dot.Dot, error) {
	dconf := &configEncode{}

	err := dot.UnMarshalConfig(conf, dconf)
	if err != nil {
		return nil, err
	}

	d := &Encode{conf: *dconf}

	return d, nil
}

//EncodeTypeLives
func EncodeTypeLives() []*dot.TypeLives {
	tl := &dot.TypeLives{
		Meta: dot.Metadata{TypeID: EncodeTypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
			return newEncode(conf)
		}},
		//Lives: []dot.Live{
		//	{
		//		LiveID:    EncodeTypeID,
		//		RelyLives: map[string]dot.LiveID{"some field": "some id"},
		//	},
		//},
	}

	lives := []*dot.TypeLives{tl}

	return lives
}

//EncodeConfigTypeLive
func EncodeConfigTypeLive() *dot.ConfigTypeLive {
	paths := make([]string, 0)
	paths = append(paths, "")
	return &dot.ConfigTypeLive{
		TypeIDConfig: EncodeTypeID,
		ConfigInfo: &configEncode{
			//todo
		},
	}
}

//返回值为true 接着运行
func (c *Encode) parseEnParameter() bool {
	logger := dot.Logger()
	if c.conf.Help {
		//todo
		return false
	}

	if len(c.conf.Generate) > 0 {
		GenerateKey(c.conf.Generate)
		return false
	}

	if c.conf.EndeType != string(scrypto.EndeType_X25519) {
		logger.Errorln("the EndeType is not support: " + c.conf.EndeType)
		return false
	}

	if len(c.conf.File) < 1 {
		logger.Errorln("请入要加密的文件")
		return false
	}

	fullPath := utils.GetFullPathFile(c.conf.File)
	if len(fullPath) < 1 || !sfile.ExistFile(fullPath) {
		logger.Errorln(fmt.Sprintf("不能找到文件： %s\n", c.conf.File))
		return false
	}

	if len(c.conf.OutFile) < 1 {
		c.conf.OutFile = fullPath + "_en"
	}

	body, err := ioutil.ReadFile(fullPath)
	if err != nil {
		logger.Errorln("", zap.Error(err))
		return false
	}

	data := scrypto.EndeData{
		PublicKey:       nil,
		EndeType:        scrypto.EndeType(c.conf.EndeType),
		Signature:       nil,
		SignedPublicKey: nil,
		EnData:          false,
		Body:            body,
	}

	{ //encode
		var peerKey crypto.PublicKey
		{
			bytes, err := hex.DecodeString(c.conf.X25519PeerKey)
			if err != nil {
				logger.Errorln("", zap.Error(err))
				return false
			}
			peerKey = bytes
		}
		var signedPrivateKey ed25519.PrivateKey
		{
			bytes, err := hex.DecodeString(c.conf.Ed25519PrivateKey)
			if err != nil {
				logger.Errorln("", zap.Error(err))
				return false
			}
			if len(bytes) > 0 {
				signedPrivateKey = bytes
			}
		}
		data, err = scrypto.EncodeData(&data, peerKey, signedPrivateKey)
		if err != nil {
			logger.Errorln("", zap.Error(err))
			return false
		}
	}

	bytes, err := json.Marshal(&data)
	if err != nil {
		logger.Errorln("", zap.Error(err))
		return false
	}

	err = ioutil.WriteFile(c.conf.OutFile, bytes, 0644)
	if err != nil {
		logger.Errorln("", zap.Error(err))
		return false
	}
	fmt.Printf("encode successful, file: %s\n", c.conf.OutFile)
	return true
}


<|start_filename|>sample/grpc/nobl/runnobl.bat<|end_filename|>

@echo on

cd %~dp0
%~d0
set batPath=%cd%

cd %batPath%/client  & go build client.go && start client.exe
cd %batPath%/server & go build server.go && start server.exe
cd %batPath%/server2 & go build server2.go && start server2.exe

cd %batPath%



<|start_filename|>dots/gindot/file_server.go<|end_filename|>
package gindot

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/golang/gddo/httputil/header"
	"net/http"
	"os"
	"path"
	"sort"
	"strconv"
	"strings"
)

const (
	gzip = "gzip"
	br   = "br"
	con
)

//see https://github.com/lpar/gzipped/blob/master/fileserver.go
// FileServer is a drop-in replacement for Go's standard http.FileServer
// which adds support for static resources precompressed with gzip, at
// the cost of removing the support for directory browsing.
//
// If file filename.ext has a compressed version filename.ext.gz alongside
// it, if the client indicates that it accepts gzip-compressed data, and
// if the .gz file can be opened, then the compressed version of the file
// will be sent to the client. Otherwise the request is passed on to
// http.ServeContent, and the raw (uncompressed) version is used.
//
// It is up to you to ensure that the compressed and uncompressed versions
// of files match and have sensible timestamps.
//
// Compressed or not, requests are fulfilled using http.ServeContent, and
// details like accept ranges and content-type sniffing are handled by that
// method.
type FileServer struct {
	fs        http.FileSystem
	resPath   string
	paramName string
	encodings encodingByPreference
}

func NewFileServer(resPath string, paramName string, encodings []Encoding) *FileServer {
	fs := http.Dir(resPath)
	if len(encodings) < 1 {
		encodings = supportedEncodings[:]
	}
	return &FileServer{
		fs:        fs,
		resPath:   resPath,
		paramName: paramName,
		encodings: encodings,
	}
}

func (c *FileServer) Handler(ctx *gin.Context) {
	fileString := ctx.Param(c.paramName)
	fileString = path.Clean(fileString)
	if strings.HasSuffix(fileString, "/") { //不支持目录
		ctx.Status(http.StatusNotFound)
		ctx.Abort()
		return
	}

	// Find the best acceptable file, including trying uncompressed
	if file, info, err := c.findBestFile(ctx.Writer, ctx.Request, fileString); err == nil {
		http.ServeContent(ctx.Writer, ctx.Request, fileString, info.ModTime(), file)
		file.Close()
		//ctx.Abort()
		return
	}

	ctx.Status(http.StatusNotFound)
	ctx.Abort()
	return
}

// Encoding represents an Accept-Encoding. All of these fields are pre-populated
// in the supportedEncodings variable, except the ClientPreference which is updated
// (by copying a value from supportedEncodings) when examining client headers.
type Encoding struct {
	Name             string  `json:"name"`             // the Encoding Name
	Extension        string  `json:"extension"`        // the file Extension (including a leading dot)
	ClientPreference float64 `json:"clientPreference"` // the client's preference
	ServerPreference int     `json:"serverPreference"` // the server's preference
}

// Helper type to sort encodings, using ClientPreference first, and then
// ServerPreference as a tie breaker. This sorts in *DESCENDING* order, rather
// than the usual ascending order.
type encodingByPreference []Encoding

// Implement the sort.Interface interface
func (e encodingByPreference) Len() int { return len(e) }
func (e encodingByPreference) Less(i, j int) bool {
	if e[i].ClientPreference == e[j].ClientPreference {
		return e[i].ServerPreference > e[j].ServerPreference
	}
	return e[i].ClientPreference > e[j].ClientPreference
}
func (e encodingByPreference) Swap(i, j int) { e[i], e[j] = e[j], e[i] }

// Supported encodings. Higher server preference means the Encoding will be when
// the client doesn't have an explicit preference.
var supportedEncodings = [...]Encoding{
	{
		Name:             "gzip",
		Extension:        ".gz",
		ServerPreference: 1,
	},
	{
		Name:             "br",
		Extension:        ".br",
		ServerPreference: 2,
	},
}

func (c *FileServer) openAndStat(path string) (http.File, os.FileInfo, error) {
	file, err := c.fs.Open(path)
	var info os.FileInfo
	// This slightly weird variable reuse is so we can get 100% test coverage
	// without having to come up with a test file that can be opened, yet
	// fails to stat.
	if err == nil {
		info, err = file.Stat()
	}
	if err != nil {
		return file, nil, err
	}
	if info.IsDir() {
		return file, nil, fmt.Errorf("%s is directory", path)
	}
	return file, info, nil
}

// Build a []Encoding based on the Accept-Encoding header supplied by the
// client. The returned list will be sorted from most-preferred to
// least-preferred.
func (c *FileServer) acceptable(r *http.Request) []Encoding {
	// list of acceptable encodings, as provided by the client
	acceptEncodings := make([]Encoding, 0, len(c.encodings))

	// the quality of the * Encoding; this will be -1 if not sent by client
	starQuality := -1.

	// encodings we've already seen (used to handle duplicates and *)
	seenEncodings := make(map[string]interface{})

	// match the client accept encodings against the ones we support
	for _, aspec := range header.ParseAccept(r.Header, acceptEncodingHeader) {
		if _, alreadySeen := seenEncodings[aspec.Value]; alreadySeen {
			continue
		}
		seenEncodings[aspec.Value] = nil
		if aspec.Value == "*" {
			starQuality = aspec.Q
			continue
		}
		for _, known := range c.encodings {
			if aspec.Value == known.Name && aspec.Q != 0 {
				enc := known
				enc.ClientPreference = aspec.Q
				acceptEncodings = append(acceptEncodings, enc)
				break
			}
		}
	}

	// If the client sent Accept: *, add all our extra known encodings. Use
	// the quality of * as the client quality for the Encoding.
	if starQuality != -1. {
		for _, known := range c.encodings {
			if _, seen := seenEncodings[known.Name]; !seen {
				enc := known
				enc.ClientPreference = starQuality
				acceptEncodings = append(acceptEncodings, enc)
			}
		}
	}

	// sort the Encoding based on client/server preference
	sort.Sort(encodingByPreference(acceptEncodings))
	return acceptEncodings
}

const (
	acceptEncodingHeader  = "Accept-Encoding"
	contentEncodingHeader = "Content-Encoding"
	contentLengthHeader   = "Content-Length"
	rangeHeader           = "Range"
	varyHeader            = "Vary"
)

// Find the best file to serve based on the client's Accept-Encoding, and which
// files actually exist on the filesystem. If no file was found that can satisfy
// the request, the error field will be non-nil.
func (c *FileServer) findBestFile(w http.ResponseWriter, r *http.Request, fpath string) (http.File, os.FileInfo, error) {
	// find the best matching file
	for _, enc := range c.acceptable(r) {
		if file, info, err := c.openAndStat(fpath + enc.Extension); err == nil {
			wHeader := w.Header()
			wHeader[contentEncodingHeader] = []string{enc.Name}
			wHeader.Add(varyHeader, acceptEncodingHeader)

			if len(r.Header[rangeHeader]) == 0 {
				// If not a range request then we can easily set the content length which the
				// Go standard library does not do if "Content-Encoding" is set.
				wHeader[contentLengthHeader] = []string{strconv.FormatInt(info.Size(), 10)}
			}
			return file, info, nil
		}
	}

	// if nothing found, try the base file with no content-Encoding
	return c.openAndStat(fpath)
}

//func (c *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//	upath := r.URL.Path
//	if !strings.HasPrefix(upath, "/") {
//		upath = "/" + upath
//		r.URL.Path = upath
//	}
//	fpath := path.Clean(upath)
//	if strings.HasSuffix(fpath, "/") {
//		// If you wanted to put back directory browsing support, this is
//		// where you'd do it.
//		http.NotFound(w, r)
//		return
//	}
//
//	// Find the best acceptable file, including trying uncompressed
//	if file, info, err := c.findBestFile(w, r, fpath); err == nil {
//		http.ServeContent(w, r, fpath, info.ModTime(), file)
//		file.Close()
//		return
//	}
//
//	// Doesn't exist, compressed or uncompressed
//	http.NotFound(w, r)
//}


<|start_filename|>demo/t/main.go<|end_filename|>
package main

import (
	"flag"
	"fmt"
)

type arrayFlags []string

func (i *arrayFlags) String() string {
	return "my string representation"
}

func (i *arrayFlags) Set(value string) error {
	*i = append(*i, value)
	return nil
}

var myFlags arrayFlags

func main() {
	flag.Var(&myFlags, "list1", "Some description for this param.")
	flag.Parse()
	fmt.Println(myFlags)
}


<|start_filename|>lib/must_do/must_do_test.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package must_do

import (
	"errors"
	"log"
	"math/rand"
	"testing"
	"time"
)

func One(msg ...interface{}) error {
	//随机一个10
	i := rand.Intn(11)
	log.Print("当前值为：", i)
	if i != 10 {
		return errors.New("err")
	}
	return nil
}

type two struct {
}

func (t *two) GetTen() bool {
	i := rand.Intn(11)
	log.Print("当前值为：", i)
	if i != 10 {
		return false
	}
	return true
}

func TestMustDo_Start(t *testing.T) {

	do := &MustDo{
		Conf: &MustDoConfig{
			LargeInterval: time.Second * 20,
			SmallInterval: time.Second * 5,
			CycleIndex:    3,
		},
	}
	//第一个,函数测试
	do.Thing = func() bool {
		if One() != nil {
			return false
		} else {
			return true
		}
	}
	do.Start()

	//第二个,方法测试
	tt := &two{}
	do.Thing = func() bool {
		return tt.GetTen()
	}
	do.Start()
	//go do.Start()

}


<|start_filename|>sample/db/tools/model/models.go<|end_filename|>
package model

import (
	"github.com/scryinfo/dot/dots/db"
)

type DataType struct {
	Name  string
	Count int64
}

//go:generate gmodel -typeName=Notice -tableName=notices
//go:generate gdao -typeName=Notice -tableName=notices -daoPackage=dao
type Notice struct {
	db.ModelBase
	Data   DataType `pg:"composite:data"`
	Status int
	No     int `pg:"-"`
}

//go:generate gmodel -typeName=Sub -tableName=subs
//go:generate gdao -typeName=Sub -tableName=subs -daoPackage=dao
type Sub struct {
	db.ModelBase
	Name string
}

//go:generate gmodel -typeName=HasSub -tableName=has_subs
//go:generate gdao -typeName=HasSub -tableName=has_subs -daoPackage=dao
type HasSub struct {
	db.ModelBase
	SubId   string
	Count   int
	SubData *Sub `pg:"rel:has-one"`
}

//go:generate gmodel -typeName=AutoData -tableName=auto_datas
//go:generate gdao -typeName=AutoData -tableName=auto_datas -daoPackage=dao -useGorm=true
type AutoData struct {
	db.AutoModelBase
	Name string
	Age  int8
}


<|start_filename|>lib/scrypto/ecdh.go<|end_filename|>
package scrypto

import (
	"crypto"
	"io"
)

type CurveParameters struct {
	Name    string // the canonical name of the curve
	BitSize int    // the size of the underlying field
}

//以下值只会在init中进行修改，所以认为是安全的
var (
	Ecdhs = make(map[string]Ecdh, 2)
)

// Ecdh is the interface defining all functions
// necessary for ECDH.
type Ecdh interface {
	// GenerateKey generates a private/public key pair using entropy from rand.
	// If rand is nil, crypto/rand.Reader will be used.
	GenerateKey(rand io.Reader) (private crypto.PrivateKey, public crypto.PublicKey, err error)

	// Parameters returns the curve parameters - like the field size.
	Parameters() CurveParameters

	// PublicKey returns the public key corresponding to the given private one.
	PublicKey(private crypto.PrivateKey) (public crypto.PublicKey, err error)

	//// Check returns a non-nil error if the peers public key cannot used for the
	//// key exchange - for instance the public key isn't a point on the elliptic curve.
	//// It's recommended to check peer's public key before computing the secret.
	//Check(peersPublic crypto.PublicKey) (err error)

	// ComputeSecret returns the secret value computed from the given private key
	// and the peers public key.
	ComputeSecret(private crypto.PrivateKey, peersPublic crypto.PublicKey) (secret []byte, err error)

	PublicKeyToBytes(publicKey crypto.PublicKey) (key []byte, err error)

	PrivateKeyToBytes(privateKey crypto.PrivateKey) (key []byte, err error)

	BytesToPublicKey(keyBytes []byte) (publicKey crypto.PublicKey, err error)

	BytesToPrivateKey(keyBytes []byte) (privateKey crypto.PrivateKey, err error)
}

func GetEcdh(data *EndeData) Ecdh {
	var re Ecdh = nil
	//还没有专门为ecdh设置类型，暂时使用endeType类型作为， ecdh的类型
	if v, ok := Ecdhs[string(data.EndeType)]; ok {
		re = v
	}
	return re
}


<|start_filename|>dots/db/pgs/kits.go<|end_filename|>
package pgs

import (
	"github.com/go-pg/pg/v10"
	"github.com/go-pg/pg/v10/orm"
	"reflect"
	"strconv"
	"strings"
)

//CreateSchema create tables
func CreateSchema(db *pg.DB, ms []interface{}) error {
	for _, model := range ms {
		err := db.Model(model).CreateTable(&orm.CreateTableOptions{Temp: false, IfNotExists: true})
		if err != nil {
			return err
		}
	}
	return nil
}

//SQLLikeEscapePostgres like escape
func SQLLikeEscapePostgres(param string) string {
	return SQLLikeEscape(param, []rune{'%', '_'}, '\\')
}

//SQLLikeEscape  like escape
func SQLLikeEscape(param string, special []rune, escape rune) string {
	cs := []rune(param)
	newcs := make([]rune, 0, len(cs)+10)
	es := escape
	for _, c := range cs {
		for _, s := range special {
			if c == s {
				newcs = append(newcs, es)
				break
			}
		}
		newcs = append(newcs, c)
	}

	res := string(newcs)
	return res
}

//ToMap convert fields of struct to map,  key is Lowercase for the first letter of the field name
func ToMap(d interface{}, ex map[string]bool) map[string]string {
	if ex == nil {
		ex = map[string]bool{}
	}
	res := make(map[string]string)
	mv := reflect.ValueOf(d).Elem()
	mt := mv.Type()
	for i := 0; i < mv.NumField(); i++ {
		v := mv.Field(i)
		fname := mt.Field(i).Name
		lfname := ToFirstLower(fname)
		if _, ok := ex[fname]; ok {
			continue
		}

		if _, ok := ex[lfname]; ok {
			continue
		}
		switch v.Kind() {
		case reflect.Int64, reflect.Int32, reflect.Int, reflect.Int16:
			res[lfname] = strconv.FormatInt(v.Int(), 10)
		default:
			res[lfname] = v.String()
		}
	}

	return res
}

//ToFirstLower Lowercase for the first letter
func ToFirstLower(s string) string {
	cs := []rune(s)
	return strings.ToLower(string(cs[0])) + string(cs[1:])
}
//ToFirstUpper Uppercase for the first letter
func ToFirstUpper(s string) string {
	cs := []rune(s)
	return strings.ToUpper(string(cs[0])) + string(cs[1:])
}
/////////////////////////////////////////////see github.com/go-pg/pg/internal
func isUpper(c byte) bool {
	return c >= 'A' && c <= 'Z'
}

func isLower(c byte) bool {
	return c >= 'a' && c <= 'z'
}

func toUpper(c byte) byte {
	return c - 32
}

func toLower(c byte) byte {
	return c + 32
}

// Underscore converts "CamelCasedString" to "camel_cased_string".
// Just work for ASCⅡ code
func Underscore(s string) string {
	r := make([]byte, 0, len(s)+5)
	for i := 0; i < len(s); i++ {
		c := s[i]
		if isUpper(c) {
			if i > 0 && i+1 < len(s) && (isLower(s[i-1]) || isLower(s[i+1])) {
				r = append(r, '_', toLower(c))
			} else {
				r = append(r, toLower(c))
			}
		} else {
			r = append(r, c)
		}
	}
	return string(r)
}

//CamelCased Just work for ASCⅡ code
func CamelCased(s string) string {
	r := make([]byte, 0, len(s))
	upperNext := true
	for i := 0; i < len(s); i++ {
		c := s[i]
		if c == '_' {
			upperNext = true
			continue
		}
		if upperNext {
			if isLower(c) {
				c = toUpper(c)
			}
			upperNext = false
		}
		r = append(r, c)
	}
	return string(r)
}

//ToExported Just work for ASCⅡ code
func ToExported(s string) string {
	if len(s) == 0 {
		return s
	}
	if c := s[0]; isLower(c) {
		b := []byte(s)
		b[0] = toUpper(c)
		return string(b)
	}
	return s
}

//UpperString Just work for ASCⅡ code
func UpperString(s string) string {
	if isUpperString(s) {
		return s
	}

	b := make([]byte, len(s))
	for i := range b {
		c := s[i]
		if isLower(c) {
			c = toUpper(c)
		}
		b[i] = c
	}
	return string(b)
}

func isUpperString(s string) bool {
	for i := 0; i < len(s); i++ {
		c := s[i]
		if isLower(c) {
			return false
		}
	}
	return true
}

/////////////////////////////////////////////see github.com/go-pg/pg/internal


<|start_filename|>sample/db/redis_client/redis_client.go<|end_filename|>
package main

import (
	"github.com/scryinfo/dot/dots/db/redis_client"
	"os"

	"go.uber.org/zap"

	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/line"
	"github.com/scryinfo/scryg/sutils/ssignal"
)

func main() {
	l, err := line.BuildAndStart(add)
	if err != nil {
		dot.Logger().Errorln("", zap.Error(err))
	}
	defer line.StopAndDestroy(l, true)
	dot.Logger().Infoln("dot ok")
	{ // get redisSample client do something
		redisSample := &RedisSample{}
		l.ToInjecter().Inject(redisSample)
		redisSample.basicDemo()
		redisSample.versionControlDemo()
	}

	ssignal.WaitCtrlC(func(s os.Signal) bool {
		return false
	})
}
func add(l dot.Line) error {
	lives := redis_client.RedisClientTypeLives()
	err := l.PreAdd(lives...)
	return err
}


<|start_filename|>dots/jsonrpc2/server.go<|end_filename|>
package jsonrpc2

import (
	"github.com/pkg/errors"
	"net/http"
)

//only one input parameter, one out parameter
func NewService(pattern string, preName string, service interface{}) (http.Handler, error) {
	if service == nil {
		return nil, errors.New("service is nil")
	}
	h := NewHandle(preName, service)
	return h, nil
}


<|start_filename|>dots/grpc/conns/conn_name.go<|end_filename|>
// <NAME>.  All rights reserved.
// license that can be found in the license file.

package conns

import (
	"errors"
	"google.golang.org/grpc"

	"github.com/scryinfo/dot/dot"
)

const (
	ConnNameTypeID = "2d281e77-3133-4718-a5b7-9eea069591ca"
)

type ConnName struct {
	serviceName string
	conn        *grpc.ClientConn
	Conns_      Conns `dot:"?"` //可选组件，优先使用etcd
	//EtcdConns   *EtcdConns `dot:"?"` //可选组件，优先使用etcd
}

type configName struct {
	Name string `json:"name"`
}

func newConnName(conf []byte) (dot.Dot, error) {
	dconf := &configName{}
	err := dot.UnMarshalConfig(conf, dconf)
	if err != nil {
		return nil, err
	}

	d := &ConnName{
		serviceName: dconf.Name,
	}

	return d, err
}

func ConnNameTypeLives() []*dot.TypeLives {
	lives := []*dot.TypeLives{{
		Meta: dot.Metadata{TypeID: ConnNameTypeID, NewDoter: func(conf []byte) (dot dot.Dot, err error) {
			return newConnName(conf)
		}},
		//Lives: []dot.Live{
		//	{
		//		LiveID:    ConnNameTypeID,
		//		RelyLives: map[string]dot.LiveID{"Conns_": ConnsTypeID, "EtcdConns": EtcdConnsTypeID},
		//	},
		//},
	}}
	//please call the EtcdConnsTypeLives or ConnsTypeLives by yourself
	//lives = EtcdConnsTypeLives()
	//lives = append(lives, ConnsTypeLives()...)

	return lives
}

//jayce edit
//return config of ConnName
func ConnNameConfigTypeLive() *dot.ConfigTypeLive {
	return &dot.ConfigTypeLive{
		TypeIDConfig: ConnNameTypeID,
		ConfigInfo:   &configName{},
	}
}

func (c *ConnName) Injected(dot.Line) error {
	//if c.Conns_ == nil && c.EtcdConns == nil {
	if c.Conns_ == nil {
		return errors.New("no conn is checked")
	}
	return nil
}

func (c *ConnName) AfterAllInject(l dot.Line) {
	if c.conn == nil {
		c.conn = c.Conns_.ClientConn(c.serviceName)
		//if c.EtcdConns != nil { //优先使用 etcd中的名字
		//	c.conn = c.EtcdConns.ClientConn(c.serviceName)
		//}
		//if c.conn == nil {
		//	c.conn = c.Conns_.ClientConn(c.serviceName)
		//}
	}
}

func (c *ConnName) Conn() *grpc.ClientConn {
	return c.conn
}

func (c *ConnName) ClientContext() *ClientContext {
	var cc *ClientContext
	if c.Conns_ != nil {
		cc = c.Conns_.ClientContext(c.serviceName)
	}
	return cc
}

func (c *ConnName) ServerName() string {
	return c.serviceName
}

func NewTestConnName(conn Conns, name string) *ConnName {
	re := &ConnName{
		serviceName: name,
		conn:        nil,
		Conns_:      conn,
	}

	re.AfterAllInject(nil)

	return re
}


<|start_filename|>utils/tls.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package utils

//TlsConfig
//case the CaPem Pem Key are not empty, both tls
//case only the Pem is not empty, server tls,  if the ServerNameOverride exist, then set the ServerNameOverride that it make the pam and key
type TlsConfig struct {
	//public key of ca
	CaPem string `json:"caPem"`
	//public key of client or server
	Pem string `json:"pem"`
	//private key of client
	Key string `json:"key"`
	//if the CaPam and Key are empty, set the ServerNameOverride is the name of the pem
	ServerNameOverride string `json:"serverNameOverride"`
}


<|start_filename|>tools/dotconf/ui/vue.config.js<|end_filename|>
const fs = require("fs");
let path = require("path");
let glob = require("glob");
const CopyPlugin = require("copy-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CompressionWebpackPlugin = require("compression-webpack-plugin");
const productionGzipExtensions = /\.(js|css|txt|html|ico|svg)(\?.*)?$/i; // del 'json' type
const merge = require("webpack-merge");

const pages = getEntry("src/views/**/main.ts");

function getEntry(globPath) {
    let pages = {};
    glob.sync(globPath).forEach(function (entry) {
        let dname = path.dirname(entry);
        let basename = path.basename(dname);
        let template = path.join(dname, "index.html");
        if (!fs.existsSync(template)) {
            template = "scr/views/index.html";
        }

        pages[basename] = {
            entry: entry,
            template: template,
            filename: `${basename}.html`
            // chunks: [basename]
        };

        // console.log(pages[basename]);
    });
    return pages;
}

module.exports = {
    publicPath: "./",
    assetsDir: "assets", // 打包后静态资源的位置
    productionSourceMap: false,
    configureWebpack: config => {
        config.output.filename = "assets/js/[name].[hash:8].js";
        config.output.chunkFilename = "assets/js/[name].[hash:8].js";
        config.plugins.push(new CopyPlugin([{from: "src/assets", to: "assets"}]));

        if (process.env.NODE_ENV === "production") {
            const plugins = [];
            plugins.push(
                new CompressionWebpackPlugin({
                    filename: "[path].gz[query]",
                    algorithm: "gzip",
                    test: productionGzipExtensions,
                    threshold: 10240,
                    minRatio: 0.8
                })
            );
            plugins.push(
                new CompressionWebpackPlugin({
                    filename: "[path].br[query]",
                    algorithm: "brotliCompress",
                    test: /\.(js|css|html|svg)$/,
                    compressionOptions: {level: 11},
                    threshold: 10240,
                    minRatio: 0.8
                })
            );
            config.plugins = [...config.plugins, ...plugins];
            config.optimization = merge(config.optimization, {
                minimize: true
            });
        } else {
            // mutate for development...
        }
    },
    chainWebpack: config => {
        config.resolve.alias.set("@", path.join(__dirname, "src"));
        config.resolve.alias.set("vue$", "vue/dist/vue.runtime.esm.js");

        config.plugin("extract-css").use(
            new MiniCssExtractPlugin({
                filename: "assets/css/[name].[hash:8].css",
                chunkFilename: "assets/css/[name].[hash:8].css"
            })
        );

        config.module
            .rule("images")
            .test(/\.(gif|png|jpe?g|svg)$/i)
            .use("url-loader")
            .loader("file-loader")
            .options({
                name: "assets/img/[name].[ext]"
            });

        if (process.env.NODE_ENV === "production") {
            //
        } else {
            //
        }
    },
    pages: pages,
    css: {
        // 是否使用css分离插件 ExtractTextPlugin
        extract: false,
        // 开启 CSS source maps?
        sourceMap: false,
        // css预设器配置项
        loaderOptions: {},
        // 启用 CSS modules for all css / pre-processor files.
        requireModuleExtension: true
    },
    devServer: {
        contentBase: "./dist",
        host: "",
        port: "9689",
        open: true, //打开浏览器
        openPage: "/home.html",
        hot: true, //热加载,
        clientLogLevel: "debug",
        overlay: {
            warnings: false,
            errors: false
        }
    },
    lintOnSave: process.env.NODE_ENV === "production"
};


<|start_filename|>tools/dotconf/data/configload_test.go<|end_filename|>
package data

import "testing"

func TestPathDeal(t *testing.T) {
	path, err := pathDeal("testdata")
	if err != nil {
		return
	}
	t.Logf("%#v", path)
}


<|start_filename|>dots/db/gorms/dao_base.go<|end_filename|>
package gorms

import (
	"github.com/scryinfo/dot/dot"
	"gorm.io/gorm"
)

const DaoBaseTypeID = "06ce4450-161e-44aa-8695-527a97bf57c5"

type DaoBase struct {
	Wrapper *Gorms `dot:""`
	//todo add
}

//WithTx with transaction, if return err != nil then rollback, or commit the transaction
func (c *DaoBase) WithTx(task func(tx *gorm.DB) error) error {
	var err error
	if task != nil {
		err = c.Wrapper.GetDb().Transaction(task)
	}
	return err
}

//DaoBaseTypeLives
func DaoBaseTypeLives() []*dot.TypeLives {
	tl := &dot.TypeLives{
		Meta: dot.Metadata{TypeID: DaoBaseTypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
			return &DaoBase{}, nil
		}},
		Lives: []dot.Live{
			{
				LiveID:    DaoBaseTypeID,
				RelyLives: map[string]dot.LiveID{"Wrapper": GormTypeID},
			},
		},
	}

	lives := []*dot.TypeLives{tl}

	return lives
}

//GenerateDaoBaseByDb this func is for test
func GenerateDaoBaseByDb(db *Gorms) *DaoBase {
	base := &DaoBase{db}
	return base
}


<|start_filename|>dots/gindot/ui.go<|end_filename|>
package gindot

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/scryg/sutils/sfile"
	"go.uber.org/zap"
	"net/http"
	"os"
	"path"
	"path/filepath"
)

const UiTypeID = "d9972be7-cef9-464c-9bbb-d1f11abea803" //type id of dot

type configUi struct {
	UrlRelativePath string `json:"urlRelativePath"` //relative path of url
	ResRelativePath string `json:"resRelativePath"` //relative path of resource， The order of locating files is: absolute path, relative path，executable path，current path，user path
	Paths           []struct {
		RelativePath string `json:"relativePath"`
		Value        string `json:"value"` // the static resource of path, it is file or folder
	} `json:"paths"`
	MainHTMlName string     `json:"mainHTMlName"` //maybe home.html or index.html
	NoCompress   bool       `json:"noCompress"`
	Encodings    []Encoding `json:"encodings"` //default are br-->gzip
}

//Ui  add static resource into gin
type Ui struct {
	Engine_ *Engine `dot:""`

	router       *gin.RouterGroup
	config       configUi
	executePath  string //executable path
	currentPath  string //current path
	userPath     string //user path
	relativePath string //relative path
}

func (c *Ui) Injected(l dot.Line) error {
	c.router = c.Engine_.GinEngine().Group(c.config.UrlRelativePath)
	c.router.Use(func(ctx *gin.Context) {
		ctx.Handler()
	})
	if len(c.config.MainHTMlName) > 0 {
		c.Engine_.GinEngine().GET("/", func(ctx *gin.Context) {
			ctx.Redirect(http.StatusFound, c.UrlRelativePath()+"/"+c.config.MainHTMlName)
		})
		c.Engine_.GinEngine().GET("/home", func(ctx *gin.Context) {
			ctx.Redirect(http.StatusFound, c.UrlRelativePath()+"/"+c.config.MainHTMlName)
		})
		c.Engine_.GinEngine().GET("/index", func(ctx *gin.Context) {
			ctx.Redirect(http.StatusFound, c.UrlRelativePath()+"/"+c.config.MainHTMlName)
		})
	}
	return nil
}

//Start start the gin
func (c *Ui) Start(ignore bool) error {
	logger := dot.Logger()
	for _, it := range c.config.Paths {
		res := c.ResAbsolutePath(it.Value)
		if len(res) > 0 {
			logger.Debugln("Ui", zap.String("", res))
			if sfile.IsDir(res) {
				if c.config.NoCompress {
					c.router.Static(it.RelativePath, res)
				} else {
					//urlPrePath := path.Join(c.router.BasePath(), it.RelativePath)
					//if it.RelativePath[len(it.RelativePath) -1] == '/' && urlPrePath[len(urlPrePath) -1] != '/' {
					//	urlPrePath += "/"
					//}
					if len(c.config.Encodings) < 1 {
						c.config.Encodings = supportedEncodings[:]
					}
					handler := NewFileServer(res, "filepath", c.config.Encodings)
					urlPattern := path.Join(it.RelativePath, "/*filepath")
					c.router.GET(urlPattern, handler.Handler)
					c.router.HEAD(urlPattern, handler.Handler)
				}
			} else if sfile.IsFile(res) {
				c.router.StaticFile(it.RelativePath, res)
			} else {
				logger.Errorln("", zap.String("", "can not: "+it.Value+" realy: "+res))
			}
		} else {
			logger.Errorln("", zap.String("", fmt.Sprintf("can not find : %s  under (%s, %s, %s, %s)", it.RelativePath, c.relativePath, c.executePath, c.currentPath, c.userPath)))
		}
	}
	return nil
}

func (c *Ui) Router() *gin.RouterGroup {
	return c.router
}

func (c *Ui) UrlRelativePath() string {
	return c.config.UrlRelativePath
}

func (c *Ui) ResRelativePath() string {
	return c.relativePath
}

func (c *Ui) SetResRelativePath(relativePath string) {
	c.relativePath = ""
	c.relativePath = c.ResAbsolutePath(relativePath)
}

//ResAbsolutePath the order of locating files is: absolute path, relative path，executable path，current path，user path
//if do not find, then return ""
func (c *Ui) ResAbsolutePath(res string) string {
	if filepath.IsAbs(res) {
		if sfile.ExistFile(res) {
			return res
		}
	}

	if len(c.relativePath) > 0 {
		temp := filepath.Join(c.relativePath, res)
		if sfile.ExistFile(temp) {
			return temp
		}
	}

	if len(c.executePath) > 0 {
		temp := filepath.Join(c.executePath, res)
		if sfile.ExistFile(temp) {
			return temp
		}
	}

	if len(c.currentPath) > 0 {
		temp := filepath.Join(c.currentPath, res)
		if sfile.ExistFile(temp) {
			return temp
		}
	}

	if len(c.userPath) > 0 {
		temp := filepath.Join(c.userPath, res)
		if sfile.ExistFile(temp) {
			return temp
		}
	}

	return ""
}

//construct dot
func newUi(conf []byte) (*Ui, error) {
	dconf := &configUi{}
	err := dot.UnMarshalConfig(conf, dconf)
	if err != nil {
		return nil, err
	}

	ui := &Ui{config: *dconf}
	d := ui
	{
		ui.executePath, err = os.Executable()
		if err != nil {
			dot.Logger().Errorln("Ui", zap.Error(err))
			ui.executePath = ""
		} else {
			ui.executePath = filepath.Dir(ui.executePath)
		}
		ui.currentPath, err = os.Getwd()
		if err != nil {
			dot.Logger().Errorln("Ui", zap.Error(err))
			ui.currentPath = ""
		}
		ui.userPath, err = os.UserHomeDir()
		if err != nil {
			dot.Logger().Errorln("Ui", zap.Error(err))
			ui.userPath = ""
		}

		if len(ui.config.ResRelativePath) > 0 {
			////for dev
			if !sfile.ExistFile(ui.ResAbsolutePath("dist")) {
				dot.Logger().Debugln("UiPreAdd", zap.String("", ui.config.ResRelativePath))
				ui.SetResRelativePath(ui.config.ResRelativePath)
			}
		}

		err = nil
	}

	return d, err
}

//UiTypeLives generate data for structural  dot,  include gindot.Engine
func UiTypeLives() []*dot.TypeLives {
	lives := []*dot.TypeLives{{
		Meta: dot.Metadata{TypeID: UiTypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
			return newUi(conf)
		}},

		Lives: []dot.Live{
			{
				LiveID:    UiTypeID,
				RelyLives: map[string]dot.LiveID{"Engine_": EngineLiveID},
			},
		},
	}}
	lives = append(lives, GinDotTypeLives()...)
	return lives
}

//return config of Ui
func UiConfigTypeLive() *dot.ConfigTypeLive {
	return &dot.ConfigTypeLive{
		TypeIDConfig: UiTypeID,
		ConfigInfo:   &configUi{},
	}
}


<|start_filename|>demo/inject/main.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package main

import (
	"fmt"
	"reflect"
	"unsafe"
)

func main() {
	SetPrivateField()
}

func SetPrivateField() {
	{ //Pointer
		t := &T{fPtr: nil, fInterface: nil}
		field := reflect.ValueOf(t).Elem().FieldByName("fPtr")
		if field.CanAddr() { // have to true
			fp := field.Addr().Pointer()             //Get the field address
			fpp := ((**uintptr)(unsafe.Pointer(fp))) //Convert to pointer
			t2 := &T2{f2: 10}
			fp2 := (*uintptr)(unsafe.Pointer(t2))
			*fpp = fp2
			fmt.Println(t.fPtr.f2)
		}
	}
	{ //interface
		t := &T{fPtr: nil, fInterface: nil}
		field := reflect.ValueOf(t).Elem().FieldByName("fInterface")
		if field.CanAddr() {
			fp := field.Addr().Pointer()
			fpp := ((*interface{})(unsafe.Pointer(fp)))

			{ // Method 1, need to confirm interface type when compiling
				var t2 Inter2 = &Inter2Imp{F: 20}
				fp2 := (*interface{})(unsafe.Pointer(&t2))
				*fpp = *fp2
			}

			{ // Method 2, Generally use reflection to realize it
				var t2 interface{} = &Inter2Imp{F: 15}
				v := reflect.ValueOf(t2).Convert(field.Type()) // Must convert to  field type,since type in t2 is interface{}, not Inter2 type
				v2 := reflect.ValueOf(v)                       // Get ptr value through reflection, cannot use Pointer here，it will panic，Since t2 is not pointer type
				ptr := v2.FieldByName("ptr")
				fp2 := (*interface{})(unsafe.Pointer(ptr.Pointer()))
				*fpp = *fp2
			}
		}
		if t.fInterface != nil {
			fmt.Println(t.fInterface.Get())
		}
	}

}

type T struct {
	fPtr       *T2
	fInterface Inter2
}

type T2 struct {
	f2 int
}

type Inter2 interface {
	Get() int
}

type Inter2Imp struct {
	F int
}

func (c *Inter2Imp) Get() int {
	return c.F
}


<|start_filename|>dots/grpc/lb/client_resolver.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package lb

import (
	"google.golang.org/grpc/resolver"
)

//ClientV8 load balancing
type clientBuilder struct {
	scheme       string
	serviceAddrs map[string][]string //key service name, value service corresponding address(such as 12.23.23.23：909）
}

func NewClientBuilder(schema string, serviceAddrs map[string][]string) resolver.Builder {
	return &clientBuilder{
		scheme:       schema,
		serviceAddrs: serviceAddrs,
	}
}

func (c *clientBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
	r := &clientResolver{
		target:     target,
		conn:       cc,
		addrsStore: c.serviceAddrs,
	}
	r.start()
	return r, nil
}
func (c *clientBuilder) Scheme() string { return c.scheme }

type clientResolver struct {
	target     resolver.Target
	conn       resolver.ClientConn
	addrsStore map[string][]string
}

func (c clientResolver) ResolveNow(resolver.ResolveNowOptions) {
}

func (c clientResolver) Close() {
}

func (c *clientResolver) start() {
	addrStrs := c.addrsStore[c.target.Endpoint]
	addrs := make([]resolver.Address, len(addrStrs))
	for i, s := range addrStrs {
		addrs[i] = resolver.Address{Addr: s}
	}
	c.conn.UpdateState(resolver.State{Addresses: addrs})
}


<|start_filename|>lib/scrypto/ende_test.go<|end_filename|>
package scrypto

import (
	"encoding/json"
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestEndeData(t *testing.T) {
	data := EndeData{
		PublicKey:       []byte{1},
		EndeType:        "test",
		Signature:       []byte{3},
		SignedPublicKey: []byte{},
		EnData:          false,
		Body:            []byte{10},
	}

	{
		bytes, err := json.Marshal(&data)
		assert.Equal(t, nil, err)
		assert.NotNil(t, bytes)

		var jData EndeData
		err = json.Unmarshal(bytes, &jData)
		assert.Equal(t, nil, err)

		assert.Equal(t, data, jData)
	}
	{
		bytes, err := json.Marshal(data)
		assert.Equal(t, nil, err)
		assert.NotNil(t, bytes)

		var jData EndeData
		err = json.Unmarshal(bytes, &jData)
		assert.Equal(t, nil, err)

		assert.Equal(t, data, jData)
	}
}


<|start_filename|>dots/line/line_imp_test.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package line

import (
	"github.com/scryinfo/dot/dot"
	"reflect"
	"testing"
)

func TestLineImp_Start(t *testing.T) {
	l, _ := BuildAndStart(func(l dot.Line) error {
		_ = l.PreAdd(&dot.TypeLives{
			Meta: dot.Metadata{
				TypeID: "one1",
				NewDoter: func(conf []byte) (dot dot.Dot, err error) {
					t := 1
					return &t, nil
				},
			},
			Lives: []dot.Live{
				{
					LiveID: "one1-1",
				},
				{
					LiveID: "one1-2",
				},
			},
		})

		_ = l.PreAdd(&dot.TypeLives{
			Meta: dot.Metadata{
				TypeID: "one3",
				NewDoter: func(conf []byte) (dot dot.Dot, err error) {
					t := 1
					return &t, nil
				},
			},
			Lives: []dot.Live{
				{
					LiveID: "one3-1",
				},
			},
		})

		_ = l.PreAdd(&dot.TypeLives{
			Meta: dot.Metadata{
				TypeID: "two",
				NewDoter: func(conf []byte) (dot dot.Dot, err error) {
					t := 1
					return &t, nil
				},
			},
			Lives: []dot.Live{
				{
					LiveID:    "two-1",
					RelyLives: map[string]dot.LiveID{"_": "one1-1"},
				},
				{
					LiveID:    "two-2",
					RelyLives: map[string]dot.LiveID{"_": "one1-2"},
				},
			},
		})

		_ = l.PreAdd(&dot.TypeLives{
			Meta: dot.Metadata{
				TypeID: "three",
				NewDoter: func(conf []byte) (dot dot.Dot, err error) {
					t := 1
					return &t, nil
				},
			},
			Lives: []dot.Live{
				{
					LiveID:    "three-1",
					RelyLives: map[string]dot.LiveID{"_": "one1-1"},
				},
				{
					LiveID:    "three-2",
					RelyLives: map[string]dot.LiveID{"_": "two-2"},
				},
			},
		})

		{ //circle
			_ = l.PreAdd(&dot.TypeLives{
				Meta: dot.Metadata{
					TypeID: "circle",
					NewDoter: func(conf []byte) (dot dot.Dot, err error) {
						t := 1
						return &t, nil
					},
				},
				Lives: []dot.Live{
					{
						LiveID:    "circle-1",
						RelyLives: map[string]dot.LiveID{"_": "circle2-1"},
					},
					{
						LiveID: "circle-2",
					},
				},
			})

			_ = l.PreAdd(&dot.TypeLives{
				Meta: dot.Metadata{
					TypeID: "circle2",
					NewDoter: func(conf []byte) (dot dot.Dot, err error) {
						t := 1
						return &t, nil
					},
				},
				Lives: []dot.Live{
					{
						LiveID:    "circle2-1",
						RelyLives: map[string]dot.LiveID{"_": "circle3-1"},
					},
				},
			})

			_ = l.PreAdd(&dot.TypeLives{
				Meta: dot.Metadata{
					TypeID: "circle3",
					NewDoter: func(conf []byte) (dot dot.Dot, err error) {
						t := 1
						return &t, nil
					},
					RelyTypeIDs: []dot.TypeID{"circle"},
				},
				Lives: []dot.Live{
					{
						LiveID:    "circle3-1",
						RelyLives: map[string]dot.LiveID{"_": "circle-1"},
					},
				},
			})

			_ = l.PreAdd(&dot.TypeLives{ //duplication
				Meta: dot.Metadata{
					TypeID: "circle3",
					NewDoter: func(conf []byte) (dot dot.Dot, err error) {
						t := 1
						return &t, nil
					},
					RelyTypeIDs: []dot.TypeID{"circle"},
				},
				Lives: []dot.Live{
					{
						LiveID:    "circle3-1",
						RelyLives: map[string]dot.LiveID{"_": "circle-1"},
					},
				},
			})
		}

		return nil
	})

	lImp, _ := l.(*lineImp)

	order, err := lImp.relyOrder()
	if len(order) != 11 {
		t.Error("len(order) != 11")
	}

	if err == nil {
		t.Error("error == nil, circle dependency")
	}

	_ = l.ToLifer().Stop(true)
	_ = l.ToLifer().Destroy(true)
}

func TestLineImp_InterfaceOrPoint(t *testing.T) {
	type Dot1 struct {

	}

	type Dot2 struct {
		Dot1 Dot1 `dot:""`
	}

	l, err := BuildAndStart(func(l dot.Line) error {
		_ = l.PreAdd(&dot.TypeLives{
			Meta: dot.Metadata{
				TypeID: "dot1",
				NewDoter: func(conf []byte) (dot dot.Dot, err error) {
					return &Dot1{}, nil
				},
			},
			Lives: []dot.Live{
				{
					LiveID: "dot1",
				},
			},
		},&dot.TypeLives{
			Meta:  dot.Metadata{
				TypeID:      "dot2",
				RefType:     reflect.TypeOf((*Dot2)(nil)).Elem(),
			},
		})

		return nil
	})

	if err == nil {
		t.Error("the field is not pointer")
	}

	_ = l.ToLifer().Stop(true)
	_ = l.ToLifer().Destroy(true)
}


<|start_filename|>dots/grpc/gserver/websocket.go<|end_filename|>
// <NAME>.  All rights reserved.
// license that can be found in the license file.

package gserver

import (
	"github.com/scryinfo/dot/dots/gindot"
	"net/http"
	"os"

	"github.com/gin-gonic/gin"
	"github.com/improbable-eng/grpc-web/go/grpcweb"
	"go.uber.org/zap"
	"google.golang.org/grpc"

	"github.com/scryinfo/dot/dot"
)

const (
	WebSocketTypeID = "27709862-0a7b-48e9-8427-5bbc86760c41"
)

// WebSocket component makes it possible the full-duplex communication with low latency
// between a gRPC-WebSocket request and a remote standard gRPC server.
type WebSocket struct {
	GinEngine *gindot.Engine `dot:""`

	wrappedServer *grpcweb.WrappedGrpcServer
}

//WebSocketTypeLives
func WebSocketTypeLives() []*dot.TypeLives {
	lives := []*dot.TypeLives{{
		Meta: dot.Metadata{TypeID: WebSocketTypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
			return &WebSocket{}, nil
		}},
		//Lives: []dot.Live{
		//	{
		//		TypeID: WebSocketTypeID,
		//		RelyLives: map[string]dot.LiveID{
		//			"GinEngine": gindot.EngineTypeID,
		//		},
		//	},
		//},
	}}
	lives = append(lives, gindot.GinDotTypeLives()...)
	return lives
}

func (s *WebSocket) Stop(ignore bool) error {
	if s.wrappedServer != nil {
		s.wrappedServer = nil
	}
	return nil
}

// Wrap wraps the given grpcServer to allow for handling grpc-web requests of websockets - enabling bidirectional requests.
//
// Under the hood, Wrap takes a HTTP request from gin.Context and if it is a gRPC-WebSocket request wraps it with a compatibility layer
// to transform it to a standard gRPC request for the wrapped gRPC server and transforms the request to comply with
// the gRPC-Web protocol.
//
// Through this mechanism, client (e.g. browser) is able to fully take advantage of WebSocket communication with remote
// gRPC service server, initially routed by the HTTP GET method and the URLs of resources that are registered on gRPC server
//
// Note: this Wrap method can only be called before the underlying gin.Engine starts running, besides the caller must insure that
// all the grpc service servers get appropriately registered with the standard gRPC server.
func (s *WebSocket) Wrap(grpcServer *grpc.Server) {
	// Argument validation of the passed grpcServer
	if grpcServer == nil {
		dot.Logger().Errorln("nil argument of grpcServer not allowed")
		os.Exit(1)
	}
	if len(grpcServer.GetServiceInfo()) == 0 {
		dot.Logger().Errorln("no service registered with grpcServer")
		os.Exit(1)
	}

	// Control the behaviour of the gRPC-WebSocket wrapper (e.g. modifying CORS behaviour) using `With*` options.
	options := []grpcweb.Option{
		// Allows for handling grpc-web requests of websockets - enabling bidirectional requests.
		grpcweb.WithWebsockets(true),
		// Accept all requests from remote origins,
		// don't check whether the origin of the request matches the host of the request.
		grpcweb.WithWebsocketOriginFunc(func(req *http.Request) bool {
			return true
		}),
		// Not allow requests incoming with a path prefix added to the URL,
		// exposing the endpoint as the root resource, to avoid
		// the performance cost of path processing for every request.
		grpcweb.WithAllowNonRootResource(false),
		// Only allow CORS requests for registered endpoints,
		// not allow handling gRPC requests for unknown endpoints (e.g. for proxying).
		grpcweb.WithCorsForRegisteredEndpointsOnly(true),
	}
	s.wrappedServer = grpcweb.WrapServer(grpcServer, options...)

	// HandlerFunc takes a HTTP request from gin.Context and if it is a gRPC-WebSocket request wraps it with a compatibility layer
	// to transform it to a standard gRPC request for the wrapped gRPC server and transforms the request to comply with
	// the gRPC-Web protocol.
	handlerFunc := func(ctx *gin.Context) {
		dot.Logger().Debugln("WebSocket", zap.String("", ctx.Request.RequestURI))

		if s.wrappedServer.IsGrpcWebSocketRequest(ctx.Request) {
			s.wrappedServer.ServeHTTP(ctx.Writer, ctx.Request)
			return
		}

		ctx.String(http.StatusForbidden, "Not a valid gRPC-WebSocket request!")
	}

	// registers the handlerFunc (without any middleware) with all URLs of resources that are registered on gRPC server.
	urls := grpcweb.ListGRPCResources(grpcServer)
	for _, url := range urls {
		s.GinEngine.GinEngine().GET(url, handlerFunc)
	}
}


<|start_filename|>dots/grpc/gserver/gin_nobl.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package gserver

import (
	"net/http"
	"reflect"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/improbable-eng/grpc-web/go/grpcweb"
	"go.uber.org/zap"
	"google.golang.org/grpc"

	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/gindot"
)

const (
	GinNoblTypeID = "3c9e8119-3d42-45bd-98f9-32939c895c6d"
)

//support the http and tcp
type ginNobl struct {
	ServerNobl        ServerNobl     `dot:""`
	GinRouter         *gindot.Router `dot:""`
	wrappedGrpcServer *grpcweb.WrappedGrpcServer
	preUrl            string
}

//GinNoblTypeLives Data structure needed when generating newer component
func GinNoblTypeLives() []*dot.TypeLives {

	lives := []*dot.TypeLives{{
		Meta: dot.Metadata{TypeID: GinNoblTypeID, RefType: reflect.TypeOf((*ginNobl)(nil)).Elem(), NewDoter: func(conf []byte) (dot dot.Dot, err error) {
			return &ginNobl{}, nil
		}},
		Lives: []dot.Live{
			{
				LiveID:    GinNoblTypeID,
				RelyLives: map[string]dot.LiveID{"GinRouter": gindot.RouterTypeID, "ServerNobl": ServerNoblTypeID},
			},
		},
	}}

	lives = append(lives, ServerNoblTypeLives()...)
	lives = append(lives, gindot.RouterTypeLives()...)
	return lives
}

//Run after every component finished start, this can ensure all service has been registered on grpc server
func (c *ginNobl) AfterAllStart(dot.Line) {
	if rp := c.GinRouter.RelativePath(); len(rp) > 0 && rp != "/" {
		if !strings.HasPrefix(rp, "/") {
			rp = "/" + rp
		}
		if !strings.HasSuffix(rp, "/") {
			rp += "/"
		}
		c.preUrl = rp
	} else {
		c.preUrl = ""
	}
	c.startServer()
}

//Stop stop dot
func (c *ginNobl) Stop(bool) error {
	if c.wrappedGrpcServer != nil {
		c.wrappedGrpcServer = nil
	}
	return nil
}

func (c *ginNobl) Server() *grpc.Server {
	return c.ServerNobl.Server()
}

func (c *ginNobl) startServer() {

	logger := dot.Logger()
	// Control the behaviour of the gRPC-WebSocket wrapper (e.g. modifying CORS behaviour) using `With*` options.
	options := []grpcweb.Option{
		// Allows for handling grpc-web requests of websockets - enabling bidirectional requests.
		grpcweb.WithWebsockets(true),
		// Accept all requests from remote origins,
		// don't check whether the origin of the request matches the host of the request.
		grpcweb.WithWebsocketOriginFunc(func(req *http.Request) bool {
			return true
		}),
		// Not allow requests incoming with a path prefix added to the URL,
		// exposing the endpoint as the root resource, to avoid
		// the performance cost of path processing for every request.
		grpcweb.WithAllowNonRootResource(false),
		// Only allow CORS requests for registered endpoints,
		// not allow handling gRPC requests for unknown endpoints (e.g. for proxying).
		grpcweb.WithCorsForRegisteredEndpointsOnly(true),
		grpcweb.WithAllowedRequestHeaders([]string{"Access-Control-Allow-Origin:*", "Access-Control-Allow-Methods:*"}),
	}//todo #49

	c.wrappedGrpcServer = grpcweb.WrapServer(c.Server(), options...)

	handle := func(ctx *gin.Context) {
		logger.Debugln("ginNobl", zap.String("", ctx.Request.RequestURI))

		if c.wrappedGrpcServer.IsGrpcWebRequest(ctx.Request) {
			if len(c.preUrl) > 0 { //todo #49
				old := ctx.Request.URL.Path
				if strings.HasPrefix(old, c.preUrl) {
					index := len(c.preUrl) - 1
					ctx.Request.URL.Path = old[index:]
				}
			}

			resp := ctx.Writer
			resp.Header().Set("Access-Control-Allow-Origin", "*")  //
			resp.Header().Set("Access-Control-Allow-Methods", "*") //
			resp.Header().Add("Access-Control-Allow-Headers", "content-type,x-grpc-web,x-user-agent")
			c.wrappedGrpcServer.ServeHTTP(resp, ctx.Request)
			return
		} else if c.wrappedGrpcServer.IsGrpcWebSocketRequest(ctx.Request) {
			if len(c.preUrl) > 0 { // because can not set the "endpointFunc" of WrapServer, do this so so
				old := ctx.Request.URL.Path
				if strings.HasPrefix(old, c.preUrl) {
					index := len(c.preUrl) - 1
					ctx.Request.URL.Path = old[index:]
				}
			}
			c.wrappedGrpcServer.HandleGrpcWebsocketRequest(ctx.Writer, ctx.Request)
			return
		} else {
			ctx.String(http.StatusOK, "no rpc")
		}
	}

	url := "/*rpc"

	c.GinRouter.Router().POST(url, handle)
	c.GinRouter.Router().OPTIONS(url, func(ctx *gin.Context) {
		ctx.Header("Access-Control-Allow-Origin", "*")  //
		ctx.Header("Access-Control-Allow-Methods", "*") //
		ctx.Header("Access-Control-Allow-Headers", "content-type,x-grpc-web,x-user-agent")
		ctx.String(http.StatusOK, "ok")
	})
	c.GinRouter.Router().GET(url, handle) //for websocket
}


<|start_filename|>tools/dotconf/data/confload.go<|end_filename|>
package data

import (
	"fmt"
	"github.com/gookit/config"
	"github.com/gookit/config/json"
)

//For storage configuration
type Config struct {
	Dc *config.Config
}

//Configuring storage object instantiation
func NewConfig() *Config {
	return &Config{config.New("default")}
}

//Return loaded data
func (sc *Config) ConfLoad(configPaths ...string) (map[string]interface{}, error) {
	_, err := sc.LoadConfigFile(configPaths...)
	if err != nil {
		return nil, err
	}
	return sc.Dc.Data(), nil
}

//Get the Json bytes configuration information of this part by key
//Key uses `.` as an interval to represent hierarchical relationships
func (sc *Config) GetJsonByte(key string) ([]byte, error) {
	var subConf interface{}
	var ok bool
	if key != "" {
		subConf, ok = sc.Dc.Get(key)
		if !ok {
			return nil, fmt.Errorf("can't get data by key")
		}
	} else {
		subConf = sc.Dc.Data()
	}
	jsonByte, err := json.Encoder(subConf)
	if err != nil {
		return nil, err
	}
	return jsonByte, nil
}


<|start_filename|>dot/slog.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package dot

import (
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

//Level level of log
type Level = zapcore.Level

const (
	//LogLiveID log dot live id
	LogLiveID = "d8299d21-4f43-48bd-9a5c-654c4395ea17"

	// DebugLevel logs are typically voluminous, and are usually disabled in
	// production.
	DebugLevel = zapcore.DebugLevel
	// InfoLevel is the default logging priority.
	InfoLevel = zapcore.InfoLevel
	// WarnLevel logs are more important than Info, but don't need individual
	// human review.
	WarnLevel = zapcore.WarnLevel
	// ErrorLevel logs are high-priority. If an application is running smoothly,
	// it shouldn't generate any error-level logs.
	ErrorLevel = zapcore.ErrorLevel
	//FatalLevel DPanicLevel logs are particularly important errors. In development the
	// logger panics after writing the message.
	FatalLevel = zapcore.FatalLevel
)

//Default log, if not created, then returned log will be output to “before.log” file，all log will be returned
var logger SLogger = nil

//Logger Return default log, this API is used to call log easily
//This method does not consider thread security, Adjusting value is not suggested after program initialization
//Note: Default log, if log is not created, then returned log will be output to control panel, all log will be output
func Logger() SLogger {
	return logger
}

//SetLogger Set default log,
//This method does not consider thread security, Adjusting value is not suggested after program initialization
func SetLogger(log SLogger) {
	if logger != nil {
		if d, ok := logger.(Destroyer); ok {
			_ = d.Destroy(true)
		}
		logger = nil
	}
	logger = log
}

//MakeStringer Generate log string
type MakeStringer func() string

//SLogger log belongs to one component Dot, but it is too basic, most Dot need it, so defined it to dot.go file
//All log calling should not call function in parameters, function run priorly than log, if must call function, you should use callback(must run normally)
//S represents scry info, log name used frequently so add s to distinguish it
type SLogger interface {
	//GetLevel get level
	GetLevel() Level
	//SetLevel set level
	SetLevel(level Level)
	//Debugln debug
	Debugln(msg string, fields ...zap.Field)
	//Debug debug
	Debug(mstr MakeStringer)
	//Infoln info
	Infoln(msg string, fields ...zap.Field)
	//Info info
	Info(mstr MakeStringer)
	//Warnln warn
	Warnln(msg string, fields ...zap.Field)
	//Warn warn
	Warn(mstr MakeStringer)
	//Errorln error
	Errorln(msg string, fields ...zap.Field)
	//Error error
	Error(mstr MakeStringer)
	//Fatalln fatal
	Fatalln(msg string, fields ...zap.Field)
	//Fatal fatal
	Fatal(mstr MakeStringer)
	//NewLogger return new logger
	NewLogger(callerSkip int) SLogger
}

//LogConfig log config
type LogConfig struct {
	File  string `json:"file" toml:"file" yaml:"file"`
	Level string `json:"level" toml:"level" yaml:"level"`
	Time  string `json:"time" toml:"time" yaml:"time"` //hour,h,day,d,month,m,y,year
}

//Initialize one default log, let program use log at first, output to “before.log” file, all log will be output
func init() {
	SetLogger(newBlog())
}


<|start_filename|>dots/slog/slog_imp_test.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package slog


<|start_filename|>demo/uuid/main.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package main

import (
	"fmt"

	"github.com/scryinfo/scryg/sutils/uuid"
)

func main() {
	fmt.Println(uuid.GetUuid())
}


<|start_filename|>dots/grpc/conns/etcd_conns.go<|end_filename|>
package conns

//
//import (
//	"context"
//	"crypto/tls"
//	"encoding/json"
//	"time"
//
//	"github.com/pkg/errors"
//	"github.com/scryinfo/dot/dot"
//	"github.com/scryinfo/dot/utils"
//	clientv3 "go.etcd.io/etcd/client/v3"
//	"go.etcd.io/etcd/client/v3/naming/endpoints"
//	"go.etcd.io/etcd/client/v3/naming/resolver"
//	"google.golang.org/grpc"
//	gresolver "google.golang.org/grpc/resolver"
//)
//
//const EtcdConnsTypeID = "c91c8c68-281a-4949-8e55-3516664e80c7"
//
////see https://github.com/etcd-io/etcd/blob/master/Documentation/dev-guide/grpc_naming.md
//
//type configEtcdConns struct {
//	Endpoints   []string        `json:"endpoints"`
//	DialTimeout int64           `json:"dialTimeout"`
//	Tls         utils.TlsConfig `json:"tls"` //not sure about the Mutual Authentication can work
//
//	Names []string `json:"names"` //服务名字
//}
//
////etcd client
//type EtcdConns struct {
//	etcdClient   *clientv3.Client
//	grpcManager  endpoints.Manager //ref the etcdClient
//	grpcResolver gresolver.Builder
//	conns        map[string]*grpc.ClientConn
//	conf         configEtcdConns
//	ctx          context.Context
//	cancelFun    context.CancelFunc
//}
//
//func (c *EtcdConns) ClientConn(serviceName string) *grpc.ClientConn {
//	var conn *grpc.ClientConn = nil
//	if len(c.conns) > 0 {
//		if c, ok := c.conns[serviceName]; ok {
//			conn = c
//		}
//	}
//	return conn
//}
//
//func (c *EtcdConns) EtcdClient() *clientv3.Client {
//	return c.etcdClient
//}
//
//func (c *EtcdConns) Context() context.Context {
//	return c.ctx
//}
//
//func (c *EtcdConns) CancelFun() context.CancelFunc {
//	return c.cancelFun
//}
//
//func (c *EtcdConns) Manager() endpoints.Manager {
//	return c.grpcManager
//}
//func (c *EtcdConns) Builder() gresolver.Builder {
//	return c.grpcResolver
//}
//func (c *EtcdConns) RegisterServer(ctx context.Context, name string, addr string) error {
//	if c.grpcManager != nil {
//		opt := make([]*endpoints.UpdateWithOpts, 1)
//		opt[0] = endpoints.NewAddUpdateOpts(name, endpoints.Endpoint{
//			Addr:     addr,
//			Metadata: nil,
//		})
//		return c.grpcManager.Update(ctx, opt)
//	}
//	return errors.New("GRPC Resolver is null")
//}
//func (c *EtcdConns) UnRegisterServer(ctx context.Context, name string, addr string) error {
//	if c.grpcManager != nil {
//		opt := make([]*endpoints.UpdateWithOpts, 1)
//		opt[0] = endpoints.NewAddUpdateOpts(name, endpoints.Endpoint{
//			Addr:     addr,
//			Metadata: nil,
//		})
//		return c.grpcManager.DeleteEndpoint(ctx, name)
//	}
//	return errors.New("GRPC Resolver is null")
//}
//
////func (c *EtcdConns) Create(l dot.Line) error {
////
////}
////func (c *EtcdConns) Injected(l dot.Line) error {
////
////}
////func (c *EtcdConns) AfterAllInject(l dot.Line) {
////
////}
////
////func (c *EtcdConns) Start(ignore bool) error {
////
////}
//
//func (c *EtcdConns) Stop(ignore bool) error {
//	if c.cancelFun != nil {
//		c.cancelFun()
//	}
//	if c.etcdClient != nil {
//		c.etcdClient.Close()
//		//c.etcdClient = nil // maybe somewhere use the client, so do not set nil
//	}
//	return nil
//}
//
////func (c *EtcdConns) Destroy(ignore bool) error {
////
////}
//
////construct dot
//func newEtcdConns(conf []byte) (dot.Dot, error) {
//	dconf := &configEtcdConns{}
//	err := dot.UnMarshalConfig(conf, dconf)
//	if err != nil {
//		return nil, err
//	}
//
//	d := &EtcdConns{conf: *dconf, conns: make(map[string]*grpc.ClientConn)}
//	d.ctx, d.cancelFun = context.WithCancel(context.Background())
//	{
//		var tlsConfig *tls.Config
//		{
//			tlsConfig, err = utils.GetTlsConfig(&d.conf.Tls)
//			if err != nil {
//				return nil, err
//			}
//		}
//		if d.conf.DialTimeout < 1 {
//			d.conf.DialTimeout = 6
//		}
//
//		d.etcdClient, err = clientv3.New(clientv3.Config{
//			Endpoints:   d.conf.Endpoints,
//			DialTimeout: time.Duration(d.conf.DialTimeout) * time.Second,
//			TLS:         tlsConfig,
//			Context:     d.ctx,
//		})
//		if err != nil {
//			return nil, err
//		}
//	}
//	//todo target
//	d.grpcManager, err = endpoints.NewManager(d.etcdClient, "")
//	if err != nil {
//		return nil, err
//	}
//	d.grpcResolver, err = resolver.NewBuilder(d.etcdClient)
//	if err != nil {
//		return nil, err
//	}
//	if len(d.conf.Names) > 0 {
//
//		for _, n := range d.conf.Names {
//			conn, err := grpc.Dial(n, grpc.WithResolvers(d.grpcResolver), grpc.WithInsecure())
//			if err != nil {
//				return nil, err
//			}
//			d.conns[n] = conn
//		}
//	}
//
//	return d, nil
//}
//
////EtcdConnsTypeLives
//func EtcdConnsTypeLives() []*dot.TypeLives {
//	tl := &dot.TypeLives{
//		Meta: dot.Metadata{TypeID: EtcdConnsTypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
//			return newEtcdConns(conf)
//		}},
//		//Lives: []dot.Live{
//		//	{
//		//		LiveID:    EtcdConnsTypeID,
//		//		RelyLives: map[string]dot.LiveID{"some field": "some id"},
//		//	},
//		//},
//	}
//
//	lives := []*dot.TypeLives{tl}
//
//	return lives
//}
//
////EtcdConnsConfigTypeLive
//func EtcdConnsConfigTypeLive() *dot.ConfigTypeLive {
//	paths := make([]string, 0)
//	paths = append(paths, "")
//	return &dot.ConfigTypeLive{
//		TypeIDConfig: EtcdConnsTypeID,
//		ConfigInfo:   &configEtcdConns{},
//	}
//}
//
//func NewEtcd(endpoints []string, names []string) *EtcdConns {
//	conf := &configEtcdConns{
//		Endpoints:   endpoints,
//		DialTimeout: 10,
//		Tls:         utils.TlsConfig{},
//		Names:       names,
//	}
//	bs, _ := json.Marshal(conf)
//	re, _ := newEtcdConns(bs)
//	etcdConns, _ := re.(*EtcdConns)
//	return etcdConns
//}


<|start_filename|>demo/redis/conn.go<|end_filename|>
package main

import "github.com/go-redis/redis/v8"

func conn(addr string) *redis.Client {
    return redis.NewClient(&redis.Options{
        Addr:     addr,
        Username: "",
        Password: "",
        DB:       0,
    })
}


<|start_filename|>sample/event/event.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package main

import (
	"fmt"
	"go.uber.org/zap"
	"os"

	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/line"
	"github.com/scryinfo/scryg/sutils/ssignal"
)

func main() {
	l, err := line.BuildAndStart(add) //first step create line and dots
	if err != nil {
		dot.Logger().Errorln("", zap.Error(err))
		return
	}
	defer line.StopAndDestroy(l, true) //fourth step stop and destroy dots

	//second step ....

	ssignal.WaitCtrlC(func(s os.Signal) bool { //third wait for exit
		return false
	})
}

func add(l dot.Line) error {
	logger := dot.Logger()
	err := l.PreAdd(&dot.TypeLives{
		Meta: dot.Metadata{TypeID: "dotId",
			NewDoter: func(conf []byte) (dot dot.Dot, err error) {
				d := 1
				return &d, nil
			},
		},
	})

	l.ToDotEventer().AddLiveEvents("dotId", &dot.LiveEvents{
		BeforeCreate: func(live *dot.Live, l dot.Line) {
			//do something
			logger.Infoln("BeforeCreate")
		},
		AfterCreate: func(live *dot.Live, l dot.Line) {
			logger.Infoln("AfterCreate")
			if d, ok := live.Dot.(*int); ok {
				logger.Infoln(fmt.Sprintf("dot: %d", *d))
			}
		},
		BeforeStart: func(live *dot.Live, l dot.Line) {
			logger.Infoln("BeforeStart")
		},
		AfterStart: func(live *dot.Live, l dot.Line) {
			logger.Infoln("AfterStart")
		},
		BeforeStop: func(live *dot.Live, l dot.Line) {
			logger.Infoln("BeforeStop")
		},
		AfterStop: func(live *dot.Live, l dot.Line) {
			logger.Infoln("AfterStop")
		},
		BeforeDestroy: func(live *dot.Live, l dot.Line) {
			logger.Infoln("BeforeDestroy")
		},
		AfterDestroy: func(live *dot.Live, l dot.Line) {
			logger.Infoln("AfterDestroy")
		},
	})

	return err
}


<|start_filename|>sample/grpc/nobl/client/client.go<|end_filename|>
// <NAME>.  All rights reserved.
// license that can be found in the license file.

package main

import (
	"context"
	"fmt"
	"github.com/scryinfo/dot/sample/grpc/go_out/hidot"
	"github.com/scryinfo/dot/sample/grpc/nobl"
	"go.uber.org/zap"
	"os"
	"time"

	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/line"
	"github.com/scryinfo/scryg/sutils/ssignal"
)

func main() {
	l, err := line.BuildAndStart(add) //first step create line and dots
	if err != nil {
		dot.Logger().Errorln("", zap.Error(err))
		return
	}
	defer line.StopAndDestroy(l, true) //fourth step stop and destroy dots

	dot.Logger().Infoln("dot ok")
	//second step ....

	go func() {
		dd, _ := l.ToInjecter().GetByLiveID(dot.LiveID(nobl.HiClientTypeID))
		if hiclient, ok := dd.(*nobl.HiClient); ok {
			logger := dot.Logger()
			for i := 0; i < 1000; i++ {
				name := fmt.Sprintf("client: %d", i)
				req, err := hiclient.HiClient().Hi(context.Background(), &hidot.HiReq{Name: name})
				if err != nil {
					logger.Infoln(err.Error())
				} else {
					logger.Infoln(fmt.Sprintf("%s %s", name, req.Name))
				}
				time.Sleep(100 * time.Millisecond)
			}
			logger.Infoln("done")
		}
	}()

	ssignal.WaitCtrlC(func(s os.Signal) bool { //third wait for exit
		return false
	})

}

func add(l dot.Line) error {
	return l.PreAdd(nobl.HiClientTypeLives()...)
}


<|start_filename|>dots/db/gorms/gorms.go<|end_filename|>
package gorms

import (
	"encoding/json"
	"fmt"
	"github.com/pkg/errors"
	"github.com/scryinfo/dot/dot"
	"go.uber.org/zap"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

const (
	//GormTypeID type id
	GormTypeID = "d2b575cd-e38f-4002-b4bd-9dc85fe13fe6"
)

type config struct {
	//sample:  "user:password@/dbname?charset=utf8&parseTime=True&loc=Local"
	//see https://github.com/go-sql-driver/mysql#parameters
	DBParameters string `json:"dbParameters"`
	//ShowSQL      bool   `json:"showSql"` //是否显示sql
	Dialect string `json:"dialect"`
}

type Gorms struct {
	conf config
	db   *gorm.DB
}

func (c *Gorms) GetDb() *gorm.DB {
	return c.db
}

func (c *Gorms) Create(l dot.Line) (err error) {
	logger := dot.Logger()
	if len(c.conf.Dialect) < 1 {
		err = errors.New("not in (sqlite3 mysql postgres sql_server)")
		logger.Errorln("", zap.Error(err))
		return err
	}
	c.db, err = gorm.Open(mysql.Open(c.conf.DBParameters), &gorm.Config{
		//SkipDefaultTransaction: true, //
	})
	if err != nil {
		logger.Errorln("Gorms", zap.Error(err))
		c.db = nil
	} else {
		if l != nil {
			l.ToInjecter().ReplaceOrAddByType(c.db)
		}
	}
	return err
}

func newGorms(conf []byte) (d dot.Dot, err error) {
	dconf := &config{}
	err = dot.UnMarshalConfig(conf, dconf)
	if err != nil {
		return nil, err
	}

	d = &Gorms{conf: *dconf}
	return d, err
}

//GormsTypeLives return type lives
func GormsTypeLives() []*dot.TypeLives {
	lives := []*dot.TypeLives{
		{
			Meta: dot.Metadata{TypeID: GormTypeID, NewDoter: func(conf []byte) (dot dot.Dot, err error) {
				return newGorms(conf)
			}},
		},
	}
	return lives
}

//GormsConfigTypeLive return config
func GormsConfigTypeLive() *dot.ConfigTypeLive {
	return &dot.ConfigTypeLive{
		TypeIDConfig: GormTypeID,
		ConfigInfo:   &config{},
	}
}

//NewGormsTest just for test
func NewGormsTest(dbParameters string, showSQL bool, dialect string) *Gorms {
	conf := config{
		DBParameters: dbParameters,
		//ShowSQL:      showSQL,
		Dialect: dialect,
	}
	bs, _ := json.Marshal(conf)
	d, err := newGorms(bs)
	if err != nil {
		fmt.Println(err)
		return nil
	}
	db := d.(*Gorms)
	err = db.Create(nil)
	if err != nil {
		fmt.Println(err)
		return nil
	}
	return db
}


<|start_filename|>tools/dotconf/dotconf.go<|end_filename|>
// <NAME>.  All rights reserved.
// license that can be found in the license file.

package main

import (
	"fmt"
	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/gindot"
	"github.com/scryinfo/dot/dots/grpc/gserver"
	"github.com/scryinfo/dot/dots/line"
	"github.com/scryinfo/dot/tools/dotconf/data"
	"github.com/scryinfo/scryg/sutils/ssignal"
	"go.uber.org/zap"
	"os"
	"os/exec"
	"runtime"
)

func main() {

	{
		path := "./run_out"
		_, err := os.Stat(path)
		if err != nil {
			if os.IsNotExist(err) {
				err = os.Mkdir(path, os.ModePerm)
				if err != nil {
					dot.Logger().Errorln("", zap.Error(err))
					return
				}
			}
		}
	}

	l, err := line.BuildAndStart(add)
	if err != nil {
		dot.Logger().Errorln("", zap.Error(err))
		return
	}
	defer line.StopAndDestroy(l, true) //fourth step stop and destroy dots

	dot.Logger().Infoln("dot ok")
	//second step ....

	go func() {
		switch runtime.GOOS {
		case "windows":
			windowsBrowser()
		case "linux":
			linuxBrowser()
		default:
			dot.Logger().Fatalln("无法识别的操作系统")
		}
	}()

	ssignal.WaitCtrlC(func(s os.Signal) bool { //third wait for exit
		return false
	})
}

func add(l dot.Line) error {
	lives := data.RpcImplementTypeLives()
	lives = append(lives, gserver.GinNoblTypeLives()...)
	lives = append(lives, gindot.UiTypeLives()...)

	return l.PreAdd(lives...)
}
func linuxBrowser() {
	err := exec.Command("x-www-browser", "http://localhost:8080").Run()
	if err != nil {
		_, _ = fmt.Fprintf(os.Stderr, "please click ->   http://localhost:8080\n")
	}
}
func windowsBrowser() {
	err := exec.Command("cmd", "/C", "start", "http://localhost:8080").Run()
	if err != nil {
		_, _ = fmt.Fprintf(os.Stderr, "please click ->   http://localhost:8080\n")
	}
}


<|start_filename|>dots/line/build.go<|end_filename|>
// <NAME>.  All rights reserved.
// license that can be found in the license file.

package line

import (
	"encoding/json"
	"flag"
	"github.com/scryinfo/dot/dot"
	"go.uber.org/zap"
)

//BuildAndStart Construct line and call create rely create dots start
//add will be called before reply, after create
func BuildAndStart(add dot.BuildNewer) (l dot.Line, err error) {
	builder := &dot.Builder{Add: add, LineLiveID: "default"}
	l, err = BuildAndStartBy(builder)
	return l, err
}

//BuildAndStartBy Construct line and call create rely create dots start
func BuildAndStartBy(builder *dot.Builder) (l dot.Line, err error) {
	if !flag.Parsed() {
		flag.Parse()
	}
	err = nil

	if len(builder.LineLiveID) < 1 {
		builder.LineLiveID = "default"
	}

	line := newLine(builder)
	l = line
	if builder.BeforeCreate != nil {
		builder.BeforeCreate(line)
	}
	{
		err = line.Create(nil)

		if err != nil {
			return
		}

		if builder.Add != nil {
			err = builder.Add(line)
			if err != nil {
				return
			}
		}

		err = line.makeDotMetaFromConfig() // after the Add
		if err != nil {
			return
		}

		line.autoMakeLiveID() //issue #17

		line.makeRelays()

		dotOrder, circles := line.relyOrder() //do not care the error, it is circle dependency
		//circle dependency
		if len(circles) > 0 {
			bs, _ := json.Marshal(circles) //the %v just print the address of memory
			dot.Logger().Warnln("build", zap.String("", string(bs)))
		}

		err = line.CreateDots(dotOrder)
		if err != nil {
			return
		}
	}

	if builder.AfterCreate != nil {
		builder.AfterCreate(line)
	}

	dot.Logger().Infoln("dots Create")

	if builder.BeforeStart != nil {
		builder.BeforeStart(line)
	}
	err = line.Start(false)
	if builder.AfterStart != nil {
		builder.AfterStart(line)
	}

	if err != nil {
		return
	}

	dot.Logger().Infoln("dots Start")

	return l, err
}

//StopAndDestroy stop and destroy
func StopAndDestroy(l dot.Line, ignore bool) {
	builder := l.GetLineBuilder()

	if builder.BeforeStop != nil {
		builder.BeforeStop(l)
	}
	_ = l.ToLifer().Stop(ignore)
	if builder.AfterStop != nil {
		builder.AfterStop(l)
	}
	dot.Logger().Infoln("dots Stop")

	if builder.BeforeDestroy != nil {
		builder.BeforeDestroy(l)
	}

	_ = l.ToLifer().Destroy(ignore)
	if builder.AfterDestroy != nil {
		builder.AfterDestroy(l)
	}
	dot.Logger().Infoln("dots will Destroy")
	l.DestroyConfigLog()
}


<|start_filename|>dots/grpc/lb/balance.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package lb

import (
	"google.golang.org/grpc/balancer/roundrobin"
	"strings"

	"google.golang.org/grpc"
)

const (
	Round = "round"
	First = "first"
)

//If not found, then return Round Balance
func Balance(bname string) grpc.DialOption {
	var do grpc.DialOption = nil
	switch strings.ToLower(bname) {
	case Round:
		do = BalancerRound()
	case First:
		do = BalancerFirst()
	default:
		do = BalancerRound()
	}
	return do
}

func BalancerRound() grpc.DialOption { //todo grpc realization balance management use global variables, and do not consider multi thread condition, this is a temporary point
	return grpc.WithBalancerName(roundrobin.Name)
}

func BalancerFirst() grpc.DialOption { //todo grpc realization balance management use global variables, and do not consider multi thread condition, this is a temporary point
	return grpc.WithBalancerName(grpc.PickFirstBalancerName)
}


<|start_filename|>tools/dotconf/data/rpc/config.pb.go<|end_filename|>
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.25.0
// 	protoc        v3.12.3
// source: config.proto

package rpc

import (
	context "context"
	proto "github.com/golang/protobuf/proto"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4

//findDot
type FindReq struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Dirs []string `protobuf:"bytes,1,rep,name=dirs,proto3" json:"dirs,omitempty"` //目录集合
}

func (x *FindReq) Reset() {
	*x = FindReq{}
	if protoimpl.UnsafeEnabled {
		mi := &file_config_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *FindReq) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*FindReq) ProtoMessage() {}

func (x *FindReq) ProtoReflect() protoreflect.Message {
	mi := &file_config_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use FindReq.ProtoReflect.Descriptor instead.
func (*FindReq) Descriptor() ([]byte, []int) {
	return file_config_proto_rawDescGZIP(), []int{0}
}

func (x *FindReq) GetDirs() []string {
	if x != nil {
		return x.Dirs
	}
	return nil
}

type FindRes struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	DotsInfo    string   `protobuf:"bytes,1,opt,name=dotsInfo,proto3" json:"dotsInfo,omitempty"`       //组件信息（json）
	NoExistDirs []string `protobuf:"bytes,2,rep,name=noExistDirs,proto3" json:"noExistDirs,omitempty"` //不存在的目录集合
	Error       string   `protobuf:"bytes,3,opt,name=error,proto3" json:"error,omitempty"`             //错误信息
}

func (x *FindRes) Reset() {
	*x = FindRes{}
	if protoimpl.UnsafeEnabled {
		mi := &file_config_proto_msgTypes[1]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *FindRes) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*FindRes) ProtoMessage() {}

func (x *FindRes) ProtoReflect() protoreflect.Message {
	mi := &file_config_proto_msgTypes[1]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use FindRes.ProtoReflect.Descriptor instead.
func (*FindRes) Descriptor() ([]byte, []int) {
	return file_config_proto_rawDescGZIP(), []int{1}
}

func (x *FindRes) GetDotsInfo() string {
	if x != nil {
		return x.DotsInfo
	}
	return ""
}

func (x *FindRes) GetNoExistDirs() []string {
	if x != nil {
		return x.NoExistDirs
	}
	return nil
}

func (x *FindRes) GetError() string {
	if x != nil {
		return x.Error
	}
	return ""
}

//importfile
type ImportReq struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Filepath string `protobuf:"bytes,1,opt,name=filepath,proto3" json:"filepath,omitempty"` //导入文件的路径
}

func (x *ImportReq) Reset() {
	*x = ImportReq{}
	if protoimpl.UnsafeEnabled {
		mi := &file_config_proto_msgTypes[2]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *ImportReq) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*ImportReq) ProtoMessage() {}

func (x *ImportReq) ProtoReflect() protoreflect.Message {
	mi := &file_config_proto_msgTypes[2]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use ImportReq.ProtoReflect.Descriptor instead.
func (*ImportReq) Descriptor() ([]byte, []int) {
	return file_config_proto_rawDescGZIP(), []int{2}
}

func (x *ImportReq) GetFilepath() string {
	if x != nil {
		return x.Filepath
	}
	return ""
}

type ImportRes struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Json  string `protobuf:"bytes,1,opt,name=json,proto3" json:"json,omitempty"`   //返回导入文件的内容
	Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` //导入出错
}

func (x *ImportRes) Reset() {
	*x = ImportRes{}
	if protoimpl.UnsafeEnabled {
		mi := &file_config_proto_msgTypes[3]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *ImportRes) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*ImportRes) ProtoMessage() {}

func (x *ImportRes) ProtoReflect() protoreflect.Message {
	mi := &file_config_proto_msgTypes[3]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use ImportRes.ProtoReflect.Descriptor instead.
func (*ImportRes) Descriptor() ([]byte, []int) {
	return file_config_proto_rawDescGZIP(), []int{3}
}

func (x *ImportRes) GetJson() string {
	if x != nil {
		return x.Json
	}
	return ""
}

func (x *ImportRes) GetError() string {
	if x != nil {
		return x.Error
	}
	return ""
}

//exportfile
type ExportReq struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Configdata string   `protobuf:"bytes,1,opt,name=configdata,proto3" json:"configdata,omitempty"` //配置数据信息
	Filename   []string `protobuf:"bytes,2,rep,name=filename,proto3" json:"filename,omitempty"`     //导出的文件名
	Dotdata    string   `protobuf:"bytes,3,opt,name=dotdata,proto3" json:"dotdata,omitempty"`       //组件数据信息
}

func (x *ExportReq) Reset() {
	*x = ExportReq{}
	if protoimpl.UnsafeEnabled {
		mi := &file_config_proto_msgTypes[4]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *ExportReq) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*ExportReq) ProtoMessage() {}

func (x *ExportReq) ProtoReflect() protoreflect.Message {
	mi := &file_config_proto_msgTypes[4]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use ExportReq.ProtoReflect.Descriptor instead.
func (*ExportReq) Descriptor() ([]byte, []int) {
	return file_config_proto_rawDescGZIP(), []int{4}
}

func (x *ExportReq) GetConfigdata() string {
	if x != nil {
		return x.Configdata
	}
	return ""
}

func (x *ExportReq) GetFilename() []string {
	if x != nil {
		return x.Filename
	}
	return nil
}

func (x *ExportReq) GetDotdata() string {
	if x != nil {
		return x.Dotdata
	}
	return ""
}

type ExportRes struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` //导出是否成功
}

func (x *ExportRes) Reset() {
	*x = ExportRes{}
	if protoimpl.UnsafeEnabled {
		mi := &file_config_proto_msgTypes[5]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *ExportRes) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*ExportRes) ProtoMessage() {}

func (x *ExportRes) ProtoReflect() protoreflect.Message {
	mi := &file_config_proto_msgTypes[5]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use ExportRes.ProtoReflect.Descriptor instead.
func (*ExportRes) Descriptor() ([]byte, []int) {
	return file_config_proto_rawDescGZIP(), []int{5}
}

func (x *ExportRes) GetError() string {
	if x != nil {
		return x.Error
	}
	return ""
}

var File_config_proto protoreflect.FileDescriptor

var file_config_proto_rawDesc = []byte{
	0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03,
	0x72, 0x70, 0x63, 0x22, 0x1d, 0x0a, 0x07, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x12, 0x12,
	0x0a, 0x04, 0x64, 0x69, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x64, 0x69,
	0x72, 0x73, 0x22, 0x5d, 0x0a, 0x07, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x12, 0x1a, 0x0a,
	0x08, 0x64, 0x6f, 0x74, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
	0x08, 0x64, 0x6f, 0x74, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x6f, 0x45,
	0x78, 0x69, 0x73, 0x74, 0x44, 0x69, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b,
	0x6e, 0x6f, 0x45, 0x78, 0x69, 0x73, 0x74, 0x44, 0x69, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65,
	0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f,
	0x72, 0x22, 0x27, 0x0a, 0x09, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x12, 0x1a,
	0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
	0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x22, 0x35, 0x0a, 0x09, 0x49, 0x6d,
	0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x18,
	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x65,
	0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f,
	0x72, 0x22, 0x61, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x12, 0x1e,
	0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01,
	0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a,
	0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09,
	0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x6f,
	0x74, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6f, 0x74,
	0x64, 0x61, 0x74, 0x61, 0x22, 0x21, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65,
	0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
	0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x32, 0xa2, 0x02, 0x0a, 0x0d, 0x44, 0x6f, 0x74, 0x43,
	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x61, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x07, 0x46, 0x69, 0x6e,
	0x64, 0x44, 0x6f, 0x74, 0x12, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52,
	0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73,
	0x12, 0x30, 0x0a, 0x0e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x66,
	0x69, 0x67, 0x12, 0x0e, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52,
	0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52,
	0x65, 0x73, 0x12, 0x2d, 0x0a, 0x0b, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x79, 0x44, 0x6f,
	0x74, 0x12, 0x0e, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65,
	0x71, 0x1a, 0x0e, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65,
	0x73, 0x12, 0x2c, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12,
	0x0e, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x1a,
	0x0e, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x12,
	0x2e, 0x0a, 0x0c, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
	0x0e, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x1a,
	0x0e, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x12,
	0x2b, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x6f, 0x74, 0x12, 0x0e, 0x2e, 0x72,
	0x70, 0x63, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x0e, 0x2e, 0x72,
	0x70, 0x63, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x42, 0x02, 0x48, 0x03,
	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_config_proto_rawDescOnce sync.Once
	file_config_proto_rawDescData = file_config_proto_rawDesc
)

func file_config_proto_rawDescGZIP() []byte {
	file_config_proto_rawDescOnce.Do(func() {
		file_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_config_proto_rawDescData)
	})
	return file_config_proto_rawDescData
}

var file_config_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_config_proto_goTypes = []interface{}{
	(*FindReq)(nil),   // 0: rpc.FindReq
	(*FindRes)(nil),   // 1: rpc.FindRes
	(*ImportReq)(nil), // 2: rpc.ImportReq
	(*ImportRes)(nil), // 3: rpc.ImportRes
	(*ExportReq)(nil), // 4: rpc.ExportReq
	(*ExportRes)(nil), // 5: rpc.ExportRes
}
var file_config_proto_depIdxs = []int32{
	0, // 0: rpc.DotConfigFace.FindDot:input_type -> rpc.FindReq
	2, // 1: rpc.DotConfigFace.ImportByConfig:input_type -> rpc.ImportReq
	2, // 2: rpc.DotConfigFace.ImportByDot:input_type -> rpc.ImportReq
	2, // 3: rpc.DotConfigFace.InitImport:input_type -> rpc.ImportReq
	4, // 4: rpc.DotConfigFace.ExportConfig:input_type -> rpc.ExportReq
	4, // 5: rpc.DotConfigFace.ExportDot:input_type -> rpc.ExportReq
	1, // 6: rpc.DotConfigFace.FindDot:output_type -> rpc.FindRes
	3, // 7: rpc.DotConfigFace.ImportByConfig:output_type -> rpc.ImportRes
	3, // 8: rpc.DotConfigFace.ImportByDot:output_type -> rpc.ImportRes
	3, // 9: rpc.DotConfigFace.InitImport:output_type -> rpc.ImportRes
	5, // 10: rpc.DotConfigFace.ExportConfig:output_type -> rpc.ExportRes
	5, // 11: rpc.DotConfigFace.ExportDot:output_type -> rpc.ExportRes
	6, // [6:12] is the sub-list for method output_type
	0, // [0:6] is the sub-list for method input_type
	0, // [0:0] is the sub-list for extension type_name
	0, // [0:0] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() { file_config_proto_init() }
func file_config_proto_init() {
	if File_config_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*FindReq); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*FindRes); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ImportReq); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ImportRes); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_config_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ExportReq); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_config_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ExportRes); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_config_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   6,
			NumExtensions: 0,
			NumServices:   1,
		},
		GoTypes:           file_config_proto_goTypes,
		DependencyIndexes: file_config_proto_depIdxs,
		MessageInfos:      file_config_proto_msgTypes,
	}.Build()
	File_config_proto = out.File
	file_config_proto_rawDesc = nil
	file_config_proto_goTypes = nil
	file_config_proto_depIdxs = nil
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6

// DotConfigFaceClient is the client API for DotConfigFace service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type DotConfigFaceClient interface {
	FindDot(ctx context.Context, in *FindReq, opts ...grpc.CallOption) (*FindRes, error)
	//文件导入
	ImportByConfig(ctx context.Context, in *ImportReq, opts ...grpc.CallOption) (*ImportRes, error)
	ImportByDot(ctx context.Context, in *ImportReq, opts ...grpc.CallOption) (*ImportRes, error)
	InitImport(ctx context.Context, in *ImportReq, opts ...grpc.CallOption) (*ImportRes, error)
	//导出文件
	ExportConfig(ctx context.Context, in *ExportReq, opts ...grpc.CallOption) (*ExportRes, error)
	ExportDot(ctx context.Context, in *ExportReq, opts ...grpc.CallOption) (*ExportRes, error)
}

type dotConfigFaceClient struct {
	cc grpc.ClientConnInterface
}

func NewDotConfigFaceClient(cc grpc.ClientConnInterface) DotConfigFaceClient {
	return &dotConfigFaceClient{cc}
}

func (c *dotConfigFaceClient) FindDot(ctx context.Context, in *FindReq, opts ...grpc.CallOption) (*FindRes, error) {
	out := new(FindRes)
	err := c.cc.Invoke(ctx, "/rpc.DotConfigFace/FindDot", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *dotConfigFaceClient) ImportByConfig(ctx context.Context, in *ImportReq, opts ...grpc.CallOption) (*ImportRes, error) {
	out := new(ImportRes)
	err := c.cc.Invoke(ctx, "/rpc.DotConfigFace/ImportByConfig", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *dotConfigFaceClient) ImportByDot(ctx context.Context, in *ImportReq, opts ...grpc.CallOption) (*ImportRes, error) {
	out := new(ImportRes)
	err := c.cc.Invoke(ctx, "/rpc.DotConfigFace/ImportByDot", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *dotConfigFaceClient) InitImport(ctx context.Context, in *ImportReq, opts ...grpc.CallOption) (*ImportRes, error) {
	out := new(ImportRes)
	err := c.cc.Invoke(ctx, "/rpc.DotConfigFace/InitImport", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *dotConfigFaceClient) ExportConfig(ctx context.Context, in *ExportReq, opts ...grpc.CallOption) (*ExportRes, error) {
	out := new(ExportRes)
	err := c.cc.Invoke(ctx, "/rpc.DotConfigFace/ExportConfig", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *dotConfigFaceClient) ExportDot(ctx context.Context, in *ExportReq, opts ...grpc.CallOption) (*ExportRes, error) {
	out := new(ExportRes)
	err := c.cc.Invoke(ctx, "/rpc.DotConfigFace/ExportDot", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// DotConfigFaceServer is the server API for DotConfigFace service.
type DotConfigFaceServer interface {
	FindDot(context.Context, *FindReq) (*FindRes, error)
	//文件导入
	ImportByConfig(context.Context, *ImportReq) (*ImportRes, error)
	ImportByDot(context.Context, *ImportReq) (*ImportRes, error)
	InitImport(context.Context, *ImportReq) (*ImportRes, error)
	//导出文件
	ExportConfig(context.Context, *ExportReq) (*ExportRes, error)
	ExportDot(context.Context, *ExportReq) (*ExportRes, error)
}

// UnimplementedDotConfigFaceServer can be embedded to have forward compatible implementations.
type UnimplementedDotConfigFaceServer struct {
}

func (*UnimplementedDotConfigFaceServer) FindDot(context.Context, *FindReq) (*FindRes, error) {
	return nil, status.Errorf(codes.Unimplemented, "method FindDot not implemented")
}
func (*UnimplementedDotConfigFaceServer) ImportByConfig(context.Context, *ImportReq) (*ImportRes, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ImportByConfig not implemented")
}
func (*UnimplementedDotConfigFaceServer) ImportByDot(context.Context, *ImportReq) (*ImportRes, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ImportByDot not implemented")
}
func (*UnimplementedDotConfigFaceServer) InitImport(context.Context, *ImportReq) (*ImportRes, error) {
	return nil, status.Errorf(codes.Unimplemented, "method InitImport not implemented")
}
func (*UnimplementedDotConfigFaceServer) ExportConfig(context.Context, *ExportReq) (*ExportRes, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ExportConfig not implemented")
}
func (*UnimplementedDotConfigFaceServer) ExportDot(context.Context, *ExportReq) (*ExportRes, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ExportDot not implemented")
}

func RegisterDotConfigFaceServer(s *grpc.Server, srv DotConfigFaceServer) {
	s.RegisterService(&_DotConfigFace_serviceDesc, srv)
}

func _DotConfigFace_FindDot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(FindReq)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(DotConfigFaceServer).FindDot(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/rpc.DotConfigFace/FindDot",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(DotConfigFaceServer).FindDot(ctx, req.(*FindReq))
	}
	return interceptor(ctx, in, info, handler)
}

func _DotConfigFace_ImportByConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ImportReq)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(DotConfigFaceServer).ImportByConfig(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/rpc.DotConfigFace/ImportByConfig",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(DotConfigFaceServer).ImportByConfig(ctx, req.(*ImportReq))
	}
	return interceptor(ctx, in, info, handler)
}

func _DotConfigFace_ImportByDot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ImportReq)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(DotConfigFaceServer).ImportByDot(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/rpc.DotConfigFace/ImportByDot",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(DotConfigFaceServer).ImportByDot(ctx, req.(*ImportReq))
	}
	return interceptor(ctx, in, info, handler)
}

func _DotConfigFace_InitImport_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ImportReq)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(DotConfigFaceServer).InitImport(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/rpc.DotConfigFace/InitImport",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(DotConfigFaceServer).InitImport(ctx, req.(*ImportReq))
	}
	return interceptor(ctx, in, info, handler)
}

func _DotConfigFace_ExportConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ExportReq)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(DotConfigFaceServer).ExportConfig(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/rpc.DotConfigFace/ExportConfig",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(DotConfigFaceServer).ExportConfig(ctx, req.(*ExportReq))
	}
	return interceptor(ctx, in, info, handler)
}

func _DotConfigFace_ExportDot_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ExportReq)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(DotConfigFaceServer).ExportDot(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/rpc.DotConfigFace/ExportDot",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(DotConfigFaceServer).ExportDot(ctx, req.(*ExportReq))
	}
	return interceptor(ctx, in, info, handler)
}

var _DotConfigFace_serviceDesc = grpc.ServiceDesc{
	ServiceName: "rpc.DotConfigFace",
	HandlerType: (*DotConfigFaceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "FindDot",
			Handler:    _DotConfigFace_FindDot_Handler,
		},
		{
			MethodName: "ImportByConfig",
			Handler:    _DotConfigFace_ImportByConfig_Handler,
		},
		{
			MethodName: "ImportByDot",
			Handler:    _DotConfigFace_ImportByDot_Handler,
		},
		{
			MethodName: "InitImport",
			Handler:    _DotConfigFace_InitImport_Handler,
		},
		{
			MethodName: "ExportConfig",
			Handler:    _DotConfigFace_ExportConfig_Handler,
		},
		{
			MethodName: "ExportDot",
			Handler:    _DotConfigFace_ExportDot_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "config.proto",
}


<|start_filename|>tools/ende/decode.go<|end_filename|>
package ende

import (
	"crypto"
	"crypto/ed25519"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"syscall"

	"go.uber.org/zap"

	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/lib/scrypto"
	_ "github.com/scryinfo/dot/lib/scrypto/ende25519"
	_ "github.com/scryinfo/dot/lib/scrypto/sx25519"
	"github.com/scryinfo/dot/utils"
	"github.com/scryinfo/scryg/sutils/sfile"
)

const DecodeTypeID = "7e592fd2-6cd8-4953-8fae-8c3a9915bef7"

type configDecode struct {
	Help     bool   `json:"help"` //输出帮助信息
	Generate string `json:"generate"`
	File     string `json:"file"`
	OutFile  string `json:"outFile"`

	//EndeType string `json:"endeType"` //加密的实现，现支持X25519
	Ed25519PublicKey    string `json:"ed25519PublicKey"`    //用于签名的公钥, hex
	X25519PrivateKeyKey string `json:"x25519PrivateKeyKey"` //解密用的x25519的私钥， hex
}
type Decode struct {
	conf configDecode
}

//func (c *Decode) Create(l dot.Line) error {
//
//}
//func (c *Decode) Injected(l dot.Line) error {
//
//}
//func (c *Decode) AfterAllInject(l dot.Line) {
//
//}

func (c *Decode) Start(ignore bool) error {
	c.parseEnParameter()
	SendSignal(syscall.SIGKILL)
	//os.Exit(0)
	return nil
}

//func (c *Decode) Stop(ignore bool) error {
//
//}
//
//func (c *Decode) Destroy(ignore bool) error {
//
//}

//construct dot
func newDecode(conf []byte) (dot.Dot, error) {
	dconf := &configDecode{}

	err := dot.UnMarshalConfig(conf, dconf)
	if err != nil {
		return nil, err
	}

	d := &Decode{conf: *dconf}

	return d, nil
}

//DecodeTypeLives
func DecodeTypeLives() []*dot.TypeLives {
	tl := &dot.TypeLives{
		Meta: dot.Metadata{TypeID: DecodeTypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
			return newDecode(conf)
		}},
		//Lives: []dot.Live{
		//	{
		//		LiveID:    DecodeTypeID,
		//		RelyLives: map[string]dot.LiveID{"some field": "some id"},
		//	},
		//},
	}

	lives := []*dot.TypeLives{tl}

	return lives
}

//DecodeConfigTypeLive
func DecodeConfigTypeLive() *dot.ConfigTypeLive {
	paths := make([]string, 0)
	paths = append(paths, "")
	return &dot.ConfigTypeLive{
		TypeIDConfig: DecodeTypeID,
		ConfigInfo: &configDecode{
			//todo
		},
	}
}

//返回值为true 接着运行
func (c *Decode) parseEnParameter() bool {
	logger := dot.Logger()
	if c.conf.Help {
		//todo
		return false
	}

	if len(c.conf.Generate) > 0 {
		GenerateKey(c.conf.Generate)
		return false
	}

	if len(c.conf.File) < 1 {
		logger.Errorln("请入要解密的文件")
		return false
	}

	fullPath := utils.GetFullPathFile(c.conf.File)
	if len(fullPath) < 1 || !sfile.ExistFile(fullPath) {
		logger.Errorln(fmt.Sprintf("不能找到文件： %s\n", c.conf.File))
		return false
	}

	if len(c.conf.OutFile) < 1 {
		c.conf.OutFile = fullPath + "_de"
	}

	data := scrypto.EndeData{}
	{
		bytes, err := ioutil.ReadFile(fullPath)
		if err != nil {
			logger.Errorln("", zap.Error(err))
			return false
		}
		err = json.Unmarshal(bytes, &data)
		if err != nil {
			logger.Errorln("", zap.Error(err))
			return false
		}
	}
	{ //decode
		var privateKey crypto.PrivateKey
		{
			bytes, err := hex.DecodeString(c.conf.X25519PrivateKeyKey)
			if err != nil {
				logger.Errorln("", zap.Error(err))
				return false
			}
			privateKey = bytes
		}
		var signedPublicKey ed25519.PublicKey
		{
			bytes, err := hex.DecodeString(c.conf.Ed25519PublicKey)
			if err != nil {
				logger.Errorln("", zap.Error(err))
				return false
			}
			signedPublicKey = bytes
		}
		var err error
		data, err = scrypto.DecodeData(&data, privateKey, signedPublicKey)
		if err != nil {
			logger.Errorln("", zap.Error(err))
			return false
		}
	}

	err := ioutil.WriteFile(c.conf.OutFile, data.Body, 0644)
	if err != nil {
		logger.Errorln("", zap.Error(err))
		return false
	}

	fmt.Printf("decode successful, file: %s\n", c.conf.OutFile)

	return true
}


<|start_filename|>dots/gindot/kits.go<|end_filename|>
// S<NAME>.  All rights reserved.
// license that can be found in the license file.

package gindot

import (
	"reflect"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/scryinfo/dot/dot"
)

//for each funcs that like “gin.HandlerFunc”
//sampe pre = "scry", and  "func (c * SampleCtroller) Hello(cxt *gin.Context) {}", the url is "/scry/hello"
func RouterSelf(h interface{}, pre string, call func(url string, gmethod reflect.Value)) {
	hf := reflect.TypeOf(gin.HandlerFunc(nil))
	vr := reflect.ValueOf(h)
	tr := reflect.TypeOf(h)
	pre = strings.TrimSpace(pre)
	if pre == "" || pre == "/" {
		pre = "/"
	} else {
		if pre[0] != '/' {
			pre = "/" + pre
		}
		if pre[len(pre)-1] != '/' {
			pre = pre + "/"
		}
	}
	for i := 0; i < vr.NumMethod(); i++ {
		vm := vr.Method(i)
		if vm.Type().AssignableTo(hf) {
			lname := strings.ToLower(tr.Method(i).Name)
			if lname == "index" {
				lname = ""
			}
			p := pre + lname
			call(p, vm)
		}
	}
}

//all post
func RouterPost(g *gin.RouterGroup, h interface{}, pre string) {
	post := reflect.ValueOf(g).MethodByName("POST")
	RouterSelf(h, pre, func(url string, gmethod reflect.Value) {
		vs := []reflect.Value{reflect.ValueOf(url), gmethod}
		post.Call(vs)
	})
}

//all get
func RouterGet(g *gin.RouterGroup, h interface{}, pre string) {
	get := reflect.ValueOf(g).MethodByName("GET")
	RouterSelf(h, pre, func(url string, gmethod reflect.Value) {
		vs := []reflect.Value{reflect.ValueOf(url), gmethod}
		get.Call(vs)
	})
}

//GinDotTypeLives generate data for structural  dot
//routerID: is the liveid of  gindot/router component
func PreAddControlDot(ctype reflect.Type, routerID dot.LiveID) *dot.TypeLives {
	tl := &dot.TypeLives{
		Meta: dot.Metadata{TypeID: dot.TypeID(ctype.Name()), RefType: ctype, NewDoter: nil},
		Lives: []dot.Live{dot.Live{
			LiveID:    dot.LiveID(ctype.Name()),
			RelyLives: map[string]dot.LiveID{"GinRouter_": routerID},
		}},
	}
	return tl
}


<|start_filename|>sample/db/tools/dao/gorms/auto_data_dao.go<|end_filename|>
package gorms

import (
	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/db/gorms"
	"github.com/scryinfo/dot/dots/db/pgs"
	"github.com/scryinfo/dot/sample/db/tools/model"
	"gorm.io/gorm/clause"
)

const AutoDataDaoTypeID = "b7ea29d4-64d9-4ac1-a288-ecfcfbaa9fc6"

type AutoDataDao struct {
	*gorms.DaoBase `dot:""`
}

//AutoDataDaoTypeLives
func AutoDataDaoTypeLives() []*dot.TypeLives {
	tl := &dot.TypeLives{
		Meta: dot.Metadata{TypeID: AutoDataDaoTypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
			return &AutoDataDao{}, nil
		}},
		Lives: []dot.Live{
			{
				LiveID: AutoDataDaoTypeID,
				RelyLives: map[string]dot.LiveID{
					"DaoBase": pgs.DaoBaseTypeID,
				},
			},
		},
	}

	lives := gorms.DaoBaseTypeLives()
	lives = append(lives, tl)

	return lives
}

func (c *AutoDataDao) GetByID(id uint) (m *model.AutoData, err error) {
	result := c.Wrapper.GetDb().First(&m, id)
	if result.RowsAffected == 1 {
		return m, nil
	}
	return nil, result.Error
}

func (c *AutoDataDao) Query(condition string, params ...interface{}) (ms []*model.AutoData, err error) {

	db := c.Wrapper.GetDb()
	if len(condition) < 1 {
		db = db.Find(&ms)
	} else {
		db = db.Where(condition, params...).Find(&ms)
	}
	err = db.Error
	if err != nil {
		ms = nil
	}
	return
}

func (c *AutoDataDao) List() (ms []*model.AutoData, err error) {
	db := c.Wrapper.GetDb().Find(&ms)
	if db.Error != nil {
		ms = nil
	}
	return ms, db.Error
}

func (c *AutoDataDao) Count(condition string, params ...interface{}) (count int64, err error) {

	var ms []*model.AutoData
	db := c.Wrapper.GetDb()
	if len(condition) < 1 {
		db = db.Find(&ms)
	} else {
		db = db.Where(condition, params...).Find(&ms)
	}
	err = db.Error
	if err != nil {
		count = 0
	}
	count = db.RowsAffected
	return
}

func (c *AutoDataDao) QueryPage(pageSize int, page int, condition string, params ...interface{}) (ms []*model.AutoData, err error) {
	db := c.Wrapper.GetDb()
	if len(condition) < 1 {
		db = db.Limit(pageSize).Offset((page - 1) * pageSize).Find(&ms)
	} else {
		db = db.Limit(pageSize).Offset((page-1)*pageSize).Where(condition, params...).Find(&ms)
	}
	if db.Error != nil { //be sure
		ms = nil
	}
	return ms, db.Error
}

func (c *AutoDataDao) QueryPageWithCount(pageSize int, page int, condition string, params ...interface{}) (ms []*model.AutoData, count int64, err error) {
	db := c.Wrapper.GetDb()
	if len(condition) < 1 {
		db = db.Limit(pageSize).Offset((page - 1) * pageSize).Find(&ms)
	} else {
		db = db.Limit(pageSize).Offset((page-1)*pageSize).Where(condition, params...).Find(&ms)
	}
	if db.Error != nil { //be sure
		ms = nil
	}
	return ms, db.RowsAffected, db.Error
}

func (c *AutoDataDao) QueryOne(condition string, params ...interface{}) (m *model.AutoData, err error) {
	db := c.Wrapper.GetDb()
	if len(condition) < 1 {
		db = db.First(&m)
	} else {
		db = db.Where(condition, params...).First(&m)
	}
	err = db.Error
	if err != nil {
		m = nil
	}
	return
}

//insert = insertReturn
func (c *AutoDataDao) Insert(m *model.AutoData) (err error) {
	//because id auto increment
	//m.ID = 0
	err = c.Wrapper.GetDb().Create(&m).Error
	return
}

func (c *AutoDataDao) Inserts(ms []*model.AutoData) (err error) {
	//because id auto increment
	//m.ID = 0
	err = c.Wrapper.GetDb().Create(&ms).Error
	return
}

//update everything except ID
func (c *AutoDataDao) Upsert(m *model.AutoData) (err error) {
	//because id auto increment
	//m.ID = 0
	err = c.Wrapper.GetDb().Clauses(clause.OnConflict{
		UpdateAll: true,
	}).Create(&m).Error
	return
}

func (c *AutoDataDao) Upserts(ms []*model.AutoData) (err error) {
	//because id auto increment
	//m.ID = 0
	err = c.Wrapper.GetDb().Clauses(clause.OnConflict{
		UpdateAll: true,
	}).Create(&ms).Error
	return
}

//Updates 方法支持 struct 和 map[string]interface{} 参数
//当使用 struct 更新时，默认情况下，GORM 只会更新非零值的字段
func (c *AutoDataDao) Update(m *model.AutoData) (err error) {
	err = c.Wrapper.GetDb().Updates(&m).Error
	return
}

//Save 会保存所有的字段，即使字段是零值
//todo CreateTime=0
func (c *AutoDataDao) Save(m *model.AutoData) (err error) {
	err = c.Wrapper.GetDb().Save(&m).Error
	return
}

//default where id=m.ID
func (c *AutoDataDao) UpdateColumn(m *model.AutoData, columnName string, value interface{}) (err error) {
	err = c.Wrapper.GetDb().Model(&m).Update(columnName, value).Error
	return
}

//soft delete
func (c *AutoDataDao) DeleteById(id uint) error {
	return c.Wrapper.GetDb().Delete(&model.AutoData{}, id).Error
}

//soft delete
func (c *AutoDataDao) DeleteByIds(ids []uint) error {
	return c.Wrapper.GetDb().Delete(&model.AutoData{}, ids).Error
}

//soft delete
func (c *AutoDataDao) Delete(condition string, params ...interface{}) error {
	return c.Wrapper.GetDb().Where(condition, params...).Delete(&model.AutoData{}).Error
}

//Delete permanently
func (c *AutoDataDao) DeleteByIdUnscoped(id uint) error {
	return c.Wrapper.GetDb().Unscoped().Delete(&model.AutoData{}, id).Error
}


<|start_filename|>dots/jsonrpc2/client.go<|end_filename|>
package jsonrpc2

import (
	"context"
	"encoding/json"
	"github.com/go-kit/kit/transport/http/jsonrpc"
	"net/url"
)

func CallOne(urlStr string, out interface{}, method string, params ...interface{}) error {
	u, err := url.Parse(urlStr)
	if err != nil {
		return err
	}
	client := jsonrpc.NewClient(u, method, jsonrpc.ClientResponseDecoder(func(_ context.Context, res jsonrpc.Response) (interface{}, error) {
		if res.Error != nil {
			return nil, *res.Error
		}
		err := json.Unmarshal(res.Result, out)
		if err != nil {
			return nil, err
		}
		return out, nil
	}))
	_, err = client.Endpoint()(context.Background(), params)
	if err != nil {
		return err
	}
	return nil
}


<|start_filename|>lib/scrypto/ende25519/ende25519.go<|end_filename|>
package ende25519

import (
	"crypto"
	"crypto/sha256"
	"github.com/pkg/errors"
	"github.com/scryinfo/dot/lib/scrypto"
	"github.com/scryinfo/dot/lib/scrypto/sx25519"
	"golang.org/x/crypto/chacha20poly1305"
	"golang.org/x/crypto/hkdf"
	"io"
)

type ende25519 struct{}

func EcdhDecoder25519() scrypto.AsymmetricDecoder {
	return &ende25519{}
}

func EcdhEncoder25519() scrypto.AsymmetricEncoder {
	return &ende25519{}
}

var (
	salt     []byte
	hash     = sha256.New
	info     = []byte("scry info")
	nonce    = make([]byte, chacha20poly1305.NonceSize)
	ecdh     = sx25519.X25519()
	endeType = scrypto.EndeType_X25519
)

func init() {
	scrypto.Encoders[scrypto.EndeType_X25519] = EcdhEncoder25519()
	scrypto.Decoders[scrypto.EndeType_X25519] = EcdhDecoder25519()
}

func (c *ende25519) EcdhDecode(privateKey crypto.PrivateKey, _cipher *scrypto.EndeData) (plain scrypto.EndeData, err error) {
	plain = *_cipher
	if !plain.EnData {
		return
	}
	if plain.EndeType != endeType {
		err = errors.New("the ende type is not " + string(endeType))
		return
	}

	var peersKey crypto.PublicKey = plain.PublicKey

	plain.Body, err = c._ecdhDecode(privateKey, peersKey, plain.Body)
	if err != nil {
		return
	}
	plain.EnData = false //decode data

	return
}

func (c *ende25519) EcdhEncode(privateKey crypto.PrivateKey, peersKey crypto.PublicKey, _plain *scrypto.EndeData) (cipher scrypto.EndeData, err error) {
	cipher = *_plain
	if cipher.EnData {
		return cipher, nil
	}
	cipher.EndeType = endeType
	publicKey, err := ecdh.PublicKey(privateKey)
	if err != nil {
		return
	}
	cipher.PublicKey, err = ecdh.PublicKeyToBytes(publicKey)
	if err != nil {
		return
	}

	cipher.Body, err = c._ecdhEncode(privateKey, peersKey, cipher.Body)
	if err != nil {
		return
	}
	cipher.EnData = true
	return
}

// EcdhDecode
// privateKey sx25519, peersKey sx25519
//
func (c *ende25519) _ecdhDecode(privateKey crypto.PrivateKey, peersKey crypto.PublicKey, ciphertext []byte) (plaintext []byte, err error) {

	key, err := ecdh.ComputeSecret(privateKey, peersKey)
	if err != nil {
		return
	}
	dk := hkdf.New(hash, key, salt, info)
	wrappingKey := make([]byte, chacha20poly1305.KeySize)
	if _, err = io.ReadFull(dk, wrappingKey); err != nil {
		return
	}
	aead, err := chacha20poly1305.New(key)
	if err != nil {
		return
	}
	plaintext, err = aead.Open(nil, nonce, ciphertext, nil)
	return
}

// EcdhEncode
// privateKey sx25519, peersKey sx25519
func (c *ende25519) _ecdhEncode(privateKey crypto.PrivateKey, peersKey crypto.PublicKey, plaintext []byte) (ciphertext []byte, err error) {
	echg := sx25519.X25519()
	key, err := echg.ComputeSecret(privateKey, peersKey)
	if err != nil {
		return
	}

	dk := hkdf.New(hash, key, salt, info)

	wrappingKey := make([]byte, chacha20poly1305.KeySize)
	if _, err = io.ReadFull(dk, wrappingKey); err != nil {
		return
	}

	aead, err := chacha20poly1305.New(key)
	if err != nil {
		return
	}
	ciphertext = aead.Seal(nil, nonce, plaintext, nil)
	return
}


<|start_filename|>tools/dotconf/ui/src/views/components/utils/schemaGenerator/ast.js<|end_filename|>
'use strict';

/**
 Generates an Abstract Syntax Tree
 used for generating the schema.

 @see: https://en.wikipedia.org/wiki/Abstract_syntax_tree
 */
import {getType, isArray, isBoolean, isNumber, isObject, isString} from './type';

/**
 Abstract Syntax Tree Class

 @class AST
 @return {Object}
 */
var AST = function () {
    if (!this instanceof AST) {
        return new AST();
    }

    this.tree = {};
};
/**
 Inspect primitatives and apply the correct type
 and mark as required if the element contains a value.

 @method buildPrimitive
 @param {Object} tree Schema which represents the node
 @param {Node} node The JSON node being inspected
 @return void
 */
AST.prototype.buildPrimitive = function (tree, node) {
    tree.type = getType(node);
    if (tree.type === 'string') {
        tree.minLength = (node.length > 0) ? 1 : 0;
    }

    if (node !== null && typeof node !== 'undefined') {
        tree.required = true;
    }
}

/**
 Inspect object properties and apply the correct
 type and mark as required if the element has set
 properties.

 @method buildObject
 @param {Object} tree Schema which represents the node
 @param {Node} node The JSON node being inspected
 */
AST.prototype.buildObjectTree = function (tree, node) {
    tree.type = tree.type || 'object';
    tree.children = tree.children || {};
    for (var i in node) {
        if (isObject(node[i])) {
            tree.children[i] = {};
            this.buildObjectTree(tree.children[i], node[i]);
            continue;
        } else if (isArray(node[i])) {
            tree.children[i] = {};
            this.buildArrayTree(tree.children[i], node[i]);
        } else {
            tree.children[i] = {};
            this.buildPrimitive(tree.children[i], node[i]);
        }
    }
};

/**
 Inspect array elements apply the correct
 type and mark as required if the element has
 set properties.

 @method buildObject
 @param {Object} tree Schema which represents the node
 @param {Node} node The JSON node being inspected
 */
AST.prototype.buildArrayTree = function (tree, node) {
    tree.type = 'array';
    tree.children = {};
    for (var i = 0; i < node.length; i++) {
        if (isObject(node[i])) {
            tree.children[i] = {};
            tree.children[i].type = 'object';
            var keys = Object.keys(node[i]);
            if (keys.length > 0) {
                tree.children[i].required = true;
            }
            this.buildObjectTree(tree.children[i], node[i]);
        } else if (isArray(node[i])) {
            tree.children[i] = {};
            tree.children[i].type = 'array';
            tree.children[i].uniqueItems = false;
            if (node[i].length > 0) {
                tree.children[i].required = true;
            }
            this.buildArrayTree(tree.children[i], node[i]);
        } else if (isNumber(node[i])) {
            tree.children[i] = {};
            tree.children[i].type = 'number';
        } else if (isString(node[i])) {
            tree.children[i] = {};
            tree.children[i].type = 'string';
        } else if (isBoolean(node[i])) {
            tree.children[i] = {};
            tree.children[i].type = 'boolean';
        } else if (tree.type === 'object') {
            tree.children[i] = {};
            this.buildPrimitive(tree.children[i], node[i]);
        }
    }
};

/**
 Initiates generating the AST from the
 given JSON document.

 @param {Object} json JSON object
 @return void
 */
AST.prototype.build = function (json) {
    if (json instanceof Array) {
        this.buildArrayTree(this.tree, json);
    } else {
        this.buildObjectTree(this.tree, json);
    }
};

export {AST};


<|start_filename|>sample/db/tools/model/hassub_model.go<|end_filename|>
package model

import (
	"fmt"
	"github.com/scryinfo/dot/dots/db/pgs"
)

const (
	HasSub_Table                 = "has_subs"
	HasSub_Struct                = "has_sub"
	HasSub_ID                    = "id"
	HasSub_UpdateTime            = "update_time"
	HasSub_CreateTime            = "create_time"
	HasSub_OptimisticLockVersion = "optimistic_lock_version"
	HasSub_SubId                 = "sub_id"
	HasSub_Count                 = "count"
	HasSub_SubData               = "sub_data"
)

func (m *HasSub) String() string {
	//todo please change the format string
	//m.ID, m.UpdateTime, m.CreateTime, m.OptimisticLockVersion, m.SubId, m.Count, m.SubData,
	str := fmt.Sprintf("HasSub<%s %s >",
		m.ID, m.SubId,
	)
	return str
}

func (m *HasSub) ToMap() map[string]string {
	res := pgs.ToMap(m, map[string]bool{})
	return res
}

func (m *HasSub) ToUpsertSet() []string {
	res := []string{
		fmt.Sprintf("%s = EXCLUDED.%s", HasSub_ID, HasSub_ID),
		fmt.Sprintf("%s = EXCLUDED.%s", HasSub_UpdateTime, HasSub_UpdateTime),
		fmt.Sprintf("%s = EXCLUDED.%s", HasSub_CreateTime, HasSub_CreateTime),
		fmt.Sprintf("%s = EXCLUDED.%s", HasSub_OptimisticLockVersion, HasSub_OptimisticLockVersion),
		fmt.Sprintf("%s = EXCLUDED.%s", HasSub_SubId, HasSub_SubId),
		fmt.Sprintf("%s = EXCLUDED.%s", HasSub_Count, HasSub_Count),
	}
	return res
}


<|start_filename|>dots/line/line_imp.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package line

import (
	"fmt"
	"github.com/pkg/errors"
	"log"
	"reflect"
	"strings"
	"sync"

	"go.uber.org/zap"

	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/sconfig"
	"github.com/scryinfo/dot/dots/slog"
	"github.com/scryinfo/scryg/sutils/skit"
)

var (
	_ dot.Lifer    = (*lineImp)(nil)
	_ dot.Line     = (*lineImp)(nil)
	_ dot.Injecter = (*lineImp)(nil)
)

type lineImp struct {
	logger     dot.SLogger
	sConfig    dot.SConfig //External general config
	config     dot.Config  //Config object of component
	metas      *Metas      //
	lives      *Lives      //
	types      map[reflect.Type]dot.Dot
	newerLives map[dot.LiveID]dot.Newer
	newerTypes map[dot.TypeID]dot.Newer

	parent dot.Injecter
	mutex  sync.Mutex

	lineBuilder *dot.Builder

	//dot event
	dotEvent dotEventerImp
}

//newLine new
func newLine(builder *dot.Builder) *lineImp {
	a := &lineImp{metas: NewMetas(),
		lives: NewLives(), types: make(map[reflect.Type]dot.Dot),
		newerLives:  make(map[dot.LiveID]dot.Newer),
		newerTypes:  make(map[dot.TypeID]dot.Newer),
		lineBuilder: builder,
	}
	a.dotEvent.Init()

	if dot.GetDefaultLine() == nil {
		dot.SetDefaultLine(a)
	}

	return a
}

func (c *lineImp) ID() string {
	return c.lineBuilder.LineLiveID
}

//AddNewerByLiveID add new for live id
func (c *lineImp) AddNewerByLiveID(liveID dot.LiveID, newDot dot.Newer) error {
	c.mutex.Lock()
	defer c.mutex.Unlock()

	if _, ok := c.newerLives[liveID]; ok {
		return dot.SError.Existed.AddNewError(liveID.String())
	}

	c.newerLives[liveID] = newDot

	return nil
}

//AddNewerByTypeID add new for type
func (c *lineImp) AddNewerByTypeID(typeID dot.TypeID, newDot dot.Newer) error {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	if _, ok := c.newerTypes[typeID]; ok {
		return dot.SError.Existed.AddNewError(typeID.String())
	}

	c.newerTypes[typeID] = newDot

	return nil
}

//RemoveNewerByLiveID remove
func (c *lineImp) RemoveNewerByLiveID(liveID dot.LiveID) {
	c.mutex.Lock()
	defer c.mutex.Unlock()

	delete(c.newerLives, liveID)
}

//RemoveNewerByTypeID remove
func (c *lineImp) RemoveNewerByTypeID(typeID dot.TypeID) {
	c.mutex.Lock()
	defer c.mutex.Unlock()

	delete(c.newerTypes, typeID)
}

//PreAdd the dot is nil, do not create it
func (c *lineImp) PreAdd(typeLives ...*dot.TypeLives) error {
	logger := dot.Logger()
	c.mutex.Lock()
	defer c.mutex.Unlock()

	var err error

	for _, typeLive := range typeLives {
		err2 := c.metas.UpdateOrAdd(&typeLive.Meta)
		if err2 == nil {
			if len(typeLive.Lives) > 0 {
				for i := range typeLive.Lives {
					it := &typeLive.Lives[i]
					if len(it.TypeID.String()) < 1 {
						it.TypeID = typeLive.Meta.TypeID
					}

					//live := dot.Live{TypeID: it.TypeID, LiveID: it.LiveID, Dot: nil}
					//live.RelyLives = CloneRelyLiveID(it.RelyLives)
					err2 = c.lives.UpdateOrAdd(it)
					if err2 != nil {
						if err != nil {
							logger.Debugln(fmt.Sprintf("lineImp - meta: %v", typeLive.Meta))
							logger.Errorln("lineImp", zap.Error(err)) //write it into logfile, otherwise it will gone
						}
						err = err2
					}
				}
			}
		} else {
			if err != nil {
				logger.Debugln(fmt.Sprintf("lineImp - meta: %v", typeLive.Meta))
				logger.Errorln("lineImp", zap.Error(err)) //write it into logfile, otherwise it will gone
			}
			err = err2
		}
	}

	return err
}

//order the dots by relay relation
//first return, ordered dots
//second return, circle relay dots
//nolint:funlen
func (c *lineImp) relyOrder() ([]*dot.Live, []*dot.Live) {

	var cloneLives map[dot.LiveID]*dot.Live
	var cloneMetas map[dot.TypeID]*dot.Metadata
	logger := dot.Logger()
	{ //clone live and type
		c.mutex.Lock()
		cloneLives = make(map[dot.LiveID]*dot.Live, len(c.lives.LiveIDMap))
		for k, v := range c.lives.LiveIDMap {
			cloneLives[k] = v
		}
		cloneMetas = make(map[dot.TypeID]*dot.Metadata, len(c.metas.metas))
		for k, v := range c.metas.metas {
			cloneMetas[k] = v
		}
		c.mutex.Unlock()
	}

	order := make([]*dot.Live, 0, len(cloneLives))
	var circle []*dot.Live
	{
		relyed := make(map[dot.LiveID][]dot.LiveID, len(cloneLives))
		for _, it := range cloneLives {
			if _, ok := relyed[it.LiveID]; !ok {
				relyed[it.LiveID] = []dot.LiveID{}
			}

			for _, liveID := range it.RelyLives {
				r, ok := relyed[liveID]
				if !ok {
					r = []dot.LiveID{it.LiveID}
				} else {
					r = append(r, it.LiveID)
				}
				relyed[liveID] = r
			}
		}
		done := make(map[dot.LiveID]bool, len(relyed))          //know orderID
		remain := make(map[dot.LiveID]bool, len(relyed))        //do not know orderID
		levels := make([]map[dot.LiveID]bool, 0, len(relyed)/3) //
		{
			for liveID := range relyed {
				remain[liveID] = true
			}
			level0 := make(map[dot.LiveID]bool)
			for liveID, live := range cloneLives { //level 0
				if len(live.RelyLives) < 1 {
					level0[liveID] = true
					delete(remain, liveID)
					done[liveID] = true
				}
			}
			levels = append(levels, level0)
			levelCurrent := level0
			//todo if level0 is zero
			for curFor := 0; curFor <= len(relyed); curFor++ { //
				levelNext := make(map[dot.LiveID]bool, len(remain))
				for liveID := range levelCurrent {
					des := relyed[liveID]
					if len(des) < 1 {
						delete(remain, liveID)
						done[liveID] = true
					} else {
						for _, liveID2 := range des {
							allDone := true
							for _, liveID3 := range cloneLives[liveID2].RelyLives { //check all RelyLives
								if _, ok := done[liveID3]; !ok {
									allDone = false
									break
								}
							}
							if allDone {
								if _, ok := done[liveID2]; !ok { //just do it once
									levelNext[liveID2] = true
									done[liveID2] = true
								}
								delete(remain, liveID2)
							} else {
								//levelNext[liveID2] = true //put next level
							}
						}
					}
				}
				levels = append(levels, levelNext)
				if len(remain) < 1 || len(levelNext) < 1 {
					break
				}
				levelCurrent = levelNext
			}
		}

		//todo type relay
		{
			for i, lev := range levels {
				logger.Debugln(fmt.Sprintf("level : %d", i))
				for liveID := range lev {
					logger.Debugln(cloneLives[liveID].LiveID.String())
					live, ok := cloneLives[liveID]
					if ok {
						order = append(order, live)
					} else {
						logger.Warnln("", zap.String("", "dot not find the dot live id: "+liveID.String()))
					}
				}
			}
			if len(remain) > 0 {
				circle = make([]*dot.Live, 0, len(remain))
				for liveID := range remain { //append to tail
					live, ok := cloneLives[liveID]
					if ok {
						order = append(order, live)
						circle = append(circle, live)
					} else {
						logger.Warnln("", zap.String("", "dot not find the dot live id: "+liveID.String()))
					}
				}
			}
		}
	}

	return order, circle
}

//CreateDots create dots
func (c *lineImp) CreateDots(orderedDots []*dot.Live) error {
	logger := dot.Logger()
	createDotFun := func(it *dot.Live) error {
		{ // Check whether special info needed before Create
			if nl, ok := it.Dot.(dot.SetterLine); ok {
				nl.SetLine(c)
			}

			if nl, ok := it.Dot.(dot.SetterTypeAndLiveID); ok {
				nl.SetTypeID(it.TypeID, it.LiveID)
			}
		}

		if b := c.dotEvent.TypeEvents(it.TypeID); len(b) > 0 { // do before create for type
			for i := range b {
				e := &b[i]
				if e.BeforeCreate != nil {
					e.BeforeCreate(it, c)
				}
			}
		}

		if b := c.dotEvent.LiveEvents(it.LiveID); len(b) > 0 { // do before create for live
			for i := range b {
				e := &b[i]
				if e.BeforeCreate != nil {
					e.BeforeCreate(it, c)
				}
			}
		}

		if creator, ok := it.Dot.(dot.Creator); ok { //do createDotFun
			if err := creator.Create(c); err != nil {
				return err
			}
		}

		if a := c.dotEvent.LiveEvents(it.LiveID); len(a) > 0 { //do after create for live
			for i := range a {
				e := &a[i]
				if e.AfterCreate != nil {
					e.AfterCreate(it, c)
				}
			}
		}

		if a := c.dotEvent.TypeEvents(it.TypeID); len(a) > 0 { // dot after create for type
			for i := range a {
				e := &a[i]
				if e.AfterCreate != nil {
					e.AfterCreate(it, c)
				}
			}
		}

		return nil
	}
	var err error
	var dotLive *dot.Live //just for debug
CreateLives:
	for _, dotLive = range orderedDots {
		logger.Debug(func() string {
			m, _ := c.metas.Get(dotLive.TypeID)
			if m != nil {
				return fmt.Sprintf("Create dot, type id: %s, live id: %s, name: %s", dotLive.TypeID, dotLive.LiveID, m.Name)
			}
			return fmt.Sprintf("Create dot, type id: %s, live id: %s", dotLive.TypeID, dotLive.LiveID)
		})

		if skit.IsNil(&dotLive.Dot) {
			var bytesConfig []byte
			var config *dot.LiveConfig
			{
				config = c.config.FindConfig(dotLive.TypeID, dotLive.LiveID)
				bytesConfig, err = dot.MarshalConfig(config)
				if err != nil {
					break CreateLives
				}
			}

			//new by liveID
			{
				if newer, ok := c.newerLives[dotLive.LiveID]; ok {
					dotLive.Dot, err = newer(bytesConfig)
					if err != nil {
						break CreateLives
					} else {
						if err = createDotFun(dotLive); err != nil {
							break CreateLives
						}
						continue CreateLives
					}
				}
			}
			//new by typeID
			{
				if newer, ok := c.newerTypes[dotLive.TypeID]; ok {
					dotLive.Dot, err = newer(bytesConfig)
					if err != nil {
						break CreateLives
					} else {
						if err = createDotFun(dotLive); err != nil {
							break CreateLives
						}
						continue CreateLives
					}
				}
			}

			//new by metadata
			{
				var m *dot.Metadata
				m, err = c.metas.Get(dotLive.TypeID)
				if err != nil {
					break CreateLives
				}

				if m.NewDoter == nil && m.RefType == nil {
					err = dot.SError.NoDotNewer.AddNewError(m.TypeID.String())
					break CreateLives
				}

				dotLive.Dot, err = m.NewDot(bytesConfig)
				if err == nil {
					if err = createDotFun(dotLive); err != nil {
						break CreateLives
					}
					continue CreateLives
				} else {
					break CreateLives
				}
			}
		}
	}

	if err != nil {
		logger.Debug(func() string {
			m, _ := c.metas.Get(dotLive.TypeID)
			if m != nil {
				return fmt.Sprintf("Create dot, meta: %v\n live: %v", m, dotLive)
			}
			return fmt.Sprintf("Create dot, live: %v", dotLive)
		})
		logger.Errorln("lineImp", zap.Error(err))
		return err
	}
	//Add logger and config
	{
		c.mutex.Lock()
		c.types[reflect.TypeOf(c.logger)] = c.logger
		{
			t := reflect.TypeOf((*dot.SLogger)(nil)).Elem()
			c.types[t] = c.logger
		}
		c.types[reflect.TypeOf(c.config)] = c.config
		{
			t := reflect.TypeOf((*dot.SConfig)(nil)).Elem()
			c.types[t] = c.sConfig
		}
		c.mutex.Unlock()
	}

	//Add type and relationships with dot, only record whose type id == live ID
	for _, it := range orderedDots {
		if !skit.IsNil(&it.Dot) && ((string)(it.TypeID) == (string)(it.LiveID)) {
			t := reflect.TypeOf(it.Dot)
			c.mutex.Lock()
			c.types[t] = it.Dot
			//if the dot implements the dot.GetInterfaceType, put the interface into types too
			if getter, ok := it.Dot.(dot.GetInterfaceType); ok {
				c.types[getter.GetInterfaceType()] = it.Dot
			}
			c.mutex.Unlock()
		}
	}

	{
		afterInjects := make([]dot.AfterAllInjecter, 0, 20)
		err = nil
		for _, it := range orderedDots {
			if it.Dot != nil { //not success
				err = c.injectInLine(it.Dot, it)
				if err != nil {
					break
				}
				if ed, ok := it.Dot.(dot.Injected); ok {
					err = ed.Injected(c)
					if err != nil {
						logger.Debug(func() string {
							m, _ := c.metas.Get(it.TypeID)
							if m != nil {
								return fmt.Sprintf("Create dot, meta: %v\n live: %v", m, it)
							}
							return fmt.Sprintf("Create dot, live: %v", it)
						})
						logger.Errorln("lineImp", zap.Error(err))
						break
					}
				}
				if s, ok := it.Dot.(dot.AfterAllInjecter); ok {
					afterInjects = append(afterInjects, s)
				}
			}
		}
		if err == nil {
			for _, v := range afterInjects {
				v.AfterAllInject(c)
			}
		}
	}

	return err
}

func (c *lineImp) Config() *dot.Config {
	return &c.config
}

func (c *lineImp) SLogger() dot.SLogger {
	return c.logger
}

func (c *lineImp) SConfig() dot.SConfig {
	return c.sConfig
}

func (c *lineImp) ToLifer() dot.Lifer {
	return c
}

//ToInjecter to injecter
func (c *lineImp) ToInjecter() dot.Injecter {
	return c
}

func (c *lineImp) ToDotEventer() dot.Eventer {
	return &c.dotEvent
}

func (c *lineImp) GetDotConfig(liveID dot.LiveID) *dot.LiveConfig {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	co := c.config.FindConfig("", liveID)
	return co
}

/////injecter
//Inject see https://github.com/facebookgo/inject
func (c *lineImp) Inject(obj interface{}) error {
	logger := dot.Logger()
	var err error
	if skit.IsNil(obj) {
		return dot.SError.NilParameter
	}

	value := reflect.ValueOf(obj)

	for value.Kind() == reflect.Ptr {
		value = value.Elem()
	}

	if value.Kind() != reflect.Struct {
		return dot.SError.NotStruct
	}

	rType := value.Type()

	for i := 0; i < value.NumField(); i++ {
		var err2 error
		valueField := value.Field(i)
		if !valueField.CanSet() {
			continue
		}

		typeField := rType.Field(i)
		tagName, ok := typeField.Tag.Lookup(dot.TagDot)
		if !ok {
			continue
		}

		//check the field type, #40
		if typeField.Type.Kind() != reflect.Ptr && typeField.Type.Kind() != reflect.Interface {
			err2 = errors.New("the field with dot tag must be point or interface")
			logger.Debug(func() string {
				return fmt.Sprintf("error: %s\ninstance: %v", err2.Error(), obj)
			})
			multiErr(&err, err2)
		}

		var d dot.Dot
		{
			if len(tagName) < 1 || tagName == dot.CanNull { //by type
				d, err2 = c.GetByType(valueField.Type())
			} else { //by live id
				liveID := strings.TrimPrefix(tagName, dot.CanNull) // like ?live id
				d, err2 = c.GetByLiveID(dot.LiveID(liveID))
			}

			if err2 != nil {
				if tagName == dot.CanNull { //组件为可选
					if dotError, ok := err2.(dot.Errorer); !ok || dotError.Code() != dot.SError.NotExisted.Code() { //如果error code不为不存在
						logger.Debugln(fmt.Sprintf("lineImp, find dot error, field: %s, err: %value", typeField.Name, err2))
						multiErr(&err, err2)
					}
				} else {
					logger.Debugln(fmt.Sprintf("lineImp, find dot error, field: %s, err: %value", typeField.Name, err2))
					multiErr(&err, err2)
				}
			}

			if d == nil {
				logger.Debugln(fmt.Sprintf("lineImp, can not find dot error, field: %s", typeField.Name))
				continue
			}
		}

		if err2 == nil {
			valueDot := reflect.ValueOf(d)
			if valueDot.IsValid() && valueDot.Type().AssignableTo(valueField.Type()) {
				valueField.Set(valueDot)
			} else {
				multiErr(&err, dot.SError.DotInvalid.AddNewError(typeField.Type.String()+"  "+tagName))
			}
		}
	}

	return err
}

// like Inject func
func (c *lineImp) injectInLine(obj interface{}, live *dot.Live) error {
	logger := dot.Logger()
	var err error
	if skit.IsNil(obj) {
		return dot.SError.NilParameter
	}

	value := reflect.ValueOf(obj)

	for value.Kind() == reflect.Ptr {
		value = value.Elem()
	}

	if value.Kind() != reflect.Struct {
		return dot.SError.NotStruct
	}

	rType := value.Type()

	for i := 0; i < value.NumField(); i++ {
		var err2 error = nil
		valueField := value.Field(i)
		if !valueField.CanSet() {
			continue
		}

		tField := rType.Field(i)
		tagName, ok := tField.Tag.Lookup(dot.TagDot)
		if !ok {
			continue
		}
		//check the field type, #40
		if tField.Type.Kind() != reflect.Ptr && tField.Type.Kind() != reflect.Interface {
			err2 = errors.New("the field with dot tag must be point or interface")
			logger.Debug(func() string {
				return fmt.Sprintf("error: %s\nlive: %v", err2.Error(), live)
			})
			multiErr(&err, err2)
		}

		var d dot.Dot
		{
			if len(live.RelyLives) > 0 { //Config prior
				if liveID, ok := live.RelyLives[tField.Name]; ok {
					d, err2 = c.GetByLiveID(liveID)
				}
			}
			if d == nil {
				if len(tagName) < 1 || tagName == dot.CanNull { //by type
					d, err2 = c.GetByType(valueField.Type())
				} else { //by live id
					liveID := strings.TrimPrefix(tagName, dot.CanNull) // like ?live id
					d, err2 = c.GetByLiveID(dot.LiveID(liveID))
				}
			}

			if err2 != nil {
				if tagName == dot.CanNull { //组件为可选
					if dotError, ok := err2.(dot.Errorer); !ok || dotError.Code() != dot.SError.NotExisted.Code() { //如果error code不为不存在
						logger.Debugln(fmt.Sprintf("lineImp, find dot error, field: %s, err: %value", tField.Name, err2))
						multiErr(&err, err2)
					}
				} else {
					logger.Debugln(fmt.Sprintf("lineImp, find dot error, field: %s, err: %value", tField.Name, err2))
					multiErr(&err, err2)
				}
			}

			if d == nil {
				logger.Debugln(fmt.Sprintf("lineImp, can not find dot error, field: %s, live: %value", tField.Name, live))
				continue
			}
		}

		if err2 == nil {
			valueDot := reflect.ValueOf(d)
			//fmt.Println("valueDot: ", valueDot.Type(), "valueField: ", valueField.Type(), "dd: ", reflect.TypeOf(d))
			if valueDot.IsValid() && valueDot.Type().AssignableTo(valueField.Type()) {
				valueField.Set(valueDot)
			} else if err == nil {
				multiErr(&err, dot.SError.DotInvalid.AddNewError(tField.Type.String()+"  "+tagName))
			}
		}
	}

	return err
}

//GetByType get by type
func (c *lineImp) GetByType(t reflect.Type) (d dot.Dot, err error) {
	d = nil
	err = nil
	c.mutex.Lock()
	d, ok := c.types[t]
	c.mutex.Unlock()
	if !ok {
		if c.parent != nil {
			d, err = c.parent.GetByType(t)
		} else {
			err = dot.SError.NotExisted.AddNewError(t.String())
		}
	}

	return
}

//GetByLiveID get by live id
func (c *lineImp) GetByLiveID(liveID dot.LiveID) (d dot.Dot, err error) {
	d = nil
	err = nil
	c.mutex.Lock()
	var l *dot.Live
	l, err = c.lives.Get(liveID)
	c.mutex.Unlock()
	if err != nil {
		if c.parent != nil {
			d, err = c.parent.GetByLiveID(liveID)
		}
	} else {
		d = l.Dot
	}

	return
}

//ReplaceOrAddByType update
func (c *lineImp) ReplaceOrAddByType(d dot.Dot) error {
	var err error
	typeDot := reflect.TypeOf(d)
	//for typeDot.Kind() == reflect.Ptr || typeDot.Kind() == reflect.Interface {
	//	typeDot = typeDot.Elem()
	//}
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.types[typeDot] = d
	return err
}

//ReplaceOrAddByParamType update
func (c *lineImp) ReplaceOrAddByParamType(d dot.Dot, rType reflect.Type) error {
	var err error
	//for rType.Kind() == reflect.Ptr || rType.Kind() == reflect.Interface {
	//	rType = rType.Elem()
	//}
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.types[rType] = d
	return err
}

//ReplaceOrAddByLiveID update
func (c *lineImp) ReplaceOrAddByLiveID(d dot.Dot, liveID dot.LiveID) error {
	var err error
	c.mutex.Lock()
	defer c.mutex.Unlock()

	l := dot.Live{LiveID: liveID, TypeID: "", Dot: d, RelyLives: nil}
	//c.lives.Remove(&l)
	err = c.lives.UpdateOrAdd(&l)

	return err
}

//RemoveByType remove
func (c *lineImp) RemoveByType(rType reflect.Type) error {
	var err error
	c.mutex.Lock()
	defer c.mutex.Unlock()
	delete(c.types, rType)
	return err
}

//RemoveByLiveID remove
func (c *lineImp) RemoveByLiveID(liveID dot.LiveID) error {
	var err error
	c.mutex.Lock()
	defer c.mutex.Unlock()
	err = c.lives.RemoveByID(liveID)
	return err
}

//SetParent set parent injecter
func (c *lineImp) SetParent(parent dot.Injecter) {
	c.parent = parent
}

//GetParent get parent injecter
func (c *lineImp) GetParent() dot.Injecter {
	return c.parent
}

////injecter end

//Create create
//If live id is empty， directly assign type id
//If live id repeated，directly return dot.SError.ErrExistedLiveID
func (c *lineImp) Create(l dot.Line) error {
	var err error

	//first create config
	c.sConfig = sconfig.NewConfig()
	c.sConfig.RootPath()
	if s, ok := c.sConfig.(dot.Creator); ok {
		if err = s.Create(l); err != nil {
			createLog(c)
			return err
		} else if len(c.sConfig.ConfigFile()) < 1 { //no config file return
			createLog(c)
			return err
		}
	}

	if err = c.sConfig.Unmarshal(&c.config); err != nil {
		createLog(c)
		return err
	}
	if len(c.config.Dots) < 1 { //no config
		createLog(c)
		return err
	}

	//create log
	createLog(c)
	return err
}

func (c *lineImp) makeDotMetaFromConfig() error {
	c.mutex.Lock()
	defer c.mutex.Unlock()

	var err error
	var dotConfig *dot.MetaLivesConfig
ForConfigDots: //handle config
	for i := range c.config.Dots {
		dotConfig = &c.config.Dots[i]
		if len(dotConfig.MetaData.TypeID.String()) < 1 {
			err = dot.SError.Config.AddNewError("type id is null")
			break ForConfigDots
		}

		if err = c.metas.UpdateOrAdd(&dotConfig.MetaData); err != nil {
			break ForConfigDots
		}

		if len(dotConfig.Lives) < 1 { //create the single live
			live := dot.Live{TypeID: dotConfig.MetaData.TypeID, LiveID: dot.LiveID(dotConfig.MetaData.TypeID), Dot: nil}
			if len(dotConfig.MetaData.RelyTypeIDs) > 0 {
				live.RelyLives = make(map[string]dot.LiveID, len(dotConfig.MetaData.RelyTypeIDs))
				for i := range dotConfig.MetaData.RelyTypeIDs {
					li := &dotConfig.MetaData.RelyTypeIDs[i]
					live.RelyLives[li.String()] = dot.LiveID(*li)
				}
			}
			if err = c.lives.UpdateOrAdd(&live); err != nil {
				break ForConfigDots
			}
		} else {
			for _, li := range dotConfig.Lives {
				if len(li.LiveID.String()) < 1 {
					li.LiveID = dot.LiveID(dotConfig.MetaData.TypeID)
				}
				live := dot.Live{TypeID: dotConfig.MetaData.TypeID, LiveID: li.LiveID, RelyLives: li.RelyLives, Dot: nil}
				if err = c.lives.UpdateOrAdd(&live); err != nil {
					break ForConfigDots
				}
			}
		}
	}
	if err != nil {
		dot.Logger().Debugln(fmt.Sprintf("lineImp, %v", dotConfig))
	}

	return err
}

//case #17
func (c *lineImp) autoMakeLiveID() {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	hasType := make(map[dot.TypeID]bool, len(c.lives.LiveIDMap))
	for _, v := range c.lives.LiveIDMap {
		hasType[v.TypeID] = true
	}

	for typeID := range c.metas.metas {
		if _, ok := hasType[typeID]; !ok {
			liveID := (dot.LiveID)(typeID)
			live := dot.Live{TypeID: typeID, LiveID: liveID, Dot: nil, RelyLives: nil}
			err2 := c.lives.UpdateOrAdd(&live)
			if err2 != nil && c.logger != nil {
				c.logger.Debugln(fmt.Sprintf("err: %v, live: %v", err2, live))
			}
		}
	}
}

//get relay from the tag
//merge type relay
//merge live relay
//verify the key of relay lives(the name have to eq the field name)
func (c *lineImp) makeRelays() {
	var setExists = struct{}{} //only for set value
	c.mutex.Lock()
	defer c.mutex.Unlock()
	logger := dot.Logger()
	liveIDToType := make(map[dot.LiveID]dot.TypeID)
	typeIDToLiveIds := make(map[dot.TypeID]map[dot.LiveID]struct{}, len(c.lives.LiveIDMap))
	for _, live := range c.lives.LiveIDMap {
		liveIDToType[live.LiveID] = live.TypeID
		if _, ok := typeIDToLiveIds[live.TypeID]; !ok {
			typeIDToLiveIds[live.TypeID] = make(map[dot.LiveID]struct{})
		}
		typeIDToLiveIds[live.TypeID][live.LiveID] = setExists
	}
	typeToTypeID := make(map[reflect.Type]dot.TypeID)
	for _, meta := range c.metas.metas {
		if meta.RefType != nil {
			typeToTypeID[meta.RefType] = meta.TypeID
		}
	}
	for _, meta := range c.metas.metas { //relay type
		dotFields := make(map[string]dot.LiveID)
		if meta.RefType != nil {
			relayTypeIDs := make(map[dot.TypeID]struct{})
			for i := 0; i < meta.RefType.NumField(); i++ { // relay by tag
				tField := meta.RefType.Field(i)
				liveID, ok := tField.Tag.Lookup(dot.TagDot)
				if !ok || liveID == dot.CanNull { //not find or eq ?
					continue
				}
				dotFields[tField.Name] = dot.LiveID(liveID)
				if len(liveID) < 1 {
					if typeID, ok := typeToTypeID[tField.Type]; ok {
						relayTypeIDs[typeID] = setExists
					} else {
						//do not find typeID
					}
				} else {
					if typeID, ok := liveIDToType[dot.LiveID(liveID)]; ok {
						relayTypeIDs[typeID] = setExists
					}
				}
			}

			if lives, ok := typeIDToLiveIds[meta.TypeID]; ok {
				//for liveID := range lives { relay type and relay live, sometimes they are not same
				//	if live, ok := c.lives.LiveIDMap[liveID]; ok {
				//		relayTypeIDs[live.TypeID] = setExists
				//	}
				//}

				//verify the field name for relay live
				for liveID := range lives {
					if live, ok := c.lives.LiveIDMap[liveID]; ok {
						for name := range live.RelyLives {
							if _, ok := dotFields[name]; !ok {
								if logger != nil {
									logger.Warn(func() string {
										return fmt.Sprintf("make relay of dot, meta: %v\n live: %v", meta, live)
									})
								}
							}
						}

						for name, nameLiveID := range dotFields {
							if _, ok := live.RelyLives[name]; !ok {
								if len(nameLiveID.String()) > 0 {
									live.RelyLives[name] = nameLiveID
								} else {
									//do nothing, do not know live id
								}
							}
						}
					}
				}
			}

			if len(relayTypeIDs) > 0 {
				for _, typeID := range meta.RelyTypeIDs { //distinct
					relayTypeIDs[typeID] = setExists
				}
				meta.RelyTypeIDs = make([]dot.TypeID, 0, len(relayTypeIDs))
				for typeID := range relayTypeIDs {
					meta.RelyTypeIDs = append(meta.RelyTypeIDs, typeID)
				}
			}
		}
	}
}

func createLog(c *lineImp) {
	c.logger = slog.NewSLogger(&(c.config.Log), c)
	dot.SetLogger(c.logger)
}

//Start
func (c *lineImp) Start(ignore bool) error {
	var err error
	logger := dot.Logger()

	for {
		//start config
		if s, ok := c.sConfig.(dot.Starter); ok {
			if err = s.Start(ignore); err != nil {
				break
			}
		}
		//start log
		if s, ok := c.logger.(dot.Starter); ok {
			if err = s.Start(ignore); err != nil {
				break
			}
		}

		//start other
		{
			//recount the order, maybe the "Ceate" change it
			tdots, _ := c.relyOrder() //do not care the circle
			afterStarts := make([]dot.AfterAllStarter, 0, 20)
			for _, it := range tdots {
				logger.Debug(func() string {
					m, _ := c.metas.Get(it.TypeID)
					if m != nil {
						return fmt.Sprintf("Start dot, type id: %s, live id: %s, name: %s", it.TypeID, it.LiveID, m.Name)
					}
					return fmt.Sprintf("Start dot, type id: %s, live id: %s", it.TypeID, it.LiveID)
				})
				if b := c.dotEvent.TypeEvents(it.TypeID); len(b) > 0 {
					for i := range b {
						e := &b[i]
						if e.BeforeStart != nil {
							e.BeforeStart(it, c)
						}
					}
				}

				if b := c.dotEvent.LiveEvents(it.LiveID); len(b) > 0 {
					for i := range b {
						e := &b[i]
						if e.BeforeStart != nil {
							e.BeforeStart(it, c)
						}
					}
				}

				if d, ok := it.Dot.(dot.Starter); ok {
					err2 := d.Start(ignore)
					if err2 != nil {
						logger.Debug(func() string {
							m, _ := c.metas.Get(it.TypeID)
							if m != nil {
								return fmt.Sprintf("Start dot, meta: %v\n live: %v\n %v", m, it, d)
							}
							return fmt.Sprintf("Start dot, live: %v\n %v", it, d)
						})
						if err != nil {
							logger.Errorln("lineImp", zap.Error(err))
						}
						err = err2
						if !ignore {
							return err
						}
					}
				}

				if a := c.dotEvent.LiveEvents(it.LiveID); len(a) > 0 {
					for i := range a {
						e := &a[i]
						if e.AfterStart != nil {
							e.AfterStart(it, c)
						}
					}
				}

				if a := c.dotEvent.TypeEvents(it.TypeID); len(a) > 0 {
					for i := range a {
						e := &a[i]
						if e.AfterStart != nil {
							e.AfterStart(it, c)
						}
					}
				}

				if s, ok := it.Dot.(dot.AfterAllStarter); ok {
					afterStarts = append(afterStarts, s)
				}
			}

			for _, s := range afterStarts {
				s.AfterAllStart(c)
			}
		}

		break
	}

	return err
}

//Stop
func (c *lineImp) Stop(ignore bool) error {
	var err error
	logger := dot.Logger()
	//stop others
	{
		//recount the order, maybe the "Ceate" change it
		tdots, _ := c.relyOrder() //do not care the circle
		{
			beforeStops := make([]dot.BeforeAllStopper, 0, 20)

			for i := len(tdots) - 1; i >= 0; i-- {
				if b, ok := tdots[i].Dot.(dot.BeforeAllStopper); ok {
					beforeStops = append(beforeStops, b)
				}
			}

			for _, it := range beforeStops {
				it.BeforeAllStop(c)
			}
		}

		for i := len(tdots) - 1; i >= 0; i-- {
			it := tdots[i]
			logger.Debug(func() string {
				m, _ := c.metas.Get(it.TypeID)
				if m != nil {
					return fmt.Sprintf("Stop dot, type id: %s, live id: %s, name: %s", it.TypeID, it.LiveID, m.Name)
				}
				return fmt.Sprintf("Stop dot, type id: %s, live id: %s", it.TypeID, it.LiveID)
			})
			if b := c.dotEvent.TypeEvents(it.TypeID); len(b) > 0 {
				for i := range b {
					e := &b[i]
					if e.BeforeStop != nil {
						e.BeforeStop(it, c)
					}
				}
			}

			if b := c.dotEvent.LiveEvents(it.LiveID); len(b) > 0 {
				for i := range b {
					e := &b[i]
					if e.BeforeStop != nil {
						e.BeforeStop(it, c)
					}
				}
			}

			if d, ok := it.Dot.(dot.Stopper); ok {
				err2 := d.Stop(ignore)
				if err2 != nil {
					logger.Debugln(fmt.Sprintf("lineImp, Stop dot: %v", d))
					if err != nil {
						logger.Errorln("", zap.Error(err))
					}
					err = err2
				}

				if !ignore {
					return err
				}
			}

			if a := c.dotEvent.LiveEvents(it.LiveID); len(a) > 0 {
				for i := range a {
					e := &a[i]
					if e.AfterStop != nil {
						e.AfterStop(it, c)
					}
				}
			}

			if a := c.dotEvent.TypeEvents(it.TypeID); len(a) > 0 {
				for i := range a {
					e := &a[i]
					if e.AfterStop != nil {
						e.AfterStop(it, c)
					}
				}
			}
		}
	}
	//stop log
	if d, ok := c.logger.(dot.Stopper); ok {
		err2 := d.Stop(ignore)
		if err2 != nil {
			logger.Debugln(fmt.Sprintf("lineImp, Stop dot: %v", d))
			if err != nil {
				logger.Errorln("", zap.Error(err))
			}
			err = err2
		}
	}

	//stop config
	if d, ok := c.sConfig.(dot.Stopper); ok {
		err2 := d.Stop(ignore)
		if err2 != nil {
			logger.Debugln(fmt.Sprintf("lineImp, Stop dot: %v", d))
			if err != nil {
				logger.Errorln("", zap.Error(err))
			}
			err = err2
		}
	}

	return err
}

//Destroy Destroy Dot
func (c *lineImp) Destroy(ignore bool) error {
	var err error
	logger := dot.Logger()
	//Destroy others
	{
		afterAll := make([]dot.AfterAllDestroyer, 0, 20)
		//recount the order, maybe the "Ceate" change it
		tdots, _ := c.relyOrder() //do not care the circle
		for i := len(tdots) - 1; i >= 0; i-- {
			it := tdots[i]
			logger.Debug(func() string {
				m, _ := c.metas.Get(it.TypeID)
				if m != nil {
					return fmt.Sprintf("Destroy dot, type id: %s, live id: %s, name: %s", it.TypeID, it.LiveID, m.Name)
				}
				return fmt.Sprintf("Destroy dot, type id: %s, live id: %s", it.TypeID, it.LiveID)
			})
			if b := c.dotEvent.TypeEvents(it.TypeID); len(b) > 0 {
				for i := range b {
					e := &b[i]
					if e.BeforeDestroy != nil {
						e.BeforeDestroy(it, c)
					}
				}
			}

			if b := c.dotEvent.LiveEvents(it.LiveID); len(b) > 0 {
				for i := range b {
					e := &b[i]
					if e.BeforeDestroy != nil {
						e.BeforeDestroy(it, c)
					}
				}
			}

			if d, ok := it.Dot.(dot.Destroyer); ok {
				err2 := d.Destroy(ignore)
				if err2 != nil {
					logger.Debugln(fmt.Sprintf("lineImp, Destroy dot: %v", d))
					if err != nil {
						logger.Errorln("lineImp", zap.Error(err))
					}
					err = err2
				}
				if !ignore {
					return err
				}
			}

			if a := c.dotEvent.LiveEvents(it.LiveID); len(a) > 0 {
				for i := range a {
					e := &a[i]
					if e.AfterDestroy != nil {
						e.AfterDestroy(it, c)
					}
				}
			}

			if a := c.dotEvent.TypeEvents(it.TypeID); len(a) > 0 {
				for i := range a {
					e := &a[i]
					if e.AfterDestroy != nil {
						e.AfterDestroy(it, c)
					}
				}
			}

			if all, ok := it.Dot.(dot.AfterAllDestroyer); ok {
				afterAll = append(afterAll, all)
			}
		}

		for _, it := range afterAll {
			it.AfterAllDestroy(c)
		}
	}
	return err
}

func (c *lineImp) GetLineBuilder() *dot.Builder {
	return c.lineBuilder
}
func (c *lineImp) InfoAllTypeAdnLives() {
	c.logger.Info(func() string {
		return fmt.Sprintf("lives - %d: %v, types - %d: %v", len(c.lives.LiveIDMap), c.lives.LiveIDMap, len(c.types), c.types)
	})
}

func (c *lineImp) EachLives(call func(live *dot.Live, meta *dot.Metadata) bool) {
	if call != nil {
		c.mutex.Lock()
		liveIDS := make([]dot.LiveID, 0, len(c.lives.LiveIDMap))
		for liveID := range c.lives.LiveIDMap {
			liveIDS = append(liveIDS, liveID)
		}
		typeIDS := make([]dot.TypeID, 0, len(c.metas.metas))
		for typeID := range c.metas.metas {
			typeIDS = append(typeIDS, typeID)
		}
		c.mutex.Unlock()
		for _, liveID := range liveIDS {
			var live *dot.Live
			var meta *dot.Metadata
			c.mutex.Lock()
			live = c.lives.LiveIDMap[liveID] //if the key do not exist, return nil
			if live != nil {
				meta = c.metas.metas[live.TypeID] //if the key do not exist, return nil
			}
			c.mutex.Unlock() //unlock mutex to avoid the dead lock
			if !call(live, meta) {
				break
			}
		}
	}
}

func (c *lineImp) DestroyConfigLog() error {
	var err error
	//Destroy config
	if d, ok := c.sConfig.(dot.Destroyer); ok {
		err = d.Destroy(true)
		if err != nil {
			c.logger.Debugln(fmt.Sprintf("lineImp, Destroy dot: %v", d))
		}
	}
	//Destroy log
	if d, ok := c.logger.(dot.Destroyer); ok {
		err2 := d.Destroy(true)
		if err2 != nil {
			log.Printf("lineImp, Destroy dot: %v", d) //no logger
			err = err2
		}
	}

	return err
}

///////////////

func multiErr(err *error, err2 error) {
	if err2 != nil {
		if *err != nil {
			dot.Logger().Errorln("lineImp", zap.Error(*err))
		}
		*err = err2
	}
}


<|start_filename|>tools/dotconf/ui/src/rpc_face/config_pb.js<|end_filename|>
// source: config.proto
/**
 * @fileoverview
 * @enhanceable
 * @suppress {messageConventions} JS Compiler reports an error if a variable or
 *     field starts with 'MSG_' and isn't a translatable message.
 * @public
 */
// GENERATED CODE -- DO NOT EDIT!

var jspb = require('google-protobuf');
var goog = jspb;
var global = Function('return this')();

goog.exportSymbol('proto.rpc.ExportReq', null, global);
goog.exportSymbol('proto.rpc.ExportRes', null, global);
goog.exportSymbol('proto.rpc.FindReq', null, global);
goog.exportSymbol('proto.rpc.FindRes', null, global);
goog.exportSymbol('proto.rpc.ImportReq', null, global);
goog.exportSymbol('proto.rpc.ImportRes', null, global);
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.rpc.FindReq = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, proto.rpc.FindReq.repeatedFields_, null);
};
goog.inherits(proto.rpc.FindReq, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.rpc.FindReq.displayName = 'proto.rpc.FindReq';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.rpc.FindRes = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, proto.rpc.FindRes.repeatedFields_, null);
};
goog.inherits(proto.rpc.FindRes, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.rpc.FindRes.displayName = 'proto.rpc.FindRes';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.rpc.ImportReq = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.rpc.ImportReq, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.rpc.ImportReq.displayName = 'proto.rpc.ImportReq';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.rpc.ImportRes = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.rpc.ImportRes, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.rpc.ImportRes.displayName = 'proto.rpc.ImportRes';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.rpc.ExportReq = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, proto.rpc.ExportReq.repeatedFields_, null);
};
goog.inherits(proto.rpc.ExportReq, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.rpc.ExportReq.displayName = 'proto.rpc.ExportReq';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.rpc.ExportRes = function(opt_data) {
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.rpc.ExportRes, jspb.Message);
if (goog.DEBUG && !COMPILED) {
  /**
   * @public
   * @override
   */
  proto.rpc.ExportRes.displayName = 'proto.rpc.ExportRes';
}

/**
 * List of repeated fields within this message type.
 * @private {!Array<number>}
 * @const
 */
proto.rpc.FindReq.repeatedFields_ = [1];



if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.rpc.FindReq.prototype.toObject = function(opt_includeInstance) {
  return proto.rpc.FindReq.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.rpc.FindReq} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.rpc.FindReq.toObject = function(includeInstance, msg) {
  var f, obj = {
    dirsList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.rpc.FindReq}
 */
proto.rpc.FindReq.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.rpc.FindReq;
  return proto.rpc.FindReq.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.rpc.FindReq} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.rpc.FindReq}
 */
proto.rpc.FindReq.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = /** @type {string} */ (reader.readString());
      msg.addDirs(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.rpc.FindReq.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.rpc.FindReq.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.rpc.FindReq} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.rpc.FindReq.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getDirsList();
  if (f.length > 0) {
    writer.writeRepeatedString(
      1,
      f
    );
  }
};


/**
 * repeated string dirs = 1;
 * @return {!Array<string>}
 */
proto.rpc.FindReq.prototype.getDirsList = function() {
  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 1));
};


/**
 * @param {!Array<string>} value
 * @return {!proto.rpc.FindReq} returns this
 */
proto.rpc.FindReq.prototype.setDirsList = function(value) {
  return jspb.Message.setField(this, 1, value || []);
};


/**
 * @param {string} value
 * @param {number=} opt_index
 * @return {!proto.rpc.FindReq} returns this
 */
proto.rpc.FindReq.prototype.addDirs = function(value, opt_index) {
  return jspb.Message.addToRepeatedField(this, 1, value, opt_index);
};


/**
 * Clears the list making it empty but non-null.
 * @return {!proto.rpc.FindReq} returns this
 */
proto.rpc.FindReq.prototype.clearDirsList = function() {
  return this.setDirsList([]);
};



/**
 * List of repeated fields within this message type.
 * @private {!Array<number>}
 * @const
 */
proto.rpc.FindRes.repeatedFields_ = [2];



if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.rpc.FindRes.prototype.toObject = function(opt_includeInstance) {
  return proto.rpc.FindRes.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.rpc.FindRes} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.rpc.FindRes.toObject = function(includeInstance, msg) {
  var f, obj = {
    dotsinfo: jspb.Message.getFieldWithDefault(msg, 1, ""),
    noexistdirsList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f,
    error: jspb.Message.getFieldWithDefault(msg, 3, "")
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.rpc.FindRes}
 */
proto.rpc.FindRes.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.rpc.FindRes;
  return proto.rpc.FindRes.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.rpc.FindRes} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.rpc.FindRes}
 */
proto.rpc.FindRes.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = /** @type {string} */ (reader.readString());
      msg.setDotsinfo(value);
      break;
    case 2:
      var value = /** @type {string} */ (reader.readString());
      msg.addNoexistdirs(value);
      break;
    case 3:
      var value = /** @type {string} */ (reader.readString());
      msg.setError(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.rpc.FindRes.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.rpc.FindRes.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.rpc.FindRes} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.rpc.FindRes.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getDotsinfo();
  if (f.length > 0) {
    writer.writeString(
      1,
      f
    );
  }
  f = message.getNoexistdirsList();
  if (f.length > 0) {
    writer.writeRepeatedString(
      2,
      f
    );
  }
  f = message.getError();
  if (f.length > 0) {
    writer.writeString(
      3,
      f
    );
  }
};


/**
 * optional string dotsInfo = 1;
 * @return {string}
 */
proto.rpc.FindRes.prototype.getDotsinfo = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
};


/**
 * @param {string} value
 * @return {!proto.rpc.FindRes} returns this
 */
proto.rpc.FindRes.prototype.setDotsinfo = function(value) {
  return jspb.Message.setProto3StringField(this, 1, value);
};


/**
 * repeated string noExistDirs = 2;
 * @return {!Array<string>}
 */
proto.rpc.FindRes.prototype.getNoexistdirsList = function() {
  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 2));
};


/**
 * @param {!Array<string>} value
 * @return {!proto.rpc.FindRes} returns this
 */
proto.rpc.FindRes.prototype.setNoexistdirsList = function(value) {
  return jspb.Message.setField(this, 2, value || []);
};


/**
 * @param {string} value
 * @param {number=} opt_index
 * @return {!proto.rpc.FindRes} returns this
 */
proto.rpc.FindRes.prototype.addNoexistdirs = function(value, opt_index) {
  return jspb.Message.addToRepeatedField(this, 2, value, opt_index);
};


/**
 * Clears the list making it empty but non-null.
 * @return {!proto.rpc.FindRes} returns this
 */
proto.rpc.FindRes.prototype.clearNoexistdirsList = function() {
  return this.setNoexistdirsList([]);
};


/**
 * optional string error = 3;
 * @return {string}
 */
proto.rpc.FindRes.prototype.getError = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
};


/**
 * @param {string} value
 * @return {!proto.rpc.FindRes} returns this
 */
proto.rpc.FindRes.prototype.setError = function(value) {
  return jspb.Message.setProto3StringField(this, 3, value);
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.rpc.ImportReq.prototype.toObject = function(opt_includeInstance) {
  return proto.rpc.ImportReq.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.rpc.ImportReq} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.rpc.ImportReq.toObject = function(includeInstance, msg) {
  var f, obj = {
    filepath: jspb.Message.getFieldWithDefault(msg, 1, "")
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.rpc.ImportReq}
 */
proto.rpc.ImportReq.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.rpc.ImportReq;
  return proto.rpc.ImportReq.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.rpc.ImportReq} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.rpc.ImportReq}
 */
proto.rpc.ImportReq.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = /** @type {string} */ (reader.readString());
      msg.setFilepath(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.rpc.ImportReq.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.rpc.ImportReq.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.rpc.ImportReq} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.rpc.ImportReq.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getFilepath();
  if (f.length > 0) {
    writer.writeString(
      1,
      f
    );
  }
};


/**
 * optional string filepath = 1;
 * @return {string}
 */
proto.rpc.ImportReq.prototype.getFilepath = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
};


/**
 * @param {string} value
 * @return {!proto.rpc.ImportReq} returns this
 */
proto.rpc.ImportReq.prototype.setFilepath = function(value) {
  return jspb.Message.setProto3StringField(this, 1, value);
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.rpc.ImportRes.prototype.toObject = function(opt_includeInstance) {
  return proto.rpc.ImportRes.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.rpc.ImportRes} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.rpc.ImportRes.toObject = function(includeInstance, msg) {
  var f, obj = {
    json: jspb.Message.getFieldWithDefault(msg, 1, ""),
    error: jspb.Message.getFieldWithDefault(msg, 2, "")
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.rpc.ImportRes}
 */
proto.rpc.ImportRes.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.rpc.ImportRes;
  return proto.rpc.ImportRes.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.rpc.ImportRes} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.rpc.ImportRes}
 */
proto.rpc.ImportRes.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = /** @type {string} */ (reader.readString());
      msg.setJson(value);
      break;
    case 2:
      var value = /** @type {string} */ (reader.readString());
      msg.setError(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.rpc.ImportRes.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.rpc.ImportRes.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.rpc.ImportRes} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.rpc.ImportRes.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getJson();
  if (f.length > 0) {
    writer.writeString(
      1,
      f
    );
  }
  f = message.getError();
  if (f.length > 0) {
    writer.writeString(
      2,
      f
    );
  }
};


/**
 * optional string json = 1;
 * @return {string}
 */
proto.rpc.ImportRes.prototype.getJson = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
};


/**
 * @param {string} value
 * @return {!proto.rpc.ImportRes} returns this
 */
proto.rpc.ImportRes.prototype.setJson = function(value) {
  return jspb.Message.setProto3StringField(this, 1, value);
};


/**
 * optional string error = 2;
 * @return {string}
 */
proto.rpc.ImportRes.prototype.getError = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
};


/**
 * @param {string} value
 * @return {!proto.rpc.ImportRes} returns this
 */
proto.rpc.ImportRes.prototype.setError = function(value) {
  return jspb.Message.setProto3StringField(this, 2, value);
};



/**
 * List of repeated fields within this message type.
 * @private {!Array<number>}
 * @const
 */
proto.rpc.ExportReq.repeatedFields_ = [2];



if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.rpc.ExportReq.prototype.toObject = function(opt_includeInstance) {
  return proto.rpc.ExportReq.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.rpc.ExportReq} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.rpc.ExportReq.toObject = function(includeInstance, msg) {
  var f, obj = {
    configdata: jspb.Message.getFieldWithDefault(msg, 1, ""),
    filenameList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f,
    dotdata: jspb.Message.getFieldWithDefault(msg, 3, "")
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.rpc.ExportReq}
 */
proto.rpc.ExportReq.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.rpc.ExportReq;
  return proto.rpc.ExportReq.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.rpc.ExportReq} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.rpc.ExportReq}
 */
proto.rpc.ExportReq.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = /** @type {string} */ (reader.readString());
      msg.setConfigdata(value);
      break;
    case 2:
      var value = /** @type {string} */ (reader.readString());
      msg.addFilename(value);
      break;
    case 3:
      var value = /** @type {string} */ (reader.readString());
      msg.setDotdata(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.rpc.ExportReq.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.rpc.ExportReq.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.rpc.ExportReq} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.rpc.ExportReq.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getConfigdata();
  if (f.length > 0) {
    writer.writeString(
      1,
      f
    );
  }
  f = message.getFilenameList();
  if (f.length > 0) {
    writer.writeRepeatedString(
      2,
      f
    );
  }
  f = message.getDotdata();
  if (f.length > 0) {
    writer.writeString(
      3,
      f
    );
  }
};


/**
 * optional string configdata = 1;
 * @return {string}
 */
proto.rpc.ExportReq.prototype.getConfigdata = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
};


/**
 * @param {string} value
 * @return {!proto.rpc.ExportReq} returns this
 */
proto.rpc.ExportReq.prototype.setConfigdata = function(value) {
  return jspb.Message.setProto3StringField(this, 1, value);
};


/**
 * repeated string filename = 2;
 * @return {!Array<string>}
 */
proto.rpc.ExportReq.prototype.getFilenameList = function() {
  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 2));
};


/**
 * @param {!Array<string>} value
 * @return {!proto.rpc.ExportReq} returns this
 */
proto.rpc.ExportReq.prototype.setFilenameList = function(value) {
  return jspb.Message.setField(this, 2, value || []);
};


/**
 * @param {string} value
 * @param {number=} opt_index
 * @return {!proto.rpc.ExportReq} returns this
 */
proto.rpc.ExportReq.prototype.addFilename = function(value, opt_index) {
  return jspb.Message.addToRepeatedField(this, 2, value, opt_index);
};


/**
 * Clears the list making it empty but non-null.
 * @return {!proto.rpc.ExportReq} returns this
 */
proto.rpc.ExportReq.prototype.clearFilenameList = function() {
  return this.setFilenameList([]);
};


/**
 * optional string dotdata = 3;
 * @return {string}
 */
proto.rpc.ExportReq.prototype.getDotdata = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
};


/**
 * @param {string} value
 * @return {!proto.rpc.ExportReq} returns this
 */
proto.rpc.ExportReq.prototype.setDotdata = function(value) {
  return jspb.Message.setProto3StringField(this, 3, value);
};





if (jspb.Message.GENERATE_TO_OBJECT) {
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.rpc.ExportRes.prototype.toObject = function(opt_includeInstance) {
  return proto.rpc.ExportRes.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.rpc.ExportRes} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.rpc.ExportRes.toObject = function(includeInstance, msg) {
  var f, obj = {
    error: jspb.Message.getFieldWithDefault(msg, 1, "")
  };

  if (includeInstance) {
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.rpc.ExportRes}
 */
proto.rpc.ExportRes.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.rpc.ExportRes;
  return proto.rpc.ExportRes.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.rpc.ExportRes} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.rpc.ExportRes}
 */
proto.rpc.ExportRes.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = /** @type {string} */ (reader.readString());
      msg.setError(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.rpc.ExportRes.prototype.serializeBinary = function() {
  var writer = new jspb.BinaryWriter();
  proto.rpc.ExportRes.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.rpc.ExportRes} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.rpc.ExportRes.serializeBinaryToWriter = function(message, writer) {
  var f = undefined;
  f = message.getError();
  if (f.length > 0) {
    writer.writeString(
      1,
      f
    );
  }
};


/**
 * optional string error = 1;
 * @return {string}
 */
proto.rpc.ExportRes.prototype.getError = function() {
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
};


/**
 * @param {string} value
 * @return {!proto.rpc.ExportRes} returns this
 */
proto.rpc.ExportRes.prototype.setError = function(value) {
  return jspb.Message.setProto3StringField(this, 1, value);
};


goog.object.extend(exports, proto.rpc);


<|start_filename|>sample/grpc/go_out/hidot/hi.pb.go<|end_filename|>
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.23.0
// 	protoc        v3.13.0
// source: hi.proto

package hidot

import (
	context "context"
	proto "github.com/golang/protobuf/proto"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4

type HiReq struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}

func (x *HiReq) Reset() {
	*x = HiReq{}
	if protoimpl.UnsafeEnabled {
		mi := &file_hi_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *HiReq) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*HiReq) ProtoMessage() {}

func (x *HiReq) ProtoReflect() protoreflect.Message {
	mi := &file_hi_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use HiReq.ProtoReflect.Descriptor instead.
func (*HiReq) Descriptor() ([]byte, []int) {
	return file_hi_proto_rawDescGZIP(), []int{0}
}

func (x *HiReq) GetName() string {
	if x != nil {
		return x.Name
	}
	return ""
}

type HiRes struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}

func (x *HiRes) Reset() {
	*x = HiRes{}
	if protoimpl.UnsafeEnabled {
		mi := &file_hi_proto_msgTypes[1]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *HiRes) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*HiRes) ProtoMessage() {}

func (x *HiRes) ProtoReflect() protoreflect.Message {
	mi := &file_hi_proto_msgTypes[1]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use HiRes.ProtoReflect.Descriptor instead.
func (*HiRes) Descriptor() ([]byte, []int) {
	return file_hi_proto_rawDescGZIP(), []int{1}
}

func (x *HiRes) GetName() string {
	if x != nil {
		return x.Name
	}
	return ""
}

type WriteReq struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
}

func (x *WriteReq) Reset() {
	*x = WriteReq{}
	if protoimpl.UnsafeEnabled {
		mi := &file_hi_proto_msgTypes[2]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *WriteReq) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*WriteReq) ProtoMessage() {}

func (x *WriteReq) ProtoReflect() protoreflect.Message {
	mi := &file_hi_proto_msgTypes[2]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use WriteReq.ProtoReflect.Descriptor instead.
func (*WriteReq) Descriptor() ([]byte, []int) {
	return file_hi_proto_rawDescGZIP(), []int{2}
}

func (x *WriteReq) GetData() string {
	if x != nil {
		return x.Data
	}
	return ""
}

type WriteRes struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
}

func (x *WriteRes) Reset() {
	*x = WriteRes{}
	if protoimpl.UnsafeEnabled {
		mi := &file_hi_proto_msgTypes[3]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *WriteRes) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*WriteRes) ProtoMessage() {}

func (x *WriteRes) ProtoReflect() protoreflect.Message {
	mi := &file_hi_proto_msgTypes[3]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use WriteRes.ProtoReflect.Descriptor instead.
func (*WriteRes) Descriptor() ([]byte, []int) {
	return file_hi_proto_rawDescGZIP(), []int{3}
}

func (x *WriteRes) GetData() string {
	if x != nil {
		return x.Data
	}
	return ""
}

type HelloRequest struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Greeting string `protobuf:"bytes,1,opt,name=greeting,proto3" json:"greeting,omitempty"`
}

func (x *HelloRequest) Reset() {
	*x = HelloRequest{}
	if protoimpl.UnsafeEnabled {
		mi := &file_hi_proto_msgTypes[4]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *HelloRequest) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*HelloRequest) ProtoMessage() {}

func (x *HelloRequest) ProtoReflect() protoreflect.Message {
	mi := &file_hi_proto_msgTypes[4]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use HelloRequest.ProtoReflect.Descriptor instead.
func (*HelloRequest) Descriptor() ([]byte, []int) {
	return file_hi_proto_rawDescGZIP(), []int{4}
}

func (x *HelloRequest) GetGreeting() string {
	if x != nil {
		return x.Greeting
	}
	return ""
}

type HelloResponse struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Reply string `protobuf:"bytes,1,opt,name=reply,proto3" json:"reply,omitempty"`
}

func (x *HelloResponse) Reset() {
	*x = HelloResponse{}
	if protoimpl.UnsafeEnabled {
		mi := &file_hi_proto_msgTypes[5]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *HelloResponse) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*HelloResponse) ProtoMessage() {}

func (x *HelloResponse) ProtoReflect() protoreflect.Message {
	mi := &file_hi_proto_msgTypes[5]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use HelloResponse.ProtoReflect.Descriptor instead.
func (*HelloResponse) Descriptor() ([]byte, []int) {
	return file_hi_proto_rawDescGZIP(), []int{5}
}

func (x *HelloResponse) GetReply() string {
	if x != nil {
		return x.Reply
	}
	return ""
}

var File_hi_proto protoreflect.FileDescriptor

var file_hi_proto_rawDesc = []byte{
	0x0a, 0x08, 0x68, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x68, 0x69, 0x64, 0x6f,
	0x74, 0x22, 0x1b, 0x0a, 0x05, 0x48, 0x69, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
	0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x1b,
	0x0a, 0x05, 0x48, 0x69, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x1e, 0x0a, 0x08, 0x57,
	0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18,
	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x1e, 0x0a, 0x08, 0x57,
	0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18,
	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x2a, 0x0a, 0x0c, 0x48,
	0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x67,
	0x72, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67,
	0x72, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x22, 0x25, 0x0a, 0x0d, 0x48, 0x65, 0x6c, 0x6c, 0x6f,
	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x70, 0x6c,
	0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, 0x70, 0x6c, 0x79, 0x32, 0x8a,
	0x02, 0x0a, 0x05, 0x48, 0x69, 0x44, 0x6f, 0x74, 0x12, 0x20, 0x0a, 0x02, 0x48, 0x69, 0x12, 0x0c,
	0x2e, 0x68, 0x69, 0x64, 0x6f, 0x74, 0x2e, 0x48, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x0c, 0x2e, 0x68,
	0x69, 0x64, 0x6f, 0x74, 0x2e, 0x48, 0x69, 0x52, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x05, 0x57, 0x72,
	0x69, 0x74, 0x65, 0x12, 0x0f, 0x2e, 0x68, 0x69, 0x64, 0x6f, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74,
	0x65, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x68, 0x69, 0x64, 0x6f, 0x74, 0x2e, 0x57, 0x72, 0x69,
	0x74, 0x65, 0x52, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53,
	0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x13, 0x2e, 0x68, 0x69, 0x64, 0x6f, 0x74, 0x2e, 0x48, 0x65,
	0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x68, 0x69, 0x64,
	0x6f, 0x74, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
	0x30, 0x01, 0x12, 0x3b, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65,
	0x61, 0x6d, 0x12, 0x13, 0x2e, 0x68, 0x69, 0x64, 0x6f, 0x74, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f,
	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x68, 0x69, 0x64, 0x6f, 0x74, 0x2e,
	0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x12,
	0x3a, 0x0a, 0x09, 0x42, 0x6f, 0x74, 0x68, 0x53, 0x69, 0x64, 0x65, 0x73, 0x12, 0x13, 0x2e, 0x68,
	0x69, 0x64, 0x6f, 0x74, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
	0x74, 0x1a, 0x14, 0x2e, 0x68, 0x69, 0x64, 0x6f, 0x74, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52,
	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x32, 0x5a, 0x30, 0x67,
	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x63, 0x72, 0x79, 0x69, 0x6e,
	0x66, 0x6f, 0x2f, 0x64, 0x6f, 0x74, 0x2f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x67, 0x72,
	0x70, 0x63, 0x2f, 0x67, 0x6f, 0x5f, 0x6f, 0x75, 0x74, 0x2f, 0x68, 0x69, 0x64, 0x6f, 0x74, 0x62,
	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_hi_proto_rawDescOnce sync.Once
	file_hi_proto_rawDescData = file_hi_proto_rawDesc
)

func file_hi_proto_rawDescGZIP() []byte {
	file_hi_proto_rawDescOnce.Do(func() {
		file_hi_proto_rawDescData = protoimpl.X.CompressGZIP(file_hi_proto_rawDescData)
	})
	return file_hi_proto_rawDescData
}

var file_hi_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_hi_proto_goTypes = []interface{}{
	(*HiReq)(nil),         // 0: hidot.HiReq
	(*HiRes)(nil),         // 1: hidot.HiRes
	(*WriteReq)(nil),      // 2: hidot.WriteReq
	(*WriteRes)(nil),      // 3: hidot.WriteRes
	(*HelloRequest)(nil),  // 4: hidot.HelloRequest
	(*HelloResponse)(nil), // 5: hidot.HelloResponse
}
var file_hi_proto_depIdxs = []int32{
	0, // 0: hidot.HiDot.Hi:input_type -> hidot.HiReq
	2, // 1: hidot.HiDot.Write:input_type -> hidot.WriteReq
	4, // 2: hidot.HiDot.ServerStream:input_type -> hidot.HelloRequest
	4, // 3: hidot.HiDot.ClientStream:input_type -> hidot.HelloRequest
	4, // 4: hidot.HiDot.BothSides:input_type -> hidot.HelloRequest
	1, // 5: hidot.HiDot.Hi:output_type -> hidot.HiRes
	3, // 6: hidot.HiDot.Write:output_type -> hidot.WriteRes
	5, // 7: hidot.HiDot.ServerStream:output_type -> hidot.HelloResponse
	5, // 8: hidot.HiDot.ClientStream:output_type -> hidot.HelloResponse
	5, // 9: hidot.HiDot.BothSides:output_type -> hidot.HelloResponse
	5, // [5:10] is the sub-list for method output_type
	0, // [0:5] is the sub-list for method input_type
	0, // [0:0] is the sub-list for extension type_name
	0, // [0:0] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() { file_hi_proto_init() }
func file_hi_proto_init() {
	if File_hi_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_hi_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*HiReq); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_hi_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*HiRes); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_hi_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*WriteReq); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_hi_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*WriteRes); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_hi_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*HelloRequest); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_hi_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*HelloResponse); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_hi_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   6,
			NumExtensions: 0,
			NumServices:   1,
		},
		GoTypes:           file_hi_proto_goTypes,
		DependencyIndexes: file_hi_proto_depIdxs,
		MessageInfos:      file_hi_proto_msgTypes,
	}.Build()
	File_hi_proto = out.File
	file_hi_proto_rawDesc = nil
	file_hi_proto_goTypes = nil
	file_hi_proto_depIdxs = nil
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6

// HiDotClient is the client API for HiDot service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type HiDotClient interface {
	Hi(ctx context.Context, in *HiReq, opts ...grpc.CallOption) (*HiRes, error)
	Write(ctx context.Context, in *WriteReq, opts ...grpc.CallOption) (*WriteRes, error)
	ServerStream(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (HiDot_ServerStreamClient, error)
	ClientStream(ctx context.Context, opts ...grpc.CallOption) (HiDot_ClientStreamClient, error)
	BothSides(ctx context.Context, opts ...grpc.CallOption) (HiDot_BothSidesClient, error)
}

type hiDotClient struct {
	cc grpc.ClientConnInterface
}

func NewHiDotClient(cc grpc.ClientConnInterface) HiDotClient {
	return &hiDotClient{cc}
}

func (c *hiDotClient) Hi(ctx context.Context, in *HiReq, opts ...grpc.CallOption) (*HiRes, error) {
	out := new(HiRes)
	err := c.cc.Invoke(ctx, "/hidot.HiDot/Hi", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *hiDotClient) Write(ctx context.Context, in *WriteReq, opts ...grpc.CallOption) (*WriteRes, error) {
	out := new(WriteRes)
	err := c.cc.Invoke(ctx, "/hidot.HiDot/Write", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *hiDotClient) ServerStream(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (HiDot_ServerStreamClient, error) {
	stream, err := c.cc.NewStream(ctx, &_HiDot_serviceDesc.Streams[0], "/hidot.HiDot/ServerStream", opts...)
	if err != nil {
		return nil, err
	}
	x := &hiDotServerStreamClient{stream}
	if err := x.ClientStream.SendMsg(in); err != nil {
		return nil, err
	}
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	return x, nil
}

type HiDot_ServerStreamClient interface {
	Recv() (*HelloResponse, error)
	grpc.ClientStream
}

type hiDotServerStreamClient struct {
	grpc.ClientStream
}

func (x *hiDotServerStreamClient) Recv() (*HelloResponse, error) {
	m := new(HelloResponse)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

func (c *hiDotClient) ClientStream(ctx context.Context, opts ...grpc.CallOption) (HiDot_ClientStreamClient, error) {
	stream, err := c.cc.NewStream(ctx, &_HiDot_serviceDesc.Streams[1], "/hidot.HiDot/ClientStream", opts...)
	if err != nil {
		return nil, err
	}
	x := &hiDotClientStreamClient{stream}
	return x, nil
}

type HiDot_ClientStreamClient interface {
	Send(*HelloRequest) error
	CloseAndRecv() (*HelloResponse, error)
	grpc.ClientStream
}

type hiDotClientStreamClient struct {
	grpc.ClientStream
}

func (x *hiDotClientStreamClient) Send(m *HelloRequest) error {
	return x.ClientStream.SendMsg(m)
}

func (x *hiDotClientStreamClient) CloseAndRecv() (*HelloResponse, error) {
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	m := new(HelloResponse)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

func (c *hiDotClient) BothSides(ctx context.Context, opts ...grpc.CallOption) (HiDot_BothSidesClient, error) {
	stream, err := c.cc.NewStream(ctx, &_HiDot_serviceDesc.Streams[2], "/hidot.HiDot/BothSides", opts...)
	if err != nil {
		return nil, err
	}
	x := &hiDotBothSidesClient{stream}
	return x, nil
}

type HiDot_BothSidesClient interface {
	Send(*HelloRequest) error
	Recv() (*HelloResponse, error)
	grpc.ClientStream
}

type hiDotBothSidesClient struct {
	grpc.ClientStream
}

func (x *hiDotBothSidesClient) Send(m *HelloRequest) error {
	return x.ClientStream.SendMsg(m)
}

func (x *hiDotBothSidesClient) Recv() (*HelloResponse, error) {
	m := new(HelloResponse)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

// HiDotServer is the server API for HiDot service.
type HiDotServer interface {
	Hi(context.Context, *HiReq) (*HiRes, error)
	Write(context.Context, *WriteReq) (*WriteRes, error)
	ServerStream(*HelloRequest, HiDot_ServerStreamServer) error
	ClientStream(HiDot_ClientStreamServer) error
	BothSides(HiDot_BothSidesServer) error
}

// UnimplementedHiDotServer can be embedded to have forward compatible implementations.
type UnimplementedHiDotServer struct {
}

func (*UnimplementedHiDotServer) Hi(context.Context, *HiReq) (*HiRes, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Hi not implemented")
}
func (*UnimplementedHiDotServer) Write(context.Context, *WriteReq) (*WriteRes, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Write not implemented")
}
func (*UnimplementedHiDotServer) ServerStream(*HelloRequest, HiDot_ServerStreamServer) error {
	return status.Errorf(codes.Unimplemented, "method ServerStream not implemented")
}
func (*UnimplementedHiDotServer) ClientStream(HiDot_ClientStreamServer) error {
	return status.Errorf(codes.Unimplemented, "method ClientStream not implemented")
}
func (*UnimplementedHiDotServer) BothSides(HiDot_BothSidesServer) error {
	return status.Errorf(codes.Unimplemented, "method BothSides not implemented")
}

func RegisterHiDotServer(s *grpc.Server, srv HiDotServer) {
	s.RegisterService(&_HiDot_serviceDesc, srv)
}

func _HiDot_Hi_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(HiReq)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(HiDotServer).Hi(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/hidot.HiDot/Hi",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(HiDotServer).Hi(ctx, req.(*HiReq))
	}
	return interceptor(ctx, in, info, handler)
}

func _HiDot_Write_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(WriteReq)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(HiDotServer).Write(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/hidot.HiDot/Write",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(HiDotServer).Write(ctx, req.(*WriteReq))
	}
	return interceptor(ctx, in, info, handler)
}

func _HiDot_ServerStream_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(HelloRequest)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(HiDotServer).ServerStream(m, &hiDotServerStreamServer{stream})
}

type HiDot_ServerStreamServer interface {
	Send(*HelloResponse) error
	grpc.ServerStream
}

type hiDotServerStreamServer struct {
	grpc.ServerStream
}

func (x *hiDotServerStreamServer) Send(m *HelloResponse) error {
	return x.ServerStream.SendMsg(m)
}

func _HiDot_ClientStream_Handler(srv interface{}, stream grpc.ServerStream) error {
	return srv.(HiDotServer).ClientStream(&hiDotClientStreamServer{stream})
}

type HiDot_ClientStreamServer interface {
	SendAndClose(*HelloResponse) error
	Recv() (*HelloRequest, error)
	grpc.ServerStream
}

type hiDotClientStreamServer struct {
	grpc.ServerStream
}

func (x *hiDotClientStreamServer) SendAndClose(m *HelloResponse) error {
	return x.ServerStream.SendMsg(m)
}

func (x *hiDotClientStreamServer) Recv() (*HelloRequest, error) {
	m := new(HelloRequest)
	if err := x.ServerStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

func _HiDot_BothSides_Handler(srv interface{}, stream grpc.ServerStream) error {
	return srv.(HiDotServer).BothSides(&hiDotBothSidesServer{stream})
}

type HiDot_BothSidesServer interface {
	Send(*HelloResponse) error
	Recv() (*HelloRequest, error)
	grpc.ServerStream
}

type hiDotBothSidesServer struct {
	grpc.ServerStream
}

func (x *hiDotBothSidesServer) Send(m *HelloResponse) error {
	return x.ServerStream.SendMsg(m)
}

func (x *hiDotBothSidesServer) Recv() (*HelloRequest, error) {
	m := new(HelloRequest)
	if err := x.ServerStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

var _HiDot_serviceDesc = grpc.ServiceDesc{
	ServiceName: "hidot.HiDot",
	HandlerType: (*HiDotServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Hi",
			Handler:    _HiDot_Hi_Handler,
		},
		{
			MethodName: "Write",
			Handler:    _HiDot_Write_Handler,
		},
	},
	Streams: []grpc.StreamDesc{
		{
			StreamName:    "ServerStream",
			Handler:       _HiDot_ServerStream_Handler,
			ServerStreams: true,
		},
		{
			StreamName:    "ClientStream",
			Handler:       _HiDot_ClientStream_Handler,
			ClientStreams: true,
		},
		{
			StreamName:    "BothSides",
			Handler:       _HiDot_BothSides_Handler,
			ServerStreams: true,
			ClientStreams: true,
		},
	},
	Metadata: "hi.proto",
}


<|start_filename|>sample/db/tools/dao/gorms/auto_data_dao_test.go<|end_filename|>
package gorms

import (
	"github.com/scryinfo/dot/dots/db/gorms"
	"github.com/scryinfo/dot/sample/db/tools/model"
	"github.com/stretchr/testify/assert"
	"testing"
)

const dsn = "root:123456@tcp(127.0.0.1:3306)/dot_test?charset=utf8mb4&parseTime=True&loc=Local"

func CreateTestConn() *AutoDataDao {
	db := gorms.NewGormsTest(dsn, true, "mysql")
	if db != nil {
		base := gorms.GenerateDaoBaseByDb(db)
		return &AutoDataDao{base}
	}
	return nil
}

func TestCreateTable(t *testing.T) {
	dao := CreateTestConn()
	dao.Wrapper.GetDb().AutoMigrate(&model.AutoData{})
}

func TestAutoDataDao_GetByID(t *testing.T) {
	dao := CreateTestConn()
	m, err := dao.GetByID(1)
	if err != nil {
		return
	}
	assert.Equal(t, m.Age, 12)
}

func TestAutoDataDao_Query(t *testing.T) {
	dao := CreateTestConn()
	ms, err := dao.Query("age <  ? ", 25)
	if err != nil {
		return
	}
	assert.Equal(t, len(ms), 0)
}
func TestAutoDataDao_List(t *testing.T) {
	dao := CreateTestConn()
	ms, err := dao.List()
	if err != nil {
		return
	}
	assert.Equal(t, len(ms), 5)
}
func TestAutoDataDao_Count(t *testing.T) {
	dao := CreateTestConn()
	count, err := dao.Count("age > ? ", int8(24))
	if err != nil {
		return
	}
	assert.Equal(t, count, int64(4))
}
func TestAutoDataDao_QueryPage(t *testing.T) {
	dao := CreateTestConn()
	ms, err := dao.QueryPage(2, 2, "age > ?", 24)
	assert.Equal(t, err, nil)
	assert.Equal(t, len(ms), 2)
}
func TestAutoDataDao_QueryPageWithCount(t *testing.T) {
	dao := CreateTestConn()
	ms, count, err := dao.QueryPageWithCount(2, 2, "age > ?", 24)
	assert.Equal(t, err, nil)
	assert.Equal(t, len(ms), 2)
	assert.Equal(t, count, int64(2))

}
func TestAutoDataDao_QueryOne(t *testing.T) {
	dao := CreateTestConn()
	m, err := dao.QueryOne("age > ? and age <= ? ", 12, 25)
	assert.Equal(t, err, nil)
	assert.Equal(t, m.ID, uint(1))
}

func TestAutoDataDao_Insert(t *testing.T) {
	dao := CreateTestConn()
	m := &model.AutoData{
		Name: "jayce",
		Age:  25,
	}
	assert.Equal(t, dao.Insert(m), nil)
}

func TestAutoDataDao_Inserts(t *testing.T) {
	dao := CreateTestConn()
	ms := make([]*model.AutoData, 0)
	ms = append(ms, &model.AutoData{
		Name: "jayce",
		Age:  20,
	})
	ms = append(ms, &model.AutoData{
		Name: "jayce",
		Age:  21,
	})
	ms = append(ms, &model.AutoData{
		Name: "jayce",
		Age:  22,
	})
	assert.Equal(t, dao.Inserts(ms), nil)
}

func TestAutoDataDao_Upsert(t *testing.T) {
	dao := CreateTestConn()
	m := &model.AutoData{
		Name: "herry",
	}
	//m.ID = 1
	assert.Equal(t, dao.Upsert(m), nil)

}

func TestAutoDataDao_Upserts(t *testing.T) {
	dao := CreateTestConn()
	ms := make([]*model.AutoData, 0)
	ms = append(ms, &model.AutoData{
		Name: "jayce",
		Age:  20,
	})
	ms = append(ms, &model.AutoData{
		Name: "jayce",
		Age:  21,
	})
	ms = append(ms, &model.AutoData{
		Name: "jayce",
		Age:  22,
	})
	ms[0].ID = 1
	ms[1].ID = 11
	assert.Equal(t, dao.Upserts(ms), nil)

}

func TestAutoDataDao_Update(t *testing.T) {
	dao := CreateTestConn()
	m := &model.AutoData{
		Name: "Herry",
	}
	m.ID = 1
	assert.Equal(t, dao.Update(m), nil)

}

func TestAutoDataDao_Save(t *testing.T) {
	dao := CreateTestConn()
	m := &model.AutoData{
		Name: "Herry",
	}
	m.ID = 1
	assert.Equal(t, dao.Save(m), nil)
	assert.Equal(t, m.Age, int8(0))

}

func TestAutoDataDao_UpdateColumn(t *testing.T) {
	dao := CreateTestConn()
	m := &model.AutoData{}
	m.ID = 1
	assert.Equal(t, dao.UpdateColumn(m, "age", 12), nil)
}

func TestAutoDataDao_DeleteById(t *testing.T) {
	dao := CreateTestConn()
	assert.Equal(t, dao.DeleteById(1), nil)
}

func TestAutoDataDao_DeleteByIds(t *testing.T) {
	dao := CreateTestConn()
	assert.Equal(t, dao.DeleteByIds([]uint{2, 3}), nil)

}

func TestAutoDataDao_Delete(t *testing.T) {
	dao := CreateTestConn()
	assert.Equal(t, dao.Delete("age < ?", 25), nil)
}

func TestAutoDataDao_DeleteByIdUnscoped(t *testing.T) {
	dao := CreateTestConn()
	assert.Equal(t, dao.DeleteByIdUnscoped(1), nil)
}


<|start_filename|>sample/gindot/gindot.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package main

import (
	"go.uber.org/zap"
	"net/http"
	"os"
	"reflect"

	"github.com/gin-gonic/gin"
	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/line"
	"github.com/scryinfo/scryg/sutils/ssignal"

	"github.com/scryinfo/dot/dots/gindot"
)

func main() {
	//l, err := line.BuildAndStart(add) //first step create line and dots
	l, err := line.BuildAndStartBy(&dot.Builder{
		AfterCreate: func(l dot.Line) {
			dot.Logger().Infoln("AfterCreate")
		},
		Add: add,
	})
	if err != nil {
		dot.Logger().Errorln("", zap.Error(err))
		return
	}
	defer line.StopAndDestroy(l, true) //fourth step stop and destroy dots
	dot.Logger().Infoln("dot ok")
	//third step
	//....

	ssignal.WaitCtrlC(func(s os.Signal) bool { //third wait for exit
		return false
	})
	dot.Logger().Infoln("dot will stop")
}

func add(l dot.Line) error {
	err := l.PreAdd(gindot.RouterTypeLives()...)
	//ReSetLiveEvents AddLiveEvents , they are different
	l.ToDotEventer().ReSetLiveEvents(dot.LiveID("6be39d0b-3f5b-47b4-818c-642c049f3166"), &dot.LiveEvents{AfterStart: func(live *dot.Live, l dot.Line) {
		//do any init for the router
		// router.Router().Use()
		// ....
	}})

	//add the SampleCtroller
	err = l.PreAdd(gindot.PreAddControlDot(reflect.TypeOf((*SampleCtroller)(nil)).Elem(), dot.LiveID("6be39d0b-3f5b-47b4-818c-642c049f3166")))

	l.ToDotEventer().AddLiveEvents(dot.LiveID(gindot.EngineLiveID), &dot.LiveEvents{
		AfterCreate: func(live *dot.Live, l dot.Line) {
			if g, ok := live.Dot.(*gindot.Engine); ok {
				//d.GinEngine().St
				_ = g
				dot.Logger().Infoln("sdf")
			}
			dot.Logger().Infoln("BeforeStop")

		},

		BeforeStop: func(live *dot.Live, l dot.Line) {
			dot.Logger().Infoln("BeforeStop")
		},

		BeforeStart: func(live *dot.Live, l dot.Line) {
			dot.Logger().Infoln("BeforeStart")
		},
	})

	return err
}

type SampleCtroller struct {
	GinRouter_ *gindot.Router `dot:"6be39d0b-3f5b-47b4-818c-642c049f3166"`
}

func (c *SampleCtroller) Start(ignore bool) error {

	//post := reflect.ValueOf(c.GinRouter_.Router()).MethodByName("POST")
	//gindot.RouterSelf(c,"sample", func(url string, gmethod reflect.Value) {
	//	vs := []reflect.Value{reflect.ValueOf(url), gmethod}
	//	post.Call(vs)
	//})
	c.GinRouter_.RouterGet(c, "sample")
	c.GinRouter_.Router().GET("/rpctest/*rpc", func(ctx *gin.Context) {
		ctx.String(http.StatusOK, "ok")
	})
	return nil
}

func (c *SampleCtroller) Hello(cxt *gin.Context) {
	cxt.JSON(http.StatusOK, "ok")
}


<|start_filename|>lib/must_do/must_do.go<|end_filename|>
// <NAME>.  All rights reserved.
// license that can be found in the license file.

package must_do

import (
	"github.com/scryinfo/dot/dot"
	"time"
)

/*
	必须完成某个动作
	按组进行尝试，组与组之间有间隔时间
	每组固定次数与间隔时间
*/
/*
	第一版初步完成
*/
type MustDoConfig struct {
	LargeInterval time.Duration //每组间隔执行时间
	SmallInterval time.Duration //每次尝试的间隔时间
	CycleIndex    int           //每组循环次数
}

type MustDo struct {
	Thing func() bool
	Conf  *MustDoConfig
}

func (c *MustDo) Start() {

	for true {
		for i := 0; i < c.Conf.CycleIndex; i++ {
			if c.Thing() {
				//todo 日志怎么知道具体做了什么事情
				dot.Logger().Infoln("try successful")
				return
			}
			dot.Logger().Warnln("try fail")
			time.Sleep(c.Conf.SmallInterval)
		}
		time.Sleep(c.Conf.LargeInterval)
	}
}


<|start_filename|>sample/certificate/certificate.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package main

import (
	"go.uber.org/zap"
	"os"

	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/certificate"
	"github.com/scryinfo/dot/dots/line"
	"github.com/scryinfo/scryg/sutils/ssignal"
)

func main() {
	l, err := line.BuildAndStart(add) //first step create line and dots
	if err != nil {
		dot.Logger().Errorln("", zap.Error(err))
		return
	}
	defer line.StopAndDestroy(l, true) //fourth step stop and destroy dots

	dot.Logger().Infoln("dot ok")
	//second step ....

	dd, _ := l.ToInjecter().GetByLiveID(dot.LiveID(certificate.EcdsaTypeID))
	if d, ok := dd.(*certificate.Ecdsa); ok {
		err := makeSample(d)
		if err != nil {
			dot.Logger().Errorln(err.Error())
		}
	}
	ssignal.WaitCtrlC(func(s os.Signal) bool { //third wait for exit
		return false
	})
}

func add(l dot.Line) error {
	err := l.PreAdd(certificate.EcdsaTypeLives()...)
	return err
}

//Generate ca certificate, generate serve and client certificate under ca certificate
func makeSample(cs *certificate.Ecdsa) error {

	caPri, err := certificate.MakePriKey()
	if err != nil {
		return err
	}

	ca, err := cs.GenerateCaCertKey(caPri, "ca.key", "ca.pem", []string{"scry"}, []string{"scry"})
	if err != nil {
		return err
	}

	err = cs.GenerateCertKey(ca, caPri, "server.key", "server.pem", []string{"scry"}, []string{"scry"})
	if err != nil {
		return err
	}

	err = cs.GenerateCertKey(ca, caPri, "client.key", "client.pem", []string{"scry"}, []string{"scry"})
	if err != nil {
		return err
	}

	return nil

}


<|start_filename|>dots/line/line_data.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package line

import (
	"github.com/scryinfo/dot/dot"
)

//Metas metas of dot
type Metas struct {
	metas map[dot.TypeID]*dot.Metadata
}

//NewMetas new metas
func NewMetas() *Metas {
	m := &Metas{}
	m.metas = make(map[dot.TypeID]*dot.Metadata)
	return m
}

//Lives lives of dot
type Lives struct {
	// typeIDMap map[dot.TypeID][]*dot.Live
	LiveIDMap map[dot.LiveID]*dot.Live
}

//NewLives new lives
func NewLives() *Lives {
	l := &Lives{}
	l.LiveIDMap = make(map[dot.LiveID]*dot.Live)
	return l
}

//Add add meta data to metas
func (ms *Metas) Add(m *dot.Metadata) error {
	if m == nil || m.TypeID.String() == "" {
		return dot.SError.NilParameter
	}

	if _, ok := ms.metas[m.TypeID]; ok {
		return dot.SError.Existed.AddNewError(m.TypeID.String())
	}

	ms.metas[m.TypeID] = m.Clone()

	return nil
}

//UpdateOrAdd if the meta exist then update, or add it
func (ms *Metas) UpdateOrAdd(m *dot.Metadata) error {
	if m == nil || m.TypeID.String() == "" {
		return dot.SError.NilParameter
	}

	old, ok := ms.metas[m.TypeID]
	if ok {
		old.Merge(m)
	} else {
		ms.metas[m.TypeID] = m.Clone()
	}
	return nil
}

//RemoveByID remove meta data from metas
func (ms *Metas) RemoveByID(typeID dot.TypeID) error {
	delete(ms.metas, typeID)
	return nil
}

//Get get meta by type id
func (ms *Metas) Get(typeID dot.TypeID) (meta *dot.Metadata, err error) {
	meta = nil
	err = nil

	meta, ok := ms.metas[typeID]
	if !ok {
		err = dot.SError.NotExisted.AddNewError(typeID.String())
	}
	return
}

//NewDot new dot
func (ms *Metas) NewDot(t dot.TypeID) (dot dot.Dot, err error) {
	dot = nil
	err = nil

	m, err := ms.Get(t)
	if err == nil {
		dot, err = m.NewDot(nil)
	}
	return
}

//Add add live
func (ms *Lives) Add(m *dot.Live) error {
	if m == nil || m.LiveID.String() == "" {
		return dot.SError.NilParameter
	}

	_, ok := ms.LiveIDMap[m.LiveID]
	if ok {
		return dot.SError.Existed.AddNewError(m.LiveID.String())
	}
	ms.LiveIDMap[m.LiveID] = m

	return nil
}

//UpdateOrAdd if the live exist then update, or add it
func (ms *Lives) UpdateOrAdd(m *dot.Live) error {
	if m == nil || m.LiveID.String() == "" {
		return dot.SError.NilParameter
	}

	old, ok := ms.LiveIDMap[m.LiveID]
	if ok {
		old.Dot = m.Dot
		old.TypeID = m.TypeID
		if len(m.RelyLives) > 0 { //merge the rely lives
			if old.RelyLives == nil {
				old.RelyLives = make(map[string]dot.LiveID, len(m.RelyLives))
			}
			for k, v := range m.RelyLives {
				old.RelyLives[k] = v
			}
		}
	} else {
		ms.LiveIDMap[m.LiveID] = m
	}

	return nil
}

//RemoveByID remove the dot by live id
func (ms *Lives) RemoveByID(id dot.LiveID) error {
	delete(ms.LiveIDMap, id)
	return nil
}

//Get get dot by live id
func (ms *Lives) Get(liveID dot.LiveID) (meta *dot.Live, err error) {
	var ok bool
	meta, ok = ms.LiveIDMap[liveID]
	if !ok {
		err = dot.SError.NotExisted.AddNewError(liveID.String())
	}
	return
}


<|start_filename|>dots/db/tools/gdao/gdao.go<|end_filename|>
package main

import (
	"bytes"
	"flag"
	"fmt"
	"github.com/scryinfo/dot/dots/db/pgs"
	"github.com/scryinfo/scryg/sutils/sfile"
	"github.com/scryinfo/scryg/sutils/uuid"
	"go/ast"
	"go/format"
	"go/parser"
	"go/token"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
	"text/template"
)

//DbField do not use the map, we need the order
type DbField struct {
	Name   string
	DbName string
}

type tData struct {
	DaoName            string
	TypeName           string
	TableName          string
	ModelPkgName       string
	ImportModelPkgName string
	DaoPkgName         string
	BackQuote          string
	ID                 string
	//Fields       []DbField
	//StringFields []DbField
}

var params struct {
	typeName   string
	tableName  string
	daoPackage string
	suffix     string
	useLock    bool
	useGorm    bool
}

func parms(data *tData) {
	flag.StringVar(&params.typeName, "typeName", "", "")
	flag.StringVar(&params.tableName, "tableName", "", "")
	flag.StringVar(&params.daoPackage, "daoPackage", "", "")
	flag.StringVar(&params.suffix, "suffix", "Dao", "")
	flag.BoolVar(&params.useGorm, "useGorm", false, "")
	flag.Parse()

	if len(params.tableName) < 1 {
		params.tableName = pgs.Underscore(params.typeName)
	}

	data.TypeName = params.typeName
	data.TableName = params.tableName
	data.DaoPkgName = params.daoPackage
	if len(data.DaoPkgName) < 1 {
		data.DaoPkgName = "dao"
	}
	if len(params.suffix) > 0 {
		data.DaoName = data.TypeName + params.suffix
	} else {
		data.DaoName = data.TypeName
	}
	data.ID = uuid.GetUuid()
}

func main() {
	log.Println("run gdao")
	data := &tData{}
	data.BackQuote = "`"
	parms(data)
	if len(params.typeName) < 1 {
		log.Fatal("type name is null")
	}

	if len(params.tableName) < 1 {
		log.Fatal("table name is null")
	}

	var src []byte = nil
	{
		makeData(data)
		src = gmodel(data, params.useGorm)
	}

	outputName := ""
	{
		types := pgs.Underscore(data.DaoName)
		baseName := fmt.Sprintf("%s.go", types)
		outputName = filepath.Join("../", data.DaoPkgName, strings.ToLower(baseName))
		if sfile.ExistFile(outputName) {
			outputName = filepath.Join(".", strings.ToLower(baseName))
		}
	}

	if _, err := os.Stat(outputName); os.IsNotExist(err) {
		err := ioutil.WriteFile(outputName, src, 0644)
		if err != nil {
			log.Fatalf("writing output: %s", err)
		}
	} else {
		log.Println("exist the file: " + outputName)
	}

	log.Println("finished gdao")
}

func makeData(data *tData) {
	data.ModelPkgName = os.Getenv("GOPACKAGE")
	file := os.Getenv("GOFILE")
	{
		f, err := parser.ParseFile(token.NewFileSet(), file, nil, 0)
		if err != nil {
			log.Fatal(err)
		}
		{
			dir, err := filepath.Abs(file)
			if err != nil {
				log.Fatal(err)
			}
			dir = filepath.Dir(dir)
			dir = strings.Replace(dir, "\\", "/", -1)
			index := strings.Index(dir, "github.com/scryinfo")
			if index >= 0 {
				data.ImportModelPkgName = dir[index:]
			} else {
				log.Println("not find the model")
			}
		}
		find := false
		ast.Inspect(f, func(n ast.Node) bool {
			if n != nil {
				decl, ok := n.(*ast.GenDecl)
				// just STRUCT
				if !ok || decl.Tok != token.TYPE {
					return true
				}
				for _, spec := range decl.Specs {
					typeS, ok := spec.(*ast.TypeSpec)
					if ok && typeS.Name.Name == data.TypeName {
						find = true
						return false
					}
				}
			}
			return true
		})

		if !find {
			log.Fatal("not find: " + data.TypeName)
		}
	}
	//data.Fields = fields
}

func gmodel(data *tData, supportGorm bool) []byte {

	temp := ""
	if supportGorm {
		temp = `
package dao

import (
	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/db/gorms"
	"github.com/scryinfo/dot/dots/db/pgs"
	"{{$.ImportModelPkgName}}"
	"gorm.io/gorm/clause"
)

const {{$.DaoName}}TypeID = "{{$.ID}}"

type {{$.DaoName}} struct {
	*gorms.DaoBase {{$.BackQuote}}dot:""{{$.BackQuote}}
}

//{{$.DaoName}}TypeLives
func {{$.DaoName}}TypeLives() []*dot.TypeLives {
	tl := &dot.TypeLives{
		Meta: dot.Metadata{TypeID: {{$.DaoName}}TypeID, NewDoter: func(conf []byte) (dot.Dot, error) {
			return &{{$.DaoName}}{}, nil
		}},
		Lives: []dot.Live{
			{
				LiveID: {{$.DaoName}}TypeID,
				RelyLives: map[string]dot.LiveID{
					"DaoBase": pgs.DaoBaseTypeID,
				},
			},
		},
	}

	lives := gorms.DaoBaseTypeLives()
	lives = append(lives, tl)

	return lives
}

func (c *{{$.DaoName}}) GetByID(id uint) (m *{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	result := c.Wrapper.GetDb().First(&m, id)
	if result.RowsAffected == 1 {
		return m, nil
	}
	return nil, result.Error
}

func (c *{{$.DaoName}}) Query(condition string, params ...interface{}) (ms []*{{$.ModelPkgName}}.{{$.TypeName}}, err error) {

	db := c.Wrapper.GetDb()
	if len(condition) < 1 {
		db = db.Find(&ms)
	} else {
		db = db.Where(condition, params...).Find(&ms)
	}
	err = db.Error
	if err != nil {
		ms = nil
	}
	return
}

func (c *{{$.DaoName}}) List() (ms []*{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	db := c.Wrapper.GetDb().Find(&ms)
	if db.Error != nil {
		ms = nil
	}
	return ms, db.Error
}

func (c *{{$.DaoName}}) Count(condition string, params ...interface{}) (count int64, err error) {

	var ms []*{{$.ModelPkgName}}.{{$.TypeName}}
	db := c.Wrapper.GetDb()
	if len(condition) < 1 {
		db = db.Find(&ms)
	} else {
		db = db.Where(condition, params...).Find(&ms)
	}
	err = db.Error
	if err != nil {
		count = 0
	}
	count=db.RowsAffected
	return
}

func (c *{{$.DaoName}}) QueryPage(pageSize int, page int, condition string, params ...interface{}) (ms []*{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	db := c.Wrapper.GetDb()
	if len(condition) < 1 {
		db = db.Limit(pageSize).Offset((page - 1) * pageSize).Find(&ms)
	} else {
		db = db.Limit(pageSize).Offset((page-1)*pageSize).Where(condition, params...).Find(&ms)
	}
	if db.Error != nil { //be sure
		ms = nil
	}
	return ms, db.Error
}

func (c *{{$.DaoName}}) QueryPageWithCount(pageSize int, page int, condition string, params ...interface{}) (ms []*{{$.ModelPkgName}}.{{$.TypeName}}, count int64, err error) {
	db := c.Wrapper.GetDb()
	if len(condition) < 1 {
		db = db.Limit(pageSize).Offset((page - 1) * pageSize).Find(&ms)
	} else {
		db = db.Limit(pageSize).Offset((page-1)*pageSize).Where(condition, params...).Find(&ms)
	}
	if db.Error != nil { //be sure
		ms = nil
	}
	return ms, db.RowsAffected, db.Error
}

func (c *{{$.DaoName}}) QueryOne(condition string, params ...interface{}) (m *{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	db := c.Wrapper.GetDb()
	if len(condition) < 1 {
		db = db.First(&m)
	} else {
		db = db.Where(condition, params...).First(&m)
	}
	err = db.Error
	if err != nil {
		m = nil
	}
	return
}

//insert = insertReturn
func (c *{{$.DaoName}}) Insert(m *{{$.ModelPkgName}}.{{$.TypeName}}) (err error) {
	//because id auto increment
	//m.ID = 0
	err = c.Wrapper.GetDb().Create(&m).Error
	return
}

func (c *{{$.DaoName}}) Inserts(ms []*{{$.ModelPkgName}}.{{$.TypeName}}) (err error) {
	//because id auto increment
	//m.ID = 0
	err = c.Wrapper.GetDb().Create(&ms).Error
	return
}

//update everything except ID
func (c *{{$.DaoName}}) Upsert(m *{{$.ModelPkgName}}.{{$.TypeName}}) (err error) {
	//because id auto increment
	//m.ID = 0
	err = c.Wrapper.GetDb().Clauses(clause.OnConflict{
		UpdateAll: true,
	}).Create(&m).Error
	return
}

func (c *{{$.DaoName}}) Upserts(ms []*{{$.ModelPkgName}}.{{$.TypeName}}) (err error) {
	//because id auto increment
	//m.ID = 0
	err = c.Wrapper.GetDb().Clauses(clause.OnConflict{
		UpdateAll: true,
	}).Create(&ms).Error
	return
}

//Updates 方法支持 struct 和 map[string]interface{} 参数
//当使用 struct 更新时，默认情况下，GORM 只会更新非零值的字段
func (c *{{$.DaoName}}) Update(m *{{$.ModelPkgName}}.{{$.TypeName}}) (err error) {
	err = c.Wrapper.GetDb().Updates(&m).Error
	return
}

//Save 会保存所有的字段，即使字段是零值
//todo CreateTime=0
func (c *{{$.DaoName}}) Save(m *{{$.ModelPkgName}}.{{$.TypeName}}) (err error) {
	err = c.Wrapper.GetDb().Save(&m).Error
	return
}

//default where id=m.ID
func (c *{{$.DaoName}}) UpdateColumn(m *{{$.ModelPkgName}}.{{$.TypeName}}, columnName string, value interface{}) (err error) {
	err = c.Wrapper.GetDb().Model(&m).Update(columnName, value).Error
	return
}
//soft delete
func (c *{{$.DaoName}}) DeleteById(id uint) error {
	return c.Wrapper.GetDb().Delete(&{{$.ModelPkgName}}.{{$.TypeName}}{}, id).Error
}
//soft delete
func (c *{{$.DaoName}}) DeleteByIds(ids []uint) error {
	return c.Wrapper.GetDb().Delete(&{{$.ModelPkgName}}.{{$.TypeName}}{}, ids).Error
}
//soft delete
func (c *{{$.DaoName}}) Delete(condition string, params ...interface{}) error {
	return c.Wrapper.GetDb().Where(condition, params...).Delete(&{{$.ModelPkgName}}.{{$.TypeName}}{}).Error
}

//Delete permanently
func (c *{{$.DaoName}}) DeleteByIdUnscoped(id uint) error {
	return c.Wrapper.GetDb().Unscoped().Delete(&{{$.ModelPkgName}}.{{$.TypeName}}{}, id).Error
}

`
	} else {
		temp = `
package {{$.DaoPkgName}}
import (
	"time"
	
	"github.com/go-pg/pg/v10"
	"github.com/go-pg/pg/v10/orm"
	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/db/pgs"
	"github.com/scryinfo/scryg/sutils/uuid"
	"{{$.ImportModelPkgName}}"
)

const {{$.DaoName}}TypeID = "{{$.ID}}"

type {{$.DaoName}} struct {
	*pgs.DaoBase {{$.BackQuote}}dot:""{{$.BackQuote}}
}

//{{$.DaoName}}TypeLives
func {{$.DaoName}}TypeLives() []*dot.TypeLives {
	tl := &dot.TypeLives{
		Meta: dot.Metadata{
			Name: "{{$.DaoName}}",
			TypeID: {{$.DaoName}}TypeID, 
			NewDoter: func(conf []byte) (dot.Dot, error) {
				return &{{$.DaoName}}{}, nil
			},
		},
		Lives: []dot.Live{
			{
				LiveID: {{$.DaoName}}TypeID,
				RelyLives: map[string]dot.LiveID{
					"DaoBase": pgs.DaoBaseTypeID,
				},
			},
		},
	}

	lives := pgs.DaoBaseTypeLives()
	lives = append(lives, tl)
	return lives
}

// if find nothing, return pg.ErrNoRows
func (c *{{$.DaoName}}) GetByIDWithLock(conn orm.DB, id string) (m *{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	m = &{{$.ModelPkgName}}.{{$.TypeName}}{}
	m.ID = id
	err = conn.Model(m).WherePK().For("UPDATE").Select()
	if err != nil {
		m = nil
	}
	return
}
func (c *{{$.DaoName}}) GetByID(conn orm.DB, id string) (m *{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	m = &{{$.ModelPkgName}}.{{$.TypeName}}{}
	m.ID = id
	err = conn.Model(m).WherePK().Select()
	if err != nil {
		m = nil
	}
	return
}

//update before
//you must get OptimisticLockVersion value
func (c *{{$.DaoName}}) GetLockByID(conn orm.DB, ids ...string) (ms []*{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	for i,_ := range ids {
		m := &{{$.ModelPkgName}}.{{$.TypeName}}{}
		m.ID = ids[i]
		ms=append(ms,m)
	}
	err=conn.Model(&ms).WherePK().Column({{$.ModelPkgName}}.{{$.TypeName}}_OptimisticLockVersion,{{$.ModelPkgName}}.{{$.TypeName}}_Struct+"."+{{$.ModelPkgName}}.{{$.TypeName}}_ID).For("UPDATE").Select()
	if err != nil {
		ms=nil
	}
	return
}
func (c *{{$.DaoName}}) GetLockByModelID(conn orm.DB, ms ...*{{$.ModelPkgName}}.{{$.TypeName}}) error {
	return conn.Model(&ms).WherePK().Column({{$.ModelPkgName}}.{{$.TypeName}}_OptimisticLockVersion,{{$.ModelPkgName}}.{{$.TypeName}}_Struct+"."+{{$.ModelPkgName}}.{{$.TypeName}}_ID).For("UPDATE").Select()
}

// if find nothing, return pg.ErrNoRows
func (c *{{$.DaoName}}) QueryWithLock(conn orm.DB, condition string, params ...interface{}) (ms []*{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	if len(condition) < 1 {
		err = conn.Model(&ms).For("UPDATE").Select()
	} else {
		err = conn.Model(&ms).Where(condition, params...).For("UPDATE").Select()
	}
	if err != nil { //be sure
		ms = nil
	}
	return
}
func (c *{{$.DaoName}}) Query(conn orm.DB, condition string, params ...interface{}) (ms []*{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	if len(condition) < 1 {
		err = conn.Model(&ms).Select()
	} else {
		err = conn.Model(&ms).Where(condition, params...).Select()
	}
	if err != nil { //be sure
		ms = nil
	}
	return
}


// if find nothing, return pg.ErrNoRows
func (c *{{$.DaoName}}) ListWithLock(conn orm.DB) (ms []*{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	err = conn.Model(&ms).For("UPDATE").Select()
	if err != nil {//be sure
		ms = nil
	}
	return
}
func (c *{{$.DaoName}}) List(conn orm.DB) (ms []*{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	err = conn.Model(&ms).Select()
	if err != nil {//be sure
		ms = nil
	}
	return
}

func (c *{{$.DaoName}}) Count(conn orm.DB, condition string, params ...interface{}) (count int, err error) {
	if len(condition) < 1 {
		count, err = conn.Model(&{{$.ModelPkgName}}.{{$.TypeName}}{}).Count()
	}else {
		count, err = conn.Model(&{{$.ModelPkgName}}.{{$.TypeName}}{}).Where(condition, params...).Count()
	}
	return
}

// if find nothing, return pg.ErrNoRows
func (c *{{$.DaoName}}) QueryPageWithLock(conn orm.DB, pageSize int, page int, condition string, params ...interface{}) (ms []*{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	if len(condition) < 1 {
		err = conn.Model(&ms).Limit(pageSize).Offset((page - 1) * pageSize).For("UPDATE").Select()
	}else {
		err = conn.Model(&ms).Where(condition, params...).Limit(pageSize).Offset((page - 1) * pageSize).For("UPDATE").Select()
	}
	if err != nil { //be sure
		ms = nil
	}
	return
}
func (c *{{$.DaoName}}) QueryPage(conn orm.DB, pageSize int, page int, condition string, params ...interface{}) (ms []*{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	if len(condition) < 1 {
		err = conn.Model(&ms).Limit(pageSize).Offset((page - 1) * pageSize).Select()
	}else {
		err = conn.Model(&ms).Where(condition, params...).Limit(pageSize).Offset((page - 1) * pageSize).Select()
	}
	if err != nil { //be sure
		ms = nil
	}
	return
}

// count counts valid records which after conditions filter, rather than whole table's count
func (c *{{$.DaoName}}) QueryPageWithCount(
	conn orm.DB,
	pageSize,
	pageNum int,
	condition string,
	params ...interface{},
) (ms []*{{$.ModelPkgName}}.{{$.TypeName}}, count int, err error) {
	if len(condition) < 1 {
		count, err = conn.Model(&ms).Limit(pageSize).Offset((pageNum - 1) * pageSize).SelectAndCount()
	} else {
		count, err = conn.Model(&ms).Where(condition, params...).Limit(pageSize).Offset((pageNum - 1) * pageSize).SelectAndCount()
	}

	if err != nil { //be sure
		ms = nil
	}
	return
}

// if find nothing, return pg.ErrNoRows
func (c *{{$.DaoName}}) QueryOneWithLock(conn orm.DB, condition string, params ...interface{}) (m *{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	m = &{{$.ModelPkgName}}.{{$.TypeName}}{}
	if len(condition) < 1 {
		err = conn.Model(m).For("UPDATE").First()
	} else {
		err = conn.Model(m).Where(condition, params...).For("UPDATE").First()
	}
	if err != nil {//be sure
		m = nil
	}
	return
}
func (c *{{$.DaoName}}) QueryOne(conn orm.DB, condition string, params ...interface{}) (m *{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	m = &{{$.ModelPkgName}}.{{$.TypeName}}{}
	if len(condition) < 1 {
		err = conn.Model(m).First()
	} else {
		err = conn.Model(m).Where(condition, params...).First()
	}
	if err != nil {//be sure
		m = nil
	}
	return
}

//if insert nothing, then return pg.ErrNoRows
func (c *{{$.DaoName}}) Insert(conn orm.DB, m *{{$.ModelPkgName}}.{{$.TypeName}}) (err error) {
	if len(m.ID) < 1 {
		m.ID = uuid.GetUuid()
	}
	m.CreateTime = time.Now().Unix()
	m.UpdateTime = m.CreateTime
	_, err = conn.Model(m).Insert()
	return
}
//if insert nothing, then return pg.ErrNoRows
func (c *{{$.DaoName}}) InsertReturn(conn orm.DB, m *{{$.ModelPkgName}}.{{$.TypeName}}) ( mnew *{{$.ModelPkgName}}.{{$.TypeName}}, err error) {
	if len(m.ID) < 1 {
		m.ID = uuid.GetUuid()
	}
	m.CreateTime = time.Now().Unix()
	m.UpdateTime = m.CreateTime

	mnew = &{{$.ModelPkgName}}.{{$.TypeName}}{}
	_, err = conn.Model(m).Returning("*").Insert(mnew)
	if err != nil{
		mnew = nil
	}
	return
}


//if update nothing, then return pg.ErrNoRows
func (c *{{$.DaoName}}) Upsert(conn orm.DB, m *{{$.ModelPkgName}}.{{$.TypeName}}) (err error) {
    m.UpdateTime = time.Now().Unix()
	if len(m.ID) < 1 {
		m.ID = uuid.GetUuid()
		m.CreateTime = m.UpdateTime
	} else if m.CreateTime == 0 {
		m.CreateTime = m.UpdateTime
	}
	m.OptimisticLockVersion++
	om := conn.Model(m).OnConflict("(id) DO UPDATE").Where({{$.ModelPkgName}}.{{$.TypeName}}_Struct+"."+{{$.ModelPkgName}}.{{$.TypeName}}_OptimisticLockVersion+" = ?",m.OptimisticLockVersion-1)
	for _, it := range m.ToUpsertSet() {
		om.Set(it)
	}
	res, err := om.Insert()
	if res.RowsAffected() == 0 {
		//err = pg.ErrNoRows
		newm ,err:=c.GetLockByID(conn,m.ID)
		if err != nil {
			return err
		}
		m.OptimisticLockVersion =newm[0].OptimisticLockVersion
		err =c.Update(conn,m)
		return err
	}
	return err
}

//if update nothing, then return pg.ErrNoRows
func (c *{{$.DaoName}}) UpsertReturn(conn orm.DB, m *{{$.ModelPkgName}}.{{$.TypeName}}) ( mnew *{{$.ModelPkgName}}.{{$.TypeName}},err error) {
	m.UpdateTime = time.Now().Unix()
	if len(m.ID) < 1 {
		m.ID = uuid.GetUuid()
		m.CreateTime = m.UpdateTime
	} else if m.CreateTime == 0 {
		m.CreateTime = m.UpdateTime
	}
	m.OptimisticLockVersion++
	om := conn.Model(m).OnConflict("(id) DO UPDATE").Where({{$.ModelPkgName}}.{{$.TypeName}}_Struct+"."+{{$.ModelPkgName}}.{{$.TypeName}}_OptimisticLockVersion+" = ?",m.OptimisticLockVersion-1)
	for _, it := range m.ToUpsertSet() {
		om.Set(it)
	}
	mnew = &{{$.ModelPkgName}}.{{$.TypeName}}{}
	_, err = om.Returning("*").Insert(mnew)
	if err ==pg.ErrNoRows {
		new_m ,err:=c.GetLockByID(conn,m.ID)
		if err != nil {
			return nil,err
		}
		m.OptimisticLockVersion =new_m[0].OptimisticLockVersion
		mnew,err =c.UpdateReturn(conn,m)
		return mnew,err
	}
	return
}
//if update nothing, then return pg.ErrNoRows
func (c *{{$.DaoName}}) Update(conn orm.DB, m *{{$.ModelPkgName}}.{{$.TypeName}}) (err error) {
	m.UpdateTime = time.Now().Unix()
	m.OptimisticLockVersion++
	//err = conn.Update(m)
	res, err := conn.Model(m).Where({{$.ModelPkgName}}.{{$.TypeName}}_ID+" = ? and "+{{$.ModelPkgName}}.{{$.TypeName}}_OptimisticLockVersion+" = ?", m.ID, m.OptimisticLockVersion-1).Update()
	if res.RowsAffected() == 0 {
		err = pg.ErrNoRows
	}
	return
}

//if update nothing, then return pg.ErrNoRows
func (c *{{$.DaoName}}) UpdateReturn(conn orm.DB, m *{{$.ModelPkgName}}.{{$.TypeName}}) (mnew *{{$.ModelPkgName}}.{{$.TypeName}},  err error) {
	m.UpdateTime = time.Now().Unix()
	m.OptimisticLockVersion++
	mnew = &{{$.ModelPkgName}}.{{$.TypeName}}{}
	res, err := conn.Model(m).Where({{$.ModelPkgName}}.{{$.TypeName}}_ID+" = ? and "+{{$.ModelPkgName}}.{{$.TypeName}}_OptimisticLockVersion+" = ?", m.ID, m.OptimisticLockVersion-1).Returning("*").Update(mnew)
	if err != nil {
		mnew = nil
	}
	if res.RowsAffected() == 0 {
		err = pg.ErrNoRows
	}
	return
}

//if delete nothing, then return pg.ErrNoRows
func (c *{{$.DaoName}}) Delete(conn orm.DB, m *{{$.ModelPkgName}}.{{$.TypeName}}) (err error) {
	_, err = conn.Model(m).Delete()
	return
}

//if delete nothing, then return pg.ErrNoRows
func (c *{{$.DaoName}}) DeleteByID(conn orm.DB, id string) (err error) {
	_, err = conn.Model((*{{$.ModelPkgName}}.{{$.TypeName}})(nil)).Where({{$.ModelPkgName}}.{{$.TypeName}}_ID+" = ?", id).Delete()
	return
}

//if delete nothing, then return pg.ErrNoRows
func (c *{{$.DaoName}}) DeleteByIDs(conn orm.DB, ids []string, oneMax int) (err error) {
	m := (*{{$.ModelPkgName}}.{{$.TypeName}})(nil)
	max := oneMax
	times := len(ids)/max;
	for i := 1; i < times; i++ {
		oneIDs := ids[(i-1) * max:i * max -1]
		_, err = conn.Model(m).Where({{$.ModelPkgName}}.{{$.TypeName}}_ID+" in (?)", pg.In(oneIDs)).Delete()
		if err != nil {
			return
		}
	}

	if max * times < len(ids) {
		oneIDs := ids[max * times:]
		_, err = conn.Model(m).Where({{$.ModelPkgName}}.{{$.TypeName}}_ID+" in (?)", pg.In(oneIDs)).Delete()
	}
	return 
}

//if delete nothing, then return pg.ErrNoRows
func (c *{{$.DaoName}}) DeleteReturn(conn orm.DB, m *{{$.ModelPkgName}}.{{$.TypeName}}) (mnew *{{$.ModelPkgName}}.{{$.TypeName}},err error) {
	mnew = &{{$.ModelPkgName}}.{{$.TypeName}}{}
	_, err = conn.Model(m).WherePK().Returning("*").Delete(mnew)
	if err != nil {
		mnew = nil
	}
	return
}

//example,please edit it
//update designated column with Optimistic Lock
func (c *{{$.DaoName}}) Update{{$.TypeName}}SomeColumn(conn orm.DB, ids []string,/*todo: update parameters*/) (err error) {

	ms, err := c.GetLockByID(conn, ids...)
	if err != nil {
		return
	}

	for i, _ := range ms {
		ms[i].UpdateTime = time.Now().Unix()
		ms[i].OptimisticLockVersion++
		//todo ms[i].xx=parameter
		_, err = conn.Model(ms[i]).Where({{$.ModelPkgName}}.{{$.TypeName}}_ID+" = ? and "+{{$.ModelPkgName}}.{{$.TypeName}}_OptimisticLockVersion+" = ?", ms[i].ID, ms[i].OptimisticLockVersion-1).Column(/*{{$.ModelPkgName}}.{{$.TypeName}}_xx,*/ {{$.ModelPkgName}}.{{$.TypeName}}_OptimisticLockVersion, {{$.ModelPkgName}}.{{$.TypeName}}_UpdateTime).Update()
		if err != nil {
			dot.Logger().Debugln(err.Error())
			return
		}
	}
	return
}
`
	}

	var src []byte = nil
	{
		t, err := template.New("").Parse(temp)
		if err != nil {
			log.Fatal(err)
		}
		buff := bytes.NewBufferString("")
		err = t.Execute(buff, data)
		if err != nil {
			log.Fatal(err)
		}

		src, err = format.Source(buff.Bytes())
		if err != nil {
			log.Fatal(err)
		}
	}
	return src
}


<|start_filename|>tools/dotconf/ui/src/rpc_face/config_grpc_web_pb.js<|end_filename|>
/**
 * @fileoverview gRPC-Web generated client stub for rpc
 * @enhanceable
 * @public
 */

// GENERATED CODE -- DO NOT EDIT!


/* eslint-disable */
// @ts-nocheck



const grpc = {};
grpc.web = require('grpc-web');

const proto = {};
proto.rpc = require('./config_pb.js');

/**
 * @param {string} hostname
 * @param {?Object} credentials
 * @param {?Object} options
 * @constructor
 * @struct
 * @final
 */
proto.rpc.DotConfigFaceClient =
    function(hostname, credentials, options) {
  if (!options) options = {};
  options['format'] = 'text';

  /**
   * @private @const {!grpc.web.GrpcWebClientBase} The client
   */
  this.client_ = new grpc.web.GrpcWebClientBase(options);

  /**
   * @private @const {string} The hostname
   */
  this.hostname_ = hostname;

};


/**
 * @param {string} hostname
 * @param {?Object} credentials
 * @param {?Object} options
 * @constructor
 * @struct
 * @final
 */
proto.rpc.DotConfigFacePromiseClient =
    function(hostname, credentials, options) {
  if (!options) options = {};
  options['format'] = 'text';

  /**
   * @private @const {!grpc.web.GrpcWebClientBase} The client
   */
  this.client_ = new grpc.web.GrpcWebClientBase(options);

  /**
   * @private @const {string} The hostname
   */
  this.hostname_ = hostname;

};


/**
 * @const
 * @type {!grpc.web.MethodDescriptor<
 *   !proto.rpc.FindReq,
 *   !proto.rpc.FindRes>}
 */
const methodDescriptor_DotConfigFace_FindDot = new grpc.web.MethodDescriptor(
  '/rpc.DotConfigFace/FindDot',
  grpc.web.MethodType.UNARY,
  proto.rpc.FindReq,
  proto.rpc.FindRes,
  /**
   * @param {!proto.rpc.FindReq} request
   * @return {!Uint8Array}
   */
  function(request) {
    return request.serializeBinary();
  },
  proto.rpc.FindRes.deserializeBinary
);


/**
 * @const
 * @type {!grpc.web.AbstractClientBase.MethodInfo<
 *   !proto.rpc.FindReq,
 *   !proto.rpc.FindRes>}
 */
const methodInfo_DotConfigFace_FindDot = new grpc.web.AbstractClientBase.MethodInfo(
  proto.rpc.FindRes,
  /**
   * @param {!proto.rpc.FindReq} request
   * @return {!Uint8Array}
   */
  function(request) {
    return request.serializeBinary();
  },
  proto.rpc.FindRes.deserializeBinary
);


/**
 * @param {!proto.rpc.FindReq} request The
 *     request proto
 * @param {?Object<string, string>} metadata User defined
 *     call metadata
 * @param {function(?grpc.web.Error, ?proto.rpc.FindRes)}
 *     callback The callback function(error, response)
 * @return {!grpc.web.ClientReadableStream<!proto.rpc.FindRes>|undefined}
 *     The XHR Node Readable Stream
 */
proto.rpc.DotConfigFaceClient.prototype.findDot =
    function(request, metadata, callback) {
  return this.client_.rpcCall(this.hostname_ +
      '/rpc.DotConfigFace/FindDot',
      request,
      metadata || {},
      methodDescriptor_DotConfigFace_FindDot,
      callback);
};


/**
 * @param {!proto.rpc.FindReq} request The
 *     request proto
 * @param {?Object<string, string>} metadata User defined
 *     call metadata
 * @return {!Promise<!proto.rpc.FindRes>}
 *     A native promise that resolves to the response
 */
proto.rpc.DotConfigFacePromiseClient.prototype.findDot =
    function(request, metadata) {
  return this.client_.unaryCall(this.hostname_ +
      '/rpc.DotConfigFace/FindDot',
      request,
      metadata || {},
      methodDescriptor_DotConfigFace_FindDot);
};


/**
 * @const
 * @type {!grpc.web.MethodDescriptor<
 *   !proto.rpc.ImportReq,
 *   !proto.rpc.ImportRes>}
 */
const methodDescriptor_DotConfigFace_ImportByConfig = new grpc.web.MethodDescriptor(
  '/rpc.DotConfigFace/ImportByConfig',
  grpc.web.MethodType.UNARY,
  proto.rpc.ImportReq,
  proto.rpc.ImportRes,
  /**
   * @param {!proto.rpc.ImportReq} request
   * @return {!Uint8Array}
   */
  function(request) {
    return request.serializeBinary();
  },
  proto.rpc.ImportRes.deserializeBinary
);


/**
 * @const
 * @type {!grpc.web.AbstractClientBase.MethodInfo<
 *   !proto.rpc.ImportReq,
 *   !proto.rpc.ImportRes>}
 */
const methodInfo_DotConfigFace_ImportByConfig = new grpc.web.AbstractClientBase.MethodInfo(
  proto.rpc.ImportRes,
  /**
   * @param {!proto.rpc.ImportReq} request
   * @return {!Uint8Array}
   */
  function(request) {
    return request.serializeBinary();
  },
  proto.rpc.ImportRes.deserializeBinary
);


/**
 * @param {!proto.rpc.ImportReq} request The
 *     request proto
 * @param {?Object<string, string>} metadata User defined
 *     call metadata
 * @param {function(?grpc.web.Error, ?proto.rpc.ImportRes)}
 *     callback The callback function(error, response)
 * @return {!grpc.web.ClientReadableStream<!proto.rpc.ImportRes>|undefined}
 *     The XHR Node Readable Stream
 */
proto.rpc.DotConfigFaceClient.prototype.importByConfig =
    function(request, metadata, callback) {
  return this.client_.rpcCall(this.hostname_ +
      '/rpc.DotConfigFace/ImportByConfig',
      request,
      metadata || {},
      methodDescriptor_DotConfigFace_ImportByConfig,
      callback);
};


/**
 * @param {!proto.rpc.ImportReq} request The
 *     request proto
 * @param {?Object<string, string>} metadata User defined
 *     call metadata
 * @return {!Promise<!proto.rpc.ImportRes>}
 *     A native promise that resolves to the response
 */
proto.rpc.DotConfigFacePromiseClient.prototype.importByConfig =
    function(request, metadata) {
  return this.client_.unaryCall(this.hostname_ +
      '/rpc.DotConfigFace/ImportByConfig',
      request,
      metadata || {},
      methodDescriptor_DotConfigFace_ImportByConfig);
};


/**
 * @const
 * @type {!grpc.web.MethodDescriptor<
 *   !proto.rpc.ImportReq,
 *   !proto.rpc.ImportRes>}
 */
const methodDescriptor_DotConfigFace_ImportByDot = new grpc.web.MethodDescriptor(
  '/rpc.DotConfigFace/ImportByDot',
  grpc.web.MethodType.UNARY,
  proto.rpc.ImportReq,
  proto.rpc.ImportRes,
  /**
   * @param {!proto.rpc.ImportReq} request
   * @return {!Uint8Array}
   */
  function(request) {
    return request.serializeBinary();
  },
  proto.rpc.ImportRes.deserializeBinary
);


/**
 * @const
 * @type {!grpc.web.AbstractClientBase.MethodInfo<
 *   !proto.rpc.ImportReq,
 *   !proto.rpc.ImportRes>}
 */
const methodInfo_DotConfigFace_ImportByDot = new grpc.web.AbstractClientBase.MethodInfo(
  proto.rpc.ImportRes,
  /**
   * @param {!proto.rpc.ImportReq} request
   * @return {!Uint8Array}
   */
  function(request) {
    return request.serializeBinary();
  },
  proto.rpc.ImportRes.deserializeBinary
);


/**
 * @param {!proto.rpc.ImportReq} request The
 *     request proto
 * @param {?Object<string, string>} metadata User defined
 *     call metadata
 * @param {function(?grpc.web.Error, ?proto.rpc.ImportRes)}
 *     callback The callback function(error, response)
 * @return {!grpc.web.ClientReadableStream<!proto.rpc.ImportRes>|undefined}
 *     The XHR Node Readable Stream
 */
proto.rpc.DotConfigFaceClient.prototype.importByDot =
    function(request, metadata, callback) {
  return this.client_.rpcCall(this.hostname_ +
      '/rpc.DotConfigFace/ImportByDot',
      request,
      metadata || {},
      methodDescriptor_DotConfigFace_ImportByDot,
      callback);
};


/**
 * @param {!proto.rpc.ImportReq} request The
 *     request proto
 * @param {?Object<string, string>} metadata User defined
 *     call metadata
 * @return {!Promise<!proto.rpc.ImportRes>}
 *     A native promise that resolves to the response
 */
proto.rpc.DotConfigFacePromiseClient.prototype.importByDot =
    function(request, metadata) {
  return this.client_.unaryCall(this.hostname_ +
      '/rpc.DotConfigFace/ImportByDot',
      request,
      metadata || {},
      methodDescriptor_DotConfigFace_ImportByDot);
};


/**
 * @const
 * @type {!grpc.web.MethodDescriptor<
 *   !proto.rpc.ImportReq,
 *   !proto.rpc.ImportRes>}
 */
const methodDescriptor_DotConfigFace_InitImport = new grpc.web.MethodDescriptor(
  '/rpc.DotConfigFace/InitImport',
  grpc.web.MethodType.UNARY,
  proto.rpc.ImportReq,
  proto.rpc.ImportRes,
  /**
   * @param {!proto.rpc.ImportReq} request
   * @return {!Uint8Array}
   */
  function(request) {
    return request.serializeBinary();
  },
  proto.rpc.ImportRes.deserializeBinary
);


/**
 * @const
 * @type {!grpc.web.AbstractClientBase.MethodInfo<
 *   !proto.rpc.ImportReq,
 *   !proto.rpc.ImportRes>}
 */
const methodInfo_DotConfigFace_InitImport = new grpc.web.AbstractClientBase.MethodInfo(
  proto.rpc.ImportRes,
  /**
   * @param {!proto.rpc.ImportReq} request
   * @return {!Uint8Array}
   */
  function(request) {
    return request.serializeBinary();
  },
  proto.rpc.ImportRes.deserializeBinary
);


/**
 * @param {!proto.rpc.ImportReq} request The
 *     request proto
 * @param {?Object<string, string>} metadata User defined
 *     call metadata
 * @param {function(?grpc.web.Error, ?proto.rpc.ImportRes)}
 *     callback The callback function(error, response)
 * @return {!grpc.web.ClientReadableStream<!proto.rpc.ImportRes>|undefined}
 *     The XHR Node Readable Stream
 */
proto.rpc.DotConfigFaceClient.prototype.initImport =
    function(request, metadata, callback) {
  return this.client_.rpcCall(this.hostname_ +
      '/rpc.DotConfigFace/InitImport',
      request,
      metadata || {},
      methodDescriptor_DotConfigFace_InitImport,
      callback);
};


/**
 * @param {!proto.rpc.ImportReq} request The
 *     request proto
 * @param {?Object<string, string>} metadata User defined
 *     call metadata
 * @return {!Promise<!proto.rpc.ImportRes>}
 *     A native promise that resolves to the response
 */
proto.rpc.DotConfigFacePromiseClient.prototype.initImport =
    function(request, metadata) {
  return this.client_.unaryCall(this.hostname_ +
      '/rpc.DotConfigFace/InitImport',
      request,
      metadata || {},
      methodDescriptor_DotConfigFace_InitImport);
};


/**
 * @const
 * @type {!grpc.web.MethodDescriptor<
 *   !proto.rpc.ExportReq,
 *   !proto.rpc.ExportRes>}
 */
const methodDescriptor_DotConfigFace_ExportConfig = new grpc.web.MethodDescriptor(
  '/rpc.DotConfigFace/ExportConfig',
  grpc.web.MethodType.UNARY,
  proto.rpc.ExportReq,
  proto.rpc.ExportRes,
  /**
   * @param {!proto.rpc.ExportReq} request
   * @return {!Uint8Array}
   */
  function(request) {
    return request.serializeBinary();
  },
  proto.rpc.ExportRes.deserializeBinary
);


/**
 * @const
 * @type {!grpc.web.AbstractClientBase.MethodInfo<
 *   !proto.rpc.ExportReq,
 *   !proto.rpc.ExportRes>}
 */
const methodInfo_DotConfigFace_ExportConfig = new grpc.web.AbstractClientBase.MethodInfo(
  proto.rpc.ExportRes,
  /**
   * @param {!proto.rpc.ExportReq} request
   * @return {!Uint8Array}
   */
  function(request) {
    return request.serializeBinary();
  },
  proto.rpc.ExportRes.deserializeBinary
);


/**
 * @param {!proto.rpc.ExportReq} request The
 *     request proto
 * @param {?Object<string, string>} metadata User defined
 *     call metadata
 * @param {function(?grpc.web.Error, ?proto.rpc.ExportRes)}
 *     callback The callback function(error, response)
 * @return {!grpc.web.ClientReadableStream<!proto.rpc.ExportRes>|undefined}
 *     The XHR Node Readable Stream
 */
proto.rpc.DotConfigFaceClient.prototype.exportConfig =
    function(request, metadata, callback) {
  return this.client_.rpcCall(this.hostname_ +
      '/rpc.DotConfigFace/ExportConfig',
      request,
      metadata || {},
      methodDescriptor_DotConfigFace_ExportConfig,
      callback);
};


/**
 * @param {!proto.rpc.ExportReq} request The
 *     request proto
 * @param {?Object<string, string>} metadata User defined
 *     call metadata
 * @return {!Promise<!proto.rpc.ExportRes>}
 *     A native promise that resolves to the response
 */
proto.rpc.DotConfigFacePromiseClient.prototype.exportConfig =
    function(request, metadata) {
  return this.client_.unaryCall(this.hostname_ +
      '/rpc.DotConfigFace/ExportConfig',
      request,
      metadata || {},
      methodDescriptor_DotConfigFace_ExportConfig);
};


/**
 * @const
 * @type {!grpc.web.MethodDescriptor<
 *   !proto.rpc.ExportReq,
 *   !proto.rpc.ExportRes>}
 */
const methodDescriptor_DotConfigFace_ExportDot = new grpc.web.MethodDescriptor(
  '/rpc.DotConfigFace/ExportDot',
  grpc.web.MethodType.UNARY,
  proto.rpc.ExportReq,
  proto.rpc.ExportRes,
  /**
   * @param {!proto.rpc.ExportReq} request
   * @return {!Uint8Array}
   */
  function(request) {
    return request.serializeBinary();
  },
  proto.rpc.ExportRes.deserializeBinary
);


/**
 * @const
 * @type {!grpc.web.AbstractClientBase.MethodInfo<
 *   !proto.rpc.ExportReq,
 *   !proto.rpc.ExportRes>}
 */
const methodInfo_DotConfigFace_ExportDot = new grpc.web.AbstractClientBase.MethodInfo(
  proto.rpc.ExportRes,
  /**
   * @param {!proto.rpc.ExportReq} request
   * @return {!Uint8Array}
   */
  function(request) {
    return request.serializeBinary();
  },
  proto.rpc.ExportRes.deserializeBinary
);


/**
 * @param {!proto.rpc.ExportReq} request The
 *     request proto
 * @param {?Object<string, string>} metadata User defined
 *     call metadata
 * @param {function(?grpc.web.Error, ?proto.rpc.ExportRes)}
 *     callback The callback function(error, response)
 * @return {!grpc.web.ClientReadableStream<!proto.rpc.ExportRes>|undefined}
 *     The XHR Node Readable Stream
 */
proto.rpc.DotConfigFaceClient.prototype.exportDot =
    function(request, metadata, callback) {
  return this.client_.rpcCall(this.hostname_ +
      '/rpc.DotConfigFace/ExportDot',
      request,
      metadata || {},
      methodDescriptor_DotConfigFace_ExportDot,
      callback);
};


/**
 * @param {!proto.rpc.ExportReq} request The
 *     request proto
 * @param {?Object<string, string>} metadata User defined
 *     call metadata
 * @return {!Promise<!proto.rpc.ExportRes>}
 *     A native promise that resolves to the response
 */
proto.rpc.DotConfigFacePromiseClient.prototype.exportDot =
    function(request, metadata) {
  return this.client_.unaryCall(this.hostname_ +
      '/rpc.DotConfigFace/ExportDot',
      request,
      metadata || {},
      methodDescriptor_DotConfigFace_ExportDot);
};


module.exports = proto.rpc;



<|start_filename|>tools/dotconf/data/rpc/build.bat<|end_filename|>
@echo on

set batPath=%~dp0
cd %batPath%
%~d0
cd ..
set out=%cd%
cd %batPath%
protoc --go_out=plugins=grpc:../rpc --go_opt=paths=source_relative config.proto

protoc --js_out=import_style=commonjs:../../ui/src/rpc_face/ --grpc-web_out=import_style=commonjs+dts,mode=grpcwebtext:../../ui/src/rpc_face/ config.proto


go build

cd %batPath%

<|start_filename|>sample/sample.go<|end_filename|>
// Scry Info.  All rights reserved.
// license that can be found in the license file.

package main

import (
	"encoding/json"
	"os"
	"reflect"

	"github.com/scryinfo/dot/dot"
	"github.com/scryinfo/dot/dots/line"
	"github.com/scryinfo/scryg/sutils/ssignal"
)

func main() {
	l, err := line.BuildAndStart(add) //first step create line and dots
	if err != nil {
		dot.Logger().Errorln(err.Error())
		return
	}
	defer line.StopAndDestroy(l, true) //fourth step stop and destroy dots

	dot.Logger().Infoln("dot ok")
	t := &SomeUse{}

	l.InfoAllTypeAdnLives()
	_ = l.ToInjecter().Inject(t)                    //second step use the injecter or others
	_ = dot.GetDefaultLine().ToInjecter().Inject(t) //or second step, use the default line(in the sample, the default line  == l)

	ssignal.WaitCtrlC(func(s os.Signal) bool { //third wait for exit
		return false
	})

}

//how to new the dots of config
func add(l dot.Line) error {
	var err error
	{
		t := reflect.TypeOf((*Dot1)(nil))
		t = t.Elem()
		err = l.PreAdd(&dot.TypeLives{
			Meta: dot.Metadata{TypeID: "1", RefType: t}, Lives: []dot.Live{
				{LiveID: "1"},
			},
		})

		// Point newer for typeid
		err = l.PreAdd(&dot.TypeLives{
			Meta: dot.Metadata{TypeID: "1", NewDoter: func(conf []byte) (dot dot.Dot, err error) {
				return &Dot1{Name: "Create by type 1"}, nil
			}},
		})
	}

	{
		t := reflect.TypeOf((*Dot2)(nil))
		t = t.Elem()
		//If no newer assignment, then use reflect.newLine to create it
		err = l.PreAdd(&dot.TypeLives{
			Meta: dot.Metadata{TypeID: "2", RefType: t}, Lives: []dot.Live{
				{LiveID: "21"}, {LiveID: "22"},
			},
		})
	}

	{ // The following is Newer using LiveID，
		err = l.AddNewerByLiveID(dot.LiveID("31"), func(conf []byte) (d dot.Dot, err error) {
			d = &Dot3{}
			err = nil
			t := reflect.ValueOf(conf)
			if t.Kind() == reflect.Slice || t.Kind() == reflect.Array {
				if t.Len() > 0 && t.Index(0).Kind() == reflect.Uint8 {
					v := t.Slice(0, t.Len())
					err = json.Unmarshal(v.Bytes(), d)
				}
			} else {
				err = dot.SError.Parameter
			}

			return
		})

		err = l.AddNewerByLiveID(dot.LiveID("32"), func(conf []byte) (d dot.Dot, err error) {
			d = &Dot3{}
			err = nil
			t := reflect.ValueOf(conf)
			if t.Kind() == reflect.Slice || t.Kind() == reflect.Array {
				if t.Len() > 0 && t.Index(0).Kind() == reflect.Uint8 {
					v := t.Slice(0, t.Len())
					err = json.Unmarshal(v.Bytes(), d)
				}
			} else {
				err = dot.SError.Parameter
			}

			return
		})
	}

	{ // The following is Newer using typeid and LiveID，if both are provided, then use Liveid priorly
		err = l.AddNewerByLiveID(dot.LiveID("41"), func(conf []byte) (d dot.Dot, err error) {
			d = &Dot4{}
			err = nil
			t := reflect.ValueOf(conf)
			if t.Kind() == reflect.Slice || t.Kind() == reflect.Array {
				if t.Len() > 0 && t.Index(0).Kind() == reflect.Uint8 {
					v := t.Slice(0, t.Len())
					err = json.Unmarshal(v.Bytes(), d)
				}
			} else {
				err = dot.SError.Parameter
			}

			return
		})

		err = l.AddNewerByTypeID(dot.TypeID("type_live"), func(conf []byte) (d dot.Dot, err error) {
			d = &Dot4{}
			err = nil
			t := reflect.ValueOf(conf)
			if t.Kind() == reflect.Slice || t.Kind() == reflect.Array {
				if t.Len() > 0 && t.Index(0).Kind() == reflect.Uint8 {
					v := t.Slice(0, t.Len())
					err = json.Unmarshal(v.Bytes(), d)
				}
			} else {
				err = dot.SError.Parameter
			}
			return
		})
	}
	return err
}

//Add assigned type to container directly
func addDot(l dot.Line) {
	_ = l.ToInjecter().ReplaceOrAddByType(&Dot1{Name: "null"})
	_ = l.ToInjecter().ReplaceOrAddByLiveID(&Dot1{Name: "6666"}, dot.LiveID("6666"))
}

type Dot1 struct {
	Name string
}

type SomeUse struct {
	DotLive  *Dot1 `dot:""`
	DotLive2 *Dot1 `dot:"1"`

	DotLive3 *Dot2 `dot:"21"`
	DotLive4 *Dot2 `dot:"22"`

	DotLive5 *Dot3 `dot:"31"`
	DotLive6 *Dot3 `dot:"32"`

	DotLive10 *Dot4 `dot:"41"`
	DotLive11 *Dot4 `dot:"42"`

	Logger dot.SLogger `dot:""`
}

type Dot2 struct {
	T string
}

type Dot3 struct {
	T string
}

type Dot4 struct {
	T string
}

//Create use this method to initialize, run or monitor same content, better realize it in start method
func (c *Dot3) Create(l dot.Line) error {
	return nil
}

//Start
//ignore When calliing other Lifer, if true erred then continue, if false erred return directly
func (c *Dot3) Start(ignore bool) error {
	return nil
}

//Stop
//ignore When calliing other Lifer, if true erred then continue, if false erred return directly
func (c *Dot3) Stop(ignore bool) error {
	return nil
}

//Destroy Destroy Dot
//ignore When calliing other Lifer, if true erred then continue, if false erred return directly
func (c *Dot3) Destroy(ignore bool) error {
	return nil
}


<|start_filename|>dots/grpc/gserver/etcd_register_test.go<|end_filename|>
package gserver
//
//import (
//	"context"
//	"encoding/json"
//	"github.com/golang/mock/gomock"
//	"github.com/scryinfo/dot/dots/grpc/conns"
//	"github.com/scryinfo/dot/dots/line"
//	"github.com/stretchr/testify/assert"
//	"runtime"
//	"testing"
//	"time"
//)
//
//var controller *gomock.Controller
//
//// generate the mock
//// cd to folder gserver, run "mockgen -source ./server_nobl.go -destination ./server_nobl_mock.go -package gserver"
//
//func TestEtcdConns_EtcdRegister(t *testing.T) {
//	//first run the etcd 3.4.9 on default port 2379 , (2380 is for peer)
//
//	const (
//		addr = "127.0.0.1:100"
//		name = "test"
//	)
//	var (
//		etcdConns = conns.NewEtcd([]string{"127.0.0.1:2379"}, []string{name})
//		l, err    = line.BuildAndStart(nil)
//		//ctx := context.Background()
//	)
//	{
//		runtime.GOMAXPROCS(4)
//		assert.Equal(t, nil, err)
//		l.ToInjecter().ReplaceOrAddByLiveID(etcdConns, conns.EtcdConnsTypeID)
//		l.ToInjecter().ReplaceOrAddByType(etcdConns)
//		{
//			controller := gomock.NewController(t)
//			s := NewMockServerNobl(controller)
//			s.EXPECT().ServerItem().Return(ServerItem{
//				Name:  name,
//				Addrs: []string{addr},
//			})
//
//			l.ToInjecter().ReplaceOrAddByLiveID(s, GinNoblTypeID)
//		}
//
//		etcdRegister := NewEctcRegisterTest(nil)
//		l.ToInjecter().Inject(etcdRegister)
//		l.ToInjecter().ReplaceOrAddByLiveID(etcdRegister, EtcdRegisterTypeID)
//		etcdRegister.AfterAllInject(l)
//		etcdRegister.AfterAllStart()
//		time.Sleep(2 * time.Second)
//	}
//
//	{
//		re, err := etcdConns.EtcdClient().Get(context.TODO(), name+"/"+addr)
//		assert.Equal(t, nil, err)
//		assert.Equal(t, true, len(re.Kvs) > 0)
//		v := &naming.Update{}
//		err = json.Unmarshal(re.Kvs[0].Value, v)
//		assert.Equal(t, nil, err)
//		assert.Equal(t, addr, v.Addr)
//		cl := etcdConns.ClientConn(name)
//		assert.NotEqual(t, nil, cl)
//	}
//
//	{
//		err := etcdConns.UnRegisterServer(context.TODO(), name, addr)
//		assert.Equal(t, nil, err)
//
//		etcdConns.RegisterServer(context.TODO(), name, addr)
//		re, err := etcdConns.EtcdClient().Get(context.TODO(), name+"/"+addr)
//		assert.Equal(t, nil, err)
//		assert.Equal(t, true, len(re.Kvs) > 0)
//		v := &naming.Update{}
//		err = json.Unmarshal(re.Kvs[0].Value, v)
//		assert.Equal(t, nil, err)
//		assert.Equal(t, addr, v.Addr)
//	}
//
//	line.StopAndDestroy(l, true)
//	if controller != nil {
//		controller.Finish()
//		controller = nil
//	}
//
//}
