Merge pull request #1005 from cfromknecht/wallet-recovery
Wallet Recovery
This commit is contained in:
commit
4ab2bba5c7
4
Gopkg.lock
generated
4
Gopkg.lock
generated
@ -225,7 +225,7 @@
|
|||||||
"walletdb/bdb",
|
"walletdb/bdb",
|
||||||
"wtxmgr"
|
"wtxmgr"
|
||||||
]
|
]
|
||||||
revision = "41f0e0145c5a4d1b90105dcccf0cbe5d22372eed"
|
revision = "ccd48bb4720f2baeaa795cac81264f6ced2da4c7"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -359,6 +359,6 @@
|
|||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "25f631ecffcdb9df5a8675cd1fee102ee89a39a64dd8a467667a257d35f816e0"
|
inputs-digest = "7edcc418d8e2f483001838e05dc77e3fe613273418f8ddf7efd5cee6df68c6a8"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/roasbeef/btcwallet"
|
name = "github.com/roasbeef/btcwallet"
|
||||||
revision = "41f0e0145c5a4d1b90105dcccf0cbe5d22372eed"
|
revision = "ccd48bb4720f2baeaa795cac81264f6ced2da4c7"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/tv42/zbase32"
|
name = "github.com/tv42/zbase32"
|
||||||
|
@ -126,12 +126,12 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// bitcoinGenesisDate is the timestamp of Bitcoin's genesis block.
|
// BitcoinGenesisDate is the timestamp of Bitcoin's genesis block.
|
||||||
// We'll use this value in order to create a compact birthday for the
|
// We'll use this value in order to create a compact birthday for the
|
||||||
// seed. The birthday will be interested as the number of days since
|
// seed. The birthday will be interested as the number of days since
|
||||||
// the genesis date. We refer to this time period as ABE (after Bitcoin
|
// the genesis date. We refer to this time period as ABE (after Bitcoin
|
||||||
// era).
|
// era).
|
||||||
bitcoinGenesisDate = time.Unix(1231006505, 0)
|
BitcoinGenesisDate = time.Unix(1231006505, 0)
|
||||||
)
|
)
|
||||||
|
|
||||||
// CipherSeed is a fully decoded instance of the aezeed scheme. At a high
|
// CipherSeed is a fully decoded instance of the aezeed scheme. At a high
|
||||||
@ -201,7 +201,7 @@ func New(internalVersion uint8, entropy *[EntropySize]byte,
|
|||||||
// To compute our "birthday", we'll first use the current time, then
|
// To compute our "birthday", we'll first use the current time, then
|
||||||
// subtract that from the Bitcoin Genesis Date. We'll then convert that
|
// subtract that from the Bitcoin Genesis Date. We'll then convert that
|
||||||
// value to days.
|
// value to days.
|
||||||
birthday := uint16(now.Sub(bitcoinGenesisDate) / (time.Hour * 24))
|
birthday := uint16(now.Sub(BitcoinGenesisDate) / (time.Hour * 24))
|
||||||
|
|
||||||
c := &CipherSeed{
|
c := &CipherSeed{
|
||||||
InternalVersion: internalVersion,
|
InternalVersion: internalVersion,
|
||||||
@ -384,6 +384,13 @@ func (c *CipherSeed) Encipher(pass []byte) ([EncipheredCipherSeedSize]byte, erro
|
|||||||
return c.encipher(pass)
|
return c.encipher(pass)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BirthdayTime returns the cipher seed's internal birthday format as a native
|
||||||
|
// golang Time struct.
|
||||||
|
func (c *CipherSeed) BirthdayTime() time.Time {
|
||||||
|
offset := time.Duration(c.Birthday) * 24 * time.Hour
|
||||||
|
return BitcoinGenesisDate.Add(offset)
|
||||||
|
}
|
||||||
|
|
||||||
// Mnemonic is a 24-word passphrase as of CipherSeedVersion zero. This
|
// Mnemonic is a 24-word passphrase as of CipherSeedVersion zero. This
|
||||||
// passphrase encodes an encrypted seed triple (version, birthday, entropy).
|
// passphrase encodes an encrypted seed triple (version, birthday, entropy).
|
||||||
// Additionally, we also encode the salt used with scrypt to derive the key
|
// Additionally, we also encode the salt used with scrypt to derive the key
|
||||||
|
@ -33,7 +33,7 @@ var (
|
|||||||
version0TestVectors = []TestVector{
|
version0TestVectors = []TestVector{
|
||||||
{
|
{
|
||||||
version: 0,
|
version: 0,
|
||||||
time: bitcoinGenesisDate,
|
time: BitcoinGenesisDate,
|
||||||
entropy: testEntropy,
|
entropy: testEntropy,
|
||||||
salt: testSalt,
|
salt: testSalt,
|
||||||
password: []byte{},
|
password: []byte{},
|
||||||
@ -466,7 +466,7 @@ func TestSeedEncodeDecode(t *testing.T) {
|
|||||||
now := time.Unix(nowInt, 0)
|
now := time.Unix(nowInt, 0)
|
||||||
seed := CipherSeed{
|
seed := CipherSeed{
|
||||||
InternalVersion: version,
|
InternalVersion: version,
|
||||||
Birthday: uint16(now.Sub(bitcoinGenesisDate) / (time.Hour * 24)),
|
Birthday: uint16(now.Sub(BitcoinGenesisDate) / (time.Hour * 24)),
|
||||||
Entropy: entropy,
|
Entropy: entropy,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,8 @@ type chainControl struct {
|
|||||||
// branches of chainControl instances exist: one backed by a running btcd
|
// branches of chainControl instances exist: one backed by a running btcd
|
||||||
// full-node, and the other backed by a running neutrino light client instance.
|
// full-node, and the other backed by a running neutrino light client instance.
|
||||||
func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
||||||
privateWalletPw, publicWalletPw []byte) (*chainControl, func(), error) {
|
privateWalletPw, publicWalletPw []byte, birthday time.Time,
|
||||||
|
recoveryWindow uint32) (*chainControl, func(), error) {
|
||||||
|
|
||||||
// Set the RPC config from the "home" chain. Multi-chain isn't yet
|
// Set the RPC config from the "home" chain. Multi-chain isn't yet
|
||||||
// active, so we'll restrict usage to a particular chain for now.
|
// active, so we'll restrict usage to a particular chain for now.
|
||||||
@ -152,12 +153,14 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
walletConfig := &btcwallet.Config{
|
walletConfig := &btcwallet.Config{
|
||||||
PrivatePass: privateWalletPw,
|
PrivatePass: privateWalletPw,
|
||||||
PublicPass: publicWalletPw,
|
PublicPass: publicWalletPw,
|
||||||
DataDir: homeChainConfig.ChainDir,
|
Birthday: birthday,
|
||||||
NetParams: activeNetParams.Params,
|
RecoveryWindow: recoveryWindow,
|
||||||
FeeEstimator: cc.feeEstimator,
|
DataDir: homeChainConfig.ChainDir,
|
||||||
CoinType: activeNetParams.CoinType,
|
NetParams: activeNetParams.Params,
|
||||||
|
FeeEstimator: cc.feeEstimator,
|
||||||
|
CoinType: activeNetParams.CoinType,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -243,7 +246,9 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
|||||||
// Finally, we'll set the chain source for btcwallet, and
|
// Finally, we'll set the chain source for btcwallet, and
|
||||||
// create our clean up function which simply closes the
|
// create our clean up function which simply closes the
|
||||||
// database.
|
// database.
|
||||||
walletConfig.ChainSource = chain.NewNeutrinoClient(svc)
|
walletConfig.ChainSource = chain.NewNeutrinoClient(
|
||||||
|
activeNetParams.Params, svc,
|
||||||
|
)
|
||||||
cleanUp = func() {
|
cleanUp = func() {
|
||||||
svc.Stop()
|
svc.Stop()
|
||||||
nodeDatabase.Close()
|
nodeDatabase.Close()
|
||||||
|
@ -35,6 +35,8 @@ import (
|
|||||||
|
|
||||||
// TODO(roasbeef): expose all fee conf targets
|
// TODO(roasbeef): expose all fee conf targets
|
||||||
|
|
||||||
|
const defaultRecoveryWindow int32 = 250
|
||||||
|
|
||||||
func printJSON(resp interface{}) {
|
func printJSON(resp interface{}) {
|
||||||
b, err := json.Marshal(resp)
|
b, err := json.Marshal(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1132,6 +1134,7 @@ mnemonicCheck:
|
|||||||
var (
|
var (
|
||||||
cipherSeedMnemonic []string
|
cipherSeedMnemonic []string
|
||||||
aezeedPass []byte
|
aezeedPass []byte
|
||||||
|
recoveryWindow int32
|
||||||
)
|
)
|
||||||
if hasMnemonic {
|
if hasMnemonic {
|
||||||
// We'll now prompt the user to enter in their 24-word
|
// We'll now prompt the user to enter in their 24-word
|
||||||
@ -1170,7 +1173,37 @@ mnemonicCheck:
|
|||||||
|
|
||||||
aezeedPass = []byte(passphrase)
|
aezeedPass = []byte(passphrase)
|
||||||
|
|
||||||
fmt.Println()
|
for {
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Printf("Input an optional address look-ahead "+
|
||||||
|
"used to scan for used keys (default %d): ",
|
||||||
|
defaultRecoveryWindow)
|
||||||
|
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
answer, err := reader.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
answer = strings.TrimSpace(answer)
|
||||||
|
|
||||||
|
if len(answer) == 0 {
|
||||||
|
recoveryWindow = defaultRecoveryWindow
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
lookAhead, err := strconv.Atoi(answer)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Unable to parse recovery "+
|
||||||
|
"window: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
recoveryWindow = int32(lookAhead)
|
||||||
|
break
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, if the user doesn't have a mnemonic that they
|
// Otherwise, if the user doesn't have a mnemonic that they
|
||||||
// want to use, we'll generate a fresh one with the GenSeed
|
// want to use, we'll generate a fresh one with the GenSeed
|
||||||
@ -1247,6 +1280,7 @@ mnemonicCheck:
|
|||||||
WalletPassword: pw1,
|
WalletPassword: pw1,
|
||||||
CipherSeedMnemonic: cipherSeedMnemonic,
|
CipherSeedMnemonic: cipherSeedMnemonic,
|
||||||
AezeedPassphrase: aezeedPass,
|
AezeedPassphrase: aezeedPass,
|
||||||
|
RecoveryWindow: recoveryWindow,
|
||||||
}
|
}
|
||||||
if _, err := client.InitWallet(ctxb, req); err != nil {
|
if _, err := client.InitWallet(ctxb, req); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -1265,6 +1299,16 @@ var unlockCommand = cli.Command{
|
|||||||
able to carry out its duties. An exception is if a user is running with
|
able to carry out its duties. An exception is if a user is running with
|
||||||
--noencryptwallet, then a default passphrase will be used.
|
--noencryptwallet, then a default passphrase will be used.
|
||||||
`,
|
`,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.IntFlag{
|
||||||
|
Name: "recovery_window",
|
||||||
|
Usage: "address lookahead to resume recovery rescan, " +
|
||||||
|
"value should be non-zero -- To recover all " +
|
||||||
|
"funds, this should be greater than the " +
|
||||||
|
"maximum number of consecutive, unused " +
|
||||||
|
"addresses ever generated by the wallet.",
|
||||||
|
},
|
||||||
|
},
|
||||||
Action: actionDecorator(unlock),
|
Action: actionDecorator(unlock),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1280,8 +1324,26 @@ func unlock(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
|
args := ctx.Args()
|
||||||
|
|
||||||
|
// Parse the optional recovery window if it is specified. By default,
|
||||||
|
// the recovery window will be 0, indicating no lookahead should be
|
||||||
|
// used.
|
||||||
|
var recoveryWindow int32
|
||||||
|
switch {
|
||||||
|
case ctx.IsSet("recovery_window"):
|
||||||
|
recoveryWindow = int32(ctx.Int64("recovery_window"))
|
||||||
|
case args.Present():
|
||||||
|
window, err := strconv.ParseInt(args.First(), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
recoveryWindow = int32(window)
|
||||||
|
}
|
||||||
|
|
||||||
req := &lnrpc.UnlockWalletRequest{
|
req := &lnrpc.UnlockWalletRequest{
|
||||||
WalletPassword: pw,
|
WalletPassword: pw,
|
||||||
|
RecoveryWindow: recoveryWindow,
|
||||||
}
|
}
|
||||||
_, err = client.UnlockWallet(ctxb, req)
|
_, err = client.UnlockWallet(ctxb, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/roasbeef/btcd/chaincfg"
|
"github.com/roasbeef/btcd/chaincfg"
|
||||||
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
||||||
@ -42,11 +43,13 @@ func createTestBtcWallet(coinType uint32) (func(), *wallet.Wallet, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
loader := wallet.NewLoader(&chaincfg.SimNetParams, tempDir)
|
loader := wallet.NewLoader(&chaincfg.SimNetParams, tempDir, 0)
|
||||||
|
|
||||||
pass := []byte("test")
|
pass := []byte("test")
|
||||||
|
|
||||||
baseWallet, err := loader.CreateNewWallet(pass, pass, testHDSeed[:])
|
baseWallet, err := loader.CreateNewWallet(
|
||||||
|
pass, pass, testHDSeed[:], time.Time{},
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
98
lnd.go
98
lnd.go
@ -207,19 +207,35 @@ func lndMain() error {
|
|||||||
defer macaroonService.Close()
|
defer macaroonService.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
privateWalletPw = []byte("hello")
|
||||||
|
publicWalletPw = []byte("public")
|
||||||
|
birthday time.Time
|
||||||
|
recoveryWindow uint32
|
||||||
|
)
|
||||||
|
|
||||||
// We wait until the user provides a password over RPC. In case lnd is
|
// We wait until the user provides a password over RPC. In case lnd is
|
||||||
// started with the --noencryptwallet flag, we use the default password
|
// started with the --noencryptwallet flag, we use the default password
|
||||||
// "hello" for wallet encryption.
|
// "hello" for wallet encryption.
|
||||||
privateWalletPw := []byte("hello")
|
|
||||||
publicWalletPw := []byte("public")
|
|
||||||
if !cfg.NoEncryptWallet {
|
if !cfg.NoEncryptWallet {
|
||||||
privateWalletPw, publicWalletPw, err = waitForWalletPassword(
|
walletInitParams, err := waitForWalletPassword(
|
||||||
cfg.RPCListeners, cfg.RESTListeners, serverOpts, proxyOpts,
|
cfg.RPCListeners, cfg.RESTListeners, serverOpts,
|
||||||
tlsConf, macaroonService,
|
proxyOpts, tlsConf, macaroonService,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
privateWalletPw = walletInitParams.Password
|
||||||
|
publicWalletPw = walletInitParams.Password
|
||||||
|
birthday = walletInitParams.Birthday
|
||||||
|
recoveryWindow = walletInitParams.RecoveryWindow
|
||||||
|
|
||||||
|
if recoveryWindow > 0 {
|
||||||
|
ltndLog.Infof("Wallet recovery mode enabled with "+
|
||||||
|
"address lookahead of %d addresses",
|
||||||
|
recoveryWindow)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !cfg.NoMacaroons {
|
if !cfg.NoMacaroons {
|
||||||
@ -251,8 +267,10 @@ func lndMain() error {
|
|||||||
// With the information parsed from the configuration, create valid
|
// With the information parsed from the configuration, create valid
|
||||||
// instances of the pertinent interfaces required to operate the
|
// instances of the pertinent interfaces required to operate the
|
||||||
// Lightning Network Daemon.
|
// Lightning Network Daemon.
|
||||||
activeChainControl, chainCleanUp, err := newChainControlFromConfig(cfg,
|
activeChainControl, chainCleanUp, err := newChainControlFromConfig(
|
||||||
chanDB, privateWalletPw, publicWalletPw)
|
cfg, chanDB, privateWalletPw, publicWalletPw, birthday,
|
||||||
|
recoveryWindow,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("unable to create chain control: %v\n", err)
|
fmt.Printf("unable to create chain control: %v\n", err)
|
||||||
return err
|
return err
|
||||||
@ -827,12 +845,30 @@ func genMacaroons(ctx context.Context, svc *macaroons.Service,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WalletUnlockParams holds the variables used to parameterize the unlocking of
|
||||||
|
// lnd's wallet after it has already been created.
|
||||||
|
type WalletUnlockParams struct {
|
||||||
|
// Password is the public and private wallet passphrase.
|
||||||
|
Password []byte
|
||||||
|
|
||||||
|
// Birthday specifies the approximate time that this wallet was created.
|
||||||
|
// This is used to bound any rescans on startup.
|
||||||
|
Birthday time.Time
|
||||||
|
|
||||||
|
// RecoveryWindow specifies the address lookahead when entering recovery
|
||||||
|
// mode. A recovery will be attempted if this value is non-zero.
|
||||||
|
RecoveryWindow uint32
|
||||||
|
}
|
||||||
|
|
||||||
// waitForWalletPassword will spin up gRPC and REST endpoints for the
|
// waitForWalletPassword will spin up gRPC and REST endpoints for the
|
||||||
// WalletUnlocker server, and block until a password is provided by
|
// WalletUnlocker server, and block until a password is provided by
|
||||||
// the user to this RPC server.
|
// the user to this RPC server.
|
||||||
func waitForWalletPassword(grpcEndpoints, restEndpoints []string,
|
func waitForWalletPassword(
|
||||||
serverOpts []grpc.ServerOption, proxyOpts []grpc.DialOption,
|
grpcEndpoints, restEndpoints []string,
|
||||||
tlsConf *tls.Config, macaroonService *macaroons.Service) ([]byte, []byte, error) {
|
serverOpts []grpc.ServerOption,
|
||||||
|
proxyOpts []grpc.DialOption,
|
||||||
|
tlsConf *tls.Config,
|
||||||
|
macaroonService *macaroons.Service) (*WalletUnlockParams, error) {
|
||||||
|
|
||||||
// Set up a new PasswordService, which will listen
|
// Set up a new PasswordService, which will listen
|
||||||
// for passwords provided over RPC.
|
// for passwords provided over RPC.
|
||||||
@ -857,7 +893,7 @@ func waitForWalletPassword(grpcEndpoints, restEndpoints []string,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
ltndLog.Errorf("password RPC server unable to listen on %s",
|
ltndLog.Errorf("password RPC server unable to listen on %s",
|
||||||
grpcEndpoint)
|
grpcEndpoint)
|
||||||
return nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer lis.Close()
|
defer lis.Close()
|
||||||
|
|
||||||
@ -879,7 +915,7 @@ func waitForWalletPassword(grpcEndpoints, restEndpoints []string,
|
|||||||
err := lnrpc.RegisterWalletUnlockerHandlerFromEndpoint(ctx, mux,
|
err := lnrpc.RegisterWalletUnlockerHandlerFromEndpoint(ctx, mux,
|
||||||
grpcEndpoints[0], proxyOpts)
|
grpcEndpoints[0], proxyOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
srv := &http.Server{Handler: mux}
|
srv := &http.Server{Handler: mux}
|
||||||
@ -889,7 +925,7 @@ func waitForWalletPassword(grpcEndpoints, restEndpoints []string,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
ltndLog.Errorf("password gRPC proxy unable to listen on %s",
|
ltndLog.Errorf("password gRPC proxy unable to listen on %s",
|
||||||
restEndpoint)
|
restEndpoint)
|
||||||
return nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer lis.Close()
|
defer lis.Close()
|
||||||
|
|
||||||
@ -920,14 +956,15 @@ func waitForWalletPassword(grpcEndpoints, restEndpoints []string,
|
|||||||
case initMsg := <-pwService.InitMsgs:
|
case initMsg := <-pwService.InitMsgs:
|
||||||
password := initMsg.Passphrase
|
password := initMsg.Passphrase
|
||||||
cipherSeed := initMsg.WalletSeed
|
cipherSeed := initMsg.WalletSeed
|
||||||
|
recoveryWindow := initMsg.RecoveryWindow
|
||||||
|
|
||||||
// Before we proceed, we'll check the internal version of the
|
// Before we proceed, we'll check the internal version of the
|
||||||
// seed. If it's greater than the current key derivation
|
// seed. If it's greater than the current key derivation
|
||||||
// version, then we'll return an error as we don't understand
|
// version, then we'll return an error as we don't understand
|
||||||
// this.
|
// this.
|
||||||
if cipherSeed.InternalVersion != keychain.KeyDerivationVersion {
|
if cipherSeed.InternalVersion != keychain.KeyDerivationVersion {
|
||||||
return nil, nil, fmt.Errorf("invalid internal seed "+
|
return nil, fmt.Errorf("invalid internal seed version "+
|
||||||
"version %v, current version is %v",
|
"%v, current version is %v",
|
||||||
cipherSeed.InternalVersion,
|
cipherSeed.InternalVersion,
|
||||||
keychain.KeyDerivationVersion)
|
keychain.KeyDerivationVersion)
|
||||||
}
|
}
|
||||||
@ -935,31 +972,42 @@ func waitForWalletPassword(grpcEndpoints, restEndpoints []string,
|
|||||||
netDir := btcwallet.NetworkDir(
|
netDir := btcwallet.NetworkDir(
|
||||||
chainConfig.ChainDir, activeNetParams.Params,
|
chainConfig.ChainDir, activeNetParams.Params,
|
||||||
)
|
)
|
||||||
loader := wallet.NewLoader(activeNetParams.Params, netDir)
|
loader := wallet.NewLoader(
|
||||||
|
activeNetParams.Params, netDir, uint32(recoveryWindow),
|
||||||
|
)
|
||||||
|
|
||||||
// With the seed, we can now use the wallet loader to create
|
// With the seed, we can now use the wallet loader to create
|
||||||
// the wallet, then unload it so it can be opened shortly
|
// the wallet, then unload it so it can be opened shortly
|
||||||
// after.
|
birthday := cipherSeed.BirthdayTime()
|
||||||
// TODO(roasbeef): extend loader to also accept birthday
|
|
||||||
_, err = loader.CreateNewWallet(
|
_, err = loader.CreateNewWallet(
|
||||||
password, password, cipherSeed.Entropy[:],
|
password, password, cipherSeed.Entropy[:], birthday,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := loader.UnloadWallet(); err != nil {
|
if err := loader.UnloadWallet(); err != nil {
|
||||||
return nil, nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return password, password, nil
|
walletInitParams := &WalletUnlockParams{
|
||||||
|
Password: password,
|
||||||
|
Birthday: birthday,
|
||||||
|
RecoveryWindow: recoveryWindow,
|
||||||
|
}
|
||||||
|
|
||||||
|
return walletInitParams, nil
|
||||||
|
|
||||||
// The wallet has already been created in the past, and is simply being
|
// The wallet has already been created in the past, and is simply being
|
||||||
// unlocked. So we'll just return these passphrases.
|
// unlocked. So we'll just return these passphrases.
|
||||||
case walletPw := <-pwService.UnlockPasswords:
|
case unlockMsg := <-pwService.UnlockMsgs:
|
||||||
return walletPw, walletPw, nil
|
walletInitParams := &WalletUnlockParams{
|
||||||
|
Password: unlockMsg.Passphrase,
|
||||||
|
RecoveryWindow: unlockMsg.RecoveryWindow,
|
||||||
|
}
|
||||||
|
return walletInitParams, nil
|
||||||
|
|
||||||
case <-shutdownChannel:
|
case <-shutdownChannel:
|
||||||
return nil, nil, fmt.Errorf("shutting down")
|
return nil, fmt.Errorf("shutting down")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
178
lnd_test.go
178
lnd_test.go
@ -440,6 +440,180 @@ func completePaymentRequests(ctx context.Context, client lnrpc.LightningClient,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
AddrTypeWitnessPubkeyHash = lnrpc.NewAddressRequest_WITNESS_PUBKEY_HASH
|
||||||
|
AddrTypeNestedPubkeyHash = lnrpc.NewAddressRequest_NESTED_PUBKEY_HASH
|
||||||
|
)
|
||||||
|
|
||||||
|
// testOnchainFundRecovery checks lnd's ability to rescan for onchain outputs
|
||||||
|
// when providing a valid aezeed that owns outputs on the chain. This test
|
||||||
|
// performs multiple restorations using the same seed and various recovery
|
||||||
|
// windows to ensure we detect funds properly.
|
||||||
|
func testOnchainFundRecovery(net *lntest.NetworkHarness, t *harnessTest) {
|
||||||
|
timeout := time.Duration(time.Second * 15)
|
||||||
|
ctxb := context.Background()
|
||||||
|
|
||||||
|
// First, create a new node with strong passphrase and grab the mnemonic
|
||||||
|
// used for key derivation. This will bring up Carol with an empty
|
||||||
|
// wallet, and such that she is synced up.
|
||||||
|
password := []byte("The Magic Words are Squeamish Ossifrage")
|
||||||
|
carol, mnemonic, err := net.NewNodeWithSeed(nil, password)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to create node with seed; %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = net.ShutdownNode(carol)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to shutdown carol: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a closure for testing the recovery of Carol's wallet. This
|
||||||
|
// method takes the expected value of Carol's balance when using the
|
||||||
|
// given recovery window. Additionally, the caller can specify an action
|
||||||
|
// to perform on the restored node before the node is shutdown.
|
||||||
|
restoreCheckBalance := func(expAmount int64, recoveryWindow int32,
|
||||||
|
fn func(*lntest.HarnessNode)) {
|
||||||
|
|
||||||
|
// Restore Carol, passing in the password, mnemonic, and
|
||||||
|
// desired recovery window.
|
||||||
|
node, err := net.RestoreNodeWithSeed(
|
||||||
|
nil, password, mnemonic, recoveryWindow,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to restore node: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query carol for her current wallet balance.
|
||||||
|
var currBalance int64
|
||||||
|
err = lntest.WaitPredicate(func() bool {
|
||||||
|
req := &lnrpc.WalletBalanceRequest{}
|
||||||
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
|
resp, err := node.WalletBalance(ctxt, req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to query wallet balance: %v",
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that Carol's balance matches our expected
|
||||||
|
// amount.
|
||||||
|
currBalance = resp.ConfirmedBalance
|
||||||
|
if expAmount != currBalance {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}, 15*time.Second)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected restored node to have %d satoshis, "+
|
||||||
|
"instead has %d satoshis", expAmount,
|
||||||
|
currBalance)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the user provided a callback, execute the commands against
|
||||||
|
// the restored Carol.
|
||||||
|
if fn != nil {
|
||||||
|
fn(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lastly, shutdown this Carol so we can move on to the next
|
||||||
|
// restoration.
|
||||||
|
err = net.ShutdownNode(node)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to shutdown node: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a closure-factory for building closures that can generate and
|
||||||
|
// skip a configurable number of addresses, before finally sending coins
|
||||||
|
// to a next generated address. The returned closure will apply the same
|
||||||
|
// behavior to both default P2WKH and NP2WKH scopes.
|
||||||
|
skipAndSend := func(nskip int) func(*lntest.HarnessNode) {
|
||||||
|
return func(node *lntest.HarnessNode) {
|
||||||
|
newP2WKHAddrReq := &lnrpc.NewAddressRequest{
|
||||||
|
Type: AddrTypeWitnessPubkeyHash,
|
||||||
|
}
|
||||||
|
|
||||||
|
newNP2WKHAddrReq := &lnrpc.NewAddressRequest{
|
||||||
|
Type: AddrTypeNestedPubkeyHash,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate and skip the number of addresses requested.
|
||||||
|
for i := 0; i < nskip; i++ {
|
||||||
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
|
_, err = node.NewAddress(ctxt, newP2WKHAddrReq)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to generate new "+
|
||||||
|
"p2wkh address: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
|
_, err = node.NewAddress(ctxt, newNP2WKHAddrReq)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to generate new "+
|
||||||
|
"np2wkh address: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send one BTC to the next P2WKH address.
|
||||||
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
|
err = net.SendCoins(
|
||||||
|
ctxt, btcutil.SatoshiPerBitcoin, node,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to send coins to node: %v",
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// And another to the next NP2WKH address.
|
||||||
|
ctxt, _ = context.WithTimeout(ctxb, timeout)
|
||||||
|
err = net.SendCoinsNP2WKH(
|
||||||
|
ctxt, btcutil.SatoshiPerBitcoin, node,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to send coins to node: %v",
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore Carol with a recovery window of 0. Since no coins have been
|
||||||
|
// sent, her balance should be zero.
|
||||||
|
//
|
||||||
|
// After, one BTC is sent to both her first external P2WKH and NP2WKH
|
||||||
|
// addresses.
|
||||||
|
restoreCheckBalance(0, 0, skipAndSend(0))
|
||||||
|
|
||||||
|
// Check that restoring without a look-ahead results in having no funds
|
||||||
|
// in the wallet, even though they exist on-chain.
|
||||||
|
restoreCheckBalance(0, 0, nil)
|
||||||
|
|
||||||
|
// Now, check that using a look-ahead of 1 recovers the balance from the
|
||||||
|
// two transactions above.
|
||||||
|
//
|
||||||
|
// After, we will generate and skip 9 P2WKH and NP2WKH addresses, and
|
||||||
|
// send another BTC to the subsequent 10th address in each derivation
|
||||||
|
// path.
|
||||||
|
restoreCheckBalance(2*btcutil.SatoshiPerBitcoin, 1, skipAndSend(9))
|
||||||
|
|
||||||
|
// Check that using a recovery window of 9 does not find the two most
|
||||||
|
// recent txns.
|
||||||
|
restoreCheckBalance(2*btcutil.SatoshiPerBitcoin, 9, nil)
|
||||||
|
|
||||||
|
// Extending our recovery window to 10 should find the most recent
|
||||||
|
// transactions, leaving the wallet with 4 BTC total.
|
||||||
|
//
|
||||||
|
// After, we will skip 19 more addrs, sending to the 20th address past
|
||||||
|
// our last found address, and repeat the same checks.
|
||||||
|
restoreCheckBalance(4*btcutil.SatoshiPerBitcoin, 10, skipAndSend(19))
|
||||||
|
|
||||||
|
// Check that recovering with a recovery window of 19 fails to find the
|
||||||
|
// most recent transactions.
|
||||||
|
restoreCheckBalance(4*btcutil.SatoshiPerBitcoin, 19, nil)
|
||||||
|
|
||||||
|
// Ensure that using a recovery window of 20 succeeds.
|
||||||
|
restoreCheckBalance(6*btcutil.SatoshiPerBitcoin, 20, nil)
|
||||||
|
}
|
||||||
|
|
||||||
// testBasicChannelFunding performs a test exercising expected behavior from a
|
// testBasicChannelFunding performs a test exercising expected behavior from a
|
||||||
// basic funding workflow. The test creates a new channel between Alice and
|
// basic funding workflow. The test creates a new channel between Alice and
|
||||||
// Bob, then immediately closes the channel after asserting some expected post
|
// Bob, then immediately closes the channel after asserting some expected post
|
||||||
@ -8808,6 +8982,10 @@ type testCase struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var testsCases = []*testCase{
|
var testsCases = []*testCase{
|
||||||
|
{
|
||||||
|
name: "onchain fund recovery",
|
||||||
|
test: testOnchainFundRecovery,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "basic funding flow",
|
name: "basic funding flow",
|
||||||
test: testBasicChannelFunding,
|
test: testBasicChannelFunding,
|
||||||
|
734
lnrpc/rpc.pb.go
734
lnrpc/rpc.pb.go
@ -232,6 +232,13 @@ type InitWalletRequest struct {
|
|||||||
// aezeed_passphrase is an optional user provided passphrase that will be used
|
// aezeed_passphrase is an optional user provided passphrase that will be used
|
||||||
// to encrypt the generated aezeed cipher seed.
|
// to encrypt the generated aezeed cipher seed.
|
||||||
AezeedPassphrase []byte `protobuf:"bytes,3,opt,name=aezeed_passphrase,json=aezeedPassphrase,proto3" json:"aezeed_passphrase,omitempty"`
|
AezeedPassphrase []byte `protobuf:"bytes,3,opt,name=aezeed_passphrase,json=aezeedPassphrase,proto3" json:"aezeed_passphrase,omitempty"`
|
||||||
|
// *
|
||||||
|
// recovery_window is an optional argument specifying the address lookahead
|
||||||
|
// when restoring a wallet seed. The recovery window applies to each
|
||||||
|
// invdividual branch of the BIP44 derivation paths. Supplying a recovery
|
||||||
|
// window of zero indicates that no addresses should be recovered, such after
|
||||||
|
// the first initialization of the wallet.
|
||||||
|
RecoveryWindow int32 `protobuf:"varint,4,opt,name=recovery_window,json=recoveryWindow" json:"recovery_window,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *InitWalletRequest) Reset() { *m = InitWalletRequest{} }
|
func (m *InitWalletRequest) Reset() { *m = InitWalletRequest{} }
|
||||||
@ -260,6 +267,13 @@ func (m *InitWalletRequest) GetAezeedPassphrase() []byte {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *InitWalletRequest) GetRecoveryWindow() int32 {
|
||||||
|
if m != nil {
|
||||||
|
return m.RecoveryWindow
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
type InitWalletResponse struct {
|
type InitWalletResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,6 +288,13 @@ type UnlockWalletRequest struct {
|
|||||||
// will be required to decrypt on-disk material that the daemon requires to
|
// will be required to decrypt on-disk material that the daemon requires to
|
||||||
// function properly.
|
// function properly.
|
||||||
WalletPassword []byte `protobuf:"bytes,1,opt,name=wallet_password,json=walletPassword,proto3" json:"wallet_password,omitempty"`
|
WalletPassword []byte `protobuf:"bytes,1,opt,name=wallet_password,json=walletPassword,proto3" json:"wallet_password,omitempty"`
|
||||||
|
// *
|
||||||
|
// recovery_window is an optional argument specifying the address lookahead
|
||||||
|
// when restoring a wallet seed. The recovery window applies to each
|
||||||
|
// invdividual branch of the BIP44 derivation paths. Supplying a recovery
|
||||||
|
// window of zero indicates that no addresses should be recovered, such after
|
||||||
|
// the first initialization of the wallet.
|
||||||
|
RecoveryWindow int32 `protobuf:"varint,2,opt,name=recovery_window,json=recoveryWindow" json:"recovery_window,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *UnlockWalletRequest) Reset() { *m = UnlockWalletRequest{} }
|
func (m *UnlockWalletRequest) Reset() { *m = UnlockWalletRequest{} }
|
||||||
@ -288,6 +309,13 @@ func (m *UnlockWalletRequest) GetWalletPassword() []byte {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *UnlockWalletRequest) GetRecoveryWindow() int32 {
|
||||||
|
if m != nil {
|
||||||
|
return m.RecoveryWindow
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
type UnlockWalletResponse struct {
|
type UnlockWalletResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6351,356 +6379,358 @@ var _Lightning_serviceDesc = grpc.ServiceDesc{
|
|||||||
func init() { proto.RegisterFile("rpc.proto", fileDescriptor0) }
|
func init() { proto.RegisterFile("rpc.proto", fileDescriptor0) }
|
||||||
|
|
||||||
var fileDescriptor0 = []byte{
|
var fileDescriptor0 = []byte{
|
||||||
// 5611 bytes of a gzipped FileDescriptorProto
|
// 5640 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7c, 0xcb, 0x73, 0x1c, 0xc9,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7c, 0x4d, 0x90, 0x1c, 0xc9,
|
||||||
0x71, 0x37, 0x7b, 0x30, 0x78, 0x4c, 0xce, 0x60, 0x00, 0x14, 0x40, 0x70, 0x38, 0xe4, 0x72, 0xb9,
|
0x55, 0xbf, 0xaa, 0xa7, 0xe7, 0xa3, 0x5f, 0xf7, 0xf4, 0xcc, 0xe4, 0x8c, 0x46, 0xad, 0x96, 0x56,
|
||||||
0xad, 0x0d, 0x91, 0x1f, 0xbe, 0x35, 0xc1, 0x85, 0xa4, 0xf5, 0x6a, 0x69, 0x4b, 0xe6, 0x1b, 0x2b,
|
0xab, 0x2d, 0x6f, 0x58, 0xfa, 0xcf, 0x7f, 0xd1, 0x68, 0xc7, 0xf6, 0xb2, 0x5e, 0x81, 0x8d, 0xbe,
|
||||||
0x71, 0x29, 0xa8, 0x41, 0x8a, 0xb6, 0x64, 0x7b, 0xd4, 0x98, 0x29, 0x0c, 0x7a, 0xd9, 0xd3, 0xdd,
|
0x67, 0x6d, 0xad, 0x3c, 0xae, 0x91, 0x2c, 0xb0, 0x81, 0x76, 0x4d, 0x77, 0x4e, 0x4f, 0xad, 0xaa,
|
||||||
0xdb, 0xdd, 0x03, 0x70, 0x76, 0xcd, 0x08, 0xbf, 0xc2, 0x27, 0x2b, 0x7c, 0xb0, 0x2f, 0xb2, 0xc3,
|
0xab, 0x6a, 0xab, 0xaa, 0x67, 0xd4, 0xbb, 0x28, 0x82, 0xaf, 0xe0, 0x84, 0x83, 0x03, 0x5c, 0x4c,
|
||||||
0xe1, 0x08, 0xe9, 0x62, 0x1f, 0x7c, 0xf4, 0x49, 0xf6, 0x3f, 0xe0, 0x08, 0x87, 0x0f, 0x7b, 0x52,
|
0x04, 0x41, 0x84, 0x7d, 0x81, 0x03, 0x47, 0x4e, 0x86, 0x1b, 0x27, 0x22, 0x08, 0x0e, 0x7b, 0x72,
|
||||||
0xf8, 0xe6, 0xc7, 0xc1, 0x56, 0xf8, 0xe2, 0x08, 0x5f, 0x7c, 0x70, 0x38, 0x32, 0xeb, 0xd1, 0x55,
|
0x70, 0xe3, 0xe3, 0x00, 0x0e, 0x2e, 0x44, 0x70, 0xe1, 0x40, 0x10, 0xef, 0xe5, 0x47, 0x65, 0x56,
|
||||||
0xdd, 0x0d, 0x92, 0x7a, 0xd8, 0xb7, 0xa9, 0x5f, 0x65, 0x67, 0xbd, 0x32, 0xb3, 0x32, 0xb3, 0xaa,
|
0xd5, 0x48, 0xf2, 0x07, 0xdc, 0x3a, 0x7f, 0xf9, 0xea, 0xe5, 0xd7, 0x7b, 0x2f, 0xdf, 0x7b, 0x99,
|
||||||
0x06, 0x5a, 0x69, 0x32, 0xbc, 0x96, 0xa4, 0x71, 0x1e, 0xb3, 0xf9, 0x30, 0x4a, 0x93, 0x61, 0xff,
|
0xd9, 0xd0, 0x4a, 0x93, 0xe1, 0xb5, 0x24, 0x8d, 0xf3, 0x98, 0xcd, 0x87, 0x51, 0x9a, 0x0c, 0xfb,
|
||||||
0xe2, 0x38, 0x8e, 0xc7, 0x21, 0xdf, 0xf6, 0x93, 0x60, 0xdb, 0x8f, 0xa2, 0x38, 0xf7, 0xf3, 0x20,
|
0x17, 0xc7, 0x71, 0x3c, 0x0e, 0xf9, 0xb6, 0x9f, 0x04, 0xdb, 0x7e, 0x14, 0xc5, 0xb9, 0x9f, 0x07,
|
||||||
0x8e, 0x32, 0x41, 0xe4, 0x7e, 0x1b, 0xba, 0xf7, 0x79, 0xb4, 0xcf, 0xf9, 0xc8, 0xe3, 0x1f, 0x4d,
|
0x71, 0x94, 0x09, 0x22, 0xf7, 0xdb, 0xd0, 0xbd, 0xcf, 0xa3, 0x7d, 0xce, 0x47, 0x1e, 0xff, 0x68,
|
||||||
0x79, 0x96, 0xb3, 0xff, 0x0f, 0x6b, 0x3e, 0xff, 0x98, 0xf3, 0xd1, 0x20, 0xf1, 0xb3, 0x2c, 0x39,
|
0xca, 0xb3, 0x9c, 0xfd, 0x7f, 0x58, 0xf3, 0xf9, 0xc7, 0x9c, 0x8f, 0x06, 0x89, 0x9f, 0x65, 0xc9,
|
||||||
0x4a, 0xfd, 0x8c, 0xf7, 0x9c, 0xcb, 0xce, 0xd5, 0x8e, 0xb7, 0x2a, 0x2a, 0xf6, 0x34, 0xce, 0xde,
|
0x51, 0xea, 0x67, 0xbc, 0xe7, 0x5c, 0x76, 0xae, 0x76, 0xbc, 0x55, 0x51, 0xb1, 0xa7, 0x71, 0xf6,
|
||||||
0x80, 0x4e, 0x86, 0xa4, 0x3c, 0xca, 0xd3, 0x38, 0x99, 0xf5, 0x1a, 0x44, 0xd7, 0x46, 0xec, 0xae,
|
0x06, 0x74, 0x32, 0x24, 0xe5, 0x51, 0x9e, 0xc6, 0xc9, 0xac, 0xd7, 0x20, 0xba, 0x36, 0x62, 0x77,
|
||||||
0x80, 0xdc, 0x10, 0x56, 0x74, 0x0b, 0x59, 0x12, 0x47, 0x19, 0x67, 0xd7, 0x61, 0x63, 0x18, 0x24,
|
0x05, 0xe4, 0x86, 0xb0, 0xa2, 0x5b, 0xc8, 0x92, 0x38, 0xca, 0x38, 0xbb, 0x0e, 0x1b, 0xc3, 0x20,
|
||||||
0x47, 0x3c, 0x1d, 0xd0, 0xc7, 0x93, 0x88, 0x4f, 0xe2, 0x28, 0x18, 0xf6, 0x9c, 0xcb, 0x73, 0x57,
|
0x39, 0xe2, 0xe9, 0x80, 0x3e, 0x9e, 0x44, 0x7c, 0x12, 0x47, 0xc1, 0xb0, 0xe7, 0x5c, 0x9e, 0xbb,
|
||||||
0x5b, 0x1e, 0x13, 0x75, 0xf8, 0xc5, 0x07, 0xb2, 0x86, 0x5d, 0x81, 0x15, 0x1e, 0x09, 0x9c, 0x8f,
|
0xda, 0xf2, 0x98, 0xa8, 0xc3, 0x2f, 0x3e, 0x90, 0x35, 0xec, 0x0a, 0xac, 0xf0, 0x48, 0xe0, 0x7c,
|
||||||
0xe8, 0x2b, 0xd9, 0x54, 0xb7, 0x80, 0xf1, 0x03, 0xf7, 0x4f, 0x1c, 0x58, 0x7b, 0x3f, 0x0a, 0xf2,
|
0x44, 0x5f, 0xc9, 0xa6, 0xba, 0x05, 0x8c, 0x1f, 0xb8, 0x7f, 0xe3, 0xc0, 0xda, 0xfb, 0x51, 0x90,
|
||||||
0x27, 0x7e, 0x18, 0xf2, 0x5c, 0x8d, 0xe9, 0x0a, 0xac, 0x9c, 0x10, 0x40, 0x63, 0x3a, 0x89, 0xd3,
|
0x3f, 0xf1, 0xc3, 0x90, 0xe7, 0x6a, 0x4c, 0x57, 0x60, 0xe5, 0x84, 0x00, 0x1a, 0xd3, 0x49, 0x9c,
|
||||||
0x91, 0x1c, 0x51, 0x57, 0xc0, 0x7b, 0x12, 0x3d, 0xb5, 0x67, 0x8d, 0x53, 0x7b, 0x56, 0x3b, 0x5d,
|
0x8e, 0xe4, 0x88, 0xba, 0x02, 0xde, 0x93, 0xe8, 0xa9, 0x3d, 0x6b, 0x9c, 0xda, 0xb3, 0xda, 0xe9,
|
||||||
0x73, 0xf5, 0xd3, 0xe5, 0x6e, 0x00, 0x33, 0x3b, 0x27, 0xa6, 0xc3, 0xfd, 0x12, 0xac, 0x3f, 0x8e,
|
0x9a, 0x3b, 0x65, 0xba, 0xae, 0xc0, 0x4a, 0xca, 0x87, 0xf1, 0x31, 0x4f, 0x67, 0x83, 0x93, 0x20,
|
||||||
0xc2, 0x78, 0xf8, 0xf4, 0x27, 0xeb, 0xb4, 0xbb, 0x09, 0x1b, 0xf6, 0xf7, 0x92, 0xef, 0x77, 0x1b,
|
0x1a, 0xc5, 0x27, 0xbd, 0xe6, 0x65, 0xe7, 0xea, 0xbc, 0xd7, 0x55, 0xf0, 0x13, 0x42, 0xdd, 0x0d,
|
||||||
0xd0, 0x7e, 0x94, 0xfa, 0x51, 0xe6, 0x0f, 0x71, 0xc9, 0x59, 0x0f, 0x16, 0xf3, 0x67, 0x83, 0x23,
|
0x60, 0xe6, 0x28, 0xc4, 0xbc, 0xb9, 0x63, 0x58, 0x7f, 0x1c, 0x85, 0xf1, 0xf0, 0xe9, 0x4f, 0x38,
|
||||||
0x3f, 0x3b, 0x22, 0x46, 0x2d, 0x4f, 0x15, 0xd9, 0x26, 0x2c, 0xf8, 0x93, 0x78, 0x1a, 0xe5, 0x34,
|
0xba, 0x9a, 0xe6, 0x1b, 0xb5, 0xcd, 0x6f, 0xc2, 0x86, 0xdd, 0x90, 0xec, 0xc0, 0x77, 0x1b, 0xd0,
|
||||||
0xab, 0x73, 0x9e, 0x2c, 0xb1, 0xb7, 0x60, 0x2d, 0x9a, 0x4e, 0x06, 0xc3, 0x38, 0x3a, 0x0c, 0xd2,
|
0x7e, 0x94, 0xfa, 0x51, 0xe6, 0x0f, 0x51, 0x88, 0x58, 0x0f, 0x16, 0xf3, 0x67, 0x83, 0x23, 0x3f,
|
||||||
0x89, 0x10, 0x1c, 0x1a, 0xdc, 0xbc, 0x57, 0xad, 0x60, 0x97, 0x00, 0x0e, 0xb0, 0x1b, 0xa2, 0x89,
|
0x3b, 0xa2, 0x16, 0x5b, 0x9e, 0x2a, 0xb2, 0x4d, 0x58, 0xf0, 0x27, 0xf1, 0x34, 0xca, 0xa9, 0x85,
|
||||||
0x26, 0x35, 0x61, 0x20, 0xcc, 0x85, 0x8e, 0x2c, 0xf1, 0x60, 0x7c, 0x94, 0xf7, 0xe6, 0x89, 0x91,
|
0x39, 0x4f, 0x96, 0xd8, 0x5b, 0xb0, 0x16, 0x4d, 0x27, 0x83, 0x61, 0x1c, 0x1d, 0x06, 0xe9, 0x44,
|
||||||
0x85, 0x21, 0x8f, 0x3c, 0x98, 0xf0, 0x41, 0x96, 0xfb, 0x93, 0xa4, 0xb7, 0x40, 0xbd, 0x31, 0x10,
|
0x88, 0x22, 0x4d, 0xd7, 0xbc, 0x57, 0xad, 0x60, 0x97, 0x00, 0x0e, 0xb0, 0x1b, 0xa2, 0x89, 0x26,
|
||||||
0xaa, 0x8f, 0x73, 0x3f, 0x1c, 0x1c, 0x72, 0x9e, 0xf5, 0x16, 0x65, 0xbd, 0x46, 0xd8, 0x67, 0xa1,
|
0x35, 0x61, 0x20, 0xcc, 0x85, 0x8e, 0x2c, 0xf1, 0x60, 0x7c, 0x94, 0xf7, 0xe6, 0x89, 0x91, 0x85,
|
||||||
0x3b, 0xe2, 0x59, 0x3e, 0xf0, 0x47, 0xa3, 0x94, 0x67, 0x19, 0xcf, 0x7a, 0x4b, 0xb4, 0x74, 0x25,
|
0x21, 0x8f, 0x3c, 0x98, 0xf0, 0x41, 0x96, 0xfb, 0x93, 0xa4, 0xb7, 0x40, 0xbd, 0x31, 0x10, 0xaa,
|
||||||
0xd4, 0xed, 0xc1, 0xe6, 0x7d, 0x9e, 0x1b, 0xb3, 0x93, 0xc9, 0x69, 0x77, 0x1f, 0x00, 0x33, 0xe0,
|
0x8f, 0x73, 0x3f, 0x1c, 0x1c, 0x72, 0x9e, 0xf5, 0x16, 0x65, 0xbd, 0x46, 0xd8, 0x67, 0xa1, 0x3b,
|
||||||
0x3b, 0x3c, 0xf7, 0x83, 0x30, 0x63, 0xef, 0x40, 0x27, 0x37, 0x88, 0x49, 0x54, 0xdb, 0x3b, 0xec,
|
0xe2, 0x59, 0x3e, 0xf0, 0x47, 0xa3, 0x94, 0x67, 0x19, 0xcf, 0x7a, 0x4b, 0x24, 0x0c, 0x25, 0xd4,
|
||||||
0x1a, 0xe9, 0xd8, 0x35, 0xe3, 0x03, 0xcf, 0xa2, 0x73, 0xff, 0xcb, 0x81, 0xf6, 0x3e, 0x8f, 0xb4,
|
0xed, 0xc1, 0xe6, 0x7d, 0x9e, 0x1b, 0xb3, 0x93, 0xc9, 0xf5, 0x71, 0x1f, 0x00, 0x33, 0xe0, 0x3b,
|
||||||
0x76, 0x31, 0x68, 0x62, 0x4f, 0xe4, 0x4a, 0xd2, 0x6f, 0xf6, 0x3a, 0xb4, 0xa9, 0x77, 0x59, 0x9e,
|
0x3c, 0xf7, 0x83, 0x30, 0x63, 0xef, 0x40, 0x27, 0x37, 0x88, 0x49, 0xf8, 0xdb, 0x3b, 0xec, 0x1a,
|
||||||
0x06, 0xd1, 0x98, 0x96, 0xa0, 0xe5, 0x01, 0x42, 0xfb, 0x84, 0xb0, 0x55, 0x98, 0xf3, 0x27, 0x39,
|
0x69, 0xed, 0x35, 0xe3, 0x03, 0xcf, 0xa2, 0x73, 0xff, 0xcb, 0x81, 0xf6, 0x3e, 0x8f, 0xb4, 0xbe,
|
||||||
0x4d, 0xfc, 0x9c, 0x87, 0x3f, 0x51, 0xef, 0x12, 0x7f, 0x36, 0xe1, 0x51, 0x5e, 0x4c, 0x76, 0xc7,
|
0x32, 0x68, 0x62, 0x4f, 0xe4, 0x92, 0xd3, 0x6f, 0xf6, 0x3a, 0xb4, 0xa9, 0x77, 0x59, 0x9e, 0x06,
|
||||||
0x6b, 0x4b, 0x6c, 0x17, 0x67, 0xfb, 0x1a, 0xac, 0x9b, 0x24, 0x8a, 0xfb, 0x3c, 0x71, 0x5f, 0x33,
|
0xd1, 0x98, 0x96, 0xa0, 0xe5, 0x01, 0x42, 0xfb, 0x84, 0xb0, 0x55, 0x98, 0xf3, 0x27, 0x39, 0x4d,
|
||||||
0x28, 0x65, 0x23, 0x57, 0x60, 0x45, 0xd1, 0xa7, 0xa2, 0xb3, 0x34, 0xfd, 0x2d, 0xaf, 0x2b, 0x61,
|
0xfc, 0x9c, 0x87, 0x3f, 0x51, 0x93, 0x13, 0x7f, 0x36, 0xe1, 0x51, 0x5e, 0x4c, 0x76, 0xc7, 0x6b,
|
||||||
0x35, 0x84, 0xab, 0xb0, 0x7a, 0x18, 0x44, 0x7e, 0x38, 0x18, 0x86, 0xf9, 0xf1, 0x60, 0xc4, 0xc3,
|
0x4b, 0x6c, 0x17, 0x67, 0xfb, 0x1a, 0xac, 0x9b, 0x24, 0x8a, 0xfb, 0x3c, 0x71, 0x5f, 0x33, 0x28,
|
||||||
0xdc, 0xa7, 0x85, 0x98, 0xf7, 0xba, 0x84, 0xdf, 0x0e, 0xf3, 0xe3, 0x3b, 0x88, 0xba, 0x7f, 0xe4,
|
0x65, 0x23, 0x57, 0x60, 0x45, 0xd1, 0xa7, 0xa2, 0xb3, 0x34, 0xfd, 0x2d, 0xaf, 0x2b, 0x61, 0x35,
|
||||||
0x40, 0x47, 0x0c, 0x5e, 0x2a, 0xfe, 0x9b, 0xb0, 0xac, 0xda, 0xe0, 0x69, 0x1a, 0xa7, 0x52, 0x0e,
|
0x84, 0xab, 0xb0, 0x7a, 0x18, 0x44, 0x7e, 0x38, 0x18, 0x86, 0xf9, 0xf1, 0x60, 0xc4, 0xc3, 0xdc,
|
||||||
0x6d, 0x90, 0x6d, 0xc1, 0xaa, 0x02, 0x92, 0x94, 0x07, 0x13, 0x7f, 0xcc, 0xa5, 0xb6, 0x57, 0x70,
|
0xa7, 0x85, 0x98, 0xf7, 0xba, 0x84, 0xdf, 0x0e, 0xf3, 0xe3, 0x3b, 0x88, 0xba, 0x7f, 0xe4, 0x40,
|
||||||
0xb6, 0x53, 0x70, 0x4c, 0xe3, 0x69, 0x2e, 0x54, 0xaf, 0xbd, 0xd3, 0x91, 0x0b, 0xe3, 0x21, 0xe6,
|
0x47, 0x0c, 0x5e, 0x9a, 0x92, 0x37, 0x61, 0x59, 0xb5, 0xc1, 0xd3, 0x34, 0x4e, 0xa5, 0x1c, 0xda,
|
||||||
0xd9, 0x24, 0xee, 0xf7, 0x1c, 0xe8, 0xdc, 0x3e, 0xf2, 0xa3, 0x88, 0x87, 0x7b, 0x71, 0x10, 0xe5,
|
0x20, 0xdb, 0x82, 0x55, 0x05, 0x24, 0x29, 0x0f, 0x26, 0xfe, 0x98, 0x4b, 0xfb, 0x51, 0xc1, 0xd9,
|
||||||
0xec, 0x3a, 0xb0, 0xc3, 0x69, 0x34, 0x0a, 0xa2, 0xf1, 0x20, 0x7f, 0x16, 0x8c, 0x06, 0x07, 0xb3,
|
0x4e, 0xc1, 0x31, 0x8d, 0xa7, 0xb9, 0x50, 0xe6, 0xf6, 0x4e, 0x47, 0x2e, 0x8c, 0x87, 0x98, 0x67,
|
||||||
0x9c, 0x67, 0x62, 0x89, 0x76, 0xcf, 0x78, 0x35, 0x75, 0xec, 0x2d, 0x58, 0xb5, 0xd0, 0x2c, 0x4f,
|
0x93, 0xb8, 0xdf, 0x73, 0xa0, 0x73, 0xfb, 0xc8, 0x8f, 0x22, 0x1e, 0xee, 0xc5, 0x41, 0x94, 0xb3,
|
||||||
0xc5, 0xba, 0xed, 0x9e, 0xf1, 0x2a, 0x35, 0x28, 0xf8, 0xf1, 0x34, 0x4f, 0xa6, 0xf9, 0x20, 0x88,
|
0xeb, 0xc0, 0x0e, 0xa7, 0xd1, 0x28, 0x88, 0xc6, 0x83, 0xfc, 0x59, 0x30, 0x1a, 0x1c, 0xcc, 0x72,
|
||||||
0x46, 0xfc, 0x19, 0xf5, 0x71, 0xd9, 0xb3, 0xb0, 0x5b, 0x5d, 0xe8, 0x98, 0xdf, 0xb9, 0x5f, 0x82,
|
0x9e, 0x89, 0x25, 0xda, 0x3d, 0xe3, 0xd5, 0xd4, 0xb1, 0xb7, 0x60, 0xd5, 0x42, 0xb3, 0x3c, 0x15,
|
||||||
0xd5, 0x07, 0xa8, 0x11, 0x51, 0x10, 0x8d, 0x6f, 0x0a, 0xb1, 0x45, 0x35, 0x4d, 0xa6, 0x07, 0x4f,
|
0xeb, 0xb6, 0x7b, 0xc6, 0xab, 0xd4, 0xa0, 0xe0, 0xc7, 0xd3, 0x3c, 0x99, 0xe6, 0x83, 0x20, 0x1a,
|
||||||
0xf9, 0x4c, 0xce, 0x9b, 0x2c, 0xa1, 0x50, 0x1d, 0xc5, 0x59, 0x2e, 0x25, 0x87, 0x7e, 0xbb, 0xff,
|
0xf1, 0x67, 0xd4, 0xc7, 0x65, 0xcf, 0xc2, 0x6e, 0x75, 0xa1, 0x63, 0x7e, 0xe7, 0x7e, 0x09, 0x56,
|
||||||
0xe4, 0xc0, 0x0a, 0xce, 0xfd, 0x07, 0x7e, 0x34, 0x53, 0x2b, 0xf7, 0x00, 0x3a, 0xc8, 0xea, 0x51,
|
0x1f, 0xa0, 0x46, 0x44, 0x41, 0x34, 0xbe, 0x29, 0xc4, 0x16, 0xd5, 0x34, 0x99, 0x1e, 0x3c, 0xe5,
|
||||||
0x7c, 0x53, 0x28, 0xbb, 0x10, 0xe2, 0xab, 0x72, 0xae, 0x4a, 0xd4, 0xd7, 0x4c, 0x52, 0x34, 0xe6,
|
0x33, 0x39, 0x6f, 0xb2, 0x84, 0x42, 0x75, 0x14, 0x67, 0xb9, 0x94, 0x1c, 0xfa, 0xed, 0xfe, 0x93,
|
||||||
0x33, 0xcf, 0xfa, 0x1a, 0xc5, 0x36, 0xf7, 0xd3, 0x31, 0xcf, 0xc9, 0x0c, 0x48, 0xb3, 0x00, 0x02,
|
0x03, 0x2b, 0x38, 0xf7, 0x1f, 0xf8, 0xd1, 0x4c, 0xad, 0xdc, 0x03, 0xe8, 0x20, 0xab, 0x47, 0xf1,
|
||||||
0xba, 0x1d, 0x47, 0x87, 0xec, 0x32, 0x74, 0x32, 0x3f, 0x1f, 0x24, 0x3c, 0xa5, 0x59, 0x23, 0xd1,
|
0x4d, 0xa1, 0xec, 0x42, 0x88, 0xaf, 0xca, 0xb9, 0x2a, 0x51, 0x5f, 0x33, 0x49, 0x71, 0x7b, 0x98,
|
||||||
0x9b, 0xf3, 0x20, 0xf3, 0xf3, 0x3d, 0x9e, 0xde, 0x9a, 0xe5, 0xbc, 0xff, 0x65, 0x58, 0xab, 0xb4,
|
0x79, 0xd6, 0xd7, 0x28, 0xb6, 0xb9, 0x9f, 0x8e, 0x79, 0x4e, 0x66, 0x40, 0x9a, 0x05, 0x10, 0xd0,
|
||||||
0x82, 0xd2, 0x5e, 0x0c, 0x11, 0x7f, 0xb2, 0x0d, 0x98, 0x3f, 0xf6, 0xc3, 0x29, 0x97, 0xd6, 0x49,
|
0xed, 0x38, 0x3a, 0x64, 0x97, 0xa1, 0x93, 0xf9, 0xf9, 0x20, 0xe1, 0x29, 0xcd, 0x1a, 0x89, 0xde,
|
||||||
0x14, 0xde, 0x6b, 0xbc, 0xeb, 0xb8, 0x9f, 0x85, 0xd5, 0xa2, 0xdb, 0x52, 0xc8, 0x18, 0x34, 0x71,
|
0x9c, 0x07, 0x99, 0x9f, 0xef, 0xf1, 0xf4, 0xd6, 0x2c, 0xe7, 0xfd, 0x2f, 0xc3, 0x5a, 0xa5, 0x15,
|
||||||
0x06, 0x25, 0x03, 0xfa, 0xed, 0xfe, 0x96, 0x23, 0x08, 0x6f, 0xc7, 0x81, 0xd6, 0x74, 0x24, 0x44,
|
0x94, 0xf6, 0x62, 0x88, 0xf8, 0x93, 0x6d, 0xc0, 0xfc, 0xb1, 0x1f, 0x4e, 0xb9, 0xb4, 0x4e, 0xa2,
|
||||||
0x83, 0xa0, 0x08, 0xf1, 0xf7, 0xa9, 0x96, 0xf0, 0xa7, 0x1f, 0xac, 0x7b, 0x05, 0xd6, 0x8c, 0x2e,
|
0xf0, 0x5e, 0xe3, 0x5d, 0xc7, 0xfd, 0x2c, 0xac, 0x16, 0xdd, 0x96, 0x42, 0xc6, 0xa0, 0x89, 0x33,
|
||||||
0xbc, 0xa0, 0xb3, 0xdf, 0x71, 0x60, 0xed, 0x21, 0x3f, 0x91, 0xab, 0xae, 0x7a, 0xfb, 0x2e, 0x34,
|
0x28, 0x19, 0xd0, 0x6f, 0xf7, 0xb7, 0x1c, 0x41, 0x78, 0x3b, 0x0e, 0xb4, 0xa6, 0x23, 0x21, 0x1a,
|
||||||
0xf3, 0x59, 0x22, 0xb6, 0xe2, 0xee, 0xce, 0x9b, 0x72, 0xd1, 0x2a, 0x74, 0xd7, 0x64, 0xf1, 0xd1,
|
0x04, 0x45, 0x88, 0xbf, 0x4f, 0xb5, 0x84, 0x3f, 0xfd, 0x60, 0xdd, 0x2b, 0xb0, 0x66, 0x74, 0xe1,
|
||||||
0x2c, 0xe1, 0x1e, 0x7d, 0xe1, 0x7e, 0x09, 0xda, 0x06, 0xc8, 0xce, 0xc1, 0xfa, 0x93, 0xf7, 0x1f,
|
0x05, 0x9d, 0xfd, 0x8e, 0x03, 0x6b, 0x0f, 0xf9, 0x89, 0x5c, 0x75, 0xd5, 0xdb, 0x77, 0xa1, 0x99,
|
||||||
0x3d, 0xbc, 0xbb, 0xbf, 0x3f, 0xd8, 0x7b, 0x7c, 0xeb, 0xab, 0x77, 0x7f, 0x65, 0xb0, 0x7b, 0x73,
|
0xcf, 0x12, 0xb1, 0xb9, 0x77, 0x77, 0xde, 0x94, 0x8b, 0x56, 0xa1, 0xbb, 0x26, 0x8b, 0x8f, 0x66,
|
||||||
0x7f, 0x77, 0xf5, 0x0c, 0xdb, 0x04, 0xf6, 0xf0, 0xee, 0xfe, 0xa3, 0xbb, 0x77, 0x2c, 0xdc, 0x71,
|
0x09, 0xf7, 0xe8, 0x0b, 0xf7, 0x4b, 0xd0, 0x36, 0x40, 0x76, 0x0e, 0xd6, 0x9f, 0xbc, 0xff, 0xe8,
|
||||||
0xfb, 0xd0, 0x7b, 0xc8, 0x4f, 0x9e, 0x04, 0x79, 0xc4, 0xb3, 0xcc, 0x6e, 0xcd, 0xbd, 0x06, 0xcc,
|
0xe1, 0xdd, 0xfd, 0xfd, 0xc1, 0xde, 0xe3, 0x5b, 0x5f, 0xbd, 0xfb, 0x2b, 0x83, 0xdd, 0x9b, 0xfb,
|
||||||
0xec, 0x82, 0x1c, 0x55, 0x0f, 0x16, 0xa5, 0xa9, 0x55, 0x3b, 0x8d, 0x2c, 0xba, 0x9f, 0x05, 0xb6,
|
0xbb, 0xab, 0x67, 0xd8, 0x26, 0xb0, 0x87, 0x77, 0xf7, 0x1f, 0xdd, 0xbd, 0x63, 0xe1, 0x8e, 0xdb,
|
||||||
0x1f, 0x8c, 0xa3, 0x0f, 0x78, 0x96, 0xf9, 0x63, 0xae, 0xc6, 0xb6, 0x0a, 0x73, 0x93, 0x6c, 0x2c,
|
0x87, 0xde, 0x43, 0x7e, 0xf2, 0x24, 0xc8, 0x23, 0x9e, 0x65, 0x76, 0x6b, 0xee, 0x35, 0x60, 0x66,
|
||||||
0x8d, 0x22, 0xfe, 0x74, 0x3f, 0x07, 0xeb, 0x16, 0x9d, 0x64, 0x7c, 0x11, 0x5a, 0x59, 0x30, 0x8e,
|
0x17, 0xe4, 0xa8, 0x7a, 0xb0, 0x28, 0x4d, 0xad, 0xda, 0x69, 0x64, 0xd1, 0xfd, 0x2c, 0xb0, 0xfd,
|
||||||
0xfc, 0x7c, 0x9a, 0x72, 0xc9, 0xba, 0x00, 0xdc, 0x7b, 0xb0, 0xf1, 0x0d, 0x9e, 0x06, 0x87, 0xb3,
|
0x60, 0x1c, 0x7d, 0xc0, 0xb3, 0xcc, 0x1f, 0x73, 0x35, 0xb6, 0x55, 0x98, 0x9b, 0x64, 0x63, 0x69,
|
||||||
0x97, 0xb1, 0xb7, 0xf9, 0x34, 0xca, 0x7c, 0xee, 0xc2, 0xd9, 0x12, 0x1f, 0xd9, 0xbc, 0x10, 0x44,
|
0x14, 0xf1, 0xa7, 0xfb, 0x39, 0x58, 0xb7, 0xe8, 0x24, 0xe3, 0x8b, 0xd0, 0xca, 0x82, 0x71, 0xe4,
|
||||||
0xb9, 0x5c, 0x4b, 0x9e, 0x28, 0x18, 0x6a, 0xd9, 0x30, 0xd5, 0xd2, 0x7d, 0x0c, 0xec, 0x76, 0x1c,
|
0xe7, 0xd3, 0x94, 0x4b, 0xd6, 0x05, 0xe0, 0xde, 0x83, 0x8d, 0x6f, 0xf0, 0x34, 0x38, 0x9c, 0xbd,
|
||||||
0x45, 0x7c, 0x98, 0xef, 0x71, 0x9e, 0x16, 0xfe, 0x55, 0x21, 0x75, 0xed, 0x9d, 0x73, 0x72, 0x1d,
|
0x8c, 0xbd, 0xcd, 0xa7, 0x51, 0xe6, 0x73, 0x17, 0xce, 0x96, 0xf8, 0xc8, 0xe6, 0x85, 0x20, 0xca,
|
||||||
0xcb, 0xba, 0x2e, 0xc5, 0x91, 0x41, 0x33, 0xe1, 0xe9, 0x84, 0x18, 0x2f, 0x79, 0xf4, 0xdb, 0x3d,
|
0xe5, 0x5a, 0xf2, 0x44, 0xc1, 0x50, 0xcb, 0x86, 0xa9, 0x96, 0xee, 0x63, 0x60, 0xb7, 0xe3, 0x28,
|
||||||
0x0b, 0xeb, 0x16, 0x5b, 0xb9, 0xdb, 0xbf, 0x0d, 0x67, 0xef, 0x04, 0xd9, 0xb0, 0xda, 0x60, 0x0f,
|
0xe2, 0xc3, 0x7c, 0x8f, 0xf3, 0xb4, 0xf0, 0xd8, 0x0a, 0xa9, 0x6b, 0xef, 0x9c, 0x93, 0xeb, 0x58,
|
||||||
0x16, 0x93, 0xe9, 0xc1, 0xa0, 0xd0, 0x29, 0x55, 0xc4, 0x4d, 0xb0, 0xfc, 0x89, 0x64, 0xf6, 0x7b,
|
0xd6, 0x75, 0x29, 0x8e, 0x0c, 0x9a, 0x09, 0x4f, 0x27, 0xc4, 0x78, 0xc9, 0xa3, 0xdf, 0xee, 0x59,
|
||||||
0x0e, 0x34, 0x77, 0x1f, 0x3d, 0xb8, 0xcd, 0xfa, 0xb0, 0x14, 0x44, 0xc3, 0x78, 0x82, 0x5b, 0x87,
|
0x58, 0xb7, 0xd8, 0xca, 0xdd, 0xfe, 0x6d, 0x38, 0x7b, 0x27, 0xc8, 0x86, 0xd5, 0x06, 0x7b, 0xb0,
|
||||||
0x18, 0xb4, 0x2e, 0x9f, 0xaa, 0x2b, 0x17, 0xa1, 0x45, 0x3b, 0x0e, 0xee, 0xeb, 0xd2, 0x15, 0x2a,
|
0x98, 0x4c, 0x0f, 0x06, 0x85, 0x4e, 0xa9, 0x22, 0x6e, 0x82, 0xe5, 0x4f, 0x24, 0xb3, 0xdf, 0x73,
|
||||||
0x00, 0xf4, 0x29, 0xf8, 0xb3, 0x24, 0x48, 0xc9, 0x69, 0x50, 0xae, 0x40, 0x93, 0x2c, 0x62, 0xb5,
|
0xa0, 0xb9, 0xfb, 0xe8, 0xc1, 0x6d, 0xd6, 0x87, 0xa5, 0x20, 0x1a, 0xc6, 0x13, 0xdc, 0x3a, 0xc4,
|
||||||
0xc2, 0xfd, 0xef, 0x26, 0x2c, 0x4a, 0x5b, 0x4d, 0xed, 0x0d, 0xf3, 0xe0, 0x98, 0xcb, 0x9e, 0xc8,
|
0xa0, 0x75, 0xf9, 0x54, 0x5d, 0xb9, 0x08, 0x2d, 0xda, 0x71, 0x70, 0x5f, 0x97, 0xce, 0x55, 0x01,
|
||||||
0x12, 0xee, 0x2a, 0x29, 0x9f, 0xc4, 0x39, 0x1f, 0x58, 0xcb, 0x60, 0x83, 0x48, 0x35, 0x14, 0x8c,
|
0xa0, 0x4f, 0xc1, 0x9f, 0x25, 0x41, 0x4a, 0x4e, 0x83, 0x72, 0x05, 0x9a, 0x64, 0x11, 0xab, 0x15,
|
||||||
0x06, 0x09, 0x5a, 0x7d, 0xea, 0x59, 0xcb, 0xb3, 0x41, 0x9c, 0x2c, 0x04, 0x06, 0xc1, 0x88, 0xfa,
|
0xee, 0x7f, 0x37, 0x61, 0x51, 0xda, 0x6a, 0x6a, 0x6f, 0x98, 0x07, 0xc7, 0x5c, 0xf6, 0x44, 0x96,
|
||||||
0xd4, 0xf4, 0x54, 0x11, 0x67, 0x62, 0xe8, 0x27, 0xfe, 0x30, 0xc8, 0x67, 0x52, 0xb9, 0x75, 0x19,
|
0x70, 0x57, 0x49, 0xf9, 0x24, 0xce, 0xf9, 0xc0, 0x5a, 0x06, 0x1b, 0x44, 0xaa, 0xa1, 0x60, 0x34,
|
||||||
0x79, 0x87, 0xf1, 0xd0, 0x0f, 0x07, 0x07, 0x7e, 0xe8, 0x47, 0x43, 0x2e, 0x1d, 0x17, 0x1b, 0x44,
|
0x48, 0xd0, 0xea, 0x53, 0xcf, 0x5a, 0x9e, 0x0d, 0xe2, 0x64, 0x21, 0x30, 0x08, 0x46, 0xd4, 0xa7,
|
||||||
0xdf, 0x44, 0x76, 0x49, 0x91, 0x09, 0xff, 0xa5, 0x84, 0xa2, 0x8f, 0x33, 0x8c, 0x27, 0x93, 0x20,
|
0xa6, 0xa7, 0x8a, 0x38, 0x13, 0x43, 0x3f, 0xf1, 0x87, 0x41, 0x3e, 0x93, 0xca, 0xad, 0xcb, 0xc8,
|
||||||
0x47, 0x97, 0xa6, 0xb7, 0x24, 0x0c, 0x49, 0x81, 0xd0, 0x48, 0x44, 0xe9, 0x44, 0xcc, 0x5e, 0x4b,
|
0x3b, 0x8c, 0x87, 0x7e, 0x38, 0x38, 0xf0, 0x43, 0x3f, 0x1a, 0x72, 0xe9, 0xb8, 0xd8, 0x20, 0xfa,
|
||||||
0xb4, 0x66, 0x81, 0xc8, 0xe5, 0x90, 0x73, 0x32, 0x48, 0x4f, 0x4f, 0x7a, 0x20, 0xb8, 0x14, 0x08,
|
0x26, 0xb2, 0x4b, 0x8a, 0x4c, 0xf8, 0x2f, 0x25, 0x14, 0x7d, 0x9c, 0x61, 0x3c, 0x99, 0x04, 0x39,
|
||||||
0xae, 0xc3, 0x34, 0xca, 0x78, 0x9e, 0x87, 0x7c, 0xa4, 0x3b, 0xd4, 0x26, 0xb2, 0x6a, 0x05, 0xbb,
|
0xba, 0x34, 0xbd, 0x25, 0x61, 0x48, 0x0a, 0x84, 0x46, 0x22, 0x4a, 0x27, 0x62, 0xf6, 0x5a, 0xa2,
|
||||||
0x0e, 0xeb, 0xc2, 0xcb, 0xca, 0xfc, 0x3c, 0xce, 0x8e, 0x82, 0x6c, 0x90, 0xf1, 0x28, 0xef, 0x75,
|
0x35, 0x0b, 0x44, 0x2e, 0x87, 0x9c, 0x93, 0x41, 0x7a, 0x7a, 0xd2, 0x03, 0xc1, 0xa5, 0x40, 0x70,
|
||||||
0x88, 0xbe, 0xae, 0x8a, 0xbd, 0x0b, 0xe7, 0x4a, 0x70, 0xca, 0x87, 0x3c, 0x38, 0xe6, 0xa3, 0xde,
|
0x1d, 0xa6, 0x51, 0xc6, 0xf3, 0x3c, 0xe4, 0x23, 0xdd, 0xa1, 0x36, 0x91, 0x55, 0x2b, 0xd8, 0x75,
|
||||||
0x32, 0x7d, 0x75, 0x5a, 0x35, 0xbb, 0x0c, 0x6d, 0x74, 0x2e, 0xa7, 0xc9, 0xc8, 0xc7, 0x7d, 0xb8,
|
0x58, 0x17, 0x5e, 0x56, 0xe6, 0xe7, 0x71, 0x76, 0x14, 0x64, 0x83, 0x8c, 0x47, 0x79, 0xaf, 0x43,
|
||||||
0x4b, 0xeb, 0x60, 0x42, 0xec, 0x6d, 0x58, 0x4e, 0xb8, 0xd8, 0x2c, 0x8f, 0xf2, 0x70, 0x98, 0xf5,
|
0xf4, 0x75, 0x55, 0xec, 0x5d, 0x38, 0x57, 0x82, 0x53, 0x3e, 0xe4, 0xc1, 0x31, 0x1f, 0xf5, 0x96,
|
||||||
0x56, 0x68, 0x27, 0x6b, 0x4b, 0x65, 0x42, 0xc9, 0xf5, 0x6c, 0x0a, 0x14, 0xca, 0x61, 0x46, 0xee,
|
0xe9, 0xab, 0xd3, 0xaa, 0xd9, 0x65, 0x68, 0xa3, 0x73, 0x39, 0x4d, 0x46, 0x3e, 0xee, 0xc3, 0x5d,
|
||||||
0x8a, 0x3f, 0xeb, 0xad, 0x92, 0xb8, 0x15, 0x00, 0xe9, 0x48, 0x1a, 0x1c, 0xfb, 0x39, 0xef, 0xad,
|
0x5a, 0x07, 0x13, 0x62, 0x6f, 0xc3, 0x72, 0xc2, 0xc5, 0x66, 0x79, 0x94, 0x87, 0xc3, 0xac, 0xb7,
|
||||||
0x91, 0x6c, 0xa9, 0xa2, 0xfb, 0x67, 0x0e, 0xac, 0x3f, 0x08, 0xb2, 0x5c, 0x0a, 0xa1, 0x36, 0xc7,
|
0x42, 0x3b, 0x59, 0x5b, 0x2a, 0x13, 0x4a, 0xae, 0x67, 0x53, 0xa0, 0x50, 0x0e, 0x33, 0x72, 0x57,
|
||||||
0xaf, 0x43, 0x5b, 0x88, 0xdf, 0x20, 0x8e, 0xc2, 0x99, 0x94, 0x48, 0x10, 0xd0, 0xd7, 0xa2, 0x70,
|
0xfc, 0x59, 0x6f, 0x95, 0xc4, 0xad, 0x00, 0x48, 0x47, 0xd2, 0xe0, 0xd8, 0xcf, 0x79, 0x6f, 0x8d,
|
||||||
0xc6, 0x3e, 0x03, 0xcb, 0x41, 0x64, 0x92, 0x08, 0x1d, 0xee, 0x28, 0x90, 0x88, 0x5e, 0x87, 0x76,
|
0x64, 0x4b, 0x15, 0xdd, 0x3f, 0x75, 0x60, 0xfd, 0x41, 0x90, 0xe5, 0x52, 0x08, 0xb5, 0x39, 0x7e,
|
||||||
0x32, 0x3d, 0x08, 0x83, 0xa1, 0x20, 0x99, 0x13, 0x5c, 0x04, 0x44, 0x04, 0xe8, 0xe8, 0x89, 0x9e,
|
0x1d, 0xda, 0x42, 0xfc, 0x06, 0x71, 0x14, 0xce, 0xa4, 0x44, 0x82, 0x80, 0xbe, 0x16, 0x85, 0x33,
|
||||||
0x08, 0x8a, 0x26, 0x51, 0xb4, 0x25, 0x86, 0x24, 0xee, 0x2d, 0xd8, 0xb0, 0x3b, 0x28, 0x8d, 0xd5,
|
0xf6, 0x19, 0x58, 0x0e, 0x22, 0x93, 0x44, 0xe8, 0x70, 0x47, 0x81, 0x44, 0xf4, 0x3a, 0xb4, 0x93,
|
||||||
0x16, 0x2c, 0x49, 0xd9, 0xce, 0x7a, 0x6d, 0x9a, 0x9f, 0xae, 0x9c, 0x1f, 0x49, 0xea, 0xe9, 0x7a,
|
0xe9, 0x41, 0x18, 0x0c, 0x05, 0xc9, 0x9c, 0xe0, 0x22, 0x20, 0x22, 0x40, 0x47, 0x4f, 0xf4, 0x44,
|
||||||
0xf7, 0xdf, 0x1c, 0x68, 0xa2, 0x01, 0x38, 0xdd, 0x58, 0x98, 0x36, 0x7d, 0xce, 0xb2, 0xe9, 0xe4,
|
0x50, 0x34, 0x89, 0xa2, 0x2d, 0x31, 0x24, 0x71, 0x6f, 0xc1, 0x86, 0xdd, 0x41, 0x69, 0xac, 0xb6,
|
||||||
0xf7, 0xa3, 0x57, 0x24, 0x44, 0x42, 0xa8, 0x8d, 0x81, 0x14, 0xf5, 0x29, 0x1f, 0x1e, 0x93, 0xee,
|
0x60, 0x49, 0xca, 0x76, 0xd6, 0x6b, 0xd3, 0xfc, 0x74, 0xe5, 0xfc, 0x48, 0x52, 0x4f, 0xd7, 0xbb,
|
||||||
0xe8, 0x7a, 0x44, 0x50, 0xb3, 0x70, 0xeb, 0xa4, 0xaf, 0x85, 0xe2, 0xe8, 0xb2, 0xaa, 0xa3, 0x2f,
|
0xff, 0xe6, 0x40, 0x13, 0x0d, 0xc0, 0xe9, 0xc6, 0xc2, 0xb4, 0xe9, 0x73, 0x96, 0x4d, 0x27, 0xbf,
|
||||||
0x17, 0x8b, 0x3a, 0xfa, 0xae, 0x07, 0x8b, 0x41, 0x74, 0x10, 0x4f, 0xa3, 0x11, 0x29, 0xc9, 0x92,
|
0x1f, 0xbd, 0x22, 0x21, 0x12, 0x42, 0x6d, 0x0c, 0xa4, 0xa8, 0x4f, 0xf9, 0xf0, 0x98, 0x74, 0x47,
|
||||||
0xa7, 0x8a, 0xb8, 0xd8, 0x09, 0x79, 0x52, 0xc1, 0x84, 0x4b, 0xed, 0x28, 0x00, 0x97, 0xa1, 0x6b,
|
0xd7, 0x23, 0x82, 0x9a, 0x85, 0x5b, 0x27, 0x7d, 0x2d, 0x14, 0x47, 0x97, 0x55, 0x1d, 0x7d, 0xb9,
|
||||||
0x95, 0x91, 0xc1, 0xd3, 0xfb, 0xd8, 0x3b, 0xb0, 0x66, 0x60, 0x72, 0x06, 0xdf, 0x80, 0xf9, 0x04,
|
0x58, 0xd4, 0xd1, 0x77, 0x3d, 0x58, 0x0c, 0xa2, 0x83, 0x78, 0x1a, 0x8d, 0x48, 0x49, 0x96, 0x3c,
|
||||||
0x01, 0xe9, 0x28, 0x29, 0xf1, 0x22, 0x4b, 0x29, 0x6a, 0xdc, 0x55, 0x8c, 0x9f, 0xf3, 0xf7, 0xa3,
|
0x55, 0xc4, 0xc5, 0x4e, 0xc8, 0x93, 0x0a, 0x26, 0x5c, 0x6a, 0x47, 0x01, 0xb8, 0x0c, 0x5d, 0xab,
|
||||||
0xc3, 0x58, 0x71, 0xfa, 0xe1, 0x1c, 0x06, 0xbc, 0x12, 0x92, 0x8c, 0xae, 0xc2, 0x4a, 0x30, 0xe2,
|
0x8c, 0x0c, 0x9e, 0xde, 0xc7, 0xde, 0x81, 0x35, 0x03, 0x93, 0x33, 0xf8, 0x06, 0xcc, 0x27, 0x08,
|
||||||
0x51, 0x1e, 0xe4, 0xb3, 0x81, 0xe5, 0xc1, 0x95, 0x61, 0xdc, 0x61, 0xfc, 0x30, 0xf0, 0x33, 0x69,
|
0x48, 0x47, 0x49, 0x89, 0x17, 0x59, 0x4a, 0x51, 0xe3, 0xae, 0x62, 0x44, 0x9e, 0xbf, 0x1f, 0x1d,
|
||||||
0xc3, 0x44, 0x81, 0xed, 0xc0, 0x06, 0x8a, 0xbf, 0x92, 0x68, 0xbd, 0xac, 0xc2, 0x91, 0xac, 0xad,
|
0xc6, 0x8a, 0xd3, 0x0f, 0xe7, 0x30, 0x84, 0x96, 0x90, 0x64, 0x74, 0x15, 0x56, 0x82, 0x11, 0x8f,
|
||||||
0x43, 0x8d, 0x45, 0x5c, 0x4a, 0xa0, 0xfe, 0x44, 0x58, 0xda, 0xba, 0x2a, 0x9c, 0x35, 0xc1, 0x09,
|
0xf2, 0x20, 0x9f, 0x0d, 0x2c, 0x0f, 0xae, 0x0c, 0xe3, 0x0e, 0xe3, 0x87, 0x81, 0x9f, 0x49, 0x1b,
|
||||||
0x87, 0x3c, 0x2f, 0x54, 0x44, 0x03, 0x95, 0xe8, 0x6d, 0x41, 0x38, 0xb1, 0xe5, 0xe8, 0xcd, 0x88,
|
0x26, 0x0a, 0x6c, 0x07, 0x36, 0x50, 0xfc, 0x95, 0x44, 0xeb, 0x65, 0x15, 0x8e, 0x64, 0x6d, 0x1d,
|
||||||
0x00, 0x97, 0x2a, 0x11, 0xe0, 0x55, 0x58, 0xc9, 0x66, 0xd1, 0x90, 0x8f, 0x06, 0x79, 0x8c, 0xed,
|
0x6a, 0x2c, 0xe2, 0x52, 0x02, 0xf5, 0x27, 0xc2, 0xd2, 0xd6, 0x55, 0xe1, 0xac, 0x09, 0x4e, 0x38,
|
||||||
0x06, 0x11, 0xad, 0xce, 0x92, 0x57, 0x86, 0x29, 0x56, 0xe5, 0x59, 0x1e, 0xf1, 0x9c, 0x4c, 0xd7,
|
0xe4, 0x79, 0xa1, 0x22, 0x1a, 0xa8, 0x44, 0x6f, 0x0b, 0xc2, 0x89, 0x2d, 0x47, 0x6f, 0x46, 0x04,
|
||||||
0x92, 0xa7, 0x8a, 0xb8, 0x0b, 0x10, 0x89, 0x10, 0xea, 0x96, 0x27, 0x4b, 0xb8, 0x55, 0x4e, 0xd3,
|
0xb8, 0x54, 0x89, 0x00, 0xaf, 0xc2, 0x4a, 0x36, 0x8b, 0x86, 0x7c, 0x34, 0xc8, 0x63, 0x6c, 0x37,
|
||||||
0x20, 0xeb, 0x75, 0x08, 0xa5, 0xdf, 0xec, 0xf3, 0x70, 0xf6, 0x00, 0x23, 0xab, 0x23, 0xee, 0x8f,
|
0x88, 0x68, 0x75, 0x96, 0xbc, 0x32, 0x4c, 0xb1, 0x2a, 0xcf, 0xf2, 0x88, 0xe7, 0x64, 0xba, 0x96,
|
||||||
0x78, 0x4a, 0xab, 0x2f, 0x02, 0x4b, 0x61, 0x81, 0xea, 0x2b, 0xb1, 0xed, 0x63, 0x9e, 0x66, 0x41,
|
0x3c, 0x55, 0xc4, 0x5d, 0x80, 0x48, 0x84, 0x50, 0xb7, 0x3c, 0x59, 0xc2, 0xad, 0x72, 0x9a, 0x06,
|
||||||
0x1c, 0x91, 0xed, 0x69, 0x79, 0xaa, 0xe8, 0x7e, 0x4c, 0x3b, 0xba, 0x0e, 0x79, 0x1f, 0x93, 0x39,
|
0x59, 0xaf, 0x43, 0x28, 0xfd, 0x66, 0x9f, 0x87, 0xb3, 0x07, 0x18, 0x59, 0x1d, 0x71, 0x7f, 0xc4,
|
||||||
0x62, 0x17, 0xa0, 0x25, 0xc6, 0x98, 0x1d, 0xf9, 0xd2, 0xc9, 0x58, 0x22, 0x60, 0xff, 0xc8, 0x47,
|
0x53, 0x5a, 0x7d, 0x11, 0x58, 0x0a, 0x0b, 0x54, 0x5f, 0x89, 0x6d, 0x1f, 0xf3, 0x34, 0x0b, 0xe2,
|
||||||
0x05, 0xb6, 0xa6, 0xad, 0x41, 0x9e, 0x63, 0x9b, 0xb0, 0x5d, 0x31, 0x6b, 0x6f, 0x42, 0x57, 0x05,
|
0x88, 0x6c, 0x4f, 0xcb, 0x53, 0x45, 0xf7, 0x63, 0xda, 0xd1, 0x75, 0xc8, 0xfb, 0x98, 0xcc, 0x11,
|
||||||
0xd3, 0xd9, 0x20, 0xe4, 0x87, 0xb9, 0x0a, 0x10, 0xa2, 0xe9, 0x04, 0x9b, 0xcb, 0x1e, 0xf0, 0xc3,
|
0xbb, 0x00, 0x2d, 0x31, 0xc6, 0xec, 0xc8, 0x97, 0x4e, 0xc6, 0x12, 0x01, 0xfb, 0x47, 0x3e, 0x2a,
|
||||||
0xdc, 0x7d, 0x08, 0x6b, 0x52, 0x6f, 0xbf, 0x96, 0x70, 0xd5, 0xf4, 0x17, 0xcb, 0x9b, 0x9a, 0xf0,
|
0xb0, 0x35, 0x6d, 0x22, 0x84, 0x6f, 0x13, 0xb6, 0x2b, 0x66, 0xed, 0x4d, 0xe8, 0xaa, 0x60, 0x3a,
|
||||||
0x2a, 0xd6, 0x6d, 0x45, 0xa7, 0x28, 0xa7, 0xb4, 0xd3, 0xb9, 0x1e, 0x30, 0x59, 0x7d, 0x3b, 0x8c,
|
0x1b, 0x84, 0xfc, 0x30, 0x57, 0x01, 0x42, 0x34, 0x9d, 0x60, 0x73, 0xd9, 0x03, 0x7e, 0x98, 0xbb,
|
||||||
0x33, 0x2e, 0x19, 0xba, 0xd0, 0x19, 0x86, 0x71, 0xa6, 0xc2, 0x10, 0x39, 0x1c, 0x0b, 0xc3, 0xf9,
|
0x0f, 0x61, 0x4d, 0xea, 0xed, 0xd7, 0x12, 0xae, 0x9a, 0xfe, 0x62, 0x79, 0x53, 0x13, 0x5e, 0xc5,
|
||||||
0xc9, 0xa6, 0xc3, 0x21, 0x5a, 0x02, 0x61, 0xd3, 0x54, 0xd1, 0xfd, 0x73, 0x07, 0xd6, 0x89, 0x9b,
|
0xba, 0xad, 0xe8, 0x14, 0xe5, 0x94, 0x76, 0x3a, 0xd7, 0x03, 0x26, 0xab, 0x6f, 0x87, 0x71, 0xc6,
|
||||||
0xb2, 0x30, 0xda, 0x77, 0x7d, 0xf5, 0x6e, 0x76, 0x86, 0x66, 0x68, 0xb6, 0x01, 0xf3, 0x87, 0x71,
|
0x25, 0x43, 0x17, 0x3a, 0xc3, 0x30, 0xce, 0x54, 0x18, 0x22, 0x87, 0x63, 0x61, 0x38, 0x3f, 0xd9,
|
||||||
0x3a, 0xe4, 0xb2, 0x25, 0x51, 0xf8, 0xf1, 0xbd, 0xf1, 0x66, 0xc5, 0x1b, 0xff, 0xa1, 0x03, 0x6b,
|
0x74, 0x38, 0x44, 0x4b, 0x20, 0x6c, 0x9a, 0x2a, 0xba, 0x7f, 0xe6, 0xc0, 0x3a, 0x71, 0x53, 0x16,
|
||||||
0xd4, 0xd5, 0xfd, 0xdc, 0xcf, 0xa7, 0x99, 0x1c, 0xfe, 0x2f, 0xc0, 0x32, 0x0e, 0x95, 0x2b, 0x75,
|
0x46, 0xfb, 0xae, 0xaf, 0xde, 0xcd, 0xce, 0xd0, 0x0c, 0xcd, 0x36, 0x60, 0xfe, 0x30, 0x4e, 0x87,
|
||||||
0x92, 0x1d, 0xdd, 0xd0, 0x9a, 0x4f, 0xa8, 0x20, 0xde, 0x3d, 0xe3, 0xd9, 0xc4, 0xec, 0xcb, 0xd0,
|
0x5c, 0xb6, 0x24, 0x0a, 0x3f, 0xbe, 0x37, 0xde, 0xac, 0x78, 0xe3, 0x3f, 0x74, 0x60, 0x8d, 0xba,
|
||||||
0x31, 0x33, 0x22, 0xd4, 0xe7, 0xf6, 0xce, 0x79, 0x35, 0xca, 0x8a, 0xe4, 0xec, 0x9e, 0xf1, 0xac,
|
0xba, 0x9f, 0xfb, 0xf9, 0x34, 0x93, 0xc3, 0xff, 0x05, 0x58, 0xc6, 0xa1, 0x72, 0xa5, 0x4e, 0xb2,
|
||||||
0x0f, 0xd8, 0x0d, 0x00, 0x72, 0x37, 0x88, 0xad, 0x0c, 0x65, 0xcf, 0xdb, 0x93, 0x64, 0x2c, 0xd6,
|
0xa3, 0x1b, 0x5a, 0xf3, 0x09, 0x15, 0xc4, 0xbb, 0x67, 0x3c, 0x9b, 0x98, 0x7d, 0x19, 0x3a, 0x66,
|
||||||
0xee, 0x19, 0xcf, 0x20, 0xbf, 0xb5, 0x04, 0x0b, 0x62, 0x7f, 0x74, 0xef, 0xc3, 0xb2, 0xd5, 0x53,
|
0x46, 0x84, 0xfa, 0xdc, 0xde, 0x39, 0xaf, 0x46, 0x59, 0x91, 0x9c, 0xdd, 0x33, 0x9e, 0xf5, 0x01,
|
||||||
0x2b, 0xca, 0xe8, 0x88, 0x28, 0xa3, 0x12, 0x94, 0x36, 0xaa, 0x41, 0xa9, 0xfb, 0x2f, 0x0d, 0x60,
|
0xbb, 0x01, 0x40, 0xee, 0x06, 0xb1, 0x95, 0xa1, 0xec, 0x79, 0x7b, 0x92, 0x8c, 0xc5, 0xda, 0x3d,
|
||||||
0x28, 0x6d, 0xa5, 0xe5, 0xc4, 0x0d, 0x3a, 0x1e, 0x59, 0xee, 0x56, 0xc7, 0x33, 0x21, 0x76, 0x0d,
|
0xe3, 0x19, 0xe4, 0xb7, 0x96, 0x60, 0x41, 0xec, 0x8f, 0xee, 0x7d, 0x58, 0xb6, 0x7a, 0x6a, 0x45,
|
||||||
0x98, 0x51, 0x54, 0xb9, 0x07, 0xb1, 0x6f, 0xd4, 0xd4, 0xa0, 0x81, 0x13, 0xbe, 0x92, 0x8a, 0x81,
|
0x19, 0x1d, 0x11, 0x65, 0x54, 0x82, 0xd2, 0x46, 0x35, 0x28, 0x75, 0xff, 0xa5, 0x01, 0x0c, 0xa5,
|
||||||
0xa5, 0x63, 0x29, 0xd6, 0xad, 0xb6, 0x0e, 0xb7, 0x86, 0x64, 0x9a, 0x1d, 0xa1, 0x03, 0xa1, 0x1c,
|
0xad, 0xb4, 0x9c, 0xb8, 0x41, 0xc7, 0x23, 0xcb, 0xdd, 0xea, 0x78, 0x26, 0xc4, 0xae, 0x01, 0x33,
|
||||||
0x32, 0x55, 0x2e, 0x0b, 0xc8, 0xc2, 0x4b, 0x05, 0x64, 0xb1, 0x2c, 0x20, 0xa6, 0x4b, 0xb0, 0x64,
|
0x8a, 0x2a, 0xf7, 0x20, 0xf6, 0x8d, 0x9a, 0x1a, 0x34, 0x70, 0xc2, 0x57, 0x52, 0x31, 0xb0, 0x74,
|
||||||
0xb9, 0x04, 0xe8, 0x7f, 0x4d, 0x82, 0x88, 0xfc, 0x8a, 0xc1, 0x04, 0x5b, 0x97, 0xfe, 0x97, 0x05,
|
0x2c, 0xc5, 0xba, 0xd5, 0xd6, 0xe1, 0xd6, 0x90, 0x4c, 0xb3, 0x23, 0x74, 0x20, 0x94, 0x43, 0xa6,
|
||||||
0xb2, 0x2d, 0x58, 0x95, 0x7e, 0x5d, 0xe1, 0x77, 0x00, 0xcd, 0x71, 0x05, 0x77, 0x3f, 0x75, 0x60,
|
0xca, 0x65, 0x01, 0x59, 0x78, 0xa9, 0x80, 0x2c, 0x96, 0x05, 0xc4, 0x74, 0x09, 0x96, 0x2c, 0x97,
|
||||||
0x15, 0xe7, 0xd9, 0x92, 0xc5, 0xf7, 0x80, 0x54, 0xe1, 0x15, 0x45, 0xd1, 0xa2, 0xfd, 0xe9, 0x25,
|
0x00, 0xfd, 0xaf, 0x49, 0x10, 0x91, 0x5f, 0x31, 0x98, 0x60, 0xeb, 0xd2, 0xff, 0xb2, 0x40, 0xb6,
|
||||||
0xf1, 0x5d, 0x68, 0x11, 0xc3, 0x38, 0xe1, 0x91, 0x14, 0xc4, 0x9e, 0x2d, 0x88, 0x85, 0x15, 0xda,
|
0x05, 0xab, 0xd2, 0xaf, 0x2b, 0xfc, 0x0e, 0xa0, 0x39, 0xae, 0xe0, 0xee, 0xa7, 0x0e, 0xac, 0xe2,
|
||||||
0x3d, 0xe3, 0x15, 0xc4, 0x86, 0x18, 0xfe, 0xbd, 0x03, 0x6d, 0xd9, 0xcd, 0x9f, 0x38, 0x96, 0xe8,
|
0x3c, 0x5b, 0xb2, 0xf8, 0x1e, 0x90, 0x2a, 0xbc, 0xa2, 0x28, 0x5a, 0xb4, 0x3f, 0xbd, 0x24, 0xbe,
|
||||||
0xc3, 0x12, 0x4a, 0xa4, 0xe1, 0xb0, 0xeb, 0x32, 0xee, 0x26, 0x13, 0x0c, 0xd8, 0x70, 0xfb, 0xb4,
|
0x0b, 0x2d, 0x62, 0x18, 0x27, 0x3c, 0x92, 0x82, 0xd8, 0xb3, 0x05, 0xb1, 0xb0, 0x42, 0xbb, 0x67,
|
||||||
0xe2, 0x88, 0x32, 0x8c, 0x7b, 0x21, 0x19, 0xdc, 0x6c, 0x90, 0x07, 0xe1, 0x40, 0xd5, 0xca, 0x04,
|
0xbc, 0x82, 0xd8, 0x10, 0xc3, 0xbf, 0x77, 0xa0, 0x2d, 0xbb, 0xf9, 0x13, 0xc7, 0x12, 0x7d, 0x58,
|
||||||
0x64, 0x5d, 0x15, 0xda, 0x9d, 0x2c, 0xf7, 0xc7, 0x5c, 0x6e, 0x73, 0xa2, 0x80, 0x01, 0x93, 0x1c,
|
0x42, 0x89, 0x34, 0x1c, 0x76, 0x5d, 0xc6, 0xdd, 0x64, 0x82, 0x01, 0x1b, 0x6e, 0x9f, 0x56, 0x1c,
|
||||||
0x50, 0xc9, 0x1d, 0x74, 0xff, 0xa6, 0x03, 0xe7, 0x2a, 0x55, 0x3a, 0xdd, 0x2d, 0x1d, 0xe4, 0x30,
|
0x51, 0x86, 0x71, 0x2f, 0x24, 0x83, 0x9b, 0x0d, 0xf2, 0x20, 0x1c, 0xa8, 0x5a, 0x99, 0x80, 0xac,
|
||||||
0x98, 0x1c, 0xc4, 0xda, 0xd7, 0x76, 0x4c, 0xdf, 0xd9, 0xaa, 0x62, 0x63, 0x38, 0xab, 0xf6, 0x73,
|
0xab, 0x42, 0xbb, 0x93, 0xe5, 0xfe, 0x98, 0xcb, 0x6d, 0x4e, 0x14, 0x30, 0x60, 0x92, 0x03, 0x2a,
|
||||||
0x9c, 0xd3, 0x62, 0xf7, 0x6e, 0x90, 0x23, 0xf2, 0xb6, 0x2d, 0x03, 0xe5, 0x06, 0x15, 0x6e, 0x6a,
|
0xb9, 0x83, 0xee, 0x5f, 0x77, 0xe0, 0x5c, 0xa5, 0x4a, 0x27, 0xd0, 0xa5, 0x83, 0x1c, 0x06, 0x93,
|
||||||
0x6e, 0x3d, 0x3f, 0x76, 0x04, 0x3d, 0xed, 0x38, 0x48, 0x13, 0x6f, 0x38, 0x17, 0xd8, 0xd6, 0x5b,
|
0x83, 0x58, 0xfb, 0xda, 0x8e, 0xe9, 0x3b, 0x5b, 0x55, 0x6c, 0x0c, 0x67, 0xd5, 0x7e, 0x8e, 0x73,
|
||||||
0x2f, 0x69, 0x8b, 0xec, 0xd1, 0x48, 0x35, 0x73, 0x2a, 0x37, 0x36, 0x83, 0x4b, 0xaa, 0x8e, 0x6c,
|
0x5a, 0xec, 0xde, 0x0d, 0x72, 0x44, 0xde, 0xb6, 0x65, 0xa0, 0xdc, 0xa0, 0xc2, 0x4d, 0xcd, 0xad,
|
||||||
0x78, 0xb5, 0xbd, 0xe6, 0x2b, 0x8d, 0xed, 0x1e, 0x7e, 0x6c, 0x37, 0xfa, 0x12, 0xc6, 0xec, 0x43,
|
0xe7, 0xc7, 0x8e, 0xa0, 0xa7, 0x1d, 0x07, 0x69, 0xe2, 0x0d, 0xe7, 0x02, 0xdb, 0x7a, 0xeb, 0x25,
|
||||||
0xd8, 0x3c, 0xf1, 0x83, 0x5c, 0x75, 0xcb, 0x70, 0x86, 0xe6, 0xa9, 0xc9, 0x9d, 0x97, 0x34, 0xf9,
|
0x6d, 0x91, 0x3d, 0x1a, 0xa9, 0x66, 0x4e, 0xe5, 0xc6, 0x66, 0x70, 0x49, 0xd5, 0x91, 0x0d, 0xaf,
|
||||||
0x44, 0x7c, 0x6c, 0x6d, 0x6c, 0xa7, 0x70, 0xec, 0xff, 0xad, 0x03, 0x5d, 0x9b, 0x0f, 0x8a, 0xa9,
|
0xb6, 0xd7, 0x7c, 0xa5, 0xb1, 0xdd, 0xc3, 0x8f, 0xed, 0x46, 0x5f, 0xc2, 0x98, 0x7d, 0x08, 0x9b,
|
||||||
0x54, 0x78, 0x65, 0xf8, 0x94, 0xf3, 0x57, 0x82, 0xab, 0x21, 0x6a, 0xa3, 0x2e, 0x44, 0x35, 0x03,
|
0x27, 0x7e, 0x90, 0xab, 0x6e, 0x19, 0xce, 0xd0, 0x3c, 0x35, 0xb9, 0xf3, 0x92, 0x26, 0x9f, 0x88,
|
||||||
0xd1, 0xb9, 0x97, 0x05, 0xa2, 0xcd, 0x57, 0x0b, 0x44, 0xe7, 0xeb, 0x02, 0xd1, 0xfe, 0x7f, 0x3a,
|
0x8f, 0xad, 0x8d, 0xed, 0x14, 0x8e, 0xfd, 0xbf, 0x75, 0xa0, 0x6b, 0xf3, 0x41, 0x31, 0x95, 0x0a,
|
||||||
0xc0, 0xaa, 0xb2, 0xc4, 0xee, 0x8b, 0x18, 0x39, 0xe2, 0xa1, 0xb4, 0x49, 0x3f, 0xf7, 0x6a, 0xf2,
|
0xaf, 0x0c, 0x9f, 0x72, 0xfe, 0x4a, 0x70, 0x35, 0x44, 0x6d, 0xd4, 0x85, 0xa8, 0x66, 0x20, 0x3a,
|
||||||
0xa8, 0xe6, 0x4e, 0x7d, 0x8d, 0x8a, 0x61, 0x1a, 0x1d, 0xd3, 0x45, 0x5a, 0xf6, 0xea, 0xaa, 0x4a,
|
0xf7, 0xb2, 0x40, 0xb4, 0xf9, 0x6a, 0x81, 0xe8, 0x7c, 0x5d, 0x20, 0xda, 0xff, 0x4f, 0x07, 0x58,
|
||||||
0xa1, 0x71, 0xf3, 0xe5, 0xa1, 0xf1, 0xfc, 0xcb, 0x43, 0xe3, 0x85, 0x72, 0x68, 0xdc, 0xff, 0x5d,
|
0x55, 0x96, 0xd8, 0x7d, 0x11, 0x23, 0x47, 0x3c, 0x94, 0x36, 0xe9, 0xe7, 0x5e, 0x4d, 0x1e, 0xd5,
|
||||||
0x07, 0xd6, 0x6b, 0x16, 0xfd, 0x67, 0x37, 0x70, 0x5c, 0x26, 0xcb, 0x16, 0x34, 0xe4, 0x32, 0x99,
|
0xdc, 0xa9, 0xaf, 0x51, 0x31, 0x4c, 0xa3, 0x63, 0xba, 0x48, 0xcb, 0x5e, 0x5d, 0x55, 0x29, 0x34,
|
||||||
0x60, 0xff, 0x37, 0x60, 0xd9, 0x12, 0xf4, 0x9f, 0x5d, 0xfb, 0x65, 0x2f, 0x4f, 0xc8, 0x99, 0x85,
|
0x6e, 0xbe, 0x3c, 0x34, 0x9e, 0x7f, 0x79, 0x68, 0xbc, 0x50, 0x0e, 0x8d, 0xfb, 0xbf, 0xeb, 0xc0,
|
||||||
0xf5, 0x7f, 0xd4, 0x00, 0x56, 0x55, 0xb6, 0xff, 0xd3, 0x3e, 0x54, 0xe7, 0x69, 0xae, 0x66, 0x9e,
|
0x7a, 0xcd, 0xa2, 0xff, 0xec, 0x06, 0x8e, 0xcb, 0x64, 0xd9, 0x82, 0x86, 0x5c, 0x26, 0x13, 0xec,
|
||||||
0xfe, 0x57, 0xf7, 0x81, 0xb7, 0x60, 0x2d, 0xe5, 0xc3, 0xf8, 0x98, 0xce, 0x1d, 0xed, 0xec, 0x4e,
|
0xff, 0x06, 0x2c, 0x5b, 0x82, 0xfe, 0xb3, 0x6b, 0xbf, 0xec, 0xe5, 0x09, 0x39, 0xb3, 0xb0, 0xfe,
|
||||||
0xb5, 0x02, 0xfd, 0x5c, 0x3b, 0x2f, 0xb1, 0x64, 0x1d, 0x13, 0x19, 0x9b, 0x61, 0x29, 0x3d, 0xe1,
|
0x8f, 0x1a, 0xc0, 0xaa, 0xca, 0xf6, 0x7f, 0xda, 0x87, 0xea, 0x3c, 0xcd, 0xd5, 0xcc, 0xd3, 0xff,
|
||||||
0x6e, 0xc2, 0x86, 0x38, 0xbd, 0xbb, 0x25, 0x58, 0xa9, 0x7d, 0xe5, 0x4f, 0x1d, 0x38, 0x5b, 0xaa,
|
0xea, 0x3e, 0xf0, 0x16, 0xac, 0xc9, 0xd3, 0x36, 0x23, 0x4b, 0x22, 0x24, 0xa6, 0x5a, 0x81, 0x7e,
|
||||||
0x28, 0xce, 0x52, 0xc4, 0xd6, 0x61, 0xef, 0x27, 0x36, 0x88, 0xfd, 0x97, 0x7a, 0x64, 0xf4, 0x5f,
|
0xae, 0x9d, 0x97, 0x58, 0xb2, 0x8e, 0x89, 0x8c, 0xcd, 0xb0, 0x94, 0x9e, 0x70, 0x37, 0x61, 0x43,
|
||||||
0x48, 0x5b, 0xb5, 0x02, 0xe7, 0x67, 0x1a, 0x55, 0xe9, 0xc5, 0xac, 0xd7, 0x55, 0xb9, 0xe7, 0xe0,
|
0x9c, 0xde, 0xdd, 0x12, 0xac, 0xd4, 0xbe, 0xf2, 0x27, 0x0e, 0x9c, 0x2d, 0x55, 0x14, 0x67, 0x29,
|
||||||
0xac, 0x5c, 0xd9, 0x52, 0xc7, 0x0f, 0x61, 0xb3, 0x5c, 0x51, 0x24, 0x87, 0xed, 0x2e, 0xab, 0x22,
|
0x62, 0xeb, 0xb0, 0xf7, 0x13, 0x1b, 0xc4, 0xfe, 0x4b, 0x3d, 0x32, 0xfa, 0x2f, 0xa4, 0xad, 0x5a,
|
||||||
0x7a, 0x81, 0xd6, 0x36, 0x65, 0xf7, 0xb7, 0xb6, 0xce, 0xfd, 0x75, 0x60, 0x5f, 0x9f, 0xf2, 0x74,
|
0x81, 0xf3, 0x33, 0x8d, 0xaa, 0xf4, 0x62, 0xd6, 0xeb, 0xaa, 0xdc, 0x73, 0x70, 0x56, 0xae, 0x6c,
|
||||||
0x46, 0x27, 0x3d, 0x3a, 0x3b, 0x73, 0xae, 0x9c, 0xc6, 0x58, 0x48, 0xa6, 0x07, 0x5f, 0xe5, 0x33,
|
0xa9, 0xe3, 0x87, 0xb0, 0x59, 0xae, 0x28, 0x92, 0xc3, 0x76, 0x97, 0x55, 0x11, 0xbd, 0x40, 0x6b,
|
||||||
0x75, 0x94, 0xd6, 0x28, 0x8e, 0xd2, 0x5e, 0x03, 0xc0, 0xe8, 0x8b, 0x8e, 0x86, 0xd4, 0xe1, 0x26,
|
0x9b, 0xb2, 0xfb, 0x5b, 0x5b, 0xe7, 0xfe, 0x3a, 0xb0, 0xaf, 0x4f, 0x79, 0x3a, 0xa3, 0x93, 0x1e,
|
||||||
0x86, 0xbd, 0x82, 0xa1, 0x7b, 0x03, 0xd6, 0x2d, 0xfe, 0x7a, 0xf6, 0x17, 0xe4, 0x17, 0x22, 0x37,
|
0x9d, 0x9d, 0x39, 0x57, 0x4e, 0x63, 0x2c, 0x24, 0xd3, 0x83, 0xaf, 0xf2, 0x99, 0x3a, 0x4a, 0x6b,
|
||||||
0x60, 0x1f, 0x38, 0xc9, 0x3a, 0xf7, 0xdf, 0x1d, 0x98, 0xdb, 0x8d, 0x13, 0x33, 0xab, 0xe8, 0xd8,
|
0x14, 0x47, 0x69, 0xaf, 0x01, 0x60, 0xf4, 0x45, 0x47, 0x43, 0xea, 0x70, 0x13, 0xc3, 0x5e, 0xc1,
|
||||||
0x59, 0x45, 0x69, 0xf2, 0x07, 0xda, 0xa2, 0x4b, 0x4b, 0x60, 0x81, 0x6c, 0x0b, 0xba, 0xfe, 0x24,
|
0xd0, 0xbd, 0x01, 0xeb, 0x16, 0x7f, 0x3d, 0xfb, 0x0b, 0xf2, 0x0b, 0x91, 0x1b, 0xb0, 0x0f, 0x9c,
|
||||||
0xc7, 0xe8, 0xf8, 0x30, 0x4e, 0x4f, 0xfc, 0x74, 0x24, 0x96, 0xe4, 0x56, 0xa3, 0xe7, 0x78, 0xa5,
|
0x64, 0x9d, 0xfb, 0xef, 0x0e, 0xcc, 0xed, 0xc6, 0x89, 0x99, 0x55, 0x74, 0xec, 0xac, 0xa2, 0x34,
|
||||||
0x1a, 0xb6, 0x01, 0x73, 0xda, 0x36, 0x12, 0x01, 0x16, 0xd1, 0xbf, 0xa2, 0xe4, 0xea, 0x4c, 0x06,
|
0xf9, 0x03, 0x6d, 0xd1, 0xa5, 0x25, 0xb0, 0x40, 0xb6, 0x05, 0x5d, 0x7f, 0x92, 0x63, 0x74, 0x7c,
|
||||||
0xf6, 0xb2, 0x84, 0x2b, 0x6e, 0x7f, 0x2f, 0x3c, 0x5a, 0x21, 0xe1, 0x75, 0x55, 0xb8, 0xfd, 0xa0,
|
0x18, 0xa7, 0x27, 0x7e, 0x3a, 0x12, 0x4b, 0x72, 0xab, 0xd1, 0x73, 0xbc, 0x52, 0x0d, 0xdb, 0x80,
|
||||||
0xa9, 0x24, 0x32, 0x99, 0x91, 0x51, 0x65, 0xf7, 0x5f, 0x1d, 0x98, 0xa7, 0x19, 0x40, 0x9d, 0x14,
|
0x39, 0x6d, 0x1b, 0x89, 0x00, 0x8b, 0xe8, 0x5f, 0x51, 0x72, 0x75, 0x26, 0x03, 0x7b, 0x59, 0xc2,
|
||||||
0x82, 0x48, 0x67, 0xb7, 0x94, 0x09, 0x76, 0x84, 0x4e, 0x96, 0x60, 0xe6, 0x5a, 0x27, 0xba, 0x0d,
|
0x15, 0xb7, 0xbf, 0x17, 0x1e, 0xad, 0x90, 0xf0, 0xba, 0x2a, 0xdc, 0x7e, 0xd0, 0x54, 0x12, 0x99,
|
||||||
0xdd, 0x6d, 0xf3, 0x54, 0xf7, 0x32, 0xb4, 0x44, 0x49, 0x1f, 0x83, 0x12, 0x49, 0x01, 0xb2, 0x4b,
|
0xcc, 0xc8, 0xa8, 0xb2, 0xfb, 0xaf, 0x0e, 0xcc, 0xd3, 0x0c, 0xa0, 0x4e, 0x0a, 0x41, 0xa4, 0xb3,
|
||||||
0xd0, 0x3c, 0x8a, 0x13, 0xe5, 0x44, 0x80, 0x4a, 0x04, 0xc6, 0x89, 0x47, 0x78, 0xd1, 0x1f, 0xe4,
|
0x5b, 0xca, 0x04, 0x3b, 0x42, 0x27, 0x4b, 0x30, 0x73, 0xad, 0x13, 0xdd, 0x86, 0xee, 0xb6, 0x79,
|
||||||
0x27, 0x3a, 0x2f, 0xb6, 0x86, 0x32, 0x8c, 0x9b, 0xa3, 0x66, 0x6b, 0x4e, 0x46, 0x09, 0x75, 0xb7,
|
0xaa, 0x7b, 0x19, 0x5a, 0xa2, 0xa4, 0x8f, 0x41, 0x89, 0xa4, 0x00, 0xd9, 0x25, 0x68, 0x1e, 0xc5,
|
||||||
0x60, 0xe5, 0x61, 0x3c, 0xe2, 0x46, 0xea, 0xe7, 0x54, 0xa9, 0x73, 0x7f, 0xd3, 0x81, 0x25, 0x45,
|
0x89, 0x72, 0x22, 0x40, 0x25, 0x02, 0xe3, 0xc4, 0x23, 0xbc, 0xe8, 0x0f, 0xf2, 0x13, 0x9d, 0x17,
|
||||||
0xcc, 0xae, 0x42, 0x13, 0x77, 0xfc, 0x92, 0x3f, 0xaf, 0x0f, 0x00, 0x90, 0xce, 0x23, 0x0a, 0x34,
|
0x5b, 0x43, 0x19, 0xc6, 0xcd, 0x51, 0xb3, 0x35, 0x27, 0xa3, 0x84, 0xba, 0x5b, 0xb0, 0xf2, 0x30,
|
||||||
0x91, 0x94, 0x18, 0x28, 0xbc, 0x3f, 0x95, 0x16, 0x28, 0x9c, 0x1b, 0xdd, 0xdd, 0x92, 0x4f, 0x50,
|
0x1e, 0x71, 0x23, 0xf5, 0x73, 0xaa, 0xd4, 0xb9, 0xbf, 0xe9, 0xc0, 0x92, 0x22, 0x66, 0x57, 0xa1,
|
||||||
0x42, 0xdd, 0xbf, 0x70, 0x60, 0xd9, 0x6a, 0x03, 0xa3, 0xb8, 0xd0, 0xcf, 0x72, 0x99, 0x54, 0x95,
|
0x89, 0x3b, 0x7e, 0xc9, 0x9f, 0xd7, 0x07, 0x00, 0x48, 0xe7, 0x11, 0x05, 0x9a, 0x48, 0x4a, 0x0c,
|
||||||
0xcb, 0x63, 0x42, 0x66, 0x32, 0xb0, 0x61, 0x27, 0x03, 0x75, 0x9a, 0x6a, 0xce, 0x4c, 0x53, 0x5d,
|
0x14, 0xde, 0x9f, 0x4a, 0x0b, 0x14, 0xce, 0x8d, 0xee, 0x6e, 0xc9, 0x27, 0x28, 0xa1, 0xee, 0x9f,
|
||||||
0x87, 0x56, 0x71, 0xee, 0xde, 0xb4, 0x4c, 0x1f, 0xb6, 0xa8, 0x8e, 0x36, 0x0a, 0x22, 0xe4, 0x33,
|
0x3b, 0xb0, 0x6c, 0xb5, 0x81, 0x51, 0x5c, 0xe8, 0x67, 0xb9, 0x4c, 0xaa, 0xca, 0xe5, 0x31, 0x21,
|
||||||
0x8c, 0xc3, 0x38, 0x95, 0xc7, 0xd2, 0xa2, 0xe0, 0xde, 0x80, 0xb6, 0x41, 0x8f, 0xdd, 0x88, 0x78,
|
0x33, 0x19, 0xd8, 0xb0, 0x93, 0x81, 0x3a, 0x4d, 0x35, 0x67, 0xa6, 0xa9, 0xae, 0x43, 0xab, 0x38,
|
||||||
0x7e, 0x12, 0xa7, 0x4f, 0x55, 0x4e, 0x52, 0x16, 0xf5, 0x09, 0x5e, 0xa3, 0x38, 0xc1, 0x73, 0xff,
|
0x77, 0x6f, 0x5a, 0xa6, 0x0f, 0x5b, 0x54, 0x47, 0x1b, 0x05, 0x11, 0xf2, 0x19, 0xc6, 0x61, 0x9c,
|
||||||
0xd2, 0x81, 0x65, 0x94, 0xc1, 0x20, 0x1a, 0xef, 0xc5, 0x61, 0x30, 0x9c, 0xd1, 0xda, 0x2b, 0x71,
|
0xca, 0x63, 0x69, 0x51, 0x70, 0x6f, 0x40, 0xdb, 0xa0, 0xc7, 0x6e, 0x44, 0x3c, 0x3f, 0x89, 0xd3,
|
||||||
0x93, 0xe7, 0xd5, 0x4a, 0x16, 0x6d, 0x18, 0x65, 0x5b, 0x05, 0x71, 0x52, 0x11, 0x75, 0x19, 0x35,
|
0xa7, 0x2a, 0x27, 0x29, 0x8b, 0xfa, 0x04, 0xaf, 0x51, 0x9c, 0xe0, 0xb9, 0x7f, 0xe1, 0xc0, 0x32,
|
||||||
0x15, 0xe5, 0xfc, 0xc0, 0xcf, 0xa4, 0xf0, 0xcb, 0xbd, 0xc8, 0x02, 0x51, 0x9f, 0x10, 0x48, 0xfd,
|
0xca, 0x60, 0x10, 0x8d, 0xf7, 0xe2, 0x30, 0x18, 0xce, 0x68, 0xed, 0x95, 0xb8, 0xc9, 0xf3, 0x6a,
|
||||||
0x9c, 0x0f, 0x26, 0x41, 0x18, 0x06, 0x82, 0x56, 0x78, 0x2a, 0x75, 0x55, 0xee, 0x0f, 0x1a, 0xd0,
|
0x25, 0x8b, 0x36, 0x8c, 0xb2, 0xad, 0x82, 0x38, 0xa9, 0x88, 0xba, 0x8c, 0x9a, 0x8a, 0x72, 0x7e,
|
||||||
0x96, 0x96, 0xf2, 0xee, 0x68, 0x2c, 0xb2, 0xff, 0xd2, 0xdf, 0xd3, 0xe6, 0xc2, 0x40, 0x54, 0xbd,
|
0xe0, 0x67, 0x52, 0xf8, 0xe5, 0x5e, 0x64, 0x81, 0xa8, 0x4f, 0x08, 0xa4, 0x7e, 0xce, 0x07, 0x93,
|
||||||
0xe5, 0x21, 0x1a, 0x48, 0x79, 0x59, 0xe7, 0xaa, 0xcb, 0x7a, 0x11, 0x5a, 0x28, 0x5e, 0x6f, 0x93,
|
0x20, 0x0c, 0x03, 0x41, 0x2b, 0x3c, 0x95, 0xba, 0x2a, 0xf7, 0x07, 0x0d, 0x68, 0x4b, 0x4b, 0x79,
|
||||||
0x2b, 0x2a, 0xae, 0x69, 0x14, 0x80, 0xaa, 0xdd, 0xa1, 0xda, 0xf9, 0xa2, 0x96, 0x00, 0xcb, 0xf9,
|
0x77, 0x34, 0x16, 0xd9, 0x7f, 0xe9, 0xef, 0x69, 0x73, 0x61, 0x20, 0xaa, 0xde, 0xf2, 0x10, 0x0d,
|
||||||
0x5c, 0x28, 0x39, 0x9f, 0xef, 0x42, 0x47, 0xb2, 0xa1, 0x79, 0x27, 0xeb, 0x50, 0x08, 0xb8, 0xb5,
|
0xa4, 0xbc, 0xac, 0x73, 0xd5, 0x65, 0xbd, 0x08, 0x2d, 0x14, 0xaf, 0xb7, 0xc9, 0x15, 0x15, 0xd7,
|
||||||
0x26, 0x9e, 0x45, 0xa9, 0xbe, 0xdc, 0x51, 0x5f, 0x2e, 0xbd, 0xec, 0x4b, 0x45, 0x49, 0x87, 0x61,
|
0x34, 0x0a, 0x40, 0xd5, 0xee, 0x50, 0xed, 0x7c, 0x51, 0x4b, 0x80, 0xe5, 0x7c, 0x2e, 0x94, 0x9c,
|
||||||
0x62, 0x6e, 0xee, 0xa7, 0x7e, 0x72, 0xa4, 0x76, 0x9f, 0x91, 0x3e, 0xe1, 0x27, 0x98, 0x6d, 0xc1,
|
0xcf, 0x77, 0xa1, 0x23, 0xd9, 0xd0, 0xbc, 0x93, 0x75, 0x28, 0x04, 0xdc, 0x5a, 0x13, 0xcf, 0xa2,
|
||||||
0x3c, 0x7e, 0xa6, 0xac, 0x75, 0xbd, 0xd2, 0x09, 0x12, 0x76, 0x15, 0xe6, 0xf9, 0x68, 0xcc, 0x55,
|
0x54, 0x5f, 0xee, 0xa8, 0x2f, 0x97, 0x5e, 0xf6, 0xa5, 0xa2, 0xa4, 0xc3, 0x30, 0x31, 0x37, 0xf7,
|
||||||
0xb0, 0xc5, 0xec, 0xb0, 0x17, 0xd7, 0xc8, 0x13, 0x04, 0x68, 0x02, 0x10, 0x2d, 0x99, 0x00, 0xdb,
|
0x53, 0x3f, 0x39, 0x52, 0xbb, 0xcf, 0x48, 0x9f, 0xf0, 0x13, 0xcc, 0xb6, 0x60, 0x1e, 0x3f, 0x53,
|
||||||
0xd2, 0x2f, 0x60, 0xf1, 0xfd, 0x91, 0xbb, 0x01, 0xec, 0xa1, 0x90, 0x5a, 0x33, 0x59, 0xfc, 0x3b,
|
0xd6, 0xba, 0x5e, 0xe9, 0x04, 0x09, 0xbb, 0x0a, 0xf3, 0x7c, 0x34, 0xe6, 0x2a, 0xd8, 0x62, 0x76,
|
||||||
0x73, 0xd0, 0x36, 0x60, 0xd4, 0xe6, 0x31, 0x76, 0x78, 0x30, 0x0a, 0xfc, 0x09, 0xcf, 0x79, 0x2a,
|
0xd8, 0x8b, 0x6b, 0xe4, 0x09, 0x02, 0x34, 0x01, 0x88, 0x96, 0x4c, 0x80, 0x6d, 0xe9, 0x17, 0xb0,
|
||||||
0x25, 0xb5, 0x84, 0x22, 0x9d, 0x7f, 0x3c, 0x1e, 0xc4, 0xd3, 0x7c, 0x30, 0xe2, 0xe3, 0x94, 0x8b,
|
0xf8, 0xfe, 0xc8, 0xdd, 0x00, 0xf6, 0x50, 0x48, 0xad, 0x99, 0x2c, 0xfe, 0x9d, 0x39, 0x68, 0x1b,
|
||||||
0x3d, 0x12, 0x37, 0x03, 0x0b, 0x45, 0xba, 0x89, 0xff, 0xcc, 0xa4, 0x13, 0xf2, 0x50, 0x42, 0x55,
|
0x30, 0x6a, 0xf3, 0x18, 0x3b, 0x3c, 0x18, 0x05, 0xfe, 0x84, 0xe7, 0x3c, 0x95, 0x92, 0x5a, 0x42,
|
||||||
0xea, 0x57, 0xcc, 0x51, 0xb3, 0x48, 0xfd, 0x8a, 0x19, 0x29, 0xdb, 0xa1, 0xf9, 0x1a, 0x3b, 0xf4,
|
0x91, 0xce, 0x3f, 0x1e, 0x0f, 0xe2, 0x69, 0x3e, 0x18, 0xf1, 0x71, 0xca, 0xc5, 0x1e, 0x89, 0x9b,
|
||||||
0x0e, 0x6c, 0x0a, 0x8b, 0x23, 0x75, 0x73, 0x50, 0x12, 0x93, 0x53, 0x6a, 0xd9, 0x16, 0xac, 0x62,
|
0x81, 0x85, 0x22, 0xdd, 0xc4, 0x7f, 0x66, 0xd2, 0x09, 0x79, 0x28, 0xa1, 0x2a, 0xf5, 0x2b, 0xe6,
|
||||||
0x9f, 0x95, 0x80, 0x67, 0xc1, 0xc7, 0x22, 0x19, 0xe3, 0x78, 0x15, 0x1c, 0x69, 0x51, 0x1d, 0x2d,
|
0xa8, 0x59, 0xa4, 0x7e, 0xc5, 0x8c, 0x94, 0xed, 0xd0, 0x7c, 0x8d, 0x1d, 0x7a, 0x07, 0x36, 0x85,
|
||||||
0x5a, 0x71, 0x3c, 0x56, 0xc1, 0x89, 0xd6, 0x7f, 0x66, 0xd3, 0xb6, 0x24, 0x6d, 0x09, 0x77, 0x97,
|
0xc5, 0x91, 0xba, 0x39, 0x28, 0x89, 0xc9, 0x29, 0xb5, 0x6c, 0x0b, 0x56, 0xb1, 0xcf, 0x4a, 0xc0,
|
||||||
0xa1, 0xbd, 0x9f, 0xc7, 0x89, 0x5a, 0x94, 0x2e, 0x74, 0x44, 0x51, 0x1e, 0x86, 0x5e, 0x80, 0xf3,
|
0xb3, 0xe0, 0x63, 0x91, 0x8c, 0x71, 0xbc, 0x0a, 0x8e, 0xb4, 0xa8, 0x8e, 0x16, 0xad, 0x38, 0x1e,
|
||||||
0x24, 0x45, 0x8f, 0xe2, 0x24, 0x0e, 0xe3, 0xf1, 0x6c, 0x7f, 0x7a, 0x90, 0x0d, 0xd3, 0x20, 0xc1,
|
0xab, 0xe0, 0x44, 0xeb, 0x3f, 0xb3, 0x69, 0x5b, 0x92, 0xb6, 0x84, 0xbb, 0xcb, 0xd0, 0xde, 0xcf,
|
||||||
0xc0, 0xc4, 0xfd, 0x3b, 0x07, 0xd6, 0xad, 0x5a, 0x99, 0xbd, 0xf9, 0xbc, 0x10, 0x69, 0x7d, 0x8a,
|
0xe3, 0x44, 0x2d, 0x4a, 0x17, 0x3a, 0xa2, 0x28, 0x0f, 0x43, 0x2f, 0xc0, 0x79, 0x92, 0xa2, 0x47,
|
||||||
0x25, 0x04, 0x6f, 0xcd, 0x30, 0x87, 0x82, 0x50, 0xe4, 0xcd, 0x1e, 0xcb, 0x83, 0xad, 0x9b, 0xb0,
|
0x71, 0x12, 0x87, 0xf1, 0x78, 0xb6, 0x3f, 0x3d, 0xc8, 0x86, 0x69, 0x90, 0x60, 0x60, 0xe2, 0xfe,
|
||||||
0xa2, 0x7a, 0xa6, 0x3e, 0x14, 0x52, 0xd8, 0xab, 0x4a, 0xa1, 0xfc, 0xbe, 0x2b, 0x3f, 0x50, 0x2c,
|
0x9d, 0x03, 0xeb, 0x56, 0xad, 0xcc, 0xde, 0x7c, 0x5e, 0x88, 0xb4, 0x3e, 0xc5, 0x12, 0x82, 0xb7,
|
||||||
0x7e, 0x51, 0xf8, 0xd5, 0x7c, 0x44, 0x63, 0x54, 0x61, 0x7c, 0x5f, 0x7d, 0x6f, 0x3a, 0xf3, 0xaa,
|
0x66, 0x98, 0x43, 0x41, 0x28, 0xf2, 0x66, 0x8f, 0xe5, 0xc1, 0xd6, 0x4d, 0x58, 0x51, 0x3d, 0x53,
|
||||||
0x07, 0x43, 0x0d, 0x66, 0xee, 0xef, 0x3b, 0x00, 0x45, 0xef, 0x50, 0x30, 0x0a, 0x93, 0x2e, 0xee,
|
0x1f, 0x0a, 0x29, 0xec, 0x55, 0xa5, 0x50, 0x7e, 0xdf, 0x95, 0x1f, 0x28, 0x16, 0xbf, 0x28, 0xfc,
|
||||||
0xe7, 0x19, 0xe6, 0xfb, 0x0d, 0xe8, 0xe8, 0x03, 0x8c, 0x62, 0x97, 0x68, 0x2b, 0x0c, 0x1d, 0xae,
|
0x6a, 0x3e, 0xa2, 0x31, 0xaa, 0x30, 0xbe, 0xaf, 0xbe, 0x37, 0x9d, 0x79, 0xd5, 0x83, 0xa1, 0x06,
|
||||||
0x2b, 0xb0, 0x32, 0x0e, 0xe3, 0x03, 0xda, 0x62, 0xe9, 0x74, 0x3d, 0x93, 0x47, 0xc2, 0x5d, 0x01,
|
0x33, 0xf7, 0xf7, 0x1d, 0x80, 0xa2, 0x77, 0x28, 0x18, 0x85, 0x49, 0x17, 0x37, 0xfe, 0x0c, 0xf3,
|
||||||
0xdf, 0x93, 0x68, 0xb1, 0xa5, 0x34, 0x8d, 0x2d, 0xc5, 0xfd, 0x4e, 0x43, 0xa7, 0xbd, 0x8b, 0x31,
|
0xfd, 0x06, 0x74, 0xf4, 0x01, 0x46, 0xb1, 0x4b, 0xb4, 0x15, 0x86, 0x0e, 0xd7, 0x15, 0x58, 0x19,
|
||||||
0x9f, 0xaa, 0x65, 0x6c, 0xa7, 0x62, 0x1c, 0x4f, 0xc9, 0x32, 0x53, 0xc2, 0x6a, 0xef, 0xa5, 0xf1,
|
0x87, 0xf1, 0x01, 0x6d, 0xb1, 0x74, 0xba, 0x9e, 0xc9, 0x23, 0xe1, 0xae, 0x80, 0xef, 0x49, 0xb4,
|
||||||
0xf4, 0x0d, 0xe8, 0xa6, 0xc2, 0xfa, 0x28, 0xd3, 0xd4, 0x7c, 0x81, 0x69, 0x5a, 0x4e, 0xad, 0x7d,
|
0xd8, 0x52, 0x9a, 0xc6, 0x96, 0xe2, 0x7e, 0xa7, 0xa1, 0xd3, 0xde, 0xc5, 0x98, 0x4f, 0xd5, 0x32,
|
||||||
0xe7, 0xff, 0xc1, 0xaa, 0x3f, 0x3a, 0xe6, 0x69, 0x1e, 0x50, 0x44, 0x43, 0x9b, 0xbe, 0x30, 0xa8,
|
0xb6, 0x53, 0x31, 0x8e, 0xa7, 0x64, 0x99, 0x29, 0x61, 0xb5, 0xf7, 0xd2, 0x78, 0xfa, 0x06, 0x74,
|
||||||
0x2b, 0x06, 0x4e, 0x7b, 0xf1, 0x15, 0x58, 0x91, 0xc7, 0xf0, 0x9a, 0x52, 0x5e, 0xbe, 0x2a, 0x60,
|
0x53, 0x61, 0x7d, 0x94, 0x69, 0x6a, 0xbe, 0xc0, 0x34, 0x2d, 0xa7, 0xd6, 0xbe, 0xf3, 0xff, 0x60,
|
||||||
0x24, 0x74, 0xbf, 0xaf, 0x32, 0xec, 0xf6, 0x1a, 0x9e, 0x3e, 0x23, 0xe6, 0xe8, 0x1a, 0xa5, 0xd1,
|
0xd5, 0x1f, 0x1d, 0xf3, 0x34, 0x0f, 0x28, 0xa2, 0xa1, 0x4d, 0x5f, 0x18, 0xd4, 0x15, 0x03, 0xa7,
|
||||||
0x7d, 0x46, 0x66, 0xbb, 0x47, 0x2a, 0x6c, 0x92, 0xe7, 0x0e, 0x02, 0x94, 0xa7, 0x13, 0xf6, 0x94,
|
0xbd, 0xf8, 0x0a, 0xac, 0xc8, 0x63, 0x78, 0x4d, 0x29, 0x2f, 0x5f, 0x15, 0x30, 0x12, 0xba, 0xdf,
|
||||||
0x36, 0x5f, 0x65, 0x4a, 0xdd, 0x4f, 0x1d, 0x58, 0xdc, 0x8d, 0x93, 0x5d, 0x79, 0xa2, 0x4e, 0x8a,
|
0x57, 0x19, 0x76, 0x7b, 0x0d, 0x4f, 0x9f, 0x11, 0x73, 0x74, 0x8d, 0xd2, 0xe8, 0x3e, 0x23, 0xb3,
|
||||||
0xa0, 0x2f, 0xb9, 0xa8, 0xa2, 0xe9, 0x15, 0x37, 0x2a, 0x5e, 0x71, 0x75, 0xaf, 0x5d, 0x2e, 0xef,
|
0xdd, 0x23, 0x15, 0x36, 0xc9, 0x73, 0x07, 0x01, 0xca, 0xd3, 0x09, 0x7b, 0x4a, 0x9b, 0xaf, 0x32,
|
||||||
0xb5, 0xbf, 0x04, 0x17, 0x28, 0x68, 0x4f, 0xe3, 0x24, 0x4e, 0x51, 0x19, 0xfd, 0x50, 0x6c, 0xac,
|
0xa5, 0xee, 0xa7, 0x0e, 0x2c, 0xee, 0xc6, 0xc9, 0xae, 0x3c, 0x51, 0x27, 0x45, 0xd0, 0x97, 0x5c,
|
||||||
0x71, 0x94, 0x1f, 0x29, 0x33, 0xf6, 0x22, 0x12, 0x8a, 0x8e, 0xc2, 0xfc, 0x78, 0x20, 0x9c, 0x61,
|
0x54, 0xd1, 0xf4, 0x8a, 0x1b, 0x15, 0xaf, 0xb8, 0xba, 0xd7, 0x2e, 0x97, 0xf7, 0xda, 0x5f, 0x82,
|
||||||
0xe9, 0x1b, 0x08, 0xeb, 0x56, 0xad, 0x70, 0xbf, 0x08, 0x2d, 0x72, 0x6e, 0x69, 0x58, 0x6f, 0x41,
|
0x0b, 0x14, 0xb4, 0xa7, 0x71, 0x12, 0xa7, 0xa8, 0x8c, 0x7e, 0x28, 0x36, 0xd6, 0x38, 0xca, 0x8f,
|
||||||
0xeb, 0x28, 0x4e, 0x06, 0x47, 0x41, 0x94, 0x2b, 0xe5, 0xee, 0x16, 0x5e, 0xe7, 0x2e, 0x4d, 0x88,
|
0x94, 0x19, 0x7b, 0x11, 0x09, 0x45, 0x47, 0x61, 0x7e, 0x3c, 0x10, 0xce, 0xb0, 0xf4, 0x0d, 0x84,
|
||||||
0x26, 0x70, 0x7f, 0x34, 0x07, 0x8b, 0xef, 0x47, 0xc7, 0x71, 0x30, 0xa4, 0x64, 0xfc, 0x84, 0x4f,
|
0x75, 0xab, 0x56, 0xb8, 0x5f, 0x84, 0x16, 0x39, 0xb7, 0x34, 0xac, 0xb7, 0xa0, 0x75, 0x14, 0x27,
|
||||||
0x62, 0x75, 0xe5, 0x07, 0x7f, 0xe3, 0x54, 0xd0, 0xf1, 0x77, 0x92, 0xcb, 0x6c, 0xba, 0x2a, 0xe2,
|
0x83, 0xa3, 0x20, 0xca, 0x95, 0x72, 0x77, 0x0b, 0xaf, 0x73, 0x97, 0x26, 0x44, 0x13, 0xb8, 0x3f,
|
||||||
0x76, 0x9f, 0x16, 0xd7, 0xe0, 0x84, 0xea, 0x18, 0x08, 0x3a, 0xf6, 0xa9, 0x79, 0x07, 0x50, 0x96,
|
0x9a, 0x83, 0xc5, 0xf7, 0xa3, 0xe3, 0x38, 0x18, 0x52, 0x32, 0x7e, 0xc2, 0x27, 0xb1, 0xba, 0xf2,
|
||||||
0x8a, 0x3b, 0x53, 0xf3, 0xc6, 0x9d, 0x29, 0x3a, 0xba, 0x11, 0x27, 0xfb, 0x24, 0x5f, 0x4b, 0x9e,
|
0x83, 0xbf, 0x71, 0x2a, 0xe8, 0xf8, 0x3b, 0xc9, 0x65, 0x36, 0x5d, 0x15, 0x71, 0xbb, 0x4f, 0x8b,
|
||||||
0x2a, 0x52, 0x20, 0x92, 0x72, 0x91, 0x6c, 0x21, 0xc7, 0x61, 0x51, 0x06, 0x22, 0x26, 0x88, 0xce,
|
0x6b, 0x70, 0x42, 0x75, 0x0c, 0x04, 0x1d, 0xfb, 0xd4, 0xbc, 0x03, 0x28, 0x4b, 0xc5, 0x9d, 0xa9,
|
||||||
0x85, 0xf8, 0x40, 0xd0, 0x08, 0xe3, 0x6b, 0x42, 0xe8, 0x6c, 0x95, 0xaf, 0x11, 0xb6, 0x84, 0xcc,
|
0x79, 0xe3, 0xce, 0x14, 0x1d, 0xdd, 0x88, 0x93, 0x7d, 0x92, 0xaf, 0x25, 0x4f, 0x15, 0x29, 0x10,
|
||||||
0x97, 0x60, 0xb4, 0xd0, 0x23, 0xae, 0x0d, 0xa9, 0x18, 0x03, 0x88, 0x6b, 0x7e, 0x65, 0xdc, 0x08,
|
0x49, 0xb9, 0x48, 0xb6, 0x90, 0xe3, 0xb0, 0x28, 0x03, 0x11, 0x13, 0x44, 0xe7, 0x42, 0x7c, 0x20,
|
||||||
0x5f, 0xc4, 0x0d, 0x05, 0x15, 0xbe, 0xa0, 0xa0, 0xf8, 0x61, 0x78, 0xe0, 0x0f, 0x9f, 0xd2, 0xe5,
|
0x68, 0x84, 0xf1, 0x35, 0x21, 0x74, 0xb6, 0xca, 0xd7, 0x08, 0x5b, 0x42, 0xe6, 0x4b, 0x30, 0x5a,
|
||||||
0x4e, 0xba, 0x90, 0xd0, 0xf2, 0x6c, 0x10, 0x7b, 0x6d, 0xac, 0x26, 0x1d, 0xfe, 0x35, 0x3d, 0x13,
|
0xe8, 0x11, 0xd7, 0x86, 0x54, 0x8c, 0x01, 0xc4, 0x35, 0xbf, 0x32, 0x6e, 0x84, 0x2f, 0xe2, 0x86,
|
||||||
0x62, 0x3b, 0xd0, 0xa6, 0x90, 0x4d, 0xae, 0x67, 0x97, 0xd6, 0x73, 0xd5, 0x8c, 0xe9, 0x68, 0x45,
|
0x82, 0x0a, 0x5f, 0x50, 0x50, 0xfc, 0x30, 0x3c, 0xf0, 0x87, 0x4f, 0xe9, 0x72, 0x27, 0x5d, 0x48,
|
||||||
0x4d, 0x22, 0xf3, 0x80, 0x60, 0xc5, 0xbe, 0x33, 0xf0, 0x0d, 0x60, 0x37, 0x47, 0x23, 0xb9, 0xde,
|
0x68, 0x79, 0x36, 0x88, 0xbd, 0x36, 0x56, 0x93, 0x0e, 0xff, 0x9a, 0x9e, 0x09, 0xb1, 0x1d, 0x68,
|
||||||
0x3a, 0x64, 0x2c, 0x56, 0xca, 0xb1, 0x56, 0xaa, 0x66, 0xc6, 0x1a, 0xb5, 0x33, 0xe6, 0xde, 0x85,
|
0x53, 0xc8, 0x26, 0xd7, 0xb3, 0x4b, 0xeb, 0xb9, 0x6a, 0xc6, 0x74, 0xb4, 0xa2, 0x26, 0x91, 0x79,
|
||||||
0xf6, 0x9e, 0x71, 0xc3, 0x93, 0x44, 0x43, 0xdd, 0xed, 0x94, 0xe2, 0x64, 0x20, 0x46, 0x83, 0x0d,
|
0x40, 0xb0, 0x62, 0xdf, 0x19, 0xf8, 0x06, 0xb0, 0x9b, 0xa3, 0x91, 0x5c, 0x6f, 0x1d, 0x32, 0x16,
|
||||||
0xb3, 0x41, 0xf7, 0xe7, 0x81, 0x3d, 0x08, 0xb2, 0x5c, 0xf7, 0x4f, 0x2c, 0xc7, 0x1b, 0xd0, 0xd1,
|
0x2b, 0xe5, 0x58, 0x2b, 0x55, 0x33, 0x63, 0x8d, 0xda, 0x19, 0x73, 0xef, 0x42, 0x7b, 0xcf, 0xb8,
|
||||||
0x01, 0x76, 0x71, 0xa3, 0xa1, 0x2d, 0x31, 0xba, 0x69, 0x70, 0x53, 0x5c, 0x85, 0x28, 0x0f, 0x6c,
|
0xe1, 0x49, 0xa2, 0xa1, 0xee, 0x76, 0x4a, 0x71, 0x32, 0x10, 0xa3, 0xc1, 0x86, 0xd9, 0xa0, 0xfb,
|
||||||
0x0b, 0x96, 0x02, 0x01, 0x95, 0x35, 0x41, 0x51, 0xea, 0x7a, 0xf4, 0xd7, 0x24, 0x68, 0xed, 0xa2,
|
0xf3, 0xc0, 0x1e, 0x04, 0x59, 0xae, 0xfb, 0x27, 0x96, 0xe3, 0x0d, 0xe8, 0xe8, 0x00, 0xbb, 0xb8,
|
||||||
0x3f, 0x70, 0x60, 0x51, 0x0e, 0x0d, 0xbd, 0x0d, 0xeb, 0x6e, 0xab, 0x18, 0x98, 0x85, 0xd5, 0xdf,
|
0xd1, 0xd0, 0x96, 0x18, 0xdd, 0x34, 0xb8, 0x29, 0xae, 0x42, 0x94, 0x07, 0xb6, 0x05, 0x4b, 0x81,
|
||||||
0x08, 0xac, 0xca, 0xf0, 0x5c, 0x9d, 0x0c, 0x33, 0x68, 0x26, 0x7e, 0x7e, 0x44, 0x01, 0x4a, 0xcb,
|
0x80, 0xca, 0x9a, 0xa0, 0x28, 0x75, 0x3d, 0xfa, 0x6b, 0x12, 0xb4, 0x76, 0xd1, 0x1f, 0x38, 0xb0,
|
||||||
0xa3, 0xdf, 0x6c, 0x55, 0x04, 0xcd, 0x42, 0x57, 0x28, 0x60, 0xae, 0xbb, 0x84, 0x2a, 0x4c, 0x72,
|
0x28, 0x87, 0x86, 0xde, 0x86, 0x75, 0xb7, 0x55, 0x0c, 0xcc, 0xc2, 0xea, 0x6f, 0x04, 0x56, 0x65,
|
||||||
0x05, 0xc7, 0x41, 0xd1, 0xe5, 0x01, 0x81, 0xeb, 0x33, 0x01, 0x79, 0x31, 0xa3, 0x80, 0x8b, 0xf9,
|
0x78, 0xae, 0x4e, 0x86, 0x19, 0x34, 0x13, 0x3f, 0x3f, 0xa2, 0x00, 0xa5, 0xe5, 0xd1, 0x6f, 0xb6,
|
||||||
0x92, 0x2c, 0xca, 0xf3, 0x25, 0x49, 0x3d, 0x5d, 0xef, 0xf6, 0xa1, 0x77, 0x87, 0x87, 0x3c, 0xe7,
|
0x2a, 0x82, 0x66, 0xa1, 0x2b, 0x14, 0x30, 0xd7, 0x5d, 0x42, 0x15, 0x26, 0xb9, 0x82, 0xe3, 0xa0,
|
||||||
0x37, 0xc3, 0xb0, 0xcc, 0xff, 0x02, 0x9c, 0xaf, 0xa9, 0x93, 0x4e, 0xcb, 0x3d, 0x58, 0xbb, 0xc3,
|
0xe8, 0xf2, 0x80, 0xc0, 0xf5, 0x99, 0x80, 0xbc, 0x98, 0x51, 0xc0, 0xc5, 0x7c, 0x49, 0x16, 0xe5,
|
||||||
0x0f, 0xa6, 0xe3, 0x07, 0xfc, 0xb8, 0x38, 0xb8, 0x63, 0xd0, 0xcc, 0x8e, 0xe2, 0x13, 0xb9, 0xb6,
|
0xf9, 0x92, 0xa4, 0x9e, 0xae, 0x77, 0xfb, 0xd0, 0xbb, 0xc3, 0x43, 0x9e, 0xf3, 0x9b, 0x61, 0x58,
|
||||||
0xf4, 0x9b, 0xbd, 0x06, 0x10, 0x22, 0xcd, 0x20, 0x4b, 0xf8, 0x50, 0xdd, 0x85, 0x23, 0x64, 0x3f,
|
0xe6, 0x7f, 0x01, 0xce, 0xd7, 0xd4, 0x49, 0xa7, 0xe5, 0x1e, 0xac, 0xdd, 0xe1, 0x07, 0xd3, 0xf1,
|
||||||
0xe1, 0x43, 0xf7, 0x1d, 0x60, 0x26, 0x1f, 0x39, 0x04, 0xb4, 0x03, 0xd3, 0x83, 0x41, 0x36, 0xcb,
|
0x03, 0x7e, 0x5c, 0x1c, 0xdc, 0x31, 0x68, 0x66, 0x47, 0xf1, 0x89, 0x5c, 0x5b, 0xfa, 0xcd, 0x5e,
|
||||||
0x72, 0x3e, 0x51, 0x97, 0xfc, 0x4c, 0xc8, 0xbd, 0x02, 0x9d, 0x3d, 0x7f, 0xe6, 0xf1, 0x8f, 0xe4,
|
0x03, 0x08, 0x91, 0x66, 0x90, 0x25, 0x7c, 0xa8, 0xee, 0xc2, 0x11, 0xb2, 0x9f, 0xf0, 0xa1, 0xfb,
|
||||||
0xf5, 0x62, 0x8c, 0x8d, 0xfd, 0x19, 0x8a, 0xb2, 0x8e, 0x8d, 0xa9, 0xda, 0xfd, 0x8f, 0x06, 0x2c,
|
0x0e, 0x30, 0x93, 0x8f, 0x1c, 0x02, 0xda, 0x81, 0xe9, 0xc1, 0x20, 0x9b, 0x65, 0x39, 0x9f, 0xa8,
|
||||||
0x08, 0x4a, 0xe4, 0x3a, 0xe2, 0x59, 0x1e, 0x44, 0xe2, 0xd0, 0x4a, 0x72, 0x35, 0xa0, 0x8a, 0x6c,
|
0x4b, 0x7e, 0x26, 0xe4, 0x5e, 0x81, 0xce, 0x9e, 0x3f, 0xf3, 0xf8, 0x47, 0xf2, 0x7a, 0x31, 0xc6,
|
||||||
0x34, 0x6a, 0x64, 0x43, 0x7a, 0xab, 0xea, 0x5e, 0x91, 0x14, 0x02, 0x0b, 0x43, 0xb7, 0xa6, 0xb8,
|
0xc6, 0xfe, 0x0c, 0x45, 0x59, 0xc7, 0xc6, 0x54, 0xed, 0xfe, 0x47, 0x03, 0x16, 0x04, 0x25, 0x72,
|
||||||
0x0c, 0x20, 0x82, 0xb3, 0x02, 0x28, 0x25, 0x4b, 0x0a, 0x6b, 0x23, 0xfa, 0xa7, 0x84, 0x56, 0x8a,
|
0x1d, 0xf1, 0x2c, 0x0f, 0x22, 0x71, 0x68, 0x25, 0xb9, 0x1a, 0x50, 0x45, 0x36, 0x1a, 0x35, 0xb2,
|
||||||
0x83, 0x09, 0xd5, 0xda, 0xb4, 0x45, 0x21, 0x35, 0x15, 0x9b, 0x56, 0xb1, 0x5d, 0x4b, 0xaf, 0x60,
|
0x21, 0xbd, 0x55, 0x75, 0xaf, 0x48, 0x0a, 0x81, 0x85, 0xa1, 0x5b, 0x53, 0x5c, 0x06, 0x10, 0xc1,
|
||||||
0xbb, 0x84, 0x0b, 0xfb, 0x22, 0xdb, 0x05, 0xaf, 0x60, 0xbb, 0x5c, 0x06, 0xab, 0xf7, 0x38, 0xf7,
|
0x59, 0x01, 0x94, 0x92, 0x25, 0x85, 0xb5, 0x11, 0xfd, 0x53, 0x42, 0x2b, 0xc5, 0xc1, 0x84, 0x6a,
|
||||||
0x38, 0xee, 0x8a, 0x4a, 0x9c, 0xbe, 0xeb, 0xc0, 0xaa, 0xdc, 0xd0, 0x75, 0x1d, 0x7b, 0xc3, 0xda,
|
0x6d, 0xda, 0xa2, 0x90, 0x9a, 0x8a, 0x4d, 0xab, 0xd8, 0xae, 0xa5, 0x57, 0xb0, 0x5d, 0xc2, 0x85,
|
||||||
0xfd, 0x9d, 0xba, 0xf3, 0x88, 0x37, 0x61, 0x99, 0xf6, 0x64, 0x9d, 0x15, 0x92, 0x29, 0x2c, 0x0b,
|
0x7d, 0x91, 0xed, 0x82, 0x57, 0xb0, 0x5d, 0x2e, 0x83, 0xd5, 0x7b, 0x9c, 0x7b, 0x1c, 0x77, 0x45,
|
||||||
0xc4, 0x71, 0xa8, 0x0c, 0xfb, 0x24, 0x08, 0xe5, 0xa2, 0x98, 0x90, 0x4a, 0x2c, 0x61, 0x7c, 0x4c,
|
0x25, 0x4e, 0xdf, 0x75, 0x60, 0x55, 0x6e, 0xe8, 0xba, 0x8e, 0xbd, 0x61, 0xed, 0xfe, 0x4e, 0xdd,
|
||||||
0x4b, 0xe2, 0x78, 0xba, 0xec, 0xfe, 0xb5, 0x03, 0x6b, 0x46, 0x87, 0xa5, 0x14, 0xde, 0x00, 0x75,
|
0x79, 0xc4, 0x9b, 0xb0, 0x4c, 0x7b, 0xb2, 0xce, 0x0a, 0xc9, 0x14, 0x96, 0x05, 0xe2, 0x38, 0x54,
|
||||||
0x59, 0x40, 0x24, 0x8f, 0x84, 0x32, 0x9d, 0xb3, 0x9d, 0x93, 0xe2, 0x33, 0x8b, 0x98, 0x16, 0xd3,
|
0x86, 0x7d, 0x12, 0x84, 0x72, 0x51, 0x4c, 0x48, 0x25, 0x96, 0x30, 0x3e, 0xa6, 0x25, 0x71, 0x3c,
|
||||||
0x9f, 0x51, 0x07, 0xb3, 0xe9, 0x44, 0x7a, 0x20, 0x26, 0x84, 0x82, 0x74, 0xc2, 0xf9, 0x53, 0x4d,
|
0x5d, 0x76, 0xff, 0xca, 0x81, 0x35, 0xa3, 0xc3, 0x52, 0x0a, 0x6f, 0x80, 0xba, 0x2c, 0x20, 0x92,
|
||||||
0x32, 0x47, 0x24, 0x16, 0x46, 0x67, 0xc1, 0xe8, 0x4b, 0x68, 0x22, 0x71, 0xfd, 0xc9, 0x06, 0xdd,
|
0x47, 0x42, 0x99, 0xce, 0xd9, 0xce, 0x49, 0xf1, 0x99, 0x45, 0x4c, 0x8b, 0xe9, 0xcf, 0xa8, 0x83,
|
||||||
0x7f, 0x70, 0x60, 0x5d, 0x38, 0x85, 0xd2, 0xe5, 0xd6, 0x57, 0x33, 0x17, 0x84, 0x17, 0x2c, 0x34,
|
0xd9, 0x74, 0x22, 0x3d, 0x10, 0x13, 0x42, 0x41, 0x3a, 0xe1, 0xfc, 0xa9, 0x26, 0x99, 0x23, 0x12,
|
||||||
0x72, 0xf7, 0x8c, 0x27, 0xcb, 0xec, 0x0b, 0xaf, 0xe8, 0xc8, 0xea, 0x3b, 0x00, 0xa7, 0xac, 0xc5,
|
0x0b, 0xa3, 0xb3, 0x60, 0xf4, 0x25, 0x34, 0x91, 0xb8, 0xfe, 0x64, 0x83, 0xee, 0x3f, 0x38, 0xb0,
|
||||||
0x5c, 0xdd, 0x5a, 0xbc, 0x60, 0xa6, 0xeb, 0x92, 0x25, 0xf3, 0xb5, 0xc9, 0x92, 0x5b, 0x8b, 0x30,
|
0x2e, 0x9c, 0x42, 0xe9, 0x72, 0xeb, 0xab, 0x99, 0x0b, 0xc2, 0x0b, 0x16, 0x1a, 0xb9, 0x7b, 0xc6,
|
||||||
0x9f, 0x0d, 0xe3, 0x84, 0xbb, 0x9b, 0xb0, 0x61, 0x0f, 0x4e, 0x9a, 0xa0, 0xef, 0x39, 0xd0, 0xbb,
|
0x93, 0x65, 0xf6, 0x85, 0x57, 0x74, 0x64, 0xf5, 0x1d, 0x80, 0x53, 0xd6, 0x62, 0xae, 0x6e, 0x2d,
|
||||||
0x27, 0x52, 0x87, 0x41, 0x34, 0xde, 0x0d, 0xb2, 0x3c, 0x4e, 0xf5, 0x5d, 0xf4, 0x4b, 0x00, 0x59,
|
0x5e, 0x30, 0xd3, 0x75, 0xc9, 0x92, 0xf9, 0xda, 0x64, 0xc9, 0xad, 0x45, 0x98, 0xcf, 0x86, 0x71,
|
||||||
0xee, 0xa7, 0xb9, 0xb8, 0xa3, 0x25, 0xd3, 0x1c, 0x05, 0x82, 0x7d, 0xe4, 0xd1, 0x48, 0xd4, 0x8a,
|
0xc2, 0xdd, 0x4d, 0xd8, 0xb0, 0x07, 0x27, 0x4d, 0xd0, 0xf7, 0x1c, 0xe8, 0xdd, 0x13, 0xa9, 0xc3,
|
||||||
0xb5, 0xd1, 0x65, 0x5c, 0x18, 0xba, 0x9f, 0x30, 0x88, 0x0f, 0x0f, 0x33, 0xae, 0xdd, 0x56, 0x13,
|
0x20, 0x1a, 0xef, 0x06, 0x59, 0x1e, 0xa7, 0xfa, 0x2e, 0xfa, 0x25, 0x80, 0x2c, 0xf7, 0xd3, 0x5c,
|
||||||
0xc3, 0xc8, 0x17, 0x35, 0x1e, 0x63, 0x3d, 0x7e, 0x4c, 0xa6, 0x56, 0xf8, 0x83, 0x25, 0xd4, 0xfd,
|
0xdc, 0xd1, 0x92, 0x69, 0x8e, 0x02, 0xc1, 0x3e, 0xf2, 0x68, 0x24, 0x6a, 0xc5, 0xda, 0xe8, 0x32,
|
||||||
0x2b, 0x07, 0x56, 0x8a, 0x4e, 0xde, 0x45, 0xd0, 0xb6, 0x0e, 0xa2, 0x6b, 0x86, 0x75, 0x50, 0x09,
|
0x2e, 0x0c, 0xdd, 0x4f, 0x18, 0xc4, 0x87, 0x87, 0x19, 0xd7, 0x6e, 0xab, 0x89, 0x61, 0xe4, 0x8b,
|
||||||
0x98, 0x60, 0x34, 0x08, 0x22, 0xd9, 0x37, 0x03, 0x21, 0x8d, 0x95, 0xa5, 0x78, 0xaa, 0xee, 0xc3,
|
0x1a, 0x8f, 0xb1, 0x1e, 0x3f, 0x26, 0x53, 0x2b, 0xfc, 0xc1, 0x12, 0xea, 0xfe, 0xa5, 0x03, 0x2b,
|
||||||
0x99, 0x90, 0x38, 0xec, 0xce, 0xf1, 0x6b, 0x71, 0x19, 0x4e, 0x96, 0xe8, 0x8a, 0xdd, 0x24, 0xa7,
|
0x45, 0x27, 0xef, 0x22, 0x68, 0x5b, 0x07, 0xd1, 0x35, 0xc3, 0x3a, 0xa8, 0x04, 0x4c, 0x30, 0x1a,
|
||||||
0xaf, 0x16, 0x84, 0x43, 0x2c, 0x8b, 0x6a, 0x7f, 0x5a, 0x24, 0x14, 0x7f, 0xba, 0x7f, 0xe0, 0xc0,
|
0x04, 0x91, 0xec, 0x9b, 0x81, 0x90, 0xc6, 0xca, 0x52, 0x3c, 0x55, 0xf7, 0xe1, 0x4c, 0x48, 0x1c,
|
||||||
0xf9, 0x9a, 0xc9, 0x95, 0x9a, 0x71, 0x07, 0xd6, 0x0e, 0x75, 0xa5, 0x9a, 0x00, 0xa1, 0x1e, 0x9b,
|
0x76, 0xe7, 0xf8, 0xb5, 0xb8, 0x0c, 0x27, 0x4b, 0x74, 0xc5, 0x6e, 0x92, 0xd3, 0x57, 0x0b, 0xc2,
|
||||||
0x52, 0x8a, 0x4a, 0x83, 0xf6, 0xaa, 0x1f, 0xa0, 0x7b, 0x4c, 0x79, 0x23, 0x31, 0xa5, 0xd6, 0x3d,
|
0x21, 0x96, 0x45, 0xb5, 0x3f, 0x2d, 0x12, 0x8a, 0x3f, 0xdd, 0x3f, 0x70, 0xe0, 0x7c, 0xcd, 0xe4,
|
||||||
0x91, 0x6a, 0xc5, 0xce, 0xf7, 0x1b, 0xd0, 0x15, 0x47, 0x15, 0xe2, 0x35, 0x12, 0x4f, 0xd9, 0x07,
|
0x4a, 0xcd, 0xb8, 0x03, 0x6b, 0x87, 0xba, 0x52, 0x4d, 0x80, 0x50, 0x8f, 0x4d, 0x29, 0x45, 0xa5,
|
||||||
0xb0, 0x28, 0xdf, 0x7e, 0xb1, 0xb3, 0xb2, 0x59, 0xfb, 0xb5, 0x59, 0x7f, 0xb3, 0x0c, 0x4b, 0xd9,
|
0x41, 0x7b, 0xd5, 0x0f, 0xd0, 0x3d, 0xa6, 0xbc, 0x91, 0x98, 0x52, 0xeb, 0x9e, 0x48, 0xb5, 0x62,
|
||||||
0x59, 0xff, 0xed, 0x4f, 0xff, 0xf9, 0x0f, 0x1b, 0xcb, 0xac, 0xbd, 0x7d, 0xfc, 0xf6, 0xf6, 0x98,
|
0xe7, 0xfb, 0x0d, 0xe8, 0x8a, 0xa3, 0x0a, 0xf1, 0x1a, 0x89, 0xa7, 0xec, 0x03, 0x58, 0x94, 0xaf,
|
||||||
0x47, 0x19, 0xf2, 0xf8, 0x55, 0x80, 0xe2, 0xf9, 0x14, 0xeb, 0x69, 0x27, 0xa3, 0xf4, 0xdc, 0xab,
|
0xc9, 0xd8, 0x59, 0xd9, 0xac, 0xfd, 0x7e, 0xad, 0xbf, 0x59, 0x86, 0xa5, 0xec, 0xac, 0xff, 0xf6,
|
||||||
0x7f, 0xbe, 0xa6, 0x46, 0xf2, 0x3d, 0x4f, 0x7c, 0xd7, 0xdd, 0x2e, 0xf2, 0x0d, 0xa2, 0x20, 0x17,
|
0xa7, 0xff, 0xfc, 0x87, 0x8d, 0x65, 0xd6, 0xde, 0x3e, 0x7e, 0x7b, 0x7b, 0xcc, 0xa3, 0x0c, 0x79,
|
||||||
0x6f, 0xa9, 0xde, 0x73, 0xb6, 0xd8, 0x08, 0x3a, 0xe6, 0x33, 0x2a, 0xa6, 0x42, 0xe6, 0x9a, 0xb7,
|
0xfc, 0x2a, 0x40, 0xf1, 0xce, 0x8a, 0xf5, 0xb4, 0x93, 0x51, 0x7a, 0x40, 0xd6, 0x3f, 0x5f, 0x53,
|
||||||
0x59, 0xfd, 0x0b, 0xb5, 0x75, 0x2a, 0x5f, 0x40, 0x6d, 0x9c, 0x75, 0x57, 0xb1, 0x8d, 0x29, 0x51,
|
0x23, 0xf9, 0x9e, 0x27, 0xbe, 0xeb, 0x6e, 0x17, 0xf9, 0x06, 0x51, 0x90, 0x8b, 0x47, 0x57, 0xef,
|
||||||
0xe8, 0x56, 0x76, 0xfe, 0xf1, 0x02, 0xb4, 0x74, 0xda, 0x89, 0x7d, 0x08, 0xcb, 0xd6, 0xe9, 0x0e,
|
0x39, 0x5b, 0x6c, 0x04, 0x1d, 0xf3, 0x19, 0x15, 0x53, 0x21, 0x73, 0xcd, 0x23, 0xae, 0xfe, 0x85,
|
||||||
0x53, 0x8c, 0xeb, 0x0e, 0x83, 0xfa, 0x17, 0xeb, 0x2b, 0x65, 0xb3, 0x97, 0xa8, 0xd9, 0x1e, 0xdb,
|
0xda, 0x3a, 0x95, 0x2f, 0xa0, 0x36, 0xce, 0xba, 0xab, 0xd8, 0xc6, 0x94, 0x28, 0x74, 0x2b, 0x3b,
|
||||||
0xc4, 0x66, 0xe5, 0xf1, 0xc8, 0x36, 0x9d, 0x69, 0x89, 0x2b, 0x75, 0x4f, 0xa1, 0x6b, 0x9f, 0xc8,
|
0xff, 0x78, 0x01, 0x5a, 0x3a, 0xed, 0xc4, 0x3e, 0x84, 0x65, 0xeb, 0x74, 0x87, 0x29, 0xc6, 0x75,
|
||||||
0xb0, 0x8b, 0xb6, 0x41, 0x29, 0xb5, 0xf6, 0xda, 0x29, 0xb5, 0xb2, 0xb9, 0x8b, 0xd4, 0xdc, 0x26,
|
0x87, 0x41, 0xfd, 0x8b, 0xf5, 0x95, 0xb2, 0xd9, 0x4b, 0xd4, 0x6c, 0x8f, 0x6d, 0x62, 0xb3, 0xf2,
|
||||||
0xdb, 0x30, 0x9b, 0xd3, 0xe9, 0x20, 0x4e, 0x97, 0x20, 0xcd, 0xf7, 0x55, 0xec, 0x35, 0xbd, 0xd4,
|
0x78, 0x64, 0x9b, 0xce, 0xb4, 0xc4, 0x95, 0xba, 0xa7, 0xd0, 0xb5, 0x4f, 0x64, 0xd8, 0x45, 0xdb,
|
||||||
0x75, 0xef, 0xae, 0xf4, 0xa2, 0x55, 0x1f, 0x5f, 0xb9, 0x3d, 0x6a, 0x8a, 0x31, 0x9a, 0x50, 0xf3,
|
0xa0, 0x94, 0x5a, 0x7b, 0xed, 0x94, 0x5a, 0xd9, 0xdc, 0x45, 0x6a, 0x6e, 0x93, 0x6d, 0x98, 0xcd,
|
||||||
0x79, 0x15, 0xfb, 0x16, 0xb4, 0xf4, 0x9b, 0x0a, 0x76, 0xce, 0x78, 0xc8, 0x62, 0x3e, 0xf4, 0xe8,
|
0xe9, 0x74, 0x10, 0xa7, 0x4b, 0x90, 0xe6, 0xfb, 0x2a, 0xf6, 0x9a, 0x5e, 0xea, 0xba, 0x77, 0x57,
|
||||||
0xf7, 0xaa, 0x15, 0x75, 0x4b, 0x65, 0x72, 0x46, 0x81, 0x78, 0x00, 0x67, 0xa5, 0x93, 0x7a, 0xc0,
|
0x7a, 0xd1, 0xaa, 0x8f, 0xaf, 0xdc, 0x1e, 0x35, 0xc5, 0x18, 0x4d, 0xa8, 0xf9, 0xbc, 0x8a, 0x7d,
|
||||||
0x7f, 0x9c, 0x91, 0xd4, 0xbc, 0x0a, 0xbb, 0xee, 0xb0, 0x1b, 0xb0, 0xa4, 0x9e, 0xaa, 0xb0, 0xcd,
|
0x0b, 0x5a, 0xfa, 0x4d, 0x05, 0x3b, 0x67, 0x3c, 0x64, 0x31, 0x1f, 0x7a, 0xf4, 0x7b, 0xd5, 0x8a,
|
||||||
0xfa, 0x27, 0x37, 0xfd, 0x73, 0x15, 0x5c, 0xea, 0xf3, 0x4d, 0x80, 0xe2, 0x99, 0x85, 0x96, 0xfc,
|
0xba, 0xa5, 0x32, 0x39, 0xa3, 0x40, 0x3c, 0x80, 0xb3, 0xd2, 0x49, 0x3d, 0xe0, 0x3f, 0xce, 0x48,
|
||||||
0xca, 0xe3, 0x0f, 0x3d, 0x89, 0x35, 0x6f, 0x32, 0xc6, 0xf4, 0xa8, 0xc4, 0x7e, 0xc5, 0xc1, 0x5e,
|
0x6a, 0x5e, 0x85, 0x5d, 0x77, 0xd8, 0x0d, 0x58, 0x52, 0x4f, 0x55, 0xd8, 0x66, 0xfd, 0x93, 0x9b,
|
||||||
0x2f, 0xe8, 0x6b, 0xdf, 0x77, 0xbc, 0x80, 0xa1, 0xbb, 0x49, 0x73, 0xb7, 0xca, 0x48, 0x95, 0x22,
|
0xfe, 0xb9, 0x0a, 0x2e, 0xf5, 0xf9, 0x26, 0x40, 0xf1, 0xcc, 0x42, 0x4b, 0x7e, 0xe5, 0xf1, 0x87,
|
||||||
0x7e, 0xa2, 0xae, 0x03, 0xdf, 0x81, 0xb6, 0xf1, 0x74, 0x83, 0x29, 0x0e, 0xd5, 0x67, 0x1f, 0xfd,
|
0x9e, 0xc4, 0x9a, 0x37, 0x19, 0x63, 0x7a, 0x54, 0x62, 0xbf, 0xe2, 0x60, 0xaf, 0x17, 0xf4, 0xb5,
|
||||||
0x7e, 0x5d, 0x95, 0xec, 0xee, 0x57, 0x60, 0xd9, 0x7a, 0x83, 0xa1, 0x35, 0xa3, 0xee, 0x85, 0x87,
|
0xef, 0x3b, 0x5e, 0xc0, 0xd0, 0xdd, 0xa4, 0xb9, 0x5b, 0x65, 0xa4, 0x4a, 0x11, 0x3f, 0x51, 0xd7,
|
||||||
0xd6, 0x8c, 0xfa, 0x67, 0x1b, 0xdf, 0x84, 0xb6, 0xf1, 0x62, 0x82, 0x19, 0xd7, 0xa0, 0x4a, 0x6f,
|
0x81, 0xef, 0x40, 0xdb, 0x78, 0xba, 0xc1, 0x14, 0x87, 0xea, 0xb3, 0x8f, 0x7e, 0xbf, 0xae, 0x4a,
|
||||||
0x25, 0x74, 0x8f, 0xea, 0x1e, 0x58, 0x6c, 0xd0, 0x78, 0xbb, 0x6e, 0x0b, 0xc7, 0x4b, 0x77, 0x62,
|
0x76, 0xf7, 0x2b, 0xb0, 0x6c, 0xbd, 0xc1, 0xd0, 0x9a, 0x51, 0xf7, 0xc2, 0x43, 0x6b, 0x46, 0xfd,
|
||||||
0x51, 0x48, 0x3e, 0x84, 0xae, 0xfd, 0x86, 0x42, 0x6b, 0x55, 0xed, 0x6b, 0x0c, 0xad, 0x55, 0xa7,
|
0xb3, 0x8d, 0x6f, 0x42, 0xdb, 0x78, 0x31, 0xc1, 0x8c, 0x6b, 0x50, 0xa5, 0xb7, 0x12, 0xba, 0x47,
|
||||||
0x3c, 0xbc, 0x90, 0x02, 0xb9, 0xb5, 0xae, 0x1b, 0xd9, 0xfe, 0x44, 0x1e, 0xba, 0x3c, 0x67, 0x5f,
|
0x75, 0x0f, 0x2c, 0x36, 0x68, 0xbc, 0x5d, 0xb7, 0x85, 0xe3, 0xa5, 0x3b, 0xb1, 0x28, 0x24, 0x1f,
|
||||||
0x47, 0xd3, 0x21, 0x2f, 0x29, 0xb3, 0xe2, 0xe5, 0x88, 0x7d, 0x95, 0x59, 0x4b, 0x7b, 0xe5, 0x3e,
|
0x42, 0xd7, 0x7e, 0x43, 0xa1, 0xb5, 0xaa, 0xf6, 0x35, 0x86, 0xd6, 0xaa, 0x53, 0x1e, 0x5e, 0x48,
|
||||||
0xb3, 0xbb, 0x46, 0xcc, 0xdb, 0xac, 0x18, 0x81, 0xb0, 0xd0, 0x74, 0x59, 0xd9, 0xb0, 0xd0, 0xe6,
|
0x81, 0xdc, 0x5a, 0xd7, 0x8d, 0x6c, 0x7f, 0x22, 0x0f, 0x5d, 0x9e, 0xb3, 0xaf, 0xa3, 0xe9, 0x90,
|
||||||
0x7d, 0x66, 0xc3, 0x42, 0x5b, 0x77, 0x9a, 0xcb, 0x16, 0x3a, 0x0f, 0x90, 0x47, 0x04, 0x2b, 0xa5,
|
0x97, 0x94, 0x59, 0xf1, 0x72, 0xc4, 0xbe, 0xca, 0xac, 0xa5, 0xbd, 0x72, 0x9f, 0xd9, 0x5d, 0x23,
|
||||||
0x7b, 0x00, 0x5a, 0x59, 0xea, 0x2f, 0x4e, 0xf5, 0x2f, 0xbd, 0xf8, 0xfa, 0x80, 0x6d, 0x66, 0x94,
|
0xe6, 0x6d, 0x56, 0x8c, 0x40, 0x58, 0x68, 0xba, 0xac, 0x6c, 0x58, 0x68, 0xf3, 0x3e, 0xb3, 0x61,
|
||||||
0x79, 0xd9, 0x56, 0xf7, 0xdc, 0x7e, 0x0d, 0x3a, 0xe6, 0xdd, 0x77, 0x6d, 0xb3, 0x6b, 0x6e, 0xec,
|
0xa1, 0xad, 0x3b, 0xcd, 0x65, 0x0b, 0x9d, 0x07, 0xc8, 0x23, 0x82, 0x95, 0xd2, 0x3d, 0x00, 0xad,
|
||||||
0x6b, 0x9b, 0x5d, 0x77, 0x59, 0x5e, 0x2d, 0x2e, 0xeb, 0x98, 0xcd, 0xb0, 0x6f, 0xc2, 0x8a, 0x71,
|
0x2c, 0xf5, 0x17, 0xa7, 0xfa, 0x97, 0x5e, 0x7c, 0x7d, 0xc0, 0x36, 0x33, 0xca, 0xbc, 0x6c, 0xab,
|
||||||
0xf1, 0x65, 0x7f, 0x16, 0x0d, 0xb5, 0xf0, 0x54, 0xaf, 0x45, 0xf6, 0xeb, 0xfc, 0x33, 0xf7, 0x1c,
|
0x7b, 0x6e, 0xbf, 0x06, 0x1d, 0xf3, 0xee, 0xbb, 0xb6, 0xd9, 0x35, 0x37, 0xf6, 0xb5, 0xcd, 0xae,
|
||||||
0x31, 0x5e, 0x73, 0x2d, 0xc6, 0x28, 0x38, 0xb7, 0xa1, 0x6d, 0x5e, 0xaa, 0x79, 0x01, 0xdf, 0x73,
|
0xbb, 0x2c, 0xaf, 0x16, 0x97, 0x75, 0xcc, 0x66, 0xd8, 0x37, 0x61, 0xc5, 0xb8, 0xf8, 0xb2, 0x3f,
|
||||||
0x46, 0x95, 0x79, 0x43, 0xf0, 0xba, 0xc3, 0xfe, 0xd8, 0x81, 0x8e, 0x75, 0x45, 0xc5, 0xca, 0xf3,
|
0x8b, 0x86, 0x5a, 0x78, 0xaa, 0xd7, 0x22, 0xfb, 0x75, 0xfe, 0x99, 0x7b, 0x8e, 0x18, 0xaf, 0xb9,
|
||||||
0x96, 0xf8, 0xf4, 0xcc, 0x3a, 0x93, 0x91, 0xeb, 0x51, 0x27, 0x1f, 0x6c, 0x7d, 0xc5, 0x9a, 0xe4,
|
0x16, 0x63, 0x14, 0x9c, 0xdb, 0xd0, 0x36, 0x2f, 0xd5, 0xbc, 0x80, 0xef, 0x39, 0xa3, 0xca, 0xbc,
|
||||||
0x4f, 0x2c, 0x3f, 0xff, 0x5a, 0xf9, 0x59, 0xe3, 0xf3, 0x32, 0x81, 0x79, 0x75, 0xf4, 0xf9, 0x75,
|
0x21, 0x78, 0xdd, 0x61, 0x7f, 0xec, 0x40, 0xc7, 0xba, 0xa2, 0x62, 0xe5, 0x79, 0x4b, 0x7c, 0x7a,
|
||||||
0x87, 0xbd, 0x27, 0x9e, 0xbe, 0xaa, 0xb8, 0x9e, 0x19, 0xc6, 0xad, 0x3c, 0x65, 0xe6, 0x2b, 0xd1,
|
0x66, 0x9d, 0xc9, 0xc8, 0xf5, 0xa8, 0x93, 0x0f, 0xb6, 0xbe, 0x62, 0x4d, 0xf2, 0x27, 0x96, 0x9f,
|
||||||
0xab, 0xce, 0x75, 0x87, 0x7d, 0x5b, 0xbc, 0x5e, 0x94, 0xdf, 0xd2, 0xcc, 0xbf, 0xea, 0xf7, 0xee,
|
0x7f, 0xad, 0xfc, 0xac, 0xf1, 0x79, 0x99, 0xc0, 0xbc, 0x3a, 0xfa, 0xfc, 0xba, 0xc3, 0xde, 0x13,
|
||||||
0x9b, 0x34, 0x9a, 0x4b, 0xee, 0x79, 0x6b, 0x34, 0x65, 0xeb, 0xbe, 0x07, 0x50, 0x24, 0x69, 0x58,
|
0x4f, 0x5f, 0x55, 0x5c, 0xcf, 0x0c, 0xe3, 0x56, 0x9e, 0x32, 0xf3, 0x95, 0xe8, 0x55, 0xe7, 0xba,
|
||||||
0x29, 0x63, 0xa1, 0xed, 0x5e, 0x35, 0x8f, 0x63, 0xaf, 0xa8, 0x4a, 0x6c, 0x20, 0xc7, 0x6f, 0x09,
|
0xc3, 0xbe, 0x2d, 0x5e, 0x2f, 0xca, 0x6f, 0x69, 0xe6, 0x5f, 0xf5, 0x7b, 0xf7, 0x4d, 0x1a, 0xcd,
|
||||||
0x61, 0x94, 0xf4, 0x99, 0x5e, 0xd2, 0x6a, 0xb2, 0xa5, 0xdf, 0xaf, 0xab, 0xaa, 0x13, 0x45, 0xc5,
|
0x25, 0xf7, 0xbc, 0x35, 0x9a, 0xb2, 0x75, 0xdf, 0x03, 0x28, 0x92, 0x34, 0xac, 0x94, 0xb1, 0xd0,
|
||||||
0x9f, 0x3d, 0x86, 0xe5, 0x07, 0x71, 0xfc, 0x74, 0x9a, 0xe8, 0x34, 0xa2, 0x9d, 0x33, 0xd8, 0xf5,
|
0x76, 0xaf, 0x9a, 0xc7, 0xb1, 0x57, 0x54, 0x25, 0x36, 0x90, 0xe3, 0xb7, 0x84, 0x30, 0x4a, 0xfa,
|
||||||
0xb3, 0xa3, 0x7e, 0x69, 0x14, 0xee, 0x65, 0x62, 0xd5, 0x67, 0x3d, 0x83, 0xd5, 0xf6, 0x27, 0x45,
|
0x4c, 0x2f, 0x69, 0x35, 0xd9, 0xd2, 0xef, 0xd7, 0x55, 0xd5, 0x89, 0xa2, 0xe2, 0xcf, 0x1e, 0xc3,
|
||||||
0x8a, 0xe8, 0x39, 0xf3, 0x61, 0x4d, 0xef, 0x71, 0xba, 0xe3, 0x7d, 0x9b, 0x8d, 0x99, 0xa9, 0xa9,
|
0xf2, 0x83, 0x38, 0x7e, 0x3a, 0x4d, 0x74, 0x1a, 0xd1, 0xce, 0x19, 0xec, 0xfa, 0xd9, 0x51, 0xbf,
|
||||||
0x34, 0x61, 0x79, 0x1d, 0xaa, 0xb7, 0xdb, 0x99, 0xe2, 0x79, 0xdd, 0x61, 0x7b, 0xd0, 0xb9, 0xc3,
|
0x34, 0x0a, 0xf7, 0x32, 0xb1, 0xea, 0xb3, 0x9e, 0xc1, 0x6a, 0xfb, 0x93, 0x22, 0x45, 0xf4, 0x9c,
|
||||||
0x87, 0xf1, 0x88, 0xcb, 0x28, 0x7f, 0xbd, 0xe8, 0xb8, 0x4e, 0x0f, 0xf4, 0x97, 0x2d, 0xd0, 0xd6,
|
0xf9, 0xb0, 0xa6, 0xf7, 0x38, 0xdd, 0xf1, 0xbe, 0xcd, 0xc6, 0xcc, 0xd4, 0x54, 0x9a, 0xb0, 0xbc,
|
||||||
0xfa, 0xc4, 0x9f, 0xa5, 0xfc, 0xa3, 0xed, 0x4f, 0x64, 0xfe, 0xe0, 0xb9, 0xd2, 0x7a, 0x95, 0xf3,
|
0x0e, 0xd5, 0xdb, 0xed, 0x4c, 0xf1, 0xbc, 0xee, 0xb0, 0x3d, 0xe8, 0xdc, 0xe1, 0xc3, 0x78, 0xc4,
|
||||||
0xb0, 0xb4, 0xbe, 0x94, 0x24, 0xb1, 0xb4, 0xbe, 0x92, 0x24, 0xb1, 0xa6, 0x5a, 0xe5, 0x5c, 0x58,
|
0x65, 0x94, 0xbf, 0x5e, 0x74, 0x5c, 0xa7, 0x07, 0xfa, 0xcb, 0x16, 0x68, 0x6b, 0x7d, 0xe2, 0xcf,
|
||||||
0x08, 0x6b, 0x95, 0xbc, 0x8a, 0xde, 0x29, 0x4f, 0xcb, 0xc6, 0xf4, 0x2f, 0x9f, 0x4e, 0x60, 0xb7,
|
0x52, 0xfe, 0xd1, 0xf6, 0x27, 0x32, 0x7f, 0xf0, 0x5c, 0x69, 0xbd, 0xca, 0x79, 0x58, 0x5a, 0x5f,
|
||||||
0xb6, 0x65, 0xb7, 0xb6, 0x0f, 0xcb, 0x77, 0xb8, 0x98, 0x2c, 0x71, 0x56, 0xd9, 0xb7, 0xcd, 0x88,
|
0x4a, 0x92, 0x58, 0x5a, 0x5f, 0x49, 0x92, 0x58, 0x53, 0xad, 0x72, 0x2e, 0x2c, 0x84, 0xb5, 0x4a,
|
||||||
0x79, 0xae, 0x59, 0x36, 0x31, 0x54, 0x67, 0x9b, 0x75, 0x3a, 0x28, 0x64, 0xdf, 0x82, 0xf6, 0x7d,
|
0x5e, 0x45, 0xef, 0x94, 0xa7, 0x65, 0x63, 0xfa, 0x97, 0x4f, 0x27, 0xb0, 0x5b, 0xdb, 0xb2, 0x5b,
|
||||||
0x9e, 0xab, 0xc3, 0x49, 0xed, 0x6f, 0x94, 0x4e, 0x2b, 0xfb, 0x35, 0x67, 0x9b, 0xb6, 0xcc, 0x10,
|
0xdb, 0x87, 0xe5, 0x3b, 0x5c, 0x4c, 0x96, 0x38, 0xab, 0xec, 0xdb, 0x66, 0xc4, 0x3c, 0xd7, 0x2c,
|
||||||
0xb7, 0x6d, 0x3e, 0x1a, 0x73, 0xa1, 0xec, 0x83, 0x60, 0xf4, 0x9c, 0xfd, 0x32, 0x31, 0xd7, 0xf7,
|
0x9b, 0x18, 0xaa, 0xb3, 0xcd, 0x3a, 0x1d, 0x14, 0xb2, 0x6f, 0x41, 0xfb, 0x3e, 0xcf, 0xd5, 0xe1,
|
||||||
0x19, 0x36, 0x8d, 0x33, 0x2d, 0x93, 0xf9, 0x4a, 0x09, 0xaf, 0xe3, 0x1c, 0xc5, 0x23, 0x6e, 0x6c,
|
0xa4, 0xf6, 0x37, 0x4a, 0xa7, 0x95, 0xfd, 0x9a, 0xb3, 0x4d, 0x5b, 0x66, 0x88, 0xdb, 0x36, 0x1f,
|
||||||
0x70, 0x11, 0xb4, 0x8d, 0xcb, 0x36, 0x5a, 0x81, 0xaa, 0x17, 0x7c, 0xb4, 0x02, 0xd5, 0xdc, 0xcd,
|
0x8d, 0xb9, 0x50, 0xf6, 0x41, 0x30, 0x7a, 0xce, 0x7e, 0x99, 0x98, 0xeb, 0xfb, 0x0c, 0x9b, 0xc6,
|
||||||
0x71, 0xaf, 0x52, 0x3b, 0x2e, 0xbb, 0x5c, 0xb4, 0x23, 0xee, 0xe3, 0x14, 0x2d, 0x6d, 0x7f, 0xe2,
|
0x99, 0x96, 0xc9, 0x7c, 0xa5, 0x84, 0xd7, 0x71, 0x8e, 0xe2, 0x11, 0x37, 0x36, 0xb8, 0x08, 0xda,
|
||||||
0x4f, 0xf2, 0xe7, 0xec, 0x09, 0xbd, 0xde, 0x31, 0x0f, 0x60, 0x0b, 0x7f, 0xa7, 0x7c, 0x56, 0xab,
|
0xc6, 0x65, 0x1b, 0xad, 0x40, 0xd5, 0x0b, 0x3e, 0x5a, 0x81, 0x6a, 0xee, 0xe6, 0xb8, 0x57, 0xa9,
|
||||||
0x27, 0xcb, 0xa8, 0xb2, 0x7d, 0x20, 0xd1, 0x14, 0xed, 0x83, 0x5f, 0x00, 0xd8, 0xcf, 0xe3, 0xe4,
|
0x1d, 0x97, 0x5d, 0x2e, 0xda, 0x11, 0xf7, 0x71, 0x8a, 0x96, 0xb6, 0x3f, 0xf1, 0x27, 0xf9, 0x73,
|
||||||
0x8e, 0xcf, 0x27, 0x71, 0x54, 0x58, 0xae, 0xe2, 0x90, 0xb1, 0xb0, 0x5c, 0xc6, 0x49, 0x23, 0x7b,
|
0xf6, 0x84, 0x5e, 0xef, 0x98, 0x07, 0xb0, 0x85, 0xbf, 0x53, 0x3e, 0xab, 0xd5, 0x93, 0x65, 0x54,
|
||||||
0x62, 0x78, 0x9c, 0xd6, 0xf9, 0xb5, 0x12, 0xae, 0x53, 0xcf, 0x21, 0xf5, 0x84, 0xd4, 0x9c, 0x45,
|
0xd9, 0x3e, 0x90, 0x68, 0x8a, 0xf6, 0xc1, 0x2f, 0x00, 0xec, 0xe7, 0x71, 0x72, 0xc7, 0xe7, 0x93,
|
||||||
0x5e, 0x77, 0xd0, 0x7f, 0x2c, 0xb2, 0x78, 0xda, 0x7f, 0xac, 0x24, 0x08, 0xb5, 0xd9, 0xab, 0x49,
|
0x38, 0x2a, 0x2c, 0x57, 0x71, 0xc8, 0x58, 0x58, 0x2e, 0xe3, 0xa4, 0x91, 0x3d, 0x31, 0x3c, 0x4e,
|
||||||
0xf9, 0xed, 0x41, 0xab, 0x48, 0x0b, 0xa9, 0x2d, 0xa9, 0x9c, 0x44, 0xd2, 0x7b, 0x4c, 0x25, 0x59,
|
0xeb, 0xfc, 0x5a, 0x09, 0xd7, 0xa9, 0xe7, 0x90, 0x7a, 0x42, 0x6a, 0xce, 0x22, 0xaf, 0x3b, 0xe8,
|
||||||
0xe3, 0xae, 0xd2, 0x54, 0x01, 0x5b, 0xc2, 0xa9, 0xa2, 0x0c, 0x4c, 0x00, 0xeb, 0xa2, 0x83, 0x7a,
|
0x3f, 0x16, 0x59, 0x3c, 0xed, 0x3f, 0x56, 0x12, 0x84, 0xda, 0xec, 0xd5, 0xa4, 0xfc, 0xf6, 0xa0,
|
||||||
0xc3, 0xa4, 0x63, 0x33, 0x35, 0x92, 0x9a, 0x84, 0x89, 0xd6, 0xe6, 0xda, 0x7c, 0x83, 0x15, 0xdb,
|
0x55, 0xa4, 0x85, 0xd4, 0x96, 0x54, 0x4e, 0x22, 0xe9, 0x3d, 0xa6, 0x92, 0xac, 0x71, 0x57, 0x69,
|
||||||
0xa1, 0xb4, 0x8a, 0x23, 0x3b, 0x34, 0xcd, 0x13, 0x58, 0xab, 0x04, 0xcb, 0x5a, 0xa5, 0x4f, 0xcb,
|
0xaa, 0x80, 0x2d, 0xe1, 0x54, 0x51, 0x06, 0x26, 0x80, 0x75, 0xd1, 0x41, 0xbd, 0x61, 0xd2, 0xb1,
|
||||||
0x51, 0x68, 0x95, 0x3e, 0x35, 0xce, 0x76, 0xcf, 0x52, 0x93, 0x2b, 0x2e, 0x60, 0x93, 0xd9, 0x49,
|
0x99, 0x1a, 0x49, 0x4d, 0xc2, 0x44, 0x6b, 0x73, 0x6d, 0xbe, 0xc1, 0x8a, 0xed, 0x50, 0x5a, 0xc5,
|
||||||
0x90, 0x0f, 0x8f, 0xde, 0x73, 0xb6, 0x0e, 0x16, 0xe8, 0xcf, 0x55, 0x3e, 0xf7, 0x3f, 0x01, 0x00,
|
0x91, 0x1d, 0x9a, 0xe6, 0x09, 0xac, 0x55, 0x82, 0x65, 0xad, 0xd2, 0xa7, 0xe5, 0x28, 0xb4, 0x4a,
|
||||||
0x00, 0xff, 0xff, 0x8f, 0xec, 0x5b, 0xef, 0x8e, 0x45, 0x00, 0x00,
|
0x9f, 0x1a, 0x67, 0xbb, 0x67, 0xa9, 0xc9, 0x15, 0x17, 0xb0, 0xc9, 0xec, 0x24, 0xc8, 0x87, 0x47,
|
||||||
|
0xef, 0x39, 0x5b, 0x07, 0x0b, 0xf4, 0x77, 0x2d, 0x9f, 0xfb, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||||
|
0x5c, 0x78, 0xf8, 0x82, 0xe0, 0x45, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
@ -592,7 +592,15 @@ func RegisterWalletUnlockerHandlerFromEndpoint(ctx context.Context, mux *runtime
|
|||||||
// RegisterWalletUnlockerHandler registers the http handlers for service WalletUnlocker to "mux".
|
// RegisterWalletUnlockerHandler registers the http handlers for service WalletUnlocker to "mux".
|
||||||
// The handlers forward requests to the grpc endpoint over "conn".
|
// The handlers forward requests to the grpc endpoint over "conn".
|
||||||
func RegisterWalletUnlockerHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
func RegisterWalletUnlockerHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||||
client := NewWalletUnlockerClient(conn)
|
return RegisterWalletUnlockerHandlerClient(ctx, mux, NewWalletUnlockerClient(conn))
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterWalletUnlockerHandler registers the http handlers for service WalletUnlocker to "mux".
|
||||||
|
// The handlers forward requests to the grpc endpoint over the given implementation of "WalletUnlockerClient".
|
||||||
|
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "WalletUnlockerClient"
|
||||||
|
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||||
|
// "WalletUnlockerClient" to call the correct interceptors.
|
||||||
|
func RegisterWalletUnlockerHandlerClient(ctx context.Context, mux *runtime.ServeMux, client WalletUnlockerClient) error {
|
||||||
|
|
||||||
mux.Handle("GET", pattern_WalletUnlocker_GenSeed_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle("GET", pattern_WalletUnlocker_GenSeed_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
@ -728,7 +736,15 @@ func RegisterLightningHandlerFromEndpoint(ctx context.Context, mux *runtime.Serv
|
|||||||
// RegisterLightningHandler registers the http handlers for service Lightning to "mux".
|
// RegisterLightningHandler registers the http handlers for service Lightning to "mux".
|
||||||
// The handlers forward requests to the grpc endpoint over "conn".
|
// The handlers forward requests to the grpc endpoint over "conn".
|
||||||
func RegisterLightningHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
func RegisterLightningHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||||
client := NewLightningClient(conn)
|
return RegisterLightningHandlerClient(ctx, mux, NewLightningClient(conn))
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterLightningHandler registers the http handlers for service Lightning to "mux".
|
||||||
|
// The handlers forward requests to the grpc endpoint over the given implementation of "LightningClient".
|
||||||
|
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "LightningClient"
|
||||||
|
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||||
|
// "LightningClient" to call the correct interceptors.
|
||||||
|
func RegisterLightningHandlerClient(ctx context.Context, mux *runtime.ServeMux, client LightningClient) error {
|
||||||
|
|
||||||
mux.Handle("GET", pattern_Lightning_WalletBalance_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle("GET", pattern_Lightning_WalletBalance_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
@ -127,6 +127,15 @@ message InitWalletRequest {
|
|||||||
to encrypt the generated aezeed cipher seed.
|
to encrypt the generated aezeed cipher seed.
|
||||||
*/
|
*/
|
||||||
bytes aezeed_passphrase = 3;
|
bytes aezeed_passphrase = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
recovery_window is an optional argument specifying the address lookahead
|
||||||
|
when restoring a wallet seed. The recovery window applies to each
|
||||||
|
invdividual branch of the BIP44 derivation paths. Supplying a recovery
|
||||||
|
window of zero indicates that no addresses should be recovered, such after
|
||||||
|
the first initialization of the wallet.
|
||||||
|
*/
|
||||||
|
int32 recovery_window = 4;
|
||||||
}
|
}
|
||||||
message InitWalletResponse {
|
message InitWalletResponse {
|
||||||
}
|
}
|
||||||
@ -138,6 +147,15 @@ message UnlockWalletRequest {
|
|||||||
function properly.
|
function properly.
|
||||||
*/
|
*/
|
||||||
bytes wallet_password = 1;
|
bytes wallet_password = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
recovery_window is an optional argument specifying the address lookahead
|
||||||
|
when restoring a wallet seed. The recovery window applies to each
|
||||||
|
invdividual branch of the BIP44 derivation paths. Supplying a recovery
|
||||||
|
window of zero indicates that no addresses should be recovered, such after
|
||||||
|
the first initialization of the wallet.
|
||||||
|
*/
|
||||||
|
int32 recovery_window = 2;
|
||||||
}
|
}
|
||||||
message UnlockWalletResponse {}
|
message UnlockWalletResponse {}
|
||||||
|
|
||||||
|
@ -1569,6 +1569,11 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "byte",
|
"format": "byte",
|
||||||
"description": "*\naezeed_passphrase is an optional user provided passphrase that will be used\nto encrypt the generated aezeed cipher seed."
|
"description": "*\naezeed_passphrase is an optional user provided passphrase that will be used\nto encrypt the generated aezeed cipher seed."
|
||||||
|
},
|
||||||
|
"recovery_window": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32",
|
||||||
|
"description": "*\nrecovery_window is an optional argument specifying the address lookahead\nwhen restoring a wallet seed. The recovery window applies to each\ninvdividual branch of the BIP44 derivation paths. Supplying a recovery\nwindow of zero indicates that no addresses should be recovered, such after\nthe first initialization of the wallet."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2390,6 +2395,11 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "byte",
|
"format": "byte",
|
||||||
"description": "*\nwallet_password should be the current valid passphrase for the daemon. This\nwill be required to decrypt on-disk material that the daemon requires to\nfunction properly."
|
"description": "*\nwallet_password should be the current valid passphrase for the daemon. This\nwill be required to decrypt on-disk material that the daemon requires to\nfunction properly."
|
||||||
|
},
|
||||||
|
"recovery_window": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32",
|
||||||
|
"description": "*\nrecovery_window is an optional argument specifying the address lookahead\nwhen restoring a wallet seed. The recovery window applies to each\ninvdividual branch of the BIP44 derivation paths. Supplying a recovery\nwindow of zero indicates that no addresses should be recovered, such after\nthe first initialization of the wallet."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -238,7 +238,97 @@ func (n *NetworkHarness) TearDownAll() error {
|
|||||||
// current instance of the network harness. The created node is running, but
|
// current instance of the network harness. The created node is running, but
|
||||||
// not yet connected to other nodes within the network.
|
// not yet connected to other nodes within the network.
|
||||||
func (n *NetworkHarness) NewNode(extraArgs []string) (*HarnessNode, error) {
|
func (n *NetworkHarness) NewNode(extraArgs []string) (*HarnessNode, error) {
|
||||||
|
return n.newNode(extraArgs, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNodeWithSeed fully initializes a new HarnessNode after creating a fresh
|
||||||
|
// aezeed. The provided password is used as both the aezeed password and the
|
||||||
|
// wallet password. The generated mnemonic is returned along with the
|
||||||
|
// initialized harness node.
|
||||||
|
func (n *NetworkHarness) NewNodeWithSeed(extraArgs []string,
|
||||||
|
password []byte) (*HarnessNode, []string, error) {
|
||||||
|
|
||||||
|
node, err := n.newNode(extraArgs, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout := time.Duration(time.Second * 15)
|
||||||
|
ctxb := context.Background()
|
||||||
|
|
||||||
|
// Create a request to generate a new aezeed. The new seed will have the
|
||||||
|
// same password as the internal wallet.
|
||||||
|
genSeedReq := &lnrpc.GenSeedRequest{
|
||||||
|
AezeedPassphrase: password,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt, _ := context.WithTimeout(ctxb, timeout)
|
||||||
|
genSeedResp, err := node.GenSeed(ctxt, genSeedReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// With the seed created, construct the init request to the node,
|
||||||
|
// including the newly generated seed.
|
||||||
|
initReq := &lnrpc.InitWalletRequest{
|
||||||
|
WalletPassword: password,
|
||||||
|
CipherSeedMnemonic: genSeedResp.CipherSeedMnemonic,
|
||||||
|
AezeedPassphrase: password,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass the init request via rpc to finish unlocking the node. This will
|
||||||
|
// also initialize the macaroon-authenticated LightningClient.
|
||||||
|
err = node.Init(ctxb, initReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// With the node started, we can now record its public key within the
|
||||||
|
// global mapping.
|
||||||
|
n.RegisterNode(node)
|
||||||
|
|
||||||
|
return node, genSeedResp.CipherSeedMnemonic, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RestoreNodeWithSeed fully initializes a HarnessNode using a chosen mnemonic,
|
||||||
|
// password, and recovery window. After providing the initialization request to
|
||||||
|
// unlock the node, this method will finish initializing the LightningClient
|
||||||
|
// such that the HarnessNode can be used for regular rpc operations.
|
||||||
|
func (n *NetworkHarness) RestoreNodeWithSeed(extraArgs []string,
|
||||||
|
password []byte, mnemonic []string,
|
||||||
|
recoveryWindow int32) (*HarnessNode, error) {
|
||||||
|
|
||||||
|
node, err := n.newNode(extraArgs, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
initReq := &lnrpc.InitWalletRequest{
|
||||||
|
WalletPassword: password,
|
||||||
|
CipherSeedMnemonic: mnemonic,
|
||||||
|
AezeedPassphrase: password,
|
||||||
|
RecoveryWindow: recoveryWindow,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = node.Init(context.Background(), initReq)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// With the node started, we can now record its public key within the
|
||||||
|
// global mapping.
|
||||||
|
n.RegisterNode(node)
|
||||||
|
|
||||||
|
return node, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newNode initializes a new HarnessNode, supporting the ability to initialize a
|
||||||
|
// wallet with or without a seed. If hasSeed is false, the returned harness node
|
||||||
|
// can be used immediately. Otherwise, the node will require an additional
|
||||||
|
// initialization phase where the wallet is either created or restored.
|
||||||
|
func (n *NetworkHarness) newNode(extraArgs []string, hasSeed bool) (*HarnessNode, error) {
|
||||||
node, err := newNode(nodeConfig{
|
node, err := newNode(nodeConfig{
|
||||||
|
HasSeed: hasSeed,
|
||||||
RPCConfig: &n.rpcConfig,
|
RPCConfig: &n.rpcConfig,
|
||||||
NetParams: n.netParams,
|
NetParams: n.netParams,
|
||||||
ExtraArgs: extraArgs,
|
ExtraArgs: extraArgs,
|
||||||
@ -257,13 +347,27 @@ func (n *NetworkHarness) NewNode(extraArgs []string) (*HarnessNode, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this node is to have a seed, it will need to be unlocked or
|
||||||
|
// initialized via rpc. Delay registering it with the network until it
|
||||||
|
// can be driven via an unlocked rpc connection.
|
||||||
|
if node.cfg.HasSeed {
|
||||||
|
return node, nil
|
||||||
|
}
|
||||||
|
|
||||||
// With the node started, we can now record its public key within the
|
// With the node started, we can now record its public key within the
|
||||||
// global mapping.
|
// global mapping.
|
||||||
|
n.RegisterNode(node)
|
||||||
|
|
||||||
|
return node, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterNode records a new HarnessNode in the NetworkHarnesses map of known
|
||||||
|
// nodes. This method should only be called with nodes that have successfully
|
||||||
|
// retrieved their public keys via FetchNodeInfo.
|
||||||
|
func (n *NetworkHarness) RegisterNode(node *HarnessNode) {
|
||||||
n.mtx.Lock()
|
n.mtx.Lock()
|
||||||
n.nodesByPub[node.PubKeyStr] = node
|
n.nodesByPub[node.PubKeyStr] = node
|
||||||
n.mtx.Unlock()
|
n.mtx.Unlock()
|
||||||
|
|
||||||
return node, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnsureConnected will try to connect to two nodes, returning no error if they
|
// EnsureConnected will try to connect to two nodes, returning no error if they
|
||||||
@ -986,10 +1090,31 @@ func (n *NetworkHarness) DumpLogs(node *HarnessNode) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SendCoins attempts to send amt satoshis from the internal mining node to the
|
// SendCoins attempts to send amt satoshis from the internal mining node to the
|
||||||
// targeted lightning node.
|
// targeted lightning node using a P2WKH address.
|
||||||
func (n *NetworkHarness) SendCoins(ctx context.Context, amt btcutil.Amount,
|
func (n *NetworkHarness) SendCoins(ctx context.Context, amt btcutil.Amount,
|
||||||
target *HarnessNode) error {
|
target *HarnessNode) error {
|
||||||
|
|
||||||
|
return n.sendCoins(
|
||||||
|
ctx, amt, target, lnrpc.NewAddressRequest_WITNESS_PUBKEY_HASH,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendCoinsNP2WKH attempts to send amt satoshis from the internal mining node
|
||||||
|
// to the targeted lightning node using a NP2WKH address.
|
||||||
|
func (n *NetworkHarness) SendCoinsNP2WKH(ctx context.Context,
|
||||||
|
amt btcutil.Amount, target *HarnessNode) error {
|
||||||
|
|
||||||
|
return n.sendCoins(
|
||||||
|
ctx, amt, target, lnrpc.NewAddressRequest_NESTED_PUBKEY_HASH,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sendCoins attempts to send amt satoshis from the internal mining node to the
|
||||||
|
// targeted lightning node.
|
||||||
|
func (n *NetworkHarness) sendCoins(ctx context.Context, amt btcutil.Amount,
|
||||||
|
target *HarnessNode,
|
||||||
|
addrType lnrpc.NewAddressRequest_AddressType) error {
|
||||||
|
|
||||||
balReq := &lnrpc.WalletBalanceRequest{}
|
balReq := &lnrpc.WalletBalanceRequest{}
|
||||||
initialBalance, err := target.WalletBalance(ctx, balReq)
|
initialBalance, err := target.WalletBalance(ctx, balReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1000,7 +1125,7 @@ func (n *NetworkHarness) SendCoins(ctx context.Context, amt btcutil.Amount,
|
|||||||
// to receive a p2wkh address s.t the output can immediately be used as
|
// to receive a p2wkh address s.t the output can immediately be used as
|
||||||
// an input to a funding transaction.
|
// an input to a funding transaction.
|
||||||
addrReq := &lnrpc.NewAddressRequest{
|
addrReq := &lnrpc.NewAddressRequest{
|
||||||
Type: lnrpc.NewAddressRequest_WITNESS_PUBKEY_HASH,
|
Type: addrType,
|
||||||
}
|
}
|
||||||
resp, err := target.NewAddress(ctx, addrReq)
|
resp, err := target.NewAddress(ctx, addrReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
124
lntest/node.go
124
lntest/node.go
@ -98,6 +98,8 @@ type nodeConfig struct {
|
|||||||
ReadMacPath string
|
ReadMacPath string
|
||||||
InvoiceMacPath string
|
InvoiceMacPath string
|
||||||
|
|
||||||
|
HasSeed bool
|
||||||
|
|
||||||
P2PPort int
|
P2PPort int
|
||||||
RPCPort int
|
RPCPort int
|
||||||
RESTPort int
|
RESTPort int
|
||||||
@ -136,7 +138,6 @@ func (cfg nodeConfig) genArgs() []string {
|
|||||||
encodedCert := hex.EncodeToString(cfg.RPCConfig.Certificates)
|
encodedCert := hex.EncodeToString(cfg.RPCConfig.Certificates)
|
||||||
args = append(args, "--bitcoin.active")
|
args = append(args, "--bitcoin.active")
|
||||||
args = append(args, "--nobootstrap")
|
args = append(args, "--nobootstrap")
|
||||||
args = append(args, "--noencryptwallet")
|
|
||||||
args = append(args, "--debuglevel=debug")
|
args = append(args, "--debuglevel=debug")
|
||||||
args = append(args, "--bitcoin.defaultchanconfs=1")
|
args = append(args, "--bitcoin.defaultchanconfs=1")
|
||||||
args = append(args, "--bitcoin.defaultremotedelay=4")
|
args = append(args, "--bitcoin.defaultremotedelay=4")
|
||||||
@ -159,6 +160,10 @@ func (cfg nodeConfig) genArgs() []string {
|
|||||||
args = append(args, fmt.Sprintf("--externalip=%s", cfg.P2PAddr()))
|
args = append(args, fmt.Sprintf("--externalip=%s", cfg.P2PAddr()))
|
||||||
args = append(args, fmt.Sprintf("--trickledelay=%v", trickleDelay))
|
args = append(args, fmt.Sprintf("--trickledelay=%v", trickleDelay))
|
||||||
|
|
||||||
|
if !cfg.HasSeed {
|
||||||
|
args = append(args, "--noencryptwallet")
|
||||||
|
}
|
||||||
|
|
||||||
if cfg.ExtraArgs != nil {
|
if cfg.ExtraArgs != nil {
|
||||||
args = append(args, cfg.ExtraArgs...)
|
args = append(args, cfg.ExtraArgs...)
|
||||||
}
|
}
|
||||||
@ -195,10 +200,13 @@ type HarnessNode struct {
|
|||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
|
|
||||||
lnrpc.LightningClient
|
lnrpc.LightningClient
|
||||||
|
|
||||||
|
lnrpc.WalletUnlockerClient
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert *HarnessNode implements the lnrpc.LightningClient interface.
|
// Assert *HarnessNode implements the lnrpc.LightningClient interface.
|
||||||
var _ lnrpc.LightningClient = (*HarnessNode)(nil)
|
var _ lnrpc.LightningClient = (*HarnessNode)(nil)
|
||||||
|
var _ lnrpc.WalletUnlockerClient = (*HarnessNode)(nil)
|
||||||
|
|
||||||
// newNode creates a new test lightning node instance from the passed config.
|
// newNode creates a new test lightning node instance from the passed config.
|
||||||
func newNode(cfg nodeConfig) (*HarnessNode, error) {
|
func newNode(cfg nodeConfig) (*HarnessNode, error) {
|
||||||
@ -301,13 +309,78 @@ func (hn *HarnessNode) start(lndError chan<- error) error {
|
|||||||
|
|
||||||
// Since Stop uses the LightningClient to stop the node, if we fail to get a
|
// Since Stop uses the LightningClient to stop the node, if we fail to get a
|
||||||
// connected client, we have to kill the process.
|
// connected client, we have to kill the process.
|
||||||
conn, err := hn.connectRPC()
|
useMacaroons := !hn.cfg.HasSeed
|
||||||
|
conn, err := hn.ConnectRPC(useMacaroons)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hn.cmd.Process.Kill()
|
hn.cmd.Process.Kill()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the node was created with a seed, we will need to perform an
|
||||||
|
// additional step to unlock the wallet. The connection returned will
|
||||||
|
// only use the TLS certs, and can only perform operations necessary to
|
||||||
|
// unlock the daemon.
|
||||||
|
if hn.cfg.HasSeed {
|
||||||
|
hn.WalletUnlockerClient = lnrpc.NewWalletUnlockerClient(conn)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return hn.initLightningClient(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init initializes a harness node by passing the init request via rpc. After
|
||||||
|
// the request is submitted, this method will block until an
|
||||||
|
// macaroon-authenticated rpc connection can be established to the harness node.
|
||||||
|
// Once established, the new connection is used to initialize the
|
||||||
|
// LightningClient and subscribes the HarnessNode to topology changes.
|
||||||
|
func (hn *HarnessNode) Init(ctx context.Context,
|
||||||
|
initReq *lnrpc.InitWalletRequest) error {
|
||||||
|
|
||||||
|
timeout := time.Duration(time.Second * 15)
|
||||||
|
ctxt, _ := context.WithTimeout(ctx, timeout)
|
||||||
|
_, err := hn.InitWallet(ctxt, initReq)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the wallet to finish unlocking, such that we can connect to
|
||||||
|
// it via a macaroon-authenticated rpc connection.
|
||||||
|
var conn *grpc.ClientConn
|
||||||
|
if err = WaitPredicate(func() bool {
|
||||||
|
conn, err = hn.ConnectRPC(true)
|
||||||
|
return err == nil
|
||||||
|
}, 5*time.Second); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return hn.initLightningClient(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// initLightningClient constructs the grpc LightningClient from the given client
|
||||||
|
// connection and subscribes the harness node to graph topology updates.
|
||||||
|
func (hn *HarnessNode) initLightningClient(conn *grpc.ClientConn) error {
|
||||||
|
// Construct the LightningClient that will allow us to use the
|
||||||
|
// HarnessNode directly for normal rpc operations.
|
||||||
hn.LightningClient = lnrpc.NewLightningClient(conn)
|
hn.LightningClient = lnrpc.NewLightningClient(conn)
|
||||||
|
|
||||||
|
// Set the harness node's pubkey to what the node claims in GetInfo.
|
||||||
|
err := hn.FetchNodeInfo()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Launch the watcher that will hook into graph related topology change
|
||||||
|
// from the PoV of this node.
|
||||||
|
hn.wg.Add(1)
|
||||||
|
go hn.lightningNetworkWatcher()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FetchNodeInfo queries an unlocked node to retrieve its public key. This
|
||||||
|
// method also spawns a lightning network watcher for this node, which watches
|
||||||
|
// for topology changes.
|
||||||
|
func (hn *HarnessNode) FetchNodeInfo() error {
|
||||||
// Obtain the lnid of this node for quick identification purposes.
|
// Obtain the lnid of this node for quick identification purposes.
|
||||||
ctxb := context.Background()
|
ctxb := context.Background()
|
||||||
info, err := hn.GetInfo(ctxb, &lnrpc.GetInfoRequest{})
|
info, err := hn.GetInfo(ctxb, &lnrpc.GetInfoRequest{})
|
||||||
@ -323,11 +396,6 @@ func (hn *HarnessNode) start(lndError chan<- error) error {
|
|||||||
}
|
}
|
||||||
copy(hn.PubKey[:], pubkey)
|
copy(hn.PubKey[:], pubkey)
|
||||||
|
|
||||||
// Launch the watcher that will hook into graph related topology change
|
|
||||||
// from the PoV of this node.
|
|
||||||
hn.wg.Add(1)
|
|
||||||
go hn.lightningNetworkWatcher()
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,24 +433,45 @@ func (hn *HarnessNode) writePidFile() error {
|
|||||||
|
|
||||||
// connectRPC uses the TLS certificate and admin macaroon files written by the
|
// connectRPC uses the TLS certificate and admin macaroon files written by the
|
||||||
// lnd node to create a gRPC client connection.
|
// lnd node to create a gRPC client connection.
|
||||||
func (hn *HarnessNode) connectRPC() (*grpc.ClientConn, error) {
|
func (hn *HarnessNode) ConnectRPC(useMacs bool) (*grpc.ClientConn, error) {
|
||||||
// Wait until TLS certificate and admin macaroon are created before
|
// Wait until TLS certificate and admin macaroon are created before
|
||||||
// using them, up to 20 sec.
|
// using them, up to 20 sec.
|
||||||
tlsTimeout := time.After(30 * time.Second)
|
tlsTimeout := time.After(30 * time.Second)
|
||||||
for !fileExists(hn.cfg.TLSCertPath) || !fileExists(hn.cfg.AdminMacPath) {
|
for !fileExists(hn.cfg.TLSCertPath) {
|
||||||
select {
|
select {
|
||||||
case <-tlsTimeout:
|
case <-tlsTimeout:
|
||||||
return nil, fmt.Errorf("timeout waiting for TLS cert file " +
|
return nil, fmt.Errorf("timeout waiting for TLS cert " +
|
||||||
"and admin macaroon file to be created after " +
|
"file to be created after 30 seconds")
|
||||||
"20 seconds")
|
|
||||||
case <-time.After(100 * time.Millisecond):
|
case <-time.After(100 * time.Millisecond):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opts := []grpc.DialOption{
|
||||||
|
grpc.WithBlock(),
|
||||||
|
grpc.WithTimeout(time.Second * 20),
|
||||||
|
}
|
||||||
|
|
||||||
tlsCreds, err := credentials.NewClientTLSFromFile(hn.cfg.TLSCertPath, "")
|
tlsCreds, err := credentials.NewClientTLSFromFile(hn.cfg.TLSCertPath, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opts = append(opts, grpc.WithTransportCredentials(tlsCreds))
|
||||||
|
|
||||||
|
if !useMacs {
|
||||||
|
return grpc.Dial(hn.cfg.RPCAddr(), opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
macTimeout := time.After(30 * time.Second)
|
||||||
|
for !fileExists(hn.cfg.AdminMacPath) {
|
||||||
|
select {
|
||||||
|
case <-macTimeout:
|
||||||
|
return nil, fmt.Errorf("timeout waiting for admin " +
|
||||||
|
"macaroon file to be created after 30 seconds")
|
||||||
|
case <-time.After(100 * time.Millisecond):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macBytes, err := ioutil.ReadFile(hn.cfg.AdminMacPath)
|
macBytes, err := ioutil.ReadFile(hn.cfg.AdminMacPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -391,12 +480,10 @@ func (hn *HarnessNode) connectRPC() (*grpc.ClientConn, error) {
|
|||||||
if err = mac.UnmarshalBinary(macBytes); err != nil {
|
if err = mac.UnmarshalBinary(macBytes); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
opts := []grpc.DialOption{
|
|
||||||
grpc.WithTransportCredentials(tlsCreds),
|
macCred := macaroons.NewMacaroonCredential(mac)
|
||||||
grpc.WithPerRPCCredentials(macaroons.NewMacaroonCredential(mac)),
|
opts = append(opts, grpc.WithPerRPCCredentials(macCred))
|
||||||
grpc.WithBlock(),
|
|
||||||
grpc.WithTimeout(time.Second * 20),
|
|
||||||
}
|
|
||||||
return grpc.Dial(hn.cfg.RPCAddr(), opts...)
|
return grpc.Dial(hn.cfg.RPCAddr(), opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,6 +528,7 @@ func (hn *HarnessNode) stop() error {
|
|||||||
hn.quit = nil
|
hn.quit = nil
|
||||||
hn.processExit = nil
|
hn.processExit = nil
|
||||||
hn.LightningClient = nil
|
hn.LightningClient = nil
|
||||||
|
hn.WalletUnlockerClient = nil
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ func New(cfg Config) (*BtcWallet, error) {
|
|||||||
pubPass = cfg.PublicPass
|
pubPass = cfg.PublicPass
|
||||||
}
|
}
|
||||||
|
|
||||||
loader := base.NewLoader(cfg.NetParams, netDir)
|
loader := base.NewLoader(cfg.NetParams, netDir, cfg.RecoveryWindow)
|
||||||
walletExists, err := loader.WalletExists()
|
walletExists, err := loader.WalletExists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -98,7 +98,7 @@ func New(cfg Config) (*BtcWallet, error) {
|
|||||||
if !walletExists {
|
if !walletExists {
|
||||||
// Wallet has never been created, perform initial set up.
|
// Wallet has never been created, perform initial set up.
|
||||||
wallet, err = loader.CreateNewWallet(
|
wallet, err = loader.CreateNewWallet(
|
||||||
pubPass, cfg.PrivatePass, cfg.HdSeed,
|
pubPass, cfg.PrivatePass, cfg.HdSeed, cfg.Birthday,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -2,6 +2,7 @@ package btcwallet
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/roasbeef/btcd/chaincfg"
|
"github.com/roasbeef/btcd/chaincfg"
|
||||||
@ -63,6 +64,15 @@ type Config struct {
|
|||||||
// unspecified, a new seed will be generated.
|
// unspecified, a new seed will be generated.
|
||||||
HdSeed []byte
|
HdSeed []byte
|
||||||
|
|
||||||
|
// Birthday specifies the time at which this wallet was initially
|
||||||
|
// created. It is used to bound rescans for used addresses.
|
||||||
|
Birthday time.Time
|
||||||
|
|
||||||
|
// RecoveryWindow specifies the address look-ahead for which to scan
|
||||||
|
// when restoring a wallet. The recovery window will apply to all
|
||||||
|
// default BIP44 derivation paths.
|
||||||
|
RecoveryWindow uint32
|
||||||
|
|
||||||
// ChainSource is the primary chain interface. This is used to operate
|
// ChainSource is the primary chain interface. This is used to operate
|
||||||
// the wallet and do things such as rescanning, sending transactions,
|
// the wallet and do things such as rescanning, sending transactions,
|
||||||
// notifications for received funds, etc.
|
// notifications for received funds, etc.
|
||||||
|
@ -2083,7 +2083,9 @@ func runTests(t *testing.T, walletDriver *lnwallet.WalletDriver,
|
|||||||
}
|
}
|
||||||
aliceChain.Start()
|
aliceChain.Start()
|
||||||
defer aliceChain.Stop()
|
defer aliceChain.Stop()
|
||||||
aliceClient = chain.NewNeutrinoClient(aliceChain)
|
aliceClient = chain.NewNeutrinoClient(
|
||||||
|
netParams, aliceChain,
|
||||||
|
)
|
||||||
|
|
||||||
// Start Bob - open a database, start a neutrino
|
// Start Bob - open a database, start a neutrino
|
||||||
// instance, and initialize a btcwallet driver for it.
|
// instance, and initialize a btcwallet driver for it.
|
||||||
@ -2108,7 +2110,9 @@ func runTests(t *testing.T, walletDriver *lnwallet.WalletDriver,
|
|||||||
}
|
}
|
||||||
bobChain.Start()
|
bobChain.Start()
|
||||||
defer bobChain.Stop()
|
defer bobChain.Stop()
|
||||||
bobClient = chain.NewNeutrinoClient(bobChain)
|
bobClient = chain.NewNeutrinoClient(
|
||||||
|
netParams, bobChain,
|
||||||
|
)
|
||||||
|
|
||||||
case "bitcoind":
|
case "bitcoind":
|
||||||
feeEstimator, err = lnwallet.NewBitcoindFeeEstimator(
|
feeEstimator, err = lnwallet.NewBitcoindFeeEstimator(
|
||||||
|
@ -14,7 +14,7 @@ import (
|
|||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WalletInitMsg is a message sent to the UnlockerService when a user wishes to
|
// WalletInitMsg is a message sent by the UnlockerService when a user wishes to
|
||||||
// set up the internal wallet for the first time. The user MUST provide a
|
// set up the internal wallet for the first time. The user MUST provide a
|
||||||
// passphrase, but is also able to provide their own source of entropy. If
|
// passphrase, but is also able to provide their own source of entropy. If
|
||||||
// provided, then this source of entropy will be used to generate the wallet's
|
// provided, then this source of entropy will be used to generate the wallet's
|
||||||
@ -27,6 +27,28 @@ type WalletInitMsg struct {
|
|||||||
// WalletSeed is the deciphered cipher seed that the wallet should use
|
// WalletSeed is the deciphered cipher seed that the wallet should use
|
||||||
// to initialize itself.
|
// to initialize itself.
|
||||||
WalletSeed *aezeed.CipherSeed
|
WalletSeed *aezeed.CipherSeed
|
||||||
|
|
||||||
|
// RecoveryWindow is the address look-ahead used when restoring a seed
|
||||||
|
// with existing funds. A recovery window zero indicates that no
|
||||||
|
// recovery should be attempted, such as after the wallet's initial
|
||||||
|
// creation.
|
||||||
|
RecoveryWindow uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// WalletUnlockMsg is a message sent by the UnlockerService when a user wishes
|
||||||
|
// to unlock the internal wallet after initial setup. The user can optionally
|
||||||
|
// specify a recovery window, which will resume an interrupted rescan for used
|
||||||
|
// addresses.
|
||||||
|
type WalletUnlockMsg struct {
|
||||||
|
// Passphrase is the passphrase that will be used to encrypt the wallet
|
||||||
|
// itself. This MUST be at least 8 characters.
|
||||||
|
Passphrase []byte
|
||||||
|
|
||||||
|
// RecoveryWindow is the address look-ahead used when restoring a seed
|
||||||
|
// with existing funds. A recovery window zero indicates that no
|
||||||
|
// recovery should be attempted, such as after the wallet's initial
|
||||||
|
// creation, but before any addresses have been created.
|
||||||
|
RecoveryWindow uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnlockerService implements the WalletUnlocker service used to provide lnd
|
// UnlockerService implements the WalletUnlocker service used to provide lnd
|
||||||
@ -37,10 +59,10 @@ type UnlockerService struct {
|
|||||||
// InitMsgs is a channel that carries all wallet init messages.
|
// InitMsgs is a channel that carries all wallet init messages.
|
||||||
InitMsgs chan *WalletInitMsg
|
InitMsgs chan *WalletInitMsg
|
||||||
|
|
||||||
// UnlockPasswords is a channel where passwords provided by the rpc
|
// UnlockMsgs is a channel where unlock parameters provided by the rpc
|
||||||
// client to be used to unlock and decrypt an existing wallet will be
|
// client to be used to unlock and decrypt an existing wallet will be
|
||||||
// sent.
|
// sent.
|
||||||
UnlockPasswords chan []byte
|
UnlockMsgs chan *WalletUnlockMsg
|
||||||
|
|
||||||
chainDir string
|
chainDir string
|
||||||
netParams *chaincfg.Params
|
netParams *chaincfg.Params
|
||||||
@ -52,10 +74,10 @@ func New(authSvc *macaroons.Service, chainDir string,
|
|||||||
params *chaincfg.Params) *UnlockerService {
|
params *chaincfg.Params) *UnlockerService {
|
||||||
|
|
||||||
return &UnlockerService{
|
return &UnlockerService{
|
||||||
InitMsgs: make(chan *WalletInitMsg, 1),
|
InitMsgs: make(chan *WalletInitMsg, 1),
|
||||||
UnlockPasswords: make(chan []byte, 1),
|
UnlockMsgs: make(chan *WalletUnlockMsg, 1),
|
||||||
chainDir: chainDir,
|
chainDir: chainDir,
|
||||||
netParams: params,
|
netParams: params,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +95,7 @@ func (u *UnlockerService) GenSeed(ctx context.Context,
|
|||||||
// Before we start, we'll ensure that the wallet hasn't already created
|
// Before we start, we'll ensure that the wallet hasn't already created
|
||||||
// so we don't show a *new* seed to the user if one already exists.
|
// so we don't show a *new* seed to the user if one already exists.
|
||||||
netDir := btcwallet.NetworkDir(u.chainDir, u.netParams)
|
netDir := btcwallet.NetworkDir(u.chainDir, u.netParams)
|
||||||
loader := wallet.NewLoader(u.netParams, netDir)
|
loader := wallet.NewLoader(u.netParams, netDir, 0)
|
||||||
walletExists, err := loader.WalletExists()
|
walletExists, err := loader.WalletExists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -156,10 +178,17 @@ func (u *UnlockerService) InitWallet(ctx context.Context,
|
|||||||
"at least 8 characters")
|
"at least 8 characters")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Require that the recovery window be non-negative.
|
||||||
|
recoveryWindow := in.RecoveryWindow
|
||||||
|
if recoveryWindow < 0 {
|
||||||
|
return nil, fmt.Errorf("recovery window %d must be "+
|
||||||
|
"non-negative", recoveryWindow)
|
||||||
|
}
|
||||||
|
|
||||||
// We'll then open up the directory that will be used to store the
|
// We'll then open up the directory that will be used to store the
|
||||||
// wallet's files so we can check if the wallet already exists.
|
// wallet's files so we can check if the wallet already exists.
|
||||||
netDir := btcwallet.NetworkDir(u.chainDir, u.netParams)
|
netDir := btcwallet.NetworkDir(u.chainDir, u.netParams)
|
||||||
loader := wallet.NewLoader(u.netParams, netDir)
|
loader := wallet.NewLoader(u.netParams, netDir, uint32(recoveryWindow))
|
||||||
|
|
||||||
walletExists, err := loader.WalletExists()
|
walletExists, err := loader.WalletExists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -198,8 +227,9 @@ func (u *UnlockerService) InitWallet(ctx context.Context,
|
|||||||
// now send over the wallet password and the seed. This will allow the
|
// now send over the wallet password and the seed. This will allow the
|
||||||
// daemon to initialize itself and startup.
|
// daemon to initialize itself and startup.
|
||||||
initMsg := &WalletInitMsg{
|
initMsg := &WalletInitMsg{
|
||||||
Passphrase: password,
|
Passphrase: password,
|
||||||
WalletSeed: cipherSeed,
|
WalletSeed: cipherSeed,
|
||||||
|
RecoveryWindow: uint32(recoveryWindow),
|
||||||
}
|
}
|
||||||
|
|
||||||
u.InitMsgs <- initMsg
|
u.InitMsgs <- initMsg
|
||||||
@ -208,13 +238,16 @@ func (u *UnlockerService) InitWallet(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UnlockWallet sends the password provided by the incoming UnlockWalletRequest
|
// UnlockWallet sends the password provided by the incoming UnlockWalletRequest
|
||||||
// over the UnlockPasswords channel in case it successfully decrypts an
|
// over the UnlockMsgs channel in case it successfully decrypts an existing
|
||||||
// existing wallet found in the chain's wallet database directory.
|
// wallet found in the chain's wallet database directory.
|
||||||
func (u *UnlockerService) UnlockWallet(ctx context.Context,
|
func (u *UnlockerService) UnlockWallet(ctx context.Context,
|
||||||
in *lnrpc.UnlockWalletRequest) (*lnrpc.UnlockWalletResponse, error) {
|
in *lnrpc.UnlockWalletRequest) (*lnrpc.UnlockWalletResponse, error) {
|
||||||
|
|
||||||
|
password := in.WalletPassword
|
||||||
|
recoveryWindow := uint32(in.RecoveryWindow)
|
||||||
|
|
||||||
netDir := btcwallet.NetworkDir(u.chainDir, u.netParams)
|
netDir := btcwallet.NetworkDir(u.chainDir, u.netParams)
|
||||||
loader := wallet.NewLoader(u.netParams, netDir)
|
loader := wallet.NewLoader(u.netParams, netDir, recoveryWindow)
|
||||||
|
|
||||||
// Check if wallet already exists.
|
// Check if wallet already exists.
|
||||||
walletExists, err := loader.WalletExists()
|
walletExists, err := loader.WalletExists()
|
||||||
@ -228,7 +261,7 @@ func (u *UnlockerService) UnlockWallet(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try opening the existing wallet with the provided password.
|
// Try opening the existing wallet with the provided password.
|
||||||
_, err = loader.OpenExistingWallet(in.WalletPassword, false)
|
_, err = loader.OpenExistingWallet(password, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Could not open wallet, most likely this means that provided
|
// Could not open wallet, most likely this means that provided
|
||||||
// password was incorrect.
|
// password was incorrect.
|
||||||
@ -244,17 +277,22 @@ func (u *UnlockerService) UnlockWallet(ctx context.Context,
|
|||||||
|
|
||||||
// Attempt to create a password for the macaroon service.
|
// Attempt to create a password for the macaroon service.
|
||||||
if u.authSvc != nil {
|
if u.authSvc != nil {
|
||||||
err = u.authSvc.CreateUnlock(&in.WalletPassword)
|
err = u.authSvc.CreateUnlock(&password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to create/unlock "+
|
return nil, fmt.Errorf("unable to create/unlock "+
|
||||||
"macaroon store: %v", err)
|
"macaroon store: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
walletUnlockMsg := &WalletUnlockMsg{
|
||||||
|
Passphrase: password,
|
||||||
|
RecoveryWindow: recoveryWindow,
|
||||||
|
}
|
||||||
|
|
||||||
// At this point we was able to open the existing wallet with the
|
// At this point we was able to open the existing wallet with the
|
||||||
// provided password. We send the password over the UnlockPasswords
|
// provided password. We send the password over the UnlockMsgs
|
||||||
// channel, such that it can be used by lnd to open the wallet.
|
// channel, such that it can be used by lnd to open the wallet.
|
||||||
u.UnlockPasswords <- in.WalletPassword
|
u.UnlockMsgs <- walletUnlockMsg
|
||||||
|
|
||||||
return &lnrpc.UnlockWalletResponse{}, nil
|
return &lnrpc.UnlockWalletResponse{}, nil
|
||||||
}
|
}
|
||||||
|
@ -33,12 +33,16 @@ var (
|
|||||||
}
|
}
|
||||||
|
|
||||||
testNetParams = &chaincfg.MainNetParams
|
testNetParams = &chaincfg.MainNetParams
|
||||||
|
|
||||||
|
testRecoveryWindow uint32 = 150
|
||||||
)
|
)
|
||||||
|
|
||||||
func createTestWallet(t *testing.T, dir string, netParams *chaincfg.Params) {
|
func createTestWallet(t *testing.T, dir string, netParams *chaincfg.Params) {
|
||||||
netDir := btcwallet.NetworkDir(dir, netParams)
|
netDir := btcwallet.NetworkDir(dir, netParams)
|
||||||
loader := wallet.NewLoader(netParams, netDir)
|
loader := wallet.NewLoader(netParams, netDir, 0)
|
||||||
_, err := loader.CreateNewWallet(testPassword, testPassword, testSeed)
|
_, err := loader.CreateNewWallet(
|
||||||
|
testPassword, testPassword, testSeed, time.Time{},
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed creating wallet: %v", err)
|
t.Fatalf("failed creating wallet: %v", err)
|
||||||
}
|
}
|
||||||
@ -207,6 +211,7 @@ func TestInitWallet(t *testing.T) {
|
|||||||
WalletPassword: testPassword,
|
WalletPassword: testPassword,
|
||||||
CipherSeedMnemonic: []string(mnemonic[:]),
|
CipherSeedMnemonic: []string(mnemonic[:]),
|
||||||
AezeedPassphrase: pass,
|
AezeedPassphrase: pass,
|
||||||
|
RecoveryWindow: int32(testRecoveryWindow),
|
||||||
}
|
}
|
||||||
_, err = service.InitWallet(ctx, req)
|
_, err = service.InitWallet(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -236,6 +241,11 @@ func TestInitWallet(t *testing.T) {
|
|||||||
"got %x", cipherSeed.Entropy[:],
|
"got %x", cipherSeed.Entropy[:],
|
||||||
msg.WalletSeed.Entropy[:])
|
msg.WalletSeed.Entropy[:])
|
||||||
}
|
}
|
||||||
|
if msg.RecoveryWindow != testRecoveryWindow {
|
||||||
|
t.Fatalf("mismatched recovery window: expected %v,"+
|
||||||
|
"got %v", testRecoveryWindow,
|
||||||
|
msg.RecoveryWindow)
|
||||||
|
}
|
||||||
|
|
||||||
case <-time.After(3 * time.Second):
|
case <-time.After(3 * time.Second):
|
||||||
t.Fatalf("password not received")
|
t.Fatalf("password not received")
|
||||||
@ -312,6 +322,7 @@ func TestUnlockWallet(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
req := &lnrpc.UnlockWalletRequest{
|
req := &lnrpc.UnlockWalletRequest{
|
||||||
WalletPassword: testPassword,
|
WalletPassword: testPassword,
|
||||||
|
RecoveryWindow: int32(testRecoveryWindow),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should fail to unlock non-existing wallet.
|
// Should fail to unlock non-existing wallet.
|
||||||
@ -338,12 +349,17 @@ func TestUnlockWallet(t *testing.T) {
|
|||||||
t.Fatalf("unable to unlock wallet: %v", err)
|
t.Fatalf("unable to unlock wallet: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Password should be sent over the channel.
|
// Password and recovery window should be sent over the channel.
|
||||||
select {
|
select {
|
||||||
case pw := <-service.UnlockPasswords:
|
case unlockMsg := <-service.UnlockMsgs:
|
||||||
if !bytes.Equal(pw, testPassword) {
|
if !bytes.Equal(unlockMsg.Passphrase, testPassword) {
|
||||||
t.Fatalf("expected to receive password %x, got %x",
|
t.Fatalf("expected to receive password %x, got %x",
|
||||||
testPassword, pw)
|
testPassword, unlockMsg.Passphrase)
|
||||||
|
}
|
||||||
|
if unlockMsg.RecoveryWindow != testRecoveryWindow {
|
||||||
|
t.Fatalf("expected to receive recovery window %d, "+
|
||||||
|
"got %d", testRecoveryWindow,
|
||||||
|
unlockMsg.RecoveryWindow)
|
||||||
}
|
}
|
||||||
case <-time.After(3 * time.Second):
|
case <-time.After(3 * time.Second):
|
||||||
t.Fatalf("password not received")
|
t.Fatalf("password not received")
|
||||||
|
Loading…
Reference in New Issue
Block a user