From a778e225af7f4b70858c8608bff59d7cfb326710 Mon Sep 17 00:00:00 2001 From: ia Date: Tue, 16 Jan 2018 23:21:41 +0900 Subject: [PATCH 01/45] feat: create WIP prototype for tx/address indexing - api: debug_getAddressTransactions(<0xaddress>, , , ) - cli cmd: 'geth atxi-build [--start=number] [--stop=number]' - cli flag: 'geth [--atxi|--add-tx-index] The api returns an array of 0x-prefixed transactions hashes. Creates a new database /indexes which holds key indexes of the form txa-<8-byte block number uint64> Lookups by address use a prefix iterator on address, eg. txa-... Known issues currently: - Case not handled: delete/reorg blocks. If there is a chain reorg, and a once-canonical block is relegated to side chain, we should remove associated atxi's, which is to say the atx index should only reflect the known canonical chain. - ethdb.Database interface doesn't include iterator, so storage testing with MemDatabase will require changes to Database interface or some other kind of stub - Build the indexes performance might be improved significantly by using a memory cache with Batch writes. --- cmd/geth/build_atxi_cmd.go | 76 +++++++++++++++++++++++++ cmd/geth/flag.go | 43 +++++++++----- cmd/geth/flags.go | 4 ++ cmd/geth/main.go | 26 +++++++++ core/blockchain.go | 44 +++++++++++++++ core/database_util.go | 109 ++++++++++++++++++++++++++++++++++++ core/database_util_test.go | 51 +++++++++++++++++ eth/api.go | 21 +++++++ eth/backend.go | 25 ++++++++- ethdb/database.go | 9 +++ internal/web3ext/web3ext.go | 5 ++ 11 files changed, 397 insertions(+), 16 deletions(-) create mode 100644 cmd/geth/build_atxi_cmd.go diff --git a/cmd/geth/build_atxi_cmd.go b/cmd/geth/build_atxi_cmd.go new file mode 100644 index 000000000..f371340c8 --- /dev/null +++ b/cmd/geth/build_atxi_cmd.go @@ -0,0 +1,76 @@ +package main + +import ( + "gopkg.in/urfave/cli.v1" + "strconv" + "github.com/ethereumproject/go-ethereum/logger/glog" + "github.com/ethereumproject/go-ethereum/core/types" + "github.com/ethereumproject/go-ethereum/core" + "github.com/cheggaaa/pb" + "os" + "path/filepath" + "io/ioutil" +) + +func buildAddrTxIndexCmd(ctx *cli.Context) error { + startIndex := uint64(ctx.Int("start")) + var stopIndex uint64 + + // Use persistent placeholder in case start not spec'd + placeholderFilename := filepath.Join(MustMakeChainDataDir(ctx), "index.at") + if !ctx.IsSet("start") { + bs, err := ioutil.ReadFile(placeholderFilename) + if err == nil { // ignore errors for now + startIndex, _ = strconv.ParseUint(string(bs), 10, 64) + } + } + + bc, chainDB := MakeChain(ctx) + if bc == nil || chainDB == nil { + panic("bc or cdb is nil") + } + defer chainDB.Close() + + stopIndex = uint64(ctx.Int("stop")) + if stopIndex == 0 { + stopIndex = bc.CurrentHeader().Number.Uint64() + } + + if stopIndex < startIndex { + glog.Fatal("start must be prior to (smaller than) or equal to stop, got start=", startIndex, "stop=", stopIndex) + } + + indexDb := MakeIndexDatabase(ctx) + if indexDb == nil { + panic("indexdb is nil") + } + defer indexDb.Close() + + var block *types.Block + blockIndex := startIndex + block = bc.GetBlockByNumber(blockIndex) + if block == nil { + glog.Fatal(blockIndex, "block is nil") + } + + bar := pb.StartNew(int(stopIndex)) // progress bar + for block != nil && block.NumberU64() <= stopIndex { + + if err := core.WriteBlockAddTxIndexes(indexDb, block); err != nil { + return err + } + + bar.Set(int(block.NumberU64())) + blockIndex++ + + // Placeholder every 1000 blocks is plenty. + if blockIndex % 1000 == 0 { + ioutil.WriteFile(placeholderFilename, []byte(strconv.Itoa(int(blockIndex))), os.ModePerm) + } + block = bc.GetBlockByNumber(blockIndex) + } + bar.Finish() + return nil +} + + diff --git a/cmd/geth/flag.go b/cmd/geth/flag.go index 84e2d8ca9..cc282c829 100644 --- a/cmd/geth/flag.go +++ b/cmd/geth/flag.go @@ -599,16 +599,17 @@ func mustMakeEthConf(ctx *cli.Context, sconf *core.SufficientChainConfig) *eth.C } ethConf := ð.Config{ - ChainConfig: sconf.ChainConfig, - Genesis: sconf.Genesis, - FastSync: ctx.GlobalBool(aliasableName(FastSyncFlag.Name, ctx)), - BlockChainVersion: ctx.GlobalInt(aliasableName(BlockchainVersionFlag.Name, ctx)), - DatabaseCache: ctx.GlobalInt(aliasableName(CacheFlag.Name, ctx)), - DatabaseHandles: MakeDatabaseHandles(), - NetworkId: sconf.Network, - AccountManager: accman, - Etherbase: MakeEtherbase(accman, ctx), - MinerThreads: ctx.GlobalInt(aliasableName(MinerThreadsFlag.Name, ctx)), + ChainConfig: sconf.ChainConfig, + Genesis: sconf.Genesis, + UseAddrTxIndex: ctx.GlobalBool(aliasableName(AddrTxIndexFlag.Name, ctx)), + FastSync: ctx.GlobalBool(aliasableName(FastSyncFlag.Name, ctx)), + BlockChainVersion: ctx.GlobalInt(aliasableName(BlockchainVersionFlag.Name, ctx)), + DatabaseCache: ctx.GlobalInt(aliasableName(CacheFlag.Name, ctx)), + DatabaseHandles: MakeDatabaseHandles(), + NetworkId: sconf.Network, + AccountManager: accman, + Etherbase: MakeEtherbase(accman, ctx), + MinerThreads: ctx.GlobalInt(aliasableName(MinerThreadsFlag.Name, ctx)), NatSpec: ctx.GlobalBool(aliasableName(NatspecEnabledFlag.Name, ctx)), DocRoot: ctx.GlobalString(aliasableName(DocRootFlag.Name, ctx)), GasPrice: new(big.Int), @@ -799,18 +800,32 @@ func MustMakeChainConfigFromDefaults(ctx *cli.Context) *core.ChainConfig { // MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails. func MakeChainDatabase(ctx *cli.Context) ethdb.Database { var ( - datadir = MustMakeChainDataDir(ctx) - cache = ctx.GlobalInt(aliasableName(CacheFlag.Name, ctx)) - handles = MakeDatabaseHandles() + chaindir = MustMakeChainDataDir(ctx) + cache = ctx.GlobalInt(aliasableName(CacheFlag.Name, ctx)) + handles = MakeDatabaseHandles() ) - chainDb, err := ethdb.NewLDBDatabase(filepath.Join(datadir, "chaindata"), cache, handles) + chainDb, err := ethdb.NewLDBDatabase(filepath.Join(chaindir, "chaindata"), cache, handles) if err != nil { glog.Fatal("Could not open database: ", err) } return chainDb } +func MakeIndexDatabase(ctx *cli.Context) ethdb.Database { + var ( + chaindir = MustMakeChainDataDir(ctx) + cache = ctx.GlobalInt(aliasableName(CacheFlag.Name, ctx)) + handles = MakeDatabaseHandles() + ) + + indexesDb, err := ethdb.NewLDBDatabase(filepath.Join(chaindir, "indexes"), cache, handles) + if err != nil { + glog.Fatal("Could not open database: ", err) + } + return indexesDb +} + // MakeChain creates a chain manager from set command line flags. func MakeChain(ctx *cli.Context) (chain *core.BlockChain, chainDb ethdb.Database) { var err error diff --git a/cmd/geth/flags.go b/cmd/geth/flags.go index bd511f99f..65acfc2ef 100644 --- a/cmd/geth/flags.go +++ b/cmd/geth/flags.go @@ -89,6 +89,10 @@ var ( Name: "light-kdf,lightkdf", Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", } + AddrTxIndexFlag = cli.BoolFlag{ + Name: "add-tx-index,atxi", + Usage: "Toggle indexes for transactions by address. Pre-existing chaindata can be indexed with command 'geth atxi-build'", + } // Network Split settings ETFChain = cli.BoolFlag{ Name: "etf", diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 1cf0e10be..9cb97824c 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -99,6 +99,31 @@ func makeCLIApp() (app *cli.App) { The output of this command is supposed to be machine-readable. `, }, + { + Action: buildAddrTxIndexCmd, + Name: "atxi-build", + Usage: "Generate index for transactions by address", + Description: ` + Builds an index for transactions by address. + The command is idempotent; it will not hurt to run multiple times on the same range. + + If run without --start flag, the command makes use of a persistent placeholder, so you can + run 'geth build-atxi' on multiple occasions and pick up indexing progress where the last session + left off. + + To enable address-transaction indexing during block sync and import, use the '--atxi' flag. + `, + Flags: []cli.Flag{ + cli.IntFlag{ + Name: "start", + Usage: "Block number at which to begin building index", + }, + cli.IntFlag{ + Name: "stop", + Usage: "Block number at which to stop building index", + }, + }, + }, { Action: makeMLogDocumentation, Name: "mdoc", @@ -132,6 +157,7 @@ func makeCLIApp() (app *cli.App) { ChainIdentityFlag, BlockchainVersionFlag, FastSyncFlag, + AddrTxIndexFlag, CacheFlag, LightKDFFlag, JSpathFlag, diff --git a/core/blockchain.go b/core/blockchain.go index 9d5459475..2a6e44206 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -109,6 +109,9 @@ type BlockChain struct { pow pow.PoW processor Processor // block processor interface validator Validator // block and state validator interface + + useAddTxIndex bool + indexesDb ethdb.Database } // NewBlockChain returns a fully initialised block chain using information @@ -214,6 +217,17 @@ func (self *BlockChain) GetEventMux() *event.TypeMux { return self.eventMux } +// SetAddTxIndex sets the db and in-use var for atx indexing. +func (self *BlockChain) SetAddTxIndex(db ethdb.Database, tf bool) { + self.useAddTxIndex = tf + self.indexesDb = db +} + +// GetAddTxIndex return indexes db and if atx index in use. +func (self *BlockChain) GetAddTxIndex() (ethdb.Database, bool) { + return self.indexesDb, self.useAddTxIndex +} + func (self *BlockChain) getProcInterrupt() bool { return atomic.LoadInt32(&self.procInterrupt) == 1 } @@ -1276,6 +1290,30 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain return 0, nil } +func WriteBlockAddTxIndexes(indexDb ethdb.Database, block *types.Block) error { + for _, tx := range block.Transactions() { + var err error + from, err := tx.From() + if err != nil { + return err + } + err = PutAddrTxs(indexDb, block, false, from, tx.Hash()) + if err != nil { + return err + } + + to := tx.To() + if to == nil { + continue + } + err = PutAddrTxs(indexDb, block, true, *to, tx.Hash()) + if err != nil { + return err + } + } + return nil +} + // WriteBlock writes the block to the chain. func (self *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err error) { @@ -1523,6 +1561,12 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (chainIndex int, err err if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil { return i, err } + // Store the add-tx indexes + if self.useAddTxIndex { + if err := WriteBlockAddTxIndexes(self.indexesDb, block); err != nil { + glog.Fatalf("failed to write block add-tx indexes", err) + } + } case SideStatTy: if glog.V(logger.Detail) { glog.Infof("inserted forked block #%d (TD=%v) (%d TXs %d UNCs) [%s]. Took %v\n", block.Number(), block.Difficulty(), len(block.Transactions()), len(block.Uncles()), block.Hash().Hex(), time.Since(bstart)) diff --git a/core/database_util.go b/core/database_util.go index ce06606ed..85acd9e7c 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -46,6 +46,8 @@ var ( receiptsPrefix = []byte("receipts-") blockReceiptsPrefix = []byte("receipts-block-") + txAddressIndexPrefix = []byte("atx-") + mipmapPre = []byte("mipmap-log-bloom-") MIPMapLevels = []uint64{1000000, 500000, 100000, 50000, 1000} @@ -138,6 +140,113 @@ func GetBody(db ethdb.Database, hash common.Hash) *types.Body { return body } +// formatAddrTxIterator formats the index key prefix iterator, eg. atx-
+func formatAddrTxIterator(address common.Address) (iteratorPrefix []byte) { + iteratorPrefix = append(iteratorPrefix, txAddressIndexPrefix...) + iteratorPrefix = append(iteratorPrefix, address.Bytes()...) + return +} + +// GetAddrTxs gets the indexed transactions for a given account address. +func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, blockEndN uint64, toFromOrBoth string) []string { + if toFromOrBoth != "to" && toFromOrBoth != "from" && toFromOrBoth != "both" && toFromOrBoth != "" { + glog.Fatal("Address transactions list signature requires 'to', 'from', or 'both' or '' (=both)") + } + + // Have to cast to LevelDB to use iterator. Yuck. + ldb, ok := db.(*ethdb.LDBDatabase) + if !ok { + return nil + } + + // Create address prefix for iteration. + prefix := ethdb.NewBytesPrefix(formatAddrTxIterator(address)) + it := ldb.NewIteratorRange(prefix) + + // This will be the returnable. + var hashes []string + + // Convert start/stop block number to *big for easier comparison. + wantStart := new(big.Int).SetUint64(blockStartN) + wantEnd := new(big.Int).SetUint64(blockEndN) + + for it.Next() { + key := it.Key() + + _, blockNum, torf, txh := resolveAddrTxBytes(key) + + if blockStartN > 0 { + txaI := new(big.Int).SetUint64(binary.LittleEndian.Uint64(blockNum)) + if txaI.Cmp(wantStart) < 0 { + continue + } + } + if blockEndN > 0 { + txaI := new(big.Int).SetUint64(binary.LittleEndian.Uint64(blockNum)) + if txaI.Cmp(wantEnd) > 0 { + continue + } + } + if toFromOrBoth == "to" { + if string(torf) != "t" { + continue + } + } else if toFromOrBoth == "from" { + if string(torf) != "f" { + continue + } + } + tx := common.ToHex(txh) + hashes = append(hashes, tx) + } + it.Release() + if it.Error() != nil { + panic(it.Error()) + } + + return hashes +} + +// formatAddrTxBytes formats the index key, eg. atx- +// The values for these arguments should be of determinate length and format, see test TestFormatAndResolveAddrTxBytesKey +// for example. +func formatAddrTxBytes(address, blockNumber, toOrFrom, txhash []byte) (key []byte) { + key = txAddressIndexPrefix + key = append(key, address...) + key = append(key, blockNumber...) + key = append(key, toOrFrom...) + key = append(key, txhash...) + return +} + +// resolveAddrTxBytes resolves the index key to individual []byte values +func resolveAddrTxBytes(key []byte) (address, blockNumber, toOrFrom, txhash []byte) { + // prefix = key[:4] + address = key[4:24] // common.AddressLength = 20 + blockNumber = key[24:32] + toOrFrom = key[32:33] // == key[32] (1 byte) + txhash = key[33:] + return +} + +// PutAddrTxs adds an address/tx index to the indexes db. +// if isTo is false, then the address is the sender in the tx (from), t/f +func PutAddrTxs(db ethdb.Database, block *types.Block, isTo bool, address common.Address, txhash common.Hash) error { + var tOrF = []byte("f") + if isTo { + tOrF = []byte("t") + } + + bk := make([]byte, 8) + binary.LittleEndian.PutUint64(bk, block.NumberU64()) + k := formatAddrTxBytes(address.Bytes(), bk, tOrF, txhash.Bytes()) + + if err := db.Put(k, nil); err != nil { + glog.Fatalf("failed to store addrtxidx into database: %v", err) + } + return nil +} + // GetTd retrieves a block's total difficulty corresponding to the hash, nil if // none found. func GetTd(db ethdb.Database, hash common.Hash) *big.Int { diff --git a/core/database_util_test.go b/core/database_util_test.go index a98a81173..70401bbb7 100644 --- a/core/database_util_test.go +++ b/core/database_util_test.go @@ -33,6 +33,7 @@ import ( "github.com/ethereumproject/go-ethereum/crypto/sha3" "github.com/ethereumproject/go-ethereum/ethdb" "github.com/ethereumproject/go-ethereum/rlp" + "encoding/binary" ) type diffTest struct { @@ -298,6 +299,56 @@ func TestTdStorage(t *testing.T) { } } +func TestFormatAndResolveAddrTxBytesKey(t *testing.T) { + testAddr := common.Address{} + testBN := big.NewInt(42) + testTorf := "f" + testTxH := common.Hash{} + + testBNBytes := make([]byte, 8) + binary.LittleEndian.PutUint64(testBNBytes, testBN.Uint64()) + + key := formatAddrTxBytes(testAddr.Bytes(), testBNBytes, []byte(testTorf), testTxH.Bytes()) + + // Test key/prefix iterator-ability. + itPrefix := formatAddrTxIterator(testAddr) + if !bytes.HasPrefix(key, itPrefix) { + t.Fatalf("key/prefix mismatch: prefix=%s key=%s", itPrefix, key) + } + + // Reverse engineer key and ensure expected. + outAddr, outBNBytes, outTorf, outTxH := resolveAddrTxBytes(key) + + if gotAddr := common.BytesToAddress(outAddr); gotAddr != testAddr { + t.Errorf("got: %v, want: %v", gotAddr.Hex(), testAddr.Hex()) + } + if gotBN := new(big.Int).SetUint64(binary.LittleEndian.Uint64(outBNBytes)); gotBN.Cmp(testBN) != 0 { + t.Errorf("got: %v, want: %v", gotBN, testBN) + } + if gotTorf := string(outTorf); gotTorf != testTorf { + t.Errorf("got: %v, want: %v", gotTorf, testTorf) + } + if gotTxH := common.BytesToHash(outTxH); gotTxH != testTxH { + t.Errorf("got: %v, want: %v", gotTxH, testTxH) + } + + // Ensure proper key part sizing. + sizes := []struct{ + b []byte + expectedLen int + }{ + {outAddr, common.AddressLength}, + {outBNBytes, 8}, + {outTorf, 1}, + {outTxH, common.HashLength}, + } + for _, s := range sizes { + if l := len(s.b); l != s.expectedLen { + t.Errorf("want: %v, got: %v", s.expectedLen, l) + } + } +} + // Tests that canonical numbers can be mapped to hashes and retrieved. func TestCanonicalMappingStorage(t *testing.T) { db, _ := ethdb.NewMemDatabase() diff --git a/eth/api.go b/eth/api.go index 881e79896..bad7fb734 100644 --- a/eth/api.go +++ b/eth/api.go @@ -520,6 +520,7 @@ type PublicBlockChainAPI struct { config *core.ChainConfig bc *core.BlockChain chainDb ethdb.Database + indexesDb ethdb.Database eventMux *event.TypeMux muNewBlockSubscriptions sync.Mutex // protects newBlocksSubscriptions newBlockSubscriptions map[string]func(core.ChainEvent) error // callbacks for new block subscriptions @@ -1618,6 +1619,26 @@ func NewPublicDebugAPI(eth *Ethereum) *PublicDebugAPI { return &PublicDebugAPI{eth: eth} } +// AddressTransactions gets transactions for a given address. +// Optional values include start and stop block numbers, and to/from/both value for tx/address relation. +// Returns a slice of strings of transactions hashes. +func (api *PublicDebugAPI) GetAddressTransactions(address common.Address, blockStartN uint64, blockEndN uint64, toOrFrom string) (list []string, err error) { + glog.V(logger.Debug).Infoln("RPC call: debug_getAddressTransactions %s %d %d %s", address, blockStartN, blockEndN, toOrFrom) + + if _, inUse := api.eth.BlockChain().GetAddTxIndex(); !inUse { + return nil, errors.New("addr-tx indexing not enabled") + } + + list = core.GetAddrTxs(api.eth.indexesDb, address, blockStartN, blockEndN, toOrFrom) + + // Since list is a slice, it can be nil, which returns 'null'. + // Should return empty 'array' if no txs found. + if list == nil { + list = []string{} + } + return list, nil +} + // DumpBlock retrieves the entire state of the database at a given block. // TODO: update to be able to dump for specific addresses? func (api *PublicDebugAPI) DumpBlock(number uint64) (state.Dump, error) { diff --git a/eth/backend.go b/eth/backend.go index 00eeec8c8..58e2d7742 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -81,6 +81,8 @@ type Config struct { MinerThreads int SolcPath string + UseAddrTxIndex bool + GpoMinGasPrice *big.Int GpoMaxGasPrice *big.Int GpoFullBlockRatio int @@ -98,8 +100,9 @@ type Ethereum struct { shutdownChan chan bool // DB interfaces - chainDb ethdb.Database // Block chain database - dappDb ethdb.Database // Dapp database + chainDb ethdb.Database // Block chain database + dappDb ethdb.Database // Dapp database + indexesDb ethdb.Database // Indexes database (optional -- eg. add-tx indexes) // Handlers txPool *core.TxPool @@ -220,6 +223,19 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { eth.pow = ethash.New() } + // Initialize indexes db if enabled + // Blockchain will be assigned the db and atx enabled after blockchain is intialized below. + var indexesDb ethdb.Database + if config.UseAddrTxIndex { + indexesDb, err = ctx.OpenDatabase("indexes", config.DatabaseCache, config.DatabaseHandles) + if err != nil { + return nil, err + } + eth.indexesDb = indexesDb + glog.V(logger.Info).Infof("Opened add-tx index db") + glog.D(logger.Warn).Infof("Opened add-tx index db") + } + // load the genesis block or write a new one if no genesis // block is present in the database. genesis := core.GetBlock(chainDb, core.GetCanonicalHash(chainDb, 0)) @@ -257,6 +273,11 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { } return nil, err } + // Configure enabled atxi for blockchain + if config.UseAddrTxIndex { + eth.blockchain.SetAddTxIndex(eth.indexesDb, true) + } + eth.gpo = NewGasPriceOracle(eth) newPool := core.NewTxPool(eth.chainConfig, eth.EventMux(), eth.blockchain.State, eth.blockchain.GasLimit) diff --git a/ethdb/database.go b/ethdb/database.go index 4363e7b8a..23f7d8b50 100644 --- a/ethdb/database.go +++ b/ethdb/database.go @@ -28,6 +28,7 @@ import ( "github.com/syndtr/goleveldb/leveldb/filter" "github.com/syndtr/goleveldb/leveldb/iterator" "github.com/syndtr/goleveldb/leveldb/opt" + ldbutil "github.com/syndtr/goleveldb/leveldb/util" ) var OpenFileLimit = 64 @@ -110,6 +111,14 @@ func (self *LDBDatabase) NewIterator() iterator.Iterator { return self.db.NewIterator(nil, nil) } +func (self *LDBDatabase) NewIteratorRange(slice *ldbutil.Range) iterator.Iterator { + return self.db.NewIterator(slice, nil) +} + +func NewBytesPrefix(prefix []byte) *ldbutil.Range { + return ldbutil.BytesPrefix(prefix) +} + func (self *LDBDatabase) Close() { if err := self.db.Close(); err != nil { glog.Errorf("eth: DB %s: %s", self.file, err) diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index e1aa668c5..d714a6d43 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -206,6 +206,11 @@ web3._extend({ name: 'accountExist', call: 'debug_accountExist', params: 2 + }), + new web3._extend.Method({ + name: 'getAddressTransactions', + call: 'debug_getAddressTransactions', + params: 4 }) ], properties: [] From 71c0b77a2e0e144fb09a3f6b984af065074d11f1 Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 18 Jan 2018 14:03:11 +0900 Subject: [PATCH 02/45] dep ensure --- Gopkg.lock | 56 +- vendor/github.com/cheggaaa/pb/.gitignore | 1 + vendor/github.com/cheggaaa/pb/.travis.yml | 13 + vendor/github.com/cheggaaa/pb/Gopkg.lock | 63 + vendor/github.com/cheggaaa/pb/Gopkg.toml | 91 ++ vendor/github.com/cheggaaa/pb/LICENSE | 12 + vendor/github.com/cheggaaa/pb/README.md | 70 + vendor/github.com/cheggaaa/pb/element.go | 290 ++++ vendor/github.com/cheggaaa/pb/element_test.go | 278 ++++ vendor/github.com/cheggaaa/pb/pb.go | 540 ++++++++ vendor/github.com/cheggaaa/pb/pb_test.go | 219 +++ vendor/github.com/cheggaaa/pb/preset.go | 17 + vendor/github.com/cheggaaa/pb/reader.go | 26 + vendor/github.com/cheggaaa/pb/reader_test.go | 60 + vendor/github.com/cheggaaa/pb/speed.go | 83 ++ vendor/github.com/cheggaaa/pb/template.go | 87 ++ .../github.com/cheggaaa/pb/template_test.go | 53 + .../github.com/cheggaaa/pb/termutil/term.go | 57 + .../cheggaaa/pb/termutil/term_appengine.go | 11 + .../cheggaaa/pb/termutil/term_bsd.go | 9 + .../cheggaaa/pb/termutil/term_linux.go | 7 + .../cheggaaa/pb/termutil/term_nix.go | 8 + .../cheggaaa/pb/termutil/term_solaris.go | 8 + .../cheggaaa/pb/termutil/term_win.go | 149 ++ .../github.com/cheggaaa/pb/termutil/term_x.go | 70 + vendor/github.com/cheggaaa/pb/util.go | 94 ++ vendor/github.com/cheggaaa/pb/util_test.go | 73 + .../github.com/mattn/go-colorable/.travis.yml | 9 + vendor/github.com/mattn/go-colorable/LICENSE | 21 + .../github.com/mattn/go-colorable/README.md | 48 + .../go-colorable/_example/escape-seq/main.go | 16 + .../go-colorable/_example/logrus/main.go | 16 + .../mattn/go-colorable/_example/title/main.go | 14 + .../mattn/go-colorable/colorable_appengine.go | 29 + .../mattn/go-colorable/colorable_others.go | 30 + .../mattn/go-colorable/colorable_test.go | 83 ++ .../mattn/go-colorable/colorable_windows.go | 884 ++++++++++++ .../mattn/go-colorable/noncolorable.go | 55 + vendor/github.com/mattn/go-isatty/.travis.yml | 9 + vendor/github.com/mattn/go-isatty/LICENSE | 9 + vendor/github.com/mattn/go-isatty/README.md | 50 + vendor/github.com/mattn/go-isatty/doc.go | 2 + .../mattn/go-isatty/example_test.go | 18 + .../mattn/go-isatty/isatty_appengine.go | 15 + .../github.com/mattn/go-isatty/isatty_bsd.go | 18 + .../mattn/go-isatty/isatty_linux.go | 18 + .../mattn/go-isatty/isatty_linux_ppc64x.go | 19 + .../mattn/go-isatty/isatty_others.go | 10 + .../mattn/go-isatty/isatty_others_test.go | 19 + .../mattn/go-isatty/isatty_solaris.go | 16 + .../mattn/go-isatty/isatty_windows.go | 94 ++ .../mattn/go-isatty/isatty_windows_test.go | 35 + .../ewma.v1/.github/ISSUE_TEMPLATE.md | 10 + .../ewma.v1/.github/PULL_REQUEST_TEMPLATE.md | 10 + .../gopkg.in/VividCortex/ewma.v1/.gitignore | 2 + vendor/gopkg.in/VividCortex/ewma.v1/LICENSE | 21 + vendor/gopkg.in/VividCortex/ewma.v1/README.md | 140 ++ vendor/gopkg.in/VividCortex/ewma.v1/ewma.go | 126 ++ .../gopkg.in/VividCortex/ewma.v1/ewma_test.go | 103 ++ vendor/gopkg.in/cheggaaa/pb.v2/.gitignore | 1 + vendor/gopkg.in/cheggaaa/pb.v2/.travis.yml | 13 + vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.lock | 63 + vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.toml | 91 ++ vendor/gopkg.in/cheggaaa/pb.v2/LICENSE | 12 + vendor/gopkg.in/cheggaaa/pb.v2/README.md | 70 + vendor/gopkg.in/cheggaaa/pb.v2/element.go | 290 ++++ .../gopkg.in/cheggaaa/pb.v2/element_test.go | 278 ++++ vendor/gopkg.in/cheggaaa/pb.v2/pb.go | 540 ++++++++ vendor/gopkg.in/cheggaaa/pb.v2/pb_test.go | 219 +++ vendor/gopkg.in/cheggaaa/pb.v2/preset.go | 17 + vendor/gopkg.in/cheggaaa/pb.v2/reader.go | 26 + vendor/gopkg.in/cheggaaa/pb.v2/reader_test.go | 60 + vendor/gopkg.in/cheggaaa/pb.v2/speed.go | 83 ++ vendor/gopkg.in/cheggaaa/pb.v2/template.go | 87 ++ .../gopkg.in/cheggaaa/pb.v2/template_test.go | 53 + .../gopkg.in/cheggaaa/pb.v2/termutil/term.go | 57 + .../cheggaaa/pb.v2/termutil/term_appengine.go | 11 + .../cheggaaa/pb.v2/termutil/term_bsd.go | 9 + .../cheggaaa/pb.v2/termutil/term_linux.go | 7 + .../cheggaaa/pb.v2/termutil/term_nix.go | 8 + .../cheggaaa/pb.v2/termutil/term_solaris.go | 8 + .../cheggaaa/pb.v2/termutil/term_win.go | 149 ++ .../cheggaaa/pb.v2/termutil/term_x.go | 70 + vendor/gopkg.in/cheggaaa/pb.v2/util.go | 94 ++ vendor/gopkg.in/cheggaaa/pb.v2/util_test.go | 73 + vendor/gopkg.in/fatih/color.v1/.travis.yml | 5 + vendor/gopkg.in/fatih/color.v1/LICENSE.md | 20 + vendor/gopkg.in/fatih/color.v1/README.md | 177 +++ vendor/gopkg.in/fatih/color.v1/color.go | 600 ++++++++ vendor/gopkg.in/fatih/color.v1/color_test.go | 342 +++++ vendor/gopkg.in/fatih/color.v1/doc.go | 133 ++ .../mattn/go-colorable.v0/.travis.yml | 9 + vendor/gopkg.in/mattn/go-colorable.v0/LICENSE | 21 + .../gopkg.in/mattn/go-colorable.v0/README.md | 48 + .../_example/escape-seq/main.go | 16 + .../go-colorable.v0/_example/logrus/main.go | 16 + .../go-colorable.v0/_example/title/main.go | 14 + .../go-colorable.v0/colorable_appengine.go | 29 + .../mattn/go-colorable.v0/colorable_others.go | 30 + .../mattn/go-colorable.v0/colorable_test.go | 83 ++ .../go-colorable.v0/colorable_windows.go | 884 ++++++++++++ .../mattn/go-colorable.v0/noncolorable.go | 55 + .../gopkg.in/mattn/go-isatty.v0/.travis.yml | 9 + vendor/gopkg.in/mattn/go-isatty.v0/LICENSE | 9 + vendor/gopkg.in/mattn/go-isatty.v0/README.md | 50 + vendor/gopkg.in/mattn/go-isatty.v0/doc.go | 2 + .../mattn/go-isatty.v0/example_test.go | 18 + .../mattn/go-isatty.v0/isatty_appengine.go | 15 + .../gopkg.in/mattn/go-isatty.v0/isatty_bsd.go | 18 + .../mattn/go-isatty.v0/isatty_linux.go | 18 + .../mattn/go-isatty.v0/isatty_linux_ppc64x.go | 19 + .../mattn/go-isatty.v0/isatty_others.go | 10 + .../mattn/go-isatty.v0/isatty_others_test.go | 19 + .../mattn/go-isatty.v0/isatty_solaris.go | 16 + .../mattn/go-isatty.v0/isatty_windows.go | 94 ++ .../mattn/go-isatty.v0/isatty_windows_test.go | 35 + .../mattn/go-runewidth.v0/.travis.yml | 8 + vendor/gopkg.in/mattn/go-runewidth.v0/LICENSE | 21 + .../gopkg.in/mattn/go-runewidth.v0/README.mkd | 27 + .../mattn/go-runewidth.v0/runewidth.go | 1223 +++++++++++++++++ .../mattn/go-runewidth.v0/runewidth_js.go | 8 + .../mattn/go-runewidth.v0/runewidth_posix.go | 77 ++ .../mattn/go-runewidth.v0/runewidth_test.go | 275 ++++ .../go-runewidth.v0/runewidth_windows.go | 25 + 124 files changed, 11260 insertions(+), 1 deletion(-) create mode 100644 vendor/github.com/cheggaaa/pb/.gitignore create mode 100644 vendor/github.com/cheggaaa/pb/.travis.yml create mode 100644 vendor/github.com/cheggaaa/pb/Gopkg.lock create mode 100644 vendor/github.com/cheggaaa/pb/Gopkg.toml create mode 100644 vendor/github.com/cheggaaa/pb/LICENSE create mode 100644 vendor/github.com/cheggaaa/pb/README.md create mode 100644 vendor/github.com/cheggaaa/pb/element.go create mode 100644 vendor/github.com/cheggaaa/pb/element_test.go create mode 100644 vendor/github.com/cheggaaa/pb/pb.go create mode 100644 vendor/github.com/cheggaaa/pb/pb_test.go create mode 100644 vendor/github.com/cheggaaa/pb/preset.go create mode 100644 vendor/github.com/cheggaaa/pb/reader.go create mode 100644 vendor/github.com/cheggaaa/pb/reader_test.go create mode 100644 vendor/github.com/cheggaaa/pb/speed.go create mode 100644 vendor/github.com/cheggaaa/pb/template.go create mode 100644 vendor/github.com/cheggaaa/pb/template_test.go create mode 100644 vendor/github.com/cheggaaa/pb/termutil/term.go create mode 100644 vendor/github.com/cheggaaa/pb/termutil/term_appengine.go create mode 100644 vendor/github.com/cheggaaa/pb/termutil/term_bsd.go create mode 100644 vendor/github.com/cheggaaa/pb/termutil/term_linux.go create mode 100644 vendor/github.com/cheggaaa/pb/termutil/term_nix.go create mode 100644 vendor/github.com/cheggaaa/pb/termutil/term_solaris.go create mode 100644 vendor/github.com/cheggaaa/pb/termutil/term_win.go create mode 100644 vendor/github.com/cheggaaa/pb/termutil/term_x.go create mode 100644 vendor/github.com/cheggaaa/pb/util.go create mode 100644 vendor/github.com/cheggaaa/pb/util_test.go create mode 100644 vendor/github.com/mattn/go-colorable/.travis.yml create mode 100644 vendor/github.com/mattn/go-colorable/LICENSE create mode 100644 vendor/github.com/mattn/go-colorable/README.md create mode 100644 vendor/github.com/mattn/go-colorable/_example/escape-seq/main.go create mode 100644 vendor/github.com/mattn/go-colorable/_example/logrus/main.go create mode 100644 vendor/github.com/mattn/go-colorable/_example/title/main.go create mode 100644 vendor/github.com/mattn/go-colorable/colorable_appengine.go create mode 100644 vendor/github.com/mattn/go-colorable/colorable_others.go create mode 100644 vendor/github.com/mattn/go-colorable/colorable_test.go create mode 100644 vendor/github.com/mattn/go-colorable/colorable_windows.go create mode 100644 vendor/github.com/mattn/go-colorable/noncolorable.go create mode 100644 vendor/github.com/mattn/go-isatty/.travis.yml create mode 100644 vendor/github.com/mattn/go-isatty/LICENSE create mode 100644 vendor/github.com/mattn/go-isatty/README.md create mode 100644 vendor/github.com/mattn/go-isatty/doc.go create mode 100644 vendor/github.com/mattn/go-isatty/example_test.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_appengine.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_bsd.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_linux.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_others.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_others_test.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_solaris.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_windows.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_windows_test.go create mode 100644 vendor/gopkg.in/VividCortex/ewma.v1/.github/ISSUE_TEMPLATE.md create mode 100644 vendor/gopkg.in/VividCortex/ewma.v1/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 vendor/gopkg.in/VividCortex/ewma.v1/.gitignore create mode 100644 vendor/gopkg.in/VividCortex/ewma.v1/LICENSE create mode 100644 vendor/gopkg.in/VividCortex/ewma.v1/README.md create mode 100644 vendor/gopkg.in/VividCortex/ewma.v1/ewma.go create mode 100644 vendor/gopkg.in/VividCortex/ewma.v1/ewma_test.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/.gitignore create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/.travis.yml create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.lock create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.toml create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/LICENSE create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/README.md create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/element.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/element_test.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/pb.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/pb_test.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/preset.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/reader.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/reader_test.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/speed.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/template.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/template_test.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_appengine.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_bsd.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_linux.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_nix.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_solaris.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_win.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_x.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/util.go create mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/util_test.go create mode 100644 vendor/gopkg.in/fatih/color.v1/.travis.yml create mode 100644 vendor/gopkg.in/fatih/color.v1/LICENSE.md create mode 100644 vendor/gopkg.in/fatih/color.v1/README.md create mode 100644 vendor/gopkg.in/fatih/color.v1/color.go create mode 100644 vendor/gopkg.in/fatih/color.v1/color_test.go create mode 100644 vendor/gopkg.in/fatih/color.v1/doc.go create mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/.travis.yml create mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/LICENSE create mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/README.md create mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/_example/escape-seq/main.go create mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/_example/logrus/main.go create mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/_example/title/main.go create mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/colorable_appengine.go create mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/colorable_others.go create mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/colorable_test.go create mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/colorable_windows.go create mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/noncolorable.go create mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/.travis.yml create mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/LICENSE create mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/README.md create mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/doc.go create mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/example_test.go create mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_appengine.go create mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_bsd.go create mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux.go create mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux_ppc64x.go create mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_others.go create mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_others_test.go create mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_solaris.go create mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows.go create mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows_test.go create mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/.travis.yml create mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/LICENSE create mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/README.mkd create mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/runewidth.go create mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_js.go create mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_posix.go create mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_test.go create mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_windows.go diff --git a/Gopkg.lock b/Gopkg.lock index 336bd3e79..5893580f0 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -13,6 +13,12 @@ revision = "2f1ce7a837dcb8da3ec595b1dac9d0632f0f99e8" version = "v1.3.1" +[[projects]] + name = "github.com/cheggaaa/pb" + packages = ["."] + revision = "c112833d014c77e8bde723fd0158e3156951639f" + version = "v2.0.6" + [[projects]] name = "github.com/davecgh/go-spew" packages = ["spew"] @@ -73,6 +79,18 @@ revision = "766956aceb8ff49664065ae50bef0ae8a0a83ec4" version = "v1.0.2" +[[projects]] + name = "github.com/mattn/go-colorable" + packages = ["."] + revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072" + version = "v0.0.9" + +[[projects]] + name = "github.com/mattn/go-isatty" + packages = ["."] + revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" + version = "v0.0.3" + [[projects]] name = "github.com/mattn/go-runewidth" packages = ["."] @@ -163,12 +181,30 @@ packages = ["go/ast/astutil","imports"] revision = "b451b9aaee4dcf75f9f28cddb69b9d0ed17a9752" +[[projects]] + name = "gopkg.in/VividCortex/ewma.v1" + packages = ["."] + revision = "b24eb346a94c3ba12c1da1e564dbac1b498a77ce" + version = "v1.1.1" + [[projects]] branch = "v1" name = "gopkg.in/check.v1" packages = ["."] revision = "20d25e2804050c1cd24a7eea1e7a6447dd0e74ec" +[[projects]] + name = "gopkg.in/cheggaaa/pb.v2" + packages = ["termutil"] + revision = "c112833d014c77e8bde723fd0158e3156951639f" + version = "v2.0.6" + +[[projects]] + name = "gopkg.in/fatih/color.v1" + packages = ["."] + revision = "570b54cabe6b8eb0bc2dfce68d964677d63b5260" + version = "v1.5.0" + [[projects]] name = "gopkg.in/fatih/set.v0" packages = ["."] @@ -181,6 +217,24 @@ packages = ["collections/prque"] revision = "8dcd6a7f4951f6ff3ee9cbb919a06d8925822e57" +[[projects]] + name = "gopkg.in/mattn/go-colorable.v0" + packages = ["."] + revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072" + version = "v0.0.9" + +[[projects]] + name = "gopkg.in/mattn/go-isatty.v0" + packages = ["."] + revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" + version = "v0.0.3" + +[[projects]] + name = "gopkg.in/mattn/go-runewidth.v0" + packages = ["."] + revision = "9e777a8366cce605130a531d2cd6363d07ad7317" + version = "v0.0.2" + [[projects]] name = "gopkg.in/sourcemap.v1" packages = [".","base64vlq"] @@ -195,6 +249,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "803cc2cdca758526169a444788e436c4d905150702b80d333138703a813ba169" + inputs-digest = "cf961bcfe2cc1919ed1448c844efdd74014f76f9c076ff85cf397b7185a67829" solver-name = "gps-cdcl" solver-version = 1 diff --git a/vendor/github.com/cheggaaa/pb/.gitignore b/vendor/github.com/cheggaaa/pb/.gitignore new file mode 100644 index 000000000..48b8bf907 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/.gitignore @@ -0,0 +1 @@ +vendor/ diff --git a/vendor/github.com/cheggaaa/pb/.travis.yml b/vendor/github.com/cheggaaa/pb/.travis.yml new file mode 100644 index 000000000..7d3bc2399 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/.travis.yml @@ -0,0 +1,13 @@ +language: go +go: +- 1.7 +- 1.8 +sudo: false +gobuild_args: -v -race +os: +- linux +- osx +before_install: + - go get github.com/mattn/goveralls +script: + - $HOME/gopath/bin/goveralls -service=travis-ci -ignore=termutil/* diff --git a/vendor/github.com/cheggaaa/pb/Gopkg.lock b/vendor/github.com/cheggaaa/pb/Gopkg.lock new file mode 100644 index 000000000..fd90c4b6a --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/Gopkg.lock @@ -0,0 +1,63 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/mattn/go-colorable" + packages = ["."] + revision = "ed8eb9e318d7a84ce5915b495b7d35e0cfe7b5a8" + version = "v0.0.6" + +[[projects]] + name = "github.com/mattn/go-isatty" + packages = ["."] + revision = "3a115632dcd687f9c8cd01679c83a06a0e21c1f3" + version = "v0.0.1" + +[[projects]] + branch = "master" + name = "golang.org/x/sys" + packages = ["unix"] + revision = "b90f89a1e7a9c1f6b918820b3daa7f08488c8594" + +[[projects]] + name = "gopkg.in/VividCortex/ewma.v1" + packages = ["."] + revision = "2f8aa9741ab4b5b80945c750b871131b88ef5b7f" + version = "v1.0" + +[[projects]] + name = "gopkg.in/cheggaaa/pb.v2" + packages = ["termutil"] + revision = "180c76fdb3025713f501cd481e47810a9c715bd7" + version = "v2.0.1" + +[[projects]] + name = "gopkg.in/fatih/color.v1" + packages = ["."] + revision = "570b54cabe6b8eb0bc2dfce68d964677d63b5260" + version = "v1.5.0" + +[[projects]] + name = "gopkg.in/mattn/go-colorable.v0" + packages = ["."] + revision = "d228849504861217f796da67fae4f6e347643f15" + version = "v0.0.7" + +[[projects]] + name = "gopkg.in/mattn/go-isatty.v0" + packages = ["."] + revision = "fc9e8d8ef48496124e79ae0df75490096eccf6fe" + version = "v0.0.2" + +[[projects]] + name = "gopkg.in/mattn/go-runewidth.v0" + packages = ["."] + revision = "9e777a8366cce605130a531d2cd6363d07ad7317" + version = "v0.0.2" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "cf10fbfc96962122f1a56c1752a1d5dab64799ffedc58460e1ab1465d2bef5e2" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/cheggaaa/pb/Gopkg.toml b/vendor/github.com/cheggaaa/pb/Gopkg.toml new file mode 100644 index 000000000..d5f2fef13 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/Gopkg.toml @@ -0,0 +1,91 @@ + +## Gopkg.toml example (these lines may be deleted) + +## "metadata" defines metadata about the project that could be used by other independent +## systems. The metadata defined here will be ignored by dep. +# [metadata] +# key1 = "value that convey data to other systems" +# system1-data = "value that is used by a system" +# system2-data = "value that is used by another system" + +## "required" lists a set of packages (not projects) that must be included in +## Gopkg.lock. This list is merged with the set of packages imported by the current +## project. Use it when your project needs a package it doesn't explicitly import - +## including "main" packages. +# required = ["github.com/user/thing/cmd/thing"] + +## "ignored" lists a set of packages (not projects) that are ignored when +## dep statically analyzes source code. Ignored packages can be in this project, +## or in a dependency. +# ignored = ["github.com/user/project/badpkg"] + +## Constraints are rules for how directly imported projects +## may be incorporated into the depgraph. They are respected by +## dep whether coming from the Gopkg.toml of the current project or a dependency. +# [[constraint]] +## Required: the root import path of the project being constrained. +# name = "github.com/user/project" +# +## Recommended: the version constraint to enforce for the project. +## Only one of "branch", "version" or "revision" can be specified. +# version = "1.0.0" +# branch = "master" +# revision = "abc123" +# +## Optional: an alternate location (URL or import path) for the project's source. +# source = "https://github.com/myfork/package.git" +# +## "metadata" defines metadata about the dependency or override that could be used +## by other independent systems. The metadata defined here will be ignored by dep. +# [metadata] +# key1 = "value that convey data to other systems" +# system1-data = "value that is used by a system" +# system2-data = "value that is used by another system" + +## Overrides have the same structure as [[constraint]], but supersede all +## [[constraint]] declarations from all projects. Only [[override]] from +## the current project's are applied. +## +## Overrides are a sledgehammer. Use them only as a last resort. +# [[override]] +## Required: the root import path of the project being constrained. +# name = "github.com/user/project" +# +## Optional: specifying a version constraint override will cause all other +## constraints on this project to be ignored; only the overridden constraint +## need be satisfied. +## Again, only one of "branch", "version" or "revision" can be specified. +# version = "1.0.0" +# branch = "master" +# revision = "abc123" +# +## Optional: specifying an alternate source location as an override will +## enforce that the alternate location is used for that project, regardless of +## what source location any dependent projects specify. +# source = "https://github.com/myfork/package.git" + + + +[[constraint]] + name = "gopkg.in/VividCortex/ewma.v1" + version = "1.0.0" + +[[constraint]] + name = "gopkg.in/cheggaaa/pb.v2" + version = "2.0.1" + +[[constraint]] + name = "gopkg.in/fatih/color.v1" + version = "1.5.0" + +[[constraint]] + name = "gopkg.in/mattn/go-colorable.v0" + version = "0.0.7" + +[[constraint]] + name = "gopkg.in/mattn/go-isatty.v0" + version = "0.0.2" + +[[constraint]] + name = "gopkg.in/mattn/go-runewidth.v0" + version = "0.0.2" diff --git a/vendor/github.com/cheggaaa/pb/LICENSE b/vendor/github.com/cheggaaa/pb/LICENSE new file mode 100644 index 000000000..511970333 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/LICENSE @@ -0,0 +1,12 @@ +Copyright (c) 2012-2015, Sergey Cherepanov +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/github.com/cheggaaa/pb/README.md b/vendor/github.com/cheggaaa/pb/README.md new file mode 100644 index 000000000..907124e19 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/README.md @@ -0,0 +1,70 @@ +# Terminal progress bar for Go + +[![Coverage Status](https://coveralls.io/repos/github/cheggaaa/pb/badge.svg?branch=v2)](https://coveralls.io/github/cheggaaa/pb?branch=v2) + +### It's beta, some features may be changed + +This is proposal for the second version of progress bar +- based on text/template +- can take custom elements +- using colors is easy + +## Installation + +``` +go get gopkg.in/cheggaaa/pb.v2 +``` + +## Usage + +```Go +package main + +import ( + "gopkg.in/cheggaaa/pb.v2" + "time" +) + +func main() { + simple() + fromPreset() + customTemplate(`Custom template: {{counters . }}`) + customTemplate(`{{ red "With colors:" }} {{bar . | green}} {{speed . | blue }}`) + customTemplate(`{{ red "With funcs:" }} {{ bar . "<" "-" (cycle . "↖" "↗" "↘" "↙" ) "." ">"}} {{speed . | rndcolor }}`) + customTemplate(`{{ bar . "[<" "·····•·····" (rnd "ᗧ" "◔" "◕" "◷" ) "•" ">]"}}`) +} + +func simple() { + count := 1000 + bar := pb.StartNew(count) + for i := 0; i < count; i++ { + bar.Increment() + time.Sleep(time.Millisecond * 2) + } + bar.Finish() +} + +func fromPreset() { + count := 1000 + //bar := pb.Default.Start(total) + //bar := pb.Simple.Start(total) + bar := pb.Full.Start(count) + defer bar.Finish() + bar.Set("prefix", "fromPreset(): ") + for i := 0; i < count/2; i++ { + bar.Add(2) + time.Sleep(time.Millisecond * 4) + } +} + +func customTemplate(tmpl string) { + count := 1000 + bar := pb.ProgressBarTemplate(tmpl).Start(count) + defer bar.Finish() + for i := 0; i < count/2; i++ { + bar.Add(2) + time.Sleep(time.Millisecond * 4) + } +} + +``` \ No newline at end of file diff --git a/vendor/github.com/cheggaaa/pb/element.go b/vendor/github.com/cheggaaa/pb/element.go new file mode 100644 index 000000000..965183fe7 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/element.go @@ -0,0 +1,290 @@ +package pb + +import ( + "bytes" + "fmt" + "math" + "sync" + "time" +) + +const ( + adElPlaceholder = "%_ad_el_%" + adElPlaceholderLen = len(adElPlaceholder) +) + +var ( + defaultBarEls = [5]string{"[", "-", ">", "_", "]"} +) + +// Element is an interface for bar elements +type Element interface { + ProgressElement(state *State, args ...string) string +} + +// ElementFunc type implements Element interface and created for simplify elements +type ElementFunc func(state *State, args ...string) string + +// ProgressElement just call self func +func (e ElementFunc) ProgressElement(state *State, args ...string) string { + return e(state, args...) +} + +var elementsM sync.Mutex + +var elements = map[string]Element{ + "percent": ElementPercent, + "counters": ElementCounters, + "bar": adaptiveWrap(ElementBar), + "speed": ElementSpeed, + "rtime": ElementRemainingTime, + "etime": ElementElapsedTime, + "string": ElementString, + "cycle": ElementCycle, +} + +// RegisterElement give you a chance to use custom elements +func RegisterElement(name string, el Element, adaptive bool) { + if adaptive { + el = adaptiveWrap(el) + } + elementsM.Lock() + elements[name] = el + elementsM.Unlock() +} + +type argsHelper []string + +func (args argsHelper) getOr(n int, value string) string { + if len(args) > n { + return args[n] + } + return value +} + +func (args argsHelper) getNotEmptyOr(n int, value string) (v string) { + if v = args.getOr(n, value); v == "" { + return value + } + return +} + +func adaptiveWrap(el Element) Element { + return ElementFunc(func(state *State, args ...string) string { + state.recalc = append(state.recalc, ElementFunc(func(s *State, _ ...string) (result string) { + s.adaptive = true + result = el.ProgressElement(s, args...) + s.adaptive = false + return + })) + return adElPlaceholder + }) +} + +// ElementPercent shows current percent of progress. +// Optionally can take one or two string arguments. +// First string will be used as value for format float64, default is "%.02f%%". +// Second string will be used when percent can't be calculated, default is "?%" +// In template use as follows: {{percent .}} or {{percent . "%.03f%%"}} or {{percent . "%.03f%%" "?"}} +var ElementPercent ElementFunc = func(state *State, args ...string) string { + argsh := argsHelper(args) + if state.Total() > 0 { + return fmt.Sprintf( + argsh.getNotEmptyOr(0, "%.02f%%"), + float64(state.Value())/(float64(state.Total())/float64(100)), + ) + } + return argsh.getOr(1, "?%") +} + +// ElementCounters shows current and total values. +// Optionally can take one or two string arguments. +// First string will be used as format value when Total is present (>0). Default is "%s / %s" +// Second string will be used when total <= 0. Default is "%[1]s" +// In template use as follows: {{counters .}} or {{counters . "%s/%s"}} or {{counters . "%s/%s" "%s/?"}} +var ElementCounters ElementFunc = func(state *State, args ...string) string { + var f string + if state.Total() > 0 { + f = argsHelper(args).getNotEmptyOr(0, "%s / %s") + } else { + f = argsHelper(args).getNotEmptyOr(1, "%[1]s") + } + return fmt.Sprintf(f, state.Format(state.Value()), state.Format(state.Total())) +} + +type elementKey int + +const ( + barObj elementKey = iota + speedObj + cycleObj +) + +type bar struct { + eb [5][]byte // elements in bytes + cc [5]int // cell counts + buf *bytes.Buffer +} + +func (p *bar) write(state *State, eln, width int) int { + repeat := width / p.cc[eln] + for i := 0; i < repeat; i++ { + p.buf.Write(p.eb[eln]) + } + StripStringToBuffer(string(p.eb[eln]), width%p.cc[eln], p.buf) + return width +} + +func getProgressObj(state *State, args ...string) (p *bar) { + var ok bool + if p, ok = state.Get(barObj).(*bar); !ok { + p = &bar{ + buf: bytes.NewBuffer(nil), + } + state.Set(barObj, p) + } + argsH := argsHelper(args) + for i := range p.eb { + arg := argsH.getNotEmptyOr(i, defaultBarEls[i]) + if string(p.eb[i]) != arg { + p.cc[i] = CellCount(arg) + p.eb[i] = []byte(arg) + if p.cc[i] == 0 { + p.cc[i] = 1 + p.eb[i] = []byte(" ") + } + } + } + return +} + +// ElementBar make progress bar view [-->__] +// Optionally can take up to 5 string arguments. Defaults is "[", "-", ">", "_", "]" +// In template use as follows: {{bar . }} or {{bar . "<" "oOo" "|" "~" ">"}} +// Color args: {{bar . (red "[") (green "-") ... +var ElementBar ElementFunc = func(state *State, args ...string) string { + // init + var p = getProgressObj(state, args...) + + total, value := state.Total(), state.Value() + if total < 0 { + total = -total + } + if value < 0 { + value = -value + } + + // check for overflow + if total != 0 && value > total { + total = value + } + + p.buf.Reset() + + var widthLeft = state.AdaptiveElWidth() + if widthLeft <= 0 || !state.IsAdaptiveWidth() { + widthLeft = 30 + } + + // write left border + if p.cc[0] < widthLeft { + widthLeft -= p.write(state, 0, p.cc[0]) + } else { + p.write(state, 0, widthLeft) + return p.buf.String() + } + + // check right border size + if p.cc[4] < widthLeft { + // write later + widthLeft -= p.cc[4] + } else { + p.write(state, 4, widthLeft) + return p.buf.String() + } + + var curCount int + + if total > 0 { + // calculate count of currenct space + curCount = int(math.Ceil((float64(value) / float64(total)) * float64(widthLeft))) + } + + // write bar + if total == value && state.IsFinished() { + widthLeft -= p.write(state, 1, curCount) + } else if toWrite := curCount - p.cc[2]; toWrite > 0 { + widthLeft -= p.write(state, 1, toWrite) + widthLeft -= p.write(state, 2, p.cc[2]) + } else if curCount > 0 { + widthLeft -= p.write(state, 2, curCount) + } + if widthLeft > 0 { + widthLeft -= p.write(state, 3, widthLeft) + } + // write right border + p.write(state, 4, p.cc[4]) + // cut result and return string + return p.buf.String() +} + +// ElementRemainingTime calculates remaining time based on speed (EWMA) +// Optionally can take one or two string arguments. +// First string will be used as value for format time duration string, default is "%s". +// Second string will be used when bar finished and value indicates elapsed time, default is "%s" +// Third string will be used when value not available, default is "?" +// In template use as follows: {{rtime .}} or {{rtime . "%s remain"}} or {{rtime . "%s remain" "%s total" "???"}} +var ElementRemainingTime ElementFunc = func(state *State, args ...string) string { + var rts string + sp := getSpeedObj(state).value(state) + if !state.IsFinished() { + if sp > 0 { + remain := float64(state.Total() - state.Value()) + remainDur := time.Duration(remain/sp) * time.Second + rts = remainDur.String() + } else { + return argsHelper(args).getOr(2, "?") + } + } else { + rts = state.Time().Truncate(time.Second).Sub(state.StartTime().Truncate(time.Second)).String() + return fmt.Sprintf(argsHelper(args).getOr(1, "%s"), rts) + } + return fmt.Sprintf(argsHelper(args).getOr(0, "%s"), rts) +} + +// ElementElapsedTime shows elapsed time +// Optionally cat take one argument - it's format for time string. +// In template use as follows: {{etime .}} or {{etime . "%s elapsed"}} +var ElementElapsedTime ElementFunc = func(state *State, args ...string) string { + etm := state.Time().Truncate(time.Second).Sub(state.StartTime().Truncate(time.Second)) + return fmt.Sprintf(argsHelper(args).getOr(0, "%s"), etm.String()) +} + +// ElementString get value from bar by given key and print them +// bar.Set("myKey", "string to print") +// In template use as follows: {{string . "myKey"}} +var ElementString ElementFunc = func(state *State, args ...string) string { + if len(args) == 0 { + return "" + } + v := state.Get(args[0]) + if v == nil { + return "" + } + return fmt.Sprint(v) +} + +// ElementCycle return next argument for every call +// In template use as follows: {{cycle . "1" "2" "3"}} +// Or mix width other elements: {{ bar . "" "" (cycle . "↖" "↗" "↘" "↙" )}} +var ElementCycle ElementFunc = func(state *State, args ...string) string { + if len(args) == 0 { + return "" + } + n, _ := state.Get(cycleObj).(int) + if n >= len(args) { + n = 0 + } + state.Set(cycleObj, n+1) + return args[n] +} diff --git a/vendor/github.com/cheggaaa/pb/element_test.go b/vendor/github.com/cheggaaa/pb/element_test.go new file mode 100644 index 000000000..d572c4a6a --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/element_test.go @@ -0,0 +1,278 @@ +package pb + +import ( + "fmt" + "strings" + "testing" + "time" + + "gopkg.in/fatih/color.v1" +) + +func testState(total, value int64, maxWidth int, bools ...bool) (s *State) { + s = &State{ + total: total, + current: value, + adaptiveElWidth: maxWidth, + ProgressBar: new(ProgressBar), + } + if len(bools) > 0 { + s.Set(Bytes, bools[0]) + } + if len(bools) > 1 && bools[1] { + s.adaptive = true + } + return +} + +func testElementBarString(t *testing.T, state *State, el Element, want string, args ...string) { + if state.ProgressBar == nil { + state.ProgressBar = new(ProgressBar) + } + res := el.ProgressElement(state, args...) + if res != want { + t.Errorf("Unexpected result: '%s'; want: '%s'", res, want) + } + if state.IsAdaptiveWidth() && state.AdaptiveElWidth() != CellCount(res) { + t.Errorf("Unepected width: %d; want: %d", CellCount(res), state.AdaptiveElWidth()) + } +} + +func TestElementPercent(t *testing.T) { + testElementBarString(t, testState(100, 50, 0), ElementPercent, "50.00%") + testElementBarString(t, testState(100, 50, 0), ElementPercent, "50 percent", "%v percent") + testElementBarString(t, testState(0, 50, 0), ElementPercent, "?%") + testElementBarString(t, testState(0, 50, 0), ElementPercent, "unkn", "%v%%", "unkn") +} + +func TestElementCounters(t *testing.T) { + testElementBarString(t, testState(100, 50, 0), ElementCounters, "50 / 100") + testElementBarString(t, testState(100, 50, 0), ElementCounters, "50 of 100", "%s of %s") + testElementBarString(t, testState(100, 50, 0, true), ElementCounters, "50 B of 100 B", "%s of %s") + testElementBarString(t, testState(100, 50, 0, true), ElementCounters, "50 B / 100 B") + testElementBarString(t, testState(0, 50, 0, true), ElementCounters, "50 B") + testElementBarString(t, testState(0, 50, 0, true), ElementCounters, "50 B / ?", "", "%[1]s / ?") +} + +func TestElementBar(t *testing.T) { + // short + testElementBarString(t, testState(100, 50, 1, false, true), ElementBar, "[") + testElementBarString(t, testState(100, 50, 2, false, true), ElementBar, "[]") + testElementBarString(t, testState(100, 50, 3, false, true), ElementBar, "[>]") + testElementBarString(t, testState(100, 50, 4, false, true), ElementBar, "[>_]") + testElementBarString(t, testState(100, 50, 5, false, true), ElementBar, "[->_]") + // middle + testElementBarString(t, testState(100, 50, 10, false, true), ElementBar, "[--->____]") + testElementBarString(t, testState(100, 50, 10, false, true), ElementBar, "<--->____>", "<", "", "", "", ">") + // finished + st := testState(100, 100, 10, false, true) + st.finished = true + testElementBarString(t, st, ElementBar, "[--------]") + // empty color + st = testState(100, 50, 10, false, true) + st.Set(Terminal, true) + color.NoColor = false + testElementBarString(t, st, ElementBar, " --->____]", color.RedString("%s", "")) + // empty + testElementBarString(t, testState(0, 50, 10, false, true), ElementBar, "[________]") + // full + testElementBarString(t, testState(20, 20, 10, false, true), ElementBar, "[------->]") + // everflow + testElementBarString(t, testState(20, 50, 10, false, true), ElementBar, "[------->]") + // small width + testElementBarString(t, testState(20, 50, 2, false, true), ElementBar, "[]") + testElementBarString(t, testState(20, 50, 1, false, true), ElementBar, "[") + // negative counters + testElementBarString(t, testState(-50, -150, 10, false, true), ElementBar, "[------->]") + testElementBarString(t, testState(-150, -50, 10, false, true), ElementBar, "[-->_____]") + testElementBarString(t, testState(50, -150, 10, false, true), ElementBar, "[------->]") + testElementBarString(t, testState(-50, 150, 10, false, true), ElementBar, "[------->]") + // long entities / unicode + f1 := []string{"進捗|", "многобайт", "active", "пусто", "|end"} + testElementBarString(t, testState(100, 50, 1, false, true), ElementBar, " ", f1...) + testElementBarString(t, testState(100, 50, 3, false, true), ElementBar, "進 ", f1...) + testElementBarString(t, testState(100, 50, 4, false, true), ElementBar, "進捗", f1...) + testElementBarString(t, testState(100, 50, 29, false, true), ElementBar, "進捗|многactiveпустопусто|end", f1...) + testElementBarString(t, testState(100, 50, 11, false, true), ElementBar, "進捗|aп|end", f1...) + + // unicode + f2 := []string{"⚑", "⚒", "⚟", "⟞", "⚐"} + testElementBarString(t, testState(100, 50, 10, false, true), ElementBar, "⚑⚒⚒⚒⚟⟞⟞⟞⟞⚐", f2...) + + // no adaptive + testElementBarString(t, testState(0, 50, 10), ElementBar, "[____________________________]") + + var formats = [][]string{ + []string{}, + f1, f2, + } + + // all widths / extreme values + // check for panic and correct width + for _, f := range formats { + for tt := int64(-2); tt < 12; tt++ { + for v := int64(-2); v < 12; v++ { + state := testState(tt, v, 0, false, true) + for w := -2; w < 20; w++ { + state.adaptiveElWidth = w + res := ElementBar(state, f...) + var we = w + if we <= 0 { + we = 30 + } + if CellCount(res) != we { + t.Errorf("Unexpected len(%d): '%s'", we, res) + } + } + } + } + } +} + +func TestElementSpeed(t *testing.T) { + var state = testState(1000, 0, 0, false) + state.time = time.Now() + for i := int64(0); i < 10; i++ { + state.id = uint64(i) + 1 + state.current += 42 + state.time = state.time.Add(time.Second) + state.finished = i == 9 + if state.finished { + state.current += 100 + } + r := ElementSpeed(state) + r2 := ElementSpeed(state) + if r != r2 { + t.Errorf("Must be the same: '%s' vs '%s'", r, r2) + } + if i < 1 { + // do not calc first result + if w := "? p/s"; r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + } else if state.finished { + if w := "58 p/s"; r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + state.time = state.time.Add(-time.Hour) + r = ElementSpeed(state) + if w := "? p/s"; r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + } else { + if w := "42 p/s"; r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + } + } +} + +func TestElementRemainingTime(t *testing.T) { + var state = testState(100, 0, 0, false) + state.time = time.Now() + state.startTime = state.time + for i := int64(0); i < 10; i++ { + state.id = uint64(i) + 1 + state.time = state.time.Add(time.Second) + state.finished = i == 9 + r := ElementRemainingTime(state) + if i < 1 { + // do not calc first two results + if w := "?"; r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + } else if state.finished { + // final elapsed time + if w := "10s"; r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + } else { + w := fmt.Sprintf("%ds", 10-i) + if r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + } + state.current += 10 + } +} + +func TestElementElapsedTime(t *testing.T) { + var state = testState(1000, 0, 0, false) + state.startTime = time.Now() + state.time = state.startTime + for i := int64(0); i < 10; i++ { + r := ElementElapsedTime(state) + if w := fmt.Sprintf("%ds", i); r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + state.time = state.time.Add(time.Second) + } +} + +func TestElementString(t *testing.T) { + var state = testState(0, 0, 0, false) + testElementBarString(t, state, ElementString, "", "myKey") + state.Set("myKey", "my value") + testElementBarString(t, state, ElementString, "my value", "myKey") + state.Set("myKey", "my value1") + testElementBarString(t, state, ElementString, "my value1", "myKey") + testElementBarString(t, state, ElementString, "") +} + +func TestElementCycle(t *testing.T) { + var state = testState(0, 0, 0, false) + testElementBarString(t, state, ElementCycle, "") + testElementBarString(t, state, ElementCycle, "1", "1", "2", "3") + testElementBarString(t, state, ElementCycle, "2", "1", "2", "3") + testElementBarString(t, state, ElementCycle, "3", "1", "2", "3") + testElementBarString(t, state, ElementCycle, "1", "1", "2", "3") + testElementBarString(t, state, ElementCycle, "2", "1", "2") + testElementBarString(t, state, ElementCycle, "1", "1", "2") +} + +func TestAdaptiveWrap(t *testing.T) { + var state = testState(0, 0, 0, false) + state.id = 1 + state.Set("myKey", "my value") + el := adaptiveWrap(ElementString) + testElementBarString(t, state, el, adElPlaceholder, "myKey") + if v := state.recalc[0].ProgressElement(state); v != "my value" { + t.Errorf("Unexpected result: %s", v) + } + state.id = 2 + testElementBarString(t, state, el, adElPlaceholder, "myKey1") + state.Set("myKey", "my value1") + if v := state.recalc[0].ProgressElement(state); v != "my value1" { + t.Errorf("Unexpected result: %s", v) + } +} + +func TestRegisterElement(t *testing.T) { + var testEl ElementFunc = func(state *State, args ...string) string { + return strings.Repeat("*", state.AdaptiveElWidth()) + } + RegisterElement("testEl", testEl, true) + result := ProgressBarTemplate(`{{testEl . }}`).New(0).SetWidth(5).String() + if result != "*****" { + t.Errorf("Unexpected result: '%v'", result) + } +} + +func BenchmarkBar(b *testing.B) { + var formats = map[string][]string{ + "simple": []string{".", ".", ".", ".", "."}, + "unicode": []string{"⚑", "⚒", "⚟", "⟞", "⚐"}, + "color": []string{color.RedString("%s", "."), color.RedString("%s", "."), color.RedString("%s", "."), color.RedString("%s", "."), color.RedString("%s", ".")}, + "long": []string{"..", "..", "..", "..", ".."}, + "longunicode": []string{"⚑⚑", "⚒⚒", "⚟⚟", "⟞⟞", "⚐⚐"}, + } + for name, args := range formats { + state := testState(100, 50, 100, false, true) + b.Run(name, func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + ElementBar(state, args...) + } + }) + } +} diff --git a/vendor/github.com/cheggaaa/pb/pb.go b/vendor/github.com/cheggaaa/pb/pb.go new file mode 100644 index 000000000..c8e7b52ae --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/pb.go @@ -0,0 +1,540 @@ +package pb + +import ( + "bytes" + "fmt" + "io" + "os" + "strconv" + "strings" + "sync" + "sync/atomic" + "text/template" + "time" + + "gopkg.in/cheggaaa/pb.v2/termutil" + "gopkg.in/mattn/go-colorable.v0" + "gopkg.in/mattn/go-isatty.v0" +) + +// Version of ProgressBar library +const Version = "2.0.6" + +type key int + +const ( + // Bytes means we're working with byte sizes. Numbers will print as Kb, Mb, etc + // bar.Set(pb.Bytes, true) + Bytes key = 1 << iota + + // Terminal means we're will print to terminal and can use ascii sequences + // Also we're will try to use terminal width + Terminal + + // Static means progress bar will not update automaticly + Static + + // ReturnSymbol - by default in terminal mode it's '\r' + ReturnSymbol + + // Color by default is true when output is tty, but you can set to false for disabling colors + Color +) + +const ( + defaultBarWidth = 100 + defaultRefreshRate = time.Millisecond * 200 +) + +// New creates new ProgressBar object +func New(total int) *ProgressBar { + return New64(int64(total)) +} + +// New64 creates new ProgressBar object using int64 as total +func New64(total int64) *ProgressBar { + pb := new(ProgressBar) + return pb.SetTotal(total) +} + +// StartNew starts new ProgressBar with Default template +func StartNew(total int) *ProgressBar { + return New(total).Start() +} + +// Start64 starts new ProgressBar with Default template. Using int64 as total. +func Start64(total int64) *ProgressBar { + return New64(total).Start() +} + +var ( + terminalWidth = termutil.TerminalWidth + isTerminal = isatty.IsTerminal + isCygwinTerminal = isatty.IsCygwinTerminal +) + +// ProgressBar is the main object of bar +type ProgressBar struct { + current, total int64 + width int + mu sync.RWMutex + rm sync.Mutex + vars map[interface{}]interface{} + elements map[string]Element + output io.Writer + coutput io.Writer + nocoutput io.Writer + startTime time.Time + refreshRate time.Duration + tmpl *template.Template + state *State + buf *bytes.Buffer + ticker *time.Ticker + finish chan struct{} + finished bool + configured bool + err error +} + +func (pb *ProgressBar) configure() { + if pb.configured { + return + } + pb.configured = true + + if pb.vars == nil { + pb.vars = make(map[interface{}]interface{}) + } + if pb.output == nil { + pb.output = os.Stderr + } + + if pb.tmpl == nil { + pb.tmpl, pb.err = getTemplate(string(Default)) + if pb.err != nil { + return + } + } + if pb.vars[Terminal] == nil { + if f, ok := pb.output.(*os.File); ok { + if isTerminal(f.Fd()) || isCygwinTerminal(f.Fd()) { + pb.vars[Terminal] = true + } + } + } + if pb.vars[ReturnSymbol] == nil { + if tm, ok := pb.vars[Terminal].(bool); ok && tm { + pb.vars[ReturnSymbol] = "\r" + } + } + if pb.vars[Color] == nil { + if tm, ok := pb.vars[Terminal].(bool); ok && tm { + pb.vars[Color] = true + } + } + if pb.refreshRate == 0 { + pb.refreshRate = defaultRefreshRate + } + if f, ok := pb.output.(*os.File); ok { + pb.coutput = colorable.NewColorable(f) + } else { + pb.coutput = pb.output + } + pb.nocoutput = colorable.NewNonColorable(pb.output) +} + +// Start starts the bar +func (pb *ProgressBar) Start() *ProgressBar { + pb.mu.Lock() + defer pb.mu.Unlock() + if pb.finish != nil { + return pb + } + pb.configure() + pb.finished = false + pb.state = nil + pb.startTime = time.Now() + if st, ok := pb.vars[Static].(bool); ok && st { + return pb + } + pb.finish = make(chan struct{}) + pb.ticker = time.NewTicker(pb.refreshRate) + go pb.writer(pb.finish) + return pb +} + +func (pb *ProgressBar) writer(finish chan struct{}) { + for { + select { + case <-pb.ticker.C: + pb.write(false) + case <-finish: + pb.ticker.Stop() + pb.write(true) + finish <- struct{}{} + return + } + } +} + +// Write performs write to the output +func (pb *ProgressBar) Write() *ProgressBar { + pb.mu.RLock() + finished := pb.finished + pb.mu.RUnlock() + pb.write(finished) + return pb +} + +func (pb *ProgressBar) write(finish bool) { + result, width := pb.render() + if pb.Err() != nil { + return + } + if pb.GetBool(Terminal) { + if r := (width - CellCount(result)); r > 0 { + result += strings.Repeat(" ", r) + } + } + if ret, ok := pb.Get(ReturnSymbol).(string); ok { + result = ret + result + if finish && ret == "\r" { + result += "\n" + } + } + if pb.GetBool(Color) { + pb.coutput.Write([]byte(result)) + } else { + pb.nocoutput.Write([]byte(result)) + } +} + +// Total return current total bar value +func (pb *ProgressBar) Total() int64 { + return atomic.LoadInt64(&pb.total) +} + +// SetTotal sets the total bar value +func (pb *ProgressBar) SetTotal(value int64) *ProgressBar { + atomic.StoreInt64(&pb.total, value) + return pb +} + +// SetCurrent sets the current bar value +func (pb *ProgressBar) SetCurrent(value int64) *ProgressBar { + atomic.StoreInt64(&pb.current, value) + return pb +} + +// Current return current bar value +func (pb *ProgressBar) Current() int64 { + return atomic.LoadInt64(&pb.current) +} + +// Add adding given int64 value to bar value +func (pb *ProgressBar) Add64(value int64) *ProgressBar { + atomic.AddInt64(&pb.current, value) + return pb +} + +// Add adding given int value to bar value +func (pb *ProgressBar) Add(value int) *ProgressBar { + return pb.Add64(int64(value)) +} + +// Increment atomically increments the progress +func (pb *ProgressBar) Increment() *ProgressBar { + return pb.Add64(1) +} + +// Set sets any value by any key +func (pb *ProgressBar) Set(key, value interface{}) *ProgressBar { + pb.mu.Lock() + defer pb.mu.Unlock() + if pb.vars == nil { + pb.vars = make(map[interface{}]interface{}) + } + pb.vars[key] = value + return pb +} + +// Get return value by key +func (pb *ProgressBar) Get(key interface{}) interface{} { + pb.mu.RLock() + defer pb.mu.RUnlock() + if pb.vars == nil { + return nil + } + return pb.vars[key] +} + +// GetBool return value by key and try to convert there to boolean +// If value doesn't set or not boolean - return false +func (pb *ProgressBar) GetBool(key interface{}) bool { + if v, ok := pb.Get(key).(bool); ok { + return v + } + return false +} + +// SetWidth sets the bar width +// When given value <= 0 would be using the terminal width (if possible) or default value. +func (pb *ProgressBar) SetWidth(width int) *ProgressBar { + pb.mu.Lock() + pb.width = width + pb.mu.Unlock() + return pb +} + +// Width return the bar width +// It's current terminal width or settled over 'SetWidth' value. +func (pb *ProgressBar) Width() (width int) { + defer func() { + if r := recover(); r != nil { + width = defaultBarWidth + } + }() + pb.mu.RLock() + width = pb.width + pb.mu.RUnlock() + if width <= 0 { + var err error + if width, err = terminalWidth(); err != nil { + return defaultBarWidth + } + } + return +} + +func (pb *ProgressBar) SetRefreshRate(dur time.Duration) *ProgressBar { + pb.mu.Lock() + if dur > 0 { + pb.refreshRate = dur + } + pb.mu.Unlock() + return pb +} + +// SetWriter sets the io.Writer. Bar will write in this writer +// By default this is os.Stderr +func (pb *ProgressBar) SetWriter(w io.Writer) *ProgressBar { + pb.mu.Lock() + pb.output = w + pb.configured = false + pb.configure() + pb.mu.Unlock() + return pb +} + +// StartTime return the time when bar started +func (pb *ProgressBar) StartTime() time.Time { + pb.mu.RLock() + defer pb.mu.RUnlock() + return pb.startTime +} + +// Format convert int64 to string according to the current settings +func (pb *ProgressBar) Format(v int64) string { + if pb.GetBool(Bytes) { + return formatBytes(v) + } + return strconv.FormatInt(v, 10) +} + +// Finish stops the bar +func (pb *ProgressBar) Finish() *ProgressBar { + pb.mu.Lock() + if pb.finished { + pb.mu.Unlock() + return pb + } + finishChan := pb.finish + pb.finished = true + pb.mu.Unlock() + if finishChan != nil { + finishChan <- struct{}{} + <-finishChan + pb.mu.Lock() + pb.finish = nil + pb.mu.Unlock() + } + return pb +} + +// IsStarted indicates progress bar state +func (pb *ProgressBar) IsStarted() bool { + pb.mu.RLock() + defer pb.mu.RUnlock() + return pb.finish != nil +} + +// SetTemplateString sets ProgressBar tempate string and parse it +func (pb *ProgressBar) SetTemplateString(tmpl string) *ProgressBar { + pb.mu.Lock() + defer pb.mu.Unlock() + pb.tmpl, pb.err = getTemplate(tmpl) + return pb +} + +// SetTemplateString sets ProgressBarTempate and parse it +func (pb *ProgressBar) SetTemplate(tmpl ProgressBarTemplate) *ProgressBar { + return pb.SetTemplateString(string(tmpl)) +} + +// NewProxyReader creates a wrapper for given reader, but with progress handle +// Takes io.Reader or io.ReadCloser +// Also, it automatically switches progress bar to handle units as bytes +func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader { + pb.Set(Bytes, true) + return &Reader{r, pb} +} + +func (pb *ProgressBar) render() (result string, width int) { + defer func() { + if r := recover(); r != nil { + pb.SetErr(fmt.Errorf("render panic: %v", r)) + } + }() + pb.rm.Lock() + defer pb.rm.Unlock() + pb.mu.Lock() + pb.configure() + if pb.state == nil { + pb.state = &State{ProgressBar: pb} + pb.buf = bytes.NewBuffer(nil) + } + if pb.startTime.IsZero() { + pb.startTime = time.Now() + } + pb.state.id++ + pb.state.finished = pb.finished + pb.state.time = time.Now() + pb.mu.Unlock() + + pb.state.width = pb.Width() + width = pb.state.width + pb.state.total = pb.Total() + pb.state.current = pb.Current() + pb.buf.Reset() + + if e := pb.tmpl.Execute(pb.buf, pb.state); e != nil { + pb.SetErr(e) + return "", 0 + } + + result = pb.buf.String() + + aec := len(pb.state.recalc) + if aec == 0 { + // no adaptive elements + return + } + + staticWidth := CellCount(result) - (aec * adElPlaceholderLen) + + if pb.state.Width()-staticWidth <= 0 { + result = strings.Replace(result, adElPlaceholder, "", -1) + result = StripString(result, pb.state.Width()) + } else { + pb.state.adaptiveElWidth = (width - staticWidth) / aec + for _, el := range pb.state.recalc { + result = strings.Replace(result, adElPlaceholder, el.ProgressElement(pb.state), 1) + } + } + pb.state.recalc = pb.state.recalc[:0] + return +} + +// SetErr sets error to the ProgressBar +// Error will be available over Err() +func (pb *ProgressBar) SetErr(err error) *ProgressBar { + pb.mu.Lock() + pb.err = err + pb.mu.Unlock() + return pb +} + +// Err return possible error +// When all ok - will be nil +// May contain template.Execute errors +func (pb *ProgressBar) Err() error { + pb.mu.RLock() + defer pb.mu.RUnlock() + return pb.err +} + +// String return currrent string representation of ProgressBar +func (pb *ProgressBar) String() string { + res, _ := pb.render() + return res +} + +// ProgressElement implements Element interface +func (pb *ProgressBar) ProgressElement(s *State, args ...string) string { + if s.IsAdaptiveWidth() { + pb.SetWidth(s.AdaptiveElWidth()) + } + return pb.String() +} + +// State represents the current state of bar +// Need for bar elements +type State struct { + *ProgressBar + + id uint64 + total, current int64 + width, adaptiveElWidth int + finished, adaptive bool + time time.Time + + recalc []Element +} + +// Id it's the current state identifier +// - incremental +// - starts with 1 +// - resets after finish/start +func (s *State) Id() uint64 { + return s.id +} + +// Total it's bar int64 total +func (s *State) Total() int64 { + return s.total +} + +// Value it's current value +func (s *State) Value() int64 { + return s.current +} + +// Width of bar +func (s *State) Width() int { + return s.width +} + +// AdaptiveElWidth - adaptive elements must return string with given cell count (when AdaptiveElWidth > 0) +func (s *State) AdaptiveElWidth() int { + return s.adaptiveElWidth +} + +// IsAdaptiveWidth returns true when element must be shown as adaptive +func (s *State) IsAdaptiveWidth() bool { + return s.adaptive +} + +// IsFinished return true when bar is finished +func (s *State) IsFinished() bool { + return s.finished +} + +// IsFirst return true only in first render +func (s *State) IsFirst() bool { + return s.id == 1 +} + +// Time when state was created +func (s *State) Time() time.Time { + return s.time +} diff --git a/vendor/github.com/cheggaaa/pb/pb_test.go b/vendor/github.com/cheggaaa/pb/pb_test.go new file mode 100644 index 000000000..929778466 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/pb_test.go @@ -0,0 +1,219 @@ +package pb + +import ( + "bytes" + "errors" + "fmt" + "strings" + "testing" + "time" + + "gopkg.in/fatih/color.v1" +) + +func TestPBBasic(t *testing.T) { + bar := new(ProgressBar) + var a, e int64 + if a, e = bar.Total(), 0; a != e { + t.Errorf("Unexpected total: actual: %v; expected: %v", a, e) + } + if a, e = bar.Current(), 0; a != e { + t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) + } + bar.SetCurrent(10).SetTotal(20) + if a, e = bar.Total(), 20; a != e { + t.Errorf("Unexpected total: actual: %v; expected: %v", a, e) + } + if a, e = bar.Current(), 10; a != e { + t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) + } + bar.Add(5) + if a, e = bar.Current(), 15; a != e { + t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) + } + bar.Increment() + if a, e = bar.Current(), 16; a != e { + t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) + } +} + +func TestPBWidth(t *testing.T) { + terminalWidth = func() (int, error) { + return 50, nil + } + // terminal width + bar := new(ProgressBar) + if a, e := bar.Width(), 50; a != e { + t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) + } + // terminal width error + terminalWidth = func() (int, error) { + return 0, errors.New("test error") + } + if a, e := bar.Width(), defaultBarWidth; a != e { + t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) + } + // terminal width panic + terminalWidth = func() (int, error) { + panic("test") + return 0, nil + } + if a, e := bar.Width(), defaultBarWidth; a != e { + t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) + } + // set negative terminal width + bar.SetWidth(-42) + if a, e := bar.Width(), defaultBarWidth; a != e { + t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) + } + // set terminal width + bar.SetWidth(42) + if a, e := bar.Width(), 42; a != e { + t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) + } +} + +func TestPBTemplate(t *testing.T) { + bar := new(ProgressBar) + result := bar.SetTotal(100).SetCurrent(50).SetWidth(40).String() + expected := "50 / 100 [------->________] 50.00% ? p/s" + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) + } + + // check strip + result = bar.SetWidth(8).String() + expected = "50 / 100" + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) + } + + // invalid template + for _, invalidTemplate := range []string{ + `{{invalid template`, `{{speed}}`, + } { + bar.SetTemplateString(invalidTemplate) + result = bar.String() + expected = "" + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) + } + if err := bar.Err(); err == nil { + t.Errorf("Must be error") + } + } + + // simple template without adaptive elemnts + bar.SetTemplateString(`{{counters . }}`) + result = bar.String() + expected = "50 / 100" + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) + } +} + +func TestPBStartFinish(t *testing.T) { + bar := ProgressBarTemplate(`{{counters . }}`).New(0) + for i := int64(0); i < 2; i++ { + if bar.IsStarted() { + t.Error("Must be false") + } + var buf = bytes.NewBuffer(nil) + bar.SetTotal(100). + SetCurrent(int64(i)). + SetWidth(7). + Set(Terminal, true). + SetWriter(buf). + SetRefreshRate(time.Millisecond * 20). + Start() + if !bar.IsStarted() { + t.Error("Must be true") + } + time.Sleep(time.Millisecond * 100) + bar.Finish() + if buf.Len() == 0 { + t.Error("no writes") + } + var resultsString = strings.TrimPrefix(buf.String(), "\r") + if !strings.HasSuffix(resultsString, "\n") { + t.Error("No end \\n symb") + } else { + resultsString = resultsString[:len(resultsString)-1] + } + var results = strings.Split(resultsString, "\r") + if len(results) < 3 { + t.Errorf("Unexpected writes count: %v", len(results)) + } + exp := fmt.Sprintf("%d / 100", i) + for i, res := range results { + if res != exp { + t.Errorf("Unexpected result[%d]: '%v'", i, res) + } + } + // test second finish call + bar.Finish() + } +} + +func TestPBFlags(t *testing.T) { + // Static + color.NoColor = false + buf := bytes.NewBuffer(nil) + bar := ProgressBarTemplate(`{{counters . | red}}`).New(100) + bar.Set(Static, true).SetCurrent(50).SetWidth(10).SetWriter(buf).Start() + if bar.IsStarted() { + t.Error("Must be false") + } + bar.Write() + result := buf.String() + expected := "50 / 100" + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected) + } + if !bar.state.IsFirst() { + t.Error("must be true") + } + // Color + bar.Set(Color, true) + buf.Reset() + bar.Write() + result = buf.String() + expected = color.RedString("50 / 100") + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected) + } + if bar.state.IsFirst() { + t.Error("must be false") + } + // Terminal + bar.Set(Terminal, true).SetWriter(buf) + buf.Reset() + bar.Write() + result = buf.String() + expected = "\r" + color.RedString("50 / 100") + " " + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected) + } +} + +func BenchmarkRender(b *testing.B) { + var formats = []string{ + string(Simple), + string(Default), + string(Full), + `{{string . "prefix" | red}}{{counters . | green}} {{bar . | yellow}} {{percent . | cyan}} {{speed . | cyan}}{{string . "suffix" | cyan}}`, + } + var names = []string{ + "Simple", "Default", "Full", "Color", + } + for i, tmpl := range formats { + bar := new(ProgressBar) + bar.SetTemplateString(tmpl).SetWidth(100) + b.Run(names[i], func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + bar.String() + } + }) + } +} diff --git a/vendor/github.com/cheggaaa/pb/preset.go b/vendor/github.com/cheggaaa/pb/preset.go new file mode 100644 index 000000000..1934c0e88 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/preset.go @@ -0,0 +1,17 @@ +package pb + +import () + +var ( + // Full - preset with all default available elements + // Example: 'Prefix 20/100 [-->______] 20% 1 p/s ETA 1m Suffix' + Full ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }} {{speed . }} {{rtime . "ETA %s"}}{{string . "suffix"}}` + + // Default - preset like Full but without elapsed time + // Example: 'Prefix 20/100 [-->______] 20% 1 p/s ETA 1m Suffix' + Default ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }} {{speed . }}{{string . "suffix"}}` + + // Simple - preset without speed and any timers. Only counters, bar and percents + // Example: 'Prefix 20/100 [-->______] 20% Suffix' + Simple ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }}{{string . "suffix"}}` +) diff --git a/vendor/github.com/cheggaaa/pb/reader.go b/vendor/github.com/cheggaaa/pb/reader.go new file mode 100644 index 000000000..f2e60a09d --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/reader.go @@ -0,0 +1,26 @@ +package pb + +import ( + "io" +) + +// Reader it's a wrapper for given reader, but with progress handle +type Reader struct { + io.Reader + bar *ProgressBar +} + +// Read reads bytes from wrapped reader and add amount of bytes to progress bar +func (r *Reader) Read(p []byte) (n int, err error) { + n, err = r.Reader.Read(p) + r.bar.Add(n) + return +} + +// Close the wrapped reader when it implements io.Closer +func (r *Reader) Close() (err error) { + if closer, ok := r.Reader.(io.Closer); ok { + return closer.Close() + } + return +} diff --git a/vendor/github.com/cheggaaa/pb/reader_test.go b/vendor/github.com/cheggaaa/pb/reader_test.go new file mode 100644 index 000000000..a5d745a0b --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/reader_test.go @@ -0,0 +1,60 @@ +package pb + +import ( + "testing" +) + +func TestPBProxyReader(t *testing.T) { + bar := new(ProgressBar) + if bar.GetBool(Bytes) { + t.Errorf("By default bytes must be false") + } + + testReader := new(testReaderCloser) + proxyReader := bar.NewProxyReader(testReader) + + if !bar.GetBool(Bytes) { + t.Errorf("Bytes must be true after call NewProxyReader") + } + + for i := 0; i < 10; i++ { + buf := make([]byte, 10) + n, e := proxyReader.Read(buf) + if e != nil { + t.Errorf("Proxy reader return err: %v", e) + } + if n != len(buf) { + t.Errorf("Proxy reader return unexpected N: %d (wand %d)", n, len(buf)) + } + for _, b := range buf { + if b != 'f' { + t.Errorf("Unexpected read value: %v (want %v)", b, 'f') + } + } + if want := int64((i + 1) * len(buf)); bar.Current() != want { + t.Errorf("Unexpected bar current value: %d (want %d)", bar.Current(), want) + } + } + proxyReader.Close() + if !testReader.closed { + t.Errorf("Reader must be closed after call ProxyReader.Close") + } + proxyReader.Reader = nil + proxyReader.Close() +} + +type testReaderCloser struct { + closed bool +} + +func (tr *testReaderCloser) Read(p []byte) (n int, err error) { + for i := range p { + p[i] = 'f' + } + return len(p), nil +} + +func (tr *testReaderCloser) Close() (err error) { + tr.closed = true + return +} diff --git a/vendor/github.com/cheggaaa/pb/speed.go b/vendor/github.com/cheggaaa/pb/speed.go new file mode 100644 index 000000000..4cf34b1d1 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/speed.go @@ -0,0 +1,83 @@ +package pb + +import ( + "fmt" + "math" + "time" + + "gopkg.in/VividCortex/ewma.v1" +) + +var speedAddLimit = time.Second / 2 + +type speed struct { + ewma ewma.MovingAverage + lastStateId uint64 + prevValue, startValue int64 + prevTime, startTime time.Time +} + +func (s *speed) value(state *State) float64 { + if s.ewma == nil { + s.ewma = ewma.NewMovingAverage() + } + if state.IsFirst() || state.Id() < s.lastStateId { + s.reset(state) + return 0 + } + if state.Id() == s.lastStateId { + return s.ewma.Value() + } + if state.IsFinished() { + return s.absValue(state) + } + dur := state.Time().Sub(s.prevTime) + if dur < speedAddLimit { + return s.ewma.Value() + } + diff := math.Abs(float64(state.Value() - s.prevValue)) + lastSpeed := diff / dur.Seconds() + s.prevTime = state.Time() + s.prevValue = state.Value() + s.lastStateId = state.Id() + s.ewma.Add(lastSpeed) + return s.ewma.Value() +} + +func (s *speed) reset(state *State) { + s.lastStateId = state.Id() + s.startTime = state.Time() + s.prevTime = state.Time() + s.startValue = state.Value() + s.prevValue = state.Value() + s.ewma = ewma.NewMovingAverage() +} + +func (s *speed) absValue(state *State) float64 { + if dur := state.Time().Sub(s.startTime); dur > 0 { + return float64(state.Value()) / dur.Seconds() + } + return 0 +} + +func getSpeedObj(state *State) (s *speed) { + if sObj, ok := state.Get(speedObj).(*speed); ok { + return sObj + } + s = new(speed) + state.Set(speedObj, s) + return +} + +// ElementSpeed calculates current speed by EWMA +// Optionally can take one or two string arguments. +// First string will be used as value for format speed, default is "%s p/s". +// Second string will be used when speed not available, default is "? p/s" +// In template use as follows: {{speed .}} or {{speed . "%s per second"}} or {{speed . "%s ps" "..."} +var ElementSpeed ElementFunc = func(state *State, args ...string) string { + sp := getSpeedObj(state).value(state) + if sp == 0 { + return argsHelper(args).getNotEmptyOr(1, "? p/s") + } + return fmt.Sprintf(argsHelper(args).getNotEmptyOr(0, "%s p/s"), state.Format(int64(round(sp)))) +} diff --git a/vendor/github.com/cheggaaa/pb/template.go b/vendor/github.com/cheggaaa/pb/template.go new file mode 100644 index 000000000..98aeea44e --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/template.go @@ -0,0 +1,87 @@ +package pb + +import ( + "math/rand" + "sync" + "text/template" + + "gopkg.in/fatih/color.v1" +) + +// ProgressBarTemplate that template string +type ProgressBarTemplate string + +// New creates new bar from template +func (pbt ProgressBarTemplate) New(total int) *ProgressBar { + return New(total).SetTemplate(pbt) +} + +// Start64 create and start new bar with given int64 total value +func (pbt ProgressBarTemplate) Start64(total int64) *ProgressBar { + return New64(total).SetTemplate(pbt).Start() +} + +// Start create and start new bar with given int total value +func (pbt ProgressBarTemplate) Start(total int) *ProgressBar { + return pbt.Start64(int64(total)) +} + +var templateCacheMu sync.Mutex +var templateCache = make(map[string]*template.Template) + +var defaultTemplateFuncs = template.FuncMap{ + // colors + "black": color.New(color.FgBlack).SprintFunc(), + "red": color.New(color.FgRed).SprintFunc(), + "green": color.New(color.FgGreen).SprintFunc(), + "yellow": color.New(color.FgYellow).SprintFunc(), + "blue": color.New(color.FgBlue).SprintFunc(), + "magenta": color.New(color.FgMagenta).SprintFunc(), + "cyan": color.New(color.FgCyan).SprintFunc(), + "white": color.New(color.FgWhite).SprintFunc(), + "rndcolor": rndcolor, + "rnd": rnd, +} + +func getTemplate(tmpl string) (t *template.Template, err error) { + templateCacheMu.Lock() + defer templateCacheMu.Unlock() + t = templateCache[tmpl] + if t != nil { + // found in cache + return + } + t = template.New("") + fillTemplateFuncs(t) + _, err = t.Parse(tmpl) + if err != nil { + t = nil + return + } + templateCache[tmpl] = t + return +} + +func fillTemplateFuncs(t *template.Template) { + t.Funcs(defaultTemplateFuncs) + emf := make(template.FuncMap) + elementsM.Lock() + for k, v := range elements { + emf[k] = v + } + elementsM.Unlock() + t.Funcs(emf) + return +} + +func rndcolor(s string) string { + c := rand.Intn(int(color.FgWhite-color.FgBlack)) + int(color.FgBlack) + return color.New(color.Attribute(c)).Sprint(s) +} + +func rnd(args ...string) string { + if len(args) == 0 { + return "" + } + return args[rand.Intn(len(args))] +} diff --git a/vendor/github.com/cheggaaa/pb/template_test.go b/vendor/github.com/cheggaaa/pb/template_test.go new file mode 100644 index 000000000..84022d347 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/template_test.go @@ -0,0 +1,53 @@ +package pb + +import ( + "bytes" + "testing" +) + +func TestProgressBarTemplate(t *testing.T) { + // test New + bar := ProgressBarTemplate(`{{counters . }}`).New(0) + result := bar.String() + expected := "0" + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) + } + if bar.IsStarted() { + t.Error("Must be false") + } + + // test Start + bar = ProgressBarTemplate(`{{counters . }}`).Start(42).SetWriter(bytes.NewBuffer(nil)) + result = bar.String() + expected = "0 / 42" + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) + } + if !bar.IsStarted() { + t.Error("Must be true") + } +} + +func TestTemplateFuncs(t *testing.T) { + var results = make(map[string]int) + for i := 0; i < 100; i++ { + r := rndcolor("s") + results[r] = results[r] + 1 + } + if len(results) < 6 { + t.Errorf("Unexpected rndcolor results count: %v", len(results)) + } + + results = make(map[string]int) + for i := 0; i < 100; i++ { + r := rnd("1", "2", "3") + results[r] = results[r] + 1 + } + if len(results) != 3 { + t.Errorf("Unexpected rnd results count: %v", len(results)) + } + if r := rnd(); r != "" { + t.Errorf("Unexpected rnd result: '%v'", r) + } +} diff --git a/vendor/github.com/cheggaaa/pb/termutil/term.go b/vendor/github.com/cheggaaa/pb/termutil/term.go new file mode 100644 index 000000000..b53b4b24a --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/termutil/term.go @@ -0,0 +1,57 @@ +package termutil + +import ( + "errors" + "os" + "os/signal" + "sync" + "syscall" +) + +var echoLocked bool +var echoLockMutex sync.Mutex +var errLocked = errors.New("terminal locked") + +// RawModeOn switches terminal to raw mode +func RawModeOn() (quit chan struct{}, err error) { + echoLockMutex.Lock() + defer echoLockMutex.Unlock() + if echoLocked { + err = errLocked + return + } + if err = lockEcho(); err != nil { + return + } + echoLocked = true + quit = make(chan struct{}, 1) + go catchTerminate(quit) + return +} + +// RawModeOff restore previous terminal state +func RawModeOff() (err error) { + echoLockMutex.Lock() + defer echoLockMutex.Unlock() + if !echoLocked { + return + } + if err = unlockEcho(); err != nil { + return + } + echoLocked = false + return +} + +// listen exit signals and restore terminal state +func catchTerminate(quit chan struct{}) { + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL) + defer signal.Stop(sig) + select { + case <-quit: + RawModeOff() + case <-sig: + RawModeOff() + } +} diff --git a/vendor/github.com/cheggaaa/pb/termutil/term_appengine.go b/vendor/github.com/cheggaaa/pb/termutil/term_appengine.go new file mode 100644 index 000000000..4b7b20e6b --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/termutil/term_appengine.go @@ -0,0 +1,11 @@ +// +build appengine + +package termutil + +import "errors" + +// terminalWidth returns width of the terminal, which is not supported +// and should always failed on appengine classic which is a sandboxed PaaS. +func TerminalWidth() (int, error) { + return 0, errors.New("Not supported") +} diff --git a/vendor/github.com/cheggaaa/pb/termutil/term_bsd.go b/vendor/github.com/cheggaaa/pb/termutil/term_bsd.go new file mode 100644 index 000000000..272659a12 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/termutil/term_bsd.go @@ -0,0 +1,9 @@ +// +build darwin freebsd netbsd openbsd dragonfly +// +build !appengine + +package termutil + +import "syscall" + +const ioctlReadTermios = syscall.TIOCGETA +const ioctlWriteTermios = syscall.TIOCSETA diff --git a/vendor/github.com/cheggaaa/pb/termutil/term_linux.go b/vendor/github.com/cheggaaa/pb/termutil/term_linux.go new file mode 100644 index 000000000..2f59e53e1 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/termutil/term_linux.go @@ -0,0 +1,7 @@ +// +build linux +// +build !appengine + +package termutil + +const ioctlReadTermios = 0x5401 // syscall.TCGETS +const ioctlWriteTermios = 0x5402 // syscall.TCSETS diff --git a/vendor/github.com/cheggaaa/pb/termutil/term_nix.go b/vendor/github.com/cheggaaa/pb/termutil/term_nix.go new file mode 100644 index 000000000..14277e71f --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/termutil/term_nix.go @@ -0,0 +1,8 @@ +// +build linux darwin freebsd netbsd openbsd dragonfly +// +build !appengine + +package termutil + +import "syscall" + +const sysIoctl = syscall.SYS_IOCTL diff --git a/vendor/github.com/cheggaaa/pb/termutil/term_solaris.go b/vendor/github.com/cheggaaa/pb/termutil/term_solaris.go new file mode 100644 index 000000000..fc96c2b7f --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/termutil/term_solaris.go @@ -0,0 +1,8 @@ +// +build solaris +// +build !appengine + +package termutil + +const ioctlReadTermios = 0x5401 // syscall.TCGETS +const ioctlWriteTermios = 0x5402 // syscall.TCSETS +const sysIoctl = 54 diff --git a/vendor/github.com/cheggaaa/pb/termutil/term_win.go b/vendor/github.com/cheggaaa/pb/termutil/term_win.go new file mode 100644 index 000000000..963158360 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/termutil/term_win.go @@ -0,0 +1,149 @@ +// +build windows + +package termutil + +import ( + "fmt" + "os" + "os/exec" + "strconv" + "syscall" + "unsafe" +) + +var tty = os.Stdin + +var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") + + // GetConsoleScreenBufferInfo retrieves information about the + // specified console screen buffer. + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx + procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") + + // GetConsoleMode retrieves the current input mode of a console's + // input buffer or the current output mode of a console screen buffer. + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx + getConsoleMode = kernel32.NewProc("GetConsoleMode") + + // SetConsoleMode sets the input mode of a console's input buffer + // or the output mode of a console screen buffer. + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx + setConsoleMode = kernel32.NewProc("SetConsoleMode") + + // SetConsoleCursorPosition sets the cursor position in the + // specified console screen buffer. + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx + setConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") + + mingw = isMingw() +) + +type ( + // Defines the coordinates of the upper left and lower right corners + // of a rectangle. + // See + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311(v=vs.85).aspx + smallRect struct { + Left, Top, Right, Bottom int16 + } + + // Defines the coordinates of a character cell in a console screen + // buffer. The origin of the coordinate system (0,0) is at the top, left cell + // of the buffer. + // See + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119(v=vs.85).aspx + coordinates struct { + X, Y int16 + } + + word int16 + + // Contains information about a console screen buffer. + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx + consoleScreenBufferInfo struct { + dwSize coordinates + dwCursorPosition coordinates + wAttributes word + srWindow smallRect + dwMaximumWindowSize coordinates + } +) + +// TerminalWidth returns width of the terminal. +func TerminalWidth() (width int, err error) { + if mingw { + return termWidthTPut() + } + return termWidthCmd() +} + +func termWidthCmd() (width int, err error) { + var info consoleScreenBufferInfo + _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0) + if e != 0 { + return 0, error(e) + } + return int(info.dwSize.X) - 1, nil +} + +func isMingw() bool { + return os.Getenv("MINGW_PREFIX") != "" || os.Getenv("MSYSTEM") == "MINGW64" +} + +func termWidthTPut() (width int, err error) { + // TODO: maybe anybody knows a better way to get it on mintty... + var res []byte + cmd := exec.Command("tput", "cols") + cmd.Stdin = os.Stdin + if res, err = cmd.CombinedOutput(); err != nil { + return 0, fmt.Errorf("%s: %v", string(res), err) + } + if len(res) > 1 { + res = res[:len(res)-1] + } + return strconv.Atoi(string(res)) +} + +func getCursorPos() (pos coordinates, err error) { + var info consoleScreenBufferInfo + _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0) + if e != 0 { + return info.dwCursorPosition, error(e) + } + return info.dwCursorPosition, nil +} + +func setCursorPos(pos coordinates) error { + _, _, e := syscall.Syscall(setConsoleCursorPosition.Addr(), 2, uintptr(syscall.Stdout), uintptr(uint32(uint16(pos.Y))<<16|uint32(uint16(pos.X))), 0) + if e != 0 { + return error(e) + } + return nil +} + +var oldState word + +func lockEcho() (err error) { + if _, _, e := syscall.Syscall(getConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&oldState)), 0); e != 0 { + err = fmt.Errorf("Can't get terminal settings: %v", e) + return + } + + newState := oldState + const ENABLE_ECHO_INPUT = 0x0004 + const ENABLE_LINE_INPUT = 0x0002 + newState = newState & (^(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)) + if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(newState), 0); e != 0 { + err = fmt.Errorf("Can't set terminal settings: %v", e) + return + } + return +} + +func unlockEcho() (err error) { + if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(oldState), 0); e != 0 { + err = fmt.Errorf("Can't set terminal settings") + } + return +} diff --git a/vendor/github.com/cheggaaa/pb/termutil/term_x.go b/vendor/github.com/cheggaaa/pb/termutil/term_x.go new file mode 100644 index 000000000..e2f69b214 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/termutil/term_x.go @@ -0,0 +1,70 @@ +// +build linux darwin freebsd netbsd openbsd solaris dragonfly +// +build !appengine + +package termutil + +import ( + "fmt" + "os" + "syscall" + "unsafe" +) + +var tty *os.File + +type window struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +func init() { + var err error + tty, err = os.Open("/dev/tty") + if err != nil { + tty = os.Stdin + } +} + +// TerminalWidth returns width of the terminal. +func TerminalWidth() (int, error) { + w := new(window) + res, _, err := syscall.Syscall(sysIoctl, + tty.Fd(), + uintptr(syscall.TIOCGWINSZ), + uintptr(unsafe.Pointer(w)), + ) + if int(res) == -1 { + return 0, err + } + return int(w.Col), nil +} + +var oldState syscall.Termios + +func lockEcho() (err error) { + fd := tty.Fd() + if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { + err = fmt.Errorf("Can't get terminal settings: %v", e) + return + } + + newState := oldState + newState.Lflag &^= syscall.ECHO + newState.Lflag |= syscall.ICANON | syscall.ISIG + newState.Iflag |= syscall.ICRNL + if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); e != 0 { + err = fmt.Errorf("Can't set terminal settings: %v", e) + return + } + return +} + +func unlockEcho() (err error) { + fd := tty.Fd() + if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { + err = fmt.Errorf("Can't set terminal settings") + } + return +} diff --git a/vendor/github.com/cheggaaa/pb/util.go b/vendor/github.com/cheggaaa/pb/util.go new file mode 100644 index 000000000..44eedae56 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/util.go @@ -0,0 +1,94 @@ +package pb + +import ( + "bytes" + "fmt" + "gopkg.in/mattn/go-runewidth.v0" + "math" + "regexp" + //"unicode/utf8" +) + +const ( + _KiB = 1024 + _MiB = 1048576 + _GiB = 1073741824 + _TiB = 1099511627776 +) + +var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9]+\x6d") + +func CellCount(s string) int { + n := runewidth.StringWidth(s) + for _, sm := range ctrlFinder.FindAllString(s, -1) { + n -= runewidth.StringWidth(sm) + } + return n +} + +func StripString(s string, w int) string { + l := CellCount(s) + if l <= w { + return s + } + var buf = bytes.NewBuffer(make([]byte, 0, len(s))) + StripStringToBuffer(s, w, buf) + return buf.String() +} + +func StripStringToBuffer(s string, w int, buf *bytes.Buffer) { + var seqs = ctrlFinder.FindAllStringIndex(s, -1) +mainloop: + for i, r := range s { + for _, seq := range seqs { + if i >= seq[0] && i < seq[1] { + buf.WriteRune(r) + continue mainloop + } + } + if rw := CellCount(string(r)); rw <= w { + w -= rw + buf.WriteRune(r) + } else { + break + } + } + for w > 0 { + buf.WriteByte(' ') + w-- + } + return +} + +func round(val float64) (newVal float64) { + roundOn := 0.5 + places := 0 + var round float64 + pow := math.Pow(10, float64(places)) + digit := pow * val + _, div := math.Modf(digit) + if div >= roundOn { + round = math.Ceil(digit) + } else { + round = math.Floor(digit) + } + newVal = round / pow + return +} + +// Convert bytes to human readable string. Like a 2 MiB, 64.2 KiB, 52 B +func formatBytes(i int64) (result string) { + switch { + case i >= _TiB: + result = fmt.Sprintf("%.02f TiB", float64(i)/_TiB) + case i >= _GiB: + result = fmt.Sprintf("%.02f GiB", float64(i)/_GiB) + case i >= _MiB: + result = fmt.Sprintf("%.02f MiB", float64(i)/_MiB) + case i >= _KiB: + result = fmt.Sprintf("%.02f KiB", float64(i)/_KiB) + default: + result = fmt.Sprintf("%d B", i) + } + return +} diff --git a/vendor/github.com/cheggaaa/pb/util_test.go b/vendor/github.com/cheggaaa/pb/util_test.go new file mode 100644 index 000000000..1c7fe7850 --- /dev/null +++ b/vendor/github.com/cheggaaa/pb/util_test.go @@ -0,0 +1,73 @@ +package pb + +import ( + "gopkg.in/fatih/color.v1" + "testing" +) + +var testColorString = color.RedString("red") + + color.GreenString("hello") + + "simple" + + color.WhiteString("進捗") + +func TestUtilCellCount(t *testing.T) { + if e, l := 18, CellCount(testColorString); l != e { + t.Errorf("Invalid length %d, expected %d", l, e) + } +} + +func TestUtilStripString(t *testing.T) { + if r, e := StripString("12345", 4), "1234"; r != e { + t.Errorf("Invalid result '%s', expected '%s'", r, e) + } + + if r, e := StripString("12345", 5), "12345"; r != e { + t.Errorf("Invalid result '%s', expected '%s'", r, e) + } + if r, e := StripString("12345", 10), "12345"; r != e { + t.Errorf("Invalid result '%s', expected '%s'", r, e) + } + + s := color.RedString("1") + "23" + e := color.RedString("1") + "2" + if r := StripString(s, 2); r != e { + t.Errorf("Invalid result '%s', expected '%s'", r, e) + } + return +} + +func TestUtilRound(t *testing.T) { + if v := round(4.4); v != 4 { + t.Errorf("Unexpected result: %v", v) + } + if v := round(4.501); v != 5 { + t.Errorf("Unexpected result: %v", v) + } +} + +func TestUtilFormatBytes(t *testing.T) { + inputs := []struct { + v int64 + e string + }{ + {v: 1000, e: "1000 B"}, + {v: 1024, e: "1.00 KiB"}, + {v: 3*_MiB + 140*_KiB, e: "3.14 MiB"}, + {v: 2 * _GiB, e: "2.00 GiB"}, + {v: 2048 * _GiB, e: "2.00 TiB"}, + } + + for _, input := range inputs { + actual := formatBytes(input.v) + if actual != input.e { + t.Errorf("Expected {%s} was {%s}", input.e, actual) + } + } +} + +func BenchmarkUtilsCellCount(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + CellCount(testColorString) + } +} diff --git a/vendor/github.com/mattn/go-colorable/.travis.yml b/vendor/github.com/mattn/go-colorable/.travis.yml new file mode 100644 index 000000000..98db8f060 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/.travis.yml @@ -0,0 +1,9 @@ +language: go +go: + - tip + +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover +script: + - $HOME/gopath/bin/goveralls -repotoken xnXqRGwgW3SXIguzxf90ZSK1GPYZPaGrw diff --git a/vendor/github.com/mattn/go-colorable/LICENSE b/vendor/github.com/mattn/go-colorable/LICENSE new file mode 100644 index 000000000..91b5cef30 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Yasuhiro Matsumoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/mattn/go-colorable/README.md b/vendor/github.com/mattn/go-colorable/README.md new file mode 100644 index 000000000..56729a92c --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/README.md @@ -0,0 +1,48 @@ +# go-colorable + +[![Godoc Reference](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable) +[![Build Status](https://travis-ci.org/mattn/go-colorable.svg?branch=master)](https://travis-ci.org/mattn/go-colorable) +[![Coverage Status](https://coveralls.io/repos/github/mattn/go-colorable/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-colorable?branch=master) +[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable) + +Colorable writer for windows. + +For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.) +This package is possible to handle escape sequence for ansi color on windows. + +## Too Bad! + +![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png) + + +## So Good! + +![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png) + +## Usage + +```go +logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) +logrus.SetOutput(colorable.NewColorableStdout()) + +logrus.Info("succeeded") +logrus.Warn("not correct") +logrus.Error("something error") +logrus.Fatal("panic") +``` + +You can compile above code on non-windows OSs. + +## Installation + +``` +$ go get github.com/mattn/go-colorable +``` + +# License + +MIT + +# Author + +Yasuhiro Matsumoto (a.k.a mattn) diff --git a/vendor/github.com/mattn/go-colorable/_example/escape-seq/main.go b/vendor/github.com/mattn/go-colorable/_example/escape-seq/main.go new file mode 100644 index 000000000..8cbcb9097 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/_example/escape-seq/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "bufio" + "fmt" + + "github.com/mattn/go-colorable" +) + +func main() { + stdOut := bufio.NewWriter(colorable.NewColorableStdout()) + + fmt.Fprint(stdOut, "\x1B[3GMove to 3rd Column\n") + fmt.Fprint(stdOut, "\x1B[1;2HMove to 2nd Column on 1st Line\n") + stdOut.Flush() +} diff --git a/vendor/github.com/mattn/go-colorable/_example/logrus/main.go b/vendor/github.com/mattn/go-colorable/_example/logrus/main.go new file mode 100644 index 000000000..c569164b2 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/_example/logrus/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "github.com/mattn/go-colorable" + "github.com/sirupsen/logrus" +) + +func main() { + logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) + logrus.SetOutput(colorable.NewColorableStdout()) + + logrus.Info("succeeded") + logrus.Warn("not correct") + logrus.Error("something error") + logrus.Fatal("panic") +} diff --git a/vendor/github.com/mattn/go-colorable/_example/title/main.go b/vendor/github.com/mattn/go-colorable/_example/title/main.go new file mode 100644 index 000000000..e208870e7 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/_example/title/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "fmt" + "os" + . "github.com/mattn/go-colorable" +) + +func main() { + out := NewColorableStdout() + fmt.Fprint(out, "\x1B]0;TITLE Changed\007(See title and hit any key)") + var c [1]byte + os.Stdin.Read(c[:]) +} diff --git a/vendor/github.com/mattn/go-colorable/colorable_appengine.go b/vendor/github.com/mattn/go-colorable/colorable_appengine.go new file mode 100644 index 000000000..1f28d773d --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/colorable_appengine.go @@ -0,0 +1,29 @@ +// +build appengine + +package colorable + +import ( + "io" + "os" + + _ "github.com/mattn/go-isatty" +) + +// NewColorable return new instance of Writer which handle escape sequence. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + return file +} + +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. +func NewColorableStdout() io.Writer { + return os.Stdout +} + +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. +func NewColorableStderr() io.Writer { + return os.Stderr +} diff --git a/vendor/github.com/mattn/go-colorable/colorable_others.go b/vendor/github.com/mattn/go-colorable/colorable_others.go new file mode 100644 index 000000000..887f203dc --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/colorable_others.go @@ -0,0 +1,30 @@ +// +build !windows +// +build !appengine + +package colorable + +import ( + "io" + "os" + + _ "github.com/mattn/go-isatty" +) + +// NewColorable return new instance of Writer which handle escape sequence. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + return file +} + +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. +func NewColorableStdout() io.Writer { + return os.Stdout +} + +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. +func NewColorableStderr() io.Writer { + return os.Stderr +} diff --git a/vendor/github.com/mattn/go-colorable/colorable_test.go b/vendor/github.com/mattn/go-colorable/colorable_test.go new file mode 100644 index 000000000..3069869a3 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/colorable_test.go @@ -0,0 +1,83 @@ +package colorable + +import ( + "bytes" + "os" + "runtime" + "testing" +) + +// checkEncoding checks that colorable is output encoding agnostic as long as +// the encoding is a superset of ASCII. This implies that one byte not part of +// an ANSI sequence must give exactly one byte in output +func checkEncoding(t *testing.T, data []byte) { + // Send non-UTF8 data to colorable + b := bytes.NewBuffer(make([]byte, 0, 10)) + if b.Len() != 0 { + t.FailNow() + } + // TODO move colorable wrapping outside the test + c := NewNonColorable(b) + c.Write(data) + if b.Len() != len(data) { + t.Fatalf("%d bytes expected, got %d", len(data), b.Len()) + } +} + +func TestEncoding(t *testing.T) { + checkEncoding(t, []byte{}) // Empty + checkEncoding(t, []byte(`abc`)) // "abc" + checkEncoding(t, []byte(`é`)) // "é" in UTF-8 + checkEncoding(t, []byte{233}) // 'é' in Latin-1 +} + +func TestNonColorable(t *testing.T) { + var buf bytes.Buffer + want := "hello" + NewNonColorable(&buf).Write([]byte("\x1b[0m" + want + "\x1b[2J")) + got := buf.String() + if got != "hello" { + t.Fatalf("want %q but %q", want, got) + } + + buf.Reset() + NewNonColorable(&buf).Write([]byte("\x1b[")) + got = buf.String() + if got != "" { + t.Fatalf("want %q but %q", "", got) + } +} + +func TestNonColorableNil(t *testing.T) { + paniced := false + func() { + defer func() { + recover() + paniced = true + }() + NewNonColorable(nil) + NewColorable(nil) + }() + + if !paniced { + t.Fatalf("should panic") + } +} + +func TestColorable(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skipf("skip this test on windows") + } + _, ok := NewColorableStdout().(*os.File) + if !ok { + t.Fatalf("should os.Stdout on UNIX") + } + _, ok = NewColorableStderr().(*os.File) + if !ok { + t.Fatalf("should os.Stdout on UNIX") + } + _, ok = NewColorable(os.Stdout).(*os.File) + if !ok { + t.Fatalf("should os.Stdout on UNIX") + } +} diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go new file mode 100644 index 000000000..e17a5474e --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/colorable_windows.go @@ -0,0 +1,884 @@ +// +build windows +// +build !appengine + +package colorable + +import ( + "bytes" + "io" + "math" + "os" + "strconv" + "strings" + "syscall" + "unsafe" + + "github.com/mattn/go-isatty" +) + +const ( + foregroundBlue = 0x1 + foregroundGreen = 0x2 + foregroundRed = 0x4 + foregroundIntensity = 0x8 + foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity) + backgroundBlue = 0x10 + backgroundGreen = 0x20 + backgroundRed = 0x40 + backgroundIntensity = 0x80 + backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity) +) + +type wchar uint16 +type short int16 +type dword uint32 +type word uint16 + +type coord struct { + x short + y short +} + +type smallRect struct { + left short + top short + right short + bottom short +} + +type consoleScreenBufferInfo struct { + size coord + cursorPosition coord + attributes word + window smallRect + maximumWindowSize coord +} + +type consoleCursorInfo struct { + size dword + visible int32 +} + +var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") + procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") + procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") + procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") + procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") + procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") + procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo") + procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo") + procSetConsoleTitle = kernel32.NewProc("SetConsoleTitleW") +) + +// Writer provide colorable Writer to the console +type Writer struct { + out io.Writer + handle syscall.Handle + oldattr word + oldpos coord +} + +// NewColorable return new instance of Writer which handle escape sequence from File. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + if isatty.IsTerminal(file.Fd()) { + var csbi consoleScreenBufferInfo + handle := syscall.Handle(file.Fd()) + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + return &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}} + } + return file +} + +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. +func NewColorableStdout() io.Writer { + return NewColorable(os.Stdout) +} + +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. +func NewColorableStderr() io.Writer { + return NewColorable(os.Stderr) +} + +var color256 = map[int]int{ + 0: 0x000000, + 1: 0x800000, + 2: 0x008000, + 3: 0x808000, + 4: 0x000080, + 5: 0x800080, + 6: 0x008080, + 7: 0xc0c0c0, + 8: 0x808080, + 9: 0xff0000, + 10: 0x00ff00, + 11: 0xffff00, + 12: 0x0000ff, + 13: 0xff00ff, + 14: 0x00ffff, + 15: 0xffffff, + 16: 0x000000, + 17: 0x00005f, + 18: 0x000087, + 19: 0x0000af, + 20: 0x0000d7, + 21: 0x0000ff, + 22: 0x005f00, + 23: 0x005f5f, + 24: 0x005f87, + 25: 0x005faf, + 26: 0x005fd7, + 27: 0x005fff, + 28: 0x008700, + 29: 0x00875f, + 30: 0x008787, + 31: 0x0087af, + 32: 0x0087d7, + 33: 0x0087ff, + 34: 0x00af00, + 35: 0x00af5f, + 36: 0x00af87, + 37: 0x00afaf, + 38: 0x00afd7, + 39: 0x00afff, + 40: 0x00d700, + 41: 0x00d75f, + 42: 0x00d787, + 43: 0x00d7af, + 44: 0x00d7d7, + 45: 0x00d7ff, + 46: 0x00ff00, + 47: 0x00ff5f, + 48: 0x00ff87, + 49: 0x00ffaf, + 50: 0x00ffd7, + 51: 0x00ffff, + 52: 0x5f0000, + 53: 0x5f005f, + 54: 0x5f0087, + 55: 0x5f00af, + 56: 0x5f00d7, + 57: 0x5f00ff, + 58: 0x5f5f00, + 59: 0x5f5f5f, + 60: 0x5f5f87, + 61: 0x5f5faf, + 62: 0x5f5fd7, + 63: 0x5f5fff, + 64: 0x5f8700, + 65: 0x5f875f, + 66: 0x5f8787, + 67: 0x5f87af, + 68: 0x5f87d7, + 69: 0x5f87ff, + 70: 0x5faf00, + 71: 0x5faf5f, + 72: 0x5faf87, + 73: 0x5fafaf, + 74: 0x5fafd7, + 75: 0x5fafff, + 76: 0x5fd700, + 77: 0x5fd75f, + 78: 0x5fd787, + 79: 0x5fd7af, + 80: 0x5fd7d7, + 81: 0x5fd7ff, + 82: 0x5fff00, + 83: 0x5fff5f, + 84: 0x5fff87, + 85: 0x5fffaf, + 86: 0x5fffd7, + 87: 0x5fffff, + 88: 0x870000, + 89: 0x87005f, + 90: 0x870087, + 91: 0x8700af, + 92: 0x8700d7, + 93: 0x8700ff, + 94: 0x875f00, + 95: 0x875f5f, + 96: 0x875f87, + 97: 0x875faf, + 98: 0x875fd7, + 99: 0x875fff, + 100: 0x878700, + 101: 0x87875f, + 102: 0x878787, + 103: 0x8787af, + 104: 0x8787d7, + 105: 0x8787ff, + 106: 0x87af00, + 107: 0x87af5f, + 108: 0x87af87, + 109: 0x87afaf, + 110: 0x87afd7, + 111: 0x87afff, + 112: 0x87d700, + 113: 0x87d75f, + 114: 0x87d787, + 115: 0x87d7af, + 116: 0x87d7d7, + 117: 0x87d7ff, + 118: 0x87ff00, + 119: 0x87ff5f, + 120: 0x87ff87, + 121: 0x87ffaf, + 122: 0x87ffd7, + 123: 0x87ffff, + 124: 0xaf0000, + 125: 0xaf005f, + 126: 0xaf0087, + 127: 0xaf00af, + 128: 0xaf00d7, + 129: 0xaf00ff, + 130: 0xaf5f00, + 131: 0xaf5f5f, + 132: 0xaf5f87, + 133: 0xaf5faf, + 134: 0xaf5fd7, + 135: 0xaf5fff, + 136: 0xaf8700, + 137: 0xaf875f, + 138: 0xaf8787, + 139: 0xaf87af, + 140: 0xaf87d7, + 141: 0xaf87ff, + 142: 0xafaf00, + 143: 0xafaf5f, + 144: 0xafaf87, + 145: 0xafafaf, + 146: 0xafafd7, + 147: 0xafafff, + 148: 0xafd700, + 149: 0xafd75f, + 150: 0xafd787, + 151: 0xafd7af, + 152: 0xafd7d7, + 153: 0xafd7ff, + 154: 0xafff00, + 155: 0xafff5f, + 156: 0xafff87, + 157: 0xafffaf, + 158: 0xafffd7, + 159: 0xafffff, + 160: 0xd70000, + 161: 0xd7005f, + 162: 0xd70087, + 163: 0xd700af, + 164: 0xd700d7, + 165: 0xd700ff, + 166: 0xd75f00, + 167: 0xd75f5f, + 168: 0xd75f87, + 169: 0xd75faf, + 170: 0xd75fd7, + 171: 0xd75fff, + 172: 0xd78700, + 173: 0xd7875f, + 174: 0xd78787, + 175: 0xd787af, + 176: 0xd787d7, + 177: 0xd787ff, + 178: 0xd7af00, + 179: 0xd7af5f, + 180: 0xd7af87, + 181: 0xd7afaf, + 182: 0xd7afd7, + 183: 0xd7afff, + 184: 0xd7d700, + 185: 0xd7d75f, + 186: 0xd7d787, + 187: 0xd7d7af, + 188: 0xd7d7d7, + 189: 0xd7d7ff, + 190: 0xd7ff00, + 191: 0xd7ff5f, + 192: 0xd7ff87, + 193: 0xd7ffaf, + 194: 0xd7ffd7, + 195: 0xd7ffff, + 196: 0xff0000, + 197: 0xff005f, + 198: 0xff0087, + 199: 0xff00af, + 200: 0xff00d7, + 201: 0xff00ff, + 202: 0xff5f00, + 203: 0xff5f5f, + 204: 0xff5f87, + 205: 0xff5faf, + 206: 0xff5fd7, + 207: 0xff5fff, + 208: 0xff8700, + 209: 0xff875f, + 210: 0xff8787, + 211: 0xff87af, + 212: 0xff87d7, + 213: 0xff87ff, + 214: 0xffaf00, + 215: 0xffaf5f, + 216: 0xffaf87, + 217: 0xffafaf, + 218: 0xffafd7, + 219: 0xffafff, + 220: 0xffd700, + 221: 0xffd75f, + 222: 0xffd787, + 223: 0xffd7af, + 224: 0xffd7d7, + 225: 0xffd7ff, + 226: 0xffff00, + 227: 0xffff5f, + 228: 0xffff87, + 229: 0xffffaf, + 230: 0xffffd7, + 231: 0xffffff, + 232: 0x080808, + 233: 0x121212, + 234: 0x1c1c1c, + 235: 0x262626, + 236: 0x303030, + 237: 0x3a3a3a, + 238: 0x444444, + 239: 0x4e4e4e, + 240: 0x585858, + 241: 0x626262, + 242: 0x6c6c6c, + 243: 0x767676, + 244: 0x808080, + 245: 0x8a8a8a, + 246: 0x949494, + 247: 0x9e9e9e, + 248: 0xa8a8a8, + 249: 0xb2b2b2, + 250: 0xbcbcbc, + 251: 0xc6c6c6, + 252: 0xd0d0d0, + 253: 0xdadada, + 254: 0xe4e4e4, + 255: 0xeeeeee, +} + +// `\033]0;TITLESTR\007` +func doTitleSequence(er *bytes.Reader) error { + var c byte + var err error + + c, err = er.ReadByte() + if err != nil { + return err + } + if c != '0' && c != '2' { + return nil + } + c, err = er.ReadByte() + if err != nil { + return err + } + if c != ';' { + return nil + } + title := make([]byte, 0, 80) + for { + c, err = er.ReadByte() + if err != nil { + return err + } + if c == 0x07 || c == '\n' { + break + } + title = append(title, c) + } + if len(title) > 0 { + title8, err := syscall.UTF16PtrFromString(string(title)) + if err == nil { + procSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8))) + } + } + return nil +} + +// Write write data on console +func (w *Writer) Write(data []byte) (n int, err error) { + var csbi consoleScreenBufferInfo + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + + er := bytes.NewReader(data) + var bw [1]byte +loop: + for { + c1, err := er.ReadByte() + if err != nil { + break loop + } + if c1 != 0x1b { + bw[0] = c1 + w.out.Write(bw[:]) + continue + } + c2, err := er.ReadByte() + if err != nil { + break loop + } + + if c2 == ']' { + if err := doTitleSequence(er); err != nil { + break loop + } + continue + } + if c2 != 0x5b { + continue + } + + var buf bytes.Buffer + var m byte + for { + c, err := er.ReadByte() + if err != nil { + break loop + } + if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { + m = c + break + } + buf.Write([]byte(string(c))) + } + + switch m { + case 'A': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.y -= short(n) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'B': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.y += short(n) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'C': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x += short(n) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'D': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x -= short(n) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'E': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = 0 + csbi.cursorPosition.y += short(n) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'F': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = 0 + csbi.cursorPosition.y -= short(n) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'G': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = short(n - 1) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'H', 'f': + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + if buf.Len() > 0 { + token := strings.Split(buf.String(), ";") + switch len(token) { + case 1: + n1, err := strconv.Atoi(token[0]) + if err != nil { + continue + } + csbi.cursorPosition.y = short(n1 - 1) + case 2: + n1, err := strconv.Atoi(token[0]) + if err != nil { + continue + } + n2, err := strconv.Atoi(token[1]) + if err != nil { + continue + } + csbi.cursorPosition.x = short(n2 - 1) + csbi.cursorPosition.y = short(n1 - 1) + } + } else { + csbi.cursorPosition.y = 0 + } + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'J': + n := 0 + if buf.Len() > 0 { + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + } + var count, written dword + var cursor coord + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + switch n { + case 0: + cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) + case 1: + cursor = coord{x: csbi.window.left, y: csbi.window.top} + count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.window.top-csbi.cursorPosition.y)*csbi.size.x) + case 2: + cursor = coord{x: csbi.window.left, y: csbi.window.top} + count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) + } + procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + case 'K': + n := 0 + if buf.Len() > 0 { + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + var cursor coord + var count, written dword + switch n { + case 0: + cursor = coord{x: csbi.cursorPosition.x + 1, y: csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x - 1) + case 1: + cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x) + case 2: + cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} + count = dword(csbi.size.x) + } + procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + case 'm': + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + attr := csbi.attributes + cs := buf.String() + if cs == "" { + procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr)) + continue + } + token := strings.Split(cs, ";") + for i := 0; i < len(token); i++ { + ns := token[i] + if n, err = strconv.Atoi(ns); err == nil { + switch { + case n == 0 || n == 100: + attr = w.oldattr + case 1 <= n && n <= 5: + attr |= foregroundIntensity + case n == 7: + attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) + case n == 22 || n == 25: + attr |= foregroundIntensity + case n == 27: + attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) + case 30 <= n && n <= 37: + attr &= backgroundMask + if (n-30)&1 != 0 { + attr |= foregroundRed + } + if (n-30)&2 != 0 { + attr |= foregroundGreen + } + if (n-30)&4 != 0 { + attr |= foregroundBlue + } + case n == 38: // set foreground color. + if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") { + if n256, err := strconv.Atoi(token[i+2]); err == nil { + if n256foreAttr == nil { + n256setup() + } + attr &= backgroundMask + attr |= n256foreAttr[n256] + i += 2 + } + } else { + attr = attr & (w.oldattr & backgroundMask) + } + case n == 39: // reset foreground color. + attr &= backgroundMask + attr |= w.oldattr & foregroundMask + case 40 <= n && n <= 47: + attr &= foregroundMask + if (n-40)&1 != 0 { + attr |= backgroundRed + } + if (n-40)&2 != 0 { + attr |= backgroundGreen + } + if (n-40)&4 != 0 { + attr |= backgroundBlue + } + case n == 48: // set background color. + if i < len(token)-2 && token[i+1] == "5" { + if n256, err := strconv.Atoi(token[i+2]); err == nil { + if n256backAttr == nil { + n256setup() + } + attr &= foregroundMask + attr |= n256backAttr[n256] + i += 2 + } + } else { + attr = attr & (w.oldattr & foregroundMask) + } + case n == 49: // reset foreground color. + attr &= foregroundMask + attr |= w.oldattr & backgroundMask + case 90 <= n && n <= 97: + attr = (attr & backgroundMask) + attr |= foregroundIntensity + if (n-90)&1 != 0 { + attr |= foregroundRed + } + if (n-90)&2 != 0 { + attr |= foregroundGreen + } + if (n-90)&4 != 0 { + attr |= foregroundBlue + } + case 100 <= n && n <= 107: + attr = (attr & foregroundMask) + attr |= backgroundIntensity + if (n-100)&1 != 0 { + attr |= backgroundRed + } + if (n-100)&2 != 0 { + attr |= backgroundGreen + } + if (n-100)&4 != 0 { + attr |= backgroundBlue + } + } + procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr)) + } + } + case 'h': + var ci consoleCursorInfo + cs := buf.String() + if cs == "5>" { + procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 0 + procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?25" { + procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 1 + procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + } + case 'l': + var ci consoleCursorInfo + cs := buf.String() + if cs == "5>" { + procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 1 + procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?25" { + procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 0 + procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + } + case 's': + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + w.oldpos = csbi.cursorPosition + case 'u': + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) + } + } + + return len(data), nil +} + +type consoleColor struct { + rgb int + red bool + green bool + blue bool + intensity bool +} + +func (c consoleColor) foregroundAttr() (attr word) { + if c.red { + attr |= foregroundRed + } + if c.green { + attr |= foregroundGreen + } + if c.blue { + attr |= foregroundBlue + } + if c.intensity { + attr |= foregroundIntensity + } + return +} + +func (c consoleColor) backgroundAttr() (attr word) { + if c.red { + attr |= backgroundRed + } + if c.green { + attr |= backgroundGreen + } + if c.blue { + attr |= backgroundBlue + } + if c.intensity { + attr |= backgroundIntensity + } + return +} + +var color16 = []consoleColor{ + {0x000000, false, false, false, false}, + {0x000080, false, false, true, false}, + {0x008000, false, true, false, false}, + {0x008080, false, true, true, false}, + {0x800000, true, false, false, false}, + {0x800080, true, false, true, false}, + {0x808000, true, true, false, false}, + {0xc0c0c0, true, true, true, false}, + {0x808080, false, false, false, true}, + {0x0000ff, false, false, true, true}, + {0x00ff00, false, true, false, true}, + {0x00ffff, false, true, true, true}, + {0xff0000, true, false, false, true}, + {0xff00ff, true, false, true, true}, + {0xffff00, true, true, false, true}, + {0xffffff, true, true, true, true}, +} + +type hsv struct { + h, s, v float32 +} + +func (a hsv) dist(b hsv) float32 { + dh := a.h - b.h + switch { + case dh > 0.5: + dh = 1 - dh + case dh < -0.5: + dh = -1 - dh + } + ds := a.s - b.s + dv := a.v - b.v + return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv))) +} + +func toHSV(rgb int) hsv { + r, g, b := float32((rgb&0xFF0000)>>16)/256.0, + float32((rgb&0x00FF00)>>8)/256.0, + float32(rgb&0x0000FF)/256.0 + min, max := minmax3f(r, g, b) + h := max - min + if h > 0 { + if max == r { + h = (g - b) / h + if h < 0 { + h += 6 + } + } else if max == g { + h = 2 + (b-r)/h + } else { + h = 4 + (r-g)/h + } + } + h /= 6.0 + s := max - min + if max != 0 { + s /= max + } + v := max + return hsv{h: h, s: s, v: v} +} + +type hsvTable []hsv + +func toHSVTable(rgbTable []consoleColor) hsvTable { + t := make(hsvTable, len(rgbTable)) + for i, c := range rgbTable { + t[i] = toHSV(c.rgb) + } + return t +} + +func (t hsvTable) find(rgb int) consoleColor { + hsv := toHSV(rgb) + n := 7 + l := float32(5.0) + for i, p := range t { + d := hsv.dist(p) + if d < l { + l, n = d, i + } + } + return color16[n] +} + +func minmax3f(a, b, c float32) (min, max float32) { + if a < b { + if b < c { + return a, c + } else if a < c { + return a, b + } else { + return c, b + } + } else { + if a < c { + return b, c + } else if b < c { + return b, a + } else { + return c, a + } + } +} + +var n256foreAttr []word +var n256backAttr []word + +func n256setup() { + n256foreAttr = make([]word, 256) + n256backAttr = make([]word, 256) + t := toHSVTable(color16) + for i, rgb := range color256 { + c := t.find(rgb) + n256foreAttr[i] = c.foregroundAttr() + n256backAttr[i] = c.backgroundAttr() + } +} diff --git a/vendor/github.com/mattn/go-colorable/noncolorable.go b/vendor/github.com/mattn/go-colorable/noncolorable.go new file mode 100644 index 000000000..9721e16f4 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/noncolorable.go @@ -0,0 +1,55 @@ +package colorable + +import ( + "bytes" + "io" +) + +// NonColorable hold writer but remove escape sequence. +type NonColorable struct { + out io.Writer +} + +// NewNonColorable return new instance of Writer which remove escape sequence from Writer. +func NewNonColorable(w io.Writer) io.Writer { + return &NonColorable{out: w} +} + +// Write write data on console +func (w *NonColorable) Write(data []byte) (n int, err error) { + er := bytes.NewReader(data) + var bw [1]byte +loop: + for { + c1, err := er.ReadByte() + if err != nil { + break loop + } + if c1 != 0x1b { + bw[0] = c1 + w.out.Write(bw[:]) + continue + } + c2, err := er.ReadByte() + if err != nil { + break loop + } + if c2 != 0x5b { + continue + } + + var buf bytes.Buffer + for { + c, err := er.ReadByte() + if err != nil { + break loop + } + if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { + break + } + buf.Write([]byte(string(c))) + } + } + + return len(data), nil +} diff --git a/vendor/github.com/mattn/go-isatty/.travis.yml b/vendor/github.com/mattn/go-isatty/.travis.yml new file mode 100644 index 000000000..b9f8b239c --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/.travis.yml @@ -0,0 +1,9 @@ +language: go +go: + - tip + +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover +script: + - $HOME/gopath/bin/goveralls -repotoken 3gHdORO5k5ziZcWMBxnd9LrMZaJs8m9x5 diff --git a/vendor/github.com/mattn/go-isatty/LICENSE b/vendor/github.com/mattn/go-isatty/LICENSE new file mode 100644 index 000000000..65dc692b6 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/LICENSE @@ -0,0 +1,9 @@ +Copyright (c) Yasuhiro MATSUMOTO + +MIT License (Expat) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/mattn/go-isatty/README.md b/vendor/github.com/mattn/go-isatty/README.md new file mode 100644 index 000000000..1e69004bb --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/README.md @@ -0,0 +1,50 @@ +# go-isatty + +[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty) +[![Build Status](https://travis-ci.org/mattn/go-isatty.svg?branch=master)](https://travis-ci.org/mattn/go-isatty) +[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master) +[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty) + +isatty for golang + +## Usage + +```go +package main + +import ( + "fmt" + "github.com/mattn/go-isatty" + "os" +) + +func main() { + if isatty.IsTerminal(os.Stdout.Fd()) { + fmt.Println("Is Terminal") + } else if isatty.IsCygwinTerminal(os.Stdout.Fd()) { + fmt.Println("Is Cygwin/MSYS2 Terminal") + } else { + fmt.Println("Is Not Terminal") + } +} +``` + +## Installation + +``` +$ go get github.com/mattn/go-isatty +``` + +## License + +MIT + +## Author + +Yasuhiro Matsumoto (a.k.a mattn) + +## Thanks + +* k-takata: base idea for IsCygwinTerminal + + https://github.com/k-takata/go-iscygpty diff --git a/vendor/github.com/mattn/go-isatty/doc.go b/vendor/github.com/mattn/go-isatty/doc.go new file mode 100644 index 000000000..17d4f90eb --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/doc.go @@ -0,0 +1,2 @@ +// Package isatty implements interface to isatty +package isatty diff --git a/vendor/github.com/mattn/go-isatty/example_test.go b/vendor/github.com/mattn/go-isatty/example_test.go new file mode 100644 index 000000000..fa8f7e745 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/example_test.go @@ -0,0 +1,18 @@ +package isatty_test + +import ( + "fmt" + "os" + + "github.com/mattn/go-isatty" +) + +func Example() { + if isatty.IsTerminal(os.Stdout.Fd()) { + fmt.Println("Is Terminal") + } else if isatty.IsCygwinTerminal(os.Stdout.Fd()) { + fmt.Println("Is Cygwin/MSYS2 Terminal") + } else { + fmt.Println("Is Not Terminal") + } +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_appengine.go b/vendor/github.com/mattn/go-isatty/isatty_appengine.go new file mode 100644 index 000000000..9584a9884 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_appengine.go @@ -0,0 +1,15 @@ +// +build appengine + +package isatty + +// IsTerminal returns true if the file descriptor is terminal which +// is always false on on appengine classic which is a sandboxed PaaS. +func IsTerminal(fd uintptr) bool { + return false +} + +// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go new file mode 100644 index 000000000..42f2514d1 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_bsd.go @@ -0,0 +1,18 @@ +// +build darwin freebsd openbsd netbsd dragonfly +// +build !appengine + +package isatty + +import ( + "syscall" + "unsafe" +) + +const ioctlReadTermios = syscall.TIOCGETA + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var termios syscall.Termios + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_linux.go b/vendor/github.com/mattn/go-isatty/isatty_linux.go new file mode 100644 index 000000000..7384cf991 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_linux.go @@ -0,0 +1,18 @@ +// +build linux +// +build !appengine,!ppc64,!ppc64le + +package isatty + +import ( + "syscall" + "unsafe" +) + +const ioctlReadTermios = syscall.TCGETS + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var termios syscall.Termios + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go b/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go new file mode 100644 index 000000000..44e5d2130 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go @@ -0,0 +1,19 @@ +// +build linux +// +build ppc64 ppc64le + +package isatty + +import ( + "unsafe" + + syscall "golang.org/x/sys/unix" +) + +const ioctlReadTermios = syscall.TCGETS + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var termios syscall.Termios + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go new file mode 100644 index 000000000..ff4de3d9a --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_others.go @@ -0,0 +1,10 @@ +// +build !windows +// +build !appengine + +package isatty + +// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_others_test.go b/vendor/github.com/mattn/go-isatty/isatty_others_test.go new file mode 100644 index 000000000..a2091cf47 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_others_test.go @@ -0,0 +1,19 @@ +// +build !windows + +package isatty + +import ( + "os" + "testing" +) + +func TestTerminal(t *testing.T) { + // test for non-panic + IsTerminal(os.Stdout.Fd()) +} + +func TestCygwinPipeName(t *testing.T) { + if IsCygwinTerminal(os.Stdout.Fd()) { + t.Fatal("should be false always") + } +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_solaris.go b/vendor/github.com/mattn/go-isatty/isatty_solaris.go new file mode 100644 index 000000000..1f0c6bf53 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_solaris.go @@ -0,0 +1,16 @@ +// +build solaris +// +build !appengine + +package isatty + +import ( + "golang.org/x/sys/unix" +) + +// IsTerminal returns true if the given file descriptor is a terminal. +// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c +func IsTerminal(fd uintptr) bool { + var termio unix.Termio + err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio) + return err == nil +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_windows.go b/vendor/github.com/mattn/go-isatty/isatty_windows.go new file mode 100644 index 000000000..af51cbcaa --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_windows.go @@ -0,0 +1,94 @@ +// +build windows +// +build !appengine + +package isatty + +import ( + "strings" + "syscall" + "unicode/utf16" + "unsafe" +) + +const ( + fileNameInfo uintptr = 2 + fileTypePipe = 3 +) + +var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") + procGetConsoleMode = kernel32.NewProc("GetConsoleMode") + procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx") + procGetFileType = kernel32.NewProc("GetFileType") +) + +func init() { + // Check if GetFileInformationByHandleEx is available. + if procGetFileInformationByHandleEx.Find() != nil { + procGetFileInformationByHandleEx = nil + } +} + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var st uint32 + r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) + return r != 0 && e == 0 +} + +// Check pipe name is used for cygwin/msys2 pty. +// Cygwin/MSYS2 PTY has a name like: +// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master +func isCygwinPipeName(name string) bool { + token := strings.Split(name, "-") + if len(token) < 5 { + return false + } + + if token[0] != `\msys` && token[0] != `\cygwin` { + return false + } + + if token[1] == "" { + return false + } + + if !strings.HasPrefix(token[2], "pty") { + return false + } + + if token[3] != `from` && token[3] != `to` { + return false + } + + if token[4] != "master" { + return false + } + + return true +} + +// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 +// terminal. +func IsCygwinTerminal(fd uintptr) bool { + if procGetFileInformationByHandleEx == nil { + return false + } + + // Cygwin/msys's pty is a pipe. + ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0) + if ft != fileTypePipe || e != 0 { + return false + } + + var buf [2 + syscall.MAX_PATH]uint16 + r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), + 4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)), + uintptr(len(buf)*2), 0, 0) + if r == 0 || e != 0 { + return false + } + + l := *(*uint32)(unsafe.Pointer(&buf)) + return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2]))) +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_windows_test.go b/vendor/github.com/mattn/go-isatty/isatty_windows_test.go new file mode 100644 index 000000000..777e8a603 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_windows_test.go @@ -0,0 +1,35 @@ +// +build windows + +package isatty + +import ( + "testing" +) + +func TestCygwinPipeName(t *testing.T) { + tests := []struct { + name string + result bool + }{ + {``, false}, + {`\msys-`, false}, + {`\cygwin-----`, false}, + {`\msys-x-PTY5-pty1-from-master`, false}, + {`\cygwin-x-PTY5-from-master`, false}, + {`\cygwin-x-pty2-from-toaster`, false}, + {`\cygwin--pty2-from-master`, false}, + {`\\cygwin-x-pty2-from-master`, false}, + {`\cygwin-x-pty2-from-master-`, true}, // for the feature + {`\cygwin-e022582115c10879-pty4-from-master`, true}, + {`\msys-e022582115c10879-pty4-to-master`, true}, + {`\cygwin-e022582115c10879-pty4-to-master`, true}, + } + + for _, test := range tests { + want := test.result + got := isCygwinPipeName(test.name) + if want != got { + t.Fatalf("isatty(%q): got %v, want %v:", test.name, got, want) + } + } +} diff --git a/vendor/gopkg.in/VividCortex/ewma.v1/.github/ISSUE_TEMPLATE.md b/vendor/gopkg.in/VividCortex/ewma.v1/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..f3c19086c --- /dev/null +++ b/vendor/gopkg.in/VividCortex/ewma.v1/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,10 @@ +Before you file an issue, please consider: + +We only accept pull requests for minor fixes or improvements. This includes: + +* Small bug fixes +* Typos +* Documentation or comments + +Please open issues to discuss new features. Pull requests for new features will be rejected, +so we recommend forking the repository and making changes in your fork for your use case. diff --git a/vendor/gopkg.in/VividCortex/ewma.v1/.github/PULL_REQUEST_TEMPLATE.md b/vendor/gopkg.in/VividCortex/ewma.v1/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..0c22b9267 --- /dev/null +++ b/vendor/gopkg.in/VividCortex/ewma.v1/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,10 @@ +Before you create a pull request, please consider: + +We only accept pull requests for minor fixes or improvements. This includes: + +* Small bug fixes +* Typos +* Documentation or comments + +Please open issues to discuss new features. Pull requests for new features will be rejected, +so we recommend forking the repository and making changes in your fork for your use case. diff --git a/vendor/gopkg.in/VividCortex/ewma.v1/.gitignore b/vendor/gopkg.in/VividCortex/ewma.v1/.gitignore new file mode 100644 index 000000000..6c7104aef --- /dev/null +++ b/vendor/gopkg.in/VividCortex/ewma.v1/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +.*.sw? diff --git a/vendor/gopkg.in/VividCortex/ewma.v1/LICENSE b/vendor/gopkg.in/VividCortex/ewma.v1/LICENSE new file mode 100644 index 000000000..a78d643ed --- /dev/null +++ b/vendor/gopkg.in/VividCortex/ewma.v1/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013 VividCortex + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/gopkg.in/VividCortex/ewma.v1/README.md b/vendor/gopkg.in/VividCortex/ewma.v1/README.md new file mode 100644 index 000000000..7aab61b87 --- /dev/null +++ b/vendor/gopkg.in/VividCortex/ewma.v1/README.md @@ -0,0 +1,140 @@ +# EWMA [![GoDoc](https://godoc.org/github.com/VividCortex/ewma?status.svg)](https://godoc.org/github.com/VividCortex/ewma) ![Build Status](https://circleci.com/gh/VividCortex/moving_average.png?circle-token=1459fa37f9ca0e50cef05d1963146d96d47ea523) + +This repo provides Exponentially Weighted Moving Average algorithms, or EWMAs for short, [based on our +Quantifying Abnormal Behavior talk](https://vividcortex.com/blog/2013/07/23/a-fast-go-library-for-exponential-moving-averages/). + +### Exponentially Weighted Moving Average + +An exponentially weighted moving average is a way to continuously compute a type of +average for a series of numbers, as the numbers arrive. After a value in the series is +added to the average, its weight in the average decreases exponentially over time. This +biases the average towards more recent data. EWMAs are useful for several reasons, chiefly +their inexpensive computational and memory cost, as well as the fact that they represent +the recent central tendency of the series of values. + +The EWMA algorithm requires a decay factor, alpha. The larger the alpha, the more the average +is biased towards recent history. The alpha must be between 0 and 1, and is typically +a fairly small number, such as 0.04. We will discuss the choice of alpha later. + +The algorithm works thus, in pseudocode: + +1. Multiply the next number in the series by alpha. +2. Multiply the current value of the average by 1 minus alpha. +3. Add the result of steps 1 and 2, and store it as the new current value of the average. +4. Repeat for each number in the series. + +There are special-case behaviors for how to initialize the current value, and these vary +between implementations. One approach is to start with the first value in the series; +another is to average the first 10 or so values in the series using an arithmetic average, +and then begin the incremental updating of the average. Each method has pros and cons. + +It may help to look at it pictorially. Suppose the series has five numbers, and we choose +alpha to be 0.50 for simplicity. Here's the series, with numbers in the neighborhood of 300. + +![Data Series](https://user-images.githubusercontent.com/279875/28242350-463289a2-6977-11e7-88ca-fd778ccef1f0.png) + +Now let's take the moving average of those numbers. First we set the average to the value +of the first number. + +![EWMA Step 1](https://user-images.githubusercontent.com/279875/28242353-464c96bc-6977-11e7-9981-dc4e0789c7ba.png) + +Next we multiply the next number by alpha, multiply the current value by 1-alpha, and add +them to generate a new value. + +![EWMA Step 2](https://user-images.githubusercontent.com/279875/28242351-464abefa-6977-11e7-95d0-43900f29bef2.png) + +This continues until we are done. + +![EWMA Step N](https://user-images.githubusercontent.com/279875/28242352-464c58f0-6977-11e7-8cd0-e01e4efaac7f.png) + +Notice how each of the values in the series decays by half each time a new value +is added, and the top of the bars in the lower portion of the image represents the +size of the moving average. It is a smoothed, or low-pass, average of the original +series. + +For further reading, see [Exponentially weighted moving average](http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average) on wikipedia. + +### Choosing Alpha + +Consider a fixed-size sliding-window moving average (not an exponentially weighted moving average) +that averages over the previous N samples. What is the average age of each sample? It is N/2. + +Now suppose that you wish to construct a EWMA whose samples have the same average age. The formula +to compute the alpha required for this is: alpha = 2/(N+1). Proof is in the book +"Production and Operations Analysis" by Steven Nahmias. + +So, for example, if you have a time-series with samples once per second, and you want to get the +moving average over the previous minute, you should use an alpha of .032786885. This, by the way, +is the constant alpha used for this repository's SimpleEWMA. + +### Implementations + +This repository contains two implementations of the EWMA algorithm, with different properties. + +The implementations all conform to the MovingAverage interface, and the constructor returns +that type. + +Current implementations assume an implicit time interval of 1.0 between every sample added. +That is, the passage of time is treated as though it's the same as the arrival of samples. +If you need time-based decay when samples are not arriving precisely at set intervals, then +this package will not support your needs at present. + +#### SimpleEWMA + +A SimpleEWMA is designed for low CPU and memory consumption. It **will** have different behavior than the VariableEWMA +for multiple reasons. It has no warm-up period and it uses a constant +decay. These properties let it use less memory. It will also behave +differently when it's equal to zero, which is assumed to mean +uninitialized, so if a value is likely to actually become zero over time, +then any non-zero value will cause a sharp jump instead of a small change. + +#### VariableEWMA + +Unlike SimpleEWMA, this supports a custom age which must be stored, and thus uses more memory. +It also has a "warmup" time when you start adding values to it. It will report a value of 0.0 +until you have added the required number of samples to it. It uses some memory to store the +number of samples added to it. As a result it uses a little over twice the memory of SimpleEWMA. + +## Usage + +### API Documentation + +View the GoDoc generated documentation [here](http://godoc.org/github.com/VividCortex/ewma). + +```go +package main +import "github.com/VividCortex/ewma" + +func main() { + samples := [100]float64{ + 4599, 5711, 4746, 4621, 5037, 4218, 4925, 4281, 5207, 5203, 5594, 5149, + } + + e := ewma.NewMovingAverage() //=> Returns a SimpleEWMA if called without params + a := ewma.NewMovingAverage(5) //=> returns a VariableEWMA with a decay of 2 / (5 + 1) + + for _, f := range samples { + e.Add(f) + a.Add(f) + } + + e.Value() //=> 13.577404704631077 + a.Value() //=> 1.5806140565521463e-12 +} +``` + +## Contributing + +We only accept pull requests for minor fixes or improvements. This includes: + +* Small bug fixes +* Typos +* Documentation or comments + +Please open issues to discuss new features. Pull requests for new features will be rejected, +so we recommend forking the repository and making changes in your fork for your use case. + +## License + +This repository is Copyright (c) 2013 VividCortex, Inc. All rights reserved. +It is licensed under the MIT license. Please see the LICENSE file for applicable license terms. diff --git a/vendor/gopkg.in/VividCortex/ewma.v1/ewma.go b/vendor/gopkg.in/VividCortex/ewma.v1/ewma.go new file mode 100644 index 000000000..44d5d53e3 --- /dev/null +++ b/vendor/gopkg.in/VividCortex/ewma.v1/ewma.go @@ -0,0 +1,126 @@ +// Package ewma implements exponentially weighted moving averages. +package ewma + +// Copyright (c) 2013 VividCortex, Inc. All rights reserved. +// Please see the LICENSE file for applicable license terms. + +const ( + // By default, we average over a one-minute period, which means the average + // age of the metrics in the period is 30 seconds. + AVG_METRIC_AGE float64 = 30.0 + + // The formula for computing the decay factor from the average age comes + // from "Production and Operations Analysis" by Steven Nahmias. + DECAY float64 = 2 / (float64(AVG_METRIC_AGE) + 1) + + // For best results, the moving average should not be initialized to the + // samples it sees immediately. The book "Production and Operations + // Analysis" by Steven Nahmias suggests initializing the moving average to + // the mean of the first 10 samples. Until the VariableEwma has seen this + // many samples, it is not "ready" to be queried for the value of the + // moving average. This adds some memory cost. + WARMUP_SAMPLES uint8 = 10 +) + +// MovingAverage is the interface that computes a moving average over a time- +// series stream of numbers. The average may be over a window or exponentially +// decaying. +type MovingAverage interface { + Add(float64) + Value() float64 + Set(float64) +} + +// NewMovingAverage constructs a MovingAverage that computes an average with the +// desired characteristics in the moving window or exponential decay. If no +// age is given, it constructs a default exponentially weighted implementation +// that consumes minimal memory. The age is related to the decay factor alpha +// by the formula given for the DECAY constant. It signifies the average age +// of the samples as time goes to infinity. +func NewMovingAverage(age ...float64) MovingAverage { + if len(age) == 0 || age[0] == AVG_METRIC_AGE { + return new(SimpleEWMA) + } + return &VariableEWMA{ + decay: 2 / (age[0] + 1), + } +} + +// A SimpleEWMA represents the exponentially weighted moving average of a +// series of numbers. It WILL have different behavior than the VariableEWMA +// for multiple reasons. It has no warm-up period and it uses a constant +// decay. These properties let it use less memory. It will also behave +// differently when it's equal to zero, which is assumed to mean +// uninitialized, so if a value is likely to actually become zero over time, +// then any non-zero value will cause a sharp jump instead of a small change. +// However, note that this takes a long time, and the value may just +// decays to a stable value that's close to zero, but which won't be mistaken +// for uninitialized. See http://play.golang.org/p/litxBDr_RC for example. +type SimpleEWMA struct { + // The current value of the average. After adding with Add(), this is + // updated to reflect the average of all values seen thus far. + value float64 +} + +// Add adds a value to the series and updates the moving average. +func (e *SimpleEWMA) Add(value float64) { + if e.value == 0 { // this is a proxy for "uninitialized" + e.value = value + } else { + e.value = (value * DECAY) + (e.value * (1 - DECAY)) + } +} + +// Value returns the current value of the moving average. +func (e *SimpleEWMA) Value() float64 { + return e.value +} + +// Set sets the EWMA's value. +func (e *SimpleEWMA) Set(value float64) { + e.value = value +} + +// VariableEWMA represents the exponentially weighted moving average of a series of +// numbers. Unlike SimpleEWMA, it supports a custom age, and thus uses more memory. +type VariableEWMA struct { + // The multiplier factor by which the previous samples decay. + decay float64 + // The current value of the average. + value float64 + // The number of samples added to this instance. + count uint8 +} + +// Add adds a value to the series and updates the moving average. +func (e *VariableEWMA) Add(value float64) { + switch { + case e.count < WARMUP_SAMPLES: + e.count++ + e.value += value + case e.count == WARMUP_SAMPLES: + e.count++ + e.value = e.value / float64(WARMUP_SAMPLES) + e.value = (value * e.decay) + (e.value * (1 - e.decay)) + default: + e.value = (value * e.decay) + (e.value * (1 - e.decay)) + } +} + +// Value returns the current value of the average, or 0.0 if the series hasn't +// warmed up yet. +func (e *VariableEWMA) Value() float64 { + if e.count <= WARMUP_SAMPLES { + return 0.0 + } + + return e.value +} + +// Set sets the EWMA's value. +func (e *VariableEWMA) Set(value float64) { + e.value = value + if e.count <= WARMUP_SAMPLES { + e.count = WARMUP_SAMPLES + 1 + } +} diff --git a/vendor/gopkg.in/VividCortex/ewma.v1/ewma_test.go b/vendor/gopkg.in/VividCortex/ewma.v1/ewma_test.go new file mode 100644 index 000000000..8060a859f --- /dev/null +++ b/vendor/gopkg.in/VividCortex/ewma.v1/ewma_test.go @@ -0,0 +1,103 @@ +package ewma + +// Copyright (c) 2013 VividCortex, Inc. All rights reserved. +// Please see the LICENSE file for applicable license terms. + +import ( + "math" + "testing" +) + +const testMargin = 0.00000001 + +var samples = [100]float64{ + 4599, 5711, 4746, 4621, 5037, 4218, 4925, 4281, 5207, 5203, 5594, 5149, + 4948, 4994, 6056, 4417, 4973, 4714, 4964, 5280, 5074, 4913, 4119, 4522, + 4631, 4341, 4909, 4750, 4663, 5167, 3683, 4964, 5151, 4892, 4171, 5097, + 3546, 4144, 4551, 6557, 4234, 5026, 5220, 4144, 5547, 4747, 4732, 5327, + 5442, 4176, 4907, 3570, 4684, 4161, 5206, 4952, 4317, 4819, 4668, 4603, + 4885, 4645, 4401, 4362, 5035, 3954, 4738, 4545, 5433, 6326, 5927, 4983, + 5364, 4598, 5071, 5231, 5250, 4621, 4269, 3953, 3308, 3623, 5264, 5322, + 5395, 4753, 4936, 5315, 5243, 5060, 4989, 4921, 4480, 3426, 3687, 4220, + 3197, 5139, 6101, 5279, +} + +func withinMargin(a, b float64) bool { + return math.Abs(a-b) <= testMargin +} + +func TestSimpleEWMA(t *testing.T) { + var e SimpleEWMA + for _, f := range samples { + e.Add(f) + } + if !withinMargin(e.Value(), 4734.500946466118) { + t.Errorf("e.Value() is %v, wanted %v", e.Value(), 4734.500946466118) + } + e.Set(1.0) + if e.Value() != 1.0 { + t.Errorf("e.Value() is %d", e.Value()) + } +} + +func TestVariableEWMA(t *testing.T) { + e := NewMovingAverage(30) + for _, f := range samples { + e.Add(f) + } + if !withinMargin(e.Value(), 4734.500946466118) { + t.Errorf("e.Value() is %v, wanted %v", e.Value(), 4734.500946466118) + } + e.Set(1.0) + if e.Value() != 1.0 { + t.Errorf("e.Value() is %d", e.Value()) + } +} + +func TestVariableEWMA2(t *testing.T) { + e := NewMovingAverage(5) + for _, f := range samples { + e.Add(f) + } + if !withinMargin(e.Value(), 5015.397367486725) { + t.Errorf("e.Value() is %v, wanted %v", e.Value(), 5015.397367486725) + } +} + +func TestVariableEWMAWarmup(t *testing.T) { + e := NewMovingAverage(5) + for i, f := range samples { + e.Add(f) + + // all values returned during warmup should be 0.0 + if uint8(i) < WARMUP_SAMPLES { + if e.Value() != 0.0 { + t.Errorf("e.Value() is %v, expected %v", e.Value(), 0.0) + } + } + } + e = NewMovingAverage(5) + e.Set(5) + e.Add(1) + if e.Value() >= 5 { + t.Errorf("e.Value() is %d, expected it to decay towards 0", e.Value()) + } +} + +func TestVariableEWMAWarmup2(t *testing.T) { + e := NewMovingAverage(5) + testSamples := [12]float64{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10000, 1} + for i, f := range testSamples { + e.Add(f) + + // all values returned during warmup should be 0.0 + if uint8(i) < WARMUP_SAMPLES { + if e.Value() != 0.0 { + t.Errorf("e.Value() is %v, expected %v", e.Value(), 0.0) + } + } + } + if val := e.Value(); val == 1.0 { + t.Errorf("e.Value() is expected to be greater than %v", 1.0) + } +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/.gitignore b/vendor/gopkg.in/cheggaaa/pb.v2/.gitignore new file mode 100644 index 000000000..48b8bf907 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/.gitignore @@ -0,0 +1 @@ +vendor/ diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/.travis.yml b/vendor/gopkg.in/cheggaaa/pb.v2/.travis.yml new file mode 100644 index 000000000..7d3bc2399 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/.travis.yml @@ -0,0 +1,13 @@ +language: go +go: +- 1.7 +- 1.8 +sudo: false +gobuild_args: -v -race +os: +- linux +- osx +before_install: + - go get github.com/mattn/goveralls +script: + - $HOME/gopath/bin/goveralls -service=travis-ci -ignore=termutil/* diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.lock b/vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.lock new file mode 100644 index 000000000..fd90c4b6a --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.lock @@ -0,0 +1,63 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/mattn/go-colorable" + packages = ["."] + revision = "ed8eb9e318d7a84ce5915b495b7d35e0cfe7b5a8" + version = "v0.0.6" + +[[projects]] + name = "github.com/mattn/go-isatty" + packages = ["."] + revision = "3a115632dcd687f9c8cd01679c83a06a0e21c1f3" + version = "v0.0.1" + +[[projects]] + branch = "master" + name = "golang.org/x/sys" + packages = ["unix"] + revision = "b90f89a1e7a9c1f6b918820b3daa7f08488c8594" + +[[projects]] + name = "gopkg.in/VividCortex/ewma.v1" + packages = ["."] + revision = "2f8aa9741ab4b5b80945c750b871131b88ef5b7f" + version = "v1.0" + +[[projects]] + name = "gopkg.in/cheggaaa/pb.v2" + packages = ["termutil"] + revision = "180c76fdb3025713f501cd481e47810a9c715bd7" + version = "v2.0.1" + +[[projects]] + name = "gopkg.in/fatih/color.v1" + packages = ["."] + revision = "570b54cabe6b8eb0bc2dfce68d964677d63b5260" + version = "v1.5.0" + +[[projects]] + name = "gopkg.in/mattn/go-colorable.v0" + packages = ["."] + revision = "d228849504861217f796da67fae4f6e347643f15" + version = "v0.0.7" + +[[projects]] + name = "gopkg.in/mattn/go-isatty.v0" + packages = ["."] + revision = "fc9e8d8ef48496124e79ae0df75490096eccf6fe" + version = "v0.0.2" + +[[projects]] + name = "gopkg.in/mattn/go-runewidth.v0" + packages = ["."] + revision = "9e777a8366cce605130a531d2cd6363d07ad7317" + version = "v0.0.2" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "cf10fbfc96962122f1a56c1752a1d5dab64799ffedc58460e1ab1465d2bef5e2" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.toml b/vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.toml new file mode 100644 index 000000000..d5f2fef13 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.toml @@ -0,0 +1,91 @@ + +## Gopkg.toml example (these lines may be deleted) + +## "metadata" defines metadata about the project that could be used by other independent +## systems. The metadata defined here will be ignored by dep. +# [metadata] +# key1 = "value that convey data to other systems" +# system1-data = "value that is used by a system" +# system2-data = "value that is used by another system" + +## "required" lists a set of packages (not projects) that must be included in +## Gopkg.lock. This list is merged with the set of packages imported by the current +## project. Use it when your project needs a package it doesn't explicitly import - +## including "main" packages. +# required = ["github.com/user/thing/cmd/thing"] + +## "ignored" lists a set of packages (not projects) that are ignored when +## dep statically analyzes source code. Ignored packages can be in this project, +## or in a dependency. +# ignored = ["github.com/user/project/badpkg"] + +## Constraints are rules for how directly imported projects +## may be incorporated into the depgraph. They are respected by +## dep whether coming from the Gopkg.toml of the current project or a dependency. +# [[constraint]] +## Required: the root import path of the project being constrained. +# name = "github.com/user/project" +# +## Recommended: the version constraint to enforce for the project. +## Only one of "branch", "version" or "revision" can be specified. +# version = "1.0.0" +# branch = "master" +# revision = "abc123" +# +## Optional: an alternate location (URL or import path) for the project's source. +# source = "https://github.com/myfork/package.git" +# +## "metadata" defines metadata about the dependency or override that could be used +## by other independent systems. The metadata defined here will be ignored by dep. +# [metadata] +# key1 = "value that convey data to other systems" +# system1-data = "value that is used by a system" +# system2-data = "value that is used by another system" + +## Overrides have the same structure as [[constraint]], but supersede all +## [[constraint]] declarations from all projects. Only [[override]] from +## the current project's are applied. +## +## Overrides are a sledgehammer. Use them only as a last resort. +# [[override]] +## Required: the root import path of the project being constrained. +# name = "github.com/user/project" +# +## Optional: specifying a version constraint override will cause all other +## constraints on this project to be ignored; only the overridden constraint +## need be satisfied. +## Again, only one of "branch", "version" or "revision" can be specified. +# version = "1.0.0" +# branch = "master" +# revision = "abc123" +# +## Optional: specifying an alternate source location as an override will +## enforce that the alternate location is used for that project, regardless of +## what source location any dependent projects specify. +# source = "https://github.com/myfork/package.git" + + + +[[constraint]] + name = "gopkg.in/VividCortex/ewma.v1" + version = "1.0.0" + +[[constraint]] + name = "gopkg.in/cheggaaa/pb.v2" + version = "2.0.1" + +[[constraint]] + name = "gopkg.in/fatih/color.v1" + version = "1.5.0" + +[[constraint]] + name = "gopkg.in/mattn/go-colorable.v0" + version = "0.0.7" + +[[constraint]] + name = "gopkg.in/mattn/go-isatty.v0" + version = "0.0.2" + +[[constraint]] + name = "gopkg.in/mattn/go-runewidth.v0" + version = "0.0.2" diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/LICENSE b/vendor/gopkg.in/cheggaaa/pb.v2/LICENSE new file mode 100644 index 000000000..511970333 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/LICENSE @@ -0,0 +1,12 @@ +Copyright (c) 2012-2015, Sergey Cherepanov +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/README.md b/vendor/gopkg.in/cheggaaa/pb.v2/README.md new file mode 100644 index 000000000..907124e19 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/README.md @@ -0,0 +1,70 @@ +# Terminal progress bar for Go + +[![Coverage Status](https://coveralls.io/repos/github/cheggaaa/pb/badge.svg?branch=v2)](https://coveralls.io/github/cheggaaa/pb?branch=v2) + +### It's beta, some features may be changed + +This is proposal for the second version of progress bar +- based on text/template +- can take custom elements +- using colors is easy + +## Installation + +``` +go get gopkg.in/cheggaaa/pb.v2 +``` + +## Usage + +```Go +package main + +import ( + "gopkg.in/cheggaaa/pb.v2" + "time" +) + +func main() { + simple() + fromPreset() + customTemplate(`Custom template: {{counters . }}`) + customTemplate(`{{ red "With colors:" }} {{bar . | green}} {{speed . | blue }}`) + customTemplate(`{{ red "With funcs:" }} {{ bar . "<" "-" (cycle . "↖" "↗" "↘" "↙" ) "." ">"}} {{speed . | rndcolor }}`) + customTemplate(`{{ bar . "[<" "·····•·····" (rnd "ᗧ" "◔" "◕" "◷" ) "•" ">]"}}`) +} + +func simple() { + count := 1000 + bar := pb.StartNew(count) + for i := 0; i < count; i++ { + bar.Increment() + time.Sleep(time.Millisecond * 2) + } + bar.Finish() +} + +func fromPreset() { + count := 1000 + //bar := pb.Default.Start(total) + //bar := pb.Simple.Start(total) + bar := pb.Full.Start(count) + defer bar.Finish() + bar.Set("prefix", "fromPreset(): ") + for i := 0; i < count/2; i++ { + bar.Add(2) + time.Sleep(time.Millisecond * 4) + } +} + +func customTemplate(tmpl string) { + count := 1000 + bar := pb.ProgressBarTemplate(tmpl).Start(count) + defer bar.Finish() + for i := 0; i < count/2; i++ { + bar.Add(2) + time.Sleep(time.Millisecond * 4) + } +} + +``` \ No newline at end of file diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/element.go b/vendor/gopkg.in/cheggaaa/pb.v2/element.go new file mode 100644 index 000000000..965183fe7 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/element.go @@ -0,0 +1,290 @@ +package pb + +import ( + "bytes" + "fmt" + "math" + "sync" + "time" +) + +const ( + adElPlaceholder = "%_ad_el_%" + adElPlaceholderLen = len(adElPlaceholder) +) + +var ( + defaultBarEls = [5]string{"[", "-", ">", "_", "]"} +) + +// Element is an interface for bar elements +type Element interface { + ProgressElement(state *State, args ...string) string +} + +// ElementFunc type implements Element interface and created for simplify elements +type ElementFunc func(state *State, args ...string) string + +// ProgressElement just call self func +func (e ElementFunc) ProgressElement(state *State, args ...string) string { + return e(state, args...) +} + +var elementsM sync.Mutex + +var elements = map[string]Element{ + "percent": ElementPercent, + "counters": ElementCounters, + "bar": adaptiveWrap(ElementBar), + "speed": ElementSpeed, + "rtime": ElementRemainingTime, + "etime": ElementElapsedTime, + "string": ElementString, + "cycle": ElementCycle, +} + +// RegisterElement give you a chance to use custom elements +func RegisterElement(name string, el Element, adaptive bool) { + if adaptive { + el = adaptiveWrap(el) + } + elementsM.Lock() + elements[name] = el + elementsM.Unlock() +} + +type argsHelper []string + +func (args argsHelper) getOr(n int, value string) string { + if len(args) > n { + return args[n] + } + return value +} + +func (args argsHelper) getNotEmptyOr(n int, value string) (v string) { + if v = args.getOr(n, value); v == "" { + return value + } + return +} + +func adaptiveWrap(el Element) Element { + return ElementFunc(func(state *State, args ...string) string { + state.recalc = append(state.recalc, ElementFunc(func(s *State, _ ...string) (result string) { + s.adaptive = true + result = el.ProgressElement(s, args...) + s.adaptive = false + return + })) + return adElPlaceholder + }) +} + +// ElementPercent shows current percent of progress. +// Optionally can take one or two string arguments. +// First string will be used as value for format float64, default is "%.02f%%". +// Second string will be used when percent can't be calculated, default is "?%" +// In template use as follows: {{percent .}} or {{percent . "%.03f%%"}} or {{percent . "%.03f%%" "?"}} +var ElementPercent ElementFunc = func(state *State, args ...string) string { + argsh := argsHelper(args) + if state.Total() > 0 { + return fmt.Sprintf( + argsh.getNotEmptyOr(0, "%.02f%%"), + float64(state.Value())/(float64(state.Total())/float64(100)), + ) + } + return argsh.getOr(1, "?%") +} + +// ElementCounters shows current and total values. +// Optionally can take one or two string arguments. +// First string will be used as format value when Total is present (>0). Default is "%s / %s" +// Second string will be used when total <= 0. Default is "%[1]s" +// In template use as follows: {{counters .}} or {{counters . "%s/%s"}} or {{counters . "%s/%s" "%s/?"}} +var ElementCounters ElementFunc = func(state *State, args ...string) string { + var f string + if state.Total() > 0 { + f = argsHelper(args).getNotEmptyOr(0, "%s / %s") + } else { + f = argsHelper(args).getNotEmptyOr(1, "%[1]s") + } + return fmt.Sprintf(f, state.Format(state.Value()), state.Format(state.Total())) +} + +type elementKey int + +const ( + barObj elementKey = iota + speedObj + cycleObj +) + +type bar struct { + eb [5][]byte // elements in bytes + cc [5]int // cell counts + buf *bytes.Buffer +} + +func (p *bar) write(state *State, eln, width int) int { + repeat := width / p.cc[eln] + for i := 0; i < repeat; i++ { + p.buf.Write(p.eb[eln]) + } + StripStringToBuffer(string(p.eb[eln]), width%p.cc[eln], p.buf) + return width +} + +func getProgressObj(state *State, args ...string) (p *bar) { + var ok bool + if p, ok = state.Get(barObj).(*bar); !ok { + p = &bar{ + buf: bytes.NewBuffer(nil), + } + state.Set(barObj, p) + } + argsH := argsHelper(args) + for i := range p.eb { + arg := argsH.getNotEmptyOr(i, defaultBarEls[i]) + if string(p.eb[i]) != arg { + p.cc[i] = CellCount(arg) + p.eb[i] = []byte(arg) + if p.cc[i] == 0 { + p.cc[i] = 1 + p.eb[i] = []byte(" ") + } + } + } + return +} + +// ElementBar make progress bar view [-->__] +// Optionally can take up to 5 string arguments. Defaults is "[", "-", ">", "_", "]" +// In template use as follows: {{bar . }} or {{bar . "<" "oOo" "|" "~" ">"}} +// Color args: {{bar . (red "[") (green "-") ... +var ElementBar ElementFunc = func(state *State, args ...string) string { + // init + var p = getProgressObj(state, args...) + + total, value := state.Total(), state.Value() + if total < 0 { + total = -total + } + if value < 0 { + value = -value + } + + // check for overflow + if total != 0 && value > total { + total = value + } + + p.buf.Reset() + + var widthLeft = state.AdaptiveElWidth() + if widthLeft <= 0 || !state.IsAdaptiveWidth() { + widthLeft = 30 + } + + // write left border + if p.cc[0] < widthLeft { + widthLeft -= p.write(state, 0, p.cc[0]) + } else { + p.write(state, 0, widthLeft) + return p.buf.String() + } + + // check right border size + if p.cc[4] < widthLeft { + // write later + widthLeft -= p.cc[4] + } else { + p.write(state, 4, widthLeft) + return p.buf.String() + } + + var curCount int + + if total > 0 { + // calculate count of currenct space + curCount = int(math.Ceil((float64(value) / float64(total)) * float64(widthLeft))) + } + + // write bar + if total == value && state.IsFinished() { + widthLeft -= p.write(state, 1, curCount) + } else if toWrite := curCount - p.cc[2]; toWrite > 0 { + widthLeft -= p.write(state, 1, toWrite) + widthLeft -= p.write(state, 2, p.cc[2]) + } else if curCount > 0 { + widthLeft -= p.write(state, 2, curCount) + } + if widthLeft > 0 { + widthLeft -= p.write(state, 3, widthLeft) + } + // write right border + p.write(state, 4, p.cc[4]) + // cut result and return string + return p.buf.String() +} + +// ElementRemainingTime calculates remaining time based on speed (EWMA) +// Optionally can take one or two string arguments. +// First string will be used as value for format time duration string, default is "%s". +// Second string will be used when bar finished and value indicates elapsed time, default is "%s" +// Third string will be used when value not available, default is "?" +// In template use as follows: {{rtime .}} or {{rtime . "%s remain"}} or {{rtime . "%s remain" "%s total" "???"}} +var ElementRemainingTime ElementFunc = func(state *State, args ...string) string { + var rts string + sp := getSpeedObj(state).value(state) + if !state.IsFinished() { + if sp > 0 { + remain := float64(state.Total() - state.Value()) + remainDur := time.Duration(remain/sp) * time.Second + rts = remainDur.String() + } else { + return argsHelper(args).getOr(2, "?") + } + } else { + rts = state.Time().Truncate(time.Second).Sub(state.StartTime().Truncate(time.Second)).String() + return fmt.Sprintf(argsHelper(args).getOr(1, "%s"), rts) + } + return fmt.Sprintf(argsHelper(args).getOr(0, "%s"), rts) +} + +// ElementElapsedTime shows elapsed time +// Optionally cat take one argument - it's format for time string. +// In template use as follows: {{etime .}} or {{etime . "%s elapsed"}} +var ElementElapsedTime ElementFunc = func(state *State, args ...string) string { + etm := state.Time().Truncate(time.Second).Sub(state.StartTime().Truncate(time.Second)) + return fmt.Sprintf(argsHelper(args).getOr(0, "%s"), etm.String()) +} + +// ElementString get value from bar by given key and print them +// bar.Set("myKey", "string to print") +// In template use as follows: {{string . "myKey"}} +var ElementString ElementFunc = func(state *State, args ...string) string { + if len(args) == 0 { + return "" + } + v := state.Get(args[0]) + if v == nil { + return "" + } + return fmt.Sprint(v) +} + +// ElementCycle return next argument for every call +// In template use as follows: {{cycle . "1" "2" "3"}} +// Or mix width other elements: {{ bar . "" "" (cycle . "↖" "↗" "↘" "↙" )}} +var ElementCycle ElementFunc = func(state *State, args ...string) string { + if len(args) == 0 { + return "" + } + n, _ := state.Get(cycleObj).(int) + if n >= len(args) { + n = 0 + } + state.Set(cycleObj, n+1) + return args[n] +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/element_test.go b/vendor/gopkg.in/cheggaaa/pb.v2/element_test.go new file mode 100644 index 000000000..d572c4a6a --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/element_test.go @@ -0,0 +1,278 @@ +package pb + +import ( + "fmt" + "strings" + "testing" + "time" + + "gopkg.in/fatih/color.v1" +) + +func testState(total, value int64, maxWidth int, bools ...bool) (s *State) { + s = &State{ + total: total, + current: value, + adaptiveElWidth: maxWidth, + ProgressBar: new(ProgressBar), + } + if len(bools) > 0 { + s.Set(Bytes, bools[0]) + } + if len(bools) > 1 && bools[1] { + s.adaptive = true + } + return +} + +func testElementBarString(t *testing.T, state *State, el Element, want string, args ...string) { + if state.ProgressBar == nil { + state.ProgressBar = new(ProgressBar) + } + res := el.ProgressElement(state, args...) + if res != want { + t.Errorf("Unexpected result: '%s'; want: '%s'", res, want) + } + if state.IsAdaptiveWidth() && state.AdaptiveElWidth() != CellCount(res) { + t.Errorf("Unepected width: %d; want: %d", CellCount(res), state.AdaptiveElWidth()) + } +} + +func TestElementPercent(t *testing.T) { + testElementBarString(t, testState(100, 50, 0), ElementPercent, "50.00%") + testElementBarString(t, testState(100, 50, 0), ElementPercent, "50 percent", "%v percent") + testElementBarString(t, testState(0, 50, 0), ElementPercent, "?%") + testElementBarString(t, testState(0, 50, 0), ElementPercent, "unkn", "%v%%", "unkn") +} + +func TestElementCounters(t *testing.T) { + testElementBarString(t, testState(100, 50, 0), ElementCounters, "50 / 100") + testElementBarString(t, testState(100, 50, 0), ElementCounters, "50 of 100", "%s of %s") + testElementBarString(t, testState(100, 50, 0, true), ElementCounters, "50 B of 100 B", "%s of %s") + testElementBarString(t, testState(100, 50, 0, true), ElementCounters, "50 B / 100 B") + testElementBarString(t, testState(0, 50, 0, true), ElementCounters, "50 B") + testElementBarString(t, testState(0, 50, 0, true), ElementCounters, "50 B / ?", "", "%[1]s / ?") +} + +func TestElementBar(t *testing.T) { + // short + testElementBarString(t, testState(100, 50, 1, false, true), ElementBar, "[") + testElementBarString(t, testState(100, 50, 2, false, true), ElementBar, "[]") + testElementBarString(t, testState(100, 50, 3, false, true), ElementBar, "[>]") + testElementBarString(t, testState(100, 50, 4, false, true), ElementBar, "[>_]") + testElementBarString(t, testState(100, 50, 5, false, true), ElementBar, "[->_]") + // middle + testElementBarString(t, testState(100, 50, 10, false, true), ElementBar, "[--->____]") + testElementBarString(t, testState(100, 50, 10, false, true), ElementBar, "<--->____>", "<", "", "", "", ">") + // finished + st := testState(100, 100, 10, false, true) + st.finished = true + testElementBarString(t, st, ElementBar, "[--------]") + // empty color + st = testState(100, 50, 10, false, true) + st.Set(Terminal, true) + color.NoColor = false + testElementBarString(t, st, ElementBar, " --->____]", color.RedString("%s", "")) + // empty + testElementBarString(t, testState(0, 50, 10, false, true), ElementBar, "[________]") + // full + testElementBarString(t, testState(20, 20, 10, false, true), ElementBar, "[------->]") + // everflow + testElementBarString(t, testState(20, 50, 10, false, true), ElementBar, "[------->]") + // small width + testElementBarString(t, testState(20, 50, 2, false, true), ElementBar, "[]") + testElementBarString(t, testState(20, 50, 1, false, true), ElementBar, "[") + // negative counters + testElementBarString(t, testState(-50, -150, 10, false, true), ElementBar, "[------->]") + testElementBarString(t, testState(-150, -50, 10, false, true), ElementBar, "[-->_____]") + testElementBarString(t, testState(50, -150, 10, false, true), ElementBar, "[------->]") + testElementBarString(t, testState(-50, 150, 10, false, true), ElementBar, "[------->]") + // long entities / unicode + f1 := []string{"進捗|", "многобайт", "active", "пусто", "|end"} + testElementBarString(t, testState(100, 50, 1, false, true), ElementBar, " ", f1...) + testElementBarString(t, testState(100, 50, 3, false, true), ElementBar, "進 ", f1...) + testElementBarString(t, testState(100, 50, 4, false, true), ElementBar, "進捗", f1...) + testElementBarString(t, testState(100, 50, 29, false, true), ElementBar, "進捗|многactiveпустопусто|end", f1...) + testElementBarString(t, testState(100, 50, 11, false, true), ElementBar, "進捗|aп|end", f1...) + + // unicode + f2 := []string{"⚑", "⚒", "⚟", "⟞", "⚐"} + testElementBarString(t, testState(100, 50, 10, false, true), ElementBar, "⚑⚒⚒⚒⚟⟞⟞⟞⟞⚐", f2...) + + // no adaptive + testElementBarString(t, testState(0, 50, 10), ElementBar, "[____________________________]") + + var formats = [][]string{ + []string{}, + f1, f2, + } + + // all widths / extreme values + // check for panic and correct width + for _, f := range formats { + for tt := int64(-2); tt < 12; tt++ { + for v := int64(-2); v < 12; v++ { + state := testState(tt, v, 0, false, true) + for w := -2; w < 20; w++ { + state.adaptiveElWidth = w + res := ElementBar(state, f...) + var we = w + if we <= 0 { + we = 30 + } + if CellCount(res) != we { + t.Errorf("Unexpected len(%d): '%s'", we, res) + } + } + } + } + } +} + +func TestElementSpeed(t *testing.T) { + var state = testState(1000, 0, 0, false) + state.time = time.Now() + for i := int64(0); i < 10; i++ { + state.id = uint64(i) + 1 + state.current += 42 + state.time = state.time.Add(time.Second) + state.finished = i == 9 + if state.finished { + state.current += 100 + } + r := ElementSpeed(state) + r2 := ElementSpeed(state) + if r != r2 { + t.Errorf("Must be the same: '%s' vs '%s'", r, r2) + } + if i < 1 { + // do not calc first result + if w := "? p/s"; r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + } else if state.finished { + if w := "58 p/s"; r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + state.time = state.time.Add(-time.Hour) + r = ElementSpeed(state) + if w := "? p/s"; r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + } else { + if w := "42 p/s"; r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + } + } +} + +func TestElementRemainingTime(t *testing.T) { + var state = testState(100, 0, 0, false) + state.time = time.Now() + state.startTime = state.time + for i := int64(0); i < 10; i++ { + state.id = uint64(i) + 1 + state.time = state.time.Add(time.Second) + state.finished = i == 9 + r := ElementRemainingTime(state) + if i < 1 { + // do not calc first two results + if w := "?"; r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + } else if state.finished { + // final elapsed time + if w := "10s"; r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + } else { + w := fmt.Sprintf("%ds", 10-i) + if r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + } + state.current += 10 + } +} + +func TestElementElapsedTime(t *testing.T) { + var state = testState(1000, 0, 0, false) + state.startTime = time.Now() + state.time = state.startTime + for i := int64(0); i < 10; i++ { + r := ElementElapsedTime(state) + if w := fmt.Sprintf("%ds", i); r != w { + t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) + } + state.time = state.time.Add(time.Second) + } +} + +func TestElementString(t *testing.T) { + var state = testState(0, 0, 0, false) + testElementBarString(t, state, ElementString, "", "myKey") + state.Set("myKey", "my value") + testElementBarString(t, state, ElementString, "my value", "myKey") + state.Set("myKey", "my value1") + testElementBarString(t, state, ElementString, "my value1", "myKey") + testElementBarString(t, state, ElementString, "") +} + +func TestElementCycle(t *testing.T) { + var state = testState(0, 0, 0, false) + testElementBarString(t, state, ElementCycle, "") + testElementBarString(t, state, ElementCycle, "1", "1", "2", "3") + testElementBarString(t, state, ElementCycle, "2", "1", "2", "3") + testElementBarString(t, state, ElementCycle, "3", "1", "2", "3") + testElementBarString(t, state, ElementCycle, "1", "1", "2", "3") + testElementBarString(t, state, ElementCycle, "2", "1", "2") + testElementBarString(t, state, ElementCycle, "1", "1", "2") +} + +func TestAdaptiveWrap(t *testing.T) { + var state = testState(0, 0, 0, false) + state.id = 1 + state.Set("myKey", "my value") + el := adaptiveWrap(ElementString) + testElementBarString(t, state, el, adElPlaceholder, "myKey") + if v := state.recalc[0].ProgressElement(state); v != "my value" { + t.Errorf("Unexpected result: %s", v) + } + state.id = 2 + testElementBarString(t, state, el, adElPlaceholder, "myKey1") + state.Set("myKey", "my value1") + if v := state.recalc[0].ProgressElement(state); v != "my value1" { + t.Errorf("Unexpected result: %s", v) + } +} + +func TestRegisterElement(t *testing.T) { + var testEl ElementFunc = func(state *State, args ...string) string { + return strings.Repeat("*", state.AdaptiveElWidth()) + } + RegisterElement("testEl", testEl, true) + result := ProgressBarTemplate(`{{testEl . }}`).New(0).SetWidth(5).String() + if result != "*****" { + t.Errorf("Unexpected result: '%v'", result) + } +} + +func BenchmarkBar(b *testing.B) { + var formats = map[string][]string{ + "simple": []string{".", ".", ".", ".", "."}, + "unicode": []string{"⚑", "⚒", "⚟", "⟞", "⚐"}, + "color": []string{color.RedString("%s", "."), color.RedString("%s", "."), color.RedString("%s", "."), color.RedString("%s", "."), color.RedString("%s", ".")}, + "long": []string{"..", "..", "..", "..", ".."}, + "longunicode": []string{"⚑⚑", "⚒⚒", "⚟⚟", "⟞⟞", "⚐⚐"}, + } + for name, args := range formats { + state := testState(100, 50, 100, false, true) + b.Run(name, func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + ElementBar(state, args...) + } + }) + } +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/pb.go b/vendor/gopkg.in/cheggaaa/pb.v2/pb.go new file mode 100644 index 000000000..c8e7b52ae --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/pb.go @@ -0,0 +1,540 @@ +package pb + +import ( + "bytes" + "fmt" + "io" + "os" + "strconv" + "strings" + "sync" + "sync/atomic" + "text/template" + "time" + + "gopkg.in/cheggaaa/pb.v2/termutil" + "gopkg.in/mattn/go-colorable.v0" + "gopkg.in/mattn/go-isatty.v0" +) + +// Version of ProgressBar library +const Version = "2.0.6" + +type key int + +const ( + // Bytes means we're working with byte sizes. Numbers will print as Kb, Mb, etc + // bar.Set(pb.Bytes, true) + Bytes key = 1 << iota + + // Terminal means we're will print to terminal and can use ascii sequences + // Also we're will try to use terminal width + Terminal + + // Static means progress bar will not update automaticly + Static + + // ReturnSymbol - by default in terminal mode it's '\r' + ReturnSymbol + + // Color by default is true when output is tty, but you can set to false for disabling colors + Color +) + +const ( + defaultBarWidth = 100 + defaultRefreshRate = time.Millisecond * 200 +) + +// New creates new ProgressBar object +func New(total int) *ProgressBar { + return New64(int64(total)) +} + +// New64 creates new ProgressBar object using int64 as total +func New64(total int64) *ProgressBar { + pb := new(ProgressBar) + return pb.SetTotal(total) +} + +// StartNew starts new ProgressBar with Default template +func StartNew(total int) *ProgressBar { + return New(total).Start() +} + +// Start64 starts new ProgressBar with Default template. Using int64 as total. +func Start64(total int64) *ProgressBar { + return New64(total).Start() +} + +var ( + terminalWidth = termutil.TerminalWidth + isTerminal = isatty.IsTerminal + isCygwinTerminal = isatty.IsCygwinTerminal +) + +// ProgressBar is the main object of bar +type ProgressBar struct { + current, total int64 + width int + mu sync.RWMutex + rm sync.Mutex + vars map[interface{}]interface{} + elements map[string]Element + output io.Writer + coutput io.Writer + nocoutput io.Writer + startTime time.Time + refreshRate time.Duration + tmpl *template.Template + state *State + buf *bytes.Buffer + ticker *time.Ticker + finish chan struct{} + finished bool + configured bool + err error +} + +func (pb *ProgressBar) configure() { + if pb.configured { + return + } + pb.configured = true + + if pb.vars == nil { + pb.vars = make(map[interface{}]interface{}) + } + if pb.output == nil { + pb.output = os.Stderr + } + + if pb.tmpl == nil { + pb.tmpl, pb.err = getTemplate(string(Default)) + if pb.err != nil { + return + } + } + if pb.vars[Terminal] == nil { + if f, ok := pb.output.(*os.File); ok { + if isTerminal(f.Fd()) || isCygwinTerminal(f.Fd()) { + pb.vars[Terminal] = true + } + } + } + if pb.vars[ReturnSymbol] == nil { + if tm, ok := pb.vars[Terminal].(bool); ok && tm { + pb.vars[ReturnSymbol] = "\r" + } + } + if pb.vars[Color] == nil { + if tm, ok := pb.vars[Terminal].(bool); ok && tm { + pb.vars[Color] = true + } + } + if pb.refreshRate == 0 { + pb.refreshRate = defaultRefreshRate + } + if f, ok := pb.output.(*os.File); ok { + pb.coutput = colorable.NewColorable(f) + } else { + pb.coutput = pb.output + } + pb.nocoutput = colorable.NewNonColorable(pb.output) +} + +// Start starts the bar +func (pb *ProgressBar) Start() *ProgressBar { + pb.mu.Lock() + defer pb.mu.Unlock() + if pb.finish != nil { + return pb + } + pb.configure() + pb.finished = false + pb.state = nil + pb.startTime = time.Now() + if st, ok := pb.vars[Static].(bool); ok && st { + return pb + } + pb.finish = make(chan struct{}) + pb.ticker = time.NewTicker(pb.refreshRate) + go pb.writer(pb.finish) + return pb +} + +func (pb *ProgressBar) writer(finish chan struct{}) { + for { + select { + case <-pb.ticker.C: + pb.write(false) + case <-finish: + pb.ticker.Stop() + pb.write(true) + finish <- struct{}{} + return + } + } +} + +// Write performs write to the output +func (pb *ProgressBar) Write() *ProgressBar { + pb.mu.RLock() + finished := pb.finished + pb.mu.RUnlock() + pb.write(finished) + return pb +} + +func (pb *ProgressBar) write(finish bool) { + result, width := pb.render() + if pb.Err() != nil { + return + } + if pb.GetBool(Terminal) { + if r := (width - CellCount(result)); r > 0 { + result += strings.Repeat(" ", r) + } + } + if ret, ok := pb.Get(ReturnSymbol).(string); ok { + result = ret + result + if finish && ret == "\r" { + result += "\n" + } + } + if pb.GetBool(Color) { + pb.coutput.Write([]byte(result)) + } else { + pb.nocoutput.Write([]byte(result)) + } +} + +// Total return current total bar value +func (pb *ProgressBar) Total() int64 { + return atomic.LoadInt64(&pb.total) +} + +// SetTotal sets the total bar value +func (pb *ProgressBar) SetTotal(value int64) *ProgressBar { + atomic.StoreInt64(&pb.total, value) + return pb +} + +// SetCurrent sets the current bar value +func (pb *ProgressBar) SetCurrent(value int64) *ProgressBar { + atomic.StoreInt64(&pb.current, value) + return pb +} + +// Current return current bar value +func (pb *ProgressBar) Current() int64 { + return atomic.LoadInt64(&pb.current) +} + +// Add adding given int64 value to bar value +func (pb *ProgressBar) Add64(value int64) *ProgressBar { + atomic.AddInt64(&pb.current, value) + return pb +} + +// Add adding given int value to bar value +func (pb *ProgressBar) Add(value int) *ProgressBar { + return pb.Add64(int64(value)) +} + +// Increment atomically increments the progress +func (pb *ProgressBar) Increment() *ProgressBar { + return pb.Add64(1) +} + +// Set sets any value by any key +func (pb *ProgressBar) Set(key, value interface{}) *ProgressBar { + pb.mu.Lock() + defer pb.mu.Unlock() + if pb.vars == nil { + pb.vars = make(map[interface{}]interface{}) + } + pb.vars[key] = value + return pb +} + +// Get return value by key +func (pb *ProgressBar) Get(key interface{}) interface{} { + pb.mu.RLock() + defer pb.mu.RUnlock() + if pb.vars == nil { + return nil + } + return pb.vars[key] +} + +// GetBool return value by key and try to convert there to boolean +// If value doesn't set or not boolean - return false +func (pb *ProgressBar) GetBool(key interface{}) bool { + if v, ok := pb.Get(key).(bool); ok { + return v + } + return false +} + +// SetWidth sets the bar width +// When given value <= 0 would be using the terminal width (if possible) or default value. +func (pb *ProgressBar) SetWidth(width int) *ProgressBar { + pb.mu.Lock() + pb.width = width + pb.mu.Unlock() + return pb +} + +// Width return the bar width +// It's current terminal width or settled over 'SetWidth' value. +func (pb *ProgressBar) Width() (width int) { + defer func() { + if r := recover(); r != nil { + width = defaultBarWidth + } + }() + pb.mu.RLock() + width = pb.width + pb.mu.RUnlock() + if width <= 0 { + var err error + if width, err = terminalWidth(); err != nil { + return defaultBarWidth + } + } + return +} + +func (pb *ProgressBar) SetRefreshRate(dur time.Duration) *ProgressBar { + pb.mu.Lock() + if dur > 0 { + pb.refreshRate = dur + } + pb.mu.Unlock() + return pb +} + +// SetWriter sets the io.Writer. Bar will write in this writer +// By default this is os.Stderr +func (pb *ProgressBar) SetWriter(w io.Writer) *ProgressBar { + pb.mu.Lock() + pb.output = w + pb.configured = false + pb.configure() + pb.mu.Unlock() + return pb +} + +// StartTime return the time when bar started +func (pb *ProgressBar) StartTime() time.Time { + pb.mu.RLock() + defer pb.mu.RUnlock() + return pb.startTime +} + +// Format convert int64 to string according to the current settings +func (pb *ProgressBar) Format(v int64) string { + if pb.GetBool(Bytes) { + return formatBytes(v) + } + return strconv.FormatInt(v, 10) +} + +// Finish stops the bar +func (pb *ProgressBar) Finish() *ProgressBar { + pb.mu.Lock() + if pb.finished { + pb.mu.Unlock() + return pb + } + finishChan := pb.finish + pb.finished = true + pb.mu.Unlock() + if finishChan != nil { + finishChan <- struct{}{} + <-finishChan + pb.mu.Lock() + pb.finish = nil + pb.mu.Unlock() + } + return pb +} + +// IsStarted indicates progress bar state +func (pb *ProgressBar) IsStarted() bool { + pb.mu.RLock() + defer pb.mu.RUnlock() + return pb.finish != nil +} + +// SetTemplateString sets ProgressBar tempate string and parse it +func (pb *ProgressBar) SetTemplateString(tmpl string) *ProgressBar { + pb.mu.Lock() + defer pb.mu.Unlock() + pb.tmpl, pb.err = getTemplate(tmpl) + return pb +} + +// SetTemplateString sets ProgressBarTempate and parse it +func (pb *ProgressBar) SetTemplate(tmpl ProgressBarTemplate) *ProgressBar { + return pb.SetTemplateString(string(tmpl)) +} + +// NewProxyReader creates a wrapper for given reader, but with progress handle +// Takes io.Reader or io.ReadCloser +// Also, it automatically switches progress bar to handle units as bytes +func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader { + pb.Set(Bytes, true) + return &Reader{r, pb} +} + +func (pb *ProgressBar) render() (result string, width int) { + defer func() { + if r := recover(); r != nil { + pb.SetErr(fmt.Errorf("render panic: %v", r)) + } + }() + pb.rm.Lock() + defer pb.rm.Unlock() + pb.mu.Lock() + pb.configure() + if pb.state == nil { + pb.state = &State{ProgressBar: pb} + pb.buf = bytes.NewBuffer(nil) + } + if pb.startTime.IsZero() { + pb.startTime = time.Now() + } + pb.state.id++ + pb.state.finished = pb.finished + pb.state.time = time.Now() + pb.mu.Unlock() + + pb.state.width = pb.Width() + width = pb.state.width + pb.state.total = pb.Total() + pb.state.current = pb.Current() + pb.buf.Reset() + + if e := pb.tmpl.Execute(pb.buf, pb.state); e != nil { + pb.SetErr(e) + return "", 0 + } + + result = pb.buf.String() + + aec := len(pb.state.recalc) + if aec == 0 { + // no adaptive elements + return + } + + staticWidth := CellCount(result) - (aec * adElPlaceholderLen) + + if pb.state.Width()-staticWidth <= 0 { + result = strings.Replace(result, adElPlaceholder, "", -1) + result = StripString(result, pb.state.Width()) + } else { + pb.state.adaptiveElWidth = (width - staticWidth) / aec + for _, el := range pb.state.recalc { + result = strings.Replace(result, adElPlaceholder, el.ProgressElement(pb.state), 1) + } + } + pb.state.recalc = pb.state.recalc[:0] + return +} + +// SetErr sets error to the ProgressBar +// Error will be available over Err() +func (pb *ProgressBar) SetErr(err error) *ProgressBar { + pb.mu.Lock() + pb.err = err + pb.mu.Unlock() + return pb +} + +// Err return possible error +// When all ok - will be nil +// May contain template.Execute errors +func (pb *ProgressBar) Err() error { + pb.mu.RLock() + defer pb.mu.RUnlock() + return pb.err +} + +// String return currrent string representation of ProgressBar +func (pb *ProgressBar) String() string { + res, _ := pb.render() + return res +} + +// ProgressElement implements Element interface +func (pb *ProgressBar) ProgressElement(s *State, args ...string) string { + if s.IsAdaptiveWidth() { + pb.SetWidth(s.AdaptiveElWidth()) + } + return pb.String() +} + +// State represents the current state of bar +// Need for bar elements +type State struct { + *ProgressBar + + id uint64 + total, current int64 + width, adaptiveElWidth int + finished, adaptive bool + time time.Time + + recalc []Element +} + +// Id it's the current state identifier +// - incremental +// - starts with 1 +// - resets after finish/start +func (s *State) Id() uint64 { + return s.id +} + +// Total it's bar int64 total +func (s *State) Total() int64 { + return s.total +} + +// Value it's current value +func (s *State) Value() int64 { + return s.current +} + +// Width of bar +func (s *State) Width() int { + return s.width +} + +// AdaptiveElWidth - adaptive elements must return string with given cell count (when AdaptiveElWidth > 0) +func (s *State) AdaptiveElWidth() int { + return s.adaptiveElWidth +} + +// IsAdaptiveWidth returns true when element must be shown as adaptive +func (s *State) IsAdaptiveWidth() bool { + return s.adaptive +} + +// IsFinished return true when bar is finished +func (s *State) IsFinished() bool { + return s.finished +} + +// IsFirst return true only in first render +func (s *State) IsFirst() bool { + return s.id == 1 +} + +// Time when state was created +func (s *State) Time() time.Time { + return s.time +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/pb_test.go b/vendor/gopkg.in/cheggaaa/pb.v2/pb_test.go new file mode 100644 index 000000000..929778466 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/pb_test.go @@ -0,0 +1,219 @@ +package pb + +import ( + "bytes" + "errors" + "fmt" + "strings" + "testing" + "time" + + "gopkg.in/fatih/color.v1" +) + +func TestPBBasic(t *testing.T) { + bar := new(ProgressBar) + var a, e int64 + if a, e = bar.Total(), 0; a != e { + t.Errorf("Unexpected total: actual: %v; expected: %v", a, e) + } + if a, e = bar.Current(), 0; a != e { + t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) + } + bar.SetCurrent(10).SetTotal(20) + if a, e = bar.Total(), 20; a != e { + t.Errorf("Unexpected total: actual: %v; expected: %v", a, e) + } + if a, e = bar.Current(), 10; a != e { + t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) + } + bar.Add(5) + if a, e = bar.Current(), 15; a != e { + t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) + } + bar.Increment() + if a, e = bar.Current(), 16; a != e { + t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) + } +} + +func TestPBWidth(t *testing.T) { + terminalWidth = func() (int, error) { + return 50, nil + } + // terminal width + bar := new(ProgressBar) + if a, e := bar.Width(), 50; a != e { + t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) + } + // terminal width error + terminalWidth = func() (int, error) { + return 0, errors.New("test error") + } + if a, e := bar.Width(), defaultBarWidth; a != e { + t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) + } + // terminal width panic + terminalWidth = func() (int, error) { + panic("test") + return 0, nil + } + if a, e := bar.Width(), defaultBarWidth; a != e { + t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) + } + // set negative terminal width + bar.SetWidth(-42) + if a, e := bar.Width(), defaultBarWidth; a != e { + t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) + } + // set terminal width + bar.SetWidth(42) + if a, e := bar.Width(), 42; a != e { + t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) + } +} + +func TestPBTemplate(t *testing.T) { + bar := new(ProgressBar) + result := bar.SetTotal(100).SetCurrent(50).SetWidth(40).String() + expected := "50 / 100 [------->________] 50.00% ? p/s" + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) + } + + // check strip + result = bar.SetWidth(8).String() + expected = "50 / 100" + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) + } + + // invalid template + for _, invalidTemplate := range []string{ + `{{invalid template`, `{{speed}}`, + } { + bar.SetTemplateString(invalidTemplate) + result = bar.String() + expected = "" + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) + } + if err := bar.Err(); err == nil { + t.Errorf("Must be error") + } + } + + // simple template without adaptive elemnts + bar.SetTemplateString(`{{counters . }}`) + result = bar.String() + expected = "50 / 100" + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) + } +} + +func TestPBStartFinish(t *testing.T) { + bar := ProgressBarTemplate(`{{counters . }}`).New(0) + for i := int64(0); i < 2; i++ { + if bar.IsStarted() { + t.Error("Must be false") + } + var buf = bytes.NewBuffer(nil) + bar.SetTotal(100). + SetCurrent(int64(i)). + SetWidth(7). + Set(Terminal, true). + SetWriter(buf). + SetRefreshRate(time.Millisecond * 20). + Start() + if !bar.IsStarted() { + t.Error("Must be true") + } + time.Sleep(time.Millisecond * 100) + bar.Finish() + if buf.Len() == 0 { + t.Error("no writes") + } + var resultsString = strings.TrimPrefix(buf.String(), "\r") + if !strings.HasSuffix(resultsString, "\n") { + t.Error("No end \\n symb") + } else { + resultsString = resultsString[:len(resultsString)-1] + } + var results = strings.Split(resultsString, "\r") + if len(results) < 3 { + t.Errorf("Unexpected writes count: %v", len(results)) + } + exp := fmt.Sprintf("%d / 100", i) + for i, res := range results { + if res != exp { + t.Errorf("Unexpected result[%d]: '%v'", i, res) + } + } + // test second finish call + bar.Finish() + } +} + +func TestPBFlags(t *testing.T) { + // Static + color.NoColor = false + buf := bytes.NewBuffer(nil) + bar := ProgressBarTemplate(`{{counters . | red}}`).New(100) + bar.Set(Static, true).SetCurrent(50).SetWidth(10).SetWriter(buf).Start() + if bar.IsStarted() { + t.Error("Must be false") + } + bar.Write() + result := buf.String() + expected := "50 / 100" + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected) + } + if !bar.state.IsFirst() { + t.Error("must be true") + } + // Color + bar.Set(Color, true) + buf.Reset() + bar.Write() + result = buf.String() + expected = color.RedString("50 / 100") + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected) + } + if bar.state.IsFirst() { + t.Error("must be false") + } + // Terminal + bar.Set(Terminal, true).SetWriter(buf) + buf.Reset() + bar.Write() + result = buf.String() + expected = "\r" + color.RedString("50 / 100") + " " + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected) + } +} + +func BenchmarkRender(b *testing.B) { + var formats = []string{ + string(Simple), + string(Default), + string(Full), + `{{string . "prefix" | red}}{{counters . | green}} {{bar . | yellow}} {{percent . | cyan}} {{speed . | cyan}}{{string . "suffix" | cyan}}`, + } + var names = []string{ + "Simple", "Default", "Full", "Color", + } + for i, tmpl := range formats { + bar := new(ProgressBar) + bar.SetTemplateString(tmpl).SetWidth(100) + b.Run(names[i], func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + bar.String() + } + }) + } +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/preset.go b/vendor/gopkg.in/cheggaaa/pb.v2/preset.go new file mode 100644 index 000000000..1934c0e88 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/preset.go @@ -0,0 +1,17 @@ +package pb + +import () + +var ( + // Full - preset with all default available elements + // Example: 'Prefix 20/100 [-->______] 20% 1 p/s ETA 1m Suffix' + Full ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }} {{speed . }} {{rtime . "ETA %s"}}{{string . "suffix"}}` + + // Default - preset like Full but without elapsed time + // Example: 'Prefix 20/100 [-->______] 20% 1 p/s ETA 1m Suffix' + Default ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }} {{speed . }}{{string . "suffix"}}` + + // Simple - preset without speed and any timers. Only counters, bar and percents + // Example: 'Prefix 20/100 [-->______] 20% Suffix' + Simple ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }}{{string . "suffix"}}` +) diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/reader.go b/vendor/gopkg.in/cheggaaa/pb.v2/reader.go new file mode 100644 index 000000000..f2e60a09d --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/reader.go @@ -0,0 +1,26 @@ +package pb + +import ( + "io" +) + +// Reader it's a wrapper for given reader, but with progress handle +type Reader struct { + io.Reader + bar *ProgressBar +} + +// Read reads bytes from wrapped reader and add amount of bytes to progress bar +func (r *Reader) Read(p []byte) (n int, err error) { + n, err = r.Reader.Read(p) + r.bar.Add(n) + return +} + +// Close the wrapped reader when it implements io.Closer +func (r *Reader) Close() (err error) { + if closer, ok := r.Reader.(io.Closer); ok { + return closer.Close() + } + return +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/reader_test.go b/vendor/gopkg.in/cheggaaa/pb.v2/reader_test.go new file mode 100644 index 000000000..a5d745a0b --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/reader_test.go @@ -0,0 +1,60 @@ +package pb + +import ( + "testing" +) + +func TestPBProxyReader(t *testing.T) { + bar := new(ProgressBar) + if bar.GetBool(Bytes) { + t.Errorf("By default bytes must be false") + } + + testReader := new(testReaderCloser) + proxyReader := bar.NewProxyReader(testReader) + + if !bar.GetBool(Bytes) { + t.Errorf("Bytes must be true after call NewProxyReader") + } + + for i := 0; i < 10; i++ { + buf := make([]byte, 10) + n, e := proxyReader.Read(buf) + if e != nil { + t.Errorf("Proxy reader return err: %v", e) + } + if n != len(buf) { + t.Errorf("Proxy reader return unexpected N: %d (wand %d)", n, len(buf)) + } + for _, b := range buf { + if b != 'f' { + t.Errorf("Unexpected read value: %v (want %v)", b, 'f') + } + } + if want := int64((i + 1) * len(buf)); bar.Current() != want { + t.Errorf("Unexpected bar current value: %d (want %d)", bar.Current(), want) + } + } + proxyReader.Close() + if !testReader.closed { + t.Errorf("Reader must be closed after call ProxyReader.Close") + } + proxyReader.Reader = nil + proxyReader.Close() +} + +type testReaderCloser struct { + closed bool +} + +func (tr *testReaderCloser) Read(p []byte) (n int, err error) { + for i := range p { + p[i] = 'f' + } + return len(p), nil +} + +func (tr *testReaderCloser) Close() (err error) { + tr.closed = true + return +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/speed.go b/vendor/gopkg.in/cheggaaa/pb.v2/speed.go new file mode 100644 index 000000000..4cf34b1d1 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/speed.go @@ -0,0 +1,83 @@ +package pb + +import ( + "fmt" + "math" + "time" + + "gopkg.in/VividCortex/ewma.v1" +) + +var speedAddLimit = time.Second / 2 + +type speed struct { + ewma ewma.MovingAverage + lastStateId uint64 + prevValue, startValue int64 + prevTime, startTime time.Time +} + +func (s *speed) value(state *State) float64 { + if s.ewma == nil { + s.ewma = ewma.NewMovingAverage() + } + if state.IsFirst() || state.Id() < s.lastStateId { + s.reset(state) + return 0 + } + if state.Id() == s.lastStateId { + return s.ewma.Value() + } + if state.IsFinished() { + return s.absValue(state) + } + dur := state.Time().Sub(s.prevTime) + if dur < speedAddLimit { + return s.ewma.Value() + } + diff := math.Abs(float64(state.Value() - s.prevValue)) + lastSpeed := diff / dur.Seconds() + s.prevTime = state.Time() + s.prevValue = state.Value() + s.lastStateId = state.Id() + s.ewma.Add(lastSpeed) + return s.ewma.Value() +} + +func (s *speed) reset(state *State) { + s.lastStateId = state.Id() + s.startTime = state.Time() + s.prevTime = state.Time() + s.startValue = state.Value() + s.prevValue = state.Value() + s.ewma = ewma.NewMovingAverage() +} + +func (s *speed) absValue(state *State) float64 { + if dur := state.Time().Sub(s.startTime); dur > 0 { + return float64(state.Value()) / dur.Seconds() + } + return 0 +} + +func getSpeedObj(state *State) (s *speed) { + if sObj, ok := state.Get(speedObj).(*speed); ok { + return sObj + } + s = new(speed) + state.Set(speedObj, s) + return +} + +// ElementSpeed calculates current speed by EWMA +// Optionally can take one or two string arguments. +// First string will be used as value for format speed, default is "%s p/s". +// Second string will be used when speed not available, default is "? p/s" +// In template use as follows: {{speed .}} or {{speed . "%s per second"}} or {{speed . "%s ps" "..."} +var ElementSpeed ElementFunc = func(state *State, args ...string) string { + sp := getSpeedObj(state).value(state) + if sp == 0 { + return argsHelper(args).getNotEmptyOr(1, "? p/s") + } + return fmt.Sprintf(argsHelper(args).getNotEmptyOr(0, "%s p/s"), state.Format(int64(round(sp)))) +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/template.go b/vendor/gopkg.in/cheggaaa/pb.v2/template.go new file mode 100644 index 000000000..98aeea44e --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/template.go @@ -0,0 +1,87 @@ +package pb + +import ( + "math/rand" + "sync" + "text/template" + + "gopkg.in/fatih/color.v1" +) + +// ProgressBarTemplate that template string +type ProgressBarTemplate string + +// New creates new bar from template +func (pbt ProgressBarTemplate) New(total int) *ProgressBar { + return New(total).SetTemplate(pbt) +} + +// Start64 create and start new bar with given int64 total value +func (pbt ProgressBarTemplate) Start64(total int64) *ProgressBar { + return New64(total).SetTemplate(pbt).Start() +} + +// Start create and start new bar with given int total value +func (pbt ProgressBarTemplate) Start(total int) *ProgressBar { + return pbt.Start64(int64(total)) +} + +var templateCacheMu sync.Mutex +var templateCache = make(map[string]*template.Template) + +var defaultTemplateFuncs = template.FuncMap{ + // colors + "black": color.New(color.FgBlack).SprintFunc(), + "red": color.New(color.FgRed).SprintFunc(), + "green": color.New(color.FgGreen).SprintFunc(), + "yellow": color.New(color.FgYellow).SprintFunc(), + "blue": color.New(color.FgBlue).SprintFunc(), + "magenta": color.New(color.FgMagenta).SprintFunc(), + "cyan": color.New(color.FgCyan).SprintFunc(), + "white": color.New(color.FgWhite).SprintFunc(), + "rndcolor": rndcolor, + "rnd": rnd, +} + +func getTemplate(tmpl string) (t *template.Template, err error) { + templateCacheMu.Lock() + defer templateCacheMu.Unlock() + t = templateCache[tmpl] + if t != nil { + // found in cache + return + } + t = template.New("") + fillTemplateFuncs(t) + _, err = t.Parse(tmpl) + if err != nil { + t = nil + return + } + templateCache[tmpl] = t + return +} + +func fillTemplateFuncs(t *template.Template) { + t.Funcs(defaultTemplateFuncs) + emf := make(template.FuncMap) + elementsM.Lock() + for k, v := range elements { + emf[k] = v + } + elementsM.Unlock() + t.Funcs(emf) + return +} + +func rndcolor(s string) string { + c := rand.Intn(int(color.FgWhite-color.FgBlack)) + int(color.FgBlack) + return color.New(color.Attribute(c)).Sprint(s) +} + +func rnd(args ...string) string { + if len(args) == 0 { + return "" + } + return args[rand.Intn(len(args))] +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/template_test.go b/vendor/gopkg.in/cheggaaa/pb.v2/template_test.go new file mode 100644 index 000000000..84022d347 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/template_test.go @@ -0,0 +1,53 @@ +package pb + +import ( + "bytes" + "testing" +) + +func TestProgressBarTemplate(t *testing.T) { + // test New + bar := ProgressBarTemplate(`{{counters . }}`).New(0) + result := bar.String() + expected := "0" + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) + } + if bar.IsStarted() { + t.Error("Must be false") + } + + // test Start + bar = ProgressBarTemplate(`{{counters . }}`).Start(42).SetWriter(bytes.NewBuffer(nil)) + result = bar.String() + expected = "0 / 42" + if result != expected { + t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) + } + if !bar.IsStarted() { + t.Error("Must be true") + } +} + +func TestTemplateFuncs(t *testing.T) { + var results = make(map[string]int) + for i := 0; i < 100; i++ { + r := rndcolor("s") + results[r] = results[r] + 1 + } + if len(results) < 6 { + t.Errorf("Unexpected rndcolor results count: %v", len(results)) + } + + results = make(map[string]int) + for i := 0; i < 100; i++ { + r := rnd("1", "2", "3") + results[r] = results[r] + 1 + } + if len(results) != 3 { + t.Errorf("Unexpected rnd results count: %v", len(results)) + } + if r := rnd(); r != "" { + t.Errorf("Unexpected rnd result: '%v'", r) + } +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term.go new file mode 100644 index 000000000..b53b4b24a --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term.go @@ -0,0 +1,57 @@ +package termutil + +import ( + "errors" + "os" + "os/signal" + "sync" + "syscall" +) + +var echoLocked bool +var echoLockMutex sync.Mutex +var errLocked = errors.New("terminal locked") + +// RawModeOn switches terminal to raw mode +func RawModeOn() (quit chan struct{}, err error) { + echoLockMutex.Lock() + defer echoLockMutex.Unlock() + if echoLocked { + err = errLocked + return + } + if err = lockEcho(); err != nil { + return + } + echoLocked = true + quit = make(chan struct{}, 1) + go catchTerminate(quit) + return +} + +// RawModeOff restore previous terminal state +func RawModeOff() (err error) { + echoLockMutex.Lock() + defer echoLockMutex.Unlock() + if !echoLocked { + return + } + if err = unlockEcho(); err != nil { + return + } + echoLocked = false + return +} + +// listen exit signals and restore terminal state +func catchTerminate(quit chan struct{}) { + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL) + defer signal.Stop(sig) + select { + case <-quit: + RawModeOff() + case <-sig: + RawModeOff() + } +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_appengine.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_appengine.go new file mode 100644 index 000000000..4b7b20e6b --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_appengine.go @@ -0,0 +1,11 @@ +// +build appengine + +package termutil + +import "errors" + +// terminalWidth returns width of the terminal, which is not supported +// and should always failed on appengine classic which is a sandboxed PaaS. +func TerminalWidth() (int, error) { + return 0, errors.New("Not supported") +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_bsd.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_bsd.go new file mode 100644 index 000000000..272659a12 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_bsd.go @@ -0,0 +1,9 @@ +// +build darwin freebsd netbsd openbsd dragonfly +// +build !appengine + +package termutil + +import "syscall" + +const ioctlReadTermios = syscall.TIOCGETA +const ioctlWriteTermios = syscall.TIOCSETA diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_linux.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_linux.go new file mode 100644 index 000000000..2f59e53e1 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_linux.go @@ -0,0 +1,7 @@ +// +build linux +// +build !appengine + +package termutil + +const ioctlReadTermios = 0x5401 // syscall.TCGETS +const ioctlWriteTermios = 0x5402 // syscall.TCSETS diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_nix.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_nix.go new file mode 100644 index 000000000..14277e71f --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_nix.go @@ -0,0 +1,8 @@ +// +build linux darwin freebsd netbsd openbsd dragonfly +// +build !appengine + +package termutil + +import "syscall" + +const sysIoctl = syscall.SYS_IOCTL diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_solaris.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_solaris.go new file mode 100644 index 000000000..fc96c2b7f --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_solaris.go @@ -0,0 +1,8 @@ +// +build solaris +// +build !appengine + +package termutil + +const ioctlReadTermios = 0x5401 // syscall.TCGETS +const ioctlWriteTermios = 0x5402 // syscall.TCSETS +const sysIoctl = 54 diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_win.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_win.go new file mode 100644 index 000000000..963158360 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_win.go @@ -0,0 +1,149 @@ +// +build windows + +package termutil + +import ( + "fmt" + "os" + "os/exec" + "strconv" + "syscall" + "unsafe" +) + +var tty = os.Stdin + +var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") + + // GetConsoleScreenBufferInfo retrieves information about the + // specified console screen buffer. + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx + procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") + + // GetConsoleMode retrieves the current input mode of a console's + // input buffer or the current output mode of a console screen buffer. + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx + getConsoleMode = kernel32.NewProc("GetConsoleMode") + + // SetConsoleMode sets the input mode of a console's input buffer + // or the output mode of a console screen buffer. + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx + setConsoleMode = kernel32.NewProc("SetConsoleMode") + + // SetConsoleCursorPosition sets the cursor position in the + // specified console screen buffer. + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx + setConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") + + mingw = isMingw() +) + +type ( + // Defines the coordinates of the upper left and lower right corners + // of a rectangle. + // See + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311(v=vs.85).aspx + smallRect struct { + Left, Top, Right, Bottom int16 + } + + // Defines the coordinates of a character cell in a console screen + // buffer. The origin of the coordinate system (0,0) is at the top, left cell + // of the buffer. + // See + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119(v=vs.85).aspx + coordinates struct { + X, Y int16 + } + + word int16 + + // Contains information about a console screen buffer. + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx + consoleScreenBufferInfo struct { + dwSize coordinates + dwCursorPosition coordinates + wAttributes word + srWindow smallRect + dwMaximumWindowSize coordinates + } +) + +// TerminalWidth returns width of the terminal. +func TerminalWidth() (width int, err error) { + if mingw { + return termWidthTPut() + } + return termWidthCmd() +} + +func termWidthCmd() (width int, err error) { + var info consoleScreenBufferInfo + _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0) + if e != 0 { + return 0, error(e) + } + return int(info.dwSize.X) - 1, nil +} + +func isMingw() bool { + return os.Getenv("MINGW_PREFIX") != "" || os.Getenv("MSYSTEM") == "MINGW64" +} + +func termWidthTPut() (width int, err error) { + // TODO: maybe anybody knows a better way to get it on mintty... + var res []byte + cmd := exec.Command("tput", "cols") + cmd.Stdin = os.Stdin + if res, err = cmd.CombinedOutput(); err != nil { + return 0, fmt.Errorf("%s: %v", string(res), err) + } + if len(res) > 1 { + res = res[:len(res)-1] + } + return strconv.Atoi(string(res)) +} + +func getCursorPos() (pos coordinates, err error) { + var info consoleScreenBufferInfo + _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0) + if e != 0 { + return info.dwCursorPosition, error(e) + } + return info.dwCursorPosition, nil +} + +func setCursorPos(pos coordinates) error { + _, _, e := syscall.Syscall(setConsoleCursorPosition.Addr(), 2, uintptr(syscall.Stdout), uintptr(uint32(uint16(pos.Y))<<16|uint32(uint16(pos.X))), 0) + if e != 0 { + return error(e) + } + return nil +} + +var oldState word + +func lockEcho() (err error) { + if _, _, e := syscall.Syscall(getConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&oldState)), 0); e != 0 { + err = fmt.Errorf("Can't get terminal settings: %v", e) + return + } + + newState := oldState + const ENABLE_ECHO_INPUT = 0x0004 + const ENABLE_LINE_INPUT = 0x0002 + newState = newState & (^(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)) + if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(newState), 0); e != 0 { + err = fmt.Errorf("Can't set terminal settings: %v", e) + return + } + return +} + +func unlockEcho() (err error) { + if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(oldState), 0); e != 0 { + err = fmt.Errorf("Can't set terminal settings") + } + return +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_x.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_x.go new file mode 100644 index 000000000..e2f69b214 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_x.go @@ -0,0 +1,70 @@ +// +build linux darwin freebsd netbsd openbsd solaris dragonfly +// +build !appengine + +package termutil + +import ( + "fmt" + "os" + "syscall" + "unsafe" +) + +var tty *os.File + +type window struct { + Row uint16 + Col uint16 + Xpixel uint16 + Ypixel uint16 +} + +func init() { + var err error + tty, err = os.Open("/dev/tty") + if err != nil { + tty = os.Stdin + } +} + +// TerminalWidth returns width of the terminal. +func TerminalWidth() (int, error) { + w := new(window) + res, _, err := syscall.Syscall(sysIoctl, + tty.Fd(), + uintptr(syscall.TIOCGWINSZ), + uintptr(unsafe.Pointer(w)), + ) + if int(res) == -1 { + return 0, err + } + return int(w.Col), nil +} + +var oldState syscall.Termios + +func lockEcho() (err error) { + fd := tty.Fd() + if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { + err = fmt.Errorf("Can't get terminal settings: %v", e) + return + } + + newState := oldState + newState.Lflag &^= syscall.ECHO + newState.Lflag |= syscall.ICANON | syscall.ISIG + newState.Iflag |= syscall.ICRNL + if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); e != 0 { + err = fmt.Errorf("Can't set terminal settings: %v", e) + return + } + return +} + +func unlockEcho() (err error) { + fd := tty.Fd() + if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { + err = fmt.Errorf("Can't set terminal settings") + } + return +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/util.go b/vendor/gopkg.in/cheggaaa/pb.v2/util.go new file mode 100644 index 000000000..44eedae56 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/util.go @@ -0,0 +1,94 @@ +package pb + +import ( + "bytes" + "fmt" + "gopkg.in/mattn/go-runewidth.v0" + "math" + "regexp" + //"unicode/utf8" +) + +const ( + _KiB = 1024 + _MiB = 1048576 + _GiB = 1073741824 + _TiB = 1099511627776 +) + +var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9]+\x6d") + +func CellCount(s string) int { + n := runewidth.StringWidth(s) + for _, sm := range ctrlFinder.FindAllString(s, -1) { + n -= runewidth.StringWidth(sm) + } + return n +} + +func StripString(s string, w int) string { + l := CellCount(s) + if l <= w { + return s + } + var buf = bytes.NewBuffer(make([]byte, 0, len(s))) + StripStringToBuffer(s, w, buf) + return buf.String() +} + +func StripStringToBuffer(s string, w int, buf *bytes.Buffer) { + var seqs = ctrlFinder.FindAllStringIndex(s, -1) +mainloop: + for i, r := range s { + for _, seq := range seqs { + if i >= seq[0] && i < seq[1] { + buf.WriteRune(r) + continue mainloop + } + } + if rw := CellCount(string(r)); rw <= w { + w -= rw + buf.WriteRune(r) + } else { + break + } + } + for w > 0 { + buf.WriteByte(' ') + w-- + } + return +} + +func round(val float64) (newVal float64) { + roundOn := 0.5 + places := 0 + var round float64 + pow := math.Pow(10, float64(places)) + digit := pow * val + _, div := math.Modf(digit) + if div >= roundOn { + round = math.Ceil(digit) + } else { + round = math.Floor(digit) + } + newVal = round / pow + return +} + +// Convert bytes to human readable string. Like a 2 MiB, 64.2 KiB, 52 B +func formatBytes(i int64) (result string) { + switch { + case i >= _TiB: + result = fmt.Sprintf("%.02f TiB", float64(i)/_TiB) + case i >= _GiB: + result = fmt.Sprintf("%.02f GiB", float64(i)/_GiB) + case i >= _MiB: + result = fmt.Sprintf("%.02f MiB", float64(i)/_MiB) + case i >= _KiB: + result = fmt.Sprintf("%.02f KiB", float64(i)/_KiB) + default: + result = fmt.Sprintf("%d B", i) + } + return +} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/util_test.go b/vendor/gopkg.in/cheggaaa/pb.v2/util_test.go new file mode 100644 index 000000000..1c7fe7850 --- /dev/null +++ b/vendor/gopkg.in/cheggaaa/pb.v2/util_test.go @@ -0,0 +1,73 @@ +package pb + +import ( + "gopkg.in/fatih/color.v1" + "testing" +) + +var testColorString = color.RedString("red") + + color.GreenString("hello") + + "simple" + + color.WhiteString("進捗") + +func TestUtilCellCount(t *testing.T) { + if e, l := 18, CellCount(testColorString); l != e { + t.Errorf("Invalid length %d, expected %d", l, e) + } +} + +func TestUtilStripString(t *testing.T) { + if r, e := StripString("12345", 4), "1234"; r != e { + t.Errorf("Invalid result '%s', expected '%s'", r, e) + } + + if r, e := StripString("12345", 5), "12345"; r != e { + t.Errorf("Invalid result '%s', expected '%s'", r, e) + } + if r, e := StripString("12345", 10), "12345"; r != e { + t.Errorf("Invalid result '%s', expected '%s'", r, e) + } + + s := color.RedString("1") + "23" + e := color.RedString("1") + "2" + if r := StripString(s, 2); r != e { + t.Errorf("Invalid result '%s', expected '%s'", r, e) + } + return +} + +func TestUtilRound(t *testing.T) { + if v := round(4.4); v != 4 { + t.Errorf("Unexpected result: %v", v) + } + if v := round(4.501); v != 5 { + t.Errorf("Unexpected result: %v", v) + } +} + +func TestUtilFormatBytes(t *testing.T) { + inputs := []struct { + v int64 + e string + }{ + {v: 1000, e: "1000 B"}, + {v: 1024, e: "1.00 KiB"}, + {v: 3*_MiB + 140*_KiB, e: "3.14 MiB"}, + {v: 2 * _GiB, e: "2.00 GiB"}, + {v: 2048 * _GiB, e: "2.00 TiB"}, + } + + for _, input := range inputs { + actual := formatBytes(input.v) + if actual != input.e { + t.Errorf("Expected {%s} was {%s}", input.e, actual) + } + } +} + +func BenchmarkUtilsCellCount(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + CellCount(testColorString) + } +} diff --git a/vendor/gopkg.in/fatih/color.v1/.travis.yml b/vendor/gopkg.in/fatih/color.v1/.travis.yml new file mode 100644 index 000000000..57b4b57c8 --- /dev/null +++ b/vendor/gopkg.in/fatih/color.v1/.travis.yml @@ -0,0 +1,5 @@ +language: go +go: + - 1.6 + - tip + diff --git a/vendor/gopkg.in/fatih/color.v1/LICENSE.md b/vendor/gopkg.in/fatih/color.v1/LICENSE.md new file mode 100644 index 000000000..25fdaf639 --- /dev/null +++ b/vendor/gopkg.in/fatih/color.v1/LICENSE.md @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Fatih Arslan + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/gopkg.in/fatih/color.v1/README.md b/vendor/gopkg.in/fatih/color.v1/README.md new file mode 100644 index 000000000..623baf3c3 --- /dev/null +++ b/vendor/gopkg.in/fatih/color.v1/README.md @@ -0,0 +1,177 @@ +# Color [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/fatih/color) [![Build Status](http://img.shields.io/travis/fatih/color.svg?style=flat-square)](https://travis-ci.org/fatih/color) + + + +Color lets you use colorized outputs in terms of [ANSI Escape +Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It +has support for Windows too! The API can be used in several ways, pick one that +suits you. + + +![Color](http://i.imgur.com/c1JI0lA.png) + + +## Install + +```bash +go get github.com/fatih/color +``` + +Note that the `vendor` folder is here for stability. Remove the folder if you +already have the dependencies in your GOPATH. + +## Examples + +### Standard colors + +```go +// Print with default helper functions +color.Cyan("Prints text in cyan.") + +// A newline will be appended automatically +color.Blue("Prints %s in blue.", "text") + +// These are using the default foreground colors +color.Red("We have red") +color.Magenta("And many others ..") + +``` + +### Mix and reuse colors + +```go +// Create a new color object +c := color.New(color.FgCyan).Add(color.Underline) +c.Println("Prints cyan text with an underline.") + +// Or just add them to New() +d := color.New(color.FgCyan, color.Bold) +d.Printf("This prints bold cyan %s\n", "too!.") + +// Mix up foreground and background colors, create new mixes! +red := color.New(color.FgRed) + +boldRed := red.Add(color.Bold) +boldRed.Println("This will print text in bold red.") + +whiteBackground := red.Add(color.BgWhite) +whiteBackground.Println("Red text with white background.") +``` + +### Use your own output (io.Writer) + +```go +// Use your own io.Writer output +color.New(color.FgBlue).Fprintln(myWriter, "blue color!") + +blue := color.New(color.FgBlue) +blue.Fprint(writer, "This will print text in blue.") +``` + +### Custom print functions (PrintFunc) + +```go +// Create a custom print function for convenience +red := color.New(color.FgRed).PrintfFunc() +red("Warning") +red("Error: %s", err) + +// Mix up multiple attributes +notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() +notice("Don't forget this...") +``` + +### Custom fprint functions (FprintFunc) + +```go +blue := color.New(FgBlue).FprintfFunc() +blue(myWriter, "important notice: %s", stars) + +// Mix up with multiple attributes +success := color.New(color.Bold, color.FgGreen).FprintlnFunc() +success(myWriter, "Don't forget this...") +``` + +### Insert into noncolor strings (SprintFunc) + +```go +// Create SprintXxx functions to mix strings with other non-colorized strings: +yellow := color.New(color.FgYellow).SprintFunc() +red := color.New(color.FgRed).SprintFunc() +fmt.Printf("This is a %s and this is %s.\n", yellow("warning"), red("error")) + +info := color.New(color.FgWhite, color.BgGreen).SprintFunc() +fmt.Printf("This %s rocks!\n", info("package")) + +// Use helper functions +fmt.Println("This", color.RedString("warning"), "should be not neglected.") +fmt.Printf("%v %v\n", color.GreenString("Info:"), "an important message.") + +// Windows supported too! Just don't forget to change the output to color.Output +fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) +``` + +### Plug into existing code + +```go +// Use handy standard colors +color.Set(color.FgYellow) + +fmt.Println("Existing text will now be in yellow") +fmt.Printf("This one %s\n", "too") + +color.Unset() // Don't forget to unset + +// You can mix up parameters +color.Set(color.FgMagenta, color.Bold) +defer color.Unset() // Use it in your function + +fmt.Println("All text will now be bold magenta.") +``` + +### Disable color + +There might be a case where you want to disable color output (for example to +pipe the standard output of your app to somewhere else). `Color` has support to +disable colors both globally and for single color definition. For example +suppose you have a CLI app and a `--no-color` bool flag. You can easily disable +the color output with: + +```go + +var flagNoColor = flag.Bool("no-color", false, "Disable color output") + +if *flagNoColor { + color.NoColor = true // disables colorized output +} +``` + +It also has support for single color definitions (local). You can +disable/enable color output on the fly: + +```go +c := color.New(color.FgCyan) +c.Println("Prints cyan text") + +c.DisableColor() +c.Println("This is printed without any color") + +c.EnableColor() +c.Println("This prints again cyan...") +``` + +## Todo + +* Save/Return previous values +* Evaluate fmt.Formatter interface + + +## Credits + + * [Fatih Arslan](https://github.com/fatih) + * Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable) + +## License + +The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details + diff --git a/vendor/gopkg.in/fatih/color.v1/color.go b/vendor/gopkg.in/fatih/color.v1/color.go new file mode 100644 index 000000000..7b5f3146d --- /dev/null +++ b/vendor/gopkg.in/fatih/color.v1/color.go @@ -0,0 +1,600 @@ +package color + +import ( + "fmt" + "io" + "os" + "strconv" + "strings" + "sync" + + "github.com/mattn/go-colorable" + "github.com/mattn/go-isatty" +) + +var ( + // NoColor defines if the output is colorized or not. It's dynamically set to + // false or true based on the stdout's file descriptor referring to a terminal + // or not. This is a global option and affects all colors. For more control + // over each color block use the methods DisableColor() individually. + NoColor = os.Getenv("TERM") == "dumb" || + (!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd())) + + // Output defines the standard output of the print functions. By default + // os.Stdout is used. + Output = colorable.NewColorableStdout() + + // colorsCache is used to reduce the count of created Color objects and + // allows to reuse already created objects with required Attribute. + colorsCache = make(map[Attribute]*Color) + colorsCacheMu sync.Mutex // protects colorsCache +) + +// Color defines a custom color object which is defined by SGR parameters. +type Color struct { + params []Attribute + noColor *bool +} + +// Attribute defines a single SGR Code +type Attribute int + +const escape = "\x1b" + +// Base attributes +const ( + Reset Attribute = iota + Bold + Faint + Italic + Underline + BlinkSlow + BlinkRapid + ReverseVideo + Concealed + CrossedOut +) + +// Foreground text colors +const ( + FgBlack Attribute = iota + 30 + FgRed + FgGreen + FgYellow + FgBlue + FgMagenta + FgCyan + FgWhite +) + +// Foreground Hi-Intensity text colors +const ( + FgHiBlack Attribute = iota + 90 + FgHiRed + FgHiGreen + FgHiYellow + FgHiBlue + FgHiMagenta + FgHiCyan + FgHiWhite +) + +// Background text colors +const ( + BgBlack Attribute = iota + 40 + BgRed + BgGreen + BgYellow + BgBlue + BgMagenta + BgCyan + BgWhite +) + +// Background Hi-Intensity text colors +const ( + BgHiBlack Attribute = iota + 100 + BgHiRed + BgHiGreen + BgHiYellow + BgHiBlue + BgHiMagenta + BgHiCyan + BgHiWhite +) + +// New returns a newly created color object. +func New(value ...Attribute) *Color { + c := &Color{params: make([]Attribute, 0)} + c.Add(value...) + return c +} + +// Set sets the given parameters immediately. It will change the color of +// output with the given SGR parameters until color.Unset() is called. +func Set(p ...Attribute) *Color { + c := New(p...) + c.Set() + return c +} + +// Unset resets all escape attributes and clears the output. Usually should +// be called after Set(). +func Unset() { + if NoColor { + return + } + + fmt.Fprintf(Output, "%s[%dm", escape, Reset) +} + +// Set sets the SGR sequence. +func (c *Color) Set() *Color { + if c.isNoColorSet() { + return c + } + + fmt.Fprintf(Output, c.format()) + return c +} + +func (c *Color) unset() { + if c.isNoColorSet() { + return + } + + Unset() +} + +func (c *Color) setWriter(w io.Writer) *Color { + if c.isNoColorSet() { + return c + } + + fmt.Fprintf(w, c.format()) + return c +} + +func (c *Color) unsetWriter(w io.Writer) { + if c.isNoColorSet() { + return + } + + if NoColor { + return + } + + fmt.Fprintf(w, "%s[%dm", escape, Reset) +} + +// Add is used to chain SGR parameters. Use as many as parameters to combine +// and create custom color objects. Example: Add(color.FgRed, color.Underline). +func (c *Color) Add(value ...Attribute) *Color { + c.params = append(c.params, value...) + return c +} + +func (c *Color) prepend(value Attribute) { + c.params = append(c.params, 0) + copy(c.params[1:], c.params[0:]) + c.params[0] = value +} + +// Fprint formats using the default formats for its operands and writes to w. +// Spaces are added between operands when neither is a string. +// It returns the number of bytes written and any write error encountered. +// On Windows, users should wrap w with colorable.NewColorable() if w is of +// type *os.File. +func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) { + c.setWriter(w) + defer c.unsetWriter(w) + + return fmt.Fprint(w, a...) +} + +// Print formats using the default formats for its operands and writes to +// standard output. Spaces are added between operands when neither is a +// string. It returns the number of bytes written and any write error +// encountered. This is the standard fmt.Print() method wrapped with the given +// color. +func (c *Color) Print(a ...interface{}) (n int, err error) { + c.Set() + defer c.unset() + + return fmt.Fprint(Output, a...) +} + +// Fprintf formats according to a format specifier and writes to w. +// It returns the number of bytes written and any write error encountered. +// On Windows, users should wrap w with colorable.NewColorable() if w is of +// type *os.File. +func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { + c.setWriter(w) + defer c.unsetWriter(w) + + return fmt.Fprintf(w, format, a...) +} + +// Printf formats according to a format specifier and writes to standard output. +// It returns the number of bytes written and any write error encountered. +// This is the standard fmt.Printf() method wrapped with the given color. +func (c *Color) Printf(format string, a ...interface{}) (n int, err error) { + c.Set() + defer c.unset() + + return fmt.Fprintf(Output, format, a...) +} + +// Fprintln formats using the default formats for its operands and writes to w. +// Spaces are always added between operands and a newline is appended. +// On Windows, users should wrap w with colorable.NewColorable() if w is of +// type *os.File. +func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + c.setWriter(w) + defer c.unsetWriter(w) + + return fmt.Fprintln(w, a...) +} + +// Println formats using the default formats for its operands and writes to +// standard output. Spaces are always added between operands and a newline is +// appended. It returns the number of bytes written and any write error +// encountered. This is the standard fmt.Print() method wrapped with the given +// color. +func (c *Color) Println(a ...interface{}) (n int, err error) { + c.Set() + defer c.unset() + + return fmt.Fprintln(Output, a...) +} + +// Sprint is just like Print, but returns a string instead of printing it. +func (c *Color) Sprint(a ...interface{}) string { + return c.wrap(fmt.Sprint(a...)) +} + +// Sprintln is just like Println, but returns a string instead of printing it. +func (c *Color) Sprintln(a ...interface{}) string { + return c.wrap(fmt.Sprintln(a...)) +} + +// Sprintf is just like Printf, but returns a string instead of printing it. +func (c *Color) Sprintf(format string, a ...interface{}) string { + return c.wrap(fmt.Sprintf(format, a...)) +} + +// FprintFunc returns a new function that prints the passed arguments as +// colorized with color.Fprint(). +func (c *Color) FprintFunc() func(w io.Writer, a ...interface{}) { + return func(w io.Writer, a ...interface{}) { + c.Fprint(w, a...) + } +} + +// PrintFunc returns a new function that prints the passed arguments as +// colorized with color.Print(). +func (c *Color) PrintFunc() func(a ...interface{}) { + return func(a ...interface{}) { + c.Print(a...) + } +} + +// FprintfFunc returns a new function that prints the passed arguments as +// colorized with color.Fprintf(). +func (c *Color) FprintfFunc() func(w io.Writer, format string, a ...interface{}) { + return func(w io.Writer, format string, a ...interface{}) { + c.Fprintf(w, format, a...) + } +} + +// PrintfFunc returns a new function that prints the passed arguments as +// colorized with color.Printf(). +func (c *Color) PrintfFunc() func(format string, a ...interface{}) { + return func(format string, a ...interface{}) { + c.Printf(format, a...) + } +} + +// FprintlnFunc returns a new function that prints the passed arguments as +// colorized with color.Fprintln(). +func (c *Color) FprintlnFunc() func(w io.Writer, a ...interface{}) { + return func(w io.Writer, a ...interface{}) { + c.Fprintln(w, a...) + } +} + +// PrintlnFunc returns a new function that prints the passed arguments as +// colorized with color.Println(). +func (c *Color) PrintlnFunc() func(a ...interface{}) { + return func(a ...interface{}) { + c.Println(a...) + } +} + +// SprintFunc returns a new function that returns colorized strings for the +// given arguments with fmt.Sprint(). Useful to put into or mix into other +// string. Windows users should use this in conjunction with color.Output, example: +// +// put := New(FgYellow).SprintFunc() +// fmt.Fprintf(color.Output, "This is a %s", put("warning")) +func (c *Color) SprintFunc() func(a ...interface{}) string { + return func(a ...interface{}) string { + return c.wrap(fmt.Sprint(a...)) + } +} + +// SprintfFunc returns a new function that returns colorized strings for the +// given arguments with fmt.Sprintf(). Useful to put into or mix into other +// string. Windows users should use this in conjunction with color.Output. +func (c *Color) SprintfFunc() func(format string, a ...interface{}) string { + return func(format string, a ...interface{}) string { + return c.wrap(fmt.Sprintf(format, a...)) + } +} + +// SprintlnFunc returns a new function that returns colorized strings for the +// given arguments with fmt.Sprintln(). Useful to put into or mix into other +// string. Windows users should use this in conjunction with color.Output. +func (c *Color) SprintlnFunc() func(a ...interface{}) string { + return func(a ...interface{}) string { + return c.wrap(fmt.Sprintln(a...)) + } +} + +// sequence returns a formated SGR sequence to be plugged into a "\x1b[...m" +// an example output might be: "1;36" -> bold cyan +func (c *Color) sequence() string { + format := make([]string, len(c.params)) + for i, v := range c.params { + format[i] = strconv.Itoa(int(v)) + } + + return strings.Join(format, ";") +} + +// wrap wraps the s string with the colors attributes. The string is ready to +// be printed. +func (c *Color) wrap(s string) string { + if c.isNoColorSet() { + return s + } + + return c.format() + s + c.unformat() +} + +func (c *Color) format() string { + return fmt.Sprintf("%s[%sm", escape, c.sequence()) +} + +func (c *Color) unformat() string { + return fmt.Sprintf("%s[%dm", escape, Reset) +} + +// DisableColor disables the color output. Useful to not change any existing +// code and still being able to output. Can be used for flags like +// "--no-color". To enable back use EnableColor() method. +func (c *Color) DisableColor() { + c.noColor = boolPtr(true) +} + +// EnableColor enables the color output. Use it in conjunction with +// DisableColor(). Otherwise this method has no side effects. +func (c *Color) EnableColor() { + c.noColor = boolPtr(false) +} + +func (c *Color) isNoColorSet() bool { + // check first if we have user setted action + if c.noColor != nil { + return *c.noColor + } + + // if not return the global option, which is disabled by default + return NoColor +} + +// Equals returns a boolean value indicating whether two colors are equal. +func (c *Color) Equals(c2 *Color) bool { + if len(c.params) != len(c2.params) { + return false + } + + for _, attr := range c.params { + if !c2.attrExists(attr) { + return false + } + } + + return true +} + +func (c *Color) attrExists(a Attribute) bool { + for _, attr := range c.params { + if attr == a { + return true + } + } + + return false +} + +func boolPtr(v bool) *bool { + return &v +} + +func getCachedColor(p Attribute) *Color { + colorsCacheMu.Lock() + defer colorsCacheMu.Unlock() + + c, ok := colorsCache[p] + if !ok { + c = New(p) + colorsCache[p] = c + } + + return c +} + +func colorPrint(format string, p Attribute, a ...interface{}) { + c := getCachedColor(p) + + if !strings.HasSuffix(format, "\n") { + format += "\n" + } + + if len(a) == 0 { + c.Print(format) + } else { + c.Printf(format, a...) + } +} + +func colorString(format string, p Attribute, a ...interface{}) string { + c := getCachedColor(p) + + if len(a) == 0 { + return c.SprintFunc()(format) + } + + return c.SprintfFunc()(format, a...) +} + +// Black is a convenient helper function to print with black foreground. A +// newline is appended to format by default. +func Black(format string, a ...interface{}) { colorPrint(format, FgBlack, a...) } + +// Red is a convenient helper function to print with red foreground. A +// newline is appended to format by default. +func Red(format string, a ...interface{}) { colorPrint(format, FgRed, a...) } + +// Green is a convenient helper function to print with green foreground. A +// newline is appended to format by default. +func Green(format string, a ...interface{}) { colorPrint(format, FgGreen, a...) } + +// Yellow is a convenient helper function to print with yellow foreground. +// A newline is appended to format by default. +func Yellow(format string, a ...interface{}) { colorPrint(format, FgYellow, a...) } + +// Blue is a convenient helper function to print with blue foreground. A +// newline is appended to format by default. +func Blue(format string, a ...interface{}) { colorPrint(format, FgBlue, a...) } + +// Magenta is a convenient helper function to print with magenta foreground. +// A newline is appended to format by default. +func Magenta(format string, a ...interface{}) { colorPrint(format, FgMagenta, a...) } + +// Cyan is a convenient helper function to print with cyan foreground. A +// newline is appended to format by default. +func Cyan(format string, a ...interface{}) { colorPrint(format, FgCyan, a...) } + +// White is a convenient helper function to print with white foreground. A +// newline is appended to format by default. +func White(format string, a ...interface{}) { colorPrint(format, FgWhite, a...) } + +// BlackString is a convenient helper function to return a string with black +// foreground. +func BlackString(format string, a ...interface{}) string { return colorString(format, FgBlack, a...) } + +// RedString is a convenient helper function to return a string with red +// foreground. +func RedString(format string, a ...interface{}) string { return colorString(format, FgRed, a...) } + +// GreenString is a convenient helper function to return a string with green +// foreground. +func GreenString(format string, a ...interface{}) string { return colorString(format, FgGreen, a...) } + +// YellowString is a convenient helper function to return a string with yellow +// foreground. +func YellowString(format string, a ...interface{}) string { return colorString(format, FgYellow, a...) } + +// BlueString is a convenient helper function to return a string with blue +// foreground. +func BlueString(format string, a ...interface{}) string { return colorString(format, FgBlue, a...) } + +// MagentaString is a convenient helper function to return a string with magenta +// foreground. +func MagentaString(format string, a ...interface{}) string { + return colorString(format, FgMagenta, a...) +} + +// CyanString is a convenient helper function to return a string with cyan +// foreground. +func CyanString(format string, a ...interface{}) string { return colorString(format, FgCyan, a...) } + +// WhiteString is a convenient helper function to return a string with white +// foreground. +func WhiteString(format string, a ...interface{}) string { return colorString(format, FgWhite, a...) } + +// HiBlack is a convenient helper function to print with hi-intensity black foreground. A +// newline is appended to format by default. +func HiBlack(format string, a ...interface{}) { colorPrint(format, FgHiBlack, a...) } + +// HiRed is a convenient helper function to print with hi-intensity red foreground. A +// newline is appended to format by default. +func HiRed(format string, a ...interface{}) { colorPrint(format, FgHiRed, a...) } + +// HiGreen is a convenient helper function to print with hi-intensity green foreground. A +// newline is appended to format by default. +func HiGreen(format string, a ...interface{}) { colorPrint(format, FgHiGreen, a...) } + +// HiYellow is a convenient helper function to print with hi-intensity yellow foreground. +// A newline is appended to format by default. +func HiYellow(format string, a ...interface{}) { colorPrint(format, FgHiYellow, a...) } + +// HiBlue is a convenient helper function to print with hi-intensity blue foreground. A +// newline is appended to format by default. +func HiBlue(format string, a ...interface{}) { colorPrint(format, FgHiBlue, a...) } + +// HiMagenta is a convenient helper function to print with hi-intensity magenta foreground. +// A newline is appended to format by default. +func HiMagenta(format string, a ...interface{}) { colorPrint(format, FgHiMagenta, a...) } + +// HiCyan is a convenient helper function to print with hi-intensity cyan foreground. A +// newline is appended to format by default. +func HiCyan(format string, a ...interface{}) { colorPrint(format, FgHiCyan, a...) } + +// HiWhite is a convenient helper function to print with hi-intensity white foreground. A +// newline is appended to format by default. +func HiWhite(format string, a ...interface{}) { colorPrint(format, FgHiWhite, a...) } + +// HiBlackString is a convenient helper function to return a string with hi-intensity black +// foreground. +func HiBlackString(format string, a ...interface{}) string { + return colorString(format, FgHiBlack, a...) +} + +// HiRedString is a convenient helper function to return a string with hi-intensity red +// foreground. +func HiRedString(format string, a ...interface{}) string { return colorString(format, FgHiRed, a...) } + +// HiGreenString is a convenient helper function to return a string with hi-intensity green +// foreground. +func HiGreenString(format string, a ...interface{}) string { + return colorString(format, FgHiGreen, a...) +} + +// HiYellowString is a convenient helper function to return a string with hi-intensity yellow +// foreground. +func HiYellowString(format string, a ...interface{}) string { + return colorString(format, FgHiYellow, a...) +} + +// HiBlueString is a convenient helper function to return a string with hi-intensity blue +// foreground. +func HiBlueString(format string, a ...interface{}) string { return colorString(format, FgHiBlue, a...) } + +// HiMagentaString is a convenient helper function to return a string with hi-intensity magenta +// foreground. +func HiMagentaString(format string, a ...interface{}) string { + return colorString(format, FgHiMagenta, a...) +} + +// HiCyanString is a convenient helper function to return a string with hi-intensity cyan +// foreground. +func HiCyanString(format string, a ...interface{}) string { return colorString(format, FgHiCyan, a...) } + +// HiWhiteString is a convenient helper function to return a string with hi-intensity white +// foreground. +func HiWhiteString(format string, a ...interface{}) string { + return colorString(format, FgHiWhite, a...) +} diff --git a/vendor/gopkg.in/fatih/color.v1/color_test.go b/vendor/gopkg.in/fatih/color.v1/color_test.go new file mode 100644 index 000000000..a8ed14fba --- /dev/null +++ b/vendor/gopkg.in/fatih/color.v1/color_test.go @@ -0,0 +1,342 @@ +package color + +import ( + "bytes" + "fmt" + "os" + "testing" + + "github.com/mattn/go-colorable" +) + +// Testing colors is kinda different. First we test for given colors and their +// escaped formatted results. Next we create some visual tests to be tested. +// Each visual test includes the color name to be compared. +func TestColor(t *testing.T) { + rb := new(bytes.Buffer) + Output = rb + + NoColor = false + + testColors := []struct { + text string + code Attribute + }{ + {text: "black", code: FgBlack}, + {text: "red", code: FgRed}, + {text: "green", code: FgGreen}, + {text: "yellow", code: FgYellow}, + {text: "blue", code: FgBlue}, + {text: "magent", code: FgMagenta}, + {text: "cyan", code: FgCyan}, + {text: "white", code: FgWhite}, + {text: "hblack", code: FgHiBlack}, + {text: "hred", code: FgHiRed}, + {text: "hgreen", code: FgHiGreen}, + {text: "hyellow", code: FgHiYellow}, + {text: "hblue", code: FgHiBlue}, + {text: "hmagent", code: FgHiMagenta}, + {text: "hcyan", code: FgHiCyan}, + {text: "hwhite", code: FgHiWhite}, + } + + for _, c := range testColors { + New(c.code).Print(c.text) + + line, _ := rb.ReadString('\n') + scannedLine := fmt.Sprintf("%q", line) + colored := fmt.Sprintf("\x1b[%dm%s\x1b[0m", c.code, c.text) + escapedForm := fmt.Sprintf("%q", colored) + + fmt.Printf("%s\t: %s\n", c.text, line) + + if scannedLine != escapedForm { + t.Errorf("Expecting %s, got '%s'\n", escapedForm, scannedLine) + } + } + + for _, c := range testColors { + line := New(c.code).Sprintf("%s", c.text) + scannedLine := fmt.Sprintf("%q", line) + colored := fmt.Sprintf("\x1b[%dm%s\x1b[0m", c.code, c.text) + escapedForm := fmt.Sprintf("%q", colored) + + fmt.Printf("%s\t: %s\n", c.text, line) + + if scannedLine != escapedForm { + t.Errorf("Expecting %s, got '%s'\n", escapedForm, scannedLine) + } + } +} + +func TestColorEquals(t *testing.T) { + fgblack1 := New(FgBlack) + fgblack2 := New(FgBlack) + bgblack := New(BgBlack) + fgbgblack := New(FgBlack, BgBlack) + fgblackbgred := New(FgBlack, BgRed) + fgred := New(FgRed) + bgred := New(BgRed) + + if !fgblack1.Equals(fgblack2) { + t.Error("Two black colors are not equal") + } + + if fgblack1.Equals(bgblack) { + t.Error("Fg and bg black colors are equal") + } + + if fgblack1.Equals(fgbgblack) { + t.Error("Fg black equals fg/bg black color") + } + + if fgblack1.Equals(fgred) { + t.Error("Fg black equals Fg red") + } + + if fgblack1.Equals(bgred) { + t.Error("Fg black equals Bg red") + } + + if fgblack1.Equals(fgblackbgred) { + t.Error("Fg black equals fg black bg red") + } +} + +func TestNoColor(t *testing.T) { + rb := new(bytes.Buffer) + Output = rb + + testColors := []struct { + text string + code Attribute + }{ + {text: "black", code: FgBlack}, + {text: "red", code: FgRed}, + {text: "green", code: FgGreen}, + {text: "yellow", code: FgYellow}, + {text: "blue", code: FgBlue}, + {text: "magent", code: FgMagenta}, + {text: "cyan", code: FgCyan}, + {text: "white", code: FgWhite}, + {text: "hblack", code: FgHiBlack}, + {text: "hred", code: FgHiRed}, + {text: "hgreen", code: FgHiGreen}, + {text: "hyellow", code: FgHiYellow}, + {text: "hblue", code: FgHiBlue}, + {text: "hmagent", code: FgHiMagenta}, + {text: "hcyan", code: FgHiCyan}, + {text: "hwhite", code: FgHiWhite}, + } + + for _, c := range testColors { + p := New(c.code) + p.DisableColor() + p.Print(c.text) + + line, _ := rb.ReadString('\n') + if line != c.text { + t.Errorf("Expecting %s, got '%s'\n", c.text, line) + } + } + + // global check + NoColor = true + defer func() { + NoColor = false + }() + for _, c := range testColors { + p := New(c.code) + p.Print(c.text) + + line, _ := rb.ReadString('\n') + if line != c.text { + t.Errorf("Expecting %s, got '%s'\n", c.text, line) + } + } + +} + +func TestColorVisual(t *testing.T) { + // First Visual Test + Output = colorable.NewColorableStdout() + + New(FgRed).Printf("red\t") + New(BgRed).Print(" ") + New(FgRed, Bold).Println(" red") + + New(FgGreen).Printf("green\t") + New(BgGreen).Print(" ") + New(FgGreen, Bold).Println(" green") + + New(FgYellow).Printf("yellow\t") + New(BgYellow).Print(" ") + New(FgYellow, Bold).Println(" yellow") + + New(FgBlue).Printf("blue\t") + New(BgBlue).Print(" ") + New(FgBlue, Bold).Println(" blue") + + New(FgMagenta).Printf("magenta\t") + New(BgMagenta).Print(" ") + New(FgMagenta, Bold).Println(" magenta") + + New(FgCyan).Printf("cyan\t") + New(BgCyan).Print(" ") + New(FgCyan, Bold).Println(" cyan") + + New(FgWhite).Printf("white\t") + New(BgWhite).Print(" ") + New(FgWhite, Bold).Println(" white") + fmt.Println("") + + // Second Visual test + Black("black") + Red("red") + Green("green") + Yellow("yellow") + Blue("blue") + Magenta("magenta") + Cyan("cyan") + White("white") + HiBlack("hblack") + HiRed("hred") + HiGreen("hgreen") + HiYellow("hyellow") + HiBlue("hblue") + HiMagenta("hmagenta") + HiCyan("hcyan") + HiWhite("hwhite") + + // Third visual test + fmt.Println() + Set(FgBlue) + fmt.Println("is this blue?") + Unset() + + Set(FgMagenta) + fmt.Println("and this magenta?") + Unset() + + // Fourth Visual test + fmt.Println() + blue := New(FgBlue).PrintlnFunc() + blue("blue text with custom print func") + + red := New(FgRed).PrintfFunc() + red("red text with a printf func: %d\n", 123) + + put := New(FgYellow).SprintFunc() + warn := New(FgRed).SprintFunc() + + fmt.Fprintf(Output, "this is a %s and this is %s.\n", put("warning"), warn("error")) + + info := New(FgWhite, BgGreen).SprintFunc() + fmt.Fprintf(Output, "this %s rocks!\n", info("package")) + + notice := New(FgBlue).FprintFunc() + notice(os.Stderr, "just a blue notice to stderr") + + // Fifth Visual Test + fmt.Println() + + fmt.Fprintln(Output, BlackString("black")) + fmt.Fprintln(Output, RedString("red")) + fmt.Fprintln(Output, GreenString("green")) + fmt.Fprintln(Output, YellowString("yellow")) + fmt.Fprintln(Output, BlueString("blue")) + fmt.Fprintln(Output, MagentaString("magenta")) + fmt.Fprintln(Output, CyanString("cyan")) + fmt.Fprintln(Output, WhiteString("white")) + fmt.Fprintln(Output, HiBlackString("hblack")) + fmt.Fprintln(Output, HiRedString("hred")) + fmt.Fprintln(Output, HiGreenString("hgreen")) + fmt.Fprintln(Output, HiYellowString("hyellow")) + fmt.Fprintln(Output, HiBlueString("hblue")) + fmt.Fprintln(Output, HiMagentaString("hmagenta")) + fmt.Fprintln(Output, HiCyanString("hcyan")) + fmt.Fprintln(Output, HiWhiteString("hwhite")) +} + +func TestNoFormat(t *testing.T) { + fmt.Printf("%s %%s = ", BlackString("Black")) + Black("%s") + + fmt.Printf("%s %%s = ", RedString("Red")) + Red("%s") + + fmt.Printf("%s %%s = ", GreenString("Green")) + Green("%s") + + fmt.Printf("%s %%s = ", YellowString("Yellow")) + Yellow("%s") + + fmt.Printf("%s %%s = ", BlueString("Blue")) + Blue("%s") + + fmt.Printf("%s %%s = ", MagentaString("Magenta")) + Magenta("%s") + + fmt.Printf("%s %%s = ", CyanString("Cyan")) + Cyan("%s") + + fmt.Printf("%s %%s = ", WhiteString("White")) + White("%s") + + fmt.Printf("%s %%s = ", HiBlackString("HiBlack")) + HiBlack("%s") + + fmt.Printf("%s %%s = ", HiRedString("HiRed")) + HiRed("%s") + + fmt.Printf("%s %%s = ", HiGreenString("HiGreen")) + HiGreen("%s") + + fmt.Printf("%s %%s = ", HiYellowString("HiYellow")) + HiYellow("%s") + + fmt.Printf("%s %%s = ", HiBlueString("HiBlue")) + HiBlue("%s") + + fmt.Printf("%s %%s = ", HiMagentaString("HiMagenta")) + HiMagenta("%s") + + fmt.Printf("%s %%s = ", HiCyanString("HiCyan")) + HiCyan("%s") + + fmt.Printf("%s %%s = ", HiWhiteString("HiWhite")) + HiWhite("%s") +} + +func TestNoFormatString(t *testing.T) { + tests := []struct { + f func(string, ...interface{}) string + format string + args []interface{} + want string + }{ + {BlackString, "%s", nil, "\x1b[30m%s\x1b[0m"}, + {RedString, "%s", nil, "\x1b[31m%s\x1b[0m"}, + {GreenString, "%s", nil, "\x1b[32m%s\x1b[0m"}, + {YellowString, "%s", nil, "\x1b[33m%s\x1b[0m"}, + {BlueString, "%s", nil, "\x1b[34m%s\x1b[0m"}, + {MagentaString, "%s", nil, "\x1b[35m%s\x1b[0m"}, + {CyanString, "%s", nil, "\x1b[36m%s\x1b[0m"}, + {WhiteString, "%s", nil, "\x1b[37m%s\x1b[0m"}, + {HiBlackString, "%s", nil, "\x1b[90m%s\x1b[0m"}, + {HiRedString, "%s", nil, "\x1b[91m%s\x1b[0m"}, + {HiGreenString, "%s", nil, "\x1b[92m%s\x1b[0m"}, + {HiYellowString, "%s", nil, "\x1b[93m%s\x1b[0m"}, + {HiBlueString, "%s", nil, "\x1b[94m%s\x1b[0m"}, + {HiMagentaString, "%s", nil, "\x1b[95m%s\x1b[0m"}, + {HiCyanString, "%s", nil, "\x1b[96m%s\x1b[0m"}, + {HiWhiteString, "%s", nil, "\x1b[97m%s\x1b[0m"}, + } + + for i, test := range tests { + s := fmt.Sprintf("%s", test.f(test.format, test.args...)) + if s != test.want { + t.Errorf("[%d] want: %q, got: %q", i, test.want, s) + } + } +} diff --git a/vendor/gopkg.in/fatih/color.v1/doc.go b/vendor/gopkg.in/fatih/color.v1/doc.go new file mode 100644 index 000000000..cf1e96500 --- /dev/null +++ b/vendor/gopkg.in/fatih/color.v1/doc.go @@ -0,0 +1,133 @@ +/* +Package color is an ANSI color package to output colorized or SGR defined +output to the standard output. The API can be used in several way, pick one +that suits you. + +Use simple and default helper functions with predefined foreground colors: + + color.Cyan("Prints text in cyan.") + + // a newline will be appended automatically + color.Blue("Prints %s in blue.", "text") + + // More default foreground colors.. + color.Red("We have red") + color.Yellow("Yellow color too!") + color.Magenta("And many others ..") + + // Hi-intensity colors + color.HiGreen("Bright green color.") + color.HiBlack("Bright black means gray..") + color.HiWhite("Shiny white color!") + +However there are times where custom color mixes are required. Below are some +examples to create custom color objects and use the print functions of each +separate color object. + + // Create a new color object + c := color.New(color.FgCyan).Add(color.Underline) + c.Println("Prints cyan text with an underline.") + + // Or just add them to New() + d := color.New(color.FgCyan, color.Bold) + d.Printf("This prints bold cyan %s\n", "too!.") + + + // Mix up foreground and background colors, create new mixes! + red := color.New(color.FgRed) + + boldRed := red.Add(color.Bold) + boldRed.Println("This will print text in bold red.") + + whiteBackground := red.Add(color.BgWhite) + whiteBackground.Println("Red text with White background.") + + // Use your own io.Writer output + color.New(color.FgBlue).Fprintln(myWriter, "blue color!") + + blue := color.New(color.FgBlue) + blue.Fprint(myWriter, "This will print text in blue.") + +You can create PrintXxx functions to simplify even more: + + // Create a custom print function for convenient + red := color.New(color.FgRed).PrintfFunc() + red("warning") + red("error: %s", err) + + // Mix up multiple attributes + notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() + notice("don't forget this...") + +You can also FprintXxx functions to pass your own io.Writer: + + blue := color.New(FgBlue).FprintfFunc() + blue(myWriter, "important notice: %s", stars) + + // Mix up with multiple attributes + success := color.New(color.Bold, color.FgGreen).FprintlnFunc() + success(myWriter, don't forget this...") + + +Or create SprintXxx functions to mix strings with other non-colorized strings: + + yellow := New(FgYellow).SprintFunc() + red := New(FgRed).SprintFunc() + + fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error")) + + info := New(FgWhite, BgGreen).SprintFunc() + fmt.Printf("this %s rocks!\n", info("package")) + +Windows support is enabled by default. All Print functions work as intended. +However only for color.SprintXXX functions, user should use fmt.FprintXXX and +set the output to color.Output: + + fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) + + info := New(FgWhite, BgGreen).SprintFunc() + fmt.Fprintf(color.Output, "this %s rocks!\n", info("package")) + +Using with existing code is possible. Just use the Set() method to set the +standard output to the given parameters. That way a rewrite of an existing +code is not required. + + // Use handy standard colors. + color.Set(color.FgYellow) + + fmt.Println("Existing text will be now in Yellow") + fmt.Printf("This one %s\n", "too") + + color.Unset() // don't forget to unset + + // You can mix up parameters + color.Set(color.FgMagenta, color.Bold) + defer color.Unset() // use it in your function + + fmt.Println("All text will be now bold magenta.") + +There might be a case where you want to disable color output (for example to +pipe the standard output of your app to somewhere else). `Color` has support to +disable colors both globally and for single color definition. For example +suppose you have a CLI app and a `--no-color` bool flag. You can easily disable +the color output with: + + var flagNoColor = flag.Bool("no-color", false, "Disable color output") + + if *flagNoColor { + color.NoColor = true // disables colorized output + } + +It also has support for single color definitions (local). You can +disable/enable color output on the fly: + + c := color.New(color.FgCyan) + c.Println("Prints cyan text") + + c.DisableColor() + c.Println("This is printed without any color") + + c.EnableColor() + c.Println("This prints again cyan...") +*/ +package color diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/.travis.yml b/vendor/gopkg.in/mattn/go-colorable.v0/.travis.yml new file mode 100644 index 000000000..98db8f060 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-colorable.v0/.travis.yml @@ -0,0 +1,9 @@ +language: go +go: + - tip + +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover +script: + - $HOME/gopath/bin/goveralls -repotoken xnXqRGwgW3SXIguzxf90ZSK1GPYZPaGrw diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/LICENSE b/vendor/gopkg.in/mattn/go-colorable.v0/LICENSE new file mode 100644 index 000000000..91b5cef30 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-colorable.v0/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Yasuhiro Matsumoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/README.md b/vendor/gopkg.in/mattn/go-colorable.v0/README.md new file mode 100644 index 000000000..56729a92c --- /dev/null +++ b/vendor/gopkg.in/mattn/go-colorable.v0/README.md @@ -0,0 +1,48 @@ +# go-colorable + +[![Godoc Reference](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable) +[![Build Status](https://travis-ci.org/mattn/go-colorable.svg?branch=master)](https://travis-ci.org/mattn/go-colorable) +[![Coverage Status](https://coveralls.io/repos/github/mattn/go-colorable/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-colorable?branch=master) +[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable) + +Colorable writer for windows. + +For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.) +This package is possible to handle escape sequence for ansi color on windows. + +## Too Bad! + +![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png) + + +## So Good! + +![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png) + +## Usage + +```go +logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) +logrus.SetOutput(colorable.NewColorableStdout()) + +logrus.Info("succeeded") +logrus.Warn("not correct") +logrus.Error("something error") +logrus.Fatal("panic") +``` + +You can compile above code on non-windows OSs. + +## Installation + +``` +$ go get github.com/mattn/go-colorable +``` + +# License + +MIT + +# Author + +Yasuhiro Matsumoto (a.k.a mattn) diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/_example/escape-seq/main.go b/vendor/gopkg.in/mattn/go-colorable.v0/_example/escape-seq/main.go new file mode 100644 index 000000000..8cbcb9097 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-colorable.v0/_example/escape-seq/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "bufio" + "fmt" + + "github.com/mattn/go-colorable" +) + +func main() { + stdOut := bufio.NewWriter(colorable.NewColorableStdout()) + + fmt.Fprint(stdOut, "\x1B[3GMove to 3rd Column\n") + fmt.Fprint(stdOut, "\x1B[1;2HMove to 2nd Column on 1st Line\n") + stdOut.Flush() +} diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/_example/logrus/main.go b/vendor/gopkg.in/mattn/go-colorable.v0/_example/logrus/main.go new file mode 100644 index 000000000..c569164b2 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-colorable.v0/_example/logrus/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "github.com/mattn/go-colorable" + "github.com/sirupsen/logrus" +) + +func main() { + logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) + logrus.SetOutput(colorable.NewColorableStdout()) + + logrus.Info("succeeded") + logrus.Warn("not correct") + logrus.Error("something error") + logrus.Fatal("panic") +} diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/_example/title/main.go b/vendor/gopkg.in/mattn/go-colorable.v0/_example/title/main.go new file mode 100644 index 000000000..e208870e7 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-colorable.v0/_example/title/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "fmt" + "os" + . "github.com/mattn/go-colorable" +) + +func main() { + out := NewColorableStdout() + fmt.Fprint(out, "\x1B]0;TITLE Changed\007(See title and hit any key)") + var c [1]byte + os.Stdin.Read(c[:]) +} diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/colorable_appengine.go b/vendor/gopkg.in/mattn/go-colorable.v0/colorable_appengine.go new file mode 100644 index 000000000..1f28d773d --- /dev/null +++ b/vendor/gopkg.in/mattn/go-colorable.v0/colorable_appengine.go @@ -0,0 +1,29 @@ +// +build appengine + +package colorable + +import ( + "io" + "os" + + _ "github.com/mattn/go-isatty" +) + +// NewColorable return new instance of Writer which handle escape sequence. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + return file +} + +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. +func NewColorableStdout() io.Writer { + return os.Stdout +} + +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. +func NewColorableStderr() io.Writer { + return os.Stderr +} diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/colorable_others.go b/vendor/gopkg.in/mattn/go-colorable.v0/colorable_others.go new file mode 100644 index 000000000..887f203dc --- /dev/null +++ b/vendor/gopkg.in/mattn/go-colorable.v0/colorable_others.go @@ -0,0 +1,30 @@ +// +build !windows +// +build !appengine + +package colorable + +import ( + "io" + "os" + + _ "github.com/mattn/go-isatty" +) + +// NewColorable return new instance of Writer which handle escape sequence. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + return file +} + +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. +func NewColorableStdout() io.Writer { + return os.Stdout +} + +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. +func NewColorableStderr() io.Writer { + return os.Stderr +} diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/colorable_test.go b/vendor/gopkg.in/mattn/go-colorable.v0/colorable_test.go new file mode 100644 index 000000000..3069869a3 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-colorable.v0/colorable_test.go @@ -0,0 +1,83 @@ +package colorable + +import ( + "bytes" + "os" + "runtime" + "testing" +) + +// checkEncoding checks that colorable is output encoding agnostic as long as +// the encoding is a superset of ASCII. This implies that one byte not part of +// an ANSI sequence must give exactly one byte in output +func checkEncoding(t *testing.T, data []byte) { + // Send non-UTF8 data to colorable + b := bytes.NewBuffer(make([]byte, 0, 10)) + if b.Len() != 0 { + t.FailNow() + } + // TODO move colorable wrapping outside the test + c := NewNonColorable(b) + c.Write(data) + if b.Len() != len(data) { + t.Fatalf("%d bytes expected, got %d", len(data), b.Len()) + } +} + +func TestEncoding(t *testing.T) { + checkEncoding(t, []byte{}) // Empty + checkEncoding(t, []byte(`abc`)) // "abc" + checkEncoding(t, []byte(`é`)) // "é" in UTF-8 + checkEncoding(t, []byte{233}) // 'é' in Latin-1 +} + +func TestNonColorable(t *testing.T) { + var buf bytes.Buffer + want := "hello" + NewNonColorable(&buf).Write([]byte("\x1b[0m" + want + "\x1b[2J")) + got := buf.String() + if got != "hello" { + t.Fatalf("want %q but %q", want, got) + } + + buf.Reset() + NewNonColorable(&buf).Write([]byte("\x1b[")) + got = buf.String() + if got != "" { + t.Fatalf("want %q but %q", "", got) + } +} + +func TestNonColorableNil(t *testing.T) { + paniced := false + func() { + defer func() { + recover() + paniced = true + }() + NewNonColorable(nil) + NewColorable(nil) + }() + + if !paniced { + t.Fatalf("should panic") + } +} + +func TestColorable(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skipf("skip this test on windows") + } + _, ok := NewColorableStdout().(*os.File) + if !ok { + t.Fatalf("should os.Stdout on UNIX") + } + _, ok = NewColorableStderr().(*os.File) + if !ok { + t.Fatalf("should os.Stdout on UNIX") + } + _, ok = NewColorable(os.Stdout).(*os.File) + if !ok { + t.Fatalf("should os.Stdout on UNIX") + } +} diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/colorable_windows.go b/vendor/gopkg.in/mattn/go-colorable.v0/colorable_windows.go new file mode 100644 index 000000000..e17a5474e --- /dev/null +++ b/vendor/gopkg.in/mattn/go-colorable.v0/colorable_windows.go @@ -0,0 +1,884 @@ +// +build windows +// +build !appengine + +package colorable + +import ( + "bytes" + "io" + "math" + "os" + "strconv" + "strings" + "syscall" + "unsafe" + + "github.com/mattn/go-isatty" +) + +const ( + foregroundBlue = 0x1 + foregroundGreen = 0x2 + foregroundRed = 0x4 + foregroundIntensity = 0x8 + foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity) + backgroundBlue = 0x10 + backgroundGreen = 0x20 + backgroundRed = 0x40 + backgroundIntensity = 0x80 + backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity) +) + +type wchar uint16 +type short int16 +type dword uint32 +type word uint16 + +type coord struct { + x short + y short +} + +type smallRect struct { + left short + top short + right short + bottom short +} + +type consoleScreenBufferInfo struct { + size coord + cursorPosition coord + attributes word + window smallRect + maximumWindowSize coord +} + +type consoleCursorInfo struct { + size dword + visible int32 +} + +var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") + procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") + procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") + procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") + procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") + procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") + procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo") + procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo") + procSetConsoleTitle = kernel32.NewProc("SetConsoleTitleW") +) + +// Writer provide colorable Writer to the console +type Writer struct { + out io.Writer + handle syscall.Handle + oldattr word + oldpos coord +} + +// NewColorable return new instance of Writer which handle escape sequence from File. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + if isatty.IsTerminal(file.Fd()) { + var csbi consoleScreenBufferInfo + handle := syscall.Handle(file.Fd()) + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + return &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}} + } + return file +} + +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. +func NewColorableStdout() io.Writer { + return NewColorable(os.Stdout) +} + +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. +func NewColorableStderr() io.Writer { + return NewColorable(os.Stderr) +} + +var color256 = map[int]int{ + 0: 0x000000, + 1: 0x800000, + 2: 0x008000, + 3: 0x808000, + 4: 0x000080, + 5: 0x800080, + 6: 0x008080, + 7: 0xc0c0c0, + 8: 0x808080, + 9: 0xff0000, + 10: 0x00ff00, + 11: 0xffff00, + 12: 0x0000ff, + 13: 0xff00ff, + 14: 0x00ffff, + 15: 0xffffff, + 16: 0x000000, + 17: 0x00005f, + 18: 0x000087, + 19: 0x0000af, + 20: 0x0000d7, + 21: 0x0000ff, + 22: 0x005f00, + 23: 0x005f5f, + 24: 0x005f87, + 25: 0x005faf, + 26: 0x005fd7, + 27: 0x005fff, + 28: 0x008700, + 29: 0x00875f, + 30: 0x008787, + 31: 0x0087af, + 32: 0x0087d7, + 33: 0x0087ff, + 34: 0x00af00, + 35: 0x00af5f, + 36: 0x00af87, + 37: 0x00afaf, + 38: 0x00afd7, + 39: 0x00afff, + 40: 0x00d700, + 41: 0x00d75f, + 42: 0x00d787, + 43: 0x00d7af, + 44: 0x00d7d7, + 45: 0x00d7ff, + 46: 0x00ff00, + 47: 0x00ff5f, + 48: 0x00ff87, + 49: 0x00ffaf, + 50: 0x00ffd7, + 51: 0x00ffff, + 52: 0x5f0000, + 53: 0x5f005f, + 54: 0x5f0087, + 55: 0x5f00af, + 56: 0x5f00d7, + 57: 0x5f00ff, + 58: 0x5f5f00, + 59: 0x5f5f5f, + 60: 0x5f5f87, + 61: 0x5f5faf, + 62: 0x5f5fd7, + 63: 0x5f5fff, + 64: 0x5f8700, + 65: 0x5f875f, + 66: 0x5f8787, + 67: 0x5f87af, + 68: 0x5f87d7, + 69: 0x5f87ff, + 70: 0x5faf00, + 71: 0x5faf5f, + 72: 0x5faf87, + 73: 0x5fafaf, + 74: 0x5fafd7, + 75: 0x5fafff, + 76: 0x5fd700, + 77: 0x5fd75f, + 78: 0x5fd787, + 79: 0x5fd7af, + 80: 0x5fd7d7, + 81: 0x5fd7ff, + 82: 0x5fff00, + 83: 0x5fff5f, + 84: 0x5fff87, + 85: 0x5fffaf, + 86: 0x5fffd7, + 87: 0x5fffff, + 88: 0x870000, + 89: 0x87005f, + 90: 0x870087, + 91: 0x8700af, + 92: 0x8700d7, + 93: 0x8700ff, + 94: 0x875f00, + 95: 0x875f5f, + 96: 0x875f87, + 97: 0x875faf, + 98: 0x875fd7, + 99: 0x875fff, + 100: 0x878700, + 101: 0x87875f, + 102: 0x878787, + 103: 0x8787af, + 104: 0x8787d7, + 105: 0x8787ff, + 106: 0x87af00, + 107: 0x87af5f, + 108: 0x87af87, + 109: 0x87afaf, + 110: 0x87afd7, + 111: 0x87afff, + 112: 0x87d700, + 113: 0x87d75f, + 114: 0x87d787, + 115: 0x87d7af, + 116: 0x87d7d7, + 117: 0x87d7ff, + 118: 0x87ff00, + 119: 0x87ff5f, + 120: 0x87ff87, + 121: 0x87ffaf, + 122: 0x87ffd7, + 123: 0x87ffff, + 124: 0xaf0000, + 125: 0xaf005f, + 126: 0xaf0087, + 127: 0xaf00af, + 128: 0xaf00d7, + 129: 0xaf00ff, + 130: 0xaf5f00, + 131: 0xaf5f5f, + 132: 0xaf5f87, + 133: 0xaf5faf, + 134: 0xaf5fd7, + 135: 0xaf5fff, + 136: 0xaf8700, + 137: 0xaf875f, + 138: 0xaf8787, + 139: 0xaf87af, + 140: 0xaf87d7, + 141: 0xaf87ff, + 142: 0xafaf00, + 143: 0xafaf5f, + 144: 0xafaf87, + 145: 0xafafaf, + 146: 0xafafd7, + 147: 0xafafff, + 148: 0xafd700, + 149: 0xafd75f, + 150: 0xafd787, + 151: 0xafd7af, + 152: 0xafd7d7, + 153: 0xafd7ff, + 154: 0xafff00, + 155: 0xafff5f, + 156: 0xafff87, + 157: 0xafffaf, + 158: 0xafffd7, + 159: 0xafffff, + 160: 0xd70000, + 161: 0xd7005f, + 162: 0xd70087, + 163: 0xd700af, + 164: 0xd700d7, + 165: 0xd700ff, + 166: 0xd75f00, + 167: 0xd75f5f, + 168: 0xd75f87, + 169: 0xd75faf, + 170: 0xd75fd7, + 171: 0xd75fff, + 172: 0xd78700, + 173: 0xd7875f, + 174: 0xd78787, + 175: 0xd787af, + 176: 0xd787d7, + 177: 0xd787ff, + 178: 0xd7af00, + 179: 0xd7af5f, + 180: 0xd7af87, + 181: 0xd7afaf, + 182: 0xd7afd7, + 183: 0xd7afff, + 184: 0xd7d700, + 185: 0xd7d75f, + 186: 0xd7d787, + 187: 0xd7d7af, + 188: 0xd7d7d7, + 189: 0xd7d7ff, + 190: 0xd7ff00, + 191: 0xd7ff5f, + 192: 0xd7ff87, + 193: 0xd7ffaf, + 194: 0xd7ffd7, + 195: 0xd7ffff, + 196: 0xff0000, + 197: 0xff005f, + 198: 0xff0087, + 199: 0xff00af, + 200: 0xff00d7, + 201: 0xff00ff, + 202: 0xff5f00, + 203: 0xff5f5f, + 204: 0xff5f87, + 205: 0xff5faf, + 206: 0xff5fd7, + 207: 0xff5fff, + 208: 0xff8700, + 209: 0xff875f, + 210: 0xff8787, + 211: 0xff87af, + 212: 0xff87d7, + 213: 0xff87ff, + 214: 0xffaf00, + 215: 0xffaf5f, + 216: 0xffaf87, + 217: 0xffafaf, + 218: 0xffafd7, + 219: 0xffafff, + 220: 0xffd700, + 221: 0xffd75f, + 222: 0xffd787, + 223: 0xffd7af, + 224: 0xffd7d7, + 225: 0xffd7ff, + 226: 0xffff00, + 227: 0xffff5f, + 228: 0xffff87, + 229: 0xffffaf, + 230: 0xffffd7, + 231: 0xffffff, + 232: 0x080808, + 233: 0x121212, + 234: 0x1c1c1c, + 235: 0x262626, + 236: 0x303030, + 237: 0x3a3a3a, + 238: 0x444444, + 239: 0x4e4e4e, + 240: 0x585858, + 241: 0x626262, + 242: 0x6c6c6c, + 243: 0x767676, + 244: 0x808080, + 245: 0x8a8a8a, + 246: 0x949494, + 247: 0x9e9e9e, + 248: 0xa8a8a8, + 249: 0xb2b2b2, + 250: 0xbcbcbc, + 251: 0xc6c6c6, + 252: 0xd0d0d0, + 253: 0xdadada, + 254: 0xe4e4e4, + 255: 0xeeeeee, +} + +// `\033]0;TITLESTR\007` +func doTitleSequence(er *bytes.Reader) error { + var c byte + var err error + + c, err = er.ReadByte() + if err != nil { + return err + } + if c != '0' && c != '2' { + return nil + } + c, err = er.ReadByte() + if err != nil { + return err + } + if c != ';' { + return nil + } + title := make([]byte, 0, 80) + for { + c, err = er.ReadByte() + if err != nil { + return err + } + if c == 0x07 || c == '\n' { + break + } + title = append(title, c) + } + if len(title) > 0 { + title8, err := syscall.UTF16PtrFromString(string(title)) + if err == nil { + procSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8))) + } + } + return nil +} + +// Write write data on console +func (w *Writer) Write(data []byte) (n int, err error) { + var csbi consoleScreenBufferInfo + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + + er := bytes.NewReader(data) + var bw [1]byte +loop: + for { + c1, err := er.ReadByte() + if err != nil { + break loop + } + if c1 != 0x1b { + bw[0] = c1 + w.out.Write(bw[:]) + continue + } + c2, err := er.ReadByte() + if err != nil { + break loop + } + + if c2 == ']' { + if err := doTitleSequence(er); err != nil { + break loop + } + continue + } + if c2 != 0x5b { + continue + } + + var buf bytes.Buffer + var m byte + for { + c, err := er.ReadByte() + if err != nil { + break loop + } + if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { + m = c + break + } + buf.Write([]byte(string(c))) + } + + switch m { + case 'A': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.y -= short(n) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'B': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.y += short(n) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'C': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x += short(n) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'D': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x -= short(n) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'E': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = 0 + csbi.cursorPosition.y += short(n) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'F': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = 0 + csbi.cursorPosition.y -= short(n) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'G': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = short(n - 1) + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'H', 'f': + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + if buf.Len() > 0 { + token := strings.Split(buf.String(), ";") + switch len(token) { + case 1: + n1, err := strconv.Atoi(token[0]) + if err != nil { + continue + } + csbi.cursorPosition.y = short(n1 - 1) + case 2: + n1, err := strconv.Atoi(token[0]) + if err != nil { + continue + } + n2, err := strconv.Atoi(token[1]) + if err != nil { + continue + } + csbi.cursorPosition.x = short(n2 - 1) + csbi.cursorPosition.y = short(n1 - 1) + } + } else { + csbi.cursorPosition.y = 0 + } + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'J': + n := 0 + if buf.Len() > 0 { + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + } + var count, written dword + var cursor coord + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + switch n { + case 0: + cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) + case 1: + cursor = coord{x: csbi.window.left, y: csbi.window.top} + count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.window.top-csbi.cursorPosition.y)*csbi.size.x) + case 2: + cursor = coord{x: csbi.window.left, y: csbi.window.top} + count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) + } + procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + case 'K': + n := 0 + if buf.Len() > 0 { + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + } + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + var cursor coord + var count, written dword + switch n { + case 0: + cursor = coord{x: csbi.cursorPosition.x + 1, y: csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x - 1) + case 1: + cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x) + case 2: + cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} + count = dword(csbi.size.x) + } + procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + case 'm': + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + attr := csbi.attributes + cs := buf.String() + if cs == "" { + procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr)) + continue + } + token := strings.Split(cs, ";") + for i := 0; i < len(token); i++ { + ns := token[i] + if n, err = strconv.Atoi(ns); err == nil { + switch { + case n == 0 || n == 100: + attr = w.oldattr + case 1 <= n && n <= 5: + attr |= foregroundIntensity + case n == 7: + attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) + case n == 22 || n == 25: + attr |= foregroundIntensity + case n == 27: + attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) + case 30 <= n && n <= 37: + attr &= backgroundMask + if (n-30)&1 != 0 { + attr |= foregroundRed + } + if (n-30)&2 != 0 { + attr |= foregroundGreen + } + if (n-30)&4 != 0 { + attr |= foregroundBlue + } + case n == 38: // set foreground color. + if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") { + if n256, err := strconv.Atoi(token[i+2]); err == nil { + if n256foreAttr == nil { + n256setup() + } + attr &= backgroundMask + attr |= n256foreAttr[n256] + i += 2 + } + } else { + attr = attr & (w.oldattr & backgroundMask) + } + case n == 39: // reset foreground color. + attr &= backgroundMask + attr |= w.oldattr & foregroundMask + case 40 <= n && n <= 47: + attr &= foregroundMask + if (n-40)&1 != 0 { + attr |= backgroundRed + } + if (n-40)&2 != 0 { + attr |= backgroundGreen + } + if (n-40)&4 != 0 { + attr |= backgroundBlue + } + case n == 48: // set background color. + if i < len(token)-2 && token[i+1] == "5" { + if n256, err := strconv.Atoi(token[i+2]); err == nil { + if n256backAttr == nil { + n256setup() + } + attr &= foregroundMask + attr |= n256backAttr[n256] + i += 2 + } + } else { + attr = attr & (w.oldattr & foregroundMask) + } + case n == 49: // reset foreground color. + attr &= foregroundMask + attr |= w.oldattr & backgroundMask + case 90 <= n && n <= 97: + attr = (attr & backgroundMask) + attr |= foregroundIntensity + if (n-90)&1 != 0 { + attr |= foregroundRed + } + if (n-90)&2 != 0 { + attr |= foregroundGreen + } + if (n-90)&4 != 0 { + attr |= foregroundBlue + } + case 100 <= n && n <= 107: + attr = (attr & foregroundMask) + attr |= backgroundIntensity + if (n-100)&1 != 0 { + attr |= backgroundRed + } + if (n-100)&2 != 0 { + attr |= backgroundGreen + } + if (n-100)&4 != 0 { + attr |= backgroundBlue + } + } + procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr)) + } + } + case 'h': + var ci consoleCursorInfo + cs := buf.String() + if cs == "5>" { + procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 0 + procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?25" { + procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 1 + procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + } + case 'l': + var ci consoleCursorInfo + cs := buf.String() + if cs == "5>" { + procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 1 + procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?25" { + procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 0 + procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) + } + case 's': + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + w.oldpos = csbi.cursorPosition + case 'u': + procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) + } + } + + return len(data), nil +} + +type consoleColor struct { + rgb int + red bool + green bool + blue bool + intensity bool +} + +func (c consoleColor) foregroundAttr() (attr word) { + if c.red { + attr |= foregroundRed + } + if c.green { + attr |= foregroundGreen + } + if c.blue { + attr |= foregroundBlue + } + if c.intensity { + attr |= foregroundIntensity + } + return +} + +func (c consoleColor) backgroundAttr() (attr word) { + if c.red { + attr |= backgroundRed + } + if c.green { + attr |= backgroundGreen + } + if c.blue { + attr |= backgroundBlue + } + if c.intensity { + attr |= backgroundIntensity + } + return +} + +var color16 = []consoleColor{ + {0x000000, false, false, false, false}, + {0x000080, false, false, true, false}, + {0x008000, false, true, false, false}, + {0x008080, false, true, true, false}, + {0x800000, true, false, false, false}, + {0x800080, true, false, true, false}, + {0x808000, true, true, false, false}, + {0xc0c0c0, true, true, true, false}, + {0x808080, false, false, false, true}, + {0x0000ff, false, false, true, true}, + {0x00ff00, false, true, false, true}, + {0x00ffff, false, true, true, true}, + {0xff0000, true, false, false, true}, + {0xff00ff, true, false, true, true}, + {0xffff00, true, true, false, true}, + {0xffffff, true, true, true, true}, +} + +type hsv struct { + h, s, v float32 +} + +func (a hsv) dist(b hsv) float32 { + dh := a.h - b.h + switch { + case dh > 0.5: + dh = 1 - dh + case dh < -0.5: + dh = -1 - dh + } + ds := a.s - b.s + dv := a.v - b.v + return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv))) +} + +func toHSV(rgb int) hsv { + r, g, b := float32((rgb&0xFF0000)>>16)/256.0, + float32((rgb&0x00FF00)>>8)/256.0, + float32(rgb&0x0000FF)/256.0 + min, max := minmax3f(r, g, b) + h := max - min + if h > 0 { + if max == r { + h = (g - b) / h + if h < 0 { + h += 6 + } + } else if max == g { + h = 2 + (b-r)/h + } else { + h = 4 + (r-g)/h + } + } + h /= 6.0 + s := max - min + if max != 0 { + s /= max + } + v := max + return hsv{h: h, s: s, v: v} +} + +type hsvTable []hsv + +func toHSVTable(rgbTable []consoleColor) hsvTable { + t := make(hsvTable, len(rgbTable)) + for i, c := range rgbTable { + t[i] = toHSV(c.rgb) + } + return t +} + +func (t hsvTable) find(rgb int) consoleColor { + hsv := toHSV(rgb) + n := 7 + l := float32(5.0) + for i, p := range t { + d := hsv.dist(p) + if d < l { + l, n = d, i + } + } + return color16[n] +} + +func minmax3f(a, b, c float32) (min, max float32) { + if a < b { + if b < c { + return a, c + } else if a < c { + return a, b + } else { + return c, b + } + } else { + if a < c { + return b, c + } else if b < c { + return b, a + } else { + return c, a + } + } +} + +var n256foreAttr []word +var n256backAttr []word + +func n256setup() { + n256foreAttr = make([]word, 256) + n256backAttr = make([]word, 256) + t := toHSVTable(color16) + for i, rgb := range color256 { + c := t.find(rgb) + n256foreAttr[i] = c.foregroundAttr() + n256backAttr[i] = c.backgroundAttr() + } +} diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/noncolorable.go b/vendor/gopkg.in/mattn/go-colorable.v0/noncolorable.go new file mode 100644 index 000000000..9721e16f4 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-colorable.v0/noncolorable.go @@ -0,0 +1,55 @@ +package colorable + +import ( + "bytes" + "io" +) + +// NonColorable hold writer but remove escape sequence. +type NonColorable struct { + out io.Writer +} + +// NewNonColorable return new instance of Writer which remove escape sequence from Writer. +func NewNonColorable(w io.Writer) io.Writer { + return &NonColorable{out: w} +} + +// Write write data on console +func (w *NonColorable) Write(data []byte) (n int, err error) { + er := bytes.NewReader(data) + var bw [1]byte +loop: + for { + c1, err := er.ReadByte() + if err != nil { + break loop + } + if c1 != 0x1b { + bw[0] = c1 + w.out.Write(bw[:]) + continue + } + c2, err := er.ReadByte() + if err != nil { + break loop + } + if c2 != 0x5b { + continue + } + + var buf bytes.Buffer + for { + c, err := er.ReadByte() + if err != nil { + break loop + } + if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { + break + } + buf.Write([]byte(string(c))) + } + } + + return len(data), nil +} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/.travis.yml b/vendor/gopkg.in/mattn/go-isatty.v0/.travis.yml new file mode 100644 index 000000000..b9f8b239c --- /dev/null +++ b/vendor/gopkg.in/mattn/go-isatty.v0/.travis.yml @@ -0,0 +1,9 @@ +language: go +go: + - tip + +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover +script: + - $HOME/gopath/bin/goveralls -repotoken 3gHdORO5k5ziZcWMBxnd9LrMZaJs8m9x5 diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/LICENSE b/vendor/gopkg.in/mattn/go-isatty.v0/LICENSE new file mode 100644 index 000000000..65dc692b6 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-isatty.v0/LICENSE @@ -0,0 +1,9 @@ +Copyright (c) Yasuhiro MATSUMOTO + +MIT License (Expat) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/README.md b/vendor/gopkg.in/mattn/go-isatty.v0/README.md new file mode 100644 index 000000000..1e69004bb --- /dev/null +++ b/vendor/gopkg.in/mattn/go-isatty.v0/README.md @@ -0,0 +1,50 @@ +# go-isatty + +[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty) +[![Build Status](https://travis-ci.org/mattn/go-isatty.svg?branch=master)](https://travis-ci.org/mattn/go-isatty) +[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master) +[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty) + +isatty for golang + +## Usage + +```go +package main + +import ( + "fmt" + "github.com/mattn/go-isatty" + "os" +) + +func main() { + if isatty.IsTerminal(os.Stdout.Fd()) { + fmt.Println("Is Terminal") + } else if isatty.IsCygwinTerminal(os.Stdout.Fd()) { + fmt.Println("Is Cygwin/MSYS2 Terminal") + } else { + fmt.Println("Is Not Terminal") + } +} +``` + +## Installation + +``` +$ go get github.com/mattn/go-isatty +``` + +## License + +MIT + +## Author + +Yasuhiro Matsumoto (a.k.a mattn) + +## Thanks + +* k-takata: base idea for IsCygwinTerminal + + https://github.com/k-takata/go-iscygpty diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/doc.go b/vendor/gopkg.in/mattn/go-isatty.v0/doc.go new file mode 100644 index 000000000..17d4f90eb --- /dev/null +++ b/vendor/gopkg.in/mattn/go-isatty.v0/doc.go @@ -0,0 +1,2 @@ +// Package isatty implements interface to isatty +package isatty diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/example_test.go b/vendor/gopkg.in/mattn/go-isatty.v0/example_test.go new file mode 100644 index 000000000..fa8f7e745 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-isatty.v0/example_test.go @@ -0,0 +1,18 @@ +package isatty_test + +import ( + "fmt" + "os" + + "github.com/mattn/go-isatty" +) + +func Example() { + if isatty.IsTerminal(os.Stdout.Fd()) { + fmt.Println("Is Terminal") + } else if isatty.IsCygwinTerminal(os.Stdout.Fd()) { + fmt.Println("Is Cygwin/MSYS2 Terminal") + } else { + fmt.Println("Is Not Terminal") + } +} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_appengine.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_appengine.go new file mode 100644 index 000000000..9584a9884 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_appengine.go @@ -0,0 +1,15 @@ +// +build appengine + +package isatty + +// IsTerminal returns true if the file descriptor is terminal which +// is always false on on appengine classic which is a sandboxed PaaS. +func IsTerminal(fd uintptr) bool { + return false +} + +// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_bsd.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_bsd.go new file mode 100644 index 000000000..42f2514d1 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_bsd.go @@ -0,0 +1,18 @@ +// +build darwin freebsd openbsd netbsd dragonfly +// +build !appengine + +package isatty + +import ( + "syscall" + "unsafe" +) + +const ioctlReadTermios = syscall.TIOCGETA + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var termios syscall.Termios + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 +} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux.go new file mode 100644 index 000000000..7384cf991 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux.go @@ -0,0 +1,18 @@ +// +build linux +// +build !appengine,!ppc64,!ppc64le + +package isatty + +import ( + "syscall" + "unsafe" +) + +const ioctlReadTermios = syscall.TCGETS + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var termios syscall.Termios + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 +} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux_ppc64x.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux_ppc64x.go new file mode 100644 index 000000000..44e5d2130 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux_ppc64x.go @@ -0,0 +1,19 @@ +// +build linux +// +build ppc64 ppc64le + +package isatty + +import ( + "unsafe" + + syscall "golang.org/x/sys/unix" +) + +const ioctlReadTermios = syscall.TCGETS + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var termios syscall.Termios + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 +} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_others.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_others.go new file mode 100644 index 000000000..ff4de3d9a --- /dev/null +++ b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_others.go @@ -0,0 +1,10 @@ +// +build !windows +// +build !appengine + +package isatty + +// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_others_test.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_others_test.go new file mode 100644 index 000000000..a2091cf47 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_others_test.go @@ -0,0 +1,19 @@ +// +build !windows + +package isatty + +import ( + "os" + "testing" +) + +func TestTerminal(t *testing.T) { + // test for non-panic + IsTerminal(os.Stdout.Fd()) +} + +func TestCygwinPipeName(t *testing.T) { + if IsCygwinTerminal(os.Stdout.Fd()) { + t.Fatal("should be false always") + } +} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_solaris.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_solaris.go new file mode 100644 index 000000000..1f0c6bf53 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_solaris.go @@ -0,0 +1,16 @@ +// +build solaris +// +build !appengine + +package isatty + +import ( + "golang.org/x/sys/unix" +) + +// IsTerminal returns true if the given file descriptor is a terminal. +// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c +func IsTerminal(fd uintptr) bool { + var termio unix.Termio + err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio) + return err == nil +} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows.go new file mode 100644 index 000000000..af51cbcaa --- /dev/null +++ b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows.go @@ -0,0 +1,94 @@ +// +build windows +// +build !appengine + +package isatty + +import ( + "strings" + "syscall" + "unicode/utf16" + "unsafe" +) + +const ( + fileNameInfo uintptr = 2 + fileTypePipe = 3 +) + +var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") + procGetConsoleMode = kernel32.NewProc("GetConsoleMode") + procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx") + procGetFileType = kernel32.NewProc("GetFileType") +) + +func init() { + // Check if GetFileInformationByHandleEx is available. + if procGetFileInformationByHandleEx.Find() != nil { + procGetFileInformationByHandleEx = nil + } +} + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var st uint32 + r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) + return r != 0 && e == 0 +} + +// Check pipe name is used for cygwin/msys2 pty. +// Cygwin/MSYS2 PTY has a name like: +// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master +func isCygwinPipeName(name string) bool { + token := strings.Split(name, "-") + if len(token) < 5 { + return false + } + + if token[0] != `\msys` && token[0] != `\cygwin` { + return false + } + + if token[1] == "" { + return false + } + + if !strings.HasPrefix(token[2], "pty") { + return false + } + + if token[3] != `from` && token[3] != `to` { + return false + } + + if token[4] != "master" { + return false + } + + return true +} + +// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 +// terminal. +func IsCygwinTerminal(fd uintptr) bool { + if procGetFileInformationByHandleEx == nil { + return false + } + + // Cygwin/msys's pty is a pipe. + ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0) + if ft != fileTypePipe || e != 0 { + return false + } + + var buf [2 + syscall.MAX_PATH]uint16 + r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), + 4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)), + uintptr(len(buf)*2), 0, 0) + if r == 0 || e != 0 { + return false + } + + l := *(*uint32)(unsafe.Pointer(&buf)) + return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2]))) +} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows_test.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows_test.go new file mode 100644 index 000000000..777e8a603 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows_test.go @@ -0,0 +1,35 @@ +// +build windows + +package isatty + +import ( + "testing" +) + +func TestCygwinPipeName(t *testing.T) { + tests := []struct { + name string + result bool + }{ + {``, false}, + {`\msys-`, false}, + {`\cygwin-----`, false}, + {`\msys-x-PTY5-pty1-from-master`, false}, + {`\cygwin-x-PTY5-from-master`, false}, + {`\cygwin-x-pty2-from-toaster`, false}, + {`\cygwin--pty2-from-master`, false}, + {`\\cygwin-x-pty2-from-master`, false}, + {`\cygwin-x-pty2-from-master-`, true}, // for the feature + {`\cygwin-e022582115c10879-pty4-from-master`, true}, + {`\msys-e022582115c10879-pty4-to-master`, true}, + {`\cygwin-e022582115c10879-pty4-to-master`, true}, + } + + for _, test := range tests { + want := test.result + got := isCygwinPipeName(test.name) + if want != got { + t.Fatalf("isatty(%q): got %v, want %v:", test.name, got, want) + } + } +} diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/.travis.yml b/vendor/gopkg.in/mattn/go-runewidth.v0/.travis.yml new file mode 100644 index 000000000..5c9c2a30f --- /dev/null +++ b/vendor/gopkg.in/mattn/go-runewidth.v0/.travis.yml @@ -0,0 +1,8 @@ +language: go +go: + - tip +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover +script: + - $HOME/gopath/bin/goveralls -repotoken lAKAWPzcGsD3A8yBX3BGGtRUdJ6CaGERL diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/LICENSE b/vendor/gopkg.in/mattn/go-runewidth.v0/LICENSE new file mode 100644 index 000000000..91b5cef30 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-runewidth.v0/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Yasuhiro Matsumoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/README.mkd b/vendor/gopkg.in/mattn/go-runewidth.v0/README.mkd new file mode 100644 index 000000000..66663a94b --- /dev/null +++ b/vendor/gopkg.in/mattn/go-runewidth.v0/README.mkd @@ -0,0 +1,27 @@ +go-runewidth +============ + +[![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth) +[![Coverage Status](https://coveralls.io/repos/mattn/go-runewidth/badge.png?branch=HEAD)](https://coveralls.io/r/mattn/go-runewidth?branch=HEAD) +[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth) +[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth) + +Provides functions to get fixed width of the character or string. + +Usage +----- + +```go +runewidth.StringWidth("つのだ☆HIRO") == 12 +``` + + +Author +------ + +Yasuhiro Matsumoto + +License +------- + +under the MIT License: http://mattn.mit-license.org/2013 diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth.go b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth.go new file mode 100644 index 000000000..2164497ad --- /dev/null +++ b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth.go @@ -0,0 +1,1223 @@ +package runewidth + +var ( + // EastAsianWidth will be set true if the current locale is CJK + EastAsianWidth = IsEastAsian() + + // DefaultCondition is a condition in current locale + DefaultCondition = &Condition{EastAsianWidth} +) + +type interval struct { + first rune + last rune +} + +type table []interval + +func inTables(r rune, ts ...table) bool { + for _, t := range ts { + if inTable(r, t) { + return true + } + } + return false +} + +func inTable(r rune, t table) bool { + // func (t table) IncludesRune(r rune) bool { + if r < t[0].first { + return false + } + + bot := 0 + top := len(t) - 1 + for top >= bot { + mid := (bot + top) / 2 + + switch { + case t[mid].last < r: + bot = mid + 1 + case t[mid].first > r: + top = mid - 1 + default: + return true + } + } + + return false +} + +var private = table{ + {0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD}, +} + +var nonprint = table{ + {0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD}, + {0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F}, + {0x202A, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF}, + {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF}, +} + +var combining = table{ + {0x0300, 0x036F}, {0x0483, 0x0489}, {0x0591, 0x05BD}, + {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C5}, + {0x05C7, 0x05C7}, {0x0610, 0x061A}, {0x064B, 0x065F}, + {0x0670, 0x0670}, {0x06D6, 0x06DC}, {0x06DF, 0x06E4}, + {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, {0x0711, 0x0711}, + {0x0730, 0x074A}, {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, + {0x0816, 0x0819}, {0x081B, 0x0823}, {0x0825, 0x0827}, + {0x0829, 0x082D}, {0x0859, 0x085B}, {0x08D4, 0x08E1}, + {0x08E3, 0x0903}, {0x093A, 0x093C}, {0x093E, 0x094F}, + {0x0951, 0x0957}, {0x0962, 0x0963}, {0x0981, 0x0983}, + {0x09BC, 0x09BC}, {0x09BE, 0x09C4}, {0x09C7, 0x09C8}, + {0x09CB, 0x09CD}, {0x09D7, 0x09D7}, {0x09E2, 0x09E3}, + {0x0A01, 0x0A03}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42}, + {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, + {0x0A70, 0x0A71}, {0x0A75, 0x0A75}, {0x0A81, 0x0A83}, + {0x0ABC, 0x0ABC}, {0x0ABE, 0x0AC5}, {0x0AC7, 0x0AC9}, + {0x0ACB, 0x0ACD}, {0x0AE2, 0x0AE3}, {0x0B01, 0x0B03}, + {0x0B3C, 0x0B3C}, {0x0B3E, 0x0B44}, {0x0B47, 0x0B48}, + {0x0B4B, 0x0B4D}, {0x0B56, 0x0B57}, {0x0B62, 0x0B63}, + {0x0B82, 0x0B82}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, + {0x0BCA, 0x0BCD}, {0x0BD7, 0x0BD7}, {0x0C00, 0x0C03}, + {0x0C3E, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, + {0x0C55, 0x0C56}, {0x0C62, 0x0C63}, {0x0C81, 0x0C83}, + {0x0CBC, 0x0CBC}, {0x0CBE, 0x0CC4}, {0x0CC6, 0x0CC8}, + {0x0CCA, 0x0CCD}, {0x0CD5, 0x0CD6}, {0x0CE2, 0x0CE3}, + {0x0D01, 0x0D03}, {0x0D3E, 0x0D44}, {0x0D46, 0x0D48}, + {0x0D4A, 0x0D4D}, {0x0D57, 0x0D57}, {0x0D62, 0x0D63}, + {0x0D82, 0x0D83}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, + {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, {0x0DF2, 0x0DF3}, + {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, + {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, + {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, + {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F3E, 0x0F3F}, + {0x0F71, 0x0F84}, {0x0F86, 0x0F87}, {0x0F8D, 0x0F97}, + {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102B, 0x103E}, + {0x1056, 0x1059}, {0x105E, 0x1060}, {0x1062, 0x1064}, + {0x1067, 0x106D}, {0x1071, 0x1074}, {0x1082, 0x108D}, + {0x108F, 0x108F}, {0x109A, 0x109D}, {0x135D, 0x135F}, + {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753}, + {0x1772, 0x1773}, {0x17B4, 0x17D3}, {0x17DD, 0x17DD}, + {0x180B, 0x180D}, {0x1885, 0x1886}, {0x18A9, 0x18A9}, + {0x1920, 0x192B}, {0x1930, 0x193B}, {0x1A17, 0x1A1B}, + {0x1A55, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A7F}, + {0x1AB0, 0x1ABE}, {0x1B00, 0x1B04}, {0x1B34, 0x1B44}, + {0x1B6B, 0x1B73}, {0x1B80, 0x1B82}, {0x1BA1, 0x1BAD}, + {0x1BE6, 0x1BF3}, {0x1C24, 0x1C37}, {0x1CD0, 0x1CD2}, + {0x1CD4, 0x1CE8}, {0x1CED, 0x1CED}, {0x1CF2, 0x1CF4}, + {0x1CF8, 0x1CF9}, {0x1DC0, 0x1DF5}, {0x1DFB, 0x1DFF}, + {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2D7F, 0x2D7F}, + {0x2DE0, 0x2DFF}, {0x302A, 0x302F}, {0x3099, 0x309A}, + {0xA66F, 0xA672}, {0xA674, 0xA67D}, {0xA69E, 0xA69F}, + {0xA6F0, 0xA6F1}, {0xA802, 0xA802}, {0xA806, 0xA806}, + {0xA80B, 0xA80B}, {0xA823, 0xA827}, {0xA880, 0xA881}, + {0xA8B4, 0xA8C5}, {0xA8E0, 0xA8F1}, {0xA926, 0xA92D}, + {0xA947, 0xA953}, {0xA980, 0xA983}, {0xA9B3, 0xA9C0}, + {0xA9E5, 0xA9E5}, {0xAA29, 0xAA36}, {0xAA43, 0xAA43}, + {0xAA4C, 0xAA4D}, {0xAA7B, 0xAA7D}, {0xAAB0, 0xAAB0}, + {0xAAB2, 0xAAB4}, {0xAAB7, 0xAAB8}, {0xAABE, 0xAABF}, + {0xAAC1, 0xAAC1}, {0xAAEB, 0xAAEF}, {0xAAF5, 0xAAF6}, + {0xABE3, 0xABEA}, {0xABEC, 0xABED}, {0xFB1E, 0xFB1E}, + {0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, + {0x102E0, 0x102E0}, {0x10376, 0x1037A}, {0x10A01, 0x10A03}, + {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, {0x10A38, 0x10A3A}, + {0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x11000, 0x11002}, + {0x11038, 0x11046}, {0x1107F, 0x11082}, {0x110B0, 0x110BA}, + {0x11100, 0x11102}, {0x11127, 0x11134}, {0x11173, 0x11173}, + {0x11180, 0x11182}, {0x111B3, 0x111C0}, {0x111CA, 0x111CC}, + {0x1122C, 0x11237}, {0x1123E, 0x1123E}, {0x112DF, 0x112EA}, + {0x11300, 0x11303}, {0x1133C, 0x1133C}, {0x1133E, 0x11344}, + {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11357, 0x11357}, + {0x11362, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374}, + {0x11435, 0x11446}, {0x114B0, 0x114C3}, {0x115AF, 0x115B5}, + {0x115B8, 0x115C0}, {0x115DC, 0x115DD}, {0x11630, 0x11640}, + {0x116AB, 0x116B7}, {0x1171D, 0x1172B}, {0x11C2F, 0x11C36}, + {0x11C38, 0x11C3F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, + {0x16AF0, 0x16AF4}, {0x16B30, 0x16B36}, {0x16F51, 0x16F7E}, + {0x16F8F, 0x16F92}, {0x1BC9D, 0x1BC9E}, {0x1D165, 0x1D169}, + {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, + {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1DA00, 0x1DA36}, + {0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84}, + {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006}, + {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, + {0x1E026, 0x1E02A}, {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E94A}, + {0xE0100, 0xE01EF}, +} + +var doublewidth = table{ + {0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A}, + {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3}, + {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653}, + {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1}, + {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, + {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA}, + {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA}, + {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B}, + {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E}, + {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797}, + {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C}, + {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99}, + {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, + {0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF}, + {0x3105, 0x312D}, {0x3131, 0x318E}, {0x3190, 0x31BA}, + {0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3247}, + {0x3250, 0x32FE}, {0x3300, 0x4DBF}, {0x4E00, 0xA48C}, + {0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3}, + {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52}, + {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, + {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE0}, {0x17000, 0x187EC}, + {0x18800, 0x18AF2}, {0x1B000, 0x1B001}, {0x1F004, 0x1F004}, + {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A}, + {0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, + {0x1F250, 0x1F251}, {0x1F300, 0x1F320}, {0x1F32D, 0x1F335}, + {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA}, + {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4}, + {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440}, {0x1F442, 0x1F4FC}, + {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E}, {0x1F550, 0x1F567}, + {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4}, + {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, + {0x1F6D0, 0x1F6D2}, {0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6F6}, + {0x1F910, 0x1F91E}, {0x1F920, 0x1F927}, {0x1F930, 0x1F930}, + {0x1F933, 0x1F93E}, {0x1F940, 0x1F94B}, {0x1F950, 0x1F95E}, + {0x1F980, 0x1F991}, {0x1F9C0, 0x1F9C0}, {0x20000, 0x2FFFD}, + {0x30000, 0x3FFFD}, +} + +var ambiguous = table{ + {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, + {0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4}, + {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, + {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, + {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, + {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, + {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101}, + {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, + {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, + {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, + {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, + {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, + {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, + {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, + {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, + {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, + {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, + {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F}, + {0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1}, + {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F}, + {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016}, + {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022}, + {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033}, + {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E}, + {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, + {0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105}, + {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116}, + {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B}, + {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B}, + {0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199}, + {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4}, + {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, + {0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F}, + {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A}, + {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225}, + {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237}, + {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C}, + {0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267}, + {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283}, + {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, + {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312}, + {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573}, + {0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1}, + {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, + {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, + {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5}, + {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609}, + {0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E}, + {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661}, + {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D}, + {0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF}, + {0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1}, + {0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1}, + {0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC}, + {0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F}, + {0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF}, + {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A}, + {0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D}, + {0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF}, + {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}, +} + +var emoji = table{ + {0x1F1E6, 0x1F1FF}, {0x1F321, 0x1F321}, {0x1F324, 0x1F32C}, + {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, {0x1F396, 0x1F397}, + {0x1F399, 0x1F39B}, {0x1F39E, 0x1F39F}, {0x1F3CB, 0x1F3CE}, + {0x1F3D4, 0x1F3DF}, {0x1F3F3, 0x1F3F5}, {0x1F3F7, 0x1F3F7}, + {0x1F43F, 0x1F43F}, {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FD}, + {0x1F549, 0x1F54A}, {0x1F56F, 0x1F570}, {0x1F573, 0x1F579}, + {0x1F587, 0x1F587}, {0x1F58A, 0x1F58D}, {0x1F590, 0x1F590}, + {0x1F5A5, 0x1F5A5}, {0x1F5A8, 0x1F5A8}, {0x1F5B1, 0x1F5B2}, + {0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4}, {0x1F5D1, 0x1F5D3}, + {0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1}, {0x1F5E3, 0x1F5E3}, + {0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF}, {0x1F5F3, 0x1F5F3}, + {0x1F5FA, 0x1F5FA}, {0x1F6CB, 0x1F6CF}, {0x1F6E0, 0x1F6E5}, + {0x1F6E9, 0x1F6E9}, {0x1F6F0, 0x1F6F0}, {0x1F6F3, 0x1F6F3}, +} + +var notassigned = table{ + {0x0378, 0x0379}, {0x0380, 0x0383}, {0x038B, 0x038B}, + {0x038D, 0x038D}, {0x03A2, 0x03A2}, {0x0530, 0x0530}, + {0x0557, 0x0558}, {0x0560, 0x0560}, {0x0588, 0x0588}, + {0x058B, 0x058C}, {0x0590, 0x0590}, {0x05C8, 0x05CF}, + {0x05EB, 0x05EF}, {0x05F5, 0x05FF}, {0x061D, 0x061D}, + {0x070E, 0x070E}, {0x074B, 0x074C}, {0x07B2, 0x07BF}, + {0x07FB, 0x07FF}, {0x082E, 0x082F}, {0x083F, 0x083F}, + {0x085C, 0x085D}, {0x085F, 0x089F}, {0x08B5, 0x08B5}, + {0x08BE, 0x08D3}, {0x0984, 0x0984}, {0x098D, 0x098E}, + {0x0991, 0x0992}, {0x09A9, 0x09A9}, {0x09B1, 0x09B1}, + {0x09B3, 0x09B5}, {0x09BA, 0x09BB}, {0x09C5, 0x09C6}, + {0x09C9, 0x09CA}, {0x09CF, 0x09D6}, {0x09D8, 0x09DB}, + {0x09DE, 0x09DE}, {0x09E4, 0x09E5}, {0x09FC, 0x0A00}, + {0x0A04, 0x0A04}, {0x0A0B, 0x0A0E}, {0x0A11, 0x0A12}, + {0x0A29, 0x0A29}, {0x0A31, 0x0A31}, {0x0A34, 0x0A34}, + {0x0A37, 0x0A37}, {0x0A3A, 0x0A3B}, {0x0A3D, 0x0A3D}, + {0x0A43, 0x0A46}, {0x0A49, 0x0A4A}, {0x0A4E, 0x0A50}, + {0x0A52, 0x0A58}, {0x0A5D, 0x0A5D}, {0x0A5F, 0x0A65}, + {0x0A76, 0x0A80}, {0x0A84, 0x0A84}, {0x0A8E, 0x0A8E}, + {0x0A92, 0x0A92}, {0x0AA9, 0x0AA9}, {0x0AB1, 0x0AB1}, + {0x0AB4, 0x0AB4}, {0x0ABA, 0x0ABB}, {0x0AC6, 0x0AC6}, + {0x0ACA, 0x0ACA}, {0x0ACE, 0x0ACF}, {0x0AD1, 0x0ADF}, + {0x0AE4, 0x0AE5}, {0x0AF2, 0x0AF8}, {0x0AFA, 0x0B00}, + {0x0B04, 0x0B04}, {0x0B0D, 0x0B0E}, {0x0B11, 0x0B12}, + {0x0B29, 0x0B29}, {0x0B31, 0x0B31}, {0x0B34, 0x0B34}, + {0x0B3A, 0x0B3B}, {0x0B45, 0x0B46}, {0x0B49, 0x0B4A}, + {0x0B4E, 0x0B55}, {0x0B58, 0x0B5B}, {0x0B5E, 0x0B5E}, + {0x0B64, 0x0B65}, {0x0B78, 0x0B81}, {0x0B84, 0x0B84}, + {0x0B8B, 0x0B8D}, {0x0B91, 0x0B91}, {0x0B96, 0x0B98}, + {0x0B9B, 0x0B9B}, {0x0B9D, 0x0B9D}, {0x0BA0, 0x0BA2}, + {0x0BA5, 0x0BA7}, {0x0BAB, 0x0BAD}, {0x0BBA, 0x0BBD}, + {0x0BC3, 0x0BC5}, {0x0BC9, 0x0BC9}, {0x0BCE, 0x0BCF}, + {0x0BD1, 0x0BD6}, {0x0BD8, 0x0BE5}, {0x0BFB, 0x0BFF}, + {0x0C04, 0x0C04}, {0x0C0D, 0x0C0D}, {0x0C11, 0x0C11}, + {0x0C29, 0x0C29}, {0x0C3A, 0x0C3C}, {0x0C45, 0x0C45}, + {0x0C49, 0x0C49}, {0x0C4E, 0x0C54}, {0x0C57, 0x0C57}, + {0x0C5B, 0x0C5F}, {0x0C64, 0x0C65}, {0x0C70, 0x0C77}, + {0x0C84, 0x0C84}, {0x0C8D, 0x0C8D}, {0x0C91, 0x0C91}, + {0x0CA9, 0x0CA9}, {0x0CB4, 0x0CB4}, {0x0CBA, 0x0CBB}, + {0x0CC5, 0x0CC5}, {0x0CC9, 0x0CC9}, {0x0CCE, 0x0CD4}, + {0x0CD7, 0x0CDD}, {0x0CDF, 0x0CDF}, {0x0CE4, 0x0CE5}, + {0x0CF0, 0x0CF0}, {0x0CF3, 0x0D00}, {0x0D04, 0x0D04}, + {0x0D0D, 0x0D0D}, {0x0D11, 0x0D11}, {0x0D3B, 0x0D3C}, + {0x0D45, 0x0D45}, {0x0D49, 0x0D49}, {0x0D50, 0x0D53}, + {0x0D64, 0x0D65}, {0x0D80, 0x0D81}, {0x0D84, 0x0D84}, + {0x0D97, 0x0D99}, {0x0DB2, 0x0DB2}, {0x0DBC, 0x0DBC}, + {0x0DBE, 0x0DBF}, {0x0DC7, 0x0DC9}, {0x0DCB, 0x0DCE}, + {0x0DD5, 0x0DD5}, {0x0DD7, 0x0DD7}, {0x0DE0, 0x0DE5}, + {0x0DF0, 0x0DF1}, {0x0DF5, 0x0E00}, {0x0E3B, 0x0E3E}, + {0x0E5C, 0x0E80}, {0x0E83, 0x0E83}, {0x0E85, 0x0E86}, + {0x0E89, 0x0E89}, {0x0E8B, 0x0E8C}, {0x0E8E, 0x0E93}, + {0x0E98, 0x0E98}, {0x0EA0, 0x0EA0}, {0x0EA4, 0x0EA4}, + {0x0EA6, 0x0EA6}, {0x0EA8, 0x0EA9}, {0x0EAC, 0x0EAC}, + {0x0EBA, 0x0EBA}, {0x0EBE, 0x0EBF}, {0x0EC5, 0x0EC5}, + {0x0EC7, 0x0EC7}, {0x0ECE, 0x0ECF}, {0x0EDA, 0x0EDB}, + {0x0EE0, 0x0EFF}, {0x0F48, 0x0F48}, {0x0F6D, 0x0F70}, + {0x0F98, 0x0F98}, {0x0FBD, 0x0FBD}, {0x0FCD, 0x0FCD}, + {0x0FDB, 0x0FFF}, {0x10C6, 0x10C6}, {0x10C8, 0x10CC}, + {0x10CE, 0x10CF}, {0x1249, 0x1249}, {0x124E, 0x124F}, + {0x1257, 0x1257}, {0x1259, 0x1259}, {0x125E, 0x125F}, + {0x1289, 0x1289}, {0x128E, 0x128F}, {0x12B1, 0x12B1}, + {0x12B6, 0x12B7}, {0x12BF, 0x12BF}, {0x12C1, 0x12C1}, + {0x12C6, 0x12C7}, {0x12D7, 0x12D7}, {0x1311, 0x1311}, + {0x1316, 0x1317}, {0x135B, 0x135C}, {0x137D, 0x137F}, + {0x139A, 0x139F}, {0x13F6, 0x13F7}, {0x13FE, 0x13FF}, + {0x169D, 0x169F}, {0x16F9, 0x16FF}, {0x170D, 0x170D}, + {0x1715, 0x171F}, {0x1737, 0x173F}, {0x1754, 0x175F}, + {0x176D, 0x176D}, {0x1771, 0x1771}, {0x1774, 0x177F}, + {0x17DE, 0x17DF}, {0x17EA, 0x17EF}, {0x17FA, 0x17FF}, + {0x180F, 0x180F}, {0x181A, 0x181F}, {0x1878, 0x187F}, + {0x18AB, 0x18AF}, {0x18F6, 0x18FF}, {0x191F, 0x191F}, + {0x192C, 0x192F}, {0x193C, 0x193F}, {0x1941, 0x1943}, + {0x196E, 0x196F}, {0x1975, 0x197F}, {0x19AC, 0x19AF}, + {0x19CA, 0x19CF}, {0x19DB, 0x19DD}, {0x1A1C, 0x1A1D}, + {0x1A5F, 0x1A5F}, {0x1A7D, 0x1A7E}, {0x1A8A, 0x1A8F}, + {0x1A9A, 0x1A9F}, {0x1AAE, 0x1AAF}, {0x1ABF, 0x1AFF}, + {0x1B4C, 0x1B4F}, {0x1B7D, 0x1B7F}, {0x1BF4, 0x1BFB}, + {0x1C38, 0x1C3A}, {0x1C4A, 0x1C4C}, {0x1C89, 0x1CBF}, + {0x1CC8, 0x1CCF}, {0x1CF7, 0x1CF7}, {0x1CFA, 0x1CFF}, + {0x1DF6, 0x1DFA}, {0x1F16, 0x1F17}, {0x1F1E, 0x1F1F}, + {0x1F46, 0x1F47}, {0x1F4E, 0x1F4F}, {0x1F58, 0x1F58}, + {0x1F5A, 0x1F5A}, {0x1F5C, 0x1F5C}, {0x1F5E, 0x1F5E}, + {0x1F7E, 0x1F7F}, {0x1FB5, 0x1FB5}, {0x1FC5, 0x1FC5}, + {0x1FD4, 0x1FD5}, {0x1FDC, 0x1FDC}, {0x1FF0, 0x1FF1}, + {0x1FF5, 0x1FF5}, {0x1FFF, 0x1FFF}, {0x2065, 0x2065}, + {0x2072, 0x2073}, {0x208F, 0x208F}, {0x209D, 0x209F}, + {0x20BF, 0x20CF}, {0x20F1, 0x20FF}, {0x218C, 0x218F}, + {0x23FF, 0x23FF}, {0x2427, 0x243F}, {0x244B, 0x245F}, + {0x2B74, 0x2B75}, {0x2B96, 0x2B97}, {0x2BBA, 0x2BBC}, + {0x2BC9, 0x2BC9}, {0x2BD2, 0x2BEB}, {0x2BF0, 0x2BFF}, + {0x2C2F, 0x2C2F}, {0x2C5F, 0x2C5F}, {0x2CF4, 0x2CF8}, + {0x2D26, 0x2D26}, {0x2D28, 0x2D2C}, {0x2D2E, 0x2D2F}, + {0x2D68, 0x2D6E}, {0x2D71, 0x2D7E}, {0x2D97, 0x2D9F}, + {0x2DA7, 0x2DA7}, {0x2DAF, 0x2DAF}, {0x2DB7, 0x2DB7}, + {0x2DBF, 0x2DBF}, {0x2DC7, 0x2DC7}, {0x2DCF, 0x2DCF}, + {0x2DD7, 0x2DD7}, {0x2DDF, 0x2DDF}, {0x2E45, 0x2E7F}, + {0x2E9A, 0x2E9A}, {0x2EF4, 0x2EFF}, {0x2FD6, 0x2FEF}, + {0x2FFC, 0x2FFF}, {0x3040, 0x3040}, {0x3097, 0x3098}, + {0x3100, 0x3104}, {0x312E, 0x3130}, {0x318F, 0x318F}, + {0x31BB, 0x31BF}, {0x31E4, 0x31EF}, {0x321F, 0x321F}, + {0x32FF, 0x32FF}, {0x4DB6, 0x4DBF}, {0x9FD6, 0x9FFF}, + {0xA48D, 0xA48F}, {0xA4C7, 0xA4CF}, {0xA62C, 0xA63F}, + {0xA6F8, 0xA6FF}, {0xA7AF, 0xA7AF}, {0xA7B8, 0xA7F6}, + {0xA82C, 0xA82F}, {0xA83A, 0xA83F}, {0xA878, 0xA87F}, + {0xA8C6, 0xA8CD}, {0xA8DA, 0xA8DF}, {0xA8FE, 0xA8FF}, + {0xA954, 0xA95E}, {0xA97D, 0xA97F}, {0xA9CE, 0xA9CE}, + {0xA9DA, 0xA9DD}, {0xA9FF, 0xA9FF}, {0xAA37, 0xAA3F}, + {0xAA4E, 0xAA4F}, {0xAA5A, 0xAA5B}, {0xAAC3, 0xAADA}, + {0xAAF7, 0xAB00}, {0xAB07, 0xAB08}, {0xAB0F, 0xAB10}, + {0xAB17, 0xAB1F}, {0xAB27, 0xAB27}, {0xAB2F, 0xAB2F}, + {0xAB66, 0xAB6F}, {0xABEE, 0xABEF}, {0xABFA, 0xABFF}, + {0xD7A4, 0xD7AF}, {0xD7C7, 0xD7CA}, {0xD7FC, 0xD7FF}, + {0xFA6E, 0xFA6F}, {0xFADA, 0xFAFF}, {0xFB07, 0xFB12}, + {0xFB18, 0xFB1C}, {0xFB37, 0xFB37}, {0xFB3D, 0xFB3D}, + {0xFB3F, 0xFB3F}, {0xFB42, 0xFB42}, {0xFB45, 0xFB45}, + {0xFBC2, 0xFBD2}, {0xFD40, 0xFD4F}, {0xFD90, 0xFD91}, + {0xFDC8, 0xFDEF}, {0xFDFE, 0xFDFF}, {0xFE1A, 0xFE1F}, + {0xFE53, 0xFE53}, {0xFE67, 0xFE67}, {0xFE6C, 0xFE6F}, + {0xFE75, 0xFE75}, {0xFEFD, 0xFEFE}, {0xFF00, 0xFF00}, + {0xFFBF, 0xFFC1}, {0xFFC8, 0xFFC9}, {0xFFD0, 0xFFD1}, + {0xFFD8, 0xFFD9}, {0xFFDD, 0xFFDF}, {0xFFE7, 0xFFE7}, + {0xFFEF, 0xFFF8}, {0xFFFE, 0xFFFF}, {0x1000C, 0x1000C}, + {0x10027, 0x10027}, {0x1003B, 0x1003B}, {0x1003E, 0x1003E}, + {0x1004E, 0x1004F}, {0x1005E, 0x1007F}, {0x100FB, 0x100FF}, + {0x10103, 0x10106}, {0x10134, 0x10136}, {0x1018F, 0x1018F}, + {0x1019C, 0x1019F}, {0x101A1, 0x101CF}, {0x101FE, 0x1027F}, + {0x1029D, 0x1029F}, {0x102D1, 0x102DF}, {0x102FC, 0x102FF}, + {0x10324, 0x1032F}, {0x1034B, 0x1034F}, {0x1037B, 0x1037F}, + {0x1039E, 0x1039E}, {0x103C4, 0x103C7}, {0x103D6, 0x103FF}, + {0x1049E, 0x1049F}, {0x104AA, 0x104AF}, {0x104D4, 0x104D7}, + {0x104FC, 0x104FF}, {0x10528, 0x1052F}, {0x10564, 0x1056E}, + {0x10570, 0x105FF}, {0x10737, 0x1073F}, {0x10756, 0x1075F}, + {0x10768, 0x107FF}, {0x10806, 0x10807}, {0x10809, 0x10809}, + {0x10836, 0x10836}, {0x10839, 0x1083B}, {0x1083D, 0x1083E}, + {0x10856, 0x10856}, {0x1089F, 0x108A6}, {0x108B0, 0x108DF}, + {0x108F3, 0x108F3}, {0x108F6, 0x108FA}, {0x1091C, 0x1091E}, + {0x1093A, 0x1093E}, {0x10940, 0x1097F}, {0x109B8, 0x109BB}, + {0x109D0, 0x109D1}, {0x10A04, 0x10A04}, {0x10A07, 0x10A0B}, + {0x10A14, 0x10A14}, {0x10A18, 0x10A18}, {0x10A34, 0x10A37}, + {0x10A3B, 0x10A3E}, {0x10A48, 0x10A4F}, {0x10A59, 0x10A5F}, + {0x10AA0, 0x10ABF}, {0x10AE7, 0x10AEA}, {0x10AF7, 0x10AFF}, + {0x10B36, 0x10B38}, {0x10B56, 0x10B57}, {0x10B73, 0x10B77}, + {0x10B92, 0x10B98}, {0x10B9D, 0x10BA8}, {0x10BB0, 0x10BFF}, + {0x10C49, 0x10C7F}, {0x10CB3, 0x10CBF}, {0x10CF3, 0x10CF9}, + {0x10D00, 0x10E5F}, {0x10E7F, 0x10FFF}, {0x1104E, 0x11051}, + {0x11070, 0x1107E}, {0x110C2, 0x110CF}, {0x110E9, 0x110EF}, + {0x110FA, 0x110FF}, {0x11135, 0x11135}, {0x11144, 0x1114F}, + {0x11177, 0x1117F}, {0x111CE, 0x111CF}, {0x111E0, 0x111E0}, + {0x111F5, 0x111FF}, {0x11212, 0x11212}, {0x1123F, 0x1127F}, + {0x11287, 0x11287}, {0x11289, 0x11289}, {0x1128E, 0x1128E}, + {0x1129E, 0x1129E}, {0x112AA, 0x112AF}, {0x112EB, 0x112EF}, + {0x112FA, 0x112FF}, {0x11304, 0x11304}, {0x1130D, 0x1130E}, + {0x11311, 0x11312}, {0x11329, 0x11329}, {0x11331, 0x11331}, + {0x11334, 0x11334}, {0x1133A, 0x1133B}, {0x11345, 0x11346}, + {0x11349, 0x1134A}, {0x1134E, 0x1134F}, {0x11351, 0x11356}, + {0x11358, 0x1135C}, {0x11364, 0x11365}, {0x1136D, 0x1136F}, + {0x11375, 0x113FF}, {0x1145A, 0x1145A}, {0x1145C, 0x1145C}, + {0x1145E, 0x1147F}, {0x114C8, 0x114CF}, {0x114DA, 0x1157F}, + {0x115B6, 0x115B7}, {0x115DE, 0x115FF}, {0x11645, 0x1164F}, + {0x1165A, 0x1165F}, {0x1166D, 0x1167F}, {0x116B8, 0x116BF}, + {0x116CA, 0x116FF}, {0x1171A, 0x1171C}, {0x1172C, 0x1172F}, + {0x11740, 0x1189F}, {0x118F3, 0x118FE}, {0x11900, 0x11ABF}, + {0x11AF9, 0x11BFF}, {0x11C09, 0x11C09}, {0x11C37, 0x11C37}, + {0x11C46, 0x11C4F}, {0x11C6D, 0x11C6F}, {0x11C90, 0x11C91}, + {0x11CA8, 0x11CA8}, {0x11CB7, 0x11FFF}, {0x1239A, 0x123FF}, + {0x1246F, 0x1246F}, {0x12475, 0x1247F}, {0x12544, 0x12FFF}, + {0x1342F, 0x143FF}, {0x14647, 0x167FF}, {0x16A39, 0x16A3F}, + {0x16A5F, 0x16A5F}, {0x16A6A, 0x16A6D}, {0x16A70, 0x16ACF}, + {0x16AEE, 0x16AEF}, {0x16AF6, 0x16AFF}, {0x16B46, 0x16B4F}, + {0x16B5A, 0x16B5A}, {0x16B62, 0x16B62}, {0x16B78, 0x16B7C}, + {0x16B90, 0x16EFF}, {0x16F45, 0x16F4F}, {0x16F7F, 0x16F8E}, + {0x16FA0, 0x16FDF}, {0x16FE1, 0x16FFF}, {0x187ED, 0x187FF}, + {0x18AF3, 0x1AFFF}, {0x1B002, 0x1BBFF}, {0x1BC6B, 0x1BC6F}, + {0x1BC7D, 0x1BC7F}, {0x1BC89, 0x1BC8F}, {0x1BC9A, 0x1BC9B}, + {0x1BCA4, 0x1CFFF}, {0x1D0F6, 0x1D0FF}, {0x1D127, 0x1D128}, + {0x1D1E9, 0x1D1FF}, {0x1D246, 0x1D2FF}, {0x1D357, 0x1D35F}, + {0x1D372, 0x1D3FF}, {0x1D455, 0x1D455}, {0x1D49D, 0x1D49D}, + {0x1D4A0, 0x1D4A1}, {0x1D4A3, 0x1D4A4}, {0x1D4A7, 0x1D4A8}, + {0x1D4AD, 0x1D4AD}, {0x1D4BA, 0x1D4BA}, {0x1D4BC, 0x1D4BC}, + {0x1D4C4, 0x1D4C4}, {0x1D506, 0x1D506}, {0x1D50B, 0x1D50C}, + {0x1D515, 0x1D515}, {0x1D51D, 0x1D51D}, {0x1D53A, 0x1D53A}, + {0x1D53F, 0x1D53F}, {0x1D545, 0x1D545}, {0x1D547, 0x1D549}, + {0x1D551, 0x1D551}, {0x1D6A6, 0x1D6A7}, {0x1D7CC, 0x1D7CD}, + {0x1DA8C, 0x1DA9A}, {0x1DAA0, 0x1DAA0}, {0x1DAB0, 0x1DFFF}, + {0x1E007, 0x1E007}, {0x1E019, 0x1E01A}, {0x1E022, 0x1E022}, + {0x1E025, 0x1E025}, {0x1E02B, 0x1E7FF}, {0x1E8C5, 0x1E8C6}, + {0x1E8D7, 0x1E8FF}, {0x1E94B, 0x1E94F}, {0x1E95A, 0x1E95D}, + {0x1E960, 0x1EDFF}, {0x1EE04, 0x1EE04}, {0x1EE20, 0x1EE20}, + {0x1EE23, 0x1EE23}, {0x1EE25, 0x1EE26}, {0x1EE28, 0x1EE28}, + {0x1EE33, 0x1EE33}, {0x1EE38, 0x1EE38}, {0x1EE3A, 0x1EE3A}, + {0x1EE3C, 0x1EE41}, {0x1EE43, 0x1EE46}, {0x1EE48, 0x1EE48}, + {0x1EE4A, 0x1EE4A}, {0x1EE4C, 0x1EE4C}, {0x1EE50, 0x1EE50}, + {0x1EE53, 0x1EE53}, {0x1EE55, 0x1EE56}, {0x1EE58, 0x1EE58}, + {0x1EE5A, 0x1EE5A}, {0x1EE5C, 0x1EE5C}, {0x1EE5E, 0x1EE5E}, + {0x1EE60, 0x1EE60}, {0x1EE63, 0x1EE63}, {0x1EE65, 0x1EE66}, + {0x1EE6B, 0x1EE6B}, {0x1EE73, 0x1EE73}, {0x1EE78, 0x1EE78}, + {0x1EE7D, 0x1EE7D}, {0x1EE7F, 0x1EE7F}, {0x1EE8A, 0x1EE8A}, + {0x1EE9C, 0x1EEA0}, {0x1EEA4, 0x1EEA4}, {0x1EEAA, 0x1EEAA}, + {0x1EEBC, 0x1EEEF}, {0x1EEF2, 0x1EFFF}, {0x1F02C, 0x1F02F}, + {0x1F094, 0x1F09F}, {0x1F0AF, 0x1F0B0}, {0x1F0C0, 0x1F0C0}, + {0x1F0D0, 0x1F0D0}, {0x1F0F6, 0x1F0FF}, {0x1F10D, 0x1F10F}, + {0x1F12F, 0x1F12F}, {0x1F16C, 0x1F16F}, {0x1F1AD, 0x1F1E5}, + {0x1F203, 0x1F20F}, {0x1F23C, 0x1F23F}, {0x1F249, 0x1F24F}, + {0x1F252, 0x1F2FF}, {0x1F6D3, 0x1F6DF}, {0x1F6ED, 0x1F6EF}, + {0x1F6F7, 0x1F6FF}, {0x1F774, 0x1F77F}, {0x1F7D5, 0x1F7FF}, + {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, {0x1F85A, 0x1F85F}, + {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F90F}, {0x1F91F, 0x1F91F}, + {0x1F928, 0x1F92F}, {0x1F931, 0x1F932}, {0x1F93F, 0x1F93F}, + {0x1F94C, 0x1F94F}, {0x1F95F, 0x1F97F}, {0x1F992, 0x1F9BF}, + {0x1F9C1, 0x1FFFF}, {0x2A6D7, 0x2A6FF}, {0x2B735, 0x2B73F}, + {0x2B81E, 0x2B81F}, {0x2CEA2, 0x2F7FF}, {0x2FA1E, 0xE0000}, + {0xE0002, 0xE001F}, {0xE0080, 0xE00FF}, {0xE01F0, 0xEFFFF}, + {0xFFFFE, 0xFFFFF}, +} + +var neutral = table{ + {0x0000, 0x001F}, {0x007F, 0x007F}, {0x0080, 0x009F}, + {0x00A0, 0x00A0}, {0x00A9, 0x00A9}, {0x00AB, 0x00AB}, + {0x00B5, 0x00B5}, {0x00BB, 0x00BB}, {0x00C0, 0x00C5}, + {0x00C7, 0x00CF}, {0x00D1, 0x00D6}, {0x00D9, 0x00DD}, + {0x00E2, 0x00E5}, {0x00E7, 0x00E7}, {0x00EB, 0x00EB}, + {0x00EE, 0x00EF}, {0x00F1, 0x00F1}, {0x00F4, 0x00F6}, + {0x00FB, 0x00FB}, {0x00FD, 0x00FD}, {0x00FF, 0x00FF}, + {0x0100, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112}, + {0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A}, + {0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E}, + {0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C}, + {0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A}, + {0x016C, 0x017F}, {0x0180, 0x01BA}, {0x01BB, 0x01BB}, + {0x01BC, 0x01BF}, {0x01C0, 0x01C3}, {0x01C4, 0x01CD}, + {0x01CF, 0x01CF}, {0x01D1, 0x01D1}, {0x01D3, 0x01D3}, + {0x01D5, 0x01D5}, {0x01D7, 0x01D7}, {0x01D9, 0x01D9}, + {0x01DB, 0x01DB}, {0x01DD, 0x024F}, {0x0250, 0x0250}, + {0x0252, 0x0260}, {0x0262, 0x0293}, {0x0294, 0x0294}, + {0x0295, 0x02AF}, {0x02B0, 0x02C1}, {0x02C2, 0x02C3}, + {0x02C5, 0x02C5}, {0x02C6, 0x02C6}, {0x02C8, 0x02C8}, + {0x02CC, 0x02CC}, {0x02CE, 0x02CF}, {0x02D1, 0x02D1}, + {0x02D2, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE}, + {0x02E0, 0x02E4}, {0x02E5, 0x02EB}, {0x02EC, 0x02EC}, + {0x02ED, 0x02ED}, {0x02EE, 0x02EE}, {0x02EF, 0x02FF}, + {0x0370, 0x0373}, {0x0374, 0x0374}, {0x0375, 0x0375}, + {0x0376, 0x0377}, {0x037A, 0x037A}, {0x037B, 0x037D}, + {0x037E, 0x037E}, {0x037F, 0x037F}, {0x0384, 0x0385}, + {0x0386, 0x0386}, {0x0387, 0x0387}, {0x0388, 0x038A}, + {0x038C, 0x038C}, {0x038E, 0x0390}, {0x03AA, 0x03B0}, + {0x03C2, 0x03C2}, {0x03CA, 0x03F5}, {0x03F6, 0x03F6}, + {0x03F7, 0x03FF}, {0x0400, 0x0400}, {0x0402, 0x040F}, + {0x0450, 0x0450}, {0x0452, 0x0481}, {0x0482, 0x0482}, + {0x0483, 0x0487}, {0x0488, 0x0489}, {0x048A, 0x04FF}, + {0x0500, 0x052F}, {0x0531, 0x0556}, {0x0559, 0x0559}, + {0x055A, 0x055F}, {0x0561, 0x0587}, {0x0589, 0x0589}, + {0x058A, 0x058A}, {0x058D, 0x058E}, {0x058F, 0x058F}, + {0x0591, 0x05BD}, {0x05BE, 0x05BE}, {0x05BF, 0x05BF}, + {0x05C0, 0x05C0}, {0x05C1, 0x05C2}, {0x05C3, 0x05C3}, + {0x05C4, 0x05C5}, {0x05C6, 0x05C6}, {0x05C7, 0x05C7}, + {0x05D0, 0x05EA}, {0x05F0, 0x05F2}, {0x05F3, 0x05F4}, + {0x0600, 0x0605}, {0x0606, 0x0608}, {0x0609, 0x060A}, + {0x060B, 0x060B}, {0x060C, 0x060D}, {0x060E, 0x060F}, + {0x0610, 0x061A}, {0x061B, 0x061B}, {0x061C, 0x061C}, + {0x061E, 0x061F}, {0x0620, 0x063F}, {0x0640, 0x0640}, + {0x0641, 0x064A}, {0x064B, 0x065F}, {0x0660, 0x0669}, + {0x066A, 0x066D}, {0x066E, 0x066F}, {0x0670, 0x0670}, + {0x0671, 0x06D3}, {0x06D4, 0x06D4}, {0x06D5, 0x06D5}, + {0x06D6, 0x06DC}, {0x06DD, 0x06DD}, {0x06DE, 0x06DE}, + {0x06DF, 0x06E4}, {0x06E5, 0x06E6}, {0x06E7, 0x06E8}, + {0x06E9, 0x06E9}, {0x06EA, 0x06ED}, {0x06EE, 0x06EF}, + {0x06F0, 0x06F9}, {0x06FA, 0x06FC}, {0x06FD, 0x06FE}, + {0x06FF, 0x06FF}, {0x0700, 0x070D}, {0x070F, 0x070F}, + {0x0710, 0x0710}, {0x0711, 0x0711}, {0x0712, 0x072F}, + {0x0730, 0x074A}, {0x074D, 0x074F}, {0x0750, 0x077F}, + {0x0780, 0x07A5}, {0x07A6, 0x07B0}, {0x07B1, 0x07B1}, + {0x07C0, 0x07C9}, {0x07CA, 0x07EA}, {0x07EB, 0x07F3}, + {0x07F4, 0x07F5}, {0x07F6, 0x07F6}, {0x07F7, 0x07F9}, + {0x07FA, 0x07FA}, {0x0800, 0x0815}, {0x0816, 0x0819}, + {0x081A, 0x081A}, {0x081B, 0x0823}, {0x0824, 0x0824}, + {0x0825, 0x0827}, {0x0828, 0x0828}, {0x0829, 0x082D}, + {0x0830, 0x083E}, {0x0840, 0x0858}, {0x0859, 0x085B}, + {0x085E, 0x085E}, {0x08A0, 0x08B4}, {0x08B6, 0x08BD}, + {0x08D4, 0x08E1}, {0x08E2, 0x08E2}, {0x08E3, 0x08FF}, + {0x0900, 0x0902}, {0x0903, 0x0903}, {0x0904, 0x0939}, + {0x093A, 0x093A}, {0x093B, 0x093B}, {0x093C, 0x093C}, + {0x093D, 0x093D}, {0x093E, 0x0940}, {0x0941, 0x0948}, + {0x0949, 0x094C}, {0x094D, 0x094D}, {0x094E, 0x094F}, + {0x0950, 0x0950}, {0x0951, 0x0957}, {0x0958, 0x0961}, + {0x0962, 0x0963}, {0x0964, 0x0965}, {0x0966, 0x096F}, + {0x0970, 0x0970}, {0x0971, 0x0971}, {0x0972, 0x097F}, + {0x0980, 0x0980}, {0x0981, 0x0981}, {0x0982, 0x0983}, + {0x0985, 0x098C}, {0x098F, 0x0990}, {0x0993, 0x09A8}, + {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9}, + {0x09BC, 0x09BC}, {0x09BD, 0x09BD}, {0x09BE, 0x09C0}, + {0x09C1, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CC}, + {0x09CD, 0x09CD}, {0x09CE, 0x09CE}, {0x09D7, 0x09D7}, + {0x09DC, 0x09DD}, {0x09DF, 0x09E1}, {0x09E2, 0x09E3}, + {0x09E6, 0x09EF}, {0x09F0, 0x09F1}, {0x09F2, 0x09F3}, + {0x09F4, 0x09F9}, {0x09FA, 0x09FA}, {0x09FB, 0x09FB}, + {0x0A01, 0x0A02}, {0x0A03, 0x0A03}, {0x0A05, 0x0A0A}, + {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, + {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, + {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A40}, {0x0A41, 0x0A42}, + {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, + {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A6F}, + {0x0A70, 0x0A71}, {0x0A72, 0x0A74}, {0x0A75, 0x0A75}, + {0x0A81, 0x0A82}, {0x0A83, 0x0A83}, {0x0A85, 0x0A8D}, + {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, + {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABC, 0x0ABC}, + {0x0ABD, 0x0ABD}, {0x0ABE, 0x0AC0}, {0x0AC1, 0x0AC5}, + {0x0AC7, 0x0AC8}, {0x0AC9, 0x0AC9}, {0x0ACB, 0x0ACC}, + {0x0ACD, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE1}, + {0x0AE2, 0x0AE3}, {0x0AE6, 0x0AEF}, {0x0AF0, 0x0AF0}, + {0x0AF1, 0x0AF1}, {0x0AF9, 0x0AF9}, {0x0B01, 0x0B01}, + {0x0B02, 0x0B03}, {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, + {0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, + {0x0B35, 0x0B39}, {0x0B3C, 0x0B3C}, {0x0B3D, 0x0B3D}, + {0x0B3E, 0x0B3E}, {0x0B3F, 0x0B3F}, {0x0B40, 0x0B40}, + {0x0B41, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4C}, + {0x0B4D, 0x0B4D}, {0x0B56, 0x0B56}, {0x0B57, 0x0B57}, + {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61}, {0x0B62, 0x0B63}, + {0x0B66, 0x0B6F}, {0x0B70, 0x0B70}, {0x0B71, 0x0B71}, + {0x0B72, 0x0B77}, {0x0B82, 0x0B82}, {0x0B83, 0x0B83}, + {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, + {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F}, + {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9}, + {0x0BBE, 0x0BBF}, {0x0BC0, 0x0BC0}, {0x0BC1, 0x0BC2}, + {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCC}, {0x0BCD, 0x0BCD}, + {0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BEF}, + {0x0BF0, 0x0BF2}, {0x0BF3, 0x0BF8}, {0x0BF9, 0x0BF9}, + {0x0BFA, 0x0BFA}, {0x0C00, 0x0C00}, {0x0C01, 0x0C03}, + {0x0C05, 0x0C0C}, {0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, + {0x0C2A, 0x0C39}, {0x0C3D, 0x0C3D}, {0x0C3E, 0x0C40}, + {0x0C41, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, + {0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C61}, + {0x0C62, 0x0C63}, {0x0C66, 0x0C6F}, {0x0C78, 0x0C7E}, + {0x0C7F, 0x0C7F}, {0x0C80, 0x0C80}, {0x0C81, 0x0C81}, + {0x0C82, 0x0C83}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90}, + {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, + {0x0CBC, 0x0CBC}, {0x0CBD, 0x0CBD}, {0x0CBE, 0x0CBE}, + {0x0CBF, 0x0CBF}, {0x0CC0, 0x0CC4}, {0x0CC6, 0x0CC6}, + {0x0CC7, 0x0CC8}, {0x0CCA, 0x0CCB}, {0x0CCC, 0x0CCD}, + {0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE1}, + {0x0CE2, 0x0CE3}, {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, + {0x0D01, 0x0D01}, {0x0D02, 0x0D03}, {0x0D05, 0x0D0C}, + {0x0D0E, 0x0D10}, {0x0D12, 0x0D3A}, {0x0D3D, 0x0D3D}, + {0x0D3E, 0x0D40}, {0x0D41, 0x0D44}, {0x0D46, 0x0D48}, + {0x0D4A, 0x0D4C}, {0x0D4D, 0x0D4D}, {0x0D4E, 0x0D4E}, + {0x0D4F, 0x0D4F}, {0x0D54, 0x0D56}, {0x0D57, 0x0D57}, + {0x0D58, 0x0D5E}, {0x0D5F, 0x0D61}, {0x0D62, 0x0D63}, + {0x0D66, 0x0D6F}, {0x0D70, 0x0D78}, {0x0D79, 0x0D79}, + {0x0D7A, 0x0D7F}, {0x0D82, 0x0D83}, {0x0D85, 0x0D96}, + {0x0D9A, 0x0DB1}, {0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, + {0x0DC0, 0x0DC6}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD1}, + {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, + {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF3}, {0x0DF4, 0x0DF4}, + {0x0E01, 0x0E30}, {0x0E31, 0x0E31}, {0x0E32, 0x0E33}, + {0x0E34, 0x0E3A}, {0x0E3F, 0x0E3F}, {0x0E40, 0x0E45}, + {0x0E46, 0x0E46}, {0x0E47, 0x0E4E}, {0x0E4F, 0x0E4F}, + {0x0E50, 0x0E59}, {0x0E5A, 0x0E5B}, {0x0E81, 0x0E82}, + {0x0E84, 0x0E84}, {0x0E87, 0x0E88}, {0x0E8A, 0x0E8A}, + {0x0E8D, 0x0E8D}, {0x0E94, 0x0E97}, {0x0E99, 0x0E9F}, + {0x0EA1, 0x0EA3}, {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EA7}, + {0x0EAA, 0x0EAB}, {0x0EAD, 0x0EB0}, {0x0EB1, 0x0EB1}, + {0x0EB2, 0x0EB3}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, + {0x0EBD, 0x0EBD}, {0x0EC0, 0x0EC4}, {0x0EC6, 0x0EC6}, + {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9}, {0x0EDC, 0x0EDF}, + {0x0F00, 0x0F00}, {0x0F01, 0x0F03}, {0x0F04, 0x0F12}, + {0x0F13, 0x0F13}, {0x0F14, 0x0F14}, {0x0F15, 0x0F17}, + {0x0F18, 0x0F19}, {0x0F1A, 0x0F1F}, {0x0F20, 0x0F29}, + {0x0F2A, 0x0F33}, {0x0F34, 0x0F34}, {0x0F35, 0x0F35}, + {0x0F36, 0x0F36}, {0x0F37, 0x0F37}, {0x0F38, 0x0F38}, + {0x0F39, 0x0F39}, {0x0F3A, 0x0F3A}, {0x0F3B, 0x0F3B}, + {0x0F3C, 0x0F3C}, {0x0F3D, 0x0F3D}, {0x0F3E, 0x0F3F}, + {0x0F40, 0x0F47}, {0x0F49, 0x0F6C}, {0x0F71, 0x0F7E}, + {0x0F7F, 0x0F7F}, {0x0F80, 0x0F84}, {0x0F85, 0x0F85}, + {0x0F86, 0x0F87}, {0x0F88, 0x0F8C}, {0x0F8D, 0x0F97}, + {0x0F99, 0x0FBC}, {0x0FBE, 0x0FC5}, {0x0FC6, 0x0FC6}, + {0x0FC7, 0x0FCC}, {0x0FCE, 0x0FCF}, {0x0FD0, 0x0FD4}, + {0x0FD5, 0x0FD8}, {0x0FD9, 0x0FDA}, {0x1000, 0x102A}, + {0x102B, 0x102C}, {0x102D, 0x1030}, {0x1031, 0x1031}, + {0x1032, 0x1037}, {0x1038, 0x1038}, {0x1039, 0x103A}, + {0x103B, 0x103C}, {0x103D, 0x103E}, {0x103F, 0x103F}, + {0x1040, 0x1049}, {0x104A, 0x104F}, {0x1050, 0x1055}, + {0x1056, 0x1057}, {0x1058, 0x1059}, {0x105A, 0x105D}, + {0x105E, 0x1060}, {0x1061, 0x1061}, {0x1062, 0x1064}, + {0x1065, 0x1066}, {0x1067, 0x106D}, {0x106E, 0x1070}, + {0x1071, 0x1074}, {0x1075, 0x1081}, {0x1082, 0x1082}, + {0x1083, 0x1084}, {0x1085, 0x1086}, {0x1087, 0x108C}, + {0x108D, 0x108D}, {0x108E, 0x108E}, {0x108F, 0x108F}, + {0x1090, 0x1099}, {0x109A, 0x109C}, {0x109D, 0x109D}, + {0x109E, 0x109F}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, + {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FB, 0x10FB}, + {0x10FC, 0x10FC}, {0x10FD, 0x10FF}, {0x1160, 0x11FF}, + {0x1200, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, + {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, + {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, + {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, + {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, + {0x1318, 0x135A}, {0x135D, 0x135F}, {0x1360, 0x1368}, + {0x1369, 0x137C}, {0x1380, 0x138F}, {0x1390, 0x1399}, + {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1400, 0x1400}, + {0x1401, 0x166C}, {0x166D, 0x166E}, {0x166F, 0x167F}, + {0x1680, 0x1680}, {0x1681, 0x169A}, {0x169B, 0x169B}, + {0x169C, 0x169C}, {0x16A0, 0x16EA}, {0x16EB, 0x16ED}, + {0x16EE, 0x16F0}, {0x16F1, 0x16F8}, {0x1700, 0x170C}, + {0x170E, 0x1711}, {0x1712, 0x1714}, {0x1720, 0x1731}, + {0x1732, 0x1734}, {0x1735, 0x1736}, {0x1740, 0x1751}, + {0x1752, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770}, + {0x1772, 0x1773}, {0x1780, 0x17B3}, {0x17B4, 0x17B5}, + {0x17B6, 0x17B6}, {0x17B7, 0x17BD}, {0x17BE, 0x17C5}, + {0x17C6, 0x17C6}, {0x17C7, 0x17C8}, {0x17C9, 0x17D3}, + {0x17D4, 0x17D6}, {0x17D7, 0x17D7}, {0x17D8, 0x17DA}, + {0x17DB, 0x17DB}, {0x17DC, 0x17DC}, {0x17DD, 0x17DD}, + {0x17E0, 0x17E9}, {0x17F0, 0x17F9}, {0x1800, 0x1805}, + {0x1806, 0x1806}, {0x1807, 0x180A}, {0x180B, 0x180D}, + {0x180E, 0x180E}, {0x1810, 0x1819}, {0x1820, 0x1842}, + {0x1843, 0x1843}, {0x1844, 0x1877}, {0x1880, 0x1884}, + {0x1885, 0x1886}, {0x1887, 0x18A8}, {0x18A9, 0x18A9}, + {0x18AA, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E}, + {0x1920, 0x1922}, {0x1923, 0x1926}, {0x1927, 0x1928}, + {0x1929, 0x192B}, {0x1930, 0x1931}, {0x1932, 0x1932}, + {0x1933, 0x1938}, {0x1939, 0x193B}, {0x1940, 0x1940}, + {0x1944, 0x1945}, {0x1946, 0x194F}, {0x1950, 0x196D}, + {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, + {0x19D0, 0x19D9}, {0x19DA, 0x19DA}, {0x19DE, 0x19DF}, + {0x19E0, 0x19FF}, {0x1A00, 0x1A16}, {0x1A17, 0x1A18}, + {0x1A19, 0x1A1A}, {0x1A1B, 0x1A1B}, {0x1A1E, 0x1A1F}, + {0x1A20, 0x1A54}, {0x1A55, 0x1A55}, {0x1A56, 0x1A56}, + {0x1A57, 0x1A57}, {0x1A58, 0x1A5E}, {0x1A60, 0x1A60}, + {0x1A61, 0x1A61}, {0x1A62, 0x1A62}, {0x1A63, 0x1A64}, + {0x1A65, 0x1A6C}, {0x1A6D, 0x1A72}, {0x1A73, 0x1A7C}, + {0x1A7F, 0x1A7F}, {0x1A80, 0x1A89}, {0x1A90, 0x1A99}, + {0x1AA0, 0x1AA6}, {0x1AA7, 0x1AA7}, {0x1AA8, 0x1AAD}, + {0x1AB0, 0x1ABD}, {0x1ABE, 0x1ABE}, {0x1B00, 0x1B03}, + {0x1B04, 0x1B04}, {0x1B05, 0x1B33}, {0x1B34, 0x1B34}, + {0x1B35, 0x1B35}, {0x1B36, 0x1B3A}, {0x1B3B, 0x1B3B}, + {0x1B3C, 0x1B3C}, {0x1B3D, 0x1B41}, {0x1B42, 0x1B42}, + {0x1B43, 0x1B44}, {0x1B45, 0x1B4B}, {0x1B50, 0x1B59}, + {0x1B5A, 0x1B60}, {0x1B61, 0x1B6A}, {0x1B6B, 0x1B73}, + {0x1B74, 0x1B7C}, {0x1B80, 0x1B81}, {0x1B82, 0x1B82}, + {0x1B83, 0x1BA0}, {0x1BA1, 0x1BA1}, {0x1BA2, 0x1BA5}, + {0x1BA6, 0x1BA7}, {0x1BA8, 0x1BA9}, {0x1BAA, 0x1BAA}, + {0x1BAB, 0x1BAD}, {0x1BAE, 0x1BAF}, {0x1BB0, 0x1BB9}, + {0x1BBA, 0x1BBF}, {0x1BC0, 0x1BE5}, {0x1BE6, 0x1BE6}, + {0x1BE7, 0x1BE7}, {0x1BE8, 0x1BE9}, {0x1BEA, 0x1BEC}, + {0x1BED, 0x1BED}, {0x1BEE, 0x1BEE}, {0x1BEF, 0x1BF1}, + {0x1BF2, 0x1BF3}, {0x1BFC, 0x1BFF}, {0x1C00, 0x1C23}, + {0x1C24, 0x1C2B}, {0x1C2C, 0x1C33}, {0x1C34, 0x1C35}, + {0x1C36, 0x1C37}, {0x1C3B, 0x1C3F}, {0x1C40, 0x1C49}, + {0x1C4D, 0x1C4F}, {0x1C50, 0x1C59}, {0x1C5A, 0x1C77}, + {0x1C78, 0x1C7D}, {0x1C7E, 0x1C7F}, {0x1C80, 0x1C88}, + {0x1CC0, 0x1CC7}, {0x1CD0, 0x1CD2}, {0x1CD3, 0x1CD3}, + {0x1CD4, 0x1CE0}, {0x1CE1, 0x1CE1}, {0x1CE2, 0x1CE8}, + {0x1CE9, 0x1CEC}, {0x1CED, 0x1CED}, {0x1CEE, 0x1CF1}, + {0x1CF2, 0x1CF3}, {0x1CF4, 0x1CF4}, {0x1CF5, 0x1CF6}, + {0x1CF8, 0x1CF9}, {0x1D00, 0x1D2B}, {0x1D2C, 0x1D6A}, + {0x1D6B, 0x1D77}, {0x1D78, 0x1D78}, {0x1D79, 0x1D7F}, + {0x1D80, 0x1D9A}, {0x1D9B, 0x1DBF}, {0x1DC0, 0x1DF5}, + {0x1DFB, 0x1DFF}, {0x1E00, 0x1EFF}, {0x1F00, 0x1F15}, + {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, + {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, + {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, + {0x1FB6, 0x1FBC}, {0x1FBD, 0x1FBD}, {0x1FBE, 0x1FBE}, + {0x1FBF, 0x1FC1}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, + {0x1FCD, 0x1FCF}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, + {0x1FDD, 0x1FDF}, {0x1FE0, 0x1FEC}, {0x1FED, 0x1FEF}, + {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x1FFD, 0x1FFE}, + {0x2000, 0x200A}, {0x200B, 0x200F}, {0x2011, 0x2012}, + {0x2017, 0x2017}, {0x201A, 0x201A}, {0x201B, 0x201B}, + {0x201E, 0x201E}, {0x201F, 0x201F}, {0x2023, 0x2023}, + {0x2028, 0x2028}, {0x2029, 0x2029}, {0x202A, 0x202E}, + {0x202F, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034}, + {0x2036, 0x2038}, {0x2039, 0x2039}, {0x203A, 0x203A}, + {0x203C, 0x203D}, {0x203F, 0x2040}, {0x2041, 0x2043}, + {0x2044, 0x2044}, {0x2045, 0x2045}, {0x2046, 0x2046}, + {0x2047, 0x2051}, {0x2052, 0x2052}, {0x2053, 0x2053}, + {0x2054, 0x2054}, {0x2055, 0x205E}, {0x205F, 0x205F}, + {0x2060, 0x2064}, {0x2066, 0x206F}, {0x2070, 0x2070}, + {0x2071, 0x2071}, {0x2075, 0x2079}, {0x207A, 0x207C}, + {0x207D, 0x207D}, {0x207E, 0x207E}, {0x2080, 0x2080}, + {0x2085, 0x2089}, {0x208A, 0x208C}, {0x208D, 0x208D}, + {0x208E, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8}, + {0x20AA, 0x20AB}, {0x20AD, 0x20BE}, {0x20D0, 0x20DC}, + {0x20DD, 0x20E0}, {0x20E1, 0x20E1}, {0x20E2, 0x20E4}, + {0x20E5, 0x20F0}, {0x2100, 0x2101}, {0x2102, 0x2102}, + {0x2104, 0x2104}, {0x2106, 0x2106}, {0x2107, 0x2107}, + {0x2108, 0x2108}, {0x210A, 0x2112}, {0x2114, 0x2114}, + {0x2115, 0x2115}, {0x2117, 0x2117}, {0x2118, 0x2118}, + {0x2119, 0x211D}, {0x211E, 0x2120}, {0x2123, 0x2123}, + {0x2124, 0x2124}, {0x2125, 0x2125}, {0x2127, 0x2127}, + {0x2128, 0x2128}, {0x2129, 0x2129}, {0x212A, 0x212A}, + {0x212C, 0x212D}, {0x212E, 0x212E}, {0x212F, 0x2134}, + {0x2135, 0x2138}, {0x2139, 0x2139}, {0x213A, 0x213B}, + {0x213C, 0x213F}, {0x2140, 0x2144}, {0x2145, 0x2149}, + {0x214A, 0x214A}, {0x214B, 0x214B}, {0x214C, 0x214D}, + {0x214E, 0x214E}, {0x214F, 0x214F}, {0x2150, 0x2152}, + {0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F}, + {0x217A, 0x2182}, {0x2183, 0x2184}, {0x2185, 0x2188}, + {0x218A, 0x218B}, {0x219A, 0x219B}, {0x219C, 0x219F}, + {0x21A0, 0x21A0}, {0x21A1, 0x21A2}, {0x21A3, 0x21A3}, + {0x21A4, 0x21A5}, {0x21A6, 0x21A6}, {0x21A7, 0x21AD}, + {0x21AE, 0x21AE}, {0x21AF, 0x21B7}, {0x21BA, 0x21CD}, + {0x21CE, 0x21CF}, {0x21D0, 0x21D1}, {0x21D3, 0x21D3}, + {0x21D5, 0x21E6}, {0x21E8, 0x21F3}, {0x21F4, 0x21FF}, + {0x2201, 0x2201}, {0x2204, 0x2206}, {0x2209, 0x220A}, + {0x220C, 0x220E}, {0x2210, 0x2210}, {0x2212, 0x2214}, + {0x2216, 0x2219}, {0x221B, 0x221C}, {0x2221, 0x2222}, + {0x2224, 0x2224}, {0x2226, 0x2226}, {0x222D, 0x222D}, + {0x222F, 0x2233}, {0x2238, 0x223B}, {0x223E, 0x2247}, + {0x2249, 0x224B}, {0x224D, 0x2251}, {0x2253, 0x225F}, + {0x2262, 0x2263}, {0x2268, 0x2269}, {0x226C, 0x226D}, + {0x2270, 0x2281}, {0x2284, 0x2285}, {0x2288, 0x2294}, + {0x2296, 0x2298}, {0x229A, 0x22A4}, {0x22A6, 0x22BE}, + {0x22C0, 0x22FF}, {0x2300, 0x2307}, {0x2308, 0x2308}, + {0x2309, 0x2309}, {0x230A, 0x230A}, {0x230B, 0x230B}, + {0x230C, 0x2311}, {0x2313, 0x2319}, {0x231C, 0x231F}, + {0x2320, 0x2321}, {0x2322, 0x2328}, {0x232B, 0x237B}, + {0x237C, 0x237C}, {0x237D, 0x239A}, {0x239B, 0x23B3}, + {0x23B4, 0x23DB}, {0x23DC, 0x23E1}, {0x23E2, 0x23E8}, + {0x23ED, 0x23EF}, {0x23F1, 0x23F2}, {0x23F4, 0x23FE}, + {0x2400, 0x2426}, {0x2440, 0x244A}, {0x24EA, 0x24EA}, + {0x254C, 0x254F}, {0x2574, 0x257F}, {0x2590, 0x2591}, + {0x2596, 0x259F}, {0x25A2, 0x25A2}, {0x25AA, 0x25B1}, + {0x25B4, 0x25B5}, {0x25B8, 0x25BB}, {0x25BE, 0x25BF}, + {0x25C2, 0x25C5}, {0x25C9, 0x25CA}, {0x25CC, 0x25CD}, + {0x25D2, 0x25E1}, {0x25E6, 0x25EE}, {0x25F0, 0x25F7}, + {0x25F8, 0x25FC}, {0x25FF, 0x25FF}, {0x2600, 0x2604}, + {0x2607, 0x2608}, {0x260A, 0x260D}, {0x2610, 0x2613}, + {0x2616, 0x261B}, {0x261D, 0x261D}, {0x261F, 0x263F}, + {0x2641, 0x2641}, {0x2643, 0x2647}, {0x2654, 0x265F}, + {0x2662, 0x2662}, {0x2666, 0x2666}, {0x266B, 0x266B}, + {0x266E, 0x266E}, {0x2670, 0x267E}, {0x2680, 0x2692}, + {0x2694, 0x269D}, {0x26A0, 0x26A0}, {0x26A2, 0x26A9}, + {0x26AC, 0x26BC}, {0x26C0, 0x26C3}, {0x26E2, 0x26E2}, + {0x26E4, 0x26E7}, {0x2700, 0x2704}, {0x2706, 0x2709}, + {0x270C, 0x2727}, {0x2729, 0x273C}, {0x273E, 0x274B}, + {0x274D, 0x274D}, {0x274F, 0x2752}, {0x2756, 0x2756}, + {0x2758, 0x2767}, {0x2768, 0x2768}, {0x2769, 0x2769}, + {0x276A, 0x276A}, {0x276B, 0x276B}, {0x276C, 0x276C}, + {0x276D, 0x276D}, {0x276E, 0x276E}, {0x276F, 0x276F}, + {0x2770, 0x2770}, {0x2771, 0x2771}, {0x2772, 0x2772}, + {0x2773, 0x2773}, {0x2774, 0x2774}, {0x2775, 0x2775}, + {0x2780, 0x2793}, {0x2794, 0x2794}, {0x2798, 0x27AF}, + {0x27B1, 0x27BE}, {0x27C0, 0x27C4}, {0x27C5, 0x27C5}, + {0x27C6, 0x27C6}, {0x27C7, 0x27E5}, {0x27EE, 0x27EE}, + {0x27EF, 0x27EF}, {0x27F0, 0x27FF}, {0x2800, 0x28FF}, + {0x2900, 0x297F}, {0x2980, 0x2982}, {0x2983, 0x2983}, + {0x2984, 0x2984}, {0x2987, 0x2987}, {0x2988, 0x2988}, + {0x2989, 0x2989}, {0x298A, 0x298A}, {0x298B, 0x298B}, + {0x298C, 0x298C}, {0x298D, 0x298D}, {0x298E, 0x298E}, + {0x298F, 0x298F}, {0x2990, 0x2990}, {0x2991, 0x2991}, + {0x2992, 0x2992}, {0x2993, 0x2993}, {0x2994, 0x2994}, + {0x2995, 0x2995}, {0x2996, 0x2996}, {0x2997, 0x2997}, + {0x2998, 0x2998}, {0x2999, 0x29D7}, {0x29D8, 0x29D8}, + {0x29D9, 0x29D9}, {0x29DA, 0x29DA}, {0x29DB, 0x29DB}, + {0x29DC, 0x29FB}, {0x29FC, 0x29FC}, {0x29FD, 0x29FD}, + {0x29FE, 0x29FF}, {0x2A00, 0x2AFF}, {0x2B00, 0x2B1A}, + {0x2B1D, 0x2B2F}, {0x2B30, 0x2B44}, {0x2B45, 0x2B46}, + {0x2B47, 0x2B4C}, {0x2B4D, 0x2B4F}, {0x2B51, 0x2B54}, + {0x2B5A, 0x2B73}, {0x2B76, 0x2B95}, {0x2B98, 0x2BB9}, + {0x2BBD, 0x2BC8}, {0x2BCA, 0x2BD1}, {0x2BEC, 0x2BEF}, + {0x2C00, 0x2C2E}, {0x2C30, 0x2C5E}, {0x2C60, 0x2C7B}, + {0x2C7C, 0x2C7D}, {0x2C7E, 0x2C7F}, {0x2C80, 0x2CE4}, + {0x2CE5, 0x2CEA}, {0x2CEB, 0x2CEE}, {0x2CEF, 0x2CF1}, + {0x2CF2, 0x2CF3}, {0x2CF9, 0x2CFC}, {0x2CFD, 0x2CFD}, + {0x2CFE, 0x2CFF}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, + {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D6F}, + {0x2D70, 0x2D70}, {0x2D7F, 0x2D7F}, {0x2D80, 0x2D96}, + {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, + {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, + {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2DFF}, + {0x2E00, 0x2E01}, {0x2E02, 0x2E02}, {0x2E03, 0x2E03}, + {0x2E04, 0x2E04}, {0x2E05, 0x2E05}, {0x2E06, 0x2E08}, + {0x2E09, 0x2E09}, {0x2E0A, 0x2E0A}, {0x2E0B, 0x2E0B}, + {0x2E0C, 0x2E0C}, {0x2E0D, 0x2E0D}, {0x2E0E, 0x2E16}, + {0x2E17, 0x2E17}, {0x2E18, 0x2E19}, {0x2E1A, 0x2E1A}, + {0x2E1B, 0x2E1B}, {0x2E1C, 0x2E1C}, {0x2E1D, 0x2E1D}, + {0x2E1E, 0x2E1F}, {0x2E20, 0x2E20}, {0x2E21, 0x2E21}, + {0x2E22, 0x2E22}, {0x2E23, 0x2E23}, {0x2E24, 0x2E24}, + {0x2E25, 0x2E25}, {0x2E26, 0x2E26}, {0x2E27, 0x2E27}, + {0x2E28, 0x2E28}, {0x2E29, 0x2E29}, {0x2E2A, 0x2E2E}, + {0x2E2F, 0x2E2F}, {0x2E30, 0x2E39}, {0x2E3A, 0x2E3B}, + {0x2E3C, 0x2E3F}, {0x2E40, 0x2E40}, {0x2E41, 0x2E41}, + {0x2E42, 0x2E42}, {0x2E43, 0x2E44}, {0x303F, 0x303F}, + {0x4DC0, 0x4DFF}, {0xA4D0, 0xA4F7}, {0xA4F8, 0xA4FD}, + {0xA4FE, 0xA4FF}, {0xA500, 0xA60B}, {0xA60C, 0xA60C}, + {0xA60D, 0xA60F}, {0xA610, 0xA61F}, {0xA620, 0xA629}, + {0xA62A, 0xA62B}, {0xA640, 0xA66D}, {0xA66E, 0xA66E}, + {0xA66F, 0xA66F}, {0xA670, 0xA672}, {0xA673, 0xA673}, + {0xA674, 0xA67D}, {0xA67E, 0xA67E}, {0xA67F, 0xA67F}, + {0xA680, 0xA69B}, {0xA69C, 0xA69D}, {0xA69E, 0xA69F}, + {0xA6A0, 0xA6E5}, {0xA6E6, 0xA6EF}, {0xA6F0, 0xA6F1}, + {0xA6F2, 0xA6F7}, {0xA700, 0xA716}, {0xA717, 0xA71F}, + {0xA720, 0xA721}, {0xA722, 0xA76F}, {0xA770, 0xA770}, + {0xA771, 0xA787}, {0xA788, 0xA788}, {0xA789, 0xA78A}, + {0xA78B, 0xA78E}, {0xA78F, 0xA78F}, {0xA790, 0xA7AE}, + {0xA7B0, 0xA7B7}, {0xA7F7, 0xA7F7}, {0xA7F8, 0xA7F9}, + {0xA7FA, 0xA7FA}, {0xA7FB, 0xA7FF}, {0xA800, 0xA801}, + {0xA802, 0xA802}, {0xA803, 0xA805}, {0xA806, 0xA806}, + {0xA807, 0xA80A}, {0xA80B, 0xA80B}, {0xA80C, 0xA822}, + {0xA823, 0xA824}, {0xA825, 0xA826}, {0xA827, 0xA827}, + {0xA828, 0xA82B}, {0xA830, 0xA835}, {0xA836, 0xA837}, + {0xA838, 0xA838}, {0xA839, 0xA839}, {0xA840, 0xA873}, + {0xA874, 0xA877}, {0xA880, 0xA881}, {0xA882, 0xA8B3}, + {0xA8B4, 0xA8C3}, {0xA8C4, 0xA8C5}, {0xA8CE, 0xA8CF}, + {0xA8D0, 0xA8D9}, {0xA8E0, 0xA8F1}, {0xA8F2, 0xA8F7}, + {0xA8F8, 0xA8FA}, {0xA8FB, 0xA8FB}, {0xA8FC, 0xA8FC}, + {0xA8FD, 0xA8FD}, {0xA900, 0xA909}, {0xA90A, 0xA925}, + {0xA926, 0xA92D}, {0xA92E, 0xA92F}, {0xA930, 0xA946}, + {0xA947, 0xA951}, {0xA952, 0xA953}, {0xA95F, 0xA95F}, + {0xA980, 0xA982}, {0xA983, 0xA983}, {0xA984, 0xA9B2}, + {0xA9B3, 0xA9B3}, {0xA9B4, 0xA9B5}, {0xA9B6, 0xA9B9}, + {0xA9BA, 0xA9BB}, {0xA9BC, 0xA9BC}, {0xA9BD, 0xA9C0}, + {0xA9C1, 0xA9CD}, {0xA9CF, 0xA9CF}, {0xA9D0, 0xA9D9}, + {0xA9DE, 0xA9DF}, {0xA9E0, 0xA9E4}, {0xA9E5, 0xA9E5}, + {0xA9E6, 0xA9E6}, {0xA9E7, 0xA9EF}, {0xA9F0, 0xA9F9}, + {0xA9FA, 0xA9FE}, {0xAA00, 0xAA28}, {0xAA29, 0xAA2E}, + {0xAA2F, 0xAA30}, {0xAA31, 0xAA32}, {0xAA33, 0xAA34}, + {0xAA35, 0xAA36}, {0xAA40, 0xAA42}, {0xAA43, 0xAA43}, + {0xAA44, 0xAA4B}, {0xAA4C, 0xAA4C}, {0xAA4D, 0xAA4D}, + {0xAA50, 0xAA59}, {0xAA5C, 0xAA5F}, {0xAA60, 0xAA6F}, + {0xAA70, 0xAA70}, {0xAA71, 0xAA76}, {0xAA77, 0xAA79}, + {0xAA7A, 0xAA7A}, {0xAA7B, 0xAA7B}, {0xAA7C, 0xAA7C}, + {0xAA7D, 0xAA7D}, {0xAA7E, 0xAA7F}, {0xAA80, 0xAAAF}, + {0xAAB0, 0xAAB0}, {0xAAB1, 0xAAB1}, {0xAAB2, 0xAAB4}, + {0xAAB5, 0xAAB6}, {0xAAB7, 0xAAB8}, {0xAAB9, 0xAABD}, + {0xAABE, 0xAABF}, {0xAAC0, 0xAAC0}, {0xAAC1, 0xAAC1}, + {0xAAC2, 0xAAC2}, {0xAADB, 0xAADC}, {0xAADD, 0xAADD}, + {0xAADE, 0xAADF}, {0xAAE0, 0xAAEA}, {0xAAEB, 0xAAEB}, + {0xAAEC, 0xAAED}, {0xAAEE, 0xAAEF}, {0xAAF0, 0xAAF1}, + {0xAAF2, 0xAAF2}, {0xAAF3, 0xAAF4}, {0xAAF5, 0xAAF5}, + {0xAAF6, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, + {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, + {0xAB30, 0xAB5A}, {0xAB5B, 0xAB5B}, {0xAB5C, 0xAB5F}, + {0xAB60, 0xAB65}, {0xAB70, 0xABBF}, {0xABC0, 0xABE2}, + {0xABE3, 0xABE4}, {0xABE5, 0xABE5}, {0xABE6, 0xABE7}, + {0xABE8, 0xABE8}, {0xABE9, 0xABEA}, {0xABEB, 0xABEB}, + {0xABEC, 0xABEC}, {0xABED, 0xABED}, {0xABF0, 0xABF9}, + {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDB7F}, + {0xDB80, 0xDBFF}, {0xDC00, 0xDFFF}, {0xFB00, 0xFB06}, + {0xFB13, 0xFB17}, {0xFB1D, 0xFB1D}, {0xFB1E, 0xFB1E}, + {0xFB1F, 0xFB28}, {0xFB29, 0xFB29}, {0xFB2A, 0xFB36}, + {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, + {0xFB43, 0xFB44}, {0xFB46, 0xFB4F}, {0xFB50, 0xFBB1}, + {0xFBB2, 0xFBC1}, {0xFBD3, 0xFD3D}, {0xFD3E, 0xFD3E}, + {0xFD3F, 0xFD3F}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, + {0xFDF0, 0xFDFB}, {0xFDFC, 0xFDFC}, {0xFDFD, 0xFDFD}, + {0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, + {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFC, 0xFFFC}, + {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, + {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, + {0x10080, 0x100FA}, {0x10100, 0x10102}, {0x10107, 0x10133}, + {0x10137, 0x1013F}, {0x10140, 0x10174}, {0x10175, 0x10178}, + {0x10179, 0x10189}, {0x1018A, 0x1018B}, {0x1018C, 0x1018E}, + {0x10190, 0x1019B}, {0x101A0, 0x101A0}, {0x101D0, 0x101FC}, + {0x101FD, 0x101FD}, {0x10280, 0x1029C}, {0x102A0, 0x102D0}, + {0x102E0, 0x102E0}, {0x102E1, 0x102FB}, {0x10300, 0x1031F}, + {0x10320, 0x10323}, {0x10330, 0x10340}, {0x10341, 0x10341}, + {0x10342, 0x10349}, {0x1034A, 0x1034A}, {0x10350, 0x10375}, + {0x10376, 0x1037A}, {0x10380, 0x1039D}, {0x1039F, 0x1039F}, + {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D0, 0x103D0}, + {0x103D1, 0x103D5}, {0x10400, 0x1044F}, {0x10450, 0x1047F}, + {0x10480, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, + {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, + {0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755}, + {0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808}, + {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, + {0x1083F, 0x1083F}, {0x10840, 0x10855}, {0x10857, 0x10857}, + {0x10858, 0x1085F}, {0x10860, 0x10876}, {0x10877, 0x10878}, + {0x10879, 0x1087F}, {0x10880, 0x1089E}, {0x108A7, 0x108AF}, + {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x108FF}, + {0x10900, 0x10915}, {0x10916, 0x1091B}, {0x1091F, 0x1091F}, + {0x10920, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x1099F}, + {0x109A0, 0x109B7}, {0x109BC, 0x109BD}, {0x109BE, 0x109BF}, + {0x109C0, 0x109CF}, {0x109D2, 0x109FF}, {0x10A00, 0x10A00}, + {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, + {0x10A10, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A33}, + {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x10A40, 0x10A47}, + {0x10A50, 0x10A58}, {0x10A60, 0x10A7C}, {0x10A7D, 0x10A7E}, + {0x10A7F, 0x10A7F}, {0x10A80, 0x10A9C}, {0x10A9D, 0x10A9F}, + {0x10AC0, 0x10AC7}, {0x10AC8, 0x10AC8}, {0x10AC9, 0x10AE4}, + {0x10AE5, 0x10AE6}, {0x10AEB, 0x10AEF}, {0x10AF0, 0x10AF6}, + {0x10B00, 0x10B35}, {0x10B39, 0x10B3F}, {0x10B40, 0x10B55}, + {0x10B58, 0x10B5F}, {0x10B60, 0x10B72}, {0x10B78, 0x10B7F}, + {0x10B80, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, + {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, + {0x10CFA, 0x10CFF}, {0x10E60, 0x10E7E}, {0x11000, 0x11000}, + {0x11001, 0x11001}, {0x11002, 0x11002}, {0x11003, 0x11037}, + {0x11038, 0x11046}, {0x11047, 0x1104D}, {0x11052, 0x11065}, + {0x11066, 0x1106F}, {0x1107F, 0x1107F}, {0x11080, 0x11081}, + {0x11082, 0x11082}, {0x11083, 0x110AF}, {0x110B0, 0x110B2}, + {0x110B3, 0x110B6}, {0x110B7, 0x110B8}, {0x110B9, 0x110BA}, + {0x110BB, 0x110BC}, {0x110BD, 0x110BD}, {0x110BE, 0x110C1}, + {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11100, 0x11102}, + {0x11103, 0x11126}, {0x11127, 0x1112B}, {0x1112C, 0x1112C}, + {0x1112D, 0x11134}, {0x11136, 0x1113F}, {0x11140, 0x11143}, + {0x11150, 0x11172}, {0x11173, 0x11173}, {0x11174, 0x11175}, + {0x11176, 0x11176}, {0x11180, 0x11181}, {0x11182, 0x11182}, + {0x11183, 0x111B2}, {0x111B3, 0x111B5}, {0x111B6, 0x111BE}, + {0x111BF, 0x111C0}, {0x111C1, 0x111C4}, {0x111C5, 0x111C9}, + {0x111CA, 0x111CC}, {0x111CD, 0x111CD}, {0x111D0, 0x111D9}, + {0x111DA, 0x111DA}, {0x111DB, 0x111DB}, {0x111DC, 0x111DC}, + {0x111DD, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211}, + {0x11213, 0x1122B}, {0x1122C, 0x1122E}, {0x1122F, 0x11231}, + {0x11232, 0x11233}, {0x11234, 0x11234}, {0x11235, 0x11235}, + {0x11236, 0x11237}, {0x11238, 0x1123D}, {0x1123E, 0x1123E}, + {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, + {0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112A9, 0x112A9}, + {0x112B0, 0x112DE}, {0x112DF, 0x112DF}, {0x112E0, 0x112E2}, + {0x112E3, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11301}, + {0x11302, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, + {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, + {0x11335, 0x11339}, {0x1133C, 0x1133C}, {0x1133D, 0x1133D}, + {0x1133E, 0x1133F}, {0x11340, 0x11340}, {0x11341, 0x11344}, + {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350}, + {0x11357, 0x11357}, {0x1135D, 0x11361}, {0x11362, 0x11363}, + {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11400, 0x11434}, + {0x11435, 0x11437}, {0x11438, 0x1143F}, {0x11440, 0x11441}, + {0x11442, 0x11444}, {0x11445, 0x11445}, {0x11446, 0x11446}, + {0x11447, 0x1144A}, {0x1144B, 0x1144F}, {0x11450, 0x11459}, + {0x1145B, 0x1145B}, {0x1145D, 0x1145D}, {0x11480, 0x114AF}, + {0x114B0, 0x114B2}, {0x114B3, 0x114B8}, {0x114B9, 0x114B9}, + {0x114BA, 0x114BA}, {0x114BB, 0x114BE}, {0x114BF, 0x114C0}, + {0x114C1, 0x114C1}, {0x114C2, 0x114C3}, {0x114C4, 0x114C5}, + {0x114C6, 0x114C6}, {0x114C7, 0x114C7}, {0x114D0, 0x114D9}, + {0x11580, 0x115AE}, {0x115AF, 0x115B1}, {0x115B2, 0x115B5}, + {0x115B8, 0x115BB}, {0x115BC, 0x115BD}, {0x115BE, 0x115BE}, + {0x115BF, 0x115C0}, {0x115C1, 0x115D7}, {0x115D8, 0x115DB}, + {0x115DC, 0x115DD}, {0x11600, 0x1162F}, {0x11630, 0x11632}, + {0x11633, 0x1163A}, {0x1163B, 0x1163C}, {0x1163D, 0x1163D}, + {0x1163E, 0x1163E}, {0x1163F, 0x11640}, {0x11641, 0x11643}, + {0x11644, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C}, + {0x11680, 0x116AA}, {0x116AB, 0x116AB}, {0x116AC, 0x116AC}, + {0x116AD, 0x116AD}, {0x116AE, 0x116AF}, {0x116B0, 0x116B5}, + {0x116B6, 0x116B6}, {0x116B7, 0x116B7}, {0x116C0, 0x116C9}, + {0x11700, 0x11719}, {0x1171D, 0x1171F}, {0x11720, 0x11721}, + {0x11722, 0x11725}, {0x11726, 0x11726}, {0x11727, 0x1172B}, + {0x11730, 0x11739}, {0x1173A, 0x1173B}, {0x1173C, 0x1173E}, + {0x1173F, 0x1173F}, {0x118A0, 0x118DF}, {0x118E0, 0x118E9}, + {0x118EA, 0x118F2}, {0x118FF, 0x118FF}, {0x11AC0, 0x11AF8}, + {0x11C00, 0x11C08}, {0x11C0A, 0x11C2E}, {0x11C2F, 0x11C2F}, + {0x11C30, 0x11C36}, {0x11C38, 0x11C3D}, {0x11C3E, 0x11C3E}, + {0x11C3F, 0x11C3F}, {0x11C40, 0x11C40}, {0x11C41, 0x11C45}, + {0x11C50, 0x11C59}, {0x11C5A, 0x11C6C}, {0x11C70, 0x11C71}, + {0x11C72, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CA9}, + {0x11CAA, 0x11CB0}, {0x11CB1, 0x11CB1}, {0x11CB2, 0x11CB3}, + {0x11CB4, 0x11CB4}, {0x11CB5, 0x11CB6}, {0x12000, 0x12399}, + {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, + {0x13000, 0x1342E}, {0x14400, 0x14646}, {0x16800, 0x16A38}, + {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16A6F}, + {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF4}, {0x16AF5, 0x16AF5}, + {0x16B00, 0x16B2F}, {0x16B30, 0x16B36}, {0x16B37, 0x16B3B}, + {0x16B3C, 0x16B3F}, {0x16B40, 0x16B43}, {0x16B44, 0x16B44}, + {0x16B45, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, + {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16F00, 0x16F44}, + {0x16F50, 0x16F50}, {0x16F51, 0x16F7E}, {0x16F8F, 0x16F92}, + {0x16F93, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, + {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BC9C}, + {0x1BC9D, 0x1BC9E}, {0x1BC9F, 0x1BC9F}, {0x1BCA0, 0x1BCA3}, + {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D164}, + {0x1D165, 0x1D166}, {0x1D167, 0x1D169}, {0x1D16A, 0x1D16C}, + {0x1D16D, 0x1D172}, {0x1D173, 0x1D17A}, {0x1D17B, 0x1D182}, + {0x1D183, 0x1D184}, {0x1D185, 0x1D18B}, {0x1D18C, 0x1D1A9}, + {0x1D1AA, 0x1D1AD}, {0x1D1AE, 0x1D1E8}, {0x1D200, 0x1D241}, + {0x1D242, 0x1D244}, {0x1D245, 0x1D245}, {0x1D300, 0x1D356}, + {0x1D360, 0x1D371}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, + {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, + {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, + {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, + {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, + {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, + {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, + {0x1D6C1, 0x1D6C1}, {0x1D6C2, 0x1D6DA}, {0x1D6DB, 0x1D6DB}, + {0x1D6DC, 0x1D6FA}, {0x1D6FB, 0x1D6FB}, {0x1D6FC, 0x1D714}, + {0x1D715, 0x1D715}, {0x1D716, 0x1D734}, {0x1D735, 0x1D735}, + {0x1D736, 0x1D74E}, {0x1D74F, 0x1D74F}, {0x1D750, 0x1D76E}, + {0x1D76F, 0x1D76F}, {0x1D770, 0x1D788}, {0x1D789, 0x1D789}, + {0x1D78A, 0x1D7A8}, {0x1D7A9, 0x1D7A9}, {0x1D7AA, 0x1D7C2}, + {0x1D7C3, 0x1D7C3}, {0x1D7C4, 0x1D7CB}, {0x1D7CE, 0x1D7FF}, + {0x1D800, 0x1D9FF}, {0x1DA00, 0x1DA36}, {0x1DA37, 0x1DA3A}, + {0x1DA3B, 0x1DA6C}, {0x1DA6D, 0x1DA74}, {0x1DA75, 0x1DA75}, + {0x1DA76, 0x1DA83}, {0x1DA84, 0x1DA84}, {0x1DA85, 0x1DA86}, + {0x1DA87, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, + {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, + {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E800, 0x1E8C4}, + {0x1E8C7, 0x1E8CF}, {0x1E8D0, 0x1E8D6}, {0x1E900, 0x1E943}, + {0x1E944, 0x1E94A}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, + {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, + {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, + {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, + {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, + {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, + {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, + {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, + {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, + {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, + {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, + {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, + {0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, + {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, + {0x1F0C1, 0x1F0CE}, {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10C}, + {0x1F12E, 0x1F12E}, {0x1F16A, 0x1F16B}, {0x1F1E6, 0x1F1FF}, + {0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, + {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF}, + {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F}, + {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A}, + {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594}, + {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F}, + {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6E0, 0x1F6EA}, + {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773}, {0x1F780, 0x1F7D4}, + {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, {0x1F850, 0x1F859}, + {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, {0xE0001, 0xE0001}, + {0xE0020, 0xE007F}, +} + +// Condition have flag EastAsianWidth whether the current locale is CJK or not. +type Condition struct { + EastAsianWidth bool +} + +// NewCondition return new instance of Condition which is current locale. +func NewCondition() *Condition { + return &Condition{EastAsianWidth} +} + +// RuneWidth returns the number of cells in r. +// See http://www.unicode.org/reports/tr11/ +func (c *Condition) RuneWidth(r rune) int { + switch { + case r < 0 || r > 0x10FFFF || + inTables(r, nonprint, combining, notassigned): + return 0 + case (c.EastAsianWidth && IsAmbiguousWidth(r)) || + inTables(r, doublewidth, emoji): + return 2 + default: + return 1 + } +} + +// StringWidth return width as you can see +func (c *Condition) StringWidth(s string) (width int) { + for _, r := range []rune(s) { + width += c.RuneWidth(r) + } + return width +} + +// Truncate return string truncated with w cells +func (c *Condition) Truncate(s string, w int, tail string) string { + if c.StringWidth(s) <= w { + return s + } + r := []rune(s) + tw := c.StringWidth(tail) + w -= tw + width := 0 + i := 0 + for ; i < len(r); i++ { + cw := c.RuneWidth(r[i]) + if width+cw > w { + break + } + width += cw + } + return string(r[0:i]) + tail +} + +// Wrap return string wrapped with w cells +func (c *Condition) Wrap(s string, w int) string { + width := 0 + out := "" + for _, r := range []rune(s) { + cw := RuneWidth(r) + if r == '\n' { + out += string(r) + width = 0 + continue + } else if width+cw > w { + out += "\n" + width = 0 + out += string(r) + width += cw + continue + } + out += string(r) + width += cw + } + return out +} + +// FillLeft return string filled in left by spaces in w cells +func (c *Condition) FillLeft(s string, w int) string { + width := c.StringWidth(s) + count := w - width + if count > 0 { + b := make([]byte, count) + for i := range b { + b[i] = ' ' + } + return string(b) + s + } + return s +} + +// FillRight return string filled in left by spaces in w cells +func (c *Condition) FillRight(s string, w int) string { + width := c.StringWidth(s) + count := w - width + if count > 0 { + b := make([]byte, count) + for i := range b { + b[i] = ' ' + } + return s + string(b) + } + return s +} + +// RuneWidth returns the number of cells in r. +// See http://www.unicode.org/reports/tr11/ +func RuneWidth(r rune) int { + return DefaultCondition.RuneWidth(r) +} + +// IsAmbiguousWidth returns whether is ambiguous width or not. +func IsAmbiguousWidth(r rune) bool { + return inTables(r, private, ambiguous) +} + +// IsNeutralWidth returns whether is neutral width or not. +func IsNeutralWidth(r rune) bool { + return inTable(r, neutral) +} + +// StringWidth return width as you can see +func StringWidth(s string) (width int) { + return DefaultCondition.StringWidth(s) +} + +// Truncate return string truncated with w cells +func Truncate(s string, w int, tail string) string { + return DefaultCondition.Truncate(s, w, tail) +} + +// Wrap return string wrapped with w cells +func Wrap(s string, w int) string { + return DefaultCondition.Wrap(s, w) +} + +// FillLeft return string filled in left by spaces in w cells +func FillLeft(s string, w int) string { + return DefaultCondition.FillLeft(s, w) +} + +// FillRight return string filled in left by spaces in w cells +func FillRight(s string, w int) string { + return DefaultCondition.FillRight(s, w) +} diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_js.go b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_js.go new file mode 100644 index 000000000..0ce32c5e7 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_js.go @@ -0,0 +1,8 @@ +// +build js + +package runewidth + +func IsEastAsian() bool { + // TODO: Implement this for the web. Detect east asian in a compatible way, and return true. + return false +} diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_posix.go b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_posix.go new file mode 100644 index 000000000..c579e9a31 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_posix.go @@ -0,0 +1,77 @@ +// +build !windows,!js + +package runewidth + +import ( + "os" + "regexp" + "strings" +) + +var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`) + +var mblenTable = map[string]int{ + "utf-8": 6, + "utf8": 6, + "jis": 8, + "eucjp": 3, + "euckr": 2, + "euccn": 2, + "sjis": 2, + "cp932": 2, + "cp51932": 2, + "cp936": 2, + "cp949": 2, + "cp950": 2, + "big5": 2, + "gbk": 2, + "gb2312": 2, +} + +func isEastAsian(locale string) bool { + charset := strings.ToLower(locale) + r := reLoc.FindStringSubmatch(locale) + if len(r) == 2 { + charset = strings.ToLower(r[1]) + } + + if strings.HasSuffix(charset, "@cjk_narrow") { + return false + } + + for pos, b := range []byte(charset) { + if b == '@' { + charset = charset[:pos] + break + } + } + max := 1 + if m, ok := mblenTable[charset]; ok { + max = m + } + if max > 1 && (charset[0] != 'u' || + strings.HasPrefix(locale, "ja") || + strings.HasPrefix(locale, "ko") || + strings.HasPrefix(locale, "zh")) { + return true + } + return false +} + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + locale := os.Getenv("LC_CTYPE") + if locale == "" { + locale = os.Getenv("LANG") + } + + // ignore C locale + if locale == "POSIX" || locale == "C" { + return false + } + if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') { + return false + } + + return isEastAsian(locale) +} diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_test.go b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_test.go new file mode 100644 index 000000000..b0378a193 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_test.go @@ -0,0 +1,275 @@ +package runewidth + +import ( + "sort" + "testing" +) + +var _ sort.Interface = (*table)(nil) + +func (t table) Len() int { + return len(t) +} + +func (t table) Less(i, j int) bool { + return t[i].first < t[j].first +} + +func (t *table) Swap(i, j int) { + (*t)[i], (*t)[j] = (*t)[j], (*t)[i] +} + +var tables = []table{ + private, + nonprint, + combining, + doublewidth, + ambiguous, + emoji, + notassigned, + neutral, +} + +func TestSorted(t *testing.T) { + for _, tbl := range tables { + if !sort.IsSorted(&tbl) { + t.Errorf("not sorted") + } + } +} + +var runewidthtests = []struct { + in rune + out int + eaout int +}{ + {'世', 2, 2}, + {'界', 2, 2}, + {'セ', 1, 1}, + {'カ', 1, 1}, + {'イ', 1, 1}, + {'☆', 1, 2}, // double width in ambiguous + {'\x00', 0, 0}, + {'\x01', 0, 0}, + {'\u0300', 0, 0}, +} + +func TestRuneWidth(t *testing.T) { + c := NewCondition() + for _, tt := range runewidthtests { + if out := c.RuneWidth(tt.in); out != tt.out { + t.Errorf("RuneWidth(%q) = %d, want %d", tt.in, out, tt.out) + } + } + c.EastAsianWidth = true + for _, tt := range runewidthtests { + if out := c.RuneWidth(tt.in); out != tt.eaout { + t.Errorf("RuneWidth(%q) = %d, want %d", tt.in, out, tt.eaout) + } + } +} + +var isambiguouswidthtests = []struct { + in rune + out bool +}{ + {'世', false}, + {'■', true}, + {'界', false}, + {'○', true}, + {'㈱', false}, + {'①', true}, + {'②', true}, + {'③', true}, + {'④', true}, + {'⑤', true}, + {'⑥', true}, + {'⑦', true}, + {'⑧', true}, + {'⑨', true}, + {'⑩', true}, + {'⑪', true}, + {'⑫', true}, + {'⑬', true}, + {'⑭', true}, + {'⑮', true}, + {'⑯', true}, + {'⑰', true}, + {'⑱', true}, + {'⑲', true}, + {'⑳', true}, + {'☆', true}, +} + +func TestIsAmbiguousWidth(t *testing.T) { + for _, tt := range isambiguouswidthtests { + if out := IsAmbiguousWidth(tt.in); out != tt.out { + t.Errorf("IsAmbiguousWidth(%q) = %v, want %v", tt.in, out, tt.out) + } + } +} + +var stringwidthtests = []struct { + in string + out int + eaout int +}{ + {"■㈱の世界①", 10, 12}, + {"スター☆", 7, 8}, + {"つのだ☆HIRO", 11, 12}, +} + +func TestStringWidth(t *testing.T) { + c := NewCondition() + for _, tt := range stringwidthtests { + if out := c.StringWidth(tt.in); out != tt.out { + t.Errorf("StringWidth(%q) = %q, want %q", tt.in, out, tt.out) + } + } + c.EastAsianWidth = true + for _, tt := range stringwidthtests { + if out := c.StringWidth(tt.in); out != tt.eaout { + t.Errorf("StringWidth(%q) = %q, want %q", tt.in, out, tt.eaout) + } + } +} + +func TestStringWidthInvalid(t *testing.T) { + s := "こんにちわ\x00世界" + if out := StringWidth(s); out != 14 { + t.Errorf("StringWidth(%q) = %q, want %q", s, out, 14) + } +} + +func TestTruncateSmaller(t *testing.T) { + s := "あいうえお" + expected := "あいうえお" + + if out := Truncate(s, 10, "..."); out != expected { + t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) + } +} + +func TestTruncate(t *testing.T) { + s := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお" + expected := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおお..." + out := Truncate(s, 80, "...") + if out != expected { + t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) + } + width := StringWidth(out) + if width != 79 { + t.Errorf("width of Truncate(%q) should be %d, but %d", s, 79, width) + } +} + +func TestTruncateFit(t *testing.T) { + s := "aあいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお" + expected := "aあいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおお..." + + out := Truncate(s, 80, "...") + if out != expected { + t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) + } + width := StringWidth(out) + if width != 80 { + t.Errorf("width of Truncate(%q) should be %d, but %d", s, 80, width) + } +} + +func TestTruncateJustFit(t *testing.T) { + s := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおお" + expected := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおお" + + out := Truncate(s, 80, "...") + if out != expected { + t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) + } + width := StringWidth(out) + if width != 80 { + t.Errorf("width of Truncate(%q) should be %d, but %d", s, 80, width) + } +} + +func TestWrap(t *testing.T) { + s := `東京特許許可局局長はよく柿喰う客だ/東京特許許可局局長はよく柿喰う客だ +123456789012345678901234567890 + +END` + expected := `東京特許許可局局長はよく柿喰う +客だ/東京特許許可局局長はよく +柿喰う客だ +123456789012345678901234567890 + +END` + + if out := Wrap(s, 30); out != expected { + t.Errorf("Wrap(%q) = %q, want %q", s, out, expected) + } +} + +func TestTruncateNoNeeded(t *testing.T) { + s := "あいうえおあい" + expected := "あいうえおあい" + + if out := Truncate(s, 80, "..."); out != expected { + t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) + } +} + +var isneutralwidthtests = []struct { + in rune + out bool +}{ + {'→', false}, + {'┊', false}, + {'┈', false}, + {'~', false}, + {'└', false}, + {'⣀', true}, + {'⣀', true}, +} + +func TestIsNeutralWidth(t *testing.T) { + for _, tt := range isneutralwidthtests { + if out := IsNeutralWidth(tt.in); out != tt.out { + t.Errorf("IsNeutralWidth(%q) = %v, want %v", tt.in, out, tt.out) + } + } +} + +func TestFillLeft(t *testing.T) { + s := "あxいうえお" + expected := " あxいうえお" + + if out := FillLeft(s, 15); out != expected { + t.Errorf("FillLeft(%q) = %q, want %q", s, out, expected) + } +} + +func TestFillLeftFit(t *testing.T) { + s := "あいうえお" + expected := "あいうえお" + + if out := FillLeft(s, 10); out != expected { + t.Errorf("FillLeft(%q) = %q, want %q", s, out, expected) + } +} + +func TestFillRight(t *testing.T) { + s := "あxいうえお" + expected := "あxいうえお " + + if out := FillRight(s, 15); out != expected { + t.Errorf("FillRight(%q) = %q, want %q", s, out, expected) + } +} + +func TestFillRightFit(t *testing.T) { + s := "あいうえお" + expected := "あいうえお" + + if out := FillRight(s, 10); out != expected { + t.Errorf("FillRight(%q) = %q, want %q", s, out, expected) + } +} diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_windows.go b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_windows.go new file mode 100644 index 000000000..0258876b9 --- /dev/null +++ b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_windows.go @@ -0,0 +1,25 @@ +package runewidth + +import ( + "syscall" +) + +var ( + kernel32 = syscall.NewLazyDLL("kernel32") + procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP") +) + +// IsEastAsian return true if the current locale is CJK +func IsEastAsian() bool { + r1, _, _ := procGetConsoleOutputCP.Call() + if r1 == 0 { + return false + } + + switch int(r1) { + case 932, 51932, 936, 949, 950: + return true + } + + return false +} From d87a80763261689904f6158a00fe7daa4c3d1fea Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 18 Jan 2018 16:55:36 +0900 Subject: [PATCH 03/45] init batching sketch --- cmd/geth/build_atxi_cmd.go | 21 ++---------------- core/blockchain.go | 45 ++++++++++++++++++++++++++++++++++++++ core/database_util.go | 6 ++--- core/database_util_test.go | 2 +- 4 files changed, 51 insertions(+), 23 deletions(-) diff --git a/cmd/geth/build_atxi_cmd.go b/cmd/geth/build_atxi_cmd.go index f371340c8..2f6f6ec04 100644 --- a/cmd/geth/build_atxi_cmd.go +++ b/cmd/geth/build_atxi_cmd.go @@ -5,9 +5,6 @@ import ( "strconv" "github.com/ethereumproject/go-ethereum/logger/glog" "github.com/ethereumproject/go-ethereum/core/types" - "github.com/ethereumproject/go-ethereum/core" - "github.com/cheggaaa/pb" - "os" "path/filepath" "io/ioutil" ) @@ -53,23 +50,9 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { glog.Fatal(blockIndex, "block is nil") } - bar := pb.StartNew(int(stopIndex)) // progress bar - for block != nil && block.NumberU64() <= stopIndex { - - if err := core.WriteBlockAddTxIndexes(indexDb, block); err != nil { - return err - } - - bar.Set(int(block.NumberU64())) - blockIndex++ - - // Placeholder every 1000 blocks is plenty. - if blockIndex % 1000 == 0 { - ioutil.WriteFile(placeholderFilename, []byte(strconv.Itoa(int(blockIndex))), os.ModePerm) - } - block = bc.GetBlockByNumber(blockIndex) + if err := bc.AddTxIndexesBatch(indexDb, startIndex, stopIndex); err != nil { + return err } - bar.Finish() return nil } diff --git a/core/blockchain.go b/core/blockchain.go index 2a6e44206..05e95acdd 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -45,6 +45,7 @@ import ( "github.com/ethereumproject/go-ethereum/rlp" "github.com/ethereumproject/go-ethereum/trie" "github.com/hashicorp/golang-lru" + "encoding/binary" ) var ( @@ -1290,6 +1291,50 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain return 0, nil } +func (self *BlockChain) AddTxIndexesBatch(indexDb ethdb.Database, startBlock, stopBlock uint64) (err error) { + block := self.GetBlockByNumber(startBlock) + putBatch := indexDb.NewBatch() + startTime := time.Now() + lastTime := time.Now() + for block != nil && block.NumberU64() <= stopBlock { + for _, tx := range block.Transactions() { + from, err := tx.From() + if err != nil { + return err + } + bn := make([]byte, 8) + binary.LittleEndian.PutUint64(bn, block.NumberU64()) + + if err := putBatch.Put(FormatAddrTxBytesIndex(from.Bytes(), bn, []byte("f"), tx.Hash().Bytes()), nil); err != nil { + return err + } + + to := tx.To() + if to == nil { + continue + } + var tob []byte + copy(tob, to.Bytes()) + if err := putBatch.Put(FormatAddrTxBytesIndex(tob, bn, []byte("t"), tx.Hash().Bytes()), nil); err != nil { + return err + } + } + if block.NumberU64() % 10000 == 0 { + if err := putBatch.Write(); err != nil { + return err + } else { + putBatch = indexDb.NewBatch() + } + glog.D(logger.Error).Infoln("Batch atxi... block", block.NumberU64(), "/", stopBlock, time.Since(startTime), "~", + 10000/time.Since(lastTime).Seconds(), "bps") + lastTime = time.Now() + } + block = self.GetBlockByNumber(block.NumberU64()+1) + } + glog.D(logger.Error).Infoln("Batch atxi... block", stopBlock, "/", stopBlock, "took:", time.Since(startTime)) + return putBatch.Write() +} + func WriteBlockAddTxIndexes(indexDb ethdb.Database, block *types.Block) error { for _, tx := range block.Transactions() { var err error diff --git a/core/database_util.go b/core/database_util.go index 85acd9e7c..4f3166e60 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -207,10 +207,10 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b return hashes } -// formatAddrTxBytes formats the index key, eg. atx- +// FormatAddrTxBytesIndex formats the index key, eg. atx- // The values for these arguments should be of determinate length and format, see test TestFormatAndResolveAddrTxBytesKey // for example. -func formatAddrTxBytes(address, blockNumber, toOrFrom, txhash []byte) (key []byte) { +func FormatAddrTxBytesIndex(address, blockNumber, toOrFrom, txhash []byte) (key []byte) { key = txAddressIndexPrefix key = append(key, address...) key = append(key, blockNumber...) @@ -239,7 +239,7 @@ func PutAddrTxs(db ethdb.Database, block *types.Block, isTo bool, address common bk := make([]byte, 8) binary.LittleEndian.PutUint64(bk, block.NumberU64()) - k := formatAddrTxBytes(address.Bytes(), bk, tOrF, txhash.Bytes()) + k := FormatAddrTxBytesIndex(address.Bytes(), bk, tOrF, txhash.Bytes()) if err := db.Put(k, nil); err != nil { glog.Fatalf("failed to store addrtxidx into database: %v", err) diff --git a/core/database_util_test.go b/core/database_util_test.go index 70401bbb7..9263f9233 100644 --- a/core/database_util_test.go +++ b/core/database_util_test.go @@ -308,7 +308,7 @@ func TestFormatAndResolveAddrTxBytesKey(t *testing.T) { testBNBytes := make([]byte, 8) binary.LittleEndian.PutUint64(testBNBytes, testBN.Uint64()) - key := formatAddrTxBytes(testAddr.Bytes(), testBNBytes, []byte(testTorf), testTxH.Bytes()) + key := FormatAddrTxBytesIndex(testAddr.Bytes(), testBNBytes, []byte(testTorf), testTxH.Bytes()) // Test key/prefix iterator-ability. itPrefix := formatAddrTxIterator(testAddr) From ffaed6acfeedc088eb6c630c72a0f2d50fe8d9aa Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 18 Jan 2018 21:05:32 +0900 Subject: [PATCH 04/45] use delegated batching for atxi cmd --- cmd/geth/build_atxi_cmd.go | 22 ++++++++++++++++++++-- cmd/geth/main.go | 5 +++++ core/blockchain.go | 30 +++++++++++++++++++----------- 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/cmd/geth/build_atxi_cmd.go b/cmd/geth/build_atxi_cmd.go index 2f6f6ec04..2da139ff7 100644 --- a/cmd/geth/build_atxi_cmd.go +++ b/cmd/geth/build_atxi_cmd.go @@ -7,6 +7,9 @@ import ( "github.com/ethereumproject/go-ethereum/core/types" "path/filepath" "io/ioutil" + "os" + "github.com/ethereumproject/go-ethereum/logger" + "time" ) func buildAddrTxIndexCmd(ctx *cli.Context) error { @@ -36,6 +39,10 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { if stopIndex < startIndex { glog.Fatal("start must be prior to (smaller than) or equal to stop, got start=", startIndex, "stop=", stopIndex) } + if startIndex == stopIndex { + glog.D(logger.Error).Infoln("Up to date. Exiting.") + os.Exit(0) + } indexDb := MakeIndexDatabase(ctx) if indexDb == nil { @@ -50,9 +57,20 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { glog.Fatal(blockIndex, "block is nil") } - if err := bc.AddTxIndexesBatch(indexDb, startIndex, stopIndex); err != nil { - return err + var inc = uint64(ctx.Int("step")) + startTime := time.Now() + glog.D(logger.Error).Infoln("Address/tx indexing (atxi) start:", startIndex, "stop:", stopIndex, "step:", inc) + for i := startIndex; i <= stopIndex; i = i+inc { + if i+inc > stopIndex { + inc = stopIndex - startIndex + } + if err := bc.AddTxIndexesBatch(indexDb, i, i+inc); err != nil { + return err + } + ioutil.WriteFile(placeholderFilename, []byte(strconv.Itoa(int(i+inc))), os.ModePerm) } + ioutil.WriteFile(placeholderFilename, []byte(strconv.Itoa(int(stopIndex))), os.ModePerm) + glog.D(logger.Error).Infoln("Finished atxi. Took:", time.Since(startTime)) return nil } diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 9cb97824c..f6d5f0329 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -122,6 +122,11 @@ func makeCLIApp() (app *cli.App) { Name: "stop", Usage: "Block number at which to stop building index", }, + cli.IntFlag{ + Name: "step", + Usage: "Step increment for batching. Higher number requires more mem, but may be faster. [default: 10000]", + Value: 10000, + }, }, }, { diff --git a/core/blockchain.go b/core/blockchain.go index 05e95acdd..e5061da65 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -32,6 +32,7 @@ import ( "reflect" "strconv" + "encoding/binary" "github.com/ethereumproject/go-ethereum/common" "github.com/ethereumproject/go-ethereum/core/state" "github.com/ethereumproject/go-ethereum/core/types" @@ -45,7 +46,6 @@ import ( "github.com/ethereumproject/go-ethereum/rlp" "github.com/ethereumproject/go-ethereum/trie" "github.com/hashicorp/golang-lru" - "encoding/binary" ) var ( @@ -1291,13 +1291,16 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain return 0, nil } -func (self *BlockChain) AddTxIndexesBatch(indexDb ethdb.Database, startBlock, stopBlock uint64) (err error) { - block := self.GetBlockByNumber(startBlock) +func (self *BlockChain) AddTxIndexesBatch(indexDb ethdb.Database, startBlockN, stopBlockN uint64) (err error) { + block := self.GetBlockByNumber(startBlockN) putBatch := indexDb.NewBatch() startTime := time.Now() lastTime := time.Now() - for block != nil && block.NumberU64() <= stopBlock { + txsCount := 0 + for block != nil && block.NumberU64() <= stopBlockN { for _, tx := range block.Transactions() { + txsCount++ + from, err := tx.From() if err != nil { return err @@ -1319,19 +1322,24 @@ func (self *BlockChain) AddTxIndexesBatch(indexDb ethdb.Database, startBlock, st return err } } - if block.NumberU64() % 10000 == 0 { + if block.NumberU64()%10000 == 0 { if err := putBatch.Write(); err != nil { return err } else { putBatch = indexDb.NewBatch() } - glog.D(logger.Error).Infoln("Batch atxi... block", block.NumberU64(), "/", stopBlock, time.Since(startTime), "~", - 10000/time.Since(lastTime).Seconds(), "bps") - lastTime = time.Now() } - block = self.GetBlockByNumber(block.NumberU64()+1) - } - glog.D(logger.Error).Infoln("Batch atxi... block", stopBlock, "/", stopBlock, "took:", time.Since(startTime)) + block = self.GetBlockByNumber(block.NumberU64() + 1) + } + // TODO: remove me D... i'm just a debugger + glog.D(logger.Error).Infoln("Batch atxi... block", + startBlockN, "/", stopBlockN, + "txs:", txsCount, + "took:", time.Since(startTime), + float64(stopBlockN-startBlockN)/time.Since(lastTime).Seconds(), "bps", + float64(txsCount)/time.Since(lastTime).Seconds(), "txps") + glog.V(logger.Debug).Infoln("Batch atxi... block", startBlockN, "/", stopBlockN, "txs:", txsCount, "took:", time.Since(startTime), float64(stopBlockN-startBlockN)/time.Since(lastTime).Seconds(), "bps") + lastTime = time.Now() return putBatch.Write() } From 3a39d4c739524352546665020cc51a6f807d4b57 Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 19 Jan 2018 09:32:58 +0900 Subject: [PATCH 05/45] dep ensure: remove progress bar deps --- Gopkg.lock | 56 +- vendor/github.com/cheggaaa/pb/.gitignore | 1 - vendor/github.com/cheggaaa/pb/.travis.yml | 13 - vendor/github.com/cheggaaa/pb/Gopkg.lock | 63 - vendor/github.com/cheggaaa/pb/Gopkg.toml | 91 -- vendor/github.com/cheggaaa/pb/LICENSE | 12 - vendor/github.com/cheggaaa/pb/README.md | 70 - vendor/github.com/cheggaaa/pb/element.go | 290 ---- vendor/github.com/cheggaaa/pb/element_test.go | 278 ---- vendor/github.com/cheggaaa/pb/pb.go | 540 -------- vendor/github.com/cheggaaa/pb/pb_test.go | 219 --- vendor/github.com/cheggaaa/pb/preset.go | 17 - vendor/github.com/cheggaaa/pb/reader.go | 26 - vendor/github.com/cheggaaa/pb/reader_test.go | 60 - vendor/github.com/cheggaaa/pb/speed.go | 83 -- vendor/github.com/cheggaaa/pb/template.go | 87 -- .../github.com/cheggaaa/pb/template_test.go | 53 - .../github.com/cheggaaa/pb/termutil/term.go | 57 - .../cheggaaa/pb/termutil/term_appengine.go | 11 - .../cheggaaa/pb/termutil/term_bsd.go | 9 - .../cheggaaa/pb/termutil/term_linux.go | 7 - .../cheggaaa/pb/termutil/term_nix.go | 8 - .../cheggaaa/pb/termutil/term_solaris.go | 8 - .../cheggaaa/pb/termutil/term_win.go | 149 -- .../github.com/cheggaaa/pb/termutil/term_x.go | 70 - vendor/github.com/cheggaaa/pb/util.go | 94 -- vendor/github.com/cheggaaa/pb/util_test.go | 73 - .../github.com/mattn/go-colorable/.travis.yml | 9 - vendor/github.com/mattn/go-colorable/LICENSE | 21 - .../github.com/mattn/go-colorable/README.md | 48 - .../go-colorable/_example/escape-seq/main.go | 16 - .../go-colorable/_example/logrus/main.go | 16 - .../mattn/go-colorable/_example/title/main.go | 14 - .../mattn/go-colorable/colorable_appengine.go | 29 - .../mattn/go-colorable/colorable_others.go | 30 - .../mattn/go-colorable/colorable_test.go | 83 -- .../mattn/go-colorable/colorable_windows.go | 884 ------------ .../mattn/go-colorable/noncolorable.go | 55 - vendor/github.com/mattn/go-isatty/.travis.yml | 9 - vendor/github.com/mattn/go-isatty/LICENSE | 9 - vendor/github.com/mattn/go-isatty/README.md | 50 - vendor/github.com/mattn/go-isatty/doc.go | 2 - .../mattn/go-isatty/example_test.go | 18 - .../mattn/go-isatty/isatty_appengine.go | 15 - .../github.com/mattn/go-isatty/isatty_bsd.go | 18 - .../mattn/go-isatty/isatty_linux.go | 18 - .../mattn/go-isatty/isatty_linux_ppc64x.go | 19 - .../mattn/go-isatty/isatty_others.go | 10 - .../mattn/go-isatty/isatty_others_test.go | 19 - .../mattn/go-isatty/isatty_solaris.go | 16 - .../mattn/go-isatty/isatty_windows.go | 94 -- .../mattn/go-isatty/isatty_windows_test.go | 35 - .../ewma.v1/.github/ISSUE_TEMPLATE.md | 10 - .../ewma.v1/.github/PULL_REQUEST_TEMPLATE.md | 10 - .../gopkg.in/VividCortex/ewma.v1/.gitignore | 2 - vendor/gopkg.in/VividCortex/ewma.v1/LICENSE | 21 - vendor/gopkg.in/VividCortex/ewma.v1/README.md | 140 -- vendor/gopkg.in/VividCortex/ewma.v1/ewma.go | 126 -- .../gopkg.in/VividCortex/ewma.v1/ewma_test.go | 103 -- vendor/gopkg.in/cheggaaa/pb.v2/.gitignore | 1 - vendor/gopkg.in/cheggaaa/pb.v2/.travis.yml | 13 - vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.lock | 63 - vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.toml | 91 -- vendor/gopkg.in/cheggaaa/pb.v2/LICENSE | 12 - vendor/gopkg.in/cheggaaa/pb.v2/README.md | 70 - vendor/gopkg.in/cheggaaa/pb.v2/element.go | 290 ---- .../gopkg.in/cheggaaa/pb.v2/element_test.go | 278 ---- vendor/gopkg.in/cheggaaa/pb.v2/pb.go | 540 -------- vendor/gopkg.in/cheggaaa/pb.v2/pb_test.go | 219 --- vendor/gopkg.in/cheggaaa/pb.v2/preset.go | 17 - vendor/gopkg.in/cheggaaa/pb.v2/reader.go | 26 - vendor/gopkg.in/cheggaaa/pb.v2/reader_test.go | 60 - vendor/gopkg.in/cheggaaa/pb.v2/speed.go | 83 -- vendor/gopkg.in/cheggaaa/pb.v2/template.go | 87 -- .../gopkg.in/cheggaaa/pb.v2/template_test.go | 53 - .../gopkg.in/cheggaaa/pb.v2/termutil/term.go | 57 - .../cheggaaa/pb.v2/termutil/term_appengine.go | 11 - .../cheggaaa/pb.v2/termutil/term_bsd.go | 9 - .../cheggaaa/pb.v2/termutil/term_linux.go | 7 - .../cheggaaa/pb.v2/termutil/term_nix.go | 8 - .../cheggaaa/pb.v2/termutil/term_solaris.go | 8 - .../cheggaaa/pb.v2/termutil/term_win.go | 149 -- .../cheggaaa/pb.v2/termutil/term_x.go | 70 - vendor/gopkg.in/cheggaaa/pb.v2/util.go | 94 -- vendor/gopkg.in/cheggaaa/pb.v2/util_test.go | 73 - vendor/gopkg.in/fatih/color.v1/.travis.yml | 5 - vendor/gopkg.in/fatih/color.v1/LICENSE.md | 20 - vendor/gopkg.in/fatih/color.v1/README.md | 177 --- vendor/gopkg.in/fatih/color.v1/color.go | 600 -------- vendor/gopkg.in/fatih/color.v1/color_test.go | 342 ----- vendor/gopkg.in/fatih/color.v1/doc.go | 133 -- .../mattn/go-colorable.v0/.travis.yml | 9 - vendor/gopkg.in/mattn/go-colorable.v0/LICENSE | 21 - .../gopkg.in/mattn/go-colorable.v0/README.md | 48 - .../_example/escape-seq/main.go | 16 - .../go-colorable.v0/_example/logrus/main.go | 16 - .../go-colorable.v0/_example/title/main.go | 14 - .../go-colorable.v0/colorable_appengine.go | 29 - .../mattn/go-colorable.v0/colorable_others.go | 30 - .../mattn/go-colorable.v0/colorable_test.go | 83 -- .../go-colorable.v0/colorable_windows.go | 884 ------------ .../mattn/go-colorable.v0/noncolorable.go | 55 - .../gopkg.in/mattn/go-isatty.v0/.travis.yml | 9 - vendor/gopkg.in/mattn/go-isatty.v0/LICENSE | 9 - vendor/gopkg.in/mattn/go-isatty.v0/README.md | 50 - vendor/gopkg.in/mattn/go-isatty.v0/doc.go | 2 - .../mattn/go-isatty.v0/example_test.go | 18 - .../mattn/go-isatty.v0/isatty_appengine.go | 15 - .../gopkg.in/mattn/go-isatty.v0/isatty_bsd.go | 18 - .../mattn/go-isatty.v0/isatty_linux.go | 18 - .../mattn/go-isatty.v0/isatty_linux_ppc64x.go | 19 - .../mattn/go-isatty.v0/isatty_others.go | 10 - .../mattn/go-isatty.v0/isatty_others_test.go | 19 - .../mattn/go-isatty.v0/isatty_solaris.go | 16 - .../mattn/go-isatty.v0/isatty_windows.go | 94 -- .../mattn/go-isatty.v0/isatty_windows_test.go | 35 - .../mattn/go-runewidth.v0/.travis.yml | 8 - vendor/gopkg.in/mattn/go-runewidth.v0/LICENSE | 21 - .../gopkg.in/mattn/go-runewidth.v0/README.mkd | 27 - .../mattn/go-runewidth.v0/runewidth.go | 1223 ----------------- .../mattn/go-runewidth.v0/runewidth_js.go | 8 - .../mattn/go-runewidth.v0/runewidth_posix.go | 77 -- .../mattn/go-runewidth.v0/runewidth_test.go | 275 ---- .../go-runewidth.v0/runewidth_windows.go | 25 - 124 files changed, 1 insertion(+), 11260 deletions(-) delete mode 100644 vendor/github.com/cheggaaa/pb/.gitignore delete mode 100644 vendor/github.com/cheggaaa/pb/.travis.yml delete mode 100644 vendor/github.com/cheggaaa/pb/Gopkg.lock delete mode 100644 vendor/github.com/cheggaaa/pb/Gopkg.toml delete mode 100644 vendor/github.com/cheggaaa/pb/LICENSE delete mode 100644 vendor/github.com/cheggaaa/pb/README.md delete mode 100644 vendor/github.com/cheggaaa/pb/element.go delete mode 100644 vendor/github.com/cheggaaa/pb/element_test.go delete mode 100644 vendor/github.com/cheggaaa/pb/pb.go delete mode 100644 vendor/github.com/cheggaaa/pb/pb_test.go delete mode 100644 vendor/github.com/cheggaaa/pb/preset.go delete mode 100644 vendor/github.com/cheggaaa/pb/reader.go delete mode 100644 vendor/github.com/cheggaaa/pb/reader_test.go delete mode 100644 vendor/github.com/cheggaaa/pb/speed.go delete mode 100644 vendor/github.com/cheggaaa/pb/template.go delete mode 100644 vendor/github.com/cheggaaa/pb/template_test.go delete mode 100644 vendor/github.com/cheggaaa/pb/termutil/term.go delete mode 100644 vendor/github.com/cheggaaa/pb/termutil/term_appengine.go delete mode 100644 vendor/github.com/cheggaaa/pb/termutil/term_bsd.go delete mode 100644 vendor/github.com/cheggaaa/pb/termutil/term_linux.go delete mode 100644 vendor/github.com/cheggaaa/pb/termutil/term_nix.go delete mode 100644 vendor/github.com/cheggaaa/pb/termutil/term_solaris.go delete mode 100644 vendor/github.com/cheggaaa/pb/termutil/term_win.go delete mode 100644 vendor/github.com/cheggaaa/pb/termutil/term_x.go delete mode 100644 vendor/github.com/cheggaaa/pb/util.go delete mode 100644 vendor/github.com/cheggaaa/pb/util_test.go delete mode 100644 vendor/github.com/mattn/go-colorable/.travis.yml delete mode 100644 vendor/github.com/mattn/go-colorable/LICENSE delete mode 100644 vendor/github.com/mattn/go-colorable/README.md delete mode 100644 vendor/github.com/mattn/go-colorable/_example/escape-seq/main.go delete mode 100644 vendor/github.com/mattn/go-colorable/_example/logrus/main.go delete mode 100644 vendor/github.com/mattn/go-colorable/_example/title/main.go delete mode 100644 vendor/github.com/mattn/go-colorable/colorable_appengine.go delete mode 100644 vendor/github.com/mattn/go-colorable/colorable_others.go delete mode 100644 vendor/github.com/mattn/go-colorable/colorable_test.go delete mode 100644 vendor/github.com/mattn/go-colorable/colorable_windows.go delete mode 100644 vendor/github.com/mattn/go-colorable/noncolorable.go delete mode 100644 vendor/github.com/mattn/go-isatty/.travis.yml delete mode 100644 vendor/github.com/mattn/go-isatty/LICENSE delete mode 100644 vendor/github.com/mattn/go-isatty/README.md delete mode 100644 vendor/github.com/mattn/go-isatty/doc.go delete mode 100644 vendor/github.com/mattn/go-isatty/example_test.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_appengine.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_bsd.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_linux.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_others.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_others_test.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_solaris.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_windows.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_windows_test.go delete mode 100644 vendor/gopkg.in/VividCortex/ewma.v1/.github/ISSUE_TEMPLATE.md delete mode 100644 vendor/gopkg.in/VividCortex/ewma.v1/.github/PULL_REQUEST_TEMPLATE.md delete mode 100644 vendor/gopkg.in/VividCortex/ewma.v1/.gitignore delete mode 100644 vendor/gopkg.in/VividCortex/ewma.v1/LICENSE delete mode 100644 vendor/gopkg.in/VividCortex/ewma.v1/README.md delete mode 100644 vendor/gopkg.in/VividCortex/ewma.v1/ewma.go delete mode 100644 vendor/gopkg.in/VividCortex/ewma.v1/ewma_test.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/.gitignore delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/.travis.yml delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.lock delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.toml delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/LICENSE delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/README.md delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/element.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/element_test.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/pb.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/pb_test.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/preset.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/reader.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/reader_test.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/speed.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/template.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/template_test.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_appengine.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_bsd.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_linux.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_nix.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_solaris.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_win.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_x.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/util.go delete mode 100644 vendor/gopkg.in/cheggaaa/pb.v2/util_test.go delete mode 100644 vendor/gopkg.in/fatih/color.v1/.travis.yml delete mode 100644 vendor/gopkg.in/fatih/color.v1/LICENSE.md delete mode 100644 vendor/gopkg.in/fatih/color.v1/README.md delete mode 100644 vendor/gopkg.in/fatih/color.v1/color.go delete mode 100644 vendor/gopkg.in/fatih/color.v1/color_test.go delete mode 100644 vendor/gopkg.in/fatih/color.v1/doc.go delete mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/.travis.yml delete mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/LICENSE delete mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/README.md delete mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/_example/escape-seq/main.go delete mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/_example/logrus/main.go delete mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/_example/title/main.go delete mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/colorable_appengine.go delete mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/colorable_others.go delete mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/colorable_test.go delete mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/colorable_windows.go delete mode 100644 vendor/gopkg.in/mattn/go-colorable.v0/noncolorable.go delete mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/.travis.yml delete mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/LICENSE delete mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/README.md delete mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/doc.go delete mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/example_test.go delete mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_appengine.go delete mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_bsd.go delete mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux.go delete mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux_ppc64x.go delete mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_others.go delete mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_others_test.go delete mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_solaris.go delete mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows.go delete mode 100644 vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows_test.go delete mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/.travis.yml delete mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/LICENSE delete mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/README.mkd delete mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/runewidth.go delete mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_js.go delete mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_posix.go delete mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_test.go delete mode 100644 vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_windows.go diff --git a/Gopkg.lock b/Gopkg.lock index 5893580f0..336bd3e79 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -13,12 +13,6 @@ revision = "2f1ce7a837dcb8da3ec595b1dac9d0632f0f99e8" version = "v1.3.1" -[[projects]] - name = "github.com/cheggaaa/pb" - packages = ["."] - revision = "c112833d014c77e8bde723fd0158e3156951639f" - version = "v2.0.6" - [[projects]] name = "github.com/davecgh/go-spew" packages = ["spew"] @@ -79,18 +73,6 @@ revision = "766956aceb8ff49664065ae50bef0ae8a0a83ec4" version = "v1.0.2" -[[projects]] - name = "github.com/mattn/go-colorable" - packages = ["."] - revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072" - version = "v0.0.9" - -[[projects]] - name = "github.com/mattn/go-isatty" - packages = ["."] - revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" - version = "v0.0.3" - [[projects]] name = "github.com/mattn/go-runewidth" packages = ["."] @@ -181,30 +163,12 @@ packages = ["go/ast/astutil","imports"] revision = "b451b9aaee4dcf75f9f28cddb69b9d0ed17a9752" -[[projects]] - name = "gopkg.in/VividCortex/ewma.v1" - packages = ["."] - revision = "b24eb346a94c3ba12c1da1e564dbac1b498a77ce" - version = "v1.1.1" - [[projects]] branch = "v1" name = "gopkg.in/check.v1" packages = ["."] revision = "20d25e2804050c1cd24a7eea1e7a6447dd0e74ec" -[[projects]] - name = "gopkg.in/cheggaaa/pb.v2" - packages = ["termutil"] - revision = "c112833d014c77e8bde723fd0158e3156951639f" - version = "v2.0.6" - -[[projects]] - name = "gopkg.in/fatih/color.v1" - packages = ["."] - revision = "570b54cabe6b8eb0bc2dfce68d964677d63b5260" - version = "v1.5.0" - [[projects]] name = "gopkg.in/fatih/set.v0" packages = ["."] @@ -217,24 +181,6 @@ packages = ["collections/prque"] revision = "8dcd6a7f4951f6ff3ee9cbb919a06d8925822e57" -[[projects]] - name = "gopkg.in/mattn/go-colorable.v0" - packages = ["."] - revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072" - version = "v0.0.9" - -[[projects]] - name = "gopkg.in/mattn/go-isatty.v0" - packages = ["."] - revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" - version = "v0.0.3" - -[[projects]] - name = "gopkg.in/mattn/go-runewidth.v0" - packages = ["."] - revision = "9e777a8366cce605130a531d2cd6363d07ad7317" - version = "v0.0.2" - [[projects]] name = "gopkg.in/sourcemap.v1" packages = [".","base64vlq"] @@ -249,6 +195,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "cf961bcfe2cc1919ed1448c844efdd74014f76f9c076ff85cf397b7185a67829" + inputs-digest = "803cc2cdca758526169a444788e436c4d905150702b80d333138703a813ba169" solver-name = "gps-cdcl" solver-version = 1 diff --git a/vendor/github.com/cheggaaa/pb/.gitignore b/vendor/github.com/cheggaaa/pb/.gitignore deleted file mode 100644 index 48b8bf907..000000000 --- a/vendor/github.com/cheggaaa/pb/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vendor/ diff --git a/vendor/github.com/cheggaaa/pb/.travis.yml b/vendor/github.com/cheggaaa/pb/.travis.yml deleted file mode 100644 index 7d3bc2399..000000000 --- a/vendor/github.com/cheggaaa/pb/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: go -go: -- 1.7 -- 1.8 -sudo: false -gobuild_args: -v -race -os: -- linux -- osx -before_install: - - go get github.com/mattn/goveralls -script: - - $HOME/gopath/bin/goveralls -service=travis-ci -ignore=termutil/* diff --git a/vendor/github.com/cheggaaa/pb/Gopkg.lock b/vendor/github.com/cheggaaa/pb/Gopkg.lock deleted file mode 100644 index fd90c4b6a..000000000 --- a/vendor/github.com/cheggaaa/pb/Gopkg.lock +++ /dev/null @@ -1,63 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - name = "github.com/mattn/go-colorable" - packages = ["."] - revision = "ed8eb9e318d7a84ce5915b495b7d35e0cfe7b5a8" - version = "v0.0.6" - -[[projects]] - name = "github.com/mattn/go-isatty" - packages = ["."] - revision = "3a115632dcd687f9c8cd01679c83a06a0e21c1f3" - version = "v0.0.1" - -[[projects]] - branch = "master" - name = "golang.org/x/sys" - packages = ["unix"] - revision = "b90f89a1e7a9c1f6b918820b3daa7f08488c8594" - -[[projects]] - name = "gopkg.in/VividCortex/ewma.v1" - packages = ["."] - revision = "2f8aa9741ab4b5b80945c750b871131b88ef5b7f" - version = "v1.0" - -[[projects]] - name = "gopkg.in/cheggaaa/pb.v2" - packages = ["termutil"] - revision = "180c76fdb3025713f501cd481e47810a9c715bd7" - version = "v2.0.1" - -[[projects]] - name = "gopkg.in/fatih/color.v1" - packages = ["."] - revision = "570b54cabe6b8eb0bc2dfce68d964677d63b5260" - version = "v1.5.0" - -[[projects]] - name = "gopkg.in/mattn/go-colorable.v0" - packages = ["."] - revision = "d228849504861217f796da67fae4f6e347643f15" - version = "v0.0.7" - -[[projects]] - name = "gopkg.in/mattn/go-isatty.v0" - packages = ["."] - revision = "fc9e8d8ef48496124e79ae0df75490096eccf6fe" - version = "v0.0.2" - -[[projects]] - name = "gopkg.in/mattn/go-runewidth.v0" - packages = ["."] - revision = "9e777a8366cce605130a531d2cd6363d07ad7317" - version = "v0.0.2" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "cf10fbfc96962122f1a56c1752a1d5dab64799ffedc58460e1ab1465d2bef5e2" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/cheggaaa/pb/Gopkg.toml b/vendor/github.com/cheggaaa/pb/Gopkg.toml deleted file mode 100644 index d5f2fef13..000000000 --- a/vendor/github.com/cheggaaa/pb/Gopkg.toml +++ /dev/null @@ -1,91 +0,0 @@ - -## Gopkg.toml example (these lines may be deleted) - -## "metadata" defines metadata about the project that could be used by other independent -## systems. The metadata defined here will be ignored by dep. -# [metadata] -# key1 = "value that convey data to other systems" -# system1-data = "value that is used by a system" -# system2-data = "value that is used by another system" - -## "required" lists a set of packages (not projects) that must be included in -## Gopkg.lock. This list is merged with the set of packages imported by the current -## project. Use it when your project needs a package it doesn't explicitly import - -## including "main" packages. -# required = ["github.com/user/thing/cmd/thing"] - -## "ignored" lists a set of packages (not projects) that are ignored when -## dep statically analyzes source code. Ignored packages can be in this project, -## or in a dependency. -# ignored = ["github.com/user/project/badpkg"] - -## Constraints are rules for how directly imported projects -## may be incorporated into the depgraph. They are respected by -## dep whether coming from the Gopkg.toml of the current project or a dependency. -# [[constraint]] -## Required: the root import path of the project being constrained. -# name = "github.com/user/project" -# -## Recommended: the version constraint to enforce for the project. -## Only one of "branch", "version" or "revision" can be specified. -# version = "1.0.0" -# branch = "master" -# revision = "abc123" -# -## Optional: an alternate location (URL or import path) for the project's source. -# source = "https://github.com/myfork/package.git" -# -## "metadata" defines metadata about the dependency or override that could be used -## by other independent systems. The metadata defined here will be ignored by dep. -# [metadata] -# key1 = "value that convey data to other systems" -# system1-data = "value that is used by a system" -# system2-data = "value that is used by another system" - -## Overrides have the same structure as [[constraint]], but supersede all -## [[constraint]] declarations from all projects. Only [[override]] from -## the current project's are applied. -## -## Overrides are a sledgehammer. Use them only as a last resort. -# [[override]] -## Required: the root import path of the project being constrained. -# name = "github.com/user/project" -# -## Optional: specifying a version constraint override will cause all other -## constraints on this project to be ignored; only the overridden constraint -## need be satisfied. -## Again, only one of "branch", "version" or "revision" can be specified. -# version = "1.0.0" -# branch = "master" -# revision = "abc123" -# -## Optional: specifying an alternate source location as an override will -## enforce that the alternate location is used for that project, regardless of -## what source location any dependent projects specify. -# source = "https://github.com/myfork/package.git" - - - -[[constraint]] - name = "gopkg.in/VividCortex/ewma.v1" - version = "1.0.0" - -[[constraint]] - name = "gopkg.in/cheggaaa/pb.v2" - version = "2.0.1" - -[[constraint]] - name = "gopkg.in/fatih/color.v1" - version = "1.5.0" - -[[constraint]] - name = "gopkg.in/mattn/go-colorable.v0" - version = "0.0.7" - -[[constraint]] - name = "gopkg.in/mattn/go-isatty.v0" - version = "0.0.2" - -[[constraint]] - name = "gopkg.in/mattn/go-runewidth.v0" - version = "0.0.2" diff --git a/vendor/github.com/cheggaaa/pb/LICENSE b/vendor/github.com/cheggaaa/pb/LICENSE deleted file mode 100644 index 511970333..000000000 --- a/vendor/github.com/cheggaaa/pb/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) 2012-2015, Sergey Cherepanov -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/github.com/cheggaaa/pb/README.md b/vendor/github.com/cheggaaa/pb/README.md deleted file mode 100644 index 907124e19..000000000 --- a/vendor/github.com/cheggaaa/pb/README.md +++ /dev/null @@ -1,70 +0,0 @@ -# Terminal progress bar for Go - -[![Coverage Status](https://coveralls.io/repos/github/cheggaaa/pb/badge.svg?branch=v2)](https://coveralls.io/github/cheggaaa/pb?branch=v2) - -### It's beta, some features may be changed - -This is proposal for the second version of progress bar -- based on text/template -- can take custom elements -- using colors is easy - -## Installation - -``` -go get gopkg.in/cheggaaa/pb.v2 -``` - -## Usage - -```Go -package main - -import ( - "gopkg.in/cheggaaa/pb.v2" - "time" -) - -func main() { - simple() - fromPreset() - customTemplate(`Custom template: {{counters . }}`) - customTemplate(`{{ red "With colors:" }} {{bar . | green}} {{speed . | blue }}`) - customTemplate(`{{ red "With funcs:" }} {{ bar . "<" "-" (cycle . "↖" "↗" "↘" "↙" ) "." ">"}} {{speed . | rndcolor }}`) - customTemplate(`{{ bar . "[<" "·····•·····" (rnd "ᗧ" "◔" "◕" "◷" ) "•" ">]"}}`) -} - -func simple() { - count := 1000 - bar := pb.StartNew(count) - for i := 0; i < count; i++ { - bar.Increment() - time.Sleep(time.Millisecond * 2) - } - bar.Finish() -} - -func fromPreset() { - count := 1000 - //bar := pb.Default.Start(total) - //bar := pb.Simple.Start(total) - bar := pb.Full.Start(count) - defer bar.Finish() - bar.Set("prefix", "fromPreset(): ") - for i := 0; i < count/2; i++ { - bar.Add(2) - time.Sleep(time.Millisecond * 4) - } -} - -func customTemplate(tmpl string) { - count := 1000 - bar := pb.ProgressBarTemplate(tmpl).Start(count) - defer bar.Finish() - for i := 0; i < count/2; i++ { - bar.Add(2) - time.Sleep(time.Millisecond * 4) - } -} - -``` \ No newline at end of file diff --git a/vendor/github.com/cheggaaa/pb/element.go b/vendor/github.com/cheggaaa/pb/element.go deleted file mode 100644 index 965183fe7..000000000 --- a/vendor/github.com/cheggaaa/pb/element.go +++ /dev/null @@ -1,290 +0,0 @@ -package pb - -import ( - "bytes" - "fmt" - "math" - "sync" - "time" -) - -const ( - adElPlaceholder = "%_ad_el_%" - adElPlaceholderLen = len(adElPlaceholder) -) - -var ( - defaultBarEls = [5]string{"[", "-", ">", "_", "]"} -) - -// Element is an interface for bar elements -type Element interface { - ProgressElement(state *State, args ...string) string -} - -// ElementFunc type implements Element interface and created for simplify elements -type ElementFunc func(state *State, args ...string) string - -// ProgressElement just call self func -func (e ElementFunc) ProgressElement(state *State, args ...string) string { - return e(state, args...) -} - -var elementsM sync.Mutex - -var elements = map[string]Element{ - "percent": ElementPercent, - "counters": ElementCounters, - "bar": adaptiveWrap(ElementBar), - "speed": ElementSpeed, - "rtime": ElementRemainingTime, - "etime": ElementElapsedTime, - "string": ElementString, - "cycle": ElementCycle, -} - -// RegisterElement give you a chance to use custom elements -func RegisterElement(name string, el Element, adaptive bool) { - if adaptive { - el = adaptiveWrap(el) - } - elementsM.Lock() - elements[name] = el - elementsM.Unlock() -} - -type argsHelper []string - -func (args argsHelper) getOr(n int, value string) string { - if len(args) > n { - return args[n] - } - return value -} - -func (args argsHelper) getNotEmptyOr(n int, value string) (v string) { - if v = args.getOr(n, value); v == "" { - return value - } - return -} - -func adaptiveWrap(el Element) Element { - return ElementFunc(func(state *State, args ...string) string { - state.recalc = append(state.recalc, ElementFunc(func(s *State, _ ...string) (result string) { - s.adaptive = true - result = el.ProgressElement(s, args...) - s.adaptive = false - return - })) - return adElPlaceholder - }) -} - -// ElementPercent shows current percent of progress. -// Optionally can take one or two string arguments. -// First string will be used as value for format float64, default is "%.02f%%". -// Second string will be used when percent can't be calculated, default is "?%" -// In template use as follows: {{percent .}} or {{percent . "%.03f%%"}} or {{percent . "%.03f%%" "?"}} -var ElementPercent ElementFunc = func(state *State, args ...string) string { - argsh := argsHelper(args) - if state.Total() > 0 { - return fmt.Sprintf( - argsh.getNotEmptyOr(0, "%.02f%%"), - float64(state.Value())/(float64(state.Total())/float64(100)), - ) - } - return argsh.getOr(1, "?%") -} - -// ElementCounters shows current and total values. -// Optionally can take one or two string arguments. -// First string will be used as format value when Total is present (>0). Default is "%s / %s" -// Second string will be used when total <= 0. Default is "%[1]s" -// In template use as follows: {{counters .}} or {{counters . "%s/%s"}} or {{counters . "%s/%s" "%s/?"}} -var ElementCounters ElementFunc = func(state *State, args ...string) string { - var f string - if state.Total() > 0 { - f = argsHelper(args).getNotEmptyOr(0, "%s / %s") - } else { - f = argsHelper(args).getNotEmptyOr(1, "%[1]s") - } - return fmt.Sprintf(f, state.Format(state.Value()), state.Format(state.Total())) -} - -type elementKey int - -const ( - barObj elementKey = iota - speedObj - cycleObj -) - -type bar struct { - eb [5][]byte // elements in bytes - cc [5]int // cell counts - buf *bytes.Buffer -} - -func (p *bar) write(state *State, eln, width int) int { - repeat := width / p.cc[eln] - for i := 0; i < repeat; i++ { - p.buf.Write(p.eb[eln]) - } - StripStringToBuffer(string(p.eb[eln]), width%p.cc[eln], p.buf) - return width -} - -func getProgressObj(state *State, args ...string) (p *bar) { - var ok bool - if p, ok = state.Get(barObj).(*bar); !ok { - p = &bar{ - buf: bytes.NewBuffer(nil), - } - state.Set(barObj, p) - } - argsH := argsHelper(args) - for i := range p.eb { - arg := argsH.getNotEmptyOr(i, defaultBarEls[i]) - if string(p.eb[i]) != arg { - p.cc[i] = CellCount(arg) - p.eb[i] = []byte(arg) - if p.cc[i] == 0 { - p.cc[i] = 1 - p.eb[i] = []byte(" ") - } - } - } - return -} - -// ElementBar make progress bar view [-->__] -// Optionally can take up to 5 string arguments. Defaults is "[", "-", ">", "_", "]" -// In template use as follows: {{bar . }} or {{bar . "<" "oOo" "|" "~" ">"}} -// Color args: {{bar . (red "[") (green "-") ... -var ElementBar ElementFunc = func(state *State, args ...string) string { - // init - var p = getProgressObj(state, args...) - - total, value := state.Total(), state.Value() - if total < 0 { - total = -total - } - if value < 0 { - value = -value - } - - // check for overflow - if total != 0 && value > total { - total = value - } - - p.buf.Reset() - - var widthLeft = state.AdaptiveElWidth() - if widthLeft <= 0 || !state.IsAdaptiveWidth() { - widthLeft = 30 - } - - // write left border - if p.cc[0] < widthLeft { - widthLeft -= p.write(state, 0, p.cc[0]) - } else { - p.write(state, 0, widthLeft) - return p.buf.String() - } - - // check right border size - if p.cc[4] < widthLeft { - // write later - widthLeft -= p.cc[4] - } else { - p.write(state, 4, widthLeft) - return p.buf.String() - } - - var curCount int - - if total > 0 { - // calculate count of currenct space - curCount = int(math.Ceil((float64(value) / float64(total)) * float64(widthLeft))) - } - - // write bar - if total == value && state.IsFinished() { - widthLeft -= p.write(state, 1, curCount) - } else if toWrite := curCount - p.cc[2]; toWrite > 0 { - widthLeft -= p.write(state, 1, toWrite) - widthLeft -= p.write(state, 2, p.cc[2]) - } else if curCount > 0 { - widthLeft -= p.write(state, 2, curCount) - } - if widthLeft > 0 { - widthLeft -= p.write(state, 3, widthLeft) - } - // write right border - p.write(state, 4, p.cc[4]) - // cut result and return string - return p.buf.String() -} - -// ElementRemainingTime calculates remaining time based on speed (EWMA) -// Optionally can take one or two string arguments. -// First string will be used as value for format time duration string, default is "%s". -// Second string will be used when bar finished and value indicates elapsed time, default is "%s" -// Third string will be used when value not available, default is "?" -// In template use as follows: {{rtime .}} or {{rtime . "%s remain"}} or {{rtime . "%s remain" "%s total" "???"}} -var ElementRemainingTime ElementFunc = func(state *State, args ...string) string { - var rts string - sp := getSpeedObj(state).value(state) - if !state.IsFinished() { - if sp > 0 { - remain := float64(state.Total() - state.Value()) - remainDur := time.Duration(remain/sp) * time.Second - rts = remainDur.String() - } else { - return argsHelper(args).getOr(2, "?") - } - } else { - rts = state.Time().Truncate(time.Second).Sub(state.StartTime().Truncate(time.Second)).String() - return fmt.Sprintf(argsHelper(args).getOr(1, "%s"), rts) - } - return fmt.Sprintf(argsHelper(args).getOr(0, "%s"), rts) -} - -// ElementElapsedTime shows elapsed time -// Optionally cat take one argument - it's format for time string. -// In template use as follows: {{etime .}} or {{etime . "%s elapsed"}} -var ElementElapsedTime ElementFunc = func(state *State, args ...string) string { - etm := state.Time().Truncate(time.Second).Sub(state.StartTime().Truncate(time.Second)) - return fmt.Sprintf(argsHelper(args).getOr(0, "%s"), etm.String()) -} - -// ElementString get value from bar by given key and print them -// bar.Set("myKey", "string to print") -// In template use as follows: {{string . "myKey"}} -var ElementString ElementFunc = func(state *State, args ...string) string { - if len(args) == 0 { - return "" - } - v := state.Get(args[0]) - if v == nil { - return "" - } - return fmt.Sprint(v) -} - -// ElementCycle return next argument for every call -// In template use as follows: {{cycle . "1" "2" "3"}} -// Or mix width other elements: {{ bar . "" "" (cycle . "↖" "↗" "↘" "↙" )}} -var ElementCycle ElementFunc = func(state *State, args ...string) string { - if len(args) == 0 { - return "" - } - n, _ := state.Get(cycleObj).(int) - if n >= len(args) { - n = 0 - } - state.Set(cycleObj, n+1) - return args[n] -} diff --git a/vendor/github.com/cheggaaa/pb/element_test.go b/vendor/github.com/cheggaaa/pb/element_test.go deleted file mode 100644 index d572c4a6a..000000000 --- a/vendor/github.com/cheggaaa/pb/element_test.go +++ /dev/null @@ -1,278 +0,0 @@ -package pb - -import ( - "fmt" - "strings" - "testing" - "time" - - "gopkg.in/fatih/color.v1" -) - -func testState(total, value int64, maxWidth int, bools ...bool) (s *State) { - s = &State{ - total: total, - current: value, - adaptiveElWidth: maxWidth, - ProgressBar: new(ProgressBar), - } - if len(bools) > 0 { - s.Set(Bytes, bools[0]) - } - if len(bools) > 1 && bools[1] { - s.adaptive = true - } - return -} - -func testElementBarString(t *testing.T, state *State, el Element, want string, args ...string) { - if state.ProgressBar == nil { - state.ProgressBar = new(ProgressBar) - } - res := el.ProgressElement(state, args...) - if res != want { - t.Errorf("Unexpected result: '%s'; want: '%s'", res, want) - } - if state.IsAdaptiveWidth() && state.AdaptiveElWidth() != CellCount(res) { - t.Errorf("Unepected width: %d; want: %d", CellCount(res), state.AdaptiveElWidth()) - } -} - -func TestElementPercent(t *testing.T) { - testElementBarString(t, testState(100, 50, 0), ElementPercent, "50.00%") - testElementBarString(t, testState(100, 50, 0), ElementPercent, "50 percent", "%v percent") - testElementBarString(t, testState(0, 50, 0), ElementPercent, "?%") - testElementBarString(t, testState(0, 50, 0), ElementPercent, "unkn", "%v%%", "unkn") -} - -func TestElementCounters(t *testing.T) { - testElementBarString(t, testState(100, 50, 0), ElementCounters, "50 / 100") - testElementBarString(t, testState(100, 50, 0), ElementCounters, "50 of 100", "%s of %s") - testElementBarString(t, testState(100, 50, 0, true), ElementCounters, "50 B of 100 B", "%s of %s") - testElementBarString(t, testState(100, 50, 0, true), ElementCounters, "50 B / 100 B") - testElementBarString(t, testState(0, 50, 0, true), ElementCounters, "50 B") - testElementBarString(t, testState(0, 50, 0, true), ElementCounters, "50 B / ?", "", "%[1]s / ?") -} - -func TestElementBar(t *testing.T) { - // short - testElementBarString(t, testState(100, 50, 1, false, true), ElementBar, "[") - testElementBarString(t, testState(100, 50, 2, false, true), ElementBar, "[]") - testElementBarString(t, testState(100, 50, 3, false, true), ElementBar, "[>]") - testElementBarString(t, testState(100, 50, 4, false, true), ElementBar, "[>_]") - testElementBarString(t, testState(100, 50, 5, false, true), ElementBar, "[->_]") - // middle - testElementBarString(t, testState(100, 50, 10, false, true), ElementBar, "[--->____]") - testElementBarString(t, testState(100, 50, 10, false, true), ElementBar, "<--->____>", "<", "", "", "", ">") - // finished - st := testState(100, 100, 10, false, true) - st.finished = true - testElementBarString(t, st, ElementBar, "[--------]") - // empty color - st = testState(100, 50, 10, false, true) - st.Set(Terminal, true) - color.NoColor = false - testElementBarString(t, st, ElementBar, " --->____]", color.RedString("%s", "")) - // empty - testElementBarString(t, testState(0, 50, 10, false, true), ElementBar, "[________]") - // full - testElementBarString(t, testState(20, 20, 10, false, true), ElementBar, "[------->]") - // everflow - testElementBarString(t, testState(20, 50, 10, false, true), ElementBar, "[------->]") - // small width - testElementBarString(t, testState(20, 50, 2, false, true), ElementBar, "[]") - testElementBarString(t, testState(20, 50, 1, false, true), ElementBar, "[") - // negative counters - testElementBarString(t, testState(-50, -150, 10, false, true), ElementBar, "[------->]") - testElementBarString(t, testState(-150, -50, 10, false, true), ElementBar, "[-->_____]") - testElementBarString(t, testState(50, -150, 10, false, true), ElementBar, "[------->]") - testElementBarString(t, testState(-50, 150, 10, false, true), ElementBar, "[------->]") - // long entities / unicode - f1 := []string{"進捗|", "многобайт", "active", "пусто", "|end"} - testElementBarString(t, testState(100, 50, 1, false, true), ElementBar, " ", f1...) - testElementBarString(t, testState(100, 50, 3, false, true), ElementBar, "進 ", f1...) - testElementBarString(t, testState(100, 50, 4, false, true), ElementBar, "進捗", f1...) - testElementBarString(t, testState(100, 50, 29, false, true), ElementBar, "進捗|многactiveпустопусто|end", f1...) - testElementBarString(t, testState(100, 50, 11, false, true), ElementBar, "進捗|aп|end", f1...) - - // unicode - f2 := []string{"⚑", "⚒", "⚟", "⟞", "⚐"} - testElementBarString(t, testState(100, 50, 10, false, true), ElementBar, "⚑⚒⚒⚒⚟⟞⟞⟞⟞⚐", f2...) - - // no adaptive - testElementBarString(t, testState(0, 50, 10), ElementBar, "[____________________________]") - - var formats = [][]string{ - []string{}, - f1, f2, - } - - // all widths / extreme values - // check for panic and correct width - for _, f := range formats { - for tt := int64(-2); tt < 12; tt++ { - for v := int64(-2); v < 12; v++ { - state := testState(tt, v, 0, false, true) - for w := -2; w < 20; w++ { - state.adaptiveElWidth = w - res := ElementBar(state, f...) - var we = w - if we <= 0 { - we = 30 - } - if CellCount(res) != we { - t.Errorf("Unexpected len(%d): '%s'", we, res) - } - } - } - } - } -} - -func TestElementSpeed(t *testing.T) { - var state = testState(1000, 0, 0, false) - state.time = time.Now() - for i := int64(0); i < 10; i++ { - state.id = uint64(i) + 1 - state.current += 42 - state.time = state.time.Add(time.Second) - state.finished = i == 9 - if state.finished { - state.current += 100 - } - r := ElementSpeed(state) - r2 := ElementSpeed(state) - if r != r2 { - t.Errorf("Must be the same: '%s' vs '%s'", r, r2) - } - if i < 1 { - // do not calc first result - if w := "? p/s"; r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - } else if state.finished { - if w := "58 p/s"; r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - state.time = state.time.Add(-time.Hour) - r = ElementSpeed(state) - if w := "? p/s"; r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - } else { - if w := "42 p/s"; r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - } - } -} - -func TestElementRemainingTime(t *testing.T) { - var state = testState(100, 0, 0, false) - state.time = time.Now() - state.startTime = state.time - for i := int64(0); i < 10; i++ { - state.id = uint64(i) + 1 - state.time = state.time.Add(time.Second) - state.finished = i == 9 - r := ElementRemainingTime(state) - if i < 1 { - // do not calc first two results - if w := "?"; r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - } else if state.finished { - // final elapsed time - if w := "10s"; r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - } else { - w := fmt.Sprintf("%ds", 10-i) - if r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - } - state.current += 10 - } -} - -func TestElementElapsedTime(t *testing.T) { - var state = testState(1000, 0, 0, false) - state.startTime = time.Now() - state.time = state.startTime - for i := int64(0); i < 10; i++ { - r := ElementElapsedTime(state) - if w := fmt.Sprintf("%ds", i); r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - state.time = state.time.Add(time.Second) - } -} - -func TestElementString(t *testing.T) { - var state = testState(0, 0, 0, false) - testElementBarString(t, state, ElementString, "", "myKey") - state.Set("myKey", "my value") - testElementBarString(t, state, ElementString, "my value", "myKey") - state.Set("myKey", "my value1") - testElementBarString(t, state, ElementString, "my value1", "myKey") - testElementBarString(t, state, ElementString, "") -} - -func TestElementCycle(t *testing.T) { - var state = testState(0, 0, 0, false) - testElementBarString(t, state, ElementCycle, "") - testElementBarString(t, state, ElementCycle, "1", "1", "2", "3") - testElementBarString(t, state, ElementCycle, "2", "1", "2", "3") - testElementBarString(t, state, ElementCycle, "3", "1", "2", "3") - testElementBarString(t, state, ElementCycle, "1", "1", "2", "3") - testElementBarString(t, state, ElementCycle, "2", "1", "2") - testElementBarString(t, state, ElementCycle, "1", "1", "2") -} - -func TestAdaptiveWrap(t *testing.T) { - var state = testState(0, 0, 0, false) - state.id = 1 - state.Set("myKey", "my value") - el := adaptiveWrap(ElementString) - testElementBarString(t, state, el, adElPlaceholder, "myKey") - if v := state.recalc[0].ProgressElement(state); v != "my value" { - t.Errorf("Unexpected result: %s", v) - } - state.id = 2 - testElementBarString(t, state, el, adElPlaceholder, "myKey1") - state.Set("myKey", "my value1") - if v := state.recalc[0].ProgressElement(state); v != "my value1" { - t.Errorf("Unexpected result: %s", v) - } -} - -func TestRegisterElement(t *testing.T) { - var testEl ElementFunc = func(state *State, args ...string) string { - return strings.Repeat("*", state.AdaptiveElWidth()) - } - RegisterElement("testEl", testEl, true) - result := ProgressBarTemplate(`{{testEl . }}`).New(0).SetWidth(5).String() - if result != "*****" { - t.Errorf("Unexpected result: '%v'", result) - } -} - -func BenchmarkBar(b *testing.B) { - var formats = map[string][]string{ - "simple": []string{".", ".", ".", ".", "."}, - "unicode": []string{"⚑", "⚒", "⚟", "⟞", "⚐"}, - "color": []string{color.RedString("%s", "."), color.RedString("%s", "."), color.RedString("%s", "."), color.RedString("%s", "."), color.RedString("%s", ".")}, - "long": []string{"..", "..", "..", "..", ".."}, - "longunicode": []string{"⚑⚑", "⚒⚒", "⚟⚟", "⟞⟞", "⚐⚐"}, - } - for name, args := range formats { - state := testState(100, 50, 100, false, true) - b.Run(name, func(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - ElementBar(state, args...) - } - }) - } -} diff --git a/vendor/github.com/cheggaaa/pb/pb.go b/vendor/github.com/cheggaaa/pb/pb.go deleted file mode 100644 index c8e7b52ae..000000000 --- a/vendor/github.com/cheggaaa/pb/pb.go +++ /dev/null @@ -1,540 +0,0 @@ -package pb - -import ( - "bytes" - "fmt" - "io" - "os" - "strconv" - "strings" - "sync" - "sync/atomic" - "text/template" - "time" - - "gopkg.in/cheggaaa/pb.v2/termutil" - "gopkg.in/mattn/go-colorable.v0" - "gopkg.in/mattn/go-isatty.v0" -) - -// Version of ProgressBar library -const Version = "2.0.6" - -type key int - -const ( - // Bytes means we're working with byte sizes. Numbers will print as Kb, Mb, etc - // bar.Set(pb.Bytes, true) - Bytes key = 1 << iota - - // Terminal means we're will print to terminal and can use ascii sequences - // Also we're will try to use terminal width - Terminal - - // Static means progress bar will not update automaticly - Static - - // ReturnSymbol - by default in terminal mode it's '\r' - ReturnSymbol - - // Color by default is true when output is tty, but you can set to false for disabling colors - Color -) - -const ( - defaultBarWidth = 100 - defaultRefreshRate = time.Millisecond * 200 -) - -// New creates new ProgressBar object -func New(total int) *ProgressBar { - return New64(int64(total)) -} - -// New64 creates new ProgressBar object using int64 as total -func New64(total int64) *ProgressBar { - pb := new(ProgressBar) - return pb.SetTotal(total) -} - -// StartNew starts new ProgressBar with Default template -func StartNew(total int) *ProgressBar { - return New(total).Start() -} - -// Start64 starts new ProgressBar with Default template. Using int64 as total. -func Start64(total int64) *ProgressBar { - return New64(total).Start() -} - -var ( - terminalWidth = termutil.TerminalWidth - isTerminal = isatty.IsTerminal - isCygwinTerminal = isatty.IsCygwinTerminal -) - -// ProgressBar is the main object of bar -type ProgressBar struct { - current, total int64 - width int - mu sync.RWMutex - rm sync.Mutex - vars map[interface{}]interface{} - elements map[string]Element - output io.Writer - coutput io.Writer - nocoutput io.Writer - startTime time.Time - refreshRate time.Duration - tmpl *template.Template - state *State - buf *bytes.Buffer - ticker *time.Ticker - finish chan struct{} - finished bool - configured bool - err error -} - -func (pb *ProgressBar) configure() { - if pb.configured { - return - } - pb.configured = true - - if pb.vars == nil { - pb.vars = make(map[interface{}]interface{}) - } - if pb.output == nil { - pb.output = os.Stderr - } - - if pb.tmpl == nil { - pb.tmpl, pb.err = getTemplate(string(Default)) - if pb.err != nil { - return - } - } - if pb.vars[Terminal] == nil { - if f, ok := pb.output.(*os.File); ok { - if isTerminal(f.Fd()) || isCygwinTerminal(f.Fd()) { - pb.vars[Terminal] = true - } - } - } - if pb.vars[ReturnSymbol] == nil { - if tm, ok := pb.vars[Terminal].(bool); ok && tm { - pb.vars[ReturnSymbol] = "\r" - } - } - if pb.vars[Color] == nil { - if tm, ok := pb.vars[Terminal].(bool); ok && tm { - pb.vars[Color] = true - } - } - if pb.refreshRate == 0 { - pb.refreshRate = defaultRefreshRate - } - if f, ok := pb.output.(*os.File); ok { - pb.coutput = colorable.NewColorable(f) - } else { - pb.coutput = pb.output - } - pb.nocoutput = colorable.NewNonColorable(pb.output) -} - -// Start starts the bar -func (pb *ProgressBar) Start() *ProgressBar { - pb.mu.Lock() - defer pb.mu.Unlock() - if pb.finish != nil { - return pb - } - pb.configure() - pb.finished = false - pb.state = nil - pb.startTime = time.Now() - if st, ok := pb.vars[Static].(bool); ok && st { - return pb - } - pb.finish = make(chan struct{}) - pb.ticker = time.NewTicker(pb.refreshRate) - go pb.writer(pb.finish) - return pb -} - -func (pb *ProgressBar) writer(finish chan struct{}) { - for { - select { - case <-pb.ticker.C: - pb.write(false) - case <-finish: - pb.ticker.Stop() - pb.write(true) - finish <- struct{}{} - return - } - } -} - -// Write performs write to the output -func (pb *ProgressBar) Write() *ProgressBar { - pb.mu.RLock() - finished := pb.finished - pb.mu.RUnlock() - pb.write(finished) - return pb -} - -func (pb *ProgressBar) write(finish bool) { - result, width := pb.render() - if pb.Err() != nil { - return - } - if pb.GetBool(Terminal) { - if r := (width - CellCount(result)); r > 0 { - result += strings.Repeat(" ", r) - } - } - if ret, ok := pb.Get(ReturnSymbol).(string); ok { - result = ret + result - if finish && ret == "\r" { - result += "\n" - } - } - if pb.GetBool(Color) { - pb.coutput.Write([]byte(result)) - } else { - pb.nocoutput.Write([]byte(result)) - } -} - -// Total return current total bar value -func (pb *ProgressBar) Total() int64 { - return atomic.LoadInt64(&pb.total) -} - -// SetTotal sets the total bar value -func (pb *ProgressBar) SetTotal(value int64) *ProgressBar { - atomic.StoreInt64(&pb.total, value) - return pb -} - -// SetCurrent sets the current bar value -func (pb *ProgressBar) SetCurrent(value int64) *ProgressBar { - atomic.StoreInt64(&pb.current, value) - return pb -} - -// Current return current bar value -func (pb *ProgressBar) Current() int64 { - return atomic.LoadInt64(&pb.current) -} - -// Add adding given int64 value to bar value -func (pb *ProgressBar) Add64(value int64) *ProgressBar { - atomic.AddInt64(&pb.current, value) - return pb -} - -// Add adding given int value to bar value -func (pb *ProgressBar) Add(value int) *ProgressBar { - return pb.Add64(int64(value)) -} - -// Increment atomically increments the progress -func (pb *ProgressBar) Increment() *ProgressBar { - return pb.Add64(1) -} - -// Set sets any value by any key -func (pb *ProgressBar) Set(key, value interface{}) *ProgressBar { - pb.mu.Lock() - defer pb.mu.Unlock() - if pb.vars == nil { - pb.vars = make(map[interface{}]interface{}) - } - pb.vars[key] = value - return pb -} - -// Get return value by key -func (pb *ProgressBar) Get(key interface{}) interface{} { - pb.mu.RLock() - defer pb.mu.RUnlock() - if pb.vars == nil { - return nil - } - return pb.vars[key] -} - -// GetBool return value by key and try to convert there to boolean -// If value doesn't set or not boolean - return false -func (pb *ProgressBar) GetBool(key interface{}) bool { - if v, ok := pb.Get(key).(bool); ok { - return v - } - return false -} - -// SetWidth sets the bar width -// When given value <= 0 would be using the terminal width (if possible) or default value. -func (pb *ProgressBar) SetWidth(width int) *ProgressBar { - pb.mu.Lock() - pb.width = width - pb.mu.Unlock() - return pb -} - -// Width return the bar width -// It's current terminal width or settled over 'SetWidth' value. -func (pb *ProgressBar) Width() (width int) { - defer func() { - if r := recover(); r != nil { - width = defaultBarWidth - } - }() - pb.mu.RLock() - width = pb.width - pb.mu.RUnlock() - if width <= 0 { - var err error - if width, err = terminalWidth(); err != nil { - return defaultBarWidth - } - } - return -} - -func (pb *ProgressBar) SetRefreshRate(dur time.Duration) *ProgressBar { - pb.mu.Lock() - if dur > 0 { - pb.refreshRate = dur - } - pb.mu.Unlock() - return pb -} - -// SetWriter sets the io.Writer. Bar will write in this writer -// By default this is os.Stderr -func (pb *ProgressBar) SetWriter(w io.Writer) *ProgressBar { - pb.mu.Lock() - pb.output = w - pb.configured = false - pb.configure() - pb.mu.Unlock() - return pb -} - -// StartTime return the time when bar started -func (pb *ProgressBar) StartTime() time.Time { - pb.mu.RLock() - defer pb.mu.RUnlock() - return pb.startTime -} - -// Format convert int64 to string according to the current settings -func (pb *ProgressBar) Format(v int64) string { - if pb.GetBool(Bytes) { - return formatBytes(v) - } - return strconv.FormatInt(v, 10) -} - -// Finish stops the bar -func (pb *ProgressBar) Finish() *ProgressBar { - pb.mu.Lock() - if pb.finished { - pb.mu.Unlock() - return pb - } - finishChan := pb.finish - pb.finished = true - pb.mu.Unlock() - if finishChan != nil { - finishChan <- struct{}{} - <-finishChan - pb.mu.Lock() - pb.finish = nil - pb.mu.Unlock() - } - return pb -} - -// IsStarted indicates progress bar state -func (pb *ProgressBar) IsStarted() bool { - pb.mu.RLock() - defer pb.mu.RUnlock() - return pb.finish != nil -} - -// SetTemplateString sets ProgressBar tempate string and parse it -func (pb *ProgressBar) SetTemplateString(tmpl string) *ProgressBar { - pb.mu.Lock() - defer pb.mu.Unlock() - pb.tmpl, pb.err = getTemplate(tmpl) - return pb -} - -// SetTemplateString sets ProgressBarTempate and parse it -func (pb *ProgressBar) SetTemplate(tmpl ProgressBarTemplate) *ProgressBar { - return pb.SetTemplateString(string(tmpl)) -} - -// NewProxyReader creates a wrapper for given reader, but with progress handle -// Takes io.Reader or io.ReadCloser -// Also, it automatically switches progress bar to handle units as bytes -func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader { - pb.Set(Bytes, true) - return &Reader{r, pb} -} - -func (pb *ProgressBar) render() (result string, width int) { - defer func() { - if r := recover(); r != nil { - pb.SetErr(fmt.Errorf("render panic: %v", r)) - } - }() - pb.rm.Lock() - defer pb.rm.Unlock() - pb.mu.Lock() - pb.configure() - if pb.state == nil { - pb.state = &State{ProgressBar: pb} - pb.buf = bytes.NewBuffer(nil) - } - if pb.startTime.IsZero() { - pb.startTime = time.Now() - } - pb.state.id++ - pb.state.finished = pb.finished - pb.state.time = time.Now() - pb.mu.Unlock() - - pb.state.width = pb.Width() - width = pb.state.width - pb.state.total = pb.Total() - pb.state.current = pb.Current() - pb.buf.Reset() - - if e := pb.tmpl.Execute(pb.buf, pb.state); e != nil { - pb.SetErr(e) - return "", 0 - } - - result = pb.buf.String() - - aec := len(pb.state.recalc) - if aec == 0 { - // no adaptive elements - return - } - - staticWidth := CellCount(result) - (aec * adElPlaceholderLen) - - if pb.state.Width()-staticWidth <= 0 { - result = strings.Replace(result, adElPlaceholder, "", -1) - result = StripString(result, pb.state.Width()) - } else { - pb.state.adaptiveElWidth = (width - staticWidth) / aec - for _, el := range pb.state.recalc { - result = strings.Replace(result, adElPlaceholder, el.ProgressElement(pb.state), 1) - } - } - pb.state.recalc = pb.state.recalc[:0] - return -} - -// SetErr sets error to the ProgressBar -// Error will be available over Err() -func (pb *ProgressBar) SetErr(err error) *ProgressBar { - pb.mu.Lock() - pb.err = err - pb.mu.Unlock() - return pb -} - -// Err return possible error -// When all ok - will be nil -// May contain template.Execute errors -func (pb *ProgressBar) Err() error { - pb.mu.RLock() - defer pb.mu.RUnlock() - return pb.err -} - -// String return currrent string representation of ProgressBar -func (pb *ProgressBar) String() string { - res, _ := pb.render() - return res -} - -// ProgressElement implements Element interface -func (pb *ProgressBar) ProgressElement(s *State, args ...string) string { - if s.IsAdaptiveWidth() { - pb.SetWidth(s.AdaptiveElWidth()) - } - return pb.String() -} - -// State represents the current state of bar -// Need for bar elements -type State struct { - *ProgressBar - - id uint64 - total, current int64 - width, adaptiveElWidth int - finished, adaptive bool - time time.Time - - recalc []Element -} - -// Id it's the current state identifier -// - incremental -// - starts with 1 -// - resets after finish/start -func (s *State) Id() uint64 { - return s.id -} - -// Total it's bar int64 total -func (s *State) Total() int64 { - return s.total -} - -// Value it's current value -func (s *State) Value() int64 { - return s.current -} - -// Width of bar -func (s *State) Width() int { - return s.width -} - -// AdaptiveElWidth - adaptive elements must return string with given cell count (when AdaptiveElWidth > 0) -func (s *State) AdaptiveElWidth() int { - return s.adaptiveElWidth -} - -// IsAdaptiveWidth returns true when element must be shown as adaptive -func (s *State) IsAdaptiveWidth() bool { - return s.adaptive -} - -// IsFinished return true when bar is finished -func (s *State) IsFinished() bool { - return s.finished -} - -// IsFirst return true only in first render -func (s *State) IsFirst() bool { - return s.id == 1 -} - -// Time when state was created -func (s *State) Time() time.Time { - return s.time -} diff --git a/vendor/github.com/cheggaaa/pb/pb_test.go b/vendor/github.com/cheggaaa/pb/pb_test.go deleted file mode 100644 index 929778466..000000000 --- a/vendor/github.com/cheggaaa/pb/pb_test.go +++ /dev/null @@ -1,219 +0,0 @@ -package pb - -import ( - "bytes" - "errors" - "fmt" - "strings" - "testing" - "time" - - "gopkg.in/fatih/color.v1" -) - -func TestPBBasic(t *testing.T) { - bar := new(ProgressBar) - var a, e int64 - if a, e = bar.Total(), 0; a != e { - t.Errorf("Unexpected total: actual: %v; expected: %v", a, e) - } - if a, e = bar.Current(), 0; a != e { - t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) - } - bar.SetCurrent(10).SetTotal(20) - if a, e = bar.Total(), 20; a != e { - t.Errorf("Unexpected total: actual: %v; expected: %v", a, e) - } - if a, e = bar.Current(), 10; a != e { - t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) - } - bar.Add(5) - if a, e = bar.Current(), 15; a != e { - t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) - } - bar.Increment() - if a, e = bar.Current(), 16; a != e { - t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) - } -} - -func TestPBWidth(t *testing.T) { - terminalWidth = func() (int, error) { - return 50, nil - } - // terminal width - bar := new(ProgressBar) - if a, e := bar.Width(), 50; a != e { - t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) - } - // terminal width error - terminalWidth = func() (int, error) { - return 0, errors.New("test error") - } - if a, e := bar.Width(), defaultBarWidth; a != e { - t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) - } - // terminal width panic - terminalWidth = func() (int, error) { - panic("test") - return 0, nil - } - if a, e := bar.Width(), defaultBarWidth; a != e { - t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) - } - // set negative terminal width - bar.SetWidth(-42) - if a, e := bar.Width(), defaultBarWidth; a != e { - t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) - } - // set terminal width - bar.SetWidth(42) - if a, e := bar.Width(), 42; a != e { - t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) - } -} - -func TestPBTemplate(t *testing.T) { - bar := new(ProgressBar) - result := bar.SetTotal(100).SetCurrent(50).SetWidth(40).String() - expected := "50 / 100 [------->________] 50.00% ? p/s" - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) - } - - // check strip - result = bar.SetWidth(8).String() - expected = "50 / 100" - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) - } - - // invalid template - for _, invalidTemplate := range []string{ - `{{invalid template`, `{{speed}}`, - } { - bar.SetTemplateString(invalidTemplate) - result = bar.String() - expected = "" - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) - } - if err := bar.Err(); err == nil { - t.Errorf("Must be error") - } - } - - // simple template without adaptive elemnts - bar.SetTemplateString(`{{counters . }}`) - result = bar.String() - expected = "50 / 100" - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) - } -} - -func TestPBStartFinish(t *testing.T) { - bar := ProgressBarTemplate(`{{counters . }}`).New(0) - for i := int64(0); i < 2; i++ { - if bar.IsStarted() { - t.Error("Must be false") - } - var buf = bytes.NewBuffer(nil) - bar.SetTotal(100). - SetCurrent(int64(i)). - SetWidth(7). - Set(Terminal, true). - SetWriter(buf). - SetRefreshRate(time.Millisecond * 20). - Start() - if !bar.IsStarted() { - t.Error("Must be true") - } - time.Sleep(time.Millisecond * 100) - bar.Finish() - if buf.Len() == 0 { - t.Error("no writes") - } - var resultsString = strings.TrimPrefix(buf.String(), "\r") - if !strings.HasSuffix(resultsString, "\n") { - t.Error("No end \\n symb") - } else { - resultsString = resultsString[:len(resultsString)-1] - } - var results = strings.Split(resultsString, "\r") - if len(results) < 3 { - t.Errorf("Unexpected writes count: %v", len(results)) - } - exp := fmt.Sprintf("%d / 100", i) - for i, res := range results { - if res != exp { - t.Errorf("Unexpected result[%d]: '%v'", i, res) - } - } - // test second finish call - bar.Finish() - } -} - -func TestPBFlags(t *testing.T) { - // Static - color.NoColor = false - buf := bytes.NewBuffer(nil) - bar := ProgressBarTemplate(`{{counters . | red}}`).New(100) - bar.Set(Static, true).SetCurrent(50).SetWidth(10).SetWriter(buf).Start() - if bar.IsStarted() { - t.Error("Must be false") - } - bar.Write() - result := buf.String() - expected := "50 / 100" - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected) - } - if !bar.state.IsFirst() { - t.Error("must be true") - } - // Color - bar.Set(Color, true) - buf.Reset() - bar.Write() - result = buf.String() - expected = color.RedString("50 / 100") - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected) - } - if bar.state.IsFirst() { - t.Error("must be false") - } - // Terminal - bar.Set(Terminal, true).SetWriter(buf) - buf.Reset() - bar.Write() - result = buf.String() - expected = "\r" + color.RedString("50 / 100") + " " - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected) - } -} - -func BenchmarkRender(b *testing.B) { - var formats = []string{ - string(Simple), - string(Default), - string(Full), - `{{string . "prefix" | red}}{{counters . | green}} {{bar . | yellow}} {{percent . | cyan}} {{speed . | cyan}}{{string . "suffix" | cyan}}`, - } - var names = []string{ - "Simple", "Default", "Full", "Color", - } - for i, tmpl := range formats { - bar := new(ProgressBar) - bar.SetTemplateString(tmpl).SetWidth(100) - b.Run(names[i], func(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - bar.String() - } - }) - } -} diff --git a/vendor/github.com/cheggaaa/pb/preset.go b/vendor/github.com/cheggaaa/pb/preset.go deleted file mode 100644 index 1934c0e88..000000000 --- a/vendor/github.com/cheggaaa/pb/preset.go +++ /dev/null @@ -1,17 +0,0 @@ -package pb - -import () - -var ( - // Full - preset with all default available elements - // Example: 'Prefix 20/100 [-->______] 20% 1 p/s ETA 1m Suffix' - Full ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }} {{speed . }} {{rtime . "ETA %s"}}{{string . "suffix"}}` - - // Default - preset like Full but without elapsed time - // Example: 'Prefix 20/100 [-->______] 20% 1 p/s ETA 1m Suffix' - Default ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }} {{speed . }}{{string . "suffix"}}` - - // Simple - preset without speed and any timers. Only counters, bar and percents - // Example: 'Prefix 20/100 [-->______] 20% Suffix' - Simple ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }}{{string . "suffix"}}` -) diff --git a/vendor/github.com/cheggaaa/pb/reader.go b/vendor/github.com/cheggaaa/pb/reader.go deleted file mode 100644 index f2e60a09d..000000000 --- a/vendor/github.com/cheggaaa/pb/reader.go +++ /dev/null @@ -1,26 +0,0 @@ -package pb - -import ( - "io" -) - -// Reader it's a wrapper for given reader, but with progress handle -type Reader struct { - io.Reader - bar *ProgressBar -} - -// Read reads bytes from wrapped reader and add amount of bytes to progress bar -func (r *Reader) Read(p []byte) (n int, err error) { - n, err = r.Reader.Read(p) - r.bar.Add(n) - return -} - -// Close the wrapped reader when it implements io.Closer -func (r *Reader) Close() (err error) { - if closer, ok := r.Reader.(io.Closer); ok { - return closer.Close() - } - return -} diff --git a/vendor/github.com/cheggaaa/pb/reader_test.go b/vendor/github.com/cheggaaa/pb/reader_test.go deleted file mode 100644 index a5d745a0b..000000000 --- a/vendor/github.com/cheggaaa/pb/reader_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package pb - -import ( - "testing" -) - -func TestPBProxyReader(t *testing.T) { - bar := new(ProgressBar) - if bar.GetBool(Bytes) { - t.Errorf("By default bytes must be false") - } - - testReader := new(testReaderCloser) - proxyReader := bar.NewProxyReader(testReader) - - if !bar.GetBool(Bytes) { - t.Errorf("Bytes must be true after call NewProxyReader") - } - - for i := 0; i < 10; i++ { - buf := make([]byte, 10) - n, e := proxyReader.Read(buf) - if e != nil { - t.Errorf("Proxy reader return err: %v", e) - } - if n != len(buf) { - t.Errorf("Proxy reader return unexpected N: %d (wand %d)", n, len(buf)) - } - for _, b := range buf { - if b != 'f' { - t.Errorf("Unexpected read value: %v (want %v)", b, 'f') - } - } - if want := int64((i + 1) * len(buf)); bar.Current() != want { - t.Errorf("Unexpected bar current value: %d (want %d)", bar.Current(), want) - } - } - proxyReader.Close() - if !testReader.closed { - t.Errorf("Reader must be closed after call ProxyReader.Close") - } - proxyReader.Reader = nil - proxyReader.Close() -} - -type testReaderCloser struct { - closed bool -} - -func (tr *testReaderCloser) Read(p []byte) (n int, err error) { - for i := range p { - p[i] = 'f' - } - return len(p), nil -} - -func (tr *testReaderCloser) Close() (err error) { - tr.closed = true - return -} diff --git a/vendor/github.com/cheggaaa/pb/speed.go b/vendor/github.com/cheggaaa/pb/speed.go deleted file mode 100644 index 4cf34b1d1..000000000 --- a/vendor/github.com/cheggaaa/pb/speed.go +++ /dev/null @@ -1,83 +0,0 @@ -package pb - -import ( - "fmt" - "math" - "time" - - "gopkg.in/VividCortex/ewma.v1" -) - -var speedAddLimit = time.Second / 2 - -type speed struct { - ewma ewma.MovingAverage - lastStateId uint64 - prevValue, startValue int64 - prevTime, startTime time.Time -} - -func (s *speed) value(state *State) float64 { - if s.ewma == nil { - s.ewma = ewma.NewMovingAverage() - } - if state.IsFirst() || state.Id() < s.lastStateId { - s.reset(state) - return 0 - } - if state.Id() == s.lastStateId { - return s.ewma.Value() - } - if state.IsFinished() { - return s.absValue(state) - } - dur := state.Time().Sub(s.prevTime) - if dur < speedAddLimit { - return s.ewma.Value() - } - diff := math.Abs(float64(state.Value() - s.prevValue)) - lastSpeed := diff / dur.Seconds() - s.prevTime = state.Time() - s.prevValue = state.Value() - s.lastStateId = state.Id() - s.ewma.Add(lastSpeed) - return s.ewma.Value() -} - -func (s *speed) reset(state *State) { - s.lastStateId = state.Id() - s.startTime = state.Time() - s.prevTime = state.Time() - s.startValue = state.Value() - s.prevValue = state.Value() - s.ewma = ewma.NewMovingAverage() -} - -func (s *speed) absValue(state *State) float64 { - if dur := state.Time().Sub(s.startTime); dur > 0 { - return float64(state.Value()) / dur.Seconds() - } - return 0 -} - -func getSpeedObj(state *State) (s *speed) { - if sObj, ok := state.Get(speedObj).(*speed); ok { - return sObj - } - s = new(speed) - state.Set(speedObj, s) - return -} - -// ElementSpeed calculates current speed by EWMA -// Optionally can take one or two string arguments. -// First string will be used as value for format speed, default is "%s p/s". -// Second string will be used when speed not available, default is "? p/s" -// In template use as follows: {{speed .}} or {{speed . "%s per second"}} or {{speed . "%s ps" "..."} -var ElementSpeed ElementFunc = func(state *State, args ...string) string { - sp := getSpeedObj(state).value(state) - if sp == 0 { - return argsHelper(args).getNotEmptyOr(1, "? p/s") - } - return fmt.Sprintf(argsHelper(args).getNotEmptyOr(0, "%s p/s"), state.Format(int64(round(sp)))) -} diff --git a/vendor/github.com/cheggaaa/pb/template.go b/vendor/github.com/cheggaaa/pb/template.go deleted file mode 100644 index 98aeea44e..000000000 --- a/vendor/github.com/cheggaaa/pb/template.go +++ /dev/null @@ -1,87 +0,0 @@ -package pb - -import ( - "math/rand" - "sync" - "text/template" - - "gopkg.in/fatih/color.v1" -) - -// ProgressBarTemplate that template string -type ProgressBarTemplate string - -// New creates new bar from template -func (pbt ProgressBarTemplate) New(total int) *ProgressBar { - return New(total).SetTemplate(pbt) -} - -// Start64 create and start new bar with given int64 total value -func (pbt ProgressBarTemplate) Start64(total int64) *ProgressBar { - return New64(total).SetTemplate(pbt).Start() -} - -// Start create and start new bar with given int total value -func (pbt ProgressBarTemplate) Start(total int) *ProgressBar { - return pbt.Start64(int64(total)) -} - -var templateCacheMu sync.Mutex -var templateCache = make(map[string]*template.Template) - -var defaultTemplateFuncs = template.FuncMap{ - // colors - "black": color.New(color.FgBlack).SprintFunc(), - "red": color.New(color.FgRed).SprintFunc(), - "green": color.New(color.FgGreen).SprintFunc(), - "yellow": color.New(color.FgYellow).SprintFunc(), - "blue": color.New(color.FgBlue).SprintFunc(), - "magenta": color.New(color.FgMagenta).SprintFunc(), - "cyan": color.New(color.FgCyan).SprintFunc(), - "white": color.New(color.FgWhite).SprintFunc(), - "rndcolor": rndcolor, - "rnd": rnd, -} - -func getTemplate(tmpl string) (t *template.Template, err error) { - templateCacheMu.Lock() - defer templateCacheMu.Unlock() - t = templateCache[tmpl] - if t != nil { - // found in cache - return - } - t = template.New("") - fillTemplateFuncs(t) - _, err = t.Parse(tmpl) - if err != nil { - t = nil - return - } - templateCache[tmpl] = t - return -} - -func fillTemplateFuncs(t *template.Template) { - t.Funcs(defaultTemplateFuncs) - emf := make(template.FuncMap) - elementsM.Lock() - for k, v := range elements { - emf[k] = v - } - elementsM.Unlock() - t.Funcs(emf) - return -} - -func rndcolor(s string) string { - c := rand.Intn(int(color.FgWhite-color.FgBlack)) + int(color.FgBlack) - return color.New(color.Attribute(c)).Sprint(s) -} - -func rnd(args ...string) string { - if len(args) == 0 { - return "" - } - return args[rand.Intn(len(args))] -} diff --git a/vendor/github.com/cheggaaa/pb/template_test.go b/vendor/github.com/cheggaaa/pb/template_test.go deleted file mode 100644 index 84022d347..000000000 --- a/vendor/github.com/cheggaaa/pb/template_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package pb - -import ( - "bytes" - "testing" -) - -func TestProgressBarTemplate(t *testing.T) { - // test New - bar := ProgressBarTemplate(`{{counters . }}`).New(0) - result := bar.String() - expected := "0" - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) - } - if bar.IsStarted() { - t.Error("Must be false") - } - - // test Start - bar = ProgressBarTemplate(`{{counters . }}`).Start(42).SetWriter(bytes.NewBuffer(nil)) - result = bar.String() - expected = "0 / 42" - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) - } - if !bar.IsStarted() { - t.Error("Must be true") - } -} - -func TestTemplateFuncs(t *testing.T) { - var results = make(map[string]int) - for i := 0; i < 100; i++ { - r := rndcolor("s") - results[r] = results[r] + 1 - } - if len(results) < 6 { - t.Errorf("Unexpected rndcolor results count: %v", len(results)) - } - - results = make(map[string]int) - for i := 0; i < 100; i++ { - r := rnd("1", "2", "3") - results[r] = results[r] + 1 - } - if len(results) != 3 { - t.Errorf("Unexpected rnd results count: %v", len(results)) - } - if r := rnd(); r != "" { - t.Errorf("Unexpected rnd result: '%v'", r) - } -} diff --git a/vendor/github.com/cheggaaa/pb/termutil/term.go b/vendor/github.com/cheggaaa/pb/termutil/term.go deleted file mode 100644 index b53b4b24a..000000000 --- a/vendor/github.com/cheggaaa/pb/termutil/term.go +++ /dev/null @@ -1,57 +0,0 @@ -package termutil - -import ( - "errors" - "os" - "os/signal" - "sync" - "syscall" -) - -var echoLocked bool -var echoLockMutex sync.Mutex -var errLocked = errors.New("terminal locked") - -// RawModeOn switches terminal to raw mode -func RawModeOn() (quit chan struct{}, err error) { - echoLockMutex.Lock() - defer echoLockMutex.Unlock() - if echoLocked { - err = errLocked - return - } - if err = lockEcho(); err != nil { - return - } - echoLocked = true - quit = make(chan struct{}, 1) - go catchTerminate(quit) - return -} - -// RawModeOff restore previous terminal state -func RawModeOff() (err error) { - echoLockMutex.Lock() - defer echoLockMutex.Unlock() - if !echoLocked { - return - } - if err = unlockEcho(); err != nil { - return - } - echoLocked = false - return -} - -// listen exit signals and restore terminal state -func catchTerminate(quit chan struct{}) { - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL) - defer signal.Stop(sig) - select { - case <-quit: - RawModeOff() - case <-sig: - RawModeOff() - } -} diff --git a/vendor/github.com/cheggaaa/pb/termutil/term_appengine.go b/vendor/github.com/cheggaaa/pb/termutil/term_appengine.go deleted file mode 100644 index 4b7b20e6b..000000000 --- a/vendor/github.com/cheggaaa/pb/termutil/term_appengine.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build appengine - -package termutil - -import "errors" - -// terminalWidth returns width of the terminal, which is not supported -// and should always failed on appengine classic which is a sandboxed PaaS. -func TerminalWidth() (int, error) { - return 0, errors.New("Not supported") -} diff --git a/vendor/github.com/cheggaaa/pb/termutil/term_bsd.go b/vendor/github.com/cheggaaa/pb/termutil/term_bsd.go deleted file mode 100644 index 272659a12..000000000 --- a/vendor/github.com/cheggaaa/pb/termutil/term_bsd.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build darwin freebsd netbsd openbsd dragonfly -// +build !appengine - -package termutil - -import "syscall" - -const ioctlReadTermios = syscall.TIOCGETA -const ioctlWriteTermios = syscall.TIOCSETA diff --git a/vendor/github.com/cheggaaa/pb/termutil/term_linux.go b/vendor/github.com/cheggaaa/pb/termutil/term_linux.go deleted file mode 100644 index 2f59e53e1..000000000 --- a/vendor/github.com/cheggaaa/pb/termutil/term_linux.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build linux -// +build !appengine - -package termutil - -const ioctlReadTermios = 0x5401 // syscall.TCGETS -const ioctlWriteTermios = 0x5402 // syscall.TCSETS diff --git a/vendor/github.com/cheggaaa/pb/termutil/term_nix.go b/vendor/github.com/cheggaaa/pb/termutil/term_nix.go deleted file mode 100644 index 14277e71f..000000000 --- a/vendor/github.com/cheggaaa/pb/termutil/term_nix.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build linux darwin freebsd netbsd openbsd dragonfly -// +build !appengine - -package termutil - -import "syscall" - -const sysIoctl = syscall.SYS_IOCTL diff --git a/vendor/github.com/cheggaaa/pb/termutil/term_solaris.go b/vendor/github.com/cheggaaa/pb/termutil/term_solaris.go deleted file mode 100644 index fc96c2b7f..000000000 --- a/vendor/github.com/cheggaaa/pb/termutil/term_solaris.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build solaris -// +build !appengine - -package termutil - -const ioctlReadTermios = 0x5401 // syscall.TCGETS -const ioctlWriteTermios = 0x5402 // syscall.TCSETS -const sysIoctl = 54 diff --git a/vendor/github.com/cheggaaa/pb/termutil/term_win.go b/vendor/github.com/cheggaaa/pb/termutil/term_win.go deleted file mode 100644 index 963158360..000000000 --- a/vendor/github.com/cheggaaa/pb/termutil/term_win.go +++ /dev/null @@ -1,149 +0,0 @@ -// +build windows - -package termutil - -import ( - "fmt" - "os" - "os/exec" - "strconv" - "syscall" - "unsafe" -) - -var tty = os.Stdin - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - - // GetConsoleScreenBufferInfo retrieves information about the - // specified console screen buffer. - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") - - // GetConsoleMode retrieves the current input mode of a console's - // input buffer or the current output mode of a console screen buffer. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx - getConsoleMode = kernel32.NewProc("GetConsoleMode") - - // SetConsoleMode sets the input mode of a console's input buffer - // or the output mode of a console screen buffer. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx - setConsoleMode = kernel32.NewProc("SetConsoleMode") - - // SetConsoleCursorPosition sets the cursor position in the - // specified console screen buffer. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx - setConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") - - mingw = isMingw() -) - -type ( - // Defines the coordinates of the upper left and lower right corners - // of a rectangle. - // See - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311(v=vs.85).aspx - smallRect struct { - Left, Top, Right, Bottom int16 - } - - // Defines the coordinates of a character cell in a console screen - // buffer. The origin of the coordinate system (0,0) is at the top, left cell - // of the buffer. - // See - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119(v=vs.85).aspx - coordinates struct { - X, Y int16 - } - - word int16 - - // Contains information about a console screen buffer. - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx - consoleScreenBufferInfo struct { - dwSize coordinates - dwCursorPosition coordinates - wAttributes word - srWindow smallRect - dwMaximumWindowSize coordinates - } -) - -// TerminalWidth returns width of the terminal. -func TerminalWidth() (width int, err error) { - if mingw { - return termWidthTPut() - } - return termWidthCmd() -} - -func termWidthCmd() (width int, err error) { - var info consoleScreenBufferInfo - _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0) - if e != 0 { - return 0, error(e) - } - return int(info.dwSize.X) - 1, nil -} - -func isMingw() bool { - return os.Getenv("MINGW_PREFIX") != "" || os.Getenv("MSYSTEM") == "MINGW64" -} - -func termWidthTPut() (width int, err error) { - // TODO: maybe anybody knows a better way to get it on mintty... - var res []byte - cmd := exec.Command("tput", "cols") - cmd.Stdin = os.Stdin - if res, err = cmd.CombinedOutput(); err != nil { - return 0, fmt.Errorf("%s: %v", string(res), err) - } - if len(res) > 1 { - res = res[:len(res)-1] - } - return strconv.Atoi(string(res)) -} - -func getCursorPos() (pos coordinates, err error) { - var info consoleScreenBufferInfo - _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0) - if e != 0 { - return info.dwCursorPosition, error(e) - } - return info.dwCursorPosition, nil -} - -func setCursorPos(pos coordinates) error { - _, _, e := syscall.Syscall(setConsoleCursorPosition.Addr(), 2, uintptr(syscall.Stdout), uintptr(uint32(uint16(pos.Y))<<16|uint32(uint16(pos.X))), 0) - if e != 0 { - return error(e) - } - return nil -} - -var oldState word - -func lockEcho() (err error) { - if _, _, e := syscall.Syscall(getConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&oldState)), 0); e != 0 { - err = fmt.Errorf("Can't get terminal settings: %v", e) - return - } - - newState := oldState - const ENABLE_ECHO_INPUT = 0x0004 - const ENABLE_LINE_INPUT = 0x0002 - newState = newState & (^(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)) - if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(newState), 0); e != 0 { - err = fmt.Errorf("Can't set terminal settings: %v", e) - return - } - return -} - -func unlockEcho() (err error) { - if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(oldState), 0); e != 0 { - err = fmt.Errorf("Can't set terminal settings") - } - return -} diff --git a/vendor/github.com/cheggaaa/pb/termutil/term_x.go b/vendor/github.com/cheggaaa/pb/termutil/term_x.go deleted file mode 100644 index e2f69b214..000000000 --- a/vendor/github.com/cheggaaa/pb/termutil/term_x.go +++ /dev/null @@ -1,70 +0,0 @@ -// +build linux darwin freebsd netbsd openbsd solaris dragonfly -// +build !appengine - -package termutil - -import ( - "fmt" - "os" - "syscall" - "unsafe" -) - -var tty *os.File - -type window struct { - Row uint16 - Col uint16 - Xpixel uint16 - Ypixel uint16 -} - -func init() { - var err error - tty, err = os.Open("/dev/tty") - if err != nil { - tty = os.Stdin - } -} - -// TerminalWidth returns width of the terminal. -func TerminalWidth() (int, error) { - w := new(window) - res, _, err := syscall.Syscall(sysIoctl, - tty.Fd(), - uintptr(syscall.TIOCGWINSZ), - uintptr(unsafe.Pointer(w)), - ) - if int(res) == -1 { - return 0, err - } - return int(w.Col), nil -} - -var oldState syscall.Termios - -func lockEcho() (err error) { - fd := tty.Fd() - if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { - err = fmt.Errorf("Can't get terminal settings: %v", e) - return - } - - newState := oldState - newState.Lflag &^= syscall.ECHO - newState.Lflag |= syscall.ICANON | syscall.ISIG - newState.Iflag |= syscall.ICRNL - if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); e != 0 { - err = fmt.Errorf("Can't set terminal settings: %v", e) - return - } - return -} - -func unlockEcho() (err error) { - fd := tty.Fd() - if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { - err = fmt.Errorf("Can't set terminal settings") - } - return -} diff --git a/vendor/github.com/cheggaaa/pb/util.go b/vendor/github.com/cheggaaa/pb/util.go deleted file mode 100644 index 44eedae56..000000000 --- a/vendor/github.com/cheggaaa/pb/util.go +++ /dev/null @@ -1,94 +0,0 @@ -package pb - -import ( - "bytes" - "fmt" - "gopkg.in/mattn/go-runewidth.v0" - "math" - "regexp" - //"unicode/utf8" -) - -const ( - _KiB = 1024 - _MiB = 1048576 - _GiB = 1073741824 - _TiB = 1099511627776 -) - -var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9]+\x6d") - -func CellCount(s string) int { - n := runewidth.StringWidth(s) - for _, sm := range ctrlFinder.FindAllString(s, -1) { - n -= runewidth.StringWidth(sm) - } - return n -} - -func StripString(s string, w int) string { - l := CellCount(s) - if l <= w { - return s - } - var buf = bytes.NewBuffer(make([]byte, 0, len(s))) - StripStringToBuffer(s, w, buf) - return buf.String() -} - -func StripStringToBuffer(s string, w int, buf *bytes.Buffer) { - var seqs = ctrlFinder.FindAllStringIndex(s, -1) -mainloop: - for i, r := range s { - for _, seq := range seqs { - if i >= seq[0] && i < seq[1] { - buf.WriteRune(r) - continue mainloop - } - } - if rw := CellCount(string(r)); rw <= w { - w -= rw - buf.WriteRune(r) - } else { - break - } - } - for w > 0 { - buf.WriteByte(' ') - w-- - } - return -} - -func round(val float64) (newVal float64) { - roundOn := 0.5 - places := 0 - var round float64 - pow := math.Pow(10, float64(places)) - digit := pow * val - _, div := math.Modf(digit) - if div >= roundOn { - round = math.Ceil(digit) - } else { - round = math.Floor(digit) - } - newVal = round / pow - return -} - -// Convert bytes to human readable string. Like a 2 MiB, 64.2 KiB, 52 B -func formatBytes(i int64) (result string) { - switch { - case i >= _TiB: - result = fmt.Sprintf("%.02f TiB", float64(i)/_TiB) - case i >= _GiB: - result = fmt.Sprintf("%.02f GiB", float64(i)/_GiB) - case i >= _MiB: - result = fmt.Sprintf("%.02f MiB", float64(i)/_MiB) - case i >= _KiB: - result = fmt.Sprintf("%.02f KiB", float64(i)/_KiB) - default: - result = fmt.Sprintf("%d B", i) - } - return -} diff --git a/vendor/github.com/cheggaaa/pb/util_test.go b/vendor/github.com/cheggaaa/pb/util_test.go deleted file mode 100644 index 1c7fe7850..000000000 --- a/vendor/github.com/cheggaaa/pb/util_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package pb - -import ( - "gopkg.in/fatih/color.v1" - "testing" -) - -var testColorString = color.RedString("red") + - color.GreenString("hello") + - "simple" + - color.WhiteString("進捗") - -func TestUtilCellCount(t *testing.T) { - if e, l := 18, CellCount(testColorString); l != e { - t.Errorf("Invalid length %d, expected %d", l, e) - } -} - -func TestUtilStripString(t *testing.T) { - if r, e := StripString("12345", 4), "1234"; r != e { - t.Errorf("Invalid result '%s', expected '%s'", r, e) - } - - if r, e := StripString("12345", 5), "12345"; r != e { - t.Errorf("Invalid result '%s', expected '%s'", r, e) - } - if r, e := StripString("12345", 10), "12345"; r != e { - t.Errorf("Invalid result '%s', expected '%s'", r, e) - } - - s := color.RedString("1") + "23" - e := color.RedString("1") + "2" - if r := StripString(s, 2); r != e { - t.Errorf("Invalid result '%s', expected '%s'", r, e) - } - return -} - -func TestUtilRound(t *testing.T) { - if v := round(4.4); v != 4 { - t.Errorf("Unexpected result: %v", v) - } - if v := round(4.501); v != 5 { - t.Errorf("Unexpected result: %v", v) - } -} - -func TestUtilFormatBytes(t *testing.T) { - inputs := []struct { - v int64 - e string - }{ - {v: 1000, e: "1000 B"}, - {v: 1024, e: "1.00 KiB"}, - {v: 3*_MiB + 140*_KiB, e: "3.14 MiB"}, - {v: 2 * _GiB, e: "2.00 GiB"}, - {v: 2048 * _GiB, e: "2.00 TiB"}, - } - - for _, input := range inputs { - actual := formatBytes(input.v) - if actual != input.e { - t.Errorf("Expected {%s} was {%s}", input.e, actual) - } - } -} - -func BenchmarkUtilsCellCount(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - CellCount(testColorString) - } -} diff --git a/vendor/github.com/mattn/go-colorable/.travis.yml b/vendor/github.com/mattn/go-colorable/.travis.yml deleted file mode 100644 index 98db8f060..000000000 --- a/vendor/github.com/mattn/go-colorable/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go -go: - - tip - -before_install: - - go get github.com/mattn/goveralls - - go get golang.org/x/tools/cmd/cover -script: - - $HOME/gopath/bin/goveralls -repotoken xnXqRGwgW3SXIguzxf90ZSK1GPYZPaGrw diff --git a/vendor/github.com/mattn/go-colorable/LICENSE b/vendor/github.com/mattn/go-colorable/LICENSE deleted file mode 100644 index 91b5cef30..000000000 --- a/vendor/github.com/mattn/go-colorable/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/mattn/go-colorable/README.md b/vendor/github.com/mattn/go-colorable/README.md deleted file mode 100644 index 56729a92c..000000000 --- a/vendor/github.com/mattn/go-colorable/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# go-colorable - -[![Godoc Reference](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable) -[![Build Status](https://travis-ci.org/mattn/go-colorable.svg?branch=master)](https://travis-ci.org/mattn/go-colorable) -[![Coverage Status](https://coveralls.io/repos/github/mattn/go-colorable/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-colorable?branch=master) -[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable) - -Colorable writer for windows. - -For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.) -This package is possible to handle escape sequence for ansi color on windows. - -## Too Bad! - -![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png) - - -## So Good! - -![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png) - -## Usage - -```go -logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) -logrus.SetOutput(colorable.NewColorableStdout()) - -logrus.Info("succeeded") -logrus.Warn("not correct") -logrus.Error("something error") -logrus.Fatal("panic") -``` - -You can compile above code on non-windows OSs. - -## Installation - -``` -$ go get github.com/mattn/go-colorable -``` - -# License - -MIT - -# Author - -Yasuhiro Matsumoto (a.k.a mattn) diff --git a/vendor/github.com/mattn/go-colorable/_example/escape-seq/main.go b/vendor/github.com/mattn/go-colorable/_example/escape-seq/main.go deleted file mode 100644 index 8cbcb9097..000000000 --- a/vendor/github.com/mattn/go-colorable/_example/escape-seq/main.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - - "github.com/mattn/go-colorable" -) - -func main() { - stdOut := bufio.NewWriter(colorable.NewColorableStdout()) - - fmt.Fprint(stdOut, "\x1B[3GMove to 3rd Column\n") - fmt.Fprint(stdOut, "\x1B[1;2HMove to 2nd Column on 1st Line\n") - stdOut.Flush() -} diff --git a/vendor/github.com/mattn/go-colorable/_example/logrus/main.go b/vendor/github.com/mattn/go-colorable/_example/logrus/main.go deleted file mode 100644 index c569164b2..000000000 --- a/vendor/github.com/mattn/go-colorable/_example/logrus/main.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "github.com/mattn/go-colorable" - "github.com/sirupsen/logrus" -) - -func main() { - logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) - logrus.SetOutput(colorable.NewColorableStdout()) - - logrus.Info("succeeded") - logrus.Warn("not correct") - logrus.Error("something error") - logrus.Fatal("panic") -} diff --git a/vendor/github.com/mattn/go-colorable/_example/title/main.go b/vendor/github.com/mattn/go-colorable/_example/title/main.go deleted file mode 100644 index e208870e7..000000000 --- a/vendor/github.com/mattn/go-colorable/_example/title/main.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -import ( - "fmt" - "os" - . "github.com/mattn/go-colorable" -) - -func main() { - out := NewColorableStdout() - fmt.Fprint(out, "\x1B]0;TITLE Changed\007(See title and hit any key)") - var c [1]byte - os.Stdin.Read(c[:]) -} diff --git a/vendor/github.com/mattn/go-colorable/colorable_appengine.go b/vendor/github.com/mattn/go-colorable/colorable_appengine.go deleted file mode 100644 index 1f28d773d..000000000 --- a/vendor/github.com/mattn/go-colorable/colorable_appengine.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build appengine - -package colorable - -import ( - "io" - "os" - - _ "github.com/mattn/go-isatty" -) - -// NewColorable return new instance of Writer which handle escape sequence. -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - return file -} - -// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. -func NewColorableStdout() io.Writer { - return os.Stdout -} - -// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. -func NewColorableStderr() io.Writer { - return os.Stderr -} diff --git a/vendor/github.com/mattn/go-colorable/colorable_others.go b/vendor/github.com/mattn/go-colorable/colorable_others.go deleted file mode 100644 index 887f203dc..000000000 --- a/vendor/github.com/mattn/go-colorable/colorable_others.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build !windows -// +build !appengine - -package colorable - -import ( - "io" - "os" - - _ "github.com/mattn/go-isatty" -) - -// NewColorable return new instance of Writer which handle escape sequence. -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - return file -} - -// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. -func NewColorableStdout() io.Writer { - return os.Stdout -} - -// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. -func NewColorableStderr() io.Writer { - return os.Stderr -} diff --git a/vendor/github.com/mattn/go-colorable/colorable_test.go b/vendor/github.com/mattn/go-colorable/colorable_test.go deleted file mode 100644 index 3069869a3..000000000 --- a/vendor/github.com/mattn/go-colorable/colorable_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package colorable - -import ( - "bytes" - "os" - "runtime" - "testing" -) - -// checkEncoding checks that colorable is output encoding agnostic as long as -// the encoding is a superset of ASCII. This implies that one byte not part of -// an ANSI sequence must give exactly one byte in output -func checkEncoding(t *testing.T, data []byte) { - // Send non-UTF8 data to colorable - b := bytes.NewBuffer(make([]byte, 0, 10)) - if b.Len() != 0 { - t.FailNow() - } - // TODO move colorable wrapping outside the test - c := NewNonColorable(b) - c.Write(data) - if b.Len() != len(data) { - t.Fatalf("%d bytes expected, got %d", len(data), b.Len()) - } -} - -func TestEncoding(t *testing.T) { - checkEncoding(t, []byte{}) // Empty - checkEncoding(t, []byte(`abc`)) // "abc" - checkEncoding(t, []byte(`é`)) // "é" in UTF-8 - checkEncoding(t, []byte{233}) // 'é' in Latin-1 -} - -func TestNonColorable(t *testing.T) { - var buf bytes.Buffer - want := "hello" - NewNonColorable(&buf).Write([]byte("\x1b[0m" + want + "\x1b[2J")) - got := buf.String() - if got != "hello" { - t.Fatalf("want %q but %q", want, got) - } - - buf.Reset() - NewNonColorable(&buf).Write([]byte("\x1b[")) - got = buf.String() - if got != "" { - t.Fatalf("want %q but %q", "", got) - } -} - -func TestNonColorableNil(t *testing.T) { - paniced := false - func() { - defer func() { - recover() - paniced = true - }() - NewNonColorable(nil) - NewColorable(nil) - }() - - if !paniced { - t.Fatalf("should panic") - } -} - -func TestColorable(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skipf("skip this test on windows") - } - _, ok := NewColorableStdout().(*os.File) - if !ok { - t.Fatalf("should os.Stdout on UNIX") - } - _, ok = NewColorableStderr().(*os.File) - if !ok { - t.Fatalf("should os.Stdout on UNIX") - } - _, ok = NewColorable(os.Stdout).(*os.File) - if !ok { - t.Fatalf("should os.Stdout on UNIX") - } -} diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go deleted file mode 100644 index e17a5474e..000000000 --- a/vendor/github.com/mattn/go-colorable/colorable_windows.go +++ /dev/null @@ -1,884 +0,0 @@ -// +build windows -// +build !appengine - -package colorable - -import ( - "bytes" - "io" - "math" - "os" - "strconv" - "strings" - "syscall" - "unsafe" - - "github.com/mattn/go-isatty" -) - -const ( - foregroundBlue = 0x1 - foregroundGreen = 0x2 - foregroundRed = 0x4 - foregroundIntensity = 0x8 - foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity) - backgroundBlue = 0x10 - backgroundGreen = 0x20 - backgroundRed = 0x40 - backgroundIntensity = 0x80 - backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity) -) - -type wchar uint16 -type short int16 -type dword uint32 -type word uint16 - -type coord struct { - x short - y short -} - -type smallRect struct { - left short - top short - right short - bottom short -} - -type consoleScreenBufferInfo struct { - size coord - cursorPosition coord - attributes word - window smallRect - maximumWindowSize coord -} - -type consoleCursorInfo struct { - size dword - visible int32 -} - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") - procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") - procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") - procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") - procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") - procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo") - procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo") - procSetConsoleTitle = kernel32.NewProc("SetConsoleTitleW") -) - -// Writer provide colorable Writer to the console -type Writer struct { - out io.Writer - handle syscall.Handle - oldattr word - oldpos coord -} - -// NewColorable return new instance of Writer which handle escape sequence from File. -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - if isatty.IsTerminal(file.Fd()) { - var csbi consoleScreenBufferInfo - handle := syscall.Handle(file.Fd()) - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - return &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}} - } - return file -} - -// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. -func NewColorableStdout() io.Writer { - return NewColorable(os.Stdout) -} - -// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. -func NewColorableStderr() io.Writer { - return NewColorable(os.Stderr) -} - -var color256 = map[int]int{ - 0: 0x000000, - 1: 0x800000, - 2: 0x008000, - 3: 0x808000, - 4: 0x000080, - 5: 0x800080, - 6: 0x008080, - 7: 0xc0c0c0, - 8: 0x808080, - 9: 0xff0000, - 10: 0x00ff00, - 11: 0xffff00, - 12: 0x0000ff, - 13: 0xff00ff, - 14: 0x00ffff, - 15: 0xffffff, - 16: 0x000000, - 17: 0x00005f, - 18: 0x000087, - 19: 0x0000af, - 20: 0x0000d7, - 21: 0x0000ff, - 22: 0x005f00, - 23: 0x005f5f, - 24: 0x005f87, - 25: 0x005faf, - 26: 0x005fd7, - 27: 0x005fff, - 28: 0x008700, - 29: 0x00875f, - 30: 0x008787, - 31: 0x0087af, - 32: 0x0087d7, - 33: 0x0087ff, - 34: 0x00af00, - 35: 0x00af5f, - 36: 0x00af87, - 37: 0x00afaf, - 38: 0x00afd7, - 39: 0x00afff, - 40: 0x00d700, - 41: 0x00d75f, - 42: 0x00d787, - 43: 0x00d7af, - 44: 0x00d7d7, - 45: 0x00d7ff, - 46: 0x00ff00, - 47: 0x00ff5f, - 48: 0x00ff87, - 49: 0x00ffaf, - 50: 0x00ffd7, - 51: 0x00ffff, - 52: 0x5f0000, - 53: 0x5f005f, - 54: 0x5f0087, - 55: 0x5f00af, - 56: 0x5f00d7, - 57: 0x5f00ff, - 58: 0x5f5f00, - 59: 0x5f5f5f, - 60: 0x5f5f87, - 61: 0x5f5faf, - 62: 0x5f5fd7, - 63: 0x5f5fff, - 64: 0x5f8700, - 65: 0x5f875f, - 66: 0x5f8787, - 67: 0x5f87af, - 68: 0x5f87d7, - 69: 0x5f87ff, - 70: 0x5faf00, - 71: 0x5faf5f, - 72: 0x5faf87, - 73: 0x5fafaf, - 74: 0x5fafd7, - 75: 0x5fafff, - 76: 0x5fd700, - 77: 0x5fd75f, - 78: 0x5fd787, - 79: 0x5fd7af, - 80: 0x5fd7d7, - 81: 0x5fd7ff, - 82: 0x5fff00, - 83: 0x5fff5f, - 84: 0x5fff87, - 85: 0x5fffaf, - 86: 0x5fffd7, - 87: 0x5fffff, - 88: 0x870000, - 89: 0x87005f, - 90: 0x870087, - 91: 0x8700af, - 92: 0x8700d7, - 93: 0x8700ff, - 94: 0x875f00, - 95: 0x875f5f, - 96: 0x875f87, - 97: 0x875faf, - 98: 0x875fd7, - 99: 0x875fff, - 100: 0x878700, - 101: 0x87875f, - 102: 0x878787, - 103: 0x8787af, - 104: 0x8787d7, - 105: 0x8787ff, - 106: 0x87af00, - 107: 0x87af5f, - 108: 0x87af87, - 109: 0x87afaf, - 110: 0x87afd7, - 111: 0x87afff, - 112: 0x87d700, - 113: 0x87d75f, - 114: 0x87d787, - 115: 0x87d7af, - 116: 0x87d7d7, - 117: 0x87d7ff, - 118: 0x87ff00, - 119: 0x87ff5f, - 120: 0x87ff87, - 121: 0x87ffaf, - 122: 0x87ffd7, - 123: 0x87ffff, - 124: 0xaf0000, - 125: 0xaf005f, - 126: 0xaf0087, - 127: 0xaf00af, - 128: 0xaf00d7, - 129: 0xaf00ff, - 130: 0xaf5f00, - 131: 0xaf5f5f, - 132: 0xaf5f87, - 133: 0xaf5faf, - 134: 0xaf5fd7, - 135: 0xaf5fff, - 136: 0xaf8700, - 137: 0xaf875f, - 138: 0xaf8787, - 139: 0xaf87af, - 140: 0xaf87d7, - 141: 0xaf87ff, - 142: 0xafaf00, - 143: 0xafaf5f, - 144: 0xafaf87, - 145: 0xafafaf, - 146: 0xafafd7, - 147: 0xafafff, - 148: 0xafd700, - 149: 0xafd75f, - 150: 0xafd787, - 151: 0xafd7af, - 152: 0xafd7d7, - 153: 0xafd7ff, - 154: 0xafff00, - 155: 0xafff5f, - 156: 0xafff87, - 157: 0xafffaf, - 158: 0xafffd7, - 159: 0xafffff, - 160: 0xd70000, - 161: 0xd7005f, - 162: 0xd70087, - 163: 0xd700af, - 164: 0xd700d7, - 165: 0xd700ff, - 166: 0xd75f00, - 167: 0xd75f5f, - 168: 0xd75f87, - 169: 0xd75faf, - 170: 0xd75fd7, - 171: 0xd75fff, - 172: 0xd78700, - 173: 0xd7875f, - 174: 0xd78787, - 175: 0xd787af, - 176: 0xd787d7, - 177: 0xd787ff, - 178: 0xd7af00, - 179: 0xd7af5f, - 180: 0xd7af87, - 181: 0xd7afaf, - 182: 0xd7afd7, - 183: 0xd7afff, - 184: 0xd7d700, - 185: 0xd7d75f, - 186: 0xd7d787, - 187: 0xd7d7af, - 188: 0xd7d7d7, - 189: 0xd7d7ff, - 190: 0xd7ff00, - 191: 0xd7ff5f, - 192: 0xd7ff87, - 193: 0xd7ffaf, - 194: 0xd7ffd7, - 195: 0xd7ffff, - 196: 0xff0000, - 197: 0xff005f, - 198: 0xff0087, - 199: 0xff00af, - 200: 0xff00d7, - 201: 0xff00ff, - 202: 0xff5f00, - 203: 0xff5f5f, - 204: 0xff5f87, - 205: 0xff5faf, - 206: 0xff5fd7, - 207: 0xff5fff, - 208: 0xff8700, - 209: 0xff875f, - 210: 0xff8787, - 211: 0xff87af, - 212: 0xff87d7, - 213: 0xff87ff, - 214: 0xffaf00, - 215: 0xffaf5f, - 216: 0xffaf87, - 217: 0xffafaf, - 218: 0xffafd7, - 219: 0xffafff, - 220: 0xffd700, - 221: 0xffd75f, - 222: 0xffd787, - 223: 0xffd7af, - 224: 0xffd7d7, - 225: 0xffd7ff, - 226: 0xffff00, - 227: 0xffff5f, - 228: 0xffff87, - 229: 0xffffaf, - 230: 0xffffd7, - 231: 0xffffff, - 232: 0x080808, - 233: 0x121212, - 234: 0x1c1c1c, - 235: 0x262626, - 236: 0x303030, - 237: 0x3a3a3a, - 238: 0x444444, - 239: 0x4e4e4e, - 240: 0x585858, - 241: 0x626262, - 242: 0x6c6c6c, - 243: 0x767676, - 244: 0x808080, - 245: 0x8a8a8a, - 246: 0x949494, - 247: 0x9e9e9e, - 248: 0xa8a8a8, - 249: 0xb2b2b2, - 250: 0xbcbcbc, - 251: 0xc6c6c6, - 252: 0xd0d0d0, - 253: 0xdadada, - 254: 0xe4e4e4, - 255: 0xeeeeee, -} - -// `\033]0;TITLESTR\007` -func doTitleSequence(er *bytes.Reader) error { - var c byte - var err error - - c, err = er.ReadByte() - if err != nil { - return err - } - if c != '0' && c != '2' { - return nil - } - c, err = er.ReadByte() - if err != nil { - return err - } - if c != ';' { - return nil - } - title := make([]byte, 0, 80) - for { - c, err = er.ReadByte() - if err != nil { - return err - } - if c == 0x07 || c == '\n' { - break - } - title = append(title, c) - } - if len(title) > 0 { - title8, err := syscall.UTF16PtrFromString(string(title)) - if err == nil { - procSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8))) - } - } - return nil -} - -// Write write data on console -func (w *Writer) Write(data []byte) (n int, err error) { - var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - - er := bytes.NewReader(data) - var bw [1]byte -loop: - for { - c1, err := er.ReadByte() - if err != nil { - break loop - } - if c1 != 0x1b { - bw[0] = c1 - w.out.Write(bw[:]) - continue - } - c2, err := er.ReadByte() - if err != nil { - break loop - } - - if c2 == ']' { - if err := doTitleSequence(er); err != nil { - break loop - } - continue - } - if c2 != 0x5b { - continue - } - - var buf bytes.Buffer - var m byte - for { - c, err := er.ReadByte() - if err != nil { - break loop - } - if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { - m = c - break - } - buf.Write([]byte(string(c))) - } - - switch m { - case 'A': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.y -= short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'B': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.y += short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'C': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x += short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'D': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x -= short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'E': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = 0 - csbi.cursorPosition.y += short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'F': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = 0 - csbi.cursorPosition.y -= short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'G': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = short(n - 1) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'H', 'f': - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - if buf.Len() > 0 { - token := strings.Split(buf.String(), ";") - switch len(token) { - case 1: - n1, err := strconv.Atoi(token[0]) - if err != nil { - continue - } - csbi.cursorPosition.y = short(n1 - 1) - case 2: - n1, err := strconv.Atoi(token[0]) - if err != nil { - continue - } - n2, err := strconv.Atoi(token[1]) - if err != nil { - continue - } - csbi.cursorPosition.x = short(n2 - 1) - csbi.cursorPosition.y = short(n1 - 1) - } - } else { - csbi.cursorPosition.y = 0 - } - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'J': - n := 0 - if buf.Len() > 0 { - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - } - var count, written dword - var cursor coord - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - switch n { - case 0: - cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} - count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) - case 1: - cursor = coord{x: csbi.window.left, y: csbi.window.top} - count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.window.top-csbi.cursorPosition.y)*csbi.size.x) - case 2: - cursor = coord{x: csbi.window.left, y: csbi.window.top} - count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) - } - procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - case 'K': - n := 0 - if buf.Len() > 0 { - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - var cursor coord - var count, written dword - switch n { - case 0: - cursor = coord{x: csbi.cursorPosition.x + 1, y: csbi.cursorPosition.y} - count = dword(csbi.size.x - csbi.cursorPosition.x - 1) - case 1: - cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} - count = dword(csbi.size.x - csbi.cursorPosition.x) - case 2: - cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} - count = dword(csbi.size.x) - } - procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - case 'm': - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - attr := csbi.attributes - cs := buf.String() - if cs == "" { - procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr)) - continue - } - token := strings.Split(cs, ";") - for i := 0; i < len(token); i++ { - ns := token[i] - if n, err = strconv.Atoi(ns); err == nil { - switch { - case n == 0 || n == 100: - attr = w.oldattr - case 1 <= n && n <= 5: - attr |= foregroundIntensity - case n == 7: - attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) - case n == 22 || n == 25: - attr |= foregroundIntensity - case n == 27: - attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) - case 30 <= n && n <= 37: - attr &= backgroundMask - if (n-30)&1 != 0 { - attr |= foregroundRed - } - if (n-30)&2 != 0 { - attr |= foregroundGreen - } - if (n-30)&4 != 0 { - attr |= foregroundBlue - } - case n == 38: // set foreground color. - if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") { - if n256, err := strconv.Atoi(token[i+2]); err == nil { - if n256foreAttr == nil { - n256setup() - } - attr &= backgroundMask - attr |= n256foreAttr[n256] - i += 2 - } - } else { - attr = attr & (w.oldattr & backgroundMask) - } - case n == 39: // reset foreground color. - attr &= backgroundMask - attr |= w.oldattr & foregroundMask - case 40 <= n && n <= 47: - attr &= foregroundMask - if (n-40)&1 != 0 { - attr |= backgroundRed - } - if (n-40)&2 != 0 { - attr |= backgroundGreen - } - if (n-40)&4 != 0 { - attr |= backgroundBlue - } - case n == 48: // set background color. - if i < len(token)-2 && token[i+1] == "5" { - if n256, err := strconv.Atoi(token[i+2]); err == nil { - if n256backAttr == nil { - n256setup() - } - attr &= foregroundMask - attr |= n256backAttr[n256] - i += 2 - } - } else { - attr = attr & (w.oldattr & foregroundMask) - } - case n == 49: // reset foreground color. - attr &= foregroundMask - attr |= w.oldattr & backgroundMask - case 90 <= n && n <= 97: - attr = (attr & backgroundMask) - attr |= foregroundIntensity - if (n-90)&1 != 0 { - attr |= foregroundRed - } - if (n-90)&2 != 0 { - attr |= foregroundGreen - } - if (n-90)&4 != 0 { - attr |= foregroundBlue - } - case 100 <= n && n <= 107: - attr = (attr & foregroundMask) - attr |= backgroundIntensity - if (n-100)&1 != 0 { - attr |= backgroundRed - } - if (n-100)&2 != 0 { - attr |= backgroundGreen - } - if (n-100)&4 != 0 { - attr |= backgroundBlue - } - } - procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr)) - } - } - case 'h': - var ci consoleCursorInfo - cs := buf.String() - if cs == "5>" { - procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 0 - procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - } else if cs == "?25" { - procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 1 - procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - } - case 'l': - var ci consoleCursorInfo - cs := buf.String() - if cs == "5>" { - procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 1 - procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - } else if cs == "?25" { - procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 0 - procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - } - case 's': - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - w.oldpos = csbi.cursorPosition - case 'u': - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) - } - } - - return len(data), nil -} - -type consoleColor struct { - rgb int - red bool - green bool - blue bool - intensity bool -} - -func (c consoleColor) foregroundAttr() (attr word) { - if c.red { - attr |= foregroundRed - } - if c.green { - attr |= foregroundGreen - } - if c.blue { - attr |= foregroundBlue - } - if c.intensity { - attr |= foregroundIntensity - } - return -} - -func (c consoleColor) backgroundAttr() (attr word) { - if c.red { - attr |= backgroundRed - } - if c.green { - attr |= backgroundGreen - } - if c.blue { - attr |= backgroundBlue - } - if c.intensity { - attr |= backgroundIntensity - } - return -} - -var color16 = []consoleColor{ - {0x000000, false, false, false, false}, - {0x000080, false, false, true, false}, - {0x008000, false, true, false, false}, - {0x008080, false, true, true, false}, - {0x800000, true, false, false, false}, - {0x800080, true, false, true, false}, - {0x808000, true, true, false, false}, - {0xc0c0c0, true, true, true, false}, - {0x808080, false, false, false, true}, - {0x0000ff, false, false, true, true}, - {0x00ff00, false, true, false, true}, - {0x00ffff, false, true, true, true}, - {0xff0000, true, false, false, true}, - {0xff00ff, true, false, true, true}, - {0xffff00, true, true, false, true}, - {0xffffff, true, true, true, true}, -} - -type hsv struct { - h, s, v float32 -} - -func (a hsv) dist(b hsv) float32 { - dh := a.h - b.h - switch { - case dh > 0.5: - dh = 1 - dh - case dh < -0.5: - dh = -1 - dh - } - ds := a.s - b.s - dv := a.v - b.v - return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv))) -} - -func toHSV(rgb int) hsv { - r, g, b := float32((rgb&0xFF0000)>>16)/256.0, - float32((rgb&0x00FF00)>>8)/256.0, - float32(rgb&0x0000FF)/256.0 - min, max := minmax3f(r, g, b) - h := max - min - if h > 0 { - if max == r { - h = (g - b) / h - if h < 0 { - h += 6 - } - } else if max == g { - h = 2 + (b-r)/h - } else { - h = 4 + (r-g)/h - } - } - h /= 6.0 - s := max - min - if max != 0 { - s /= max - } - v := max - return hsv{h: h, s: s, v: v} -} - -type hsvTable []hsv - -func toHSVTable(rgbTable []consoleColor) hsvTable { - t := make(hsvTable, len(rgbTable)) - for i, c := range rgbTable { - t[i] = toHSV(c.rgb) - } - return t -} - -func (t hsvTable) find(rgb int) consoleColor { - hsv := toHSV(rgb) - n := 7 - l := float32(5.0) - for i, p := range t { - d := hsv.dist(p) - if d < l { - l, n = d, i - } - } - return color16[n] -} - -func minmax3f(a, b, c float32) (min, max float32) { - if a < b { - if b < c { - return a, c - } else if a < c { - return a, b - } else { - return c, b - } - } else { - if a < c { - return b, c - } else if b < c { - return b, a - } else { - return c, a - } - } -} - -var n256foreAttr []word -var n256backAttr []word - -func n256setup() { - n256foreAttr = make([]word, 256) - n256backAttr = make([]word, 256) - t := toHSVTable(color16) - for i, rgb := range color256 { - c := t.find(rgb) - n256foreAttr[i] = c.foregroundAttr() - n256backAttr[i] = c.backgroundAttr() - } -} diff --git a/vendor/github.com/mattn/go-colorable/noncolorable.go b/vendor/github.com/mattn/go-colorable/noncolorable.go deleted file mode 100644 index 9721e16f4..000000000 --- a/vendor/github.com/mattn/go-colorable/noncolorable.go +++ /dev/null @@ -1,55 +0,0 @@ -package colorable - -import ( - "bytes" - "io" -) - -// NonColorable hold writer but remove escape sequence. -type NonColorable struct { - out io.Writer -} - -// NewNonColorable return new instance of Writer which remove escape sequence from Writer. -func NewNonColorable(w io.Writer) io.Writer { - return &NonColorable{out: w} -} - -// Write write data on console -func (w *NonColorable) Write(data []byte) (n int, err error) { - er := bytes.NewReader(data) - var bw [1]byte -loop: - for { - c1, err := er.ReadByte() - if err != nil { - break loop - } - if c1 != 0x1b { - bw[0] = c1 - w.out.Write(bw[:]) - continue - } - c2, err := er.ReadByte() - if err != nil { - break loop - } - if c2 != 0x5b { - continue - } - - var buf bytes.Buffer - for { - c, err := er.ReadByte() - if err != nil { - break loop - } - if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { - break - } - buf.Write([]byte(string(c))) - } - } - - return len(data), nil -} diff --git a/vendor/github.com/mattn/go-isatty/.travis.yml b/vendor/github.com/mattn/go-isatty/.travis.yml deleted file mode 100644 index b9f8b239c..000000000 --- a/vendor/github.com/mattn/go-isatty/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go -go: - - tip - -before_install: - - go get github.com/mattn/goveralls - - go get golang.org/x/tools/cmd/cover -script: - - $HOME/gopath/bin/goveralls -repotoken 3gHdORO5k5ziZcWMBxnd9LrMZaJs8m9x5 diff --git a/vendor/github.com/mattn/go-isatty/LICENSE b/vendor/github.com/mattn/go-isatty/LICENSE deleted file mode 100644 index 65dc692b6..000000000 --- a/vendor/github.com/mattn/go-isatty/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -Copyright (c) Yasuhiro MATSUMOTO - -MIT License (Expat) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/mattn/go-isatty/README.md b/vendor/github.com/mattn/go-isatty/README.md deleted file mode 100644 index 1e69004bb..000000000 --- a/vendor/github.com/mattn/go-isatty/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# go-isatty - -[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty) -[![Build Status](https://travis-ci.org/mattn/go-isatty.svg?branch=master)](https://travis-ci.org/mattn/go-isatty) -[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master) -[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty) - -isatty for golang - -## Usage - -```go -package main - -import ( - "fmt" - "github.com/mattn/go-isatty" - "os" -) - -func main() { - if isatty.IsTerminal(os.Stdout.Fd()) { - fmt.Println("Is Terminal") - } else if isatty.IsCygwinTerminal(os.Stdout.Fd()) { - fmt.Println("Is Cygwin/MSYS2 Terminal") - } else { - fmt.Println("Is Not Terminal") - } -} -``` - -## Installation - -``` -$ go get github.com/mattn/go-isatty -``` - -## License - -MIT - -## Author - -Yasuhiro Matsumoto (a.k.a mattn) - -## Thanks - -* k-takata: base idea for IsCygwinTerminal - - https://github.com/k-takata/go-iscygpty diff --git a/vendor/github.com/mattn/go-isatty/doc.go b/vendor/github.com/mattn/go-isatty/doc.go deleted file mode 100644 index 17d4f90eb..000000000 --- a/vendor/github.com/mattn/go-isatty/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package isatty implements interface to isatty -package isatty diff --git a/vendor/github.com/mattn/go-isatty/example_test.go b/vendor/github.com/mattn/go-isatty/example_test.go deleted file mode 100644 index fa8f7e745..000000000 --- a/vendor/github.com/mattn/go-isatty/example_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package isatty_test - -import ( - "fmt" - "os" - - "github.com/mattn/go-isatty" -) - -func Example() { - if isatty.IsTerminal(os.Stdout.Fd()) { - fmt.Println("Is Terminal") - } else if isatty.IsCygwinTerminal(os.Stdout.Fd()) { - fmt.Println("Is Cygwin/MSYS2 Terminal") - } else { - fmt.Println("Is Not Terminal") - } -} diff --git a/vendor/github.com/mattn/go-isatty/isatty_appengine.go b/vendor/github.com/mattn/go-isatty/isatty_appengine.go deleted file mode 100644 index 9584a9884..000000000 --- a/vendor/github.com/mattn/go-isatty/isatty_appengine.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build appengine - -package isatty - -// IsTerminal returns true if the file descriptor is terminal which -// is always false on on appengine classic which is a sandboxed PaaS. -func IsTerminal(fd uintptr) bool { - return false -} - -// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 -// terminal. This is also always false on this environment. -func IsCygwinTerminal(fd uintptr) bool { - return false -} diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go deleted file mode 100644 index 42f2514d1..000000000 --- a/vendor/github.com/mattn/go-isatty/isatty_bsd.go +++ /dev/null @@ -1,18 +0,0 @@ -// +build darwin freebsd openbsd netbsd dragonfly -// +build !appengine - -package isatty - -import ( - "syscall" - "unsafe" -) - -const ioctlReadTermios = syscall.TIOCGETA - -// IsTerminal return true if the file descriptor is terminal. -func IsTerminal(fd uintptr) bool { - var termios syscall.Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 -} diff --git a/vendor/github.com/mattn/go-isatty/isatty_linux.go b/vendor/github.com/mattn/go-isatty/isatty_linux.go deleted file mode 100644 index 7384cf991..000000000 --- a/vendor/github.com/mattn/go-isatty/isatty_linux.go +++ /dev/null @@ -1,18 +0,0 @@ -// +build linux -// +build !appengine,!ppc64,!ppc64le - -package isatty - -import ( - "syscall" - "unsafe" -) - -const ioctlReadTermios = syscall.TCGETS - -// IsTerminal return true if the file descriptor is terminal. -func IsTerminal(fd uintptr) bool { - var termios syscall.Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 -} diff --git a/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go b/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go deleted file mode 100644 index 44e5d2130..000000000 --- a/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build linux -// +build ppc64 ppc64le - -package isatty - -import ( - "unsafe" - - syscall "golang.org/x/sys/unix" -) - -const ioctlReadTermios = syscall.TCGETS - -// IsTerminal return true if the file descriptor is terminal. -func IsTerminal(fd uintptr) bool { - var termios syscall.Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 -} diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go deleted file mode 100644 index ff4de3d9a..000000000 --- a/vendor/github.com/mattn/go-isatty/isatty_others.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build !windows -// +build !appengine - -package isatty - -// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 -// terminal. This is also always false on this environment. -func IsCygwinTerminal(fd uintptr) bool { - return false -} diff --git a/vendor/github.com/mattn/go-isatty/isatty_others_test.go b/vendor/github.com/mattn/go-isatty/isatty_others_test.go deleted file mode 100644 index a2091cf47..000000000 --- a/vendor/github.com/mattn/go-isatty/isatty_others_test.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build !windows - -package isatty - -import ( - "os" - "testing" -) - -func TestTerminal(t *testing.T) { - // test for non-panic - IsTerminal(os.Stdout.Fd()) -} - -func TestCygwinPipeName(t *testing.T) { - if IsCygwinTerminal(os.Stdout.Fd()) { - t.Fatal("should be false always") - } -} diff --git a/vendor/github.com/mattn/go-isatty/isatty_solaris.go b/vendor/github.com/mattn/go-isatty/isatty_solaris.go deleted file mode 100644 index 1f0c6bf53..000000000 --- a/vendor/github.com/mattn/go-isatty/isatty_solaris.go +++ /dev/null @@ -1,16 +0,0 @@ -// +build solaris -// +build !appengine - -package isatty - -import ( - "golang.org/x/sys/unix" -) - -// IsTerminal returns true if the given file descriptor is a terminal. -// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c -func IsTerminal(fd uintptr) bool { - var termio unix.Termio - err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio) - return err == nil -} diff --git a/vendor/github.com/mattn/go-isatty/isatty_windows.go b/vendor/github.com/mattn/go-isatty/isatty_windows.go deleted file mode 100644 index af51cbcaa..000000000 --- a/vendor/github.com/mattn/go-isatty/isatty_windows.go +++ /dev/null @@ -1,94 +0,0 @@ -// +build windows -// +build !appengine - -package isatty - -import ( - "strings" - "syscall" - "unicode/utf16" - "unsafe" -) - -const ( - fileNameInfo uintptr = 2 - fileTypePipe = 3 -) - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") - procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx") - procGetFileType = kernel32.NewProc("GetFileType") -) - -func init() { - // Check if GetFileInformationByHandleEx is available. - if procGetFileInformationByHandleEx.Find() != nil { - procGetFileInformationByHandleEx = nil - } -} - -// IsTerminal return true if the file descriptor is terminal. -func IsTerminal(fd uintptr) bool { - var st uint32 - r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) - return r != 0 && e == 0 -} - -// Check pipe name is used for cygwin/msys2 pty. -// Cygwin/MSYS2 PTY has a name like: -// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master -func isCygwinPipeName(name string) bool { - token := strings.Split(name, "-") - if len(token) < 5 { - return false - } - - if token[0] != `\msys` && token[0] != `\cygwin` { - return false - } - - if token[1] == "" { - return false - } - - if !strings.HasPrefix(token[2], "pty") { - return false - } - - if token[3] != `from` && token[3] != `to` { - return false - } - - if token[4] != "master" { - return false - } - - return true -} - -// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 -// terminal. -func IsCygwinTerminal(fd uintptr) bool { - if procGetFileInformationByHandleEx == nil { - return false - } - - // Cygwin/msys's pty is a pipe. - ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0) - if ft != fileTypePipe || e != 0 { - return false - } - - var buf [2 + syscall.MAX_PATH]uint16 - r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), - 4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)), - uintptr(len(buf)*2), 0, 0) - if r == 0 || e != 0 { - return false - } - - l := *(*uint32)(unsafe.Pointer(&buf)) - return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2]))) -} diff --git a/vendor/github.com/mattn/go-isatty/isatty_windows_test.go b/vendor/github.com/mattn/go-isatty/isatty_windows_test.go deleted file mode 100644 index 777e8a603..000000000 --- a/vendor/github.com/mattn/go-isatty/isatty_windows_test.go +++ /dev/null @@ -1,35 +0,0 @@ -// +build windows - -package isatty - -import ( - "testing" -) - -func TestCygwinPipeName(t *testing.T) { - tests := []struct { - name string - result bool - }{ - {``, false}, - {`\msys-`, false}, - {`\cygwin-----`, false}, - {`\msys-x-PTY5-pty1-from-master`, false}, - {`\cygwin-x-PTY5-from-master`, false}, - {`\cygwin-x-pty2-from-toaster`, false}, - {`\cygwin--pty2-from-master`, false}, - {`\\cygwin-x-pty2-from-master`, false}, - {`\cygwin-x-pty2-from-master-`, true}, // for the feature - {`\cygwin-e022582115c10879-pty4-from-master`, true}, - {`\msys-e022582115c10879-pty4-to-master`, true}, - {`\cygwin-e022582115c10879-pty4-to-master`, true}, - } - - for _, test := range tests { - want := test.result - got := isCygwinPipeName(test.name) - if want != got { - t.Fatalf("isatty(%q): got %v, want %v:", test.name, got, want) - } - } -} diff --git a/vendor/gopkg.in/VividCortex/ewma.v1/.github/ISSUE_TEMPLATE.md b/vendor/gopkg.in/VividCortex/ewma.v1/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index f3c19086c..000000000 --- a/vendor/gopkg.in/VividCortex/ewma.v1/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,10 +0,0 @@ -Before you file an issue, please consider: - -We only accept pull requests for minor fixes or improvements. This includes: - -* Small bug fixes -* Typos -* Documentation or comments - -Please open issues to discuss new features. Pull requests for new features will be rejected, -so we recommend forking the repository and making changes in your fork for your use case. diff --git a/vendor/gopkg.in/VividCortex/ewma.v1/.github/PULL_REQUEST_TEMPLATE.md b/vendor/gopkg.in/VividCortex/ewma.v1/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 0c22b9267..000000000 --- a/vendor/gopkg.in/VividCortex/ewma.v1/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,10 +0,0 @@ -Before you create a pull request, please consider: - -We only accept pull requests for minor fixes or improvements. This includes: - -* Small bug fixes -* Typos -* Documentation or comments - -Please open issues to discuss new features. Pull requests for new features will be rejected, -so we recommend forking the repository and making changes in your fork for your use case. diff --git a/vendor/gopkg.in/VividCortex/ewma.v1/.gitignore b/vendor/gopkg.in/VividCortex/ewma.v1/.gitignore deleted file mode 100644 index 6c7104aef..000000000 --- a/vendor/gopkg.in/VividCortex/ewma.v1/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.DS_Store -.*.sw? diff --git a/vendor/gopkg.in/VividCortex/ewma.v1/LICENSE b/vendor/gopkg.in/VividCortex/ewma.v1/LICENSE deleted file mode 100644 index a78d643ed..000000000 --- a/vendor/gopkg.in/VividCortex/ewma.v1/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License - -Copyright (c) 2013 VividCortex - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/gopkg.in/VividCortex/ewma.v1/README.md b/vendor/gopkg.in/VividCortex/ewma.v1/README.md deleted file mode 100644 index 7aab61b87..000000000 --- a/vendor/gopkg.in/VividCortex/ewma.v1/README.md +++ /dev/null @@ -1,140 +0,0 @@ -# EWMA [![GoDoc](https://godoc.org/github.com/VividCortex/ewma?status.svg)](https://godoc.org/github.com/VividCortex/ewma) ![Build Status](https://circleci.com/gh/VividCortex/moving_average.png?circle-token=1459fa37f9ca0e50cef05d1963146d96d47ea523) - -This repo provides Exponentially Weighted Moving Average algorithms, or EWMAs for short, [based on our -Quantifying Abnormal Behavior talk](https://vividcortex.com/blog/2013/07/23/a-fast-go-library-for-exponential-moving-averages/). - -### Exponentially Weighted Moving Average - -An exponentially weighted moving average is a way to continuously compute a type of -average for a series of numbers, as the numbers arrive. After a value in the series is -added to the average, its weight in the average decreases exponentially over time. This -biases the average towards more recent data. EWMAs are useful for several reasons, chiefly -their inexpensive computational and memory cost, as well as the fact that they represent -the recent central tendency of the series of values. - -The EWMA algorithm requires a decay factor, alpha. The larger the alpha, the more the average -is biased towards recent history. The alpha must be between 0 and 1, and is typically -a fairly small number, such as 0.04. We will discuss the choice of alpha later. - -The algorithm works thus, in pseudocode: - -1. Multiply the next number in the series by alpha. -2. Multiply the current value of the average by 1 minus alpha. -3. Add the result of steps 1 and 2, and store it as the new current value of the average. -4. Repeat for each number in the series. - -There are special-case behaviors for how to initialize the current value, and these vary -between implementations. One approach is to start with the first value in the series; -another is to average the first 10 or so values in the series using an arithmetic average, -and then begin the incremental updating of the average. Each method has pros and cons. - -It may help to look at it pictorially. Suppose the series has five numbers, and we choose -alpha to be 0.50 for simplicity. Here's the series, with numbers in the neighborhood of 300. - -![Data Series](https://user-images.githubusercontent.com/279875/28242350-463289a2-6977-11e7-88ca-fd778ccef1f0.png) - -Now let's take the moving average of those numbers. First we set the average to the value -of the first number. - -![EWMA Step 1](https://user-images.githubusercontent.com/279875/28242353-464c96bc-6977-11e7-9981-dc4e0789c7ba.png) - -Next we multiply the next number by alpha, multiply the current value by 1-alpha, and add -them to generate a new value. - -![EWMA Step 2](https://user-images.githubusercontent.com/279875/28242351-464abefa-6977-11e7-95d0-43900f29bef2.png) - -This continues until we are done. - -![EWMA Step N](https://user-images.githubusercontent.com/279875/28242352-464c58f0-6977-11e7-8cd0-e01e4efaac7f.png) - -Notice how each of the values in the series decays by half each time a new value -is added, and the top of the bars in the lower portion of the image represents the -size of the moving average. It is a smoothed, or low-pass, average of the original -series. - -For further reading, see [Exponentially weighted moving average](http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average) on wikipedia. - -### Choosing Alpha - -Consider a fixed-size sliding-window moving average (not an exponentially weighted moving average) -that averages over the previous N samples. What is the average age of each sample? It is N/2. - -Now suppose that you wish to construct a EWMA whose samples have the same average age. The formula -to compute the alpha required for this is: alpha = 2/(N+1). Proof is in the book -"Production and Operations Analysis" by Steven Nahmias. - -So, for example, if you have a time-series with samples once per second, and you want to get the -moving average over the previous minute, you should use an alpha of .032786885. This, by the way, -is the constant alpha used for this repository's SimpleEWMA. - -### Implementations - -This repository contains two implementations of the EWMA algorithm, with different properties. - -The implementations all conform to the MovingAverage interface, and the constructor returns -that type. - -Current implementations assume an implicit time interval of 1.0 between every sample added. -That is, the passage of time is treated as though it's the same as the arrival of samples. -If you need time-based decay when samples are not arriving precisely at set intervals, then -this package will not support your needs at present. - -#### SimpleEWMA - -A SimpleEWMA is designed for low CPU and memory consumption. It **will** have different behavior than the VariableEWMA -for multiple reasons. It has no warm-up period and it uses a constant -decay. These properties let it use less memory. It will also behave -differently when it's equal to zero, which is assumed to mean -uninitialized, so if a value is likely to actually become zero over time, -then any non-zero value will cause a sharp jump instead of a small change. - -#### VariableEWMA - -Unlike SimpleEWMA, this supports a custom age which must be stored, and thus uses more memory. -It also has a "warmup" time when you start adding values to it. It will report a value of 0.0 -until you have added the required number of samples to it. It uses some memory to store the -number of samples added to it. As a result it uses a little over twice the memory of SimpleEWMA. - -## Usage - -### API Documentation - -View the GoDoc generated documentation [here](http://godoc.org/github.com/VividCortex/ewma). - -```go -package main -import "github.com/VividCortex/ewma" - -func main() { - samples := [100]float64{ - 4599, 5711, 4746, 4621, 5037, 4218, 4925, 4281, 5207, 5203, 5594, 5149, - } - - e := ewma.NewMovingAverage() //=> Returns a SimpleEWMA if called without params - a := ewma.NewMovingAverage(5) //=> returns a VariableEWMA with a decay of 2 / (5 + 1) - - for _, f := range samples { - e.Add(f) - a.Add(f) - } - - e.Value() //=> 13.577404704631077 - a.Value() //=> 1.5806140565521463e-12 -} -``` - -## Contributing - -We only accept pull requests for minor fixes or improvements. This includes: - -* Small bug fixes -* Typos -* Documentation or comments - -Please open issues to discuss new features. Pull requests for new features will be rejected, -so we recommend forking the repository and making changes in your fork for your use case. - -## License - -This repository is Copyright (c) 2013 VividCortex, Inc. All rights reserved. -It is licensed under the MIT license. Please see the LICENSE file for applicable license terms. diff --git a/vendor/gopkg.in/VividCortex/ewma.v1/ewma.go b/vendor/gopkg.in/VividCortex/ewma.v1/ewma.go deleted file mode 100644 index 44d5d53e3..000000000 --- a/vendor/gopkg.in/VividCortex/ewma.v1/ewma.go +++ /dev/null @@ -1,126 +0,0 @@ -// Package ewma implements exponentially weighted moving averages. -package ewma - -// Copyright (c) 2013 VividCortex, Inc. All rights reserved. -// Please see the LICENSE file for applicable license terms. - -const ( - // By default, we average over a one-minute period, which means the average - // age of the metrics in the period is 30 seconds. - AVG_METRIC_AGE float64 = 30.0 - - // The formula for computing the decay factor from the average age comes - // from "Production and Operations Analysis" by Steven Nahmias. - DECAY float64 = 2 / (float64(AVG_METRIC_AGE) + 1) - - // For best results, the moving average should not be initialized to the - // samples it sees immediately. The book "Production and Operations - // Analysis" by Steven Nahmias suggests initializing the moving average to - // the mean of the first 10 samples. Until the VariableEwma has seen this - // many samples, it is not "ready" to be queried for the value of the - // moving average. This adds some memory cost. - WARMUP_SAMPLES uint8 = 10 -) - -// MovingAverage is the interface that computes a moving average over a time- -// series stream of numbers. The average may be over a window or exponentially -// decaying. -type MovingAverage interface { - Add(float64) - Value() float64 - Set(float64) -} - -// NewMovingAverage constructs a MovingAverage that computes an average with the -// desired characteristics in the moving window or exponential decay. If no -// age is given, it constructs a default exponentially weighted implementation -// that consumes minimal memory. The age is related to the decay factor alpha -// by the formula given for the DECAY constant. It signifies the average age -// of the samples as time goes to infinity. -func NewMovingAverage(age ...float64) MovingAverage { - if len(age) == 0 || age[0] == AVG_METRIC_AGE { - return new(SimpleEWMA) - } - return &VariableEWMA{ - decay: 2 / (age[0] + 1), - } -} - -// A SimpleEWMA represents the exponentially weighted moving average of a -// series of numbers. It WILL have different behavior than the VariableEWMA -// for multiple reasons. It has no warm-up period and it uses a constant -// decay. These properties let it use less memory. It will also behave -// differently when it's equal to zero, which is assumed to mean -// uninitialized, so if a value is likely to actually become zero over time, -// then any non-zero value will cause a sharp jump instead of a small change. -// However, note that this takes a long time, and the value may just -// decays to a stable value that's close to zero, but which won't be mistaken -// for uninitialized. See http://play.golang.org/p/litxBDr_RC for example. -type SimpleEWMA struct { - // The current value of the average. After adding with Add(), this is - // updated to reflect the average of all values seen thus far. - value float64 -} - -// Add adds a value to the series and updates the moving average. -func (e *SimpleEWMA) Add(value float64) { - if e.value == 0 { // this is a proxy for "uninitialized" - e.value = value - } else { - e.value = (value * DECAY) + (e.value * (1 - DECAY)) - } -} - -// Value returns the current value of the moving average. -func (e *SimpleEWMA) Value() float64 { - return e.value -} - -// Set sets the EWMA's value. -func (e *SimpleEWMA) Set(value float64) { - e.value = value -} - -// VariableEWMA represents the exponentially weighted moving average of a series of -// numbers. Unlike SimpleEWMA, it supports a custom age, and thus uses more memory. -type VariableEWMA struct { - // The multiplier factor by which the previous samples decay. - decay float64 - // The current value of the average. - value float64 - // The number of samples added to this instance. - count uint8 -} - -// Add adds a value to the series and updates the moving average. -func (e *VariableEWMA) Add(value float64) { - switch { - case e.count < WARMUP_SAMPLES: - e.count++ - e.value += value - case e.count == WARMUP_SAMPLES: - e.count++ - e.value = e.value / float64(WARMUP_SAMPLES) - e.value = (value * e.decay) + (e.value * (1 - e.decay)) - default: - e.value = (value * e.decay) + (e.value * (1 - e.decay)) - } -} - -// Value returns the current value of the average, or 0.0 if the series hasn't -// warmed up yet. -func (e *VariableEWMA) Value() float64 { - if e.count <= WARMUP_SAMPLES { - return 0.0 - } - - return e.value -} - -// Set sets the EWMA's value. -func (e *VariableEWMA) Set(value float64) { - e.value = value - if e.count <= WARMUP_SAMPLES { - e.count = WARMUP_SAMPLES + 1 - } -} diff --git a/vendor/gopkg.in/VividCortex/ewma.v1/ewma_test.go b/vendor/gopkg.in/VividCortex/ewma.v1/ewma_test.go deleted file mode 100644 index 8060a859f..000000000 --- a/vendor/gopkg.in/VividCortex/ewma.v1/ewma_test.go +++ /dev/null @@ -1,103 +0,0 @@ -package ewma - -// Copyright (c) 2013 VividCortex, Inc. All rights reserved. -// Please see the LICENSE file for applicable license terms. - -import ( - "math" - "testing" -) - -const testMargin = 0.00000001 - -var samples = [100]float64{ - 4599, 5711, 4746, 4621, 5037, 4218, 4925, 4281, 5207, 5203, 5594, 5149, - 4948, 4994, 6056, 4417, 4973, 4714, 4964, 5280, 5074, 4913, 4119, 4522, - 4631, 4341, 4909, 4750, 4663, 5167, 3683, 4964, 5151, 4892, 4171, 5097, - 3546, 4144, 4551, 6557, 4234, 5026, 5220, 4144, 5547, 4747, 4732, 5327, - 5442, 4176, 4907, 3570, 4684, 4161, 5206, 4952, 4317, 4819, 4668, 4603, - 4885, 4645, 4401, 4362, 5035, 3954, 4738, 4545, 5433, 6326, 5927, 4983, - 5364, 4598, 5071, 5231, 5250, 4621, 4269, 3953, 3308, 3623, 5264, 5322, - 5395, 4753, 4936, 5315, 5243, 5060, 4989, 4921, 4480, 3426, 3687, 4220, - 3197, 5139, 6101, 5279, -} - -func withinMargin(a, b float64) bool { - return math.Abs(a-b) <= testMargin -} - -func TestSimpleEWMA(t *testing.T) { - var e SimpleEWMA - for _, f := range samples { - e.Add(f) - } - if !withinMargin(e.Value(), 4734.500946466118) { - t.Errorf("e.Value() is %v, wanted %v", e.Value(), 4734.500946466118) - } - e.Set(1.0) - if e.Value() != 1.0 { - t.Errorf("e.Value() is %d", e.Value()) - } -} - -func TestVariableEWMA(t *testing.T) { - e := NewMovingAverage(30) - for _, f := range samples { - e.Add(f) - } - if !withinMargin(e.Value(), 4734.500946466118) { - t.Errorf("e.Value() is %v, wanted %v", e.Value(), 4734.500946466118) - } - e.Set(1.0) - if e.Value() != 1.0 { - t.Errorf("e.Value() is %d", e.Value()) - } -} - -func TestVariableEWMA2(t *testing.T) { - e := NewMovingAverage(5) - for _, f := range samples { - e.Add(f) - } - if !withinMargin(e.Value(), 5015.397367486725) { - t.Errorf("e.Value() is %v, wanted %v", e.Value(), 5015.397367486725) - } -} - -func TestVariableEWMAWarmup(t *testing.T) { - e := NewMovingAverage(5) - for i, f := range samples { - e.Add(f) - - // all values returned during warmup should be 0.0 - if uint8(i) < WARMUP_SAMPLES { - if e.Value() != 0.0 { - t.Errorf("e.Value() is %v, expected %v", e.Value(), 0.0) - } - } - } - e = NewMovingAverage(5) - e.Set(5) - e.Add(1) - if e.Value() >= 5 { - t.Errorf("e.Value() is %d, expected it to decay towards 0", e.Value()) - } -} - -func TestVariableEWMAWarmup2(t *testing.T) { - e := NewMovingAverage(5) - testSamples := [12]float64{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10000, 1} - for i, f := range testSamples { - e.Add(f) - - // all values returned during warmup should be 0.0 - if uint8(i) < WARMUP_SAMPLES { - if e.Value() != 0.0 { - t.Errorf("e.Value() is %v, expected %v", e.Value(), 0.0) - } - } - } - if val := e.Value(); val == 1.0 { - t.Errorf("e.Value() is expected to be greater than %v", 1.0) - } -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/.gitignore b/vendor/gopkg.in/cheggaaa/pb.v2/.gitignore deleted file mode 100644 index 48b8bf907..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vendor/ diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/.travis.yml b/vendor/gopkg.in/cheggaaa/pb.v2/.travis.yml deleted file mode 100644 index 7d3bc2399..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: go -go: -- 1.7 -- 1.8 -sudo: false -gobuild_args: -v -race -os: -- linux -- osx -before_install: - - go get github.com/mattn/goveralls -script: - - $HOME/gopath/bin/goveralls -service=travis-ci -ignore=termutil/* diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.lock b/vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.lock deleted file mode 100644 index fd90c4b6a..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.lock +++ /dev/null @@ -1,63 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - name = "github.com/mattn/go-colorable" - packages = ["."] - revision = "ed8eb9e318d7a84ce5915b495b7d35e0cfe7b5a8" - version = "v0.0.6" - -[[projects]] - name = "github.com/mattn/go-isatty" - packages = ["."] - revision = "3a115632dcd687f9c8cd01679c83a06a0e21c1f3" - version = "v0.0.1" - -[[projects]] - branch = "master" - name = "golang.org/x/sys" - packages = ["unix"] - revision = "b90f89a1e7a9c1f6b918820b3daa7f08488c8594" - -[[projects]] - name = "gopkg.in/VividCortex/ewma.v1" - packages = ["."] - revision = "2f8aa9741ab4b5b80945c750b871131b88ef5b7f" - version = "v1.0" - -[[projects]] - name = "gopkg.in/cheggaaa/pb.v2" - packages = ["termutil"] - revision = "180c76fdb3025713f501cd481e47810a9c715bd7" - version = "v2.0.1" - -[[projects]] - name = "gopkg.in/fatih/color.v1" - packages = ["."] - revision = "570b54cabe6b8eb0bc2dfce68d964677d63b5260" - version = "v1.5.0" - -[[projects]] - name = "gopkg.in/mattn/go-colorable.v0" - packages = ["."] - revision = "d228849504861217f796da67fae4f6e347643f15" - version = "v0.0.7" - -[[projects]] - name = "gopkg.in/mattn/go-isatty.v0" - packages = ["."] - revision = "fc9e8d8ef48496124e79ae0df75490096eccf6fe" - version = "v0.0.2" - -[[projects]] - name = "gopkg.in/mattn/go-runewidth.v0" - packages = ["."] - revision = "9e777a8366cce605130a531d2cd6363d07ad7317" - version = "v0.0.2" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "cf10fbfc96962122f1a56c1752a1d5dab64799ffedc58460e1ab1465d2bef5e2" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.toml b/vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.toml deleted file mode 100644 index d5f2fef13..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/Gopkg.toml +++ /dev/null @@ -1,91 +0,0 @@ - -## Gopkg.toml example (these lines may be deleted) - -## "metadata" defines metadata about the project that could be used by other independent -## systems. The metadata defined here will be ignored by dep. -# [metadata] -# key1 = "value that convey data to other systems" -# system1-data = "value that is used by a system" -# system2-data = "value that is used by another system" - -## "required" lists a set of packages (not projects) that must be included in -## Gopkg.lock. This list is merged with the set of packages imported by the current -## project. Use it when your project needs a package it doesn't explicitly import - -## including "main" packages. -# required = ["github.com/user/thing/cmd/thing"] - -## "ignored" lists a set of packages (not projects) that are ignored when -## dep statically analyzes source code. Ignored packages can be in this project, -## or in a dependency. -# ignored = ["github.com/user/project/badpkg"] - -## Constraints are rules for how directly imported projects -## may be incorporated into the depgraph. They are respected by -## dep whether coming from the Gopkg.toml of the current project or a dependency. -# [[constraint]] -## Required: the root import path of the project being constrained. -# name = "github.com/user/project" -# -## Recommended: the version constraint to enforce for the project. -## Only one of "branch", "version" or "revision" can be specified. -# version = "1.0.0" -# branch = "master" -# revision = "abc123" -# -## Optional: an alternate location (URL or import path) for the project's source. -# source = "https://github.com/myfork/package.git" -# -## "metadata" defines metadata about the dependency or override that could be used -## by other independent systems. The metadata defined here will be ignored by dep. -# [metadata] -# key1 = "value that convey data to other systems" -# system1-data = "value that is used by a system" -# system2-data = "value that is used by another system" - -## Overrides have the same structure as [[constraint]], but supersede all -## [[constraint]] declarations from all projects. Only [[override]] from -## the current project's are applied. -## -## Overrides are a sledgehammer. Use them only as a last resort. -# [[override]] -## Required: the root import path of the project being constrained. -# name = "github.com/user/project" -# -## Optional: specifying a version constraint override will cause all other -## constraints on this project to be ignored; only the overridden constraint -## need be satisfied. -## Again, only one of "branch", "version" or "revision" can be specified. -# version = "1.0.0" -# branch = "master" -# revision = "abc123" -# -## Optional: specifying an alternate source location as an override will -## enforce that the alternate location is used for that project, regardless of -## what source location any dependent projects specify. -# source = "https://github.com/myfork/package.git" - - - -[[constraint]] - name = "gopkg.in/VividCortex/ewma.v1" - version = "1.0.0" - -[[constraint]] - name = "gopkg.in/cheggaaa/pb.v2" - version = "2.0.1" - -[[constraint]] - name = "gopkg.in/fatih/color.v1" - version = "1.5.0" - -[[constraint]] - name = "gopkg.in/mattn/go-colorable.v0" - version = "0.0.7" - -[[constraint]] - name = "gopkg.in/mattn/go-isatty.v0" - version = "0.0.2" - -[[constraint]] - name = "gopkg.in/mattn/go-runewidth.v0" - version = "0.0.2" diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/LICENSE b/vendor/gopkg.in/cheggaaa/pb.v2/LICENSE deleted file mode 100644 index 511970333..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) 2012-2015, Sergey Cherepanov -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/README.md b/vendor/gopkg.in/cheggaaa/pb.v2/README.md deleted file mode 100644 index 907124e19..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/README.md +++ /dev/null @@ -1,70 +0,0 @@ -# Terminal progress bar for Go - -[![Coverage Status](https://coveralls.io/repos/github/cheggaaa/pb/badge.svg?branch=v2)](https://coveralls.io/github/cheggaaa/pb?branch=v2) - -### It's beta, some features may be changed - -This is proposal for the second version of progress bar -- based on text/template -- can take custom elements -- using colors is easy - -## Installation - -``` -go get gopkg.in/cheggaaa/pb.v2 -``` - -## Usage - -```Go -package main - -import ( - "gopkg.in/cheggaaa/pb.v2" - "time" -) - -func main() { - simple() - fromPreset() - customTemplate(`Custom template: {{counters . }}`) - customTemplate(`{{ red "With colors:" }} {{bar . | green}} {{speed . | blue }}`) - customTemplate(`{{ red "With funcs:" }} {{ bar . "<" "-" (cycle . "↖" "↗" "↘" "↙" ) "." ">"}} {{speed . | rndcolor }}`) - customTemplate(`{{ bar . "[<" "·····•·····" (rnd "ᗧ" "◔" "◕" "◷" ) "•" ">]"}}`) -} - -func simple() { - count := 1000 - bar := pb.StartNew(count) - for i := 0; i < count; i++ { - bar.Increment() - time.Sleep(time.Millisecond * 2) - } - bar.Finish() -} - -func fromPreset() { - count := 1000 - //bar := pb.Default.Start(total) - //bar := pb.Simple.Start(total) - bar := pb.Full.Start(count) - defer bar.Finish() - bar.Set("prefix", "fromPreset(): ") - for i := 0; i < count/2; i++ { - bar.Add(2) - time.Sleep(time.Millisecond * 4) - } -} - -func customTemplate(tmpl string) { - count := 1000 - bar := pb.ProgressBarTemplate(tmpl).Start(count) - defer bar.Finish() - for i := 0; i < count/2; i++ { - bar.Add(2) - time.Sleep(time.Millisecond * 4) - } -} - -``` \ No newline at end of file diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/element.go b/vendor/gopkg.in/cheggaaa/pb.v2/element.go deleted file mode 100644 index 965183fe7..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/element.go +++ /dev/null @@ -1,290 +0,0 @@ -package pb - -import ( - "bytes" - "fmt" - "math" - "sync" - "time" -) - -const ( - adElPlaceholder = "%_ad_el_%" - adElPlaceholderLen = len(adElPlaceholder) -) - -var ( - defaultBarEls = [5]string{"[", "-", ">", "_", "]"} -) - -// Element is an interface for bar elements -type Element interface { - ProgressElement(state *State, args ...string) string -} - -// ElementFunc type implements Element interface and created for simplify elements -type ElementFunc func(state *State, args ...string) string - -// ProgressElement just call self func -func (e ElementFunc) ProgressElement(state *State, args ...string) string { - return e(state, args...) -} - -var elementsM sync.Mutex - -var elements = map[string]Element{ - "percent": ElementPercent, - "counters": ElementCounters, - "bar": adaptiveWrap(ElementBar), - "speed": ElementSpeed, - "rtime": ElementRemainingTime, - "etime": ElementElapsedTime, - "string": ElementString, - "cycle": ElementCycle, -} - -// RegisterElement give you a chance to use custom elements -func RegisterElement(name string, el Element, adaptive bool) { - if adaptive { - el = adaptiveWrap(el) - } - elementsM.Lock() - elements[name] = el - elementsM.Unlock() -} - -type argsHelper []string - -func (args argsHelper) getOr(n int, value string) string { - if len(args) > n { - return args[n] - } - return value -} - -func (args argsHelper) getNotEmptyOr(n int, value string) (v string) { - if v = args.getOr(n, value); v == "" { - return value - } - return -} - -func adaptiveWrap(el Element) Element { - return ElementFunc(func(state *State, args ...string) string { - state.recalc = append(state.recalc, ElementFunc(func(s *State, _ ...string) (result string) { - s.adaptive = true - result = el.ProgressElement(s, args...) - s.adaptive = false - return - })) - return adElPlaceholder - }) -} - -// ElementPercent shows current percent of progress. -// Optionally can take one or two string arguments. -// First string will be used as value for format float64, default is "%.02f%%". -// Second string will be used when percent can't be calculated, default is "?%" -// In template use as follows: {{percent .}} or {{percent . "%.03f%%"}} or {{percent . "%.03f%%" "?"}} -var ElementPercent ElementFunc = func(state *State, args ...string) string { - argsh := argsHelper(args) - if state.Total() > 0 { - return fmt.Sprintf( - argsh.getNotEmptyOr(0, "%.02f%%"), - float64(state.Value())/(float64(state.Total())/float64(100)), - ) - } - return argsh.getOr(1, "?%") -} - -// ElementCounters shows current and total values. -// Optionally can take one or two string arguments. -// First string will be used as format value when Total is present (>0). Default is "%s / %s" -// Second string will be used when total <= 0. Default is "%[1]s" -// In template use as follows: {{counters .}} or {{counters . "%s/%s"}} or {{counters . "%s/%s" "%s/?"}} -var ElementCounters ElementFunc = func(state *State, args ...string) string { - var f string - if state.Total() > 0 { - f = argsHelper(args).getNotEmptyOr(0, "%s / %s") - } else { - f = argsHelper(args).getNotEmptyOr(1, "%[1]s") - } - return fmt.Sprintf(f, state.Format(state.Value()), state.Format(state.Total())) -} - -type elementKey int - -const ( - barObj elementKey = iota - speedObj - cycleObj -) - -type bar struct { - eb [5][]byte // elements in bytes - cc [5]int // cell counts - buf *bytes.Buffer -} - -func (p *bar) write(state *State, eln, width int) int { - repeat := width / p.cc[eln] - for i := 0; i < repeat; i++ { - p.buf.Write(p.eb[eln]) - } - StripStringToBuffer(string(p.eb[eln]), width%p.cc[eln], p.buf) - return width -} - -func getProgressObj(state *State, args ...string) (p *bar) { - var ok bool - if p, ok = state.Get(barObj).(*bar); !ok { - p = &bar{ - buf: bytes.NewBuffer(nil), - } - state.Set(barObj, p) - } - argsH := argsHelper(args) - for i := range p.eb { - arg := argsH.getNotEmptyOr(i, defaultBarEls[i]) - if string(p.eb[i]) != arg { - p.cc[i] = CellCount(arg) - p.eb[i] = []byte(arg) - if p.cc[i] == 0 { - p.cc[i] = 1 - p.eb[i] = []byte(" ") - } - } - } - return -} - -// ElementBar make progress bar view [-->__] -// Optionally can take up to 5 string arguments. Defaults is "[", "-", ">", "_", "]" -// In template use as follows: {{bar . }} or {{bar . "<" "oOo" "|" "~" ">"}} -// Color args: {{bar . (red "[") (green "-") ... -var ElementBar ElementFunc = func(state *State, args ...string) string { - // init - var p = getProgressObj(state, args...) - - total, value := state.Total(), state.Value() - if total < 0 { - total = -total - } - if value < 0 { - value = -value - } - - // check for overflow - if total != 0 && value > total { - total = value - } - - p.buf.Reset() - - var widthLeft = state.AdaptiveElWidth() - if widthLeft <= 0 || !state.IsAdaptiveWidth() { - widthLeft = 30 - } - - // write left border - if p.cc[0] < widthLeft { - widthLeft -= p.write(state, 0, p.cc[0]) - } else { - p.write(state, 0, widthLeft) - return p.buf.String() - } - - // check right border size - if p.cc[4] < widthLeft { - // write later - widthLeft -= p.cc[4] - } else { - p.write(state, 4, widthLeft) - return p.buf.String() - } - - var curCount int - - if total > 0 { - // calculate count of currenct space - curCount = int(math.Ceil((float64(value) / float64(total)) * float64(widthLeft))) - } - - // write bar - if total == value && state.IsFinished() { - widthLeft -= p.write(state, 1, curCount) - } else if toWrite := curCount - p.cc[2]; toWrite > 0 { - widthLeft -= p.write(state, 1, toWrite) - widthLeft -= p.write(state, 2, p.cc[2]) - } else if curCount > 0 { - widthLeft -= p.write(state, 2, curCount) - } - if widthLeft > 0 { - widthLeft -= p.write(state, 3, widthLeft) - } - // write right border - p.write(state, 4, p.cc[4]) - // cut result and return string - return p.buf.String() -} - -// ElementRemainingTime calculates remaining time based on speed (EWMA) -// Optionally can take one or two string arguments. -// First string will be used as value for format time duration string, default is "%s". -// Second string will be used when bar finished and value indicates elapsed time, default is "%s" -// Third string will be used when value not available, default is "?" -// In template use as follows: {{rtime .}} or {{rtime . "%s remain"}} or {{rtime . "%s remain" "%s total" "???"}} -var ElementRemainingTime ElementFunc = func(state *State, args ...string) string { - var rts string - sp := getSpeedObj(state).value(state) - if !state.IsFinished() { - if sp > 0 { - remain := float64(state.Total() - state.Value()) - remainDur := time.Duration(remain/sp) * time.Second - rts = remainDur.String() - } else { - return argsHelper(args).getOr(2, "?") - } - } else { - rts = state.Time().Truncate(time.Second).Sub(state.StartTime().Truncate(time.Second)).String() - return fmt.Sprintf(argsHelper(args).getOr(1, "%s"), rts) - } - return fmt.Sprintf(argsHelper(args).getOr(0, "%s"), rts) -} - -// ElementElapsedTime shows elapsed time -// Optionally cat take one argument - it's format for time string. -// In template use as follows: {{etime .}} or {{etime . "%s elapsed"}} -var ElementElapsedTime ElementFunc = func(state *State, args ...string) string { - etm := state.Time().Truncate(time.Second).Sub(state.StartTime().Truncate(time.Second)) - return fmt.Sprintf(argsHelper(args).getOr(0, "%s"), etm.String()) -} - -// ElementString get value from bar by given key and print them -// bar.Set("myKey", "string to print") -// In template use as follows: {{string . "myKey"}} -var ElementString ElementFunc = func(state *State, args ...string) string { - if len(args) == 0 { - return "" - } - v := state.Get(args[0]) - if v == nil { - return "" - } - return fmt.Sprint(v) -} - -// ElementCycle return next argument for every call -// In template use as follows: {{cycle . "1" "2" "3"}} -// Or mix width other elements: {{ bar . "" "" (cycle . "↖" "↗" "↘" "↙" )}} -var ElementCycle ElementFunc = func(state *State, args ...string) string { - if len(args) == 0 { - return "" - } - n, _ := state.Get(cycleObj).(int) - if n >= len(args) { - n = 0 - } - state.Set(cycleObj, n+1) - return args[n] -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/element_test.go b/vendor/gopkg.in/cheggaaa/pb.v2/element_test.go deleted file mode 100644 index d572c4a6a..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/element_test.go +++ /dev/null @@ -1,278 +0,0 @@ -package pb - -import ( - "fmt" - "strings" - "testing" - "time" - - "gopkg.in/fatih/color.v1" -) - -func testState(total, value int64, maxWidth int, bools ...bool) (s *State) { - s = &State{ - total: total, - current: value, - adaptiveElWidth: maxWidth, - ProgressBar: new(ProgressBar), - } - if len(bools) > 0 { - s.Set(Bytes, bools[0]) - } - if len(bools) > 1 && bools[1] { - s.adaptive = true - } - return -} - -func testElementBarString(t *testing.T, state *State, el Element, want string, args ...string) { - if state.ProgressBar == nil { - state.ProgressBar = new(ProgressBar) - } - res := el.ProgressElement(state, args...) - if res != want { - t.Errorf("Unexpected result: '%s'; want: '%s'", res, want) - } - if state.IsAdaptiveWidth() && state.AdaptiveElWidth() != CellCount(res) { - t.Errorf("Unepected width: %d; want: %d", CellCount(res), state.AdaptiveElWidth()) - } -} - -func TestElementPercent(t *testing.T) { - testElementBarString(t, testState(100, 50, 0), ElementPercent, "50.00%") - testElementBarString(t, testState(100, 50, 0), ElementPercent, "50 percent", "%v percent") - testElementBarString(t, testState(0, 50, 0), ElementPercent, "?%") - testElementBarString(t, testState(0, 50, 0), ElementPercent, "unkn", "%v%%", "unkn") -} - -func TestElementCounters(t *testing.T) { - testElementBarString(t, testState(100, 50, 0), ElementCounters, "50 / 100") - testElementBarString(t, testState(100, 50, 0), ElementCounters, "50 of 100", "%s of %s") - testElementBarString(t, testState(100, 50, 0, true), ElementCounters, "50 B of 100 B", "%s of %s") - testElementBarString(t, testState(100, 50, 0, true), ElementCounters, "50 B / 100 B") - testElementBarString(t, testState(0, 50, 0, true), ElementCounters, "50 B") - testElementBarString(t, testState(0, 50, 0, true), ElementCounters, "50 B / ?", "", "%[1]s / ?") -} - -func TestElementBar(t *testing.T) { - // short - testElementBarString(t, testState(100, 50, 1, false, true), ElementBar, "[") - testElementBarString(t, testState(100, 50, 2, false, true), ElementBar, "[]") - testElementBarString(t, testState(100, 50, 3, false, true), ElementBar, "[>]") - testElementBarString(t, testState(100, 50, 4, false, true), ElementBar, "[>_]") - testElementBarString(t, testState(100, 50, 5, false, true), ElementBar, "[->_]") - // middle - testElementBarString(t, testState(100, 50, 10, false, true), ElementBar, "[--->____]") - testElementBarString(t, testState(100, 50, 10, false, true), ElementBar, "<--->____>", "<", "", "", "", ">") - // finished - st := testState(100, 100, 10, false, true) - st.finished = true - testElementBarString(t, st, ElementBar, "[--------]") - // empty color - st = testState(100, 50, 10, false, true) - st.Set(Terminal, true) - color.NoColor = false - testElementBarString(t, st, ElementBar, " --->____]", color.RedString("%s", "")) - // empty - testElementBarString(t, testState(0, 50, 10, false, true), ElementBar, "[________]") - // full - testElementBarString(t, testState(20, 20, 10, false, true), ElementBar, "[------->]") - // everflow - testElementBarString(t, testState(20, 50, 10, false, true), ElementBar, "[------->]") - // small width - testElementBarString(t, testState(20, 50, 2, false, true), ElementBar, "[]") - testElementBarString(t, testState(20, 50, 1, false, true), ElementBar, "[") - // negative counters - testElementBarString(t, testState(-50, -150, 10, false, true), ElementBar, "[------->]") - testElementBarString(t, testState(-150, -50, 10, false, true), ElementBar, "[-->_____]") - testElementBarString(t, testState(50, -150, 10, false, true), ElementBar, "[------->]") - testElementBarString(t, testState(-50, 150, 10, false, true), ElementBar, "[------->]") - // long entities / unicode - f1 := []string{"進捗|", "многобайт", "active", "пусто", "|end"} - testElementBarString(t, testState(100, 50, 1, false, true), ElementBar, " ", f1...) - testElementBarString(t, testState(100, 50, 3, false, true), ElementBar, "進 ", f1...) - testElementBarString(t, testState(100, 50, 4, false, true), ElementBar, "進捗", f1...) - testElementBarString(t, testState(100, 50, 29, false, true), ElementBar, "進捗|многactiveпустопусто|end", f1...) - testElementBarString(t, testState(100, 50, 11, false, true), ElementBar, "進捗|aп|end", f1...) - - // unicode - f2 := []string{"⚑", "⚒", "⚟", "⟞", "⚐"} - testElementBarString(t, testState(100, 50, 10, false, true), ElementBar, "⚑⚒⚒⚒⚟⟞⟞⟞⟞⚐", f2...) - - // no adaptive - testElementBarString(t, testState(0, 50, 10), ElementBar, "[____________________________]") - - var formats = [][]string{ - []string{}, - f1, f2, - } - - // all widths / extreme values - // check for panic and correct width - for _, f := range formats { - for tt := int64(-2); tt < 12; tt++ { - for v := int64(-2); v < 12; v++ { - state := testState(tt, v, 0, false, true) - for w := -2; w < 20; w++ { - state.adaptiveElWidth = w - res := ElementBar(state, f...) - var we = w - if we <= 0 { - we = 30 - } - if CellCount(res) != we { - t.Errorf("Unexpected len(%d): '%s'", we, res) - } - } - } - } - } -} - -func TestElementSpeed(t *testing.T) { - var state = testState(1000, 0, 0, false) - state.time = time.Now() - for i := int64(0); i < 10; i++ { - state.id = uint64(i) + 1 - state.current += 42 - state.time = state.time.Add(time.Second) - state.finished = i == 9 - if state.finished { - state.current += 100 - } - r := ElementSpeed(state) - r2 := ElementSpeed(state) - if r != r2 { - t.Errorf("Must be the same: '%s' vs '%s'", r, r2) - } - if i < 1 { - // do not calc first result - if w := "? p/s"; r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - } else if state.finished { - if w := "58 p/s"; r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - state.time = state.time.Add(-time.Hour) - r = ElementSpeed(state) - if w := "? p/s"; r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - } else { - if w := "42 p/s"; r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - } - } -} - -func TestElementRemainingTime(t *testing.T) { - var state = testState(100, 0, 0, false) - state.time = time.Now() - state.startTime = state.time - for i := int64(0); i < 10; i++ { - state.id = uint64(i) + 1 - state.time = state.time.Add(time.Second) - state.finished = i == 9 - r := ElementRemainingTime(state) - if i < 1 { - // do not calc first two results - if w := "?"; r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - } else if state.finished { - // final elapsed time - if w := "10s"; r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - } else { - w := fmt.Sprintf("%ds", 10-i) - if r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - } - state.current += 10 - } -} - -func TestElementElapsedTime(t *testing.T) { - var state = testState(1000, 0, 0, false) - state.startTime = time.Now() - state.time = state.startTime - for i := int64(0); i < 10; i++ { - r := ElementElapsedTime(state) - if w := fmt.Sprintf("%ds", i); r != w { - t.Errorf("Unexpected result[%d]: '%s' vs '%s'", i, r, w) - } - state.time = state.time.Add(time.Second) - } -} - -func TestElementString(t *testing.T) { - var state = testState(0, 0, 0, false) - testElementBarString(t, state, ElementString, "", "myKey") - state.Set("myKey", "my value") - testElementBarString(t, state, ElementString, "my value", "myKey") - state.Set("myKey", "my value1") - testElementBarString(t, state, ElementString, "my value1", "myKey") - testElementBarString(t, state, ElementString, "") -} - -func TestElementCycle(t *testing.T) { - var state = testState(0, 0, 0, false) - testElementBarString(t, state, ElementCycle, "") - testElementBarString(t, state, ElementCycle, "1", "1", "2", "3") - testElementBarString(t, state, ElementCycle, "2", "1", "2", "3") - testElementBarString(t, state, ElementCycle, "3", "1", "2", "3") - testElementBarString(t, state, ElementCycle, "1", "1", "2", "3") - testElementBarString(t, state, ElementCycle, "2", "1", "2") - testElementBarString(t, state, ElementCycle, "1", "1", "2") -} - -func TestAdaptiveWrap(t *testing.T) { - var state = testState(0, 0, 0, false) - state.id = 1 - state.Set("myKey", "my value") - el := adaptiveWrap(ElementString) - testElementBarString(t, state, el, adElPlaceholder, "myKey") - if v := state.recalc[0].ProgressElement(state); v != "my value" { - t.Errorf("Unexpected result: %s", v) - } - state.id = 2 - testElementBarString(t, state, el, adElPlaceholder, "myKey1") - state.Set("myKey", "my value1") - if v := state.recalc[0].ProgressElement(state); v != "my value1" { - t.Errorf("Unexpected result: %s", v) - } -} - -func TestRegisterElement(t *testing.T) { - var testEl ElementFunc = func(state *State, args ...string) string { - return strings.Repeat("*", state.AdaptiveElWidth()) - } - RegisterElement("testEl", testEl, true) - result := ProgressBarTemplate(`{{testEl . }}`).New(0).SetWidth(5).String() - if result != "*****" { - t.Errorf("Unexpected result: '%v'", result) - } -} - -func BenchmarkBar(b *testing.B) { - var formats = map[string][]string{ - "simple": []string{".", ".", ".", ".", "."}, - "unicode": []string{"⚑", "⚒", "⚟", "⟞", "⚐"}, - "color": []string{color.RedString("%s", "."), color.RedString("%s", "."), color.RedString("%s", "."), color.RedString("%s", "."), color.RedString("%s", ".")}, - "long": []string{"..", "..", "..", "..", ".."}, - "longunicode": []string{"⚑⚑", "⚒⚒", "⚟⚟", "⟞⟞", "⚐⚐"}, - } - for name, args := range formats { - state := testState(100, 50, 100, false, true) - b.Run(name, func(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - ElementBar(state, args...) - } - }) - } -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/pb.go b/vendor/gopkg.in/cheggaaa/pb.v2/pb.go deleted file mode 100644 index c8e7b52ae..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/pb.go +++ /dev/null @@ -1,540 +0,0 @@ -package pb - -import ( - "bytes" - "fmt" - "io" - "os" - "strconv" - "strings" - "sync" - "sync/atomic" - "text/template" - "time" - - "gopkg.in/cheggaaa/pb.v2/termutil" - "gopkg.in/mattn/go-colorable.v0" - "gopkg.in/mattn/go-isatty.v0" -) - -// Version of ProgressBar library -const Version = "2.0.6" - -type key int - -const ( - // Bytes means we're working with byte sizes. Numbers will print as Kb, Mb, etc - // bar.Set(pb.Bytes, true) - Bytes key = 1 << iota - - // Terminal means we're will print to terminal and can use ascii sequences - // Also we're will try to use terminal width - Terminal - - // Static means progress bar will not update automaticly - Static - - // ReturnSymbol - by default in terminal mode it's '\r' - ReturnSymbol - - // Color by default is true when output is tty, but you can set to false for disabling colors - Color -) - -const ( - defaultBarWidth = 100 - defaultRefreshRate = time.Millisecond * 200 -) - -// New creates new ProgressBar object -func New(total int) *ProgressBar { - return New64(int64(total)) -} - -// New64 creates new ProgressBar object using int64 as total -func New64(total int64) *ProgressBar { - pb := new(ProgressBar) - return pb.SetTotal(total) -} - -// StartNew starts new ProgressBar with Default template -func StartNew(total int) *ProgressBar { - return New(total).Start() -} - -// Start64 starts new ProgressBar with Default template. Using int64 as total. -func Start64(total int64) *ProgressBar { - return New64(total).Start() -} - -var ( - terminalWidth = termutil.TerminalWidth - isTerminal = isatty.IsTerminal - isCygwinTerminal = isatty.IsCygwinTerminal -) - -// ProgressBar is the main object of bar -type ProgressBar struct { - current, total int64 - width int - mu sync.RWMutex - rm sync.Mutex - vars map[interface{}]interface{} - elements map[string]Element - output io.Writer - coutput io.Writer - nocoutput io.Writer - startTime time.Time - refreshRate time.Duration - tmpl *template.Template - state *State - buf *bytes.Buffer - ticker *time.Ticker - finish chan struct{} - finished bool - configured bool - err error -} - -func (pb *ProgressBar) configure() { - if pb.configured { - return - } - pb.configured = true - - if pb.vars == nil { - pb.vars = make(map[interface{}]interface{}) - } - if pb.output == nil { - pb.output = os.Stderr - } - - if pb.tmpl == nil { - pb.tmpl, pb.err = getTemplate(string(Default)) - if pb.err != nil { - return - } - } - if pb.vars[Terminal] == nil { - if f, ok := pb.output.(*os.File); ok { - if isTerminal(f.Fd()) || isCygwinTerminal(f.Fd()) { - pb.vars[Terminal] = true - } - } - } - if pb.vars[ReturnSymbol] == nil { - if tm, ok := pb.vars[Terminal].(bool); ok && tm { - pb.vars[ReturnSymbol] = "\r" - } - } - if pb.vars[Color] == nil { - if tm, ok := pb.vars[Terminal].(bool); ok && tm { - pb.vars[Color] = true - } - } - if pb.refreshRate == 0 { - pb.refreshRate = defaultRefreshRate - } - if f, ok := pb.output.(*os.File); ok { - pb.coutput = colorable.NewColorable(f) - } else { - pb.coutput = pb.output - } - pb.nocoutput = colorable.NewNonColorable(pb.output) -} - -// Start starts the bar -func (pb *ProgressBar) Start() *ProgressBar { - pb.mu.Lock() - defer pb.mu.Unlock() - if pb.finish != nil { - return pb - } - pb.configure() - pb.finished = false - pb.state = nil - pb.startTime = time.Now() - if st, ok := pb.vars[Static].(bool); ok && st { - return pb - } - pb.finish = make(chan struct{}) - pb.ticker = time.NewTicker(pb.refreshRate) - go pb.writer(pb.finish) - return pb -} - -func (pb *ProgressBar) writer(finish chan struct{}) { - for { - select { - case <-pb.ticker.C: - pb.write(false) - case <-finish: - pb.ticker.Stop() - pb.write(true) - finish <- struct{}{} - return - } - } -} - -// Write performs write to the output -func (pb *ProgressBar) Write() *ProgressBar { - pb.mu.RLock() - finished := pb.finished - pb.mu.RUnlock() - pb.write(finished) - return pb -} - -func (pb *ProgressBar) write(finish bool) { - result, width := pb.render() - if pb.Err() != nil { - return - } - if pb.GetBool(Terminal) { - if r := (width - CellCount(result)); r > 0 { - result += strings.Repeat(" ", r) - } - } - if ret, ok := pb.Get(ReturnSymbol).(string); ok { - result = ret + result - if finish && ret == "\r" { - result += "\n" - } - } - if pb.GetBool(Color) { - pb.coutput.Write([]byte(result)) - } else { - pb.nocoutput.Write([]byte(result)) - } -} - -// Total return current total bar value -func (pb *ProgressBar) Total() int64 { - return atomic.LoadInt64(&pb.total) -} - -// SetTotal sets the total bar value -func (pb *ProgressBar) SetTotal(value int64) *ProgressBar { - atomic.StoreInt64(&pb.total, value) - return pb -} - -// SetCurrent sets the current bar value -func (pb *ProgressBar) SetCurrent(value int64) *ProgressBar { - atomic.StoreInt64(&pb.current, value) - return pb -} - -// Current return current bar value -func (pb *ProgressBar) Current() int64 { - return atomic.LoadInt64(&pb.current) -} - -// Add adding given int64 value to bar value -func (pb *ProgressBar) Add64(value int64) *ProgressBar { - atomic.AddInt64(&pb.current, value) - return pb -} - -// Add adding given int value to bar value -func (pb *ProgressBar) Add(value int) *ProgressBar { - return pb.Add64(int64(value)) -} - -// Increment atomically increments the progress -func (pb *ProgressBar) Increment() *ProgressBar { - return pb.Add64(1) -} - -// Set sets any value by any key -func (pb *ProgressBar) Set(key, value interface{}) *ProgressBar { - pb.mu.Lock() - defer pb.mu.Unlock() - if pb.vars == nil { - pb.vars = make(map[interface{}]interface{}) - } - pb.vars[key] = value - return pb -} - -// Get return value by key -func (pb *ProgressBar) Get(key interface{}) interface{} { - pb.mu.RLock() - defer pb.mu.RUnlock() - if pb.vars == nil { - return nil - } - return pb.vars[key] -} - -// GetBool return value by key and try to convert there to boolean -// If value doesn't set or not boolean - return false -func (pb *ProgressBar) GetBool(key interface{}) bool { - if v, ok := pb.Get(key).(bool); ok { - return v - } - return false -} - -// SetWidth sets the bar width -// When given value <= 0 would be using the terminal width (if possible) or default value. -func (pb *ProgressBar) SetWidth(width int) *ProgressBar { - pb.mu.Lock() - pb.width = width - pb.mu.Unlock() - return pb -} - -// Width return the bar width -// It's current terminal width or settled over 'SetWidth' value. -func (pb *ProgressBar) Width() (width int) { - defer func() { - if r := recover(); r != nil { - width = defaultBarWidth - } - }() - pb.mu.RLock() - width = pb.width - pb.mu.RUnlock() - if width <= 0 { - var err error - if width, err = terminalWidth(); err != nil { - return defaultBarWidth - } - } - return -} - -func (pb *ProgressBar) SetRefreshRate(dur time.Duration) *ProgressBar { - pb.mu.Lock() - if dur > 0 { - pb.refreshRate = dur - } - pb.mu.Unlock() - return pb -} - -// SetWriter sets the io.Writer. Bar will write in this writer -// By default this is os.Stderr -func (pb *ProgressBar) SetWriter(w io.Writer) *ProgressBar { - pb.mu.Lock() - pb.output = w - pb.configured = false - pb.configure() - pb.mu.Unlock() - return pb -} - -// StartTime return the time when bar started -func (pb *ProgressBar) StartTime() time.Time { - pb.mu.RLock() - defer pb.mu.RUnlock() - return pb.startTime -} - -// Format convert int64 to string according to the current settings -func (pb *ProgressBar) Format(v int64) string { - if pb.GetBool(Bytes) { - return formatBytes(v) - } - return strconv.FormatInt(v, 10) -} - -// Finish stops the bar -func (pb *ProgressBar) Finish() *ProgressBar { - pb.mu.Lock() - if pb.finished { - pb.mu.Unlock() - return pb - } - finishChan := pb.finish - pb.finished = true - pb.mu.Unlock() - if finishChan != nil { - finishChan <- struct{}{} - <-finishChan - pb.mu.Lock() - pb.finish = nil - pb.mu.Unlock() - } - return pb -} - -// IsStarted indicates progress bar state -func (pb *ProgressBar) IsStarted() bool { - pb.mu.RLock() - defer pb.mu.RUnlock() - return pb.finish != nil -} - -// SetTemplateString sets ProgressBar tempate string and parse it -func (pb *ProgressBar) SetTemplateString(tmpl string) *ProgressBar { - pb.mu.Lock() - defer pb.mu.Unlock() - pb.tmpl, pb.err = getTemplate(tmpl) - return pb -} - -// SetTemplateString sets ProgressBarTempate and parse it -func (pb *ProgressBar) SetTemplate(tmpl ProgressBarTemplate) *ProgressBar { - return pb.SetTemplateString(string(tmpl)) -} - -// NewProxyReader creates a wrapper for given reader, but with progress handle -// Takes io.Reader or io.ReadCloser -// Also, it automatically switches progress bar to handle units as bytes -func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader { - pb.Set(Bytes, true) - return &Reader{r, pb} -} - -func (pb *ProgressBar) render() (result string, width int) { - defer func() { - if r := recover(); r != nil { - pb.SetErr(fmt.Errorf("render panic: %v", r)) - } - }() - pb.rm.Lock() - defer pb.rm.Unlock() - pb.mu.Lock() - pb.configure() - if pb.state == nil { - pb.state = &State{ProgressBar: pb} - pb.buf = bytes.NewBuffer(nil) - } - if pb.startTime.IsZero() { - pb.startTime = time.Now() - } - pb.state.id++ - pb.state.finished = pb.finished - pb.state.time = time.Now() - pb.mu.Unlock() - - pb.state.width = pb.Width() - width = pb.state.width - pb.state.total = pb.Total() - pb.state.current = pb.Current() - pb.buf.Reset() - - if e := pb.tmpl.Execute(pb.buf, pb.state); e != nil { - pb.SetErr(e) - return "", 0 - } - - result = pb.buf.String() - - aec := len(pb.state.recalc) - if aec == 0 { - // no adaptive elements - return - } - - staticWidth := CellCount(result) - (aec * adElPlaceholderLen) - - if pb.state.Width()-staticWidth <= 0 { - result = strings.Replace(result, adElPlaceholder, "", -1) - result = StripString(result, pb.state.Width()) - } else { - pb.state.adaptiveElWidth = (width - staticWidth) / aec - for _, el := range pb.state.recalc { - result = strings.Replace(result, adElPlaceholder, el.ProgressElement(pb.state), 1) - } - } - pb.state.recalc = pb.state.recalc[:0] - return -} - -// SetErr sets error to the ProgressBar -// Error will be available over Err() -func (pb *ProgressBar) SetErr(err error) *ProgressBar { - pb.mu.Lock() - pb.err = err - pb.mu.Unlock() - return pb -} - -// Err return possible error -// When all ok - will be nil -// May contain template.Execute errors -func (pb *ProgressBar) Err() error { - pb.mu.RLock() - defer pb.mu.RUnlock() - return pb.err -} - -// String return currrent string representation of ProgressBar -func (pb *ProgressBar) String() string { - res, _ := pb.render() - return res -} - -// ProgressElement implements Element interface -func (pb *ProgressBar) ProgressElement(s *State, args ...string) string { - if s.IsAdaptiveWidth() { - pb.SetWidth(s.AdaptiveElWidth()) - } - return pb.String() -} - -// State represents the current state of bar -// Need for bar elements -type State struct { - *ProgressBar - - id uint64 - total, current int64 - width, adaptiveElWidth int - finished, adaptive bool - time time.Time - - recalc []Element -} - -// Id it's the current state identifier -// - incremental -// - starts with 1 -// - resets after finish/start -func (s *State) Id() uint64 { - return s.id -} - -// Total it's bar int64 total -func (s *State) Total() int64 { - return s.total -} - -// Value it's current value -func (s *State) Value() int64 { - return s.current -} - -// Width of bar -func (s *State) Width() int { - return s.width -} - -// AdaptiveElWidth - adaptive elements must return string with given cell count (when AdaptiveElWidth > 0) -func (s *State) AdaptiveElWidth() int { - return s.adaptiveElWidth -} - -// IsAdaptiveWidth returns true when element must be shown as adaptive -func (s *State) IsAdaptiveWidth() bool { - return s.adaptive -} - -// IsFinished return true when bar is finished -func (s *State) IsFinished() bool { - return s.finished -} - -// IsFirst return true only in first render -func (s *State) IsFirst() bool { - return s.id == 1 -} - -// Time when state was created -func (s *State) Time() time.Time { - return s.time -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/pb_test.go b/vendor/gopkg.in/cheggaaa/pb.v2/pb_test.go deleted file mode 100644 index 929778466..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/pb_test.go +++ /dev/null @@ -1,219 +0,0 @@ -package pb - -import ( - "bytes" - "errors" - "fmt" - "strings" - "testing" - "time" - - "gopkg.in/fatih/color.v1" -) - -func TestPBBasic(t *testing.T) { - bar := new(ProgressBar) - var a, e int64 - if a, e = bar.Total(), 0; a != e { - t.Errorf("Unexpected total: actual: %v; expected: %v", a, e) - } - if a, e = bar.Current(), 0; a != e { - t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) - } - bar.SetCurrent(10).SetTotal(20) - if a, e = bar.Total(), 20; a != e { - t.Errorf("Unexpected total: actual: %v; expected: %v", a, e) - } - if a, e = bar.Current(), 10; a != e { - t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) - } - bar.Add(5) - if a, e = bar.Current(), 15; a != e { - t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) - } - bar.Increment() - if a, e = bar.Current(), 16; a != e { - t.Errorf("Unexpected current: actual: %v; expected: %v", a, e) - } -} - -func TestPBWidth(t *testing.T) { - terminalWidth = func() (int, error) { - return 50, nil - } - // terminal width - bar := new(ProgressBar) - if a, e := bar.Width(), 50; a != e { - t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) - } - // terminal width error - terminalWidth = func() (int, error) { - return 0, errors.New("test error") - } - if a, e := bar.Width(), defaultBarWidth; a != e { - t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) - } - // terminal width panic - terminalWidth = func() (int, error) { - panic("test") - return 0, nil - } - if a, e := bar.Width(), defaultBarWidth; a != e { - t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) - } - // set negative terminal width - bar.SetWidth(-42) - if a, e := bar.Width(), defaultBarWidth; a != e { - t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) - } - // set terminal width - bar.SetWidth(42) - if a, e := bar.Width(), 42; a != e { - t.Errorf("Unexpected width: actual: %v; expected: %v", a, e) - } -} - -func TestPBTemplate(t *testing.T) { - bar := new(ProgressBar) - result := bar.SetTotal(100).SetCurrent(50).SetWidth(40).String() - expected := "50 / 100 [------->________] 50.00% ? p/s" - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) - } - - // check strip - result = bar.SetWidth(8).String() - expected = "50 / 100" - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) - } - - // invalid template - for _, invalidTemplate := range []string{ - `{{invalid template`, `{{speed}}`, - } { - bar.SetTemplateString(invalidTemplate) - result = bar.String() - expected = "" - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) - } - if err := bar.Err(); err == nil { - t.Errorf("Must be error") - } - } - - // simple template without adaptive elemnts - bar.SetTemplateString(`{{counters . }}`) - result = bar.String() - expected = "50 / 100" - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) - } -} - -func TestPBStartFinish(t *testing.T) { - bar := ProgressBarTemplate(`{{counters . }}`).New(0) - for i := int64(0); i < 2; i++ { - if bar.IsStarted() { - t.Error("Must be false") - } - var buf = bytes.NewBuffer(nil) - bar.SetTotal(100). - SetCurrent(int64(i)). - SetWidth(7). - Set(Terminal, true). - SetWriter(buf). - SetRefreshRate(time.Millisecond * 20). - Start() - if !bar.IsStarted() { - t.Error("Must be true") - } - time.Sleep(time.Millisecond * 100) - bar.Finish() - if buf.Len() == 0 { - t.Error("no writes") - } - var resultsString = strings.TrimPrefix(buf.String(), "\r") - if !strings.HasSuffix(resultsString, "\n") { - t.Error("No end \\n symb") - } else { - resultsString = resultsString[:len(resultsString)-1] - } - var results = strings.Split(resultsString, "\r") - if len(results) < 3 { - t.Errorf("Unexpected writes count: %v", len(results)) - } - exp := fmt.Sprintf("%d / 100", i) - for i, res := range results { - if res != exp { - t.Errorf("Unexpected result[%d]: '%v'", i, res) - } - } - // test second finish call - bar.Finish() - } -} - -func TestPBFlags(t *testing.T) { - // Static - color.NoColor = false - buf := bytes.NewBuffer(nil) - bar := ProgressBarTemplate(`{{counters . | red}}`).New(100) - bar.Set(Static, true).SetCurrent(50).SetWidth(10).SetWriter(buf).Start() - if bar.IsStarted() { - t.Error("Must be false") - } - bar.Write() - result := buf.String() - expected := "50 / 100" - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected) - } - if !bar.state.IsFirst() { - t.Error("must be true") - } - // Color - bar.Set(Color, true) - buf.Reset() - bar.Write() - result = buf.String() - expected = color.RedString("50 / 100") - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected) - } - if bar.state.IsFirst() { - t.Error("must be false") - } - // Terminal - bar.Set(Terminal, true).SetWriter(buf) - buf.Reset() - bar.Write() - result = buf.String() - expected = "\r" + color.RedString("50 / 100") + " " - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n'%s'\n'%s'", result, expected) - } -} - -func BenchmarkRender(b *testing.B) { - var formats = []string{ - string(Simple), - string(Default), - string(Full), - `{{string . "prefix" | red}}{{counters . | green}} {{bar . | yellow}} {{percent . | cyan}} {{speed . | cyan}}{{string . "suffix" | cyan}}`, - } - var names = []string{ - "Simple", "Default", "Full", "Color", - } - for i, tmpl := range formats { - bar := new(ProgressBar) - bar.SetTemplateString(tmpl).SetWidth(100) - b.Run(names[i], func(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - bar.String() - } - }) - } -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/preset.go b/vendor/gopkg.in/cheggaaa/pb.v2/preset.go deleted file mode 100644 index 1934c0e88..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/preset.go +++ /dev/null @@ -1,17 +0,0 @@ -package pb - -import () - -var ( - // Full - preset with all default available elements - // Example: 'Prefix 20/100 [-->______] 20% 1 p/s ETA 1m Suffix' - Full ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }} {{speed . }} {{rtime . "ETA %s"}}{{string . "suffix"}}` - - // Default - preset like Full but without elapsed time - // Example: 'Prefix 20/100 [-->______] 20% 1 p/s ETA 1m Suffix' - Default ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }} {{speed . }}{{string . "suffix"}}` - - // Simple - preset without speed and any timers. Only counters, bar and percents - // Example: 'Prefix 20/100 [-->______] 20% Suffix' - Simple ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }}{{string . "suffix"}}` -) diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/reader.go b/vendor/gopkg.in/cheggaaa/pb.v2/reader.go deleted file mode 100644 index f2e60a09d..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/reader.go +++ /dev/null @@ -1,26 +0,0 @@ -package pb - -import ( - "io" -) - -// Reader it's a wrapper for given reader, but with progress handle -type Reader struct { - io.Reader - bar *ProgressBar -} - -// Read reads bytes from wrapped reader and add amount of bytes to progress bar -func (r *Reader) Read(p []byte) (n int, err error) { - n, err = r.Reader.Read(p) - r.bar.Add(n) - return -} - -// Close the wrapped reader when it implements io.Closer -func (r *Reader) Close() (err error) { - if closer, ok := r.Reader.(io.Closer); ok { - return closer.Close() - } - return -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/reader_test.go b/vendor/gopkg.in/cheggaaa/pb.v2/reader_test.go deleted file mode 100644 index a5d745a0b..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/reader_test.go +++ /dev/null @@ -1,60 +0,0 @@ -package pb - -import ( - "testing" -) - -func TestPBProxyReader(t *testing.T) { - bar := new(ProgressBar) - if bar.GetBool(Bytes) { - t.Errorf("By default bytes must be false") - } - - testReader := new(testReaderCloser) - proxyReader := bar.NewProxyReader(testReader) - - if !bar.GetBool(Bytes) { - t.Errorf("Bytes must be true after call NewProxyReader") - } - - for i := 0; i < 10; i++ { - buf := make([]byte, 10) - n, e := proxyReader.Read(buf) - if e != nil { - t.Errorf("Proxy reader return err: %v", e) - } - if n != len(buf) { - t.Errorf("Proxy reader return unexpected N: %d (wand %d)", n, len(buf)) - } - for _, b := range buf { - if b != 'f' { - t.Errorf("Unexpected read value: %v (want %v)", b, 'f') - } - } - if want := int64((i + 1) * len(buf)); bar.Current() != want { - t.Errorf("Unexpected bar current value: %d (want %d)", bar.Current(), want) - } - } - proxyReader.Close() - if !testReader.closed { - t.Errorf("Reader must be closed after call ProxyReader.Close") - } - proxyReader.Reader = nil - proxyReader.Close() -} - -type testReaderCloser struct { - closed bool -} - -func (tr *testReaderCloser) Read(p []byte) (n int, err error) { - for i := range p { - p[i] = 'f' - } - return len(p), nil -} - -func (tr *testReaderCloser) Close() (err error) { - tr.closed = true - return -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/speed.go b/vendor/gopkg.in/cheggaaa/pb.v2/speed.go deleted file mode 100644 index 4cf34b1d1..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/speed.go +++ /dev/null @@ -1,83 +0,0 @@ -package pb - -import ( - "fmt" - "math" - "time" - - "gopkg.in/VividCortex/ewma.v1" -) - -var speedAddLimit = time.Second / 2 - -type speed struct { - ewma ewma.MovingAverage - lastStateId uint64 - prevValue, startValue int64 - prevTime, startTime time.Time -} - -func (s *speed) value(state *State) float64 { - if s.ewma == nil { - s.ewma = ewma.NewMovingAverage() - } - if state.IsFirst() || state.Id() < s.lastStateId { - s.reset(state) - return 0 - } - if state.Id() == s.lastStateId { - return s.ewma.Value() - } - if state.IsFinished() { - return s.absValue(state) - } - dur := state.Time().Sub(s.prevTime) - if dur < speedAddLimit { - return s.ewma.Value() - } - diff := math.Abs(float64(state.Value() - s.prevValue)) - lastSpeed := diff / dur.Seconds() - s.prevTime = state.Time() - s.prevValue = state.Value() - s.lastStateId = state.Id() - s.ewma.Add(lastSpeed) - return s.ewma.Value() -} - -func (s *speed) reset(state *State) { - s.lastStateId = state.Id() - s.startTime = state.Time() - s.prevTime = state.Time() - s.startValue = state.Value() - s.prevValue = state.Value() - s.ewma = ewma.NewMovingAverage() -} - -func (s *speed) absValue(state *State) float64 { - if dur := state.Time().Sub(s.startTime); dur > 0 { - return float64(state.Value()) / dur.Seconds() - } - return 0 -} - -func getSpeedObj(state *State) (s *speed) { - if sObj, ok := state.Get(speedObj).(*speed); ok { - return sObj - } - s = new(speed) - state.Set(speedObj, s) - return -} - -// ElementSpeed calculates current speed by EWMA -// Optionally can take one or two string arguments. -// First string will be used as value for format speed, default is "%s p/s". -// Second string will be used when speed not available, default is "? p/s" -// In template use as follows: {{speed .}} or {{speed . "%s per second"}} or {{speed . "%s ps" "..."} -var ElementSpeed ElementFunc = func(state *State, args ...string) string { - sp := getSpeedObj(state).value(state) - if sp == 0 { - return argsHelper(args).getNotEmptyOr(1, "? p/s") - } - return fmt.Sprintf(argsHelper(args).getNotEmptyOr(0, "%s p/s"), state.Format(int64(round(sp)))) -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/template.go b/vendor/gopkg.in/cheggaaa/pb.v2/template.go deleted file mode 100644 index 98aeea44e..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/template.go +++ /dev/null @@ -1,87 +0,0 @@ -package pb - -import ( - "math/rand" - "sync" - "text/template" - - "gopkg.in/fatih/color.v1" -) - -// ProgressBarTemplate that template string -type ProgressBarTemplate string - -// New creates new bar from template -func (pbt ProgressBarTemplate) New(total int) *ProgressBar { - return New(total).SetTemplate(pbt) -} - -// Start64 create and start new bar with given int64 total value -func (pbt ProgressBarTemplate) Start64(total int64) *ProgressBar { - return New64(total).SetTemplate(pbt).Start() -} - -// Start create and start new bar with given int total value -func (pbt ProgressBarTemplate) Start(total int) *ProgressBar { - return pbt.Start64(int64(total)) -} - -var templateCacheMu sync.Mutex -var templateCache = make(map[string]*template.Template) - -var defaultTemplateFuncs = template.FuncMap{ - // colors - "black": color.New(color.FgBlack).SprintFunc(), - "red": color.New(color.FgRed).SprintFunc(), - "green": color.New(color.FgGreen).SprintFunc(), - "yellow": color.New(color.FgYellow).SprintFunc(), - "blue": color.New(color.FgBlue).SprintFunc(), - "magenta": color.New(color.FgMagenta).SprintFunc(), - "cyan": color.New(color.FgCyan).SprintFunc(), - "white": color.New(color.FgWhite).SprintFunc(), - "rndcolor": rndcolor, - "rnd": rnd, -} - -func getTemplate(tmpl string) (t *template.Template, err error) { - templateCacheMu.Lock() - defer templateCacheMu.Unlock() - t = templateCache[tmpl] - if t != nil { - // found in cache - return - } - t = template.New("") - fillTemplateFuncs(t) - _, err = t.Parse(tmpl) - if err != nil { - t = nil - return - } - templateCache[tmpl] = t - return -} - -func fillTemplateFuncs(t *template.Template) { - t.Funcs(defaultTemplateFuncs) - emf := make(template.FuncMap) - elementsM.Lock() - for k, v := range elements { - emf[k] = v - } - elementsM.Unlock() - t.Funcs(emf) - return -} - -func rndcolor(s string) string { - c := rand.Intn(int(color.FgWhite-color.FgBlack)) + int(color.FgBlack) - return color.New(color.Attribute(c)).Sprint(s) -} - -func rnd(args ...string) string { - if len(args) == 0 { - return "" - } - return args[rand.Intn(len(args))] -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/template_test.go b/vendor/gopkg.in/cheggaaa/pb.v2/template_test.go deleted file mode 100644 index 84022d347..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/template_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package pb - -import ( - "bytes" - "testing" -) - -func TestProgressBarTemplate(t *testing.T) { - // test New - bar := ProgressBarTemplate(`{{counters . }}`).New(0) - result := bar.String() - expected := "0" - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) - } - if bar.IsStarted() { - t.Error("Must be false") - } - - // test Start - bar = ProgressBarTemplate(`{{counters . }}`).Start(42).SetWriter(bytes.NewBuffer(nil)) - result = bar.String() - expected = "0 / 42" - if result != expected { - t.Errorf("Unexpected result: (actual/expected)\n%s\n%s", result, expected) - } - if !bar.IsStarted() { - t.Error("Must be true") - } -} - -func TestTemplateFuncs(t *testing.T) { - var results = make(map[string]int) - for i := 0; i < 100; i++ { - r := rndcolor("s") - results[r] = results[r] + 1 - } - if len(results) < 6 { - t.Errorf("Unexpected rndcolor results count: %v", len(results)) - } - - results = make(map[string]int) - for i := 0; i < 100; i++ { - r := rnd("1", "2", "3") - results[r] = results[r] + 1 - } - if len(results) != 3 { - t.Errorf("Unexpected rnd results count: %v", len(results)) - } - if r := rnd(); r != "" { - t.Errorf("Unexpected rnd result: '%v'", r) - } -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term.go deleted file mode 100644 index b53b4b24a..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term.go +++ /dev/null @@ -1,57 +0,0 @@ -package termutil - -import ( - "errors" - "os" - "os/signal" - "sync" - "syscall" -) - -var echoLocked bool -var echoLockMutex sync.Mutex -var errLocked = errors.New("terminal locked") - -// RawModeOn switches terminal to raw mode -func RawModeOn() (quit chan struct{}, err error) { - echoLockMutex.Lock() - defer echoLockMutex.Unlock() - if echoLocked { - err = errLocked - return - } - if err = lockEcho(); err != nil { - return - } - echoLocked = true - quit = make(chan struct{}, 1) - go catchTerminate(quit) - return -} - -// RawModeOff restore previous terminal state -func RawModeOff() (err error) { - echoLockMutex.Lock() - defer echoLockMutex.Unlock() - if !echoLocked { - return - } - if err = unlockEcho(); err != nil { - return - } - echoLocked = false - return -} - -// listen exit signals and restore terminal state -func catchTerminate(quit chan struct{}) { - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL) - defer signal.Stop(sig) - select { - case <-quit: - RawModeOff() - case <-sig: - RawModeOff() - } -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_appengine.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_appengine.go deleted file mode 100644 index 4b7b20e6b..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_appengine.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build appengine - -package termutil - -import "errors" - -// terminalWidth returns width of the terminal, which is not supported -// and should always failed on appengine classic which is a sandboxed PaaS. -func TerminalWidth() (int, error) { - return 0, errors.New("Not supported") -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_bsd.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_bsd.go deleted file mode 100644 index 272659a12..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_bsd.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build darwin freebsd netbsd openbsd dragonfly -// +build !appengine - -package termutil - -import "syscall" - -const ioctlReadTermios = syscall.TIOCGETA -const ioctlWriteTermios = syscall.TIOCSETA diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_linux.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_linux.go deleted file mode 100644 index 2f59e53e1..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_linux.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build linux -// +build !appengine - -package termutil - -const ioctlReadTermios = 0x5401 // syscall.TCGETS -const ioctlWriteTermios = 0x5402 // syscall.TCSETS diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_nix.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_nix.go deleted file mode 100644 index 14277e71f..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_nix.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build linux darwin freebsd netbsd openbsd dragonfly -// +build !appengine - -package termutil - -import "syscall" - -const sysIoctl = syscall.SYS_IOCTL diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_solaris.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_solaris.go deleted file mode 100644 index fc96c2b7f..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_solaris.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build solaris -// +build !appengine - -package termutil - -const ioctlReadTermios = 0x5401 // syscall.TCGETS -const ioctlWriteTermios = 0x5402 // syscall.TCSETS -const sysIoctl = 54 diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_win.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_win.go deleted file mode 100644 index 963158360..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_win.go +++ /dev/null @@ -1,149 +0,0 @@ -// +build windows - -package termutil - -import ( - "fmt" - "os" - "os/exec" - "strconv" - "syscall" - "unsafe" -) - -var tty = os.Stdin - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - - // GetConsoleScreenBufferInfo retrieves information about the - // specified console screen buffer. - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") - - // GetConsoleMode retrieves the current input mode of a console's - // input buffer or the current output mode of a console screen buffer. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx - getConsoleMode = kernel32.NewProc("GetConsoleMode") - - // SetConsoleMode sets the input mode of a console's input buffer - // or the output mode of a console screen buffer. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx - setConsoleMode = kernel32.NewProc("SetConsoleMode") - - // SetConsoleCursorPosition sets the cursor position in the - // specified console screen buffer. - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx - setConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") - - mingw = isMingw() -) - -type ( - // Defines the coordinates of the upper left and lower right corners - // of a rectangle. - // See - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311(v=vs.85).aspx - smallRect struct { - Left, Top, Right, Bottom int16 - } - - // Defines the coordinates of a character cell in a console screen - // buffer. The origin of the coordinate system (0,0) is at the top, left cell - // of the buffer. - // See - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119(v=vs.85).aspx - coordinates struct { - X, Y int16 - } - - word int16 - - // Contains information about a console screen buffer. - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx - consoleScreenBufferInfo struct { - dwSize coordinates - dwCursorPosition coordinates - wAttributes word - srWindow smallRect - dwMaximumWindowSize coordinates - } -) - -// TerminalWidth returns width of the terminal. -func TerminalWidth() (width int, err error) { - if mingw { - return termWidthTPut() - } - return termWidthCmd() -} - -func termWidthCmd() (width int, err error) { - var info consoleScreenBufferInfo - _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0) - if e != 0 { - return 0, error(e) - } - return int(info.dwSize.X) - 1, nil -} - -func isMingw() bool { - return os.Getenv("MINGW_PREFIX") != "" || os.Getenv("MSYSTEM") == "MINGW64" -} - -func termWidthTPut() (width int, err error) { - // TODO: maybe anybody knows a better way to get it on mintty... - var res []byte - cmd := exec.Command("tput", "cols") - cmd.Stdin = os.Stdin - if res, err = cmd.CombinedOutput(); err != nil { - return 0, fmt.Errorf("%s: %v", string(res), err) - } - if len(res) > 1 { - res = res[:len(res)-1] - } - return strconv.Atoi(string(res)) -} - -func getCursorPos() (pos coordinates, err error) { - var info consoleScreenBufferInfo - _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0) - if e != 0 { - return info.dwCursorPosition, error(e) - } - return info.dwCursorPosition, nil -} - -func setCursorPos(pos coordinates) error { - _, _, e := syscall.Syscall(setConsoleCursorPosition.Addr(), 2, uintptr(syscall.Stdout), uintptr(uint32(uint16(pos.Y))<<16|uint32(uint16(pos.X))), 0) - if e != 0 { - return error(e) - } - return nil -} - -var oldState word - -func lockEcho() (err error) { - if _, _, e := syscall.Syscall(getConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&oldState)), 0); e != 0 { - err = fmt.Errorf("Can't get terminal settings: %v", e) - return - } - - newState := oldState - const ENABLE_ECHO_INPUT = 0x0004 - const ENABLE_LINE_INPUT = 0x0002 - newState = newState & (^(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)) - if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(newState), 0); e != 0 { - err = fmt.Errorf("Can't set terminal settings: %v", e) - return - } - return -} - -func unlockEcho() (err error) { - if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(oldState), 0); e != 0 { - err = fmt.Errorf("Can't set terminal settings") - } - return -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_x.go b/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_x.go deleted file mode 100644 index e2f69b214..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/termutil/term_x.go +++ /dev/null @@ -1,70 +0,0 @@ -// +build linux darwin freebsd netbsd openbsd solaris dragonfly -// +build !appengine - -package termutil - -import ( - "fmt" - "os" - "syscall" - "unsafe" -) - -var tty *os.File - -type window struct { - Row uint16 - Col uint16 - Xpixel uint16 - Ypixel uint16 -} - -func init() { - var err error - tty, err = os.Open("/dev/tty") - if err != nil { - tty = os.Stdin - } -} - -// TerminalWidth returns width of the terminal. -func TerminalWidth() (int, error) { - w := new(window) - res, _, err := syscall.Syscall(sysIoctl, - tty.Fd(), - uintptr(syscall.TIOCGWINSZ), - uintptr(unsafe.Pointer(w)), - ) - if int(res) == -1 { - return 0, err - } - return int(w.Col), nil -} - -var oldState syscall.Termios - -func lockEcho() (err error) { - fd := tty.Fd() - if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { - err = fmt.Errorf("Can't get terminal settings: %v", e) - return - } - - newState := oldState - newState.Lflag &^= syscall.ECHO - newState.Lflag |= syscall.ICANON | syscall.ISIG - newState.Iflag |= syscall.ICRNL - if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); e != 0 { - err = fmt.Errorf("Can't set terminal settings: %v", e) - return - } - return -} - -func unlockEcho() (err error) { - fd := tty.Fd() - if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 { - err = fmt.Errorf("Can't set terminal settings") - } - return -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/util.go b/vendor/gopkg.in/cheggaaa/pb.v2/util.go deleted file mode 100644 index 44eedae56..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/util.go +++ /dev/null @@ -1,94 +0,0 @@ -package pb - -import ( - "bytes" - "fmt" - "gopkg.in/mattn/go-runewidth.v0" - "math" - "regexp" - //"unicode/utf8" -) - -const ( - _KiB = 1024 - _MiB = 1048576 - _GiB = 1073741824 - _TiB = 1099511627776 -) - -var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9]+\x6d") - -func CellCount(s string) int { - n := runewidth.StringWidth(s) - for _, sm := range ctrlFinder.FindAllString(s, -1) { - n -= runewidth.StringWidth(sm) - } - return n -} - -func StripString(s string, w int) string { - l := CellCount(s) - if l <= w { - return s - } - var buf = bytes.NewBuffer(make([]byte, 0, len(s))) - StripStringToBuffer(s, w, buf) - return buf.String() -} - -func StripStringToBuffer(s string, w int, buf *bytes.Buffer) { - var seqs = ctrlFinder.FindAllStringIndex(s, -1) -mainloop: - for i, r := range s { - for _, seq := range seqs { - if i >= seq[0] && i < seq[1] { - buf.WriteRune(r) - continue mainloop - } - } - if rw := CellCount(string(r)); rw <= w { - w -= rw - buf.WriteRune(r) - } else { - break - } - } - for w > 0 { - buf.WriteByte(' ') - w-- - } - return -} - -func round(val float64) (newVal float64) { - roundOn := 0.5 - places := 0 - var round float64 - pow := math.Pow(10, float64(places)) - digit := pow * val - _, div := math.Modf(digit) - if div >= roundOn { - round = math.Ceil(digit) - } else { - round = math.Floor(digit) - } - newVal = round / pow - return -} - -// Convert bytes to human readable string. Like a 2 MiB, 64.2 KiB, 52 B -func formatBytes(i int64) (result string) { - switch { - case i >= _TiB: - result = fmt.Sprintf("%.02f TiB", float64(i)/_TiB) - case i >= _GiB: - result = fmt.Sprintf("%.02f GiB", float64(i)/_GiB) - case i >= _MiB: - result = fmt.Sprintf("%.02f MiB", float64(i)/_MiB) - case i >= _KiB: - result = fmt.Sprintf("%.02f KiB", float64(i)/_KiB) - default: - result = fmt.Sprintf("%d B", i) - } - return -} diff --git a/vendor/gopkg.in/cheggaaa/pb.v2/util_test.go b/vendor/gopkg.in/cheggaaa/pb.v2/util_test.go deleted file mode 100644 index 1c7fe7850..000000000 --- a/vendor/gopkg.in/cheggaaa/pb.v2/util_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package pb - -import ( - "gopkg.in/fatih/color.v1" - "testing" -) - -var testColorString = color.RedString("red") + - color.GreenString("hello") + - "simple" + - color.WhiteString("進捗") - -func TestUtilCellCount(t *testing.T) { - if e, l := 18, CellCount(testColorString); l != e { - t.Errorf("Invalid length %d, expected %d", l, e) - } -} - -func TestUtilStripString(t *testing.T) { - if r, e := StripString("12345", 4), "1234"; r != e { - t.Errorf("Invalid result '%s', expected '%s'", r, e) - } - - if r, e := StripString("12345", 5), "12345"; r != e { - t.Errorf("Invalid result '%s', expected '%s'", r, e) - } - if r, e := StripString("12345", 10), "12345"; r != e { - t.Errorf("Invalid result '%s', expected '%s'", r, e) - } - - s := color.RedString("1") + "23" - e := color.RedString("1") + "2" - if r := StripString(s, 2); r != e { - t.Errorf("Invalid result '%s', expected '%s'", r, e) - } - return -} - -func TestUtilRound(t *testing.T) { - if v := round(4.4); v != 4 { - t.Errorf("Unexpected result: %v", v) - } - if v := round(4.501); v != 5 { - t.Errorf("Unexpected result: %v", v) - } -} - -func TestUtilFormatBytes(t *testing.T) { - inputs := []struct { - v int64 - e string - }{ - {v: 1000, e: "1000 B"}, - {v: 1024, e: "1.00 KiB"}, - {v: 3*_MiB + 140*_KiB, e: "3.14 MiB"}, - {v: 2 * _GiB, e: "2.00 GiB"}, - {v: 2048 * _GiB, e: "2.00 TiB"}, - } - - for _, input := range inputs { - actual := formatBytes(input.v) - if actual != input.e { - t.Errorf("Expected {%s} was {%s}", input.e, actual) - } - } -} - -func BenchmarkUtilsCellCount(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - CellCount(testColorString) - } -} diff --git a/vendor/gopkg.in/fatih/color.v1/.travis.yml b/vendor/gopkg.in/fatih/color.v1/.travis.yml deleted file mode 100644 index 57b4b57c8..000000000 --- a/vendor/gopkg.in/fatih/color.v1/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: go -go: - - 1.6 - - tip - diff --git a/vendor/gopkg.in/fatih/color.v1/LICENSE.md b/vendor/gopkg.in/fatih/color.v1/LICENSE.md deleted file mode 100644 index 25fdaf639..000000000 --- a/vendor/gopkg.in/fatih/color.v1/LICENSE.md +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 Fatih Arslan - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/gopkg.in/fatih/color.v1/README.md b/vendor/gopkg.in/fatih/color.v1/README.md deleted file mode 100644 index 623baf3c3..000000000 --- a/vendor/gopkg.in/fatih/color.v1/README.md +++ /dev/null @@ -1,177 +0,0 @@ -# Color [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/fatih/color) [![Build Status](http://img.shields.io/travis/fatih/color.svg?style=flat-square)](https://travis-ci.org/fatih/color) - - - -Color lets you use colorized outputs in terms of [ANSI Escape -Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It -has support for Windows too! The API can be used in several ways, pick one that -suits you. - - -![Color](http://i.imgur.com/c1JI0lA.png) - - -## Install - -```bash -go get github.com/fatih/color -``` - -Note that the `vendor` folder is here for stability. Remove the folder if you -already have the dependencies in your GOPATH. - -## Examples - -### Standard colors - -```go -// Print with default helper functions -color.Cyan("Prints text in cyan.") - -// A newline will be appended automatically -color.Blue("Prints %s in blue.", "text") - -// These are using the default foreground colors -color.Red("We have red") -color.Magenta("And many others ..") - -``` - -### Mix and reuse colors - -```go -// Create a new color object -c := color.New(color.FgCyan).Add(color.Underline) -c.Println("Prints cyan text with an underline.") - -// Or just add them to New() -d := color.New(color.FgCyan, color.Bold) -d.Printf("This prints bold cyan %s\n", "too!.") - -// Mix up foreground and background colors, create new mixes! -red := color.New(color.FgRed) - -boldRed := red.Add(color.Bold) -boldRed.Println("This will print text in bold red.") - -whiteBackground := red.Add(color.BgWhite) -whiteBackground.Println("Red text with white background.") -``` - -### Use your own output (io.Writer) - -```go -// Use your own io.Writer output -color.New(color.FgBlue).Fprintln(myWriter, "blue color!") - -blue := color.New(color.FgBlue) -blue.Fprint(writer, "This will print text in blue.") -``` - -### Custom print functions (PrintFunc) - -```go -// Create a custom print function for convenience -red := color.New(color.FgRed).PrintfFunc() -red("Warning") -red("Error: %s", err) - -// Mix up multiple attributes -notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() -notice("Don't forget this...") -``` - -### Custom fprint functions (FprintFunc) - -```go -blue := color.New(FgBlue).FprintfFunc() -blue(myWriter, "important notice: %s", stars) - -// Mix up with multiple attributes -success := color.New(color.Bold, color.FgGreen).FprintlnFunc() -success(myWriter, "Don't forget this...") -``` - -### Insert into noncolor strings (SprintFunc) - -```go -// Create SprintXxx functions to mix strings with other non-colorized strings: -yellow := color.New(color.FgYellow).SprintFunc() -red := color.New(color.FgRed).SprintFunc() -fmt.Printf("This is a %s and this is %s.\n", yellow("warning"), red("error")) - -info := color.New(color.FgWhite, color.BgGreen).SprintFunc() -fmt.Printf("This %s rocks!\n", info("package")) - -// Use helper functions -fmt.Println("This", color.RedString("warning"), "should be not neglected.") -fmt.Printf("%v %v\n", color.GreenString("Info:"), "an important message.") - -// Windows supported too! Just don't forget to change the output to color.Output -fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) -``` - -### Plug into existing code - -```go -// Use handy standard colors -color.Set(color.FgYellow) - -fmt.Println("Existing text will now be in yellow") -fmt.Printf("This one %s\n", "too") - -color.Unset() // Don't forget to unset - -// You can mix up parameters -color.Set(color.FgMagenta, color.Bold) -defer color.Unset() // Use it in your function - -fmt.Println("All text will now be bold magenta.") -``` - -### Disable color - -There might be a case where you want to disable color output (for example to -pipe the standard output of your app to somewhere else). `Color` has support to -disable colors both globally and for single color definition. For example -suppose you have a CLI app and a `--no-color` bool flag. You can easily disable -the color output with: - -```go - -var flagNoColor = flag.Bool("no-color", false, "Disable color output") - -if *flagNoColor { - color.NoColor = true // disables colorized output -} -``` - -It also has support for single color definitions (local). You can -disable/enable color output on the fly: - -```go -c := color.New(color.FgCyan) -c.Println("Prints cyan text") - -c.DisableColor() -c.Println("This is printed without any color") - -c.EnableColor() -c.Println("This prints again cyan...") -``` - -## Todo - -* Save/Return previous values -* Evaluate fmt.Formatter interface - - -## Credits - - * [Fatih Arslan](https://github.com/fatih) - * Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable) - -## License - -The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details - diff --git a/vendor/gopkg.in/fatih/color.v1/color.go b/vendor/gopkg.in/fatih/color.v1/color.go deleted file mode 100644 index 7b5f3146d..000000000 --- a/vendor/gopkg.in/fatih/color.v1/color.go +++ /dev/null @@ -1,600 +0,0 @@ -package color - -import ( - "fmt" - "io" - "os" - "strconv" - "strings" - "sync" - - "github.com/mattn/go-colorable" - "github.com/mattn/go-isatty" -) - -var ( - // NoColor defines if the output is colorized or not. It's dynamically set to - // false or true based on the stdout's file descriptor referring to a terminal - // or not. This is a global option and affects all colors. For more control - // over each color block use the methods DisableColor() individually. - NoColor = os.Getenv("TERM") == "dumb" || - (!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd())) - - // Output defines the standard output of the print functions. By default - // os.Stdout is used. - Output = colorable.NewColorableStdout() - - // colorsCache is used to reduce the count of created Color objects and - // allows to reuse already created objects with required Attribute. - colorsCache = make(map[Attribute]*Color) - colorsCacheMu sync.Mutex // protects colorsCache -) - -// Color defines a custom color object which is defined by SGR parameters. -type Color struct { - params []Attribute - noColor *bool -} - -// Attribute defines a single SGR Code -type Attribute int - -const escape = "\x1b" - -// Base attributes -const ( - Reset Attribute = iota - Bold - Faint - Italic - Underline - BlinkSlow - BlinkRapid - ReverseVideo - Concealed - CrossedOut -) - -// Foreground text colors -const ( - FgBlack Attribute = iota + 30 - FgRed - FgGreen - FgYellow - FgBlue - FgMagenta - FgCyan - FgWhite -) - -// Foreground Hi-Intensity text colors -const ( - FgHiBlack Attribute = iota + 90 - FgHiRed - FgHiGreen - FgHiYellow - FgHiBlue - FgHiMagenta - FgHiCyan - FgHiWhite -) - -// Background text colors -const ( - BgBlack Attribute = iota + 40 - BgRed - BgGreen - BgYellow - BgBlue - BgMagenta - BgCyan - BgWhite -) - -// Background Hi-Intensity text colors -const ( - BgHiBlack Attribute = iota + 100 - BgHiRed - BgHiGreen - BgHiYellow - BgHiBlue - BgHiMagenta - BgHiCyan - BgHiWhite -) - -// New returns a newly created color object. -func New(value ...Attribute) *Color { - c := &Color{params: make([]Attribute, 0)} - c.Add(value...) - return c -} - -// Set sets the given parameters immediately. It will change the color of -// output with the given SGR parameters until color.Unset() is called. -func Set(p ...Attribute) *Color { - c := New(p...) - c.Set() - return c -} - -// Unset resets all escape attributes and clears the output. Usually should -// be called after Set(). -func Unset() { - if NoColor { - return - } - - fmt.Fprintf(Output, "%s[%dm", escape, Reset) -} - -// Set sets the SGR sequence. -func (c *Color) Set() *Color { - if c.isNoColorSet() { - return c - } - - fmt.Fprintf(Output, c.format()) - return c -} - -func (c *Color) unset() { - if c.isNoColorSet() { - return - } - - Unset() -} - -func (c *Color) setWriter(w io.Writer) *Color { - if c.isNoColorSet() { - return c - } - - fmt.Fprintf(w, c.format()) - return c -} - -func (c *Color) unsetWriter(w io.Writer) { - if c.isNoColorSet() { - return - } - - if NoColor { - return - } - - fmt.Fprintf(w, "%s[%dm", escape, Reset) -} - -// Add is used to chain SGR parameters. Use as many as parameters to combine -// and create custom color objects. Example: Add(color.FgRed, color.Underline). -func (c *Color) Add(value ...Attribute) *Color { - c.params = append(c.params, value...) - return c -} - -func (c *Color) prepend(value Attribute) { - c.params = append(c.params, 0) - copy(c.params[1:], c.params[0:]) - c.params[0] = value -} - -// Fprint formats using the default formats for its operands and writes to w. -// Spaces are added between operands when neither is a string. -// It returns the number of bytes written and any write error encountered. -// On Windows, users should wrap w with colorable.NewColorable() if w is of -// type *os.File. -func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) { - c.setWriter(w) - defer c.unsetWriter(w) - - return fmt.Fprint(w, a...) -} - -// Print formats using the default formats for its operands and writes to -// standard output. Spaces are added between operands when neither is a -// string. It returns the number of bytes written and any write error -// encountered. This is the standard fmt.Print() method wrapped with the given -// color. -func (c *Color) Print(a ...interface{}) (n int, err error) { - c.Set() - defer c.unset() - - return fmt.Fprint(Output, a...) -} - -// Fprintf formats according to a format specifier and writes to w. -// It returns the number of bytes written and any write error encountered. -// On Windows, users should wrap w with colorable.NewColorable() if w is of -// type *os.File. -func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - c.setWriter(w) - defer c.unsetWriter(w) - - return fmt.Fprintf(w, format, a...) -} - -// Printf formats according to a format specifier and writes to standard output. -// It returns the number of bytes written and any write error encountered. -// This is the standard fmt.Printf() method wrapped with the given color. -func (c *Color) Printf(format string, a ...interface{}) (n int, err error) { - c.Set() - defer c.unset() - - return fmt.Fprintf(Output, format, a...) -} - -// Fprintln formats using the default formats for its operands and writes to w. -// Spaces are always added between operands and a newline is appended. -// On Windows, users should wrap w with colorable.NewColorable() if w is of -// type *os.File. -func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - c.setWriter(w) - defer c.unsetWriter(w) - - return fmt.Fprintln(w, a...) -} - -// Println formats using the default formats for its operands and writes to -// standard output. Spaces are always added between operands and a newline is -// appended. It returns the number of bytes written and any write error -// encountered. This is the standard fmt.Print() method wrapped with the given -// color. -func (c *Color) Println(a ...interface{}) (n int, err error) { - c.Set() - defer c.unset() - - return fmt.Fprintln(Output, a...) -} - -// Sprint is just like Print, but returns a string instead of printing it. -func (c *Color) Sprint(a ...interface{}) string { - return c.wrap(fmt.Sprint(a...)) -} - -// Sprintln is just like Println, but returns a string instead of printing it. -func (c *Color) Sprintln(a ...interface{}) string { - return c.wrap(fmt.Sprintln(a...)) -} - -// Sprintf is just like Printf, but returns a string instead of printing it. -func (c *Color) Sprintf(format string, a ...interface{}) string { - return c.wrap(fmt.Sprintf(format, a...)) -} - -// FprintFunc returns a new function that prints the passed arguments as -// colorized with color.Fprint(). -func (c *Color) FprintFunc() func(w io.Writer, a ...interface{}) { - return func(w io.Writer, a ...interface{}) { - c.Fprint(w, a...) - } -} - -// PrintFunc returns a new function that prints the passed arguments as -// colorized with color.Print(). -func (c *Color) PrintFunc() func(a ...interface{}) { - return func(a ...interface{}) { - c.Print(a...) - } -} - -// FprintfFunc returns a new function that prints the passed arguments as -// colorized with color.Fprintf(). -func (c *Color) FprintfFunc() func(w io.Writer, format string, a ...interface{}) { - return func(w io.Writer, format string, a ...interface{}) { - c.Fprintf(w, format, a...) - } -} - -// PrintfFunc returns a new function that prints the passed arguments as -// colorized with color.Printf(). -func (c *Color) PrintfFunc() func(format string, a ...interface{}) { - return func(format string, a ...interface{}) { - c.Printf(format, a...) - } -} - -// FprintlnFunc returns a new function that prints the passed arguments as -// colorized with color.Fprintln(). -func (c *Color) FprintlnFunc() func(w io.Writer, a ...interface{}) { - return func(w io.Writer, a ...interface{}) { - c.Fprintln(w, a...) - } -} - -// PrintlnFunc returns a new function that prints the passed arguments as -// colorized with color.Println(). -func (c *Color) PrintlnFunc() func(a ...interface{}) { - return func(a ...interface{}) { - c.Println(a...) - } -} - -// SprintFunc returns a new function that returns colorized strings for the -// given arguments with fmt.Sprint(). Useful to put into or mix into other -// string. Windows users should use this in conjunction with color.Output, example: -// -// put := New(FgYellow).SprintFunc() -// fmt.Fprintf(color.Output, "This is a %s", put("warning")) -func (c *Color) SprintFunc() func(a ...interface{}) string { - return func(a ...interface{}) string { - return c.wrap(fmt.Sprint(a...)) - } -} - -// SprintfFunc returns a new function that returns colorized strings for the -// given arguments with fmt.Sprintf(). Useful to put into or mix into other -// string. Windows users should use this in conjunction with color.Output. -func (c *Color) SprintfFunc() func(format string, a ...interface{}) string { - return func(format string, a ...interface{}) string { - return c.wrap(fmt.Sprintf(format, a...)) - } -} - -// SprintlnFunc returns a new function that returns colorized strings for the -// given arguments with fmt.Sprintln(). Useful to put into or mix into other -// string. Windows users should use this in conjunction with color.Output. -func (c *Color) SprintlnFunc() func(a ...interface{}) string { - return func(a ...interface{}) string { - return c.wrap(fmt.Sprintln(a...)) - } -} - -// sequence returns a formated SGR sequence to be plugged into a "\x1b[...m" -// an example output might be: "1;36" -> bold cyan -func (c *Color) sequence() string { - format := make([]string, len(c.params)) - for i, v := range c.params { - format[i] = strconv.Itoa(int(v)) - } - - return strings.Join(format, ";") -} - -// wrap wraps the s string with the colors attributes. The string is ready to -// be printed. -func (c *Color) wrap(s string) string { - if c.isNoColorSet() { - return s - } - - return c.format() + s + c.unformat() -} - -func (c *Color) format() string { - return fmt.Sprintf("%s[%sm", escape, c.sequence()) -} - -func (c *Color) unformat() string { - return fmt.Sprintf("%s[%dm", escape, Reset) -} - -// DisableColor disables the color output. Useful to not change any existing -// code and still being able to output. Can be used for flags like -// "--no-color". To enable back use EnableColor() method. -func (c *Color) DisableColor() { - c.noColor = boolPtr(true) -} - -// EnableColor enables the color output. Use it in conjunction with -// DisableColor(). Otherwise this method has no side effects. -func (c *Color) EnableColor() { - c.noColor = boolPtr(false) -} - -func (c *Color) isNoColorSet() bool { - // check first if we have user setted action - if c.noColor != nil { - return *c.noColor - } - - // if not return the global option, which is disabled by default - return NoColor -} - -// Equals returns a boolean value indicating whether two colors are equal. -func (c *Color) Equals(c2 *Color) bool { - if len(c.params) != len(c2.params) { - return false - } - - for _, attr := range c.params { - if !c2.attrExists(attr) { - return false - } - } - - return true -} - -func (c *Color) attrExists(a Attribute) bool { - for _, attr := range c.params { - if attr == a { - return true - } - } - - return false -} - -func boolPtr(v bool) *bool { - return &v -} - -func getCachedColor(p Attribute) *Color { - colorsCacheMu.Lock() - defer colorsCacheMu.Unlock() - - c, ok := colorsCache[p] - if !ok { - c = New(p) - colorsCache[p] = c - } - - return c -} - -func colorPrint(format string, p Attribute, a ...interface{}) { - c := getCachedColor(p) - - if !strings.HasSuffix(format, "\n") { - format += "\n" - } - - if len(a) == 0 { - c.Print(format) - } else { - c.Printf(format, a...) - } -} - -func colorString(format string, p Attribute, a ...interface{}) string { - c := getCachedColor(p) - - if len(a) == 0 { - return c.SprintFunc()(format) - } - - return c.SprintfFunc()(format, a...) -} - -// Black is a convenient helper function to print with black foreground. A -// newline is appended to format by default. -func Black(format string, a ...interface{}) { colorPrint(format, FgBlack, a...) } - -// Red is a convenient helper function to print with red foreground. A -// newline is appended to format by default. -func Red(format string, a ...interface{}) { colorPrint(format, FgRed, a...) } - -// Green is a convenient helper function to print with green foreground. A -// newline is appended to format by default. -func Green(format string, a ...interface{}) { colorPrint(format, FgGreen, a...) } - -// Yellow is a convenient helper function to print with yellow foreground. -// A newline is appended to format by default. -func Yellow(format string, a ...interface{}) { colorPrint(format, FgYellow, a...) } - -// Blue is a convenient helper function to print with blue foreground. A -// newline is appended to format by default. -func Blue(format string, a ...interface{}) { colorPrint(format, FgBlue, a...) } - -// Magenta is a convenient helper function to print with magenta foreground. -// A newline is appended to format by default. -func Magenta(format string, a ...interface{}) { colorPrint(format, FgMagenta, a...) } - -// Cyan is a convenient helper function to print with cyan foreground. A -// newline is appended to format by default. -func Cyan(format string, a ...interface{}) { colorPrint(format, FgCyan, a...) } - -// White is a convenient helper function to print with white foreground. A -// newline is appended to format by default. -func White(format string, a ...interface{}) { colorPrint(format, FgWhite, a...) } - -// BlackString is a convenient helper function to return a string with black -// foreground. -func BlackString(format string, a ...interface{}) string { return colorString(format, FgBlack, a...) } - -// RedString is a convenient helper function to return a string with red -// foreground. -func RedString(format string, a ...interface{}) string { return colorString(format, FgRed, a...) } - -// GreenString is a convenient helper function to return a string with green -// foreground. -func GreenString(format string, a ...interface{}) string { return colorString(format, FgGreen, a...) } - -// YellowString is a convenient helper function to return a string with yellow -// foreground. -func YellowString(format string, a ...interface{}) string { return colorString(format, FgYellow, a...) } - -// BlueString is a convenient helper function to return a string with blue -// foreground. -func BlueString(format string, a ...interface{}) string { return colorString(format, FgBlue, a...) } - -// MagentaString is a convenient helper function to return a string with magenta -// foreground. -func MagentaString(format string, a ...interface{}) string { - return colorString(format, FgMagenta, a...) -} - -// CyanString is a convenient helper function to return a string with cyan -// foreground. -func CyanString(format string, a ...interface{}) string { return colorString(format, FgCyan, a...) } - -// WhiteString is a convenient helper function to return a string with white -// foreground. -func WhiteString(format string, a ...interface{}) string { return colorString(format, FgWhite, a...) } - -// HiBlack is a convenient helper function to print with hi-intensity black foreground. A -// newline is appended to format by default. -func HiBlack(format string, a ...interface{}) { colorPrint(format, FgHiBlack, a...) } - -// HiRed is a convenient helper function to print with hi-intensity red foreground. A -// newline is appended to format by default. -func HiRed(format string, a ...interface{}) { colorPrint(format, FgHiRed, a...) } - -// HiGreen is a convenient helper function to print with hi-intensity green foreground. A -// newline is appended to format by default. -func HiGreen(format string, a ...interface{}) { colorPrint(format, FgHiGreen, a...) } - -// HiYellow is a convenient helper function to print with hi-intensity yellow foreground. -// A newline is appended to format by default. -func HiYellow(format string, a ...interface{}) { colorPrint(format, FgHiYellow, a...) } - -// HiBlue is a convenient helper function to print with hi-intensity blue foreground. A -// newline is appended to format by default. -func HiBlue(format string, a ...interface{}) { colorPrint(format, FgHiBlue, a...) } - -// HiMagenta is a convenient helper function to print with hi-intensity magenta foreground. -// A newline is appended to format by default. -func HiMagenta(format string, a ...interface{}) { colorPrint(format, FgHiMagenta, a...) } - -// HiCyan is a convenient helper function to print with hi-intensity cyan foreground. A -// newline is appended to format by default. -func HiCyan(format string, a ...interface{}) { colorPrint(format, FgHiCyan, a...) } - -// HiWhite is a convenient helper function to print with hi-intensity white foreground. A -// newline is appended to format by default. -func HiWhite(format string, a ...interface{}) { colorPrint(format, FgHiWhite, a...) } - -// HiBlackString is a convenient helper function to return a string with hi-intensity black -// foreground. -func HiBlackString(format string, a ...interface{}) string { - return colorString(format, FgHiBlack, a...) -} - -// HiRedString is a convenient helper function to return a string with hi-intensity red -// foreground. -func HiRedString(format string, a ...interface{}) string { return colorString(format, FgHiRed, a...) } - -// HiGreenString is a convenient helper function to return a string with hi-intensity green -// foreground. -func HiGreenString(format string, a ...interface{}) string { - return colorString(format, FgHiGreen, a...) -} - -// HiYellowString is a convenient helper function to return a string with hi-intensity yellow -// foreground. -func HiYellowString(format string, a ...interface{}) string { - return colorString(format, FgHiYellow, a...) -} - -// HiBlueString is a convenient helper function to return a string with hi-intensity blue -// foreground. -func HiBlueString(format string, a ...interface{}) string { return colorString(format, FgHiBlue, a...) } - -// HiMagentaString is a convenient helper function to return a string with hi-intensity magenta -// foreground. -func HiMagentaString(format string, a ...interface{}) string { - return colorString(format, FgHiMagenta, a...) -} - -// HiCyanString is a convenient helper function to return a string with hi-intensity cyan -// foreground. -func HiCyanString(format string, a ...interface{}) string { return colorString(format, FgHiCyan, a...) } - -// HiWhiteString is a convenient helper function to return a string with hi-intensity white -// foreground. -func HiWhiteString(format string, a ...interface{}) string { - return colorString(format, FgHiWhite, a...) -} diff --git a/vendor/gopkg.in/fatih/color.v1/color_test.go b/vendor/gopkg.in/fatih/color.v1/color_test.go deleted file mode 100644 index a8ed14fba..000000000 --- a/vendor/gopkg.in/fatih/color.v1/color_test.go +++ /dev/null @@ -1,342 +0,0 @@ -package color - -import ( - "bytes" - "fmt" - "os" - "testing" - - "github.com/mattn/go-colorable" -) - -// Testing colors is kinda different. First we test for given colors and their -// escaped formatted results. Next we create some visual tests to be tested. -// Each visual test includes the color name to be compared. -func TestColor(t *testing.T) { - rb := new(bytes.Buffer) - Output = rb - - NoColor = false - - testColors := []struct { - text string - code Attribute - }{ - {text: "black", code: FgBlack}, - {text: "red", code: FgRed}, - {text: "green", code: FgGreen}, - {text: "yellow", code: FgYellow}, - {text: "blue", code: FgBlue}, - {text: "magent", code: FgMagenta}, - {text: "cyan", code: FgCyan}, - {text: "white", code: FgWhite}, - {text: "hblack", code: FgHiBlack}, - {text: "hred", code: FgHiRed}, - {text: "hgreen", code: FgHiGreen}, - {text: "hyellow", code: FgHiYellow}, - {text: "hblue", code: FgHiBlue}, - {text: "hmagent", code: FgHiMagenta}, - {text: "hcyan", code: FgHiCyan}, - {text: "hwhite", code: FgHiWhite}, - } - - for _, c := range testColors { - New(c.code).Print(c.text) - - line, _ := rb.ReadString('\n') - scannedLine := fmt.Sprintf("%q", line) - colored := fmt.Sprintf("\x1b[%dm%s\x1b[0m", c.code, c.text) - escapedForm := fmt.Sprintf("%q", colored) - - fmt.Printf("%s\t: %s\n", c.text, line) - - if scannedLine != escapedForm { - t.Errorf("Expecting %s, got '%s'\n", escapedForm, scannedLine) - } - } - - for _, c := range testColors { - line := New(c.code).Sprintf("%s", c.text) - scannedLine := fmt.Sprintf("%q", line) - colored := fmt.Sprintf("\x1b[%dm%s\x1b[0m", c.code, c.text) - escapedForm := fmt.Sprintf("%q", colored) - - fmt.Printf("%s\t: %s\n", c.text, line) - - if scannedLine != escapedForm { - t.Errorf("Expecting %s, got '%s'\n", escapedForm, scannedLine) - } - } -} - -func TestColorEquals(t *testing.T) { - fgblack1 := New(FgBlack) - fgblack2 := New(FgBlack) - bgblack := New(BgBlack) - fgbgblack := New(FgBlack, BgBlack) - fgblackbgred := New(FgBlack, BgRed) - fgred := New(FgRed) - bgred := New(BgRed) - - if !fgblack1.Equals(fgblack2) { - t.Error("Two black colors are not equal") - } - - if fgblack1.Equals(bgblack) { - t.Error("Fg and bg black colors are equal") - } - - if fgblack1.Equals(fgbgblack) { - t.Error("Fg black equals fg/bg black color") - } - - if fgblack1.Equals(fgred) { - t.Error("Fg black equals Fg red") - } - - if fgblack1.Equals(bgred) { - t.Error("Fg black equals Bg red") - } - - if fgblack1.Equals(fgblackbgred) { - t.Error("Fg black equals fg black bg red") - } -} - -func TestNoColor(t *testing.T) { - rb := new(bytes.Buffer) - Output = rb - - testColors := []struct { - text string - code Attribute - }{ - {text: "black", code: FgBlack}, - {text: "red", code: FgRed}, - {text: "green", code: FgGreen}, - {text: "yellow", code: FgYellow}, - {text: "blue", code: FgBlue}, - {text: "magent", code: FgMagenta}, - {text: "cyan", code: FgCyan}, - {text: "white", code: FgWhite}, - {text: "hblack", code: FgHiBlack}, - {text: "hred", code: FgHiRed}, - {text: "hgreen", code: FgHiGreen}, - {text: "hyellow", code: FgHiYellow}, - {text: "hblue", code: FgHiBlue}, - {text: "hmagent", code: FgHiMagenta}, - {text: "hcyan", code: FgHiCyan}, - {text: "hwhite", code: FgHiWhite}, - } - - for _, c := range testColors { - p := New(c.code) - p.DisableColor() - p.Print(c.text) - - line, _ := rb.ReadString('\n') - if line != c.text { - t.Errorf("Expecting %s, got '%s'\n", c.text, line) - } - } - - // global check - NoColor = true - defer func() { - NoColor = false - }() - for _, c := range testColors { - p := New(c.code) - p.Print(c.text) - - line, _ := rb.ReadString('\n') - if line != c.text { - t.Errorf("Expecting %s, got '%s'\n", c.text, line) - } - } - -} - -func TestColorVisual(t *testing.T) { - // First Visual Test - Output = colorable.NewColorableStdout() - - New(FgRed).Printf("red\t") - New(BgRed).Print(" ") - New(FgRed, Bold).Println(" red") - - New(FgGreen).Printf("green\t") - New(BgGreen).Print(" ") - New(FgGreen, Bold).Println(" green") - - New(FgYellow).Printf("yellow\t") - New(BgYellow).Print(" ") - New(FgYellow, Bold).Println(" yellow") - - New(FgBlue).Printf("blue\t") - New(BgBlue).Print(" ") - New(FgBlue, Bold).Println(" blue") - - New(FgMagenta).Printf("magenta\t") - New(BgMagenta).Print(" ") - New(FgMagenta, Bold).Println(" magenta") - - New(FgCyan).Printf("cyan\t") - New(BgCyan).Print(" ") - New(FgCyan, Bold).Println(" cyan") - - New(FgWhite).Printf("white\t") - New(BgWhite).Print(" ") - New(FgWhite, Bold).Println(" white") - fmt.Println("") - - // Second Visual test - Black("black") - Red("red") - Green("green") - Yellow("yellow") - Blue("blue") - Magenta("magenta") - Cyan("cyan") - White("white") - HiBlack("hblack") - HiRed("hred") - HiGreen("hgreen") - HiYellow("hyellow") - HiBlue("hblue") - HiMagenta("hmagenta") - HiCyan("hcyan") - HiWhite("hwhite") - - // Third visual test - fmt.Println() - Set(FgBlue) - fmt.Println("is this blue?") - Unset() - - Set(FgMagenta) - fmt.Println("and this magenta?") - Unset() - - // Fourth Visual test - fmt.Println() - blue := New(FgBlue).PrintlnFunc() - blue("blue text with custom print func") - - red := New(FgRed).PrintfFunc() - red("red text with a printf func: %d\n", 123) - - put := New(FgYellow).SprintFunc() - warn := New(FgRed).SprintFunc() - - fmt.Fprintf(Output, "this is a %s and this is %s.\n", put("warning"), warn("error")) - - info := New(FgWhite, BgGreen).SprintFunc() - fmt.Fprintf(Output, "this %s rocks!\n", info("package")) - - notice := New(FgBlue).FprintFunc() - notice(os.Stderr, "just a blue notice to stderr") - - // Fifth Visual Test - fmt.Println() - - fmt.Fprintln(Output, BlackString("black")) - fmt.Fprintln(Output, RedString("red")) - fmt.Fprintln(Output, GreenString("green")) - fmt.Fprintln(Output, YellowString("yellow")) - fmt.Fprintln(Output, BlueString("blue")) - fmt.Fprintln(Output, MagentaString("magenta")) - fmt.Fprintln(Output, CyanString("cyan")) - fmt.Fprintln(Output, WhiteString("white")) - fmt.Fprintln(Output, HiBlackString("hblack")) - fmt.Fprintln(Output, HiRedString("hred")) - fmt.Fprintln(Output, HiGreenString("hgreen")) - fmt.Fprintln(Output, HiYellowString("hyellow")) - fmt.Fprintln(Output, HiBlueString("hblue")) - fmt.Fprintln(Output, HiMagentaString("hmagenta")) - fmt.Fprintln(Output, HiCyanString("hcyan")) - fmt.Fprintln(Output, HiWhiteString("hwhite")) -} - -func TestNoFormat(t *testing.T) { - fmt.Printf("%s %%s = ", BlackString("Black")) - Black("%s") - - fmt.Printf("%s %%s = ", RedString("Red")) - Red("%s") - - fmt.Printf("%s %%s = ", GreenString("Green")) - Green("%s") - - fmt.Printf("%s %%s = ", YellowString("Yellow")) - Yellow("%s") - - fmt.Printf("%s %%s = ", BlueString("Blue")) - Blue("%s") - - fmt.Printf("%s %%s = ", MagentaString("Magenta")) - Magenta("%s") - - fmt.Printf("%s %%s = ", CyanString("Cyan")) - Cyan("%s") - - fmt.Printf("%s %%s = ", WhiteString("White")) - White("%s") - - fmt.Printf("%s %%s = ", HiBlackString("HiBlack")) - HiBlack("%s") - - fmt.Printf("%s %%s = ", HiRedString("HiRed")) - HiRed("%s") - - fmt.Printf("%s %%s = ", HiGreenString("HiGreen")) - HiGreen("%s") - - fmt.Printf("%s %%s = ", HiYellowString("HiYellow")) - HiYellow("%s") - - fmt.Printf("%s %%s = ", HiBlueString("HiBlue")) - HiBlue("%s") - - fmt.Printf("%s %%s = ", HiMagentaString("HiMagenta")) - HiMagenta("%s") - - fmt.Printf("%s %%s = ", HiCyanString("HiCyan")) - HiCyan("%s") - - fmt.Printf("%s %%s = ", HiWhiteString("HiWhite")) - HiWhite("%s") -} - -func TestNoFormatString(t *testing.T) { - tests := []struct { - f func(string, ...interface{}) string - format string - args []interface{} - want string - }{ - {BlackString, "%s", nil, "\x1b[30m%s\x1b[0m"}, - {RedString, "%s", nil, "\x1b[31m%s\x1b[0m"}, - {GreenString, "%s", nil, "\x1b[32m%s\x1b[0m"}, - {YellowString, "%s", nil, "\x1b[33m%s\x1b[0m"}, - {BlueString, "%s", nil, "\x1b[34m%s\x1b[0m"}, - {MagentaString, "%s", nil, "\x1b[35m%s\x1b[0m"}, - {CyanString, "%s", nil, "\x1b[36m%s\x1b[0m"}, - {WhiteString, "%s", nil, "\x1b[37m%s\x1b[0m"}, - {HiBlackString, "%s", nil, "\x1b[90m%s\x1b[0m"}, - {HiRedString, "%s", nil, "\x1b[91m%s\x1b[0m"}, - {HiGreenString, "%s", nil, "\x1b[92m%s\x1b[0m"}, - {HiYellowString, "%s", nil, "\x1b[93m%s\x1b[0m"}, - {HiBlueString, "%s", nil, "\x1b[94m%s\x1b[0m"}, - {HiMagentaString, "%s", nil, "\x1b[95m%s\x1b[0m"}, - {HiCyanString, "%s", nil, "\x1b[96m%s\x1b[0m"}, - {HiWhiteString, "%s", nil, "\x1b[97m%s\x1b[0m"}, - } - - for i, test := range tests { - s := fmt.Sprintf("%s", test.f(test.format, test.args...)) - if s != test.want { - t.Errorf("[%d] want: %q, got: %q", i, test.want, s) - } - } -} diff --git a/vendor/gopkg.in/fatih/color.v1/doc.go b/vendor/gopkg.in/fatih/color.v1/doc.go deleted file mode 100644 index cf1e96500..000000000 --- a/vendor/gopkg.in/fatih/color.v1/doc.go +++ /dev/null @@ -1,133 +0,0 @@ -/* -Package color is an ANSI color package to output colorized or SGR defined -output to the standard output. The API can be used in several way, pick one -that suits you. - -Use simple and default helper functions with predefined foreground colors: - - color.Cyan("Prints text in cyan.") - - // a newline will be appended automatically - color.Blue("Prints %s in blue.", "text") - - // More default foreground colors.. - color.Red("We have red") - color.Yellow("Yellow color too!") - color.Magenta("And many others ..") - - // Hi-intensity colors - color.HiGreen("Bright green color.") - color.HiBlack("Bright black means gray..") - color.HiWhite("Shiny white color!") - -However there are times where custom color mixes are required. Below are some -examples to create custom color objects and use the print functions of each -separate color object. - - // Create a new color object - c := color.New(color.FgCyan).Add(color.Underline) - c.Println("Prints cyan text with an underline.") - - // Or just add them to New() - d := color.New(color.FgCyan, color.Bold) - d.Printf("This prints bold cyan %s\n", "too!.") - - - // Mix up foreground and background colors, create new mixes! - red := color.New(color.FgRed) - - boldRed := red.Add(color.Bold) - boldRed.Println("This will print text in bold red.") - - whiteBackground := red.Add(color.BgWhite) - whiteBackground.Println("Red text with White background.") - - // Use your own io.Writer output - color.New(color.FgBlue).Fprintln(myWriter, "blue color!") - - blue := color.New(color.FgBlue) - blue.Fprint(myWriter, "This will print text in blue.") - -You can create PrintXxx functions to simplify even more: - - // Create a custom print function for convenient - red := color.New(color.FgRed).PrintfFunc() - red("warning") - red("error: %s", err) - - // Mix up multiple attributes - notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() - notice("don't forget this...") - -You can also FprintXxx functions to pass your own io.Writer: - - blue := color.New(FgBlue).FprintfFunc() - blue(myWriter, "important notice: %s", stars) - - // Mix up with multiple attributes - success := color.New(color.Bold, color.FgGreen).FprintlnFunc() - success(myWriter, don't forget this...") - - -Or create SprintXxx functions to mix strings with other non-colorized strings: - - yellow := New(FgYellow).SprintFunc() - red := New(FgRed).SprintFunc() - - fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error")) - - info := New(FgWhite, BgGreen).SprintFunc() - fmt.Printf("this %s rocks!\n", info("package")) - -Windows support is enabled by default. All Print functions work as intended. -However only for color.SprintXXX functions, user should use fmt.FprintXXX and -set the output to color.Output: - - fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) - - info := New(FgWhite, BgGreen).SprintFunc() - fmt.Fprintf(color.Output, "this %s rocks!\n", info("package")) - -Using with existing code is possible. Just use the Set() method to set the -standard output to the given parameters. That way a rewrite of an existing -code is not required. - - // Use handy standard colors. - color.Set(color.FgYellow) - - fmt.Println("Existing text will be now in Yellow") - fmt.Printf("This one %s\n", "too") - - color.Unset() // don't forget to unset - - // You can mix up parameters - color.Set(color.FgMagenta, color.Bold) - defer color.Unset() // use it in your function - - fmt.Println("All text will be now bold magenta.") - -There might be a case where you want to disable color output (for example to -pipe the standard output of your app to somewhere else). `Color` has support to -disable colors both globally and for single color definition. For example -suppose you have a CLI app and a `--no-color` bool flag. You can easily disable -the color output with: - - var flagNoColor = flag.Bool("no-color", false, "Disable color output") - - if *flagNoColor { - color.NoColor = true // disables colorized output - } - -It also has support for single color definitions (local). You can -disable/enable color output on the fly: - - c := color.New(color.FgCyan) - c.Println("Prints cyan text") - - c.DisableColor() - c.Println("This is printed without any color") - - c.EnableColor() - c.Println("This prints again cyan...") -*/ -package color diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/.travis.yml b/vendor/gopkg.in/mattn/go-colorable.v0/.travis.yml deleted file mode 100644 index 98db8f060..000000000 --- a/vendor/gopkg.in/mattn/go-colorable.v0/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go -go: - - tip - -before_install: - - go get github.com/mattn/goveralls - - go get golang.org/x/tools/cmd/cover -script: - - $HOME/gopath/bin/goveralls -repotoken xnXqRGwgW3SXIguzxf90ZSK1GPYZPaGrw diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/LICENSE b/vendor/gopkg.in/mattn/go-colorable.v0/LICENSE deleted file mode 100644 index 91b5cef30..000000000 --- a/vendor/gopkg.in/mattn/go-colorable.v0/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/README.md b/vendor/gopkg.in/mattn/go-colorable.v0/README.md deleted file mode 100644 index 56729a92c..000000000 --- a/vendor/gopkg.in/mattn/go-colorable.v0/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# go-colorable - -[![Godoc Reference](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable) -[![Build Status](https://travis-ci.org/mattn/go-colorable.svg?branch=master)](https://travis-ci.org/mattn/go-colorable) -[![Coverage Status](https://coveralls.io/repos/github/mattn/go-colorable/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-colorable?branch=master) -[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable) - -Colorable writer for windows. - -For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.) -This package is possible to handle escape sequence for ansi color on windows. - -## Too Bad! - -![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png) - - -## So Good! - -![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png) - -## Usage - -```go -logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) -logrus.SetOutput(colorable.NewColorableStdout()) - -logrus.Info("succeeded") -logrus.Warn("not correct") -logrus.Error("something error") -logrus.Fatal("panic") -``` - -You can compile above code on non-windows OSs. - -## Installation - -``` -$ go get github.com/mattn/go-colorable -``` - -# License - -MIT - -# Author - -Yasuhiro Matsumoto (a.k.a mattn) diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/_example/escape-seq/main.go b/vendor/gopkg.in/mattn/go-colorable.v0/_example/escape-seq/main.go deleted file mode 100644 index 8cbcb9097..000000000 --- a/vendor/gopkg.in/mattn/go-colorable.v0/_example/escape-seq/main.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "bufio" - "fmt" - - "github.com/mattn/go-colorable" -) - -func main() { - stdOut := bufio.NewWriter(colorable.NewColorableStdout()) - - fmt.Fprint(stdOut, "\x1B[3GMove to 3rd Column\n") - fmt.Fprint(stdOut, "\x1B[1;2HMove to 2nd Column on 1st Line\n") - stdOut.Flush() -} diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/_example/logrus/main.go b/vendor/gopkg.in/mattn/go-colorable.v0/_example/logrus/main.go deleted file mode 100644 index c569164b2..000000000 --- a/vendor/gopkg.in/mattn/go-colorable.v0/_example/logrus/main.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "github.com/mattn/go-colorable" - "github.com/sirupsen/logrus" -) - -func main() { - logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) - logrus.SetOutput(colorable.NewColorableStdout()) - - logrus.Info("succeeded") - logrus.Warn("not correct") - logrus.Error("something error") - logrus.Fatal("panic") -} diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/_example/title/main.go b/vendor/gopkg.in/mattn/go-colorable.v0/_example/title/main.go deleted file mode 100644 index e208870e7..000000000 --- a/vendor/gopkg.in/mattn/go-colorable.v0/_example/title/main.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -import ( - "fmt" - "os" - . "github.com/mattn/go-colorable" -) - -func main() { - out := NewColorableStdout() - fmt.Fprint(out, "\x1B]0;TITLE Changed\007(See title and hit any key)") - var c [1]byte - os.Stdin.Read(c[:]) -} diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/colorable_appengine.go b/vendor/gopkg.in/mattn/go-colorable.v0/colorable_appengine.go deleted file mode 100644 index 1f28d773d..000000000 --- a/vendor/gopkg.in/mattn/go-colorable.v0/colorable_appengine.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build appengine - -package colorable - -import ( - "io" - "os" - - _ "github.com/mattn/go-isatty" -) - -// NewColorable return new instance of Writer which handle escape sequence. -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - return file -} - -// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. -func NewColorableStdout() io.Writer { - return os.Stdout -} - -// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. -func NewColorableStderr() io.Writer { - return os.Stderr -} diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/colorable_others.go b/vendor/gopkg.in/mattn/go-colorable.v0/colorable_others.go deleted file mode 100644 index 887f203dc..000000000 --- a/vendor/gopkg.in/mattn/go-colorable.v0/colorable_others.go +++ /dev/null @@ -1,30 +0,0 @@ -// +build !windows -// +build !appengine - -package colorable - -import ( - "io" - "os" - - _ "github.com/mattn/go-isatty" -) - -// NewColorable return new instance of Writer which handle escape sequence. -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - return file -} - -// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. -func NewColorableStdout() io.Writer { - return os.Stdout -} - -// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. -func NewColorableStderr() io.Writer { - return os.Stderr -} diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/colorable_test.go b/vendor/gopkg.in/mattn/go-colorable.v0/colorable_test.go deleted file mode 100644 index 3069869a3..000000000 --- a/vendor/gopkg.in/mattn/go-colorable.v0/colorable_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package colorable - -import ( - "bytes" - "os" - "runtime" - "testing" -) - -// checkEncoding checks that colorable is output encoding agnostic as long as -// the encoding is a superset of ASCII. This implies that one byte not part of -// an ANSI sequence must give exactly one byte in output -func checkEncoding(t *testing.T, data []byte) { - // Send non-UTF8 data to colorable - b := bytes.NewBuffer(make([]byte, 0, 10)) - if b.Len() != 0 { - t.FailNow() - } - // TODO move colorable wrapping outside the test - c := NewNonColorable(b) - c.Write(data) - if b.Len() != len(data) { - t.Fatalf("%d bytes expected, got %d", len(data), b.Len()) - } -} - -func TestEncoding(t *testing.T) { - checkEncoding(t, []byte{}) // Empty - checkEncoding(t, []byte(`abc`)) // "abc" - checkEncoding(t, []byte(`é`)) // "é" in UTF-8 - checkEncoding(t, []byte{233}) // 'é' in Latin-1 -} - -func TestNonColorable(t *testing.T) { - var buf bytes.Buffer - want := "hello" - NewNonColorable(&buf).Write([]byte("\x1b[0m" + want + "\x1b[2J")) - got := buf.String() - if got != "hello" { - t.Fatalf("want %q but %q", want, got) - } - - buf.Reset() - NewNonColorable(&buf).Write([]byte("\x1b[")) - got = buf.String() - if got != "" { - t.Fatalf("want %q but %q", "", got) - } -} - -func TestNonColorableNil(t *testing.T) { - paniced := false - func() { - defer func() { - recover() - paniced = true - }() - NewNonColorable(nil) - NewColorable(nil) - }() - - if !paniced { - t.Fatalf("should panic") - } -} - -func TestColorable(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skipf("skip this test on windows") - } - _, ok := NewColorableStdout().(*os.File) - if !ok { - t.Fatalf("should os.Stdout on UNIX") - } - _, ok = NewColorableStderr().(*os.File) - if !ok { - t.Fatalf("should os.Stdout on UNIX") - } - _, ok = NewColorable(os.Stdout).(*os.File) - if !ok { - t.Fatalf("should os.Stdout on UNIX") - } -} diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/colorable_windows.go b/vendor/gopkg.in/mattn/go-colorable.v0/colorable_windows.go deleted file mode 100644 index e17a5474e..000000000 --- a/vendor/gopkg.in/mattn/go-colorable.v0/colorable_windows.go +++ /dev/null @@ -1,884 +0,0 @@ -// +build windows -// +build !appengine - -package colorable - -import ( - "bytes" - "io" - "math" - "os" - "strconv" - "strings" - "syscall" - "unsafe" - - "github.com/mattn/go-isatty" -) - -const ( - foregroundBlue = 0x1 - foregroundGreen = 0x2 - foregroundRed = 0x4 - foregroundIntensity = 0x8 - foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity) - backgroundBlue = 0x10 - backgroundGreen = 0x20 - backgroundRed = 0x40 - backgroundIntensity = 0x80 - backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity) -) - -type wchar uint16 -type short int16 -type dword uint32 -type word uint16 - -type coord struct { - x short - y short -} - -type smallRect struct { - left short - top short - right short - bottom short -} - -type consoleScreenBufferInfo struct { - size coord - cursorPosition coord - attributes word - window smallRect - maximumWindowSize coord -} - -type consoleCursorInfo struct { - size dword - visible int32 -} - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") - procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") - procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") - procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") - procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") - procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo") - procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo") - procSetConsoleTitle = kernel32.NewProc("SetConsoleTitleW") -) - -// Writer provide colorable Writer to the console -type Writer struct { - out io.Writer - handle syscall.Handle - oldattr word - oldpos coord -} - -// NewColorable return new instance of Writer which handle escape sequence from File. -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - if isatty.IsTerminal(file.Fd()) { - var csbi consoleScreenBufferInfo - handle := syscall.Handle(file.Fd()) - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - return &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}} - } - return file -} - -// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. -func NewColorableStdout() io.Writer { - return NewColorable(os.Stdout) -} - -// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. -func NewColorableStderr() io.Writer { - return NewColorable(os.Stderr) -} - -var color256 = map[int]int{ - 0: 0x000000, - 1: 0x800000, - 2: 0x008000, - 3: 0x808000, - 4: 0x000080, - 5: 0x800080, - 6: 0x008080, - 7: 0xc0c0c0, - 8: 0x808080, - 9: 0xff0000, - 10: 0x00ff00, - 11: 0xffff00, - 12: 0x0000ff, - 13: 0xff00ff, - 14: 0x00ffff, - 15: 0xffffff, - 16: 0x000000, - 17: 0x00005f, - 18: 0x000087, - 19: 0x0000af, - 20: 0x0000d7, - 21: 0x0000ff, - 22: 0x005f00, - 23: 0x005f5f, - 24: 0x005f87, - 25: 0x005faf, - 26: 0x005fd7, - 27: 0x005fff, - 28: 0x008700, - 29: 0x00875f, - 30: 0x008787, - 31: 0x0087af, - 32: 0x0087d7, - 33: 0x0087ff, - 34: 0x00af00, - 35: 0x00af5f, - 36: 0x00af87, - 37: 0x00afaf, - 38: 0x00afd7, - 39: 0x00afff, - 40: 0x00d700, - 41: 0x00d75f, - 42: 0x00d787, - 43: 0x00d7af, - 44: 0x00d7d7, - 45: 0x00d7ff, - 46: 0x00ff00, - 47: 0x00ff5f, - 48: 0x00ff87, - 49: 0x00ffaf, - 50: 0x00ffd7, - 51: 0x00ffff, - 52: 0x5f0000, - 53: 0x5f005f, - 54: 0x5f0087, - 55: 0x5f00af, - 56: 0x5f00d7, - 57: 0x5f00ff, - 58: 0x5f5f00, - 59: 0x5f5f5f, - 60: 0x5f5f87, - 61: 0x5f5faf, - 62: 0x5f5fd7, - 63: 0x5f5fff, - 64: 0x5f8700, - 65: 0x5f875f, - 66: 0x5f8787, - 67: 0x5f87af, - 68: 0x5f87d7, - 69: 0x5f87ff, - 70: 0x5faf00, - 71: 0x5faf5f, - 72: 0x5faf87, - 73: 0x5fafaf, - 74: 0x5fafd7, - 75: 0x5fafff, - 76: 0x5fd700, - 77: 0x5fd75f, - 78: 0x5fd787, - 79: 0x5fd7af, - 80: 0x5fd7d7, - 81: 0x5fd7ff, - 82: 0x5fff00, - 83: 0x5fff5f, - 84: 0x5fff87, - 85: 0x5fffaf, - 86: 0x5fffd7, - 87: 0x5fffff, - 88: 0x870000, - 89: 0x87005f, - 90: 0x870087, - 91: 0x8700af, - 92: 0x8700d7, - 93: 0x8700ff, - 94: 0x875f00, - 95: 0x875f5f, - 96: 0x875f87, - 97: 0x875faf, - 98: 0x875fd7, - 99: 0x875fff, - 100: 0x878700, - 101: 0x87875f, - 102: 0x878787, - 103: 0x8787af, - 104: 0x8787d7, - 105: 0x8787ff, - 106: 0x87af00, - 107: 0x87af5f, - 108: 0x87af87, - 109: 0x87afaf, - 110: 0x87afd7, - 111: 0x87afff, - 112: 0x87d700, - 113: 0x87d75f, - 114: 0x87d787, - 115: 0x87d7af, - 116: 0x87d7d7, - 117: 0x87d7ff, - 118: 0x87ff00, - 119: 0x87ff5f, - 120: 0x87ff87, - 121: 0x87ffaf, - 122: 0x87ffd7, - 123: 0x87ffff, - 124: 0xaf0000, - 125: 0xaf005f, - 126: 0xaf0087, - 127: 0xaf00af, - 128: 0xaf00d7, - 129: 0xaf00ff, - 130: 0xaf5f00, - 131: 0xaf5f5f, - 132: 0xaf5f87, - 133: 0xaf5faf, - 134: 0xaf5fd7, - 135: 0xaf5fff, - 136: 0xaf8700, - 137: 0xaf875f, - 138: 0xaf8787, - 139: 0xaf87af, - 140: 0xaf87d7, - 141: 0xaf87ff, - 142: 0xafaf00, - 143: 0xafaf5f, - 144: 0xafaf87, - 145: 0xafafaf, - 146: 0xafafd7, - 147: 0xafafff, - 148: 0xafd700, - 149: 0xafd75f, - 150: 0xafd787, - 151: 0xafd7af, - 152: 0xafd7d7, - 153: 0xafd7ff, - 154: 0xafff00, - 155: 0xafff5f, - 156: 0xafff87, - 157: 0xafffaf, - 158: 0xafffd7, - 159: 0xafffff, - 160: 0xd70000, - 161: 0xd7005f, - 162: 0xd70087, - 163: 0xd700af, - 164: 0xd700d7, - 165: 0xd700ff, - 166: 0xd75f00, - 167: 0xd75f5f, - 168: 0xd75f87, - 169: 0xd75faf, - 170: 0xd75fd7, - 171: 0xd75fff, - 172: 0xd78700, - 173: 0xd7875f, - 174: 0xd78787, - 175: 0xd787af, - 176: 0xd787d7, - 177: 0xd787ff, - 178: 0xd7af00, - 179: 0xd7af5f, - 180: 0xd7af87, - 181: 0xd7afaf, - 182: 0xd7afd7, - 183: 0xd7afff, - 184: 0xd7d700, - 185: 0xd7d75f, - 186: 0xd7d787, - 187: 0xd7d7af, - 188: 0xd7d7d7, - 189: 0xd7d7ff, - 190: 0xd7ff00, - 191: 0xd7ff5f, - 192: 0xd7ff87, - 193: 0xd7ffaf, - 194: 0xd7ffd7, - 195: 0xd7ffff, - 196: 0xff0000, - 197: 0xff005f, - 198: 0xff0087, - 199: 0xff00af, - 200: 0xff00d7, - 201: 0xff00ff, - 202: 0xff5f00, - 203: 0xff5f5f, - 204: 0xff5f87, - 205: 0xff5faf, - 206: 0xff5fd7, - 207: 0xff5fff, - 208: 0xff8700, - 209: 0xff875f, - 210: 0xff8787, - 211: 0xff87af, - 212: 0xff87d7, - 213: 0xff87ff, - 214: 0xffaf00, - 215: 0xffaf5f, - 216: 0xffaf87, - 217: 0xffafaf, - 218: 0xffafd7, - 219: 0xffafff, - 220: 0xffd700, - 221: 0xffd75f, - 222: 0xffd787, - 223: 0xffd7af, - 224: 0xffd7d7, - 225: 0xffd7ff, - 226: 0xffff00, - 227: 0xffff5f, - 228: 0xffff87, - 229: 0xffffaf, - 230: 0xffffd7, - 231: 0xffffff, - 232: 0x080808, - 233: 0x121212, - 234: 0x1c1c1c, - 235: 0x262626, - 236: 0x303030, - 237: 0x3a3a3a, - 238: 0x444444, - 239: 0x4e4e4e, - 240: 0x585858, - 241: 0x626262, - 242: 0x6c6c6c, - 243: 0x767676, - 244: 0x808080, - 245: 0x8a8a8a, - 246: 0x949494, - 247: 0x9e9e9e, - 248: 0xa8a8a8, - 249: 0xb2b2b2, - 250: 0xbcbcbc, - 251: 0xc6c6c6, - 252: 0xd0d0d0, - 253: 0xdadada, - 254: 0xe4e4e4, - 255: 0xeeeeee, -} - -// `\033]0;TITLESTR\007` -func doTitleSequence(er *bytes.Reader) error { - var c byte - var err error - - c, err = er.ReadByte() - if err != nil { - return err - } - if c != '0' && c != '2' { - return nil - } - c, err = er.ReadByte() - if err != nil { - return err - } - if c != ';' { - return nil - } - title := make([]byte, 0, 80) - for { - c, err = er.ReadByte() - if err != nil { - return err - } - if c == 0x07 || c == '\n' { - break - } - title = append(title, c) - } - if len(title) > 0 { - title8, err := syscall.UTF16PtrFromString(string(title)) - if err == nil { - procSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8))) - } - } - return nil -} - -// Write write data on console -func (w *Writer) Write(data []byte) (n int, err error) { - var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - - er := bytes.NewReader(data) - var bw [1]byte -loop: - for { - c1, err := er.ReadByte() - if err != nil { - break loop - } - if c1 != 0x1b { - bw[0] = c1 - w.out.Write(bw[:]) - continue - } - c2, err := er.ReadByte() - if err != nil { - break loop - } - - if c2 == ']' { - if err := doTitleSequence(er); err != nil { - break loop - } - continue - } - if c2 != 0x5b { - continue - } - - var buf bytes.Buffer - var m byte - for { - c, err := er.ReadByte() - if err != nil { - break loop - } - if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { - m = c - break - } - buf.Write([]byte(string(c))) - } - - switch m { - case 'A': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.y -= short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'B': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.y += short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'C': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x += short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'D': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x -= short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'E': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = 0 - csbi.cursorPosition.y += short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'F': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = 0 - csbi.cursorPosition.y -= short(n) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'G': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = short(n - 1) - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'H', 'f': - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - if buf.Len() > 0 { - token := strings.Split(buf.String(), ";") - switch len(token) { - case 1: - n1, err := strconv.Atoi(token[0]) - if err != nil { - continue - } - csbi.cursorPosition.y = short(n1 - 1) - case 2: - n1, err := strconv.Atoi(token[0]) - if err != nil { - continue - } - n2, err := strconv.Atoi(token[1]) - if err != nil { - continue - } - csbi.cursorPosition.x = short(n2 - 1) - csbi.cursorPosition.y = short(n1 - 1) - } - } else { - csbi.cursorPosition.y = 0 - } - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'J': - n := 0 - if buf.Len() > 0 { - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - } - var count, written dword - var cursor coord - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - switch n { - case 0: - cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} - count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) - case 1: - cursor = coord{x: csbi.window.left, y: csbi.window.top} - count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.window.top-csbi.cursorPosition.y)*csbi.size.x) - case 2: - cursor = coord{x: csbi.window.left, y: csbi.window.top} - count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) - } - procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - case 'K': - n := 0 - if buf.Len() > 0 { - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - } - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - var cursor coord - var count, written dword - switch n { - case 0: - cursor = coord{x: csbi.cursorPosition.x + 1, y: csbi.cursorPosition.y} - count = dword(csbi.size.x - csbi.cursorPosition.x - 1) - case 1: - cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} - count = dword(csbi.size.x - csbi.cursorPosition.x) - case 2: - cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} - count = dword(csbi.size.x) - } - procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - case 'm': - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - attr := csbi.attributes - cs := buf.String() - if cs == "" { - procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr)) - continue - } - token := strings.Split(cs, ";") - for i := 0; i < len(token); i++ { - ns := token[i] - if n, err = strconv.Atoi(ns); err == nil { - switch { - case n == 0 || n == 100: - attr = w.oldattr - case 1 <= n && n <= 5: - attr |= foregroundIntensity - case n == 7: - attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) - case n == 22 || n == 25: - attr |= foregroundIntensity - case n == 27: - attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) - case 30 <= n && n <= 37: - attr &= backgroundMask - if (n-30)&1 != 0 { - attr |= foregroundRed - } - if (n-30)&2 != 0 { - attr |= foregroundGreen - } - if (n-30)&4 != 0 { - attr |= foregroundBlue - } - case n == 38: // set foreground color. - if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") { - if n256, err := strconv.Atoi(token[i+2]); err == nil { - if n256foreAttr == nil { - n256setup() - } - attr &= backgroundMask - attr |= n256foreAttr[n256] - i += 2 - } - } else { - attr = attr & (w.oldattr & backgroundMask) - } - case n == 39: // reset foreground color. - attr &= backgroundMask - attr |= w.oldattr & foregroundMask - case 40 <= n && n <= 47: - attr &= foregroundMask - if (n-40)&1 != 0 { - attr |= backgroundRed - } - if (n-40)&2 != 0 { - attr |= backgroundGreen - } - if (n-40)&4 != 0 { - attr |= backgroundBlue - } - case n == 48: // set background color. - if i < len(token)-2 && token[i+1] == "5" { - if n256, err := strconv.Atoi(token[i+2]); err == nil { - if n256backAttr == nil { - n256setup() - } - attr &= foregroundMask - attr |= n256backAttr[n256] - i += 2 - } - } else { - attr = attr & (w.oldattr & foregroundMask) - } - case n == 49: // reset foreground color. - attr &= foregroundMask - attr |= w.oldattr & backgroundMask - case 90 <= n && n <= 97: - attr = (attr & backgroundMask) - attr |= foregroundIntensity - if (n-90)&1 != 0 { - attr |= foregroundRed - } - if (n-90)&2 != 0 { - attr |= foregroundGreen - } - if (n-90)&4 != 0 { - attr |= foregroundBlue - } - case 100 <= n && n <= 107: - attr = (attr & foregroundMask) - attr |= backgroundIntensity - if (n-100)&1 != 0 { - attr |= backgroundRed - } - if (n-100)&2 != 0 { - attr |= backgroundGreen - } - if (n-100)&4 != 0 { - attr |= backgroundBlue - } - } - procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr)) - } - } - case 'h': - var ci consoleCursorInfo - cs := buf.String() - if cs == "5>" { - procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 0 - procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - } else if cs == "?25" { - procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 1 - procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - } - case 'l': - var ci consoleCursorInfo - cs := buf.String() - if cs == "5>" { - procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 1 - procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - } else if cs == "?25" { - procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 0 - procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) - } - case 's': - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - w.oldpos = csbi.cursorPosition - case 'u': - procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) - } - } - - return len(data), nil -} - -type consoleColor struct { - rgb int - red bool - green bool - blue bool - intensity bool -} - -func (c consoleColor) foregroundAttr() (attr word) { - if c.red { - attr |= foregroundRed - } - if c.green { - attr |= foregroundGreen - } - if c.blue { - attr |= foregroundBlue - } - if c.intensity { - attr |= foregroundIntensity - } - return -} - -func (c consoleColor) backgroundAttr() (attr word) { - if c.red { - attr |= backgroundRed - } - if c.green { - attr |= backgroundGreen - } - if c.blue { - attr |= backgroundBlue - } - if c.intensity { - attr |= backgroundIntensity - } - return -} - -var color16 = []consoleColor{ - {0x000000, false, false, false, false}, - {0x000080, false, false, true, false}, - {0x008000, false, true, false, false}, - {0x008080, false, true, true, false}, - {0x800000, true, false, false, false}, - {0x800080, true, false, true, false}, - {0x808000, true, true, false, false}, - {0xc0c0c0, true, true, true, false}, - {0x808080, false, false, false, true}, - {0x0000ff, false, false, true, true}, - {0x00ff00, false, true, false, true}, - {0x00ffff, false, true, true, true}, - {0xff0000, true, false, false, true}, - {0xff00ff, true, false, true, true}, - {0xffff00, true, true, false, true}, - {0xffffff, true, true, true, true}, -} - -type hsv struct { - h, s, v float32 -} - -func (a hsv) dist(b hsv) float32 { - dh := a.h - b.h - switch { - case dh > 0.5: - dh = 1 - dh - case dh < -0.5: - dh = -1 - dh - } - ds := a.s - b.s - dv := a.v - b.v - return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv))) -} - -func toHSV(rgb int) hsv { - r, g, b := float32((rgb&0xFF0000)>>16)/256.0, - float32((rgb&0x00FF00)>>8)/256.0, - float32(rgb&0x0000FF)/256.0 - min, max := minmax3f(r, g, b) - h := max - min - if h > 0 { - if max == r { - h = (g - b) / h - if h < 0 { - h += 6 - } - } else if max == g { - h = 2 + (b-r)/h - } else { - h = 4 + (r-g)/h - } - } - h /= 6.0 - s := max - min - if max != 0 { - s /= max - } - v := max - return hsv{h: h, s: s, v: v} -} - -type hsvTable []hsv - -func toHSVTable(rgbTable []consoleColor) hsvTable { - t := make(hsvTable, len(rgbTable)) - for i, c := range rgbTable { - t[i] = toHSV(c.rgb) - } - return t -} - -func (t hsvTable) find(rgb int) consoleColor { - hsv := toHSV(rgb) - n := 7 - l := float32(5.0) - for i, p := range t { - d := hsv.dist(p) - if d < l { - l, n = d, i - } - } - return color16[n] -} - -func minmax3f(a, b, c float32) (min, max float32) { - if a < b { - if b < c { - return a, c - } else if a < c { - return a, b - } else { - return c, b - } - } else { - if a < c { - return b, c - } else if b < c { - return b, a - } else { - return c, a - } - } -} - -var n256foreAttr []word -var n256backAttr []word - -func n256setup() { - n256foreAttr = make([]word, 256) - n256backAttr = make([]word, 256) - t := toHSVTable(color16) - for i, rgb := range color256 { - c := t.find(rgb) - n256foreAttr[i] = c.foregroundAttr() - n256backAttr[i] = c.backgroundAttr() - } -} diff --git a/vendor/gopkg.in/mattn/go-colorable.v0/noncolorable.go b/vendor/gopkg.in/mattn/go-colorable.v0/noncolorable.go deleted file mode 100644 index 9721e16f4..000000000 --- a/vendor/gopkg.in/mattn/go-colorable.v0/noncolorable.go +++ /dev/null @@ -1,55 +0,0 @@ -package colorable - -import ( - "bytes" - "io" -) - -// NonColorable hold writer but remove escape sequence. -type NonColorable struct { - out io.Writer -} - -// NewNonColorable return new instance of Writer which remove escape sequence from Writer. -func NewNonColorable(w io.Writer) io.Writer { - return &NonColorable{out: w} -} - -// Write write data on console -func (w *NonColorable) Write(data []byte) (n int, err error) { - er := bytes.NewReader(data) - var bw [1]byte -loop: - for { - c1, err := er.ReadByte() - if err != nil { - break loop - } - if c1 != 0x1b { - bw[0] = c1 - w.out.Write(bw[:]) - continue - } - c2, err := er.ReadByte() - if err != nil { - break loop - } - if c2 != 0x5b { - continue - } - - var buf bytes.Buffer - for { - c, err := er.ReadByte() - if err != nil { - break loop - } - if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { - break - } - buf.Write([]byte(string(c))) - } - } - - return len(data), nil -} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/.travis.yml b/vendor/gopkg.in/mattn/go-isatty.v0/.travis.yml deleted file mode 100644 index b9f8b239c..000000000 --- a/vendor/gopkg.in/mattn/go-isatty.v0/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go -go: - - tip - -before_install: - - go get github.com/mattn/goveralls - - go get golang.org/x/tools/cmd/cover -script: - - $HOME/gopath/bin/goveralls -repotoken 3gHdORO5k5ziZcWMBxnd9LrMZaJs8m9x5 diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/LICENSE b/vendor/gopkg.in/mattn/go-isatty.v0/LICENSE deleted file mode 100644 index 65dc692b6..000000000 --- a/vendor/gopkg.in/mattn/go-isatty.v0/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -Copyright (c) Yasuhiro MATSUMOTO - -MIT License (Expat) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/README.md b/vendor/gopkg.in/mattn/go-isatty.v0/README.md deleted file mode 100644 index 1e69004bb..000000000 --- a/vendor/gopkg.in/mattn/go-isatty.v0/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# go-isatty - -[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty) -[![Build Status](https://travis-ci.org/mattn/go-isatty.svg?branch=master)](https://travis-ci.org/mattn/go-isatty) -[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master) -[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty) - -isatty for golang - -## Usage - -```go -package main - -import ( - "fmt" - "github.com/mattn/go-isatty" - "os" -) - -func main() { - if isatty.IsTerminal(os.Stdout.Fd()) { - fmt.Println("Is Terminal") - } else if isatty.IsCygwinTerminal(os.Stdout.Fd()) { - fmt.Println("Is Cygwin/MSYS2 Terminal") - } else { - fmt.Println("Is Not Terminal") - } -} -``` - -## Installation - -``` -$ go get github.com/mattn/go-isatty -``` - -## License - -MIT - -## Author - -Yasuhiro Matsumoto (a.k.a mattn) - -## Thanks - -* k-takata: base idea for IsCygwinTerminal - - https://github.com/k-takata/go-iscygpty diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/doc.go b/vendor/gopkg.in/mattn/go-isatty.v0/doc.go deleted file mode 100644 index 17d4f90eb..000000000 --- a/vendor/gopkg.in/mattn/go-isatty.v0/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package isatty implements interface to isatty -package isatty diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/example_test.go b/vendor/gopkg.in/mattn/go-isatty.v0/example_test.go deleted file mode 100644 index fa8f7e745..000000000 --- a/vendor/gopkg.in/mattn/go-isatty.v0/example_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package isatty_test - -import ( - "fmt" - "os" - - "github.com/mattn/go-isatty" -) - -func Example() { - if isatty.IsTerminal(os.Stdout.Fd()) { - fmt.Println("Is Terminal") - } else if isatty.IsCygwinTerminal(os.Stdout.Fd()) { - fmt.Println("Is Cygwin/MSYS2 Terminal") - } else { - fmt.Println("Is Not Terminal") - } -} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_appengine.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_appengine.go deleted file mode 100644 index 9584a9884..000000000 --- a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_appengine.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build appengine - -package isatty - -// IsTerminal returns true if the file descriptor is terminal which -// is always false on on appengine classic which is a sandboxed PaaS. -func IsTerminal(fd uintptr) bool { - return false -} - -// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 -// terminal. This is also always false on this environment. -func IsCygwinTerminal(fd uintptr) bool { - return false -} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_bsd.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_bsd.go deleted file mode 100644 index 42f2514d1..000000000 --- a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_bsd.go +++ /dev/null @@ -1,18 +0,0 @@ -// +build darwin freebsd openbsd netbsd dragonfly -// +build !appengine - -package isatty - -import ( - "syscall" - "unsafe" -) - -const ioctlReadTermios = syscall.TIOCGETA - -// IsTerminal return true if the file descriptor is terminal. -func IsTerminal(fd uintptr) bool { - var termios syscall.Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 -} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux.go deleted file mode 100644 index 7384cf991..000000000 --- a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux.go +++ /dev/null @@ -1,18 +0,0 @@ -// +build linux -// +build !appengine,!ppc64,!ppc64le - -package isatty - -import ( - "syscall" - "unsafe" -) - -const ioctlReadTermios = syscall.TCGETS - -// IsTerminal return true if the file descriptor is terminal. -func IsTerminal(fd uintptr) bool { - var termios syscall.Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 -} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux_ppc64x.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux_ppc64x.go deleted file mode 100644 index 44e5d2130..000000000 --- a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_linux_ppc64x.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build linux -// +build ppc64 ppc64le - -package isatty - -import ( - "unsafe" - - syscall "golang.org/x/sys/unix" -) - -const ioctlReadTermios = syscall.TCGETS - -// IsTerminal return true if the file descriptor is terminal. -func IsTerminal(fd uintptr) bool { - var termios syscall.Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 -} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_others.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_others.go deleted file mode 100644 index ff4de3d9a..000000000 --- a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_others.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build !windows -// +build !appengine - -package isatty - -// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 -// terminal. This is also always false on this environment. -func IsCygwinTerminal(fd uintptr) bool { - return false -} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_others_test.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_others_test.go deleted file mode 100644 index a2091cf47..000000000 --- a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_others_test.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build !windows - -package isatty - -import ( - "os" - "testing" -) - -func TestTerminal(t *testing.T) { - // test for non-panic - IsTerminal(os.Stdout.Fd()) -} - -func TestCygwinPipeName(t *testing.T) { - if IsCygwinTerminal(os.Stdout.Fd()) { - t.Fatal("should be false always") - } -} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_solaris.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_solaris.go deleted file mode 100644 index 1f0c6bf53..000000000 --- a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_solaris.go +++ /dev/null @@ -1,16 +0,0 @@ -// +build solaris -// +build !appengine - -package isatty - -import ( - "golang.org/x/sys/unix" -) - -// IsTerminal returns true if the given file descriptor is a terminal. -// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c -func IsTerminal(fd uintptr) bool { - var termio unix.Termio - err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio) - return err == nil -} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows.go deleted file mode 100644 index af51cbcaa..000000000 --- a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows.go +++ /dev/null @@ -1,94 +0,0 @@ -// +build windows -// +build !appengine - -package isatty - -import ( - "strings" - "syscall" - "unicode/utf16" - "unsafe" -) - -const ( - fileNameInfo uintptr = 2 - fileTypePipe = 3 -) - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") - procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx") - procGetFileType = kernel32.NewProc("GetFileType") -) - -func init() { - // Check if GetFileInformationByHandleEx is available. - if procGetFileInformationByHandleEx.Find() != nil { - procGetFileInformationByHandleEx = nil - } -} - -// IsTerminal return true if the file descriptor is terminal. -func IsTerminal(fd uintptr) bool { - var st uint32 - r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) - return r != 0 && e == 0 -} - -// Check pipe name is used for cygwin/msys2 pty. -// Cygwin/MSYS2 PTY has a name like: -// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master -func isCygwinPipeName(name string) bool { - token := strings.Split(name, "-") - if len(token) < 5 { - return false - } - - if token[0] != `\msys` && token[0] != `\cygwin` { - return false - } - - if token[1] == "" { - return false - } - - if !strings.HasPrefix(token[2], "pty") { - return false - } - - if token[3] != `from` && token[3] != `to` { - return false - } - - if token[4] != "master" { - return false - } - - return true -} - -// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 -// terminal. -func IsCygwinTerminal(fd uintptr) bool { - if procGetFileInformationByHandleEx == nil { - return false - } - - // Cygwin/msys's pty is a pipe. - ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0) - if ft != fileTypePipe || e != 0 { - return false - } - - var buf [2 + syscall.MAX_PATH]uint16 - r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), - 4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)), - uintptr(len(buf)*2), 0, 0) - if r == 0 || e != 0 { - return false - } - - l := *(*uint32)(unsafe.Pointer(&buf)) - return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2]))) -} diff --git a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows_test.go b/vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows_test.go deleted file mode 100644 index 777e8a603..000000000 --- a/vendor/gopkg.in/mattn/go-isatty.v0/isatty_windows_test.go +++ /dev/null @@ -1,35 +0,0 @@ -// +build windows - -package isatty - -import ( - "testing" -) - -func TestCygwinPipeName(t *testing.T) { - tests := []struct { - name string - result bool - }{ - {``, false}, - {`\msys-`, false}, - {`\cygwin-----`, false}, - {`\msys-x-PTY5-pty1-from-master`, false}, - {`\cygwin-x-PTY5-from-master`, false}, - {`\cygwin-x-pty2-from-toaster`, false}, - {`\cygwin--pty2-from-master`, false}, - {`\\cygwin-x-pty2-from-master`, false}, - {`\cygwin-x-pty2-from-master-`, true}, // for the feature - {`\cygwin-e022582115c10879-pty4-from-master`, true}, - {`\msys-e022582115c10879-pty4-to-master`, true}, - {`\cygwin-e022582115c10879-pty4-to-master`, true}, - } - - for _, test := range tests { - want := test.result - got := isCygwinPipeName(test.name) - if want != got { - t.Fatalf("isatty(%q): got %v, want %v:", test.name, got, want) - } - } -} diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/.travis.yml b/vendor/gopkg.in/mattn/go-runewidth.v0/.travis.yml deleted file mode 100644 index 5c9c2a30f..000000000 --- a/vendor/gopkg.in/mattn/go-runewidth.v0/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: go -go: - - tip -before_install: - - go get github.com/mattn/goveralls - - go get golang.org/x/tools/cmd/cover -script: - - $HOME/gopath/bin/goveralls -repotoken lAKAWPzcGsD3A8yBX3BGGtRUdJ6CaGERL diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/LICENSE b/vendor/gopkg.in/mattn/go-runewidth.v0/LICENSE deleted file mode 100644 index 91b5cef30..000000000 --- a/vendor/gopkg.in/mattn/go-runewidth.v0/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/README.mkd b/vendor/gopkg.in/mattn/go-runewidth.v0/README.mkd deleted file mode 100644 index 66663a94b..000000000 --- a/vendor/gopkg.in/mattn/go-runewidth.v0/README.mkd +++ /dev/null @@ -1,27 +0,0 @@ -go-runewidth -============ - -[![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth) -[![Coverage Status](https://coveralls.io/repos/mattn/go-runewidth/badge.png?branch=HEAD)](https://coveralls.io/r/mattn/go-runewidth?branch=HEAD) -[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth) -[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth) - -Provides functions to get fixed width of the character or string. - -Usage ------ - -```go -runewidth.StringWidth("つのだ☆HIRO") == 12 -``` - - -Author ------- - -Yasuhiro Matsumoto - -License -------- - -under the MIT License: http://mattn.mit-license.org/2013 diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth.go b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth.go deleted file mode 100644 index 2164497ad..000000000 --- a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth.go +++ /dev/null @@ -1,1223 +0,0 @@ -package runewidth - -var ( - // EastAsianWidth will be set true if the current locale is CJK - EastAsianWidth = IsEastAsian() - - // DefaultCondition is a condition in current locale - DefaultCondition = &Condition{EastAsianWidth} -) - -type interval struct { - first rune - last rune -} - -type table []interval - -func inTables(r rune, ts ...table) bool { - for _, t := range ts { - if inTable(r, t) { - return true - } - } - return false -} - -func inTable(r rune, t table) bool { - // func (t table) IncludesRune(r rune) bool { - if r < t[0].first { - return false - } - - bot := 0 - top := len(t) - 1 - for top >= bot { - mid := (bot + top) / 2 - - switch { - case t[mid].last < r: - bot = mid + 1 - case t[mid].first > r: - top = mid - 1 - default: - return true - } - } - - return false -} - -var private = table{ - {0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD}, -} - -var nonprint = table{ - {0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD}, - {0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F}, - {0x202A, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF}, - {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF}, -} - -var combining = table{ - {0x0300, 0x036F}, {0x0483, 0x0489}, {0x0591, 0x05BD}, - {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C5}, - {0x05C7, 0x05C7}, {0x0610, 0x061A}, {0x064B, 0x065F}, - {0x0670, 0x0670}, {0x06D6, 0x06DC}, {0x06DF, 0x06E4}, - {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, {0x0711, 0x0711}, - {0x0730, 0x074A}, {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, - {0x0816, 0x0819}, {0x081B, 0x0823}, {0x0825, 0x0827}, - {0x0829, 0x082D}, {0x0859, 0x085B}, {0x08D4, 0x08E1}, - {0x08E3, 0x0903}, {0x093A, 0x093C}, {0x093E, 0x094F}, - {0x0951, 0x0957}, {0x0962, 0x0963}, {0x0981, 0x0983}, - {0x09BC, 0x09BC}, {0x09BE, 0x09C4}, {0x09C7, 0x09C8}, - {0x09CB, 0x09CD}, {0x09D7, 0x09D7}, {0x09E2, 0x09E3}, - {0x0A01, 0x0A03}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42}, - {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, - {0x0A70, 0x0A71}, {0x0A75, 0x0A75}, {0x0A81, 0x0A83}, - {0x0ABC, 0x0ABC}, {0x0ABE, 0x0AC5}, {0x0AC7, 0x0AC9}, - {0x0ACB, 0x0ACD}, {0x0AE2, 0x0AE3}, {0x0B01, 0x0B03}, - {0x0B3C, 0x0B3C}, {0x0B3E, 0x0B44}, {0x0B47, 0x0B48}, - {0x0B4B, 0x0B4D}, {0x0B56, 0x0B57}, {0x0B62, 0x0B63}, - {0x0B82, 0x0B82}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, - {0x0BCA, 0x0BCD}, {0x0BD7, 0x0BD7}, {0x0C00, 0x0C03}, - {0x0C3E, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, - {0x0C55, 0x0C56}, {0x0C62, 0x0C63}, {0x0C81, 0x0C83}, - {0x0CBC, 0x0CBC}, {0x0CBE, 0x0CC4}, {0x0CC6, 0x0CC8}, - {0x0CCA, 0x0CCD}, {0x0CD5, 0x0CD6}, {0x0CE2, 0x0CE3}, - {0x0D01, 0x0D03}, {0x0D3E, 0x0D44}, {0x0D46, 0x0D48}, - {0x0D4A, 0x0D4D}, {0x0D57, 0x0D57}, {0x0D62, 0x0D63}, - {0x0D82, 0x0D83}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, - {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, {0x0DF2, 0x0DF3}, - {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, - {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, - {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, - {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F3E, 0x0F3F}, - {0x0F71, 0x0F84}, {0x0F86, 0x0F87}, {0x0F8D, 0x0F97}, - {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102B, 0x103E}, - {0x1056, 0x1059}, {0x105E, 0x1060}, {0x1062, 0x1064}, - {0x1067, 0x106D}, {0x1071, 0x1074}, {0x1082, 0x108D}, - {0x108F, 0x108F}, {0x109A, 0x109D}, {0x135D, 0x135F}, - {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753}, - {0x1772, 0x1773}, {0x17B4, 0x17D3}, {0x17DD, 0x17DD}, - {0x180B, 0x180D}, {0x1885, 0x1886}, {0x18A9, 0x18A9}, - {0x1920, 0x192B}, {0x1930, 0x193B}, {0x1A17, 0x1A1B}, - {0x1A55, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A7F}, - {0x1AB0, 0x1ABE}, {0x1B00, 0x1B04}, {0x1B34, 0x1B44}, - {0x1B6B, 0x1B73}, {0x1B80, 0x1B82}, {0x1BA1, 0x1BAD}, - {0x1BE6, 0x1BF3}, {0x1C24, 0x1C37}, {0x1CD0, 0x1CD2}, - {0x1CD4, 0x1CE8}, {0x1CED, 0x1CED}, {0x1CF2, 0x1CF4}, - {0x1CF8, 0x1CF9}, {0x1DC0, 0x1DF5}, {0x1DFB, 0x1DFF}, - {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2D7F, 0x2D7F}, - {0x2DE0, 0x2DFF}, {0x302A, 0x302F}, {0x3099, 0x309A}, - {0xA66F, 0xA672}, {0xA674, 0xA67D}, {0xA69E, 0xA69F}, - {0xA6F0, 0xA6F1}, {0xA802, 0xA802}, {0xA806, 0xA806}, - {0xA80B, 0xA80B}, {0xA823, 0xA827}, {0xA880, 0xA881}, - {0xA8B4, 0xA8C5}, {0xA8E0, 0xA8F1}, {0xA926, 0xA92D}, - {0xA947, 0xA953}, {0xA980, 0xA983}, {0xA9B3, 0xA9C0}, - {0xA9E5, 0xA9E5}, {0xAA29, 0xAA36}, {0xAA43, 0xAA43}, - {0xAA4C, 0xAA4D}, {0xAA7B, 0xAA7D}, {0xAAB0, 0xAAB0}, - {0xAAB2, 0xAAB4}, {0xAAB7, 0xAAB8}, {0xAABE, 0xAABF}, - {0xAAC1, 0xAAC1}, {0xAAEB, 0xAAEF}, {0xAAF5, 0xAAF6}, - {0xABE3, 0xABEA}, {0xABEC, 0xABED}, {0xFB1E, 0xFB1E}, - {0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, - {0x102E0, 0x102E0}, {0x10376, 0x1037A}, {0x10A01, 0x10A03}, - {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, {0x10A38, 0x10A3A}, - {0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x11000, 0x11002}, - {0x11038, 0x11046}, {0x1107F, 0x11082}, {0x110B0, 0x110BA}, - {0x11100, 0x11102}, {0x11127, 0x11134}, {0x11173, 0x11173}, - {0x11180, 0x11182}, {0x111B3, 0x111C0}, {0x111CA, 0x111CC}, - {0x1122C, 0x11237}, {0x1123E, 0x1123E}, {0x112DF, 0x112EA}, - {0x11300, 0x11303}, {0x1133C, 0x1133C}, {0x1133E, 0x11344}, - {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11357, 0x11357}, - {0x11362, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374}, - {0x11435, 0x11446}, {0x114B0, 0x114C3}, {0x115AF, 0x115B5}, - {0x115B8, 0x115C0}, {0x115DC, 0x115DD}, {0x11630, 0x11640}, - {0x116AB, 0x116B7}, {0x1171D, 0x1172B}, {0x11C2F, 0x11C36}, - {0x11C38, 0x11C3F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, - {0x16AF0, 0x16AF4}, {0x16B30, 0x16B36}, {0x16F51, 0x16F7E}, - {0x16F8F, 0x16F92}, {0x1BC9D, 0x1BC9E}, {0x1D165, 0x1D169}, - {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, - {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1DA00, 0x1DA36}, - {0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84}, - {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006}, - {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, - {0x1E026, 0x1E02A}, {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E94A}, - {0xE0100, 0xE01EF}, -} - -var doublewidth = table{ - {0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A}, - {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3}, - {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653}, - {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1}, - {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, - {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA}, - {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA}, - {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B}, - {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E}, - {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797}, - {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C}, - {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99}, - {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, - {0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF}, - {0x3105, 0x312D}, {0x3131, 0x318E}, {0x3190, 0x31BA}, - {0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3247}, - {0x3250, 0x32FE}, {0x3300, 0x4DBF}, {0x4E00, 0xA48C}, - {0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3}, - {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52}, - {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, - {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE0}, {0x17000, 0x187EC}, - {0x18800, 0x18AF2}, {0x1B000, 0x1B001}, {0x1F004, 0x1F004}, - {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A}, - {0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, - {0x1F250, 0x1F251}, {0x1F300, 0x1F320}, {0x1F32D, 0x1F335}, - {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA}, - {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4}, - {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440}, {0x1F442, 0x1F4FC}, - {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E}, {0x1F550, 0x1F567}, - {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4}, - {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, - {0x1F6D0, 0x1F6D2}, {0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6F6}, - {0x1F910, 0x1F91E}, {0x1F920, 0x1F927}, {0x1F930, 0x1F930}, - {0x1F933, 0x1F93E}, {0x1F940, 0x1F94B}, {0x1F950, 0x1F95E}, - {0x1F980, 0x1F991}, {0x1F9C0, 0x1F9C0}, {0x20000, 0x2FFFD}, - {0x30000, 0x3FFFD}, -} - -var ambiguous = table{ - {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, - {0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4}, - {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, - {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, - {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, - {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, - {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101}, - {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, - {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, - {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, - {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, - {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, - {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, - {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, - {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, - {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, - {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, - {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F}, - {0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1}, - {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F}, - {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016}, - {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022}, - {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033}, - {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E}, - {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, - {0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105}, - {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116}, - {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B}, - {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B}, - {0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199}, - {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4}, - {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, - {0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F}, - {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A}, - {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225}, - {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237}, - {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C}, - {0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267}, - {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283}, - {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, - {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312}, - {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573}, - {0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1}, - {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, - {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, - {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5}, - {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609}, - {0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E}, - {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661}, - {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D}, - {0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF}, - {0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1}, - {0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1}, - {0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC}, - {0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F}, - {0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF}, - {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A}, - {0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D}, - {0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF}, - {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}, -} - -var emoji = table{ - {0x1F1E6, 0x1F1FF}, {0x1F321, 0x1F321}, {0x1F324, 0x1F32C}, - {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, {0x1F396, 0x1F397}, - {0x1F399, 0x1F39B}, {0x1F39E, 0x1F39F}, {0x1F3CB, 0x1F3CE}, - {0x1F3D4, 0x1F3DF}, {0x1F3F3, 0x1F3F5}, {0x1F3F7, 0x1F3F7}, - {0x1F43F, 0x1F43F}, {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FD}, - {0x1F549, 0x1F54A}, {0x1F56F, 0x1F570}, {0x1F573, 0x1F579}, - {0x1F587, 0x1F587}, {0x1F58A, 0x1F58D}, {0x1F590, 0x1F590}, - {0x1F5A5, 0x1F5A5}, {0x1F5A8, 0x1F5A8}, {0x1F5B1, 0x1F5B2}, - {0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4}, {0x1F5D1, 0x1F5D3}, - {0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1}, {0x1F5E3, 0x1F5E3}, - {0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF}, {0x1F5F3, 0x1F5F3}, - {0x1F5FA, 0x1F5FA}, {0x1F6CB, 0x1F6CF}, {0x1F6E0, 0x1F6E5}, - {0x1F6E9, 0x1F6E9}, {0x1F6F0, 0x1F6F0}, {0x1F6F3, 0x1F6F3}, -} - -var notassigned = table{ - {0x0378, 0x0379}, {0x0380, 0x0383}, {0x038B, 0x038B}, - {0x038D, 0x038D}, {0x03A2, 0x03A2}, {0x0530, 0x0530}, - {0x0557, 0x0558}, {0x0560, 0x0560}, {0x0588, 0x0588}, - {0x058B, 0x058C}, {0x0590, 0x0590}, {0x05C8, 0x05CF}, - {0x05EB, 0x05EF}, {0x05F5, 0x05FF}, {0x061D, 0x061D}, - {0x070E, 0x070E}, {0x074B, 0x074C}, {0x07B2, 0x07BF}, - {0x07FB, 0x07FF}, {0x082E, 0x082F}, {0x083F, 0x083F}, - {0x085C, 0x085D}, {0x085F, 0x089F}, {0x08B5, 0x08B5}, - {0x08BE, 0x08D3}, {0x0984, 0x0984}, {0x098D, 0x098E}, - {0x0991, 0x0992}, {0x09A9, 0x09A9}, {0x09B1, 0x09B1}, - {0x09B3, 0x09B5}, {0x09BA, 0x09BB}, {0x09C5, 0x09C6}, - {0x09C9, 0x09CA}, {0x09CF, 0x09D6}, {0x09D8, 0x09DB}, - {0x09DE, 0x09DE}, {0x09E4, 0x09E5}, {0x09FC, 0x0A00}, - {0x0A04, 0x0A04}, {0x0A0B, 0x0A0E}, {0x0A11, 0x0A12}, - {0x0A29, 0x0A29}, {0x0A31, 0x0A31}, {0x0A34, 0x0A34}, - {0x0A37, 0x0A37}, {0x0A3A, 0x0A3B}, {0x0A3D, 0x0A3D}, - {0x0A43, 0x0A46}, {0x0A49, 0x0A4A}, {0x0A4E, 0x0A50}, - {0x0A52, 0x0A58}, {0x0A5D, 0x0A5D}, {0x0A5F, 0x0A65}, - {0x0A76, 0x0A80}, {0x0A84, 0x0A84}, {0x0A8E, 0x0A8E}, - {0x0A92, 0x0A92}, {0x0AA9, 0x0AA9}, {0x0AB1, 0x0AB1}, - {0x0AB4, 0x0AB4}, {0x0ABA, 0x0ABB}, {0x0AC6, 0x0AC6}, - {0x0ACA, 0x0ACA}, {0x0ACE, 0x0ACF}, {0x0AD1, 0x0ADF}, - {0x0AE4, 0x0AE5}, {0x0AF2, 0x0AF8}, {0x0AFA, 0x0B00}, - {0x0B04, 0x0B04}, {0x0B0D, 0x0B0E}, {0x0B11, 0x0B12}, - {0x0B29, 0x0B29}, {0x0B31, 0x0B31}, {0x0B34, 0x0B34}, - {0x0B3A, 0x0B3B}, {0x0B45, 0x0B46}, {0x0B49, 0x0B4A}, - {0x0B4E, 0x0B55}, {0x0B58, 0x0B5B}, {0x0B5E, 0x0B5E}, - {0x0B64, 0x0B65}, {0x0B78, 0x0B81}, {0x0B84, 0x0B84}, - {0x0B8B, 0x0B8D}, {0x0B91, 0x0B91}, {0x0B96, 0x0B98}, - {0x0B9B, 0x0B9B}, {0x0B9D, 0x0B9D}, {0x0BA0, 0x0BA2}, - {0x0BA5, 0x0BA7}, {0x0BAB, 0x0BAD}, {0x0BBA, 0x0BBD}, - {0x0BC3, 0x0BC5}, {0x0BC9, 0x0BC9}, {0x0BCE, 0x0BCF}, - {0x0BD1, 0x0BD6}, {0x0BD8, 0x0BE5}, {0x0BFB, 0x0BFF}, - {0x0C04, 0x0C04}, {0x0C0D, 0x0C0D}, {0x0C11, 0x0C11}, - {0x0C29, 0x0C29}, {0x0C3A, 0x0C3C}, {0x0C45, 0x0C45}, - {0x0C49, 0x0C49}, {0x0C4E, 0x0C54}, {0x0C57, 0x0C57}, - {0x0C5B, 0x0C5F}, {0x0C64, 0x0C65}, {0x0C70, 0x0C77}, - {0x0C84, 0x0C84}, {0x0C8D, 0x0C8D}, {0x0C91, 0x0C91}, - {0x0CA9, 0x0CA9}, {0x0CB4, 0x0CB4}, {0x0CBA, 0x0CBB}, - {0x0CC5, 0x0CC5}, {0x0CC9, 0x0CC9}, {0x0CCE, 0x0CD4}, - {0x0CD7, 0x0CDD}, {0x0CDF, 0x0CDF}, {0x0CE4, 0x0CE5}, - {0x0CF0, 0x0CF0}, {0x0CF3, 0x0D00}, {0x0D04, 0x0D04}, - {0x0D0D, 0x0D0D}, {0x0D11, 0x0D11}, {0x0D3B, 0x0D3C}, - {0x0D45, 0x0D45}, {0x0D49, 0x0D49}, {0x0D50, 0x0D53}, - {0x0D64, 0x0D65}, {0x0D80, 0x0D81}, {0x0D84, 0x0D84}, - {0x0D97, 0x0D99}, {0x0DB2, 0x0DB2}, {0x0DBC, 0x0DBC}, - {0x0DBE, 0x0DBF}, {0x0DC7, 0x0DC9}, {0x0DCB, 0x0DCE}, - {0x0DD5, 0x0DD5}, {0x0DD7, 0x0DD7}, {0x0DE0, 0x0DE5}, - {0x0DF0, 0x0DF1}, {0x0DF5, 0x0E00}, {0x0E3B, 0x0E3E}, - {0x0E5C, 0x0E80}, {0x0E83, 0x0E83}, {0x0E85, 0x0E86}, - {0x0E89, 0x0E89}, {0x0E8B, 0x0E8C}, {0x0E8E, 0x0E93}, - {0x0E98, 0x0E98}, {0x0EA0, 0x0EA0}, {0x0EA4, 0x0EA4}, - {0x0EA6, 0x0EA6}, {0x0EA8, 0x0EA9}, {0x0EAC, 0x0EAC}, - {0x0EBA, 0x0EBA}, {0x0EBE, 0x0EBF}, {0x0EC5, 0x0EC5}, - {0x0EC7, 0x0EC7}, {0x0ECE, 0x0ECF}, {0x0EDA, 0x0EDB}, - {0x0EE0, 0x0EFF}, {0x0F48, 0x0F48}, {0x0F6D, 0x0F70}, - {0x0F98, 0x0F98}, {0x0FBD, 0x0FBD}, {0x0FCD, 0x0FCD}, - {0x0FDB, 0x0FFF}, {0x10C6, 0x10C6}, {0x10C8, 0x10CC}, - {0x10CE, 0x10CF}, {0x1249, 0x1249}, {0x124E, 0x124F}, - {0x1257, 0x1257}, {0x1259, 0x1259}, {0x125E, 0x125F}, - {0x1289, 0x1289}, {0x128E, 0x128F}, {0x12B1, 0x12B1}, - {0x12B6, 0x12B7}, {0x12BF, 0x12BF}, {0x12C1, 0x12C1}, - {0x12C6, 0x12C7}, {0x12D7, 0x12D7}, {0x1311, 0x1311}, - {0x1316, 0x1317}, {0x135B, 0x135C}, {0x137D, 0x137F}, - {0x139A, 0x139F}, {0x13F6, 0x13F7}, {0x13FE, 0x13FF}, - {0x169D, 0x169F}, {0x16F9, 0x16FF}, {0x170D, 0x170D}, - {0x1715, 0x171F}, {0x1737, 0x173F}, {0x1754, 0x175F}, - {0x176D, 0x176D}, {0x1771, 0x1771}, {0x1774, 0x177F}, - {0x17DE, 0x17DF}, {0x17EA, 0x17EF}, {0x17FA, 0x17FF}, - {0x180F, 0x180F}, {0x181A, 0x181F}, {0x1878, 0x187F}, - {0x18AB, 0x18AF}, {0x18F6, 0x18FF}, {0x191F, 0x191F}, - {0x192C, 0x192F}, {0x193C, 0x193F}, {0x1941, 0x1943}, - {0x196E, 0x196F}, {0x1975, 0x197F}, {0x19AC, 0x19AF}, - {0x19CA, 0x19CF}, {0x19DB, 0x19DD}, {0x1A1C, 0x1A1D}, - {0x1A5F, 0x1A5F}, {0x1A7D, 0x1A7E}, {0x1A8A, 0x1A8F}, - {0x1A9A, 0x1A9F}, {0x1AAE, 0x1AAF}, {0x1ABF, 0x1AFF}, - {0x1B4C, 0x1B4F}, {0x1B7D, 0x1B7F}, {0x1BF4, 0x1BFB}, - {0x1C38, 0x1C3A}, {0x1C4A, 0x1C4C}, {0x1C89, 0x1CBF}, - {0x1CC8, 0x1CCF}, {0x1CF7, 0x1CF7}, {0x1CFA, 0x1CFF}, - {0x1DF6, 0x1DFA}, {0x1F16, 0x1F17}, {0x1F1E, 0x1F1F}, - {0x1F46, 0x1F47}, {0x1F4E, 0x1F4F}, {0x1F58, 0x1F58}, - {0x1F5A, 0x1F5A}, {0x1F5C, 0x1F5C}, {0x1F5E, 0x1F5E}, - {0x1F7E, 0x1F7F}, {0x1FB5, 0x1FB5}, {0x1FC5, 0x1FC5}, - {0x1FD4, 0x1FD5}, {0x1FDC, 0x1FDC}, {0x1FF0, 0x1FF1}, - {0x1FF5, 0x1FF5}, {0x1FFF, 0x1FFF}, {0x2065, 0x2065}, - {0x2072, 0x2073}, {0x208F, 0x208F}, {0x209D, 0x209F}, - {0x20BF, 0x20CF}, {0x20F1, 0x20FF}, {0x218C, 0x218F}, - {0x23FF, 0x23FF}, {0x2427, 0x243F}, {0x244B, 0x245F}, - {0x2B74, 0x2B75}, {0x2B96, 0x2B97}, {0x2BBA, 0x2BBC}, - {0x2BC9, 0x2BC9}, {0x2BD2, 0x2BEB}, {0x2BF0, 0x2BFF}, - {0x2C2F, 0x2C2F}, {0x2C5F, 0x2C5F}, {0x2CF4, 0x2CF8}, - {0x2D26, 0x2D26}, {0x2D28, 0x2D2C}, {0x2D2E, 0x2D2F}, - {0x2D68, 0x2D6E}, {0x2D71, 0x2D7E}, {0x2D97, 0x2D9F}, - {0x2DA7, 0x2DA7}, {0x2DAF, 0x2DAF}, {0x2DB7, 0x2DB7}, - {0x2DBF, 0x2DBF}, {0x2DC7, 0x2DC7}, {0x2DCF, 0x2DCF}, - {0x2DD7, 0x2DD7}, {0x2DDF, 0x2DDF}, {0x2E45, 0x2E7F}, - {0x2E9A, 0x2E9A}, {0x2EF4, 0x2EFF}, {0x2FD6, 0x2FEF}, - {0x2FFC, 0x2FFF}, {0x3040, 0x3040}, {0x3097, 0x3098}, - {0x3100, 0x3104}, {0x312E, 0x3130}, {0x318F, 0x318F}, - {0x31BB, 0x31BF}, {0x31E4, 0x31EF}, {0x321F, 0x321F}, - {0x32FF, 0x32FF}, {0x4DB6, 0x4DBF}, {0x9FD6, 0x9FFF}, - {0xA48D, 0xA48F}, {0xA4C7, 0xA4CF}, {0xA62C, 0xA63F}, - {0xA6F8, 0xA6FF}, {0xA7AF, 0xA7AF}, {0xA7B8, 0xA7F6}, - {0xA82C, 0xA82F}, {0xA83A, 0xA83F}, {0xA878, 0xA87F}, - {0xA8C6, 0xA8CD}, {0xA8DA, 0xA8DF}, {0xA8FE, 0xA8FF}, - {0xA954, 0xA95E}, {0xA97D, 0xA97F}, {0xA9CE, 0xA9CE}, - {0xA9DA, 0xA9DD}, {0xA9FF, 0xA9FF}, {0xAA37, 0xAA3F}, - {0xAA4E, 0xAA4F}, {0xAA5A, 0xAA5B}, {0xAAC3, 0xAADA}, - {0xAAF7, 0xAB00}, {0xAB07, 0xAB08}, {0xAB0F, 0xAB10}, - {0xAB17, 0xAB1F}, {0xAB27, 0xAB27}, {0xAB2F, 0xAB2F}, - {0xAB66, 0xAB6F}, {0xABEE, 0xABEF}, {0xABFA, 0xABFF}, - {0xD7A4, 0xD7AF}, {0xD7C7, 0xD7CA}, {0xD7FC, 0xD7FF}, - {0xFA6E, 0xFA6F}, {0xFADA, 0xFAFF}, {0xFB07, 0xFB12}, - {0xFB18, 0xFB1C}, {0xFB37, 0xFB37}, {0xFB3D, 0xFB3D}, - {0xFB3F, 0xFB3F}, {0xFB42, 0xFB42}, {0xFB45, 0xFB45}, - {0xFBC2, 0xFBD2}, {0xFD40, 0xFD4F}, {0xFD90, 0xFD91}, - {0xFDC8, 0xFDEF}, {0xFDFE, 0xFDFF}, {0xFE1A, 0xFE1F}, - {0xFE53, 0xFE53}, {0xFE67, 0xFE67}, {0xFE6C, 0xFE6F}, - {0xFE75, 0xFE75}, {0xFEFD, 0xFEFE}, {0xFF00, 0xFF00}, - {0xFFBF, 0xFFC1}, {0xFFC8, 0xFFC9}, {0xFFD0, 0xFFD1}, - {0xFFD8, 0xFFD9}, {0xFFDD, 0xFFDF}, {0xFFE7, 0xFFE7}, - {0xFFEF, 0xFFF8}, {0xFFFE, 0xFFFF}, {0x1000C, 0x1000C}, - {0x10027, 0x10027}, {0x1003B, 0x1003B}, {0x1003E, 0x1003E}, - {0x1004E, 0x1004F}, {0x1005E, 0x1007F}, {0x100FB, 0x100FF}, - {0x10103, 0x10106}, {0x10134, 0x10136}, {0x1018F, 0x1018F}, - {0x1019C, 0x1019F}, {0x101A1, 0x101CF}, {0x101FE, 0x1027F}, - {0x1029D, 0x1029F}, {0x102D1, 0x102DF}, {0x102FC, 0x102FF}, - {0x10324, 0x1032F}, {0x1034B, 0x1034F}, {0x1037B, 0x1037F}, - {0x1039E, 0x1039E}, {0x103C4, 0x103C7}, {0x103D6, 0x103FF}, - {0x1049E, 0x1049F}, {0x104AA, 0x104AF}, {0x104D4, 0x104D7}, - {0x104FC, 0x104FF}, {0x10528, 0x1052F}, {0x10564, 0x1056E}, - {0x10570, 0x105FF}, {0x10737, 0x1073F}, {0x10756, 0x1075F}, - {0x10768, 0x107FF}, {0x10806, 0x10807}, {0x10809, 0x10809}, - {0x10836, 0x10836}, {0x10839, 0x1083B}, {0x1083D, 0x1083E}, - {0x10856, 0x10856}, {0x1089F, 0x108A6}, {0x108B0, 0x108DF}, - {0x108F3, 0x108F3}, {0x108F6, 0x108FA}, {0x1091C, 0x1091E}, - {0x1093A, 0x1093E}, {0x10940, 0x1097F}, {0x109B8, 0x109BB}, - {0x109D0, 0x109D1}, {0x10A04, 0x10A04}, {0x10A07, 0x10A0B}, - {0x10A14, 0x10A14}, {0x10A18, 0x10A18}, {0x10A34, 0x10A37}, - {0x10A3B, 0x10A3E}, {0x10A48, 0x10A4F}, {0x10A59, 0x10A5F}, - {0x10AA0, 0x10ABF}, {0x10AE7, 0x10AEA}, {0x10AF7, 0x10AFF}, - {0x10B36, 0x10B38}, {0x10B56, 0x10B57}, {0x10B73, 0x10B77}, - {0x10B92, 0x10B98}, {0x10B9D, 0x10BA8}, {0x10BB0, 0x10BFF}, - {0x10C49, 0x10C7F}, {0x10CB3, 0x10CBF}, {0x10CF3, 0x10CF9}, - {0x10D00, 0x10E5F}, {0x10E7F, 0x10FFF}, {0x1104E, 0x11051}, - {0x11070, 0x1107E}, {0x110C2, 0x110CF}, {0x110E9, 0x110EF}, - {0x110FA, 0x110FF}, {0x11135, 0x11135}, {0x11144, 0x1114F}, - {0x11177, 0x1117F}, {0x111CE, 0x111CF}, {0x111E0, 0x111E0}, - {0x111F5, 0x111FF}, {0x11212, 0x11212}, {0x1123F, 0x1127F}, - {0x11287, 0x11287}, {0x11289, 0x11289}, {0x1128E, 0x1128E}, - {0x1129E, 0x1129E}, {0x112AA, 0x112AF}, {0x112EB, 0x112EF}, - {0x112FA, 0x112FF}, {0x11304, 0x11304}, {0x1130D, 0x1130E}, - {0x11311, 0x11312}, {0x11329, 0x11329}, {0x11331, 0x11331}, - {0x11334, 0x11334}, {0x1133A, 0x1133B}, {0x11345, 0x11346}, - {0x11349, 0x1134A}, {0x1134E, 0x1134F}, {0x11351, 0x11356}, - {0x11358, 0x1135C}, {0x11364, 0x11365}, {0x1136D, 0x1136F}, - {0x11375, 0x113FF}, {0x1145A, 0x1145A}, {0x1145C, 0x1145C}, - {0x1145E, 0x1147F}, {0x114C8, 0x114CF}, {0x114DA, 0x1157F}, - {0x115B6, 0x115B7}, {0x115DE, 0x115FF}, {0x11645, 0x1164F}, - {0x1165A, 0x1165F}, {0x1166D, 0x1167F}, {0x116B8, 0x116BF}, - {0x116CA, 0x116FF}, {0x1171A, 0x1171C}, {0x1172C, 0x1172F}, - {0x11740, 0x1189F}, {0x118F3, 0x118FE}, {0x11900, 0x11ABF}, - {0x11AF9, 0x11BFF}, {0x11C09, 0x11C09}, {0x11C37, 0x11C37}, - {0x11C46, 0x11C4F}, {0x11C6D, 0x11C6F}, {0x11C90, 0x11C91}, - {0x11CA8, 0x11CA8}, {0x11CB7, 0x11FFF}, {0x1239A, 0x123FF}, - {0x1246F, 0x1246F}, {0x12475, 0x1247F}, {0x12544, 0x12FFF}, - {0x1342F, 0x143FF}, {0x14647, 0x167FF}, {0x16A39, 0x16A3F}, - {0x16A5F, 0x16A5F}, {0x16A6A, 0x16A6D}, {0x16A70, 0x16ACF}, - {0x16AEE, 0x16AEF}, {0x16AF6, 0x16AFF}, {0x16B46, 0x16B4F}, - {0x16B5A, 0x16B5A}, {0x16B62, 0x16B62}, {0x16B78, 0x16B7C}, - {0x16B90, 0x16EFF}, {0x16F45, 0x16F4F}, {0x16F7F, 0x16F8E}, - {0x16FA0, 0x16FDF}, {0x16FE1, 0x16FFF}, {0x187ED, 0x187FF}, - {0x18AF3, 0x1AFFF}, {0x1B002, 0x1BBFF}, {0x1BC6B, 0x1BC6F}, - {0x1BC7D, 0x1BC7F}, {0x1BC89, 0x1BC8F}, {0x1BC9A, 0x1BC9B}, - {0x1BCA4, 0x1CFFF}, {0x1D0F6, 0x1D0FF}, {0x1D127, 0x1D128}, - {0x1D1E9, 0x1D1FF}, {0x1D246, 0x1D2FF}, {0x1D357, 0x1D35F}, - {0x1D372, 0x1D3FF}, {0x1D455, 0x1D455}, {0x1D49D, 0x1D49D}, - {0x1D4A0, 0x1D4A1}, {0x1D4A3, 0x1D4A4}, {0x1D4A7, 0x1D4A8}, - {0x1D4AD, 0x1D4AD}, {0x1D4BA, 0x1D4BA}, {0x1D4BC, 0x1D4BC}, - {0x1D4C4, 0x1D4C4}, {0x1D506, 0x1D506}, {0x1D50B, 0x1D50C}, - {0x1D515, 0x1D515}, {0x1D51D, 0x1D51D}, {0x1D53A, 0x1D53A}, - {0x1D53F, 0x1D53F}, {0x1D545, 0x1D545}, {0x1D547, 0x1D549}, - {0x1D551, 0x1D551}, {0x1D6A6, 0x1D6A7}, {0x1D7CC, 0x1D7CD}, - {0x1DA8C, 0x1DA9A}, {0x1DAA0, 0x1DAA0}, {0x1DAB0, 0x1DFFF}, - {0x1E007, 0x1E007}, {0x1E019, 0x1E01A}, {0x1E022, 0x1E022}, - {0x1E025, 0x1E025}, {0x1E02B, 0x1E7FF}, {0x1E8C5, 0x1E8C6}, - {0x1E8D7, 0x1E8FF}, {0x1E94B, 0x1E94F}, {0x1E95A, 0x1E95D}, - {0x1E960, 0x1EDFF}, {0x1EE04, 0x1EE04}, {0x1EE20, 0x1EE20}, - {0x1EE23, 0x1EE23}, {0x1EE25, 0x1EE26}, {0x1EE28, 0x1EE28}, - {0x1EE33, 0x1EE33}, {0x1EE38, 0x1EE38}, {0x1EE3A, 0x1EE3A}, - {0x1EE3C, 0x1EE41}, {0x1EE43, 0x1EE46}, {0x1EE48, 0x1EE48}, - {0x1EE4A, 0x1EE4A}, {0x1EE4C, 0x1EE4C}, {0x1EE50, 0x1EE50}, - {0x1EE53, 0x1EE53}, {0x1EE55, 0x1EE56}, {0x1EE58, 0x1EE58}, - {0x1EE5A, 0x1EE5A}, {0x1EE5C, 0x1EE5C}, {0x1EE5E, 0x1EE5E}, - {0x1EE60, 0x1EE60}, {0x1EE63, 0x1EE63}, {0x1EE65, 0x1EE66}, - {0x1EE6B, 0x1EE6B}, {0x1EE73, 0x1EE73}, {0x1EE78, 0x1EE78}, - {0x1EE7D, 0x1EE7D}, {0x1EE7F, 0x1EE7F}, {0x1EE8A, 0x1EE8A}, - {0x1EE9C, 0x1EEA0}, {0x1EEA4, 0x1EEA4}, {0x1EEAA, 0x1EEAA}, - {0x1EEBC, 0x1EEEF}, {0x1EEF2, 0x1EFFF}, {0x1F02C, 0x1F02F}, - {0x1F094, 0x1F09F}, {0x1F0AF, 0x1F0B0}, {0x1F0C0, 0x1F0C0}, - {0x1F0D0, 0x1F0D0}, {0x1F0F6, 0x1F0FF}, {0x1F10D, 0x1F10F}, - {0x1F12F, 0x1F12F}, {0x1F16C, 0x1F16F}, {0x1F1AD, 0x1F1E5}, - {0x1F203, 0x1F20F}, {0x1F23C, 0x1F23F}, {0x1F249, 0x1F24F}, - {0x1F252, 0x1F2FF}, {0x1F6D3, 0x1F6DF}, {0x1F6ED, 0x1F6EF}, - {0x1F6F7, 0x1F6FF}, {0x1F774, 0x1F77F}, {0x1F7D5, 0x1F7FF}, - {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, {0x1F85A, 0x1F85F}, - {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F90F}, {0x1F91F, 0x1F91F}, - {0x1F928, 0x1F92F}, {0x1F931, 0x1F932}, {0x1F93F, 0x1F93F}, - {0x1F94C, 0x1F94F}, {0x1F95F, 0x1F97F}, {0x1F992, 0x1F9BF}, - {0x1F9C1, 0x1FFFF}, {0x2A6D7, 0x2A6FF}, {0x2B735, 0x2B73F}, - {0x2B81E, 0x2B81F}, {0x2CEA2, 0x2F7FF}, {0x2FA1E, 0xE0000}, - {0xE0002, 0xE001F}, {0xE0080, 0xE00FF}, {0xE01F0, 0xEFFFF}, - {0xFFFFE, 0xFFFFF}, -} - -var neutral = table{ - {0x0000, 0x001F}, {0x007F, 0x007F}, {0x0080, 0x009F}, - {0x00A0, 0x00A0}, {0x00A9, 0x00A9}, {0x00AB, 0x00AB}, - {0x00B5, 0x00B5}, {0x00BB, 0x00BB}, {0x00C0, 0x00C5}, - {0x00C7, 0x00CF}, {0x00D1, 0x00D6}, {0x00D9, 0x00DD}, - {0x00E2, 0x00E5}, {0x00E7, 0x00E7}, {0x00EB, 0x00EB}, - {0x00EE, 0x00EF}, {0x00F1, 0x00F1}, {0x00F4, 0x00F6}, - {0x00FB, 0x00FB}, {0x00FD, 0x00FD}, {0x00FF, 0x00FF}, - {0x0100, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112}, - {0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A}, - {0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E}, - {0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C}, - {0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A}, - {0x016C, 0x017F}, {0x0180, 0x01BA}, {0x01BB, 0x01BB}, - {0x01BC, 0x01BF}, {0x01C0, 0x01C3}, {0x01C4, 0x01CD}, - {0x01CF, 0x01CF}, {0x01D1, 0x01D1}, {0x01D3, 0x01D3}, - {0x01D5, 0x01D5}, {0x01D7, 0x01D7}, {0x01D9, 0x01D9}, - {0x01DB, 0x01DB}, {0x01DD, 0x024F}, {0x0250, 0x0250}, - {0x0252, 0x0260}, {0x0262, 0x0293}, {0x0294, 0x0294}, - {0x0295, 0x02AF}, {0x02B0, 0x02C1}, {0x02C2, 0x02C3}, - {0x02C5, 0x02C5}, {0x02C6, 0x02C6}, {0x02C8, 0x02C8}, - {0x02CC, 0x02CC}, {0x02CE, 0x02CF}, {0x02D1, 0x02D1}, - {0x02D2, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE}, - {0x02E0, 0x02E4}, {0x02E5, 0x02EB}, {0x02EC, 0x02EC}, - {0x02ED, 0x02ED}, {0x02EE, 0x02EE}, {0x02EF, 0x02FF}, - {0x0370, 0x0373}, {0x0374, 0x0374}, {0x0375, 0x0375}, - {0x0376, 0x0377}, {0x037A, 0x037A}, {0x037B, 0x037D}, - {0x037E, 0x037E}, {0x037F, 0x037F}, {0x0384, 0x0385}, - {0x0386, 0x0386}, {0x0387, 0x0387}, {0x0388, 0x038A}, - {0x038C, 0x038C}, {0x038E, 0x0390}, {0x03AA, 0x03B0}, - {0x03C2, 0x03C2}, {0x03CA, 0x03F5}, {0x03F6, 0x03F6}, - {0x03F7, 0x03FF}, {0x0400, 0x0400}, {0x0402, 0x040F}, - {0x0450, 0x0450}, {0x0452, 0x0481}, {0x0482, 0x0482}, - {0x0483, 0x0487}, {0x0488, 0x0489}, {0x048A, 0x04FF}, - {0x0500, 0x052F}, {0x0531, 0x0556}, {0x0559, 0x0559}, - {0x055A, 0x055F}, {0x0561, 0x0587}, {0x0589, 0x0589}, - {0x058A, 0x058A}, {0x058D, 0x058E}, {0x058F, 0x058F}, - {0x0591, 0x05BD}, {0x05BE, 0x05BE}, {0x05BF, 0x05BF}, - {0x05C0, 0x05C0}, {0x05C1, 0x05C2}, {0x05C3, 0x05C3}, - {0x05C4, 0x05C5}, {0x05C6, 0x05C6}, {0x05C7, 0x05C7}, - {0x05D0, 0x05EA}, {0x05F0, 0x05F2}, {0x05F3, 0x05F4}, - {0x0600, 0x0605}, {0x0606, 0x0608}, {0x0609, 0x060A}, - {0x060B, 0x060B}, {0x060C, 0x060D}, {0x060E, 0x060F}, - {0x0610, 0x061A}, {0x061B, 0x061B}, {0x061C, 0x061C}, - {0x061E, 0x061F}, {0x0620, 0x063F}, {0x0640, 0x0640}, - {0x0641, 0x064A}, {0x064B, 0x065F}, {0x0660, 0x0669}, - {0x066A, 0x066D}, {0x066E, 0x066F}, {0x0670, 0x0670}, - {0x0671, 0x06D3}, {0x06D4, 0x06D4}, {0x06D5, 0x06D5}, - {0x06D6, 0x06DC}, {0x06DD, 0x06DD}, {0x06DE, 0x06DE}, - {0x06DF, 0x06E4}, {0x06E5, 0x06E6}, {0x06E7, 0x06E8}, - {0x06E9, 0x06E9}, {0x06EA, 0x06ED}, {0x06EE, 0x06EF}, - {0x06F0, 0x06F9}, {0x06FA, 0x06FC}, {0x06FD, 0x06FE}, - {0x06FF, 0x06FF}, {0x0700, 0x070D}, {0x070F, 0x070F}, - {0x0710, 0x0710}, {0x0711, 0x0711}, {0x0712, 0x072F}, - {0x0730, 0x074A}, {0x074D, 0x074F}, {0x0750, 0x077F}, - {0x0780, 0x07A5}, {0x07A6, 0x07B0}, {0x07B1, 0x07B1}, - {0x07C0, 0x07C9}, {0x07CA, 0x07EA}, {0x07EB, 0x07F3}, - {0x07F4, 0x07F5}, {0x07F6, 0x07F6}, {0x07F7, 0x07F9}, - {0x07FA, 0x07FA}, {0x0800, 0x0815}, {0x0816, 0x0819}, - {0x081A, 0x081A}, {0x081B, 0x0823}, {0x0824, 0x0824}, - {0x0825, 0x0827}, {0x0828, 0x0828}, {0x0829, 0x082D}, - {0x0830, 0x083E}, {0x0840, 0x0858}, {0x0859, 0x085B}, - {0x085E, 0x085E}, {0x08A0, 0x08B4}, {0x08B6, 0x08BD}, - {0x08D4, 0x08E1}, {0x08E2, 0x08E2}, {0x08E3, 0x08FF}, - {0x0900, 0x0902}, {0x0903, 0x0903}, {0x0904, 0x0939}, - {0x093A, 0x093A}, {0x093B, 0x093B}, {0x093C, 0x093C}, - {0x093D, 0x093D}, {0x093E, 0x0940}, {0x0941, 0x0948}, - {0x0949, 0x094C}, {0x094D, 0x094D}, {0x094E, 0x094F}, - {0x0950, 0x0950}, {0x0951, 0x0957}, {0x0958, 0x0961}, - {0x0962, 0x0963}, {0x0964, 0x0965}, {0x0966, 0x096F}, - {0x0970, 0x0970}, {0x0971, 0x0971}, {0x0972, 0x097F}, - {0x0980, 0x0980}, {0x0981, 0x0981}, {0x0982, 0x0983}, - {0x0985, 0x098C}, {0x098F, 0x0990}, {0x0993, 0x09A8}, - {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9}, - {0x09BC, 0x09BC}, {0x09BD, 0x09BD}, {0x09BE, 0x09C0}, - {0x09C1, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CC}, - {0x09CD, 0x09CD}, {0x09CE, 0x09CE}, {0x09D7, 0x09D7}, - {0x09DC, 0x09DD}, {0x09DF, 0x09E1}, {0x09E2, 0x09E3}, - {0x09E6, 0x09EF}, {0x09F0, 0x09F1}, {0x09F2, 0x09F3}, - {0x09F4, 0x09F9}, {0x09FA, 0x09FA}, {0x09FB, 0x09FB}, - {0x0A01, 0x0A02}, {0x0A03, 0x0A03}, {0x0A05, 0x0A0A}, - {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, - {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, - {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A40}, {0x0A41, 0x0A42}, - {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, - {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A6F}, - {0x0A70, 0x0A71}, {0x0A72, 0x0A74}, {0x0A75, 0x0A75}, - {0x0A81, 0x0A82}, {0x0A83, 0x0A83}, {0x0A85, 0x0A8D}, - {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, - {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABC, 0x0ABC}, - {0x0ABD, 0x0ABD}, {0x0ABE, 0x0AC0}, {0x0AC1, 0x0AC5}, - {0x0AC7, 0x0AC8}, {0x0AC9, 0x0AC9}, {0x0ACB, 0x0ACC}, - {0x0ACD, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE1}, - {0x0AE2, 0x0AE3}, {0x0AE6, 0x0AEF}, {0x0AF0, 0x0AF0}, - {0x0AF1, 0x0AF1}, {0x0AF9, 0x0AF9}, {0x0B01, 0x0B01}, - {0x0B02, 0x0B03}, {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, - {0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, - {0x0B35, 0x0B39}, {0x0B3C, 0x0B3C}, {0x0B3D, 0x0B3D}, - {0x0B3E, 0x0B3E}, {0x0B3F, 0x0B3F}, {0x0B40, 0x0B40}, - {0x0B41, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4C}, - {0x0B4D, 0x0B4D}, {0x0B56, 0x0B56}, {0x0B57, 0x0B57}, - {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61}, {0x0B62, 0x0B63}, - {0x0B66, 0x0B6F}, {0x0B70, 0x0B70}, {0x0B71, 0x0B71}, - {0x0B72, 0x0B77}, {0x0B82, 0x0B82}, {0x0B83, 0x0B83}, - {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, - {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F}, - {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9}, - {0x0BBE, 0x0BBF}, {0x0BC0, 0x0BC0}, {0x0BC1, 0x0BC2}, - {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCC}, {0x0BCD, 0x0BCD}, - {0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BEF}, - {0x0BF0, 0x0BF2}, {0x0BF3, 0x0BF8}, {0x0BF9, 0x0BF9}, - {0x0BFA, 0x0BFA}, {0x0C00, 0x0C00}, {0x0C01, 0x0C03}, - {0x0C05, 0x0C0C}, {0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, - {0x0C2A, 0x0C39}, {0x0C3D, 0x0C3D}, {0x0C3E, 0x0C40}, - {0x0C41, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, - {0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C61}, - {0x0C62, 0x0C63}, {0x0C66, 0x0C6F}, {0x0C78, 0x0C7E}, - {0x0C7F, 0x0C7F}, {0x0C80, 0x0C80}, {0x0C81, 0x0C81}, - {0x0C82, 0x0C83}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90}, - {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, - {0x0CBC, 0x0CBC}, {0x0CBD, 0x0CBD}, {0x0CBE, 0x0CBE}, - {0x0CBF, 0x0CBF}, {0x0CC0, 0x0CC4}, {0x0CC6, 0x0CC6}, - {0x0CC7, 0x0CC8}, {0x0CCA, 0x0CCB}, {0x0CCC, 0x0CCD}, - {0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE1}, - {0x0CE2, 0x0CE3}, {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, - {0x0D01, 0x0D01}, {0x0D02, 0x0D03}, {0x0D05, 0x0D0C}, - {0x0D0E, 0x0D10}, {0x0D12, 0x0D3A}, {0x0D3D, 0x0D3D}, - {0x0D3E, 0x0D40}, {0x0D41, 0x0D44}, {0x0D46, 0x0D48}, - {0x0D4A, 0x0D4C}, {0x0D4D, 0x0D4D}, {0x0D4E, 0x0D4E}, - {0x0D4F, 0x0D4F}, {0x0D54, 0x0D56}, {0x0D57, 0x0D57}, - {0x0D58, 0x0D5E}, {0x0D5F, 0x0D61}, {0x0D62, 0x0D63}, - {0x0D66, 0x0D6F}, {0x0D70, 0x0D78}, {0x0D79, 0x0D79}, - {0x0D7A, 0x0D7F}, {0x0D82, 0x0D83}, {0x0D85, 0x0D96}, - {0x0D9A, 0x0DB1}, {0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, - {0x0DC0, 0x0DC6}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD1}, - {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, - {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF3}, {0x0DF4, 0x0DF4}, - {0x0E01, 0x0E30}, {0x0E31, 0x0E31}, {0x0E32, 0x0E33}, - {0x0E34, 0x0E3A}, {0x0E3F, 0x0E3F}, {0x0E40, 0x0E45}, - {0x0E46, 0x0E46}, {0x0E47, 0x0E4E}, {0x0E4F, 0x0E4F}, - {0x0E50, 0x0E59}, {0x0E5A, 0x0E5B}, {0x0E81, 0x0E82}, - {0x0E84, 0x0E84}, {0x0E87, 0x0E88}, {0x0E8A, 0x0E8A}, - {0x0E8D, 0x0E8D}, {0x0E94, 0x0E97}, {0x0E99, 0x0E9F}, - {0x0EA1, 0x0EA3}, {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EA7}, - {0x0EAA, 0x0EAB}, {0x0EAD, 0x0EB0}, {0x0EB1, 0x0EB1}, - {0x0EB2, 0x0EB3}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, - {0x0EBD, 0x0EBD}, {0x0EC0, 0x0EC4}, {0x0EC6, 0x0EC6}, - {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9}, {0x0EDC, 0x0EDF}, - {0x0F00, 0x0F00}, {0x0F01, 0x0F03}, {0x0F04, 0x0F12}, - {0x0F13, 0x0F13}, {0x0F14, 0x0F14}, {0x0F15, 0x0F17}, - {0x0F18, 0x0F19}, {0x0F1A, 0x0F1F}, {0x0F20, 0x0F29}, - {0x0F2A, 0x0F33}, {0x0F34, 0x0F34}, {0x0F35, 0x0F35}, - {0x0F36, 0x0F36}, {0x0F37, 0x0F37}, {0x0F38, 0x0F38}, - {0x0F39, 0x0F39}, {0x0F3A, 0x0F3A}, {0x0F3B, 0x0F3B}, - {0x0F3C, 0x0F3C}, {0x0F3D, 0x0F3D}, {0x0F3E, 0x0F3F}, - {0x0F40, 0x0F47}, {0x0F49, 0x0F6C}, {0x0F71, 0x0F7E}, - {0x0F7F, 0x0F7F}, {0x0F80, 0x0F84}, {0x0F85, 0x0F85}, - {0x0F86, 0x0F87}, {0x0F88, 0x0F8C}, {0x0F8D, 0x0F97}, - {0x0F99, 0x0FBC}, {0x0FBE, 0x0FC5}, {0x0FC6, 0x0FC6}, - {0x0FC7, 0x0FCC}, {0x0FCE, 0x0FCF}, {0x0FD0, 0x0FD4}, - {0x0FD5, 0x0FD8}, {0x0FD9, 0x0FDA}, {0x1000, 0x102A}, - {0x102B, 0x102C}, {0x102D, 0x1030}, {0x1031, 0x1031}, - {0x1032, 0x1037}, {0x1038, 0x1038}, {0x1039, 0x103A}, - {0x103B, 0x103C}, {0x103D, 0x103E}, {0x103F, 0x103F}, - {0x1040, 0x1049}, {0x104A, 0x104F}, {0x1050, 0x1055}, - {0x1056, 0x1057}, {0x1058, 0x1059}, {0x105A, 0x105D}, - {0x105E, 0x1060}, {0x1061, 0x1061}, {0x1062, 0x1064}, - {0x1065, 0x1066}, {0x1067, 0x106D}, {0x106E, 0x1070}, - {0x1071, 0x1074}, {0x1075, 0x1081}, {0x1082, 0x1082}, - {0x1083, 0x1084}, {0x1085, 0x1086}, {0x1087, 0x108C}, - {0x108D, 0x108D}, {0x108E, 0x108E}, {0x108F, 0x108F}, - {0x1090, 0x1099}, {0x109A, 0x109C}, {0x109D, 0x109D}, - {0x109E, 0x109F}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, - {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FB, 0x10FB}, - {0x10FC, 0x10FC}, {0x10FD, 0x10FF}, {0x1160, 0x11FF}, - {0x1200, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, - {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, - {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, - {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, - {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, - {0x1318, 0x135A}, {0x135D, 0x135F}, {0x1360, 0x1368}, - {0x1369, 0x137C}, {0x1380, 0x138F}, {0x1390, 0x1399}, - {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1400, 0x1400}, - {0x1401, 0x166C}, {0x166D, 0x166E}, {0x166F, 0x167F}, - {0x1680, 0x1680}, {0x1681, 0x169A}, {0x169B, 0x169B}, - {0x169C, 0x169C}, {0x16A0, 0x16EA}, {0x16EB, 0x16ED}, - {0x16EE, 0x16F0}, {0x16F1, 0x16F8}, {0x1700, 0x170C}, - {0x170E, 0x1711}, {0x1712, 0x1714}, {0x1720, 0x1731}, - {0x1732, 0x1734}, {0x1735, 0x1736}, {0x1740, 0x1751}, - {0x1752, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770}, - {0x1772, 0x1773}, {0x1780, 0x17B3}, {0x17B4, 0x17B5}, - {0x17B6, 0x17B6}, {0x17B7, 0x17BD}, {0x17BE, 0x17C5}, - {0x17C6, 0x17C6}, {0x17C7, 0x17C8}, {0x17C9, 0x17D3}, - {0x17D4, 0x17D6}, {0x17D7, 0x17D7}, {0x17D8, 0x17DA}, - {0x17DB, 0x17DB}, {0x17DC, 0x17DC}, {0x17DD, 0x17DD}, - {0x17E0, 0x17E9}, {0x17F0, 0x17F9}, {0x1800, 0x1805}, - {0x1806, 0x1806}, {0x1807, 0x180A}, {0x180B, 0x180D}, - {0x180E, 0x180E}, {0x1810, 0x1819}, {0x1820, 0x1842}, - {0x1843, 0x1843}, {0x1844, 0x1877}, {0x1880, 0x1884}, - {0x1885, 0x1886}, {0x1887, 0x18A8}, {0x18A9, 0x18A9}, - {0x18AA, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E}, - {0x1920, 0x1922}, {0x1923, 0x1926}, {0x1927, 0x1928}, - {0x1929, 0x192B}, {0x1930, 0x1931}, {0x1932, 0x1932}, - {0x1933, 0x1938}, {0x1939, 0x193B}, {0x1940, 0x1940}, - {0x1944, 0x1945}, {0x1946, 0x194F}, {0x1950, 0x196D}, - {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, - {0x19D0, 0x19D9}, {0x19DA, 0x19DA}, {0x19DE, 0x19DF}, - {0x19E0, 0x19FF}, {0x1A00, 0x1A16}, {0x1A17, 0x1A18}, - {0x1A19, 0x1A1A}, {0x1A1B, 0x1A1B}, {0x1A1E, 0x1A1F}, - {0x1A20, 0x1A54}, {0x1A55, 0x1A55}, {0x1A56, 0x1A56}, - {0x1A57, 0x1A57}, {0x1A58, 0x1A5E}, {0x1A60, 0x1A60}, - {0x1A61, 0x1A61}, {0x1A62, 0x1A62}, {0x1A63, 0x1A64}, - {0x1A65, 0x1A6C}, {0x1A6D, 0x1A72}, {0x1A73, 0x1A7C}, - {0x1A7F, 0x1A7F}, {0x1A80, 0x1A89}, {0x1A90, 0x1A99}, - {0x1AA0, 0x1AA6}, {0x1AA7, 0x1AA7}, {0x1AA8, 0x1AAD}, - {0x1AB0, 0x1ABD}, {0x1ABE, 0x1ABE}, {0x1B00, 0x1B03}, - {0x1B04, 0x1B04}, {0x1B05, 0x1B33}, {0x1B34, 0x1B34}, - {0x1B35, 0x1B35}, {0x1B36, 0x1B3A}, {0x1B3B, 0x1B3B}, - {0x1B3C, 0x1B3C}, {0x1B3D, 0x1B41}, {0x1B42, 0x1B42}, - {0x1B43, 0x1B44}, {0x1B45, 0x1B4B}, {0x1B50, 0x1B59}, - {0x1B5A, 0x1B60}, {0x1B61, 0x1B6A}, {0x1B6B, 0x1B73}, - {0x1B74, 0x1B7C}, {0x1B80, 0x1B81}, {0x1B82, 0x1B82}, - {0x1B83, 0x1BA0}, {0x1BA1, 0x1BA1}, {0x1BA2, 0x1BA5}, - {0x1BA6, 0x1BA7}, {0x1BA8, 0x1BA9}, {0x1BAA, 0x1BAA}, - {0x1BAB, 0x1BAD}, {0x1BAE, 0x1BAF}, {0x1BB0, 0x1BB9}, - {0x1BBA, 0x1BBF}, {0x1BC0, 0x1BE5}, {0x1BE6, 0x1BE6}, - {0x1BE7, 0x1BE7}, {0x1BE8, 0x1BE9}, {0x1BEA, 0x1BEC}, - {0x1BED, 0x1BED}, {0x1BEE, 0x1BEE}, {0x1BEF, 0x1BF1}, - {0x1BF2, 0x1BF3}, {0x1BFC, 0x1BFF}, {0x1C00, 0x1C23}, - {0x1C24, 0x1C2B}, {0x1C2C, 0x1C33}, {0x1C34, 0x1C35}, - {0x1C36, 0x1C37}, {0x1C3B, 0x1C3F}, {0x1C40, 0x1C49}, - {0x1C4D, 0x1C4F}, {0x1C50, 0x1C59}, {0x1C5A, 0x1C77}, - {0x1C78, 0x1C7D}, {0x1C7E, 0x1C7F}, {0x1C80, 0x1C88}, - {0x1CC0, 0x1CC7}, {0x1CD0, 0x1CD2}, {0x1CD3, 0x1CD3}, - {0x1CD4, 0x1CE0}, {0x1CE1, 0x1CE1}, {0x1CE2, 0x1CE8}, - {0x1CE9, 0x1CEC}, {0x1CED, 0x1CED}, {0x1CEE, 0x1CF1}, - {0x1CF2, 0x1CF3}, {0x1CF4, 0x1CF4}, {0x1CF5, 0x1CF6}, - {0x1CF8, 0x1CF9}, {0x1D00, 0x1D2B}, {0x1D2C, 0x1D6A}, - {0x1D6B, 0x1D77}, {0x1D78, 0x1D78}, {0x1D79, 0x1D7F}, - {0x1D80, 0x1D9A}, {0x1D9B, 0x1DBF}, {0x1DC0, 0x1DF5}, - {0x1DFB, 0x1DFF}, {0x1E00, 0x1EFF}, {0x1F00, 0x1F15}, - {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, - {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, - {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, - {0x1FB6, 0x1FBC}, {0x1FBD, 0x1FBD}, {0x1FBE, 0x1FBE}, - {0x1FBF, 0x1FC1}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, - {0x1FCD, 0x1FCF}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, - {0x1FDD, 0x1FDF}, {0x1FE0, 0x1FEC}, {0x1FED, 0x1FEF}, - {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x1FFD, 0x1FFE}, - {0x2000, 0x200A}, {0x200B, 0x200F}, {0x2011, 0x2012}, - {0x2017, 0x2017}, {0x201A, 0x201A}, {0x201B, 0x201B}, - {0x201E, 0x201E}, {0x201F, 0x201F}, {0x2023, 0x2023}, - {0x2028, 0x2028}, {0x2029, 0x2029}, {0x202A, 0x202E}, - {0x202F, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034}, - {0x2036, 0x2038}, {0x2039, 0x2039}, {0x203A, 0x203A}, - {0x203C, 0x203D}, {0x203F, 0x2040}, {0x2041, 0x2043}, - {0x2044, 0x2044}, {0x2045, 0x2045}, {0x2046, 0x2046}, - {0x2047, 0x2051}, {0x2052, 0x2052}, {0x2053, 0x2053}, - {0x2054, 0x2054}, {0x2055, 0x205E}, {0x205F, 0x205F}, - {0x2060, 0x2064}, {0x2066, 0x206F}, {0x2070, 0x2070}, - {0x2071, 0x2071}, {0x2075, 0x2079}, {0x207A, 0x207C}, - {0x207D, 0x207D}, {0x207E, 0x207E}, {0x2080, 0x2080}, - {0x2085, 0x2089}, {0x208A, 0x208C}, {0x208D, 0x208D}, - {0x208E, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8}, - {0x20AA, 0x20AB}, {0x20AD, 0x20BE}, {0x20D0, 0x20DC}, - {0x20DD, 0x20E0}, {0x20E1, 0x20E1}, {0x20E2, 0x20E4}, - {0x20E5, 0x20F0}, {0x2100, 0x2101}, {0x2102, 0x2102}, - {0x2104, 0x2104}, {0x2106, 0x2106}, {0x2107, 0x2107}, - {0x2108, 0x2108}, {0x210A, 0x2112}, {0x2114, 0x2114}, - {0x2115, 0x2115}, {0x2117, 0x2117}, {0x2118, 0x2118}, - {0x2119, 0x211D}, {0x211E, 0x2120}, {0x2123, 0x2123}, - {0x2124, 0x2124}, {0x2125, 0x2125}, {0x2127, 0x2127}, - {0x2128, 0x2128}, {0x2129, 0x2129}, {0x212A, 0x212A}, - {0x212C, 0x212D}, {0x212E, 0x212E}, {0x212F, 0x2134}, - {0x2135, 0x2138}, {0x2139, 0x2139}, {0x213A, 0x213B}, - {0x213C, 0x213F}, {0x2140, 0x2144}, {0x2145, 0x2149}, - {0x214A, 0x214A}, {0x214B, 0x214B}, {0x214C, 0x214D}, - {0x214E, 0x214E}, {0x214F, 0x214F}, {0x2150, 0x2152}, - {0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F}, - {0x217A, 0x2182}, {0x2183, 0x2184}, {0x2185, 0x2188}, - {0x218A, 0x218B}, {0x219A, 0x219B}, {0x219C, 0x219F}, - {0x21A0, 0x21A0}, {0x21A1, 0x21A2}, {0x21A3, 0x21A3}, - {0x21A4, 0x21A5}, {0x21A6, 0x21A6}, {0x21A7, 0x21AD}, - {0x21AE, 0x21AE}, {0x21AF, 0x21B7}, {0x21BA, 0x21CD}, - {0x21CE, 0x21CF}, {0x21D0, 0x21D1}, {0x21D3, 0x21D3}, - {0x21D5, 0x21E6}, {0x21E8, 0x21F3}, {0x21F4, 0x21FF}, - {0x2201, 0x2201}, {0x2204, 0x2206}, {0x2209, 0x220A}, - {0x220C, 0x220E}, {0x2210, 0x2210}, {0x2212, 0x2214}, - {0x2216, 0x2219}, {0x221B, 0x221C}, {0x2221, 0x2222}, - {0x2224, 0x2224}, {0x2226, 0x2226}, {0x222D, 0x222D}, - {0x222F, 0x2233}, {0x2238, 0x223B}, {0x223E, 0x2247}, - {0x2249, 0x224B}, {0x224D, 0x2251}, {0x2253, 0x225F}, - {0x2262, 0x2263}, {0x2268, 0x2269}, {0x226C, 0x226D}, - {0x2270, 0x2281}, {0x2284, 0x2285}, {0x2288, 0x2294}, - {0x2296, 0x2298}, {0x229A, 0x22A4}, {0x22A6, 0x22BE}, - {0x22C0, 0x22FF}, {0x2300, 0x2307}, {0x2308, 0x2308}, - {0x2309, 0x2309}, {0x230A, 0x230A}, {0x230B, 0x230B}, - {0x230C, 0x2311}, {0x2313, 0x2319}, {0x231C, 0x231F}, - {0x2320, 0x2321}, {0x2322, 0x2328}, {0x232B, 0x237B}, - {0x237C, 0x237C}, {0x237D, 0x239A}, {0x239B, 0x23B3}, - {0x23B4, 0x23DB}, {0x23DC, 0x23E1}, {0x23E2, 0x23E8}, - {0x23ED, 0x23EF}, {0x23F1, 0x23F2}, {0x23F4, 0x23FE}, - {0x2400, 0x2426}, {0x2440, 0x244A}, {0x24EA, 0x24EA}, - {0x254C, 0x254F}, {0x2574, 0x257F}, {0x2590, 0x2591}, - {0x2596, 0x259F}, {0x25A2, 0x25A2}, {0x25AA, 0x25B1}, - {0x25B4, 0x25B5}, {0x25B8, 0x25BB}, {0x25BE, 0x25BF}, - {0x25C2, 0x25C5}, {0x25C9, 0x25CA}, {0x25CC, 0x25CD}, - {0x25D2, 0x25E1}, {0x25E6, 0x25EE}, {0x25F0, 0x25F7}, - {0x25F8, 0x25FC}, {0x25FF, 0x25FF}, {0x2600, 0x2604}, - {0x2607, 0x2608}, {0x260A, 0x260D}, {0x2610, 0x2613}, - {0x2616, 0x261B}, {0x261D, 0x261D}, {0x261F, 0x263F}, - {0x2641, 0x2641}, {0x2643, 0x2647}, {0x2654, 0x265F}, - {0x2662, 0x2662}, {0x2666, 0x2666}, {0x266B, 0x266B}, - {0x266E, 0x266E}, {0x2670, 0x267E}, {0x2680, 0x2692}, - {0x2694, 0x269D}, {0x26A0, 0x26A0}, {0x26A2, 0x26A9}, - {0x26AC, 0x26BC}, {0x26C0, 0x26C3}, {0x26E2, 0x26E2}, - {0x26E4, 0x26E7}, {0x2700, 0x2704}, {0x2706, 0x2709}, - {0x270C, 0x2727}, {0x2729, 0x273C}, {0x273E, 0x274B}, - {0x274D, 0x274D}, {0x274F, 0x2752}, {0x2756, 0x2756}, - {0x2758, 0x2767}, {0x2768, 0x2768}, {0x2769, 0x2769}, - {0x276A, 0x276A}, {0x276B, 0x276B}, {0x276C, 0x276C}, - {0x276D, 0x276D}, {0x276E, 0x276E}, {0x276F, 0x276F}, - {0x2770, 0x2770}, {0x2771, 0x2771}, {0x2772, 0x2772}, - {0x2773, 0x2773}, {0x2774, 0x2774}, {0x2775, 0x2775}, - {0x2780, 0x2793}, {0x2794, 0x2794}, {0x2798, 0x27AF}, - {0x27B1, 0x27BE}, {0x27C0, 0x27C4}, {0x27C5, 0x27C5}, - {0x27C6, 0x27C6}, {0x27C7, 0x27E5}, {0x27EE, 0x27EE}, - {0x27EF, 0x27EF}, {0x27F0, 0x27FF}, {0x2800, 0x28FF}, - {0x2900, 0x297F}, {0x2980, 0x2982}, {0x2983, 0x2983}, - {0x2984, 0x2984}, {0x2987, 0x2987}, {0x2988, 0x2988}, - {0x2989, 0x2989}, {0x298A, 0x298A}, {0x298B, 0x298B}, - {0x298C, 0x298C}, {0x298D, 0x298D}, {0x298E, 0x298E}, - {0x298F, 0x298F}, {0x2990, 0x2990}, {0x2991, 0x2991}, - {0x2992, 0x2992}, {0x2993, 0x2993}, {0x2994, 0x2994}, - {0x2995, 0x2995}, {0x2996, 0x2996}, {0x2997, 0x2997}, - {0x2998, 0x2998}, {0x2999, 0x29D7}, {0x29D8, 0x29D8}, - {0x29D9, 0x29D9}, {0x29DA, 0x29DA}, {0x29DB, 0x29DB}, - {0x29DC, 0x29FB}, {0x29FC, 0x29FC}, {0x29FD, 0x29FD}, - {0x29FE, 0x29FF}, {0x2A00, 0x2AFF}, {0x2B00, 0x2B1A}, - {0x2B1D, 0x2B2F}, {0x2B30, 0x2B44}, {0x2B45, 0x2B46}, - {0x2B47, 0x2B4C}, {0x2B4D, 0x2B4F}, {0x2B51, 0x2B54}, - {0x2B5A, 0x2B73}, {0x2B76, 0x2B95}, {0x2B98, 0x2BB9}, - {0x2BBD, 0x2BC8}, {0x2BCA, 0x2BD1}, {0x2BEC, 0x2BEF}, - {0x2C00, 0x2C2E}, {0x2C30, 0x2C5E}, {0x2C60, 0x2C7B}, - {0x2C7C, 0x2C7D}, {0x2C7E, 0x2C7F}, {0x2C80, 0x2CE4}, - {0x2CE5, 0x2CEA}, {0x2CEB, 0x2CEE}, {0x2CEF, 0x2CF1}, - {0x2CF2, 0x2CF3}, {0x2CF9, 0x2CFC}, {0x2CFD, 0x2CFD}, - {0x2CFE, 0x2CFF}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, - {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D6F}, - {0x2D70, 0x2D70}, {0x2D7F, 0x2D7F}, {0x2D80, 0x2D96}, - {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, - {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, - {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2DFF}, - {0x2E00, 0x2E01}, {0x2E02, 0x2E02}, {0x2E03, 0x2E03}, - {0x2E04, 0x2E04}, {0x2E05, 0x2E05}, {0x2E06, 0x2E08}, - {0x2E09, 0x2E09}, {0x2E0A, 0x2E0A}, {0x2E0B, 0x2E0B}, - {0x2E0C, 0x2E0C}, {0x2E0D, 0x2E0D}, {0x2E0E, 0x2E16}, - {0x2E17, 0x2E17}, {0x2E18, 0x2E19}, {0x2E1A, 0x2E1A}, - {0x2E1B, 0x2E1B}, {0x2E1C, 0x2E1C}, {0x2E1D, 0x2E1D}, - {0x2E1E, 0x2E1F}, {0x2E20, 0x2E20}, {0x2E21, 0x2E21}, - {0x2E22, 0x2E22}, {0x2E23, 0x2E23}, {0x2E24, 0x2E24}, - {0x2E25, 0x2E25}, {0x2E26, 0x2E26}, {0x2E27, 0x2E27}, - {0x2E28, 0x2E28}, {0x2E29, 0x2E29}, {0x2E2A, 0x2E2E}, - {0x2E2F, 0x2E2F}, {0x2E30, 0x2E39}, {0x2E3A, 0x2E3B}, - {0x2E3C, 0x2E3F}, {0x2E40, 0x2E40}, {0x2E41, 0x2E41}, - {0x2E42, 0x2E42}, {0x2E43, 0x2E44}, {0x303F, 0x303F}, - {0x4DC0, 0x4DFF}, {0xA4D0, 0xA4F7}, {0xA4F8, 0xA4FD}, - {0xA4FE, 0xA4FF}, {0xA500, 0xA60B}, {0xA60C, 0xA60C}, - {0xA60D, 0xA60F}, {0xA610, 0xA61F}, {0xA620, 0xA629}, - {0xA62A, 0xA62B}, {0xA640, 0xA66D}, {0xA66E, 0xA66E}, - {0xA66F, 0xA66F}, {0xA670, 0xA672}, {0xA673, 0xA673}, - {0xA674, 0xA67D}, {0xA67E, 0xA67E}, {0xA67F, 0xA67F}, - {0xA680, 0xA69B}, {0xA69C, 0xA69D}, {0xA69E, 0xA69F}, - {0xA6A0, 0xA6E5}, {0xA6E6, 0xA6EF}, {0xA6F0, 0xA6F1}, - {0xA6F2, 0xA6F7}, {0xA700, 0xA716}, {0xA717, 0xA71F}, - {0xA720, 0xA721}, {0xA722, 0xA76F}, {0xA770, 0xA770}, - {0xA771, 0xA787}, {0xA788, 0xA788}, {0xA789, 0xA78A}, - {0xA78B, 0xA78E}, {0xA78F, 0xA78F}, {0xA790, 0xA7AE}, - {0xA7B0, 0xA7B7}, {0xA7F7, 0xA7F7}, {0xA7F8, 0xA7F9}, - {0xA7FA, 0xA7FA}, {0xA7FB, 0xA7FF}, {0xA800, 0xA801}, - {0xA802, 0xA802}, {0xA803, 0xA805}, {0xA806, 0xA806}, - {0xA807, 0xA80A}, {0xA80B, 0xA80B}, {0xA80C, 0xA822}, - {0xA823, 0xA824}, {0xA825, 0xA826}, {0xA827, 0xA827}, - {0xA828, 0xA82B}, {0xA830, 0xA835}, {0xA836, 0xA837}, - {0xA838, 0xA838}, {0xA839, 0xA839}, {0xA840, 0xA873}, - {0xA874, 0xA877}, {0xA880, 0xA881}, {0xA882, 0xA8B3}, - {0xA8B4, 0xA8C3}, {0xA8C4, 0xA8C5}, {0xA8CE, 0xA8CF}, - {0xA8D0, 0xA8D9}, {0xA8E0, 0xA8F1}, {0xA8F2, 0xA8F7}, - {0xA8F8, 0xA8FA}, {0xA8FB, 0xA8FB}, {0xA8FC, 0xA8FC}, - {0xA8FD, 0xA8FD}, {0xA900, 0xA909}, {0xA90A, 0xA925}, - {0xA926, 0xA92D}, {0xA92E, 0xA92F}, {0xA930, 0xA946}, - {0xA947, 0xA951}, {0xA952, 0xA953}, {0xA95F, 0xA95F}, - {0xA980, 0xA982}, {0xA983, 0xA983}, {0xA984, 0xA9B2}, - {0xA9B3, 0xA9B3}, {0xA9B4, 0xA9B5}, {0xA9B6, 0xA9B9}, - {0xA9BA, 0xA9BB}, {0xA9BC, 0xA9BC}, {0xA9BD, 0xA9C0}, - {0xA9C1, 0xA9CD}, {0xA9CF, 0xA9CF}, {0xA9D0, 0xA9D9}, - {0xA9DE, 0xA9DF}, {0xA9E0, 0xA9E4}, {0xA9E5, 0xA9E5}, - {0xA9E6, 0xA9E6}, {0xA9E7, 0xA9EF}, {0xA9F0, 0xA9F9}, - {0xA9FA, 0xA9FE}, {0xAA00, 0xAA28}, {0xAA29, 0xAA2E}, - {0xAA2F, 0xAA30}, {0xAA31, 0xAA32}, {0xAA33, 0xAA34}, - {0xAA35, 0xAA36}, {0xAA40, 0xAA42}, {0xAA43, 0xAA43}, - {0xAA44, 0xAA4B}, {0xAA4C, 0xAA4C}, {0xAA4D, 0xAA4D}, - {0xAA50, 0xAA59}, {0xAA5C, 0xAA5F}, {0xAA60, 0xAA6F}, - {0xAA70, 0xAA70}, {0xAA71, 0xAA76}, {0xAA77, 0xAA79}, - {0xAA7A, 0xAA7A}, {0xAA7B, 0xAA7B}, {0xAA7C, 0xAA7C}, - {0xAA7D, 0xAA7D}, {0xAA7E, 0xAA7F}, {0xAA80, 0xAAAF}, - {0xAAB0, 0xAAB0}, {0xAAB1, 0xAAB1}, {0xAAB2, 0xAAB4}, - {0xAAB5, 0xAAB6}, {0xAAB7, 0xAAB8}, {0xAAB9, 0xAABD}, - {0xAABE, 0xAABF}, {0xAAC0, 0xAAC0}, {0xAAC1, 0xAAC1}, - {0xAAC2, 0xAAC2}, {0xAADB, 0xAADC}, {0xAADD, 0xAADD}, - {0xAADE, 0xAADF}, {0xAAE0, 0xAAEA}, {0xAAEB, 0xAAEB}, - {0xAAEC, 0xAAED}, {0xAAEE, 0xAAEF}, {0xAAF0, 0xAAF1}, - {0xAAF2, 0xAAF2}, {0xAAF3, 0xAAF4}, {0xAAF5, 0xAAF5}, - {0xAAF6, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, - {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, - {0xAB30, 0xAB5A}, {0xAB5B, 0xAB5B}, {0xAB5C, 0xAB5F}, - {0xAB60, 0xAB65}, {0xAB70, 0xABBF}, {0xABC0, 0xABE2}, - {0xABE3, 0xABE4}, {0xABE5, 0xABE5}, {0xABE6, 0xABE7}, - {0xABE8, 0xABE8}, {0xABE9, 0xABEA}, {0xABEB, 0xABEB}, - {0xABEC, 0xABEC}, {0xABED, 0xABED}, {0xABF0, 0xABF9}, - {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDB7F}, - {0xDB80, 0xDBFF}, {0xDC00, 0xDFFF}, {0xFB00, 0xFB06}, - {0xFB13, 0xFB17}, {0xFB1D, 0xFB1D}, {0xFB1E, 0xFB1E}, - {0xFB1F, 0xFB28}, {0xFB29, 0xFB29}, {0xFB2A, 0xFB36}, - {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, - {0xFB43, 0xFB44}, {0xFB46, 0xFB4F}, {0xFB50, 0xFBB1}, - {0xFBB2, 0xFBC1}, {0xFBD3, 0xFD3D}, {0xFD3E, 0xFD3E}, - {0xFD3F, 0xFD3F}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, - {0xFDF0, 0xFDFB}, {0xFDFC, 0xFDFC}, {0xFDFD, 0xFDFD}, - {0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, - {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFC, 0xFFFC}, - {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, - {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, - {0x10080, 0x100FA}, {0x10100, 0x10102}, {0x10107, 0x10133}, - {0x10137, 0x1013F}, {0x10140, 0x10174}, {0x10175, 0x10178}, - {0x10179, 0x10189}, {0x1018A, 0x1018B}, {0x1018C, 0x1018E}, - {0x10190, 0x1019B}, {0x101A0, 0x101A0}, {0x101D0, 0x101FC}, - {0x101FD, 0x101FD}, {0x10280, 0x1029C}, {0x102A0, 0x102D0}, - {0x102E0, 0x102E0}, {0x102E1, 0x102FB}, {0x10300, 0x1031F}, - {0x10320, 0x10323}, {0x10330, 0x10340}, {0x10341, 0x10341}, - {0x10342, 0x10349}, {0x1034A, 0x1034A}, {0x10350, 0x10375}, - {0x10376, 0x1037A}, {0x10380, 0x1039D}, {0x1039F, 0x1039F}, - {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D0, 0x103D0}, - {0x103D1, 0x103D5}, {0x10400, 0x1044F}, {0x10450, 0x1047F}, - {0x10480, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, - {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, - {0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755}, - {0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808}, - {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, - {0x1083F, 0x1083F}, {0x10840, 0x10855}, {0x10857, 0x10857}, - {0x10858, 0x1085F}, {0x10860, 0x10876}, {0x10877, 0x10878}, - {0x10879, 0x1087F}, {0x10880, 0x1089E}, {0x108A7, 0x108AF}, - {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x108FF}, - {0x10900, 0x10915}, {0x10916, 0x1091B}, {0x1091F, 0x1091F}, - {0x10920, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x1099F}, - {0x109A0, 0x109B7}, {0x109BC, 0x109BD}, {0x109BE, 0x109BF}, - {0x109C0, 0x109CF}, {0x109D2, 0x109FF}, {0x10A00, 0x10A00}, - {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, - {0x10A10, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A33}, - {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x10A40, 0x10A47}, - {0x10A50, 0x10A58}, {0x10A60, 0x10A7C}, {0x10A7D, 0x10A7E}, - {0x10A7F, 0x10A7F}, {0x10A80, 0x10A9C}, {0x10A9D, 0x10A9F}, - {0x10AC0, 0x10AC7}, {0x10AC8, 0x10AC8}, {0x10AC9, 0x10AE4}, - {0x10AE5, 0x10AE6}, {0x10AEB, 0x10AEF}, {0x10AF0, 0x10AF6}, - {0x10B00, 0x10B35}, {0x10B39, 0x10B3F}, {0x10B40, 0x10B55}, - {0x10B58, 0x10B5F}, {0x10B60, 0x10B72}, {0x10B78, 0x10B7F}, - {0x10B80, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, - {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, - {0x10CFA, 0x10CFF}, {0x10E60, 0x10E7E}, {0x11000, 0x11000}, - {0x11001, 0x11001}, {0x11002, 0x11002}, {0x11003, 0x11037}, - {0x11038, 0x11046}, {0x11047, 0x1104D}, {0x11052, 0x11065}, - {0x11066, 0x1106F}, {0x1107F, 0x1107F}, {0x11080, 0x11081}, - {0x11082, 0x11082}, {0x11083, 0x110AF}, {0x110B0, 0x110B2}, - {0x110B3, 0x110B6}, {0x110B7, 0x110B8}, {0x110B9, 0x110BA}, - {0x110BB, 0x110BC}, {0x110BD, 0x110BD}, {0x110BE, 0x110C1}, - {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11100, 0x11102}, - {0x11103, 0x11126}, {0x11127, 0x1112B}, {0x1112C, 0x1112C}, - {0x1112D, 0x11134}, {0x11136, 0x1113F}, {0x11140, 0x11143}, - {0x11150, 0x11172}, {0x11173, 0x11173}, {0x11174, 0x11175}, - {0x11176, 0x11176}, {0x11180, 0x11181}, {0x11182, 0x11182}, - {0x11183, 0x111B2}, {0x111B3, 0x111B5}, {0x111B6, 0x111BE}, - {0x111BF, 0x111C0}, {0x111C1, 0x111C4}, {0x111C5, 0x111C9}, - {0x111CA, 0x111CC}, {0x111CD, 0x111CD}, {0x111D0, 0x111D9}, - {0x111DA, 0x111DA}, {0x111DB, 0x111DB}, {0x111DC, 0x111DC}, - {0x111DD, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211}, - {0x11213, 0x1122B}, {0x1122C, 0x1122E}, {0x1122F, 0x11231}, - {0x11232, 0x11233}, {0x11234, 0x11234}, {0x11235, 0x11235}, - {0x11236, 0x11237}, {0x11238, 0x1123D}, {0x1123E, 0x1123E}, - {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, - {0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112A9, 0x112A9}, - {0x112B0, 0x112DE}, {0x112DF, 0x112DF}, {0x112E0, 0x112E2}, - {0x112E3, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11301}, - {0x11302, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, - {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, - {0x11335, 0x11339}, {0x1133C, 0x1133C}, {0x1133D, 0x1133D}, - {0x1133E, 0x1133F}, {0x11340, 0x11340}, {0x11341, 0x11344}, - {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350}, - {0x11357, 0x11357}, {0x1135D, 0x11361}, {0x11362, 0x11363}, - {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11400, 0x11434}, - {0x11435, 0x11437}, {0x11438, 0x1143F}, {0x11440, 0x11441}, - {0x11442, 0x11444}, {0x11445, 0x11445}, {0x11446, 0x11446}, - {0x11447, 0x1144A}, {0x1144B, 0x1144F}, {0x11450, 0x11459}, - {0x1145B, 0x1145B}, {0x1145D, 0x1145D}, {0x11480, 0x114AF}, - {0x114B0, 0x114B2}, {0x114B3, 0x114B8}, {0x114B9, 0x114B9}, - {0x114BA, 0x114BA}, {0x114BB, 0x114BE}, {0x114BF, 0x114C0}, - {0x114C1, 0x114C1}, {0x114C2, 0x114C3}, {0x114C4, 0x114C5}, - {0x114C6, 0x114C6}, {0x114C7, 0x114C7}, {0x114D0, 0x114D9}, - {0x11580, 0x115AE}, {0x115AF, 0x115B1}, {0x115B2, 0x115B5}, - {0x115B8, 0x115BB}, {0x115BC, 0x115BD}, {0x115BE, 0x115BE}, - {0x115BF, 0x115C0}, {0x115C1, 0x115D7}, {0x115D8, 0x115DB}, - {0x115DC, 0x115DD}, {0x11600, 0x1162F}, {0x11630, 0x11632}, - {0x11633, 0x1163A}, {0x1163B, 0x1163C}, {0x1163D, 0x1163D}, - {0x1163E, 0x1163E}, {0x1163F, 0x11640}, {0x11641, 0x11643}, - {0x11644, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C}, - {0x11680, 0x116AA}, {0x116AB, 0x116AB}, {0x116AC, 0x116AC}, - {0x116AD, 0x116AD}, {0x116AE, 0x116AF}, {0x116B0, 0x116B5}, - {0x116B6, 0x116B6}, {0x116B7, 0x116B7}, {0x116C0, 0x116C9}, - {0x11700, 0x11719}, {0x1171D, 0x1171F}, {0x11720, 0x11721}, - {0x11722, 0x11725}, {0x11726, 0x11726}, {0x11727, 0x1172B}, - {0x11730, 0x11739}, {0x1173A, 0x1173B}, {0x1173C, 0x1173E}, - {0x1173F, 0x1173F}, {0x118A0, 0x118DF}, {0x118E0, 0x118E9}, - {0x118EA, 0x118F2}, {0x118FF, 0x118FF}, {0x11AC0, 0x11AF8}, - {0x11C00, 0x11C08}, {0x11C0A, 0x11C2E}, {0x11C2F, 0x11C2F}, - {0x11C30, 0x11C36}, {0x11C38, 0x11C3D}, {0x11C3E, 0x11C3E}, - {0x11C3F, 0x11C3F}, {0x11C40, 0x11C40}, {0x11C41, 0x11C45}, - {0x11C50, 0x11C59}, {0x11C5A, 0x11C6C}, {0x11C70, 0x11C71}, - {0x11C72, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CA9}, - {0x11CAA, 0x11CB0}, {0x11CB1, 0x11CB1}, {0x11CB2, 0x11CB3}, - {0x11CB4, 0x11CB4}, {0x11CB5, 0x11CB6}, {0x12000, 0x12399}, - {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, - {0x13000, 0x1342E}, {0x14400, 0x14646}, {0x16800, 0x16A38}, - {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16A6F}, - {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF4}, {0x16AF5, 0x16AF5}, - {0x16B00, 0x16B2F}, {0x16B30, 0x16B36}, {0x16B37, 0x16B3B}, - {0x16B3C, 0x16B3F}, {0x16B40, 0x16B43}, {0x16B44, 0x16B44}, - {0x16B45, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, - {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16F00, 0x16F44}, - {0x16F50, 0x16F50}, {0x16F51, 0x16F7E}, {0x16F8F, 0x16F92}, - {0x16F93, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, - {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BC9C}, - {0x1BC9D, 0x1BC9E}, {0x1BC9F, 0x1BC9F}, {0x1BCA0, 0x1BCA3}, - {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D164}, - {0x1D165, 0x1D166}, {0x1D167, 0x1D169}, {0x1D16A, 0x1D16C}, - {0x1D16D, 0x1D172}, {0x1D173, 0x1D17A}, {0x1D17B, 0x1D182}, - {0x1D183, 0x1D184}, {0x1D185, 0x1D18B}, {0x1D18C, 0x1D1A9}, - {0x1D1AA, 0x1D1AD}, {0x1D1AE, 0x1D1E8}, {0x1D200, 0x1D241}, - {0x1D242, 0x1D244}, {0x1D245, 0x1D245}, {0x1D300, 0x1D356}, - {0x1D360, 0x1D371}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, - {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, - {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, - {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, - {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, - {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, - {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, - {0x1D6C1, 0x1D6C1}, {0x1D6C2, 0x1D6DA}, {0x1D6DB, 0x1D6DB}, - {0x1D6DC, 0x1D6FA}, {0x1D6FB, 0x1D6FB}, {0x1D6FC, 0x1D714}, - {0x1D715, 0x1D715}, {0x1D716, 0x1D734}, {0x1D735, 0x1D735}, - {0x1D736, 0x1D74E}, {0x1D74F, 0x1D74F}, {0x1D750, 0x1D76E}, - {0x1D76F, 0x1D76F}, {0x1D770, 0x1D788}, {0x1D789, 0x1D789}, - {0x1D78A, 0x1D7A8}, {0x1D7A9, 0x1D7A9}, {0x1D7AA, 0x1D7C2}, - {0x1D7C3, 0x1D7C3}, {0x1D7C4, 0x1D7CB}, {0x1D7CE, 0x1D7FF}, - {0x1D800, 0x1D9FF}, {0x1DA00, 0x1DA36}, {0x1DA37, 0x1DA3A}, - {0x1DA3B, 0x1DA6C}, {0x1DA6D, 0x1DA74}, {0x1DA75, 0x1DA75}, - {0x1DA76, 0x1DA83}, {0x1DA84, 0x1DA84}, {0x1DA85, 0x1DA86}, - {0x1DA87, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, - {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, - {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E800, 0x1E8C4}, - {0x1E8C7, 0x1E8CF}, {0x1E8D0, 0x1E8D6}, {0x1E900, 0x1E943}, - {0x1E944, 0x1E94A}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, - {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, - {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, - {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, - {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, - {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, - {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, - {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, - {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, - {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, - {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, - {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, - {0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, - {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, - {0x1F0C1, 0x1F0CE}, {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10C}, - {0x1F12E, 0x1F12E}, {0x1F16A, 0x1F16B}, {0x1F1E6, 0x1F1FF}, - {0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, - {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF}, - {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F}, - {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A}, - {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594}, - {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F}, - {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6E0, 0x1F6EA}, - {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773}, {0x1F780, 0x1F7D4}, - {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, {0x1F850, 0x1F859}, - {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, {0xE0001, 0xE0001}, - {0xE0020, 0xE007F}, -} - -// Condition have flag EastAsianWidth whether the current locale is CJK or not. -type Condition struct { - EastAsianWidth bool -} - -// NewCondition return new instance of Condition which is current locale. -func NewCondition() *Condition { - return &Condition{EastAsianWidth} -} - -// RuneWidth returns the number of cells in r. -// See http://www.unicode.org/reports/tr11/ -func (c *Condition) RuneWidth(r rune) int { - switch { - case r < 0 || r > 0x10FFFF || - inTables(r, nonprint, combining, notassigned): - return 0 - case (c.EastAsianWidth && IsAmbiguousWidth(r)) || - inTables(r, doublewidth, emoji): - return 2 - default: - return 1 - } -} - -// StringWidth return width as you can see -func (c *Condition) StringWidth(s string) (width int) { - for _, r := range []rune(s) { - width += c.RuneWidth(r) - } - return width -} - -// Truncate return string truncated with w cells -func (c *Condition) Truncate(s string, w int, tail string) string { - if c.StringWidth(s) <= w { - return s - } - r := []rune(s) - tw := c.StringWidth(tail) - w -= tw - width := 0 - i := 0 - for ; i < len(r); i++ { - cw := c.RuneWidth(r[i]) - if width+cw > w { - break - } - width += cw - } - return string(r[0:i]) + tail -} - -// Wrap return string wrapped with w cells -func (c *Condition) Wrap(s string, w int) string { - width := 0 - out := "" - for _, r := range []rune(s) { - cw := RuneWidth(r) - if r == '\n' { - out += string(r) - width = 0 - continue - } else if width+cw > w { - out += "\n" - width = 0 - out += string(r) - width += cw - continue - } - out += string(r) - width += cw - } - return out -} - -// FillLeft return string filled in left by spaces in w cells -func (c *Condition) FillLeft(s string, w int) string { - width := c.StringWidth(s) - count := w - width - if count > 0 { - b := make([]byte, count) - for i := range b { - b[i] = ' ' - } - return string(b) + s - } - return s -} - -// FillRight return string filled in left by spaces in w cells -func (c *Condition) FillRight(s string, w int) string { - width := c.StringWidth(s) - count := w - width - if count > 0 { - b := make([]byte, count) - for i := range b { - b[i] = ' ' - } - return s + string(b) - } - return s -} - -// RuneWidth returns the number of cells in r. -// See http://www.unicode.org/reports/tr11/ -func RuneWidth(r rune) int { - return DefaultCondition.RuneWidth(r) -} - -// IsAmbiguousWidth returns whether is ambiguous width or not. -func IsAmbiguousWidth(r rune) bool { - return inTables(r, private, ambiguous) -} - -// IsNeutralWidth returns whether is neutral width or not. -func IsNeutralWidth(r rune) bool { - return inTable(r, neutral) -} - -// StringWidth return width as you can see -func StringWidth(s string) (width int) { - return DefaultCondition.StringWidth(s) -} - -// Truncate return string truncated with w cells -func Truncate(s string, w int, tail string) string { - return DefaultCondition.Truncate(s, w, tail) -} - -// Wrap return string wrapped with w cells -func Wrap(s string, w int) string { - return DefaultCondition.Wrap(s, w) -} - -// FillLeft return string filled in left by spaces in w cells -func FillLeft(s string, w int) string { - return DefaultCondition.FillLeft(s, w) -} - -// FillRight return string filled in left by spaces in w cells -func FillRight(s string, w int) string { - return DefaultCondition.FillRight(s, w) -} diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_js.go b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_js.go deleted file mode 100644 index 0ce32c5e7..000000000 --- a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_js.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build js - -package runewidth - -func IsEastAsian() bool { - // TODO: Implement this for the web. Detect east asian in a compatible way, and return true. - return false -} diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_posix.go b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_posix.go deleted file mode 100644 index c579e9a31..000000000 --- a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_posix.go +++ /dev/null @@ -1,77 +0,0 @@ -// +build !windows,!js - -package runewidth - -import ( - "os" - "regexp" - "strings" -) - -var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`) - -var mblenTable = map[string]int{ - "utf-8": 6, - "utf8": 6, - "jis": 8, - "eucjp": 3, - "euckr": 2, - "euccn": 2, - "sjis": 2, - "cp932": 2, - "cp51932": 2, - "cp936": 2, - "cp949": 2, - "cp950": 2, - "big5": 2, - "gbk": 2, - "gb2312": 2, -} - -func isEastAsian(locale string) bool { - charset := strings.ToLower(locale) - r := reLoc.FindStringSubmatch(locale) - if len(r) == 2 { - charset = strings.ToLower(r[1]) - } - - if strings.HasSuffix(charset, "@cjk_narrow") { - return false - } - - for pos, b := range []byte(charset) { - if b == '@' { - charset = charset[:pos] - break - } - } - max := 1 - if m, ok := mblenTable[charset]; ok { - max = m - } - if max > 1 && (charset[0] != 'u' || - strings.HasPrefix(locale, "ja") || - strings.HasPrefix(locale, "ko") || - strings.HasPrefix(locale, "zh")) { - return true - } - return false -} - -// IsEastAsian return true if the current locale is CJK -func IsEastAsian() bool { - locale := os.Getenv("LC_CTYPE") - if locale == "" { - locale = os.Getenv("LANG") - } - - // ignore C locale - if locale == "POSIX" || locale == "C" { - return false - } - if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') { - return false - } - - return isEastAsian(locale) -} diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_test.go b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_test.go deleted file mode 100644 index b0378a193..000000000 --- a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_test.go +++ /dev/null @@ -1,275 +0,0 @@ -package runewidth - -import ( - "sort" - "testing" -) - -var _ sort.Interface = (*table)(nil) - -func (t table) Len() int { - return len(t) -} - -func (t table) Less(i, j int) bool { - return t[i].first < t[j].first -} - -func (t *table) Swap(i, j int) { - (*t)[i], (*t)[j] = (*t)[j], (*t)[i] -} - -var tables = []table{ - private, - nonprint, - combining, - doublewidth, - ambiguous, - emoji, - notassigned, - neutral, -} - -func TestSorted(t *testing.T) { - for _, tbl := range tables { - if !sort.IsSorted(&tbl) { - t.Errorf("not sorted") - } - } -} - -var runewidthtests = []struct { - in rune - out int - eaout int -}{ - {'世', 2, 2}, - {'界', 2, 2}, - {'セ', 1, 1}, - {'カ', 1, 1}, - {'イ', 1, 1}, - {'☆', 1, 2}, // double width in ambiguous - {'\x00', 0, 0}, - {'\x01', 0, 0}, - {'\u0300', 0, 0}, -} - -func TestRuneWidth(t *testing.T) { - c := NewCondition() - for _, tt := range runewidthtests { - if out := c.RuneWidth(tt.in); out != tt.out { - t.Errorf("RuneWidth(%q) = %d, want %d", tt.in, out, tt.out) - } - } - c.EastAsianWidth = true - for _, tt := range runewidthtests { - if out := c.RuneWidth(tt.in); out != tt.eaout { - t.Errorf("RuneWidth(%q) = %d, want %d", tt.in, out, tt.eaout) - } - } -} - -var isambiguouswidthtests = []struct { - in rune - out bool -}{ - {'世', false}, - {'■', true}, - {'界', false}, - {'○', true}, - {'㈱', false}, - {'①', true}, - {'②', true}, - {'③', true}, - {'④', true}, - {'⑤', true}, - {'⑥', true}, - {'⑦', true}, - {'⑧', true}, - {'⑨', true}, - {'⑩', true}, - {'⑪', true}, - {'⑫', true}, - {'⑬', true}, - {'⑭', true}, - {'⑮', true}, - {'⑯', true}, - {'⑰', true}, - {'⑱', true}, - {'⑲', true}, - {'⑳', true}, - {'☆', true}, -} - -func TestIsAmbiguousWidth(t *testing.T) { - for _, tt := range isambiguouswidthtests { - if out := IsAmbiguousWidth(tt.in); out != tt.out { - t.Errorf("IsAmbiguousWidth(%q) = %v, want %v", tt.in, out, tt.out) - } - } -} - -var stringwidthtests = []struct { - in string - out int - eaout int -}{ - {"■㈱の世界①", 10, 12}, - {"スター☆", 7, 8}, - {"つのだ☆HIRO", 11, 12}, -} - -func TestStringWidth(t *testing.T) { - c := NewCondition() - for _, tt := range stringwidthtests { - if out := c.StringWidth(tt.in); out != tt.out { - t.Errorf("StringWidth(%q) = %q, want %q", tt.in, out, tt.out) - } - } - c.EastAsianWidth = true - for _, tt := range stringwidthtests { - if out := c.StringWidth(tt.in); out != tt.eaout { - t.Errorf("StringWidth(%q) = %q, want %q", tt.in, out, tt.eaout) - } - } -} - -func TestStringWidthInvalid(t *testing.T) { - s := "こんにちわ\x00世界" - if out := StringWidth(s); out != 14 { - t.Errorf("StringWidth(%q) = %q, want %q", s, out, 14) - } -} - -func TestTruncateSmaller(t *testing.T) { - s := "あいうえお" - expected := "あいうえお" - - if out := Truncate(s, 10, "..."); out != expected { - t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) - } -} - -func TestTruncate(t *testing.T) { - s := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお" - expected := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおお..." - out := Truncate(s, 80, "...") - if out != expected { - t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) - } - width := StringWidth(out) - if width != 79 { - t.Errorf("width of Truncate(%q) should be %d, but %d", s, 79, width) - } -} - -func TestTruncateFit(t *testing.T) { - s := "aあいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお" - expected := "aあいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおお..." - - out := Truncate(s, 80, "...") - if out != expected { - t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) - } - width := StringWidth(out) - if width != 80 { - t.Errorf("width of Truncate(%q) should be %d, but %d", s, 80, width) - } -} - -func TestTruncateJustFit(t *testing.T) { - s := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおお" - expected := "あいうえおあいうえおえおおおおおおおおおおおおおおおおおおおおおおおおおおおおお" - - out := Truncate(s, 80, "...") - if out != expected { - t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) - } - width := StringWidth(out) - if width != 80 { - t.Errorf("width of Truncate(%q) should be %d, but %d", s, 80, width) - } -} - -func TestWrap(t *testing.T) { - s := `東京特許許可局局長はよく柿喰う客だ/東京特許許可局局長はよく柿喰う客だ -123456789012345678901234567890 - -END` - expected := `東京特許許可局局長はよく柿喰う -客だ/東京特許許可局局長はよく -柿喰う客だ -123456789012345678901234567890 - -END` - - if out := Wrap(s, 30); out != expected { - t.Errorf("Wrap(%q) = %q, want %q", s, out, expected) - } -} - -func TestTruncateNoNeeded(t *testing.T) { - s := "あいうえおあい" - expected := "あいうえおあい" - - if out := Truncate(s, 80, "..."); out != expected { - t.Errorf("Truncate(%q) = %q, want %q", s, out, expected) - } -} - -var isneutralwidthtests = []struct { - in rune - out bool -}{ - {'→', false}, - {'┊', false}, - {'┈', false}, - {'~', false}, - {'└', false}, - {'⣀', true}, - {'⣀', true}, -} - -func TestIsNeutralWidth(t *testing.T) { - for _, tt := range isneutralwidthtests { - if out := IsNeutralWidth(tt.in); out != tt.out { - t.Errorf("IsNeutralWidth(%q) = %v, want %v", tt.in, out, tt.out) - } - } -} - -func TestFillLeft(t *testing.T) { - s := "あxいうえお" - expected := " あxいうえお" - - if out := FillLeft(s, 15); out != expected { - t.Errorf("FillLeft(%q) = %q, want %q", s, out, expected) - } -} - -func TestFillLeftFit(t *testing.T) { - s := "あいうえお" - expected := "あいうえお" - - if out := FillLeft(s, 10); out != expected { - t.Errorf("FillLeft(%q) = %q, want %q", s, out, expected) - } -} - -func TestFillRight(t *testing.T) { - s := "あxいうえお" - expected := "あxいうえお " - - if out := FillRight(s, 15); out != expected { - t.Errorf("FillRight(%q) = %q, want %q", s, out, expected) - } -} - -func TestFillRightFit(t *testing.T) { - s := "あいうえお" - expected := "あいうえお" - - if out := FillRight(s, 10); out != expected { - t.Errorf("FillRight(%q) = %q, want %q", s, out, expected) - } -} diff --git a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_windows.go b/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_windows.go deleted file mode 100644 index 0258876b9..000000000 --- a/vendor/gopkg.in/mattn/go-runewidth.v0/runewidth_windows.go +++ /dev/null @@ -1,25 +0,0 @@ -package runewidth - -import ( - "syscall" -) - -var ( - kernel32 = syscall.NewLazyDLL("kernel32") - procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP") -) - -// IsEastAsian return true if the current locale is CJK -func IsEastAsian() bool { - r1, _, _ := procGetConsoleOutputCP.Call() - if r1 == 0 { - return false - } - - switch int(r1) { - case 932, 51932, 936, 949, 950: - return true - } - - return false -} From 031c1981500ae10b67a2ca384bc030528cd51e75 Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 19 Jan 2018 09:34:06 +0900 Subject: [PATCH 06/45] Rename AddTxIndexesBatch->WriteBlockAddrTxIndexesBatch --- cmd/geth/build_atxi_cmd.go | 2 +- core/blockchain.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/geth/build_atxi_cmd.go b/cmd/geth/build_atxi_cmd.go index 2da139ff7..a8e5e3d86 100644 --- a/cmd/geth/build_atxi_cmd.go +++ b/cmd/geth/build_atxi_cmd.go @@ -64,7 +64,7 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { if i+inc > stopIndex { inc = stopIndex - startIndex } - if err := bc.AddTxIndexesBatch(indexDb, i, i+inc); err != nil { + if err := bc.WriteBlockAddrTxIndexesBatch(indexDb, i, i+inc); err != nil { return err } ioutil.WriteFile(placeholderFilename, []byte(strconv.Itoa(int(i+inc))), os.ModePerm) diff --git a/core/blockchain.go b/core/blockchain.go index e5061da65..b7951c742 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1291,7 +1291,7 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain return 0, nil } -func (self *BlockChain) AddTxIndexesBatch(indexDb ethdb.Database, startBlockN, stopBlockN uint64) (err error) { +func (self *BlockChain) WriteBlockAddrTxIndexesBatch(indexDb ethdb.Database, startBlockN, stopBlockN uint64) (err error) { block := self.GetBlockByNumber(startBlockN) putBatch := indexDb.NewBatch() startTime := time.Now() From 63f5c833833a9189aa63ec30a484fe020cc64916 Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 19 Jan 2018 10:44:15 +0900 Subject: [PATCH 07/45] write atxis for bc insertreceipts and reorg makes compatible with --fast --- core/blockchain.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/core/blockchain.go b/core/blockchain.go index b7951c742..4f2886065 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1246,6 +1246,12 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain glog.Fatal(errs[index]) return } + // Store the addr-tx indexes if enabled + if self.useAddTxIndex { + if err := WriteBlockAddTxIndexes(self.indexesDb, block); err != nil { + glog.Fatalf("failed to write block add-tx indexes", err) + } + } atomic.AddInt32(&stats.processed, 1) } } @@ -1614,7 +1620,7 @@ func (self *BlockChain) InsertChain(chain types.Blocks) (chainIndex int, err err if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil { return i, err } - // Store the add-tx indexes + // Store the addr-tx indexes if enabled if self.useAddTxIndex { if err := WriteBlockAddTxIndexes(self.indexesDb, block); err != nil { glog.Fatalf("failed to write block add-tx indexes", err) @@ -1770,6 +1776,12 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil { return err } + // Store the addr-tx indexes if enabled + if self.useAddTxIndex { + if err := WriteBlockAddTxIndexes(self.indexesDb, block); err != nil { + glog.Fatalf("failed to write block add-tx indexes", err) + } + } addedTxs = append(addedTxs, block.Transactions()...) } @@ -1779,6 +1791,11 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { // receipts that were created in the fork must also be deleted for _, tx := range diff { DeleteReceipt(self.chainDb, tx.Hash()) + if self.useAddTxIndex { + if err := RmAddrTx(self.indexesDb, tx); err != nil { + return err + } + } DeleteTransaction(self.chainDb, tx.Hash()) } // Must be posted in a goroutine because of the transaction pool trying From 4b45f4281642d72208d651be1b02940ecc1bf9ee Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 19 Jan 2018 10:44:50 +0900 Subject: [PATCH 08/45] remove atxis given bc rollback or reorg --- core/blockchain.go | 27 ++++++++++++++++++++ core/database_util.go | 57 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/core/blockchain.go b/core/blockchain.go index 4f2886065..1050a2ab5 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -788,6 +788,33 @@ func (bc *BlockChain) SetHead(head uint64) error { glog.Fatalf("failed to reset head fast block hash: %v", err) } + if bc.useAddTxIndex { + ldb, ok := bc.indexesDb.(*ethdb.LDBDatabase) + if !ok { + glog.Fatal("could not cast indexes db to level db") + } + pre := ethdb.NewBytesPrefix(txAddressIndexPrefix) + it := ldb.NewIteratorRange(pre) + removals := [][]byte{} + for it.Next() { + key := it.Key() + _, bn, _, _ := resolveAddrTxBytes(key) + n := binary.LittleEndian.Uint64(bn) + if n > head { + removals = append(removals, key) + } + } + it.Release() + if e := it.Error(); e != nil { + return e + } + for _, r := range removals { + if e := ldb.Delete(r); e != nil { + glog.Fatal(e) + } + } + } + bc.mu.Unlock() return bc.LoadLastState(false) } diff --git a/core/database_util.go b/core/database_util.go index 4f3166e60..3a96ccd4b 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -247,6 +247,63 @@ func PutAddrTxs(db ethdb.Database, block *types.Block, isTo bool, address common return nil } +func RmAddrTx(db ethdb.Database, tx *types.Transaction) error { + ldb, ok := db.(*ethdb.LDBDatabase) + if !ok { + return nil + } + + txH := tx.Hash() + from, err := tx.From() + if err != nil { + return err + } + + removals := [][]byte{} + + // TODO: not DRY, could be refactored + pre := ethdb.NewBytesPrefix(formatAddrTxIterator(from)) + it := ldb.NewIteratorRange(pre) + for it.Next() { + key := it.Key() + _, _, _, txh := resolveAddrTxBytes(key) + if bytes.Compare(txH.Bytes(), txh) == 0 { + removals = append(removals, txh) + break // because there can be only one + } + } + it.Release() + if e := it.Error(); e != nil { + return e + } + + to := tx.To() + if to != nil { + toRef := *to + pre := ethdb.NewBytesPrefix(formatAddrTxIterator(toRef)) + it := ldb.NewIteratorRange(pre) + for it.Next() { + key := it.Key() + _, _, _, txh := resolveAddrTxBytes(key) + if bytes.Compare(txH.Bytes(), txh) == 0 { + removals = append(removals, txh) + break // because there can be only one + } + } + it.Release() + if e := it.Error(); e != nil { + return e + } + } + + for _, r := range removals { + if err := db.Delete(r); err != nil { + return err + } + } + return nil +} + // GetTd retrieves a block's total difficulty corresponding to the hash, nil if // none found. func GetTd(db ethdb.Database, hash common.Hash) *big.Int { From e09bd1a56116e470c5c97a6ede11074ce352cd5e Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 19 Jan 2018 11:01:33 +0900 Subject: [PATCH 09/45] improvements based on @tzdybal feedback - use step param for batch atxi fn - use blockprocessed counter for batch atxi fn instead of block number - use glog.Fatal instead of panic --- cmd/geth/build_atxi_cmd.go | 10 +++++++--- core/blockchain.go | 11 +++++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/cmd/geth/build_atxi_cmd.go b/cmd/geth/build_atxi_cmd.go index a8e5e3d86..8edb0b397 100644 --- a/cmd/geth/build_atxi_cmd.go +++ b/cmd/geth/build_atxi_cmd.go @@ -27,7 +27,7 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { bc, chainDB := MakeChain(ctx) if bc == nil || chainDB == nil { - panic("bc or cdb is nil") + glog.Fatal("bc or cdb is nil") } defer chainDB.Close() @@ -46,7 +46,7 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { indexDb := MakeIndexDatabase(ctx) if indexDb == nil { - panic("indexdb is nil") + glog.Fatal("indexes db is nil") } defer indexDb.Close() @@ -64,7 +64,11 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { if i+inc > stopIndex { inc = stopIndex - startIndex } - if err := bc.WriteBlockAddrTxIndexesBatch(indexDb, i, i+inc); err != nil { + // It may seem weird to pass i, i+inc, and inc, but its just a "coincidence" + // The function could accepts a smaller step for batch putting (in this case, inc), + // or a larger stopBlock (i+inc), but this is just how this cmd is using the fn now + // We could mess around a little with exploring batch optimization... + if err := bc.WriteBlockAddrTxIndexesBatch(indexDb, i, i+inc, inc); err != nil { return err } ioutil.WriteFile(placeholderFilename, []byte(strconv.Itoa(int(i+inc))), os.ModePerm) diff --git a/core/blockchain.go b/core/blockchain.go index 1050a2ab5..77e1aafdf 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1324,12 +1324,16 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain return 0, nil } -func (self *BlockChain) WriteBlockAddrTxIndexesBatch(indexDb ethdb.Database, startBlockN, stopBlockN uint64) (err error) { +func (self *BlockChain) WriteBlockAddrTxIndexesBatch(indexDb ethdb.Database, startBlockN, stopBlockN, stepN uint64) (err error) { block := self.GetBlockByNumber(startBlockN) putBatch := indexDb.NewBatch() + startTime := time.Now() lastTime := time.Now() + + blockProcessedCount := uint64(0) txsCount := 0 + for block != nil && block.NumberU64() <= stopBlockN { for _, tx := range block.Transactions() { txsCount++ @@ -1355,7 +1359,8 @@ func (self *BlockChain) WriteBlockAddrTxIndexesBatch(indexDb ethdb.Database, sta return err } } - if block.NumberU64()%10000 == 0 { + blockProcessedCount++ + if blockProcessedCount%stepN == 0 { if err := putBatch.Write(); err != nil { return err } else { @@ -1373,6 +1378,8 @@ func (self *BlockChain) WriteBlockAddrTxIndexesBatch(indexDb ethdb.Database, sta float64(txsCount)/time.Since(lastTime).Seconds(), "txps") glog.V(logger.Debug).Infoln("Batch atxi... block", startBlockN, "/", stopBlockN, "txs:", txsCount, "took:", time.Since(startTime), float64(stopBlockN-startBlockN)/time.Since(lastTime).Seconds(), "bps") lastTime = time.Now() + + // This will put the last batch return putBatch.Write() } From 0fd5868be9494a37385552645cc96fd37b211b92 Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 19 Jan 2018 11:04:15 +0900 Subject: [PATCH 10/45] rename toOrFromOrBoth -> direction --- core/database_util.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/database_util.go b/core/database_util.go index 3a96ccd4b..db3625152 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -148,8 +148,8 @@ func formatAddrTxIterator(address common.Address) (iteratorPrefix []byte) { } // GetAddrTxs gets the indexed transactions for a given account address. -func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, blockEndN uint64, toFromOrBoth string) []string { - if toFromOrBoth != "to" && toFromOrBoth != "from" && toFromOrBoth != "both" && toFromOrBoth != "" { +func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, blockEndN uint64, direction string) []string { + if direction != "to" && direction != "from" && direction != "both" && direction != "" { glog.Fatal("Address transactions list signature requires 'to', 'from', or 'both' or '' (=both)") } @@ -187,11 +187,11 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b continue } } - if toFromOrBoth == "to" { + if direction == "to" { if string(torf) != "t" { continue } - } else if toFromOrBoth == "from" { + } else if direction == "from" { if string(torf) != "f" { continue } From ec6f4e6187ac694a36ca40528528e936c5e7746d Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 19 Jan 2018 11:06:52 +0900 Subject: [PATCH 11/45] compare uint64s blockstart/stopNs instead of converting to bigints --- core/database_util.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/core/database_util.go b/core/database_util.go index db3625152..bdefa6d84 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -166,24 +166,19 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b // This will be the returnable. var hashes []string - // Convert start/stop block number to *big for easier comparison. - wantStart := new(big.Int).SetUint64(blockStartN) - wantEnd := new(big.Int).SetUint64(blockEndN) - for it.Next() { key := it.Key() _, blockNum, torf, txh := resolveAddrTxBytes(key) + // If atxi is smaller than blockstart, skip if blockStartN > 0 { - txaI := new(big.Int).SetUint64(binary.LittleEndian.Uint64(blockNum)) - if txaI.Cmp(wantStart) < 0 { + if binary.LittleEndian.Uint64(blockNum) < blockStartN { continue } } if blockEndN > 0 { - txaI := new(big.Int).SetUint64(binary.LittleEndian.Uint64(blockNum)) - if txaI.Cmp(wantEnd) > 0 { + if binary.LittleEndian.Uint64(blockNum) > blockEndN { continue } } From 674da81b888ac88935a258ee8723d37d7dd65b33 Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 19 Jan 2018 11:21:12 +0900 Subject: [PATCH 12/45] simplify t/f direction check for iterator --- core/database_util.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/core/database_util.go b/core/database_util.go index bdefa6d84..e48f44362 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -166,6 +166,12 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b // This will be the returnable. var hashes []string + // Map direction -> byte + var wantDirectionB byte = 'b' + if len(direction) > 0 { + wantDirectionB = direction[0] + } + for it.Next() { key := it.Key() @@ -177,19 +183,15 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b continue } } + // If atxi is greater than blockend, skip if blockEndN > 0 { if binary.LittleEndian.Uint64(blockNum) > blockEndN { continue } } - if direction == "to" { - if string(torf) != "t" { - continue - } - } else if direction == "from" { - if string(torf) != "f" { - continue - } + // Ensure matching direction if spec'd + if wantDirectionB != 'b' && wantDirectionB != torf[0] { + continue } tx := common.ToHex(txh) hashes = append(hashes, tx) From cd429f79d58b92f618d950cbfa145f33646a8948 Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 19 Jan 2018 11:22:50 +0900 Subject: [PATCH 13/45] rename more toOrFrom -> direction --- core/database_util.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/database_util.go b/core/database_util.go index e48f44362..8b3f2b0fa 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -207,21 +207,21 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b // FormatAddrTxBytesIndex formats the index key, eg. atx- // The values for these arguments should be of determinate length and format, see test TestFormatAndResolveAddrTxBytesKey // for example. -func FormatAddrTxBytesIndex(address, blockNumber, toOrFrom, txhash []byte) (key []byte) { +func FormatAddrTxBytesIndex(address, blockNumber, direction, txhash []byte) (key []byte) { key = txAddressIndexPrefix key = append(key, address...) key = append(key, blockNumber...) - key = append(key, toOrFrom...) + key = append(key, direction...) key = append(key, txhash...) return } // resolveAddrTxBytes resolves the index key to individual []byte values -func resolveAddrTxBytes(key []byte) (address, blockNumber, toOrFrom, txhash []byte) { +func resolveAddrTxBytes(key []byte) (address, blockNumber, direction, txhash []byte) { // prefix = key[:4] address = key[4:24] // common.AddressLength = 20 blockNumber = key[24:32] - toOrFrom = key[32:33] // == key[32] (1 byte) + direction = key[32:33] // == key[32] (1 byte) txhash = key[33:] return } From 0c746d3a133c54a49a263033ed5294426fb67d9e Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 19 Jan 2018 12:15:27 +0900 Subject: [PATCH 14/45] refactor putBlockAddrTxsToBatch and atxi-build cmd --- cmd/geth/build_atxi_cmd.go | 51 +++++++++++++++++---- core/blockchain.go | 93 ++++++++++++++++---------------------- 2 files changed, 82 insertions(+), 62 deletions(-) diff --git a/cmd/geth/build_atxi_cmd.go b/cmd/geth/build_atxi_cmd.go index 8edb0b397..7966653a7 100644 --- a/cmd/geth/build_atxi_cmd.go +++ b/cmd/geth/build_atxi_cmd.go @@ -27,7 +27,7 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { bc, chainDB := MakeChain(ctx) if bc == nil || chainDB == nil { - glog.Fatal("bc or cdb is nil") + glog.Fatalln("bc or cdb is nil") } defer chainDB.Close() @@ -37,7 +37,7 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { } if stopIndex < startIndex { - glog.Fatal("start must be prior to (smaller than) or equal to stop, got start=", startIndex, "stop=", stopIndex) + glog.Fatalln("start must be prior to (smaller than) or equal to stop, got start=", startIndex, "stop=", stopIndex) } if startIndex == stopIndex { glog.D(logger.Error).Infoln("Up to date. Exiting.") @@ -46,7 +46,7 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { indexDb := MakeIndexDatabase(ctx) if indexDb == nil { - glog.Fatal("indexes db is nil") + glog.Fatalln("indexes db is nil") } defer indexDb.Close() @@ -54,27 +54,62 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { blockIndex := startIndex block = bc.GetBlockByNumber(blockIndex) if block == nil { - glog.Fatal(blockIndex, "block is nil") + glog.Fatalln(blockIndex, "block is nil") } var inc = uint64(ctx.Int("step")) startTime := time.Now() - glog.D(logger.Error).Infoln("Address/tx indexing (atxi) start:", startIndex, "stop:", stopIndex, "step:", inc) + totalTxCount := uint64(0) + glog.D(logger.Error).Infoln("Address/tx indexing (atxi) start:", startIndex, "stop:", stopIndex, "step:", inc, "| This may take a while.") + breaker := false for i := startIndex; i <= stopIndex; i = i+inc { if i+inc > stopIndex { - inc = stopIndex - startIndex + inc = stopIndex - i + breaker = true } + + stepStartTime := time.Now() + // It may seem weird to pass i, i+inc, and inc, but its just a "coincidence" // The function could accepts a smaller step for batch putting (in this case, inc), // or a larger stopBlock (i+inc), but this is just how this cmd is using the fn now // We could mess around a little with exploring batch optimization... - if err := bc.WriteBlockAddrTxIndexesBatch(indexDb, i, i+inc, inc); err != nil { + txsCount, err := bc.WriteBlockAddrTxIndexesBatch(indexDb, i, i+inc, inc) + if err != nil { return err } + totalTxCount += uint64(txsCount) + + // TODO: use dedicated placeholder in indexes db instead ioutil.WriteFile(placeholderFilename, []byte(strconv.Itoa(int(i+inc))), os.ModePerm) + + glog.D(logger.Error).Infoln("atxi-build... block", + i+inc, "/", stopIndex, + "txs:", txsCount, + "took:", time.Since(stepStartTime), + float64(inc)/time.Since(stepStartTime).Seconds(), "bps", + float64(txsCount)/time.Since(stepStartTime).Seconds(), "txps") + glog.V(logger.Info).Infoln("Batch atxi... block", i, "/", stopIndex, "txs:", txsCount, "took:", time.Since(stepStartTime), float64(inc)/time.Since(stepStartTime).Seconds(), "bps") + if breaker { + break + } } + ioutil.WriteFile(placeholderFilename, []byte(strconv.Itoa(int(stopIndex))), os.ModePerm) - glog.D(logger.Error).Infoln("Finished atxi. Took:", time.Since(startTime)) + totalBlocksF := float64(stopIndex - startIndex) + totalTxsF := float64(totalTxCount) + took := time.Since(startTime) + glog.D(logger.Error).Infof(`Finished atxi. Took: %v + %d blocks + ~ %.2f blocks/sec + %d txs + ~ %.2f txs/sec`, + took.Round(time.Second), + stopIndex - startIndex, + totalBlocksF/took.Seconds(), + totalTxCount, + totalTxsF/took.Seconds(), + ) return nil } diff --git a/core/blockchain.go b/core/blockchain.go index 77e1aafdf..360f3c87c 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1324,87 +1324,72 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain return 0, nil } -func (self *BlockChain) WriteBlockAddrTxIndexesBatch(indexDb ethdb.Database, startBlockN, stopBlockN, stepN uint64) (err error) { +func (self *BlockChain) WriteBlockAddrTxIndexesBatch(indexDb ethdb.Database, startBlockN, stopBlockN, stepN uint64) (txsCount int, err error) { block := self.GetBlockByNumber(startBlockN) - putBatch := indexDb.NewBatch() - - startTime := time.Now() - lastTime := time.Now() + batch := indexDb.NewBatch() blockProcessedCount := uint64(0) - txsCount := 0 - - for block != nil && block.NumberU64() <= stopBlockN { - for _, tx := range block.Transactions() { - txsCount++ - - from, err := tx.From() - if err != nil { - return err - } - bn := make([]byte, 8) - binary.LittleEndian.PutUint64(bn, block.NumberU64()) - - if err := putBatch.Put(FormatAddrTxBytesIndex(from.Bytes(), bn, []byte("f"), tx.Hash().Bytes()), nil); err != nil { - return err - } + blockProcessedHead := func() uint64 { + return startBlockN + blockProcessedCount + } - to := tx.To() - if to == nil { - continue - } - var tob []byte - copy(tob, to.Bytes()) - if err := putBatch.Put(FormatAddrTxBytesIndex(tob, bn, []byte("t"), tx.Hash().Bytes()), nil); err != nil { - return err - } + for block != nil && blockProcessedHead() <= stopBlockN { + txP, err := putBlockAddrTxsToBatch(batch, block) + if err != nil { + return txsCount, err } + txsCount += txP blockProcessedCount++ + + // Write on stepN mod if blockProcessedCount%stepN == 0 { - if err := putBatch.Write(); err != nil { - return err + if err := batch.Write(); err != nil { + return txsCount, err } else { - putBatch = indexDb.NewBatch() + batch = indexDb.NewBatch() } } - block = self.GetBlockByNumber(block.NumberU64() + 1) + block = self.GetBlockByNumber(blockProcessedHead()) } - // TODO: remove me D... i'm just a debugger - glog.D(logger.Error).Infoln("Batch atxi... block", - startBlockN, "/", stopBlockN, - "txs:", txsCount, - "took:", time.Since(startTime), - float64(stopBlockN-startBlockN)/time.Since(lastTime).Seconds(), "bps", - float64(txsCount)/time.Since(lastTime).Seconds(), "txps") - glog.V(logger.Debug).Infoln("Batch atxi... block", startBlockN, "/", stopBlockN, "txs:", txsCount, "took:", time.Since(startTime), float64(stopBlockN-startBlockN)/time.Since(lastTime).Seconds(), "bps") - lastTime = time.Now() // This will put the last batch - return putBatch.Write() + return txsCount, batch.Write() } -func WriteBlockAddTxIndexes(indexDb ethdb.Database, block *types.Block) error { +func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount int, err error) { for _, tx := range block.Transactions() { - var err error + txsCount++ + from, err := tx.From() if err != nil { - return err + return txsCount, err } - err = PutAddrTxs(indexDb, block, false, from, tx.Hash()) - if err != nil { - return err + bn := make([]byte, 8) + binary.LittleEndian.PutUint64(bn, block.NumberU64()) + + if err := putBatch.Put(FormatAddrTxBytesIndex(from.Bytes(), bn, []byte("f"), tx.Hash().Bytes()), nil); err != nil { + return txsCount, err } to := tx.To() if to == nil { continue } - err = PutAddrTxs(indexDb, block, true, *to, tx.Hash()) - if err != nil { - return err + var tob []byte + copy(tob, to.Bytes()) + if err := putBatch.Put(FormatAddrTxBytesIndex(tob, bn, []byte("t"), tx.Hash().Bytes()), nil); err != nil { + return txsCount, err } } - return nil + return txsCount, nil +} + +func WriteBlockAddTxIndexes(indexDb ethdb.Database, block *types.Block) error { + batch := indexDb.NewBatch() + if _, err := putBlockAddrTxsToBatch(batch, block); err != nil { + return err + } + return batch.Write() } // WriteBlock writes the block to the chain. From 0c38d84fd6375790fb8261bf5686f586b849cf2f Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 19 Jan 2018 12:28:11 +0900 Subject: [PATCH 15/45] Add comments and remove unused fn --- core/blockchain.go | 8 ++++++++ core/database_util.go | 22 ++++------------------ 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 360f3c87c..9aaca6ab7 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1324,6 +1324,10 @@ func (self *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain return 0, nil } +// WriteBlockAddrTxIndexesBatch builds indexes for a given range of blocks N. It writes batches at increment 'step'. +// If any error occurs during db writing it will be returned immediately. +// It's sole implementation is the command 'atxi-build', since we must use individual block atxi indexing during +// sync and import in order to ensure we're on the canonical chain for each block. func (self *BlockChain) WriteBlockAddrTxIndexesBatch(indexDb ethdb.Database, startBlockN, stopBlockN, stepN uint64) (txsCount int, err error) { block := self.GetBlockByNumber(startBlockN) batch := indexDb.NewBatch() @@ -1356,6 +1360,8 @@ func (self *BlockChain) WriteBlockAddrTxIndexesBatch(indexDb ethdb.Database, sta return txsCount, batch.Write() } +// putBlockAddrTxsToBatch formats and puts keys for a given block to a db Batch. +// Batch can be written afterward if no errors, ie. batch.Write() func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount int, err error) { for _, tx := range block.Transactions() { txsCount++ @@ -1364,6 +1370,7 @@ func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount if err != nil { return txsCount, err } + // Note that len 8 because uint64 guaranteed <= 8 bytes. bn := make([]byte, 8) binary.LittleEndian.PutUint64(bn, block.NumberU64()) @@ -1384,6 +1391,7 @@ func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount return txsCount, nil } +// WriteBlockAddTxIndexes writes atx-indexes for a given block. func WriteBlockAddTxIndexes(indexDb ethdb.Database, block *types.Block) error { batch := indexDb.NewBatch() if _, err := putBlockAddrTxsToBatch(batch, block); err != nil { diff --git a/core/database_util.go b/core/database_util.go index 8b3f2b0fa..445f0ac2e 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -226,24 +226,10 @@ func resolveAddrTxBytes(key []byte) (address, blockNumber, direction, txhash []b return } -// PutAddrTxs adds an address/tx index to the indexes db. -// if isTo is false, then the address is the sender in the tx (from), t/f -func PutAddrTxs(db ethdb.Database, block *types.Block, isTo bool, address common.Address, txhash common.Hash) error { - var tOrF = []byte("f") - if isTo { - tOrF = []byte("t") - } - - bk := make([]byte, 8) - binary.LittleEndian.PutUint64(bk, block.NumberU64()) - k := FormatAddrTxBytesIndex(address.Bytes(), bk, tOrF, txhash.Bytes()) - - if err := db.Put(k, nil); err != nil { - glog.Fatalf("failed to store addrtxidx into database: %v", err) - } - return nil -} - +// RmAddrTx removes all atxi indexes for a given tx in case of a transaction removal, eg. +// in the case of chain reorg. +// It isn't an elegant function, but not a top priority for optimization because of +// expected infrequency of it's being called. func RmAddrTx(db ethdb.Database, tx *types.Transaction) error { ldb, ok := db.(*ethdb.LDBDatabase) if !ok { From 67769f6b870faa5881d4aa571a6bb750b0e3d8c5 Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 19 Jan 2018 13:06:17 +0900 Subject: [PATCH 16/45] a few minor tweaks and improvements, comments, etc --- cmd/geth/flags.go | 4 ++-- cmd/geth/main.go | 4 ++-- cmd/geth/usage.go | 1 + core/blockchain.go | 24 ++++++++++++++++++------ core/database_util.go | 2 +- core/database_util_test.go | 6 +++--- eth/backend.go | 2 -- 7 files changed, 27 insertions(+), 16 deletions(-) diff --git a/cmd/geth/flags.go b/cmd/geth/flags.go index 65acfc2ef..3fee76948 100644 --- a/cmd/geth/flags.go +++ b/cmd/geth/flags.go @@ -90,8 +90,8 @@ var ( Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", } AddrTxIndexFlag = cli.BoolFlag{ - Name: "add-tx-index,atxi", - Usage: "Toggle indexes for transactions by address. Pre-existing chaindata can be indexed with command 'geth atxi-build'", + Name: "atxi,add-tx-index", + Usage: "Toggle indexes for transactions by address. Pre-existing chaindata can be indexed with command 'atxi-build'", } // Network Split settings ETFChain = cli.BoolFlag{ diff --git a/cmd/geth/main.go b/cmd/geth/main.go index f6d5f0329..bc63582fa 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -108,7 +108,7 @@ func makeCLIApp() (app *cli.App) { The command is idempotent; it will not hurt to run multiple times on the same range. If run without --start flag, the command makes use of a persistent placeholder, so you can - run 'geth build-atxi' on multiple occasions and pick up indexing progress where the last session + run the command on multiple occasions and pick up indexing progress where the last session left off. To enable address-transaction indexing during block sync and import, use the '--atxi' flag. @@ -124,7 +124,7 @@ func makeCLIApp() (app *cli.App) { }, cli.IntFlag{ Name: "step", - Usage: "Step increment for batching. Higher number requires more mem, but may be faster. [default: 10000]", + Usage: "Step increment for batching. Higher number requires more mem, but may be faster", Value: 10000, }, }, diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 9532a4808..77474db0f 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -163,6 +163,7 @@ var AppHelpFlagGroups = []flagGroup{ DisplayFlag, DisplayFormatFlag, NeckbeardFlag, + AddrTxIndexFlag, }, }, { diff --git a/core/blockchain.go b/core/blockchain.go index 9aaca6ab7..f45b15d78 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -793,26 +793,38 @@ func (bc *BlockChain) SetHead(head uint64) error { if !ok { glog.Fatal("could not cast indexes db to level db") } + + removals := [][]byte{} + removeRemovals := func(removals [][]byte) { + for _, r := range removals { + if e := ldb.Delete(r); e != nil { + glog.Fatal(e) + } + } + } + pre := ethdb.NewBytesPrefix(txAddressIndexPrefix) it := ldb.NewIteratorRange(pre) - removals := [][]byte{} + for it.Next() { key := it.Key() _, bn, _, _ := resolveAddrTxBytes(key) n := binary.LittleEndian.Uint64(bn) if n > head { removals = append(removals, key) + // Prevent removals from getting too massive in case it's a big rollback + // 100000 is a guess at a big but not-too-big memory allowance + if len(removals) > 100000 { + removeRemovals(removals) + removals = [][]byte{} + } } } it.Release() if e := it.Error(); e != nil { return e } - for _, r := range removals { - if e := ldb.Delete(r); e != nil { - glog.Fatal(e) - } - } + removeRemovals(removals) } bc.mu.Unlock() diff --git a/core/database_util.go b/core/database_util.go index 445f0ac2e..c3632df23 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -198,7 +198,7 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b } it.Release() if it.Error() != nil { - panic(it.Error()) + glog.Fatalln(it.Error()) } return hashes diff --git a/core/database_util_test.go b/core/database_util_test.go index 9263f9233..3dc9d39fc 100644 --- a/core/database_util_test.go +++ b/core/database_util_test.go @@ -301,12 +301,12 @@ func TestTdStorage(t *testing.T) { func TestFormatAndResolveAddrTxBytesKey(t *testing.T) { testAddr := common.Address{} - testBN := big.NewInt(42) + testBN := uint64(42) testTorf := "f" testTxH := common.Hash{} testBNBytes := make([]byte, 8) - binary.LittleEndian.PutUint64(testBNBytes, testBN.Uint64()) + binary.LittleEndian.PutUint64(testBNBytes, testBN) key := FormatAddrTxBytesIndex(testAddr.Bytes(), testBNBytes, []byte(testTorf), testTxH.Bytes()) @@ -322,7 +322,7 @@ func TestFormatAndResolveAddrTxBytesKey(t *testing.T) { if gotAddr := common.BytesToAddress(outAddr); gotAddr != testAddr { t.Errorf("got: %v, want: %v", gotAddr.Hex(), testAddr.Hex()) } - if gotBN := new(big.Int).SetUint64(binary.LittleEndian.Uint64(outBNBytes)); gotBN.Cmp(testBN) != 0 { + if gotBN := binary.LittleEndian.Uint64(outBNBytes); gotBN != testBN { t.Errorf("got: %v, want: %v", gotBN, testBN) } if gotTorf := string(outTorf); gotTorf != testTorf { diff --git a/eth/backend.go b/eth/backend.go index 58e2d7742..d82402f40 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -232,8 +232,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { return nil, err } eth.indexesDb = indexesDb - glog.V(logger.Info).Infof("Opened add-tx index db") - glog.D(logger.Warn).Infof("Opened add-tx index db") } // load the genesis block or write a new one if no genesis From 4fc155f218dd9d34ff2a50b9188609afc4a05e6f Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 19 Jan 2018 13:35:02 +0900 Subject: [PATCH 17/45] move atxi placeholder to db k/v, polish cmd ui --- cmd/geth/build_atxi_cmd.go | 56 +++++++++++++++++--------------------- core/database_util.go | 20 ++++++++++++++ 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/cmd/geth/build_atxi_cmd.go b/cmd/geth/build_atxi_cmd.go index 7966653a7..06d4bc770 100644 --- a/cmd/geth/build_atxi_cmd.go +++ b/cmd/geth/build_atxi_cmd.go @@ -2,27 +2,27 @@ package main import ( "gopkg.in/urfave/cli.v1" - "strconv" "github.com/ethereumproject/go-ethereum/logger/glog" "github.com/ethereumproject/go-ethereum/core/types" - "path/filepath" - "io/ioutil" "os" "github.com/ethereumproject/go-ethereum/logger" "time" + "github.com/ethereumproject/go-ethereum/core" ) func buildAddrTxIndexCmd(ctx *cli.Context) error { startIndex := uint64(ctx.Int("start")) var stopIndex uint64 + indexDb := MakeIndexDatabase(ctx) + if indexDb == nil { + glog.Fatalln("indexes db is nil") + } + defer indexDb.Close() + // Use persistent placeholder in case start not spec'd - placeholderFilename := filepath.Join(MustMakeChainDataDir(ctx), "index.at") if !ctx.IsSet("start") { - bs, err := ioutil.ReadFile(placeholderFilename) - if err == nil { // ignore errors for now - startIndex, _ = strconv.ParseUint(string(bs), 10, 64) - } + startIndex = core.GetATXIBookmark(indexDb) } bc, chainDB := MakeChain(ctx) @@ -33,23 +33,20 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { stopIndex = uint64(ctx.Int("stop")) if stopIndex == 0 { - stopIndex = bc.CurrentHeader().Number.Uint64() + stopIndex = bc.CurrentBlock().NumberU64() + if n := bc.CurrentFastBlock().NumberU64(); n > stopIndex { + stopIndex = n + } } if stopIndex < startIndex { glog.Fatalln("start must be prior to (smaller than) or equal to stop, got start=", startIndex, "stop=", stopIndex) } if startIndex == stopIndex { - glog.D(logger.Error).Infoln("Up to date. Exiting.") + glog.D(logger.Error).Infoln("atxi is up to date, exiting") os.Exit(0) } - indexDb := MakeIndexDatabase(ctx) - if indexDb == nil { - glog.Fatalln("indexes db is nil") - } - defer indexDb.Close() - var block *types.Block blockIndex := startIndex block = bc.GetBlockByNumber(blockIndex) @@ -80,30 +77,27 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { } totalTxCount += uint64(txsCount) - // TODO: use dedicated placeholder in indexes db instead - ioutil.WriteFile(placeholderFilename, []byte(strconv.Itoa(int(i+inc))), os.ModePerm) + if err := core.SetATXIBookmark(indexDb, i+inc); err != nil { + glog.Fatalln(err) + } + + glog.D(logger.Error).Infof("atxi-build: block %d / %d txs: %d took: %v %.2f bps %.2f txps", i+inc, stopIndex, txsCount, time.Since(stepStartTime).Round(time.Millisecond), float64(inc)/time.Since(stepStartTime).Seconds(), float64(txsCount)/time.Since(stepStartTime).Seconds()) + glog.V(logger.Info).Infof("atxi-build: block %d / %d txs: %d took: %v %.2f bps %.2f txps", i+inc, stopIndex, txsCount, time.Since(stepStartTime).Round(time.Millisecond), float64(inc)/time.Since(stepStartTime).Seconds(), float64(txsCount)/time.Since(stepStartTime).Seconds()) - glog.D(logger.Error).Infoln("atxi-build... block", - i+inc, "/", stopIndex, - "txs:", txsCount, - "took:", time.Since(stepStartTime), - float64(inc)/time.Since(stepStartTime).Seconds(), "bps", - float64(txsCount)/time.Since(stepStartTime).Seconds(), "txps") - glog.V(logger.Info).Infoln("Batch atxi... block", i, "/", stopIndex, "txs:", txsCount, "took:", time.Since(stepStartTime), float64(inc)/time.Since(stepStartTime).Seconds(), "bps") if breaker { break } } - ioutil.WriteFile(placeholderFilename, []byte(strconv.Itoa(int(stopIndex))), os.ModePerm) + if err := core.SetATXIBookmark(indexDb, stopIndex); err != nil { + glog.Fatalln(err) + } + + // Print summary totalBlocksF := float64(stopIndex - startIndex) totalTxsF := float64(totalTxCount) took := time.Since(startTime) - glog.D(logger.Error).Infof(`Finished atxi. Took: %v - %d blocks - ~ %.2f blocks/sec - %d txs - ~ %.2f txs/sec`, + glog.D(logger.Error).Infof(`Finished atxi-build in %v: %d blocks (~ %.2f blocks/sec), %d txs (~ %.2f txs/sec)`, took.Round(time.Second), stopIndex - startIndex, totalBlocksF/took.Seconds(), diff --git a/core/database_util.go b/core/database_util.go index c3632df23..4845972ce 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -28,6 +28,7 @@ import ( "github.com/ethereumproject/go-ethereum/logger" "github.com/ethereumproject/go-ethereum/logger/glog" "github.com/ethereumproject/go-ethereum/rlp" + "strconv" ) var ( @@ -47,6 +48,7 @@ var ( blockReceiptsPrefix = []byte("receipts-block-") txAddressIndexPrefix = []byte("atx-") + txAddressBookmarkKey = []byte("ATXIBookmark") mipmapPre = []byte("mipmap-log-bloom-") MIPMapLevels = []uint64{1000000, 500000, 100000, 50000, 1000} @@ -54,6 +56,24 @@ var ( blockHashPrefix = []byte("block-hash-") // [deprecated by the header/block split, remove eventually] ) +func GetATXIBookmark(db ethdb.Database) uint64 { + v, err := db.Get(txAddressBookmarkKey) + if err != nil || v == nil { + return 0 + } + s := string(v) + i, err := strconv.ParseUint(s, 10, 64) + if err != nil { + glog.Fatalln(err) + } + return i +} + +func SetATXIBookmark(db ethdb.Database, i uint64) error { + s := strconv.FormatUint(i, 10) + return db.Put(txAddressBookmarkKey, []byte(s)) +} + // GetCanonicalHash retrieves a hash assigned to a canonical block number. func GetCanonicalHash(db ethdb.Database, number uint64) common.Hash { data, _ := db.Get(append(blockNumPrefix, big.NewInt(int64(number)).Bytes()...)) From 74d7fe0f03c8b2f570398b72a24fa165c37d249b Mon Sep 17 00:00:00 2001 From: ia Date: Sat, 20 Jan 2018 13:45:09 +0900 Subject: [PATCH 18/45] write test for atxi, refactor, and fix bu g bug was with the address field for 'to' indexes being messed up cuz unnecessary pointer --- common/types.go | 8 ++ core/blockchain.go | 40 ---------- core/database_util.go | 104 ++++++++++++++++-------- core/database_util_test.go | 159 ++++++++++++++++++++++++++++++++++++- 4 files changed, 237 insertions(+), 74 deletions(-) diff --git a/common/types.go b/common/types.go index 768146736..b238d89c5 100644 --- a/common/types.go +++ b/common/types.go @@ -125,6 +125,14 @@ func StringToAddress(s string) Address { return BytesToAddress([]byte(s)) } func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) } func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) } +func EmptyAddress(a Address) bool { + return a == Address{} +} + +func (a Address) IsEmpty() bool { + return EmptyAddress(a) +} + // IsHexAddress verifies whether a string can represent a valid hex-encoded // Ethereum address or not. func IsHexAddress(s string) bool { diff --git a/core/blockchain.go b/core/blockchain.go index f45b15d78..f8696ddfc 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1372,46 +1372,6 @@ func (self *BlockChain) WriteBlockAddrTxIndexesBatch(indexDb ethdb.Database, sta return txsCount, batch.Write() } -// putBlockAddrTxsToBatch formats and puts keys for a given block to a db Batch. -// Batch can be written afterward if no errors, ie. batch.Write() -func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount int, err error) { - for _, tx := range block.Transactions() { - txsCount++ - - from, err := tx.From() - if err != nil { - return txsCount, err - } - // Note that len 8 because uint64 guaranteed <= 8 bytes. - bn := make([]byte, 8) - binary.LittleEndian.PutUint64(bn, block.NumberU64()) - - if err := putBatch.Put(FormatAddrTxBytesIndex(from.Bytes(), bn, []byte("f"), tx.Hash().Bytes()), nil); err != nil { - return txsCount, err - } - - to := tx.To() - if to == nil { - continue - } - var tob []byte - copy(tob, to.Bytes()) - if err := putBatch.Put(FormatAddrTxBytesIndex(tob, bn, []byte("t"), tx.Hash().Bytes()), nil); err != nil { - return txsCount, err - } - } - return txsCount, nil -} - -// WriteBlockAddTxIndexes writes atx-indexes for a given block. -func WriteBlockAddTxIndexes(indexDb ethdb.Database, block *types.Block) error { - batch := indexDb.NewBatch() - if _, err := putBlockAddrTxsToBatch(batch, block); err != nil { - return err - } - return batch.Write() -} - // WriteBlock writes the block to the chain. func (self *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err error) { diff --git a/core/database_util.go b/core/database_util.go index 4845972ce..76356b8d1 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -145,6 +145,35 @@ func GetBodyRLP(db ethdb.Database, hash common.Hash) rlp.RawValue { return data } +// formatAddrTxIterator formats the index key prefix iterator, eg. atx-
+func formatAddrTxIterator(address common.Address) (iteratorPrefix []byte) { + iteratorPrefix = append(iteratorPrefix, txAddressIndexPrefix...) + iteratorPrefix = append(iteratorPrefix, address.Bytes()...) + return +} + +// formatAddrTxBytesIndex formats the index key, eg. atx- +// The values for these arguments should be of determinate length and format, see test TestFormatAndResolveAddrTxBytesKey +// for example. +func formatAddrTxBytesIndex(address, blockNumber, direction, txhash []byte) (key []byte) { + key = txAddressIndexPrefix + key = append(key, address...) + key = append(key, blockNumber...) + key = append(key, direction...) + key = append(key, txhash...) + return +} + +// resolveAddrTxBytes resolves the index key to individual []byte values +func resolveAddrTxBytes(key []byte) (address, blockNumber, direction, txhash []byte) { + // prefix = key[:4] + address = key[4:24] // common.AddressLength = 20 + blockNumber = key[24:32] + direction = key[32:33] // == key[32] (1 byte) + txhash = key[33:] + return +} + // GetBody retrieves the block body (transactons, uncles) corresponding to the // hash, nil if none found. func GetBody(db ethdb.Database, hash common.Hash) *types.Body { @@ -160,11 +189,42 @@ func GetBody(db ethdb.Database, hash common.Hash) *types.Body { return body } -// formatAddrTxIterator formats the index key prefix iterator, eg. atx-
-func formatAddrTxIterator(address common.Address) (iteratorPrefix []byte) { - iteratorPrefix = append(iteratorPrefix, txAddressIndexPrefix...) - iteratorPrefix = append(iteratorPrefix, address.Bytes()...) - return +// WriteBlockAddTxIndexes writes atx-indexes for a given block. +func WriteBlockAddTxIndexes(indexDb ethdb.Database, block *types.Block) error { + batch := indexDb.NewBatch() + if _, err := putBlockAddrTxsToBatch(batch, block); err != nil { + return err + } + return batch.Write() +} + +// putBlockAddrTxsToBatch formats and puts keys for a given block to a db Batch. +// Batch can be written afterward if no errors, ie. batch.Write() +func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount int, err error) { + for _, tx := range block.Transactions() { + txsCount++ + + from, err := tx.From() + if err != nil { + return txsCount, err + } + // Note that len 8 because uint64 guaranteed <= 8 bytes. + bn := make([]byte, 8) + binary.LittleEndian.PutUint64(bn, block.NumberU64()) + + if err := putBatch.Put(formatAddrTxBytesIndex(from.Bytes(), bn, []byte("f"), tx.Hash().Bytes()), nil); err != nil { + return txsCount, err + } + + to := tx.To() + if to == nil || to.IsEmpty() { + continue + } + if err := putBatch.Put(formatAddrTxBytesIndex(to.Bytes(), bn, []byte("t"), tx.Hash().Bytes()), nil); err != nil { + return txsCount, err + } + } + return txsCount, nil } // GetAddrTxs gets the indexed transactions for a given account address. @@ -179,10 +239,6 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b return nil } - // Create address prefix for iteration. - prefix := ethdb.NewBytesPrefix(formatAddrTxIterator(address)) - it := ldb.NewIteratorRange(prefix) - // This will be the returnable. var hashes []string @@ -192,6 +248,10 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b wantDirectionB = direction[0] } + // Create address prefix for iteration. + prefix := ethdb.NewBytesPrefix(formatAddrTxIterator(address)) + it := ldb.NewIteratorRange(prefix) + for it.Next() { key := it.Key() @@ -217,35 +277,13 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b hashes = append(hashes, tx) } it.Release() - if it.Error() != nil { - glog.Fatalln(it.Error()) + if e := it.Error(); e != nil { + glog.Fatalln(e) } return hashes } -// FormatAddrTxBytesIndex formats the index key, eg. atx- -// The values for these arguments should be of determinate length and format, see test TestFormatAndResolveAddrTxBytesKey -// for example. -func FormatAddrTxBytesIndex(address, blockNumber, direction, txhash []byte) (key []byte) { - key = txAddressIndexPrefix - key = append(key, address...) - key = append(key, blockNumber...) - key = append(key, direction...) - key = append(key, txhash...) - return -} - -// resolveAddrTxBytes resolves the index key to individual []byte values -func resolveAddrTxBytes(key []byte) (address, blockNumber, direction, txhash []byte) { - // prefix = key[:4] - address = key[4:24] // common.AddressLength = 20 - blockNumber = key[24:32] - direction = key[32:33] // == key[32] (1 byte) - txhash = key[33:] - return -} - // RmAddrTx removes all atxi indexes for a given tx in case of a transaction removal, eg. // in the case of chain reorg. // It isn't an elegant function, but not a top priority for optimization because of diff --git a/core/database_util_test.go b/core/database_util_test.go index 3dc9d39fc..41755dedf 100644 --- a/core/database_util_test.go +++ b/core/database_util_test.go @@ -34,6 +34,8 @@ import ( "github.com/ethereumproject/go-ethereum/ethdb" "github.com/ethereumproject/go-ethereum/rlp" "encoding/binary" + "crypto/ecdsa" + "strings" ) type diffTest struct { @@ -299,6 +301,161 @@ func TestTdStorage(t *testing.T) { } } +func TestAddrTxStorage(t *testing.T) { + dbFilepath, err := ioutil.TempDir("", "geth-db-util-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dbFilepath) + db, _ := ethdb.NewLDBDatabase(dbFilepath, 10, 100) + + testKey := func(hex string) (*ecdsa.PrivateKey, common.Address) { + key := crypto.ToECDSA(common.Hex2Bytes(hex)) + addr := crypto.PubkeyToAddress(key.PublicKey) + return key, addr + } + + skey1, from1 := testKey("123915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8") + skey2, from2 := testKey("456915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8") + + from2to := common.BytesToAddress([]byte{0x22}) + + // from1 -> 1 + tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), big.NewInt(1111), big.NewInt(11111), []byte{0x11, 0x11, 0x11}) + + // from2 -> 2,3,txC + tx2 := types.NewTransaction(2, from2to, big.NewInt(222), big.NewInt(2222), big.NewInt(22222), []byte{0x22, 0x22, 0x22}) + tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), big.NewInt(3333), big.NewInt(33333), []byte{0x33, 0x33, 0x33}) + txC := types.NewTransaction(4, common.Address{}, big.NewInt(333), big.NewInt(3333), big.NewInt(33333), []byte{0x33, 0x33, 0x33}) + + txs := []*types.Transaction{tx1, tx2, tx3, txC} + txsSigned := []*types.Transaction{} + + for _, x := range txs { + // Sign em so we get from + key := skey1 + if x.Nonce() != 1 { + key = skey2 + } + x.SetSigner(types.NewChainIdSigner(big.NewInt(1))) + xs, err := x.SignECDSA(key) + if err != nil { + t.Fatal(err) + } + txsSigned = append(txsSigned, xs) + } + + block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txsSigned, nil, nil) + + // Put in the transactions just for fun. + // + // Check that no transactions entries are in a pristine database + for i, tx := range txsSigned { + if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn != nil { + t.Fatalf("tx #%d [%x]: non existent transaction returned: %v", i, tx.Hash(), txn) + } + } + // Insert all the transactions into the database, and verify contents + if err := WriteTransactions(db, block); err != nil { + t.Fatalf("failed to write transactions: %v", err) + } + for i, tx := range txsSigned { + if txn, hash, number, index := GetTransaction(db, tx.Hash()); txn == nil { + t.Fatalf("tx #%d [%x]: transaction not found", i, tx.Hash()) + } else { + if hash != block.Hash() || number != block.NumberU64() || index != uint64(i) { + t.Fatalf("tx #%d [%x]: positional metadata mismatch: have %x/%d/%d, want %x/%v/%v", i, tx.Hash(), hash, number, index, block.Hash(), block.NumberU64(), i) + } + if tx.String() != txn.String() { + t.Fatalf("tx #%d [%x]: transaction mismatch: have %v, want %v", i, tx.Hash(), txn, tx) + } + } + } + + // Write the atx indexes + if err := WriteBlockAddTxIndexes(db, block); err != nil { + t.Fatal(err) + } + + prefix := ethdb.NewBytesPrefix(txAddressIndexPrefix) + it := db.NewIteratorRange(prefix) + count := 0 + for it.Next() { + count++ + //// Debugger -- it's kinda nice to see what the indexes look like + //ad, bn, tf, txh := resolveAddrTxBytes(it.Key()) + //addr, blockn, direc, txhash := common.BytesToAddress(ad), binary.LittleEndian.Uint64(bn), string(tf), common.BytesToHash(txh) + //t.Log(addr.Hex(), blockn, direc, txhash.Hex()) + } + it.Release() + if e := it.Error(); e != nil { + t.Fatal(e) + } + if count != 7 { + t.Errorf("want: %v, got: %v", 7, count) + } + + out := GetAddrTxs(db, from2, 0, 0, "") + if len(out) != 3 { + t.Errorf("want: %v, got: %v", 3, len(out)) + } + + out = GetAddrTxs(db, from1, 314, 314, "") + if len(out) != 1 { + t.Errorf("want: %v, got: %v", 1, len(out)) + } else { + h := out[0] + if !strings.HasPrefix(h, "0x") { + t.Errorf("want: 0x-prefix, got: %v", h) + } + if !common.IsHex(h) { + t.Errorf("want: hex, got: %v", h) + } + txh := common.HexToHash(h) + + if txh != txsSigned[0].Hash() { + t.Errorf("got: %x, want: %x", txh, txsSigned[0].Hash()) + } + + gx, _, _, _ := GetTransaction(db, txh) + if gx == nil { + t.Errorf("missing tx: %x", txh) + } + } + + out = GetAddrTxs(db, from2to, 314, 314, "to") + if len(out) != 1 { + t.Errorf("want: %v, got: %v", 1, len(out)) + } else { + h := out[0] + if !strings.HasPrefix(h, "0x") { + t.Errorf("want: 0x-prefix, got: %v", h) + } + if !common.IsHex(h) { + t.Errorf("want: hex, got: %v", h) + } + txh := common.HexToHash(h) + if txh != txsSigned[1].Hash() { + t.Errorf("got: %x, want: %x", txh, txsSigned[0].Hash()) + } + gx, _, _, _ := GetTransaction(db, txh) + if gx == nil { + t.Errorf("missing tx: %x", txh) + } + f, e := gx.From() + if e != nil { + t.Error(e) + } + if f != from2 { + t.Errorf("got: %v, want: %v", f, from2) + } + } + out = GetAddrTxs(db, from2to, 314, 314, "from") + if len(out) != 0 { + t.Errorf("want: %v, got: %v", 0, len(out)) + } +} + func TestFormatAndResolveAddrTxBytesKey(t *testing.T) { testAddr := common.Address{} testBN := uint64(42) @@ -308,7 +465,7 @@ func TestFormatAndResolveAddrTxBytesKey(t *testing.T) { testBNBytes := make([]byte, 8) binary.LittleEndian.PutUint64(testBNBytes, testBN) - key := FormatAddrTxBytesIndex(testAddr.Bytes(), testBNBytes, []byte(testTorf), testTxH.Bytes()) + key := formatAddrTxBytesIndex(testAddr.Bytes(), testBNBytes, []byte(testTorf), testTxH.Bytes()) // Test key/prefix iterator-ability. itPrefix := formatAddrTxIterator(testAddr) From cdb4055168c149d8791e7ba5e92b1268064e309c Mon Sep 17 00:00:00 2001 From: ia Date: Sat, 20 Jan 2018 17:32:51 +0900 Subject: [PATCH 19/45] test for fast/full sync implements atxi if enabled --- core/blockchain_test.go | 118 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 0b49ca16d..492de3fa1 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -37,6 +37,7 @@ import ( "github.com/ethereumproject/go-ethereum/logger/glog" "github.com/ethereumproject/go-ethereum/rlp" "github.com/hashicorp/golang-lru" + "io/ioutil" ) func init() { @@ -884,6 +885,123 @@ func TestFastVsFullChains(t *testing.T) { } } +func TestFastVsFullChainsATXI(t *testing.T) { + archiveDir, e := ioutil.TempDir("", "archive-") + if e != nil { + t.Fatal(e) + } + fastDir, e := ioutil.TempDir("", "fast-") + if e != nil { + t.Fatal(e) + } + defer os.RemoveAll(archiveDir) + defer os.RemoveAll(fastDir) + + // Create the dbs + // + archiveDb, err := ethdb.NewLDBDatabase(archiveDir, 10, 100) + if err != nil { + t.Fatal(err) + } + fastDb, err := ethdb.NewLDBDatabase(fastDir, 10, 100) + if err != nil { + t.Fatal(err) + } + + MinGasLimit = big.NewInt(125000) + + key1, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + if err != nil { + t.Fatal(err) + } + key2, err := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") + if err != nil { + t.Fatal(err) + } + + var ( + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + addr2 = crypto.PubkeyToAddress(key2.PublicKey) + signer = types.NewChainIdSigner(big.NewInt(63)) + dbs = []ethdb.Database{archiveDb, fastDb} + config = MakeDiehardChainConfig() + ) + + for i, db := range dbs { + t1, err := types.NewTransaction(0, addr2, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key1) + if err != nil { + t.Fatal(err) + } + t2, err := types.NewTransaction(1, addr2, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key1) + if err != nil { + t.Fatal(err) + } + t3, err := types.NewTransaction(0, addr1, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key2) + if err != nil { + t.Fatal(err) + } + genesis := WriteGenesisBlockForTesting(db, + GenesisAccount{addr1, big.NewInt(1000000)}, + GenesisAccount{addr2, big.NewInt(1000000)}, + ) + blocks, receipts := GenerateChain(config, genesis, db, 3, func(i int, gen *BlockGen) { + if i == 0 { + gen.AddTx(t1) + } + if i == 1 { + gen.AddTx(t2) + } + if i == 2 { + gen.AddTx(t3) + } + }) + + blockchain, err := NewBlockChain(db, config, FakePow{}, new(event.TypeMux)) + if err != nil { + t.Fatal(err) + } + // turn on atxi + blockchain.SetAddTxIndex(db, true) + if i == 0 { + if n, err := blockchain.InsertChain(blocks); err != nil { + t.Fatalf("failed to process block %d: %v", n, err) + } + } else { + headers := make([]*types.Header, len(blocks)) + for i, block := range blocks { + headers[i] = block.Header() + } + if n, err := blockchain.InsertHeaderChain(headers, 1); err != nil { + t.Fatalf("failed to insert header %d: %v", n, err) + } + if n, err := blockchain.InsertReceiptChain(blocks, receipts); err != nil { + t.Fatalf("failed to insert receipt %d: %v", n, err) + } + } + + out := GetAddrTxs(db, addr1, 0, 0, "") + if len(out) != 3 { + t.Errorf("[%d] got: %v, want: %v", i, len(out), 3) + } + out = GetAddrTxs(db, addr1, 0, 0, "from") + if len(out) != 2 { + t.Errorf("[%d] got: %v, want: %v", i, len(out), 2) + } + out = GetAddrTxs(db, addr1, 0, 0, "to") + if len(out) != 1 { + t.Errorf("[%d] got: %v, want: %v", i, len(out), 1) + } + out = GetAddrTxs(db, addr2, 0, 0, "") + if len(out) != 3 { + t.Errorf("[%d] got: %v, want: %v", i, len(out), 3) + } + out = GetAddrTxs(db, addr2, 3, 3, "") + if len(out) != 1 { + t.Errorf("[%d] got: %v, want: %v", i, len(out), 1) + } + } +} + // Tests that various import methods move the chain head pointers to the correct // positions. func TestLightVsFastVsFullChainHeads(t *testing.T) { From 2ef01570c8b3393d1d7749ccbd2be1f5e27055c5 Mon Sep 17 00:00:00 2001 From: ia Date: Sun, 21 Jan 2018 13:00:07 +0900 Subject: [PATCH 20/45] problem: atxi not removing indexes solution: use key instead of tx hash (typo) --- core/database_util.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/database_util.go b/core/database_util.go index 76356b8d1..d8ae9037e 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -289,6 +289,10 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b // It isn't an elegant function, but not a top priority for optimization because of // expected infrequency of it's being called. func RmAddrTx(db ethdb.Database, tx *types.Transaction) error { + if tx == nil { + return nil + } + ldb, ok := db.(*ethdb.LDBDatabase) if !ok { return nil @@ -309,7 +313,7 @@ func RmAddrTx(db ethdb.Database, tx *types.Transaction) error { key := it.Key() _, _, _, txh := resolveAddrTxBytes(key) if bytes.Compare(txH.Bytes(), txh) == 0 { - removals = append(removals, txh) + removals = append(removals, key) break // because there can be only one } } @@ -327,7 +331,7 @@ func RmAddrTx(db ethdb.Database, tx *types.Transaction) error { key := it.Key() _, _, _, txh := resolveAddrTxBytes(key) if bytes.Compare(txH.Bytes(), txh) == 0 { - removals = append(removals, txh) + removals = append(removals, key) break // because there can be only one } } @@ -338,6 +342,8 @@ func RmAddrTx(db ethdb.Database, tx *types.Transaction) error { } for _, r := range removals { + //addr, bn, tf, txh := resolveAddrTxBytes(r) + //glog.Fatalln(len(removals), common.BytesToAddress(addr).Hex(), binary.LittleEndian.Uint64(bn), string(tf), common.Bytes2Hex(txh)) if err := db.Delete(r); err != nil { return err } From 258d4185b1aec5872cea941ff64b76008c505ac3 Mon Sep 17 00:00:00 2001 From: ia Date: Sun, 21 Jan 2018 13:01:10 +0900 Subject: [PATCH 21/45] problem: weirdly named signature var for tx Diff fn solution: rename keep -> diff because it returns the difference, see usage in bv.reorg --- core/types/transaction.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/types/transaction.go b/core/types/transaction.go index e660eb608..b7c96b587 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -274,8 +274,8 @@ func (s Transactions) GetRlp(i int) []byte { } // Returns a new set t which is the difference between a to b -func TxDifference(a, b Transactions) (keep Transactions) { - keep = make(Transactions, 0, len(a)) +func TxDifference(a, b Transactions) (diff Transactions) { + diff = make(Transactions, 0, len(a)) remove := make(map[common.Hash]struct{}) for _, tx := range b { @@ -284,11 +284,11 @@ func TxDifference(a, b Transactions) (keep Transactions) { for _, tx := range a { if _, ok := remove[tx.Hash()]; !ok { - keep = append(keep, tx) + diff = append(diff, tx) } } - return keep + return diff } // TxByNonce implements the sort interface to allow sorting a list of transactions From 2644af4b0b26972cdbd4476b8e8573822b23cadb Mon Sep 17 00:00:00 2001 From: ia Date: Sun, 21 Jan 2018 13:03:00 +0900 Subject: [PATCH 22/45] problem: duplicate txs hashes return when chain reorg ... with shared but postponed txs (same tx, later block) solution: rm all txs from old chain, add all txs for new chain in case of reorg. atxi should only reflect canonical chain. --- core/blockchain.go | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index f8696ddfc..a5700dd77 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1757,6 +1757,17 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { ).Send(mlogBlockchain) } + // Remove all atxis from old chain; indexes should only reflect canonical + if self.useAddTxIndex { + for _, block := range oldChain { + for _, tx := range block.Transactions() { + if err := RmAddrTx(self.indexesDb, tx); err != nil { + return err + } + } + } + } + var addedTxs types.Transactions // insert blocks. Order does not matter. Last block will be written in ImportChain itself which creates the new head properly for _, block := range newChain { @@ -1766,6 +1777,12 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { if err := WriteTransactions(self.chainDb, block); err != nil { return err } + // Store the addr-tx indexes if enabled + if self.useAddTxIndex { + if err := WriteBlockAddTxIndexes(self.indexesDb, block); err != nil { + return err + } + } receipts := GetBlockReceipts(self.chainDb, block.Hash()) // write receipts if err := WriteReceipts(self.chainDb, receipts); err != nil { @@ -1775,12 +1792,6 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { if err := WriteMipmapBloom(self.chainDb, block.NumberU64(), receipts); err != nil { return err } - // Store the addr-tx indexes if enabled - if self.useAddTxIndex { - if err := WriteBlockAddTxIndexes(self.indexesDb, block); err != nil { - glog.Fatalf("failed to write block add-tx indexes", err) - } - } addedTxs = append(addedTxs, block.Transactions()...) } @@ -1790,11 +1801,6 @@ func (self *BlockChain) reorg(oldBlock, newBlock *types.Block) error { // receipts that were created in the fork must also be deleted for _, tx := range diff { DeleteReceipt(self.chainDb, tx.Hash()) - if self.useAddTxIndex { - if err := RmAddrTx(self.indexesDb, tx); err != nil { - return err - } - } DeleteTransaction(self.chainDb, tx.Hash()) } // Must be posted in a goroutine because of the transaction pool trying From 4bb36a10fed4433576b876fb35ed81c39bf69555 Mon Sep 17 00:00:00 2001 From: ia Date: Sun, 21 Jan 2018 13:03:35 +0900 Subject: [PATCH 23/45] problem: no tests for atxi rm or reorg solution: write 'em --- core/blockchain_test.go | 197 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 183 insertions(+), 14 deletions(-) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 492de3fa1..0a9360c87 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -38,6 +38,7 @@ import ( "github.com/ethereumproject/go-ethereum/rlp" "github.com/hashicorp/golang-lru" "io/ioutil" + "strings" ) func init() { @@ -1002,6 +1003,90 @@ func TestFastVsFullChainsATXI(t *testing.T) { } } +func TestRmAddrTx(t *testing.T) { + archiveDir, e := ioutil.TempDir("", "archive-") + if e != nil { + t.Fatal(e) + } + defer os.RemoveAll(archiveDir) + + // Create the dbs + // + db, err := ethdb.NewLDBDatabase(archiveDir, 10, 100) + if err != nil { + t.Fatal(err) + } + + MinGasLimit = big.NewInt(125000) + + key1, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + if err != nil { + t.Fatal(err) + } + key2, err := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") + if err != nil { + t.Fatal(err) + } + + var ( + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + addr2 = crypto.PubkeyToAddress(key2.PublicKey) + signer = types.NewChainIdSigner(big.NewInt(63)) + config = MakeDiehardChainConfig() + ) + + t1, err := types.NewTransaction(0, addr2, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key1) + if err != nil { + t.Fatal(err) + } + t2, err := types.NewTransaction(1, addr2, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key1) + if err != nil { + t.Fatal(err) + } + t3, err := types.NewTransaction(0, addr1, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key2) + if err != nil { + t.Fatal(err) + } + genesis := WriteGenesisBlockForTesting(db, + GenesisAccount{addr1, big.NewInt(1000000)}, + GenesisAccount{addr2, big.NewInt(1000000)}, + ) + blocks, _ := GenerateChain(config, genesis, db, 3, func(i int, gen *BlockGen) { + if i == 0 { + gen.AddTx(t1) + } + if i == 1 { + gen.AddTx(t2) + } + if i == 2 { + gen.AddTx(t3) + } + }) + + blockchain, err := NewBlockChain(db, config, FakePow{}, new(event.TypeMux)) + if err != nil { + t.Fatal(err) + } + // turn on atxi + blockchain.SetAddTxIndex(db, true) + + if n, err := blockchain.InsertChain(blocks); err != nil { + t.Fatalf("failed to process block %d: %v", n, err) + } + + out := GetAddrTxs(db, addr1, 0, 0, "") + if len(out) != 3 { + t.Errorf("got: %v, want: %v", len(out), 3) + } + if err := RmAddrTx(db, t1); err != nil { + t.Fatal(err) + } + out = GetAddrTxs(db, addr1, 0, 0, "") + if len(out) != 2 { + t.Errorf("got: %v, want: %v", len(out), 2) + } +} + // Tests that various import methods move the chain head pointers to the correct // positions. func TestLightVsFastVsFullChainHeads(t *testing.T) { @@ -1104,6 +1189,28 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) { // Tests that chain reorganisations handle transaction removals and reinsertions. func TestChainTxReorgs(t *testing.T) { + db, err := ethdb.NewMemDatabase() + if err != nil { + t.Fatal(err) + } + testChainTxReorgs(t, db, false) +} + +func TestChainTxReorgsAtxi(t *testing.T) { + p, err := ioutil.TempDir("", "test-reorg-atxi-") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(p) + + db, err := ethdb.NewLDBDatabase(p, 10, 100) + if err != nil { + t.Fatal(err) + } + testChainTxReorgs(t, db, true) +} + +func testChainTxReorgs(t *testing.T, db ethdb.Database, withATXI bool) { MinGasLimit = big.NewInt(125000) key1, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") @@ -1118,10 +1225,6 @@ func TestChainTxReorgs(t *testing.T) { if err != nil { t.Fatal(err) } - db, err := ethdb.NewMemDatabase() - if err != nil { - t.Fatal(err) - } var ( addr1 = crypto.PubkeyToAddress(key1.PublicKey) @@ -1135,39 +1238,47 @@ func TestChainTxReorgs(t *testing.T) { GenesisAccount{addr3, big.NewInt(1000000)}, ) // Create two transactions shared between the chains: + // addr1 -> addr2 // - postponed: transaction included at a later block in the forked chain // - swapped: transaction included at the same block number in the forked chain - postponed, err := types.NewTransaction(0, addr1, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key1) + postponed, err := types.NewTransaction(0, addr2, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key1) if err != nil { t.Fatal(err) } - swapped, err := types.NewTransaction(1, addr1, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key1) + swapped, err := types.NewTransaction(1, addr2, big.NewInt(1001), TxGas, nil, nil).WithSigner(signer).SignECDSA(key1) if err != nil { t.Fatal(err) } // Create two transactions that will be dropped by the forked chain: + // addr2 -> addr3 // - pastDrop: transaction dropped retroactively from a past block // - freshDrop: transaction dropped exactly at the block where the reorg is detected var pastDrop, freshDrop *types.Transaction // Create three transactions that will be added in the forked chain: + // addr3 -> addr1 // - pastAdd: transaction added before the reorganization is detected // - freshAdd: transaction added at the exact block the reorg is detected // - futureAdd: transaction added after the reorg has already finished var pastAdd, freshAdd, futureAdd *types.Transaction + // ATXI tallies, (means) will be removed + // addr1: 2f+3t + // addr2: 2t+(2f) + // addr3: (2t)+3f + chainConfig := MakeDiehardChainConfig() chain, _ := GenerateChain(chainConfig, genesis, db, 3, func(i int, gen *BlockGen) { switch i { case 0: - pastDrop, _ = types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key2) + pastDrop, _ = types.NewTransaction(gen.TxNonce(addr2), addr3, big.NewInt(1002), TxGas, nil, nil).WithSigner(signer).SignECDSA(key2) gen.AddTx(pastDrop) // This transaction will be dropped in the fork from below the split point gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork case 2: - freshDrop, _ = types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key2) + freshDrop, _ = types.NewTransaction(gen.TxNonce(addr2), addr3, big.NewInt(1003), TxGas, nil, nil).WithSigner(signer).SignECDSA(key2) gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point gen.AddTx(swapped) // This transaction will be swapped out at the exact height @@ -1182,6 +1293,9 @@ func TestChainTxReorgs(t *testing.T) { if err != nil { t.Fatal(err) } + if withATXI { + blockchain.SetAddTxIndex(db, true) + } if i, err := blockchain.InsertChain(chain); err != nil { t.Fatalf("failed to insert original chain[%d]: %v", i, err) } @@ -1190,18 +1304,18 @@ func TestChainTxReorgs(t *testing.T) { chain, _ = GenerateChain(chainConfig, genesis, db, 5, func(i int, gen *BlockGen) { switch i { case 0: - pastAdd, _ = types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key3) + pastAdd, _ = types.NewTransaction(gen.TxNonce(addr3), addr1, big.NewInt(1004), TxGas, nil, nil).WithSigner(signer).SignECDSA(key3) gen.AddTx(pastAdd) // This transaction needs to be injected during reorg case 2: gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain gen.AddTx(swapped) // This transaction was swapped from the exact current spot in the original chain - freshAdd, _ = types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key3) + freshAdd, _ = types.NewTransaction(gen.TxNonce(addr3), addr1, big.NewInt(1005), TxGas, nil, nil).WithSigner(signer).SignECDSA(key3) gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time case 3: - futureAdd, _ = types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key3) + futureAdd, _ = types.NewTransaction(gen.TxNonce(addr3), addr1, big.NewInt(1006), TxGas, nil, nil).WithSigner(signer).SignECDSA(key3) gen.AddTx(futureAdd) // This transaction will be added after a full reorg } }) @@ -1209,8 +1323,14 @@ func TestChainTxReorgs(t *testing.T) { t.Fatalf("failed to insert forked chain: %v", err) } + // Conveniently grouped + txsRemoved := types.Transactions{pastDrop, freshDrop} + txsAdded := types.Transactions{pastAdd, freshAdd, futureAdd} + txsShared := types.Transactions{postponed, swapped} + txsAll := types.Transactions{pastDrop, freshDrop, pastAdd, freshAdd, futureAdd, postponed, swapped} + // removed tx - for i, tx := range (types.Transactions{pastDrop, freshDrop}) { + for i, tx := range txsRemoved { if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn != nil { t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn) } @@ -1219,7 +1339,7 @@ func TestChainTxReorgs(t *testing.T) { } } // added tx - for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) { + for i, tx := range txsAdded { if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn == nil { t.Errorf("add %d: expected tx to be found", i) } @@ -1228,7 +1348,7 @@ func TestChainTxReorgs(t *testing.T) { } } // shared tx - for i, tx := range (types.Transactions{postponed, swapped}) { + for i, tx := range txsShared { if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn == nil { t.Errorf("share %d: expected tx to be found", i) } @@ -1236,8 +1356,57 @@ func TestChainTxReorgs(t *testing.T) { t.Errorf("share %d: expected receipt to be found", i) } } + + // ATXI checks + if !withATXI { + return + } + txsh1 := GetAddrTxs(db, addr1, 0, 0, "") + txsh2 := GetAddrTxs(db, addr2, 0, 0, "") + txsh3 := GetAddrTxs(db, addr3, 0, 0, "") + + allAtxis := txsh1 + allAtxis = append(allAtxis, txsh2...) + allAtxis = append(allAtxis, txsh3...) + + // Ensure a transaction exists for each atxi hash + for _, x := range allAtxis { + if tx, _, _, _ := GetTransaction(db, common.HexToHash(x)); tx == nil { + t.Error("atxi not removed") + } + } + + // Ensure no duplicate tx hashes returned + DUPECHECK: + for i, l := range ([][]string{txsh1, txsh2, txsh3}) { + j := strings.Join(l, "") + for _, h := range l { + if strings.Count(j, h[:8]) > 1 { + // show offending tx + offendingTxN := new(big.Int) + for _, x := range txsAll { + if x.Hash().Hex() == h { + offendingTxN.Set(x.Value()) // use unique value as a way to identify offender + break + } + } + t.Log(strings.Join(l, "\n")) + t.Errorf("[%d] duplicate tx hash (%v)", i, offendingTxN) + break DUPECHECK + } + } + + } + + // Check magnitude; 2 atxis per canonical tx (to & from) + wantMag := (len(txsAdded) + len(txsShared)) * 2 + if len(allAtxis) != wantMag { + t.Errorf("got: %v, want: %v", len(allAtxis), wantMag) + } } + + func TestLogReorgs(t *testing.T) { // This test itself is a little bit incorrect. Below, // MakeDiehardChainConfig would make a chain configuration that From 429d2abe96bcb655e325a12edbaec6d2cf5bbbb8 Mon Sep 17 00:00:00 2001 From: ia Date: Sun, 21 Jan 2018 13:48:25 +0900 Subject: [PATCH 24/45] allow empty tx.to to allow querying just contracts --- core/database_util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/database_util.go b/core/database_util.go index d8ae9037e..f92c75989 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -217,7 +217,7 @@ func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount } to := tx.To() - if to == nil || to.IsEmpty() { + if to == nil { continue } if err := putBatch.Put(formatAddrTxBytesIndex(to.Bytes(), bn, []byte("t"), tx.Hash().Bytes()), nil); err != nil { From bf00bf058abd3891a32a01c40def31580ae191a3 Mon Sep 17 00:00:00 2001 From: ia Date: Sun, 21 Jan 2018 13:49:02 +0900 Subject: [PATCH 25/45] minor refactorings for code cleanliness, see pr code comments --- core/database_util.go | 31 +++++++++++-------------------- eth/api.go | 7 ++++--- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/core/database_util.go b/core/database_util.go index f92c75989..0d5317f24 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -28,7 +28,7 @@ import ( "github.com/ethereumproject/go-ethereum/logger" "github.com/ethereumproject/go-ethereum/logger/glog" "github.com/ethereumproject/go-ethereum/rlp" - "strconv" + "strings" ) var ( @@ -61,17 +61,14 @@ func GetATXIBookmark(db ethdb.Database) uint64 { if err != nil || v == nil { return 0 } - s := string(v) - i, err := strconv.ParseUint(s, 10, 64) - if err != nil { - glog.Fatalln(err) - } + i := binary.LittleEndian.Uint64(v) return i } func SetATXIBookmark(db ethdb.Database, i uint64) error { - s := strconv.FormatUint(i, 10) - return db.Put(txAddressBookmarkKey, []byte(s)) + bn := make([]byte, 8) + binary.LittleEndian.PutUint64(bn, i) + return db.Put(txAddressBookmarkKey, bn) } // GetCanonicalHash retrieves a hash assigned to a canonical block number. @@ -229,8 +226,8 @@ func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount // GetAddrTxs gets the indexed transactions for a given account address. func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, blockEndN uint64, direction string) []string { - if direction != "to" && direction != "from" && direction != "both" && direction != "" { - glog.Fatal("Address transactions list signature requires 'to', 'from', or 'both' or '' (=both)") + if len(direction) > 0 && !strings.Contains("btf", direction[:1]) { + glog.Fatal("Address transactions list signature requires empty string or [b|t|f] prefix") } // Have to cast to LevelDB to use iterator. Yuck. @@ -258,16 +255,12 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b _, blockNum, torf, txh := resolveAddrTxBytes(key) // If atxi is smaller than blockstart, skip - if blockStartN > 0 { - if binary.LittleEndian.Uint64(blockNum) < blockStartN { - continue - } + if blockStartN > 0 && binary.LittleEndian.Uint64(blockNum) < blockStartN { + continue } // If atxi is greater than blockend, skip - if blockEndN > 0 { - if binary.LittleEndian.Uint64(blockNum) > blockEndN { - continue - } + if blockEndN > 0 && binary.LittleEndian.Uint64(blockNum) > blockEndN { + continue } // Ensure matching direction if spec'd if wantDirectionB != 'b' && wantDirectionB != torf[0] { @@ -342,8 +335,6 @@ func RmAddrTx(db ethdb.Database, tx *types.Transaction) error { } for _, r := range removals { - //addr, bn, tf, txh := resolveAddrTxBytes(r) - //glog.Fatalln(len(removals), common.BytesToAddress(addr).Hex(), binary.LittleEndian.Uint64(bn), string(tf), common.Bytes2Hex(txh)) if err := db.Delete(r); err != nil { return err } diff --git a/eth/api.go b/eth/api.go index bad7fb734..837bd65d3 100644 --- a/eth/api.go +++ b/eth/api.go @@ -520,7 +520,7 @@ type PublicBlockChainAPI struct { config *core.ChainConfig bc *core.BlockChain chainDb ethdb.Database - indexesDb ethdb.Database + indexesDb ethdb.Database eventMux *event.TypeMux muNewBlockSubscriptions sync.Mutex // protects newBlocksSubscriptions newBlockSubscriptions map[string]func(core.ChainEvent) error // callbacks for new block subscriptions @@ -1625,11 +1625,12 @@ func NewPublicDebugAPI(eth *Ethereum) *PublicDebugAPI { func (api *PublicDebugAPI) GetAddressTransactions(address common.Address, blockStartN uint64, blockEndN uint64, toOrFrom string) (list []string, err error) { glog.V(logger.Debug).Infoln("RPC call: debug_getAddressTransactions %s %d %d %s", address, blockStartN, blockEndN, toOrFrom) - if _, inUse := api.eth.BlockChain().GetAddTxIndex(); !inUse { + db, inUse := api.eth.BlockChain().GetAddTxIndex() + if !inUse { return nil, errors.New("addr-tx indexing not enabled") } - list = core.GetAddrTxs(api.eth.indexesDb, address, blockStartN, blockEndN, toOrFrom) + list = core.GetAddrTxs(db, address, blockStartN, blockEndN, toOrFrom) // Since list is a slice, it can be nil, which returns 'null'. // Should return empty 'array' if no txs found. From a7dbbb5a010541b82bb254b9357b2c287c0f1c81 Mon Sep 17 00:00:00 2001 From: ia Date: Sun, 21 Jan 2018 14:15:16 +0900 Subject: [PATCH 26/45] solution: implement addition param for standard/contract filter --- core/blockchain.go | 2 +- core/blockchain_test.go | 20 ++++++++-------- core/database_util.go | 46 ++++++++++++++++++++++++++----------- core/database_util_test.go | 34 +++++++++++++++++++-------- eth/api.go | 6 ++--- internal/web3ext/web3ext.go | 2 +- 6 files changed, 72 insertions(+), 38 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index a5700dd77..d96ffc6c5 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -808,7 +808,7 @@ func (bc *BlockChain) SetHead(head uint64) error { for it.Next() { key := it.Key() - _, bn, _, _ := resolveAddrTxBytes(key) + _, bn, _, _, _ := resolveAddrTxBytes(key) n := binary.LittleEndian.Uint64(bn) if n > head { removals = append(removals, key) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 0a9360c87..218098beb 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -980,23 +980,23 @@ func TestFastVsFullChainsATXI(t *testing.T) { } } - out := GetAddrTxs(db, addr1, 0, 0, "") + out := GetAddrTxs(db, addr1, 0, 0, "", "") if len(out) != 3 { t.Errorf("[%d] got: %v, want: %v", i, len(out), 3) } - out = GetAddrTxs(db, addr1, 0, 0, "from") + out = GetAddrTxs(db, addr1, 0, 0, "from", "") if len(out) != 2 { t.Errorf("[%d] got: %v, want: %v", i, len(out), 2) } - out = GetAddrTxs(db, addr1, 0, 0, "to") + out = GetAddrTxs(db, addr1, 0, 0, "to", "") if len(out) != 1 { t.Errorf("[%d] got: %v, want: %v", i, len(out), 1) } - out = GetAddrTxs(db, addr2, 0, 0, "") + out = GetAddrTxs(db, addr2, 0, 0, "", "") if len(out) != 3 { t.Errorf("[%d] got: %v, want: %v", i, len(out), 3) } - out = GetAddrTxs(db, addr2, 3, 3, "") + out = GetAddrTxs(db, addr2, 3, 3, "", "") if len(out) != 1 { t.Errorf("[%d] got: %v, want: %v", i, len(out), 1) } @@ -1074,14 +1074,14 @@ func TestRmAddrTx(t *testing.T) { t.Fatalf("failed to process block %d: %v", n, err) } - out := GetAddrTxs(db, addr1, 0, 0, "") + out := GetAddrTxs(db, addr1, 0, 0, "", "") if len(out) != 3 { t.Errorf("got: %v, want: %v", len(out), 3) } if err := RmAddrTx(db, t1); err != nil { t.Fatal(err) } - out = GetAddrTxs(db, addr1, 0, 0, "") + out = GetAddrTxs(db, addr1, 0, 0, "", "") if len(out) != 2 { t.Errorf("got: %v, want: %v", len(out), 2) } @@ -1361,9 +1361,9 @@ func testChainTxReorgs(t *testing.T, db ethdb.Database, withATXI bool) { if !withATXI { return } - txsh1 := GetAddrTxs(db, addr1, 0, 0, "") - txsh2 := GetAddrTxs(db, addr2, 0, 0, "") - txsh3 := GetAddrTxs(db, addr3, 0, 0, "") + txsh1 := GetAddrTxs(db, addr1, 0, 0, "", "") + txsh2 := GetAddrTxs(db, addr2, 0, 0, "", "") + txsh3 := GetAddrTxs(db, addr3, 0, 0, "", "") allAtxis := txsh1 allAtxis = append(allAtxis, txsh2...) diff --git a/core/database_util.go b/core/database_util.go index 0d5317f24..8cf25564a 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -149,25 +149,27 @@ func formatAddrTxIterator(address common.Address) (iteratorPrefix []byte) { return } -// formatAddrTxBytesIndex formats the index key, eg. atx- +// formatAddrTxBytesIndex formats the index key, eg. atx- // The values for these arguments should be of determinate length and format, see test TestFormatAndResolveAddrTxBytesKey // for example. -func formatAddrTxBytesIndex(address, blockNumber, direction, txhash []byte) (key []byte) { +func formatAddrTxBytesIndex(address, blockNumber, direction, kindof, txhash []byte) (key []byte) { key = txAddressIndexPrefix key = append(key, address...) key = append(key, blockNumber...) key = append(key, direction...) + key = append(key, kindof...) key = append(key, txhash...) return } // resolveAddrTxBytes resolves the index key to individual []byte values -func resolveAddrTxBytes(key []byte) (address, blockNumber, direction, txhash []byte) { +func resolveAddrTxBytes(key []byte) (address, blockNumber, direction, kindof, txhash []byte) { // prefix = key[:4] address = key[4:24] // common.AddressLength = 20 - blockNumber = key[24:32] + blockNumber = key[24:32] // uint64 via little endian direction = key[32:33] // == key[32] (1 byte) - txhash = key[33:] + kindof = key[33:34] + txhash = key[34:] return } @@ -205,19 +207,26 @@ func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount if err != nil { return txsCount, err } + to := tx.To() + // s: standard + // c: contract + txKindOf := []byte("s") + if to.IsEmpty() { + txKindOf = []byte("c") + } + // Note that len 8 because uint64 guaranteed <= 8 bytes. bn := make([]byte, 8) binary.LittleEndian.PutUint64(bn, block.NumberU64()) - if err := putBatch.Put(formatAddrTxBytesIndex(from.Bytes(), bn, []byte("f"), tx.Hash().Bytes()), nil); err != nil { + if err := putBatch.Put(formatAddrTxBytesIndex(from.Bytes(), bn, []byte("f"), txKindOf, tx.Hash().Bytes()), nil); err != nil { return txsCount, err } - to := tx.To() if to == nil { continue } - if err := putBatch.Put(formatAddrTxBytesIndex(to.Bytes(), bn, []byte("t"), tx.Hash().Bytes()), nil); err != nil { + if err := putBatch.Put(formatAddrTxBytesIndex(to.Bytes(), bn, []byte("t"), txKindOf, tx.Hash().Bytes()), nil); err != nil { return txsCount, err } } @@ -225,9 +234,12 @@ func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount } // GetAddrTxs gets the indexed transactions for a given account address. -func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, blockEndN uint64, direction string) []string { +func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, blockEndN uint64, direction string, kindof string) []string { if len(direction) > 0 && !strings.Contains("btf", direction[:1]) { - glog.Fatal("Address transactions list signature requires empty string or [b|t|f] prefix") + glog.Fatal("Address transactions list signature requires direction param to be empty string or [b|t|f] prefix (eg. both, to, or from)") + } + if len(kindof) > 0 && !strings.Contains("bsc", kindof[:1]) { + glog.Fatal("Address transactions list signature requires 'kind of' param to be empty string or [s|c] prefix (eg. both, standard, or contract)") } // Have to cast to LevelDB to use iterator. Yuck. @@ -244,6 +256,10 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b if len(direction) > 0 { wantDirectionB = direction[0] } + var wantKindOf byte = 'b' + if len(kindof) > 0 { + wantKindOf = kindof[0] + } // Create address prefix for iteration. prefix := ethdb.NewBytesPrefix(formatAddrTxIterator(address)) @@ -252,7 +268,7 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b for it.Next() { key := it.Key() - _, blockNum, torf, txh := resolveAddrTxBytes(key) + _, blockNum, torf, k, txh := resolveAddrTxBytes(key) // If atxi is smaller than blockstart, skip if blockStartN > 0 && binary.LittleEndian.Uint64(blockNum) < blockStartN { @@ -266,6 +282,10 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b if wantDirectionB != 'b' && wantDirectionB != torf[0] { continue } + // Ensure filter for/agnostic transaction kind of (contract, standard, both) + if wantKindOf != 'b' && wantKindOf != k[0] { + continue + } tx := common.ToHex(txh) hashes = append(hashes, tx) } @@ -304,7 +324,7 @@ func RmAddrTx(db ethdb.Database, tx *types.Transaction) error { it := ldb.NewIteratorRange(pre) for it.Next() { key := it.Key() - _, _, _, txh := resolveAddrTxBytes(key) + _, _, _, _, txh := resolveAddrTxBytes(key) if bytes.Compare(txH.Bytes(), txh) == 0 { removals = append(removals, key) break // because there can be only one @@ -322,7 +342,7 @@ func RmAddrTx(db ethdb.Database, tx *types.Transaction) error { it := ldb.NewIteratorRange(pre) for it.Next() { key := it.Key() - _, _, _, txh := resolveAddrTxBytes(key) + _, _, _, _, txh := resolveAddrTxBytes(key) if bytes.Compare(txH.Bytes(), txh) == 0 { removals = append(removals, key) break // because there can be only one diff --git a/core/database_util_test.go b/core/database_util_test.go index 41755dedf..c8a6150e0 100644 --- a/core/database_util_test.go +++ b/core/database_util_test.go @@ -383,24 +383,33 @@ func TestAddrTxStorage(t *testing.T) { for it.Next() { count++ //// Debugger -- it's kinda nice to see what the indexes look like - //ad, bn, tf, txh := resolveAddrTxBytes(it.Key()) - //addr, blockn, direc, txhash := common.BytesToAddress(ad), binary.LittleEndian.Uint64(bn), string(tf), common.BytesToHash(txh) - //t.Log(addr.Hex(), blockn, direc, txhash.Hex()) + ad, bn, tf, sc, txh := resolveAddrTxBytes(it.Key()) + addr, blockn, direc, ko, txhash := common.BytesToAddress(ad), binary.LittleEndian.Uint64(bn), string(tf), string(sc), common.BytesToHash(txh) + t.Log(addr.Hex(), blockn, direc, ko, txhash.Hex()) } it.Release() if e := it.Error(); e != nil { t.Fatal(e) } - if count != 7 { + if count != 8 { t.Errorf("want: %v, got: %v", 7, count) } - out := GetAddrTxs(db, from2, 0, 0, "") + out := GetAddrTxs(db, from2, 0, 0, "", "") if len(out) != 3 { t.Errorf("want: %v, got: %v", 3, len(out)) } - out = GetAddrTxs(db, from1, 314, 314, "") + out = GetAddrTxs(db, from2, 0, 0, "", "c") + if len(out) !=1 { + t.Errorf("got: %v, want: %v", len(out), 1) + } + out = GetAddrTxs(db, common.Address{}, 0, 0, "", "") + if len(out) !=1 { + t.Errorf("got: %v, want: %v", len(out), 1) + } + + out = GetAddrTxs(db, from1, 314, 314, "", "") if len(out) != 1 { t.Errorf("want: %v, got: %v", 1, len(out)) } else { @@ -423,7 +432,7 @@ func TestAddrTxStorage(t *testing.T) { } } - out = GetAddrTxs(db, from2to, 314, 314, "to") + out = GetAddrTxs(db, from2to, 314, 314, "to", "") if len(out) != 1 { t.Errorf("want: %v, got: %v", 1, len(out)) } else { @@ -450,7 +459,7 @@ func TestAddrTxStorage(t *testing.T) { t.Errorf("got: %v, want: %v", f, from2) } } - out = GetAddrTxs(db, from2to, 314, 314, "from") + out = GetAddrTxs(db, from2to, 314, 314, "from", "") if len(out) != 0 { t.Errorf("want: %v, got: %v", 0, len(out)) } @@ -460,12 +469,13 @@ func TestFormatAndResolveAddrTxBytesKey(t *testing.T) { testAddr := common.Address{} testBN := uint64(42) testTorf := "f" + testKindOf := "s" testTxH := common.Hash{} testBNBytes := make([]byte, 8) binary.LittleEndian.PutUint64(testBNBytes, testBN) - key := formatAddrTxBytesIndex(testAddr.Bytes(), testBNBytes, []byte(testTorf), testTxH.Bytes()) + key := formatAddrTxBytesIndex(testAddr.Bytes(), testBNBytes, []byte(testTorf), []byte(testKindOf), testTxH.Bytes()) // Test key/prefix iterator-ability. itPrefix := formatAddrTxIterator(testAddr) @@ -474,7 +484,7 @@ func TestFormatAndResolveAddrTxBytesKey(t *testing.T) { } // Reverse engineer key and ensure expected. - outAddr, outBNBytes, outTorf, outTxH := resolveAddrTxBytes(key) + outAddr, outBNBytes, outTorf, outKindOf, outTxH := resolveAddrTxBytes(key) if gotAddr := common.BytesToAddress(outAddr); gotAddr != testAddr { t.Errorf("got: %v, want: %v", gotAddr.Hex(), testAddr.Hex()) @@ -485,6 +495,9 @@ func TestFormatAndResolveAddrTxBytesKey(t *testing.T) { if gotTorf := string(outTorf); gotTorf != testTorf { t.Errorf("got: %v, want: %v", gotTorf, testTorf) } + if gotKindOf := string(outKindOf); gotKindOf != testKindOf { + t.Errorf("got: %v, want: %v", gotKindOf, testKindOf) + } if gotTxH := common.BytesToHash(outTxH); gotTxH != testTxH { t.Errorf("got: %v, want: %v", gotTxH, testTxH) } @@ -497,6 +510,7 @@ func TestFormatAndResolveAddrTxBytesKey(t *testing.T) { {outAddr, common.AddressLength}, {outBNBytes, 8}, {outTorf, 1}, + {outKindOf, 1}, {outTxH, common.HashLength}, } for _, s := range sizes { diff --git a/eth/api.go b/eth/api.go index 837bd65d3..122db0e18 100644 --- a/eth/api.go +++ b/eth/api.go @@ -1622,15 +1622,15 @@ func NewPublicDebugAPI(eth *Ethereum) *PublicDebugAPI { // AddressTransactions gets transactions for a given address. // Optional values include start and stop block numbers, and to/from/both value for tx/address relation. // Returns a slice of strings of transactions hashes. -func (api *PublicDebugAPI) GetAddressTransactions(address common.Address, blockStartN uint64, blockEndN uint64, toOrFrom string) (list []string, err error) { - glog.V(logger.Debug).Infoln("RPC call: debug_getAddressTransactions %s %d %d %s", address, blockStartN, blockEndN, toOrFrom) +func (api *PublicDebugAPI) GetAddressTransactions(address common.Address, blockStartN uint64, blockEndN uint64, toOrFrom string, txKindOf string) (list []string, err error) { + glog.V(logger.Debug).Infoln("RPC call: debug_getAddressTransactions %s %d %d %s %s", address, blockStartN, blockEndN, toOrFrom, txKindOf) db, inUse := api.eth.BlockChain().GetAddTxIndex() if !inUse { return nil, errors.New("addr-tx indexing not enabled") } - list = core.GetAddrTxs(db, address, blockStartN, blockEndN, toOrFrom) + list = core.GetAddrTxs(db, address, blockStartN, blockEndN, toOrFrom, txKindOf) // Since list is a slice, it can be nil, which returns 'null'. // Should return empty 'array' if no txs found. diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index d714a6d43..1d3ed603e 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -210,7 +210,7 @@ web3._extend({ new web3._extend.Method({ name: 'getAddressTransactions', call: 'debug_getAddressTransactions', - params: 4 + params: 5 }) ], properties: [] From 8f36212333d18dcca0acbcb4d5a31849b93e99dc Mon Sep 17 00:00:00 2001 From: ia Date: Sun, 21 Jan 2018 14:24:38 +0900 Subject: [PATCH 27/45] problem: nix pointer on contract tx type putting atxi solution: nil check in condit --- core/database_util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/database_util.go b/core/database_util.go index 8cf25564a..efebd140a 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -211,7 +211,7 @@ func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount // s: standard // c: contract txKindOf := []byte("s") - if to.IsEmpty() { + if to == nil || to.IsEmpty() { txKindOf = []byte("c") } From 0ba44cef89e47a413d102736e96e71d65e7f141b Mon Sep 17 00:00:00 2001 From: ia Date: Sun, 21 Jan 2018 14:27:39 +0900 Subject: [PATCH 28/45] problem: don't skip atxi for to==nil txs ... because not skipping allows indexing just for contracts solution: assign if nil --- core/database_util.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/core/database_util.go b/core/database_util.go index efebd140a..19edda16d 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -211,7 +211,10 @@ func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount // s: standard // c: contract txKindOf := []byte("s") - if to == nil || to.IsEmpty() { + if to == nil { + to = &common.Address{} + } + if to.IsEmpty() { txKindOf = []byte("c") } @@ -222,10 +225,6 @@ func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount if err := putBatch.Put(formatAddrTxBytesIndex(from.Bytes(), bn, []byte("f"), txKindOf, tx.Hash().Bytes()), nil); err != nil { return txsCount, err } - - if to == nil { - continue - } if err := putBatch.Put(formatAddrTxBytesIndex(to.Bytes(), bn, []byte("t"), txKindOf, tx.Hash().Bytes()), nil); err != nil { return txsCount, err } From cb4ed85615f3d88113e09bc5fcb1dc36bd993579 Mon Sep 17 00:00:00 2001 From: ia Date: Sun, 21 Jan 2018 23:49:49 +0900 Subject: [PATCH 29/45] problem: unhandled index db allowance solution: getter/setter fns with a guess for ok chaindb/indexdb ratio --- cmd/geth/build_atxi_cmd.go | 7 +++++++ eth/backend.go | 7 ++++++- ethdb/database.go | 10 +++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/cmd/geth/build_atxi_cmd.go b/cmd/geth/build_atxi_cmd.go index 06d4bc770..38606f69d 100644 --- a/cmd/geth/build_atxi_cmd.go +++ b/cmd/geth/build_atxi_cmd.go @@ -8,9 +8,16 @@ import ( "github.com/ethereumproject/go-ethereum/logger" "time" "github.com/ethereumproject/go-ethereum/core" + "github.com/ethereumproject/go-ethereum/ethdb" ) func buildAddrTxIndexCmd(ctx *cli.Context) error { + + ethdb.SetCacheRatio("chaindata", 0.5) + ethdb.SetHandleRatio("chaindata", 1) + ethdb.SetCacheRatio("indexes", 0.5) + ethdb.SetHandleRatio("indexes", 1) + startIndex := uint64(ctx.Int("start")) var stopIndex uint64 diff --git a/eth/backend.go b/eth/backend.go index d82402f40..915e816a8 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -227,7 +227,12 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { // Blockchain will be assigned the db and atx enabled after blockchain is intialized below. var indexesDb ethdb.Database if config.UseAddrTxIndex { - indexesDb, err = ctx.OpenDatabase("indexes", config.DatabaseCache, config.DatabaseHandles) + // TODO: these are arbitrary numbers I just made up. Optimize? + ethdb.SetCacheRatio("chaindata", 0.95) + ethdb.SetHandleRatio("chaindata", 0.95) + ethdb.SetCacheRatio("indexes", 0.05) + ethdb.SetHandleRatio("indexes", 0.05) + indexesDb, err = ctx.OpenDatabase("indexes", config.DatabaseCache, config.DatabaseCache) if err != nil { return nil, err } diff --git a/ethdb/database.go b/ethdb/database.go index 23f7d8b50..82e84a56b 100644 --- a/ethdb/database.go +++ b/ethdb/database.go @@ -33,7 +33,7 @@ import ( var OpenFileLimit = 64 -// cacheRatio specifies how the total alloted cache is distributed between the +// cacheRatio specifies how the total allotted cache is distributed between the // various system databases. var cacheRatio = map[string]float64{ "dapp": 0.0, @@ -47,6 +47,14 @@ var handleRatio = map[string]float64{ "chaindata": 1.0, } +func SetCacheRatio(db string, ratio float64) { + cacheRatio[db] = ratio +} + +func SetHandleRatio(db string, ratio float64) { + handleRatio[db] = ratio +} + type LDBDatabase struct { file string db *leveldb.DB From 55a7eff4ce185c17c02782d909658e5ee3328f4c Mon Sep 17 00:00:00 2001 From: ia Date: Mon, 22 Jan 2018 18:15:03 +0900 Subject: [PATCH 30/45] problem: no formatter for web3ext input formatter solution: add it --- internal/web3ext/web3ext.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 1d3ed603e..764cbf9a2 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -210,7 +210,8 @@ web3._extend({ new web3._extend.Method({ name: 'getAddressTransactions', call: 'debug_getAddressTransactions', - params: 5 + params: 5, + inputFormatter: [web3._extend.formatters.inputAddressFormatter, null, null, null, null] }) ], properties: [] From f2eb1ba9e5f7811c1dd93b4c15b4e382c18695df Mon Sep 17 00:00:00 2001 From: ia Date: Sun, 4 Mar 2018 15:00:22 +0900 Subject: [PATCH 31/45] problem: api should use human-friendly t|f|tf/ft interface solution: implement that nonexclusively cc @pyskell --- eth/api.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/eth/api.go b/eth/api.go index 8d0ccdea5..e813cbce6 100644 --- a/eth/api.go +++ b/eth/api.go @@ -1667,6 +1667,16 @@ func (api *PublicDebugAPI) GetAddressTransactions(address common.Address, blockS if !inUse { return nil, errors.New("addr-tx indexing not enabled") } + // Use human-friendly abbreviations, per https://github.com/ethereumproject/go-ethereum/pull/475#issuecomment-366065122 + // so 't' => to, 'f' => from, 'tf|ft' => either/both. Same pattern for txKindOf. + // _t_o OR _f_rom + if toOrFrom == "tf" || toOrFrom == "ft" { + toOrFrom = "b" + } + // _s_tandard OR _c_ontract + if txKindOf == "sc" || txKindOf == "cs" { + txKindOf = "b" + } list = core.GetAddrTxs(db, address, blockStartN, blockEndN, toOrFrom, txKindOf) From 513ad885f7485b00049246ea460efae7eb1575e7 Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 5 Apr 2018 12:42:34 -0500 Subject: [PATCH 32/45] solution: remove redundant horizontal rule from usage output --- cmd/geth/usage.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 2e5380ea4..f1645990d 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -35,7 +35,7 @@ VERSION: {{.App.Version}}{{if .CommandAndFlagGroups}} COMMANDS AND FLAGS: ------------------------------------------------------------------------- + {{range .CommandAndFlagGroups}}{{.Name}} ------------------------------------------------------------------------ {{if .Commands}}{{range .Commands}} From 02efe7fde2ba2a5c8f2fb2a83ef93a78e64ed561 Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 5 Apr 2018 12:50:07 -0500 Subject: [PATCH 33/45] gofmt: project-wide --- cmd/geth/build_atxi_cmd.go | 18 ++++++++---------- cmd/geth/flag.go | 22 +++++++++++----------- cmd/geth/flags.go | 2 +- core/blockchain_test.go | 8 +++----- core/database_util.go | 9 ++++----- core/database_util_test.go | 12 ++++++------ core/state/database.go | 1 - core/state/dump.go | 2 +- core/state/iterator.go | 1 - core/state/journal.go | 1 - core/state/state_object.go | 6 +++--- core/state/state_test.go | 1 - core/state/statedb.go | 9 ++++----- core/state/statedb_test.go | 4 ++-- core/types/log.go | 1 - eth/downloader/downloader.go | 16 ++++++++-------- eth/downloader/peer.go | 4 ++-- eth/downloader/queue.go | 2 +- ethdb/database.go | 1 - tests/state_test_util.go | 2 +- trie/encoding.go | 3 ++- trie/encoding_test.go | 2 +- trie/errors.go | 1 - trie/hasher.go | 2 +- trie/iterator.go | 1 - trie/iterator_test.go | 4 ++-- trie/node.go | 1 - trie/proof.go | 5 +++-- trie/proof_test.go | 4 ++-- trie/secure_trie.go | 4 ++-- trie/sync.go | 2 +- trie/trie.go | 2 +- trie/trie_test.go | 20 ++++++++++---------- 33 files changed, 80 insertions(+), 93 deletions(-) diff --git a/cmd/geth/build_atxi_cmd.go b/cmd/geth/build_atxi_cmd.go index 38606f69d..ad0ce1caf 100644 --- a/cmd/geth/build_atxi_cmd.go +++ b/cmd/geth/build_atxi_cmd.go @@ -1,14 +1,14 @@ package main import ( - "gopkg.in/urfave/cli.v1" - "github.com/ethereumproject/go-ethereum/logger/glog" + "github.com/ethereumproject/go-ethereum/core" "github.com/ethereumproject/go-ethereum/core/types" - "os" + "github.com/ethereumproject/go-ethereum/ethdb" "github.com/ethereumproject/go-ethereum/logger" + "github.com/ethereumproject/go-ethereum/logger/glog" + "gopkg.in/urfave/cli.v1" + "os" "time" - "github.com/ethereumproject/go-ethereum/core" - "github.com/ethereumproject/go-ethereum/ethdb" ) func buildAddrTxIndexCmd(ctx *cli.Context) error { @@ -66,7 +66,7 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { totalTxCount := uint64(0) glog.D(logger.Error).Infoln("Address/tx indexing (atxi) start:", startIndex, "stop:", stopIndex, "step:", inc, "| This may take a while.") breaker := false - for i := startIndex; i <= stopIndex; i = i+inc { + for i := startIndex; i <= stopIndex; i = i + inc { if i+inc > stopIndex { inc = stopIndex - i breaker = true @@ -106,12 +106,10 @@ func buildAddrTxIndexCmd(ctx *cli.Context) error { took := time.Since(startTime) glog.D(logger.Error).Infof(`Finished atxi-build in %v: %d blocks (~ %.2f blocks/sec), %d txs (~ %.2f txs/sec)`, took.Round(time.Second), - stopIndex - startIndex, + stopIndex-startIndex, totalBlocksF/took.Seconds(), totalTxCount, totalTxsF/took.Seconds(), - ) + ) return nil } - - diff --git a/cmd/geth/flag.go b/cmd/geth/flag.go index cc282c829..b00928b20 100644 --- a/cmd/geth/flag.go +++ b/cmd/geth/flag.go @@ -599,17 +599,17 @@ func mustMakeEthConf(ctx *cli.Context, sconf *core.SufficientChainConfig) *eth.C } ethConf := ð.Config{ - ChainConfig: sconf.ChainConfig, - Genesis: sconf.Genesis, - UseAddrTxIndex: ctx.GlobalBool(aliasableName(AddrTxIndexFlag.Name, ctx)), - FastSync: ctx.GlobalBool(aliasableName(FastSyncFlag.Name, ctx)), - BlockChainVersion: ctx.GlobalInt(aliasableName(BlockchainVersionFlag.Name, ctx)), - DatabaseCache: ctx.GlobalInt(aliasableName(CacheFlag.Name, ctx)), - DatabaseHandles: MakeDatabaseHandles(), - NetworkId: sconf.Network, - AccountManager: accman, - Etherbase: MakeEtherbase(accman, ctx), - MinerThreads: ctx.GlobalInt(aliasableName(MinerThreadsFlag.Name, ctx)), + ChainConfig: sconf.ChainConfig, + Genesis: sconf.Genesis, + UseAddrTxIndex: ctx.GlobalBool(aliasableName(AddrTxIndexFlag.Name, ctx)), + FastSync: ctx.GlobalBool(aliasableName(FastSyncFlag.Name, ctx)), + BlockChainVersion: ctx.GlobalInt(aliasableName(BlockchainVersionFlag.Name, ctx)), + DatabaseCache: ctx.GlobalInt(aliasableName(CacheFlag.Name, ctx)), + DatabaseHandles: MakeDatabaseHandles(), + NetworkId: sconf.Network, + AccountManager: accman, + Etherbase: MakeEtherbase(accman, ctx), + MinerThreads: ctx.GlobalInt(aliasableName(MinerThreadsFlag.Name, ctx)), NatSpec: ctx.GlobalBool(aliasableName(NatspecEnabledFlag.Name, ctx)), DocRoot: ctx.GlobalString(aliasableName(DocRootFlag.Name, ctx)), GasPrice: new(big.Int), diff --git a/cmd/geth/flags.go b/cmd/geth/flags.go index 84c868216..88559defa 100644 --- a/cmd/geth/flags.go +++ b/cmd/geth/flags.go @@ -99,7 +99,7 @@ var ( Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", } AddrTxIndexFlag = cli.BoolFlag{ - Name: "atxi,add-tx-index", + Name: "atxi,add-tx-index", Usage: "Toggle indexes for transactions by address. Pre-existing chaindata can be indexed with command 'atxi-build'", } // Network Split settings diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 3f7777622..50ab86b1c 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -1362,7 +1362,7 @@ func testChainTxReorgs(t *testing.T, db ethdb.Database, withATXI bool) { return } txsh1 := GetAddrTxs(db, addr1, 0, 0, "", "") - txsh2 := GetAddrTxs(db, addr2, 0, 0, "", "") + txsh2 := GetAddrTxs(db, addr2, 0, 0, "", "") txsh3 := GetAddrTxs(db, addr3, 0, 0, "", "") allAtxis := txsh1 @@ -1377,8 +1377,8 @@ func testChainTxReorgs(t *testing.T, db ethdb.Database, withATXI bool) { } // Ensure no duplicate tx hashes returned - DUPECHECK: - for i, l := range ([][]string{txsh1, txsh2, txsh3}) { +DUPECHECK: + for i, l := range [][]string{txsh1, txsh2, txsh3} { j := strings.Join(l, "") for _, h := range l { if strings.Count(j, h[:8]) > 1 { @@ -1405,8 +1405,6 @@ func testChainTxReorgs(t *testing.T, db ethdb.Database, withATXI bool) { } } - - func TestLogReorgs(t *testing.T) { // This test itself is a little bit incorrect. Below, // MakeDiehardChainConfig would make a chain configuration that diff --git a/core/database_util.go b/core/database_util.go index 71dca7092..71c383b2c 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -55,8 +55,8 @@ var ( blockHashPrefix = []byte("block-hash-") // [deprecated by the header/block split, remove eventually] - preimagePrefix = "secure-key-" // preimagePrefix + hash -> preimage - lookupPrefix = []byte("l") // lookupPrefix + hash -> transaction/receipt lookup metadata + preimagePrefix = "secure-key-" // preimagePrefix + hash -> preimage + lookupPrefix = []byte("l") // lookupPrefix + hash -> transaction/receipt lookup metadata ) // TxLookupEntry is a positional metadata to help looking up the data content of @@ -176,9 +176,9 @@ func formatAddrTxBytesIndex(address, blockNumber, direction, kindof, txhash []by // resolveAddrTxBytes resolves the index key to individual []byte values func resolveAddrTxBytes(key []byte) (address, blockNumber, direction, kindof, txhash []byte) { // prefix = key[:4] - address = key[4:24] // common.AddressLength = 20 + address = key[4:24] // common.AddressLength = 20 blockNumber = key[24:32] // uint64 via little endian - direction = key[32:33] // == key[32] (1 byte) + direction = key[32:33] // == key[32] (1 byte) kindof = key[33:34] txhash = key[34:] return @@ -744,7 +744,6 @@ func WriteTxLookupEntries(db ethdb.Putter, block *types.Block) error { return nil } - // [deprecated by the header/block split, remove eventually] // GetBlockByHashOld returns the old combined block corresponding to the hash // or nil if not found. This method is only used by the upgrade mechanism to diff --git a/core/database_util_test.go b/core/database_util_test.go index c8a6150e0..73e3b823b 100644 --- a/core/database_util_test.go +++ b/core/database_util_test.go @@ -26,6 +26,8 @@ import ( "strconv" "testing" + "crypto/ecdsa" + "encoding/binary" "github.com/ethereumproject/go-ethereum/common" "github.com/ethereumproject/go-ethereum/core/types" "github.com/ethereumproject/go-ethereum/core/vm" @@ -33,8 +35,6 @@ import ( "github.com/ethereumproject/go-ethereum/crypto/sha3" "github.com/ethereumproject/go-ethereum/ethdb" "github.com/ethereumproject/go-ethereum/rlp" - "encoding/binary" - "crypto/ecdsa" "strings" ) @@ -401,11 +401,11 @@ func TestAddrTxStorage(t *testing.T) { } out = GetAddrTxs(db, from2, 0, 0, "", "c") - if len(out) !=1 { + if len(out) != 1 { t.Errorf("got: %v, want: %v", len(out), 1) } out = GetAddrTxs(db, common.Address{}, 0, 0, "", "") - if len(out) !=1 { + if len(out) != 1 { t.Errorf("got: %v, want: %v", len(out), 1) } @@ -503,8 +503,8 @@ func TestFormatAndResolveAddrTxBytesKey(t *testing.T) { } // Ensure proper key part sizing. - sizes := []struct{ - b []byte + sizes := []struct { + b []byte expectedLen int }{ {outAddr, common.AddressLength}, diff --git a/core/state/database.go b/core/state/database.go index 1b10b2d93..30784e19d 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -152,4 +152,3 @@ func (m cachedTrie) CommitTo(dbw trie.DatabaseWriter) (common.Hash, error) { } return root, err } - diff --git a/core/state/dump.go b/core/state/dump.go index ba19418d1..0f3214618 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -25,9 +25,9 @@ import ( "sort" "sync" + "fmt" "github.com/ethereumproject/go-ethereum/common" "github.com/ethereumproject/go-ethereum/rlp" - "fmt" "github.com/ethereumproject/go-ethereum/trie" ) diff --git a/core/state/iterator.go b/core/state/iterator.go index d2a17ba4a..91ff589f3 100644 --- a/core/state/iterator.go +++ b/core/state/iterator.go @@ -151,4 +151,3 @@ func (it *NodeIterator) retrieve() bool { } return true } - diff --git a/core/state/journal.go b/core/state/journal.go index dc15861b4..d164a6360 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -138,4 +138,3 @@ func (ch addLogChange) undo(s *StateDB) { func (ch addPreimageChange) undo(s *StateDB) { delete(s.preimages, ch.hash) } - diff --git a/core/state/state_object.go b/core/state/state_object.go index 13d8f0c3b..20b541460 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -24,10 +24,10 @@ import ( "github.com/ethereumproject/go-ethereum/common" "github.com/ethereumproject/go-ethereum/crypto" - "github.com/ethereumproject/go-ethereum/rlp" - "github.com/ethereumproject/go-ethereum/trie" "github.com/ethereumproject/go-ethereum/logger" "github.com/ethereumproject/go-ethereum/logger/glog" + "github.com/ethereumproject/go-ethereum/rlp" + "github.com/ethereumproject/go-ethereum/trie" ) var emptyCodeHash = crypto.Keccak256(nil) @@ -425,4 +425,4 @@ func (self *StateObject) ForEachStorage(cb func(key, value common.Hash) bool) { cb(key, common.BytesToHash(it.Value)) } } -} \ No newline at end of file +} diff --git a/core/state/state_test.go b/core/state/state_test.go index 6db8cdd15..cd0dcc317 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -231,4 +231,3 @@ func compareStateObjects(so0, so1 *StateObject, t *testing.T) { t.Fatalf("Deleted mismatch: have %v, want %v", so0.deleted, so1.deleted) } } - diff --git a/core/state/statedb.go b/core/state/statedb.go index ef8a34a1a..bc46ea010 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -24,12 +24,12 @@ import ( "sync" "github.com/ethereumproject/go-ethereum/common" + "github.com/ethereumproject/go-ethereum/core/vm" "github.com/ethereumproject/go-ethereum/crypto" "github.com/ethereumproject/go-ethereum/logger" "github.com/ethereumproject/go-ethereum/logger/glog" "github.com/ethereumproject/go-ethereum/rlp" "github.com/ethereumproject/go-ethereum/trie" - "github.com/ethereumproject/go-ethereum/core/vm" ) // The starting nonce determines the default nonce when new accounts are being @@ -62,9 +62,9 @@ type revision struct { // * Contracts // * Accounts type StateDB struct { - db Database - trie Trie - pastTries []*trie.SecureTrie + db Database + trie Trie + pastTries []*trie.SecureTrie // DB error. // State objects are used by the consensus core and VM which are @@ -616,4 +616,3 @@ func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common } } } - diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index c6bd6512c..4a8bee569 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -29,9 +29,9 @@ import ( "testing/quick" "github.com/ethereumproject/go-ethereum/common" + "github.com/ethereumproject/go-ethereum/core/vm" "github.com/ethereumproject/go-ethereum/ethdb" "gopkg.in/check.v1" - "github.com/ethereumproject/go-ethereum/core/vm" ) // Tests that updating a state trie does not leak any database writes prior to @@ -421,4 +421,4 @@ func (s *StateSuite) TestTouchDelete(c *check.C) { if len(s.state.stateObjectsDirty) != 0 { c.Fatal("expected no dirty state object") } -} \ No newline at end of file +} diff --git a/core/types/log.go b/core/types/log.go index 8d112fbe2..b90fd9b29 100644 --- a/core/types/log.go +++ b/core/types/log.go @@ -134,4 +134,3 @@ func (l *LogForStorage) DecodeRLP(s *rlp.Stream) error { } return err } - diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 996f12a79..f61dfa5d9 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -32,9 +32,9 @@ import ( "github.com/ethereumproject/go-ethereum/core/types" "github.com/ethereumproject/go-ethereum/ethdb" "github.com/ethereumproject/go-ethereum/event" - "github.com/ethereumproject/go-ethereum/metrics" "github.com/ethereumproject/go-ethereum/logger" "github.com/ethereumproject/go-ethereum/logger/glog" + "github.com/ethereumproject/go-ethereum/metrics" ) const ( @@ -65,12 +65,12 @@ var ( maxHeadersProcess = 2048 // Number of header download results to import at once into the chain maxResultsProcess = 2048 // Number of content download results to import at once into the chain - fsHeaderCheckFrequency = 100 // Verification frequency of the downloaded headers during fast sync - fsHeaderSafetyNet = 2048 // Number of headers to discard in case a chain violation is detected - fsHeaderForceVerify = 24 // Number of headers to verify before and after the pivot to accept it - fsPivotInterval = 512 // Number of headers out of which to randomize the pivot point - fsMinFullBlocks = 1024 // Number of blocks to retrieve fully even in fast sync - fsCriticalTrials uint32 = 10 // Number of times to retry in the cricical section before bailing + fsHeaderCheckFrequency = 100 // Verification frequency of the downloaded headers during fast sync + fsHeaderSafetyNet = 2048 // Number of headers to discard in case a chain violation is detected + fsHeaderForceVerify = 24 // Number of headers to verify before and after the pivot to accept it + fsPivotInterval = 512 // Number of headers out of which to randomize the pivot point + fsMinFullBlocks = 1024 // Number of blocks to retrieve fully even in fast sync + fsCriticalTrials uint32 = 10 // Number of times to retry in the cricical section before bailing ) var ( @@ -129,7 +129,7 @@ type Downloader struct { stateDB ethdb.Database fsPivotLock *types.Header // Pivot header on critical section entry (cannot change between retries) - fsPivotFails uint32 // Number of fast sync failures in the critical section + fsPivotFails uint32 // Number of fast sync failures in the critical section rttEstimate uint64 // Round trip time to target for download requests rttConfidence uint64 // Confidence in the estimated RTT (unit: millionths to allow atomic ops) diff --git a/eth/downloader/peer.go b/eth/downloader/peer.go index 70b165578..298756bd3 100644 --- a/eth/downloader/peer.go +++ b/eth/downloader/peer.go @@ -345,8 +345,8 @@ func (p *peer) String() string { // peerSet represents the collection of active peer participating in the chain // download procedure. type peerSet struct { - peers map[string]*peer - lock sync.RWMutex + peers map[string]*peer + lock sync.RWMutex } // newPeerSet creates a new peer set top track the active download sources. diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index ffcc26ca1..da963440d 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -27,10 +27,10 @@ import ( "github.com/ethereumproject/go-ethereum/common" "github.com/ethereumproject/go-ethereum/core/types" + "github.com/ethereumproject/go-ethereum/logger" "github.com/ethereumproject/go-ethereum/logger/glog" "github.com/ethereumproject/go-ethereum/metrics" "gopkg.in/karalabe/cookiejar.v2/collections/prque" - "github.com/ethereumproject/go-ethereum/logger" ) var blockCacheLimit = 8192 // Maximum number of blocks to cache before throttling the download diff --git a/ethdb/database.go b/ethdb/database.go index 16b00584b..5857bce14 100644 --- a/ethdb/database.go +++ b/ethdb/database.go @@ -98,7 +98,6 @@ func NewLDBDatabase(file string, cache int, handles int) (*LDBDatabase, error) { }, nil } - // Path returns the path to the database directory. func (db *LDBDatabase) Path() string { return db.file diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 9b7986279..e0a435917 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -243,7 +243,7 @@ func RunState(ruleSet RuleSet, db ethdb.Database, statedb *state.StateDB, env, t if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || core.IsGasLimitErr(err) { statedb.RevertToSnapshot(snapshot) } - statedb.CommitTo(db,false) + statedb.CommitTo(db, false) return ret, vmenv.state.Logs(), vmenv.Gas, err } diff --git a/trie/encoding.go b/trie/encoding.go index 6db8dd00d..e96a786e4 100644 --- a/trie/encoding.go +++ b/trie/encoding.go @@ -15,6 +15,7 @@ // along with the go-ethereum library. If not, see . package trie + // Trie keys are dealt with in three distinct encodings: // // KEYBYTES encoding contains the actual key and nothing else. This encoding is the @@ -110,4 +111,4 @@ func prefixLen(a, b []byte) int { // hasTerm returns whether a hex key has the terminator flag. func hasTerm(s []byte) bool { return len(s) > 0 && s[len(s)-1] == 16 -} \ No newline at end of file +} diff --git a/trie/encoding_test.go b/trie/encoding_test.go index 75e886272..97d8da136 100644 --- a/trie/encoding_test.go +++ b/trie/encoding_test.go @@ -17,8 +17,8 @@ package trie import ( - "testing" "bytes" + "testing" ) func TestHexCompact(t *testing.T) { diff --git a/trie/errors.go b/trie/errors.go index 65c6d46c3..5d16d8b30 100644 --- a/trie/errors.go +++ b/trie/errors.go @@ -52,4 +52,3 @@ type MissingNodeError struct { func (err *MissingNodeError) Error() string { return fmt.Sprintf("missing trie node %x (path %x)", err.NodeHash, err.Path) } - diff --git a/trie/hasher.go b/trie/hasher.go index 1b9fc813c..cd2d7b5d6 100644 --- a/trie/hasher.go +++ b/trie/hasher.go @@ -227,4 +227,4 @@ func (h *hasher) store(n node, db DatabaseWriter, force bool) (node, error) { return hash, err } return hash, nil -} \ No newline at end of file +} diff --git a/trie/iterator.go b/trie/iterator.go index 31a01b5bc..af30efb11 100644 --- a/trie/iterator.go +++ b/trie/iterator.go @@ -24,7 +24,6 @@ import ( "github.com/ethereumproject/go-ethereum/common" ) - // Iterator is a key-value trie iterator that traverses a Trie. type Iterator struct { nodeIt NodeIterator diff --git a/trie/iterator_test.go b/trie/iterator_test.go index 5ecb2feef..ab811d35e 100644 --- a/trie/iterator_test.go +++ b/trie/iterator_test.go @@ -19,10 +19,10 @@ package trie import ( "testing" + "bytes" + "fmt" "github.com/ethereumproject/go-ethereum/common" "github.com/ethereumproject/go-ethereum/ethdb" - "fmt" - "bytes" "math/rand" ) diff --git a/trie/node.go b/trie/node.go index adfc3be6e..2b559c36d 100644 --- a/trie/node.go +++ b/trie/node.go @@ -201,7 +201,6 @@ func decodeRef(buf []byte, cachegen uint16) (node, []byte, error) { } } - // wraps a decoding error with information about the path to the // invalid child node (for debugging encoding issues). type decodeError struct { diff --git a/trie/proof.go b/trie/proof.go index 2fc0be62b..eea29e11c 100644 --- a/trie/proof.go +++ b/trie/proof.go @@ -20,11 +20,12 @@ import ( "bytes" "fmt" - "github.com/ethereumproject/go-ethereum/rlp" - "github.com/ethereumproject/go-ethereum/crypto" "github.com/ethereumproject/go-ethereum/common" + "github.com/ethereumproject/go-ethereum/crypto" "github.com/ethereumproject/go-ethereum/logger/glog" + "github.com/ethereumproject/go-ethereum/rlp" ) + // Prove constructs a merkle proof for key. The result contains all // encoded nodes on the path to the value at key. The value itself is // also included in the last node and can be retrieved by verifying diff --git a/trie/proof_test.go b/trie/proof_test.go index f83581f95..882156676 100644 --- a/trie/proof_test.go +++ b/trie/proof_test.go @@ -24,8 +24,8 @@ import ( "time" "github.com/ethereumproject/go-ethereum/common" - "github.com/ethereumproject/go-ethereum/ethdb" "github.com/ethereumproject/go-ethereum/crypto" + "github.com/ethereumproject/go-ethereum/ethdb" ) func init() { @@ -161,4 +161,4 @@ func randBytes(n int) []byte { r := make([]byte, n) crand.Read(r) return r -} \ No newline at end of file +} diff --git a/trie/secure_trie.go b/trie/secure_trie.go index a8c438145..813883f3c 100644 --- a/trie/secure_trie.go +++ b/trie/secure_trie.go @@ -17,8 +17,8 @@ package trie import ( - "github.com/ethereumproject/go-ethereum/common" "fmt" + "github.com/ethereumproject/go-ethereum/common" "github.com/ethereumproject/go-ethereum/logger/glog" ) @@ -214,4 +214,4 @@ func (t *SecureTrie) getSecKeyCache() map[string][]byte { t.secKeyCache = make(map[string][]byte) } return t.secKeyCache -} \ No newline at end of file +} diff --git a/trie/sync.go b/trie/sync.go index cee208e63..b89906c78 100644 --- a/trie/sync.go +++ b/trie/sync.go @@ -38,7 +38,7 @@ type request struct { hash common.Hash // Hash of the node data content to retrieve data []byte // Data content of the node, cached until all subtrees complete object *node // Target node to populate with retrieved data (hashnode originally) - raw bool // Whether this is a raw entry (code) or a trie node + raw bool // Whether this is a raw entry (code) or a trie node parents []*request // Parent state nodes referencing this entry (notify all upon completion) depth int // Depth level within the trie the node is located to prioritise DFS diff --git a/trie/trie.go b/trie/trie.go index 763648660..9ac48cccf 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -23,8 +23,8 @@ import ( "github.com/ethereumproject/go-ethereum/common" "github.com/ethereumproject/go-ethereum/crypto/sha3" - "github.com/rcrowley/go-metrics" "github.com/ethereumproject/go-ethereum/logger/glog" + "github.com/rcrowley/go-metrics" ) var ( diff --git a/trie/trie_test.go b/trie/trie_test.go index 3253dfa82..e175bb71d 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -18,21 +18,21 @@ package trie import ( "bytes" - "testing" + "encoding/binary" + "errors" "fmt" "github.com/davecgh/go-spew/spew" "github.com/ethereumproject/go-ethereum/common" + "github.com/ethereumproject/go-ethereum/crypto" "github.com/ethereumproject/go-ethereum/ethdb" - "encoding/binary" - "reflect" - "testing/quick" - "os" + "github.com/ethereumproject/go-ethereum/rlp" + "io/ioutil" "math/big" "math/rand" - "errors" - "io/ioutil" - "github.com/ethereumproject/go-ethereum/crypto" - "github.com/ethereumproject/go-ethereum/rlp" + "os" + "reflect" + "testing" + "testing/quick" ) func init() { @@ -606,4 +606,4 @@ func updateString(trie *Trie, k, v string) { func deleteString(trie *Trie, k string) { trie.Delete([]byte(k)) -} \ No newline at end of file +} From a29921a95e71f42378a1fee865c6ecb1318933b8 Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 5 Apr 2018 13:01:34 -0500 Subject: [PATCH 34/45] problem: merge missed atxi command/flag additions solution: add them --- cmd/geth/build_atxi_cmd.go | 29 +++++++++++++++++++++++++++++ cmd/geth/main.go | 1 + cmd/geth/usage.go | 2 ++ 3 files changed, 32 insertions(+) diff --git a/cmd/geth/build_atxi_cmd.go b/cmd/geth/build_atxi_cmd.go index ad0ce1caf..5c181a84c 100644 --- a/cmd/geth/build_atxi_cmd.go +++ b/cmd/geth/build_atxi_cmd.go @@ -11,6 +11,35 @@ import ( "time" ) +var buildAddrTxIndexCommand = cli.Command{ + Action: buildAddrTxIndexCmd, + Name: "atxi-build", + Usage: "Generate index for transactions by address", + Description: ` + Builds an index for transactions by address. + The command is idempotent; it will not hurt to run multiple times on the same range. + If run without --start flag, the command makes use of a persistent placeholder, so you can + run the command on multiple occasions and pick up indexing progress where the last session + left off. + To enable address-transaction indexing during block sync and import, use the '--atxi' flag. + `, + Flags: []cli.Flag{ + cli.IntFlag{ + Name: "start", + Usage: "Block number at which to begin building index", + }, + cli.IntFlag{ + Name: "stop", + Usage: "Block number at which to stop building index", + }, + cli.IntFlag{ + Name: "step", + Usage: "Step increment for batching. Higher number requires more mem, but may be faster", + Value: 10000, + }, + }, +} + func buildAddrTxIndexCmd(ctx *cli.Context) error { ethdb.SetCacheRatio("chaindata", 0.5) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index b10280115..69866b0bd 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -136,6 +136,7 @@ func makeCLIApp() (app *cli.App) { gpuBenchCommand, versionCommand, makeMlogDocCommand, + buildAddrTxIndexCommand, } app.Flags = []cli.Flag{ diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index f1645990d..902c170c4 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -88,12 +88,14 @@ var AppHelpFlagAndCommandGroups = []flagGroup{ Commands: []cli.Command{ accountCommand, walletCommand, + buildAddrTxIndexCommand, }, Flags: []cli.Flag{ KeyStoreDirFlag, UnlockedAccountFlag, PasswordFileFlag, AccountsIndexFlag, + AddrTxIndexFlag, }, }, { From 54773f630ddd81a0fac9c4918b7d21e189444eb5 Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 5 Apr 2018 13:11:56 -0500 Subject: [PATCH 35/45] solution: add comment to explain cache ratio sharing --- cmd/geth/build_atxi_cmd.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/geth/build_atxi_cmd.go b/cmd/geth/build_atxi_cmd.go index 5c181a84c..b9314df58 100644 --- a/cmd/geth/build_atxi_cmd.go +++ b/cmd/geth/build_atxi_cmd.go @@ -42,6 +42,8 @@ var buildAddrTxIndexCommand = cli.Command{ func buildAddrTxIndexCmd(ctx *cli.Context) error { + // Divide global cache availability equally between chaindata (pre-existing blockdata) and + // address-transaction database. This ratio is arbitrary and could potentially be optimized or delegated to be user configurable. ethdb.SetCacheRatio("chaindata", 0.5) ethdb.SetHandleRatio("chaindata", 1) ethdb.SetCacheRatio("indexes", 0.5) From f5adee263991cd6bb32598496a759a4fb5462bb7 Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 5 Apr 2018 13:24:58 -0500 Subject: [PATCH 36/45] problem: unused addr.IsEmpty func solution: refactor to use common addr == zero-value fn --- accounts/cache.go | 4 ++-- accounts/cachedb.go | 4 ++-- common/registrar/registrar.go | 6 +++--- eth/backend.go | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/accounts/cache.go b/accounts/cache.go index 3b532a495..7cba83596 100644 --- a/accounts/cache.go +++ b/accounts/cache.go @@ -145,7 +145,7 @@ func (ac *addrCache) find(a Account) (Account, error) { return matches[i], nil } } - if (a.Address == common.Address{}) { + if a.Address.IsEmpty() { return Account{}, ErrNoMatch } } @@ -239,7 +239,7 @@ func (ac *addrCache) scan() ([]Account, error) { switch { case err != nil: glog.V(logger.Debug).Infof("can't decode key %s: %v", path, err) - case (keyJSON.Address == common.Address{}): + case keyJSON.Address.IsEmpty(): glog.V(logger.Debug).Infof("can't decode key %s: missing or zero address", path) default: addrs = append(addrs, Account{Address: keyJSON.Address, File: path}) diff --git a/accounts/cachedb.go b/accounts/cachedb.go index 0a4b978be..35910bf67 100644 --- a/accounts/cachedb.go +++ b/accounts/cachedb.go @@ -236,7 +236,7 @@ func (cdb *cacheDB) find(a Account) (Account, error) { return acc, e } // no other possible way - if (a.Address == common.Address{}) { + if a.Address.IsEmpty() { return Account{}, ErrNoMatch } } @@ -498,7 +498,7 @@ func processKeyFile(wg *sync.WaitGroup, path string, fi os.FileInfo, i int, numF case err != nil: glog.V(logger.Debug).Infof("(%v/%v) can't decode key %s: %v", i, numFiles, path, err) errs <- err - case (keyJSON.Address == common.Address{}): + case keyJSON.Address.IsEmpty(): glog.V(logger.Debug).Infof("(%v/%v) can't decode key %s: missing or zero address", i, numFiles, path) errs <- fmt.Errorf("(%v/%v) can't decode key %s: missing or zero address", i, numFiles, path) default: diff --git a/common/registrar/registrar.go b/common/registrar/registrar.go index 84b5ec7be..51c89d84a 100644 --- a/common/registrar/registrar.go +++ b/common/registrar/registrar.go @@ -112,7 +112,7 @@ func (self *Registrar) SetGlobalRegistrar(namereg string, addr common.Address) ( return } if zero.MatchString(GlobalRegistrarAddr) { - if (addr == common.Address{}) { + if addr.IsEmpty() { err = fmt.Errorf("GlobalRegistrar address not found and sender for creation not given") return } else { @@ -142,7 +142,7 @@ func (self *Registrar) SetHashReg(hashreg string, addr common.Address) (txhash s HashRegAddr = "0x" + res[len(res)-40:] } if err != nil || zero.MatchString(HashRegAddr) { - if (addr == common.Address{}) { + if addr.IsEmpty() { err = fmt.Errorf("HashReg address not found and sender for creation not given") return } @@ -177,7 +177,7 @@ func (self *Registrar) SetUrlHint(urlhint string, addr common.Address) (txhash s UrlHintAddr = "0x" + res[len(res)-40:] } if err != nil || zero.MatchString(UrlHintAddr) { - if (addr == common.Address{}) { + if addr.IsEmpty() { err = fmt.Errorf("UrlHint address not found and sender for creation not given") return } diff --git a/eth/backend.go b/eth/backend.go index d38568a48..0d0e3f96a 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -385,7 +385,7 @@ func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) { func (s *Ethereum) Etherbase() (eb common.Address, err error) { eb = s.etherbase - if (eb == common.Address{}) { + if eb.IsEmpty() { firstAccount, err := s.AccountManager().AccountByIndex(0) eb = firstAccount.Address if err != nil { From e465063a0f1f62bdaf2ef2f09a44c103501d1a84 Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 5 Apr 2018 13:26:55 -0500 Subject: [PATCH 37/45] problem: (refactor syntax) ugly 'removals' name collision solution: removeRemovals -> deleteRemovalsFn --- core/blockchain.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 93274cd62..6f0ccf85d 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -795,7 +795,7 @@ func (bc *BlockChain) SetHead(head uint64) error { } removals := [][]byte{} - removeRemovals := func(removals [][]byte) { + deleteRemovalsFn := func(removals [][]byte) { for _, r := range removals { if e := ldb.Delete(r); e != nil { glog.Fatal(e) @@ -815,7 +815,7 @@ func (bc *BlockChain) SetHead(head uint64) error { // Prevent removals from getting too massive in case it's a big rollback // 100000 is a guess at a big but not-too-big memory allowance if len(removals) > 100000 { - removeRemovals(removals) + deleteRemovalsFn(removals) removals = [][]byte{} } } @@ -824,7 +824,7 @@ func (bc *BlockChain) SetHead(head uint64) error { if e := it.Error(); e != nil { return e } - removeRemovals(removals) + deleteRemovalsFn(removals) } bc.mu.Unlock() From 483701466b343792b948c7ecbf13fb6e78c19977 Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 5 Apr 2018 13:50:54 -0500 Subject: [PATCH 38/45] solution: optimize key slice with known length --- core/database_util.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/database_util.go b/core/database_util.go index 71c383b2c..70eadba6c 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -164,7 +164,8 @@ func formatAddrTxIterator(address common.Address) (iteratorPrefix []byte) { // The values for these arguments should be of determinate length and format, see test TestFormatAndResolveAddrTxBytesKey // for example. func formatAddrTxBytesIndex(address, blockNumber, direction, kindof, txhash []byte) (key []byte) { - key = txAddressIndexPrefix + key = make([]byte, 0, 66) // 66 is the total capacity of the key = prefix(4)+addr(20)+blockNumber(8)+dir(1)+kindof(1)+txhash(32) + key = append(key, txAddressIndexPrefix...) key = append(key, address...) key = append(key, blockNumber...) key = append(key, direction...) From 42bf79535e57d7303bc3d6cffb13f8dee5e63401 Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 5 Apr 2018 13:52:58 -0500 Subject: [PATCH 39/45] solution: merge to addr check conditional for eloquence --- core/database_util.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/database_util.go b/core/database_util.go index 70eadba6c..4fb9aec47 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -223,10 +223,8 @@ func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount // s: standard // c: contract txKindOf := []byte("s") - if to == nil { + if to == nil || to.IsEmpty() { to = &common.Address{} - } - if to.IsEmpty() { txKindOf = []byte("c") } From 95f000f1c2a746ce0e15ce415bc6bf38f691b01c Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 5 Apr 2018 13:59:15 -0500 Subject: [PATCH 40/45] solution: add comment explaining atxi db cache ratio for sync (vs build) --- eth/backend.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eth/backend.go b/eth/backend.go index 0d0e3f96a..02d1cae91 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -230,10 +230,12 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { } // Initialize indexes db if enabled - // Blockchain will be assigned the db and atx enabled after blockchain is intialized below. + // Blockchain will be assigned the db and atx enabled after blockchain is initialized below. var indexesDb ethdb.Database if config.UseAddrTxIndex { // TODO: these are arbitrary numbers I just made up. Optimize? + // The reason these numbers are different than the atxi-build command is because for "appending" (vs. building) + // the atxi database should require far fewer resources since application performance is limited primarily by block import (chaindata db). ethdb.SetCacheRatio("chaindata", 0.95) ethdb.SetHandleRatio("chaindata", 0.95) ethdb.SetCacheRatio("indexes", 0.05) From 32505e236d76074fb0a8bee5f07a42f74fd76523 Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 5 Apr 2018 15:06:29 -0500 Subject: [PATCH 41/45] problem: some addresses have lots of txs solution: implement pagination and reverse params for atxi api This seems like a useful thing for most applications... - reverse because most relevant transactions are latest txs - pagination because some account have tens- or hundreds- of thousands of txs --- core/blockchain_test.go | 20 ++++++++++---------- core/database_util.go | 22 ++++++++++++++++++++-- core/database_util_test.go | 33 ++++++++++++++++++++++++--------- eth/api.go | 4 ++-- internal/web3ext/web3ext.go | 4 ++-- 5 files changed, 58 insertions(+), 25 deletions(-) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 50ab86b1c..b0673bd96 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -980,23 +980,23 @@ func TestFastVsFullChainsATXI(t *testing.T) { } } - out := GetAddrTxs(db, addr1, 0, 0, "", "") + out := GetAddrTxs(db, addr1, 0, 0, "", "", -1, -1, false) if len(out) != 3 { t.Errorf("[%d] got: %v, want: %v", i, len(out), 3) } - out = GetAddrTxs(db, addr1, 0, 0, "from", "") + out = GetAddrTxs(db, addr1, 0, 0, "from", "", -1, -1, false) if len(out) != 2 { t.Errorf("[%d] got: %v, want: %v", i, len(out), 2) } - out = GetAddrTxs(db, addr1, 0, 0, "to", "") + out = GetAddrTxs(db, addr1, 0, 0, "to", "", -1, -1, false) if len(out) != 1 { t.Errorf("[%d] got: %v, want: %v", i, len(out), 1) } - out = GetAddrTxs(db, addr2, 0, 0, "", "") + out = GetAddrTxs(db, addr2, 0, 0, "", "", -1, -1, false) if len(out) != 3 { t.Errorf("[%d] got: %v, want: %v", i, len(out), 3) } - out = GetAddrTxs(db, addr2, 3, 3, "", "") + out = GetAddrTxs(db, addr2, 3, 3, "", "", -1, -1, false) if len(out) != 1 { t.Errorf("[%d] got: %v, want: %v", i, len(out), 1) } @@ -1074,14 +1074,14 @@ func TestRmAddrTx(t *testing.T) { t.Fatalf("failed to process block %d: %v", n, err) } - out := GetAddrTxs(db, addr1, 0, 0, "", "") + out := GetAddrTxs(db, addr1, 0, 0, "", "", -1, -1, false) if len(out) != 3 { t.Errorf("got: %v, want: %v", len(out), 3) } if err := RmAddrTx(db, t1); err != nil { t.Fatal(err) } - out = GetAddrTxs(db, addr1, 0, 0, "", "") + out = GetAddrTxs(db, addr1, 0, 0, "", "", -1, -1, false) if len(out) != 2 { t.Errorf("got: %v, want: %v", len(out), 2) } @@ -1361,9 +1361,9 @@ func testChainTxReorgs(t *testing.T, db ethdb.Database, withATXI bool) { if !withATXI { return } - txsh1 := GetAddrTxs(db, addr1, 0, 0, "", "") - txsh2 := GetAddrTxs(db, addr2, 0, 0, "", "") - txsh3 := GetAddrTxs(db, addr3, 0, 0, "", "") + txsh1 := GetAddrTxs(db, addr1, 0, 0, "", "", -1, -1, false) + txsh2 := GetAddrTxs(db, addr2, 0, 0, "", "", -1, -1, false) + txsh3 := GetAddrTxs(db, addr3, 0, 0, "", "", -1, -1, false) allAtxis := txsh1 allAtxis = append(allAtxis, txsh2...) diff --git a/core/database_util.go b/core/database_util.go index 4fb9aec47..7a92b817c 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -243,7 +243,7 @@ func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount } // GetAddrTxs gets the indexed transactions for a given account address. -func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, blockEndN uint64, direction string, kindof string) []string { +func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, blockEndN uint64, direction string, kindof string, paginationStart int, paginationEnd int, reverse bool) []string { if len(direction) > 0 && !strings.Contains("btf", direction[:1]) { glog.Fatal("Address transactions list signature requires direction param to be empty string or [b|t|f] prefix (eg. both, to, or from)") } @@ -303,7 +303,25 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b glog.Fatalln(e) } - return hashes + handleSorting := func(s []string) []string { + if len(s) <= 1 { + return s + } + if reverse { + for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } + } + if paginationStart < 0 { + paginationStart = 0 + } + if paginationEnd < 0 { + paginationEnd = len(s) + } + return s[paginationStart:paginationEnd] + } + + return handleSorting(hashes) } // RmAddrTx removes all atxi indexes for a given tx in case of a transaction removal, eg. diff --git a/core/database_util_test.go b/core/database_util_test.go index 73e3b823b..b32386741 100644 --- a/core/database_util_test.go +++ b/core/database_util_test.go @@ -383,9 +383,9 @@ func TestAddrTxStorage(t *testing.T) { for it.Next() { count++ //// Debugger -- it's kinda nice to see what the indexes look like - ad, bn, tf, sc, txh := resolveAddrTxBytes(it.Key()) - addr, blockn, direc, ko, txhash := common.BytesToAddress(ad), binary.LittleEndian.Uint64(bn), string(tf), string(sc), common.BytesToHash(txh) - t.Log(addr.Hex(), blockn, direc, ko, txhash.Hex()) + //ad, bn, tf, sc, txh := resolveAddrTxBytes(it.Key()) + //addr, blockn, direc, ko, txhash := common.BytesToAddress(ad), binary.LittleEndian.Uint64(bn), string(tf), string(sc), common.BytesToHash(txh) + //t.Log(addr.Hex(), blockn, direc, ko, txhash.Hex()) } it.Release() if e := it.Error(); e != nil { @@ -395,21 +395,36 @@ func TestAddrTxStorage(t *testing.T) { t.Errorf("want: %v, got: %v", 7, count) } - out := GetAddrTxs(db, from2, 0, 0, "", "") + out := GetAddrTxs(db, from2, 0, 0, "", "", -1, -1, false) if len(out) != 3 { t.Errorf("want: %v, got: %v", 3, len(out)) } - out = GetAddrTxs(db, from2, 0, 0, "", "c") + // Test pagination and reverse + outReverse := GetAddrTxs(db, from2, 0, 0, "", "", -1, -1, true) + if len(outReverse) != 3 { + t.Errorf("want: %v, got: %v", 3, len(outReverse)) + } + // reverse + if out[0] != outReverse[2] || out[1] != outReverse[1] || out[2] != outReverse[0] { + t.Errorf("got: %v, want: %v", outReverse, out) + } + // pagination + outPag := GetAddrTxs(db, from2, 0, 0, "", "", 1, -1, false) + if len(outPag) != 2 { + t.Errorf("got: %v, want: %v", len(outPag), 2) + } + + out = GetAddrTxs(db, from2, 0, 0, "", "c", -1, -1, false) if len(out) != 1 { t.Errorf("got: %v, want: %v", len(out), 1) } - out = GetAddrTxs(db, common.Address{}, 0, 0, "", "") + out = GetAddrTxs(db, common.Address{}, 0, 0, "", "", -1, -1, false) if len(out) != 1 { t.Errorf("got: %v, want: %v", len(out), 1) } - out = GetAddrTxs(db, from1, 314, 314, "", "") + out = GetAddrTxs(db, from1, 314, 314, "", "", -1, -1, false) if len(out) != 1 { t.Errorf("want: %v, got: %v", 1, len(out)) } else { @@ -432,7 +447,7 @@ func TestAddrTxStorage(t *testing.T) { } } - out = GetAddrTxs(db, from2to, 314, 314, "to", "") + out = GetAddrTxs(db, from2to, 314, 314, "to", "", -1, -1, false) if len(out) != 1 { t.Errorf("want: %v, got: %v", 1, len(out)) } else { @@ -459,7 +474,7 @@ func TestAddrTxStorage(t *testing.T) { t.Errorf("got: %v, want: %v", f, from2) } } - out = GetAddrTxs(db, from2to, 314, 314, "from", "") + out = GetAddrTxs(db, from2to, 314, 314, "from", "", -1, -1, false) if len(out) != 0 { t.Errorf("want: %v, got: %v", 0, len(out)) } diff --git a/eth/api.go b/eth/api.go index 90fd9da64..4acc44b06 100644 --- a/eth/api.go +++ b/eth/api.go @@ -1660,7 +1660,7 @@ func NewPublicDebugAPI(eth *Ethereum) *PublicDebugAPI { // AddressTransactions gets transactions for a given address. // Optional values include start and stop block numbers, and to/from/both value for tx/address relation. // Returns a slice of strings of transactions hashes. -func (api *PublicDebugAPI) GetAddressTransactions(address common.Address, blockStartN uint64, blockEndN uint64, toOrFrom string, txKindOf string) (list []string, err error) { +func (api *PublicDebugAPI) GetAddressTransactions(address common.Address, blockStartN uint64, blockEndN uint64, toOrFrom string, txKindOf string, pagStart, pagEnd int, reverse bool) (list []string, err error) { glog.V(logger.Debug).Infoln("RPC call: debug_getAddressTransactions %s %d %d %s %s", address, blockStartN, blockEndN, toOrFrom, txKindOf) db, inUse := api.eth.BlockChain().GetAddTxIndex() @@ -1678,7 +1678,7 @@ func (api *PublicDebugAPI) GetAddressTransactions(address common.Address, blockS txKindOf = "b" } - list = core.GetAddrTxs(db, address, blockStartN, blockEndN, toOrFrom, txKindOf) + list = core.GetAddrTxs(db, address, blockStartN, blockEndN, toOrFrom, txKindOf, pagStart, pagEnd, reverse) // Since list is a slice, it can be nil, which returns 'null'. // Should return empty 'array' if no txs found. diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 7eeca4209..9ac00974c 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -210,8 +210,8 @@ web3._extend({ new web3._extend.Method({ name: 'getAddressTransactions', call: 'debug_getAddressTransactions', - params: 5, - inputFormatter: [web3._extend.formatters.inputAddressFormatter, null, null, null, null] + params: 8, + inputFormatter: [web3._extend.formatters.inputAddressFormatter, null, null, null, null, null, null, null] }) ], properties: [] From d69ac3b8ea4de00d525b03029471b6c9c17cd08e Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 5 Apr 2018 16:15:05 -0500 Subject: [PATCH 42/45] problem: must ensure atxis are ordered by block number solution: implement sort.Sort interface for custom sortable struct --- core/database_util.go | 49 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/core/database_util.go b/core/database_util.go index 7a92b817c..273a6b2f9 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -28,6 +28,7 @@ import ( "github.com/ethereumproject/go-ethereum/logger" "github.com/ethereumproject/go-ethereum/logger/glog" "github.com/ethereumproject/go-ethereum/rlp" + "sort" "strings" ) @@ -242,7 +243,37 @@ func putBlockAddrTxsToBatch(putBatch ethdb.Batch, block *types.Block) (txsCount return txsCount, nil } +type atxi struct { + blockN uint64 + tx string +} +type sortableAtxis []atxi + +// Len implements sort.Sort interface. +func (s sortableAtxis) Len() int { + return len(s) +} + +// Less implements sort.Sort interface. +// By default newer transactions by blockNumber are first. +func (s sortableAtxis) Less(i, j int) bool { + return s[i].blockN < s[j].blockN +} + +// Swap implements sort.Sort interface. +func (s sortableAtxis) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} +func (s sortableAtxis) TxStrings() []string { + var out = make([]string, 0, len(s)) + for _, str := range s { + out = append(out, str.tx) + } + return out +} + // GetAddrTxs gets the indexed transactions for a given account address. +// 'reverse' means "oldest first" func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, blockEndN uint64, direction string, kindof string, paginationStart int, paginationEnd int, reverse bool) []string { if len(direction) > 0 && !strings.Contains("btf", direction[:1]) { glog.Fatal("Address transactions list signature requires direction param to be empty string or [b|t|f] prefix (eg. both, to, or from)") @@ -274,17 +305,21 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b prefix := ethdb.NewBytesPrefix(formatAddrTxIterator(address)) it := ldb.NewIteratorRange(prefix) + var atxis sortableAtxis + for it.Next() { key := it.Key() _, blockNum, torf, k, txh := resolveAddrTxBytes(key) + bn := binary.LittleEndian.Uint64(blockNum) + // If atxi is smaller than blockstart, skip - if blockStartN > 0 && binary.LittleEndian.Uint64(blockNum) < blockStartN { + if blockStartN > 0 && bn < blockStartN { continue } // If atxi is greater than blockend, skip - if blockEndN > 0 && binary.LittleEndian.Uint64(blockNum) > blockEndN { + if blockEndN > 0 && bn > blockEndN { continue } // Ensure matching direction if spec'd @@ -294,19 +329,23 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b // Ensure filter for/agnostic transaction kind of (contract, standard, both) if wantKindOf != 'b' && wantKindOf != k[0] { continue + } + if len(hashes) > 0 { + } tx := common.ToHex(txh) - hashes = append(hashes, tx) + atxis = append(atxis, atxi{blockN: bn, tx: tx}) } it.Release() if e := it.Error(); e != nil { glog.Fatalln(e) } - handleSorting := func(s []string) []string { + handleSorting := func(s sortableAtxis) sortableAtxis { if len(s) <= 1 { return s } + sort.Sort(s) // newest txs (by blockNumber) latest if reverse { for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { s[i], s[j] = s[j], s[i] @@ -321,7 +360,7 @@ func GetAddrTxs(db ethdb.Database, address common.Address, blockStartN uint64, b return s[paginationStart:paginationEnd] } - return handleSorting(hashes) + return handleSorting(atxis).TxStrings() } // RmAddrTx removes all atxi indexes for a given tx in case of a transaction removal, eg. From 6ac5a9a0466bcc44134dda3131f1d2aeeff974f5 Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 5 Apr 2018 16:18:10 -0500 Subject: [PATCH 43/45] solution: fix variable shadowing and empty slice by struct init --- core/blockchain.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 6f0ccf85d..e0f6e4dfc 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -794,9 +794,9 @@ func (bc *BlockChain) SetHead(head uint64) error { glog.Fatal("could not cast indexes db to level db") } - removals := [][]byte{} - deleteRemovalsFn := func(removals [][]byte) { - for _, r := range removals { + var removals [][]byte + deleteRemovalsFn := func(rs [][]byte) { + for _, r := range rs { if e := ldb.Delete(r); e != nil { glog.Fatal(e) } From efc2a42dffb70fafd9b303682ade3b3345966233 Mon Sep 17 00:00:00 2001 From: ia Date: Thu, 5 Apr 2018 17:09:53 -0500 Subject: [PATCH 44/45] problem: atxis returned are backward solution: sort.Sort interface Less method should use be backwards since we want higher block numbers first --- core/database_util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/database_util.go b/core/database_util.go index 273a6b2f9..b72c45cfd 100644 --- a/core/database_util.go +++ b/core/database_util.go @@ -257,7 +257,7 @@ func (s sortableAtxis) Len() int { // Less implements sort.Sort interface. // By default newer transactions by blockNumber are first. func (s sortableAtxis) Less(i, j int) bool { - return s[i].blockN < s[j].blockN + return s[i].blockN > s[j].blockN } // Swap implements sort.Sort interface. From 2ec2a97dfe9ece36b8e9fe95688666541fe99cb2 Mon Sep 17 00:00:00 2001 From: ia Date: Wed, 11 Apr 2018 14:52:19 -0400 Subject: [PATCH 45/45] solution: move API debug_ -> geth_ This creates a new public RPC/JS API module 'geth_'. --- eth/api.go | 20 ++++++++++++++++---- eth/backend.go | 5 +++++ internal/web3ext/web3ext.go | 17 +++++++++++++++++ rpc/server.go | 2 +- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/eth/api.go b/eth/api.go index 4acc44b06..1cdcf5fa6 100644 --- a/eth/api.go +++ b/eth/api.go @@ -1647,20 +1647,20 @@ func (api *PrivateAdminAPI) ImportChain(file string) (bool, error) { // PublicDebugAPI is the collection of Etheruem APIs exposed over the public // debugging endpoint. -type PublicDebugAPI struct { +type PublicGethAPI struct { eth *Ethereum } // NewPublicDebugAPI creates a new API definition for the public debug methods // of the Ethereum service. -func NewPublicDebugAPI(eth *Ethereum) *PublicDebugAPI { - return &PublicDebugAPI{eth: eth} +func NewPublicGethAPI(eth *Ethereum) *PublicGethAPI { + return &PublicGethAPI{eth: eth} } // AddressTransactions gets transactions for a given address. // Optional values include start and stop block numbers, and to/from/both value for tx/address relation. // Returns a slice of strings of transactions hashes. -func (api *PublicDebugAPI) GetAddressTransactions(address common.Address, blockStartN uint64, blockEndN uint64, toOrFrom string, txKindOf string, pagStart, pagEnd int, reverse bool) (list []string, err error) { +func (api *PublicGethAPI) GetAddressTransactions(address common.Address, blockStartN uint64, blockEndN uint64, toOrFrom string, txKindOf string, pagStart, pagEnd int, reverse bool) (list []string, err error) { glog.V(logger.Debug).Infoln("RPC call: debug_getAddressTransactions %s %d %d %s %s", address, blockStartN, blockEndN, toOrFrom, txKindOf) db, inUse := api.eth.BlockChain().GetAddTxIndex() @@ -1688,6 +1688,18 @@ func (api *PublicDebugAPI) GetAddressTransactions(address common.Address, blockS return list, nil } +// PublicDebugAPI is the collection of Etheruem APIs exposed over the public +// debugging endpoint. +type PublicDebugAPI struct { + eth *Ethereum +} + +// NewPublicDebugAPI creates a new API definition for the public debug methods +// of the Ethereum service. +func NewPublicDebugAPI(eth *Ethereum) *PublicDebugAPI { + return &PublicDebugAPI{eth: eth} +} + // DumpBlock retrieves the entire state of the database at a given block. // TODO: update to be able to dump for specific addresses? func (api *PublicDebugAPI) DumpBlock(number uint64) (state.Dump, error) { diff --git a/eth/backend.go b/eth/backend.go index 02d1cae91..a5904cead 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -377,6 +377,11 @@ func (s *Ethereum) APIs() []rpc.API { Namespace: "admin", Version: "1.0", Service: ethreg.NewPrivateRegistarAPI(s.chainConfig, s.blockchain, s.chainDb, s.txPool, s.accountManager), + }, { + Namespace: "geth", + Version: "1.0", + Service: NewPublicGethAPI(s), + Public: true, }, } } diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 9ac00974c..ce9ea34ed 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -27,6 +27,7 @@ var Modules = map[string]string{ "rpc": RPC_JS, "shh": Shh_JS, "txpool": TxPool_JS, + "geth": Geth_JS, } const Admin_JS = ` @@ -149,6 +150,22 @@ web3._extend({ }); ` +const Geth_JS = ` +web3._extend({ + property: 'geth', + methods: + [ + new web3._extend.Method({ + name: 'getAddressTransactions', + call: 'geth_getAddressTransactions', + params: 8, + inputFormatter: [web3._extend.formatters.inputAddressFormatter, null, null, null, null, null, null, null] + }) + ], + properties: [] +}); +` + const Debug_JS = ` web3._extend({ property: 'debug', diff --git a/rpc/server.go b/rpc/server.go index 7bece588d..9f4af3b9a 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -36,7 +36,7 @@ const ( notificationBufferSize = 10000 // max buffered notifications before codec is closed MetadataApi = "rpc" - DefaultIPCApis = "admin,debug,eth,miner,net,personal,shh,txpool,web3" + DefaultIPCApis = "admin,debug,eth,miner,net,personal,shh,txpool,web3,geth" DefaultHTTPApis = "eth,net,web3" )