+++ /dev/null
-package blockchain
-
-import (
- "os"
- "path/filepath"
-)
-
-// HomeDirFromEnvironment returns the directory to use
-// for reading config and storing variable data.
-// It returns $BYTOM_HOME,
-// or, if that is empty, $HOME/.chaincore.
-func HomeDirFromEnvironment() string {
- if s := os.Getenv("BYTOM_HOME"); s != "" {
- return s
- }
- return filepath.Join(os.Getenv("HOME"), ".bytom")
-}
+++ /dev/null
-package txfeed
-
-import (
- "context"
- //"database/sql"
- // "fmt"
- // "github.com/bytom/errors"
-)
-
-// Query queries the Chain Core for txfeeds matching the query.
-func /* (t *Tracker)*/ Query(ctx context.Context, after string, limit int) ([]*TxFeed, string, error) {
- /* const baseQ = `
- SELECT id, alias, filter, after FROM txfeeds
- WHERE ($1='' OR id < $1) ORDER BY id DESC LIMIT %d
- `
- rows, err := t.DB.QueryContext(ctx, fmt.Sprintf(baseQ, limit), after)
- if err != nil {
- return nil, "", errors.Wrap(err, "executing txfeeds query")
- }
- defer rows.Close()
-
- txfeeds := make([]*TxFeed, 0, limit)
- for rows.Next() {
- var (
- feed TxFeed
- alias sql.NullString
- )
- err := rows.Scan(&feed.ID, &alias, &feed.Filter, &feed.After)
- if err != nil {
- return nil, "", errors.Wrap(err, "scanning txfeed row")
- }
-
- if alias.Valid {
- feed.Alias = &alias.String
- }
- after = feed.ID
- txfeeds = append(txfeeds, &feed)
- }
- err = rows.Err()
- if err != nil {
- return nil, "", errors.Wrap(err)
- }
- return txfeeds, after, nil
- */
- after = "qwertyu"
- return nil, after, nil
-}
"bufio"
"bytes"
"compress/gzip"
- "crypto/rand"
"encoding/hex"
"io"
"os"
"strings"
"testing"
-
- "github.com/agl/ed25519/edwards25519"
)
type zeroReader struct{}
return len(buf), nil
}
-func TestUnmarshalMarshal(t *testing.T) {
- pub, _, _ := GenerateKey(rand.Reader)
-
- var A edwards25519.ExtendedGroupElement
- if !A.FromBytes(pub) {
- t.Fatalf("ExtendedGroupElement.FromBytes failed")
- }
-
- var pub2 [32]byte
- A.ToBytes(&pub2)
-
- if *pub != pub2 {
- t.Errorf("FromBytes(%v)->ToBytes does not round-trip, got %x\n", *pub, pub2)
- }
-}
-
func TestSignVerify(t *testing.T) {
var zero zeroReader
public, private, _ := GenerateKey(zero)
+++ /dev/null
-# Changelog
-
-## 0.4.1 (October 27, 2017)
-
-This release removes support for bcrypt as it was merged too soon without an upgrade plan
-for existing keys.
-
-REVERTS THE FOLLOWING COMMITS:
-
-- Parameterize and lower bcrypt cost - dfc4cdd2d71513e4a9922d679c74f36357c4c862
-- Upgrade keys to use bcrypt with salts (#38) - 8e7f0e7701f92206679ad093d013b9b162427631
-
-## 0.4.0 (October 27, 2017)
-
-BREAKING CHANGES:
-
-- `keys`: use bcrypt plus salt
-
-FEATURES:
-
-- add support for signing via Ledger Nano
-
-IMPROVEMENTS:
-
-- linting and comments
-
-## 0.3.0 (September 22, 2017)
-
-BREAKING CHANGES:
-
-- Remove `cmd` and `keys/tx` packages altogether: move it to the cosmos-sdk
-- `cryptostore.Generator` takes a secret
-- Remove `String()` from `Signature` interface
-
-FEATURES:
-
-- `keys`: add CRC16 error correcting code
-
-IMPROVEMENTS:
-
-- Allow no passwords on keys for development convenience
-
-
-## 0.2.1 (June 21, 2017)
-
-- Improve keys command
- - No password prompts in non-interactive mode (echo 'foobar' | keys new foo)
- - Added support for seed phrases
- - Seed phrase now returned on `keys new`
- - Add `keys restore` to restore private key from key phrase
- - Checksum to verify typos in the seed phrase (rather than just a useless key)
- - Add `keys delete` to remove a key if needed
-
-## 0.2.0 (May 18, 2017)
-
-BREAKING CHANGES:
-
-- [hd] The following functions no longer take a `coin string` as argument: `ComputeAddress`, `AddrFromPubKeyBytes`, `ComputeAddressForPrivKey`, `ComputeWIF`, `WIFFromPrivKeyBytes`
-- Changes to `PrivKey`, `PubKey`, and `Signature` (denoted `Xxx` below):
- - interfaces are renamed `XxxInner`, and are not for use outside the package, though they must be exposed for sake of serialization.
- - `Xxx` is now a struct that wraps the corresponding `XxxInner` interface
-
-FEATURES:
-
-- `github.com/tendermint/go-keys -> github.com/tendermint/go-crypto/keys` - command and lib for generating and managing encrypted keys
-- [hd] New function `WIFFromPrivKeyBytes(privKeyBytes []byte, compress bool) string`
-- Changes to `PrivKey`, `PubKey`, and `Signature` (denoted `Xxx` below):
- - Expose a new method `Unwrap() XxxInner` on the `Xxx` struct which returns the corresponding `XxxInner` interface
- - Expose a new method `Wrap() Xxx` on the `XxxInner` interface which returns the corresponding `Xxx` struct
-
-IMPROVEMENTS:
-
-- Update to use new `tmlibs` repository
-
-## 0.1.0 (April 14, 2017)
-
-Initial release
-
+++ /dev/null
-Tendermint Go-Crypto
-Copyright (C) 2015 Tendermint
-
-
-
- Apache License
- Version 2.0, January 2004
- https://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+++ /dev/null
-.PHONEY: all test install get_vendor_deps ensure_tools codegen wordlist
-
-GOTOOLS = \
- github.com/Masterminds/glide \
- github.com/jteeuwen/go-bindata/go-bindata \
- github.com/alecthomas/gometalinter
-
-REPO:=github.com/tendermint/go-crypto
-
-all: get_vendor_deps metalinter_test test
-
-test:
- go test -p 1 `glide novendor`
-
-get_vendor_deps: ensure_tools
- @rm -rf vendor/
- @echo "--> Running glide install"
- @glide install
-
-ensure_tools:
- go get $(GOTOOLS)
-
-wordlist:
- go-bindata -ignore ".*\.go" -o keys/wordlist/wordlist.go -pkg "wordlist" keys/wordlist/...
-
-prepgen: install
- go install ./vendor/github.com/btcsuite/btcutil/base58
- go install ./vendor/github.com/stretchr/testify/assert
- go install ./vendor/github.com/stretchr/testify/require
- go install ./vendor/golang.org/x/crypto/bcrypt
-
-codegen:
- @echo "--> regenerating all interface wrappers"
- @gen
- @echo "Done!"
-
-metalinter: ensure_tools
- @gometalinter --install
- gometalinter --vendor --deadline=600s --enable-all --disable=lll ./...
-
-metalinter_test: ensure_tools
- @gometalinter --install
- gometalinter --vendor --deadline=600s --disable-all \
- --enable=deadcode \
- --enable=gas \
- --enable=goconst \
- --enable=gocyclo \
- --enable=gosimple \
- --enable=ineffassign \
- --enable=interfacer \
- --enable=maligned \
- --enable=megacheck \
- --enable=misspell \
- --enable=safesql \
- --enable=staticcheck \
- --enable=structcheck \
- --enable=unconvert \
- --enable=unused \
- --enable=vetshadow \
- --enable=vet \
- --enable=varcheck \
- ./...
-
- #--enable=dupl \
- #--enable=errcheck \
- #--enable=goimports \
- #--enable=golint \ <== comments on anything exported
- #--enable=gotype \
- #--enable=unparam \
+++ /dev/null
-# go-crypto [![GoDoc](https://godoc.org/github.com/tendermint/go-crypto?status.svg)](https://godoc.org/github.com/tendermint/go-crypto)
-
-go-crypto is the cryptographic package adapted for Tendermint's uses
-
-## Importing it
-`import "github.com/tendermint/go-crypto"`
\ No newline at end of file
+++ /dev/null
-package crypto
-
-import (
- "bytes"
- "io/ioutil"
-
- . "github.com/tendermint/tmlibs/common"
- "golang.org/x/crypto/openpgp/armor"
-)
-
-func EncodeArmor(blockType string, headers map[string]string, data []byte) string {
- buf := new(bytes.Buffer)
- w, err := armor.Encode(buf, blockType, headers)
- if err != nil {
- PanicSanity("Error encoding ascii armor: " + err.Error())
- }
- _, err = w.Write(data)
- if err != nil {
- PanicSanity("Error encoding ascii armor: " + err.Error())
- }
- err = w.Close()
- if err != nil {
- PanicSanity("Error encoding ascii armor: " + err.Error())
- }
- return buf.String()
-}
-
-func DecodeArmor(armorStr string) (blockType string, headers map[string]string, data []byte, err error) {
- buf := bytes.NewBufferString(armorStr)
- block, err := armor.Decode(buf)
- if err != nil {
- return "", nil, nil, err
- }
- data, err = ioutil.ReadAll(block.Body)
- if err != nil {
- return "", nil, nil, err
- }
- return block.Type, block.Header, data, nil
-}
+++ /dev/null
-package crypto
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestSimpleArmor(t *testing.T) {
- blockType := "MINT TEST"
- data := []byte("somedata")
- armorStr := EncodeArmor(blockType, nil, data)
-
- // Decode armorStr and test for equivalence.
- blockType2, _, data2, err := DecodeArmor(armorStr)
- require.Nil(t, err, "%+v", err)
- assert.Equal(t, blockType, blockType2)
- assert.Equal(t, data, data2)
-}
+++ /dev/null
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package bcrypt
-
-import "encoding/base64"
-
-const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
-
-var bcEncoding = base64.NewEncoding(alphabet)
-
-func base64Encode(src []byte) []byte {
- n := bcEncoding.EncodedLen(len(src))
- dst := make([]byte, n)
- bcEncoding.Encode(dst, src)
- for dst[n-1] == '=' {
- n--
- }
- return dst[:n]
-}
-
-func base64Decode(src []byte) ([]byte, error) {
- numOfEquals := 4 - (len(src) % 4)
- for i := 0; i < numOfEquals; i++ {
- src = append(src, '=')
- }
-
- dst := make([]byte, bcEncoding.DecodedLen(len(src)))
- n, err := bcEncoding.Decode(dst, src)
- if err != nil {
- return nil, err
- }
- return dst[:n], nil
-}
+++ /dev/null
-package bcrypt
-
-// MODIFIED BY TENDERMINT TO EXPOSE NONCE
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package bcrypt implements Provos and Mazières's bcrypt adaptive hashing
-// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
-
-// The code is a port of Provos and Mazières's C implementation.
-import (
- "crypto/subtle"
- "errors"
- "fmt"
- "strconv"
-
- "golang.org/x/crypto/blowfish"
-)
-
-const (
- MinCost int = 4 // the minimum allowable cost as passed in to GenerateFromPassword
- MaxCost int = 31 // the maximum allowable cost as passed in to GenerateFromPassword
- DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword
-)
-
-// The error returned from CompareHashAndPassword when a password and hash do
-// not match.
-var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password")
-
-// The error returned from CompareHashAndPassword when a hash is too short to
-// be a bcrypt hash.
-var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password")
-
-// The error returned from CompareHashAndPassword when a hash was created with
-// a bcrypt algorithm newer than this implementation.
-type HashVersionTooNewError byte
-
-func (hv HashVersionTooNewError) Error() string {
- return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion)
-}
-
-// The error returned from CompareHashAndPassword when a hash starts with something other than '$'
-type InvalidHashPrefixError byte
-
-func (ih InvalidHashPrefixError) Error() string {
- return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih))
-}
-
-type InvalidCostError int
-
-func (ic InvalidCostError) Error() string {
- return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost)) // nolint: unconvert
-}
-
-const (
- majorVersion = '2'
- minorVersion = 'a'
- maxSaltSize = 16
- maxCryptedHashSize = 23
- encodedSaltSize = 22
- encodedHashSize = 31
- minHashSize = 59
-)
-
-// magicCipherData is an IV for the 64 Blowfish encryption calls in
-// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
-var magicCipherData = []byte{
- 0x4f, 0x72, 0x70, 0x68,
- 0x65, 0x61, 0x6e, 0x42,
- 0x65, 0x68, 0x6f, 0x6c,
- 0x64, 0x65, 0x72, 0x53,
- 0x63, 0x72, 0x79, 0x44,
- 0x6f, 0x75, 0x62, 0x74,
-}
-
-type hashed struct {
- hash []byte
- salt []byte
- cost int // allowed range is MinCost to MaxCost
- major byte
- minor byte
-}
-
-// GenerateFromPassword returns the bcrypt hash of the password at the given
-// cost. If the cost given is less than MinCost, the cost will be set to
-// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
-// to compare the returned hashed password with its cleartext version.
-func GenerateFromPassword(salt []byte, password []byte, cost int) ([]byte, error) {
- if len(salt) != maxSaltSize {
- return nil, fmt.Errorf("Salt len must be %v", maxSaltSize)
- }
- p, err := newFromPassword(salt, password, cost)
- if err != nil {
- return nil, err
- }
- return p.Hash(), nil
-}
-
-// CompareHashAndPassword compares a bcrypt hashed password with its possible
-// plaintext equivalent. Returns nil on success, or an error on failure.
-func CompareHashAndPassword(hashedPassword, password []byte) error {
- p, err := newFromHash(hashedPassword)
- if err != nil {
- return err
- }
-
- otherHash, err := bcrypt(password, p.cost, p.salt)
- if err != nil {
- return err
- }
-
- otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor}
- if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 {
- return nil
- }
-
- return ErrMismatchedHashAndPassword
-}
-
-// Cost returns the hashing cost used to create the given hashed
-// password. When, in the future, the hashing cost of a password system needs
-// to be increased in order to adjust for greater computational power, this
-// function allows one to establish which passwords need to be updated.
-func Cost(hashedPassword []byte) (int, error) {
- p, err := newFromHash(hashedPassword)
- if err != nil {
- return 0, err
- }
- return p.cost, nil
-}
-
-func newFromPassword(salt []byte, password []byte, cost int) (*hashed, error) {
- if cost < MinCost {
- cost = DefaultCost
- }
- p := new(hashed)
- p.major = majorVersion
- p.minor = minorVersion
-
- err := checkCost(cost)
- if err != nil {
- return nil, err
- }
- p.cost = cost
-
- p.salt = base64Encode(salt)
- hash, err := bcrypt(password, p.cost, p.salt)
- if err != nil {
- return nil, err
- }
- p.hash = hash
- return p, err
-}
-
-func newFromHash(hashedSecret []byte) (*hashed, error) {
- if len(hashedSecret) < minHashSize {
- return nil, ErrHashTooShort
- }
- p := new(hashed)
- n, err := p.decodeVersion(hashedSecret)
- if err != nil {
- return nil, err
- }
- hashedSecret = hashedSecret[n:]
- n, err = p.decodeCost(hashedSecret)
- if err != nil {
- return nil, err
- }
- hashedSecret = hashedSecret[n:]
-
- // The "+2" is here because we'll have to append at most 2 '=' to the salt
- // when base64 decoding it in expensiveBlowfishSetup().
- p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
- copy(p.salt, hashedSecret[:encodedSaltSize])
-
- hashedSecret = hashedSecret[encodedSaltSize:]
- p.hash = make([]byte, len(hashedSecret))
- copy(p.hash, hashedSecret)
-
- return p, nil
-}
-
-func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
- cipherData := make([]byte, len(magicCipherData))
- copy(cipherData, magicCipherData)
-
- c, err := expensiveBlowfishSetup(password, uint32(cost), salt)
- if err != nil {
- return nil, err
- }
-
- for i := 0; i < 24; i += 8 {
- for j := 0; j < 64; j++ {
- c.Encrypt(cipherData[i:i+8], cipherData[i:i+8])
- }
- }
-
- // Bug compatibility with C bcrypt implementations. We only encode 23 of
- // the 24 bytes encrypted.
- hsh := base64Encode(cipherData[:maxCryptedHashSize])
- return hsh, nil
-}
-
-func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
-
- csalt, err := base64Decode(salt)
- if err != nil {
- return nil, err
- }
-
- // Bug compatibility with C bcrypt implementations. They use the trailing
- // NULL in the key string during expansion.
- ckey := append(key, 0)
-
- c, err := blowfish.NewSaltedCipher(ckey, csalt)
- if err != nil {
- return nil, err
- }
-
- var i, rounds uint64
- rounds = 1 << cost
- for i = 0; i < rounds; i++ {
- blowfish.ExpandKey(ckey, c)
- blowfish.ExpandKey(csalt, c)
- }
-
- return c, nil
-}
-
-func (p *hashed) Hash() []byte {
- arr := make([]byte, 60)
- arr[0] = '$'
- arr[1] = p.major
- n := 2
- if p.minor != 0 {
- arr[2] = p.minor
- n = 3
- }
- arr[n] = '$'
- n += 1
- copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
- n += 2
- arr[n] = '$'
- n += 1
- copy(arr[n:], p.salt)
- n += encodedSaltSize
- copy(arr[n:], p.hash)
- n += encodedHashSize
- return arr[:n]
-}
-
-func (p *hashed) decodeVersion(sbytes []byte) (int, error) {
- if sbytes[0] != '$' {
- return -1, InvalidHashPrefixError(sbytes[0])
- }
- if sbytes[1] > majorVersion {
- return -1, HashVersionTooNewError(sbytes[1])
- }
- p.major = sbytes[1]
- n := 3
- if sbytes[2] != '$' {
- p.minor = sbytes[2]
- n++
- }
- return n, nil
-}
-
-// sbytes should begin where decodeVersion left off.
-func (p *hashed) decodeCost(sbytes []byte) (int, error) {
- cost, err := strconv.Atoi(string(sbytes[0:2]))
- if err != nil {
- return -1, err
- }
- err = checkCost(cost)
- if err != nil {
- return -1, err
- }
- p.cost = cost
- return 3, nil
-}
-
-func (p *hashed) String() string {
- return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor)
-}
-
-func checkCost(cost int) error {
- if cost < MinCost || cost > MaxCost {
- return InvalidCostError(cost)
- }
- return nil
-}
+++ /dev/null
-machine:
- environment:
- GOPATH: /home/ubuntu/.go_workspace
- PROJECT_PARENT_PATH: "$GOPATH/src/github.com/$CIRCLE_PROJECT_USERNAME"
- PROJECT_PATH: $GOPATH/src/github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME
- GO15VENDOREXPERIMENT: 1
- hosts:
- circlehost: 127.0.0.1
- localhost: 127.0.0.1
-
-dependencies:
- override:
- - mkdir -p "$PROJECT_PARENT_PATH"
- - ln -sf "$HOME/$CIRCLE_PROJECT_REPONAME/" "$PROJECT_PATH"
- post:
- - go version
-
-test:
- override:
- - "go version"
- - "cd $PROJECT_PATH && make all"
+++ /dev/null
-/*
-go-crypto is a customized/convenience cryptography package
-for supporting Tendermint.
-
-It wraps select functionality of equivalent functions in the
-Go standard library, for easy usage with our libraries.
-
-Keys:
-
-All key generation functions return an instance of the PrivKey interface
-which implements methods
-
- AssertIsPrivKeyInner()
- Bytes() []byte
- Sign(msg []byte) Signature
- PubKey() PubKey
- Equals(PrivKey) bool
- Wrap() PrivKey
-
-From the above method we can:
-a) Retrieve the public key if needed
-
- pubKey := key.PubKey()
-
-For example:
- privKey, err := crypto.GenPrivKeyEd25519()
- if err != nil {
- ...
- }
- pubKey := privKey.PubKey()
- ...
- // And then you can use the private and public key
- doSomething(privKey, pubKey)
-
-
-We also provide hashing wrappers around algorithms:
-
-Sha256
- sum := crypto.Sha256([]byte("This is Tendermint"))
- fmt.Printf("%x\n", sum)
-
-Ripemd160
- sum := crypto.Ripemd160([]byte("This is consensus"))
- fmt.Printf("%x\n", sum)
-*/
-package crypto
-
-// TODO: Add more docs in here
+++ /dev/null
-/*
-package cryptostore maintains everything needed for doing public-key signing and
-key management in software, based on the go-crypto library from tendermint.
-
-It is flexible, and allows the user to provide a key generation algorithm
-(currently Ed25519 or Secp256k1), an encoder to passphrase-encrypt our keys
-when storing them (currently SecretBox from NaCl), and a method to persist
-the keys (currently FileStorage like ssh, or MemStorage for tests).
-It should be relatively simple to write your own implementation of these
-interfaces to match your specific security requirements.
-
-Note that the private keys are never exposed outside the package, and the
-interface of Manager could be implemented by an HSM in the future for
-enhanced security. It would require a completely different implementation
-however.
-
-This Manager aims to implement Signer and KeyManager interfaces, along
-with some extensions to allow importing/exporting keys and updating the
-passphrase.
-
-Encoder and Generator implementations are currently in this package,
-keys.Storage implementations exist as subpackages of
-keys/storage
-*/
-package cryptostore
+++ /dev/null
-package cryptostore
-
-import (
- crypto "github.com/tendermint/go-crypto"
- keys "github.com/tendermint/go-crypto/keys"
-)
-
-// encryptedStorage needs passphrase to get private keys
-type encryptedStorage struct {
- coder Encoder
- store keys.Storage
-}
-
-func (es encryptedStorage) Put(name, pass string, key crypto.PrivKey) error {
- secret, err := es.coder.Encrypt(key, pass)
- if err != nil {
- return err
- }
-
- ki := info(name, key)
- return es.store.Put(name, secret, ki)
-}
-
-func (es encryptedStorage) Get(name, pass string) (crypto.PrivKey, keys.Info, error) {
- secret, info, err := es.store.Get(name)
- if err != nil {
- return crypto.PrivKey{}, info, err
- }
- key, err := es.coder.Decrypt(secret, pass)
- return key, info, err
-}
-
-func (es encryptedStorage) List() (keys.Infos, error) {
- return es.store.List()
-}
-
-func (es encryptedStorage) Delete(name string) error {
- return es.store.Delete(name)
-}
-
-// info hardcodes the encoding of keys
-func info(name string, key crypto.PrivKey) keys.Info {
- pub := key.PubKey()
- return keys.Info{
- Name: name,
- Address: pub.Address(),
- PubKey: pub,
- }
-}
+++ /dev/null
-package cryptostore
-
-import (
- "github.com/pkg/errors"
- crypto "github.com/tendermint/go-crypto"
-)
-
-var (
- // SecretBox uses the algorithm from NaCL to store secrets securely
- SecretBox Encoder = secretbox{}
- // Noop doesn't do any encryption, should only be used in test code
- Noop Encoder = noop{}
-)
-
-// Encoder is used to encrypt any key with a passphrase for storage.
-//
-// This should use a well-designed symetric encryption algorithm
-type Encoder interface {
- Encrypt(key crypto.PrivKey, pass string) ([]byte, error)
- Decrypt(data []byte, pass string) (crypto.PrivKey, error)
-}
-
-func secret(passphrase string) []byte {
- // TODO: Sha256(Bcrypt(passphrase))
- return crypto.Sha256([]byte(passphrase))
-}
-
-type secretbox struct{}
-
-func (e secretbox) Encrypt(key crypto.PrivKey, pass string) ([]byte, error) {
- if pass == "" {
- return key.Bytes(), nil
- }
- s := secret(pass)
- cipher := crypto.EncryptSymmetric(key.Bytes(), s)
- return cipher, nil
-}
-
-func (e secretbox) Decrypt(data []byte, pass string) (key crypto.PrivKey, err error) {
- private := data
- if pass != "" {
- s := secret(pass)
- private, err = crypto.DecryptSymmetric(data, s)
- if err != nil {
- return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase")
- }
- }
- key, err = crypto.PrivKeyFromBytes(private)
- return key, errors.Wrap(err, "Invalid Passphrase")
-}
-
-type noop struct{}
-
-func (n noop) Encrypt(key crypto.PrivKey, pass string) ([]byte, error) {
- return key.Bytes(), nil
-}
-
-func (n noop) Decrypt(data []byte, pass string) (crypto.PrivKey, error) {
- return crypto.PrivKeyFromBytes(data)
-}
+++ /dev/null
-package cryptostore_test
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-
- cmn "github.com/tendermint/tmlibs/common"
-
- "github.com/tendermint/go-crypto/keys/cryptostore"
-)
-
-func TestNoopEncoder(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
- noop := cryptostore.Noop
-
- key, err := cryptostore.GenEd25519.Generate(cmn.RandBytes(16))
- require.NoError(err)
- key2, err := cryptostore.GenSecp256k1.Generate(cmn.RandBytes(16))
- require.NoError(err)
-
- b, err := noop.Encrypt(key, "encode")
- require.Nil(err)
- assert.NotEmpty(b)
-
- b2, err := noop.Encrypt(key2, "encode")
- require.Nil(err)
- assert.NotEmpty(b2)
- assert.NotEqual(b, b2)
-
- // note the decode with a different password works - not secure!
- pk, err := noop.Decrypt(b, "decode")
- require.Nil(err)
- require.NotNil(pk)
- assert.Equal(key, pk)
-
- pk2, err := noop.Decrypt(b2, "kggugougp")
- require.Nil(err)
- require.NotNil(pk2)
- assert.Equal(key2, pk2)
-}
-
-func TestSecretBox(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
- enc := cryptostore.SecretBox
-
- key, err := cryptostore.GenEd25519.Generate(cmn.RandBytes(16))
- require.NoError(err)
- pass := "some-special-secret"
-
- b, err := enc.Encrypt(key, pass)
- require.Nil(err)
- assert.NotEmpty(b)
-
- // decoding with a different pass is an error
- pk, err := enc.Decrypt(b, "decode")
- require.NotNil(err)
- require.True(pk.Empty())
-
- // but decoding with the same passphrase gets us our key
- pk, err = enc.Decrypt(b, pass)
- require.Nil(err)
- assert.Equal(key, pk)
-}
-
-func TestSecretBoxNoPass(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
- enc := cryptostore.SecretBox
-
- key, rerr := cryptostore.GenEd25519.Generate(cmn.RandBytes(16))
- require.NoError(rerr)
-
- cases := []struct {
- encode string
- decode string
- valid bool
- }{
- {"foo", "foo", true},
- {"foo", "food", false},
- {"", "", true},
- {"", "a", false},
- {"a", "", false},
- }
-
- for i, tc := range cases {
- b, err := enc.Encrypt(key, tc.encode)
- require.Nil(err, "%d: %+v", i, err)
- assert.NotEmpty(b, "%d", i)
-
- pk, err := enc.Decrypt(b, tc.decode)
- if tc.valid {
- require.Nil(err, "%d: %+v", i, err)
- assert.Equal(key, pk, "%d", i)
- } else {
- require.NotNil(err, "%d", i)
- }
- }
-
- // now let's make sure raw bytes also work...
- b := key.Bytes()
- pk, err := enc.Decrypt(b, "")
- require.Nil(err, "%+v", err)
- assert.Equal(key, pk)
-}
+++ /dev/null
-package cryptostore
-
-import (
- "github.com/pkg/errors"
- crypto "github.com/tendermint/go-crypto"
- "github.com/tendermint/go-crypto/nano"
-)
-
-var (
- // GenEd25519 produces Ed25519 private keys
- GenEd25519 Generator = GenFunc(genEd25519)
- // GenSecp256k1 produces Secp256k1 private keys
- GenSecp256k1 Generator = GenFunc(genSecp256)
- // GenLedgerEd25519 used Ed25519 keys stored on nano ledger s with cosmos app
- GenLedgerEd25519 Generator = GenFunc(genLedgerEd25519)
-)
-
-// Generator determines the type of private key the keystore creates
-type Generator interface {
- Generate(secret []byte) (crypto.PrivKey, error)
-}
-
-// GenFunc is a helper to transform a function into a Generator
-type GenFunc func(secret []byte) (crypto.PrivKey, error)
-
-func (f GenFunc) Generate(secret []byte) (crypto.PrivKey, error) {
- return f(secret)
-}
-
-func genEd25519(secret []byte) (crypto.PrivKey, error) {
- key := crypto.GenPrivKeyEd25519FromSecret(secret).Wrap()
- return key, nil
-}
-
-func genSecp256(secret []byte) (crypto.PrivKey, error) {
- key := crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap()
- return key, nil
-}
-
-// secret is completely ignored for the ledger...
-// just for interface compatibility
-func genLedgerEd25519(secret []byte) (crypto.PrivKey, error) {
- return nano.NewPrivKeyLedgerEd25519Ed25519()
-}
-
-type genInvalidByte struct {
- typ byte
-}
-
-func (g genInvalidByte) Generate(secret []byte) (crypto.PrivKey, error) {
- err := errors.Errorf("Cannot generate keys for algorithm: %X", g.typ)
- return crypto.PrivKey{}, err
-}
-
-type genInvalidAlgo struct {
- algo string
-}
-
-func (g genInvalidAlgo) Generate(secret []byte) (crypto.PrivKey, error) {
- err := errors.Errorf("Cannot generate keys for algorithm: %s", g.algo)
- return crypto.PrivKey{}, err
-}
-
-func getGenerator(algo string) Generator {
- switch algo {
- case crypto.NameEd25519:
- return GenEd25519
- case crypto.NameSecp256k1:
- return GenSecp256k1
- case nano.NameLedgerEd25519:
- return GenLedgerEd25519
- default:
- return genInvalidAlgo{algo}
- }
-}
-
-func getGeneratorByType(typ byte) Generator {
- switch typ {
- case crypto.TypeEd25519:
- return GenEd25519
- case crypto.TypeSecp256k1:
- return GenSecp256k1
- case nano.TypeLedgerEd25519:
- return GenLedgerEd25519
- default:
- return genInvalidByte{typ}
- }
-}
+++ /dev/null
-package cryptostore
-
-import (
- "strings"
-
- crypto "github.com/tendermint/go-crypto"
- keys "github.com/tendermint/go-crypto/keys"
-)
-
-// Manager combines encyption and storage implementation to provide
-// a full-featured key manager
-type Manager struct {
- es encryptedStorage
- codec keys.Codec
-}
-
-func New(coder Encoder, store keys.Storage, codec keys.Codec) Manager {
- return Manager{
- es: encryptedStorage{
- coder: coder,
- store: store,
- },
- codec: codec,
- }
-}
-
-// assert Manager satisfies keys.Signer and keys.Manager interfaces
-var _ keys.Signer = Manager{}
-var _ keys.Manager = Manager{}
-
-// Create adds a new key to the storage engine, returning error if
-// another key already stored under this name
-//
-// algo must be a supported go-crypto algorithm: ed25519, secp256k1
-func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error) {
- // 128-bits are the all the randomness we can make use of
- secret := crypto.CRandBytes(16)
- gen := getGenerator(algo)
-
- key, err := gen.Generate(secret)
- if err != nil {
- return keys.Info{}, "", err
- }
-
- err = s.es.Put(name, passphrase, key)
- if err != nil {
- return keys.Info{}, "", err
- }
-
- // we append the type byte to the serialized secret to help with recovery
- // ie [secret] = [secret] + [type]
- typ := key.Bytes()[0]
- secret = append(secret, typ)
-
- seed, err := s.codec.BytesToWords(secret)
- phrase := strings.Join(seed, " ")
- return info(name, key), phrase, err
-}
-
-// Recover takes a seed phrase and tries to recover the private key.
-//
-// If the seed phrase is valid, it will create the private key and store
-// it under name, protected by passphrase.
-//
-// Result similar to New(), except it doesn't return the seed again...
-func (s Manager) Recover(name, passphrase, seedphrase string) (keys.Info, error) {
- words := strings.Split(strings.TrimSpace(seedphrase), " ")
- secret, err := s.codec.WordsToBytes(words)
- if err != nil {
- return keys.Info{}, err
- }
-
- // secret is comprised of the actual secret with the type appended
- // ie [secret] = [secret] + [type]
- l := len(secret)
- secret, typ := secret[:l-1], secret[l-1]
-
- gen := getGeneratorByType(typ)
- key, err := gen.Generate(secret)
- if err != nil {
- return keys.Info{}, err
- }
-
- // d00d, it worked! create the bugger....
- err = s.es.Put(name, passphrase, key)
- return info(name, key), err
-}
-
-// List loads the keys from the storage and enforces alphabetical order
-func (s Manager) List() (keys.Infos, error) {
- res, err := s.es.List()
- res.Sort()
- return res, err
-}
-
-// Get returns the public information about one key
-func (s Manager) Get(name string) (keys.Info, error) {
- _, info, err := s.es.store.Get(name)
- return info, err
-}
-
-// Sign will modify the Signable in order to attach a valid signature with
-// this public key
-//
-// If no key for this name, or the passphrase doesn't match, returns an error
-func (s Manager) Sign(name, passphrase string, tx keys.Signable) error {
- key, _, err := s.es.Get(name, passphrase)
- if err != nil {
- return err
- }
- sig := key.Sign(tx.SignBytes())
- pubkey := key.PubKey()
- return tx.Sign(pubkey, sig)
-}
-
-// Export decodes the private key with the current password, encodes
-// it with a secure one-time password and generates a sequence that can be
-// Imported by another Manager
-//
-// This is designed to copy from one device to another, or provide backups
-// during version updates.
-func (s Manager) Export(name, oldpass, transferpass string) ([]byte, error) {
- key, _, err := s.es.Get(name, oldpass)
- if err != nil {
- return nil, err
- }
-
- res, err := s.es.coder.Encrypt(key, transferpass)
- return res, err
-}
-
-// Import accepts bytes generated by Export along with the same transferpass
-// If they are valid, it stores the password under the given name with the
-// new passphrase.
-func (s Manager) Import(name, newpass, transferpass string, data []byte) error {
- key, err := s.es.coder.Decrypt(data, transferpass)
- if err != nil {
- return err
- }
-
- return s.es.Put(name, newpass, key)
-}
-
-// Delete removes key forever, but we must present the
-// proper passphrase before deleting it (for security)
-func (s Manager) Delete(name, passphrase string) error {
- // verify we have the proper password before deleting
- _, _, err := s.es.Get(name, passphrase)
- if err != nil {
- return err
- }
- return s.es.Delete(name)
-}
-
-// Update changes the passphrase with which a already stored key is encoded.
-//
-// oldpass must be the current passphrase used for encoding, newpass will be
-// the only valid passphrase from this time forward
-func (s Manager) Update(name, oldpass, newpass string) error {
- key, _, err := s.es.Get(name, oldpass)
- if err != nil {
- return err
- }
-
- // we must delete first, as Putting over an existing name returns an error
- s.Delete(name, oldpass)
-
- return s.es.Put(name, newpass, key)
-}
+++ /dev/null
-package cryptostore_test
-
-import (
- "bytes"
- "fmt"
- "os"
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-
- cmn "github.com/tendermint/tmlibs/common"
-
- crypto "github.com/tendermint/go-crypto"
- "github.com/tendermint/go-crypto/keys"
- "github.com/tendermint/go-crypto/keys/cryptostore"
- "github.com/tendermint/go-crypto/keys/storage/memstorage"
- "github.com/tendermint/go-crypto/nano"
-)
-
-// TestKeyManagement makes sure we can manipulate these keys well
-func TestKeyManagement(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- // make the storage with reasonable defaults
- cstore := cryptostore.New(
- cryptostore.SecretBox,
- memstorage.New(),
- keys.MustLoadCodec("english"),
- )
-
- algo := crypto.NameEd25519
- n1, n2, n3 := "personal", "business", "other"
- p1, p2 := "1234", "really-secure!@#$"
-
- // Check empty state
- l, err := cstore.List()
- require.Nil(err)
- assert.Empty(l)
-
- // create some keys
- _, err = cstore.Get(n1)
- assert.NotNil(err)
- i, _, err := cstore.Create(n1, p1, algo)
- require.Equal(n1, i.Name)
- require.Nil(err)
- _, _, err = cstore.Create(n2, p2, algo)
- require.Nil(err)
-
- // we can get these keys
- i2, err := cstore.Get(n2)
- assert.Nil(err)
- _, err = cstore.Get(n3)
- assert.NotNil(err)
-
- // list shows them in order
- keyS, err := cstore.List()
- require.Nil(err)
- require.Equal(2, len(keyS))
- // note these are in alphabetical order
- assert.Equal(n2, keyS[0].Name)
- assert.Equal(n1, keyS[1].Name)
- assert.Equal(i2.PubKey, keyS[0].PubKey)
-
- // deleting a key removes it
- err = cstore.Delete("bad name", "foo")
- require.NotNil(err)
- err = cstore.Delete(n1, p1)
- require.Nil(err)
- keyS, err = cstore.List()
- require.Nil(err)
- assert.Equal(1, len(keyS))
- _, err = cstore.Get(n1)
- assert.NotNil(err)
-
- // make sure that it only signs with the right password
- // tx := mock.NewSig([]byte("mytransactiondata"))
- // err = cstore.Sign(n2, p1, tx)
- // assert.NotNil(err)
- // err = cstore.Sign(n2, p2, tx)
- // assert.Nil(err, "%+v", err)
- // sigs, err := tx.Signers()
- // assert.Nil(err, "%+v", err)
- // if assert.Equal(1, len(sigs)) {
- // assert.Equal(i2.PubKey, sigs[0])
- // }
-}
-
-// TestSignVerify does some detailed checks on how we sign and validate
-// signatures
-func TestSignVerify(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- // make the storage with reasonable defaults
- cstore := cryptostore.New(
- cryptostore.SecretBox,
- memstorage.New(),
- keys.MustLoadCodec("english"),
- )
- algo := crypto.NameSecp256k1
-
- n1, n2 := "some dude", "a dudette"
- p1, p2 := "1234", "foobar"
-
- // create two users and get their info
- i1, _, err := cstore.Create(n1, p1, algo)
- require.Nil(err)
-
- i2, _, err := cstore.Create(n2, p2, algo)
- require.Nil(err)
-
- // let's try to sign some messages
- d1 := []byte("my first message")
- d2 := []byte("some other important info!")
-
- // try signing both data with both keys...
- s11 := keys.NewMockSignable(d1)
- err = cstore.Sign(n1, p1, s11)
- require.Nil(err)
- s12 := keys.NewMockSignable(d2)
- err = cstore.Sign(n1, p1, s12)
- require.Nil(err)
- s21 := keys.NewMockSignable(d1)
- err = cstore.Sign(n2, p2, s21)
- require.Nil(err)
- s22 := keys.NewMockSignable(d2)
- err = cstore.Sign(n2, p2, s22)
- require.Nil(err)
-
- // let's try to validate and make sure it only works when everything is proper
- cases := []struct {
- key crypto.PubKey
- data []byte
- sig crypto.Signature
- valid bool
- }{
- // proper matches
- {i1.PubKey, d1, s11.Signature, true},
- // change data, pubkey, or signature leads to fail
- {i1.PubKey, d2, s11.Signature, false},
- {i2.PubKey, d1, s11.Signature, false},
- {i1.PubKey, d1, s21.Signature, false},
- // make sure other successes
- {i1.PubKey, d2, s12.Signature, true},
- {i2.PubKey, d1, s21.Signature, true},
- {i2.PubKey, d2, s22.Signature, true},
- }
-
- for i, tc := range cases {
- valid := tc.key.VerifyBytes(tc.data, tc.sig)
- assert.Equal(tc.valid, valid, "%d", i)
- }
-}
-
-// TestSignWithLedger makes sure we have ledger compatibility with
-// the crypto store.
-//
-// This test will only succeed with a ledger attached to the computer
-// and the cosmos app open
-func TestSignWithLedger(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
- if os.Getenv("WITH_LEDGER") == "" {
- t.Skip("Set WITH_LEDGER to run code on real ledger")
- }
-
- // make the storage with reasonable defaults
- cstore := cryptostore.New(
- cryptostore.SecretBox,
- memstorage.New(),
- keys.MustLoadCodec("english"),
- )
- n := "nano-s"
- p := "hard2hack"
-
- // create a nano user
- c, _, err := cstore.Create(n, p, nano.NameLedgerEd25519)
- require.Nil(err, "%+v", err)
- assert.Equal(c.Name, n)
- _, ok := c.PubKey.Unwrap().(nano.PubKeyLedgerEd25519)
- require.True(ok)
-
- // make sure we can get it back
- info, err := cstore.Get(n)
- require.Nil(err, "%+v", err)
- assert.Equal(info.Name, n)
- key := info.PubKey
- require.False(key.Empty())
- require.True(key.Equals(c.PubKey))
-
- // let's try to sign some messages
- d1 := []byte("welcome to cosmos")
- d2 := []byte("please turn on the app")
-
- // try signing both data with the ledger...
- s1 := keys.NewMockSignable(d1)
- err = cstore.Sign(n, p, s1)
- require.Nil(err)
- s2 := keys.NewMockSignable(d2)
- err = cstore.Sign(n, p, s2)
- require.Nil(err)
-
- // now, let's check those signatures work
- assert.True(key.VerifyBytes(d1, s1.Signature))
- assert.True(key.VerifyBytes(d2, s2.Signature))
- // and mismatched signatures don't
- assert.False(key.VerifyBytes(d1, s2.Signature))
-}
-
-func assertPassword(assert *assert.Assertions, cstore cryptostore.Manager, name, pass, badpass string) {
- err := cstore.Update(name, badpass, pass)
- assert.NotNil(err)
- err = cstore.Update(name, pass, pass)
- assert.Nil(err, "%+v", err)
-}
-
-// TestImportUnencrypted tests accepting raw priv keys bytes as input
-func TestImportUnencrypted(t *testing.T) {
- require := require.New(t)
-
- // make the storage with reasonable defaults
- cstore := cryptostore.New(
- cryptostore.SecretBox,
- memstorage.New(),
- keys.MustLoadCodec("english"),
- )
-
- key, err := cryptostore.GenEd25519.Generate(cmn.RandBytes(16))
- require.NoError(err)
-
- addr := key.PubKey().Address()
- name := "john"
- pass := "top-secret"
-
- // import raw bytes
- err = cstore.Import(name, pass, "", key.Bytes())
- require.Nil(err, "%+v", err)
-
- // make sure the address matches
- info, err := cstore.Get(name)
- require.Nil(err, "%+v", err)
- require.EqualValues(addr, info.Address)
-}
-
-// TestAdvancedKeyManagement verifies update, import, export functionality
-func TestAdvancedKeyManagement(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- // make the storage with reasonable defaults
- cstore := cryptostore.New(
- cryptostore.SecretBox,
- memstorage.New(),
- keys.MustLoadCodec("english"),
- )
-
- algo := crypto.NameSecp256k1
- n1, n2 := "old-name", "new name"
- p1, p2, p3, pt := "1234", "foobar", "ding booms!", "really-secure!@#$"
-
- // make sure key works with initial password
- _, _, err := cstore.Create(n1, p1, algo)
- require.Nil(err, "%+v", err)
- assertPassword(assert, cstore, n1, p1, p2)
-
- // update password requires the existing password
- err = cstore.Update(n1, "jkkgkg", p2)
- assert.NotNil(err)
- assertPassword(assert, cstore, n1, p1, p2)
-
- // then it changes the password when correct
- err = cstore.Update(n1, p1, p2)
- assert.Nil(err)
- // p2 is now the proper one!
- assertPassword(assert, cstore, n1, p2, p1)
-
- // exporting requires the proper name and passphrase
- _, err = cstore.Export(n2, p2, pt)
- assert.NotNil(err)
- _, err = cstore.Export(n1, p1, pt)
- assert.NotNil(err)
- exported, err := cstore.Export(n1, p2, pt)
- require.Nil(err, "%+v", err)
-
- // import fails on bad transfer pass
- err = cstore.Import(n2, p3, p2, exported)
- assert.NotNil(err)
-}
-
-// TestSeedPhrase verifies restoring from a seed phrase
-func TestSeedPhrase(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- // make the storage with reasonable defaults
- cstore := cryptostore.New(
- cryptostore.SecretBox,
- memstorage.New(),
- keys.MustLoadCodec("english"),
- )
-
- algo := crypto.NameEd25519
- n1, n2 := "lost-key", "found-again"
- p1, p2 := "1234", "foobar"
-
- // make sure key works with initial password
- info, seed, err := cstore.Create(n1, p1, algo)
- require.Nil(err, "%+v", err)
- assert.Equal(n1, info.Name)
- assert.NotEmpty(seed)
-
- // now, let us delete this key
- err = cstore.Delete(n1, p1)
- require.Nil(err, "%+v", err)
- _, err = cstore.Get(n1)
- require.NotNil(err)
-
- // let us re-create it from the seed-phrase
- newInfo, err := cstore.Recover(n2, p2, seed)
- require.Nil(err, "%+v", err)
- assert.Equal(n2, newInfo.Name)
- assert.Equal(info.Address, newInfo.Address)
- assert.Equal(info.PubKey, newInfo.PubKey)
-}
-
-func ExampleNew() {
- // Select the encryption and storage for your cryptostore
- cstore := cryptostore.New(
- cryptostore.SecretBox,
- // Note: use filestorage.New(dir) for real data
- memstorage.New(),
- keys.MustLoadCodec("english"),
- )
- ed := crypto.NameEd25519
- sec := crypto.NameSecp256k1
-
- // Add keys and see they return in alphabetical order
- bob, _, err := cstore.Create("Bob", "friend", ed)
- if err != nil {
- // this should never happen
- fmt.Println(err)
- } else {
- // return info here just like in List
- fmt.Println(bob.Name)
- }
- cstore.Create("Alice", "secret", sec)
- cstore.Create("Carl", "mitm", ed)
- info, _ := cstore.List()
- for _, i := range info {
- fmt.Println(i.Name)
- }
-
- // We need to use passphrase to generate a signature
- tx := keys.NewMockSignable([]byte("deadbeef"))
- err = cstore.Sign("Bob", "friend", tx)
- if err != nil {
- fmt.Println("don't accept real passphrase")
- }
-
- // and we can validate the signature with publically available info
- binfo, _ := cstore.Get("Bob")
- if !binfo.PubKey.Equals(bob.PubKey) {
- fmt.Println("Get and Create return different keys")
- }
-
- sigs, err := tx.Signers()
- if err != nil {
- fmt.Println("badly signed")
- } else if bytes.Equal(sigs[0].Bytes(), binfo.PubKey.Bytes()) {
- fmt.Println("signed by Bob")
- } else {
- fmt.Println("signed by someone else")
- }
-
- // Output:
- // Bob
- // Alice
- // Bob
- // Carl
- // signed by Bob
-}
+++ /dev/null
-package cryptostore
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
-
- crypto "github.com/tendermint/go-crypto"
- cmn "github.com/tendermint/tmlibs/common"
-
- keys "github.com/tendermint/go-crypto/keys"
-)
-
-func TestSortKeys(t *testing.T) {
- assert := assert.New(t)
-
- gen := func() crypto.PrivKey {
- key, _ := GenEd25519.Generate(cmn.RandBytes(16))
- return key
- }
- assert.NotEqual(gen(), gen())
-
- // alphabetical order is n3, n1, n2
- n1, n2, n3 := "john", "mike", "alice"
- infos := keys.Infos{
- info(n1, gen()),
- info(n2, gen()),
- info(n3, gen()),
- }
-
- // make sure they are initialized unsorted
- assert.Equal(n1, infos[0].Name)
- assert.Equal(n2, infos[1].Name)
- assert.Equal(n3, infos[2].Name)
-
- // now they are sorted
- infos.Sort()
- assert.Equal(n3, infos[0].Name)
- assert.Equal(n1, infos[1].Name)
- assert.Equal(n2, infos[2].Name)
-
- // make sure info put some real data there...
- assert.NotEmpty(infos[0].PubKey)
- assert.NotEmpty(infos[0].PubKey.Address())
- assert.NotEmpty(infos[1].PubKey)
- assert.NotEmpty(infos[1].PubKey.Address())
- assert.NotEqual(infos[0].PubKey, infos[1].PubKey)
-}
+++ /dev/null
-package keys
-
-import (
- "encoding/binary"
- "errors"
- "hash/crc32"
- "hash/crc64"
-
- "github.com/howeyc/crc16"
-)
-
-// ECC is used for anything that calculates an error-correcting code
-type ECC interface {
- // AddECC calculates an error-correcting code for the input
- // returns an output with the code appended
- AddECC([]byte) []byte
-
- // CheckECC verifies if the ECC is proper on the input and returns
- // the data with the code removed, or an error
- CheckECC([]byte) ([]byte, error)
-}
-
-var errInputTooShort = errors.New("input too short, no checksum present")
-var errChecksumDoesntMatch = errors.New("checksum does not match")
-
-// NoECC is a no-op placeholder, kind of useless... except for tests
-type NoECC struct{}
-
-var _ ECC = NoECC{}
-
-func (_ NoECC) AddECC(input []byte) []byte { return input }
-func (_ NoECC) CheckECC(input []byte) ([]byte, error) { return input, nil }
-
-// CRC16 does the ieee crc16 polynomial check
-type CRC16 struct {
- Poly uint16
- table *crc16.Table
-}
-
-var _ ECC = (*CRC16)(nil)
-
-const crc16ByteCount = 2
-
-func NewIBMCRC16() *CRC16 {
- return &CRC16{Poly: crc16.IBM}
-}
-
-func NewSCSICRC16() *CRC16 {
- return &CRC16{Poly: crc16.SCSI}
-}
-
-func NewCCITTCRC16() *CRC16 {
- return &CRC16{Poly: crc16.CCITT}
-}
-
-func (c *CRC16) AddECC(input []byte) []byte {
- table := c.getTable()
-
- // get crc and convert to some bytes...
- crc := crc16.Checksum(input, table)
- check := make([]byte, crc16ByteCount)
- binary.BigEndian.PutUint16(check, crc)
-
- // append it to the input
- output := append(input, check...)
- return output
-}
-
-func (c *CRC16) CheckECC(input []byte) ([]byte, error) {
- table := c.getTable()
-
- if len(input) <= crc16ByteCount {
- return nil, errInputTooShort
- }
- cut := len(input) - crc16ByteCount
- data, check := input[:cut], input[cut:]
- crc := binary.BigEndian.Uint16(check)
- calc := crc16.Checksum(data, table)
- if crc != calc {
- return nil, errChecksumDoesntMatch
- }
- return data, nil
-}
-
-func (c *CRC16) getTable() *crc16.Table {
- if c.table != nil {
- return c.table
- }
- if c.Poly == 0 {
- c.Poly = crc16.IBM
- }
- c.table = crc16.MakeTable(c.Poly)
- return c.table
-}
-
-// CRC32 does the ieee crc32 polynomial check
-type CRC32 struct {
- Poly uint32
- table *crc32.Table
-}
-
-var _ ECC = (*CRC32)(nil)
-
-func NewIEEECRC32() *CRC32 {
- return &CRC32{Poly: crc32.IEEE}
-}
-
-func NewCastagnoliCRC32() *CRC32 {
- return &CRC32{Poly: crc32.Castagnoli}
-}
-
-func NewKoopmanCRC32() *CRC32 {
- return &CRC32{Poly: crc32.Koopman}
-}
-
-func (c *CRC32) AddECC(input []byte) []byte {
- table := c.getTable()
-
- // get crc and convert to some bytes...
- crc := crc32.Checksum(input, table)
- check := make([]byte, crc32.Size)
- binary.BigEndian.PutUint32(check, crc)
-
- // append it to the input
- output := append(input, check...)
- return output
-}
-
-func (c *CRC32) CheckECC(input []byte) ([]byte, error) {
- table := c.getTable()
-
- if len(input) <= crc32.Size {
- return nil, errInputTooShort
- }
- cut := len(input) - crc32.Size
- data, check := input[:cut], input[cut:]
- crc := binary.BigEndian.Uint32(check)
- calc := crc32.Checksum(data, table)
- if crc != calc {
- return nil, errChecksumDoesntMatch
- }
- return data, nil
-}
-
-func (c *CRC32) getTable() *crc32.Table {
- if c.table == nil {
- if c.Poly == 0 {
- c.Poly = crc32.IEEE
- }
- c.table = crc32.MakeTable(c.Poly)
- }
- return c.table
-}
-
-// CRC64 does the ieee crc64 polynomial check
-type CRC64 struct {
- Poly uint64
- table *crc64.Table
-}
-
-var _ ECC = (*CRC64)(nil)
-
-func NewISOCRC64() *CRC64 {
- return &CRC64{Poly: crc64.ISO}
-}
-
-func NewECMACRC64() *CRC64 {
- return &CRC64{Poly: crc64.ECMA}
-}
-
-func (c *CRC64) AddECC(input []byte) []byte {
- table := c.getTable()
-
- // get crc and convert to some bytes...
- crc := crc64.Checksum(input, table)
- check := make([]byte, crc64.Size)
- binary.BigEndian.PutUint64(check, crc)
-
- // append it to the input
- output := append(input, check...)
- return output
-}
-
-func (c *CRC64) CheckECC(input []byte) ([]byte, error) {
- table := c.getTable()
-
- if len(input) <= crc64.Size {
- return nil, errInputTooShort
- }
- cut := len(input) - crc64.Size
- data, check := input[:cut], input[cut:]
- crc := binary.BigEndian.Uint64(check)
- calc := crc64.Checksum(data, table)
- if crc != calc {
- return nil, errChecksumDoesntMatch
- }
- return data, nil
-}
-
-func (c *CRC64) getTable() *crc64.Table {
- if c.table == nil {
- if c.Poly == 0 {
- c.Poly = crc64.ISO
- }
- c.table = crc64.MakeTable(c.Poly)
- }
- return c.table
-}
+++ /dev/null
-package keys
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
-
- cmn "github.com/tendermint/tmlibs/common"
-)
-
-var codecs = []ECC{
- NewIBMCRC16(),
- NewSCSICRC16(),
- NewCCITTCRC16(),
- NewIEEECRC32(),
- NewCastagnoliCRC32(),
- NewKoopmanCRC32(),
- NewISOCRC64(),
- NewECMACRC64(),
-}
-
-// TestECCPasses makes sure that the AddECC/CheckECC methods are symetric
-func TestECCPasses(t *testing.T) {
- assert := assert.New(t)
-
- checks := append(codecs, NoECC{})
-
- for _, check := range checks {
- for i := 0; i < 2000; i++ {
- numBytes := cmn.RandInt()%60 + 1
- data := cmn.RandBytes(numBytes)
-
- checked := check.AddECC(data)
- res, err := check.CheckECC(checked)
- if assert.Nil(err, "%#v: %+v", check, err) {
- assert.Equal(data, res, "%v", check)
- }
- }
- }
-}
-
-// TestECCFails makes sure random data will (usually) fail the checksum
-func TestECCFails(t *testing.T) {
- assert := assert.New(t)
-
- checks := codecs
- attempts := 2000
-
- for _, check := range checks {
- failed := 0
- for i := 0; i < attempts; i++ {
- numBytes := cmn.RandInt()%60 + 1
- data := cmn.RandBytes(numBytes)
- _, err := check.CheckECC(data)
- if err != nil {
- failed += 1
- }
- }
- // we allow up to 1 falsely accepted checksums, as there are random matches
- assert.InDelta(attempts, failed, 1, "%v", check)
- }
-}
+++ /dev/null
-output = "text"
-keydir = ".mykeys"
+++ /dev/null
-/*
-package filestorage provides a secure on-disk storage of private keys and
-metadata. Security is enforced by file and directory permissions, much
-like standard ssh key storage.
-*/
-package filestorage
-
-import (
- "fmt"
- "io/ioutil"
- "os"
- "path"
- "strings"
-
- "github.com/pkg/errors"
- crypto "github.com/tendermint/go-crypto"
- keys "github.com/tendermint/go-crypto/keys"
-)
-
-const (
- BlockType = "Tendermint Light Client"
-
- // PrivExt is the extension for private keys.
- PrivExt = "tlc"
- // PubExt is the extensions for public keys.
- PubExt = "pub"
-
- keyPerm = os.FileMode(0600)
- // pubPerm = os.FileMode(0644)
- dirPerm = os.FileMode(0700)
-)
-
-type FileStore struct {
- keyDir string
-}
-
-// New creates an instance of file-based key storage with tight permissions
-//
-// dir should be an absolute path of a directory owner by this user. It will
-// be created if it doesn't exist already.
-func New(dir string) FileStore {
- err := os.MkdirAll(dir, dirPerm)
- if err != nil {
- panic(err)
- }
- return FileStore{dir}
-}
-
-// assert FileStore satisfies keys.Storage
-var _ keys.Storage = FileStore{}
-
-// Put creates two files, one with the public info as json, the other
-// with the (encoded) private key as gpg ascii-armor style
-func (s FileStore) Put(name string, key []byte, info keys.Info) error {
- pub, priv := s.nameToPaths(name)
-
- // write public info
- err := writeInfo(pub, info)
- if err != nil {
- return err
- }
-
- // write private info
- return write(priv, name, key)
-}
-
-// Get loads the info and (encoded) private key from the directory
-// It uses `name` to generate the filename, and returns an error if the
-// files don't exist or are in the incorrect format
-func (s FileStore) Get(name string) ([]byte, keys.Info, error) {
- pub, priv := s.nameToPaths(name)
-
- info, err := readInfo(pub)
- if err != nil {
- return nil, info, err
- }
-
- key, _, err := read(priv)
- return key, info.Format(), err
-}
-
-// List parses the key directory for public info and returns a list of
-// Info for all keys located in this directory.
-func (s FileStore) List() (keys.Infos, error) {
- dir, err := os.Open(s.keyDir)
- if err != nil {
- return nil, errors.Wrap(err, "List Keys")
- }
- defer dir.Close()
-
- names, err := dir.Readdirnames(0)
- if err != nil {
- return nil, errors.Wrap(err, "List Keys")
- }
-
- // filter names for .pub ending and load them one by one
- // half the files is a good guess for pre-allocating the slice
- infos := make([]keys.Info, 0, len(names)/2)
- for _, name := range names {
- if strings.HasSuffix(name, PubExt) {
- p := path.Join(s.keyDir, name)
- info, err := readInfo(p)
- if err != nil {
- return nil, err
- }
- infos = append(infos, info.Format())
- }
- }
-
- return infos, nil
-}
-
-// Delete permanently removes the public and private info for the named key
-// The calling function should provide some security checks first.
-func (s FileStore) Delete(name string) error {
- pub, priv := s.nameToPaths(name)
- err := os.Remove(priv)
- if err != nil {
- return errors.Wrap(err, "Deleting Private Key")
- }
- err = os.Remove(pub)
- return errors.Wrap(err, "Deleting Public Key")
-}
-
-func (s FileStore) nameToPaths(name string) (pub, priv string) {
- privName := fmt.Sprintf("%s.%s", name, PrivExt)
- pubName := fmt.Sprintf("%s.%s", name, PubExt)
- return path.Join(s.keyDir, pubName), path.Join(s.keyDir, privName)
-}
-
-func writeInfo(path string, info keys.Info) error {
- return write(path, info.Name, info.PubKey.Bytes())
-}
-
-func readInfo(path string) (info keys.Info, err error) {
- var data []byte
- data, info.Name, err = read(path)
- if err != nil {
- return
- }
- pk, err := crypto.PubKeyFromBytes(data)
- info.PubKey = pk
- return
-}
-
-func read(path string) ([]byte, string, error) {
- f, err := os.Open(path)
- if err != nil {
- return nil, "", errors.Wrap(err, "Reading data")
- }
- defer f.Close()
-
- d, err := ioutil.ReadAll(f)
- if err != nil {
- return nil, "", errors.Wrap(err, "Reading data")
- }
- block, headers, key, err := crypto.DecodeArmor(string(d))
- if err != nil {
- return nil, "", errors.Wrap(err, "Invalid Armor")
- }
- if block != BlockType {
- return nil, "", errors.Errorf("Unknown key type: %s", block)
- }
- return key, headers["name"], nil
-}
-
-func write(path, name string, key []byte) error {
- f, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, keyPerm)
- if err != nil {
- return errors.Wrap(err, "Writing data")
- }
- defer f.Close()
- headers := map[string]string{"name": name}
- text := crypto.EncodeArmor(BlockType, headers, key)
- _, err = f.WriteString(text)
- return errors.Wrap(err, "Writing data")
-}
+++ /dev/null
-package filestorage
-
-import (
- "io/ioutil"
- "os"
- "path"
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- crypto "github.com/tendermint/go-crypto"
- keys "github.com/tendermint/go-crypto/keys"
-)
-
-func TestBasicCRUD(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- dir, err := ioutil.TempDir("", "filestorage-test")
- assert.Nil(err)
- defer os.RemoveAll(dir)
- store := New(dir)
-
- name := "bar"
- key := []byte("secret-key-here")
- pubkey := crypto.GenPrivKeyEd25519().PubKey()
- info := keys.Info{
- Name: name,
- PubKey: pubkey.Wrap(),
- }
-
- // No data: Get and Delete return nothing
- _, _, err = store.Get(name)
- assert.NotNil(err)
- err = store.Delete(name)
- assert.NotNil(err)
- // List returns empty list
- l, err := store.List()
- assert.Nil(err)
- assert.Empty(l)
-
- // Putting the key in the store must work
- err = store.Put(name, key, info)
- assert.Nil(err)
- // But a second time is a failure
- err = store.Put(name, key, info)
- assert.NotNil(err)
-
- // Now, we can get and list properly
- k, i, err := store.Get(name)
- require.Nil(err, "%+v", err)
- assert.Equal(key, k)
- assert.Equal(info.Name, i.Name)
- assert.Equal(info.PubKey, i.PubKey)
- assert.NotEmpty(i.Address)
- l, err = store.List()
- require.Nil(err, "%+v", err)
- assert.Equal(1, len(l))
- assert.Equal(i, l[0])
-
- // querying a non-existent key fails
- _, _, err = store.Get("badname")
- assert.NotNil(err)
-
- // We can only delete once
- err = store.Delete(name)
- assert.Nil(err)
- err = store.Delete(name)
- assert.NotNil(err)
-
- // and then Get and List don't work
- _, _, err = store.Get(name)
- assert.NotNil(err)
- // List returns empty list
- l, err = store.List()
- assert.Nil(err)
- assert.Empty(l)
-}
-
-func TestDirectoryHandling(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- // prepare a temp dir and make sure it is not there
- newDir := path.Join(os.TempDir(), "file-test-dir")
- _, err := os.Open(newDir)
- assert.True(os.IsNotExist(err))
- defer os.RemoveAll(newDir)
-
- // now, check with two levels deep....
- parentDir := path.Join(os.TempDir(), "missing-dir")
- nestedDir := path.Join(parentDir, "lots", "of", "levels", "here")
- _, err = os.Open(parentDir)
- assert.True(os.IsNotExist(err))
- defer os.RemoveAll(parentDir)
-
- // create a new storage, and verify it creates the directory with good permissions
- for _, dir := range []string{newDir, nestedDir, newDir} {
- New(dir)
- d, err := os.Open(dir)
- require.Nil(err)
- defer d.Close()
-
- stat, err := d.Stat()
- require.Nil(err)
- assert.Equal(dirPerm, stat.Mode()&os.ModePerm)
- }
-}
+++ /dev/null
-/*
-package memstorage provides a simple in-memory key store designed for
-use in test cases, particularly to isolate them from the filesystem,
-concurrency, and cleanup issues.
-*/
-package memstorage
-
-import (
- "github.com/pkg/errors"
- keys "github.com/tendermint/go-crypto/keys"
-)
-
-type data struct {
- info keys.Info
- key []byte
-}
-
-type MemStore map[string]data
-
-// New creates an instance of file-based key storage with tight permissions
-func New() MemStore {
- return MemStore{}
-}
-
-// assert MemStore satisfies keys.Storage
-var _ keys.Storage = MemStore{}
-
-// Put adds the given key, returns an error if it another key
-// is already stored under this name
-func (s MemStore) Put(name string, key []byte, info keys.Info) error {
- if _, ok := s[name]; ok {
- return errors.Errorf("Key named '%s' already exists", name)
- }
- s[name] = data{info, key}
- return nil
-}
-
-// Get returns the key stored under the name, or returns an error if not present
-func (s MemStore) Get(name string) ([]byte, keys.Info, error) {
- var err error
- d, ok := s[name]
- if !ok {
- err = errors.Errorf("Key named '%s' doesn't exist", name)
- }
- return d.key, d.info.Format(), err
-}
-
-// List returns the public info of all keys in the MemStore in unsorted order
-func (s MemStore) List() (keys.Infos, error) {
- res := make([]keys.Info, len(s))
- i := 0
- for _, d := range s {
- res[i] = d.info.Format()
- i++
- }
- return res, nil
-}
-
-// Delete removes the named key from the MemStore, raising an error if it
-// wasn't present yet.
-func (s MemStore) Delete(name string) error {
- _, ok := s[name]
- if !ok {
- return errors.Errorf("Key named '%s' doesn't exist", name)
- }
- delete(s, name)
- return nil
-}
+++ /dev/null
-package memstorage
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
- crypto "github.com/tendermint/go-crypto"
- keys "github.com/tendermint/go-crypto/keys"
-)
-
-func TestBasicCRUD(t *testing.T) {
- assert := assert.New(t)
- store := New()
-
- name := "foo"
- key := []byte("secret-key-here")
- pubkey := crypto.GenPrivKeyEd25519().PubKey()
- info := keys.Info{
- Name: name,
- PubKey: pubkey,
- }
-
- // No data: Get and Delete return nothing
- _, _, err := store.Get(name)
- assert.NotNil(err)
- err = store.Delete(name)
- assert.NotNil(err)
- // List returns empty list
- l, err := store.List()
- assert.Nil(err)
- assert.Empty(l)
-
- // Putting the key in the store must work
- err = store.Put(name, key, info)
- assert.Nil(err)
- // But a second time is a failure
- err = store.Put(name, key, info)
- assert.NotNil(err)
-
- // Now, we can get and list properly
- k, i, err := store.Get(name)
- assert.Nil(err)
- assert.Equal(key, k)
- assert.Equal(info.Name, i.Name)
- assert.Equal(info.PubKey, i.PubKey)
- assert.NotEmpty(i.Address)
- l, err = store.List()
- assert.Nil(err)
- assert.Equal(1, len(l))
- assert.Equal(i, l[0])
-
- // querying a non-existent key fails
- _, _, err = store.Get("badname")
- assert.NotNil(err)
-
- // We can only delete once
- err = store.Delete(name)
- assert.Nil(err)
- err = store.Delete(name)
- assert.NotNil(err)
-
- // and then Get and List don't work
- _, _, err = store.Get(name)
- assert.NotNil(err)
- // List returns empty list
- l, err = store.List()
- assert.Nil(err)
- assert.Empty(l)
-}
+++ /dev/null
-package keys
-
-import (
- "fmt"
- "sort"
-
- crypto "github.com/tendermint/go-crypto"
- wire "github.com/tendermint/go-wire"
- data "github.com/tendermint/go-wire/data"
-)
-
-// Storage has many implementation, based on security and sharing requirements
-// like disk-backed, mem-backed, vault, db, etc.
-type Storage interface {
- Put(name string, key []byte, info Info) error
- Get(name string) (key []byte, info Info, err error)
- List() (Infos, error)
- Delete(name string) error
-}
-
-// Info is the public information about a key
-type Info struct {
- Name string `json:"name"`
- Address data.Bytes `json:"address"`
- PubKey crypto.PubKey `json:"pubkey"`
-}
-
-func (i *Info) Format() Info {
- if !i.PubKey.Empty() {
- i.Address = i.PubKey.Address()
- }
- return *i
-}
-
-// Infos is a wrapper to allows alphabetical sorting of the keys
-type Infos []Info
-
-func (k Infos) Len() int { return len(k) }
-func (k Infos) Less(i, j int) bool { return k[i].Name < k[j].Name }
-func (k Infos) Swap(i, j int) { k[i], k[j] = k[j], k[i] }
-func (k Infos) Sort() {
- if k != nil {
- sort.Sort(k)
- }
-}
-
-// Signable represents any transaction we wish to send to tendermint core
-// These methods allow us to sign arbitrary Tx with the KeyStore
-type Signable interface {
- // SignBytes is the immutable data, which needs to be signed
- SignBytes() []byte
-
- // Sign will add a signature and pubkey.
- //
- // Depending on the Signable, one may be able to call this multiple times for multisig
- // Returns error if called with invalid data or too many times
- Sign(pubkey crypto.PubKey, sig crypto.Signature) error
-
- // Signers will return the public key(s) that signed if the signature
- // is valid, or an error if there is any issue with the signature,
- // including if there are no signatures
- Signers() ([]crypto.PubKey, error)
-
- // TxBytes returns the transaction data as well as all signatures
- // It should return an error if Sign was never called
- TxBytes() ([]byte, error)
-}
-
-// Signer allows one to use a keystore to sign transactions
-type Signer interface {
- Sign(name, passphrase string, tx Signable) error
-}
-
-// Manager allows simple CRUD on a keystore, as an aid to signing
-type Manager interface {
- Signer
- // Create also returns a seed phrase for cold-storage
- Create(name, passphrase, algo string) (Info, string, error)
- // Recover takes a seedphrase and loads in the private key
- Recover(name, passphrase, seedphrase string) (Info, error)
- List() (Infos, error)
- Get(name string) (Info, error)
- Update(name, oldpass, newpass string) error
- Delete(name, passphrase string) error
-}
-
-/**** MockSignable allows us to view data ***/
-
-// MockSignable lets us wrap arbitrary data with a go-crypto signature
-type MockSignable struct {
- Data []byte
- PubKey crypto.PubKey
- Signature crypto.Signature
-}
-
-var _ Signable = &MockSignable{}
-
-// NewMockSignable sets the data to sign
-func NewMockSignable(data []byte) *MockSignable {
- return &MockSignable{Data: data}
-}
-
-// TxBytes returns the full data with signatures
-func (s *MockSignable) TxBytes() ([]byte, error) {
- return wire.BinaryBytes(s), nil
-}
-
-// SignBytes returns the original data passed into `NewSig`
-func (s *MockSignable) SignBytes() []byte {
- return s.Data
-}
-
-// Sign will add a signature and pubkey.
-//
-// Depending on the Signable, one may be able to call this multiple times for multisig
-// Returns error if called with invalid data or too many times
-func (s *MockSignable) Sign(pubkey crypto.PubKey, sig crypto.Signature) error {
- s.PubKey = pubkey
- s.Signature = sig
- return nil
-}
-
-// Signers will return the public key(s) that signed if the signature
-// is valid, or an error if there is any issue with the signature,
-// including if there are no signatures
-func (s *MockSignable) Signers() ([]crypto.PubKey, error) {
- if s.PubKey.Empty() {
- return nil, fmt.Errorf("no signers")
- }
- if !s.PubKey.VerifyBytes(s.SignBytes(), s.Signature) {
- return nil, fmt.Errorf("invalid signature")
- }
- return []crypto.PubKey{s.PubKey}, nil
-}
+++ /dev/null
-package keys
-
-import (
- "math/big"
- "strings"
-
- "github.com/pkg/errors"
-
- "github.com/tendermint/go-crypto/keys/wordlist"
-)
-
-const BankSize = 2048
-
-// TODO: add error-checking codecs for invalid phrases
-
-type Codec interface {
- BytesToWords([]byte) ([]string, error)
- WordsToBytes([]string) ([]byte, error)
-}
-
-type WordCodec struct {
- words []string
- bytes map[string]int
- check ECC
-}
-
-var _ Codec = &WordCodec{}
-
-func NewCodec(words []string) (codec *WordCodec, err error) {
- if len(words) != BankSize {
- return codec, errors.Errorf("Bank must have %d words, found %d", BankSize, len(words))
- }
-
- res := &WordCodec{
- words: words,
- // TODO: configure this outside???
- check: NewIEEECRC32(),
- // check: NewIBMCRC16(),
- }
-
- return res, nil
-}
-
-// LoadCodec loads a pre-compiled language file
-func LoadCodec(bank string) (codec *WordCodec, err error) {
- words, err := loadBank(bank)
- if err != nil {
- return codec, err
- }
- return NewCodec(words)
-}
-
-// MustLoadCodec panics if word bank is missing, only for tests
-func MustLoadCodec(bank string) *WordCodec {
- codec, err := LoadCodec(bank)
- if err != nil {
- panic(err)
- }
- return codec
-}
-
-// loadBank opens a wordlist file and returns all words inside
-func loadBank(bank string) ([]string, error) {
- filename := "keys/wordlist/" + bank + ".txt"
- words, err := wordlist.Asset(filename)
- if err != nil {
- return nil, err
- }
- wordsAll := strings.Split(strings.TrimSpace(string(words)), "\n")
- return wordsAll, nil
-}
-
-// // TODO: read from go-bind assets
-// func getData(filename string) (string, error) {
-// f, err := os.Open(filename)
-// if err != nil {
-// return "", errors.WithStack(err)
-// }
-// defer f.Close()
-
-// data, err := ioutil.ReadAll(f)
-// if err != nil {
-// return "", errors.WithStack(err)
-// }
-
-// return string(data), nil
-// }
-
-// given this many bytes, we will produce this many words
-func wordlenFromBytes(numBytes int) int {
- // 2048 words per bank, which is 2^11.
- // 8 bits per byte, and we add +10 so it rounds up
- return (8*numBytes + 10) / 11
-}
-
-// given this many words, we will produce this many bytes.
-// sometimes there are two possibilities.
-// if maybeShorter is true, then represents len OR len-1 bytes
-func bytelenFromWords(numWords int) (length int, maybeShorter bool) {
- // calculate the max number of complete bytes we could store in this word
- length = 11 * numWords / 8
- // if one less byte would also generate this length, set maybeShorter
- if wordlenFromBytes(length-1) == numWords {
- maybeShorter = true
- }
- return
-}
-
-// TODO: add checksum
-func (c *WordCodec) BytesToWords(raw []byte) (words []string, err error) {
- // always add a checksum to the data
- data := c.check.AddECC(raw)
- numWords := wordlenFromBytes(len(data))
-
- n2048 := big.NewInt(2048)
- nData := big.NewInt(0).SetBytes(data)
- nRem := big.NewInt(0)
- // Alternative, use condition "nData.BitLen() > 0"
- // to allow for shorter words when data has leading 0's
- for i := 0; i < numWords; i++ {
- nData.DivMod(nData, n2048, nRem)
- rem := nRem.Int64()
- w := c.words[rem]
- // double-check bank on generation...
- _, err := c.GetIndex(w)
- if err != nil {
- return nil, err
- }
- words = append(words, w)
- }
- return words, nil
-}
-
-func (c *WordCodec) WordsToBytes(words []string) ([]byte, error) {
- l := len(words)
-
- if l == 0 {
- return nil, errors.New("Didn't provide any words")
- }
-
- n2048 := big.NewInt(2048)
- nData := big.NewInt(0)
- // since we output words based on the remainder, the first word has the lowest
- // value... we must load them in reverse order
- for i := 1; i <= l; i++ {
- rem, err := c.GetIndex(words[l-i])
- if err != nil {
- return nil, err
- }
- nRem := big.NewInt(int64(rem))
- nData.Mul(nData, n2048)
- nData.Add(nData, nRem)
- }
-
- // we copy into a slice of the expected size, so it is not shorter if there
- // are lots of leading 0s
- dataBytes := nData.Bytes()
-
- // copy into the container we have with the expected size
- outLen, flex := bytelenFromWords(len(words))
- toCheck := make([]byte, outLen)
- if len(dataBytes) > outLen {
- return nil, errors.New("Invalid data, could not have been generated by this codec")
- }
- copy(toCheck[outLen-len(dataBytes):], dataBytes)
-
- // validate the checksum...
- output, err := c.check.CheckECC(toCheck)
- if flex && err != nil {
- // if flex, try again one shorter....
- toCheck = toCheck[1:]
- output, err = c.check.CheckECC(toCheck)
- }
-
- return output, err
-}
-
-// GetIndex finds the index of the words to create bytes
-// Generates a map the first time it is loaded, to avoid needless
-// computation when list is not used.
-func (c *WordCodec) GetIndex(word string) (int, error) {
- // generate the first time
- if c.bytes == nil {
- b := map[string]int{}
- for i, w := range c.words {
- if _, ok := b[w]; ok {
- return -1, errors.Errorf("Duplicate word in list: %s", w)
- }
- b[w] = i
- }
- c.bytes = b
- }
-
- // get the index, or an error
- rem, ok := c.bytes[word]
- if !ok {
- return -1, errors.Errorf("Unrecognized word: %s", word)
- }
- return rem, nil
-}
+++ /dev/null
-package keys
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-
- cmn "github.com/tendermint/tmlibs/common"
-)
-
-func TestLengthCalc(t *testing.T) {
- assert := assert.New(t)
-
- cases := []struct {
- bytes, words int
- flexible bool
- }{
- {1, 1, false},
- {2, 2, false},
- // bytes pairs with same word count
- {3, 3, true},
- {4, 3, true},
- {5, 4, false},
- // bytes pairs with same word count
- {10, 8, true},
- {11, 8, true},
- {12, 9, false},
- {13, 10, false},
- {20, 15, false},
- // bytes pairs with same word count
- {21, 16, true},
- {32, 24, true},
- }
-
- for _, tc := range cases {
- wl := wordlenFromBytes(tc.bytes)
- assert.Equal(tc.words, wl, "%d", tc.bytes)
-
- bl, flex := bytelenFromWords(tc.words)
- assert.Equal(tc.flexible, flex, "%d", tc.words)
- if !flex {
- assert.Equal(tc.bytes, bl, "%d", tc.words)
- } else {
- // check if it is either tc.bytes or tc.bytes +1
- choices := []int{tc.bytes, tc.bytes + 1}
- assert.Contains(choices, bl, "%d", tc.words)
- }
- }
-}
-
-func TestEncodeDecode(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- codec, err := LoadCodec("english")
- require.Nil(err, "%+v", err)
-
- cases := [][]byte{
- {7, 8, 9}, // TODO: 3 words -> 3 or 4 bytes
- {12, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes
- {0, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes, detect leading 0
- {1, 2, 3, 4, 5}, // normal
- {0, 0, 0, 0, 122, 23, 82, 195}, // leading 0s (8 chars, unclear)
- {0, 0, 0, 0, 5, 22, 123, 55, 22}, // leading 0s (9 chars, clear)
- {22, 44, 55, 1, 13, 0, 0, 0, 0}, // trailing 0s (9 chars, clear)
- {0, 5, 253, 2, 0}, // leading and trailing zeros
- {255, 196, 172, 234, 192, 255}, // big numbers
- {255, 196, 172, 1, 234, 192, 255}, // big numbers, two length choices
- // others?
- }
-
- for i, tc := range cases {
- w, err := codec.BytesToWords(tc)
- if assert.Nil(err, "%d: %v", i, err) {
- b, err := codec.WordsToBytes(w)
- if assert.Nil(err, "%d: %v", i, err) {
- assert.Equal(len(tc), len(b))
- assert.Equal(tc, b)
- }
- }
- }
-}
-
-func TestCheckInvalidLists(t *testing.T) {
- assert := assert.New(t)
-
- trivial := []string{"abc", "def"}
- short := make([]string, 1234)
- long := make([]string, BankSize+1)
- right := make([]string, BankSize)
- dups := make([]string, BankSize)
-
- for _, list := range [][]string{short, long, right, dups} {
- for i := range list {
- list[i] = cmn.RandStr(8)
- }
- }
- // create one single duplicate
- dups[192] = dups[782]
-
- cases := []struct {
- words []string
- loadable bool
- valid bool
- }{
- {trivial, false, false},
- {short, false, false},
- {long, false, false},
- {dups, true, false}, // we only check dups on first use...
- {right, true, true},
- }
-
- for i, tc := range cases {
- codec, err := NewCodec(tc.words)
- if !tc.loadable {
- assert.NotNil(err, "%d", i)
- } else if assert.Nil(err, "%d: %+v", i, err) {
- data := cmn.RandBytes(32)
- w, err := codec.BytesToWords(data)
- if tc.valid {
- assert.Nil(err, "%d: %+v", i, err)
- b, err1 := codec.WordsToBytes(w)
- assert.Nil(err1, "%d: %+v", i, err1)
- assert.Equal(data, b)
- } else {
- assert.NotNil(err, "%d", i)
- }
- }
- }
-
-}
-
-func getRandWord(c *WordCodec) string {
- idx := cmn.RandInt() % BankSize
- return c.words[idx]
-}
-
-func getDiffWord(c *WordCodec, not string) string {
- w := getRandWord(c)
- if w == not {
- w = getRandWord(c)
- }
- return w
-}
-
-func TestCheckTypoDetection(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- banks := []string{"english", "spanish", "japanese", "chinese_simplified"}
-
- for _, bank := range banks {
- codec, err := LoadCodec(bank)
- require.Nil(err, "%s: %+v", bank, err)
- for i := 0; i < 1000; i++ {
- numBytes := cmn.RandInt()%60 + 4
- data := cmn.RandBytes(numBytes)
-
- words, err := codec.BytesToWords(data)
- assert.Nil(err, "%s: %+v", bank, err)
- good, err := codec.WordsToBytes(words)
- assert.Nil(err, "%s: %+v", bank, err)
- assert.Equal(data, good, bank)
-
- // now try some tweaks...
- cut := words[1:]
- _, err = codec.WordsToBytes(cut)
- assert.NotNil(err, "%s: %s", bank, words)
-
- // swap a word within the bank, should fails
- words[3] = getDiffWord(codec, words[3])
- _, err = codec.WordsToBytes(words)
- assert.NotNil(err, "%s: %s", bank, words)
-
- // put a random word here, must fail
- words[3] = cmn.RandStr(10)
- _, err = codec.WordsToBytes(words)
- assert.NotNil(err, "%s: %s", bank, words)
- }
- }
-}
+++ /dev/null
-package keys
-
-import (
- "testing"
-
- cmn "github.com/tendermint/tmlibs/common"
-)
-
-func warmupCodec(bank string) *WordCodec {
- codec, err := LoadCodec(bank)
- if err != nil {
- panic(err)
- }
- _, err = codec.GetIndex(codec.words[123])
- if err != nil {
- panic(err)
- }
- return codec
-}
-
-func BenchmarkCodec(b *testing.B) {
- banks := []string{"english", "spanish", "japanese", "chinese_simplified"}
-
- for _, bank := range banks {
- b.Run(bank, func(sub *testing.B) {
- codec := warmupCodec(bank)
- sub.ResetTimer()
- benchSuite(sub, codec)
- })
- }
-}
-
-func benchSuite(b *testing.B, codec *WordCodec) {
- b.Run("to_words", func(sub *testing.B) {
- benchMakeWords(sub, codec)
- })
- b.Run("to_bytes", func(sub *testing.B) {
- benchParseWords(sub, codec)
- })
-}
-
-func benchMakeWords(b *testing.B, codec *WordCodec) {
- numBytes := 32
- data := cmn.RandBytes(numBytes)
- for i := 1; i <= b.N; i++ {
- _, err := codec.BytesToWords(data)
- if err != nil {
- panic(err)
- }
- }
-}
-
-func benchParseWords(b *testing.B, codec *WordCodec) {
- // generate a valid test string to parse
- numBytes := 32
- data := cmn.RandBytes(numBytes)
- words, err := codec.BytesToWords(data)
- if err != nil {
- panic(err)
- }
-
- for i := 1; i <= b.N; i++ {
- _, err := codec.WordsToBytes(words)
- if err != nil {
- panic(err)
- }
- }
-}
+++ /dev/null
-的
-一
-是
-在
-不
-了
-有
-和
-人
-这
-中
-大
-为
-上
-个
-国
-我
-以
-要
-他
-时
-来
-用
-们
-生
-到
-作
-地
-于
-出
-就
-分
-对
-成
-会
-可
-主
-发
-年
-动
-同
-工
-也
-能
-下
-过
-子
-说
-产
-种
-面
-而
-方
-后
-多
-定
-行
-学
-法
-所
-民
-得
-经
-十
-三
-之
-进
-着
-等
-部
-度
-家
-电
-力
-里
-如
-水
-化
-高
-自
-二
-理
-起
-小
-物
-现
-实
-加
-量
-都
-两
-体
-制
-机
-当
-使
-点
-从
-业
-本
-去
-把
-性
-好
-应
-开
-它
-合
-还
-因
-由
-其
-些
-然
-前
-外
-天
-政
-四
-日
-那
-社
-义
-事
-平
-形
-相
-全
-表
-间
-样
-与
-关
-各
-重
-新
-线
-内
-数
-正
-心
-反
-你
-明
-看
-原
-又
-么
-利
-比
-或
-但
-质
-气
-第
-向
-道
-命
-此
-变
-条
-只
-没
-结
-解
-问
-意
-建
-月
-公
-无
-系
-军
-很
-情
-者
-最
-立
-代
-想
-已
-通
-并
-提
-直
-题
-党
-程
-展
-五
-果
-料
-象
-员
-革
-位
-入
-常
-文
-总
-次
-品
-式
-活
-设
-及
-管
-特
-件
-长
-求
-老
-头
-基
-资
-边
-流
-路
-级
-少
-图
-山
-统
-接
-知
-较
-将
-组
-见
-计
-别
-她
-手
-角
-期
-根
-论
-运
-农
-指
-几
-九
-区
-强
-放
-决
-西
-被
-干
-做
-必
-战
-先
-回
-则
-任
-取
-据
-处
-队
-南
-给
-色
-光
-门
-即
-保
-治
-北
-造
-百
-规
-热
-领
-七
-海
-口
-东
-导
-器
-压
-志
-世
-金
-增
-争
-济
-阶
-油
-思
-术
-极
-交
-受
-联
-什
-认
-六
-共
-权
-收
-证
-改
-清
-美
-再
-采
-转
-更
-单
-风
-切
-打
-白
-教
-速
-花
-带
-安
-场
-身
-车
-例
-真
-务
-具
-万
-每
-目
-至
-达
-走
-积
-示
-议
-声
-报
-斗
-完
-类
-八
-离
-华
-名
-确
-才
-科
-张
-信
-马
-节
-话
-米
-整
-空
-元
-况
-今
-集
-温
-传
-土
-许
-步
-群
-广
-石
-记
-需
-段
-研
-界
-拉
-林
-律
-叫
-且
-究
-观
-越
-织
-装
-影
-算
-低
-持
-音
-众
-书
-布
-复
-容
-儿
-须
-际
-商
-非
-验
-连
-断
-深
-难
-近
-矿
-千
-周
-委
-素
-技
-备
-半
-办
-青
-省
-列
-习
-响
-约
-支
-般
-史
-感
-劳
-便
-团
-往
-酸
-历
-市
-克
-何
-除
-消
-构
-府
-称
-太
-准
-精
-值
-号
-率
-族
-维
-划
-选
-标
-写
-存
-候
-毛
-亲
-快
-效
-斯
-院
-查
-江
-型
-眼
-王
-按
-格
-养
-易
-置
-派
-层
-片
-始
-却
-专
-状
-育
-厂
-京
-识
-适
-属
-圆
-包
-火
-住
-调
-满
-县
-局
-照
-参
-红
-细
-引
-听
-该
-铁
-价
-严
-首
-底
-液
-官
-德
-随
-病
-苏
-失
-尔
-死
-讲
-配
-女
-黄
-推
-显
-谈
-罪
-神
-艺
-呢
-席
-含
-企
-望
-密
-批
-营
-项
-防
-举
-球
-英
-氧
-势
-告
-李
-台
-落
-木
-帮
-轮
-破
-亚
-师
-围
-注
-远
-字
-材
-排
-供
-河
-态
-封
-另
-施
-减
-树
-溶
-怎
-止
-案
-言
-士
-均
-武
-固
-叶
-鱼
-波
-视
-仅
-费
-紧
-爱
-左
-章
-早
-朝
-害
-续
-轻
-服
-试
-食
-充
-兵
-源
-判
-护
-司
-足
-某
-练
-差
-致
-板
-田
-降
-黑
-犯
-负
-击
-范
-继
-兴
-似
-余
-坚
-曲
-输
-修
-故
-城
-夫
-够
-送
-笔
-船
-占
-右
-财
-吃
-富
-春
-职
-觉
-汉
-画
-功
-巴
-跟
-虽
-杂
-飞
-检
-吸
-助
-升
-阳
-互
-初
-创
-抗
-考
-投
-坏
-策
-古
-径
-换
-未
-跑
-留
-钢
-曾
-端
-责
-站
-简
-述
-钱
-副
-尽
-帝
-射
-草
-冲
-承
-独
-令
-限
-阿
-宣
-环
-双
-请
-超
-微
-让
-控
-州
-良
-轴
-找
-否
-纪
-益
-依
-优
-顶
-础
-载
-倒
-房
-突
-坐
-粉
-敌
-略
-客
-袁
-冷
-胜
-绝
-析
-块
-剂
-测
-丝
-协
-诉
-念
-陈
-仍
-罗
-盐
-友
-洋
-错
-苦
-夜
-刑
-移
-频
-逐
-靠
-混
-母
-短
-皮
-终
-聚
-汽
-村
-云
-哪
-既
-距
-卫
-停
-烈
-央
-察
-烧
-迅
-境
-若
-印
-洲
-刻
-括
-激
-孔
-搞
-甚
-室
-待
-核
-校
-散
-侵
-吧
-甲
-游
-久
-菜
-味
-旧
-模
-湖
-货
-损
-预
-阻
-毫
-普
-稳
-乙
-妈
-植
-息
-扩
-银
-语
-挥
-酒
-守
-拿
-序
-纸
-医
-缺
-雨
-吗
-针
-刘
-啊
-急
-唱
-误
-训
-愿
-审
-附
-获
-茶
-鲜
-粮
-斤
-孩
-脱
-硫
-肥
-善
-龙
-演
-父
-渐
-血
-欢
-械
-掌
-歌
-沙
-刚
-攻
-谓
-盾
-讨
-晚
-粒
-乱
-燃
-矛
-乎
-杀
-药
-宁
-鲁
-贵
-钟
-煤
-读
-班
-伯
-香
-介
-迫
-句
-丰
-培
-握
-兰
-担
-弦
-蛋
-沉
-假
-穿
-执
-答
-乐
-谁
-顺
-烟
-缩
-征
-脸
-喜
-松
-脚
-困
-异
-免
-背
-星
-福
-买
-染
-井
-概
-慢
-怕
-磁
-倍
-祖
-皇
-促
-静
-补
-评
-翻
-肉
-践
-尼
-衣
-宽
-扬
-棉
-希
-伤
-操
-垂
-秋
-宜
-氢
-套
-督
-振
-架
-亮
-末
-宪
-庆
-编
-牛
-触
-映
-雷
-销
-诗
-座
-居
-抓
-裂
-胞
-呼
-娘
-景
-威
-绿
-晶
-厚
-盟
-衡
-鸡
-孙
-延
-危
-胶
-屋
-乡
-临
-陆
-顾
-掉
-呀
-灯
-岁
-措
-束
-耐
-剧
-玉
-赵
-跳
-哥
-季
-课
-凯
-胡
-额
-款
-绍
-卷
-齐
-伟
-蒸
-殖
-永
-宗
-苗
-川
-炉
-岩
-弱
-零
-杨
-奏
-沿
-露
-杆
-探
-滑
-镇
-饭
-浓
-航
-怀
-赶
-库
-夺
-伊
-灵
-税
-途
-灭
-赛
-归
-召
-鼓
-播
-盘
-裁
-险
-康
-唯
-录
-菌
-纯
-借
-糖
-盖
-横
-符
-私
-努
-堂
-域
-枪
-润
-幅
-哈
-竟
-熟
-虫
-泽
-脑
-壤
-碳
-欧
-遍
-侧
-寨
-敢
-彻
-虑
-斜
-薄
-庭
-纳
-弹
-饲
-伸
-折
-麦
-湿
-暗
-荷
-瓦
-塞
-床
-筑
-恶
-户
-访
-塔
-奇
-透
-梁
-刀
-旋
-迹
-卡
-氯
-遇
-份
-毒
-泥
-退
-洗
-摆
-灰
-彩
-卖
-耗
-夏
-择
-忙
-铜
-献
-硬
-予
-繁
-圈
-雪
-函
-亦
-抽
-篇
-阵
-阴
-丁
-尺
-追
-堆
-雄
-迎
-泛
-爸
-楼
-避
-谋
-吨
-野
-猪
-旗
-累
-偏
-典
-馆
-索
-秦
-脂
-潮
-爷
-豆
-忽
-托
-惊
-塑
-遗
-愈
-朱
-替
-纤
-粗
-倾
-尚
-痛
-楚
-谢
-奋
-购
-磨
-君
-池
-旁
-碎
-骨
-监
-捕
-弟
-暴
-割
-贯
-殊
-释
-词
-亡
-壁
-顿
-宝
-午
-尘
-闻
-揭
-炮
-残
-冬
-桥
-妇
-警
-综
-招
-吴
-付
-浮
-遭
-徐
-您
-摇
-谷
-赞
-箱
-隔
-订
-男
-吹
-园
-纷
-唐
-败
-宋
-玻
-巨
-耕
-坦
-荣
-闭
-湾
-键
-凡
-驻
-锅
-救
-恩
-剥
-凝
-碱
-齿
-截
-炼
-麻
-纺
-禁
-废
-盛
-版
-缓
-净
-睛
-昌
-婚
-涉
-筒
-嘴
-插
-岸
-朗
-庄
-街
-藏
-姑
-贸
-腐
-奴
-啦
-惯
-乘
-伙
-恢
-匀
-纱
-扎
-辩
-耳
-彪
-臣
-亿
-璃
-抵
-脉
-秀
-萨
-俄
-网
-舞
-店
-喷
-纵
-寸
-汗
-挂
-洪
-贺
-闪
-柬
-爆
-烯
-津
-稻
-墙
-软
-勇
-像
-滚
-厘
-蒙
-芳
-肯
-坡
-柱
-荡
-腿
-仪
-旅
-尾
-轧
-冰
-贡
-登
-黎
-削
-钻
-勒
-逃
-障
-氨
-郭
-峰
-币
-港
-伏
-轨
-亩
-毕
-擦
-莫
-刺
-浪
-秘
-援
-株
-健
-售
-股
-岛
-甘
-泡
-睡
-童
-铸
-汤
-阀
-休
-汇
-舍
-牧
-绕
-炸
-哲
-磷
-绩
-朋
-淡
-尖
-启
-陷
-柴
-呈
-徒
-颜
-泪
-稍
-忘
-泵
-蓝
-拖
-洞
-授
-镜
-辛
-壮
-锋
-贫
-虚
-弯
-摩
-泰
-幼
-廷
-尊
-窗
-纲
-弄
-隶
-疑
-氏
-宫
-姐
-震
-瑞
-怪
-尤
-琴
-循
-描
-膜
-违
-夹
-腰
-缘
-珠
-穷
-森
-枝
-竹
-沟
-催
-绳
-忆
-邦
-剩
-幸
-浆
-栏
-拥
-牙
-贮
-礼
-滤
-钠
-纹
-罢
-拍
-咱
-喊
-袖
-埃
-勤
-罚
-焦
-潜
-伍
-墨
-欲
-缝
-姓
-刊
-饱
-仿
-奖
-铝
-鬼
-丽
-跨
-默
-挖
-链
-扫
-喝
-袋
-炭
-污
-幕
-诸
-弧
-励
-梅
-奶
-洁
-灾
-舟
-鉴
-苯
-讼
-抱
-毁
-懂
-寒
-智
-埔
-寄
-届
-跃
-渡
-挑
-丹
-艰
-贝
-碰
-拔
-爹
-戴
-码
-梦
-芽
-熔
-赤
-渔
-哭
-敬
-颗
-奔
-铅
-仲
-虎
-稀
-妹
-乏
-珍
-申
-桌
-遵
-允
-隆
-螺
-仓
-魏
-锐
-晓
-氮
-兼
-隐
-碍
-赫
-拨
-忠
-肃
-缸
-牵
-抢
-博
-巧
-壳
-兄
-杜
-讯
-诚
-碧
-祥
-柯
-页
-巡
-矩
-悲
-灌
-龄
-伦
-票
-寻
-桂
-铺
-圣
-恐
-恰
-郑
-趣
-抬
-荒
-腾
-贴
-柔
-滴
-猛
-阔
-辆
-妻
-填
-撤
-储
-签
-闹
-扰
-紫
-砂
-递
-戏
-吊
-陶
-伐
-喂
-疗
-瓶
-婆
-抚
-臂
-摸
-忍
-虾
-蜡
-邻
-胸
-巩
-挤
-偶
-弃
-槽
-劲
-乳
-邓
-吉
-仁
-烂
-砖
-租
-乌
-舰
-伴
-瓜
-浅
-丙
-暂
-燥
-橡
-柳
-迷
-暖
-牌
-秧
-胆
-详
-簧
-踏
-瓷
-谱
-呆
-宾
-糊
-洛
-辉
-愤
-竞
-隙
-怒
-粘
-乃
-绪
-肩
-籍
-敏
-涂
-熙
-皆
-侦
-悬
-掘
-享
-纠
-醒
-狂
-锁
-淀
-恨
-牲
-霸
-爬
-赏
-逆
-玩
-陵
-祝
-秒
-浙
-貌
-役
-彼
-悉
-鸭
-趋
-凤
-晨
-畜
-辈
-秩
-卵
-署
-梯
-炎
-滩
-棋
-驱
-筛
-峡
-冒
-啥
-寿
-译
-浸
-泉
-帽
-迟
-硅
-疆
-贷
-漏
-稿
-冠
-嫩
-胁
-芯
-牢
-叛
-蚀
-奥
-鸣
-岭
-羊
-凭
-串
-塘
-绘
-酵
-融
-盆
-锡
-庙
-筹
-冻
-辅
-摄
-袭
-筋
-拒
-僚
-旱
-钾
-鸟
-漆
-沈
-眉
-疏
-添
-棒
-穗
-硝
-韩
-逼
-扭
-侨
-凉
-挺
-碗
-栽
-炒
-杯
-患
-馏
-劝
-豪
-辽
-勃
-鸿
-旦
-吏
-拜
-狗
-埋
-辊
-掩
-饮
-搬
-骂
-辞
-勾
-扣
-估
-蒋
-绒
-雾
-丈
-朵
-姆
-拟
-宇
-辑
-陕
-雕
-偿
-蓄
-崇
-剪
-倡
-厅
-咬
-驶
-薯
-刷
-斥
-番
-赋
-奉
-佛
-浇
-漫
-曼
-扇
-钙
-桃
-扶
-仔
-返
-俗
-亏
-腔
-鞋
-棱
-覆
-框
-悄
-叔
-撞
-骗
-勘
-旺
-沸
-孤
-吐
-孟
-渠
-屈
-疾
-妙
-惜
-仰
-狠
-胀
-谐
-抛
-霉
-桑
-岗
-嘛
-衰
-盗
-渗
-脏
-赖
-涌
-甜
-曹
-阅
-肌
-哩
-厉
-烃
-纬
-毅
-昨
-伪
-症
-煮
-叹
-钉
-搭
-茎
-笼
-酷
-偷
-弓
-锥
-恒
-杰
-坑
-鼻
-翼
-纶
-叙
-狱
-逮
-罐
-络
-棚
-抑
-膨
-蔬
-寺
-骤
-穆
-冶
-枯
-册
-尸
-凸
-绅
-坯
-牺
-焰
-轰
-欣
-晋
-瘦
-御
-锭
-锦
-丧
-旬
-锻
-垄
-搜
-扑
-邀
-亭
-酯
-迈
-舒
-脆
-酶
-闲
-忧
-酚
-顽
-羽
-涨
-卸
-仗
-陪
-辟
-惩
-杭
-姚
-肚
-捉
-飘
-漂
-昆
-欺
-吾
-郎
-烷
-汁
-呵
-饰
-萧
-雅
-邮
-迁
-燕
-撒
-姻
-赴
-宴
-烦
-债
-帐
-斑
-铃
-旨
-醇
-董
-饼
-雏
-姿
-拌
-傅
-腹
-妥
-揉
-贤
-拆
-歪
-葡
-胺
-丢
-浩
-徽
-昂
-垫
-挡
-览
-贪
-慰
-缴
-汪
-慌
-冯
-诺
-姜
-谊
-凶
-劣
-诬
-耀
-昏
-躺
-盈
-骑
-乔
-溪
-丛
-卢
-抹
-闷
-咨
-刮
-驾
-缆
-悟
-摘
-铒
-掷
-颇
-幻
-柄
-惠
-惨
-佳
-仇
-腊
-窝
-涤
-剑
-瞧
-堡
-泼
-葱
-罩
-霍
-捞
-胎
-苍
-滨
-俩
-捅
-湘
-砍
-霞
-邵
-萄
-疯
-淮
-遂
-熊
-粪
-烘
-宿
-档
-戈
-驳
-嫂
-裕
-徙
-箭
-捐
-肠
-撑
-晒
-辨
-殿
-莲
-摊
-搅
-酱
-屏
-疫
-哀
-蔡
-堵
-沫
-皱
-畅
-叠
-阁
-莱
-敲
-辖
-钩
-痕
-坝
-巷
-饿
-祸
-丘
-玄
-溜
-曰
-逻
-彭
-尝
-卿
-妨
-艇
-吞
-韦
-怨
-矮
-歇
+++ /dev/null
-abandon
-ability
-able
-about
-above
-absent
-absorb
-abstract
-absurd
-abuse
-access
-accident
-account
-accuse
-achieve
-acid
-acoustic
-acquire
-across
-act
-action
-actor
-actress
-actual
-adapt
-add
-addict
-address
-adjust
-admit
-adult
-advance
-advice
-aerobic
-affair
-afford
-afraid
-again
-age
-agent
-agree
-ahead
-aim
-air
-airport
-aisle
-alarm
-album
-alcohol
-alert
-alien
-all
-alley
-allow
-almost
-alone
-alpha
-already
-also
-alter
-always
-amateur
-amazing
-among
-amount
-amused
-analyst
-anchor
-ancient
-anger
-angle
-angry
-animal
-ankle
-announce
-annual
-another
-answer
-antenna
-antique
-anxiety
-any
-apart
-apology
-appear
-apple
-approve
-april
-arch
-arctic
-area
-arena
-argue
-arm
-armed
-armor
-army
-around
-arrange
-arrest
-arrive
-arrow
-art
-artefact
-artist
-artwork
-ask
-aspect
-assault
-asset
-assist
-assume
-asthma
-athlete
-atom
-attack
-attend
-attitude
-attract
-auction
-audit
-august
-aunt
-author
-auto
-autumn
-average
-avocado
-avoid
-awake
-aware
-away
-awesome
-awful
-awkward
-axis
-baby
-bachelor
-bacon
-badge
-bag
-balance
-balcony
-ball
-bamboo
-banana
-banner
-bar
-barely
-bargain
-barrel
-base
-basic
-basket
-battle
-beach
-bean
-beauty
-because
-become
-beef
-before
-begin
-behave
-behind
-believe
-below
-belt
-bench
-benefit
-best
-betray
-better
-between
-beyond
-bicycle
-bid
-bike
-bind
-biology
-bird
-birth
-bitter
-black
-blade
-blame
-blanket
-blast
-bleak
-bless
-blind
-blood
-blossom
-blouse
-blue
-blur
-blush
-board
-boat
-body
-boil
-bomb
-bone
-bonus
-book
-boost
-border
-boring
-borrow
-boss
-bottom
-bounce
-box
-boy
-bracket
-brain
-brand
-brass
-brave
-bread
-breeze
-brick
-bridge
-brief
-bright
-bring
-brisk
-broccoli
-broken
-bronze
-broom
-brother
-brown
-brush
-bubble
-buddy
-budget
-buffalo
-build
-bulb
-bulk
-bullet
-bundle
-bunker
-burden
-burger
-burst
-bus
-business
-busy
-butter
-buyer
-buzz
-cabbage
-cabin
-cable
-cactus
-cage
-cake
-call
-calm
-camera
-camp
-can
-canal
-cancel
-candy
-cannon
-canoe
-canvas
-canyon
-capable
-capital
-captain
-car
-carbon
-card
-cargo
-carpet
-carry
-cart
-case
-cash
-casino
-castle
-casual
-cat
-catalog
-catch
-category
-cattle
-caught
-cause
-caution
-cave
-ceiling
-celery
-cement
-census
-century
-cereal
-certain
-chair
-chalk
-champion
-change
-chaos
-chapter
-charge
-chase
-chat
-cheap
-check
-cheese
-chef
-cherry
-chest
-chicken
-chief
-child
-chimney
-choice
-choose
-chronic
-chuckle
-chunk
-churn
-cigar
-cinnamon
-circle
-citizen
-city
-civil
-claim
-clap
-clarify
-claw
-clay
-clean
-clerk
-clever
-click
-client
-cliff
-climb
-clinic
-clip
-clock
-clog
-close
-cloth
-cloud
-clown
-club
-clump
-cluster
-clutch
-coach
-coast
-coconut
-code
-coffee
-coil
-coin
-collect
-color
-column
-combine
-come
-comfort
-comic
-common
-company
-concert
-conduct
-confirm
-congress
-connect
-consider
-control
-convince
-cook
-cool
-copper
-copy
-coral
-core
-corn
-correct
-cost
-cotton
-couch
-country
-couple
-course
-cousin
-cover
-coyote
-crack
-cradle
-craft
-cram
-crane
-crash
-crater
-crawl
-crazy
-cream
-credit
-creek
-crew
-cricket
-crime
-crisp
-critic
-crop
-cross
-crouch
-crowd
-crucial
-cruel
-cruise
-crumble
-crunch
-crush
-cry
-crystal
-cube
-culture
-cup
-cupboard
-curious
-current
-curtain
-curve
-cushion
-custom
-cute
-cycle
-dad
-damage
-damp
-dance
-danger
-daring
-dash
-daughter
-dawn
-day
-deal
-debate
-debris
-decade
-december
-decide
-decline
-decorate
-decrease
-deer
-defense
-define
-defy
-degree
-delay
-deliver
-demand
-demise
-denial
-dentist
-deny
-depart
-depend
-deposit
-depth
-deputy
-derive
-describe
-desert
-design
-desk
-despair
-destroy
-detail
-detect
-develop
-device
-devote
-diagram
-dial
-diamond
-diary
-dice
-diesel
-diet
-differ
-digital
-dignity
-dilemma
-dinner
-dinosaur
-direct
-dirt
-disagree
-discover
-disease
-dish
-dismiss
-disorder
-display
-distance
-divert
-divide
-divorce
-dizzy
-doctor
-document
-dog
-doll
-dolphin
-domain
-donate
-donkey
-donor
-door
-dose
-double
-dove
-draft
-dragon
-drama
-drastic
-draw
-dream
-dress
-drift
-drill
-drink
-drip
-drive
-drop
-drum
-dry
-duck
-dumb
-dune
-during
-dust
-dutch
-duty
-dwarf
-dynamic
-eager
-eagle
-early
-earn
-earth
-easily
-east
-easy
-echo
-ecology
-economy
-edge
-edit
-educate
-effort
-egg
-eight
-either
-elbow
-elder
-electric
-elegant
-element
-elephant
-elevator
-elite
-else
-embark
-embody
-embrace
-emerge
-emotion
-employ
-empower
-empty
-enable
-enact
-end
-endless
-endorse
-enemy
-energy
-enforce
-engage
-engine
-enhance
-enjoy
-enlist
-enough
-enrich
-enroll
-ensure
-enter
-entire
-entry
-envelope
-episode
-equal
-equip
-era
-erase
-erode
-erosion
-error
-erupt
-escape
-essay
-essence
-estate
-eternal
-ethics
-evidence
-evil
-evoke
-evolve
-exact
-example
-excess
-exchange
-excite
-exclude
-excuse
-execute
-exercise
-exhaust
-exhibit
-exile
-exist
-exit
-exotic
-expand
-expect
-expire
-explain
-expose
-express
-extend
-extra
-eye
-eyebrow
-fabric
-face
-faculty
-fade
-faint
-faith
-fall
-false
-fame
-family
-famous
-fan
-fancy
-fantasy
-farm
-fashion
-fat
-fatal
-father
-fatigue
-fault
-favorite
-feature
-february
-federal
-fee
-feed
-feel
-female
-fence
-festival
-fetch
-fever
-few
-fiber
-fiction
-field
-figure
-file
-film
-filter
-final
-find
-fine
-finger
-finish
-fire
-firm
-first
-fiscal
-fish
-fit
-fitness
-fix
-flag
-flame
-flash
-flat
-flavor
-flee
-flight
-flip
-float
-flock
-floor
-flower
-fluid
-flush
-fly
-foam
-focus
-fog
-foil
-fold
-follow
-food
-foot
-force
-forest
-forget
-fork
-fortune
-forum
-forward
-fossil
-foster
-found
-fox
-fragile
-frame
-frequent
-fresh
-friend
-fringe
-frog
-front
-frost
-frown
-frozen
-fruit
-fuel
-fun
-funny
-furnace
-fury
-future
-gadget
-gain
-galaxy
-gallery
-game
-gap
-garage
-garbage
-garden
-garlic
-garment
-gas
-gasp
-gate
-gather
-gauge
-gaze
-general
-genius
-genre
-gentle
-genuine
-gesture
-ghost
-giant
-gift
-giggle
-ginger
-giraffe
-girl
-give
-glad
-glance
-glare
-glass
-glide
-glimpse
-globe
-gloom
-glory
-glove
-glow
-glue
-goat
-goddess
-gold
-good
-goose
-gorilla
-gospel
-gossip
-govern
-gown
-grab
-grace
-grain
-grant
-grape
-grass
-gravity
-great
-green
-grid
-grief
-grit
-grocery
-group
-grow
-grunt
-guard
-guess
-guide
-guilt
-guitar
-gun
-gym
-habit
-hair
-half
-hammer
-hamster
-hand
-happy
-harbor
-hard
-harsh
-harvest
-hat
-have
-hawk
-hazard
-head
-health
-heart
-heavy
-hedgehog
-height
-hello
-helmet
-help
-hen
-hero
-hidden
-high
-hill
-hint
-hip
-hire
-history
-hobby
-hockey
-hold
-hole
-holiday
-hollow
-home
-honey
-hood
-hope
-horn
-horror
-horse
-hospital
-host
-hotel
-hour
-hover
-hub
-huge
-human
-humble
-humor
-hundred
-hungry
-hunt
-hurdle
-hurry
-hurt
-husband
-hybrid
-ice
-icon
-idea
-identify
-idle
-ignore
-ill
-illegal
-illness
-image
-imitate
-immense
-immune
-impact
-impose
-improve
-impulse
-inch
-include
-income
-increase
-index
-indicate
-indoor
-industry
-infant
-inflict
-inform
-inhale
-inherit
-initial
-inject
-injury
-inmate
-inner
-innocent
-input
-inquiry
-insane
-insect
-inside
-inspire
-install
-intact
-interest
-into
-invest
-invite
-involve
-iron
-island
-isolate
-issue
-item
-ivory
-jacket
-jaguar
-jar
-jazz
-jealous
-jeans
-jelly
-jewel
-job
-join
-joke
-journey
-joy
-judge
-juice
-jump
-jungle
-junior
-junk
-just
-kangaroo
-keen
-keep
-ketchup
-key
-kick
-kid
-kidney
-kind
-kingdom
-kiss
-kit
-kitchen
-kite
-kitten
-kiwi
-knee
-knife
-knock
-know
-lab
-label
-labor
-ladder
-lady
-lake
-lamp
-language
-laptop
-large
-later
-latin
-laugh
-laundry
-lava
-law
-lawn
-lawsuit
-layer
-lazy
-leader
-leaf
-learn
-leave
-lecture
-left
-leg
-legal
-legend
-leisure
-lemon
-lend
-length
-lens
-leopard
-lesson
-letter
-level
-liar
-liberty
-library
-license
-life
-lift
-light
-like
-limb
-limit
-link
-lion
-liquid
-list
-little
-live
-lizard
-load
-loan
-lobster
-local
-lock
-logic
-lonely
-long
-loop
-lottery
-loud
-lounge
-love
-loyal
-lucky
-luggage
-lumber
-lunar
-lunch
-luxury
-lyrics
-machine
-mad
-magic
-magnet
-maid
-mail
-main
-major
-make
-mammal
-man
-manage
-mandate
-mango
-mansion
-manual
-maple
-marble
-march
-margin
-marine
-market
-marriage
-mask
-mass
-master
-match
-material
-math
-matrix
-matter
-maximum
-maze
-meadow
-mean
-measure
-meat
-mechanic
-medal
-media
-melody
-melt
-member
-memory
-mention
-menu
-mercy
-merge
-merit
-merry
-mesh
-message
-metal
-method
-middle
-midnight
-milk
-million
-mimic
-mind
-minimum
-minor
-minute
-miracle
-mirror
-misery
-miss
-mistake
-mix
-mixed
-mixture
-mobile
-model
-modify
-mom
-moment
-monitor
-monkey
-monster
-month
-moon
-moral
-more
-morning
-mosquito
-mother
-motion
-motor
-mountain
-mouse
-move
-movie
-much
-muffin
-mule
-multiply
-muscle
-museum
-mushroom
-music
-must
-mutual
-myself
-mystery
-myth
-naive
-name
-napkin
-narrow
-nasty
-nation
-nature
-near
-neck
-need
-negative
-neglect
-neither
-nephew
-nerve
-nest
-net
-network
-neutral
-never
-news
-next
-nice
-night
-noble
-noise
-nominee
-noodle
-normal
-north
-nose
-notable
-note
-nothing
-notice
-novel
-now
-nuclear
-number
-nurse
-nut
-oak
-obey
-object
-oblige
-obscure
-observe
-obtain
-obvious
-occur
-ocean
-october
-odor
-off
-offer
-office
-often
-oil
-okay
-old
-olive
-olympic
-omit
-once
-one
-onion
-online
-only
-open
-opera
-opinion
-oppose
-option
-orange
-orbit
-orchard
-order
-ordinary
-organ
-orient
-original
-orphan
-ostrich
-other
-outdoor
-outer
-output
-outside
-oval
-oven
-over
-own
-owner
-oxygen
-oyster
-ozone
-pact
-paddle
-page
-pair
-palace
-palm
-panda
-panel
-panic
-panther
-paper
-parade
-parent
-park
-parrot
-party
-pass
-patch
-path
-patient
-patrol
-pattern
-pause
-pave
-payment
-peace
-peanut
-pear
-peasant
-pelican
-pen
-penalty
-pencil
-people
-pepper
-perfect
-permit
-person
-pet
-phone
-photo
-phrase
-physical
-piano
-picnic
-picture
-piece
-pig
-pigeon
-pill
-pilot
-pink
-pioneer
-pipe
-pistol
-pitch
-pizza
-place
-planet
-plastic
-plate
-play
-please
-pledge
-pluck
-plug
-plunge
-poem
-poet
-point
-polar
-pole
-police
-pond
-pony
-pool
-popular
-portion
-position
-possible
-post
-potato
-pottery
-poverty
-powder
-power
-practice
-praise
-predict
-prefer
-prepare
-present
-pretty
-prevent
-price
-pride
-primary
-print
-priority
-prison
-private
-prize
-problem
-process
-produce
-profit
-program
-project
-promote
-proof
-property
-prosper
-protect
-proud
-provide
-public
-pudding
-pull
-pulp
-pulse
-pumpkin
-punch
-pupil
-puppy
-purchase
-purity
-purpose
-purse
-push
-put
-puzzle
-pyramid
-quality
-quantum
-quarter
-question
-quick
-quit
-quiz
-quote
-rabbit
-raccoon
-race
-rack
-radar
-radio
-rail
-rain
-raise
-rally
-ramp
-ranch
-random
-range
-rapid
-rare
-rate
-rather
-raven
-raw
-razor
-ready
-real
-reason
-rebel
-rebuild
-recall
-receive
-recipe
-record
-recycle
-reduce
-reflect
-reform
-refuse
-region
-regret
-regular
-reject
-relax
-release
-relief
-rely
-remain
-remember
-remind
-remove
-render
-renew
-rent
-reopen
-repair
-repeat
-replace
-report
-require
-rescue
-resemble
-resist
-resource
-response
-result
-retire
-retreat
-return
-reunion
-reveal
-review
-reward
-rhythm
-rib
-ribbon
-rice
-rich
-ride
-ridge
-rifle
-right
-rigid
-ring
-riot
-ripple
-risk
-ritual
-rival
-river
-road
-roast
-robot
-robust
-rocket
-romance
-roof
-rookie
-room
-rose
-rotate
-rough
-round
-route
-royal
-rubber
-rude
-rug
-rule
-run
-runway
-rural
-sad
-saddle
-sadness
-safe
-sail
-salad
-salmon
-salon
-salt
-salute
-same
-sample
-sand
-satisfy
-satoshi
-sauce
-sausage
-save
-say
-scale
-scan
-scare
-scatter
-scene
-scheme
-school
-science
-scissors
-scorpion
-scout
-scrap
-screen
-script
-scrub
-sea
-search
-season
-seat
-second
-secret
-section
-security
-seed
-seek
-segment
-select
-sell
-seminar
-senior
-sense
-sentence
-series
-service
-session
-settle
-setup
-seven
-shadow
-shaft
-shallow
-share
-shed
-shell
-sheriff
-shield
-shift
-shine
-ship
-shiver
-shock
-shoe
-shoot
-shop
-short
-shoulder
-shove
-shrimp
-shrug
-shuffle
-shy
-sibling
-sick
-side
-siege
-sight
-sign
-silent
-silk
-silly
-silver
-similar
-simple
-since
-sing
-siren
-sister
-situate
-six
-size
-skate
-sketch
-ski
-skill
-skin
-skirt
-skull
-slab
-slam
-sleep
-slender
-slice
-slide
-slight
-slim
-slogan
-slot
-slow
-slush
-small
-smart
-smile
-smoke
-smooth
-snack
-snake
-snap
-sniff
-snow
-soap
-soccer
-social
-sock
-soda
-soft
-solar
-soldier
-solid
-solution
-solve
-someone
-song
-soon
-sorry
-sort
-soul
-sound
-soup
-source
-south
-space
-spare
-spatial
-spawn
-speak
-special
-speed
-spell
-spend
-sphere
-spice
-spider
-spike
-spin
-spirit
-split
-spoil
-sponsor
-spoon
-sport
-spot
-spray
-spread
-spring
-spy
-square
-squeeze
-squirrel
-stable
-stadium
-staff
-stage
-stairs
-stamp
-stand
-start
-state
-stay
-steak
-steel
-stem
-step
-stereo
-stick
-still
-sting
-stock
-stomach
-stone
-stool
-story
-stove
-strategy
-street
-strike
-strong
-struggle
-student
-stuff
-stumble
-style
-subject
-submit
-subway
-success
-such
-sudden
-suffer
-sugar
-suggest
-suit
-summer
-sun
-sunny
-sunset
-super
-supply
-supreme
-sure
-surface
-surge
-surprise
-surround
-survey
-suspect
-sustain
-swallow
-swamp
-swap
-swarm
-swear
-sweet
-swift
-swim
-swing
-switch
-sword
-symbol
-symptom
-syrup
-system
-table
-tackle
-tag
-tail
-talent
-talk
-tank
-tape
-target
-task
-taste
-tattoo
-taxi
-teach
-team
-tell
-ten
-tenant
-tennis
-tent
-term
-test
-text
-thank
-that
-theme
-then
-theory
-there
-they
-thing
-this
-thought
-three
-thrive
-throw
-thumb
-thunder
-ticket
-tide
-tiger
-tilt
-timber
-time
-tiny
-tip
-tired
-tissue
-title
-toast
-tobacco
-today
-toddler
-toe
-together
-toilet
-token
-tomato
-tomorrow
-tone
-tongue
-tonight
-tool
-tooth
-top
-topic
-topple
-torch
-tornado
-tortoise
-toss
-total
-tourist
-toward
-tower
-town
-toy
-track
-trade
-traffic
-tragic
-train
-transfer
-trap
-trash
-travel
-tray
-treat
-tree
-trend
-trial
-tribe
-trick
-trigger
-trim
-trip
-trophy
-trouble
-truck
-true
-truly
-trumpet
-trust
-truth
-try
-tube
-tuition
-tumble
-tuna
-tunnel
-turkey
-turn
-turtle
-twelve
-twenty
-twice
-twin
-twist
-two
-type
-typical
-ugly
-umbrella
-unable
-unaware
-uncle
-uncover
-under
-undo
-unfair
-unfold
-unhappy
-uniform
-unique
-unit
-universe
-unknown
-unlock
-until
-unusual
-unveil
-update
-upgrade
-uphold
-upon
-upper
-upset
-urban
-urge
-usage
-use
-used
-useful
-useless
-usual
-utility
-vacant
-vacuum
-vague
-valid
-valley
-valve
-van
-vanish
-vapor
-various
-vast
-vault
-vehicle
-velvet
-vendor
-venture
-venue
-verb
-verify
-version
-very
-vessel
-veteran
-viable
-vibrant
-vicious
-victory
-video
-view
-village
-vintage
-violin
-virtual
-virus
-visa
-visit
-visual
-vital
-vivid
-vocal
-voice
-void
-volcano
-volume
-vote
-voyage
-wage
-wagon
-wait
-walk
-wall
-walnut
-want
-warfare
-warm
-warrior
-wash
-wasp
-waste
-water
-wave
-way
-wealth
-weapon
-wear
-weasel
-weather
-web
-wedding
-weekend
-weird
-welcome
-west
-wet
-whale
-what
-wheat
-wheel
-when
-where
-whip
-whisper
-wide
-width
-wife
-wild
-will
-win
-window
-wine
-wing
-wink
-winner
-winter
-wire
-wisdom
-wise
-wish
-witness
-wolf
-woman
-wonder
-wood
-wool
-word
-work
-world
-worry
-worth
-wrap
-wreck
-wrestle
-wrist
-write
-wrong
-yard
-year
-yellow
-you
-young
-youth
-zebra
-zero
-zone
-zoo
+++ /dev/null
-あいこくしん
-あいさつ
-あいだ
-あおぞら
-あかちゃん
-あきる
-あけがた
-あける
-あこがれる
-あさい
-あさひ
-あしあと
-あじわう
-あずかる
-あずき
-あそぶ
-あたえる
-あたためる
-あたりまえ
-あたる
-あつい
-あつかう
-あっしゅく
-あつまり
-あつめる
-あてな
-あてはまる
-あひる
-あぶら
-あぶる
-あふれる
-あまい
-あまど
-あまやかす
-あまり
-あみもの
-あめりか
-あやまる
-あゆむ
-あらいぐま
-あらし
-あらすじ
-あらためる
-あらゆる
-あらわす
-ありがとう
-あわせる
-あわてる
-あんい
-あんがい
-あんこ
-あんぜん
-あんてい
-あんない
-あんまり
-いいだす
-いおん
-いがい
-いがく
-いきおい
-いきなり
-いきもの
-いきる
-いくじ
-いくぶん
-いけばな
-いけん
-いこう
-いこく
-いこつ
-いさましい
-いさん
-いしき
-いじゅう
-いじょう
-いじわる
-いずみ
-いずれ
-いせい
-いせえび
-いせかい
-いせき
-いぜん
-いそうろう
-いそがしい
-いだい
-いだく
-いたずら
-いたみ
-いたりあ
-いちおう
-いちじ
-いちど
-いちば
-いちぶ
-いちりゅう
-いつか
-いっしゅん
-いっせい
-いっそう
-いったん
-いっち
-いってい
-いっぽう
-いてざ
-いてん
-いどう
-いとこ
-いない
-いなか
-いねむり
-いのち
-いのる
-いはつ
-いばる
-いはん
-いびき
-いひん
-いふく
-いへん
-いほう
-いみん
-いもうと
-いもたれ
-いもり
-いやがる
-いやす
-いよかん
-いよく
-いらい
-いらすと
-いりぐち
-いりょう
-いれい
-いれもの
-いれる
-いろえんぴつ
-いわい
-いわう
-いわかん
-いわば
-いわゆる
-いんげんまめ
-いんさつ
-いんしょう
-いんよう
-うえき
-うえる
-うおざ
-うがい
-うかぶ
-うかべる
-うきわ
-うくらいな
-うくれれ
-うけたまわる
-うけつけ
-うけとる
-うけもつ
-うける
-うごかす
-うごく
-うこん
-うさぎ
-うしなう
-うしろがみ
-うすい
-うすぎ
-うすぐらい
-うすめる
-うせつ
-うちあわせ
-うちがわ
-うちき
-うちゅう
-うっかり
-うつくしい
-うったえる
-うつる
-うどん
-うなぎ
-うなじ
-うなずく
-うなる
-うねる
-うのう
-うぶげ
-うぶごえ
-うまれる
-うめる
-うもう
-うやまう
-うよく
-うらがえす
-うらぐち
-うらない
-うりあげ
-うりきれ
-うるさい
-うれしい
-うれゆき
-うれる
-うろこ
-うわき
-うわさ
-うんこう
-うんちん
-うんてん
-うんどう
-えいえん
-えいが
-えいきょう
-えいご
-えいせい
-えいぶん
-えいよう
-えいわ
-えおり
-えがお
-えがく
-えきたい
-えくせる
-えしゃく
-えすて
-えつらん
-えのぐ
-えほうまき
-えほん
-えまき
-えもじ
-えもの
-えらい
-えらぶ
-えりあ
-えんえん
-えんかい
-えんぎ
-えんげき
-えんしゅう
-えんぜつ
-えんそく
-えんちょう
-えんとつ
-おいかける
-おいこす
-おいしい
-おいつく
-おうえん
-おうさま
-おうじ
-おうせつ
-おうたい
-おうふく
-おうべい
-おうよう
-おえる
-おおい
-おおう
-おおどおり
-おおや
-おおよそ
-おかえり
-おかず
-おがむ
-おかわり
-おぎなう
-おきる
-おくさま
-おくじょう
-おくりがな
-おくる
-おくれる
-おこす
-おこなう
-おこる
-おさえる
-おさない
-おさめる
-おしいれ
-おしえる
-おじぎ
-おじさん
-おしゃれ
-おそらく
-おそわる
-おたがい
-おたく
-おだやか
-おちつく
-おっと
-おつり
-おでかけ
-おとしもの
-おとなしい
-おどり
-おどろかす
-おばさん
-おまいり
-おめでとう
-おもいで
-おもう
-おもたい
-おもちゃ
-おやつ
-おやゆび
-およぼす
-おらんだ
-おろす
-おんがく
-おんけい
-おんしゃ
-おんせん
-おんだん
-おんちゅう
-おんどけい
-かあつ
-かいが
-がいき
-がいけん
-がいこう
-かいさつ
-かいしゃ
-かいすいよく
-かいぜん
-かいぞうど
-かいつう
-かいてん
-かいとう
-かいふく
-がいへき
-かいほう
-かいよう
-がいらい
-かいわ
-かえる
-かおり
-かかえる
-かがく
-かがし
-かがみ
-かくご
-かくとく
-かざる
-がぞう
-かたい
-かたち
-がちょう
-がっきゅう
-がっこう
-がっさん
-がっしょう
-かなざわし
-かのう
-がはく
-かぶか
-かほう
-かほご
-かまう
-かまぼこ
-かめれおん
-かゆい
-かようび
-からい
-かるい
-かろう
-かわく
-かわら
-がんか
-かんけい
-かんこう
-かんしゃ
-かんそう
-かんたん
-かんち
-がんばる
-きあい
-きあつ
-きいろ
-ぎいん
-きうい
-きうん
-きえる
-きおう
-きおく
-きおち
-きおん
-きかい
-きかく
-きかんしゃ
-ききて
-きくばり
-きくらげ
-きけんせい
-きこう
-きこえる
-きこく
-きさい
-きさく
-きさま
-きさらぎ
-ぎじかがく
-ぎしき
-ぎじたいけん
-ぎじにってい
-ぎじゅつしゃ
-きすう
-きせい
-きせき
-きせつ
-きそう
-きぞく
-きぞん
-きたえる
-きちょう
-きつえん
-ぎっちり
-きつつき
-きつね
-きてい
-きどう
-きどく
-きない
-きなが
-きなこ
-きぬごし
-きねん
-きのう
-きのした
-きはく
-きびしい
-きひん
-きふく
-きぶん
-きぼう
-きほん
-きまる
-きみつ
-きむずかしい
-きめる
-きもだめし
-きもち
-きもの
-きゃく
-きやく
-ぎゅうにく
-きよう
-きょうりゅう
-きらい
-きらく
-きりん
-きれい
-きれつ
-きろく
-ぎろん
-きわめる
-ぎんいろ
-きんかくじ
-きんじょ
-きんようび
-ぐあい
-くいず
-くうかん
-くうき
-くうぐん
-くうこう
-ぐうせい
-くうそう
-ぐうたら
-くうふく
-くうぼ
-くかん
-くきょう
-くげん
-ぐこう
-くさい
-くさき
-くさばな
-くさる
-くしゃみ
-くしょう
-くすのき
-くすりゆび
-くせげ
-くせん
-ぐたいてき
-くださる
-くたびれる
-くちこみ
-くちさき
-くつした
-ぐっすり
-くつろぐ
-くとうてん
-くどく
-くなん
-くねくね
-くのう
-くふう
-くみあわせ
-くみたてる
-くめる
-くやくしょ
-くらす
-くらべる
-くるま
-くれる
-くろう
-くわしい
-ぐんかん
-ぐんしょく
-ぐんたい
-ぐんて
-けあな
-けいかく
-けいけん
-けいこ
-けいさつ
-げいじゅつ
-けいたい
-げいのうじん
-けいれき
-けいろ
-けおとす
-けおりもの
-げきか
-げきげん
-げきだん
-げきちん
-げきとつ
-げきは
-げきやく
-げこう
-げこくじょう
-げざい
-けさき
-げざん
-けしき
-けしごむ
-けしょう
-げすと
-けたば
-けちゃっぷ
-けちらす
-けつあつ
-けつい
-けつえき
-けっこん
-けつじょ
-けっせき
-けってい
-けつまつ
-げつようび
-げつれい
-けつろん
-げどく
-けとばす
-けとる
-けなげ
-けなす
-けなみ
-けぬき
-げねつ
-けねん
-けはい
-げひん
-けぶかい
-げぼく
-けまり
-けみかる
-けむし
-けむり
-けもの
-けらい
-けろけろ
-けわしい
-けんい
-けんえつ
-けんお
-けんか
-げんき
-けんげん
-けんこう
-けんさく
-けんしゅう
-けんすう
-げんそう
-けんちく
-けんてい
-けんとう
-けんない
-けんにん
-げんぶつ
-けんま
-けんみん
-けんめい
-けんらん
-けんり
-こあくま
-こいぬ
-こいびと
-ごうい
-こうえん
-こうおん
-こうかん
-ごうきゅう
-ごうけい
-こうこう
-こうさい
-こうじ
-こうすい
-ごうせい
-こうそく
-こうたい
-こうちゃ
-こうつう
-こうてい
-こうどう
-こうない
-こうはい
-ごうほう
-ごうまん
-こうもく
-こうりつ
-こえる
-こおり
-ごかい
-ごがつ
-ごかん
-こくご
-こくさい
-こくとう
-こくない
-こくはく
-こぐま
-こけい
-こける
-ここのか
-こころ
-こさめ
-こしつ
-こすう
-こせい
-こせき
-こぜん
-こそだて
-こたい
-こたえる
-こたつ
-こちょう
-こっか
-こつこつ
-こつばん
-こつぶ
-こてい
-こてん
-ことがら
-ことし
-ことば
-ことり
-こなごな
-こねこね
-このまま
-このみ
-このよ
-ごはん
-こひつじ
-こふう
-こふん
-こぼれる
-ごまあぶら
-こまかい
-ごますり
-こまつな
-こまる
-こむぎこ
-こもじ
-こもち
-こもの
-こもん
-こやく
-こやま
-こゆう
-こゆび
-こよい
-こよう
-こりる
-これくしょん
-ころっけ
-こわもて
-こわれる
-こんいん
-こんかい
-こんき
-こんしゅう
-こんすい
-こんだて
-こんとん
-こんなん
-こんびに
-こんぽん
-こんまけ
-こんや
-こんれい
-こんわく
-ざいえき
-さいかい
-さいきん
-ざいげん
-ざいこ
-さいしょ
-さいせい
-ざいたく
-ざいちゅう
-さいてき
-ざいりょう
-さうな
-さかいし
-さがす
-さかな
-さかみち
-さがる
-さぎょう
-さくし
-さくひん
-さくら
-さこく
-さこつ
-さずかる
-ざせき
-さたん
-さつえい
-ざつおん
-ざっか
-ざつがく
-さっきょく
-ざっし
-さつじん
-ざっそう
-さつたば
-さつまいも
-さてい
-さといも
-さとう
-さとおや
-さとし
-さとる
-さのう
-さばく
-さびしい
-さべつ
-さほう
-さほど
-さます
-さみしい
-さみだれ
-さむけ
-さめる
-さやえんどう
-さゆう
-さよう
-さよく
-さらだ
-ざるそば
-さわやか
-さわる
-さんいん
-さんか
-さんきゃく
-さんこう
-さんさい
-ざんしょ
-さんすう
-さんせい
-さんそ
-さんち
-さんま
-さんみ
-さんらん
-しあい
-しあげ
-しあさって
-しあわせ
-しいく
-しいん
-しうち
-しえい
-しおけ
-しかい
-しかく
-じかん
-しごと
-しすう
-じだい
-したうけ
-したぎ
-したて
-したみ
-しちょう
-しちりん
-しっかり
-しつじ
-しつもん
-してい
-してき
-してつ
-じてん
-じどう
-しなぎれ
-しなもの
-しなん
-しねま
-しねん
-しのぐ
-しのぶ
-しはい
-しばかり
-しはつ
-しはらい
-しはん
-しひょう
-しふく
-じぶん
-しへい
-しほう
-しほん
-しまう
-しまる
-しみん
-しむける
-じむしょ
-しめい
-しめる
-しもん
-しゃいん
-しゃうん
-しゃおん
-じゃがいも
-しやくしょ
-しゃくほう
-しゃけん
-しゃこ
-しゃざい
-しゃしん
-しゃせん
-しゃそう
-しゃたい
-しゃちょう
-しゃっきん
-じゃま
-しゃりん
-しゃれい
-じゆう
-じゅうしょ
-しゅくはく
-じゅしん
-しゅっせき
-しゅみ
-しゅらば
-じゅんばん
-しょうかい
-しょくたく
-しょっけん
-しょどう
-しょもつ
-しらせる
-しらべる
-しんか
-しんこう
-じんじゃ
-しんせいじ
-しんちく
-しんりん
-すあげ
-すあし
-すあな
-ずあん
-すいえい
-すいか
-すいとう
-ずいぶん
-すいようび
-すうがく
-すうじつ
-すうせん
-すおどり
-すきま
-すくう
-すくない
-すける
-すごい
-すこし
-ずさん
-すずしい
-すすむ
-すすめる
-すっかり
-ずっしり
-ずっと
-すてき
-すてる
-すねる
-すのこ
-すはだ
-すばらしい
-ずひょう
-ずぶぬれ
-すぶり
-すふれ
-すべて
-すべる
-ずほう
-すぼん
-すまい
-すめし
-すもう
-すやき
-すらすら
-するめ
-すれちがう
-すろっと
-すわる
-すんぜん
-すんぽう
-せあぶら
-せいかつ
-せいげん
-せいじ
-せいよう
-せおう
-せかいかん
-せきにん
-せきむ
-せきゆ
-せきらんうん
-せけん
-せこう
-せすじ
-せたい
-せたけ
-せっかく
-せっきゃく
-ぜっく
-せっけん
-せっこつ
-せっさたくま
-せつぞく
-せつだん
-せつでん
-せっぱん
-せつび
-せつぶん
-せつめい
-せつりつ
-せなか
-せのび
-せはば
-せびろ
-せぼね
-せまい
-せまる
-せめる
-せもたれ
-せりふ
-ぜんあく
-せんい
-せんえい
-せんか
-せんきょ
-せんく
-せんげん
-ぜんご
-せんさい
-せんしゅ
-せんすい
-せんせい
-せんぞ
-せんたく
-せんちょう
-せんてい
-せんとう
-せんぬき
-せんねん
-せんぱい
-ぜんぶ
-ぜんぽう
-せんむ
-せんめんじょ
-せんもん
-せんやく
-せんゆう
-せんよう
-ぜんら
-ぜんりゃく
-せんれい
-せんろ
-そあく
-そいとげる
-そいね
-そうがんきょう
-そうき
-そうご
-そうしん
-そうだん
-そうなん
-そうび
-そうめん
-そうり
-そえもの
-そえん
-そがい
-そげき
-そこう
-そこそこ
-そざい
-そしな
-そせい
-そせん
-そそぐ
-そだてる
-そつう
-そつえん
-そっかん
-そつぎょう
-そっけつ
-そっこう
-そっせん
-そっと
-そとがわ
-そとづら
-そなえる
-そなた
-そふぼ
-そぼく
-そぼろ
-そまつ
-そまる
-そむく
-そむりえ
-そめる
-そもそも
-そよかぜ
-そらまめ
-そろう
-そんかい
-そんけい
-そんざい
-そんしつ
-そんぞく
-そんちょう
-ぞんび
-ぞんぶん
-そんみん
-たあい
-たいいん
-たいうん
-たいえき
-たいおう
-だいがく
-たいき
-たいぐう
-たいけん
-たいこ
-たいざい
-だいじょうぶ
-だいすき
-たいせつ
-たいそう
-だいたい
-たいちょう
-たいてい
-だいどころ
-たいない
-たいねつ
-たいのう
-たいはん
-だいひょう
-たいふう
-たいへん
-たいほ
-たいまつばな
-たいみんぐ
-たいむ
-たいめん
-たいやき
-たいよう
-たいら
-たいりょく
-たいる
-たいわん
-たうえ
-たえる
-たおす
-たおる
-たおれる
-たかい
-たかね
-たきび
-たくさん
-たこく
-たこやき
-たさい
-たしざん
-だじゃれ
-たすける
-たずさわる
-たそがれ
-たたかう
-たたく
-ただしい
-たたみ
-たちばな
-だっかい
-だっきゃく
-だっこ
-だっしゅつ
-だったい
-たてる
-たとえる
-たなばた
-たにん
-たぬき
-たのしみ
-たはつ
-たぶん
-たべる
-たぼう
-たまご
-たまる
-だむる
-ためいき
-ためす
-ためる
-たもつ
-たやすい
-たよる
-たらす
-たりきほんがん
-たりょう
-たりる
-たると
-たれる
-たれんと
-たろっと
-たわむれる
-だんあつ
-たんい
-たんおん
-たんか
-たんき
-たんけん
-たんご
-たんさん
-たんじょうび
-だんせい
-たんそく
-たんたい
-だんち
-たんてい
-たんとう
-だんな
-たんにん
-だんねつ
-たんのう
-たんぴん
-だんぼう
-たんまつ
-たんめい
-だんれつ
-だんろ
-だんわ
-ちあい
-ちあん
-ちいき
-ちいさい
-ちえん
-ちかい
-ちから
-ちきゅう
-ちきん
-ちけいず
-ちけん
-ちこく
-ちさい
-ちしき
-ちしりょう
-ちせい
-ちそう
-ちたい
-ちたん
-ちちおや
-ちつじょ
-ちてき
-ちてん
-ちぬき
-ちぬり
-ちのう
-ちひょう
-ちへいせん
-ちほう
-ちまた
-ちみつ
-ちみどろ
-ちめいど
-ちゃんこなべ
-ちゅうい
-ちゆりょく
-ちょうし
-ちょさくけん
-ちらし
-ちらみ
-ちりがみ
-ちりょう
-ちるど
-ちわわ
-ちんたい
-ちんもく
-ついか
-ついたち
-つうか
-つうじょう
-つうはん
-つうわ
-つかう
-つかれる
-つくね
-つくる
-つけね
-つける
-つごう
-つたえる
-つづく
-つつじ
-つつむ
-つとめる
-つながる
-つなみ
-つねづね
-つのる
-つぶす
-つまらない
-つまる
-つみき
-つめたい
-つもり
-つもる
-つよい
-つるぼ
-つるみく
-つわもの
-つわり
-てあし
-てあて
-てあみ
-ていおん
-ていか
-ていき
-ていけい
-ていこく
-ていさつ
-ていし
-ていせい
-ていたい
-ていど
-ていねい
-ていひょう
-ていへん
-ていぼう
-てうち
-ておくれ
-てきとう
-てくび
-でこぼこ
-てさぎょう
-てさげ
-てすり
-てそう
-てちがい
-てちょう
-てつがく
-てつづき
-でっぱ
-てつぼう
-てつや
-でぬかえ
-てぬき
-てぬぐい
-てのひら
-てはい
-てぶくろ
-てふだ
-てほどき
-てほん
-てまえ
-てまきずし
-てみじか
-てみやげ
-てらす
-てれび
-てわけ
-てわたし
-でんあつ
-てんいん
-てんかい
-てんき
-てんぐ
-てんけん
-てんごく
-てんさい
-てんし
-てんすう
-でんち
-てんてき
-てんとう
-てんない
-てんぷら
-てんぼうだい
-てんめつ
-てんらんかい
-でんりょく
-でんわ
-どあい
-といれ
-どうかん
-とうきゅう
-どうぐ
-とうし
-とうむぎ
-とおい
-とおか
-とおく
-とおす
-とおる
-とかい
-とかす
-ときおり
-ときどき
-とくい
-とくしゅう
-とくてん
-とくに
-とくべつ
-とけい
-とける
-とこや
-とさか
-としょかん
-とそう
-とたん
-とちゅう
-とっきゅう
-とっくん
-とつぜん
-とつにゅう
-とどける
-ととのえる
-とない
-となえる
-となり
-とのさま
-とばす
-どぶがわ
-とほう
-とまる
-とめる
-ともだち
-ともる
-どようび
-とらえる
-とんかつ
-どんぶり
-ないかく
-ないこう
-ないしょ
-ないす
-ないせん
-ないそう
-なおす
-ながい
-なくす
-なげる
-なこうど
-なさけ
-なたでここ
-なっとう
-なつやすみ
-ななおし
-なにごと
-なにもの
-なにわ
-なのか
-なふだ
-なまいき
-なまえ
-なまみ
-なみだ
-なめらか
-なめる
-なやむ
-ならう
-ならび
-ならぶ
-なれる
-なわとび
-なわばり
-にあう
-にいがた
-にうけ
-におい
-にかい
-にがて
-にきび
-にくしみ
-にくまん
-にげる
-にさんかたんそ
-にしき
-にせもの
-にちじょう
-にちようび
-にっか
-にっき
-にっけい
-にっこう
-にっさん
-にっしょく
-にっすう
-にっせき
-にってい
-になう
-にほん
-にまめ
-にもつ
-にやり
-にゅういん
-にりんしゃ
-にわとり
-にんい
-にんか
-にんき
-にんげん
-にんしき
-にんずう
-にんそう
-にんたい
-にんち
-にんてい
-にんにく
-にんぷ
-にんまり
-にんむ
-にんめい
-にんよう
-ぬいくぎ
-ぬかす
-ぬぐいとる
-ぬぐう
-ぬくもり
-ぬすむ
-ぬまえび
-ぬめり
-ぬらす
-ぬんちゃく
-ねあげ
-ねいき
-ねいる
-ねいろ
-ねぐせ
-ねくたい
-ねくら
-ねこぜ
-ねこむ
-ねさげ
-ねすごす
-ねそべる
-ねだん
-ねつい
-ねっしん
-ねつぞう
-ねったいぎょ
-ねぶそく
-ねふだ
-ねぼう
-ねほりはほり
-ねまき
-ねまわし
-ねみみ
-ねむい
-ねむたい
-ねもと
-ねらう
-ねわざ
-ねんいり
-ねんおし
-ねんかん
-ねんきん
-ねんぐ
-ねんざ
-ねんし
-ねんちゃく
-ねんど
-ねんぴ
-ねんぶつ
-ねんまつ
-ねんりょう
-ねんれい
-のいず
-のおづま
-のがす
-のきなみ
-のこぎり
-のこす
-のこる
-のせる
-のぞく
-のぞむ
-のたまう
-のちほど
-のっく
-のばす
-のはら
-のべる
-のぼる
-のみもの
-のやま
-のらいぬ
-のらねこ
-のりもの
-のりゆき
-のれん
-のんき
-ばあい
-はあく
-ばあさん
-ばいか
-ばいく
-はいけん
-はいご
-はいしん
-はいすい
-はいせん
-はいそう
-はいち
-ばいばい
-はいれつ
-はえる
-はおる
-はかい
-ばかり
-はかる
-はくしゅ
-はけん
-はこぶ
-はさみ
-はさん
-はしご
-ばしょ
-はしる
-はせる
-ぱそこん
-はそん
-はたん
-はちみつ
-はつおん
-はっかく
-はづき
-はっきり
-はっくつ
-はっけん
-はっこう
-はっさん
-はっしん
-はったつ
-はっちゅう
-はってん
-はっぴょう
-はっぽう
-はなす
-はなび
-はにかむ
-はぶらし
-はみがき
-はむかう
-はめつ
-はやい
-はやし
-はらう
-はろうぃん
-はわい
-はんい
-はんえい
-はんおん
-はんかく
-はんきょう
-ばんぐみ
-はんこ
-はんしゃ
-はんすう
-はんだん
-ぱんち
-ぱんつ
-はんてい
-はんとし
-はんのう
-はんぱ
-はんぶん
-はんぺん
-はんぼうき
-はんめい
-はんらん
-はんろん
-ひいき
-ひうん
-ひえる
-ひかく
-ひかり
-ひかる
-ひかん
-ひくい
-ひけつ
-ひこうき
-ひこく
-ひさい
-ひさしぶり
-ひさん
-びじゅつかん
-ひしょ
-ひそか
-ひそむ
-ひたむき
-ひだり
-ひたる
-ひつぎ
-ひっこし
-ひっし
-ひつじゅひん
-ひっす
-ひつぜん
-ぴったり
-ぴっちり
-ひつよう
-ひてい
-ひとごみ
-ひなまつり
-ひなん
-ひねる
-ひはん
-ひびく
-ひひょう
-ひほう
-ひまわり
-ひまん
-ひみつ
-ひめい
-ひめじし
-ひやけ
-ひやす
-ひよう
-びょうき
-ひらがな
-ひらく
-ひりつ
-ひりょう
-ひるま
-ひるやすみ
-ひれい
-ひろい
-ひろう
-ひろき
-ひろゆき
-ひんかく
-ひんけつ
-ひんこん
-ひんしゅ
-ひんそう
-ぴんち
-ひんぱん
-びんぼう
-ふあん
-ふいうち
-ふうけい
-ふうせん
-ぷうたろう
-ふうとう
-ふうふ
-ふえる
-ふおん
-ふかい
-ふきん
-ふくざつ
-ふくぶくろ
-ふこう
-ふさい
-ふしぎ
-ふじみ
-ふすま
-ふせい
-ふせぐ
-ふそく
-ぶたにく
-ふたん
-ふちょう
-ふつう
-ふつか
-ふっかつ
-ふっき
-ふっこく
-ぶどう
-ふとる
-ふとん
-ふのう
-ふはい
-ふひょう
-ふへん
-ふまん
-ふみん
-ふめつ
-ふめん
-ふよう
-ふりこ
-ふりる
-ふるい
-ふんいき
-ぶんがく
-ぶんぐ
-ふんしつ
-ぶんせき
-ふんそう
-ぶんぽう
-へいあん
-へいおん
-へいがい
-へいき
-へいげん
-へいこう
-へいさ
-へいしゃ
-へいせつ
-へいそ
-へいたく
-へいてん
-へいねつ
-へいわ
-へきが
-へこむ
-べにいろ
-べにしょうが
-へらす
-へんかん
-べんきょう
-べんごし
-へんさい
-へんたい
-べんり
-ほあん
-ほいく
-ぼうぎょ
-ほうこく
-ほうそう
-ほうほう
-ほうもん
-ほうりつ
-ほえる
-ほおん
-ほかん
-ほきょう
-ぼきん
-ほくろ
-ほけつ
-ほけん
-ほこう
-ほこる
-ほしい
-ほしつ
-ほしゅ
-ほしょう
-ほせい
-ほそい
-ほそく
-ほたて
-ほたる
-ぽちぶくろ
-ほっきょく
-ほっさ
-ほったん
-ほとんど
-ほめる
-ほんい
-ほんき
-ほんけ
-ほんしつ
-ほんやく
-まいにち
-まかい
-まかせる
-まがる
-まける
-まこと
-まさつ
-まじめ
-ますく
-まぜる
-まつり
-まとめ
-まなぶ
-まぬけ
-まねく
-まほう
-まもる
-まゆげ
-まよう
-まろやか
-まわす
-まわり
-まわる
-まんが
-まんきつ
-まんぞく
-まんなか
-みいら
-みうち
-みえる
-みがく
-みかた
-みかん
-みけん
-みこん
-みじかい
-みすい
-みすえる
-みせる
-みっか
-みつかる
-みつける
-みてい
-みとめる
-みなと
-みなみかさい
-みねらる
-みのう
-みのがす
-みほん
-みもと
-みやげ
-みらい
-みりょく
-みわく
-みんか
-みんぞく
-むいか
-むえき
-むえん
-むかい
-むかう
-むかえ
-むかし
-むぎちゃ
-むける
-むげん
-むさぼる
-むしあつい
-むしば
-むじゅん
-むしろ
-むすう
-むすこ
-むすぶ
-むすめ
-むせる
-むせん
-むちゅう
-むなしい
-むのう
-むやみ
-むよう
-むらさき
-むりょう
-むろん
-めいあん
-めいうん
-めいえん
-めいかく
-めいきょく
-めいさい
-めいし
-めいそう
-めいぶつ
-めいれい
-めいわく
-めぐまれる
-めざす
-めした
-めずらしい
-めだつ
-めまい
-めやす
-めんきょ
-めんせき
-めんどう
-もうしあげる
-もうどうけん
-もえる
-もくし
-もくてき
-もくようび
-もちろん
-もどる
-もらう
-もんく
-もんだい
-やおや
-やける
-やさい
-やさしい
-やすい
-やすたろう
-やすみ
-やせる
-やそう
-やたい
-やちん
-やっと
-やっぱり
-やぶる
-やめる
-ややこしい
-やよい
-やわらかい
-ゆうき
-ゆうびんきょく
-ゆうべ
-ゆうめい
-ゆけつ
-ゆしゅつ
-ゆせん
-ゆそう
-ゆたか
-ゆちゃく
-ゆでる
-ゆにゅう
-ゆびわ
-ゆらい
-ゆれる
-ようい
-ようか
-ようきゅう
-ようじ
-ようす
-ようちえん
-よかぜ
-よかん
-よきん
-よくせい
-よくぼう
-よけい
-よごれる
-よさん
-よしゅう
-よそう
-よそく
-よっか
-よてい
-よどがわく
-よねつ
-よやく
-よゆう
-よろこぶ
-よろしい
-らいう
-らくがき
-らくご
-らくさつ
-らくだ
-らしんばん
-らせん
-らぞく
-らたい
-らっか
-られつ
-りえき
-りかい
-りきさく
-りきせつ
-りくぐん
-りくつ
-りけん
-りこう
-りせい
-りそう
-りそく
-りてん
-りねん
-りゆう
-りゅうがく
-りよう
-りょうり
-りょかん
-りょくちゃ
-りょこう
-りりく
-りれき
-りろん
-りんご
-るいけい
-るいさい
-るいじ
-るいせき
-るすばん
-るりがわら
-れいかん
-れいぎ
-れいせい
-れいぞうこ
-れいとう
-れいぼう
-れきし
-れきだい
-れんあい
-れんけい
-れんこん
-れんさい
-れんしゅう
-れんぞく
-れんらく
-ろうか
-ろうご
-ろうじん
-ろうそく
-ろくが
-ろこつ
-ろじうら
-ろしゅつ
-ろせん
-ろてん
-ろめん
-ろれつ
-ろんぎ
-ろんぱ
-ろんぶん
-ろんり
-わかす
-わかめ
-わかやま
-わかれる
-わしつ
-わじまし
-わすれもの
-わらう
-われる
+++ /dev/null
-ábaco
-abdomen
-abeja
-abierto
-abogado
-abono
-aborto
-abrazo
-abrir
-abuelo
-abuso
-acabar
-academia
-acceso
-acción
-aceite
-acelga
-acento
-aceptar
-ácido
-aclarar
-acné
-acoger
-acoso
-activo
-acto
-actriz
-actuar
-acudir
-acuerdo
-acusar
-adicto
-admitir
-adoptar
-adorno
-aduana
-adulto
-aéreo
-afectar
-afición
-afinar
-afirmar
-ágil
-agitar
-agonía
-agosto
-agotar
-agregar
-agrio
-agua
-agudo
-águila
-aguja
-ahogo
-ahorro
-aire
-aislar
-ajedrez
-ajeno
-ajuste
-alacrán
-alambre
-alarma
-alba
-álbum
-alcalde
-aldea
-alegre
-alejar
-alerta
-aleta
-alfiler
-alga
-algodón
-aliado
-aliento
-alivio
-alma
-almeja
-almíbar
-altar
-alteza
-altivo
-alto
-altura
-alumno
-alzar
-amable
-amante
-amapola
-amargo
-amasar
-ámbar
-ámbito
-ameno
-amigo
-amistad
-amor
-amparo
-amplio
-ancho
-anciano
-ancla
-andar
-andén
-anemia
-ángulo
-anillo
-ánimo
-anís
-anotar
-antena
-antiguo
-antojo
-anual
-anular
-anuncio
-añadir
-añejo
-año
-apagar
-aparato
-apetito
-apio
-aplicar
-apodo
-aporte
-apoyo
-aprender
-aprobar
-apuesta
-apuro
-arado
-araña
-arar
-árbitro
-árbol
-arbusto
-archivo
-arco
-arder
-ardilla
-arduo
-área
-árido
-aries
-armonía
-arnés
-aroma
-arpa
-arpón
-arreglo
-arroz
-arruga
-arte
-artista
-asa
-asado
-asalto
-ascenso
-asegurar
-aseo
-asesor
-asiento
-asilo
-asistir
-asno
-asombro
-áspero
-astilla
-astro
-astuto
-asumir
-asunto
-atajo
-ataque
-atar
-atento
-ateo
-ático
-atleta
-átomo
-atraer
-atroz
-atún
-audaz
-audio
-auge
-aula
-aumento
-ausente
-autor
-aval
-avance
-avaro
-ave
-avellana
-avena
-avestruz
-avión
-aviso
-ayer
-ayuda
-ayuno
-azafrán
-azar
-azote
-azúcar
-azufre
-azul
-baba
-babor
-bache
-bahía
-baile
-bajar
-balanza
-balcón
-balde
-bambú
-banco
-banda
-baño
-barba
-barco
-barniz
-barro
-báscula
-bastón
-basura
-batalla
-batería
-batir
-batuta
-baúl
-bazar
-bebé
-bebida
-bello
-besar
-beso
-bestia
-bicho
-bien
-bingo
-blanco
-bloque
-blusa
-boa
-bobina
-bobo
-boca
-bocina
-boda
-bodega
-boina
-bola
-bolero
-bolsa
-bomba
-bondad
-bonito
-bono
-bonsái
-borde
-borrar
-bosque
-bote
-botín
-bóveda
-bozal
-bravo
-brazo
-brecha
-breve
-brillo
-brinco
-brisa
-broca
-broma
-bronce
-brote
-bruja
-brusco
-bruto
-buceo
-bucle
-bueno
-buey
-bufanda
-bufón
-búho
-buitre
-bulto
-burbuja
-burla
-burro
-buscar
-butaca
-buzón
-caballo
-cabeza
-cabina
-cabra
-cacao
-cadáver
-cadena
-caer
-café
-caída
-caimán
-caja
-cajón
-cal
-calamar
-calcio
-caldo
-calidad
-calle
-calma
-calor
-calvo
-cama
-cambio
-camello
-camino
-campo
-cáncer
-candil
-canela
-canguro
-canica
-canto
-caña
-cañón
-caoba
-caos
-capaz
-capitán
-capote
-captar
-capucha
-cara
-carbón
-cárcel
-careta
-carga
-cariño
-carne
-carpeta
-carro
-carta
-casa
-casco
-casero
-caspa
-castor
-catorce
-catre
-caudal
-causa
-cazo
-cebolla
-ceder
-cedro
-celda
-célebre
-celoso
-célula
-cemento
-ceniza
-centro
-cerca
-cerdo
-cereza
-cero
-cerrar
-certeza
-césped
-cetro
-chacal
-chaleco
-champú
-chancla
-chapa
-charla
-chico
-chiste
-chivo
-choque
-choza
-chuleta
-chupar
-ciclón
-ciego
-cielo
-cien
-cierto
-cifra
-cigarro
-cima
-cinco
-cine
-cinta
-ciprés
-circo
-ciruela
-cisne
-cita
-ciudad
-clamor
-clan
-claro
-clase
-clave
-cliente
-clima
-clínica
-cobre
-cocción
-cochino
-cocina
-coco
-código
-codo
-cofre
-coger
-cohete
-cojín
-cojo
-cola
-colcha
-colegio
-colgar
-colina
-collar
-colmo
-columna
-combate
-comer
-comida
-cómodo
-compra
-conde
-conejo
-conga
-conocer
-consejo
-contar
-copa
-copia
-corazón
-corbata
-corcho
-cordón
-corona
-correr
-coser
-cosmos
-costa
-cráneo
-cráter
-crear
-crecer
-creído
-crema
-cría
-crimen
-cripta
-crisis
-cromo
-crónica
-croqueta
-crudo
-cruz
-cuadro
-cuarto
-cuatro
-cubo
-cubrir
-cuchara
-cuello
-cuento
-cuerda
-cuesta
-cueva
-cuidar
-culebra
-culpa
-culto
-cumbre
-cumplir
-cuna
-cuneta
-cuota
-cupón
-cúpula
-curar
-curioso
-curso
-curva
-cutis
-dama
-danza
-dar
-dardo
-dátil
-deber
-débil
-década
-decir
-dedo
-defensa
-definir
-dejar
-delfín
-delgado
-delito
-demora
-denso
-dental
-deporte
-derecho
-derrota
-desayuno
-deseo
-desfile
-desnudo
-destino
-desvío
-detalle
-detener
-deuda
-día
-diablo
-diadema
-diamante
-diana
-diario
-dibujo
-dictar
-diente
-dieta
-diez
-difícil
-digno
-dilema
-diluir
-dinero
-directo
-dirigir
-disco
-diseño
-disfraz
-diva
-divino
-doble
-doce
-dolor
-domingo
-don
-donar
-dorado
-dormir
-dorso
-dos
-dosis
-dragón
-droga
-ducha
-duda
-duelo
-dueño
-dulce
-dúo
-duque
-durar
-dureza
-duro
-ébano
-ebrio
-echar
-eco
-ecuador
-edad
-edición
-edificio
-editor
-educar
-efecto
-eficaz
-eje
-ejemplo
-elefante
-elegir
-elemento
-elevar
-elipse
-élite
-elixir
-elogio
-eludir
-embudo
-emitir
-emoción
-empate
-empeño
-empleo
-empresa
-enano
-encargo
-enchufe
-encía
-enemigo
-enero
-enfado
-enfermo
-engaño
-enigma
-enlace
-enorme
-enredo
-ensayo
-enseñar
-entero
-entrar
-envase
-envío
-época
-equipo
-erizo
-escala
-escena
-escolar
-escribir
-escudo
-esencia
-esfera
-esfuerzo
-espada
-espejo
-espía
-esposa
-espuma
-esquí
-estar
-este
-estilo
-estufa
-etapa
-eterno
-ética
-etnia
-evadir
-evaluar
-evento
-evitar
-exacto
-examen
-exceso
-excusa
-exento
-exigir
-exilio
-existir
-éxito
-experto
-explicar
-exponer
-extremo
-fábrica
-fábula
-fachada
-fácil
-factor
-faena
-faja
-falda
-fallo
-falso
-faltar
-fama
-familia
-famoso
-faraón
-farmacia
-farol
-farsa
-fase
-fatiga
-fauna
-favor
-fax
-febrero
-fecha
-feliz
-feo
-feria
-feroz
-fértil
-fervor
-festín
-fiable
-fianza
-fiar
-fibra
-ficción
-ficha
-fideo
-fiebre
-fiel
-fiera
-fiesta
-figura
-fijar
-fijo
-fila
-filete
-filial
-filtro
-fin
-finca
-fingir
-finito
-firma
-flaco
-flauta
-flecha
-flor
-flota
-fluir
-flujo
-flúor
-fobia
-foca
-fogata
-fogón
-folio
-folleto
-fondo
-forma
-forro
-fortuna
-forzar
-fosa
-foto
-fracaso
-frágil
-franja
-frase
-fraude
-freír
-freno
-fresa
-frío
-frito
-fruta
-fuego
-fuente
-fuerza
-fuga
-fumar
-función
-funda
-furgón
-furia
-fusil
-fútbol
-futuro
-gacela
-gafas
-gaita
-gajo
-gala
-galería
-gallo
-gamba
-ganar
-gancho
-ganga
-ganso
-garaje
-garza
-gasolina
-gastar
-gato
-gavilán
-gemelo
-gemir
-gen
-género
-genio
-gente
-geranio
-gerente
-germen
-gesto
-gigante
-gimnasio
-girar
-giro
-glaciar
-globo
-gloria
-gol
-golfo
-goloso
-golpe
-goma
-gordo
-gorila
-gorra
-gota
-goteo
-gozar
-grada
-gráfico
-grano
-grasa
-gratis
-grave
-grieta
-grillo
-gripe
-gris
-grito
-grosor
-grúa
-grueso
-grumo
-grupo
-guante
-guapo
-guardia
-guerra
-guía
-guiño
-guion
-guiso
-guitarra
-gusano
-gustar
-haber
-hábil
-hablar
-hacer
-hacha
-hada
-hallar
-hamaca
-harina
-haz
-hazaña
-hebilla
-hebra
-hecho
-helado
-helio
-hembra
-herir
-hermano
-héroe
-hervir
-hielo
-hierro
-hígado
-higiene
-hijo
-himno
-historia
-hocico
-hogar
-hoguera
-hoja
-hombre
-hongo
-honor
-honra
-hora
-hormiga
-horno
-hostil
-hoyo
-hueco
-huelga
-huerta
-hueso
-huevo
-huida
-huir
-humano
-húmedo
-humilde
-humo
-hundir
-huracán
-hurto
-icono
-ideal
-idioma
-ídolo
-iglesia
-iglú
-igual
-ilegal
-ilusión
-imagen
-imán
-imitar
-impar
-imperio
-imponer
-impulso
-incapaz
-índice
-inerte
-infiel
-informe
-ingenio
-inicio
-inmenso
-inmune
-innato
-insecto
-instante
-interés
-íntimo
-intuir
-inútil
-invierno
-ira
-iris
-ironía
-isla
-islote
-jabalí
-jabón
-jamón
-jarabe
-jardín
-jarra
-jaula
-jazmín
-jefe
-jeringa
-jinete
-jornada
-joroba
-joven
-joya
-juerga
-jueves
-juez
-jugador
-jugo
-juguete
-juicio
-junco
-jungla
-junio
-juntar
-júpiter
-jurar
-justo
-juvenil
-juzgar
-kilo
-koala
-labio
-lacio
-lacra
-lado
-ladrón
-lagarto
-lágrima
-laguna
-laico
-lamer
-lámina
-lámpara
-lana
-lancha
-langosta
-lanza
-lápiz
-largo
-larva
-lástima
-lata
-látex
-latir
-laurel
-lavar
-lazo
-leal
-lección
-leche
-lector
-leer
-legión
-legumbre
-lejano
-lengua
-lento
-leña
-león
-leopardo
-lesión
-letal
-letra
-leve
-leyenda
-libertad
-libro
-licor
-líder
-lidiar
-lienzo
-liga
-ligero
-lima
-límite
-limón
-limpio
-lince
-lindo
-línea
-lingote
-lino
-linterna
-líquido
-liso
-lista
-litera
-litio
-litro
-llaga
-llama
-llanto
-llave
-llegar
-llenar
-llevar
-llorar
-llover
-lluvia
-lobo
-loción
-loco
-locura
-lógica
-logro
-lombriz
-lomo
-lonja
-lote
-lucha
-lucir
-lugar
-lujo
-luna
-lunes
-lupa
-lustro
-luto
-luz
-maceta
-macho
-madera
-madre
-maduro
-maestro
-mafia
-magia
-mago
-maíz
-maldad
-maleta
-malla
-malo
-mamá
-mambo
-mamut
-manco
-mando
-manejar
-manga
-maniquí
-manjar
-mano
-manso
-manta
-mañana
-mapa
-máquina
-mar
-marco
-marea
-marfil
-margen
-marido
-mármol
-marrón
-martes
-marzo
-masa
-máscara
-masivo
-matar
-materia
-matiz
-matriz
-máximo
-mayor
-mazorca
-mecha
-medalla
-medio
-médula
-mejilla
-mejor
-melena
-melón
-memoria
-menor
-mensaje
-mente
-menú
-mercado
-merengue
-mérito
-mes
-mesón
-meta
-meter
-método
-metro
-mezcla
-miedo
-miel
-miembro
-miga
-mil
-milagro
-militar
-millón
-mimo
-mina
-minero
-mínimo
-minuto
-miope
-mirar
-misa
-miseria
-misil
-mismo
-mitad
-mito
-mochila
-moción
-moda
-modelo
-moho
-mojar
-molde
-moler
-molino
-momento
-momia
-monarca
-moneda
-monja
-monto
-moño
-morada
-morder
-moreno
-morir
-morro
-morsa
-mortal
-mosca
-mostrar
-motivo
-mover
-móvil
-mozo
-mucho
-mudar
-mueble
-muela
-muerte
-muestra
-mugre
-mujer
-mula
-muleta
-multa
-mundo
-muñeca
-mural
-muro
-músculo
-museo
-musgo
-música
-muslo
-nácar
-nación
-nadar
-naipe
-naranja
-nariz
-narrar
-nasal
-natal
-nativo
-natural
-náusea
-naval
-nave
-navidad
-necio
-néctar
-negar
-negocio
-negro
-neón
-nervio
-neto
-neutro
-nevar
-nevera
-nicho
-nido
-niebla
-nieto
-niñez
-niño
-nítido
-nivel
-nobleza
-noche
-nómina
-noria
-norma
-norte
-nota
-noticia
-novato
-novela
-novio
-nube
-nuca
-núcleo
-nudillo
-nudo
-nuera
-nueve
-nuez
-nulo
-número
-nutria
-oasis
-obeso
-obispo
-objeto
-obra
-obrero
-observar
-obtener
-obvio
-oca
-ocaso
-océano
-ochenta
-ocho
-ocio
-ocre
-octavo
-octubre
-oculto
-ocupar
-ocurrir
-odiar
-odio
-odisea
-oeste
-ofensa
-oferta
-oficio
-ofrecer
-ogro
-oído
-oír
-ojo
-ola
-oleada
-olfato
-olivo
-olla
-olmo
-olor
-olvido
-ombligo
-onda
-onza
-opaco
-opción
-ópera
-opinar
-oponer
-optar
-óptica
-opuesto
-oración
-orador
-oral
-órbita
-orca
-orden
-oreja
-órgano
-orgía
-orgullo
-oriente
-origen
-orilla
-oro
-orquesta
-oruga
-osadía
-oscuro
-osezno
-oso
-ostra
-otoño
-otro
-oveja
-óvulo
-óxido
-oxígeno
-oyente
-ozono
-pacto
-padre
-paella
-página
-pago
-país
-pájaro
-palabra
-palco
-paleta
-pálido
-palma
-paloma
-palpar
-pan
-panal
-pánico
-pantera
-pañuelo
-papá
-papel
-papilla
-paquete
-parar
-parcela
-pared
-parir
-paro
-párpado
-parque
-párrafo
-parte
-pasar
-paseo
-pasión
-paso
-pasta
-pata
-patio
-patria
-pausa
-pauta
-pavo
-payaso
-peatón
-pecado
-pecera
-pecho
-pedal
-pedir
-pegar
-peine
-pelar
-peldaño
-pelea
-peligro
-pellejo
-pelo
-peluca
-pena
-pensar
-peñón
-peón
-peor
-pepino
-pequeño
-pera
-percha
-perder
-pereza
-perfil
-perico
-perla
-permiso
-perro
-persona
-pesa
-pesca
-pésimo
-pestaña
-pétalo
-petróleo
-pez
-pezuña
-picar
-pichón
-pie
-piedra
-pierna
-pieza
-pijama
-pilar
-piloto
-pimienta
-pino
-pintor
-pinza
-piña
-piojo
-pipa
-pirata
-pisar
-piscina
-piso
-pista
-pitón
-pizca
-placa
-plan
-plata
-playa
-plaza
-pleito
-pleno
-plomo
-pluma
-plural
-pobre
-poco
-poder
-podio
-poema
-poesía
-poeta
-polen
-policía
-pollo
-polvo
-pomada
-pomelo
-pomo
-pompa
-poner
-porción
-portal
-posada
-poseer
-posible
-poste
-potencia
-potro
-pozo
-prado
-precoz
-pregunta
-premio
-prensa
-preso
-previo
-primo
-príncipe
-prisión
-privar
-proa
-probar
-proceso
-producto
-proeza
-profesor
-programa
-prole
-promesa
-pronto
-propio
-próximo
-prueba
-público
-puchero
-pudor
-pueblo
-puerta
-puesto
-pulga
-pulir
-pulmón
-pulpo
-pulso
-puma
-punto
-puñal
-puño
-pupa
-pupila
-puré
-quedar
-queja
-quemar
-querer
-queso
-quieto
-química
-quince
-quitar
-rábano
-rabia
-rabo
-ración
-radical
-raíz
-rama
-rampa
-rancho
-rango
-rapaz
-rápido
-rapto
-rasgo
-raspa
-rato
-rayo
-raza
-razón
-reacción
-realidad
-rebaño
-rebote
-recaer
-receta
-rechazo
-recoger
-recreo
-recto
-recurso
-red
-redondo
-reducir
-reflejo
-reforma
-refrán
-refugio
-regalo
-regir
-regla
-regreso
-rehén
-reino
-reír
-reja
-relato
-relevo
-relieve
-relleno
-reloj
-remar
-remedio
-remo
-rencor
-rendir
-renta
-reparto
-repetir
-reposo
-reptil
-res
-rescate
-resina
-respeto
-resto
-resumen
-retiro
-retorno
-retrato
-reunir
-revés
-revista
-rey
-rezar
-rico
-riego
-rienda
-riesgo
-rifa
-rígido
-rigor
-rincón
-riñón
-río
-riqueza
-risa
-ritmo
-rito
-rizo
-roble
-roce
-rociar
-rodar
-rodeo
-rodilla
-roer
-rojizo
-rojo
-romero
-romper
-ron
-ronco
-ronda
-ropa
-ropero
-rosa
-rosca
-rostro
-rotar
-rubí
-rubor
-rudo
-rueda
-rugir
-ruido
-ruina
-ruleta
-rulo
-rumbo
-rumor
-ruptura
-ruta
-rutina
-sábado
-saber
-sabio
-sable
-sacar
-sagaz
-sagrado
-sala
-saldo
-salero
-salir
-salmón
-salón
-salsa
-salto
-salud
-salvar
-samba
-sanción
-sandía
-sanear
-sangre
-sanidad
-sano
-santo
-sapo
-saque
-sardina
-sartén
-sastre
-satán
-sauna
-saxofón
-sección
-seco
-secreto
-secta
-sed
-seguir
-seis
-sello
-selva
-semana
-semilla
-senda
-sensor
-señal
-señor
-separar
-sepia
-sequía
-ser
-serie
-sermón
-servir
-sesenta
-sesión
-seta
-setenta
-severo
-sexo
-sexto
-sidra
-siesta
-siete
-siglo
-signo
-sílaba
-silbar
-silencio
-silla
-símbolo
-simio
-sirena
-sistema
-sitio
-situar
-sobre
-socio
-sodio
-sol
-solapa
-soldado
-soledad
-sólido
-soltar
-solución
-sombra
-sondeo
-sonido
-sonoro
-sonrisa
-sopa
-soplar
-soporte
-sordo
-sorpresa
-sorteo
-sostén
-sótano
-suave
-subir
-suceso
-sudor
-suegra
-suelo
-sueño
-suerte
-sufrir
-sujeto
-sultán
-sumar
-superar
-suplir
-suponer
-supremo
-sur
-surco
-sureño
-surgir
-susto
-sutil
-tabaco
-tabique
-tabla
-tabú
-taco
-tacto
-tajo
-talar
-talco
-talento
-talla
-talón
-tamaño
-tambor
-tango
-tanque
-tapa
-tapete
-tapia
-tapón
-taquilla
-tarde
-tarea
-tarifa
-tarjeta
-tarot
-tarro
-tarta
-tatuaje
-tauro
-taza
-tazón
-teatro
-techo
-tecla
-técnica
-tejado
-tejer
-tejido
-tela
-teléfono
-tema
-temor
-templo
-tenaz
-tender
-tener
-tenis
-tenso
-teoría
-terapia
-terco
-término
-ternura
-terror
-tesis
-tesoro
-testigo
-tetera
-texto
-tez
-tibio
-tiburón
-tiempo
-tienda
-tierra
-tieso
-tigre
-tijera
-tilde
-timbre
-tímido
-timo
-tinta
-tío
-típico
-tipo
-tira
-tirón
-titán
-títere
-título
-tiza
-toalla
-tobillo
-tocar
-tocino
-todo
-toga
-toldo
-tomar
-tono
-tonto
-topar
-tope
-toque
-tórax
-torero
-tormenta
-torneo
-toro
-torpedo
-torre
-torso
-tortuga
-tos
-tosco
-toser
-tóxico
-trabajo
-tractor
-traer
-tráfico
-trago
-traje
-tramo
-trance
-trato
-trauma
-trazar
-trébol
-tregua
-treinta
-tren
-trepar
-tres
-tribu
-trigo
-tripa
-triste
-triunfo
-trofeo
-trompa
-tronco
-tropa
-trote
-trozo
-truco
-trueno
-trufa
-tubería
-tubo
-tuerto
-tumba
-tumor
-túnel
-túnica
-turbina
-turismo
-turno
-tutor
-ubicar
-úlcera
-umbral
-unidad
-unir
-universo
-uno
-untar
-uña
-urbano
-urbe
-urgente
-urna
-usar
-usuario
-útil
-utopía
-uva
-vaca
-vacío
-vacuna
-vagar
-vago
-vaina
-vajilla
-vale
-válido
-valle
-valor
-válvula
-vampiro
-vara
-variar
-varón
-vaso
-vecino
-vector
-vehículo
-veinte
-vejez
-vela
-velero
-veloz
-vena
-vencer
-venda
-veneno
-vengar
-venir
-venta
-venus
-ver
-verano
-verbo
-verde
-vereda
-verja
-verso
-verter
-vía
-viaje
-vibrar
-vicio
-víctima
-vida
-vídeo
-vidrio
-viejo
-viernes
-vigor
-vil
-villa
-vinagre
-vino
-viñedo
-violín
-viral
-virgo
-virtud
-visor
-víspera
-vista
-vitamina
-viudo
-vivaz
-vivero
-vivir
-vivo
-volcán
-volumen
-volver
-voraz
-votar
-voto
-voz
-vuelo
-vulgar
-yacer
-yate
-yegua
-yema
-yerno
-yeso
-yodo
-yoga
-yogur
-zafiro
-zanja
-zapato
-zarza
-zona
-zorro
-zumo
-zurdo
+++ /dev/null
-// Code generated by go-bindata.
-// sources:
-// keys/wordlist/chinese_simplified.txt
-// keys/wordlist/english.txt
-// keys/wordlist/japanese.txt
-// keys/wordlist/spanish.txt
-// DO NOT EDIT!
-
-package wordlist
-
-import (
- "bytes"
- "compress/gzip"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
- "time"
-)
-
-func bindataRead(data []byte, name string) ([]byte, error) {
- gz, err := gzip.NewReader(bytes.NewBuffer(data))
- if err != nil {
- return nil, fmt.Errorf("Read %q: %v", name, err)
- }
-
- var buf bytes.Buffer
- _, err = io.Copy(&buf, gz)
- clErr := gz.Close()
-
- if err != nil {
- return nil, fmt.Errorf("Read %q: %v", name, err)
- }
- if clErr != nil {
- return nil, err
- }
-
- return buf.Bytes(), nil
-}
-
-type asset struct {
- bytes []byte
- info os.FileInfo
-}
-
-type bindataFileInfo struct {
- name string
- size int64
- mode os.FileMode
- modTime time.Time
-}
-
-func (fi bindataFileInfo) Name() string {
- return fi.name
-}
-func (fi bindataFileInfo) Size() int64 {
- return fi.size
-}
-func (fi bindataFileInfo) Mode() os.FileMode {
- return fi.mode
-}
-func (fi bindataFileInfo) ModTime() time.Time {
- return fi.modTime
-}
-func (fi bindataFileInfo) IsDir() bool {
- return false
-}
-func (fi bindataFileInfo) Sys() interface{} {
- return nil
-}
-
-var _keysWordlistChinese_simplifiedTxt = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x1c\x97\x55\x76\xeb\x30\x14\x45\xff\xf7\xa8\xc3\xcc\x49\xc3\x69\x98\xda\x86\xd9\x0e\x4c\xc6\xf7\x4a\x9a\xc5\x5b\x7e\x7f\x5d\x5d\x6d\x6c\x45\x07\xf6\x31\xdd\x04\xc1\x3d\x82\xb6\x77\x48\x7f\x45\x70\x2f\x12\x78\x29\xb4\x9f\x45\x6a\x05\x02\xcf\xc3\x7e\x3a\x04\xf7\x0d\x32\x5b\x12\xdc\x3d\x82\x7b\x8e\xe0\xfe\x83\xf4\x5e\x68\xa6\x4a\xe0\xcf\xb1\x8b\x28\x81\xdf\x44\x5b\x57\x74\x30\xc7\x34\x56\x04\xfe\x1f\xa6\x31\x44\x32\x7b\x82\x57\x1f\xe9\xef\x09\xbc\x12\x92\xf6\x90\xfd\x01\xc9\xa4\x90\xdd\x03\xcd\x54\x08\x9e\x5d\xa4\xbc\x23\xb8\xfb\x48\xb9\x8a\x3c\xce\x48\x6e\x85\x54\x0a\xc8\x6d\x4e\xf0\x18\x62\xe3\x2f\x82\x7b\x1e\xfb\x49\x23\x9b\x0a\x76\x77\x26\xf0\x96\x98\x65\x11\x37\x98\x60\x23\x05\xb4\xf9\x40\x2a\x25\x64\xd6\x45\xb6\x5d\xec\xb8\x80\x6c\x16\xe8\xe9\x0b\xcd\x46\xd0\x7d\x15\x79\xb7\x30\x7e\x19\x29\x46\x09\xee\x59\x82\x47\xf8\x99\x3d\xcc\x20\x82\xd9\x64\x71\xf1\x15\xe2\x2d\x90\xed\x15\xd3\xb8\x20\xb9\x1e\x2e\x5d\x40\x16\x31\x74\x7f\x46\x0a\x4d\xdc\x6f\x1b\x9b\xfe\x21\xf0\x0a\x98\x4a\x0a\x7b\xb9\x21\xfb\x32\x26\xbb\xc6\x94\xf6\xc8\xf6\x1b\xc9\x8d\x70\xe9\x32\xee\xff\x7b\xcf\x08\x5e\x75\x24\x73\x45\xfb\x1e\xf2\xaa\x13\xbc\x3e\x98\xd8\x83\xc0\x2f\x11\xdc\xbb\x68\xff\x0f\x29\xf9\x68\x2e\x87\x46\x96\xc8\xfc\x85\x78\x0d\xe4\x19\x41\xb6\x71\xa4\x92\xc1\x7e\xda\x48\x6f\x84\x69\x1c\x90\xe4\x95\xc0\xeb\x61\x12\x57\x24\x5b\x44\x66\x4d\x64\xb6\x46\x1b\x1f\xa4\xd7\x43\x5b\x73\x5c\x6c\x8a\x99\xbd\x09\x1e\x59\x02\x2f\x8f\x3c\x4e\xc8\x6b\x82\xe9\xdd\x91\xe4\x0a\x3b\x5e\xe1\x5a\x67\x74\x74\x23\xb8\x97\x90\xe4\x09\xa9\x24\x70\xe9\x22\xda\xdc\x63\xbc\x0f\x92\x4a\xa2\x5f\x7b\x74\x33\x45\x3e\x71\xa4\x5c\x24\x78\x8d\xd0\x76\x09\xd3\xcf\x23\xa5\x21\x52\xce\x10\x3c\x32\x48\x66\x8d\xee\x1a\x68\xa6\x49\xf0\x4a\x61\xcf\x2b\x74\xdf\xc0\xfc\xfd\x21\x95\x2a\x2e\x5a\x47\xaa\x2f\x74\x33\x43\xca\x6d\x74\x30\x46\xca\x3f\xe8\x71\x8c\xf1\xeb\xd8\xe5\x14\xd7\xda\xa2\x89\x32\xe2\x7b\x68\x3f\x83\x24\xff\xd0\xd6\x08\x73\xf2\x91\x54\x0f\x79\x67\xd0\x78\x12\x1b\x49\xa2\xfd\x08\xe6\x37\x4f\xe0\x4f\xd1\xf8\x09\xb9\x1d\x71\x91\x2e\xf2\xb8\xa2\xe5\x0a\xa6\x77\xc6\x4d\xda\x48\xb2\x8b\x59\xe5\x91\xc3\x17\x81\xd7\x40\xbf\xfb\x68\xb3\x83\x3d\x8c\x91\x6a\x1b\x37\x58\x13\xbc\x8a\x48\x72\x8e\xdc\xef\x68\x33\x8d\x46\x7c\xf4\x6f\x8c\xd4\xa3\xc8\xb3\x8c\x9e\x7d\xec\xf6\x8d\x94\x73\x98\xed\x18\x93\x0d\xef\xee\x8a\xfb\xfa\xa0\x87\x18\x36\x12\x45\x66\x67\x64\xe8\x61\x2f\x09\xec\xfb\x81\x5e\xa2\xd8\xdb\x0e\xe3\x2d\x91\x50\x7b\xbd\x37\x72\x38\x60\xfc\x21\x5a\x9a\x63\x86\x73\xec\x3b\x8e\xec\x53\x18\x3f\x81\x5d\x46\xb1\xdb\x31\x92\xf9\x45\xe6\x0f\x34\x9b\xc7\x2e\x6b\x68\x7f\x88\x8e\x1e\xd8\x6d\xe8\xc7\x0a\x92\xea\xa3\x85\x34\x92\x1e\x11\x3c\x06\x48\xc1\x43\x9e\x1e\xda\x78\x23\xa9\x13\x76\xfe\xc1\x4e\x7e\x91\xc7\x11\x89\x76\x91\x4f\x12\xcd\x84\xdf\x43\x06\xe9\x7d\x23\x99\x0e\x81\x1f\x7a\xad\x89\x16\xb7\xc8\x2c\x81\x6b\x0f\x91\x62\xe8\x8d\x0e\x36\x7b\x44\x92\x59\x5c\x6b\x85\x14\x4f\x04\x9f\x01\x7a\xf4\x91\x42\x0b\x17\x19\x61\x3a\x6f\xec\x32\x81\x89\x6f\x70\x93\x14\xc1\x3d\x8e\x86\x1e\x28\x4f\x09\xee\x7d\x64\xf7\x44\x3a\x2b\xa4\x94\x47\x3e\x2d\x82\x7b\x13\x97\xae\x22\x93\x6f\x02\x2f\x8b\x5e\x4a\xb8\xf6\x15\x3d\x3e\xd0\xc8\x00\xed\xef\xd0\xef\x28\x81\x17\xea\xa2\x85\x8d\x36\x08\xfc\x08\x76\x3b\x43\x92\x1b\x24\x79\x40\x07\x71\xb4\x71\xc5\xee\xa2\x68\xe3\x81\xde\x93\x98\x77\x09\x49\x15\x71\xe9\x34\xf6\xf5\x87\xf6\xce\x48\xf1\x0b\x37\x2d\x21\x99\x34\x9a\xad\x63\x3a\x2f\xf4\xab\x83\x8b\x0c\xb1\xb9\x03\x72\x0f\xbd\x9d\x45\xfa\x1e\xd6\xfb\xc5\xbe\x16\x04\xef\x3c\xa6\x3f\x44\x72\x63\x24\x19\x7a\x21\x8d\xee\xca\x98\xde\x16\x9b\x3e\x61\xdf\x6f\xec\x65\x8f\x59\xee\x30\x33\x0f\xbb\xdd\x22\xd3\x3d\x9a\x9b\xa3\xcd\x16\xb2\x2d\x60\x0e\x3e\x92\xfc\xc5\x2c\x7c\xa4\x58\x42\x2a\x45\xcc\x78\x8b\x66\x8b\x98\x65\x15\x79\x8e\x08\x3e\x63\xdc\xfa\x0f\x9b\x8b\x61\x77\x03\xcc\xe1\x84\x7e\x9d\x31\x6b\x0f\x49\xc6\x91\xd4\x85\xc0\xcf\xe1\x7a\x29\xf4\xbe\x26\x78\x8e\x90\xfe\x10\xbb\xbd\xa3\x9b\x39\xe6\x3d\x43\x1e\x1f\xcc\xf0\x84\xdd\xee\x71\xfd\x08\xba\xbd\x60\x46\x0d\xcc\x57\x01\xcd\x67\xd1\xef\x16\xf2\xce\x23\xe5\x5f\x82\x7b\x03\xb3\xbe\x62\x97\x31\xec\x35\x87\xf1\xd3\xd8\x69\x12\x79\x1d\x30\xdb\x16\xc1\xab\x84\x16\xa2\xb8\xe1\x89\xe0\xd9\x22\x78\x2c\x90\x7b\x1c\x99\x15\x91\xed\x03\x49\x7c\x70\x63\x1f\xd7\x49\x22\x5f\x29\xdc\xe0\x1b\xf7\x53\xc0\x7e\xbe\xd1\xe6\x06\xbd\x1d\x70\xdd\x37\xf6\x53\xc5\x0c\x3f\x48\x31\x8e\x54\x57\xc8\xb2\x81\x39\x8f\xd0\x5c\x04\x99\xa5\x91\x62\x0e\xc9\x7d\xe3\x06\x35\x4c\x3f\x8a\x64\xc2\x67\x8d\x90\x7a\x11\xe3\x2d\xd0\xc6\x0e\x9b\xf9\x43\xca\x47\x34\x11\xde\xc3\x89\xe0\x1d\xe6\xd8\x04\x79\x47\x70\xc9\x3b\x52\x4a\x21\xf7\x18\x92\xcc\x13\xbc\xbe\x70\x9d\x19\x7a\xcd\xa0\xdf\x09\xc4\xeb\x63\x96\x7b\x64\xf6\x83\xa4\x53\x98\xe3\x1b\x89\x3c\x91\xf2\x0d\x53\x4a\xa3\xad\x32\xc6\x3f\x23\x99\x1a\x2e\x92\x45\x47\x69\x24\xd5\x41\x36\x6d\x24\xd2\x41\x77\x3d\x02\xef\x88\x7c\x7e\xd1\xaf\x0c\xda\xdc\xe1\x3a\x13\x74\x38\x47\x0f\x43\xe4\x3b\xd4\xc7\x13\x53\xca\xa3\x85\xf0\xff\x9f\x48\xd2\x47\xdb\x75\xcc\x6b\x8b\x9e\x43\x5f\xc7\x30\xd9\x34\xb2\xcc\x23\xc5\x33\xc1\xbd\x8e\xc9\x5d\xb1\xb1\x23\x52\x8a\x11\x78\x7f\xd8\x5d\x0a\x17\x89\x21\x87\x6f\xa4\x9f\x42\x0a\x49\x4c\xf4\x97\xe0\x55\xc6\xee\xe3\xa8\x3f\x46\x4a\x1f\xe4\x10\xc1\x24\x97\x48\x39\x86\xf1\x26\x18\x3f\x85\x3c\xbf\x90\x4a\xf8\x19\x73\x5c\x3d\xec\xdb\x50\xa7\x73\xdc\xa2\x89\x78\x5f\xe8\xf5\x88\x6c\xdb\xc8\xfb\x86\xeb\x96\x31\xad\x24\x36\x5f\x46\x66\x07\x64\xdf\x40\x37\x61\x7e\x1d\x71\xc9\x22\x32\x3f\xe1\xfc\x04\x5a\x5a\xa1\xed\x37\x76\x9f\xc1\xbc\x7e\x30\xf3\x6f\x6c\xd6\x43\xaa\x13\x24\xec\xfc\xca\x2f\xc1\x33\x8a\xf6\x7b\xc8\x2e\x85\x66\x1f\xd8\xca\x1c\x37\x7e\xe0\xda\x47\x82\xfb\x1b\x53\x89\x63\xf3\x07\x74\xbf\x44\x72\x1f\xa4\x9a\x43\x07\x25\xa4\xbc\xc7\x56\x5e\x68\x7f\x85\xdc\xb7\xd8\xd7\x16\x33\x0a\x3b\xbb\x8b\xdc\xc3\x1c\x3a\xa3\xa7\x15\xf6\xd3\x47\x36\x2d\x74\x50\x41\x4b\x35\x82\x77\x0f\x3d\x9e\xd0\x30\x4f\xf7\x51\xa4\xbc\x40\x9b\x2f\x24\x5d\x46\x47\x55\xd4\xbb\xa2\x91\x12\xba\x99\xa0\xe3\x0c\x76\x15\x41\xa6\xbf\xc8\x20\x8d\x6e\x16\x48\xcf\x43\xca\x57\xdc\xe1\x89\x9e\x26\xd8\x65\x8a\xc0\x4f\x62\xcf\x0f\xcc\x79\x89\xc9\x1c\x90\xdb\x02\xf3\x3b\x42\x5b\x6b\xb4\x3f\x40\xb6\x27\x8c\xbf\xc1\xbe\x7c\xb4\x5f\xc4\xee\xc2\x0c\x19\x22\xc9\x24\x92\xbc\xa0\x5e\x05\xc9\xcc\xd0\x5c\x98\x4f\x77\xec\xf5\x84\x0e\x2b\x18\x3f\x8e\xdc\xc2\x8c\x38\xa3\x83\x0f\xa6\xb1\xc7\x75\x8a\x38\xbf\x8a\xc9\xed\xb0\xe7\x21\x92\xf6\xb1\x85\x38\xc6\x5f\x22\xc9\x33\xc1\xf3\x49\xf0\xea\x20\x83\x2e\xda\x3b\x62\xdf\x75\x82\xcf\x16\xfd\x4a\x22\xc3\x90\x5d\x7e\x91\xd9\x10\x17\x89\x62\xfe\x1a\xd8\xcc\x03\x29\x8e\x90\xf2\x09\x7b\x9e\x20\x95\x38\xb2\x2b\xa0\xed\x39\x36\x5a\xc0\x2e\xb3\xe8\x21\x8b\x69\xf8\x48\x6e\x88\xdc\xce\xd8\xdb\x10\x1b\xe6\xde\x20\x86\x9b\x7e\xa3\xd3\x08\x52\xb9\x23\xb9\x35\x52\x4c\xe3\xda\x27\x02\xaf\x86\x64\x06\x48\xa6\x87\xe6\x5a\xd8\x48\x1c\xcd\x7d\x21\x83\x32\x66\xd3\x44\xca\x33\xe4\x9d\x40\x8b\x13\xb4\xff\x83\xbd\x55\x31\x61\x8e\xd6\x26\x68\xef\x8d\xf9\x0d\xcf\x37\xc5\xfc\x76\x30\xdb\x08\xf6\xb3\xc7\xd5\x0e\x48\x76\x87\xec\x5f\xc8\x7d\x80\xec\x13\xd8\x62\x16\x49\x1d\xd1\xec\x07\x93\xff\x23\xf0\x67\xb8\x4e\x05\xd7\xfe\x20\xdb\x29\xa6\xb4\x43\xca\x05\xec\xee\x86\xbd\x26\x91\xf7\x16\xbb\x5d\xa3\xa5\x25\x72\x0b\xf5\xb8\xc3\xbe\xce\x68\xf6\x8d\x54\x16\x18\xef\x07\xd3\xcb\x11\xbc\x07\x04\xcf\x36\x6e\x7c\xc5\x8c\x23\xd8\xd7\x0b\x89\xd4\xd0\xcc\x07\xf3\x13\x45\x06\x15\xcc\x31\x8b\x7e\x15\x30\x5f\x73\x64\x3b\xc1\x4e\xa2\x48\xea\x86\x8d\xf7\x31\xfe\x00\xfd\xae\x20\x83\x16\x92\x8d\xa1\x97\x3c\x41\xf8\xce\xc5\x32\x76\x97\x45\x3e\x17\x5c\x27\x43\xe0\x17\x31\xaf\x16\xa6\x57\x41\xca\x79\xf4\x9c\xc7\x35\x3a\xd8\xfc\x02\x99\xf5\x91\x4c\x15\xb3\xf4\x71\x93\x2a\x2e\x52\xc1\x0d\x46\xe8\xed\x86\xee\x8a\x98\xe1\x06\xd3\xdd\x62\xfc\x0c\x36\xda\x45\x0f\xe1\x9d\x54\x09\xbc\x2a\x52\xff\x41\x5b\x13\xec\x2d\x7c\xe6\x2f\x12\xed\x63\xe2\x19\x64\xb6\x45\x76\x43\x4c\x7c\x89\xfd\x24\x91\x49\xe8\xaf\x39\x52\xdc\xa3\xe7\x23\x92\xf1\xd1\xfc\x1f\xfa\x89\x20\x9b\x06\x5a\xf9\xc6\x34\x42\xde\x0d\xef\x2b\x89\x8e\xee\xe8\x68\x8c\x7e\x4d\x09\xde\x17\xa4\xb2\xc4\x34\x8e\xe8\xfd\x4e\xf0\x48\x62\xcb\x7d\xa4\x7a\x42\x5b\x4b\x74\x35\x46\x1f\x4d\xec\x79\x89\x16\x87\xb8\x49\xc8\x01\x3e\xba\xfb\x45\x3b\x5b\xcc\xea\x44\xf0\xe8\x20\x8b\x0c\x3a\x2b\xa2\xd1\x1d\x9a\x5d\xe3\xea\x61\x0f\x6f\xd0\xc2\x1c\x97\xac\x21\xdb\x0c\x9a\xff\x20\x5e\x19\xe3\xdd\x91\x82\x8f\x79\x7a\xb8\x5e\xc8\xf0\x2d\x5c\x2d\x64\xc3\x36\xf2\x15\xb2\xed\x1c\x69\x1c\xb0\xbb\x1d\x76\xbb\x41\x13\xa1\x0e\xc6\xb8\x4e\x02\x5b\xba\x61\x0b\x57\xdc\xb1\x8f\x39\x6e\xd1\xe6\x0c\xd9\xac\xb1\x89\x03\x66\xfc\x8b\x8d\xcd\x91\x66\x02\xf7\xee\xa0\xcf\x06\x26\xe4\xe9\x7b\x05\x3b\x8e\xa0\x7f\x13\x74\xb2\x47\x4b\x05\x74\x53\x40\x8f\x1d\x24\xd3\x45\x1b\x3e\x76\x5f\xc7\xf4\xde\xd8\xed\x0a\xed\x74\x31\xc7\x1a\xc1\xe3\x80\x49\xc7\x31\xc3\x1e\xc1\xa3\x84\x0e\x22\xd8\xe2\x0e\xd9\x46\x71\xc7\x28\xf6\x7c\xc1\xd5\x86\x98\xe4\x0c\xbb\xf3\x31\xe5\x0d\xc1\x73\x87\x5b\x84\xec\x14\x6e\x86\x5f\xa4\x3c\x27\xb8\xef\x91\xe1\x03\x2d\x87\xec\xb0\x47\xf3\x49\xe4\xb9\xc0\xf6\xf2\xe8\x31\x8b\x44\xd3\x98\xf5\x07\xcd\x2e\x31\x9b\x06\xc1\xa3\x82\xdd\x47\x71\x63\x0f\x13\x1f\x62\x9e\x6b\xe4\x1d\xc5\x26\xee\x48\xb3\x8f\x0e\xde\xd8\x44\x17\xe9\xed\x91\x67\xd8\x77\x45\x6c\x3c\xf4\xfb\x10\xb3\x28\x13\x3c\xf6\xe8\xb0\x4e\x10\x66\x7e\xb8\x49\x92\x13\x34\xf2\x85\x99\x46\x91\x48\x11\x33\x6f\x62\xba\x69\x82\x4f\x1c\x37\xe8\x60\xc7\x73\xec\x2e\x81\xf9\xf8\xd8\x58\x16\x7b\xbb\x20\xfb\x27\x76\x3c\x45\xb6\x2f\x34\xfb\x87\x4e\xb3\xc8\xbd\x40\xf0\x9c\xa1\xf5\x22\xf2\x1d\xc3\x84\x3d\xb6\xed\xa3\xfb\x09\x32\x6f\x61\x06\x53\xb4\x10\x72\x5a\xb8\x3b\xb6\x68\xff\x17\xd9\xfe\x20\x5e\x0a\xf3\x6c\x62\xb2\x3d\xec\x72\x81\xb6\x47\xb8\xde\x0d\xd7\x88\x60\x77\x2d\x24\x64\xdf\x43\x12\xcd\xd5\xb1\xd3\x18\x36\xfe\x8d\x54\x9f\xc8\xaa\x8d\x76\x76\xc8\x2a\x8a\xf1\x3f\x68\xe7\x8a\x94\xba\x98\xde\x10\x3b\x1e\xe3\xee\x63\x64\xd3\x41\xfc\x2b\x52\x3c\x60\xe3\x57\xe4\x90\x27\x78\x8c\x09\xee\x67\x5c\x27\x85\x1b\xbf\xd1\x52\x16\xa9\x46\x30\xd1\x1d\x72\x8c\xa2\xa5\x1f\x74\x30\xc4\x46\x2a\x48\xf8\x9d\x97\xb2\xd8\xcb\x05\x7b\x3b\x21\xf5\x39\xb2\x99\x62\x77\x6f\x24\xbd\xc3\xc6\xc7\xb8\xc9\x00\xfd\x7b\x63\xfc\x22\x52\xbc\xe1\x5e\xe1\x1e\x1d\x62\x6b\x77\x74\xdb\x44\xf7\x77\x64\xdb\xc2\xe6\x5b\xc8\x6d\x80\x89\x65\x91\xe3\x1a\x79\x1e\x70\xbd\x70\xef\xae\x90\x79\x19\x3d\x7e\x70\xfd\x23\x3a\x48\xa1\xa5\x09\xea\x57\x71\x5f\x69\xdc\x7c\x83\x5e\xea\xd8\xcc\x0f\x1a\x89\x60\x2f\x57\xc4\xab\x23\x33\x8f\xe0\x99\xc3\x44\x2f\x98\x55\x09\x17\x69\x60\xa2\x1b\xec\xa5\x87\xbc\x6a\x48\xf9\x0f\xf7\xac\xa3\xb5\x0d\xa6\xd7\xc6\x4e\xa3\xb8\xce\x1a\xf1\x6e\x48\x63\x87\xbc\xbe\xb0\xe5\x02\xc6\xdb\x21\x91\x21\xe6\xd4\xc4\xf4\x9a\xe8\xea\x07\xf3\xb7\xc0\x2c\xa3\x48\xee\x07\x19\xc5\x90\xe1\x10\xfd\xfe\x41\xaf\x0b\xe4\x91\x44\xea\x19\xcc\xef\x10\x93\x0a\x7b\xe2\x17\x3d\xbd\xb0\x89\x2a\x32\x9d\x61\x26\x27\xf4\x6f\x89\x8b\x16\x09\xde\x4b\x64\xb7\x42\xbf\x26\xc8\xcb\xc7\x76\xaa\x68\xb3\x8f\x6d\x86\xcc\xb5\xc1\x78\x27\xe4\xf9\xc0\xcd\x8f\x04\xcf\x3b\x9a\x6b\xe3\x42\x9e\x7b\x7c\xd0\x6e\x0b\x5b\xbc\x61\xea\x0b\x64\xfc\x8d\x78\x39\xcc\xa6\x8a\x46\xaf\x68\xe6\x86\xdd\x7e\x90\x71\x03\x99\xa7\x71\x91\x32\x1a\x66\x73\x26\x82\xb6\x42\x6f\x85\x9d\x37\x46\xf7\x3b\x5c\x34\x4d\xe0\xbf\xd0\x5d\x0d\x3d\xcd\x71\x91\x08\x7a\x6e\xa1\xd5\x14\x26\xba\x47\x5e\x61\xa7\x35\xb1\x91\x16\x32\x2b\xa3\xf9\x35\xf2\xe9\xe0\xea\x7d\x4c\x61\x8b\x19\xff\x11\x78\x19\xcc\x23\x8a\xf4\x33\xb8\x5e\xc8\x88\x2f\x82\xf0\x3d\x73\x2f\xcc\x2e\xec\xc3\x0b\xae\x1d\x32\x5b\xc8\x1c\xe1\xc6\x7a\x21\xa3\x14\xae\x97\xc0\x7e\x4a\xe8\xa9\x87\xc9\xdc\xd1\xf9\x13\x17\xfd\x60\xf7\x79\xa4\xb2\xc2\xa5\x4b\x98\x42\x98\xe3\x2d\xcc\x79\x87\x44\xcb\x48\xf2\x8e\x5b\xa4\x30\xe7\x09\x66\xb9\xc0\x26\x62\x68\xc8\x3e\xe1\x99\x0f\x29\xe4\x13\x7a\xae\x8d\xc6\x73\xc8\x38\xdc\xc4\x2d\x34\x91\x41\xfb\x07\xb4\xf7\xc1\x78\x33\xcc\xb1\x85\x44\xde\xc8\xbe\x8b\x69\xf5\xd0\x79\x17\xfb\xdf\x87\x79\xec\x79\x83\x99\x86\xb9\xda\x43\x0f\x21\xc3\x44\x31\x93\x12\xee\x67\x85\xe9\x55\xd1\xe2\x17\xf2\x1c\xa2\xdd\x33\x92\x3d\x62\xcf\x3b\x74\x9b\xc3\xa5\x73\xd8\x5d\x91\xc0\x1b\x23\xa1\x96\xc6\x61\xee\x86\xdd\x93\x41\xf6\x6d\x5c\xcb\x47\xcb\x1b\x4c\x6c\x8b\x6e\xf3\x48\xea\x0f\x1d\xcf\x91\x45\x1a\xbb\x59\x60\xfc\x27\x9a\xef\x21\x95\x33\x81\xdf\x46\x2f\x5b\x5c\x74\x83\xbc\x2b\x68\x6c\x85\x56\xd3\xd8\xfd\x0d\x7b\xf9\xc6\x6c\xc3\x5d\xd0\xc0\x6e\x27\x98\xc6\x0d\xa9\x3c\x90\x5e\xa8\x97\x50\xbb\x15\xec\x39\xec\xe3\x3c\xa6\xe4\x23\xb7\x15\x36\x12\x72\xc7\x02\x5b\x0c\xf7\xff\x06\x7d\xbc\x71\x8d\x2d\x92\x0e\xf7\x92\x8f\x6b\x24\xd1\xaf\x50\x3b\x6b\x24\x3b\x47\xd2\x03\xcc\xe4\x80\x7b\x7d\xd0\xcc\x0f\x26\xf6\xc4\x79\x3e\xc6\xf3\x30\x8b\x28\xe2\x0d\x31\xbd\x1e\x26\x9b\xc1\x3c\xeb\x48\x3a\x82\x19\xf4\xd0\x76\x01\x59\x77\xd1\x6b\x16\xb3\xa9\x21\xed\x33\x5a\xae\x21\xc7\x3b\xda\x0f\xb3\x2a\x81\x1d\xb7\xb0\xad\x32\xb2\xac\x62\xcf\x77\x6c\xb2\x82\xcc\xcf\xc8\xd7\x02\x8d\xef\x08\x1e\x6d\x82\x67\x07\x8d\x4e\x90\x42\x04\xe3\x1d\xd0\x6c\x09\xfb\x5e\x63\x23\x27\xe4\xf5\x83\x4d\x4f\x09\xbc\x0f\xa6\x16\x32\xd5\x05\x9b\xc8\x62\x96\x11\x6c\x65\x45\xf0\x49\x60\x5e\x55\x6c\x26\xf4\x44\x0b\x69\xde\x30\xde\x05\xd9\xdd\xd1\x43\x0b\x2d\xc4\xd0\xf3\x0f\xf6\xec\xe1\x5a\x3f\xe8\xf0\x0f\x93\x49\x61\xe2\x3b\xf4\x3c\xc7\xac\x7c\x64\xd2\xc1\xbe\x76\x48\x3e\x8d\xc4\xcb\xa8\xdf\x45\x4a\x6d\x6c\xad\x83\xcd\x9d\xb0\xb1\x1d\x32\x18\xa3\xc3\x03\xb6\x38\xc6\x26\x3f\x04\x7e\xa8\xd3\x24\xb2\x7f\x63\x5f\x4b\x24\xb5\xc7\x9e\xc7\x98\x8e\x8f\xf3\x4b\x48\x36\x87\xab\xf9\x48\x3e\xdc\x48\x71\x5c\x37\xcc\xfe\x15\x2e\xbe\x41\x4e\x7b\xe4\x1e\x45\xef\x3b\x82\x67\x19\xfb\x5a\x11\x78\x6b\x74\xf7\x85\xd6\x17\xd8\xd2\x2f\x92\xf1\xd0\xcb\x0f\x66\xd9\x46\xcb\x67\x74\xf4\x83\x44\xc3\xae\xdf\x62\x63\x63\xe4\xd8\xc3\x34\xda\xe8\x69\x8c\x19\x8c\x31\xbf\xe1\x8e\x09\xcf\x3c\xc3\xb5\x23\x04\xcf\x2a\x7a\x48\x63\x33\x45\x4c\x98\xdb\xfe\x17\x26\x76\x47\xea\x47\xcc\xf4\x86\xf1\x43\x56\xcf\xa3\xb7\x31\xb2\x6f\x22\x95\x70\xa3\xdd\xd0\xe1\x19\xa9\x66\x90\x77\x0d\x37\xe9\xa3\xa7\x1f\xcc\xaa\x88\x7c\xc2\x67\x5d\xb0\xf5\x01\x9a\x6f\xa2\xe7\x6f\xb4\x94\xc1\x7d\xf5\xb1\xef\x1e\x32\xdd\xe2\x1a\xa1\x9f\x7e\xb1\x9d\x2e\xf2\xdc\xa1\xd5\x35\x1a\x9e\xf5\xf1\x44\xfc\x1b\xb2\xcf\x61\x7e\x5a\x98\x70\x1b\x3e\x13\xb8\xee\x15\xd3\xac\xa2\xfb\x32\xb2\xfd\x45\x96\x15\x5c\x3f\x8d\xa9\x7e\xa3\x91\x1f\x64\x3f\xc3\x54\xce\xc8\xfb\x07\x2d\x97\xb1\xa9\x3e\xf6\x33\x40\x66\x0f\x6c\x72\x8f\x79\xb6\x31\xe5\x11\x66\x7d\x43\xa7\x5b\xf4\x7b\x80\xf9\x7d\xa0\xc7\x21\x12\xfb\xc3\xf8\x27\xe4\x93\xc2\xc5\x16\x48\x76\x8d\x3c\xee\xe8\x25\x85\x8e\xc2\x5c\x9b\x63\xb2\x1d\xec\x79\x8b\x99\x3d\xd1\x90\xa3\x6b\x23\x8c\xf7\xc0\xbc\x26\x68\xbe\x88\x84\xfc\xdd\xcc\x61\x27\x4d\x64\x18\x47\xf2\x33\xcc\xab\x8b\x49\x2c\xd0\x57\x9f\xe0\x59\x44\x26\x2b\xf4\xef\x88\x79\x0e\x90\x65\x1d\xc9\xe4\x70\xf3\x03\x81\xff\x41\xe6\x4d\x5c\x7d\x80\xfb\x7b\x12\xdc\x5f\xd8\xdb\x0a\x17\x7a\xbd\x10\xfe\xfe\x8d\x66\x7f\x91\xe6\x00\x3b\xc9\x63\x62\x1b\xf4\x30\x46\x1e\x5f\xd8\xdd\x1d\x79\x86\xfb\xef\x80\x4e\x92\xc8\xfc\x8a\x9e\xa3\x98\xe8\x1b\x9b\x19\xe2\xb2\x67\x6c\x3e\xe4\xbd\x27\x1a\xfe\xcd\x2e\x8a\xa6\x63\x48\x98\xe9\x1d\x0f\x19\x36\x90\x5d\x02\x39\xe4\xb0\xb7\x38\x7a\x1f\xa3\x85\x2a\xc1\xfd\x81\xcd\x86\x3a\x0d\xfd\x1e\xb2\x55\xc8\x7c\x0f\x34\x73\xc6\x8c\xa2\xe8\x64\x81\x0d\x33\x3c\xd5\xc0\x5e\x66\xe8\xbd\x81\xd4\x37\xe8\xd7\x1f\x6e\xd2\x42\xe6\x0d\x5c\x3d\x49\xe0\x1f\xb1\x9d\x12\x26\xdc\x8a\x8b\x07\xc1\xa3\x8c\x29\x17\x31\x8d\x13\x3a\x2e\xe0\xa2\x17\x24\x19\xc5\x75\x53\xd8\x6f\x8f\xc0\xaf\xe3\x36\x65\x5c\xa3\x82\x76\xea\xe8\x7e\x8b\x24\x9f\xb8\x6e\x05\x33\x29\x62\x2f\xbf\x68\x7e\x85\x7c\x46\xd8\x58\x1c\xf3\xbc\x63\xb2\x17\x34\x37\x41\x8a\x5d\xe4\xb6\x44\xa6\x27\x24\x99\x40\x07\x7d\xec\x76\x87\xdd\x75\x31\x93\x25\x66\x3e\x47\x87\x3b\xdc\xf8\x82\xdc\xc6\x98\xe1\x1a\x8d\x1d\x31\xd1\x02\xee\x9d\x20\x78\x2e\x30\xf3\x15\xb2\xf3\xd1\x71\x0c\x57\xf7\x90\xfe\x14\x8d\x56\xd0\xe8\x1e\x17\xaf\x62\xaf\x53\x34\xf7\x87\x2d\xd6\xb0\xc9\x37\xf6\x7c\x46\x87\x0d\xd4\x3f\x63\x0a\x3d\x5c\xbb\x81\x7d\xa7\x90\x85\x8f\x8c\x7f\xd1\xda\x0c\x89\xad\x30\x9b\x37\xae\xf5\x40\xb3\x7b\xcc\xf9\x17\x33\x8a\xe1\xfe\x6f\xa6\x32\x52\xc9\xe1\x3a\x57\x82\x67\x05\x69\xc6\x30\xcd\x16\xa6\x7e\x45\xd6\x29\x34\xd7\xc5\xa6\x63\x68\xf5\x8e\x7c\x8a\xd8\xce\x1b\xdb\x1f\xe3\x62\x3e\x36\x7e\x47\x6e\x6b\xb4\x30\x43\xa2\x57\xe4\x19\x47\x97\x2f\x24\x77\x24\x78\x9c\x70\xb1\x3a\x52\xc9\x12\xf8\x51\x4c\x3c\x86\x19\x35\x31\xcb\x21\xc1\xa3\x80\xcd\xec\x09\x9e\x67\x4c\xbd\x8f\x5e\x92\x04\xf7\x0e\xda\x8d\x61\xd2\x73\x74\x1d\xe6\xd7\x09\xfb\xb9\xa1\xdd\x90\x2f\x0b\x98\xe5\x12\x1b\x4f\x61\x77\x0b\xcc\x7e\x89\xbd\x97\x31\xf5\x1b\x76\x7f\x40\xaa\x29\x64\xfb\xc6\x9c\x72\xe8\xb9\x87\x7d\x67\xd1\xc4\x0c\xf3\xfb\x8d\xeb\x76\xd0\x48\x0d\x73\x6c\x13\x3c\xc2\x2d\xfe\x83\x8d\xad\x31\x87\x22\xfa\x55\x46\xaf\x31\x4c\xaa\x83\xe9\xa6\x08\xde\x0b\x34\xf6\x87\x96\xda\x04\xde\x2f\xc6\x1b\xe1\x52\x35\x4c\x3e\x86\x6b\x44\xd1\x5b\x04\x8d\xae\x30\xd9\x23\xae\x7f\xc7\x64\xfe\xb0\x97\x32\x2e\x92\xc2\x94\xd6\xb8\xce\x05\x33\x1f\x60\x96\x35\xf4\xd2\xc1\x1e\x0b\xc8\xeb\x81\xbc\x9e\x68\x2c\x8b\xbb\x6f\xb0\xd7\x3c\x92\x9e\xa1\x9d\x15\xe6\x7f\x1e\x65\x30\xcb\x90\x63\x2e\x98\xd7\x11\x9d\xec\x30\xb1\x12\x1a\x66\xde\x34\x8f\x5b\x1f\x30\x9b\x1e\x72\x1a\x23\xa9\x1a\x12\xee\xd9\xdd\x07\xbb\xab\xa2\x97\x3b\x7a\x0a\xf9\xfd\x85\xfd\x0c\x31\xe3\x24\xa6\x99\xc2\x9e\x6f\xe8\xb3\x8c\x59\x7d\x90\xd4\x08\xf9\x5d\x63\xe3\x51\x6c\x6e\x87\xc9\x4e\x90\x72\x0f\xdb\x8d\x20\xf3\x39\xee\x3e\x45\x8e\x1b\xcc\x3b\x87\xa4\x37\x04\xf7\x23\x32\x6e\x63\xfc\x36\x2e\x79\xc1\x7e\x17\x31\xbd\x14\xae\x31\x46\xbc\x0e\x66\xf3\x40\x52\x3e\x36\xdc\x9b\xd5\x04\x76\xb2\xc1\x6c\xf2\x68\xbe\x86\xc4\xbb\x68\xeb\x80\xab\xbd\x71\xf7\x21\xfa\x4c\xa1\xc7\x0c\xa6\x9f\xc5\x34\xcb\xe8\xcd\x47\xa7\x35\xcc\xba\x85\x19\x0f\x70\xc3\x35\x2e\xf2\x44\xb3\x1b\x82\xf7\x0a\x49\x67\xd1\x82\x87\x99\xb4\xd0\xd1\x0b\x13\xab\xa1\x83\x1d\x1a\x9b\xe2\x16\x65\x24\x37\xc0\x1e\x7e\xb0\xef\x17\x92\x8f\xe3\xee\x1f\xb4\xb5\x40\x2a\x61\x46\xf6\x31\x21\xa7\x0f\xf3\xd8\x77\x0e\x0d\xef\x63\xbe\x45\x2b\x7f\xb8\x9f\x18\xf6\xfd\x8d\xe4\xc3\x1c\x9b\x12\x3c\xf7\xd8\x5a\x1e\xe3\xd7\x70\xbd\x37\xc1\x3d\x64\xb0\x0b\xb2\x4c\xa1\xf9\x21\xb2\x4d\x63\xdf\x55\x5c\xe7\x0b\xd7\xfb\x42\x42\xee\xab\x27\x90\x73\x1a\xc9\xfe\x20\x91\x31\x52\x4a\x22\xb5\x3f\xdc\xfa\x8a\x6d\xee\x90\xcc\x0d\x6d\xce\x31\x5f\x3f\xd8\x4b\x1e\x99\x67\x09\x5e\x3d\xf4\x92\x46\x9f\xbf\x68\x2f\x3c\x67\x1a\x57\xeb\xa0\xe3\x38\x9a\xbd\x12\xf8\x0d\xec\xa7\x41\xf0\x69\x11\x78\x65\x6c\xb2\x81\xfb\xce\xa3\xd3\x03\x76\x91\x42\xc7\x29\x34\x96\x40\xca\x0d\xb4\xf6\x8d\xfb\x69\x21\xf9\x36\xda\xf2\xd0\xe3\x1d\xd9\xcc\x90\x4a\x05\xd9\x0c\xd1\xfb\x08\x39\x64\x30\xcd\x37\xb2\xe8\xa0\xf1\x3e\x81\xbf\xc7\xe4\x47\xd8\x78\x04\xbb\xaf\xa0\xb9\x1e\xae\x9f\x45\xc7\x55\x24\xe4\xcc\x76\x0f\x3b\xde\x63\x7a\x2d\xf4\xde\xc2\x26\xca\xd8\x4b\x13\xbd\x16\x30\x8d\x3e\xda\x7b\xe0\xda\x49\x6c\xac\x80\xd4\xd7\x48\x29\x8b\x89\xc7\x31\xde\x1f\xba\x4b\xa2\xed\x15\xc1\xf3\x07\xd3\x4a\x63\x92\x5b\xa4\xfc\xc0\xd5\xb2\x68\x65\x83\x2d\x94\x30\x7f\x4f\x5c\xf2\x86\x44\x6f\xc8\xb3\x8e\x6b\xcc\xd1\x68\x78\xa7\x7b\x64\x50\xc5\x3d\x7d\xcc\xe7\x89\xf1\xae\x48\xb9\x83\xc9\x1f\x70\x91\x2d\xe6\x55\xc1\xf8\x7d\x74\xda\x45\x73\x55\x6c\x6a\x85\x6d\xfc\x21\x3b\x0f\xf7\x33\xc3\xac\x53\x48\xea\x8a\x7e\xef\x90\x54\x01\x09\x77\x5a\xfa\x8e\xf1\x93\xc8\x20\xd4\xb8\x87\x49\xec\xb1\xaf\x3d\xfa\x37\x45\x3b\x79\x4c\x7b\x81\xbc\xc7\xb8\xc6\x06\xd7\x58\x10\xdc\x97\x68\xeb\x0f\xd7\xf0\x91\xef\x04\x5a\xe9\xa3\xd9\x2a\x2e\x16\x21\xf0\x36\xb8\xe4\x0e\xfb\xc9\x60\x33\x35\x6c\x22\x85\x4b\x5e\x71\xad\x23\xf2\x59\xe2\x92\x5d\xdc\xf8\x85\x79\xbf\xd0\xeb\x0a\x29\xde\x09\xfc\x16\xae\x13\x6a\x73\x88\xc6\xd7\xe8\x60\x83\x2c\xbb\xd8\x58\x17\x2d\x66\x71\xd3\x36\xfa\x8c\xa1\xed\x14\xfa\xe7\x21\x95\x37\x2e\x5e\xc2\xc4\x6f\xe8\x21\x8a\x54\x2f\xb8\xf9\x1e\x5b\x59\xe2\x7a\x49\x5c\x6c\x8b\xfd\x44\x31\xe9\x2f\xb4\x56\x43\x96\x3e\xf6\x72\x46\xb6\x67\x4c\x7c\x81\x44\x3c\xe4\x5e\x41\x9b\x55\x5c\x3d\x8e\xb6\x56\xb8\x54\x1a\x5b\x9d\xe2\xc2\xad\xd2\x0b\x39\xf6\x83\xe6\x0b\x48\x2c\x89\x4d\x3e\x90\xc5\x1c\x2d\x67\xb1\xe7\x19\x9a\x4f\xa1\x9b\x1f\x6c\x75\x8c\x8d\x7b\x04\xf7\x09\x7a\x59\x23\xe1\x99\xda\x31\xe4\xfb\x17\x2d\x8c\xb1\xcb\x0c\xf6\xfc\x83\xfe\x67\x98\x33\x7a\x08\x7f\x2e\x20\xa9\xb0\xd7\x3c\x64\xd9\xc7\xee\xc3\xec\xb8\x22\xb9\x70\x5f\xff\x61\xc3\x9d\xd6\x2e\x63\x43\x26\xef\x65\x70\x3f\x55\x82\x47\x03\xf5\x7e\x08\xee\x3d\xa4\x38\x41\x73\x0f\x5c\xeb\x86\xd4\x56\x48\x66\x8b\x5b\xbf\x31\x61\x5e\xc4\x86\x68\xb5\x8d\xab\xd7\xd0\xd2\x0d\x37\x49\x23\x0f\x1f\x1d\x26\xd0\xf8\x08\x8d\xaf\x08\x5e\x27\x02\x3f\x8d\x4d\x86\x8c\x36\x40\xaf\x33\x24\x5b\xc5\x7c\x2f\x91\xd1\x18\x3d\x3d\xb1\xd5\x03\xe6\xb5\xc6\xf5\x8b\x68\xf1\x1b\x1b\x2f\x61\xf3\x45\xd4\x0f\x39\x7c\x8d\x16\x93\xe8\xa3\x8d\x19\x15\x71\xfd\x6f\x5c\xec\x82\xad\x24\x30\xcd\x1d\x7a\x0b\xf7\x4d\xd8\x0b\x39\xcc\xf1\x07\x13\x6f\x23\xdb\x0f\x3a\x9e\xa2\x99\x0c\x6e\x7d\x42\x7e\x63\xd8\xe9\x17\xf2\xee\x60\xb6\x1b\xb4\x58\xc1\xc6\x46\x68\xad\x8a\x76\x6a\xd8\xf7\x0a\xdd\x7e\xb0\xa5\x23\x5a\xcd\xa1\x95\x24\x2e\x79\x40\x0e\x65\x4c\xf3\x17\xa9\x47\xb0\x61\xa6\x8e\x2e\xe8\xf1\x17\xd3\x3d\x60\xbe\x92\x48\x79\x84\x6b\x47\xb1\xa5\x03\xfa\x75\xc4\xbe\x9b\xb8\xda\x1a\xd3\x0a\x77\xd2\x00\xb9\xdd\x70\xf3\x0f\x66\x7e\x27\xb8\xb7\x31\xa5\x04\xea\x85\x5e\xdd\xe3\x22\x3e\xf2\xda\x20\xfb\x70\xdb\x7d\x90\xc5\x0a\x9b\x4d\x23\x95\x6f\xdc\x70\x81\x46\x56\x98\xe1\x16\xdd\xa4\xf9\x17\x00\x00\xff\xff\xbf\x1b\x72\xe3\x00\x20\x00\x00")
-
-func keysWordlistChinese_simplifiedTxtBytes() ([]byte, error) {
- return bindataRead(
- _keysWordlistChinese_simplifiedTxt,
- "keys/wordlist/chinese_simplified.txt",
- )
-}
-
-func keysWordlistChinese_simplifiedTxt() (*asset, error) {
- bytes, err := keysWordlistChinese_simplifiedTxtBytes()
- if err != nil {
- return nil, err
- }
-
- info := bindataFileInfo{name: "keys/wordlist/chinese_simplified.txt", size: 8192, mode: os.FileMode(420), modTime: time.Unix(1497960590, 0)}
- a := &asset{bytes: bytes, info: info}
- return a, nil
-}
-
-var _keysWordlistEnglishTxt = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x2c\x5b\xdd\xbe\xbc\x2a\x08\xbd\xf7\x2d\xc9\xa8\xd8\xa3\xe2\x41\x9d\x76\xfb\xe9\xcf\x6f\xad\xfe\x17\x83\xe5\x07\x2a\x22\x2c\xcc\x91\x4d\xda\xee\x2d\xc9\x66\xc5\xe6\x93\x64\x2b\x9a\x64\xf3\x35\x41\xbf\x78\x1e\xda\xf0\x32\x3c\x36\x24\x33\x24\xf3\x7d\xc5\x9e\x64\x5b\x43\x93\xe4\xac\x63\x20\xb1\x9d\x95\x73\xf6\xf5\xa6\x6f\xf1\x65\x0a\x56\xd9\xf6\x24\xd9\xd7\x98\x96\x93\xe4\xff\x96\x05\x72\xc3\xd9\x18\xf5\xa7\x61\x2c\x79\x7a\x80\xc6\xcb\x75\x2e\x29\x49\x76\xe9\x33\xc9\xbe\xe3\x67\x99\x8f\x6f\xf9\xfe\xb3\x06\x5e\xab\x81\xae\x02\xfa\x95\x96\x15\xa9\x21\xd1\xf0\x0d\x3d\x1e\x87\x58\x20\x71\x0c\xfd\x08\xc1\x78\x4e\xb1\x96\xe4\x54\xfc\x30\xe6\x33\x54\x93\x5c\x2a\x7b\x12\xab\x89\x2d\x2c\xba\xc7\x4c\x62\x03\xd2\x29\x12\x35\x49\xd9\x16\x68\xf6\xcb\x4b\x92\xa2\x28\x2f\xa6\x2d\x49\xc1\x7b\xd1\x07\xd4\xef\x24\xa5\x3a\x06\x58\xbc\xa1\x71\xbf\x24\x49\x09\x95\x1d\x15\x86\x27\x29\x53\x23\x49\xb9\xe5\x19\x49\xaa\x4c\x5d\x81\xf4\xcf\xda\x99\xa4\xfa\x4b\x29\xcf\xba\x86\xee\x49\x9a\x94\x07\x1c\x5b\xbe\x20\xa8\x96\x8d\x23\x6f\x27\xf8\xb4\x13\x63\x6c\x67\x3c\x49\x9a\x55\x88\xae\x7d\x98\xd5\x7c\x51\x2a\xad\x51\xa0\xcd\xe7\xc5\x06\xe3\x66\x32\xb5\x35\x41\x6a\xff\x2d\xd4\xfa\x35\x85\x42\xb4\x27\x49\x17\xcc\xae\x7b\xf1\x13\x6f\x5d\x25\x90\x80\x6b\xef\x41\x35\xe9\x61\x25\x49\xe4\x0b\x84\xeb\x1b\x2a\x20\xe0\x19\x27\x38\x42\x6a\x51\x31\x81\xa8\x18\x77\xd4\x27\x49\xf8\x6a\xc8\x09\x0c\x1f\xa9\x62\x66\x11\xf6\xe5\x1b\xe4\x87\xbe\x63\xea\x41\x15\x89\x69\xac\x30\x6f\x8f\x4f\x92\x81\x5f\x57\x94\x8c\x21\x5c\xfc\x31\x94\x94\xf5\xc6\x58\x55\x93\x8c\x79\x55\x49\x32\xaf\xa2\x53\x93\x4c\xaf\x49\xe6\x94\xfc\x41\xa2\x18\xc0\x9c\x36\xd7\x8e\xb2\x7f\x0a\xbe\xfe\x29\xe3\xda\xa1\x57\xeb\xa4\x92\x71\x15\xd6\xa4\xd8\xd7\x74\x90\x55\x5b\x92\xaf\x06\x55\xe8\xeb\x59\x76\x47\x0a\xd5\xba\xe5\xa3\xa0\x41\xfa\x24\xb9\x75\x38\x86\x73\x1f\xab\x24\xb9\x3f\xb7\x40\x11\x7f\x6d\xa4\x4d\xb6\x27\x6d\x92\x2f\x2d\x1e\x78\xf0\x96\x36\xd9\x4f\x4d\x9b\x9c\x69\x93\x42\x85\xde\xa0\x6f\x0d\x15\x4b\x49\x9b\xd4\xcd\x3d\x6d\xd2\xa4\x09\x92\xa6\x68\xc9\x9f\x16\x54\x0a\xea\xf6\x06\xa1\xa2\xfa\x00\x83\x61\x19\xf4\xa3\x33\x6d\x32\x67\xd1\xb4\xa9\xe4\x0b\xb4\x81\xac\xf9\xa4\x4d\xb3\x60\xe3\x6e\x9a\x31\xdc\x4d\xf5\x48\x9b\x1e\x1e\x78\x3e\xc1\x52\x2f\xf9\xe2\xe5\xb2\xb6\xa7\x4d\x0b\xf7\xf7\xa6\x50\xf7\x4d\xcb\x4c\x9b\x36\xf2\x6c\x7a\x18\xde\x06\xc8\x0c\x01\xef\x09\x75\xdf\x74\xde\xaa\xe0\xf4\x38\x58\x58\x7e\x32\xc6\x62\x78\xfe\xe0\x81\xb9\xaf\xc6\x6d\x16\x78\x89\x79\xa5\xcd\xde\xe6\x05\x6b\xb7\x15\xd9\x15\xb4\x92\x36\x4e\xaa\x08\x3a\x2b\x2a\x28\x87\x81\xd8\x0a\x79\x15\x77\xd2\x31\xbc\x22\xe5\x04\xcb\x22\x01\xc3\x35\xae\xb4\x39\x16\x64\x73\x99\x69\xf3\xfd\x49\x9b\x5b\x49\x9b\xd7\x2d\x6d\xd8\xbc\x9b\xb7\x35\xd2\xe6\xfe\x01\x41\x37\x1e\x3b\x46\xe3\x81\xbd\xba\x39\xf5\x75\x83\x39\xdb\x7c\x42\xc9\xb6\x77\xcb\x6d\xfe\x9b\x36\x7f\xd2\x16\x92\x39\xc8\xe0\xc2\x84\x60\x60\x21\xa8\x1f\x14\x28\xcc\x02\xa8\xfe\xe1\xc5\x30\xc7\x30\x6a\x41\x18\x16\x21\xec\xbc\xd0\x9c\xdd\x85\x0d\x94\x7b\xce\x5e\x0c\x0f\x1f\x08\x34\xbc\xb1\xb1\xa3\xfb\x78\xf7\xf8\x16\x7e\xa3\x88\x73\x5c\x1b\x6c\xfc\xb6\x76\x4c\x70\xed\x27\xc6\xb3\x8e\x43\x8a\xa7\x6d\x59\xd9\xd3\xb6\xca\x06\xf2\x01\x29\x2c\x6e\x3b\x9b\xb4\x0f\x98\xad\xd8\xd1\xd1\x8a\xf3\x7d\x83\x20\x20\x97\x35\xac\x51\xe0\x6b\x80\xf3\xbb\x50\xeb\x21\xfd\xfb\x4b\x59\xb6\x0d\x9b\x24\xcb\x66\x0d\xb4\xe0\x39\xcf\x35\x52\x7e\xf3\x3f\x20\xa5\x80\xd4\x94\xa5\x6a\x08\x92\x9e\xb2\xa0\x41\x13\x14\xb5\xac\x4c\xf6\x07\xb4\x39\x4b\x1c\x2d\xdb\x57\xc0\xaa\x3d\xcc\xeb\xff\x3a\xe8\x36\xd9\xae\x4f\x61\xb7\x81\xdf\xc6\x2a\xb1\x83\x9c\x0e\xda\x75\x22\x09\x70\x0d\x3c\x0e\x34\x1e\x17\x88\x35\x54\x19\x93\xfc\xc6\x22\x3b\x54\x99\x52\xfc\x44\x9a\x51\x6d\xea\xe9\x6c\x3e\xdf\x8a\x0b\x4b\xf5\x6e\xa4\x2c\x8b\xc6\x24\x63\x91\xb3\x5a\xc1\xfa\x65\x2d\x8a\xfa\x5a\x61\xbd\xb3\xb6\x01\x49\x68\x9b\x8b\xb9\xa1\xe8\x47\xe3\x1d\xf6\x05\x3f\x94\x2f\x29\x1f\xd0\xda\xc9\xed\xa2\xcd\xcc\x97\xf8\x00\xed\x10\x78\xbe\x24\xde\xcc\x41\x3a\x53\xbe\x54\x3a\x68\x46\x5b\x55\xe6\xeb\x01\xc2\xe9\x5e\xd8\x9d\xf9\xb2\x0c\xf5\x81\xab\x46\x11\xf4\x20\x5f\x56\x9b\xa2\x86\xc3\x8d\xe6\xcb\x9d\x6d\xc3\x9b\xe5\x94\xaf\x95\xe1\x57\xf2\xb5\x1a\x18\xaf\x68\x29\xdb\x09\xf9\x5a\x6b\xf0\x5b\x29\x5b\x60\x53\x67\x9b\xf6\x07\xde\x00\x18\xd9\xbe\x56\x52\x2e\xf0\xad\xb9\x60\x60\x45\xc2\x8e\x07\xe9\x0d\x82\x27\xd8\xa2\x5c\x34\x3e\xa0\x5f\xcc\xaa\x60\x2f\xe4\x42\x47\x97\x8b\x1d\x07\x68\xdd\x40\x39\x98\x62\xe0\xe4\xac\x84\x35\x29\x1c\x6a\xf1\x79\x81\xae\x1d\xf4\x06\xd3\x85\x36\x0b\x3a\x55\xd6\xa0\xc0\xca\xe2\xfa\xb9\xbc\x14\xc2\xf0\xec\x6d\x21\xdd\x35\x65\x3f\x0e\x45\x82\x61\x3b\xd6\xc2\x4b\x81\xc3\xc9\x0e\x53\x9d\xbd\xc0\x03\x64\xaf\x9b\x35\x54\xab\x24\x07\xf0\x42\xf6\x8a\xb1\x79\xa5\x30\xbc\x76\x38\xd3\xec\x0d\xab\x8a\x74\x5f\x64\xd3\x0e\x8b\x8a\xf4\x24\xa0\xc9\xde\xda\xcb\xbf\x0d\x83\x79\xc9\xde\x66\x38\x7a\x6f\x5f\x83\x39\xc9\xb0\x40\xd9\x99\xd5\x3b\x6b\x74\x30\x0e\x68\x0c\xac\x74\x76\x2c\x86\x47\xbc\x7c\x38\xa5\x39\x39\x88\xc5\x59\xae\x36\xb1\xf4\xbe\xe0\xc3\xb3\xaf\x18\x4c\x06\xa7\x47\x81\xfb\xe3\x53\x53\x86\xc1\x02\xc5\xfe\xcf\x21\xc7\x04\xad\x20\x8d\x19\xd8\x20\x21\x94\x63\xc8\x5d\x40\xff\x9e\x94\x43\x59\x49\xe1\x3b\x73\xa8\x82\x87\xde\x29\xc3\xa4\x61\xa3\x85\x41\x4c\x61\xa3\x83\x02\x2e\xe4\x70\x3c\xc3\x76\xe6\x78\x47\x19\x7e\xef\x29\xc7\xca\x86\x79\xc5\x52\x52\xc3\x50\x63\x55\xee\xee\x58\x8d\x35\x17\xc7\x81\x8e\x9f\xc1\xed\xbe\x36\x4d\x79\x95\xb9\x20\x8d\xd5\xf1\x7b\x8d\x7b\x5e\x61\x8e\x8d\xb6\x22\xa8\x4c\xeb\xdf\x0e\x5b\x81\xbd\xb9\xc6\xc5\xad\xb5\x06\xcc\x77\x5e\x90\x01\x3d\xd3\x2e\x7b\xda\xa5\xc2\x50\xed\x30\x49\x3b\x1d\xf2\xfe\x82\xae\x5d\x68\x91\x77\x88\x63\xe7\xc6\x67\xe6\xdd\xd2\x2e\x4f\xda\xb1\x93\x77\xdd\x64\x2a\x92\xb0\x91\x76\xcd\x70\x5d\xbb\x66\xad\x1b\xea\x2a\xa0\x33\x92\x02\x2d\xda\x15\x8b\xc9\xea\x10\xe5\xc0\x03\x6b\x1d\xda\xf8\x72\xbc\xb5\x0e\x30\x27\x60\xdd\xb5\xb0\xa7\x62\x5f\x56\xac\x70\x2d\xbb\x56\x63\xf5\x66\x1c\x41\x23\x76\xda\xb5\xa1\x26\x31\xdd\xae\x5d\x59\xb1\xfb\x30\xbe\xce\x0b\x14\x28\x60\x57\x82\xb0\x5d\x47\x0e\xdb\xf8\xa0\x6c\x32\xec\x6c\x48\x3e\x20\x1d\x86\x69\xd7\x31\xc3\xd1\x64\x8a\xa1\xa7\x09\xc5\xdb\xf5\xab\xc5\x3b\x52\xd8\x8f\x5d\xbf\x50\xa9\xdd\xe4\x84\x0a\xed\x1c\x93\xc1\x50\xec\x48\xe3\x49\x3b\xab\x99\x0e\x45\x89\xce\xb4\xdb\x71\x60\x3a\x76\xd2\x88\xef\x76\x36\xd8\x90\xdd\x8a\xd6\x2a\x69\x37\x62\x9e\xdd\x9a\x0f\x59\x78\xa0\xc2\xef\x86\x61\xda\x78\xa1\xfc\x6e\xe3\x55\xe9\xdd\xc6\x2b\x4a\xc3\x2a\xd9\xa8\x36\x06\xd2\xd7\x87\xef\x36\x3a\x45\x68\x63\xbe\x4b\x0b\x49\x82\xcf\x97\x2b\x63\x5f\x0f\xe6\xfe\xfd\x3d\x69\x77\x86\x28\xbb\xe7\x45\xe3\xbd\xfb\x99\x76\x2f\x05\xa4\x5f\xd6\xd2\xee\x55\x98\x34\xae\xa2\xb7\x8f\xa2\x55\x63\x23\x12\x0c\xc4\x17\x94\x78\x07\x7e\xde\xb9\xb7\xf6\x90\xd3\x1b\x12\xcc\x2e\x84\x81\xd2\x1e\x72\xa7\x9d\x3b\xea\x8d\x78\xf6\x30\xd6\x35\x74\x18\xd6\x3e\xa0\x1d\x84\x8c\x20\xf1\x58\xa8\xfc\xa4\x7d\xe5\x4f\xda\x57\xdd\xd2\xbe\xa0\x31\xeb\xd5\x53\x60\xd9\x9d\x66\x6f\xe7\x4a\xdf\x12\x47\xda\x9f\x26\xb0\x57\x2a\x50\x69\x15\xc4\x11\x2a\x51\x1e\xd0\x06\x32\xaf\xa4\x32\x8c\x39\x63\x82\x3c\x49\xf3\xe5\x49\xf3\x0b\xd4\x34\x7b\xf3\xfa\x24\x05\x64\xe1\xe6\xd7\x7d\xc1\x33\x26\x3d\x68\x11\xf5\x3c\x93\x12\xc3\xa8\x11\x99\x68\xd9\xfc\x4e\x5a\x76\x3e\x6b\x9e\x81\x11\x14\x3d\xa5\x4d\xa4\x14\xaf\x16\xed\xd7\xbf\x8c\xaf\x40\xf2\x5a\x0c\x4c\xcb\xd0\xa4\x75\x93\xf8\x20\x01\x62\xd3\x0a\x8c\x85\x5c\x85\x1b\xd4\xea\x74\xbc\x5a\x7b\x71\x94\x76\x47\xb0\xa3\xb5\xcf\x27\x69\x23\x44\xd0\x06\xbc\x8f\x6d\xa0\x80\x39\x63\x20\x75\x58\x44\x6d\x8a\xc9\x34\x0d\xcc\xad\x1d\xd4\x00\x6d\x27\x8c\x80\xb6\x13\x7b\x50\xdb\x45\x6d\xd1\xf6\x03\xfe\xad\x60\x87\x69\xf3\x75\x5e\x49\x5b\x58\x66\x02\xd5\x80\x7f\x0f\x54\x84\x6d\xc0\x56\x7c\x5f\x02\xad\xb8\x4f\x34\x69\xb7\x01\x97\xa3\xff\x01\x63\xe8\x7f\xcb\x7a\x02\x06\xd2\x80\xde\x6a\xb0\x2c\x7c\x70\x46\x11\x90\x43\xac\x3e\x93\x8e\x2c\x68\x3e\x86\x3c\xa0\xca\x11\x8d\x49\xc1\x4f\x0d\x00\x27\x9d\x97\xe5\x91\x14\xda\xcc\x62\xb8\x61\xfd\xfa\x07\x8f\x5e\xbe\x9a\xf4\x97\x72\xf8\x95\x0a\xa7\xa0\xbf\x8c\xe9\xf5\xf7\x1f\xca\xd0\xdf\x4c\x91\xff\xe6\x82\x30\x49\x7f\x19\xda\xeb\xaf\xd2\x46\xea\xaf\x46\x36\x66\x5c\x02\xed\xd2\xdf\xcb\x36\xac\xff\xaf\x91\x19\xc5\xf2\xcb\x0c\x87\x52\xeb\x6f\x87\x85\xd2\x5f\xc6\x6e\xfa\xdb\x29\x8e\xdf\x5e\xb0\x6d\xf4\xb7\x3b\x79\xf5\x78\xc7\xc0\x10\x4d\x7f\x27\x64\xf1\x28\x7e\x40\xb4\xe9\x10\x60\xe4\x74\x60\xc1\x0f\x81\xb9\x7f\xd2\x01\xbb\x7a\x88\xb5\x09\x3a\xaf\x74\x00\x51\x1e\x02\x55\x39\x10\x28\x1c\x52\xa1\xc1\x07\x62\xea\x91\x0e\x69\xf8\x65\x64\xb4\x09\x85\x3e\x10\xa7\x1e\xf2\xfa\x81\x43\xc0\x06\xb6\xe7\x10\xea\xeb\x21\xd3\x10\xcc\x1e\x8c\x35\x0f\xf9\x7a\x40\x2c\x87\x0a\x5d\xcd\xa1\x5b\x2c\x98\xb2\x43\x77\x85\x3b\x06\x74\x38\x54\x77\x10\xbc\x55\x29\xc8\xc0\x0a\x1c\x3a\xa6\x7d\x59\x07\x3b\xf1\x20\xd0\x39\xf4\x4e\x87\xc1\x25\x1c\xf6\x06\xa0\x87\x69\xd9\xd3\x61\x27\xf9\x43\x9a\x87\x95\x0a\x32\x59\x0b\x8b\x7b\x20\xc2\xa1\x4f\x38\x8c\x0e\xe9\xb0\x06\x2b\x77\x18\xdb\x60\x42\x06\x98\x7e\xd8\xc8\xac\xce\x32\xbc\x4f\x22\xf6\xc3\x7e\xd3\x51\xe4\x04\x81\x88\x0a\x1c\xd9\x51\x30\xf9\x82\x29\xa6\xa3\x60\x1e\x85\x3b\xf7\x00\xd6\x3a\x8a\xb3\x14\x88\xeb\x28\xce\x2a\xdc\x5a\x47\x59\xb6\x83\x92\xc3\x93\x0e\x97\x9a\x0e\xcf\x90\xb5\x9f\xe9\x00\x8c\x3a\x1c\x33\x72\x9e\x8e\x1c\x08\xcb\x0e\xf7\x99\xde\xed\x85\x28\x73\xf0\x05\x81\xc9\x81\x20\x1f\x96\x03\xd6\xeb\x70\x98\xb5\xc3\x83\x61\xf3\xe1\x63\x90\x17\x51\xdc\xc1\x63\x84\xc3\x7f\xd3\x11\x72\x52\x4a\xc1\xa9\x84\xfe\xb7\x60\x43\x8e\x50\x8c\x28\x0c\xaa\x74\xc0\x0c\xa2\x10\x23\x0a\x67\x31\x50\xd2\xc1\x38\xe9\x08\x07\x5c\x3d\x62\x41\x44\x80\x1d\xc7\x6a\xf8\xb5\x27\x1d\x2b\x1a\xd5\x0d\x20\xfd\x58\x5c\xf4\x53\x18\x44\x31\xd8\x3e\xa5\xc8\xef\x83\x84\xe0\xfe\xc4\x18\x4e\xe9\xe9\x14\x1e\x10\x9c\x12\xdb\xbf\x14\x31\xd4\x29\x51\x2c\x23\xa1\x9d\x3b\x65\xe0\x87\xda\x13\x75\xa8\x71\xa7\x2c\x36\xf8\xd3\x74\xc2\x14\x49\x41\x6a\x6b\x20\x09\x66\x22\xde\x38\xb5\x2d\x28\xc0\xa9\xe3\x1d\xd4\x85\x09\x9d\x06\xb3\x79\xc2\x5f\x9c\x76\xc2\xa2\x9f\xaf\x82\x9c\x16\x72\x1c\x78\x8d\x92\x4e\x38\x8e\xb3\xc8\x0e\x02\xd5\x3c\x8b\x04\xe9\x18\xe9\x2c\xf0\x7f\x67\xb1\xda\x07\x52\xdf\x48\xbd\x82\x62\x8a\xc5\xd9\xda\xef\x74\x22\x9c\x3e\xa1\x18\xa7\xef\x3b\x14\xeb\xc4\x4a\x9f\x58\xe2\x93\xc1\xc3\xe9\xf0\x5a\x92\x4e\x1f\x5d\x0b\x92\x61\x3d\x9d\xf0\xcf\x2d\x9d\x10\xfe\x19\xb2\x81\x60\x14\x8c\x92\xcf\xe0\x14\x02\x16\xee\x64\xac\x7c\x86\x7c\x01\x03\xce\x50\x74\x15\x0a\x49\x86\xed\x20\x7a\x80\x22\xd7\x33\x17\x20\x7c\x75\xd0\x3b\x9d\xb1\xc0\x68\x41\x79\xce\xc5\xd1\x2d\x4e\x6d\x59\x41\xbe\x4d\x89\x74\xae\x96\xce\xa7\xa6\x4b\x60\xbd\x18\x75\x5d\x52\x8e\x74\x49\xad\x8a\xe7\x4a\x75\xbb\x60\xbc\x2e\xe9\xfd\x49\x17\xa2\x49\xe4\x04\x72\x62\x5c\xa0\x5f\xe8\x30\x82\x2f\x9e\x93\x5c\x72\x7f\xd2\x25\x7f\xac\x82\x08\xff\x52\x29\xf3\x42\x12\x13\xf4\xfb\xa4\x0b\x3e\xf3\xf2\x33\x5d\xaf\x7f\xbc\xb4\x14\x07\xad\xca\x97\x9e\x2e\x6d\xe9\xd2\xf0\x74\xd9\x0e\xe5\xb9\xec\xbc\xd2\x05\x10\x70\xc1\xda\x5d\xd6\xd3\x85\xfd\x7e\xd9\x98\x58\x98\xcb\xb7\x0d\x34\x03\x7b\x5c\x58\x88\xcb\x8b\x82\x18\x50\xe9\xf5\xee\xbf\x0b\x01\xcb\xe5\x8d\x75\x1c\x75\x3a\xde\xa3\x81\xc0\xc5\x5c\x74\x85\x97\x8f\x37\x90\xa6\x5a\x5d\x3e\x15\x8f\x0b\xc5\x30\x5b\xd7\xda\xd2\x05\x3d\xbd\x56\x95\x06\x0a\xcf\x7a\xad\x0a\x06\xab\xed\xa1\x3b\xd2\x13\xc3\xc2\x2a\x5c\x2b\x76\x56\x08\xe6\x40\x0a\x6b\x6c\x14\xea\xb3\x61\x29\x81\x04\x2d\x7b\x4b\xb6\xab\x24\x1e\x2b\x23\x48\x34\xb4\xb2\xb3\x21\xc8\xc1\xcc\xad\x00\x2a\x30\xa5\x21\x33\x02\x74\xab\x46\xdf\x67\xb5\x12\x2f\x5b\xad\xb0\x1f\x56\x3b\x3c\x9c\x55\x7a\x17\xab\xef\xc9\xa5\xd5\xbe\xe0\x1c\x0c\x91\x84\xb5\xd7\xbd\x59\x63\x20\x67\xed\x1f\xfc\xb6\xb6\xeb\x2f\xa8\x11\xcd\x58\x23\x8a\xb3\x06\x24\x15\x4f\xb2\x06\xef\x81\xa4\x58\x66\xea\x51\x93\xb5\x0b\xd6\xde\xda\xa5\x50\x49\x6b\x36\x81\x79\xad\xfd\x28\x2b\xfd\x2c\x36\xad\x2f\x47\x20\x59\x6b\xcd\xb3\x92\x53\x5f\xa0\xff\x2d\x63\x9d\x81\x70\xcb\xda\x78\x1b\x22\x2c\x44\x42\xa7\x69\x0d\x11\x0f\xd8\x4e\xce\x0e\xf8\x02\xda\x67\x6d\x7a\xb2\xf6\x7d\x9f\xbf\xc6\x4e\x5e\x4f\x6f\x01\xc1\x8e\x02\x79\xdb\xf0\xc2\x01\x8c\xb1\x34\xd9\xd4\x9a\x00\x75\x9f\xf4\xf3\x1e\x55\xfd\x08\x76\x4c\xfa\xe1\xef\xef\x2f\xfd\xa8\x14\x38\xce\x1f\x95\x06\x5a\xca\x93\x7e\xf4\xd6\x92\x7e\x7c\x4b\x3f\x08\x90\x7f\x00\x2a\x7e\x7c\x05\x94\x0a\xb0\xe8\x67\x01\x0f\xfe\x2c\x2c\xea\x0f\x62\xef\x9f\xc5\x53\xea\x9f\xd5\xcc\x03\xc9\x27\xf1\x10\xff\x23\xed\x94\x70\x4f\x1f\xec\xe9\x8f\x6a\x4f\x1f\x38\xc7\x85\xf4\x49\x1f\xcb\x9f\xf4\xb1\x1d\xbf\xc6\xf7\x86\xe7\x76\xee\x5e\xd3\x07\x70\xfe\x63\x13\xbf\x8c\xbd\xf2\xc1\x94\x3f\x36\x27\x9f\x6f\x4b\x9f\xa6\x9a\x3e\xcd\x0e\x50\x38\xae\x4f\xf3\x3b\x15\xd9\xf0\xd3\x02\xea\x91\x8a\xec\x00\xa3\x45\xf6\x27\x15\xf9\x68\x2a\x08\xf7\x8a\xb4\x73\x41\xb7\x8a\xf4\xe9\x78\x0f\xbe\x4c\x56\x9d\xd6\x52\x41\xdc\x07\xda\x00\xbc\x8b\x7c\x25\x15\x01\xfb\x1b\x65\xf7\x80\x33\x29\xf2\xb0\xfe\xdf\x93\x8a\x0a\xbb\x51\x39\x40\xa2\x81\x7e\x35\x01\x03\xc3\x7e\x17\x3d\x66\x2a\x7a\xa6\x57\xc1\x8b\x9e\x70\x5c\x45\x6d\xbc\xa5\xd5\xd1\x82\x59\xed\x9c\x17\x92\x91\x8a\x7a\x87\x91\x01\x8a\x65\x39\xcf\xe0\x0a\xe2\xb0\x54\x4c\x22\x15\x40\x8b\xf9\x20\x0d\xc0\x94\x62\x99\x3b\xa4\x40\x28\x05\x6e\xe2\xf5\xf1\xc5\x30\x71\xab\x1b\x08\x06\x8e\x28\xa3\x00\x8e\x14\xfb\x0f\x0e\x9e\x38\xb7\x18\x8f\xba\x10\x73\xa6\x62\x34\x6f\xc5\x85\xa4\xa5\xe2\x1b\x4d\x65\x71\x40\x0e\x02\x85\xe2\xa7\xe5\x54\xbc\x69\x79\x90\x9c\xa9\x38\x64\xe9\x18\x26\x72\x16\xda\x2e\xb8\x66\x3a\x95\xe2\x0f\x9a\xae\xfc\x79\x52\x59\x27\x71\x77\x59\x0c\x98\xcb\x6a\x42\x9a\xaf\x54\xd6\x2f\x76\x52\x79\x02\x08\xb7\x4a\xbe\xe0\x08\xab\xec\xa9\x0a\x3a\xac\x72\x36\x9d\xa9\x8a\x21\xc7\x4a\x62\x6c\x56\xe5\xc7\x23\x55\xac\x70\x95\x5a\x05\xd9\xc8\x6d\xe8\x05\xe1\x33\x76\x45\x95\x76\x3a\x28\x31\x77\x15\x7e\x39\xa9\x02\x80\x5c\x25\xb6\x37\xc9\x17\xe8\x49\x9e\xf1\x76\x1d\x1f\x76\x18\x61\x2f\xb7\xf1\x01\xc1\xe0\x28\x93\xca\x23\x43\x6c\xfc\x30\x32\x9c\x7c\x0b\xfb\x45\xf2\xd6\xf8\xb5\xba\x6a\xaa\xf0\xfb\x55\x65\xf7\x1b\x49\x03\xa1\x06\x54\xf8\xbe\xaa\x40\xe7\x98\xa2\xee\xe0\xa3\xbb\x49\xaa\x5a\x10\x09\x55\x2d\xa8\x40\x69\x55\xad\xd8\xd2\x00\x19\x9c\x87\xb6\x95\xaa\x46\x46\x16\xf4\xb8\xd2\x40\x55\x9e\x07\x56\xe0\xa4\x8a\x58\x82\x05\x93\x7c\xe7\xe5\x7b\xaa\xb6\xc3\xfc\x56\xdb\x1b\x95\xa4\x5a\xf9\x80\x50\x2f\xaa\x21\x76\xac\xd8\x91\xd5\xda\x3b\x76\x43\xbc\x5b\xad\x21\x42\xa8\x16\x92\xd9\x9a\x5e\xa5\xda\xc0\x92\x33\x06\xaf\x08\xb9\xb1\x0c\x98\xbe\xfd\x2a\x38\xfc\x72\x13\x54\xdf\x00\xe5\xaa\xef\x5a\x40\xe1\x02\xaa\x57\xfc\x60\x25\xab\x37\x43\x34\x58\xdf\xf8\xba\x7a\x7b\xa5\xeb\x0d\xf2\x74\x8c\x8a\x67\x62\xd5\xc9\x2b\x1a\x82\xdf\xea\xe3\xbf\x65\xd3\x53\x7d\xcf\xc6\xff\x45\x88\xd5\x5f\x4e\xab\xf1\x38\xa8\xf2\xfb\x40\x85\x16\x56\xff\x9a\xa6\xba\xb0\x62\xeb\x38\x50\xb8\x30\xa8\x55\xa6\xf5\xf2\xa4\xba\x06\x27\xb6\x86\x62\xd2\x6b\x5c\x3c\x7b\xaf\x6b\x40\x20\x30\x6b\x75\xf1\x13\x66\x7d\x86\x96\x03\x09\xd5\xbd\x3e\xf3\x4a\x4d\xb0\x79\x1a\x60\x62\x93\xfe\xb1\x96\xda\xfb\xd5\xab\xc9\x98\x4f\x6a\xc2\xc1\xb5\x37\xba\x68\x2a\x91\x9a\xe6\x4f\x6a\x08\x29\x9a\x9e\x32\xd9\x5c\x4f\x9e\x48\xb6\x7f\x41\x75\xd3\x7e\xe9\x9d\x9a\x06\x0b\x07\x4a\xf8\xe3\x37\xb3\xa6\x6b\x42\x2a\x8d\x01\x47\xd3\x7b\xa4\xa6\xbf\x33\x35\x98\xe7\x77\x65\x9b\x43\xb5\x9b\x23\xa2\x6b\x5e\x0d\x86\xb3\xb9\xef\xcc\x0c\xec\x95\xe6\x81\xd1\x3b\x2b\x4c\x79\xab\x4f\x92\x0b\x52\x6e\x88\xf2\xf0\x0a\xd3\x03\x33\xdb\x56\x2e\x1c\xfe\xbb\x7f\x1b\x8f\x1c\xdb\x9a\xc9\xe5\x93\x7c\xd3\x27\xf9\x46\xbf\xe8\x5b\xb1\x53\x93\x6f\x23\x63\xce\xbe\x0d\x4e\xc3\x37\xae\x8b\x6f\x5f\x1e\xdf\x79\xce\x2b\x92\x67\x6c\x09\xcf\xd3\xc1\xd3\x77\x8f\xe4\xc7\x81\x9f\xf2\x09\x43\xf0\x03\x0e\x00\x61\x87\x7f\xe4\x49\xc0\x41\x4e\x8b\xe5\xe5\xa9\xdd\x72\x72\x18\x38\x07\xec\xf5\x86\x1f\x04\xee\x8d\xe7\x70\xde\xca\x93\xbc\xa3\x7d\x47\x20\xee\xdd\xde\xe2\x4e\x08\xe1\x9d\xab\xe3\xef\xb7\x4b\x0f\x40\x46\x8f\x4c\x28\xf8\x9e\x2a\x79\xec\xd6\x60\x68\x3d\x4e\x8c\x34\x78\x80\xed\x61\x27\xe3\x36\x8f\x7e\x21\x7b\x4c\x9e\x14\xbc\x0a\xe9\x6b\x12\x5d\xf8\x9a\xef\x1b\xa0\x80\xaf\x49\xaf\xef\x08\x18\xfd\x8b\x11\x61\xf5\x80\x98\xfd\x06\x74\xf0\xdf\xe7\x44\x2e\x95\x2b\xf9\x1f\xe6\x42\xb8\xd3\x85\xbb\xb6\x63\x3b\xf3\xb0\xae\x4b\x01\xba\xee\x52\x6a\x42\x10\x2e\xa0\x5a\x40\x2d\x83\x72\x14\x5d\x3a\x69\x20\x9e\xee\xc2\xb3\xd2\x2e\xf1\x01\x09\xe7\xf3\x7c\x52\x87\x51\xeb\xb4\x66\x1d\x46\xac\xcb\xb4\xb7\x26\x4f\xac\x3b\x8d\x59\x4b\x9d\x5f\x41\x3a\xfc\x5b\x97\x87\x7b\xb7\x2b\x07\xa1\x02\x1d\xe0\x07\xe5\xae\x32\x84\x25\xc5\xb2\xb4\x04\xb1\x77\x6d\x82\xa8\xbe\x6b\xcb\x56\x52\x57\x87\xe9\xed\xca\x53\xef\xae\x71\x40\x63\xba\x06\x96\xb0\x6b\xc0\xe9\x75\x9d\xa9\x5f\x9c\xfe\xe5\xd3\x53\xbf\x78\x7a\xd2\xaf\x67\x18\x3c\x51\x37\x69\x9e\xba\x65\xce\xd6\x5e\x6f\xdb\x4d\x31\x1a\x3b\xf1\x53\x70\x01\xba\xec\x56\x30\x53\xf8\xbe\x6e\xde\x14\x7d\x5a\x47\xbd\x31\x31\x3b\xe3\xbc\xed\xef\x4f\x52\x7f\x65\x5a\x04\x3b\xad\x97\xf7\xe4\xae\x13\x59\xf1\x58\xb1\x17\xe2\xc8\x5e\x78\x34\xd6\xe1\xd3\x40\x4f\x10\x28\x4f\x77\xad\x20\x33\x75\x07\x9a\xef\x5e\x20\x12\x00\xf6\xee\xf0\xd2\xa9\x7b\xdb\x41\x9e\xd4\x1d\x9d\x7b\x5f\x6f\x95\xa0\x12\xf2\x00\xf7\xdf\xc3\xb0\x8d\xed\x06\xf8\x4c\x81\x10\xfe\xb9\xd8\x0e\xad\x81\x3c\xfd\x86\x7a\xbe\xa7\x61\x3d\x24\x73\xb7\xf6\x10\xec\xf8\x1e\xca\x1b\x16\x3d\xf4\x60\xb1\x62\xfd\x91\xf2\x2a\x48\x0f\x9d\x60\x11\xfa\x7d\x5f\xdf\xa6\xd0\xce\x1e\x56\xa1\xed\x3d\xec\x2d\xf1\x30\x56\x35\xae\x4c\xd8\x97\x02\x09\xfb\x03\x85\x91\xa9\x48\x79\xd2\xd4\xc3\xf7\x45\x4e\x7e\x60\x35\xc3\x79\x4c\xdc\xc3\x69\x16\x7a\x78\x75\x36\x76\x3f\x40\xfb\x3b\x91\x40\x24\x89\x41\xfa\xfc\x57\x6d\xed\xa0\x3c\xb5\xed\x6b\x43\x7c\xdd\xd7\xbe\xc3\x28\xf5\x85\x45\x5d\xa5\xa7\x17\xf2\xf7\x55\x69\x72\x3b\x61\x44\x5f\x1d\x2a\xb6\x10\xd4\xf5\x15\xef\x17\xb4\xbe\xde\x19\xac\xe0\x8e\xef\x34\x5b\x7d\x0d\x54\x9f\xa9\xaf\xbf\x3f\x48\xfa\x09\xa9\xb6\xa7\xff\x96\xf0\x12\xcd\x7f\x4b\xda\x5c\x15\x69\x60\x37\xfe\xb7\x74\x70\x6d\xfe\x5b\x40\xb0\x70\x3f\x20\x7f\xe9\xbf\x85\x29\x85\x6c\xb0\x1c\x21\x39\xc3\x67\x31\xf6\xe5\x77\x97\x90\x5d\x02\xd4\x3c\x05\x80\x0b\x03\xe2\x77\x91\x42\x80\xbc\x03\xd8\x34\x04\xc3\x0f\x69\x80\xc1\xaf\x2d\x0a\xe9\xb6\xa7\xc0\xb2\xf1\x3b\x42\xbc\x67\x09\x21\xb0\x1c\x21\x77\x0a\xf9\xf3\x48\xef\x2d\x14\x7e\x69\x44\x9c\x83\xce\x15\x48\x38\xf4\xfd\x12\x1c\xca\xef\xb1\xa1\x59\x61\x31\x43\x33\xd4\x3f\x34\x7b\xb0\x90\x5f\x46\x42\xb9\x6e\xa1\x07\x9d\x50\x28\x83\x9f\xd0\x03\x7b\x3e\xf4\x34\xb2\x3d\x43\x51\x76\x52\x69\x43\x7f\xde\xaa\x45\x7e\x41\xb9\x37\x42\x0b\xc2\x77\xde\x5d\x08\x25\x46\x0b\xfd\x07\x60\x42\x89\x2c\x42\xe9\x91\x43\xdb\xce\xcc\xa6\x77\xa2\x65\x0a\xa5\x95\x86\xa6\x1a\x0a\x3a\xd0\x51\xe8\xbb\x2b\x43\x79\x7b\x27\xf4\xbd\x70\x14\x3a\xf2\x62\xa2\x8c\x52\x43\x79\x55\x24\x74\xf8\x0a\x56\x1f\xdd\x1b\x07\x34\x56\x41\xc1\x7c\x9b\xcd\x78\xb9\xce\x15\xe8\x6a\xb5\x77\x66\xdf\x57\x7c\x5f\xe3\x60\x78\x36\x15\xd7\x33\xaf\x9a\xc2\x36\xfc\x36\x54\xc3\x26\xa1\x91\xe7\x46\x79\x3f\xea\x87\x1d\xe8\x9f\x2e\x17\x2e\x61\x4f\x3c\x9e\x0f\x73\xbc\xf3\x7e\x0d\xbf\xf1\x87\x11\x3f\x04\x4f\x0b\x83\x5f\x78\x02\x38\x3b\xf8\xb5\x32\x7c\x73\xd2\xc5\x17\x46\x6d\xe1\x95\x07\x39\xdc\x2c\xe1\xfe\x31\x3e\xd7\x14\xd0\xe2\x70\x86\xc7\xc1\x53\xea\xf7\x02\x4e\xc0\xdb\xa4\x20\xe0\x8e\xb5\x51\xe6\x08\x84\x63\x9d\x29\x00\x77\x62\x35\xfc\x6e\x79\x52\x2c\xc0\x87\x21\x3b\x7e\xf0\x2d\x43\x76\x46\xdf\x43\x0e\xbc\x18\x0a\x0b\x8b\x0b\xc2\x94\x21\xe5\xa5\x13\x04\xfd\x0c\xe0\x9d\xf1\x1e\x34\x0f\x44\xa1\x43\xa6\x8d\xe3\x41\xea\xe3\xb2\x34\x04\x2a\x35\x64\x11\x85\x0e\x38\x8e\x21\x4f\x1a\x19\x01\xf5\x80\x77\x18\x19\xca\x3d\xf2\x0b\x97\x47\xd6\x86\xb7\x4b\x2b\x13\x58\xc8\x91\x8d\xe7\xac\x23\xdb\x18\x1e\x23\x8d\xec\xc1\x0f\xe7\x23\xfb\x9a\x69\xe4\x90\x0e\x8a\x58\x73\xe4\xb0\xce\xbc\xb5\xa5\xa1\x82\x1f\x80\xfd\x78\xb7\xc5\xc0\xca\x0f\xcd\xb0\xc1\x43\x33\x74\x19\xb1\x38\x99\x69\x7e\x6d\xc4\x00\x26\x1b\xaa\x9f\x34\xf4\xa4\x8f\x1b\xfc\xa2\x81\xa4\xa4\x01\x0d\x96\x48\x43\x19\xf3\x0e\x86\x5d\xb0\xa7\xef\x18\x35\x4c\x07\x12\x7e\x2a\x1b\x3a\xc6\xcb\x9b\x01\xd6\xd0\xb9\x7a\x1a\xb0\xb7\x69\x5c\x8c\x05\xc6\x25\xc7\x04\xe5\x21\xce\xb8\x28\x8c\x0b\x03\xb8\xd8\xdb\xa5\x61\xc7\x91\xc6\xc5\xd3\xe3\x71\x19\x6b\x03\xd3\x8c\xcb\x3a\x08\xb4\x68\x5c\x08\xcb\xc6\xe5\xc8\x76\x47\x15\x47\x21\xb6\xcb\xb8\x7c\xf1\xb3\xcc\xb8\xb0\xe7\xc6\x15\x56\x51\x06\x8d\x18\xd7\x3a\xa0\xba\xe3\x7a\x12\x9c\x0d\xb4\x76\xc0\xb4\x11\xa3\x0c\x53\x2c\x1a\xd5\x9a\xdf\x0a\x87\x15\x8a\x03\xf1\xc2\x30\xd8\xad\x61\x85\xfd\x5b\x35\xd8\x83\x61\xaf\x2a\xf0\xeb\xf6\x78\xb9\x05\x26\x6b\x44\x33\x03\xfa\x0f\xb5\xb1\xdf\x34\xe0\x3b\xc6\x87\xaf\x3c\x1b\x48\xe3\x63\xf8\x61\xd6\x30\xe6\xe3\x63\x18\xfd\x07\xb6\x7e\x20\xb8\x1f\x45\x6a\x1a\x45\xb5\x83\xd2\x72\x0c\x7a\xd4\xc1\x93\xcd\xf1\x46\xbc\xa3\x18\x6a\x39\x60\xda\x80\xdb\x1f\x14\x2c\xcf\xb1\x47\x85\x15\x1c\x55\xc0\xb8\x22\x22\x19\xd5\x3f\xa4\x3e\xaf\x34\x1a\x8c\xf5\x68\x88\x61\x46\x83\x4e\x35\xca\x1e\xb0\x77\x38\xde\x3d\x67\xf4\xea\xfc\x92\x3d\x28\x73\xdf\x25\x0d\xc7\xaa\xd0\xd3\x0f\x2f\xbb\xb1\x4e\xb1\x1d\xf4\xbd\x30\x32\x78\x5e\x33\xbc\x2a\x00\xcd\x40\xc8\x3c\x9c\xf9\x08\xd5\x06\xd7\xc9\x17\x78\x62\x13\x0f\x87\x9a\xbc\x56\x6c\xf8\xc2\xd0\x3a\x0c\xe0\xa0\xff\x1e\x00\x67\xe8\xbf\xcb\xdd\xd2\xe8\x2a\x1f\xd0\x77\x4c\x9d\xca\xdb\xa9\x3b\xfc\x24\x3c\xfa\xa5\x6c\x44\x49\x75\x5e\x44\x18\xdd\x3e\x7c\x41\x73\x43\xc8\x38\x7a\x21\x05\xbc\xa6\xd5\x84\x6a\x77\x8e\x90\x36\x77\x74\x48\xb2\x07\xf6\x6e\xe7\xe5\xa6\xd1\x69\xe3\x46\x7f\xd2\x80\x7f\x54\x24\xbc\xef\x84\xb0\x8c\x37\xd5\xc6\x1b\x4f\x8c\x29\xbb\xad\x8a\x14\xd2\x9c\xb4\x04\x53\x0c\x3b\x79\xc2\xef\x8d\x49\xd3\x31\xb9\x2c\xb4\x68\x63\xa2\xa3\xc9\x99\x4d\x25\x2b\x05\x03\x2c\xfd\xd4\x50\x4f\xc0\x65\x28\xa4\xba\x4c\x8e\x64\x72\x3d\xa6\x57\x81\x32\x4d\x0a\x7a\xd2\x80\xf0\x18\x75\x4c\xaa\xff\x84\x1f\x3d\xf1\x1a\x8a\xdd\x3f\x83\xb2\x98\xc1\x35\x99\xb1\x78\xba\x3e\xe6\xe2\x0d\xd8\x31\x17\xc7\xfc\x9e\x83\x8e\xf9\x80\xae\x37\xc0\x19\x6b\x03\x5c\x1d\x6b\x83\x31\x1d\xeb\xbd\x3c\x3b\x10\x5f\x8e\xc5\x93\xdd\xb1\x18\xc0\x8c\x75\x0a\xe9\x89\x10\x8e\x07\x48\x63\xf1\x18\x7a\x2c\x54\x6a\x0d\xcd\xdb\xc0\x70\x56\x67\x76\x47\x40\x3a\x56\x0f\xda\x41\x20\xdb\xb1\x82\xdf\xc7\xc6\x42\xa0\x3f\x56\x00\x8c\xf1\xe1\x35\xfc\x63\xc5\x57\xd1\xe6\xbd\x45\x39\xd6\x60\x9c\x35\xee\x7f\x96\xe5\xa6\xa4\x6f\x21\x89\x9a\xc6\x0d\xac\x3e\x6e\x0a\xe1\xa6\x59\xb9\xb1\x73\x6e\xca\xf2\x26\x24\x1e\x37\xf0\xc1\x78\xea\x06\x29\x3e\xb5\x4f\xaf\x69\x3c\x01\xed\x7c\xb8\x24\xef\x0a\x4f\xe1\x0d\xa2\x29\x67\xe2\xbd\x81\x29\xb4\x13\x53\xca\x27\x4d\x69\x20\x1d\xc5\xfc\x14\x34\x65\x20\x63\x4c\xe4\xcc\xe9\x9e\xa6\xfc\x5a\x9a\xbc\xbd\x38\x55\x6a\x9a\xd0\x5e\x04\x7b\x53\x1b\x02\x89\xa9\xad\xd9\x40\x82\xe7\x40\x85\x81\xa7\xdf\x99\xe6\x45\xf6\x97\xe0\x11\xb2\x9a\x17\xda\x5d\x8a\x15\x9f\xd4\xfc\x79\x29\x1e\x31\xad\x79\x81\xcd\xe5\xbc\xd1\x35\xaf\x50\x94\xf2\x6b\xfb\xbc\x10\xab\xcf\x6b\xd5\x0d\x94\xc6\x65\xbe\x77\x5c\x26\x8c\xcb\xb4\x93\x39\x05\xef\x44\x32\xd3\xd0\x9b\xb5\x27\x4d\xeb\x09\xc8\x62\x4f\xf3\x3d\x7c\x9d\x06\x63\x3f\xe9\xd4\xa7\x6f\x80\x83\x69\xfa\x2e\x0f\xe8\x5e\xd0\xd8\x51\x7e\x2a\xc1\xdc\x74\x2b\xe8\x87\xd7\xfe\xa0\xbe\x13\xd5\xeb\x7b\x09\x91\x6a\x3c\xbd\x9d\x8b\x09\x4d\x1c\x95\x7a\xd2\x64\x4d\xef\xf8\x59\x06\xed\xec\x15\xde\x6e\x7a\x34\xd9\xc1\x26\x26\x83\xff\xe9\x63\xa4\xe9\x53\xd0\x70\x85\x71\x64\x84\x38\x93\xa1\xc3\x44\x00\x3a\xfd\x49\x93\x80\x75\x32\x5a\x9c\x21\x08\xbd\x91\x9e\x6f\x62\x0d\xb4\x0d\x68\xf5\x84\xd7\x9d\xbc\x39\x34\x81\x47\x4b\xe2\xbd\xd0\x17\x5c\x4d\xca\x16\xf8\x2e\x4d\x1e\x8d\x4d\x5e\x3d\x99\xbc\x0a\x39\xc3\x4e\x8a\x33\xac\x82\x80\x8d\xf7\x0b\x6d\xdf\x9b\x14\x33\x16\xab\x2d\x3e\x16\x14\xac\x8a\x78\x70\x06\xb0\xd1\x0c\x98\xc4\x89\x15\x5e\x60\xba\xde\x80\xe9\xdf\x26\x9d\xab\x09\x08\x42\xe1\xb9\xe2\x83\xd5\x07\xd0\x9b\x2b\xb8\x2c\xb7\xc2\x14\xcf\x5b\xdb\x7c\xd2\xbc\x61\x16\xe7\x8d\x89\xdd\x94\xca\xed\x69\x3e\xd0\xd6\xa7\x33\xcc\x5c\x67\x79\xd2\xaa\x5b\x68\x29\x92\xd6\x7b\xd5\x60\xb5\xf7\x36\xf0\x6a\x99\x6f\xef\xc5\x94\x57\x6d\x56\xdb\x3d\xad\xc6\x2b\xea\xab\xf1\x13\xe9\x6a\xef\x27\xa6\xd5\x8c\x98\x7a\x35\x5e\xcd\x5e\xcd\x26\xc8\x57\x11\x8c\xac\xf6\x69\x58\x85\xd5\x78\xc6\xba\xda\xb4\x92\x56\x5b\xbc\xa7\xb8\xda\x57\xf1\xda\x79\x9a\xb9\xfa\xc9\x05\x5a\x9d\x9f\x83\x56\xf7\x96\x16\x43\xe9\xd5\x61\x45\x56\x6c\xd2\x12\x0d\xc5\x0b\xbc\x80\xe0\x79\xe5\x7c\x0d\x3d\x56\x41\xc2\x0b\x12\xff\x98\xcf\xf7\x3f\x03\x5f\xc9\xd8\x6e\x5f\xc9\x6b\xd5\xf4\x15\xe8\xdc\x57\xe0\xc7\xbe\xef\x3d\xf8\xaf\x40\x74\x5f\x69\xf8\xd9\xb8\xd2\x57\xba\x47\xfa\xca\x7b\x15\xeb\x0b\x85\xff\xf2\x83\xfa\x57\x2f\x83\x68\xbe\x10\x36\x5e\xdb\x8e\x8a\xbc\x14\x89\xdc\x06\xd6\x1a\x1b\x88\x1d\x0f\x12\x02\xa5\x2f\x82\xdb\xaf\x8e\xa1\x25\x7d\x75\x6a\xa0\x2f\xa3\xcc\xbf\xb6\xf1\x0b\xe2\xd7\xf2\xdb\x9b\x65\xda\x75\x04\x88\x9e\x88\xda\xbf\x56\x0a\xa6\xfb\xb5\x36\xdf\xd4\x8b\x81\x41\x10\x77\x7f\x2d\xd8\x6e\x08\x88\x81\xd5\x78\xf3\x27\xe9\x17\x33\xe5\x29\xf7\x97\x17\x25\x79\xf9\xfb\xeb\x25\x4b\x73\xa4\xab\x22\x6f\x82\x3c\x60\x7f\xff\x23\xde\xd2\x2d\x36\xd3\x0d\x7b\x07\x7b\x0b\xd2\x16\x32\x1a\x48\x1c\xd0\x15\x5a\xdd\x5b\x02\xc1\x74\xba\xb1\x6d\x6e\x19\x1d\x64\xa2\x10\xf8\xe8\x06\x3e\x86\x33\xb9\xdf\xef\x8a\xb7\x0a\x96\x96\x96\xfa\x46\x6c\x55\x90\xd0\x68\xdc\xba\xa5\x5b\xdf\x70\xf8\x56\xfd\x60\xa7\xdd\x6a\x01\x5a\xf8\xcd\xeb\x86\x91\xbc\x75\xa6\x9b\x5f\xaf\x6e\xd8\xc8\xfb\xd2\x97\x82\x13\x2c\xe5\x4d\x13\x79\x03\x4a\xde\x97\x31\x02\xbf\x61\xef\x6e\xdb\xd1\xbf\x1d\x78\x2c\x3b\x48\x49\xd8\x25\xb7\x35\xc0\xd6\x1b\x08\x94\xae\xe2\xb6\xf6\x01\x69\x6c\xca\x4b\x31\x37\xc2\xac\xdb\x06\xc2\xd8\x1b\xd6\xe7\x86\xae\xdc\xff\xee\x28\xdc\x5e\x8e\x74\x23\xae\x49\xb7\x73\xc7\xdc\xee\x3b\x48\x49\xf4\x37\x3c\xdc\xbc\x3d\x0a\x1f\xe3\x01\xc5\x60\x60\x6f\xee\xd0\xfc\x01\xe5\x25\xde\x9b\x86\xec\xe6\xcd\x8d\x9b\x0e\xfc\x81\x49\x7b\x20\xaf\x47\xe9\xf7\x1e\x5f\xf8\xa1\x88\x40\xea\x4f\xb7\x90\xf4\xa7\xe1\x89\x47\x6b\x7f\xee\xe9\xff\x00\x00\x00\xff\xff\x96\xd2\xdb\xc1\x3c\x33\x00\x00")
-
-func keysWordlistEnglishTxtBytes() ([]byte, error) {
- return bindataRead(
- _keysWordlistEnglishTxt,
- "keys/wordlist/english.txt",
- )
-}
-
-func keysWordlistEnglishTxt() (*asset, error) {
- bytes, err := keysWordlistEnglishTxtBytes()
- if err != nil {
- return nil, err
- }
-
- info := bindataFileInfo{name: "keys/wordlist/english.txt", size: 13116, mode: os.FileMode(420), modTime: time.Unix(1497960590, 0)}
- a := &asset{bytes: bytes, info: info}
- return a, nil
-}
-
-var _keysWordlistJapaneseTxt = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x5c\x5c\xff\x72\xe2\xb8\xd2\xfd\x9f\xa7\x5e\xbc\x5c\x2f\x01\x3c\x0e\x71\x1c\xc7\x61\x58\x87\x8a\x2f\x43\x60\x80\x0c\x59\xb8\x93\x8f\x2c\x3c\x8c\x5f\xe4\x2b\xf5\xe9\x3e\xea\x99\xaa\x54\xea\x1c\x59\xd6\xcf\x56\x77\xab\x25\xd3\xf5\x93\xae\x3f\xe8\xfa\x45\xd7\xcf\xbb\x7e\xd5\x25\x45\xcf\x92\xca\xae\xdf\x92\x3c\x03\x8d\xba\xfe\xdf\x5d\x72\x03\x32\xee\xfa\x8b\x2e\xf9\x93\xef\x64\x5d\x32\x06\x9a\x76\xfd\x49\xd7\x6f\x8c\x58\x72\x11\x92\x93\x09\x79\xd9\xf5\x07\x44\x07\xa0\x4a\xfe\xaf\x40\x1e\xbb\x24\xef\xfa\x29\xc8\x53\xa8\xd1\x5e\x7d\xea\xfa\x19\xd0\xbc\xeb\x9f\x80\x9a\xae\x3f\x64\x86\x26\xfc\x25\x7d\xc7\x93\x51\xd7\xbf\x74\xfd\x21\xb9\x3e\x69\xd9\x8a\x56\xfa\xa4\xd5\xbd\xc8\x70\xfc\xa7\xeb\xe7\x7c\x78\xe9\x92\x91\x11\x57\xf4\xb2\xeb\xaf\x89\xf6\x92\x4d\x9f\x1c\x88\x4e\x1c\xb5\x13\xd3\x8e\x7e\x2c\x2e\x6c\xc5\xa5\xeb\xbf\x1a\x4a\x06\xd2\xa4\x9a\x5c\xeb\xbf\x76\x49\xd2\xf5\x77\x42\x42\x4b\x46\x5d\x1f\xe5\x84\x17\x58\x7f\x92\x76\xc9\x1f\x40\x37\x32\x8b\xb7\x5d\xff\x42\x5e\x11\xd5\x5d\xff\x91\xc4\x8f\x5a\x72\x23\x65\x44\x92\x5b\x5b\x42\x8d\x93\xae\xbf\xb2\xe1\x0a\x4f\x66\xcc\x99\x87\xa1\x30\x52\x58\xcf\x12\x99\x7f\x47\x0a\xa2\xaf\x26\x44\x81\x2c\x7d\x9e\xb5\x27\x3a\x00\x03\x88\x24\xda\x32\x08\x52\x29\x6f\x0f\x58\x3c\x50\x0e\x94\x89\xd8\x0e\x48\xd6\x2c\x24\xe3\x28\x0e\x28\xbd\x03\x59\x08\x8f\x44\x27\x96\x3d\xed\xfa\x6f\x98\x69\x21\x96\x5c\x60\x08\x74\x0d\x11\xb5\x3d\x5b\x44\x17\x11\xea\x81\x71\x7b\xaf\x82\x04\x0f\x44\xca\xff\xc3\x42\x1e\xbb\xe4\x2f\x4f\x72\x36\xeb\xa9\xeb\x5f\x0d\x25\x13\xa0\x19\x0b\x9e\x05\xe1\xef\xbf\x93\x8c\xfd\x13\xad\xe8\x2b\x2b\x9f\x77\xfd\xb4\x4b\x32\x56\x34\x97\x01\x8b\xcd\x7c\xf6\x48\x3b\xd5\x48\xc5\x37\x24\x57\x43\x41\x16\x12\x90\x85\x8c\x75\x4a\xf2\x48\xf4\x4a\xf4\x46\x74\x32\x94\x8c\xfc\x10\xb4\x10\xe6\x41\x5c\x83\xd6\xec\x17\xdf\xe3\x17\x74\x83\xa4\xf1\xd9\x16\x44\x4b\xff\xc2\xbf\x7c\x61\xd9\xf5\x1f\x0c\xd9\x7b\xaf\x7c\xba\x82\x70\x0e\x28\x7f\x40\xda\xac\x6d\x97\xfc\x41\x21\xda\xb1\xb2\x1d\xa7\x6a\xcf\xf9\x7f\x73\x69\x56\xcd\x3b\x27\xe4\xc0\xb4\x23\x87\xf9\x27\xd3\xce\x6c\xce\xd5\xd2\x82\xbc\xa6\x50\x8f\x20\x8d\x89\x42\x92\x58\x8b\x12\x91\x7e\xad\x36\x10\xac\x92\x64\x28\xfa\xb3\x20\x41\x7d\xa2\x19\x88\x6a\x96\x3d\x12\x6d\xb1\x30\x12\x85\x32\xe1\x1a\x0b\xda\x8b\xeb\x27\x89\x55\x66\xa2\x87\x8b\xae\xff\x8f\x0d\x43\x50\x08\x03\xa2\x94\x28\xb6\x27\x37\xb9\x08\x02\x9f\xb2\xa8\xa2\xeb\xdf\xd9\xca\xef\x33\xa9\x64\xb9\x85\x08\x48\x6c\x5b\x21\x3d\x0b\x24\x95\xf5\x90\x19\x92\x02\x53\x91\xce\x07\x20\xed\x46\x2a\x4b\xe5\x44\xf4\xc1\xac\x59\x97\xe4\x40\xb9\xe9\xcf\x35\xf9\x04\xe3\x9e\x8a\x5a\x68\xa4\x7d\x39\xdf\x9c\x8a\x0c\x4f\x49\x56\xee\x49\x18\xb1\x96\x44\x93\xef\xa9\xe5\x41\xb4\xde\x02\xc3\x93\x4a\x8f\xbf\x00\x55\x22\x88\xa9\x91\x30\xd8\x13\xac\xc5\x54\xa6\x6f\x40\xf4\x85\xe8\x96\xb3\x2c\xdc\xf4\x7b\x2a\xab\x49\x1b\xb3\xa0\x16\x27\x9f\x70\x00\x16\x1c\xc9\x05\x17\x6a\x2a\x0b\x6a\x0c\xa9\x4b\xa5\xc7\x39\x55\x48\xaa\x2b\xd2\x8d\x7c\x4b\xf4\xca\x6e\xad\xd9\xca\x35\x74\x05\xd0\x13\x47\x60\xcd\x97\xb6\x44\x3b\xd6\x7f\xea\xfa\x77\x44\xf7\x30\xed\xa9\xcc\xc5\xc4\x72\xc7\xbe\xca\xd2\x01\x12\x1b\x69\x64\x68\x95\x85\x31\x9a\x88\xd4\xd4\xe4\xba\x04\x40\xd6\xd6\x37\x51\x78\x56\x77\x20\x99\x49\x43\x32\xa6\x57\x93\xca\x4a\xa9\x1c\x49\x52\x1b\x46\xd7\xbe\x0c\x9a\x26\x95\xb1\xcf\x88\x4a\xa0\x82\xf6\x05\x64\x61\x43\x07\x3b\xe9\x88\xea\xae\xa1\xc8\xe9\x10\x4f\x40\x26\x44\x19\x97\x0a\xf8\x3d\x91\x6a\x55\x90\x93\x7b\xdb\x96\x13\x48\x0e\x34\xc2\xa4\x0f\x65\xbc\x22\xd2\xa7\x99\x4c\xbc\x16\x17\xdd\x82\xa1\x88\xeb\x9f\xcc\x56\x77\xfd\x25\x50\x2b\xae\x85\x56\xb9\xeb\xfa\xb7\x40\x67\x9d\x4c\x19\x15\xe1\x96\x87\x69\x61\x4e\x1f\x89\x76\x40\x37\x56\x79\x40\x27\x20\xb5\x50\x50\x4b\x1c\x9d\x40\xc6\xcc\x5d\x40\x18\x87\xaa\x75\xac\x8a\xc2\xfc\xc0\x94\xfc\x2b\x56\x0d\xc8\xdc\x7a\xa4\xf3\xf3\x97\xcf\xb9\x42\xce\x91\x8c\xeb\x98\x4b\x7e\x64\x5e\x42\x4d\xa2\x82\x32\x32\x0b\x98\x83\xa4\x6c\xee\xc8\x14\xc1\x85\xe4\x91\x68\xc6\x7a\x52\x8e\x3e\xc8\xd1\x17\xf5\xe1\x9e\xd8\xcc\x8e\xb8\x48\x47\x74\x94\x46\x34\xe3\x40\xaf\x9c\x73\xe1\x09\xf3\x84\x42\xe6\x20\x63\x0c\x34\xc9\x13\xd0\x04\x2e\xa8\xa4\x05\x15\xa9\x19\xbe\x50\x8d\x8d\xe8\x7a\x8d\x44\x5c\x62\x0f\x73\xef\x0d\x09\x57\xaf\x73\x4d\xce\xd7\x6c\x45\x8d\xfc\xb0\x16\xbe\x92\x82\x19\x4a\xdf\xe3\x92\xeb\x5a\x88\xe9\x8b\x11\x66\x04\xeb\x1a\x24\xbe\xf3\x08\x49\x01\x2a\x39\x3d\x22\xde\xf6\xc2\x5c\xc4\x2f\x27\x89\x8d\x6d\x68\x7b\x40\x34\xcf\x33\x9c\x7d\x90\x85\x97\x81\x17\x18\xe5\x91\xac\x14\x1d\xbf\x6f\x10\x27\x90\x95\xd4\xad\x2b\x00\x7c\xed\x25\xea\x95\xaf\xbd\x8a\xc2\x19\x73\x84\xde\x7c\xfb\x2f\xb0\xf5\x42\x92\xbe\xd4\xb1\xb2\xe1\x4b\xb0\x0d\xfc\x46\x12\x93\x29\x6e\x81\x84\x0d\x21\xc8\xc0\x44\x32\x19\x88\xe6\x7b\xef\x99\xc0\x7c\x5a\xf5\xb2\xec\xb1\xb7\x1c\x49\xc3\x34\xb9\xa0\x3a\x01\x99\xb2\x06\x2c\xc6\x3f\x49\x66\xd6\x78\x29\xc7\x93\x68\xa8\x46\xa6\x1f\xb5\x98\x31\x76\x70\x40\xaa\x1f\x27\xd0\x8f\x44\xea\xde\x4f\xbc\x87\x3f\xf6\xbb\xe2\xb1\x2e\x5a\x69\x0b\x48\xed\x1d\xab\xb1\x77\xb8\x41\xfe\x86\xf1\x23\x6f\x7d\xb1\x4b\x9f\x73\xe5\x9f\xe8\x02\x9e\xa8\x73\x28\x8d\x1c\x7b\xff\x70\xec\xf5\xf4\xc4\xfb\x74\x63\x2a\xed\x31\xc5\x77\xcc\xa5\x3c\xfe\x2d\x79\xc2\x96\x4f\xb0\x39\x1c\xd3\xb5\x18\xcb\x62\xbc\x27\x5a\x31\xeb\x03\x5e\x9f\xa0\x7b\x48\x6b\x58\x7b\x03\xf3\x39\xf1\x8a\x71\x22\x02\x9d\x71\x7a\xc0\x0b\x4f\x4a\x8e\xfe\x8b\xf7\xef\xc6\x22\xd6\x0f\x62\x1f\xb5\x7d\x3b\xbe\xb6\x67\x93\x4e\x58\x45\x63\x3f\x40\x67\xb6\xfe\xc2\xb4\x8b\x48\x22\x46\x3d\x2c\xfb\x09\x37\x92\x63\x11\x58\xf4\x41\x06\x16\xd2\x3b\x76\x03\x9b\x8c\x89\x32\x2b\x31\xb4\x2b\x37\x24\x1b\xa5\x09\x4c\x0c\xd2\x0a\x27\x81\xce\xb0\x8f\xbd\x54\x8f\xcd\xa4\xc4\x27\x0d\xdb\x54\xd8\x68\x06\xa4\x1b\x8b\x0c\x01\x1a\xa2\x16\x28\x78\xe1\x3d\xd1\xb2\x03\xbc\x9e\x49\x2f\x06\x86\x2c\x6d\xc8\x52\x54\xdf\x03\xe5\x44\x0b\x43\xf6\xc6\x98\xa5\x8c\x99\xef\x97\x2e\x64\xf2\xb7\x04\xca\xa5\xa1\x23\x23\x61\xfc\xee\x40\xa6\xba\x7e\xad\xb4\x82\xf5\x17\xbe\x59\x05\x2b\x29\x99\xb5\xf4\x69\x17\x43\xa1\xec\x2f\xe8\xf3\xa3\x97\xe7\x2f\xdc\x6a\xe3\x49\xe3\x17\x38\x92\x36\x7e\xa3\xf8\xc5\x36\xe4\xad\xef\x52\xcd\xe6\xc5\x26\xeb\xc6\x3a\xa3\xf9\xcd\x38\x75\x99\xac\x87\xdc\x90\x0d\x5e\xe3\xbb\x16\x97\x44\x26\x95\x0d\xd9\xa4\x17\xec\x89\xf9\xa4\x65\x45\x6d\xd7\xdf\x02\x2d\xd9\x8c\x57\x16\xf2\xca\x2a\xd7\x7c\xba\x86\x82\x03\xd2\x66\x7c\x17\x6f\xb9\x02\xd9\xb2\x75\x3b\x16\xb4\x93\x31\x6b\x40\xf6\x2c\xf5\x9d\x46\x25\xe3\xde\x35\xa3\x86\xca\xe8\x39\x66\xb2\xb2\xb4\xac\x33\xd3\x2e\xec\xfa\xd5\xc6\x2b\xf9\x43\xe3\x7a\xb1\x60\xb3\xc0\x08\xce\x3c\x8b\x25\xaa\xc8\x17\x3d\x1f\xb6\xc9\xe8\x50\x66\x62\x70\x30\xdf\xa2\x59\x64\x56\xf5\xc9\xd0\x1a\x23\x03\xee\xa3\x0d\x19\x97\x74\x46\x7b\x9d\x49\x06\xb4\xd9\x36\xbb\x40\xda\xe6\x8c\x15\x65\xcc\x97\xb3\xdd\x5f\x10\xf1\xc2\x02\xcc\xcc\xc7\xd4\x98\x12\x78\xf0\x6a\x8c\x38\xfd\x72\xcb\xb5\x9c\x23\xcc\x03\x94\x72\x9f\x0c\x92\x11\xdd\xfa\x64\x5d\x40\xb7\xe6\x0f\x0e\xf8\x64\xee\x9f\x34\xd0\x4c\xb9\x77\x0e\x41\x3e\x81\x62\x5d\x71\xbb\x90\x63\x1b\x8e\x42\x0a\xa6\x95\xac\xa5\x64\xb3\x4a\x46\xc9\x84\xc8\x90\xe4\xe6\xfa\x5f\x49\x62\xc1\xb5\x88\x5b\x66\x24\x8c\xbd\x8e\x87\xec\x1d\x44\x5f\xe4\xb4\xf4\xb7\xb6\x80\x97\x7c\xe7\xd9\xd7\xd3\x04\x29\x35\x67\x30\x17\x47\xaa\x60\xbd\x0b\xdf\xd0\x96\x32\x7e\x2b\x2b\xae\xc6\x8a\x93\x27\x61\x8a\x6f\x7b\x66\xea\x52\x9a\xe7\x9c\x6b\x2c\x97\xbd\xa9\xa6\x6d\xf1\x1f\x64\xc7\x9e\x1d\x89\xae\x7e\x73\x0d\xde\x30\x44\x1a\x45\x27\x87\x10\x63\x80\x7a\xa6\x30\x6b\xa2\x0f\x66\x1b\x43\xf1\xe5\xae\xab\x66\x87\x72\xd8\x47\x4c\xcd\xad\xca\x9f\x8e\x5d\x8c\x97\xe4\xe4\x8d\xcf\x19\xd4\xf6\x54\xc4\x70\x0d\x34\xa0\x9e\x9f\x7a\xbd\x09\x12\x91\x7a\x45\x77\x2e\x9e\xd9\xf2\xa1\xd6\x70\x67\xe1\xb2\x54\xb2\xf0\xe5\xb0\xb2\x32\x12\x45\xf0\x62\x6b\x23\xc9\x88\x6b\xfe\x0e\x26\x87\x48\x05\x13\xe4\xd9\x93\x85\x27\x2b\xb6\x30\xa8\x34\x43\xa6\x34\xee\x28\xd6\x77\x76\x16\x12\xb7\x1e\x77\xc1\xe9\x90\x2e\x4c\x29\x40\x92\x66\x7d\xa8\xd8\x81\x2a\x68\x56\xd9\xf0\x4c\xbd\x98\xdf\x31\xb2\x86\x68\xd1\x1b\x90\x9c\x9e\x04\xd9\xfb\x1f\xf9\x0d\x3b\xdd\xd2\x9e\x4f\x79\x46\x31\x55\x43\x61\xd5\xbd\x30\x46\x84\x27\xaa\x58\xa6\x16\x29\x8d\xd9\x96\xbe\x80\x0b\xc7\xa2\xf5\xfa\x07\x7c\xe2\x72\x9a\x82\xbb\xa3\xdc\x4b\x34\x2b\xac\xf0\xba\xe7\x43\x5b\x53\x31\x2f\x77\x44\x35\xd1\x15\xe8\x3b\x87\x6d\xcb\x4e\x6d\xd9\xf4\x3d\x25\xe4\xc0\xb4\x13\x7d\x8d\x3b\x31\x27\x5a\xbb\x1e\x01\x4c\x65\x11\x8d\xad\xf6\x60\x47\x2a\x43\x9a\xc1\x04\x66\x4a\x1d\x3f\x95\x45\x32\x35\x21\x73\xeb\x64\xca\x63\x8a\xa9\x86\x08\xb4\x91\x81\x8c\x88\x20\x75\x01\x65\x4c\xbb\xb3\x16\x3b\x9f\x6e\x6a\x61\xca\x9c\x24\xc6\x10\xc0\x6b\x93\x0c\xe7\xf0\x4d\x75\xe7\xe2\x5e\x5b\xfa\x56\xad\x7c\xb6\xb5\x7f\xb2\xb1\x79\x0a\xe4\xe4\x1b\x7f\x21\xba\xba\x86\x06\xa3\xca\xb7\x2d\xfa\x02\x12\x7a\x5b\x88\xec\xe5\x78\x5b\xac\x59\xff\x3b\xd1\x3b\x24\xf9\x9e\x1e\x65\xe1\xc3\x14\x85\x86\x59\x1d\x51\xf5\x73\x6f\x51\x55\x1d\x87\x7b\x0b\x8f\xc6\x32\x74\xf8\x0a\x0b\x75\xc4\x27\x8f\x44\x1a\xe3\xbc\xf7\x76\xae\x30\x3b\x97\x93\x34\xfe\x89\xee\x4a\x0b\x0b\x54\xc6\x4a\x96\x3e\xdb\xab\x7f\xb2\xf6\x4f\xf6\xbe\xd2\xb3\x6f\xff\xc5\xf5\x34\x48\x1c\x5b\x90\x8c\x30\x0d\xd1\x9d\x2d\xb8\xf5\xba\xa7\x6c\xdf\x8b\x9f\xda\x5a\x9a\x95\xa5\xbb\xad\xc2\x9b\xd9\x82\xf6\x88\x64\xed\x9f\xec\x59\xf9\x2d\x27\x2e\x8e\xee\x94\x6d\x28\x44\x09\x93\xc8\x62\x28\x10\xfb\x00\xaa\xd8\xf0\x9a\x95\xc5\x81\x56\xb5\x12\x0f\xed\x20\xbf\xcf\x30\x1e\x85\x1f\xf9\xc6\x77\xbd\x61\xa9\xd1\xf1\x2d\x10\x43\x06\x6a\x79\x6e\x06\xf2\xc6\xe2\x5b\xc4\xf1\x0a\x3f\x5d\x4b\x3e\x5d\xc9\x96\xe8\x86\xa4\x22\x7a\x33\x64\x42\xbd\x96\x61\x5e\x83\x6c\xf1\xbf\x67\x23\x72\xe1\xa8\xed\xa0\xb6\x04\x25\x43\xcc\xcd\x9e\xf5\x1d\xa0\x6a\x41\x8e\xec\xc8\x91\x19\x3e\x69\x95\xef\xa5\xd4\x78\xfc\x2b\x07\x19\x6e\xea\x2f\x74\x3b\xf0\xa4\x65\xe3\x2e\x36\x6e\x41\xb3\x7d\x81\xa9\x2d\x18\xef\x2c\xe8\x0b\x17\x54\x73\x82\xb4\x09\x66\xd6\x80\xd0\xab\xe0\x55\xa5\x44\xef\x40\x43\x1b\x4f\xf3\x91\x0b\x31\xb5\x5a\xf5\x24\x7a\x6b\x56\x70\x26\x33\x36\x05\xc9\xa5\xf2\x25\xc9\x84\x6f\x16\xdc\x78\x16\x3e\xca\x5a\x50\x77\x16\xbf\x29\xc5\xc2\x94\x62\xcc\x46\x89\x82\xea\x73\xa5\xad\x3d\x79\xef\xfa\x1b\x92\x7f\xfd\x93\x0b\x1b\x5a\x20\x64\x09\x34\x71\x95\xd8\x96\xfd\x41\xc3\xe6\xd2\xb6\xd2\xdc\x9e\x01\x89\xda\x41\x64\xbb\xf3\xa4\x60\x1e\x75\xda\x4a\x1f\x50\x7f\x30\x07\x28\x56\x12\x03\x53\xa5\x77\x64\x1f\x7e\x3b\x68\x2b\xa1\x84\x80\x34\xda\x04\x32\x81\x79\x45\x72\xcc\x70\x85\x40\x94\x3c\xfc\x2b\x65\x2f\x12\x8b\xcb\x59\x42\x4e\x3b\x5b\xc2\xb5\x04\xd2\xbd\x76\xc9\x75\x58\xfa\x4b\x17\x0f\x5c\xfa\x25\x83\x12\xa5\xf9\x23\xda\xd7\x96\x9a\xff\x81\x2b\x1b\xc9\x13\x96\xfd\x62\x1b\x8b\x9c\xd9\x2a\x16\xf5\xe8\xdf\x9e\xb3\xe9\x2d\xbd\xa6\xd2\x1c\x98\x41\x97\x24\xe0\x4b\x4e\xd4\xca\x27\xaf\xf8\xf6\x8a\x31\xeb\x92\x0a\xa2\xa4\xeb\x52\xd2\x65\xc7\xd6\x45\x9b\x19\xf7\xba\xa5\xc4\xcd\x75\x3c\xce\xcc\x7a\x46\x2c\x0f\x07\xfc\x3a\x21\x57\xff\xd2\x55\xdc\xd1\x89\x90\xb0\x8a\xa7\x3d\x1f\x60\x2e\x65\x69\x0e\xfd\xd9\x4d\xc9\x35\x5a\x72\x3d\x96\x8c\x28\x22\xc2\xf1\xdc\x43\xcc\x4d\x46\x07\x03\x92\xe4\x8c\x1c\x97\x8c\x33\x97\x7e\x0d\x96\x74\x5e\x80\xe2\xb6\xb9\xf4\x5e\x4b\x69\x5e\x0b\x66\xd3\x36\x0b\x7c\x52\xfb\x6c\x33\xeb\xa7\xf8\x2f\x44\x0b\xa2\x0b\xd1\xd5\x90\x39\x1a\x15\x37\xba\x15\x0f\xd2\x2a\xbb\x07\xf4\x82\x65\x5f\xf9\x2d\x93\x84\xe2\xa5\xc1\x15\x3b\x55\xc1\xb2\xf7\x34\x36\x6f\xc5\x8d\x30\xd0\x15\x17\x70\xc5\x1d\xcc\x23\x2d\xac\xb8\xe9\xe2\xc5\x54\xec\xd6\x23\x6f\x3d\x54\x22\x6d\x29\x0b\x6a\x10\x58\x02\x5a\x12\x5d\x81\xa2\x35\xab\xec\x2a\x83\x56\x11\x8f\x47\x2b\x9a\x0c\x41\xa6\xa8\x2b\x0a\x6f\x45\x3d\x00\xd4\xa2\x41\x6a\xe4\x1e\x29\x22\x38\xfd\xfd\x02\xb1\x12\x62\xea\xbf\xa2\x5a\xac\xc4\xb4\x5d\x0c\x59\x9a\x1e\xac\x01\x9d\x80\xf6\xac\xfd\xcd\xb7\x55\xaf\x2f\x08\x32\xdf\xb9\xa2\x09\xac\x44\x7b\xc4\x3e\x1f\x39\xba\x27\x66\xf8\xc9\x97\xce\xcc\x77\xe6\xd3\x0b\xd3\xd4\xcc\x55\xf4\x4e\x2b\x2c\x15\x24\x3f\xc2\xaf\x87\x0c\x56\x74\x5a\x2b\x2e\xa2\xca\x0d\x65\x10\xe9\x81\x27\xa9\x27\x23\x1b\xc9\x40\x26\xd4\x13\xd5\x6f\x3b\x6e\x3d\xa1\x74\xcd\x0e\x7c\xea\x4b\x8a\xe8\x81\xcd\xf9\x93\x57\xe7\x40\x66\x9e\xcc\x7d\x51\x8d\x7f\xc7\x8b\x8e\xee\x04\x33\xdf\xce\x8b\x3d\x89\x42\x25\x27\x4c\x28\xe3\x91\xea\xe2\xd1\x42\x5e\xb1\x17\xff\xf1\x2e\x21\x9e\xc7\x16\xfe\xc7\xef\x0f\xc1\xaf\x86\xc2\x7c\xbf\xd9\x3b\x1a\x68\xd6\xd7\xfe\xb2\x3b\x12\x03\xf2\x9c\xc6\x0d\xfc\xc5\x0f\xd6\x5f\x4e\x6c\x83\x0b\x91\x98\x58\x85\x3a\x66\x9c\xc1\x18\xd8\xa8\xa8\xa7\x2a\xaf\x97\x1e\x2d\x68\xf6\x27\x9f\xcc\x10\x68\x20\x5f\xb0\x11\x05\x07\xab\xa6\x6e\x01\xaa\x88\x82\xd1\x7c\xc2\x9d\xb2\x9e\x9e\xdb\x98\x06\x01\x19\x13\xa9\x15\x79\xf2\x07\xe3\x3c\xe8\x51\x3f\xaa\xb6\xfb\x24\x39\xc9\x23\xba\x5a\xeb\x26\xc5\x5e\x8b\x67\x71\x35\x22\xa2\x40\x7a\x27\xa6\xf6\x3e\x7d\xcd\x55\x50\x8b\xb2\xd2\xb4\x02\xfd\x78\xe2\x21\x49\x2d\xa4\x62\x86\x1a\xe1\x87\xda\x5f\xf4\xa8\xbd\x2e\x7a\xb2\x53\x95\x48\x56\xc8\xa3\x1a\xa8\x66\x64\xaa\xe6\xb5\x0b\x04\xe9\xb4\xbe\x3d\xcc\x50\x2d\xb2\x71\xc3\xca\x9f\xbc\x5e\x78\x92\x6d\xe8\x77\x28\xaa\x5a\x86\x4e\xbb\x7d\x64\xda\x07\xb4\x69\xcd\xf9\x7f\xe2\xba\xab\xc5\x8b\xd6\xfa\x2e\xd6\x39\x0b\x05\xd7\x3c\x81\xac\x65\xfd\xa2\xd5\xb8\xbf\x24\xce\x4c\x1d\x2c\xa4\x6c\x67\x6a\x59\x2e\x72\x99\xc5\x5e\xc8\x5c\x9f\xcd\x5c\xd6\xfe\x16\x62\xad\xae\xa4\xbc\x30\xf3\xfe\xfb\xcc\x3c\xc3\x96\x44\x9d\xc1\x28\x90\x33\x7f\x1c\x37\xe3\xc1\xca\xcc\xbc\xb8\x31\x5f\xc8\xb8\x6f\x9f\x21\x16\x4e\x94\x12\xe1\x84\x34\x65\xb6\x29\x51\xc1\x72\x6b\x56\xac\xda\x05\x68\x0a\xf4\x42\xfb\x37\x33\x0d\xa3\xc6\xff\xab\xf0\xf8\x24\x96\xfd\x42\x17\x70\xa6\x07\x72\xb2\xcc\x21\xb0\x33\x31\x66\x7f\xf3\xcd\x96\x61\x37\x90\x6f\xbe\x98\x1f\xfe\xc9\x3b\xd1\xc9\x25\x9b\x5a\x07\x19\xb1\x5e\xbd\x6f\x37\x13\xd1\xd3\x57\xf7\x50\x4e\x33\x89\xf2\x66\x40\x9f\xd8\xc4\xcd\x28\x28\x33\xda\x95\x19\x97\xc0\xcc\xdf\x96\x9b\x49\x35\xc7\x1e\x66\x1c\xb1\x0e\x24\x17\x56\x82\x06\x81\x22\x19\x13\x65\x50\xb2\x20\xf1\x3d\x15\x04\x94\x78\xcf\xe4\xd2\x17\x12\x34\x2c\x49\xed\x9f\xcc\x3c\xf9\x9b\xa8\xf1\x35\x44\x73\x31\xf3\xb1\xa1\x99\x8f\x0d\x81\x68\xb4\x0d\x64\x6b\x63\x1d\xc8\x0f\xbc\x83\x56\x9e\x88\xfe\x75\x6f\xab\x1c\x22\x4a\xe4\x8e\x2b\x90\x94\xb8\xd2\x6c\x9b\x09\x92\xfa\x32\x54\xfe\xbf\xc2\xed\x23\x1a\x51\xf8\x66\x7e\x2f\x06\x12\x9a\x3c\xe7\x6c\xcc\x4d\xff\xde\x61\x06\xc1\xb7\x3d\xbd\xbc\xaa\xc7\xa0\xf1\x8c\x62\xce\xc3\x11\xa0\x7b\x22\x35\x7c\x20\xcf\x9e\xac\x3d\x79\x37\x24\xdd\x26\x19\x01\xc5\x2b\x46\x73\xc6\xba\xe6\xbc\xc9\x31\xe7\x8d\xa1\x39\x57\xe6\xdc\x42\x23\x9a\xf5\x81\x59\x2b\x98\xa0\x39\xa7\x7d\x4e\x23\x31\x97\xbf\xdb\x1e\x63\x2a\xec\x7c\xcb\x52\x5b\xdf\x80\x17\x6a\x14\x3c\xf9\xe2\x07\xe4\x05\x71\x5c\x92\xc2\x3f\x99\xf9\x32\x56\x40\x2b\xde\xfa\x03\xf9\x2f\x26\x6f\x2e\xab\x71\xc8\xb6\xac\x71\x70\x32\x17\xe7\xef\x13\xe8\x93\xd3\xf6\xc9\xa9\xbc\xb0\xf2\x8b\xbd\x1b\x3c\xba\xdc\x50\x58\x86\x43\x90\x3e\x33\x24\xf8\x0f\x22\x97\x56\xfb\x5f\x7b\x76\xa1\x46\xef\x81\xce\x79\xdc\x31\xf7\xf1\x85\xb9\x3f\x65\x07\x79\xf0\xa4\xb2\xf6\xc8\x2a\x63\x43\x7e\x59\x5b\x7f\x23\xaa\x40\x74\xb2\x61\x72\x31\xd4\x86\x1b\x18\x1c\x46\x0d\x98\x3c\xa0\xb2\x6e\x7c\x48\x01\x44\x4d\xc1\x33\xae\x9d\xa0\xfa\x86\x37\x4f\x80\x6e\x91\xe7\x97\x53\xea\x86\x91\x06\x20\xed\xd3\x73\xe7\x2e\x8c\x63\x35\x3f\xdb\x4d\x94\x58\xa0\x9e\x4d\x83\xcc\x7d\x0b\x1a\xdf\x85\x38\x00\x3c\x5f\x8b\x75\xbc\x32\x50\x88\x87\x6b\xff\xe6\xd6\x57\xb0\xf3\x65\xe8\x86\x01\x65\x1c\x7e\xab\xe0\xe8\xc9\x4f\xdf\xd1\x33\xd1\x45\x03\x81\xb2\x5c\x90\x74\x95\x79\xb8\x35\x2e\xca\x0a\xa8\xef\xca\x48\xfc\x98\x9a\x32\x02\xb9\x21\x1a\x31\x0c\x01\x3e\x26\xca\x59\x54\x0a\x01\x8d\x91\xcc\x46\xa6\xb1\x36\x14\xd3\x2c\xfa\xd5\x50\x1a\x81\xb6\x40\x19\x64\xaa\xb1\x73\x51\x2d\xbf\x60\x03\x0a\xdf\xe8\x92\x25\x54\x3c\x68\x7a\xd6\x6d\x81\x98\xb0\xc6\x7b\x88\x8d\x39\x84\x39\xf9\x1c\x9f\xda\xf4\xf4\x43\x18\xfb\xae\xa5\xa1\x49\x69\xa4\xc0\x8a\xf5\xe8\x86\xb6\xc1\x15\x7d\x8c\xf8\xb3\x79\x0f\x03\x92\xe8\x3d\x80\x17\x44\x15\x4f\xfd\x9e\xed\xf2\xaf\x16\xbd\x64\xab\x56\x7e\x18\xd7\x52\x4f\x03\xb2\xe1\x88\x7c\xe7\x20\xe0\x16\x82\xb6\x6a\x4f\x29\x3b\x31\xeb\x07\xcb\xfa\x64\xf7\x2e\xd0\xfc\x0d\x55\xce\xb3\x28\x1a\xe4\x13\x57\xc3\xca\x0f\xa4\xee\xf9\x0f\x5e\x1a\xee\x51\x1a\x5c\x9c\xb7\x2e\x24\x6c\xb5\x1d\xd0\x35\x7a\xef\x57\x76\xb5\x30\x46\x96\x1a\xc5\x3c\xa1\x7c\x24\x63\xa8\xd8\xc6\x89\x49\x02\x0b\xa6\xc9\xd1\x2b\x6d\x64\x1e\xff\x60\xce\x67\xf3\x51\xb4\x61\x05\x5b\x55\x70\x5f\xdb\xd0\x47\x69\x18\x62\x6d\x54\x19\xba\x0c\xf7\x44\xa5\x4f\xa6\x0a\x79\x67\x75\x33\x5f\xc9\xdc\x44\xc6\x9d\x17\x3f\x33\xdc\xd3\x78\x67\xa4\xf1\xce\x08\xf2\xac\x99\xbc\x31\x41\x86\x5b\xe2\x3a\x44\xb5\x91\xc8\x67\x03\x2e\xdb\xa7\x7f\x72\x71\xef\x98\xdb\xf8\x6c\x8e\x44\x4b\x92\x11\x85\x66\x2f\xa8\xac\x17\xdc\xf3\x2d\x28\x07\x0b\x3b\xbf\xd6\x0c\x43\x66\x18\x33\x6d\x0c\xad\xb1\xf0\xa7\x57\x0b\xee\xd5\x17\x76\xce\xfd\x64\xc4\x92\x75\x71\x2f\x7c\xf9\x15\xab\xad\xbc\xb0\x2c\x38\xe4\x0b\x6a\xe9\x05\x07\x7b\xc1\x88\xeb\x42\xbf\xb1\x49\x34\x39\x1e\xfa\x2e\xb8\x81\x5b\x30\x70\xb4\xe0\x72\x12\x24\xbe\xcc\x82\xa3\xbd\xf0\x4a\x79\x81\xa0\x0d\xdd\x82\x05\xf7\x62\x0b\x19\xf7\x06\x48\x6f\xee\x00\xbd\x62\xa8\x17\xb6\xae\x5e\x7b\xfc\x22\xd0\x8e\x5b\x3e\x7a\x8c\x78\x5b\x57\x92\xd4\xab\xde\x85\xc9\x5e\x45\x82\x08\x35\x87\xd1\xbe\x55\x03\xba\xf6\x34\xca\x66\x77\x13\x17\xbf\x0e\x63\x58\x69\xda\x8e\xdc\xe6\xdf\x89\xed\x42\x9d\x58\xa9\xbb\xe5\x66\xbf\x35\x83\xb8\x00\x49\x99\x9c\xfa\x9b\x00\xad\x1e\x06\x4a\xcb\x5a\xdc\xd5\xef\xf9\xef\x06\x05\xd9\xc2\x6d\x79\x2d\xa4\xe5\x65\xe5\x16\x27\xdf\x86\x2c\xed\x9e\xaf\x47\x4b\xd3\x06\xf7\xcb\xda\xa9\xe1\x43\x41\x62\xf3\x5a\x09\x60\xf7\x99\x75\xcd\xb8\x7f\xcb\x73\xf7\x56\x56\xd9\x7f\x59\xdf\x8e\x19\x4e\xd0\x62\xf8\xa6\x31\x7e\xda\xd0\x52\x6b\xb6\x32\xc1\x59\xcf\x36\x68\x8d\x65\xb0\xef\x8c\x80\x90\xd5\x8e\x91\x5a\x19\xfd\x4f\xa2\xab\x35\x5f\x4f\x8a\x76\x24\xa1\x84\x25\xa3\x32\x40\x4b\xa2\x2b\x50\xfc\xb2\x6f\xc9\x89\x5a\x72\xe1\x2e\xd5\x43\x92\x9a\x97\x76\x51\x37\x27\xd1\x2b\x29\x4b\x1e\x9d\x2c\xfd\xc1\xcc\xd2\x7b\x40\x4b\x4a\xef\xd2\x3c\x9a\x98\x1c\x97\xc8\xd2\xbb\x2a\x20\x9f\x7c\xa2\xb1\xe8\x25\xef\xa3\x83\x64\x54\x86\x4b\x91\x86\xa0\x61\xbf\xe9\x29\x61\x5f\xcb\xf9\xe5\xa0\x06\xfc\x0e\xa8\xe6\x48\xcd\xf9\x74\xc1\x4d\xc7\xd2\x7b\x6d\x4b\x7f\xcc\xb2\x34\xe9\xc9\x50\x5d\xd8\x88\x33\xf9\xd3\xbd\x20\x6a\xe4\x9b\x68\x89\x31\x3c\x9d\x25\x55\x06\xd0\x2d\xeb\xda\xc9\x58\xdc\xf4\xec\x33\x57\x4d\x3e\xe1\xf2\x11\xc8\x11\xa1\xa1\x25\x8e\x47\x58\xce\x99\x63\x76\x61\x2d\x17\x19\x9c\x27\xce\xcd\x15\x01\x7a\x23\xc1\xfe\x62\x14\xcc\xe4\x2e\x45\xcb\xbf\x03\xe5\x88\x6f\x00\x35\x28\xe4\x9b\x37\x94\x4b\x7f\x00\xb2\xf4\x9b\x84\x25\x2d\xe4\x92\xbe\xe4\xd2\xdb\x4a\x90\x7b\x1b\x4a\xb7\x8b\x07\xa9\x88\xf4\xe8\xe0\x1b\x6d\xe1\xd2\x6c\x61\x2c\x9e\xd3\xef\x2e\x6d\x80\xfc\xcf\x46\xd3\xec\x1c\x4f\x20\x96\x66\xe0\xd8\x13\x0d\x04\x69\x17\xbe\xd9\x66\x5a\x95\xe8\x37\x1a\xbb\x57\x1a\x3b\x1c\x86\x4d\x90\x16\x6f\x61\xac\x7e\xbb\x85\x81\x87\xb7\x7c\x52\x19\x92\x83\xe7\x9e\x9e\x9e\x59\x89\xfa\x9d\xf1\x8a\xb7\x84\x57\x74\x87\x57\x74\x87\x57\x6c\xe7\x8a\xdf\x1a\xac\xec\x1a\xf1\x88\x44\xc5\x63\x85\xeb\x8e\x44\xf1\x4c\x18\x7c\xc9\x76\xe7\x38\xe9\x05\xd2\x23\xb9\x15\x55\xc0\x8a\xfa\x74\x05\x67\x1a\xa8\x64\x8b\x11\x91\x8e\xc3\x30\x67\x2d\x0d\xd3\x16\xbe\xf2\x5f\xae\xa9\x83\xe7\xcc\xd9\x32\x5c\x08\xb2\xf1\x39\x5f\x7d\x5b\x56\xb2\x74\x86\xe4\x6b\xb6\x77\xfd\x6b\xb2\x8d\xcd\x8e\x17\x9b\xe3\x55\xab\x57\x59\x68\xba\x37\x5f\xd1\x36\xaf\xa8\xb0\xa3\x31\x58\xe9\xc5\x59\x11\xc8\x15\xd5\xf4\xab\x0f\x59\xaf\x64\x55\xb1\x72\x15\xad\x16\xd9\x0a\x86\x6b\xd7\xfe\x02\xe0\xda\x7f\x0c\xb1\xf6\x47\xde\x20\x35\x91\xba\x10\x6b\xbf\xe5\x5c\x53\x50\xd6\x54\x60\x6b\xdc\xf9\x04\xd2\x30\xcf\x9a\x97\x71\x40\x4a\x2c\xf4\xb5\xac\x72\x68\x4e\x2d\xfb\x85\x6b\x6b\x0d\x55\x26\xeb\xf1\x0a\x8e\xea\x2a\x90\x0d\x8f\xfb\x84\x98\x29\x02\xd1\xae\xe9\x95\x98\x35\x75\xd8\x5a\x8f\x99\x45\x48\xd7\xd4\x5c\x40\x5a\xcb\xd5\xb2\x86\xb1\xbf\xb1\x12\x6c\x22\xd6\xf2\xe9\xcb\x1f\x40\x37\xd6\xd4\x80\xde\x89\x4e\x40\x13\xbe\x81\x2b\x3e\xef\x24\x7a\x7d\x7e\x23\xeb\x3a\x05\x1a\xf0\xe7\x15\x36\x3c\xa7\xdc\x70\x99\x6e\xb8\xfc\x36\x92\x6f\x09\xa4\x1b\xd0\x8d\x7d\xa6\x79\x25\xd1\x2b\x4c\x1b\xce\xc1\x86\x47\xc6\xdc\x01\x20\x55\x9d\xd7\x8d\xc5\x53\x77\x20\x0b\xef\x23\x09\x77\xa2\xb6\xe1\x4d\x00\xa0\x8c\x68\xca\x56\xc6\xd0\xd4\xc6\x7f\x00\xb2\x71\x1f\x80\xe4\xe4\xb5\xcf\x39\xf3\x05\x2e\x59\xe0\x9a\x79\xce\x2c\x4a\x43\x47\x1b\x6e\xf2\x36\x32\x3f\x18\x5d\xf3\x50\x2d\x77\xf2\xcb\xc7\x46\x1b\x9d\x17\xcb\x5c\x58\x45\xb6\xeb\xda\xd0\xa6\x6c\x7c\x30\x78\x63\x51\xa7\xf8\xe4\xc9\x5a\x96\xc4\x7b\x7f\x1b\xef\xa1\x6e\x68\x4c\x36\x7e\x63\xb5\xd1\x1d\x94\x0e\x84\xd8\x0f\xa2\x8b\x6b\x99\x08\xdc\xc6\xef\x90\x36\x3e\x22\xfb\x1d\x47\xe9\xd0\xed\xdf\xa9\x9f\xd5\xd2\xf3\x56\xc4\x77\x46\xa2\xbe\x8b\xd6\x53\xaf\xef\x3b\x0f\x98\xbe\x63\x45\x60\x8e\xbf\xe3\x47\x28\x80\x6e\xac\x44\x8d\xab\x69\xbc\x60\xcb\xe3\xb8\x2d\x97\xd5\x96\x71\x97\x2d\x2f\xff\x6e\xa5\xe6\x59\xcf\xae\x55\xeb\xb0\x6c\x79\x53\x05\xf7\xb6\xbe\x1a\x92\xd6\x6c\xe9\x35\x6d\xed\xc0\xac\x06\x99\x33\x4c\xb0\x65\xf0\x77\xcb\x0b\xb5\x5b\x93\xb0\x98\xac\xdf\x31\x6d\x19\xc4\x80\x77\x86\xa4\x13\x37\xc3\x5b\x2a\x8a\x2d\x5d\xaa\xad\x88\xdb\x48\xbc\xa3\x33\xc6\x63\xcb\xaf\x55\xb7\xfa\x91\xb8\x28\xa5\xad\xe8\x8e\x6b\x4f\x7f\x4b\x40\xdb\x12\x10\xbb\x9b\xe8\xcf\xa0\x6c\xa9\x3b\xb6\xf2\xfa\x03\x10\x9c\x9b\x11\xc9\xc8\x0a\x4e\xe2\x85\xef\xad\x85\xc8\x23\xb9\x25\x8a\xe5\xc4\xf7\xfc\x6c\xc9\xc5\x14\xa2\x7f\x88\xf4\x76\xe9\xd6\x6f\xc8\xb7\xce\x1f\x49\xc9\x55\xcb\xef\xb8\x39\xde\x49\x33\xff\x0b\xdb\xb6\xe3\x4d\xa6\x9d\x7d\x9e\x72\x05\x29\x64\xc4\x47\x24\xb5\x21\x99\xc6\x1d\xcf\x8e\x77\x8c\xe1\x0a\x12\x41\xd8\x59\x10\x28\x05\x59\xf0\xa2\xce\x8e\xa7\x5d\x3b\x5a\xd5\x1d\x6e\x38\x00\x7d\xb0\xd4\x4f\xa2\xf8\x3b\x2b\x3b\x5e\xa5\xdb\xd9\xaf\x01\x7c\x27\xd9\xc2\x28\xed\xfc\x3d\xf5\x9d\x7d\xca\x90\x81\x68\x88\x68\x47\x4d\xf1\x46\x57\x6d\xcf\x43\x8f\x37\xbd\x05\x23\x59\xdf\xb8\xeb\x79\xe3\xfd\x97\xbd\x8f\x0b\x83\xdc\x13\x55\x3e\xb9\x66\xd9\xd1\x22\xef\xbd\x45\x06\x59\xb0\xf8\x37\xf7\x82\xc5\x53\xf6\x74\x12\xf6\x74\xef\xf6\xb4\x2f\xf1\xd2\xc8\x9e\xd7\xc4\xf6\x74\xe2\x40\x62\x53\xf5\xc0\x69\x8f\xcb\x51\x86\xec\x69\x85\x8e\xbc\xd1\xa9\x90\x34\x2b\x52\x67\xfc\x87\x9e\xaa\xd8\x4b\x73\xa2\x86\x28\x06\x29\xf6\xfe\x42\xda\xde\x9f\x84\xee\xb9\x39\xda\x9b\x9b\x37\x22\xc9\xf9\xf6\x8b\x6f\x7e\xb4\x51\x7b\x6f\xa3\xf6\x5e\x83\xec\x4d\x69\xc4\x02\xa2\x47\xb9\x57\x1b\xe5\x72\xfe\xc3\x15\xb3\xf7\x3f\x4f\xb2\xe7\x1d\x7a\xa0\x77\x20\x31\xec\x22\xe5\x7b\x9c\x48\x63\xe9\xee\xa5\xc3\x13\xeb\x4f\x50\x22\x63\x2b\xc7\xf6\x10\x7b\x91\xde\x01\x11\xde\x33\xc5\xb2\xc7\x69\x4a\xd7\xff\xd3\x1a\x67\x3f\xd8\xb1\xa7\xad\x03\x1a\x7a\xc2\x91\x55\x57\x21\x27\x89\xa7\x72\x6f\xd0\x3a\x36\xe1\x89\xba\x6f\x7b\x6f\x5d\xf7\x7e\x2f\x05\xa2\x8a\xfa\x07\x6d\x21\x50\xcb\x0c\x4b\xdf\x90\x15\x3b\x14\x43\x89\x20\x3f\x88\x4e\xbe\xb1\xff\xe7\xc9\x27\x0f\x0e\xf7\xde\x6a\xee\x3b\x77\x63\x0d\x44\x35\xe9\x81\xf6\xeb\xc0\xd3\x9e\x03\x17\xca\x81\x63\x71\xe0\xf2\x38\x70\x79\x1c\xa8\x9c\x0f\xdc\xf7\x1c\x78\x4a\x77\x30\xe7\x37\x23\xd1\x82\x4a\x66\x2d\x65\xad\x9c\x58\xb0\xca\xe1\xbb\xfb\x6c\x31\xd6\xa0\x6b\xe9\x20\xeb\x66\x6c\x48\x64\xe8\x20\x8b\xe6\x0f\xd6\xf5\xcc\x12\x1b\x36\xb5\x85\x9b\x70\x30\xe9\xaf\x48\x2a\x66\x40\xad\x07\x56\xf9\x02\xc9\x3d\xf8\x2d\xd2\x3f\xf6\x03\x3d\x23\x92\x05\xab\x6b\xe9\x9b\x1c\x38\xaf\x07\x99\xd4\x7b\x88\xcd\xc1\xbc\xee\x96\xef\xac\x59\xdd\x96\x8d\xdd\x33\xed\x9d\xc3\x16\x83\x37\x07\xee\x99\x0e\xf6\x6b\x2d\x23\x12\x7d\xef\x6a\xb3\x60\x32\x00\xf4\x68\xdd\x0d\x2b\x67\x4a\x84\x5e\x5a\xdb\xdf\x2d\x8e\x89\xe1\xd4\x1f\x13\x59\x93\xa0\x41\x76\xbd\xe1\xe0\xad\xe5\x81\xdf\x73\x09\x72\x1b\x99\x03\x8d\xe8\x41\x96\x68\x44\x29\x51\x66\x28\x89\x95\x17\x4e\x06\xf5\x44\xb4\x25\x29\xac\xbf\xee\x46\xc2\xc1\xbb\xa3\xff\x70\xd5\x21\xf9\x87\x49\x98\x8b\xc7\x1f\x19\x4a\x3f\xea\xa1\xa7\xbc\x70\xf4\xdf\x74\x1c\xfd\xed\xa7\xff\xd9\xd7\x87\x19\x0b\x48\xb9\x81\x03\x39\x02\xe9\x3a\x3a\x52\xc1\x1c\x69\x70\x8e\xf4\x66\x8e\xb2\x7a\x1e\xd0\xaf\xa3\xfe\x52\x97\x05\xa2\x8e\x54\xd5\x47\xae\x9c\xa3\x2c\x9b\x2f\x40\x8f\x18\xde\x23\xae\x17\x01\xcd\x98\x6f\x06\x37\xe9\x48\x5f\xef\xa4\x47\x54\x42\x8e\x34\x36\x47\x1f\x7f\x3b\xf2\x84\xfe\xc8\x5f\xb0\x3a\x9a\xcd\x69\x49\x32\xa2\x82\x65\xbf\xf2\xbd\x15\xbb\xbe\x62\x15\x3b\x3e\xdd\xb3\x85\x07\x5f\xed\x4f\x66\xbd\x10\x5d\x0d\x99\x01\x38\xf2\x7c\xf4\x48\x91\x3d\x8a\x38\x16\x86\xb4\xea\x84\x63\x0d\x1f\x53\x9a\x7c\xd2\x53\x2e\x6d\xb2\x79\x92\xc7\xce\x9d\xaa\x9f\xec\xe0\x28\xe3\x13\x15\x28\x3c\x51\xe3\x86\x53\x06\x15\x9e\x9f\x3e\xca\xfb\xd3\x76\xb6\x03\x92\x8c\xe8\xce\xe7\x29\x7c\x51\x25\x91\xda\x93\x9f\xfe\xdc\x1b\x64\x4e\xa4\xc7\x9f\x3f\x3b\xf7\xab\x0b\x3f\xfd\x39\xf6\xcf\xce\x7e\x34\xe1\xa7\xf8\xa5\x13\x20\xdd\x68\x7c\xe8\x06\x5c\xe4\xec\x43\x37\xc5\xba\xf2\x91\xd3\xf6\x3f\x3f\xbd\x27\xfe\xf1\x9b\x59\xfc\xb0\x10\x63\xc5\x9c\xa5\xf5\xdb\xed\x05\x3f\x3a\xfb\x22\xeb\xcc\x21\x3b\xd3\x17\x84\xe1\xd2\xcd\xc9\xd9\x3e\xa0\xca\x49\x74\xf4\xcf\xfe\xa3\xa5\xb3\x7e\xa7\x64\x45\xc5\xef\x94\xce\x5c\x79\x67\xce\xc8\x99\x1d\x38\xfb\xd6\x7f\x72\x19\x9e\xb9\xe6\xce\xd4\x32\x67\x7a\x4d\x67\xce\xd4\x99\xee\xfb\x99\x87\xce\x67\x4a\xce\x99\x7a\xe8\xdc\xb9\xaf\x26\xcf\x5c\x94\x67\x5c\xff\x21\xd2\x3e\xea\x75\xec\x33\x4d\xd6\xbf\xf8\x59\x39\xdf\xa8\x5f\x3e\x37\x00\x2f\x89\x1a\xb6\x73\xc5\xfd\xce\x99\xf1\x9b\x33\x9d\x9f\x33\x9d\x76\xa0\x29\x11\x7b\xe0\xae\x43\x21\x6c\xb4\x81\x46\x8c\xdf\xfb\x00\xa9\x27\x7b\xe1\x71\xcd\x85\xb1\xc2\x0b\xbe\x56\x02\xd2\xe3\x8b\x8b\x18\xd8\x7e\x4f\xbf\x15\xb2\xf2\xbf\xf2\x0d\xb5\x89\x17\x44\x00\x81\xd6\xf0\xb4\x2f\xb2\x4b\x9f\x02\x6d\xf9\xae\x4a\xc2\x85\x91\xc1\x8b\x98\x8e\x3b\xa0\x21\x9f\x66\xfc\xac\xe0\xc2\x1f\x7e\x8c\x86\x33\xfe\xe0\xd9\x05\xba\x81\x28\xb3\x96\xbb\x4b\x36\x17\x8b\x7e\x87\x17\xae\xbc\x87\x71\xa5\xe1\xb8\x52\xfa\xae\xd4\x33\x57\x04\xa0\x0c\xc9\x54\x5d\x29\x5c\x57\x5a\xb2\xab\xfd\xe2\xc3\x00\xa4\xf6\x28\x96\x3a\x23\x7a\x61\x3b\x5a\x3a\x66\x57\x7f\x22\x77\xa5\x23\x72\xf5\x91\xd5\xab\x74\x61\x45\x84\x06\x96\xcc\x29\x5b\x75\xcb\xa9\x7a\xfb\xea\x77\xba\x57\xc6\xa3\xae\xdc\xdf\xc7\xa3\x8e\x2b\x2f\xdb\x5f\x7d\x70\xff\xca\xaf\x94\xae\x8c\x37\x5d\xdd\xe0\x4a\xfc\x40\x92\x03\xc2\x85\x23\xa0\x50\x93\x6e\x07\x06\x3d\xb7\x31\x50\x34\x24\xaa\x7a\xf6\x9d\x19\xbe\x94\x8c\x77\xf0\x03\xba\x63\x41\xa5\xed\x8d\x71\x2f\x3f\xfe\x7a\xaa\xf2\x37\xa0\x47\xfb\xcd\x46\xbd\xbe\xaf\x0d\xaa\x59\x79\x2d\x66\x47\xd1\xc9\x50\x10\xdf\x80\x66\xac\x62\xc6\x52\xb8\x8d\x0a\x84\x3f\x6e\x14\xc8\xce\x92\xc3\x30\x5e\x81\x86\x4c\xbb\xb1\x2f\xb6\x71\xdb\x4c\x55\x4b\x20\xd0\x60\x7a\x72\x9d\x78\x92\x7a\x32\xf4\x04\x4e\x95\xdd\x22\xb1\x19\x52\x0e\x39\x50\x52\x11\x41\x0b\x2b\x41\xf0\x04\x44\x5d\x3b\x25\x39\x8b\xba\x75\xbf\x60\x17\xf8\x83\xc8\x8e\xdc\x7d\x96\xd5\x10\xd0\x93\xbb\x78\x1d\xf8\x33\xcb\xbd\x58\x9a\xba\xa8\x7a\x87\x13\x97\x56\x95\xc0\x46\x2b\x81\xf7\xa1\x3f\x2c\xa9\xdf\xe3\xa0\xee\x84\x1f\xc5\xda\xa2\x0b\x49\x43\x3e\x44\x2c\x4b\x11\xce\xbc\x40\x62\xf4\x57\x7f\x12\x2a\xe3\xdb\xaf\xf6\xb6\xee\x3d\x13\xfc\xb0\x6b\x4e\x84\x13\xb0\x64\x60\x97\x1c\x92\x01\x45\x31\x8e\xf1\xc0\xb6\x41\x4a\x6a\x8f\xe8\x63\x46\x47\x3a\x19\x50\xaa\xe2\x8c\xf0\xfc\x37\x19\xd8\x6f\x05\x24\x03\xbb\x85\xa3\xe8\x87\x28\xbb\x64\x60\x3f\xdb\x9b\x0c\x4c\x19\x24\xb8\x64\x56\xb8\x66\xe8\x31\x78\x82\x0b\x64\x37\x5c\x77\xa9\xed\x0b\x14\xbd\x3b\x67\x20\x67\xea\x87\x21\xdd\x7c\x24\xa9\x59\xd4\x24\x75\xb7\xab\x12\xba\xd4\x09\x4d\x7c\x82\xef\x9d\xc7\x40\x0c\xe2\x05\xf2\x0d\x8d\x4d\xdd\x01\x55\x82\x26\x20\x83\x6a\x9c\x84\xbf\x49\xa8\x73\x37\x20\x8a\x69\x3c\x0c\x53\xfe\x48\x54\x13\xf1\x06\x4d\xbc\xb9\x19\x7f\x78\x34\x19\x9a\xe3\x90\xd8\x4f\x03\x5a\x45\xb9\xed\x2c\x02\x99\x32\xf9\xde\x37\xab\xe4\xab\x95\x6f\xc9\xdc\xa3\x1c\xe8\x85\xed\x5e\xb2\xac\x57\x9c\x9f\x31\x0f\xfc\xbd\x64\x68\x76\x3b\xa0\xd4\xca\x4a\x32\x0b\x58\x29\xd1\x59\x46\xe4\x2f\x05\xca\x2d\xec\xa2\xe4\x9e\x08\xd6\x5b\xc9\x73\x4f\x57\x6b\xc2\xcf\x69\xf4\x0b\x18\x45\xaa\xc7\x6f\x28\x90\x37\xec\xc1\x8d\x85\xe2\xe4\xaa\x2c\x2a\x1b\x51\xb2\x46\xee\xf7\x90\x94\xcc\x98\x3b\xb7\x1f\x88\x51\xa2\xc9\x53\xa6\xc1\x37\x0b\x68\xc6\xe2\xe6\x4c\x9b\xb3\xd4\x25\xdf\xd8\x1a\xb2\x81\x1a\xd9\xc1\xc9\xc4\x72\x9b\xee\x1d\xf1\xc7\x76\x48\xc6\x7c\xfb\x2f\xfd\x39\x16\xb1\x35\xe0\x6c\x4c\x32\x62\x51\x13\xeb\xaf\x29\x10\x1c\xca\x84\x61\x1e\xbb\xdb\x1f\xc9\xd8\xeb\x5f\x90\x47\x22\x55\x76\x63\xfb\x60\xa5\x10\x82\x0b\x44\xfa\x3b\x5d\xc9\xa4\x8b\x5f\x66\x28\xf9\x42\xa4\x83\x03\x82\x1f\x71\x8b\xd9\xb0\x81\x55\xf2\x49\x92\x41\x35\x4e\xf4\x47\x49\xb4\x00\xbd\x9e\x10\xc9\xd4\x93\xc2\xaa\x8f\xbb\x01\x25\x51\xdc\x27\xde\xee\x4f\x34\x42\x25\x24\xe3\x62\xcd\xec\xfa\xbb\x22\x7c\x53\xab\x64\xce\xdc\xb9\xf8\x6c\x2a\xe7\x2d\xd0\xa3\xcc\xd8\x4d\x4f\x25\xde\x54\x4e\x46\x61\xcd\x28\x0d\x99\x6d\x28\x13\xfe\x36\x52\x82\x5f\x37\xfa\x42\xf4\x83\xe8\xc4\xac\xd8\xcf\xe0\xc7\x7f\x45\x6f\xe0\x27\x87\xfa\x44\x88\xb2\x2b\xd1\xc5\x9f\x9b\xa3\x9d\xc8\x0f\xb3\xc8\x4f\x6a\x83\xd4\xee\x57\x88\x55\xeb\xa6\xbd\xf8\x31\xfa\xff\x07\x00\x00\xff\xff\xaa\x0a\xcc\xb8\xdf\x5e\x00\x00")
-
-func keysWordlistJapaneseTxtBytes() ([]byte, error) {
- return bindataRead(
- _keysWordlistJapaneseTxt,
- "keys/wordlist/japanese.txt",
- )
-}
-
-func keysWordlistJapaneseTxt() (*asset, error) {
- bytes, err := keysWordlistJapaneseTxtBytes()
- if err != nil {
- return nil, err
- }
-
- info := bindataFileInfo{name: "keys/wordlist/japanese.txt", size: 24287, mode: os.FileMode(420), modTime: time.Unix(1497960590, 0)}
- a := &asset{bytes: bytes, info: info}
- return a, nil
-}
-
-var _keysWordlistSpanishTxt = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x34\x5b\xbb\x76\xfc\x2e\xaf\xed\x79\x4b\x8c\x65\x8f\xe6\x00\xe2\x27\xc0\x2b\x99\xb7\x49\x99\x62\x8a\xff\x4a\x97\xd6\x2f\x76\xd6\xde\xe4\x2b\x46\x98\x3b\xe8\x2e\x60\xee\xaf\x2d\x26\x0b\x71\xdb\xad\x48\x0d\x71\x93\x67\x0c\x71\x53\xf1\x81\x52\x3b\xe3\xce\xb4\x12\xae\x42\x8f\x2f\x26\xea\x21\x6e\x53\x32\x32\xb3\x5b\x88\x29\x6e\xd1\x91\xec\x52\x34\x86\x98\x92\xb0\x38\xe9\xfd\x53\x43\x4c\xa2\x43\x90\xe4\x13\x95\x52\x31\x5a\x92\x36\xa2\x87\xfb\x2b\x29\x66\x4a\x39\x3a\xc7\xa8\xf7\x77\x88\xc9\x4e\x41\xc6\x38\xcc\xd0\x8b\x09\x81\xeb\x0b\xc9\x64\xe3\xb9\x2b\x13\x71\x8e\x31\x3b\x4a\x77\x65\xd3\xbd\xe8\x40\xed\x6e\x9c\x28\xee\xe6\xd8\xcc\x3e\x63\x8d\x48\x32\x1a\xdd\xdf\x2e\x16\xe2\x21\x89\x6d\x0e\xfd\x5b\xf2\xa1\x75\xe5\xbd\x70\x91\xa7\xe6\x10\x4f\x65\xa3\xd3\xea\xfd\x8e\x48\x3b\x86\x38\x6d\x95\xba\x9c\x2b\x55\x14\x4e\x34\x98\xbb\xa1\xef\xd4\xcc\x1c\x30\xfc\xb0\xd3\x00\xdd\x2d\x44\x75\x09\x51\x7b\x46\xbf\xa7\xec\x2e\x2f\xa4\x58\xe5\x73\x76\xa0\x2c\xc7\xe4\xf7\x57\xc5\x47\xd9\x9c\x05\x5e\x62\x88\x79\x8b\xe1\xfe\xca\xdb\x2c\x21\xe6\x14\xf3\x8e\xaa\x5d\x50\x23\x27\xdb\xc9\x13\x83\x66\xf1\xc1\x42\xc2\x43\x33\xb0\x4a\x2a\xe4\xd3\x76\xee\x34\x2b\x29\x9d\x75\x91\x25\xeb\x85\xf5\x67\xce\x52\xc8\x14\xb9\xdc\x6f\xd2\x37\x8f\x05\xe5\x85\xd2\x45\x15\x62\x31\x8f\xe9\x28\x9a\x05\x6b\xcf\x2f\x34\x2b\x71\xcb\x82\xa4\x0e\x26\xcd\x80\x84\x12\x1d\xfb\x2f\xb1\x13\xad\x65\xfb\x4b\x14\xc3\x14\x6e\xbd\x28\x5b\x68\x1f\x71\x0f\xb1\x18\xc6\x6a\x11\xe8\x2a\x2d\x63\x6d\x35\x3d\x08\x35\x56\xa6\x18\xb7\xee\x98\xb3\xee\xf7\x77\x0d\xb1\x92\x0b\xef\xaf\x7a\x4e\xf0\x68\xd5\x9c\x41\x87\xaa\x05\xb9\xfb\xdd\x43\xac\x8b\x68\x75\x08\x98\xa1\x0e\x3d\x27\xea\x86\x3d\x91\xcc\x98\x01\x49\x97\x3a\x6b\xc2\xac\xf7\x7f\x91\xcc\x76\xff\x27\x4f\x66\x2d\xc4\x16\x49\xf2\x16\x3d\x62\xfd\x4d\x06\xf7\xd1\xd0\xbe\x65\x4d\xac\x34\xa0\xb7\x99\x03\x0d\xcd\x3e\x91\x71\xa9\x3b\x28\xd1\xdc\x88\xd8\x36\xa5\x83\x42\x6d\x62\x9b\x4e\x82\x38\x66\x0c\x14\x8a\xfb\xcb\x37\x1d\x6e\xfc\xb0\x1c\xa2\x6f\x93\xac\xe7\xe9\x41\x22\x38\x24\xd9\x39\xa4\xef\x9a\x81\x10\xdf\x27\xdb\x0b\x10\xe1\x14\x31\x57\xe9\x21\x7a\xf9\x63\x5f\xaf\xf7\x37\xf2\x06\x52\x7b\x23\x20\x47\xb8\xcb\x09\xbc\xb9\xdb\x0b\x70\x82\x5f\xb8\x7c\x1f\xca\x75\x76\xfe\x30\x66\x5f\x0c\xd0\x93\x54\x88\x6a\x97\x73\x52\x8c\xbb\x30\xd7\x41\xbd\xfe\xc7\x5a\x5d\x33\x61\xa7\x58\x76\x10\xaf\x5b\xd9\xb8\xaf\xde\x04\x5b\xef\x63\xad\xbe\x8f\x95\x9b\xec\x37\x0b\x3b\x4c\x8e\x32\xe2\x93\xf0\xdf\x14\x24\x1e\xe2\x58\xc3\x0f\xc1\x40\x43\x81\x8b\x41\x8e\xbf\xbf\x86\x81\xe4\xc3\x23\x50\x33\xb8\x9f\x71\xff\xd6\x10\xe7\x1e\x5f\x80\xa0\xd4\x3c\x25\xc4\x89\x69\x67\x59\x43\xcd\x2e\xe4\xda\x39\xb0\xfe\x0b\xdc\x70\xc5\x9a\x04\x09\x16\x76\xe1\x4b\x72\xa6\x26\xb9\x64\xc1\x3e\x7c\xbe\x42\xbc\x96\x02\xb9\x14\xf8\xf8\xc4\xbc\x9f\x73\x8f\x80\xd8\xf0\x2b\x1e\x4b\xa0\x29\x23\x2f\xc3\x2c\xaf\xfb\x97\x9c\xf2\x9a\x07\x44\xf7\x35\x73\xd8\xe2\x16\x01\xcc\xc3\x16\xd3\x43\xc2\x16\x1f\x20\xda\x16\x35\x23\x03\xe1\xde\x62\x8e\xf5\x85\xb2\x9c\x30\xe5\x46\x35\xb0\xc5\xb2\xdd\xbf\x61\x8b\x35\x19\xe0\x8e\x06\x60\xd6\x2d\x3a\xc7\x74\x96\x7b\xd5\x17\x12\xb7\xb0\xdd\x5f\x3d\x61\xfb\x5b\xec\x63\x0d\xd4\x21\xce\x5b\x1c\x31\xb3\x78\x88\xaf\xc9\x41\xb8\x2d\x8e\x39\x38\xe8\x2f\xd6\x89\x7d\x6c\xb2\xdd\xdf\x80\x8a\xd9\x04\xd2\xb6\x49\x67\x45\xe7\xe7\xd0\x18\x36\x85\xd8\x6e\x2a\x35\x6c\x5a\x4f\x0b\x5b\x5e\x6b\xcc\x06\x52\x6e\x79\xf6\x18\x36\xc3\x6f\xd3\xca\xc4\xc2\x66\x09\x5f\x69\x15\xec\x04\x72\x22\x59\x25\x99\x00\xac\xb3\x59\x66\xff\x82\x4d\x5a\xdd\xe3\x8e\x04\xe2\x48\x1b\xb6\x59\xed\xf7\x97\x86\xcd\x1c\x48\x32\x07\x97\x6e\xd6\x39\x35\xa8\xb0\xd9\xb8\xdf\x35\x6c\xf7\xcf\x25\x9c\xe7\x15\x73\xd8\x3c\x5e\x16\x96\xdd\xdb\x5c\xd2\x23\x22\xb9\x24\x6c\x4e\x9d\xb2\xb9\x72\x0b\xae\x98\xdb\xb9\x58\xca\xd3\xe6\x06\x76\xd9\x9c\x43\x3b\x34\xff\xe6\xb3\xb3\x2d\x78\x7a\x9b\x49\x08\x41\xcd\x09\xb5\xb7\x4d\xf9\x0c\xdb\x3c\x16\xc5\xe6\x41\x42\xdc\xbf\x40\xd9\xd4\xe1\x68\x96\xd9\xd1\x37\x8e\x36\x3d\x13\x62\xeb\xb3\x83\x7f\xb6\x39\x22\x16\x30\x5f\xe8\x0b\x93\x8c\x25\xa6\xb8\x41\x5d\xa7\x48\xa4\x26\x18\xf1\x90\x62\x8a\xa8\xd9\xef\xaf\x4b\x1c\x1f\xc2\x3a\x7e\x1f\xf7\x77\x48\xf1\x7e\xef\x28\xd1\x02\x66\x4d\xf1\x89\xcc\x73\x8d\x9b\xf1\x83\x22\x47\x0a\xd5\x08\xfb\x43\xa8\xc0\x7a\x8a\x39\x0b\x60\x41\x9f\x6c\x6c\x76\xa1\x9e\x05\x65\x63\x8f\x22\x6b\x71\x45\x2b\x93\x66\x21\xdd\x5f\x35\x71\x09\x75\x57\x4c\x52\x25\xa3\x47\x3d\xa1\x15\x53\xac\x9a\x98\x1d\xc8\x40\x37\x02\xae\x25\xd9\x86\x9c\xf5\x90\x62\x8b\x2f\x40\x1d\x6b\xe1\x0d\x04\x48\x91\x1e\x40\x8a\x6d\x82\x84\x29\x12\x07\xbe\xb1\xf3\xfd\xe5\x49\x30\x9d\x43\x65\xa4\xe8\x27\xa1\x42\x66\x52\xf4\x8a\xee\xde\xfe\xea\xb8\x10\xe7\x77\x27\x48\x28\xe8\xc2\xf2\xde\x58\x34\xb8\xe5\x61\x9e\xd0\x15\xa4\x4b\x50\x37\x98\x62\xb2\xd3\xcb\x42\x92\xcd\x20\x5b\x49\xa0\xb4\x93\xec\x18\x40\x32\x70\x7e\x7f\x67\x81\xa9\x4f\x92\xe1\xfd\x20\x3f\xd9\x72\xe9\xa6\x24\x55\x41\x4f\xa9\x83\x7d\x1c\x48\xa1\xfb\x93\xc4\x49\x69\x59\xe5\x60\xf0\x24\x4e\x63\x9d\xee\xef\xde\x64\x0f\x49\xd8\xe9\x11\x49\xc5\x47\xcc\x92\x98\x2d\xed\xfe\x45\x4a\x5b\x9a\x1e\xb1\x11\x3a\x33\xca\x26\x0a\x77\x64\x59\x9b\xf4\xa0\xc0\xa6\x87\x61\xe4\xc7\xa4\xaa\x4d\x8f\xd9\x30\xa1\xa6\x4c\xac\xaa\x9c\x06\x98\x09\x59\x00\x1f\x32\xe9\x01\xdc\xeb\xb9\x50\xa9\x60\x09\x8a\x50\x52\x20\x5a\x2b\x86\xd2\xe6\xb0\x4c\x49\x9d\x15\x3e\xc9\x07\xda\xd9\x82\x0d\x26\x19\x2d\xd3\x39\x48\x39\x56\x00\x8c\x97\x63\x17\xc0\x0b\x50\xa9\xc3\x53\xe6\x24\xf9\x7e\x2f\xfe\x31\xe2\xd6\xfe\x5c\xd3\x64\xe9\x41\x0e\x5c\x2a\x26\x19\x66\xbc\x7f\x76\xb8\x20\x09\x86\x3b\xd9\xc1\xf6\x70\x47\x93\x3d\x04\x23\xda\x13\x9a\x22\xc1\x55\x48\xd0\x40\xc9\x32\xd9\xca\xb2\x9c\xca\x32\x78\x05\xc9\xf2\x1a\x32\xe7\x95\x2b\xac\x9a\x85\x85\x05\x5a\x15\x29\xc7\x2d\x4a\xca\xff\x94\x35\x65\x69\x40\x92\xd5\x1d\x2d\xaa\x70\x9e\x7a\xb2\xc8\x28\x21\x56\xfb\x5f\x29\xf9\xda\x40\x2f\x6b\x0a\xe8\x71\x89\xbf\x39\xf4\x37\x52\xa8\xdd\x64\xbe\xff\x15\x1b\xe7\x77\xe7\x38\x7d\xc1\x02\xd1\x31\x98\x76\xba\x9b\x62\x4c\x07\x2a\x5d\x22\x61\x5a\x99\xfb\x8d\x15\xba\x14\x36\x7d\x03\x2a\xe2\x87\xe4\xda\xd8\x5d\xbb\xf6\x90\x1c\x76\x37\xf9\xfd\xb3\x90\xee\xe0\x18\x56\x4f\x76\x9f\xaf\x90\x66\x24\xd3\xcf\x48\xbe\x98\x91\x9c\x39\x37\x02\x44\x18\x09\xb2\x0a\x3c\xcc\xa5\x2a\xe6\x62\x7f\xb8\xfa\x2c\xe4\x6a\xa7\x5c\x80\x0a\xef\x2f\x4d\x08\x0e\xb2\xb9\x11\xb2\x39\xdd\xe6\x34\xe1\x3a\xa2\x09\x36\x3f\x2b\xd7\x32\x8d\xb0\x2d\x2d\xf0\xdb\x28\x65\xf4\x5e\xd2\x74\xa5\xec\x4d\x5f\x90\x93\x0c\xed\x61\x87\x12\xdb\x69\x76\x31\xe5\x1e\x21\x78\x3b\xbc\x8e\x1c\x76\xd9\xc4\xc3\x7e\x7f\x6f\xc8\xdc\xdf\x29\xee\x31\xec\x92\xd4\xc3\x2e\x68\x26\x87\xd4\x8e\xa2\x43\x2b\x0b\x61\xc5\x77\xc9\x07\xd8\x69\x47\x70\xc4\x56\x19\x46\x6b\x97\x62\x8e\xb6\x70\xab\x76\xa9\x23\x62\x82\xe5\x45\xee\x02\x53\x84\x62\x77\xec\x61\x97\xbe\xbc\x8b\x5d\xe0\x76\xed\xd2\xe1\xe8\x23\xad\x93\x23\xf6\xa1\xab\xf6\xba\xdf\x48\x07\x55\xf4\x2e\x43\x2a\x56\x2c\xf0\x4f\x76\x10\x73\xd7\xb8\x65\x43\xb2\x83\xc2\xbb\xfe\xb9\xef\xbb\xc2\xd3\xd9\x35\x22\xb6\xd9\x75\x9b\x4f\x24\x0c\x99\xf6\x25\x66\xbb\x02\xa7\xbb\xca\x2b\xec\x7a\xdc\xef\x04\x1c\xe8\x89\x69\x35\xaf\xb1\xf2\xc4\xa6\xb5\x42\x3f\xed\xea\x82\x20\x6d\x57\xd7\x93\xc5\xd0\xa4\xbb\x76\x81\xda\xdd\xb5\x1f\x1e\x31\xd2\x85\x8e\x17\x57\x6f\x08\x27\x76\x4b\x00\xb0\x2a\xbb\x15\xba\x11\xbb\x55\xfc\xb0\x14\xa3\xe7\xbc\x9b\xc3\x5f\xdc\x0d\xc4\xdb\xad\xe3\x07\xd2\x79\x3c\x41\xea\xdd\xed\x8c\x61\xa7\x25\xd8\xb9\x73\x46\xb2\xfb\x5c\x53\xcf\x8c\x19\xee\x5f\x7c\x42\xcd\xed\xe4\x88\x7d\x52\xb7\xee\xb0\x44\xf7\xf7\x86\xc0\x43\x36\x20\x03\x3e\x81\x07\xa8\x51\x01\x47\x9b\x07\x81\x6e\x92\xfd\x2f\x90\x94\x5d\x11\x53\x1a\x3e\x06\x6b\x27\x6c\xb5\x1c\xdc\xbe\x1c\x9a\xe2\x2b\xc8\x53\xf0\x2b\x2d\x5b\x90\x2c\x07\x71\x2e\xd0\x26\x8e\x64\x29\x7e\xc9\x72\xa1\x67\xd6\xd6\x25\xdc\xdf\x59\xd9\x48\x3f\xd8\xc8\xa0\x79\x24\x33\x1e\x96\xb2\x81\xee\xb2\xe2\x5f\x29\xf6\xb7\x94\xd2\xa0\x73\xa4\x34\xee\x14\xd3\x09\x13\x97\x1e\x83\x54\x6e\xaa\x26\x06\x68\x52\xd3\x63\x1e\x82\x14\x7c\x21\x88\xa8\x58\x0c\xe2\x49\x3d\x80\x67\xa9\x87\x78\x41\x7a\xd2\xc1\x94\xaa\x67\x41\xdb\x1c\x13\x7a\x9a\x17\x24\x2e\x6c\xdb\xe3\x27\x13\xb9\xff\xc3\x2e\xea\x58\x23\x0d\x67\xee\x82\xe2\x96\x4a\xfe\xbc\xbf\x1b\x1c\x29\xf9\x37\xb5\x59\x10\xd7\x97\x05\xe9\xf0\x39\x90\xc0\x53\x91\x0e\xbd\xeb\x48\x5d\x37\xe5\x07\x77\xdc\x05\x51\x61\x90\x7e\x88\x33\x99\xe2\xec\xdd\x20\x8b\xd2\x1b\xb4\xa6\xf4\xc6\x3d\xf5\x66\x9d\xc9\xc4\xaa\xfb\xbf\x79\xbf\x03\xb4\x0a\x86\x03\x9e\x10\x8b\xa0\xf5\x98\x47\x0c\x32\x60\x14\x65\x88\x57\xac\x70\x40\xad\xc9\xa8\x98\xec\x62\x5c\x28\x57\xcc\x13\x7d\xaf\x45\xad\x8b\x67\x05\xf2\xc1\x63\x0b\xf9\x40\x6c\x1b\xe4\x83\xe7\x22\xf2\x91\xe0\x08\xc8\xc7\x6a\xf9\x41\x09\x90\x0f\x45\x70\x2b\x1f\x2b\x3c\xba\xbf\x3f\x94\x95\x8d\x76\x53\x3e\xfe\xc2\x49\xf9\x68\x06\xa1\x95\x8f\xe1\x52\x2c\x1c\xf7\xd7\xe6\x58\x0c\x3e\xa0\xc1\x8e\x98\x1e\xd8\xec\x71\x7f\x41\x06\x0f\xcc\xef\xe1\x88\xc0\xdb\x01\x3f\xee\x88\x70\x33\x0e\x3a\x87\x47\xcc\x9d\x10\x6b\x3d\xa0\xdb\x8e\x58\x34\x2b\x53\x63\x95\x47\xf0\xce\x11\xbd\xc4\xc4\x72\x37\x8c\xea\x1d\xdf\x5d\xc2\x11\x87\x9e\xf8\x9e\x9c\xe0\xe2\x64\x1f\xe1\x80\x0f\xe3\x16\x0e\x3a\xcd\x87\x64\x7d\x85\x43\x90\x77\x8c\x22\x08\xc5\x8e\xfb\xdb\xa1\x38\x0f\x71\x76\x93\x4e\x17\xfc\x50\x9e\x1c\x1c\x4a\x35\x7b\x28\x96\xa6\x50\xec\x87\xfe\x59\xed\x43\x39\xa8\xee\x18\x50\xe9\x2d\x1d\x2a\x19\x80\xcd\x68\x1b\x0e\x45\x28\x1a\x0e\x7d\x72\x80\x27\x9a\x02\x3f\x9a\x61\xc4\x0f\xec\x12\x3d\x32\xec\xce\xa1\x18\xb4\x02\x8d\x5a\x41\x0d\x68\xe8\x81\x72\x07\x4e\x72\x4c\x06\x88\xb8\xe7\xc8\x6b\x47\x50\x41\x47\x36\x96\x40\xb1\x1d\x19\x4a\xf1\xc8\xf7\x2f\x2a\x6c\xc3\x2e\xc1\xc6\x87\x9d\xb0\xc3\x87\x51\xf9\x1c\x06\x22\x1f\x96\xb3\x60\x78\xab\x3b\x20\x27\xe1\x89\xd0\x61\x3e\x88\x48\x73\x04\x56\x07\x38\xf4\x30\x34\xf5\x98\x22\x08\xe2\xeb\x2c\xea\xf0\x58\x41\x4c\x27\x0d\x3c\xce\x1d\x89\xdc\x6f\x47\x52\xd1\x10\x52\x7d\x38\x24\xea\x70\x6e\xc6\xb9\xfe\x09\xcf\xec\x98\xd4\xda\x94\x0f\x94\x81\x82\x13\x2e\xfd\x31\xeb\x1f\x8e\x27\x02\x91\x63\xfa\x5a\xf7\x24\xd9\x66\xc7\xd4\xf7\xef\xd8\xc0\x04\x73\x40\x1d\x9e\x31\xc1\x3f\x3b\xe3\x11\x7b\x38\x23\x1c\xb4\x13\x21\xfa\x19\x59\x9a\x57\xec\x78\x92\xdf\xce\x88\xf0\xec\x8c\xd0\xd6\xe7\x3a\xc7\x39\x23\x3c\x9b\x33\xc2\xce\x9d\xd1\xe3\x53\x90\xbc\x50\xd4\x97\x07\x75\x46\x0a\xe5\x19\x07\x5a\x5c\x9a\xe1\xd9\x9f\x52\xa0\xb5\x4f\x81\xaa\x3f\xa5\x86\xf3\xfe\xa6\x72\x3a\xa5\x2a\xe1\x90\x70\x8a\xc7\x95\xf3\xff\xe5\x21\x86\xa7\x74\x0c\xa5\x27\xf5\xec\xa9\xa5\xc6\x8e\x56\x0a\x5d\x74\x2a\x06\xc9\x60\x76\x0f\x67\x46\x10\x7a\x66\xc3\xee\x4f\xcb\xf8\x1d\x06\x08\xe1\x38\x2d\x37\x09\x27\xe2\xbd\xd3\xe0\x08\x9c\xe6\x60\xb1\x13\xd1\x65\x38\xc1\x1b\xa7\x0d\x41\x39\x88\x79\x3a\xe4\xf2\xf4\xfb\xeb\x80\x4f\x7d\x3a\x14\xee\xe9\x08\x24\x4e\x8f\xf0\x2e\x4e\x87\xe7\x7a\x3a\x6d\xe9\xb9\x42\xcc\xd3\xb5\xb1\x0c\xd5\x20\xe3\xe9\xd6\x0d\xa3\xdd\xbf\x68\x34\xa1\x51\x4e\x9f\x85\xb0\x59\x38\xe7\xda\xd6\x8c\x2b\xe3\x3b\xd6\x3e\x85\x6b\x9a\xa4\xc5\x64\x70\x73\x4e\xb5\x0a\xd8\xf9\x3d\xe2\x6a\xd1\xb9\xac\x49\x9c\x3f\x22\x5c\x9a\xc7\xfd\x05\x97\xe6\x11\xb7\xcc\x32\xb8\x82\x0f\xa8\x99\x40\x4d\xf3\x88\x79\x95\x17\x84\x9f\x8f\xe8\x20\xda\x23\xbe\xf0\x63\x9c\xf6\x90\x8d\xa7\x3a\x0f\xba\x67\x0f\xfa\x2e\x0f\xc9\xb0\x21\x0f\x81\x3c\x3c\xa4\xac\x1a\xf8\x7d\x0f\xf1\x82\x25\x3c\xee\x6f\x37\x41\xf6\x42\x29\x43\x89\x87\xc2\xe5\x09\x8f\xfb\x4d\x5f\xe9\xa1\xa7\x4a\x95\xf0\x80\x74\x3f\xb4\xa0\x97\x22\xfe\xd2\x18\x1e\x96\x80\xe5\x87\xc1\x17\x7f\x18\x10\x80\xc2\x27\x00\x7d\xc2\x87\xc1\x7b\x78\x58\x35\xd4\x57\xd6\x2e\x50\xa0\xd0\x1e\x3c\x2d\x7e\x18\xac\x40\x78\xd8\xa7\x85\xc7\x84\x99\x7f\x4c\x9e\x62\x3f\x26\x4f\x56\x1f\x44\xff\x63\xca\x05\x08\x2f\xfe\x01\x65\xf0\x98\x7f\x5b\xf8\x2d\xb0\x7e\x8f\x59\x34\xef\x82\x14\x99\xba\xb3\x89\x47\x44\xbc\xf8\x18\x16\x14\xbe\x7d\xd0\x5d\x62\x0e\xba\x2b\x78\x0a\xae\x76\xb6\xa0\x67\x96\xae\x11\xe9\xfd\x1b\xf4\x9c\x68\x91\xe5\x64\x32\x3b\x85\x55\x4b\x84\x0c\xac\x68\x5d\x0b\x4d\x8f\x96\xb6\xa0\xc0\x4f\xd1\xb2\xec\x86\x96\x36\xa1\xf3\xa1\xec\x10\x2a\xdf\xef\xba\x6b\x92\x00\xb7\x6c\x20\xa1\x22\xd5\x7a\xd0\x7a\x6b\x5d\xe2\xa4\x95\x3e\x8c\xd6\x42\x7f\x54\x6b\x99\x15\xb5\x15\x32\xa9\xb5\xd3\x99\xd1\xda\x07\x59\x4f\x61\xdc\x11\xc1\xdd\xef\x3a\xb4\xa0\x66\x00\x2b\x5a\xef\x5f\x60\x53\xeb\xa5\xb4\xa3\xea\x31\x28\x38\x5b\x7d\x9d\x49\x6a\xcf\x04\x08\xda\x9f\x71\x8b\xf9\x7e\x23\xc5\x16\x9f\xb1\xac\xc4\xe3\x86\x4a\xdf\x61\x2b\x9e\x64\xda\x27\x4f\xef\x9e\xf1\x55\x58\x26\x87\x84\xa7\xb8\x42\xb1\x3c\xb5\x42\xdd\x3f\xcd\x2b\x78\xf5\x69\x6e\x1b\x92\x4b\x6a\x78\xda\x67\x0c\xcf\x29\x88\xf8\x9f\x53\x2e\xe9\x48\x5e\xe1\x39\x4f\x7a\x72\xcf\x79\x1a\xc0\xe4\x08\x93\x28\x78\x4e\x44\xab\xcf\x59\x4f\xcc\x38\xeb\x2a\x02\xbe\x9f\xf7\x6f\x53\x84\x4c\x4f\x7a\x8c\x4f\x9e\xd0\x3e\xe7\x25\x55\x73\x78\xce\x17\xf8\xf0\xff\xe0\x51\xfc\x9f\x41\x33\xe6\xb8\xa9\x05\xe8\x19\x42\x47\xc9\x8e\xcf\x1d\x51\x53\xc8\xf1\x64\x60\x94\xef\xaf\xd3\x11\xc1\xe6\x78\xc2\x30\xe4\x08\xae\xce\x11\x71\x63\xbe\xbf\x0a\x64\x0d\x69\x8b\x1c\x81\x2d\x2a\x44\x33\xc7\x7a\x32\xa2\x5b\x87\x84\xf9\xfe\x6a\xfa\x0a\x99\xde\x5d\x8e\x88\x68\xf2\xfd\xd5\xc7\x1a\x7a\x30\x37\xe4\x03\xdf\xea\x21\xc7\xe9\x92\x43\x8e\xf0\x38\x73\x7c\x59\xc8\x60\xcc\x2c\x7f\x06\x18\x36\x50\x00\xe1\x5b\x64\xc1\x5a\xe4\xfc\xab\x39\x57\xc8\x95\xe5\x09\x11\xc8\x52\xcf\x19\x91\x60\x33\x70\xfe\x00\xd9\xd0\x1a\xa3\x27\x70\xf7\x2a\x18\x9c\x62\x60\x23\x72\x61\x84\x4f\x81\x0d\xca\xba\x41\xd6\x76\x7c\xb8\x85\xac\x09\x93\xde\xef\x1d\xd3\x2a\x82\x92\x80\x58\x1f\x8b\x84\xe0\x66\x3d\x85\xcd\xb0\xb3\xfb\x5d\xe0\x26\x67\x25\xf3\x64\x2d\x0d\xe8\xd6\x9a\x50\x06\xe3\x9b\xef\x77\x15\x74\xaa\x50\xd5\x48\x59\x0f\x3f\x8f\xdd\xff\x4d\x45\x2b\xe8\xc8\xcc\xb3\x6f\xb8\xdd\xce\x84\x23\xc1\x7b\xc8\x20\x16\x60\x21\xe4\x4e\x79\x06\x91\x33\xaf\x84\x72\x96\xba\x12\xa2\x33\x9b\xaf\xe4\xc2\x06\xf2\xbc\x34\x06\xda\x99\xfc\xe7\xa8\x67\x4b\xcc\xc0\x7d\xc9\xf7\xcf\x09\xf7\x2e\xdb\x89\x99\xa0\xba\x40\x46\x84\xd7\xd9\xe0\x01\x50\x56\x32\xa3\x99\x3c\x11\x6b\xe6\xc9\x39\xe1\x8d\x64\x72\xcc\xac\xd2\x43\x9e\x0d\x9f\x3c\x57\xcf\x13\x2b\x9c\xaf\x50\x62\x82\xa5\x29\x11\x1a\xb9\xc4\x1d\x1b\x2b\x71\x77\x01\x84\x6d\x2f\x51\xd8\xa3\xc4\x43\x51\x75\x2e\x88\x82\xfb\x8d\xfe\x19\xc1\x4e\x59\xf7\x4b\x85\xa7\xc5\x25\x66\x54\x97\xfb\x0b\x70\xe3\xf7\x1c\xa1\xf0\xac\xb7\x44\xe0\xbc\xc4\xca\xd0\xb7\xd0\xf4\x97\x58\x95\xbe\x77\x81\x47\xc3\x52\x36\xe9\x84\x1c\xf7\xfe\x0f\x8c\x5d\xe0\x81\x97\xfb\xeb\xdf\x54\xe6\xd0\xd4\x39\xa8\x0b\xf3\x87\x66\x24\xd0\x84\x25\xf2\xca\xa3\xdc\x5f\x5e\x8c\xa5\x94\xaa\x12\x7d\x48\x47\xf2\x42\xbf\xce\xf1\x3a\xcf\x03\x4b\xec\x7a\xa1\x70\x70\xe0\x41\x3f\xb5\xc4\xa1\xd8\x26\x2f\x1d\xcb\xfd\xf5\x01\x6d\x56\xe2\xa7\xa1\xc9\xcb\x3c\xc5\x50\xe8\x0e\x16\xd9\xd7\xee\x65\x57\x4c\xfb\xbd\x4f\xe6\x9e\xba\x4a\x9f\xe8\x21\xe0\x03\x24\x5c\x0a\x02\x7c\x4c\x81\x40\x09\xb0\xc3\xf5\x29\xf4\x53\x8a\xd4\xfb\x37\x14\xf1\x04\x95\x50\xe0\xbd\x9c\x53\x30\x2c\x3d\x80\x82\x2d\x48\x5f\xa3\x00\x41\x08\x4b\x50\x3b\x8c\xcd\x49\x31\x79\x25\xcc\xac\xb0\x3f\x05\x3a\xbd\xa8\xf0\xae\x85\xd6\xad\x00\x55\x9a\xe3\xc9\x82\x4c\x83\x51\x34\xaf\x95\x71\x93\xc4\xf1\x0a\xd6\xa1\x55\xff\xca\xc0\x39\x45\xad\x49\x28\xf4\x96\x8a\x02\x87\xda\x17\xb6\xb4\x73\xd8\xce\xb6\x90\xd8\xc2\xe5\x5a\x7a\xc0\x2d\xfa\x5f\x1c\x5a\x6c\x47\x66\x87\x41\x2f\x06\xce\x33\xd2\xdd\x60\x22\x8b\x65\xe1\x37\x04\xb1\xd8\x0a\x7d\x8b\x15\x0c\x8f\x20\x3f\x31\x15\x8e\x00\xf6\x2f\xb6\x1a\xc0\xa1\x29\x46\x0f\xab\x18\x6f\xc2\x8a\xd1\x0f\x06\x96\x99\x71\x7e\x77\xd6\x43\xd3\x14\xeb\x1c\xac\x33\x04\x2d\xc6\xeb\xcc\x42\xa1\x2c\xf7\xcf\x85\x9d\x18\xb8\x64\x52\x38\xe6\x8e\x46\x53\x10\x99\x14\x1e\x48\x96\x49\x8b\x59\x26\x44\x04\xd9\x13\x72\x33\x9f\xe8\x4f\xe2\xaf\x83\xd1\x32\x33\x21\x19\x7f\xde\xff\x09\x26\x9d\x8e\x05\x50\xc2\xee\xdf\x9e\x26\x30\x31\xbb\x10\x9e\xab\x50\xd9\xae\x67\x0b\xf5\xfe\x42\xe4\x57\xe3\x42\x1f\xec\x18\x72\x70\x0b\x6b\x5c\x61\x40\x8d\x60\xd0\x1a\x79\xe8\x5b\x63\x8f\x39\xd4\x38\x16\xc4\xb6\x6a\x1c\x9c\xb2\xde\x5f\xb3\x0b\xda\x5f\xac\xbc\x30\xc4\xc5\x63\xfb\x2a\xb0\x44\xf5\xfe\xe6\xa9\x4e\xa5\xe2\xaa\x72\x1a\x4b\x05\x7c\x52\xa9\xb7\x2b\xfc\x31\x64\x06\xc0\x1c\xac\xb8\xd8\xf8\x82\xfe\xa8\xbc\xe6\xa9\x90\xbe\xaa\xb2\x65\x94\xb0\xad\xde\xff\xc9\x8b\x09\xa6\x79\x8f\xd5\xe2\x92\x1c\xaa\x6d\x59\x5e\x31\x54\x83\x55\xa9\xf7\x0f\x99\xaf\x52\x3c\x2a\x83\xa3\xca\x73\xaf\x0a\x8f\xba\xda\xd0\xc4\x8a\x0b\xce\x47\xb5\x0b\xc4\xa8\xc6\x45\xcd\x4d\x42\x9d\x29\x86\x7a\xff\xa6\x2c\x28\xd9\xe9\x45\xf3\x20\xac\xd2\x07\xac\xb0\xf4\x80\xaf\x50\x27\xd1\xfb\x5b\xc0\xe5\x75\x0e\x4c\x68\xb1\x6b\x0f\xc6\x9b\x2b\xdb\xb4\x37\x24\x4f\xec\xc0\xe0\xa3\xda\x0a\x6b\x6d\xeb\xe2\xd8\xb5\x6d\xeb\x10\xcd\x36\x2c\x00\x01\x9f\x31\x4e\xb3\x74\x7f\x43\x91\x61\x4b\x50\x62\x06\xac\x10\x99\x96\x5c\x82\xa5\x11\x2f\x7c\x8f\xb9\x31\xcb\xd3\x4a\x4b\x3c\x44\x87\xe6\x07\xd3\x1a\x6d\x9b\x41\xa3\xd8\xae\xa0\x9b\xf1\x64\xc2\xd6\x39\xa2\x1d\x74\x41\x6d\x9d\x2f\xd9\xb1\xce\x68\x69\x27\x8c\xc7\xb4\x86\x68\xd0\x9e\x16\x2c\xc7\x60\x59\x20\x1c\x96\x0f\xa0\xcd\x32\xd8\x82\x57\x10\x3c\x98\xe6\x89\x9a\xe5\x0b\x44\xb1\xb2\x65\x3d\x2d\x18\x8c\xaf\xc1\x79\xb0\x86\x00\xd8\xda\x62\xc0\xfb\xa7\x01\x8f\xd6\xf8\x44\xc2\x96\x5f\xb9\xde\x58\xdc\x3f\x8d\x27\x23\xc6\x0b\x6d\x0b\xe6\x7f\x4c\xcb\x93\x39\x47\x92\xc3\xfd\xe3\x1b\xa2\x44\xaa\x4f\xc8\x2a\xaa\xe5\x19\x51\x71\x12\x67\x7e\xc2\x19\x34\x3f\x27\x68\x67\xbe\x8e\x18\xcd\xf5\x64\x5b\xea\x54\xc3\x36\xfd\xdf\x3a\x07\x36\xde\x51\x5b\x8f\x3c\xc5\xb4\x9e\x20\x5a\xd6\xe5\x85\xd1\x40\x0d\x8a\xa8\x0d\xaa\x09\x03\xcf\xda\xb5\x66\xbc\xc0\x02\xf7\xcf\x07\x37\xfe\x71\xbf\x4f\xe8\x0c\xfb\x5c\x13\xbe\xe0\x93\x37\x9e\xe0\x34\x9a\xc5\x16\x05\x73\x37\xc4\xe0\x35\x86\x06\x53\xd8\xe2\xfd\xee\x28\x7a\x46\x47\x2e\xf3\x8a\xad\xc5\x9c\x98\x83\x0e\x68\xf7\x57\xc6\x04\x8d\x97\x62\x2d\x66\x5b\x09\x88\xdd\x62\xc5\x2f\x66\xb4\xaa\xca\x4e\x95\x2e\x46\x8b\xf7\x7f\x3c\x9a\x6c\xb1\xdd\x5f\x80\x92\x01\xb9\xfd\x16\xff\xd1\x2d\x6d\x7c\x20\xd0\xa2\x33\x08\x6f\xd1\x65\x07\x54\x96\x19\xc6\xf4\x16\x39\x35\x70\xc5\xbc\xc7\x83\x79\xf6\xee\xec\x0d\xd5\xd3\xe2\xf2\xc3\x1a\xd8\xb7\x21\xe6\x0e\x2d\x2e\xa0\x28\xa0\x74\x34\x5e\x61\x35\x9e\x84\x34\x70\x70\x8b\x9f\x6c\x2f\x91\x57\xc7\x4d\x68\xb2\x1a\x58\x31\x22\x79\x20\xb3\x63\x77\x82\xa8\xa7\x51\xaf\x34\xd1\x2a\xa1\x49\xe6\x77\xde\x79\x7c\xd8\x24\x0b\xba\x64\x05\x07\x37\xc9\x59\x9e\x4c\x09\x20\xd4\x0d\xe6\xb3\x81\xf7\xd1\x6d\xdd\xfd\x35\x59\xd0\x50\xd4\x60\x34\x9a\xfc\x5b\x47\xb9\x6d\x2d\xc1\x61\x9f\x9b\xd0\x26\xb4\x75\x45\xd6\x84\xbe\x02\x22\xa3\xc4\x76\x99\x65\x45\xb9\x13\xe7\xf4\xde\x8d\xb3\x75\x02\xcc\x7e\x7f\x77\x58\xc1\x06\x8e\x83\x1f\xdb\xee\xef\x11\xb9\xba\xe1\xf7\x0f\xb4\x4d\x93\x17\x7e\x93\xb5\x3c\xae\x6b\x9a\x1e\x5c\xa0\x0a\x7e\x3b\x56\xa4\xf4\x2d\x9b\x72\x25\xfa\x84\xd7\xd8\x94\xa8\xd0\x6c\x60\x35\x2d\x4a\x9d\xb1\xb6\xa3\x15\x4e\x76\xd3\xca\xe6\x6b\x68\x08\x75\xd3\x86\x4f\x27\x8d\x94\x38\xd1\xce\x5b\xac\xc6\x7d\xd0\x5b\x6d\xba\xc8\xa2\x2f\xec\x20\xc7\x05\x2b\xc0\xe0\xe7\x27\x21\x86\xce\x02\x63\xdd\x32\x04\xa0\xd1\xc1\x6c\x79\x62\x6d\x99\xa6\xa3\xf1\xe2\xac\xc1\x35\x6d\x46\x5c\x52\x31\x35\x13\xb4\x31\xe9\x90\xbc\x66\x64\x77\xcb\x52\x01\x35\xad\x42\x48\x71\xb3\x0c\x76\xb1\x02\x2d\xd4\x8c\xa7\x37\x8d\xb3\x58\xc1\x46\xa8\x45\x9a\xf9\xd2\x17\x6d\xd9\xe8\x06\x91\x46\x65\x17\xd6\x76\x85\xfd\x6d\x06\x2d\xd8\x6c\xac\xd3\xde\x46\x81\x6e\x30\xd6\x8d\x17\x00\xcd\x25\xd9\x0b\xc9\x39\x89\x47\x97\xa2\x2c\x86\xda\x6c\x0e\xd5\xde\x5c\x2e\x96\x91\xa4\x7e\xbf\x6b\x82\x41\x6d\xae\x7f\x52\xe0\x0a\xf5\xde\xdc\xd0\x83\xaf\x74\x9a\x5b\x5a\x5d\x6d\x9f\xd4\x09\x6e\xa4\xa1\xdb\xc1\x87\x2e\xcd\xed\x74\x92\xd3\x0d\xcb\x74\x2b\x64\x1f\xa7\x8f\xd2\xdc\x1a\x67\x84\xb6\xe1\xa4\x53\x36\x70\xd1\xef\x96\xc9\x86\x33\x3d\x60\x5a\xda\x84\xa6\x6c\x70\x35\x90\xa1\x8e\xff\x53\xa7\x6d\xe6\x13\x99\x0c\x49\x9a\x99\x31\x4d\x9b\xb9\xb1\x06\x2b\x23\xbd\xf8\x4c\xa6\x81\x09\x33\x13\x64\x80\xe1\x09\x2e\x0b\x6d\xfa\xfd\x1d\xfe\x4d\x81\x17\xf1\x6f\x42\x0b\xfe\x9b\x52\x56\xc6\x85\x49\xb7\xf0\x6f\xd2\x6a\xc3\x31\x2f\xd0\xe8\x70\xba\x93\x20\x81\x9e\xf7\xfb\x8b\x77\x20\x1e\x37\x8d\x80\xf8\x5c\x94\xf3\xb8\x6b\x8a\x39\x38\x23\x04\xa2\xc3\x23\x28\xec\xeb\xbc\xcf\x11\x97\x06\xe7\xe1\x83\x23\x28\xdd\x99\x1b\x80\x9d\x35\x9d\x8d\x59\xf0\x09\xf0\x42\x96\x97\x9a\x2e\xff\x7b\x52\xe8\xf2\xf7\xda\xc0\x65\xbd\x6e\x71\xe1\x2b\x0e\x17\xbe\x62\x80\x29\x1c\x31\xf0\xc5\xc6\x0b\x95\xeb\x02\xd7\x25\xb9\x30\x3b\x08\x79\xbd\x07\x8d\xe9\xb2\xf3\x28\xd6\x65\x67\x0c\xe5\x72\x50\xfb\xb8\xac\xc3\x59\x97\xf5\x6a\xc7\xe5\x98\xa7\xa2\xfc\x84\xe4\x3b\x6f\x68\x5c\xce\x8c\x26\x27\x19\xcb\xe5\x71\x7f\xa3\x25\x84\x77\x1d\xc8\xd2\xb8\xb9\x64\xee\x49\xb2\x5c\x4c\x14\x6e\x88\x43\xcd\xb1\x61\xb6\x67\x70\xd2\xc1\x65\x45\x11\x3c\xdf\x77\xa9\x08\x77\x5d\x78\x68\xe4\xd4\x0b\x2e\x8d\x67\x03\x2e\x4d\x06\x4b\x9b\x71\xe6\x36\x34\x07\x97\x8e\x5f\x8a\x44\x47\x87\x42\x70\xe9\x4d\xd8\xa1\x2f\x38\x8b\x60\x89\x43\x1d\xd9\xc1\xa3\x2e\x47\xe4\xcd\xea\x59\x39\xe8\x75\x7f\x63\xa4\x8b\x8a\xc4\xe5\x33\x40\x77\x7a\xa0\xce\x74\xde\xef\xc3\x30\xef\x11\x09\x29\xa7\x47\x0c\x7e\xbf\x4f\x92\x54\x4f\x2c\x5b\x2b\x9f\x26\xb9\x2e\x6d\xcd\xd3\x68\xd7\x7f\x13\x72\xc3\x47\x33\xae\x03\xbb\x84\xea\xe1\x45\x8f\xf3\x9a\x0f\x92\x06\x00\xff\xc7\x6d\x5f\x10\x94\xb3\xf5\xba\xcd\x0d\xd4\xb4\xe7\xea\x01\x42\x19\x7d\x38\xb7\xd2\x58\x53\xf1\xc3\x3a\xe9\xc4\xb8\x35\x82\xd5\x04\xb3\xd2\xf7\x77\x63\x70\xeb\x7c\x0a\xe8\x73\xbb\xdf\x80\x58\x36\xbc\x45\x87\x88\x04\x9f\x24\x31\x4f\x01\x9c\x81\xa7\x2f\xbf\xde\xe1\x38\xf8\x44\x84\xeb\xb3\xb0\x53\xe3\x2b\x48\x9e\xb2\xfb\x1c\x68\xdb\x21\x27\xbb\x85\xce\x73\xd4\xce\x23\x9f\xce\xdb\x8d\x1e\x61\x1e\x7a\x3c\xe3\x0b\xd0\x57\xab\x1c\x01\xd6\x27\x16\xdb\x23\x44\xbd\xc7\x25\xea\x3d\xe6\xbf\xa4\xb3\xdd\x60\x83\xb9\x03\x5e\x1c\xad\x6c\xa8\xf8\x3b\xc1\xef\xb1\xd2\x1d\xea\xb1\x0a\x6b\x2b\x22\x94\x1e\x2b\x05\x87\xc7\xbc\x9d\x87\x15\x3d\x36\x00\xf8\x07\x3d\xfa\xce\x85\x47\x1f\x60\xe3\x1e\xfb\x60\x27\x3e\xa7\xe9\xbc\xe4\xe9\xf1\xc3\xf8\x3c\xa9\xff\xef\x38\xa8\x4b\x32\x00\xb0\x12\xd2\x11\x43\x97\x3d\x74\x39\x27\x96\x2f\xda\x43\xe7\x25\x7e\x97\x7c\xa1\xae\x20\x9e\xef\x52\x48\xcc\x4e\x26\xea\x52\xa1\x43\x79\x3f\x98\x99\x30\xb7\xfc\x9b\x2e\x4d\xd1\xe4\x1f\xcf\xaf\x3b\x70\x29\xae\x02\xb8\x30\xb3\x0e\x89\xbb\x74\x0a\x48\xff\x3b\x52\xea\xc2\xcc\xf8\x2b\xbc\x88\x52\xf9\x20\xc0\x4a\x15\xf6\xb8\xaf\xeb\xa2\xae\x70\xa7\xba\x9e\x58\x26\x2f\xae\xfb\xfd\xce\x11\x08\xd5\x0c\xf5\xdf\x35\x0b\x5f\x82\xf6\xb5\xea\xfb\x5d\x36\x63\xe3\xc2\x42\x87\x77\xd2\xb5\x0f\x18\xc4\xce\xe3\xa1\xae\x7c\xa6\xdc\x69\x3a\x3b\xbd\xff\x4e\xab\xd9\x2d\xe3\x17\x5b\x44\xb2\x93\xf8\x96\x79\x73\xdc\xef\x1f\xfa\x8a\xdd\x78\x29\xd7\x2d\xcf\x3f\x24\x1b\x0f\xc9\xbb\x55\x48\x42\xb7\xba\x5a\x55\x38\xc2\xdd\x2a\xa5\xa9\x1b\x47\x6c\x99\x3d\xd7\x6b\x81\xce\xab\x89\x6e\xbe\xee\x79\x3b\x0a\x91\xef\x8b\xc0\xf7\xcf\x20\x27\x4c\x04\x83\x7d\x6e\x40\xe3\xa4\x9d\xeb\x34\x44\x7d\xca\x89\x69\xe9\x89\xf6\xe5\x59\xf5\x15\xfa\xf6\x79\x38\x9b\x33\x3c\xea\x33\x2f\x26\xe1\x3d\x52\x9f\x70\xbf\x98\x92\x85\xe7\x32\xf0\x7d\x36\xaa\xb5\x3e\xf1\xed\x89\x5f\x7f\x63\xfa\xc9\x86\x9d\x63\x41\x93\x8d\xc8\x27\xea\x23\x6e\xd0\x18\x48\x73\x04\xbc\x7f\xc3\x58\x15\xd0\xe3\x7c\x0f\x3a\x22\xb6\x3c\xe8\x74\x8f\xb8\x4e\x1b\xd7\xeb\xc5\xb1\x84\x66\xc4\x42\x3b\x31\x62\x81\x84\x0f\x5a\xa1\x11\xeb\x1a\xb8\xa1\x5d\x03\x03\x8c\x08\x4e\x1b\xb1\xad\x4e\xff\xa6\xae\x41\x7c\x47\x9d\x0b\xbf\xa1\xe8\x46\xf4\x27\xd8\x6b\x44\xb7\x01\xe8\x18\xcf\x59\x32\x66\x7c\xa2\xf9\x64\xd9\x0b\x45\xb4\x5f\x43\xf8\xca\x65\xd0\x2d\x1e\x92\x30\xf2\xfd\x9d\xf8\x46\x66\xc8\x13\x6c\x30\xe4\x29\x0e\xa8\xcc\xa0\x85\xe4\xfb\xfb\x40\x24\x42\xce\x1a\x02\x65\x33\xd6\x63\x81\x21\x35\xbe\x00\x77\x76\xaa\x0b\x6a\x07\xec\xa8\x36\x5e\xbe\x21\x9c\xe0\xb6\x04\x18\x1f\xf7\xb7\xf3\xd9\xdd\x10\xaf\xd0\x58\x03\x2e\x2f\x7a\x76\xf6\xec\xc6\x35\xf6\x81\x20\x70\x08\x63\x91\x41\x81\x19\xf2\x0a\x43\xa1\xc4\x86\x6e\x93\x27\x6a\x43\xa5\x34\xe4\x29\xc4\x43\x79\xcd\x34\x14\xfc\x33\x14\xfa\x66\xe8\x93\x03\xf0\x02\x64\x28\xcf\x86\x07\x9c\x0a\xec\x0f\x7e\xd0\xe0\xa3\xaf\x01\xcb\x30\xee\x77\x83\x75\x19\xca\x21\xd9\xed\x6f\x16\xb2\xd6\xb8\xdf\x43\x56\xff\x01\xf5\x3b\x14\xb8\xb5\x45\x67\xdb\x18\xe9\x0f\x83\x62\x1d\x96\xb8\x43\xc3\x2c\x76\xa2\x3a\xf3\xb3\xb0\x92\x55\xe4\x11\x6b\x2c\x68\x12\x06\x5f\xb5\x8d\xfb\xc7\xe3\x47\x18\xc6\x30\x7f\x98\x17\x2a\x0f\x98\x48\x61\x9e\xa0\x09\x07\x73\xac\x85\xcf\x4c\x86\xf9\x98\x9c\xa6\xe3\x87\x3d\xf0\x6d\xd5\x80\xb3\x87\x9c\xc7\x8d\x7c\xea\xeb\x3e\x7e\xbd\x48\x1e\xff\xbb\x0b\x1c\x8e\x48\x72\xf0\xf6\x73\x78\x2c\xfc\x86\xbf\xb5\x4c\xf2\xf0\x08\xcf\x6e\x38\x5f\xdb\x0e\xbf\xbf\x37\xcb\x61\xc0\xbf\x45\xa9\x2c\x0c\xba\x54\x00\x6e\x08\x4e\xc0\x70\xdd\x26\x20\x87\x46\xb4\x30\x9c\xcf\xf8\x86\xeb\xac\x07\x0a\xed\x10\x26\x85\x95\xb4\x98\x83\xc6\x72\xf0\xe1\xea\x70\x38\xd5\xc3\x27\xcb\xf9\x4c\x75\xf8\x04\xf3\xcf\x6d\x5d\xeb\x8e\xb9\x59\x18\x93\x6f\x14\xc6\x84\xf9\x19\x34\x86\xe3\xfe\xad\x92\x99\x90\xb9\xa7\xf3\xf9\xe9\x98\xce\xd3\xc1\x31\xe1\x71\x0c\x3e\xaf\x9e\x1b\x23\xa5\xfb\x37\x33\x66\x9c\xd0\x72\x39\xcc\x65\xa5\xe8\x8a\xcc\xaa\x17\xe2\xb1\x30\x2b\x7e\x50\x8b\x0c\xb1\xa6\xd3\x09\x9d\xbe\x49\x98\xbe\xae\x7c\x27\x62\x2b\xfe\x0d\x64\xf6\xc9\xe7\x4a\xeb\xce\x69\x0e\xe3\xab\x8f\x79\xc5\x70\x21\x0c\xba\x62\x02\xcb\x5d\x91\x6f\xc2\x2e\x3e\xe4\xbf\x40\x85\x2b\x2a\x0b\xd6\xd1\xed\x15\xb3\x84\xeb\x2f\x7e\xbf\xf8\x6e\xea\xe2\xa3\x56\x94\x5d\x93\x2d\x4a\x83\x1f\x75\x45\x47\xc6\x95\x03\x91\x6d\x2f\x84\xc6\x97\x90\x15\xaf\x75\x59\x72\xc9\xe3\x7e\xf3\xc0\xef\x02\xd9\x24\x5c\xf2\x94\x57\xe0\x21\xd6\x25\x34\xfa\x97\x64\x43\x09\x56\x21\x7c\x11\x7b\x51\xb8\x2e\xa9\xc2\x81\x2a\xd7\x2a\x40\xcd\x45\xee\xbc\xa4\xce\x1e\x2e\xb6\xe4\xad\xf2\x25\xbe\x11\xee\x98\xc0\x85\xbd\xfd\x49\xc8\x25\xf9\x40\x63\x20\xe4\x52\x30\xdd\xa5\x1b\xb4\xf5\xc5\xa3\xa4\xeb\x7e\x27\x5e\x0c\x5d\x8a\x8e\xf7\x1b\x06\xe7\xd2\x1d\xd8\xbc\x14\x7e\x31\xef\xef\xa4\x87\x8b\x5e\xde\xa5\x19\x3f\xec\x40\x6b\x84\xd0\xf3\xc5\xd6\xa5\xf7\x7f\x90\x93\x4b\x2d\xdf\xef\x1a\x2e\x05\x61\x2f\x75\x20\x59\x7d\xcc\x3d\x5c\xda\x89\xca\x77\x67\xb0\xbe\x5c\xcd\x4b\x47\xe4\x09\xe0\xa5\x93\xdd\xaf\xf8\x02\x24\x6e\x14\x76\xfe\xd2\xcb\xc2\x65\x99\xf7\xa7\x97\x65\xba\xb3\x97\x65\x62\xc0\x1c\xcd\xe9\xd3\x5d\x08\xa7\x2f\x20\x93\xd6\xeb\x9a\x7c\x98\xf9\xc9\x0b\xec\x4f\xf8\xc7\x9f\x94\xa0\x4f\xe8\xd5\x4f\xde\x48\x7e\x42\x71\x7d\x42\x6b\x7c\x42\x6b\x7c\xda\x39\x3d\xbc\xe2\x01\x02\xbf\x78\xd4\xfa\x8a\x0d\x22\xf9\xe2\x1b\x85\x97\x55\x00\xe8\xfe\xd7\x2c\x00\xb0\xb5\xff\x1f\x00\x00\xff\xff\x11\x91\x1a\xde\x5b\x35\x00\x00")
-
-func keysWordlistSpanishTxtBytes() ([]byte, error) {
- return bindataRead(
- _keysWordlistSpanishTxt,
- "keys/wordlist/spanish.txt",
- )
-}
-
-func keysWordlistSpanishTxt() (*asset, error) {
- bytes, err := keysWordlistSpanishTxtBytes()
- if err != nil {
- return nil, err
- }
-
- info := bindataFileInfo{name: "keys/wordlist/spanish.txt", size: 13659, mode: os.FileMode(420), modTime: time.Unix(1497960590, 0)}
- a := &asset{bytes: bytes, info: info}
- return a, nil
-}
-
-// Asset loads and returns the asset for the given name.
-// It returns an error if the asset could not be found or
-// could not be loaded.
-func Asset(name string) ([]byte, error) {
- cannonicalName := strings.Replace(name, "\\", "/", -1)
- if f, ok := _bindata[cannonicalName]; ok {
- a, err := f()
- if err != nil {
- return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
- }
- return a.bytes, nil
- }
- return nil, fmt.Errorf("Asset %s not found", name)
-}
-
-// MustAsset is like Asset but panics when Asset would return an error.
-// It simplifies safe initialization of global variables.
-func MustAsset(name string) []byte {
- a, err := Asset(name)
- if err != nil {
- panic("asset: Asset(" + name + "): " + err.Error())
- }
-
- return a
-}
-
-// AssetInfo loads and returns the asset info for the given name.
-// It returns an error if the asset could not be found or
-// could not be loaded.
-func AssetInfo(name string) (os.FileInfo, error) {
- cannonicalName := strings.Replace(name, "\\", "/", -1)
- if f, ok := _bindata[cannonicalName]; ok {
- a, err := f()
- if err != nil {
- return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
- }
- return a.info, nil
- }
- return nil, fmt.Errorf("AssetInfo %s not found", name)
-}
-
-// AssetNames returns the names of the assets.
-func AssetNames() []string {
- names := make([]string, 0, len(_bindata))
- for name := range _bindata {
- names = append(names, name)
- }
- return names
-}
-
-// _bindata is a table, holding each asset generator, mapped to its name.
-var _bindata = map[string]func() (*asset, error){
- "keys/wordlist/chinese_simplified.txt": keysWordlistChinese_simplifiedTxt,
- "keys/wordlist/english.txt": keysWordlistEnglishTxt,
- "keys/wordlist/japanese.txt": keysWordlistJapaneseTxt,
- "keys/wordlist/spanish.txt": keysWordlistSpanishTxt,
-}
-
-// AssetDir returns the file names below a certain
-// directory embedded in the file by go-bindata.
-// For example if you run go-bindata on data/... and data contains the
-// following hierarchy:
-// data/
-// foo.txt
-// img/
-// a.png
-// b.png
-// then AssetDir("data") would return []string{"foo.txt", "img"}
-// AssetDir("data/img") would return []string{"a.png", "b.png"}
-// AssetDir("foo.txt") and AssetDir("notexist") would return an error
-// AssetDir("") will return []string{"data"}.
-func AssetDir(name string) ([]string, error) {
- node := _bintree
- if len(name) != 0 {
- cannonicalName := strings.Replace(name, "\\", "/", -1)
- pathList := strings.Split(cannonicalName, "/")
- for _, p := range pathList {
- node = node.Children[p]
- if node == nil {
- return nil, fmt.Errorf("Asset %s not found", name)
- }
- }
- }
- if node.Func != nil {
- return nil, fmt.Errorf("Asset %s not found", name)
- }
- rv := make([]string, 0, len(node.Children))
- for childName := range node.Children {
- rv = append(rv, childName)
- }
- return rv, nil
-}
-
-type bintree struct {
- Func func() (*asset, error)
- Children map[string]*bintree
-}
-
-var _bintree = &bintree{nil, map[string]*bintree{
- "keys": &bintree{nil, map[string]*bintree{
- "wordlist": &bintree{nil, map[string]*bintree{
- "chinese_simplified.txt": &bintree{keysWordlistChinese_simplifiedTxt, map[string]*bintree{}},
- "english.txt": &bintree{keysWordlistEnglishTxt, map[string]*bintree{}},
- "japanese.txt": &bintree{keysWordlistJapaneseTxt, map[string]*bintree{}},
- "spanish.txt": &bintree{keysWordlistSpanishTxt, map[string]*bintree{}},
- }},
- }},
-}}
-
-// RestoreAsset restores an asset under the given directory
-func RestoreAsset(dir, name string) error {
- data, err := Asset(name)
- if err != nil {
- return err
- }
- info, err := AssetInfo(name)
- if err != nil {
- return err
- }
- err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
- if err != nil {
- return err
- }
- err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
- if err != nil {
- return err
- }
- err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
- if err != nil {
- return err
- }
- return nil
-}
-
-// RestoreAssets restores an asset under the given directory recursively
-func RestoreAssets(dir, name string) error {
- children, err := AssetDir(name)
- // File
- if err != nil {
- return RestoreAsset(dir, name)
- }
- // Dir
- for _, child := range children {
- err = RestoreAssets(dir, filepath.Join(name, child))
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func _filePath(dir, name string) string {
- cannonicalName := strings.Replace(name, "\\", "/", -1)
- return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
-}
+++ /dev/null
-package nano
-
-import (
- "bytes"
- "encoding/hex"
-
- "github.com/pkg/errors"
-
- ledger "github.com/ethanfrey/ledger"
-
- crypto "github.com/tendermint/go-crypto"
- wire "github.com/tendermint/go-wire"
-)
-
-//nolint
-const (
- NameLedgerEd25519 = "ledger-ed25519"
- TypeLedgerEd25519 = 0x10
-
- // Timeout is the number of seconds to wait for a response from the ledger
- // if eg. waiting for user confirmation on button push
- Timeout = 20
-)
-
-var device *ledger.Ledger
-
-// getLedger gets a copy of the device, and caches it
-func getLedger() (*ledger.Ledger, error) {
- var err error
- if device == nil {
- device, err = ledger.FindLedger()
- }
- return device, err
-}
-
-func signLedger(device *ledger.Ledger, msg []byte) (pk crypto.PubKey, sig crypto.Signature, err error) {
- var resp []byte
-
- packets := generateSignRequests(msg)
- for _, pack := range packets {
- resp, err = device.Exchange(pack, Timeout)
- if err != nil {
- return pk, sig, err
- }
- }
-
- // the last call is the result we want and needs to be parsed
- key, bsig, err := parseDigest(resp)
- if err != nil {
- return pk, sig, err
- }
-
- var b [32]byte
- copy(b[:], key)
- return PubKeyLedgerEd25519FromBytes(b), crypto.SignatureEd25519FromBytes(bsig), nil
-}
-
-// PrivKeyLedgerEd25519 implements PrivKey, calling the ledger nano
-// we cache the PubKey from the first call to use it later
-type PrivKeyLedgerEd25519 struct {
- // PubKey should be private, but we want to encode it via go-wire
- // so we can view the address later, even without having the ledger
- // attached
- CachedPubKey crypto.PubKey
-}
-
-// NewPrivKeyLedgerEd25519Ed25519 will generate a new key and store the
-// public key for later use.
-func NewPrivKeyLedgerEd25519Ed25519() (crypto.PrivKey, error) {
- var pk PrivKeyLedgerEd25519
- // getPubKey will cache the pubkey for later use,
- // this allows us to return an error early if the ledger
- // is not plugged in
- _, err := pk.getPubKey()
- return pk.Wrap(), err
-}
-
-// ValidateKey allows us to verify the sanity of a key
-// after loading it from disk
-func (pk *PrivKeyLedgerEd25519) ValidateKey() error {
- // getPubKey will return an error if the ledger is not
- // properly set up...
- pub, err := pk.forceGetPubKey()
- if err != nil {
- return err
- }
- // verify this matches cached address
- if !pub.Equals(pk.CachedPubKey) {
- return errors.New("ledger doesn't match cached key")
- }
- return nil
-}
-
-// AssertIsPrivKeyInner fulfils PrivKey Interface
-func (pk *PrivKeyLedgerEd25519) AssertIsPrivKeyInner() {}
-
-// Bytes fulfils pk Interface - stores the cached pubkey so we can verify
-// the same key when we reconnect to a ledger
-func (pk *PrivKeyLedgerEd25519) Bytes() []byte {
- return wire.BinaryBytes(pk.Wrap())
-}
-
-// Sign calls the ledger and stores the pk for future use
-//
-// XXX/TODO: panics if there is an error communicating with the ledger.
-//
-// Communication is checked on NewPrivKeyLedger and PrivKeyFromBytes,
-// returning an error, so this should only trigger if the privkey is held
-// in memory for a while before use.
-func (pk *PrivKeyLedgerEd25519) Sign(msg []byte) crypto.Signature {
- // oh, I wish there was better error handling
- dev, err := getLedger()
- if err != nil {
- panic(err)
- }
-
- pub, sig, err := signLedger(dev, msg)
- if err != nil {
- panic(err)
- }
-
- // if we have no pubkey yet, store it for future queries
- if pk.CachedPubKey.Empty() {
- pk.CachedPubKey = pub
- } else if !pk.CachedPubKey.Equals(pub) {
- panic("signed with a different key than stored")
- }
- return sig
-}
-
-// PubKey returns the stored PubKey
-// TODO: query the ledger if not there, once it is not volatile
-func (pk *PrivKeyLedgerEd25519) PubKey() crypto.PubKey {
- key, err := pk.getPubKey()
- if err != nil {
- panic(err)
- }
- return key
-}
-
-// getPubKey reads the pubkey from cache or from the ledger itself
-// since this involves IO, it may return an error, which is not exposed
-// in the PubKey interface, so this function allows better error handling
-func (pk *PrivKeyLedgerEd25519) getPubKey() (key crypto.PubKey, err error) {
- // if we have no pubkey, set it
- if pk.CachedPubKey.Empty() {
- pk.CachedPubKey, err = pk.forceGetPubKey()
- }
- return pk.CachedPubKey, err
-}
-
-// forceGetPubKey is like getPubKey but ignores any cached key
-// and ensures we get it from the ledger itself.
-func (pk *PrivKeyLedgerEd25519) forceGetPubKey() (key crypto.PubKey, err error) {
- dev, err := getLedger()
- if err != nil {
- return key, errors.New("Can't connect to ledger device")
- }
- key, _, err = signLedger(dev, []byte{0})
- if err != nil {
- return key, errors.New("Please open cosmos app on the ledger")
- }
- return key, err
-}
-
-// Equals fulfils PrivKey Interface - makes sure both keys refer to the
-// same
-func (pk *PrivKeyLedgerEd25519) Equals(other crypto.PrivKey) bool {
- if ledger, ok := other.Unwrap().(*PrivKeyLedgerEd25519); ok {
- return pk.CachedPubKey.Equals(ledger.CachedPubKey)
- }
- return false
-}
-
-// MockPrivKeyLedgerEd25519 behaves as the ledger, but stores a pre-packaged call-response
-// for use in test cases
-type MockPrivKeyLedgerEd25519 struct {
- Msg []byte
- Pub [KeyLength]byte
- Sig [SigLength]byte
-}
-
-// NewMockKey returns
-func NewMockKey(msg, pubkey, sig string) (pk MockPrivKeyLedgerEd25519) {
- var err error
- pk.Msg, err = hex.DecodeString(msg)
- if err != nil {
- panic(err)
- }
-
- bpk, err := hex.DecodeString(pubkey)
- if err != nil {
- panic(err)
- }
- bsig, err := hex.DecodeString(sig)
- if err != nil {
- panic(err)
- }
-
- copy(pk.Pub[:], bpk)
- copy(pk.Sig[:], bsig)
- return pk
-}
-
-var _ crypto.PrivKeyInner = MockPrivKeyLedgerEd25519{}
-
-// AssertIsPrivKeyInner fulfils PrivKey Interface
-func (pk MockPrivKeyLedgerEd25519) AssertIsPrivKeyInner() {}
-
-// Bytes fulfils PrivKey Interface - not supported
-func (pk MockPrivKeyLedgerEd25519) Bytes() []byte {
- return nil
-}
-
-// Sign returns a real SignatureLedger, if the msg matches what we expect
-func (pk MockPrivKeyLedgerEd25519) Sign(msg []byte) crypto.Signature {
- if !bytes.Equal(pk.Msg, msg) {
- panic("Mock key is for different msg")
- }
- return crypto.SignatureEd25519(pk.Sig).Wrap()
-}
-
-// PubKey returns a real PubKeyLedgerEd25519, that will verify this signature
-func (pk MockPrivKeyLedgerEd25519) PubKey() crypto.PubKey {
- return PubKeyLedgerEd25519FromBytes(pk.Pub)
-}
-
-// Equals compares that two Mocks have the same data
-func (pk MockPrivKeyLedgerEd25519) Equals(other crypto.PrivKey) bool {
- if mock, ok := other.Unwrap().(MockPrivKeyLedgerEd25519); ok {
- return bytes.Equal(mock.Pub[:], pk.Pub[:]) &&
- bytes.Equal(mock.Sig[:], pk.Sig[:]) &&
- bytes.Equal(mock.Msg, pk.Msg)
- }
- return false
-}
-
-////////////////////////////////////////////
-// pubkey
-
-// PubKeyLedgerEd25519 works like a normal Ed25519 except a hash before the verify bytes
-type PubKeyLedgerEd25519 struct {
- crypto.PubKeyEd25519
-}
-
-// PubKeyLedgerEd25519FromBytes creates a PubKey from the raw bytes
-func PubKeyLedgerEd25519FromBytes(key [32]byte) crypto.PubKey {
- return PubKeyLedgerEd25519{crypto.PubKeyEd25519(key)}.Wrap()
-}
-
-// Bytes fulfils pk Interface - no data, just type info
-func (pk PubKeyLedgerEd25519) Bytes() []byte {
- return wire.BinaryBytes(pk.Wrap())
-}
-
-// VerifyBytes uses the normal Ed25519 algorithm but a sha512 hash beforehand
-func (pk PubKeyLedgerEd25519) VerifyBytes(msg []byte, sig crypto.Signature) bool {
- hmsg := hashMsg(msg)
- return pk.PubKeyEd25519.VerifyBytes(hmsg, sig)
-}
-
-// Equals implements PubKey interface
-func (pk PubKeyLedgerEd25519) Equals(other crypto.PubKey) bool {
- if ledger, ok := other.Unwrap().(PubKeyLedgerEd25519); ok {
- return pk.PubKeyEd25519.Equals(ledger.PubKeyEd25519.Wrap())
- }
- return false
-}
-
-/*** registration with go-data ***/
-
-func init() {
- crypto.PrivKeyMapper.
- RegisterImplementation(&PrivKeyLedgerEd25519{}, NameLedgerEd25519, TypeLedgerEd25519).
- RegisterImplementation(MockPrivKeyLedgerEd25519{}, "mock-ledger", 0x11)
-
- crypto.PubKeyMapper.
- RegisterImplementation(PubKeyLedgerEd25519{}, NameLedgerEd25519, TypeLedgerEd25519)
-}
-
-// Wrap fulfils interface for PrivKey struct
-func (pk *PrivKeyLedgerEd25519) Wrap() crypto.PrivKey {
- return crypto.PrivKey{PrivKeyInner: pk}
-}
-
-// Wrap fulfils interface for PrivKey struct
-func (pk MockPrivKeyLedgerEd25519) Wrap() crypto.PrivKey {
- return crypto.PrivKey{PrivKeyInner: pk}
-}
-
-// Wrap fulfils interface for PubKey struct
-func (pk PubKeyLedgerEd25519) Wrap() crypto.PubKey {
- return crypto.PubKey{PubKeyInner: pk}
-}
+++ /dev/null
-package nano
-
-import (
- "encoding/hex"
- "os"
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-
- crypto "github.com/tendermint/go-crypto"
-)
-
-func TestLedgerKeys(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- cases := []struct {
- msg, pubkey, sig string
- valid bool
- }{
- 0: {
- msg: "F00D",
- pubkey: "8E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C93",
- sig: "787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400",
- valid: true,
- },
- 1: {
- msg: "DEADBEEF",
- pubkey: "0C45ADC887A5463F668533443C829ED13EA8E2E890C778957DC28DB9D2AD5A6C",
- sig: "00ED74EED8FDAC7988A14BF6BC222120CBAC249D569AF4C2ADABFC86B792F97DF73C4919BE4B6B0ACB53547273BF29FBF0A9E0992FFAB6CB6C9B09311FC86A00",
- valid: true,
- },
- 2: {
- msg: "1234567890AA",
- pubkey: "598FC1F0C76363D14D7480736DEEF390D85863360F075792A6975EFA149FD7EA",
- sig: "59AAB7D7BDC4F936B6415DE672A8B77FA6B8B3451CD95B3A631F31F9A05DAEEE5E7E4F89B64DDEBB5F63DC042CA13B8FCB8185F82AD7FD5636FFDA6B0DC9570B",
- valid: true,
- },
- 3: {
- msg: "1234432112344321",
- pubkey: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120",
- sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208",
- valid: true,
- },
- 4: {
- msg: "12344321123443",
- pubkey: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120",
- sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208",
- valid: false,
- },
- 5: {
- msg: "1234432112344321",
- pubkey: "459E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120",
- sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208",
- valid: false,
- },
- 6: {
- msg: "1234432112344321",
- pubkey: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120",
- sig: "716B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208",
- valid: false,
- },
- }
-
- for i, tc := range cases {
- bmsg, err := hex.DecodeString(tc.msg)
- require.NoError(err, "%d", i)
-
- priv := NewMockKey(tc.msg, tc.pubkey, tc.sig)
- pub := priv.PubKey()
- sig := priv.Sign(bmsg)
-
- valid := pub.VerifyBytes(bmsg, sig)
- assert.Equal(tc.valid, valid, "%d", i)
- }
-}
-
-func TestRealLedger(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- if os.Getenv("WITH_LEDGER") == "" {
- t.Skip("Set WITH_LEDGER to run code on real ledger")
- }
- msg := []byte("kuhehfeohg")
-
- priv, err := NewPrivKeyLedgerEd25519Ed25519()
- require.Nil(err, "%+v", err)
- pub := priv.PubKey()
- sig := priv.Sign(msg)
-
- valid := pub.VerifyBytes(msg, sig)
- assert.True(valid)
-
- // now, let's serialize the key and make sure it still works
- bs := priv.Bytes()
- priv2, err := crypto.PrivKeyFromBytes(bs)
- require.Nil(err, "%+v", err)
-
- // make sure we get the same pubkey when we load from disk
- pub2 := priv2.PubKey()
- require.Equal(pub, pub2)
-
- // signing with the loaded key should match the original pubkey
- sig = priv2.Sign(msg)
- valid = pub.VerifyBytes(msg, sig)
- assert.True(valid)
-
- // make sure pubkeys serialize properly as well
- bs = pub.Bytes()
- bpub, err := crypto.PubKeyFromBytes(bs)
- require.NoError(err)
- assert.Equal(pub, bpub)
-}
-
-// TestRealLedgerErrorHandling calls. These tests assume
-// the ledger is not plugged in....
-func TestRealLedgerErrorHandling(t *testing.T) {
- require := require.New(t)
-
- if os.Getenv("WITH_LEDGER") != "" {
- t.Skip("Skipping on WITH_LEDGER as it tests unplugged cases")
- }
-
- // first, try to generate a key, must return an error
- // (no panic)
- _, err := NewPrivKeyLedgerEd25519Ed25519()
- require.Error(err)
-
- led := PrivKeyLedgerEd25519{} // empty
- // or with some pub key
- ed := crypto.GenPrivKeyEd25519()
- led2 := PrivKeyLedgerEd25519{CachedPubKey: ed.PubKey()}
-
- // loading these should return errors
- bs := led.Bytes()
- _, err = crypto.PrivKeyFromBytes(bs)
- require.Error(err)
-
- bs = led2.Bytes()
- _, err = crypto.PrivKeyFromBytes(bs)
- require.Error(err)
-}
+++ /dev/null
-package nano
-
-import (
- "bytes"
- "crypto/sha512"
-
- "github.com/pkg/errors"
-)
-
-const (
- App = 0x80
- Init = 0x00
- Update = 0x01
- Digest = 0x02
- MaxChunk = 253
- KeyLength = 32
- SigLength = 64
-)
-
-var separator = []byte{0, 0xCA, 0xFE, 0}
-
-func generateSignRequests(payload []byte) [][]byte {
- // nice one-shot
- digest := []byte{App, Digest}
- if len(payload) < MaxChunk {
- return [][]byte{append(digest, payload...)}
- }
-
- // large payload is multi-chunk
- result := [][]byte{{App, Init}}
- update := []byte{App, Update}
- for len(payload) > MaxChunk {
- msg := append(update, payload[:MaxChunk]...)
- payload = payload[MaxChunk:]
- result = append(result, msg)
- }
- result = append(result, append(update, payload...))
- result = append(result, digest)
- return result
-}
-
-func parseDigest(resp []byte) (key, sig []byte, err error) {
- if resp[0] != App || resp[1] != Digest {
- return nil, nil, errors.New("Invalid header")
- }
- resp = resp[2:]
- if len(resp) != KeyLength+SigLength+len(separator) {
- return nil, nil, errors.Errorf("Incorrect length: %d", len(resp))
- }
-
- key, resp = resp[:KeyLength], resp[KeyLength:]
- if !bytes.Equal(separator, resp[:len(separator)]) {
- return nil, nil, errors.New("Cannot find 0xCAFE")
- }
-
- sig = resp[len(separator):]
- return key, sig, nil
-}
-
-func hashMsg(data []byte) []byte {
- res := sha512.Sum512(data)
- return res[:]
-}
+++ /dev/null
-package nano
-
-import (
- "encoding/hex"
- "testing"
-
- "github.com/pkg/errors"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- crypto "github.com/tendermint/go-crypto"
-)
-
-func parseEdKey(data []byte) (key crypto.PubKey, err error) {
- ed := crypto.PubKeyEd25519{}
- if len(data) < len(ed) {
- return key, errors.Errorf("Key length too short: %d", len(data))
- }
- copy(ed[:], data)
- return ed.Wrap(), nil
-}
-
-func parseSig(data []byte) (key crypto.Signature, err error) {
- ed := crypto.SignatureEd25519{}
- if len(data) < len(ed) {
- return key, errors.Errorf("Sig length too short: %d", len(data))
- }
- copy(ed[:], data)
- return ed.Wrap(), nil
-}
-
-func TestParseDigest(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- cases := []struct {
- output string
- key string
- sig string
- valid bool
- }{
- {
- output: "80028E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C9300CAFE00787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400",
- key: "8E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C93",
- sig: "787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400",
- valid: true,
- },
- {
- output: "800235467890876543525437890796574535467890",
- key: "",
- sig: "",
- valid: false,
- },
- }
-
- for i, tc := range cases {
- msg, err := hex.DecodeString(tc.output)
- require.Nil(err, "%d: %+v", i, err)
-
- lKey, lSig, err := parseDigest(msg)
- if !tc.valid {
- assert.NotNil(err, "%d", i)
- } else if assert.Nil(err, "%d: %+v", i, err) {
- key, err := hex.DecodeString(tc.key)
- require.Nil(err, "%d: %+v", i, err)
- sig, err := hex.DecodeString(tc.sig)
- require.Nil(err, "%d: %+v", i, err)
-
- assert.Equal(key, lKey, "%d", i)
- assert.Equal(sig, lSig, "%d", i)
- }
- }
-}
-
-type cryptoCase struct {
- msg string
- key string
- sig string
- valid bool
-}
-
-func toBytes(c cryptoCase) (msg, key, sig []byte, err error) {
- msg, err = hex.DecodeString(c.msg)
- if err != nil {
- return
- }
- key, err = hex.DecodeString(c.key)
- if err != nil {
- return
- }
- sig, err = hex.DecodeString(c.sig)
- return
-}
-
-func TestCryptoConvert(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- cases := []cryptoCase{
- 0: {
- msg: "F00D",
- key: "8E8754F012C2FDB492183D41437FD837CB81D8BBE731924E2E0DAF43FD3F2C93",
- sig: "787DC03E9E4EE05983E30BAE0DEFB8DB0671DBC2F5874AC93F8D8CA4018F7A42D6F9A9BCEADB422AC8E27CEE9CA205A0B88D22CD686F0A43EB806E8190A3C400",
- valid: true,
- },
- 1: {
- msg: "DEADBEEF",
- key: "0C45ADC887A5463F668533443C829ED13EA8E2E890C778957DC28DB9D2AD5A6C",
- sig: "00ED74EED8FDAC7988A14BF6BC222120CBAC249D569AF4C2ADABFC86B792F97DF73C4919BE4B6B0ACB53547273BF29FBF0A9E0992FFAB6CB6C9B09311FC86A00",
- valid: true,
- },
- 2: {
- msg: "1234567890AA",
- key: "598FC1F0C76363D14D7480736DEEF390D85863360F075792A6975EFA149FD7EA",
- sig: "59AAB7D7BDC4F936B6415DE672A8B77FA6B8B3451CD95B3A631F31F9A05DAEEE5E7E4F89B64DDEBB5F63DC042CA13B8FCB8185F82AD7FD5636FFDA6B0DC9570B",
- valid: true,
- },
- 3: {
- msg: "1234432112344321",
- key: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120",
- sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208",
- valid: true,
- },
- 4: {
- msg: "12344321123443",
- key: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120",
- sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208",
- valid: false,
- },
- 5: {
- msg: "1234432112344321",
- key: "459E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120",
- sig: "616B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208",
- valid: false,
- },
- 6: {
- msg: "1234432112344321",
- key: "359E0636E780457294CCA5D2D84DB190C3EDBD6879729C10D3963DEA1D5D8120",
- sig: "716B44EC7A65E7C719C170D669A47DE80C6AC0BB13FBCC89230976F9CC14D4CF9ECF26D4AFBB9FFF625599F1FF6F78EDA15E9F6B6BDCE07CFE9D8C407AC45208",
- valid: false,
- },
- }
-
- for i, tc := range cases {
- msg, key, sig, err := toBytes(tc)
- require.Nil(err, "%d: %+v", i, err)
-
- pk, err := parseEdKey(key)
- require.Nil(err, "%d: %+v", i, err)
- psig, err := parseSig(sig)
- require.Nil(err, "%d: %+v", i, err)
-
- // it is not the signature of the message itself
- valid := pk.VerifyBytes(msg, psig)
- assert.False(valid, "%d", i)
-
- // but rather of the hash of the msg
- hmsg := hashMsg(msg)
- valid = pk.VerifyBytes(hmsg, psig)
- assert.Equal(tc.valid, valid, "%d", i)
- }
-}
return Fmt("PrivKeySecp256k1{*****}")
}
-/*
-// Deterministically generates new priv-key bytes from key.
-func (key PrivKeySecp256k1) Generate(index int) PrivKeySecp256k1 {
- newBytes := wire.BinarySha256(struct {
- PrivKey [64]byte
- Index int
- }{key, index})
- var newKey [64]byte
- copy(newKey[:], newBytes)
- return PrivKeySecp256k1(newKey)
-}
-*/
-
func GenPrivKeySecp256k1() PrivKeySecp256k1 {
privKeyBytes := [32]byte{}
copy(privKeyBytes[:], CRandBytes(32))
copy(privKeyBytes[:], priv.Serialize())
return PrivKeySecp256k1(privKeyBytes)
}
-
-// NOTE: secret should be the output of a KDF like bcrypt,
-// if it's derived from user input.
-func GenPrivKeySecp256k1FromSecret(secret []byte) PrivKeySecp256k1 {
- privKey32 := Sha256(secret) // Not Ripemd160 because we want 32 bytes.
- priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey32)
- privKeyBytes := [32]byte{}
- copy(privKeyBytes[:], priv.Serialize())
- return PrivKeySecp256k1(privKeyBytes)
-}
import (
"bytes"
- "fmt"
"github.com/tendermint/go-wire"
data "github.com/tendermint/go-wire/data"
- . "github.com/tendermint/tmlibs/common"
)
func SignatureFromBytes(sigBytes []byte) (sig Signature, err error) {
func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 }
-func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) }
-
func (sig SignatureEd25519) Equals(other Signature) bool {
if otherEd, ok := other.Unwrap().(SignatureEd25519); ok {
return bytes.Equal(sig[:], otherEd[:])
func (sig SignatureSecp256k1) IsZero() bool { return len(sig) == 0 }
-func (sig SignatureSecp256k1) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) }
-
func (sig SignatureSecp256k1) Equals(other Signature) bool {
if otherEd, ok := other.Unwrap().(SignatureSecp256k1); ok {
return bytes.Equal(sig[:], otherEd[:])
+++ /dev/null
-package crypto
-
-import (
- "errors"
-
- . "github.com/tendermint/tmlibs/common"
- "golang.org/x/crypto/nacl/secretbox"
-)
-
-const nonceLen = 24
-const secretLen = 32
-
-// secret must be 32 bytes long. Use something like Sha256(Bcrypt(passphrase))
-// The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext.
-// NOTE: call crypto.MixEntropy() first.
-func EncryptSymmetric(plaintext []byte, secret []byte) (ciphertext []byte) {
- if len(secret) != secretLen {
- PanicSanity(Fmt("Secret must be 32 bytes long, got len %v", len(secret)))
- }
- nonce := CRandBytes(nonceLen)
- nonceArr := [nonceLen]byte{}
- copy(nonceArr[:], nonce)
- secretArr := [secretLen]byte{}
- copy(secretArr[:], secret)
- ciphertext = make([]byte, nonceLen+secretbox.Overhead+len(plaintext))
- copy(ciphertext, nonce)
- secretbox.Seal(ciphertext[nonceLen:nonceLen], plaintext, &nonceArr, &secretArr)
- return ciphertext
-}
-
-// secret must be 32 bytes long. Use something like Sha256(Bcrypt(passphrase))
-// The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext.
-func DecryptSymmetric(ciphertext []byte, secret []byte) (plaintext []byte, err error) {
- if len(secret) != secretLen {
- PanicSanity(Fmt("Secret must be 32 bytes long, got len %v", len(secret)))
- }
- if len(ciphertext) <= secretbox.Overhead+nonceLen {
- return nil, errors.New("Ciphertext is too short")
- }
- nonce := ciphertext[:nonceLen]
- nonceArr := [nonceLen]byte{}
- copy(nonceArr[:], nonce)
- secretArr := [secretLen]byte{}
- copy(secretArr[:], secret)
- plaintext = make([]byte, len(ciphertext)-nonceLen-secretbox.Overhead)
- _, ok := secretbox.Open(plaintext[:0], ciphertext[nonceLen:], &nonceArr, &secretArr)
- if !ok {
- return nil, errors.New("Ciphertext decryption failed")
- }
- return plaintext, nil
-}
+++ /dev/null
-package crypto
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-
- "golang.org/x/crypto/bcrypt"
-)
-
-func TestSimple(t *testing.T) {
-
- MixEntropy([]byte("someentropy"))
-
- plaintext := []byte("sometext")
- secret := []byte("somesecretoflengththirtytwo===32")
- ciphertext := EncryptSymmetric(plaintext, secret)
- plaintext2, err := DecryptSymmetric(ciphertext, secret)
-
- require.Nil(t, err, "%+v", err)
- assert.Equal(t, plaintext, plaintext2)
-}
-
-func TestSimpleWithKDF(t *testing.T) {
-
- MixEntropy([]byte("someentropy"))
-
- plaintext := []byte("sometext")
- secretPass := []byte("somesecret")
- secret, err := bcrypt.GenerateFromPassword(secretPass, 12)
- if err != nil {
- t.Error(err)
- }
- secret = Sha256(secret)
-
- ciphertext := EncryptSymmetric(plaintext, secret)
- plaintext2, err := DecryptSymmetric(ciphertext, secret)
-
- require.Nil(t, err, "%+v", err)
- assert.Equal(t, plaintext, plaintext2)
-}
+++ /dev/null
-package crypto
-
-const Version = "0.4.1"
+++ /dev/null
-package main
-
-import (
- "fmt"
- "os"
- "strings"
-
- "github.com/tendermint/go-wire/expr"
- cmn "github.com/tendermint/tmlibs/common"
-)
-
-func main() {
- input := ""
- if len(os.Args) > 2 {
- input = strings.Join(os.Args[1:], " ")
- } else if len(os.Args) == 2 {
- input = os.Args[1]
- } else {
- fmt.Println("Usage: wire 'u64:1 u64:2 <sig:Alice>'")
- return
- }
-
- // fmt.Println(input)
- got, err := expr.ParseReader(input, strings.NewReader(input))
- if err != nil {
- cmn.Exit("Error parsing input: " + err.Error())
- }
- gotBytes, err := got.(expr.Byteful).Bytes()
- if err != nil {
- cmn.Exit("Error serializing parsed input: " + err.Error())
- }
-
- fmt.Println(cmn.Fmt("%X", gotBytes))
-}
+++ /dev/null
-# go-base58
-
-I copied this package from https://github.com/jbenet/go-base58
-which in turn came from https://github.com/conformal/btcutil
-to provide a simple base58 package that
-- defaults to base58-check (btc)
-- and allows using different alphabets.
-- and returns an error on decoding problems to be
- compatible with the `encoding/*` packages in stdlib
-
-## Usage
-
-```go
-package main
-
-import (
- "fmt"
- b58 "github.com/tendermint/go-wire/data/base58"
-)
-
-func main() {
- buf := []byte{255, 254, 253, 252}
- fmt.Printf("buffer: %v\n", buf)
-
- str := b58.Encode(buf)
- fmt.Printf("encoded: %s\n", str)
-
- buf2, err := b58.Decode(str)
- if err != nil {
- panic(err)
- }
- fmt.Printf("decoded: %v\n", buf2)
-}
-```
-
-### Another alphabet
-
-```go
-package main
-
-import (
- "fmt"
- b58 "github.com/tendermint/go-wire/data/base58"
-)
-
-const BogusAlphabet = "ZYXWVUTSRQPNMLKJHGFEDCBAzyxwvutsrqponmkjihgfedcba987654321"
-
-
-func encdec(alphabet string) {
- fmt.Printf("using: %s\n", alphabet)
-
- buf := []byte{255, 254, 253, 252}
- fmt.Printf("buffer: %v\n", buf)
-
- str := b58.EncodeAlphabet(buf, alphabet)
- fmt.Printf("encoded: %s\n", str)
-
- buf2, err := b58.DecodeAlphabet(str, alphabet)
- if err != nil {
- panic(err)
- }
- fmt.Printf("decoded: %v\n\n", buf2)
-}
-
-
-func main() {
- encdec(b58.BTCAlphabet)
- encdec(b58.FlickrAlphabet)
- encdec(BogusAlphabet)
-}
-```
-
-
-## License
-
-Package base58 (and the original btcutil) are licensed under the ISC License.
+++ /dev/null
-// Copyright (c) 2013-2014 Conformal Systems LLC.
-// Use of this source code is governed by an ISC
-// license that can be found in the LICENSE file.
-// Modified by Juan Benet (juan@benet.ai)
-
-package base58
-
-import (
- "math/big"
- "strings"
-
- "github.com/pkg/errors"
-)
-
-// alphabet is the modified base58 alphabet used by Bitcoin.
-const BTCAlphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
-const FlickrAlphabet = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
-
-var bigRadix = big.NewInt(58)
-var bigZero = big.NewInt(0)
-
-// Decode decodes a modified base58 string to a byte slice, using BTCAlphabet
-func Decode(b string) ([]byte, error) {
- return DecodeAlphabet(b, BTCAlphabet)
-}
-
-// Encode encodes a byte slice to a modified base58 string, using BTCAlphabet
-func Encode(b []byte) string {
- return EncodeAlphabet(b, BTCAlphabet)
-}
-
-// DecodeAlphabet decodes a modified base58 string to a byte slice, using alphabet.
-func DecodeAlphabet(b, alphabet string) ([]byte, error) {
- answer := big.NewInt(0)
- j := big.NewInt(1)
-
- for i := len(b) - 1; i >= 0; i-- {
- tmp := strings.IndexAny(alphabet, string(b[i]))
- if tmp == -1 {
- return nil, errors.Errorf("Encountered unknown character: %s", string(b[i]))
- }
- idx := big.NewInt(int64(tmp))
- tmp1 := big.NewInt(0)
- tmp1.Mul(j, idx)
-
- answer.Add(answer, tmp1)
- j.Mul(j, bigRadix)
- }
-
- tmpval := answer.Bytes()
-
- var numZeros int
- for numZeros = 0; numZeros < len(b); numZeros++ {
- if b[numZeros] != alphabet[0] {
- break
- }
- }
- flen := numZeros + len(tmpval)
- val := make([]byte, flen, flen)
- copy(val[numZeros:], tmpval)
-
- return val, nil
-}
-
-// Encode encodes a byte slice to a modified base58 string, using alphabet
-func EncodeAlphabet(b []byte, alphabet string) string {
- x := new(big.Int)
- x.SetBytes(b)
-
- answer := make([]byte, 0, len(b)*136/100)
- for x.Cmp(bigZero) > 0 {
- mod := new(big.Int)
- x.DivMod(x, bigRadix, mod)
- answer = append(answer, alphabet[mod.Int64()])
- }
-
- // leading zero bytes
- for _, i := range b {
- if i != 0 {
- break
- }
- answer = append(answer, alphabet[0])
- }
-
- // reverse
- alen := len(answer)
- for i := 0; i < alen/2; i++ {
- answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i]
- }
-
- return string(answer)
-}
+++ /dev/null
-// Copyright (c) 2013-2014 Conformal Systems LLC.
-// Use of this source code is governed by an ISC
-// license that can be found in the LICENSE file.
-
-package base58
-
-import (
- "bytes"
- "encoding/hex"
- "testing"
-)
-
-var stringTests = []struct {
- in string
- out string
-}{
- {"", ""},
- {" ", "Z"},
- {"-", "n"},
- {"0", "q"},
- {"1", "r"},
- {"-1", "4SU"},
- {"11", "4k8"},
- {"abc", "ZiCa"},
- {"1234598760", "3mJr7AoUXx2Wqd"},
- {"abcdefghijklmnopqrstuvwxyz", "3yxU3u1igY8WkgtjK92fbJQCd4BZiiT1v25f"},
- {"00000000000000000000000000000000000000000000000000000000000000", "3sN2THZeE9Eh9eYrwkvZqNstbHGvrxSAM7gXUXvyFQP8XvQLUqNCS27icwUeDT7ckHm4FUHM2mTVh1vbLmk7y"},
-}
-
-var invalidStringTests = []struct {
- in string
- out string
-}{
- {"0", ""},
- {"O", ""},
- {"I", ""},
- {"l", ""},
- {"3mJr0", ""},
- {"O3yxU", ""},
- {"3sNI", ""},
- {"4kl8", ""},
- {"0OIl", ""},
- {"!@#$%^&*()-_=+~`", ""},
-}
-
-var hexTests = []struct {
- in string
- out string
-}{
- {"61", "2g"},
- {"626262", "a3gV"},
- {"636363", "aPEr"},
- {"73696d706c792061206c6f6e6720737472696e67", "2cFupjhnEsSn59qHXstmK2ffpLv2"},
- {"00eb15231dfceb60925886b67d065299925915aeb172c06647", "1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L"},
- {"516b6fcd0f", "ABnLTmg"},
- {"bf4f89001e670274dd", "3SEo3LWLoPntC"},
- {"572e4794", "3EFU7m"},
- {"ecac89cad93923c02321", "EJDM8drfXA6uyA"},
- {"10c8511e", "Rt5zm"},
- {"00000000000000000000", "1111111111"},
-}
-
-func TestBase58(t *testing.T) {
- // Base58Encode tests
- for x, test := range stringTests {
- tmp := []byte(test.in)
- if res := Encode(tmp); res != test.out {
- t.Errorf("Base58Encode test #%d failed: got: %s want: %s",
- x, res, test.out)
- continue
- }
- }
-
- // Base58Decode tests
- for x, test := range hexTests {
- b, err := hex.DecodeString(test.in)
- if err != nil {
- t.Errorf("hex.DecodeString failed failed #%d: got: %s", x, test.in)
- continue
- }
- res, err := Decode(test.out)
- if err != nil {
- t.Errorf("Base58Decode test returned error: %+v", err)
- continue
- }
- if bytes.Equal(res, b) != true {
- t.Errorf("Base58Decode test #%d failed: got: %q want: %q",
- x, res, test.in)
- continue
- }
- }
-
- // Base58Decode with invalid input
- for _, test := range invalidStringTests {
- _, err := Decode(test.in)
- if err == nil {
- t.Errorf("Base58Decode invalidString test accepted string: %s", test.in)
- continue
- }
- }
-}
-
-func BenchmarkDecodeShort(b *testing.B) {
- const in = "1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L"
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- _, _ = Decode(in)
- }
-}
-
-func BenchmarkEncodeShort(b *testing.B) {
- var in = []byte("00eb15231dfceb60925886b67d065299925915aeb172c06647")
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- _ = Encode(in)
- }
-}
-
-func BenchmarkDecodeOneKilo(b *testing.B) {
- const in = "3GimCffBLAHhXMCeNxX2nST6dBem9pbUi3KVKykW73LmewcFtMk9oh9eNPdNR2eSzNqp7Z3E21vrWUkGHzJ7w2yqDUDJ4LKo1w5D6aafZ4SUoNQyrSVxyVG3pwgoZkKXMZVixRyiPZVUpekrsTvZuUoW7mB6BQgDTXbDuMMSRoNR7yiUTKpgwTD61DLmhNZopNxfFjn4avpYPgzsTB94iWueq1yU3EoruWCUMvp6fc1CEbDrZY3pkx9oUbUaSMC37rruBKSSGHh1ZE3XK3kQXBCFraMmUQf8dagofMEg5aTnDiLAZjLyWJMdnQwW1FqKKztP8KAQS2JX8GCCfc68KB4VGf2CfEGXtaapnsNWFrHuWi7Wo5vqyuHd21zGm1u5rsiR6tKNCsFC4nzf3WUNxJNoZrDSdF9KERqhTWWmmcM4qdKRCtBWKTrs1DJD2oiK6BK9BgwoW2dfQdKuxojFyFvmxqPKDDAEZPPpJ51wHoFzBFMM1tUBBkN15cT2GpNwKzDcjHPKJAQ6FNRgppfQytzqpq76sSeZaWAB8hhULMJCQGU57ZUjvP7xYAQwtACBnYrjdxA91XwXFbq5AsQJwAmLw6euKVWNyv11BuHrejVmnNViWg5kuZBrtgL6NtzRWHtdxngHDMtuyky3brqGXaGQhUyXrkSpeknkkHL6NLThHH5NPnfFMVPwn2xf5UM5R51X2nTBzADSVcpi4cT7i44dT7o3yRKWtKfUzZiuNyTcSSrfH8KVdLap5ZKLmdPuXM65M2Z5wJVh3Uc4iv6iZKk44RKikM7zs1hqC4sBxRwLZjxhKvvMXDjDcYFkzyUkues4y7fjdCnVTxc4vTYUqcbY2k2WMssyj9SDseVc7dVrEvWCLQtYy79mJFoz1Hmsfk5ynE28ipznzQ3yTBugLHA6j6qW3S74eY4pJ6iynFEuXT4RqqkLGFcMh3goqS7CkphUMzP4wuJyGnzqa5tCno4U3dJ2jUL7Povg8voRqYAfiHyXC8zuhn225EdmRcSnu2pAuutQVV9hN3bkjfzAFUhUWKki8SwXtFSjy6NJyrYUiaze4p7ApsjHQBCgg2zAoBaGCwVN8991Jny31B5vPyYHy1oRSE4xTVZ7tTw9FyQ7w9p1NSEF4sziCxZHh5rFWZKAajc5c7KaMNDvHPNV6S62MTFGTyuKPQNbv9yHRGN4eH6SnZGW6snvEVdYCspWZ1U3Nbxo6vCmBK95UyYpcxHgg1CCGdU4s3edju2NDQkMifyPkJdkabzzHVDhJJbChAJc1ACQfNW74VXXwrBZmeZyA2R28MBctDyXuSuffiwueys2LVowLu9wiTHUox7KQjtHK2c9howk9czzx2mpnYzkVYH42CYsWa5514EM4CJEXPJSSbXSgJJ"
- b.SetBytes(int64(len(in))) // 1024
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- _, _ = Decode(in)
- }
-}
-
-func BenchmarkEncodeOneKilo(b *testing.B) {
- var in = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x00\x00\x04\xff\xfb\x63\xc9\x7e\x5f\x97\x68\xe5\x10\x08\xe5\xa5\x9a\x7c\x24\x75\x35\xbe\xaf\x37\x0b\xc3\xf4\x18\x62\x4a\xb7\x18\xd0\x10\x0b\x6b\x62\xe1\x36\x0f\x62\xa6\xeb\x78\xa5\xf3\x33\x52\xbc\xdf\x04\xcb\x37\xcf\x3d\x97\x5c\xb8\x75\x09\x1f\x18\x9f\xfc\xa9\xda\x1e\x59\x77\x09\x9c\x5d\xb6\xf2\x9e\x45\xb7\x5e\x5d\x11\xf1\x20\x14\x85\xf8\x54\x87\x8c\x1e\x2c\x2e\x15\x57\x89\xe7\x5d\x49\xb6\xae\x24\x3a\x20\x50\x0e\xa7\x5b\x10\xbf\x0a\xb4\x01\x42\xed\xce\x2d\x45\x21\xb6\xe8\x64\x73\x4e\x7e\x0a\x36\x1d\x57\x0a\x5e\x1c\x21\xc2\xb8\xe7\x89\x82\xe4\x04\x7e\x50\xff\xda\x4f\xfe\x11\x95\xfb\x35\xf9\x6d\x32\xce\xef\x8f\x3d\x1b\xdb\x38\xfa\xcd\x26\x36\x12\x93\xa0\x96\xea\x42\xbe\xd6\x85\x86\xc1\xc1\xe2\x55\x41\xd1\x7f\x8d\x0e\x00\x81\x58\xb4\x10\xbb\x64\x92\x05\x07\xa9\xd5\xd9\x40\x28\x8b\x9b\x4c\x8d\x8e\x4e\x69\xf9\xc9\x35\xea\xda\x2f\x61\x87\x35\x2d\x6b\x25\x32\xf0\x7e\x89\x1a\xcb\xc0\xea\x66\x88\x99\x39\xe0\x3b\x24\x3b\x05\x74\xd3\x72\xf6\x48\x15\xdc\x02\x0a\xbf\xc8\x49\x42\x10\x22\xeb\xe9\x44\x71\x55\xaf\x67\x67\xe6\x2a\x40\x31\x81\xb9\x6f\x65\x86\x0f\x0f\x9d\x58\x4c\x51\xc1\x2e\x4e\x60\x7e\xe8\x93\x39\x90\xda\xe5\xbe\xec\xe4\xdd\xbc\x1d\xba\x40\xa6\x85\xd9\xb2\xec\xb4\x26\x74\xee\xc1\xec\xe3\x40\xb9\x49\xa3\xe1\x26\x76\x8a\xeb\x95\xc8\x72\xb0\x85\x36\x19\x3f\x55\x06\x7b\xcd\x3e\xd0\xdf\x7e\x8d\x2a\xea\xa6\x24\xc6\xf6\xfb\xda\xe0\x45\xcf\x32\x0e\xbc\xf4\x41\x7d\x71\x3d\x86\xf9\xb4\xaf\x07\xa0\xd1\x34\x8a\x02\x28\x56\xd4\xcc\x36\x44\x98\x44\xcb\x9d\xc5\xfc\x45\x2d\xc4\x5c\xfe\xce\xaa\x44\xda\x66\x52\x2d\x32\x6e\x13\x32\xac\xaf\x13\x72\x87\x79\xd2\x92\x54\x9f\xc7\xb9\xf3\x21\xae\xdd\x69\x44\xe9\x46\x94\x1c\x62\x84\x03\xe0\xbf\x66\xfb\xe0\x79\xf9\x57\x9e\x22\x9e\x23\x2d\x2a\x73\xeb\x74\x38\xf0\xea\x5d\xb3\x8f\x87\x26\x3e\x3c\x54\x11\xb7\x98\xbd\x7f\x78\x64\xa3\xf1\x8f\xa9\x5e\x4f\x18\x3f\xa7\x1f\x3a\x29\x27\x27\xb7\x49\x40\x16\x18\x1f\xd3\xed\x86\x61\xbd\xc3\x4e\x4a\x53\x37\x78\x5c\x00\xd3\x50\x45\x1c\x55\xc0\x9b\xd7\x62\x29\x88\x2e\xa4\x0d\x6a\x15\x6c\x33\x3c\xe7\x31\xfa\xc1\xaf\xdf\x7a\x3e\x37\x3e\xe5\xbc\xfd\xfb\x9b\x72\x10\x35\x90\x25\x6e\x87\x0d\x74\x1c\xfd\xe3\x0b\xee\xf5\x92\x28\x8d\x22\x8a\x49\x7b\xcd\xbb\xd8\x24\x6b\x5e\x58\x40\xec\x1b\x6c\xed\x8e\xcb\x56\x62\xa6\xb4\x42\x3d\x7d\xa2\xef\x27\x27\x46\x50\xbc\x5e\x37\x9b\x27\x72\xf0\xea\xa7\xe7\x4d\xf4\xae\x7e\x95\x8f\x91\x2e\x58\xc4\x6a\x06\xda\x7a\x06\x5c\x8d\xfe\xef\xf5\xb3\x0f\xb4\x0a\x20\x53\xd8\x35\x80\x02\xca\x97\x81\xb6\x1c\x4b\x8f\xb7\xee\xd0\xc3\x88\x6c\x76\x3e\xb0\x28\xce\xa1\x9f\x76\x5f\xaa\xc3\x53\x44\x09\x70\xa3\x95\xd9\x8c\x54\xba\x8a\x9a\x6b\xce\xc3\x07\xdf\x13\x6d\xea\x0f\x51\x9c\xe2\x81\x87\xf6\x82\x7a\x70\xd8\xfa\xe2\xa8\x32\xc1\x5e\x53\xc2\x85\xe9\x61\x8a\x17\x82\x12\xab\x92\x79\x2b\xed\x07\xca\x1e\x93\x23\x9c\x4b\xd2\x89\x86\xac\x55\xf9\x50\x23\x8f\x9e\xd3\xab\x22\x57\x91\x5a\x0b\x48\xd7\xa2\xb8\x06\xbb\x74\xae\xe9\xca\x06\x41\x8d\x6a\x00\x42\xc4\x40\xa9\xfe\xae\x88\x42\xc2\x83\xe0\x8a\xd8\x5c\xbb\x5a\xb5\x9c\x1d\xa5\xbe\x67\x50\xb1\x4e\xec\x96\x65\xaa\x87\x5b\xb0\x76\x88\xe3\x1b\xcb\x38\x21\x02\x8e\xc9\xe7\xf5\xc7\xe1\x1d\xe8\xeb\x54\x0e\x0b\xea\xd1\x2e\xad\xbb\xec\x22\x21\xb3\x64\x36\x29\x34\x5e\x3a\x22\xe8\x03\x4b\x86\xb1\x67\x7d\x4f\x48\x6d\xfb\x4b\xde\xe6\x4c\xb0\xaf\x40\x66\xab\xe9\x1a\x4e\xae\x1a\x7e\x05\xc5\x67\x2a\x95\x6d\xc2\x61\x35\x20\xfe\x33\xc3\x2c\x7f\x9b\xbe\x9f\x9a\xd5\xf0\x63\x28\xa1\x94\xb1\x5c\xc1\x18\x6b\x5b\x33\xb4\x4d\xcf\xbe\xf7\xb2\x94\x58\xaa\xcf\xad\xc8\x75\x93\x1a\x08\xf4\xd2\xd9\xf6\x95\x03\x3b\xf3\x4e\xfb\x15\xe4\x28\xed\xd5\x79\xd9\xbf\xb7\x8f\xb2\x70\x16\x4c\x2d\x65\xf6\xec\x33\x1e\xaf\xea\x46\x69\xc6\x9a\x6b\xdd\xf3\x57\xe0\x1d\x28\xcd\xf8\x83\x3d\x94\x4c\x2f\x6e\xfd\x51\x3d\xa8\xff\xcb\x33\xad\x32\x42\x0e\xd3\x00\x0a\xe5\x71\x76\x3b\x83\xc9\x2a\x67\x50\xc3\xa5\xeb\x4d\x8d\x67\xd6\xd9\x1b\x9a\x5a\xbe\xdd\xc5\x15\x00\xcf\x97\x0f\x47\x44\x34\x1d\x4e\xb6\x6f\x91\x31\xf3\x45\x0f\x59\x48\x10\x23\x53\x40\x49\x83\xe6\xc8\xdf\x51\x6c\xa8\x9f\x3a\x43\x3d\xb9\xd4\xea\x30\x4d\xe0\xd2\xb8\x44\xf3\x91\x20\x79\xdb\x7b\xe6\x50\xf9\x0f\xfb\x4c\xac\x79\x93\xf6\xf8\x96\x0d\x55\x7c\x41\x9b\x1a\x86\xad\x4b\xd1\xf9\x5d\xed\x3a\x4f\xc9\x64\x72\xd4\x22\x53\x59\x2f\x01\x00\x00\xff\xff\xc6\xfd\xa0\x37\x00\x04\x00\x00")
- b.SetBytes(int64(len(in))) // 1024
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- _ = Encode(in)
- }
-}
+++ /dev/null
-// Copyright (c) 2013-2014 Conformal Systems LLC.
-// Use of this source code is governed by an ISC
-// license that can be found in the LICENSE file.
-
-/*
-Package base58 provides base58-check encoding.
-The alphabet is modifyiable for
-
-Base58 Usage
-
-To decode a base58 string:
-
- rawData := base58.Base58Decode(encodedData)
-
-Similarly, to encode the same data:
-
- encodedData := base58.Base58Encode(rawData)
-
-*/
-package base58
+++ /dev/null
-package base58
-
-import (
- "encoding/json"
-
- "github.com/pkg/errors"
- data "github.com/tendermint/go-wire/data"
-)
-
-var (
- BTCEncoder data.ByteEncoder = base58Encoder{BTCAlphabet}
- FlickrEncoder = base58Encoder{FlickrAlphabet}
-)
-
-// base58Encoder implements ByteEncoder encoding the slice as
-// base58 url-safe encoding
-type base58Encoder struct {
- alphabet string
-}
-
-func (e base58Encoder) _assertByteEncoder() data.ByteEncoder {
- return e
-}
-
-func (e base58Encoder) Unmarshal(dst *[]byte, src []byte) (err error) {
- var s string
- err = json.Unmarshal(src, &s)
- if err != nil {
- return errors.Wrap(err, "parse string")
- }
- *dst, err = DecodeAlphabet(s, e.alphabet)
- return err
-}
-
-func (e base58Encoder) Marshal(bytes []byte) ([]byte, error) {
- s := EncodeAlphabet(bytes, e.alphabet)
- return json.Marshal(s)
-}
+++ /dev/null
-package base58_test
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
- data "github.com/tendermint/go-wire/data"
- "github.com/tendermint/go-wire/data/base58"
-)
-
-func TestEncoders(t *testing.T) {
- assert := assert.New(t)
-
- // TODO: also test other alphabets???
- btc := base58.BTCEncoder
-
- cases := []struct {
- encoder data.ByteEncoder
- input, expected []byte
- }{
- {btc, []byte(`"3mJr7AoUXx2Wqd"`), []byte("1234598760")},
- {btc, []byte(`"3yxU3u1igY8WkgtjK92fbJQCd4BZiiT1v25f"`), []byte("abcdefghijklmnopqrstuvwxyz")},
- // these are errors
- {btc, []byte(`0123`), nil}, // not in quotes
- {btc, []byte(`"3mJr0"`), nil}, // invalid chars
- }
-
- for _, tc := range cases {
- var output []byte
- err := tc.encoder.Unmarshal(&output, tc.input)
- if tc.expected == nil {
- assert.NotNil(err, tc.input)
- } else if assert.Nil(err, "%s: %+v", tc.input, err) {
- assert.Equal(tc.expected, output, tc.input)
- }
- }
-}
+++ /dev/null
-
-package expr
-
-import (
- "bytes"
- "encoding/hex"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "strconv"
- "strings"
- "unicode"
- "unicode/utf8"
-)
-
-var g = &grammar {
- rules: []*rule{
-{
- name: "Start",
- pos: position{line: 19, col: 1, offset: 148},
- expr: &actionExpr{
- pos: position{line: 19, col: 9, offset: 158},
- run: (*parser).callonStart1,
- expr: &seqExpr{
- pos: position{line: 19, col: 9, offset: 158},
- exprs: []interface{}{
-&labeledExpr{
- pos: position{line: 19, col: 9, offset: 158},
- label: "items_",
- expr: &oneOrMoreExpr{
- pos: position{line: 19, col: 16, offset: 165},
- expr: &ruleRefExpr{
- pos: position{line: 19, col: 16, offset: 165},
- name: "Item",
-},
-},
-},
-&ruleRefExpr{
- pos: position{line: 19, col: 22, offset: 171},
- name: "_",
-},
-&ruleRefExpr{
- pos: position{line: 19, col: 24, offset: 173},
- name: "EOF",
-},
- },
-},
-},
-},
-{
- name: "Item",
- pos: position{line: 27, col: 1, offset: 307},
- expr: &actionExpr{
- pos: position{line: 27, col: 8, offset: 316},
- run: (*parser).callonItem1,
- expr: &seqExpr{
- pos: position{line: 27, col: 8, offset: 316},
- exprs: []interface{}{
-&ruleRefExpr{
- pos: position{line: 27, col: 8, offset: 316},
- name: "_",
-},
-&labeledExpr{
- pos: position{line: 27, col: 10, offset: 318},
- label: "it",
- expr: &choiceExpr{
- pos: position{line: 27, col: 14, offset: 322},
- alternatives: []interface{}{
-&ruleRefExpr{
- pos: position{line: 27, col: 14, offset: 322},
- name: "Array",
-},
-&ruleRefExpr{
- pos: position{line: 27, col: 22, offset: 330},
- name: "Tuple",
-},
-&ruleRefExpr{
- pos: position{line: 27, col: 30, offset: 338},
- name: "Hex",
-},
-&ruleRefExpr{
- pos: position{line: 27, col: 36, offset: 344},
- name: "TypedNumeric",
-},
-&ruleRefExpr{
- pos: position{line: 27, col: 51, offset: 359},
- name: "UntypedNumeric",
-},
-&ruleRefExpr{
- pos: position{line: 27, col: 68, offset: 376},
- name: "Placeholder",
-},
-&ruleRefExpr{
- pos: position{line: 27, col: 82, offset: 390},
- name: "String",
-},
- },
-},
-},
- },
-},
-},
-},
-{
- name: "Array",
- pos: position{line: 31, col: 1, offset: 422},
- expr: &actionExpr{
- pos: position{line: 31, col: 9, offset: 432},
- run: (*parser).callonArray1,
- expr: &seqExpr{
- pos: position{line: 31, col: 9, offset: 432},
- exprs: []interface{}{
-&litMatcher{
- pos: position{line: 31, col: 9, offset: 432},
- val: "[",
- ignoreCase: false,
-},
-&labeledExpr{
- pos: position{line: 31, col: 13, offset: 436},
- label: "items",
- expr: &zeroOrMoreExpr{
- pos: position{line: 31, col: 19, offset: 442},
- expr: &ruleRefExpr{
- pos: position{line: 31, col: 19, offset: 442},
- name: "Item",
-},
-},
-},
-&ruleRefExpr{
- pos: position{line: 31, col: 25, offset: 448},
- name: "_",
-},
-&litMatcher{
- pos: position{line: 31, col: 27, offset: 450},
- val: "]",
- ignoreCase: false,
-},
- },
-},
-},
-},
-{
- name: "Tuple",
- pos: position{line: 35, col: 1, offset: 504},
- expr: &actionExpr{
- pos: position{line: 35, col: 9, offset: 514},
- run: (*parser).callonTuple1,
- expr: &seqExpr{
- pos: position{line: 35, col: 9, offset: 514},
- exprs: []interface{}{
-&litMatcher{
- pos: position{line: 35, col: 9, offset: 514},
- val: "(",
- ignoreCase: false,
-},
-&labeledExpr{
- pos: position{line: 35, col: 13, offset: 518},
- label: "items",
- expr: &oneOrMoreExpr{
- pos: position{line: 35, col: 19, offset: 524},
- expr: &ruleRefExpr{
- pos: position{line: 35, col: 19, offset: 524},
- name: "Item",
-},
-},
-},
-&ruleRefExpr{
- pos: position{line: 35, col: 25, offset: 530},
- name: "_",
-},
-&litMatcher{
- pos: position{line: 35, col: 27, offset: 532},
- val: ")",
- ignoreCase: false,
-},
- },
-},
-},
-},
-{
- name: "UntypedNumeric",
- pos: position{line: 39, col: 1, offset: 586},
- expr: &actionExpr{
- pos: position{line: 39, col: 18, offset: 605},
- run: (*parser).callonUntypedNumeric1,
- expr: &labeledExpr{
- pos: position{line: 39, col: 18, offset: 605},
- label: "number",
- expr: &ruleRefExpr{
- pos: position{line: 39, col: 25, offset: 612},
- name: "Integer",
-},
-},
-},
-},
-{
- name: "TypedNumeric",
- pos: position{line: 46, col: 1, offset: 704},
- expr: &actionExpr{
- pos: position{line: 46, col: 16, offset: 721},
- run: (*parser).callonTypedNumeric1,
- expr: &seqExpr{
- pos: position{line: 46, col: 16, offset: 721},
- exprs: []interface{}{
-&labeledExpr{
- pos: position{line: 46, col: 16, offset: 721},
- label: "t",
- expr: &ruleRefExpr{
- pos: position{line: 46, col: 18, offset: 723},
- name: "Type",
-},
-},
-&litMatcher{
- pos: position{line: 46, col: 23, offset: 728},
- val: ":",
- ignoreCase: false,
-},
-&labeledExpr{
- pos: position{line: 46, col: 27, offset: 732},
- label: "number",
- expr: &ruleRefExpr{
- pos: position{line: 46, col: 34, offset: 739},
- name: "Integer",
-},
-},
- },
-},
-},
-},
-{
- name: "Hex",
- pos: position{line: 53, col: 1, offset: 838},
- expr: &choiceExpr{
- pos: position{line: 53, col: 7, offset: 846},
- alternatives: []interface{}{
-&ruleRefExpr{
- pos: position{line: 53, col: 7, offset: 846},
- name: "HexLengthPrefixed",
-},
-&ruleRefExpr{
- pos: position{line: 53, col: 27, offset: 866},
- name: "HexRaw",
-},
- },
-},
-},
-{
- name: "HexLengthPrefixed",
- pos: position{line: 55, col: 1, offset: 874},
- expr: &actionExpr{
- pos: position{line: 55, col: 21, offset: 896},
- run: (*parser).callonHexLengthPrefixed1,
- expr: &seqExpr{
- pos: position{line: 55, col: 21, offset: 896},
- exprs: []interface{}{
-&litMatcher{
- pos: position{line: 55, col: 21, offset: 896},
- val: "0x",
- ignoreCase: false,
-},
-&labeledExpr{
- pos: position{line: 55, col: 26, offset: 901},
- label: "hexbytes",
- expr: &ruleRefExpr{
- pos: position{line: 55, col: 35, offset: 910},
- name: "HexBytes",
-},
-},
- },
-},
-},
-},
-{
- name: "HexRaw",
- pos: position{line: 59, col: 1, offset: 974},
- expr: &actionExpr{
- pos: position{line: 59, col: 10, offset: 985},
- run: (*parser).callonHexRaw1,
- expr: &seqExpr{
- pos: position{line: 59, col: 10, offset: 985},
- exprs: []interface{}{
-&litMatcher{
- pos: position{line: 59, col: 10, offset: 985},
- val: "x",
- ignoreCase: false,
-},
-&labeledExpr{
- pos: position{line: 59, col: 14, offset: 989},
- label: "hexbytes",
- expr: &ruleRefExpr{
- pos: position{line: 59, col: 23, offset: 998},
- name: "HexBytes",
-},
-},
- },
-},
-},
-},
-{
- name: "HexBytes",
- pos: position{line: 63, col: 1, offset: 1063},
- expr: &actionExpr{
- pos: position{line: 63, col: 12, offset: 1076},
- run: (*parser).callonHexBytes1,
- expr: &oneOrMoreExpr{
- pos: position{line: 63, col: 12, offset: 1076},
- expr: &charClassMatcher{
- pos: position{line: 63, col: 12, offset: 1076},
- val: "[0-9abcdefABCDEF]",
- chars: []rune{'a','b','c','d','e','f','A','B','C','D','E','F',},
- ranges: []rune{'0','9',},
- ignoreCase: false,
- inverted: false,
-},
-},
-},
-},
-{
- name: "Type",
- pos: position{line: 71, col: 1, offset: 1223},
- expr: &actionExpr{
- pos: position{line: 71, col: 8, offset: 1232},
- run: (*parser).callonType1,
- expr: &choiceExpr{
- pos: position{line: 71, col: 9, offset: 1233},
- alternatives: []interface{}{
-&litMatcher{
- pos: position{line: 71, col: 9, offset: 1233},
- val: "u64",
- ignoreCase: false,
-},
-&litMatcher{
- pos: position{line: 71, col: 17, offset: 1241},
- val: "i64",
- ignoreCase: false,
-},
- },
-},
-},
-},
-{
- name: "Integer",
- pos: position{line: 75, col: 1, offset: 1284},
- expr: &actionExpr{
- pos: position{line: 75, col: 11, offset: 1296},
- run: (*parser).callonInteger1,
- expr: &seqExpr{
- pos: position{line: 75, col: 11, offset: 1296},
- exprs: []interface{}{
-&zeroOrOneExpr{
- pos: position{line: 75, col: 11, offset: 1296},
- expr: &litMatcher{
- pos: position{line: 75, col: 11, offset: 1296},
- val: "-",
- ignoreCase: false,
-},
-},
-&oneOrMoreExpr{
- pos: position{line: 75, col: 16, offset: 1301},
- expr: &charClassMatcher{
- pos: position{line: 75, col: 16, offset: 1301},
- val: "[0-9]",
- ranges: []rune{'0','9',},
- ignoreCase: false,
- inverted: false,
-},
-},
- },
-},
-},
-},
-{
- name: "Label",
- pos: position{line: 79, col: 1, offset: 1344},
- expr: &actionExpr{
- pos: position{line: 79, col: 9, offset: 1354},
- run: (*parser).callonLabel1,
- expr: &oneOrMoreExpr{
- pos: position{line: 79, col: 9, offset: 1354},
- expr: &charClassMatcher{
- pos: position{line: 79, col: 9, offset: 1354},
- val: "[0-9a-zA-Z:]",
- chars: []rune{':',},
- ranges: []rune{'0','9','a','z','A','Z',},
- ignoreCase: false,
- inverted: false,
-},
-},
-},
-},
-{
- name: "Placeholder",
- pos: position{line: 83, col: 1, offset: 1404},
- expr: &actionExpr{
- pos: position{line: 83, col: 15, offset: 1420},
- run: (*parser).callonPlaceholder1,
- expr: &seqExpr{
- pos: position{line: 83, col: 15, offset: 1420},
- exprs: []interface{}{
-&litMatcher{
- pos: position{line: 83, col: 15, offset: 1420},
- val: "<",
- ignoreCase: false,
-},
-&labeledExpr{
- pos: position{line: 83, col: 19, offset: 1424},
- label: "label",
- expr: &ruleRefExpr{
- pos: position{line: 83, col: 25, offset: 1430},
- name: "Label",
-},
-},
-&litMatcher{
- pos: position{line: 83, col: 31, offset: 1436},
- val: ">",
- ignoreCase: false,
-},
- },
-},
-},
-},
-{
- name: "String",
- pos: position{line: 89, col: 1, offset: 1509},
- expr: &actionExpr{
- pos: position{line: 89, col: 10, offset: 1520},
- run: (*parser).callonString1,
- expr: &seqExpr{
- pos: position{line: 89, col: 10, offset: 1520},
- exprs: []interface{}{
-&litMatcher{
- pos: position{line: 89, col: 10, offset: 1520},
- val: "\"",
- ignoreCase: false,
-},
-&zeroOrMoreExpr{
- pos: position{line: 89, col: 14, offset: 1524},
- expr: &choiceExpr{
- pos: position{line: 89, col: 16, offset: 1526},
- alternatives: []interface{}{
-&seqExpr{
- pos: position{line: 89, col: 16, offset: 1526},
- exprs: []interface{}{
-¬Expr{
- pos: position{line: 89, col: 16, offset: 1526},
- expr: &ruleRefExpr{
- pos: position{line: 89, col: 17, offset: 1527},
- name: "EscapedChar",
-},
-},
-&anyMatcher{
- line: 89, col: 29, offset: 1539,
-},
- },
-},
-&seqExpr{
- pos: position{line: 89, col: 33, offset: 1543},
- exprs: []interface{}{
-&litMatcher{
- pos: position{line: 89, col: 33, offset: 1543},
- val: "\\",
- ignoreCase: false,
-},
-&ruleRefExpr{
- pos: position{line: 89, col: 38, offset: 1548},
- name: "EscapeSequence",
-},
- },
-},
- },
-},
-},
-&litMatcher{
- pos: position{line: 89, col: 56, offset: 1566},
- val: "\"",
- ignoreCase: false,
-},
- },
-},
-},
-},
-{
- name: "EscapedChar",
- pos: position{line: 100, col: 1, offset: 1839},
- expr: &charClassMatcher{
- pos: position{line: 100, col: 15, offset: 1855},
- val: "[\\x00-\\x1f\"\\\\]",
- chars: []rune{'"','\\',},
- ranges: []rune{'\x00','\x1f',},
- ignoreCase: false,
- inverted: false,
-},
-},
-{
- name: "EscapeSequence",
- pos: position{line: 102, col: 1, offset: 1871},
- expr: &choiceExpr{
- pos: position{line: 102, col: 18, offset: 1890},
- alternatives: []interface{}{
-&ruleRefExpr{
- pos: position{line: 102, col: 18, offset: 1890},
- name: "SingleCharEscape",
-},
-&ruleRefExpr{
- pos: position{line: 102, col: 37, offset: 1909},
- name: "UnicodeEscape",
-},
- },
-},
-},
-{
- name: "SingleCharEscape",
- pos: position{line: 104, col: 1, offset: 1924},
- expr: &charClassMatcher{
- pos: position{line: 104, col: 20, offset: 1945},
- val: "[\"\\\\/bfnrt]",
- chars: []rune{'"','\\','/','b','f','n','r','t',},
- ignoreCase: false,
- inverted: false,
-},
-},
-{
- name: "UnicodeEscape",
- pos: position{line: 106, col: 1, offset: 1958},
- expr: &seqExpr{
- pos: position{line: 106, col: 17, offset: 1976},
- exprs: []interface{}{
-&litMatcher{
- pos: position{line: 106, col: 17, offset: 1976},
- val: "u",
- ignoreCase: false,
-},
-&ruleRefExpr{
- pos: position{line: 106, col: 21, offset: 1980},
- name: "HexDigit",
-},
-&ruleRefExpr{
- pos: position{line: 106, col: 30, offset: 1989},
- name: "HexDigit",
-},
-&ruleRefExpr{
- pos: position{line: 106, col: 39, offset: 1998},
- name: "HexDigit",
-},
-&ruleRefExpr{
- pos: position{line: 106, col: 48, offset: 2007},
- name: "HexDigit",
-},
- },
-},
-},
-{
- name: "HexDigit",
- pos: position{line: 108, col: 1, offset: 2017},
- expr: &charClassMatcher{
- pos: position{line: 108, col: 12, offset: 2030},
- val: "[0-9a-f]i",
- ranges: []rune{'0','9','a','f',},
- ignoreCase: true,
- inverted: false,
-},
-},
-{
- name: "_",
- displayName: "\"whitespace\"",
- pos: position{line: 110, col: 1, offset: 2041},
- expr: &zeroOrMoreExpr{
- pos: position{line: 110, col: 18, offset: 2060},
- expr: &charClassMatcher{
- pos: position{line: 110, col: 18, offset: 2060},
- val: "[ \\n\\t\\r]",
- chars: []rune{' ','\n','\t','\r',},
- ignoreCase: false,
- inverted: false,
-},
-},
-},
-{
- name: "EOF",
- pos: position{line: 112, col: 1, offset: 2072},
- expr: ¬Expr{
- pos: position{line: 112, col: 7, offset: 2080},
- expr: &anyMatcher{
- line: 112, col: 8, offset: 2081,
-},
-},
-},
- },
-}
-func (c *current) onStart1(items_ interface{}) (interface{}, error) {
- items := items_.([]interface{})
- if len(items) == 1 {
- return items[0], nil
- }
- return Tuple(items), nil
-}
-
-func (p *parser) callonStart1() (interface{}, error) {
- stack := p.vstack[len(p.vstack)-1]
- _ = stack
- return p.cur.onStart1(stack["items_"])
-}
-
-func (c *current) onItem1(it interface{}) (interface{}, error) {
- return it, nil
-}
-
-func (p *parser) callonItem1() (interface{}, error) {
- stack := p.vstack[len(p.vstack)-1]
- _ = stack
- return p.cur.onItem1(stack["it"])
-}
-
-func (c *current) onArray1(items interface{}) (interface{}, error) {
- return Array(items.([]interface{})), nil
-}
-
-func (p *parser) callonArray1() (interface{}, error) {
- stack := p.vstack[len(p.vstack)-1]
- _ = stack
- return p.cur.onArray1(stack["items"])
-}
-
-func (c *current) onTuple1(items interface{}) (interface{}, error) {
- return Tuple(items.([]interface{})), nil
-}
-
-func (p *parser) callonTuple1() (interface{}, error) {
- stack := p.vstack[len(p.vstack)-1]
- _ = stack
- return p.cur.onTuple1(stack["items"])
-}
-
-func (c *current) onUntypedNumeric1(number interface{}) (interface{}, error) {
- return Numeric{
- Type: "i",
- Number: number.(string),
- }, nil
-}
-
-func (p *parser) callonUntypedNumeric1() (interface{}, error) {
- stack := p.vstack[len(p.vstack)-1]
- _ = stack
- return p.cur.onUntypedNumeric1(stack["number"])
-}
-
-func (c *current) onTypedNumeric1(t, number interface{}) (interface{}, error) {
- return Numeric{
- Type: t.(string),
- Number: number.(string),
- }, nil
-}
-
-func (p *parser) callonTypedNumeric1() (interface{}, error) {
- stack := p.vstack[len(p.vstack)-1]
- _ = stack
- return p.cur.onTypedNumeric1(stack["t"], stack["number"])
-}
-
-func (c *current) onHexLengthPrefixed1(hexbytes interface{}) (interface{}, error) {
- return NewBytes(hexbytes.([]byte), true), nil
-}
-
-func (p *parser) callonHexLengthPrefixed1() (interface{}, error) {
- stack := p.vstack[len(p.vstack)-1]
- _ = stack
- return p.cur.onHexLengthPrefixed1(stack["hexbytes"])
-}
-
-func (c *current) onHexRaw1(hexbytes interface{}) (interface{}, error) {
- return NewBytes(hexbytes.([]byte), false), nil
-}
-
-func (p *parser) callonHexRaw1() (interface{}, error) {
- stack := p.vstack[len(p.vstack)-1]
- _ = stack
- return p.cur.onHexRaw1(stack["hexbytes"])
-}
-
-func (c *current) onHexBytes1() (interface{}, error) {
- bytez, err := hex.DecodeString(string(c.text))
- if err != nil {
- return nil, err
- }
- return bytez, nil
-}
-
-func (p *parser) callonHexBytes1() (interface{}, error) {
- stack := p.vstack[len(p.vstack)-1]
- _ = stack
- return p.cur.onHexBytes1()
-}
-
-func (c *current) onType1() (interface{}, error) {
- return string(c.text), nil
-}
-
-func (p *parser) callonType1() (interface{}, error) {
- stack := p.vstack[len(p.vstack)-1]
- _ = stack
- return p.cur.onType1()
-}
-
-func (c *current) onInteger1() (interface{}, error) {
- return string(c.text), nil
-}
-
-func (p *parser) callonInteger1() (interface{}, error) {
- stack := p.vstack[len(p.vstack)-1]
- _ = stack
- return p.cur.onInteger1()
-}
-
-func (c *current) onLabel1() (interface{}, error) {
- return string(c.text), nil
-}
-
-func (p *parser) callonLabel1() (interface{}, error) {
- stack := p.vstack[len(p.vstack)-1]
- _ = stack
- return p.cur.onLabel1()
-}
-
-func (c *current) onPlaceholder1(label interface{}) (interface{}, error) {
- return Placeholder{
- Label: label.(string),
- }, nil
-}
-
-func (p *parser) callonPlaceholder1() (interface{}, error) {
- stack := p.vstack[len(p.vstack)-1]
- _ = stack
- return p.cur.onPlaceholder1(stack["label"])
-}
-
-func (c *current) onString1() (interface{}, error) {
- // TODO : the forward slash (solidus) is not a valid escape in Go, it will
- // fail if there's one in the string
- text, err := strconv.Unquote(string(c.text))
- if err != nil {
- return nil, err
- } else {
- return NewString(text), nil
- }
-}
-
-func (p *parser) callonString1() (interface{}, error) {
- stack := p.vstack[len(p.vstack)-1]
- _ = stack
- return p.cur.onString1()
-}
-
-
-var (
- // errNoRule is returned when the grammar to parse has no rule.
- errNoRule = errors.New("grammar has no rule")
-
- // errInvalidEncoding is returned when the source is not properly
- // utf8-encoded.
- errInvalidEncoding = errors.New("invalid encoding")
-
- // errNoMatch is returned if no match could be found.
- errNoMatch = errors.New("no match found")
-)
-
-// Option is a function that can set an option on the parser. It returns
-// the previous setting as an Option.
-type Option func(*parser) Option
-
-// Debug creates an Option to set the debug flag to b. When set to true,
-// debugging information is printed to stdout while parsing.
-//
-// The default is false.
-func Debug(b bool) Option {
- return func(p *parser) Option {
- old := p.debug
- p.debug = b
- return Debug(old)
- }
-}
-
-// Memoize creates an Option to set the memoize flag to b. When set to true,
-// the parser will cache all results so each expression is evaluated only
-// once. This guarantees linear parsing time even for pathological cases,
-// at the expense of more memory and slower times for typical cases.
-//
-// The default is false.
-func Memoize(b bool) Option {
- return func(p *parser) Option {
- old := p.memoize
- p.memoize = b
- return Memoize(old)
- }
-}
-
-// Recover creates an Option to set the recover flag to b. When set to
-// true, this causes the parser to recover from panics and convert it
-// to an error. Setting it to false can be useful while debugging to
-// access the full stack trace.
-//
-// The default is true.
-func Recover(b bool) Option {
- return func(p *parser) Option {
- old := p.recover
- p.recover = b
- return Recover(old)
- }
-}
-
-// ParseFile parses the file identified by filename.
-func ParseFile(filename string, opts ...Option) (interface{}, error) {
- f, err := os.Open(filename)
- if err != nil {
- return nil, err
- }
- defer f.Close()
- return ParseReader(filename, f, opts...)
-}
-
-// ParseReader parses the data from r using filename as information in the
-// error messages.
-func ParseReader(filename string, r io.Reader, opts ...Option) (interface{}, error) {
- b, err := ioutil.ReadAll(r)
- if err != nil {
- return nil, err
- }
-
- return Parse(filename, b, opts...)
-}
-
-// Parse parses the data from b using filename as information in the
-// error messages.
-func Parse(filename string, b []byte, opts ...Option) (interface{}, error) {
- return newParser(filename, b, opts...).parse(g)
-}
-
-// position records a position in the text.
-type position struct {
- line, col, offset int
-}
-
-func (p position) String() string {
- return fmt.Sprintf("%d:%d [%d]", p.line, p.col, p.offset)
-}
-
-// savepoint stores all state required to go back to this point in the
-// parser.
-type savepoint struct {
- position
- rn rune
- w int
-}
-
-type current struct {
- pos position // start position of the match
- text []byte // raw text of the match
-}
-
-// the AST types...
-
-type grammar struct {
- pos position
- rules []*rule
-}
-
-type rule struct {
- pos position
- name string
- displayName string
- expr interface{}
-}
-
-type choiceExpr struct {
- pos position
- alternatives []interface{}
-}
-
-type actionExpr struct {
- pos position
- expr interface{}
- run func(*parser) (interface{}, error)
-}
-
-type seqExpr struct {
- pos position
- exprs []interface{}
-}
-
-type labeledExpr struct {
- pos position
- label string
- expr interface{}
-}
-
-type expr struct {
- pos position
- expr interface{}
-}
-
-type andExpr expr
-type notExpr expr
-type zeroOrOneExpr expr
-type zeroOrMoreExpr expr
-type oneOrMoreExpr expr
-
-type ruleRefExpr struct {
- pos position
- name string
-}
-
-type andCodeExpr struct {
- pos position
- run func(*parser) (bool, error)
-}
-
-type notCodeExpr struct {
- pos position
- run func(*parser) (bool, error)
-}
-
-type litMatcher struct {
- pos position
- val string
- ignoreCase bool
-}
-
-type charClassMatcher struct {
- pos position
- val string
- chars []rune
- ranges []rune
- classes []*unicode.RangeTable
- ignoreCase bool
- inverted bool
-}
-
-type anyMatcher position
-
-// errList cumulates the errors found by the parser.
-type errList []error
-
-func (e *errList) add(err error) {
- *e = append(*e, err)
-}
-
-func (e errList) err() error {
- if len(e) == 0 {
- return nil
- }
- e.dedupe()
- return e
-}
-
-func (e *errList) dedupe() {
- var cleaned []error
- set := make(map[string]bool)
- for _, err := range *e {
- if msg := err.Error(); !set[msg] {
- set[msg] = true
- cleaned = append(cleaned, err)
- }
- }
- *e = cleaned
-}
-
-func (e errList) Error() string {
- switch len(e) {
- case 0:
- return ""
- case 1:
- return e[0].Error()
- default:
- var buf bytes.Buffer
-
- for i, err := range e {
- if i > 0 {
- buf.WriteRune('\n')
- }
- buf.WriteString(err.Error())
- }
- return buf.String()
- }
-}
-
-// parserError wraps an error with a prefix indicating the rule in which
-// the error occurred. The original error is stored in the Inner field.
-type parserError struct {
- Inner error
- pos position
- prefix string
-}
-
-// Error returns the error message.
-func (p *parserError) Error() string {
- return p.prefix + ": " + p.Inner.Error()
-}
-
-// newParser creates a parser with the specified input source and options.
-func newParser(filename string, b []byte, opts ...Option) *parser {
- p := &parser{
- filename: filename,
- errs: new(errList),
- data: b,
- pt: savepoint{position: position{line: 1}},
- recover: true,
- }
- p.setOptions(opts)
- return p
-}
-
-// setOptions applies the options to the parser.
-func (p *parser) setOptions(opts []Option) {
- for _, opt := range opts {
- opt(p)
- }
-}
-
-type resultTuple struct {
- v interface{}
- b bool
- end savepoint
-}
-
-type parser struct {
- filename string
- pt savepoint
- cur current
-
- data []byte
- errs *errList
-
- recover bool
- debug bool
- depth int
-
- memoize bool
- // memoization table for the packrat algorithm:
- // map[offset in source] map[expression or rule] {value, match}
- memo map[int]map[interface{}]resultTuple
-
- // rules table, maps the rule identifier to the rule node
- rules map[string]*rule
- // variables stack, map of label to value
- vstack []map[string]interface{}
- // rule stack, allows identification of the current rule in errors
- rstack []*rule
-
- // stats
- exprCnt int
-}
-
-// push a variable set on the vstack.
-func (p *parser) pushV() {
- if cap(p.vstack) == len(p.vstack) {
- // create new empty slot in the stack
- p.vstack = append(p.vstack, nil)
- } else {
- // slice to 1 more
- p.vstack = p.vstack[:len(p.vstack)+1]
- }
-
- // get the last args set
- m := p.vstack[len(p.vstack)-1]
- if m != nil && len(m) == 0 {
- // empty map, all good
- return
- }
-
- m = make(map[string]interface{})
- p.vstack[len(p.vstack)-1] = m
-}
-
-// pop a variable set from the vstack.
-func (p *parser) popV() {
- // if the map is not empty, clear it
- m := p.vstack[len(p.vstack)-1]
- if len(m) > 0 {
- // GC that map
- p.vstack[len(p.vstack)-1] = nil
- }
- p.vstack = p.vstack[:len(p.vstack)-1]
-}
-
-func (p *parser) print(prefix, s string) string {
- if !p.debug {
- return s
- }
-
- fmt.Printf("%s %d:%d:%d: %s [%#U]\n",
- prefix, p.pt.line, p.pt.col, p.pt.offset, s, p.pt.rn)
- return s
-}
-
-func (p *parser) in(s string) string {
- p.depth++
- return p.print(strings.Repeat(" ", p.depth) + ">", s)
-}
-
-func (p *parser) out(s string) string {
- p.depth--
- return p.print(strings.Repeat(" ", p.depth) + "<", s)
-}
-
-func (p *parser) addErr(err error) {
- p.addErrAt(err, p.pt.position)
-}
-
-func (p *parser) addErrAt(err error, pos position) {
- var buf bytes.Buffer
- if p.filename != "" {
- buf.WriteString(p.filename)
- }
- if buf.Len() > 0 {
- buf.WriteString(":")
- }
- buf.WriteString(fmt.Sprintf("%d:%d (%d)", pos.line, pos.col, pos.offset))
- if len(p.rstack) > 0 {
- if buf.Len() > 0 {
- buf.WriteString(": ")
- }
- rule := p.rstack[len(p.rstack)-1]
- if rule.displayName != "" {
- buf.WriteString("rule " + rule.displayName)
- } else {
- buf.WriteString("rule " + rule.name)
- }
- }
- pe := &parserError{Inner: err, prefix: buf.String()}
- p.errs.add(pe)
-}
-
-// read advances the parser to the next rune.
-func (p *parser) read() {
- p.pt.offset += p.pt.w
- rn, n := utf8.DecodeRune(p.data[p.pt.offset:])
- p.pt.rn = rn
- p.pt.w = n
- p.pt.col++
- if rn == '\n' {
- p.pt.line++
- p.pt.col = 0
- }
-
- if rn == utf8.RuneError {
- if n > 0 {
- p.addErr(errInvalidEncoding)
- }
- }
-}
-
-// restore parser position to the savepoint pt.
-func (p *parser) restore(pt savepoint) {
- if p.debug {
- defer p.out(p.in("restore"))
- }
- if pt.offset == p.pt.offset {
- return
- }
- p.pt = pt
-}
-
-// get the slice of bytes from the savepoint start to the current position.
-func (p *parser) sliceFrom(start savepoint) []byte {
- return p.data[start.position.offset:p.pt.position.offset]
-}
-
-func (p *parser) getMemoized(node interface{}) (resultTuple, bool) {
- if len(p.memo) == 0 {
- return resultTuple{}, false
- }
- m := p.memo[p.pt.offset]
- if len(m) == 0 {
- return resultTuple{}, false
- }
- res, ok := m[node]
- return res, ok
-}
-
-func (p *parser) setMemoized(pt savepoint, node interface{}, tuple resultTuple) {
- if p.memo == nil {
- p.memo = make(map[int]map[interface{}]resultTuple)
- }
- m := p.memo[pt.offset]
- if m == nil {
- m = make(map[interface{}]resultTuple)
- p.memo[pt.offset] = m
- }
- m[node] = tuple
-}
-
-func (p *parser) buildRulesTable(g *grammar) {
- p.rules = make(map[string]*rule, len(g.rules))
- for _, r := range g.rules {
- p.rules[r.name] = r
- }
-}
-
-func (p *parser) parse(g *grammar) (val interface{}, err error) {
- if len(g.rules) == 0 {
- p.addErr(errNoRule)
- return nil, p.errs.err()
- }
-
- // TODO : not super critical but this could be generated
- p.buildRulesTable(g)
-
- if p.recover {
- // panic can be used in action code to stop parsing immediately
- // and return the panic as an error.
- defer func() {
- if e := recover(); e != nil {
- if p.debug {
- defer p.out(p.in("panic handler"))
- }
- val = nil
- switch e := e.(type) {
- case error:
- p.addErr(e)
- default:
- p.addErr(fmt.Errorf("%v", e))
- }
- err = p.errs.err()
- }
- }()
- }
-
- // start rule is rule [0]
- p.read() // advance to first rune
- val, ok := p.parseRule(g.rules[0])
- if !ok {
- if len(*p.errs) == 0 {
- // make sure this doesn't go out silently
- p.addErr(errNoMatch)
- }
- return nil, p.errs.err()
- }
- return val, p.errs.err()
-}
-
-func (p *parser) parseRule(rule *rule) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseRule " + rule.name))
- }
-
- if p.memoize {
- res, ok := p.getMemoized(rule)
- if ok {
- p.restore(res.end)
- return res.v, res.b
- }
- }
-
- start := p.pt
- p.rstack = append(p.rstack, rule)
- p.pushV()
- val, ok := p.parseExpr(rule.expr)
- p.popV()
- p.rstack = p.rstack[:len(p.rstack)-1]
- if ok && p.debug {
- p.print(strings.Repeat(" ", p.depth) + "MATCH", string(p.sliceFrom(start)))
- }
-
- if p.memoize {
- p.setMemoized(start, rule, resultTuple{val, ok, p.pt})
- }
- return val, ok
-}
-
-func (p *parser) parseExpr(expr interface{}) (interface{}, bool) {
- var pt savepoint
- var ok bool
-
- if p.memoize {
- res, ok := p.getMemoized(expr)
- if ok {
- p.restore(res.end)
- return res.v, res.b
- }
- pt = p.pt
- }
-
- p.exprCnt++
- var val interface{}
- switch expr := expr.(type) {
- case *actionExpr:
- val, ok = p.parseActionExpr(expr)
- case *andCodeExpr:
- val, ok = p.parseAndCodeExpr(expr)
- case *andExpr:
- val, ok = p.parseAndExpr(expr)
- case *anyMatcher:
- val, ok = p.parseAnyMatcher(expr)
- case *charClassMatcher:
- val, ok = p.parseCharClassMatcher(expr)
- case *choiceExpr:
- val, ok = p.parseChoiceExpr(expr)
- case *labeledExpr:
- val, ok = p.parseLabeledExpr(expr)
- case *litMatcher:
- val, ok = p.parseLitMatcher(expr)
- case *notCodeExpr:
- val, ok = p.parseNotCodeExpr(expr)
- case *notExpr:
- val, ok = p.parseNotExpr(expr)
- case *oneOrMoreExpr:
- val, ok = p.parseOneOrMoreExpr(expr)
- case *ruleRefExpr:
- val, ok = p.parseRuleRefExpr(expr)
- case *seqExpr:
- val, ok = p.parseSeqExpr(expr)
- case *zeroOrMoreExpr:
- val, ok = p.parseZeroOrMoreExpr(expr)
- case *zeroOrOneExpr:
- val, ok = p.parseZeroOrOneExpr(expr)
- default:
- panic(fmt.Sprintf("unknown expression type %T", expr))
- }
- if p.memoize {
- p.setMemoized(pt, expr, resultTuple{val, ok, p.pt})
- }
- return val, ok
-}
-
-func (p *parser) parseActionExpr(act *actionExpr) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseActionExpr"))
- }
-
- start := p.pt
- val, ok := p.parseExpr(act.expr)
- if ok {
- p.cur.pos = start.position
- p.cur.text = p.sliceFrom(start)
- actVal, err := act.run(p)
- if err != nil {
- p.addErrAt(err, start.position)
- }
- val = actVal
- }
- if ok && p.debug {
- p.print(strings.Repeat(" ", p.depth) + "MATCH", string(p.sliceFrom(start)))
- }
- return val, ok
-}
-
-func (p *parser) parseAndCodeExpr(and *andCodeExpr) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseAndCodeExpr"))
- }
-
- ok, err := and.run(p)
- if err != nil {
- p.addErr(err)
- }
- return nil, ok
-}
-
-func (p *parser) parseAndExpr(and *andExpr) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseAndExpr"))
- }
-
- pt := p.pt
- p.pushV()
- _, ok := p.parseExpr(and.expr)
- p.popV()
- p.restore(pt)
- return nil, ok
-}
-
-func (p *parser) parseAnyMatcher(any *anyMatcher) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseAnyMatcher"))
- }
-
- if p.pt.rn != utf8.RuneError {
- start := p.pt
- p.read()
- return p.sliceFrom(start), true
- }
- return nil, false
-}
-
-func (p *parser) parseCharClassMatcher(chr *charClassMatcher) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseCharClassMatcher"))
- }
-
- cur := p.pt.rn
- // can't match EOF
- if cur == utf8.RuneError {
- return nil, false
- }
- start := p.pt
- if chr.ignoreCase {
- cur = unicode.ToLower(cur)
- }
-
- // try to match in the list of available chars
- for _, rn := range chr.chars {
- if rn == cur {
- if chr.inverted {
- return nil, false
- }
- p.read()
- return p.sliceFrom(start), true
- }
- }
-
- // try to match in the list of ranges
- for i := 0; i < len(chr.ranges); i += 2 {
- if cur >= chr.ranges[i] && cur <= chr.ranges[i+1] {
- if chr.inverted {
- return nil, false
- }
- p.read()
- return p.sliceFrom(start), true
- }
- }
-
- // try to match in the list of Unicode classes
- for _, cl := range chr.classes {
- if unicode.Is(cl, cur) {
- if chr.inverted {
- return nil, false
- }
- p.read()
- return p.sliceFrom(start), true
- }
- }
-
- if chr.inverted {
- p.read()
- return p.sliceFrom(start), true
- }
- return nil, false
-}
-
-func (p *parser) parseChoiceExpr(ch *choiceExpr) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseChoiceExpr"))
- }
-
- for _, alt := range ch.alternatives {
- p.pushV()
- val, ok := p.parseExpr(alt)
- p.popV()
- if ok {
- return val, ok
- }
- }
- return nil, false
-}
-
-func (p *parser) parseLabeledExpr(lab *labeledExpr) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseLabeledExpr"))
- }
-
- p.pushV()
- val, ok := p.parseExpr(lab.expr)
- p.popV()
- if ok && lab.label != "" {
- m := p.vstack[len(p.vstack)-1]
- m[lab.label] = val
- }
- return val, ok
-}
-
-func (p *parser) parseLitMatcher(lit *litMatcher) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseLitMatcher"))
- }
-
- start := p.pt
- for _, want := range lit.val {
- cur := p.pt.rn
- if lit.ignoreCase {
- cur = unicode.ToLower(cur)
- }
- if cur != want {
- p.restore(start)
- return nil, false
- }
- p.read()
- }
- return p.sliceFrom(start), true
-}
-
-func (p *parser) parseNotCodeExpr(not *notCodeExpr) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseNotCodeExpr"))
- }
-
- ok, err := not.run(p)
- if err != nil {
- p.addErr(err)
- }
- return nil, !ok
-}
-
-func (p *parser) parseNotExpr(not *notExpr) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseNotExpr"))
- }
-
- pt := p.pt
- p.pushV()
- _, ok := p.parseExpr(not.expr)
- p.popV()
- p.restore(pt)
- return nil, !ok
-}
-
-func (p *parser) parseOneOrMoreExpr(expr *oneOrMoreExpr) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseOneOrMoreExpr"))
- }
-
- var vals []interface{}
-
- for {
- p.pushV()
- val, ok := p.parseExpr(expr.expr)
- p.popV()
- if !ok {
- if len(vals) == 0 {
- // did not match once, no match
- return nil, false
- }
- return vals, true
- }
- vals = append(vals, val)
- }
-}
-
-func (p *parser) parseRuleRefExpr(ref *ruleRefExpr) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseRuleRefExpr " + ref.name))
- }
-
- if ref.name == "" {
- panic(fmt.Sprintf("%s: invalid rule: missing name", ref.pos))
- }
-
- rule := p.rules[ref.name]
- if rule == nil {
- p.addErr(fmt.Errorf("undefined rule: %s", ref.name))
- return nil, false
- }
- return p.parseRule(rule)
-}
-
-func (p *parser) parseSeqExpr(seq *seqExpr) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseSeqExpr"))
- }
-
- var vals []interface{}
-
- pt := p.pt
- for _, expr := range seq.exprs {
- val, ok := p.parseExpr(expr)
- if !ok {
- p.restore(pt)
- return nil, false
- }
- vals = append(vals, val)
- }
- return vals, true
-}
-
-func (p *parser) parseZeroOrMoreExpr(expr *zeroOrMoreExpr) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseZeroOrMoreExpr"))
- }
-
- var vals []interface{}
-
- for {
- p.pushV()
- val, ok := p.parseExpr(expr.expr)
- p.popV()
- if !ok {
- return vals, true
- }
- vals = append(vals, val)
- }
-}
-
-func (p *parser) parseZeroOrOneExpr(expr *zeroOrOneExpr) (interface{}, bool) {
- if p.debug {
- defer p.out(p.in("parseZeroOrOneExpr"))
- }
-
- p.pushV()
- val, _ := p.parseExpr(expr.expr)
- p.popV()
- // whether it matched or not, consider it a match
- return val, true
-}
-
-func rangeTable(class string) *unicode.RangeTable {
- if rt, ok := unicode.Categories[class]; ok {
- return rt
- }
- if rt, ok := unicode.Properties[class]; ok {
- return rt
- }
- if rt, ok := unicode.Scripts[class]; ok {
- return rt
- }
-
- // cannot happen
- panic(fmt.Sprintf("invalid Unicode class: %s", class))
-}
-
+++ /dev/null
-{
-package expr
-
-import (
- "bytes"
- "encoding/hex"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "strconv"
- "strings"
- "unicode"
- "unicode/utf8"
-)
-}
-
-Start ← items_:Item+ _ EOF {
- items := items_.([]interface{})
- if len(items) == 1 {
- return items[0], nil
- }
- return Tuple(items), nil
-}
-
-Item ← _ it:(Array / Tuple / Hex / TypedNumeric / UntypedNumeric / Placeholder / String) {
- return it, nil
-}
-
-Array ← '[' items:Item* _ ']' {
- return Array(items.([]interface{})), nil
-}
-
-Tuple ← '(' items:Item+ _ ')' {
- return Tuple(items.([]interface{})), nil
-}
-
-UntypedNumeric ← number:Integer {
- return Numeric{
- Type: "i",
- Number: number.(string),
- }, nil
-}
-
-TypedNumeric ← t:Type ':' number:Integer {
- return Numeric{
- Type: t.(string),
- Number: number.(string),
- }, nil
-}
-
-Hex ← HexLengthPrefixed / HexRaw
-
-HexLengthPrefixed ← "0x" hexbytes:HexBytes {
- return NewBytes(hexbytes.([]byte), true), nil
-}
-
-HexRaw ← "x" hexbytes:HexBytes {
- return NewBytes(hexbytes.([]byte), false), nil
-}
-
-HexBytes ← [0-9abcdefABCDEF]+ {
- bytez, err := hex.DecodeString(string(c.text))
- if err != nil {
- return nil, err
- }
- return bytez, nil
-}
-
-Type ← ("u64" / "i64") {
- return string(c.text), nil
-}
-
-Integer ← '-'? [0-9]+ {
- return string(c.text), nil
-}
-
-Label ← [0-9a-zA-Z:]+ {
- return string(c.text), nil
-}
-
-Placeholder ← '<' label:Label '>' {
- return Placeholder{
- Label: label.(string),
- }, nil
-}
-
-String ← '"' ( !EscapedChar . / '\\' EscapeSequence )* '"' {
- // TODO : the forward slash (solidus) is not a valid escape in Go, it will
- // fail if there's one in the string
- text, err := strconv.Unquote(string(c.text))
- if err != nil {
- return nil, err
- } else {
- return NewString(text), nil
- }
-}
-
-EscapedChar ← [\x00-\x1f"\\]
-
-EscapeSequence ← SingleCharEscape / UnicodeEscape
-
-SingleCharEscape ← ["\\/bfnrt]
-
-UnicodeEscape ← 'u' HexDigit HexDigit HexDigit HexDigit
-
-HexDigit ← [0-9a-f]i
-
-_ "whitespace" ← [ \n\t\r]*
-
-EOF ← !.
+++ /dev/null
-package expr
-
-import (
- "strings"
- "testing"
-
- cmn "github.com/tendermint/tmlibs/common"
-)
-
-func TestParse(t *testing.T) {
- testParse(t, `"foobar"`, `"foobar"`)
- testParse(t, "0x1234", "0x1234")
- testParse(t, "0xbeef", "0xBEEF")
- testParse(t, "xbeef", "xBEEF")
- testParse(t, "12345", "{i 12345}")
- testParse(t, "u64:12345", "{u64 12345}")
- testParse(t, "i64:12345", "{i64 12345}")
- testParse(t, "i64:-12345", "{i64 -12345}")
- testParse(t, "[1 u64:2]", "[{i 1},{u64 2}]")
- testParse(t, "[(1 2) (3 4)]", "[({i 1} {i 2}),({i 3} {i 4})]")
- testParse(t, "0x1234 1 u64:2 [3 4]", "(0x1234 {i 1} {u64 2} [{i 3},{i 4}])")
- testParse(t, "[(1 <sig:user1>)(2 <sig:user2>)][3 4]",
- "([({i 1} <sig:user1>),({i 2} <sig:user2>)] [{i 3},{i 4}])")
-}
-
-func testParse(t *testing.T, input string, expected string) {
- got, err := ParseReader(input, strings.NewReader(input))
- if err != nil {
- t.Error(err.Error())
- return
- }
- gotStr := cmn.Fmt("%v", got)
- if gotStr != expected {
- t.Error(cmn.Fmt("Expected %v, got %v", expected, gotStr))
- }
-}
-
-func TestBytes(t *testing.T) {
- testBytes(t, `"foobar"`, `0106666F6F626172`)
- testBytes(t, "0x1234", "01021234")
- testBytes(t, "0xbeef", "0102BEEF")
- testBytes(t, "xbeef", "BEEF")
- testBytes(t, "12345", "023039")
- testBytes(t, "u64:12345", "0000000000003039")
- testBytes(t, "i64:12345", "0000000000003039")
- testBytes(t, "i64:-12345", "FFFFFFFFFFFFCFC7")
- testBytes(t, "[1 u64:2]", "010201010000000000000002")
- testBytes(t, "[(1 2) (3 4)]", "01020101010201030104")
- testBytes(t, "0x1234 1 u64:2 [3 4]", "0102123401010000000000000002010201030104")
- testBytes(t, "[(1 <sig:user1>)(2 <sig:user2>)][3 4]",
- "0102010100010200010201030104")
-}
-
-func testBytes(t *testing.T, input string, expected string) {
- got, err := ParseReader(input, strings.NewReader(input))
- if err != nil {
- t.Error(err.Error())
- return
- }
- gotBytes, err := got.(Byteful).Bytes()
- if err != nil {
- t.Error(err.Error())
- return
- }
- gotHex := cmn.Fmt("%X", gotBytes)
- if gotHex != expected {
- t.Error(cmn.Fmt("Expected %v, got %v", expected, gotHex))
- }
-}
+++ /dev/null
-package expr
-
-import (
- "errors"
- "strconv"
-
- cmn "github.com/tendermint/tmlibs/common"
- "github.com/tendermint/go-wire"
-)
-
-type Byteful interface {
- Bytes() ([]byte, error)
-}
-
-//----------------------------------------
-
-type Numeric struct {
- Type string
- Number string
-}
-
-func (n Numeric) Bytes() ([]byte, error) {
- num, err := strconv.Atoi(n.Number)
- if err != nil {
- return nil, err
- }
- switch n.Type {
- case "u": // Uvarint
- return wire.BinaryBytes(uint(num)), nil
- case "i": // Varint
- return wire.BinaryBytes(int(num)), nil
- case "u64": // Uint64
- return wire.BinaryBytes(uint64(num)), nil
- case "i64": // Int64
- return wire.BinaryBytes(int64(num)), nil
- case "u32": // Uint32
- return wire.BinaryBytes(uint32(num)), nil
- case "i32": // Int32
- return wire.BinaryBytes(int32(num)), nil
- case "u16": // Uint16
- return wire.BinaryBytes(uint16(num)), nil
- case "i16": // Int16
- return wire.BinaryBytes(int16(num)), nil
- case "u8": // Uint8
- return wire.BinaryBytes(uint8(num)), nil
- case "i8": // Int8
- return wire.BinaryBytes(int8(num)), nil
- }
- return nil, errors.New(cmn.Fmt("Unknown Numeric type %v", n.Type))
-}
-
-//----------------------------------------
-
-type Tuple []interface{}
-
-func (t Tuple) Bytes() ([]byte, error) {
- bz := []byte{}
- for _, item := range t {
- if _, ok := item.(Byteful); !ok {
- return nil, errors.New("Tuple item was not Byteful")
- }
- bzi, err := item.(Byteful).Bytes()
- if err != nil {
- return nil, err
- }
- bz = append(bz, bzi...)
- }
- return bz, nil
-}
-
-func (t Tuple) String() string {
- s := "("
- for i, ti := range t {
- if i == 0 {
- s += cmn.Fmt("%v", ti)
- } else {
- s += cmn.Fmt(" %v", ti)
- }
- }
- s += ")"
- return s
-}
-
-//----------------------------------------
-
-type Array []interface{}
-
-func (arr Array) Bytes() ([]byte, error) {
- bz := wire.BinaryBytes(int(len(arr)))
- for _, item := range arr {
- if _, ok := item.(Byteful); !ok {
- return nil, errors.New("Array item was not Byteful")
- }
- bzi, err := item.(Byteful).Bytes()
- if err != nil {
- return nil, err
- }
- bz = append(bz, bzi...)
- }
- return bz, nil
-}
-
-func (t Array) String() string {
- s := "["
- for i, ti := range t {
- if i == 0 {
- s += cmn.Fmt("%v", ti)
- } else {
- s += cmn.Fmt(",%v", ti)
- }
- }
- s += "]"
- return s
-}
-
-//----------------------------------------
-
-type Bytes struct {
- Data []byte
- LengthPrefixed bool
-}
-
-func NewBytes(bz []byte, lengthPrefixed bool) Bytes {
- return Bytes{
- Data: bz,
- LengthPrefixed: lengthPrefixed,
- }
-}
-
-func (b Bytes) Bytes() ([]byte, error) {
- if b.LengthPrefixed {
- bz := wire.BinaryBytes(len(b.Data))
- bz = append(bz, b.Data...)
- return bz, nil
- } else {
- return b.Data, nil
- }
-}
-
-func (b Bytes) String() string {
- if b.LengthPrefixed {
- return cmn.Fmt("0x%X", []byte(b.Data))
- } else {
- return cmn.Fmt("x%X", []byte(b.Data))
- }
-}
-
-//----------------------------------------
-
-type Placeholder struct {
- Label string
-}
-
-func (p Placeholder) Bytes() ([]byte, error) {
- return []byte{0x00}, nil
-}
-
-func (p Placeholder) String() string {
- return cmn.Fmt("<%v>", p.Label)
-}
-
-//----------------------------------------
-
-type String struct {
- Text string
-}
-
-func NewString(text string) String {
- return String{text}
-}
-
-func (s String) Bytes() ([]byte, error) {
- bz := wire.BinaryBytes(int(len(s.Text)))
- bz = append(bz, []byte(s.Text)...)
- return bz, nil
-}
-
-func (s String) String() string {
- return strconv.Quote(s.Text)
-}
+++ /dev/null
-package expr
-
-import (
- "strings"
-)
-
-func Compile(exprStr string) ([]byte, error) {
- exprObj, err := ParseReader("", strings.NewReader(exprStr))
- if err != nil {
- return nil, err
- }
- bz, err := exprObj.(Byteful).Bytes()
- if err != nil {
- return nil, err
- }
- return bz, err
-}
+++ /dev/null
-# Codegen for Interface Wrappers
-
-We often want to wrap interfaces in structs to help with wire and json serialization. However, there is a lot of boilerplate, so I made this tool. Look at `go-crypto/pubkeyinner_holder.go` for an example of the boilerplate ...
-
-## Setup (one-time)
-
-Before you can run the codegen, you need to install the proper tooling on your system. Just go to the most recent `develop` of `go-wire` and type:
-
-```bash
-make tools
-```
-
-## Testing it out...
-
-Let's see if this works now... go to `go-crypto` and checkout `data-codegen` (if it has not yet been merged into `develop`). Now, to prepare and execute the generator, type:
-
-```bash
-make prepgen
-make codegen
-```
-
-If you see no errors, it works! You can verify by adding some random comments in `pubkeyinner_holder.go` and running `make codegen` again. It will re-generate the code and they will disappear.
-
-## Adding it to your repo
-
-The best time to use it is when you create the interface... otherwise it is a bit of a dance to port code without causing duplicate names and uncompilable code. If this is you, talk to Frey. But best to use this when you start writing all the interfaces.
-
-First, go to the directory that has the interface you want to wrap, and create the following file as `_gen.go`:
-
-```Go
-package main
-
-import (
- _ "github.com/tendermint/go-wire/gen"
-)
-```
-
-Now, go to the interface you want to wrap and place a comment before it. Like:
-
-```Go
-// +gen holder:"Food,Impl[Bling,*Fuzz]"
-type FooInner interface {
- Bar() int
-}
-```
-
-Let's disect what this line means...
-
-```Go
-// +gen holder:"STRUCT_NAME,Impl[IMPLEMENATION_STRUCTS...],(JSON_NAMES,...)"
-```
-
-If you run it with nothing, just `// +gen holder`, it will create a surrounding struct with the name `FooInnerHolder` and register no implementations. This is rarely desired.
-
-If you just add a name, it will apply the name to the surrounding struct. So `// +gen holder:"Food"` leads to...
-
-```Go
-type Food Struct {
- FooInner `json:"unwrap"`
-}
-```
-
-It provides all the helper methods, which is great, but you still have to register the implementations. If you want to use codegen for this, then add a tag called `Impl[]` and include the class names inside the brackets. Prepend `*` if the pointer receiver is what fulfills the interface, so we generate the proper bindings. This will add a `Wrap()` method to those implementations and register them with go-wire (and data) for easy serialization and deserialization.
-
-## Running it in your repo
-
-This will run code from `github.com/tendermin/go-wire/gen` to do the actual codegen, and knowing go, it will look in your vendor directory if you have one... so update glide and make sure you have a recent version of `go-wire:develop` in your vendor dir.
-
-Then... just type `gen` in the same directory... suddenly a brand new file will appear called `fooinner_holder.go` or whatever the interface name was that we wrapped.
-
-Enjoy!
-
-One nice bonus, is if we add methods to the codegen templates, you just have to update go-wire in your vendor dir and re-run `gen` to get the new code.
+++ /dev/null
-package main
-
-import (
- _ "github.com/tendermint/go-wire/gen"
-)
+++ /dev/null
-package ex
-
-import (
- "fmt"
-
- "github.com/tendermint/tmlibs/common"
-)
-
-// +gen wrapper:"Foo,Impl[Bling,*Fuzz],blng,fzz"
-type FooInner interface {
- Bar() int
-}
-
-type Bling struct{}
-
-func (b Bling) Bar() int {
- return common.RandInt()
-}
-
-type Fuzz struct{}
-
-func (f *Fuzz) Bar() int {
- fmt.Println("hello")
- return 42
-}
+++ /dev/null
-// Generated by: main
-// TypeWriter: wrapper
-// Directive: +gen on FooInner
-
-package ex
-
-import (
- "github.com/tendermint/go-wire/data"
-)
-
-// Auto-generated adapters for happily unmarshaling interfaces
-// Apache License 2.0
-// Copyright (c) 2017 Ethan Frey (ethan.frey@tendermint.com)
-
-type Foo struct {
- FooInner "json:\"unwrap\""
-}
-
-var FooMapper = data.NewMapper(Foo{})
-
-func (h Foo) MarshalJSON() ([]byte, error) {
- return FooMapper.ToJSON(h.FooInner)
-}
-
-func (h *Foo) UnmarshalJSON(data []byte) (err error) {
- parsed, err := FooMapper.FromJSON(data)
- if err == nil && parsed != nil {
- h.FooInner = parsed.(FooInner)
- }
- return err
-}
-
-// Unwrap recovers the concrete interface safely (regardless of levels of embeds)
-func (h Foo) Unwrap() FooInner {
- hi := h.FooInner
- for wrap, ok := hi.(Foo); ok; wrap, ok = hi.(Foo) {
- hi = wrap.FooInner
- }
- return hi
-}
-
-func (h Foo) Empty() bool {
- return h.FooInner == nil
-}
-
-/*** below are bindings for each implementation ***/
-
-func init() {
- FooMapper.RegisterImplementation(Bling{}, "blng", 0x1)
-}
-
-func (hi Bling) Wrap() Foo {
- return Foo{hi}
-}
-
-func init() {
- FooMapper.RegisterImplementation(&Fuzz{}, "fzz", 0x2)
-}
-
-func (hi *Fuzz) Wrap() Foo {
- return Foo{hi}
-}
+++ /dev/null
-package gen
-
-import (
- "fmt"
- "io"
- "strings"
-
- "github.com/clipperhouse/typewriter"
-)
-
-func init() {
- err := typewriter.Register(NewWrapperWriter())
- if err != nil {
- panic(err)
- }
-}
-
-type WrapperWriter struct{}
-
-func NewWrapperWriter() *WrapperWriter {
- return &WrapperWriter{}
-}
-
-func (sw *WrapperWriter) Name() string {
- return "wrapper"
-}
-
-func (sw *WrapperWriter) Imports(t typewriter.Type) []typewriter.ImportSpec {
- return []typewriter.ImportSpec{{Path: "github.com/tendermint/go-wire/data"}}
-}
-
-func (sw *WrapperWriter) Write(w io.Writer, t typewriter.Type) error {
- tag, found := t.FindTag(sw)
-
- if !found {
- // nothing to be done
- return nil
- }
-
- license := `// Auto-generated adapters for happily unmarshaling interfaces
-// Apache License 2.0
-// Copyright (c) 2017 Ethan Frey (ethan.frey@tendermint.com)
-`
-
- if _, err := w.Write([]byte(license)); err != nil {
- fmt.Println("write error")
- return err
- }
-
- // prepare parameters
- name := t.Name + "Wrapper"
- if len(tag.Values) > 0 {
- name = tag.Values[0].Name
- }
- m := model{Type: t, Wrapper: name, Inner: t.Name}
-
- // now, first main Wrapper
- v := typewriter.TagValue{Name: "Wrapper"}
- htmpl, err := templates.ByTagValue(t, v)
- if err != nil {
- return err
- }
- if err := htmpl.Execute(w, m); err != nil {
- return err
- }
-
- // Now, add any implementations...
- v.Name = "Register"
- rtmpl, err := templates.ByTagValue(t, v)
- if err != nil {
- return err
- }
-
- for ti, t := range tag.Values {
- if t.Name == "Impl" {
- for i, p := range t.TypeParameters {
- m.Impl = p
- m.Count = i + 1
- ni := ti + i + 1
- if len(tag.Values) > ni {
- m.ImplType = tag.Values[ni].Name
- } else {
- m.ImplType = strings.ToLower(p.Name)
- }
- if err := rtmpl.Execute(w, m); err != nil {
- return err
- }
- }
- }
- }
-
- return nil
-}
-
-type model struct {
- Type typewriter.Type
- Wrapper string
- Inner string
- Impl typewriter.Type // fill in when adding for implementations
- ImplType string
- Count int
-}
+++ /dev/null
-package gen
-
-import (
- "strings"
-
- "github.com/clipperhouse/typewriter"
-)
-
-var templates = typewriter.TemplateSlice{
- wrapper,
- register,
-}
-
-// this is the template for generating the go-data wrappers of an interface
-var wrapper = &typewriter.Template{
- Name: "Wrapper",
- TypeConstraint: typewriter.Constraint{},
- FuncMap: fmap,
- Text: `
-type {{.Wrapper}} struct {
- {{.Inner}} "json:\"unwrap\""
-}
-
-var {{.Wrapper}}Mapper = data.NewMapper({{.Wrapper}}{})
-
-func (h {{.Wrapper}}) MarshalJSON() ([]byte, error) {
- return {{.Wrapper}}Mapper.ToJSON(h.{{.Inner}})
-}
-
-func (h *{{.Wrapper}}) UnmarshalJSON(data []byte) (err error) {
- parsed, err := {{.Wrapper}}Mapper.FromJSON(data)
- if err == nil && parsed != nil {
- h.{{.Inner}} = parsed.({{.Inner}})
- }
- return err
-}
-
-// Unwrap recovers the concrete interface safely (regardless of levels of embeds)
-func (h {{.Wrapper}}) Unwrap() {{.Inner}} {
- hi := h.{{.Inner}}
- for wrap, ok := hi.({{.Wrapper}}); ok; wrap, ok = hi.({{.Wrapper}}) {
- hi = wrap.{{.Inner}}
- }
- return hi
-}
-
-func (h {{.Wrapper}}) Empty() bool {
- return h.{{.Inner}} == nil
-}
-
-/*** below are bindings for each implementation ***/
-`,
-}
-
-var register = &typewriter.Template{
- Name: "Register",
- TypeConstraint: typewriter.Constraint{},
- FuncMap: fmap,
- Text: `
-func init() {
- {{.Wrapper}}Mapper.RegisterImplementation({{ if .Impl.Pointer }}&{{ end }}{{.Impl.Name}}{}, "{{.ImplType }}", 0x{{.Count}})
-}
-
-func (hi {{ if .Impl.Pointer }}*{{ end }}{{.Impl.Name}}) Wrap() {{.Wrapper}} {
- return {{.Wrapper}}{hi}
-}
-`,
-}
-
-var fmap = map[string]interface{}{
- "ToLower": strings.ToLower,
-}
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
-
- data "github.com/tendermint/go-wire/data"
- "github.com/tendermint/go-wire/data/base58"
)
const (
return Executor{cmd, os.Exit}
}
-// PrepareMainCmd is meant for client side libs that want some more flags
-//
-// This adds --encoding (hex, btc, base64) and --output (text, json) to
-// the command. These only really make sense in interactive commands.
-func PrepareMainCmd(cmd *cobra.Command, envPrefix, defautRoot string) Executor {
- cmd.PersistentFlags().StringP(EncodingFlag, "e", "hex", "Binary encoding (hex|b64|btc)")
- cmd.PersistentFlags().StringP(OutputFlag, "o", "text", "Output format (text|json)")
- cmd.PersistentPreRunE = concatCobraCmdFuncs(setEncoding, validateOutput, cmd.PersistentPreRunE)
- return PrepareBaseCmd(cmd, envPrefix, defautRoot)
-}
-
// initEnv sets to use ENV variables if set.
func initEnv(prefix string) {
copyEnvVars(prefix)
return nil
}
-// setEncoding reads the encoding flag
-func setEncoding(cmd *cobra.Command, args []string) error {
- // validate and set encoding
- enc := viper.GetString("encoding")
- switch enc {
- case "hex":
- data.Encoder = data.HexEncoder
- case "b64":
- data.Encoder = data.B64Encoder
- case "btc":
- data.Encoder = base58.BTCEncoder
- default:
- return errors.Errorf("Unsupported encoding: %s", enc)
- }
- return nil
-}
-
func validateOutput(cmd *cobra.Command, args []string) error {
// validate output format
output := viper.GetString(OutputFlag)
+++ /dev/null
-Tendermint Go-Common
-Copyright (C) 2015 Tendermint
-
-
-
- Apache License
- Version 2.0, January 2004
- https://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+++ /dev/null
-package common
-
-func Arr(items ...interface{}) []interface{} {
- return items
-}
+++ /dev/null
-package common
-
-import (
- "encoding/binary"
- "fmt"
- "math/rand"
- "strings"
- "sync"
-)
-
-type BitArray struct {
- mtx sync.Mutex
- Bits int `json:"bits"` // NOTE: persisted via reflect, must be exported
- Elems []uint64 `json:"elems"` // NOTE: persisted via reflect, must be exported
-}
-
-// There is no BitArray whose Size is 0. Use nil instead.
-func NewBitArray(bits int) *BitArray {
- if bits == 0 {
- return nil
- }
- return &BitArray{
- Bits: bits,
- Elems: make([]uint64, (bits+63)/64),
- }
-}
-
-func (bA *BitArray) Size() int {
- if bA == nil {
- return 0
- }
- return bA.Bits
-}
-
-// NOTE: behavior is undefined if i >= bA.Bits
-func (bA *BitArray) GetIndex(i int) bool {
- if bA == nil {
- return false
- }
- bA.mtx.Lock()
- defer bA.mtx.Unlock()
- return bA.getIndex(i)
-}
-
-func (bA *BitArray) getIndex(i int) bool {
- if i >= bA.Bits {
- return false
- }
- return bA.Elems[i/64]&(uint64(1)<<uint(i%64)) > 0
-}
-
-// NOTE: behavior is undefined if i >= bA.Bits
-func (bA *BitArray) SetIndex(i int, v bool) bool {
- if bA == nil {
- return false
- }
- bA.mtx.Lock()
- defer bA.mtx.Unlock()
- return bA.setIndex(i, v)
-}
-
-func (bA *BitArray) setIndex(i int, v bool) bool {
- if i >= bA.Bits {
- return false
- }
- if v {
- bA.Elems[i/64] |= (uint64(1) << uint(i%64))
- } else {
- bA.Elems[i/64] &= ^(uint64(1) << uint(i%64))
- }
- return true
-}
-
-func (bA *BitArray) Copy() *BitArray {
- if bA == nil {
- return nil
- }
- bA.mtx.Lock()
- defer bA.mtx.Unlock()
- return bA.copy()
-}
-
-func (bA *BitArray) copy() *BitArray {
- c := make([]uint64, len(bA.Elems))
- copy(c, bA.Elems)
- return &BitArray{
- Bits: bA.Bits,
- Elems: c,
- }
-}
-
-func (bA *BitArray) copyBits(bits int) *BitArray {
- c := make([]uint64, (bits+63)/64)
- copy(c, bA.Elems)
- return &BitArray{
- Bits: bits,
- Elems: c,
- }
-}
-
-// Returns a BitArray of larger bits size.
-func (bA *BitArray) Or(o *BitArray) *BitArray {
- if bA == nil {
- o.Copy()
- }
- bA.mtx.Lock()
- defer bA.mtx.Unlock()
- c := bA.copyBits(MaxInt(bA.Bits, o.Bits))
- for i := 0; i < len(c.Elems); i++ {
- c.Elems[i] |= o.Elems[i]
- }
- return c
-}
-
-// Returns a BitArray of smaller bit size.
-func (bA *BitArray) And(o *BitArray) *BitArray {
- if bA == nil {
- return nil
- }
- bA.mtx.Lock()
- defer bA.mtx.Unlock()
- return bA.and(o)
-}
-
-func (bA *BitArray) and(o *BitArray) *BitArray {
- c := bA.copyBits(MinInt(bA.Bits, o.Bits))
- for i := 0; i < len(c.Elems); i++ {
- c.Elems[i] &= o.Elems[i]
- }
- return c
-}
-
-func (bA *BitArray) Not() *BitArray {
- if bA == nil {
- return nil // Degenerate
- }
- bA.mtx.Lock()
- defer bA.mtx.Unlock()
- c := bA.copy()
- for i := 0; i < len(c.Elems); i++ {
- c.Elems[i] = ^c.Elems[i]
- }
- return c
-}
-
-func (bA *BitArray) Sub(o *BitArray) *BitArray {
- if bA == nil {
- return nil
- }
- bA.mtx.Lock()
- defer bA.mtx.Unlock()
- if bA.Bits > o.Bits {
- c := bA.copy()
- for i := 0; i < len(o.Elems)-1; i++ {
- c.Elems[i] &= ^c.Elems[i]
- }
- i := len(o.Elems) - 1
- if i >= 0 {
- for idx := i * 64; idx < o.Bits; idx++ {
- // NOTE: each individual GetIndex() call to o is safe.
- c.setIndex(idx, c.getIndex(idx) && !o.GetIndex(idx))
- }
- }
- return c
- } else {
- return bA.and(o.Not()) // Note degenerate case where o == nil
- }
-}
-
-func (bA *BitArray) IsEmpty() bool {
- if bA == nil {
- return true // should this be opposite?
- }
- bA.mtx.Lock()
- defer bA.mtx.Unlock()
- for _, e := range bA.Elems {
- if e > 0 {
- return false
- }
- }
- return true
-}
-
-func (bA *BitArray) IsFull() bool {
- if bA == nil {
- return true
- }
- bA.mtx.Lock()
- defer bA.mtx.Unlock()
-
- // Check all elements except the last
- for _, elem := range bA.Elems[:len(bA.Elems)-1] {
- if (^elem) != 0 {
- return false
- }
- }
-
- // Check that the last element has (lastElemBits) 1's
- lastElemBits := (bA.Bits+63)%64 + 1
- lastElem := bA.Elems[len(bA.Elems)-1]
- return (lastElem+1)&((uint64(1)<<uint(lastElemBits))-1) == 0
-}
-
-func (bA *BitArray) PickRandom() (int, bool) {
- if bA == nil {
- return 0, false
- }
- bA.mtx.Lock()
- defer bA.mtx.Unlock()
-
- length := len(bA.Elems)
- if length == 0 {
- return 0, false
- }
- randElemStart := rand.Intn(length)
- for i := 0; i < length; i++ {
- elemIdx := ((i + randElemStart) % length)
- if elemIdx < length-1 {
- if bA.Elems[elemIdx] > 0 {
- randBitStart := rand.Intn(64)
- for j := 0; j < 64; j++ {
- bitIdx := ((j + randBitStart) % 64)
- if (bA.Elems[elemIdx] & (uint64(1) << uint(bitIdx))) > 0 {
- return 64*elemIdx + bitIdx, true
- }
- }
- PanicSanity("should not happen")
- }
- } else {
- // Special case for last elem, to ignore straggler bits
- elemBits := bA.Bits % 64
- if elemBits == 0 {
- elemBits = 64
- }
- randBitStart := rand.Intn(elemBits)
- for j := 0; j < elemBits; j++ {
- bitIdx := ((j + randBitStart) % elemBits)
- if (bA.Elems[elemIdx] & (uint64(1) << uint(bitIdx))) > 0 {
- return 64*elemIdx + bitIdx, true
- }
- }
- }
- }
- return 0, false
-}
-
-func (bA *BitArray) String() string {
- if bA == nil {
- return "nil-BitArray"
- }
- bA.mtx.Lock()
- defer bA.mtx.Unlock()
- return bA.stringIndented("")
-}
-
-func (bA *BitArray) StringIndented(indent string) string {
- if bA == nil {
- return "nil-BitArray"
- }
- bA.mtx.Lock()
- defer bA.mtx.Unlock()
- return bA.stringIndented(indent)
-}
-
-func (bA *BitArray) stringIndented(indent string) string {
-
- lines := []string{}
- bits := ""
- for i := 0; i < bA.Bits; i++ {
- if bA.getIndex(i) {
- bits += "X"
- } else {
- bits += "_"
- }
- if i%100 == 99 {
- lines = append(lines, bits)
- bits = ""
- }
- if i%10 == 9 {
- bits += " "
- }
- if i%50 == 49 {
- bits += " "
- }
- }
- if len(bits) > 0 {
- lines = append(lines, bits)
- }
- return fmt.Sprintf("BA{%v:%v}", bA.Bits, strings.Join(lines, indent))
-}
-
-func (bA *BitArray) Bytes() []byte {
- bA.mtx.Lock()
- defer bA.mtx.Unlock()
-
- numBytes := (bA.Bits + 7) / 8
- bytes := make([]byte, numBytes)
- for i := 0; i < len(bA.Elems); i++ {
- elemBytes := [8]byte{}
- binary.LittleEndian.PutUint64(elemBytes[:], bA.Elems[i])
- copy(bytes[i*8:], elemBytes[:])
- }
- return bytes
-}
-
-// NOTE: other bitarray o is not locked when reading,
-// so if necessary, caller must copy or lock o prior to calling Update.
-// If bA is nil, does nothing.
-func (bA *BitArray) Update(o *BitArray) {
- if bA == nil {
- return
- }
- bA.mtx.Lock()
- defer bA.mtx.Unlock()
-
- copy(bA.Elems, o.Elems)
-}
+++ /dev/null
-package common
-
-import (
- "bytes"
- "testing"
-)
-
-func randBitArray(bits int) (*BitArray, []byte) {
- src := RandBytes((bits + 7) / 8)
- bA := NewBitArray(bits)
- for i := 0; i < len(src); i++ {
- for j := 0; j < 8; j++ {
- if i*8+j >= bits {
- return bA, src
- }
- setBit := src[i]&(1<<uint(j)) > 0
- bA.SetIndex(i*8+j, setBit)
- }
- }
- return bA, src
-}
-
-func TestAnd(t *testing.T) {
-
- bA1, _ := randBitArray(51)
- bA2, _ := randBitArray(31)
- bA3 := bA1.And(bA2)
-
- if bA3.Bits != 31 {
- t.Error("Expected min bits", bA3.Bits)
- }
- if len(bA3.Elems) != len(bA2.Elems) {
- t.Error("Expected min elems length")
- }
- for i := 0; i < bA3.Bits; i++ {
- expected := bA1.GetIndex(i) && bA2.GetIndex(i)
- if bA3.GetIndex(i) != expected {
- t.Error("Wrong bit from bA3", i, bA1.GetIndex(i), bA2.GetIndex(i), bA3.GetIndex(i))
- }
- }
-}
-
-func TestOr(t *testing.T) {
-
- bA1, _ := randBitArray(51)
- bA2, _ := randBitArray(31)
- bA3 := bA1.Or(bA2)
-
- if bA3.Bits != 51 {
- t.Error("Expected max bits")
- }
- if len(bA3.Elems) != len(bA1.Elems) {
- t.Error("Expected max elems length")
- }
- for i := 0; i < bA3.Bits; i++ {
- expected := bA1.GetIndex(i) || bA2.GetIndex(i)
- if bA3.GetIndex(i) != expected {
- t.Error("Wrong bit from bA3", i, bA1.GetIndex(i), bA2.GetIndex(i), bA3.GetIndex(i))
- }
- }
-}
-
-func TestSub1(t *testing.T) {
-
- bA1, _ := randBitArray(31)
- bA2, _ := randBitArray(51)
- bA3 := bA1.Sub(bA2)
-
- if bA3.Bits != bA1.Bits {
- t.Error("Expected bA1 bits")
- }
- if len(bA3.Elems) != len(bA1.Elems) {
- t.Error("Expected bA1 elems length")
- }
- for i := 0; i < bA3.Bits; i++ {
- expected := bA1.GetIndex(i)
- if bA2.GetIndex(i) {
- expected = false
- }
- if bA3.GetIndex(i) != expected {
- t.Error("Wrong bit from bA3", i, bA1.GetIndex(i), bA2.GetIndex(i), bA3.GetIndex(i))
- }
- }
-}
-
-func TestSub2(t *testing.T) {
-
- bA1, _ := randBitArray(51)
- bA2, _ := randBitArray(31)
- bA3 := bA1.Sub(bA2)
-
- if bA3.Bits != bA1.Bits {
- t.Error("Expected bA1 bits")
- }
- if len(bA3.Elems) != len(bA1.Elems) {
- t.Error("Expected bA1 elems length")
- }
- for i := 0; i < bA3.Bits; i++ {
- expected := bA1.GetIndex(i)
- if i < bA2.Bits && bA2.GetIndex(i) {
- expected = false
- }
- if bA3.GetIndex(i) != expected {
- t.Error("Wrong bit from bA3")
- }
- }
-}
-
-func TestPickRandom(t *testing.T) {
- for idx := 0; idx < 123; idx++ {
- bA1 := NewBitArray(123)
- bA1.SetIndex(idx, true)
- index, ok := bA1.PickRandom()
- if !ok {
- t.Fatal("Expected to pick element but got none")
- }
- if index != idx {
- t.Fatalf("Expected to pick element at %v but got wrong index", idx)
- }
- }
-}
-
-func TestBytes(t *testing.T) {
- bA := NewBitArray(4)
- bA.SetIndex(0, true)
- check := func(bA *BitArray, bz []byte) {
- if !bytes.Equal(bA.Bytes(), bz) {
- panic(Fmt("Expected %X but got %X", bz, bA.Bytes()))
- }
- }
- check(bA, []byte{0x01})
- bA.SetIndex(3, true)
- check(bA, []byte{0x09})
-
- bA = NewBitArray(9)
- check(bA, []byte{0x00, 0x00})
- bA.SetIndex(7, true)
- check(bA, []byte{0x80, 0x00})
- bA.SetIndex(8, true)
- check(bA, []byte{0x80, 0x01})
-
- bA = NewBitArray(16)
- check(bA, []byte{0x00, 0x00})
- bA.SetIndex(7, true)
- check(bA, []byte{0x80, 0x00})
- bA.SetIndex(8, true)
- check(bA, []byte{0x80, 0x01})
- bA.SetIndex(9, true)
- check(bA, []byte{0x80, 0x03})
-}
-
-func TestEmptyFull(t *testing.T) {
- ns := []int{47, 123}
- for _, n := range ns {
- bA := NewBitArray(n)
- if !bA.IsEmpty() {
- t.Fatal("Expected bit array to be empty")
- }
- for i := 0; i < n; i++ {
- bA.SetIndex(i, true)
- }
- if !bA.IsFull() {
- t.Fatal("Expected bit array to be full")
- }
- }
-}
+++ /dev/null
-package common
-
-import (
- "bytes"
-)
-
-// Fingerprint returns the first 6 bytes of a byte slice.
-// If the slice is less than 6 bytes, the fingerprint
-// contains trailing zeroes.
-func Fingerprint(slice []byte) []byte {
- fingerprint := make([]byte, 6)
- copy(fingerprint, slice)
- return fingerprint
-}
-
-func IsZeros(slice []byte) bool {
- for _, byt := range slice {
- if byt != byte(0) {
- return false
- }
- }
- return true
-}
-
-func RightPadBytes(slice []byte, l int) []byte {
- if l < len(slice) {
- return slice
- }
- padded := make([]byte, l)
- copy(padded[0:len(slice)], slice)
- return padded
-}
-
-func LeftPadBytes(slice []byte, l int) []byte {
- if l < len(slice) {
- return slice
- }
- padded := make([]byte, l)
- copy(padded[l-len(slice):], slice)
- return padded
-}
-
-func TrimmedString(b []byte) string {
- trimSet := string([]byte{0})
- return string(bytes.TrimLeft(b, trimSet))
-
-}
+++ /dev/null
-package common
-
-import (
- "fmt"
- "strings"
-)
-
-const (
- ANSIReset = "\x1b[0m"
- ANSIBright = "\x1b[1m"
- ANSIDim = "\x1b[2m"
- ANSIUnderscore = "\x1b[4m"
- ANSIBlink = "\x1b[5m"
- ANSIReverse = "\x1b[7m"
- ANSIHidden = "\x1b[8m"
-
- ANSIFgBlack = "\x1b[30m"
- ANSIFgRed = "\x1b[31m"
- ANSIFgGreen = "\x1b[32m"
- ANSIFgYellow = "\x1b[33m"
- ANSIFgBlue = "\x1b[34m"
- ANSIFgMagenta = "\x1b[35m"
- ANSIFgCyan = "\x1b[36m"
- ANSIFgWhite = "\x1b[37m"
-
- ANSIBgBlack = "\x1b[40m"
- ANSIBgRed = "\x1b[41m"
- ANSIBgGreen = "\x1b[42m"
- ANSIBgYellow = "\x1b[43m"
- ANSIBgBlue = "\x1b[44m"
- ANSIBgMagenta = "\x1b[45m"
- ANSIBgCyan = "\x1b[46m"
- ANSIBgWhite = "\x1b[47m"
-)
-
-// color the string s with color 'color'
-// unless s is already colored
-func treat(s string, color string) string {
- if len(s) > 2 && s[:2] == "\x1b[" {
- return s
- } else {
- return color + s + ANSIReset
- }
-}
-
-func treatAll(color string, args ...interface{}) string {
- var parts []string
- for _, arg := range args {
- parts = append(parts, treat(fmt.Sprintf("%v", arg), color))
- }
- return strings.Join(parts, "")
-}
-
-func Black(args ...interface{}) string {
- return treatAll(ANSIFgBlack, args...)
-}
-
-func Red(args ...interface{}) string {
- return treatAll(ANSIFgRed, args...)
-}
-
-func Green(args ...interface{}) string {
- return treatAll(ANSIFgGreen, args...)
-}
-
-func Yellow(args ...interface{}) string {
- return treatAll(ANSIFgYellow, args...)
-}
-
-func Blue(args ...interface{}) string {
- return treatAll(ANSIFgBlue, args...)
-}
-
-func Magenta(args ...interface{}) string {
- return treatAll(ANSIFgMagenta, args...)
-}
-
-func Cyan(args ...interface{}) string {
- return treatAll(ANSIFgCyan, args...)
-}
-
-func White(args ...interface{}) string {
- return treatAll(ANSIFgWhite, args...)
-}
+++ /dev/null
-package common
-
-import (
- "strings"
- "time"
-
- "github.com/pkg/errors"
-)
-
-// TimeLayout helps to parse a date string of the format YYYY-MM-DD
-// Intended to be used with the following function:
-// time.Parse(TimeLayout, date)
-var TimeLayout = "2006-01-02" //this represents YYYY-MM-DD
-
-// ParseDateRange parses a date range string of the format start:end
-// where the start and end date are of the format YYYY-MM-DD.
-// The parsed dates are time.Time and will return the zero time for
-// unbounded dates, ex:
-// unbounded start: :2000-12-31
-// unbounded end: 2000-12-31:
-func ParseDateRange(dateRange string) (startDate, endDate time.Time, err error) {
- dates := strings.Split(dateRange, ":")
- if len(dates) != 2 {
- err = errors.New("bad date range, must be in format date:date")
- return
- }
- parseDate := func(date string) (out time.Time, err error) {
- if len(date) == 0 {
- return
- }
- out, err = time.Parse(TimeLayout, date)
- return
- }
- startDate, err = parseDate(dates[0])
- if err != nil {
- return
- }
- endDate, err = parseDate(dates[1])
- if err != nil {
- return
- }
- return
-}
+++ /dev/null
-package common
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-)
-
-var (
- date = time.Date(2015, time.Month(12), 31, 0, 0, 0, 0, time.UTC)
- date2 = time.Date(2016, time.Month(12), 31, 0, 0, 0, 0, time.UTC)
- zero time.Time
-)
-
-func TestParseDateRange(t *testing.T) {
- assert := assert.New(t)
-
- var testDates = []struct {
- dateStr string
- start time.Time
- end time.Time
- errNil bool
- }{
- {"2015-12-31:2016-12-31", date, date2, true},
- {"2015-12-31:", date, zero, true},
- {":2016-12-31", zero, date2, true},
- {"2016-12-31", zero, zero, false},
- {"2016-31-12:", zero, zero, false},
- {":2016-31-12", zero, zero, false},
- }
-
- for _, test := range testDates {
- start, end, err := ParseDateRange(test.dateStr)
- if test.errNil {
- assert.Nil(err)
- testPtr := func(want, have time.Time) {
- assert.True(have.Equal(want))
- }
- testPtr(test.start, start)
- testPtr(test.end, end)
- } else {
- assert.NotNil(err)
- }
- }
-}
+++ /dev/null
-package common
-
-import (
- "container/heap"
-)
-
-type Comparable interface {
- Less(o interface{}) bool
-}
-
-//-----------------------------------------------------------------------------
-
-/*
-Example usage:
- h := NewHeap()
-
- h.Push(String("msg1"), 1)
- h.Push(String("msg3"), 3)
- h.Push(String("msg2"), 2)
-
- fmt.Println(h.Pop())
- fmt.Println(h.Pop())
- fmt.Println(h.Pop())
-*/
-
-type Heap struct {
- pq priorityQueue
-}
-
-func NewHeap() *Heap {
- return &Heap{pq: make([]*pqItem, 0)}
-}
-
-func (h *Heap) Len() int64 {
- return int64(len(h.pq))
-}
-
-func (h *Heap) Push(value interface{}, priority Comparable) {
- heap.Push(&h.pq, &pqItem{value: value, priority: priority})
-}
-
-func (h *Heap) Peek() interface{} {
- if len(h.pq) == 0 {
- return nil
- }
- return h.pq[0].value
-}
-
-func (h *Heap) Update(value interface{}, priority Comparable) {
- h.pq.Update(h.pq[0], value, priority)
-}
-
-func (h *Heap) Pop() interface{} {
- item := heap.Pop(&h.pq).(*pqItem)
- return item.value
-}
-
-//-----------------------------------------------------------------------------
-
-///////////////////////
-// From: http://golang.org/pkg/container/heap/#example__priorityQueue
-
-type pqItem struct {
- value interface{}
- priority Comparable
- index int
-}
-
-type priorityQueue []*pqItem
-
-func (pq priorityQueue) Len() int { return len(pq) }
-
-func (pq priorityQueue) Less(i, j int) bool {
- return pq[i].priority.Less(pq[j].priority)
-}
-
-func (pq priorityQueue) Swap(i, j int) {
- pq[i], pq[j] = pq[j], pq[i]
- pq[i].index = i
- pq[j].index = j
-}
-
-func (pq *priorityQueue) Push(x interface{}) {
- n := len(*pq)
- item := x.(*pqItem)
- item.index = n
- *pq = append(*pq, item)
-}
-
-func (pq *priorityQueue) Pop() interface{} {
- old := *pq
- n := len(old)
- item := old[n-1]
- item.index = -1 // for safety
- *pq = old[0 : n-1]
- return item
-}
-
-func (pq *priorityQueue) Update(item *pqItem, value interface{}, priority Comparable) {
- item.value = value
- item.priority = priority
- heap.Fix(pq, item.index)
-}
+++ /dev/null
-package common
-
-import (
- "encoding/binary"
- "sort"
-)
-
-// Sort for []uint64
-
-type Uint64Slice []uint64
-
-func (p Uint64Slice) Len() int { return len(p) }
-func (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] }
-func (p Uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
-func (p Uint64Slice) Sort() { sort.Sort(p) }
-
-func SearchUint64s(a []uint64, x uint64) int {
- return sort.Search(len(a), func(i int) bool { return a[i] >= x })
-}
-
-func (p Uint64Slice) Search(x uint64) int { return SearchUint64s(p, x) }
-
-//--------------------------------------------------------------------------------
-
-func PutUint64LE(dest []byte, i uint64) {
- binary.LittleEndian.PutUint64(dest, i)
-}
-
-func GetUint64LE(src []byte) uint64 {
- return binary.LittleEndian.Uint64(src)
-}
-
-func PutUint64BE(dest []byte, i uint64) {
- binary.BigEndian.PutUint64(dest, i)
-}
-
-func GetUint64BE(src []byte) uint64 {
- return binary.BigEndian.Uint64(src)
-}
-
-func PutInt64LE(dest []byte, i int64) {
- binary.LittleEndian.PutUint64(dest, uint64(i))
-}
-
-func GetInt64LE(src []byte) int64 {
- return int64(binary.LittleEndian.Uint64(src))
-}
-
-func PutInt64BE(dest []byte, i int64) {
- binary.BigEndian.PutUint64(dest, uint64(i))
-}
-
-func GetInt64BE(src []byte) int64 {
- return int64(binary.BigEndian.Uint64(src))
-}
+++ /dev/null
-package common
-
-import (
- "bytes"
- "errors"
- "io"
-)
-
-type PrefixedReader struct {
- Prefix []byte
- reader io.Reader
-}
-
-func NewPrefixedReader(prefix []byte, reader io.Reader) *PrefixedReader {
- return &PrefixedReader{prefix, reader}
-}
-
-func (pr *PrefixedReader) Read(p []byte) (n int, err error) {
- if len(pr.Prefix) > 0 {
- read := copy(p, pr.Prefix)
- pr.Prefix = pr.Prefix[read:]
- return read, nil
- } else {
- return pr.reader.Read(p)
- }
-}
-
-// NOTE: Not goroutine safe
-type BufferCloser struct {
- bytes.Buffer
- Closed bool
-}
-
-func NewBufferCloser(buf []byte) *BufferCloser {
- return &BufferCloser{
- *bytes.NewBuffer(buf),
- false,
- }
-}
-
-func (bc *BufferCloser) Close() error {
- if bc.Closed {
- return errors.New("BufferCloser already closed")
- }
- bc.Closed = true
- return nil
-}
-
-func (bc *BufferCloser) Write(p []byte) (n int, err error) {
- if bc.Closed {
- return 0, errors.New("Cannot write to closed BufferCloser")
- }
- return bc.Buffer.Write(p)
-}
-
-func (bc *BufferCloser) WriteByte(c byte) error {
- if bc.Closed {
- return errors.New("Cannot write to closed BufferCloser")
- }
- return bc.Buffer.WriteByte(c)
-}
-
-func (bc *BufferCloser) WriteRune(r rune) (n int, err error) {
- if bc.Closed {
- return 0, errors.New("Cannot write to closed BufferCloser")
- }
- return bc.Buffer.WriteRune(r)
-}
-
-func (bc *BufferCloser) WriteString(s string) (n int, err error) {
- if bc.Closed {
- return 0, errors.New("Cannot write to closed BufferCloser")
- }
- return bc.Buffer.WriteString(s)
-}
+++ /dev/null
-package common
-
-import (
- "net"
- "strings"
-)
-
-// Connect dials the given address and returns a net.Conn. The protoAddr argument should be prefixed with the protocol,
-// eg. "tcp://127.0.0.1:8080" or "unix:///tmp/test.sock"
-func Connect(protoAddr string) (net.Conn, error) {
- proto, address := ProtocolAndAddress(protoAddr)
- conn, err := net.Dial(proto, address)
- return conn, err
-}
-
-// ProtocolAndAddress splits an address into the protocol and address components.
-// For instance, "tcp://127.0.0.1:8080" will be split into "tcp" and "127.0.0.1:8080".
-// If the address has no protocol prefix, the default is "tcp".
-func ProtocolAndAddress(listenAddr string) (string, string) {
- protocol, address := "tcp", listenAddr
- parts := strings.SplitN(address, "://", 2)
- if len(parts) == 2 {
- protocol, address = parts[0], parts[1]
- }
- return protocol, address
-}
+++ /dev/null
-package common
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestProtocolAndAddress(t *testing.T) {
-
- cases := []struct {
- fullAddr string
- proto string
- addr string
- }{
- {
- "tcp://mydomain:80",
- "tcp",
- "mydomain:80",
- },
- {
- "mydomain:80",
- "tcp",
- "mydomain:80",
- },
- {
- "unix://mydomain:80",
- "unix",
- "mydomain:80",
- },
- }
-
- for _, c := range cases {
- proto, addr := ProtocolAndAddress(c.fullAddr)
- assert.Equal(t, proto, c.proto)
- assert.Equal(t, addr, c.addr)
- }
-}
package common
import (
- "bufio"
"fmt"
- "io"
"io/ioutil"
"os"
- "os/exec"
"os/signal"
- "path/filepath"
- "strings"
"syscall"
)
-var gopath string
-
-// GoPath returns GOPATH env variable value. If it is not set, this function
-// will try to call `go env GOPATH` subcommand.
-func GoPath() string {
- if gopath != "" {
- return gopath
- }
-
- path := os.Getenv("GOPATH")
- if len(path) == 0 {
- goCmd := exec.Command("go", "env", "GOPATH")
- out, err := goCmd.Output()
- if err != nil {
- panic(fmt.Sprintf("failed to determine gopath: %v", err))
- }
- path = string(out)
- }
- gopath = path
- return path
-}
-
// TrapSignal catches the SIGTERM and executes cb function. After that it exits
// with code 1.
func TrapSignal(cb func()) {
select {}
}
-// Kill the running process by sending itself SIGTERM.
-func Kill() error {
- p, err := os.FindProcess(os.Getpid())
- if err != nil {
- return err
- }
- return p.Signal(syscall.SIGTERM)
-}
-
func Exit(s string) {
fmt.Printf(s + "\n")
os.Exit(1)
return nil
}
-func IsDirEmpty(name string) (bool, error) {
- f, err := os.Open(name)
- if err != nil {
- if os.IsNotExist(err) {
- return true, err
- }
- // Otherwise perhaps a permission
- // error or some other error.
- return false, err
- }
- defer f.Close()
-
- _, err = f.Readdirnames(1) // Or f.Readdir(1)
- if err == io.EOF {
- return true, nil
- }
- return false, err // Either not empty or error, suits both cases
-}
-
func FileExists(filePath string) bool {
_, err := os.Stat(filePath)
return !os.IsNotExist(err)
}
-func ReadFile(filePath string) ([]byte, error) {
- return ioutil.ReadFile(filePath)
-}
-
-func MustReadFile(filePath string) []byte {
- fileBytes, err := ioutil.ReadFile(filePath)
- if err != nil {
- Exit(Fmt("MustReadFile failed: %v", err))
- return nil
- }
- return fileBytes
-}
-
func WriteFile(filePath string, contents []byte, mode os.FileMode) error {
return ioutil.WriteFile(filePath, contents, mode)
}
Exit(Fmt("MustWriteFile failed: %v", err))
}
}
-
-// WriteFileAtomic writes newBytes to temp and atomically moves to filePath
-// when everything else succeeds.
-func WriteFileAtomic(filePath string, newBytes []byte, mode os.FileMode) error {
- dir := filepath.Dir(filePath)
- f, err := ioutil.TempFile(dir, "")
- if err != nil {
- return err
- }
- _, err = f.Write(newBytes)
- if err == nil {
- err = f.Sync()
- }
- if closeErr := f.Close(); err == nil {
- err = closeErr
- }
- if permErr := os.Chmod(f.Name(), mode); err == nil {
- err = permErr
- }
- if err == nil {
- err = os.Rename(f.Name(), filePath)
- }
- // any err should result in full cleanup
- if err != nil {
- os.Remove(f.Name())
- }
- return err
-}
-
-//--------------------------------------------------------------------------------
-
-func Tempfile(prefix string) (*os.File, string) {
- file, err := ioutil.TempFile("", prefix)
- if err != nil {
- PanicCrisis(err)
- }
- return file, file.Name()
-}
-
-func Tempdir(prefix string) (*os.File, string) {
- tempDir := os.TempDir() + "/" + prefix + RandStr(12)
- err := EnsureDir(tempDir, 0700)
- if err != nil {
- panic(Fmt("Error creating temp dir: %v", err))
- }
- dir, err := os.Open(tempDir)
- if err != nil {
- panic(Fmt("Error opening temp dir: %v", err))
- }
- return dir, tempDir
-}
-
-//--------------------------------------------------------------------------------
-
-func Prompt(prompt string, defaultValue string) (string, error) {
- fmt.Print(prompt)
- reader := bufio.NewReader(os.Stdin)
- line, err := reader.ReadString('\n')
- if err != nil {
- return defaultValue, err
- } else {
- line = strings.TrimSpace(line)
- if line == "" {
- return defaultValue, nil
- }
- return line, nil
- }
-}
+++ /dev/null
-package common
-
-import (
- "bytes"
- "fmt"
- "io/ioutil"
- "os"
- "testing"
- "time"
-)
-
-func TestWriteFileAtomic(t *testing.T) {
- data := []byte("Becatron")
- fname := fmt.Sprintf("/tmp/write-file-atomic-test-%v.txt", time.Now().UnixNano())
- err := WriteFileAtomic(fname, data, 0664)
- if err != nil {
- t.Fatal(err)
- }
- rData, err := ioutil.ReadFile(fname)
- if err != nil {
- t.Fatal(err)
- }
- if !bytes.Equal(data, rData) {
- t.Fatalf("data mismatch: %v != %v", data, rData)
- }
- if err := os.Remove(fname); err != nil {
- t.Fatal(err)
- }
-}
-
-func TestGoPath(t *testing.T) {
- // restore original gopath upon exit
- path := os.Getenv("GOPATH")
- defer func() {
- _ = os.Setenv("GOPATH", path)
- }()
-
- err := os.Setenv("GOPATH", "~/testgopath")
- if err != nil {
- t.Fatal(err)
- }
- path = GoPath()
- if path != "~/testgopath" {
- t.Fatalf("should get GOPATH env var value, got %v", path)
- }
- os.Unsetenv("GOPATH")
-
- path = GoPath()
- if path != "~/testgopath" {
- t.Fatalf("subsequent calls should return the same value, got %v", path)
- }
-}
-
-func TestGoPathWithoutEnvVar(t *testing.T) {
- // restore original gopath upon exit
- path := os.Getenv("GOPATH")
- defer func() {
- _ = os.Setenv("GOPATH", path)
- }()
-
- os.Unsetenv("GOPATH")
- // reset cache
- gopath = ""
-
- path = GoPath()
- if path == "" || path == "~/testgopath" {
- t.Fatalf("should get nonempty result of calling go env GOPATH, got %v", path)
- }
-}
+++ /dev/null
-package common
-
-import (
- "sync"
- "time"
-)
-
-/*
-RepeatTimer repeatedly sends a struct{}{} to .Ch after each "dur" period.
-It's good for keeping connections alive.
-A RepeatTimer must be Stop()'d or it will keep a goroutine alive.
-*/
-type RepeatTimer struct {
- Ch chan time.Time
-
- mtx sync.Mutex
- name string
- ticker *time.Ticker
- quit chan struct{}
- wg *sync.WaitGroup
- dur time.Duration
-}
-
-func NewRepeatTimer(name string, dur time.Duration) *RepeatTimer {
- var t = &RepeatTimer{
- Ch: make(chan time.Time),
- ticker: time.NewTicker(dur),
- quit: make(chan struct{}),
- wg: new(sync.WaitGroup),
- name: name,
- dur: dur,
- }
- t.wg.Add(1)
- go t.fireRoutine(t.ticker)
- return t
-}
-
-func (t *RepeatTimer) fireRoutine(ticker *time.Ticker) {
- for {
- select {
- case t_ := <-ticker.C:
- t.Ch <- t_
- case <-t.quit:
- // needed so we know when we can reset t.quit
- t.wg.Done()
- return
- }
- }
-}
-
-// Wait the duration again before firing.
-func (t *RepeatTimer) Reset() {
- t.Stop()
-
- t.mtx.Lock() // Lock
- defer t.mtx.Unlock()
-
- t.ticker = time.NewTicker(t.dur)
- t.quit = make(chan struct{})
- t.wg.Add(1)
- go t.fireRoutine(t.ticker)
-}
-
-// For ease of .Stop()'ing services before .Start()'ing them,
-// we ignore .Stop()'s on nil RepeatTimers.
-func (t *RepeatTimer) Stop() bool {
- if t == nil {
- return false
- }
- t.mtx.Lock() // Lock
- defer t.mtx.Unlock()
-
- exists := t.ticker != nil
- if exists {
- t.ticker.Stop() // does not close the channel
- select {
- case <-t.Ch:
- // read off channel if there's anything there
- default:
- }
- close(t.quit)
- t.wg.Wait() // must wait for quit to close else we race Reset
- t.ticker = nil
- }
- return exists
-}
func (bs *BaseService) String() string {
return bs.name
}
-
-//----------------------------------------
-
-type QuitService struct {
- BaseService
-}
-
-func NewQuitService(logger log.Logger, name string, impl Service) *QuitService {
- if logger != nil {
- logger.Info("QuitService is deprecated, use BaseService instead")
- }
- return &QuitService{
- BaseService: *NewBaseService(logger, name, impl),
- }
-}
+++ /dev/null
-package common
-
-import (
- "bytes"
- "sort"
-)
-
-var (
- Zero256 = Word256{0}
- One256 = Word256{1}
-)
-
-type Word256 [32]byte
-
-func (w Word256) String() string { return string(w[:]) }
-func (w Word256) TrimmedString() string { return TrimmedString(w.Bytes()) }
-func (w Word256) Copy() Word256 { return w }
-func (w Word256) Bytes() []byte { return w[:] } // copied.
-func (w Word256) Prefix(n int) []byte { return w[:n] }
-func (w Word256) Postfix(n int) []byte { return w[32-n:] }
-func (w Word256) IsZero() bool {
- accum := byte(0)
- for _, byt := range w {
- accum |= byt
- }
- return accum == 0
-}
-func (w Word256) Compare(other Word256) int {
- return bytes.Compare(w[:], other[:])
-}
-
-func Uint64ToWord256(i uint64) Word256 {
- buf := [8]byte{}
- PutUint64BE(buf[:], i)
- return LeftPadWord256(buf[:])
-}
-
-func Int64ToWord256(i int64) Word256 {
- buf := [8]byte{}
- PutInt64BE(buf[:], i)
- return LeftPadWord256(buf[:])
-}
-
-func RightPadWord256(bz []byte) (word Word256) {
- copy(word[:], bz)
- return
-}
-
-func LeftPadWord256(bz []byte) (word Word256) {
- copy(word[32-len(bz):], bz)
- return
-}
-
-func Uint64FromWord256(word Word256) uint64 {
- buf := word.Postfix(8)
- return GetUint64BE(buf)
-}
-
-func Int64FromWord256(word Word256) int64 {
- buf := word.Postfix(8)
- return GetInt64BE(buf)
-}
-
-//-------------------------------------
-
-type Tuple256 struct {
- First Word256
- Second Word256
-}
-
-func (tuple Tuple256) Compare(other Tuple256) int {
- firstCompare := tuple.First.Compare(other.First)
- if firstCompare == 0 {
- return tuple.Second.Compare(other.Second)
- } else {
- return firstCompare
- }
-}
-
-func Tuple256Split(t Tuple256) (Word256, Word256) {
- return t.First, t.Second
-}
-
-type Tuple256Slice []Tuple256
-
-func (p Tuple256Slice) Len() int { return len(p) }
-func (p Tuple256Slice) Less(i, j int) bool {
- return p[i].Compare(p[j]) < 0
-}
-func (p Tuple256Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
-func (p Tuple256Slice) Sort() { sort.Sort(p) }